diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 74e8107c..07ea7f45 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -496,6 +496,7 @@ #define float16_mul float16_mul_aarch64 #define float16_muladd float16_muladd_aarch64 #define float16_round_to_int float16_round_to_int_aarch64 +#define float16_scalbn float16_scalbn_aarch64 #define float16_squash_input_denormal float16_squash_input_denormal_aarch64 #define float16_sub float16_sub_aarch64 #define float16_to_int16 float16_to_int16_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index fb4ac03c..11a09015 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -496,6 +496,7 @@ #define float16_mul float16_mul_aarch64eb #define float16_muladd float16_muladd_aarch64eb #define float16_round_to_int float16_round_to_int_aarch64eb +#define float16_scalbn float16_scalbn_aarch64eb #define float16_squash_input_denormal float16_squash_input_denormal_aarch64eb #define float16_sub float16_sub_aarch64eb #define float16_to_int16 float16_to_int16_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 0a1faad5..8bd378ac 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -496,6 +496,7 @@ #define float16_mul float16_mul_arm #define float16_muladd float16_muladd_arm #define float16_round_to_int float16_round_to_int_arm +#define float16_scalbn float16_scalbn_arm #define float16_squash_input_denormal float16_squash_input_denormal_arm #define float16_sub float16_sub_arm #define float16_to_int16 float16_to_int16_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 689e9314..a94db789 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -496,6 +496,7 @@ #define float16_mul float16_mul_armeb #define float16_muladd float16_muladd_armeb #define float16_round_to_int float16_round_to_int_armeb +#define float16_scalbn float16_scalbn_armeb #define float16_squash_input_denormal float16_squash_input_denormal_armeb #define float16_sub float16_sub_armeb #define float16_to_int16 float16_to_int16_armeb diff --git a/qemu/fpu/softfloat.c b/qemu/fpu/softfloat.c index 03a3ab97..319f1fc4 100644 --- a/qemu/fpu/softfloat.c +++ b/qemu/fpu/softfloat.c @@ -1664,6 +1664,39 @@ float64 uint16_to_float64(uint16_t a, float_status *status) return uint64_to_float64(a, status); } +/* Multiply A by 2 raised to the power N. */ +static FloatParts scalbn_decomposed(FloatParts a, int n, float_status *s) +{ + if (unlikely(is_nan(a.cls))) { + return return_nan(a, s); + } + if (a.cls == float_class_normal) { + a.exp += n; + } + return a; +} + +float16 float16_scalbn(float16 a, int n, float_status *status) +{ + FloatParts pa = float16_unpack_canonical(a, status); + FloatParts pr = scalbn_decomposed(pa, n, status); + return float16_round_pack_canonical(pr, status); +} + +float32 float32_scalbn(float32 a, int n, float_status *status) +{ + FloatParts pa = float32_unpack_canonical(a, status); + FloatParts pr = scalbn_decomposed(pa, n, status); + return float32_round_pack_canonical(pr, status); +} + +float64 float64_scalbn(float64 a, int n, float_status *status) +{ + FloatParts pa = float64_unpack_canonical(a, status); + FloatParts pr = scalbn_decomposed(pa, n, status); + return float64_round_pack_canonical(pr, status); +} + /*---------------------------------------------------------------------------- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to the @@ -6905,80 +6938,6 @@ float ## s float ## s ## _maxnummag(float ## s a, float ## s b, float_status *st MINMAX(32) MINMAX(64) - -/* Multiply A by 2 raised to the power N. */ -float32 float32_scalbn(float32 a, int n, float_status *status) -{ - flag aSign; - int16_t aExp; - uint32_t aSig; - - a = float32_squash_input_denormal(a, status); - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - - if ( aExp == 0xFF ) { - if ( aSig ) { - return propagateFloat32NaN( a, a, status ); - } - return a; - } - if (aExp != 0) { - aSig |= 0x00800000; - } else if (aSig == 0) { - return a; - } else { - aExp++; - } - - if (n > 0x200) { - n = 0x200; - } else if (n < -0x200) { - n = -0x200; - } - - aExp += n - 1; - aSig <<= 7; - return normalizeRoundAndPackFloat32( aSign, aExp, aSig, status ); -} - -float64 float64_scalbn(float64 a, int n, float_status *status) -{ - flag aSign; - int16_t aExp; - uint64_t aSig; - - a = float64_squash_input_denormal(a, status); - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - - if ( aExp == 0x7FF ) { - if ( aSig ) { - return propagateFloat64NaN( a, a, status ); - } - return a; - } - if (aExp != 0) { - aSig |= LIT64( 0x0010000000000000 ); - } else if (aSig == 0) { - return a; - } else { - aExp++; - } - - if (n > 0x1000) { - n = 0x1000; - } else if (n < -0x1000) { - n = -0x1000; - } - - aExp += n - 1; - aSig <<= 10; - return normalizeRoundAndPackFloat64( aSign, aExp, aSig, status ); -} - floatx80 floatx80_scalbn(floatx80 a, int n, float_status *status) { flag aSign; diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 4d37c2c6..b94a1d20 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -502,6 +502,7 @@ symbols = ( 'float16_mul', 'float16_muladd', 'float16_round_to_int', + 'float16_scalbn', 'float16_squash_input_denormal', 'float16_sub', 'float16_to_int16', diff --git a/qemu/include/fpu/softfloat.h b/qemu/include/fpu/softfloat.h index 7c2c32a1..b39d2c21 100644 --- a/qemu/include/fpu/softfloat.h +++ b/qemu/include/fpu/softfloat.h @@ -251,6 +251,7 @@ float16 float16_sub(float16, float16, float_status *status); float16 float16_mul(float16, float16, float_status *status); float16 float16_muladd(float16, float16, float16, int, float_status *status); float16 float16_div(float16, float16, float_status *status); +float16 float16_scalbn(float16, int, float_status *status); int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); diff --git a/qemu/m68k.h b/qemu/m68k.h index 0758e36e..6a8a580b 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -496,6 +496,7 @@ #define float16_mul float16_mul_m68k #define float16_muladd float16_muladd_m68k #define float16_round_to_int float16_round_to_int_m68k +#define float16_scalbn float16_scalbn_m68k #define float16_squash_input_denormal float16_squash_input_denormal_m68k #define float16_sub float16_sub_m68k #define float16_to_int16 float16_to_int16_m68k diff --git a/qemu/mips.h b/qemu/mips.h index eb2af058..a6b7f215 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -496,6 +496,7 @@ #define float16_mul float16_mul_mips #define float16_muladd float16_muladd_mips #define float16_round_to_int float16_round_to_int_mips +#define float16_scalbn float16_scalbn_mips #define float16_squash_input_denormal float16_squash_input_denormal_mips #define float16_sub float16_sub_mips #define float16_to_int16 float16_to_int16_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 5cc50f9a..06ba754a 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -496,6 +496,7 @@ #define float16_mul float16_mul_mips64 #define float16_muladd float16_muladd_mips64 #define float16_round_to_int float16_round_to_int_mips64 +#define float16_scalbn float16_scalbn_mips64 #define float16_squash_input_denormal float16_squash_input_denormal_mips64 #define float16_sub float16_sub_mips64 #define float16_to_int16 float16_to_int16_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 1387d6f4..782fa295 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -496,6 +496,7 @@ #define float16_mul float16_mul_mips64el #define float16_muladd float16_muladd_mips64el #define float16_round_to_int float16_round_to_int_mips64el +#define float16_scalbn float16_scalbn_mips64el #define float16_squash_input_denormal float16_squash_input_denormal_mips64el #define float16_sub float16_sub_mips64el #define float16_to_int16 float16_to_int16_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 4ca955c6..88ebbe11 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -496,6 +496,7 @@ #define float16_mul float16_mul_mipsel #define float16_muladd float16_muladd_mipsel #define float16_round_to_int float16_round_to_int_mipsel +#define float16_scalbn float16_scalbn_mipsel #define float16_squash_input_denormal float16_squash_input_denormal_mipsel #define float16_sub float16_sub_mipsel #define float16_to_int16 float16_to_int16_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index e956764c..fb3d870a 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -496,6 +496,7 @@ #define float16_mul float16_mul_powerpc #define float16_muladd float16_muladd_powerpc #define float16_round_to_int float16_round_to_int_powerpc +#define float16_scalbn float16_scalbn_powerpc #define float16_squash_input_denormal float16_squash_input_denormal_powerpc #define float16_sub float16_sub_powerpc #define float16_to_int16 float16_to_int16_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index 88f6853a..e46019b9 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -496,6 +496,7 @@ #define float16_mul float16_mul_sparc #define float16_muladd float16_muladd_sparc #define float16_round_to_int float16_round_to_int_sparc +#define float16_scalbn float16_scalbn_sparc #define float16_squash_input_denormal float16_squash_input_denormal_sparc #define float16_sub float16_sub_sparc #define float16_to_int16 float16_to_int16_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 7d430ca7..018bafaf 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -496,6 +496,7 @@ #define float16_mul float16_mul_sparc64 #define float16_muladd float16_muladd_sparc64 #define float16_round_to_int float16_round_to_int_sparc64 +#define float16_scalbn float16_scalbn_sparc64 #define float16_squash_input_denormal float16_squash_input_denormal_sparc64 #define float16_sub float16_sub_sparc64 #define float16_to_int16 float16_to_int16_sparc64 diff --git a/qemu/x86_64.h b/qemu/x86_64.h index efd177c0..330e523d 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -496,6 +496,7 @@ #define float16_mul float16_mul_x86_64 #define float16_muladd float16_muladd_x86_64 #define float16_round_to_int float16_round_to_int_x86_64 +#define float16_scalbn float16_scalbn_x86_64 #define float16_squash_input_denormal float16_squash_input_denormal_x86_64 #define float16_sub float16_sub_x86_64 #define float16_to_int16 float16_to_int16_x86_64