Files
Interpreter/isa/src/Encode.cpp
T
Admin 96607cfe75 isa 模块注释完善:Doxygen 风格。
- Types.h:定宽类型、TypeTag、饱和四则的 @brief/@param/@return
- Op.h:Op 枚举冻结约束、OpFormat/OpClass、OpDef/kOpDefs 表、三个查询函数
- Instr.h:指令字布局、pack/拆字段、按形态 enc_* 系列
- Encode.h/.cpp:Decoded 字段语义、encode/decode/disasm 契约
2026-08-21 23:19:08 +08:00

93 lines
2.6 KiB
C++

/**
* @file Encode.cpp
* @brief 指令编解码与反汇编实现
* @author
* @date 2026-08-19
*/
#include "isa/Encode.h"
#include <cstdio>
namespace isa {
/**
* @brief 编码:字段视图打包成一条 32 位指令字。
* @param d 解码后的字段视图
* @return 打包后的指令字;满足 encode(decode(w)) == w
*/
Instr encode(Decoded d) {
return pack(d.op, d.rd, d.a, d.b);
}
/**
* @brief 解码:指令字拆成字段视图。
* @param w 32 位指令字
* @return 各字段视图
*/
Decoded decode(Instr w) {
Decoded d;
d.op = op(w);
d.rd = rd(w);
d.a = a(w);
d.b = b(w);
return d;
}
/**
* @brief 反汇编一条指令为一行文本。
* @param w 指令字
* @param out 输出缓冲
* @param cap 缓冲容量(含 '\0');cap==0 时直接返回、不写 out
* @details 按操作数形态表驱动输出,文本与 Doc/isa/指令与映像.md 一致;
* 未知操作码输出 `??? 0x<w>`。
*/
void disasm(Instr w, char* out, size_t cap) {
if (cap == 0) {
return;
}
out[0] = '\0';
const Op o = op(w);
const int idx = static_cast<int>(o);
if (idx < 0 || idx >= kOpCount) {
snprintf(out, cap, "??? 0x%08x", static_cast<unsigned>(w));
return;
}
const char* m = mnemonic(o);
// 表驱动:按操作数形态输出(文本与 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 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 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 OpFormat::JMP:
snprintf(out, cap, "%s %+d", m, static_cast<int>(off16(w)));
break;
case OpFormat::JC:
snprintf(out, cap, "%s r%u, %+d", m,
static_cast<unsigned>(rd(w)), static_cast<int>(off16(w)));
break;
case OpFormat::CALL:
case OpFormat::CAL:
snprintf(out, cap, "%s %u", m, static_cast<unsigned>(imm16(w)));
break;
case OpFormat::NONE:
snprintf(out, cap, "%s", m);
break;
}
}
} // namespace isa