aboutsummaryrefslogtreecommitdiff
path: root/target/arm/translate-a64.c
diff options
context:
space:
mode:
authorAlex Bennée <alex.bennee@linaro.org>2018-05-07 13:17:16 +0100
committerRichard Henderson <richard.henderson@linaro.org>2018-05-17 15:27:09 -0700
commit486624fcd3eaca6165ab8401d73bbae6c0fb81c1 (patch)
tree27e312af8e35ffa07c146a56f1da899fee9ee9df /target/arm/translate-a64.c
parent0bcfbcbea548656ff930394f296589728c2a0c5d (diff)
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. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/arm/translate-a64.c')
-rw-r--r--target/arm/translate-a64.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index a0b0c43d12..d8284678f7 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -5147,10 +5147,15 @@ static void handle_fp_fcvt(DisasContext *s, int opcode,
} else {
/* Single to half */
TCGv_i32 tcg_rd = tcg_temp_new_i32();
- gen_helper_vfp_fcvt_f32_to_f16(tcg_rd, tcg_rn, cpu_env);
+ TCGv_i32 ahp = get_ahp_flag();
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
+
+ gen_helper_vfp_fcvt_f32_to_f16(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_rd);
+ tcg_temp_free_i32(ahp);
+ tcg_temp_free_ptr(fpst);
}
tcg_temp_free_i32(tcg_rn);
break;
@@ -5163,9 +5168,13 @@ static void handle_fp_fcvt(DisasContext *s, int opcode,
/* Double to single */
gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, cpu_env);
} else {
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
+ TCGv_i32 ahp = get_ahp_flag();
/* Double to half */
- gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, cpu_env);
+ gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, fpst, ahp);
/* write_fp_sreg is OK here because top half of tcg_rd is zero */
+ tcg_temp_free_ptr(fpst);
+ tcg_temp_free_i32(ahp);
}
write_fp_sreg(s, rd, tcg_rd);
tcg_temp_free_i32(tcg_rd);
@@ -5175,17 +5184,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(false);
+ TCGv_i32 tcg_ahp = get_ahp_flag();
tcg_gen_ext16u_i32(tcg_rn, tcg_rn);
if (dtype == 0) {
/* Half to single */
TCGv_i32 tcg_rd = tcg_temp_new_i32();
- gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, cpu_env);
+ gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp);
write_fp_sreg(s, rd, tcg_rd);
+ tcg_temp_free_ptr(tcg_fpst);
+ tcg_temp_free_i32(tcg_ahp);
tcg_temp_free_i32(tcg_rd);
} else {
/* Half to double */
TCGv_i64 tcg_rd = tcg_temp_new_i64();
- gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, cpu_env);
+ gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp);
write_fp_dreg(s, rd, tcg_rd);
tcg_temp_free_i64(tcg_rd);
}
@@ -9053,12 +9066,17 @@ static void handle_2misc_narrow(DisasContext *s, bool scalar,
} else {
TCGv_i32 tcg_lo = tcg_temp_new_i32();
TCGv_i32 tcg_hi = tcg_temp_new_i32();
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
+ TCGv_i32 ahp = get_ahp_flag();
+
tcg_gen_extr_i64_i32(tcg_lo, tcg_hi, tcg_op);
- gen_helper_vfp_fcvt_f32_to_f16(tcg_lo, tcg_lo, cpu_env);
- gen_helper_vfp_fcvt_f32_to_f16(tcg_hi, tcg_hi, cpu_env);
+ gen_helper_vfp_fcvt_f32_to_f16(tcg_lo, tcg_lo, fpst, ahp);
+ gen_helper_vfp_fcvt_f32_to_f16(tcg_hi, tcg_hi, fpst, ahp);
tcg_gen_deposit_i32(tcg_res[pass], tcg_lo, tcg_hi, 16, 16);
tcg_temp_free_i32(tcg_lo);
tcg_temp_free_i32(tcg_hi);
+ tcg_temp_free_ptr(fpst);
+ tcg_temp_free_i32(ahp);
}
break;
case 0x56: /* FCVTXN, FCVTXN2 */
@@ -11532,18 +11550,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(false);
+ TCGv_i32 ahp = get_ahp_flag();
for (pass = 0; pass < 4; pass++) {
tcg_res[pass] = tcg_temp_new_i32();
read_vec_element_i32(s, tcg_res[pass], rn, srcelt + pass, MO_16);
gen_helper_vfp_fcvt_f16_to_f32(tcg_res[pass], tcg_res[pass],
- 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_res[pass]);
}
+
+ tcg_temp_free_ptr(fpst);
+ tcg_temp_free_i32(ahp);
}
}