| /* mmix.h -- Header file for MMIX opcode table | |
| Copyright (C) 2001-2023 Free Software Foundation, Inc. | |
| Written by Hans-Peter Nilsson (hp@bitrange.com) | |
| This file is part of GDB, GAS, and the GNU binutils. | |
| GDB, GAS, and the GNU binutils are free software; you can redistribute | |
| them and/or modify them under the terms of the GNU General Public | |
| License as published by the Free Software Foundation; either version 3, | |
| or (at your option) any later version. | |
| GDB, GAS, and the GNU binutils are distributed in the hope that they | |
| 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 file; see the file COPYING3. If not, write to the Free | |
| Software Foundation, 51 Franklin Street - Fifth Floor, Boston, | |
| MA 02110-1301, USA. */ | |
| /* We could have just a char*[] table indexed by the register number, but | |
| that would not allow for synonyms. The table is terminated with an | |
| entry with a NULL name. */ | |
| struct mmix_spec_reg | |
| { | |
| const char *name; | |
| unsigned int number; | |
| }; | |
| /* General indication of the type of instruction. */ | |
| enum mmix_insn_type | |
| { | |
| mmix_type_pseudo, | |
| mmix_type_normal, | |
| mmix_type_branch, | |
| mmix_type_condbranch, | |
| mmix_type_memaccess_octa, | |
| mmix_type_memaccess_tetra, | |
| mmix_type_memaccess_wyde, | |
| mmix_type_memaccess_byte, | |
| mmix_type_memaccess_block, | |
| mmix_type_jsr | |
| }; | |
| /* Type of operands an instruction takes. Use when parsing assembly code | |
| and disassembling. */ | |
| enum mmix_operands_type | |
| { | |
| mmix_operands_none = 0, | |
| /* All operands are registers: "$X,$Y,$Z". */ | |
| mmix_operands_regs, | |
| /* "$X,YZ", like SETH. */ | |
| mmix_operands_reg_yz, | |
| /* The regular "$X,$Y,$Z|Z". | |
| The Z is optional; if only "$X,$Y" is given, then "$X,$Y,0" is | |
| assumed. */ | |
| mmix_operands_regs_z_opt, | |
| /* The regular "$X,$Y,$Z|Z". */ | |
| mmix_operands_regs_z, | |
| /* "Address"; only JMP. Zero operands allowed unless GNU syntax. */ | |
| mmix_operands_jmp, | |
| /* "$X|X,$Y,$Z|Z": PUSHGO; like "3", but X can be expressed as an | |
| integer. */ | |
| mmix_operands_pushgo, | |
| /* Two registers or a register and a byte, like FLOT, possibly with | |
| rounding: "$X,$Z|Z" or "$X,ROUND_MODE,$Z|Z". */ | |
| mmix_operands_roundregs_z, | |
| /* "X,YZ", POP. Unless GNU syntax, zero or one operand is allowed. */ | |
| mmix_operands_pop, | |
| /* Two registers, possibly with rounding: "$X,$Z" or | |
| "$X,ROUND_MODE,$Z". */ | |
| mmix_operands_roundregs, | |
| /* "XYZ", like SYNC. */ | |
| mmix_operands_sync, | |
| /* "X,$Y,$Z|Z", like SYNCD. */ | |
| mmix_operands_x_regs_z, | |
| /* "$X,Y,$Z|Z", like NEG and NEGU. The Y field is optional, default 0. */ | |
| mmix_operands_neg, | |
| /* "$X,Address, like GETA or branches. */ | |
| mmix_operands_regaddr, | |
| /* "$X|X,Address, like PUSHJ. */ | |
| mmix_operands_pushj, | |
| /* "$X,spec_reg"; GET. */ | |
| mmix_operands_get, | |
| /* "spec_reg,$Z|Z"; PUT. */ | |
| mmix_operands_put, | |
| /* Two registers, "$X,$Y". */ | |
| mmix_operands_set, | |
| /* "$X,0"; SAVE. */ | |
| mmix_operands_save, | |
| /* "0,$Z"; UNSAVE. */ | |
| mmix_operands_unsave, | |
| /* "X,Y,Z"; like SWYM or TRAP. Zero (or 1 if GNU syntax) to three | |
| operands, interpreted as 0; XYZ; X, YZ and X, Y, Z. */ | |
| mmix_operands_xyz_opt, | |
| /* Just "Z", like RESUME. Unless GNU syntax, the operand can be omitted | |
| and will then be assumed zero. */ | |
| mmix_operands_resume, | |
| /* These are specials to handle that pseudo-directives are specified | |
| like ordinary insns when being mmixal-compatible. They signify the | |
| specific pseudo-directive rather than the operands type. */ | |
| /* LOC. */ | |
| mmix_operands_loc, | |
| /* PREFIX. */ | |
| mmix_operands_prefix, | |
| /* BYTE. */ | |
| mmix_operands_byte, | |
| /* WYDE. */ | |
| mmix_operands_wyde, | |
| /* TETRA. */ | |
| mmix_operands_tetra, | |
| /* OCTA. */ | |
| mmix_operands_octa, | |
| /* LOCAL. */ | |
| mmix_operands_local, | |
| /* BSPEC. */ | |
| mmix_operands_bspec, | |
| /* ESPEC. */ | |
| mmix_operands_espec, | |
| }; | |
| struct mmix_opcode | |
| { | |
| const char *name; | |
| unsigned long match; | |
| unsigned long lose; | |
| enum mmix_operands_type operands; | |
| /* This is used by the disassembly function. */ | |
| enum mmix_insn_type type; | |
| }; | |
| /* Declare the actual tables. */ | |
| extern const struct mmix_opcode mmix_opcodes[]; | |
| /* This one is terminated with an entry with a NULL name. */ | |
| extern const struct mmix_spec_reg mmix_spec_regs[]; | |
| /* Some insn values we use when padding and synthesizing address loads. */ | |
| #define IMM_OFFSET_BIT 1 | |
| #define COND_INV_BIT 0x8 | |
| #define PRED_INV_BIT 0x10 | |
| #define PUSHGO_INSN_BYTE 0xbeu | |
| #define GO_INSN_BYTE 0x9eu | |
| #define SETL_INSN_BYTE 0xe3u | |
| #define INCML_INSN_BYTE 0xe6u | |
| #define INCMH_INSN_BYTE 0xe5u | |
| #define INCH_INSN_BYTE 0xe4u | |
| #define SWYM_INSN_BYTE 0xfdu | |
| #define JMP_INSN_BYTE 0xf0u | |
| /* We can have 256 - 32 (local registers) - 1 ($255 is not allocatable) | |
| global registers. */ | |
| #define MAX_GREGS 223 |