From b70bea6b541c0b5800815fb26c187922c90cb81c Mon Sep 17 00:00:00 2001 From: chentianya Date: Mon, 24 Aug 2026 10:46:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E6=A1=A3=EF=BC=9A=E6=8C=87=E4=BB=A4?= =?UTF-8?q?=E9=9B=86=E4=BC=98=E5=8C=96=20V2=20=E8=8D=89=E6=A1=88=EF=BC=88?= =?UTF-8?q?=E5=8F=98=E9=95=BF=E6=8C=87=E4=BB=A4/=E6=A7=BD=E8=A1=A8?= =?UTF-8?q?=E5=80=BC=E5=8C=BA/IEC=20=E7=B1=BB=E5=9E=8B=E6=89=A9=E5=B1=95/?= =?UTF-8?q?=E5=BE=85=E7=A1=AE=E8=AE=A4=E9=97=AE=E9=A2=98=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 动机:opcode 位域化、8B 定宽槽浪费、类型扩展、结构体预留、变长指令 - 已定案:变长指令(长度组在 opcode)、寄存器 8 位编号维持、槽表→值区 两级模型、宽度编码进 opcode、初值同文件分段、全 32 位寻址、STATOR2 - 待确认:跳转字节化 / type:4 vs 5 / 长度组映射 / I/Q/M 合并 / 结构体范围 / ST 层类型支持 / 转换规则 / 字面量 - 影响面清单 + 6 阶段实施计划 + 决策历史 --- Doc/isa/指令集优化.md | 171 ++++++++++++++++++++++++++++++++++++++++++ Doc/索引.md | 2 + 2 files changed, 173 insertions(+) create mode 100644 Doc/isa/指令集优化.md diff --git a/Doc/isa/指令集优化.md b/Doc/isa/指令集优化.md new file mode 100644 index 0000000..f562083 --- /dev/null +++ b/Doc/isa/指令集优化.md @@ -0,0 +1,171 @@ +# 指令集优化(V2 草案,型号 STATOR2) + +> 状态:**设计中**。本文汇总「指令集优化」的全部信息:动机、已确认设计决策、 +> 待确认问题、影响面与实施阶段。全部内容为**草案**,未进入实现。 +> 与现状(V1)的关系:V1 编码冻结不可改(opcode 0..33、32bit 指令、8 字节定宽槽), +> 本优化为**全新 V2 架构**,.stb 格式 / 指令字 / 数据模型全部重设计,型号 bump 为 STATOR2。 + +## 1. 背景与动机 + +| # | 现状问题 | 优化方向 | +|---|---|---| +| 1 | opcode 定义草率:34 条按语义乱序编号,无位域结构 | format/宽度**编码进 opcode**,位掩码机械推导 | +| 2 | 8 字节定宽槽浪费:BOOL 只用 1/8 空间 | **变宽紧凑值区**(1/2/8 字节按类型) | +| 3 | 变量区利用率低 | 值区按类型紧凑布局 + 地址 u32(4GB) | +| 4 | 类型只有 BOOL/INT/TIME | 扩展 IEC 整数族(12 种)+ REAL 预留 | +| 5 | 结构体无法支持 | 槽表引用 + 元数据段字段表(预留) | +| 6 | 寄存器上限 256、指令 32bit 固定 | 变长指令(长度编码在 opcode);寄存器编号维持 8 位 | +| 7 | 槽(变量)与初值(数据)耦合在同一格 | **槽表(引用)与值区(数据)解耦** | + +## 2. 已确认设计决策 + +### 2.1 变长指令,长度编码在 opcode + +- 指令长度**不固定**:4 / 8 / 16 字节(32 字节预留) +- **长度组 = 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 扩展区 +``` + +| 长度组 | 指令长度 | 覆盖格式 | 字段 | +|---|---|---|---| +| `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 | +| `11` | 32 字节 | 预留 | 超大立即数/未来扩展 | + +- 取指:读字节 0 → `len` 位段定总长 → 搬 4/8/16 字节 +- **位掩码推导**(三件事全编码在头两字节): + - 指令长度 ← `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 宽度/符号表) + +### 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(1 对齐) │ +│ 槽 0..n_slots-1 │ │ INT 2B(2 对齐) │ +└─────────────────────────┘ │ TIME 8B(8 对齐) │ + │ 结构体 = 连续字段块(预留) │ + └──────────────────────────┘ +``` + +- 访问:`LOAD rd, slot` → `addr = 槽表[slot].addr` → 值区按 `type` 位段读 1/2/8 字节 +- **两级间接**:每次访问多一次内存读(PLC 规模无感) +- **宽度编码进 opcode**(用户决策):`type` 位段携带宽度 + 符号,VM 无歧义读写(解决 V1 定宽的原因——V1 因"变宽布局无法从槽号推断宽度"而改定宽,V2 用 type 位段化解) +- 对齐规则:1/2/8 字节,编译器布局保证 +- 初值**整合在 .stb 内分段**(用户决策,ELF 式):槽表段 / 值段 / 元数据段并列,单文件 SHA-256 校验 +- 寻址规模(用户决策):**全 32 位**——槽号 u32(2^32 引用)、值区地址 u32(4GB) + +### 2.4 类型系统:IEC 整数族扩展 + +`type` 位段候选:**type:4(16 种)**——14 个 IEC 标量 + REAL + 预留 1;**结构体/字符串/数组不占位段**,走元数据段字段表(`LOADF rd, slot, field_id`,宽度从元数据查) + +| type | 宽度 | 符号 | type | 宽度 | 符号 | +|---|---|---|---|---|---| +| BOOL | 1B | — | SINT | 1B | 有 | +| BYTE | 1B | 无 | INT | 2B | 有 | +| WORD | 2B | 无 | DINT | 4B | 有 | +| DWORD | 4B | 无 | LINT | 8B | 有 | +| LWORD | 8B | 无 | USINT | 1B | 无 | +| TIME | 8B | 有(ms) | UINT | 2B | 无 | +| | | | UDINT | 4B | 无 | +| | | | ULINT | 8B | 无 | + +- **type 位段红利**:CMP/算术按类型自动语义——无符号类型无符号比较、饱和到类型宽度(模板化)、读取按宽度+符号/零扩展 +- 常量表 `tag` 契约升级:tag = type 位段值(0..14) + +### 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 ← 值段 +72..103 型号标识(STATOR2) +104 n_slots ← 新增 +108 n_values ← 新增(值段字节数) +112..127 预留 +``` + +段序:头 → 常量表 → 函数表 → 字节码 → 槽表段 → 值段 → 元数据段(预留) → SHA-256 尾 + +### 2.6 其他定案 + +- **型号 bump**:STATOR1 → **STATOR2**(格式大变,老 .stb 被型号校验明确拒绝) +- **I/Q/M 六条 LOAD/STORE 合并为 LOAD/STORE 两条**(单一值区,语义标签交给 sidecar)——待确认(见 §4) +- 结构体 v1 **只留编码(LOADF + 元数据段)不实现语法**——待确认(见 §4) + +## 3. 与 V1 的差异对照 + +| 项 | V1(现状) | V2(草案) | +|---|---|---| +| 指令长度 | 固定 32bit | **变长 4/8/16B**,长度在 opcode | +| opcode | 0..33 乱序,无位域 | `[len:2\|op:6]` + `[fmt:4\|type:4]` 位域 | +| 寄存器编号 | 8 位(256/帧) | 8 位(256/帧,不变) | +| 变量访问 | 立即数槽号直接寻址 | **槽表引用 → 值区**(两级间接) | +| 槽 | 8B 定宽 | 8B 引用表({addr:u32}) | +| 值区 | 定宽 8B/变量 | **变宽紧凑**(1/2/8B) | +| 宽度信息 | 无(定宽) | **type 位段**(RISC-V lb/lh/lw 式) | +| 类型 | BOOL/INT/TIME | **14 IEC 标量 + REAL 预留** | +| 结构体 | 不支持 | 元数据段字段表(预留) | +| 寻址空间 | 槽 65535(512KB) | 槽 2^32、值区 4GB | +| 初值 | 槽内 | 值段(逻辑分段,同文件) | +| 跳转/pc | 条数单位 | **字节单位**(待确认 §4) | +| 型号 | STATOR1 | STATOR2 | + +## 4. 待确认问题 + +| # | 问题 | 选项 | 推荐 | +|---|---|---|---| +| 1 | **跳转偏移单位字节化**:off32(字节,相对下一条)、pc/code_offset/code_len 全字节单位、code 段 16 字节对齐 | 接受 / 保持条数 | 接受(变长指令下按条数算偏移不成立) | +| 2 | **type 位段宽度**:type:4(16 种,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→DINT→LINT、BYTE→WORD→…)允许、降宽禁止 | 按此 / 全显式 | 隐式升宽 | +| 8 | **字面量**:IEC 进制前缀(2#/8#/16#)是否 v1 支持 | 十进制 only / 进制前缀 | 十进制 only | + +## 5. 影响面清单 + +| 模块 | 改动 | +|---|---| +| isa | Op.h 重排(位域)、Instr.h 变长 pack/拆、Encode disasm 表驱动、Types 宽度/符号表 + 饱和模板化 | +| compiler | machine.toml V2(type 表 14 条 + 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. **规格冻结**:文档先行——本文件确认全部待确认项后,重写指令与映像.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 lb/lh/lw 式,对应「槽表条目带类型」被否) +- 初值组织:用户选「整合 .stb 内分段」(ELF 式) +- 寻址规模:用户选「全 32 位」(槽号 u32 + 地址 u32) +- 指令长度:用户定「变长指令,长度编码在 opcode」;此前 128bit 固定长度方案被否 +- 寄存器:用户定「编号 8 位(256/帧)维持现状」,容量恒定式 8bit×256=16bit×128=32bit×64=64bit×32 +- 类型扩展:用户提出 IEC 整数族 12 种(BYTE..ULINT) diff --git a/Doc/索引.md b/Doc/索引.md index 5b30e71..f5a71f7 100644 --- a/Doc/索引.md +++ b/Doc/索引.md @@ -9,6 +9,7 @@ doc/ isa/指令与映像.md isa/stb文件格式.md isa/指令配置.md + isa/指令集优化.md compiler/编译管线.md compiler/STCompiler使用说明.md compiler/词法.md @@ -27,6 +28,7 @@ doc/ | [`isa/指令与映像.md`](isa/指令与映像.md) | 指令、映像、定宽类型、饱和;**规范以此为准** | | [`isa/stb文件格式.md`](isa/stb文件格式.md) | `.stb` 结构说明(用 line1 真实字节拆解) | | [`isa/指令配置.md`](isa/指令配置.md) | ops.txt:指令登记唯一事实来源、OpTable、屏蔽机制 | +| [`isa/指令集优化.md`](isa/指令集优化.md) | **V2 草案**:变长指令、槽表/值区、IEC 类型扩展、待确认问题 | | [`compiler/编译管线.md`](compiler/编译管线.md) | 编译器边界与管线 | | [`compiler/STCompiler使用说明.md`](compiler/STCompiler使用说明.md) | 构建、用法、工程文件、ST 子集、错误类别 | | [`compiler/词法.md`](compiler/词法.md) | 12.4 词法:关键字表、token、大小写、TIME 字面量 |