- Types.h:定宽类型、TypeTag、饱和四则的 @brief/@param/@return - Op.h:Op 枚举冻结约束、OpFormat/OpClass、OpDef/kOpDefs 表、三个查询函数 - Instr.h:指令字布局、pack/拆字段、按形态 enc_* 系列 - Encode.h/.cpp:Decoded 字段语义、encode/decode/disasm 契约
93 lines
2.6 KiB
C++
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
|