diff options
author | Oxore <oxore@protonmail.com> | 2023-08-12 00:50:22 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2023-08-12 00:50:22 +0300 |
commit | 3e584a3df6bede3ae545ae530c619ba6eecc97c9 (patch) | |
tree | c3fc9afbf17f0e79d81c044f3e85be63f8c2986e | |
parent | 5a724adfc7cfbdd015c38e8627d491e8c297964d (diff) |
Impl basic kind of instruction emission
-rw-r--r-- | main.c | 150 |
1 files changed, 143 insertions, 7 deletions
@@ -379,7 +379,6 @@ enum arg_type { ARG_SR, ARG_CCR, ARG_USP, - ARG_EXPR, }; enum args_count { @@ -1422,7 +1421,6 @@ static const char *arg_type_to_string(const enum arg_type type) case ARG_SR: return "SR"; case ARG_CCR: return "CCR"; case ARG_USP: return "USP"; - case ARG_EXPR: return "EXPR"; } UNREACHABLE(); return "_UNKNOWN"; @@ -1497,14 +1495,13 @@ static void fprint_expr( fputc(']', s); } -static void fprint_arg( +static void fprint_arg_debug( const struct lex *const lex, const struct arg *const arg, FILE *const s) { fprintf(s, "(%s", arg_type_to_string(arg->type)); switch (arg->type) { - case ARG_NONE: case ARG_DN: fprintf(s, " reg [d%d]", arg->xn); break; @@ -1562,10 +1559,17 @@ static void fprint_arg( } } fprintf(s, "]"); + break; case ARG_SR: + fprintf(s, "reg [sr]"); + break; case ARG_CCR: + fprintf(s, "reg [ccr]"); + break; case ARG_USP: - case ARG_EXPR: + fprintf(s, "reg [usp]"); + break; + case ARG_NONE: break; } fprintf(s, " raw-tokens ["); @@ -1596,13 +1600,13 @@ static int fprint_stmt_debug( fprintf(s, "\n\t(size %s)", opsize_to_string(stmt->instruction.opsize)); if (stmt->instruction.arg1.type != ARG_NONE) { fprintf(s, "\n\t(arg1 "); - fprint_arg(lex, &stmt->instruction.arg1, s); + fprint_arg_debug(lex, &stmt->instruction.arg1, s); fprintf(s, ")"); } if (stmt->instruction.arg2.type != ARG_NONE) { assert(stmt->instruction.arg1.type != ARG_NONE); fprintf(s, "\n\t(arg2 "); - fprint_arg(lex, &stmt->instruction.arg2, s); + fprint_arg_debug(lex, &stmt->instruction.arg2, s); fprintf(s, ")"); } } else if (stmt->type == ST_DIRECTIVE) { @@ -2729,6 +2733,7 @@ static int pars_parse_instruction( static int pars_parse_assignment( struct pars *const self, const size_t label_id, const size_t symbol_id) { + // TODO (void) label_id; (void) symbol_id; return pars_yield_error_msg(self, self->cur_tok_id, E_NIMPL); @@ -2835,6 +2840,113 @@ static int assem_resolve(struct assem *const self) return OK; } +static void emit_expr( + const struct lex *const lex, + const struct expr_tokens_span *const expr, + FILE *const s) +{ + for (size_t i = 0; i < expr->num_tokens; i++) { + const struct token token = lex->tokbuf[expr->first_token + i]; + if (token.type == TT_NEWLINE) { + break; + } + fprintf(s, "%.*s", (int)token.length, lex->input + token.offset); + } +} + +static void emit_arg( + const struct lex *const lex, + const struct arg *const arg, + FILE *const s) +{ + switch (arg->type) { + case ARG_DN: + fprintf(s, "%%d%d", arg->xn); + break; + case ARG_AN: + fprintf(s, "%%a%d", arg->xn); + break; + case ARG_AN_ADDR: + fprintf(s, "%%a%d@", arg->xn); + break; + case ARG_AN_ADDR_INCR: + fprintf(s, "%%a%d@+", arg->xn); + break; + case ARG_AN_ADDR_DECR: + fprintf(s, "%%a%d@-", arg->xn); + break; + case ARG_AN_ADDR_16: + fprintf(s, "%%a%d@(", arg->xn); + emit_expr(lex, &arg->expr, s); + fprintf(s, ")"); + break; + case ARG_AN_ADDR_8_XI: + fprintf(s, "%%a%d@(", arg->xn); + emit_expr(lex, &arg->expr, s); + { + const char reg_type = arg->xi & 0x8 ? 'a' : 'd'; + const char size = arg->briefext_size == OPSIZE_L ? 'l' : 'w'; + fprintf(s, ",%c%d:%c)", reg_type, arg->xi & 0x7, size); + } + break; + case ARG_ADDR_WORD: + emit_expr(lex, &arg->expr, s), fprintf(s, ".w"); + break; + case ARG_ADDR_LONG: + emit_expr(lex, &arg->expr, s), fprintf(s, ".l"); + break; + case ARG_ADDR_UNSPEC: + emit_expr(lex, &arg->expr, s); + break; + case ARG_PC_ADDR_16: + fprintf(s, "%%pc@("); + emit_expr(lex, &arg->expr, s); + fprintf(s, ")"); + break; + case ARG_PC_ADDR_8_XI: + fprintf(s, "%%pc@("); + emit_expr(lex, &arg->expr, s); + { + const char reg_type = arg->xi & 0x8 ? 'a' : 'd'; + const char size = arg->briefext_size == OPSIZE_L ? 'l' : 'w'; + fprintf(s, ",%c%d:%c)", reg_type, arg->xi & 0x7, size); + } + break; + case ARG_IMMEDIATE: + fprintf(s, "#"), emit_expr(lex, &arg->expr, s); + break; + case ARG_REGMASK: + { + // TODO make it concise + bool leading_space = false; + for (unsigned i = 0; i < 8; i++) { + if (arg->regmask & (1 << i)) { + fprintf(s, "%s%%d%d", leading_space ? "/" : "", i); + leading_space = true; + } + } + for (unsigned i = 0; i < 8; i++) { + if (arg->regmask & (1 << (i + 8))) { + fprintf(s, "%s%%a%d", leading_space ? "/" : "", i); + leading_space = true; + } + } + } + break; + case ARG_SR: + fprintf(s, "%%sr"); + break; + case ARG_CCR: + fprintf(s, "%%ccr"); + break; + case ARG_USP: + fprintf(s, "%%usp"); + break; + case ARG_NONE: + break; + } +} + static int assem_emit(struct assem *const self, FILE *const stream) { const struct lex *const lex = self->pars->lex; @@ -2849,6 +2961,30 @@ static int assem_emit(struct assem *const self, FILE *const stream) fprint_stmt_debug(lex, pars->stmttab + i, stream); } } + for (size_t i = 1; i < pars->stmttab_size / (sizeof *pars->stmttab); i++) { + const struct stmt *stmt = pars->stmttab + i; + if (stmt->label_token) { + const struct token token = lex->tokbuf[stmt->label_token]; + fprintf(stream, "%.*s:", (int)token.length, lex->input + token.offset); + } + if (stmt->type == ST_INSTRUCTION) { + const struct instruction instr = stmt->instruction; + fprintf(stream, "\t%s", mnemonic_to_string(instr.mnemonic)); + if (instr.arg1.type != ARG_NONE) { + fprintf(stream, " "); + emit_arg(lex, &instr.arg1, stream); + if (instr.arg2.type != ARG_NONE) { + fprintf(stream, ", "); + emit_arg(lex, &instr.arg2, stream); + } + } + } + if (stmt->comment_token) { + const struct token token = lex->tokbuf[stmt->comment_token]; + fprintf(stream, " %.*s", (int)token.length, lex->input + token.offset); + } + fprintf(stream, "\n"); + } return OK; } |