Rev 9666 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 9666 | Rev 9765 | ||
---|---|---|---|
Line 42... | Line 42... | ||
42 | 42 | ||
43 | struct DWstruct { |
43 | struct DWstruct { |
44 | Wtype low, high; |
44 | Wtype low, high; |
Line 45... | Line 45... | ||
45 | }; |
45 | }; |
46 | - | ||
47 | typedef union |
46 | |
48 | { |
47 | typedef union { |
49 | struct DWstruct s; |
48 | struct DWstruct s; |
Line 50... | Line 49... | ||
50 | DWtype ll; |
49 | DWtype ll; |
Line 66... | Line 65... | ||
66 | /* the following deal with IEEE double-precision numbers */ |
65 | /* the following deal with IEEE double-precision numbers */ |
67 | #define EXCESSD 1022 |
66 | #define EXCESSD 1022 |
68 | #define HIDDEND (1 << 20) |
67 | #define HIDDEND (1 << 20) |
69 | #define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) |
68 | #define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) |
70 | #define SIGND(fp) ((fp.l.upper) & SIGNBIT) |
69 | #define SIGND(fp) ((fp.l.upper) & SIGNBIT) |
71 | #define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \ |
70 | #define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | (fp.l.lower >> 22)) |
72 | (fp.l.lower >> 22)) |
- | |
73 | #define HIDDEND_LL ((long long)1 << 52) |
71 | #define HIDDEND_LL ((long long)1 << 52) |
74 | #define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL) |
72 | #define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL - 1)) | HIDDEND_LL) |
75 | #define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m)) |
73 | #define PACKD_LL(s, e, m) (((long long)((s) + ((e) << 20)) << 32) | (m)) |
Line 76... | Line 74... | ||
76 | 74 | ||
Line 137... | Line 135... | ||
137 | "rm" ((USItype) (dv))) |
135 | "rm"((USItype)(dv))) |
138 | #define count_leading_zeros(count, x) \ |
136 | #define count_leading_zeros(count, x) \ |
139 | do { \ |
137 | do { \ |
140 | USItype __cbtmp; \ |
138 | USItype __cbtmp; \ |
141 | __asm__ ("bsrl %1,%0" \ |
139 | __asm__("bsrl %1,%0" \ |
- | 140 | : "=r"(__cbtmp) \ |
|
142 | : "=r" (__cbtmp) : "rm" ((USItype) (x))); \ |
141 | : "rm"((USItype)(x))); \ |
143 | (count) = __cbtmp ^ 31; \ |
142 | (count) = __cbtmp ^ 31; \ |
144 | } while (0) |
143 | } while (0) |
145 | #else |
144 | #else |
146 | #error unsupported CPU type |
145 | #error unsupported CPU type |
147 | #endif |
146 | #endif |
Line 163... | Line 162... | ||
163 | d1 = dd.s.high; |
162 | d1 = dd.s.high; |
164 | n0 = nn.s.low; |
163 | n0 = nn.s.low; |
165 | n1 = nn.s.high; |
164 | n1 = nn.s.high; |
Line 166... | Line 165... | ||
166 | 165 | ||
167 | #if !defined(UDIV_NEEDS_NORMALIZATION) |
166 | #if !defined(UDIV_NEEDS_NORMALIZATION) |
168 | if (d1 == 0) |
- | |
169 | { |
167 | if (d1 == 0) { |
170 | if (d0 > n1) |
- | |
171 | { |
168 | if (d0 > n1) { |
Line 172... | Line 169... | ||
172 | /* 0q = nn / 0D */ |
169 | /* 0q = nn / 0D */ |
173 | 170 | ||
Line 174... | Line 171... | ||
174 | udiv_qrnnd (q0, n0, n1, n0, d0); |
171 | udiv_qrnnd(q0, n0, n1, n0, d0); |
175 | q1 = 0; |
- | |
176 | 172 | q1 = 0; |
|
177 | /* Remainder in n0. */ |
- | |
178 | } |
173 | |
Line 179... | Line 174... | ||
179 | else |
174 | /* Remainder in n0. */ |
180 | { |
175 | } else { |
Line 187... | Line 182... | ||
187 | udiv_qrnnd (q0, n0, n1, n0, d0); |
182 | udiv_qrnnd(q0, n0, n1, n0, d0); |
Line 188... | Line 183... | ||
188 | 183 | ||
189 | /* Remainder in n0. */ |
184 | /* Remainder in n0. */ |
Line 190... | Line 185... | ||
190 | } |
185 | } |
191 | - | ||
192 | if (rp != 0) |
186 | |
193 | { |
187 | if (rp != 0) { |
194 | rr.s.low = n0; |
188 | rr.s.low = n0; |
195 | rr.s.high = 0; |
189 | rr.s.high = 0; |
196 | *rp = rr.ll; |
190 | *rp = rr.ll; |
Line 197... | Line 191... | ||
197 | } |
191 | } |
Line 198... | Line 192... | ||
198 | } |
192 | } |
199 | - | ||
200 | #else /* UDIV_NEEDS_NORMALIZATION */ |
193 | |
201 | - | ||
202 | if (d1 == 0) |
194 | #else /* UDIV_NEEDS_NORMALIZATION */ |
Line 203... | Line 195... | ||
203 | { |
195 | |
Line 204... | Line 196... | ||
204 | if (d0 > n1) |
196 | if (d1 == 0) { |
205 | { |
- | |
206 | /* 0q = nn / 0D */ |
197 | if (d0 > n1) { |
207 | 198 | /* 0q = nn / 0D */ |
|
Line 208... | Line 199... | ||
208 | count_leading_zeros (bm, d0); |
199 | |
209 | 200 | count_leading_zeros(bm, d0); |
|
Line 219... | Line 210... | ||
219 | 210 | ||
220 | udiv_qrnnd (q0, n0, n1, n0, d0); |
211 | udiv_qrnnd(q0, n0, n1, n0, d0); |
Line 221... | Line 212... | ||
221 | q1 = 0; |
212 | q1 = 0; |
222 | - | ||
223 | /* Remainder in n0 >> bm. */ |
213 | |
224 | } |
- | |
225 | else |
214 | /* Remainder in n0 >> bm. */ |
Line 226... | Line 215... | ||
226 | { |
215 | } else { |
227 | /* qq = NN / 0d */ |
216 | /* qq = NN / 0d */ |
Line 228... | Line 217... | ||
228 | 217 | ||
Line 229... | Line 218... | ||
229 | if (d0 == 0) |
218 | if (d0 == 0) |
230 | d0 = 1 / d0; /* Divide intentionally by zero. */ |
- | |
231 | 219 | d0 = 1 / d0; /* Divide intentionally by zero. */ |
|
232 | count_leading_zeros (bm, d0); |
220 | |
233 | 221 | count_leading_zeros(bm, d0); |
|
Line 234... | Line 222... | ||
234 | if (bm == 0) |
222 | |
235 | { |
223 | if (bm == 0) { |
Line 236... | Line 224... | ||
236 | /* From (n1 >= d0) /\ (the most significant bit of d0 is set), |
224 | /* From (n1 >= d0) /\ (the most significant bit of d0 is set), |
237 | conclude (the most significant bit of n1 is set) /\ (the |
225 | conclude (the most significant bit of n1 is set) /\ (the |
238 | leading quotient digit q1 = 1). |
- | |
239 | 226 | leading quotient digit q1 = 1). |
|
240 | This special case is necessary, not an optimization. |
- | |
241 | (Shifts counts of W_TYPE_SIZE are undefined.) */ |
227 | |
Line 242... | Line 228... | ||
242 | 228 | This special case is necessary, not an optimization. |
|
Line 243... | Line 229... | ||
243 | n1 -= d0; |
229 | (Shifts counts of W_TYPE_SIZE are undefined.) */ |
Line 262... | Line 248... | ||
262 | udiv_qrnnd (q0, n0, n1, n0, d0); |
248 | udiv_qrnnd(q0, n0, n1, n0, d0); |
Line 263... | Line 249... | ||
263 | 249 | ||
264 | /* Remainder in n0 >> bm. */ |
250 | /* Remainder in n0 >> bm. */ |
Line 265... | Line 251... | ||
265 | } |
251 | } |
266 | - | ||
267 | if (rp != 0) |
252 | |
268 | { |
253 | if (rp != 0) { |
269 | rr.s.low = n0 >> bm; |
254 | rr.s.low = n0 >> bm; |
270 | rr.s.high = 0; |
255 | rr.s.high = 0; |
271 | *rp = rr.ll; |
256 | *rp = rr.ll; |
272 | } |
257 | } |
Line 273... | Line 258... | ||
273 | } |
258 | } |
274 | #endif /* UDIV_NEEDS_NORMALIZATION */ |
- | |
275 | 259 | #endif /* UDIV_NEEDS_NORMALIZATION */ |
|
276 | else |
- | |
277 | { |
260 | |
Line 278... | Line 261... | ||
278 | if (d1 > n1) |
261 | else { |
279 | { |
262 | if (d1 > n1) { |
Line 280... | Line 263... | ||
280 | /* 00 = nn / DD */ |
263 | /* 00 = nn / DD */ |
281 | 264 | ||
282 | q0 = 0; |
- | |
283 | q1 = 0; |
265 | q0 = 0; |
284 | 266 | q1 = 0; |
|
285 | /* Remainder in n1n0. */ |
267 | |
286 | if (rp != 0) |
268 | /* Remainder in n1n0. */ |
287 | { |
- | |
288 | rr.s.low = n0; |
269 | if (rp != 0) { |
289 | rr.s.high = n1; |
- | |
290 | *rp = rr.ll; |
270 | rr.s.low = n0; |
Line 291... | Line 271... | ||
291 | } |
271 | rr.s.high = n1; |
292 | } |
272 | *rp = rr.ll; |
293 | else |
- | |
294 | { |
273 | } |
295 | /* 0q = NN / dd */ |
274 | } else { |
296 | 275 | /* 0q = NN / dd */ |
|
Line 297... | Line 276... | ||
297 | count_leading_zeros (bm, d1); |
276 | |
Line 298... | Line 277... | ||
298 | if (bm == 0) |
277 | count_leading_zeros(bm, d1); |
299 | { |
278 | if (bm == 0) { |
300 | /* From (n1 >= d1) /\ (the most significant bit of d1 is set), |
279 | /* From (n1 >= d1) /\ (the most significant bit of d1 is set), |
301 | conclude (the most significant bit of n1 is set) /\ (the |
- | |
302 | quotient digit q0 = 0 or 1). |
280 | conclude (the most significant bit of n1 is set) /\ (the |
303 | 281 | quotient digit q0 = 0 or 1). |
|
304 | This special case is necessary, not an optimization. */ |
- | |
305 | 282 | ||
306 | /* The condition on the next line takes advantage of that |
283 | This special case is necessary, not an optimization. */ |
Line 307... | Line 284... | ||
307 | n1 >= d1 (true due to program flow). */ |
284 | |
Line 308... | Line 285... | ||
308 | if (n1 > d1 || n0 >= d0) |
285 | /* The condition on the next line takes advantage of that |
309 | { |
- | |
310 | q0 = 1; |
286 | n1 >= d1 (true due to program flow). */ |
311 | sub_ddmmss (n1, n0, n1, n0, d1, d0); |
287 | if (n1 > d1 || n0 >= d0) { |
312 | } |
288 | q0 = 1; |
313 | else |
289 | sub_ddmmss(n1, n0, n1, n0, d1, d0); |
314 | q0 = 0; |
- | |
315 | 290 | } else |
|
316 | q1 = 0; |
- | |
317 | 291 | q0 = 0; |
|
318 | if (rp != 0) |
292 | |
Line 319... | Line 293... | ||
319 | { |
293 | q1 = 0; |
Line 336... | Line 310... | ||
336 | n0 = n0 << bm; |
310 | n0 = n0 << bm; |
Line 337... | Line 311... | ||
337 | 311 | ||
338 | udiv_qrnnd (q0, n1, n2, n1, d1); |
312 | udiv_qrnnd(q0, n1, n2, n1, d1); |
Line 339... | Line 313... | ||
339 | umul_ppmm (m1, m0, q0, d0); |
313 | umul_ppmm(m1, m0, q0, d0); |
340 | - | ||
341 | if (m1 > n1 || (m1 == n1 && m0 > n0)) |
314 | |
342 | { |
315 | if (m1 > n1 || (m1 == n1 && m0 > n0)) { |
343 | q0--; |
316 | q0--; |
Line 344... | Line 317... | ||
344 | sub_ddmmss (m1, m0, m1, m0, d1, d0); |
317 | sub_ddmmss(m1, m0, m1, m0, d1, d0); |
Line 345... | Line 318... | ||
345 | } |
318 | } |
346 | 319 | ||
347 | q1 = 0; |
- | |
348 | 320 | q1 = 0; |
|
349 | /* Remainder in (n1n0 - m1m0) >> bm. */ |
321 | |
350 | if (rp != 0) |
322 | /* Remainder in (n1n0 - m1m0) >> bm. */ |
351 | { |
323 | if (rp != 0) { |
352 | sub_ddmmss (n1, n0, n1, n0, m1, m0); |
324 | sub_ddmmss(n1, n0, n1, n0, m1, m0); |
Line 493... | Line 465... | ||
493 | #ifndef COMMIT_4ad186c5ef61_IS_FIXED |
465 | #ifndef COMMIT_4ad186c5ef61_IS_FIXED |
494 | long long __tcc_cvt_ftol(long double x) |
466 | long long __tcc_cvt_ftol(long double x) |
495 | { |
467 | { |
496 | unsigned c0, c1; |
468 | unsigned c0, c1; |
497 | long long ret; |
469 | long long ret; |
498 | __asm__ __volatile__ ("fnstcw %0" : "=m" (c0)); |
470 | __asm__ __volatile__("fnstcw %0" |
- | 471 | : "=m"(c0)); |
|
499 | c1 = c0 | 0x0C00; |
472 | c1 = c0 | 0x0C00; |
500 | __asm__ __volatile__ ("fldcw %0" : : "m" (c1)); |
473 | __asm__ __volatile__("fldcw %0" |
- | 474 | : |
|
- | 475 | : "m"(c1)); |
|
501 | __asm__ __volatile__ ("fistpll %0" : "=m" (ret)); |
476 | __asm__ __volatile__("fistpll %0" |
- | 477 | : "=m"(ret)); |
|
502 | __asm__ __volatile__ ("fldcw %0" : : "m" (c0)); |
478 | __asm__ __volatile__("fldcw %0" |
- | 479 | : |
|
- | 480 | : "m"(c0)); |
|
503 | return ret; |
481 | return ret; |
504 | } |
482 | } |
505 | #endif |
483 | #endif |
Line 506... | Line 484... | ||
506 | 484 | ||
Line 624... | Line 602... | ||
624 | return 0; |
602 | return 0; |
625 | } |
603 | } |
Line 626... | Line 604... | ||
626 | 604 | ||
627 | long long __fixsfdi (float a1) |
605 | long long __fixsfdi(float a1) |
628 | { |
606 | { |
- | 607 | long long ret; |
|
629 | long long ret; int s; |
608 | int s; |
630 | ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1); |
609 | ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1); |
631 | return s ? ret : -ret; |
610 | return s ? ret : -ret; |
Line 632... | Line 611... | ||
632 | } |
611 | } |
633 | 612 | ||
634 | long long __fixdfdi (double a1) |
613 | long long __fixdfdi(double a1) |
- | 614 | { |
|
635 | { |
615 | long long ret; |
636 | long long ret; int s; |
616 | int s; |
637 | ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1); |
617 | ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1); |
Line 638... | Line 618... | ||
638 | return s ? ret : -ret; |
618 | return s ? ret : -ret; |
639 | } |
619 | } |
640 | 620 | ||
- | 621 | long long __fixxfdi(long double a1) |
|
641 | long long __fixxfdi (long double a1) |
622 | { |
642 | { |
623 | long long ret; |
643 | long long ret; int s; |
624 | int s; |
Line 644... | Line 625... | ||
644 | ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1); |
625 | ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1); |
Line 645... | Line 626... | ||
645 | return s ? ret : -ret; |
626 | return s ? ret : -ret; |
646 | } |
- | |
647 | 627 | } |
|
- | 628 | ||
648 | #if defined(TCC_TARGET_X86_64) && !defined(_WIN64) |
629 | #if defined(TCC_TARGET_X86_64) && !defined(_WIN64) |
649 | 630 | ||
650 | #ifndef __TINYC__ |
631 | #ifndef __TINYC__ |
651 | #include |
632 | #include |
652 | #include |
633 | #include |
Line 660... | Line 641... | ||
660 | void free(void*); |
641 | void free(void*); |
661 | void abort(void); |
642 | void abort(void); |
662 | #endif |
643 | #endif |
Line 663... | Line 644... | ||
663 | 644 | ||
- | 645 | enum __va_arg_type { |
|
664 | enum __va_arg_type { |
646 | __va_gen_reg, |
- | 647 | __va_float_reg, |
|
665 | __va_gen_reg, __va_float_reg, __va_stack |
648 | __va_stack |
Line 666... | Line 649... | ||
666 | }; |
649 | }; |
667 | 650 | ||
668 | //This should be in sync with the declaration on our include/stdarg.h |
651 | // This should be in sync with the declaration on our include/stdarg.h |
Line 736... | Line 719... | ||
736 | } |
719 | } |
Line 737... | Line 720... | ||
737 | 720 | ||
Line 738... | Line 721... | ||
738 | #elif defined(TCC_TARGET_ARM) |
721 | #elif defined(TCC_TARGET_ARM) |
739 | - | ||
740 | #define _GNU_SOURCE |
- | |
741 | #include |
722 | |
- | 723 | #define _GNU_SOURCE |
|
- | 724 | #include |
|
Line 742... | Line 725... | ||
742 | #include |
725 | #include |
743 | #include |
726 | #include |
744 | 727 | ||
745 | void __clear_cache(void *beginning, void *end) |
728 | void __clear_cache(void* beginning, void* end) |