浏览代码

The default __GNUC__ C code cannot be used with MinGW as it inserts
implicit calls to _umoddi3 and _udivdi3, which are unavailable when
compiling without the standard libraries (-nostdlib).

This patch addresses this by providing an inline assembly definition
that is an exact conversion of the existing MS one, but for GCC's
AT&T syntax.

Signed-off-by: Pete Batard <pbatard@users.sf.net>
Signed-off-by: Nigel Croxon <nigel.croxon@hpe.com>

Nigel Croxon 9 年之前
父节点
当前提交
78e4df7c5e
共有 1 个文件被更改,包括 25 次插入7 次删除
  1. 25 7
      lib/ia32/math.c

+ 25 - 7
lib/ia32/math.c

@@ -140,13 +140,13 @@ DivU64x32 (
 // divide 64bit by 32bit and get a 64bit result
 // N.B. only works for 31bit divisors!!
 {
-#ifdef __GNUC__
+#if defined(__GNUC__) && !defined(__MINGW32__)
     if (Remainder)
-	*Remainder = Dividend % Divisor;
+        *Remainder = Dividend % Divisor;
     return Dividend / Divisor;
 #else
     UINT32      Rem;
-    UINT32      bit;        
+    UINT32      bit;
 
     ASSERT (Divisor != 0);
     ASSERT ((Divisor >> 31) == 0);
@@ -157,19 +157,37 @@ DivU64x32 (
 
     Rem = 0;
     for (bit=0; bit < 64; bit++) {
+#ifdef __MINGW32__
+        asm (
+            "shll	$1, %0\n\t"
+            "rcll	$1, 4%0\n\t"
+            "rcll	$1, %2\n\t"
+            "mov	%2, %%eax\n\t"
+            "cmp	%1, %%eax\n\t"
+            "cmc\n\t"
+            "sbb	%%eax, %%eax\n\t"
+            "sub	%%eax, %0\n\t"
+            "and	%1, %%eax\n\t"
+            "sub	%%eax, %2"
+            : /* no outputs */
+            : "m"(Dividend), "m"(Divisor), "m"(Rem)
+            : "cc","memory","%eax"
+            );
+#else
         _asm {
             shl     dword ptr Dividend[0], 1    ; shift rem:dividend left one
-            rcl     dword ptr Dividend[4], 1    
-            rcl     dword ptr Rem, 1            
+            rcl     dword ptr Dividend[4], 1
+            rcl     dword ptr Rem, 1
 
             mov     eax, Rem
             cmp     eax, Divisor                ; Is Rem >= Divisor?
             cmc                                 ; No - do nothing
-            sbb     eax, eax                    ; Else, 
+            sbb     eax, eax                    ; Else,
             sub     dword ptr Dividend[0], eax  ;   set low bit in dividen
             and     eax, Divisor                ; and
-            sub     Rem, eax                    ;   subtract divisor 
+            sub     Rem, eax                    ;   subtract divisor
         }
+#endif
     }
 
     if (Remainder) {