target/arm: Replace A64 get_fpstatus_ptr() with generic fpstatus_ptr()

We currently have two versions of get_fpstatus_ptr(), which both take
an effectively boolean argument:
* the one for A64 takes "bool is_f16" to distinguish fp16 from other ops
* the one for A32/T32 takes "int neon" to distinguish Neon from other ops

This is confusing, and to implement ARMv8.2-FP16 the A32/T32 one will
need to make a four-way distinction between "non-Neon, FP16",
"non-Neon, single/double", "Neon, FP16" and "Neon, single/double".
The A64 version will then be a strict subset of the A32/T32 version.

To clean this all up, we want to go to a single implementation which
takes an enum argument with values FPST_FPCR, FPST_STD,
FPST_FPCR_F16, and FPST_STD_F16. We rename the function to
fpstatus_ptr() so that unconverted code gets a compilation error
rather than silently passing the wrong thing to the new function.

This commit implements that new API, and converts A64 to use it:
get_fpstatus_ptr(false) -> fpstatus_ptr(FPST_FPCR)
get_fpstatus_ptr(true) -> fpstatus_ptr(FPST_FPCR_F16)

Backports commit cdfb22bb7326fee607d9553358856cca341dbc9a
This commit is contained in:
Peter Maydell 2021-02-26 11:46:49 -05:00 committed by Lioncash
parent e9240f0f54
commit 79359e3a69
4 changed files with 103 additions and 72 deletions

View file

@ -768,25 +768,6 @@ static void write_fp_sreg(DisasContext *s, int reg, TCGv_i32 v)
tcg_temp_free_i64(tcg_ctx, tmp); tcg_temp_free_i64(tcg_ctx, tmp);
} }
TCGv_ptr get_fpstatus_ptr(TCGContext *tcg_ctx, bool is_f16)
{
TCGv_ptr statusptr = tcg_temp_new_ptr(tcg_ctx);
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(tcg_ctx, statusptr, tcg_ctx->cpu_env, offset);
return statusptr;
}
/* Expand a 2-operand AdvSIMD vector operation using an expander function. */ /* 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, static void gen_gvec_fn2(DisasContext *s, bool is_q, int rd, int rn,
GVecGen2Fn *gvec_fn, int vece) GVecGen2Fn *gvec_fn, int vece)
@ -862,7 +843,7 @@ static void gen_gvec_op3_fpst(DisasContext *s, bool is_q, int rd, int rn,
{ {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, is_fp16); TCGv_ptr fpst = fpstatus_ptr(tcg_ctx, is_fp16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, rd), tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, rd),
vec_full_reg_offset(s, rn), vec_full_reg_offset(s, rn),
vec_full_reg_offset(s, rm), fpst, vec_full_reg_offset(s, rm), fpst,
@ -6135,7 +6116,7 @@ static void handle_fp_compare(DisasContext *s, int size,
{ {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
TCGv_i64 tcg_flags = tcg_temp_new_i64(tcg_ctx); TCGv_i64 tcg_flags = tcg_temp_new_i64(tcg_ctx);
TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, size == MO_16); TCGv_ptr fpst = fpstatus_ptr(tcg_ctx, size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
if (size == MO_64) { if (size == MO_64) {
TCGv_i64 tcg_vn, tcg_vm; TCGv_i64 tcg_vn, tcg_vm;
@ -6397,7 +6378,7 @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
tcg_gen_xori_i32(tcg_ctx, tcg_res, tcg_op, 0x8000); tcg_gen_xori_i32(tcg_ctx, tcg_res, tcg_op, 0x8000);
break; break;
case 0x3: /* FSQRT */ case 0x3: /* FSQRT */
fpst = get_fpstatus_ptr(tcg_ctx, true); fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR_F16);
gen_helper_sqrt_f16(tcg_ctx, tcg_res, tcg_op, fpst); gen_helper_sqrt_f16(tcg_ctx, tcg_res, tcg_op, fpst);
break; break;
case 0x8: /* FRINTN */ case 0x8: /* FRINTN */
@ -6407,7 +6388,7 @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
case 0xc: /* FRINTA */ case 0xc: /* FRINTA */
{ {
TCGv_i32 tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(opcode & 7)); TCGv_i32 tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(opcode & 7));
fpst = get_fpstatus_ptr(tcg_ctx, true); fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR_F16);
gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, fpst); gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, fpst);
gen_helper_advsimd_rinth(tcg_ctx, tcg_res, tcg_op, fpst); gen_helper_advsimd_rinth(tcg_ctx, tcg_res, tcg_op, fpst);
@ -6417,11 +6398,11 @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
break; break;
} }
case 0xe: /* FRINTX */ case 0xe: /* FRINTX */
fpst = get_fpstatus_ptr(tcg_ctx, true); fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR_F16);
gen_helper_advsimd_rinth_exact(tcg_ctx, tcg_res, tcg_op, fpst); gen_helper_advsimd_rinth_exact(tcg_ctx, tcg_res, tcg_op, fpst);
break; break;
case 0xf: /* FRINTI */ case 0xf: /* FRINTI */
fpst = get_fpstatus_ptr(tcg_ctx, true); fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR_F16);
gen_helper_advsimd_rinth(tcg_ctx, tcg_res, tcg_op, fpst); gen_helper_advsimd_rinth(tcg_ctx, tcg_res, tcg_op, fpst);
break; break;
default: default:
@ -6494,7 +6475,7 @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
g_assert_not_reached(); g_assert_not_reached();
} }
fpst = get_fpstatus_ptr(tcg_ctx, false); fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
if (rmode >= 0) { if (rmode >= 0) {
TCGv_i32 tcg_rmode = tcg_const_i32(tcg_ctx, rmode); TCGv_i32 tcg_rmode = tcg_const_i32(tcg_ctx, rmode);
gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, fpst); gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, fpst);
@ -6572,7 +6553,7 @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
g_assert_not_reached(); g_assert_not_reached();
} }
fpst = get_fpstatus_ptr(tcg_ctx, false); fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
if (rmode >= 0) { if (rmode >= 0) {
TCGv_i32 tcg_rmode = tcg_const_i32(tcg_ctx, rmode); TCGv_i32 tcg_rmode = tcg_const_i32(tcg_ctx, rmode);
gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, fpst); gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, fpst);
@ -6609,7 +6590,7 @@ static void handle_fp_fcvt(DisasContext *s, int opcode,
/* Single to half */ /* Single to half */
TCGv_i32 tcg_rd = tcg_temp_new_i32(tcg_ctx); TCGv_i32 tcg_rd = tcg_temp_new_i32(tcg_ctx);
TCGv_i32 ahp = get_ahp_flag(s); TCGv_i32 ahp = get_ahp_flag(s);
TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, false); TCGv_ptr fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tcg_rd, tcg_rn, fpst, ahp); 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 is OK here because top half of tcg_rd is zero */
@ -6629,7 +6610,7 @@ static void handle_fp_fcvt(DisasContext *s, int opcode,
/* Double to single */ /* Double to single */
gen_helper_vfp_fcvtsd(tcg_ctx, tcg_rd, tcg_rn, tcg_ctx->cpu_env); gen_helper_vfp_fcvtsd(tcg_ctx, tcg_rd, tcg_rn, tcg_ctx->cpu_env);
} else { } else {
TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, false); TCGv_ptr fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
TCGv_i32 ahp = get_ahp_flag(s); TCGv_i32 ahp = get_ahp_flag(s);
/* Double to half */ /* Double to half */
gen_helper_vfp_fcvt_f64_to_f16(tcg_ctx, tcg_rd, tcg_rn, fpst, ahp); gen_helper_vfp_fcvt_f64_to_f16(tcg_ctx, tcg_rd, tcg_rn, fpst, ahp);
@ -6645,7 +6626,7 @@ static void handle_fp_fcvt(DisasContext *s, int opcode,
case 0x3: case 0x3:
{ {
TCGv_i32 tcg_rn = read_fp_sreg(s, rn); TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
TCGv_ptr tcg_fpst = get_fpstatus_ptr(tcg_ctx, false); TCGv_ptr tcg_fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
TCGv_i32 tcg_ahp = get_ahp_flag(s); TCGv_i32 tcg_ahp = get_ahp_flag(s);
tcg_gen_ext16u_i32(tcg_ctx, tcg_rn, tcg_rn); tcg_gen_ext16u_i32(tcg_ctx, tcg_rn, tcg_rn);
if (dtype == 0) { if (dtype == 0) {
@ -6763,7 +6744,7 @@ static void handle_fp_2src_single(DisasContext *s, int opcode,
TCGv_ptr fpst; TCGv_ptr fpst;
tcg_res = tcg_temp_new_i32(tcg_ctx); tcg_res = tcg_temp_new_i32(tcg_ctx);
fpst = get_fpstatus_ptr(tcg_ctx, false); fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
tcg_op1 = read_fp_sreg(s, rn); tcg_op1 = read_fp_sreg(s, rn);
tcg_op2 = read_fp_sreg(s, rm); tcg_op2 = read_fp_sreg(s, rm);
@ -6817,7 +6798,7 @@ static void handle_fp_2src_double(DisasContext *s, int opcode,
TCGv_ptr fpst; TCGv_ptr fpst;
tcg_res = tcg_temp_new_i64(tcg_ctx); tcg_res = tcg_temp_new_i64(tcg_ctx);
fpst = get_fpstatus_ptr(tcg_ctx, false); fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
tcg_op1 = read_fp_dreg(s, rn); tcg_op1 = read_fp_dreg(s, rn);
tcg_op2 = read_fp_dreg(s, rm); tcg_op2 = read_fp_dreg(s, rm);
@ -6872,7 +6853,7 @@ static void handle_fp_2src_half(DisasContext *s, int opcode,
TCGv_ptr fpst; TCGv_ptr fpst;
tcg_res = tcg_temp_new_i32(tcg_ctx); tcg_res = tcg_temp_new_i32(tcg_ctx);
fpst = get_fpstatus_ptr(tcg_ctx, true); fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR_F16);
tcg_op1 = read_fp_hreg(s, rn); tcg_op1 = read_fp_hreg(s, rn);
tcg_op2 = read_fp_hreg(s, rm); tcg_op2 = read_fp_hreg(s, rm);
@ -6972,7 +6953,7 @@ static void handle_fp_3src_single(DisasContext *s, bool o0, bool o1,
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
TCGv_i32 tcg_op1, tcg_op2, tcg_op3; TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
TCGv_i32 tcg_res = tcg_temp_new_i32(tcg_ctx); TCGv_i32 tcg_res = tcg_temp_new_i32(tcg_ctx);
TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, false); TCGv_ptr fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
tcg_op1 = read_fp_sreg(s, rn); tcg_op1 = read_fp_sreg(s, rn);
tcg_op2 = read_fp_sreg(s, rm); tcg_op2 = read_fp_sreg(s, rm);
@ -7011,7 +6992,7 @@ static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
TCGv_i64 tcg_op1, tcg_op2, tcg_op3; TCGv_i64 tcg_op1, tcg_op2, tcg_op3;
TCGv_i64 tcg_res = tcg_temp_new_i64(tcg_ctx); TCGv_i64 tcg_res = tcg_temp_new_i64(tcg_ctx);
TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, false); TCGv_ptr fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
tcg_op1 = read_fp_dreg(s, rn); tcg_op1 = read_fp_dreg(s, rn);
tcg_op2 = read_fp_dreg(s, rm); tcg_op2 = read_fp_dreg(s, rm);
@ -7051,7 +7032,7 @@ static void handle_fp_3src_half(DisasContext *s, bool o0, bool o1,
TCGv_i32 tcg_op1, tcg_op2, tcg_op3; TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
TCGv_i32 tcg_res = tcg_temp_new_i32(tcg_ctx); TCGv_i32 tcg_res = tcg_temp_new_i32(tcg_ctx);
TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, true); TCGv_ptr fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR_F16);
tcg_op1 = read_fp_hreg(s, rn); tcg_op1 = read_fp_hreg(s, rn);
tcg_op2 = read_fp_hreg(s, rm); tcg_op2 = read_fp_hreg(s, rm);
@ -7199,7 +7180,7 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
TCGv_i32 tcg_shift, tcg_single; TCGv_i32 tcg_shift, tcg_single;
TCGv_i64 tcg_double; TCGv_i64 tcg_double;
tcg_fpstatus = get_fpstatus_ptr(tcg_ctx, type == 3); tcg_fpstatus = fpstatus_ptr(tcg_ctx, type == 3 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_shift = tcg_const_i32(tcg_ctx, 64 - scale); tcg_shift = tcg_const_i32(tcg_ctx, 64 - scale);
@ -7489,7 +7470,7 @@ static void handle_fjcvtzs(DisasContext *s, int rd, int rn)
{ {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
TCGv_i64 t = read_fp_dreg(s, rn); TCGv_i64 t = read_fp_dreg(s, rn);
TCGv_ptr fpstatus = get_fpstatus_ptr(tcg_ctx, false); TCGv_ptr fpstatus = fpstatus_ptr(tcg_ctx, FPST_FPCR);
gen_helper_fjcvtzs(tcg_ctx, t, t, fpstatus); gen_helper_fjcvtzs(tcg_ctx, t, t, fpstatus);
@ -8109,7 +8090,7 @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
* Note that correct NaN propagation requires that we do these * Note that correct NaN propagation requires that we do these
* operations in exactly the order specified by the pseudocode. * operations in exactly the order specified by the pseudocode.
*/ */
TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, size == MO_16); TCGv_ptr fpst = fpstatus_ptr(tcg_ctx, size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
int fpopcode = opcode | is_min << 4 | is_u << 5; int fpopcode = opcode | is_min << 4 | is_u << 5;
int vmap = (1 << elements) - 1; int vmap = (1 << elements) - 1;
TCGv_i32 tcg_res32 = do_reduction_op(s, fpopcode, rn, esize, TCGv_i32 tcg_res32 = do_reduction_op(s, fpopcode, rn, esize,
@ -8628,7 +8609,7 @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
return; return;
} }
fpst = get_fpstatus_ptr(tcg_ctx, size == MO_16); fpst = fpstatus_ptr(tcg_ctx, size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
break; break;
default: default:
unallocated_encoding(s); unallocated_encoding(s);
@ -9147,7 +9128,7 @@ static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn,
int fracbits, int size) int fracbits, int size)
{ {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
TCGv_ptr tcg_fpst = get_fpstatus_ptr(tcg_ctx, size == MO_16); TCGv_ptr tcg_fpst = fpstatus_ptr(tcg_ctx, size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
TCGv_i32 tcg_shift = NULL; TCGv_i32 tcg_shift = NULL;
MemOp mop = size | (is_signed ? MO_SIGN : 0); MemOp mop = size | (is_signed ? MO_SIGN : 0);
@ -9329,7 +9310,7 @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
assert(!(is_scalar && is_q)); assert(!(is_scalar && is_q));
tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(FPROUNDING_ZERO)); tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(FPROUNDING_ZERO));
tcg_fpstatus = get_fpstatus_ptr(tcg_ctx, size == MO_16); tcg_fpstatus = fpstatus_ptr(tcg_ctx, size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_fpstatus); gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_fpstatus);
fracbits = (16 << size) - immhb; fracbits = (16 << size) - immhb;
tcg_shift = tcg_const_i32(tcg_ctx, fracbits); tcg_shift = tcg_const_i32(tcg_ctx, fracbits);
@ -9671,7 +9652,7 @@ static void handle_3same_float(DisasContext *s, int size, int elements,
{ {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
int pass; int pass;
TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, false); TCGv_ptr fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
for (pass = 0; pass < elements; pass++) { for (pass = 0; pass < elements; pass++) {
if (size) { if (size) {
@ -10066,7 +10047,7 @@ static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s,
return; return;
} }
fpst = get_fpstatus_ptr(tcg_ctx, true); fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR_F16);
tcg_op1 = read_fp_hreg(s, rn); tcg_op1 = read_fp_hreg(s, rn);
tcg_op2 = read_fp_hreg(s, rm); tcg_op2 = read_fp_hreg(s, rm);
@ -10322,7 +10303,7 @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
return; return;
} }
fpst = get_fpstatus_ptr(tcg_ctx, size == MO_16); fpst = fpstatus_ptr(tcg_ctx, size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
if (is_double) { if (is_double) {
TCGv_i64 tcg_op = tcg_temp_new_i64(tcg_ctx); TCGv_i64 tcg_op = tcg_temp_new_i64(tcg_ctx);
@ -10453,7 +10434,7 @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode,
{ {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
bool is_double = (size == 3); bool is_double = (size == 3);
TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, false); TCGv_ptr fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
if (is_double) { if (is_double) {
TCGv_i64 tcg_op = tcg_temp_new_i64(tcg_ctx); TCGv_i64 tcg_op = tcg_temp_new_i64(tcg_ctx);
@ -10595,7 +10576,7 @@ static void handle_2misc_narrow(DisasContext *s, bool scalar,
} else { } else {
TCGv_i32 tcg_lo = tcg_temp_new_i32(tcg_ctx); TCGv_i32 tcg_lo = tcg_temp_new_i32(tcg_ctx);
TCGv_i32 tcg_hi = 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_ptr fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
TCGv_i32 ahp = get_ahp_flag(s); TCGv_i32 ahp = get_ahp_flag(s);
tcg_gen_extr_i64_i32(tcg_ctx, tcg_lo, tcg_hi, tcg_op); tcg_gen_extr_i64_i32(tcg_ctx, tcg_lo, tcg_hi, tcg_op);
@ -10859,7 +10840,7 @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
if (is_fcvt) { if (is_fcvt) {
tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(rmode)); tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(rmode));
tcg_fpstatus = get_fpstatus_ptr(tcg_ctx, false); tcg_fpstatus = fpstatus_ptr(tcg_ctx, FPST_FPCR);
gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_fpstatus); gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_fpstatus);
} else { } else {
tcg_rmode = NULL; tcg_rmode = NULL;
@ -11691,7 +11672,7 @@ static void handle_simd_3same_pair(DisasContext *s, int is_q, int u, int opcode,
/* Floating point operations need fpst */ /* Floating point operations need fpst */
if (opcode >= 0x58) { if (opcode >= 0x58) {
fpst = get_fpstatus_ptr(tcg_ctx, false); fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
} else { } else {
fpst = NULL; fpst = NULL;
} }
@ -12296,7 +12277,7 @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
break; break;
} }
fpst = get_fpstatus_ptr(tcg_ctx, true); fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR_F16);
if (pairwise) { if (pairwise) {
int maxpass = is_q ? 8 : 4; int maxpass = is_q ? 8 : 4;
@ -12589,7 +12570,7 @@ static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q,
/* 16 -> 32 bit fp conversion */ /* 16 -> 32 bit fp conversion */
int srcelt = is_q ? 4 : 0; int srcelt = is_q ? 4 : 0;
TCGv_i32 tcg_res[4]; TCGv_i32 tcg_res[4];
TCGv_ptr fpst = get_fpstatus_ptr(tcg_ctx, false); TCGv_ptr fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR);
TCGv_i32 ahp = get_ahp_flag(s); TCGv_i32 ahp = get_ahp_flag(s);
for (pass = 0; pass < 4; pass++) { for (pass = 0; pass < 4; pass++) {
@ -13066,7 +13047,7 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
} }
if (need_fpstatus || need_rmode) { if (need_fpstatus || need_rmode) {
tcg_fpstatus = get_fpstatus_ptr(tcg_ctx, false); tcg_fpstatus = fpstatus_ptr(tcg_ctx, FPST_FPCR);
} else { } else {
tcg_fpstatus = NULL; tcg_fpstatus = NULL;
} }
@ -13457,7 +13438,7 @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
} }
if (need_rmode || need_fpst) { if (need_rmode || need_fpst) {
tcg_fpstatus = get_fpstatus_ptr(tcg_ctx, true); tcg_fpstatus = fpstatus_ptr(tcg_ctx, FPST_FPCR_F16);
} }
if (need_rmode) { if (need_rmode) {
@ -13767,7 +13748,7 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
} }
if (is_fp) { if (is_fp) {
fpst = get_fpstatus_ptr(tcg_ctx, is_fp16); fpst = fpstatus_ptr(tcg_ctx, is_fp16 ? FPST_FPCR_F16 : FPST_FPCR);
} else { } else {
fpst = NULL; fpst = NULL;
} }

View file

@ -37,7 +37,6 @@ TCGv_i64 cpu_reg_sp(DisasContext *s, int reg);
TCGv_i64 read_cpu_reg(DisasContext *s, int reg, int sf); TCGv_i64 read_cpu_reg(DisasContext *s, int reg, int sf);
TCGv_i64 read_cpu_reg_sp(DisasContext *s, int reg, int sf); TCGv_i64 read_cpu_reg_sp(DisasContext *s, int reg, int sf);
void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v); void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v);
TCGv_ptr get_fpstatus_ptr(TCGContext *, bool);
bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn, bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
unsigned int imms, unsigned int immr); unsigned int imms, unsigned int immr);
bool sve_access_check(DisasContext *s); bool sve_access_check(DisasContext *s);

View file

@ -3598,7 +3598,7 @@ static bool trans_FMLA_zzxz(DisasContext *s, arg_FMLA_zzxz *a)
if (sve_access_check(s)) { if (sve_access_check(s)) {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_4_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd), tcg_gen_gvec_4_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm), vec_full_reg_offset(s, a->rm),
@ -3625,7 +3625,7 @@ static bool trans_FMUL_zzx(DisasContext *s, arg_FMUL_zzx *a)
if (sve_access_check(s)) { if (sve_access_check(s)) {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd), tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm), vec_full_reg_offset(s, a->rm),
@ -3658,7 +3658,7 @@ static void do_reduce(DisasContext *s, arg_rpr_esz *a,
tcg_gen_addi_ptr(tcg_ctx, t_zn, tcg_ctx->cpu_env, vec_full_reg_offset(s, a->rn)); tcg_gen_addi_ptr(tcg_ctx, t_zn, tcg_ctx->cpu_env, vec_full_reg_offset(s, a->rn));
tcg_gen_addi_ptr(tcg_ctx, t_pg, tcg_ctx->cpu_env, pred_full_reg_offset(s, a->pg)); tcg_gen_addi_ptr(tcg_ctx, t_pg, tcg_ctx->cpu_env, pred_full_reg_offset(s, a->pg));
status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
fn(tcg_ctx, temp, t_zn, t_pg, status, t_desc); fn(tcg_ctx, temp, t_zn, t_pg, status, t_desc);
tcg_temp_free_ptr(tcg_ctx, t_zn); tcg_temp_free_ptr(tcg_ctx, t_zn);
@ -3701,7 +3701,7 @@ static void do_zz_fp(DisasContext *s, arg_rr_esz *a, gen_helper_gvec_2_ptr *fn)
{ {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_2_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd), tcg_gen_gvec_2_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
@ -3750,7 +3750,7 @@ static void do_ppz_fp(DisasContext *s, arg_rpr_esz *a,
{ {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_3_ptr(tcg_ctx, pred_full_reg_offset(s, a->rd), tcg_gen_gvec_3_ptr(tcg_ctx, pred_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
@ -3803,7 +3803,7 @@ static bool trans_FTMAD(DisasContext *s, arg_FTMAD *a)
if (sve_access_check(s)) { if (sve_access_check(s)) {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd), tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm), vec_full_reg_offset(s, a->rm),
@ -3844,7 +3844,7 @@ static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a)
t_pg = tcg_temp_new_ptr(tcg_ctx); t_pg = tcg_temp_new_ptr(tcg_ctx);
tcg_gen_addi_ptr(tcg_ctx, t_rm, tcg_ctx->cpu_env, vec_full_reg_offset(s, a->rm)); tcg_gen_addi_ptr(tcg_ctx, t_rm, tcg_ctx->cpu_env, vec_full_reg_offset(s, a->rm));
tcg_gen_addi_ptr(tcg_ctx, t_pg, tcg_ctx->cpu_env, pred_full_reg_offset(s, a->pg)); tcg_gen_addi_ptr(tcg_ctx, t_pg, tcg_ctx->cpu_env, pred_full_reg_offset(s, a->pg));
t_fpst = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); t_fpst = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
t_desc = tcg_const_i32(tcg_ctx, simd_desc(vsz, vsz, 0)); t_desc = tcg_const_i32(tcg_ctx, simd_desc(vsz, vsz, 0));
fns[a->esz - 1](tcg_ctx, t_val, t_val, t_rm, t_pg, t_fpst, t_desc); fns[a->esz - 1](tcg_ctx, t_val, t_val, t_rm, t_pg, t_fpst, t_desc);
@ -3872,7 +3872,7 @@ static bool do_zzz_fp(DisasContext *s, arg_rrr_esz *a,
if (sve_access_check(s)) { if (sve_access_check(s)) {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd), tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm), vec_full_reg_offset(s, a->rm),
@ -3915,7 +3915,7 @@ static bool do_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
if (sve_access_check(s)) { if (sve_access_check(s)) {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_4_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd), tcg_gen_gvec_4_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm), vec_full_reg_offset(s, a->rm),
@ -3968,7 +3968,7 @@ static void do_fp_scalar(DisasContext *s, int zd, int zn, int pg, bool is_fp16,
tcg_gen_addi_ptr(tcg_ctx, t_zn, tcg_ctx->cpu_env, vec_full_reg_offset(s, zn)); tcg_gen_addi_ptr(tcg_ctx, t_zn, tcg_ctx->cpu_env, vec_full_reg_offset(s, zn));
tcg_gen_addi_ptr(tcg_ctx, t_pg, tcg_ctx->cpu_env, pred_full_reg_offset(s, pg)); tcg_gen_addi_ptr(tcg_ctx, t_pg, tcg_ctx->cpu_env, pred_full_reg_offset(s, pg));
status = get_fpstatus_ptr(tcg_ctx, is_fp16); status = fpstatus_ptr(tcg_ctx, is_fp16 ? FPST_FPCR_F16 : FPST_FPCR);
desc = tcg_const_i32(tcg_ctx, simd_desc(vsz, vsz, 0)); desc = tcg_const_i32(tcg_ctx, simd_desc(vsz, vsz, 0));
fn(tcg_ctx, t_zd, t_zn, t_pg, scalar, status, desc); fn(tcg_ctx, t_zd, t_zn, t_pg, scalar, status, desc);
@ -4034,7 +4034,7 @@ static bool do_fp_cmp(DisasContext *s, arg_rprr_esz *a,
if (sve_access_check(s)) { if (sve_access_check(s)) {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_4_ptr(tcg_ctx, pred_full_reg_offset(s, a->rd), tcg_gen_gvec_4_ptr(tcg_ctx, pred_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm), vec_full_reg_offset(s, a->rm),
@ -4079,7 +4079,7 @@ static bool trans_FCADD(DisasContext *s, arg_FCADD *a)
if (sve_access_check(s)) { if (sve_access_check(s)) {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_4_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd), tcg_gen_gvec_4_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm), vec_full_reg_offset(s, a->rm),
@ -4100,7 +4100,7 @@ static bool do_fmla(DisasContext *s, arg_rprrr_esz *a,
if (sve_access_check(s)) { if (sve_access_check(s)) {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_5_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd), tcg_gen_gvec_5_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm), vec_full_reg_offset(s, a->rm),
@ -4145,7 +4145,7 @@ static bool trans_FCMLA_zpzzz(DisasContext *s, arg_FCMLA_zpzzz *a)
if (sve_access_check(s)) { if (sve_access_check(s)) {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_5_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd), tcg_gen_gvec_5_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm), vec_full_reg_offset(s, a->rm),
@ -4169,7 +4169,7 @@ static bool trans_FCMLA_zzxz(DisasContext *s, arg_FCMLA_zzxz *a)
if (sve_access_check(s)) { if (sve_access_check(s)) {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd), tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm), vec_full_reg_offset(s, a->rm),
@ -4191,7 +4191,7 @@ static bool do_zpz_ptr(DisasContext *s, int rd, int rn, int pg,
if (sve_access_check(s)) { if (sve_access_check(s)) {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, is_fp16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, is_fp16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, rd), tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, rd),
vec_full_reg_offset(s, rn), vec_full_reg_offset(s, rn),
pred_full_reg_offset(s, pg), pred_full_reg_offset(s, pg),
@ -4338,7 +4338,7 @@ static bool do_frint_mode(DisasContext *s, arg_rpr_esz *a, int mode)
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_i32 tmode = tcg_const_i32(tcg_ctx, mode); TCGv_i32 tmode = tcg_const_i32(tcg_ctx, mode);
TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); TCGv_ptr status = fpstatus_ptr(tcg_ctx, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
gen_helper_set_rmode(tcg_ctx, tmode, tmode, status); gen_helper_set_rmode(tcg_ctx, tmode, tmode, status);

View file

@ -401,4 +401,55 @@ typedef void CryptoThreeOpIntFn(TCGContext *, TCGv_ptr, TCGv_ptr, TCGv_i32);
typedef void CryptoThreeOpFn(TCGContext *, TCGv_ptr, TCGv_ptr, TCGv_ptr); typedef void CryptoThreeOpFn(TCGContext *, TCGv_ptr, TCGv_ptr, TCGv_ptr);
typedef void AtomicThreeOpFn(TCGContext *, TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp); typedef void AtomicThreeOpFn(TCGContext *, TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
/*
* Enum for argument to fpstatus_ptr().
*/
typedef enum ARMFPStatusFlavour {
FPST_FPCR,
FPST_FPCR_F16,
FPST_STD,
FPST_STD_F16,
} ARMFPStatusFlavour;
/**
* fpstatus_ptr: return TCGv_ptr to the specified fp_status field
*
* We have multiple softfloat float_status fields in the Arm CPU state struct
* (see the comment in cpu.h for details). Return a TCGv_ptr which has
* been set up to point to the requested field in the CPU state struct.
* The options are:
*
* FPST_FPCR
* for non-FP16 operations controlled by the FPCR
* FPST_FPCR_F16
* for operations controlled by the FPCR where FPCR.FZ16 is to be used
* FPST_STD
* for A32/T32 Neon operations using the "standard FPSCR value"
* FPST_STD_F16
* as FPST_STD, but where FPCR.FZ16 is to be used
*/
static inline TCGv_ptr fpstatus_ptr(TCGContext *s, ARMFPStatusFlavour flavour)
{
TCGv_ptr statusptr = tcg_temp_new_ptr(s);
int offset;
switch (flavour) {
case FPST_FPCR:
offset = offsetof(CPUARMState, vfp.fp_status);
break;
case FPST_FPCR_F16:
offset = offsetof(CPUARMState, vfp.fp_status_f16);
break;
case FPST_STD:
offset = offsetof(CPUARMState, vfp.standard_fp_status);
break;
case FPST_STD_F16:
/* Not yet used or implemented: fall through to assert */
default:
g_assert_not_reached();
}
tcg_gen_addi_ptr(s, statusptr, s->cpu_env, offset);
return statusptr;
}
#endif /* TARGET_ARM_TRANSLATE_H */ #endif /* TARGET_ARM_TRANSLATE_H */