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>
This commit is contained in:
parent
f97b454e9e
commit
080c4eadcb
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in a new issue