简介:
RISC-V 指令相对嵌入式中广泛使用的ARM指令的优点是设计简洁和模块化的设计,不过缺点也很明显,指令密度比较低,以ARM 指令集中的 存储/加载 指令来说明,在ARM 中使用一条指令可以同时完成数据的存储/加载及基地址的修改,在RISC-V 中需要使用两条指令,一条存储加载指令,一条ADD指令完成对基地址的修改。以下是官方文档对RSVC 指令密度的说明。
This chapter describes the current proposal for the RISC-V standard compressed instruction-set extension, named “C”, which reduces static and dynamic code size by adding short 16-bit instruction encodings for common operations. The C extension can be added to any of the base ISAs (RV32,RV64, RV128), and we use the generic term“RVC” to cover any of these. Typically, 50%–60% of the RISC-V instructions in a program can be replaced with RVC instructions, resulting in a 25%–30% code-size reduction.
RVC 代码指令格式说明如下:
因指令的code 格式只要16bit,指令中使用的rs1',rs2',rd' 的寄存器编码空间只有3bit 相对指令可以使用的寄存器也有限制,对应的寄存器索引如上,通用寄存器可以使用s0-s1,a0-a5 8个寄存器,浮点寄存器可以使用fs0-fs1,fa0-fa5,CR/CI/CSS 指令编码格式中寄存器域编码空间为5bit 可以使用x0-x31的所有寄存器,对应的官方文档说明如下.
RVC 所有指令编码格式如下
对于一条指令解码如何分辨出是32位指令还是16位指令是通过指令编码中的bit[1:0]来区分,当bit[1:0]=0b11时为32位指令,否则为16位指令。我们在编写汇编代码时不直接使用RVC指令,而让汇编器完成指令压缩,例如在GCC编译选项中设置-march参数,来编译芯片支持压缩指令,让GCC自动完成指令压缩。以下是GD32VF103 的编译参数其中 ’c‘代表支持压缩指令。
说到-march 编译器也会根据该编译参数的不同链接不同的库文件
了解了以上的基础知识后,我们在回头看我们之前使用内嵌汇编编写的memcpy(RISC-V GCC 内嵌汇编的使用)函数对应的反汇编代码。
40034284 <main>: 40034284: 1101 addi sp,sp,-32 40034286: ca26 sw s1,20(sp) 40034288: 0007c497 auipc s1,0x7c 4003428c: 98048493 addi s1,s1,-1664 # 400afc08 <dest.0> 40034290: ce06 sw ra,28(sp) 40034292: cc22 sw s0,24(sp) 40034294: c84a sw s2,16(sp) 40034296: c64e sw s3,12(sp) 40034298: 87a6 mv a5,s1 4003429a: 4701 li a4,0 4003429c: 00078697 auipc a3,0x78 400342a0: 1c868693 addi a3,a3,456 # 400ac464 <src.1> 400342a4: 00078617 auipc a2,0x78 400342a8: 1e060613 addi a2,a2,480 # 400ac484 <aic_audio_ops> 400342ac: 4298 lw a4,0(a3) 400342ae: c398 sw a4,0(a5) 400342b0: 0791 addi a5,a5,4 400342b2: 0691 addi a3,a3,4 400342b4: fec6cce3 blt a3,a2,400342ac <main+0x28>
上述代码的4-5 行为32位指令,2-3 为16位压缩指令,从中可以看出32位指令的bit[1:0]=0b11 从实际的反汇编代码也验证了该结论。从官方的文档中压缩指令集CSS 可以索引所有的寄存器,CS指令值只可以使用s0-s1,a0-a5 8个通用寄存器。上述代码的第8行和17行都是16bit的压缩指令,但是明显可以看出第7行访问了s2寄存器,从中也可以看出CSS 和 CS 指令对寄存器的索引范围的区别。