Make it run on wingnut (88k, DGUX). Complete list of changes in the ChangeLog.

This commit is contained in:
Jim Kingdon 1991-05-03 06:02:03 +00:00
parent 6f48f7f198
commit 8aa13b8777
9 changed files with 1969 additions and 23 deletions

View File

@ -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
View 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
View 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
View 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 (&registers, 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
View 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);
}
}

View File

@ -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

View File

@ -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

View File

@ -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));
}

View File

@ -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