From df4a225ccf79dd9f5fa3faef4fd68ae87471f0ca Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Fri, 13 Sep 2024 11:11:18 -0400 Subject: [PATCH] better --- include/mips.h | 283 +++++++++++++++++---------------- lib/error.c | 7 + masm/asm.c | 28 ++-- masm/lex.c | 32 +++- masm/lex.h | 13 ++ masm/parse.c | 419 ++++++++++++++++++++++++++++++++++++++----------- masm/parse.h | 12 +- 7 files changed, 541 insertions(+), 253 deletions(-) diff --git a/include/mips.h b/include/mips.h index ff043cd..b63d631 100644 --- a/include/mips.h +++ b/include/mips.h @@ -42,14 +42,6 @@ enum mips_register { MIPS_REG_RA = 31, }; -/* mips instruction format */ -enum mips_instruction_format { - MIPS_FORMAT_R, - MIPS_FORMAT_I, - MIPS_FORMAT_J, - MIPS_FORMAT_B, -}; - /* mips instructions */ enum mips_instruction_type { MIPS_INS_ADD, @@ -77,10 +69,10 @@ enum mips_instruction_type { MIPS_INS_BLTZL, MIPS_INS_BNE, MIPS_INS_BNEL, - MIPS_INS_DDIV, - MIPS_INS_DDIVU, MIPS_INS_DIV, + MIPS_INS_MOD, MIPS_INS_DIVU, + MIPS_INS_MODU, MIPS_INS_J, MIPS_INS_JAL, MIPS_INS_JALR, @@ -98,8 +90,11 @@ enum mips_instruction_type { MIPS_INS_MFLO, MIPS_INS_MTHI, MIPS_INS_MTLO, + MIPS_INS_MUL, + MIPS_INS_MUH, + MIPS_INS_MULU, + MIPS_INS_MUHU, MIPS_INS_MULT, - MIPS_INS_MULTU, MIPS_INS_SB, MIPS_INS_SH, MIPS_INS_SW, @@ -127,352 +122,368 @@ enum mips_instruction_type { __MIPS_INS_LEN, }; -/* mips instruction R TYPE */ -struct mips_instruction_r_data { - uint32_t funct : 6; - uint32_t shamt : 5; - uint32_t rd : 5; - uint32_t rt : 5; - uint32_t rs : 5; - uint32_t op : 6; -} __attribute__((packed)); - -/* mips instruction I TYPE */ -struct mips_instruction_i_data { - uint32_t immd : 16; - uint32_t rt : 5; - uint32_t rs : 5; - uint32_t op : 6; -} __attribute__((packed)); - -/* mips instruction J TYPE */ -struct mips_instruction_j_data { - uint32_t target : 26; - uint32_t op : 6; -} __attribute__((packed)); - -/* mips instruction BRANCH TYPE */ -struct mips_instruction_branch_data { - int32_t offset : 16; - uint32_t funct : 5; - uint32_t rs : 5; - uint32_t op : 6; -} __attribute__((packed)); - union mips_instruction_data { - uint32_t raw; - struct mips_instruction_r_data R; - struct mips_instruction_i_data I; - struct mips_instruction_j_data J; - struct mips_instruction_branch_data B; + /* raw ins */ + uint32_t raw : 32; + /* register type */ + struct { + uint32_t funct : 6; + uint32_t shamt : 5; + uint32_t rd : 5; + uint32_t rt : 5; + uint32_t rs : 5; + uint32_t op : 6; + }; + /* immediate type */ + struct { + uint32_t immd : 16; + uint32_t : 16; + }; + /* jump type */ + struct { + uint32_t target : 26; + uint32_t : 6; + }; + /* branch compact */ + struct { + int32_t offs26 : 26; + uint32_t : 6; + }; + /* branch */ + struct { + int32_t offset : 16; + uint32_t bfunct : 5; + uint32_t : 11; + }; } __attribute__((packed)); /* mips instruction information */ struct mips_instruction { // metadata enum mips_instruction_type type; - enum mips_instruction_format format; const char *name; // data union mips_instruction_data data; }; - -#define MIPS_INS(ins, format, ...) \ +#define MIPS_INS(ins, ...) \ [MIPS_INS_ ##ins] = { \ MIPS_INS_ ##ins, \ - MIPS_FORMAT_ ##format, \ #ins, \ - .data = { .format = { __VA_ARGS__ } } \ + .data = { __VA_ARGS__ } \ }, \ static const struct mips_instruction mips_instructions[] = { /* ADD - add */ #define MIPS_OP_SPECIAL 0b000000 #define MIPS_FUNCT_ADD 0b100000 -MIPS_INS(ADD, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_ADD) +MIPS_INS(ADD, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_ADD) /* ADDI - add immediate */ #define MIPS_OP_ADDI 0b001000 -MIPS_INS(ADDI, I, .op = MIPS_OP_ADDI) +MIPS_INS(ADDI, .op = MIPS_OP_ADDI) /* ADDIU - add immediate unsigned */ #define MIPS_OP_ADDIU 0b001001 -MIPS_INS(ADDIU, I, .op = MIPS_OP_ADDIU) +MIPS_INS(ADDIU, .op = MIPS_OP_ADDIU) /* ADDU - add unsigned */ #define MIPS_FUNCT_ADDU 0b100001 -MIPS_INS(ADDU, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_ADDU) +MIPS_INS(ADDU, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_ADDU) /* AND - and */ #define MIPS_FUNCT_AND 0b100100 -MIPS_INS(AND, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_AND) +MIPS_INS(AND, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_AND) /* ANDI - and immediate */ #define MIPS_OP_ANDI 0b001100 -MIPS_INS(ANDI, I, .op = MIPS_OP_ANDI) +MIPS_INS(ANDI, .op = MIPS_OP_ANDI) /* BAL - branch and link */ #define MIPS_OP_REGIMM 0b000001 #define MIPS_FUNCT_BAL 0b10001 -MIPS_INS(BAL, B, .op = MIPS_OP_REGIMM, .funct = MIPS_FUNCT_BAL) +MIPS_INS(BAL, .op = MIPS_OP_REGIMM, .funct = MIPS_FUNCT_BAL) /* BALC - branch and link, compact */ #define MIPS_OP_BALC 0b111010 -MIPS_INS(BALC, J, .op = MIPS_OP_BALC) +MIPS_INS(BALC, .op = MIPS_OP_BALC) /* BC - branch, compact */ #define MIPS_OP_BC 0b110010 -MIPS_INS(BC, J, .op = MIPS_OP_BC) +MIPS_INS(BC, .op = MIPS_OP_BC) /* BEQ - branch on equal */ #define MIPS_OP_BEQ 0b000100 -MIPS_INS(BEQ, I, .op = MIPS_OP_BEQ) +MIPS_INS(BEQ, .op = MIPS_OP_BEQ) /* BEQL - branch on equal likely */ #define MIPS_OP_BEQL 0b010100 -MIPS_INS(BEQL, I, .op = MIPS_OP_BEQL) +MIPS_INS(BEQL, .op = MIPS_OP_BEQL) /* BGEZ - branch on greater than or equal to zero */ #define MIPS_FUNCT_BGEZ 0b00001 -MIPS_INS(BGEZ, B, .op = MIPS_OP_REGIMM, .funct = MIPS_FUNCT_BGEZ) +MIPS_INS(BGEZ, .op = MIPS_OP_REGIMM, .bfunct = MIPS_FUNCT_BGEZ) /* BGEZAL - branch on greater than or equal to zero and link */ #define MIPS_FUNCT_BGEZAL 0b10001 -MIPS_INS(BGEZAL, B, .op = MIPS_OP_REGIMM, .funct = MIPS_FUNCT_BGEZAL) +MIPS_INS(BGEZAL, .op = MIPS_OP_REGIMM, .bfunct = MIPS_FUNCT_BGEZAL) /* BGEZAL - branch on greater than or equal to zero and link likely */ #define MIPS_FUNCT_BGEZALL 0b10011 -MIPS_INS(BGEZALL, B, .op = MIPS_OP_REGIMM, .funct = MIPS_FUNCT_BGEZALL) +MIPS_INS(BGEZALL, .op = MIPS_OP_REGIMM, .bfunct = MIPS_FUNCT_BGEZALL) /* BGEZL - branch on greater than or equal to zero likely */ #define MIPS_FUNCT_BGEZL 0b00011 -MIPS_INS(BGEZL, B, .op = MIPS_OP_REGIMM, .funct = MIPS_FUNCT_BGEZL) +MIPS_INS(BGEZL, .op = MIPS_OP_REGIMM, .bfunct = MIPS_FUNCT_BGEZL) /* BGTZ - branch on greater than zero */ #define MIPS_OP_BGTZ 0b000111 -MIPS_INS(BGTZ, I, .op = MIPS_OP_BGTZ) +MIPS_INS(BGTZ, .op = MIPS_OP_BGTZ) /* BGTZL - branch on greater than zero likely */ #define MIPS_OP_BGTZL 0b010111 -MIPS_INS(BGTZL, I, .op = MIPS_OP_BGTZL) +MIPS_INS(BGTZL, .op = MIPS_OP_BGTZL) /* BLEZ - branch on less than or equal to zero */ #define MIPS_OP_BLEZ 0b000110 -MIPS_INS(BLEZ, I, .op = MIPS_OP_BLEZ) +MIPS_INS(BLEZ, .op = MIPS_OP_BLEZ) /* BLEZL - branch on less than or equal to zero likely */ #define MIPS_OP_BLEZL 0b010110 -MIPS_INS(BLEZL, I, .op = MIPS_OP_BLEZL) +MIPS_INS(BLEZL, .op = MIPS_OP_BLEZL) /* BLTZ - branch on less than zero */ #define MIPS_FUNCT_BLTZ 0b00000 -MIPS_INS(BLTZ, B, .op = MIPS_OP_REGIMM, .funct = MIPS_FUNCT_BLTZ) +MIPS_INS(BLTZ, .op = MIPS_OP_REGIMM, .bfunct = MIPS_FUNCT_BLTZ) /* BLTZAL - branch on less than zero and link */ #define MIPS_FUNCT_BLTZAL 0b10000 -MIPS_INS(BLTZAL, B, .op = MIPS_OP_REGIMM, .funct = MIPS_FUNCT_BLTZAL) +MIPS_INS(BLTZAL, .op = MIPS_OP_REGIMM, .bfunct = MIPS_FUNCT_BLTZAL) /* BLTZALL - branch on less than zero and link likely */ #define MIPS_FUNCT_BLTZALL 0b10010 -MIPS_INS(BLTZALL, B, .op = MIPS_OP_REGIMM, .funct = MIPS_FUNCT_BLTZALL) +MIPS_INS(BLTZALL, .op = MIPS_OP_REGIMM, .bfunct = MIPS_FUNCT_BLTZALL) /* BLTZL - branch on less than zero likely */ #define MIPS_FUNCT_BLTZL 0b00010 -MIPS_INS(BLTZL, B, .op = MIPS_OP_REGIMM, .funct = MIPS_FUNCT_BLTZL) +MIPS_INS(BLTZL, .op = MIPS_OP_REGIMM, .bfunct = MIPS_FUNCT_BLTZL) /* BNE - branch on not equal */ #define MIPS_OP_BNE 0b000101 -MIPS_INS(BNE, I, .op = MIPS_OP_BNE) +MIPS_INS(BNE, .op = MIPS_OP_BNE) /* BNEL - branch on not equal likely */ #define MIPS_OP_BNEL 0b010101 -MIPS_INS(BNEL, I, .op = MIPS_OP_BNEL) - -/* DDIV - doubleword divide */ -#define MIPS_FUNCT_DDIV 0b011110 -MIPS_INS(DDIV, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_DDIV) - -/* DDIVU - doubleword divide unsigned */ -#define MIPS_FUNCT_DDIVU 0b011111 -MIPS_INS(DDIVU, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_DDIVU) +MIPS_INS(BNEL, .op = MIPS_OP_BNEL) /* DIV - divide */ -#define MIPS_FUNCT_DIV 0b011010 -MIPS_INS(DIV, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_DIV) +#define MIPS_FUNCT_SOP32 0b011010 +#define MIPS_SOP32_DIV 0b00010 +MIPS_INS(DIV, .op = MIPS_OP_SPECIAL, .shamt = MIPS_SOP32_DIV, + .funct = MIPS_FUNCT_SOP32) + +/* MOD - modulo */ +#define MIPS_SOP32_MOD 0b00011 +MIPS_INS(MOD, .op = MIPS_OP_SPECIAL, .shamt = MIPS_SOP32_MOD, + .funct = MIPS_FUNCT_SOP32) /* DIVU - divide unsigned */ -#define MIPS_FUNCT_DIVU 0b011011 -MIPS_INS(DIVU, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_DIVU) +#define MIPS_FUNCT_SOP33 0b011011 +#define MIPS_SOP33_DIVU 0b00010 +MIPS_INS(DIVU, .op = MIPS_OP_SPECIAL, .shamt = MIPS_SOP33_DIVU, + .funct = MIPS_FUNCT_SOP33) + +/* MODU - modulo unsigned */ +#define MIPS_SOP33_MODU 0b00011 +MIPS_INS(MODU, .op = MIPS_OP_SPECIAL, .shamt = MIPS_SOP33_MODU, + .funct = MIPS_FUNCT_SOP33) /* J - jump */ #define MIPS_OP_J 0b000010 -MIPS_INS(J, J, .op = MIPS_OP_J) +MIPS_INS(J, .op = MIPS_OP_J) /* JAL - jump and link */ #define MIPS_OP_JAL 0b000011 -MIPS_INS(JAL, J, .op = MIPS_OP_JAL) +MIPS_INS(JAL, .op = MIPS_OP_JAL) /* JALR - jump and link register */ #define MIPS_FUNCT_JALR 0b001001 -MIPS_INS(JALR, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_JALR) +MIPS_INS(JALR, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_JALR) /* JALX - jump and link exchange */ #define MIPS_OP_JALX 0b011101 -MIPS_INS(JALX, J, .op = MIPS_OP_JALX) +MIPS_INS(JALX, .op = MIPS_OP_JALX) /* JR - jump register */ #define MIPS_FUNCT_JR 0b001000 -MIPS_INS(JR, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_JR) +MIPS_INS(JR, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_JR) /* LB - load byte */ #define MIPS_OP_LB 0b100000 -MIPS_INS(LB, I, .op = MIPS_OP_LB) +MIPS_INS(LB, .op = MIPS_OP_LB) /* LBU - load byte unsigned */ #define MIPS_OP_LBU 0b100100 -MIPS_INS(LBU, I, .op = MIPS_OP_LBU) +MIPS_INS(LBU, .op = MIPS_OP_LBU) /* LH - load half */ #define MIPS_OP_LH 0b100001 -MIPS_INS(LH, I, .op = MIPS_OP_LH) +MIPS_INS(LH, .op = MIPS_OP_LH) /* LHU - load half unsigned */ #define MIPS_OP_LHU 0b100101 -MIPS_INS(LHU, I, .op = MIPS_OP_LHU) +MIPS_INS(LHU, .op = MIPS_OP_LHU) /* LUI - load upper immediate */ #define MIPS_OP_LUI 0b001111 -MIPS_INS(LUI, I, .op = MIPS_OP_LUI) +MIPS_INS(LUI, .op = MIPS_OP_LUI) /* LW - load word */ #define MIPS_OP_LW 0b100011 -MIPS_INS(LW, I, .op = MIPS_OP_LW) +MIPS_INS(LW, .op = MIPS_OP_LW) /* LWL - load word left */ #define MIPS_OP_LWL 0b100010 -MIPS_INS(LWL, I, .op = MIPS_OP_LWL) +MIPS_INS(LWL, .op = MIPS_OP_LWL) /* LWR - load word right */ #define MIPS_OP_LWR 0b100110 -MIPS_INS(LWR, I, .op = MIPS_OP_LWR) +MIPS_INS(LWR, .op = MIPS_OP_LWR) /* MFHI - move from hi */ #define MIPS_FUNCT_MFHI 0b010000 -MIPS_INS(MFHI, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_MFHI) +MIPS_INS(MFHI, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_MFHI) /* MFLO - move from hi */ #define MIPS_FUNCT_MFLO 0b010010 -MIPS_INS(MFLO, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_MFLO) +MIPS_INS(MFLO, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_MFLO) /* MTHI - move from hi */ #define MIPS_FUNCT_MTHI 0b010001 -MIPS_INS(MTHI, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_MTHI) +MIPS_INS(MTHI, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_MTHI) /* MTLO - move from hi */ #define MIPS_FUNCT_MTLO 0b010011 -MIPS_INS(MTLO, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_MTLO) +MIPS_INS(MTLO, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_MTLO) -/* MULT - multiply */ +/* MUL - multiply low word */ +#define MIPS_FUNCT_SOP30 0b011000 +#define MIPS_SOP30_MUL 0b00010 +MIPS_INS(MUL, .op = MIPS_OP_SPECIAL, .shamt = MIPS_SOP30_MUL, + .funct = MIPS_FUNCT_SOP30) + +/* MUH - multiply high word */ +#define MIPS_SOP30_MUH 0b00011 +MIPS_INS(MUH, .op = MIPS_OP_SPECIAL, .shamt = MIPS_SOP30_MUH, + .funct = MIPS_FUNCT_SOP30) + +/* MULU - multiply low word unsigned */ +#define MIPS_FUNCT_SOP31 0b011001 +#define MIPS_SOP31_MULU 0b00010 +MIPS_INS(MULU, .op = MIPS_OP_SPECIAL, .shamt = MIPS_SOP31_MULU, + .funct = MIPS_FUNCT_SOP31) + +/* MUHU - multiply high word unsgined */ +#define MIPS_SOP31_MUHU 0b00011 +MIPS_INS(MUHU, .op = MIPS_OP_SPECIAL, .shamt = MIPS_SOP31_MUHU, + .funct = MIPS_FUNCT_SOP31) + +/* MULT - multiply (OLD) */ #define MIPS_FUNCT_MULT 0b011000 -MIPS_INS(MULT, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_MULT) - -/* MULTU - multiply unsigned */ -#define MIPS_FUNCT_MULTU 0b011001 -MIPS_INS(MULTU, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_MULTU) +MIPS_INS(MULT, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_MULT) /* SB - store byte */ #define MIPS_OP_SB 0b101000 -MIPS_INS(SB, I, .op = MIPS_OP_SB) +MIPS_INS(SB, .op = MIPS_OP_SB) /* SH - store half */ #define MIPS_OP_SH 0b101001 -MIPS_INS(SH, I, .op = MIPS_OP_SH) +MIPS_INS(SH, .op = MIPS_OP_SH) /* SW - store word */ #define MIPS_OP_SW 0b101011 -MIPS_INS(SW, I, .op = MIPS_OP_SW) +MIPS_INS(SW, .op = MIPS_OP_SW) /* SWL - store word left */ #define MIPS_OP_SWL 0b101010 -MIPS_INS(SWL, I, .op = MIPS_OP_SWL) +MIPS_INS(SWL, .op = MIPS_OP_SWL) /* SWR - store word right */ #define MIPS_OP_SWR 0b101110 -MIPS_INS(SWR, I, .op = MIPS_OP_SWR) +MIPS_INS(SWR, .op = MIPS_OP_SWR) /* SLL - shift left logical */ #define MIPS_FUNCT_SLL 0b000000 -MIPS_INS(SLL, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SLL) +MIPS_INS(SLL, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SLL) /* SLLV - shift left logical variable */ #define MIPS_FUNCT_SLLV 0b000100 -MIPS_INS(SLLV, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SLLV) +MIPS_INS(SLLV, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SLLV) /* SLT - set less then */ #define MIPS_FUNCT_SLT 0b101010 -MIPS_INS(SLT, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SLT) +MIPS_INS(SLT, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SLT) /* SLTI - set less then immediate */ #define MIPS_OP_SLTI 0b001010 -MIPS_INS(SLTI, I, .op = MIPS_OP_SLTI) +MIPS_INS(SLTI, .op = MIPS_OP_SLTI) /* SLTIU - set less then imemdiate unsigned */ #define MIPS_OP_SLTIU 0b001011 -MIPS_INS(SLTIU, I, .op = MIPS_OP_SLTIU) +MIPS_INS(SLTIU, .op = MIPS_OP_SLTIU) /* SLTU - set less than unsigned */ #define MIPS_FUNCT_SLTU 0b101011 -MIPS_INS(SLTU, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SLTU) +MIPS_INS(SLTU, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SLTU) /* SRA - shift right arithmetic */ #define MIPS_FUNCT_SRA 0b000011 -MIPS_INS(SRA, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SRA) +MIPS_INS(SRA, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SRA) /* SRAV - shift right arithmetic variable */ #define MIPS_FUNCT_SRAV 0b000111 -MIPS_INS(SRAV, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SRAV) +MIPS_INS(SRAV, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SRAV) /* SRL - shift right logical */ #define MIPS_FUNCT_SRL 0b000010 -MIPS_INS(SRL, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SRL) +MIPS_INS(SRL, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SRL) /* SRLV - shift right logical variable */ #define MIPS_FUNCT_SRLV 0b000110 -MIPS_INS(SRLV, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SRLV) +MIPS_INS(SRLV, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SRLV) /* SUB - subtract */ #define MIPS_FUNCT_SUB 0b100010 -MIPS_INS(SUB, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SUB) +MIPS_INS(SUB, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SUB) /* SUBU - subtract unsigned */ #define MIPS_FUNCT_SUBU 0b100011 -MIPS_INS(SUBU, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SUBU) +MIPS_INS(SUBU, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SUBU) /* SYSCALL - syscall */ #define MIPS_FUNCT_SYSCALL 0b001100 -MIPS_INS(SYSCALL, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SYSCALL) +MIPS_INS(SYSCALL, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_SYSCALL) /* OR - or */ #define MIPS_FUNCT_OR 0b100101 -MIPS_INS(OR, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_OR) +MIPS_INS(OR, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_OR) /* ORI - or imemdiate */ #define MIPS_OP_ORI 0b001101 -MIPS_INS(ORI, I, .op = MIPS_OP_ORI) +MIPS_INS(ORI, .op = MIPS_OP_ORI) /* NOR - not or */ #define MIPS_FUNCT_NOR 0b100111 -MIPS_INS(NOR, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_NOR) +MIPS_INS(NOR, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_NOR) /* XOR - exclusive or */ #define MIPS_FUNCT_XOR 0b100110 -MIPS_INS(XOR, R, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_XOR) +MIPS_INS(XOR, .op = MIPS_OP_SPECIAL, .funct = MIPS_FUNCT_XOR) /* XORI - exclusive or immediate */ #define MIPS_OP_XORI 0b001110 -MIPS_INS(XORI, I, .op = MIPS_OP_XORI) +MIPS_INS(XORI, .op = MIPS_OP_XORI) }; #undef MIPS_INS diff --git a/lib/error.c b/lib/error.c index 78f75ef..352a60d 100644 --- a/lib/error.c +++ b/lib/error.c @@ -3,10 +3,14 @@ #include char *current_file = "file.asm"; +int log_disabled = 1; __attribute__((format(printf, 4, 5))) void __log_impl_pos(int line, int column, int type, const char *format, ...) { + if (log_disabled) + return; + va_list list; va_start(list, format); @@ -31,6 +35,9 @@ void __log_impl_pos(int line, int column, int type, const char *format, ...) __attribute__((format(printf, 2, 3))) void __log_impl(int type, const char *format, ...) { + if (log_disabled) + return; + va_list list; va_start(list, format); diff --git a/masm/asm.c b/masm/asm.c index 883cb55..fb8d12c 100644 --- a/masm/asm.c +++ b/masm/asm.c @@ -247,24 +247,15 @@ static int handle_ins(struct assembler *assembler, if (sec_push(sec, entry)) return M_ERROR; - unsigned char type = 0; - switch (ref->type) { - case REF_NONE: + if (ref->type == R_MIPS_NONE) continue; - case REF_OFFESET: - type = R_MIPS_PC16; - break; - case REF_TARGET: - type = R_MIPS_26; - break; - } size_t symidx; if (find_symbol_or_stub(assembler, ref->name, NULL, &symidx)) return M_ERROR; Elf32_Rela rel = { - .r_info = htonl(ELF32_R_INFO(symidx, type)), + .r_info = htonl(ELF32_R_INFO(symidx, ref->type)), .r_addend = htonl(ref->addend), .r_offset = htonl(sec_index(sec, secidx + i)), }; @@ -543,7 +534,7 @@ static void update_offsets(struct assembler *assembler, Elf32_Ehdr *ehdr) } // sections - size_t v_addr = 0x00400000; + size_t v_addr = 0; for (uint32_t i = 0; i < assembler->sectab.len; i++) { struct section *sec = &assembler->sectab.sections[i]; uint32_t idx = sec->shdr_idx; @@ -631,11 +622,14 @@ static int write_file(struct assembler *assembler, Elf32_Ehdr *ehdr, for (uint32_t j = 0; j < sec->len; j++) { struct section_entry *entry = &sec->entries[j]; size_t size = entry->size; - fwrite(&entry->data, size, 1, out); - while(size % sec->alignment) { - uint8_t zero = 0; - fwrite(&zero, 1, 1, out); - size++; + size_t zeros = size % sec->alignment;; + if (entry->type != ENT_NO_DATA) + fwrite(&entry->data, size, 1, out); + else + zeros += size; + while(zeros) { + fputc(0, out); + zeros--; } } } diff --git a/masm/lex.c b/masm/lex.c index 788523b..37adf8e 100644 --- a/masm/lex.c +++ b/masm/lex.c @@ -149,6 +149,14 @@ static int lex_number(struct lexer *lexer, int64_t *n) { int64_t number = 0; int base = 10; + int neg = 0; + + // check if negative + if (lex_peek(lexer) == '-') { + lex_next(lexer); + neg = 1; + } + // skip all leading zeros, they dont do anything. // this also allows us to directly check for 0b, 0o, and 0x @@ -200,6 +208,9 @@ static int lex_number(struct lexer *lexer, int64_t *n) number += n; } + if (neg) + number = -number; + *n = number; return M_SUCCESS; } @@ -226,7 +237,8 @@ again: // use label to avoid whitespace recursion case ';': case '#': skip_comment(lexer); - goto again; + token->type = TOK_NL; + break; case ' ': case '\t': // skip white space @@ -267,6 +279,7 @@ again: // use label to avoid whitespace recursion lex_next(lexer); res = lex_string(lexer, token->text); break; + case '-': case '0': case '1': case '2': @@ -341,3 +354,20 @@ char *token_str(enum token_type type) } return "unknown"; } + +void lexer_save(struct lexer *lexer, struct lexer_state *state) +{ + state->x = lexer->x; + state->y = lexer->y; + state->peek = lexer->peek; + state->offset = ftell(lexer->file); +} + +/* load a different state into a lexer */ +void lexer_load(struct lexer *lexer, const struct lexer_state *state) +{ + lexer->x = state->x; + lexer->y = state->y; + lexer->peek = state->peek; + fseek(lexer->file, state->offset, SEEK_SET); +} diff --git a/masm/lex.h b/masm/lex.h index f1c482a..e08d0a3 100644 --- a/masm/lex.h +++ b/masm/lex.h @@ -14,6 +14,13 @@ struct lexer { int y; }; +struct lexer_state { + long offset; + int peek; + int x; + int y; +}; + enum token_type { TOK_IDENT, TOK_REG, @@ -52,4 +59,10 @@ int lexer_next(struct lexer *lexer, struct token *token); /* token type to string */ char *token_str(enum token_type); +/* save the state of a lexer */ +void lexer_save(struct lexer *lexer, struct lexer_state *state); + +/* load a different state into a lexer */ +void lexer_load(struct lexer *lexer, const struct lexer_state *state); + #endif /* __LEX_H__ */ diff --git a/masm/parse.c b/masm/parse.c index d0a1f33..221ef6d 100644 --- a/masm/parse.c +++ b/masm/parse.c @@ -1,10 +1,14 @@ #include #include +#include +#include #include #include +#include #include "parse.h" #include "lex.h" +#include "mips.h" static int next_token(struct parser *parser, struct token *tok) { @@ -78,8 +82,6 @@ enum mips_parse_format { MIPS_PARSE_I, // jump type: offset MIPS_PARSE_J, - // jump type: register - MIPS_PARSE_JR, // offset 16b type: offset MIPS_PARSE_O16, // offset 26b type: offset @@ -129,15 +131,15 @@ const enum mips_parse_format mips_parse_formats[] = { FORMAT(BLTZL, BZ) FORMAT(BNE, BE) FORMAT(BNEL, BE) - FORMAT(DDIV, R2) - FORMAT(DDIVU, R2) - FORMAT(DIV, R2) - FORMAT(DIVU, R2) + FORMAT(DIV, R) + FORMAT(MOD, R) + FORMAT(DIVU, R) + FORMAT(MODU, R) FORMAT(J, J) FORMAT(JAL, J) - FORMAT(JALR, JR) // TODO: handle rd + FORMAT(JALR, RS) // TODO: handle rd FORMAT(JALX, J) - FORMAT(JR, JR) + FORMAT(JR, RS) FORMAT(LB, SL) FORMAT(LBU, SL) FORMAT(LH, SL) @@ -150,8 +152,11 @@ const enum mips_parse_format mips_parse_formats[] = { FORMAT(MFLO, RD) FORMAT(MTHI, RS) FORMAT(MTLO, RS) + FORMAT(MUL, R) + FORMAT(MUH, R) + FORMAT(MULU, R) + FORMAT(MUHU, R) FORMAT(MULT, R2) - FORMAT(MULTU, R2) FORMAT(SB, SL) FORMAT(SH, SL) FORMAT(SW, SL) @@ -178,12 +183,13 @@ const enum mips_parse_format mips_parse_formats[] = { #undef FORMAT -#define MAX5 32 -#define MAX16 65536 -#define MAX26 67108864 +#define MAX5 (1 << 5) +#define MAX16 (1 << 16) +#define MAX26 (1 << 25) +#define MAX32 (1 << 31) -static int get_reference(struct parser *parser, uint32_t *offset, - struct reference *ref, enum reference_type type) +static int get_reference(struct parser *parser, uint64_t *offset, + struct reference *ref, unsigned char type) { struct token token; @@ -191,6 +197,7 @@ static int get_reference(struct parser *parser, uint32_t *offset, return M_ERROR; if (token.type == TOK_NUMBER) { + *offset = token.number; return M_SUCCESS; } @@ -210,16 +217,64 @@ static int get_reference(struct parser *parser, uint32_t *offset, return M_SUCCESS; } -static int get_offset(struct parser *parser, uint32_t *offset, +static int get_offset(struct parser *parser, int32_t *offset, struct reference *ref) { - return get_reference(parser, offset, ref, REF_OFFESET); + uint64_t off; + if (get_reference(parser, &off, ref, R_MIPS_PC16)) + return M_ERROR; + + if (off % 4) { + ERROR_POS((*parser->lexer), "cannot use offset of '%ld', must " + "be divisble by four", off); + return M_ERROR; + } + + if (off > MAX16) { + ERROR("offset '%d' cannot be larger than 16 bits", off); + return M_ERROR; + } + + *offset = off; + return M_SUCCESS; +} + +static int get_offset_26(struct parser *parser, int32_t *offset, + struct reference *ref) +{ + uint64_t off; + if (get_reference(parser, &off, ref, R_MIPS_PC26_S2)) + return M_ERROR; + + if (off % 4) { + ERROR_POS((*parser->lexer), "cannot use offset of '%ld', must " + "be divisble by four", off); + return M_ERROR; + } + + if (off > MAX26) { + ERROR("offset '%d' cannot be larger than 26 bits", off); + return M_ERROR; + } + + *offset = off; + return M_SUCCESS; } static int get_target(struct parser *parser, uint32_t *offset, struct reference *ref) { - return get_reference(parser, offset, ref, REF_TARGET); + uint64_t off; + if (get_reference(parser, &off, ref, R_MIPS_26)) + return M_ERROR; + + if (off > MAX26) { + ERROR("target '%d' cannot be larger than 26 bits", off); + return M_ERROR; + } + + *offset = off; + return M_SUCCESS; } static int get_instruction(const char *ident, struct mips_instruction *res) @@ -333,7 +388,7 @@ static int parse_register(struct parser *parser, enum mips_register *reg) // $rp else if (c0 == 'r') { - if (c1 == 'p') { + if (c1 == 'a') { *reg = MIPS_REG_RA; return M_SUCCESS; } @@ -356,6 +411,77 @@ static int parse_register(struct parser *parser, enum mips_register *reg) return M_ERROR; } +static int get_reg_offset(struct parser *parser, struct mips_instruction *ins, + struct reference *ref) +{ + struct token token; + enum mips_register reg; + +// ============================================= + + // defaults + ins->data.rs = MIPS_REG_ZERO; + ins->data.immd = 0; + + if (peek_token(parser, &token)) + return M_ERROR; + + if (token.type == TOK_LPAREN) + goto reg; + else + goto off; + +// ============================================= + +off: + + uint64_t immd; + if (get_reference(parser, &immd, ref, R_MIPS_16)) + return M_ERROR; + ins->data.offset = htons(immd); + + if (peek_token(parser, &token)) + return M_ERROR; + + if (token.type == TOK_LPAREN) + goto reg; + else + goto end; + +// ============================================= + +reg: + if (assert_token(parser, TOK_LPAREN, NULL)) + return M_ERROR; + + if (parse_register(parser, ®)) + return M_ERROR; + ins->data.rs = reg; + + if (assert_token(parser, TOK_RPAREN, NULL)) + return M_ERROR; + +// ============================================= +end: + if (peek_token(parser, &token)) + return M_ERROR; + + return M_SUCCESS; +} + +static int parse_number(struct parser *parser, uint32_t *n, uint32_t max) +{ + struct token token; + if (assert_token(parser, TOK_NUMBER, &token)) + return M_ERROR; + if (max && token.number > max) { + ERROR_POS(token, "number cannot be larger than '%d'", max); + return M_ERROR; + } + *n = token.number; + return M_SUCCESS; +} + static int parse_instruction_r(struct parser *parser, struct mips_instruction *ins) { @@ -364,21 +490,21 @@ static int parse_instruction_r(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->data.R.rd = reg; + ins->data.rd = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->data.R.rs = reg; + ins->data.rs = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->data.R.rt = reg; + ins->data.rt = reg; return M_SUCCESS; } @@ -391,14 +517,14 @@ static int parse_instruction_r2(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->data.R.rs = reg; + ins->data.rs = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->data.R.rt = reg; + ins->data.rt = reg; return M_SUCCESS; } @@ -411,7 +537,7 @@ static int parse_instruction_rs(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->data.R.rs = reg; + ins->data.rs = reg; return M_SUCCESS; } @@ -424,7 +550,7 @@ static int parse_instruction_rd(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->data.R.rd = reg; + ins->data.rd = reg; return M_SUCCESS; } @@ -438,14 +564,14 @@ static int parse_instruction_i(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->data.I.rt = reg; + ins->data.rt = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->data.I.rs = reg; + ins->data.rs = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; @@ -455,7 +581,7 @@ static int parse_instruction_i(struct parser *parser, if (token.number >= MAX16) return M_ERROR; - ins->data.I.immd = token.number; + ins->data.immd = htons(token.number); return M_SUCCESS; } @@ -465,17 +591,21 @@ static int parse_instruction_offset(struct parser *parser, struct mips_instruction *ins, struct reference *ref) { - uint32_t n; - if (get_offset(parser, &n, ref) || n > max) - return M_ERROR; + int32_t n; switch (max) { case MAX26: - ins->data.J.target = n; + if (get_offset_26(parser, &n, ref)) + return M_ERROR; + ins->data.offs26 = htonl(n); break; case MAX16: - ins->data.B.offset = n; + if (get_offset(parser, &n, ref)) + return M_ERROR; + ins->data.offset = htons(n); break; + default: + return M_ERROR; } return M_SUCCESS; @@ -488,30 +618,34 @@ static int parse_instruction_j(struct parser *parser, uint32_t n; if (get_target(parser, &n, ref) || n > MAX26) return M_ERROR; - ins->data.J.target = n; - - return M_SUCCESS; -} - -static int parse_instruction_jr(struct parser *parser, - struct mips_instruction *ins, - struct reference *ref) -{ - uint32_t n; - if (get_target(parser, &n, ref) || n > MAX26) - return M_ERROR; - ins->data.J.target = n; + ins->data.target = n; return M_SUCCESS; } static int parse_instruction_branch_equal(struct parser *parser, - struct mips_instruction *ins) + struct mips_instruction *ins, + struct reference *ref) { enum mips_register reg; if (parse_register(parser, ®)) return M_ERROR; - ins->data.R.rs = reg; + ins->data.rs = reg; + + if (assert_token(parser, TOK_COMMA, NULL)) + return M_ERROR; + + if (parse_register(parser, ®)) + return M_ERROR; + ins->data.rt = reg; + + if (assert_token(parser, TOK_COMMA, NULL)) + return M_ERROR; + + int32_t off; + if (get_offset(parser, &off, ref)) + return M_ERROR; + ins->data.offset = htons(off); return M_SUCCESS; } @@ -521,18 +655,18 @@ static int parse_instruction_branch(struct parser *parser, struct reference *ref) { enum mips_register reg; - uint32_t n; + int32_t n; if (parse_register(parser, ®)) return M_ERROR; - ins->data.B.rs = reg; + ins->data.rs = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; - if (get_offset(parser, &n, ref) || n > MAX16) + if (get_offset(parser, &n, ref)) return M_ERROR; - ins->data.B.offset = n; + ins->data.offset = htons(n); return M_SUCCESS; } @@ -542,40 +676,15 @@ static int parse_instruction_sl(struct parser *parser, struct reference *ref) { enum mips_register reg; - uint32_t offset = 0; - struct token token; if (parse_register(parser, ®)) return M_ERROR; - ins->data.I.rt = reg; + ins->data.rt = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; - if (peek_token(parser, &token)) - return M_ERROR; - - if (token.type != TOK_LPAREN) - if (get_offset(parser, &offset, ref)) - return M_ERROR; - ins->data.I.immd = offset; - - if (peek_token(parser, &token)) - return M_ERROR; - - if (token.type == TOK_NL) { - ins->data.I.rs = MIPS_REG_ZERO; - return M_SUCCESS; - } - - if (assert_token(parser, TOK_LPAREN, NULL)) - return M_ERROR; - - if (parse_register(parser, ®)) - return M_ERROR; - ins->data.I.rs = reg; - - if (assert_token(parser, TOK_RPAREN, NULL)) + if (get_reg_offset(parser, ins, ref)) return M_ERROR; return M_SUCCESS; @@ -589,14 +698,14 @@ static int parse_instruction_sli(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->data.I.rt = reg; + ins->data.rt = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (assert_token(parser, TOK_NUMBER, &token) || token.number > MAX16) return M_ERROR; - ins->data.I.immd = token.number; + ins->data.immd = htons(token.number); return M_SUCCESS; } @@ -609,21 +718,21 @@ static int parse_instruction_s(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->data.R.rd = reg; + ins->data.rd = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->data.R.rt = reg; + ins->data.rt = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (assert_token(parser, TOK_NUMBER, &token) || token.number > MAX5) return M_ERROR; - ins->data.R.shamt = token.number; + ins->data.shamt = token.number; return M_SUCCESS; } @@ -635,25 +744,151 @@ static int parse_instruction_sv(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->data.R.rd = reg; + ins->data.rd = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->data.R.rt = reg; + ins->data.rt = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->data.R.rs = reg; + ins->data.rs = reg; return M_SUCCESS; } +static int parse_pseudo_li(struct parser *parser, struct ins_expr *expr) +{ + enum mips_register reg; + uint32_t immd; + + if (parse_register(parser, ®)) + return M_ERROR; + + if (assert_token(parser, TOK_COMMA, NULL)) + return M_ERROR; + + if (parse_number(parser, &immd, MAX16)) + return M_ERROR; + + expr->ins_len = 1; + expr->ins[0] = mips_instructions[MIPS_INS_ORI]; + expr->ins[0].data.rt = reg; + expr->ins[0].data.rs = MIPS_REG_ZERO; + expr->ins[0].data.immd = htons(immd); + expr->ref[0].type = R_MIPS_NONE; + + return M_SUCCESS; +} + +static int parse_pseudo_la(struct parser *parser, struct ins_expr *expr) +{ + enum mips_register reg; + struct token token; + + uint16_t hi = 0, lo = 0; + + if (parse_register(parser, ®)) + return M_ERROR; + + if (assert_token(parser, TOK_COMMA, NULL)) + return M_ERROR; + + if (next_token(parser, &token)) + return M_ERROR; + + if (token.type == TOK_IDENT) { + expr->ref[0].type = R_MIPS_HI16; + expr->ref[0].addend = 0; + strcpy(expr->ref[0].name, token.text); + expr->ref[1].type = R_MIPS_LO16; + expr->ref[1].addend = 0; + strcpy(expr->ref[1].name, token.text); + } else if (token.type == TOK_NUMBER && token.number > MAX32) { + hi = token.number >> 16; + lo = token.number & 0x0000ffff; + expr->ref[0].type = R_MIPS_NONE; + expr->ref[1].type = R_MIPS_NONE; + } else { + return M_ERROR; + } + + expr->ins_len = 2; + expr->ins[0] = mips_instructions[MIPS_INS_LUI]; + expr->ins[0].data.rt = reg; + expr->ins[0].data.immd = htons(hi); + expr->ins[1] = mips_instructions[MIPS_INS_ORI]; + expr->ins[1].data.rt = reg; + expr->ins[1].data.rs = MIPS_REG_ZERO; + expr->ins[1].data.immd = htons(lo); + + return M_SUCCESS; +} + +static int parse_pseudo_move(struct parser *parser, struct ins_expr *expr) +{ + enum mips_register rd, rs; + + if (parse_register(parser, &rd)) + return M_ERROR; + + if (assert_token(parser, TOK_COMMA, NULL)) + return M_ERROR; + + if (parse_register(parser, &rs)) + return M_ERROR; + + expr->ins_len = 1; + expr->ins[0] = mips_instructions[MIPS_INS_OR]; + expr->ins[0].data.rs = rs; + expr->ins[0].data.rt = MIPS_REG_ZERO; + expr->ins[0].data.rd = rd; + expr->ref[0].type = R_MIPS_NONE; + + return M_SUCCESS; +} + +static int parse_pseudo_instruction(struct parser *parser, + struct ins_expr *expr, + struct token ident) +{ + // disablle logging in the logging + // module + extern int log_disabled; + log_disabled = 1; + + int res = M_ERROR; + + struct lexer_state state; + lexer_save(parser->lexer, &state); + + #define CHK(name) if (strcmp(ident.text, #name) == 0) + + CHK(li) + res = parse_pseudo_li(parser, expr); + else CHK(la) + res = parse_pseudo_la(parser, expr); + else CHK(move) + res = parse_pseudo_move(parser, expr); + + if (res) + lexer_load(parser->lexer, &state); + + expr->ins[0].data.raw = 0; + expr->ins[1].data.raw = 0; + expr->ref[0] = (struct reference) {0}; + expr->ref[1] = (struct reference) {0}; + + log_disabled = 0; + return res; +} + static int parse_instruction(struct parser *parser, struct ins_expr *expr, struct token ident) @@ -662,6 +897,9 @@ static int parse_instruction(struct parser *parser, enum mips_parse_format format; int res = M_SUCCESS; + if (parse_pseudo_instruction(parser, expr, ident) == M_SUCCESS) + return M_SUCCESS; + if (get_instruction(ident.text, &instruction)) { ERROR_POS(ident, "unknown instruction '%s'", ident.text); return M_ERROR; @@ -673,7 +911,7 @@ static int parse_instruction(struct parser *parser, // this will only ever generate one instruction expr->ins_len = 1; *ins = instruction; - ref->type = REF_NONE; + ref->type = R_MIPS_NONE; format = mips_parse_formats[instruction.type]; switch (format) { @@ -695,9 +933,6 @@ static int parse_instruction(struct parser *parser, case MIPS_PARSE_J: res = parse_instruction_j(parser, ins, ref); break; - case MIPS_PARSE_JR: - res = parse_instruction_jr(parser, ins, ref); - break; case MIPS_PARSE_O16: res = parse_instruction_offset(parser, MAX16, ins, ref); break; @@ -705,7 +940,7 @@ static int parse_instruction(struct parser *parser, res = parse_instruction_offset(parser, MAX26, ins, ref); break; case MIPS_PARSE_BE: - res = parse_instruction_branch_equal(parser, ins); + res = parse_instruction_branch_equal(parser, ins, ref); break; case MIPS_PARSE_BZ: res = parse_instruction_branch(parser, ins, ref); diff --git a/masm/parse.h b/masm/parse.h index 3052d51..9e0e928 100644 --- a/masm/parse.h +++ b/masm/parse.h @@ -37,14 +37,9 @@ struct mips_directive { }; }; -enum reference_type { - REF_NONE, - REF_OFFESET, - REF_TARGET, -}; - struct reference { - enum reference_type type; + // ELF relocate type + unsigned char type; /// symbol name char name[MAX_LEX_LENGTH]; @@ -91,7 +86,10 @@ struct expr { }; struct parser { + // the lexer + // *weak* ponter, we do not own this struct lexer *lexer; + // the last token peeked struct token peek; };