diff options
Diffstat (limited to 'usr.bin/oasm/lex.c')
-rw-r--r-- | usr.bin/oasm/lex.c | 85 |
1 files changed, 82 insertions, 3 deletions
diff --git a/usr.bin/oasm/lex.c b/usr.bin/oasm/lex.c index a33a570..fea9dc3 100644 --- a/usr.bin/oasm/lex.c +++ b/usr.bin/oasm/lex.c @@ -40,6 +40,7 @@ static char putback = '\0'; /* Instruction mnemonic strings */ +#define S_IMN_NOP "nop" #define S_IMN_MOV "mov" #define S_IMN_ADD "add" #define S_IMN_SUB "sub" @@ -49,6 +50,24 @@ static char putback = '\0'; #define S_IMN_DEC "dec" #define S_IMN_HLT "hlt" #define S_IMN_BR "br" +#define S_IMN_MROB "mrob" +#define S_IMN_MROW "mrow" +#define S_IMN_MROD "mrod" +#define S_IMN_MROQ "mroq" + +/* Instruction length */ +#define OSMX64_INST_LEN 4 + +/* + * Update the state when the caller encounters + * a newline. + */ +static inline void +lex_newline(struct oasm_state *state) +{ + ++state->line; + state->pip += OSMX64_INST_LEN; +} /* * Returns 0 if a char is counted as a @@ -63,7 +82,7 @@ lex_skippable(struct oasm_state *state, char c) case '\t': return 0; case '\r': return 0; case '\n': - ++state->line; + lex_newline(state); return 0; } @@ -154,6 +173,10 @@ lex_nomstr(struct oasm_state *state, char **res) retval = tmp; break; } + if (tmp == ':') { + retval = tmp; + break; + } if (tmp == '\n') { ++state->line; retval = tmp; @@ -205,6 +228,41 @@ token_cfi(char *p) return TT_UNKNOWN; } +/* + * Bitwise MRO instructions + */ +static tt_t +token_bitw_mro(char *p) +{ + if (strcmp(p, S_IMN_MROB) == 0) { + return TT_MROB; + } else if (strcmp(p, S_IMN_MROW) == 0) { + return TT_MROW; + } else if (strcmp(p, S_IMN_MROD) == 0) { + return TT_MROD; + } else if (strcmp(p, S_IMN_MROQ) == 0) { + return TT_MROQ; + } + + return TT_UNKNOWN; +} + +/* + * Bitwise instructions + */ +static tt_t +token_bitw(char *p) +{ + tt_t token; + + token = token_bitw_mro(p); + if (token != TT_UNKNOWN) { + return token; + } + + return TT_UNKNOWN; +} + static tt_t token_xreg(char *p) { @@ -295,7 +353,7 @@ lex_tok(struct oasm_state *state, struct oasm_token *ttp) switch (c) { case '\n': - ++state->line; + lex_newline(state); return 0; case '\0': return -1; @@ -306,7 +364,21 @@ lex_tok(struct oasm_state *state, struct oasm_token *ttp) ttp->raw = NULL; lex_putback(c); - lex_nomstr(state, &p); + c = lex_nomstr(state, &p); + + while (c == ':') { + ttp->type = TT_LABEL; + ttp->raw = p; + state->label_ip = state->pip; + return 0; + } + + /* No operation? */ + if (strcmp(p, S_IMN_NOP) == 0) { + ttp->type = TT_NOP; + ttp->raw = p; + return 0; + } /* Arithmetic operation? */ if ((tok = token_arith(p)) != TT_UNKNOWN) { @@ -330,6 +402,12 @@ lex_tok(struct oasm_state *state, struct oasm_token *ttp) return 0; } + if ((tok = token_bitw(p)) != TT_UNKNOWN) { + ttp->type = tok; + ttp->raw = p; + return 0; + } + /* Immediate operand? */ if ((tok = token_operand(p)) != TT_UNKNOWN) { if (tok == TT_IMM) { @@ -340,6 +418,7 @@ lex_tok(struct oasm_state *state, struct oasm_token *ttp) ttp->raw = p; return 0; } + oasm_err("bad token \"%s\"\n", p); lex_try_free(p); return -1; |