[PATCH v2 06/28] Add add_ssaaaa and sub_ssaaaa to gmp-arch.h
Adhemerval Zanella
adhemerval.zanella@linaro.org
Tue Oct 28 17:08:15 GMT 2025
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 | 4 +-
sysdeps/generic/gmp-arch.h | 35 ++++++++++++-
sysdeps/loongarch/sfp-machine.h | 6 +--
.../powerpc/powerpc64/le/fpu/sfp-machine.h | 6 +--
sysdeps/riscv/sfp-machine.h | 6 +--
sysdeps/x86/fpu/sfp-machine.h | 18 ++++---
sysdeps/x86/gmp-arch.h | 52 +++++++++++++++++++
7 files changed, 109 insertions(+), 18 deletions(-)
diff --git a/sysdeps/aarch64/sfp-machine.h b/sysdeps/aarch64/sfp-machine.h
index b41a9462df..3468e47db3 100644
--- a/sysdeps/aarch64/sfp-machine.h
+++ b/sysdeps/aarch64/sfp-machine.h
@@ -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)
diff --git a/sysdeps/generic/gmp-arch.h b/sysdeps/generic/gmp-arch.h
index 623b0ae968..3ec144562a 100644
--- a/sysdeps/generic/gmp-arch.h
+++ b/sysdeps/generic/gmp-arch.h
@@ -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
diff --git a/sysdeps/loongarch/sfp-machine.h b/sysdeps/loongarch/sfp-machine.h
index 497b550f5c..113d96651b 100644
--- a/sysdeps/loongarch/sfp-machine.h
+++ b/sysdeps/loongarch/sfp-machine.h
@@ -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) \
diff --git a/sysdeps/powerpc/powerpc64/le/fpu/sfp-machine.h b/sysdeps/powerpc/powerpc64/le/fpu/sfp-machine.h
index b4b27f95f4..30b7fcf6ed 100644
--- a/sysdeps/powerpc/powerpc64/le/fpu/sfp-machine.h
+++ b/sysdeps/powerpc/powerpc64/le/fpu/sfp-machine.h
@@ -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)));
diff --git a/sysdeps/riscv/sfp-machine.h b/sysdeps/riscv/sfp-machine.h
index 43b2ba10ab..a38edd1e3c 100644
--- a/sysdeps/riscv/sfp-machine.h
+++ b/sysdeps/riscv/sfp-machine.h
@@ -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)
diff --git a/sysdeps/x86/fpu/sfp-machine.h b/sysdeps/x86/fpu/sfp-machine.h
index 5892f4f5fe..cbcedb8621 100644
--- a/sysdeps/x86/fpu/sfp-machine.h
+++ b/sysdeps/x86/fpu/sfp-machine.h
@@ -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" \
diff --git a/sysdeps/x86/gmp-arch.h b/sysdeps/x86/gmp-arch.h
index 5c8b8830af..45f047e1b6 100644
--- a/sysdeps/x86/gmp-arch.h
+++ b/sysdeps/x86/gmp-arch.h
@@ -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
--
2.43.0
More information about the Libc-alpha
mailing list