有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
RISC-V没有条件码,如何处理32位加法溢出?如何处理32位减法借位?以及如执行64位数的加减法?
64位加法
写一段64位加法的程序: - uint64_t add64u(uint64_t a, uint64_t b)
- {
- uint64_t c;
- c = a + b;
- return c;
- }
复制代码
以RV32架构编译,然后反汇编: - $ riscv64-unknown-elf-gcc -O2 -c -o 64.o -march=rv32i -mabi=ilp32 -Wall 64.c
- $ riscv64-unknown-elf-objdump -d -M no-aliases 64.o
复制代码
反汇编结果如果: - 00000000 <add64u>:
- 0: 00050793 addi a5,a0,0
- 4: 00c50533 add a0,a0,a2
- 8: 00f537b3 sltu a5,a0,a5
- c: 00d585b3 add a1,a1,a3
- 10: 00b785b3 add a1,a5,a1
- 14: 00008067 jalr zero,0(ra)
复制代码
按照函数调用规约,a0,a1存储第一个64位入参a,a2,a3存储第二个64位入参b,返回值c存储在a0,a1,低字节存储在编号较低的寄存器。
- 0: 00050793 addi a5,a0,0: 首先保存一下a的低32位,后面还要用。
- 4: 00c50533 add a0,a0,a2: a的低32位加上b的低32位。
- 8: 00f537b3 sltu a5,a0,a5: 比较c的低32位和a的低32位,如果c的低32位比a的低32位小,那么说明加法溢出了,必须产生进位,此时a5寄存器赋值1;否则没有加法进位,a5寄存器赋值0。也就是说a5寄存器存储的是低32位加法的进位标志。从这可以看出SLTU指令的作用了吧。
- c: 00d585b3 add a1,a1,a3:a的高32位加上b的高32位。
- 10: 00b785b3 add a1,a5,a1:低32位的进位标志存储在a5寄存器了,再加上进位标志。
RISC-V 没有进位标志位,它通过和是否小于加数来判断是否产生进位,然后再把进位累加进最终的和当中。利用了和大于任意一个加数这条数学规律。
和 Cortex-M 对比
相比之下,Cortex-M生成的指令要少得多,因为Cortex-M有进位标志,还有带进位的加法指令。 - 00000000 <add64u>:
- 0: 1880 adds r0, r0, r2
- 2: eb41 0103 adc.w r1, r1, r3
- 6: 4770 bx lr
复制代码
那么,这能证明 Cortex-M 更优秀吗?一般使用32位处理器的应用不会有大量的64位运算,如果有大量64位运算的话,那应该改用64位处理器。RISC-V的设计哲学是让硬件尽可能的简单,剔除进位标志和带进位加法指令同样也是基于同样的设计哲学,硬件设计得简单,那么在同样的工艺下,可以达到更高的主频,同样的主频下消耗更少的能量。所以,别看 Cortex-M 在64位运算上占了便宜,综合起来,谁输谁赢真不一定。
其它64位运算
还有64位的有符号数加法,以及64位的减法,源代码如下: - int64_t add64s(int64_t a, int64_t b)
- {
- return a + b;
- }
- uint64_t sub64u(uint64_t a, uint64_t b)
- {
- return a - b;
- }
- int64_t sub64s(int64_t a, int64_t b)
- {
- return a - b;
- }
复制代码
反汇编如下: - 00000018 <add64s>:
- 18: 00050793 addi a5,a0,0
- 1c: 00c50533 add a0,a0,a2
- 20: 00f537b3 sltu a5,a0,a5
- 24: 00d585b3 add a1,a1,a3
- 28: 00b785b3 add a1,a5,a1
- 2c: 00008067 jalr zero,0(ra)
- 00000030 <sub64u>:
- 30: 00050793 addi a5,a0,0
- 34: 40c50533 sub a0,a0,a2
- 38: 00a7b7b3 sltu a5,a5,a0
- 3c: 40d585b3 sub a1,a1,a3
- 40: 40f585b3 sub a1,a1,a5
- 44: 00008067 jalr zero,0(ra)
- 00000048 <sub64s>:
- 48: 00050793 addi a5,a0,0
- 4c: 40c50533 sub a0,a0,a2
- 50: 00a7b7b3 sltu a5,a5,a0
- 54: 40d585b3 sub a1,a1,a3
- 58: 40f585b3 sub a1,a1,a5
- 5c: 00008067 jalr zero,0(ra)
复制代码
完
|