指令集优化(V2 规格,型号 STATOR2)
状态:规格冻结中。核心决策已全部定案(§2),本文为 V2 规格草案;
§4 列出尚未确定的细节项,全部闭合后进入实现阶段。
与现状(V1)的关系:V1 编码冻结不可改(opcode 0..33、32bit 指令、8 字节定宽槽),
本优化为全新 V2 架构,.stb 格式 / 指令字 / 数据模型全部重设计,型号 bump 为 STATOR2。
1. 背景与动机
| # |
现状问题 |
优化方向 |
| 1 |
opcode 定义草率:34 条按语义乱序编号,无位域结构 |
format/宽度编码进 opcode,位掩码机械推导 |
| 2 |
8 字节定宽槽浪费:BOOL 只用 1/8 空间 |
变宽紧凑值区(1/2/4/8 字节按类型) |
| 3 |
变量区利用率低 |
值区按类型紧凑布局 + 地址 u32(4GB) |
| 4 |
类型只有 BOOL/INT/TIME |
扩展 IEC 全基础类型(19 种) |
| 5 |
结构体无法支持 |
槽表引用 + LOAD 16B 变体(基槽+偏移,预留) |
| 6 |
指令 32bit 固定 |
变长指令(长度编码在 opcode);寄存器编号维持 8 位 |
| 7 |
槽(变量)与初值(数据)耦合在同一格 |
槽表(引用)与值区(数据)解耦 |
2. 已定案设计
2.1 变长指令,长度编码在 opcode
- 指令长度不固定:4 / 8 / 16 字节(32 字节预留)
- 长度组 = opcode 高 2 位:
[len:2 | op:6];长度组 = 操作数形态(fmt)的自然覆盖
| 位段 |
宽度 |
内容 |
| len |
2 |
4 / 8 / 16B + 32B 预留 |
| op |
6 |
主操作码(64 空间,实际约 30 个) |
| type |
5 |
32 种:19 IEC 基础类型 + 13 预留 |
| fmt |
3 |
8 种形态:RR、RRR、IMM、SLOT、JMP、JC、NONE、预留 |
格式合并(9 → 7 种形态):CALL 并入 IMM(fn_id 即 32 位立即数,rd 未用)、CAL 并入 SLOT(实例号即槽号,rd 未用)——形态相同,指令身份由 op 位段区分。
| 长度组 |
指令长度 |
覆盖形态 |
操作数区 |
00 |
4 字节 |
NONE / RR |
rd + rs1(各 1B) |
01 |
8 字节 |
RRR / IMM / SLOT / JMP / JC |
+ rs2 + slot32/fn_id32/const_id32/off32 |
10 |
16 字节 |
SLOT+off(字段访问)/ IMM64 |
+ slot32 + off32/imm64 |
11 |
32 字节 |
预留 |
超大立即数/未来扩展 |
- 取指:读字节 0 →
len 位段定总长 → 搬 4/8/16 字节
- 位掩码推导(全部编码在头 2 字节):
- 指令长度 ←
len 组
- 操作数形态 ←
fmt:uses_rd = fmt∈{RR,RRR,IMM,SLOT,JC}、uses_ra = fmt∈{RR,RRR}、uses_rb = {RRR}(CALL/CAL 的 rd 恒 0,按 fmt 检查无害)
- 数据宽度/符号 ←
type(查 constexpr 宽度/符号表)
- 字段访问统一为 LOAD/STORE 16B 变体:
LOAD rd, slot, off32(基槽 + 偏移,编译期算死)——结构体字段与 FB 共享体字段同一指令,无单独 LOADF
- 跳转偏移字节化:off32(字节,相对下一条);pc/code_offset/code_len 全字节单位;code 段 16 字节对齐
2.2 寄存器模型(维持现状)
- 寄存器编号 = 1 字节(8 位)→ 256 个/帧(定长)
- 编号容量恒定关系:
8bit×256 == 16bit×128 == 32bit×64 == 64bit×32(编号位宽 × 数量反比,总容量恒定)
- 寄存器值仍 8 字节(int64);codegen
register overflow (>256) 检查保留
- 调用约定不变:r0 结果、r1..r7 参数、r8+ 变量/临时
2.3 数据模型:槽表(引用)→ 值区(数据)
- 访问:
LOAD rd, slot → addr = 槽表[slot].addr → 值区按 type 位段读 1/2/4/8 字节;字段访问 LOAD rd, slot, off32 → addr + off
- 两级间接:每次访问多一次内存读(PLC 规模无感)
- 宽度编码进 opcode:
type 位段携带宽度 + 符号,VM 无歧义读写(V1 因"变宽布局无法从槽号推断宽度"而改定宽,V2 用 type 位段化解)
- 对齐规则:1/2/4/8 字节,编译器布局保证
- 初值整合在 .stb 内分段(ELF 式):槽表段 / 值段 / 元数据段并列,单文件 SHA-256 校验
- 寻址规模:全 32 位——槽号 u32(2^32 引用)、值区地址 u32(4GB)
2.4 类型系统:IEC 全基础类型(19 种,type:5)
type 位段 type:5(32 种):19 个 IEC 基础类型 + 13 预留;结构体/字符串/数组不占位段(组合类型走元数据段)。
| type |
类型 |
宽度 |
符号 |
C 对应 |
type |
类型 |
宽度 |
符号 |
C 对应 |
| 0 |
BOOL |
1B |
— |
bool |
10 |
UINT |
2B |
无 |
uint16_t |
| 1 |
BYTE |
1B |
无 |
uint8_t |
11 |
UDINT |
4B |
无 |
uint32_t |
| 2 |
WORD |
2B |
无 |
uint16_t |
12 |
ULINT |
8B |
无 |
uint64_t |
| 3 |
DWORD |
4B |
无 |
uint32_t |
13 |
TIME |
8B |
有(ms) |
int64_t |
| 4 |
LWORD |
8B |
无 |
uint64_t |
14 |
REAL |
4B |
IEEE754 |
float |
| 5 |
SINT |
1B |
有 |
int8_t |
15 |
LREAL |
8B |
IEEE754 |
double |
| 6 |
INT |
2B |
有 |
int16_t |
16 |
DATE |
4B |
无 |
uint32_t(天) |
| 7 |
DINT |
4B |
有 |
int32_t |
17 |
TOD |
4B |
无 |
uint32_t(当日 ms) |
| 8 |
LINT |
8B |
有 |
int64_t |
18 |
DT |
8B |
无 |
uint64_t |
| 9 |
USINT |
1B |
无 |
uint8_t |
19..31 |
预留 |
|
|
|
- type 位段红利:CMP/算术按类型自动语义——无符号类型无符号比较、整数饱和到类型宽度(模板化)、浮点走 IEEE 754(无饱和,溢出→±inf)、读取按宽度+符号/零扩展
- 浮点表示:REAL 4B / LREAL 8B,值区 4/8 字节对齐;寄存器 int64 位模式搬运(REAL 低 4 字节),运算时按 type 重解释
- 常量表契约(A2 定案):条目 = 8 字节原始值(无 tag),按位模式去重;
LOADK rd, const_id(8B IMM 形态)用指令 type 位段解释(读 width 字节、按符号扩展),
与 LOAD 语义统一;同一常量可被不同 type 的 LOADK 复用(字面量按上下文适配的落地)。
V1 的 {tag, value} 契约废弃。IMM64 形态(16B 内嵌 64 位值)保留编码、v1 不发射。
- ST 层:19 类型名全量进关键字;进制前缀
2#/8#/16# 支持(浮点无前缀);浮点十进制字面量(1.5、-2.5e3)
- 类型转换:禁止隐式变量转换(赋值/比较/算术要求类型严格一致,Typecheck 阶段报错);字面量按上下文适配(
5 可赋 INT/REAL/DINT 等,编译期解释,非运行时转换);显式转换函数(INT_TO_REAL())v1 不做
2.5 映像格式(头 128 字节,16 对齐)
段序:头 → 常量表 → 函数表 → 字节码 → 槽表段 → 值段 → 元数据段(预留) → SHA-256 尾
2.6 其他定案
- 型号 bump:STATOR1 → STATOR2
- I/Q/M 六条 LOAD/STORE 合并为 LOAD/STORE 两条(单一值区,语义标签交给 sidecar)
- LOADF 取消:结构体/FB 字段访问统一用 LOAD/STORE 16B 变体(基槽 + 偏移)
- FB 共享体实施:16B 变体即基址寻址指令,FB 体编译一次消除内联膨胀
- 结构体语法 v1 不实现,只留编码路径(16B 变体 + 元数据段)
- FB 编码定案(B1/B2):1 条 CAL(SLOT 形态,8B:头 2 + fb_id:16 + slot32)+ fb_id 16 位(查 machine.toml
[[fb]] 表);新增内建 FB 只改配置 + VM 实现,指令格式零变化。V1 的 CAL_TON..CAL_F_TRIG 8 个 opcode 作废
- 领域指令不进指令集(B4 定案):运动控制 / 通信等全部走 FB 库(ST 层 FB + CALL + 共享体),V2 不设 EXT 服务指令——op 位段只承载基础指令
2.7 调用与内联策略(V1 现状 + V2 方向)
V1 现状:
| 对象 |
V1 处理 |
原因 |
| 用户 FB(FUNCTION_BLOCK) |
调用点内联展开(字节码随调用点数膨胀) |
12.8 定案:FB 体访问绝对字段地址,不同实例基址不同,共享体无法复用 |
| FUNCTION(FC) |
独立函数 + CALL fn_id 帧栈 |
FC 无状态,寄存器约定(r1..r7 / r0),无地址冲突;递归在前层被拒 |
| 内建 FB(TON/CTU/…) |
CAL_* 指令(VM 运行时原语 do_cal) |
定时器/计数器是 VM 侧状态机,天然共享 |
V2 定案:16B 变体 LOAD/STORE rd, slot, off = 基址寻址——FB 体编译一次,运行时按实例槽定位字段,消除内联膨胀。FUNCTION 仍走 CALL 帧栈;内建 FB 仍走 CAL(SLOT 形态,实例号即槽号)。
3. 与 V1 的差异对照
| 项 |
V1(现状) |
V2(定案) |
| 指令长度 |
固定 32bit |
变长 4/8/16B,长度在 opcode |
| opcode |
0..33 乱序,无位域 |
[len:2|op:6] + [type:5|fmt:3] 位域 |
| 格式 |
9 种(RR/RRR/IMM/SLOT/JMP/JC/CALL/CAL/NONE) |
7 种形态(CALL→IMM、CAL→SLOT 合并)+ 1 预留 |
| 寄存器编号 |
8 位(256/帧) |
8 位(256/帧,不变) |
| 变量访问 |
立即数槽号直接寻址 |
槽表引用 → 值区(两级间接) |
| 槽 |
8B 定宽 |
8B 引用表({addr:u32}) |
| 值区 |
定宽 8B/变量 |
变宽紧凑(1/2/4/8B) |
| 宽度信息 |
无(定宽) |
type 位段(RISC-V 式) |
| 类型 |
BOOL/INT/TIME |
19 IEC 基础类型 + 13 预留 |
| 字段访问 |
无(FB 内联) |
LOAD/STORE rd, slot, off(结构体/FB 共用) |
| FB 调用 |
用户 FB 内联展开 |
基址寻址共享体(消除膨胀) |
| 寻址空间 |
槽 65535(512KB) |
槽 2^32、值区 4GB |
| 初值 |
槽内 |
值段(逻辑分段,同文件) |
| 跳转/pc |
条数单位 |
字节单位 |
| 型号 |
STATOR1 |
STATOR2 |
4. 尚未确定项(细节,待逐项闭合)
核心决策已全部定案,以下为进入实现前需闭合的设计细节:
| # |
项 |
状态 |
| A1 |
元数据段格式 |
结构体/字符串的表 schema——v1 预留但格式未定(待定) |
A2 |
常量内嵌 vs 常量表 |
已定案:常量表(8B LOADK 查表);LOADK 用 type 位段解释;条目 8B 无 tag;IMM64 预留不发射 |
| A3 |
内建 FB 字段类型化 |
已定案:字段类型化(TON: in/pt/q/et = BOOL/TIME/BOOL/TIME;R_TRIG: clk/q = BOOL/BOOL);计数器单/双字(INT/DINT)编码形式 = CAL 的 type 位段给计数宽度(B3,说明中待确认) |
| A4 |
DATE/TOD/DT 字面量 |
已定案:v1 不支持(类型存在,仅声明/存取/比较,无 D#/TOD#/DT# 字面量语法) |
| A5 |
算术语义细化 |
已定案:饱和模板化到各宽度(SINT/DINT/LINT);TIME+TIME / TIME-TIME / TIME 比较;浮点 IEEE 常规(溢出→±inf、0 除→±inf、NaN 传播,无特判);DATE/TOD/DT 不做运算(仅存取/比较) |
| A6 |
sidecar/I/O 绑定 |
已定案:与现状一致——绑定粒度仍 slot = 槽号(指向槽表条目),channel/bit 语义不变 |
| A7 |
disasm 文本格式 |
已定案:类型后缀形式:LOAD.I16 r5, s3、STORE.U32 s1, r7、ADD.F64 r1, r2, r3 |
| A8 |
machine.toml V2 schema |
已定案:type 表 = 编译器内建基元别名(bit/int8/int16/int32/int64/uint8/uint16/uint32/uint64/float32/float64):REAL→base float32(=C float)、LREAL→base float64(=C double),其余按位宽/符号映射;op 表 {name, op(0..63), fmt} + fmt/type 位段互锁校验 |
A9 |
字面量类型推断 |
已定案:按上下文适配;默认 DINT 仅作兜底语义(上下文恒存在,正常程序不触发) |
A10 |
FB 编码 |
已定案(B1/B2):1 CAL + fb_id 16 位(查 fb 表);新增 FB 只改配置 + VM 实现 |
另:CALL 的 V2 确认(随 A10)——ret_pc 字节化(随跳转已定);CALL(IMM 形态)rd 恒 0;帧/寄存器约定不变(r0..r7 复制)。
未定 / 待细化(C1..C6)
| # |
项 |
说明 |
| C1 |
元数据段格式(原 A1) |
结构体/字符串表 schema——v1 预留但格式未定;建议 v1 定「0 长度占位段,schema 延后」 |
| C2 |
头 128B 布局终稿 |
§2.5 字段表(64/68 改义、n_slots/n_values)需与 A8 schema 最终核对 |
| C3 |
machine.toml [[fb]] 表 schema |
fb_id/name/字段类型(含单/双字计数 width 列)细则——随 B3 定 |
| C4 |
CALL/CAL 的 rd 字段约定成文 |
已定「恒 0」,待写入规范文档 |
| C5 |
line1 推演重算 |
实施阶段(阶段 5)才需要 |
| C6 |
CTU/CTD/CTUD 字段表终稿 |
pv/cv 定 INT/DINT 后,字段宽度/对齐/偏移终稿(随 B3 定) |
8. 待讨论(用户反问)
A9:什么情况下会没有上下文?(已定案)
ST 中字面量只能出现在表达式/赋值里(x := 5、y + 5、IF 16#FF > t THEN),
目标类型或运算操作数类型恒在,v1 无"裸字面量"位置——上下文恒存在。
因此"默认 DINT"只是防御性兜底(编译器内部缺类型时的报错路径),
正常程序不触发。结论:按上下文适配即可,默认 DINT 保留为兜底语义。已确认(2026-08-24)。
A10:FB 为什么会有 8 种?(已定案)
V1 的 CAL_TON..CAL_F_TRIG 是 8 个 opcode(24..31),因为 V1 opcode 充足、无位段压力。
V2 的 op 位段仅 6 位(64 个),FB 占 8 个不划算,且 machine.toml 已有 [[fb]] 表
(8 条,含 opcode 字段)——可收敛为 1 个 CAL(SLOT 形态)+ FB 类型 id(立即数/查 fb 表):
- 收益:op 位段省 7 个;新增 FB(如自定义内建)不加 opcode、只加配置
- 代价:VM 按 id 分派(一次查表,可接受);disasm 需查 fb 表打印名称
- 关联:A3 的单字/双字计数变体编码也随此定(fb 表加 width/type 列即可)
已定案(B1/B2):1 CAL + fb_id 16 位。
后续扩展讨论(B4/B5):领域指令(运动控制/通信)不进指令集——PLCopen 运动控制本
是 FB 库;V2 不设 EXT 服务指令,一切领域功能走 FB 库(CALL + 共享体)。op 位段预算见 B5。
5. 影响面清单
| 模块 |
改动 |
| isa |
Op.h 重排(位域)、Instr.h 变长 pack/拆、Encode disasm 表驱动、Types 宽度/符号表 + 饱和模板化 |
| compiler |
machine.toml V2(type 表 19 条 + fmt/type 位段互锁)、MachineConfig 校验、Codec 变长、Codegen(槽表+值区布局、初值写值段、E_* 变长发射、字节化回填)、Stb 新头/段 |
| vm |
Image 新头/段校验、Machine 取指变长 + 两级访问(槽表→值区)+ 按 type 读写 |
| executor |
slot_bool 按 BOOL 读 1 字节(小改) |
| tests |
isa/vm/machine/codegen/compiler 全部重写;cases 20 个重新生成产物 |
| docs |
指令与映像、指令配置、stb文件格式、寄存器码、指令执行(line1 推演重算)、扫描周期、初步计划、README |
6. 实施阶段(每阶段独立可验证 + 提交)
- 规格冻结:本文 §4 全部闭合后,重写指令与映像.md / 指令配置.md / stb文件格式.md
- isa 重构:变长 Instr + 位域 Op + Encode + isa_test
- compiler 侧:machine.toml V2 + MachineConfig + Codec + Codegen + Stb + 对应测试
- vm 侧:Image + Machine(两级访问)+ vm_test
- executor + 全链路:cases 20 个 + cli 测试 + line1 产物重生成
- 文档收尾:指令执行推演、扫描周期、初步计划、README
7. 决策历史(讨论纪要)
- 动机源起:用户质疑 opcode 定义草率;探索 format 位前缀编码(方案 A)与 uses_rd 位掩码推导
- 数据模型演进:8B 定宽槽 →(用户提出槽表引用 + 初值分离)→ 槽表/值区两级模型
- 宽度信息:用户选「宽度编码进 opcode」(RISC-V 式,对应「槽表条目带类型」被否)
- 初值组织:用户选「整合 .stb 内分段」(ELF 式)
- 寻址规模:用户选「全 32 位」(槽号 u32 + 地址 u32)
- 指令长度:用户定「变长指令,长度编码在 opcode」;此前 128bit 固定长度方案被否
- 寄存器:用户定「编号 8 位(256/帧)维持现状」,容量恒定式 8bit×256=16bit×128=32bit×64=64bit×32
- 类型扩展:IEC 整数族 12 种 + REAL/LREAL(= C float/double)+ DATE/TOD/DT → 19 种,type:5(32 种)
- 格式合并:用户确认原子类型固定后选位段方案;数位得出 type:5;CALL→IMM、CAL→SLOT 形态合并,fmt 3 位
- 调用策略:V1 用户 FB 内联 / FC CALL / 内建 CAL_*;V2 用 16B 变体(基槽+偏移)实现 FB 共享体
- LOADF 取消:用户指出 LOADF 与 LOAD 无本质区别(仅数据搬运)→ 字段访问统一 LOAD/STORE 16B 变体
- 类型转换:用户定「禁止隐式变换,编译阶段检查」+ 字面量按上下文适配
- 字面量:用户定支持 IEC 进制前缀(2#/8#/16#)
- A2 定案:LOADK 用 type 位段解释常量值(与 LOAD 语义统一);常量表条目 8B 无 tag;IMM64 预留不发射
- A3..A8 定案(2026-08-24):计数器单/双字两种;DATE 字面量不支持;TIME/浮点运算按推荐;sidecar 一致;disasm 类型后缀;type 表=基元别名(REAL→float32、LREAL→float64)
- A9 定案:按上下文适配、默认 DINT 兜底(用户确认)
- A10 定案(B1/B2):1 CAL + fb_id 16 位(查 fb 表);V1 的 8 个 CAL_* opcode 作废
- B4 定案:领域指令(运动控制/通信)不进指令集,一律 FB 库;无 EXT 服务指令
- B3/B5 说明中待确认:单/双字计数编码(CAL type 位段)、op 位段预算
- 未定项记录:C1 元数据段 / C2 头终稿 / C3 fb 表 schema / C4 rd 约定成文 / C5 line1 推演 / C6 计数器字段表
9. 确认核验清单(2026-08-24 核对)
原则:未明确回答 ≠ 同意。本清单逐项记录「用户明确回答」与「待确认」,
待确认项由用户逐项表态后闭合。
9.1 已确认(用户明确回答)
| # |
项 |
用户回答 |
| K1 |
变长指令(长度编码在 opcode) |
「变长指令,指令长度编码再opcode里面」 |
| K2 |
寄存器 8 位编号 256/帧(容量恒定式) |
「寄存器大小不变,8bit256 == 16bit128 == ...」 |
| K3 |
宽度编码进 opcode(非槽表带类型) |
question 选「宽度编码进 opcode」 |
| K4 |
初值整合 .stb 内分段(ELF 式) |
question 选「整合在 .stb 内分段」 |
| K5 |
全 32 位寻址(槽号 u32 + 地址 u32) |
question 选「全 32 位寻址」 |
| K6 |
type:5(32 种,含 DATE/TOD/DT 19 基础类型) |
「B」 |
| K7 |
跳转偏移字节化 |
「接受」 |
| K8 |
I/Q/M 六条合并为 LOAD/STORE 两条 |
「合并」 |
| K9 |
LOADF 取消(LOAD/STORE 16B 变体=字段访问) |
「LOADF和普通的LOAD应该没有区别吧」 |
| K10 |
ST 层类型全量(19 类型名进关键字) |
「全量」 |
| K11 |
禁止隐式变量转换(编译期检查) |
「禁止隐式变换,只需要编译阶段检查」 |
| K12 |
进制前缀(2#/8#/16#) |
「进制前缀」 |
| K13 |
A2 常量表(LOADK type 解释、条目 8B 无 tag、IMM64 预留) |
「使用常量表吧」+ 讨论 |
| K14 |
A3 计数单字/双字两种都要 |
「需要两种,单字的和双字的计数指令都要有」 |
| K15 |
A4 DATE/TOD/DT 字面量 v1 不支持 |
「先不支持」 |
| K16 |
A5 算术语义(饱和模板/TIME±/浮点 IEEE/DATE 不运算) |
「先做吧」 |
| K17 |
A6 sidecar 绑定粒度一致(slot=槽号) |
「应该可以保持一致」 |
| K18 |
A7 disasm 类型后缀(LOAD.I16 r5, s3) |
「类型后缀」 |
| K19 |
A8 type 表=基元别名(REAL→float32、LREAL→float64) |
「类型:编译器内建基元...float32-float,float64-double」 |
| K20 |
A9 字面量按上下文适配、默认 DINT 兜底 |
「就这么做」 |
| K21 |
B1 fb_id 16 位 |
「16位」 |
| K22 |
B2 1 CAL + fb_id(查 fb 表) |
「cal + fb_id」 |
| K23 |
B4 领域指令不进指令集(运动/通信走 FB 库) |
「不进指令集」 |
9.2 待确认(用户未明确回答)
| # |
事项 |
当前文档写法 |
待表态 |
| U1 |
格式合并 9→7(CALL→IMM、CAL→SLOT,fmt 4→3 位) |
§2.1 已写定案 |
接受 / 改 |
| U2 |
长度组映射 4/8/16/32B(32B 预留) |
§2.1 已写 |
接受 / 改 |
| U3 |
字节布局 [len:2|op:6] + [type:5|fmt:3] 两字节头 |
§2.1 已写 |
接受 / 改 |
| U4 |
结构体 v1 只留编码不实现语法(原问题 5,未答) |
§2.6 已写"不实现" |
预留 / 实现 |
| U5 |
B3 最新方案:fb 表拆条 CTU/DCTU/CTD/DCTD/CTUD/DCTUD(6 计数 + TON/TOF/TP/R_TRIG/F_TRIG = 11 条) |
用户提出,未最终确认 |
定案 / 改 |
| U6 |
B5 op 预算:基础 23 + 余 41,op:6 不扩 |
讨论过,未写文档 |
接受 / 改 |
| U7 |
头 128 字节布局(64/68 改义、n_slots/n_values、型号@72、112..127 预留) |
§2.5 已写 |
未细审,确认 / 改 |
| U8 |
槽表条目 {addr:u32, 预留:u32} 8B |
§2.3 已写 |
确认 / 改 |
| U9 |
值段对齐 1/2/4/8B 编译器保证 |
§2.3 已写 |
确认 / 改 |
| U10 |
寄存器值 int64(8B)不变 + 调用约定 r0..r7 不变 |
§2.2 已写 |
确认 / 改 |
| U11 |
CAL 编码布局(头2 + fb_id:16 + slot32 = 8B) |
讨论过未成文 |
确认 / 改 |
| U12 |
C1 元数据段:v1 定 0 长度占位、schema 延后 |
§4 建议 |
确认 / 改 |
| U13 |
DATE/TOD/DT 表示(uint32 天 / uint32 当日ms / uint64) |
§2.4 已写 |
确认 / 改 |
| U14 |
CALL/CAL 的 rd 恒 0 约定成文 |
讨论过未成文 |
确认 / 改 |
| U15 |
无类型指令 type=NONE(MOVE/跳转/CALL/RET 等) |
§2.1 已写 |
确认 / 改 |
| U16 |
off32 相对下一条公式(目标=当前+off,字节单位) |
§2.1 已写 |
确认 / 改 |
10. 全功能指令集清单(草案,参考)
全功能目标下的完整指令清单。状态列:核心 = v1 实现;扩展 = v1 后实现;预留 = 仅留编码/未来。
组 = 长度组(前缀编码:1=4B、01=8B、001=16B、0001=32B);fmt = 操作数形态。
type 列:有 = 用 type 位段(宽度/符号/浮点语义)、无 = type=NONE、dst = type 位段为转换目标类型。
操作数记法:rd=目标寄存器、rs/ra/rb=源寄存器、slot=槽号、off=字段偏移、const_id=常量表下标、fn_id=函数下标、fb_id=内建 FB id。
10.1 数据搬运
| 指令 |
组 |
fmt |
type |
操作数 |
语义 |
状态 |
| MOVE |
4B |
RR |
无 |
rd, rs |
寄存器间搬运(int64 全宽) |
核心 |
| NOP |
4B |
NONE |
无 |
— |
空操作 |
核心 |
| LOAD |
8B |
SLOT |
有 |
rd, slot |
槽→寄存器(按 type 读宽+扩展) |
核心 |
| STORE |
8B |
SLOT |
有 |
slot, rs |
寄存器→槽(按 type 写宽) |
核心 |
| LOADK |
8B |
IMM |
有 |
rd, const_id |
常量表→寄存器(按 type 解释) |
核心 |
| LOAD_OFF |
16B |
SLOT+off |
有 |
rd, slot, off |
字段读(结构体/FB 共享体) |
核心 |
| STORE_OFF |
16B |
SLOT+off |
有 |
slot, off, rs |
字段写 |
核心 |
| LOADK64 |
16B |
IMM64 |
有 |
rd, imm64 |
64 位立即数内嵌(免查表) |
预留 |
10.2 逻辑与位运算
| 指令 |
组 |
fmt |
type |
操作数 |
语义 |
状态 |
| NOT |
4B |
RR |
有 |
rd, rs |
按 type:BOOL 逻辑非 / 位串取反 |
核心 |
| AND / OR / XOR |
8B |
RRR |
有 |
rd, ra, rb |
按 type 位宽 |
核心 |
| NAND / NOR / XNOR |
8B |
RRR |
有 |
rd, ra, rb |
扩展三态 |
扩展 |
| SHL / SHR |
8B |
RRR |
有 |
rd, rs, n |
左移/右移(SHR 按 type 符号:算术/逻辑) |
扩展 |
| ROL / ROR |
8B |
RRR |
有 |
rd, rs, n |
循环移位(位串) |
扩展 |
| GETBIT |
8B |
RRR |
无 |
rd, rs, bit |
取位(位号在 rb) |
扩展 |
| SETBIT / CLRBIT / TOGBIT |
8B |
RRR |
无 |
slot/rd, rs, bit |
置位/清位/翻转(目标可槽) |
扩展 |
10.3 算术
| 指令 |
组 |
fmt |
type |
操作数 |
语义 |
状态 |
| ADD / SUB / MUL / DIV |
8B |
RRR |
有 |
rd, ra, rb |
整数饱和 / 浮点 IEEE / 无符号按 type |
核心 |
| MOD |
8B |
RRR |
有 |
rd, ra, rb |
取模 |
扩展 |
| NEG |
4B |
RR |
有 |
rd, rs |
取负 |
扩展 |
| ABS |
4B |
RR |
有 |
rd, rs |
绝对值 |
扩展 |
| INC / DEC |
4B |
RR |
有 |
rd, rs |
自增/自减 |
扩展 |
| EXPT |
8B |
RRR |
有 |
rd, ra, rb |
幂(整数/浮点) |
扩展 |
| SQRT |
4B |
RR |
有 |
rd, rs |
平方根 |
扩展 |
| SIN / COS / TAN / ASIN / ACOS / ATAN |
4B |
RR |
有 |
rd, rs |
三角函数(浮点) |
扩展 |
| LN / LOG / EXP |
4B |
RR |
有 |
rd, rs |
对数/指数(浮点) |
扩展 |
| ROUND / TRUNC / FLOOR / CEIL |
4B |
RR |
有 |
rd, rs |
舍入(浮点→整数) |
扩展 |
10.4 比较
| 指令 |
组 |
fmt |
type |
操作数 |
语义 |
状态 |
| CMP_EQ / NE / LT / LE / GT / GE |
8B |
RRR |
有 |
rd, ra, rb |
按 type:有/无符号/浮点/IEEE(NaN 传播) |
核心 |
10.5 转换
| 指令 |
组 |
fmt |
type |
操作数 |
语义 |
状态 |
| CONV |
4B |
RR |
dst |
rd, rs |
类型转换(dst 在 type 位段;src 值已在寄存器,按 dst 宽度截断/扩展/舍入) |
扩展 |
| TRUNC(并入 CONV 舍入模式) |
— |
— |
— |
— |
舍入模式由 CONV 的 op 变体或独立指令(见上) |
扩展 |
10.6 控制流
| 指令 |
组 |
fmt |
type |
操作数 |
语义 |
状态 |
| JMP |
8B |
JMP |
无 |
off32 |
无条件跳转(相对下一条,字节) |
核心 |
| JT / JF |
8B |
JC |
无 |
rd, off |
rd≠0/==0 跳转 |
核心 |
| CALL |
8B |
IMM |
无 |
fn_id |
压帧调用(r0..r7 复制) |
核心 |
| RET |
4B |
NONE |
无 |
— |
弹帧 / MAIN 周期结束 |
核心 |
| CAL |
8B |
SLOT |
无 |
fb_id, slot |
内建 FB 调用(fb_id 查 fb 表) |
核心 |
| JTBL |
32B |
预留 |
无 |
rd, slot, n |
CASE 跳转表 |
预留 |
10.7 内建 FB(CAL + fb_id,fb 表)
| fb_id |
FB |
字段(类型化) |
状态 |
| 0 |
TON |
in/pt/q/et = BOOL/TIME/BOOL/TIME |
核心 |
| 1 |
TOF |
同上 |
核心 |
| 2 |
TP |
同上 |
核心 |
| 3 |
CTU |
cu/r/pv(INT)/q/cv(INT) 单字 |
核心 |
| 4 |
DCTU |
cu/r/pv(DINT)/q/cv(DINT) 双字 |
核心 |
| 5 |
CTD |
cd/ld/pv(INT)/q/cv(INT) |
核心 |
| 6 |
DCTD |
cd/ld/pv(DINT)/q/cv(DINT) |
核心 |
| 7 |
CTUD |
cu/cd/r/lu/pv(INT)/qu/qd/cv(INT) |
核心 |
| 8 |
DCTUD |
cu/cd/r/lu/pv(DINT)/qu/qd/cv(DINT) |
核心 |
| 9 |
R_TRIG |
clk/q = BOOL/BOOL |
核心 |
| 10 |
F_TRIG |
clk/q = BOOL/BOOL |
核心 |
| 11 |
SR / RS(锁存) |
s1/r/s/q… |
扩展 |
| 12 |
PWM |
in/pt/q… |
扩展 |
| 13 |
RTC |
日期时钟字段 |
扩展 |
10.8 字符串(未来,元数据段 + 16/32B)
| 指令 |
组 |
fmt |
语义 |
状态 |
| STR_LEN |
16B |
SLOT+off |
字符串长度 |
预留 |
| STR_CMP / STR_EQ |
16B |
SLOT+off |
比较(按元数据段定长/变长) |
预留 |
| STR_CONCAT |
32B |
预留 |
拼接 |
预留 |
| STR_MID / STR_LEFT / STR_RIGHT |
16B/32B |
预留 |
取子串 |
预留 |
| STR_FIND / STR_REPLACE |
32B |
预留 |
查找/替换 |
预留 |
10.9 数组(未来)
| 指令 |
组 |
fmt |
语义 |
状态 |
| ARR_LEN |
16B |
SLOT+off |
数组长度 |
预留 |
| ARR_LOAD / ARR_STORE |
32B |
预留 |
索引访问(基槽+index) |
预留 |
10.10 系统
| 指令 |
组 |
fmt |
语义 |
状态 |
| NOP |
4B |
NONE |
空操作(占位/对齐) |
核心 |
10.11 op 预算核对(前缀编码按组分治)
| 组 |
op 空间 |
v1 核心用量 |
扩展/预留量 |
| 4B(op:7) |
128 |
MOVE/NOP/NOT/RET ≈ 4 |
124(浮点单目/舍入/CONV 等) |
| 8B(op:6) |
64 |
ADD..CMP/LOAD/STORE/LOADK/CALL/CAL/JMP/JT/JF ≈ 19 |
45(位运算/移位/GETBIT 等) |
| 16B(op:5) |
32 |
LOAD_OFF/STORE_OFF ≈ 2 |
30(LOADK64/字符串/数组) |
| 32B(op:4) |
16 |
0 |
16(JTBL/复杂字符串) |
注:以上为全功能目标清单,v1 只实现「核心」列;「扩展/预留」列给出指令格式占位,
具体操作数形态(如 GETBIT 的槽/寄存器目标、CONV 舍入模式)在实现时定稿。