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.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190904193059.26202-5-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Richard Henderson 2019-09-04 12:29:54 -07:00 committed by Peter Maydell
parent 25ae32c558
commit 5be2c12337
3 changed files with 87 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

@ -7795,17 +7795,66 @@ 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)(TCGv_i32, 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(tmp2, a->shty, tmp1, logic_cc);
tmp1 = load_reg(s, a->rn);
gen(tmp1, tmp1, tmp2);
tcg_temp_free_i32(tmp2);
if (logic_cc) {
gen_logic_CC(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)(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(tmp2, a->shty, tmp1, logic_cc);
gen(tmp2, tmp2);
if (logic_cc) {
gen_logic_CC(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, tcg_gen_and_i32, a->s, STREG_NORMAL)
DO_ANY3(EOR, tcg_gen_xor_i32, a->s, STREG_NORMAL)
@ -9590,7 +9639,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.
@ -10028,22 +10076,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(tmp, op, tmp2, logic_cc);
if (logic_cc)
gen_logic_CC(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) {