forked from OSchip/llvm-project
[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
This commit is contained in:
parent
535b507ba5
commit
3b0c78fe3b
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue