Files
Interpreter/Doc/compiler/寄存器码.md
T

133 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 寄存器码(V2
compiler 模块的代码生成。输入:`Project` + `Unit`AST+ `LinkResult`;输出:`.stb` 映像字节(`std::vector<uint8_t>`)。全工程定案见 [`初步计划.md`](../初步计划.md) 12.8,指令/映像布局见 [`指令与映像.md`](../isa/指令与映像.md),槽表/值段格式见 [`stb文件格式.md`](../isa/stb文件格式.md)。
## 做 / 不做
**做**
- 寄存器分配:局部/变量固定寄存器,表达式临时值往后编号,`nregs` 写进函数头
- 跳转先留洞、后回填(字节单位,相对下一条);`AND` / `OR` **必须编成跳转**(短路),禁止两边都算
- 常量表(`LOADK`8B 原始值无 tag,按 func 解释)、全局/实例槽(`LOAD` / `STORE` / `LOAD_OFF` / `STORE_OFF`)、FB 共享体基址访问(`LOAD_PTR` / `STORE_PTR`
- `CALL fn_id` 有界帧;用户 FB **共享体函数化**r1 = 实例指针);内建 `CAL fb_id, 实例槽`
- 拼装映像:V2 头 128B / 函数表 / 常量表 / 字节码 / 槽表 / 值段 + SHA-256 尾部
- `max_stack`MAIN + FUNCTION 调用图 DAG 最坏路径 Σ(12 + nregs×8);递归 = 编译期报错
**不做(第一版)**
- 图染色、SSA、生命周期分析、优化、异常表、闭包
- 函数指针、间接跳转、动态实例
## 存储布局(V2 定案)
| 数据 | 放哪 | 说明 |
|---|---|---|
| PROGRAM / FUNCTION 标量变量与临时 | **寄存器**(函数帧) | 每周期帧保留由 VM 负责(12.9) |
| 全局(含 I/Q/M)与 FB 实例 | **值区**(紧凑变宽,1/2/4/8 对齐) | 槽表条目(8Baddr:u32 + 预留)指到值区偏移;状态跨周期持久 |
- **槽表两级**:指令操作数 = **槽号**(u32)→ 槽表条目 → 值区字节偏移;`slot_addr(slot)` 由 VM/Image 提供
- 全局按 GVL 声明序编槽;**FB 实例 = 1 个槽表条目**,字段在实例基址上按偏移访问(字段偏移编译期按 1/2/4/8 对齐计算,字段类型 = machine.toml `[[fb]]` 表)
- 字段访问 `fb.Q``LOAD_OFF rd, <实例槽>, <偏移>` / `STORE_OFF <实例槽>, <偏移>, rs`16B SLOT+off 指令,调用点/输出读用);FB 共享体函数体内:`LOAD_PTR` / `STORE_PTR rd, r1, <偏移>`16B RS+off,基址寄存器 r1 = 实例指针);I/Q/M 同普通槽(`LOAD` / `STORE`
- 函数帧寄存器:`FUNCTION` 结果固定 **r0**`VAR_INPUT` 从 r1 起按声明序,`VAR` 续后;PROGRAM / FB 变量从 r0 起按声明序
### 调用约定(v1 冻结,VM 12.9 按此实现)
| 项 | 约定 |
|---|---|
| 结果寄存器 | **r0**FUNCTION 结果写入处) |
| 参数寄存器 | **r1..r7**(最多 7 个输入,按声明序) |
| 变量 / 临时 | **全部从 r8 起**(调用约定区不受覆盖) |
| `CALL` | VM 复制当前帧 **r0..r7 → 新帧 r0..r7**(全宽) |
| `RET` | VM 复制当前帧 **r0..r7 → 调用方帧 r0..r7**(r0=结果,r1..r7 原样返回) |
| 函数输入 | 函数体内**只读**(写输入 → codegen error |
- 调用点:实参求值到 r8+ 临时 → `MOVE r(1+i), t``CALL fn_id``MOVE rd, r0`
- 所有 POU 的变量/临时统一 r8 起,故 r1..r7 在调用点可安全覆盖
## 寄存器分配
- 局部变量固定占用前段(0..k-1)
- 表达式临时从 k 起,**语句内递增、语句结束复用基址**(不分析生命周期)
- `nregs` = 全函数临时峰值 + 1
## 表达式与语句的指令模式
```text
字面量 LOADK rd, const_id func = 语言类型;REAL/LREAL 位模式按目标类型装载)
变量读 LOAD rd, slot (帧内直接 MOVE)
字段读 LOAD_OFF rd, <实例槽>, <偏移>
函数调用 <实参求值 → 参数寄存器> CALL fn_id MOVE rd, r0
NOT <operand → t> NOT rd, t
AND/OR 短路(必须跳转):
<lhs → rd> JF(AND)/JT(OR) rd, L_end
<rhs → t> MOVE rd, t
L_end:
比较 <l→t1> <r→t2> CMP_xx rd, t1, t2
算术 <l→t1> <r→t2> ADD/SUB/MUL/DIV rd, t1, t2
负号 <operand → t> NEG rd, t
IF <cond → t> JF t, L_else
<then body> JMP L_end
L_else: (ELSIF 逐级) <elsif cond → t> JF t, L_next ...
L_end:
WHILE L_loop: <cond → t> JF t, L_end <body> JMP L_loop L_end:
FB 调用(用户,共享体):
<每个实参求值 → 临时> STORE_OFF <实例槽>, <字段偏移>, 临时
LOADK r1, <实例值区地址> CALL <fb_fn_id>
(FB 函数体内:字段访问 = LOAD_PTR/STORE_PTR rd, r1, <字段偏移>
内建 实参同左 → CAL <fb_id>, <实例槽>
```
- 常量统一进常量表(8B 原始值,位模式去重;BOOL / 整数 / 时间 / 浮点 / 日期),`const_id` = 首次出现序;`LOADK` 按 func 解释位模式
- 指令 func 位段 = 语言类型对应(`func_of_name`:宽度 × 符号 + F32/F64
## 用户 FB 共享体(函数化,2026-08-26 实施)
FB 体共享会与「绝对字段地址」冲突(不同实例基址不同),V1 内联;V2 改为**共享体函数化**:
- FB 编译为**独立共享函数**(fn_id 收集序):`r1` = 实例指针(值区地址,隐藏参数/this),字段访问 `LOAD_PTR/STORE_PTR rd, r1, 字段偏移`
- 调用点:实参 `STORE_OFF`(绝对槽)→ `LOADK r1, c(实例addr)``CALL fb_fn_id`2 条指令替代整个展开体)
- 嵌套(FB 函数内调 FUNCTION):实参区 r1..r7 会覆盖实例指针 → 调用点自动 `MOVE t, r1` / 调用后 `MOVE r1, t` 保护
- `VAR_TEMP` 落 FB 帧寄存器,帧每周期重建 → 天然每次调用重置(内联期的寄存器隔离 hack 退役)
- 多实例共享同一函数体,状态经 r1 指针隔离(`count``VAR` 仍在实例字段)
- FB 无递归、无动态实例(链接层保证),函数化安全
## 映像拼装(V2
```text
头 128Bmagic / version=2 / model=STATOR2 / cycle_limit / dt_ms / 工程哈希 /
entry_fn_id / n_globals / n_consts / n_funcs / 各段偏移 /
n_slots / values_size / meta / max_stack
函数表:收集序 fn_id → { nregs, code_offset(相对字节码段), code_len }
常量表:const_id → { value:u64 }(无 tag
字节码:各函数指令连续
槽表:每条目 8Baddr:u32 + 预留:u32
值段:全局 + FB 实例紧凑变宽
尾部:SHA-256(覆盖头部到值段末尾)
```
-`isa``enc_*` 编码指令(变长 4/8/16/32B,前缀分区)
- 工程哈希用 12.3 的 `compute_project_hash`FNV-1a 64
- `--dump-map` 可打印变量/槽映射(对照源码 ↔ 反汇编)
## 错误
稳定前缀 `codegen error`
```text
codegen error: register overflow (>256) in function 'f'
codegen error: constant table overflow
codegen error: no storage for 'x'
codegen error: no instance 't' in 'MAIN'
codegen error: recursive CALL/FB nesting too deep
```
## 完成标准
1. `line1` 能写出映像(函数字节码 + 槽表/值段 + 工程哈希 + SHA-256),`StbView` 校验通过
2. 跳转回填无悬空(`--disasm` 抽查)
3. 用例 19、13、15、17、18、20 编译出映像;负例(10/11/12/14/16/19)仍在前层被拒
4. 全部构建 + `ctest` 无回归(14/14