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);
18 Uint64 __udivdi3(Uint64 Num, Uint64 Den);
19 Uint64 __umoddi3(Uint64 Num, Uint64 Den);
20 Uint32 __udivsi3(Uint32 Num, Uint32 Den);
21 Uint32 __umodsi3(Uint32 Num, Uint32 Den);
22 Sint32 __divsi3(Sint32 Num, Sint32 Den);
23 Sint32 __modsi3(Sint32 Num, Sint32 Den);
27 void *memcpy(void *_dest, const void *_src, size_t _length)
30 const Uint8 *src8 = _src;
32 if( ((tVAddr)_dest & 3) == 0 && ((tVAddr)_src & 3) == 0 )
34 __memcpy_align4(_dest, _src, _length);
38 // Handle small copies / Non-aligned
39 if( _length < 4 || ((tVAddr)_dest & 3) != ((tVAddr)_src & 3) )
41 __memcpy_byte(_dest, _src, _length);
46 while( (tVAddr)dst8 & 3 ) *dst8 ++ = *src8++, _length --;
48 __memcpy_align4(dst8, src8, _length);
53 int memcmp(const void *_m1, const void *_m2, size_t _length)
55 const Uint32 *m1, *m2;
56 const Uint8 *m1_8 = _m1, *m2_8 = _m2;
58 // Handle small copies / Non-aligned
59 if( _length < 4 || ((tVAddr)_m1 & 3) != ((tVAddr)_m1 & 3) )
61 for( ; _length--; m1_8++,m2_8++ ) {
62 if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
68 for( ; (tVAddr)m1_8 & 3; m1_8 ++, m2_8 ++) {
69 if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
71 m1 = (void *)m1_8; m2 = (void *)m2_8;
74 for( ; _length > 3; _length -= 4, m1++, m2++)
75 if(*m1 != *m2) return *m1 - *m2;
78 m1_8 = (void*)m1; m2_8 = (void*)m2;
79 for( ; _length; _length --, m1_8++, m2_8++ )
80 if(*m1_8 != *m2_8) return *m1_8 - *m2_8;
85 void *memset(void *_dest, int _value, size_t _length)
90 _value = (Uint8)_value;
92 // Handle small copies
95 for( ; _length--; dst8++ )
102 val32 |= val32 << 16;
105 while( (tVAddr)dst8 & 3 ) *dst8 ++ = _value;
109 for( ; _length > 3; _length -= 4)
114 for( ; _length; _length -- )
123 Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
126 if(Den == 0) return 0; // TODO: #div0
140 if(Rem) *Rem = Num & 1;
144 if(Rem) *Rem = Num & 0xF;
148 if(Rem) *Rem = Num & 0x1F;
152 if(Rem) *Rem = Num & 0xFFF;
156 if( !(Den >> 32) && !(Num >> 32) ) {
157 if(Rem) *Rem = 0; // Clear high bits
158 return __divmod32_asm(Num, Den, (Uint32*)Rem);
161 ret = __divmod64(Num, Den, Rem);
166 // Unsigned Divide 64-bit Integer
167 Uint64 __udivdi3(Uint64 Num, Uint64 Den)
169 return DivMod64U(Num, Den, NULL);
172 // Unsigned Modulus 64-bit Integer
173 Uint64 __umoddi3(Uint64 Num, Uint64 Den)
176 DivMod64U(Num, Den, &ret);
180 Uint32 __udivsi3(Uint32 Num, Uint32 Den)
182 return __divmod32_asm(Num, Den, NULL);
185 Uint32 __umodsi3(Uint32 Num, Uint32 Den)
188 __divmod32_asm(Num, Den, &rem);
193 static inline Sint32 DivMod32S(Sint32 Num, Sint32 Den, Sint32 *Rem)
205 ret = -__divmod32(Num, Den, (Uint32*)Rem);
207 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);