Loong 虚拟机指令集设计文档
指令分类总表
类别 | 包含指令 |
---|---|
基本控制 | Trap、ReturnVoid、Return |
常量与变量 | I8/I16/I32/I64/U8/U16/U32/U64、F32/F64、Null、Const、Grow、Var、StoreVar、Peek |
函数调用与返回 | Call、CallImm |
类型转换 | F32tI64、F64tI64、I64tF32、I64tF64、F64tF32、F32tF64 |
外部/内建函数调用 | NativeCall、BuiltinCall |
算术运算 | 整数运算(AddI/SubI/MulI/DivI/ModI细分类型)、浮点运算(AddF32/AddF64等) |
比较与逻辑 | CmpEQ/CmpNE、CmpLTI/CmpLTF32/CmpLTF64/CmpGTI/CmpGTF32/CmpGTF64、CmpLTE/CmpGTE、AndL/OrL/Not |
输出 | PrintI、PrintF32、PrintF64、PrintS、PrintN、PrintO、PrintB |
跳转 | Jmp、JmpIf、JmpIfNot |
内存与对象操作 | New、Array、Ptr8/Ptr16/Ptr32/Ptr64/ObjPtr64、Ptr64Var/ObjPtr64Var、PtrInd8/PtrInd16/PtrInd32/PtrInd64/ObjPtrInd64、StorePtr8/StorePtr16/StorePtr32/StorePtr64、StorePtr64Var、StorePtrInd8/StorePtrInd16/StorePtrInd32/StorePtrInd64 |
栈操作 | Repeat、Pop、Swap |
类型判断 | CmpType |
详细指令说明表
一、基本控制
指令名称 | 功能描述 |
---|---|
Trap | 停止虚拟机执行;将虚拟机状态(status)设为 STOPPED ;回退指令指针(ip);常用于调试或断点场景。 |
ReturnVoid | 无返回值的函数返回操作;恢复上一个调用帧的 ip 和 bp ;弹出调用栈顶部帧。 |
Return | 有返回值的函数返回操作;弹出栈顶的返回值,恢复上一个调用帧(栈缩回);将返回值压回新栈顶;若调用栈为空,虚拟机结束(主函数返回)。 |
二、常量与变量
指令名称 | 功能描述 |
---|---|
I8/I16/I32/I64 | 读取指定宽度(8/16/32/64位)的有符号整数常量,转换为 int64 类型后压入栈顶。 |
U8/U16/U32/U64 | 读取指定宽度(8/16/32/64位)的无符号整数常量,转换为 int64 类型后压入栈顶(高位补零)。 |
F32/F64 | 读取32位/64位浮点数常量,封装为 VMValue (带类型标记)后压入栈顶。 |
Null | 压入一个空值(默认 VMValue ,类型标记为 NULL )。 |
Const | 读取常量池索引,从常量池中获取对应值,封装为 VMValue 后压入栈顶。 |
Grow | 扩展栈空间;参数为需要增加的栈容量(字节数或元素数?需明确),调整栈顶指针(sp)。 |
Var | 读取局部变量(以基址指针 bp 为基准的偏移量);根据偏移量从局部变量表中获取值,压入栈顶。 |
StoreVar | 弹出栈顶值,将其存入指定的局部变量位置(以 bp 为基准的偏移量)。 |
Peek | 查看距离栈顶指定距离(偏移量)的值(不弹出);例如 Peek 1 表示取栈顶前一个元素,压入栈顶。 |
三、函数调用与返回
指令名称 | 功能描述 |
---|---|
Call | 弹出栈顶的目标函数入口地址;读取参数个数(由前序指令或约定确定);保存当前调用帧(bp 、ip )到调用栈;设置新的 bp (当前 sp )和 ip (目标地址)。 |
CallImm | 直接读取目标函数入口地址(立即数)和参数个数(立即数);保存当前调用帧到调用栈;设置新的 bp 和 ip 。 |
四、类型转换
指令名称 | 功能描述 |
---|---|
F32tI64 | 浮点转整数:弹出栈顶的 f32 类型值,截断或舍入转换为 i64 类型,修改栈顶元素的类型和值。 |
F64tI64 | 浮点转整数:弹出栈顶的 f64 类型值,截断或舍入转换为 i64 类型,修改栈顶元素的类型和值。 |
I64tF32 | 整数转浮点:弹出栈顶的 i64 类型值,转换为 f32 类型(可能丢失精度),修改栈顶元素的类型和值。 |
I64tF64 | 整数转浮点:弹出栈顶的 i64 类型值,转换为 f64 类型(精确转换),修改栈顶元素的类型和值。 |
F64tF32 | 浮点类型间转换:弹出栈顶的 f64 类型值,转换为 f32 类型(可能丢失精度),修改栈顶元素的类型和值。 |
F32tF64 | 浮点类型间转换:弹出栈顶的 f32 类型值,转换为 f64 类型(精确扩展),修改栈顶元素的类型和值。 |
五、外部/内建函数调用
指令名称 | 功能描述 |
---|---|
NativeCall | 调用外部C函数;弹出栈顶的函数索引(对应C函数指针表);弹出参数(按调用约定顺序);通过函数指针调用C函数;将返回值(若有)压入栈顶。 |
BuiltinCall | 调用内建函数(虚拟机预定义的函数);读取函数指针(内置实现);按调用约定传递参数;执行内建函数逻辑;将返回值(若有)压入栈顶。 |
六、算术运算
整数运算
指令名称 | 功能描述 |
---|---|
AddI/SubI/MulI/DivI/ModI(已弃用) | 弹出栈顶右操作数,左操作数为当前栈顶;执行加法/减法/乘法/除法/取模运算(整数运算);结果写回栈顶(类型为 i64 )。 |
AddI8/SubI8/MulI8/DivI8/ModI8 | 8位整数运算;操作数范围限制为 i8 (-128~127);结果截断为8位,类型标记为 i8 。 |
AddI16/SubI16/MulI16/DivI16/ModI16 | 16位整数运算;结果截断为16位,类型标记为 i16 。 |
AddI32/SubI32/MulI32/DivI32/ModI32 | 32位整数运算;结果截断为32位,类型标记为 i32 。 |
AddI64/SubI64/MulI64/DivI64/ModI64 | 64位整数运算;结果保留64位,类型标记为 i64 。 |
备注:DivI /ModI 需处理除零异常;ModI 结果符号与左操作数一致。 |
浮点运算
指令名称 | 功能描述 |
---|---|
AddF32/SubF32/MulF32/DivF32 | 32位浮点运算;弹出右操作数(f32 ),左操作数为当前栈顶(f32 );执行加减乘除;结果写回栈顶(类型 f32 )。 |
AddF64/SubF64/MulF64/DivF64 | 64位浮点运算;操作数类型为 f64 ;结果类型为 f64 。 |
七、比较与逻辑
指令名称 | 功能描述 |
---|---|
CmpEQ/CmpNE | 比较相等/不等;弹出两个值(类型需相同),比较是否相等;结果为 bool (true /false )压入栈顶(类型 bool )。 |
CmpLTI/CmpLTF32/CmpLTF64 | 小于比较;CmpLTI 用于整数(i32 /i64 ),CmpLTF32 /CmpLTF64 用于浮点;弹出右操作数和左操作数,判断左 < 右;结果压入栈顶(bool )。 |
CmpGTI/CmpGTF32/CmpGTF64 | 大于比较;逻辑同上(左 > 右)。 |
CmpLTE/CmpGTE | 小于等于/大于等于;弹出两个值,判断左 <= 右 或 左 >= 右;结果压入栈顶(bool )。 |
AndL/OrL/Not | 逻辑与/或/非;AndL /OrL 操作 bool 类型(弹出两个值);Not 操作单个 bool 值(弹出后取反);结果压入栈顶(bool )。 |
八、输出
指令名称 | 功能描述 |
---|---|
PrintI | 打印 i32 类型值(十进制)到标准输出。 |
PrintF32 | 打印 f32 类型值(默认格式,如 %f )到标准输出。 |
PrintF64 | 打印 f64 类型值(默认格式,如 %lf )到标准输出。 |
PrintS | 打印字符串(栈顶值为字符串指针或句柄,需结合运行时字符串管理)到标准输出。 |
PrintN | 打印换行符(\n )。 |
PrintO | 打印对象(需结合运行时对象toString方法或元数据)到标准输出。 |
PrintB | 打印 bool 类型值(true /false )到标准输出。 |
九、跳转
指令名称 | 功能描述 |
---|---|
Jmp | 无条件跳转;弹出栈顶的目标地址(ip 绝对地址或相对偏移),设置 ip 为该地址。 |
JmpIf | 条件跳转(若条件为真);弹出条件值(bool )和目标地址;若条件为 true ,设置 ip 为目标地址。 |
JmpIfNot | 条件跳转(若条件为假);逻辑同上,仅当条件为 false 时跳转。 |
十、内存与对象操作
指令名称 | 功能描述 |
---|---|
New | 分配新对象;参数为对象类型(如类元数据指针);在堆上分配内存,初始化对象头(类型、引用计数等);将对象指针压入栈顶。 |
Array | 分配新数组;弹出栈顶的两个值:类型(元素类型)和长度(i32 );在堆上分配连续内存(长度×元素大小);初始化数组头(类型、长度、容量);将数组指针压入栈顶。 |
Ptr8/Ptr16/Ptr32/Ptr64 | 对象指针偏移读取;弹出栈顶的对象指针(void* )和偏移量(i32 );读取对象内存中 [指针 + 偏移量] 处的 8/16/32/64 位值;转换为 int64 压入栈顶(或保留类型?需明确)。 |
ObjPtr64 | 对象指针偏移读取(对象由64位指针表示);类似 Ptr64 ,但显式处理64位指针。 |
Ptr64Var/ObjPtr64Var | 变量偏移读取;弹出栈顶的变量索引(对应局部变量表中的对象指针)和偏移量;从局部变量中获取对象指针,读取 [指针 + 偏移量] 处的值;压入栈顶。 |
PtrInd8/PtrInd16/... | 间接偏移读取;弹出栈顶的对象指针和偏移量(均为栈中值);读取 [对象指针 + 偏移量] 处的值;压入栈顶。 |
StorePtr8/StorePtr16/... | 对象指针偏移写入;弹出栈顶的对象指针、值和偏移量;将值写入 [对象指针 + 偏移量] 内存位置(需检查类型匹配)。 |
StorePtr64Var | 变量偏移写入;弹出栈顶的变量索引、值和偏移量;从局部变量获取对象指针,将值写入 [对象指针 + 偏移量] 。 |
StorePtrInd8/... | 间接偏移写入;弹出对象指针、值和偏移量(均为栈中值);将值写入 [对象指针 + 偏移量] 。 |
十一、栈操作
指令名称 | 功能描述 |
---|---|
Repeat | 复制栈顶元素;将栈顶值再次压入栈顶(如栈顶为 a ,执行后栈顶为 a, a )。 |
Pop | 弹出栈顶元素;丢弃当前栈顶值,sp 减1(或按元素大小调整)。 |
Swap | 交换栈顶两个元素;弹出栈顶两个值 a 和 b ,重新压入 a 、b (顺序变为 b, a )。 |
十二、类型判断
指令名称 | 功能描述 |
---|---|
CmpType | 判断对象类型是否为指定类型;弹出栈顶的对象指针;查询对象头中的类型元数据;与目标类型(栈顶或立即数)比较;结果为 bool 压入栈顶。 |
评论