Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'include/opcode/mips.h')
-rw-r--r--include/opcode/mips.h491
1 files changed, 131 insertions, 360 deletions
diff --git a/include/opcode/mips.h b/include/opcode/mips.h
index b299bd870..89ea3e9a7 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -332,310 +332,6 @@
#define OP_SH_EVAOFFSET 7
#define OP_MASK_EVAOFFSET 0x1ff
-/* Enumerates the various types of MIPS operand. */
-enum mips_operand_type {
- /* Described by mips_int_operand. */
- OP_INT,
-
- /* Described by mips_mapped_int_operand. */
- OP_MAPPED_INT,
-
- /* Described by mips_msb_operand. */
- OP_MSB,
-
- /* Described by mips_reg_operand. */
- OP_REG,
-
- /* Described by mips_reg_pair_operand. */
- OP_REG_PAIR,
-
- /* Described by mips_pcrel_operand. */
- OP_PCREL,
-
- /* A performance register. The field is 5 bits in size, but the supported
- values are much more restricted. */
- OP_PERF_REG,
-
- /* The final operand in a microMIPS ADDIUSP instruction. It mostly acts
- as a normal 9-bit signed offset that is multiplied by four, but there
- are four special cases:
-
- -2 * 4 => -258 * 4
- -1 * 4 => -257 * 4
- 0 * 4 => 256 * 4
- 1 * 4 => 257 * 4. */
- OP_ADDIUSP_INT,
-
- /* The target of a (D)CLO or (D)CLZ instruction. The operand spans two
- 5-bit register fields, both of which must be set to the destination
- register. */
- OP_CLO_CLZ_DEST,
-
- /* A register list for a microMIPS LWM or SWM instruction. The operand
- size determines whether the 16-bit or 32-bit encoding is required. */
- OP_LWM_SWM_LIST,
-
- /* The register list for an emulated MIPS16 ENTRY or EXIT instruction. */
- OP_ENTRY_EXIT_LIST,
-
- /* The register list and frame size for a MIPS16 SAVE or RESTORE
- instruction. */
- OP_SAVE_RESTORE_LIST,
-
- /* A 10-bit field VVVVVNNNNN used for octobyte and quadhalf instructions:
-
- V Meaning
- ----- -------
- 0EEE0 8 copies of $vN[E], OB format
- 0EE01 4 copies of $vN[E], QH format
- 10110 all 8 elements of $vN, OB format
- 10101 all 4 elements of $vN, QH format
- 11110 8 copies of immediate N, OB format
- 11101 4 copies of immediate N, QH format. */
- OP_MDMX_IMM_REG,
-
- /* A register operand that must match the destination register. */
- OP_REPEAT_DEST_REG,
-
- /* A register operand that must match the previous register. */
- OP_REPEAT_PREV_REG,
-
- /* $pc, which has no encoding in the architectural instruction. */
- OP_PC
-};
-
-/* Enumerates the types of MIPS register. */
-enum mips_reg_operand_type {
- /* General registers $0-$31. Software names like $at can also be used. */
- OP_REG_GP,
-
- /* Floating-point registers $f0-$f31. */
- OP_REG_FP,
-
- /* Coprocessor condition code registers $cc0-$cc7. FPU condition codes
- can also be written $fcc0-$fcc7. */
- OP_REG_CCC,
-
- /* FPRs used in a vector capacity. They can be written $f0-$f31
- or $v0-$v31, although the latter form is not used for the VR5400
- vector instructions. */
- OP_REG_VEC,
-
- /* DSP accumulator registers $ac0-$ac3. */
- OP_REG_ACC,
-
- /* Coprocessor registers $0-$31. Mnemonic names like c0_cause can
- also be used in some contexts. */
- OP_REG_COPRO,
-
- /* Hardware registers $0-$31. Mnemonic names like hwr_cpunum can
- also be used in some contexts. */
- OP_REG_HW
-};
-
-/* Base class for all operands. */
-struct mips_operand
-{
- /* The type of the operand. */
- enum mips_operand_type type;
-
- /* The operand occupies SIZE bits of the instruction, starting at LSB. */
- unsigned short size;
- unsigned short lsb;
-};
-
-/* Describes an integer operand with a regular encoding pattern. */
-struct mips_int_operand
-{
- struct mips_operand root;
-
- /* The low ROOT.SIZE bits of MAX_VAL encodes (MAX_VAL + BIAS) << SHIFT.
- The cyclically previous field value encodes 1 << SHIFT less than that,
- and so on. E.g.
-
- - for { { T, 4, L }, 14, 0, 0 }, field values 0...14 encode themselves,
- but 15 encodes -1.
-
- - { { T, 8, L }, 127, 0, 2 } is a normal signed 8-bit operand that is
- shifted left two places.
-
- - { { T, 3, L }, 8, 0, 0 } is a normal unsigned 3-bit operand except
- that 0 encodes 8.
-
- - { { ... }, 0, 1, 3 } means that N encodes (N + 1) << 3. */
- unsigned int max_val;
- int bias;
- unsigned int shift;
-
- /* True if the operand should be printed as hex rather than decimal. */
- bfd_boolean print_hex;
-};
-
-/* Uses a lookup table to describe a small integer operand. */
-struct mips_mapped_int_operand
-{
- struct mips_operand root;
-
- /* Maps each encoding value to the integer that it represents. */
- const int *int_map;
-
- /* True if the operand should be printed as hex rather than decimal. */
- bfd_boolean print_hex;
-};
-
-/* An operand that encodes the most significant bit position of a bitfield.
- Given a bitfield that spans bits [MSB, LSB], some operands of this type
- encode MSB directly while others encode MSB - LSB. Each operand of this
- type is preceded by an integer operand that specifies LSB.
-
- The assembly form varies between instructions. For some instructions,
- such as EXT, the operand is written as the bitfield size. For others,
- such as EXTS, it is written in raw MSB - LSB form. */
-struct mips_msb_operand
-{
- struct mips_operand root;
-
- /* The assembly-level operand encoded by a field value of 0. */
- int bias;
-
- /* True if the operand encodes MSB directly, false if it encodes
- MSB - LSB. */
- bfd_boolean add_lsb;
-
- /* The maximum value of MSB + 1. */
- unsigned int opsize;
-};
-
-/* Describes a single register operand. */
-struct mips_reg_operand
-{
- struct mips_operand root;
-
- /* The type of register. */
- enum mips_reg_operand_type reg_type;
-
- /* If nonnull, REG_MAP[N] gives the register associated with encoding N,
- otherwise the encoding is the same as the register number. */
- const unsigned char *reg_map;
-};
-
-/* Describes an operand that encodes a pair of registers. */
-struct mips_reg_pair_operand
-{
- struct mips_operand root;
-
- /* The type of register. */
- enum mips_reg_operand_type reg_type;
-
- /* Encoding N represents REG1_MAP[N], REG2_MAP[N]. */
- unsigned char *reg1_map;
- unsigned char *reg2_map;
-};
-
-/* Describes an operand that is calculated relative to a base PC.
- The base PC is usually the address of the following instruction,
- but the rules for MIPS16 instructions like ADDIUPC are more complicated. */
-struct mips_pcrel_operand
-{
- struct mips_operand root;
-
- /* The low ALIGN_LOG2 bits of the base PC are cleared to give PC'. */
- unsigned int align_log2 : 8;
-
- /* The operand is shifted left SHIFT places and added to PC'.
- The operand is signed if IS_SIGNED. */
- unsigned int shift : 8;
- unsigned int is_signed : 1;
-
- /* If INCLUDE_ISA_BIT, the ISA bit of the original base PC is then
- reinstated. This is true for jumps and branches and false for
- PC-relative data instructions. */
- unsigned int include_isa_bit : 1;
-
- /* If FLIP_ISA_BIT, the ISA bit of the result is inverted.
- This is true for JALX and false otherwise. */
- unsigned int flip_isa_bit : 1;
-};
-
-/* Return a version of INSN in which the field specified by OPERAND
- has value UVAL. */
-
-static inline unsigned int
-mips_insert_operand (const struct mips_operand *operand, unsigned int insn,
- unsigned int uval)
-{
- unsigned int mask;
-
- mask = (1 << operand->size) - 1;
- insn &= ~(mask << operand->lsb);
- insn |= (uval & mask) << operand->lsb;
- return insn;
-}
-
-/* Extract OPERAND from instruction INSN. */
-
-static inline unsigned int
-mips_extract_operand (const struct mips_operand *operand, unsigned int insn)
-{
- return (insn >> operand->lsb) & ((1 << operand->size) - 1);
-}
-
-/* UVAL is the value encoded by OPERAND. Return it in signed form. */
-
-static inline int
-mips_signed_operand (const struct mips_operand *operand, unsigned int uval)
-{
- unsigned int sign_bit, mask;
-
- mask = (1 << operand->size) - 1;
- sign_bit = 1 << (operand->size - 1);
- return ((uval + sign_bit) & mask) - sign_bit;
-}
-
-/* Return the integer that OPERAND encodes as UVAL. */
-
-static inline int
-mips_decode_int_operand (const struct mips_int_operand *operand,
- unsigned int uval)
-{
- uval |= (operand->max_val - uval) & -(1 << operand->root.size);
- uval += operand->bias;
- uval <<= operand->shift;
- return uval;
-}
-
-/* Return the register that OPERAND encodes as UVAL. */
-
-static inline int
-mips_decode_reg_operand (const struct mips_reg_operand *operand,
- unsigned int uval)
-{
- if (operand->reg_map)
- uval = operand->reg_map[uval];
- return uval;
-}
-
-/* PC-relative operand OPERAND has value UVAL and is relative to BASE_PC.
- Return the address that it encodes. */
-
-static inline bfd_vma
-mips_decode_pcrel_operand (const struct mips_pcrel_operand *operand,
- bfd_vma base_pc, unsigned int uval)
-{
- bfd_vma addr;
-
- addr = base_pc & -(1 << operand->align_log2);
- if (operand->is_signed)
- addr += mips_signed_operand (&operand->root, uval) * (1 << operand->shift);
- else
- addr += uval << operand->shift;
- if (operand->include_isa_bit)
- addr |= base_pc & 1;
- if (operand->flip_isa_bit)
- addr ^= 1;
- return addr;
-}
-
/* This structure holds information for a particular instruction. */
struct mips_opcode
@@ -847,67 +543,71 @@ struct mips_opcode
/* These are the bits which may be set in the pinfo field of an
instructions, if it is not equal to INSN_MACRO. */
-/* Writes to operand number N. */
-#define INSN_WRITE_SHIFT 0
-#define INSN_WRITE_1 0x00000001
-#define INSN_WRITE_2 0x00000002
-#define INSN_WRITE_ALL 0x00000003
-/* Reads from operand number N. */
-#define INSN_READ_SHIFT 2
-#define INSN_READ_1 0x00000004
-#define INSN_READ_2 0x00000008
-#define INSN_READ_3 0x00000010
-#define INSN_READ_4 0x00000020
-#define INSN_READ_ALL 0x0000003c
+/* Modifies the general purpose register in OP_*_RD. */
+#define INSN_WRITE_GPR_D 0x00000001
+/* Modifies the general purpose register in OP_*_RT. */
+#define INSN_WRITE_GPR_T 0x00000002
/* Modifies general purpose register 31. */
-#define INSN_WRITE_GPR_31 0x00000040
+#define INSN_WRITE_GPR_31 0x00000004
+/* Modifies the floating point register in OP_*_FD. */
+#define INSN_WRITE_FPR_D 0x00000008
+/* Modifies the floating point register in OP_*_FS. */
+#define INSN_WRITE_FPR_S 0x00000010
+/* Modifies the floating point register in OP_*_FT. */
+#define INSN_WRITE_FPR_T 0x00000020
+/* Reads the general purpose register in OP_*_RS. */
+#define INSN_READ_GPR_S 0x00000040
+/* Reads the general purpose register in OP_*_RT. */
+#define INSN_READ_GPR_T 0x00000080
+/* Reads the floating point register in OP_*_FS. */
+#define INSN_READ_FPR_S 0x00000100
+/* Reads the floating point register in OP_*_FT. */
+#define INSN_READ_FPR_T 0x00000200
+/* Reads the floating point register in OP_*_FR. */
+#define INSN_READ_FPR_R 0x00000400
/* Modifies coprocessor condition code. */
-#define INSN_WRITE_COND_CODE 0x00000080
+#define INSN_WRITE_COND_CODE 0x00000800
/* Reads coprocessor condition code. */
-#define INSN_READ_COND_CODE 0x00000100
+#define INSN_READ_COND_CODE 0x00001000
/* TLB operation. */
-#define INSN_TLB 0x00000200
+#define INSN_TLB 0x00002000
/* Reads coprocessor register other than floating point register. */
-#define INSN_COP 0x00000400
+#define INSN_COP 0x00004000
/* Instruction loads value from memory, requiring delay. */
-#define INSN_LOAD_MEMORY_DELAY 0x00000800
+#define INSN_LOAD_MEMORY_DELAY 0x00008000
/* Instruction loads value from coprocessor, requiring delay. */
-#define INSN_LOAD_COPROC_DELAY 0x00001000
+#define INSN_LOAD_COPROC_DELAY 0x00010000
/* Instruction has unconditional branch delay slot. */
-#define INSN_UNCOND_BRANCH_DELAY 0x00002000
+#define INSN_UNCOND_BRANCH_DELAY 0x00020000
/* Instruction has conditional branch delay slot. */
-#define INSN_COND_BRANCH_DELAY 0x00004000
+#define INSN_COND_BRANCH_DELAY 0x00040000
/* Conditional branch likely: if branch not taken, insn nullified. */
-#define INSN_COND_BRANCH_LIKELY 0x00008000
+#define INSN_COND_BRANCH_LIKELY 0x00080000
/* Moves to coprocessor register, requiring delay. */
-#define INSN_COPROC_MOVE_DELAY 0x00010000
+#define INSN_COPROC_MOVE_DELAY 0x00100000
/* Loads coprocessor register from memory, requiring delay. */
-#define INSN_COPROC_MEMORY_DELAY 0x00020000
+#define INSN_COPROC_MEMORY_DELAY 0x00200000
/* Reads the HI register. */
-#define INSN_READ_HI 0x00040000
+#define INSN_READ_HI 0x00400000
/* Reads the LO register. */
-#define INSN_READ_LO 0x00080000
+#define INSN_READ_LO 0x00800000
/* Modifies the HI register. */
-#define INSN_WRITE_HI 0x00100000
+#define INSN_WRITE_HI 0x01000000
/* Modifies the LO register. */
-#define INSN_WRITE_LO 0x00200000
+#define INSN_WRITE_LO 0x02000000
/* Not to be placed in a branch delay slot, either architecturally
or for ease of handling (such as with instructions that take a trap). */
-#define INSN_NO_DELAY_SLOT 0x00400000
+#define INSN_NO_DELAY_SLOT 0x04000000
/* Instruction stores value into memory. */
-#define INSN_STORE_MEMORY 0x00800000
+#define INSN_STORE_MEMORY 0x08000000
/* Instruction uses single precision floating point. */
-#define FP_S 0x01000000
+#define FP_S 0x10000000
/* Instruction uses double precision floating point. */
-#define FP_D 0x02000000
+#define FP_D 0x20000000
/* Instruction is part of the tx39's integer multiply family. */
-#define INSN_MULT 0x04000000
-/* Reads general purpose register 24. */
-#define INSN_READ_GPR_24 0x08000000
-/* Writes to general purpose register 24. */
-#define INSN_WRITE_GPR_24 0x10000000
-/* A user-defined instruction. */
-#define INSN_UDI 0x20000000
+#define INSN_MULT 0x40000000
+/* Modifies the general purpose register in MICROMIPSOP_*_RS. */
+#define INSN_WRITE_GPR_S 0x80000000
/* Instruction is actually a macro. It should be ignored by the
disassembler, and requires special treatment by the assembler. */
#define INSN_MACRO 0xffffffff
@@ -929,24 +629,62 @@ struct mips_opcode
only be set for macros. For instructions, FP_D in pinfo carries the
same information. */
#define INSN2_M_FP_D 0x00000010
+/* Modifies the general purpose register in OP_*_RZ. */
+#define INSN2_WRITE_GPR_Z 0x00000020
+/* Modifies the floating point register in OP_*_FZ. */
+#define INSN2_WRITE_FPR_Z 0x00000040
+/* Reads the general purpose register in OP_*_RZ. */
+#define INSN2_READ_GPR_Z 0x00000080
+/* Reads the floating point register in OP_*_FZ. */
+#define INSN2_READ_FPR_Z 0x00000100
+/* Reads the general purpose register in OP_*_RD. */
+#define INSN2_READ_GPR_D 0x00000200
+
+
/* Instruction has a branch delay slot that requires a 16-bit instruction. */
-#define INSN2_BRANCH_DELAY_16BIT 0x00000020
+#define INSN2_BRANCH_DELAY_16BIT 0x00000400
/* Instruction has a branch delay slot that requires a 32-bit instruction. */
-#define INSN2_BRANCH_DELAY_32BIT 0x00000040
-/* Writes to the stack pointer ($29). */
-#define INSN2_WRITE_SP 0x00000080
-/* Reads from the stack pointer ($29). */
-#define INSN2_READ_SP 0x00000100
+#define INSN2_BRANCH_DELAY_32BIT 0x00000800
+/* Reads the floating point register in MICROMIPSOP_*_FD. */
+#define INSN2_READ_FPR_D 0x00001000
+/* Modifies the general purpose register in MICROMIPSOP_*_MB. */
+#define INSN2_WRITE_GPR_MB 0x00002000
+/* Reads the general purpose register in MICROMIPSOP_*_MC. */
+#define INSN2_READ_GPR_MC 0x00004000
+/* Reads/writes the general purpose register in MICROMIPSOP_*_MD. */
+#define INSN2_MOD_GPR_MD 0x00008000
+/* Reads the general purpose register in MICROMIPSOP_*_ME. */
+#define INSN2_READ_GPR_ME 0x00010000
+/* Reads/writes the general purpose register in MICROMIPSOP_*_MF. */
+#define INSN2_MOD_GPR_MF 0x00020000
+/* Reads the general purpose register in MICROMIPSOP_*_MG. */
+#define INSN2_READ_GPR_MG 0x00040000
+/* Reads the general purpose register in MICROMIPSOP_*_MJ. */
+#define INSN2_READ_GPR_MJ 0x00080000
+/* Modifies the general purpose register in MICROMIPSOP_*_MJ. */
+#define INSN2_WRITE_GPR_MJ 0x00100000
+/* Reads the general purpose register in MICROMIPSOP_*_MP. */
+#define INSN2_READ_GPR_MP 0x00200000
+/* Modifies the general purpose register in MICROMIPSOP_*_MP. */
+#define INSN2_WRITE_GPR_MP 0x00400000
+/* Reads the general purpose register in MICROMIPSOP_*_MQ. */
+#define INSN2_READ_GPR_MQ 0x00800000
+/* Reads/Writes the stack pointer ($29). */
+#define INSN2_MOD_SP 0x01000000
/* Reads the RA ($31) register. */
-#define INSN2_READ_GPR_31 0x00000200
+#define INSN2_READ_GPR_31 0x02000000
+/* Reads the global pointer ($28). */
+#define INSN2_READ_GP 0x04000000
/* Reads the program counter ($pc). */
-#define INSN2_READ_PC 0x00000400
+#define INSN2_READ_PC 0x08000000
/* Is an unconditional branch insn. */
-#define INSN2_UNCOND_BRANCH 0x00000800
+#define INSN2_UNCOND_BRANCH 0x10000000
/* Is a conditional branch insn. */
-#define INSN2_COND_BRANCH 0x00001000
-/* Reads from $16. This is true of the MIPS16 0x6500 nop. */
-#define INSN2_READ_GPR_16 0x00002000
+#define INSN2_COND_BRANCH 0x20000000
+/* Modifies the general purpose registers in MICROMIPSOP_*_MH. */
+#define INSN2_WRITE_GPR_MH 0x40000000
+/* Reads the general purpose registers in MICROMIPSOP_*_MM/N. */
+#define INSN2_READ_GPR_MMN 0x80000000
/* Masks used to mark instructions to indicate which MIPS ISA level
they were introduced in. INSN_ISA_MASK masks an enumeration that
@@ -1477,7 +1215,6 @@ enum
Many instructions are short hand for other instructions (i.e., The
jal <register> instruction is short for jalr <register>). */
-extern const struct mips_operand *decode_mips_operand (const char *);
extern const struct mips_opcode mips_builtin_opcodes[];
extern const int bfd_mips_num_builtin_opcodes;
extern struct mips_opcode *mips_opcodes;
@@ -1568,8 +1305,6 @@ extern int bfd_mips_num_opcodes;
"l" register list for entry instruction
"L" register list for exit instruction
- "I" an immediate value used for macros
-
The remaining codes may be extended. Except as otherwise noted,
the full extended operand is a 16 bit signed value.
"<" 3 bit unsigned shift count * 0 (MIPS16OP_*_RZ) (full 5 bit unsigned)
@@ -1602,6 +1337,44 @@ extern int bfd_mips_num_opcodes;
#define MIPS16_ALL_ARGS 0xe
#define MIPS16_ALL_STATICS 0xb
+/* For the mips16, we use the same opcode table format and a few of
+ the same flags. However, most of the flags are different. */
+
+/* Modifies the register in MIPS16OP_*_RX. */
+#define MIPS16_INSN_WRITE_X 0x00000001
+/* Modifies the register in MIPS16OP_*_RY. */
+#define MIPS16_INSN_WRITE_Y 0x00000002
+/* Modifies the register in MIPS16OP_*_RZ. */
+#define MIPS16_INSN_WRITE_Z 0x00000004
+/* Modifies the T ($24) register. */
+#define MIPS16_INSN_WRITE_T 0x00000008
+/* Modifies the SP ($29) register. */
+#define MIPS16_INSN_WRITE_SP 0x00000010
+/* Modifies the RA ($31) register. */
+#define MIPS16_INSN_WRITE_31 0x00000020
+/* Modifies the general purpose register in MIPS16OP_*_REG32R. */
+#define MIPS16_INSN_WRITE_GPR_Y 0x00000040
+/* Reads the register in MIPS16OP_*_RX. */
+#define MIPS16_INSN_READ_X 0x00000080
+/* Reads the register in MIPS16OP_*_RY. */
+#define MIPS16_INSN_READ_Y 0x00000100
+/* Reads the register in MIPS16OP_*_MOVE32Z. */
+#define MIPS16_INSN_READ_Z 0x00000200
+/* Reads the T ($24) register. */
+#define MIPS16_INSN_READ_T 0x00000400
+/* Reads the SP ($29) register. */
+#define MIPS16_INSN_READ_SP 0x00000800
+/* Reads the RA ($31) register. */
+#define MIPS16_INSN_READ_31 0x00001000
+/* Reads the program counter. */
+#define MIPS16_INSN_READ_PC 0x00002000
+/* Reads the general purpose register in MIPS16OP_*_REGR32. */
+#define MIPS16_INSN_READ_GPR_X 0x00004000
+/* Is an unconditional branch insn. */
+#define MIPS16_INSN_UNCOND_BRANCH 0x00008000
+/* Is a conditional branch insn. */
+#define MIPS16_INSN_COND_BRANCH 0x00010000
+
/* The following flags have the same value for the mips16 opcode
table:
@@ -1618,7 +1391,6 @@ extern int bfd_mips_num_opcodes;
FP_D (never used)
*/
-extern const struct mips_operand *decode_mips16_operand (char, bfd_boolean);
extern const struct mips_opcode mips16_opcodes[];
extern const int bfd_mips16_num_opcodes;
@@ -2006,7 +1778,6 @@ extern const int bfd_mips16_num_opcodes;
" bcdefghij lmn pq st xyz"
*/
-extern const struct mips_operand *decode_micromips_operand (const char *);
extern const struct mips_opcode micromips_opcodes[];
extern const int bfd_micromips_num_opcodes;