文档同步:machine.toml 配置驱动架构收尾。

- README.md:依赖方向(STCompiler→compiler 不链 isa)、模块表、isa 归执行器侧、
  数据流图(machine.toml + 型号/SHA)
- isa/README.md:重写——只管指令定义(Types/Op/Instr/Encode),删 Image 部分
- 指令与映像.md:依赖图与 CMake(compiler 不链 isa)
- 编译管线.md:管线首步加载 machine.toml、产物含型号/SHA
- 初步计划.md:12.10/12.13 修订(--machine、依赖方向)
- 扫描周期.md / 指令执行.md:12.9 步骤标注已落地、vm 读校验说明
- compiler/vm/executor README:依赖与边界同步
This commit is contained in:
2026-08-21 22:39:27 +08:00
parent 1168f5ae30
commit 6873b5ee0b
10 changed files with 76 additions and 158 deletions
+21 -112
View File
@@ -1,15 +1,15 @@
# isa
指令集 + 映像 + 定宽类型。CMake 目标:`isa``STATIC`),无依赖。
**归执行器侧**,只管指令定义。CMake 目标:`isa``STATIC`),无依赖;被 `vm` 依赖。
`compiler` 写映像、`vm` 读映像,两边只依赖本目录,不互链
`compiler` **不依赖 isa**——指令 opcode / 类型元数据 / FB 布局全部来自 `compiler/machine.toml`(见 [`指令配置.md`](../doc/isa/指令配置.md))。`.stb` 映像读写由 `compiler`(写侧)与 `vm`(读侧)**各自实现**
```text
STCompiler → compiler → isa
BytecodeExecutor → vm → isa
STCompiler → compiler (编码查 machine.toml,自带 .stb 写)
BytecodeExecutor → vm → isa isa 只管指令;vm 自带 .stb 读)
```
**类型、操作码、指令字、映像布局** [`doc/isa/指令与映像.md`](../doc/isa/指令与映像.md) **为准。** 头文件实现该文,本 README 不另当规范。`.stb` 结构面向使用者的拆解见 [`doc/isa/stb文件格式.md`](../doc/isa/stb文件格式.md)。全工程阶段见 [`doc/初步计划.md`](../doc/初步计划.md) 12.012.1
**操作码、指令字以** [`doc/isa/指令与映像.md`](../doc/isa/指令与映像.md) **为准。** 头文件实现该文,本 README 不另当规范。`.stb` 结构拆解见 [`doc/isa/stb文件格式.md`](../doc/isa/stb文件格式.md)。指令/类型/FB 登记见 [`doc/isa/指令配置.md`](../doc/isa/指令配置.md)
公开头:`isa/include/isa/`
@@ -17,139 +17,48 @@ BytecodeExecutor → vm → isa
## 做 / 不做
**做:** 操作码与 32-bit 指令、映像头与段`BOOL`/`INT`/`TIME`与饱和、编解码、工程哈希、一条指令的文本转储。
**做:** 操作码与 32-bit 指令`BOOL`/`INT`/`TIME` 宽与饱和、编解码、一条指令的文本转储。
**不做:** toml、关键字符号表AST、VM `switch`、扫描周期、I/O 采样。`AND`/`OR` 只组合已算好的值;短路由 `compiler` 编成跳转。
**不做:** 映像读写(compiler/vm 各自实现)、toml/关键字/符号表/AST、VM 执行 switch(在 `vm`、扫描周期、I/O 采样。
---
## 实现步骤
原则:先冻合同,再头文件,再 `.cpp`,再最小测试。每步能编过再进下一步。改编码或映像字段时,先改规范文和本模块,再动 `compiler` / `vm`
目标目录(与规范一致):
## 目录与 CMake
```text
isa/
CMakeLists.txt
README.md
include/isa/
Types.h # 宽度、饱和、槽值
Op.h # 操作码枚举 + 助记符
Types.h # 宽度、饱和
Op.h # 操作码枚举 + OpFormat/OpClass + kOpDefs 表 + 助记符
Instr.h # 32-bit 打包/拆字段(inline
Encode.h # encode / decode / disasm
Image.h # 头、段、FNV、读写缓冲
src/
Encode.cpp
Image.cpp
```
```cmake
add_library(isa STATIC src/Encode.cpp src/Image.cpp)
add_library(isa STATIC src/Encode.cpp)
target_include_directories(isa PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
```
`compiler` / `vm``target_link_libraries(... PUBLIC isa)`
`vm``target_link_libraries(vm PUBLIC isa)``compiler` 不链 `isa`
---
### 0. CMake 骨架
## 实现说明
`CMakeLists.txt` `add_subdirectory` `compiler` / `vm` / `executor`。这三个目录若没有 `CMakeLists.txt`,顶层 configure 失败,`isa` 也编不过。
- **`Types.h`**`Bool` = `uint8_t``Int` = `int16_t``Time` = `int64_t`(毫秒,理由见规范文);`sat_add/sub/mul/div`(饱和规则见规范文);`TypeTag`0/1/2`.stb` 常量表契约)
- **`Op.h`**`enum Op : uint8_t`(数值即编码,与 `machine.toml` 强校验一致);`OpFormat`RR/RRR/IMM/SLOT/JMP/JC/CALL/CAL/NONE)与 `OpClass`Plain/Instance);34 条 `kOpDefs{ name, format, cls }``mnemonic/format/op_class` 查表
- **`Encode.cpp`**`encode/decode` 往返 + `disasm`(按 format 表驱动,文本与规范文一致)
本步只让工程能配置、能链,不写业务。
## 测试
- 写本目录 `CMakeLists.txt`(上面那段即可)
- `compiler` / `vm`:空 `.cpp` + `PUBLIC``isa`
- `executor``BytecodeExecutor``main` 打印版本,链 `vm``isa``STCompiler` 入口在 `compiler/src/main.cpp`,链 `compiler``isa`
- 根 CMake`enable_testing()`(测试文件下一步再加)
完成:`cmake --build` 过。
---
### 1. 冻合同(先改规范文)
[`指令与映像.md`](../doc/isa/指令与映像.md) 已有助记符和 `[ op:8 | rd:8 | a:8 | b:8 ]`,还缺**数值和映像字节**。头文件不得自己发明一份表。
把下面这些写进规范文,再写代码(细则以该文最终落笔为准):
- 指令字:小端 `uint32_t``op`/`rd`/`a`/`b` 各 8 bit`imm16 = a | (b << 8)``off16` 为有符号、单位是指令条数
- 操作码 0..28 连续赋值,以后只追加不插队
- 各指令操作数字面(`LOADK`/`JMP`/`CALL`/`LOAD_*`/`STORE_*`/`CAL_*`/`RET`
- `INT` 饱和、`INT_MIN / -1`、除零、`BOOL` 只允许 0/1
- FNV-1a 64 的 basis/prime;路径只当排序键,对文件内容 update;空集合 = basis
- 映像魔数 `STSC`、版本 1、头字段偏移与长度、常量表/函数表/FB 表一行的字节
- 第一版可写映像:空槽、空常量表/FB、`MAIN``fn_id=0`)、一条 `RET`
完成:规范文能当唯一合同;本 README 仍只指向它。
---
### 2. `Types.h`
`include/isa/Types.h`inline,无对应 `.cpp`。命名空间 `isa`。C++20;本模块保持简单结构体,不依赖花哨特性。
- `Bool` = `uint8_t``Int` = `int16_t``Time` = `int64_t`(毫秒;理由见规范文)
- `TypeTag``Bool` / `Int` / `Time`
- `sat_add` / `sat_sub` / `sat_mul` / `sat_div`(规则见规范文)
- `pack_bool` / `pack_int` / `pack_time` → 4 字节 cell;对应 unpack
完成:单独包含该头能编译。
---
### 3. `Op.h` + `Instr.h`
- `Op.h``enum Op : uint8_t`,取值与规范文一致;`mnemonic(Op)` 助记符(已在头内落地)
- `Instr.h``typedef uint32_t Instr``pack`、取 `op`/`rd`/`a`/`b``imm16`/`off16`;按形态 `enc_rr` / `enc_rrr` / `enc_imm` / `enc_jmp` / `enc_jc`
完成:能打包/拆开一条 32-bit 指令,不依赖 `.cpp`
---
### 4. `Encode.h` + `Encode.cpp`
`STCompiler --disasm` 和测试往返打印:
- `Decoded { Op op; uint8_t rd, a, b; }`
- `Instr encode(Decoded)` / `Decoded decode(Instr)`
- `disasm(Instr, char* out, size_t cap)`
`disasm` 格式冻在规范文,例如:`RET``MOVE r1, r2``LOADK r0, 3``ADD r1, r2, r3``JMP +4``JT r0, -1``CALL 1``LOAD_I r0, 2``CAL_TON 0`
完成:一条指令能编、能解、能打出一行文本。
---
### 5. `Image.h` + `Image.cpp`
- `fnv1a64` / `fnv1a64_update`
- `ImageView`:只读视图,指向外部缓冲
- `read_image`:校验魔数、版本、头大小、各段不越界、`entry_fn_id` 落在函数表内
- `write_ret_main(cycle_limit, dt_ms, hash)``std::vector<uint8_t>`:空槽 + `MAIN` + 一条 `RET`
- `.stb` 文件读写与 `<name>.runtime.toml` sidecarI/O 绑定 var → 槽号 → channel/bit
小端 `put_*` / `get_*` 只放 `.cpp`,不把 packed struct 当 ABI。本阶段不写完整 `ImageBuilder`(等 codegen)。
完成:能写出并读回「空映像 + 一条 `RET`」。
---
### 6. 最小测试
`tests/` 加一个只链 `isa` 的 CTest 可执行文件(不是第 12.2 节那 20 个用例):
- `RET` / `ADD` / `LOADK` / `JMP -1`encode 后再 decode,字段一致;`disasm` 非空
- `write_ret_main``read_image`:魔数、version=1、`n_funcs=1`、入口是 `RET`
- `fnv1a64` 空输入等于 basis
完成:`ctest` 过上述用例。
---
`tests/isa_test`(链 `isa`):饱和、操作码冻结值、指令打包、encode/decode 往返、disasm 文本、OpClass 分类。
## 验收
- `cmake --build` 过;`ctest` isa 往返
- `compiler` / `vm``#include <isa/...>`,不互相包含
- 操作码或映像有变:先改 [`指令与映像.md`](../doc/isa/指令与映像.md) + 本目录 + 测试,再改两端
- `cmake --build` 过;`ctest``isa_roundtrip` 等 14 个用例全绿)
- `vm``#include <isa/...>``compiler` 不引用 `isa`
- 操作码有变:先改 `compiler/machine.toml` + 本目录 + 测试,再改两端