Changeset 494 for trunk/src/emx/include/386/builtin.h
- Timestamp:
- Aug 1, 2003, 8:42:12 AM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/emx/include/386/builtin.h
-
Property cvs2svn:cvs-rev
changed from
1.2
to1.3
r493 r494 87 87 } 88 88 89 /* Quick routines similar to div() and friends, but inline */ 90 91 static __inline__ long __ldivmod (long num, long den, long *rem) 92 { 93 long q, r; 94 __asm__ ("cltd; idivl %2" 95 : "=a" (q), "=&d" (r) 96 : "r?m" (den), "a" (num)); 97 *rem = r; 98 return q; 99 } 100 101 static __inline__ unsigned long __uldivmod (unsigned long num, 102 unsigned long den, unsigned long *rem) 103 { 104 unsigned long q, r; 105 __asm__ ("xorl %%edx,%%edx; divl %2" 106 : "=a" (q), "=&d" (r) 107 : "r?m" (den), "a" (num)); 108 *rem = r; 109 return q; 110 } 111 112 /* 113 Divide a 64-bit integer by a 32-bit one: 114 115 A*2^32 + B A B + (A mod 32) 116 ---------- = --- * 2^32 + ---------------- 117 C C C 118 */ 119 static __inline__ long long __lldivmod (long long num, long den, long *rem) 120 { 121 long long q; 122 long r; 123 __asm__ (" movl %%eax,%%esi;" 124 " movl %%edx,%%eax;" 125 " pushl %%edx;" 126 " cltd;" 127 " idivl %2;" 128 " ;" 129 /* Now ensure remainder is smallest of possible two values (negative and 130 positive). For this we compare the remainder with positive and negative 131 denominator/2; if it is smaller than one and bigger than another we 132 consider it optimal, otherwise it can be made smaller by adding or 133 subtracting denominator to it. This is done to ensure no overflow 134 will occur at next division. */ 135 " movl %2,%%ecx;" 136 " sarl $1,%%ecx;" /* ecx = den/2 */ 137 " cmpl %%ecx,%%edx;" 138 " setl %%bl;" 139 " negl %%ecx;" 140 " cmpl %%ecx,%%edx;" 141 " setl %%bh;" 142 " xorb %%bh,%%bl;" 143 " jnz 1f;" /* Remainder is between -den/2...den/2 */ 144 " ;" 145 /* If remainder has same sign as denominator, we have to do r -= den; q++; 146 otherwise we have to do r += den; q--; */ 147 " movl %2,%%ebx;" /* ebx = den */ 148 " xorl %%edx,%%ebx;" /* r ^ den */ 149 " js 0f;" /* Different signs */ 150 " subl %2,%%edx;" /* r -= den */ 151 " addl $1,%%eax;" /* q++ */ 152 " adcl $0,%%edx;" 153 " jmp 1f;" 154 " ;" 155 "0: addl %2,%%edx;" /* r += den */ 156 " subl $1,%%eax;" /* q-- */ 157 " sbbl $0,%%edx;" 158 " ;" 159 "1: xchgl %%eax,%%esi;" 160 " idivl %2;" 161 " ;" 162 " movl %%edx,%1;" 163 " cltd;" 164 " addl %%esi,%%edx;" 165 " ;" 166 /* Check if numerator has the same sign as remainder; if they have different 167 sign we should make the remainder have same sign as numerator to comply 168 with ANSI standard, which says we always should truncate the quotient 169 towards zero. */ 170 " popl %%ebx;" /* ebx = num >> 32 */ 171 " xorl %1,%%ebx;" /* sign(r) ^ sign(num) */ 172 " jns 3f;" /* jump if same sign */ 173 " ;" 174 /* If remainder has same sign as denominator, we have to do r -= den; q++; 175 otherwise we have to do r += den; q--; */ 176 " movl %2,%%ebx;" 177 " xorl %1,%%ebx;" /* r ^ den */ 178 " js 2f;" /* Different signs */ 179 " subl %2,%1;" /* r -= den */ 180 " addl $1,%%eax;" /* q++ */ 181 " adcl $0,%%edx;" 182 " jmp 3f;" 183 " ;" 184 "2: addl %2,%1;" /* r += den */ 185 " subl $1,%%eax;" /* q-- */ 186 " sbbl $0,%%edx;" 187 " ;" 188 "3: ;" 189 : "=A" (q), "=&c" (r) 190 : "r" (den), "A" (num) 191 : "ebx", "esi"); 192 *rem = r; 193 return q; 194 } 195 196 /* 197 Same as __lldivmod except that if A < C, we can do just one division 198 instead of two because the result is always a 32-bit integer. 199 */ 200 static __inline__ unsigned long long __ulldivmod (unsigned long long num, 201 unsigned long den, unsigned long *rem) 202 { 203 unsigned long long q; 204 unsigned long r; 205 __asm__ (" movl %%eax,%1;" 206 " movl %%edx,%%eax;" 207 " xorl %%edx,%%edx;" 208 " divl %2;" 209 " xchgl %%eax,%%ecx;" 210 " divl %2;" 211 " xchgl %%edx,%1;" 212 : "=A" (q), "=c" (r) 213 : "r?m" (den), "A" (num)); 214 *rem = r; 215 return q; 216 } 217 89 218 #if defined (__cplusplus) 90 219 } -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.