fix store/load with labels
This commit is contained in:
parent
df4a225ccf
commit
3e6b94ac2f
2 changed files with 50 additions and 15 deletions
|
@ -262,8 +262,6 @@ static int handle_ins(struct assembler *assembler,
|
||||||
|
|
||||||
if (reltab_push(&sec->reltab, rel))
|
if (reltab_push(&sec->reltab, rel))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
|
|
63
masm/parse.c
63
masm/parse.c
|
@ -411,34 +411,71 @@ static int parse_register(struct parser *parser, enum mips_register *reg)
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_reg_offset(struct parser *parser, struct mips_instruction *ins,
|
static int get_reg_offset(struct parser *parser,
|
||||||
struct reference *ref)
|
struct ins_expr *expr)
|
||||||
{
|
{
|
||||||
struct token token;
|
struct token token;
|
||||||
enum mips_register reg;
|
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
|
// defaults
|
||||||
ins->data.rs = MIPS_REG_ZERO;
|
fi->data.rs = MIPS_REG_ZERO;
|
||||||
ins->data.immd = 0;
|
fi->data.immd = 0;
|
||||||
|
|
||||||
if (peek_token(parser, &token))
|
if (peek_token(parser, &token))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
if (token.type == TOK_LPAREN)
|
if (token.type == TOK_IDENT)
|
||||||
|
goto label;
|
||||||
|
else if (token.type == TOK_LPAREN)
|
||||||
goto reg;
|
goto reg;
|
||||||
else
|
else
|
||||||
goto off;
|
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:
|
off:
|
||||||
|
|
||||||
uint64_t immd;
|
if (assert_token(parser, TOK_NUMBER, &token))
|
||||||
if (get_reference(parser, &immd, ref, R_MIPS_16))
|
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->data.offset = htons(immd);
|
fi->data.offset = htons(token.number);
|
||||||
|
|
||||||
if (peek_token(parser, &token))
|
if (peek_token(parser, &token))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
@ -456,7 +493,7 @@ reg:
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->data.rs = reg;
|
fi->data.rs = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_RPAREN, NULL))
|
if (assert_token(parser, TOK_RPAREN, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
@ -672,10 +709,10 @@ static int parse_instruction_branch(struct parser *parser,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_instruction_sl(struct parser *parser,
|
static int parse_instruction_sl(struct parser *parser,
|
||||||
struct mips_instruction *ins,
|
struct ins_expr *expr)
|
||||||
struct reference *ref)
|
|
||||||
{
|
{
|
||||||
enum mips_register reg;
|
enum mips_register reg;
|
||||||
|
struct mips_instruction *ins = &expr->ins[0];
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
@ -684,7 +721,7 @@ static int parse_instruction_sl(struct parser *parser,
|
||||||
if (assert_token(parser, TOK_COMMA, NULL))
|
if (assert_token(parser, TOK_COMMA, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
if (get_reg_offset(parser, ins, ref))
|
if (get_reg_offset(parser, expr))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
|
@ -946,7 +983,7 @@ static int parse_instruction(struct parser *parser,
|
||||||
res = parse_instruction_branch(parser, ins, ref);
|
res = parse_instruction_branch(parser, ins, ref);
|
||||||
break;
|
break;
|
||||||
case MIPS_PARSE_SL:
|
case MIPS_PARSE_SL:
|
||||||
res = parse_instruction_sl(parser, ins, ref);
|
res = parse_instruction_sl(parser, expr);
|
||||||
break;
|
break;
|
||||||
case MIPS_PARSE_SLI:
|
case MIPS_PARSE_SLI:
|
||||||
res = parse_instruction_sli(parser, ins);
|
res = parse_instruction_sli(parser, ins);
|
||||||
|
|
Loading…
Reference in a new issue