1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20 */
21
22 #if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS)
23 #define SDL_DISABLE_ANALYZE_MACROS 1
24 #endif
25
26 #include "../SDL_internal.h"
27
28 /* This file contains portable stdlib functions for SDL */
29
30 #include "SDL_stdinc.h"
31 #include "../libm/math_libm.h"
32
33
34 double
SDL_atan(double x)35 SDL_atan(double x)
36 {
37 #if defined(HAVE_ATAN)
38 return atan(x);
39 #else
40 return SDL_uclibc_atan(x);
41 #endif /* HAVE_ATAN */
42 }
43
44 double
SDL_atan2(double x,double y)45 SDL_atan2(double x, double y)
46 {
47 #if defined(HAVE_ATAN2)
48 return atan2(x, y);
49 #else
50 return SDL_uclibc_atan2(x, y);
51 #endif /* HAVE_ATAN2 */
52 }
53
54 double
SDL_acos(double val)55 SDL_acos(double val)
56 {
57 #if defined(HAVE_ACOS)
58 return acos(val);
59 #else
60 double result;
61 if (val == -1.0) {
62 result = M_PI;
63 } else {
64 result = SDL_atan(SDL_sqrt(1.0 - val * val) / val);
65 if (result < 0.0)
66 {
67 result += M_PI;
68 }
69 }
70 return result;
71 #endif
72 }
73
74 double
SDL_asin(double val)75 SDL_asin(double val)
76 {
77 #if defined(HAVE_ASIN)
78 return asin(val);
79 #else
80 double result;
81 if (val == -1.0) {
82 result = -(M_PI / 2.0);
83 } else {
84 result = (M_PI / 2.0) - SDL_acos(val);
85 }
86 return result;
87 #endif
88 }
89
90 double
SDL_ceil(double x)91 SDL_ceil(double x)
92 {
93 #if defined(HAVE_CEIL)
94 return ceil(x);
95 #else
96 double integer = SDL_floor(x);
97 double fraction = x - integer;
98 if (fraction > 0.0) {
99 integer += 1.0;
100 }
101 return integer;
102 #endif /* HAVE_CEIL */
103 }
104
105 double
SDL_copysign(double x,double y)106 SDL_copysign(double x, double y)
107 {
108 #if defined(HAVE_COPYSIGN)
109 return copysign(x, y);
110 #elif defined(HAVE__COPYSIGN)
111 return _copysign(x, y);
112 #else
113 return SDL_uclibc_copysign(x, y);
114 #endif /* HAVE_COPYSIGN */
115 }
116
117 double
SDL_cos(double x)118 SDL_cos(double x)
119 {
120 #if defined(HAVE_COS)
121 return cos(x);
122 #else
123 return SDL_uclibc_cos(x);
124 #endif /* HAVE_COS */
125 }
126
127 float
SDL_cosf(float x)128 SDL_cosf(float x)
129 {
130 #if defined(HAVE_COSF)
131 return cosf(x);
132 #else
133 return (float)SDL_cos((double)x);
134 #endif
135 }
136
137 double
SDL_fabs(double x)138 SDL_fabs(double x)
139 {
140 #if defined(HAVE_FABS)
141 return fabs(x);
142 #else
143 return SDL_uclibc_fabs(x);
144 #endif /* HAVE_FABS */
145 }
146
147 double
SDL_floor(double x)148 SDL_floor(double x)
149 {
150 #if defined(HAVE_FLOOR)
151 return floor(x);
152 #else
153 return SDL_uclibc_floor(x);
154 #endif /* HAVE_FLOOR */
155 }
156
157 double
SDL_log(double x)158 SDL_log(double x)
159 {
160 #if defined(HAVE_LOG)
161 return log(x);
162 #else
163 return SDL_uclibc_log(x);
164 #endif /* HAVE_LOG */
165 }
166
167 double
SDL_pow(double x,double y)168 SDL_pow(double x, double y)
169 {
170 #if defined(HAVE_POW)
171 return pow(x, y);
172 #else
173 return SDL_uclibc_pow(x, y);
174 #endif /* HAVE_POW */
175 }
176
177 double
SDL_scalbn(double x,int n)178 SDL_scalbn(double x, int n)
179 {
180 #if defined(HAVE_SCALBN)
181 return scalbn(x, n);
182 #elif defined(HAVE__SCALB)
183 return _scalb(x, n);
184 #else
185 return SDL_uclibc_scalbn(x, n);
186 #endif /* HAVE_SCALBN */
187 }
188
189 double
SDL_sin(double x)190 SDL_sin(double x)
191 {
192 #if defined(HAVE_SIN)
193 return sin(x);
194 #else
195 return SDL_uclibc_sin(x);
196 #endif /* HAVE_SIN */
197 }
198
199 float
SDL_sinf(float x)200 SDL_sinf(float x)
201 {
202 #if defined(HAVE_SINF)
203 return sinf(x);
204 #else
205 return (float)SDL_sin((double)x);
206 #endif /* HAVE_SINF */
207 }
208
209 double
SDL_sqrt(double x)210 SDL_sqrt(double x)
211 {
212 #if defined(HAVE_SQRT)
213 return sqrt(x);
214 #else
215 return SDL_uclibc_sqrt(x);
216 #endif
217 }
218
219 float
SDL_sqrtf(float x)220 SDL_sqrtf(float x)
221 {
222 #if defined(HAVE_SQRTF)
223 return sqrtf(x);
224 #else
225 return (float)SDL_sqrt((double)x);
226 #endif
227 }
228
229 double
SDL_tan(double x)230 SDL_tan(double x)
231 {
232 #if defined(HAVE_TAN)
233 return tan(x);
234 #else
235 return SDL_uclibc_tan(x);
236 #endif
237 }
238
239 float
SDL_tanf(float x)240 SDL_tanf(float x)
241 {
242 #if defined(HAVE_TANF)
243 return tanf(x);
244 #else
245 return (float)SDL_tan((double)x);
246 #endif
247 }
248
SDL_abs(int x)249 int SDL_abs(int x)
250 {
251 #if defined(HAVE_ABS)
252 return abs(x);
253 #else
254 return ((x) < 0 ? -(x) : (x));
255 #endif
256 }
257
258 #if defined(HAVE_CTYPE_H)
SDL_isdigit(int x)259 int SDL_isdigit(int x) { return isdigit(x); }
SDL_isspace(int x)260 int SDL_isspace(int x) { return isspace(x); }
SDL_toupper(int x)261 int SDL_toupper(int x) { return toupper(x); }
SDL_tolower(int x)262 int SDL_tolower(int x) { return tolower(x); }
263 #else
SDL_isdigit(int x)264 int SDL_isdigit(int x) { return ((x) >= '0') && ((x) <= '9'); }
SDL_isspace(int x)265 int SDL_isspace(int x) { return ((x) == ' ') || ((x) == '\t') || ((x) == '\r') || ((x) == '\n') || ((x) == '\f') || ((x) == '\v'); }
SDL_toupper(int x)266 int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A'+((x)-'a')) : (x); }
SDL_tolower(int x)267 int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a'+((x)-'A')) : (x); }
268 #endif
269
270
271 #ifndef HAVE_LIBC
272 /* These are some C runtime intrinsics that need to be defined */
273
274 #if defined(_MSC_VER)
275
276 #ifndef __FLTUSED__
277 #define __FLTUSED__
278 __declspec(selectany) int _fltused = 1;
279 #endif
280
281 /* The optimizer on Visual Studio 2005 and later generates memcpy() calls */
282 #if (_MSC_VER >= 1400) && defined(_WIN64) && !defined(_DEBUG) && !(_MSC_VER >= 1900 && defined(_MT))
283 #include <intrin.h>
284
285 #pragma function(memcpy)
memcpy(void * destination,const void * source,size_t num)286 void * memcpy ( void * destination, const void * source, size_t num )
287 {
288 const Uint8 *src = (const Uint8 *)source;
289 Uint8 *dst = (Uint8 *)destination;
290 size_t i;
291
292 /* All WIN64 architectures have SSE, right? */
293 if (!((uintptr_t) src & 15) && !((uintptr_t) dst & 15)) {
294 __m128 values[4];
295 for (i = num / 64; i--;) {
296 _mm_prefetch(src, _MM_HINT_NTA);
297 values[0] = *(__m128 *) (src + 0);
298 values[1] = *(__m128 *) (src + 16);
299 values[2] = *(__m128 *) (src + 32);
300 values[3] = *(__m128 *) (src + 48);
301 _mm_stream_ps((float *) (dst + 0), values[0]);
302 _mm_stream_ps((float *) (dst + 16), values[1]);
303 _mm_stream_ps((float *) (dst + 32), values[2]);
304 _mm_stream_ps((float *) (dst + 48), values[3]);
305 src += 64;
306 dst += 64;
307 }
308 num &= 63;
309 }
310
311 while (num--) {
312 *dst++ = *src++;
313 }
314 return destination;
315 }
316 #endif /* _MSC_VER == 1600 && defined(_WIN64) && !defined(_DEBUG) */
317
318 #ifdef _M_IX86
319
320 /* Float to long */
321 void
322 __declspec(naked)
_ftol()323 _ftol()
324 {
325 /* *INDENT-OFF* */
326 __asm {
327 push ebp
328 mov ebp,esp
329 sub esp,20h
330 and esp,0FFFFFFF0h
331 fld st(0)
332 fst dword ptr [esp+18h]
333 fistp qword ptr [esp+10h]
334 fild qword ptr [esp+10h]
335 mov edx,dword ptr [esp+18h]
336 mov eax,dword ptr [esp+10h]
337 test eax,eax
338 je integer_QnaN_or_zero
339 arg_is_not_integer_QnaN:
340 fsubp st(1),st
341 test edx,edx
342 jns positive
343 fstp dword ptr [esp]
344 mov ecx,dword ptr [esp]
345 xor ecx,80000000h
346 add ecx,7FFFFFFFh
347 adc eax,0
348 mov edx,dword ptr [esp+14h]
349 adc edx,0
350 jmp localexit
351 positive:
352 fstp dword ptr [esp]
353 mov ecx,dword ptr [esp]
354 add ecx,7FFFFFFFh
355 sbb eax,0
356 mov edx,dword ptr [esp+14h]
357 sbb edx,0
358 jmp localexit
359 integer_QnaN_or_zero:
360 mov edx,dword ptr [esp+14h]
361 test edx,7FFFFFFFh
362 jne arg_is_not_integer_QnaN
363 fstp dword ptr [esp+18h]
364 fstp dword ptr [esp+18h]
365 localexit:
366 leave
367 ret
368 }
369 /* *INDENT-ON* */
370 }
371
372 void
_ftol2_sse()373 _ftol2_sse()
374 {
375 _ftol();
376 }
377
378 /* 64-bit math operators for 32-bit systems */
379 void
380 __declspec(naked)
_allmul()381 _allmul()
382 {
383 /* *INDENT-OFF* */
384 __asm {
385 mov eax, dword ptr[esp+8]
386 mov ecx, dword ptr[esp+10h]
387 or ecx, eax
388 mov ecx, dword ptr[esp+0Ch]
389 jne hard
390 mov eax, dword ptr[esp+4]
391 mul ecx
392 ret 10h
393 hard:
394 push ebx
395 mul ecx
396 mov ebx, eax
397 mov eax, dword ptr[esp+8]
398 mul dword ptr[esp+14h]
399 add ebx, eax
400 mov eax, dword ptr[esp+8]
401 mul ecx
402 add edx, ebx
403 pop ebx
404 ret 10h
405 }
406 /* *INDENT-ON* */
407 }
408
409 void
410 __declspec(naked)
_alldiv()411 _alldiv()
412 {
413 /* *INDENT-OFF* */
414 __asm {
415 push edi
416 push esi
417 push ebx
418 xor edi,edi
419 mov eax,dword ptr [esp+14h]
420 or eax,eax
421 jge L1
422 inc edi
423 mov edx,dword ptr [esp+10h]
424 neg eax
425 neg edx
426 sbb eax,0
427 mov dword ptr [esp+14h],eax
428 mov dword ptr [esp+10h],edx
429 L1:
430 mov eax,dword ptr [esp+1Ch]
431 or eax,eax
432 jge L2
433 inc edi
434 mov edx,dword ptr [esp+18h]
435 neg eax
436 neg edx
437 sbb eax,0
438 mov dword ptr [esp+1Ch],eax
439 mov dword ptr [esp+18h],edx
440 L2:
441 or eax,eax
442 jne L3
443 mov ecx,dword ptr [esp+18h]
444 mov eax,dword ptr [esp+14h]
445 xor edx,edx
446 div ecx
447 mov ebx,eax
448 mov eax,dword ptr [esp+10h]
449 div ecx
450 mov edx,ebx
451 jmp L4
452 L3:
453 mov ebx,eax
454 mov ecx,dword ptr [esp+18h]
455 mov edx,dword ptr [esp+14h]
456 mov eax,dword ptr [esp+10h]
457 L5:
458 shr ebx,1
459 rcr ecx,1
460 shr edx,1
461 rcr eax,1
462 or ebx,ebx
463 jne L5
464 div ecx
465 mov esi,eax
466 mul dword ptr [esp+1Ch]
467 mov ecx,eax
468 mov eax,dword ptr [esp+18h]
469 mul esi
470 add edx,ecx
471 jb L6
472 cmp edx,dword ptr [esp+14h]
473 ja L6
474 jb L7
475 cmp eax,dword ptr [esp+10h]
476 jbe L7
477 L6:
478 dec esi
479 L7:
480 xor edx,edx
481 mov eax,esi
482 L4:
483 dec edi
484 jne L8
485 neg edx
486 neg eax
487 sbb edx,0
488 L8:
489 pop ebx
490 pop esi
491 pop edi
492 ret 10h
493 }
494 /* *INDENT-ON* */
495 }
496
497 void
498 __declspec(naked)
_aulldiv()499 _aulldiv()
500 {
501 /* *INDENT-OFF* */
502 __asm {
503 push ebx
504 push esi
505 mov eax,dword ptr [esp+18h]
506 or eax,eax
507 jne L1
508 mov ecx,dword ptr [esp+14h]
509 mov eax,dword ptr [esp+10h]
510 xor edx,edx
511 div ecx
512 mov ebx,eax
513 mov eax,dword ptr [esp+0Ch]
514 div ecx
515 mov edx,ebx
516 jmp L2
517 L1:
518 mov ecx,eax
519 mov ebx,dword ptr [esp+14h]
520 mov edx,dword ptr [esp+10h]
521 mov eax,dword ptr [esp+0Ch]
522 L3:
523 shr ecx,1
524 rcr ebx,1
525 shr edx,1
526 rcr eax,1
527 or ecx,ecx
528 jne L3
529 div ebx
530 mov esi,eax
531 mul dword ptr [esp+18h]
532 mov ecx,eax
533 mov eax,dword ptr [esp+14h]
534 mul esi
535 add edx,ecx
536 jb L4
537 cmp edx,dword ptr [esp+10h]
538 ja L4
539 jb L5
540 cmp eax,dword ptr [esp+0Ch]
541 jbe L5
542 L4:
543 dec esi
544 L5:
545 xor edx,edx
546 mov eax,esi
547 L2:
548 pop esi
549 pop ebx
550 ret 10h
551 }
552 /* *INDENT-ON* */
553 }
554
555 void
556 __declspec(naked)
_allrem()557 _allrem()
558 {
559 /* *INDENT-OFF* */
560 __asm {
561 push ebx
562 push edi
563 xor edi,edi
564 mov eax,dword ptr [esp+10h]
565 or eax,eax
566 jge L1
567 inc edi
568 mov edx,dword ptr [esp+0Ch]
569 neg eax
570 neg edx
571 sbb eax,0
572 mov dword ptr [esp+10h],eax
573 mov dword ptr [esp+0Ch],edx
574 L1:
575 mov eax,dword ptr [esp+18h]
576 or eax,eax
577 jge L2
578 mov edx,dword ptr [esp+14h]
579 neg eax
580 neg edx
581 sbb eax,0
582 mov dword ptr [esp+18h],eax
583 mov dword ptr [esp+14h],edx
584 L2:
585 or eax,eax
586 jne L3
587 mov ecx,dword ptr [esp+14h]
588 mov eax,dword ptr [esp+10h]
589 xor edx,edx
590 div ecx
591 mov eax,dword ptr [esp+0Ch]
592 div ecx
593 mov eax,edx
594 xor edx,edx
595 dec edi
596 jns L4
597 jmp L8
598 L3:
599 mov ebx,eax
600 mov ecx,dword ptr [esp+14h]
601 mov edx,dword ptr [esp+10h]
602 mov eax,dword ptr [esp+0Ch]
603 L5:
604 shr ebx,1
605 rcr ecx,1
606 shr edx,1
607 rcr eax,1
608 or ebx,ebx
609 jne L5
610 div ecx
611 mov ecx,eax
612 mul dword ptr [esp+18h]
613 xchg eax,ecx
614 mul dword ptr [esp+14h]
615 add edx,ecx
616 jb L6
617 cmp edx,dword ptr [esp+10h]
618 ja L6
619 jb L7
620 cmp eax,dword ptr [esp+0Ch]
621 jbe L7
622 L6:
623 sub eax,dword ptr [esp+14h]
624 sbb edx,dword ptr [esp+18h]
625 L7:
626 sub eax,dword ptr [esp+0Ch]
627 sbb edx,dword ptr [esp+10h]
628 dec edi
629 jns L8
630 L4:
631 neg edx
632 neg eax
633 sbb edx,0
634 L8:
635 pop edi
636 pop ebx
637 ret 10h
638 }
639 /* *INDENT-ON* */
640 }
641
642 void
643 __declspec(naked)
_aullrem()644 _aullrem()
645 {
646 /* *INDENT-OFF* */
647 __asm {
648 push ebx
649 mov eax,dword ptr [esp+14h]
650 or eax,eax
651 jne L1
652 mov ecx,dword ptr [esp+10h]
653 mov eax,dword ptr [esp+0Ch]
654 xor edx,edx
655 div ecx
656 mov eax,dword ptr [esp+8]
657 div ecx
658 mov eax,edx
659 xor edx,edx
660 jmp L2
661 L1:
662 mov ecx,eax
663 mov ebx,dword ptr [esp+10h]
664 mov edx,dword ptr [esp+0Ch]
665 mov eax,dword ptr [esp+8]
666 L3:
667 shr ecx,1
668 rcr ebx,1
669 shr edx,1
670 rcr eax,1
671 or ecx,ecx
672 jne L3
673 div ebx
674 mov ecx,eax
675 mul dword ptr [esp+14h]
676 xchg eax,ecx
677 mul dword ptr [esp+10h]
678 add edx,ecx
679 jb L4
680 cmp edx,dword ptr [esp+0Ch]
681 ja L4
682 jb L5
683 cmp eax,dword ptr [esp+8]
684 jbe L5
685 L4:
686 sub eax,dword ptr [esp+10h]
687 sbb edx,dword ptr [esp+14h]
688 L5:
689 sub eax,dword ptr [esp+8]
690 sbb edx,dword ptr [esp+0Ch]
691 neg edx
692 neg eax
693 sbb edx,0
694 L2:
695 pop ebx
696 ret 10h
697 }
698 /* *INDENT-ON* */
699 }
700
701 void
702 __declspec(naked)
_alldvrm()703 _alldvrm()
704 {
705 /* *INDENT-OFF* */
706 __asm {
707 push edi
708 push esi
709 push ebp
710 xor edi,edi
711 xor ebp,ebp
712 mov eax,dword ptr [esp+14h]
713 or eax,eax
714 jge L1
715 inc edi
716 inc ebp
717 mov edx,dword ptr [esp+10h]
718 neg eax
719 neg edx
720 sbb eax,0
721 mov dword ptr [esp+14h],eax
722 mov dword ptr [esp+10h],edx
723 L1:
724 mov eax,dword ptr [esp+1Ch]
725 or eax,eax
726 jge L2
727 inc edi
728 mov edx,dword ptr [esp+18h]
729 neg eax
730 neg edx
731 sbb eax,0
732 mov dword ptr [esp+1Ch],eax
733 mov dword ptr [esp+18h],edx
734 L2:
735 or eax,eax
736 jne L3
737 mov ecx,dword ptr [esp+18h]
738 mov eax,dword ptr [esp+14h]
739 xor edx,edx
740 div ecx
741 mov ebx,eax
742 mov eax,dword ptr [esp+10h]
743 div ecx
744 mov esi,eax
745 mov eax,ebx
746 mul dword ptr [esp+18h]
747 mov ecx,eax
748 mov eax,esi
749 mul dword ptr [esp+18h]
750 add edx,ecx
751 jmp L4
752 L3:
753 mov ebx,eax
754 mov ecx,dword ptr [esp+18h]
755 mov edx,dword ptr [esp+14h]
756 mov eax,dword ptr [esp+10h]
757 L5:
758 shr ebx,1
759 rcr ecx,1
760 shr edx,1
761 rcr eax,1
762 or ebx,ebx
763 jne L5
764 div ecx
765 mov esi,eax
766 mul dword ptr [esp+1Ch]
767 mov ecx,eax
768 mov eax,dword ptr [esp+18h]
769 mul esi
770 add edx,ecx
771 jb L6
772 cmp edx,dword ptr [esp+14h]
773 ja L6
774 jb L7
775 cmp eax,dword ptr [esp+10h]
776 jbe L7
777 L6:
778 dec esi
779 sub eax,dword ptr [esp+18h]
780 sbb edx,dword ptr [esp+1Ch]
781 L7:
782 xor ebx,ebx
783 L4:
784 sub eax,dword ptr [esp+10h]
785 sbb edx,dword ptr [esp+14h]
786 dec ebp
787 jns L9
788 neg edx
789 neg eax
790 sbb edx,0
791 L9:
792 mov ecx,edx
793 mov edx,ebx
794 mov ebx,ecx
795 mov ecx,eax
796 mov eax,esi
797 dec edi
798 jne L8
799 neg edx
800 neg eax
801 sbb edx,0
802 L8:
803 pop ebp
804 pop esi
805 pop edi
806 ret 10h
807 }
808 /* *INDENT-ON* */
809 }
810
811 void
812 __declspec(naked)
_aulldvrm()813 _aulldvrm()
814 {
815 /* *INDENT-OFF* */
816 __asm {
817 push esi
818 mov eax,dword ptr [esp+14h]
819 or eax,eax
820 jne L1
821 mov ecx,dword ptr [esp+10h]
822 mov eax,dword ptr [esp+0Ch]
823 xor edx,edx
824 div ecx
825 mov ebx,eax
826 mov eax,dword ptr [esp+8]
827 div ecx
828 mov esi,eax
829 mov eax,ebx
830 mul dword ptr [esp+10h]
831 mov ecx,eax
832 mov eax,esi
833 mul dword ptr [esp+10h]
834 add edx,ecx
835 jmp L2
836 L1:
837 mov ecx,eax
838 mov ebx,dword ptr [esp+10h]
839 mov edx,dword ptr [esp+0Ch]
840 mov eax,dword ptr [esp+8]
841 L3:
842 shr ecx,1
843 rcr ebx,1
844 shr edx,1
845 rcr eax,1
846 or ecx,ecx
847 jne L3
848 div ebx
849 mov esi,eax
850 mul dword ptr [esp+14h]
851 mov ecx,eax
852 mov eax,dword ptr [esp+10h]
853 mul esi
854 add edx,ecx
855 jb L4
856 cmp edx,dword ptr [esp+0Ch]
857 ja L4
858 jb L5
859 cmp eax,dword ptr [esp+8]
860 jbe L5
861 L4:
862 dec esi
863 sub eax,dword ptr [esp+10h]
864 sbb edx,dword ptr [esp+14h]
865 L5:
866 xor ebx,ebx
867 L2:
868 sub eax,dword ptr [esp+8]
869 sbb edx,dword ptr [esp+0Ch]
870 neg edx
871 neg eax
872 sbb edx,0
873 mov ecx,edx
874 mov edx,ebx
875 mov ebx,ecx
876 mov ecx,eax
877 mov eax,esi
878 pop esi
879 ret 10h
880 }
881 /* *INDENT-ON* */
882 }
883
884 void
885 __declspec(naked)
_allshl()886 _allshl()
887 {
888 /* *INDENT-OFF* */
889 __asm {
890 cmp cl,40h
891 jae RETZERO
892 cmp cl,20h
893 jae MORE32
894 shld edx,eax,cl
895 shl eax,cl
896 ret
897 MORE32:
898 mov edx,eax
899 xor eax,eax
900 and cl,1Fh
901 shl edx,cl
902 ret
903 RETZERO:
904 xor eax,eax
905 xor edx,edx
906 ret
907 }
908 /* *INDENT-ON* */
909 }
910
911 void
912 __declspec(naked)
_allshr()913 _allshr()
914 {
915 /* *INDENT-OFF* */
916 __asm {
917 cmp cl,40h
918 jae RETZERO
919 cmp cl,20h
920 jae MORE32
921 shrd eax,edx,cl
922 sar edx,cl
923 ret
924 MORE32:
925 mov eax,edx
926 xor edx,edx
927 and cl,1Fh
928 sar eax,cl
929 ret
930 RETZERO:
931 xor eax,eax
932 xor edx,edx
933 ret
934 }
935 /* *INDENT-ON* */
936 }
937
938 void
939 __declspec(naked)
_aullshr()940 _aullshr()
941 {
942 /* *INDENT-OFF* */
943 __asm {
944 cmp cl,40h
945 jae RETZERO
946 cmp cl,20h
947 jae MORE32
948 shrd eax,edx,cl
949 shr edx,cl
950 ret
951 MORE32:
952 mov eax,edx
953 xor edx,edx
954 and cl,1Fh
955 shr eax,cl
956 ret
957 RETZERO:
958 xor eax,eax
959 xor edx,edx
960 ret
961 }
962 /* *INDENT-ON* */
963 }
964
965 #endif /* _M_IX86 */
966
967 #endif /* MSC_VER */
968
969 #endif /* !HAVE_LIBC */
970
971 /* vi: set ts=4 sw=4 expandtab: */
972