X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Fa29k-dis.c;h=0e937ba0eab4d3189887d76f8c2f34a49be35a77;hb=d83c654853c53c431e581c6ca3a715dd70cbe126;hp=102d57a9aa402de0015762bfec21a8e5df46eccb;hpb=e9aff87e192419f31758b95c2ee9b5d6e2ad4f4e;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/a29k-dis.c b/opcodes/a29k-dis.c index 102d57a9aa..0e937ba0ea 100644 --- a/opcodes/a29k-dis.c +++ b/opcodes/a29k-dis.c @@ -1,5 +1,6 @@ /* Instruction printing code for the AMD 29000 - Copyright (C) 1990 Free Software Foundation, Inc. + Copyright 1990, 1993, 1994, 1995, 1998, 2000, 2001 + Free Software Foundation, Inc. Contributed by Cygnus Support. Written by Jim Kingdon. This file is part of GDB. @@ -16,11 +17,24 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "sysdep.h" #include "dis-asm.h" #include "opcode/a29k.h" +static void print_general PARAMS ((int, struct disassemble_info *)); +static void print_special PARAMS ((unsigned int, struct disassemble_info *)); +static int is_delayed_branch PARAMS ((int)); +static void find_bytes_little + PARAMS ((char *, unsigned char *, unsigned char *, unsigned char *, + unsigned char *)); +static void find_bytes_big + PARAMS ((char *, unsigned char *, unsigned char *, unsigned char *, + unsigned char *)); +static int print_insn PARAMS ((bfd_vma, struct disassemble_info *)); + + /* Print a symbolic representation of a general-purpose register number NUM on STREAM. NUM is a number as found in the instruction, not as found in @@ -37,19 +51,21 @@ print_general (num, info) } /* Like print_general but a special-purpose register. - + The mnemonics used by the AMD assembler are not quite the same as the ones in the User's Manual. We use the ones that the assembler uses. */ static void print_special (num, info) - int num; + unsigned int num; struct disassemble_info *info; { /* Register names of registers 0-SPEC0_NUM-1. */ static char *spec0_names[] = { "vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr", - "pc0", "pc1", "pc2", "mmu", "lru" + "pc0", "pc1", "pc2", "mmu", "lru", "rsn", "rma0", "rmc0", "rma1", "rmc1", + "spc0", "spc1", "spc2", "iba0", "ibc0", "iba1", "ibc1", "dba", "dbc", + "cir", "cdr" }; #define SPEC0_NUM ((sizeof spec0_names) / (sizeof spec0_names[0])) @@ -117,12 +133,13 @@ find_bytes_little (insn, insn0, insn8, insn16, insn24) *insn0 = insn[0]; } -typedef (*find_byte_func_type) +typedef void (*find_byte_func_type) PARAMS ((char *, unsigned char *, unsigned char *, unsigned char *, unsigned char *)); -/* Print one instruction from MEMADDR on STREAM. +/* Print one instruction from MEMADDR on INFO->STREAM. Return the size of the instruction (always 4 on a29k). */ + static int print_insn (memaddr, info) bfd_vma memaddr; @@ -140,7 +157,7 @@ print_insn (memaddr, info) { int status = - (*info->read_memory_func) (memaddr, (char *) &insn[0], 4, info); + (*info->read_memory_func) (memaddr, (bfd_byte *) &insn[0], 4, info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); @@ -150,6 +167,8 @@ print_insn (memaddr, info) (*find_byte_func) (insn, &insn0, &insn8, &insn16, &insn24); + printf ("%02x%02x%02x%02x ", insn24, insn16, insn8, insn0); + /* Handle the nop (aseq 0x40,gr1,gr1) specially */ if ((insn24==0x70) && (insn16==0x40) && (insn8==0x01) && (insn0==0x01)) { (*info->fprintf_func) (info->stream,"nop"); @@ -161,10 +180,10 @@ print_insn (memaddr, info) opcode < &a29k_opcodes[num_opcodes]; ++opcode) { - if ((insn24<<24) == opcode->opcode) + if (((unsigned long) insn24 << 24) == opcode->opcode) { char *s; - + (*info->fprintf_func) (info->stream, "%s ", opcode->name); for (s = opcode->args; *s != '\0'; ++s) { @@ -173,7 +192,7 @@ print_insn (memaddr, info) case 'a': print_general (insn8, info); break; - + case 'b': print_general (insn0, info); break; @@ -187,7 +206,7 @@ print_insn (memaddr, info) break; case 'x': - (*info->fprintf_func) (info->stream, "%d", (insn16 << 8) + insn0); + (*info->fprintf_func) (info->stream, "0x%x", (insn16 << 8) + insn0); break; case 'h': @@ -241,6 +260,11 @@ print_insn (memaddr, info) (*info->fprintf_func) (info->stream, "%d", (insn0 >> 4) & 7); break; + case 'I': + if ((insn16 & 3) != 0) + (*info->fprintf_func) (info->stream, "%d", insn16 & 3); + break; + case 'd': (*info->fprintf_func) (info->stream, "%d", (insn0 >> 2) & 3); break; @@ -269,9 +293,9 @@ print_insn (memaddr, info) int errcode; char prev_insn[4]; unsigned char prev_insn0, prev_insn8, prev_insn16, prev_insn24; - + errcode = (*info->read_memory_func) (memaddr - 4, - &prev_insn[0], + (bfd_byte *) &prev_insn[0], 4, info); if (errcode == 0) @@ -279,7 +303,7 @@ print_insn (memaddr, info) /* If it is a delayed branch, we need to look at the instruction before the delayed brach to handle things like - + const _foo call _printf consth _foo @@ -289,12 +313,12 @@ print_insn (memaddr, info) if (is_delayed_branch (prev_insn24)) { errcode = (*info->read_memory_func) - (memaddr - 8, &prev_insn[0], 4, info); + (memaddr - 8, (bfd_byte *) &prev_insn[0], 4, info); (*find_byte_func) (prev_insn, &prev_insn0, &prev_insn8, &prev_insn16, &prev_insn24); } } - + /* If there was a problem reading memory, then assume the previous instruction was not const. */ if (errcode == 0) @@ -317,7 +341,7 @@ print_insn (memaddr, info) } /* This used to be %8x for binutils. */ (*info->fprintf_func) - (info->stream, ".word 0x%8x", + (info->stream, ".word 0x%08x", (insn24 << 24) + (insn16 << 16) + (insn8 << 8) + insn0); return 4; }