diff options
author | Matthew Gretton-Dann <matthew.gretton-dann@arm.com> | 2010-09-23 15:52:19 +0000 |
---|---|---|
committer | Matthew Gretton-Dann <matthew.gretton-dann@arm.com> | 2010-09-23 15:52:19 +0000 |
commit | 90ec0d684e3555429768fd2a8ce1d396b4bacbb9 (patch) | |
tree | 7891120464fdb272d19f0e9d0aff8b23b24da9c5 /opcodes | |
parent | eea54501f730cf7697d5bce04f634c95a236bfdd (diff) | |
download | gdb-90ec0d684e3555429768fd2a8ce1d396b4bacbb9.zip gdb-90ec0d684e3555429768fd2a8ce1d396b4bacbb9.tar.gz gdb-90ec0d684e3555429768fd2a8ce1d396b4bacbb9.tar.bz2 |
* 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.
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/ChangeLog | 8 | ||||
-rw-r--r-- | opcodes/arm-dis.c | 159 |
2 files changed, 151 insertions, 16 deletions
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; |