- Codec:set_byte0 的 11/10 前缀位修正(0xC0/0x80);新增 JC 形态偏移 专用读写(off@55..24,字节 3..6)——修复 JF rd 被 off 覆盖 - Stb:offset_meta=0(空段)时值段大小校验按 SHA 尾计算(修复 values segment size mismatch) - Codegen:实例字段带 func(field_func),LOAD_OFF/STORE_OFF 按字段 类型设 func(pt=TIME → I64) - main.cpp:--disasm 按 instr_len 迭代变长字节码 - 验证:13 个正例全部编译出 V2 产物 + disasm 自读通过(RET/CAL.TON/ STORE_OFF.I64/JF 偏移等抽查正确);ctest 11/13(vm/cases 待阶段 4)
128 lines
4.9 KiB
C++
128 lines
4.9 KiB
C++
/**
|
||
* @file Codec.h
|
||
* @brief 指令字编解码 + 配置驱动反汇编(编译器侧,V2)
|
||
* @author
|
||
* @date 2026-08-21
|
||
*
|
||
* @details 编译器不依赖 isa:变长指令字(前缀分区编码,4/8/16/32B)与
|
||
* 反汇编输出(按 machine.toml 的 prefix/op/func/fmt)全部由本模块 + MachineConfig
|
||
* 提供,保证与执行器(isa V2)产生的字节一致。位号见 Doc/isa/指令编码.md。
|
||
*/
|
||
|
||
#pragma once
|
||
|
||
#include <cstddef>
|
||
#include <cstdint>
|
||
#include <string>
|
||
|
||
#include "compiler/MachineConfig.h"
|
||
|
||
namespace compiler {
|
||
|
||
/// 指令字最大长度(字节)。
|
||
static constexpr size_t kMaxInstrLen = 16;
|
||
|
||
/**
|
||
* @brief 前缀定长:读字节 0 判指令长度。
|
||
* @param code 指令字节(至少 1 字节)
|
||
* @return 4/8/16/32(前缀 `1`/`01`/`001`/`0001`)
|
||
*/
|
||
size_t instr_len(const uint8_t* code);
|
||
|
||
/**
|
||
* @brief 推导形态前缀字符串。
|
||
* @param code 指令字节
|
||
* @return "11"/"10"/"011"/"010000".."010101"/"0010"/"0011"/"0001"
|
||
*/
|
||
std::string prefix_of(const uint8_t* code);
|
||
|
||
/**
|
||
* @brief 取分区内操作码。
|
||
* @param code 指令字节
|
||
* @return op(4B 6 位 / 8B 5 位或 2 位 / 16B·32B 4 位)
|
||
*/
|
||
uint8_t op_of(const uint8_t* code);
|
||
|
||
/**
|
||
* @brief 取 func 位段(字节 1 高 4 位)。
|
||
* @param code 指令字节
|
||
* @return 0..15(0..9 有效)
|
||
*/
|
||
uint8_t func_of(const uint8_t* code);
|
||
|
||
/// @brief 取 rd(23..16)。
|
||
uint8_t rd_of(const uint8_t* code);
|
||
/// @brief 取 rs1(31..24)。
|
||
uint8_t rs1_of(const uint8_t* code);
|
||
/// @brief 取 rs2(39..32)。
|
||
uint8_t rs2_of(const uint8_t* code);
|
||
/// @brief 取 imm32(55..24,IMM 形态)。
|
||
uint32_t imm32_of(const uint8_t* code);
|
||
/// @brief 取 slot32(55..24,SLOT 形态)。
|
||
uint32_t slot32_of(const uint8_t* code);
|
||
/// @brief 取 off32(47..16,JMP 形态,有符号字节偏移)。
|
||
int32_t off32_of(const uint8_t* code);
|
||
/// @brief 取 off32(55..24,JC 形态,有符号字节偏移)。
|
||
int32_t off32_jc_of(const uint8_t* code);
|
||
/// @brief 取 fn_id32(47..16,CALL 形态)。
|
||
uint32_t fn_id32_of(const uint8_t* code);
|
||
/// @brief 取 fb_id16(31..16,CAL 形态)。
|
||
uint16_t fb_id16_of(const uint8_t* code);
|
||
/// @brief 取 CAL 的实例槽号(63..32)。
|
||
uint32_t cal_slot32_of(const uint8_t* code);
|
||
/// @brief 取 16B 形态的 off32(87..56)。
|
||
int32_t off32_hi_of(const uint8_t* code);
|
||
/// @brief 取 imm64(87..24,IMM64 形态)。
|
||
uint64_t imm64_of(const uint8_t* code);
|
||
|
||
/**
|
||
* @brief 写字节 0(前缀 + 操作码)。
|
||
* @param out 指令缓冲(≥16B,写入后高位补 0 由调用方保证)
|
||
* @param prefix 形态前缀(11/10/011/010000..010101/0010/0011/0001)
|
||
* @param op 分区内编号
|
||
*/
|
||
void set_byte0(uint8_t* out, const std::string& prefix, uint32_t op);
|
||
|
||
/// @brief 写字节 1 的 func(高 4 位)。
|
||
void set_func(uint8_t* out, uint8_t func);
|
||
/// @brief 写 rd(23..16)。
|
||
void set_rd(uint8_t* out, uint8_t rd);
|
||
/// @brief 写 rs1(31..24)。
|
||
void set_rs1(uint8_t* out, uint8_t rs1);
|
||
/// @brief 写 rs2(39..32)。
|
||
void set_rs2(uint8_t* out, uint8_t rs2);
|
||
/// @brief 写 imm32(55..24)。
|
||
void set_imm32(uint8_t* out, uint32_t v);
|
||
/// @brief 写 slot32(55..24)。
|
||
void set_slot32(uint8_t* out, uint32_t v);
|
||
/// @brief 写 off32(47..16,JMP 形态)。
|
||
void set_off32(uint8_t* out, int32_t v);
|
||
/// @brief 写 off32(55..24,JC 形态)。
|
||
void set_off32_jc(uint8_t* out, int32_t v);
|
||
/// @brief 写 fn_id32(47..16)。
|
||
void set_fn_id32(uint8_t* out, uint32_t v);
|
||
/// @brief 写 fb_id16(31..16)。
|
||
void set_fb_id16(uint8_t* out, uint16_t v);
|
||
/// @brief 写 CAL 实例槽号(63..32)。
|
||
void set_cal_slot32(uint8_t* out, uint32_t v);
|
||
/// @brief 写 16B 形态的 off32(87..56)。
|
||
void set_off32_hi(uint8_t* out, int32_t v);
|
||
/// @brief 写 imm64(87..24)。
|
||
void set_imm64(uint8_t* out, uint64_t v);
|
||
|
||
/**
|
||
* @brief 配置驱动反汇编:按 machine.toml 的 prefix/op/func/fmt 输出一行文本。
|
||
* @param cfg 机器配置(指令名 / fmt / func 类别 / fb 名来源)
|
||
* @param code 指令字节
|
||
* @param len 指令长度(instr_len 定)
|
||
* @param out 输出缓冲
|
||
* @param cap 缓冲容量(含 '\0');cap==0 时直接返回、不写 out
|
||
* @details 文本格式与 Doc/isa/指令与映像.md §10 一致:
|
||
* `MOVE r1, r2`、`LOAD.I16 r5, s3`(full/float/dst 类显示类型后缀)、
|
||
* `JMP +4`、`JT r0, -1`、`CALL 1`、`CAL.TON s5`、`RET`;
|
||
* 未知 (prefix, op) 输出 `??? 0x<hex dump>`。
|
||
*/
|
||
void disasm(const MachineConfig& cfg, const uint8_t* code, size_t len,
|
||
char* out, size_t cap);
|
||
}
|