1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2021 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
34double
35SDL_atan(double x)
36{
37#if defined(HAVE_ATAN)
38 return atan(x);
39#else
40 return SDL_uclibc_atan(x);
41#endif
42}
43
44float
45SDL_atanf(float x)
46{
47#if defined(HAVE_ATANF)
48 return atanf(x);
49#else
50 return (float)SDL_atan((double)x);
51#endif
52}
53
54double
55SDL_atan2(double x, double y)
56{
57#if defined(HAVE_ATAN2)
58 return atan2(x, y);
59#else
60 return SDL_uclibc_atan2(x, y);
61#endif
62}
63
64float
65SDL_atan2f(float x, float y)
66{
67#if defined(HAVE_ATAN2F)
68 return atan2f(x, y);
69#else
70 return (float)SDL_atan2((double)x, (double)y);
71#endif
72}
73
74double
75SDL_acos(double val)
76{
77#if defined(HAVE_ACOS)
78 return acos(val);
79#else
80 double result;
81 if (val == -1.0) {
82 result = M_PI;
83 } else {
84 result = SDL_atan(SDL_sqrt(1.0 - val * val) / val);
85 if (result < 0.0)
86 {
87 result += M_PI;
88 }
89 }
90 return result;
91#endif
92}
93
94float
95SDL_acosf(float val)
96{
97#if defined(HAVE_ACOSF)
98 return acosf(val);
99#else
100 return (float)SDL_acos((double)val);
101#endif
102}
103
104double
105SDL_asin(double val)
106{
107#if defined(HAVE_ASIN)
108 return asin(val);
109#else
110 double result;
111 if (val == -1.0) {
112 result = -(M_PI / 2.0);
113 } else {
114 result = (M_PI / 2.0) - SDL_acos(val);
115 }
116 return result;
117#endif
118}
119
120float
121SDL_asinf(float val)
122{
123#if defined(HAVE_ASINF)
124 return asinf(val);
125#else
126 return (float)SDL_asin((double)val);
127#endif
128}
129
130double
131SDL_ceil(double x)
132{
133#if defined(HAVE_CEIL)
134 return ceil(x);
135#else
136 double integer = SDL_floor(x);
137 double fraction = x - integer;
138 if (fraction > 0.0) {
139 integer += 1.0;
140 }
141 return integer;
142#endif /* HAVE_CEIL */
143}
144
145float
146SDL_ceilf(float x)
147{
148#if defined(HAVE_CEILF)
149 return ceilf(x);
150#else
151 return (float)SDL_ceil((double)x);
152#endif
153}
154
155double
156SDL_copysign(double x, double y)
157{
158#if defined(HAVE_COPYSIGN)
159 return copysign(x, y);
160#elif defined(HAVE__COPYSIGN)
161 return _copysign(x, y);
162#elif defined(__WATCOMC__) && defined(__386__)
163 /* this is nasty as hell, but it works.. */
164 unsigned int *xi = (unsigned int *) &x,
165 *yi = (unsigned int *) &y;
166 xi[1] = (yi[1] & 0x80000000) | (xi[1] & 0x7fffffff);
167 return x;
168#else
169 return SDL_uclibc_copysign(x, y);
170#endif /* HAVE_COPYSIGN */
171}
172
173float
174SDL_copysignf(float x, float y)
175{
176#if defined(HAVE_COPYSIGNF)
177 return copysignf(x, y);
178#else
179 return (float)SDL_copysign((double)x, (double)y);
180#endif
181}
182
183double
184SDL_cos(double x)
185{
186#if defined(HAVE_COS)
187 return cos(x);
188#else
189 return SDL_uclibc_cos(x);
190#endif
191}
192
193float
194SDL_cosf(float x)
195{
196#if defined(HAVE_COSF)
197 return cosf(x);
198#else
199 return (float)SDL_cos((double)x);
200#endif
201}
202
203double
204SDL_exp(double x)
205{
206#if defined(HAVE_EXP)
207 return exp(x);
208#else
209 return SDL_uclibc_exp(x);
210#endif
211}
212
213float
214SDL_expf(float x)
215{
216#if defined(HAVE_EXPF)
217 return expf(x);
218#else
219 return (float)SDL_exp((double)x);
220#endif
221}
222
223double
224SDL_fabs(double x)
225{
226#if defined(HAVE_FABS)
227 return fabs(x);
228#else
229 return SDL_uclibc_fabs(x);
230#endif
231}
232
233float
234SDL_fabsf(float x)
235{
236#if defined(HAVE_FABSF)
237 return fabsf(x);
238#else
239 return (float)SDL_fabs((double)x);
240#endif
241}
242
243double
244SDL_floor(double x)
245{
246#if defined(HAVE_FLOOR)
247 return floor(x);
248#else
249 return SDL_uclibc_floor(x);
250#endif
251}
252
253float
254SDL_floorf(float x)
255{
256#if defined(HAVE_FLOORF)
257 return floorf(x);
258#else
259 return (float)SDL_floor((double)x);
260#endif
261}
262
263double
264SDL_trunc(double x)
265{
266#if defined(HAVE_TRUNC)
267 return trunc(x);
268#else
269 if (x >= 0.0f) {
270 return SDL_floor(x);
271 } else {
272 return SDL_ceil(x);
273 }
274#endif
275}
276
277float
278SDL_truncf(float x)
279{
280#if defined(HAVE_TRUNCF)
281 return truncf(x);
282#else
283 return (float)SDL_trunc((double)x);
284#endif
285}
286
287double
288SDL_fmod(double x, double y)
289{
290#if defined(HAVE_FMOD)
291 return fmod(x, y);
292#else
293 return SDL_uclibc_fmod(x, y);
294#endif
295}
296
297float
298SDL_fmodf(float x, float y)
299{
300#if defined(HAVE_FMODF)
301 return fmodf(x, y);
302#else
303 return (float)SDL_fmod((double)x, (double)y);
304#endif
305}
306
307double
308SDL_log(double x)
309{
310#if defined(HAVE_LOG)
311 return log(x);
312#else
313 return SDL_uclibc_log(x);
314#endif
315}
316
317float
318SDL_logf(float x)
319{
320#if defined(HAVE_LOGF)
321 return logf(x);
322#else
323 return (float)SDL_log((double)x);
324#endif
325}
326
327double
328SDL_log10(double x)
329{
330#if defined(HAVE_LOG10)
331 return log10(x);
332#else
333 return SDL_uclibc_log10(x);
334#endif
335}
336
337float
338SDL_log10f(float x)
339{
340#if defined(HAVE_LOG10F)
341 return log10f(x);
342#else
343 return (float)SDL_log10((double)x);
344#endif
345}
346
347double
348SDL_pow(double x, double y)
349{
350#if defined(HAVE_POW)
351 return pow(x, y);
352#else
353 return SDL_uclibc_pow(x, y);
354#endif
355}
356
357float
358SDL_powf(float x, float y)
359{
360#if defined(HAVE_POWF)
361 return powf(x, y);
362#else
363 return (float)SDL_pow((double)x, (double)y);
364#endif
365}
366
367double
368SDL_round(double arg)
369{
370#if defined HAVE_ROUND
371 return round(arg);
372#else
373 if (arg >= 0.0) {
374 return SDL_floor(arg + 0.5);
375 } else {
376 return SDL_ceil(arg - 0.5);
377 }
378#endif
379}
380
381float
382SDL_roundf(float arg)
383{
384#if defined HAVE_ROUNDF
385 return roundf(arg);
386#else
387 return (float)SDL_round((double)arg);
388#endif
389}
390
391long
392SDL_lround(double arg)
393{
394#if defined HAVE_LROUND
395 return lround(arg);
396#else
397 return (long)SDL_round(arg);
398#endif
399}
400
401long
402SDL_lroundf(float arg)
403{
404#if defined HAVE_LROUNDF
405 return lroundf(arg);
406#else
407 return (long)SDL_round((double)arg);
408#endif
409}
410
411double
412SDL_scalbn(double x, int n)
413{
414#if defined(HAVE_SCALBN)
415 return scalbn(x, n);
416#elif defined(HAVE__SCALB)
417 return _scalb(x, n);
418#elif defined(HAVE_LIBC) && defined(HAVE_FLOAT_H) && (FLT_RADIX == 2)
419/* from scalbn(3): If FLT_RADIX equals 2 (which is
420 * usual), then scalbn() is equivalent to ldexp(3). */
421 return ldexp(x, n);
422#else
423 return SDL_uclibc_scalbn(x, n);
424#endif
425}
426
427float
428SDL_scalbnf(float x, int n)
429{
430#if defined(HAVE_SCALBNF)
431 return scalbnf(x, n);
432#else
433 return (float)SDL_scalbn((double)x, n);
434#endif
435}
436
437double
438SDL_sin(double x)
439{
440#if defined(HAVE_SIN)
441 return sin(x);
442#else
443 return SDL_uclibc_sin(x);
444#endif
445}
446
447float
448SDL_sinf(float x)
449{
450#if defined(HAVE_SINF)
451 return sinf(x);
452#else
453 return (float)SDL_sin((double)x);
454#endif
455}
456
457double
458SDL_sqrt(double x)
459{
460#if defined(HAVE_SQRT)
461 return sqrt(x);
462#else
463 return SDL_uclibc_sqrt(x);
464#endif
465}
466
467float
468SDL_sqrtf(float x)
469{
470#if defined(HAVE_SQRTF)
471 return sqrtf(x);
472#else
473 return (float)SDL_sqrt((double)x);
474#endif
475}
476
477double
478SDL_tan(double x)
479{
480#if defined(HAVE_TAN)
481 return tan(x);
482#else
483 return SDL_uclibc_tan(x);
484#endif
485}
486
487float
488SDL_tanf(float x)
489{
490#if defined(HAVE_TANF)
491 return tanf(x);
492#else
493 return (float)SDL_tan((double)x);
494#endif
495}
496
497int SDL_abs(int x)
498{
499#if defined(HAVE_ABS)
500 return abs(x);
501#else
502 return ((x) < 0 ? -(x) : (x));
503#endif
504}
505
506#if defined(HAVE_CTYPE_H)
507int SDL_isalpha(int x) { return isalpha(x); }
508int SDL_isalnum(int x) { return isalnum(x); }
509int SDL_isdigit(int x) { return isdigit(x); }
510int SDL_isxdigit(int x) { return isxdigit(x); }
511int SDL_ispunct(int x) { return ispunct(x); }
512int SDL_isspace(int x) { return isspace(x); }
513int SDL_isupper(int x) { return isupper(x); }
514int SDL_islower(int x) { return islower(x); }
515int SDL_isprint(int x) { return isprint(x); }
516int SDL_isgraph(int x) { return isgraph(x); }
517int SDL_iscntrl(int x) { return iscntrl(x); }
518int SDL_toupper(int x) { return toupper(x); }
519int SDL_tolower(int x) { return tolower(x); }
520#else
521int SDL_isalpha(int x) { return (SDL_isupper(x)) || (SDL_islower(x)); }
522int SDL_isalnum(int x) { return (SDL_isalpha(x)) || (SDL_isdigit(x)); }
523int SDL_isdigit(int x) { return ((x) >= '0') && ((x) <= '9'); }
524int SDL_isxdigit(int x) { return (((x) >= 'A') && ((x) <= 'F')) || (((x) >= 'a') && ((x) <= 'f')) || (SDL_isdigit(x)); }
525int SDL_ispunct(int x) { return (SDL_isgraph(x)) && (!SDL_isalnum(x)); }
526int SDL_isspace(int x) { return ((x) == ' ') || ((x) == '\t') || ((x) == '\r') || ((x) == '\n') || ((x) == '\f') || ((x) == '\v'); }
527int SDL_isupper(int x) { return ((x) >= 'A') && ((x) <= 'Z'); }
528int SDL_islower(int x) { return ((x) >= 'a') && ((x) <= 'z'); }
529int SDL_isprint(int x) { return ((x) >= ' ') && ((x) < '\x7f'); }
530int SDL_isgraph(int x) { return (SDL_isprint(x)) && ((x) != ' '); }
531int SDL_iscntrl(int x) { return (((x) >= '\0') && ((x) <= '\x1f')) || ((x) == '\x7f'); }
532int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A'+((x)-'a')) : (x); }
533int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a'+((x)-'A')) : (x); }
534#endif
535
536#if defined(HAVE_CTYPE_H) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
537int SDL_isblank(int x) { return isblank(x); }
538#else
539int SDL_isblank(int x) { return ((x) == ' ') || ((x) == '\t'); }
540#endif
541
542#ifndef HAVE_LIBC
543/* These are some C runtime intrinsics that need to be defined */
544
545#if defined(_MSC_VER)
546
547#ifndef __FLTUSED__
548#define __FLTUSED__
549__declspec(selectany) int _fltused = 1;
550#endif
551
552/* The optimizer on Visual Studio 2005 and later generates memcpy() and memset() calls */
553#if _MSC_VER >= 1400
554extern void *memcpy(void* dst, const void* src, size_t len);
555#pragma intrinsic(memcpy)
556
557#pragma function(memcpy)
558void *
559memcpy(void *dst, const void *src, size_t len)
560{
561 return SDL_memcpy(dst, src, len);
562}
563
564extern void *memset(void* dst, int c, size_t len);
565#pragma intrinsic(memset)
566
567#pragma function(memset)
568void *
569memset(void *dst, int c, size_t len)
570{
571 return SDL_memset(dst, c, len);
572}
573#endif /* _MSC_VER >= 1400 */
574
575#ifdef _M_IX86
576
577/* Float to long */
578void
579__declspec(naked)
580_ftol()
581{
582 /* *INDENT-OFF* */
583 __asm {
584 push ebp
585 mov ebp,esp
586 sub esp,20h
587 and esp,0FFFFFFF0h
588 fld st(0)
589 fst dword ptr [esp+18h]
590 fistp qword ptr [esp+10h]
591 fild qword ptr [esp+10h]
592 mov edx,dword ptr [esp+18h]
593 mov eax,dword ptr [esp+10h]
594 test eax,eax
595 je integer_QnaN_or_zero
596arg_is_not_integer_QnaN:
597 fsubp st(1),st
598 test edx,edx
599 jns positive
600 fstp dword ptr [esp]
601 mov ecx,dword ptr [esp]
602 xor ecx,80000000h
603 add ecx,7FFFFFFFh
604 adc eax,0
605 mov edx,dword ptr [esp+14h]
606 adc edx,0
607 jmp localexit
608positive:
609 fstp dword ptr [esp]
610 mov ecx,dword ptr [esp]
611 add ecx,7FFFFFFFh
612 sbb eax,0
613 mov edx,dword ptr [esp+14h]
614 sbb edx,0
615 jmp localexit
616integer_QnaN_or_zero:
617 mov edx,dword ptr [esp+14h]
618 test edx,7FFFFFFFh
619 jne arg_is_not_integer_QnaN
620 fstp dword ptr [esp+18h]
621 fstp dword ptr [esp+18h]
622localexit:
623 leave
624 ret
625 }
626 /* *INDENT-ON* */
627}
628
629void
630_ftol2_sse()
631{
632 _ftol();
633}
634
635/* 64-bit math operators for 32-bit systems */
636void
637__declspec(naked)
638_allmul()
639{
640 /* *INDENT-OFF* */
641 __asm {
642 mov eax, dword ptr[esp+8]
643 mov ecx, dword ptr[esp+10h]
644 or ecx, eax
645 mov ecx, dword ptr[esp+0Ch]
646 jne hard
647 mov eax, dword ptr[esp+4]
648 mul ecx
649 ret 10h
650hard:
651 push ebx
652 mul ecx
653 mov ebx, eax
654 mov eax, dword ptr[esp+8]
655 mul dword ptr[esp+14h]
656 add ebx, eax
657 mov eax, dword ptr[esp+8]
658 mul ecx
659 add edx, ebx
660 pop ebx
661 ret 10h
662 }
663 /* *INDENT-ON* */
664}
665
666void
667__declspec(naked)
668_alldiv()
669{
670 /* *INDENT-OFF* */
671 __asm {
672 push edi
673 push esi
674 push ebx
675 xor edi,edi
676 mov eax,dword ptr [esp+14h]
677 or eax,eax
678 jge L1
679 inc edi
680 mov edx,dword ptr [esp+10h]
681 neg eax
682 neg edx
683 sbb eax,0
684 mov dword ptr [esp+14h],eax
685 mov dword ptr [esp+10h],edx
686L1:
687 mov eax,dword ptr [esp+1Ch]
688 or eax,eax
689 jge L2
690 inc edi
691 mov edx,dword ptr [esp+18h]
692 neg eax
693 neg edx
694 sbb eax,0
695 mov dword ptr [esp+1Ch],eax
696 mov dword ptr [esp+18h],edx
697L2:
698 or eax,eax
699 jne L3
700 mov ecx,dword ptr [esp+18h]
701 mov eax,dword ptr [esp+14h]
702 xor edx,edx
703 div ecx
704 mov ebx,eax
705 mov eax,dword ptr [esp+10h]
706 div ecx
707 mov edx,ebx
708 jmp L4
709L3:
710 mov ebx,eax
711 mov ecx,dword ptr [esp+18h]
712 mov edx,dword ptr [esp+14h]
713 mov eax,dword ptr [esp+10h]
714L5:
715 shr ebx,1
716 rcr ecx,1
717 shr edx,1
718 rcr eax,1
719 or ebx,ebx
720 jne L5
721 div ecx
722 mov esi,eax
723 mul dword ptr [esp+1Ch]
724 mov ecx,eax
725 mov eax,dword ptr [esp+18h]
726 mul esi
727 add edx,ecx
728 jb L6
729 cmp edx,dword ptr [esp+14h]
730 ja L6
731 jb L7
732 cmp eax,dword ptr [esp+10h]
733 jbe L7
734L6:
735 dec esi
736L7:
737 xor edx,edx
738 mov eax,esi
739L4:
740 dec edi
741 jne L8
742 neg edx
743 neg eax
744 sbb edx,0
745L8:
746 pop ebx
747 pop esi
748 pop edi
749 ret 10h
750 }
751 /* *INDENT-ON* */
752}
753
754void
755__declspec(naked)
756_aulldiv()
757{
758 /* *INDENT-OFF* */
759 __asm {
760 push ebx
761 push esi
762 mov eax,dword ptr [esp+18h]
763 or eax,eax
764 jne L1
765 mov ecx,dword ptr [esp+14h]
766 mov eax,dword ptr [esp+10h]
767 xor edx,edx
768 div ecx
769 mov ebx,eax
770 mov eax,dword ptr [esp+0Ch]
771 div ecx
772 mov edx,ebx
773 jmp L2
774L1:
775 mov ecx,eax
776 mov ebx,dword ptr [esp+14h]
777 mov edx,dword ptr [esp+10h]
778 mov eax,dword ptr [esp+0Ch]
779L3:
780 shr ecx,1
781 rcr ebx,1
782 shr edx,1
783 rcr eax,1
784 or ecx,ecx
785 jne L3
786 div ebx
787 mov esi,eax
788 mul dword ptr [esp+18h]
789 mov ecx,eax
790 mov eax,dword ptr [esp+14h]
791 mul esi
792 add edx,ecx
793 jb L4
794 cmp edx,dword ptr [esp+10h]
795 ja L4
796 jb L5
797 cmp eax,dword ptr [esp+0Ch]
798 jbe L5
799L4:
800 dec esi
801L5:
802 xor edx,edx
803 mov eax,esi
804L2:
805 pop esi
806 pop ebx
807 ret 10h
808 }
809 /* *INDENT-ON* */
810}
811
812void
813__declspec(naked)
814_allrem()
815{
816 /* *INDENT-OFF* */
817 __asm {
818 push ebx
819 push edi
820 xor edi,edi
821 mov eax,dword ptr [esp+10h]
822 or eax,eax
823 jge L1
824 inc edi
825 mov edx,dword ptr [esp+0Ch]
826 neg eax
827 neg edx
828 sbb eax,0
829 mov dword ptr [esp+10h],eax
830 mov dword ptr [esp+0Ch],edx
831L1:
832 mov eax,dword ptr [esp+18h]
833 or eax,eax
834 jge L2
835 mov edx,dword ptr [esp+14h]
836 neg eax
837 neg edx
838 sbb eax,0
839 mov dword ptr [esp+18h],eax
840 mov dword ptr [esp+14h],edx
841L2:
842 or eax,eax
843 jne L3
844 mov ecx,dword ptr [esp+14h]
845 mov eax,dword ptr [esp+10h]
846 xor edx,edx
847 div ecx
848 mov eax,dword ptr [esp+0Ch]
849 div ecx
850 mov eax,edx
851 xor edx,edx
852 dec edi
853 jns L4
854 jmp L8
855L3:
856 mov ebx,eax
857 mov ecx,dword ptr [esp+14h]
858 mov edx,dword ptr [esp+10h]
859 mov eax,dword ptr [esp+0Ch]
860L5:
861 shr ebx,1
862 rcr ecx,1
863 shr edx,1
864 rcr eax,1
865 or ebx,ebx
866 jne L5
867 div ecx
868 mov ecx,eax
869 mul dword ptr [esp+18h]
870 xchg eax,ecx
871 mul dword ptr [esp+14h]
872 add edx,ecx
873 jb L6
874 cmp edx,dword ptr [esp+10h]
875 ja L6
876 jb L7
877 cmp eax,dword ptr [esp+0Ch]
878 jbe L7
879L6:
880 sub eax,dword ptr [esp+14h]
881 sbb edx,dword ptr [esp+18h]
882L7:
883 sub eax,dword ptr [esp+0Ch]
884 sbb edx,dword ptr [esp+10h]
885 dec edi
886 jns L8
887L4:
888 neg edx
889 neg eax
890 sbb edx,0
891L8:
892 pop edi
893 pop ebx
894 ret 10h
895 }
896 /* *INDENT-ON* */
897}
898
899void
900__declspec(naked)
901_aullrem()
902{
903 /* *INDENT-OFF* */
904 __asm {
905 push ebx
906 mov eax,dword ptr [esp+14h]
907 or eax,eax
908 jne L1
909 mov ecx,dword ptr [esp+10h]
910 mov eax,dword ptr [esp+0Ch]
911 xor edx,edx
912 div ecx
913 mov eax,dword ptr [esp+8]
914 div ecx
915 mov eax,edx
916 xor edx,edx
917 jmp L2
918L1:
919 mov ecx,eax
920 mov ebx,dword ptr [esp+10h]
921 mov edx,dword ptr [esp+0Ch]
922 mov eax,dword ptr [esp+8]
923L3:
924 shr ecx,1
925 rcr ebx,1
926 shr edx,1
927 rcr eax,1
928 or ecx,ecx
929 jne L3
930 div ebx
931 mov ecx,eax
932 mul dword ptr [esp+14h]
933 xchg eax,ecx
934 mul dword ptr [esp+10h]
935 add edx,ecx
936 jb L4
937 cmp edx,dword ptr [esp+0Ch]
938 ja L4
939 jb L5
940 cmp eax,dword ptr [esp+8]
941 jbe L5
942L4:
943 sub eax,dword ptr [esp+10h]
944 sbb edx,dword ptr [esp+14h]
945L5:
946 sub eax,dword ptr [esp+8]
947 sbb edx,dword ptr [esp+0Ch]
948 neg edx
949 neg eax
950 sbb edx,0
951L2:
952 pop ebx
953 ret 10h
954 }
955 /* *INDENT-ON* */
956}
957
958void
959__declspec(naked)
960_alldvrm()
961{
962 /* *INDENT-OFF* */
963 __asm {
964 push edi
965 push esi
966 push ebp
967 xor edi,edi
968 xor ebp,ebp
969 mov eax,dword ptr [esp+14h]
970 or eax,eax
971 jge L1
972 inc edi
973 inc ebp
974 mov edx,dword ptr [esp+10h]
975 neg eax
976 neg edx
977 sbb eax,0
978 mov dword ptr [esp+14h],eax
979 mov dword ptr [esp+10h],edx
980L1:
981 mov eax,dword ptr [esp+1Ch]
982 or eax,eax
983 jge L2
984 inc edi
985 mov edx,dword ptr [esp+18h]
986 neg eax
987 neg edx
988 sbb eax,0
989 mov dword ptr [esp+1Ch],eax
990 mov dword ptr [esp+18h],edx
991L2:
992 or eax,eax
993 jne L3
994 mov ecx,dword ptr [esp+18h]
995 mov eax,dword ptr [esp+14h]
996 xor edx,edx
997 div ecx
998 mov ebx,eax
999 mov eax,dword ptr [esp+10h]
1000 div ecx
1001 mov esi,eax
1002 mov eax,ebx
1003 mul dword ptr [esp+18h]
1004 mov ecx,eax
1005 mov eax,esi
1006 mul dword ptr [esp+18h]
1007 add edx,ecx
1008 jmp L4
1009L3:
1010 mov ebx,eax
1011 mov ecx,dword ptr [esp+18h]
1012 mov edx,dword ptr [esp+14h]
1013 mov eax,dword ptr [esp+10h]
1014L5:
1015 shr ebx,1
1016 rcr ecx,1
1017 shr edx,1
1018 rcr eax,1
1019 or ebx,ebx
1020 jne L5
1021 div ecx
1022 mov esi,eax
1023 mul dword ptr [esp+1Ch]
1024 mov ecx,eax
1025 mov eax,dword ptr [esp+18h]
1026 mul esi
1027 add edx,ecx
1028 jb L6
1029 cmp edx,dword ptr [esp+14h]
1030 ja L6
1031 jb L7
1032 cmp eax,dword ptr [esp+10h]
1033 jbe L7
1034L6:
1035 dec esi
1036 sub eax,dword ptr [esp+18h]
1037 sbb edx,dword ptr [esp+1Ch]
1038L7:
1039 xor ebx,ebx
1040L4:
1041 sub eax,dword ptr [esp+10h]
1042 sbb edx,dword ptr [esp+14h]
1043 dec ebp
1044 jns L9
1045 neg edx
1046 neg eax
1047 sbb edx,0
1048L9:
1049 mov ecx,edx
1050 mov edx,ebx
1051 mov ebx,ecx
1052 mov ecx,eax
1053 mov eax,esi
1054 dec edi
1055 jne L8
1056 neg edx
1057 neg eax
1058 sbb edx,0
1059L8:
1060 pop ebp
1061 pop esi
1062 pop edi
1063 ret 10h
1064 }
1065 /* *INDENT-ON* */
1066}
1067
1068void
1069__declspec(naked)
1070_aulldvrm()
1071{
1072 /* *INDENT-OFF* */
1073 __asm {
1074 push esi
1075 mov eax,dword ptr [esp+14h]
1076 or eax,eax
1077 jne L1
1078 mov ecx,dword ptr [esp+10h]
1079 mov eax,dword ptr [esp+0Ch]
1080 xor edx,edx
1081 div ecx
1082 mov ebx,eax
1083 mov eax,dword ptr [esp+8]
1084 div ecx
1085 mov esi,eax
1086 mov eax,ebx
1087 mul dword ptr [esp+10h]
1088 mov ecx,eax
1089 mov eax,esi
1090 mul dword ptr [esp+10h]
1091 add edx,ecx
1092 jmp L2
1093L1:
1094 mov ecx,eax
1095 mov ebx,dword ptr [esp+10h]
1096 mov edx,dword ptr [esp+0Ch]
1097 mov eax,dword ptr [esp+8]
1098L3:
1099 shr ecx,1
1100 rcr ebx,1
1101 shr edx,1
1102 rcr eax,1
1103 or ecx,ecx
1104 jne L3
1105 div ebx
1106 mov esi,eax
1107 mul dword ptr [esp+14h]
1108 mov ecx,eax
1109 mov eax,dword ptr [esp+10h]
1110 mul esi
1111 add edx,ecx
1112 jb L4
1113 cmp edx,dword ptr [esp+0Ch]
1114 ja L4
1115 jb L5
1116 cmp eax,dword ptr [esp+8]
1117 jbe L5
1118L4:
1119 dec esi
1120 sub eax,dword ptr [esp+10h]
1121 sbb edx,dword ptr [esp+14h]
1122L5:
1123 xor ebx,ebx
1124L2:
1125 sub eax,dword ptr [esp+8]
1126 sbb edx,dword ptr [esp+0Ch]
1127 neg edx
1128 neg eax
1129 sbb edx,0
1130 mov ecx,edx
1131 mov edx,ebx
1132 mov ebx,ecx
1133 mov ecx,eax
1134 mov eax,esi
1135 pop esi
1136 ret 10h
1137 }
1138 /* *INDENT-ON* */
1139}
1140
1141void
1142__declspec(naked)
1143_allshl()
1144{
1145 /* *INDENT-OFF* */
1146 __asm {
1147 cmp cl,40h
1148 jae RETZERO
1149 cmp cl,20h
1150 jae MORE32
1151 shld edx,eax,cl
1152 shl eax,cl
1153 ret
1154MORE32:
1155 mov edx,eax
1156 xor eax,eax
1157 and cl,1Fh
1158 shl edx,cl
1159 ret
1160RETZERO:
1161 xor eax,eax
1162 xor edx,edx
1163 ret
1164 }
1165 /* *INDENT-ON* */
1166}
1167
1168void
1169__declspec(naked)
1170_allshr()
1171{
1172 /* *INDENT-OFF* */
1173 __asm {
1174 cmp cl,3Fh
1175 jae RETSIGN
1176 cmp cl,20h
1177 jae MORE32
1178 shrd eax,edx,cl
1179 sar edx,cl
1180 ret
1181MORE32:
1182 mov eax,edx
1183 sar edx,1Fh
1184 and cl,1Fh
1185 sar eax,cl
1186 ret
1187RETSIGN:
1188 sar edx,1Fh
1189 mov eax,edx
1190 ret
1191 }
1192 /* *INDENT-ON* */
1193}
1194
1195void
1196__declspec(naked)
1197_aullshr()
1198{
1199 /* *INDENT-OFF* */
1200 __asm {
1201 cmp cl,40h
1202 jae RETZERO
1203 cmp cl,20h
1204 jae MORE32
1205 shrd eax,edx,cl
1206 shr edx,cl
1207 ret
1208MORE32:
1209 mov eax,edx
1210 xor edx,edx
1211 and cl,1Fh
1212 shr eax,cl
1213 ret
1214RETZERO:
1215 xor eax,eax
1216 xor edx,edx
1217 ret
1218 }
1219 /* *INDENT-ON* */
1220}
1221
1222#endif /* _M_IX86 */
1223
1224#endif /* MSC_VER */
1225
1226#endif /* !HAVE_LIBC */
1227
1228/* vi: set ts=4 sw=4 expandtab: */
1229