diff options
| -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;  }  | 
