diff mbox

[RFC] target-arm: Add and use symbolic names for register banks

Message ID 1445278174-9089-1-git-send-email-soren.brinkmann@xilinx.com
State New
Headers show

Commit Message

Soren Brinkmann Oct. 19, 2015, 6:09 p.m. UTC
Add ARM_BANK_<cpumode> #defines to index banked registers.

Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
---
This change was suggested by Peter in the submission of "target-arm: Add
support for SPSR_(ABT|UND|IRQ|FIQ)", which this patch depends on.
I applied this to the banked_(spsr|r13|r14) registers. There seem to be
more banked registers (e.g. elr_el), but they might require a different
mapping.

	Thanks,
	Sören
---
 target-arm/cpu.h       | 10 ++++++++++
 target-arm/helper.c    | 37 ++++++++++++++++++++++---------------
 target-arm/internals.h |  6 +++---
 target-arm/kvm32.c     | 34 +++++++++++++++++-----------------
 target-arm/op_helper.c |  8 ++++----
 5 files changed, 56 insertions(+), 39 deletions(-)

Comments

Peter Crosthwaite Oct. 19, 2015, 6:49 p.m. UTC | #1
On Mon, Oct 19, 2015 at 11:09 AM, Soren Brinkmann
<soren.brinkmann@xilinx.com> wrote:
> Add ARM_BANK_<cpumode> #defines to index banked registers.
>
> Suggested-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
> ---
> This change was suggested by Peter in the submission of "target-arm: Add
> support for SPSR_(ABT|UND|IRQ|FIQ)", which this patch depends on.
> I applied this to the banked_(spsr|r13|r14) registers. There seem to be
> more banked registers (e.g. elr_el), but they might require a different
> mapping.
>
>         Thanks,
>         Sören
> ---
>  target-arm/cpu.h       | 10 ++++++++++
>  target-arm/helper.c    | 37 ++++++++++++++++++++++---------------
>  target-arm/internals.h |  6 +++---
>  target-arm/kvm32.c     | 34 +++++++++++++++++-----------------
>  target-arm/op_helper.c |  8 ++++----
>  5 files changed, 56 insertions(+), 39 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 3daa7f58f92b..6353f8c23bf8 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h

The defs shouldn't need to to leave target-arm so it should be
possible to get them into internals.h.

> @@ -862,6 +862,16 @@ enum arm_cpu_mode {
>  #define ARM_IWMMXT_wCGR2       10
>  #define ARM_IWMMXT_wCGR3       11
>
> +/* register banks for CPU modes */
> +#define ARM_BANK_USRSYS 0
> +#define ARM_BANK_SVC    1
> +#define ARM_BANK_ABT    2
> +#define ARM_BANK_UND    3
> +#define ARM_BANK_IRQ    4
> +#define ARM_BANK_FIQ    5
> +#define ARM_BANK_HYP    6
> +#define ARM_BANK_MON    7
> +

And if we do that, we should be able to drop the ARM_ prefix from
everything as there will be no global contamination.

Regards,
Peter

>  /* If adding a feature bit which corresponds to a Linux ELF
>   * HWCAP bit, remember to update the feature-bit-to-hwcap
>   * mapping in linux-user/elfload.c:get_elf_hwcap().
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index aba5025403a7..0cb47f7561a5 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -3122,7 +3122,8 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
>      { .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64,
>        .type = ARM_CP_ALIAS,
>        .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
> -      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[1]) },
> +      .access = PL1_RW,
> +      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_SVC]) },
>      /* We rely on the access checks not allowing the guest to write to the
>       * state field when SPSel indicates that it's being used as the stack
>       * pointer.
> @@ -3287,23 +3288,28 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
>      { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
>        .type = ARM_CP_ALIAS,
>        .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
> -      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[6]) },
> +      .access = PL2_RW,
> +      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_HYP]) },
>      { .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
>        .type = ARM_CP_ALIAS,
>        .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0,
> -      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[4]) },
> +      .access = PL2_RW,
> +      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_IRQ]) },
>      { .name = "SPSR_ABT", .state = ARM_CP_STATE_AA64,
>        .type = ARM_CP_ALIAS,
>        .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 1,
> -      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[2]) },
> +      .access = PL2_RW,
> +      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_ABT]) },
>      { .name = "SPSR_UND", .state = ARM_CP_STATE_AA64,
>        .type = ARM_CP_ALIAS,
>        .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 2,
> -      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[3]) },
> +      .access = PL2_RW,
> +      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_UND]) },
>      { .name = "SPSR_FIQ", .state = ARM_CP_STATE_AA64,
>        .type = ARM_CP_ALIAS,
>        .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 3,
> -      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[5]) },
> +      .access = PL2_RW,
> +      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_FIQ]) },
>      { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
>        .access = PL2_RW, .writefn = vbar_write,
> @@ -3532,7 +3538,8 @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
>      { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64,
>        .type = ARM_CP_ALIAS,
>        .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0,
> -      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[7]) },
> +      .access = PL3_RW,
> +      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_MON]) },
>      { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0,
>        .access = PL3_RW, .writefn = vbar_write,
> @@ -5163,21 +5170,21 @@ int bank_number(int mode)
>      switch (mode) {
>      case ARM_CPU_MODE_USR:
>      case ARM_CPU_MODE_SYS:
> -        return 0;
> +        return ARM_BANK_USRSYS;
>      case ARM_CPU_MODE_SVC:
> -        return 1;
> +        return ARM_BANK_SVC;
>      case ARM_CPU_MODE_ABT:
> -        return 2;
> +        return ARM_BANK_ABT;
>      case ARM_CPU_MODE_UND:
> -        return 3;
> +        return ARM_BANK_UND;
>      case ARM_CPU_MODE_IRQ:
> -        return 4;
> +        return ARM_BANK_IRQ;
>      case ARM_CPU_MODE_FIQ:
> -        return 5;
> +        return ARM_BANK_FIQ;
>      case ARM_CPU_MODE_HYP:
> -        return 6;
> +        return ARM_BANK_HYP;
>      case ARM_CPU_MODE_MON:
> -        return 7;
> +        return ARM_BANK_MON;
>      }
>      g_assert_not_reached();
>  }
> diff --git a/target-arm/internals.h b/target-arm/internals.h
> index 36a56aadb0b5..c2cf9dc36e1b 100644
> --- a/target-arm/internals.h
> +++ b/target-arm/internals.h
> @@ -91,9 +91,9 @@ static inline void arm_log_exception(int idx)
>  static inline unsigned int aarch64_banked_spsr_index(unsigned int el)
>  {
>      static const unsigned int map[4] = {
> -        [1] = 1, /* EL1.  */
> -        [2] = 6, /* EL2.  */
> -        [3] = 7, /* EL3.  */
> +        [1] = ARM_BANK_SVC, /* EL1.  */
> +        [2] = ARM_BANK_HYP, /* EL2.  */
> +        [3] = ARM_BANK_MON, /* EL3.  */
>      };
>      assert(el >= 1 && el <= 3);
>      return map[el];
> diff --git a/target-arm/kvm32.c b/target-arm/kvm32.c
> index 3ae57a6d68db..85b478a60ce4 100644
> --- a/target-arm/kvm32.c
> +++ b/target-arm/kvm32.c
> @@ -280,30 +280,30 @@ static const Reg regs[] = {
>      COREREG(usr_regs.uregs[10], usr_regs[2]),
>      COREREG(usr_regs.uregs[11], usr_regs[3]),
>      COREREG(usr_regs.uregs[12], usr_regs[4]),
> -    COREREG(usr_regs.uregs[13], banked_r13[0]),
> -    COREREG(usr_regs.uregs[14], banked_r14[0]),
> +    COREREG(usr_regs.uregs[13], banked_r13[ARM_BANK_USRSYS]),
> +    COREREG(usr_regs.uregs[14], banked_r14[ARM_BANK_USRSYS]),
>      /* R13, R14, SPSR for SVC, ABT, UND, IRQ banks */
> -    COREREG(svc_regs[0], banked_r13[1]),
> -    COREREG(svc_regs[1], banked_r14[1]),
> -    COREREG64(svc_regs[2], banked_spsr[1]),
> -    COREREG(abt_regs[0], banked_r13[2]),
> -    COREREG(abt_regs[1], banked_r14[2]),
> -    COREREG64(abt_regs[2], banked_spsr[2]),
> -    COREREG(und_regs[0], banked_r13[3]),
> -    COREREG(und_regs[1], banked_r14[3]),
> -    COREREG64(und_regs[2], banked_spsr[3]),
> -    COREREG(irq_regs[0], banked_r13[4]),
> -    COREREG(irq_regs[1], banked_r14[4]),
> -    COREREG64(irq_regs[2], banked_spsr[4]),
> +    COREREG(svc_regs[0], banked_r13[ARM_BANK_SVC]),
> +    COREREG(svc_regs[1], banked_r14[ARM_BANK_SVC]),
> +    COREREG64(svc_regs[2], banked_spsr[ARM_BANK_SVC]),
> +    COREREG(abt_regs[0], banked_r13[ARM_BANK_ABT]),
> +    COREREG(abt_regs[1], banked_r14[ARM_BANK_ABT]),
> +    COREREG64(abt_regs[2], banked_spsr[ARM_BANK_ABT]),
> +    COREREG(und_regs[0], banked_r13[ARM_BANK_UND]),
> +    COREREG(und_regs[1], banked_r14[ARM_BANK_UND]),
> +    COREREG64(und_regs[2], banked_spsr[ARM_BANK_UND]),
> +    COREREG(irq_regs[0], banked_r13[ARM_BANK_IRQ]),
> +    COREREG(irq_regs[1], banked_r14[ARM_BANK_IRQ]),
> +    COREREG64(irq_regs[2], banked_spsr[ARM_BANK_IRQ]),
>      /* R8_fiq .. R14_fiq and SPSR_fiq */
>      COREREG(fiq_regs[0], fiq_regs[0]),
>      COREREG(fiq_regs[1], fiq_regs[1]),
>      COREREG(fiq_regs[2], fiq_regs[2]),
>      COREREG(fiq_regs[3], fiq_regs[3]),
>      COREREG(fiq_regs[4], fiq_regs[4]),
> -    COREREG(fiq_regs[5], banked_r13[5]),
> -    COREREG(fiq_regs[6], banked_r14[5]),
> -    COREREG64(fiq_regs[7], banked_spsr[5]),
> +    COREREG(fiq_regs[5], banked_r13[ARM_BANK_FIQ]),
> +    COREREG(fiq_regs[6], banked_r14[ARM_BANK_FIQ]),
> +    COREREG64(fiq_regs[7], banked_spsr[ARM_BANK_FIQ]),
>      /* R15 */
>      COREREG(usr_regs.uregs[15], regs[15]),
>      /* VFP system registers */
> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> index 7929c71b43bf..c43e6c66212f 100644
> --- a/target-arm/op_helper.c
> +++ b/target-arm/op_helper.c
> @@ -384,9 +384,9 @@ uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
>      uint32_t val;
>
>      if (regno == 13) {
> -        val = env->banked_r13[0];
> +        val = env->banked_r13[ARM_BANK_USRSYS];
>      } else if (regno == 14) {
> -        val = env->banked_r14[0];
> +        val = env->banked_r14[ARM_BANK_USRSYS];
>      } else if (regno >= 8
>                 && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
>          val = env->usr_regs[regno - 8];
> @@ -399,9 +399,9 @@ uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
>  void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
>  {
>      if (regno == 13) {
> -        env->banked_r13[0] = val;
> +        env->banked_r13[ARM_BANK_USRSYS] = val;
>      } else if (regno == 14) {
> -        env->banked_r14[0] = val;
> +        env->banked_r14[ARM_BANK_USRSYS] = val;
>      } else if (regno >= 8
>                 && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
>          env->usr_regs[regno - 8] = val;
> --
> 2.6.2.3.ga463a5b
>
>
diff mbox

Patch

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 3daa7f58f92b..6353f8c23bf8 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -862,6 +862,16 @@  enum arm_cpu_mode {
 #define ARM_IWMMXT_wCGR2	10
 #define ARM_IWMMXT_wCGR3	11
 
+/* register banks for CPU modes */
+#define ARM_BANK_USRSYS 0
+#define ARM_BANK_SVC    1
+#define ARM_BANK_ABT    2
+#define ARM_BANK_UND    3
+#define ARM_BANK_IRQ    4
+#define ARM_BANK_FIQ    5
+#define ARM_BANK_HYP    6
+#define ARM_BANK_MON    7
+
 /* If adding a feature bit which corresponds to a Linux ELF
  * HWCAP bit, remember to update the feature-bit-to-hwcap
  * mapping in linux-user/elfload.c:get_elf_hwcap().
diff --git a/target-arm/helper.c b/target-arm/helper.c
index aba5025403a7..0cb47f7561a5 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3122,7 +3122,8 @@  static const ARMCPRegInfo v8_cp_reginfo[] = {
     { .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS,
       .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[1]) },
+      .access = PL1_RW,
+      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_SVC]) },
     /* We rely on the access checks not allowing the guest to write to the
      * state field when SPSel indicates that it's being used as the stack
      * pointer.
@@ -3287,23 +3288,28 @@  static const ARMCPRegInfo el2_cp_reginfo[] = {
     { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS,
       .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
-      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[6]) },
+      .access = PL2_RW,
+      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_HYP]) },
     { .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS,
       .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0,
-      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[4]) },
+      .access = PL2_RW,
+      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_IRQ]) },
     { .name = "SPSR_ABT", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS,
       .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 1,
-      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[2]) },
+      .access = PL2_RW,
+      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_ABT]) },
     { .name = "SPSR_UND", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS,
       .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 2,
-      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[3]) },
+      .access = PL2_RW,
+      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_UND]) },
     { .name = "SPSR_FIQ", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS,
       .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 3,
-      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[5]) },
+      .access = PL2_RW,
+      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_FIQ]) },
     { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
       .access = PL2_RW, .writefn = vbar_write,
@@ -3532,7 +3538,8 @@  static const ARMCPRegInfo el3_cp_reginfo[] = {
     { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS,
       .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0,
-      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[7]) },
+      .access = PL3_RW,
+      .fieldoffset = offsetof(CPUARMState, banked_spsr[ARM_BANK_MON]) },
     { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0,
       .access = PL3_RW, .writefn = vbar_write,
@@ -5163,21 +5170,21 @@  int bank_number(int mode)
     switch (mode) {
     case ARM_CPU_MODE_USR:
     case ARM_CPU_MODE_SYS:
-        return 0;
+        return ARM_BANK_USRSYS;
     case ARM_CPU_MODE_SVC:
-        return 1;
+        return ARM_BANK_SVC;
     case ARM_CPU_MODE_ABT:
-        return 2;
+        return ARM_BANK_ABT;
     case ARM_CPU_MODE_UND:
-        return 3;
+        return ARM_BANK_UND;
     case ARM_CPU_MODE_IRQ:
-        return 4;
+        return ARM_BANK_IRQ;
     case ARM_CPU_MODE_FIQ:
-        return 5;
+        return ARM_BANK_FIQ;
     case ARM_CPU_MODE_HYP:
-        return 6;
+        return ARM_BANK_HYP;
     case ARM_CPU_MODE_MON:
-        return 7;
+        return ARM_BANK_MON;
     }
     g_assert_not_reached();
 }
diff --git a/target-arm/internals.h b/target-arm/internals.h
index 36a56aadb0b5..c2cf9dc36e1b 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -91,9 +91,9 @@  static inline void arm_log_exception(int idx)
 static inline unsigned int aarch64_banked_spsr_index(unsigned int el)
 {
     static const unsigned int map[4] = {
-        [1] = 1, /* EL1.  */
-        [2] = 6, /* EL2.  */
-        [3] = 7, /* EL3.  */
+        [1] = ARM_BANK_SVC, /* EL1.  */
+        [2] = ARM_BANK_HYP, /* EL2.  */
+        [3] = ARM_BANK_MON, /* EL3.  */
     };
     assert(el >= 1 && el <= 3);
     return map[el];
diff --git a/target-arm/kvm32.c b/target-arm/kvm32.c
index 3ae57a6d68db..85b478a60ce4 100644
--- a/target-arm/kvm32.c
+++ b/target-arm/kvm32.c
@@ -280,30 +280,30 @@  static const Reg regs[] = {
     COREREG(usr_regs.uregs[10], usr_regs[2]),
     COREREG(usr_regs.uregs[11], usr_regs[3]),
     COREREG(usr_regs.uregs[12], usr_regs[4]),
-    COREREG(usr_regs.uregs[13], banked_r13[0]),
-    COREREG(usr_regs.uregs[14], banked_r14[0]),
+    COREREG(usr_regs.uregs[13], banked_r13[ARM_BANK_USRSYS]),
+    COREREG(usr_regs.uregs[14], banked_r14[ARM_BANK_USRSYS]),
     /* R13, R14, SPSR for SVC, ABT, UND, IRQ banks */
-    COREREG(svc_regs[0], banked_r13[1]),
-    COREREG(svc_regs[1], banked_r14[1]),
-    COREREG64(svc_regs[2], banked_spsr[1]),
-    COREREG(abt_regs[0], banked_r13[2]),
-    COREREG(abt_regs[1], banked_r14[2]),
-    COREREG64(abt_regs[2], banked_spsr[2]),
-    COREREG(und_regs[0], banked_r13[3]),
-    COREREG(und_regs[1], banked_r14[3]),
-    COREREG64(und_regs[2], banked_spsr[3]),
-    COREREG(irq_regs[0], banked_r13[4]),
-    COREREG(irq_regs[1], banked_r14[4]),
-    COREREG64(irq_regs[2], banked_spsr[4]),
+    COREREG(svc_regs[0], banked_r13[ARM_BANK_SVC]),
+    COREREG(svc_regs[1], banked_r14[ARM_BANK_SVC]),
+    COREREG64(svc_regs[2], banked_spsr[ARM_BANK_SVC]),
+    COREREG(abt_regs[0], banked_r13[ARM_BANK_ABT]),
+    COREREG(abt_regs[1], banked_r14[ARM_BANK_ABT]),
+    COREREG64(abt_regs[2], banked_spsr[ARM_BANK_ABT]),
+    COREREG(und_regs[0], banked_r13[ARM_BANK_UND]),
+    COREREG(und_regs[1], banked_r14[ARM_BANK_UND]),
+    COREREG64(und_regs[2], banked_spsr[ARM_BANK_UND]),
+    COREREG(irq_regs[0], banked_r13[ARM_BANK_IRQ]),
+    COREREG(irq_regs[1], banked_r14[ARM_BANK_IRQ]),
+    COREREG64(irq_regs[2], banked_spsr[ARM_BANK_IRQ]),
     /* R8_fiq .. R14_fiq and SPSR_fiq */
     COREREG(fiq_regs[0], fiq_regs[0]),
     COREREG(fiq_regs[1], fiq_regs[1]),
     COREREG(fiq_regs[2], fiq_regs[2]),
     COREREG(fiq_regs[3], fiq_regs[3]),
     COREREG(fiq_regs[4], fiq_regs[4]),
-    COREREG(fiq_regs[5], banked_r13[5]),
-    COREREG(fiq_regs[6], banked_r14[5]),
-    COREREG64(fiq_regs[7], banked_spsr[5]),
+    COREREG(fiq_regs[5], banked_r13[ARM_BANK_FIQ]),
+    COREREG(fiq_regs[6], banked_r14[ARM_BANK_FIQ]),
+    COREREG64(fiq_regs[7], banked_spsr[ARM_BANK_FIQ]),
     /* R15 */
     COREREG(usr_regs.uregs[15], regs[15]),
     /* VFP system registers */
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 7929c71b43bf..c43e6c66212f 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -384,9 +384,9 @@  uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
     uint32_t val;
 
     if (regno == 13) {
-        val = env->banked_r13[0];
+        val = env->banked_r13[ARM_BANK_USRSYS];
     } else if (regno == 14) {
-        val = env->banked_r14[0];
+        val = env->banked_r14[ARM_BANK_USRSYS];
     } else if (regno >= 8
                && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
         val = env->usr_regs[regno - 8];
@@ -399,9 +399,9 @@  uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
 void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
 {
     if (regno == 13) {
-        env->banked_r13[0] = val;
+        env->banked_r13[ARM_BANK_USRSYS] = val;
     } else if (regno == 14) {
-        env->banked_r14[0] = val;
+        env->banked_r14[ARM_BANK_USRSYS] = val;
     } else if (regno >= 8
                && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
         env->usr_regs[regno - 8] = val;