1.I-Type 移位指令
上文RISC-V指令集讲解 (2) I-Type整数寄存器-立即数指令介绍了I-type中的6个指令,本文将继续介绍I-type中其余的整数寄存器-立即数指令(这里是属于I-type的移位指令)和U-type中的整数寄存器-立即数指令。
图1所示为移动次数为立即数的移位指令,后面会介绍其他的移位指令。从机器编码格式上可以看出这三个指令与上文提到的6个I-type指令有些不同,本文的I-immediate被分为两个部分:
imm[11:5]中的imm[10](机器码的bit 30)用来区分移位类型,其中SLLI和SRLI指令机器码的bit 30为0,而SRAI指令机器码的bit 30为1 [1]。
imm[4:0]或shamt[4:0](shift amount)意为移动量,可以看到SLLI,SRLI和SRAI的shamt的范围都是[4:0],这是因为在RV32I中,最大的移位量是31位,也就是2^5 – 1。
图1 移位指令机器编码格式 [1]
1.1. SLLI
SLLI(shift left logical immediate),立即数逻辑左移指令格式为 SLLI rd,rs1,shamt。x[rd] = x[rs1] ≪ shamt
其机器码如图2所示,SLLI的OP-IMM为001_0011,funct3为001,IMM[10]为0。移动多少位由imm[4:0]来决定。该指令将rs1中的值左移shamt[4:0],rs1的低位补零,结果写入rd中。
示例:
SLLI x13,x12,3
将x12寄存器中的值左移3位,并将结果写入x13寄存器中。
OP-IMM为001_0011
funct3为001
shamt为5’b0_0011
bit 25-31 为7’b000_0000
rs1为 5’b0_1100
rd为 5’b0_1101
所以SLLI x13,x12,3对应的机器码为0000000_00011_01100_001_01101_0010011,对应的16进制为32’h0036_1693
图2 SLLI机器编码格式 [2]
1.2. SRLI
SRLI(shift right logical immediate),立即数逻辑右移指令格式为 SRLI rd,rs1,shamt。x[rd] = x[rs1] ≫ shamt
其机器码如图3所示,SRLI的OP-IMM为001_0011,funct3为101,IMM[10]为0。该指令将rs1中的值右移shamt[4:0]位,rs1的高位补零,结果写入rd中。
示例:
SRLI x13,x12,5
x12寄存器中的值右移5位,并将结果写入x13中
图3 SRLI机器编码格式 [2]
1.3. SRAI
SRAI(shift right arithmetic immediate),立即数算术右移指令格式为 SRAI rd,rs1,shamt。x[rd] = x[rs1] ≫ shamt
其机器码如图4所示,SRAI的OP-IMM为001_0011,funct3为101,IMM[10]为1。该指令将rs1中的值右移shamt[4:0]位,rs1的高位由原rs1[31]填充(符号位填充),结果写入rd中。
示例:
SRAI x13,x12,3
将x12寄存器中的值算术右移3位,并将结果写入x13中
图4 SRAI机器编码格式 [2]
注意:
SRLI,SRAI的OP-IMM和funct3编码皆相同,由imm[10]的值区别指令 [1]。
1.4. 举例区分算术右移和逻辑右移
注意区分算术右移和逻辑右移,例如1100_1100(这里以8-bit数进行说明,RV32I中寄存器中实际存储的数为32-bit),
1100_1100算术右移三位,结果为1111_1001
0011_0011算数右移三位,结果为0000_0110
而1100_1100逻辑右移三位结果是0001_1001
0011_0011逻辑右移三位,结果为0000_0110
2.U-Type整数寄存器-立即数指令
这里介绍的两条U-type指令中的AUIPC不再是操作通用寄存器(x0-x31),而是对程序计数器(program counter,PC)进行操作。
图5是LUI和AUIPC的机器码格式,将其与I-type的机器码进行比较,可以看到该类型没有rs1和funct3,取而代之的是一个20位的立即数(I-type中12位立即数的位置包含在内)。
注意U-type中的指令opcode是不相同的。与I-type相同的,U-type对应的immediate,固定为20位,被命名为U-immediate[31:12],如图5所示。
图5 U-type 整数寄存器-立即数指令 [1]
2.1. LUI
LUI(load upper immediate),高位立即数加载指令格式为 LUI rd,immediate。x[rd] = sext(immediate[31:12] << 12)
其机器码如图6所示,LUI的opcode为011_0111。该指令是把U-immediate写入rd的高20位,rd的低12位补零。
指令示例,
LUI x8,0xf0000
将0xf000_0000加载进x8寄存器中
opcode为011_0111
rd为5’b01000
immediate[31:12]为1111_0000_0000_0000_0000
其对应的32位机器码为1111_0000_0000_0000_0000_01000_0110111,用16进制化简后得到32’hF000_0437
图6 LUI机器编码格式 [2]
2.2. AUIPC
AUIPC(add upper immediate to PC),PC加立即数指令格式为 AUIPC rd,immediate。x[rd] = pc + sext(immediate[31:12] << 12)
其机器码如图7所示,AUIPC的opcode为001_0111。该指令是将20位的立即数符号扩展后,左移12位,和当前的PC相加,结果写入rd寄存器。
图7 AUIPC机器编码格式 [2]
指令示例:
AUIPC x12,0xf00
将0xf0_0000加上当前的PC,加载进x12寄存器中。
注意:
大多立即数很小或需要所有XLEN位。 RISC-V选择了非对称立即拆分(常规指令中为12位,再加上20位特殊的上载立即指令,比如LUI),以增加可用于常规指令的操作码空间 [1]。
AUIPC和JALR(后续文章会进行介绍)中的12位立即数的组合可以将控制权转移到任何32位PC相对地址,而AUIPC加上常规加载或存储指令中的12位立即数偏移量可以访问任何32位PC相对的数据地址。
当前的PC可以通过将AUIPC的U-immediate设置为0来获得。
备注:其他完整内容请搜索引擎搜索“IC知识库”查看。
知识库更多内容请关注:http://www.icfedu.cn/?_tg=bz
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。