mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-03-08 10:09:43 +00:00
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:
parent
e151696a65
commit
1b21ced6a1
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue