[libc-commits] [libc] 3b0c78f - [libc][nfc] move printf inf/nan to separate function

Michael Jones via libc-commits libc-commits at lists.llvm.org
Fri Jul 22 10:29:41 PDT 2022


Author: Michael Jones
Date: 2022-07-22T10:29:35-07:00
New Revision: 3b0c78fe3bc9e20061e38935ca6d4fb435027f41

URL: https://github.com/llvm/llvm-project/commit/3b0c78fe3bc9e20061e38935ca6d4fb435027f41
DIFF: https://github.com/llvm/llvm-project/commit/3b0c78fe3bc9e20061e38935ca6d4fb435027f41.diff

LOG: [libc][nfc] move printf inf/nan to separate function

The floating point functions all use the same inf and nan formatting. By
separating this functionality out of the %a conversion I make it
available for reuse by %f/e/g.

Reviewed By: lntue, sivachandra

Differential Revision: https://reviews.llvm.org/D129665

Added: 
    libc/src/stdio/printf_core/float_inf_nan_converter.h

Modified: 
    libc/src/stdio/printf_core/CMakeLists.txt
    libc/src/stdio/printf_core/float_hex_converter.h

Removed: 
    


################################################################################
diff  --git a/libc/src/stdio/printf_core/CMakeLists.txt b/libc/src/stdio/printf_core/CMakeLists.txt
index be0734fcfe952..01414cd4a8b27 100644
--- a/libc/src/stdio/printf_core/CMakeLists.txt
+++ b/libc/src/stdio/printf_core/CMakeLists.txt
@@ -67,6 +67,7 @@ add_object_library(
     ptr_converter.h
     oct_converter.h
     write_int_converter.h
+    float_inf_nan_converter.h
     float_hex_converter.h
   DEPENDS
     .writer

diff  --git a/libc/src/stdio/printf_core/float_hex_converter.h b/libc/src/stdio/printf_core/float_hex_converter.h
index a5daeaab6971d..0844f4cb0e809 100644
--- a/libc/src/stdio/printf_core/float_hex_converter.h
+++ b/libc/src/stdio/printf_core/float_hex_converter.h
@@ -13,6 +13,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/stdio/printf_core/converter_utils.h"
 #include "src/stdio/printf_core/core_structs.h"
+#include "src/stdio/printf_core/float_inf_nan_converter.h"
 #include "src/stdio/printf_core/writer.h"
 
 #include <inttypes.h>
@@ -55,6 +56,9 @@ int inline convert_float_hex_exp(Writer *writer, const FormatSection &to_conv) {
     is_inf_or_nan = float_bits.is_inf_or_nan();
   }
 
+  if (is_inf_or_nan)
+    return convert_inf_nan(writer, to_conv);
+
   char sign_char = 0;
 
   if (is_negative)
@@ -65,34 +69,6 @@ int inline convert_float_hex_exp(Writer *writer, const FormatSection &to_conv) {
            FormatFlags::SPACE_PREFIX)
     sign_char = ' ';
 
-  // TODO: move the inf/nan handling to a seperate conversion, since the
-  // functionality is identical accross all float conversions.
-  if (is_inf_or_nan) {
-    // Both "inf" and "nan" are the same number of characters, being 3.
-    int padding = to_conv.min_width - (sign_char > 0 ? 1 : 0) - 3;
-
-    // The right justified pattern is (spaces), (sign), inf/nan
-    // The left justified pattern is  (sign), inf/nan, (spaces)
-
-    if (padding > 0 && ((to_conv.flags & FormatFlags::LEFT_JUSTIFIED) !=
-                        FormatFlags::LEFT_JUSTIFIED))
-      RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', padding));
-
-    if (sign_char)
-      RET_IF_RESULT_NEGATIVE(writer->write(&sign_char, 1));
-    if (mantissa == 0) { // inf
-      RET_IF_RESULT_NEGATIVE(writer->write((a == 'a' ? "inf" : "INF"), 3));
-    } else { // nan
-      RET_IF_RESULT_NEGATIVE(writer->write((a == 'a' ? "nan" : "NAN"), 3));
-    }
-
-    if (padding > 0 && ((to_conv.flags & FormatFlags::LEFT_JUSTIFIED) ==
-                        FormatFlags::LEFT_JUSTIFIED))
-      RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', padding));
-
-    return WRITE_OK;
-  }
-
   // Handle the exponent for numbers with a 0 exponent
   if (exponent == -exponent_bias) {
     if (mantissa > 0) // Subnormals

diff  --git a/libc/src/stdio/printf_core/float_inf_nan_converter.h b/libc/src/stdio/printf_core/float_inf_nan_converter.h
new file mode 100644
index 0000000000000..640612e1b6d4d
--- /dev/null
+++ b/libc/src/stdio/printf_core/float_inf_nan_converter.h
@@ -0,0 +1,82 @@
+//===-- Inf or Nan Converter for printf -------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_INF_NAN_CONVERTER_H
+#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_INF_NAN_CONVERTER_H
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/stdio/printf_core/converter_utils.h"
+#include "src/stdio/printf_core/core_structs.h"
+#include "src/stdio/printf_core/writer.h"
+
+#include <inttypes.h>
+#include <stddef.h>
+
+namespace __llvm_libc {
+namespace printf_core {
+
+using MantissaInt = fputil::FPBits<long double>::UIntType;
+
+int inline convert_inf_nan(Writer *writer, const FormatSection &to_conv) {
+  // All of the letters will be defined relative to variable a, which will be
+  // the appropriate case based on the case of the conversion.
+  const char a = (to_conv.conv_name & 32) | 'A';
+
+  bool is_negative;
+  MantissaInt mantissa;
+  if (to_conv.length_modifier == LengthModifier::L) {
+    fputil::FPBits<long double>::UIntType float_raw = to_conv.conv_val_raw;
+    fputil::FPBits<long double> float_bits(float_raw);
+    is_negative = float_bits.get_sign();
+    mantissa = float_bits.get_explicit_mantissa();
+  } else {
+    fputil::FPBits<double>::UIntType float_raw = to_conv.conv_val_raw;
+    fputil::FPBits<double> float_bits(float_raw);
+    is_negative = float_bits.get_sign();
+    mantissa = float_bits.get_explicit_mantissa();
+  }
+
+  char sign_char = 0;
+
+  if (is_negative)
+    sign_char = '-';
+  else if ((to_conv.flags & FormatFlags::FORCE_SIGN) == FormatFlags::FORCE_SIGN)
+    sign_char = '+'; // FORCE_SIGN has precedence over SPACE_PREFIX
+  else if ((to_conv.flags & FormatFlags::SPACE_PREFIX) ==
+           FormatFlags::SPACE_PREFIX)
+    sign_char = ' ';
+
+  // Both "inf" and "nan" are the same number of characters, being 3.
+  int padding = to_conv.min_width - (sign_char > 0 ? 1 : 0) - 3;
+
+  // The right justified pattern is (spaces), (sign), inf/nan
+  // The left justified pattern is  (sign), inf/nan, (spaces)
+
+  if (padding > 0 && ((to_conv.flags & FormatFlags::LEFT_JUSTIFIED) !=
+                      FormatFlags::LEFT_JUSTIFIED))
+    RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', padding));
+
+  if (sign_char)
+    RET_IF_RESULT_NEGATIVE(writer->write(&sign_char, 1));
+  if (mantissa == 0) { // inf
+    RET_IF_RESULT_NEGATIVE(writer->write((a == 'a' ? "inf" : "INF"), 3));
+  } else { // nan
+    RET_IF_RESULT_NEGATIVE(writer->write((a == 'a' ? "nan" : "NAN"), 3));
+  }
+
+  if (padding > 0 && ((to_conv.flags & FormatFlags::LEFT_JUSTIFIED) ==
+                      FormatFlags::LEFT_JUSTIFIED))
+    RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', padding));
+
+  return WRITE_OK;
+}
+
+} // namespace printf_core
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_INF_NAN_CONVERTER_H


        


More information about the libc-commits mailing list