summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-10-04 19:41:10 -0400
committerFreya Murphy <freya@freyacat.org>2024-10-04 19:41:10 -0400
commit1c11a13ff33873bcc79d4597d31cd252d5c6c1ae (patch)
treea4321b97f5ad69d1a9b9d06dd629a4dc532758b0 /lib
parentupdate msim usage (diff)
downloadmips-1c11a13ff33873bcc79d4597d31cd252d5c6c1ae.tar.gz
mips-1c11a13ff33873bcc79d4597d31cd252d5c6c1ae.tar.bz2
mips-1c11a13ff33873bcc79d4597d31cd252d5c6c1ae.zip
refactor masm to add codegen step
Diffstat (limited to '')
-rw-r--r--lib/mips32r6.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/lib/mips32r6.c b/lib/mips32r6.c
new file mode 100644
index 0000000..1f1fe61
--- /dev/null
+++ b/lib/mips32r6.c
@@ -0,0 +1,286 @@
+#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
+