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:
parent
25ae32c558
commit
5be2c12337
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user