summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--masm/asm.c2
-rw-r--r--masm/parse.c63
2 files changed, 50 insertions, 15 deletions
diff --git a/masm/asm.c b/masm/asm.c
index fb8d12c..0f07079 100644
--- a/masm/asm.c
+++ b/masm/asm.c
@@ -262,8 +262,6 @@ static int handle_ins(struct assembler *assembler,
if (reltab_push(&sec->reltab, rel))
return M_ERROR;
-
- break;
}
return M_SUCCESS;
diff --git a/masm/parse.c b/masm/parse.c
index 221ef6d..6c817d4 100644
--- a/masm/parse.c
+++ b/masm/parse.c
@@ -411,34 +411,71 @@ 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)
+static int get_reg_offset(struct parser *parser,
+ struct ins_expr *expr)
{
struct token token;
enum mips_register reg;
+ struct mips_instruction *fi = &expr->ins[0];
+ struct mips_instruction *si = &expr->ins[1]; // possibly pseudo
+ struct reference *fr = &expr->ref[0];
+ struct reference *sr = &expr->ref[1];
+
+ expr->ins_len = 1;
+ fr->type = R_MIPS_NONE;
+
// =============================================
// defaults
- ins->data.rs = MIPS_REG_ZERO;
- ins->data.immd = 0;
+ fi->data.rs = MIPS_REG_ZERO;
+ fi->data.immd = 0;
if (peek_token(parser, &token))
return M_ERROR;
- if (token.type == TOK_LPAREN)
+ if (token.type == TOK_IDENT)
+ goto label;
+ else if (token.type == TOK_LPAREN)
goto reg;
else
goto off;
// =============================================
+label:
+
+ next_token(parser, &token);
+
+ expr->ins_len = 2;
+
+ // move over first instruction to add in a LUI
+ *si = *fi;
+ si->data.rs = MIPS_REG_AT;
+ si->data.offset = 0;
+
+ // update LUI
+ *fi = mips_instructions[MIPS_INS_LUI];
+ fi->data.rt = MIPS_REG_AT;
+ fi->data.immd = 0;
+
+ // update references
+ strcpy(fr->name, token.text);
+ fr->type = R_MIPS_HI16;
+ fr->addend = 0;
+ strcpy(sr->name, token.text);
+ sr->type = R_MIPS_LO16;
+ sr->addend = 0;
+
+ goto end;
+
+// =============================================
+
off:
- uint64_t immd;
- if (get_reference(parser, &immd, ref, R_MIPS_16))
+ if (assert_token(parser, TOK_NUMBER, &token))
return M_ERROR;
- ins->data.offset = htons(immd);
+ fi->data.offset = htons(token.number);
if (peek_token(parser, &token))
return M_ERROR;
@@ -456,7 +493,7 @@ reg:
if (parse_register(parser, &reg))
return M_ERROR;
- ins->data.rs = reg;
+ fi->data.rs = reg;
if (assert_token(parser, TOK_RPAREN, NULL))
return M_ERROR;
@@ -672,10 +709,10 @@ static int parse_instruction_branch(struct parser *parser,
}
static int parse_instruction_sl(struct parser *parser,
- struct mips_instruction *ins,
- struct reference *ref)
+ struct ins_expr *expr)
{
enum mips_register reg;
+ struct mips_instruction *ins = &expr->ins[0];
if (parse_register(parser, &reg))
return M_ERROR;
@@ -684,7 +721,7 @@ static int parse_instruction_sl(struct parser *parser,
if (assert_token(parser, TOK_COMMA, NULL))
return M_ERROR;
- if (get_reg_offset(parser, ins, ref))
+ if (get_reg_offset(parser, expr))
return M_ERROR;
return M_SUCCESS;
@@ -946,7 +983,7 @@ static int parse_instruction(struct parser *parser,
res = parse_instruction_branch(parser, ins, ref);
break;
case MIPS_PARSE_SL:
- res = parse_instruction_sl(parser, ins, ref);
+ res = parse_instruction_sl(parser, expr);
break;
case MIPS_PARSE_SLI:
res = parse_instruction_sli(parser, ins);