diff options
author | Ian Moffett <ian@osmora.org> | 2025-07-21 09:00:41 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-07-21 09:00:41 -0400 |
commit | 348697548884b8f1943fe4545df7f34adb79b0ae (patch) | |
tree | 39a3f624fa9980891d6e3e6655757876b898bdf4 | |
parent | ceebacd4e665b3792b05eca2c3e91be4e3c86f64 (diff) |
oasm: Implement encoding for 'ADD' instruction
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r-- | usr.bin/oasm/emit.c | 54 | ||||
-rw-r--r-- | usr.bin/oasm/parse.c | 5 |
2 files changed, 59 insertions, 0 deletions
diff --git a/usr.bin/oasm/emit.c b/usr.bin/oasm/emit.c index 4783afd..ee13582 100644 --- a/usr.bin/oasm/emit.c +++ b/usr.bin/oasm/emit.c @@ -169,6 +169,57 @@ emit_encode_incdec(struct emit_state *state, struct oasm_token *tok) return TAILQ_NEXT(tok, link); } +/* + * Encode an ADD instruction + * + * add [r], <imm> + * + * Returns the next token on success, + * otherwise NULL. + */ +static struct oasm_token * +emit_encode_add(struct emit_state *state, struct oasm_token *tok) +{ + inst_t curinst; + reg_t rd; + + /* + * The next operand must be an X<n> + * register. + */ + tok = TAILQ_NEXT(tok, link); + if (tok == NULL) { + return NULL; + } + if (!tok_is_xreg(tok->type)) { + oasm_err("[emit error]: bad 'add' order\n"); + return NULL; + } + + /* Get the register and validate it */ + rd = ir_to_reg(tok->type); + if (rd == OSMX64_R_BAD) { + oasm_err("[emit error]: got bad reg in 'add'\n"); + return NULL; + } + + /* The next token should be an <imm> */ + tok = TAILQ_NEXT(tok, link); + if (tok == NULL) { + return NULL; + } + if (tok->type != TT_IMM) { + oasm_err("[emit error]: expected <imm> in 'add'\n"); + return NULL; + } + + curinst.opcode = OSMX64_ADD; + curinst.rd = rd; + curinst.imm = tok->imm; + emit_bytes(state, &curinst, sizeof(curinst)); + return TAILQ_NEXT(tok, link); +} + int emit_osxm64(struct emit_state *state, struct oasm_token *tp) { @@ -247,6 +298,9 @@ emit_process(struct oasm_state *oasm, struct emit_state *emit) case TT_DEC: curtok = emit_encode_incdec(emit, curtok); break; + case TT_ADD: + curtok = emit_encode_add(emit, curtok); + break; default: curtok = TAILQ_NEXT(curtok, link); break; diff --git a/usr.bin/oasm/parse.c b/usr.bin/oasm/parse.c index 7a855ca..f87f903 100644 --- a/usr.bin/oasm/parse.c +++ b/usr.bin/oasm/parse.c @@ -107,6 +107,7 @@ parse_reg(struct oasm_state *state, struct oasm_token *tok) case TT_MOV: case TT_DEC: case TT_INC: + case TT_ADD: state->last = tok->type; break; default: @@ -143,6 +144,10 @@ parse_tok(struct oasm_state *state, struct oasm_token *tok) state->last = tok->type; emit_osxm64(&emit_state, tok); break; + case TT_ADD: + state->last = tok->type; + emit_osxm64(&emit_state, tok); + break; case TT_DEC: case TT_INC: state->last = tok->type; |