aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog4
-rw-r--r--bfd/bfd-in2.h1
-rw-r--r--gas/ChangeLog22
-rw-r--r--gas/config/tc-arm.c183
-rw-r--r--gas/doc/c-arm.texi2
-rw-r--r--gas/testsuite/ChangeLog8
-rw-r--r--gas/testsuite/gas/arm/armv7-a+virt.d145
-rw-r--r--gas/testsuite/gas/arm/armv7-a+virt.s146
-rw-r--r--gas/testsuite/gas/arm/attr-march-all.d2
-rw-r--r--gas/testsuite/gas/arm/attr-march-armv7-a+sec+virt.d16
-rw-r--r--gas/testsuite/gas/arm/attr-march-armv7-a+virt.d16
-rw-r--r--include/opcode/ChangeLog7
-rw-r--r--include/opcode/arm.h8
-rw-r--r--opcodes/ChangeLog8
-rw-r--r--opcodes/arm-dis.c159
15 files changed, 676 insertions, 51 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 2fe58b2..c31a1eb 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 0e7b337..4bd47ca 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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,
diff --git a/gas/ChangeLog b/gas/ChangeLog
index d4d1e5c..2f1685a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,27 @@
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.
(do_div): New function.
(insns): Accept UDIV and SDIV in ARM state.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 886d92f..e4bd9f1 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -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:
@@ -8122,6 +8147,13 @@ do_smc (void)
}
static void
+do_hvc (void)
+{
+ inst.reloc.type = BFD_RELOC_ARM_HVC;
+ inst.reloc.pc_rel = 0;
+}
+
+static void
do_swi (void)
{
inst.reloc.type = BFD_RELOC_ARM_SWI;
@@ -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;
}
@@ -11390,6 +11442,16 @@ do_t_smc (void)
}
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)
{
unsigned Rd, Rn;
@@ -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. */
diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi
index 2a5c351..d3cccf4 100644
--- a/gas/doc/c-arm.texi
+++ b/gas/doc/c-arm.texi
@@ -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}.
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 37f8417..038c561 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,5 +1,13 @@
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.
* gas/arm/armv7-a+idiv.s: Likewise.
* gas/arm/attr-march-all.d: Update for Integer divide extension.
diff --git a/gas/testsuite/gas/arm/armv7-a+virt.d b/gas/testsuite/gas/arm/armv7-a+virt.d
new file mode 100644
index 0000000..1e3224c
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv7-a+virt.d
@@ -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
index 0000000..354b8bc
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv7-a+virt.s
@@ -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
+
diff --git a/gas/testsuite/gas/arm/attr-march-all.d b/gas/testsuite/gas/arm/attr-march-all.d
index a976d04..e56f317 100644
--- a/gas/testsuite/gas/arm/attr-march-all.d
+++ b/gas/testsuite/gas/arm/attr-march-all.d
@@ -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
index 0000000..c51e093
--- /dev/null
+++ b/gas/testsuite/gas/arm/attr-march-armv7-a+sec+virt.d
@@ -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
index 0000000..9329bc1
--- /dev/null
+++ b/gas/testsuite/gas/arm/attr-march-armv7-a+virt.d
@@ -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
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
index 135a28f..a53a246 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -1,4 +1,11 @@
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.
(ARM_ARCH_V7A_IDIV_MP_SEC): Likewise.
diff --git a/include/opcode/arm.h b/include/opcode/arm.h
index 58cace8..0bfd302 100644
--- a/include/opcode/arm.h
+++ b/include/opcode/arm.h
@@ -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. */
@@ -222,10 +223,11 @@
#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
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index fb6b01a..8a23f7e 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,13 @@
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
ARM state.
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 005c957..3dfbf5c 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -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;