LoongArch(龙架构) 指令集

一、架构基础与寄存器模型

LoongArch 分为 32 位(LA32)和 64 位(LA64)两个版本,所有指令均为 32 位固定长度,要求 4 字节地址对齐,非对齐取指会触发地址错误异常。

指令的操作对象以寄存器为核心,主要分为四类:

  1. 通用寄存器(GPR)

    • 共 32 个,编号 $r0 ~ $r31,LA32 为 32 位宽,LA64 为 64 位宽
    • $r0(别名 $zero):硬件强制恒为 0,写入操作被忽略,是 RISC 架构的经典优化设计,可通过它实现寄存器移动、置零等伪指令
    • $r1(别名 $ra):函数调用链接寄存器,bl 等跳转指令会自动将返回地址写入该寄存器
    • 其余寄存器在架构层面功能完全正交,仅在 ABI 规范中约定了栈指针($r3/$sp)、线程指针($r2/$tp)、参数寄存器、临时寄存器等软件用途
  2. 浮点寄存器(FPR):共 32 个,原生支持单精度(32 位)和双精度(64 位)浮点运算

  3. 控制状态寄存器(CSR):仅特权模式可访问,用于系统控制、异常处理、内存管理等内核功能

  4. 向量寄存器:属于扩展指令集部分,LSX 为 128 位向量,LASX 为 256 位高级向量


二、指令编码格式

LoongArch 的编码规则统一:寄存器操作数域从低位(第 0 bit)开始依次排列,操作码(opcode)从高位(第 31 bit)开始排列,立即数域位于寄存器域与操作码之间

架构共定义了 9 种典型指令格式,分为无立即数和带立即数两大类:

1. 无立即数格式(寄存器 - 寄存器型)

表格

格式 操作数构成 典型用途 代表指令
2R 型 目的寄存器 rd + 源寄存器 rj 单源运算、间接跳转 jr rj
3R 型 rd + rj + rk(两源一目的) 最通用格式,整数加减、逻辑运算 add.w rd, rj, rk
4R 型 rd + rj + rk + ra 仅用于部分复杂浮点运算 浮点乘累加指令

2. 带立即数格式

根据立即数长度分为 6 种,覆盖不同场景的立即数需求:

  • 2RI8:8 位立即数 + 2 个寄存器,用于短立即数位操作
  • 2RI12:12 位有符号立即数 + 2 个寄存器,最常用格式,对应访存、立即数加法
  • 2RI14:14 位立即数 + 2 个寄存器,主要用于 CSR 寄存器寻址
  • 2RI16:16 位立即数 + 2 个寄存器,用于条件分支偏移
  • 1RI21:21 位立即数 + 1 个寄存器,用于长跳转、PC 相对寻址
  • I26:26 位立即数,无寄存器操作数,用于无条件长跳转

注:21 位、26 位立即数在指令编码中会拆分为高位、低位两部分存储,以适配 32 位指令空间;所有偏移类立即数均会左移 2 位(对应 4 字节指令对齐),扩大寻址范围。


三、核心指令分类与详解

LoongArch 基础指令集包含近 200 条基础指令,覆盖整数运算、访存、转移、浮点、系统特权五大类,以下是核心指令的功能与语义说明。

1. 整数运算指令

全部基于通用寄存器操作,是程序中最常用的指令类别。

(1)算术加减指令
  • 寄存器 - 寄存器型
    • add.w rd, rj, rk:32 位整数加法,GR[rd] = GR[rj] + GR[rk]
    • sub.w rd, rj, rk:32 位整数减法,GR[rd] = GR[rj] - GR[rk]
    • add.d / sub.d:64 位版本,仅 LA64 架构支持
  • 立即数型
    • addi.w rd, rj, si12:32 位立即数加法,12 位有符号立即数自动符号扩展,GR[rd] = GR[rj] + SignExt(si12)
    • addi.d:64 位立即数加法,仅 LA64 架构支持
(2)比较指令

采用 "结果写入寄存器" 的设计,不依赖状态标志位:

  • slt rd, rj, rk:带符号小于比较,若 GR[rj] < GR[rk] 则 rd 写 1,否则写 0
  • sltu rd, rj, rk:无符号小于比较
  • slti / sltiu:立即数版本的比较指令
(3)逻辑运算指令
  • and rd, rj, rk:按位与
  • or rd, rj, rk:按位或
  • xor rd, rj, rk:按位异或
  • nor rd, rj, rk:按位或非
  • 对应立即数版本:andiorixori
(4)移位指令
  • 逻辑移位:sll.w(左移)、srl.w(逻辑右移,空位补 0)
  • 算术移位:sra.w(算术右移,空位补符号位)
  • 循环移位:rotr.w(循环右移)
  • 立即数移位版本:后缀加 i,如 slli.w rd, rj, sa5,移位量由 5 位立即数指定
(5)乘除指令
  • 乘法:mul.w(取低 32 位结果)、mulh.w(取高 32 位有符号结果)、mulh.wu(取高 32 位无符号结果)
  • 除法:div.w(有符号除法)、div.wu(无符号除法)
  • 取模:mod.wmod.wu
  • 64 位版本对应后缀 .d
(6)大立即数与 PC 相对寻址指令

这是 LoongArch 的特色优化指令,用于高效构造大地址和常量:

  • lu12i.w rd, si20:加载 20 位立即数到寄存器高 20 位,低 12 位补 0,用于快速构造 32 位常量
  • lu32i.d / lu52i.d:64 位大立即数构造指令,仅 LA64 支持
  • pcaddi rd, si20:PC 相对加法,GR[rd] = PC + SignExt({si20, 2'b0}),用于快速计算 PC 相对地址
  • pcaddu12ipcaddu18i:PC 相对高位加法,配合访存指令实现大偏移寻址

2. 访存指令

LoongArch 采用典型的 Load-Store 架构:运算只能操作寄存器,内存读写通过专用访存指令完成。所有访存指令统一使用 基址寄存器 + 12 位有符号立即数偏移 的寻址模式,单指令寻址范围为 ±2KB

加载指令(内存 → 寄存器)
  • ld.b rd, rj, si12:加载 8 位有符号字节,符号扩展到寄存器位宽
  • ld.bu rd, rj, si12:加载 8 位无符号字节,零扩展
  • ld.h / ld.hu:加载 16 位半字(有符号 / 无符号)
  • ld.w rd, rj, si12:加载 32 位字
  • ld.d rd, rj, si12:加载 64 位双字,仅 LA64 支持
存储指令(寄存器 → 内存)
  • st.b rd, rj, si12:存储 8 位字节
  • st.h rd, rj, si12:存储 16 位半字
  • st.w rd, rj, si12:存储 32 位字
  • st.d rd, rj, si12:存储 64 位双字,仅 LA64 支持

操作语义示例:ld.w rd, rj, si12 等价于 GR[rd] = Memory[ GR[rj] + SignExt(si12) ]

3. 转移与分支指令

用于控制程序执行流,分为条件分支、无条件跳转、子程序调用三类。

(1)条件分支指令

基于两个寄存器的比较结果跳转,偏移量为 16 位有符号数,跳转范围 ±128KB

  • beq rj, rk, offs16:相等则跳转,GR[rj] == GR[rk]PC += SignExt(offs16 << 2)
  • bne rj, rk, offs16:不相等则跳转
  • blt / bltu:带符号 / 无符号小于则跳转
  • bge / bgeu:带符号 / 无符号大于等于则跳转
(2)无条件跳转与子程序调用
  • b offs26:无条件相对跳转,26 位偏移,跳转范围 ±128MB
  • jr rj:寄存器间接跳转,PC = GR[rj],常用于函数返回
  • bl offs26:带链接无条件跳转,GR[ra] = PC + 4; PC += SignExt(offs26 << 2),用于子程序调用
  • blr rj:寄存器间接带链接跳转,用于函数指针调用

4. 浮点运算指令

操作 32 个独立的浮点寄存器,支持单精度(.s 后缀)和双精度(.d 后缀)运算:

  • 算术运算:fadd.sfsub.dfmul.sfdiv.dfmadd.d(乘累加)等
  • 浮点比较:fcmp.eq.sfcmp.lt.d 等,结果写入浮点条件标志寄存器
  • 类型转换:整数与浮点互转、单双精度互转,如 ffint.s.w(32 位整数转单精度浮点)
  • 浮点访存:fld.sfst.d 等,寻址模式与整数访存一致

5. 特权与系统指令

仅在内核态(PLV0)可执行,服务于操作系统内核:

  • CSR 读写:csrrd rd, csr_num(读 CSR 寄存器)、csrwr rj, csr_num(写 CSR 寄存器)
  • 异常与中断:syscall(系统调用)、break(断点异常)、eret(异常返回)
  • 内存与缓存管理:TLB 操作、缓存刷新、内存屏障等指令

四、扩展指令集

LoongArch 采用 "基础 + 扩展" 的模块化设计,除基础指令集外,还包含四大可选扩展:

  1. LSX(向量扩展):128 位单指令多数据(SIMD)指令,支持整数 / 浮点并行运算,面向多媒体、信号处理场景
  2. LASX(高级向量扩展):256 位 SIMD 指令,是 LSX 的超集,提供更高的并行计算能力
  3. LBT(二进制翻译扩展):专为二进制翻译优化的指令集,用于高效运行 x86、ARM 等架构的二进制程序
  4. LVZ(虚拟化扩展):硬件虚拟化支持指令,用于虚拟机监视器(VMM)开发

五、LoongArch 指令集设计特点

  1. 完全自主知识产权:从顶层架构到每条指令的编码、语义均为自主定义,不依赖国外指令集授权
  2. 经典 RISC 设计:定长 32 位指令、Load-Store 架构、大量通用寄存器,硬件实现简单高效
  3. 编译与硬件友好:寄存器位置固定、指令格式规整,降低编译器后端开发难度,也易于 CPU 解码实现
  4. 面向现代软件优化:原生支持 PC 相对寻址、大立即数快速构造,减少指令数量,提升代码密度
  5. 生态兼容设计:指令功能覆盖主流架构的核心特性,配合二进制翻译扩展可兼容现有软件生态