I need to deal with bignum calculation (addition and subtraction, but I treat subtraction as equivalent to signed addition) on RISC-V and the situation is a bit complicated. What I gather from half an hour of internet research:
- RISC-V operations do not provide means to check for carries or overflow
- This decision is motivated in the fact that flags or other means of handling it add a lot of complexity to Out-of-order micro architectures.
- Instead, they recommend doing branches afterwards
- For unsigned addition, overflow handling can be done with a single
bltu
. - Same for signed addition if the sign of one of the operands is known
- Otherwise, two checks need to be performed (three additional instructions)
- For unsigned addition, overflow handling can be done with a single
- People On The Internet are raging furious about this (I won't link it here)
As far as I can tell, the branches indeed cover most scenarios rather well, except for one: (signed) bignum addition. Because there, we hit the slowest check path in a hot loop.
I know only a little about ISA design, but why didn't they include an instruction that calculates (a + b) >> 32
(effectively the carry out)? A bit like how the multiplication instruction is split into mul
and mulh
as well. This would allow to do the desired calculation with always two instructions. More powerful micro architectures could then even detect the sequence and only do one addition.
Am I missing some tricks that would make this instruction obsolete (or be equivalent to it)? Does it have any major downsides that I oversee? I did not find a lot of good documentation on this general topic.