diff options
author | Ian Moffett <ian@osmora.org> | 2025-07-27 22:59:18 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-07-28 03:30:58 -0400 |
commit | a4a7080dee359ca95f09d91d68d1d8c4a1f59cd6 (patch) | |
tree | ea3a16a62d1c2bd4426273f8e28907f20c6e69ff /usr.bin | |
parent | 6b3c37f5bc9dbd3656ee08b925f2df2d233084fe (diff) |
oasm: Introduce AND mnemonic
Implement mnemonic for the AND instruction:
--
and x1, #7 ! x1 = x1 & 7
--
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/oasm/emit.c | 57 | ||||
-rw-r--r-- | usr.bin/oasm/include/oasm/lex.h | 1 | ||||
-rw-r--r-- | usr.bin/oasm/lex.c | 3 | ||||
-rw-r--r-- | usr.bin/oasm/parse.c | 7 |
4 files changed, 67 insertions, 1 deletions
diff --git a/usr.bin/oasm/emit.c b/usr.bin/oasm/emit.c index 6b17eab..ea14cce 100644 --- a/usr.bin/oasm/emit.c +++ b/usr.bin/oasm/emit.c @@ -377,6 +377,60 @@ emit_encode_nop(struct emit_state *state, struct oasm_token *tok) return TAILQ_NEXT(tok, link); } +/* + * Encode a bitwise instruction: + * + * and r, r/imm + * or r, r/imm + * xor r, r/imm + */ +static struct oasm_token * +emit_encode_bitw(struct emit_state *state, struct oasm_token *tok) +{ + inst_t curinst; + imm_t imm; + reg_t rd; + uint8_t opcode = OSMX64_AND; + char *inst_str = "and"; + + /* Next token should be a register */ + tok = TAILQ_NEXT(tok, link); + if (tok == NULL) { + oasm_err("[emit error]: expected register for '%s'\n", inst_str); + return NULL; + } + if (!tok_is_xreg(tok->type)) { + oasm_err("[emit error]: bad register for '%s'\n", inst_str); + return NULL; + } + + rd = ir_to_reg(tok->type); + tok = TAILQ_NEXT(tok, link); + if (tok == NULL) { + oasm_err("[emit error]: missing operand in '%s'\n", inst_str); + return NULL; + } + + /* + * Check that the next token is an immediate + * value. + * + * TODO: Allow a register operand to be passed + * to these instructions. + */ + if (tok->type != TT_IMM) { + oasm_err("[emit error]: expected <imm> for '%s'\n", inst_str); + return NULL; + } + + imm = tok->imm; + curinst.opcode = opcode; + curinst.rd = rd; + curinst.imm = imm; + emit_bytes(state, &curinst, sizeof(curinst)); + return TAILQ_NEXT(tok, link); +} + int emit_osmx64(struct emit_state *state, struct oasm_token *tp) { @@ -464,6 +518,9 @@ emit_process(struct oasm_state *oasm, struct emit_state *emit) case TT_DIV: curtok = emit_encode_arith(emit, curtok); break; + case TT_AND: + curtok = emit_encode_bitw(emit, curtok); + break; case TT_BR: curtok = emit_encode_br(emit, curtok); break; diff --git a/usr.bin/oasm/include/oasm/lex.h b/usr.bin/oasm/include/oasm/lex.h index 873f6b9..69e98ff 100644 --- a/usr.bin/oasm/include/oasm/lex.h +++ b/usr.bin/oasm/include/oasm/lex.h @@ -103,6 +103,7 @@ typedef enum { TT_MROW, /* 'mrow' */ TT_MROD, /* 'mrod' */ TT_MROQ, /* 'mroq' */ + TT_AND, /* 'and' */ /* Register ops */ TT_MOV, /* 'mov' */ diff --git a/usr.bin/oasm/lex.c b/usr.bin/oasm/lex.c index fea9dc3..220cdb4 100644 --- a/usr.bin/oasm/lex.c +++ b/usr.bin/oasm/lex.c @@ -54,6 +54,7 @@ static char putback = '\0'; #define S_IMN_MROW "mrow" #define S_IMN_MROD "mrod" #define S_IMN_MROQ "mroq" +#define S_IMN_AND "and" /* Instruction length */ #define OSMX64_INST_LEN 4 @@ -242,6 +243,8 @@ token_bitw_mro(char *p) return TT_MROD; } else if (strcmp(p, S_IMN_MROQ) == 0) { return TT_MROQ; + } else if (strcmp(p, S_IMN_AND) == 0) { + return TT_AND; } return TT_UNKNOWN; diff --git a/usr.bin/oasm/parse.c b/usr.bin/oasm/parse.c index c81b498..523058b 100644 --- a/usr.bin/oasm/parse.c +++ b/usr.bin/oasm/parse.c @@ -58,7 +58,7 @@ static const char *tokstr[] = { [ TT_MROW ] = "mrow", [ TT_MROD ] = "mrod", [ TT_MROQ ] = "mroq", - + [ TT_AND ] = "and", /* X<n> registers */ [ TT_X0 ] = "x0", @@ -124,6 +124,7 @@ parse_reg(struct oasm_state *state, struct oasm_token *tok) case TT_MUL: case TT_DIV: case TT_BR: + case TT_AND: state->last = tok->type; break; default: @@ -166,6 +167,10 @@ parse_tok(struct oasm_state *state, struct oasm_token *tok) state->last = tok->type; label_enter(tok->raw, state->pip); break; + case TT_AND: + state->last = tok->type; + emit_osmx64(&emit_state, tok); + break; case TT_HLT: state->last = tok->type; emit_osmx64(&emit_state, tok); |