6.5 KiB
6.5 KiB
指令编码(V2:RISC-V 式 op + func + 前缀分区形态)
状态:定案存档。RISC-V 式指令编码:opcode 定功能、func 定细节、 操作数形态由长度组前缀分区表达(fmt 位段已取消)。 与
指令集优化.md(格式/数据模型/待确认)配套。修订:2026-08-24。
1. 设计原则(RISC-V 式)
opcode 决定指令的"功能"(MOVE/LOAD/ADD…)
func 决定"功能的细节"(宽度/符号/浮点)
操作数形态(RR/RRR/IMM/SLOT/…)由长度组前缀分区 + 小表表达
2. 指令字结构(头两字节 + 操作数区)
指令 = 字节0 + 字节1 + 操作数区(rd/rs/slot/off…,按形态)
字节 0 字节 1
[长度前缀+分区 | op] [func:4 | 空:4]
↑ ↑
长度+形态分区+操作码 功能细节(空 4 位待全部编码后定)
3. 前缀编码与形态分区
前缀从最高位起比对,长度与形态分区一体:
| 前缀 | 指令长度 | 分区 | 形态 | op 位宽 | op 空间 | 指令 |
|---|---|---|---|---|---|---|
11 |
4B | 11 | RR | 6 位 | 64 | MOVE/NOT/NEG/ABS/INC/DEC/浮点单目/舍入/CONV(21) |
10 |
4B | 10 | NONE | 6 位 | 64 | NOP/RET(2) |
011 |
8B | 011 | RRR | 5 位 | 32 | 算术/逻辑/移位/位操作/比较(26) |
010 000 |
8B | 010 000 | IMM | 2 位 | 4 | LOADK(1) |
010 001 |
8B | 010 001 | SLOT | 2 位 | 4 | LOAD/STORE(2) |
010 010 |
8B | 010 010 | JMP | 2 位 | 4 | JMP(1) |
010 011 |
8B | 010 011 | JC | 2 位 | 4 | JT/JF(2) |
010 100 |
8B | 010 100 | CALL | 2 位 | 4 | CALL(1) |
010 101 |
8B | 010 101 | CAL | 2 位 | 4 | CAL(1) |
010 110/111 |
8B | 010 11x | 预留 | 2 位 | 4+4 | — |
0010 |
16B | 0010 | SLOT+off | 4 位 | 16 | LOAD_OFF/STORE_OFF/字符串(8) |
0011 |
16B | 0011 | IMM64 | 4 位 | 16 | LOADK64(1) |
0001 |
32B | 0001 | 预留 | 4 位 | 16 | JTBL/复杂字符串/数组(6,形态待定) |
- 长度自描述:
1开头 → 4B、01→ 8B、001→ 16B、0001→ 32B(前缀分区不改变长度判定) - op 按组内独立编号(各区从 0 起)
- 取指:读字节 0 → 前缀定长 → 搬整条;形态全部由前缀分区直推(含 010 区内部分区)
4. func 位段(字节 1 高 4 位,16 种)
| func | 语义 | 覆盖类型(编译期映射) |
|---|---|---|
| 0 | 1 字节、无符号 | BOOL、BYTE、USINT |
| 1 | 1 字节、有符号 | SINT |
| 2 | 2 字节、无符号 | WORD、UINT |
| 3 | 2 字节、有符号 | INT |
| 4 | 4 字节、无符号 | DWORD、UDINT、DATE、TOD |
| 5 | 4 字节、有符号 | DINT |
| 6 | 8 字节、无符号 | LWORD、ULINT、DT |
| 7 | 8 字节、有符号 | LINT、TIME |
| 8 | F32 | REAL |
| 9 | F64 | LREAL |
| 10..15 | 预留 |
- func 语义随 op:MOVE=宽度;LOAD/STORE=宽度×符号;ADD..=宽度×符号+浮点;逻辑=宽度;无类型指令 func=0(不使用)
- 字节 1 低 4 位暂空:待全部指令编码完后决定用途(func 扩位/扩展字段)
5. 形态识别(全部前缀直推,零查表)
| 前缀 | 形态 | 识别方式 |
|---|---|---|
11 |
RR | 前缀直推 |
10 |
NONE | 前缀直推 |
011 |
RRR | 前缀直推 |
010 000 |
IMM | 前缀直推 |
010 001 |
SLOT | 前缀直推 |
010 010 |
JMP | 前缀直推 |
010 011 |
JC | 前缀直推 |
010 100 |
CALL | 前缀直推 |
010 101 |
CAL | 前缀直推 |
0010 |
SLOT+off | 前缀直推 |
0011 |
IMM64 | 前缀直推 |
0001 |
预留 | 待定 |
010 区内部分区(8 条,形态位 3 位 + 子 op 2 位):
| 完整前缀 | 指令 | 子 op | 形态 | 操作数区 |
|---|---|---|---|---|
010 000 |
LOADK | 00 | IMM | rd=23..16、imm32=55..24、pad=63..56 |
010 001 |
LOAD | 00 | SLOT | rd=23..16、slot32=55..24、pad=63..56 |
010 001 |
STORE | 01 | SLOT | 同上 |
010 010 |
JMP | 00 | JMP | off32=47..16、pad=63..48 |
010 011 |
JT | 00 | JC | rd=23..16、off32=55..24、pad=63..56 |
010 011 |
JF | 01 | JC | 同上 |
010 100 |
CALL | 00 | CALL | fn_id32=47..16、pad=63..48(rd 恒 0) |
010 101 |
CAL | 00 | CAL | fb_id16=31..16、slot32=63..32(rd 恒 0) |
rd 恒 0 约定(U14 定案):CALL / CAL 的 rd 字节(23..16)未使用,编码恒 0;指令身份由前缀分区 + op 决定,rd 不参与语义。
6. uses_rd / uses_ra / uses_rb(寄存器越界检查推导)
"哪些字段是寄存器"由形态决定,全部前缀直推(零查表):
| 前缀 | 形态 | uses_rd | uses_ra | uses_rb |
|---|---|---|---|---|
11 |
RR | ✓ | ✓(rs) | — |
10 |
NONE | — | — | — |
011 |
RRR | ✓ | ✓ | ✓ |
010 000 |
IMM | ✓ | — | — |
010 001 |
SLOT | ✓ | — | — |
010 010 |
JMP | — | — | — |
010 011 |
JC | ✓ | — | — |
010 100 |
CALL | — | — | — |
010 101 |
CAL | — | — | — |
0010 |
SLOT+off | ✓ | — | — |
0011 |
IMM64 | ✓ | — | — |
执行:if (uses_rd && rd >= nregs) → BadOp——所有指令零查表,形态由前缀直推。
7. 长度组 × 操作数区
| 前缀 | 长度 | 操作数区(bit16 起) |
|---|---|---|
| 11/10 | 4B | RR: rd=23..16、rs=31..24;NONE: pad=31..16 |
| 011/010 | 8B | RRR: rd+rs1+rs2+pad;010 区六形态见 §5 |
| 0010/0011 | 16B | SLOT+off: rd+slot32+off32+pad;IMM64: rd+imm64+pad |
| 0001 | 32B | 预留(操作数区 30B,格式待定) |
8. 类型系统(编译期)→ func 映射
- 编译期:19 种 IEC 基础类型,类型检查严格比对——不匹配编译期报错
- BOOL 约束:编译器限制 0/1,越界报错;VM 无 BOOL 特例
- 运行时:VM 只认 func 的 10 种"宽度+符号+浮点"组合
- 常量表:条目 8B 原始值(无 tag),LOADK 按 func 解释
9. 决策历史
- 用户提出 RISC-V 式:opcode 定功能、func 定细节
- 前缀分区:用户提出
011=RRR、010=其他;后定 010 区内部分区(形态位 3 位+子 op 2 位),全部形态前缀直推、零查表;11=RR、10=NONE(4B);0010=SLOT+off、0011=IMM64(16B) - fmt 位段取消:形态全部由前缀分区表达(010 区内部再分区,零查表);字节 1 = [func:4 | 空:4],空位待全部编码后定
- func 4 位(10 组合);MOVE 只管宽度;19 类型 → 10 func 编译期映射;BOOL 编译器强制 0/1