aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target/arm/t16.decode36
-rw-r--r--target/arm/translate.c152
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. */