blob: 20c92a4f16f3b37cdf9a26ecbc993119d0357d11 [file] [log] [blame]
/* Table of opcodes for the Motorola M88k family.
Copyright (C) 1989-2016 Free Software Foundation, Inc.
This file is part of GDB and GAS.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
/*
* 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().
*
* 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>
/* Define the number of bits in the primary opcode field of the instruction,
the destination field, the source 1 and source 2 fields. */
/* Size of opcode field. */
#define OP 8
/* Size of destination. */
#define DEST 6
/* Size of source1. */
#define SOURCE1 6
/* Size of source2. */
#define SOURCE2 6
/* Number of registers. */
#define REGs 32
/* Type definitions. */
typedef unsigned int UINT;
#define WORD long
#define FLAG unsigned
#define STATE short
/* The next four equates define the priorities that the various classes
* of instructions have regarding writing results back into registers and
* signalling exceptions. */
/* PMEM is also defined in <sys/param.h> on Delta 88's. Sigh! */
#undef PMEM
/* Integer priority. */
#define PINT 0
/* Floating point priority. */
#define PFLT 1
/* Memory priority. */
#define PMEM 2
/* Not applicable, instruction doesn't write to regs. */
#define NA 3
/* Highest of these priorities. */
#define HIPRI 3
/* 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 op:OP,
dest: DEST,
src1: SOURCE1,
src2: SOURCE2;
int ltncy,
extime,
/* Writeback priority. */
wb_pri;
/* Immediate size. */
unsigned imm_flags:2,
/* Register source 1 used. */
rs1_used:1,
/* Register source 2 used. */
rs2_used:1,
/* Register source/dest. used. */
rsd_used:1,
/* Complement. */
c_flag:1,
/* Upper half word. */
u_flag:1,
/* Execute next. */
n_flag:1,
/* Uses writeback slot. */
wb_flag:1,
/* Dest size. */
dest_64:1,
/* Source 1 size. */
s1_64:1,
/* Source 2 size. */
s2_64:1,
scale_flag:1,
/* Scaled register. */
brk_flg:1;
};
struct mem_segs
{
/* Pointer (returned by calloc) to segment. */
struct mem_wrd *seg;
/* Base load address from file headers. */
unsigned long baseaddr;
/* Ending address of segment. */
unsigned long endaddr;
/* Segment control flags (none defined). */
int flags;
};
#define MAXSEGS (10) /* max number of segment allowed */
#define MEMSEGSIZE (sizeof(struct mem_segs))/* size of mem_segs structure */
#if 0
#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 */
#endif
struct mem_wrd
{
/* Simulator instruction break down. */
struct IR_FIELDS opcode;
union {
/* Memory element break down. */
unsigned long l;
unsigned short s[2];
unsigned char c[4];
} mem;
};
/* Size of each 32 bit memory model. */
#define MEMWRDSIZE (sizeof (struct mem_wrd))
extern struct mem_segs memory[];
extern struct PROCESSOR m78000;
struct PROCESSOR
{
unsigned WORD
/* Execute instruction pointer. */
ip,
/* Vector base register. */
vbr,
/* Processor status register. */
psr;
/* Source 1. */
WORD S1bus,
/* Source 2. */
S2bus,
/* Destination. */
Dbus,
/* Data address bus. */
DAbus,
ALU,
/* Data registers. */
Regs[REGs],
/* Max clocks before reg is available. */
time_left[REGs],
/* Writeback priority of reg. */
wb_pri[REGs],
/* Integer unit control regs. */
SFU0_regs[REGs],
/* Floating point control regs. */
SFU1_regs[REGs],
Scoreboard[REGs],
Vbr;
unsigned WORD scoreboard,
Psw,
Tpsw;
/* Waiting for a jump instruction. */
FLAG jump_pending:1;
};
/* Size of immediate field. */
#define i26bit 1
#define i16bit 2
#define i10bit 3
/* Definitions for fields in psr. */
#define psr_mode 31
#define psr_rbo 30
#define psr_ser 29
#define psr_carry 28
#define psr_sf7m 11
#define psr_sf6m 10
#define psr_sf5m 9
#define psr_sf4m 8
#define psr_sf3m 7
#define psr_sf2m 6
#define psr_sf1m 5
#define psr_mam 4
#define psr_inm 3
#define psr_exm 2
#define psr_trm 1
#define psr_ovfm 0
/* 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
/* 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
/* Stores. */
#define STB LDHU+1
#define STH LDHU+2
#define ST LDHU+3
#define STD LDHU+4
/* Exchange. */
#define XMEMBU LDHU+5
#define XMEM LDHU+6
/* 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
/* Traps. */
#define TB1 BCND+1
#define TB0 BCND+2
#define TCND BCND+3
#define RTE BCND+4
#define TBND BCND+5
/* Misc. */
#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. */
enum operand_type
{
HEX = 1,
REG = 2,
CONT = 3,
IND = 3,
BF = 4,
/* Scaled register. */
REGSC = 5,
/* Control register. */
CRREG = 6,
/* Floating point control register. */
FCRREG = 7,
PCREL = 8,
CONDMASK = 9,
/* Extended register. */
XREG = 10,
/* Decimal. */
DEC = 11
};
/* Hashing specification. */
#define HASHVAL 79
/* Structure templates. */
typedef struct
{
unsigned int offset;
unsigned int width;
enum operand_type type;
} 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 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;
} INSTAB;
#define NO_OPERAND {0,0,0}
extern const INSTAB instructions[];
/*
* Local Variables:
* fill-column: 131
* End:
*/