]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Add add_ssaaaa and sub_ssaaaa to gmp-arch.h
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 24 Oct 2025 14:37:36 +0000 (11:37 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 27 Oct 2025 19:00:37 +0000 (16:00 -0300)
To enable “longlong.h” removal, add_ssaaaa and sub_ssaaaa are moved to
gmp-arch.h.  The generic implementation now uses a static inline.  This
provides better type checking than the GNU extension, which casts the
asm constraint. It also works better with clang.

Most architectures use the generic implementation.  This is expanded
from a macro.  Exceptions are arc, arm, hppa, x86, m68k, powerpc, and
sparc.  I kept only the x86 optimization, as there is no easy way to
emit add{q}. For all others, the compiler generates good enough code.

The strongly typed implementation required some changes.  I adjusted
_FP_W_TYPE, _FP_WS_TYPE, and _FP_I_TYPE to use the same type as
mp_limb_t on aarch64, powerpc64le, x86_64, and riscv64.  This basically
means using “long” instead of “long long.”

sysdeps/aarch64/sfp-machine.h
sysdeps/generic/gmp-arch.h
sysdeps/loongarch/sfp-machine.h
sysdeps/powerpc/powerpc64/le/fpu/sfp-machine.h
sysdeps/riscv/sfp-machine.h
sysdeps/x86/fpu/sfp-machine.h
sysdeps/x86/gmp-arch.h

index b41a9462dfae742fef584fa6a0c925b175742f21..3468e47db30b7245927f4333a5bc2d961a42495f 100644 (file)
@@ -2,9 +2,9 @@
 #include <fpu_control.h>
 
 #define _FP_W_TYPE_SIZE                64
-#define _FP_W_TYPE             unsigned long long
+#define _FP_W_TYPE             unsigned long
 #define _FP_WS_TYPE            signed long long
-#define _FP_I_TYPE             long long
+#define _FP_I_TYPE             long
 
 #define _FP_MUL_MEAT_S(R,X,Y)                                  \
   _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
index 623b0ae968c7f37136874ce13fda6d102ab3be4c..3ec144562a70884d917156a2c664e601f6a7b062 100644 (file)
@@ -110,4 +110,37 @@ udiv_qrnnd_generic (mp_limb_t *q, mp_limb_t *r, mp_limb_t n1, mp_limb_t n0,
   udiv_qrnnd_generic (&__q, &__r, __n1, __n0, __d)
 
 
-#endif /* __GMP_ARHC_H */
+/* add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+   high_addend_2, low_addend_2) adds two UWtype integers, composed by
+   HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
+   respectively.  The result is placed in HIGH_SUM and LOW_SUM.  Overflow
+   (i.e. carry out) is not stored anywhere, and is lost.  */
+static __always_inline void
+add_ssaaaa_generic (mp_limb_t *sh, mp_limb_t *sl, mp_limb_t ah,
+                   mp_limb_t al,  mp_limb_t bh,  mp_limb_t bl)
+{
+  *sl = al + bl;
+  *sh = (ah + bh) + (*sl < al);
+}
+#undef add_ssaaaa
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  add_ssaaaa_generic (&sh, &sl, ah, al, bh, bl)
+
+/* sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
+   high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
+   composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
+   LOW_SUBTRAHEND_2 respectively.  The result is placed in HIGH_DIFFERENCE
+   and LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
+   and is lost.  */
+static __always_inline void
+sub_ddmmss_generic (mp_limb_t *sh, mp_limb_t *sl, mp_limb_t ah,
+                   mp_limb_t al,  mp_limb_t bh,  mp_limb_t bl)
+{
+  *sl = al - bl;
+  *sh = (ah - bh) - (*sl > al);
+}
+#undef sub_ddmmss
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  sub_ddmmss_generic (&sh, &sl, ah, al, bh, bl)
+
+#endif
index 497b550f5ca1108ea8e882de0a628ec14c7978f7..113d96651b679a78ba2b94e58ebeba300db1d3be 100644 (file)
@@ -21,9 +21,9 @@
 #include <fpu_control.h>
 
 #define _FP_W_TYPE_SIZE 64
-#define _FP_W_TYPE unsigned long long
-#define _FP_WS_TYPE signed long long
-#define _FP_I_TYPE long long
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
 
 #define _FP_MUL_MEAT_S(R, X, Y) _FP_MUL_MEAT_1_imm (_FP_WFRACBITS_S, R, X, Y)
 #define _FP_MUL_MEAT_D(R, X, Y) \
index b4b27f95f4c8a39d9164c5f7dbb614457ed34a53..30b7fcf6edb9e618d7f807631f7e2ac6c8e99d65 100644 (file)
@@ -1,7 +1,7 @@
 #define _FP_W_TYPE_SIZE                64
-#define _FP_W_TYPE             unsigned long long
-#define _FP_WS_TYPE            signed long long
-#define _FP_I_TYPE             long long
+#define _FP_W_TYPE             unsigned long
+#define _FP_WS_TYPE            signed long
+#define _FP_I_TYPE             long
 
 typedef int TItype __attribute__ ((mode (TI)));
 typedef unsigned int UTItype __attribute__ ((mode (TI)));
index 43b2ba10ab0da9b1d6a4a936ef150047d984fb79..a38edd1e3c7d223bafade3991449a16d63a7f73b 100644 (file)
@@ -52,9 +52,9 @@
 #else
 
 # define _FP_W_TYPE_SIZE               64
-# define _FP_W_TYPE            unsigned long long
-# define _FP_WS_TYPE           signed long long
-# define _FP_I_TYPE            long long
+# define _FP_W_TYPE            unsigned long
+# define _FP_WS_TYPE           signed long
+# define _FP_I_TYPE            long
 
 # define _FP_MUL_MEAT_S(R, X, Y)                                       \
   _FP_MUL_MEAT_1_imm (_FP_WFRACBITS_S, R, X, Y)
index 5892f4f5fe58d1a01b45232c1bc234db45af7ba4..cbcedb8621e7f023e335f5b57eac4c527c2102a6 100644 (file)
@@ -8,9 +8,15 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
 
 #ifdef __x86_64__
 # define _FP_W_TYPE_SIZE       64
-# define _FP_W_TYPE            unsigned long long
-# define _FP_WS_TYPE           signed long long
-# define _FP_I_TYPE            long long
+# ifndef __ILP32__
+#  define _FP_W_TYPE           unsigned long
+#  define _FP_WS_TYPE          signed long
+#  define _FP_I_TYPE           long
+# else
+#  define _FP_W_TYPE           unsigned long long
+#  define _FP_WS_TYPE          signed long long
+#  define _FP_I_TYPE           long long
+# endif
 
 typedef int TItype __attribute__ ((mode (TI)));
 typedef unsigned int UTItype __attribute__ ((mode (TI)));
@@ -45,9 +51,9 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
   } while (0)
 #else
 # define _FP_W_TYPE_SIZE       32
-# define _FP_W_TYPE            unsigned int
-# define _FP_WS_TYPE           signed int
-# define _FP_I_TYPE            int
+# define _FP_W_TYPE            unsigned long int
+# define _FP_WS_TYPE           signed long int
+# define _FP_I_TYPE            long int
 
 # define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)  \
   __asm__ ("add{l} {%11,%3|%3,%11}\n\t"                                \
index 5c8b8830afa07d6f8bae8a99d10e5532820481a7..45f047e1b643f563805471a8f2d85ff7b5dc0e0f 100644 (file)
@@ -47,4 +47,56 @@ udiv_qrnnd_x86 (mp_limb_t *q, mp_limb_t *r, mp_limb_t n1, mp_limb_t n0,
 #define udiv_qrnnd(__q, __r, __n1, __n0, __d) \
   udiv_qrnnd_x86 (&__q, &__r, __n1, __n0, __d)
 
+static __always_inline void
+add_ssaaaa_x86 (mp_limb_t *sh, mp_limb_t *sl, mp_limb_t ah,
+               mp_limb_t al, mp_limb_t bh, mp_limb_t bl)
+{
+#ifdef __x86_64__
+  asm ("add{q} {%5,%1|%1,%5}\n\tadc{q} {%3,%0|%0,%3}"
+       : "=r" (*sh),
+         "=&r" (*sl)
+       : "%0" (ah),
+         "rme" (bh),
+        "%1" (al),
+        "rme" (bl));
+#else
+  asm ("add{l} {%5,%1|%1,%5}\n\tadc{l} {%3,%0|%0,%3}"
+       : "=r" (*sh),
+         "=&r" (*sl)
+       : "%0" (ah),
+          "g" (bh),
+         "%1" (al),
+         "g" (bl));
+#endif
+}
+#undef add_ssaaaa
+#define add_ssaaaa(__sh, __sl, __ah, __al, __bh, __bl) \
+  add_ssaaaa_x86 (&__sh, &__sl, __ah, __al, __bh, __bl)
+
+static __always_inline void
+sub_ddmmss_x86 (mp_limb_t *sh, mp_limb_t *sl, mp_limb_t ah,
+               mp_limb_t al, mp_limb_t bh, mp_limb_t bl)
+{
+#ifdef __x86_64__
+  asm ("sub{q} {%5,%1|%1,%5}\n\tsbb{q} {%3,%0|%0,%3}"
+       : "=r" (*sh),
+         "=&r" (*sl)
+       : "0" (ah),
+         "rme" (bh),
+        "1" (al),
+        "rme" (bl));
+#else
+  asm ("sub{l} {%5,%1|%1,%5}\n\tsbb{l} {%3,%0|%0,%3}"
+       : "=r" (*sh),
+         "=&r" (*sl)
+       : "0" (ah),
+         "g" (bh),
+        "1" (al),
+        "g" (bl));
+#endif
+}
+#undef sub_ddmmss
+#define sub_ddmmss(__sh, __sl, __ah, __al, __bh, __bl) \
+  sub_ddmmss_x86 (&__sh, &__sl, __ah, __al, __bh, __bl)
+
 #endif