add mips1 and mips32r2 isa definitions

This commit is contained in:
Freya Murphy 2024-10-09 12:08:58 -04:00
parent fafc54ab72
commit 720b95b5d9
Signed by: freya
GPG key ID: 744AB800E383AE52
7 changed files with 2072 additions and 2 deletions

View file

@ -6,6 +6,7 @@
#include <elf.h> #include <elf.h>
#include <arpa/inet.h> #include <arpa/inet.h>
/// mips is a big endian system
#if __BYTE_ORDER == __LITTLE_ENDIAN #if __BYTE_ORDER == __LITTLE_ENDIAN
#define B32(n) (__bswap_constant_32(n)) #define B32(n) (__bswap_constant_32(n))
#define B16(n) (__bswap_constant_16(n)) #define B16(n) (__bswap_constant_16(n))
@ -32,7 +33,7 @@ static const Elf32_Ehdr MIPS_ELF_EHDR =
.e_machine = B16(EM_MIPS), .e_machine = B16(EM_MIPS),
.e_version = B32(EV_CURRENT), .e_version = B32(EV_CURRENT),
.e_entry = 0x00, .e_entry = 0x00,
.e_flags = B32(EF_MIPS_ARCH_32R6 | EF_MIPS_NAN2008 | EF_MIPS_ABI_O32), .e_flags = 0x00,
.e_ehsize = B16(sizeof(Elf32_Ehdr)), .e_ehsize = B16(sizeof(Elf32_Ehdr)),
.e_phentsize = B16(sizeof(Elf32_Phdr)), .e_phentsize = B16(sizeof(Elf32_Phdr)),
.e_shentsize = B16(sizeof(Elf32_Shdr)), .e_shentsize = B16(sizeof(Elf32_Shdr)),

View file

@ -43,6 +43,42 @@ enum mips32_register {
MIPS32_REG_RA = 31, MIPS32_REG_RA = 31,
}; };
/* all mips fp registers $f0-$f31 */
enum mips32_fp_register {
MIPS32_REG_F0 = 0,
MIPS32_REG_F1 = 1,
MIPS32_REG_F2 = 2,
MIPS32_REG_F3 = 3,
MIPS32_REG_F4 = 4,
MIPS32_REG_F5 = 5,
MIPS32_REG_F6 = 6,
MIPS32_REG_F7 = 7,
MIPS32_REG_F8 = 8,
MIPS32_REG_F9 = 9,
MIPS32_REG_F10 = 10,
MIPS32_REG_F11 = 11,
MIPS32_REG_F12 = 12,
MIPS32_REG_F13 = 13,
MIPS32_REG_F14 = 14,
MIPS32_REG_F15 = 15,
MIPS32_REG_F16 = 16,
MIPS32_REG_F17 = 17,
MIPS32_REG_F18 = 18,
MIPS32_REG_F19 = 19,
MIPS32_REG_F20 = 20,
MIPS32_REG_F21 = 21,
MIPS32_REG_F22 = 22,
MIPS32_REG_F23 = 23,
MIPS32_REG_F24 = 24,
MIPS32_REG_F25 = 25,
MIPS32_REG_F26 = 26,
MIPS32_REG_F27 = 27,
MIPS32_REG_F28 = 28,
MIPS32_REG_F29 = 29,
MIPS32_REG_F30 = 30,
MIPS32_REG_F31 = 31,
};
/* mips instruction */ /* mips instruction */
union mips32_instruction { union mips32_instruction {
/* raw ins */ /* raw ins */
@ -77,6 +113,48 @@ union mips32_instruction {
uint32_t bfunct : 5; uint32_t bfunct : 5;
uint32_t : 11; uint32_t : 11;
}; };
/* coprocessor */
struct {
uint32_t : 21;
uint32_t cfunct : 5;
uint32_t : 6;
};
/* flags */
struct {
// 6 bit
uint32_t : 5;
uint32_t sc : 1; // interrupt
// 5 bit
uint32_t rv : 1; // rotate variable
uint32_t : 3;
uint32_t hb : 1; // hazard barrier
// 5 bit
uint32_t : 5;
// 5 bit
uint32_t tf : 1; // true false
uint32_t nd : 1; //
uint32_t cc : 3; // code
// 5 bit
uint32_t r : 1; // rotate
uint32_t : 3;
uint32_t c0 : 1; // cop0
// 6 bit
uint32_t : 6;
};
/* break code */
struct {
uint32_t : 6;
uint32_t code : 20;
uint32_t : 6;
};
/* floating point */
struct {
uint32_t : 6;
uint32_t fd : 5;
uint32_t fs : 5;
uint32_t ft : 5;
uint32_t : 11;
};
} __attribute__((packed)); } __attribute__((packed));
/// grammer syntax: /// grammer syntax:

227
include/mips1.h Normal file
View file

@ -0,0 +1,227 @@
/* Copyright (c) 2024 Freya Murphy */
#ifndef __MIPS1_H__
#define __MIPS1_H__
#include <mlimits.h>
#include <stdint.h>
#include <mips.h>
// TODO:
// CFC1
// CTC1
// COP0-3
// LWC1-3
// SWC1-3
/* mips instructions */
enum mips1_instruction_type {
MIPS1_INS_ADD,
MIPS1_INS_ADDI,
MIPS1_INS_ADDIU,
MIPS1_INS_ADDU,
MIPS1_INS_AND,
MIPS1_INS_ANDI,
MIPS1_INS_BC1F,
MIPS1_INS_BC1T,
MIPS1_INS_BEQ,
MIPS1_INS_BGEZ,
MIPS1_INS_BGEZAL,
MIPS1_INS_BGTZ,
MIPS1_INS_BLEZ,
MIPS1_INS_BLTZAL,
MIPS1_INS_BLTZ,
MIPS1_INS_BNE,
MIPS1_INS_BREAK,
MIPS1_INS_CLO,
MIPS1_INS_CLZ,
MIPS1_INS_DIV,
MIPS1_INS_DIVU,
MIPS1_INS_ERET,
MIPS1_INS_J,
MIPS1_INS_JAL,
MIPS1_INS_JALR,
MIPS1_INS_JR,
MIPS1_INS_LB,
MIPS1_INS_LBU,
MIPS1_INS_LH,
MIPS1_INS_LHU,
MIPS1_INS_LL,
MIPS1_INS_LUI,
MIPS1_INS_LW,
MIPS1_INS_LWC1,
MIPS1_INS_LWL,
MIPS1_INS_LWR,
MIPS1_INS_MADD,
MIPS1_INS_MADDU,
MIPS1_INS_MFC0,
MIPS1_INS_MFC1,
MIPS1_INS_MFHI,
MIPS1_INS_MFLO,
MIPS1_INS_MOVN,
MIPS1_INS_MOVZ,
MIPS1_INS_MSUB,
MIPS1_INS_MSUBU,
MIPS1_INS_MTC0,
MIPS1_INS_MTC1,
MIPS1_INS_MTHI,
MIPS1_INS_MTLO,
MIPS1_INS_MUL,
MIPS1_INS_MULT,
MIPS1_INS_MULTU,
MIPS1_INS_NOR,
MIPS1_INS_OR,
MIPS1_INS_ORI,
MIPS1_INS_SB,
MIPS1_INS_SC,
MIPS1_INS_SDC1,
MIPS1_INS_SH,
MIPS1_INS_SLL,
MIPS1_INS_SLLV,
MIPS1_INS_SLT,
MIPS1_INS_SLTI,
MIPS1_INS_SLTIU,
MIPS1_INS_SLTU,
MIPS1_INS_SRA,
MIPS1_INS_SRAV,
MIPS1_INS_SRL,
MIPS1_INS_SRLV,
MIPS1_INS_SUB,
MIPS1_INS_SUBU,
MIPS1_INS_SW,
MIPS1_INS_SWC1,
MIPS1_INS_SWL,
MIPS1_INS_SWR,
MIPS1_INS_SYSCALL,
MIPS1_INS_TEQ,
MIPS1_INS_TEQI,
MIPS1_INS_TGE,
MIPS1_INS_TGEI,
MIPS1_INS_TGEIU,
MIPS1_INS_TGEU,
MIPS1_INS_TLT,
MIPS1_INS_TLTI,
MIPS1_INS_TLTIU,
MIPS1_INS_TLTU,
MIPS1_INS_TNE,
MIPS1_INS_TNEI,
MIPS1_INS_XOR,
MIPS1_INS_XORI,
__MIPS1_INS_NULL,
};
// op code groups
#define MIPS1_OP_SPECIAL 0b000000
#define MIPS1_OP_SPECIAL2 0b011100
#define MIPS1_OP_REGIMM 0b000001
#define MIPS1_OP_COP0 0b010000
#define MIPS1_OP_COP1 0b010001
// op codes
#define MIPS1_OP_ADDI 0b001000
#define MIPS1_OP_ADDIU 0b001001
#define MIPS1_OP_ANDI 0b001100
#define MIPS1_OP_BEQ 0b000100
#define MIPS1_OP_BGTZ 0b000111
#define MIPS1_OP_BLEZ 0b000110
#define MIPS1_OP_BNE 0b000101
#define MIPS1_OP_J 0b000010
#define MIPS1_OP_JAL 0b000011
#define MIPS1_OP_LB 0b100000
#define MIPS1_OP_LBU 0b100100
#define MIPS1_OP_LH 0b100001
#define MIPS1_OP_LHU 0b100101
#define MIPS1_OP_LL 0b110000
#define MIPS1_OP_LUI 0b001111
#define MIPS1_OP_LW 0b100011
#define MIPS1_OP_LWC1 0b110001
#define MIPS1_OP_LWL 0b100010
#define MIPS1_OP_LWR 0b100110
#define MIPS1_OP_ORI 0b001101
#define MIPS1_OP_SB 0b101000
#define MIPS1_OP_SC 0b111000
#define MIPS1_OP_SDC1 0b111101
#define MIPS1_OP_SH 0b101001
#define MIPS1_OP_SLTI 0b001010
#define MIPS1_OP_SLTIU 0b001011
#define MIPS1_OP_SW 0b101011
#define MIPS1_OP_SWC1 0b111001
#define MIPS1_OP_SWL 0b101010
#define MIPS1_OP_SWR 0b101110
#define MIPS1_OP_XORI 0b001110
// op special
#define MIPS1_FUNCT_ADD 0b100000
#define MIPS1_FUNCT_ADDU 0b100001
#define MIPS1_FUNCT_AND 0b100100
#define MIPS1_FUNCT_BREAK 0b001101
#define MIPS1_FUNCT_DIV 0b011010
#define MIPS1_FUNCT_DIVU 0b011011
#define MIPS1_FUNCT_JALR 0b001001
#define MIPS1_FUNCT_JR 0b001000
#define MIPS1_FUNCT_MFHI 0b010000
#define MIPS1_FUNCT_MFLO 0b010010
#define MIPS1_FUNCT_MOVN 0b001011
#define MIPS1_FUNCT_MOVZ 0b001010
#define MIPS1_FUNCT_MTHI 0b010001
#define MIPS1_FUNCT_MTLO 0b010011
#define MIPS1_FUNCT_MULT 0b011000
#define MIPS1_FUNCT_MULTU 0b011001
#define MIPS1_FUNCT_NOR 0b100111
#define MIPS1_FUNCT_OR 0b100101
#define MIPS1_FUNCT_SLL 0b000000
#define MIPS1_FUNCT_SLLV 0b000100
#define MIPS1_FUNCT_SLT 0b101010
#define MIPS1_FUNCT_SLTU 0b101011
#define MIPS1_FUNCT_SRA 0b000011
#define MIPS1_FUNCT_SRAV 0b000111
#define MIPS1_FUNCT_SRL 0b000010
#define MIPS1_FUNCT_SRLV 0b000110
#define MIPS1_FUNCT_SUB 0b100010
#define MIPS1_FUNCT_SUBU 0b100011
#define MIPS1_FUNCT_SYSCALL 0b001100
#define MIPS1_FUNCT_TEQ 0b110100
#define MIPS1_FUNCT_TGE 0b110000
#define MIPS1_FUNCT_TGEU 0b110001
#define MIPS1_FUNCT_TLT 0b110010
#define MIPS1_FUNCT_TLTU 0b110011
#define MIPS1_FUNCT_TNE 0b110110
#define MIPS1_FUNCT_XOR 0b100110
// op special 2
#define MIPS1_FUNCT_CLO 0b100001
#define MIPS1_FUNCT_CLZ 0b100000
#define MIPS1_FUNCT_MADD 0b000000
#define MIPS1_FUNCT_MADDU 0b000001
#define MIPS1_FUNCT_MSUB 0b000100
#define MIPS1_FUNCT_MSUBU 0b000101
#define MIPS1_FUNCT_MUL 0b100000
// op regimm
#define MIPS1_FUNCT_BGEZ 0b00001
#define MIPS1_FUNCT_BGEZAL 0b10001
#define MIPS1_FUNCT_BLTZ 0b00001
#define MIPS1_FUNCT_BLTZAL 0b10000
#define MIPS1_FUNCT_TEQI 0b01100
#define MIPS1_FUNCT_TGEI 0b01000
#define MIPS1_FUNCT_TGEIU 0b01001
#define MIPS1_FUNCT_TLTI 0b01010
#define MIPS1_FUNCT_TLTIU 0b01011
#define MIPS1_FUNCT_TNEI 0b01110
// op cop
#define MIPS1_FUNCT_BC 0b01000
#define MIPS1_FUNCT_MF 0b00000
#define MIPS1_FUNCT_MT 0b00100
// sub op c0
#define MIPS1_FUNCT_ERET 0b011000
#define __MIPS1_INS_LEN (__MIPS1_INS_NULL)
#define __MIPS1_PSEUDO_LEN (34)
#define __MIPS1_GRAMMER_LEN (__MIPS1_INS_LEN + __MIPS1_PSEUDO_LEN)
extern struct mips32_grammer mips1_grammers[__MIPS1_GRAMMER_LEN];
extern union mips32_instruction mips1_instructions[__MIPS1_INS_LEN];
#endif /* __MIPS1_H__ */

342
include/mips32r2.h Normal file
View file

@ -0,0 +1,342 @@
/* Copyright (c) 2024 Freya Murphy */
#ifndef __MIPS32R2_H__
#define __MIPS32R2_H__
#include <mlimits.h>
#include <stdint.h>
#include <mips.h>
// TODO:
// balc
/* mips instructions */
enum mips32r2_instruction_type {
MIPS32R2_INS_ADD,
MIPS32R2_INS_ADDI,
MIPS32R2_INS_ADDIU,
MIPS32R2_INS_ADDU,
MIPS32R2_INS_AND,
MIPS32R2_INS_ANDI,
MIPS32R2_INS_BC1F,
MIPS32R2_INS_BC1FL,
MIPS32R2_INS_BC1T,
MIPS32R2_INS_BC1TL,
MIPS32R2_INS_BC2F,
MIPS32R2_INS_BC2FL,
MIPS32R2_INS_BC2T,
MIPS32R2_INS_BC2TL,
MIPS32R2_INS_BEQ,
MIPS32R2_INS_BEQL,
MIPS32R2_INS_BGEZ,
MIPS32R2_INS_BGEZAL,
MIPS32R2_INS_BGEZALL,
MIPS32R2_INS_BGEZL,
MIPS32R2_INS_BGTZ,
MIPS32R2_INS_BGTZL,
MIPS32R2_INS_BLEZ,
MIPS32R2_INS_BLEZL,
MIPS32R2_INS_BLTZ,
MIPS32R2_INS_BLTZAL,
MIPS32R2_INS_BLTZALL,
MIPS32R2_INS_BLTZL,
MIPS32R2_INS_BNE,
MIPS32R2_INS_BNEL,
MIPS32R2_INS_BREAK,
MIPS32R2_INS_CACHE,
MIPS32R2_INS_CFC1,
MIPS32R2_INS_CFC2,
MIPS32R2_INS_CLO,
MIPS32R2_INS_CLZ,
MIPS32R2_INS_COP2,
MIPS32R2_INS_CTC1,
MIPS32R2_INS_CTC2,
MIPS32R2_INS_DERET,
MIPS32R2_INS_DI,
MIPS32R2_INS_DIV,
MIPS32R2_INS_DIVU,
MIPS32R2_INS_EI,
MIPS32R2_INS_ERET,
MIPS32R2_INS_EXT,
MIPS32R2_INS_INS,
MIPS32R2_INS_J,
MIPS32R2_INS_JAL,
MIPS32R2_INS_JALR,
MIPS32R2_INS_JR,
MIPS32R2_INS_LB,
MIPS32R2_INS_LBU,
MIPS32R2_INS_LDC1,
MIPS32R2_INS_LDC2,
MIPS32R2_INS_LDXC1,
MIPS32R2_INS_LH,
MIPS32R2_INS_LHU,
MIPS32R2_INS_LL,
MIPS32R2_INS_LUI,
MIPS32R2_INS_LUXC1,
MIPS32R2_INS_LW,
MIPS32R2_INS_LWC1,
MIPS32R2_INS_LWC2,
MIPS32R2_INS_LWL,
MIPS32R2_INS_LWR,
MIPS32R2_INS_LWXC1,
MIPS32R2_INS_MADD,
MIPS32R2_INS_MADDU,
MIPS32R2_INS_MFC0,
MIPS32R2_INS_MFC1,
MIPS32R2_INS_MFC2,
MIPS32R2_INS_MFHC1,
MIPS32R2_INS_MFHC2,
MIPS32R2_INS_MFHI,
MIPS32R2_INS_MFLO,
MIPS32R2_INS_MOVF,
MIPS32R2_INS_MOVN,
MIPS32R2_INS_MOVT,
MIPS32R2_INS_MOVZ,
MIPS32R2_INS_MSUB,
MIPS32R2_INS_MSUBU,
MIPS32R2_INS_MTC0,
MIPS32R2_INS_MTC1,
MIPS32R2_INS_MTC2,
MIPS32R2_INS_MTHC1,
MIPS32R2_INS_MTHC2,
MIPS32R2_INS_MTHI,
MIPS32R2_INS_MTLO,
MIPS32R2_INS_MUL,
MIPS32R2_INS_MULT,
MIPS32R2_INS_MULTU,
MIPS32R2_INS_NOR,
MIPS32R2_INS_OR,
MIPS32R2_INS_ORI,
MIPS32R2_INS_PREF,
MIPS32R2_INS_PREFX,
MIPS32R2_INS_RDHWR,
MIPS32R2_INS_RDPGPR,
MIPS32R2_INS_ROTR,
MIPS32R2_INS_ROTRV,
MIPS32R2_INS_SB,
MIPS32R2_INS_SC,
MIPS32R2_INS_SDBBP,
MIPS32R2_INS_SDC1,
MIPS32R2_INS_SDC2,
MIPS32R2_INS_SDXC1,
MIPS32R2_INS_SEB,
MIPS32R2_INS_SEH,
MIPS32R2_INS_SH,
MIPS32R2_INS_SLL,
MIPS32R2_INS_SLLV,
MIPS32R2_INS_SLT,
MIPS32R2_INS_SLTI,
MIPS32R2_INS_SLTIU,
MIPS32R2_INS_SLTU,
MIPS32R2_INS_SRA,
MIPS32R2_INS_SRAV,
MIPS32R2_INS_SRL,
MIPS32R2_INS_SRLV,
MIPS32R2_INS_SUB,
MIPS32R2_INS_SUBU,
MIPS32R2_INS_SUXC1,
MIPS32R2_INS_SW,
MIPS32R2_INS_SWC1,
MIPS32R2_INS_SWC2,
MIPS32R2_INS_SWL,
MIPS32R2_INS_SWR,
MIPS32R2_INS_SWXC1,
MIPS32R2_INS_SYNC,
MIPS32R2_INS_SYNCI,
MIPS32R2_INS_SYSCALL,
MIPS32R2_INS_TEQ,
MIPS32R2_INS_TEQI,
MIPS32R2_INS_TGE,
MIPS32R2_INS_TGEI,
MIPS32R2_INS_TGEIU,
MIPS32R2_INS_TGEU,
MIPS32R2_INS_TLBP,
MIPS32R2_INS_TLBR,
MIPS32R2_INS_TLBWI,
MIPS32R2_INS_TLBWR,
MIPS32R2_INS_TLT,
MIPS32R2_INS_TLTI,
MIPS32R2_INS_TLTIU,
MIPS32R2_INS_TLTU,
MIPS32R2_INS_TNE,
MIPS32R2_INS_TNEI,
MIPS32R2_INS_WAIT,
MIPS32R2_INS_WRPGPR,
MIPS32R2_INS_WSBH,
MIPS32R2_INS_XOR,
MIPS32R2_INS_XORI,
__MIPS32R2_INS_NULL,
};
// op code groups
#define MIPS32R2_OP_SPECIAL 0b000000
#define MIPS32R2_OP_SPECIAL2 0b011100
#define MIPS32R2_OP_SPECIAL3 0b011111
#define MIPS32R2_OP_REGIMM 0b000001
#define MIPS32R2_OP_COP0 0b010000
#define MIPS32R2_OP_COP1 0b010001
#define MIPS32R2_OP_COP2 0b010010
#define MIPS32R2_OP_COP1X 0b010011
// op codes
#define MIPS32R2_OP_ADDI 0b001000
#define MIPS32R2_OP_ADDIU 0b001001
#define MIPS32R2_OP_ANDI 0b001100
#define MIPS32R2_OP_BC 0b110010
#define MIPS32R2_OP_BEQ 0b000100
#define MIPS32R2_OP_BEQL 0b010100
#define MIPS32R2_OP_BGTZ 0b000111
#define MIPS32R2_OP_BGTZL 0b010111
#define MIPS32R2_OP_BLEZ 0b000110
#define MIPS32R2_OP_BLEZL 0b010110
#define MIPS32R2_OP_BNE 0b000101
#define MIPS32R2_OP_BNEL 0b010101
#define MIPS32R2_OP_CACHE 0b101111
#define MIPS32R2_OP_J 0b000010
#define MIPS32R2_OP_JAL 0b000011
#define MIPS32R2_OP_JALX 0b011101
#define MIPS32R2_OP_LB 0b100000
#define MIPS32R2_OP_LBU 0b100100
#define MIPS32R2_OP_LDC1 0b110101
#define MIPS32R2_OP_LDC2 0b110110
#define MIPS32R2_OP_LH 0b100001
#define MIPS32R2_OP_LHU 0b100101
#define MIPS32R2_OP_LL 0b110000
#define MIPS32R2_OP_LUI 0b001111
#define MIPS32R2_OP_LW 0b100011
#define MIPS32R2_OP_LWC1 0b110001
#define MIPS32R2_OP_LWC2 0b110010
#define MIPS32R2_OP_LWL 0b100010
#define MIPS32R2_OP_LWR 0b100110
#define MIPS32R2_OP_ORI 0b001101
#define MIPS32R2_OP_PREF 0b110011
#define MIPS32R2_OP_SB 0b101000
#define MIPS32R2_OP_SC 0b111000
#define MIPS32R2_OP_SDC1 0b111101
#define MIPS32R2_OP_SDC2 0b111110
#define MIPS32R2_OP_SH 0b101001
#define MIPS32R2_OP_SLTI 0b001010
#define MIPS32R2_OP_SLTIU 0b001011
#define MIPS32R2_OP_SW 0b101011
#define MIPS32R2_OP_SWC1 0b111001
#define MIPS32R2_OP_SWC2 0b111010
#define MIPS32R2_OP_SWL 0b101010
#define MIPS32R2_OP_SWR 0b101110
#define MIPS32R2_OP_XORI 0b001110
// op special
#define MIPS32R2_FUNCT_ADD 0b100000
#define MIPS32R2_FUNCT_ADDU 0b100001
#define MIPS32R2_FUNCT_AND 0b100100
#define MIPS32R2_FUNCT_BREAK 0b001101
#define MIPS32R2_FUNCT_DIV 0b000011
#define MIPS32R2_FUNCT_DIVU 0b011011
#define MIPS32R2_FUNCT_JALR 0b001001
#define MIPS32R2_FUNCT_JR 0b001000
#define MIPS32R2_FUNCT_MFHI 0b010000
#define MIPS32R2_FUNCT_MFLO 0b010010
#define MIPS32R2_FUNCT_MOVCL 0b000001
#define MIPS32R2_FUNCT_MOVN 0b001011
#define MIPS32R2_FUNCT_MOVZ 0b001010
#define MIPS32R2_FUNCT_MTHI 0b010001
#define MIPS32R2_FUNCT_MTLO 0b010011
#define MIPS32R2_FUNCT_MULT 0b011000
#define MIPS32R2_FUNCT_MULTU 0b011001
#define MIPS32R2_FUNCT_NOR 0b100111
#define MIPS32R2_FUNCT_OR 0b100101
#define MIPS32R2_FUNCT_SLL 0b000000
#define MIPS32R2_FUNCT_SLLV 0b000100
#define MIPS32R2_FUNCT_SLT 0b101010
#define MIPS32R2_FUNCT_SLTU 0b101011
#define MIPS32R2_FUNCT_SRA 0b000011
#define MIPS32R2_FUNCT_SRAV 0b000111
#define MIPS32R2_FUNCT_SRL 0b000010
#define MIPS32R2_FUNCT_SRLV 0b000110
#define MIPS32R2_FUNCT_SUB 0b100010
#define MIPS32R2_FUNCT_SUBU 0b100011
#define MIPS32R2_FUNCT_SYNC 0b001111
#define MIPS32R2_FUNCT_SYSCALL 0b001100
#define MIPS32R2_FUNCT_TEQ 0b110100
#define MIPS32R2_FUNCT_TGE 0b110000
#define MIPS32R2_FUNCT_TGEU 0b110001
#define MIPS32R2_FUNCT_TLT 0b110010
#define MIPS32R2_FUNCT_TLTU 0b110011
#define MIPS32R2_FUNCT_TNE 0b110110
#define MIPS32R2_FUNCT_XOR 0b100110
// op special2
#define MIPS32R2_FUNCT_CLO 0b100001
#define MIPS32R2_FUNCT_CLZ 0b100000
#define MIPS32R2_FUNCT_MADD 0b000000
#define MIPS32R2_FUNCT_MADDU 0b000001
#define MIPS32R2_FUNCT_MSUB 0b000100
#define MIPS32R2_FUNCT_MSUBU 0b000101
#define MIPS32R2_FUNCT_MUL 0b000010
#define MIPS32R2_FUNCT_SDBBP 0b111111
// op special 3
#define MIPS32R2_FUNCT_EXT 0b000000
#define MIPS32R2_FUNCT_INS 0b000100
#define MIPS32R2_FUNCT_RDHWR 0b111011
#define MIPS32R2_FUNCT_BSHFL 0b100000
// op bshfl
#define MIPS32R2_FUNCT_SEB 0b10000
#define MIPS32R2_FUNCT_SEH 0b11000
#define MIPS32R2_FUNCT_WSBH 0b00010
// op regimm
#define MIPS32R2_FUNCT_BGEZ 0b00001
#define MIPS32R2_FUNCT_BGEZAL 0b10001
#define MIPS32R2_FUNCT_BGEZALL 0b10011
#define MIPS32R2_FUNCT_BGEZL 0b00011
#define MIPS32R2_FUNCT_BLTZ 0b00000
#define MIPS32R2_FUNCT_BLTZAL 0b10000
#define MIPS32R2_FUNCT_BLTZALL 0b10010
#define MIPS32R2_FUNCT_BLTZL 0b00010
#define MIPS32R2_FUNCT_SYNCI 0b11111
#define MIPS32R2_FUNCT_TEQI 0b01100
#define MIPS32R2_FUNCT_TGEI 0b01000
#define MIPS32R2_FUNCT_TGEIU 0b01001
#define MIPS32R2_FUNCT_TLTI 0b01010
#define MIPS32R2_FUNCT_TLTIU 0b01011
#define MIPS32R2_FUNCT_TNEI 0b01110
// op cop cfunct
#define MIPS32R2_FUNCT_BC 0b01000
#define MIPS32R2_FUNCT_CF 0b00010
#define MIPS32R2_FUNCT_CT 0b00110
#define MIPS32R2_FUNCT_MF 0b00000
#define MIPS32R2_FUNCT_MFH 0b00011
#define MIPS32R2_FUNCT_MT 0b00100
#define MIPS32R2_FUNCT_MTH 0b00111
#define MIPS32R2_FUNCT_MFMC0 0b01011
#define MIPS32R2_FUNCT_RDPGPR 0b01010
#define MIPS32R2_FUNCT_WRPGPR 0b01110
// op cop funct
#define MIPS32R2_FUNCT_DERET 0b011111
#define MIPS32R2_FUNCT_ERET 0b011000
#define MIPS32R2_FUNCT_TLBP 0b001000
#define MIPS32R2_FUNCT_TLBR 0b000001
#define MIPS32R2_FUNCT_TLBWI 0b000010
#define MIPS32R2_FUNCT_TLBWR 0b000110
// op cop1x
#define MIPS32R2_FUNCT_LDXC1 0b000001
#define MIPS32R2_FUNCT_LUXC1 0b000101
#define MIPS32R2_FUNCT_LWXC1 0b000000
#define MIPS32R2_FUNCT_PREFX 0b001111
#define MIPS32R2_FUNCT_SDXC1 0b001001
#define MIPS32R2_FUNCT_SUXC1 0b001101
#define MIPS32R2_FUNCT_SWXC1 0b001000
#define MIPS32R2_FUNCT_WAIT 0b100000
#define __MIPS32R2_INS_LEN (__MIPS32R2_INS_NULL)
#define __MIPS32R2_PSEUDO_LEN (38)
#define __MIPS32R2_GRAMMER_LEN (__MIPS32R2_INS_LEN + __MIPS32R2_PSEUDO_LEN)
extern struct mips32_grammer mips32r2_grammers[__MIPS32R2_GRAMMER_LEN];
extern union mips32_instruction mips32r2_instructions[__MIPS32R2_INS_LEN];
#endif /* __MIPS32R2_H__ */

View file

@ -5,7 +5,7 @@
#include <mlimits.h> #include <mlimits.h>
#include <stdint.h> #include <stdint.h>
#include <mips32.h> #include <mips.h>
/* mips instructions */ /* mips instructions */
enum mips32r6_instruction_type { enum mips32r6_instruction_type {

571
lib/mips1.c Normal file
View file

@ -0,0 +1,571 @@
#include <mips1.h>
#define RTYPE "rd,rs,rt"
#define ITYPE "rt,rs,immd"
#define JTYPE "target"
#define LOAD "rt,offset(base)"
#define SHIFT "rd,rt,sa"
#define SHIFTV "rd,rt,rs"
#define BRANCH "rs,rt,offset"
#define BRANCHZ "rs,offset"
#define TRAP "rs,rt"
#define TRAPI "rs,immd"
#define INS(name, grammer) {#name, grammer, MIPS1_INS_ ##name, \
/* pseudo stub */ 0, {{0, ""}}}
#define PSEUDO(name, grammer, ...) {name, grammer, __MIPS1_INS_NULL, \
__VA_ARGS__ }
struct mips32_grammer mips1_grammers[__MIPS1_GRAMMER_LEN] = {
// real instructions
INS(ADD, RTYPE),
INS(ADDI, ITYPE),
INS(ADDIU, ITYPE),
INS(ADDU, RTYPE),
INS(AND, RTYPE),
INS(ANDI, ITYPE),
INS(BC1F, "cc,offset"),
INS(BC1T, "cc,offset"),
INS(BEQ, BRANCH),
INS(BGEZ, BRANCHZ),
INS(BGEZAL, BRANCHZ),
INS(BGTZ, BRANCHZ),
INS(BLEZ, BRANCHZ),
INS(BLTZAL, BRANCHZ),
INS(BLTZ, BRANCHZ),
INS(BNE, BRANCHZ),
INS(BREAK, "code"),
INS(CLO, "rd,rs"),
INS(CLZ, "rd,rs"),
INS(DIV, "rs,rt"),
INS(DIVU, "rs,rt"),
INS(ERET, ""),
INS(J, JTYPE),
INS(JAL, JTYPE),
INS(JALR, "rs"),
INS(JR, "rs"),
INS(LB, LOAD),
INS(LBU, LOAD),
INS(LH, LOAD),
INS(LHU, LOAD),
INS(LL, LOAD),
INS(LUI, "rt,immd"),
INS(LW, LOAD),
INS(LWC1, "ft,base(offset)"),
INS(LWL, LOAD),
INS(LWR, LOAD),
INS(MADD, "rs,rt"),
INS(MADDU, "rs,rt"),
INS(MFC0, "rt,rd"),
INS(MFC1, "rt,fs"),
INS(MFHI, "rd"),
INS(MFLO, "rd"),
INS(MOVN, RTYPE),
INS(MOVZ, RTYPE),
INS(MSUB, "rs,rt"),
INS(MSUBU, "rs,rt"),
INS(MTC0, "rd,rt"),
INS(MTC1, "rd,fs"),
INS(MTHI, "rs"),
INS(MTLO, "rs"),
INS(MUL, RTYPE),
INS(MULT, "rs,rt"),
INS(MULTU, "rs,rt"),
INS(NOR, "rs,rt"),
INS(OR, RTYPE),
INS(ORI, ITYPE),
INS(SB, LOAD),
INS(SC, LOAD),
INS(SDC1, "ft,base(offset)"),
INS(SH, LOAD),
INS(SLL, SHIFT),
INS(SLLV, SHIFTV),
INS(SLT, RTYPE),
INS(SLTI, ITYPE),
INS(SLTIU, ITYPE),
INS(SLTU, RTYPE),
INS(SRA, SHIFT),
INS(SRAV, SHIFTV),
INS(SRL, SHIFT),
INS(SRLV, SHIFTV),
INS(SUB, RTYPE),
INS(SUBU, RTYPE),
INS(SW, LOAD),
INS(SWC1, "ft,base(offset)"),
INS(SWL, LOAD),
INS(SWR, LOAD),
INS(SYSCALL, ""),
INS(TEQ, TRAP),
INS(TEQI, TRAPI),
INS(TGE, TRAP),
INS(TGEI, TRAPI),
INS(TGEIU, TRAPI),
INS(TGEU, TRAP),
INS(TLT, TRAP),
INS(TLTI, TRAPI),
INS(TLTIU, TRAPI),
INS(TLTU, TRAP),
INS(TNE, TRAP),
INS(TNEI, TRAPI),
INS(XOR, RTYPE),
INS(XORI, ITYPE),
// pseudo instructions
PSEUDO("abs", "rd,rs", 3, {
{MIPS1_INS_SRA, "rd=$at,rt=rs,sa=31"},
{MIPS1_INS_ADD, "rd,rs,rt=$at"},
{MIPS1_INS_XOR, "rd,rs=rd,rt=$at"},
}),
PSEUDO("div", "rd,rt,rs", 2, {
{MIPS1_INS_DIV, "rt,rs"},
{MIPS1_INS_MFLO, "rd"},
}),
PSEUDO("divu", "rd,rt,rs", 2, {
{MIPS1_INS_DIVU, "rt,rs"},
{MIPS1_INS_MFLO, "rd"},
}),
PSEUDO("mulo", "rd,rt,rs", 2, {
{MIPS1_INS_MULT, "rt,rs"},
{MIPS1_INS_MFLO, "rd"},
}),
PSEUDO("mulou", "rd,rt,rs", 2, {
{MIPS1_INS_MULTU, "rt,rs"},
{MIPS1_INS_MFLO, "rd"},
}),
PSEUDO("neg", "rd,rt", 1, {
{MIPS1_INS_SUB, "rd,rs=$zero,rt"},
}),
PSEUDO("negu", "rd,rt", 1, {
{MIPS1_INS_SUBU, "rd,rs=$zero,rt"},
}),
PSEUDO("not", "rd,rt", 1, {
{MIPS1_INS_NOR, "rd,rs=$zero,rt"},
}),
PSEUDO("rem", "rd,rt,rs", 2, {
{MIPS1_INS_DIV, "rt,rs"},
{MIPS1_INS_MFHI, "rd"},
}),
PSEUDO("remu", "rd,rt,rs", 2, {
{MIPS1_INS_DIVU, "rt,rs"},
{MIPS1_INS_MFHI, "rd"},
}),
// TODO: rol
// TODO: ror
PSEUDO("subi", "rt,rs,immd", 1, {
{MIPS1_INS_ADDI, "rt,rs,-immd"},
}),
PSEUDO("li", "rt,immd", 1, {
{MIPS1_INS_ADDI, "rt,immd"}
}),
PSEUDO("seq", "rd,rs,rt", 3, {
{MIPS1_INS_SLT, "rd,rs,rt"},
{MIPS1_INS_SLT, "rd=$at,rs,rt"},
{MIPS1_INS_NOR, "rd,rs=rd,rt=$at"},
}),
PSEUDO("sgt", "rd,rs,rt", 1, {
{MIPS1_INS_SLT, "rd,rs=rt,rt=rs"},
}),
PSEUDO("sgtu", "rd,rs,rt", 1, {
{MIPS1_INS_SLTU, "rd,rs=rt,rt=rs"},
}),
PSEUDO("sge", "rd,rs,rt", 2, {
{MIPS1_INS_SLT, "rd,rs,rt"},
{MIPS1_INS_SLTI, "rt=rd,rs=rd,immd=1"},
}),
PSEUDO("sgeu", "rd,rs,rt", 2, {
{MIPS1_INS_SLTU, "rd,rs,rt"},
{MIPS1_INS_SLTI, "rt=rd,rs=rd,immd=1"},
}),
PSEUDO("slte", "rd,rs,rt", 2, {
{MIPS1_INS_SLT, "rd,rs=rt,rt=rs"},
{MIPS1_INS_SLTI, "rt=rd,rs=rd,immd=1"},
}),
PSEUDO("slteu", "rd,rs,rt", 2, {
{MIPS1_INS_SLTU, "rd,rs=rt,rt=rs"},
{MIPS1_INS_SLTI, "rt=rd,rs=rd,immd=1"},
}),
PSEUDO("sne", "rd,rs,rt", 3, {
{MIPS1_INS_SLT, "rd,rs,rt"},
{MIPS1_INS_SLT, "rd=$at,rs,rt"},
{MIPS1_INS_OR, "rd,rs=rd,rt=$at"},
}),
PSEUDO("b", "offset", 1, {
{MIPS1_INS_BEQ, "rs=$zero,rt=$zero,offset"},
}),
PSEUDO("beqz", "rs,offset", 1, {
{MIPS1_INS_BEQ, "rs,rt=$zero,offset"},
}),
PSEUDO("bge", "rs,rt,offset", 2, {
{MIPS1_INS_SLT, "rd=$at,rs,rt"},
{MIPS1_INS_BNE, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("bgeu", "rs,rt,offset", 2, {
{MIPS1_INS_SLTU, "rd=$at,rs,rt"},
{MIPS1_INS_BNE, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("bge", "rs,rt,offset", 2, {
{MIPS1_INS_SLT, "rd=$at,rs,rt"},
{MIPS1_INS_BEQ, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("bgeu", "rs,rt,offset", 2, {
{MIPS1_INS_SLTU, "rd=$at,rs,rt"},
{MIPS1_INS_BEQ, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("ble", "rs,rt,offset", 2, {
{MIPS1_INS_SLT, "rd=$at,rs=rt,rt=rs"},
{MIPS1_INS_BEQ, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("bleu", "rs,rt,offset", 2, {
{MIPS1_INS_SLT, "rd=$at,rs=rt,rt=rs"},
{MIPS1_INS_BEQ, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("blt", "rs,rt,offset", 2, {
{MIPS1_INS_SLT, "rd=$at,rs,rt"},
{MIPS1_INS_BNE, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("bltu", "rs,rt,offset", 2, {
{MIPS1_INS_SLTU, "rd=$at,rs,rt"},
{MIPS1_INS_BNE, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("bnez", "rs,offset", 1, {
{MIPS1_INS_BNE, "rs,rt=$zero,offset"},
}),
// TODO: ld
// TODO: load unaligned
// TODO: store unaligned
PSEUDO("la", "rt,target", 2, {
{MIPS1_INS_LUI, "rt=$at,hi"},
{MIPS1_INS_ORI, "rt,rs=$at,lo"},
}),
PSEUDO("move", "rd,rs", 1, {
{MIPS1_INS_OR, "rd,rs"}
}),
PSEUDO("nop", "", 1, {
{MIPS1_INS_SLL, ""},
}),
};
#define MIPS_INS(ins, ...) \
[MIPS1_INS_ ##ins] = { __VA_ARGS__ },
union mips32_instruction mips1_instructions[__MIPS1_INS_LEN] = {
/* ADD - add */
MIPS_INS(ADD, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_ADD)
/* ADDI - add immediate */
MIPS_INS(ADDI, .op = MIPS1_OP_ADDI)
/* ADDIU - add immediate unsigned */
MIPS_INS(ADDIU, .op = MIPS1_OP_ADDIU)
/* ADDU - add unsigned */
MIPS_INS(ADDU, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_ADDU)
/* AND - and */
MIPS_INS(AND, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_AND)
/* ANDI - and immediate */
MIPS_INS(ANDI, .op = MIPS1_OP_ANDI)
/* BC1F - branch on coprocessor 1 false */
MIPS_INS(BC1F, .op = MIPS1_OP_COP1, .cfunct = MIPS1_FUNCT_BC, .tf = 0)
/* BC1T - branch on coprocessor 1 true */
MIPS_INS(BC1T, .op = MIPS1_OP_COP1, .cfunct = MIPS1_FUNCT_BC, .tf = 1)
/* BEQ - branch on equal */
MIPS_INS(BEQ, .op = MIPS1_OP_BEQ)
/* BGEZ - branch on greater than or equal to zero */
MIPS_INS(BGEZ, .op = MIPS1_OP_REGIMM, .bfunct = MIPS1_FUNCT_BGEZ)
/* BGEZAL - branch on greater than or equal to zero and link */
MIPS_INS(BGEZAL, .op = MIPS1_OP_REGIMM, .bfunct = MIPS1_FUNCT_BGEZAL)
/* BGTZ - branch on greater than zero */
MIPS_INS(BGTZ, .op = MIPS1_OP_BGTZ)
/* BLEZ - branch on less than or equal to zero */
MIPS_INS(BLEZ, .op = MIPS1_OP_BLEZ)
/* BLTZAL - branch on less than zero and link */
MIPS_INS(BLTZAL, .op = MIPS1_OP_REGIMM, .bfunct = MIPS1_FUNCT_BLTZAL)
/* BLTZ - branch on less than zero */
MIPS_INS(BLTZ, .op = MIPS1_OP_REGIMM, .bfunct = MIPS1_FUNCT_BLTZ)
/* BNE - branch on not equal */
MIPS_INS(BNE, .op = MIPS1_OP_BNE)
/* BREAK - break */
MIPS_INS(BREAK, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_BREAK)
/* CLO - count loading zeros */
MIPS_INS(CLO, .op = MIPS1_OP_SPECIAL2, .funct = MIPS1_FUNCT_CLO)
/* CLZ - count loading zeros */
MIPS_INS(CLZ, .op = MIPS1_OP_SPECIAL2, .funct = MIPS1_FUNCT_CLZ)
/* DIV - divide */
MIPS_INS(DIV, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_DIV)
/* DIVU - divide unsigned */
MIPS_INS(DIVU, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_DIVU)
/* ERET - exception return */
MIPS_INS(ERET, .op = MIPS1_OP_COP0, .c0 = 1, .funct = MIPS1_FUNCT_ERET)
/* J - jump */
MIPS_INS(J, .op = MIPS1_OP_J)
/* JAL - jump and link */
MIPS_INS(JAL, .op = MIPS1_OP_JAL)
/* JALR - jump and link register */
MIPS_INS(JALR, .rd = MIPS32_REG_RA, .op = MIPS1_OP_SPECIAL,
.funct = MIPS1_FUNCT_JALR)
/* JR - jump register */
MIPS_INS(JR, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_JR)
/* LB - load byte */
MIPS_INS(LB, .op = MIPS1_OP_LB)
/* LBU - load byte unsigned */
MIPS_INS(LBU, .op = MIPS1_OP_LBU)
/* LH - load half */
MIPS_INS(LH, .op = MIPS1_OP_LH)
/* LHU - load half unsigned */
MIPS_INS(LHU, .op = MIPS1_OP_LHU)
/* LL - load linked */
MIPS_INS(LL, .op = MIPS1_OP_LL)
/* LUI - load upper immediate */
MIPS_INS(LUI, .op = MIPS1_OP_LUI)
/* LW - load word */
MIPS_INS(LW, .op = MIPS1_OP_LW)
/* LWC1 - load word cop1 */
MIPS_INS(LWC1, .op = MIPS1_OP_LWC1)
/* LWL - load word left */
MIPS_INS(LWL, .op = MIPS1_OP_LWL)
/* LWR - load word right */
MIPS_INS(LWR, .op = MIPS1_OP_LWR)
/* MADD - multiply add */
MIPS_INS(MADD, .op = MIPS1_OP_SPECIAL2, .funct = MIPS1_FUNCT_MADD)
/* MADDU - multiply add unsigned */
MIPS_INS(MADDU, .op = MIPS1_OP_SPECIAL2, .funct = MIPS1_FUNCT_MADDU)
/* MFC0 - move from cop0 */
MIPS_INS(MFC0, .op = MIPS1_OP_COP0, .cfunct = MIPS1_FUNCT_MF)
/* MFC1 - move from cop1 */
MIPS_INS(MFC1, .op = MIPS1_OP_COP1, .cfunct = MIPS1_FUNCT_MF)
/* MFHI - move from hi */
MIPS_INS(MFHI, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_MFHI)
/* MFLO - move from low */
MIPS_INS(MFLO, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_MFLO)
/* MOVN - move conditional not zero */
MIPS_INS(MOVN, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_MOVN)
/* MOVZ - move conditional zero */
MIPS_INS(MOVZ, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_MOVZ)
/* MSUB - multiply subtract */
MIPS_INS(MSUB, .op = MIPS1_OP_SPECIAL2, .funct = MIPS1_FUNCT_MSUB)
/* MSUBU - multiply subtract unsigned */
MIPS_INS(MSUBU, .op = MIPS1_OP_SPECIAL2, .funct = MIPS1_FUNCT_MSUBU)
/* MTC0 - move from cop0 */
MIPS_INS(MTC0, .op = MIPS1_OP_COP0, .cfunct = MIPS1_FUNCT_MT)
/* MTC1 - move from cop1 */
MIPS_INS(MTC1, .op = MIPS1_OP_COP1, .cfunct = MIPS1_FUNCT_MT)
/* MTHI - move to hi */
MIPS_INS(MTHI, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_MTHI)
/* MTLO - move to low */
MIPS_INS(MTLO, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_MTLO)
/* MUL - multiply */
MIPS_INS(MUL, .op = MIPS1_OP_SPECIAL2, .funct = MIPS1_FUNCT_MUL)
/* MULT - multiply */
MIPS_INS(MULT, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_MULT)
/* MULTU - multiply unsinged */
MIPS_INS(MULTU, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_MULTU)
/* NOR - not or */
MIPS_INS(NOR, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_NOR)
/* OR - or */
MIPS_INS(OR, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_OR)
/* ORI - or imemdiate */
MIPS_INS(ORI, .op = MIPS1_OP_ORI)
/* SB - store byte */
MIPS_INS(SB, .op = MIPS1_OP_SB)
/* SC - store conditional */
MIPS_INS(SC, .op = MIPS1_OP_SC)
/* SDC1 - store double word cop1 */
MIPS_INS(SDC1, .op = MIPS1_OP_SDC1)
/* SH - store half */
MIPS_INS(SH, .op = MIPS1_OP_SH)
/* SLL - shift left logical */
MIPS_INS(SLL, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_SLL)
/* SLLV - shift left logical variable */
MIPS_INS(SLLV, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_SLLV)
/* SLT - set less then */
MIPS_INS(SLT, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_SLT)
/* SLTI - set less then immediate */
MIPS_INS(SLTI, .op = MIPS1_OP_SLTI)
/* SLTIU - set less then imemdiate unsigned */
MIPS_INS(SLTIU, .op = MIPS1_OP_SLTIU)
/* SLTU - set less than unsigned */
MIPS_INS(SLTU, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_SLTU)
/* SRA - shift right arithmetic */
MIPS_INS(SRA, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_SRA)
/* SRAV - shift right arithmetic variable */
MIPS_INS(SRAV, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_SRAV)
/* SRL - shift right logical */
MIPS_INS(SRL, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_SRL)
/* SRLV - shift right logical variable */
MIPS_INS(SRLV, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_SRLV)
/* SUB - subtract */
MIPS_INS(SUB, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_SUB)
/* SUBU - subtract unsigned */
MIPS_INS(SUBU, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_SUBU)
/* SW - store word */
MIPS_INS(SW, .op = MIPS1_OP_SW)
/* SWC1 - store word cop1 */
MIPS_INS(SWC1, .op = MIPS1_OP_SWC1)
/* SWL - store word left */
MIPS_INS(SWL, .op = MIPS1_OP_SWL)
/* SWR - store word right */
MIPS_INS(SWR, .op = MIPS1_OP_SWR)
/* SYSCALL - syscall */
MIPS_INS(SYSCALL, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_SYSCALL)
/* TEQ - trap if equal */
MIPS_INS(TEQ, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_TEQ)
/* TEQ - trap if equal immediate */
MIPS_INS(TEQI, .op = MIPS1_OP_REGIMM, .bfunct = MIPS1_FUNCT_TEQI)
/* TGE - trap if greater or equal to */
MIPS_INS(TGE, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_TGE)
/* TGEI - trap if greater or equal to immediate */
MIPS_INS(TGEI, .op = MIPS1_OP_REGIMM, .bfunct = MIPS1_FUNCT_TGEI)
/* TGEIU - trap if greater or equal to immediate unsigned */
MIPS_INS(TGEIU, .op = MIPS1_OP_REGIMM, .bfunct = MIPS1_FUNCT_TGEIU)
/* TGEU - trap if greater or equal to unsigned */
MIPS_INS(TGEU, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_TGEU)
/* TLT - trap if less or equal to */
MIPS_INS(TLT, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_TLT)
/* TLTI - trap if less or equal to immediate */
MIPS_INS(TLTI, .op = MIPS1_OP_REGIMM, .bfunct = MIPS1_FUNCT_TLTI)
/* TLTIU - trap if less or equal to immediate unsigned */
MIPS_INS(TLTIU, .op = MIPS1_OP_REGIMM, .bfunct = MIPS1_FUNCT_TLTIU)
/* TLTU - trap if less or equal to unsigned */
MIPS_INS(TLTU, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_TLTU)
/* TNE - trap if not equal */
MIPS_INS(TNE, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_TNE)
/* TNEI - trap if not equal immediate */
MIPS_INS(TNEI, .op = MIPS1_OP_REGIMM, .bfunct = MIPS1_FUNCT_TNEI)
/* XOR - exclusive or */
MIPS_INS(XOR, .op = MIPS1_OP_SPECIAL, .funct = MIPS1_FUNCT_XOR)
/* XORI - exclusive or immediate */
MIPS_INS(XORI, .op = MIPS1_OP_XORI)
};
#undef MIPS_INS

851
lib/mips32r2.c Normal file
View file

@ -0,0 +1,851 @@
#include <mips32r2.h>
#define RTYPE "rd,rs,rt"
#define ITYPE "rt,rs,immd"
#define JTYPE "target"
#define LOAD "rt,offset(base)"
#define SHIFT "rd,rt,sa"
#define SHIFTV "rd,rt,rs"
#define BRANCH "rs,rt,offset"
#define BRANCHZ "rs,offset"
#define INS(name, grammer) {#name, grammer, MIPS32R2_INS_ ##name, \
/* pseudo stub */ 0, {{0, ""}}}
#define PSEUDO(name, grammer, ...) {name, grammer, __MIPS32R2_INS_NULL, \
__VA_ARGS__ }
struct mips32_grammer mips32r2_grammers[__MIPS32R2_GRAMMER_LEN] = {
// real instructions
INS(ADD, RTYPE),
INS(ADDI, ITYPE),
INS(ADDIU, ITYPE),
INS(ADDU, RTYPE),
INS(AND, RTYPE),
INS(ANDI, ITYPE),
INS(BC1F, "cc,offset"),
INS(BC1FL, "cc,offset"),
INS(BC1T, "cc,offset"),
INS(BC1TL, "cc,offset"),
INS(BC2F, "cc,offset"),
INS(BC2FL, "cc,offset"),
INS(BC2T, "cc,offset"),
INS(BC2TL, "cc,offset"),
INS(BEQ, BRANCH),
INS(BEQL, BRANCH),
INS(BGEZ, BRANCHZ),
INS(BGEZAL, BRANCHZ),
INS(BGEZALL, BRANCHZ),
INS(BGEZL, BRANCHZ),
INS(BGTZ, BRANCHZ),
INS(BGTZL, BRANCHZ),
INS(BLEZ, BRANCHZ),
INS(BLEZL, BRANCHZ),
INS(BLTZ, BRANCHZ),
INS(BLTZAL, BRANCHZ),
INS(BLTZALL, BRANCHZ),
INS(BLTZL, BRANCHZ),
INS(BNE, BRANCH),
INS(BNEL, BRANCH),
INS(BREAK, "code"),
INS(CACHE, "op,offset(base)"),
INS(CFC1, "rt,fs"),
INS(CFC2, "rt,rd"),
INS(CLO, "rd,rs"),
INS(CLZ, "rd,rs"),
INS(COP2, "func"),
INS(CTC1, "rt,fs"),
INS(CTC2, "rt,rd"),
INS(DERET, ""),
INS(DI, "rt"),
INS(DIV, RTYPE),
INS(DIVU, RTYPE),
INS(EI, "rt"),
INS(ERET, ""),
INS(EXT, "rt,rs,pos,size"),
INS(INS, "rt,rs,pos,size"),
INS(J, JTYPE),
INS(JAL, JTYPE),
INS(JALR, "rs"),
INS(JR, "rs"),
INS(LB, LOAD),
INS(LBU, LOAD),
INS(LDC1, "ft,offset(base)"),
INS(LDC2, LOAD),
INS(LDXC1, "fd,index(base)"),
INS(LH, LOAD),
INS(LHU, LOAD),
INS(LL, LOAD),
INS(LUI, "rt,immd"),
INS(LUXC1, "fd,index(base)"),
INS(LW, LOAD),
INS(LWC1, "ft,offset(base)"),
INS(LWC2, LOAD),
INS(LWL, LOAD),
INS(LWR, LOAD),
INS(LWXC1, "fd,index(base)"),
INS(MADD, "rs,rt"),
INS(MADDU, "rs,rt"),
INS(MFC0, "rt,rd"),
INS(MFC1, "rt,fs"),
INS(MFC2, "rt,rd"),
INS(MFHC1, "rt,fs"),
INS(MFHC2, "rt,rd"),
INS(MFHI, "rd"),
INS(MFLO, "rd"),
INS(MOVF, "rd,rs,cc"),
INS(MOVN, RTYPE),
INS(MOVT, "rd,rs,cc"),
INS(MOVZ, RTYPE),
INS(MSUB, "rs,rt"),
INS(MSUBU, "rs,rt"),
INS(MTC0, "rt,rd"),
INS(MTC1, "rt,fs"),
INS(MTC2, "rt,rd"),
INS(MTHC1, "rt,fs"),
INS(MTHC2, "rt,rd"),
INS(MTHI, "rs"),
INS(MTLO, "rs"),
INS(MUL, RTYPE),
INS(MULT, "rs,rt"),
INS(MULTU, "rs,rt"),
INS(NOR, RTYPE),
INS(OR, RTYPE),
INS(ORI, ITYPE),
INS(PREF, "hint,offset(base)"),
INS(PREFX, "hint,index(base)"),
INS(RDHWR, "rt,rd"),
INS(RDPGPR, "rd,rt"),
INS(ROTR, SHIFT),
INS(ROTRV, SHIFTV),
INS(SB, LOAD),
INS(SC, LOAD),
INS(SDBBP, "code"),
INS(SDC1, "ft,offset(base)"),
INS(SDC2, LOAD),
INS(SDXC1, "fs,index(base)"),
INS(SEB, "rd,rt"),
INS(SEH, "rd,rt"),
INS(SH, LOAD),
INS(SLL, SHIFT),
INS(SLLV, SHIFTV),
INS(SLT, RTYPE),
INS(SLTI, ITYPE),
INS(SLTIU, ITYPE),
INS(SLTU, RTYPE),
INS(SRA, SHIFT),
INS(SRAV, SHIFTV),
INS(SRL, SHIFT),
INS(SRLV, SHIFT),
INS(SUB, RTYPE),
INS(SUBU, RTYPE),
INS(SUXC1, "fs,index(base)"),
INS(SW, LOAD),
INS(SWC1, "ft,offset(base)"),
INS(SWC2, LOAD),
INS(SWL, LOAD),
INS(SWR, LOAD),
INS(SWXC1, "fs,index(base)"),
INS(SYNC, ""),
INS(SYNCI, "offest(base)"),
INS(SYSCALL, ""),
INS(TEQ, "rs,rt"),
INS(TEQI, "rs,immd"),
INS(TGE, "rs,rt"),
INS(TGEI, "rs,immd"),
INS(TGEIU, "rs,immd"),
INS(TGEU, "rs,rt"),
INS(TLBP, ""),
INS(TLBR, ""),
INS(TLBWI, ""),
INS(TLBWR, ""),
INS(TLT, "rs,rt"),
INS(TLTI, "rs,immd"),
INS(TLTIU, "rs,immd"),
INS(TLTU, "rs,rt"),
INS(TNE, "rs,rt"),
INS(TNEI, "rs,immd"),
INS(WAIT, ""),
INS(WRPGPR, "rd,rt"),
INS(XOR, RTYPE),
INS(XORI, ITYPE),
// pseudo instructions
PSEUDO("abs", "rd,rs", 3, {
{MIPS32R2_INS_SRA, "rd=$at,rt=rs,sa=31"},
{MIPS32R2_INS_ADD, "rd,rs,rt=$at"},
{MIPS32R2_INS_XOR, "rd,rs=rd,rt=$at"},
}),
PSEUDO("div", "rd,rt,rs", 2, {
{MIPS32R2_INS_DIV, "rt,rs"},
{MIPS32R2_INS_MFLO, "rd"},
}),
PSEUDO("divu", "rd,rt,rs", 2, {
{MIPS32R2_INS_DIVU, "rt,rs"},
{MIPS32R2_INS_MFLO, "rd"},
}),
PSEUDO("mulo", "rd,rt,rs", 2, {
{MIPS32R2_INS_MULT, "rt,rs"},
{MIPS32R2_INS_MFLO, "rd"},
}),
PSEUDO("mulou", "rd,rt,rs", 2, {
{MIPS32R2_INS_MULTU, "rt,rs"},
{MIPS32R2_INS_MFLO, "rd"},
}),
PSEUDO("neg", "rd,rt", 1, {
{MIPS32R2_INS_SUB, "rd,rs=$zero,rt"},
}),
PSEUDO("negu", "rd,rt", 1, {
{MIPS32R2_INS_SUBU, "rd,rs=$zero,rt"},
}),
PSEUDO("not", "rd,rt", 1, {
{MIPS32R2_INS_NOR, "rd,rs=$zero,rt"},
}),
PSEUDO("rem", "rd,rt,rs", 2, {
{MIPS32R2_INS_DIV, "rt,rs"},
{MIPS32R2_INS_MFHI, "rd"},
}),
PSEUDO("remu", "rd,rt,rs", 2, {
{MIPS32R2_INS_DIVU, "rt,rs"},
{MIPS32R2_INS_MFHI, "rd"},
}),
// TODO: rol
// TODO: ror
PSEUDO("subi", "rt,rs,immd", 1, {
{MIPS32R2_INS_ADDI, "rt,rs,-immd"},
}),
PSEUDO("li", "rt,immd", 1, {
{MIPS32R2_INS_ADDI, "rt,immd"}
}),
PSEUDO("seq", "rd,rs,rt", 3, {
{MIPS32R2_INS_SLT, "rd,rs,rt"},
{MIPS32R2_INS_SLT, "rd=$at,rs,rt"},
{MIPS32R2_INS_NOR, "rd,rs=rd,rt=$at"},
}),
PSEUDO("sgt", "rd,rs,rt", 1, {
{MIPS32R2_INS_SLT, "rd,rs=rt,rt=rs"},
}),
PSEUDO("sgtu", "rd,rs,rt", 1, {
{MIPS32R2_INS_SLTU, "rd,rs=rt,rt=rs"},
}),
PSEUDO("sge", "rd,rs,rt", 2, {
{MIPS32R2_INS_SLT, "rd,rs,rt"},
{MIPS32R2_INS_SLTI, "rt=rd,rs=rd,immd=1"},
}),
PSEUDO("sgeu", "rd,rs,rt", 2, {
{MIPS32R2_INS_SLTU, "rd,rs,rt"},
{MIPS32R2_INS_SLTI, "rt=rd,rs=rd,immd=1"},
}),
PSEUDO("slte", "rd,rs,rt", 2, {
{MIPS32R2_INS_SLT, "rd,rs=rt,rt=rs"},
{MIPS32R2_INS_SLTI, "rt=rd,rs=rd,immd=1"},
}),
PSEUDO("slteu", "rd,rs,rt", 2, {
{MIPS32R2_INS_SLTU, "rd,rs=rt,rt=rs"},
{MIPS32R2_INS_SLTI, "rt=rd,rs=rd,immd=1"},
}),
PSEUDO("sne", "rd,rs,rt", 3, {
{MIPS32R2_INS_SLT, "rd,rs,rt"},
{MIPS32R2_INS_SLT, "rd=$at,rs,rt"},
{MIPS32R2_INS_OR, "rd,rs=rd,rt=$at"},
}),
PSEUDO("jalr.hb", "rs", 1, {
{MIPS32R2_INS_JALR, "rs,hb=1"}
}),
PSEUDO("jr.hb", "rs", 1, {
{MIPS32R2_INS_JR, "rs,hb=1"}
}),
PSEUDO("b", "offset", 1, {
{MIPS32R2_INS_BEQ, "rs=$zero,rt=$zero,offset"},
}),
PSEUDO("beqz", "rs,offset", 1, {
{MIPS32R2_INS_BEQ, "rs,rt=$zero,offset"},
}),
PSEUDO("bge", "rs,rt,offset", 2, {
{MIPS32R2_INS_SLT, "rd=$at,rs,rt"},
{MIPS32R2_INS_BNE, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("bgeu", "rs,rt,offset", 2, {
{MIPS32R2_INS_SLTU, "rd=$at,rs,rt"},
{MIPS32R2_INS_BNE, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("bge", "rs,rt,offset", 2, {
{MIPS32R2_INS_SLT, "rd=$at,rs,rt"},
{MIPS32R2_INS_BEQ, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("bgeu", "rs,rt,offset", 2, {
{MIPS32R2_INS_SLTU, "rd=$at,rs,rt"},
{MIPS32R2_INS_BEQ, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("ble", "rs,rt,offset", 2, {
{MIPS32R2_INS_SLT, "rd=$at,rs=rt,rt=rs"},
{MIPS32R2_INS_BEQ, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("bleu", "rs,rt,offset", 2, {
{MIPS32R2_INS_SLT, "rd=$at,rs=rt,rt=rs"},
{MIPS32R2_INS_BEQ, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("blt", "rs,rt,offset", 2, {
{MIPS32R2_INS_SLT, "rd=$at,rs,rt"},
{MIPS32R2_INS_BNE, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("bltu", "rs,rt,offset", 2, {
{MIPS32R2_INS_SLTU, "rd=$at,rs,rt"},
{MIPS32R2_INS_BNE, "rs=$at,rt=$zero,offset"},
}),
PSEUDO("bnez", "rs,offset", 1, {
{MIPS32R2_INS_BNE, "rs,rt=$zero,offset"},
}),
// TODO: ld
// TODO: load unaligned
// TODO: store unaligned
PSEUDO("la", "rt,target", 2, {
{MIPS32R2_INS_LUI, "rt=$at,hi"},
{MIPS32R2_INS_ORI, "rt,rs=$at,lo"},
}),
PSEUDO("move", "rd,rs", 1, {
{MIPS32R2_INS_OR, "rd,rs"}
}),
PSEUDO("nop", "", 1, {
{MIPS32R2_INS_SLL, ""},
}),
PSEUDO("ssnop", "", 1, {
{MIPS32R2_INS_SLL, "sa=1"},
}),
PSEUDO("ehb", "", 1, {
{MIPS32R2_INS_SLL, "sa=3"}
}),
};
#define MIPS_INS(ins, ...) \
[MIPS32R2_INS_ ##ins] = { __VA_ARGS__ },
union mips32_instruction mips32r2_instructions[__MIPS32R2_INS_LEN] = {
/* ADD - add */
MIPS_INS(ADD, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_ADD)
/* ADDI - add immediate */
MIPS_INS(ADDI, .op = MIPS32R2_OP_ADDI)
/* ADDIU - add immediate unsigned */
MIPS_INS(ADDIU, .op = MIPS32R2_OP_ADDIU)
/* ADDU - add unsigned */
MIPS_INS(ADDU, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_ADDU)
/* AND - and */
MIPS_INS(AND, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_AND)
/* ANDI - and immediate */
MIPS_INS(ANDI, .op = MIPS32R2_OP_ANDI)
/* BC1F - branch on cop1 false */
MIPS_INS(BC1F, .op = MIPS32R2_OP_COP1, .cfunct = MIPS32R2_FUNCT_BC,
.nd = 0, .tf = 0)
/* BC1FL - branch on cop1 false likely */
MIPS_INS(BC1FL, .op = MIPS32R2_OP_COP1, .cfunct = MIPS32R2_FUNCT_BC,
.nd = 1, .tf = 0)
/* BC1T - branch on cop1 true */
MIPS_INS(BC1T, .op = MIPS32R2_OP_COP1, .cfunct = MIPS32R2_FUNCT_BC,
.nd = 0, .tf = 1)
/* BC1TL - branch on cop1 true likely */
MIPS_INS(BC1TL, .op = MIPS32R2_OP_COP1, .cfunct = MIPS32R2_FUNCT_BC,
.nd = 1, .tf = 1)
/* BC2F - branch on cop1 false */
MIPS_INS(BC2F, .op = MIPS32R2_OP_COP2, .cfunct = MIPS32R2_FUNCT_BC,
.nd = 0, .tf = 0)
/* BC2FL - branch on cop1 false likely */
MIPS_INS(BC2FL, .op = MIPS32R2_OP_COP2, .cfunct = MIPS32R2_FUNCT_BC,
.nd = 1, .tf = 0)
/* BC2T - branch on cop1 true */
MIPS_INS(BC2T, .op = MIPS32R2_OP_COP2, .cfunct = MIPS32R2_FUNCT_BC,
.nd = 0, .tf = 1)
/* BC2TL - branch on cop1 true likely */
MIPS_INS(BC2TL, .op = MIPS32R2_OP_COP2, .cfunct = MIPS32R2_FUNCT_BC,
.nd = 1, .tf = 1)
/* BEQ - branch on equal */
MIPS_INS(BEQ, .op = MIPS32R2_OP_BEQ)
/* BEQL - branch on equal likely */
MIPS_INS(BEQL, .op = MIPS32R2_OP_BEQL)
/* BGEZ - branch on greater than or equal to zero */
MIPS_INS(BGEZ, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_BGEZ)
/* BGEZAL - branch on greater than or equal to zero and link */
MIPS_INS(BGEZAL, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_BGEZAL)
/* BGEZALL - branch on greater than or equal to zero and link likely */
MIPS_INS(BGEZALL, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_BGEZALL)
/* BGEZL - branch on greater than or equal to zero likely */
MIPS_INS(BGEZL, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_BGEZL)
/* BGTZ - branch on greater than zero */
MIPS_INS(BGTZ, .op = MIPS32R2_OP_BGTZ)
/* BGTZL - branch on greater than zero likely */
MIPS_INS(BGTZL, .op = MIPS32R2_OP_BGTZL)
/* BLEZ - branch on less than or equal to zero */
MIPS_INS(BLEZ, .op = MIPS32R2_OP_BLEZ)
/* BLEZL - branch on less than or equal to zero likely */
MIPS_INS(BLEZL, .op = MIPS32R2_OP_BLEZL)
/* BLTZ - branch on less than zero */
MIPS_INS(BLTZ, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_BLTZ)
/* BLTZAL - branch on less than zero and link */
MIPS_INS(BLTZAL, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_BLTZAL)
/* BLTZALL - branch on less than zero and link likely */
MIPS_INS(BLTZALL, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_BLTZALL)
/* BLTZL - branch on less than zero likely */
MIPS_INS(BLTZL, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_BLTZL)
/* BNE - branch on not equal */
MIPS_INS(BNE, .op = MIPS32R2_OP_BNE)
/* BNEL - branch on not equal likely */
MIPS_INS(BNEL, .op = MIPS32R2_OP_BNEL)
/* BREAK - breakpoint */
MIPS_INS(BREAK, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_BREAK)
/* CACHE - perform cache operation */
MIPS_INS(CACHE, .op = MIPS32R2_OP_CACHE)
/* CFC1 - move control word from floating point */
MIPS_INS(CFC1, .op = MIPS32R2_OP_COP1, .cfunct = MIPS32R2_FUNCT_CF)
/* CFC2 - move control word from coprocessor 2 */
MIPS_INS(CFC2, .op = MIPS32R2_OP_COP2, .cfunct = MIPS32R2_FUNCT_CF)
/* CLO - count leading ones */
MIPS_INS(CLO, .op = MIPS32R2_OP_SPECIAL2, .funct = MIPS32R2_FUNCT_CLO)
/* CLZ - count leading zeros */
MIPS_INS(CLZ, .op = MIPS32R2_OP_SPECIAL2, .funct = MIPS32R2_FUNCT_CLZ)
/* COP2 - coprocessor operation to coprocessor 2 */
MIPS_INS(COP2, .op = MIPS32R2_OP_COP2, .c0 = 1)
/* CTC1 - move control word to floating point */
MIPS_INS(CTC1, .op = MIPS32R2_OP_COP1, .cfunct = MIPS32R2_FUNCT_CT)
/* CTC2 - move control word to coprocessor 2 */
MIPS_INS(CTC2, .op = MIPS32R2_OP_COP2, .cfunct = MIPS32R2_FUNCT_CT)
/* DERET - debug exception return */
MIPS_INS(DERET, .op = MIPS32R2_OP_COP0, .c0 = 1, .funct = MIPS32R2_FUNCT_DERET)
/* DI - disable interupts */
MIPS_INS(DI, .op = MIPS32R2_OP_COP0, .cfunct = MIPS32R2_FUNCT_MFMC0,
.rd = 12, .sc = 0)
/* DIV - divide */
MIPS_INS(DIV, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_DIV)
/* DIVU - divide unsigned */
MIPS_INS(DIVU, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_DIVU)
/* EI - enable interupts */
MIPS_INS(EI, .op = MIPS32R2_OP_COP0, .cfunct = MIPS32R2_FUNCT_MFMC0,
.rd = 12, .sc = 1)
/* ERET - exception return */
MIPS_INS(ERET, .op = MIPS32R2_OP_COP0, .c0 = 1, .funct = MIPS32R2_FUNCT_ERET)
/* ERT - extract bit field */
MIPS_INS(EXT, .op = MIPS32R2_OP_SPECIAL3, .funct = MIPS32R2_FUNCT_EXT)
/* INS - insert bit field */
MIPS_INS(INS, .op = MIPS32R2_OP_SPECIAL3, .funct = MIPS32R2_FUNCT_INS)
/* J - jump */
MIPS_INS(J, .op = MIPS32R2_OP_J)
/* JAL - jump and link */
MIPS_INS(JAL, .op = MIPS32R2_OP_JAL)
/* JALR - jump and link register */
MIPS_INS(JALR, .rd = MIPS32_REG_RA, .op = MIPS32R2_OP_SPECIAL,
.funct = MIPS32R2_FUNCT_JALR)
/* JR - jump register */
MIPS_INS(JR, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_JR)
/* LB - load byte */
MIPS_INS(LB, .op = MIPS32R2_OP_LB)
/* LBU - load byte unsigned */
MIPS_INS(LBU, .op = MIPS32R2_OP_LBU)
/* LDC1 - load doubleword floating point */
MIPS_INS(LDC1, .op = MIPS32R2_OP_LDC1)
/* LDC2 - load doubleword cop2 */
MIPS_INS(LDC2, .op = MIPS32R2_OP_LDC2)
/* LDXC1 - load doubleword indexed to floating point */
MIPS_INS(LDXC1, .op = MIPS32R2_OP_COP1X, .funct = MIPS32R2_FUNCT_LDXC1)
/* LH - load half */
MIPS_INS(LH, .op = MIPS32R2_OP_LH)
/* LHU - load half unsigned */
MIPS_INS(LHU, .op = MIPS32R2_OP_LHU)
/* LK - load linked */
MIPS_INS(LL, .op = MIPS32R2_OP_LL)
/* LUI - load upper immediate */
MIPS_INS(LUI, .op = MIPS32R2_OP_LUI)
/* LUXC1 - load doubleword indexed unaligned to floating point */
MIPS_INS(LUXC1, .op = MIPS32R2_OP_COP1X, .funct = MIPS32R2_FUNCT_LUXC1)
/* LW - load word */
MIPS_INS(LW, .op = MIPS32R2_OP_LW)
/* LDC1 - load word floating point */
MIPS_INS(LWC1, .op = MIPS32R2_OP_LWC1)
/* LDC2 - load eword cop2 */
MIPS_INS(LWC2, .op = MIPS32R2_OP_LWC2)
/* LWL - load word left */
MIPS_INS(LWL, .op = MIPS32R2_OP_LWL)
/* LWR - load word right */
MIPS_INS(LWR, .op = MIPS32R2_OP_LWR)
/* LWXC1 - load word indexed to floating point */
MIPS_INS(LWXC1, .op = MIPS32R2_OP_COP1X, .funct = MIPS32R2_FUNCT_LWXC1)
/* MADD - multiply and add words to hi,lo */
MIPS_INS(MADD, .op = MIPS32R2_OP_SPECIAL2, .funct = MIPS32R2_FUNCT_MADD)
/* MADDU - multiply and add unsigned words to hi,lo */
MIPS_INS(MADDU, .op = MIPS32R2_OP_SPECIAL2, .funct = MIPS32R2_FUNCT_MADDU)
/* MFC0 - move from cop0 */
MIPS_INS(MFC0, .op = MIPS32R2_OP_COP0, .cfunct = MIPS32R2_FUNCT_MF)
/* MFC1 - move from floating point */
MIPS_INS(MFC1, .op = MIPS32R2_OP_COP1, .cfunct = MIPS32R2_FUNCT_MF)
/* MFC2 - move from cop2 */
MIPS_INS(MFC2, .op = MIPS32R2_OP_COP0, .cfunct = MIPS32R2_FUNCT_MF)
/* MFHC1 - move word from high half of floating point register */
MIPS_INS(MFHC1, .op = MIPS32R2_OP_COP1, .cfunct = MIPS32R2_FUNCT_MFH)
/* MFHC2 - move word from high half of cop2 */
MIPS_INS(MFHC2, .op = MIPS32R2_OP_COP2, .cfunct = MIPS32R2_FUNCT_MFH)
/* MFHI - move from hi register */
MIPS_INS(MFHI, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_MFHI)
/* MFLO - move from lo register */
MIPS_INS(MFLO, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_MFLO)
/* MOVF - move on floating point false */
MIPS_INS(MOVF, .op = MIPS32R2_OP_SPECIAL, .tf = 0,
.funct = MIPS32R2_FUNCT_MOVCL)
/* MOVN - move conditional on non zero */
MIPS_INS(MOVN, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_MOVN)
/* MOVT - move on floating point true */
MIPS_INS(MOVT, .op = MIPS32R2_OP_SPECIAL, .tf = 1,
.funct = MIPS32R2_FUNCT_MOVCL)
/* MOVZ - move conditional on zero */
MIPS_INS(MOVZ, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_MOVZ)
/* MSUB - multiply and add words to hi,lo */
MIPS_INS(MSUB, .op = MIPS32R2_OP_SPECIAL2, .funct = MIPS32R2_FUNCT_MSUB)
/* MSUBU - multiply and add unsigned words to hi,lo */
MIPS_INS(MSUBU, .op = MIPS32R2_OP_SPECIAL2, .funct = MIPS32R2_FUNCT_MSUBU)
/* MTC0 - move to cop0 */
MIPS_INS(MTC0, .op = MIPS32R2_OP_COP0, .cfunct = MIPS32R2_FUNCT_MT)
/* MTC1 - move to floating point */
MIPS_INS(MTC1, .op = MIPS32R2_OP_COP1, .cfunct = MIPS32R2_FUNCT_MT)
/* MTC2 - move to cop2 */
MIPS_INS(MTC2, .op = MIPS32R2_OP_COP0, .cfunct = MIPS32R2_FUNCT_MT)
/* MTHC1 - move word to high half of floating point register */
MIPS_INS(MTHC1, .op = MIPS32R2_OP_COP1, .cfunct = MIPS32R2_FUNCT_MTH)
/* MTHC2 - move word to high half of cop2 */
MIPS_INS(MTHC2, .op = MIPS32R2_OP_COP2, .cfunct = MIPS32R2_FUNCT_MTH)
/* MTHI - move to hi register */
MIPS_INS(MTHI, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_MTHI)
/* MTLO - move to lo register */
MIPS_INS(MTLO, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_MTLO)
/* MUL - multiply word to GPR */
MIPS_INS(MUL, .op = MIPS32R2_OP_SPECIAL2, .funct = MIPS32R2_FUNCT_MUL)
/* MULT - multiply word */
MIPS_INS(MULT, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_MULT)
/* MULTU - multiply unsigned word */
MIPS_INS(MULTU, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_MULTU)
/* NOR - not or */
MIPS_INS(NOR, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_NOR)
/* OR - or */
MIPS_INS(OR, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_OR)
/* ORI - or imemdiate */
MIPS_INS(ORI, .op = MIPS32R2_OP_ORI)
/* PREF - prefetch */
MIPS_INS(PREF, .op = MIPS32R2_OP_PREF)
/* PREFX - prefetch indexed */
MIPS_INS(PREFX, .op = MIPS32R2_OP_COP1X, .funct = MIPS32R2_FUNCT_PREFX)
/* RDHWR - read hardware register */
MIPS_INS(RDHWR, .op = MIPS32R2_OP_SPECIAL3, .funct = MIPS32R2_FUNCT_RDHWR)
/* RDPGPR - read gpr from previous shadow set */
MIPS_INS(RDPGPR, .op = MIPS32R2_OP_COP0, .cfunct = MIPS32R2_FUNCT_RDPGPR)
/* ROTR - rotate word right */
MIPS_INS(ROTR, .op = MIPS32R2_OP_SPECIAL, .r = 1, .funct = MIPS32R2_FUNCT_SRL)
/* ROTRV - rotate word right variable */
MIPS_INS(ROTRV, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_SRLV,
.rv = 1)
/* SB - store byte */
MIPS_INS(SB, .op = MIPS32R2_OP_SB)
/* SC - store conditional word */
MIPS_INS(SC, .op = MIPS32R2_OP_SC)
/* SDBBP - software debug breakpoint */
MIPS_INS(SDBBP, .op = MIPS32R2_OP_SPECIAL2, .funct = MIPS32R2_FUNCT_SDBBP)
/* SDC1 - store doubleword floating point */
MIPS_INS(SDC1, .op = MIPS32R2_OP_SDC1)
/* SDC2 - store doubleword cop2 */
MIPS_INS(SDC2, .op = MIPS32R2_OP_SDC2)
/* SDXC1 - store doubleword indexed from floating point */
MIPS_INS(SDXC1, .op = MIPS32R2_OP_COP1X, .funct = MIPS32R2_FUNCT_SDXC1)
/* SEB - sign extend byte */
MIPS_INS(SEB, .op = MIPS32R2_OP_SPECIAL3, .shamt = MIPS32R2_FUNCT_SEB,
.funct = MIPS32R2_FUNCT_BSHFL)
/* SEH - sign extend halfword */
MIPS_INS(SEH, .op = MIPS32R2_OP_SPECIAL3, .shamt = MIPS32R2_FUNCT_SEH,
.funct = MIPS32R2_FUNCT_BSHFL)
/* SH - store half */
MIPS_INS(SH, .op = MIPS32R2_OP_SH)
/* SLL - shift left logical */
MIPS_INS(SLL, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_SLL)
/* SLLV - shift left logical variable */
MIPS_INS(SLLV, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_SLLV)
/* SLT - set less then */
MIPS_INS(SLT, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_SLT)
/* SLTI - set less then immediate */
MIPS_INS(SLTI, .op = MIPS32R2_OP_SLTI)
/* SLTIU - set less then imemdiate unsigned */
MIPS_INS(SLTIU, .op = MIPS32R2_OP_SLTIU)
/* SLTU - set less than unsigned */
MIPS_INS(SLTU, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_SLTU)
/* SRA - shift right arithmetic */
MIPS_INS(SRA, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_SRA)
/* SRAV - shift right arithmetic variable */
MIPS_INS(SRAV, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_SRAV)
/* SRL - shift right logical */
MIPS_INS(SRL, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_SRL)
/* SRLV - shift right logical variable */
MIPS_INS(SRLV, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_SRLV)
/* SUB - subtract */
MIPS_INS(SUB, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_SUB)
/* SUBU - subtract unsigned */
MIPS_INS(SUBU, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_SUBU)
/* SUXC1 - store doubleword indexed unaligned from floating point */
MIPS_INS(SUXC1, .op = MIPS32R2_OP_COP1X, .funct = MIPS32R2_FUNCT_SUXC1)
/* SW - store word */
MIPS_INS(SW, .op = MIPS32R2_OP_SW)
/* SWC1 - store word floating point */
MIPS_INS(SWC1, .op = MIPS32R2_OP_SWC1)
/* SWC2 - store eword cop2 */
MIPS_INS(SWC2, .op = MIPS32R2_OP_SWC2)
/* SWL - store word left */
MIPS_INS(SWL, .op = MIPS32R2_OP_SWL)
/* SWR - store word right */
MIPS_INS(SWR, .op = MIPS32R2_OP_SWR)
/* SWXC1 - store word indexed from floating point */
MIPS_INS(SWXC1, .op = MIPS32R2_OP_COP1X, .funct = MIPS32R2_FUNCT_SWXC1)
/* SYNC - synchronize shared memory */
MIPS_INS(SYNC, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_SYNC)
/* SYNCI - synchronize caches to make instruction writes effective */
MIPS_INS(SYNCI, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_SYNCI)
/* SYSCALL - syscall */
MIPS_INS(SYSCALL, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_SYSCALL)
/* TEQ - trap if equal */
MIPS_INS(TEQ, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_TEQ)
/* TEQI - trap if equal immediate */
MIPS_INS(TEQI, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_TEQI)
/* TGE - trap if greater or equal */
MIPS_INS(TGE, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_TGE)
/* TGEI - trap if greater or equal immediate */
MIPS_INS(TGEI, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_TGEI)
/* TGEIU - trap if greater or equal immediate unsigned */
MIPS_INS(TGEIU, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_TGEIU)
/* TGEU - trap if greater or equal unsigned */
MIPS_INS(TGEU, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_TGEU)
/* TLBP - probe TLB for matching entry */
MIPS_INS(TLBP, .op = MIPS32R2_OP_COP0, .c0 = 1, .funct = MIPS32R2_FUNCT_TLBP)
/* TLBR - read indexed TLB entry */
MIPS_INS(TLBR, .op = MIPS32R2_OP_COP0, .c0 = 1, .funct = MIPS32R2_FUNCT_TLBR)
/* TLBWI - write indexed TLB entry */
MIPS_INS(TLBWI, .op = MIPS32R2_OP_COP0, .c0 = 1, .funct = MIPS32R2_FUNCT_TLBWI)
/* TLBWR - write random TLB entry */
MIPS_INS(TLBWR, .op = MIPS32R2_OP_COP0, .c0 = 1, .funct = MIPS32R2_FUNCT_TLBWR)
/* TLT - trap if less then */
MIPS_INS(TLT, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_TLT)
/* TLTI - trap if less then immediate */
MIPS_INS(TLTI, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_TLTI)
/* TLTIU - trap if less then immediate unsigned */
MIPS_INS(TLTIU, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_TLTIU)
/* TLTU - trap if less then unsigned */
MIPS_INS(TLTU, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_TLTU)
/* TNE - trap if not equal */
MIPS_INS(TNE, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_TNE)
/* TNEI - trap if not equal immediate */
MIPS_INS(TNEI, .op = MIPS32R2_OP_REGIMM, .bfunct = MIPS32R2_FUNCT_TNEI)
/* WAIT - enter standby mode */
MIPS_INS(WAIT, .op = MIPS32R2_OP_COP0, .c0 = 1, .funct = MIPS32R2_FUNCT_WAIT)
/* WRPGRP - write to GPR in previous shadow set */
MIPS_INS(WRPGPR, .op = MIPS32R2_OP_COP0, .cfunct = MIPS32R2_FUNCT_WRPGPR)
/* WSBH - word swap bytes within halfwords */
MIPS_INS(WSBH, .op = MIPS32R2_OP_SPECIAL3, .funct = MIPS32R2_FUNCT_BSHFL,
.shamt = MIPS32R2_FUNCT_WSBH)
/* XOR - exclusive or */
MIPS_INS(XOR, .op = MIPS32R2_OP_SPECIAL, .funct = MIPS32R2_FUNCT_XOR)
/* XORI - exclusive or immediate */
MIPS_INS(XORI, .op = MIPS32R2_OP_XORI)
};
#undef MIPS_INS