From 0024027986f08aa7bd6ebc491a25c104d9b5eb54 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 22 Jan 1994 00:16:18 +0000 Subject: [PATCH] * rs6000-pinsn.c: Use the new disassembler in the opcodes directory. Old code was discarded, since the new opcode table has a different format. --- gdb/ChangeLog | 6 + gdb/rs6000-pinsn.c | 372 +-------------------------------------------- 2 files changed, 14 insertions(+), 364 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 045e97534e..05a8f73c68 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +Fri Jan 21 19:08:48 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * rs6000-pinsn.c: Use the new disassembler in the opcodes + directory. Old code was discarded, since the new opcode table has + a different format. + Fri Jan 21 14:28:30 1994 Fred Fish (fnf@cygnus.com) * Makefile.in (realclean): Remove info files per make-stds.texi. diff --git a/gdb/rs6000-pinsn.c b/gdb/rs6000-pinsn.c index 28e1ee8294..3af94f9703 100644 --- a/gdb/rs6000-pinsn.c +++ b/gdb/rs6000-pinsn.c @@ -1,8 +1,9 @@ /* Print IBM RS/6000 instructions for GNU software. - Copyright 1991 Free Software Foundation, Inc. - Contributed by IBM Corporation. + Copyright 1991,1994 Free Software Foundation, Inc. + Original version was contributed by IBM Corporation. + Now we just use the disassembler in the opcodes directory. -This file is part of GDB and the GNU binutils. +This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,7 +20,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "defs.h" -#include "opcode/rs6k.h" +#include "dis-asm.h" /* Print the rs6k instruction at address MEMADDR in debugged memory, on STREAM. Returns length of the instruction, in bytes. */ @@ -29,366 +30,9 @@ print_insn (memaddr, stream) CORE_ADDR memaddr; GDB_FILE *stream; { - int pop, eop, probable_eop; /* primary and extended opcodes */ - int min, max; - int best = -1; /* found best opcode index */ - int oldbest = -1; - unsigned int the_insn; + disassemble_info info; - read_memory (memaddr, &the_insn, sizeof (the_insn)); - pop = (unsigned)(the_insn >> 26); - min = 0, max = NOPCODES-1; + GDB_INIT_DISASSEMBLE_INFO (info, stream); - while (min < max) { - best = (min + max) / 2; - - /* see if we are running in loops */ - if (best == oldbest) - goto not_found; - oldbest = best; - - if (pop < rs6k_ops [best].p_opcode) - max = best; - - else if (pop > rs6k_ops [best].p_opcode) - min = best; - - else { - /* Opcode matched, check extended opcode. */ - - if (rs6k_ops [best].e_opcode == -1) { - /* there is no valid extended opcode, what we've got is - just fine. */ - goto insn_found; - } - - /* Largest possible value of extended opcode. */ - probable_eop = ((the_insn) >> 1) & 0x3ff; - - eop = probable_eop & eopMask [rs6k_ops [best].format]; - - if (eop < rs6k_ops [best].e_opcode) { - - while (pop == rs6k_ops [best].p_opcode) { - if (eop == rs6k_ops [best].e_opcode) /* found it! */ - goto insn_found; - --best; - eop = probable_eop & eopMask [rs6k_ops [best].format]; - } - goto not_found; - } - - else if (eop > rs6k_ops [best].e_opcode) { - - while (pop == rs6k_ops [best].p_opcode) { - if (eop == rs6k_ops [best].e_opcode) /* found it! */ - goto insn_found; - ++best; - eop = probable_eop & eopMask [rs6k_ops [best].format]; - } - goto not_found; - } - - else /* eop == rs6k_ops [best].e_opcode */ - goto insn_found; - } - } - - best = min; - if (pop == rs6k_ops [best].p_opcode && - (rs6k_ops [best].e_opcode == -1 || rs6k_ops [best].e_opcode == eop)) - goto insn_found; - - else - goto not_found; - - -insn_found: - print_operator (stream, memaddr, the_insn, best); - return 4; - -not_found: - fprintf_unfiltered (stream, "0x%08x", the_insn); - return 4; -} - - - -/* condition code names */ -static char *cond_code [] = { - "lt", "gt", "eq", "so", "ge", "le", "ne", "ns", "nl", "ng", "z", "nz" }; - - -print_operator (stream, memaddr, insn_word, insn_no) -FILE *stream; -long memaddr; -long insn_word; -int insn_no; -{ - char buf [20]; - char *qq = buf; - char *pp = rs6k_ops[insn_no].opr_ext; - int tmp; - int nocomma = 0; /* true if no comma needed */ - - if (pp) { - while (*pp) { - - switch ( *pp ) { - case '.': - if (insn_word & 0x1) - *qq++ = '.'; - break; - - case 'l': - if (insn_word & 0x1) - *qq++ = 'l'; - break; - - case 't': - if ((insn_word & 0x03e00000) == 0x01800000) - *qq++ = 't'; - break; - - case 'f': - if ((insn_word & 0x03e00000) == 0x00800000) - *qq++ = 'f'; - break; - - case 'a': - if (insn_word & 0x2) - *qq++ = 'a'; - break; - - case 'o': - if (insn_word & 0x4000) - *qq++ = 'o'; - break; - - case '1': /* exception #1 for bb/bc ambiguity */ - tmp = (insn_word >> 21) & 0x1f; /* extract BO */ - if (tmp != 0xc && tmp != 0x4) { - /* you can't use `bb' now. switch to `bc' */ - *(qq-1) = 'c'; - ++insn_no; - pp = rs6k_ops[insn_no].opr_ext; - continue; - } - break; - - default: - abort (); - } - ++pp; - } - } - *qq = '\0'; - - fprintf_unfiltered (stream, "%s%s\t", rs6k_ops[insn_no].operator, buf); - - /* parse the operand now. */ - pp = rs6k_ops[insn_no].oprnd_format; - - while (*pp != 0) { - switch (*pp) { - case TO : - fprintf_unfiltered (stream, "%d", (insn_word >> 21) & 0x1f); - break; - - case RT : - case RS : - fprintf_unfiltered (stream, "r%d", (insn_word >> 21) & 0x1f); - break; - - case LI : - tmp = (insn_word >> 16) & 0x1f; -#if 0 - /* This is wrong, wrong, wrong. The condition code only goes - from 0 to 3 (for the instructions which can use extended - mnemonics of this type), and the XX (lt, gt, eq etc.) goes - into the mnemonic, not as an operand. - - Probably the best way to get this right in both assembler - and disassembler is to switch to a match/lose style opcode - table like the sparc. */ - if (tmp > 11) { - fprintf_unfiltered (stream, "{unknown cond code: 0x%x}", insn_word); - tmp = 0; - } - fprintf_unfiltered (stream, "%s", cond_code [tmp]); -#else - /* So for just always use the "bbf/bbt" form. This is perfectly - correct, just not necessarily as legible. - - If tmp is not in the range 0-3, we can't use an XX form anyway. */ - fprintf_unfiltered (stream, "%d", tmp); -#endif - break; - - case A2 : - case TA14 : - tmp = (insn_word & 0xfffc); - if (tmp & 0x8000) /* fix sign extension */ - tmp -= 0x10000; - - if ((insn_word & 0x2) == 0) /* if AA not set */ - tmp += memaddr; - - print_address (tmp, stream); - break; - - case TA24 : - tmp = insn_word & 0x03fffffc; - if (tmp & 0x2000000) - tmp -= 0x4000000; - - if ((insn_word & 0x2) == 0) /* if no AA bit set */ - tmp += memaddr; - - print_address (tmp, stream); - break; - - case LEV : /* for svc only */ - if (insn_word & 0x2) { /* SA is set */ - nocomma = 1; - } - else - fprintf_unfiltered (stream, "%d", (insn_word >> 5) & 0x7f); - break; - - case FL1 : /* for svc only */ - if (insn_word & 0x2) { /* SA is set */ - nocomma = 1; - } - else - fprintf_unfiltered (stream, "%d", (insn_word >> 12) & 0xf); - break; - - case FL2 : /* for svc only */ - nocomma = 0; - if (insn_word & 0x2) /* SA is set */ - fprintf_unfiltered (stream, "%d", (insn_word >> 2) & 0x3fff); - else - fprintf_unfiltered (stream, "%d", (insn_word >> 2) & 0x7); - break; - - case RA : - if (nocomma) { - fprintf_unfiltered (stream, "r%d)", (insn_word >> 16) & 0x1f); - nocomma = 0; - } - else - fprintf_unfiltered (stream, "r%d", (insn_word >> 16) & 0x1f); - break; - - case RB : - fprintf_unfiltered (stream, "r%d", (insn_word >> 11) & 0x1f); - break; - - case SI : - tmp = insn_word & 0xffff; - if (tmp & 0x8000) - tmp -= 0x10000; - fprintf_unfiltered (stream, "%d", tmp); - break; - - case UI : - fprintf_unfiltered (stream, "%d", insn_word & 0xffff); - break; - - case BF : - fprintf_unfiltered (stream, "%d", (insn_word >> 23) & 0x7); - break; - - case BFA : - fprintf_unfiltered (stream, "%d", (insn_word >> 18) & 0x7); - break; - - case BT : - fprintf_unfiltered (stream, "%d", (insn_word >> 21) & 0x1f); - break; - - case BA : - fprintf_unfiltered (stream, "%d", (insn_word >> 16) & 0x1f); - break; - - case BB : - fprintf_unfiltered (stream, "%d", (insn_word >> 11) & 0x1f); - break; - - case BO : - fprintf_unfiltered (stream, "%d", (insn_word >> 21) & 0x1f); - break; - - case BI : - fprintf_unfiltered (stream, "%d", (insn_word >> 16) & 0x1f); - break; - - case SH : - fprintf_unfiltered (stream, "%d", (insn_word >> 11) & 0x1f); - break; - - case MB : - fprintf_unfiltered (stream, "0x%x", (insn_word >> 6) & 0x1f); - break; - - case ME : - fprintf_unfiltered (stream, "0x%x", (insn_word >> 1) & 0x1f); - break; - - case SPR : - fprintf_unfiltered (stream, "%d", (insn_word >> 16) & 0x1f); - break; - - case DIS : - nocomma = 1; - tmp = insn_word & 0xffff; - if (tmp & 0x8000) - tmp -= 0x10000; - fprintf_unfiltered (stream, "%d(", tmp); - break; - - case FXM : - fprintf_unfiltered (stream, "0x%x", (insn_word >> 12) & 0xff); - break; - - case FRT : - case FRS : - fprintf_unfiltered (stream, "f%d", (insn_word >> 21) & 0x1f); - break; - - case FRA : - fprintf_unfiltered (stream, "f%d", (insn_word >> 16) & 0x1f); - break; - - case FRB : - fprintf_unfiltered (stream, "f%d", (insn_word >> 11) & 0x1f); - break; - - case FRC : - fprintf_unfiltered (stream, "f%d", (insn_word >> 6) & 0x1f); - break; - - case FLM : - fprintf_unfiltered (stream, "0x%x", (insn_word >> 17) & 0xff); - break; - - case NB : - fprintf_unfiltered (stream, "%d", (insn_word >> 11) & 0x1f); - break; - - case I : - fprintf_unfiltered (stream, "%d", (insn_word >> 12) & 0xf); - break; - - default : - fprintf_unfiltered (stream, - "{Internal error: Unknown operand format identifier %d}", - *pp); - } - ++pp; - - if (*pp != '\0' && !nocomma) - fputc_unfiltered(',', stream); - } + return print_insn_rs6000 ((bfd_vma) memaddr, &info); } -- 2.34.1