diff options
author | Paul Brook <paul@codesourcery.com> | 2006-02-24 15:36:36 +0000 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2006-02-24 15:36:36 +0000 |
commit | 804f24bbeb39407b12bad6944b5c1ca3dc8cede4 (patch) | |
tree | fb7ffa4f2390ade25e109f2df26036121531d830 /opcodes | |
parent | 5f8fec255f2ebe427c279e3546f5faf00d79fd65 (diff) | |
download | gdb-804f24bbeb39407b12bad6944b5c1ca3dc8cede4.tar.gz |
2006-02-24 Paul Brook <paul@codesourcery.com>
gas/
* config/arm/tc-arm.c (arm_ext_v6_notm, arm_ext_div, arm_ext_v7,
arm_ext_v7a, arm_ext_v7r, arm_ext_v7m): New variables.
(struct asm_barrier_opt): Define.
(arm_v7m_psr_hsh, arm_barrier_opt_hsh): New variables.
(parse_psr): Accept V7M psr names.
(parse_barrier): New function.
(enum operand_parse_code): Add OP_oBARRIER.
(parse_operands): Implement OP_oBARRIER.
(do_barrier): New function.
(do_dbg, do_pli, do_t_barrier, do_t_dbg, do_t_div): New functions.
(do_t_cpsi): Add V7M restrictions.
(do_t_mrs, do_t_msr): Validate V7M variants.
(md_assemble): Check for NULL variants.
(v7m_psrs, barrier_opt_names): New tables.
(insns): Add V7 instructions. Mark V6 instructions absent from V7M.
(md_begin): Initialize arm_v7m_psr_hsh and arm_barrier_opt_hsh.
(arm_cpu_option_table): Add Cortex-M3, R4 and A8.
(arm_arch_option_table): Add armv7, armv7a, armv7r and armv7m.
(struct cpu_arch_ver_table): Define.
(cpu_arch_ver): New.
(aeabi_set_public_attributes): Use cpu_arch_ver. Set
Tag_CPU_arch_profile.
* doc/c-arm.texi: Document new cpu and arch options.
gas/testsuite/
* gas/arm/thumb32.d: Fix expected msr and mrs output.
* gas/arm/arch7.d: New test.
* gas/arm/arch7.s: New test.
* gas/arm/arch7m-bad.l: New test.
* gas/arm/arch7m-bad.d: New test.
* gas/arm/arch7m-bad.s: New test.
include/opcode/
* arm.h: Add V7 feature bits.
opcodes/
* arm-dis.c (arm_opcodes): Add V7 instructions.
(thumb32_opcodes): Ditto. Handle V7M MSR/MRS variants.
(print_arm_address): New function.
(print_insn_arm): Use it. Add 'P' and 'U' cases.
(psr_name): New function.
(print_insn_thumb32): Add 'U', 'C' and 'D' cases.
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/ChangeLog | 9 | ||||
-rw-r--r-- | opcodes/arm-dis.c | 277 |
2 files changed, 203 insertions, 83 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index a8960dbaa61..6aad1942616 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,12 @@ +2006-02-24 Paul Brook <paul@codesourcery.com> + + * arm-dis.c (arm_opcodes): Add V7 instructions. + (thumb32_opcodes): Ditto. Handle V7M MSR/MRS variants. + (print_arm_address): New function. + (print_insn_arm): Use it. Add 'P' and 'U' cases. + (psr_name): New function. + (print_insn_thumb32): Add 'U', 'C' and 'D' cases. + 2006-02-23 H.J. Lu <hongjiu.lu@intel.com> * ia64-opc-i.c (bXc): New. diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index fb3cb77bc4a..b5167e9b6f2 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -402,6 +402,8 @@ static const struct opcode32 coprocessor_opcodes[] = %t print 't' iff bit 21 set and bit 24 clear %B print arm BLX(1) destination %C print the PSR sub type. + %U print barrier type. + %P print address for pli instruction. %<bitfield>r print as an ARM register %<bitfield>d print the bitfield in decimal @@ -428,6 +430,13 @@ static const struct opcode32 arm_opcodes[] = {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, + /* V7 instructions. */ + {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"}, + {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"}, + {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"}, + {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"}, + {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"}, + /* ARM V6T2 instructions. */ {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"}, {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"}, @@ -827,6 +836,8 @@ static const struct opcode16 thumb_opcodes[] = %B print an unconditional branch offset %s print the shift field of an SSAT instruction %R print the rotation field of an SXT instruction + %U print barrier type. + %P print address for pli instruction. %<bitfield>d print bitfield in decimal %<bitfield>W print bitfield*4 in decimal @@ -847,6 +858,15 @@ static const struct opcode16 thumb_opcodes[] = makes heavy use of special-case bit patterns. */ static const struct opcode32 thumb32_opcodes[] = { + /* V7 instructions. */ + {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli\t%a"}, + {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg\t#%0-3d"}, + {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb\t%U"}, + {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb\t%U"}, + {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb\t%U"}, + {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv\t%8-11r, %16-19r, %0-3r"}, + {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv\t%8-11r, %16-19r, %0-3r"}, + /* Instructions defined in the basic V6T2 set. */ {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop.w"}, {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield.w"}, @@ -861,14 +881,14 @@ static const struct opcode32 thumb32_opcodes[] = {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj\t%16-19r"}, {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb\t%16-19r%21'!"}, {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia\t%16-19r%21'!"}, - {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff0ff, "mrs\t%8-11r, %20?CSPSR"}, + {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs\t%8-11r, %D"}, {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d"}, {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb\t[%16-19r, %0-3r]"}, {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh\t[%16-19r, %0-3r, lsl #1]"}, {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d"}, {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d"}, {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs\tpc, lr, #%0-7d"}, - {ARM_EXT_V6T2, 0xf3808000, 0xffe0f0ff, "msr\t%20?CSPSR_%8'c%9'x%10's%11'f, %16-19r"}, + {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr\t%C, %16-19r"}, {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex\t%12-15r, [%16-19r]"}, {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb\t%12-15r, [%16-19r]"}, {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb\t#%0-4d%21'!"}, @@ -1602,6 +1622,96 @@ print_insn_coprocessor (struct disassemble_info *info, long given, return FALSE; } +static void +print_arm_address (bfd_vma pc, struct disassemble_info *info, long given) +{ + void *stream = info->stream; + fprintf_ftype func = info->fprintf_func; + + if (((given & 0x000f0000) == 0x000f0000) + && ((given & 0x02000000) == 0)) + { + int offset = given & 0xfff; + + func (stream, "[pc"); + + if (given & 0x01000000) + { + if ((given & 0x00800000) == 0) + offset = - offset; + + /* Pre-indexed. */ + func (stream, ", #%d]", offset); + + offset += pc + 8; + + /* Cope with the possibility of write-back + being used. Probably a very dangerous thing + for the programmer to do, but who are we to + argue ? */ + if (given & 0x00200000) + func (stream, "!"); + } + else + { + /* Post indexed. */ + func (stream, "], #%d", offset); + + /* ie ignore the offset. */ + offset = pc + 8; + } + + func (stream, "\t; "); + info->print_address_func (offset, info); + } + else + { + func (stream, "[%s", + arm_regnames[(given >> 16) & 0xf]); + if ((given & 0x01000000) != 0) + { + if ((given & 0x02000000) == 0) + { + int offset = given & 0xfff; + if (offset) + func (stream, ", #%s%d", + (((given & 0x00800000) == 0) + ? "-" : ""), offset); + } + else + { + func (stream, ", %s", + (((given & 0x00800000) == 0) + ? "-" : "")); + arm_decode_shift (given, func, stream); + } + + func (stream, "]%s", + ((given & 0x00200000) != 0) ? "!" : ""); + } + else + { + if ((given & 0x02000000) == 0) + { + int offset = given & 0xfff; + if (offset) + func (stream, "], #%s%d", + (((given & 0x00800000) == 0) + ? "-" : ""), offset); + else + func (stream, "]"); + } + else + { + func (stream, "], %s", + (((given & 0x00800000) == 0) + ? "-" : "")); + arm_decode_shift (given, func, stream); + } + } + } +} + /* Print one ARM instruction from PC on INFO->STREAM. */ static void @@ -1642,88 +1752,13 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) break; case 'a': - if (((given & 0x000f0000) == 0x000f0000) - && ((given & 0x02000000) == 0)) - { - int offset = given & 0xfff; - - func (stream, "[pc"); - - if (given & 0x01000000) - { - if ((given & 0x00800000) == 0) - offset = - offset; - - /* Pre-indexed. */ - func (stream, ", #%d]", offset); - - offset += pc + 8; - - /* Cope with the possibility of write-back - being used. Probably a very dangerous thing - for the programmer to do, but who are we to - argue ? */ - if (given & 0x00200000) - func (stream, "!"); - } - else - { - /* Post indexed. */ - func (stream, "], #%d", offset); - - /* ie ignore the offset. */ - offset = pc + 8; - } - - func (stream, "\t; "); - info->print_address_func (offset, info); - } - else - { - func (stream, "[%s", - arm_regnames[(given >> 16) & 0xf]); - if ((given & 0x01000000) != 0) - { - if ((given & 0x02000000) == 0) - { - int offset = given & 0xfff; - if (offset) - func (stream, ", #%s%d", - (((given & 0x00800000) == 0) - ? "-" : ""), offset); - } - else - { - func (stream, ", %s", - (((given & 0x00800000) == 0) - ? "-" : "")); - arm_decode_shift (given, func, stream); - } + print_arm_address (pc, info, given); + break; - func (stream, "]%s", - ((given & 0x00200000) != 0) ? "!" : ""); - } - else - { - if ((given & 0x02000000) == 0) - { - int offset = given & 0xfff; - if (offset) - func (stream, "], #%s%d", - (((given & 0x00800000) == 0) - ? "-" : ""), offset); - else - func (stream, "]"); - } - else - { - func (stream, "], %s", - (((given & 0x00800000) == 0) - ? "-" : "")); - arm_decode_shift (given, func, stream); - } - } - } + case 'P': + /* Set P address bit and use normal address + printing routine. */ + print_arm_address (pc, info, given | (1 << 24)); break; case 's': @@ -1913,6 +1948,19 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) func (stream, "c"); break; + case 'U': + switch (given & 0xf) + { + case 0xf: func(stream, "sy"); break; + case 0x7: func(stream, "un"); break; + case 0xe: func(stream, "st"); break; + case 0x6: func(stream, "unst"); break; + default: + func(stream, "#%d", (int)given & 0xf); + break; + } + break; + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { @@ -2292,6 +2340,30 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given) abort (); } +/* Return the name of an V7M special register. */ +static const char * +psr_name (int regno) +{ + switch (regno) + { + case 0: return "APSR"; + case 1: return "IAPSR"; + case 2: return "EAPSR"; + case 3: return "PSR"; + case 5: return "IPSR"; + case 6: return "EPSR"; + case 7: return "IEPSR"; + case 8: return "MSP"; + case 9: return "PSP"; + case 16: return "PRIMASK"; + case 17: return "BASEPRI"; + case 18: return "BASEPRI_MASK"; + case 19: return "FAULTMASK"; + case 20: return "CONTROL"; + default: return "<unknown>"; + } +} + /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */ static void @@ -2638,6 +2710,45 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) } break; + case 'U': + switch (given & 0xf) + { + case 0xf: func(stream, "sy"); break; + case 0x7: func(stream, "un"); break; + case 0xe: func(stream, "st"); break; + case 0x6: func(stream, "unst"); break; + default: + func(stream, "#%d", (int)given & 0xf); + break; + } + break; + + case 'C': + if ((given & 0xff) == 0) + { + func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C'); + if (given & 0x800) + func (stream, "f"); + if (given & 0x400) + func (stream, "s"); + if (given & 0x200) + func (stream, "x"); + if (given & 0x100) + func (stream, "c"); + } + else + { + func (stream, psr_name (given & 0xff)); + } + break; + + case 'D': + if ((given & 0xff) == 0) + func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C'); + else + func (stream, psr_name (given & 0xff)); + break; + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { |