286 lines
7.2 KiB
C
286 lines
7.2 KiB
C
#include <mips32r6.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, MIPS32R6_INS_ ##name, \
|
|
/* pseudo stub */ 0, {{0, ""}}}
|
|
|
|
#define PSEUDO(name, grammer, ...) {name, grammer, __MIPS32R6_INS_NULL, \
|
|
__VA_ARGS__ }
|
|
|
|
struct mips32_grammer mips32r6_grammers[__MIPS32R6_GRAMMER_LEN] = {
|
|
|
|
// real instructions
|
|
|
|
INS(ADD, RTYPE),
|
|
INS(ADDI, ITYPE),
|
|
INS(ADDIU, ITYPE),
|
|
INS(ADDU, RTYPE),
|
|
INS(AND, RTYPE),
|
|
INS(ADDI, ITYPE),
|
|
INS(ANDI, ITYPE),
|
|
INS(BAL, "offset"),
|
|
INS(BALC, "target"),
|
|
INS(BC, "target"),
|
|
INS(BEQ, BRANCH),
|
|
INS(BGEZ, BRANCHZ),
|
|
INS(BGEZAL, BRANCHZ),
|
|
INS(BGTZ, BRANCHZ),
|
|
INS(BLEZ, BRANCHZ),
|
|
INS(BLTZ, BRANCHZ),
|
|
INS(BLTZAL, BRANCHZ),
|
|
INS(BNE, BRANCH),
|
|
INS(DIV, RTYPE),
|
|
INS(MOD, RTYPE),
|
|
INS(DIVU, RTYPE),
|
|
INS(MODU, RTYPE),
|
|
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(LUI, "rt,immd"),
|
|
INS(LW, LOAD),
|
|
INS(MUL, RTYPE),
|
|
INS(MUH, RTYPE),
|
|
INS(MULU, RTYPE),
|
|
INS(MUHU, RTYPE),
|
|
INS(SB, LOAD),
|
|
INS(SH, LOAD),
|
|
INS(SW, 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(SYSCALL, ""),
|
|
INS(OR, RTYPE),
|
|
INS(ORI, ITYPE),
|
|
INS(NOR, RTYPE),
|
|
INS(XOR, RTYPE),
|
|
INS(XORI, ITYPE),
|
|
|
|
// pseudo instructions
|
|
|
|
PSEUDO("li", "rt,immd", 1, {
|
|
{MIPS32R6_INS_ADDI, "rt,immd"}
|
|
}),
|
|
|
|
PSEUDO("la", "rt,target", 2, {
|
|
{MIPS32R6_INS_LUI, "rt=$at,hi"},
|
|
{MIPS32R6_INS_ORI, "rt,rs=$at,lo"},
|
|
}),
|
|
|
|
PSEUDO("move", "rd,rs", 1, {
|
|
{MIPS32R6_INS_OR, "rd,rs"}
|
|
}),
|
|
|
|
PSEUDO("nop", "", 1, {
|
|
{MIPS32R6_INS_SLL, ""},
|
|
}),
|
|
};
|
|
|
|
#define MIPS_INS(ins, ...) \
|
|
[MIPS32R6_INS_ ##ins] = { __VA_ARGS__ },
|
|
|
|
union mips32_instruction mips32r6_instructions[__MIPS32R6_INS_LEN] = {
|
|
/* ADD - add */
|
|
MIPS_INS(ADD, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_ADD)
|
|
|
|
/* ADDI - add immediate */
|
|
MIPS_INS(ADDI, .op = MIPS32R6_OP_ADDI)
|
|
|
|
/* ADDIU - add immediate unsigned */
|
|
MIPS_INS(ADDIU, .op = MIPS32R6_OP_ADDIU)
|
|
|
|
/* ADDU - add unsigned */
|
|
MIPS_INS(ADDU, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_ADDU)
|
|
|
|
/* AND - and */
|
|
MIPS_INS(AND, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_AND)
|
|
|
|
/* ANDI - and immediate */
|
|
MIPS_INS(ANDI, .op = MIPS32R6_OP_ANDI)
|
|
|
|
/* BAL - branch and link */
|
|
MIPS_INS(BAL, .op = MIPS32R6_OP_REGIMM, .bfunct = MIPS32R6_FUNCT_BAL)
|
|
|
|
/* BALC - branch and link, compact */
|
|
MIPS_INS(BALC, .op = MIPS32R6_OP_BALC)
|
|
|
|
/* BC - branch, compact */
|
|
MIPS_INS(BC, .op = MIPS32R6_OP_BC)
|
|
|
|
/* BEQ - branch on equal */
|
|
MIPS_INS(BEQ, .op = MIPS32R6_OP_BEQ)
|
|
|
|
/* BGEZ - branch on greater than or equal to zero */
|
|
MIPS_INS(BGEZ, .op = MIPS32R6_OP_REGIMM, .bfunct = MIPS32R6_FUNCT_BGEZ)
|
|
|
|
/* BGEZAL - branch on greater than or equal to zero and link */
|
|
MIPS_INS(BGEZAL, .op = MIPS32R6_OP_REGIMM, .bfunct = MIPS32R6_FUNCT_BGEZAL)
|
|
|
|
/* BGTZ - branch on greater than zero */
|
|
MIPS_INS(BGTZ, .op = MIPS32R6_OP_BGTZ)
|
|
|
|
/* BLEZ - branch on less than or equal to zero */
|
|
MIPS_INS(BLEZ, .op = MIPS32R6_OP_BLEZ)
|
|
|
|
/* BLTZ - branch on less than zero */
|
|
MIPS_INS(BLTZ, .op = MIPS32R6_OP_REGIMM, .bfunct = MIPS32R6_FUNCT_BLTZ)
|
|
|
|
/* BLTZAL - branch on less than zero and link */
|
|
MIPS_INS(BLTZAL, .op = MIPS32R6_OP_REGIMM, .bfunct = MIPS32R6_FUNCT_BLTZAL)
|
|
|
|
/* BNE - branch on not equal */
|
|
MIPS_INS(BNE, .op = MIPS32R6_OP_BNE)
|
|
|
|
/* DIV - divide */
|
|
MIPS_INS(DIV, .op = MIPS32R6_OP_SPECIAL, .shamt = MIPS32R6_SOP32_DIV,
|
|
.funct = MIPS32R6_FUNCT_SOP32)
|
|
|
|
/* MOD - modulo */
|
|
MIPS_INS(MOD, .op = MIPS32R6_OP_SPECIAL, .shamt = MIPS32R6_SOP32_MOD,
|
|
.funct = MIPS32R6_FUNCT_SOP32)
|
|
|
|
/* DIVU - divide unsigned */
|
|
MIPS_INS(DIVU, .op = MIPS32R6_OP_SPECIAL, .shamt = MIPS32R6_SOP33_DIVU,
|
|
.funct = MIPS32R6_FUNCT_SOP33)
|
|
|
|
/* MODU - modulo unsigned */
|
|
MIPS_INS(MODU, .op = MIPS32R6_OP_SPECIAL, .shamt = MIPS32R6_SOP33_MODU,
|
|
.funct = MIPS32R6_FUNCT_SOP33)
|
|
|
|
/* J - jump */
|
|
MIPS_INS(J, .op = MIPS32R6_OP_J)
|
|
|
|
/* JAL - jump and link */
|
|
MIPS_INS(JAL, .op = MIPS32R6_OP_JAL)
|
|
|
|
/* JALR - jump and link register */
|
|
MIPS_INS(JALR, .rd = MIPS32_REG_RA, .op = MIPS32R6_OP_SPECIAL,
|
|
.funct = MIPS32R6_FUNCT_JALR)
|
|
|
|
/* JALX - jump and link exchange */
|
|
MIPS_INS(JALX, .op = MIPS32R6_OP_JALX)
|
|
|
|
/* JR - jump register */
|
|
MIPS_INS(JR, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_JR)
|
|
|
|
/* LB - load byte */
|
|
MIPS_INS(LB, .op = MIPS32R6_OP_LB)
|
|
|
|
/* LBU - load byte unsigned */
|
|
MIPS_INS(LBU, .op = MIPS32R6_OP_LBU)
|
|
|
|
/* LH - load half */
|
|
MIPS_INS(LH, .op = MIPS32R6_OP_LH)
|
|
|
|
/* LHU - load half unsigned */
|
|
MIPS_INS(LHU, .op = MIPS32R6_OP_LHU)
|
|
|
|
/* LUI - load upper immediate */
|
|
MIPS_INS(LUI, .op = MIPS32R6_OP_LUI)
|
|
|
|
/* LW - load word */
|
|
MIPS_INS(LW, .op = MIPS32R6_OP_LW)
|
|
|
|
/* MUL - multiply low word */
|
|
MIPS_INS(MUL, .op = MIPS32R6_OP_SPECIAL, .shamt = MIPS32R6_SOP30_MUL,
|
|
.funct = MIPS32R6_FUNCT_SOP30)
|
|
|
|
/* MUH - multiply high word */
|
|
MIPS_INS(MUH, .op = MIPS32R6_OP_SPECIAL, .shamt = MIPS32R6_SOP30_MUH,
|
|
.funct = MIPS32R6_FUNCT_SOP30)
|
|
|
|
/* MULU - multiply low word unsigned */
|
|
MIPS_INS(MULU, .op = MIPS32R6_OP_SPECIAL, .shamt = MIPS32R6_SOP31_MULU,
|
|
.funct = MIPS32R6_FUNCT_SOP31)
|
|
|
|
/* MUHU - multiply high word unsgined */
|
|
MIPS_INS(MUHU, .op = MIPS32R6_OP_SPECIAL, .shamt = MIPS32R6_SOP31_MUHU,
|
|
.funct = MIPS32R6_FUNCT_SOP31)
|
|
|
|
/* SB - store byte */
|
|
MIPS_INS(SB, .op = MIPS32R6_OP_SB)
|
|
|
|
/* SH - store half */
|
|
MIPS_INS(SH, .op = MIPS32R6_OP_SH)
|
|
|
|
/* SW - store word */
|
|
MIPS_INS(SW, .op = MIPS32R6_OP_SW)
|
|
|
|
/* SLL - shift left logical */
|
|
MIPS_INS(SLL, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_SLL)
|
|
|
|
/* SLLV - shift left logical variable */
|
|
MIPS_INS(SLLV, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_SLLV)
|
|
|
|
/* SLT - set less then */
|
|
MIPS_INS(SLT, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_SLT)
|
|
|
|
/* SLTI - set less then immediate */
|
|
MIPS_INS(SLTI, .op = MIPS32R6_OP_SLTI)
|
|
|
|
/* SLTIU - set less then imemdiate unsigned */
|
|
MIPS_INS(SLTIU, .op = MIPS32R6_OP_SLTIU)
|
|
|
|
/* SLTU - set less than unsigned */
|
|
MIPS_INS(SLTU, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_SLTU)
|
|
|
|
/* SRA - shift right arithmetic */
|
|
MIPS_INS(SRA, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_SRA)
|
|
|
|
/* SRAV - shift right arithmetic variable */
|
|
MIPS_INS(SRAV, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_SRAV)
|
|
|
|
/* SRL - shift right logical */
|
|
MIPS_INS(SRL, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_SRL)
|
|
|
|
/* SRLV - shift right logical variable */
|
|
MIPS_INS(SRLV, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_SRLV)
|
|
|
|
/* SUB - subtract */
|
|
MIPS_INS(SUB, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_SUB)
|
|
|
|
/* SUBU - subtract unsigned */
|
|
MIPS_INS(SUBU, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_SUBU)
|
|
|
|
/* SYSCALL - syscall */
|
|
MIPS_INS(SYSCALL, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_SYSCALL)
|
|
|
|
/* OR - or */
|
|
MIPS_INS(OR, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_OR)
|
|
|
|
/* ORI - or imemdiate */
|
|
MIPS_INS(ORI, .op = MIPS32R6_OP_ORI)
|
|
|
|
/* NOR - not or */
|
|
MIPS_INS(NOR, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_NOR)
|
|
|
|
/* XOR - exclusive or */
|
|
MIPS_INS(XOR, .op = MIPS32R6_OP_SPECIAL, .funct = MIPS32R6_FUNCT_XOR)
|
|
|
|
/* XORI - exclusive or immediate */
|
|
MIPS_INS(XORI, .op = MIPS32R6_OP_XORI)
|
|
};
|
|
|
|
#undef MIPS_INS
|
|
|