每个CPU都有自己独特的指令,比如X86结构的CPU有INTEL的指令系统,MIPS的CPU也有自己的指令系统,当然龙芯CPU也不例外,有自己的指令系统。指令是控制CPU怎么样工作的接口,每条指令都会让CPU做出响应的。如果发送一条不是CPU的指令,就会导致CPU非法执行,并且会引起CPU异常。龙芯里,每条指令都是固定长度:32位,4个字节。因此,任何指令段的代码长度,一定要是4字节的倍数,绝对不要出现不是4的倍数,否则就让CPU不能运行了。
从龙芯的使用手册中可以看到,每条 CPU 指令都是一条 32 位的指令字,这些指令都是字对齐的。指令集包含三种指令格式,如图 2-1 所示,立即数指令( I- 型),跳转指令( J- 型)和寄存器指令( J- 型)。使用简单几种指令格式可以简化指令译码,并且使得编译器根据这三种指令格式可以合成更多的复杂操作(使用频率较低)和访存模式。
op 6 位操作码
rs 5 位用于确定源操作寄存器的域
rt 5 位用于确定目标(源 / 目的)操作寄存器或跳转条件的域
immediate 16 位立即数
target 26 位跳转目标地址
rd 5 位用于确定目的操作寄存器的域
sa 5 位移位数
funct 6 位功能域
指令集可以更进一步分为以下几组:
• Load and Store 访存指令在主存和通用寄存器之间移动数据。访存指令都是立即数指令( I- 型),因为该指令模式所支持的唯一访存模式就是基址寄存器加上 16 位的对齐的偏移量。
• Computational 计算型指令完成寄存器值的算术,逻辑,移位,乘法和除法操作。计算型指令包含了寄存器指令格式( R- 型,操作数和运算结果均保存在寄存器中)和立即数指令格式( I- 型,其中一个操作数为一个 16 位的立即数)。龙芯 2E 微处理器还实现了自定义的乘法,除法和模操作指令,其方法是使用一个通用的目的寄存器来取代成
对出现的 hi 和 lo 寄存器。
• Jump and Branch 跳转和分支指令改变程序的控制流。绝对地址跳转被称为 “jump (跳转) ” ( J- 型或者 R- 型), PC (指令计数器)相关的跳转指令被称为 “branch (分支) ” ( I- 型)。跳转指令的返回地址保存在第 31 号寄存器中。
• Coprocessor 协处理器指令完成协处理器内部的操作。协处理器的访存操作是 I- 型指令。龙芯 2E 微处理器有两个协处理器: 0 号协处理器(系统处理器)和 1 号协处理器(浮点协处理器)。
0 号协处理器( CP0 )通过 CP0 的寄存器来管理内存和处理异常。这些指令列在表 3-9 中。
1 号协处理器( CP1 )指令包括浮点指令,多媒体指令,和龙芯扩展的定点计算指令。这些指令都是在浮点寄存器上操作。第八章将会对这些指令进行总结,附录将会对每条指令进行详细的描述。
• Special 特殊指令完成系统调用和断点操作。这些指令通常是 R- 型的。
• Exception 异常指令引起跳转,根据异常号比较结果跳转到通用异常处理向量。这些指令包括 R- 型和 I- 型指令格式。
表 2-1 到表 2-9 列出了除 1 号协处理器指令以外的所有指令。
表 2-1 CPU 指令集:访存指令
OpCode | Description | MIPS ISA |
LB | 取字节 | I |
LBU | 取无符号字节 | I |
LH | 取半字 | I |
LHU | 取无符号半字 | I |
LW | 取字 | I |
LWU | 取无符号字 | I |
LWL | 取字左部 | I |
LWR | 取字右部 | I |
LD | 取双字 | III |
LDL | 取双字左部 | III |
LDR | 取双字右部 | III |
LL | 取标志处地址 | I |
LLD | 取标志处双字地址 | III |
SB | 存字节 | I |
SH | 存半字 | I |
SW | 存字 | I |
SWL | 存字左部 | I |
SWR | 存字右部 | I |
SD | 存双字 | III |
SDL | 存双字左部 | III |
SDR | 存双字右部 | III |
SC | 满足条件下存 | I |
SCD | 满足条件下存双字 | III |
SYNC | 同步 | I |
表 2-2 CPU 指令集:算术指令 (ALU 立即数 )
OpCode | Description | MIPS ISA |
ADDI | 加立即数 | I |
DADDI | 加双字立即数 | III |
ADDIU | 加无符号立即数 | I |
DADDIU | 加无符号双字立即数 | III |
SLTI | d=((signed) s <(signed) j) ? 1:0 j 是立即数 | I |
SLTIU | d=((unsigned) s <(unsigned) j) ? 1:0 j 是立即数 | I |
ANDI | 与立即数 | I |
ORI | 或立即数 | I |
XORI | 异或立即数 | I |
LUI | t=u<<16 u 是立即数 | I |
表 2-3 CPU 指令集:算术指令 (3 操作数 , R- 型 )
OpCode | Description | MIPS ISA |
ADD | 加 | I |
DADD | 双字加 | III |
ADDU | 无符号加 | I |
DADDU | 无符号双字加 | III |
SUB | 减 | I |
DSUB | 双字减 | III |
SUBU | 无符号减 | I |
DSUBU | 无符号双字减 | III |
SLT | d=((signed) s <(signed) t) ? 1:0 | I |
SLTU | d=((unsigned) s <(unsigned) t) ? 1:0 | I |
AND | 与 | I |
OR | 或 | I |
XOR | 异或 | I |
NOR | 或非 | I |
表 2-4 CPU 指令集:乘法和除法指令
OpCode | Description | MIPS ISA |
MULT | 乘 | I |
DMULT | 双字乘 | III |
MULTU | 无符号乘 | I |
DMULTU | 无符号双字乘 | III |
DIV | 除 | I |
DDIV | 双字除 | III |
DIVU | 无符号除 | I |
DDIVU | 无符号双字除 | III |
MFHI | 移整数乘法单元结果到通用目的寄存器 | I |
MTHI | 移通用目的寄存器到整数乘法单元结果 | I |
MFLO | 移整数除法单元结果到通用目的寄存器 | I |
MTLO | 移通用目的寄存器到整数除法单元结果 | I |
MULTG | 龙芯 2E 乘 | GODSON2 |
DMULTG | 龙芯 2E 双字乘 | GODSON2 |
MULTUG | 龙芯 2E 无符号乘 | GODSON2 |
DMULTUG | 龙芯 2E 无符号双字乘 | GODSON2 |
DIVG | 龙芯 2E 除 | GODSON2 |
DDIVG | 龙芯 2E 双字除 | GODSON2 |
DIVUG | 龙芯 2E 无符号除 | GODSON2 |
DDIVUG | 龙芯 2E 无符号双字除 | GODSON2 |
MODG | 龙芯 2E 求模 | GODSON2 |
DMODG | 龙芯 2E 双字求模 | GODSON2 |
MODUG | 龙芯 2E 无符号求模 | GODSON2 |
DMODUG | 龙芯 2E 无符号双字求模 | GODSON2 |
表 2-5 CPU 指令集:跳转和分支指令
Opcode | Description | MIPS ISA |
J | 跳转 | I |
JAL | 立即数调用子程序 | I |
JR | 跳转到寄存器指向的指令 | I |
JALR | 寄存器调用子程序 | I |
BEQ | 相等则跳转 | I |
BNE | 不等则跳转 | I |
BLEZ | 小于等于 0 跳转 | I |
BGTZ | 大于 0 跳转 | I |
BLTZ | 小于 0 跳转 | I |
BGEZ | 大于或等于 0 跳转 | I |
BLTZAL | 小于 0 调用子程序 | I |
BGEZAL | 大于或等于 0 调用子程序 | I |
BEQL | 相等则 Likely 跳转 | II |
BNEL | 不等则 Likely 跳转 | II |
BLEZL | 小于或等于 0 则 Likely 跳转 | II |
BGTZL | 大于 0 则 Likely 跳转 | II |
BLTZL | 小于 0 则 Likely 跳转 | II |
BGEZL | 大于或等于 0 则 Likely 跳转 | II |
BLTZALL | 小于 0 则 Likely 调用子程序 | II |
BGEZALL | 大于或等于 0 则 Likely 调用子程序 | II |
表 2-6 CPU 指令集:移位指令
OpCode | Description | MIPS ISA |
SLL | 逻辑左移 | I |
SRL | 逻辑右移 | I |
SRA | 算术右移 | I |
SLLV | 可变的逻辑左移 | I |
SRLV | 可变的逻辑右移 | I |
SRAV | 可变的算术右移 | I |
DSLL | 双字逻辑左移 | III |
DSRL | 双字逻辑右移 | III |
DSRA | 双字算术右移 | III |
DSLLV | 可变的双字逻辑左移 | III |
DSRLV | 可变的双字逻辑右移 | III |
DSLL32 | d=(long long) s << (shift+32) 0<=shift<31 | III |
DSRL32 | d=(long long unsigned) s >> (shift%32) 0<=shift<31 | III |
DSRA32 | d=(long long signed) s >> (shift%32+32) 0<=shift<31 | III |
表 2-7 CPU 指令集:特殊指令
OpCode | Description | MIPS ISA |
SYSCALL | 系统调用 | I |
BREAK | 断点 | I |
表 2-8 CPU 指令集:异常指令
OpCode | Description | MIPS ISA |
TGE | 大于或等于陷入 | II |
TGEU | 无符号数大于或等于陷入 | II |
TLT | 小于陷入 | II |
TLTU | 无符号数小于陷入 | II |
TEQ | 等于陷入 | II |
TNE | 不等陷入 | II |
TGEI | 大于或等于立即数陷入 | II |
TGEIU | 大于或等于无符号立即数陷入 | II |
TLTI | 小于立即数陷入 | II |
TLTIU | 小于无符号立即数陷入 | II |
TEQI | 等于立即数陷入 | II |
TNEI | 不等于立即数陷入 | II |
表 2-9 CPU 指令集: CP0 指令
OpCode | Description | MIPS ISA |
DMFC0 | 从 CP0 寄存器取双字 | III |
DMTC0 | 往 CP0 寄存器写双字 | III |
MFC0 | 从 CP0 寄存器取 | I |
MTC0 | 往 CP0 寄存器写 | I |
TLBR | 读 TLB 索引项 | III |
TLBWI | 写 TLB 索引项 | III |
TLBWR | 写 Random 寄存器的 TLB 项 | III |
TLBP | 在 TLB 中搜索虚拟页号 | III |
CACHE | Cache 操作 | III |
ERET | 异常返回 | III |