fix store/load with labels

This commit is contained in:
Murphy 2024-09-13 20:15:56 -04:00
parent df4a225ccf
commit 3e6b94ac2f
Signed by: freya
GPG key ID: 744AB800E383AE52
2 changed files with 50 additions and 15 deletions

View file

@ -262,8 +262,6 @@ static int handle_ins(struct assembler *assembler,
if (reltab_push(&sec->reltab, rel))
return M_ERROR;
break;
}
return M_SUCCESS;

View file

@ -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);