步骤 1:OpFormat/OpClass 显式化 + disasm 表驱动。
- Op.h:新增 OpFormat(RR/RRR/IMM/SLOT/JMP/JC/CALL/CAL/NONE)与 OpClass(Plain/Instance)枚举;34 条编译期表 kOpDefs(name/format/class, 与 ops.txt 强校验的基准);mnemonic/format/op_class 查表 - Encode.cpp:disasm 按 format 表驱动输出(文本与之前逐条一致) - 验证:11 个 ctest 全绿;表查询断言(8 个 INSTANCE=CAL、越界哨兵)
This commit is contained in:
+75
-13
@@ -53,20 +53,82 @@ namespace isa {
|
||||
// 操作码总数
|
||||
static const int kOpCount = 34;
|
||||
|
||||
// 助记符:下标与 Op 数值一一对应
|
||||
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",
|
||||
// 操作数形态(三层分类第二层,见 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) {
|
||||
const int idx = static_cast<int>(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<int>(op);
|
||||
return (idx >= 0 && idx < kOpCount) ? kOpDefs[idx].format : OpFormat::NONE;
|
||||
}
|
||||
|
||||
inline OpClass op_class(Op op) {
|
||||
const int idx = static_cast<int>(op);
|
||||
return (idx >= 0 && idx < kOpCount) ? kOpDefs[idx].cls : OpClass::Plain;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-38
@@ -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<unsigned>(rd(w)), static_cast<unsigned>(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<unsigned>(rd(w)), static_cast<unsigned>(a(w)),
|
||||
static_cast<unsigned>(b(w)));
|
||||
break;
|
||||
case Op::LOADK:
|
||||
case OpFormat::IMM:
|
||||
case OpFormat::SLOT:
|
||||
snprintf(out, cap, "%s r%u, %u", m,
|
||||
static_cast<unsigned>(rd(w)), static_cast<unsigned>(imm16(w)));
|
||||
break;
|
||||
case Op::JMP:
|
||||
case OpFormat::JMP:
|
||||
snprintf(out, cap, "%s %+d", m, static_cast<int>(off16(w)));
|
||||
break;
|
||||
case Op::JT:
|
||||
case Op::JF:
|
||||
case OpFormat::JC:
|
||||
snprintf(out, cap, "%s r%u, %+d", m,
|
||||
static_cast<unsigned>(rd(w)), static_cast<int>(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<unsigned>(rd(w)), static_cast<unsigned>(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<unsigned>(imm16(w)));
|
||||
break;
|
||||
case Op::RET:
|
||||
case OpFormat::NONE:
|
||||
snprintf(out, cap, "%s", m);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user