mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-31 14:04:12 +00:00
* m88k-dis.c: New file, moved in from gdb and changed to use the
new dis-asm.h disassembler interface. * Makefile.in (DIS_LIBS): Added m88k-dis.o. (m88k-dis.o): New target.
This commit is contained in:
parent
77a401e2e0
commit
a4c0129924
@ -38,6 +38,7 @@ i386-dis.c
|
||||
i960-dis.c
|
||||
m68881-ext.c
|
||||
m68k-dis.c
|
||||
m88k-dis.c
|
||||
mips-dis.c
|
||||
sh-opc.h
|
||||
sh-dis.c
|
||||
|
@ -1,3 +1,10 @@
|
||||
Thu Jul 15 12:37:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
|
||||
|
||||
* m88k-dis.c: New file, moved in from gdb and changed to use the
|
||||
new dis-asm.h disassembler interface.
|
||||
* Makefile.in (DIS_LIBS): Added m88k-dis.o.
|
||||
(m88k-dis.o): New target.
|
||||
|
||||
Tue Jul 13 10:04:16 1993 Ian Lance Taylor (ian@cygnus.com)
|
||||
|
||||
* mips-dis.c (print_insn_arg, _print_insn_mips): Made pointer to
|
||||
|
@ -63,8 +63,10 @@ TARGETLIB = libopcodes.a
|
||||
|
||||
# To circumvent a Sun make VPATH bug, each file listed here
|
||||
# should also have a foo.o: foo.c line further along in this file.
|
||||
DIS_LIBS = i386-dis.o z8k-dis.o m68k-dis.o mips-dis.o h8500-dis.o h8300-dis.o dis-buf.o \
|
||||
sparc-dis.o a29k-dis.o i960-dis.o alpha-dis.o sh-dis.o hppa-dis.o
|
||||
|
||||
DIS_LIBS = i386-dis.o z8k-dis.o m68k-dis.o mips-dis.o h8500-dis.o \
|
||||
h8300-dis.o dis-buf.o sparc-dis.o a29k-dis.o i960-dis.o \
|
||||
alpha-dis.o sh-dis.o hppa-dis.o m88k-dis.o
|
||||
|
||||
OFILES = $(DIS_LIBS) sparc-opc.o m68881-ext.o
|
||||
#### host and target dependent Makefile fragments come in here.
|
||||
@ -128,6 +130,7 @@ z8k-dis.o: z8k-dis.c z8k-opc.h $(INCDIR)/dis-asm.h
|
||||
sh-dis.o: sh-dis.c sh-opc.h $(INCDIR)/dis-asm.h
|
||||
alpha-dis.o: alpha-dis.c alpha-opc.h $(INCDIR)/dis-asm.h
|
||||
hppa-dis.o: hppa-dis.c $(INCDIR)/dis-asm.h $(INCDIR)/opcode/hppa.h
|
||||
m88k-dis.o: m88k-dis.c $(INCDIR)/dis-asm.h $(INCDIR)/opcode/m88k.h
|
||||
|
||||
tags etags: TAGS
|
||||
|
||||
|
321
opcodes/m88k-dis.c
Normal file
321
opcodes/m88k-dis.c
Normal file
@ -0,0 +1,321 @@
|
||||
/* Print instructions for the Motorola 88000, for GDB and GNU Binutils.
|
||||
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1993
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Data General Corporation, November 1989.
|
||||
Partially derived from an earlier printcmd.c.
|
||||
|
||||
This file is part of GDB and the GNU Binutils.
|
||||
|
||||
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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
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. */
|
||||
|
||||
#include "dis-asm.h"
|
||||
#include "opcode/m88k.h"
|
||||
|
||||
/* FIXME: Uses the internal bfd swapping routines. */
|
||||
#include "libbfd.h"
|
||||
|
||||
INSTAB *hashtable[HASHVAL] = {0};
|
||||
|
||||
static int
|
||||
m88kdis PARAMS ((bfd_vma, unsigned long, struct disassemble_info *));
|
||||
|
||||
static void
|
||||
printop PARAMS ((struct disassemble_info *, OPSPEC *,
|
||||
unsigned long, bfd_vma, int));
|
||||
|
||||
static void
|
||||
init_disasm PARAMS ((void));
|
||||
|
||||
static void
|
||||
install PARAMS ((INSTAB *instptr));
|
||||
|
||||
/*
|
||||
* Disassemble an M88000 Instruction
|
||||
*
|
||||
*
|
||||
* This module decodes the instruction at memaddr.
|
||||
*
|
||||
* Revision History
|
||||
*
|
||||
* Revision 1.0 11/08/85 Creation date by Motorola
|
||||
* 05/11/89 R. Trawick adapted to GDB interface.
|
||||
* 07/12/93 Ian Lance Taylor updated to
|
||||
* binutils interface.
|
||||
*/
|
||||
|
||||
int
|
||||
print_insn_m88k (memaddr, info)
|
||||
bfd_vma memaddr;
|
||||
struct disassemble_info *info;
|
||||
{
|
||||
bfd_byte buffer[4];
|
||||
int status;
|
||||
|
||||
/* Instruction addresses may have low two bits set. Clear them. */
|
||||
memaddr &=~ (bfd_vma) 3;
|
||||
|
||||
status = (*info->read_memory_func) (memaddr, buffer, 4, info);
|
||||
if (status != 0)
|
||||
{
|
||||
(*info->memory_error_func) (status, memaddr, info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return m88kdis (memaddr, _do_getb32 (buffer), info);
|
||||
}
|
||||
|
||||
/*
|
||||
* disassemble the instruction in 'instruction'.
|
||||
* 'pc' should be the address of this instruction, it will
|
||||
* be used to print the target address if this is a relative jump or call
|
||||
* the disassembled instruction is written to 'info'.
|
||||
* The function returns the length of this instruction in bytes.
|
||||
*/
|
||||
|
||||
static int
|
||||
m88kdis (pc, instruction, info)
|
||||
bfd_vma pc;
|
||||
unsigned long instruction;
|
||||
struct disassemble_info *info;
|
||||
{
|
||||
static int ihashtab_initialized = 0;
|
||||
unsigned int opcode;
|
||||
INSTAB *entry_ptr;
|
||||
int opmask;
|
||||
int class;
|
||||
|
||||
if (! ihashtab_initialized)
|
||||
init_disasm ();
|
||||
|
||||
/* create a the appropriate mask to isolate the opcode */
|
||||
opmask = DEFMASK;
|
||||
class = instruction & DEFMASK;
|
||||
if ((class >= SFU0) && (class <= SFU7))
|
||||
{
|
||||
if (instruction < SFU1)
|
||||
opmask = CTRLMASK;
|
||||
else
|
||||
opmask = SFUMASK;
|
||||
}
|
||||
else if (class == RRR)
|
||||
opmask = RRRMASK;
|
||||
else if (class == RRI10)
|
||||
opmask = RRI10MASK;
|
||||
|
||||
/* isolate the opcode */
|
||||
opcode = instruction & opmask;
|
||||
|
||||
/* search the hash table with the isolated opcode */
|
||||
for (entry_ptr = hashtable[opcode % HASHVAL];
|
||||
(entry_ptr != NULL) && (entry_ptr->opcode != opcode);
|
||||
entry_ptr = entry_ptr->next)
|
||||
;
|
||||
|
||||
if (entry_ptr == NULL)
|
||||
(*info->fprintf_func) (info->stream, "word\t%08x", instruction);
|
||||
else
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "%s ", entry_ptr->mnemonic);
|
||||
printop (info, &(entry_ptr->op1), instruction, pc, 1);
|
||||
printop (info, &(entry_ptr->op2), instruction, pc, 0);
|
||||
printop (info, &(entry_ptr->op3), instruction, pc, 0);
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode an Operand of an Instruction
|
||||
*
|
||||
* Functional Description
|
||||
*
|
||||
* This module formats and writes an operand of an instruction to info
|
||||
* based on the operand specification. When the first flag is set this
|
||||
* is the first operand of an instruction. Undefined operand types
|
||||
* cause a <dis error> message.
|
||||
*
|
||||
* Parameters
|
||||
* disassemble_info where the operand may be printed
|
||||
* OPSPEC *opptr Pointer to an operand specification
|
||||
* UINT inst Instruction from which operand is extracted
|
||||
* UINT pc PC of instruction; used for pc-relative disp.
|
||||
* int first Flag which if nonzero indicates the first
|
||||
* operand of an instruction
|
||||
*
|
||||
* Output
|
||||
*
|
||||
* The operand specified is extracted from the instruction and is
|
||||
* written to buf in the format specified. The operand is preceded
|
||||
* by a comma if it is not the first operand of an instruction and it
|
||||
* is not a register indirect form. Registers are preceded by 'r' and
|
||||
* hex values by '0x'.
|
||||
*
|
||||
* Revision History
|
||||
*
|
||||
* Revision 1.0 11/08/85 Creation date
|
||||
*/
|
||||
|
||||
static void
|
||||
printop (info, opptr, inst, pc, first)
|
||||
struct disassemble_info *info;
|
||||
OPSPEC *opptr;
|
||||
unsigned long inst;
|
||||
bfd_vma pc;
|
||||
int first;
|
||||
{
|
||||
int extracted_field;
|
||||
char *cond_mask_sym;
|
||||
|
||||
if (opptr->width == 0)
|
||||
return;
|
||||
|
||||
if (! first)
|
||||
{
|
||||
switch (opptr->type)
|
||||
{
|
||||
case REGSC:
|
||||
case CONT:
|
||||
break;
|
||||
default:
|
||||
(*info->fprintf_func) (info->stream, ",");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (opptr->type)
|
||||
{
|
||||
case CRREG:
|
||||
(*info->fprintf_func) (info->stream, "cr%d",
|
||||
UEXT (inst, opptr->offset, opptr->width));
|
||||
break;
|
||||
|
||||
case FCRREG:
|
||||
(*info->fprintf_func) (info->stream, "fcr%d",
|
||||
UEXT (inst, opptr->offset, opptr->width));
|
||||
break;
|
||||
|
||||
case REGSC:
|
||||
(*info->fprintf_func) (info->stream, "[r%d]",
|
||||
UEXT (inst, opptr->offset, opptr->width));
|
||||
break;
|
||||
|
||||
case REG:
|
||||
(*info->fprintf_func) (info->stream, "r%d",
|
||||
UEXT (inst, opptr->offset, opptr->width));
|
||||
break;
|
||||
|
||||
case HEX:
|
||||
extracted_field = UEXT (inst, opptr->offset, opptr->width);
|
||||
if (extracted_field == 0)
|
||||
(*info->fprintf_func) (info->stream, "0");
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "0x%02x", extracted_field);
|
||||
break;
|
||||
|
||||
case CONDMASK:
|
||||
extracted_field = UEXT (inst, opptr->offset, opptr->width);
|
||||
switch (extracted_field & 0x0f)
|
||||
{
|
||||
case 0x1: cond_mask_sym = "gt0"; break;
|
||||
case 0x2: cond_mask_sym = "eq0"; break;
|
||||
case 0x3: cond_mask_sym = "ge0"; break;
|
||||
case 0xc: cond_mask_sym = "lt0"; break;
|
||||
case 0xd: cond_mask_sym = "ne0"; break;
|
||||
case 0xe: cond_mask_sym = "le0"; break;
|
||||
default: cond_mask_sym = NULL; break;
|
||||
}
|
||||
if (cond_mask_sym != NULL)
|
||||
(*info->fprintf_func) (info->stream, "%s", cond_mask_sym);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "%x", extracted_field);
|
||||
break;
|
||||
|
||||
case PCREL:
|
||||
(*info->print_address_func)
|
||||
(pc + (4 * (SEXT (inst, opptr->offset, opptr->width))),
|
||||
info);
|
||||
break;
|
||||
|
||||
case CONT:
|
||||
(*info->fprintf_func) (info->stream, "%d,r%d",
|
||||
UEXT (inst, opptr->offset, 5),
|
||||
UEXT (inst, (opptr->offset) + 5, 5));
|
||||
break;
|
||||
|
||||
case BF:
|
||||
(*info->fprintf_func) (info->stream, "%d<%d>",
|
||||
UEXT (inst, (opptr->offset) + 5, 5),
|
||||
UEXT (inst, opptr->offset, 5));
|
||||
break;
|
||||
|
||||
default:
|
||||
(*info->fprintf_func) (info->stream, "# <dis error: %08x>", inst);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the Disassembler Instruction Table
|
||||
*
|
||||
* Initialize the hash table and instruction table for the disassembler.
|
||||
* This should be called once before the first call to disasm().
|
||||
*
|
||||
* Parameters
|
||||
*
|
||||
* Output
|
||||
*
|
||||
* If the debug option is selected, certain statistics about the hashing
|
||||
* distribution are written to stdout.
|
||||
*
|
||||
* Revision History
|
||||
*
|
||||
* Revision 1.0 11/08/85 Creation date
|
||||
*/
|
||||
|
||||
static void
|
||||
init_disasm ()
|
||||
{
|
||||
int i, size;
|
||||
|
||||
for (i = 0; i < HASHVAL; i++)
|
||||
hashtable[i] = NULL;
|
||||
|
||||
size = sizeof (instructions) / sizeof (INSTAB);
|
||||
for (i = 0; i < size; i++)
|
||||
install (&instructions[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert an instruction into the disassembler table by hashing the
|
||||
* opcode and inserting it into the linked list for that hash value.
|
||||
*
|
||||
* Parameters
|
||||
*
|
||||
* INSTAB *instptr Pointer to the entry in the instruction table
|
||||
* to be installed
|
||||
*
|
||||
* Revision 1.0 11/08/85 Creation date
|
||||
* 05/11/89 R. TRAWICK ADAPTED FROM MOTOROLA
|
||||
*/
|
||||
|
||||
static void
|
||||
install (instptr)
|
||||
INSTAB *instptr;
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
i = (instptr->opcode) % HASHVAL;
|
||||
instptr->next = hashtable[i];
|
||||
hashtable[i] = instptr;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user