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);
13 Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem);
14 Uint32 __divmod32(Uint32 Num, Uint32 Den, Uint32 *Rem);
15 Uint64 __udivdi3(Uint64 Num, Uint64 Den);
16 Uint64 __umoddi3(Uint64 Num, Uint64 Den);
17 Uint32 __udivsi3(Uint32 Num, Uint32 Den);
18 Uint32 __umodsi3(Uint32 Num, Uint32 Den);
19 Sint32 __divsi3(Sint32 Num, Sint32 Den);
20 Sint32 __modsi3(Sint32 Num, Sint32 Den);
23 void *memcpy(void *_dest, const void *_src, size_t _length)
26 const Uint8 *src8 = _src;
28 if( ((tVAddr)_dest & 3) == 0 && ((tVAddr)_src & 3) == 0 )
30 __memcpy_align4(_dest, _src, _length);
34 // Handle small copies / Non-aligned
35 if( _length < 4 || ((tVAddr)_dest & 3) != ((tVAddr)_src & 3) )
37 __memcpy_byte(_dest, _src, _length);
42 while( (tVAddr)dst8 & 3 ) *dst8 ++ = *src8++, _length --;
44 __memcpy_align32(dst8, src8, _length);
49 int memcmp(const void *_m1, const void *_m2, size_t _length)
51 const Uint32 *m1, *m2;
52 const Uint8 *m1_8 = _m1, *m2_8 = _m2;
54 // Handle small copies / Non-aligned
55 if( _length < 4 || ((tVAddr)_m1 & 3) != ((tVAddr)_m1 & 3) )
57 for( ; _length--; m1_8++,m2_8++ ) {
58 if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
64 for( ; (tVAddr)m1_8 & 3; m1_8 ++, m2_8 ++) {
65 if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
67 m1 = (void *)m1_8; m2 = (void *)m2_8;
70 for( ; _length > 3; _length -= 4, m1++, m2++)
71 if(*m1 != *m2) return *m1 - *m2;
74 m1_8 = (void*)m1; m2_8 = (void*)m2;
75 for( ; _length; _length --, m1_8++, m2_8++ )
76 if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
81 void *memset(void *_dest, int _value, size_t _length)
86 _value = (Uint8)_value;
88 // Handle small copies
91 for( ; _length--; dst8++ )
101 while( (tVAddr)dst8 & 3 ) *dst8 ++ = _value;
105 for( ; _length > 3; _length -= 4)
110 for( ; _length; _length -- )
117 // - Find what power of two times Den is > Num
118 // - Iterate down in bit significance
119 // > If the `N` value is greater than `D`, we can set this bit
120 #define DEF_DIVMOD(s) Uint##s __divmod##s(Uint##s N, Uint##s D, Uint##s*Rem){\
121 Uint##s ret=0,add=1;\
122 while(N>=D&&add) {D<<=1;add<<=1;}\
125 if(N>=D){ret+=add;N-=D;}\
135 Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
138 if(Den == 0) return 0; // TODO: #div0
148 if(Rem) *Rem = Num & 1;
152 if(Rem) *Rem = Num & 0xF;
156 if(Rem) *Rem = Num & 0x1F;
160 if(Rem) *Rem = Num & 0xFFF;
164 ret = __divmod64(Num, Den, Rem);
168 // Unsigned Divide 64-bit Integer
169 Uint64 __udivdi3(Uint64 Num, Uint64 Den)
171 return DivMod64U(Num, Den, NULL);
174 // Unsigned Modulus 64-bit Integer
175 Uint64 __umoddi3(Uint64 Num, Uint64 Den)
178 DivMod64U(Num, Den, &ret);
182 Uint32 __udivsi3(Uint32 Num, Uint32 Den)
184 return __divmod32(Num, Den, NULL);
187 Uint32 __umodsi3(Uint32 Num, Uint32 Den)
190 __divmod32(Num, Den, &rem);
194 static inline Sint32 DivMod32S(Sint32 Num, Sint32 Den, Sint32 *Rem)
206 ret = -__divmod32(Num, Den, (Uint32*)Rem);
208 ret = __divmod32(Num, Den, (Uint32*)Rem);
212 Sint32 __divsi3(Sint32 Num, Sint32 Den)
214 return DivMod32S(Num, Den, NULL);
217 Sint32 __modsi3(Sint32 Num, Sint32 Den)
220 DivMod32S(Num, Den, &rem);