https://github.com/mysterymath updated 
https://github.com/llvm/llvm-project/pull/147426

>From 028a89f8a92de3b7939d092332c975c4964e0e4b Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dth...@google.com>
Date: Thu, 19 Dec 2024 11:57:27 -0800
Subject: [PATCH] [libc] Modular printf option (float only)

This adds LIBC_CONF_PRINTF_MODULAR, which causes floating point support
(later, others) to be weakly linked into the implementation.
__printf_modular becomes the main entry point of the implementaiton, an
printf itself wraps __printf_modular. printf it also contains a
BFD_RELOC_NONE relocation to bring in the float aspect.

See issue #146159 for context.
---
 libc/config/config.json                       |  4 ++
 libc/docs/configure.rst                       |  1 +
 libc/src/stdio/generic/CMakeLists.txt         |  7 ++-
 libc/src/stdio/generic/printf_modular.cpp     | 40 +++++++++++++
 libc/src/stdio/printf.h                       |  1 +
 libc/src/stdio/printf_core/CMakeLists.txt     |  7 ++-
 .../stdio/printf_core/float_dec_converter.h   | 25 +++++++--
 .../printf_core/float_dec_converter_limited.h | 24 ++++++--
 .../stdio/printf_core/float_hex_converter.h   | 10 +++-
 libc/src/stdio/printf_core/float_impl.cpp     | 41 ++++++++++++++
 libc/src/stdio/printf_core/parser.h           | 56 ++++++++++++++-----
 libc/src/stdio/printf_core/printf_config.h    |  7 +++
 libc/src/stdio/printf_core/printf_main.h      | 13 ++++-
 .../src/stdio/printf_core/vfprintf_internal.h | 13 ++++-
 14 files changed, 216 insertions(+), 33 deletions(-)
 create mode 100644 libc/src/stdio/generic/printf_modular.cpp
 create mode 100644 libc/src/stdio/printf_core/float_impl.cpp

diff --git a/libc/config/config.json b/libc/config/config.json
index d53b2936edb07..4278169cd5940 100644
--- a/libc/config/config.json
+++ b/libc/config/config.json
@@ -45,6 +45,10 @@
     "LIBC_CONF_PRINTF_RUNTIME_DISPATCH": {
       "value": true,
       "doc": "Use dynamic dispatch for the output mechanism to reduce code 
size."
+    },
+    "LIBC_CONF_PRINTF_MODULAR": {
+      "value": true,
+      "doc": "Split printf implementation into modules that can be lazily 
linked in."
     }
   },
   "scanf": {
diff --git a/libc/docs/configure.rst b/libc/docs/configure.rst
index 109412225634f..1998c067dc77a 100644
--- a/libc/docs/configure.rst
+++ b/libc/docs/configure.rst
@@ -45,6 +45,7 @@ to learn about the defaults for your platform and target.
     - ``LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_DYADIC_FLOAT``: Use dyadic float for 
faster and smaller but less accurate printf doubles.
     - ``LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_FLOAT320``: Use an alternative 
printf float implementation based on 320-bit floats
     - ``LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE``: Use large 
table for better printf long double performance.
+    - ``LIBC_CONF_PRINTF_MODULAR``: Split printf implementation into modules 
that can be lazily linked in.
     - ``LIBC_CONF_PRINTF_RUNTIME_DISPATCH``: Use dynamic dispatch for the 
output mechanism to reduce code size.
 * **"pthread" options**
     - ``LIBC_CONF_RAW_MUTEX_DEFAULT_SPIN_COUNT``: Default number of spins 
before blocking if a mutex is in contention (default to 100).
diff --git a/libc/src/stdio/generic/CMakeLists.txt 
b/libc/src/stdio/generic/CMakeLists.txt
index 6361822b61999..41b18bc7195ca 100644
--- a/libc/src/stdio/generic/CMakeLists.txt
+++ b/libc/src/stdio/generic/CMakeLists.txt
@@ -412,10 +412,15 @@ if(LLVM_LIBC_FULL_BUILD)
   )
 endif()
 
+set(printf_srcs printf.cpp)
+if (LIBC_CONF_PRINTF_MODULAR)
+  list(APPEND printf_srcs printf_modular.cpp)
+endif()
+
 add_generic_entrypoint_object(
   printf
   SRCS
-    printf.cpp
+    ${printf_srcs}
   HDRS
     ../printf.h
   DEPENDS
diff --git a/libc/src/stdio/generic/printf_modular.cpp 
b/libc/src/stdio/generic/printf_modular.cpp
new file mode 100644
index 0000000000000..3a6a580002062
--- /dev/null
+++ b/libc/src/stdio/generic/printf_modular.cpp
@@ -0,0 +1,40 @@
+//===-- Implementation of 
printf_modular-----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdio/printf.h"
+
+#include "src/__support/File/file.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/macros/config.h"
+#include "src/stdio/printf_core/vfprintf_internal.h"
+
+#include "hdr/types/FILE.h"
+#include <stdarg.h>
+
+#ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE
+#define PRINTF_STDOUT LIBC_NAMESPACE::stdout
+#else // LIBC_COPT_STDIO_USE_SYSTEM_FILE
+#define PRINTF_STDOUT ::stdout
+#endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, __printf_modular,
+                   (const char *__restrict format, ...)) {
+  va_list vlist;
+  va_start(vlist, format);
+  internal::ArgList args(vlist); // This holder class allows for easier copying
+                                 // and pointer semantics, as well as handling
+                                 // destruction automatically.
+  va_end(vlist);
+  int ret_val = printf_core::vfprintf_internal_modular(
+      reinterpret_cast<::FILE *>(PRINTF_STDOUT), format, args);
+  return ret_val;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/printf.h b/libc/src/stdio/printf.h
index 9e47ad8680f9c..81b7d866a6a59 100644
--- a/libc/src/stdio/printf.h
+++ b/libc/src/stdio/printf.h
@@ -15,6 +15,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 int printf(const char *__restrict format, ...);
+int __printf_modular(const char *__restrict format, ...);
 
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/src/stdio/printf_core/CMakeLists.txt 
b/libc/src/stdio/printf_core/CMakeLists.txt
index c22f9858f3b1e..abc4cc8269d79 100644
--- a/libc/src/stdio/printf_core/CMakeLists.txt
+++ b/libc/src/stdio/printf_core/CMakeLists.txt
@@ -28,6 +28,9 @@ endif()
 if(LIBC_CONF_PRINTF_RUNTIME_DISPATCH)
   list(APPEND printf_config_copts "-DLIBC_COPT_PRINTF_RUNTIME_DISPATCH")
 endif()
+if(LIBC_CONF_PRINTF_MODULAR)
+  list(APPEND printf_config_copts "-DLIBC_COPT_PRINTF_MODULAR")
+endif()
 if(printf_config_copts)
   list(PREPEND printf_config_copts "COMPILE_OPTIONS")
 endif()
@@ -112,10 +115,12 @@ add_header_library(
     libc.src.__support.StringUtil.error_to_string
 )
 
-add_header_library(
+add_object_library(
   printf_main
   HDRS
     printf_main.h
+  SRCS
+    float_impl.cpp
   DEPENDS
     .parser
     .converter
diff --git a/libc/src/stdio/printf_core/float_dec_converter.h 
b/libc/src/stdio/printf_core/float_dec_converter.h
index ed004f9a26a13..deeb566bd4092 100644
--- a/libc/src/stdio/printf_core/float_dec_converter.h
+++ b/libc/src/stdio/printf_core/float_dec_converter.h
@@ -1122,11 +1122,23 @@ LIBC_INLINE int 
convert_float_dec_auto_typed(Writer<write_mode> *writer,
   }
 }
 
+template <WriteMode write_mode>
+LIBC_PRINTF_MODULAR_DECL int
+convert_float_decimal(Writer<write_mode> *writer, const FormatSection 
&to_conv);
+template <WriteMode write_mode>
+LIBC_PRINTF_MODULAR_DECL int
+convert_float_dec_exp(Writer<write_mode> *writer, const FormatSection 
&to_conv);
+template <WriteMode write_mode>
+LIBC_PRINTF_MODULAR_DECL int
+convert_float_dec_auto(Writer<write_mode> *writer,
+                       const FormatSection &to_conv);
+
+#ifdef LIBC_PRINTF_DEFINE_MODULAR
 // TODO: unify the float converters to remove the duplicated checks for 
inf/nan.
 
 template <WriteMode write_mode>
-LIBC_INLINE int convert_float_decimal(Writer<write_mode> *writer,
-                                      const FormatSection &to_conv) {
+int convert_float_decimal(Writer<write_mode> *writer,
+                          const FormatSection &to_conv) {
   if (to_conv.length_modifier == LengthModifier::L) {
     fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
     fputil::FPBits<long double> float_bits(float_raw);
@@ -1147,8 +1159,8 @@ LIBC_INLINE int convert_float_decimal(Writer<write_mode> 
*writer,
 }
 
 template <WriteMode write_mode>
-LIBC_INLINE int convert_float_dec_exp(Writer<write_mode> *writer,
-                                      const FormatSection &to_conv) {
+int convert_float_dec_exp(Writer<write_mode> *writer,
+                          const FormatSection &to_conv) {
   if (to_conv.length_modifier == LengthModifier::L) {
     fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
     fputil::FPBits<long double> float_bits(float_raw);
@@ -1169,8 +1181,8 @@ LIBC_INLINE int convert_float_dec_exp(Writer<write_mode> 
*writer,
 }
 
 template <WriteMode write_mode>
-LIBC_INLINE int convert_float_dec_auto(Writer<write_mode> *writer,
-                                       const FormatSection &to_conv) {
+int convert_float_dec_auto(Writer<write_mode> *writer,
+                           const FormatSection &to_conv) {
   if (to_conv.length_modifier == LengthModifier::L) {
     fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
     fputil::FPBits<long double> float_bits(float_raw);
@@ -1189,6 +1201,7 @@ LIBC_INLINE int convert_float_dec_auto(Writer<write_mode> 
*writer,
 
   return convert_inf_nan(writer, to_conv);
 }
+#endif
 
 } // namespace printf_core
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/printf_core/float_dec_converter_limited.h 
b/libc/src/stdio/printf_core/float_dec_converter_limited.h
index f468dbc8e2ae8..9804a38964be0 100644
--- a/libc/src/stdio/printf_core/float_dec_converter_limited.h
+++ b/libc/src/stdio/printf_core/float_dec_converter_limited.h
@@ -676,22 +676,34 @@ LIBC_INLINE int 
convert_float_dec_auto_typed(Writer<write_mode> *writer,
 }
 
 template <WriteMode write_mode>
-LIBC_INLINE int convert_float_decimal(Writer<write_mode> *writer,
-                                      const FormatSection &to_conv) {
+LIBC_PRINTF_MODULAR_DECL int convert_float_decimal(Writer<write_mode> *writer,
+                                                 const FormatSection &to_conv);
+template <WriteMode write_mode>
+LIBC_PRINTF_MODULAR_DECL int convert_float_dec_exp(Writer<write_mode> *writer,
+                                                 const FormatSection &to_conv);
+template <WriteMode write_mode>
+LIBC_PRINTF_MODULAR_DECL int convert_float_dec_auto(Writer<write_mode> *writer,
+                                                  const FormatSection 
&to_conv);
+
+#ifdef LIBC_PRINTF_DEFINE_MODULAR
+template <WriteMode write_mode>
+int convert_float_decimal(Writer<write_mode> *writer,
+                          const FormatSection &to_conv) {
   return convert_float_outer(writer, to_conv, ConversionType::F);
 }
 
 template <WriteMode write_mode>
-LIBC_INLINE int convert_float_dec_exp(Writer<write_mode> *writer,
-                                      const FormatSection &to_conv) {
+int convert_float_dec_exp(Writer<write_mode> *writer,
+                          const FormatSection &to_conv) {
   return convert_float_outer(writer, to_conv, ConversionType::E);
 }
 
 template <WriteMode write_mode>
-LIBC_INLINE int convert_float_dec_auto(Writer<write_mode> *writer,
-                                       const FormatSection &to_conv) {
+int convert_float_dec_auto(Writer<write_mode> *writer,
+                           const FormatSection &to_conv) {
   return convert_float_outer(writer, to_conv, ConversionType::G);
 }
+#endif
 
 } // namespace printf_core
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/printf_core/float_hex_converter.h 
b/libc/src/stdio/printf_core/float_hex_converter.h
index 16592e7bac932..fa724066813d7 100644
--- a/libc/src/stdio/printf_core/float_hex_converter.h
+++ b/libc/src/stdio/printf_core/float_hex_converter.h
@@ -26,8 +26,13 @@ namespace LIBC_NAMESPACE_DECL {
 namespace printf_core {
 
 template <WriteMode write_mode>
-LIBC_INLINE int convert_float_hex_exp(Writer<write_mode> *writer,
-                                      const FormatSection &to_conv) {
+LIBC_PRINTF_MODULAR_DECL int convert_float_hex_exp(Writer<write_mode> *writer,
+                                                 const FormatSection &to_conv);
+
+#ifdef LIBC_PRINTF_DEFINE_MODULAR
+template <WriteMode write_mode>
+int convert_float_hex_exp(Writer<write_mode> *writer,
+                          const FormatSection &to_conv) {
   using LDBits = fputil::FPBits<long double>;
   using StorageType = LDBits::StorageType;
 
@@ -254,6 +259,7 @@ LIBC_INLINE int convert_float_hex_exp(Writer<write_mode> 
*writer,
   }
   return WRITE_OK;
 }
+#endif
 
 } // namespace printf_core
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/printf_core/float_impl.cpp 
b/libc/src/stdio/printf_core/float_impl.cpp
new file mode 100644
index 0000000000000..e7c9ba39aa148
--- /dev/null
+++ b/libc/src/stdio/printf_core/float_impl.cpp
@@ -0,0 +1,41 @@
+#ifdef LIBC_COPT_PRINTF_MODULAR
+#include "src/__support/arg_list.h"
+
+#define LIBC_PRINTF_DEFINE_MODULAR
+#include "src/stdio/printf_core/float_dec_converter.h"
+#include "src/stdio/printf_core/float_hex_converter.h"
+#include "src/stdio/printf_core/parser.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace printf_core {
+template class Parser<internal::ArgList>;
+template class Parser<internal::DummyArgList<false>>;
+template class Parser<internal::DummyArgList<true>>;
+template class Parser<internal::StructArgList<false>>;
+template class Parser<internal::StructArgList<true>>;
+
+#define INSTANTIATE_CONVERT_FN(NAME)                                           
\
+  template int NAME<WriteMode::FILL_BUFF_AND_DROP_OVERFLOW>(                   
\
+      Writer<WriteMode::FILL_BUFF_AND_DROP_OVERFLOW> * writer,                 
\
+      const FormatSection &to_conv);                                           
\
+  template int NAME<WriteMode::FLUSH_TO_STREAM>(                               
\
+      Writer<WriteMode::FLUSH_TO_STREAM> * writer,                             
\
+      const FormatSection &to_conv);                                           
\
+  template int NAME<WriteMode::RESIZE_AND_FILL_BUFF>(                          
\
+      Writer<WriteMode::RESIZE_AND_FILL_BUFF> * writer,                        
\
+      const FormatSection &to_conv);                                           
\
+  template int NAME<WriteMode::RUNTIME_DISPATCH>(                              
\
+      Writer<WriteMode::RUNTIME_DISPATCH> * writer,                            
\
+      const FormatSection &to_conv)
+
+INSTANTIATE_CONVERT_FN(convert_float_decimal);
+INSTANTIATE_CONVERT_FN(convert_float_dec_exp);
+INSTANTIATE_CONVERT_FN(convert_float_dec_auto);
+INSTANTIATE_CONVERT_FN(convert_float_hex_exp);
+
+} // namespace printf_core
+} // namespace LIBC_NAMESPACE_DECL
+
+// Bring this file into the link if __printf_float is referenced.
+extern "C" void __printf_float() {}
+#endif
diff --git a/libc/src/stdio/printf_core/parser.h 
b/libc/src/stdio/printf_core/parser.h
index cef9b1ae58fa0..5a1eea36b603f 100644
--- a/libc/src/stdio/printf_core/parser.h
+++ b/libc/src/stdio/printf_core/parser.h
@@ -236,11 +236,7 @@ template <typename ArgProvider> class Parser {
       case ('A'):
       case ('g'):
       case ('G'):
-        if (lm != LengthModifier::L) {
-          WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, double, conv_index);
-        } else {
-          WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, long double, 
conv_index);
-        }
+        write_float_arg_val(section, lm, conv_index);
         break;
 #endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
 #ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
@@ -299,6 +295,12 @@ template <typename ArgProvider> class Parser {
     return section;
   }
 
+  LIBC_PRINTF_MODULAR_DECL void write_float_arg_val(FormatSection &section,
+                                                  LengthModifier lm,
+                                                  size_t conv_index);
+  LIBC_PRINTF_MODULAR_DECL TypeDesc float_type_desc(LengthModifier lm);
+  LIBC_PRINTF_MODULAR_DECL bool advance_arg_if_float(TypeDesc cur_type_desc);
+
 private:
   // parse_flags parses the flags inside a format string. It assumes that
   // str[*local_pos] is inside a format specifier, and parses any flags it
@@ -474,10 +476,9 @@ template <typename ArgProvider> class Parser {
         args_cur.template next_var<uint64_t>();
 #ifndef LIBC_COPT_PRINTF_DISABLE_FLOAT
       // Floating point numbers are stored separately from the other arguments.
-      else if (cur_type_desc == type_desc_from_type<double>())
-        args_cur.template next_var<double>();
-      else if (cur_type_desc == type_desc_from_type<long double>())
-        args_cur.template next_var<long double>();
+      else if (&Parser::advance_arg_if_float &&
+               advance_arg_if_float(cur_type_desc))
+        ;
 #endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
 #ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
       // Floating point numbers may be stored separately from the other
@@ -630,10 +631,7 @@ template <typename ArgProvider> class Parser {
         case ('A'):
         case ('g'):
         case ('G'):
-          if (lm != LengthModifier::L)
-            conv_size = type_desc_from_type<double>();
-          else
-            conv_size = type_desc_from_type<long double>();
+          conv_size = float_type_desc(lm);
           break;
 #endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
 #ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
@@ -682,6 +680,38 @@ template <typename ArgProvider> class Parser {
 #endif // LIBC_COPT_PRINTF_DISABLE_INDEX_MODE
 };
 
+#ifdef LIBC_PRINTF_DEFINE_MODULAR
+template <typename ArgParser>
+void Parser<ArgParser>::write_float_arg_val(FormatSection &section,
+                                            LengthModifier lm,
+                                            size_t conv_index) {
+  if (lm != LengthModifier::L) {
+    WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, double, conv_index);
+  } else {
+    WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, long double, conv_index);
+  }
+}
+
+template <typename ArgParser>
+TypeDesc Parser<ArgParser>::float_type_desc(LengthModifier lm) {
+  if (lm != LengthModifier::L)
+    return type_desc_from_type<double>();
+  else
+    return type_desc_from_type<long double>();
+}
+
+template <typename ArgParser>
+bool Parser<ArgParser>::advance_arg_if_float(TypeDesc cur_type_desc) {
+  if (cur_type_desc == type_desc_from_type<double>())
+    args_cur.template next_var<double>();
+  else if (cur_type_desc == type_desc_from_type<long double>())
+    args_cur.template next_var<long double>();
+  else
+    return false;
+  return true;
+}
+#endif
+
 } // namespace printf_core
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/src/stdio/printf_core/printf_config.h 
b/libc/src/stdio/printf_core/printf_config.h
index 8a48abdd170ec..8f6ae8b41bc92 100644
--- a/libc/src/stdio/printf_core/printf_config.h
+++ b/libc/src/stdio/printf_core/printf_config.h
@@ -48,4 +48,11 @@
 
 // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
 
+#ifdef LIBC_COPT_PRINTF_MODULAR
+#define LIBC_PRINTF_MODULAR_DECL [[gnu::weak]]
+#else
+#define LIBC_PRINTF_MODULAR_DECL LIBC_INLINE
+#define LIBC_PRINTF_DEFINE_MODULAR
+#endif
+
 #endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_PRINTF_CONFIG_H
diff --git a/libc/src/stdio/printf_core/printf_main.h 
b/libc/src/stdio/printf_core/printf_main.h
index 57f29858d5298..c77922bb4f044 100644
--- a/libc/src/stdio/printf_core/printf_main.h
+++ b/libc/src/stdio/printf_core/printf_main.h
@@ -22,8 +22,8 @@ namespace LIBC_NAMESPACE_DECL {
 namespace printf_core {
 
 template <WriteMode write_mode>
-int printf_main(Writer<write_mode> *writer, const char *__restrict str,
-                internal::ArgList &args) {
+int printf_main_modular(Writer<write_mode> *writer, const char *__restrict str,
+                        internal::ArgList &args) {
   Parser<internal::ArgList> parser(str, args);
   int result = 0;
   for (FormatSection cur_section = parser.get_next_section();
@@ -41,6 +41,15 @@ int printf_main(Writer<write_mode> *writer, const char 
*__restrict str,
   return writer->get_chars_written();
 }
 
+template <WriteMode write_mode>
+int printf_main(Writer<write_mode> *writer, const char *__restrict str,
+                internal::ArgList &args) {
+#ifdef LIBC_COPT_PRINTF_MODULAR
+  __asm__ __volatile__ (".reloc ., BFD_RELOC_NONE, __printf_float");
+#endif
+  return printf_main_modular(writer, str, args);
+}
+
 } // namespace printf_core
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/src/stdio/printf_core/vfprintf_internal.h 
b/libc/src/stdio/printf_core/vfprintf_internal.h
index 630de9d9d43dd..c9d6fce458409 100644
--- a/libc/src/stdio/printf_core/vfprintf_internal.h
+++ b/libc/src/stdio/printf_core/vfprintf_internal.h
@@ -67,7 +67,7 @@ LIBC_INLINE int file_write_hook(cpp::string_view new_str, 
void *fp) {
   return WRITE_OK;
 }
 
-LIBC_INLINE int vfprintf_internal(::FILE *__restrict stream,
+LIBC_INLINE int vfprintf_internal_modular(::FILE *__restrict stream,
                                   const char *__restrict format,
                                   internal::ArgList &args) {
   constexpr size_t BUFF_SIZE = 1024;
@@ -76,7 +76,7 @@ LIBC_INLINE int vfprintf_internal(::FILE *__restrict stream,
       buffer, BUFF_SIZE, &file_write_hook, reinterpret_cast<void *>(stream));
   Writer writer(wb);
   internal::flockfile(stream);
-  int retval = printf_main(&writer, format, args);
+  int retval = printf_main_modular(&writer, format, args);
   int flushval = wb.overflow_write("");
   if (flushval != WRITE_OK)
     retval = flushval;
@@ -84,6 +84,15 @@ LIBC_INLINE int vfprintf_internal(::FILE *__restrict stream,
   return retval;
 }
 
+LIBC_INLINE int vfprintf_internal(::FILE *__restrict stream,
+                                  const char *__restrict format,
+                                  internal::ArgList &args) {
+#ifdef LIBC_COPT_PRINTF_SPLIT
+  __asm__ __volatile__(".reloc ., BFD_RELOC_NONE, __printf_float");
+#endif
+  return vfprintf_internal_modular(stream, format, args);
+}
+
 } // namespace printf_core
 } // namespace LIBC_NAMESPACE_DECL
 

_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to