target-arm/translate.c: Don't pass CPUARMState around in the decoder

Passing the CPUARMState around in the decoder is a recipe for
bugs where we accidentally generate code that depends on CPU
state which isn't reflected in the TB flags. Stop doing this
and instead use DisasContext as a way to pass around those
bits of CPU state which are known to be safe to use.

This commit simply removes initial "CPUARMState *env" parameters
from various function definitions, and removes the initial "env"
argument from the places where those functions are called.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 1414524244-20316-5-git-send-email-peter.maydell@linaro.org
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
This commit is contained in:
Peter Maydell 2014-10-28 19:24:03 +00:00
parent b53d8923a5
commit 7dcc1f894d

View File

@ -834,8 +834,7 @@ static inline void gen_bx(DisasContext *s, TCGv_i32 var)
/* Variant of store_reg which uses branch&exchange logic when storing /* Variant of store_reg which uses branch&exchange logic when storing
to r15 in ARM architecture v7 and above. The source must be a temporary to r15 in ARM architecture v7 and above. The source must be a temporary
and will be marked as dead. */ and will be marked as dead. */
static inline void store_reg_bx(CPUARMState *env, DisasContext *s, static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
int reg, TCGv_i32 var)
{ {
if (reg == 15 && ENABLE_ARCH_7) { if (reg == 15 && ENABLE_ARCH_7) {
gen_bx(s, var); gen_bx(s, var);
@ -848,8 +847,7 @@ static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
* to r15 in ARM architecture v5T and above. This is used for storing * to r15 in ARM architecture v5T and above. This is used for storing
* the results of a LDR/LDM/POP into r15, and corresponds to the cases * the results of a LDR/LDM/POP into r15, and corresponds to the cases
* in the ARM ARM which use the LoadWritePC() pseudocode function. */ * in the ARM ARM which use the LoadWritePC() pseudocode function. */
static inline void store_reg_from_load(CPUARMState *env, DisasContext *s, static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
int reg, TCGv_i32 var)
{ {
if (reg == 15 && ENABLE_ARCH_5) { if (reg == 15 && ENABLE_ARCH_5) {
gen_bx(s, var); gen_bx(s, var);
@ -1541,7 +1539,7 @@ static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
/* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
(ie. an undefined instruction). */ (ie. an undefined instruction). */
static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn) static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
{ {
int rd, wrd; int rd, wrd;
int rdhi, rdlo, rd0, rd1, i; int rdhi, rdlo, rd0, rd1, i;
@ -2547,7 +2545,7 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
/* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
(ie. an undefined instruction). */ (ie. an undefined instruction). */
static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn) static int disas_dsp_insn(DisasContext *s, uint32_t insn)
{ {
int acc, rd0, rd1, rdhi, rdlo; int acc, rd0, rd1, rdhi, rdlo;
TCGv_i32 tmp, tmp2; TCGv_i32 tmp, tmp2;
@ -2966,7 +2964,7 @@ static const uint8_t fp_decode_rm[] = {
FPROUNDING_NEGINF, FPROUNDING_NEGINF,
}; };
static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn) static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
{ {
uint32_t rd, rn, rm, dp = extract32(insn, 8, 1); uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
@ -3002,7 +3000,7 @@ static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
/* Disassemble a VFP instruction. Returns nonzero if an error occurred /* Disassemble a VFP instruction. Returns nonzero if an error occurred
(ie. an undefined instruction). */ (ie. an undefined instruction). */
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn) static int disas_vfp_insn(DisasContext *s, uint32_t insn)
{ {
uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask; uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
int dp, veclen; int dp, veclen;
@ -3039,7 +3037,7 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
/* Encodings with T=1 (Thumb) or unconditional (ARM): /* Encodings with T=1 (Thumb) or unconditional (ARM):
* only used in v8 and above. * only used in v8 and above.
*/ */
return disas_vfp_v8_insn(env, s, insn); return disas_vfp_v8_insn(s, insn);
} }
dp = ((insn & 0xf00) == 0xb00); dp = ((insn & 0xf00) == 0xb00);
@ -3962,7 +3960,8 @@ static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
} }
/* Return the mask of PSR bits set by a MSR instruction. */ /* Return the mask of PSR bits set by a MSR instruction. */
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) { static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
{
uint32_t mask; uint32_t mask;
mask = 0; mask = 0;
@ -4312,7 +4311,7 @@ static struct {
/* Translate a NEON load/store element instruction. Return nonzero if the /* Translate a NEON load/store element instruction. Return nonzero if the
instruction is invalid. */ instruction is invalid. */
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn) static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
{ {
int rd, rn, rm; int rd, rn, rm;
int op; int op;
@ -5054,7 +5053,7 @@ static const uint8_t neon_2rm_sizes[] = {
We process data in a mixture of 32-bit and 64-bit chunks. We process data in a mixture of 32-bit and 64-bit chunks.
Mostly we use 32-bit chunks so we can use normal scalar instructions. */ Mostly we use 32-bit chunks so we can use normal scalar instructions. */
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn) static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
{ {
int op; int op;
int q; int q;
@ -7049,7 +7048,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
return 0; return 0;
} }
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn) static int disas_coproc_insn(DisasContext *s, uint32_t insn)
{ {
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2; int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
const ARMCPRegInfo *ri; const ARMCPRegInfo *ri;
@ -7062,9 +7061,9 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
return 1; return 1;
} }
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) { if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
return disas_iwmmxt_insn(env, s, insn); return disas_iwmmxt_insn(s, insn);
} else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) { } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
return disas_dsp_insn(env, s, insn); return disas_dsp_insn(s, insn);
} }
return 1; return 1;
} }
@ -7592,8 +7591,9 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
goto illegal_op; goto illegal_op;
} }
if (disas_neon_data_insn(env, s, insn)) if (disas_neon_data_insn(s, insn)) {
goto illegal_op; goto illegal_op;
}
return; return;
} }
if ((insn & 0x0f100000) == 0x04000000) { if ((insn & 0x0f100000) == 0x04000000) {
@ -7602,13 +7602,14 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
goto illegal_op; goto illegal_op;
} }
if (disas_neon_ls_insn(env, s, insn)) if (disas_neon_ls_insn(s, insn)) {
goto illegal_op; goto illegal_op;
}
return; return;
} }
if ((insn & 0x0f000e10) == 0x0e000a00) { if ((insn & 0x0f000e10) == 0x0e000a00) {
/* VFP. */ /* VFP. */
if (disas_vfp_insn(env, s, insn)) { if (disas_vfp_insn(s, insn)) {
goto illegal_op; goto illegal_op;
} }
return; return;
@ -7732,7 +7733,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) { if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
/* iWMMXt register transfer. */ /* iWMMXt register transfer. */
if (extract32(s->c15_cpar, 1, 1)) { if (extract32(s->c15_cpar, 1, 1)) {
if (!disas_iwmmxt_insn(env, s, insn)) { if (!disas_iwmmxt_insn(s, insn)) {
return; return;
} }
} }
@ -7805,8 +7806,10 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
if (shift) if (shift)
val = (val >> shift) | (val << (32 - shift)); val = (val >> shift) | (val << (32 - shift));
i = ((insn & (1 << 22)) != 0); i = ((insn & (1 << 22)) != 0);
if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val)) if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
i, val)) {
goto illegal_op; goto illegal_op;
}
} }
} }
} else if ((insn & 0x0f900000) == 0x01000000 } else if ((insn & 0x0f900000) == 0x01000000
@ -7821,7 +7824,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
/* PSR = reg */ /* PSR = reg */
tmp = load_reg(s, rm); tmp = load_reg(s, rm);
i = ((op1 & 2) != 0); i = ((op1 & 2) != 0);
if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp)) if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
goto illegal_op; goto illegal_op;
} else { } else {
/* reg = PSR */ /* reg = PSR */
@ -8059,14 +8062,14 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
if (logic_cc) { if (logic_cc) {
gen_logic_CC(tmp); gen_logic_CC(tmp);
} }
store_reg_bx(env, s, rd, tmp); store_reg_bx(s, rd, tmp);
break; break;
case 0x01: case 0x01:
tcg_gen_xor_i32(tmp, tmp, tmp2); tcg_gen_xor_i32(tmp, tmp, tmp2);
if (logic_cc) { if (logic_cc) {
gen_logic_CC(tmp); gen_logic_CC(tmp);
} }
store_reg_bx(env, s, rd, tmp); store_reg_bx(s, rd, tmp);
break; break;
case 0x02: case 0x02:
if (set_cc && rd == 15) { if (set_cc && rd == 15) {
@ -8082,7 +8085,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
} else { } else {
tcg_gen_sub_i32(tmp, tmp, tmp2); tcg_gen_sub_i32(tmp, tmp, tmp2);
} }
store_reg_bx(env, s, rd, tmp); store_reg_bx(s, rd, tmp);
} }
break; break;
case 0x03: case 0x03:
@ -8091,7 +8094,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
} else { } else {
tcg_gen_sub_i32(tmp, tmp2, tmp); tcg_gen_sub_i32(tmp, tmp2, tmp);
} }
store_reg_bx(env, s, rd, tmp); store_reg_bx(s, rd, tmp);
break; break;
case 0x04: case 0x04:
if (set_cc) { if (set_cc) {
@ -8099,7 +8102,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
} else { } else {
tcg_gen_add_i32(tmp, tmp, tmp2); tcg_gen_add_i32(tmp, tmp, tmp2);
} }
store_reg_bx(env, s, rd, tmp); store_reg_bx(s, rd, tmp);
break; break;
case 0x05: case 0x05:
if (set_cc) { if (set_cc) {
@ -8107,7 +8110,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
} else { } else {
gen_add_carry(tmp, tmp, tmp2); gen_add_carry(tmp, tmp, tmp2);
} }
store_reg_bx(env, s, rd, tmp); store_reg_bx(s, rd, tmp);
break; break;
case 0x06: case 0x06:
if (set_cc) { if (set_cc) {
@ -8115,7 +8118,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
} else { } else {
gen_sub_carry(tmp, tmp, tmp2); gen_sub_carry(tmp, tmp, tmp2);
} }
store_reg_bx(env, s, rd, tmp); store_reg_bx(s, rd, tmp);
break; break;
case 0x07: case 0x07:
if (set_cc) { if (set_cc) {
@ -8123,7 +8126,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
} else { } else {
gen_sub_carry(tmp, tmp2, tmp); gen_sub_carry(tmp, tmp2, tmp);
} }
store_reg_bx(env, s, rd, tmp); store_reg_bx(s, rd, tmp);
break; break;
case 0x08: case 0x08:
if (set_cc) { if (set_cc) {
@ -8156,7 +8159,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
if (logic_cc) { if (logic_cc) {
gen_logic_CC(tmp); gen_logic_CC(tmp);
} }
store_reg_bx(env, s, rd, tmp); store_reg_bx(s, rd, tmp);
break; break;
case 0x0d: case 0x0d:
if (logic_cc && rd == 15) { if (logic_cc && rd == 15) {
@ -8169,7 +8172,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
if (logic_cc) { if (logic_cc) {
gen_logic_CC(tmp2); gen_logic_CC(tmp2);
} }
store_reg_bx(env, s, rd, tmp2); store_reg_bx(s, rd, tmp2);
} }
break; break;
case 0x0e: case 0x0e:
@ -8177,7 +8180,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
if (logic_cc) { if (logic_cc) {
gen_logic_CC(tmp); gen_logic_CC(tmp);
} }
store_reg_bx(env, s, rd, tmp); store_reg_bx(s, rd, tmp);
break; break;
default: default:
case 0x0f: case 0x0f:
@ -8185,7 +8188,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
if (logic_cc) { if (logic_cc) {
gen_logic_CC(tmp2); gen_logic_CC(tmp2);
} }
store_reg_bx(env, s, rd, tmp2); store_reg_bx(s, rd, tmp2);
break; break;
} }
if (op1 != 0x0f && op1 != 0x0d) { if (op1 != 0x0f && op1 != 0x0d) {
@ -8823,7 +8826,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
} }
if (insn & (1 << 20)) { if (insn & (1 << 20)) {
/* Complete the load. */ /* Complete the load. */
store_reg_from_load(env, s, rd, tmp); store_reg_from_load(s, rd, tmp);
} }
break; break;
case 0x08: case 0x08:
@ -8886,7 +8889,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
loaded_var = tmp; loaded_var = tmp;
loaded_base = 1; loaded_base = 1;
} else { } else {
store_reg_from_load(env, s, i, tmp); store_reg_from_load(s, i, tmp);
} }
} else { } else {
/* store */ /* store */
@ -8969,10 +8972,10 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
case 0xe: case 0xe:
if (((insn >> 8) & 0xe) == 10) { if (((insn >> 8) & 0xe) == 10) {
/* VFP. */ /* VFP. */
if (disas_vfp_insn(env, s, insn)) { if (disas_vfp_insn(s, insn)) {
goto illegal_op; goto illegal_op;
} }
} else if (disas_coproc_insn(env, s, insn)) { } else if (disas_coproc_insn(s, insn)) {
/* Coprocessor. */ /* Coprocessor. */
goto illegal_op; goto illegal_op;
} }
@ -9453,7 +9456,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
gen_arm_shift_reg(tmp, op, tmp2, logic_cc); gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
if (logic_cc) if (logic_cc)
gen_logic_CC(tmp); gen_logic_CC(tmp);
store_reg_bx(env, s, rd, tmp); store_reg_bx(s, rd, tmp);
break; break;
case 1: /* Sign/zero extend. */ case 1: /* Sign/zero extend. */
tmp = load_reg(s, rm); tmp = load_reg(s, rm);
@ -9735,17 +9738,19 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
if (((insn >> 24) & 3) == 3) { if (((insn >> 24) & 3) == 3) {
/* Translate into the equivalent ARM encoding. */ /* Translate into the equivalent ARM encoding. */
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28); insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
if (disas_neon_data_insn(env, s, insn)) if (disas_neon_data_insn(s, insn)) {
goto illegal_op; goto illegal_op;
}
} else if (((insn >> 8) & 0xe) == 10) { } else if (((insn >> 8) & 0xe) == 10) {
if (disas_vfp_insn(env, s, insn)) { if (disas_vfp_insn(s, insn)) {
goto illegal_op; goto illegal_op;
} }
} else { } else {
if (insn & (1 << 28)) if (insn & (1 << 28))
goto illegal_op; goto illegal_op;
if (disas_coproc_insn (env, s, insn)) if (disas_coproc_insn(s, insn)) {
goto illegal_op; goto illegal_op;
}
} }
break; break;
case 8: case 9: case 10: case 11: case 8: case 9: case 10: case 11:
@ -9821,7 +9826,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
} }
tmp = load_reg(s, rn); tmp = load_reg(s, rn);
if (gen_set_psr(s, if (gen_set_psr(s,
msr_mask(env, s, (insn >> 8) & 0xf, op == 1), msr_mask(s, (insn >> 8) & 0xf, op == 1),
op == 1, tmp)) op == 1, tmp))
goto illegal_op; goto illegal_op;
break; break;
@ -10087,8 +10092,9 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
int writeback = 0; int writeback = 0;
int memidx; int memidx;
if ((insn & 0x01100000) == 0x01000000) { if ((insn & 0x01100000) == 0x01000000) {
if (disas_neon_ls_insn(env, s, insn)) if (disas_neon_ls_insn(s, insn)) {
goto illegal_op; goto illegal_op;
}
break; break;
} }
op = ((insn >> 21) & 3) | ((insn >> 22) & 4); op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
@ -10784,7 +10790,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
store_reg(s, 13, addr); store_reg(s, 13, addr);
/* set the new PC value */ /* set the new PC value */
if ((insn & 0x0900) == 0x0900) { if ((insn & 0x0900) == 0x0900) {
store_reg_from_load(env, s, 15, tmp); store_reg_from_load(s, 15, tmp);
} }
break; break;