Files
Interpreter/isa/include/isa/Instr.h
T
Admin 4f3da55ed7 阶段4-1:isa 重构 V2 完成(Types/Op/Instr/Encode + isa_test 91 checks)
- 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 同步
2026-08-26 09:56:43 +08:00

305 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @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 取 rd23..16 = 字节 2)。
inline uint8_t rd_of(const uint8_t* code) { return code[2]; }
/// @brief 取 rs131..24 = 字节 3)。
inline uint8_t rs1_of(const uint8_t* code) { return code[3]; }
/// @brief 取 rs239..32 = 字节 4)。
inline uint8_t rs2_of(const uint8_t* code) { return code[4]; }
/// @brief 取 imm3255..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 取 off3247..16 = 字节 2..5JMP 形态,有符号)。
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 取 off3255..24 = 字节 3..6JC 形态,有符号)。
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_id3247..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_id1631..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 的 off3287..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 取 imm6487..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') {
// 11bit7..6 = 1110bit7..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 编码 JMP010010 区),返回指令长度。
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/JF010011 区),返回指令长度。
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 编码 CALL010100 区),返回指令长度。
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 编码 CAL010101 区),返回指令长度。
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_OFFLOAD_OFF/STORE_OFF0010 区),返回指令长度。
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 编码 RET10 区),返回指令长度。
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);
}
}