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