I have 2 different implementations of a 64bit add in HLSL. If I want to set A += B, where al, ah, bl, and bh are the low and high 32 bits of A and B respectively, then I do either
(1):
#define pluseq64(al, ah, bl, bh) do {\
uint tadd0 = al >> 1;\
uint tadd1 = bl >> 1;\
tadd0 += al & bl & 0x00000001;\
tadd0 += tadd1;\
tadd0 >>= 31;\
al += bl;\
ah += bh;\
ah += tadd0;
or (2):
#define pluseq64(al, ah, bl, bh) do {\
uint t = al;\
al += bl;\
ah += bh;\
if (al < t) { \
ah += 1; \
} } while(0)
Now, interestingly enough, (1) always produces the correct output, whereas (2) does not. Given that (1) is kind of a mess of operations (3 shifts, 5 adds to do a single 64bit +=), I'd much prefer something along the lines of (2) to (1), except that (2) doesn't work properly.
As an alternative to (2), I've tried:
#define pluseq64(al, ah, bl, bh) do {\
uint t = al;\
al += bl;\
ah += bh;\
ah += (al < t); } while(0)
Which doesn't quite work either (for likely the same reason, whatever that reason is, if I have my guess).
Why doesn't (2) work properly? Bonus: is there a better way to do a 64bit add in HLSL?
Thank you!