4 * lib.c - Library Functions
7 #include "../helpers.h"
10 extern void __memcpy_align4(void *_dest, const void *_src, size_t _length);
11 extern void __memcpy_byte(void *_dest, const void *_src, size_t _length);
12 extern Uint32 __divmod32_asm(Uint32 Num, Uint32 Den, Uint32 *Rem);
15 Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem);
16 Uint32 __divmod32(Uint32 Num, Uint32 Den, Uint32 *Rem);
17 Uint64 __udivdi3(Uint64 Num, Uint64 Den);
18 Uint64 __umoddi3(Uint64 Num, Uint64 Den);
19 Uint32 __udivsi3(Uint32 Num, Uint32 Den);
20 Uint32 __umodsi3(Uint32 Num, Uint32 Den);
21 Sint32 __divsi3(Sint32 Num, Sint32 Den);
22 Sint32 __modsi3(Sint32 Num, Sint32 Den);
25 void *memcpy(void *_dest, const void *_src, size_t _length)
28 const Uint8 *src8 = _src;
30 if( ((tVAddr)_dest & 3) == 0 && ((tVAddr)_src & 3) == 0 )
32 __memcpy_align4(_dest, _src, _length);
36 // Handle small copies / Non-aligned
37 if( _length < 4 || ((tVAddr)_dest & 3) != ((tVAddr)_src & 3) )
39 __memcpy_byte(_dest, _src, _length);
44 while( (tVAddr)dst8 & 3 ) *dst8 ++ = *src8++, _length --;
46 __memcpy_align4(dst8, src8, _length);
51 int memcmp(const void *_m1, const void *_m2, size_t _length)
53 const Uint32 *m1, *m2;
54 const Uint8 *m1_8 = _m1, *m2_8 = _m2;
56 // Handle small copies / Non-aligned
57 if( _length < 4 || ((tVAddr)_m1 & 3) != ((tVAddr)_m1 & 3) )
59 for( ; _length--; m1_8++,m2_8++ ) {
60 if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
66 for( ; (tVAddr)m1_8 & 3; m1_8 ++, m2_8 ++) {
67 if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
69 m1 = (void *)m1_8; m2 = (void *)m2_8;
72 for( ; _length > 3; _length -= 4, m1++, m2++)
73 if(*m1 != *m2) return *m1 - *m2;
76 m1_8 = (void*)m1; m2_8 = (void*)m2;
77 for( ; _length; _length --, m1_8++, m2_8++ )
78 if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
83 void *memset(void *_dest, int _value, size_t _length)
88 _value = (Uint8)_value;
90 // Handle small copies
93 for( ; _length--; dst8++ )
100 val32 |= val32 << 16;
103 while( (tVAddr)dst8 & 3 ) *dst8 ++ = _value;
107 for( ; _length > 3; _length -= 4)
112 for( ; _length; _length -- )
121 Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
124 if(Den == 0) return 0; // TODO: #div0
138 if(Rem) *Rem = Num & 1;
142 if(Rem) *Rem = Num & 0xF;
146 if(Rem) *Rem = Num & 0x1F;
150 if(Rem) *Rem = Num & 0xFFF;
154 if( !(Den >> 32) && !(Num >> 32) ) {
155 if(Rem) *Rem = 0; // Clear high bits
156 return __divmod32_asm(Num, Den, (Uint32*)Rem);
159 ret = __divmod64(Num, Den, Rem);
163 // Unsigned Divide 64-bit Integer
164 Uint64 __udivdi3(Uint64 Num, Uint64 Den)
166 return DivMod64U(Num, Den, NULL);
169 // Unsigned Modulus 64-bit Integer
170 Uint64 __umoddi3(Uint64 Num, Uint64 Den)
173 DivMod64U(Num, Den, &ret);
177 Uint32 __udivsi3(Uint32 Num, Uint32 Den)
179 return __divmod32_asm(Num, Den, NULL);
182 Uint32 __umodsi3(Uint32 Num, Uint32 Den)
185 __divmod32_asm(Num, Den, &rem);
189 static inline Sint32 DivMod32S(Sint32 Num, Sint32 Den, Sint32 *Rem)
201 ret = -__divmod32(Num, Den, (Uint32*)Rem);
203 ret = __divmod32(Num, Den, (Uint32*)Rem);
207 Sint32 __divsi3(Sint32 Num, Sint32 Den)
209 return DivMod32S(Num, Den, NULL);
212 Sint32 __modsi3(Sint32 Num, Sint32 Den)
215 DivMod32S(Num, Den, &rem);