target/arm: Convert Data Processing (reg-shifted-reg)

Convert the register shifted by register form of the data
processing insns. For A32, we cannot yet remove any code
because the legacy decoder intertwines the immediate form.

Backports commit 5be2c12337f4cbdbda4efe6ab485350f730faaad from qemu
This commit is contained in:
Richard Henderson 2019-11-19 13:08:41 -05:00 committed by Lioncash
parent e151696a65
commit 1b21ced6a1
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
3 changed files with 88 additions and 20 deletions

View file

@ -23,6 +23,7 @@
#
&s_rrr_shi s rd rn rm shim shty
&s_rrr_shr s rn rd rm rs shty
# Data-processing (register)
@ -49,3 +50,29 @@ ORR_rrri .... 000 1100 . .... .... ..... .. 0 .... @s_rrr_shi
MOV_rxri .... 000 1101 . 0000 .... ..... .. 0 .... @s_rxr_shi
BIC_rrri .... 000 1110 . .... .... ..... .. 0 .... @s_rrr_shi
MVN_rxri .... 000 1111 . 0000 .... ..... .. 0 .... @s_rxr_shi
# Data-processing (register-shifted register)
@s_rrr_shr ---- ... .... s:1 rn:4 rd:4 rs:4 . shty:2 . rm:4 \
&s_rrr_shr
@s_rxr_shr ---- ... .... s:1 .... rd:4 rs:4 . shty:2 . rm:4 \
&s_rrr_shr rn=0
@S_xrr_shr ---- ... .... . rn:4 .... rs:4 . shty:2 . rm:4 \
&s_rrr_shr rd=0 s=1
AND_rrrr .... 000 0000 . .... .... .... 0 .. 1 .... @s_rrr_shr
EOR_rrrr .... 000 0001 . .... .... .... 0 .. 1 .... @s_rrr_shr
SUB_rrrr .... 000 0010 . .... .... .... 0 .. 1 .... @s_rrr_shr
RSB_rrrr .... 000 0011 . .... .... .... 0 .. 1 .... @s_rrr_shr
ADD_rrrr .... 000 0100 . .... .... .... 0 .. 1 .... @s_rrr_shr
ADC_rrrr .... 000 0101 . .... .... .... 0 .. 1 .... @s_rrr_shr
SBC_rrrr .... 000 0110 . .... .... .... 0 .. 1 .... @s_rrr_shr
RSC_rrrr .... 000 0111 . .... .... .... 0 .. 1 .... @s_rrr_shr
TST_xrrr .... 000 1000 1 .... 0000 .... 0 .. 1 .... @S_xrr_shr
TEQ_xrrr .... 000 1001 1 .... 0000 .... 0 .. 1 .... @S_xrr_shr
CMP_xrrr .... 000 1010 1 .... 0000 .... 0 .. 1 .... @S_xrr_shr
CMN_xrrr .... 000 1011 1 .... 0000 .... 0 .. 1 .... @S_xrr_shr
ORR_rrrr .... 000 1100 . .... .... .... 0 .. 1 .... @s_rrr_shr
MOV_rxrr .... 000 1101 . 0000 .... .... 0 .. 1 .... @s_rxr_shr
BIC_rrrr .... 000 1110 . .... .... .... 0 .. 1 .... @s_rrr_shr
MVN_rxrr .... 000 1111 . 0000 .... .... 0 .. 1 .... @s_rxr_shr

View file

@ -20,6 +20,7 @@
#
&s_rrr_shi !extern s rd rn rm shim shty
&s_rrr_shr !extern s rn rd rm rs shty
# Data-processing (register)
@ -61,3 +62,8 @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
SUB_rrri 1110101 1101 . .... 0 ... .... .... .... @s_rrr_shi
}
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
# Data-processing (register-shifted register)
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \
&s_rrr_shr rn=0

View file

@ -8010,17 +8010,67 @@ static bool op_s_rxr_shi(DisasContext *s, arg_s_rrr_shi *a,
return store_reg_kind(s, a->rd, tmp, kind);
}
/*
* Data-processing (register-shifted register)
*
* Operate, with set flags, one register source,
* one register shifted register source, and a destination.
*/
static bool op_s_rrr_shr(DisasContext *s, arg_s_rrr_shr *a,
void (*gen)(DisasContext *, TCGv_i32, TCGv_i32, TCGv_i32),
int logic_cc, StoreRegKind kind)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
TCGv_i32 tmp1, tmp2;
tmp1 = load_reg(s, a->rs);
tmp2 = load_reg(s, a->rm);
gen_arm_shift_reg(s, tmp2, a->shty, tmp1, logic_cc);
tmp1 = load_reg(s, a->rn);
gen(s, tmp1, tmp1, tmp2);
tcg_temp_free_i32(tcg_ctx, tmp2);
if (logic_cc) {
gen_logic_CC(s, tmp1);
}
return store_reg_kind(s, a->rd, tmp1, kind);
}
static bool op_s_rxr_shr(DisasContext *s, arg_s_rrr_shr *a,
void (*gen)(DisasContext *, TCGv_i32, TCGv_i32),
int logic_cc, StoreRegKind kind)
{
TCGv_i32 tmp1, tmp2;
tmp1 = load_reg(s, a->rs);
tmp2 = load_reg(s, a->rm);
gen_arm_shift_reg(s, tmp2, a->shty, tmp1, logic_cc);
gen(s, tmp2, tmp2);
if (logic_cc) {
gen_logic_CC(s, tmp2);
}
return store_reg_kind(s, a->rd, tmp2, kind);
}
#define DO_ANY3(NAME, OP, L, K) \
static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
{ StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); }
{ StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \
static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \
{ StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); }
#define DO_ANY2(NAME, OP, L, K) \
static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
{ StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); }
{ StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \
static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \
{ StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); }
#define DO_CMP2(NAME, OP, L) \
static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
{ return op_s_rrr_shi(s, a, OP, L, STREG_NONE); }
{ return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \
static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \
{ return op_s_rrr_shr(s, a, OP, L, STREG_NONE); }
DO_ANY3(AND, gen_and_i32, a->s, STREG_NORMAL)
DO_ANY3(EOR, gen_xor_i32, a->s, STREG_NORMAL)
@ -9813,7 +9863,6 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
TCGv_i32 addr;
TCGv_i64 tmp64;
int op;
int logic_cc;
/*
* ARMv6-M supports a limited subset of Thumb2 instructions.
@ -10251,22 +10300,8 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
if (op < 4 && (insn & 0xf000) != 0xf000)
goto illegal_op;
switch (op) {
case 0: /* Register controlled shift. */
tmp = load_reg(s, rn);
tmp2 = load_reg(s, rm);
if ((insn & 0x70) != 0)
goto illegal_op;
/*
* 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
* - MOV, MOVS (register-shifted register), flagsetting
*/
op = (insn >> 21) & 3;
logic_cc = (insn & (1 << 20)) != 0;
gen_arm_shift_reg(s, tmp, op, tmp2, logic_cc);
if (logic_cc)
gen_logic_CC(s, tmp);
store_reg(s, rd, tmp);
break;
case 0: /* Register controlled shift, in decodetree */
goto illegal_op;
case 1: /* Sign/zero extend. */
op = (insn >> 20) & 7;
switch (op) {