diff options
-rw-r--r-- | target/arm/t16.decode | 36 | ||||
-rw-r--r-- | target/arm/translate.c | 152 |
2 files changed, 43 insertions, 145 deletions
diff --git a/target/arm/t16.decode b/target/arm/t16.decode index e954f61fe4..44e7250c55 100644 --- a/target/arm/t16.decode +++ b/target/arm/t16.decode @@ -18,3 +18,39 @@ # # This file is processed by scripts/decodetree.py # + +&s_rrr_shi !extern s rd rn rm shim shty +&s_rrr_shr !extern s rn rd rm rs shty +&s_rri_rot !extern s rn rd imm rot +&s_rrrr !extern s rd rn rm ra + +# Set S if the instruction is outside of an IT block. +%s !function=t16_setflags + +# Data-processing (two low registers) + +%reg_0 0:3 + +@lll_noshr ...... .... rm:3 rd:3 \ + &s_rrr_shi %s rn=%reg_0 shim=0 shty=0 +@xll_noshr ...... .... rm:3 rn:3 \ + &s_rrr_shi s=1 rd=0 shim=0 shty=0 +@lxl_shr ...... .... rs:3 rd:3 \ + &s_rrr_shr %s rm=%reg_0 rn=0 + +AND_rrri 010000 0000 ... ... @lll_noshr +EOR_rrri 010000 0001 ... ... @lll_noshr +MOV_rxrr 010000 0010 ... ... @lxl_shr shty=0 # LSL +MOV_rxrr 010000 0011 ... ... @lxl_shr shty=1 # LSR +MOV_rxrr 010000 0100 ... ... @lxl_shr shty=2 # ASR +ADC_rrri 010000 0101 ... ... @lll_noshr +SBC_rrri 010000 0110 ... ... @lll_noshr +MOV_rxrr 010000 0111 ... ... @lxl_shr shty=3 # ROR +TST_xrri 010000 1000 ... ... @xll_noshr +RSB_rri 010000 1001 rn:3 rd:3 &s_rri_rot %s imm=0 rot=0 +CMP_xrri 010000 1010 ... ... @xll_noshr +CMN_xrri 010000 1011 ... ... @xll_noshr +ORR_rrri 010000 1100 ... ... @lll_noshr +MUL 010000 1101 rn:3 rd:3 &s_rrrr %s rm=%reg_0 ra=0 +BIC_rrri 010000 1110 ... ... @lll_noshr +MVN_rxri 010000 1111 ... ... @lll_noshr diff --git a/target/arm/translate.c b/target/arm/translate.c index 7e530f1fdc..b77922f808 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -445,13 +445,6 @@ static inline void gen_logic_CC(TCGv_i32 var) tcg_gen_mov_i32(cpu_ZF, var); } -/* T0 += T1 + CF. */ -static void gen_adc(TCGv_i32 t0, TCGv_i32 t1) -{ - tcg_gen_add_i32(t0, t0, t1); - tcg_gen_add_i32(t0, t0, cpu_CF); -} - /* dest = T0 + T1 + CF. */ static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) { @@ -7553,6 +7546,11 @@ static int t32_branch24(DisasContext *s, int x) return x << 1; } +static int t16_setflags(DisasContext *s) +{ + return s->condexec_mask == 0; +} + /* * Include the generated decoders. */ @@ -10861,145 +10859,9 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) /* * 0b0100_00xx_xxxx_xxxx - * - Data-processing (two low registers) + * - Data-processing (two low registers), in decodetree */ - rd = insn & 7; - rm = (insn >> 3) & 7; - op = (insn >> 6) & 0xf; - if (op == 2 || op == 3 || op == 4 || op == 7) { - /* the shift/rotate ops want the operands backwards */ - val = rm; - rm = rd; - rd = val; - val = 1; - } else { - val = 0; - } - - if (op == 9) { /* neg */ - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, 0); - } else if (op != 0xf) { /* mvn doesn't read its first operand */ - tmp = load_reg(s, rd); - } else { - tmp = NULL; - } - - tmp2 = load_reg(s, rm); - switch (op) { - case 0x0: /* and */ - tcg_gen_and_i32(tmp, tmp, tmp2); - if (!s->condexec_mask) - gen_logic_CC(tmp); - break; - case 0x1: /* eor */ - tcg_gen_xor_i32(tmp, tmp, tmp2); - if (!s->condexec_mask) - gen_logic_CC(tmp); - break; - case 0x2: /* lsl */ - if (s->condexec_mask) { - gen_shl(tmp2, tmp2, tmp); - } else { - gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp); - gen_logic_CC(tmp2); - } - break; - case 0x3: /* lsr */ - if (s->condexec_mask) { - gen_shr(tmp2, tmp2, tmp); - } else { - gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp); - gen_logic_CC(tmp2); - } - break; - case 0x4: /* asr */ - if (s->condexec_mask) { - gen_sar(tmp2, tmp2, tmp); - } else { - gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp); - gen_logic_CC(tmp2); - } - break; - case 0x5: /* adc */ - if (s->condexec_mask) { - gen_adc(tmp, tmp2); - } else { - gen_adc_CC(tmp, tmp, tmp2); - } - break; - case 0x6: /* sbc */ - if (s->condexec_mask) { - gen_sub_carry(tmp, tmp, tmp2); - } else { - gen_sbc_CC(tmp, tmp, tmp2); - } - break; - case 0x7: /* ror */ - if (s->condexec_mask) { - tcg_gen_andi_i32(tmp, tmp, 0x1f); - tcg_gen_rotr_i32(tmp2, tmp2, tmp); - } else { - gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp); - gen_logic_CC(tmp2); - } - break; - case 0x8: /* tst */ - tcg_gen_and_i32(tmp, tmp, tmp2); - gen_logic_CC(tmp); - rd = 16; - break; - case 0x9: /* neg */ - if (s->condexec_mask) - tcg_gen_neg_i32(tmp, tmp2); - else - gen_sub_CC(tmp, tmp, tmp2); - break; - case 0xa: /* cmp */ - gen_sub_CC(tmp, tmp, tmp2); - rd = 16; - break; - case 0xb: /* cmn */ - gen_add_CC(tmp, tmp, tmp2); - rd = 16; - break; - case 0xc: /* orr */ - tcg_gen_or_i32(tmp, tmp, tmp2); - if (!s->condexec_mask) - gen_logic_CC(tmp); - break; - case 0xd: /* mul */ - tcg_gen_mul_i32(tmp, tmp, tmp2); - if (!s->condexec_mask) - gen_logic_CC(tmp); - break; - case 0xe: /* bic */ - tcg_gen_andc_i32(tmp, tmp, tmp2); - if (!s->condexec_mask) - gen_logic_CC(tmp); - break; - case 0xf: /* mvn */ - tcg_gen_not_i32(tmp2, tmp2); - if (!s->condexec_mask) - gen_logic_CC(tmp2); - val = 1; - rm = rd; - break; - } - if (rd != 16) { - if (val) { - store_reg(s, rm, tmp2); - if (op != 0xf) - tcg_temp_free_i32(tmp); - } else { - store_reg(s, rd, tmp); - tcg_temp_free_i32(tmp2); - } - } else { - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - } - break; + goto illegal_op; case 5: /* load/store register offset. */ |