Re: [Qemu-devel] [PATCH v2 04/68] target/arm: Convert Data Processing (reg-shifted-reg)

2019-08-23 Thread Peter Maydell
On Mon, 19 Aug 2019 at 22:38, Richard Henderson
 wrote:
>
> 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.
>
> Signed-off-by: Richard Henderson 
> ---
>  target/arm/translate.c | 74 ++
>  target/arm/a32.decode  | 27 +++
>  target/arm/t32.decode  |  6 
>  3 files changed, 87 insertions(+), 20 deletions(-)

Reviewed-by: Peter Maydell 

thanks
-- PMM



[Qemu-devel] [PATCH v2 04/68] target/arm: Convert Data Processing (reg-shifted-reg)

2019-08-19 Thread Richard Henderson
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.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 74 ++
 target/arm/a32.decode  | 27 +++
 target/arm/t32.decode  |  6 
 3 files changed, 87 insertions(+), 20 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index be8e7685e3..a32fe4b222 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -7773,17 +7773,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##_(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)
@@ -9555,7 +9604,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.
@@ -9993,22 +10041,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;
-/*
- * 0b_1010_0xxx_____:
- *  - 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) {
diff --git a/target/arm/a32.decode b/target/arm/a32.decode
index b23e83f17c..8e0fb06d05 100644
--- a/target/arm/a32.decode
+++ b/target/arm/a32.decode
@@ -23,6 +23,7 @@
 #
 
 _rrr_shi   s rd rn rm shim shty
+_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 .   . .. 0 @s_rxr_shi
 BIC_rrri  000