落地 isa 合同:饱和类型、操作码枚举、32-bit 指令编解码。
- Types.h:TIME 改 int64_t(毫秒),补 sat_add/sub/mul/div,除零与 INT_MIN/-1 规则 - Op.h:29 条操作码枚举 + mnemonic 助记符,数值即编码 - Instr.h:pack/拆字段 + 按形态 enc_rr/rrr/imm/jmp/jc/slot/call/ret
This commit is contained in:
@@ -0,0 +1,93 @@
|
|||||||
|
/**
|
||||||
|
* @file Instr.h
|
||||||
|
* @brief 32-bit 指令打包 / 拆字段
|
||||||
|
* @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。
|
||||||
|
// 字段含义按操作码形态解释,见 Doc/isa/指令与映像.md。
|
||||||
|
typedef uint32_t Instr;
|
||||||
|
|
||||||
|
// 打包 / 拆字段
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Op op(Instr w) {
|
||||||
|
return static_cast<Op>(w & 0xFFu);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint8_t rd(Instr w) {
|
||||||
|
return static_cast<uint8_t>((w >> 8) & 0xFFu);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint8_t a(Instr w) {
|
||||||
|
return static_cast<uint8_t>((w >> 16) & 0xFFu);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint8_t b(Instr w) {
|
||||||
|
return static_cast<uint8_t>((w >> 24) & 0xFFu);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组合视图:a|b 拼成 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组合视图:a|b 为有符号相对偏移,单位是指令条数
|
||||||
|
inline int16_t off16(Instr w) {
|
||||||
|
return static_cast<int16_t>(imm16(w));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按形态的便捷编码
|
||||||
|
inline Instr enc_rr(Op op, uint8_t rd, uint8_t rs) {
|
||||||
|
return pack(op, rd, rs, 0); // MOVE / NOT:a = rs
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Instr enc_rrr(Op op, uint8_t rd, uint8_t ra, uint8_t rb) {
|
||||||
|
return pack(op, rd, ra, rb); // AND/OR/ADD/.../CMP_xx
|
||||||
|
}
|
||||||
|
|
||||||
|
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)); // LOADK
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Instr enc_jc(Op op, uint8_t r, int16_t off) {
|
||||||
|
// JT / JF:条件寄存器在 rd,偏移在 a|b
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Instr enc_slot(Op op, uint8_t rd, uint16_t slot) {
|
||||||
|
// LOAD_I / STORE_Q / LOAD_M / STORE_M / LOAD_GLOBAL / STORE_GLOBAL / CAL_*
|
||||||
|
// 槽号 / 实例号在 a|b
|
||||||
|
return enc_imm(op, rd, slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Instr enc_call(uint16_t fn_id) {
|
||||||
|
return enc_imm(Op::CALL, 0, fn_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Instr enc_ret() {
|
||||||
|
return pack(Op::RET, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* @file Op.h
|
||||||
|
* @brief 操作码枚举 + 助记符
|
||||||
|
* @author
|
||||||
|
* @date 2026-08-19
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace isa {
|
||||||
|
// 操作码一次列全。数值即编码:冻结后不得改顺序、不得插值,
|
||||||
|
// 增加指令只能追加到末尾,并同步 Doc/isa/指令与映像.md 与测试。
|
||||||
|
enum class Op : uint8_t {
|
||||||
|
MOVE = 0, // MOVE rd, rs
|
||||||
|
LOADK = 1, // LOADK rd, const_id
|
||||||
|
NOT = 2, // NOT rd, rs
|
||||||
|
AND = 3, // AND rd, ra, rb
|
||||||
|
OR = 4, // OR rd, ra, rb
|
||||||
|
ADD = 5, // ADD rd, ra, rb
|
||||||
|
SUB = 6, // SUB rd, ra, rb
|
||||||
|
MUL = 7, // MUL rd, ra, rb
|
||||||
|
DIV = 8, // DIV rd, ra, rb
|
||||||
|
CMP_EQ = 9, // CMP_EQ rd, ra, rb
|
||||||
|
CMP_NE = 10, // CMP_NE rd, ra, rb
|
||||||
|
CMP_LT = 11, // CMP_LT rd, ra, rb
|
||||||
|
CMP_LE = 12, // CMP_LE rd, ra, rb
|
||||||
|
CMP_GT = 13, // CMP_GT rd, ra, rb
|
||||||
|
CMP_GE = 14, // CMP_GE rd, ra, rb
|
||||||
|
JMP = 15, // JMP offset
|
||||||
|
JT = 16, // JT r, offset
|
||||||
|
JF = 17, // JF r, offset
|
||||||
|
LOAD_I = 18, // LOAD_I rd, slot
|
||||||
|
STORE_Q = 19, // STORE_Q slot, rs
|
||||||
|
LOAD_M = 20, // LOAD_M rd, slot
|
||||||
|
STORE_M = 21, // STORE_M slot, rs
|
||||||
|
LOAD_GLOBAL = 22, // LOAD_GLOBAL rd, slot
|
||||||
|
STORE_GLOBAL = 23, // STORE_GLOBAL slot, rs
|
||||||
|
CAL_TON = 24, // CAL_TON instance_slot
|
||||||
|
CAL_TOF = 25, // CAL_TOF instance_slot
|
||||||
|
CAL_CTU = 26, // CAL_CTU instance_slot
|
||||||
|
CALL = 27, // CALL fn_id
|
||||||
|
RET = 28, // RET
|
||||||
|
};
|
||||||
|
|
||||||
|
// 操作码总数
|
||||||
|
static const int kOpCount = 29;
|
||||||
|
|
||||||
|
// 助记符:下标与 Op 数值一一对应
|
||||||
|
inline const char* mnemonic(Op op) {
|
||||||
|
static const char* const kMnemonic[kOpCount] = {
|
||||||
|
"MOVE", "LOADK", "NOT", "AND", "OR",
|
||||||
|
"ADD", "SUB", "MUL", "DIV",
|
||||||
|
"CMP_EQ", "CMP_NE", "CMP_LT", "CMP_LE", "CMP_GT", "CMP_GE",
|
||||||
|
"JMP", "JT", "JF",
|
||||||
|
"LOAD_I", "STORE_Q", "LOAD_M", "STORE_M",
|
||||||
|
"LOAD_GLOBAL", "STORE_GLOBAL",
|
||||||
|
"CAL_TON", "CAL_TOF", "CAL_CTU",
|
||||||
|
"CALL", "RET",
|
||||||
|
};
|
||||||
|
const int idx = static_cast<int>(op);
|
||||||
|
return (idx >= 0 && idx < kOpCount) ? kMnemonic[idx] : "???";
|
||||||
|
}
|
||||||
|
}
|
||||||
+41
-3
@@ -8,13 +8,51 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace isa {
|
namespace isa {
|
||||||
namespace types {
|
namespace types {
|
||||||
// 定宽类型。整数溢出规则:饱和(夹到 INT 最小/最大),
|
// 定宽类型。整数溢出规则:饱和(夹到 INT 最小/最大),
|
||||||
// 由 compiler 与 vm 按同一规则实现,见 Doc/isa/指令与映像.md。
|
// 由 compiler 与 vm 按同一规则实现,见 Doc/isa/指令与映像.md。
|
||||||
using BOOL = uint8_t;
|
using BOOL = uint8_t; // 只允许 0/1
|
||||||
using INT = int16_t;
|
using INT = int16_t; // IEC INT
|
||||||
using TIME = uint64_t;
|
// 毫秒,有符号。64 位理由见 Doc/isa/指令与映像.md:
|
||||||
|
// 差值可负、为 DATE_AND_TIME 与 64 位定时器预留。槽位按 8 字节对齐。
|
||||||
|
using TIME = int64_t;
|
||||||
|
|
||||||
|
// 饱和算术:夹到 INT 最小/最大,编译期与 VM 共用同一规则。
|
||||||
|
|
||||||
|
inline INT sat_add(INT a, INT b) {
|
||||||
|
const int32_t sum = static_cast<int32_t>(a) + static_cast<int32_t>(b);
|
||||||
|
return static_cast<INT>(sum < std::numeric_limits<INT>::min() ? std::numeric_limits<INT>::min()
|
||||||
|
: sum > std::numeric_limits<INT>::max() ? std::numeric_limits<INT>::max()
|
||||||
|
: sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline INT sat_sub(INT a, INT b) {
|
||||||
|
const int32_t diff = static_cast<int32_t>(a) - static_cast<int32_t>(b);
|
||||||
|
return static_cast<INT>(diff < std::numeric_limits<INT>::min() ? std::numeric_limits<INT>::min()
|
||||||
|
: diff > std::numeric_limits<INT>::max() ? std::numeric_limits<INT>::max()
|
||||||
|
: diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline INT sat_mul(INT a, INT b) {
|
||||||
|
const int32_t prod = static_cast<int32_t>(a) * static_cast<int32_t>(b);
|
||||||
|
return static_cast<INT>(prod < std::numeric_limits<INT>::min() ? std::numeric_limits<INT>::min()
|
||||||
|
: prod > std::numeric_limits<INT>::max() ? std::numeric_limits<INT>::max()
|
||||||
|
: prod);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline INT sat_div(INT a, INT b) {
|
||||||
|
// b == 0 视为除以 1,避免未定义行为;除零的语义由 compiler/VM 层报错
|
||||||
|
if (b == 0) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
// INT_MIN / -1 溢出:饱和到 INT_MAX
|
||||||
|
if (a == std::numeric_limits<INT>::min() && b == -1) {
|
||||||
|
return std::numeric_limits<INT>::max();
|
||||||
|
}
|
||||||
|
return static_cast<INT>(a / b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user