Re: [Qemu-devel] [PATCH v2 33/68] target/arm: Convert RFE and SRS

2019-08-25 Thread Peter Maydell
On Mon, 19 Aug 2019 at 22:38, Richard Henderson
 wrote:
>
> Signed-off-by: Richard Henderson 
> ---
>  target/arm/translate.c   | 150 ++-
>  target/arm/a32-uncond.decode |   8 ++
>  target/arm/t32.decode|  12 +++
>  3 files changed, 81 insertions(+), 89 deletions(-)
>
> diff --git a/target/arm/translate.c b/target/arm/translate.c
> index b6d8b7be8c..e268c5168d 100644
> --- a/target/arm/translate.c
> +++ b/target/arm/translate.c
> @@ -9980,16 +9980,71 @@ static bool trans_SVC(DisasContext *s, arg_SVC *a)
>  return true;
>  }
>
> +/*
> + * Unconditional system instructions
> + */
> +
> +static bool trans_RFE(DisasContext *s, arg_RFE *a)
> +{
> +int32_t offset;
> +TCGv_i32 addr, t1, t2;
> +
> +if (IS_USER(s) || !ENABLE_ARCH_6) {
> +return false;
> +}

The legacy thumb decoder for RFE and SRS also has
"not if M profile", which we seem to be missing here ?

> diff --git a/target/arm/a32-uncond.decode b/target/arm/a32-uncond.decode
> index 573ac2cf8e..3b961233e5 100644
> --- a/target/arm/a32-uncond.decode
> +++ b/target/arm/a32-uncond.decode
> @@ -29,3 +29,11 @@
>  %imm24h  0:s24 24:1 !function=times_2
>
>  BLX_i 101 .   &i imm=%imm24h
> +
> +# System Instructions
> +
> +&rfe rn w pu
> +&srs mode w pu
> +
> +RFE   100 pu:2 0 w:1 1 rn:4  1010     &rfe
> +SRS   110 pu:2 1 w:1 0 1101  0101 000 mode:5  &srs

Is this SRS encoding correct? The copy of the Arm ARM I'm looking at
thinks that it starts  100, the same as RFE.

Otherwise
Reviewed-by: Peter Maydell 

thanks
-- PMM



[Qemu-devel] [PATCH v2 33/68] target/arm: Convert RFE and SRS

2019-08-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate.c   | 150 ++-
 target/arm/a32-uncond.decode |   8 ++
 target/arm/t32.decode|  12 +++
 3 files changed, 81 insertions(+), 89 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index b6d8b7be8c..e268c5168d 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -9980,16 +9980,71 @@ static bool trans_SVC(DisasContext *s, arg_SVC *a)
 return true;
 }
 
+/*
+ * Unconditional system instructions
+ */
+
+static bool trans_RFE(DisasContext *s, arg_RFE *a)
+{
+int32_t offset;
+TCGv_i32 addr, t1, t2;
+
+if (IS_USER(s) || !ENABLE_ARCH_6) {
+return false;
+}
+
+addr = load_reg(s, a->rn);
+
+switch (a->pu) {
+case 0: offset = -4; break; /* DA */
+case 1: offset =  0; break; /* IA */
+case 2: offset = -8; break; /* DB */
+case 3: offset =  4; break; /* IB */
+default:
+g_assert_not_reached();
+}
+tcg_gen_addi_i32(addr, addr, offset);
+
+/* Load PC into tmp and CPSR into tmp2.  */
+t1 = tcg_temp_new_i32();
+gen_aa32_ld32u(s, t1, addr, get_mem_index(s));
+tcg_gen_addi_i32(addr, addr, 4);
+t2 = tcg_temp_new_i32();
+gen_aa32_ld32u(s, t2, addr, get_mem_index(s));
+
+if (a->w) {
+/* Base writeback.  */
+switch (a->pu) {
+case 0: offset = -8; break;
+case 1: offset =  4; break;
+case 2: offset = -4; break;
+case 3: offset =  0; break;
+}
+tcg_gen_addi_i32(addr, addr, offset);
+store_reg(s, a->rn, addr);
+} else {
+tcg_temp_free_i32(addr);
+}
+gen_rfe(s, t1, t2);
+return true;
+}
+
+static bool trans_SRS(DisasContext *s, arg_SRS *a)
+{
+if (!ENABLE_ARCH_6) {
+return false;
+}
+gen_srs(s, a->mode, a->pu, a->w);
+return true;
+}
+
 /*
  * Legacy decoder.
  */
 
 static void disas_arm_insn(DisasContext *s, unsigned int insn)
 {
-unsigned int cond, op1, i, rn;
-TCGv_i32 tmp;
-TCGv_i32 tmp2;
-TCGv_i32 addr;
+unsigned int cond, op1;
 
 /* M variants do not implement ARM mode; this must raise the INVSTATE
  * UsageFault exception.
@@ -10108,52 +10163,6 @@ static void disas_arm_insn(DisasContext *s, unsigned 
int insn)
 default:
 goto illegal_op;
 }
-} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
-/* srs */
-ARCH(6);
-gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
-return;
-} else if ((insn & 0x0e50ffe0) == 0x08100a00) {
-/* rfe */
-int32_t offset;
-if (IS_USER(s))
-goto illegal_op;
-ARCH(6);
-rn = (insn >> 16) & 0xf;
-addr = load_reg(s, rn);
-i = (insn >> 23) & 3;
-switch (i) {
-case 0: offset = -4; break; /* DA */
-case 1: offset = 0; break; /* IA */
-case 2: offset = -8; break; /* DB */
-case 3: offset = 4; break; /* IB */
-default: abort();
-}
-if (offset)
-tcg_gen_addi_i32(addr, addr, offset);
-/* Load PC into tmp and CPSR into tmp2.  */
-tmp = tcg_temp_new_i32();
-gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
-tcg_gen_addi_i32(addr, addr, 4);
-tmp2 = tcg_temp_new_i32();
-gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
-if (insn & (1 << 21)) {
-/* Base writeback.  */
-switch (i) {
-case 0: offset = -8; break;
-case 1: offset = 4; break;
-case 2: offset = -4; break;
-case 3: offset = 0; break;
-default: abort();
-}
-if (offset)
-tcg_gen_addi_i32(addr, addr, offset);
-store_reg(s, rn, addr);
-} else {
-tcg_temp_free_i32(addr);
-}
-gen_rfe(s, tmp, tmp2);
-return;
 } else if ((insn & 0x0e000f00) == 0x0c000100) {
 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
 /* iWMMXt register transfer.  */
@@ -10316,7 +10325,6 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t 
insn)
 uint32_t imm, offset;
 uint32_t rd, rn, rm, rs;
 TCGv_i32 tmp;
-TCGv_i32 tmp2;
 TCGv_i32 addr;
 int op;
 
@@ -10460,44 +10468,8 @@ static void disas_thumb2_insn(DisasContext *s, 
uint32_t insn)
 goto illegal_op;
 }
 } else {
-/* Load/store multiple, RFE, SRS.  */
-if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
-/* RFE, SRS: not available in user mode or on M profile */
-if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
-goto illegal_op;
-}
-