bug in longlong.h for aarch64 sub_ddmmss
Vincent Lefevre
vincent at vinc17.net
Tue Jun 16 11:28:50 UTC 2020
On 2020-06-16 12:55:07 +0200, Vincent Lefevre wrote:
> In longlong.h from GMP 6.2.0:
>
> #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
> do { \
> if (__builtin_constant_p (bl) && -(UDItype)(bl) < 0x1000) \
> __asm__ ("adds\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \
> : "=r,r" (sh), "=&r,&r" (sl) \
> : "rZ,rZ" ((UDItype)(ah)), "rZ,rZ" ((UDItype)(bh)), \
> "r,Z" ((UDItype)(al)), "rI,r" (-(UDItype)(bl)) __CLOBBER_CC);\
> else \
> __asm__ ("subs\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \
> : "=r,r" (sh), "=&r,&r" (sl) \
> : "rZ,rZ" ((UDItype)(ah)), "rZ,rZ" ((UDItype)(bh)), \
> "r,Z" ((UDItype)(al)), "rI,r" ((UDItype)(bl)) __CLOBBER_CC);\
> } while(0);
>
> I don't understand this code. For instance, on ah=al=bh=bl=0, you
> do adds(0,0), which unsets the carry. And since borrow = not(carry),
> the sbc(0,0) will return -1.
Here's a test without using MPFR:
#define W_TYPE_SIZE 64
#define __GMP_DECLSPEC
#define __GMP_GNUC_PREREQ(maj, min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
#include <stdio.h>
#include "longlong.h"
int main (void)
{
unsigned long sh, sl;
sub_ddmmss (sh, sl, 0, 0, 0, 0);
printf ("%lx\n", sh);
return 0;
}
--
Vincent Lefèvre <vincent at vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
More information about the gmp-bugs
mailing list