Bugfixes to usermode 64-bit division, more work on GUI (now sizes almost correctly)
[tpg/acess2.git] / Usermode / Libraries / libgcc.so_src / libgcc.c
index 3b0f212..6e7fb08 100644 (file)
@@ -25,14 +25,58 @@ void __stack_chk_fail()
  */
 uint64_t __udivdi3(uint64_t Num, uint64_t Den)
 {
+       #if 0
        uint64_t        ret = 0;
        if(Den == 0)    // Call Div by Zero Error
                __asm__ __volatile__ ("int $0");
+       
+       if(Den == 1)    return Num;
+       if(Den == 2)    return Num >> 1;
+       if(Den == 4)    return Num >> 2;
+       if(Den == 8)    return Num >> 3;
+       if(Den == 16)   return Num >> 4;
+       if(Den == 32)   return Num >> 5;
+       if(Den == 64)   return Num >> 6;
+       if(Den == 128)  return Num >> 7;
+       if(Den == 256)  return Num >> 8;
+       
        while(Num > Den) {
                ret ++;
                Num -= Den;
        }
        return ret;
+       #else
+       uint64_t        P[64], q, n;
+        int    i;
+       
+       if(Den == 0)    __asm__ __volatile__ ("int $0x0");
+       // Common speedups
+       if(Den == 1)    return Num;
+       if(Den == 2)    return Num >> 1;
+       if(Den == 16)   return Num >> 4;
+       
+       
+       // Non-restoring division, from wikipedia
+       // http://en.wikipedia.org/wiki/Division_(digital)
+       P[0] = Num;
+       for( i = 0; i < 64; i ++ )
+       {
+               if( P[i] >= 0 ) {
+                       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;
+               }
+       }
+       
+       n = ~q;
+       n = -n;
+       q += n;
+       
+       return q;
+       #endif
 }
 
 /**
@@ -41,9 +85,28 @@ uint64_t __udivdi3(uint64_t Num, uint64_t Den)
  */
 uint64_t __umoddi3(uint64_t Num, uint64_t Den)
 {
-       if(Den == 0)    // Call Div by Zero Error
-               __asm__ __volatile__ ("int $0");
-       while(Num >= Den)
-               Num -= Den;
+       #if 0
+       if(Den == 0)    __asm__ __volatile__ ("int $0");        // Call Div by Zero Error
+       
+       if(Den == 1)    return 0;
+       if(Den == 2)    return Num & 0x01;
+       if(Den == 4)    return Num & 0x03;
+       if(Den == 8)    return Num & 0x07;
+       if(Den == 16)   return Num & 0x0F;
+       if(Den == 32)   return Num & 0x1F;
+       if(Den == 64)   return Num & 0x3F;
+       if(Den == 128)  return Num & 0x3F;
+       if(Den == 256)  return Num & 0x7F;
+       
+       while(Num >= Den)       Num -= Den;
+       
        return Num;
+       #else
+       if(Den == 0)    __asm__ __volatile__ ("int $0");        // Call Div by Zero Error
+       // Speedups for common operations
+       if(Den == 1)    return 0;
+       if(Den == 2)    return Num & 0x01;
+       if(Den == 16)   return Num & 0x0F;
+       return Num - __udivdi3(Num, Den) * Den;
+       #endif
 }

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