diff options
Diffstat (limited to 'usr.bin/oasm/parse.c')
-rw-r--r-- | usr.bin/oasm/parse.c | 72 |
1 files changed, 61 insertions, 11 deletions
diff --git a/usr.bin/oasm/parse.c b/usr.bin/oasm/parse.c index 7a855ca..229455b 100644 --- a/usr.bin/oasm/parse.c +++ b/usr.bin/oasm/parse.c @@ -34,6 +34,7 @@ #include <oasm/lex.h> #include <oasm/parse.h> #include <oasm/log.h> +#include <oasm/label.h> static struct emit_state emit_state; static const char *tokstr[] = { @@ -42,11 +43,21 @@ static const char *tokstr[] = { [ TT_SUB ] = "sub", [ TT_MUL ] = "mul", [ TT_DIV ] = "div", + [ TT_HLT ] = "hlt", + [ TT_BR ] = "br", [ TT_COMMA ] = ",", [ TT_INC ] = "inc", [ TT_DEC ] = "dec", [ TT_MOV ] = "mov", [ TT_IMM ] = "<imm>", + [ TT_LABEL] = "<label>", + + /* Bitwise */ + [ TT_MROB ] = "mrob", + [ TT_MROW ] = "mrow", + [ TT_MROD ] = "mrod", + [ TT_MROQ ] = "mroq", + /* X<n> registers */ [ TT_X0 ] = "x0", @@ -107,9 +118,19 @@ parse_reg(struct oasm_state *state, struct oasm_token *tok) case TT_MOV: case TT_DEC: case TT_INC: + case TT_ADD: + case TT_SUB: + case TT_MUL: + case TT_DIV: + case TT_BR: state->last = tok->type; break; default: + if (lex_is_mro(state->last)) { + state->last = tok->type; + break; + } + p = tokstr[state->last]; oasm_err("bad instruction '%s' for regop\n", p); return -1; @@ -122,13 +143,7 @@ parse_reg(struct oasm_state *state, struct oasm_token *tok) } state->last = tok->type; - emit_osxm64(&emit_state, tok); - return 0; -} - -static int -parse_imm(struct oasm_token *tok, tt_t last) -{ + emit_osmx64(&emit_state, tok); return 0; } @@ -139,24 +154,58 @@ parse_tok(struct oasm_state *state, struct oasm_token *tok) int error; switch (tok->type) { + case TT_BR: + state->last = tok->type; + emit_osmx64(&emit_state, tok); + break; + case TT_LABEL: + state->last = tok->type; + label_enter(tok->raw, state->pip); + break; + case TT_HLT: + state->last = tok->type; + emit_osmx64(&emit_state, tok); + break; + case TT_MUL: + state->last = tok->type; + emit_osmx64(&emit_state, tok); + break; + case TT_DIV: + state->last = tok->type; + emit_osmx64(&emit_state, tok); + break; case TT_MOV: state->last = tok->type; - emit_osxm64(&emit_state, tok); + emit_osmx64(&emit_state, tok); + break; + case TT_ADD: + state->last = tok->type; + emit_osmx64(&emit_state, tok); + break; + case TT_SUB: + state->last = tok->type; + emit_osmx64(&emit_state, tok); break; case TT_DEC: case TT_INC: state->last = tok->type; - emit_osxm64(&emit_state, tok); + emit_osmx64(&emit_state, tok); break; case TT_IMM: p = tokstr[state->last]; if (!tok_is_xreg(state->last)) { - printf("expected X<n> but got %s\n", p); + oasm_err("expected X<n> but got %s\n", p); return -1; } - emit_osxm64(&emit_state, tok); + emit_osmx64(&emit_state, tok); break; default: + if (lex_is_mro(tok->type)) { + state->last = tok->type; + emit_osmx64(&emit_state, tok); + return 0; + } + if (!tok->is_reg) { oasm_err("syntax error\n"); return -1; @@ -199,4 +248,5 @@ parse_enter(struct oasm_state *state) /* Process then destroy the emit state */ emit_process(state, &emit_state); emit_destroy(&emit_state); + labels_destroy(); } |