dead_tmp(var);
}
-/* 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
- and will be marked as dead. */
-#define store_reg_bx(dc, reg, var) \
- if ((reg) == 15 && ENABLE_ARCH_7) \
- gen_bx((dc), (var)); \
- else \
- store_reg((dc), (reg), (var));
/* Basic operations. */
#define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
#define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1])
#define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
#define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0])
-#define gen_op_rscl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[1], cpu_T[0])
#define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1])
#define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1])
gen_bx(s, tmp);
}
+/* 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
+ and will be marked as dead. */
+static inline void store_reg_bx(CPUState *env, DisasContext *s,
+ int reg, TCGv var)
+{
+ if (reg == 15 && ENABLE_ARCH_7) {
+ gen_bx(s, var);
+ } else {
+ store_reg(s, reg, var);
+ }
+}
+
static inline TCGv gen_ld8s(TCGv addr, int index)
{
TCGv tmp = new_tmp();
/* immediate operand */
val = insn & 0xff;
shift = ((insn >> 8) & 0xf) * 2;
- if (shift)
+ if (shift) {
val = (val >> shift) | (val << (32 - shift));
+ }
tmp2 = new_tmp();
tcg_gen_movi_i32(tmp2, val);
- if (logic_cc && shift)
+ if (logic_cc && shift) {
gen_set_CF_bit31(tmp2);
+ }
} else {
/* register */
rm = (insn) & 0xf;
if (op1 != 0x0f && op1 != 0x0d) {
rn = (insn >> 16) & 0xf;
tmp = load_reg(s, rn);
- } else
- tmp = new_tmp();
+ } else {
+ TCGV_UNUSED(tmp);
+ }
rd = (insn >> 12) & 0xf;
switch(op1) {
case 0x00:
tcg_gen_and_i32(tmp, tmp, tmp2);
- if (logic_cc)
+ if (logic_cc) {
gen_logic_CC(tmp);
- store_reg_bx(s, rd, tmp);
+ }
+ store_reg_bx(env, s, rd, tmp);
break;
case 0x01:
tcg_gen_xor_i32(tmp, tmp, tmp2);
- if (logic_cc)
+ if (logic_cc) {
gen_logic_CC(tmp);
- store_reg_bx(s, rd, tmp);
+ }
+ store_reg_bx(env, s, rd, tmp);
break;
case 0x02:
if (set_cc && rd == 15) {
/* SUBS r15, ... is used for exception return. */
- if (IS_USER(s))
+ if (IS_USER(s)) {
goto illegal_op;
+ }
gen_helper_sub_cc(tmp, tmp, tmp2);
gen_exception_return(s, tmp);
} else {
- if (set_cc)
+ if (set_cc) {
gen_helper_sub_cc(tmp, tmp, tmp2);
- else
+ } else {
tcg_gen_sub_i32(tmp, tmp, tmp2);
- store_reg_bx(s, rd, tmp);
+ }
+ store_reg_bx(env, s, rd, tmp);
}
break;
case 0x03:
- if (set_cc)
+ if (set_cc) {
gen_helper_sub_cc(tmp, tmp2, tmp);
- else
+ } else {
tcg_gen_sub_i32(tmp, tmp2, tmp);
- store_reg_bx(s, rd, tmp);
+ }
+ store_reg_bx(env, s, rd, tmp);
break;
case 0x04:
- if (set_cc)
+ if (set_cc) {
gen_helper_add_cc(tmp, tmp, tmp2);
- else
+ } else {
tcg_gen_add_i32(tmp, tmp, tmp2);
- store_reg_bx(s, rd, tmp);
+ }
+ store_reg_bx(env, s, rd, tmp);
break;
case 0x05:
- if (set_cc)
+ if (set_cc) {
gen_helper_adc_cc(tmp, tmp, tmp2);
- else
+ } else {
gen_add_carry(tmp, tmp, tmp2);
- store_reg_bx(s, rd, tmp);
+ }
+ store_reg_bx(env, s, rd, tmp);
break;
case 0x06:
- if (set_cc)
+ if (set_cc) {
gen_helper_sbc_cc(tmp, tmp, tmp2);
- else
+ } else {
gen_sub_carry(tmp, tmp, tmp2);
- store_reg_bx(s, rd, tmp);
+ }
+ store_reg_bx(env, s, rd, tmp);
break;
case 0x07:
- if (set_cc)
+ if (set_cc) {
gen_helper_sbc_cc(tmp, tmp2, tmp);
- else
+ } else {
gen_sub_carry(tmp, tmp2, tmp);
- store_reg_bx(s, rd, tmp);
+ }
+ store_reg_bx(env, s, rd, tmp);
break;
case 0x08:
if (set_cc) {
dead_tmp(tmp);
break;
case 0x0a:
- if (set_cc)
+ if (set_cc) {
gen_helper_sub_cc(tmp, tmp, tmp2);
+ }
dead_tmp(tmp);
break;
case 0x0b:
- if (set_cc)
+ if (set_cc) {
gen_helper_add_cc(tmp, tmp, tmp2);
+ }
dead_tmp(tmp);
break;
case 0x0c:
tcg_gen_or_i32(tmp, tmp, tmp2);
- if (logic_cc)
+ if (logic_cc) {
gen_logic_CC(tmp);
- store_reg_bx(s, rd, tmp);
+ }
+ store_reg_bx(env, s, rd, tmp);
break;
case 0x0d:
- tcg_gen_mov_i32(tmp, tmp2);
if (logic_cc && rd == 15) {
/* MOVS r15, ... is used for exception return. */
- if (IS_USER(s))
+ if (IS_USER(s)) {
goto illegal_op;
- gen_exception_return(s, tmp);
+ }
+ gen_exception_return(s, tmp2);
} else {
- store_reg_bx(s, rd, tmp);
- if (logic_cc)
+ if (logic_cc) {
gen_logic_CC(tmp2);
+ }
+ store_reg_bx(env, s, rd, tmp2);
}
break;
case 0x0e:
tcg_gen_bic_i32(tmp, tmp, tmp2);
- if (logic_cc)
+ if (logic_cc) {
gen_logic_CC(tmp);
- store_reg_bx(s, rd, tmp);
+ }
+ store_reg_bx(env, s, rd, tmp);
break;
default:
case 0x0f:
- tcg_gen_not_i32(tmp, tmp2);
- if (logic_cc)
- gen_logic_CC(tmp);
- store_reg_bx(s, rd, tmp);
+ tcg_gen_not_i32(tmp2, tmp2);
+ if (logic_cc) {
+ gen_logic_CC(tmp2);
+ }
+ store_reg_bx(env, s, rd, tmp2);
break;
}
- dead_tmp(tmp2);
+ if (op1 != 0x0f && op1 != 0x0d) {
+ dead_tmp(tmp2);
+ }
} else {
/* other instructions */
op1 = (insn >> 24) & 0xf;
gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
if (logic_cc)
gen_logic_CC(tmp);
- store_reg(s, rd, tmp);
+ store_reg_bx(env, s, rd, tmp);
break;
case 1: /* Sign/zero extend. */
tmp = load_reg(s, rm);