Files
Interpreter/isa/README.md
T
Admin 7c855b1618 文档同步双可执行架构:STCompiler + BytecodeExecutor。
- 12.10 重写为两条命令:STCompiler 编译出 .stb + sidecar,BytecodeExecutor 加载执行
- 12.0 删独立 stc.exe,12.13 依赖方向改为 STCompiler/BytecodeExecutor
- 指令与映像.md 新增「映像文件(.stb)与 sidecar」节,I/O 绑定不进映像
- host/ 改名 executor/,宿主入口.md 重写为执行器入口.md
- README / tests / examples / isa README 同步
2026-08-19 13:59:50 +08:00

156 lines
5.8 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.
# isa
指令集 + 映像 + 定宽类型。CMake 目标:`isa``STATIC`),无依赖。
`compiler` 写映像、`vm` 读映像,两边只依赖本目录,不互链。
```text
STCompiler → compiler → isa
BytecodeExecutor → vm → isa
```
**类型、操作码、指令字、映像布局以** [`doc/isa/指令与映像.md`](../doc/isa/指令与映像.md) **为准。** 头文件实现该文,本 README 不另当规范。全工程阶段见 [`doc/初步计划.md`](../doc/初步计划.md) 12.012.1。
公开头:`isa/include/isa/`
---
## 做 / 不做
**做:** 操作码与 32-bit 指令、映像头与段、`BOOL`/`INT`/`TIME` 宽度与饱和、编解码、工程哈希、一条指令的文本转储。
**不做:** toml、关键字、符号表、AST、VM `switch`、扫描周期、I/O 采样。`AND`/`OR` 只组合已算好的值;短路由 `compiler` 编成跳转。
---
## 实现步骤
原则:先冻合同,再头文件,再 `.cpp`,再最小测试。每步能编过再进下一步。改编码或映像字段时,先改规范文和本模块,再动 `compiler` / `vm`
目标目录(与规范一致):
```text
isa/
CMakeLists.txt
README.md
include/isa/
Types.h # 宽度、饱和、槽值
Op.h # 操作码枚举 + 助记符
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)
target_include_directories(isa PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
```
`compiler` / `vm``target_link_libraries(... PUBLIC isa)`
---
### 0. CMake 骨架
`CMakeLists.txt``add_subdirectory``compiler` / `vm` / `executor`。这三个目录若没有 `CMakeLists.txt`,顶层 configure 失败,`isa` 也编不过。
本步只让工程能配置、能链,不写业务。
- 写本目录 `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++11,不用 designated initializer。
- `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` 过上述用例。
---
## 验收
- `cmake --build` 过;`ctest` 过 isa 往返
- `compiler` / `vm``#include <isa/...>`,不互相包含
- 操作码或映像有变:先改 [`指令与映像.md`](../doc/isa/指令与映像.md) + 本目录 + 本测试,再改两端