RV32执行64位的加减法及SLT/SLTU的作用

RISC-V没有条件码,如何处理32位加法溢出?如何处理32位减法借位?以及如执行64位数的加减法?

mingdu.zheng at gmail dot com
https://blog.csdn.net/zoomdy/article/details/82949816

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)

按照函数调用规约,a0a1存储第一个64位入参aa2a3存储第二个64位入参b,返回值c存储在a0a1,低字节存储在编号较低的寄存器。

  • 0: 00050793 addi a5,a0,0: 首先保存一下a的低32位,后面还要用。
  • 4: 00c50533 add a0,a0,a2a的低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,a3a的高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)
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值