diff options
Diffstat (limited to 'target/arm/translate-a64.c')
-rw-r--r-- | target/arm/translate-a64.c | 89 |
1 files changed, 35 insertions, 54 deletions
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 534c3ff5f3..0fc5e12fab 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -609,25 +609,6 @@ static void write_fp_sreg(DisasContext *s, int reg, TCGv_i32 v) tcg_temp_free_i64(tmp); } -TCGv_ptr get_fpstatus_ptr(bool is_f16) -{ - TCGv_ptr statusptr = tcg_temp_new_ptr(); - int offset; - - /* In A64 all instructions (both FP and Neon) use the FPCR; there - * is no equivalent of the A32 Neon "standard FPSCR value". - * However half-precision operations operate under a different - * FZ16 flag and use vfp.fp_status_f16 instead of vfp.fp_status. - */ - if (is_f16) { - offset = offsetof(CPUARMState, vfp.fp_status_f16); - } else { - offset = offsetof(CPUARMState, vfp.fp_status); - } - tcg_gen_addi_ptr(statusptr, cpu_env, offset); - return statusptr; -} - /* Expand a 2-operand AdvSIMD vector operation using an expander function. */ static void gen_gvec_fn2(DisasContext *s, bool is_q, int rd, int rn, GVecGen2Fn *gvec_fn, int vece) @@ -689,7 +670,7 @@ static void gen_gvec_op3_fpst(DisasContext *s, bool is_q, int rd, int rn, int rm, bool is_fp16, int data, gen_helper_gvec_3_ptr *fn) { - TCGv_ptr fpst = get_fpstatus_ptr(is_fp16); + TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR); tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn), vec_full_reg_offset(s, rm), fpst, @@ -5898,7 +5879,7 @@ static void handle_fp_compare(DisasContext *s, int size, bool cmp_with_zero, bool signal_all_nans) { TCGv_i64 tcg_flags = tcg_temp_new_i64(); - TCGv_ptr fpst = get_fpstatus_ptr(size == MO_16); + TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); if (size == MO_64) { TCGv_i64 tcg_vn, tcg_vm; @@ -6157,7 +6138,7 @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000); break; case 0x3: /* FSQRT */ - fpst = get_fpstatus_ptr(true); + fpst = fpstatus_ptr(FPST_FPCR_F16); gen_helper_sqrt_f16(tcg_res, tcg_op, fpst); break; case 0x8: /* FRINTN */ @@ -6167,7 +6148,7 @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) case 0xc: /* FRINTA */ { TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7)); - fpst = get_fpstatus_ptr(true); + fpst = fpstatus_ptr(FPST_FPCR_F16); gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst); gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst); @@ -6177,11 +6158,11 @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) break; } case 0xe: /* FRINTX */ - fpst = get_fpstatus_ptr(true); + fpst = fpstatus_ptr(FPST_FPCR_F16); gen_helper_advsimd_rinth_exact(tcg_res, tcg_op, fpst); break; case 0xf: /* FRINTI */ - fpst = get_fpstatus_ptr(true); + fpst = fpstatus_ptr(FPST_FPCR_F16); gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst); break; default: @@ -6253,7 +6234,7 @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) g_assert_not_reached(); } - fpst = get_fpstatus_ptr(false); + fpst = fpstatus_ptr(FPST_FPCR); if (rmode >= 0) { TCGv_i32 tcg_rmode = tcg_const_i32(rmode); gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst); @@ -6330,7 +6311,7 @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) g_assert_not_reached(); } - fpst = get_fpstatus_ptr(false); + fpst = fpstatus_ptr(FPST_FPCR); if (rmode >= 0) { TCGv_i32 tcg_rmode = tcg_const_i32(rmode); gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst); @@ -6365,7 +6346,7 @@ static void handle_fp_fcvt(DisasContext *s, int opcode, /* Single to half */ TCGv_i32 tcg_rd = tcg_temp_new_i32(); TCGv_i32 ahp = get_ahp_flag(); - TCGv_ptr fpst = get_fpstatus_ptr(false); + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); 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 */ @@ -6385,7 +6366,7 @@ 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_ptr fpst = fpstatus_ptr(FPST_FPCR); TCGv_i32 ahp = get_ahp_flag(); /* Double to half */ gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, fpst, ahp); @@ -6401,7 +6382,7 @@ 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_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR); TCGv_i32 tcg_ahp = get_ahp_flag(); tcg_gen_ext16u_i32(tcg_rn, tcg_rn); if (dtype == 0) { @@ -6518,7 +6499,7 @@ static void handle_fp_2src_single(DisasContext *s, int opcode, TCGv_ptr fpst; tcg_res = tcg_temp_new_i32(); - fpst = get_fpstatus_ptr(false); + fpst = fpstatus_ptr(FPST_FPCR); tcg_op1 = read_fp_sreg(s, rn); tcg_op2 = read_fp_sreg(s, rm); @@ -6571,7 +6552,7 @@ static void handle_fp_2src_double(DisasContext *s, int opcode, TCGv_ptr fpst; tcg_res = tcg_temp_new_i64(); - fpst = get_fpstatus_ptr(false); + fpst = fpstatus_ptr(FPST_FPCR); tcg_op1 = read_fp_dreg(s, rn); tcg_op2 = read_fp_dreg(s, rm); @@ -6624,7 +6605,7 @@ static void handle_fp_2src_half(DisasContext *s, int opcode, TCGv_ptr fpst; tcg_res = tcg_temp_new_i32(); - fpst = get_fpstatus_ptr(true); + fpst = fpstatus_ptr(FPST_FPCR_F16); tcg_op1 = read_fp_hreg(s, rn); tcg_op2 = read_fp_hreg(s, rm); @@ -6723,7 +6704,7 @@ static void handle_fp_3src_single(DisasContext *s, bool o0, bool o1, { TCGv_i32 tcg_op1, tcg_op2, tcg_op3; TCGv_i32 tcg_res = tcg_temp_new_i32(); - TCGv_ptr fpst = get_fpstatus_ptr(false); + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); tcg_op1 = read_fp_sreg(s, rn); tcg_op2 = read_fp_sreg(s, rm); @@ -6761,7 +6742,7 @@ static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1, { TCGv_i64 tcg_op1, tcg_op2, tcg_op3; TCGv_i64 tcg_res = tcg_temp_new_i64(); - TCGv_ptr fpst = get_fpstatus_ptr(false); + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); tcg_op1 = read_fp_dreg(s, rn); tcg_op2 = read_fp_dreg(s, rm); @@ -6799,7 +6780,7 @@ static void handle_fp_3src_half(DisasContext *s, bool o0, bool o1, { TCGv_i32 tcg_op1, tcg_op2, tcg_op3; TCGv_i32 tcg_res = tcg_temp_new_i32(); - TCGv_ptr fpst = get_fpstatus_ptr(true); + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR_F16); tcg_op1 = read_fp_hreg(s, rn); tcg_op2 = read_fp_hreg(s, rm); @@ -6945,7 +6926,7 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode, TCGv_i32 tcg_shift, tcg_single; TCGv_i64 tcg_double; - tcg_fpstatus = get_fpstatus_ptr(type == 3); + tcg_fpstatus = fpstatus_ptr(type == 3 ? FPST_FPCR_F16 : FPST_FPCR); tcg_shift = tcg_const_i32(64 - scale); @@ -7233,7 +7214,7 @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof) static void handle_fjcvtzs(DisasContext *s, int rd, int rn) { TCGv_i64 t = read_fp_dreg(s, rn); - TCGv_ptr fpstatus = get_fpstatus_ptr(false); + TCGv_ptr fpstatus = fpstatus_ptr(FPST_FPCR); gen_helper_fjcvtzs(t, t, fpstatus); @@ -7847,7 +7828,7 @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn) * Note that correct NaN propagation requires that we do these * operations in exactly the order specified by the pseudocode. */ - TCGv_ptr fpst = get_fpstatus_ptr(size == MO_16); + TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); int fpopcode = opcode | is_min << 4 | is_u << 5; int vmap = (1 << elements) - 1; TCGv_i32 tcg_res32 = do_reduction_op(s, fpopcode, rn, esize, @@ -8359,7 +8340,7 @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn) return; } - fpst = get_fpstatus_ptr(size == MO_16); + fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); break; default: unallocated_encoding(s); @@ -8872,7 +8853,7 @@ static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, int elements, int is_signed, int fracbits, int size) { - TCGv_ptr tcg_fpst = get_fpstatus_ptr(size == MO_16); + TCGv_ptr tcg_fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); TCGv_i32 tcg_shift = NULL; MemOp mop = size | (is_signed ? MO_SIGN : 0); @@ -9053,7 +9034,7 @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar, assert(!(is_scalar && is_q)); tcg_rmode = tcg_const_i32(arm_rmode_to_sf(FPROUNDING_ZERO)); - tcg_fpstatus = get_fpstatus_ptr(size == MO_16); + tcg_fpstatus = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus); fracbits = (16 << size) - immhb; tcg_shift = tcg_const_i32(fracbits); @@ -9392,7 +9373,7 @@ static void handle_3same_float(DisasContext *s, int size, int elements, int fpopcode, int rd, int rn, int rm) { int pass; - TCGv_ptr fpst = get_fpstatus_ptr(false); + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); for (pass = 0; pass < elements; pass++) { if (size) { @@ -9785,7 +9766,7 @@ static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s, return; } - fpst = get_fpstatus_ptr(true); + fpst = fpstatus_ptr(FPST_FPCR_F16); tcg_op1 = read_fp_hreg(s, rn); tcg_op2 = read_fp_hreg(s, rm); @@ -10038,7 +10019,7 @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode, return; } - fpst = get_fpstatus_ptr(size == MO_16); + fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); if (is_double) { TCGv_i64 tcg_op = tcg_temp_new_i64(); @@ -10168,7 +10149,7 @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode, int size, int rn, int rd) { bool is_double = (size == 3); - TCGv_ptr fpst = get_fpstatus_ptr(false); + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); if (is_double) { TCGv_i64 tcg_op = tcg_temp_new_i64(); @@ -10309,7 +10290,7 @@ 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_ptr fpst = fpstatus_ptr(FPST_FPCR); TCGv_i32 ahp = get_ahp_flag(); tcg_gen_extr_i64_i32(tcg_lo, tcg_hi, tcg_op); @@ -10571,7 +10552,7 @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) if (is_fcvt) { tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode)); - tcg_fpstatus = get_fpstatus_ptr(false); + tcg_fpstatus = fpstatus_ptr(FPST_FPCR); gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus); } else { tcg_rmode = NULL; @@ -11396,7 +11377,7 @@ static void handle_simd_3same_pair(DisasContext *s, int is_q, int u, int opcode, /* Floating point operations need fpst */ if (opcode >= 0x58) { - fpst = get_fpstatus_ptr(false); + fpst = fpstatus_ptr(FPST_FPCR); } else { fpst = NULL; } @@ -11994,7 +11975,7 @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn) break; } - fpst = get_fpstatus_ptr(true); + fpst = fpstatus_ptr(FPST_FPCR_F16); if (pairwise) { int maxpass = is_q ? 8 : 4; @@ -12287,7 +12268,7 @@ 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_ptr fpst = fpstatus_ptr(FPST_FPCR); TCGv_i32 ahp = get_ahp_flag(); for (pass = 0; pass < 4; pass++) { @@ -12759,7 +12740,7 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) } if (need_fpstatus || need_rmode) { - tcg_fpstatus = get_fpstatus_ptr(false); + tcg_fpstatus = fpstatus_ptr(FPST_FPCR); } else { tcg_fpstatus = NULL; } @@ -13149,7 +13130,7 @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) } if (need_rmode || need_fpst) { - tcg_fpstatus = get_fpstatus_ptr(true); + tcg_fpstatus = fpstatus_ptr(FPST_FPCR_F16); } if (need_rmode) { @@ -13458,7 +13439,7 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) } if (is_fp) { - fpst = get_fpstatus_ptr(is_fp16); + fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR); } else { fpst = NULL; } |