mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
Make it run on wingnut (88k, DGUX). Complete list of changes in the ChangeLog.
This commit is contained in:
parent
6f48f7f198
commit
8aa13b8777
@ -28,7 +28,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "bfd.h"
|
||||
#include "symfile.h"
|
||||
|
||||
#if defined (TDESC)
|
||||
/* Need to get C_VERSION and friends. */
|
||||
#include <a.out.h>
|
||||
#else /* not TDESC */
|
||||
#include <intel-coff.h>
|
||||
#endif /* not TDESC */
|
||||
|
||||
#include <obstack.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -129,13 +135,17 @@ static int prev_line_number;
|
||||
static int line_vector_length;
|
||||
|
||||
#ifdef TDESC
|
||||
#include "tdesc.h"
|
||||
#define SEM
|
||||
int int_sem_val = 's' << 24 | 'e' << 16 | 'm' << 8 | '.';
|
||||
int temp_sem_val;
|
||||
int last_coffsem = 2;
|
||||
#if 0
|
||||
/* This isn't used currently. */
|
||||
int last_coffsyn = 0;
|
||||
#endif
|
||||
int debug_info = 0; /*used by tdesc */
|
||||
extern int tdesc_handle;
|
||||
extern dc_dcontext_t tdesc_handle;
|
||||
extern int safe_to_init_tdesc_context;
|
||||
#endif
|
||||
|
||||
@ -429,7 +439,10 @@ start_symtab ()
|
||||
last_source_file = 0;
|
||||
#ifdef TDESC
|
||||
last_coffsem = 2;
|
||||
#if 0
|
||||
/* This isn't used currently. */
|
||||
last_coffsyn = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Initialize the source file information for this file. */
|
||||
@ -530,7 +543,11 @@ end_symtab ()
|
||||
|
||||
#ifdef TDESC
|
||||
symtab->coffsem = last_coffsem;
|
||||
#if 0
|
||||
/* This isn't used currently. Besides, if this is really about "syntax",
|
||||
it shouldn't need to stick around past symbol read-in time. */
|
||||
symtab->coffsyn = last_coffsyn;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
free_named_symtabs (symtab->filename);
|
||||
@ -651,6 +668,21 @@ find_linenos (abfd, asect, vpinfo)
|
||||
maxoff = offset + size;
|
||||
if (maxoff > info->max_lineno_offset)
|
||||
info->max_lineno_offset = maxoff;
|
||||
#ifdef TDESC
|
||||
/* While we're at it, find the debug_info. It's in the s_relptr
|
||||
(or, in BFD-speak, rel_filepos) of the text segment section header. */
|
||||
if (strcmp (bfd_section_name (abfd, asect), ".text") == 0)
|
||||
{
|
||||
/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
|
||||
debug_info = asect->rel_filepos;
|
||||
/* End of warning */
|
||||
if (tdesc_handle)
|
||||
{
|
||||
dc_terminate (tdesc_handle);
|
||||
tdesc_handle = 0;
|
||||
}
|
||||
}
|
||||
#endif /* TDESC */
|
||||
}
|
||||
|
||||
|
||||
@ -687,15 +719,6 @@ coff_symfile_read (sf, addr, mainline)
|
||||
stringtab_offset = symtab_offset + num_symbols * SYMESZ; /* String tab */
|
||||
/* End of warning */
|
||||
|
||||
#ifdef TDESC
|
||||
debug_info = text_hdr.s_relptr;
|
||||
if (tdesc_handle)
|
||||
{
|
||||
dc_terminate (tdesc_handle);
|
||||
tdesc_handle = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Read the line number table, all at once. */
|
||||
info->min_lineno_offset = 0;
|
||||
info->max_lineno_offset = 0;
|
||||
@ -1047,13 +1070,17 @@ read_coff_symtab (desc, nsyms)
|
||||
break;
|
||||
#ifdef TDESC
|
||||
case C_VERSION:
|
||||
#if 0
|
||||
/* This isn't used currently. */
|
||||
if (strcmp (cs->c_name, ".coffsyn") == 0)
|
||||
last_coffsyn = cs->c_value;
|
||||
else if ((strcmp (cs->c_name, ".coffsem") == 0) &&
|
||||
else
|
||||
#endif /* 0 */
|
||||
if ((strcmp (cs->c_name, ".coffsem") == 0) &&
|
||||
(cs->c_value != 0))
|
||||
last_coffsem = cs->c_value;
|
||||
break;
|
||||
#endif
|
||||
#endif /* TDESC */
|
||||
|
||||
default:
|
||||
#ifdef TDESC
|
||||
@ -1255,8 +1282,14 @@ getfilename (aux_entry)
|
||||
extern char *rindex ();
|
||||
|
||||
#ifndef COFF_NO_LONG_FILE_NAMES
|
||||
#if defined (x_zeroes)
|
||||
/* Data General. */
|
||||
if (aux_entry->x_zeroes == 0)
|
||||
strcpy (buffer, stringtab + aux_entry->x_offset);
|
||||
#else /* no x_zeroes */
|
||||
if (aux_entry->x_file.x_n.x_zeroes == 0)
|
||||
strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_offset);
|
||||
#endif /* no x_zeroes */
|
||||
else
|
||||
#endif /* COFF_NO_LONG_FILE_NAMES */
|
||||
{
|
||||
@ -1711,11 +1744,14 @@ decode_base_type (cs, c_type, aux)
|
||||
/* shows up with "void (*foo)();" structure members */
|
||||
return builtin_type_void;
|
||||
|
||||
#if 0
|
||||
/* DGUX actually defines both T_ARG and T_VOID to the same value. */
|
||||
#ifdef T_ARG
|
||||
case T_ARG:
|
||||
/* Shows up in DGUX, I think. Not sure where. */
|
||||
return builtin_type_void; /* shouldn't show up here */
|
||||
#endif
|
||||
#endif /* 0 */
|
||||
|
||||
#ifdef T_VOID
|
||||
case T_VOID:
|
||||
@ -1994,7 +2030,15 @@ read_enum_type (index, length, lastsym)
|
||||
|
||||
static struct sym_fns coff_sym_fns =
|
||||
{
|
||||
/* This assumes that 88kbcs implies TDESC and TDESC implies 88kbcs.
|
||||
If that's not true, this can be relaxed, but if it is true,
|
||||
it will just cause users grief if we try to read the wrong kind
|
||||
of symbol file. */
|
||||
#if defined (TDESC)
|
||||
"m88kbcs", 8,
|
||||
#else /* not TDESC */
|
||||
"coff", 4,
|
||||
#endif /* not TDESC */
|
||||
coff_new_init, coff_symfile_init,
|
||||
coff_symfile_read, coff_symfile_discard
|
||||
};
|
||||
|
585
gdb/m88k-opcode.h
Executable file
585
gdb/m88k-opcode.h
Executable file
@ -0,0 +1,585 @@
|
||||
/* This file has been modified by Data General Corporation, November 1989. */
|
||||
|
||||
|
||||
/*
|
||||
* Disassembler Instruction Table
|
||||
*
|
||||
* The first field of the table is the opcode field. If an opcode
|
||||
* is specified which has any non-opcode bits on, a system error
|
||||
* will occur when the system attempts the install it into the
|
||||
* instruction table. The second parameter is a pointer to the
|
||||
* instruction mnemonic. Each operand is specified by offset, width,
|
||||
* and type. The offset is the bit number of the least significant
|
||||
* bit of the operand with bit 0 being the least significant bit of
|
||||
* the instruction. The width is the number of bits used to specify
|
||||
* the operand. The type specifies the output format to be used for
|
||||
* the operand. The valid formats are: register, register indirect,
|
||||
* hex constant, and bit field specification. The last field is a
|
||||
* pointer to the next instruction in the linked list. These pointers
|
||||
* are initialized by init_disasm().
|
||||
*
|
||||
* Structure Format
|
||||
*
|
||||
* struct INSTAB {
|
||||
* UPINT opcode;
|
||||
* char *mnemonic;
|
||||
* struct OPSPEC op1,op2,op3;
|
||||
* struct SIM_FLAGS flgs;
|
||||
* struct INSTAB *next;
|
||||
* }
|
||||
*
|
||||
* struct OPSPEC {
|
||||
* UPINT offset:5;
|
||||
* UPINT width:6;
|
||||
* UPINT type:5;
|
||||
* }
|
||||
*
|
||||
* Revision History
|
||||
*
|
||||
* Revision 1.0 11/08/85 Creation date
|
||||
* 1.1 02/05/86 Updated instruction mnemonic table MD
|
||||
* 1.2 06/16/86 Updated SIM_FLAGS for floating point
|
||||
* 1.3 09/20/86 Updated for new encoding
|
||||
* 05/11/89 R. Trawick adapted from Motorola disassembler
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the structures and constants needed to build the M88000
|
||||
* simulator. It is the main include file, containing all the
|
||||
* structures, macros and definitions except for the floating point
|
||||
* instruction set.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following flag informs the Simulator as to what type of byte ordering
|
||||
* will be used. For instance, a BOFLAG = 1 indicates a DEC VAX and IBM type
|
||||
* of ordering shall be used.
|
||||
*/
|
||||
|
||||
/* # define BOFLAG 1 /* BYTE ORDERING FLAG */
|
||||
|
||||
/* define the number of bits in the primary opcode field of the instruction,
|
||||
* the destination field, the source 1 and source 2 fields.
|
||||
*/
|
||||
# define OP 8 /* size of opcode field */
|
||||
# define DEST 6 /* size of destination */
|
||||
# define SOURCE1 6 /* size of source1 */
|
||||
# define SOURCE2 6 /* size of source2 */
|
||||
|
||||
# define REGs 32 /* number of registers */
|
||||
|
||||
# define WORD long
|
||||
# define FLAG unsigned
|
||||
# define STATE short
|
||||
|
||||
# define TRUE 1
|
||||
# define FALSE 0
|
||||
|
||||
# define READ 0
|
||||
# define WRITE 1
|
||||
|
||||
/* The next four equates define the priorities that the various classes
|
||||
* of instructions have regarding writing results back into registers and
|
||||
* signalling exceptions.
|
||||
*/
|
||||
|
||||
# define PINT 0 /* Integer Priority */
|
||||
# define PFLT 1 /* Floating Point Priority */
|
||||
# define PMEM 2 /* Memory Priority */
|
||||
# define NA 3 /* Not Applicable, instruction doesnt write to regs */
|
||||
# define HIPRI 3 /* highest of these priorities */
|
||||
|
||||
/* The instruction registers are an artificial mechanism to speed up
|
||||
* simulator execution. In the real processor, an instruction register
|
||||
* is 32 bits wide. In the simulator, the 32 bit instruction is kept in
|
||||
* a structure field called rawop, and the instruction is partially decoded,
|
||||
* and split into various fields and flags which make up the other fields
|
||||
* of the structure.
|
||||
* The partial decode is done when the instructions are initially loaded
|
||||
* into simulator memory. The simulator code memory is not an array of
|
||||
* 32 bit words, but is an array of instruction register structures.
|
||||
* Yes this wastes memory, but it executes much quicker.
|
||||
*/
|
||||
|
||||
struct IR_FIELDS {
|
||||
unsigned long op:OP,
|
||||
dest: DEST,
|
||||
src1: SOURCE1,
|
||||
src2: SOURCE2;
|
||||
int ltncy,
|
||||
extime,
|
||||
wb_pri; /* writeback priority */
|
||||
unsigned short imm_flags:2,/* immediate size */
|
||||
rs1_used:1, /* register source 1 used */
|
||||
rs2_used:1, /* register source 2 used */
|
||||
rsd_used:1, /* register source/dest. used */
|
||||
c_flag:1, /* complement */
|
||||
u_flag:1, /* upper half word */
|
||||
n_flag:1, /* execute next */
|
||||
wb_flag:1, /* uses writeback slot */
|
||||
dest_64:1, /* dest size */
|
||||
s1_64:1, /* source 1 size */
|
||||
s2_64:1, /* source 2 size */
|
||||
scale_flag:1, /* scaled register */
|
||||
brk_flg:1;
|
||||
};
|
||||
|
||||
struct mem_segs {
|
||||
struct mem_wrd *seg; /* pointer (returned by calloc) to segment */
|
||||
unsigned long baseaddr; /* base load address from file headers */
|
||||
unsigned long endaddr; /* Ending address of segment */
|
||||
int flags; /* segment control flags (none defined 12/5/86) */
|
||||
};
|
||||
|
||||
#define MAXSEGS (10) /* max number of segment allowed */
|
||||
#define MEMSEGSIZE (sizeof(struct mem_segs))/* size of mem_segs structure */
|
||||
|
||||
|
||||
#define BRK_RD (0x01) /* break on memory read */
|
||||
#define BRK_WR (0x02) /* break on memory write */
|
||||
#define BRK_EXEC (0x04) /* break on execution */
|
||||
#define BRK_CNT (0x08) /* break on terminal count */
|
||||
|
||||
|
||||
struct mem_wrd {
|
||||
struct IR_FIELDS opcode; /* simulator instruction break down */
|
||||
union {
|
||||
unsigned long l; /* memory element break down */
|
||||
unsigned short s[2];
|
||||
unsigned char c[4];
|
||||
} mem;
|
||||
};
|
||||
|
||||
#define MEMWRDSIZE (sizeof(struct mem_wrd)) /* size of each 32 bit memory model */
|
||||
|
||||
/* External declarations */
|
||||
|
||||
extern struct mem_segs memory[];
|
||||
extern struct PROCESSOR m78000;
|
||||
|
||||
struct PROCESSOR {
|
||||
unsigned WORD
|
||||
ip, /* execute instruction pointer */
|
||||
vbr, /* vector base register */
|
||||
psr; /* processor status register */
|
||||
|
||||
WORD S1bus, /* source 1 */
|
||||
S2bus, /* source 2 */
|
||||
Dbus, /* destination */
|
||||
DAbus, /* data address bus */
|
||||
ALU,
|
||||
Regs[REGs], /* data registers */
|
||||
time_left[REGs], /* max clocks before reg is available */
|
||||
wb_pri[REGs], /* writeback priority of reg */
|
||||
SFU0_regs[REGs], /* integer unit control regs */
|
||||
SFU1_regs[REGs], /* floating point control regs */
|
||||
Scoreboard[REGs],
|
||||
Vbr;
|
||||
unsigned WORD scoreboard,
|
||||
Psw,
|
||||
Tpsw;
|
||||
FLAG jump_pending:1; /* waiting for a jump instr. */
|
||||
};
|
||||
|
||||
# define i26bit 1 /* size of immediate field */
|
||||
# define i16bit 2
|
||||
# define i10bit 3
|
||||
|
||||
/* Definitions for fields in psr */
|
||||
|
||||
# define mode 31
|
||||
# define rbo 30
|
||||
# define ser 29
|
||||
# define carry 28
|
||||
# define sf7m 11
|
||||
# define sf6m 10
|
||||
# define sf5m 9
|
||||
# define sf4m 8
|
||||
# define sf3m 7
|
||||
# define sf2m 6
|
||||
# define sf1m 5
|
||||
# define mam 4
|
||||
# define inm 3
|
||||
# define exm 2
|
||||
# define trm 1
|
||||
# define ovfm 0
|
||||
|
||||
#define MODEMASK (1<<(mode-1))
|
||||
# define SILENT 0 /* simulate without output to crt */
|
||||
# define VERBOSE 1 /* simulate in verbose mode */
|
||||
# define PR_INSTR 2 /* only print instructions */
|
||||
|
||||
# define RESET 16 /* reset phase */
|
||||
|
||||
# define PHASE1 0 /* data path phases */
|
||||
# define PHASE2 1
|
||||
|
||||
/* the 1 clock operations */
|
||||
|
||||
# define ADDU 1
|
||||
# define ADDC 2
|
||||
# define ADDUC 3
|
||||
# define ADD 4
|
||||
|
||||
# define SUBU ADD+1
|
||||
# define SUBB ADD+2
|
||||
# define SUBUB ADD+3
|
||||
# define SUB ADD+4
|
||||
|
||||
# define AND ADD+5
|
||||
# define OR ADD+6
|
||||
# define XOR ADD+7
|
||||
# define CMP ADD+8
|
||||
|
||||
/* the LOADS */
|
||||
|
||||
# define LDAB CMP+1
|
||||
# define LDAH CMP+2
|
||||
# define LDA CMP+3
|
||||
# define LDAD CMP+4
|
||||
|
||||
# define LDB LDAD+1
|
||||
# define LDH LDAD+2
|
||||
# define LD LDAD+3
|
||||
# define LDD LDAD+4
|
||||
# define LDBU LDAD+5
|
||||
# define LDHU LDAD+6
|
||||
|
||||
/* the STORES */
|
||||
|
||||
# define STB LDHU+1
|
||||
# define STH LDHU+2
|
||||
# define ST LDHU+3
|
||||
# define STD LDHU+4
|
||||
|
||||
/* the exchange */
|
||||
|
||||
# define XMEMBU LDHU+5
|
||||
# define XMEM LDHU+6
|
||||
|
||||
/* the branches */
|
||||
# define JSR STD+1
|
||||
# define BSR STD+2
|
||||
# define BR STD+3
|
||||
# define JMP STD+4
|
||||
# define BB1 STD+5
|
||||
# define BB0 STD+6
|
||||
# define RTN STD+7
|
||||
# define BCND STD+8
|
||||
|
||||
/* the TRAPS */
|
||||
# define TB1 BCND+1
|
||||
# define TB0 BCND+2
|
||||
# define TCND BCND+3
|
||||
# define RTE BCND+4
|
||||
# define TBND BCND+5
|
||||
|
||||
/* the MISC instructions */
|
||||
# define MUL TBND + 1
|
||||
# define DIV MUL +2
|
||||
# define DIVU MUL +3
|
||||
# define MASK MUL +4
|
||||
# define FF0 MUL +5
|
||||
# define FF1 MUL +6
|
||||
# define CLR MUL +7
|
||||
# define SET MUL +8
|
||||
# define EXT MUL +9
|
||||
# define EXTU MUL +10
|
||||
# define MAK MUL +11
|
||||
# define ROT MUL +12
|
||||
|
||||
/* control register manipulations */
|
||||
|
||||
# define LDCR ROT +1
|
||||
# define STCR ROT +2
|
||||
# define XCR ROT +3
|
||||
|
||||
# define FLDCR ROT +4
|
||||
# define FSTCR ROT +5
|
||||
# define FXCR ROT +6
|
||||
|
||||
|
||||
# define NOP XCR +1
|
||||
|
||||
/* floating point instructions */
|
||||
|
||||
# define FADD NOP +1
|
||||
# define FSUB NOP +2
|
||||
# define FMUL NOP +3
|
||||
# define FDIV NOP +4
|
||||
# define FSQRT NOP +5
|
||||
# define FCMP NOP +6
|
||||
# define FIP NOP +7
|
||||
# define FLT NOP +8
|
||||
# define INT NOP +9
|
||||
# define NINT NOP +10
|
||||
# define TRNC NOP +11
|
||||
# define FLDC NOP +12
|
||||
# define FSTC NOP +13
|
||||
# define FXC NOP +14
|
||||
|
||||
# define UEXT(src,off,wid) ((((unsigned int)(src))>>(off)) & ((1<<(wid)) - 1))
|
||||
# define SEXT(src,off,wid) (((((int)(src))<<(32-((off)+(wid)))) >>(32-(wid))) )
|
||||
# define MAKE(src,off,wid) \
|
||||
((((unsigned int)(src)) & ((1<<(wid)) - 1)) << (off))
|
||||
|
||||
# define opword(n) (unsigned long) (memaddr->mem.l)
|
||||
|
||||
/* Constants and Masks */
|
||||
|
||||
#define SFU0 0x80000000
|
||||
#define SFU1 0x84000000
|
||||
#define SFU7 0x9c000000
|
||||
#define RRI10 0xf0000000
|
||||
#define RRR 0xf4000000
|
||||
#define SFUMASK 0xfc00ffe0
|
||||
#define RRRMASK 0xfc00ffe0
|
||||
#define RRI10MASK 0xfc00fc00
|
||||
#define DEFMASK 0xfc000000
|
||||
#define CTRL 0x0000f000
|
||||
#define CTRLMASK 0xfc00f800
|
||||
|
||||
/* Operands types */
|
||||
|
||||
#define HEX 1
|
||||
#define REG 2
|
||||
#define IND 3
|
||||
#define CONT 3
|
||||
#define IND 3
|
||||
#define BF 4
|
||||
#define REGSC 5 /* scaled register */
|
||||
#define CRREG 6 /* control register */
|
||||
#define FCRREG 7 /* floating point control register */
|
||||
#define PCREL 8
|
||||
#define CONDMASK 9
|
||||
|
||||
/* Hashing Specification */
|
||||
|
||||
#define HASHVAL 79
|
||||
|
||||
/* Type definitions */
|
||||
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* Structure templates */
|
||||
|
||||
typedef struct {
|
||||
unsigned int offset:5;
|
||||
unsigned int width:6;
|
||||
unsigned int type:5;
|
||||
} OPSPEC;
|
||||
|
||||
struct SIM_FLAGS {
|
||||
int ltncy, /* latency (max number of clocks needed to execute) */
|
||||
extime, /* execution time (min number of clocks needed to execute) */
|
||||
wb_pri; /* writeback slot priority */
|
||||
unsigned long op:OP, /* simulator version of opcode */
|
||||
imm_flags:2, /* 10,16 or 26 bit immediate flags */
|
||||
rs1_used:1, /* register source 1 used */
|
||||
rs2_used:1, /* register source 2 used */
|
||||
rsd_used:1, /* register source/dest used */
|
||||
c_flag:1, /* complement */
|
||||
u_flag:1, /* upper half word */
|
||||
n_flag:1, /* execute next */
|
||||
wb_flag:1, /* uses writeback slot */
|
||||
dest_64:1, /* double precision dest */
|
||||
s1_64:1, /* double precision source 1 */
|
||||
s2_64:1, /* double precision source 2 */
|
||||
scale_flag:1; /* register is scaled */
|
||||
};
|
||||
|
||||
typedef struct INSTRUCTAB {
|
||||
unsigned int opcode;
|
||||
char *mnemonic;
|
||||
OPSPEC op1,op2,op3;
|
||||
struct SIM_FLAGS flgs;
|
||||
struct INSTRUCTAB *next;
|
||||
} INSTAB;
|
||||
|
||||
|
||||
/* Opcode Mnemonic Op 1 Spec Op 2 Spec Op 3 Spec Simflags Next */
|
||||
|
||||
static INSTAB instructions[] =
|
||||
{0xf400c800,"jsr ",{0,5,REG} ,{0,0,0} ,{0,0,0} , {2,2,NA,JSR , 0,0,1,0,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf400cc00,"jsr.n ",{0,5,REG} ,{0,0,0} ,{0,0,0} , {1,1,NA,JSR , 0,0,1,0,0,0,1,1,0,0,0,0}, NULL,
|
||||
0xf400c000,"jmp ",{0,5,REG} ,{0,0,0} ,{0,0,0} , {2,2,NA,JMP , 0,0,1,0,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf400c400,"jmp.n ",{0,5,REG} ,{0,0,0} ,{0,0,0} , {1,1,NA,JMP , 0,0,1,0,0,0,1,1,0,0,0,0}, NULL,
|
||||
0xc8000000,"bsr ",{0,26,PCREL},{0,0,0} ,{0,0,0} , {2,2,NA,BSR , i26bit,0,0,0,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xcc000000,"bsr.n ",{0,26,PCREL},{0,0,0} ,{0,0,0} , {1,1,NA,BSR , i26bit,0,0,0,0,0,1,1,0,0,0,0}, NULL,
|
||||
0xc0000000,"br ",{0,26,PCREL},{0,0,0} ,{0,0,0} , {2,2,NA,BR , i26bit,0,0,0,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xc4000000,"br.n ",{0,26,PCREL},{0,0,0} ,{0,0,0} , {1,1,NA,BR , i26bit,0,0,0,0,0,1,1,0,0,0,0}, NULL,
|
||||
0xd0000000,"bb0 ",{21,5,HEX} ,{16,5,REG} ,{0,16,PCREL},{2,2,NA,BB0, i16bit,0,1,0,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xd4000000,"bb0.n ",{21,5,HEX} ,{16,5,REG} ,{0,16,PCREL},{1,1,NA,BB0, i16bit,0,1,0,0,0,1,1,0,0,0,0}, NULL,
|
||||
0xd8000000,"bb1 ",{21,5,HEX},{16,5,REG} ,{0,16,PCREL},{2,2,NA,BB1, i16bit,0,1,0,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xdc000000,"bb1.n ",{21,5,HEX},{16,5,REG} ,{0,16,PCREL},{1,1,NA,BB1, i16bit,0,1,0,0,0,1,1,0,0,0,0}, NULL,
|
||||
0xf000d000,"tb0 ",{21,5,HEX} ,{16,5,REG} ,{0,10,HEX}, {2,2,NA,TB0 , i10bit,0,1,0,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf000d800,"tb1 ",{21,5,HEX} ,{16,5,REG} ,{0,10,HEX}, {2,2,NA,TB1 , i10bit,0,1,0,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xe8000000,"bcnd ",{21,5,CONDMASK},{16,5,REG},{0,16,PCREL},{2,2,NA,BCND, i16bit,0,1,0,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xec000000,"bcnd.n ",{21,5,CONDMASK},{16,5,REG},{0,16,PCREL},{1,1,NA,BCND, i16bit,0,1,0,0,0,1,1,0,0,0,0}, NULL,
|
||||
0xf000e800,"tcnd ",{21,5,CONDMASK},{16,5,REG},{0,10,HEX}, {2,2,NA,TCND, i10bit,0,1,0,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf8000000,"tbnd ",{16,5,REG} ,{0,16,HEX} ,{0,0,0} , {2,2,NA,TBND, i10bit,1,0,0,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf400f800,"tbnd ",{16,5,REG} ,{0,5,REG} ,{0,0,0} , {2,2,NA,TBND, 0,1,1,0,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf400fc00,"rte ",{0,0,0} ,{0,0,0} ,{0,0,0} , {2,2,NA,RTE , 0,0,0,0,0,0,0,1,0,0,0,0}, NULL,
|
||||
0x1c000000,"ld.b ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDB ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4001c00,"ld.b ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDB , 0,1,1,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0x0c000000,"ld.bu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDBU, i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4000c00,"ld.bu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDBU ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0x18000000,"ld.h ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDH ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4001800,"ld.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDH ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4001a00,"ld.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LDH ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL,
|
||||
0x08000000,"ld.hu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDHU, i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4000800,"ld.hu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDHU ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4000a00,"ld.hu ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LDHU ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL,
|
||||
0x14000000,"ld ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LD ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4001400,"ld ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LD ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4001600,"ld ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LD ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL,
|
||||
0x10000000,"ld.d ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDD ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4001000,"ld.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDD ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4001200,"ld.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LDD ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL,
|
||||
0xf4001500,"ld.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LD ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4001700,"ld.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LD ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL,
|
||||
0x2c000000,"st.b ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,NA,STB ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4002c00,"st.b ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,STB ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0x28000000,"st.h ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,NA,STH ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4002800,"st.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,STH ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4002a00,"st.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,NA,STH ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL,
|
||||
0x24000000,"st ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,NA,ST ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL,
|
||||
0xf4002400,"st ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,ST ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0xf4002600,"st ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,NA,ST ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL,
|
||||
0x20000000,"st.d ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,NA,STD ,i16bit,0,1,0,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0xf4002000,"st.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,STD ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0xf4002200,"st.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,NA,STD ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL,
|
||||
0xf4002500,"st.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,ST ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0xf4002700,"st.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,NA,ST ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL,
|
||||
0x00000000,"xmem.bu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,XMEMBU ,i16bit,1,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0xf4000000,"xmem.bu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x04000000,"xmem ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,XMEM ,i16bit,1,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0xf4000400,"xmem ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0xf4000600,"xmem ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL,
|
||||
0xf4000500,"xmem.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0xf4000700,"xmem.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL,
|
||||
0xf4003e00,"lda.b ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDAH, 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL,
|
||||
0xf4003a00,"lda.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDAH, 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL,
|
||||
0xf4003600,"lda ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDA , 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL,
|
||||
0xf4003200,"lda.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDAD, 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL,
|
||||
|
||||
0x80004000,"ldcr ",{21,5,REG} ,{5,6,CRREG} ,{0,0,0} ,{1,1,PINT,LDCR, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0x80008000,"stcr ",{16,5,REG} ,{5,6,CRREG} ,{0,0,0} ,{1,1,PINT,STCR, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0x8000c000,"xcr ",{21,5,REG} ,{16,5,REG} ,{5,6,CRREG},{1,1,PINT,XCR, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
|
||||
0xf4006000,"addu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADDU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4006200,"addu.ci ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADDU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4006100,"addu.co ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADDU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4006300,"addu.cio ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADDU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4006400,"subu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUBU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4006600,"subu.ci ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUBU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4006500,"subu.co ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUBU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4006700,"subu.cio ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUBU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4006900,"divu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {32,32,PINT,DIVU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4006d00,"mul ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,4,PINT,MUL, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4007000,"add ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADD , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4007200,"add.ci ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADD , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4007100,"add.co ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADD , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4007300,"add.cio ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADD , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4007400,"sub ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUB , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4007600,"sub.ci ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUB , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4007500,"sub.co ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUB , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4007700,"sub.cio ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUB , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4007900,"div ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {32,32,PINT,DIV , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4007d00,"cmp ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,CMP, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
|
||||
0x60000000,"addu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,ADDU, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0x64000000,"subu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,SUBU, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
|
||||
0x68000000,"divu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {32,32,PINT,DIVU, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0x6c000000,"mul ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {4,1,PINT,MUL, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0x70000000,"add ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,ADD, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0x74000000,"sub ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,SUB, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0x78000000,"div ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {32,32,PINT,DIV, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0x7c000000,"cmp ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,CMP, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
|
||||
0xf4004000,"and ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,AND ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4004400,"and.c ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,AND ,0,1,1,1,1,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4005800,"or ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,OR ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4005c00,"or.c ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,OR ,0,1,1,1,1,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4005000,"xor ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,XOR ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4005400,"xor.c ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,XOR ,0,1,1,1,1,0,0,0,0,0,0,0} ,NULL,
|
||||
0x40000000,"and ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,AND ,i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0x44000000,"and.u ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,AND ,i16bit,1,0,1,0,1,0,0,0,0,0,0} ,NULL,
|
||||
0x58000000,"or ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,OR ,i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0x5c000000,"or.u ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,OR ,i16bit,1,0,1,0,1,0,0,0,0,0,0} ,NULL,
|
||||
0x50000000,"xor ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,XOR ,i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0x54000000,"xor.u ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,XOR ,i16bit,1,0,1,0,1,0,0,0,0,0,0} ,NULL,
|
||||
0x48000000,"mask ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,MASK ,i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0x4c000000,"mask.u ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,MASK ,i16bit,1,0,1,0,1,0,0,0,0,0,0} ,NULL,
|
||||
0xf400ec00,"ff0 ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {1,1,PINT,FF0 ,0,0,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf400e800,"ff1 ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {1,1,PINT,FF1 ,0,0,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf0008000,"clr ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,CLR ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf0008800,"set ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,SET ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf0009000,"ext ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,EXT ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf0009800,"extu ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,EXTU ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf000a000,"mak ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,MAK ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf000a800,"rot ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,ROT ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4008000,"clr ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,CLR ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4008800,"set ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SET ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4009000,"ext ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,EXT ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf4009800,"extu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,EXTU ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf400a000,"mak ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,MAK ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
0xf400a800,"rot ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ROT ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL,
|
||||
|
||||
0x84002800,"fadd.sss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {5,1,PFLT,FADD ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x84002880,"fadd.ssd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,0,0,1,0} ,NULL,
|
||||
0x84002a00,"fadd.sds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL,
|
||||
0x84002a80,"fadd.sdd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,0,1,1,0} ,NULL,
|
||||
0x84002820,"fadd.dss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL,
|
||||
0x840028a0,"fadd.dsd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,1,0,1,0} ,NULL,
|
||||
0x84002a20,"fadd.dds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL,
|
||||
0x84002aa0,"fadd.ddd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,1,1,1,0} ,NULL,
|
||||
0x84003000,"fsub.sss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {5,1,PFLT,FSUB ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x84003080,"fsub.ssd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,0,0,1,0} ,NULL,
|
||||
0x84003200,"fsub.sds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL,
|
||||
0x84003280,"fsub.sdd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,0,1,1,0} ,NULL,
|
||||
0x84003020,"fsub.dss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL,
|
||||
0x840030a0,"fsub.dsd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,1,0,1,0} ,NULL,
|
||||
0x84003220,"fsub.dds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL,
|
||||
0x840032a0,"fsub.ddd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,1,1,1,0} ,NULL,
|
||||
0x84000000,"fmul.sss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,1,PFLT,FMUL ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x84000080,"fmul.ssd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,0,0,1,0} ,NULL,
|
||||
0x84000200,"fmul.sds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL,
|
||||
0x84000280,"fmul.sdd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,0,1,1,0} ,NULL,
|
||||
0x84000020,"fmul.dss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL,
|
||||
0x840000a0,"fmul.dsd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,1,0,1,0} ,NULL,
|
||||
0x84000220,"fmul.dds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL,
|
||||
0x840002a0,"fmul.ddd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,1,1,1,0} ,NULL,
|
||||
0x84007000,"fdiv.sss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {30,30,PFLT,FDIV ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x84007080,"fdiv.ssd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,0,0,1,0} ,NULL,
|
||||
0x84007200,"fdiv.sds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL,
|
||||
0x84007280,"fdiv.sdd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,0,1,1,0} ,NULL,
|
||||
0x84007020,"fdiv.dss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL,
|
||||
0x840070a0,"fdiv.dsd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,1,0,1,0} ,NULL,
|
||||
0x84007220,"fdiv.dds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL,
|
||||
0x840072a0,"fdiv.ddd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,1,1,1,0} ,NULL,
|
||||
0x84007800,"fsqrt.ss ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {5,1,PFLT,FLT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x84007880,"fsqrt.sd ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {5,1,PFLT,FLT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x84007820,"fsqrt.ds ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {5,1,PFLT,FLT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x840078a0,"fsqrt.dd ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {6,1,PFLT,FLT ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL,
|
||||
0x84003800,"fcmp.ss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {5,1,PFLT,FCMP ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x84003880,"fcmp.sd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,1,PFLT,FCMP ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL,
|
||||
0x84003a00,"fcmp.ds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,1,PFLT,FCMP ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL,
|
||||
0x84003a80,"fcmp.dd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,1,PFLT,FCMP ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL,
|
||||
0x84002000,"flt.s ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {5,1,PFLT,FLT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x84002020,"flt.d ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {6,1,PFLT,FLT ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL,
|
||||
0x84004800,"int.s ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {5,1,PFLT,INT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x84004880,"int.d ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {6,1,PFLT,INT ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL,
|
||||
0x84005000,"nint.s ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {5,1,PFLT,INT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x84005080,"nint.d ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {6,1,PFLT,INT ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL,
|
||||
0x84005800,"trnc.s ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {5,1,PFLT,TRNC ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x84005880,"trnc.d ",{21,5,REG} ,{0,5,REG} ,{0,0,0} , {6,1,PFLT,TRNC ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL,
|
||||
|
||||
0x80004800,"fldcr ",{21,5,REG} ,{5,6,FCRREG} ,{0,0,0} , {1,1,PFLT,FLDC ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x80008800,"fstcr ",{16,5,REG} ,{5,6,FCRREG} ,{0,0,0} , {1,1,PFLT,FSTC ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL,
|
||||
0x8000c800,"fxcr ",{21,5,REG} ,{16,5,REG} ,{5,6,FCRREG} , {1,1,PFLT,FXC ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL};
|
||||
|
343
gdb/m88k-pinsn.c
Normal file
343
gdb/m88k-pinsn.c
Normal file
@ -0,0 +1,343 @@
|
||||
/* This file has been modified by Data General Corporation, November 1989. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "m88k-opcode.h"
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
|
||||
void sprint_address ();
|
||||
|
||||
/* Changed hashtab to hashtable to avoid naming conflict
|
||||
with libdc.o (used for tdesc) for m88k.
|
||||
*/
|
||||
|
||||
INSTAB *hashtable[HASHVAL] = {0};
|
||||
|
||||
/*
|
||||
* Disassemble an M88000 Instruction
|
||||
*
|
||||
*
|
||||
* This module decodes the first instruction in inbuf. It uses the pc
|
||||
* to display pc-relative displacements. It writes the disassembled
|
||||
* instruction in outbuf.
|
||||
*
|
||||
* Revision History
|
||||
*
|
||||
* Revision 1.0 11/08/85 Creation date by Motorola
|
||||
* 05/11/89 R. Trawick adapted to GDB interface.
|
||||
*/
|
||||
#define MAXLEN 20
|
||||
|
||||
print_insn (memaddr, stream)
|
||||
CORE_ADDR memaddr;
|
||||
FILE *stream;
|
||||
{
|
||||
unsigned char buffer[MAXLEN];
|
||||
/* should be expanded if disassembler prints symbol names */
|
||||
char outbuf[100];
|
||||
int n;
|
||||
|
||||
/* Instruction addresses may have low two bits set. Clear them. */
|
||||
memaddr&= 0xfffffffc;
|
||||
read_memory (memaddr, buffer, MAXLEN);
|
||||
|
||||
n = m88kdis ((int)memaddr, buffer, outbuf);
|
||||
|
||||
fputs (outbuf, stream);
|
||||
|
||||
return (n);
|
||||
}
|
||||
|
||||
/*
|
||||
* disassemble the first instruction in 'inbuf'.
|
||||
* '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
|
||||
* 'outbuf' gets filled in with the disassembled instruction. It should
|
||||
* be long enough to hold the longest disassembled instruction.
|
||||
* 100 bytes is certainly enough, unless symbol printing is added later
|
||||
* The function returns the length of this instruction in bytes.
|
||||
*/
|
||||
|
||||
int m88kdis( pc, inbuf, outbuf )
|
||||
|
||||
int pc;
|
||||
int *inbuf;
|
||||
char *outbuf;
|
||||
|
||||
{ static ihashtab_initialized = 0;
|
||||
int instruction;
|
||||
unsigned int opcode;
|
||||
INSTAB *entry_ptr;
|
||||
int opmask;
|
||||
int class;
|
||||
|
||||
instruction= *inbuf;
|
||||
|
||||
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) {
|
||||
sprintf( outbuf, "word\t%08x", instruction );
|
||||
} else {
|
||||
sprintf( outbuf, "%s\t", entry_ptr->mnemonic );
|
||||
sprintop( &outbuf[strlen(outbuf)], &(entry_ptr->op1), instruction, pc, 1 );
|
||||
sprintop( &outbuf[strlen(outbuf)], &(entry_ptr->op2), instruction, pc, 0 );
|
||||
sprintop( &outbuf[strlen(outbuf)], &(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 buf
|
||||
* 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
|
||||
* char *buf buffer 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
|
||||
*/
|
||||
|
||||
sprintop( buf, opptr, inst, pc, first )
|
||||
|
||||
char *buf;
|
||||
OPSPEC *opptr;
|
||||
UINT inst;
|
||||
int pc;
|
||||
int first;
|
||||
|
||||
{ int extracted_field;
|
||||
char *cond_mask_sym;
|
||||
char cond_mask_sym_buf[6];
|
||||
|
||||
if (opptr->width == 0)
|
||||
return;
|
||||
|
||||
switch(opptr->type) {
|
||||
case CRREG:
|
||||
if (!first)
|
||||
*buf++= ',';
|
||||
sprintf( buf, "cr%d", UEXT(inst,opptr->offset,opptr->width));
|
||||
break;
|
||||
|
||||
case FCRREG:
|
||||
if (!first)
|
||||
*buf++= ',';
|
||||
sprintf( buf, "fcr%d", UEXT(inst,opptr->offset,opptr->width));
|
||||
break;
|
||||
|
||||
case REGSC:
|
||||
sprintf( buf, "[r%d]", UEXT(inst,opptr->offset,opptr->width));
|
||||
break;
|
||||
|
||||
case REG:
|
||||
if (!first)
|
||||
*buf++= ',';
|
||||
sprintf( buf, "r%d", UEXT(inst,opptr->offset,opptr->width));
|
||||
break;
|
||||
|
||||
case HEX:
|
||||
if (!first)
|
||||
*buf++= ',';
|
||||
extracted_field= UEXT(inst, opptr->offset, opptr->width);
|
||||
if (extracted_field == 0) {
|
||||
sprintf( buf, "0" );
|
||||
} else {
|
||||
sprintf( buf, "0x%02x", extracted_field );
|
||||
}
|
||||
break;
|
||||
|
||||
case CONDMASK:
|
||||
if (!first)
|
||||
*buf++= ',';
|
||||
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= cond_mask_sym_buf;
|
||||
sprintf( cond_mask_sym_buf,
|
||||
"%x",
|
||||
extracted_field );
|
||||
break;
|
||||
}
|
||||
strcpy( buf, cond_mask_sym );
|
||||
break;
|
||||
|
||||
case PCREL:
|
||||
if (!first)
|
||||
*buf++= ',';
|
||||
sprint_address( pc + 4*(SEXT(inst,opptr->offset,opptr->width)),
|
||||
buf );
|
||||
break;
|
||||
|
||||
case CONT:
|
||||
sprintf( buf,
|
||||
"%d,r%d",
|
||||
UEXT(inst,opptr->offset,5),
|
||||
UEXT(inst,(opptr->offset)+5,5) );
|
||||
break;
|
||||
|
||||
case BF:
|
||||
if (!first)
|
||||
*buf++= ',';
|
||||
sprintf( buf,
|
||||
"%d<%d>",
|
||||
UEXT(inst,(opptr->offset)+5,5),
|
||||
UEXT(inst,opptr->offset,5));
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf( buf, "<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
|
||||
*/
|
||||
|
||||
init_disasm()
|
||||
{
|
||||
int i,size;
|
||||
|
||||
for (i=0 ; i < HASHVAL ; i++)
|
||||
hashtable[i] = NULL;
|
||||
|
||||
for (i=0, size = sizeof(instructions) / sizeof(INSTAB) ; i < size ;
|
||||
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
|
||||
*/
|
||||
|
||||
install(instptr)
|
||||
INSTAB *instptr;
|
||||
{
|
||||
UINT i;
|
||||
|
||||
i = (instptr->opcode) % HASHVAL;
|
||||
instptr->next = hashtable[i];
|
||||
hashtable[i] = instptr;
|
||||
}
|
||||
|
||||
|
||||
/* adapted from print_address in printcmd by R. Trawick 5/15/89. The two should
|
||||
be combined.
|
||||
*/
|
||||
|
||||
void sprint_address (addr, buffer)
|
||||
|
||||
CORE_ADDR addr;
|
||||
char *buffer;
|
||||
|
||||
{
|
||||
register int i;
|
||||
struct symbol *fs;
|
||||
char *name;
|
||||
int name_location;
|
||||
|
||||
sprintf ( buffer, "0x%x", addr);
|
||||
|
||||
fs = find_pc_function (addr);
|
||||
|
||||
if (!fs) {
|
||||
i = find_pc_misc_function (addr);
|
||||
|
||||
if (i < 0) return; /* If nothing comes through, don't
|
||||
print anything symbolic */
|
||||
|
||||
name = misc_function_vector[i].name;
|
||||
name_location = misc_function_vector[i].address;
|
||||
} else {
|
||||
name = fs->name;
|
||||
name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (fs));
|
||||
}
|
||||
|
||||
if (addr - name_location)
|
||||
sprintf (buffer, " <%s+%d>", name, addr - name_location);
|
||||
else
|
||||
sprintf (buffer, " <%s>", name);
|
||||
}
|
600
gdb/m88k-tdep.c
Normal file
600
gdb/m88k-tdep.c
Normal file
@ -0,0 +1,600 @@
|
||||
/* Copyright (C) 1988, 1990 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
GDB 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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GDB 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 GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
#include "value.h"
|
||||
|
||||
#ifdef USG
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <signal.h>
|
||||
#include "gdbcore.h"
|
||||
#include <sys/user.h>
|
||||
#ifndef USER /* added to support BCS ptrace_user */
|
||||
|
||||
#define USER ptrace_user
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef COFF_ENCAPSULATE
|
||||
#include "a.out.encap.h"
|
||||
#else
|
||||
#include <a.out.h>
|
||||
#endif
|
||||
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "symtab.h"
|
||||
#include "setjmp.h"
|
||||
#include "value.h"
|
||||
|
||||
int stack_error;
|
||||
jmp_buf stack_jmp;
|
||||
|
||||
void
|
||||
tdesc_error_function (environment, continuable, message)
|
||||
dc_word_t environment;
|
||||
dc_boolean_t continuable;
|
||||
char *message;
|
||||
{
|
||||
if (stack_error) longjmp (stack_jmp, 1);
|
||||
if (!continuable)
|
||||
{
|
||||
printf("%s\n",message);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tdesc_read_function (environment, memory, length, buffer)
|
||||
dc_word_t environment;
|
||||
dc_word_t memory;
|
||||
int length;
|
||||
char *buffer;
|
||||
{
|
||||
int ptrace_code;
|
||||
errno = 0;
|
||||
if (memory < 2048)
|
||||
#if 0
|
||||
/* This is a no-op! It sets buffer, but doesn't do anything to
|
||||
what buffer points to. What does this function do anyway?
|
||||
And this is wrong for cross-debugging. */
|
||||
buffer = ptrace (3, inferior_pid, memory, 0);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
else
|
||||
read_memory (memory, buffer, length);
|
||||
}
|
||||
|
||||
/* Map function for tdesc */
|
||||
void
|
||||
tdesc_map_function (map_env, loc, map_info_in, map_info_out)
|
||||
dc_word_t map_env;
|
||||
dc_word_t loc;
|
||||
dc_map_info_in_t map_info_in;
|
||||
dc_map_info_out_t *map_info_out;
|
||||
{
|
||||
int map_flags = DC_MIO_ENTRY_POINT | DC_MIO_IMPLICIT_PROLOGUE_END;
|
||||
int entry_point = get_pc_function_start(loc);
|
||||
map_info_out->flags = map_flags;
|
||||
map_info_out->entry_point = entry_point;
|
||||
}
|
||||
|
||||
dc_handle_t tdesc_handle;
|
||||
|
||||
extern int debug_info;
|
||||
|
||||
void
|
||||
init_tdesc ()
|
||||
{
|
||||
tdesc_handle = dc_initiate (debug_info, tdesc_error_function,
|
||||
0,tdesc_read_function,0,0,0,0,0,tdesc_map_function,0);
|
||||
}
|
||||
dc_dcontext_t current_context;
|
||||
|
||||
/* setup current context, called from wait_for_inferior */
|
||||
|
||||
dc_dcontext_t
|
||||
init_dcontext()
|
||||
{
|
||||
dc_word_t reg_info[DC_NUM_REG];
|
||||
dc_word_t reg_flags[2] = {0,-1};
|
||||
dc_word_t aux_info[DC_NUM_AUX];
|
||||
dc_word_t aux_flags[2] = {0,-1};
|
||||
dc_exactness_t loc_exact = DC_NO;
|
||||
dc_word_t psr_info;
|
||||
dc_boolean_t psr_ind = 0;
|
||||
dc_word_t psr_flags[2] = {0,-1};
|
||||
|
||||
bcopy (®isters, reg_info, DC_NUM_REG * 4);
|
||||
aux_info[DC_AUX_LOC] = read_register(SXIP_REGNUM);
|
||||
aux_info[DC_AUX_SXIP] = read_register(SXIP_REGNUM);
|
||||
aux_info[DC_AUX_SNIP] = read_register(SNIP_REGNUM);
|
||||
aux_info[DC_AUX_SFIP] = read_register(SFIP_REGNUM);
|
||||
aux_info[DC_AUX_FPSR] = read_register(FPSR_REGNUM);
|
||||
aux_info[DC_AUX_FPCR] = read_register(FPCR_REGNUM);
|
||||
|
||||
psr_info = read_register(PSR_REGNUM);
|
||||
|
||||
return dc_make_dcontext (tdesc_handle, reg_info, reg_flags, aux_info,
|
||||
aux_flags, loc_exact, psr_info, psr_ind, psr_flags);
|
||||
}
|
||||
|
||||
|
||||
dc_dcontext_t
|
||||
get_prev_context (context)
|
||||
dc_dcontext_t context;
|
||||
{
|
||||
return current_context = dc_previous_dcontext (context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Determine frame base for this file's frames. This will be either
|
||||
the CFA or the old style FP_REGNUM; the symtab for the current pc's
|
||||
file has the information */
|
||||
|
||||
CORE_ADDR
|
||||
get_frame_base(pc)
|
||||
CORE_ADDR pc;
|
||||
{
|
||||
struct symtab *this_file = find_pc_symtab(pc);
|
||||
int coffsem_frame_position;
|
||||
|
||||
/* If this_file is null, there's a good chance the file was compiled
|
||||
without -g. If that's the case, use CFA (canonical frame addr)
|
||||
as the default frame pointer. */
|
||||
|
||||
if (this_file)
|
||||
{
|
||||
coffsem_frame_position = this_file->coffsem & 3;
|
||||
if (coffsem_frame_position == 1)
|
||||
return (CORE_ADDR) dc_general_register (current_context, FP_REGNUM);
|
||||
else
|
||||
/* default is CFA, as well as if coffsem==2 */
|
||||
return (CORE_ADDR) dc_frame_address (current_context);
|
||||
}
|
||||
|
||||
return (CORE_ADDR) dc_frame_address (current_context);
|
||||
}
|
||||
|
||||
#if TARGET_BYTE_ORDER != HOST_BYTE_ORDER
|
||||
you lose
|
||||
#else /* Host and target byte order the same. */
|
||||
#define SINGLE_EXP_BITS 8
|
||||
#define DOUBLE_EXP_BITS 11
|
||||
int
|
||||
IEEE_isNAN(fp, len)
|
||||
int *fp, len;
|
||||
/* fp points to a single precision OR double precision
|
||||
* floating point value; len is the number of bytes, either 4 or 8.
|
||||
* Returns 1 iff fp points to a valid IEEE floating point number.
|
||||
* Returns 0 if fp points to a denormalized number or a NaN
|
||||
*/
|
||||
{
|
||||
int exponent;
|
||||
if (len == 4)
|
||||
{
|
||||
exponent = *fp;
|
||||
exponent = exponent << 1 >> (32 - SINGLE_EXP_BITS - 1);
|
||||
return ((exponent == -1) || (! exponent && *fp));
|
||||
}
|
||||
else if (len == 8)
|
||||
{
|
||||
exponent = *(fp+1);
|
||||
exponent = exponent << 1 >> (32 - DOUBLE_EXP_BITS - 1);
|
||||
return ((exponent == -1) || (! exponent && *fp * *(fp+1)));
|
||||
}
|
||||
else return 1;
|
||||
}
|
||||
#endif /* Host and target byte order the same. */
|
||||
|
||||
#define FIRST_PRESERVED_REGNUM 14
|
||||
#define LAST_PRESERVED_REGNUM 25
|
||||
#define FIRST_PARM_REGNUM 2
|
||||
#define LAST_PARM_REGNUM 9
|
||||
|
||||
#define MAX_REG_PARMS (LAST_PARM_REGNUM - FIRST_PARM_REGNUM + 1)
|
||||
|
||||
void
|
||||
frame_find_saved_regs (fi, fsr)
|
||||
struct frame_info *fi;
|
||||
struct frame_saved_regs *fsr;
|
||||
{
|
||||
register int regnum;
|
||||
|
||||
error ("Feature not implemented for the 88k yet.");
|
||||
return;
|
||||
|
||||
#if 0
|
||||
for (regnum = FIRST_PARM_REGNUM; regnum <= LAST_PARM_REGNUM; regnum++)
|
||||
fsr->regs[regnum]
|
||||
= (unsigned) fi->frame - ((regnum - FIRST_PARM_REGNUM) * 4);
|
||||
|
||||
fsr->regs[SP_REGNUM] = 0; /* SP not saved in frames */
|
||||
fsr->regs[FP_REGNUM] = fi->frame;
|
||||
fsr->regs[PC_REGNUM] = fi->frame + 4;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
pushed_size (prev_words, v)
|
||||
int prev_words;
|
||||
struct value *v;
|
||||
{
|
||||
switch (TYPE_CODE (VALUE_TYPE (v)))
|
||||
{
|
||||
case TYPE_CODE_VOID: /* Void type (values zero length) */
|
||||
|
||||
return 0; /* That was easy! */
|
||||
|
||||
case TYPE_CODE_PTR: /* Pointer type */
|
||||
case TYPE_CODE_ENUM: /* Enumeration type */
|
||||
case TYPE_CODE_INT: /* Integer type */
|
||||
case TYPE_CODE_REF: /* C++ Reference types */
|
||||
case TYPE_CODE_ARRAY: /* Array type, lower bound zero */
|
||||
|
||||
return 1;
|
||||
|
||||
case TYPE_CODE_FLT: /* Floating type */
|
||||
|
||||
if (TYPE_LENGTH (VALUE_TYPE (v)) == 4)
|
||||
return 1;
|
||||
else
|
||||
/* Assume that it must be a double. */
|
||||
if (prev_words & 1) /* at an odd-word boundary */
|
||||
return 3; /* round to 8-byte boundary */
|
||||
else
|
||||
return 2;
|
||||
|
||||
case TYPE_CODE_STRUCT: /* C struct or Pascal record */
|
||||
case TYPE_CODE_UNION: /* C union or Pascal variant part */
|
||||
|
||||
return (((TYPE_LENGTH (VALUE_TYPE (v)) + 3) / 4) * 4);
|
||||
|
||||
case TYPE_CODE_FUNC: /* Function type */
|
||||
case TYPE_CODE_SET: /* Pascal sets */
|
||||
case TYPE_CODE_RANGE: /* Range (integers within bounds) */
|
||||
case TYPE_CODE_PASCAL_ARRAY: /* Array with explicit type of index */
|
||||
case TYPE_CODE_MEMBER: /* Member type */
|
||||
case TYPE_CODE_METHOD: /* Method type */
|
||||
/* Don't know how to pass these yet. */
|
||||
|
||||
case TYPE_CODE_UNDEF: /* Not used; catches errors */
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
store_parm_word (address, val)
|
||||
CORE_ADDR address;
|
||||
int val;
|
||||
{
|
||||
write_memory (address, &val, 4);
|
||||
}
|
||||
|
||||
static int
|
||||
store_parm (prev_words, left_parm_addr, v)
|
||||
unsigned int prev_words;
|
||||
CORE_ADDR left_parm_addr;
|
||||
struct value *v;
|
||||
{
|
||||
CORE_ADDR start = left_parm_addr + (prev_words * 4);
|
||||
int *val_addr = (int *)VALUE_CONTENTS(v);
|
||||
|
||||
switch (TYPE_CODE (VALUE_TYPE (v)))
|
||||
{
|
||||
case TYPE_CODE_VOID: /* Void type (values zero length) */
|
||||
|
||||
return 0;
|
||||
|
||||
case TYPE_CODE_PTR: /* Pointer type */
|
||||
case TYPE_CODE_ENUM: /* Enumeration type */
|
||||
case TYPE_CODE_INT: /* Integer type */
|
||||
case TYPE_CODE_ARRAY: /* Array type, lower bound zero */
|
||||
case TYPE_CODE_REF: /* C++ Reference types */
|
||||
|
||||
store_parm_word (start, *val_addr);
|
||||
return 1;
|
||||
|
||||
case TYPE_CODE_FLT: /* Floating type */
|
||||
|
||||
if (TYPE_LENGTH (VALUE_TYPE (v)) == 4)
|
||||
{
|
||||
store_parm_word (start, *val_addr);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
store_parm_word (start + ((prev_words & 1) * 4), val_addr[0]);
|
||||
store_parm_word (start + ((prev_words & 1) * 4) + 4, val_addr[1]);
|
||||
return 2 + (prev_words & 1);
|
||||
}
|
||||
|
||||
case TYPE_CODE_STRUCT: /* C struct or Pascal record */
|
||||
case TYPE_CODE_UNION: /* C union or Pascal variant part */
|
||||
|
||||
{
|
||||
unsigned int words = (((TYPE_LENGTH (VALUE_TYPE (v)) + 3) / 4) * 4);
|
||||
unsigned int word;
|
||||
|
||||
for (word = 0; word < words; word++)
|
||||
store_parm_word (start + (word * 4), val_addr[word]);
|
||||
return words;
|
||||
}
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* This routine sets up all of the parameter values needed to make a pseudo
|
||||
call. The name "push_parameters" is a misnomer on some archs,
|
||||
because (on the m88k) most parameters generally end up being passed in
|
||||
registers rather than on the stack. In this routine however, we do
|
||||
end up storing *all* parameter values onto the stack (even if we will
|
||||
realize later that some of these stores were unnecessary). */
|
||||
|
||||
void
|
||||
push_parameters (return_type, struct_conv, nargs, args)
|
||||
struct type *return_type;
|
||||
int struct_conv;
|
||||
int nargs;
|
||||
value *args;
|
||||
{
|
||||
int parm_num;
|
||||
unsigned int p_words = 0;
|
||||
CORE_ADDR left_parm_addr;
|
||||
|
||||
/* Start out by creating a space for the return value (if need be). We
|
||||
only need to do this if the return value is a struct or union. If we
|
||||
do make a space for a struct or union return value, then we must also
|
||||
arrange for the base address of that space to go into r12, which is the
|
||||
standard place to pass the address of the return value area to the
|
||||
callee. Note that only structs and unions are returned in this fashion.
|
||||
Ints, enums, pointers, and floats are returned into r2. Doubles are
|
||||
returned into the register pair {r2,r3}. Note also that the space
|
||||
reserved for a struct or union return value only has to be word aligned
|
||||
(not double-word) but it is double-word aligned here anyway (just in
|
||||
case that becomes important someday). */
|
||||
|
||||
switch (TYPE_CODE (return_type))
|
||||
{
|
||||
case TYPE_CODE_STRUCT:
|
||||
case TYPE_CODE_UNION:
|
||||
{
|
||||
int return_bytes = ((TYPE_LENGTH (return_type) + 7) / 8) * 8;
|
||||
CORE_ADDR rv_addr;
|
||||
|
||||
rv_addr = read_register (SP_REGNUM) - return_bytes;
|
||||
|
||||
write_register (SP_REGNUM, rv_addr); /* push space onto the stack */
|
||||
write_register (SRA_REGNUM, rv_addr);/* set return value register */
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we make a pre-pass on the whole parameter list to figure out exactly
|
||||
how many words worth of stuff we are going to pass. */
|
||||
|
||||
for (p_words = 0, parm_num = 0; parm_num < nargs; parm_num++)
|
||||
p_words += pushed_size (p_words, value_arg_coerce (args[parm_num]));
|
||||
|
||||
/* Now, check to see if we have to round up the number of parameter words
|
||||
to get up to the next 8-bytes boundary. This may be necessary because
|
||||
of the software convention to always keep the stack aligned on an 8-byte
|
||||
boundary. */
|
||||
|
||||
if (p_words & 1)
|
||||
p_words++; /* round to 8-byte boundary */
|
||||
|
||||
/* Now figure out the absolute address of the leftmost parameter, and update
|
||||
the stack pointer to point at that address. */
|
||||
|
||||
left_parm_addr = read_register (SP_REGNUM) - (p_words * 4);
|
||||
write_register (SP_REGNUM, left_parm_addr);
|
||||
|
||||
/* Now we can go through all of the parameters (in left-to-right order)
|
||||
and write them to their parameter stack slots. Note that we are not
|
||||
really "pushing" the parameter values. The stack space for these values
|
||||
was already allocated above. Now we are just filling it up. */
|
||||
|
||||
for (p_words = 0, parm_num = 0; parm_num < nargs; parm_num++)
|
||||
p_words +=
|
||||
store_parm (p_words, left_parm_addr, value_arg_coerce (args[parm_num]));
|
||||
|
||||
/* Now that we are all done storing the parameter values into the stack, we
|
||||
must go back and load up the parameter registers with the values from the
|
||||
corresponding stack slots. Note that in the two cases of (a) gaps in the
|
||||
parameter word sequence causes by (otherwise) misaligned doubles, and (b)
|
||||
slots correcponding to structs or unions, the work we do here in loading
|
||||
some parameter registers may be unnecessary, but who cares? */
|
||||
|
||||
for (p_words = 0; p_words < 8; p_words++)
|
||||
{
|
||||
write_register (FIRST_PARM_REGNUM + p_words,
|
||||
read_memory_integer (left_parm_addr + (p_words * 4), 4));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pop_frame ()
|
||||
{
|
||||
error ("Feature not implemented for the m88k yet.");
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
collect_returned_value (rval, value_type, struct_return, nargs, args)
|
||||
value *rval;
|
||||
struct type *value_type;
|
||||
int struct_return;
|
||||
int nargs;
|
||||
value *args;
|
||||
{
|
||||
char retbuf[REGISTER_BYTES];
|
||||
|
||||
bcopy (registers, retbuf, REGISTER_BYTES);
|
||||
*rval = value_being_returned (value_type, retbuf, struct_return);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Now handled in a machine independent way with CALL_DUMMY_LOCATION. */
|
||||
/* Stuff a breakpoint instruction onto the stack (or elsewhere if the stack
|
||||
is not a good place for it). Return the address at which the instruction
|
||||
got stuffed, or zero if we were unable to stuff it anywhere. */
|
||||
|
||||
CORE_ADDR
|
||||
push_breakpoint ()
|
||||
{
|
||||
static char breakpoint_insn[] = BREAKPOINT;
|
||||
extern CORE_ADDR text_end; /* of inferior */
|
||||
static char readback_buffer[] = BREAKPOINT;
|
||||
int i;
|
||||
|
||||
/* With a little bit of luck, we can just stash the breakpoint instruction
|
||||
in the word just beyond the end of normal text space. For systems on
|
||||
which the hardware will not allow us to execute out of the stack segment,
|
||||
we have to hope that we *are* at least allowed to effectively extend the
|
||||
text segment by one word. If the actual end of user's the text segment
|
||||
happens to fall right at a page boundary this trick may fail. Note that
|
||||
we check for this by reading after writing, and comparing in order to
|
||||
be sure that the write worked. */
|
||||
|
||||
write_memory (text_end, &breakpoint_insn, 4);
|
||||
|
||||
/* Fill the readback buffer with some garbage which is certain to be
|
||||
unequal to the breakpoint insn. That way we can tell if the
|
||||
following read doesn't actually succeed. */
|
||||
|
||||
for (i = 0; i < sizeof (readback_buffer); i++)
|
||||
readback_buffer[i] = ~ readback_buffer[i]; /* Invert the bits */
|
||||
|
||||
/* Now check that the breakpoint insn was successfully installed. */
|
||||
|
||||
read_memory (text_end, readback_buffer, sizeof (readback_buffer));
|
||||
for (i = 0; i < sizeof (readback_buffer); i++)
|
||||
if (readback_buffer[i] != breakpoint_insn[i])
|
||||
return 0; /* Failed to install! */
|
||||
|
||||
return text_end;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Like dc_psr_register but takes an extra int arg. */
|
||||
static dc_word_t
|
||||
psr_register (context, dummy)
|
||||
dc_dcontext_t context;
|
||||
int dummy;
|
||||
{
|
||||
return dc_psr_register (context);
|
||||
}
|
||||
|
||||
/* Same functionality as get_saved_register in findvar.c, but implemented
|
||||
to use tdesc. */
|
||||
void
|
||||
get_saved_register (raw_buffer, optim, addrp, frame, regnum, lvalp)
|
||||
char *raw_buffer;
|
||||
int *optim;
|
||||
CORE_ADDR *addrp;
|
||||
FRAME frame;
|
||||
int regnum;
|
||||
enum lval_type *lvalp;
|
||||
{
|
||||
struct frame_info *fi = get_frame_info (frame);
|
||||
|
||||
/* Functions to say whether a register is optimized out, and
|
||||
if not, to get the value. Take as args a context and the
|
||||
value of get_reg_arg. */
|
||||
int (*get_reg_state) ();
|
||||
dc_word_t (*get_reg) ();
|
||||
int get_reg_arg;
|
||||
|
||||
/* Because tdesc doesn't tell us whether it got it from a register
|
||||
or memory, always say we don't have an address for it. */
|
||||
if (addrp != NULL)
|
||||
*addrp = 0;
|
||||
|
||||
if (regnum < DC_NUM_REG)
|
||||
{
|
||||
get_reg_state = dc_general_register_state;
|
||||
get_reg = dc_general_register;
|
||||
get_reg_arg = regnum;
|
||||
}
|
||||
else
|
||||
{
|
||||
get_reg_state = dc_auxiliary_register_state;
|
||||
get_reg = dc_auxiliary_register;
|
||||
switch (regnum)
|
||||
{
|
||||
case SXIP_REGNUM:
|
||||
get_reg_arg = DC_AUX_SXIP;
|
||||
break;
|
||||
case SNIP_REGNUM:
|
||||
get_reg_arg = DC_AUX_SNIP;
|
||||
break;
|
||||
case FPSR_REGNUM:
|
||||
get_reg_arg = DC_AUX_FPSR;
|
||||
break;
|
||||
case FPCR_REGNUM:
|
||||
get_reg_arg = DC_AUX_FPCR;
|
||||
break;
|
||||
case PSR_REGNUM:
|
||||
get_reg_state = dc_psr_register_bit_state;
|
||||
get_reg = psr_register;
|
||||
get_reg_arg = 0;
|
||||
break;
|
||||
default:
|
||||
if (optim != NULL)
|
||||
*optim = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((*get_reg_state) (fi->frame_context, get_reg_arg))
|
||||
{
|
||||
if (raw_buffer != NULL)
|
||||
*(int *)raw_buffer = (*get_reg) (fi->frame_context, get_reg_arg);
|
||||
if (optim != NULL)
|
||||
*optim = 0;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optim != NULL)
|
||||
*optim = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Well, the caller can't treat it as a register or memory... */
|
||||
if (lvalp != NULL)
|
||||
*lvalp = not_lval;
|
||||
}
|
340
gdb/m88k-xdep.c
Normal file
340
gdb/m88k-xdep.c
Normal file
@ -0,0 +1,340 @@
|
||||
/* Copyright (C) 1988, 1990 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
GDB 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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GDB 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 GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
|
||||
#ifdef USG
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <signal.h>
|
||||
#include "gdbcore.h"
|
||||
#include <sys/user.h>
|
||||
#ifndef USER /* added to support BCS ptrace_user */
|
||||
|
||||
#define USER ptrace_user
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef COFF_ENCAPSULATE
|
||||
#include "a.out.encap.h"
|
||||
#else
|
||||
#include <a.out.h>
|
||||
#endif
|
||||
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "symtab.h"
|
||||
#include "setjmp.h"
|
||||
#include "value.h"
|
||||
|
||||
/* define offsets to the pc instruction offsets in ptrace_user struct */
|
||||
#define SXIP_OFFSET (char *)&u.pt_sigframe.dg_sigframe.sc_sxip - \
|
||||
(char *)&u
|
||||
|
||||
#define SNIP_OFFSET (char *)&u.pt_sigframe.dg_sigframe.sc_snip - \
|
||||
(char *)&u
|
||||
|
||||
#define SFIP_OFFSET (char *)&u.pt_sigframe.dg_sigframe.sc_sfip - (char *)&u
|
||||
extern int have_symbol_file_p();
|
||||
|
||||
extern jmp_buf stack_jmp;
|
||||
|
||||
extern int errno;
|
||||
extern char registers[REGISTER_BYTES];
|
||||
|
||||
void
|
||||
fetch_inferior_registers ()
|
||||
{
|
||||
register int regno;
|
||||
register unsigned int regaddr;
|
||||
char buf[MAX_REGISTER_RAW_SIZE];
|
||||
register int i;
|
||||
|
||||
struct USER u;
|
||||
unsigned int offset;
|
||||
|
||||
offset = (char *) &u.pt_r0 - (char *) &u;
|
||||
regaddr = offset; /* byte offset to r0;*/
|
||||
|
||||
/* offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; */
|
||||
for (regno = 0; regno < NUM_REGS; regno++)
|
||||
{
|
||||
/*regaddr = register_addr (regno, offset);*/
|
||||
/* 88k enhancement */
|
||||
|
||||
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
|
||||
{
|
||||
*(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0);
|
||||
regaddr += sizeof (int);
|
||||
}
|
||||
supply_register (regno, buf);
|
||||
}
|
||||
/* now load up registers 36 - 38; special pc registers */
|
||||
*(int *) &buf[0] = ptrace (3,inferior_pid,(char *)&u.pt_sigframe.dg_sigframe.sc_sxip - (char *)&u ,0);
|
||||
supply_register (SXIP_REGNUM, buf);
|
||||
*(int *) &buf[0] = ptrace (3, inferior_pid, (char *)&u.pt_sigframe.dg_sigframe.sc_snip - (char *)&u ,0);
|
||||
supply_register (SNIP_REGNUM, buf);
|
||||
*(int *) &buf[0] = ptrace (3, inferior_pid, (char *)&u.pt_sigframe.dg_sigframe.sc_sfip - (char *)&u ,0);
|
||||
supply_register (SFIP_REGNUM, buf);
|
||||
}
|
||||
|
||||
/* Store our register values back into the inferior.
|
||||
If REGNO is -1, do this for all registers.
|
||||
Otherwise, REGNO specifies which register (so we can save time). */
|
||||
|
||||
store_inferior_registers (regno)
|
||||
int regno;
|
||||
{
|
||||
register unsigned int regaddr;
|
||||
char buf[80];
|
||||
|
||||
struct USER u;
|
||||
|
||||
#if defined(BCS)
|
||||
#if defined(DGUX)
|
||||
|
||||
unsigned int offset = (char *) &u.pt_r0 - (char *) &u;
|
||||
|
||||
#endif /* defined (DGUX) */
|
||||
#else
|
||||
|
||||
unsigned int offset = (char *) &u.pt_r0 - (char *) &u;
|
||||
|
||||
#endif /* defined(BCS) */
|
||||
/* offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; */
|
||||
regaddr = offset;
|
||||
|
||||
if (regno >= 0)
|
||||
{
|
||||
/* regaddr = register_addr (regno, offset); */
|
||||
if (regno < PC_REGNUM)
|
||||
{
|
||||
regaddr = offset + regno * sizeof (int);
|
||||
errno = 0;
|
||||
ptrace (6, inferior_pid, regaddr, read_register (regno));
|
||||
if (errno != 0)
|
||||
{
|
||||
sprintf (buf, "writing register number %d", regno);
|
||||
perror_with_name (buf);
|
||||
}
|
||||
}
|
||||
else if (regno == SXIP_REGNUM)
|
||||
ptrace (6, inferior_pid, SXIP_OFFSET, read_register(regno));
|
||||
else if (regno == SNIP_REGNUM)
|
||||
ptrace (6, inferior_pid, SNIP_OFFSET, read_register(regno));
|
||||
else if (regno == SFIP_REGNUM)
|
||||
ptrace (6, inferior_pid, SFIP_OFFSET, read_register(regno));
|
||||
else printf ("Bad register number for store_inferior routine\n");
|
||||
}
|
||||
else {
|
||||
for (regno = 0; regno < NUM_REGS - 3; regno++)
|
||||
{
|
||||
/* regaddr = register_addr (regno, offset); */
|
||||
errno = 0;
|
||||
regaddr = offset + regno * sizeof (int);
|
||||
ptrace (6, inferior_pid, regaddr, read_register (regno));
|
||||
if (errno != 0)
|
||||
{
|
||||
sprintf (buf, "writing register number %d", regno);
|
||||
perror_with_name (buf);
|
||||
}
|
||||
}
|
||||
ptrace (6,inferior_pid,SXIP_OFFSET,read_register(SXIP_REGNUM));
|
||||
ptrace (6,inferior_pid,SNIP_OFFSET,read_register(SNIP_REGNUM));
|
||||
ptrace (6,inferior_pid,SFIP_OFFSET,read_register(SFIP_REGNUM));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Core files are now a function of BFD. */
|
||||
|
||||
void
|
||||
core_file_command (filename, from_tty)
|
||||
char *filename;
|
||||
int from_tty;
|
||||
{
|
||||
int val;
|
||||
extern char registers[];
|
||||
|
||||
/* Need symbol file and one with tdesc info for corefiles to work */
|
||||
if (!have_symbol_file_p())
|
||||
error ("Requires symbol-file and exec-file");
|
||||
if (!execfile)
|
||||
error ("Requires exec-file and symbol-file");
|
||||
|
||||
/* Discard all vestiges of any previous core file
|
||||
and mark data and stack spaces as empty. */
|
||||
|
||||
if (corefile)
|
||||
free (corefile);
|
||||
corefile = 0;
|
||||
|
||||
if (corechan >= 0)
|
||||
close (corechan);
|
||||
corechan = -1;
|
||||
|
||||
data_start = 0;
|
||||
data_end = 0;
|
||||
stack_start = STACK_END_ADDR;
|
||||
stack_end = STACK_END_ADDR;
|
||||
|
||||
/* Now, if a new core file was specified, open it and digest it. */
|
||||
|
||||
if (filename)
|
||||
{
|
||||
filename = tilde_expand (filename);
|
||||
make_cleanup (free, filename);
|
||||
|
||||
if (have_inferior_p ())
|
||||
error ("To look at a core file, you must kill the inferior with \"kill\".");
|
||||
corechan = open (filename, O_RDONLY, 0);
|
||||
if (corechan < 0)
|
||||
perror_with_name (filename);
|
||||
/* 4.2-style (and perhaps also sysV-style) core dump file. */
|
||||
{
|
||||
struct USER u;
|
||||
|
||||
int reg_offset;
|
||||
|
||||
val = myread (corechan, &u, sizeof u);
|
||||
if (val < 0)
|
||||
perror_with_name (filename);
|
||||
data_start = u.pt_o_data_start;
|
||||
|
||||
data_end = data_start + u.pt_dsize;
|
||||
stack_start = stack_end - u.pt_ssize;
|
||||
data_offset = u.pt_dataptr;
|
||||
stack_offset = data_offset + u.pt_dsize;
|
||||
|
||||
#if defined(BCS)
|
||||
#if defined(DGUX)
|
||||
|
||||
reg_offset = 2048;
|
||||
|
||||
|
||||
#endif /* defined (DGUX) */
|
||||
#else
|
||||
|
||||
/* original code: */
|
||||
reg_offset = (int) u.pt_r0 - KERNEL_U_ADDR;
|
||||
|
||||
#endif /* defined(BCS) */
|
||||
|
||||
/* I don't know where to find this info.
|
||||
So, for now, mark it as not available. */
|
||||
/* N_SET_MAGIC (core_aouthdr, 0); */
|
||||
bzero ((char *) &core_aouthdr, sizeof core_aouthdr);
|
||||
|
||||
/* Read the register values out of the core file and store
|
||||
them where `read_register' will find them. */
|
||||
|
||||
{
|
||||
register int regno;
|
||||
|
||||
for (regno = 0; regno < NUM_REGS; regno++)
|
||||
{
|
||||
char buf[MAX_REGISTER_RAW_SIZE];
|
||||
|
||||
val = lseek (corechan, register_addr (regno, reg_offset), 0);
|
||||
if (val < 0)
|
||||
perror_with_name (filename);
|
||||
|
||||
val = myread (corechan, buf, sizeof buf);
|
||||
if (val < 0)
|
||||
perror_with_name (filename);
|
||||
supply_register (regno, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filename[0] == '/')
|
||||
corefile = savestring (filename, strlen (filename));
|
||||
else
|
||||
{
|
||||
corefile = concat (current_directory, "/", filename);
|
||||
}
|
||||
init_tdesc();
|
||||
current_context = init_dcontext();
|
||||
set_current_frame ( create_new_frame(get_frame_base (read_pc()),
|
||||
read_pc ()));
|
||||
select_frame (get_current_frame (), 0);
|
||||
validate_files ();
|
||||
}
|
||||
else if (from_tty)
|
||||
printf ("No core file now.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* blockend is the address of the end of the user structure */
|
||||
m88k_register_u_addr (blockend, regnum)
|
||||
{
|
||||
struct USER u;
|
||||
int ustart = blockend - sizeof (struct USER);
|
||||
switch (regnum)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
case 24:
|
||||
case 25:
|
||||
case 26:
|
||||
case 27:
|
||||
case 28:
|
||||
case 29:
|
||||
case 30:
|
||||
case 31: return (ustart + ((int) &u.pt_r0 - (int) &u) + sizeof(REGISTER_TYPE) * regnum);
|
||||
case PSR_REGNUM: return (ustart + ((int) &u.pt_psr - (int) &u));
|
||||
case FPSR_REGNUM: return (ustart + ((int) &u.pt_fpsr - (int) &u));
|
||||
case FPCR_REGNUM: return (ustart + ((int) &u.pt_fpcr - (int) &u));
|
||||
case SXIP_REGNUM: return (ustart + SXIP_OFFSET);
|
||||
case SNIP_REGNUM: return (ustart + SNIP_OFFSET);
|
||||
case SFIP_REGNUM: return (ustart + SFIP_OFFSET);
|
||||
default: return (blockend + sizeof (REGISTER_TYPE) * regnum);
|
||||
}
|
||||
}
|
@ -555,6 +555,13 @@ struct symtab
|
||||
/* Full name of file as found by searching the source path.
|
||||
0 if not yet known. */
|
||||
char *fullname;
|
||||
|
||||
/* Anything extra for this symtab. This is for target machines
|
||||
with special debugging info of some sort (which cannot just
|
||||
be represented in a normal symtab). */
|
||||
#if defined (EXTRA_SYMTAB_INFO)
|
||||
EXTRA_SYMTAB_INFO
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Each source file that has not been fully read in is represented by
|
||||
|
@ -22,14 +22,20 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "tdesc.h"
|
||||
|
||||
#if !defined (DGUX)
|
||||
#define DGUX 1
|
||||
#endif
|
||||
|
||||
#define TARGET_BYTE_ORDER BIG_ENDIAN
|
||||
|
||||
#define EXTRA_SYMTAB_INFO int coffsem;
|
||||
|
||||
/* This is not a CREATE_INFERIOR_HOOK because it also applies to
|
||||
remote debugging. */
|
||||
#define START_INFERIOR_HOOK () \
|
||||
#define START_INFERIOR_HOOK() \
|
||||
{ \
|
||||
extern int safe_to_init_tdesc_context; \
|
||||
extern int tdesc_handle; \
|
||||
extern dc_handle_t tdesc_handle; \
|
||||
\
|
||||
safe_to_init_tdesc_context = 0; \
|
||||
if (tdesc_handle) \
|
||||
@ -39,18 +45,22 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
} \
|
||||
}
|
||||
|
||||
dc_dcontext_t get_prev_context ();
|
||||
extern int stack_error;
|
||||
|
||||
#define EXTRA_FRAME_INFO dc_dcontext_t frame_context;
|
||||
#define INIT_EXTRA_FRAME_INFO(fci) \
|
||||
{ \
|
||||
if (fci->next_frame != NULL) \
|
||||
{ \
|
||||
extern jmp_buf stack_jmp; \
|
||||
struct frame_info *next_frame = fci->next; \
|
||||
/* The call to get_prev_context */ \
|
||||
/* will update current_context for us. */ \
|
||||
int stack_error = 1; \
|
||||
jmp_buf stack_jmp; \
|
||||
stack_error = 1; \
|
||||
if (!setjmp (stack_jmp)) \
|
||||
{ \
|
||||
prev->frame_context \
|
||||
fci->frame_context \
|
||||
= get_prev_context (next_frame->frame_context); \
|
||||
stack_error = 0; \
|
||||
} \
|
||||
@ -60,7 +70,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
next_frame->prev = 0; \
|
||||
return 0; \
|
||||
} \
|
||||
if (!prev->frame_context) \
|
||||
if (!fci->frame_context) \
|
||||
{ \
|
||||
next_frame->prev = 0; \
|
||||
return 0; \
|
||||
@ -357,7 +367,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
into consecutive registers starting from r2. */
|
||||
|
||||
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
|
||||
bcopy (&(((void *)REGBUF)[REGISTER_BYTE(RV_REGNUM)]), (VALBUF), TYPE_LENGTH (TYPE))
|
||||
bcopy (&(((char *)REGBUF)[REGISTER_BYTE(RV_REGNUM)]), (VALBUF), TYPE_LENGTH (TYPE))
|
||||
|
||||
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
|
||||
|
||||
@ -372,6 +382,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#define BELIEVE_PCC_PROMOTION 1
|
||||
|
||||
/* We provide our own get_saved_register in m88k-tdep.c. */
|
||||
#define GET_SAVED_REGISTER
|
||||
|
||||
/* Describe the pointer in each stack frame to the previous stack frame
|
||||
(its caller). */
|
||||
|
||||
@ -448,6 +461,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
frame_find_saved_regs (frame_info, &frame_saved_regs)
|
||||
|
||||
|
||||
/* There is not currently a functioning way to call functions in the
|
||||
inferior. */
|
||||
|
||||
/* But if there was this is where we'd put the call dummy. */
|
||||
/* #define CALL_DUMMY_LOCATION AFTER_TEXT_END */
|
||||
|
||||
/* When popping a frame on the 88k (say when doing a return command), the
|
||||
calling function only expects to have the "preserved" registers restored.
|
||||
Thus, those are the only ones that we even try to restore here. */
|
||||
@ -457,4 +476,6 @@ extern void pop_frame ();
|
||||
#define POP_FRAME pop_frame ()
|
||||
|
||||
/* BCS is a standard for binary compatibility. This machine uses it. */
|
||||
#define BCS
|
||||
#if !defined (BCS)
|
||||
#define BCS 1
|
||||
#endif
|
||||
|
@ -448,9 +448,12 @@ savestring (ptr, size)
|
||||
return p;
|
||||
}
|
||||
|
||||
/* The "const" is so it compiles under DGUX (which prototypes strsave
|
||||
in <string.h>. FIXME: This should be named "xstrsave", shouldn't it?
|
||||
Doesn't real strsave return NULL if out of memory? */
|
||||
char *
|
||||
strsave (ptr)
|
||||
char *ptr;
|
||||
const char *ptr;
|
||||
{
|
||||
return savestring (ptr, strlen (ptr));
|
||||
}
|
||||
|
@ -22,7 +22,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#define HOST_BYTE_ORDER BIG_ENDIAN
|
||||
|
||||
#define USG
|
||||
#if !defined (USG)
|
||||
#define USG 1
|
||||
#endif
|
||||
/* DGUX has bcopy(), etc. */
|
||||
#define USG_UTILS 0
|
||||
|
||||
@ -37,7 +39,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define bcmp(left,right,count) (memcmp((right),(left),(count)))
|
||||
#ifdef __GNUC__
|
||||
#define memcpy __builtin_memcpy
|
||||
#define memset __builtin_memset
|
||||
/* gcc doesn't have this, at least not gcc 1.92. */
|
||||
/* #define memset __builtin_memset */
|
||||
#define strcmp __builtin_strcmp
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user