summaryrefslogtreecommitdiff
path: root/masm/parse_mips32.c
diff options
context:
space:
mode:
Diffstat (limited to 'masm/parse_mips32.c')
-rw-r--r--masm/parse_mips32.c955
1 files changed, 487 insertions, 468 deletions
diff --git a/masm/parse_mips32.c b/masm/parse_mips32.c
index 032f115..db7f346 100644
--- a/masm/parse_mips32.c
+++ b/masm/parse_mips32.c
@@ -14,50 +14,50 @@
/* each instruction has a given parse format
* internal to the parser */
enum mips32_parse_format {
- // register type: rs, rt, td
- MIPS32_PARSE_R,
- // register type: rs, rt
- MIPS32_PARSE_R2,
- // register type: rd
- MIPS32_PARSE_RD,
- // register type: rs
- MIPS32_PARSE_RS,
- // imeediate type: rs, rt, immd
- MIPS32_PARSE_I,
- // jump type: offset
- MIPS32_PARSE_J,
- // jump type: register
- MIPS32_PARSE_JR,
- // offset 16b type: offset
- MIPS32_PARSE_O16,
- // offset 26b type: offset
- MIPS32_PARSE_O26,
- // breanch equal type: rs, rt, offset
- MIPS32_PARSE_BE,
- // branch zero type: rs, offset
- MIPS32_PARSE_BZ,
- // store and load: rt, offset(base)
- MIPS32_PARSE_SL,
- // store and load immediate: rt, immediate
- MIPS32_PARSE_SLI,
- // shift: rd, rt, sa
- MIPS32_PARSE_S,
- // shift variable: rd, rt, rs
- MIPS32_PARSE_SV,
- // none:
- MIPS32_PARSE_NONE,
+ // register type: rs, rt, td
+ MIPS32_PARSE_R,
+ // register type: rs, rt
+ MIPS32_PARSE_R2,
+ // register type: rd
+ MIPS32_PARSE_RD,
+ // register type: rs
+ MIPS32_PARSE_RS,
+ // imeediate type: rs, rt, immd
+ MIPS32_PARSE_I,
+ // jump type: offset
+ MIPS32_PARSE_J,
+ // jump type: register
+ MIPS32_PARSE_JR,
+ // offset 16b type: offset
+ MIPS32_PARSE_O16,
+ // offset 26b type: offset
+ MIPS32_PARSE_O26,
+ // breanch equal type: rs, rt, offset
+ MIPS32_PARSE_BE,
+ // branch zero type: rs, offset
+ MIPS32_PARSE_BZ,
+ // store and load: rt, offset(base)
+ MIPS32_PARSE_SL,
+ // store and load immediate: rt, immediate
+ MIPS32_PARSE_SLI,
+ // shift: rd, rt, sa
+ MIPS32_PARSE_S,
+ // shift variable: rd, rt, rs
+ MIPS32_PARSE_SV,
+ // none:
+ MIPS32_PARSE_NONE,
};
#define FORMAT(ins, format) \
- [MIPS32_INS_##ins] = MIPS32_PARSE_##format, \
+ [MIPS32_INS_##ins] = MIPS32_PARSE_##format, \
const enum mips32_parse_format mips32_parse_formats[] = {
- FORMAT(ADD, R)
- FORMAT(ADDI, I)
+ FORMAT(ADD, R)
+ FORMAT(ADDI, I)
FORMAT(ADDIU, I)
FORMAT(ADDU, R)
- FORMAT(AND, R)
- FORMAT(ANDI, I)
+ FORMAT(AND, R)
+ FORMAT(ANDI, I)
FORMAT(BAL, O16)
FORMAT(BALC, O26)
FORMAT(BC, O26)
@@ -94,34 +94,34 @@ const enum mips32_parse_format mips32_parse_formats[] = {
FORMAT(LW, SL)
FORMAT(LWL, SL)
FORMAT(LWR, SL)
- FORMAT(MFHI, RD)
- FORMAT(MFLO, RD)
- FORMAT(MTHI, RS)
- FORMAT(MTLO, RS)
- FORMAT(MULT, R2)
- FORMAT(MULTU, R2)
+ FORMAT(MFHI, RD)
+ FORMAT(MFLO, RD)
+ FORMAT(MTHI, RS)
+ FORMAT(MTLO, RS)
+ FORMAT(MULT, R2)
+ FORMAT(MULTU, R2)
FORMAT(SB, SL)
FORMAT(SH, SL)
FORMAT(SW, SL)
FORMAT(SWL, SL)
FORMAT(SLL, S)
FORMAT(SLLV, SV)
- FORMAT(SLT, R)
- FORMAT(SLTI, I)
- FORMAT(SLTIU, I)
- FORMAT(SLTU, R)
+ FORMAT(SLT, R)
+ FORMAT(SLTI, I)
+ FORMAT(SLTIU, I)
+ FORMAT(SLTU, R)
FORMAT(SRA, S)
FORMAT(SRAV, SV)
FORMAT(SRL, S)
FORMAT(SRLV, SV)
- FORMAT(SYSCALL, NONE)
- FORMAT(OR, R)
- FORMAT(ORI, I)
- FORMAT(NOR, R)
- FORMAT(SUB, R)
- FORMAT(SUBU, R)
- FORMAT(XOR, R)
- FORMAT(XORI, I)
+ FORMAT(SYSCALL, NONE)
+ FORMAT(OR, R)
+ FORMAT(ORI, I)
+ FORMAT(NOR, R)
+ FORMAT(SUB, R)
+ FORMAT(SUBU, R)
+ FORMAT(XOR, R)
+ FORMAT(XORI, I)
};
#undef FORMAT
@@ -131,75 +131,75 @@ const enum mips32_parse_format mips32_parse_formats[] = {
#define MAX26 67108864
static int get_reference(struct parser *parser, uint32_t *offset,
- enum reference_type type)
+ enum reference_type type)
{
- struct token token;
+ struct token token;
- if (next_token(parser, &token))
- return M_ERROR;
+ if (next_token(parser, &token))
+ return M_ERROR;
- if (token.type == TOK_NUMBER) {
- *offset = token.number;
- return M_SUCCESS;
- }
+ if (token.type == TOK_NUMBER) {
+ *offset = token.number;
+ return M_SUCCESS;
+ }
- if (token.type != TOK_IDENT) {
- ERROR_POS(token, "unexpected token of type '%s'",
- token_str(token.type));
- return M_ERROR;
- }
+ if (token.type != TOK_IDENT) {
+ ERROR_POS(token, "unexpected token of type '%s'",
+ token_str(token.type));
+ return M_ERROR;
+ }
- struct reference reference = {
- .section = parser->sec_tbl.current,
- .index = parser->sec_tbl.current->count,
- .type = type,
- };
- strcpy(reference.name, token.text);
+ struct reference reference = {
+ .section = parser->sec_tbl.current,
+ .index = parser->sec_tbl.current->count,
+ .type = type,
+ };
+ strcpy(reference.name, token.text);
- if (reftbl_push(&parser->ref_tbl, reference))
- return M_ERROR;
+ if (reftbl_push(&parser->ref_tbl, reference))
+ return M_ERROR;
- *offset = 0;
+ *offset = 0;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int get_offset(struct parser *parser, uint32_t *offset)
{
- return get_reference(parser, offset, REF_OFFESET);
+ return get_reference(parser, offset, REF_OFFESET);
}
static int get_target(struct parser *parser, uint32_t *offset)
{
- return get_reference(parser, offset, REF_TARGET);
+ return get_reference(parser, offset, REF_TARGET);
}
static int get_instruction(const char *ident, struct mips32_instruction *res)
{
- for (int i = 0; i < __MIPS32_INS_LEN; i++) {
- struct mips32_instruction ins =
- mips32_instructions[i];
- if (strcasecmp(ident, ins.name) == 0) {
- if (res != NULL)
- *res = ins;
- return M_SUCCESS;
- }
- }
- return M_ERROR;
+ for (int i = 0; i < __MIPS32_INS_LEN; i++) {
+ struct mips32_instruction ins =
+ mips32_instructions[i];
+ if (strcasecmp(ident, ins.name) == 0) {
+ if (res != NULL)
+ *res = ins;
+ return M_SUCCESS;
+ }
+ }
+ return M_ERROR;
}
static int is_instruction(const char *ident)
{
- return get_instruction(ident, NULL);
+ return get_instruction(ident, NULL);
}
static int parse_register(struct parser *parser, enum mips32_register *reg)
{
- struct token token;
- if (assert_token(parser, TOK_REG, &token))
- return M_ERROR;
+ struct token token;
+ if (assert_token(parser, TOK_REG, &token))
+ return M_ERROR;
- int len = strlen(token.text);
+ int len = strlen(token.text);
int c0 = len > 0 ? token.text[0] : '\0',
c1 = len > 1 ? token.text[1] : '\0',
c2 = len > 2 ? token.text[2] : '\0',
@@ -304,550 +304,569 @@ static int parse_register(struct parser *parser, enum mips32_register *reg)
i += c1 - '0';
}
if (i <= 31) {
- *reg = i;
- return M_SUCCESS;
- }
+ *reg = i;
+ return M_SUCCESS;
+ }
}
- ERROR_POS(token, "unknown register $%s", token.text);
+ ERROR_POS(token, "unknown register $%s", token.text);
return M_ERROR;
}
static int parse_instruction_r(struct parser *parser,
- struct mips32_instruction *ins)
+ struct mips32_instruction *ins)
{
- // format: rs, rt, rd
- enum mips32_register reg;
+ // format: rs, rt, rd
+ enum mips32_register reg;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->R_data.rd = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->R_data.rd = reg;
- if (assert_token(parser, TOK_COMMA, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_COMMA, NULL))
+ return M_ERROR;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->R_data.rs = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->R_data.rs = reg;
- if (assert_token(parser, TOK_COMMA, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_COMMA, NULL))
+ return M_ERROR;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->R_data.rt = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->R_data.rt = reg;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction_r2(struct parser *parser,
- struct mips32_instruction *ins)
+ struct mips32_instruction *ins)
{
- // format: rs, rt
- enum mips32_register reg;
+ // format: rs, rt
+ enum mips32_register reg;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->R_data.rs = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->R_data.rs = reg;
- if (assert_token(parser, TOK_COMMA, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_COMMA, NULL))
+ return M_ERROR;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->R_data.rt = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->R_data.rt = reg;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction_rs(struct parser *parser,
- struct mips32_instruction *ins)
+ struct mips32_instruction *ins)
{
- // format: rs
- enum mips32_register reg;
+ // format: rs
+ enum mips32_register reg;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->R_data.rs = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->R_data.rs = reg;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction_rd(struct parser *parser,
- struct mips32_instruction *ins)
+ struct mips32_instruction *ins)
{
- // format: rd
- enum mips32_register reg;
+ // format: rd
+ enum mips32_register reg;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->R_data.rd = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->R_data.rd = reg;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction_i(struct parser *parser,
- struct mips32_instruction *ins)
+ struct mips32_instruction *ins)
{
- // format: rs, rt, immd
- enum mips32_register reg;
- struct token token;
+ // format: rs, rt, immd
+ enum mips32_register reg;
+ struct token token;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->I_data.rt = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->I_data.rt = reg;
- if (assert_token(parser, TOK_COMMA, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_COMMA, NULL))
+ return M_ERROR;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->I_data.rs = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->I_data.rs = reg;
- if (assert_token(parser, TOK_COMMA, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_COMMA, NULL))
+ return M_ERROR;
- if (assert_token(parser, TOK_NUMBER, &token))
- return M_ERROR;
+ if (assert_token(parser, TOK_NUMBER, &token))
+ return M_ERROR;
- if (token.number >= MAX16)
- return M_ERROR;
- ins->I_data.immd = token.number;
+ if (token.number >= MAX16)
+ return M_ERROR;
+ ins->I_data.immd = token.number;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction_offset(struct parser *parser,
- uint32_t max,
- struct mips32_instruction *ins)
+ uint32_t max,
+ struct mips32_instruction *ins)
{
- uint32_t n;
- if (get_offset(parser, &n) || n > max)
- return M_ERROR;
+ uint32_t n;
+ if (get_offset(parser, &n) || n > max)
+ return M_ERROR;
- switch (max) {
- case MAX26:
- ins->J_data.target = n;
- break;
- case MAX16:
- ins->B_data.offset = n;
- break;
- }
+ switch (max) {
+ case MAX26:
+ ins->J_data.target = n;
+ break;
+ case MAX16:
+ ins->B_data.offset = n;
+ break;
+ }
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction_j(struct parser *parser,
- struct mips32_instruction *ins)
+ struct mips32_instruction *ins)
{
- uint32_t n;
- if (get_target(parser, &n) || n > MAX26)
- return M_ERROR;
- ins->J_data.target = n;
+ uint32_t n;
+ if (get_target(parser, &n) || n > MAX26)
+ return M_ERROR;
+ ins->J_data.target = n;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction_jr(struct parser *parser,
- struct mips32_instruction *ins)
+ struct mips32_instruction *ins)
{
- uint32_t n;
- if (get_target(parser, &n) || n > MAX26)
- return M_ERROR;
- ins->J_data.target = n;
+ uint32_t n;
+ if (get_target(parser, &n) || n > MAX26)
+ return M_ERROR;
+ ins->J_data.target = n;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction_branch_equal(struct parser *parser,
- struct mips32_instruction *ins)
+ struct mips32_instruction *ins)
{
- enum mips32_register reg;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->R_data.rs = reg;
+ enum mips32_register reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->R_data.rs = reg;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction_branch(struct parser *parser,
- struct mips32_instruction *ins)
+ struct mips32_instruction *ins)
{
- enum mips32_register reg;
- uint32_t n;
+ enum mips32_register reg;
+ uint32_t n;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->B_data.rs = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->B_data.rs = reg;
- if (assert_token(parser, TOK_COMMA, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_COMMA, NULL))
+ return M_ERROR;
- if (get_offset(parser, &n) || n > MAX16)
- return M_ERROR;
- ins->B_data.offset = n;
+ if (get_offset(parser, &n) || n > MAX16)
+ return M_ERROR;
+ ins->B_data.offset = n;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction_sl(struct parser *parser,
- struct mips32_instruction *ins)
+ struct mips32_instruction *ins)
{
- enum mips32_register reg;
- uint32_t offset = 0;
- struct token token;
+ enum mips32_register reg;
+ uint32_t offset = 0;
+ struct token token;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->I_data.rt = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->I_data.rt = reg;
- if (assert_token(parser, TOK_COMMA, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_COMMA, NULL))
+ return M_ERROR;
- if (peek_token(parser, &token))
- return M_ERROR;
+ if (peek_token(parser, &token))
+ return M_ERROR;
- if (token.type != TOK_LPAREN)
- if (get_offset(parser, &offset))
- return M_ERROR;
- ins->I_data.immd = offset;
+ if (token.type != TOK_LPAREN)
+ if (get_offset(parser, &offset))
+ return M_ERROR;
+ ins->I_data.immd = offset;
- if (peek_token(parser, &token))
- return M_ERROR;
+ if (peek_token(parser, &token))
+ return M_ERROR;
- if (token.type == TOK_NL) {
- ins->I_data.rs = MIPS32_REG_ZERO;
- return M_SUCCESS;
- }
+ if (token.type == TOK_NL) {
+ ins->I_data.rs = MIPS32_REG_ZERO;
+ return M_SUCCESS;
+ }
- if (assert_token(parser, TOK_LPAREN, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_LPAREN, NULL))
+ return M_ERROR;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->I_data.rs = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->I_data.rs = reg;
- if (assert_token(parser, TOK_RPAREN, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_RPAREN, NULL))
+ return M_ERROR;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction_sli(struct parser *parser,
- struct mips32_instruction *ins)
+ struct mips32_instruction *ins)
{
- enum mips32_register reg;
- struct token token;
+ enum mips32_register reg;
+ struct token token;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->I_data.rt = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->I_data.rt = reg;
- if (assert_token(parser, TOK_COMMA, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_COMMA, NULL))
+ return M_ERROR;
- if (assert_token(parser, TOK_NUMBER, &token) || token.number > MAX16)
- return M_ERROR;
- ins->I_data.immd = token.number;
+ if (assert_token(parser, TOK_NUMBER, &token) || token.number > MAX16)
+ return M_ERROR;
+ ins->I_data.immd = token.number;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction_s(struct parser *parser,
- struct mips32_instruction *ins)
+ struct mips32_instruction *ins)
{
- enum mips32_register reg;
- struct token token;
+ enum mips32_register reg;
+ struct token token;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->R_data.rd = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->R_data.rd = reg;
- if (assert_token(parser, TOK_COMMA, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_COMMA, NULL))
+ return M_ERROR;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->R_data.rt = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->R_data.rt = reg;
- if (assert_token(parser, TOK_COMMA, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_COMMA, NULL))
+ return M_ERROR;
- if (assert_token(parser, TOK_NUMBER, &token) || token.number > MAX5)
- return M_ERROR;
- ins->R_data.shamt = token.number;
+ if (assert_token(parser, TOK_NUMBER, &token) || token.number > MAX5)
+ return M_ERROR;
+ ins->R_data.shamt = token.number;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction_sv(struct parser *parser,
- struct mips32_instruction *ins)
+ struct mips32_instruction *ins)
{
- enum mips32_register reg;
+ enum mips32_register reg;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->R_data.rd = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->R_data.rd = reg;
- if (assert_token(parser, TOK_COMMA, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_COMMA, NULL))
+ return M_ERROR;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->R_data.rt = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->R_data.rt = reg;
- if (assert_token(parser, TOK_COMMA, NULL))
- return M_ERROR;
+ if (assert_token(parser, TOK_COMMA, NULL))
+ return M_ERROR;
- if (parse_register(parser, &reg))
- return M_ERROR;
- ins->R_data.rs = reg;
+ if (parse_register(parser, &reg))
+ return M_ERROR;
+ ins->R_data.rs = reg;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_instruction(struct parser *parser,
- union mips_instruction *ins,
- struct token ident)
+ union mips_instruction *ins,
+ struct token ident)
{
- struct mips32_instruction instruction;
- enum mips32_parse_format format;
- int res = M_SUCCESS;
+ struct mips32_instruction instruction;
+ enum mips32_parse_format format;
+ int res = M_SUCCESS;
- if (get_instruction(ident.text, &instruction)) {
- ERROR_POS(ident, "unknown instruction '%s'", ident.text);
- return M_ERROR;
- }
+ if (get_instruction(ident.text, &instruction)) {
+ ERROR_POS(ident, "unknown instruction '%s'", ident.text);
+ return M_ERROR;
+ }
- ins->mips32 = instruction;
- format = mips32_parse_formats[instruction.type];
+ ins->mips32 = instruction;
+ format = mips32_parse_formats[instruction.type];
- switch (format) {
- case MIPS32_PARSE_R:
- res = parse_instruction_r(parser, &ins->mips32);
- break;
- case MIPS32_PARSE_R2:
- res = parse_instruction_r2(parser, &ins->mips32);
- break;
- case MIPS32_PARSE_RS:
- res = parse_instruction_rs(parser, &ins->mips32);
- break;
- case MIPS32_PARSE_RD:
- res = parse_instruction_rd(parser, &ins->mips32);
- break;
- case MIPS32_PARSE_I:
- res = parse_instruction_i(parser, &ins->mips32);
- break;
- case MIPS32_PARSE_J:
- res = parse_instruction_j(parser, &ins->mips32);
- break;
- case MIPS32_PARSE_JR:
- res = parse_instruction_jr(parser, &ins->mips32);
- break;
- case MIPS32_PARSE_O16:
- res = parse_instruction_offset(parser, MAX16, &ins->mips32);
- break;
- case MIPS32_PARSE_O26:
- res = parse_instruction_offset(parser, MAX26, &ins->mips32);
- break;
- case MIPS32_PARSE_BE:
- res = parse_instruction_branch_equal(parser, &ins->mips32);
- break;
- case MIPS32_PARSE_BZ:
- res = parse_instruction_branch(parser, &ins->mips32);
- break;
- case MIPS32_PARSE_SL:
- res = parse_instruction_sl(parser, &ins->mips32);
- break;
- case MIPS32_PARSE_SLI:
- res = parse_instruction_sli(parser, &ins->mips32);
- break;
- case MIPS32_PARSE_S:
- res = parse_instruction_s(parser, &ins->mips32);
- break;
- case MIPS32_PARSE_SV:
- res = parse_instruction_sv(parser, &ins->mips32);
- break;
- case MIPS32_PARSE_NONE:
- res = M_SUCCESS;
- break;
- }
+ switch (format) {
+ case MIPS32_PARSE_R:
+ res = parse_instruction_r(parser, &ins->mips32);
+ break;
+ case MIPS32_PARSE_R2:
+ res = parse_instruction_r2(parser, &ins->mips32);
+ break;
+ case MIPS32_PARSE_RS:
+ res = parse_instruction_rs(parser, &ins->mips32);
+ break;
+ case MIPS32_PARSE_RD:
+ res = parse_instruction_rd(parser, &ins->mips32);
+ break;
+ case MIPS32_PARSE_I:
+ res = parse_instruction_i(parser, &ins->mips32);
+ break;
+ case MIPS32_PARSE_J:
+ res = parse_instruction_j(parser, &ins->mips32);
+ break;
+ case MIPS32_PARSE_JR:
+ res = parse_instruction_jr(parser, &ins->mips32);
+ break;
+ case MIPS32_PARSE_O16:
+ res = parse_instruction_offset(parser, MAX16, &ins->mips32);
+ break;
+ case MIPS32_PARSE_O26:
+ res = parse_instruction_offset(parser, MAX26, &ins->mips32);
+ break;
+ case MIPS32_PARSE_BE:
+ res = parse_instruction_branch_equal(parser, &ins->mips32);
+ break;
+ case MIPS32_PARSE_BZ:
+ res = parse_instruction_branch(parser, &ins->mips32);
+ break;
+ case MIPS32_PARSE_SL:
+ res = parse_instruction_sl(parser, &ins->mips32);
+ break;
+ case MIPS32_PARSE_SLI:
+ res = parse_instruction_sli(parser, &ins->mips32);
+ break;
+ case MIPS32_PARSE_S:
+ res = parse_instruction_s(parser, &ins->mips32);
+ break;
+ case MIPS32_PARSE_SV:
+ res = parse_instruction_sv(parser, &ins->mips32);
+ break;
+ case MIPS32_PARSE_NONE:
+ res = M_SUCCESS;
+ break;
+ }
- if (res == M_SUCCESS && assert_eol(parser))
- return M_ERROR;
+ if (res == M_SUCCESS && assert_eol(parser))
+ return M_ERROR;
- return res;
+ return res;
}
static int parse_directive_align(struct parser *parser,
- struct mips32_directive *directive)
+ struct mips32_directive *directive)
{
- struct token token;
- if (assert_token(parser, TOK_NUMBER, &token))
- return M_ERROR;
+ struct token token;
+ if (assert_token(parser, TOK_NUMBER, &token))
+ return M_ERROR;
- if (token.number < 0) {
- ERROR_POS(token, "cannot align negative");
- return M_ERROR;
- }
+ if (token.number < 0) {
+ ERROR_POS(token, "cannot align negative");
+ return M_ERROR;
+ }
- if (token.number > MAX16) {
- ERROR_POS(token, "cannot align more than 65kb");
- return M_ERROR;
- }
+ if (token.number > MAX16) {
+ ERROR_POS(token, "cannot align more than 65kb");
+ return M_ERROR;
+ }
- directive->type = MIPS32_DIRECTIVE_ALIGN;
- directive->align = token.number;
+ directive->type = MIPS32_DIRECTIVE_ALIGN;
+ directive->align = token.number;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_directive_space(struct parser *parser,
- struct mips32_directive *directive)
+ struct mips32_directive *directive)
{
- struct token token;
- if (assert_token(parser, TOK_NUMBER, &token))
- return M_ERROR;
+ struct token token;
+ if (assert_token(parser, TOK_NUMBER, &token))
+ return M_ERROR;
- if (token.number < 0) {
- ERROR_POS(token, "cannot reserve negative");
- return M_ERROR;
- }
+ if (token.number < 0) {
+ ERROR_POS(token, "cannot reserve negative");
+ return M_ERROR;
+ }
- if (token.number > MAX16) {
- ERROR_POS(token, "cannot reserve more than 65kb");
- return M_ERROR;
- }
+ if (token.number > MAX16) {
+ ERROR_POS(token, "cannot reserve more than 65kb");
+ return M_ERROR;
+ }
- directive->type = MIPS32_DIRECTIVE_SPACE;
- directive->space = token.number;
+ directive->type = MIPS32_DIRECTIVE_SPACE;
+ directive->space = token.number;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_directive_whb(struct parser *parser,
- struct mips32_directive *directive,
- enum mips32_directive_type type)
+ struct mips32_directive *directive,
+ enum mips32_directive_type type)
{
- struct token token;
- uint32_t size = 0;
- uint32_t len = 0;
+ struct token token;
+ uint32_t size = 0;
+ uint32_t len = 0;
- switch (type) {
- case MIPS32_DIRECTIVE_WORD:
- size = UINT32_MAX;
- break;
- case MIPS32_DIRECTIVE_HALF:
- size = UINT16_MAX;
- break;
- case MIPS32_DIRECTIVE_BYTE:
- size = UINT8_MAX;
- break;
- default:
- }
+ switch (type) {
+ case MIPS32_DIRECTIVE_WORD:
+ size = UINT32_MAX;
+ break;
+ case MIPS32_DIRECTIVE_HALF:
+ size = UINT16_MAX;
+ break;
+ case MIPS32_DIRECTIVE_BYTE:
+ size = UINT8_MAX;
+ break;
+ default:
+ }
+
+ directive->type = type;
+
+ while (1) {
+ if (assert_token(parser, TOK_NUMBER, &token))
+ return M_ERROR;
+
+ if (len >= MAX_ARG_LENGTH) {
+ ERROR_POS(token, "directives cannot be longer than "
+ "%d arguments", MAX_ARG_LENGTH);
+ return M_ERROR;
+ }
+
+ if (token.number > size) {
+ ERROR_POS(token, "number cannot execede max size of: "
+ "%d", size);
+ return M_ERROR;
+ }
+
+ switch (type) {
+ case MIPS32_DIRECTIVE_WORD:
+ directive->words[len++] = token.number;
- directive->type = type;
+ break;
+ case MIPS32_DIRECTIVE_HALF:
+ directive->halfs[len++] = token.number;
+ break;
+ case MIPS32_DIRECTIVE_BYTE:
+ directive->bytes[len++] = token.number;
+ break;
+ default:
+ }
- while (1) {
- if (assert_token(parser, TOK_NUMBER, &token))
- return M_ERROR;
+ if (peek_token(parser, &token))
+ return M_ERROR;
- if (len >= MAX_ARG_LENGTH) {
- ERROR_POS(token, "directives cannot be longer than "
- "%d arguments", MAX_ARG_LENGTH);
- return M_ERROR;
- }
+ if (token.type == TOK_COMMA) {
+ next_token(parser, NULL);
+ continue;
+ }
- if (token.number > size) {
- ERROR_POS(token, "number cannot execede max size of: "
- "%d", size);
- return M_ERROR;
- }
+ break;
+ }
- switch (type) {
- case MIPS32_DIRECTIVE_WORD:
- directive->words[len++] = token.number;
- break;
- case MIPS32_DIRECTIVE_HALF:
- directive->halfs[len++] = token.number;
- break;
- case MIPS32_DIRECTIVE_BYTE:
- directive->bytes[len++] = token.number;
- break;
- default:
- }
+ directive->len = len;
- if (peek_token(parser, &token))
- return M_ERROR;
+ return M_SUCCESS;
+}
- if (token.type == TOK_COMMA) {
- next_token(parser, NULL);
- continue;
- }
+static int parse_directive_extern(struct parser *parser,
+ struct mips32_directive *directive)
+{
+ struct token token;
+ if (assert_token(parser, TOK_IDENT, &token))
+ return M_ERROR;
- break;
- }
+ directive->type = MIPS32_DIRECTIVE_EXTERN;
+ strcpy(directive->name, token.text);
- return M_SUCCESS;
+ return M_SUCCESS;
}
-static int parse_section(struct parser *parser,
- struct mips32_directive *directive,
- char name[MAX_LEX_LENGTH])
+static int parse_directive_globl(struct parser *parser,
+ struct mips32_directive *directive)
{
- directive->type = MIPS32_DIRECTIVE_SECTION;
- strcpy(directive->name, name);
+ struct token token;
+ if (assert_token(parser, TOK_IDENT, &token))
+ return M_ERROR;
+
+ directive->type = MIPS32_DIRECTIVE_GLOBL;
+ strcpy(directive->name, token.text);
- struct section *sec;
- if (sectbl_get(&parser->sec_tbl, &sec, name) == M_SUCCESS) {
- parser->sec_tbl.current = sec;
- return M_SUCCESS;
- }
+ return M_SUCCESS;
+}
- if (sectbl_alloc(&parser->sec_tbl, &sec, name))
- return M_ERROR;
+static int parse_section(struct mips32_directive *directive,
+ char name[MAX_LEX_LENGTH])
+{
+ directive->type = MIPS32_DIRECTIVE_SECTION;
+ strcpy(directive->name, name);
- parser->sec_tbl.current = sec;
- return M_SUCCESS;
+ return M_SUCCESS;
}
static int parse_directive(struct parser *parser,
- union mips_directive *directive)
+ union mips_directive *directive)
{
- struct token token;
- if (assert_token(parser, TOK_DIRECTIVE, &token))
- return M_ERROR;
+ struct token token;
+ if (assert_token(parser, TOK_DIRECTIVE, &token))
+ return M_ERROR;
- // .align n
- if (strcmp(token.text, "align") == 0)
- return parse_directive_align(parser, &directive->mips32);
- else if (strcmp(token.text, "space") == 0)
- return parse_directive_space(parser, &directive->mips32);
- else if (strcmp(token.text, "word") == 0)
- return parse_directive_whb(parser, &directive->mips32,
- MIPS32_DIRECTIVE_WORD);
- else if (strcmp(token.text, "half") == 0)
- return parse_directive_whb(parser, &directive->mips32,
- MIPS32_DIRECTIVE_HALF);
- else if (strcmp(token.text, "byte") == 0)
- return parse_directive_whb(parser, &directive->mips32,
- MIPS32_DIRECTIVE_BYTE);
- else
- return parse_section(parser, &directive->mips32, token.text);
+ // .align n
+ if (strcmp(token.text, "align") == 0)
+ return parse_directive_align(parser, &directive->mips32);
+ else if (strcmp(token.text, "space") == 0)
+ return parse_directive_space(parser, &directive->mips32);
+ else if (strcmp(token.text, "word") == 0)
+ return parse_directive_whb(parser, &directive->mips32,
+ MIPS32_DIRECTIVE_WORD);
+ else if (strcmp(token.text, "half") == 0)
+ return parse_directive_whb(parser, &directive->mips32,
+ MIPS32_DIRECTIVE_HALF);
+ else if (strcmp(token.text, "byte") == 0)
+ return parse_directive_whb(parser, &directive->mips32,
+ MIPS32_DIRECTIVE_BYTE);
+ else if (strcmp(token.text, "extern") == 0)
+ return parse_directive_extern(parser, &directive->mips32);
+ else if (strcmp(token.text, "globl") == 0)
+ return parse_directive_globl(parser, &directive->mips32);
+ else
+ return parse_section(&directive->mips32, token.text);
}
-int mips32_parser_init(struct lexer *lexer, struct parser *parser)
+void mips32_parser_init(struct parser *parser)
{
- if (parser_init(lexer, parser))
- return M_ERROR;
- parser->parse_instruction = parse_instruction;
- parser->is_instruction = is_instruction;
- parser->parse_directive = parse_directive;
- return M_SUCCESS;
+ parser->parse_instruction = parse_instruction;
+ parser->is_instruction = is_instruction;
+ parser->parse_directive = parse_directive;
}
void mips32_parser_free(struct parser *parser)
{
- parser_free(parser);
+ parser_free(parser);
}