summaryrefslogtreecommitdiff
path: root/longlong.h
diff options
context:
space:
mode:
authorTorbjorn Granlund <tg@gmplib.org>2017-02-25 00:00:30 +0100
committerTorbjorn Granlund <tg@gmplib.org>2017-02-25 00:00:30 +0100
commit2a8fe27b24a489813952ef31c23fc7ddf625519f (patch)
treed503498fa631838fb421f1c760c3924d375943b1 /longlong.h
parent5d026cd9e838ecb4826d4506cad5987466571aff (diff)
downloadgmp-2a8fe27b24a489813952ef31c23fc7ddf625519f.tar.gz
(arm32/arm64 add_sssaaaa): Use "subs" for some immediates.
(arm32/arm64 sub_sssaaaa): Use "adds" for some immediates.
Diffstat (limited to 'longlong.h')
-rw-r--r--longlong.h48
1 files changed, 37 insertions, 11 deletions
diff --git a/longlong.h b/longlong.h
index c810fce2d..03f4fe42f 100644
--- a/longlong.h
+++ b/longlong.h
@@ -1,6 +1,6 @@
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
-Copyright 1991-1994, 1996, 1997, 1999-2005, 2007-2009, 2011-2016 Free Software
+Copyright 1991-1994, 1996, 1997, 1999-2005, 2007-2009, 2011-2017 Free Software
Foundation, Inc.
This file is part of the GNU MP Library.
@@ -440,9 +440,19 @@ long __MPN(count_leading_zeros) (UDItype);
#if defined (__arm__) && (defined (__thumb2__) || !defined (__thumb__)) \
&& W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("adds\t%1, %4, %5\n\tadc\t%0, %2, %3" \
+ do { \
+ if (__builtin_constant_p (bl) && (bl) < 0 && (-(USItype) (bl) < 0x1000)) \
+ __asm__ ("subs\t%1, %4, %5\n\tadc\t%0, %2, %3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), \
+ "%r" (al), "rI" (-(USItype)(bl)) __CLOBBER_CC); \
+ else \
+ __asm__ ("adds\t%1, %4, %5\n\tadc\t%0, %2, %3" \
: "=r" (sh), "=&r" (sl) \
- : "r" (ah), "rI" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC)
+ : "r" (ah), "rI" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC); \
+ } while (0)
+/* FIXME: Extend the immediate range for the low word by using both
+ ADDS and SUBS, since they set carry in the same way. */
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
do { \
if (__builtin_constant_p (al)) \
@@ -541,15 +551,31 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
/* FIXME: Extend the immediate range for the low word by using both
ADDS and SUBS, since they set carry in the same way. */
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("adds\t%1, %x4, %5\n\tadc\t%0, %x2, %x3" \
- : "=r" (sh), "=&r" (sl) \
- : "rZ" ((UDItype)(ah)), "rZ" ((UDItype)(bh)), \
- "%r" ((UDItype)(al)), "rI" ((UDItype)(bl)) __CLOBBER_CC)
+ do { \
+ if (__builtin_constant_p (bl) && (bl) < 0 && (-(UDItype) (bl) < 0x1000)) \
+ __asm__ ("subs\t%1, %x4, %5\n\tadc\t%0, %x2, %x3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rZ" ((UDItype)(ah)), "rZ" ((UDItype)(bh)), \
+ "%r" ((UDItype)(al)), "rI" (-(UDItype)(bl)) __CLOBBER_CC);\
+ else \
+ __asm__ ("adds\t%1, %x4, %5\n\tadc\t%0, %x2, %x3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rZ" ((UDItype)(ah)), "rZ" ((UDItype)(bh)), \
+ "%r" ((UDItype)(al)), "rI" ((UDItype)(bl)) __CLOBBER_CC);\
+ } while (0)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __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)
+ do { \
+ if (__builtin_constant_p (bl) && (bl) < 0 && (-(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);
#define umul_ppmm(ph, pl, m0, m1) \
do { \
UDItype __m0 = (m0), __m1 = (m1); \