4 * lib.c - Library Functions
9 Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem);
10 Uint32 __divmod32(Uint32 Num, Uint32 Den, Uint32 *Rem);
11 Uint64 __udivdi3(Uint64 Num, Uint64 Den);
12 Uint64 __umoddi3(Uint64 Num, Uint64 Den);
13 Uint32 __udivsi3(Uint32 Num, Uint32 Den);
14 Uint32 __umodsi3(Uint32 Num, Uint32 Den);
15 Sint32 __divsi3(Sint32 Num, Sint32 Den);
16 Sint32 __modsi3(Sint32 Num, Sint32 Den);
19 void *memcpy(void *_dest, const void *_src, size_t _length)
24 const Uint8 *src8 = _src;
26 // Handle small copies / Non-aligned
27 if( _length < 4 || ((tVAddr)_dest & 3) != ((tVAddr)_src & 3) )
29 for( ; _length--; dst8++,src8++ )
35 while( (tVAddr)dst8 & 3 ) *dst8 ++ = *src8++;
36 dst = (void *)dst8; src = (void *)src8;
39 for( ; _length > 3; _length -= 4)
43 dst8 = (void*)dst; src8 = (void*)src;
44 for( ; _length; _length -- )
50 int memcmp(const void *_m1, const void *_m2, size_t _length)
52 const Uint32 *m1, *m2;
53 const Uint8 *m1_8 = _m1, *m2_8 = _m2;
55 // Handle small copies / Non-aligned
56 if( _length < 4 || ((tVAddr)_m1 & 3) != ((tVAddr)_m1 & 3) )
58 for( ; _length--; m1_8++,m2_8++ ) {
59 if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
65 for( ; (tVAddr)m1_8 & 3; m1_8 ++, m2_8 ++) {
66 if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
68 m1 = (void *)m1_8; m2 = (void *)m2_8;
71 for( ; _length > 3; _length -= 4, m1++, m2++)
72 if(*m1 != *m2) return *m1 - *m2;
75 m1_8 = (void*)m1; m2_8 = (void*)m2;
76 for( ; _length; _length --, m1_8++, m2_8++ )
77 if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
82 void *memset(void *_dest, int _value, size_t _length)
87 _value = (Uint8)_value;
89 // Handle small copies / Non-aligned
92 for( ; _length--; dst8++ )
102 while( (tVAddr)dst8 & 3 ) *dst8 ++ = _value;
106 for( ; _length > 3; _length -= 4)
111 for( ; _length; _length -- )
118 // - Find what power of two times Den is > Num
119 // - Iterate down in bit significance
120 // > If the `N` value is greater than `D`, we can set this bit
121 #define DEF_DIVMOD(s) Uint##s __divmod##s(Uint##s N, Uint##s D, Uint##s*Rem){\
122 Uint##s ret=0,add=1;\
123 while(N>=D&&add) {D<<=1;add<<=1;}\
126 if(N>=D){ret+=add;N-=D;}\
136 Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
139 if(Den == 0) return 0; // TODO: #div0
149 if(Rem) *Rem = Num & 1;
153 if(Rem) *Rem = Num & 0xF;
157 if(Rem) *Rem = Num & 0x1F;
161 if(Rem) *Rem = Num & 0xFFF;
165 ret = __divmod64(Num, Den, Rem);
169 // Unsigned Divide 64-bit Integer
170 Uint64 __udivdi3(Uint64 Num, Uint64 Den)
172 return DivMod64U(Num, Den, NULL);
175 // Unsigned Modulus 64-bit Integer
176 Uint64 __umoddi3(Uint64 Num, Uint64 Den)
179 DivMod64U(Num, Den, &ret);
183 Uint32 __udivsi3(Uint32 Num, Uint32 Den)
185 return __divmod32(Num, Den, NULL);
188 Uint32 __umodsi3(Uint32 Num, Uint32 Den)
191 __divmod32(Num, Den, &rem);
195 static inline Sint32 DivMod32S(Sint32 Num, Sint32 Den, Sint32 *Rem)
207 ret = -__divmod32(Num, Den, (Uint32*)Rem);
209 ret = __divmod32(Num, Den, (Uint32*)Rem);
213 Sint32 __divsi3(Sint32 Num, Sint32 Den)
215 return DivMod32S(Num, Den, NULL);
218 Sint32 __modsi3(Sint32 Num, Sint32 Den)
221 DivMod32S(Num, Den, &rem);