RV32I基础整数指令集

一、一页的图形表示

 

以下面为例:

 可以表示四个RV32I指令:slt,slti,sltu,sltiu

二、指令格式

指令格式有六种,如下图

 R类型指令用于寄存器寄存器操作;I型指令用于短立即数和访存load操作;S型指令用于访存store操作;B类型指令用于条件跳转操作;U型指令用于长立即数;J型指令用于无条件跳转;

将上述的指令格式与第一节中的指令内容结合,即可得到所有的RV32I指令操作码,如下图

 指令格式的优势

1、指令只有六种格式,并且所有的指令都是32位长,简化指令编码。ARM-32,x86-32都有许多不同的指令格式,使得解码部件在低端实现中偏昂贵,在中高端处理器设计中容易带来性能挑战。

2、指令提供三个寄存器操作数,而不是想x86-32一样,让源操作数和目的操作数共享一个字段。当一个操作天然就需要三个不同的操作数,但是ISA只提供了两个操作数是,编译器或者汇编程序就需要多使用一条搬运指令move,来保存目的寄存器的值。

3、对于所有指令,要读写寄存器的标识符总是在同一位置,意味着在解码指令之前,就可以先开始访问寄存器。

4、立即数字段总是符号扩展,符号位总是在指令中最高位。这意味着可能成为关键路径的立即数符号扩展,可以在指令解码之前进行。

三、RV32I寄存器

RV32I有31个寄存器加个一个值恒为0的x0寄存器。与之相比,ARM-32只有16个寄存器,x86-32甚至只有8个寄存器。

不同之处

为常量0单独分配一个寄存器是RISC-V ISA简单的一个很大的因素。相比于许多ARM-32和x86-32原生指令操作,这两个指令集中没有零寄存器。我们可以用RV32I指令完成功能相同的操作,只需使用零寄存器为操作数。

程序计数器(PC)是ARM-32的16个寄存器之一,意味着认可改变寄存器的指令都可能导致分支跳转。使硬件分支预测变得复杂,在典型的ISA中,仅有10%到20%的指令为分支指令,而在ARM-32中,任何指令都可能是分支指令。而分支预测的准确性对于良好的流水线性能至关重要。另外将PC作为一个寄存器也意味着可用的通用寄存器少了一个。

四、RV32I整数运算

简单的算术指令(add,sub),逻辑指令(and,or,xor),移位指令(sll,srl,sra)。他们从寄存器读取两个32位的值,并将32位结果写进目标寄存器。而且还有这些指令的立即数版本。

小于时置位的指令(slt,sltu,slti,sltiu),可以检查两个寄存器间或立即数的所有关系。

加载立即数到高位(lui):将20位常量加载到寄存器的高20位。接着便可以使用标准的立即指令来创建32位常量。这样仅使用2条32位RV32I指令,便可构造一个32位常量。

向PC高位加上立即数(auipc)仅用2条指令,可以基于当前PC以任意偏移量转移控制流或着访问数据。

不同之处

RISC-V无字节或者半字宽度的整数计算操作。操作始终是以完整的寄存器宽度。内存访问需要的能量比算术运算高几个数量级。因此,低宽度的数据访问可以节省大量的能量,但低宽度的运算不会。

RV32I不包含乘法和除法,包含在可选的RV32M中。

五、RV32I的load和store

加载和存储32位字(lw,sw),加载有符号和无符号字节和半字(lb,lbu,lh,lhu)和存储字节半字(sb,sh)。有符号字节和半字符号扩展为32位再写入目的寄存器。即使是自然数据类型更窄,低位宽数据也是被扩展后再处理,这使得后续的整数计算指令能正确处理所有的32位。在文本和无符号整数中常用的无符号字节和半字,在写入目标寄存器之前都被无符号扩展都32位。

加载和存储的支持唯一寻址模式是符号扩展12位立即数到基地址寄存器,这在x86-32中被称为位偏移寻址模式。

不同之处

RV32I省略了ARM-32和x86-32的复杂寻址模式。另外,ARM-32提供的寻址模式并非适用于所有数据类型,但RV32I寻址不会歧视任何数据类型。RISC-V可以模仿某些x86寻址模式。

六、RV32I条件分支

RV32I可以比较两个寄存器并根据比较结果进行分支跳转。比较可以是,相等(beq),不相等(bne),大于等于(bge),小于(blt)。最后两种比较有符号比较,相应的无符号比较bgeu,bltu。

由于RISC-V指令长度必须是两个字节的倍数,分支指令的寻址方式是12位的立即数乘以2,符号扩展它,然后将得到值加到PC上作为分支的跳转地址。

不同之处

RISC-V去掉了MIPS-32,Oracle SPARC等指令集中被广为诟病的延迟分支特性等。对于条件分支,他还没有向ARM-32和x86-32那样使用条件码。条件码的存在使得大多数指令都需要吟诗设置一些额外状态,这使乱序执行的以来计算复杂化。还省略了x86-32中的循环指令:loop,loope,loopz,loopne,loopnz。

七、RV32I无条件跳转

跳转并链接指令(jal)具有双重功能,若将下一条指令PC+4的地址保存到目标寄存器中,通常是返回地址寄存器ra,便可以用它来实现过程调用。如果使用零寄存器(x0)替换ra作为目标寄存器,则可以实现无条件跳转,因为x0不能更改。像分支一样,jal将其20位分支地址乘以2,进行符号位扩展后再添加到PC上,便得到了跳转地址。

跳转和链接指令的寄存器版本(jalr)同样是多用途的。他可以调用地址是动态计算处理的函数,或者也可以实现调用返回(只需ra作为源寄存器,零寄存器(x0)作为目的寄存器)。

不同之处

RV32I避开了错综复杂的程序调用指令,例如x86-32的进入和离开指令,或Intel Itanium,Oracle SPARC和Cadance Tensilica中的寄存器窗口。

八、RV32I杂项

控制状态寄存器指令(csrrc,csrrs,csrrw,csrrci,csrrsi,csrrwi)可以轻松的访问一些程序性能计数器。对于这些64位计数器,一次可以读取32位。这些计数器包括系统时间,时钟周期以及执行的指令数目。

ecall指令用于向运行时环境发出请求,例如系统调用。调试器使用ebreak指令将控制转移到调试环境。

fence指令对外部可见的访存请求,如设备I/O和内存访问等进行串行化。外部可见指对处理器的其他核心、线程、外部设备或协处理器可见。fence.i指令同步指令和数据流。在执行fence.i指令之前,对于同一个硬件线程,RISC-V不保证用存储指令写到内存指令去的数据可以被被取指令取到。

不同之处

RISC-V使用内存映射I/O而不是像x86-32一样,使用in,ins,insb,insw和out,outs,outsb等指令来进行I/O。为支持字符串处理,RISC-V实现了字节存取,而不是像x86-32那样实现了rep,movs,coms,scas,lods等16条特色的字符串处理指令。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值