diff options
author | Zack Weinberg <zackw@panix.com> | 2005-06-08 17:27:41 +0000 |
---|---|---|
committer | Zack Weinberg <zackw@panix.com> | 2005-06-08 17:27:41 +0000 |
commit | 6b5d3a4d35ef634397172c1744e4a26a035a50c2 (patch) | |
tree | 563bec6489bea55014d0071fece9d27441b3e700 /opcodes/arm-dis.c | |
parent | 03b13e59e203becdaec06f112afe53a50b11c2ce (diff) | |
download | gdb-6b5d3a4d35ef634397172c1744e4a26a035a50c2.zip gdb-6b5d3a4d35ef634397172c1744e4a26a035a50c2.tar.gz gdb-6b5d3a4d35ef634397172c1744e4a26a035a50c2.tar.bz2 |
opcodes:
* arm-opc.h: Delete; fold contents into ...
* arm-dis.c: ... here. Move includes of internal COFF headers
next to includes of internal ELF headers.
(streq, WORD_ADDRESS, BDISP, BDISP23): Delete, unused.
(struct arm_opcode): Rename struct opcode32. Make 'assembler' const.
(struct thumb_opcode): Rename struct opcode16. Make 'assembler' const.
(arm_conditional, arm_fp_const, arm_shift, arm_regname, regnames)
(iwmmxt_wwnames, iwmmxt_wwssnames):
Make const.
(regnames): Remove iWMMXt coprocessor register sets.
(iwmmxt_regnames, iwmmxt_cregnames): New statics.
(get_arm_regnames): Adjust fourth argument to match above changes.
(set_iwmmxt_regnames): Delete.
(print_insn_arm): Constify 'c'. Use ISO syntax for function
pointer calls. Expand sole use of BDISP. Use iwmmxt_regnames
and iwmmxt_cregnames, not set_iwmmxt_regnames.
(print_insn_thumb16, print_insn_thumb32): Constify 'c'. Use
ISO syntax for function pointer calls.
include:
* dis-asm.h (get_arm_regnames): Update prototype.
Diffstat (limited to 'opcodes/arm-dis.c')
-rw-r--r-- | opcodes/arm-dis.c | 138 |
1 files changed, 58 insertions, 80 deletions
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index a1540b7..d136af1 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -24,21 +24,17 @@ #include "dis-asm.h" #include "opcode/arm.h" -#include "arm-opc.h" -#include "coff/internal.h" -#include "libcoff.h" #include "opintl.h" #include "safe-ctype.h" /* FIXME: This shouldn't be done here. */ +#include "coff/internal.h" +#include "libcoff.h" #include "elf-bfd.h" #include "elf/internal.h" #include "elf/arm.h" -#ifndef streq -#define streq(a,b) (strcmp ((a), (b)) == 0) -#endif - +/* FIXME: Belongs in global header. */ #ifndef strneq #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0) #endif @@ -47,7 +43,19 @@ #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0]) #endif -#define WORD_ADDRESS(pc) ((pc) & ~0x3) +struct opcode32 +{ + unsigned long arch; /* Architecture defining this insn. */ + unsigned long value, mask; /* Recognise insn if (op&mask)==value. */ + const char *assembler; /* How to disassemble this insn. */ +}; + +struct opcode16 +{ + unsigned long arch; /* Architecture defining this insn. */ + unsigned short value, mask; /* Recognise insn if (op&mask)==value. */ + const char *assembler; /* How to disassemble this insn. */ +}; /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially ordered: they must be searched linearly from the top to obtain a correct @@ -101,7 +109,7 @@ %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. */ -static const struct arm_opcode arm_opcodes[] = +static const struct opcode32 arm_opcodes[] = { /* ARM instructions. */ {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"}, @@ -644,7 +652,7 @@ static const struct arm_opcode arm_opcodes[] = %<bitnum>'c print specified char iff bit is one %<bitnum>?ab print a if bit is one else print b. */ -static const struct thumb_opcode thumb_opcodes[] = +static const struct opcode16 thumb_opcodes[] = { /* Thumb instructions. */ @@ -812,7 +820,7 @@ static const struct thumb_opcode thumb_opcodes[] = is guaranteed never to catch a special-case bit pattern with a more general mask, which is important, because this instruction encoding makes heavy use of special-case bit patterns. */ -static const struct arm_opcode thumb32_opcodes[] = +static const struct opcode32 thumb32_opcodes[] = { /* Instructions defined in the basic V6T2 set. */ {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop.w"}, @@ -1018,20 +1026,25 @@ static const struct arm_opcode thumb32_opcodes[] = {0, 0, 0, 0} }; - -static char * arm_conditional[] = +static const char *const arm_conditional[] = {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "", "<und>"}; +static const char *const arm_fp_const[] = +{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"}; + +static const char *const arm_shift[] = +{"lsl", "lsr", "asr", "ror"}; + typedef struct { - const char * name; - const char * description; - const char * reg_names[16]; + const char *name; + const char *description; + const char *reg_names[16]; } arm_regname; -static arm_regname regnames[] = +static const arm_regname regnames[] = { { "raw" , "Select raw register names", { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}}, @@ -1045,22 +1058,28 @@ static arm_regname regnames[] = { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }}, { "special-atpcs", "Select special register names used in the ATPCS", { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }}, - { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor", - { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}}, - { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor", - {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}} }; -static char * iwmmxt_wwnames[] = +static const char *const iwmmxt_wwnames[] = {"b", "h", "w", "d"}; -static char * iwmmxt_wwssnames[] = +static const char *const iwmmxt_wwssnames[] = {"b", "bus", "b", "bss", "h", "hus", "h", "hss", "w", "wus", "w", "wss", "d", "dus", "d", "dss" }; +static const char *const iwmmxt_regnames[] = +{ "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", + "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15" +}; + +static const char *const iwmmxt_cregnames[] = +{ "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", + "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved" +}; + /* Default to GCC register name set. */ static unsigned int regname_selected = 1; @@ -1069,11 +1088,6 @@ static unsigned int regname_selected = 1; static bfd_boolean force_thumb = FALSE; -static char * arm_fp_const[] = -{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"}; - -static char * arm_shift[] = -{"lsl", "lsr", "asr", "ror"}; /* Functions. */ int @@ -1092,7 +1106,7 @@ set_arm_regname_option (int option) int get_arm_regnames (int option, const char **setname, const char **setdescription, - const char ***register_names) + const char *const **register_names) { *setname = regnames[option].name; *setdescription = regnames[option].description; @@ -1131,33 +1145,14 @@ arm_decode_shift (long given, fprintf_ftype func, void *stream) } } -static int -set_iwmmxt_regnames (void) -{ - const char * setname; - const char * setdesc; - const char ** regnames; - int iwmmxt_regnames = 0; - int num_regnames = get_arm_regname_num_options (); - - get_arm_regnames (iwmmxt_regnames, &setname, - &setdesc, ®names); - while ((strcmp ("iwmmxt_regnames", setname)) - && (iwmmxt_regnames < num_regnames)) - get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, ®names); - - return iwmmxt_regnames; -} - /* Print one ARM instruction from PC on INFO->STREAM. */ static void print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) { - const struct arm_opcode *insn; + const struct opcode32 *insn; void *stream = info->stream; - fprintf_ftype func = info->fprintf_func; - static int iwmmxt_regnames = 0; + fprintf_ftype func = info->fprintf_func; for (insn = arm_opcodes; insn->assembler; insn++) { @@ -1174,7 +1169,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) || (insn->mask & 0xF0000000) == 0xF0000000 || (insn->mask == 0 && insn->value == 0))) { - char * c; + const char *c; for (c = insn->assembler; *c; c++) { @@ -1281,9 +1276,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) offset = -offset; func (stream, "[pc, #%d]\t; ", offset); - - (*info->print_address_func) - (offset + pc + 8, info); + info->print_address_func (offset + pc + 8, info); } else { @@ -1340,8 +1333,10 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) break; case 'b': - (*info->print_address_func) - (BDISP (given) * 4 + pc + 8, info); + { + int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000); + info->print_address_func (disp*4 + pc + 8, info); + } break; case 'c': @@ -1663,34 +1658,18 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) case 'g': { long reg; - int current_regnames; - - if (! iwmmxt_regnames) - iwmmxt_regnames = set_iwmmxt_regnames (); - current_regnames = set_arm_regname_option - (iwmmxt_regnames); - reg = given >> bitstart; reg &= (2 << (bitend - bitstart)) - 1; - func (stream, "%s", arm_regnames[reg]); - set_arm_regname_option (current_regnames); + func (stream, "%s", iwmmxt_regnames[reg]); } break; case 'G': { long reg; - int current_regnames; - - if (! iwmmxt_regnames) - iwmmxt_regnames = set_iwmmxt_regnames (); - current_regnames = set_arm_regname_option - (iwmmxt_regnames + 1); - reg = given >> bitstart; reg &= (2 << (bitend - bitstart)) - 1; - func (stream, "%s", arm_regnames[reg]); - set_arm_regname_option (current_regnames); + func (stream, "%s", iwmmxt_cregnames[reg]); } break; @@ -1901,14 +1880,14 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) static void print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given) { - const struct thumb_opcode *insn; + const struct opcode16 *insn; void *stream = info->stream; fprintf_ftype func = info->fprintf_func; for (insn = thumb_opcodes; insn->assembler; insn++) if ((given & insn->mask) == insn->value) { - char * c = insn->assembler; + const char *c = insn->assembler; for (; *c; c++) { int domaskpc = 0; @@ -2070,8 +2049,7 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given) case 'B': reg = ((reg ^ (1 << bitend)) - (1 << bitend)); - (*info->print_address_func) - (reg * 2 + pc + 4, info); + info->print_address_func (reg * 2 + pc + 4, info); break; case 'c': @@ -2127,14 +2105,14 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given) static void print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) { - const struct arm_opcode *insn; + const struct opcode32 *insn; void *stream = info->stream; fprintf_ftype func = info->fprintf_func; for (insn = thumb32_opcodes; insn->assembler; insn++) if ((given & insn->mask) == insn->value) { - char * c = insn->assembler; + const char *c = insn->assembler; for (; *c; c++) { if (*c != '%') |