From 583f14967a374a40ac8c04ed0db4872442cfe3c9 Mon Sep 17 00:00:00 2001 From: chentianya Date: Tue, 18 Aug 2026 17:18:30 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=BB=20isa=20=E7=9A=84=E6=8C=87=E4=BB=A4?= =?UTF-8?q?=E7=BC=96=E7=A0=81=E3=80=81=E6=98=A0=E5=83=8F=E5=B8=83=E5=B1=80?= =?UTF-8?q?=E4=B8=8E=E5=AE=9A=E5=AE=BD=E7=B1=BB=E5=9E=8B=EF=BC=8C=E8=AE=A1?= =?UTF-8?q?=E5=88=92=E6=94=B9=E4=B8=BA=E5=BC=95=E7=94=A8=E8=AF=A5=E8=A7=84?= =?UTF-8?q?=E8=8C=83=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- Doc/isa/指令与映像.md | 160 ++++++++++++++++++++++++++++++++++++++++++ Doc/初步计划.md | 8 +-- isa/CMakeLists.txt | 0 isa/README.md | 16 +---- 4 files changed, 167 insertions(+), 17 deletions(-) create mode 100644 Doc/isa/指令与映像.md create mode 100644 isa/CMakeLists.txt diff --git a/Doc/isa/指令与映像.md b/Doc/isa/指令与映像.md new file mode 100644 index 0000000..c4aed38 --- /dev/null +++ b/Doc/isa/指令与映像.md @@ -0,0 +1,160 @@ +# 指令与映像 + +isa 模块规范:指令集 + 映像 + 定宽类型。不是编译器,不把 `.st` 编成映像。 + +`compiler` 按本文件写出字节,`vm` 只认这些字节。两边不互链。 + +全工程定案见 [`初步计划.md`](../初步计划.md)。**类型、指令编码、映像布局以本文为准**,不要另写一份互相打架的表。头文件实现本文,不另当规范。 + +```text +host → compiler → isa +host → vm → isa +``` + +CMake 目标:`isa`(`STATIC`),无依赖。公开头:`isa/include/isa/`。 + +--- + +## 做 / 不做 + +**做** + +- 操作码与 32 位指令布局 +- 映像头与段(函数字节码、全局 / FB 槽、工程哈希) +- `BOOL` / `INT` / `TIME` 宽度与溢出规则 +- 编解码、工程哈希、一条指令的文本转储(给 host 打印) + +**不做** + +- toml 字段、关键字表、符号表、AST +- 扫描周期循环、I/O 采样 +- 短路语义(`AND`/`OR` 指令只组合已算好的值;短路由 `compiler` 编成跳转) + +指令表可作为内部 IR 的文本形态,不必当主语言。 + +--- + +## 特性 + +| 项 | 第一版 | +|---|---| +| `BOOL` | `uint8_t`,只允许 0/1 | +| `INT` | `int16_t`(IEC `INT`) | +| `TIME` | `int32_t` 毫秒;与 `INT` 不混用 | +| 整数溢出 | **饱和**(夹到 `INT` 最小/最大) | +| 字节序 | 小端 | +| 指令宽度 | 32 bit,一种主布局 | +| 寄存器 | 下标 0..255;每函数实际个数写在函数头 `nregs` | +| 跳转 | 相对 offset,单位是**指令条数**,不是字节 | +| `CALL` | 立即数 `fn_id`(u16),无函数指针 | +| 映像魔数 | `STSC`,版本 `1` | +| 工程哈希 | 源文件路径排序后对内容做 FNV-1a 64(非密码学) | +| I/O 绑定 | **不进映像**;编译期把 `var` 收成槽号,channel/bit 留在 host 读 toml | +| 不做 | `REAL`、隐式宽化、独立 `stc.exe` | + +--- + +## 类型 + +C++11 定宽: + +- `BOOL`:`uint8_t`,0/1 +- `INT`:`int16_t`;加减乘除溢出饱和 +- `TIME`:`int32_t` 毫秒 + +`compiler` 与 `vm` 都按同一规则,不再另选溢出策略。 + +--- + +## 指令 + +定宽 32 bit: + +```text +[ op:8 | rd:8 | a:8 | b:8 ] +``` + +- 三寄存器:`a`/`b` 为 `ra`/`rb`(`MOVE`/`NOT` 只用 `rd`+`a`) +- `LOADK`:`a|b` 为 `const_id`(u16) +- `JMP` / `JT` / `JF`:`a|b` 为有符号相对 offset(指令条数) +- `CALL`:`a|b` 为 `fn_id`(u16) + +操作码一次列全(`CMP_xx` 冻下面六种): + +```text +MOVE rd, rs +LOADK rd, const_id +NOT rd, rs +AND/OR rd, ra, rb (* 已算好的值;短路用跳转 *) +ADD/SUB/MUL/DIV rd, ra, rb +CMP_EQ/NE/LT/LE/GT/GE rd, ra, rb +JMP offset +JT/JF r, offset +LOAD_I / STORE_Q / LOAD_M / STORE_M +LOAD_GLOBAL / STORE_GLOBAL +CAL_TON / CAL_TOF / CAL_CTU +CALL fn_id +RET +``` + +局部 / `VAR` = 固定寄存器;表达式临时值往后编号;`nregs` 写进函数头。 +`I`/`Q`/`M` 走映像指令,不是通用寄存器。 +FB 实例固定布局,字段偏移编译期算死。 + +--- + +## 映像 + +魔数 `STSC`,版本 `1`。 + +头: + +- `cycle_limit`、`dt_ms` +- 工程哈希 +- 全局槽数、I/Q/M 槽数 +- 常量表 / 函数表 / 字节码 / FB 布局的偏移 +- 入口 `MAIN` 的 `fn_id` + +函数表一行:`fn_id`、`nregs`、字节码偏移与长度。 + +工程哈希:收录源文件路径排序后对内容做 **FNV-1a 64**,只保证回放槽位一致,不是密码学哈希。 + +`[[io.input]]` / `[[io.output]]` 不进映像。 + +--- + +## 目录与 CMake + +```text +isa/ + CMakeLists.txt + README.md # 代码目录入口,指向本文 + include/isa/ + Types.hpp # 宽度、饱和、槽值表示 + Op.hpp # 操作码枚举 + 助记符 + Instr.hpp # 32-bit 打包/拆字段(inline) + Image.hpp # 头、段、函数表/常量表/FB 布局 + Encode.hpp # 编解码、哈希、反汇编一行 + 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)`。 + +--- + +## 实现顺序(对齐初步计划 12.0~12.1) + +1. `Types.hpp`:三类型 + `sat_add` 等饱和函数(inline 即可) +2. `Op.hpp` + `Instr.hpp`:枚举与 32-bit 编解码 +3. `Encode.cpp`:`encode` / `decode` / `disasm` 一条指令 +4. `Image.hpp` + `Image.cpp`:头布局、FNV-1a、读写缓冲(先能写空映像 + 一条 `RET`) +5. 测试随后在 `tests/` 加编解码往返;本阶段以头文件和库能链为准 + +不在本模块做:VM `switch`、toml、关键字、符号表。 diff --git a/Doc/初步计划.md b/Doc/初步计划.md index c3472fb..eb099b0 100644 --- a/Doc/初步计划.md +++ b/Doc/初步计划.md @@ -202,6 +202,8 @@ motor.st / main.st ## 7. 寄存器机与指令 +编码宽度、操作码取值、映像头与定宽类型以 [`isa/指令与映像.md`](isa/指令与映像.md) 为准。本节只列助记符。 + - 局部 / `VAR` = 固定寄存器;表达式临时值往后编号;`nregs` 写进函数头。 - `I/Q/M` 走映像指令,不是通用寄存器。 - 每个 FB 实例一块固定布局,字段偏移编译期算死。 @@ -378,11 +380,9 @@ CMake 四个目标能空编译:`isa`、`compiler`、`vm`、`host`。`host` 先 **指令(进 `isa`,约 20 条)** -第 7 节那张表:编码宽度、立即数格式、`fn_id` 是立即数、跳转是相对 offset。 -映像头:函数表、常量表、全局槽数、FB 槽布局、`cycle_limit`、`dt_ms`、工程哈希。 -工程哈希:收录的源文件排序后算,写入映像,回放时槽位必须一致。 +布局、操作码、映像、哈希、饱和以 [`isa/指令与映像.md`](isa/指令与映像.md) 为准。第 7 节只列助记符。 -完成:`isa` 能编解码一条指令;头文件即规范,不再另写一份互相打架的文档。 +完成:`isa` 能编解码一条指令;实现头文件,不另写第三份规范。 --- diff --git a/isa/CMakeLists.txt b/isa/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/isa/README.md b/isa/README.md index f0166a5..15b1948 100644 --- a/isa/README.md +++ b/isa/README.md @@ -1,17 +1,7 @@ # isa -共享契约库。CMake 目标:`isa`(`STATIC` 或 `INTERFACE`),无依赖。 +指令集 + 映像 + 定宽类型。CMake 目标:`isa`(`STATIC`)。 -`compiler` 写映像、`vm` 读映像,两边只依赖本目录,彼此不链接。 +`compiler` 写映像、`vm` 读映像,两边只依赖本目录。 -## 职责 - -- 约 20 条寄存器指令的编码(`MOVE`、`LOADK`、跳转、`LOAD_I` / `STORE_Q`、`CALL` / `RET`、`CAL_TON` 等) -- 映像头:函数字节码、全局 / FB 数据槽、工程哈希 -- 定宽类型:第一版 `BOOL`、`INT`、`TIME` - -## 不放什么 - -解析器、符号表、扫描周期循环、I/O 采样。那些分别属于 `compiler`、`vm`、`host`。 - -指令表可作为内部 IR 的文本形态,不必当主语言。 +规范、特性与实现顺序见 [`doc/isa/指令与映像.md`](../doc/isa/指令与映像.md)。