target/arm: Convert T16 data-processing (two low regs)

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190904193059.26202-47-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
master
Richard Henderson 2019-09-04 12:30:36 -07:00 committed by Peter Maydell
parent f97b454e9e
commit 080c4eadcb
2 changed files with 43 additions and 145 deletions

View File

@ -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

View File

@ -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. */