mirror of https://github.com/xemu-project/xemu.git
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_shi s rd rn rm shim shty
|
||||||
|
&s_rrr_shr s rn rd rm rs shty
|
||||||
|
|
||||||
# Data-processing (register)
|
# Data-processing (register)
|
||||||
|
|
||||||
|
@ -49,3 +50,29 @@ ORR_rrri .... 000 1100 . .... .... ..... .. 0 .... @s_rrr_shi
|
||||||
MOV_rxri .... 000 1101 . 0000 .... ..... .. 0 .... @s_rxr_shi
|
MOV_rxri .... 000 1101 . 0000 .... ..... .. 0 .... @s_rxr_shi
|
||||||
BIC_rrri .... 000 1110 . .... .... ..... .. 0 .... @s_rrr_shi
|
BIC_rrri .... 000 1110 . .... .... ..... .. 0 .... @s_rrr_shi
|
||||||
MVN_rxri .... 000 1111 . 0000 .... ..... .. 0 .... @s_rxr_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_shi !extern s rd rn rm shim shty
|
||||||
|
&s_rrr_shr !extern s rn rd rm rs shty
|
||||||
|
|
||||||
# Data-processing (register)
|
# Data-processing (register)
|
||||||
|
|
||||||
|
@ -61,3 +62,8 @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
|
||||||
SUB_rrri 1110101 1101 . .... 0 ... .... .... .... @s_rrr_shi
|
SUB_rrri 1110101 1101 . .... 0 ... .... .... .... @s_rrr_shi
|
||||||
}
|
}
|
||||||
RSB_rrri 1110101 1110 . .... 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);
|
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) \
|
#define DO_ANY3(NAME, OP, L, K) \
|
||||||
static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
|
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) \
|
#define DO_ANY2(NAME, OP, L, K) \
|
||||||
static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
|
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) \
|
#define DO_CMP2(NAME, OP, L) \
|
||||||
static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
|
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(AND, tcg_gen_and_i32, a->s, STREG_NORMAL)
|
||||||
DO_ANY3(EOR, tcg_gen_xor_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_i32 addr;
|
||||||
TCGv_i64 tmp64;
|
TCGv_i64 tmp64;
|
||||||
int op;
|
int op;
|
||||||
int logic_cc;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ARMv6-M supports a limited subset of Thumb2 instructions.
|
* 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)
|
if (op < 4 && (insn & 0xf000) != 0xf000)
|
||||||
goto illegal_op;
|
goto illegal_op;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case 0: /* Register controlled shift. */
|
case 0: /* Register controlled shift, in decodetree */
|
||||||
tmp = load_reg(s, rn);
|
|
||||||
tmp2 = load_reg(s, rm);
|
|
||||||
if ((insn & 0x70) != 0)
|
|
||||||
goto illegal_op;
|
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 1: /* Sign/zero extend. */
|
case 1: /* Sign/zero extend. */
|
||||||
op = (insn >> 20) & 7;
|
op = (insn >> 20) & 7;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|
Loading…
Reference in New Issue