diff options
author | Ian Moffett <ian@osmora.org> | 2025-07-21 04:12:43 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-07-21 04:12:43 -0400 |
commit | f5d7accdd042a56ccdc6b74c6c3f24a023bb100a (patch) | |
tree | b87d6892f269517c0f413a0923a018c8e05252d8 | |
parent | 7a5087952b4074e4a6665f850f1fa103fba1f4e8 (diff) |
oasm: emit: Handle increment/decrement operations
Implement the initial encoding logic for INC/DEC instructions.
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r-- | usr.bin/oasm/emit.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/usr.bin/oasm/emit.c b/usr.bin/oasm/emit.c index 9a8b1ee..4bad76b 100644 --- a/usr.bin/oasm/emit.c +++ b/usr.bin/oasm/emit.c @@ -122,6 +122,54 @@ emit_encode_mov(struct emit_state *state, struct oasm_token *tok) return TAILQ_NEXT(tok, link); } +/* + * Encode a INC/DEC instruction + * + * inc/dec [r] + * + * Returns the next token on success, + * otherwise NULL. + */ +static struct oasm_token * +emit_encode_incdec(struct emit_state *state, struct oasm_token *tok) +{ + inst_t curinst; + reg_t rd; + uint8_t opcode = OSMX64_INC; + char *inst_str = "inc"; + + if (state == NULL || tok == NULL) { + return NULL; + } + + if (tok->type == TT_DEC) { + inst_str = "dec"; + opcode = OSMX64_DEC; + } + + /* Next token should be a register */ + tok = TAILQ_NEXT(tok, link); + if (tok == NULL) { + return NULL; + } + if (!tok_is_xreg(tok->type)) { + oasm_err("[emit error]: bad '%s' order\n", inst_str); + return NULL; + } + + rd = ir_to_reg(tok->type); + if (rd == OSMX64_R_BAD) { + oasm_err("[emit error]: got bad reg in '%s'\n", inst_str); + return NULL; + } + + curinst.opcode = opcode; + curinst.rd = rd; + curinst.unused = 0; + emit_bytes(state, &curinst, sizeof(curinst)); + return TAILQ_NEXT(tok, link); +} + int emit_osxm64(struct emit_state *state, struct oasm_token *tp) { @@ -196,6 +244,10 @@ emit_process(struct oasm_state *oasm, struct emit_state *emit) case TT_MOV: curtok = emit_encode_mov(emit, curtok); break; + case TT_INC: + case TT_DEC: + curtok = emit_encode_incdec(emit, curtok); + break; default: curtok = TAILQ_NEXT(curtok, link); break; |