target/arm: Add FPCR.AH to tbflags
We are going to need to generate different code in some cases when FPCR.AH is 1. For example: * Floating point neg and abs must not flip the sign bit of NaNs * some insns (FRECPE, FRECPS, FRECPX, FRSQRTE, FRSQRTS, and various BFCVT and BFM bfloat16 ops) need to use a different float_status to the usual one Encode FPCR.AH into the A64 tbflags, so we can refer to it at translate time. Because we now have a bit in FPCR that affects codegen, we can't mark the AArch64 FPCR register as being SUPPRESS_TB_END any more; writes to it will now end the TB and trigger a regeneration of hflags. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
a4550b7be9
commit
731528d35e
@ -3198,6 +3198,7 @@ FIELD(TBFLAG_A64, NV2, 34, 1)
|
||||
FIELD(TBFLAG_A64, NV2_MEM_E20, 35, 1)
|
||||
/* Set if FEAT_NV2 RAM accesses are big-endian */
|
||||
FIELD(TBFLAG_A64, NV2_MEM_BE, 36, 1)
|
||||
FIELD(TBFLAG_A64, AH, 37, 1) /* FPCR.AH */
|
||||
|
||||
/*
|
||||
* Helpers for using the above. Note that only the A64 accessors use
|
||||
|
@ -4848,7 +4848,7 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
|
||||
.writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore },
|
||||
{ .name = "FPCR", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4,
|
||||
.access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END,
|
||||
.access = PL0_RW, .type = ARM_CP_FPU,
|
||||
.readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
|
||||
{ .name = "FPSR", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4,
|
||||
|
@ -404,6 +404,10 @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
|
||||
DP_TBFLAG_A64(flags, TCMA, aa64_va_parameter_tcma(tcr, mmu_idx));
|
||||
}
|
||||
|
||||
if (env->vfp.fpcr & FPCR_AH) {
|
||||
DP_TBFLAG_A64(flags, AH, 1);
|
||||
}
|
||||
|
||||
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
|
||||
}
|
||||
|
||||
|
@ -9655,6 +9655,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
|
||||
dc->nv2 = EX_TBFLAG_A64(tb_flags, NV2);
|
||||
dc->nv2_mem_e20 = EX_TBFLAG_A64(tb_flags, NV2_MEM_E20);
|
||||
dc->nv2_mem_be = EX_TBFLAG_A64(tb_flags, NV2_MEM_BE);
|
||||
dc->fpcr_ah = EX_TBFLAG_A64(tb_flags, AH);
|
||||
dc->vec_len = 0;
|
||||
dc->vec_stride = 0;
|
||||
dc->cp_regs = arm_cpu->cp_regs;
|
||||
|
@ -155,6 +155,8 @@ typedef struct DisasContext {
|
||||
bool nv2_mem_e20;
|
||||
/* True if NV2 enabled and NV2 RAM accesses are big-endian */
|
||||
bool nv2_mem_be;
|
||||
/* True if FPCR.AH is 1 (alternate floating point handling) */
|
||||
bool fpcr_ah;
|
||||
/*
|
||||
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
|
||||
* < 0, set by the current instruction.
|
||||
|
Loading…
x
Reference in New Issue
Block a user