Skip to content

Commit

Permalink
target/arm: Convert Data Processing (reg-shifted-reg)
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
rth7680 authored and pm215 committed Sep 5, 2019
1 parent 25ae32c commit 5be2c12
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 20 deletions.
27 changes: 27 additions & 0 deletions target/arm/a32.decode
Expand Up @@ -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)

Expand All @@ -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
6 changes: 6 additions & 0 deletions target/arm/t32.decode
Expand Up @@ -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)

Expand Down Expand Up @@ -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
74 changes: 54 additions & 20 deletions target/arm/translate.c
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 5be2c12

Please sign in to comment.