From 40d57900bfaf813098ad3eb6a3364e47cf4b282c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Sat, 19 May 2018 22:33:49 -0400 Subject: [PATCH] target/arm: convert conversion helpers to fpst/ahp_flag Instead of passing env and leaving it up to the helper to get the right fpstatus we pass it explicitly. There was already a get_fpstatus helper for neon for the 32 bit code. We also add an get_ahp_flag() for passing the state of the alternative FP16 format flag. This leaves scope for later tracking the AHP state in translation flags. Backports commit 486624fcd3eaca6165ab8401d73bbae6c0fb81c1 from qemu --- qemu/aarch64.h | 5 +++ qemu/aarch64eb.h | 5 +++ qemu/arm.h | 5 +++ qemu/armeb.h | 5 +++ qemu/header_gen.py | 5 +++ qemu/m68k.h | 5 +++ qemu/mips.h | 5 +++ qemu/mips64.h | 5 +++ qemu/mips64el.h | 5 +++ qemu/mipsel.h | 5 +++ qemu/powerpc.h | 5 +++ qemu/sparc.h | 5 +++ qemu/sparc64.h | 5 +++ qemu/target/arm/helper.c | 56 ++++-------------------- qemu/target/arm/helper.h | 10 ++--- qemu/target/arm/translate-a64.c | 37 +++++++++++++--- qemu/target/arm/translate.c | 75 ++++++++++++++++++++++++++------- qemu/target/arm/translate.h | 12 ++++++ qemu/x86_64.h | 5 +++ 19 files changed, 183 insertions(+), 77 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 0486d6f4..c696310c 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -472,6 +472,7 @@ #define float128_rem float128_rem_aarch64 #define float128_round_to_int float128_round_to_int_aarch64 #define float128_scalbn float128_scalbn_aarch64 +#define float128_silence_nan float128_silence_nan_aarch64 #define float128_sqrt float128_sqrt_aarch64 #define float128_sub float128_sub_aarch64 #define float128_to_float32 float128_to_float32_aarch64 @@ -505,6 +506,7 @@ #define float16_muladd float16_muladd_aarch64 #define float16_round_to_int float16_round_to_int_aarch64 #define float16_scalbn float16_scalbn_aarch64 +#define float16_silence_nan float16_silence_nan_aarch64 #define float16_sqrt float16_sqrt_aarch64 #define float16_squash_input_denormal float16_squash_input_denormal_aarch64 #define float16_sub float16_sub_aarch64 @@ -561,6 +563,7 @@ #define float32_round_to_int float32_round_to_int_aarch64 #define float32_scalbn float32_scalbn_aarch64 #define float32_set_sign float32_set_sign_aarch64 +#define float32_silence_nan float32_silence_nan_aarch64 #define float32_sqrt float32_sqrt_aarch64 #define float32_squash_input_denormal float32_squash_input_denormal_aarch64 #define float32_sub float32_sub_aarch64 @@ -618,6 +621,7 @@ #define float64_round_to_int float64_round_to_int_aarch64 #define float64_scalbn float64_scalbn_aarch64 #define float64_set_sign float64_set_sign_aarch64 +#define float64_silence_nan float64_silence_nan_aarch64 #define float64_sqrt float64_sqrt_aarch64 #define float64_squash_input_denormal float64_squash_input_denormal_aarch64 #define float64_sub float64_sub_aarch64 @@ -663,6 +667,7 @@ #define floatx80_round floatx80_round_aarch64 #define floatx80_round_to_int floatx80_round_to_int_aarch64 #define floatx80_scalbn floatx80_scalbn_aarch64 +#define floatx80_silence_nan floatx80_silence_nan_aarch64 #define floatx80_sqrt floatx80_sqrt_aarch64 #define floatx80_sub floatx80_sub_aarch64 #define floatx80_to_float128 floatx80_to_float128_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 22231d35..8a6da386 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -472,6 +472,7 @@ #define float128_rem float128_rem_aarch64eb #define float128_round_to_int float128_round_to_int_aarch64eb #define float128_scalbn float128_scalbn_aarch64eb +#define float128_silence_nan float128_silence_nan_aarch64eb #define float128_sqrt float128_sqrt_aarch64eb #define float128_sub float128_sub_aarch64eb #define float128_to_float32 float128_to_float32_aarch64eb @@ -505,6 +506,7 @@ #define float16_muladd float16_muladd_aarch64eb #define float16_round_to_int float16_round_to_int_aarch64eb #define float16_scalbn float16_scalbn_aarch64eb +#define float16_silence_nan float16_silence_nan_aarch64eb #define float16_sqrt float16_sqrt_aarch64eb #define float16_squash_input_denormal float16_squash_input_denormal_aarch64eb #define float16_sub float16_sub_aarch64eb @@ -561,6 +563,7 @@ #define float32_round_to_int float32_round_to_int_aarch64eb #define float32_scalbn float32_scalbn_aarch64eb #define float32_set_sign float32_set_sign_aarch64eb +#define float32_silence_nan float32_silence_nan_aarch64eb #define float32_sqrt float32_sqrt_aarch64eb #define float32_squash_input_denormal float32_squash_input_denormal_aarch64eb #define float32_sub float32_sub_aarch64eb @@ -618,6 +621,7 @@ #define float64_round_to_int float64_round_to_int_aarch64eb #define float64_scalbn float64_scalbn_aarch64eb #define float64_set_sign float64_set_sign_aarch64eb +#define float64_silence_nan float64_silence_nan_aarch64eb #define float64_sqrt float64_sqrt_aarch64eb #define float64_squash_input_denormal float64_squash_input_denormal_aarch64eb #define float64_sub float64_sub_aarch64eb @@ -663,6 +667,7 @@ #define floatx80_round floatx80_round_aarch64eb #define floatx80_round_to_int floatx80_round_to_int_aarch64eb #define floatx80_scalbn floatx80_scalbn_aarch64eb +#define floatx80_silence_nan floatx80_silence_nan_aarch64eb #define floatx80_sqrt floatx80_sqrt_aarch64eb #define floatx80_sub floatx80_sub_aarch64eb #define floatx80_to_float128 floatx80_to_float128_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 9d0453cf..79357936 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -472,6 +472,7 @@ #define float128_rem float128_rem_arm #define float128_round_to_int float128_round_to_int_arm #define float128_scalbn float128_scalbn_arm +#define float128_silence_nan float128_silence_nan_arm #define float128_sqrt float128_sqrt_arm #define float128_sub float128_sub_arm #define float128_to_float32 float128_to_float32_arm @@ -505,6 +506,7 @@ #define float16_muladd float16_muladd_arm #define float16_round_to_int float16_round_to_int_arm #define float16_scalbn float16_scalbn_arm +#define float16_silence_nan float16_silence_nan_arm #define float16_sqrt float16_sqrt_arm #define float16_squash_input_denormal float16_squash_input_denormal_arm #define float16_sub float16_sub_arm @@ -561,6 +563,7 @@ #define float32_round_to_int float32_round_to_int_arm #define float32_scalbn float32_scalbn_arm #define float32_set_sign float32_set_sign_arm +#define float32_silence_nan float32_silence_nan_arm #define float32_sqrt float32_sqrt_arm #define float32_squash_input_denormal float32_squash_input_denormal_arm #define float32_sub float32_sub_arm @@ -618,6 +621,7 @@ #define float64_round_to_int float64_round_to_int_arm #define float64_scalbn float64_scalbn_arm #define float64_set_sign float64_set_sign_arm +#define float64_silence_nan float64_silence_nan_arm #define float64_sqrt float64_sqrt_arm #define float64_squash_input_denormal float64_squash_input_denormal_arm #define float64_sub float64_sub_arm @@ -663,6 +667,7 @@ #define floatx80_round floatx80_round_arm #define floatx80_round_to_int floatx80_round_to_int_arm #define floatx80_scalbn floatx80_scalbn_arm +#define floatx80_silence_nan floatx80_silence_nan_arm #define floatx80_sqrt floatx80_sqrt_arm #define floatx80_sub floatx80_sub_arm #define floatx80_to_float128 floatx80_to_float128_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index c9dd7912..ffd5a697 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -472,6 +472,7 @@ #define float128_rem float128_rem_armeb #define float128_round_to_int float128_round_to_int_armeb #define float128_scalbn float128_scalbn_armeb +#define float128_silence_nan float128_silence_nan_armeb #define float128_sqrt float128_sqrt_armeb #define float128_sub float128_sub_armeb #define float128_to_float32 float128_to_float32_armeb @@ -505,6 +506,7 @@ #define float16_muladd float16_muladd_armeb #define float16_round_to_int float16_round_to_int_armeb #define float16_scalbn float16_scalbn_armeb +#define float16_silence_nan float16_silence_nan_armeb #define float16_sqrt float16_sqrt_armeb #define float16_squash_input_denormal float16_squash_input_denormal_armeb #define float16_sub float16_sub_armeb @@ -561,6 +563,7 @@ #define float32_round_to_int float32_round_to_int_armeb #define float32_scalbn float32_scalbn_armeb #define float32_set_sign float32_set_sign_armeb +#define float32_silence_nan float32_silence_nan_armeb #define float32_sqrt float32_sqrt_armeb #define float32_squash_input_denormal float32_squash_input_denormal_armeb #define float32_sub float32_sub_armeb @@ -618,6 +621,7 @@ #define float64_round_to_int float64_round_to_int_armeb #define float64_scalbn float64_scalbn_armeb #define float64_set_sign float64_set_sign_armeb +#define float64_silence_nan float64_silence_nan_armeb #define float64_sqrt float64_sqrt_armeb #define float64_squash_input_denormal float64_squash_input_denormal_armeb #define float64_sub float64_sub_armeb @@ -663,6 +667,7 @@ #define floatx80_round floatx80_round_armeb #define floatx80_round_to_int floatx80_round_to_int_armeb #define floatx80_scalbn floatx80_scalbn_armeb +#define floatx80_silence_nan floatx80_silence_nan_armeb #define floatx80_sqrt floatx80_sqrt_armeb #define floatx80_sub floatx80_sub_armeb #define floatx80_to_float128 floatx80_to_float128_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 57218b24..2aa447ff 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -478,6 +478,7 @@ symbols = ( 'float128_rem', 'float128_round_to_int', 'float128_scalbn', + 'float128_silence_nan', 'float128_sqrt', 'float128_sub', 'float128_to_float32', @@ -511,6 +512,7 @@ symbols = ( 'float16_muladd', 'float16_round_to_int', 'float16_scalbn', + 'float16_silence_nan', 'float16_sqrt', 'float16_squash_input_denormal', 'float16_sub', @@ -567,6 +569,7 @@ symbols = ( 'float32_round_to_int', 'float32_scalbn', 'float32_set_sign', + 'float32_silence_nan', 'float32_sqrt', 'float32_squash_input_denormal', 'float32_sub', @@ -624,6 +627,7 @@ symbols = ( 'float64_round_to_int', 'float64_scalbn', 'float64_set_sign', + 'float64_silence_nan', 'float64_sqrt', 'float64_squash_input_denormal', 'float64_sub', @@ -669,6 +673,7 @@ symbols = ( 'floatx80_round', 'floatx80_round_to_int', 'floatx80_scalbn', + 'floatx80_silence_nan', 'floatx80_sqrt', 'floatx80_sub', 'floatx80_to_float128', diff --git a/qemu/m68k.h b/qemu/m68k.h index c28ca927..ee239998 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -472,6 +472,7 @@ #define float128_rem float128_rem_m68k #define float128_round_to_int float128_round_to_int_m68k #define float128_scalbn float128_scalbn_m68k +#define float128_silence_nan float128_silence_nan_m68k #define float128_sqrt float128_sqrt_m68k #define float128_sub float128_sub_m68k #define float128_to_float32 float128_to_float32_m68k @@ -505,6 +506,7 @@ #define float16_muladd float16_muladd_m68k #define float16_round_to_int float16_round_to_int_m68k #define float16_scalbn float16_scalbn_m68k +#define float16_silence_nan float16_silence_nan_m68k #define float16_sqrt float16_sqrt_m68k #define float16_squash_input_denormal float16_squash_input_denormal_m68k #define float16_sub float16_sub_m68k @@ -561,6 +563,7 @@ #define float32_round_to_int float32_round_to_int_m68k #define float32_scalbn float32_scalbn_m68k #define float32_set_sign float32_set_sign_m68k +#define float32_silence_nan float32_silence_nan_m68k #define float32_sqrt float32_sqrt_m68k #define float32_squash_input_denormal float32_squash_input_denormal_m68k #define float32_sub float32_sub_m68k @@ -618,6 +621,7 @@ #define float64_round_to_int float64_round_to_int_m68k #define float64_scalbn float64_scalbn_m68k #define float64_set_sign float64_set_sign_m68k +#define float64_silence_nan float64_silence_nan_m68k #define float64_sqrt float64_sqrt_m68k #define float64_squash_input_denormal float64_squash_input_denormal_m68k #define float64_sub float64_sub_m68k @@ -663,6 +667,7 @@ #define floatx80_round floatx80_round_m68k #define floatx80_round_to_int floatx80_round_to_int_m68k #define floatx80_scalbn floatx80_scalbn_m68k +#define floatx80_silence_nan floatx80_silence_nan_m68k #define floatx80_sqrt floatx80_sqrt_m68k #define floatx80_sub floatx80_sub_m68k #define floatx80_to_float128 floatx80_to_float128_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 4591dd2b..3108d50a 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -472,6 +472,7 @@ #define float128_rem float128_rem_mips #define float128_round_to_int float128_round_to_int_mips #define float128_scalbn float128_scalbn_mips +#define float128_silence_nan float128_silence_nan_mips #define float128_sqrt float128_sqrt_mips #define float128_sub float128_sub_mips #define float128_to_float32 float128_to_float32_mips @@ -505,6 +506,7 @@ #define float16_muladd float16_muladd_mips #define float16_round_to_int float16_round_to_int_mips #define float16_scalbn float16_scalbn_mips +#define float16_silence_nan float16_silence_nan_mips #define float16_sqrt float16_sqrt_mips #define float16_squash_input_denormal float16_squash_input_denormal_mips #define float16_sub float16_sub_mips @@ -561,6 +563,7 @@ #define float32_round_to_int float32_round_to_int_mips #define float32_scalbn float32_scalbn_mips #define float32_set_sign float32_set_sign_mips +#define float32_silence_nan float32_silence_nan_mips #define float32_sqrt float32_sqrt_mips #define float32_squash_input_denormal float32_squash_input_denormal_mips #define float32_sub float32_sub_mips @@ -618,6 +621,7 @@ #define float64_round_to_int float64_round_to_int_mips #define float64_scalbn float64_scalbn_mips #define float64_set_sign float64_set_sign_mips +#define float64_silence_nan float64_silence_nan_mips #define float64_sqrt float64_sqrt_mips #define float64_squash_input_denormal float64_squash_input_denormal_mips #define float64_sub float64_sub_mips @@ -663,6 +667,7 @@ #define floatx80_round floatx80_round_mips #define floatx80_round_to_int floatx80_round_to_int_mips #define floatx80_scalbn floatx80_scalbn_mips +#define floatx80_silence_nan floatx80_silence_nan_mips #define floatx80_sqrt floatx80_sqrt_mips #define floatx80_sub floatx80_sub_mips #define floatx80_to_float128 floatx80_to_float128_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 1727223d..9920b083 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -472,6 +472,7 @@ #define float128_rem float128_rem_mips64 #define float128_round_to_int float128_round_to_int_mips64 #define float128_scalbn float128_scalbn_mips64 +#define float128_silence_nan float128_silence_nan_mips64 #define float128_sqrt float128_sqrt_mips64 #define float128_sub float128_sub_mips64 #define float128_to_float32 float128_to_float32_mips64 @@ -505,6 +506,7 @@ #define float16_muladd float16_muladd_mips64 #define float16_round_to_int float16_round_to_int_mips64 #define float16_scalbn float16_scalbn_mips64 +#define float16_silence_nan float16_silence_nan_mips64 #define float16_sqrt float16_sqrt_mips64 #define float16_squash_input_denormal float16_squash_input_denormal_mips64 #define float16_sub float16_sub_mips64 @@ -561,6 +563,7 @@ #define float32_round_to_int float32_round_to_int_mips64 #define float32_scalbn float32_scalbn_mips64 #define float32_set_sign float32_set_sign_mips64 +#define float32_silence_nan float32_silence_nan_mips64 #define float32_sqrt float32_sqrt_mips64 #define float32_squash_input_denormal float32_squash_input_denormal_mips64 #define float32_sub float32_sub_mips64 @@ -618,6 +621,7 @@ #define float64_round_to_int float64_round_to_int_mips64 #define float64_scalbn float64_scalbn_mips64 #define float64_set_sign float64_set_sign_mips64 +#define float64_silence_nan float64_silence_nan_mips64 #define float64_sqrt float64_sqrt_mips64 #define float64_squash_input_denormal float64_squash_input_denormal_mips64 #define float64_sub float64_sub_mips64 @@ -663,6 +667,7 @@ #define floatx80_round floatx80_round_mips64 #define floatx80_round_to_int floatx80_round_to_int_mips64 #define floatx80_scalbn floatx80_scalbn_mips64 +#define floatx80_silence_nan floatx80_silence_nan_mips64 #define floatx80_sqrt floatx80_sqrt_mips64 #define floatx80_sub floatx80_sub_mips64 #define floatx80_to_float128 floatx80_to_float128_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index dbaede56..cfeb8663 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -472,6 +472,7 @@ #define float128_rem float128_rem_mips64el #define float128_round_to_int float128_round_to_int_mips64el #define float128_scalbn float128_scalbn_mips64el +#define float128_silence_nan float128_silence_nan_mips64el #define float128_sqrt float128_sqrt_mips64el #define float128_sub float128_sub_mips64el #define float128_to_float32 float128_to_float32_mips64el @@ -505,6 +506,7 @@ #define float16_muladd float16_muladd_mips64el #define float16_round_to_int float16_round_to_int_mips64el #define float16_scalbn float16_scalbn_mips64el +#define float16_silence_nan float16_silence_nan_mips64el #define float16_sqrt float16_sqrt_mips64el #define float16_squash_input_denormal float16_squash_input_denormal_mips64el #define float16_sub float16_sub_mips64el @@ -561,6 +563,7 @@ #define float32_round_to_int float32_round_to_int_mips64el #define float32_scalbn float32_scalbn_mips64el #define float32_set_sign float32_set_sign_mips64el +#define float32_silence_nan float32_silence_nan_mips64el #define float32_sqrt float32_sqrt_mips64el #define float32_squash_input_denormal float32_squash_input_denormal_mips64el #define float32_sub float32_sub_mips64el @@ -618,6 +621,7 @@ #define float64_round_to_int float64_round_to_int_mips64el #define float64_scalbn float64_scalbn_mips64el #define float64_set_sign float64_set_sign_mips64el +#define float64_silence_nan float64_silence_nan_mips64el #define float64_sqrt float64_sqrt_mips64el #define float64_squash_input_denormal float64_squash_input_denormal_mips64el #define float64_sub float64_sub_mips64el @@ -663,6 +667,7 @@ #define floatx80_round floatx80_round_mips64el #define floatx80_round_to_int floatx80_round_to_int_mips64el #define floatx80_scalbn floatx80_scalbn_mips64el +#define floatx80_silence_nan floatx80_silence_nan_mips64el #define floatx80_sqrt floatx80_sqrt_mips64el #define floatx80_sub floatx80_sub_mips64el #define floatx80_to_float128 floatx80_to_float128_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 7a09d902..97e597ac 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -472,6 +472,7 @@ #define float128_rem float128_rem_mipsel #define float128_round_to_int float128_round_to_int_mipsel #define float128_scalbn float128_scalbn_mipsel +#define float128_silence_nan float128_silence_nan_mipsel #define float128_sqrt float128_sqrt_mipsel #define float128_sub float128_sub_mipsel #define float128_to_float32 float128_to_float32_mipsel @@ -505,6 +506,7 @@ #define float16_muladd float16_muladd_mipsel #define float16_round_to_int float16_round_to_int_mipsel #define float16_scalbn float16_scalbn_mipsel +#define float16_silence_nan float16_silence_nan_mipsel #define float16_sqrt float16_sqrt_mipsel #define float16_squash_input_denormal float16_squash_input_denormal_mipsel #define float16_sub float16_sub_mipsel @@ -561,6 +563,7 @@ #define float32_round_to_int float32_round_to_int_mipsel #define float32_scalbn float32_scalbn_mipsel #define float32_set_sign float32_set_sign_mipsel +#define float32_silence_nan float32_silence_nan_mipsel #define float32_sqrt float32_sqrt_mipsel #define float32_squash_input_denormal float32_squash_input_denormal_mipsel #define float32_sub float32_sub_mipsel @@ -618,6 +621,7 @@ #define float64_round_to_int float64_round_to_int_mipsel #define float64_scalbn float64_scalbn_mipsel #define float64_set_sign float64_set_sign_mipsel +#define float64_silence_nan float64_silence_nan_mipsel #define float64_sqrt float64_sqrt_mipsel #define float64_squash_input_denormal float64_squash_input_denormal_mipsel #define float64_sub float64_sub_mipsel @@ -663,6 +667,7 @@ #define floatx80_round floatx80_round_mipsel #define floatx80_round_to_int floatx80_round_to_int_mipsel #define floatx80_scalbn floatx80_scalbn_mipsel +#define floatx80_silence_nan floatx80_silence_nan_mipsel #define floatx80_sqrt floatx80_sqrt_mipsel #define floatx80_sub floatx80_sub_mipsel #define floatx80_to_float128 floatx80_to_float128_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 35cc9b17..43198b73 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -472,6 +472,7 @@ #define float128_rem float128_rem_powerpc #define float128_round_to_int float128_round_to_int_powerpc #define float128_scalbn float128_scalbn_powerpc +#define float128_silence_nan float128_silence_nan_powerpc #define float128_sqrt float128_sqrt_powerpc #define float128_sub float128_sub_powerpc #define float128_to_float32 float128_to_float32_powerpc @@ -505,6 +506,7 @@ #define float16_muladd float16_muladd_powerpc #define float16_round_to_int float16_round_to_int_powerpc #define float16_scalbn float16_scalbn_powerpc +#define float16_silence_nan float16_silence_nan_powerpc #define float16_sqrt float16_sqrt_powerpc #define float16_squash_input_denormal float16_squash_input_denormal_powerpc #define float16_sub float16_sub_powerpc @@ -561,6 +563,7 @@ #define float32_round_to_int float32_round_to_int_powerpc #define float32_scalbn float32_scalbn_powerpc #define float32_set_sign float32_set_sign_powerpc +#define float32_silence_nan float32_silence_nan_powerpc #define float32_sqrt float32_sqrt_powerpc #define float32_squash_input_denormal float32_squash_input_denormal_powerpc #define float32_sub float32_sub_powerpc @@ -618,6 +621,7 @@ #define float64_round_to_int float64_round_to_int_powerpc #define float64_scalbn float64_scalbn_powerpc #define float64_set_sign float64_set_sign_powerpc +#define float64_silence_nan float64_silence_nan_powerpc #define float64_sqrt float64_sqrt_powerpc #define float64_squash_input_denormal float64_squash_input_denormal_powerpc #define float64_sub float64_sub_powerpc @@ -663,6 +667,7 @@ #define floatx80_round floatx80_round_powerpc #define floatx80_round_to_int floatx80_round_to_int_powerpc #define floatx80_scalbn floatx80_scalbn_powerpc +#define floatx80_silence_nan floatx80_silence_nan_powerpc #define floatx80_sqrt floatx80_sqrt_powerpc #define floatx80_sub floatx80_sub_powerpc #define floatx80_to_float128 floatx80_to_float128_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index 82770cd1..e51397b4 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -472,6 +472,7 @@ #define float128_rem float128_rem_sparc #define float128_round_to_int float128_round_to_int_sparc #define float128_scalbn float128_scalbn_sparc +#define float128_silence_nan float128_silence_nan_sparc #define float128_sqrt float128_sqrt_sparc #define float128_sub float128_sub_sparc #define float128_to_float32 float128_to_float32_sparc @@ -505,6 +506,7 @@ #define float16_muladd float16_muladd_sparc #define float16_round_to_int float16_round_to_int_sparc #define float16_scalbn float16_scalbn_sparc +#define float16_silence_nan float16_silence_nan_sparc #define float16_sqrt float16_sqrt_sparc #define float16_squash_input_denormal float16_squash_input_denormal_sparc #define float16_sub float16_sub_sparc @@ -561,6 +563,7 @@ #define float32_round_to_int float32_round_to_int_sparc #define float32_scalbn float32_scalbn_sparc #define float32_set_sign float32_set_sign_sparc +#define float32_silence_nan float32_silence_nan_sparc #define float32_sqrt float32_sqrt_sparc #define float32_squash_input_denormal float32_squash_input_denormal_sparc #define float32_sub float32_sub_sparc @@ -618,6 +621,7 @@ #define float64_round_to_int float64_round_to_int_sparc #define float64_scalbn float64_scalbn_sparc #define float64_set_sign float64_set_sign_sparc +#define float64_silence_nan float64_silence_nan_sparc #define float64_sqrt float64_sqrt_sparc #define float64_squash_input_denormal float64_squash_input_denormal_sparc #define float64_sub float64_sub_sparc @@ -663,6 +667,7 @@ #define floatx80_round floatx80_round_sparc #define floatx80_round_to_int floatx80_round_to_int_sparc #define floatx80_scalbn floatx80_scalbn_sparc +#define floatx80_silence_nan floatx80_silence_nan_sparc #define floatx80_sqrt floatx80_sqrt_sparc #define floatx80_sub floatx80_sub_sparc #define floatx80_to_float128 floatx80_to_float128_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 56dfbc47..a3360555 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -472,6 +472,7 @@ #define float128_rem float128_rem_sparc64 #define float128_round_to_int float128_round_to_int_sparc64 #define float128_scalbn float128_scalbn_sparc64 +#define float128_silence_nan float128_silence_nan_sparc64 #define float128_sqrt float128_sqrt_sparc64 #define float128_sub float128_sub_sparc64 #define float128_to_float32 float128_to_float32_sparc64 @@ -505,6 +506,7 @@ #define float16_muladd float16_muladd_sparc64 #define float16_round_to_int float16_round_to_int_sparc64 #define float16_scalbn float16_scalbn_sparc64 +#define float16_silence_nan float16_silence_nan_sparc64 #define float16_sqrt float16_sqrt_sparc64 #define float16_squash_input_denormal float16_squash_input_denormal_sparc64 #define float16_sub float16_sub_sparc64 @@ -561,6 +563,7 @@ #define float32_round_to_int float32_round_to_int_sparc64 #define float32_scalbn float32_scalbn_sparc64 #define float32_set_sign float32_set_sign_sparc64 +#define float32_silence_nan float32_silence_nan_sparc64 #define float32_sqrt float32_sqrt_sparc64 #define float32_squash_input_denormal float32_squash_input_denormal_sparc64 #define float32_sub float32_sub_sparc64 @@ -618,6 +621,7 @@ #define float64_round_to_int float64_round_to_int_sparc64 #define float64_scalbn float64_scalbn_sparc64 #define float64_set_sign float64_set_sign_sparc64 +#define float64_silence_nan float64_silence_nan_sparc64 #define float64_sqrt float64_sqrt_sparc64 #define float64_squash_input_denormal float64_squash_input_denormal_sparc64 #define float64_sub float64_sub_sparc64 @@ -663,6 +667,7 @@ #define floatx80_round floatx80_round_sparc64 #define floatx80_round_to_int floatx80_round_to_int_sparc64 #define floatx80_scalbn floatx80_scalbn_sparc64 +#define floatx80_silence_nan floatx80_silence_nan_sparc64 #define floatx80_sqrt floatx80_sqrt_sparc64 #define floatx80_sub floatx80_sub_sparc64 #define floatx80_to_float128 floatx80_to_float128_sparc64 diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index 07ae7dc0..94a5054a 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -10796,64 +10796,24 @@ uint32_t HELPER(set_neon_rmode)(uint32_t rmode, CPUARMState *env) } /* Half precision conversions. */ -static float32 do_fcvt_f16_to_f32(uint32_t a, CPUARMState *env, float_status *s) +float32 HELPER(vfp_fcvt_f16_to_f32)(float16 a, void *fpstp, uint32_t ahp_mode) { - int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; - float32 r = float16_to_float32(make_float16(a), ieee, s); - if (ieee) { - return float32_maybe_silence_nan(r, s); - } - return r; + return float16_to_float32(a, !ahp_mode, fpstp); } -static uint32_t do_fcvt_f32_to_f16(float32 a, CPUARMState *env, float_status *s) +float16 HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode) { - int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; - float16 r = float32_to_float16(a, ieee, s); - if (ieee) { - r = float16_maybe_silence_nan(r, s); - } - return float16_val(r); + return float32_to_float16(a, !ahp_mode, fpstp); } -float32 HELPER(neon_fcvt_f16_to_f32)(uint32_t a, CPUARMState *env) +float64 HELPER(vfp_fcvt_f16_to_f64)(float16 a, void *fpstp, uint32_t ahp_mode) { - return do_fcvt_f16_to_f32(a, env, &env->vfp.standard_fp_status); + return float16_to_float64(a, !ahp_mode, fpstp); } -uint32_t HELPER(neon_fcvt_f32_to_f16)(float32 a, CPUARMState *env) +float16 HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode) { - return do_fcvt_f32_to_f16(a, env, &env->vfp.standard_fp_status); -} - -float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, CPUARMState *env) -{ - return do_fcvt_f16_to_f32(a, env, &env->vfp.fp_status); -} - -uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, CPUARMState *env) -{ - return do_fcvt_f32_to_f16(a, env, &env->vfp.fp_status); -} - -float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, CPUARMState *env) -{ - int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; - float64 r = float16_to_float64(make_float16(a), ieee, &env->vfp.fp_status); - if (ieee) { - return float64_maybe_silence_nan(r, &env->vfp.fp_status); - } - return r; -} - -uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, CPUARMState *env) -{ - int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; - float16 r = float64_to_float16(a, ieee, &env->vfp.fp_status); - if (ieee) { - r = float16_maybe_silence_nan(r, &env->vfp.fp_status); - } - return float16_val(r); + return float64_to_float16(a, !ahp_mode, fpstp); } #define float32_two make_float32(0x40000000) diff --git a/qemu/target/arm/helper.h b/qemu/target/arm/helper.h index e22323a6..590062fb 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -189,12 +189,10 @@ DEF_HELPER_3(vfp_uqtoh, f16, i64, i32, ptr) DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr) DEF_HELPER_FLAGS_2(set_neon_rmode, TCG_CALL_NO_RWG, i32, i32, env) -DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env) -DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env) -DEF_HELPER_2(neon_fcvt_f16_to_f32, f32, i32, env) -DEF_HELPER_2(neon_fcvt_f32_to_f16, i32, f32, env) -DEF_HELPER_FLAGS_2(vfp_fcvt_f16_to_f64, TCG_CALL_NO_RWG, f64, i32, env) -DEF_HELPER_FLAGS_2(vfp_fcvt_f64_to_f16, TCG_CALL_NO_RWG, i32, f64, env) +DEF_HELPER_FLAGS_3(vfp_fcvt_f16_to_f32, TCG_CALL_NO_RWG, f32, f16, ptr, i32) +DEF_HELPER_FLAGS_3(vfp_fcvt_f32_to_f16, TCG_CALL_NO_RWG, f16, f32, ptr, i32) +DEF_HELPER_FLAGS_3(vfp_fcvt_f16_to_f64, TCG_CALL_NO_RWG, f64, f16, ptr, i32) +DEF_HELPER_FLAGS_3(vfp_fcvt_f64_to_f16, TCG_CALL_NO_RWG, f16, f64, ptr, i32) DEF_HELPER_4(vfp_muladdd, f64, f64, f64, f64, ptr) DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr) diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index 9d46053d..ef4fab92 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -5243,10 +5243,15 @@ static void handle_fp_fcvt(DisasContext *s, int opcode, } else { /* Single to half */ TCGv_i32 tcg_rd = tcg_temp_new_i32(tcg_ctx); - gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tcg_rd, tcg_rn, tcg_ctx->cpu_env); + TCGv_i32 ahp = get_ahp_flag(tcg_ctx); + TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, false); + + gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tcg_rd, tcg_rn, fpst, ahp); /* write_fp_sreg is OK here because top half of tcg_rd is zero */ write_fp_sreg(s, rd, tcg_rd); tcg_temp_free_i32(tcg_ctx, tcg_rd); + tcg_temp_free_i32(tcg_ctx, ahp); + tcg_temp_free_ptr(tcg_ctx, fpst); } tcg_temp_free_i32(tcg_ctx, tcg_rn); break; @@ -5259,9 +5264,13 @@ static void handle_fp_fcvt(DisasContext *s, int opcode, /* Double to single */ gen_helper_vfp_fcvtsd(tcg_ctx, tcg_rd, tcg_rn, tcg_ctx->cpu_env); } else { + TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, false); + TCGv_i32 ahp = get_ahp_flag(tcg_ctx); /* Double to half */ - gen_helper_vfp_fcvt_f64_to_f16(tcg_ctx, tcg_rd, tcg_rn, tcg_ctx->cpu_env); + gen_helper_vfp_fcvt_f64_to_f16(tcg_ctx, tcg_rd, tcg_rn, fpst, ahp); /* write_fp_sreg is OK here because top half of tcg_rd is zero */ + tcg_temp_free_ptr(tcg_ctx, fpst); + tcg_temp_free_i32(tcg_ctx, ahp); } write_fp_sreg(s, rd, tcg_rd); tcg_temp_free_i32(tcg_ctx, tcg_rd); @@ -5271,17 +5280,21 @@ static void handle_fp_fcvt(DisasContext *s, int opcode, case 0x3: { TCGv_i32 tcg_rn = read_fp_sreg(s, rn); + TCGv_ptr tcg_fpst = get_fpstatus_ptr(tcg_ctx, false); + TCGv_i32 tcg_ahp = get_ahp_flag(tcg_ctx); tcg_gen_ext16u_i32(tcg_ctx, tcg_rn, tcg_rn); if (dtype == 0) { /* Half to single */ TCGv_i32 tcg_rd = tcg_temp_new_i32(tcg_ctx); - gen_helper_vfp_fcvt_f16_to_f32(tcg_ctx, tcg_rd, tcg_rn, tcg_ctx->cpu_env); + gen_helper_vfp_fcvt_f16_to_f32(tcg_ctx, tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); write_fp_sreg(s, rd, tcg_rd); + tcg_temp_free_ptr(tcg_ctx, tcg_fpst); + tcg_temp_free_i32(tcg_ctx, tcg_ahp); tcg_temp_free_i32(tcg_ctx, tcg_rd); } else { /* Half to double */ TCGv_i64 tcg_rd = tcg_temp_new_i64(tcg_ctx); - gen_helper_vfp_fcvt_f16_to_f64(tcg_ctx, tcg_rd, tcg_rn, tcg_ctx->cpu_env); + gen_helper_vfp_fcvt_f16_to_f64(tcg_ctx, tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); write_fp_dreg(s, rd, tcg_rd); tcg_temp_free_i64(tcg_ctx, tcg_rd); } @@ -9191,12 +9204,17 @@ static void handle_2misc_narrow(DisasContext *s, bool scalar, } else { TCGv_i32 tcg_lo = tcg_temp_new_i32(tcg_ctx); TCGv_i32 tcg_hi = tcg_temp_new_i32(tcg_ctx); + TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, false); + TCGv_i32 ahp = get_ahp_flag(tcg_ctx); + tcg_gen_extr_i64_i32(tcg_ctx, tcg_lo, tcg_hi, tcg_op); - gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tcg_lo, tcg_lo, tcg_ctx->cpu_env); - gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tcg_hi, tcg_hi, tcg_ctx->cpu_env); + gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tcg_lo, tcg_lo, fpst, ahp); + gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tcg_hi, tcg_hi, fpst, ahp); tcg_gen_deposit_i32(tcg_ctx, tcg_res[pass], tcg_lo, tcg_hi, 16, 16); tcg_temp_free_i32(tcg_ctx, tcg_lo); tcg_temp_free_i32(tcg_ctx, tcg_hi); + tcg_temp_free_ptr(tcg_ctx, fpst); + tcg_temp_free_i32(tcg_ctx, ahp); } break; case 0x56: /* FCVTXN, FCVTXN2 */ @@ -11686,18 +11704,23 @@ static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q, /* 16 -> 32 bit fp conversion */ int srcelt = is_q ? 4 : 0; TCGv_i32 tcg_res[4]; + TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, false); + TCGv_i32 ahp = get_ahp_flag(tcg_ctx); for (pass = 0; pass < 4; pass++) { tcg_res[pass] = tcg_temp_new_i32(tcg_ctx); read_vec_element_i32(s, tcg_res[pass], rn, srcelt + pass, MO_16); gen_helper_vfp_fcvt_f16_to_f32(tcg_ctx, tcg_res[pass], tcg_res[pass], - tcg_ctx->cpu_env); + fpst, ahp); } for (pass = 0; pass < 4; pass++) { write_vec_element_i32(s, tcg_res[pass], rd, pass, MO_32); tcg_temp_free_i32(tcg_ctx, tcg_res[pass]); } + + tcg_temp_free_ptr(tcg_ctx, fpst); + tcg_temp_free_i32(tcg_ctx, ahp); } } diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 6ad3ef35..90930c99 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -3934,38 +3934,56 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn) gen_vfp_sqrt(s, dp); break; case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */ + { + TCGv_ptr fpst = get_fpstatus_ptr(s, false); + TCGv_i32 ahp_mode = get_ahp_flag(tcg_ctx); tmp = gen_vfp_mrs(s); tcg_gen_ext16u_i32(tcg_ctx, tmp, tmp); if (dp) { gen_helper_vfp_fcvt_f16_to_f64(tcg_ctx, tcg_ctx->cpu_F0d, tmp, - tcg_ctx->cpu_env); + fpst, ahp_mode); } else { gen_helper_vfp_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp, - tcg_ctx->cpu_env); + fpst, ahp_mode); } + tcg_temp_free_i32(tcg_ctx, ahp_mode); + tcg_temp_free_ptr(tcg_ctx, fpst); tcg_temp_free_i32(tcg_ctx, tmp); break; + } case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */ + { + TCGv_ptr fpst = get_fpstatus_ptr(s, false); + TCGv_i32 ahp = get_ahp_flag(tcg_ctx); tmp = gen_vfp_mrs(s); tcg_gen_shri_i32(tcg_ctx, tmp, tmp, 16); if (dp) { gen_helper_vfp_fcvt_f16_to_f64(tcg_ctx, tcg_ctx->cpu_F0d, tmp, - tcg_ctx->cpu_env); + fpst, ahp); } else { gen_helper_vfp_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp, - tcg_ctx->cpu_env); + fpst, ahp); } tcg_temp_free_i32(tcg_ctx, tmp); + tcg_temp_free_i32(tcg_ctx, ahp); + tcg_temp_free_ptr(tcg_ctx, fpst); break; + } case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */ + { + TCGv_ptr fpst = get_fpstatus_ptr(s, false); + TCGv_i32 ahp = get_ahp_flag(tcg_ctx); tmp = tcg_temp_new_i32(tcg_ctx); + if (dp) { gen_helper_vfp_fcvt_f64_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0d, - tcg_ctx->cpu_env); + fpst, ahp); } else { gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s, - tcg_ctx->cpu_env); + fpst, ahp); } + tcg_temp_free_i32(tcg_ctx, ahp); + tcg_temp_free_ptr(tcg_ctx, fpst); gen_mov_F0_vreg(s, 0, rd); tmp2 = gen_vfp_mrs(s); tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xffff0000); @@ -3973,15 +3991,21 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn) tcg_temp_free_i32(tcg_ctx, tmp2); gen_vfp_msr(s, tmp); break; + } case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */ + { + TCGv_ptr fpst = get_fpstatus_ptr(s, false); + TCGv_i32 ahp = get_ahp_flag(tcg_ctx); tmp = tcg_temp_new_i32(tcg_ctx); if (dp) { gen_helper_vfp_fcvt_f64_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0d, - tcg_ctx->cpu_env); + fpst, ahp); } else { gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s, - tcg_ctx->cpu_env); + fpst, ahp); } + tcg_temp_free_i32(tcg_ctx, ahp); + tcg_temp_free_ptr(tcg_ctx, fpst); tcg_gen_shli_i32(tcg_ctx, tmp, tmp, 16); gen_mov_F0_vreg(s, 0, rd); tmp2 = gen_vfp_mrs(s); @@ -3990,6 +4014,7 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn) tcg_temp_free_i32(tcg_ctx, tmp2); gen_vfp_msr(s, tmp); break; + } case 8: /* cmp */ gen_vfp_cmp(s, dp); break; @@ -7372,53 +7397,71 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) } break; case NEON_2RM_VCVT_F16_F32: + { + TCGv_ptr fpst; + TCGv_i32 ahp; + if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) || q || (rm & 1)) { return 1; } tmp = tcg_temp_new_i32(tcg_ctx); tmp2 = tcg_temp_new_i32(tcg_ctx); + fpst = get_fpstatus_ptr(s, true); + ahp = get_ahp_flag(tcg_ctx); tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, 0)); - gen_helper_neon_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env); + gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s, fpst, ahp); tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, 1)); - gen_helper_neon_fcvt_f32_to_f16(tcg_ctx, tmp2, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env); + gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tmp2, tcg_ctx->cpu_F0s, fpst, ahp); tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 16); tcg_gen_or_i32(tcg_ctx, tmp2, tmp2, tmp); tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, 2)); - gen_helper_neon_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env); + gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s, fpst, ahp); tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, 3)); neon_store_reg(tcg_ctx, rd, 0, tmp2); tmp2 = tcg_temp_new_i32(tcg_ctx); - gen_helper_neon_fcvt_f32_to_f16(tcg_ctx, tmp2, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env); + gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tmp2, tcg_ctx->cpu_F0s, fpst, ahp); tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 16); tcg_gen_or_i32(tcg_ctx, tmp2, tmp2, tmp); neon_store_reg(tcg_ctx, rd, 1, tmp2); tcg_temp_free_i32(tcg_ctx, tmp); + tcg_temp_free_i32(tcg_ctx, ahp); + tcg_temp_free_ptr(tcg_ctx, fpst); break; + } case NEON_2RM_VCVT_F32_F16: + { + TCGv_ptr fpst; + TCGv_i32 ahp; + if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) || q || (rd & 1)) { return 1; } + fpst = get_fpstatus_ptr(s, true); + ahp = get_ahp_flag(tcg_ctx); tmp3 = tcg_temp_new_i32(tcg_ctx); tmp = neon_load_reg(tcg_ctx, rm, 0); tmp2 = neon_load_reg(tcg_ctx, rm, 1); tcg_gen_ext16u_i32(tcg_ctx, tmp3, tmp); - gen_helper_neon_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, tcg_ctx->cpu_env); + gen_helper_vfp_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, fpst, ahp); tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, 0)); tcg_gen_shri_i32(tcg_ctx, tmp3, tmp, 16); - gen_helper_neon_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, tcg_ctx->cpu_env); + gen_helper_vfp_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, fpst, ahp); tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, 1)); tcg_temp_free_i32(tcg_ctx, tmp); tcg_gen_ext16u_i32(tcg_ctx, tmp3, tmp2); - gen_helper_neon_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, tcg_ctx->cpu_env); + gen_helper_vfp_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, fpst, ahp); tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, 2)); tcg_gen_shri_i32(tcg_ctx, tmp3, tmp2, 16); - gen_helper_neon_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, tcg_ctx->cpu_env); + gen_helper_vfp_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, fpst, ahp); tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, 3)); tcg_temp_free_i32(tcg_ctx, tmp2); tcg_temp_free_i32(tcg_ctx, tmp3); + tcg_temp_free_i32(tcg_ctx, ahp); + tcg_temp_free_ptr(tcg_ctx, fpst); break; + } case NEON_2RM_AESE: case NEON_2RM_AESMC: if (!arm_dc_feature(s, ARM_FEATURE_V8_AES) || ((rm | rd) & 1)) { diff --git a/qemu/target/arm/translate.h b/qemu/target/arm/translate.h index 8a145231..24b1c949 100644 --- a/qemu/target/arm/translate.h +++ b/qemu/target/arm/translate.h @@ -167,4 +167,16 @@ void arm_free_cc(TCGContext *tcg_ctx, DisasCompare *cmp); void arm_jump_cc(TCGContext *tcg_ctx, DisasCompare *cmp, TCGLabel *label); void arm_gen_test_cc(TCGContext *tcg_ctx, int cc, TCGLabel *label); +/* Return state of Alternate Half-precision flag, caller frees result */ +static inline TCGv_i32 get_ahp_flag(TCGContext *tcg_ctx) +{ + TCGv_i32 ret = tcg_temp_new_i32(tcg_ctx); + + tcg_gen_ld_i32(tcg_ctx, ret, tcg_ctx->cpu_env, + offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPSCR])); + tcg_gen_extract_i32(tcg_ctx, ret, ret, 26, 1); + + return ret; +} + #endif /* TARGET_ARM_TRANSLATE_H */ diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 1b4c60fd..237cf62a 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -472,6 +472,7 @@ #define float128_rem float128_rem_x86_64 #define float128_round_to_int float128_round_to_int_x86_64 #define float128_scalbn float128_scalbn_x86_64 +#define float128_silence_nan float128_silence_nan_x86_64 #define float128_sqrt float128_sqrt_x86_64 #define float128_sub float128_sub_x86_64 #define float128_to_float32 float128_to_float32_x86_64 @@ -505,6 +506,7 @@ #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_silence_nan float16_silence_nan_x86_64 #define float16_sqrt float16_sqrt_x86_64 #define float16_squash_input_denormal float16_squash_input_denormal_x86_64 #define float16_sub float16_sub_x86_64 @@ -561,6 +563,7 @@ #define float32_round_to_int float32_round_to_int_x86_64 #define float32_scalbn float32_scalbn_x86_64 #define float32_set_sign float32_set_sign_x86_64 +#define float32_silence_nan float32_silence_nan_x86_64 #define float32_sqrt float32_sqrt_x86_64 #define float32_squash_input_denormal float32_squash_input_denormal_x86_64 #define float32_sub float32_sub_x86_64 @@ -618,6 +621,7 @@ #define float64_round_to_int float64_round_to_int_x86_64 #define float64_scalbn float64_scalbn_x86_64 #define float64_set_sign float64_set_sign_x86_64 +#define float64_silence_nan float64_silence_nan_x86_64 #define float64_sqrt float64_sqrt_x86_64 #define float64_squash_input_denormal float64_squash_input_denormal_x86_64 #define float64_sub float64_sub_x86_64 @@ -663,6 +667,7 @@ #define floatx80_round floatx80_round_x86_64 #define floatx80_round_to_int floatx80_round_to_int_x86_64 #define floatx80_scalbn floatx80_scalbn_x86_64 +#define floatx80_silence_nan floatx80_silence_nan_x86_64 #define floatx80_sqrt floatx80_sqrt_x86_64 #define floatx80_sub floatx80_sub_x86_64 #define floatx80_to_float128 floatx80_to_float128_x86_64