- Types.h:func 宽度/符号表(kFuncWidth/kFuncSigned)、饱和模板(各宽度 __int128 中间量 + 除法 A:除零返回被除数/MIN/-1 夹界/截断)、删 TypeTag - Op.h/.cpp:前缀分区 + 72 条指令表(与 machine.toml 强校验一致)、 uses_rd/rs1/rs2 直推、kFbNames(15 内建 FB) - Instr.h:变长 instr_len、位号 get/set(含 JC off@55..24、SLOT_OFF off@87..56)、 enc_* 发射器 - Encode.h/.cpp:decode/encode 往返、disasm(类型后缀 + CAL fb 名 + 未知 0x dump) - isa_test V2:饱和边界/func 表/前缀定长/位号往返/编解码/disasm/uses_*/指令表 修复的实现 bug:find_op 字符串比较(指针==)、set_byte0 11/10 与 010xxx 分支、 CAL 字段约定((slot<<16)|fb_id)、disasm 未知前缀 used 长度 状态:vm/executor 编译暂破(V1 代码引用旧 isa 接口),4-2 同步
305 lines
12 KiB
C++
305 lines
12 KiB
C++
/**
|
||
* @file Instr.h
|
||
* @brief 变长指令字:前缀定长 + 位号读写 + 发射器(V2)
|
||
* @details 执行器侧实现(compiler 侧 Codec 各自一份,位号一致)。
|
||
* - 字节 0 = [长度前缀+形态分区 | op];字节 1 = [func:4 | 空:4]
|
||
* - 前缀定长:`1`→4B、`01`→8B、`001`→16B、`0001`→32B
|
||
* - 操作数区位号(bit16 起):rd=23..16、imm32/slot32=55..24(字节 3..6)、
|
||
* off32(JMP)=47..16(字节 2..5)、off32_jc(JC)=55..24(字节 3..6)、
|
||
* fn_id32=47..16、fb_id16=31..16、CAL slot32=63..32、
|
||
* SLOT_OFF off32=87..56(字节 7..10)、imm64=87..24
|
||
* @author
|
||
* @date 2026-08-19
|
||
*/
|
||
|
||
#pragma once
|
||
|
||
#include <cstdint>
|
||
|
||
#include "isa/Op.h"
|
||
|
||
namespace isa {
|
||
|
||
/**
|
||
* @brief 前缀定长:读字节 0 判指令长度。
|
||
* @param code 指令字节(至少 1 字节)
|
||
* @return 4/8/16/32
|
||
*/
|
||
inline size_t instr_len(const uint8_t* code) {
|
||
const uint8_t b = code[0];
|
||
if (b & 0x80) return 4; // 1xxxxxxx
|
||
if ((b & 0xC0) == 0x40) return 8; // 01xxxxxx
|
||
if ((b & 0xE0) == 0x20) return 16; // 001xxxxx
|
||
return 32; // 0001xxxx
|
||
}
|
||
|
||
/// @brief 取分区内操作码(4B 6 位 / 8B 5 位或 2 位 / 16B·32B 4 位)。
|
||
inline uint8_t op_of(const uint8_t* code) {
|
||
const uint8_t b = code[0];
|
||
if (b & 0x80) return b & 0x3F;
|
||
if ((b & 0xC0) == 0x40) {
|
||
return (b & 0x20) ? (b & 0x1F) : (b & 0x03);
|
||
}
|
||
return b & 0x0F;
|
||
}
|
||
|
||
/// @brief 取 func 位段(字节 1 高 4 位)。
|
||
inline uint8_t func_of(const uint8_t* code) {
|
||
return static_cast<uint8_t>((code[1] >> 4) & 0x0F);
|
||
}
|
||
|
||
/// @brief 取 rd(23..16 = 字节 2)。
|
||
inline uint8_t rd_of(const uint8_t* code) { return code[2]; }
|
||
/// @brief 取 rs1(31..24 = 字节 3)。
|
||
inline uint8_t rs1_of(const uint8_t* code) { return code[3]; }
|
||
/// @brief 取 rs2(39..32 = 字节 4)。
|
||
inline uint8_t rs2_of(const uint8_t* code) { return code[4]; }
|
||
|
||
/// @brief 取 imm32(55..24 = 字节 3..6,小端)。
|
||
inline uint32_t imm32_of(const uint8_t* code) {
|
||
return static_cast<uint32_t>(code[3])
|
||
| (static_cast<uint32_t>(code[4]) << 8)
|
||
| (static_cast<uint32_t>(code[5]) << 16)
|
||
| (static_cast<uint32_t>(code[6]) << 24);
|
||
}
|
||
|
||
/// @brief 取 slot32(同 imm32 位号)。
|
||
inline uint32_t slot32_of(const uint8_t* code) { return imm32_of(code); }
|
||
|
||
/// @brief 取 off32(47..16 = 字节 2..5,JMP 形态,有符号)。
|
||
inline int32_t off32_of(const uint8_t* code) {
|
||
return static_cast<int32_t>(static_cast<uint32_t>(code[2])
|
||
| (static_cast<uint32_t>(code[3]) << 8)
|
||
| (static_cast<uint32_t>(code[4]) << 16)
|
||
| (static_cast<uint32_t>(code[5]) << 24));
|
||
}
|
||
|
||
/// @brief 取 off32(55..24 = 字节 3..6,JC 形态,有符号)。
|
||
inline int32_t off32_jc_of(const uint8_t* code) {
|
||
return static_cast<int32_t>(static_cast<uint32_t>(code[3])
|
||
| (static_cast<uint32_t>(code[4]) << 8)
|
||
| (static_cast<uint32_t>(code[5]) << 16)
|
||
| (static_cast<uint32_t>(code[6]) << 24));
|
||
}
|
||
|
||
/// @brief 取 fn_id32(47..16 = 字节 2..5)。
|
||
inline uint32_t fn_id32_of(const uint8_t* code) {
|
||
return static_cast<uint32_t>(code[2])
|
||
| (static_cast<uint32_t>(code[3]) << 8)
|
||
| (static_cast<uint32_t>(code[4]) << 16)
|
||
| (static_cast<uint32_t>(code[5]) << 24);
|
||
}
|
||
|
||
/// @brief 取 fb_id16(31..16 = 字节 2..3)。
|
||
inline uint16_t fb_id16_of(const uint8_t* code) {
|
||
return static_cast<uint16_t>(code[2] | (static_cast<uint16_t>(code[3]) << 8));
|
||
}
|
||
|
||
/// @brief 取 CAL 实例槽号(63..32 = 字节 4..7)。
|
||
inline uint32_t cal_slot32_of(const uint8_t* code) {
|
||
return static_cast<uint32_t>(code[4])
|
||
| (static_cast<uint32_t>(code[5]) << 8)
|
||
| (static_cast<uint32_t>(code[6]) << 16)
|
||
| (static_cast<uint32_t>(code[7]) << 24);
|
||
}
|
||
|
||
/// @brief 取 SLOT_OFF 的 off32(87..56 = 字节 7..10,有符号)。
|
||
inline int32_t off32_hi_of(const uint8_t* code) {
|
||
return static_cast<int32_t>(static_cast<uint32_t>(code[7])
|
||
| (static_cast<uint32_t>(code[8]) << 8)
|
||
| (static_cast<uint32_t>(code[9]) << 16)
|
||
| (static_cast<uint32_t>(code[10]) << 24));
|
||
}
|
||
|
||
/// @brief 取 imm64(87..24 = 字节 3..10)。
|
||
inline uint64_t imm64_of(const uint8_t* code) {
|
||
uint64_t v = 0;
|
||
for (int i = 0; i < 8; ++i) {
|
||
v |= static_cast<uint64_t>(code[3 + i]) << (8 * i);
|
||
}
|
||
return v;
|
||
}
|
||
|
||
// ---- 发射器(写字节,调用方提供 ≥16 字节缓冲;返回指令长度)----
|
||
|
||
/// @brief 写字节 0(前缀 + 分区内 op)。
|
||
inline void set_byte0(uint8_t* out, const char* prefix, uint8_t op) {
|
||
if (prefix[0] == '1') {
|
||
// 11:bit7..6 = 11;10:bit7..6 = 10
|
||
out[0] = static_cast<uint8_t>((prefix[1] == '1' ? 0xC0 : 0x80) | (op & 0x3F));
|
||
} else if (prefix[0] == '0') {
|
||
if (prefix[1] == '1' && prefix[2] == '1') {
|
||
out[0] = static_cast<uint8_t>(0x60 | (op & 0x1F)); // 011
|
||
} else if (prefix[1] == '1') {
|
||
// 010xxx:形态位 3 位 + 子 op 2 位
|
||
const uint8_t shape = static_cast<uint8_t>(
|
||
(prefix[3] - '0') * 4 + (prefix[4] - '0') * 2 + (prefix[5] - '0'));
|
||
out[0] = static_cast<uint8_t>(0x40 | (shape << 2) | (op & 0x03));
|
||
} else if (prefix[2] == '1') {
|
||
out[0] = static_cast<uint8_t>(0x20 | (op & 0x0F)); // 0010/0011
|
||
} else {
|
||
out[0] = static_cast<uint8_t>(0x10 | (op & 0x0F)); // 0001
|
||
}
|
||
} else {
|
||
out[0] = 0;
|
||
}
|
||
}
|
||
|
||
/// @brief 写 func(字节 1 高 4 位)。
|
||
inline void set_func(uint8_t* out, uint8_t func) {
|
||
out[1] = static_cast<uint8_t>((out[1] & 0x0F) | ((func & 0x0F) << 4));
|
||
}
|
||
|
||
inline void set_rd(uint8_t* out, uint8_t rd) { out[2] = rd; }
|
||
inline void set_rs1(uint8_t* out, uint8_t rs1) { out[3] = rs1; }
|
||
inline void set_rs2(uint8_t* out, uint8_t rs2) { out[4] = rs2; }
|
||
|
||
inline void set_imm32(uint8_t* out, uint32_t v) {
|
||
out[3] = static_cast<uint8_t>(v & 0xFF);
|
||
out[4] = static_cast<uint8_t>((v >> 8) & 0xFF);
|
||
out[5] = static_cast<uint8_t>((v >> 16) & 0xFF);
|
||
out[6] = static_cast<uint8_t>((v >> 24) & 0xFF);
|
||
}
|
||
|
||
inline void set_slot32(uint8_t* out, uint32_t v) { set_imm32(out, v); }
|
||
|
||
inline void set_off32(uint8_t* out, int32_t v) { // JMP:字节 2..5
|
||
const uint32_t u = static_cast<uint32_t>(v);
|
||
out[2] = static_cast<uint8_t>(u & 0xFF);
|
||
out[3] = static_cast<uint8_t>((u >> 8) & 0xFF);
|
||
out[4] = static_cast<uint8_t>((u >> 16) & 0xFF);
|
||
out[5] = static_cast<uint8_t>((u >> 24) & 0xFF);
|
||
}
|
||
|
||
inline void set_off32_jc(uint8_t* out, int32_t v) { // JC:字节 3..6
|
||
const uint32_t u = static_cast<uint32_t>(v);
|
||
out[3] = static_cast<uint8_t>(u & 0xFF);
|
||
out[4] = static_cast<uint8_t>((u >> 8) & 0xFF);
|
||
out[5] = static_cast<uint8_t>((u >> 16) & 0xFF);
|
||
out[6] = static_cast<uint8_t>((u >> 24) & 0xFF);
|
||
}
|
||
|
||
inline void set_fn_id32(uint8_t* out, uint32_t v) { set_off32(out, static_cast<int32_t>(v)); }
|
||
|
||
inline void set_fb_id16(uint8_t* out, uint16_t v) {
|
||
out[2] = static_cast<uint8_t>(v & 0xFF);
|
||
out[3] = static_cast<uint8_t>((v >> 8) & 0xFF);
|
||
}
|
||
|
||
inline void set_cal_slot32(uint8_t* out, uint32_t v) {
|
||
out[4] = static_cast<uint8_t>(v & 0xFF);
|
||
out[5] = static_cast<uint8_t>((v >> 8) & 0xFF);
|
||
out[6] = static_cast<uint8_t>((v >> 16) & 0xFF);
|
||
out[7] = static_cast<uint8_t>((v >> 24) & 0xFF);
|
||
}
|
||
|
||
inline void set_off32_hi(uint8_t* out, int32_t v) { // SLOT_OFF:字节 7..10
|
||
const uint32_t u = static_cast<uint32_t>(v);
|
||
out[7] = static_cast<uint8_t>(u & 0xFF);
|
||
out[8] = static_cast<uint8_t>((u >> 8) & 0xFF);
|
||
out[9] = static_cast<uint8_t>((u >> 16) & 0xFF);
|
||
out[10] = static_cast<uint8_t>((u >> 24) & 0xFF);
|
||
}
|
||
|
||
inline void set_imm64(uint8_t* out, uint64_t v) {
|
||
for (int i = 0; i < 8; ++i) {
|
||
out[3 + i] = static_cast<uint8_t>((v >> (8 * i)) & 0xFF);
|
||
}
|
||
}
|
||
|
||
// ---- 便捷编码(vm_test 手拼映像用;输出 ≥16 字节缓冲)----
|
||
|
||
/// @brief 编码 RR 形态(MOVE/NOT/NEG 等),返回指令长度。
|
||
inline size_t enc_rr(uint8_t* out, const char* prefix, uint8_t op, uint8_t func,
|
||
uint8_t rd, uint8_t rs) {
|
||
set_byte0(out, prefix, op);
|
||
set_func(out, func);
|
||
set_rd(out, rd);
|
||
set_rs1(out, rs);
|
||
return instr_len(out);
|
||
}
|
||
|
||
/// @brief 编码 RRR 形态,返回指令长度。
|
||
inline size_t enc_rrr(uint8_t* out, const char* prefix, uint8_t op, uint8_t func,
|
||
uint8_t rd, uint8_t ra, uint8_t rb) {
|
||
set_byte0(out, prefix, op);
|
||
set_func(out, func);
|
||
set_rd(out, rd);
|
||
set_rs1(out, ra);
|
||
set_rs2(out, rb);
|
||
return instr_len(out);
|
||
}
|
||
|
||
/// @brief 编码 SLOT 形态(LOAD/STORE),返回指令长度。
|
||
inline size_t enc_slot(uint8_t* out, const char* prefix, uint8_t op, uint8_t func,
|
||
uint8_t rd, uint32_t slot) {
|
||
set_byte0(out, prefix, op);
|
||
set_func(out, func);
|
||
set_rd(out, rd);
|
||
set_slot32(out, slot);
|
||
return instr_len(out);
|
||
}
|
||
|
||
/// @brief 编码 IMM 形态(LOADK),返回指令长度。
|
||
inline size_t enc_imm(uint8_t* out, const char* prefix, uint8_t op, uint8_t func,
|
||
uint8_t rd, uint32_t imm) {
|
||
set_byte0(out, prefix, op);
|
||
set_func(out, func);
|
||
set_rd(out, rd);
|
||
set_imm32(out, imm);
|
||
return instr_len(out);
|
||
}
|
||
|
||
/// @brief 编码 JMP(010010 区),返回指令长度。
|
||
inline size_t enc_jmp(uint8_t* out, int32_t off) {
|
||
set_byte0(out, "010010", 0);
|
||
set_func(out, 0);
|
||
set_off32(out, off);
|
||
return instr_len(out);
|
||
}
|
||
|
||
/// @brief 编码 JC 形态(JT/JF,010011 区),返回指令长度。
|
||
inline size_t enc_jc(uint8_t* out, uint8_t op, uint8_t rd, int32_t off) {
|
||
set_byte0(out, "010011", op);
|
||
set_func(out, 0);
|
||
set_rd(out, rd);
|
||
set_off32_jc(out, off);
|
||
return instr_len(out);
|
||
}
|
||
|
||
/// @brief 编码 CALL(010100 区),返回指令长度。
|
||
inline size_t enc_call(uint8_t* out, uint32_t fn_id) {
|
||
set_byte0(out, "010100", 0);
|
||
set_func(out, 0);
|
||
set_fn_id32(out, fn_id);
|
||
return instr_len(out);
|
||
}
|
||
|
||
/// @brief 编码 CAL(010101 区),返回指令长度。
|
||
inline size_t enc_cal(uint8_t* out, uint16_t fb_id, uint32_t slot) {
|
||
set_byte0(out, "010101", 0);
|
||
set_func(out, 0);
|
||
set_fb_id16(out, fb_id);
|
||
set_cal_slot32(out, slot);
|
||
return instr_len(out);
|
||
}
|
||
|
||
/// @brief 编码 SLOT_OFF(LOAD_OFF/STORE_OFF,0010 区),返回指令长度。
|
||
inline size_t enc_slot_off(uint8_t* out, uint8_t op, uint8_t func,
|
||
uint8_t rd, uint32_t slot, int32_t off) {
|
||
set_byte0(out, "0010", op);
|
||
set_func(out, func);
|
||
set_rd(out, rd);
|
||
set_slot32(out, slot);
|
||
set_off32_hi(out, off);
|
||
return instr_len(out);
|
||
}
|
||
|
||
/// @brief 编码 RET(10 区),返回指令长度。
|
||
inline size_t enc_ret(uint8_t* out) {
|
||
set_byte0(out, "10", static_cast<uint8_t>(Op::RET));
|
||
set_func(out, 0);
|
||
return instr_len(out);
|
||
}
|
||
}
|