Fixed bug 3468 - _allshr in SDL_stdlib.c is not working properly
authorSam Lantinga <slouken@libsdl.org>
Sun, 06 Nov 2016 10:01:08 -0800
changeset 10587513f0e80a7dd
parent 10586 c8ca00149330
child 10588 cc83da0cb986
Fixed bug 3468 - _allshr in SDL_stdlib.c is not working properly

Mark Pizzolato

On Windows with Visual Studio, when building SDL as a static library using the x86 (32bit) mode, several intrinsic operations are implemented in code in SDL_stdlib.c.

One of these, _allshr() is not properly implemented and fails for some input. As a result, some operations on 64bit data elements (long long) don't always work.

I classified this bug as a blocker since things absolutely don't work when the affected code is invoked. The affected code is only invoked when SDL is compiled in x86 mode on Visual Studio when building a SDL as a static library. This build environment isn't common, and hence the bug hasn't been noticed previously.

I reopened #2537 and mentioned this problem and provided a fix. That fix is provided again here along with test code which could be added to some of the SDL test code. This test code verifies that the x86 intrinsic routines produce the same results as the native x64 instructions which these routines emulate under the Microsoft compiler. The point of the tests is to make sure that Visual Studio x86 code produces the same results as Visual Studio x64 code. Some of the arguments (or boundary conditions) may produce different results on other compiler environments, so the tests really shouldn't be run on all compilers. The test driver only actually exercised code when the compiler defines _MSC_VER, so the driver can generically be invoked without issue.
src/stdlib/SDL_stdlib.c
test/testplatform.c
     1.1 --- a/src/stdlib/SDL_stdlib.c	Sun Nov 06 09:30:06 2016 -0800
     1.2 +++ b/src/stdlib/SDL_stdlib.c	Sun Nov 06 10:01:08 2016 -0800
     1.3 @@ -375,35 +375,35 @@
     1.4      _ftol();
     1.5  }
     1.6  
     1.7 -/* 64-bit math operators for 32-bit systems */
     1.8 -void
     1.9 -__declspec(naked)
    1.10 -_allmul()
    1.11 -{
    1.12 -    /* *INDENT-OFF* */
    1.13 -    __asm {
    1.14 -        mov         eax, dword ptr[esp+8]
    1.15 -        mov         ecx, dword ptr[esp+10h]
    1.16 -        or          ecx, eax
    1.17 -        mov         ecx, dword ptr[esp+0Ch]
    1.18 -        jne         hard
    1.19 -        mov         eax, dword ptr[esp+4]
    1.20 -        mul         ecx
    1.21 -        ret         10h
    1.22 -hard:
    1.23 -        push        ebx
    1.24 -        mul         ecx
    1.25 -        mov         ebx, eax
    1.26 -        mov         eax, dword ptr[esp+8]
    1.27 -        mul         dword ptr[esp+14h]
    1.28 -        add         ebx, eax
    1.29 -        mov         eax, dword ptr[esp+8]
    1.30 -        mul         ecx
    1.31 -        add         edx, ebx
    1.32 -        pop         ebx
    1.33 -        ret         10h
    1.34 -    }
    1.35 -    /* *INDENT-ON* */
    1.36 +/* 64-bit math operators for 32-bit systems */
    1.37 +void
    1.38 +__declspec(naked)
    1.39 +_allmul()
    1.40 +{
    1.41 +    /* *INDENT-OFF* */
    1.42 +    __asm {
    1.43 +        mov         eax, dword ptr[esp+8]
    1.44 +        mov         ecx, dword ptr[esp+10h]
    1.45 +        or          ecx, eax
    1.46 +        mov         ecx, dword ptr[esp+0Ch]
    1.47 +        jne         hard
    1.48 +        mov         eax, dword ptr[esp+4]
    1.49 +        mul         ecx
    1.50 +        ret         10h
    1.51 +hard:
    1.52 +        push        ebx
    1.53 +        mul         ecx
    1.54 +        mov         ebx, eax
    1.55 +        mov         eax, dword ptr[esp+8]
    1.56 +        mul         dword ptr[esp+14h]
    1.57 +        add         ebx, eax
    1.58 +        mov         eax, dword ptr[esp+8]
    1.59 +        mul         ecx
    1.60 +        add         edx, ebx
    1.61 +        pop         ebx
    1.62 +        ret         10h
    1.63 +    }
    1.64 +    /* *INDENT-ON* */
    1.65  }
    1.66  
    1.67  void
    1.68 @@ -914,8 +914,8 @@
    1.69  {
    1.70      /* *INDENT-OFF* */
    1.71      __asm {
    1.72 -        cmp         cl,40h
    1.73 -        jae         RETZERO
    1.74 +        cmp         cl,3Fh
    1.75 +        jae         RETSIGN
    1.76          cmp         cl,20h
    1.77          jae         MORE32
    1.78          shrd        eax,edx,cl
    1.79 @@ -923,13 +923,13 @@
    1.80          ret
    1.81  MORE32:
    1.82          mov         eax,edx
    1.83 -        xor         edx,edx
    1.84 +        sar         edx,1Fh
    1.85          and         cl,1Fh
    1.86          sar         eax,cl
    1.87          ret
    1.88 -RETZERO:
    1.89 -        xor         eax,eax
    1.90 -        xor         edx,edx
    1.91 +RETSIGN:
    1.92 +        sar         edx,1Fh
    1.93 +        mov         eax,edx
    1.94          ret
    1.95      }
    1.96      /* *INDENT-ON* */
     2.1 --- a/test/testplatform.c	Sun Nov 06 09:30:06 2016 -0800
     2.2 +++ b/test/testplatform.c	Sun Nov 06 10:01:08 2016 -0800
     2.3 @@ -128,6 +128,220 @@
     2.4      return (error ? 1 : 0);
     2.5  }
     2.6  
     2.7 +static int TST_allmul (void *a, void *b, int arg, void *result, void *expected)
     2.8 +{
     2.9 +    (*(long long *)result) = ((*(long long *)a) * (*(long long *)b));
    2.10 +    return (*(long long *)result) == (*(long long *)expected);
    2.11 +}
    2.12 +
    2.13 +static int TST_alldiv (void *a, void *b, int arg, void *result, void *expected)
    2.14 +{
    2.15 +    (*(long long *)result) = ((*(long long *)a) / (*(long long *)b));
    2.16 +    return (*(long long *)result) == (*(long long *)expected);
    2.17 +}
    2.18 +
    2.19 +static int TST_allrem (void *a, void *b, int arg, void *result, void *expected)
    2.20 +{
    2.21 +    (*(long long *)result) = ((*(long long *)a) % (*(long long *)b));
    2.22 +    return (*(long long *)result) == (*(long long *)expected);
    2.23 +}
    2.24 +
    2.25 +static int TST_ualldiv (void *a, void *b, int arg, void *result, void *expected)
    2.26 +{
    2.27 +    (*(unsigned long long *)result) = ((*(unsigned long long *)a) / (*(unsigned long long *)b));
    2.28 +    return (*(unsigned long long *)result) == (*(unsigned long long *)expected);
    2.29 +}
    2.30 +
    2.31 +static int TST_uallrem (void *a, void *b, int arg, void *result, void *expected)
    2.32 +{
    2.33 +    (*(unsigned long long *)result) = ((*(unsigned long long *)a) % (*(unsigned long long *)b));
    2.34 +    return (*(unsigned long long *)result) == (*(unsigned long long *)expected);
    2.35 +}
    2.36 +
    2.37 +static int TST_allshl (void *a, void *b, int arg, void *result, void *expected)
    2.38 +{
    2.39 +    (*(long long *)result) = (*(long long *)a) << arg;
    2.40 +    return (*(long long *)result) == (*(long long *)expected);
    2.41 +}
    2.42 +
    2.43 +static int TST_aullshl (void *a, void *b, int arg, void *result, void *expected)
    2.44 +{
    2.45 +    (*(unsigned long long *)result) = (*(unsigned long long *)a) << arg;
    2.46 +    return (*(unsigned long long *)result) == (*(unsigned long long *)expected);
    2.47 +}
    2.48 +
    2.49 +static int TST_allshr (void *a, void *b, int arg, void *result, void *expected)
    2.50 +{
    2.51 +    (*(long long *)result) = (*(long long *)a) >> arg;
    2.52 +    return (*(long long *)result) == (*(long long *)expected);
    2.53 +}
    2.54 +
    2.55 +static int TST_aullshr (void *a, void *b, int arg, void *result, void *expected)
    2.56 +{
    2.57 +    (*(unsigned long long *)result) = (*(unsigned long long *)a) >> arg;
    2.58 +    return (*(unsigned long long *)result) == (*(unsigned long long *)expected);
    2.59 +}
    2.60 +
    2.61 +
    2.62 +typedef int (*LL_Intrinsic)(void *a, void *b, int arg, void *result, void *expected);
    2.63 +
    2.64 +typedef struct {
    2.65 +    const char *operation;
    2.66 +    LL_Intrinsic routine;
    2.67 +    unsigned long long a, b;
    2.68 +    int arg;
    2.69 +    unsigned long long expected_result;
    2.70 +} LL_Test;
    2.71 +
    2.72 +static LL_Test LL_Tests[] = 
    2.73 +{
    2.74 +    {"_allshl",   &TST_allshl,   0xFFFFFFFFFFFFFFFFll,                  0ll, 65, 0x0000000000000000ll},
    2.75 +    {"_allshl",   &TST_allshl,   0xFFFFFFFFFFFFFFFFll,                  0ll,  1, 0xFFFFFFFFFFFFFFFEll},
    2.76 +    {"_allshl",   &TST_allshl,   0xFFFFFFFFFFFFFFFFll,                  0ll, 32, 0xFFFFFFFF00000000ll},
    2.77 +    {"_allshl",   &TST_allshl,   0xFFFFFFFFFFFFFFFFll,                  0ll, 33, 0xFFFFFFFE00000000ll},
    2.78 +    {"_allshl",   &TST_allshl,   0xFFFFFFFFFFFFFFFFll,                  0ll,  0, 0xFFFFFFFFFFFFFFFFll},
    2.79 +
    2.80 +    {"_allshr",   &TST_allshr,   0xAAAAAAAA55555555ll,                  0ll, 63, 0xFFFFFFFFFFFFFFFFll},
    2.81 +    {"_allshr",   &TST_allshr,   0xFFFFFFFFFFFFFFFFll,                  0ll, 65, 0xFFFFFFFFFFFFFFFFll},
    2.82 +    {"_allshr",   &TST_allshr,   0xFFFFFFFFFFFFFFFFll,                  0ll,  1, 0xFFFFFFFFFFFFFFFFll},
    2.83 +    {"_allshr",   &TST_allshr,   0xFFFFFFFFFFFFFFFFll,                  0ll, 32, 0xFFFFFFFFFFFFFFFFll},
    2.84 +    {"_allshr",   &TST_allshr,   0xFFFFFFFFFFFFFFFFll,                  0ll, 33, 0xFFFFFFFFFFFFFFFFll},
    2.85 +    {"_allshr",   &TST_allshr,   0xFFFFFFFFFFFFFFFFll,                  0ll,  0, 0xFFFFFFFFFFFFFFFFll},
    2.86 +    {"_allshr",   &TST_allshr,   0x5F5F5F5F5F5F5F5Fll,                  0ll, 65, 0x0000000000000000ll},
    2.87 +    {"_allshr",   &TST_allshr,   0x5F5F5F5F5F5F5F5Fll,                  0ll,  1, 0x2FAFAFAFAFAFAFAFll},
    2.88 +    {"_allshr",   &TST_allshr,   0x5F5F5F5F5F5F5F5Fll,                  0ll, 32, 0x000000005F5F5F5Fll},
    2.89 +    {"_allshr",   &TST_allshr,   0x5F5F5F5F5F5F5F5Fll,                  0ll, 33, 0x000000002FAFAFAFll},
    2.90 +
    2.91 +    {"_aullshl",  &TST_aullshl,  0xFFFFFFFFFFFFFFFFll,                  0ll, 65, 0x0000000000000000ll},
    2.92 +    {"_aullshl",  &TST_aullshl,  0xFFFFFFFFFFFFFFFFll,                  0ll,  1, 0xFFFFFFFFFFFFFFFEll},
    2.93 +    {"_aullshl",  &TST_aullshl,  0xFFFFFFFFFFFFFFFFll,                  0ll, 32, 0xFFFFFFFF00000000ll},
    2.94 +    {"_aullshl",  &TST_aullshl,  0xFFFFFFFFFFFFFFFFll,                  0ll, 33, 0xFFFFFFFE00000000ll},
    2.95 +    {"_aullshl",  &TST_aullshl,  0xFFFFFFFFFFFFFFFFll,                  0ll,  0, 0xFFFFFFFFFFFFFFFFll},
    2.96 +
    2.97 +    {"_aullshr",  &TST_aullshr,  0xFFFFFFFFFFFFFFFFll,                  0ll, 65, 0x0000000000000000ll},
    2.98 +    {"_aullshr",  &TST_aullshr,  0xFFFFFFFFFFFFFFFFll,                  0ll,  1, 0x7FFFFFFFFFFFFFFFll},
    2.99 +    {"_aullshr",  &TST_aullshr,  0xFFFFFFFFFFFFFFFFll,                  0ll, 32, 0x00000000FFFFFFFFll},
   2.100 +    {"_aullshr",  &TST_aullshr,  0xFFFFFFFFFFFFFFFFll,                  0ll, 33, 0x000000007FFFFFFFll},
   2.101 +    {"_aullshr",  &TST_aullshr,  0xFFFFFFFFFFFFFFFFll,                  0ll,  0, 0xFFFFFFFFFFFFFFFFll},
   2.102 +
   2.103 +    {"_allmul",   &TST_allmul,   0xFFFFFFFFFFFFFFFFll, 0x0000000000000000ll,  0, 0x0000000000000000ll},
   2.104 +    {"_allmul",   &TST_allmul,   0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   2.105 +    {"_allmul",   &TST_allmul,   0x000000000FFFFFFFll, 0x0000000000000001ll,  0, 0x000000000FFFFFFFll},
   2.106 +    {"_allmul",   &TST_allmul,   0x0000000000000001ll, 0x000000000FFFFFFFll,  0, 0x000000000FFFFFFFll},
   2.107 +    {"_allmul",   &TST_allmul,   0x000000000FFFFFFFll, 0x0000000000000010ll,  0, 0x00000000FFFFFFF0ll},
   2.108 +    {"_allmul",   &TST_allmul,   0x0000000000000010ll, 0x000000000FFFFFFFll,  0, 0x00000000FFFFFFF0ll},
   2.109 +    {"_allmul",   &TST_allmul,   0x000000000FFFFFFFll, 0x0000000000000100ll,  0, 0x0000000FFFFFFF00ll},
   2.110 +    {"_allmul",   &TST_allmul,   0x0000000000000100ll, 0x000000000FFFFFFFll,  0, 0x0000000FFFFFFF00ll},
   2.111 +    {"_allmul",   &TST_allmul,   0x000000000FFFFFFFll, 0x0000000010000000ll,  0, 0x00FFFFFFF0000000ll},
   2.112 +    {"_allmul",   &TST_allmul,   0x0000000010000000ll, 0x000000000FFFFFFFll,  0, 0x00FFFFFFF0000000ll},
   2.113 +    {"_allmul",   &TST_allmul,   0x000000000FFFFFFFll, 0x0000000080000000ll,  0, 0x07FFFFFF80000000ll},
   2.114 +    {"_allmul",   &TST_allmul,   0x0000000080000000ll, 0x000000000FFFFFFFll,  0, 0x07FFFFFF80000000ll},
   2.115 +    {"_allmul",   &TST_allmul,   0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll,  0, 0xFFFFFFFF00000000ll},
   2.116 +    {"_allmul",   &TST_allmul,   0x0000000080000000ll, 0xFFFFFFFFFFFFFFFEll,  0, 0xFFFFFFFF00000000ll},
   2.117 +    {"_allmul",   &TST_allmul,   0xFFFFFFFFFFFFFFFEll, 0x0000000080000008ll,  0, 0xFFFFFFFEFFFFFFF0ll},
   2.118 +    {"_allmul",   &TST_allmul,   0x0000000080000008ll, 0xFFFFFFFFFFFFFFFEll,  0, 0xFFFFFFFEFFFFFFF0ll},
   2.119 +    {"_allmul",   &TST_allmul,   0x00000000FFFFFFFFll, 0x00000000FFFFFFFFll,  0, 0xFFFFFFFE00000001ll},
   2.120 +
   2.121 +    {"_alldiv",   &TST_alldiv,   0x0000000000000000ll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   2.122 +    {"_alldiv",   &TST_alldiv,   0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   2.123 +    {"_alldiv",   &TST_alldiv,   0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0xFFFFFFFFFFFFFFFFll},
   2.124 +    {"_alldiv",   &TST_alldiv,   0xFFFFFFFFFFFFFFFFll, 0x0000000000000001ll,  0, 0xFFFFFFFFFFFFFFFFll},
   2.125 +    {"_alldiv",   &TST_alldiv,   0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0xFFFFFFFFFFFFFFFFll},
   2.126 +    {"_alldiv",   &TST_alldiv,   0x0000000000000001ll, 0x0000000000000001ll,  0, 0x0000000000000001ll},
   2.127 +    {"_alldiv",   &TST_alldiv,   0xFFFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000001ll},
   2.128 +    {"_alldiv",   &TST_alldiv,   0x000000000FFFFFFFll, 0x0000000000000001ll,  0, 0x000000000FFFFFFFll},
   2.129 +    {"_alldiv",   &TST_alldiv,   0x0000000FFFFFFFFFll, 0x0000000000000010ll,  0, 0x00000000FFFFFFFFll},
   2.130 +    {"_alldiv",   &TST_alldiv,   0x0000000000000100ll, 0x000000000FFFFFFFll,  0, 0x0000000000000000ll},
   2.131 +    {"_alldiv",   &TST_alldiv,   0x00FFFFFFF0000000ll, 0x0000000010000000ll,  0, 0x000000000FFFFFFFll},
   2.132 +    {"_alldiv",   &TST_alldiv,   0x07FFFFFF80000000ll, 0x0000000080000000ll,  0, 0x000000000FFFFFFFll},
   2.133 +    {"_alldiv",   &TST_alldiv,   0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll,  0, 0x0000000000000000ll},
   2.134 +    {"_alldiv",   &TST_alldiv,   0xFFFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0x0000000080000008ll},
   2.135 +    {"_alldiv",   &TST_alldiv,   0x7FFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0xC000000080000008ll},
   2.136 +    {"_alldiv",   &TST_alldiv,   0x7FFFFFFEFFFFFFF0ll, 0x0000FFFFFFFFFFFEll,  0, 0x0000000000007FFFll},
   2.137 +    {"_alldiv",   &TST_alldiv,   0x7FFFFFFEFFFFFFF0ll, 0x7FFFFFFEFFFFFFF0ll,  0, 0x0000000000000001ll},
   2.138 +
   2.139 +    {"_allrem",   &TST_allrem,   0x0000000000000000ll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   2.140 +    {"_allrem",   &TST_allrem,   0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   2.141 +    {"_allrem",   &TST_allrem,   0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   2.142 +    {"_allrem",   &TST_allrem,   0xFFFFFFFFFFFFFFFFll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   2.143 +    {"_allrem",   &TST_allrem,   0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   2.144 +    {"_allrem",   &TST_allrem,   0x0000000000000001ll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   2.145 +    {"_allrem",   &TST_allrem,   0xFFFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   2.146 +    {"_allrem",   &TST_allrem,   0x000000000FFFFFFFll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   2.147 +    {"_allrem",   &TST_allrem,   0x0000000FFFFFFFFFll, 0x0000000000000010ll,  0, 0x000000000000000Fll},
   2.148 +    {"_allrem",   &TST_allrem,   0x0000000000000100ll, 0x000000000FFFFFFFll,  0, 0x0000000000000100ll},
   2.149 +    {"_allrem",   &TST_allrem,   0x00FFFFFFF0000000ll, 0x0000000010000000ll,  0, 0x0000000000000000ll},
   2.150 +    {"_allrem",   &TST_allrem,   0x07FFFFFF80000000ll, 0x0000000080000000ll,  0, 0x0000000000000000ll},
   2.151 +    {"_allrem",   &TST_allrem,   0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll,  0, 0xFFFFFFFFFFFFFFFEll},
   2.152 +    {"_allrem",   &TST_allrem,   0xFFFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0x0000000000000000ll},
   2.153 +    {"_allrem",   &TST_allrem,   0x7FFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0x0000000000000000ll},
   2.154 +    {"_allrem",   &TST_allrem,   0x7FFFFFFEFFFFFFF0ll, 0x0000FFFFFFFFFFFEll,  0, 0x0000FFFF0000FFEEll},
   2.155 +    {"_allrem",   &TST_allrem,   0x7FFFFFFEFFFFFFF0ll, 0x7FFFFFFEFFFFFFF0ll,  0, 0x0000000000000000ll},
   2.156 +
   2.157 +
   2.158 +    {"_ualldiv",  &TST_ualldiv,  0x0000000000000000ll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   2.159 +    {"_ualldiv",  &TST_ualldiv,  0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   2.160 +    {"_ualldiv",  &TST_ualldiv,  0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   2.161 +    {"_ualldiv",  &TST_ualldiv,  0xFFFFFFFFFFFFFFFFll, 0x0000000000000001ll,  0, 0xFFFFFFFFFFFFFFFFll},
   2.162 +    {"_ualldiv",  &TST_ualldiv,  0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   2.163 +    {"_ualldiv",  &TST_ualldiv,  0x0000000000000001ll, 0x0000000000000001ll,  0, 0x0000000000000001ll},
   2.164 +    {"_ualldiv",  &TST_ualldiv,  0xFFFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000001ll},
   2.165 +    {"_ualldiv",  &TST_ualldiv,  0x000000000FFFFFFFll, 0x0000000000000001ll,  0, 0x000000000FFFFFFFll},
   2.166 +    {"_ualldiv",  &TST_ualldiv,  0x0000000FFFFFFFFFll, 0x0000000000000010ll,  0, 0x00000000FFFFFFFFll},
   2.167 +    {"_ualldiv",  &TST_ualldiv,  0x0000000000000100ll, 0x000000000FFFFFFFll,  0, 0x0000000000000000ll},
   2.168 +    {"_ualldiv",  &TST_ualldiv,  0x00FFFFFFF0000000ll, 0x0000000010000000ll,  0, 0x000000000FFFFFFFll},
   2.169 +    {"_ualldiv",  &TST_ualldiv,  0x07FFFFFF80000000ll, 0x0000000080000000ll,  0, 0x000000000FFFFFFFll},
   2.170 +    {"_ualldiv",  &TST_ualldiv,  0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll,  0, 0x00000001FFFFFFFFll},
   2.171 +    {"_ualldiv",  &TST_ualldiv,  0xFFFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0x0000000000000000ll},
   2.172 +    {"_ualldiv",  &TST_ualldiv,  0x7FFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0x0000000000000000ll},
   2.173 +    {"_ualldiv",  &TST_ualldiv,  0x7FFFFFFEFFFFFFF0ll, 0x0000FFFFFFFFFFFEll,  0, 0x0000000000007FFFll},
   2.174 +    {"_ualldiv",  &TST_ualldiv,  0x7FFFFFFEFFFFFFF0ll, 0x7FFFFFFEFFFFFFF0ll,  0, 0x0000000000000001ll},
   2.175 +
   2.176 +    {"_uallrem",  &TST_uallrem,  0x0000000000000000ll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   2.177 +    {"_uallrem",  &TST_uallrem,  0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   2.178 +    {"_uallrem",  &TST_uallrem,  0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000001ll},
   2.179 +    {"_uallrem",  &TST_uallrem,  0xFFFFFFFFFFFFFFFFll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   2.180 +    {"_uallrem",  &TST_uallrem,  0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000001ll},
   2.181 +    {"_uallrem",  &TST_uallrem,  0x0000000000000001ll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   2.182 +    {"_uallrem",  &TST_uallrem,  0xFFFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   2.183 +    {"_uallrem",  &TST_uallrem,  0x000000000FFFFFFFll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   2.184 +    {"_uallrem",  &TST_uallrem,  0x0000000FFFFFFFFFll, 0x0000000000000010ll,  0, 0x000000000000000Fll},
   2.185 +    {"_uallrem",  &TST_uallrem,  0x0000000000000100ll, 0x000000000FFFFFFFll,  0, 0x0000000000000100ll},
   2.186 +    {"_uallrem",  &TST_uallrem,  0x00FFFFFFF0000000ll, 0x0000000010000000ll,  0, 0x0000000000000000ll},
   2.187 +    {"_uallrem",  &TST_uallrem,  0x07FFFFFF80000000ll, 0x0000000080000000ll,  0, 0x0000000000000000ll},
   2.188 +    {"_uallrem",  &TST_uallrem,  0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll,  0, 0x000000007FFFFFFEll},
   2.189 +    {"_uallrem",  &TST_uallrem,  0xFFFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0xFFFFFFFEFFFFFFF0ll},
   2.190 +    {"_uallrem",  &TST_uallrem,  0x7FFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0x7FFFFFFEFFFFFFF0ll},
   2.191 +    {"_uallrem",  &TST_uallrem,  0x7FFFFFFEFFFFFFF0ll, 0x0000FFFFFFFFFFFEll,  0, 0x0000FFFF0000FFEEll},
   2.192 +    {"_uallrem",  &TST_uallrem,  0x7FFFFFFEFFFFFFF0ll, 0x7FFFFFFEFFFFFFF0ll,  0, 0x0000000000000000ll},
   2.193 +
   2.194 +    {NULL}
   2.195 +};
   2.196 +
   2.197 +int
   2.198 +Test64Bit (SDL_bool verbose)
   2.199 +{
   2.200 +    LL_Test *t;
   2.201 +    int failed = 0;
   2.202 +
   2.203 +    for (t = LL_Tests; t->routine != NULL; t++) {
   2.204 +        unsigned long long result = 0;
   2.205 +        unsigned int *al = (unsigned int *)&t->a;
   2.206 +        unsigned int *bl = (unsigned int *)&t->b;
   2.207 +        unsigned int *el = (unsigned int *)&t->expected_result;
   2.208 +        unsigned int *rl = (unsigned int *)&result;
   2.209 +
   2.210 +        if (!t->routine(&t->a, &t->b, t->arg, &result, &t->expected_result)) {
   2.211 +            if (verbose)
   2.212 +                SDL_Log("%s(0x%08X%08X, 0x%08X%08X, %3d, produced: 0x%08X%08X, expected: 0x%08X%08X\n",
   2.213 +                        t->operation, al[1], al[0], bl[1], bl[0], t->arg, rl[1], rl[0], el[1], el[0]);
   2.214 +            ++failed;
   2.215 +        }
   2.216 +    }
   2.217 +    if (verbose && (failed == 0))
   2.218 +        SDL_Log("All 64bit instrinsic tests passed\n");
   2.219 +    return (failed ? 1 : 0);
   2.220 +}
   2.221  
   2.222  int
   2.223  TestCPUInfo(SDL_bool verbose)
   2.224 @@ -198,6 +412,7 @@
   2.225  
   2.226      status += TestTypes(verbose);
   2.227      status += TestEndian(verbose);
   2.228 +    status += Test64Bit(verbose);
   2.229      status += TestCPUInfo(verbose);
   2.230      status += TestAssertions(verbose);
   2.231