• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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