|
|
/* Table of opcodes for the Motorola M88k family. |
|
|
Copyright (C) 1989-2014 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: |
|
|
*/
|
|
|
|