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)
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,
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;
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 */
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);
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:
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);
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);
/* 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 */
/* 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);
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) {
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);
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);
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);
{
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);
{
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);
{
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);
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);
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);
* 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,
return;
}
- fpst = get_fpstatus_ptr(size == MO_16);
+ fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
break;
default:
unallocated_encoding(s);
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);
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);
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) {
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);
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();
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();
} 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);
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;
/* Floating point operations need fpst */
if (opcode >= 0x58) {
- fpst = get_fpstatus_ptr(false);
+ fpst = fpstatus_ptr(FPST_FPCR);
} else {
fpst = NULL;
}
break;
}
- fpst = get_fpstatus_ptr(true);
+ fpst = fpstatus_ptr(FPST_FPCR_F16);
if (pairwise) {
int maxpass = is_q ? 8 : 4;
/* 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++) {
}
if (need_fpstatus || need_rmode) {
- tcg_fpstatus = get_fpstatus_ptr(false);
+ tcg_fpstatus = fpstatus_ptr(FPST_FPCR);
} else {
tcg_fpstatus = NULL;
}
}
if (need_rmode || need_fpst) {
- tcg_fpstatus = get_fpstatus_ptr(true);
+ tcg_fpstatus = fpstatus_ptr(FPST_FPCR_F16);
}
if (need_rmode) {
}
if (is_fp) {
- fpst = get_fpstatus_ptr(is_fp16);
+ fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR);
} else {
fpst = NULL;
}
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
- TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
+ TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm),
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
- TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
+ TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm),
tcg_gen_addi_ptr(t_zn, cpu_env, vec_full_reg_offset(s, a->rn));
tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, a->pg));
- status = get_fpstatus_ptr(a->esz == MO_16);
+ status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
fn(temp, t_zn, t_pg, status, t_desc);
tcg_temp_free_ptr(t_zn);
static void do_zz_fp(DisasContext *s, arg_rr_esz *a, gen_helper_gvec_2_ptr *fn)
{
unsigned vsz = vec_full_reg_size(s);
- TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
+ TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
gen_helper_gvec_3_ptr *fn)
{
unsigned vsz = vec_full_reg_size(s);
- TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
+ TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_3_ptr(pred_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
}
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
- TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
+ TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm),
t_pg = tcg_temp_new_ptr();
tcg_gen_addi_ptr(t_rm, cpu_env, vec_full_reg_offset(s, a->rm));
tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, a->pg));
- t_fpst = get_fpstatus_ptr(a->esz == MO_16);
+ t_fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
t_desc = tcg_const_i32(simd_desc(vsz, vsz, 0));
fns[a->esz - 1](t_val, t_val, t_rm, t_pg, t_fpst, t_desc);
}
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
- TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
+ TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm),
}
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
- TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
+ TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm),
tcg_gen_addi_ptr(t_zn, cpu_env, vec_full_reg_offset(s, zn));
tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
- status = get_fpstatus_ptr(is_fp16);
+ status = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR);
desc = tcg_const_i32(simd_desc(vsz, vsz, 0));
fn(t_zd, t_zn, t_pg, scalar, status, desc);
}
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
- TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
+ TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_4_ptr(pred_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm),
}
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
- TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
+ TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm),
}
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
- TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
+ TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_5_ptr(vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm),
}
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
- TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
+ TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_5_ptr(vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm),
tcg_debug_assert(a->rd == a->ra);
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
- TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
+ TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm),
{
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
- TCGv_ptr status = get_fpstatus_ptr(is_fp16);
+ TCGv_ptr status = 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),
pred_full_reg_offset(s, pg),
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
TCGv_i32 tmode = tcg_const_i32(mode);
- TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
+ TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
gen_helper_set_rmode(tmode, tmode, status);