Usermode - Switched to the POSIX read()/write() argument order
[tpg/acess2.git] / Usermode / Libraries / libgcc.so_src / libgcc.c
1 /* Acess GCC Helper Library
2  *
3  */
4 #include <acess/sys.h>
5 #include <stdint.h>
6
7 // === CODE ===
8 int SoMain()
9 {
10         return 0;
11 }
12
13 // --- Errors ---
14 void __stack_chk_fail()
15 {
16         write(2, "FATAL ERROR: Stack Check Failed\n", 32);
17         _exit(-1);
18         for(;;);
19 }
20
21 // --- 64-Bit Math ---
22 /**
23  * \fn uint64_t __udivdi3(uint64_t Num, uint64_t Den)
24  * \brief Divide two 64-bit integers
25  */
26 uint64_t __udivdi3(uint64_t Num, uint64_t Den)
27 {
28         #if 0
29         uint64_t        ret = 0;
30         if(Den == 0)    // Call Div by Zero Error
31                 __asm__ __volatile__ ("int $0");
32         
33         if(Den == 1)    return Num;
34         if(Den == 2)    return Num >> 1;
35         if(Den == 4)    return Num >> 2;
36         if(Den == 8)    return Num >> 3;
37         if(Den == 16)   return Num >> 4;
38         if(Den == 32)   return Num >> 5;
39         if(Den == 64)   return Num >> 6;
40         if(Den == 128)  return Num >> 7;
41         if(Den == 256)  return Num >> 8;
42         
43         while(Num > Den) {
44                 ret ++;
45                 Num -= Den;
46         }
47         return ret;
48         #else
49         uint64_t        P[2];
50         uint64_t        q;
51          int    i;
52         
53         if(Den == 0)    __asm__ __volatile__ ("int $0x0");
54         // Common speedups
55         if(Num <= 0xFFFFFFFF && Den <= 0xFFFFFFFF)
56                 return (uint32_t)Num / (uint32_t)Den;
57         if(Den == 1)    return Num;
58         if(Den == 2)    return Num >> 1;
59         if(Den == 16)   return Num >> 4;
60         if(Num < Den)   return 0;
61         if(Num < Den*2) return 1;
62         if(Num == Den*2)        return 2;
63         
64         // Restoring division, from wikipedia
65         // http://en.wikipedia.org/wiki/Division_(digital)
66         P[0] = Num;     P[1] = 0;
67         for( i = 64; i--; )
68         {
69                 // P <<= 1;
70                 P[1] = (P[1] << 1) | (P[0] >> 63);
71                 P[0] = P[0] << 1;
72                 
73                 // P -= Den << 64
74                 P[1] -= Den;
75                 
76                 // P >= 0
77                 if( !(P[1] & (1ULL<<63)) ) {
78                         q |= (uint64_t)1 << (63-i);
79                 }
80                 else {
81                         //q |= 0 << (63-i);
82                         P[1] += Den;
83                 }
84         }
85         
86         return q;
87         #endif
88 }
89
90 /**
91  * \fn uint64_t __umoddi3(uint64_t Num, uint64_t Den)
92  * \brief Get the modulus of two 64-bit integers
93  */
94 uint64_t __umoddi3(uint64_t Num, uint64_t Den)
95 {
96         #if 0
97         if(Den == 0)    __asm__ __volatile__ ("int $0");        // Call Div by Zero Error
98         
99         if(Den == 1)    return 0;
100         if(Den == 2)    return Num & 0x01;
101         if(Den == 4)    return Num & 0x03;
102         if(Den == 8)    return Num & 0x07;
103         if(Den == 16)   return Num & 0x0F;
104         if(Den == 32)   return Num & 0x1F;
105         if(Den == 64)   return Num & 0x3F;
106         if(Den == 128)  return Num & 0x3F;
107         if(Den == 256)  return Num & 0x7F;
108         
109         while(Num >= Den)       Num -= Den;
110         
111         return Num;
112         #else
113         if(Den == 0)    __asm__ __volatile__ ("int $0");        // Call Div by Zero Error
114         
115         // Speedups
116         if(Num < Den)   return Num;
117         if(Num == Den)  return 0;
118         if(Num <= 0xFFFFFFFF && Den <= 0xFFFFFFFF)
119                 return (uint32_t)Num % (uint32_t)Den;
120         
121         // Speedups for common operations
122         if(Den == 1)    return 0;
123         if(Den == 2)    return Num & 0x01;
124         if(Den == 8)    return Num & 0x07;
125         if(Den == 16)   return Num & 0x0F;
126         return Num - __udivdi3(Num, Den) * Den;
127         #endif
128 }

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