# 指令集优化(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)的自然覆盖 ```text 字节 0 字节 1 字节 2..n(按长度组) [len:2 | op:6] [type:5 | fmt:3] 操作数区 ``` | 位段 | 宽度 | 内容 | |---|---|---| | 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 数据模型:槽表(引用)→ 值区(数据) ```text 槽表段(静态引用表,8B/条) 值段(初值,紧凑变宽) ┌─────────────────────────┐ ┌──────────────────────────┐ │ { addr:u32, 预留:u32 } │ ──地址──▶ │ BOOL 1B / INT 2B(对齐) │ │ 槽 0..n_slots-1 │ │ DINT·REAL 4B / TIME 8B │ └─────────────────────────┘ │ 结构体 = 连续字段块(预留) │ └──────────────────────────┘ ``` - 访问:`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 对齐) ```text 0..71 原 15 字段(magic/版本/cycle_limit/dt_ms/hash/entry/n_globals/n_i/n_q/n_m/ n_consts/n_funcs + offset_const/funcs/code) 64 offset_slots ← 槽表段(原 offset_fb 改义,FB 并入值区) 68 offset_values ← 值段(原 offset_data 改义) 72..103 型号标识(STATOR2) 104 n_slots ← 新增 108 n_values ← 新增(值段字节数) 112..127 预留 ``` 段序:头 → 常量表 → 函数表 → 字节码 → 槽表段 → 值段 → 元数据段(预留) → 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. 实施阶段(每阶段独立可验证 + 提交) 1. **规格冻结**:本文 §4 全部闭合后,重写指令与映像.md / 指令配置.md / stb文件格式.md 2. **isa 重构**:变长 Instr + 位域 Op + Encode + isa_test 3. **compiler 侧**:machine.toml V2 + MachineConfig + Codec + Codegen + Stb + 对应测试 4. **vm 侧**:Image + Machine(两级访问)+ vm_test 5. **executor + 全链路**:cases 20 个 + cli 测试 + line1 产物重生成 6. **文档收尾**:指令执行推演、扫描周期、初步计划、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/帧(容量恒定式) | 「寄存器大小不变,8bit*256 == 16bit*128 == ...」 | | 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 舍入模式)在实现时定稿。