指令集优化:V2 核心决策全部定案(type:5/格式合并/19 类型/禁隐式转换/进制前缀)

- §2.1 字节布局 [len:2|op:6]+[type:5|fmt:3];格式 9→7 形态(CALL→IMM、CAL→SLOT)
- §2.4 19 IEC 基础类型(+DATE/TOD/DT)+13 预留;浮点/进制前缀/禁隐式转换+字面量适配
- §2.6 LOADF 取消、FB 共享体定案(16B 变体=基址寻址)
- §4 改为 A1..A10 尚未确定细节(元数据段/常量内嵌/FB 字段类型化/日期字面量/
  算术语义/sidecar/disasm/machine.toml schema/字面量推断/CALL 确认)
- 编译器优化.md 同步定案状态
This commit is contained in:
2026-08-24 11:19:40 +08:00
parent 109f9a7619
commit 6e8b9896f2
2 changed files with 119 additions and 99 deletions
+24 -22
View File
@@ -36,9 +36,8 @@
### 3.1 FB 共享体(基址寻址)——消除内联膨胀
- **现状问题**:FB 每调用一次复制一份体,字节码膨胀
- **V2 案**槽表模型下引入**基址寻址指令**`LOAD/STORE rd, base_slot, field_off`,base 槽取自寄存器/立即数,16B 长度组已预留)→ FB 体编译**一次**,运行时按实例基址定位字段
- 收益:字节码不再随调用点膨胀;代价:每次字段访问多一个基址操作数
- **待确认**:见指令集优化.md §4 项 9(推荐实施)
- **V2 案**`LOAD/STORE rd, slot, off32`16B 长度组,SLOT+off 形态)即基址寻址——结构体字段与 FB 共享体字段**同一指令**(LOADF 已取消);FB 体编译**一次**,运行时按实例槽 + 编译期算死的字段偏移定位
- 收益:字节码不再随调用点膨胀;代价:每次字段访问多一个偏移操作数
### 3.2 类型驱动语义(type 位段红利)
@@ -60,39 +59,42 @@
### 3.5 类型系统扩展(ST 层)
- 12 个 IEC 整数类型 + REAL/LREAL 进关键字(全量支持:声明即可用)
- 类型检查:**隐式升宽**允许(SINT→INT→DINT→LINT、BYTE→WORD→…)、降宽禁止
- 浮点字面量`1.5``-2.5e3`v1 是否支持——待确认
- **19 个 IEC 基础类型**(BOOL + 位串 4 + 有符号 4 + 无符号 4 + TIME + REAL/LREAL + DATE/TOD/DT)全量进关键字(声明即可用)
- **进制前缀**`2#`/`8#`/`16#` 字面量 + 浮点十进制字面量(`1.5``-2.5e3`
- 类型检查:**禁止隐式变量转换**(赋值/比较/算术类型严格一致,编译期报错);**字面量按上下文适配**`5` 可赋 INT/REAL/DINT,编译期解释);显式转换函数 v1 不做
- 进制字面量默认类型归属与适配细则 → 指令集优化.md §4 项 A9
## 4. 待确认(引用指令集优化.md §4 中编译器相关
## 4. 已定案(编译器相关)
| 项 | 问题 | 推荐 |
|---|---|---|
| 4 | I/Q/M 六条 LOAD/STORE 合并为两条 | 合并 |
| 5 | 结构体 v1 只留编码不实现语法 | 预留 |
| 6 | ST 层类型全量支持(12 类型名进关键字 | 全量 |
| 7 | 隐式升宽允许、降宽禁止 | 按此 |
| 8 | 字面量:十进制 only(含浮点字面量) | 十进制 |
| 9 | FB 共享体:基址寻址指令实施 | 实施 |
| 10 | REAL/LREAL 引入后 type:4 满编 | 满编(结构体走元数据) |
| 项 | 定案 |
|---|---|
| I/Q/M | 六条合并为 LOAD/STORE 两条(单一值区,语义标签交给 sidecar) |
| 结构体 | v1 只留编码LOAD/STORE 16B 变体 + 元数据段),语法不实现 |
| ST 层类型 | 19 类型名全量进关键字 |
| 类型转换 | 禁止隐式变量转换;字面量按上下文适配 |
| 字面量 | 进制前缀 2#/8#/16# + 浮点十进制 |
| FB 共享体 | 实施16B 变体 = 基址寻址) |
仍待闭合的细节见指令集优化.md §4(A1..A10,编译器相关:A5 算术语义 / A6 sidecar / A8 machine.toml schema / A9 字面量类型推断)。
## 5. 影响面(编译器侧)
| 子模块 | 改动 |
|---|---|
| Lexer | 类型关键字扩展(14 → 16+)、浮点字面量(若确认) |
| Lexer | 类型关键字扩展(19)、进制前缀 + 浮点字面量 |
| Parser | 类型引用、字面量 AST |
| Typecheck | 隐式升宽规则、16 类型元数据 |
| Typecheck | 隐式转换(严格一致)+ 字面量上下文适配、19 类型元数据 |
| Linker | 槽表条目分配(addr:u32)、FB 实例字段偏移 |
| Codegen | E_* 变长发射、字节化回填、槽表+值区 layout、FB 共享体(若实施)、基址寻址 |
| MachineConfig / machine.toml | type 表 16 条(base/width/signed/tag)、fmt/type 位段互锁校验 |
| Codegen | E_* 变长发射、字节化回填、槽表+值区 layout、FB 共享体(16B 变体) |
| MachineConfig / machine.toml | type 表 19 条(base/width/signed/tag)、fmt/type 位段互锁校验 |
## 6. 实施阶段(合并进指令集优化.md §6)
- 阶段 2isa)后接**阶段 3compiler 侧)**machine.toml V2 → MachineConfig → Codec → Codegen(槽表/值区/变长发射)→ Stb → 对应测试
- FB 共享体(§3.1若确认实施,并入阶段 3 的 Codegen 子步骤
- FB 共享体(§3.1 已定案)并入阶段 3 的 Codegen 子步骤
## 7. 决策历史
- V1 定案(12.8):用户 FB 内联 / FUNCTION CALL / 内建 FB CAL_*;短路必须跳转;固定寄存器分配
- V2 讨论:用户确认 V1 内联现状;提出 V2 用基址寻址消除内联膨胀(写入 §2.7/§4 项 9
- V2 讨论:用户确认 V1 内联现状;提出 V2 用基址寻址消除内联膨胀(已定案
- 类型扩展:19 IEC 基础类型(type:5);禁隐式转换 + 字面量适配;进制前缀定案
+95 -77
View File
@@ -1,7 +1,7 @@
# 指令集优化(V2 草案,型号 STATOR2
# 指令集优化(V2 规格,型号 STATOR2
> 状态:**设计中**。本文汇总「指令集优化」的全部信息:动机、已确认设计决策、
> 待确认问题、影响面与实施阶段。全部内容为**草案**,未进入实现。
> 状态:**规格冻结中**。核心决策已全部定案(§2),本文为 V2 规格草案;
> §4 列出**尚未确定的细节项**,全部闭合后进入实现阶段
> 与现状(V1)的关系:V1 编码冻结不可改(opcode 0..33、32bit 指令、8 字节定宽槽),
> 本优化为**全新 V2 架构**,.stb 格式 / 指令字 / 数据模型全部重设计,型号 bump 为 STATOR2。
@@ -10,38 +10,48 @@
| # | 现状问题 | 优化方向 |
|---|---|---|
| 1 | opcode 定义草率:34 条按语义乱序编号,无位域结构 | format/宽度**编码进 opcode**,位掩码机械推导 |
| 2 | 8 字节定宽槽浪费:BOOL 只用 1/8 空间 | **变宽紧凑值区**1/2/8 字节按类型) |
| 2 | 8 字节定宽槽浪费:BOOL 只用 1/8 空间 | **变宽紧凑值区**1/2/4/8 字节按类型) |
| 3 | 变量区利用率低 | 值区按类型紧凑布局 + 地址 u32(4GB) |
| 4 | 类型只有 BOOL/INT/TIME | 扩展 IEC 整数族12 种)+ REAL 预留 |
| 5 | 结构体无法支持 | 槽表引用 + 元数据段字段表(预留) |
| 6 | 寄存器上限 256、指令 32bit 固定 | 变长指令(长度编码在 opcode);寄存器编号维持 8 位 |
| 4 | 类型只有 BOOL/INT/TIME | 扩展 IEC 全基础类型19 种) |
| 5 | 结构体无法支持 | 槽表引用 + LOAD 16B 变体(基槽+偏移,预留) |
| 6 | 指令 32bit 固定 | 变长指令(长度编码在 opcode);寄存器编号维持 8 位 |
| 7 | 槽(变量)与初值(数据)耦合在同一格 | **槽表(引用)与值区(数据)解耦** |
## 2. 已确认设计决策
## 2. 已定案设计
### 2.1 变长指令,长度编码在 opcode
- 指令长度**不固定**:4 / 8 / 16 字节(32 字节预留)
- **长度组 = opcode 高 2 位**`[len:2 | op:6]`
- 长度组 = 格式(fmt)的自然覆盖,由格式决定整条长度
- **长度组 = opcode 高 2 位**`[len:2 | op:6]`;长度组 = 操作数形态(fmt)的自然覆盖
```text
字节 0 字节 1 字节 2 字节 3 字节 4 字节 5..13(按长度组)
[len:2|op:6] [fmt:4|type:4] rd:8 rs1:8 rs2:8 扩展
字节 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 |
| `01` | 8 字节 | RRR / JMP / JC / CALL / CAL / IMM / SLOT | 头 + rd + rs1 + rs2 + slot32/fn_id32/off32/const_id32 |
| `10` | 16 字节 | SLOT+off / IMM64 | 头 + rd + rs1 + slot32 + off32/imm64 |
| `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`
- 格式(uses_rd/uses_ra/uses_rb`fmt` 位段`uses_rd = fmt∈{RR,RRR,IMM,SLOT,JC}``uses_ra = fmt∈{RR,RRR}``uses_rb = {RRR}`
- 数据宽度/符号 ← `type` 位段(查 constexpr 宽度/符号表)
- 操作数形态 `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 寄存器模型(维持现状)
@@ -55,39 +65,41 @@
```text
槽表段(静态引用表,8B/条) 值段(初值,紧凑变宽)
┌─────────────────────────┐ ┌──────────────────────────┐
│ { addr:u32, 预留:u32 } │ ──地址──▶ │ BOOL 1B1 对齐)
│ 槽 0..n_slots-1 │ │ INT 2B2 对齐)
└─────────────────────────┘ │ TIME 8B8 对齐)
│ 结构体 = 连续字段块(预留) │
│ { 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/8 字节
- 访问:`LOAD rd, slot``addr = 槽表[slot].addr` → 值区按 `type` 位段读 1/2/4/8 字节;字段访问 `LOAD rd, slot, off32``addr + off`
- **两级间接**:每次访问多一次内存读(PLC 规模无感)
- **宽度编码进 opcode**(用户决策)`type` 位段携带宽度 + 符号,VM 无歧义读写(解决 V1 定宽的原因——V1 因"变宽布局无法从槽号推断宽度"而改定宽,V2 用 type 位段化解)
- 对齐规则:1/2/8 字节,编译器布局保证
- 初值**整合在 .stb 内分段**(用户决策,ELF 式):槽表段 / 值段 / 元数据段并列,单文件 SHA-256 校验
- 寻址规模(用户决策)**全 32 位**——槽号 u32(2^32 引用)、值区地址 u324GB)
- **宽度编码进 opcode**`type` 位段携带宽度 + 符号,VM 无歧义读写(V1 因"变宽布局无法从槽号推断宽度"而改定宽,V2 用 type 位段化解)
- 对齐规则:1/2/4/8 字节,编译器布局保证
- 初值**整合在 .stb 内分段**(ELF 式):槽表段 / 值段 / 元数据段并列,单文件 SHA-256 校验
- 寻址规模:**全 32 位**——槽号 u32(2^32 引用)、值区地址 u324GB)
### 2.4 类型系统:IEC 标量族扩展16满编
### 2.4 类型系统:IEC 全基础类型19type:5
`type` 位段**type:416 种)**16 个 IEC 标量**满编零预留**BOOL + 位串 4 + 有符号 4 + 无符号 4 + TIME + REAL + LREAL);**结构体/字符串/数组不占位段**,走元数据段字段表(`LOADF rd, slot, field_id`,宽度从元数据查)。将来新增标量类型需扩 type:5(32 种)——待确认(见 §4 项 2)。
`type` 位段 **type:532 种)**19 个 IEC 基础类型 + 13 预留;结构体/字符串/数组不占位段(组合类型走元数据段)。
| type | 类型 | 宽度 | 符号 | C 对应 | type | 类型 | 宽度 | 符号 | C 对应 |
|---|---|---|---|---|---|---|---|---|---|
| 0 | BOOL | 1B | — | bool | 8 | LINT | 8B | | int64_t |
| 1 | BYTE | 1B | 无 | uint8_t | 9 | USINT | 1B | 无 | uint8_t |
| 2 | WORD | 2B | 无 | uint16_t | 10 | UINT | 2B | 无 | uint16_t |
| 3 | DWORD | 4B | 无 | uint32_t | 11 | UDINT | 4B | | uint32_t |
| 4 | LWORD | 8B | 无 | uint64_t | 12 | ULINT | 8B | 无 | uint64_t |
| 5 | SINT | 1B | 有 | int8_t | 13 | TIME | 8B | 有(ms) | int64_t |
| 6 | INT | 2B | 有 | int16_t | 14 | **REAL** | 4B | IEEE754 | **float** |
| 7 | DINT | 4B | 有 | int32_t | 15 | **LREAL** | 8B | IEEE754 | **double** |
| 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 重解释
- 常量表 `tag` 契约升级:tag = type 位段值(0..15),REAL=14 / LREAL=15 存位模式
- **ST 字面量**浮点十进制字面量(`1.5``-2.5e3`v1 是否支持——待确认(见 §4 项 10)
- 常量表 `tag` 契约升级:tag = type 位段值(0..18
- **ST 层**:19 类型名全量进关键字;**进制前缀** `2#`/`8#`/`16#` 支持(浮点无前缀);浮点十进制字面量(`1.5``-2.5e3`
- **类型转换**:**禁止隐式变量转换**(赋值/比较/算术要求类型严格一致,Typecheck 阶段报错);**字面量按上下文适配**(`5` 可赋 INT/REAL/DINT 等,编译期解释,非运行时转换);显式转换函数(`INT_TO_REAL()`v1 不做
### 2.5 映像格式(头 128 字节,16 对齐)
@@ -95,7 +107,7 @@
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 ← 值段
68 offset_values ← 值段(原 offset_data 改义)
72..103 型号标识(STATOR2
104 n_slots ← 新增
108 n_values ← 新增(值段字节数)
@@ -106,64 +118,67 @@
### 2.6 其他定案
- **型号 bump**STATOR1 → **STATOR2**(格式大变,老 .stb 被型号校验明确拒绝)
- **I/Q/M 六条 LOAD/STORE 合并为 LOAD/STORE 两条**(单一值区,语义标签交给 sidecar)——待确认(见 §4
- 结构体 v1 **只留编码(LOADF + 元数据段)不实现语法**——待确认(见 §4
- **型号 bump**STATOR1 → **STATOR2**
- **I/Q/M 六条 LOAD/STORE 合并为 LOAD/STORE 两条**(单一值区,语义标签交给 sidecar)
- **LOADF 取消**:结构体/FB 字段访问统一用 LOAD/STORE 16B 变体(基槽 + 偏移
- **FB 共享体实施**:16B 变体即基址寻址指令,FB 体编译一次消除内联膨胀
- 结构体语法 v1 **不实现**,只留编码路径(16B 变体 + 元数据段)
### 2.7 调用与内联策略(V1 现状 + V2 方向)
**V1 现状**POU 调用三种处理方式:
**V1 现状**
| 对象 | V1 处理 | 原因 |
|---|---|---|
| 用户 FBFUNCTION_BLOCK | **调用点内联展开**(字节码随调用点数膨胀) | 12.8 定案:FB 体访问**绝对字段地址**`LOAD_GLOBAL rd, 基槽+字段序`,不同实例基址不同,共享函数体无法复用;无递归、无动态实例 → 内联安全 |
| FUNCTIONFC | 独立函数 + `CALL fn_id` 帧栈 | FC 无状态,参数/结果走寄存器约定(r1..r7 / r0),无字段地址冲突;递归在前层被拒(用例 19 |
| 用户 FBFUNCTION_BLOCK | **调用点内联展开**(字节码随调用点数膨胀) | 12.8 定案:FB 体访问**绝对字段地址**,不同实例基址不同,共享体无法复用 |
| FUNCTIONFC | 独立函数 + `CALL fn_id` 帧栈 | FC 无状态,寄存器约定(r1..r7 / r0),无地址冲突;递归在前层被拒 |
| 内建 FBTON/CTU/…) | `CAL_*` 指令(VM 运行时原语 `do_cal`) | 定时器/计数器是 VM 侧状态机,天然共享 |
代价:内联 = 字节码膨胀(FB 每调用一次复制一份体),V1 规模可接受;寄存器码.md 注记「以后可升级为基址寄存器寻址指令」
**V2 机会**:槽表模型下 FB 体可共享——FB 实例字段经「槽表条目 → 值区地址」定位,若引入**基址寻址指令**(如 `LOAD rd, base_slot, field_off` / `STORE base_slot, field_off, rs`,base 槽取自寄存器或立即数),FB 体编译一次、运行时按实例基址定位字段,**消除内联膨胀**。16 字节长度组(SLOT+off)已为此预留。是否实施 → 待确认(见 §4 项 9)。
**V2 定案**16B 变体 `LOAD/STORE rd, slot, off` = 基址寻址——FB 体编译一次,运行时按实例槽定位字段,**消除内联膨胀**。FUNCTION 仍走 CALL 帧栈;内建 FB 仍走 CAL(SLOT 形态,实例号即槽号)
## 3. 与 V1 的差异对照
| 项 | V1(现状) | V2案) |
| 项 | V1(现状) | V2案) |
|---|---|---|
| 指令长度 | 固定 32bit | **变长 4/8/16B**,长度在 opcode |
| opcode | 0..33 乱序,无位域 | `[len:2\|op:6]` + `[fmt:4\|type:4]` 位域 |
| 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/8B |
| 宽度信息 | 无(定宽) | **type 位段**RISC-V lb/lh/lw 式) |
| 类型 | BOOL/INT/TIME | **14 IEC 标量 + REAL 预留** |
| 结构体 | 不支持 | 元数据段字段表(预留 |
| FB 调用 | 用户 FB **内联展开**(字节码膨胀) | 基址寻址指令共享 FB 体(待确认 §4 |
| 值区 | 定宽 8B/变量 | **变宽紧凑**1/2/4/8B |
| 宽度信息 | 无(定宽) | **type 位段**RISC-V 式) |
| 类型 | BOOL/INT/TIME | **19 IEC 基础类型 + 13 预留** |
| 字段访问 | 无(FB 内联) | **LOAD/STORE rd, slot, off**(结构体/FB 共用 |
| FB 调用 | 用户 FB **内联展开** | **基址寻址共享体**(消除膨胀 |
| 寻址空间 | 槽 65535512KB | 槽 2^32、值区 4GB |
| 初值 | 槽内 | 值段(逻辑分段,同文件) |
| 跳转/pc | 条数单位 | **字节单位**(待确认 §4 |
| 跳转/pc | 条数单位 | **字节单位** |
| 型号 | STATOR1 | STATOR2 |
## 4. 待确认问题
## 4. 尚未确定项(细节,待逐项闭合)
| # | 问题 | 选项 | 推荐 |
|---|---|---|---|
| 1 | **跳转偏移单位字节化**:off32(字节,相对下一条)、pc/code_offset/code_len 全字节单位、code 段 16 字节对齐 | 接受 / 保持条数 | 接受(变长指令下按条数算偏移不成立) |
| 2 | **type 位段宽度**type:416 种,14 标量+REAL+预留 1,结构体走元数据)vs type:5(32 种,寄存器位段借位) | type:4 / type:5 | type:4 + 元数据段 |
| 3 | **长度组映射**00=4B、01=8B、10=16B、11=32B 预留 | 接受 / 2B 粒度 | 接受 4/8/16 |
| 4 | **I/Q/M 合并**:六条 LOAD_I/M/GLOBAL、STORE_Q/M/GLOBAL 合并为 LOAD/STORE 两条 | 合并 / 保留 | 合并 |
| 5 | **结构体 v1 范围**:只留编码(LOADF + 元数据段)不实现语法 | 预留 / 实现 | 预留 |
| 6 | **ST 语言层类型支持**:12 类型名进关键字全量支持 vs 仅类型系统支持 | 全量 / 仅系统 | 全量(声明即可用) |
| 7 | **类型转换规则**:隐式升宽(SINT→INT→DINTLINT、BYTE→WORD→…)允许、降宽禁止 | 按此 / 全显式 | 隐式升宽 |
| 8 | **字面量**IEC 进制前缀(2#/8#/16#)是否 v1 支持 | 十进制 only / 进制前缀 | 十进制 only |
| 9 | **FB 共享体**:基址寻址指令(LOAD/STORE rd, base_slot, field_off)消除用户 FB 内联膨胀 | 实施 / 维持内联 | 实施(16B 长度组已预留 |
| 10 | **REAL/LREAL**:浮点类型与 C float/double 对应(4B/8BIEEE 754);type 位段随之满编 16 标量(零预留) | type:4 满编 / type:5 留扩展 | 见 §2.4 |
核心决策已全部定案,以下为进入实现前需闭合的设计细节:
| # | 项 | 说明 |
|---|---|---|
| A1 | 元数据段格式 | 结构体/字符串的表 schema(类型描述、字段表条目)——v1 预留但格式未定 |
| A2 | 常量内嵌 vs 常量表 | LOADK8B IMMconst_id32 查常量表)与 IMM64(16B,内嵌 64 位值)的分工——TIME/ULINT/LREAL 常量走哪条 |
| A3 | 内建 FB 字段类型化 | CAL_* 的实例字段在 V2 值区是类型化布局(TON.et=TIME、q=BOOL 等),字段宽度/偏移怎么定 |
| A4 | DATE/TOD/DT 字面量 | IEC 语法 `D#2026-8-24``TOD#12:30:00``DT#2026-8-24-12:30:00` 是否 v1 支持 |
| A5 | 算术语义细化 | 各宽度饱和规则(SINT/DINT/LINT 模板)、TIME/DATE 运算(TIME+TIME、TIME 比较)、浮点比较(NaN/±inf 语义) |
| A6 | sidecar/I/O 绑定 | V2 下绑定粒度(槽号不变?绑定到槽表引用)、channel/bit 语义 |
| A7 | disasm 文本格式 | V2 指令文本(含 type/off 的打印形式 |
| A8 | machine.toml V2 schema | type 表 19 条字段(base/width/signed/tag)、op 表字段(fmt/type 位段互锁) |
| A9 | 字面量类型推断细则 | 进制字面量默认类型归属(`16#FF` 是 BYTE/WORD/DINT?)、赋不同目标类型的适配规则 |
| A10 | CALL 在 V2 的确认 | 帧/寄存器约定不变(r0..r7 复制),但变长指令下 ret_pc 字节化;CALL 的 IMM 形态 rd 字段约定 |
## 5. 影响面清单
| 模块 | 改动 |
|---|---|
| isa | Op.h 重排(位域)、Instr.h 变长 pack/拆、Encode disasm 表驱动、Types 宽度/符号表 + 饱和模板化 |
| compiler | machine.toml V2type 表 14 条 + fmt/type 位段)、MachineConfig 互锁校验、Codec 变长、Codegen(槽表+值区布局、初值写值段、E_* 发射器)、Stb 新头/段 |
| compiler | machine.toml V2type 表 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 个重新生成产物 |
@@ -171,7 +186,7 @@
## 6. 实施阶段(每阶段独立可验证 + 提交)
1. **规格冻结**文档先行——本文件确认全部待确认项后,重写指令与映像.md / 指令配置.md / stb文件格式.md
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
@@ -182,11 +197,14 @@
- 动机源起:用户质疑 opcode 定义草率;探索 format 位前缀编码(方案 A)与 uses_rd 位掩码推导
- 数据模型演进:8B 定宽槽 →(用户提出槽表引用 + 初值分离)→ 槽表/值区两级模型
- 宽度信息:用户选「宽度编码进 opcode」(RISC-V lb/lh/lw 式,对应「槽表条目带类型」被否)
- 宽度信息:用户选「宽度编码进 opcode」(RISC-V 式,对应「槽表条目带类型」被否)
- 初值组织:用户选「整合 .stb 内分段」(ELF 式)
- 寻址规模:用户选「全 32 位」(槽号 u32 + 地址 u32
- 指令长度:用户定「变长指令,长度编码在 opcode」;此前 128bit 固定长度方案被否
- 寄存器:用户定「编号 8 位(256/帧)维持现状」,容量恒定式 8bit×256=16bit×128=32bit×64=64bit×32
- 类型扩展:用户提出 IEC 整数族BYTE..ULINT 12 种+ REAL/LREAL= C float/doubleIEEE 754
- 调用策略:确认 V1 用户 FB 内联 / FUNCTION 走 CALL / 内建 FB 走 CAL_*;V2 探索基址寻址指令消除内联膨胀
- 类型扩展:用户提出 IEC 整数族 12 种(BYTE..ULINT
- 类型扩展:IEC 整数族 12 种 + REAL/LREAL= C float/double+ DATE/TOD/DT → **19 种,type:532 种)**
- 格式合并:用户确认原子类型固定后选位段方案;数位得出 type:5CALL→IMM、CAL→SLOT 形态合并,fmt 3 位
- 调用策略:V1 用户 FB 内联 / FC CALL / 内建 CAL_*V2 用 16B 变体(基槽+偏移)实现 FB 共享体
- LOADF 取消:用户指出 LOADF 与 LOAD 无本质区别(仅数据搬运)→ 字段访问统一 LOAD/STORE 16B 变体
- 类型转换:用户定「禁止隐式变换,编译阶段检查」+ 字面量按上下文适配
- 字面量:用户定支持 IEC 进制前缀(2#/8#/16#