- Types.h:定宽类型、TypeTag、饱和四则的 @brief/@param/@return - Op.h:Op 枚举冻结约束、OpFormat/OpClass、OpDef/kOpDefs 表、三个查询函数 - Instr.h:指令字布局、pack/拆字段、按形态 enc_* 系列 - Encode.h/.cpp:Decoded 字段语义、encode/decode/disasm 契约
176 lines
5.2 KiB
C++
176 lines
5.2 KiB
C++
/**
|
||
* @file Instr.h
|
||
* @brief 32-bit 指令字打包 / 拆字段
|
||
* @details 指令字布局:`[ op:8 | rd:8 | a:8 | b:8 ]`,整体是一个小端 uint32_t。
|
||
* 字段含义按操作码形态解释,见 Doc/isa/指令与映像.md。
|
||
* @author
|
||
* @date 2026-08-19
|
||
*/
|
||
|
||
#pragma once
|
||
|
||
#include <cstdint>
|
||
|
||
#include "isa/Op.h"
|
||
|
||
namespace isa {
|
||
/// 指令字:`[ op:8 | rd:8 | a:8 | b:8 ]`,小端 uint32_t。
|
||
typedef uint32_t Instr;
|
||
|
||
/**
|
||
* @brief 打包:四个字段拼成一条指令字。
|
||
* @param op 操作码(低 8 位)
|
||
* @param rd 目标寄存器 / 条件寄存器(第 8..15 位)
|
||
* @param a 源寄存器 / 立即数低 8 位 / 偏移低 8 位(第 16..23 位)
|
||
* @param b 源寄存器 / 立即数高 8 位 / 偏移高 8 位(第 24..31 位)
|
||
* @return 打包后的指令字
|
||
*/
|
||
inline Instr pack(Op op, uint8_t rd, uint8_t a, uint8_t b) {
|
||
return static_cast<uint32_t>(static_cast<uint8_t>(op))
|
||
| (static_cast<uint32_t>(rd) << 8)
|
||
| (static_cast<uint32_t>(a) << 16)
|
||
| (static_cast<uint32_t>(b) << 24);
|
||
}
|
||
|
||
/**
|
||
* @brief 取操作码。
|
||
* @param w 指令字
|
||
* @return 低 8 位解释为 Op
|
||
*/
|
||
inline Op op(Instr w) {
|
||
return static_cast<Op>(w & 0xFFu);
|
||
}
|
||
|
||
/**
|
||
* @brief 取目标寄存器字段。
|
||
* @param w 指令字
|
||
* @return rd(第 8..15 位)
|
||
*/
|
||
inline uint8_t rd(Instr w) {
|
||
return static_cast<uint8_t>((w >> 8) & 0xFFu);
|
||
}
|
||
|
||
/**
|
||
* @brief 取 a 字段。
|
||
* @param w 指令字
|
||
* @return a(第 16..23 位)
|
||
*/
|
||
inline uint8_t a(Instr w) {
|
||
return static_cast<uint8_t>((w >> 16) & 0xFFu);
|
||
}
|
||
|
||
/**
|
||
* @brief 取 b 字段。
|
||
* @param w 指令字
|
||
* @return b(第 24..31 位)
|
||
*/
|
||
inline uint8_t b(Instr w) {
|
||
return static_cast<uint8_t>((w >> 24) & 0xFFu);
|
||
}
|
||
|
||
/**
|
||
* @brief 组合视图:a|b 拼成 16 位无符号数。
|
||
* @param w 指令字
|
||
* @return 小端拼出的 16 位值,用作 const_id / fn_id / slot 号
|
||
*/
|
||
inline uint16_t imm16(Instr w) {
|
||
return static_cast<uint16_t>(a(w) | (static_cast<uint16_t>(b(w)) << 8));
|
||
}
|
||
|
||
/**
|
||
* @brief 组合视图:a|b 为有符号相对偏移。
|
||
* @param w 指令字
|
||
* @return 偏移量,单位是指令条数(跳转目标 = 下一条指令 + off)
|
||
*/
|
||
inline int16_t off16(Instr w) {
|
||
return static_cast<int16_t>(imm16(w));
|
||
}
|
||
|
||
/**
|
||
* @brief 按 RR 形态编码。
|
||
* @param op 操作码(MOVE / NOT)
|
||
* @param rd 目标寄存器
|
||
* @param rs 源寄存器(放进 a)
|
||
* @return 指令字
|
||
*/
|
||
inline Instr enc_rr(Op op, uint8_t rd, uint8_t rs) {
|
||
return pack(op, rd, rs, 0);
|
||
}
|
||
|
||
/**
|
||
* @brief 按 RRR 形态编码。
|
||
* @param op 操作码(AND/OR/ADD/.../CMP_xx)
|
||
* @param rd 目标寄存器
|
||
* @param ra 第一源寄存器
|
||
* @param rb 第二源寄存器
|
||
* @return 指令字
|
||
*/
|
||
inline Instr enc_rrr(Op op, uint8_t rd, uint8_t ra, uint8_t rb) {
|
||
return pack(op, rd, ra, rb);
|
||
}
|
||
|
||
/**
|
||
* @brief 按 IMM 形态编码。
|
||
* @param op 操作码(LOADK)
|
||
* @param rd 目标寄存器
|
||
* @param imm 16 位立即数(const_id),拆成 a|b 存放
|
||
* @return 指令字
|
||
*/
|
||
inline Instr enc_imm(Op op, uint8_t rd, uint16_t imm) {
|
||
return pack(op, rd, static_cast<uint8_t>(imm & 0xFFu),
|
||
static_cast<uint8_t>((imm >> 8) & 0xFFu));
|
||
}
|
||
|
||
/**
|
||
* @brief 按 JMP 形态编码。
|
||
* @param off 有符号相对偏移(条数),拆成 a|b 存放
|
||
* @return 指令字
|
||
*/
|
||
inline Instr enc_jmp(int16_t off) {
|
||
return pack(Op::JMP, 0,
|
||
static_cast<uint8_t>(static_cast<uint16_t>(off) & 0xFFu),
|
||
static_cast<uint8_t>((static_cast<uint16_t>(off) >> 8) & 0xFFu));
|
||
}
|
||
|
||
/**
|
||
* @brief 按 JC 形态编码(条件跳转)。
|
||
* @param op 操作码(JT / JF)
|
||
* @param r 条件寄存器(放进 rd)
|
||
* @param off 有符号相对偏移(条数),放进 a|b
|
||
* @return 指令字
|
||
*/
|
||
inline Instr enc_jc(Op op, uint8_t r, int16_t off) {
|
||
return pack(op, r,
|
||
static_cast<uint8_t>(static_cast<uint16_t>(off) & 0xFFu),
|
||
static_cast<uint8_t>((static_cast<uint16_t>(off) >> 8) & 0xFFu));
|
||
}
|
||
|
||
/**
|
||
* @brief 按 SLOT 形态编码。
|
||
* @param op 操作码(LOAD_I / STORE_Q / LOAD_M / STORE_M / LOAD_GLOBAL / STORE_GLOBAL / CAL_*)
|
||
* @param rd 目标寄存器(CAL_* 时置 0)
|
||
* @param slot 槽号 / 实例号,放进 a|b
|
||
* @return 指令字
|
||
*/
|
||
inline Instr enc_slot(Op op, uint8_t rd, uint16_t slot) {
|
||
return enc_imm(op, rd, slot);
|
||
}
|
||
|
||
/**
|
||
* @brief 按 CALL 形态编码。
|
||
* @param fn_id 函数表下标,放进 a|b
|
||
* @return 指令字
|
||
*/
|
||
inline Instr enc_call(uint16_t fn_id) {
|
||
return enc_imm(Op::CALL, 0, fn_id);
|
||
}
|
||
|
||
/**
|
||
* @brief 按 NONE 形态编码(RET)。
|
||
* @return 指令字
|
||
*/
|
||
inline Instr enc_ret() {
|
||
return pack(Op::RET, 0, 0, 0);
|
||
}
|
||
}
|