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