From 90ec0d684e3555429768fd2a8ce1d396b4bacbb9 Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Thu, 23 Sep 2010 15:52:19 +0000 Subject: [PATCH] * bfd/bfd-in2.h (BFD_RELOC_ARM_HVC): New enum value. * 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. --- bfd/ChangeLog | 4 + bfd/bfd-in2.h | 1 + gas/ChangeLog | 22 +++ gas/config/tc-arm.c | 183 +++++++++++++++--- gas/doc/c-arm.texi | 2 + gas/testsuite/ChangeLog | 8 + gas/testsuite/gas/arm/armv7-a+virt.d | 145 ++++++++++++++ gas/testsuite/gas/arm/armv7-a+virt.s | 146 ++++++++++++++ gas/testsuite/gas/arm/attr-march-all.d | 2 +- .../gas/arm/attr-march-armv7-a+sec+virt.d | 16 ++ .../gas/arm/attr-march-armv7-a+virt.d | 16 ++ include/opcode/ChangeLog | 7 + include/opcode/arm.h | 8 +- opcodes/ChangeLog | 8 + opcodes/arm-dis.c | 159 +++++++++++++-- 15 files changed, 676 insertions(+), 51 deletions(-) create mode 100644 gas/testsuite/gas/arm/armv7-a+virt.d create mode 100644 gas/testsuite/gas/arm/armv7-a+virt.s create mode 100644 gas/testsuite/gas/arm/attr-march-armv7-a+sec+virt.d create mode 100644 gas/testsuite/gas/arm/attr-march-armv7-a+virt.d diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 2fe58b221e..c31a1ebdc9 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,7 @@ +2010-09-23 Matthew Gretton-Dann + + * bfd-in2.h (BFD_RELOC_ARM_HVC): New enum value. + 2010-09-23 Alan Modra * 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 0e7b337f77..4bd47caeb8 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 d4d1e5c9f3..2f1685a329 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,25 @@ +2010-09-23 Matthew Gretton-Dann + + * 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 * config/tc-arm.c (arm_ext_adiv): New variable. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 886d92fa9c..e4bd9f1704 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: @@ -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. */ diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi index 2a5c351ddd..d3cccf4a49 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 37f84172e3..038c561577 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2010-09-23 Matthew Gretton-Dann + + * 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 * 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 index 0000000000..1e3224ceca --- /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 0000000000..354b8bc020 --- /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 a976d04b8f..e56f3173c5 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 0000000000..c51e093368 --- /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 0000000000..9329bc1514 --- /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 135a28fac4..a53a246c58 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,10 @@ +2010-09-23 Matthew Gretton-Dann + + * 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 * arm.h (ARM_AEXT_ADIV): New define. diff --git a/include/opcode/arm.h b/include/opcode/arm.h index 58cace8a35..0bfd302884 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 fb6b01a6aa..8a23f7ec06 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,11 @@ +2010-09-23 Matthew Gretton-Dann + + * 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 * arm-dis.c (arm_opcodes): Support disassembly of UDIV and SDIV in diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 005c957aa0..3dfbf5c541 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; -- 2.34.1