diff options
author | Ian Moffett <ian@osmora.org> | 2025-07-24 03:41:39 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-07-24 03:50:04 -0400 |
commit | af7a0cf9b65d6fee20029fe67c95c494f4b402a7 (patch) | |
tree | bef5ae96cde9bad9cad5f3350a92072f58d594dd /usr.bin/oasm/emit.c | |
parent | 2de38a06acd1f8a392f1c6ea74a7b0aaa0de3692 (diff) |
oasm: Add encoding for MRO type instructions
This commit introduces encoding logic for 4 additional instructions:
- MROB (Mask Register Over [byte])
- MROW (Mask Register Over [word])
- MROD (Mask Register Over [dword])
- MROQ (Mask Register Over [qword])
This instruction is used to fill a register with a specific length of
zeros or ones. For example, to fill a register (e.g., x2) with 16-bits
of 1s:
--
!!
!! Clear bits x2[7:0]... Mrrp,,
!! mrow!!
!!
mrow x2, #1
--
Similarly, an operand of zero sets it to zero. For example, to clear an
entire 64-bit register with zeros. Something like this can be done:
--
mroq x1, #0
--
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'usr.bin/oasm/emit.c')
-rw-r--r-- | usr.bin/oasm/emit.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/usr.bin/oasm/emit.c b/usr.bin/oasm/emit.c index eb38779..3261522 100644 --- a/usr.bin/oasm/emit.c +++ b/usr.bin/oasm/emit.c @@ -296,6 +296,67 @@ emit_encode_br(struct emit_state *state, struct oasm_token *tok) return TAILQ_NEXT(tok, link); } +/* + * Encode the MRO type instructions + * + * mrob x1[7:0] + * mrow x1[15:0] ! Mrowwww :3333 + * mrod x1[31:0] + * mroq x[63:0] + * + * Returns the next token on success, + * otherwise NULL. + */ +static struct oasm_token * +emit_encode_mro(struct emit_state *state, struct oasm_token *tok) +{ + inst_t curinst; + reg_t rd; + uint8_t opcode = OSMX64_MROB; + char *inst_str = "mrob"; + + switch (tok->type) { + case TT_MROW: + opcode = OSMX64_MROW; + inst_str = "mrow"; + break; + case TT_MROD: + opcode = OSMX64_MROD; + inst_str = "mrod"; + break; + case TT_MROQ: + opcode = OSMX64_MROQ; + inst_str = "mroq"; + break; + } + + /* Next token should be a register */ + tok = TAILQ_NEXT(tok, link); + if (!tok_is_xreg(tok->type)) { + oasm_err("[emit error]: expected register in '%s'\n", inst_str); + return NULL; + } + + rd = ir_to_reg(tok->type); + if (rd == OSMX64_R_BAD) { + oasm_err("[emit error]: got bad register in '%s'\n", inst_str); + return NULL; + } + + /* Next token should be an IMM */ + tok = TAILQ_NEXT(tok, link); + if (tok->type != TT_IMM) { + oasm_err("[emit error]: expected <imm> after reg in '%s'\n", inst_str); + return NULL; + } + + curinst.opcode = opcode; + curinst.rd = rd; + curinst.imm = tok->imm; + emit_bytes(state, &curinst, sizeof(curinst)); + return TAILQ_NEXT(tok, link); +} + int emit_osmx64(struct emit_state *state, struct oasm_token *tp) { @@ -387,6 +448,10 @@ emit_process(struct oasm_state *oasm, struct emit_state *emit) curtok = emit_encode_hlt(emit, curtok); break; default: + if (lex_is_mro(curtok->type)) { + curtok = emit_encode_mro(emit, curtok); + break; + } curtok = TAILQ_NEXT(curtok, link); break; } |