diff options
Diffstat (limited to 'usr.bin/oasm')
-rw-r--r-- | usr.bin/oasm/emit.c | 36 | ||||
-rw-r--r-- | usr.bin/oasm/include/oasm/emit.h | 2 | ||||
-rw-r--r-- | usr.bin/oasm/lex.c | 3 | ||||
-rw-r--r-- | usr.bin/oasm/parse.c | 28 |
4 files changed, 54 insertions, 15 deletions
diff --git a/usr.bin/oasm/emit.c b/usr.bin/oasm/emit.c index cef90d7..0e8ad4e 100644 --- a/usr.bin/oasm/emit.c +++ b/usr.bin/oasm/emit.c @@ -170,7 +170,7 @@ emit_encode_incdec(struct emit_state *state, struct oasm_token *tok) } /* - * Encode an ADD instruction + * Encode an arithmetic instruction * * add [r], <imm> * @@ -178,10 +178,27 @@ emit_encode_incdec(struct emit_state *state, struct oasm_token *tok) * otherwise NULL. */ static struct oasm_token * -emit_encode_add(struct emit_state *state, struct oasm_token *tok) +emit_encode_arith(struct emit_state *state, struct oasm_token *tok) { inst_t curinst; reg_t rd; + uint8_t opcode = OSMX64_ADD; + char *inst_str = "add"; + + switch (tok->type) { + case TT_SUB: + inst_str = "sub"; + opcode = OSMX64_SUB; + break; + case TT_MUL: + inst_str = "mul"; + opcode = OSMX64_MUL; + break; + case TT_DIV: + inst_str = "div"; + opcode = OSMX64_DIV; + break; + } /* * The next operand must be an X<n> @@ -192,14 +209,14 @@ emit_encode_add(struct emit_state *state, struct oasm_token *tok) return NULL; } if (!tok_is_xreg(tok->type)) { - oasm_err("[emit error]: bad 'add' order\n"); + oasm_err("[emit error]: bad '%s' order\n", inst_str); 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"); + oasm_err("[emit error]: got bad reg in '%s'\n", inst_str); return NULL; } @@ -209,11 +226,11 @@ emit_encode_add(struct emit_state *state, struct oasm_token *tok) return NULL; } if (tok->type != TT_IMM) { - oasm_err("[emit error]: expected <imm> in 'add'\n"); + oasm_err("[emit error]: expected <imm> in '%s'\n", inst_str); return NULL; } - curinst.opcode = OSMX64_ADD; + curinst.opcode = opcode; curinst.rd = rd; curinst.imm = tok->imm; emit_bytes(state, &curinst, sizeof(curinst)); @@ -241,7 +258,7 @@ emit_encode_hlt(struct emit_state *state, struct oasm_token *tok) } int -emit_osxm64(struct emit_state *state, struct oasm_token *tp) +emit_osmx64(struct emit_state *state, struct oasm_token *tp) { struct oasm_token *toknew; @@ -319,7 +336,10 @@ emit_process(struct oasm_state *oasm, struct emit_state *emit) curtok = emit_encode_incdec(emit, curtok); break; case TT_ADD: - curtok = emit_encode_add(emit, curtok); + case TT_SUB: + case TT_MUL: + case TT_DIV: + curtok = emit_encode_arith(emit, curtok); break; case TT_HLT: curtok = emit_encode_hlt(emit, curtok); diff --git a/usr.bin/oasm/include/oasm/emit.h b/usr.bin/oasm/include/oasm/emit.h index b0a2fd1..d289adb 100644 --- a/usr.bin/oasm/include/oasm/emit.h +++ b/usr.bin/oasm/include/oasm/emit.h @@ -108,6 +108,6 @@ struct emit_state { int emit_init(struct emit_state *state); int emit_destroy(struct emit_state *state); int emit_process(struct oasm_state *oasm, struct emit_state *emit); -int emit_osxm64(struct emit_state *state, struct oasm_token *tp); +int emit_osmx64(struct emit_state *state, struct oasm_token *tp); #endif /* !_EMIT_H_ */ diff --git a/usr.bin/oasm/lex.c b/usr.bin/oasm/lex.c index b3af2b1..7b78d54 100644 --- a/usr.bin/oasm/lex.c +++ b/usr.bin/oasm/lex.c @@ -42,6 +42,7 @@ static char putback = '\0'; #define S_IMN_MOV "mov" #define S_IMN_ADD "add" #define S_IMN_SUB "sub" +#define S_IMN_MUL "mul" #define S_IMN_DIV "div" #define S_IMN_INC "inc" #define S_IMN_DEC "dec" @@ -182,6 +183,8 @@ token_arith(char *p) return TT_DIV; } else if (strcmp(p, S_IMN_HLT) == 0) { return TT_HLT; + } else if (strcmp(p, S_IMN_MUL) == 0) { + return TT_MUL; } return TT_UNKNOWN; diff --git a/usr.bin/oasm/parse.c b/usr.bin/oasm/parse.c index 6851935..9a4dd0e 100644 --- a/usr.bin/oasm/parse.c +++ b/usr.bin/oasm/parse.c @@ -109,6 +109,9 @@ parse_reg(struct oasm_state *state, struct oasm_token *tok) case TT_DEC: case TT_INC: case TT_ADD: + case TT_SUB: + case TT_MUL: + case TT_DIV: state->last = tok->type; break; default: @@ -124,7 +127,7 @@ parse_reg(struct oasm_state *state, struct oasm_token *tok) } state->last = tok->type; - emit_osxm64(&emit_state, tok); + emit_osmx64(&emit_state, tok); return 0; } @@ -143,19 +146,32 @@ parse_tok(struct oasm_state *state, struct oasm_token *tok) switch (tok->type) { case TT_HLT: state->last = tok->type; - emit_osxm64(&emit_state, tok); + emit_osmx64(&emit_state, tok); + break; + case TT_MUL: + state->last = tok->type; + emit_osmx64(&emit_state, tok); + break; + case TT_DIV: + state->last = tok->type; + emit_osmx64(&emit_state, tok); + break; case TT_MOV: state->last = tok->type; - emit_osxm64(&emit_state, tok); + emit_osmx64(&emit_state, tok); break; case TT_ADD: state->last = tok->type; - emit_osxm64(&emit_state, tok); + emit_osmx64(&emit_state, tok); + break; + case TT_SUB: + state->last = tok->type; + emit_osmx64(&emit_state, tok); break; case TT_DEC: case TT_INC: state->last = tok->type; - emit_osxm64(&emit_state, tok); + emit_osmx64(&emit_state, tok); break; case TT_IMM: p = tokstr[state->last]; @@ -163,7 +179,7 @@ parse_tok(struct oasm_state *state, struct oasm_token *tok) printf("expected X<n> but got %s\n", p); return -1; } - emit_osxm64(&emit_state, tok); + emit_osmx64(&emit_state, tok); break; default: if (!tok->is_reg) { |