/** * @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 #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((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(code[3]) | (static_cast(code[4]) << 8) | (static_cast(code[5]) << 16) | (static_cast(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(static_cast(code[2]) | (static_cast(code[3]) << 8) | (static_cast(code[4]) << 16) | (static_cast(code[5]) << 24)); } /// @brief 取 off32(55..24 = 字节 3..6,JC 形态,有符号)。 inline int32_t off32_jc_of(const uint8_t* code) { return static_cast(static_cast(code[3]) | (static_cast(code[4]) << 8) | (static_cast(code[5]) << 16) | (static_cast(code[6]) << 24)); } /// @brief 取 fn_id32(47..16 = 字节 2..5)。 inline uint32_t fn_id32_of(const uint8_t* code) { return static_cast(code[2]) | (static_cast(code[3]) << 8) | (static_cast(code[4]) << 16) | (static_cast(code[5]) << 24); } /// @brief 取 fb_id16(31..16 = 字节 2..3)。 inline uint16_t fb_id16_of(const uint8_t* code) { return static_cast(code[2] | (static_cast(code[3]) << 8)); } /// @brief 取 CAL 实例槽号(63..32 = 字节 4..7)。 inline uint32_t cal_slot32_of(const uint8_t* code) { return static_cast(code[4]) | (static_cast(code[5]) << 8) | (static_cast(code[6]) << 16) | (static_cast(code[7]) << 24); } /// @brief 取 SLOT_OFF 的 off32(87..56 = 字节 7..10,有符号)。 inline int32_t off32_hi_of(const uint8_t* code) { return static_cast(static_cast(code[7]) | (static_cast(code[8]) << 8) | (static_cast(code[9]) << 16) | (static_cast(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(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((prefix[1] == '1' ? 0xC0 : 0x80) | (op & 0x3F)); } else if (prefix[0] == '0') { if (prefix[1] == '1' && prefix[2] == '1') { out[0] = static_cast(0x60 | (op & 0x1F)); // 011 } else if (prefix[1] == '1') { // 010xxx:形态位 3 位 + 子 op 2 位 const uint8_t shape = static_cast( (prefix[3] - '0') * 4 + (prefix[4] - '0') * 2 + (prefix[5] - '0')); out[0] = static_cast(0x40 | (shape << 2) | (op & 0x03)); } else if (prefix[2] == '1') { out[0] = static_cast(0x20 | (op & 0x0F)); // 0010/0011 } else { out[0] = static_cast(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((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(v & 0xFF); out[4] = static_cast((v >> 8) & 0xFF); out[5] = static_cast((v >> 16) & 0xFF); out[6] = static_cast((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(v); out[2] = static_cast(u & 0xFF); out[3] = static_cast((u >> 8) & 0xFF); out[4] = static_cast((u >> 16) & 0xFF); out[5] = static_cast((u >> 24) & 0xFF); } inline void set_off32_jc(uint8_t* out, int32_t v) { // JC:字节 3..6 const uint32_t u = static_cast(v); out[3] = static_cast(u & 0xFF); out[4] = static_cast((u >> 8) & 0xFF); out[5] = static_cast((u >> 16) & 0xFF); out[6] = static_cast((u >> 24) & 0xFF); } inline void set_fn_id32(uint8_t* out, uint32_t v) { set_off32(out, static_cast(v)); } inline void set_fb_id16(uint8_t* out, uint16_t v) { out[2] = static_cast(v & 0xFF); out[3] = static_cast((v >> 8) & 0xFF); } inline void set_cal_slot32(uint8_t* out, uint32_t v) { out[4] = static_cast(v & 0xFF); out[5] = static_cast((v >> 8) & 0xFF); out[6] = static_cast((v >> 16) & 0xFF); out[7] = static_cast((v >> 24) & 0xFF); } inline void set_off32_hi(uint8_t* out, int32_t v) { // SLOT_OFF:字节 7..10 const uint32_t u = static_cast(v); out[7] = static_cast(u & 0xFF); out[8] = static_cast((u >> 8) & 0xFF); out[9] = static_cast((u >> 16) & 0xFF); out[10] = static_cast((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((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(Op::RET)); set_func(out, 0); return instr_len(out); } }