Fiddling with x86_64 and i486 builds
[tpg/acess2.git] / Usermode / Libraries / libgcc.so_src / libgcc.c
index 6e7fb08..8f6021f 100644 (file)
@@ -46,35 +46,43 @@ uint64_t __udivdi3(uint64_t Num, uint64_t Den)
        }
        return ret;
        #else
-       uint64_t        P[64], q, n;
+       uint64_t        P[2];
+       uint64_t        q;
         int    i;
        
        if(Den == 0)    __asm__ __volatile__ ("int $0x0");
        // Common speedups
+       if(Num <= 0xFFFFFFFF && Den <= 0xFFFFFFFF)
+               return (uint32_t)Num / (uint32_t)Den;
        if(Den == 1)    return Num;
        if(Den == 2)    return Num >> 1;
        if(Den == 16)   return Num >> 4;
+       if(Num < Den)   return 0;
+       if(Num < Den*2) return 1;
+       if(Num == Den*2)        return 2;
        
-       
-       // Non-restoring division, from wikipedia
+       // Restoring division, from wikipedia
        // http://en.wikipedia.org/wiki/Division_(digital)
-       P[0] = Num;
-       for( i = 0; i < 64; i ++ )
+       P[0] = Num;     P[1] = 0;
+       for( i = 64; i--; )
        {
-               if( P[i] >= 0 ) {
+               // P <<= 1;
+               P[1] = (P[1] << 1) | (P[0] >> 63);
+               P[0] = P[0] << 1;
+               
+               // P -= Den << 64
+               P[1] -= Den;
+               
+               // P >= 0
+               if( !(P[1] & (1ULL<<63)) ) {
                        q |= (uint64_t)1 << (63-i);
-                       P[i+1] = 2*P[i] - Den;
                }
                else {
                        //q |= 0 << (63-i);
-                       P[i+1] = 2*P[i] + Den;
+                       P[1] += Den;
                }
        }
        
-       n = ~q;
-       n = -n;
-       q += n;
-       
        return q;
        #endif
 }
@@ -103,9 +111,17 @@ uint64_t __umoddi3(uint64_t Num, uint64_t Den)
        return Num;
        #else
        if(Den == 0)    __asm__ __volatile__ ("int $0");        // Call Div by Zero Error
+       
+       // Speedups
+       if(Num < Den)   return Num;
+       if(Num == Den)  return 0;
+       if(Num <= 0xFFFFFFFF && Den <= 0xFFFFFFFF)
+               return (uint32_t)Num % (uint32_t)Den;
+       
        // Speedups for common operations
        if(Den == 1)    return 0;
        if(Den == 2)    return Num & 0x01;
+       if(Den == 8)    return Num & 0x07;
        if(Den == 16)   return Num & 0x0F;
        return Num - __udivdi3(Num, Den) * Den;
        #endif

UCC git Repository :: git.ucc.asn.au