每个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
|