
原手册链接 有错误请及时联系我
基础整数指令定义
算术运算类指令
ADD.W
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 00000 | rk | rj | rd | |||||||
指令格式: add.w rd, rj, rk
功能描述: ADD.W 将通用寄存器 rj 中的数据加上通用寄存器 rk 中的数据,所得结果的[31:0]位写入通用寄存器 rd 中。
操作定义:
tmp = GR[rj] + GR[rk]
GR[rd] = tmp[31:0]
SUB.W
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 00010 | rk | rj | rd | |||||||
指令格式: sub.w rd, rj, rk
功能描述: SUB.W 将通用寄存器 rj 中的数据减去通用寄存器 rk 中的数据,所得结果的[31:0]位写入通用寄存器 rd中。
操作定义:
tmp = GR[rj] - GR[rk]
GR[rd] = tmp[31:0]
ADDI.W
| 31 | 26 | 25 | 22 | 21 | 10 | 9 | 5 | 4 | 0 | ||||
| 000000 | 1010 | si12 | rj | rd | |||||||||
指令格式: addi.w rd, rj, si12
功能描述: ADDI.W 将通用寄存器 rj 中的数据加上 12 比特立即数 si12 符号扩展后的 32 位数据,所得结果写入通用寄存器 rd 中。
操作定义:
tmp = GR[rj] + SignExtend(si12, 32)
GR[rd] = tmp[31:0]
LUI12I.W
| 31 | 25 | 24 | 5 | 4 | 0 | ||||||||
| 0001010 | si20 | rd | |||||||||||
指令格式: lu12i.w rd, si20
功能描述: LU12I.W 将 20 比特立即数 si20 最低位连接上 12 比特 0 后写入通用寄存器 rd 中。
操作定义:
GR[rd] = {si20, 12’b0}
SLT
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 00100 | rk | rj | rd | |||||||
指令格式: slt rd, rj, rk
功能描述: SLT 将通用寄存器 rj 中的数据与通用寄存器 rk 中的数据视作有符号整数进行大小比较,如果前者小于后者,则将通用寄存器 rd 的值置为 1,否则置为 0。
操作定义:
GR[rd] = (signed(GR[rj]) < signed(GR[rk])) ? 1 : 0
SLTU
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 00101 | rk | rj | rd | |||||||
指令格式: sltu rd, rj, rk
功能描述: SLTU 将通用寄存器 rj 中的数据与通用寄存器 rk 中的数据视作无符号整数进行大小比较,如果前者小于后者,则将通用寄存器 rd 的值置为 1,否则置为 0 。
操作定义:
GR[rd] = (unsigned(GR[rj]) < unsigned(GR[rk])) ? 1 : 0
SLTI
| 31 | 26 | 25 | 22 | 21 | 10 | 9 | 5 | 4 | 0 | ||||
| 000000 | 1000 | si12 | rj | rd | |||||||||
指令格式: slti rd, rj, si12
功能描述: SLTI 将通用寄存器 rj 中的数据与 12 比特立即数 si12 符号扩展后所得的数据视作有符号整数进行大小比较,如果前者小于后者,则将通用寄存器 rd 的值置为 1,否则置为 0。
操作定义:
tmp = SignExtend(si12, 32)
GR[rd] = (signed(GR[rj]) < signed(tmp)) ? 1 : 0
SLTUI
| 31 | 26 | 25 | 22 | 21 | 10 | 9 | 5 | 4 | 0 | ||||
| 000000 | 1001 | si12 | rj | rd | |||||||||
指令格式: sltui rd, rj, si12
功能描述: SLTI 将通用寄存器 rj 中的数据与 12 比特立即数 si12 符号扩展后所得的数据视作无符号整数进行大小比较,如果前者小于后者,则将通用寄存器 rd 的值置为 1,否则置为 0。
操作定义:
tmp = SignExtend(si12, 32)
GR[rd] = (unsigned(GR[rj]) < unsigned(tmp)) ? 1 : 0
PCADDU12I
| 31 | 25 | 24 | 5 | 4 | 0 | ||||||||
| 0001110 | si20 | rd | |||||||||||
指令格式: pcaddu12i rd, si20
功能描述: PCADDU12I 将 20 比特立即数 si20 最低位连接上 12 比特 0 之后符号扩展,所得数据加上该指令的 PC,相加结果写入通用寄存器 rd 中。
操作定义:
GR[rd] = PC + SignExtend({si20, 12’b0}, 32)
MUL.W
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 11000 | rk | rj | rd | |||||||
指令格式: mul.w rd, rj, rk
功能描述: MUL.W 将通用寄存器 rj 中的数据与通用寄存器 rk 中的数据进行相乘,乘积结果的[31:0]位数据写入通用寄存器 rd 中。
操作定义:
product = signed(GR[rj]) * signed(GR[rk])
GR[rd] = product[31:0]
MULH.W
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 11001 | rk | rj | rd | |||||||
指令格式: mulh.w rd, rj, rk
功能描述: MULH.W将通用寄存器rj中的数据与通用寄存器rk中的数据视作有符号数进行相乘,乘积结果的[63:32]位数据写入通用寄存器 rd 中。
操作定义:
product = signed(GR[rj]) * signed(GR[rk])
GR[rd] = product[63:32]
MULH.WU
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 11010 | rk | rj | rd | |||||||
指令格式: mulh.wu rd, rj, rk
功能描述: MULH.WU 将通用寄存器 rj 中的数据与通用寄存器 rk 中的数据视作无符号数进行相乘,乘积结果的[63:32]位数据符号扩展后写入通用寄存器 rd 中。
操作定义:
product = unsigned(GR[rj]) * unsigned(GR[rk])
GR[rd] = product[63:32]
DIV.W,DIV.WU
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| DIV.W | 000000 | 0000 | 10 | 00000 | rk | rj | rd | |||||||
| DIV.WU | 000000 | 0000 | 10 | 00010 | rk | rj | rd | |||||||
指令格式:
div.w rd, rj, rk
div.wu rd, rj, rk
功能描述: DIV.W 和 DIV.WU 将通用寄存器 rj 中的数据除以通用寄存器 rk 中的数据,所得的商写入通用寄存器rd 中。
操作定义:
DIV.W:
quotient = signed(GR[rj]) / signed(GR[rk])
GR[rd] = quotient[31:0]
DIV.WU:
quotient = unsigned(GR[rj]) / unsigned(GR[rk])
GR[rd] = quotient[31:0]
MOD.W,MOD.WU
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| MOD.W | 000000 | 0000 | 10 | 00001 | rk | rj | rd | |||||||
| MOD.WU | 000000 | 0000 | 10 | 00011 | rk | rj | rd | |||||||
指令格式:
mod.w rd, rj, rk
mod.wu rd, rj, rk
功能描述: MOD.W 和 MOD.WU 将通用寄存器 rj 中的数据除以通用寄存器 rk 中的数据,所得的余数写入通用寄存器 rd 中。
操作定义:
MOD.W:
remainder = signed(GR[rj]) % signed(GR[rk])
GR[rd] = remainder[31:0]
MOD.WU:
remainder = unsigned(GR[rj]) % unsigned(GR[rk])
GR[rd] = remainder[31:0]
逻辑运算类指令
AND
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 01001 | rk | rj | rd | |||||||
功能描述: AND 将通用寄存器 rj 中的数据与通用寄存器 rk 中的数据进行按位逻辑与运算,结果写入通用寄存器rd 中。
操作定义:
GR[rd] = GR[rj] & GR[rk]
OR
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 01010 | rk | rj | rd | |||||||
指令格式: or rd, rj, rk
功能描述: OR 将通用寄存器 rj 中的数据与通用寄存器 rk 中的数据进行按位逻辑或运算,结果写入通用寄存器 rd中。
操作定义:
GR[rd] = GR[rj] | GR[rk]
NOR
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 01000 | rk | rj | rd | |||||||
指令格式: nor rd, rj, rk
功能描述: NOR 将通用寄存器 rj 中的数据与通用寄存器 rk 中的数据进行按位逻辑或非运算,结果写入通用寄存器rd 中。
操作定义:
GR[rd] = ~(GR[rj] | GR[rk])
XOR
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 01011 | rk | rj | rd | |||||||
指令格式: xor rd, rj, rk
功能描述: XOR 将通用寄存器 rj 中的数据与通用寄存器 rk 中的数据进行按位逻辑异或运算,结果写入通用寄存器rd 中。
操作定义:
GR[rd] = GR[rj] ^ GR[rk]
ANDI
| 31 | 26 | 25 | 22 | 21 | 10 | 9 | 5 | 4 | 0 | ||||
| 000000 | 1101 | si12 | rj | rd | |||||||||
指令格式: andi rd, rj, rk
功能描述: ANDI 将通用寄存器 rj 中的数据与 12 比特立即数零扩展之后的数据进行按位逻辑与运算,结果写入通用寄存器 rd 中。
操作定义:
GR[rd] = GR[rj] & ZeroExtend(ui12, 32)
ORI
| 31 | 26 | 25 | 22 | 21 | 10 | 9 | 5 | 4 | 0 | ||||
| 000000 | 1110 | si12 | rj | rd | |||||||||
指令格式: ori rd, rj, rk
功能描述: ORI 将通用寄存器 rj 中的数据与 12 比特立即数零扩展之后的数据进行按位逻辑或运算,结果写入通用寄存器 rd 中。
操作定义:
GR[rd] = GR[rj] | ZeroExtend(ui12, 32)
XORI
| 31 | 26 | 25 | 22 | 21 | 10 | 9 | 5 | 4 | 0 | ||||
| 000000 | 1111 | si12 | rj | rd | |||||||||
指令格式: xori rd, rj, rk
功能描述: XORI 将通用寄存器 rj 中的数据与 12 比特立即数零扩展之后的数据进行按位逻辑异或运算,结果写入通用寄存器 rd 中。
操作定义:
GR[rd] = GR[rj] ^ ZeroExtend(ui12, 32)
移位运算类指令
SLL.W
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 01110 | rk | rj | rd | |||||||
指令格式: sll.w rd, rj, rk
功能描述: SLL.W 将通用寄存器 rj 中的数据逻辑左移,移位结果写入通用寄存器 rd 中。
操作定义:
tmp = SLL(GR[rj], GR[rk][4:0])
GR[rd] = tmp[31:0]
SRL.W
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 01111 | rk | rj | rd | |||||||
指令格式: srl.w rd, rj, rk
功能描述: SRL.W 将通用寄存器 rj 中的数据逻辑右移,移位结果写入通用寄存器 rd中。
操作定义:
tmp = SRL(GR[rj], GR[rk][4:0])
GR[rd] = tmp[31:0]
SRA.W
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0000 | 01 | 10000 | rk | rj | rd | |||||||
指令格式: sra.w rd, rj, rk
功能描述: SRA.W 将通用寄存器 rj 中的数据算术右移,移位结果写入通用寄存器 rd 中。
操作定义:
tmp = SRA(GR[rj], GR[rk][4:0])
GR[rd] = tmp[31:0]
SLLI.W
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0001 | 00 | 00001 | ui5 | rj | rd | |||||||
指令格式: slli.w rd, rj, ui5
功能描述: SLLI.W 将通用寄存器 rj 中的数据逻辑左移,移位结果写入通用寄存器 rd 中。
操作定义:
tmp = SLL(GR[rj], ui5)
GR[rd] = tmp[31:0]
SRLI.W
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0001 | 00 | 01001 | ui5 | rj | rd | |||||||
指令格式: srli.w rd, rj, ui5
功能描述: SRLI.W 将通用寄存器 rj 中的数据逻辑右移,移位结果写入通用寄存器 rd 中。
操作定义:
tmp = SRL(GR[rj], ui5)
GR[rd] = tmp[31:0]
SRAI.W
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0001 | 00 | 10001 | ui5 | rj | rd | |||||||
指令格式: srai.w rd, rj, ui5
功能描述: SRAI.W 将通用寄存器 rj 中的数据算术右移,移位结果写入通用寄存器 rd 中。
操作定义:
tmp = SRA(GR[rj], ui5)
GR[rd] = tmp[31:0]
转移指令
BEQ
| 31 | 26 | 25 | 10 | 9 | 5 | 4 | 0 | ||||||
| 010110 | offs16 | rj | rd | ||||||||||
指令格式: beq rj, rd, offs16
功能描述: BEQ 将通用寄存器 rj 和通用寄存器 rd 的值进行比较,如果两者相等则跳转到目标地址,否则不跳转。
其跳转目标地址计算方式是将指令码中的16比特立即数offs16逻辑左移2位后再符号扩展,所得的偏移值加上该分支指令的PC。
操作定义:
if GR[rj] == GR[rd] :
PC = PC + SignExtend({offs16, 2’b0}, 32)
BNE
| 31 | 26 | 25 | 10 | 9 | 5 | 4 | 0 | ||||||
| 010111 | offs16 | rj | rd | ||||||||||
指令格式: bne rj, rd, offs16
功能描述: BNE 将通用寄存器 rj 和通用寄存器 rd 的值进行比较,如果两者不等则跳转到目标地址,否则不跳转。
其跳转目标地址计算方式是将指令码中的16比特立即数offs16逻辑左移2位后再符号扩展,所得的偏移值加上该分支指令的PC。
操作定义:
if GR[rj] != GR[rd] :
PC = PC + SignExtend({offs16, 2’b0}, 32)
BLT
| 31 | 26 | 25 | 10 | 9 | 5 | 4 | 0 | ||||||
| 011000 | offs16 | rj | rd | ||||||||||
指令格式: blt rj, rd, offs16
功能描述: BLT 将通用寄存器 rj 和通用寄存器 rd 的值视作有符号数进行比较,如果前者小于后者则跳转到目标地址,否则不跳转。
其跳转目标地址计算方式是将指令码中的16比特立即数offs16逻辑左移2位后再符号扩展,所得的偏移值加上该分支指令的PC。
操作定义:
if signed(GR[rj]) < signed(GR[rd]) :
PC = PC + SignExtend({offs16, 2’b0}, 32)
BGE
| 31 | 26 | 25 | 10 | 9 | 5 | 4 | 0 | ||||||
| 011001 | offs16 | rj | rd | ||||||||||
指令格式: bge rj, rd, offs16
功能描述: BGE 将通用寄存器 rj 和通用寄存器 rd 的值视作有符号数进行比较,如果前者大于等于后者则跳转到目标地址,否则不跳转。
其跳转目标地址计算方式是将指令码中的16比特立即数offs16逻辑左移2位后再符号扩展,所得的偏移值加上该分支指令的PC。
操作定义:
if signed(GR[rj]) >= signed(GR[rd]) :
PC = PC + SignExtend({offs16, 2’b0}, 32)
BLTU
| 31 | 26 | 25 | 10 | 9 | 5 | 4 | 0 | ||||||
| 011010 | offs16 | rj | rd | ||||||||||
指令格式: bltu rj, rd, offs16
功能描述: BLTU 将通用寄存器 rj 和通用寄存器 rd 的值视作无符号数进行比较,如果前者小于后者则跳转到目标地址,否则不跳转。
其跳转目标地址计算方式是将指令码中的16比特立即数offs16逻辑左移2位后再符号扩展,所得的偏移值加上该分支指令的PC。
操作定义:
if unsigned(GR[rj]) < unsigned(GR[rd]) :
PC = PC + SignExtend({offs16, 2’b0}, 32)
BGEU
| 31 | 26 | 25 | 10 | 9 | 5 | 4 | 0 | ||||||
| 011011 | offs16 | rj | rd | ||||||||||
指令格式: bgeu rj, rd, offs16
功能描述: BGEU 将通用寄存器 rj 和通用寄存器 rd 的值视作无符号数进行比较,如果前者大于等于后者则跳转到目标地址,否则不跳转。
其跳转目标地址计算方式是将指令码中的16比特立即数offs16逻辑左移2位后再符号扩展,所得的偏移值加上该分支指令的PC。
操作定义:
if unsigned(GR[rj]) >= unsigned(GR[rd]) :
PC = PC + SignExtend({offs16, 2’b0}, 32)
B
| 31 | 26 | 25 | 10 | 9 | 5 | 4 | 0 | ||||||
| 010100 | offs16 | rj | rd | ||||||||||
指令格式: b offs26
功能描述: B 无条件跳转到目标地址处。
其跳转目标地址是将指令码中的 26 比特立即数 offs26 逻辑左移 2 位后再符号扩展,所得的偏移值加上该分支指令的 PC。
操作定义:
PC = PC + SignExtend({offs26, 2’b0}, 32)
BL
| 31 | 26 | 25 | 10 | 9 | 5 | 4 | 0 | ||||||
| 010101 | offs16 | rj | rd | ||||||||||
指令格式: bl offs26
功能描述: BL 无条件跳转到目标地址处,同时将该指令的 PC 值加 4 的结果写入到 1 号通用寄存器 r1 中。
其跳转目标地址是将指令码中的 26 比特立即数 offs26 逻辑左移 2 位后再符号扩展,所得的偏移值加上该分支指令的 PC。
操作定义:
GR[1] = PC + 4
PC = PC + SignExtend({offs26, 2’b0}, 32)
JIRL
| 31 | 26 | 25 | 10 | 9 | 5 | 4 | 0 | ||||||
| 010011 | offs16 | rj | rd | ||||||||||
指令格式: jirl rj, rd, offs16
功能描述: JIRL 无条件跳转到目标地址处,同时将该指令的 PC 值加 4 的结果写入到通用寄存器 rd 中。
该指令的跳转目标地址是将指令码中的 16 比特立即数 offs16 逻辑左移 2 位后再符号扩展,所得的偏移值加上通用寄存器 rj中的值。
操作定义:
GR[rd] = PC + 4
PC = GR[rj] + SignExtend({offs16, 2’b0}, 32)
注:上述指令如果在写汇编时采用直接填入偏移值的方式,则汇编表示中的立即数应
填入以字节为单位的偏移值,即指令码中offs«2。
普通访存指令
LD.B,LD.H,LD.W
| 31 | 26 | 25 | 22 | 21 | 10 | 9 | 5 | 4 | 0 | |||||
| LD.B | 001010 | 0000 | si12 | rj | rd | |||||||||
| LD.H | 001010 | 0001 | si12 | rj | rd | |||||||||
| LD.W | 001010 | 0010 | si12 | rj | rd | |||||||||
指令格式:
ld.b rd, rj, si12
ld.h rd, rj, si12
ld.w rd, rj, si12
功能描述: LD.{B/H}从内存取回一个字节/半字的数据符号扩展后写入通用寄存器 rd,LD.W 从内存取回一个字的数据写入通用寄存器 rd。
其访存地址计算方式是将通用寄存器rj中的值与符号扩展后的12比特立即数si12相加求和。
操作定义:
LD.B:
vaddr = GR[rj] + SignExtend(si12, 32)
AddressComplianceCheck(vaddr)
paddr = AddressTranslation(vaddr)
byte = MemoryLoad(paddr, BYTE)
GR[rd] = SignExtend(byte, 32)
LD.H:
vaddr = GR[rj] + SignExtend(si12, 32)
AddressComplianceCheck(vaddr)
paddr = AddressTranslation(vaddr)
halfword = MemoryLoad(paddr, HALFWORD)
GR[rd] = SignExtend(halfword, 32)
LD.W:
vaddr = GR[rj] + SignExtend(si12, 32)
AddressComplianceCheck(vaddr)
paddr = AddressTranslation(vaddr)
word = MemoryLoad(paddr, WORD)
GR[rd] = word
例外: 如果访存地址非自然对齐1,则触发地址非对齐例外(ALE)。
LD.BU,LD.HU
| 31 | 26 | 25 | 22 | 21 | 10 | 9 | 5 | 4 | 0 | |||||
| LD.BU | 001010 | 1000 | si12 | rj | rd | |||||||||
| LD.HU | 001010 | 1001 | si12 | rj | rd | |||||||||
指令格式:
ld.bu rd, rj, si12
ld.hu rd, rj, si12
功能描述: LD.{BU/HU}从内存取回一个字节/半字的数据零扩展后写入通用寄存器 rd。
其访存地址计算方式是将通用寄存器rj中的值与符号扩展后的12比特立即数si12相加求和。
操作定义:
LD.BU:
vaddr = GR[rj] + SignExtend(si12, 32)
AddressComplianceCheck(vaddr)
paddr = AddressTranslation(vaddr)
byte = MemoryLoad(paddr, BYTE)
GR[rd] = ZeroExtend(byte, 32)
LD.HU:
vaddr = GR[rj] + SignExtend(si12, 32)
AddressComplianceCheck(vaddr)
paddr = AddressTranslation(vaddr)
halfword = MemoryLoad(paddr, HALFWORD)
GR[rd] = ZeroExtend(halfword, 32)
例外: 如果访存地址非自然对齐1,则触发地址非对齐例外(ALE)。
ST.B,ST.H,ST.W
| 31 | 26 | 25 | 22 | 21 | 10 | 9 | 5 | 4 | 0 | |||||
| ST.B | 001010 | 0100 | si12 | rj | rd | |||||||||
| ST.H | 001010 | 0101 | si12 | rj | rd | |||||||||
| ST.W | 001010 | 0110 | si12 | rj | rd | |||||||||
指令格式:
st.b rd, rj, si12
st.h rd, rj, si12
st.w rd, rj, si12
功能描述: ST.{B/H/W}将通用寄存器 rd 中的[7:0]/[15:0]/[31:0]位数据写入到内存中。
其访存地址计算方式是将通用寄存器rj中的值与符号扩展后的12比特立即数si12相加求和。
操作定义:
ST.B:
vaddr = GR[rj] + SignExtend(si12, 32)
AddressComplianceCheck(vaddr)
paddr = AddressTranslation(vaddr)
MemoryStore(GR[rd][7:0], paddr, BYTE)
ST.H:
vaddr = GR[rj] + SignExtend(si12, 32)
AddressComplianceCheck(vaddr)
paddr = AddressTranslation(vaddr)
MemoryStore(GR[rd][15:0], paddr, HALFWORD)
ST.W:
vaddr = GR[rj] + SignExtend(si12, 32)
AddressComplianceCheck(vaddr)
paddr = AddressTranslation(vaddr)
MemoryStore(GR[rd][31:0], paddr, WORD)
例外: 如果访存地址非自然对齐1,则触发地址非对齐例外(ALE)。
PRELD
| 31 | 26 | 25 | 22 | 21 | 10 | 9 | 5 | 4 | 0 | ||||
| 000000 | 1001 | si12 | rj | hint | |||||||||
指令格式: preld hint, rj, si12
功能描述: PRELD 从内存中预取一个 Cache 行的数据进入 Cache 中。其访存地址的计算方式是将通用寄存器 rj 中的值与符号扩展后的 12 比特立即数 si12 相加求和。该访存地址落在待预取的 Cache 行内。
PRELD 指令中的 hint 提示处理器预取的类型以及取回的数据填入哪一级 Cache。hint 从 0~31 有 32 个可选值。目前 hint=0 定义为 load 预取至一级数据 Cache,hint=8 定义为 store 预取至一级数据 Cache。其余hint 值的含义暂未定义,处理器执行时视同 NOP 指令处理。
如果 PRELD 指令的访存地址的 Cache 属性不是 cached,那么该指令不能产生访存动作,视同 NOP 指令处理。
原子访存指令
LL.W, SC.W
| 31 | 26 | 25 | 24 | 23 | 10 | 9 | 5 | 4 | 0 | |||||
| LL.W | 001000 | 00 | si14 | rj | rd | |||||||||
| SC.W | 001010 | 01 | si14 | rj | rd | |||||||||
指令格式:
ll.w rd, rj, si14
sc.w rd, rj, si14
功能描述: LL.W 和 SC.W 这一对指令用于实现原子的“读-修改-写”访存操作序列。LL.W 指令从内存指定地址取回一个字的数据符号扩展后写入通用寄存器 rd,与之配对的 SC.W 指令操作同样宽度的数据且访问相同的内存地址。访存操作序列原子性的维护机制是,LL.W 执行时记录下访问地址并置上一个标记(LLbit 置为1),SC.W 指令执行时会查看 LLbit,仅当 LLbit 为 1 时才真正产生写动作,否则不写。当软件需要一定成功完成一个原子的“读-修改-写”访存操作序列时,需要构建一个循环来反复执行 LL-SC 指令对直至 SC 成功完成。为了构建这个循环,SC.{W/D}指令会将其执行成功与否的标志(也可以简单理解为 SC 指令执行时所看到的 LLbit 值)写入到通用寄存器 rd 中返回。
在配对的 LL-SC 执行期间,下列事件会让 LLbit 清 0:
❖ 执行了 ERTN 指令且执行时 CSR.LLBCTL 中的 KLO 位不等于 1;
❖ 其它处理器核或 Cache Coherent I/O master 对该 LLbit 对应的地址所在的 Cache 行执行完成了一个store 操作。
如果 LL-SC 指令对访问地址的存储访问属性不是 Cached,那么执行结果不确定。
需要注意的是,上述指令在计算内存地址时,需要将指令码中的 si14 左移 2 位后再与基址相加,即
vaddr = GR[rj] + SignExtend({si14, 2’b0}, 32)
栅障指令
DBAR
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 0 | ||||
| 001110 | 0001 | 11 | 00100 | hint | |||||||||
指令格式: dbar hint
功能描述: DBAR 指令用于完成 load/store 访存操作之间的栅障功能。其携带的立即数 hint 用于指示该栅障的同步对象和同步程度。
hint 值为 0 是默认必须实现的,其指示一个完全功能的同步栅障。只有等到之前所有 load/store 访存操作彻底执行完毕后,“DBAR 0”指令才能开始执行;且只有“DBAR 0”执行完成执行后,其后所有 load/store访存操作才能开始执行。
如果没有专门的功能实现,其它所有 hint 值都必须按照 hint=0 执行。
IBAR
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 0 | ||||
| 001110 | 0001 | 11 | 00101 | hint | |||||||||
指令格式: ibar hint
功能描述: IBAR 指令使用完成单个处理器核内部 store 操作与取指操作之间的同步。其携带的立即数 hint 用于指示该栅障的同步对象和同步程度。
hint 值为 0 是默认必须实现的。它能够确保“IBAR 0”指令之后的取指一定能够观察到“IBAR 0”指令之前所有 store操作的执行效果。
其它杂项指令
SYSCALL
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 0 | ||||
| 000000 | 0000 | 10 | 10110 | code | |||||||||
指令格式: syscall code
功能描述: 执行 SYSCALL 指令将立即无条件的触发系统调用例外。
指令码中 code 域携带的信息可供例外处理例程作为所传递的参数使用。
例外: 执行SYSCALL指令将确定地立刻触发系统调用例外(SYS)。
BREAK
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 0 | ||||
| 000000 | 0000 | 10 | 10100 | code | |||||||||
指令格式: break code
功能描述: 执行 BREAK 指令将立即无条件的触发系统调用例外。
指令码中 code 域携带的信息可供例外处理例程作为所传递的参数使用。
例外: 执行BREAK指令将确定地立刻触发断点例外(BRK)。
RDCNTV{L/H}.W, RDCNTID
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| RDCNTID | 000000 | 0000 | 00 | 00000 | 11000 | rj | 00000 | |||||||
| RDCNTVL.W | 000000 | 0000 | 00 | 00000 | 11000 | 00000 | rd | |||||||
| RDCNTVH.W | 000000 | 0000 | 00 | 00000 | 11001 | 00000 | rd | |||||||
指令格式:
rdcntvl.w rd
rdcntvh.w rd
rdcntid rj
功能描述: 龙芯架构 32 位精简版定义了一个恒定频率计时器,其主体是一个 64 位的计数器,称为 Stable Counter。Stable Counter 在复位后置为 0,随后每个计数时钟周期自增 1,当计数至全 1 时自动绕回至 0 继续自增。同时每个计时器都有一个软件可配置的全局唯一编号,称为 Counter ID。
RDCNTV{L/H}.W 指令用于读取恒定频率计时器信息,其中 RDCNTVL.W 读取 Counter 的[31:0]位写入通用寄存器 rd 中,RDCNTVH.W 读取 Counter 的[63:32]位。RDCNTID Counter ID 号信息写入通用寄存器 rj中。
龙芯架构 32 位精简版中的
RDCNTVL.W rd、RDCNTVH.W rd和RDCNTID rj指令实际上分别对应 32位龙芯架构中的RDTIMEL.W rd, zero、RDTIMEH.W rd, zero和RDTIMEL.W zero, rj这三种 RDTIME{L/H}.W指令的特殊使用。
操作定义:
RDCNTVL.W:
GR[rd] = Counter [31:0]
RDCNTVH.W:
GR[rd] = Counter [63:32]
RDCNTID:
GR[rj] = Counter ID
基础浮点数指令
浮点运算类指令
FADD.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FADD.S | 000000 | 0100 | 00 | 00001 | fk | fj | fd | |||||||
| FADD.D | 000000 | 0100 | 00 | 00010 | fk | fj | fd | |||||||
指令格式:
fadd.s fd, fj, fk
fadd.d fd, fj, fk
功能描述: FADD.{S/D}指令将浮点寄存器 fj 中的单精度/双精度浮点数加上浮点寄存器 fk 中的单精度/双精度浮点数,得到的单精度/双精度浮点数结果写入到浮点寄存器 fd 中。浮点加法运算遵循 IEEE 754-2008 标准中addition(x,y)操作的规范。
操作定义:
FADD.S:
FR[fd][31:0] = FP32_addition(FR[fj][31:0], FR[fk][31:0])
FADD.D:
FR[fd] = FP64_addition(FR[fj], FR[fk])
FSUB.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FSUB.S | 000000 | 0100 | 00 | 00101 | fk | fj | fd | |||||||
| FSUB.D | 000000 | 0100 | 00 | 00110 | fk | fj | fd | |||||||
指令格式:
fsub.s fd, fj, fk
fsub.d fd, fj, fk
功能描述: FSUB.{S/D}指令将浮点寄存器 fj 中的单精度/双精度浮点数减去浮点寄存器 fk 中的单精度/双精度浮点数,得到的单精度/双精度浮点数结果写入到浮点寄存器 fd 中。浮点减法运算遵循 IEEE 754-2008 标准中subtraction(x,y)操作的规范。
操作定义:
FSUB.S:
FR[fd][31:0] = FP32_subtraction(FR[fj][31:0], FR[fk][31:0])
FSUB.D:
FR[fd] = FP64_subtraction(FR[fj], FR[fk])
FMUL.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FMUL.S | 000000 | 0100 | 00 | 01001 | fk | fj | fd | |||||||
| FMUL.D | 000000 | 0100 | 00 | 01010 | fk | fj | fd | |||||||
指令格式:
fmul.s fd, fj, fk
fmul.d fd, fj, fk
功能描述: FMUL.{S/D}指令将浮点寄存器 fj 中的单精度/双精度浮点数乘以浮点寄存器 fk 中的单精度/双精度浮点数,得到的单精度/双精度浮点数结果写入到浮点寄存器 fd 中。浮点乘法运算遵循 IEEE 754-2008 标准中multiplication(x,y)操作的规范。
操作定义:
FMUL.S:
FR[fd][31:0] = FP32_multiplication(FR[fj][31:0], FR[fk][31:0])
FMUL.D:
FR[fd] = FP64_multiplication(FR[fj], FR[fk])
FDIV.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FDIV.S | 000000 | 0100 | 00 | 01101 | fk | fj | fd | |||||||
| FDIV.D | 000000 | 0100 | 00 | 01110 | fk | fj | fd | |||||||
指令格式:
fdiv.s fd, fj, fk
fdiv.d fd, fj, fk
功能描述: FDIV.{S/D}指令将浮点寄存器 fj 中的单精度/双精度浮点数除以浮点寄存器 fk 中的单精度/双精度浮点数,得到的单精度/双精度浮点数结果写入到浮点寄存器 fd 中。浮点除法运算遵循 IEEE 754-2008 标准中division(x,y)操作的规范。
操作定义:
FDIV.S:
FR[fd][31:0] = FP32_division(FR[fj][31:0], FR[fk][31:0])
FDIV.D:
FR[fd] = FP64_division(FR[fj], FR[fk])
FMADD.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FMADD.S | 000010 | 0000 | 01 | fa | fk | fj | fd | |||||||
| FMADD.D | 000010 | 0000 | 10 | fa | fk | fj | fd | |||||||
指令格式:
fmadd.s fd, fj, fk
fmadd.d fd, fj, fk
功能描述: FMADD.{S/D}指令将浮点寄存器 fj 中的单精度/双精度浮点数与浮点寄存器 fk 中的单精度/双精度浮点数相乘,得到的结果加上浮点寄存器 fa 中的单精度/双精度浮点数,得到的单精度/双精度浮点数结果写入到浮点寄存器 fd 中。
操作定义:
FMADD.S:
FR[fd][31:0] = FP32_fusedMultiplyAdd(FR[fj][31:0], FR[fk][31:0], FR[fa][31:0])
FMADD.D:
FR[fd] = FP64_fusedMultiplyAdd(FR[fj], FR[fk], FR[fa])
FMSUB.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FMSUB.S | 000010 | 0001 | 01 | fa | fk | fj | fd | |||||||
| FMSUB.D | 000010 | 0001 | 10 | fa | fk | fj | fd | |||||||
指令格式:
fmsub.s fd, fj, fk
fmsub.d fd, fj, fk
功能描述: FMSUB.{S/D}指令将浮点寄存器 fj 中的单精度/双精度浮点数与浮点寄存器 fk 中的单精度/双精度浮点数相乘,得到的结果减去浮点寄存器 fa 中的单精度/双精度浮点数,得到的单精度/双精度浮点数结果写入到浮点寄存器 fd 中。
操作定义:
FMSUB.S:
FR[fd][31:0] = FP32_fusedMultiplyAdd(FR[fj][31:0], FR[fk][31:0], -FR[fa][31:0])
FMSUB.D:
FR[fd] = FP64_fusedMultiplyAdd(FR[fj], FR[fk], -FR[fa])
FNMADD.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FNMADD.S | 000010 | 0010 | 01 | fa | fk | fj | fd | |||||||
| FNMADD.D | 000010 | 0010 | 10 | fa | fk | fj | fd | |||||||
指令格式:
fnmadd.s fd, fj, fk
fnmadd.d fd, fj, fk
功能描述: FNMADD.{S/D}指令将浮点寄存器 fj 中的单精度/双精度浮点数与浮点寄存器 fk 中的单精度/双精度浮点数相乘,得到的结果加上浮点寄存器 fa 中的单精度/双精度浮点数,得到的单精度/双精度浮点数结果取负后写入到浮点寄存器 fd 中。
操作定义:
FNMADD.S:
FR[fd][31:0] = -FP32_fusedMultiplyAdd(FR[fj][31:0], FR[fk][31:0], FR[fa][31:0])
FNMADD.D:
FR[fd] = -FP64_fusedMultiplyAdd(FR[fj], FR[fk], FR[fa])
FNMSUB.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FNMSUB.S | 000010 | 0011 | 01 | fa | fk | fj | fd | |||||||
| FNMSUB.D | 000010 | 0011 | 10 | fa | fk | fj | fd | |||||||
指令格式:
fnmsub.s fd, fj, fk
fnmsub.d fd, fj, fk
功能描述: FNMSUB.{S/D}指令将浮点寄存器 fj 中的单精度/双精度浮点数与浮点寄存器 fk 中的单精度/双精度浮点数相乘,得到的结果减去浮点寄存器 fa 中的单精度/双精度浮点数,得到的单精度/双精度浮点数结果取负后写入到浮点寄存器 fd 中。
操作定义:
FNMSUB.S:
FR[fd][31:0] = -FP32_fusedMultiplyAdd(FR[fj][31:0], FR[fk][31:0], -FR[fa][31:0])
FNMSUB.D:
FR[fd] = -FP64_fusedMultiplyAdd(FR[fj], FR[fk], -FR[fa])
FMAX.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FMAX.S | 000000 | 0100 | 00 | 10001 | fk | fj | fd | |||||||
| FMAX.D | 000000 | 0100 | 00 | 10010 | fk | fj | fd | |||||||
指令格式:
fmax.s fd, fj, fk
fmax.d fd, fj, fk
功能描述: FMAX.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数与浮点寄存器 fk 中的单精度/双精度浮点数中的较大者写入到浮点寄存器 fd 中。这两条指令的运算遵循 IEEE 754-2008 标准中 maxNum(x,y)操作的规范。
操作定义:
FMAX.S:
FR[fd][31:0] = FP32_maxNum(FR[fj][31:0], FR[fk][31:0])
FMAX.D:
FR[fd] = FP64_maxNum(FR[fj], FR[fk])
FMIN.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FMIN.S | 000000 | 0100 | 00 | 10101 | fk | fj | fd | |||||||
| FMIN.D | 000000 | 0100 | 00 | 10110 | fk | fj | fd | |||||||
指令格式:
fmin.s fd, fj, fk
fmin.d fd, fj, fk
功能描述: FMIN.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数与浮点寄存器 fk 中的单精度/双精度浮点数中的较小者写入到浮点寄存器 fd 中。这两条指令的运算遵循 IEEE 754-2008 标准中 minNum(x,y)操作的规范。
操作定义:
FMIN.S:
FR[fd][31:0] = FP32_minNum(FR[fj][31:0], FR[fk][31:0])
FMIN.D:
FR[fd] = FP64_minNum(FR[fj], FR[fk])
FMAXA.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FMAXA.S | 000000 | 0100 | 00 | 11001 | fk | fj | fd | |||||||
| FMAXA.D | 000000 | 0100 | 00 | 11010 | fk | fj | fd | |||||||
指令格式:
fmaxa.s fd, fj, fk
fmaxa.d fd, fj, fk
功能描述: FMAXA.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数与浮点寄存器 fk 中的单精度/双精度浮点数中绝对值较大者写入到浮点寄存器 fd 中。这两条指令的运算遵循 IEEE 754-2008 标准中 maxNumMag(x,y)操作的规范。
操作定义:
FMAXA.S:
FR[fd][31:0] = FP32_maxNumMag(FR[fj][31:0], FR[fk][31:0])
FMAXA.D:
FR[fd] = FP64_maxNumMag(FR[fj], FR[fk])
FMINA.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FMINA.S | 000000 | 0100 | 00 | 11101 | fk | fj | fd | |||||||
| FMINA.D | 000000 | 0100 | 00 | 11110 | fk | fj | fd | |||||||
指令格式:
fmina.s fd, fj, fk
fmina.d fd, fj, fk
功能描述: FMINA.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数与浮点寄存器 fk 中的单精度/双精度浮点数中绝对值较小者写入到浮点寄存器fd中。这两条指令的运算遵循IEEE 754-2008标准中minNumMag(x,y)操作的规范。
操作定义:
FMINA.S:
FR[fd][31:0] = FP32_minNumMag(FR[fj][31:0], FR[fk][31:0])
FMINA.D:
FR[fd] = FP64_minNumMag(FR[fj], FR[fk])
FABS.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FABS.S | 000000 | 0100 | 01 | 01000 | 00001 | fj | fd | |||||||
| FABS.D | 000000 | 0100 | 01 | 01000 | 00010 | fj | fd | |||||||
指令格式:
fabs.s fd, fj
fabs.d fd, fj
功能描述: FABS.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数,取其绝对值(也即将符号位置为 0,其它部分不变),写入到浮点寄存器 fd 中。这两条指令的运算遵循 IEEE 754-2008 标准中 abs(x)操作的规范。
操作定义:
FABS.S:
FR[fd][31:0] = FP32_abs(FR[fj][31:0])
FABS.D:
FR[fd] = FP64_abs(FR[fj])
FNEG.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FNEG.S | 000000 | 0100 | 01 | 01000 | 00101 | fj | fd | |||||||
| FNEG.D | 000000 | 0100 | 01 | 01000 | 00110 | fj | fd | |||||||
指令格式:
fneg.s fd, fj
fneg.d fd, fj
功能描述: FNEG.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数,取其相反数(也即将符号位取反,其它部分不变),写入到浮点寄存器 fd 中。这两条指令的运算遵循 IEEE 754-2008 标准中 negate(x)操作的规范。
操作定义:
FNEG.S:
FR[fd][31:0] = FP32_negate(FR[fj][31:0])
FNEG.D:
FR[fd] = FP64_negate(FR[fj])
FSQRT.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FSQRT.S | 000000 | 0100 | 01 | 01000 | 10001 | fj | fd | |||||||
| FSQRT.D | 000000 | 0100 | 01 | 01000 | 10010 | fj | fd | |||||||
指令格式:
fsqrt.s fd, fj
fsqrt.d fd, fj
功能描述: FSQRT.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数,将其开方后得到的单精度/双精度浮点数写入到浮点寄存器 fd 中。浮点开方运算遵循 IEEE 754-2008 标准中 squareRoot(x)操作的规范。
操作定义:
FSQRT.S:
FR[fd][31:0] = FP32_squareRoot(FR[fj][31:0])
FSQRT.D:
FR[fd] = FP64_squareRoot(FR[fj])
FRECIP.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FRECIP.S | 000000 | 0100 | 01 | 01000 | 10101 | fj | fd | |||||||
| FRECIP.D | 000000 | 0100 | 01 | 01000 | 10110 | fj | fd | |||||||
指令格式:
frecip.s fd, fj
frecip.d fd, fj
功能描述: FRECIP.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数,用 1.0 除以这个浮点数后将得到的单精度/双精度浮点数写入到浮点寄存器 fd 中。相当于 IEEE 754-2008 标准中 division(1.0,x)操作。
操作定义:
FRECIP.S:
FR[fd][31:0] = FP32_division(1.0, FR[fj][31:0])
FRECIP.D:
FR[fd] = FP64_division(1.0, FR[fj])
FRSQRT.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FRSQRT.S | 000000 | 0100 | 01 | 01000 | 11001 | fj | fd | |||||||
| FRSQRT.D | 000000 | 0100 | 01 | 01000 | 11010 | fj | fd | |||||||
指令格式:
frsqrt.s fd, fj
frsqrt.d fd, fj
功能描述: FRSQRT.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数,将其开方后得到的单精度/双精度浮点数再用 1.0除,得到的单精度/双精度浮点数写入到浮点寄存器 fd 中。浮点开方求倒运算遵循 IEEE 754-2008标准中 rSqrt(x)操作的规范。
操作定义:
FRSQRT.S:
FR[fd][31:0] = FP32_division(1.0, FP_squareRoot(FR[fj][31:0]))
FRSQRT.D:
FR[fd] = FP64_division(1.0, FP_squareRoot(FR[fj]))
FCOPYSIGN.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FCOPYSIGN.S | 000000 | 0100 | 01 | 00101 | fk | fj | fd | |||||||
| FCOPYSIGN.D | 000000 | 0100 | 01 | 00110 | fk | fj | fd | |||||||
指令格式:
fcopysign.s fd, fj, fk
fcopysign.d fd, fj, fk
功能描述: FCOPYSIGN.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数,将它的符号位改为浮点寄存器 fk中的单精度/双精度浮点数的符号位,得到的新的单精度/双精度浮点数写入到浮点寄存器 fd 中。浮点复制符号运算遵循 IEEE 754-2008 标准中 copySign(x, y)操作的规范。
操作定义:
FCOPYSIGN.S:
FR[fd][31:0] = FP32_copySign(FR[fj][31:0], FR[fk][31:0])
FCOPYSIGN.D:
FR[fd] = FP64_copySign(FR[fj], FR[fk])
FCLASS.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FCLASS.S | 000000 | 0100 | 01 | 01000 | 01101 | fj | fd | |||||||
| FCLASS.D | 000000 | 0100 | 01 | 01000 | 01110 | fj | fd | |||||||
指令格式:
fclass.s fd, fj
fclass.d fd, fj
功能描述: 本指令对浮点寄存器 fj 中的浮点数进行类别的判断,所得的判断结果一共由 10 比特信息组成,每比特的含义如下表所示:
| Bit0 | Bit1 | Bit2 | Bit3 | Bit4 | Bit5 | Bit6 | Bit7 | Bit8 | Bit9 |
|---|---|---|---|---|---|---|---|---|---|
| SNaN | QNaN | negative value | positive value | ||||||
| ∞ | normal | subnormal | 0 | ∞ | normal | subnormal | 0 | ||
当被判断的数据符合某个比特对应的条件时,结果信息向量的对应比特就会被置为 1。该指令对应IEEE 754-2008 标准中的 class(x)函数。
操作定义:
FCLASS.S:
FR[fd][31:0] = FP32_class(FR[fj][31:0])
FCLASS.D:
FR[fd] = FP64_class(FR[fj])
浮点比较指令
FCMP.cond.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FCMP.cond.S | 000011 | 0000 | 01 | cond | fk | fj | cd | |||||||
| FCMP.cond.D | 000011 | 0000 | 01 | cond | fk | fj | cd | |||||||
指令格式:
fcmp.cond.s cc, fj, fk
fcmp.cond.d cc, fj, f
功能描述: 这是一条浮点比较指令,将比较的结果存入指定的状态码(cc)。这条指令的 cond 有 22 种,这些比较条件以及判断的标准在下表中列出来:
| 助记符 | cond | 含义 | True Condition | QNaN是否 报例外 | 对应 IEEE 754-2008 函数 |
|---|---|---|---|---|---|
| CAF | Ox0 | 否 | 无 | 否 | |
| CUN | 0x8 | 无法比较 | UN | compareQuietUnordered | |
| CEQ | 0x4 | 相等 | EQ | compareQuietEqual | |
| CUEQ | OxC | 相等或无法比较 | UN EQ | ||
| CLT | 0x2 | 小于 | LT | compareQuietLess | |
| CULT | OxA | 小于或无法比较 | UN LT | compareQuietLessUnordered | |
| CLE | 0x6 | 小于等于 | LT EQ | compareQuietLessEqual | |
| CULE | OxE | 小于等于或无法比较 | UN LT EQ | compareQuietNotGreater | |
| CNE | 0x10 | 不等 | GT LT | ||
| COR | 0x14 | 有序 | GT LT EQ | ||
| CUNE | 0x18 | 无法比较或不等 | UN GT LT | compareQuietNotEqual | |
| SAF | 0x1 | 否 | 无 | 是 | |
| SUN | 0x9 | 不是大于小于或等于 | UN | ||
| SEQ | 0x5 | 相等 | EQ | compareSignalingEqual | |
| SUEQ | OxD | 不是大于或小于 | UN EQ | ||
| SLT | 0x3 | 小于 | LT | compareSignalingLess | |
| SULT | OxB | 不是大于或等于 | UN LT | compareSignalingLessUnordered | |
| SLE | 0x7 | 小于等于 | LT EQ | compareSignalingLessEqual | |
| SULE | OxF | 不是大于 | UN LT EQ | compareSignalingNotGreater | |
| SNE | 0x11 | 不等 | GT LT | ||
| SOR | 0x15 | 有序 | GT LT EQ | ||
| SUNE | 0x19 | 无法比较或不等 | UN GT LT | ||
| 注:UN表示无法比较、EQ表示相等、LT表示小于。当有两个操作数中有至少一个NaN时,这两个数就无法比较。 | |||||
浮点转换指令
FCVT.S.D
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0100 | 01 | 10010 | 00110 | fj | fd | |||||||
指令格式: fcvt.s.d fd, fj
功能描述: FCVT.S.D 指令选择浮点寄存器 fj 中的双精度浮点数转换为单精度浮点数,得到的单精度浮点数写入到浮点寄存器 fd 中。
操作定义:
FR[fd][31:0] = FP32_convertFormat(FR[fj], FP64)
FCVT.D.S
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000000 | 0100 | 01 | 10010 | 01001 | fj | fd | |||||||
指令格式: fcvt.d.s fd, fj
功能描述: FCVT.D.S 指令选择浮点寄存器 fj 中的单精度浮点数转换为双精度浮点数,得到的双精度浮点数写入到浮点寄存器 fd 中。
操作定义:
FR[fd] = FP64_convertFormat(FR[fj][31:0], FP32)
FFINT.{S/D}.W
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FFINT.S.W | 000000 | 0100 | 01 | 11010 | 00100 | fj | fd | |||||||
| FFINT.D.W | 000000 | 0100 | 01 | 11010 | 01000 | fj | fd | |||||||
指令格式:
ffint.s.w fd, fj
ffint.d.w fd, fj
功能描述: FFINT.{S/D}.W 指令选择浮点寄存器 fj 中的整数型定点数转换为单精度/双精度浮点数,得到的单精度/双精度浮点数写入到浮点寄存器 fd 中。此浮点格式转换运算遵循 IEEE 754-2008 标准中 convertFromInt(x)操作的规范。
操作定义:
FFINT.S.W:
FR[fd][31:0] = FP32_convertFromInt(FR[fj][31:0], SINT32)
FFINT.D.W:
FR[fd] = FP64_convertFromInt(FR[fj][31:0], SINT32)
FTINT.W.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FFINT.W.S | 000000 | 0100 | 01 | 10110 | 00001 | fj | fd | |||||||
| FFINT.W.D | 000000 | 0100 | 01 | 10110 | 00010 | fj | fd | |||||||
指令格式:
ftint.w.s fd, fj
ftint.w.d fd, fj
功能描述: FTINT.W.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数转换为整数型定点数,得到的整数型定点数写入到浮点寄存器 fd 中。根据 FCSR 中不同的状态,此浮点格式转换运算遵循的 IEEE 754-2008 标准中的操作见下表:
| 舍入模式 | IEEE754-2008标准中的操作 |
|---|---|
| 向最近的偶数舍入 | convertTolntegerExactTiesToEven(x) |
| 向零方向舍入 | convertTolntegerExactTowardZero(x) |
| 向正无穷方向舍入 | convertTolntegerExacrTowardPositive(x) |
| 向负无穷方向舍入 | convertTolntegerExactTowardNegative(x) |
操作定义:
FTINT.W.S:
FR[fd][31:0] = FP32convertToSint32(FR[fj][31:0], FCSR.RM)
FTINT.W.D:
FR[fd] = FP64convertToSint32(FR[fj], FCSR.RM)
FTINT{RM/RP/RZ/RNE}.W.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FTINTRM.W.S | 000000 | 0100 | 01 | 10100 | 00001 | fj | fd | |||||||
| FTINTRM.W.D | 000000 | 0100 | 01 | 10100 | 00010 | fj | fd | |||||||
| FTINTRP.W.S | 000000 | 0100 | 01 | 10100 | 10001 | fj | fd | |||||||
| FTINTRP.W.D | 000000 | 0100 | 01 | 10100 | 10010 | fj | fd | |||||||
| FTINTRZ.W.S | 000000 | 0100 | 01 | 10101 | 00001 | fj | fd | |||||||
| FTINTRZ.W.D | 000000 | 0100 | 01 | 10101 | 00010 | fj | fd | |||||||
| FTINTRNE.W.S | 000000 | 0100 | 01 | 10101 | 10001 | fj | fd | |||||||
| FTINTRNE.W.D | 000000 | 0100 | 01 | 10101 | 10010 | fj | fd | |||||||
指令格式:
ftintrm.w.s fd, fj ftintrp.w.s fd, fj
ftintrm.w.d fd, fj ftintrp.w.d fd, fj
ftintrz.w.s fd, fj ftintrne.w.s fd, fj
ftintrz.w.d fd, fj ftintrne.w.d fd, fj
功能描述: FTINTRM.W.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数转换为整数型定点数,得到的整数型定点数写入到浮点寄存器 fd 中,采用“向负无穷方向舍入”的方式。
FTINTRP.W.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数转换为整数型定点数,得到的整数型定点数写入到浮点寄存器fd 中,采用“向正无穷方向舍入”的方式。
FTINTRZ.W.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数转换为整数型定点数,得到的整数型定点数写入到浮点寄存器 fd 中,采用“向零方向舍入”的方式。
FTINTRNE.W.{S/D}指令选择浮点寄存器 fj 中的单精度/双精度浮点数转换为整数型定点数,得到的整数型定点数写入到浮点寄存器 fd 中,采用“向最近的偶数舍入”的方式。
操作定义:
FTINTRM.W.S:
FR[fd][31:0] = FP32convertToSint32(FR[fj][31:0], 3)
FTINTRM.W.D:
FR[fd] = FP64convertToSint32(FR[fj], 3)
FTINTRP.W.S:
FR[fd][31:0] = FP32convertToSint32(FR[fj][31:0], 2)
FTINTRP.W.D:
FR[fd] = FP64convertToSint32(FR[fj], 2)
FTINTRZ.W.S:
FR[fd][31:0] = FP32convertToSint32(FR[fj][31:0], 1)
FTINTRZ.W.D:
FR[fd] = FP64convertToSint32(FR[fj], 1)
FTINTRNE.W.S:
FR[fd][31:0] = FP32convertToSint32(FR[fj][31:0], 0)
FTINTRNE.W.D:
FR[fd] = FP64convertToSint32(FR[fj], 0)
浮点搬运指令
FMOV.{S/D}
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| FMOV.S | 000000 | 0100 | 01 | 01001 | 00101 | fj | fd | |||||||
| FMOV.D | 000000 | 0100 | 01 | 01001 | 00110 | fj | fd | |||||||
指令格式:
fmov.s fd, fj
fmov.d fd, fj
功能描述: FMOV.{S/D}将浮点寄存器 fj 的值按单精度/双精度浮点数格式写入到浮点寄
存器 fd 中,如果 fj 的值不是单精度/双精度浮点数格式,则结果不确定。
操作定义:
FMOV.S:
FR[fd][31:0] = FR[fj][31:0]
FMOV.d:
FR[fd] = FR[fj]
例外: 上述指令操作是非算术的,不会引发 IEEE 754 例外,也不修改浮点控制状态寄存器的 Cause 和 Flags域。
FSEL
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000011 | 0100 | 00 | ca | fk | fj | fd | |||||||
指令格式: fsel fd, fj, fk, ca
功能描述: FSEL 指令进行条件赋值操作。FSEL 执行时,如果条件标志寄存器 ca 的值等于 0 则将浮点寄存器 fj 的值写入到浮点寄存器 fd 中,否则将浮点寄存器 fk 的值写入到浮点寄存器 fd 中。
操作定义:
FR[fd] = CFR[ca] ? FR[fk] : FR[fj]
MOVGR2FR.W, MOVGR2FRH.W
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| MOVGR2FR.W | 000000 | 0100 | 01 | 01001 | 01001 | rj | fd | |||||||
| MOVGR2FRH.W | 000000 | 0100 | 01 | 01001 | 01010 | rj | fd | |||||||
指令格式:
movgr2fr.w fd, rj
movgr2frh.w fd, rj
功能描述: MOVGR2FR.W 将通用寄存器 rj 值写入浮点寄存器 fd 的低 32 位中。若浮
点寄存器位宽为 64 位,则 fd的高 32 位值不确定。
MOVGR2FRH.W 将通用寄存器 rj 值写入浮点寄存器 fd 的高 32 位中,浮点寄存器 fd 的低 32 位值不变。
操作定义:
MOVGR2FR.W:
FR[fd][31:0] = GR[rj]
MOVGR2FRH.W:
FR[fd][63:32] = GR[rj]
FR[fd][31: 0] = FR[fd][31:0]
MOVFR2GR.S, MOVFRH2GR.S
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| MOVFR2GR.S | 000000 | 0100 | 01 | 01001 | 01101 | fj | rd | |||||||
| MOVFRH2GR.S | 000000 | 0100 | 01 | 01001 | 01110 | fj | rd | |||||||
指令格式:
movfr2gr.s rd, fj
movfrh2gr.s rd, fj
功能描述: MOVFR2GR/MOVFRH2GR.S 将浮点寄存器 fj 的低 32 位/高 32 位值写入
通用寄存器 rd。
操作定义:
MOVFR2GR.S:
GR[rd] = FR[fj][31:0]
MOVFRH2GR.S:
GR[rd] = FR[fj][63:32]
MOVGR2FCSR, MOVFCSR2GR
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| MOVGR2FCSR | 000000 | 0100 | 01 | 01001 | 10000 | rj | fcsr | |||||||
| MOVFCSR2GR | 000000 | 0100 | 01 | 01001 | 10010 | fcsr | rd | |||||||
指令格式:
movgr2fcsr fcsr, rj
movfcsr2gr rd, fcsr
功能描述: MOVGR2FCSR 根据通用寄存器 rj 值修改 fcsr 指示的浮点控制状态寄存器对应的软件可写域的值。如果MOVGR2FCSR 指令修改 FCSR0 使得其 Cause 域的位和对应的 Enables 的位同时为 1,或者修改 FCSR1 的Enables 域、FCSR2 的 Cause 域,使得 Cause 的位和对应 Enables 位同时为 1,MOVGR2FCSR 指令自身不会触发浮点例外。
MOVFCSR2GR 将 fcsr 指示的浮点控制状态寄存器的 32 位值写入通用寄存器 rd。
操作定义:
MOVGR2FCSR:
FCSR[fcsr] = GR[rj]
MOVFCSR2GR:
GR[rd] = FCSR[fcsr]
**注:**如果上述指令中的 fcsr 指示的浮点控制状态寄存器不存在,则结果不确定。
MOVFR2CF, MOVCF2FR
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| MOVFR2CF | 000000 | 0100 | 01 | 01001 | 10101 | fj | cd | |||||||
| MOVCF2FR | 000000 | 0100 | 01 | 01001 | 10101 | cj | fd | |||||||
指令格式:
movfr2cf cd, fj
movcf2fr fd, cj
功能描述:
MOVFR2CF 将浮点寄存器 fj 的最低一比特的值写入条件标志寄存器 cd。
MOVCF2FR 将条件标志寄存器 cj 的值写入浮点寄存器 fd 的最低一比特,fd 余下的位补 0。
操作定义:
MOVFR2CF:
CFR[cd] = FR[fj][0]
MOVCF2FR:
FR[fd][0] = ZeroExtend(CFR[cj], 64)
MOVGR2CF, MOVCF2GR
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 | |
| MOVGR2CF | 000000 | 0100 | 01 | 01001 | 10110 | rj | cd | |||||||
| MOVCF2GR | 000000 | 0100 | 01 | 01001 | 10111 | cj | rd | |||||||
指令格式:
movgr2cf cd, rj
movcf2gr rd, cj
功能描述:
MOVGR2CF 将通用寄存器 rj 的最低一比特的值写入条件标志寄存器 cd。
MOVCF2GR 将条件标志寄存器 cj 的值写入通用寄存器 rd 的最低一比特,rd 余下的位补 0。
操作定义:
MOVGR2CF:
CFR[cd] = GR[rj][0]
MOVCF2GR:
GR[rd][0] = ZeroExtend(CFR[cj], 32)
浮点分支指令
BCEQZ
| 31 | 26 | 25 | 10 | 9 | 8 | 7 | 5 | 4 | 0 | ||||||
| 010010 | offs21[15:0] | 00 | cj | offs21[20:16] | |||||||||||
指令格式: bceqz cj, offs21
功能描述: BCEQZ 对条件标志寄存器 cj 的值进行判断,如果等于 0 则跳转到目标地址,否则不跳转。
跳转目标地址是将指令码中的 21 比特立即数 offs21 逻辑左移 2 位后再符号扩展,所得的偏移值加上该分支指令的 PC。
操作定义:
if CFR[cj]==0 :
PC = PC + SignExtend({offs21, 2’b0}, 32)
BCNEZ
| 31 | 26 | 25 | 10 | 9 | 8 | 7 | 5 | 4 | 0 | ||||||
| 010010 | offs21[15:0] | 01 | cj | offs21[20:16] | |||||||||||
指令格式: bcnez cj, offs21
功能描述: BCNEZ 对条件标志寄存器 cj 的值进行判断,如果不等于 0 则跳转到目标地址,否则不跳转。
跳转目标地址是将指令码中的 21 比特立即数 offs21 逻辑左移 2 位后再符号扩展,所得的偏移值加上该分支指令的 PC。
操作定义:
if CFR[cj]!=0 :
PC = PC + SignExtend({offs21, 2’b0}, 32)
注:上述指令如果在写汇编时采用直接填入偏移值的方式,则汇编表示中的立即数应
填入以字节为单位的偏移值,即指令码中offs«2。
浮点普通访存指令
FLD.{S/D}, FST.{S/D}
| 31 | 26 | 25 | 22 | 21 | 10 | 9 | 5 | 4 | 0 | |||||
| FLD.S | 001010 | 1100 | si12 | rj | fd | |||||||||
| FLD.D | 001010 | 1101 | si12 | rj | fd | |||||||||
| FLT.S | 001010 | 1110 | si12 | rj | fd | |||||||||
| FLT.D | 001010 | 1111 | si12 | rj | fd | |||||||||
指令格式:
fld.s fd, rj, si12
fld.d fd, rj, si12
fst.s fd, rj, si12
fst.d fd, rj, si12
功能描述: FLD.S 从内存取回一个字的数据写入浮点寄存器 fd 的低 32 位。若浮点寄存器位宽为 64 位,则 fd 的高32 位值不确定。FLD.D 从内存取回一个双字的数据写入浮点寄存器 fd。
FST.S 将浮点寄存器 fd 中低 32 位字数据写入到内存中。FST.D 将浮点寄存器 fd 中双字数据写入到内存中。
其访存地址计算方式是将通用寄存器 rj 中的值与符号扩展后的 12 比特立即数 si12 相加求和。
操作定义:
FLD.S:
vaddr = GR[rj] + SignExtend(si12, 32)
AddressComplianceCheck(vaddr)
paddr = AddressTranslation(vaddr)
word = MemoryLoad(paddr, WORD)
FR[fd][31:0] = word
FLD.D:
vaddr = GR[rj] + SignExtend(si12, 32)
AddressComplianceCheck(vaddr)
paddr = AddressTranslation(vaddr)
doubleword = MemoryLoad(paddr, DOUBLEWORD)
FR[fd] = doubleword
FST.S:
vaddr = GR[rj] + SignExtend(si12, 32)
AddressComplianceCheck(vaddr)
paddr = AddressTranslation(vaddr)
MemoryStore(FR[fd][31:0], paddr, WORD)
FST.D:
vaddr = GR[rj] + SignExtend(si12, 32)
AddressComplianceCheck(vaddr)
paddr = AddressTranslation(vaddr)
MemoryStore(FR[fd][63:0], paddr, DOUBLEWORD)
例外: 如果访存地址非自然对齐1,则触发地址非对齐例外(ALE)。
特权指令
CSR 访问指令
CSRRD, CSRWR, CSRXCHG
| 31 | 26 | 25 | 24 | 23 | 10 | 9 | 5 | 4 | 0 | |||||
| CSRRD | 000001 | 00 | csr | 00000 | rd | |||||||||
| CSRWR | 000001 | 00 | csr | 00001 | rd | |||||||||
| CSRXCHG | 000001 | 00 | csr | rj!=0,1 | rd | |||||||||
指令格式:
csrrd rd, csr_num
csrwr rd, csr_num
csrxchg rd, rj, csr_num
功能描述:
CSRRD、CSRWR 和 CSRXCHG 指令用于软件访问 CSR。
CSRRD 指令将指定 CSR 的值写入到通用寄存器 rd 中。
CSRWR 指令将通用寄存器 rd 中的旧值写入到指定 CSR 中,同时将指定 CSR 的旧值更新到通用寄存器 rd 中。
CSRXCHG 指令根据通用寄存器 rj 中存放的写掩码信息,将通用寄存器 rd 中的旧值写入到指定 CSR 中对应写掩码为 1 的那些比特,该 CSR 中的其余比特保持不变,同时将该 CSR 的旧值更新到通用寄存器 rd 中。
所有 CSR 寄存器采用独立的寻址空间。上述指令中 CSR 的寻址值来自于指令中的 14 比特立即数csr_num。CSR 的寻址单位是一个 CSR 寄存器,即 0 号 CSR 的 csr_num 是 0,1 号 CSR 的 csr_num 是 1,以此类推。
在龙芯架构 32 位精简版中,所有 CSR 寄存器的位宽都是 32 位。
当 CSR 访问指令访问一个架构中未定义或硬件未实现的 CSR 时,读动作返回全 0 值,写动作不修改处理器的任何软件可见状态。需要提请注意的是,CSRWR 和 CSRXCHG 指令不仅包含更新 CSR 的写动作,也包含读取 CSR 旧值的读动作。
Cache 维护指令
CACOP
| 31 | 26 | 25 | 22 | 21 | 10 | 9 | 5 | 4 | 0 | ||||
| 000001 | 1000 | si12 | rj | rd | |||||||||
指令格式: cacop code, rj, si12
功能描述:
CACOP 指令主要用于 Cache 的初始化以及 Cache 一致性维护。
通用寄存器 rj 的值加上符号扩展后的 12 位立即数 si12,将得到 CACOP 指令所用的虚拟地址 VA,其将用于指示被操作 Cache 行的位置。
CACOP 指令访问哪个 Cache 以及进行何种 Cache 操作由指令中 5 比特的 code 决定。code[2:0]指示操作的 Cache 对象,code[4:3]指示操作类型。
code[2:0]=0 表示操作一级私有指令 Cache,code[2:0]=1 表示操作一级私有数据 Cache,code[2:0]=2 表示操作二级共享混合 Cache。
code[4:3]=0 表示用于 Cache 初始化(Store Tag),将指定 Cache 行的 tag 置为全 0。假设被访问的 Cache有(1«Way)路,每一路有(1«Index)个 Cache 行,每个 Cache 行大小为(1«Offset)个字节,那么采用地址直接索引方式意味着,操作该 Cache 的第 VA[Way-1:0]路的第 VA[Index+Offset-1:Offset]个 Cache 行。
code[4:3]=1 表示采用地址直接索引方式维护 Cache 一致性(Index Invalidate / Invalidate and Writeback)。地址直接索引方式的定义请见上一段的描述。维护一致性的操作是对指定的 Cache 进行无效并写回的操作。如果被操作的是指令 Cache,那么仅需要进行无效操作,并不需要将 Cache 行中的数据写回。写回的数据进入到哪一级存储中由具体实现的 Cache 层次及各级间的包含或互斥关系决定。对于数据 Cache 或混合 Cache,由具体实现决定是否仅在 Cache 行数据为脏时才将其写回。
code[4:3]=2 表示采用查询索引方式维护 Cache 一致性(Hit Invalidate / Invalidate and Writeback)。这里维护 Cache 一致性的操作与上面一段所述一致。所谓查询索引方式,是将 CACOP 指令的 VA 视作一个普通 load指令去访问待操作的 Cache,如果命中则对命中的 Cache 行进行操作,否则不做任何操作。由于这个查询过程可能涉及虚实地址转换,所以这种情况下 CACOP 指令可能触发 TLB 相关的例外。不过,由于 CACOP指令操作的对象是 Cache 行,所以这种情况下并不需要考虑地址对齐与否。
code[4:3]=3 属于实现自定义的 Cache 操作,架构规范中不予明确的功能定义。
TLB 维护指令
TLBSRCH
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000001 | 1001 | 00 | 10000 | 01010 | 00000 | 00000 | |||||||
指令格式: tlbsrch
功能描述:
使用 CSR.ASID 和 CSR.TLBEHI 的信息去查询 TLB。如果有命中项,那么将命中项的索引值写入到CSR.TLBIDX 的 Index 域,同时将 CSR.TLBIDX 的 NE 位置为 0;如果没有命中项,那么将 CSR.TLBIDX 的NE 位置为 1。
TLB 中各项的索引值计算规则是,从 0 开始依次递增编号,从第 0 行至最后一行。
TLBRD
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000001 | 1001 | 00 | 10000 | 01011 | 00000 | 00000 | |||||||
指令格式: tlbrd
功能描述:
将 CSR.TLBIDX 的 Index 域的值作为索引值去读取 TLB 中的指定项。如果指定位置处是一个有效 TLB项,那么将该 TLB 项的页表信息写入到 CSR.TLBEHI、CSR.TLBELO0、CSR.TLBELO1 和 CSR.TLBIDX.PS中,且将 CSR.TLBIDX 的 NE 位置为 0;如果指定位置处是一个无效 TLB 项,需将 CSR.TLBIDX 的 NE 位置为 1,且将 CSR.ASID.ASID、CSR.TLBEHI、CSR.TLBELO0、CSR.TLBELO1 和 CSR.TLBIDX.PS 全置为0。
需要注意的是,有效/无效 TLB 项和 TLB 中的页表项有效/无效是两个概念。如果访问所用的 index 值超过了 TLB 的范围,则处理器的行为不确定
TLBWR
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000001 | 1001 | 00 | 10000 | 01100 | 00000 | 00000 | |||||||
指令格式: tlbwr
功能描述:
TLBWR 指令将 TLB 相关 CSR 中所存放的页表项信息写入到 TLB 的指定项。被填入的页表项信息来自于 CSR.TLBEHI、CSR.TLBELO0、CSR.TLBELO1 和 CSR.TLBIDX.PS。若此时 CSR.ESTAT.Ecode=0x3F,即处于 TLB 重填例外处理过程中,那么 TLB 中总是填入一个有效项(即 TLB 项的 E 位为 1)。否则的话,就需要看 CSR.TLBIDX.NE 位的值。此时如果 CSR.TLBIDX.NE=1,那么 TLB 中会被填入一个无效 TLB 项;仅当 CSR.TLBIDX.NE=0 时,TLB 中才会被填入一个有效 TLB 项。
执行 TLBWR 时,页表项写入 TLB 的位置是由 CSR.TLBIDX 的 Index 域的值指定的。具体的对应规则请参看 TLBSRCH 指令中关于 TLB中各项索引值的计算规则。
TLBFILL
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000001 | 1001 | 00 | 10000 | 01101 | 00000 | 00000 | |||||||
指令格式: tlbfill
功能描述:
TLBFILL 指令将 TLB 相关 CSR 中所存放的页表项信息填入到 TLB 中。被填入的页表项信息来自于CSR.TLBEHI、CSR.TLBELO0、CSR.TLBELO1 和 CSR.TLBIDX.PS。若此时 CSR.ESTAT.Ecode=0x3F,即处于 TLB 重填例外处理过程中,那么 TLB 中总是填入一个有效项(即 TLB 项的 E 位为 1)。否则的话,就需要看 CSR.TLBIDX.NE 位的值。此时如果 CSR.TLBIDX.NE=1,那么 TLB 中会被填入一个无效 TLB 项;仅当 CSR.TLBIDX.NE=0 时,TLB 中才会被填入一个有效 TLB 项。
执行 TLBFILL 时,页表项被填入到 TLB 的哪一项,是由硬件随机选择的。
INVTLB
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000001 | 1001 | 00 | 10011 | rk | rj | op | |||||||
指令格式: invtlb op, rj, rk
功能描述:
INVTLB 指令用于无效 TLB 中的内容,以维持 TLB 与内存之间页表数据的一致性。
指令的三个源操作数中,op 是 5 比特立即数,用于指示操作类型。
通用寄存器 rj 的[9:0]位存放无效操作所需的 ASID 信息(称为“寄存器指定 ASID”),其余比特必须填0。当 op 所指示的操作不需要 ASID 时,应将通用寄存器 rj 设置为 r0。
通用寄存器 rk 中用于存放无效操作所需的虚拟地址信息(称为“寄存器指定 VA”)。当 op 所指示的操作不需要虚拟地址信息时,应将通用寄存器 rk 设置为 r0。
各 op 对应的操作如下表所示,未在表中出现的 op 将触发保留指令例外。
| op | 操作 |
|---|---|
| 0x0 | 清除所有页表项 |
| 0x1 | 清除所有页表项,此时操作效果与 op=0 完全一致 |
| 0x2 | 清除所有 G=1 的页表项 |
| 0x3 | 清除所有 G=0 的页表项 |
| 0x4 | 清除所有 G=0,且 ASID 等于寄存器指定 ASID 的页表项 |
| 0x5 | 清除 G=0,且 ASID 等于寄存器指定 ASID,且 VA 等于寄存器指定 VA 的页表项 |
| 0x6 | 清除所有 G=1 或 ASID 等于寄存器指定 ASID,且 VA 等于寄存器指定 VA 的页表项 |
其它杂项指令
ERTN
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 10 | 9 | 5 | 4 | 0 |
| 000001 | 1001 | 00 | 10000 | 01110 | 00000 | 00000 | |||||||
指令格式: ertn
功能描述:
ERTN 指令用于从例外处理返回。
将例外对应的 PPLV、PIE 等信息更新至 CSR.CRMD 中,同时跳转到例外所对应的 ERA处开始取指。
例外对应的 PPLV、PIE 信息来自于 CSR.PRMD,例外对应的 ERA 来自于 CSR.ERA。
执行 ERTN 指令时,如果 CSR.LLBCTL 中的 KLO 位不等于 1,则将 LLbit 置 0,否则 LLbit 不修改。
IDLE
| 31 | 26 | 25 | 22 | 21 | 20 | 19 | 15 | 14 | 0 | ||||
| 000001 | 1001 | 00 | 10001 | level | |||||||||
指令格式: idle level
功能描述:
IDLE 指令执行完毕后,处理器核将停止取指进入等待状态,直至其被中断唤醒或被复位。从停止状态
被中断唤醒后,处理器核执行的第一条指令是 IDLE 之后的那一条指令。
CSR 寄存器
| 名称 | 地址 | 描述 |
|---|---|---|
| CRMD | 0x0 | 当前模式信息 |
| PRMD | 0x1 | 例外前模式信息 |
| EUEN | 0x2 | 扩展部件使能 |
| ECFG | 0x4 | 例外配置 |
| ESTAT | 0x5 | 例外状态 |
| ERA | 0x6 | 例外返回地址 |
| BADV | 0x7 | 出错虚地址 |
| EENTRY | 0xC | 例外入口地址 |
| TLBIDX | 0x10 | TLB 索引 |
| TLBEHI | 0x11 | TLB 表项高位 |
| TLBELO0 | 0x12 | TLB 表项低位 0 |
| TLBELO1 | 0x13 | TLB 表项低位 1 |
| ASID | 0x18 | 地址空间标识符 |
| PGDL | 0x19 | 低半地址空间全局目录基址 |
| PGDH | 0x1A | 高半地址空间全局目录基址 |
| PGD | 0x1B | 全局目录基址 |
| CPUID | 0x20 | 处理器标识 |
| SAVE0~SAVE3 | 0x30~0x33 | 数据保存 |
| TID | 0x40 | 定时器编号 |
| TCFG | 0x41 | 定时器配置 |
| TVAL | 0x42 | 定时器值 |
| TICLR | 0x44 | 定时中断清除 |
| LLBCTL | 0x60 | LLBit控制 |
| TLBRENTRY | 0x88 | TLB重填入口地址 |
| CTAG | 0x98 | Cache Tag |
| DMW0~DMW1 | 0x180~0x181 | 直接映射配置窗口 |
异常
| 异常代号 | 异常编号 | 说明 | 类别 |
|---|---|---|---|
| PIL | 0x1 | load操作页无效异常 | 地址转换异常 |
| PIS | 0x2 | store操作页无效异常 | 地址转换异常 |
| PIF | 0x3 | 取指操作页无效异常 | 地址转换异常 |
| PME | 0x4 | 页修改异常 | 地址转换异常 |
| PNR | 0x5 | 页不可读异常 | 地址转换异常 |
| PNX | 0x6 | 页不可执行异常 | 地址转换异常 |
| PPI | 0x7 | 页权限等级不合规异常 | 地址转换异常 |
| ADEF | 0x8 0x0 | 取指地址错异常 | 指令执行中异常 |
| ADEM | 0x8 0x1 | 访存地址错异常 | 指令执行中异常 |
| ALE | 0x9 | 地址非对齐异常 | 指令执行中异常 |
| BCE | 0xA | 边界约束检查错误异常 | 指令执行中异常 |
| SYS | 0xB | 系统调用异常 | 系统调用和陷入 |
| BRK | 0xC | 断点异常 | 系统调用和陷入 |
| INE | 0xD | 指令不存在异常 | 指令执行中异常 |
| IPE | 0xE | 指令权限等级错异常 | 指令执行中异常 |