阶段2-3:Codec V2 化(变长指令字编解码 + 配置驱动 disasm 类型后缀)
- instr_len 前缀定长(1/01/001/0001 → 4/8/16/32B) - prefix_of/op_of/func_of + 全部位号 get/set(rd/rs1/rs2/imm32/slot32/off32/ fn_id32/fb_id16/cal_slot32/off32_hi/imm64) - set_byte0 按前缀写(11/10/011/010xxx 形态位/0010/0011/0001) - disasm:find_op_by_key 查配置;full/float/dst 类显示 .TYPE 后缀 (U8/I8/.../F64);CAL 打印 fb 名(CAL.TON s5);未知输出 ??? 0x hex - main.cpp --disasm 调用适配(TODO V2 待 Stb 重写) - 状态:编译仅剩 Codegen.cpp(84 处 V1 残留,下一步阶段2-5 重写)
This commit is contained in:
@@ -1,59 +1,123 @@
|
||||
/**
|
||||
* @file Codec.h
|
||||
* @brief 指令字编解码 + 配置驱动反汇编(编译器侧)
|
||||
* @brief 指令字编解码 + 配置驱动反汇编(编译器侧,V2)
|
||||
* @author
|
||||
* @date 2026-08-21
|
||||
*
|
||||
* @details 编译器不依赖 isa:指令字布局([op:8|rd:8|a:8|b:8] 小端)与
|
||||
* 反汇编输出(按 machine.toml 的 format/参数名)全部由本模块 + MachineConfig 提供,
|
||||
* 保证与执行器(isa)产生的字节一致。
|
||||
* @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 {
|
||||
|
||||
/// 指令字:`[ op:8 | rd:8 | a:8 | b:8 ]`,小端 u32。
|
||||
typedef uint32_t Instr;
|
||||
/// 指令字最大长度(字节)。
|
||||
static constexpr size_t kMaxInstrLen = 16;
|
||||
|
||||
/**
|
||||
* @brief 打包:opcode + 三个 8 位字段拼成一条指令字。
|
||||
* @param opcode 操作码(低 8 位)
|
||||
* @param rd 目标寄存器 / 条件寄存器(第 8..15 位)
|
||||
* @param a 源寄存器 / 立即数低 8 位 / 偏移低 8 位(第 16..23 位)
|
||||
* @param b 源寄存器 / 立即数高 8 位 / 偏移高 8 位(第 24..31 位)
|
||||
* @return 打包后的指令字(小端 u32)
|
||||
* @details 布局与执行器 isa 一致,保证编译器产出的字节可被执行。
|
||||
* @brief 前缀定长:读字节 0 判指令长度。
|
||||
* @param code 指令字节(至少 1 字节)
|
||||
* @return 4/8/16/32(前缀 `1`/`01`/`001`/`0001`)
|
||||
*/
|
||||
Instr pack(uint8_t opcode, uint8_t rd, uint8_t a, uint8_t b);
|
||||
|
||||
/// @brief 取操作码(低 8 位)。
|
||||
uint8_t op_of(Instr w);
|
||||
/// @brief 取 rd 字段(第 8..15 位)。
|
||||
uint8_t rd_of(Instr w);
|
||||
/// @brief 取 a 字段(第 16..23 位)。
|
||||
uint8_t a_of(Instr w);
|
||||
/// @brief 取 b 字段(第 24..31 位)。
|
||||
uint8_t b_of(Instr w);
|
||||
/// @brief a|b 拼 16 位无符号数(const_id / slot / fn_id)。
|
||||
uint16_t imm16_of(Instr w);
|
||||
/// @brief a|b 为有符号相对偏移(单位:指令条数,相对下一条指令)。
|
||||
int16_t off16_of(Instr w);
|
||||
size_t instr_len(const uint8_t* code);
|
||||
|
||||
/**
|
||||
* @brief 配置驱动反汇编:按 machine.toml 的 format 输出一行文本。
|
||||
* @param cfg 机器配置(opcode 名 / format / 参数名来源)
|
||||
* @param w 指令字
|
||||
* @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/JC 形态,有符号字节偏移)。
|
||||
int32_t off32_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)。
|
||||
void set_off32(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 一致(如 `MOVE r1, r2`、
|
||||
* `LOADK r0, 3`、`JMP +4`、`JT r0, -1`、`CALL 1`、`CAL_TON 0`、`RET`);
|
||||
* 未知操作码输出 `??? 0x<hex>`。
|
||||
* @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, Instr w, char* out, size_t cap);
|
||||
void disasm(const MachineConfig& cfg, const uint8_t* code, size_t len,
|
||||
char* out, size_t cap);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user