aboutsummaryrefslogtreecommitdiff
path: root/opcodes/arm-dis.c
diff options
context:
space:
mode:
authorZack Weinberg <zackw@panix.com>2005-06-08 17:27:41 +0000
committerZack Weinberg <zackw@panix.com>2005-06-08 17:27:41 +0000
commit6b5d3a4d35ef634397172c1744e4a26a035a50c2 (patch)
tree563bec6489bea55014d0071fece9d27441b3e700 /opcodes/arm-dis.c
parent03b13e59e203becdaec06f112afe53a50b11c2ce (diff)
downloadfsf-binutils-gdb-6b5d3a4d35ef634397172c1744e4a26a035a50c2.zip
fsf-binutils-gdb-6b5d3a4d35ef634397172c1744e4a26a035a50c2.tar.gz
fsf-binutils-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.c138
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, &regnames);
- while ((strcmp ("iwmmxt_regnames", setname))
- && (iwmmxt_regnames < num_regnames))
- get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, &regnames);
-
- 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 != '%')