/* Print mips instructions for GDB, the GNU debugger, or for objdump.
- Copyright 1989, 91-97, 1998 Free Software Foundation, Inc.
+ Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001
+ Free Software Foundation, Inc.
Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
This file is part of GDB, GAS, and the GNU binutils.
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#include <ansidecl.h>
#include "sysdep.h"
#include "dis-asm.h"
#include "opcode/mips.h"
+#include "opintl.h"
-/* FIXME: These are needed to figure out if this is a mips16 symbol or
- not. It would be better to think of a cleaner way to do this. */
+/* FIXME: These are needed to figure out if the code is mips16 or
+ not. The low bit of the address is often a good indicator. No
+ symbol table is available when this code runs out in an embedded
+ system as when it is used for disassembler support in a monitor. */
+
+#if !defined(EMBEDDED_ENV)
+#define SYMTAB_AVAILABLE 1
#include "elf-bfd.h"
#include "elf/mips.h"
+#endif
-static int print_insn_mips16 PARAMS ((bfd_vma, struct disassemble_info *));
+/* Mips instructions are at maximum this many bytes long. */
+#define INSNLEN 4
+
+static int _print_insn_mips
+ PARAMS ((bfd_vma, struct disassemble_info *, enum bfd_endian));
+static int print_insn_mips
+ PARAMS ((bfd_vma, unsigned long int, struct disassemble_info *));
+static void print_insn_arg
+ PARAMS ((const char *, unsigned long, bfd_vma, struct disassemble_info *));
+static void mips_isa_type
+ PARAMS ((int, int *, int *));
+static int print_insn_mips16
+ PARAMS ((bfd_vma, struct disassemble_info *));
+static int is_newabi
+ PARAMS ((Elf_Internal_Ehdr *));
static void print_mips16_insn_arg
PARAMS ((int, const struct mips_opcode *, int, boolean, int, bfd_vma,
struct disassemble_info *));
-
-/* Mips instructions are never longer than this many bytes. */
-#define MAXLEN 4
-
-static void print_insn_arg PARAMS ((const char *, unsigned long, bfd_vma,
- struct disassemble_info *));
-static int _print_insn_mips PARAMS ((bfd_vma, unsigned long int,
- struct disassemble_info *));
-
\f
-/* FIXME: This should be shared with gdb somehow. */
-#define REGISTER_NAMES \
- { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
- "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
- "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
- "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", \
- "sr", "lo", "hi", "bad", "cause","pc", \
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
- "fsr", "fir", "fp", "inx", "rand", "tlblo","ctxt", "tlbhi",\
- "epc", "prid"\
- }
-
-static CONST char * CONST reg_names[] = REGISTER_NAMES;
+/* FIXME: These should be shared with gdb somehow. */
/* The mips16 register names. */
-static const char * const mips16_reg_names[] =
-{
+static const char * const mips16_reg_names[] = {
"s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
};
+
+static const char * const mips32_reg_names[] = {
+ "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
+ "sr", "lo", "hi", "bad", "cause", "pc",
+ "fv0", "$f1", "fv1", "$f3", "ft0", "$f5", "ft1", "$f7",
+ "ft2", "$f9", "ft3", "$f11", "fa0", "$f13", "fa1", "$f15",
+ "ft4", "f17", "ft5", "f19", "fs0", "f21", "fs1", "f23",
+ "fs2", "$f25", "fs3", "$f27", "fs4", "$f29", "fs5", "$f31",
+ "fsr", "fir", "fp", "inx", "rand", "tlblo", "ctxt", "tlbhi",
+ "epc", "prid"
+};
+
+static const char * const mips64_reg_names[] = {
+ "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+ "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
+ "sr", "lo", "hi", "bad", "cause", "pc",
+ "fv0", "$f1", "fv1", "$f3", "ft0", "ft1", "ft2", "ft3",
+ "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
+ "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
+ "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
+ "fsr", "fir", "fp", "inx", "rand", "tlblo", "ctxt", "tlbhi",
+ "epc", "prid"
+};
+
+/* Scalar register names. _print_insn_mips() decides which register name
+ table to use. */
+static const char * const *reg_names = NULL;
\f
-/* subroutine */
+/* Print insn arguments for 32/64-bit code. */
+
static void
print_insn_arg (d, l, pc, info)
const char *d;
case ',':
case '(':
case ')':
- /* start-sanitize-vr5400 */
- case '[':
- case ']':
- /* end-sanitize-vr5400 */
(*info->fprintf_func) (info->stream, "%c", *d);
break;
case 'b':
case 'r':
case 'v':
- (*info->fprintf_func) (info->stream, "$%s",
+ (*info->fprintf_func) (info->stream, "%s",
reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
break;
case 't':
case 'w':
- (*info->fprintf_func) (info->stream, "$%s",
+ (*info->fprintf_func) (info->stream, "%s",
reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
break;
case 'i':
case 'u':
(*info->fprintf_func) (info->stream, "0x%x",
- (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
+ (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
break;
- case 'j': /* same as i, but sign-extended */
+ case 'j': /* Same as i, but sign-extended. */
case 'o':
delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
if (delta & 0x8000)
case 'a':
(*info->print_address_func)
- (((pc & 0xF0000000) | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
+ ((((pc + 4) & ~(bfd_vma) 0x0fffffff)
+ | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
info);
break;
case 'p':
- /* sign extend the displacement */
+ /* Sign extend the displacement. */
delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
if (delta & 0x8000)
delta |= ~0xffff;
(*info->print_address_func)
- ((delta << 2) + pc + 4,
+ ((delta << 2) + pc + INSNLEN,
info);
break;
case 'd':
- (*info->fprintf_func) (info->stream, "$%s",
+ (*info->fprintf_func) (info->stream, "%s",
reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
break;
+ case 'U':
+ {
+ /* First check for both rd and rt being equal. */
+ unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
+ if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
+ (*info->fprintf_func) (info->stream, "%s",
+ reg_names[reg]);
+ else
+ {
+ /* If one is zero use the other. */
+ if (reg == 0)
+ (*info->fprintf_func) (info->stream, "%s",
+ reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
+ else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
+ (*info->fprintf_func) (info->stream, "%s",
+ reg_names[reg]);
+ else /* Bogus, result depends on processor. */
+ (*info->fprintf_func) (info->stream, "%s or %s",
+ reg_names[reg],
+ reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
+ }
+ }
+ break;
+
case 'z':
- (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
+ (*info->fprintf_func) (info->stream, "%s", reg_names[0]);
break;
case '<':
(l >> OP_SH_CODE) & OP_MASK_CODE);
break;
+ case 'q':
+ (*info->fprintf_func) (info->stream, "0x%x",
+ (l >> OP_SH_CODE2) & OP_MASK_CODE2);
+ break;
+
case 'C':
(*info->fprintf_func) (info->stream, "0x%x",
(l >> OP_SH_COPZ) & OP_MASK_COPZ);
case 'B':
(*info->fprintf_func) (info->stream, "0x%x",
- (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
+ (l >> OP_SH_CODE20) & OP_MASK_CODE20);
+ break;
+
+ case 'J':
+ (*info->fprintf_func) (info->stream, "0x%x",
+ (l >> OP_SH_CODE19) & OP_MASK_CODE19);
break;
case 'S':
(l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
break;
- /* start-sanitize-vr5400 */
- case 'e':
+ case 'H':
(*info->fprintf_func) (info->stream, "%d",
- (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
+ (l >> OP_SH_SEL) & OP_MASK_SEL);
break;
- case '%':
- (*info->fprintf_func) (info->stream, "%d",
- (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
+ default:
+ /* xgettext:c-format */
+ (*info->fprintf_func) (info->stream,
+ _("# internal error, undefined modifier(%c)"),
+ *d);
+ break;
+ }
+}
+\f
+/* Figure out the MIPS ISA and CPU based on the machine number. */
+
+static void
+mips_isa_type (mach, isa, cputype)
+ int mach;
+ int *isa;
+ int *cputype;
+{
+ switch (mach)
+ {
+ case bfd_mach_mips3000:
+ *cputype = CPU_R3000;
+ *isa = ISA_MIPS1;
+ break;
+ case bfd_mach_mips3900:
+ *cputype = CPU_R3900;
+ *isa = ISA_MIPS1;
+ break;
+ case bfd_mach_mips4000:
+ *cputype = CPU_R4000;
+ *isa = ISA_MIPS3;
+ break;
+ case bfd_mach_mips4010:
+ *cputype = CPU_R4010;
+ *isa = ISA_MIPS2;
+ break;
+ case bfd_mach_mips4100:
+ *cputype = CPU_VR4100;
+ *isa = ISA_MIPS3;
+ break;
+ case bfd_mach_mips4111:
+ *cputype = CPU_R4111;
+ *isa = ISA_MIPS3;
+ break;
+ case bfd_mach_mips4300:
+ *cputype = CPU_R4300;
+ *isa = ISA_MIPS3;
+ break;
+ case bfd_mach_mips4400:
+ *cputype = CPU_R4400;
+ *isa = ISA_MIPS3;
+ break;
+ case bfd_mach_mips4600:
+ *cputype = CPU_R4600;
+ *isa = ISA_MIPS3;
+ break;
+ case bfd_mach_mips4650:
+ *cputype = CPU_R4650;
+ *isa = ISA_MIPS3;
+ break;
+ case bfd_mach_mips5000:
+ *cputype = CPU_R5000;
+ *isa = ISA_MIPS4;
+ break;
+ case bfd_mach_mips6000:
+ *cputype = CPU_R6000;
+ *isa = ISA_MIPS2;
+ break;
+ case bfd_mach_mips8000:
+ *cputype = CPU_R8000;
+ *isa = ISA_MIPS4;
+ break;
+ case bfd_mach_mips10000:
+ *cputype = CPU_R10000;
+ *isa = ISA_MIPS4;
+ break;
+ case bfd_mach_mips12000:
+ *cputype = CPU_R12000;
+ *isa = ISA_MIPS4;
+ break;
+ case bfd_mach_mips16:
+ *cputype = CPU_MIPS16;
+ *isa = ISA_MIPS3;
+ break;
+ case bfd_mach_mips5:
+ *cputype = CPU_MIPS5;
+ *isa = ISA_MIPS5;
+ break;
+ case bfd_mach_mips_sb1:
+ *cputype = CPU_SB1;
+ *isa = ISA_MIPS64;
+ break;
+ case bfd_mach_mipsisa32:
+ * cputype = CPU_MIPS32;
+ * isa = ISA_MIPS32;
+ break;
+ case bfd_mach_mipsisa64:
+ * cputype = CPU_MIPS64;
+ * isa = ISA_MIPS64;
break;
- /* end-sanitize-vr5400 */
default:
- (*info->fprintf_func) (info->stream,
- "# internal error, undefined modifier(%c)", *d);
+ *cputype = CPU_R3000;
+ *isa = ISA_MIPS3;
break;
}
}
+
+/* Check if the object uses NewABI conventions. */
+
+static int
+is_newabi (header)
+ Elf_Internal_Ehdr *header;
+{
+ if ((header->e_flags
+ & (E_MIPS_ABI_EABI32 | E_MIPS_ABI_EABI64 | EF_MIPS_ABI2)) != 0
+ || (header->e_ident[EI_CLASS] == ELFCLASS64
+ && (header->e_flags & E_MIPS_ABI_O64) == 0))
+ return 1;
+
+ return 0;
+}
\f
/* Print the mips instruction at address MEMADDR in debugged memory,
on using INFO. Returns length of the instruction, in bytes, which is
- always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
+ always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
this is little-endian code. */
static int
-_print_insn_mips (memaddr, word, info)
+print_insn_mips (memaddr, word, info)
bfd_vma memaddr;
unsigned long int word;
struct disassemble_info *info;
break;
}
}
- }
+ }
init = 1;
}
- switch (info->mach)
- {
- /* start-sanitize-tx19 */
- case bfd_mach_mips1900:
- target_processor = 1900;
- mips_isa = 1;
- break;
- /* end-sanitize-tx19 */
- case bfd_mach_mips3000:
- target_processor = 3000;
- mips_isa = 1;
- break;
- case bfd_mach_mips3900:
- target_processor = 3900;
- mips_isa = 1;
- break;
- case bfd_mach_mips4000:
- target_processor = 4000;
- mips_isa = 3;
- break;
- case bfd_mach_mips4010:
- target_processor = 4010;
- mips_isa = 2;
- break;
- case bfd_mach_mips4100:
- target_processor = 4100;
- mips_isa = 3;
- break;
- case bfd_mach_mips4300:
- target_processor = 4300;
- mips_isa = 3;
- break;
- case bfd_mach_mips4400:
- target_processor = 4400;
- mips_isa = 3;
- break;
- case bfd_mach_mips4600:
- target_processor = 4600;
- mips_isa = 3;
- break;
- case bfd_mach_mips4650:
- target_processor = 4650;
- mips_isa = 3;
- break;
- /* start-sanitize-tx49 */
- case bfd_mach_mips4900:
- target_processor = 4900;
- mips_isa = 3;
- break;
- /* end-sanitize-tx49 */
- case bfd_mach_mips5000:
- target_processor = 5000;
- mips_isa = 4;
- break;
- /* start-sanitize-vr5400 */
- case bfd_mach_mips5400:
- target_processor = 5400;
- mips_isa = 3;
- break;
- /* end-sanitize-vr5400 */
- /* start-sanitize-r5900 */
- case bfd_mach_mips5900:
- target_processor = 5900;
- mips_isa = 3;
- break;
- /* end-sanitize-r5900 */
- case bfd_mach_mips6000:
- target_processor = 6000;
- mips_isa = 2;
- break;
- case bfd_mach_mips8000:
- target_processor = 8000;
- mips_isa = 4;
- break;
- case bfd_mach_mips10000:
- target_processor = 10000;
- mips_isa = 4;
- break;
- case bfd_mach_mips16:
- target_processor = 16;
- mips_isa = 3;
- break;
- default:
- target_processor = 3000;
- mips_isa = 3;
- break;
-
- }
+#if ! SYMTAB_AVAILABLE
+ /* This is running out on a target machine, not in a host tool.
+ FIXME: Where does mips_target_info come from? */
+ target_processor = mips_target_info.processor;
+ mips_isa = mips_target_info.isa;
+#else
+ mips_isa_type (info->mach, &mips_isa, &target_processor);
+#endif
- info->bytes_per_chunk = 4;
+ info->bytes_per_chunk = INSNLEN;
info->display_endian = info->endian;
op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
{
register const char *d;
- int insn_isa;
-
- if ((op->membership & INSN_ISA) == INSN_ISA1)
- insn_isa = 1;
- else if ((op->membership & INSN_ISA) == INSN_ISA2)
- insn_isa = 2;
- else if ((op->membership & INSN_ISA) == INSN_ISA3)
- insn_isa = 3;
- else if ((op->membership & INSN_ISA) == INSN_ISA4)
- insn_isa = 4;
- else
- insn_isa = 15;
-
- if (insn_isa > mips_isa
- && (target_processor == 4650
- && op->membership & INSN_4650) == 0
- && (target_processor == 4010
- && op->membership & INSN_4010) == 0
- && (target_processor == 4100
- && op->membership & INSN_4100) == 0
- /* start-sanitize-vr5400 */
- && (target_processor == 5400
- && op->membership & INSN_5400) == 0
- /* end-sanitize-vr5400 */
- /* start-sanitize-r5900 */
- && (target_processor == 5900
- && op->membership & INSN_5900) == 0
- /* end-sanitize-r5900 */
- /* start-sanitize-tx49 */
- && (target_processor == 4900
- && op->membership & INSN_4900) == 0
- /* end-sanitize-tx49 */
- && (target_processor == 3900
- && op->membership & INSN_3900) == 0)
+
+ if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor))
continue;
(*info->fprintf_func) (info->stream, "%s", op->name);
print_insn_arg (d, word, memaddr, info);
}
- return 4;
+ return INSNLEN;
}
}
}
/* Handle undefined instructions. */
(*info->fprintf_func) (info->stream, "0x%x", word);
- return 4;
+ return INSNLEN;
}
+\f
+/* In an environment where we do not know the symbol type of the
+ instruction we are forced to assume that the low order bit of the
+ instructions' address may mark it as a mips16 instruction. If we
+ are single stepping, or the pc is within the disassembled function,
+ this works. Otherwise, we need a clue. Sometimes. */
-int
-print_insn_big_mips (memaddr, info)
+static int
+_print_insn_mips (memaddr, info, endianness)
bfd_vma memaddr;
struct disassemble_info *info;
+ enum bfd_endian endianness;
{
- bfd_byte buffer[4];
+ bfd_byte buffer[INSNLEN];
int status;
+#if 1
+ /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
+ /* Only a few tools will work this way. */
+ if (memaddr & 0x01)
+ return print_insn_mips16 (memaddr, info);
+#endif
+
+#if SYMTAB_AVAILABLE
if (info->mach == 16
|| (info->flavour == bfd_target_elf_flavour
&& info->symbols != NULL
&& ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
== STO_MIPS16)))
return print_insn_mips16 (memaddr, info);
+#endif
+
+ /* Use mips64_reg_names for new ABI. */
+ reg_names = mips32_reg_names;
+
+ if (info->flavour == bfd_target_elf_flavour && info->symbols != NULL)
+ {
+ Elf_Internal_Ehdr *header;
- status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+ header = elf_elfheader (bfd_asymbol_bfd (*(info->symbols)));
+ if (is_newabi (header))
+ reg_names = mips64_reg_names;
+ }
+
+ status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
if (status == 0)
- return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
- info);
+ {
+ unsigned long insn;
+
+ if (endianness == BFD_ENDIAN_BIG)
+ insn = (unsigned long) bfd_getb32 (buffer);
+ else
+ insn = (unsigned long) bfd_getl32 (buffer);
+
+ return print_insn_mips (memaddr, insn, info);
+ }
else
{
(*info->memory_error_func) (status, memaddr, info);
}
int
-print_insn_little_mips (memaddr, info)
+print_insn_big_mips (memaddr, info)
bfd_vma memaddr;
struct disassemble_info *info;
{
- bfd_byte buffer[4];
- int status;
-
- /* start-sanitize-sky */
-#ifdef ARCH_dvp
- {
- /* bfd_mach_dvp_p is a macro which may evaluate its arguments more than
- once. Since dvp_mach_type is a function, ensure it's only called
- once. */
- int mach = dvp_info_mach_type (info);
-
- if (bfd_mach_dvp_p (info->mach)
- || bfd_mach_dvp_p (mach))
- return print_insn_dvp (memaddr, info);
- }
-#endif
- /* end-sanitize-sky */
-
- if (info->mach == 16
- || (info->flavour == bfd_target_elf_flavour
- && info->symbols != NULL
- && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
- == STO_MIPS16)))
- return print_insn_mips16 (memaddr, info);
+ return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
+}
- status = (*info->read_memory_func) (memaddr, buffer, 4, info);
- if (status == 0)
- return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
- info);
- else
- {
- (*info->memory_error_func) (status, memaddr, info);
- return -1;
- }
+int
+print_insn_little_mips (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
}
\f
/* Disassemble mips16 instructions. */
int length;
int insn;
boolean use_extend;
- int extend;
+ int extend = 0;
const struct mips_opcode *op, *opend;
info->bytes_per_chunk = 2;
info->display_endian = info->endian;
-
info->insn_info_valid = 1;
info->branch_delay_insns = 0;
info->data_size = 0;
static void
print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
- int type;
+ char type;
const struct mips_opcode *op;
int l;
boolean use_extend;
case 'y':
case 'w':
- (*info->fprintf_func) (info->stream, "$%s",
+ (*info->fprintf_func) (info->stream, "%s",
mips16_reg_names[((l >> MIPS16OP_SH_RY)
& MIPS16OP_MASK_RY)]);
break;
case 'x':
case 'v':
- (*info->fprintf_func) (info->stream, "$%s",
+ (*info->fprintf_func) (info->stream, "%s",
mips16_reg_names[((l >> MIPS16OP_SH_RX)
& MIPS16OP_MASK_RX)]);
break;
case 'z':
- (*info->fprintf_func) (info->stream, "$%s",
+ (*info->fprintf_func) (info->stream, "%s",
mips16_reg_names[((l >> MIPS16OP_SH_RZ)
& MIPS16OP_MASK_RZ)]);
break;
case 'Z':
- (*info->fprintf_func) (info->stream, "$%s",
+ (*info->fprintf_func) (info->stream, "%s",
mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
& MIPS16OP_MASK_MOVE32Z)]);
break;
case '0':
- (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
+ (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[0]);
break;
case 'S':
- (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
+ (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[29]);
break;
case 'P':
break;
case 'R':
- (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
+ (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[31]);
break;
case 'X':
- (*info->fprintf_func) (info->stream, "$%s",
- reg_names[((l >> MIPS16OP_SH_REGR32)
- & MIPS16OP_MASK_REGR32)]);
+ (*info->fprintf_func) (info->stream, "%s",
+ mips32_reg_names[((l >> MIPS16OP_SH_REGR32)
+ & MIPS16OP_MASK_REGR32)]);
break;
case 'Y':
- (*info->fprintf_func) (info->stream, "$%s",
- reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
+ (*info->fprintf_func) (info->stream, "%s",
+ mips32_reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
break;
case '<':
if (signedp && immed >= (1 << (nbits - 1)))
immed -= 1 << nbits;
immed <<= shift;
- if ((type == '<' || type == '>' || type == '[' || type == '[')
+ if ((type == '<' || type == '>' || type == '[' || type == ']')
&& immed == 0)
immed = 8;
}
baseaddr = memaddr - 2;
}
}
- val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
+ val = (baseaddr & ~((1 << shift) - 1)) + immed;
(*info->print_address_func) (val, info);
info->target = val;
}
if (! use_extend)
extend = 0;
l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
- (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
+ (*info->print_address_func) (((memaddr + 4) & 0xf0000000) | l, info);
info->insn_type = dis_jsr;
- info->target = (memaddr & 0xf0000000) | l;
+ info->target = ((memaddr + 4) & 0xf0000000) | l;
info->branch_delay_insns = 1;
break;
if (amask > 0 && amask < 5)
{
- (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
+ (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[4]);
if (amask > 1)
- (*info->fprintf_func) (info->stream, "-$%s",
- reg_names[amask + 3]);
+ (*info->fprintf_func) (info->stream, "-%s",
+ mips32_reg_names[amask + 3]);
need_comma = 1;
}
}
else if (smask > 0)
{
- (*info->fprintf_func) (info->stream, "%s$%s",
+ (*info->fprintf_func) (info->stream, "%s%s",
need_comma ? "," : "",
- reg_names[16]);
+ mips32_reg_names[16]);
if (smask > 1)
- (*info->fprintf_func) (info->stream, "-$%s",
- reg_names[smask + 15]);
+ (*info->fprintf_func) (info->stream, "-%s",
+ mips32_reg_names[smask + 15]);
need_comma = 1;
}
if (l & 1)
{
- (*info->fprintf_func) (info->stream, "%s$%s",
+ (*info->fprintf_func) (info->stream, "%s%s",
need_comma ? "," : "",
- reg_names[31]);
+ mips32_reg_names[31]);
need_comma = 1;
}
break;
default:
+ /* xgettext:c-format */
+ (*info->fprintf_func)
+ (info->stream,
+ _("# internal disassembler error, unrecognised modifier (%c)"),
+ type);
abort ();
}
}