aboutsummaryrefslogtreecommitdiff
path: root/target/arm
diff options
context:
space:
mode:
Diffstat (limited to 'target/arm')
-rw-r--r--target/arm/cpu.c16
-rw-r--r--target/arm/cpu.h59
-rw-r--r--target/arm/helper-a64.c4
-rw-r--r--target/arm/helper.c19
-rw-r--r--target/arm/hvf/hvf.c2
-rw-r--r--target/arm/m_helper.c6
-rw-r--r--target/arm/op_helper.c13
-rw-r--r--target/arm/translate-a32.h13
-rw-r--r--target/arm/translate-a64.c50
-rw-r--r--target/arm/translate-m-nocp.c12
-rw-r--r--target/arm/translate-neon.c21
-rw-r--r--target/arm/translate-sve.c9
-rw-r--r--target/arm/translate-vfp.c76
-rw-r--r--target/arm/translate.c101
-rw-r--r--target/arm/translate.h17
15 files changed, 203 insertions, 215 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 3609de0888..e3f8215203 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -51,7 +51,7 @@ static void arm_cpu_set_pc(CPUState *cs, vaddr value)
if (is_a64(env)) {
env->pc = value;
- env->thumb = 0;
+ env->thumb = false;
} else {
env->regs[15] = value & ~1;
env->thumb = value & 1;
@@ -189,7 +189,7 @@ static void arm_cpu_reset(DeviceState *dev)
if (arm_feature(env, ARM_FEATURE_AARCH64)) {
/* 64 bit CPUs always start in 64 bit mode */
- env->aarch64 = 1;
+ env->aarch64 = true;
#if defined(CONFIG_USER_ONLY)
env->pstate = PSTATE_MODE_EL0t;
/* Userspace expects access to DC ZVA, CTL_EL0 and the cache ops */
@@ -694,6 +694,16 @@ static void arm_cpu_set_irq(void *opaque, int irq, int level)
[ARM_CPU_VFIQ] = CPU_INTERRUPT_VFIQ
};
+ if (!arm_feature(env, ARM_FEATURE_EL2) &&
+ (irq == ARM_CPU_VIRQ || irq == ARM_CPU_VFIQ)) {
+ /*
+ * The GIC might tell us about VIRQ and VFIQ state, but if we don't
+ * have EL2 support we don't care. (Unless the guest is doing something
+ * silly this will only be calls saying "level is still 0".)
+ */
+ return;
+ }
+
if (level) {
env->irq_line_state |= mask[irq];
} else {
@@ -702,11 +712,9 @@ static void arm_cpu_set_irq(void *opaque, int irq, int level)
switch (irq) {
case ARM_CPU_VIRQ:
- assert(arm_feature(env, ARM_FEATURE_EL2));
arm_cpu_update_virq(cpu);
break;
case ARM_CPU_VFIQ:
- assert(arm_feature(env, ARM_FEATURE_EL2));
arm_cpu_update_vfiq(cpu);
break;
case ARM_CPU_IRQ:
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index cb5359a747..db8ff04449 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -259,7 +259,8 @@ typedef struct CPUArchState {
* all other bits are stored in their correct places in env->pstate
*/
uint32_t pstate;
- uint32_t aarch64; /* 1 if CPU is in aarch64 state; inverse of PSTATE.nRW */
+ bool aarch64; /* True if CPU is in aarch64 state; inverse of PSTATE.nRW */
+ bool thumb; /* True if CPU is in thumb mode; cpsr[5] */
/* Cached TBFLAGS state. See below for which bits are included. */
CPUARMTBFlags hflags;
@@ -286,7 +287,6 @@ typedef struct CPUArchState {
uint32_t ZF; /* Z set if zero. */
uint32_t QF; /* 0 or 1 */
uint32_t GE; /* cpsr[19:16] */
- uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */
uint32_t condexec_bits; /* IT bits. cpsr[15:10,26:25]. */
uint32_t btype; /* BTI branch type. spsr[11:10]. */
uint64_t daif; /* exception masks, in the bits they are in PSTATE */
@@ -1233,6 +1233,20 @@ void pmu_init(ARMCPU *cpu);
#define SCTLR_ATA0 (1ULL << 42) /* v8.5-MemTag */
#define SCTLR_ATA (1ULL << 43) /* v8.5-MemTag */
#define SCTLR_DSSBS_64 (1ULL << 44) /* v8.5, AArch64 only */
+#define SCTLR_TWEDEn (1ULL << 45) /* FEAT_TWED */
+#define SCTLR_TWEDEL MAKE_64_MASK(46, 4) /* FEAT_TWED */
+#define SCTLR_TMT0 (1ULL << 50) /* FEAT_TME */
+#define SCTLR_TMT (1ULL << 51) /* FEAT_TME */
+#define SCTLR_TME0 (1ULL << 52) /* FEAT_TME */
+#define SCTLR_TME (1ULL << 53) /* FEAT_TME */
+#define SCTLR_EnASR (1ULL << 54) /* FEAT_LS64_V */
+#define SCTLR_EnAS0 (1ULL << 55) /* FEAT_LS64_ACCDATA */
+#define SCTLR_EnALS (1ULL << 56) /* FEAT_LS64 */
+#define SCTLR_EPAN (1ULL << 57) /* FEAT_PAN3 */
+#define SCTLR_EnTP2 (1ULL << 60) /* FEAT_SME */
+#define SCTLR_NMI (1ULL << 61) /* FEAT_NMI */
+#define SCTLR_SPINTMASK (1ULL << 62) /* FEAT_NMI */
+#define SCTLR_TIDCP (1ULL << 63) /* FEAT_TIDCP1 */
#define CPTR_TCPAC (1U << 31)
#define CPTR_TTA (1U << 20)
@@ -1545,6 +1559,18 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
#define SCR_FIEN (1U << 21)
#define SCR_ENSCXT (1U << 25)
#define SCR_ATA (1U << 26)
+#define SCR_FGTEN (1U << 27)
+#define SCR_ECVEN (1U << 28)
+#define SCR_TWEDEN (1U << 29)
+#define SCR_TWEDEL MAKE_64BIT_MASK(30, 4)
+#define SCR_TME (1ULL << 34)
+#define SCR_AMVOFFEN (1ULL << 35)
+#define SCR_ENAS0 (1ULL << 36)
+#define SCR_ADEN (1ULL << 37)
+#define SCR_HXEN (1ULL << 38)
+#define SCR_TRNDR (1ULL << 40)
+#define SCR_ENTP2 (1ULL << 41)
+#define SCR_GPF (1ULL << 48)
#define HSTR_TTEE (1 << 16)
#define HSTR_TJDBX (1 << 17)
@@ -1934,6 +1960,7 @@ FIELD(ID_MMFR4, CCIDX, 24, 4)
FIELD(ID_MMFR4, EVT, 28, 4)
FIELD(ID_MMFR5, ETS, 0, 4)
+FIELD(ID_MMFR5, NTLBPA, 4, 4)
FIELD(ID_PFR0, STATE0, 0, 4)
FIELD(ID_PFR0, STATE1, 4, 4)
@@ -1986,6 +2013,16 @@ FIELD(ID_AA64ISAR1, SPECRES, 40, 4)
FIELD(ID_AA64ISAR1, BF16, 44, 4)
FIELD(ID_AA64ISAR1, DGH, 48, 4)
FIELD(ID_AA64ISAR1, I8MM, 52, 4)
+FIELD(ID_AA64ISAR1, XS, 56, 4)
+FIELD(ID_AA64ISAR1, LS64, 60, 4)
+
+FIELD(ID_AA64ISAR2, WFXT, 0, 4)
+FIELD(ID_AA64ISAR2, RPRES, 4, 4)
+FIELD(ID_AA64ISAR2, GPA3, 8, 4)
+FIELD(ID_AA64ISAR2, APA3, 12, 4)
+FIELD(ID_AA64ISAR2, MOPS, 16, 4)
+FIELD(ID_AA64ISAR2, BC, 20, 4)
+FIELD(ID_AA64ISAR2, PAC_FRAC, 24, 4)
FIELD(ID_AA64PFR0, EL0, 0, 4)
FIELD(ID_AA64PFR0, EL1, 4, 4)
@@ -2008,6 +2045,10 @@ FIELD(ID_AA64PFR1, SSBS, 4, 4)
FIELD(ID_AA64PFR1, MTE, 8, 4)
FIELD(ID_AA64PFR1, RAS_FRAC, 12, 4)
FIELD(ID_AA64PFR1, MPAM_FRAC, 16, 4)
+FIELD(ID_AA64PFR1, SME, 24, 4)
+FIELD(ID_AA64PFR1, RNDR_TRAP, 28, 4)
+FIELD(ID_AA64PFR1, CSV2_FRAC, 32, 4)
+FIELD(ID_AA64PFR1, NMI, 36, 4)
FIELD(ID_AA64MMFR0, PARANGE, 0, 4)
FIELD(ID_AA64MMFR0, ASIDBITS, 4, 4)
@@ -2034,6 +2075,11 @@ FIELD(ID_AA64MMFR1, SPECSEI, 24, 4)
FIELD(ID_AA64MMFR1, XNX, 28, 4)
FIELD(ID_AA64MMFR1, TWED, 32, 4)
FIELD(ID_AA64MMFR1, ETS, 36, 4)
+FIELD(ID_AA64MMFR1, HCX, 40, 4)
+FIELD(ID_AA64MMFR1, AFP, 44, 4)
+FIELD(ID_AA64MMFR1, NTLBPA, 48, 4)
+FIELD(ID_AA64MMFR1, TIDCP1, 52, 4)
+FIELD(ID_AA64MMFR1, CMOW, 56, 4)
FIELD(ID_AA64MMFR2, CNP, 0, 4)
FIELD(ID_AA64MMFR2, UAO, 4, 4)
@@ -2060,7 +2106,10 @@ FIELD(ID_AA64DFR0, CTX_CMPS, 28, 4)
FIELD(ID_AA64DFR0, PMSVER, 32, 4)
FIELD(ID_AA64DFR0, DOUBLELOCK, 36, 4)
FIELD(ID_AA64DFR0, TRACEFILT, 40, 4)
+FIELD(ID_AA64DFR0, TRACEBUFFER, 44, 4)
FIELD(ID_AA64DFR0, MTPMU, 48, 4)
+FIELD(ID_AA64DFR0, BRBE, 52, 4)
+FIELD(ID_AA64DFR0, HPMN0, 60, 4)
FIELD(ID_AA64ZFR0, SVEVER, 0, 4)
FIELD(ID_AA64ZFR0, AES, 4, 4)
@@ -2082,6 +2131,7 @@ FIELD(ID_DFR0, PERFMON, 24, 4)
FIELD(ID_DFR0, TRACEFILT, 28, 4)
FIELD(ID_DFR1, MTPMU, 0, 4)
+FIELD(ID_DFR1, HPMN0, 4, 4)
FIELD(DBGDIDR, SE_IMP, 12, 1)
FIELD(DBGDIDR, NSUHD_IMP, 14, 1)
@@ -2757,11 +2807,6 @@ typedef enum CPAccessResult {
/* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
- /* Access fails and results in an exception syndrome for an FP access,
- * trapped directly to EL2 or EL3
- */
- CP_ACCESS_TRAP_FP_EL2 = 7,
- CP_ACCESS_TRAP_FP_EL3 = 8,
} CPAccessResult;
/* Access functions for coprocessor registers. These cannot fail and
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index 7cf953b1e6..77a8502b6b 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -952,7 +952,7 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
qemu_mutex_unlock_iothread();
if (!return_to_aa64) {
- env->aarch64 = 0;
+ env->aarch64 = false;
/* We do a raw CPSR write because aarch64_sync_64_to_32()
* will sort the register banks out for us, and we've already
* caught all the bad-mode cases in el_from_spsr().
@@ -975,7 +975,7 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
} else {
int tbii;
- env->aarch64 = 1;
+ env->aarch64 = true;
spsr &= aarch64_pstate_valid_mask(&env_archcpu(env)->isar);
pstate_write(env, spsr);
if (!arm_singlestep_active(env)) {
diff --git a/target/arm/helper.c b/target/arm/helper.c
index d7715c911a..63397bbac1 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4784,18 +4784,6 @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
}
}
-static CPAccessResult fpexc32_access(CPUARMState *env, const ARMCPRegInfo *ri,
- bool isread)
-{
- if ((env->cp15.cptr_el[2] & CPTR_TFP) && arm_current_el(env) == 2) {
- return CP_ACCESS_TRAP_FP_EL2;
- }
- if (env->cp15.cptr_el[3] & CPTR_TFP) {
- return CP_ACCESS_TRAP_FP_EL3;
- }
- return CP_ACCESS_OK;
-}
-
static void sdcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
@@ -5097,9 +5085,8 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
.access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write },
{ .name = "FPEXC32_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 3, .opc2 = 0,
- .type = ARM_CP_ALIAS,
- .fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]),
- .access = PL2_RW, .accessfn = fpexc32_access },
+ .access = PL2_RW, .type = ARM_CP_ALIAS | ARM_CP_FPU,
+ .fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]) },
{ .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
.access = PL2_RW, .resetvalue = 0,
@@ -10181,7 +10168,7 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
}
pstate_write(env, PSTATE_DAIF | new_mode);
- env->aarch64 = 1;
+ env->aarch64 = true;
aarch64_restore_sp(env, new_el);
helper_rebuild_hflags_a64(env, new_el);
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 567e296b21..b11a8b9a18 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -564,7 +564,7 @@ int hvf_arch_init_vcpu(CPUState *cpu)
hv_return_t ret;
int i;
- env->aarch64 = 1;
+ env->aarch64 = true;
asm volatile("mrs %0, cntfrq_el0" : "=r"(arm_cpu->gt_cntfrq_hz));
/* Allocate enough space for our sysreg sync */
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index b7a0fe0114..a740c3e160 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -564,7 +564,7 @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
}
switch_v7m_security_state(env, dest & 1);
- env->thumb = 1;
+ env->thumb = true;
env->regs[15] = dest & ~1;
arm_rebuild_hflags(env);
}
@@ -590,7 +590,7 @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
* except that the low bit doesn't indicate Thumb/not.
*/
env->regs[14] = nextinst;
- env->thumb = 1;
+ env->thumb = true;
env->regs[15] = dest & ~1;
return;
}
@@ -626,7 +626,7 @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
}
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
switch_v7m_security_state(env, 0);
- env->thumb = 1;
+ env->thumb = true;
env->regs[15] = dest;
arm_rebuild_hflags(env);
}
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index 70b42b55fd..2b87e8808b 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -691,19 +691,6 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
target_el = 3;
syndrome = syn_uncategorized();
break;
- case CP_ACCESS_TRAP_FP_EL2:
- target_el = 2;
- /* Since we are an implementation that takes exceptions on a trapped
- * conditional insn only if the insn has passed its condition code
- * check, we take the IMPDEF choice to always report CV=1 COND=0xe
- * (which is also the required value for AArch64 traps).
- */
- syndrome = syn_fp_access_trap(1, 0xe, false);
- break;
- case CP_ACCESS_TRAP_FP_EL3:
- target_el = 3;
- syndrome = syn_fp_access_trap(1, 0xe, false);
- break;
default:
g_assert_not_reached();
}
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
index 5be4b9b834..09010ad2da 100644
--- a/target/arm/translate-a32.h
+++ b/target/arm/translate-a32.h
@@ -61,17 +61,14 @@ static inline TCGv_i32 load_cpu_offset(int offset)
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
-static inline void store_cpu_offset(TCGv_i32 var, int offset)
-{
- tcg_gen_st_i32(var, cpu_env, offset);
- tcg_temp_free_i32(var);
-}
+void store_cpu_offset(TCGv_i32 var, int offset, int size);
-#define store_cpu_field(var, name) \
- store_cpu_offset(var, offsetof(CPUARMState, name))
+#define store_cpu_field(var, name) \
+ store_cpu_offset(var, offsetof(CPUARMState, name), \
+ sizeof_field(CPUARMState, name))
#define store_cpu_field_constant(val, name) \
- tcg_gen_st_i32(tcg_constant_i32(val), cpu_env, offsetof(CPUARMState, name))
+ store_cpu_field(tcg_constant_i32(val), name)
/* Create a new temporary and set it to the value of a CPU register. */
static inline TCGv_i32 load_reg(DisasContext *s, int reg)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 19c09c3b53..adbcd99941 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -128,29 +128,28 @@ static int get_a64_user_mem_index(DisasContext *s)
return arm_to_core_mmu_idx(useridx);
}
-static void reset_btype(DisasContext *s)
+static void set_btype_raw(int val)
{
- if (s->btype != 0) {
- TCGv_i32 zero = tcg_const_i32(0);
- tcg_gen_st_i32(zero, cpu_env, offsetof(CPUARMState, btype));
- tcg_temp_free_i32(zero);
- s->btype = 0;
- }
+ tcg_gen_st_i32(tcg_constant_i32(val), cpu_env,
+ offsetof(CPUARMState, btype));
}
static void set_btype(DisasContext *s, int val)
{
- TCGv_i32 tcg_val;
-
/* BTYPE is a 2-bit field, and 0 should be done with reset_btype. */
tcg_debug_assert(val >= 1 && val <= 3);
-
- tcg_val = tcg_const_i32(val);
- tcg_gen_st_i32(tcg_val, cpu_env, offsetof(CPUARMState, btype));
- tcg_temp_free_i32(tcg_val);
+ set_btype_raw(val);
s->btype = -1;
}
+static void reset_btype(DisasContext *s)
+{
+ if (s->btype != 0) {
+ set_btype_raw(0);
+ s->btype = 0;
+ }
+}
+
void gen_a64_set_pc_im(uint64_t val)
{
tcg_gen_movi_i64(cpu_pc, val);
@@ -342,6 +341,11 @@ static void a64_free_cc(DisasCompare64 *c64)
tcg_temp_free_i64(c64->value);
}
+static void gen_rebuild_hflags(DisasContext *s)
+{
+ gen_helper_rebuild_hflags_a64(cpu_env, tcg_constant_i32(s->current_el));
+}
+
static void gen_exception_internal(int excp)
{
TCGv_i32 tcg_excp = tcg_const_i32(excp);
@@ -1668,9 +1672,7 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
} else {
clear_pstate_bits(PSTATE_UAO);
}
- t1 = tcg_const_i32(s->current_el);
- gen_helper_rebuild_hflags_a64(cpu_env, t1);
- tcg_temp_free_i32(t1);
+ gen_rebuild_hflags(s);
break;
case 0x04: /* PAN */
@@ -1682,9 +1684,7 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
} else {
clear_pstate_bits(PSTATE_PAN);
}
- t1 = tcg_const_i32(s->current_el);
- gen_helper_rebuild_hflags_a64(cpu_env, t1);
- tcg_temp_free_i32(t1);
+ gen_rebuild_hflags(s);
break;
case 0x05: /* SPSel */
@@ -1742,9 +1742,7 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
} else {
clear_pstate_bits(PSTATE_TCO);
}
- t1 = tcg_const_i32(s->current_el);
- gen_helper_rebuild_hflags_a64(cpu_env, t1);
- tcg_temp_free_i32(t1);
+ gen_rebuild_hflags(s);
/* Many factors, including TCO, go into MTE_ACTIVE. */
s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
} else if (dc_isar_feature(aa64_mte_insn_reg, s)) {
@@ -1991,9 +1989,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
* A write to any coprocessor regiser that ends a TB
* must rebuild the hflags for the next TB.
*/
- TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
- gen_helper_rebuild_hflags_a64(cpu_env, tcg_el);
- tcg_temp_free_i32(tcg_el);
+ gen_rebuild_hflags(s);
/*
* We default to ending the TB on a coprocessor register write,
* but allow this to be suppressed by the register definition
@@ -14664,13 +14660,13 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
dc->isar = &arm_cpu->isar;
dc->condjmp = 0;
- dc->aarch64 = 1;
+ dc->aarch64 = true;
/* If we are coming from secure EL0 in a system with a 32-bit EL3, then
* there is no secure EL1, so we route exceptions to EL3.
*/
dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
!arm_el_is_aa64(env, 3);
- dc->thumb = 0;
+ dc->thumb = false;
dc->sctlr_b = 0;
dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
dc->condexec_mask = 0;
diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c
index d9e144e8eb..27363a7b4e 100644
--- a/target/arm/translate-m-nocp.c
+++ b/target/arm/translate-m-nocp.c
@@ -173,7 +173,7 @@ static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
}
/* Zero the Sregs from btmreg to topreg inclusive. */
- zero = tcg_const_i64(0);
+ zero = tcg_constant_i64(0);
if (btmreg & 1) {
write_neon_element64(zero, btmreg >> 1, 1, MO_32);
btmreg++;
@@ -187,8 +187,7 @@ static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
}
assert(btmreg == topreg + 1);
if (dc_isar_feature(aa32_mve, s)) {
- TCGv_i32 z32 = tcg_const_i32(0);
- store_cpu_field(z32, v7m.vpr);
+ store_cpu_field(tcg_constant_i32(0), v7m.vpr);
}
clear_eci_state(s);
@@ -512,7 +511,7 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
}
case ARM_VFP_FPCXT_NS:
{
- TCGv_i32 control, sfpa, fpscr, fpdscr, zero;
+ TCGv_i32 control, sfpa, fpscr, fpdscr;
TCGLabel *lab_active = gen_new_label();
lookup_tb = true;
@@ -552,10 +551,9 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
storefn(s, opaque, tmp, true);
/* If SFPA is zero then set FPSCR from FPDSCR_NS */
fpdscr = load_cpu_field(v7m.fpdscr[M_REG_NS]);
- zero = tcg_const_i32(0);
- tcg_gen_movcond_i32(TCG_COND_EQ, fpscr, sfpa, zero, fpdscr, fpscr);
+ tcg_gen_movcond_i32(TCG_COND_EQ, fpscr, sfpa, tcg_constant_i32(0),
+ fpdscr, fpscr);
gen_helper_vfp_set_fpscr(cpu_env, fpscr);
- tcg_temp_free_i32(zero);
tcg_temp_free_i32(sfpa);
tcg_temp_free_i32(fpdscr);
tcg_temp_free_i32(fpscr);
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
index 384604c009..2e4d1ec87d 100644
--- a/target/arm/translate-neon.c
+++ b/target/arm/translate-neon.c
@@ -447,7 +447,7 @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
int mmu_idx = get_mem_index(s);
int size = a->size;
TCGv_i64 tmp64;
- TCGv_i32 addr, tmp;
+ TCGv_i32 addr;
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
return false;
@@ -513,7 +513,6 @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
tmp64 = tcg_temp_new_i64();
addr = tcg_temp_new_i32();
- tmp = tcg_const_i32(1 << size);
load_reg_var(s, addr, a->rn);
mop = endian | size | align;
@@ -530,7 +529,7 @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
neon_load_element64(tmp64, tt, n, size);
gen_aa32_st_internal_i64(s, tmp64, addr, mmu_idx, mop);
}
- tcg_gen_add_i32(addr, addr, tmp);
+ tcg_gen_addi_i32(addr, addr, 1 << size);
/* Subsequent memory operations inherit alignment */
mop &= ~MO_AMASK;
@@ -538,7 +537,6 @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
}
}
tcg_temp_free_i32(addr);
- tcg_temp_free_i32(tmp);
tcg_temp_free_i64(tmp64);
gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
@@ -1348,7 +1346,7 @@ static bool do_2shift_env_64(DisasContext *s, arg_2reg_shift *a,
* To avoid excessive duplication of ops we implement shift
* by immediate using the variable shift operations.
*/
- constimm = tcg_const_i64(dup_const(a->size, a->shift));
+ constimm = tcg_constant_i64(dup_const(a->size, a->shift));
for (pass = 0; pass < a->q + 1; pass++) {
TCGv_i64 tmp = tcg_temp_new_i64();
@@ -1358,7 +1356,6 @@ static bool do_2shift_env_64(DisasContext *s, arg_2reg_shift *a,
write_neon_element64(tmp, a->vd, pass, MO_64);
tcg_temp_free_i64(tmp);
}
- tcg_temp_free_i64(constimm);
return true;
}
@@ -1394,7 +1391,7 @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
* To avoid excessive duplication of ops we implement shift
* by immediate using the variable shift operations.
*/
- constimm = tcg_const_i32(dup_const(a->size, a->shift));
+ constimm = tcg_constant_i32(dup_const(a->size, a->shift));
tmp = tcg_temp_new_i32();
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
@@ -1403,7 +1400,6 @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
write_neon_element32(tmp, a->vd, pass, MO_32);
}
tcg_temp_free_i32(tmp);
- tcg_temp_free_i32(constimm);
return true;
}
@@ -1457,7 +1453,7 @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
* This is always a right shift, and the shiftfn is always a
* left-shift helper, which thus needs the negated shift count.
*/
- constimm = tcg_const_i64(-a->shift);
+ constimm = tcg_constant_i64(-a->shift);
rm1 = tcg_temp_new_i64();
rm2 = tcg_temp_new_i64();
rd = tcg_temp_new_i32();
@@ -1477,7 +1473,6 @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
tcg_temp_free_i32(rd);
tcg_temp_free_i64(rm1);
tcg_temp_free_i64(rm2);
- tcg_temp_free_i64(constimm);
return true;
}
@@ -1521,7 +1516,7 @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
/* size == 2 */
imm = -a->shift;
}
- constimm = tcg_const_i32(imm);
+ constimm = tcg_constant_i32(imm);
/* Load all inputs first to avoid potential overwrite */
rm1 = tcg_temp_new_i32();
@@ -1546,7 +1541,6 @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
shiftfn(rm3, rm3, constimm);
shiftfn(rm4, rm4, constimm);
- tcg_temp_free_i32(constimm);
tcg_gen_concat_i32_i64(rtmp, rm3, rm4);
tcg_temp_free_i32(rm4);
@@ -2911,7 +2905,7 @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
return true;
}
- desc = tcg_const_i32((a->vn << 2) | a->len);
+ desc = tcg_constant_i32((a->vn << 2) | a->len);
def = tcg_temp_new_i64();
if (a->op) {
read_neon_element64(def, a->vd, 0, MO_64);
@@ -2926,7 +2920,6 @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
tcg_temp_free_i64(def);
tcg_temp_free_i64(val);
- tcg_temp_free_i32(desc);
return true;
}
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 180e14d9f8..726cf88d7c 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1916,8 +1916,6 @@ static bool trans_PNEXT(DisasContext *s, arg_rr_esz *a)
static void do_sat_addsub_32(TCGv_i64 reg, TCGv_i64 val, bool u, bool d)
{
int64_t ibound;
- TCGv_i64 bound;
- TCGCond cond;
/* Use normal 64-bit arithmetic to detect 32-bit overflow. */
if (u) {
@@ -1928,15 +1926,12 @@ static void do_sat_addsub_32(TCGv_i64 reg, TCGv_i64 val, bool u, bool d)
if (d) {
tcg_gen_sub_i64(reg, reg, val);
ibound = (u ? 0 : INT32_MIN);
- cond = TCG_COND_LT;
+ tcg_gen_smax_i64(reg, reg, tcg_constant_i64(ibound));
} else {
tcg_gen_add_i64(reg, reg, val);
ibound = (u ? UINT32_MAX : INT32_MAX);
- cond = TCG_COND_GT;
+ tcg_gen_smin_i64(reg, reg, tcg_constant_i64(ibound));
}
- bound = tcg_const_i64(ibound);
- tcg_gen_movcond_i64(cond, reg, reg, bound, bound, reg);
- tcg_temp_free_i64(bound);
}
/* Similarly with 64-bit values. */
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
index 6a95a67a69..40a513b822 100644
--- a/target/arm/translate-vfp.c
+++ b/target/arm/translate-vfp.c
@@ -180,8 +180,7 @@ static void gen_update_fp_context(DisasContext *s)
gen_helper_vfp_set_fpscr(cpu_env, fpscr);
tcg_temp_free_i32(fpscr);
if (dc_isar_feature(aa32_mve, s)) {
- TCGv_i32 z32 = tcg_const_i32(0);
- store_cpu_field(z32, v7m.vpr);
+ store_cpu_field(tcg_constant_i32(0), v7m.vpr);
}
/*
* We just updated the FPSCR and VPR. Some of this state is cached
@@ -317,7 +316,7 @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
TCGv_i64 frn, frm, dest;
TCGv_i64 tmp, zero, zf, nf, vf;
- zero = tcg_const_i64(0);
+ zero = tcg_constant_i64(0);
frn = tcg_temp_new_i64();
frm = tcg_temp_new_i64();
@@ -335,27 +334,22 @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
vfp_load_reg64(frm, rm);
switch (a->cc) {
case 0: /* eq: Z */
- tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
- frn, frm);
+ tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero, frn, frm);
break;
case 1: /* vs: V */
- tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
- frn, frm);
+ tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero, frn, frm);
break;
case 2: /* ge: N == V -> N ^ V == 0 */
tmp = tcg_temp_new_i64();
tcg_gen_xor_i64(tmp, vf, nf);
- tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
- frn, frm);
+ tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero, frn, frm);
tcg_temp_free_i64(tmp);
break;
case 3: /* gt: !Z && N == V */
- tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
- frn, frm);
+ tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero, frn, frm);
tmp = tcg_temp_new_i64();
tcg_gen_xor_i64(tmp, vf, nf);
- tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
- dest, frm);
+ tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero, dest, frm);
tcg_temp_free_i64(tmp);
break;
}
@@ -367,13 +361,11 @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
tcg_temp_free_i64(zf);
tcg_temp_free_i64(nf);
tcg_temp_free_i64(vf);
-
- tcg_temp_free_i64(zero);
} else {
TCGv_i32 frn, frm, dest;
TCGv_i32 tmp, zero;
- zero = tcg_const_i32(0);
+ zero = tcg_constant_i32(0);
frn = tcg_temp_new_i32();
frm = tcg_temp_new_i32();
@@ -382,27 +374,22 @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
vfp_load_reg32(frm, rm);
switch (a->cc) {
case 0: /* eq: Z */
- tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
- frn, frm);
+ tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero, frn, frm);
break;
case 1: /* vs: V */
- tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
- frn, frm);
+ tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero, frn, frm);
break;
case 2: /* ge: N == V -> N ^ V == 0 */
tmp = tcg_temp_new_i32();
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
- tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
- frn, frm);
+ tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero, frn, frm);
tcg_temp_free_i32(tmp);
break;
case 3: /* gt: !Z && N == V */
- tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
- frn, frm);
+ tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero, frn, frm);
tmp = tcg_temp_new_i32();
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
- tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
- dest, frm);
+ tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero, dest, frm);
tcg_temp_free_i32(tmp);
break;
}
@@ -414,8 +401,6 @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
tcg_temp_free_i32(frn);
tcg_temp_free_i32(frm);
tcg_temp_free_i32(dest);
-
- tcg_temp_free_i32(zero);
}
return true;
@@ -547,7 +532,7 @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
fpst = fpstatus_ptr(FPST_FPCR);
}
- tcg_shift = tcg_const_i32(0);
+ tcg_shift = tcg_constant_i32(0);
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
@@ -595,8 +580,6 @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
tcg_temp_free_i32(tcg_rmode);
- tcg_temp_free_i32(tcg_shift);
-
tcg_temp_free_ptr(fpst);
return true;
@@ -850,15 +833,11 @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
case ARM_VFP_MVFR2:
case ARM_VFP_FPSID:
if (s->current_el == 1) {
- TCGv_i32 tcg_reg, tcg_rt;
-
gen_set_condexec(s);
gen_set_pc_im(s, s->pc_curr);
- tcg_reg = tcg_const_i32(a->reg);
- tcg_rt = tcg_const_i32(a->rt);
- gen_helper_check_hcr_el2_trap(cpu_env, tcg_rt, tcg_reg);
- tcg_temp_free_i32(tcg_reg);
- tcg_temp_free_i32(tcg_rt);
+ gen_helper_check_hcr_el2_trap(cpu_env,
+ tcg_constant_i32(a->rt),
+ tcg_constant_i32(a->reg));
}
/* fall through */
case ARM_VFP_FPEXC:
@@ -2388,8 +2367,6 @@ MAKE_VFM_TRANS_FNS(dp)
static bool trans_VMOV_imm_hp(DisasContext *s, arg_VMOV_imm_sp *a)
{
- TCGv_i32 fd;
-
if (!dc_isar_feature(aa32_fp16_arith, s)) {
return false;
}
@@ -2402,9 +2379,7 @@ static bool trans_VMOV_imm_hp(DisasContext *s, arg_VMOV_imm_sp *a)
return true;
}
- fd = tcg_const_i32(vfp_expand_imm(MO_16, a->imm));
- vfp_store_reg32(fd, a->vd);
- tcg_temp_free_i32(fd);
+ vfp_store_reg32(tcg_constant_i32(vfp_expand_imm(MO_16, a->imm)), a->vd);
return true;
}
@@ -2440,7 +2415,7 @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
}
}
- fd = tcg_const_i32(vfp_expand_imm(MO_32, a->imm));
+ fd = tcg_constant_i32(vfp_expand_imm(MO_32, a->imm));
for (;;) {
vfp_store_reg32(fd, vd);
@@ -2454,7 +2429,6 @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
vd = vfp_advance_sreg(vd, delta_d);
}
- tcg_temp_free_i32(fd);
return true;
}
@@ -2495,7 +2469,7 @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
}
}
- fd = tcg_const_i64(vfp_expand_imm(MO_64, a->imm));
+ fd = tcg_constant_i64(vfp_expand_imm(MO_64, a->imm));
for (;;) {
vfp_store_reg64(fd, vd);
@@ -2509,7 +2483,6 @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
vd = vfp_advance_dreg(vd, delta_d);
}
- tcg_temp_free_i64(fd);
return true;
}
@@ -3294,7 +3267,7 @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
vfp_load_reg32(vd, a->vd);
fpst = fpstatus_ptr(FPST_FPCR_F16);
- shift = tcg_const_i32(frac_bits);
+ shift = tcg_constant_i32(frac_bits);
/* Switch on op:U:sx bits */
switch (a->opc) {
@@ -3328,7 +3301,6 @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
vfp_store_reg32(vd, a->vd);
tcg_temp_free_i32(vd);
- tcg_temp_free_i32(shift);
tcg_temp_free_ptr(fpst);
return true;
}
@@ -3353,7 +3325,7 @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
vfp_load_reg32(vd, a->vd);
fpst = fpstatus_ptr(FPST_FPCR);
- shift = tcg_const_i32(frac_bits);
+ shift = tcg_constant_i32(frac_bits);
/* Switch on op:U:sx bits */
switch (a->opc) {
@@ -3387,7 +3359,6 @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
vfp_store_reg32(vd, a->vd);
tcg_temp_free_i32(vd);
- tcg_temp_free_i32(shift);
tcg_temp_free_ptr(fpst);
return true;
}
@@ -3418,7 +3389,7 @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
vfp_load_reg64(vd, a->vd);
fpst = fpstatus_ptr(FPST_FPCR);
- shift = tcg_const_i32(frac_bits);
+ shift = tcg_constant_i32(frac_bits);
/* Switch on op:U:sx bits */
switch (a->opc) {
@@ -3452,7 +3423,6 @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
vfp_store_reg64(vd, a->vd);
tcg_temp_free_i64(vd);
- tcg_temp_free_i32(shift);
tcg_temp_free_ptr(fpst);
return true;
}
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 38e7a38f28..d09692c125 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -180,6 +180,25 @@ typedef enum ISSInfo {
ISSIs16Bit = (1 << 8),
} ISSInfo;
+/*
+ * Store var into env + offset to a member with size bytes.
+ * Free var after use.
+ */
+void store_cpu_offset(TCGv_i32 var, int offset, int size)
+{
+ switch (size) {
+ case 1:
+ tcg_gen_st8_i32(var, cpu_env, offset);
+ break;
+ case 4:
+ tcg_gen_st_i32(var, cpu_env, offset);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ tcg_temp_free_i32(var);
+}
+
/* Save the syndrome information for a Data Abort */
static void disas_set_da_iss(DisasContext *s, MemOp memop, ISSInfo issinfo)
{
@@ -332,6 +351,26 @@ void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
tcg_temp_free_i32(tmp_mask);
}
+static void gen_rebuild_hflags(DisasContext *s, bool new_el)
+{
+ bool m_profile = arm_dc_feature(s, ARM_FEATURE_M);
+
+ if (new_el) {
+ if (m_profile) {
+ gen_helper_rebuild_hflags_m32_newel(cpu_env);
+ } else {
+ gen_helper_rebuild_hflags_a32_newel(cpu_env);
+ }
+ } else {
+ TCGv_i32 tcg_el = tcg_constant_i32(s->current_el);
+ if (m_profile) {
+ gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
+ } else {
+ gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
+ }
+ }
+}
+
static void gen_exception_internal(int excp)
{
TCGv_i32 tcg_excp = tcg_const_i32(excp);
@@ -513,16 +552,14 @@ static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
#define GEN_SHIFT(name) \
static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
{ \
- TCGv_i32 tmp1, tmp2, tmp3; \
- tmp1 = tcg_temp_new_i32(); \
- tcg_gen_andi_i32(tmp1, t1, 0xff); \
- tmp2 = tcg_const_i32(0); \
- tmp3 = tcg_const_i32(0x1f); \
- tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
- tcg_temp_free_i32(tmp3); \
- tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
- tcg_gen_##name##_i32(dest, tmp2, tmp1); \
- tcg_temp_free_i32(tmp2); \
+ TCGv_i32 tmpd = tcg_temp_new_i32(); \
+ TCGv_i32 tmp1 = tcg_temp_new_i32(); \
+ TCGv_i32 zero = tcg_constant_i32(0); \
+ tcg_gen_andi_i32(tmp1, t1, 0x1f); \
+ tcg_gen_##name##_i32(tmpd, t0, tmp1); \
+ tcg_gen_andi_i32(tmp1, t1, 0xe0); \
+ tcg_gen_movcond_i32(TCG_COND_NE, dest, tmp1, zero, zero, tmpd); \
+ tcg_temp_free_i32(tmpd); \
tcg_temp_free_i32(tmp1); \
}
GEN_SHIFT(shl)
@@ -531,12 +568,10 @@ GEN_SHIFT(shr)
static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
- TCGv_i32 tmp1, tmp2;
- tmp1 = tcg_temp_new_i32();
+ TCGv_i32 tmp1 = tcg_temp_new_i32();
+
tcg_gen_andi_i32(tmp1, t1, 0xff);
- tmp2 = tcg_const_i32(0x1f);
- tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
- tcg_temp_free_i32(tmp2);
+ tcg_gen_umin_i32(tmp1, tmp1, tcg_constant_i32(31));
tcg_gen_sar_i32(dest, t0, tmp1);
tcg_temp_free_i32(tmp1);
}
@@ -4852,7 +4887,7 @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
tcg_temp_free_i32(tmp);
} else {
TCGv_i32 tmp = load_reg(s, rt);
- store_cpu_offset(tmp, ri->fieldoffset);
+ store_cpu_offset(tmp, ri->fieldoffset, 4);
}
}
}
@@ -4866,17 +4901,7 @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
* A write to any coprocessor register that ends a TB
* must rebuild the hflags for the next TB.
*/
- TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
- if (arm_dc_feature(s, ARM_FEATURE_M)) {
- gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
- } else {
- if (ri->type & ARM_CP_NEWEL) {
- gen_helper_rebuild_hflags_a32_newel(cpu_env);
- } else {
- gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
- }
- }
- tcg_temp_free_i32(tcg_el);
+ gen_rebuild_hflags(s, ri->type & ARM_CP_NEWEL);
/*
* We default to ending the TB on a coprocessor register write,
* but allow this to be suppressed by the register definition
@@ -6426,7 +6451,7 @@ static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
tcg_temp_free_i32(addr);
tcg_temp_free_i32(reg);
/* If we wrote to CONTROL, the EL might have changed */
- gen_helper_rebuild_hflags_m32_newel(cpu_env);
+ gen_rebuild_hflags(s, true);
gen_lookup_tb(s);
return true;
}
@@ -8878,7 +8903,7 @@ static bool trans_CPS(DisasContext *s, arg_CPS *a)
static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m *a)
{
- TCGv_i32 tmp, addr, el;
+ TCGv_i32 tmp, addr;
if (!arm_dc_feature(s, ARM_FEATURE_M)) {
return false;
@@ -8901,9 +8926,7 @@ static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m *a)
gen_helper_v7m_msr(cpu_env, addr, tmp);
tcg_temp_free_i32(addr);
}
- el = tcg_const_i32(s->current_el);
- gen_helper_rebuild_hflags_m32(cpu_env, el);
- tcg_temp_free_i32(el);
+ gen_rebuild_hflags(s, false);
tcg_temp_free_i32(tmp);
gen_lookup_tb(s);
return true;
@@ -9334,7 +9357,7 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
dc->isar = &cpu->isar;
dc->condjmp = 0;
- dc->aarch64 = 0;
+ dc->aarch64 = false;
/* If we are coming from secure EL0 in a system with a 32-bit EL3, then
* there is no secure EL1, so we route exceptions to EL3.
*/
@@ -9847,18 +9870,14 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
/* nothing more to generate */
break;
case DISAS_WFI:
- {
- TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
- !(dc->insn & (1U << 31))) ? 2 : 4);
-
- gen_helper_wfi(cpu_env, tmp);
- tcg_temp_free_i32(tmp);
- /* The helper doesn't necessarily throw an exception, but we
+ gen_helper_wfi(cpu_env,
+ tcg_constant_i32(dc->base.pc_next - dc->pc_curr));
+ /*
+ * The helper doesn't necessarily throw an exception, but we
* must go back to the main loop to check for interrupts anyway.
*/
tcg_gen_exit_tb(NULL, 0);
break;
- }
case DISAS_WFE:
gen_helper_wfe(cpu_env);
break;
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 3a0db801d3..6f0ebdc88e 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -30,7 +30,6 @@ typedef struct DisasContext {
bool eci_handled;
/* TCG op to rewind to if this turns out to be an invalid ECI state */
TCGOp *insn_eci_rewind;
- int thumb;
int sctlr_b;
MemOp be_data;
#if !defined(CONFIG_USER_ONLY)
@@ -59,12 +58,13 @@ typedef struct DisasContext {
* so that top level loop can generate correct syndrome information.
*/
uint32_t svc_imm;
- int aarch64;
int current_el;
/* Debug target exception level for single-step exceptions */
int debug_target_el;
GHashTable *cp_regs;
uint64_t features; /* CPU features bits */
+ bool aarch64;
+ bool thumb;
/* Because unallocated encodings generate different exception syndrome
* information from traps due to FP being disabled, we can't do a single
* "is fp access disabled" check at a high level in the decode tree.
@@ -332,16 +332,9 @@ static inline void gen_ss_advance(DisasContext *s)
static inline void gen_exception(int excp, uint32_t syndrome,
uint32_t target_el)
{
- TCGv_i32 tcg_excp = tcg_const_i32(excp);
- TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
- TCGv_i32 tcg_el = tcg_const_i32(target_el);
-
- gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
- tcg_syn, tcg_el);
-
- tcg_temp_free_i32(tcg_el);
- tcg_temp_free_i32(tcg_syn);
- tcg_temp_free_i32(tcg_excp);
+ gen_helper_exception_with_syndrome(cpu_env, tcg_constant_i32(excp),
+ tcg_constant_i32(syndrome),
+ tcg_constant_i32(target_el));
}
/* Generate an architectural singlestep exception */