4 * lib.c - Library Functions
9 extern void __memcpy_align4(void *_dest, const void *_src, size_t _length);
10 extern void __memcpy_byte(void *_dest, const void *_src, size_t _length);
11 extern Uint32 __divmod32_asm(Uint32 Num, Uint32 Den, Uint32 *Rem);
14 Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem);
15 Uint32 __divmod32(Uint32 Num, Uint32 Den, Uint32 *Rem);
16 Uint64 __udivdi3(Uint64 Num, Uint64 Den);
17 Uint64 __umoddi3(Uint64 Num, Uint64 Den);
18 Uint32 __udivsi3(Uint32 Num, Uint32 Den);
19 Uint32 __umodsi3(Uint32 Num, Uint32 Den);
20 Sint32 __divsi3(Sint32 Num, Sint32 Den);
21 Sint32 __modsi3(Sint32 Num, Sint32 Den);
24 void *memcpy(void *_dest, const void *_src, size_t _length)
27 const Uint8 *src8 = _src;
29 if( ((tVAddr)_dest & 3) == 0 && ((tVAddr)_src & 3) == 0 )
31 __memcpy_align4(_dest, _src, _length);
35 // Handle small copies / Non-aligned
36 if( _length < 4 || ((tVAddr)_dest & 3) != ((tVAddr)_src & 3) )
38 __memcpy_byte(_dest, _src, _length);
43 while( (tVAddr)dst8 & 3 ) *dst8 ++ = *src8++, _length --;
45 __memcpy_align4(dst8, src8, _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
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
153 if(Rem) *Rem = Num & 1;
157 if(Rem) *Rem = Num & 0xF;
161 if(Rem) *Rem = Num & 0x1F;
165 if(Rem) *Rem = Num & 0xFFF;
169 if( !(Den >> 32) && !(Num >> 32) ) {
170 if(Rem) *Rem = 0; // Clear high bits
171 return __divmod32_asm(Num, Den, (Uint32*)Rem);
174 ret = __divmod64(Num, Den, Rem);
178 // Unsigned Divide 64-bit Integer
179 Uint64 __udivdi3(Uint64 Num, Uint64 Den)
181 return DivMod64U(Num, Den, NULL);
184 // Unsigned Modulus 64-bit Integer
185 Uint64 __umoddi3(Uint64 Num, Uint64 Den)
188 DivMod64U(Num, Den, &ret);
192 Uint32 __udivsi3(Uint32 Num, Uint32 Den)
194 return __divmod32_asm(Num, Den, NULL);
197 Uint32 __umodsi3(Uint32 Num, Uint32 Den)
200 __divmod32_asm(Num, Den, &rem);
204 static inline Sint32 DivMod32S(Sint32 Num, Sint32 Den, Sint32 *Rem)
216 ret = -__divmod32(Num, Den, (Uint32*)Rem);
218 ret = __divmod32(Num, Den, (Uint32*)Rem);
222 Sint32 __divsi3(Sint32 Num, Sint32 Den)
224 return DivMod32S(Num, Den, NULL);
227 Sint32 __modsi3(Sint32 Num, Sint32 Den)
230 DivMod32S(Num, Den, &rem);