mips/lib/mips32r6.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