* bfd/bfd-in2.h (BFD_RELOC_ARM_HVC): New enum value.
authorMatthew Gretton-Dann <matthew.gretton-dann@arm.com>
Thu, 23 Sep 2010 15:52:19 +0000 (15:52 +0000)
committerMatthew Gretton-Dann <matthew.gretton-dann@arm.com>
Thu, 23 Sep 2010 15:52:19 +0000 (15:52 +0000)
* gas/config/tc-arm.c (arm_ext_virt): New variable.
(arm_reg_type): Add REG_TYPE_RNB for banked registers.
(reg_entry): Allow registers to be larger than a byte.
(reg_alias): Fix type warning.
(parse_operands): Parse banked registers when appropriate.
(do_mrs): Add support for Virtualization Extensions.
(do_hvc): New function.
(do_t_mrs): Add support for Virtualization Extensions.
(do_t_msr): Likewise.
(do_t_hvc): New function.
(SPLRBANK): New define.
(reg_names): Add banked registers.
(insns): Add support for Virtualization Extensions.
(md_apply_fixup): Likewise.
(arm_cpus): -mcpu=cortex-a15 implies the Virtualization Extensions.
(arm_extensions): Add 'virt' extension.
(aeabi_set_public_attributes): Add support for Virtualization
Extensions.
* gas/doc/c-arm.texi: Document 'virt' extension.
* gas/testsuite/gas/arm/armv7-a+virt.d: New test.
* gas/testsuite/gas/arm/armv7-a+virt.s: Likewise.
* gas/testsuite/gas/arm/attr-march-all.d: Update for Virtualization Extensions.
* gas/testsuite/gas/arm/attr-march-armv7-a+sec+virt.d: New test.
* gas/testsuite/gas/arm/attr-march-armv7-a+virt.d: Likewise.
* include/opcode/arm.h (ARM_EXT_VIRT): New define.
(ARM_ARCH_V7A_IDIV_MP_SEC): Rename...
(ARM_ARCH_V7A_IDIV_MP_SEC_VIRT): ...to this and include Virtualization
Extensions.
* opcodes/arm-dis.c (arm_opcodes): Add Virtualiztion Extensions support.
(thumb32_opcodes): Likewise.
(banked_regname): New function.
(print_insn_arm): Add Virtualization Extensions support.
(print_insn_thumb32): Likewise.

15 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
gas/ChangeLog
gas/config/tc-arm.c
gas/doc/c-arm.texi
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/armv7-a+virt.d [new file with mode: 0644]
gas/testsuite/gas/arm/armv7-a+virt.s [new file with mode: 0644]
gas/testsuite/gas/arm/attr-march-all.d
gas/testsuite/gas/arm/attr-march-armv7-a+sec+virt.d [new file with mode: 0644]
gas/testsuite/gas/arm/attr-march-armv7-a+virt.d [new file with mode: 0644]
include/opcode/ChangeLog
include/opcode/arm.h
opcodes/ChangeLog
opcodes/arm-dis.c

index 2fe58b221e8f1fcf313f1931705b858270ff19ab..c31a1ebdc9bf6118c661c678c52d6bc1707eb3ce 100644 (file)
@@ -1,3 +1,7 @@
+2010-09-23  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
+
+       * bfd-in2.h (BFD_RELOC_ARM_HVC): New enum value.
+
 2010-09-23  Alan Modra  <amodra@gmail.com>
 
        * cpu-d10v.c: Make bits_per_address 18 for all arch_info entries.
index 0e7b337f7719571f92f50be6caacbbd5e66e67c0..4bd47caeb817df96523e2463c1402d911a44b185 100644 (file)
@@ -3166,6 +3166,7 @@ pc-relative or some form of GOT-indirect relocation.  */
   BFD_RELOC_ARM_T32_ADD_PC12,
   BFD_RELOC_ARM_SHIFT_IMM,
   BFD_RELOC_ARM_SMC,
+  BFD_RELOC_ARM_HVC,
   BFD_RELOC_ARM_SWI,
   BFD_RELOC_ARM_MULTI,
   BFD_RELOC_ARM_CP_OFF_IMM,
index d4d1e5c9f3dcc10d86910558d846d900e1bb04bd..2f1685a329c29943e3f5678e6a10c956f56fa80a 100644 (file)
@@ -1,3 +1,25 @@
+2010-09-23  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
+
+       * config/tc-arm.c (arm_ext_virt): New variable.
+       (arm_reg_type): Add REG_TYPE_RNB for banked registers.
+       (reg_entry): Allow registers to be larger than a byte.
+       (reg_alias): Fix type warning.
+       (parse_operands): Parse banked registers when appropriate.
+       (do_mrs): Add support for Virtualization Extensions.
+       (do_hvc): New function.
+       (do_t_mrs): Add support for Virtualization Extensions.
+       (do_t_msr): Likewise.
+       (do_t_hvc): New function.
+       (SPLRBANK): New define.
+       (reg_names): Add banked registers.
+       (insns): Add support for Virtualization Extensions.
+       (md_apply_fixup): Likewise.
+       (arm_cpus): -mcpu=cortex-a15 implies the Virtualization Extensions.
+       (arm_extensions): Add 'virt' extension.
+       (aeabi_set_public_attributes): Add support for Virtualization
+       Extensions.
+       * doc/c-arm.texi: Document 'virt' extension.
+
 2010-09-23  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
 
        * config/tc-arm.c (arm_ext_adiv): New variable.
index 886d92fa9c9cef656be3db96b1c400f72417f59a..e4bd9f1704e1e62f96d3511f98ce3631976a427e 100644 (file)
@@ -201,6 +201,7 @@ static const arm_feature_set arm_ext_mp = ARM_FEATURE (ARM_EXT_MP, 0);
 static const arm_feature_set arm_ext_sec = ARM_FEATURE (ARM_EXT_SEC, 0);
 static const arm_feature_set arm_ext_os = ARM_FEATURE (ARM_EXT_OS, 0);
 static const arm_feature_set arm_ext_adiv = ARM_FEATURE (ARM_EXT_ADIV, 0);
+static const arm_feature_set arm_ext_virt = ARM_FEATURE (ARM_EXT_VIRT, 0);
 
 static const arm_feature_set arm_arch_any = ARM_ANY;
 static const arm_feature_set arm_arch_full = ARM_FEATURE (-1, -1);
@@ -506,6 +507,7 @@ enum arm_reg_type
   REG_TYPE_MMXWC,
   REG_TYPE_MMXWCG,
   REG_TYPE_XSCALE,
+  REG_TYPE_RNB
 };
 
 /* Structure for a hash table entry for a register.
@@ -515,7 +517,7 @@ enum arm_reg_type
 struct reg_entry
 {
   const char *               name;
-  unsigned char              number;
+  unsigned int               number;
   unsigned char              type;
   unsigned char              builtin;
   struct neon_typed_alias *  neon;
@@ -2062,7 +2064,7 @@ parse_reloc (char **str)
 /* Directives: register aliases.  */
 
 static struct reg_entry *
-insert_reg_alias (char *str, int number, int type)
+insert_reg_alias (char *str, unsigned number, int type)
 {
   struct reg_entry *new_reg;
   const char *name;
@@ -6380,9 +6382,18 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
          break;
 
         case OP_RVC_PSR:
-          po_reg_or_goto (REG_TYPE_VFC, try_psr);
+          po_reg_or_goto (REG_TYPE_VFC, try_banked_reg);
           inst.operands[i].isvec = 1;  /* Mark VFP control reg as vector.  */
           break;
+         try_banked_reg:
+         po_reg_or_goto (REG_TYPE_RNB, try_psr);
+         if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_virt))
+           {
+             inst.error = _("Banked registers are not available with this "
+                            "architecture.");
+             goto failure;
+           }
+         break;
           try_psr:
           val = parse_psr (&str);
           break;
@@ -7851,16 +7862,30 @@ do_vmsr (void)
 static void
 do_mrs (void)
 {
+  unsigned br;
+
   if (do_vfp_nsyn_mrs () == SUCCESS)
     return;
 
-  /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all.  */
-  constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
-             != (PSR_c|PSR_f),
-             _("'CPSR' or 'SPSR' expected"));
   constraint (inst.operands[0].reg == REG_PC, BAD_PC);
   inst.instruction |= inst.operands[0].reg << 12;
-  inst.instruction |= (inst.operands[1].imm & SPSR_BIT);
+
+  if (inst.operands[1].isreg)
+    {
+      br = inst.operands[1].reg;
+      if (((br & 0x200) == 0) && ((br & 0xf0000) != 0xf000))
+       as_bad (_("bad register for mrs"));
+    }
+  else
+    {
+      /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all.  */
+      constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
+                 != (PSR_c|PSR_f),
+                 _("'CPSR' or 'SPSR' expected"));
+      br = (15<<16) | (inst.operands[1].imm & SPSR_BIT);
+    }
+
+  inst.instruction |= br;
 }
 
 /* Two possible forms:
@@ -8121,6 +8146,13 @@ do_smc (void)
   inst.reloc.pc_rel = 0;
 }
 
+static void
+do_hvc (void)
+{
+  inst.reloc.type = BFD_RELOC_ARM_HVC;
+  inst.reloc.pc_rel = 0;
+}
+
 static void
 do_swi (void)
 {
@@ -10734,34 +10766,48 @@ static void
 do_t_mrs (void)
 {
   unsigned Rd;
-  int flags;
 
   if (do_vfp_nsyn_mrs () == SUCCESS)
     return;
 
-  flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
-  if (flags == 0)
+  Rd = inst.operands[0].reg;
+  reject_bad_reg (Rd);
+  inst.instruction |= Rd << 8;
+
+  if (inst.operands[1].isreg)
     {
-      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m),
-                 _("selected processor does not support "
-                   "requested special purpose register"));
+      unsigned br = inst.operands[1].reg;
+      if (((br & 0x200) == 0) && ((br & 0xf000) != 0xf000))
+       as_bad (_("bad register for mrs"));
+
+      inst.instruction |= br & (0xf << 16);
+      inst.instruction |= (br & 0x300) >> 4;
+      inst.instruction |= (br & SPSR_BIT) >> 2;
     }
   else
     {
-      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1),
-                 _("selected processor does not support "
-                   "requested special purpose register"));
-      /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all.  */
-      constraint ((flags & ~SPSR_BIT) != (PSR_c|PSR_f),
-                 _("'CPSR' or 'SPSR' expected"));
-    }
+      int flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
 
-  Rd = inst.operands[0].reg;
-  reject_bad_reg (Rd);
+      if (flags == 0)
+       {
+         constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m),
+                     _("selected processor does not support "
+                       "requested special purpose register"));
+       }
+      else
+       {
+         constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1),
+                     _("selected processor does not support "
+                       "requested special purpose register"));
+         /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all.  */
+         constraint ((flags & ~SPSR_BIT) != (PSR_c|PSR_f),
+                     _("'CPSR' or 'SPSR' expected"));
+       }
 
-  inst.instruction |= Rd << 8;
-  inst.instruction |= (flags & SPSR_BIT) >> 2;
-  inst.instruction |= inst.operands[1].imm & 0xff;
+      inst.instruction |= (flags & SPSR_BIT) >> 2;
+      inst.instruction |= inst.operands[1].imm & 0xff;
+      inst.instruction |= 0xf0000;
+    }
 }
 
 static void
@@ -10775,7 +10821,12 @@ do_t_msr (void)
 
   constraint (!inst.operands[1].isreg,
              _("Thumb encoding does not support an immediate here"));
-  flags = inst.operands[0].imm;
+
+  if (inst.operands[0].isreg)
+    flags = (int)(inst.operands[0].reg);
+  else
+    flags = inst.operands[0].imm;
+
   if (flags & ~0xff)
     {
       constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1),
@@ -10794,7 +10845,8 @@ do_t_msr (void)
   reject_bad_reg (Rn);
 
   inst.instruction |= (flags & SPSR_BIT) >> 2;
-  inst.instruction |= (flags & ~SPSR_BIT) >> 8;
+  inst.instruction |= (flags & 0xf0000) >> 8;
+  inst.instruction |= (flags & 0x300) >> 4;
   inst.instruction |= (flags & 0xff);
   inst.instruction |= Rn << 16;
 }
@@ -11389,6 +11441,16 @@ do_t_smc (void)
   inst.instruction |= (value & 0x000f) << 16;
 }
 
+static void
+do_t_hvc (void)
+{
+  unsigned int value = inst.reloc.exp.X_add_number;
+
+  inst.reloc.type = BFD_RELOC_UNUSED;
+  inst.instruction |= (value & 0x0fff);
+  inst.instruction |= (value & 0xf000) << 4;
+}
+
 static void
 do_t_ssat_usat (int bias)
 {
@@ -16185,6 +16247,13 @@ arm_canonicalize_symbol_name (char * name)
   REGNUM2(p, 4,t), REGNUM2(p, 5,t), REGNUM2(p, 6,t), REGNUM2(p, 7,t), \
   REGNUM2(p, 8,t), REGNUM2(p, 9,t), REGNUM2(p,10,t), REGNUM2(p,11,t), \
   REGNUM2(p,12,t), REGNUM2(p,13,t), REGNUM2(p,14,t), REGNUM2(p,15,t)
+#define SPLRBANK(base,bank,t) \
+  REGDEF(lr_##bank, 768|((base+0)<<16), t), \
+  REGDEF(sp_##bank, 768|((base+1)<<16), t), \
+  REGDEF(spsr_##bank, 768|(base<<16)|SPSR_BIT, t), \
+  REGDEF(LR_##bank, 768|((base+0)<<16), t), \
+  REGDEF(SP_##bank, 768|((base+1)<<16), t), \
+  REGDEF(SPSR_##bank, 768|(base<<16)|SPSR_BIT, t)
 
 static const struct reg_entry reg_names[] =
 {
@@ -16215,6 +16284,34 @@ static const struct reg_entry reg_names[] =
   REGSET(c,  CN), REGSET(C, CN),
   REGSET(cr, CN), REGSET(CR, CN),
 
+  /* ARM banked registers.  */
+  REGDEF(R8_usr,512|(0<<16),RNB), REGDEF(r8_usr,512|(0<<16),RNB),
+  REGDEF(R9_usr,512|(1<<16),RNB), REGDEF(r9_usr,512|(1<<16),RNB),
+  REGDEF(R10_usr,512|(2<<16),RNB), REGDEF(r10_usr,512|(2<<16),RNB),
+  REGDEF(R11_usr,512|(3<<16),RNB), REGDEF(r11_usr,512|(3<<16),RNB),
+  REGDEF(R12_usr,512|(4<<16),RNB), REGDEF(r12_usr,512|(4<<16),RNB),
+  REGDEF(SP_usr,512|(5<<16),RNB), REGDEF(sp_usr,512|(5<<16),RNB),
+  REGDEF(LR_usr,512|(6<<16),RNB), REGDEF(lr_usr,512|(6<<16),RNB),
+
+  REGDEF(R8_fiq,512|(8<<16),RNB), REGDEF(r8_fiq,512|(8<<16),RNB),
+  REGDEF(R9_fiq,512|(9<<16),RNB), REGDEF(r9_fiq,512|(9<<16),RNB),
+  REGDEF(R10_fiq,512|(10<<16),RNB), REGDEF(r10_fiq,512|(10<<16),RNB),
+  REGDEF(R11_fiq,512|(11<<16),RNB), REGDEF(r11_fiq,512|(11<<16),RNB),
+  REGDEF(R12_fiq,512|(12<<16),RNB), REGDEF(r12_fiq,512|(12<<16),RNB),
+  REGDEF(SP_fiq,512|(13<<16),RNB), REGDEF(SP_fiq,512|(13<<16),RNB),
+  REGDEF(LR_fiq,512|(14<<16),RNB), REGDEF(lr_fiq,512|(14<<16),RNB),
+  REGDEF(SPSR_fiq,512|(14<<16)|SPSR_BIT,RNB), REGDEF(spsr_fiq,512|(14<<16)|SPSR_BIT,RNB),
+
+  SPLRBANK(0,IRQ,RNB), SPLRBANK(0,irq,RNB),
+  SPLRBANK(2,SVC,RNB), SPLRBANK(2,svc,RNB),
+  SPLRBANK(4,ABT,RNB), SPLRBANK(4,abt,RNB),
+  SPLRBANK(6,UND,RNB), SPLRBANK(6,und,RNB),
+  SPLRBANK(12,MON,RNB), SPLRBANK(12,mon,RNB),
+  REGDEF(elr_hyp,768|(14<<16),RNB), REGDEF(ELR_hyp,768|(14<<16),RNB),
+  REGDEF(sp_hyp,768|(15<<16),RNB), REGDEF(SP_hyp,768|(15<<16),RNB),
+  REGDEF(spsr_hyp,768|(14<<16)|SPSR_BIT,RNB), 
+  REGDEF(SPSR_hyp,768|(14<<16)|SPSR_BIT,RNB),
+
   /* FPA registers.  */
   REGNUM(f,0,FN), REGNUM(f,1,FN), REGNUM(f,2,FN), REGNUM(f,3,FN),
   REGNUM(f,4,FN), REGNUM(f,5,FN), REGNUM(f,6,FN), REGNUM(f,7, FN),
@@ -16800,7 +16897,7 @@ static const struct asm_opcode insns[] =
 #undef  THUMB_VARIANT
 #define THUMB_VARIANT  & arm_ext_msr
 
- TCE("mrs",    10f0000, f3ef8000, 2, (APSR_RR, RVC_PSR), mrs, t_mrs),
+ TCE("mrs",    1000000, f3e08000, 2, (APSR_RR, RVC_PSR), mrs, t_mrs),
  TCE("msr",    120f000, f3808000, 2, (RVC_PSR, RR_EXi), msr, t_msr),
 
 #undef  ARM_VARIANT
@@ -17088,6 +17185,14 @@ static const struct asm_opcode insns[] =
 
  TCE("smc",    1600070, f7f08000, 1, (EXPi), smc, t_smc),
 
+#undef ARM_VARIANT
+#define        ARM_VARIANT    & arm_ext_virt
+#undef THUMB_VARIANT
+#define        THUMB_VARIANT    & arm_ext_virt
+
+ TCE("hvc",    1400070, f7e08000, 1, (EXPi), hvc, t_hvc),
+ TCE("eret",   160006e, f3de8f00, 0, (), noargs, noargs),
+
 #undef  ARM_VARIANT
 #define ARM_VARIANT  & arm_ext_v6t2
 #undef  THUMB_VARIANT
@@ -20389,6 +20494,15 @@ md_apply_fix (fixS *   fixP,
       md_number_to_chars (buf, newval, INSN_SIZE);
       break;
 
+    case BFD_RELOC_ARM_HVC:
+      if (((unsigned long) value) > 0xffff)
+       as_bad_where (fixP->fx_file, fixP->fx_line,
+                     _("invalid hvc expression"));
+      newval = md_chars_to_number (buf, INSN_SIZE);
+      newval |= (value & 0xf) | ((value & 0xfff0) << 4);
+      md_number_to_chars (buf, newval, INSN_SIZE);
+      break;
+
     case BFD_RELOC_ARM_SWI:
       if (fixP->tc_fix_data != 0)
        {
@@ -22430,7 +22544,7 @@ static const struct arm_cpu_option_table arm_cpus[] =
                                         ARM_FEATURE (0, FPU_VFP_V3
                                                         | FPU_NEON_EXT_V1),
                                                           "Cortex-A9"},
-  {"cortex-a15",       ARM_ARCH_V7A_IDIV_MP_SEC,
+  {"cortex-a15",       ARM_ARCH_V7A_IDIV_MP_SEC_VIRT,
                                         FPU_ARCH_NEON_VFP_V4,
                                                           "Cortex-A15"},
   {"cortex-r4",                ARM_ARCH_V7R,    FPU_NONE,        "Cortex-R4"},
@@ -22529,6 +22643,8 @@ static const struct arm_option_extension_value_table arm_extensions[] =
                                   ARM_FEATURE (ARM_EXT_V6M, 0)},
   {"sec",      ARM_FEATURE (ARM_EXT_SEC, 0),
                     ARM_FEATURE (ARM_EXT_V6K | ARM_EXT_V7A, 0)},
+  {"virt",     ARM_FEATURE (ARM_EXT_VIRT | ARM_EXT_ADIV | ARM_EXT_DIV, 0),
+                                  ARM_FEATURE (ARM_EXT_V7A, 0)},
   {"xscale",   ARM_FEATURE (0, ARM_CEXT_XSCALE),       ARM_ANY},
   {NULL,       ARM_ARCH_NONE,                    ARM_ARCH_NONE}
 };
@@ -23084,6 +23200,7 @@ static void
 aeabi_set_public_attributes (void)
 {
   int arch;
+  int virt_sec = 0;
   arm_feature_set flags;
   arm_feature_set tmp;
   const cpu_arch_ver_table *p;
@@ -23214,7 +23331,11 @@ aeabi_set_public_attributes (void)
 
   /* Tag Virtualization_use.  */
   if (ARM_CPU_HAS_FEATURE (flags, arm_ext_sec))
-    aeabi_set_attribute_int (Tag_Virtualization_use, 1);
+    virt_sec |= 1;
+  if (ARM_CPU_HAS_FEATURE (flags, arm_ext_virt))
+    virt_sec |= 2;
+  if (virt_sec != 0)
+    aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec);
 }
 
 /* Add the default contents for the .ARM.attributes section.  */
index 2a5c351ddde30c0258afd369f0e3ac46e3c63327..d3cccf4a49828faf5e27c382d1cc0db55e35d0c9 100644 (file)
@@ -156,6 +156,8 @@ The following extensions are currently supported:
 @code{mp} (Multiprocessing Extensions for v7-A and v7-R architectures),
 @code{os} (Operating System for v6M architecture),
 @code{sec} (Security Extensions for v6K and v7-A architectures),
+@code{virt} (Virtualization Extensions for v7-A architecture, implies 
+@code{idiv}),
 and
 @code{xscale}.
 
index 37f84172e3ea4c6d1acf1e875ee378d708e78fa4..038c561577a656f57c02a80c31bda6f1fd99b974 100644 (file)
@@ -1,3 +1,11 @@
+2010-09-23  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
+
+       * gas/arm/armv7-a+virt.d: New test.
+       * gas/arm/armv7-a+virt.s: Likewise.
+       * gas/arm/attr-march-all.d: Update for Virtualization Extensions.
+       * gas/arm/attr-march-armv7-a+sec+virt.d: New test.
+       * gas/arm/attr-march-armv7-a+virt.d: Likewise.
+
 2010-09-23  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
 
        * gas/arm/armv7-a+idiv.d: New test.
diff --git a/gas/testsuite/gas/arm/armv7-a+virt.d b/gas/testsuite/gas/arm/armv7-a+virt.d
new file mode 100644 (file)
index 0000000..1e3224c
--- /dev/null
@@ -0,0 +1,145 @@
+# name: ARMv7-a+virt Instructions
+# as: -march=armv7-a+virt
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> e1400070    hvc     0
+0[0-9a-f]+ <[^>]+> e14fff7f    hvc     65535   ; 0xffff
+0[0-9a-f]+ <[^>]+> e160006e    eret
+0[0-9a-f]+ <[^>]+> e1001200    mrs     r1, R8_usr
+0[0-9a-f]+ <[^>]+> e1011200    mrs     r1, R9_usr
+0[0-9a-f]+ <[^>]+> e1021200    mrs     r1, R10_usr
+0[0-9a-f]+ <[^>]+> e1031200    mrs     r1, R11_usr
+0[0-9a-f]+ <[^>]+> e1041200    mrs     r1, R12_usr
+0[0-9a-f]+ <[^>]+> e1051200    mrs     r1, SP_usr
+0[0-9a-f]+ <[^>]+> e1061200    mrs     r1, LR_usr
+0[0-9a-f]+ <[^>]+> e1081200    mrs     r1, R8_fiq
+0[0-9a-f]+ <[^>]+> e1091200    mrs     r1, R9_fiq
+0[0-9a-f]+ <[^>]+> e10a1200    mrs     r1, R10_fiq
+0[0-9a-f]+ <[^>]+> e10b1200    mrs     r1, R11_fiq
+0[0-9a-f]+ <[^>]+> e10c1200    mrs     r1, R12_fiq
+0[0-9a-f]+ <[^>]+> e10d1200    mrs     r1, SP_fiq
+0[0-9a-f]+ <[^>]+> e10e1200    mrs     r1, LR_fiq
+0[0-9a-f]+ <[^>]+> e14e1200    mrs     r1, SPSR_fiq
+0[0-9a-f]+ <[^>]+> e1011300    mrs     r1, SP_irq
+0[0-9a-f]+ <[^>]+> e1001300    mrs     r1, LR_irq
+0[0-9a-f]+ <[^>]+> e1401300    mrs     r1, SPSR_irq
+0[0-9a-f]+ <[^>]+> e1031300    mrs     r1, SP_svc
+0[0-9a-f]+ <[^>]+> e1021300    mrs     r1, LR_svc
+0[0-9a-f]+ <[^>]+> e1421300    mrs     r1, SPSR_svc
+0[0-9a-f]+ <[^>]+> e1051300    mrs     r1, SP_abt
+0[0-9a-f]+ <[^>]+> e1041300    mrs     r1, LR_abt
+0[0-9a-f]+ <[^>]+> e1441300    mrs     r1, SPSR_abt
+0[0-9a-f]+ <[^>]+> e1071300    mrs     r1, SP_und
+0[0-9a-f]+ <[^>]+> e1061300    mrs     r1, LR_und
+0[0-9a-f]+ <[^>]+> e1461300    mrs     r1, SPSR_und
+0[0-9a-f]+ <[^>]+> e10d1300    mrs     r1, SP_mon
+0[0-9a-f]+ <[^>]+> e10c1300    mrs     r1, LR_mon
+0[0-9a-f]+ <[^>]+> e14c1300    mrs     r1, SPSR_mon
+0[0-9a-f]+ <[^>]+> e10f1300    mrs     r1, SP_hyp
+0[0-9a-f]+ <[^>]+> e10e1300    mrs     r1, ELR_hyp
+0[0-9a-f]+ <[^>]+> e14e1300    mrs     r1, SPSR_hyp
+0[0-9a-f]+ <[^>]+> e120f201    msr     R8_usr, r1
+0[0-9a-f]+ <[^>]+> e121f201    msr     R9_usr, r1
+0[0-9a-f]+ <[^>]+> e122f201    msr     R10_usr, r1
+0[0-9a-f]+ <[^>]+> e123f201    msr     R11_usr, r1
+0[0-9a-f]+ <[^>]+> e124f201    msr     R12_usr, r1
+0[0-9a-f]+ <[^>]+> e125f201    msr     SP_usr, r1
+0[0-9a-f]+ <[^>]+> e126f201    msr     LR_usr, r1
+0[0-9a-f]+ <[^>]+> e128f201    msr     R8_fiq, r1
+0[0-9a-f]+ <[^>]+> e129f201    msr     R9_fiq, r1
+0[0-9a-f]+ <[^>]+> e12af201    msr     R10_fiq, r1
+0[0-9a-f]+ <[^>]+> e12bf201    msr     R11_fiq, r1
+0[0-9a-f]+ <[^>]+> e12cf201    msr     R12_fiq, r1
+0[0-9a-f]+ <[^>]+> e12df201    msr     SP_fiq, r1
+0[0-9a-f]+ <[^>]+> e12ef201    msr     LR_fiq, r1
+0[0-9a-f]+ <[^>]+> e16ef201    msr     SPSR_fiq, r1
+0[0-9a-f]+ <[^>]+> e121f301    msr     SP_irq, r1
+0[0-9a-f]+ <[^>]+> e120f301    msr     LR_irq, r1
+0[0-9a-f]+ <[^>]+> e160f301    msr     SPSR_irq, r1
+0[0-9a-f]+ <[^>]+> e123f301    msr     SP_svc, r1
+0[0-9a-f]+ <[^>]+> e122f301    msr     LR_svc, r1
+0[0-9a-f]+ <[^>]+> e162f301    msr     SPSR_svc, r1
+0[0-9a-f]+ <[^>]+> e125f301    msr     SP_abt, r1
+0[0-9a-f]+ <[^>]+> e124f301    msr     LR_abt, r1
+0[0-9a-f]+ <[^>]+> e164f301    msr     SPSR_abt, r1
+0[0-9a-f]+ <[^>]+> e127f301    msr     SP_und, r1
+0[0-9a-f]+ <[^>]+> e126f301    msr     LR_und, r1
+0[0-9a-f]+ <[^>]+> e166f301    msr     SPSR_und, r1
+0[0-9a-f]+ <[^>]+> e12df301    msr     SP_mon, r1
+0[0-9a-f]+ <[^>]+> e12cf301    msr     LR_mon, r1
+0[0-9a-f]+ <[^>]+> e16cf301    msr     SPSR_mon, r1
+0[0-9a-f]+ <[^>]+> e12ff301    msr     SP_hyp, r1
+0[0-9a-f]+ <[^>]+> e12ef301    msr     ELR_hyp, r1
+0[0-9a-f]+ <[^>]+> e16ef301    msr     SPSR_hyp, r1
+0[0-9a-f]+ <[^>]+> f7e0 8000   hvc     #0
+0[0-9a-f]+ <[^>]+> f7ef 8fff   hvc     #65535  ; 0xffff
+0[0-9a-f]+ <[^>]+> f3de 8f00   subs    pc, lr, #0
+0[0-9a-f]+ <[^>]+> f3e0 8120   mrs     r1, R8_usr
+0[0-9a-f]+ <[^>]+> f3e1 8120   mrs     r1, R9_usr
+0[0-9a-f]+ <[^>]+> f3e2 8120   mrs     r1, R10_usr
+0[0-9a-f]+ <[^>]+> f3e3 8120   mrs     r1, R11_usr
+0[0-9a-f]+ <[^>]+> f3e4 8120   mrs     r1, R12_usr
+0[0-9a-f]+ <[^>]+> f3e5 8120   mrs     r1, SP_usr
+0[0-9a-f]+ <[^>]+> f3e6 8120   mrs     r1, LR_usr
+0[0-9a-f]+ <[^>]+> f3e8 8120   mrs     r1, R8_fiq
+0[0-9a-f]+ <[^>]+> f3e9 8120   mrs     r1, R9_fiq
+0[0-9a-f]+ <[^>]+> f3ea 8120   mrs     r1, R10_fiq
+0[0-9a-f]+ <[^>]+> f3eb 8120   mrs     r1, R11_fiq
+0[0-9a-f]+ <[^>]+> f3ec 8120   mrs     r1, R12_fiq
+0[0-9a-f]+ <[^>]+> f3ed 8120   mrs     r1, SP_fiq
+0[0-9a-f]+ <[^>]+> f3ee 8120   mrs     r1, LR_fiq
+0[0-9a-f]+ <[^>]+> f3fe 8120   mrs     r1, SPSR_fiq
+0[0-9a-f]+ <[^>]+> f3e1 8130   mrs     r1, SP_irq
+0[0-9a-f]+ <[^>]+> f3e0 8130   mrs     r1, LR_irq
+0[0-9a-f]+ <[^>]+> f3f0 8130   mrs     r1, SPSR_irq
+0[0-9a-f]+ <[^>]+> f3e3 8130   mrs     r1, SP_svc
+0[0-9a-f]+ <[^>]+> f3e2 8130   mrs     r1, LR_svc
+0[0-9a-f]+ <[^>]+> f3f2 8130   mrs     r1, SPSR_svc
+0[0-9a-f]+ <[^>]+> f3e5 8130   mrs     r1, SP_abt
+0[0-9a-f]+ <[^>]+> f3e4 8130   mrs     r1, LR_abt
+0[0-9a-f]+ <[^>]+> f3f4 8130   mrs     r1, SPSR_abt
+0[0-9a-f]+ <[^>]+> f3e7 8130   mrs     r1, SP_und
+0[0-9a-f]+ <[^>]+> f3e6 8130   mrs     r1, LR_und
+0[0-9a-f]+ <[^>]+> f3f6 8130   mrs     r1, SPSR_und
+0[0-9a-f]+ <[^>]+> f3ed 8130   mrs     r1, SP_mon
+0[0-9a-f]+ <[^>]+> f3ec 8130   mrs     r1, LR_mon
+0[0-9a-f]+ <[^>]+> f3fc 8130   mrs     r1, SPSR_mon
+0[0-9a-f]+ <[^>]+> f3ef 8130   mrs     r1, SP_hyp
+0[0-9a-f]+ <[^>]+> f3ee 8130   mrs     r1, ELR_hyp
+0[0-9a-f]+ <[^>]+> f3fe 8130   mrs     r1, SPSR_hyp
+0[0-9a-f]+ <[^>]+> f381 8020   msr     R8_usr, r1
+0[0-9a-f]+ <[^>]+> f381 8120   msr     R9_usr, r1
+0[0-9a-f]+ <[^>]+> f381 8220   msr     R10_usr, r1
+0[0-9a-f]+ <[^>]+> f381 8320   msr     R11_usr, r1
+0[0-9a-f]+ <[^>]+> f381 8420   msr     R12_usr, r1
+0[0-9a-f]+ <[^>]+> f381 8520   msr     SP_usr, r1
+0[0-9a-f]+ <[^>]+> f381 8620   msr     LR_usr, r1
+0[0-9a-f]+ <[^>]+> f381 8820   msr     R8_fiq, r1
+0[0-9a-f]+ <[^>]+> f381 8920   msr     R9_fiq, r1
+0[0-9a-f]+ <[^>]+> f381 8a20   msr     R10_fiq, r1
+0[0-9a-f]+ <[^>]+> f381 8b20   msr     R11_fiq, r1
+0[0-9a-f]+ <[^>]+> f381 8c20   msr     R12_fiq, r1
+0[0-9a-f]+ <[^>]+> f381 8d20   msr     SP_fiq, r1
+0[0-9a-f]+ <[^>]+> f381 8e20   msr     LR_fiq, r1
+0[0-9a-f]+ <[^>]+> f391 8e20   msr     SPSR_fiq, r1
+0[0-9a-f]+ <[^>]+> f381 8130   msr     SP_irq, r1
+0[0-9a-f]+ <[^>]+> f381 8030   msr     LR_irq, r1
+0[0-9a-f]+ <[^>]+> f391 8030   msr     SPSR_irq, r1
+0[0-9a-f]+ <[^>]+> f381 8330   msr     SP_svc, r1
+0[0-9a-f]+ <[^>]+> f381 8230   msr     LR_svc, r1
+0[0-9a-f]+ <[^>]+> f391 8230   msr     SPSR_svc, r1
+0[0-9a-f]+ <[^>]+> f381 8530   msr     SP_abt, r1
+0[0-9a-f]+ <[^>]+> f381 8430   msr     LR_abt, r1
+0[0-9a-f]+ <[^>]+> f391 8430   msr     SPSR_abt, r1
+0[0-9a-f]+ <[^>]+> f381 8730   msr     SP_und, r1
+0[0-9a-f]+ <[^>]+> f381 8630   msr     LR_und, r1
+0[0-9a-f]+ <[^>]+> f391 8630   msr     SPSR_und, r1
+0[0-9a-f]+ <[^>]+> f381 8d30   msr     SP_mon, r1
+0[0-9a-f]+ <[^>]+> f381 8c30   msr     LR_mon, r1
+0[0-9a-f]+ <[^>]+> f391 8c30   msr     SPSR_mon, r1
+0[0-9a-f]+ <[^>]+> f381 8f30   msr     SP_hyp, r1
+0[0-9a-f]+ <[^>]+> f381 8e30   msr     ELR_hyp, r1
+0[0-9a-f]+ <[^>]+> f391 8e30   msr     SPSR_hyp, r1
diff --git a/gas/testsuite/gas/arm/armv7-a+virt.s b/gas/testsuite/gas/arm/armv7-a+virt.s
new file mode 100644 (file)
index 0000000..354b8bc
--- /dev/null
@@ -0,0 +1,146 @@
+       .text
+       .syntax unified
+       .arm
+foo:
+       hvc 0x0000
+       hvc 0xffff
+       eret
+       mrs r1, R8_usr
+       mrs r1, R9_usr
+       mrs r1, R10_usr
+       mrs r1, R11_usr
+       mrs r1, R12_usr
+       mrs r1, SP_usr
+       mrs r1, LR_usr
+       mrs r1, R8_fiq
+       mrs r1, R9_fiq
+       mrs r1, R10_fiq
+       mrs r1, R11_fiq
+       mrs r1, R12_fiq
+       mrs r1, SP_fiq
+       mrs r1, LR_fiq
+       mrs r1, SPSR_fiq
+       mrs r1, SP_irq
+       mrs r1, LR_irq
+       mrs r1, SPSR_irq
+       mrs r1, SP_svc
+       mrs r1, LR_svc
+       mrs r1, SPSR_svc
+       mrs r1, SP_abt
+       mrs r1, LR_abt
+       mrs r1, SPSR_abt
+       mrs r1, SP_und
+       mrs r1, LR_und
+       mrs r1, SPSR_und
+       mrs r1, SP_mon
+       mrs r1, LR_mon
+       mrs r1, SPSR_mon
+       mrs r1, SP_hyp
+       mrs r1, ELR_hyp
+       mrs r1, SPSR_hyp
+       msr R8_usr, r1
+       msr R9_usr, r1
+       msr R10_usr, r1
+       msr R11_usr, r1
+       msr R12_usr, r1
+       msr SP_usr, r1
+       msr LR_usr, r1
+       msr R8_fiq, r1
+       msr R9_fiq, r1
+       msr R10_fiq, r1
+       msr R11_fiq, r1
+       msr R12_fiq, r1
+       msr SP_fiq, r1
+       msr LR_fiq, r1
+       msr SPSR_fiq, r1
+       msr SP_irq, r1
+       msr LR_irq, r1
+       msr SPSR_irq, r1
+       msr SP_svc, r1
+       msr LR_svc, r1
+       msr SPSR_svc, r1
+       msr SP_abt, r1
+       msr LR_abt, r1
+       msr SPSR_abt, r1
+       msr SP_und, r1
+       msr LR_und, r1
+       msr SPSR_und, r1
+       msr SP_mon, r1
+       msr LR_mon, r1
+       msr SPSR_mon, r1
+       msr SP_hyp, r1
+       msr ELR_hyp, r1
+       msr SPSR_hyp, r1
+
+       .thumb
+bar:
+       hvc 0x0000
+       hvc 0xffff
+       eret
+       mrs r1, R8_usr
+       mrs r1, R9_usr
+       mrs r1, R10_usr
+       mrs r1, R11_usr
+       mrs r1, R12_usr
+       mrs r1, SP_usr
+       mrs r1, LR_usr
+       mrs r1, R8_fiq
+       mrs r1, R9_fiq
+       mrs r1, R10_fiq
+       mrs r1, R11_fiq
+       mrs r1, R12_fiq
+       mrs r1, SP_fiq
+       mrs r1, LR_fiq
+       mrs r1, SPSR_fiq
+       mrs r1, SP_irq
+       mrs r1, LR_irq
+       mrs r1, SPSR_irq
+       mrs r1, SP_svc
+       mrs r1, LR_svc
+       mrs r1, SPSR_svc
+       mrs r1, SP_abt
+       mrs r1, LR_abt
+       mrs r1, SPSR_abt
+       mrs r1, SP_und
+       mrs r1, LR_und
+       mrs r1, SPSR_und
+       mrs r1, SP_mon
+       mrs r1, LR_mon
+       mrs r1, SPSR_mon
+       mrs r1, SP_hyp
+       mrs r1, ELR_hyp
+       mrs r1, SPSR_hyp
+       msr R8_usr, r1
+       msr R9_usr, r1
+       msr R10_usr, r1
+       msr R11_usr, r1
+       msr R12_usr, r1
+       msr SP_usr, r1
+       msr LR_usr, r1
+       msr R8_fiq, r1
+       msr R9_fiq, r1
+       msr R10_fiq, r1
+       msr R11_fiq, r1
+       msr R12_fiq, r1
+       msr SP_fiq, r1
+       msr LR_fiq, r1
+       msr SPSR_fiq, r1
+       msr SP_irq, r1
+       msr LR_irq, r1
+       msr SPSR_irq, r1
+       msr SP_svc, r1
+       msr LR_svc, r1
+       msr SPSR_svc, r1
+       msr SP_abt, r1
+       msr LR_abt, r1
+       msr SPSR_abt, r1
+       msr SP_und, r1
+       msr LR_und, r1
+       msr SPSR_und, r1
+       msr SP_mon, r1
+       msr LR_mon, r1
+       msr SPSR_mon, r1
+       msr SP_hyp, r1
+       msr ELR_hyp, r1
+       msr SPSR_hyp, r1
+
index a976d04b8ff49b04d8d7ba0ed13ab66bcab7382f..e56f3173c5608a256e013946b809497b9acaf36f 100644 (file)
@@ -14,4 +14,4 @@ File Attributes
   Tag_THUMB_ISA_use: Thumb-2
   Tag_MPextension_use: Allowed
   Tag_DIV_use: Allowed in v7-A with integer division extension
-  Tag_Virtualization_use: TrustZone
+  Tag_Virtualization_use: TrustZone and Virtualization Extensions
diff --git a/gas/testsuite/gas/arm/attr-march-armv7-a+sec+virt.d b/gas/testsuite/gas/arm/attr-march-armv7-a+sec+virt.d
new file mode 100644 (file)
index 0000000..c51e093
--- /dev/null
@@ -0,0 +1,16 @@
+# name: attributes for -march=armv7-a+sec+virt
+# source: blank.s
+# as: -march=armv7-a+sec+virt
+# readelf: -A
+# This test is only valid on EABI based ports.
+# target: *-*-*eabi
+
+Attribute Section: aeabi
+File Attributes
+  Tag_CPU_name: "7-A"
+  Tag_CPU_arch: v7
+  Tag_CPU_arch_profile: Application
+  Tag_ARM_ISA_use: Yes
+  Tag_THUMB_ISA_use: Thumb-2
+  Tag_DIV_use: Allowed in v7-A with integer division extension
+  Tag_Virtualization_use: TrustZone and Virtualization Extensions
diff --git a/gas/testsuite/gas/arm/attr-march-armv7-a+virt.d b/gas/testsuite/gas/arm/attr-march-armv7-a+virt.d
new file mode 100644 (file)
index 0000000..9329bc1
--- /dev/null
@@ -0,0 +1,16 @@
+# name: attributes for -march=armv7-a+virt
+# source: blank.s
+# as: -march=armv7-a+virt
+# readelf: -A
+# This test is only valid on EABI based ports.
+# target: *-*-*eabi
+
+Attribute Section: aeabi
+File Attributes
+  Tag_CPU_name: "7-A"
+  Tag_CPU_arch: v7
+  Tag_CPU_arch_profile: Application
+  Tag_ARM_ISA_use: Yes
+  Tag_THUMB_ISA_use: Thumb-2
+  Tag_DIV_use: Allowed in v7-A with integer division extension
+  Tag_Virtualization_use: Virtualization Extensions
index 135a28fac4f5d17c29b2b07d7e5b59222187c140..a53a246c58ee9129b9ebeb6eea949594f26cfa96 100644 (file)
@@ -1,3 +1,10 @@
+2010-09-23  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
+
+       * arm.h (ARM_EXT_VIRT): New define.
+       (ARM_ARCH_V7A_IDIV_MP_SEC): Rename...
+       (ARM_ARCH_V7A_IDIV_MP_SEC_VIRT): ...to this and include Virtualization
+       Extensions.
+
 2010-09-23  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
        
        * arm.h (ARM_AEXT_ADIV): New define.
index 58cace8a35b3d2d3e707b53230bd0c66b590129f..0bfd3028842af5133564f2dcce0fa06f7a7e71a1 100644 (file)
@@ -54,6 +54,7 @@
 #define ARM_EXT_OS      0x20000000     /* OS Extensions.  */
 #define ARM_EXT_ADIV    0x40000000     /* Integer divide extensions in ARM 
                                           state.  */
+#define ARM_EXT_VIRT    0x80000000     /* Virtualization extensions.  */
 
 /* Co-processor space extensions.  */
 #define ARM_CEXT_XSCALE   0x00000001   /* Allow MIA etc.          */
 #define ARM_ARCH_V7A_MP_SEC \
                        ARM_FEATURE (ARM_AEXT_V7A | ARM_EXT_MP | ARM_EXT_SEC, \
                                     0)
-/* v7-a+idiv+mp+sec.  */
-#define ARM_ARCH_V7A_IDIV_MP_SEC \
+/* v7-a+idiv+mp+sec+virt.  */
+#define ARM_ARCH_V7A_IDIV_MP_SEC_VIRT \
                        ARM_FEATURE (ARM_AEXT_V7A | ARM_EXT_MP | ARM_EXT_SEC \
-                                    | ARM_EXT_DIV | ARM_EXT_ADIV, 0)
+                                    | ARM_EXT_DIV | ARM_EXT_ADIV \
+                                    | ARM_EXT_VIRT, 0)
 
 /* There are too many feature bits to fit in a single word, so use a
    structure.  For simplicity we put all core features in one word and
index fb6b01a6aa2fcb7b3d7bce2dafd3152da51760e5..8a23f7ec06b5b0863144200f6bbc394e805dc119 100644 (file)
@@ -1,3 +1,11 @@
+2010-09-23  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
+
+       * arm-dis.c (arm_opcodes): Add Virtualiztion Extensions support.
+       (thumb32_opcodes): Likewise.
+       (banked_regname): New function.
+       (print_insn_arm): Add Virtualization Extensions support.
+       (print_insn_thumb32): Likewise.
+
 2010-09-23  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
 
        * arm-dis.c (arm_opcodes): Support disassembly of UDIV and SDIV in
index 005c957aa0ce51595a3f8beed1652b0ca50a40cb..3dfbf5c5415e7219b4f31a78ff8842f9bbd14304 100644 (file)
@@ -816,7 +816,8 @@ static const struct opcode32 neon_opcodes[] =
 
    %e                   print arm SMI operand (bits 0..7,8..19).
    %E                  print the LSB and WIDTH fields of a BFI or BFC instruction.
-   %V                   print the 16-bit immediate field of a MOVT or MOVW instruction.  */
+   %V                   print the 16-bit immediate field of a MOVT or MOVW instruction.
+   %R                  print the SPSR/CPSR or banked register of an MRS.  */
 
 static const struct opcode32 arm_opcodes[] =
 {
@@ -829,6 +830,10 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
   {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
 
+  /* Virtualization Extension instructions.  */
+  {ARM_EXT_VIRT, 0x0160006e, 0x0fffffff, "eret%c"},
+  {ARM_EXT_VIRT, 0x01400070, 0x0ff000f0, "hvc%c\t%e"},
+
   /* Integer Divide Extension instructions.  */
   {ARM_EXT_ADIV, 0x0710f010, 0x0ff0f0f0, "sdiv%c\t%16-19r, %0-3r, %8-11r"},
   {ARM_EXT_ADIV, 0x0730f010, 0x0ff0f0f0, "udiv%c\t%16-19r, %0-3r, %8-11r"},
@@ -1091,8 +1096,9 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_EXT_V1, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
   {ARM_EXT_V1, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15R, %16-19R, %o"},
 
-  {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
-  {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15R, %22?SCPSR"},
+  {ARM_EXT_VIRT, 0x0120f200, 0x0fb0f200, "msr%c\t%C, %0-3r"},
+  {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%C, %o"},
+  {ARM_EXT_V3, 0x01000000, 0x0fb00cff, "mrs%c\t%12-15R, %R"},
 
   {ARM_EXT_V1, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
   {ARM_EXT_V1, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
@@ -1103,7 +1109,6 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_EXT_V1, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19R, %o"},
 
   {ARM_EXT_V1, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
-  {ARM_EXT_V3, 0x01400000, 0x0ff00010, "mrs%c\t%12-15R, %22?SCPSR"},
   {ARM_EXT_V1, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
   {ARM_EXT_V1, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19R, %o"},
 
@@ -1313,6 +1318,7 @@ static const struct opcode16 thumb_opcodes[] =
        %M              print a modified 12-bit immediate (same location)
        %J              print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
        %K              print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
+       %H              print a 16-bit immediate from hw2[3:0],hw1[11:0]
        %S              print a possibly-shifted Rm
 
        %a              print the address of a plain load/store
@@ -1360,6 +1366,10 @@ static const struct opcode32 thumb32_opcodes[] =
   {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
   {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
 
+  /* Virtualization Extension instructions.  */
+  {ARM_EXT_VIRT, 0xf7e08000, 0xfff0f000, "hvc%c\t%V"},
+  /* We skip ERET as that is SUBS pc, lr, #0.  */
+
   /* MP Extension instructions.  */
   {ARM_EXT_MP,   0xf830f000, 0xff70f000, "pldw%c\t%a"},
 
@@ -1380,7 +1390,7 @@ static const struct opcode32 thumb32_opcodes[] =
   {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
   {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
   {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
-  {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
+  {ARM_EXT_V6T2, 0xf3e08000, 0xffe0f000, "mrs%c\t%8-11r, %D"},
   {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
   {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
   {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
@@ -2862,6 +2872,52 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
   return FALSE;
 }
 
+/* Return the name of a v7A special register.  */
+
+static const char * 
+banked_regname (unsigned reg)
+{
+  switch (reg)
+    {
+      case 15: return "CPSR";
+      case 32: return "R8_usr"; 
+      case 33: return "R9_usr";
+      case 34: return "R10_usr";
+      case 35: return "R11_usr";
+      case 36: return "R12_usr";
+      case 37: return "SP_usr";
+      case 38: return "LR_usr";
+      case 40: return "R8_fiq"; 
+      case 41: return "R9_fiq";
+      case 42: return "R10_fiq";
+      case 43: return "R11_fiq";
+      case 44: return "R12_fiq";
+      case 45: return "SP_fiq";
+      case 46: return "LR_fiq";
+      case 48: return "LR_irq";
+      case 49: return "SP_irq";
+      case 50: return "LR_svc";
+      case 51: return "SP_svc";
+      case 52: return "LR_abt";
+      case 53: return "SP_abt";
+      case 54: return "LR_und";
+      case 55: return "SP_und";
+      case 60: return "LR_mon";
+      case 61: return "SP_mon";
+      case 62: return "ELR_hyp";
+      case 63: return "SP_hyp";
+      case 79: return "SPSR";
+      case 110: return "SPSR_fiq";
+      case 112: return "SPSR_irq";
+      case 114: return "SPSR_svc";
+      case 116: return "SPSR_abt";
+      case 118: return "SPSR_und";
+      case 124: return "SPSR_mon";
+      case 126: return "SPSR_hyp";
+      default: return NULL;
+    }
+}
+
 /* Print one ARM instruction from PC on INFO->STREAM.  */
 
 static void
@@ -3156,15 +3212,32 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                      break;
 
                    case 'C':
-                     func (stream, "_");
-                     if (given & 0x80000)
-                       func (stream, "f");
-                     if (given & 0x40000)
-                       func (stream, "s");
-                     if (given & 0x20000)
-                       func (stream, "x");
-                     if (given & 0x10000)
-                       func (stream, "c");
+                     if ((given & 0x02000200) == 0x200)
+                       {
+                         const char * name;
+                         unsigned sysm = (given & 0x004f0000) >> 16;
+
+                         sysm |= (given & 0x300) >> 4;
+                         name = banked_regname (sysm);
+
+                         if (name != NULL)
+                           func (stream, "%s", name);
+                         else
+                           func (stream, "(UNDEF: %lu)", sysm);
+                       }
+                     else
+                       {
+                         func (stream, "%cPSR_", 
+                               (given & 0x00400000) ? 'S' : 'C');
+                         if (given & 0x80000)
+                           func (stream, "f");
+                         if (given & 0x40000)
+                           func (stream, "s");
+                         if (given & 0x20000)
+                           func (stream, "x");
+                         if (given & 0x10000)
+                           func (stream, "c");
+                       }
                      break;
 
                    case 'U':
@@ -3302,6 +3375,22 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                        }
                        break;
 
+                     case 'R':
+                       /* Get the PSR/banked register name.  */
+                       {
+                         const char * name;
+                         unsigned sysm = (given & 0x004f0000) >> 16;
+
+                         sysm |= (given & 0x300) >> 4;
+                         name = banked_regname (sysm);
+
+                         if (name != NULL)
+                           func (stream, "%s", name);
+                         else
+                           func (stream, "(UNDEF: %lu)", sysm);
+                       }
+                       break;
+
                      case 'V':
                        /* 16-bit unsigned immediate from a MOVT or MOVW
                           instruction, encoded in bits 0:11 and 15:19.  */
@@ -3746,6 +3835,17 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                }
                break;
 
+             case 'V':
+               {
+                 unsigned int imm = 0;
+
+                 imm |= (given & 0x00000fffu);
+                 imm |= (given & 0x000f0000u) >> 4;
+                 func (stream, "#%u", imm);
+                 value_in_comment = imm;
+               }
+               break;
+
              case 'S':
                {
                  unsigned int reg = (given & 0x0000000fu);
@@ -4070,6 +4170,20 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                    if (given & 0x100)
                      func (stream, "c");
                  }
+               else if ((given & 0x20) == 0x20)
+                 {
+                   char const* name;
+                   unsigned sysm = (given & 0xf00) >> 8;
+
+                   sysm |= (given & 0x30);
+                   sysm |= (given & 0x00100000) >> 14;
+                   name = banked_regname (sysm);
+                   
+                   if (name != NULL)
+                     func (stream, "%s", name);
+                   else
+                     func (stream, "(UNDEF: %lu)", sysm);
+                 }
                else
                  {
                    func (stream, psr_name (given & 0xff));
@@ -4077,8 +4191,21 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                break;
 
              case 'D':
-               if ((given & 0xff) == 0)
-                 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
+               if (((given & 0xff) == 0)
+                   || ((given & 0x20) == 0x20))
+                 {
+                   char const* name;
+                   unsigned sm = (given & 0xf0000) >> 16;
+
+                   sm |= (given & 0x30);
+                   sm |= (given & 0x00100000) >> 14;
+                   name = banked_regname (sm);
+
+                   if (name != NULL)
+                     func (stream, "%s", name);
+                   else
+                     func (stream, "(UNDEF: %lu)", sm);
+                 }
                else
                  func (stream, psr_name (given & 0xff));
                break;