From d26cd63ad6d2f131aa6dbdce53f5e09eabfee1cb Mon Sep 17 00:00:00 2001 From: LIU Zhiwei Date: Sat, 27 Feb 2021 16:39:52 -0500 Subject: [PATCH] softfloat: Define misc operations for bfloat16 Backports 5ebf5f4be66c378fd5f3dee85f54dd4942171d57 --- qemu/aarch64.h | 2 ++ qemu/aarch64eb.h | 2 ++ qemu/arm.h | 2 ++ qemu/armeb.h | 2 ++ qemu/fpu/softfloat-specialize.inc.c | 38 +++++++++++++++++++++++ qemu/header_gen.py | 2 ++ qemu/include/fpu/softfloat.h | 48 +++++++++++++++++++++++++++++ qemu/m68k.h | 2 ++ qemu/mips.h | 2 ++ qemu/mips64.h | 2 ++ qemu/mips64el.h | 2 ++ qemu/mipsel.h | 2 ++ qemu/powerpc.h | 2 ++ qemu/riscv32.h | 2 ++ qemu/riscv64.h | 2 ++ qemu/sparc.h | 2 ++ qemu/sparc64.h | 2 ++ qemu/x86_64.h | 2 ++ 18 files changed, 118 insertions(+) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 8c09415c..8f13e726 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_aarch64 #define bfloat16_compare bfloat16_compare_aarch64 #define bfloat16_compare_quiet bfloat16_compare_quiet_aarch64 +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_aarch64 +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_aarch64 #define bfloat16_silence_nan bfloat16_silence_nan_aarch64 #define bfloat16_default_nan bfloat16_default_nan_aarch64 #define bfloat16_to_float32 bfloat16_to_float32_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index dd84fd67..0c9813bb 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_aarch64eb #define bfloat16_compare bfloat16_compare_aarch64eb #define bfloat16_compare_quiet bfloat16_compare_quiet_aarch64eb +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_aarch64eb +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_aarch64eb #define bfloat16_silence_nan bfloat16_silence_nan_aarch64eb #define bfloat16_default_nan bfloat16_default_nan_aarch64eb #define bfloat16_to_float32 bfloat16_to_float32_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 659a78b7..61fbf4b5 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_arm #define bfloat16_compare bfloat16_compare_arm #define bfloat16_compare_quiet bfloat16_compare_quiet_arm +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_arm +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_arm #define bfloat16_silence_nan bfloat16_silence_nan_arm #define bfloat16_default_nan bfloat16_default_nan_arm #define bfloat16_to_float32 bfloat16_to_float32_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index d4bf59be..687dad6f 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_armeb #define bfloat16_compare bfloat16_compare_armeb #define bfloat16_compare_quiet bfloat16_compare_quiet_armeb +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_armeb +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_armeb #define bfloat16_silence_nan bfloat16_silence_nan_armeb #define bfloat16_default_nan bfloat16_default_nan_armeb #define bfloat16_to_float32 bfloat16_to_float32_armeb diff --git a/qemu/fpu/softfloat-specialize.inc.c b/qemu/fpu/softfloat-specialize.inc.c index 0964a542..eab50a50 100644 --- a/qemu/fpu/softfloat-specialize.inc.c +++ b/qemu/fpu/softfloat-specialize.inc.c @@ -265,6 +265,25 @@ bool float16_is_quiet_nan(float16 a_, float_status *status) } } +/*---------------------------------------------------------------------------- +| Returns 1 if the bfloat16 value `a' is a quiet +| NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +bool bfloat16_is_quiet_nan(bfloat16 a_, float_status *status) +{ + if (no_signaling_nans(status)) { + return bfloat16_is_any_nan(a_); + } else { + uint16_t a = a_; + if (snan_bit_is_one(status)) { + return (((a >> 6) & 0x1FF) == 0x1FE) && (a & 0x3F); + } else { + return ((a >> 6) & 0x1FF) == 0x1FF; + } + } +} + /*---------------------------------------------------------------------------- | Returns 1 if the half-precision floating-point value `a' is a signaling | NaN; otherwise returns 0. @@ -284,6 +303,25 @@ bool float16_is_signaling_nan(float16 a_, float_status *status) } } +/*---------------------------------------------------------------------------- +| Returns 1 if the bfloat16 value `a' is a signaling +| NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +bool bfloat16_is_signaling_nan(bfloat16 a_, float_status *status) +{ + if (no_signaling_nans(status)) { + return 0; + } else { + uint16_t a = a_; + if (snan_bit_is_one(status)) { + return ((a >> 6) & 0x1FF) == 0x1FF; + } else { + return (((a >> 6) & 0x1FF) == 0x1FE) && (a & 0x3F); + } + } +} + /*---------------------------------------------------------------------------- | Returns 1 if the single-precision floating-point value `a' is a quiet | NaN; otherwise returns 0. diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 26493754..4efb3f48 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -219,6 +219,8 @@ symbols = ( 'bfloat16_sqrt', 'bfloat16_compare', 'bfloat16_compare_quiet', + 'bfloat16_is_quiet_nan', + 'bfloat16_is_signaling_nan', 'bfloat16_silence_nan', 'bfloat16_default_nan', 'bfloat16_to_float32', diff --git a/qemu/include/fpu/softfloat.h b/qemu/include/fpu/softfloat.h index d78a0ae0..552d102f 100644 --- a/qemu/include/fpu/softfloat.h +++ b/qemu/include/fpu/softfloat.h @@ -426,9 +426,57 @@ bfloat16 bfloat16_sqrt(bfloat16, float_status *status); FloatRelation bfloat16_compare(bfloat16, bfloat16, float_status *status); FloatRelation bfloat16_compare_quiet(bfloat16, bfloat16, float_status *status); +bool bfloat16_is_quiet_nan(bfloat16, float_status *status); +bool bfloat16_is_signaling_nan(bfloat16, float_status *status); bfloat16 bfloat16_silence_nan(bfloat16, float_status *status); bfloat16 bfloat16_default_nan(float_status *status); +static inline bool bfloat16_is_any_nan(bfloat16 a) +{ + return ((a & ~0x8000) > 0x7F80); +} + +static inline bool bfloat16_is_neg(bfloat16 a) +{ + return a >> 15; +} + +static inline bool bfloat16_is_infinity(bfloat16 a) +{ + return (a & 0x7fff) == 0x7F80; +} + +static inline bool bfloat16_is_zero(bfloat16 a) +{ + return (a & 0x7fff) == 0; +} + +static inline bool bfloat16_is_zero_or_denormal(bfloat16 a) +{ + return (a & 0x7F80) == 0; +} + +static inline bool bfloat16_is_normal(bfloat16 a) +{ + return (((a >> 7) + 1) & 0xff) >= 2; +} + +static inline bfloat16 bfloat16_abs(bfloat16 a) +{ + /* Note that abs does *not* handle NaN specially, nor does + * it flush denormal inputs to zero. + */ + return a & 0x7fff; +} + +static inline bfloat16 bfloat16_chs(bfloat16 a) +{ + /* Note that chs does *not* handle NaN specially, nor does + * it flush denormal inputs to zero. + */ + return a ^ 0x8000; +} + static inline bfloat16 bfloat16_set_sign(bfloat16 a, int sign) { return (a & 0x7fff) | (sign << 15); diff --git a/qemu/m68k.h b/qemu/m68k.h index 56943144..fddcaea8 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_m68k #define bfloat16_compare bfloat16_compare_m68k #define bfloat16_compare_quiet bfloat16_compare_quiet_m68k +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_m68k +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_m68k #define bfloat16_silence_nan bfloat16_silence_nan_m68k #define bfloat16_default_nan bfloat16_default_nan_m68k #define bfloat16_to_float32 bfloat16_to_float32_m68k diff --git a/qemu/mips.h b/qemu/mips.h index e3d616ba..37fbfc29 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_mips #define bfloat16_compare bfloat16_compare_mips #define bfloat16_compare_quiet bfloat16_compare_quiet_mips +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_mips +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_mips #define bfloat16_silence_nan bfloat16_silence_nan_mips #define bfloat16_default_nan bfloat16_default_nan_mips #define bfloat16_to_float32 bfloat16_to_float32_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 7ad37bd0..3abe9173 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_mips64 #define bfloat16_compare bfloat16_compare_mips64 #define bfloat16_compare_quiet bfloat16_compare_quiet_mips64 +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_mips64 +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_mips64 #define bfloat16_silence_nan bfloat16_silence_nan_mips64 #define bfloat16_default_nan bfloat16_default_nan_mips64 #define bfloat16_to_float32 bfloat16_to_float32_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index f8a686d9..67ca4e38 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_mips64el #define bfloat16_compare bfloat16_compare_mips64el #define bfloat16_compare_quiet bfloat16_compare_quiet_mips64el +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_mips64el +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_mips64el #define bfloat16_silence_nan bfloat16_silence_nan_mips64el #define bfloat16_default_nan bfloat16_default_nan_mips64el #define bfloat16_to_float32 bfloat16_to_float32_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index e4dfc241..e1394210 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_mipsel #define bfloat16_compare bfloat16_compare_mipsel #define bfloat16_compare_quiet bfloat16_compare_quiet_mipsel +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_mipsel +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_mipsel #define bfloat16_silence_nan bfloat16_silence_nan_mipsel #define bfloat16_default_nan bfloat16_default_nan_mipsel #define bfloat16_to_float32 bfloat16_to_float32_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 5fc82019..52273cc0 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_powerpc #define bfloat16_compare bfloat16_compare_powerpc #define bfloat16_compare_quiet bfloat16_compare_quiet_powerpc +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_powerpc +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_powerpc #define bfloat16_silence_nan bfloat16_silence_nan_powerpc #define bfloat16_default_nan bfloat16_default_nan_powerpc #define bfloat16_to_float32 bfloat16_to_float32_powerpc diff --git a/qemu/riscv32.h b/qemu/riscv32.h index 19d0597e..de828b92 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_riscv32 #define bfloat16_compare bfloat16_compare_riscv32 #define bfloat16_compare_quiet bfloat16_compare_quiet_riscv32 +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_riscv32 +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_riscv32 #define bfloat16_silence_nan bfloat16_silence_nan_riscv32 #define bfloat16_default_nan bfloat16_default_nan_riscv32 #define bfloat16_to_float32 bfloat16_to_float32_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index 35209103..e82c8922 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_riscv64 #define bfloat16_compare bfloat16_compare_riscv64 #define bfloat16_compare_quiet bfloat16_compare_quiet_riscv64 +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_riscv64 +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_riscv64 #define bfloat16_silence_nan bfloat16_silence_nan_riscv64 #define bfloat16_default_nan bfloat16_default_nan_riscv64 #define bfloat16_to_float32 bfloat16_to_float32_riscv64 diff --git a/qemu/sparc.h b/qemu/sparc.h index b1bef5f5..06ba1c6d 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_sparc #define bfloat16_compare bfloat16_compare_sparc #define bfloat16_compare_quiet bfloat16_compare_quiet_sparc +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_sparc +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_sparc #define bfloat16_silence_nan bfloat16_silence_nan_sparc #define bfloat16_default_nan bfloat16_default_nan_sparc #define bfloat16_to_float32 bfloat16_to_float32_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index e08aeb85..99620270 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_sparc64 #define bfloat16_compare bfloat16_compare_sparc64 #define bfloat16_compare_quiet bfloat16_compare_quiet_sparc64 +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_sparc64 +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_sparc64 #define bfloat16_silence_nan bfloat16_silence_nan_sparc64 #define bfloat16_default_nan bfloat16_default_nan_sparc64 #define bfloat16_to_float32 bfloat16_to_float32_sparc64 diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 27717f3a..a8f4f50b 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -213,6 +213,8 @@ #define bfloat16_sqrt bfloat16_sqrt_x86_64 #define bfloat16_compare bfloat16_compare_x86_64 #define bfloat16_compare_quiet bfloat16_compare_quiet_x86_64 +#define bfloat16_is_quiet_nan bfloat16_is_quiet_nan_x86_64 +#define bfloat16_is_signaling_nan bfloat16_is_signaling_nan_x86_64 #define bfloat16_silence_nan bfloat16_silence_nan_x86_64 #define bfloat16_default_nan bfloat16_default_nan_x86_64 #define bfloat16_to_float32 bfloat16_to_float32_x86_64