From 183624479fd426c67928bb931a6474b15a8e8e95 Mon Sep 17 00:00:00 2001
From: Uros Bizjak <uros@gcc.gnu.org>
Date: Wed, 2 Nov 2016 23:23:13 +0100
Subject: [PATCH] Makefile.in (LIB2_DIVMOD_FUNCS): Add _divmoddi4.

	* Makefile.in (LIB2_DIVMOD_FUNCS): Add _divmoddi4.
	* libgcc2.c (__divmoddi4): New function.
	* libgcc2.h (__divmoddi4): Declare.
	* libgcc-std.ver.in (GCC_7.0.0): New. Add __PFX_divmoddi4
	and __PFX_divmodti4.

From-SVN: r241804
---
 libgcc/ChangeLog         | 12 ++++++++++--
 libgcc/Makefile.in       |  7 ++-----
 libgcc/libgcc-std.ver.in |  6 ++++++
 libgcc/libgcc2.c         | 37 ++++++++++++++++++++++++++++++++++---
 libgcc/libgcc2.h         |  5 ++++-
 5 files changed, 56 insertions(+), 11 deletions(-)

diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 116c87b92c62..e2e5327b37cc 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,11 @@
+2016-11-02  Uros Bizjak  <ubizjak@gmail.com>
+
+	* Makefile.in (LIB2_DIVMOD_FUNCS): Add _divmoddi4.
+	* libgcc2.c (__divmoddi4): New function.
+	* libgcc2.h (__divmoddi4): Declare.
+	* libgcc-std.ver.in (GCC_7.0.0): New. Add __PFX_divmoddi4
+	and __PFX_divmodti4.
+
 2016-10-24  Florian Weimer  <fweimer@redhat.com>
 
 	PR libgcc/78064
@@ -5,7 +13,7 @@
 
 2016-10-19  John David Anglin  <danglin@gcc.gnu.org>
 
-	* config/pa/pa64-hpux-lib.h: New file.  
+	* config/pa/pa64-hpux-lib.h: New file.
 	(EH_FRAME_SECTION_NAME): Rename to __LIBGCC_EH_FRAME_SECTION_NAME__.
 	(DTORS_SECTION_ASM_OP): Rename to __LIBGCC_DTORS_SECTION_ASM_OP__.
 	* config.host (tm_file): Add pa/pa64-hpux-lib.h to tm_file on
@@ -358,7 +366,7 @@
 
 2016-06-23  Jakub Sejdak  <jakub.sejdak@phoesys.com>
 
-   * config.host: Add suport for arm*-*-phoenix* targets.
+	* config.host: Add suport for arm*-*-phoenix* targets.
 
 2016-06-21  Trevor Saunders  <tbsaunde+gcc@tbsaunde.org>
 
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 873cad04b787..ae69611f2bf2 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -255,10 +255,6 @@ LIB2FUNCS_ST = _eprintf __gcc_bcmp
 # List of functions not to build from libgcc2.c.
 LIB2FUNCS_EXCLUDE =
 
-# These might cause a divide overflow trap and so are compiled with
-# unwinder info.
-LIB2_DIVMOD_FUNCS = _divdi3 _moddi3 _udivdi3 _umoddi3 _udiv_w_sdiv _udivmoddi4
-
 # List of extra C and assembler files to add to static and shared libgcc2.
 # Assembler files should have names ending in `.S'.
 LIB2ADD = 
@@ -455,7 +451,8 @@ endif
 
 # These might cause a divide overflow trap and so are compiled with
 # unwinder info.
-LIB2_DIVMOD_FUNCS = _divdi3 _moddi3 _udivdi3 _umoddi3 _udiv_w_sdiv _udivmoddi4
+LIB2_DIVMOD_FUNCS = _divdi3 _moddi3 _divmoddi4 \
+		    _udivdi3 _umoddi3 _udivmoddi4 _udiv_w_sdiv
 
 # Remove any objects from lib2funcs and LIB2_DIVMOD_FUNCS that are
 # defined as optimized assembly code in LIB1ASMFUNCS or as C code
diff --git a/libgcc/libgcc-std.ver.in b/libgcc/libgcc-std.ver.in
index c8ca62fbe052..a35d4b3013ad 100644
--- a/libgcc/libgcc-std.ver.in
+++ b/libgcc/libgcc-std.ver.in
@@ -1938,3 +1938,9 @@ GCC_4.7.0 {
 %inherit GCC_4.8.0 GCC_4.7.0
 GCC_4.8.0 {
 }
+
+%inherit GCC_7.0.0 GCC_4.8.0
+GCC_7.0.0 {
+  __PFX__divmoddi4
+  __PFX__divmodti4
+}
diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c
index 9fb150b2dd5f..1d71fc48567d 100644
--- a/libgcc/libgcc2.c
+++ b/libgcc/libgcc2.c
@@ -680,7 +680,8 @@ __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
 #endif
 
 #if (defined (L_udivdi3) || defined (L_divdi3) || \
-     defined (L_umoddi3) || defined (L_moddi3))
+     defined (L_umoddi3) || defined (L_moddi3) || \
+     defined (L_divmoddi4))
 #define L_udivmoddi4
 #endif
 
@@ -937,7 +938,8 @@ __parityDI2 (UDWtype x)
 #ifdef TARGET_HAS_NO_HW_DIVIDE
 
 #if (defined (L_udivdi3) || defined (L_divdi3) || \
-     defined (L_umoddi3) || defined (L_moddi3))
+     defined (L_umoddi3) || defined (L_moddi3) || \
+     defined (L_divmoddi4))
 static inline __attribute__ ((__always_inline__))
 #endif
 UDWtype
@@ -1004,7 +1006,8 @@ __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
 #else
 
 #if (defined (L_udivdi3) || defined (L_divdi3) || \
-     defined (L_umoddi3) || defined (L_moddi3))
+     defined (L_umoddi3) || defined (L_moddi3) || \
+     defined (L_divmoddi4))
 static inline __attribute__ ((__always_inline__))
 #endif
 UDWtype
@@ -1269,6 +1272,34 @@ __moddi3 (DWtype u, DWtype v)
 }
 #endif
 
+#ifdef L_divmoddi4
+DWtype
+__divmoddi4 (DWtype u, DWtype v, DWtype *rp)
+{
+  Wtype c1 = 0, c2 = 0;
+  DWunion uu = {.ll = u};
+  DWunion vv = {.ll = v};
+  DWtype w;
+  DWtype r;
+
+  if (uu.s.high < 0)
+    c1 = ~c1, c2 = ~c2,
+    uu.ll = -uu.ll;
+  if (vv.s.high < 0)
+    c1 = ~c1,
+    vv.ll = -vv.ll;
+
+  w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&r);
+  if (c1)
+    w = -w;
+  if (c2)
+    r = -r;
+
+  *rp = r;
+  return w;
+}
+#endif
+
 #ifdef L_umoddi3
 UDWtype
 __umoddi3 (UDWtype u, UDWtype v)
diff --git a/libgcc/libgcc2.h b/libgcc/libgcc2.h
index c46fb77a6ec2..15f970515f87 100644
--- a/libgcc/libgcc2.h
+++ b/libgcc/libgcc2.h
@@ -281,6 +281,7 @@ typedef int shift_count_type __attribute__((mode (__libgcc_shift_count__)));
 #define __ashrdi3	__NDW(ashr,3)
 #define __cmpdi2	__NDW(cmp,2)
 #define __ucmpdi2	__NDW(ucmp,2)
+#define __divmoddi4	__NDW(divmod,4)
 #define __udivmoddi4	__NDW(udivmod,4)
 #define __fixunstfDI	__NDW(fixunstf,)
 #define __fixtfdi	__NDW(fixtf,)
@@ -376,10 +377,12 @@ extern DWtype __divdi3 (DWtype, DWtype);
 extern UDWtype __udivdi3 (UDWtype, UDWtype);
 extern UDWtype __umoddi3 (UDWtype, UDWtype);
 extern DWtype __moddi3 (DWtype, DWtype);
+extern DWtype __divmoddi4 (DWtype, DWtype, DWtype *);
 
 /* __udivmoddi4 is static inline when building other libgcc2 portions.  */
 #if (!defined (L_udivdi3) && !defined (L_divdi3) && \
-     !defined (L_umoddi3) && !defined (L_moddi3))
+     !defined (L_umoddi3) && !defined (L_moddi3) && \
+     !defined (L_divmoddi4))
 extern UDWtype __udivmoddi4 (UDWtype, UDWtype, UDWtype *);
 #endif
 
-- 
GitLab