X-Git-Url: http://git.maemo.org/git/?p=qemu;a=blobdiff_plain;f=target-arm%2Ftranslate.c;fp=target-arm%2Ftranslate.c;h=0a1ac27d1f4ec921e87b35b91972c15bde2fede1;hp=f73f5d4d031fdc179cb4290842974a673995d916;hb=759b334a9739814df2883aa4c41b1c0f5670e90a;hpb=7e2198fc87e878b8ce5df965477e21713ebf7834 diff --git a/target-arm/translate.c b/target-arm/translate.c index f73f5d4..0a1ac27 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -191,14 +191,6 @@ static void store_reg(DisasContext *s, int reg, TCGv var) 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]) @@ -215,7 +207,6 @@ static void store_reg(DisasContext *s, int reg, TCGv var) #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]) @@ -829,6 +820,19 @@ static inline void gen_bx_T0(DisasContext *s) 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(); @@ -6116,12 +6120,14 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) /* 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; @@ -6139,71 +6145,81 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) 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) { @@ -6220,49 +6236,57 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) 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; @@ -7359,7 +7383,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) 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);