diff --git a/isa/include/isa/Op.h b/isa/include/isa/Op.h index cfa3d83..a28440d 100644 --- a/isa/include/isa/Op.h +++ b/isa/include/isa/Op.h @@ -53,20 +53,82 @@ namespace isa { // 操作码总数 static const int kOpCount = 34; - // 助记符:下标与 Op 数值一一对应 + // 操作数形态(三层分类第二层,见 Doc/isa/指令配置.md) + enum class OpFormat : uint8_t { + RR, // 两寄存器:rd rs(MOVE / NOT) + RRR, // 三寄存器:rd ra rb(逻辑 / 算术 / 比较) + IMM, // 常量:rd const_id(LOADK) + SLOT, // 槽:rd slot(LOAD_* / STORE_*) + JMP, // 偏移:off + JC, // 条件跳转:r off(JT / JF) + CALL, // 调用:fn_id + CAL, // 实例:instance(CAL_*) + NONE, // 无操作数(RET) + }; + + // 操作对象大类(三层分类第一层) + enum class OpClass : uint8_t { + Plain, // 无实例:寄存器 / 立即数 / 槽 / 分支 / 调用 + Instance, // 有实例:操作数据区实例块(内建 FB) + }; + + // 编译期指令表:下标与 Op 数值一一对应(ops.txt 强校验的基准) + struct OpDef { + const char* name; + OpFormat format; + OpClass cls; + }; + + static const OpDef kOpDefs[kOpCount] = { + {"MOVE", OpFormat::RR, OpClass::Plain}, // 0 + {"LOADK", OpFormat::IMM, OpClass::Plain}, // 1 + {"NOT", OpFormat::RR, OpClass::Plain}, // 2 + {"AND", OpFormat::RRR, OpClass::Plain}, // 3 + {"OR", OpFormat::RRR, OpClass::Plain}, // 4 + {"ADD", OpFormat::RRR, OpClass::Plain}, // 5 + {"SUB", OpFormat::RRR, OpClass::Plain}, // 6 + {"MUL", OpFormat::RRR, OpClass::Plain}, // 7 + {"DIV", OpFormat::RRR, OpClass::Plain}, // 8 + {"CMP_EQ", OpFormat::RRR, OpClass::Plain}, // 9 + {"CMP_NE", OpFormat::RRR, OpClass::Plain}, // 10 + {"CMP_LT", OpFormat::RRR, OpClass::Plain}, // 11 + {"CMP_LE", OpFormat::RRR, OpClass::Plain}, // 12 + {"CMP_GT", OpFormat::RRR, OpClass::Plain}, // 13 + {"CMP_GE", OpFormat::RRR, OpClass::Plain}, // 14 + {"JMP", OpFormat::JMP, OpClass::Plain}, // 15 + {"JT", OpFormat::JC, OpClass::Plain}, // 16 + {"JF", OpFormat::JC, OpClass::Plain}, // 17 + {"LOAD_I", OpFormat::SLOT, OpClass::Plain}, // 18 + {"STORE_Q", OpFormat::SLOT, OpClass::Plain}, // 19 + {"LOAD_M", OpFormat::SLOT, OpClass::Plain}, // 20 + {"STORE_M", OpFormat::SLOT, OpClass::Plain}, // 21 + {"LOAD_GLOBAL", OpFormat::SLOT, OpClass::Plain}, // 22 + {"STORE_GLOBAL", OpFormat::SLOT, OpClass::Plain},// 23 + {"CAL_TON", OpFormat::CAL, OpClass::Instance}, // 24 + {"CAL_TOF", OpFormat::CAL, OpClass::Instance}, // 25 + {"CAL_TP", OpFormat::CAL, OpClass::Instance}, // 26 + {"CAL_CTU", OpFormat::CAL, OpClass::Instance}, // 27 + {"CAL_CTD", OpFormat::CAL, OpClass::Instance}, // 28 + {"CAL_CTUD", OpFormat::CAL, OpClass::Instance}, // 29 + {"CAL_R_TRIG", OpFormat::CAL, OpClass::Instance},// 30 + {"CAL_F_TRIG", OpFormat::CAL, OpClass::Instance},// 31 + {"CALL", OpFormat::CALL, OpClass::Plain}, // 32 + {"RET", OpFormat::NONE, OpClass::Plain}, // 33 + }; + + // 助记符 / 格式 / 大类:查表(越界返回哨兵) inline const char* mnemonic(Op op) { - static const char* const kMnemonic[kOpCount] = { - "MOVE", "LOADK", "NOT", "AND", "OR", - "ADD", "SUB", "MUL", "DIV", - "CMP_EQ", "CMP_NE", "CMP_LT", "CMP_LE", "CMP_GT", "CMP_GE", - "JMP", "JT", "JF", - "LOAD_I", "STORE_Q", "LOAD_M", "STORE_M", - "LOAD_GLOBAL", "STORE_GLOBAL", - "CAL_TON", "CAL_TOF", "CAL_TP", "CAL_CTU", "CAL_CTD", "CAL_CTUD", - "CAL_R_TRIG", "CAL_F_TRIG", - "CALL", "RET", - }; const int idx = static_cast(op); - return (idx >= 0 && idx < kOpCount) ? kMnemonic[idx] : "???"; + return (idx >= 0 && idx < kOpCount) ? kOpDefs[idx].name : "???"; + } + + inline OpFormat format(Op op) { + const int idx = static_cast(op); + return (idx >= 0 && idx < kOpCount) ? kOpDefs[idx].format : OpFormat::NONE; + } + + inline OpClass op_class(Op op) { + const int idx = static_cast(op); + return (idx >= 0 && idx < kOpCount) ? kOpDefs[idx].cls : OpClass::Plain; } } diff --git a/isa/src/Encode.cpp b/isa/src/Encode.cpp index 9990d66..fdd74a9 100644 --- a/isa/src/Encode.cpp +++ b/isa/src/Encode.cpp @@ -38,61 +38,34 @@ void disasm(Instr w, char* out, size_t cap) { } const char* m = mnemonic(o); - switch (o) { - case Op::MOVE: - case Op::NOT: + // 表驱动:按操作数形态输出(文本与 Doc/isa/指令与映像.md 一致) + switch (format(o)) { + case OpFormat::RR: snprintf(out, cap, "%s r%u, r%u", m, static_cast(rd(w)), static_cast(a(w))); break; - case Op::AND: - case Op::OR: - case Op::ADD: - case Op::SUB: - case Op::MUL: - case Op::DIV: - case Op::CMP_EQ: - case Op::CMP_NE: - case Op::CMP_LT: - case Op::CMP_LE: - case Op::CMP_GT: - case Op::CMP_GE: + case OpFormat::RRR: snprintf(out, cap, "%s r%u, r%u, r%u", m, static_cast(rd(w)), static_cast(a(w)), static_cast(b(w))); break; - case Op::LOADK: + case OpFormat::IMM: + case OpFormat::SLOT: snprintf(out, cap, "%s r%u, %u", m, static_cast(rd(w)), static_cast(imm16(w))); break; - case Op::JMP: + case OpFormat::JMP: snprintf(out, cap, "%s %+d", m, static_cast(off16(w))); break; - case Op::JT: - case Op::JF: + case OpFormat::JC: snprintf(out, cap, "%s r%u, %+d", m, static_cast(rd(w)), static_cast(off16(w))); break; - case Op::LOAD_I: - case Op::STORE_Q: - case Op::LOAD_M: - case Op::STORE_M: - case Op::LOAD_GLOBAL: - case Op::STORE_GLOBAL: - snprintf(out, cap, "%s r%u, %u", m, - static_cast(rd(w)), static_cast(imm16(w))); - break; - case Op::CAL_TON: - case Op::CAL_TOF: - case Op::CAL_TP: - case Op::CAL_CTU: - case Op::CAL_CTD: - case Op::CAL_CTUD: - case Op::CAL_R_TRIG: - case Op::CAL_F_TRIG: - case Op::CALL: + case OpFormat::CALL: + case OpFormat::CAL: snprintf(out, cap, "%s %u", m, static_cast(imm16(w))); break; - case Op::RET: + case OpFormat::NONE: snprintf(out, cap, "%s", m); break; }