diff mbox

[1/2,libgcc] : Implement _divmoddi4

Message ID CAFULd4bt-w7ArKECLk-ut_Vk6xUGVC-AEf8T+ap6P5c+re-7eg@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Oct. 31, 2016, 2:46 p.m. UTC
This function will be used in a follow-up patch to implement
TARGET_EXPAND_DIVMOD_LIBFUNC for x86 targets. Other targets can call
this function, so IMO it should be part of a generic library.

2016-10-31  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.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32} with a
follow-up target-dependent  patch.

OK for mainline?

Uros.

Comments

Ian Lance Taylor Nov. 2, 2016, 1:27 p.m. UTC | #1
On Mon, Oct 31, 2016 at 7:46 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> This function will be used in a follow-up patch to implement
> TARGET_EXPAND_DIVMOD_LIBFUNC for x86 targets. Other targets can call
> this function, so IMO it should be part of a generic library.
>
> 2016-10-31  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.

You aren't defining divmodti4 anywhere, so it seems premature to add
it to libgcc-std.ver.in.

Other than that the patch is OK.

Thanks.

Ian
Uros Bizjak Nov. 2, 2016, 7:19 p.m. UTC | #2
On Wed, Nov 2, 2016 at 2:27 PM, Ian Lance Taylor <iant@google.com> wrote:
> On Mon, Oct 31, 2016 at 7:46 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> This function will be used in a follow-up patch to implement
>> TARGET_EXPAND_DIVMOD_LIBFUNC for x86 targets. Other targets can call
>> this function, so IMO it should be part of a generic library.
>>
>> 2016-10-31  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.
>
> You aren't defining divmodti4 anywhere, so it seems premature to add
> it to libgcc-std.ver.in.

It is created magically for x86_64, in the same way e.g. divti3 is created.

objdump of x86_64 libgcc.a:

--cut here--

...

_divmoddi4.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <__divmodti4>:
   0:    41 57                    push   %r15
   2:    41 56                    push   %r14
   4:    49 89 f9                 mov    %rdi,%r9
   ...

--cut here--

Uros.
Ian Lance Taylor Nov. 2, 2016, 10:05 p.m. UTC | #3
On Wed, Nov 2, 2016 at 12:19 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Wed, Nov 2, 2016 at 2:27 PM, Ian Lance Taylor <iant@google.com> wrote:
>> On Mon, Oct 31, 2016 at 7:46 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>>> This function will be used in a follow-up patch to implement
>>> TARGET_EXPAND_DIVMOD_LIBFUNC for x86 targets. Other targets can call
>>> this function, so IMO it should be part of a generic library.
>>>
>>> 2016-10-31  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.
>>
>> You aren't defining divmodti4 anywhere, so it seems premature to add
>> it to libgcc-std.ver.in.
>
> It is created magically for x86_64, in the same way e.g. divti3 is created.

Ah, OK.

Ian
diff mbox

Patch

Index: Makefile.in
===================================================================
--- Makefile.in	(revision 241697)
+++ Makefile.in	(working copy)
@@ -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
Index: libgcc-std.ver.in
===================================================================
--- libgcc-std.ver.in	(revision 241697)
+++ libgcc-std.ver.in	(working copy)
@@ -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
+}
Index: libgcc2.c
===================================================================
--- libgcc2.c	(revision 241697)
+++ libgcc2.c	(working copy)
@@ -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)
Index: libgcc2.h
===================================================================
--- libgcc2.h	(revision 241697)
+++ libgcc2.h	(working copy)
@@ -281,6 +281,7 @@  typedef int shift_count_type __attribute__((mode (
 #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