arm/helper.c: re-factor recpe and add recepe_f16

It looks like the ARM ARM has simplified the pseudo code for the
calculation which is done on a fixed point 9 bit integer maths. So
while adding f16 we can also clean this up to be a little less heavy
on the floating point and just return the fractional part and leave
the calle's to do the final packing of the result.

Backports commit 5eb70735af1c0b607bf2671a53aff3710cc1672f from qemu
This commit is contained in:
Alex Bennée 2018-03-08 18:57:00 -05:00 committed by Lioncash
parent c590ff441c
commit 5f3864c2c2
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
16 changed files with 143 additions and 140 deletions

View file

@ -1062,9 +1062,6 @@
#define gen_helper_qsub8 gen_helper_qsub8_aarch64 #define gen_helper_qsub8 gen_helper_qsub8_aarch64
#define gen_helper_qsubaddx gen_helper_qsubaddx_aarch64 #define gen_helper_qsubaddx gen_helper_qsubaddx_aarch64
#define gen_helper_rbit gen_helper_rbit_aarch64 #define gen_helper_rbit gen_helper_rbit_aarch64
#define gen_helper_recpe_f32 gen_helper_recpe_f32_aarch64
#define gen_helper_recpe_u32 gen_helper_recpe_u32_aarch64
#define gen_helper_recps_f32 gen_helper_recps_f32_aarch64
#define gen_helper_rintd gen_helper_rintd_aarch64 #define gen_helper_rintd gen_helper_rintd_aarch64
#define gen_helper_rintd_exact gen_helper_rintd_exact_aarch64 #define gen_helper_rintd_exact gen_helper_rintd_exact_aarch64
#define gen_helper_rints gen_helper_rints_aarch64 #define gen_helper_rints gen_helper_rints_aarch64
@ -2119,6 +2116,7 @@
#define helper_qsubaddx helper_qsubaddx_aarch64 #define helper_qsubaddx helper_qsubaddx_aarch64
#define helper_raise_exception helper_raise_exception_aarch64 #define helper_raise_exception helper_raise_exception_aarch64
#define helper_rbit helper_rbit_aarch64 #define helper_rbit helper_rbit_aarch64
#define helper_recpe_f16 helper_recpe_f16_aarch64
#define helper_recpe_f32 helper_recpe_f32_aarch64 #define helper_recpe_f32 helper_recpe_f32_aarch64
#define helper_recpe_f64 helper_recpe_f64_aarch64 #define helper_recpe_f64 helper_recpe_f64_aarch64
#define helper_recpe_u32 helper_recpe_u32_aarch64 #define helper_recpe_u32 helper_recpe_u32_aarch64

View file

@ -1062,9 +1062,6 @@
#define gen_helper_qsub8 gen_helper_qsub8_aarch64eb #define gen_helper_qsub8 gen_helper_qsub8_aarch64eb
#define gen_helper_qsubaddx gen_helper_qsubaddx_aarch64eb #define gen_helper_qsubaddx gen_helper_qsubaddx_aarch64eb
#define gen_helper_rbit gen_helper_rbit_aarch64eb #define gen_helper_rbit gen_helper_rbit_aarch64eb
#define gen_helper_recpe_f32 gen_helper_recpe_f32_aarch64eb
#define gen_helper_recpe_u32 gen_helper_recpe_u32_aarch64eb
#define gen_helper_recps_f32 gen_helper_recps_f32_aarch64eb
#define gen_helper_rintd gen_helper_rintd_aarch64eb #define gen_helper_rintd gen_helper_rintd_aarch64eb
#define gen_helper_rintd_exact gen_helper_rintd_exact_aarch64eb #define gen_helper_rintd_exact gen_helper_rintd_exact_aarch64eb
#define gen_helper_rints gen_helper_rints_aarch64eb #define gen_helper_rints gen_helper_rints_aarch64eb
@ -2119,6 +2116,7 @@
#define helper_qsubaddx helper_qsubaddx_aarch64eb #define helper_qsubaddx helper_qsubaddx_aarch64eb
#define helper_raise_exception helper_raise_exception_aarch64eb #define helper_raise_exception helper_raise_exception_aarch64eb
#define helper_rbit helper_rbit_aarch64eb #define helper_rbit helper_rbit_aarch64eb
#define helper_recpe_f16 helper_recpe_f16_aarch64eb
#define helper_recpe_f32 helper_recpe_f32_aarch64eb #define helper_recpe_f32 helper_recpe_f32_aarch64eb
#define helper_recpe_f64 helper_recpe_f64_aarch64eb #define helper_recpe_f64 helper_recpe_f64_aarch64eb
#define helper_recpe_u32 helper_recpe_u32_aarch64eb #define helper_recpe_u32 helper_recpe_u32_aarch64eb

View file

@ -1062,9 +1062,6 @@
#define gen_helper_qsub8 gen_helper_qsub8_arm #define gen_helper_qsub8 gen_helper_qsub8_arm
#define gen_helper_qsubaddx gen_helper_qsubaddx_arm #define gen_helper_qsubaddx gen_helper_qsubaddx_arm
#define gen_helper_rbit gen_helper_rbit_arm #define gen_helper_rbit gen_helper_rbit_arm
#define gen_helper_recpe_f32 gen_helper_recpe_f32_arm
#define gen_helper_recpe_u32 gen_helper_recpe_u32_arm
#define gen_helper_recps_f32 gen_helper_recps_f32_arm
#define gen_helper_rintd gen_helper_rintd_arm #define gen_helper_rintd gen_helper_rintd_arm
#define gen_helper_rintd_exact gen_helper_rintd_exact_arm #define gen_helper_rintd_exact gen_helper_rintd_exact_arm
#define gen_helper_rints gen_helper_rints_arm #define gen_helper_rints gen_helper_rints_arm
@ -2119,6 +2116,7 @@
#define helper_qsubaddx helper_qsubaddx_arm #define helper_qsubaddx helper_qsubaddx_arm
#define helper_raise_exception helper_raise_exception_arm #define helper_raise_exception helper_raise_exception_arm
#define helper_rbit helper_rbit_arm #define helper_rbit helper_rbit_arm
#define helper_recpe_f16 helper_recpe_f16_arm
#define helper_recpe_f32 helper_recpe_f32_arm #define helper_recpe_f32 helper_recpe_f32_arm
#define helper_recpe_f64 helper_recpe_f64_arm #define helper_recpe_f64 helper_recpe_f64_arm
#define helper_recpe_u32 helper_recpe_u32_arm #define helper_recpe_u32 helper_recpe_u32_arm

View file

@ -1062,9 +1062,6 @@
#define gen_helper_qsub8 gen_helper_qsub8_armeb #define gen_helper_qsub8 gen_helper_qsub8_armeb
#define gen_helper_qsubaddx gen_helper_qsubaddx_armeb #define gen_helper_qsubaddx gen_helper_qsubaddx_armeb
#define gen_helper_rbit gen_helper_rbit_armeb #define gen_helper_rbit gen_helper_rbit_armeb
#define gen_helper_recpe_f32 gen_helper_recpe_f32_armeb
#define gen_helper_recpe_u32 gen_helper_recpe_u32_armeb
#define gen_helper_recps_f32 gen_helper_recps_f32_armeb
#define gen_helper_rintd gen_helper_rintd_armeb #define gen_helper_rintd gen_helper_rintd_armeb
#define gen_helper_rintd_exact gen_helper_rintd_exact_armeb #define gen_helper_rintd_exact gen_helper_rintd_exact_armeb
#define gen_helper_rints gen_helper_rints_armeb #define gen_helper_rints gen_helper_rints_armeb
@ -2119,6 +2116,7 @@
#define helper_qsubaddx helper_qsubaddx_armeb #define helper_qsubaddx helper_qsubaddx_armeb
#define helper_raise_exception helper_raise_exception_armeb #define helper_raise_exception helper_raise_exception_armeb
#define helper_rbit helper_rbit_armeb #define helper_rbit helper_rbit_armeb
#define helper_recpe_f16 helper_recpe_f16_armeb
#define helper_recpe_f32 helper_recpe_f32_armeb #define helper_recpe_f32 helper_recpe_f32_armeb
#define helper_recpe_f64 helper_recpe_f64_armeb #define helper_recpe_f64 helper_recpe_f64_armeb
#define helper_recpe_u32 helper_recpe_u32_armeb #define helper_recpe_u32 helper_recpe_u32_armeb

View file

@ -1068,9 +1068,6 @@ symbols = (
'gen_helper_qsub8', 'gen_helper_qsub8',
'gen_helper_qsubaddx', 'gen_helper_qsubaddx',
'gen_helper_rbit', 'gen_helper_rbit',
'gen_helper_recpe_f32',
'gen_helper_recpe_u32',
'gen_helper_recps_f32',
'gen_helper_rintd', 'gen_helper_rintd',
'gen_helper_rintd_exact', 'gen_helper_rintd_exact',
'gen_helper_rints', 'gen_helper_rints',
@ -2125,6 +2122,7 @@ symbols = (
'helper_qsubaddx', 'helper_qsubaddx',
'helper_raise_exception', 'helper_raise_exception',
'helper_rbit', 'helper_rbit',
'helper_recpe_f16',
'helper_recpe_f32', 'helper_recpe_f32',
'helper_recpe_f64', 'helper_recpe_f64',
'helper_recpe_u32', 'helper_recpe_u32',

View file

@ -1062,9 +1062,6 @@
#define gen_helper_qsub8 gen_helper_qsub8_m68k #define gen_helper_qsub8 gen_helper_qsub8_m68k
#define gen_helper_qsubaddx gen_helper_qsubaddx_m68k #define gen_helper_qsubaddx gen_helper_qsubaddx_m68k
#define gen_helper_rbit gen_helper_rbit_m68k #define gen_helper_rbit gen_helper_rbit_m68k
#define gen_helper_recpe_f32 gen_helper_recpe_f32_m68k
#define gen_helper_recpe_u32 gen_helper_recpe_u32_m68k
#define gen_helper_recps_f32 gen_helper_recps_f32_m68k
#define gen_helper_rintd gen_helper_rintd_m68k #define gen_helper_rintd gen_helper_rintd_m68k
#define gen_helper_rintd_exact gen_helper_rintd_exact_m68k #define gen_helper_rintd_exact gen_helper_rintd_exact_m68k
#define gen_helper_rints gen_helper_rints_m68k #define gen_helper_rints gen_helper_rints_m68k
@ -2119,6 +2116,7 @@
#define helper_qsubaddx helper_qsubaddx_m68k #define helper_qsubaddx helper_qsubaddx_m68k
#define helper_raise_exception helper_raise_exception_m68k #define helper_raise_exception helper_raise_exception_m68k
#define helper_rbit helper_rbit_m68k #define helper_rbit helper_rbit_m68k
#define helper_recpe_f16 helper_recpe_f16_m68k
#define helper_recpe_f32 helper_recpe_f32_m68k #define helper_recpe_f32 helper_recpe_f32_m68k
#define helper_recpe_f64 helper_recpe_f64_m68k #define helper_recpe_f64 helper_recpe_f64_m68k
#define helper_recpe_u32 helper_recpe_u32_m68k #define helper_recpe_u32 helper_recpe_u32_m68k

View file

@ -1062,9 +1062,6 @@
#define gen_helper_qsub8 gen_helper_qsub8_mips #define gen_helper_qsub8 gen_helper_qsub8_mips
#define gen_helper_qsubaddx gen_helper_qsubaddx_mips #define gen_helper_qsubaddx gen_helper_qsubaddx_mips
#define gen_helper_rbit gen_helper_rbit_mips #define gen_helper_rbit gen_helper_rbit_mips
#define gen_helper_recpe_f32 gen_helper_recpe_f32_mips
#define gen_helper_recpe_u32 gen_helper_recpe_u32_mips
#define gen_helper_recps_f32 gen_helper_recps_f32_mips
#define gen_helper_rintd gen_helper_rintd_mips #define gen_helper_rintd gen_helper_rintd_mips
#define gen_helper_rintd_exact gen_helper_rintd_exact_mips #define gen_helper_rintd_exact gen_helper_rintd_exact_mips
#define gen_helper_rints gen_helper_rints_mips #define gen_helper_rints gen_helper_rints_mips
@ -2119,6 +2116,7 @@
#define helper_qsubaddx helper_qsubaddx_mips #define helper_qsubaddx helper_qsubaddx_mips
#define helper_raise_exception helper_raise_exception_mips #define helper_raise_exception helper_raise_exception_mips
#define helper_rbit helper_rbit_mips #define helper_rbit helper_rbit_mips
#define helper_recpe_f16 helper_recpe_f16_mips
#define helper_recpe_f32 helper_recpe_f32_mips #define helper_recpe_f32 helper_recpe_f32_mips
#define helper_recpe_f64 helper_recpe_f64_mips #define helper_recpe_f64 helper_recpe_f64_mips
#define helper_recpe_u32 helper_recpe_u32_mips #define helper_recpe_u32 helper_recpe_u32_mips

View file

@ -1062,9 +1062,6 @@
#define gen_helper_qsub8 gen_helper_qsub8_mips64 #define gen_helper_qsub8 gen_helper_qsub8_mips64
#define gen_helper_qsubaddx gen_helper_qsubaddx_mips64 #define gen_helper_qsubaddx gen_helper_qsubaddx_mips64
#define gen_helper_rbit gen_helper_rbit_mips64 #define gen_helper_rbit gen_helper_rbit_mips64
#define gen_helper_recpe_f32 gen_helper_recpe_f32_mips64
#define gen_helper_recpe_u32 gen_helper_recpe_u32_mips64
#define gen_helper_recps_f32 gen_helper_recps_f32_mips64
#define gen_helper_rintd gen_helper_rintd_mips64 #define gen_helper_rintd gen_helper_rintd_mips64
#define gen_helper_rintd_exact gen_helper_rintd_exact_mips64 #define gen_helper_rintd_exact gen_helper_rintd_exact_mips64
#define gen_helper_rints gen_helper_rints_mips64 #define gen_helper_rints gen_helper_rints_mips64
@ -2119,6 +2116,7 @@
#define helper_qsubaddx helper_qsubaddx_mips64 #define helper_qsubaddx helper_qsubaddx_mips64
#define helper_raise_exception helper_raise_exception_mips64 #define helper_raise_exception helper_raise_exception_mips64
#define helper_rbit helper_rbit_mips64 #define helper_rbit helper_rbit_mips64
#define helper_recpe_f16 helper_recpe_f16_mips64
#define helper_recpe_f32 helper_recpe_f32_mips64 #define helper_recpe_f32 helper_recpe_f32_mips64
#define helper_recpe_f64 helper_recpe_f64_mips64 #define helper_recpe_f64 helper_recpe_f64_mips64
#define helper_recpe_u32 helper_recpe_u32_mips64 #define helper_recpe_u32 helper_recpe_u32_mips64

View file

@ -1062,9 +1062,6 @@
#define gen_helper_qsub8 gen_helper_qsub8_mips64el #define gen_helper_qsub8 gen_helper_qsub8_mips64el
#define gen_helper_qsubaddx gen_helper_qsubaddx_mips64el #define gen_helper_qsubaddx gen_helper_qsubaddx_mips64el
#define gen_helper_rbit gen_helper_rbit_mips64el #define gen_helper_rbit gen_helper_rbit_mips64el
#define gen_helper_recpe_f32 gen_helper_recpe_f32_mips64el
#define gen_helper_recpe_u32 gen_helper_recpe_u32_mips64el
#define gen_helper_recps_f32 gen_helper_recps_f32_mips64el
#define gen_helper_rintd gen_helper_rintd_mips64el #define gen_helper_rintd gen_helper_rintd_mips64el
#define gen_helper_rintd_exact gen_helper_rintd_exact_mips64el #define gen_helper_rintd_exact gen_helper_rintd_exact_mips64el
#define gen_helper_rints gen_helper_rints_mips64el #define gen_helper_rints gen_helper_rints_mips64el
@ -2119,6 +2116,7 @@
#define helper_qsubaddx helper_qsubaddx_mips64el #define helper_qsubaddx helper_qsubaddx_mips64el
#define helper_raise_exception helper_raise_exception_mips64el #define helper_raise_exception helper_raise_exception_mips64el
#define helper_rbit helper_rbit_mips64el #define helper_rbit helper_rbit_mips64el
#define helper_recpe_f16 helper_recpe_f16_mips64el
#define helper_recpe_f32 helper_recpe_f32_mips64el #define helper_recpe_f32 helper_recpe_f32_mips64el
#define helper_recpe_f64 helper_recpe_f64_mips64el #define helper_recpe_f64 helper_recpe_f64_mips64el
#define helper_recpe_u32 helper_recpe_u32_mips64el #define helper_recpe_u32 helper_recpe_u32_mips64el

View file

@ -1062,9 +1062,6 @@
#define gen_helper_qsub8 gen_helper_qsub8_mipsel #define gen_helper_qsub8 gen_helper_qsub8_mipsel
#define gen_helper_qsubaddx gen_helper_qsubaddx_mipsel #define gen_helper_qsubaddx gen_helper_qsubaddx_mipsel
#define gen_helper_rbit gen_helper_rbit_mipsel #define gen_helper_rbit gen_helper_rbit_mipsel
#define gen_helper_recpe_f32 gen_helper_recpe_f32_mipsel
#define gen_helper_recpe_u32 gen_helper_recpe_u32_mipsel
#define gen_helper_recps_f32 gen_helper_recps_f32_mipsel
#define gen_helper_rintd gen_helper_rintd_mipsel #define gen_helper_rintd gen_helper_rintd_mipsel
#define gen_helper_rintd_exact gen_helper_rintd_exact_mipsel #define gen_helper_rintd_exact gen_helper_rintd_exact_mipsel
#define gen_helper_rints gen_helper_rints_mipsel #define gen_helper_rints gen_helper_rints_mipsel
@ -2119,6 +2116,7 @@
#define helper_qsubaddx helper_qsubaddx_mipsel #define helper_qsubaddx helper_qsubaddx_mipsel
#define helper_raise_exception helper_raise_exception_mipsel #define helper_raise_exception helper_raise_exception_mipsel
#define helper_rbit helper_rbit_mipsel #define helper_rbit helper_rbit_mipsel
#define helper_recpe_f16 helper_recpe_f16_mipsel
#define helper_recpe_f32 helper_recpe_f32_mipsel #define helper_recpe_f32 helper_recpe_f32_mipsel
#define helper_recpe_f64 helper_recpe_f64_mipsel #define helper_recpe_f64 helper_recpe_f64_mipsel
#define helper_recpe_u32 helper_recpe_u32_mipsel #define helper_recpe_u32 helper_recpe_u32_mipsel

View file

@ -1062,9 +1062,6 @@
#define gen_helper_qsub8 gen_helper_qsub8_powerpc #define gen_helper_qsub8 gen_helper_qsub8_powerpc
#define gen_helper_qsubaddx gen_helper_qsubaddx_powerpc #define gen_helper_qsubaddx gen_helper_qsubaddx_powerpc
#define gen_helper_rbit gen_helper_rbit_powerpc #define gen_helper_rbit gen_helper_rbit_powerpc
#define gen_helper_recpe_f32 gen_helper_recpe_f32_powerpc
#define gen_helper_recpe_u32 gen_helper_recpe_u32_powerpc
#define gen_helper_recps_f32 gen_helper_recps_f32_powerpc
#define gen_helper_rintd gen_helper_rintd_powerpc #define gen_helper_rintd gen_helper_rintd_powerpc
#define gen_helper_rintd_exact gen_helper_rintd_exact_powerpc #define gen_helper_rintd_exact gen_helper_rintd_exact_powerpc
#define gen_helper_rints gen_helper_rints_powerpc #define gen_helper_rints gen_helper_rints_powerpc
@ -2119,6 +2116,7 @@
#define helper_qsubaddx helper_qsubaddx_powerpc #define helper_qsubaddx helper_qsubaddx_powerpc
#define helper_raise_exception helper_raise_exception_powerpc #define helper_raise_exception helper_raise_exception_powerpc
#define helper_rbit helper_rbit_powerpc #define helper_rbit helper_rbit_powerpc
#define helper_recpe_f16 helper_recpe_f16_powerpc
#define helper_recpe_f32 helper_recpe_f32_powerpc #define helper_recpe_f32 helper_recpe_f32_powerpc
#define helper_recpe_f64 helper_recpe_f64_powerpc #define helper_recpe_f64 helper_recpe_f64_powerpc
#define helper_recpe_u32 helper_recpe_u32_powerpc #define helper_recpe_u32 helper_recpe_u32_powerpc

View file

@ -1062,9 +1062,6 @@
#define gen_helper_qsub8 gen_helper_qsub8_sparc #define gen_helper_qsub8 gen_helper_qsub8_sparc
#define gen_helper_qsubaddx gen_helper_qsubaddx_sparc #define gen_helper_qsubaddx gen_helper_qsubaddx_sparc
#define gen_helper_rbit gen_helper_rbit_sparc #define gen_helper_rbit gen_helper_rbit_sparc
#define gen_helper_recpe_f32 gen_helper_recpe_f32_sparc
#define gen_helper_recpe_u32 gen_helper_recpe_u32_sparc
#define gen_helper_recps_f32 gen_helper_recps_f32_sparc
#define gen_helper_rintd gen_helper_rintd_sparc #define gen_helper_rintd gen_helper_rintd_sparc
#define gen_helper_rintd_exact gen_helper_rintd_exact_sparc #define gen_helper_rintd_exact gen_helper_rintd_exact_sparc
#define gen_helper_rints gen_helper_rints_sparc #define gen_helper_rints gen_helper_rints_sparc
@ -2119,6 +2116,7 @@
#define helper_qsubaddx helper_qsubaddx_sparc #define helper_qsubaddx helper_qsubaddx_sparc
#define helper_raise_exception helper_raise_exception_sparc #define helper_raise_exception helper_raise_exception_sparc
#define helper_rbit helper_rbit_sparc #define helper_rbit helper_rbit_sparc
#define helper_recpe_f16 helper_recpe_f16_sparc
#define helper_recpe_f32 helper_recpe_f32_sparc #define helper_recpe_f32 helper_recpe_f32_sparc
#define helper_recpe_f64 helper_recpe_f64_sparc #define helper_recpe_f64 helper_recpe_f64_sparc
#define helper_recpe_u32 helper_recpe_u32_sparc #define helper_recpe_u32 helper_recpe_u32_sparc

View file

@ -1062,9 +1062,6 @@
#define gen_helper_qsub8 gen_helper_qsub8_sparc64 #define gen_helper_qsub8 gen_helper_qsub8_sparc64
#define gen_helper_qsubaddx gen_helper_qsubaddx_sparc64 #define gen_helper_qsubaddx gen_helper_qsubaddx_sparc64
#define gen_helper_rbit gen_helper_rbit_sparc64 #define gen_helper_rbit gen_helper_rbit_sparc64
#define gen_helper_recpe_f32 gen_helper_recpe_f32_sparc64
#define gen_helper_recpe_u32 gen_helper_recpe_u32_sparc64
#define gen_helper_recps_f32 gen_helper_recps_f32_sparc64
#define gen_helper_rintd gen_helper_rintd_sparc64 #define gen_helper_rintd gen_helper_rintd_sparc64
#define gen_helper_rintd_exact gen_helper_rintd_exact_sparc64 #define gen_helper_rintd_exact gen_helper_rintd_exact_sparc64
#define gen_helper_rints gen_helper_rints_sparc64 #define gen_helper_rints gen_helper_rints_sparc64
@ -2119,6 +2116,7 @@
#define helper_qsubaddx helper_qsubaddx_sparc64 #define helper_qsubaddx helper_qsubaddx_sparc64
#define helper_raise_exception helper_raise_exception_sparc64 #define helper_raise_exception helper_raise_exception_sparc64
#define helper_rbit helper_rbit_sparc64 #define helper_rbit helper_rbit_sparc64
#define helper_recpe_f16 helper_recpe_f16_sparc64
#define helper_recpe_f32 helper_recpe_f32_sparc64 #define helper_recpe_f32 helper_recpe_f32_sparc64
#define helper_recpe_f64 helper_recpe_f64_sparc64 #define helper_recpe_f64 helper_recpe_f64_sparc64
#define helper_recpe_u32 helper_recpe_u32_sparc64 #define helper_recpe_u32 helper_recpe_u32_sparc64

View file

@ -10715,80 +10715,75 @@ float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUARMState *env)
* int->float conversions at run-time. */ * int->float conversions at run-time. */
#define float64_256 make_float64(0x4070000000000000LL) #define float64_256 make_float64(0x4070000000000000LL)
#define float64_512 make_float64(0x4080000000000000LL) #define float64_512 make_float64(0x4080000000000000LL)
#define float16_maxnorm make_float16(0x7bff)
#define float32_maxnorm make_float32(0x7f7fffff) #define float32_maxnorm make_float32(0x7f7fffff)
#define float64_maxnorm make_float64(0x7fefffffffffffffLL) #define float64_maxnorm make_float64(0x7fefffffffffffffLL)
/* Reciprocal functions /* Reciprocal functions
* *
* The algorithm that must be used to calculate the estimate * The algorithm that must be used to calculate the estimate
* is specified by the ARM ARM, see FPRecipEstimate() * is specified by the ARM ARM, see FPRecipEstimate()/RecipEstimate
*/ */
static float64 recip_estimate(float64 a, float_status *real_fp_status) /* See RecipEstimate()
*
* input is a 9 bit fixed point number
* input range 256 .. 511 for a number from 0.5 <= x < 1.0.
* result range 256 .. 511 for a number from 1.0 to 511/256.
*/
static int recip_estimate(int input)
{ {
/* These calculations mustn't set any fp exception flags, int a, b, r;
* so we use a local copy of the fp_status. assert(256 <= input && input < 512);
*/ a = (input * 2) + 1;
float_status dummy_status = *real_fp_status; b = (1 << 19) / a;
float_status *s = &dummy_status; r = (b + 1) >> 1;
/* q = (int)(a * 512.0) */ assert(256 <= r && r < 512);
float64 q = float64_mul(float64_512, a, s); return r;
int64_t q_int = float64_to_int64_round_to_zero(q, s);
/* r = 1.0 / (((double)q + 0.5) / 512.0) */
q = int64_to_float64(q_int, s);
q = float64_add(q, float64_half, s);
q = float64_div(q, float64_512, s);
q = float64_div(float64_one, q, s);
/* s = (int)(256.0 * r + 0.5) */
q = float64_mul(q, float64_256, s);
q = float64_add(q, float64_half, s);
q_int = float64_to_int64_round_to_zero(q, s);
/* return (double)s / 256.0 */
return float64_div(int64_to_float64(q_int, s), float64_256, s);
} }
/* Common wrapper to call recip_estimate */ /*
static float64 call_recip_estimate(float64 num, int off, float_status *fpst) * Common wrapper to call recip_estimate
{ *
uint64_t val64 = float64_val(num); * The parameters are exponent and 64 bit fraction (without implicit
uint64_t frac = extract64(val64, 0, 52); * bit) where the binary point is nominally at bit 52. Returns a
int64_t exp = extract64(val64, 52, 11); * float64 which can then be rounded to the appropriate size by the
uint64_t sbit; * callee.
float64 scaled, estimate; */
/* Generate the scaled number for the estimate function */ static uint64_t call_recip_estimate(int *exp, int exp_off, uint64_t frac)
if (exp == 0) { {
uint32_t scaled, estimate;
uint64_t result_frac;
int result_exp;
/* Handle sub-normals */
if (*exp == 0) {
if (extract64(frac, 51, 1) == 0) { if (extract64(frac, 51, 1) == 0) {
exp = -1; *exp = -1;
frac = extract64(frac, 0, 50) << 2; frac <<= 2;
} else { } else {
frac = extract64(frac, 0, 51) << 1; frac <<= 1;
} }
} }
/* scaled = '0' : '01111111110' : fraction<51:44> : Zeros(44); */ /* scaled = UInt('1':fraction<51:44>) */
scaled = make_float64((0x3feULL << 52) scaled = deposit32(1 << 8, 0, 8, extract64(frac, 44, 8));
| extract64(frac, 44, 8) << 44); estimate = recip_estimate(scaled);
estimate = recip_estimate(scaled, fpst); result_exp = exp_off - *exp;
result_frac = deposit64(0, 44, 8, estimate);
/* Build new result */ if (result_exp == 0) {
val64 = float64_val(estimate); result_frac = deposit64(result_frac >> 1, 51, 1, 1);
sbit = 0x8000000000000000ULL & val64; } else if (result_exp == -1) {
exp = off - exp; result_frac = deposit64(result_frac >> 2, 50, 2, 1);
frac = extract64(val64, 0, 52); result_exp = 0;
if (exp == 0) {
frac = 1ULL << 51 | extract64(frac, 1, 51);
} else if (exp == -1) {
frac = 1ULL << 50 | extract64(frac, 2, 50);
exp = 0;
} }
return make_float64(sbit | (exp << 52) | frac); *exp = result_exp;
return result_frac;
} }
static bool round_to_inf(float_status *fpst, bool sign_bit) static bool round_to_inf(float_status *fpst, bool sign_bit)
@ -10810,18 +10805,63 @@ static bool round_to_inf(float_status *fpst, bool sign_bit)
return false; return false;
} }
float16 HELPER(recpe_f16)(float16 input, void *fpstp)
{
float_status *fpst = fpstp;
float16 f16 = float16_squash_input_denormal(input, fpst);
uint32_t f16_val = float16_val(f16);
uint32_t f16_sign = float16_is_neg(f16);
int f16_exp = extract32(f16_val, 10, 5);
uint32_t f16_frac = extract32(f16_val, 0, 10);
uint64_t f64_frac;
if (float16_is_any_nan(f16)) {
float16 nan = f16;
if (float16_is_signaling_nan(f16, fpst)) {
float_raise(float_flag_invalid, fpst);
nan = float16_maybe_silence_nan(f16, fpst);
}
if (fpst->default_nan_mode) {
nan = float16_default_nan(fpst);
}
return nan;
} else if (float16_is_infinity(f16)) {
return float16_set_sign(float16_zero, float16_is_neg(f16));
} else if (float16_is_zero(f16)) {
float_raise(float_flag_divbyzero, fpst);
return float16_set_sign(float16_infinity, float16_is_neg(f16));
} else if (float16_abs(f16) < (1 << 8)) {
/* Abs(value) < 2.0^-16 */
float_raise(float_flag_overflow | float_flag_inexact, fpst);
if (round_to_inf(fpst, f16_sign)) {
return float16_set_sign(float16_infinity, f16_sign);
} else {
return float16_set_sign(float16_maxnorm, f16_sign);
}
} else if (f16_exp >= 29 && fpst->flush_to_zero) {
float_raise(float_flag_underflow, fpst);
return float16_set_sign(float16_zero, float16_is_neg(f16));
}
f64_frac = call_recip_estimate(&f16_exp, 29,
((uint64_t) f16_frac) << (52 - 10));
/* result = sign : result_exp<4:0> : fraction<51:42> */
f16_val = deposit32(0, 15, 1, f16_sign);
f16_val = deposit32(f16_val, 10, 5, f16_exp);
f16_val = deposit32(f16_val, 0, 10, extract64(f64_frac, 52 - 10, 10));
return make_float16(f16_val);
}
float32 HELPER(recpe_f32)(float32 input, void *fpstp) float32 HELPER(recpe_f32)(float32 input, void *fpstp)
{ {
float_status *fpst = fpstp; float_status *fpst = fpstp;
float32 f32 = float32_squash_input_denormal(input, fpst); float32 f32 = float32_squash_input_denormal(input, fpst);
uint32_t f32_val = float32_val(f32); uint32_t f32_val = float32_val(f32);
uint32_t f32_sbit = 0x80000000ULL & f32_val; bool f32_sign = float32_is_neg(f32);
int32_t f32_exp = extract32(f32_val, 23, 8); int f32_exp = extract32(f32_val, 23, 8);
uint32_t f32_frac = extract32(f32_val, 0, 23); uint32_t f32_frac = extract32(f32_val, 0, 23);
float64 f64, r64; uint64_t f64_frac;
uint64_t r64_val;
int64_t r64_exp;
uint64_t r64_frac;
if (float32_is_any_nan(f32)) { if (float32_is_any_nan(f32)) {
float32 nan = f32; float32 nan = f32;
@ -10838,30 +10878,27 @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
} else if (float32_is_zero(f32)) { } else if (float32_is_zero(f32)) {
float_raise(float_flag_divbyzero, fpst); float_raise(float_flag_divbyzero, fpst);
return float32_set_sign(float32_infinity, float32_is_neg(f32)); return float32_set_sign(float32_infinity, float32_is_neg(f32));
} else if ((f32_val & ~(1ULL << 31)) < (1ULL << 21)) { } else if (float32_abs(f32) < (1ULL << 21)) {
/* Abs(value) < 2.0^-128 */ /* Abs(value) < 2.0^-128 */
float_raise(float_flag_overflow | float_flag_inexact, fpst); float_raise(float_flag_overflow | float_flag_inexact, fpst);
if (round_to_inf(fpst, f32_sbit)) { if (round_to_inf(fpst, f32_sign)) {
return float32_set_sign(float32_infinity, float32_is_neg(f32)); return float32_set_sign(float32_infinity, f32_sign);
} else { } else {
return float32_set_sign(float32_maxnorm, float32_is_neg(f32)); return float32_set_sign(float32_maxnorm, f32_sign);
} }
} else if (f32_exp >= 253 && fpst->flush_to_zero) { } else if (f32_exp >= 253 && fpst->flush_to_zero) {
float_raise(float_flag_underflow, fpst); float_raise(float_flag_underflow, fpst);
return float32_set_sign(float32_zero, float32_is_neg(f32)); return float32_set_sign(float32_zero, float32_is_neg(f32));
} }
f64_frac = call_recip_estimate(&f32_exp, 253,
((uint64_t) f32_frac) << (52 - 23));
f64 = make_float64(((int64_t)(f32_exp) << 52) | (int64_t)(f32_frac) << 29); /* result = sign : result_exp<7:0> : fraction<51:29> */
r64 = call_recip_estimate(f64, 253, fpst); f32_val = deposit32(0, 31, 1, f32_sign);
r64_val = float64_val(r64); f32_val = deposit32(f32_val, 23, 8, f32_exp);
r64_exp = extract64(r64_val, 52, 11); f32_val = deposit32(f32_val, 0, 23, extract64(f64_frac, 52 - 23, 23));
r64_frac = extract64(r64_val, 0, 52); return make_float32(f32_val);
/* result = sign : result_exp<7:0> : fraction<51:29>; */
return make_float32(f32_sbit |
(r64_exp & 0xff) << 23 |
extract64(r64_frac, 29, 24));
} }
float64 HELPER(recpe_f64)(float64 input, void *fpstp) float64 HELPER(recpe_f64)(float64 input, void *fpstp)
@ -10869,12 +10906,9 @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
float_status *fpst = fpstp; float_status *fpst = fpstp;
float64 f64 = float64_squash_input_denormal(input, fpst); float64 f64 = float64_squash_input_denormal(input, fpst);
uint64_t f64_val = float64_val(f64); uint64_t f64_val = float64_val(f64);
uint64_t f64_sbit = 0x8000000000000000ULL & f64_val; bool f64_sign = float64_is_neg(f64);
int64_t f64_exp = extract64(f64_val, 52, 11); int f64_exp = extract64(f64_val, 52, 11);
float64 r64; uint64_t f64_frac = extract64(f64_val, 0, 52);
uint64_t r64_val;
int64_t r64_exp;
uint64_t r64_frac;
/* Deal with any special cases */ /* Deal with any special cases */
if (float64_is_any_nan(f64)) { if (float64_is_any_nan(f64)) {
@ -10895,25 +10929,23 @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
} else if ((f64_val & ~(1ULL << 63)) < (1ULL << 50)) { } else if ((f64_val & ~(1ULL << 63)) < (1ULL << 50)) {
/* Abs(value) < 2.0^-1024 */ /* Abs(value) < 2.0^-1024 */
float_raise(float_flag_overflow | float_flag_inexact, fpst); float_raise(float_flag_overflow | float_flag_inexact, fpst);
if (round_to_inf(fpst, f64_sbit)) { if (round_to_inf(fpst, f64_sign)) {
return float64_set_sign(float64_infinity, float64_is_neg(f64)); return float64_set_sign(float64_infinity, f64_sign);
} else { } else {
return float64_set_sign(float64_maxnorm, float64_is_neg(f64)); return float64_set_sign(float64_maxnorm, f64_sign);
} }
} else if (f64_exp >= 2045 && fpst->flush_to_zero) { } else if (f64_exp >= 2045 && fpst->flush_to_zero) {
float_raise(float_flag_underflow, fpst); float_raise(float_flag_underflow, fpst);
return float64_set_sign(float64_zero, float64_is_neg(f64)); return float64_set_sign(float64_zero, float64_is_neg(f64));
} }
r64 = call_recip_estimate(f64, 2045, fpst); f64_frac = call_recip_estimate(&f64_exp, 2045, f64_frac);
r64_val = float64_val(r64);
r64_exp = extract64(r64_val, 52, 11);
r64_frac = extract64(r64_val, 0, 52);
/* result = sign : result_exp<10:0> : fraction<51:0> */ /* result = sign : result_exp<10:0> : fraction<51:0>; */
return make_float64(f64_sbit | f64_val = deposit64(0, 63, 1, f64_sign);
((r64_exp & 0x7ff) << 52) | f64_val = deposit64(f64_val, 52, 11, f64_exp);
r64_frac); f64_val = deposit64(f64_val, 0, 52, f64_frac);
return make_float64(f64_val);
} }
/* The algorithm that must be used to calculate the estimate /* The algorithm that must be used to calculate the estimate
@ -11104,19 +11136,17 @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp) uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp)
{ {
float_status *s = fpstp; /* float_status *s = fpstp; */
float64 f64; int input, estimate;
if ((a & 0x80000000) == 0) { if ((a & 0x80000000) == 0) {
return 0xffffffff; return 0xffffffff;
} }
f64 = make_float64((0x3feULL << 52) input = extract32(a, 23, 9);
| ((int64_t)(a & 0x7fffffff) << 21)); estimate = recip_estimate(input);
f64 = recip_estimate(f64, s); return deposit32(0, (32 - 9), 9, estimate);
return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff);
} }
uint32_t HELPER(rsqrte_u32)(uint32_t a, void *fpstp) uint32_t HELPER(rsqrte_u32)(uint32_t a, void *fpstp)

View file

@ -194,6 +194,7 @@ DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr)
DEF_HELPER_3(recps_f32, f32, f32, f32, env) DEF_HELPER_3(recps_f32, f32, f32, f32, env)
DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env) DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env)
DEF_HELPER_FLAGS_2(recpe_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
DEF_HELPER_FLAGS_2(recpe_f32, TCG_CALL_NO_RWG, f32, f32, ptr) DEF_HELPER_FLAGS_2(recpe_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
DEF_HELPER_FLAGS_2(recpe_f64, TCG_CALL_NO_RWG, f64, f64, ptr) DEF_HELPER_FLAGS_2(recpe_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr) DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr)

View file

@ -1062,9 +1062,6 @@
#define gen_helper_qsub8 gen_helper_qsub8_x86_64 #define gen_helper_qsub8 gen_helper_qsub8_x86_64
#define gen_helper_qsubaddx gen_helper_qsubaddx_x86_64 #define gen_helper_qsubaddx gen_helper_qsubaddx_x86_64
#define gen_helper_rbit gen_helper_rbit_x86_64 #define gen_helper_rbit gen_helper_rbit_x86_64
#define gen_helper_recpe_f32 gen_helper_recpe_f32_x86_64
#define gen_helper_recpe_u32 gen_helper_recpe_u32_x86_64
#define gen_helper_recps_f32 gen_helper_recps_f32_x86_64
#define gen_helper_rintd gen_helper_rintd_x86_64 #define gen_helper_rintd gen_helper_rintd_x86_64
#define gen_helper_rintd_exact gen_helper_rintd_exact_x86_64 #define gen_helper_rintd_exact gen_helper_rintd_exact_x86_64
#define gen_helper_rints gen_helper_rints_x86_64 #define gen_helper_rints gen_helper_rints_x86_64
@ -2119,6 +2116,7 @@
#define helper_qsubaddx helper_qsubaddx_x86_64 #define helper_qsubaddx helper_qsubaddx_x86_64
#define helper_raise_exception helper_raise_exception_x86_64 #define helper_raise_exception helper_raise_exception_x86_64
#define helper_rbit helper_rbit_x86_64 #define helper_rbit helper_rbit_x86_64
#define helper_recpe_f16 helper_recpe_f16_x86_64
#define helper_recpe_f32 helper_recpe_f32_x86_64 #define helper_recpe_f32 helper_recpe_f32_x86_64
#define helper_recpe_f64 helper_recpe_f64_x86_64 #define helper_recpe_f64 helper_recpe_f64_x86_64
#define helper_recpe_u32 helper_recpe_u32_x86_64 #define helper_recpe_u32 helper_recpe_u32_x86_64