test/testplatform.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 06 Nov 2016 10:01:08 -0800
changeset 10587 513f0e80a7dd
parent 10564 46cfe31e501a
child 10588 cc83da0cb986
permissions -rw-r--r--
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.
     1 /*
     2   Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
     3 
     4   This software is provided 'as-is', without any express or implied
     5   warranty.  In no event will the authors be held liable for any damages
     6   arising from the use of this software.
     7 
     8   Permission is granted to anyone to use this software for any purpose,
     9   including commercial applications, and to alter it and redistribute it
    10   freely.
    11 */
    12 
    13 #include <stdio.h>
    14 
    15 #include "SDL.h"
    16 
    17 /*
    18  * Watcom C flags these as Warning 201: "Unreachable code" if you just
    19  *  compare them directly, so we push it through a function to keep the
    20  *  compiler quiet.  --ryan.
    21  */
    22 static int
    23 badsize(size_t sizeoftype, size_t hardcodetype)
    24 {
    25     return sizeoftype != hardcodetype;
    26 }
    27 
    28 int
    29 TestTypes(SDL_bool verbose)
    30 {
    31     int error = 0;
    32 
    33     if (badsize(sizeof(Uint8), 1)) {
    34         if (verbose)
    35             SDL_Log("sizeof(Uint8) != 1, instead = %u\n",
    36                    (unsigned int)sizeof(Uint8));
    37         ++error;
    38     }
    39     if (badsize(sizeof(Uint16), 2)) {
    40         if (verbose)
    41             SDL_Log("sizeof(Uint16) != 2, instead = %u\n",
    42                    (unsigned int)sizeof(Uint16));
    43         ++error;
    44     }
    45     if (badsize(sizeof(Uint32), 4)) {
    46         if (verbose)
    47             SDL_Log("sizeof(Uint32) != 4, instead = %u\n",
    48                    (unsigned int)sizeof(Uint32));
    49         ++error;
    50     }
    51     if (badsize(sizeof(Uint64), 8)) {
    52         if (verbose)
    53             SDL_Log("sizeof(Uint64) != 8, instead = %u\n",
    54                    (unsigned int)sizeof(Uint64));
    55         ++error;
    56     }
    57     if (verbose && !error)
    58         SDL_Log("All data types are the expected size.\n");
    59 
    60     return (error ? 1 : 0);
    61 }
    62 
    63 int
    64 TestEndian(SDL_bool verbose)
    65 {
    66     int error = 0;
    67     Uint16 value = 0x1234;
    68     int real_byteorder;
    69     Uint16 value16 = 0xCDAB;
    70     Uint16 swapped16 = 0xABCD;
    71     Uint32 value32 = 0xEFBEADDE;
    72     Uint32 swapped32 = 0xDEADBEEF;
    73     Uint64 value64, swapped64;
    74 
    75     value64 = 0xEFBEADDE;
    76     value64 <<= 32;
    77     value64 |= 0xCDAB3412;
    78     swapped64 = 0x1234ABCD;
    79     swapped64 <<= 32;
    80     swapped64 |= 0xDEADBEEF;
    81 
    82     if (verbose) {
    83         SDL_Log("Detected a %s endian machine.\n",
    84                (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? "little" : "big");
    85     }
    86     if ((*((char *) &value) >> 4) == 0x1) {
    87         real_byteorder = SDL_BIG_ENDIAN;
    88     } else {
    89         real_byteorder = SDL_LIL_ENDIAN;
    90     }
    91     if (real_byteorder != SDL_BYTEORDER) {
    92         if (verbose) {
    93             SDL_Log("Actually a %s endian machine!\n",
    94                    (real_byteorder == SDL_LIL_ENDIAN) ? "little" : "big");
    95         }
    96         ++error;
    97     }
    98     if (verbose) {
    99         SDL_Log("Value 16 = 0x%X, swapped = 0x%X\n", value16,
   100                SDL_Swap16(value16));
   101     }
   102     if (SDL_Swap16(value16) != swapped16) {
   103         if (verbose) {
   104             SDL_Log("16 bit value swapped incorrectly!\n");
   105         }
   106         ++error;
   107     }
   108     if (verbose) {
   109         SDL_Log("Value 32 = 0x%X, swapped = 0x%X\n", value32,
   110                SDL_Swap32(value32));
   111     }
   112     if (SDL_Swap32(value32) != swapped32) {
   113         if (verbose) {
   114             SDL_Log("32 bit value swapped incorrectly!\n");
   115         }
   116         ++error;
   117     }
   118     if (verbose) {
   119         SDL_Log("Value 64 = 0x%"SDL_PRIX64", swapped = 0x%"SDL_PRIX64"\n", value64,
   120                SDL_Swap64(value64));
   121     }
   122     if (SDL_Swap64(value64) != swapped64) {
   123         if (verbose) {
   124             SDL_Log("64 bit value swapped incorrectly!\n");
   125         }
   126         ++error;
   127     }
   128     return (error ? 1 : 0);
   129 }
   130 
   131 static int TST_allmul (void *a, void *b, int arg, void *result, void *expected)
   132 {
   133     (*(long long *)result) = ((*(long long *)a) * (*(long long *)b));
   134     return (*(long long *)result) == (*(long long *)expected);
   135 }
   136 
   137 static int TST_alldiv (void *a, void *b, int arg, void *result, void *expected)
   138 {
   139     (*(long long *)result) = ((*(long long *)a) / (*(long long *)b));
   140     return (*(long long *)result) == (*(long long *)expected);
   141 }
   142 
   143 static int TST_allrem (void *a, void *b, int arg, void *result, void *expected)
   144 {
   145     (*(long long *)result) = ((*(long long *)a) % (*(long long *)b));
   146     return (*(long long *)result) == (*(long long *)expected);
   147 }
   148 
   149 static int TST_ualldiv (void *a, void *b, int arg, void *result, void *expected)
   150 {
   151     (*(unsigned long long *)result) = ((*(unsigned long long *)a) / (*(unsigned long long *)b));
   152     return (*(unsigned long long *)result) == (*(unsigned long long *)expected);
   153 }
   154 
   155 static int TST_uallrem (void *a, void *b, int arg, void *result, void *expected)
   156 {
   157     (*(unsigned long long *)result) = ((*(unsigned long long *)a) % (*(unsigned long long *)b));
   158     return (*(unsigned long long *)result) == (*(unsigned long long *)expected);
   159 }
   160 
   161 static int TST_allshl (void *a, void *b, int arg, void *result, void *expected)
   162 {
   163     (*(long long *)result) = (*(long long *)a) << arg;
   164     return (*(long long *)result) == (*(long long *)expected);
   165 }
   166 
   167 static int TST_aullshl (void *a, void *b, int arg, void *result, void *expected)
   168 {
   169     (*(unsigned long long *)result) = (*(unsigned long long *)a) << arg;
   170     return (*(unsigned long long *)result) == (*(unsigned long long *)expected);
   171 }
   172 
   173 static int TST_allshr (void *a, void *b, int arg, void *result, void *expected)
   174 {
   175     (*(long long *)result) = (*(long long *)a) >> arg;
   176     return (*(long long *)result) == (*(long long *)expected);
   177 }
   178 
   179 static int TST_aullshr (void *a, void *b, int arg, void *result, void *expected)
   180 {
   181     (*(unsigned long long *)result) = (*(unsigned long long *)a) >> arg;
   182     return (*(unsigned long long *)result) == (*(unsigned long long *)expected);
   183 }
   184 
   185 
   186 typedef int (*LL_Intrinsic)(void *a, void *b, int arg, void *result, void *expected);
   187 
   188 typedef struct {
   189     const char *operation;
   190     LL_Intrinsic routine;
   191     unsigned long long a, b;
   192     int arg;
   193     unsigned long long expected_result;
   194 } LL_Test;
   195 
   196 static LL_Test LL_Tests[] = 
   197 {
   198     {"_allshl",   &TST_allshl,   0xFFFFFFFFFFFFFFFFll,                  0ll, 65, 0x0000000000000000ll},
   199     {"_allshl",   &TST_allshl,   0xFFFFFFFFFFFFFFFFll,                  0ll,  1, 0xFFFFFFFFFFFFFFFEll},
   200     {"_allshl",   &TST_allshl,   0xFFFFFFFFFFFFFFFFll,                  0ll, 32, 0xFFFFFFFF00000000ll},
   201     {"_allshl",   &TST_allshl,   0xFFFFFFFFFFFFFFFFll,                  0ll, 33, 0xFFFFFFFE00000000ll},
   202     {"_allshl",   &TST_allshl,   0xFFFFFFFFFFFFFFFFll,                  0ll,  0, 0xFFFFFFFFFFFFFFFFll},
   203 
   204     {"_allshr",   &TST_allshr,   0xAAAAAAAA55555555ll,                  0ll, 63, 0xFFFFFFFFFFFFFFFFll},
   205     {"_allshr",   &TST_allshr,   0xFFFFFFFFFFFFFFFFll,                  0ll, 65, 0xFFFFFFFFFFFFFFFFll},
   206     {"_allshr",   &TST_allshr,   0xFFFFFFFFFFFFFFFFll,                  0ll,  1, 0xFFFFFFFFFFFFFFFFll},
   207     {"_allshr",   &TST_allshr,   0xFFFFFFFFFFFFFFFFll,                  0ll, 32, 0xFFFFFFFFFFFFFFFFll},
   208     {"_allshr",   &TST_allshr,   0xFFFFFFFFFFFFFFFFll,                  0ll, 33, 0xFFFFFFFFFFFFFFFFll},
   209     {"_allshr",   &TST_allshr,   0xFFFFFFFFFFFFFFFFll,                  0ll,  0, 0xFFFFFFFFFFFFFFFFll},
   210     {"_allshr",   &TST_allshr,   0x5F5F5F5F5F5F5F5Fll,                  0ll, 65, 0x0000000000000000ll},
   211     {"_allshr",   &TST_allshr,   0x5F5F5F5F5F5F5F5Fll,                  0ll,  1, 0x2FAFAFAFAFAFAFAFll},
   212     {"_allshr",   &TST_allshr,   0x5F5F5F5F5F5F5F5Fll,                  0ll, 32, 0x000000005F5F5F5Fll},
   213     {"_allshr",   &TST_allshr,   0x5F5F5F5F5F5F5F5Fll,                  0ll, 33, 0x000000002FAFAFAFll},
   214 
   215     {"_aullshl",  &TST_aullshl,  0xFFFFFFFFFFFFFFFFll,                  0ll, 65, 0x0000000000000000ll},
   216     {"_aullshl",  &TST_aullshl,  0xFFFFFFFFFFFFFFFFll,                  0ll,  1, 0xFFFFFFFFFFFFFFFEll},
   217     {"_aullshl",  &TST_aullshl,  0xFFFFFFFFFFFFFFFFll,                  0ll, 32, 0xFFFFFFFF00000000ll},
   218     {"_aullshl",  &TST_aullshl,  0xFFFFFFFFFFFFFFFFll,                  0ll, 33, 0xFFFFFFFE00000000ll},
   219     {"_aullshl",  &TST_aullshl,  0xFFFFFFFFFFFFFFFFll,                  0ll,  0, 0xFFFFFFFFFFFFFFFFll},
   220 
   221     {"_aullshr",  &TST_aullshr,  0xFFFFFFFFFFFFFFFFll,                  0ll, 65, 0x0000000000000000ll},
   222     {"_aullshr",  &TST_aullshr,  0xFFFFFFFFFFFFFFFFll,                  0ll,  1, 0x7FFFFFFFFFFFFFFFll},
   223     {"_aullshr",  &TST_aullshr,  0xFFFFFFFFFFFFFFFFll,                  0ll, 32, 0x00000000FFFFFFFFll},
   224     {"_aullshr",  &TST_aullshr,  0xFFFFFFFFFFFFFFFFll,                  0ll, 33, 0x000000007FFFFFFFll},
   225     {"_aullshr",  &TST_aullshr,  0xFFFFFFFFFFFFFFFFll,                  0ll,  0, 0xFFFFFFFFFFFFFFFFll},
   226 
   227     {"_allmul",   &TST_allmul,   0xFFFFFFFFFFFFFFFFll, 0x0000000000000000ll,  0, 0x0000000000000000ll},
   228     {"_allmul",   &TST_allmul,   0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   229     {"_allmul",   &TST_allmul,   0x000000000FFFFFFFll, 0x0000000000000001ll,  0, 0x000000000FFFFFFFll},
   230     {"_allmul",   &TST_allmul,   0x0000000000000001ll, 0x000000000FFFFFFFll,  0, 0x000000000FFFFFFFll},
   231     {"_allmul",   &TST_allmul,   0x000000000FFFFFFFll, 0x0000000000000010ll,  0, 0x00000000FFFFFFF0ll},
   232     {"_allmul",   &TST_allmul,   0x0000000000000010ll, 0x000000000FFFFFFFll,  0, 0x00000000FFFFFFF0ll},
   233     {"_allmul",   &TST_allmul,   0x000000000FFFFFFFll, 0x0000000000000100ll,  0, 0x0000000FFFFFFF00ll},
   234     {"_allmul",   &TST_allmul,   0x0000000000000100ll, 0x000000000FFFFFFFll,  0, 0x0000000FFFFFFF00ll},
   235     {"_allmul",   &TST_allmul,   0x000000000FFFFFFFll, 0x0000000010000000ll,  0, 0x00FFFFFFF0000000ll},
   236     {"_allmul",   &TST_allmul,   0x0000000010000000ll, 0x000000000FFFFFFFll,  0, 0x00FFFFFFF0000000ll},
   237     {"_allmul",   &TST_allmul,   0x000000000FFFFFFFll, 0x0000000080000000ll,  0, 0x07FFFFFF80000000ll},
   238     {"_allmul",   &TST_allmul,   0x0000000080000000ll, 0x000000000FFFFFFFll,  0, 0x07FFFFFF80000000ll},
   239     {"_allmul",   &TST_allmul,   0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll,  0, 0xFFFFFFFF00000000ll},
   240     {"_allmul",   &TST_allmul,   0x0000000080000000ll, 0xFFFFFFFFFFFFFFFEll,  0, 0xFFFFFFFF00000000ll},
   241     {"_allmul",   &TST_allmul,   0xFFFFFFFFFFFFFFFEll, 0x0000000080000008ll,  0, 0xFFFFFFFEFFFFFFF0ll},
   242     {"_allmul",   &TST_allmul,   0x0000000080000008ll, 0xFFFFFFFFFFFFFFFEll,  0, 0xFFFFFFFEFFFFFFF0ll},
   243     {"_allmul",   &TST_allmul,   0x00000000FFFFFFFFll, 0x00000000FFFFFFFFll,  0, 0xFFFFFFFE00000001ll},
   244 
   245     {"_alldiv",   &TST_alldiv,   0x0000000000000000ll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   246     {"_alldiv",   &TST_alldiv,   0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   247     {"_alldiv",   &TST_alldiv,   0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0xFFFFFFFFFFFFFFFFll},
   248     {"_alldiv",   &TST_alldiv,   0xFFFFFFFFFFFFFFFFll, 0x0000000000000001ll,  0, 0xFFFFFFFFFFFFFFFFll},
   249     {"_alldiv",   &TST_alldiv,   0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0xFFFFFFFFFFFFFFFFll},
   250     {"_alldiv",   &TST_alldiv,   0x0000000000000001ll, 0x0000000000000001ll,  0, 0x0000000000000001ll},
   251     {"_alldiv",   &TST_alldiv,   0xFFFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000001ll},
   252     {"_alldiv",   &TST_alldiv,   0x000000000FFFFFFFll, 0x0000000000000001ll,  0, 0x000000000FFFFFFFll},
   253     {"_alldiv",   &TST_alldiv,   0x0000000FFFFFFFFFll, 0x0000000000000010ll,  0, 0x00000000FFFFFFFFll},
   254     {"_alldiv",   &TST_alldiv,   0x0000000000000100ll, 0x000000000FFFFFFFll,  0, 0x0000000000000000ll},
   255     {"_alldiv",   &TST_alldiv,   0x00FFFFFFF0000000ll, 0x0000000010000000ll,  0, 0x000000000FFFFFFFll},
   256     {"_alldiv",   &TST_alldiv,   0x07FFFFFF80000000ll, 0x0000000080000000ll,  0, 0x000000000FFFFFFFll},
   257     {"_alldiv",   &TST_alldiv,   0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll,  0, 0x0000000000000000ll},
   258     {"_alldiv",   &TST_alldiv,   0xFFFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0x0000000080000008ll},
   259     {"_alldiv",   &TST_alldiv,   0x7FFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0xC000000080000008ll},
   260     {"_alldiv",   &TST_alldiv,   0x7FFFFFFEFFFFFFF0ll, 0x0000FFFFFFFFFFFEll,  0, 0x0000000000007FFFll},
   261     {"_alldiv",   &TST_alldiv,   0x7FFFFFFEFFFFFFF0ll, 0x7FFFFFFEFFFFFFF0ll,  0, 0x0000000000000001ll},
   262 
   263     {"_allrem",   &TST_allrem,   0x0000000000000000ll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   264     {"_allrem",   &TST_allrem,   0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   265     {"_allrem",   &TST_allrem,   0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   266     {"_allrem",   &TST_allrem,   0xFFFFFFFFFFFFFFFFll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   267     {"_allrem",   &TST_allrem,   0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   268     {"_allrem",   &TST_allrem,   0x0000000000000001ll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   269     {"_allrem",   &TST_allrem,   0xFFFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   270     {"_allrem",   &TST_allrem,   0x000000000FFFFFFFll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   271     {"_allrem",   &TST_allrem,   0x0000000FFFFFFFFFll, 0x0000000000000010ll,  0, 0x000000000000000Fll},
   272     {"_allrem",   &TST_allrem,   0x0000000000000100ll, 0x000000000FFFFFFFll,  0, 0x0000000000000100ll},
   273     {"_allrem",   &TST_allrem,   0x00FFFFFFF0000000ll, 0x0000000010000000ll,  0, 0x0000000000000000ll},
   274     {"_allrem",   &TST_allrem,   0x07FFFFFF80000000ll, 0x0000000080000000ll,  0, 0x0000000000000000ll},
   275     {"_allrem",   &TST_allrem,   0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll,  0, 0xFFFFFFFFFFFFFFFEll},
   276     {"_allrem",   &TST_allrem,   0xFFFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0x0000000000000000ll},
   277     {"_allrem",   &TST_allrem,   0x7FFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0x0000000000000000ll},
   278     {"_allrem",   &TST_allrem,   0x7FFFFFFEFFFFFFF0ll, 0x0000FFFFFFFFFFFEll,  0, 0x0000FFFF0000FFEEll},
   279     {"_allrem",   &TST_allrem,   0x7FFFFFFEFFFFFFF0ll, 0x7FFFFFFEFFFFFFF0ll,  0, 0x0000000000000000ll},
   280 
   281 
   282     {"_ualldiv",  &TST_ualldiv,  0x0000000000000000ll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   283     {"_ualldiv",  &TST_ualldiv,  0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   284     {"_ualldiv",  &TST_ualldiv,  0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   285     {"_ualldiv",  &TST_ualldiv,  0xFFFFFFFFFFFFFFFFll, 0x0000000000000001ll,  0, 0xFFFFFFFFFFFFFFFFll},
   286     {"_ualldiv",  &TST_ualldiv,  0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   287     {"_ualldiv",  &TST_ualldiv,  0x0000000000000001ll, 0x0000000000000001ll,  0, 0x0000000000000001ll},
   288     {"_ualldiv",  &TST_ualldiv,  0xFFFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000001ll},
   289     {"_ualldiv",  &TST_ualldiv,  0x000000000FFFFFFFll, 0x0000000000000001ll,  0, 0x000000000FFFFFFFll},
   290     {"_ualldiv",  &TST_ualldiv,  0x0000000FFFFFFFFFll, 0x0000000000000010ll,  0, 0x00000000FFFFFFFFll},
   291     {"_ualldiv",  &TST_ualldiv,  0x0000000000000100ll, 0x000000000FFFFFFFll,  0, 0x0000000000000000ll},
   292     {"_ualldiv",  &TST_ualldiv,  0x00FFFFFFF0000000ll, 0x0000000010000000ll,  0, 0x000000000FFFFFFFll},
   293     {"_ualldiv",  &TST_ualldiv,  0x07FFFFFF80000000ll, 0x0000000080000000ll,  0, 0x000000000FFFFFFFll},
   294     {"_ualldiv",  &TST_ualldiv,  0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll,  0, 0x00000001FFFFFFFFll},
   295     {"_ualldiv",  &TST_ualldiv,  0xFFFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0x0000000000000000ll},
   296     {"_ualldiv",  &TST_ualldiv,  0x7FFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0x0000000000000000ll},
   297     {"_ualldiv",  &TST_ualldiv,  0x7FFFFFFEFFFFFFF0ll, 0x0000FFFFFFFFFFFEll,  0, 0x0000000000007FFFll},
   298     {"_ualldiv",  &TST_ualldiv,  0x7FFFFFFEFFFFFFF0ll, 0x7FFFFFFEFFFFFFF0ll,  0, 0x0000000000000001ll},
   299 
   300     {"_uallrem",  &TST_uallrem,  0x0000000000000000ll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   301     {"_uallrem",  &TST_uallrem,  0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   302     {"_uallrem",  &TST_uallrem,  0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000001ll},
   303     {"_uallrem",  &TST_uallrem,  0xFFFFFFFFFFFFFFFFll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   304     {"_uallrem",  &TST_uallrem,  0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000001ll},
   305     {"_uallrem",  &TST_uallrem,  0x0000000000000001ll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   306     {"_uallrem",  &TST_uallrem,  0xFFFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll,  0, 0x0000000000000000ll},
   307     {"_uallrem",  &TST_uallrem,  0x000000000FFFFFFFll, 0x0000000000000001ll,  0, 0x0000000000000000ll},
   308     {"_uallrem",  &TST_uallrem,  0x0000000FFFFFFFFFll, 0x0000000000000010ll,  0, 0x000000000000000Fll},
   309     {"_uallrem",  &TST_uallrem,  0x0000000000000100ll, 0x000000000FFFFFFFll,  0, 0x0000000000000100ll},
   310     {"_uallrem",  &TST_uallrem,  0x00FFFFFFF0000000ll, 0x0000000010000000ll,  0, 0x0000000000000000ll},
   311     {"_uallrem",  &TST_uallrem,  0x07FFFFFF80000000ll, 0x0000000080000000ll,  0, 0x0000000000000000ll},
   312     {"_uallrem",  &TST_uallrem,  0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll,  0, 0x000000007FFFFFFEll},
   313     {"_uallrem",  &TST_uallrem,  0xFFFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0xFFFFFFFEFFFFFFF0ll},
   314     {"_uallrem",  &TST_uallrem,  0x7FFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll,  0, 0x7FFFFFFEFFFFFFF0ll},
   315     {"_uallrem",  &TST_uallrem,  0x7FFFFFFEFFFFFFF0ll, 0x0000FFFFFFFFFFFEll,  0, 0x0000FFFF0000FFEEll},
   316     {"_uallrem",  &TST_uallrem,  0x7FFFFFFEFFFFFFF0ll, 0x7FFFFFFEFFFFFFF0ll,  0, 0x0000000000000000ll},
   317 
   318     {NULL}
   319 };
   320 
   321 int
   322 Test64Bit (SDL_bool verbose)
   323 {
   324     LL_Test *t;
   325     int failed = 0;
   326 
   327     for (t = LL_Tests; t->routine != NULL; t++) {
   328         unsigned long long result = 0;
   329         unsigned int *al = (unsigned int *)&t->a;
   330         unsigned int *bl = (unsigned int *)&t->b;
   331         unsigned int *el = (unsigned int *)&t->expected_result;
   332         unsigned int *rl = (unsigned int *)&result;
   333 
   334         if (!t->routine(&t->a, &t->b, t->arg, &result, &t->expected_result)) {
   335             if (verbose)
   336                 SDL_Log("%s(0x%08X%08X, 0x%08X%08X, %3d, produced: 0x%08X%08X, expected: 0x%08X%08X\n",
   337                         t->operation, al[1], al[0], bl[1], bl[0], t->arg, rl[1], rl[0], el[1], el[0]);
   338             ++failed;
   339         }
   340     }
   341     if (verbose && (failed == 0))
   342         SDL_Log("All 64bit instrinsic tests passed\n");
   343     return (failed ? 1 : 0);
   344 }
   345 
   346 int
   347 TestCPUInfo(SDL_bool verbose)
   348 {
   349     if (verbose) {
   350         SDL_Log("CPU count: %d\n", SDL_GetCPUCount());
   351         SDL_Log("CPU cache line size: %d\n", SDL_GetCPUCacheLineSize());
   352         SDL_Log("RDTSC %s\n", SDL_HasRDTSC()? "detected" : "not detected");
   353         SDL_Log("AltiVec %s\n", SDL_HasAltiVec()? "detected" : "not detected");
   354         SDL_Log("MMX %s\n", SDL_HasMMX()? "detected" : "not detected");
   355         SDL_Log("3DNow! %s\n", SDL_Has3DNow()? "detected" : "not detected");
   356         SDL_Log("SSE %s\n", SDL_HasSSE()? "detected" : "not detected");
   357         SDL_Log("SSE2 %s\n", SDL_HasSSE2()? "detected" : "not detected");
   358         SDL_Log("SSE3 %s\n", SDL_HasSSE3()? "detected" : "not detected");
   359         SDL_Log("SSE4.1 %s\n", SDL_HasSSE41()? "detected" : "not detected");
   360         SDL_Log("SSE4.2 %s\n", SDL_HasSSE42()? "detected" : "not detected");
   361         SDL_Log("AVX %s\n", SDL_HasAVX()? "detected" : "not detected");
   362         SDL_Log("AVX2 %s\n", SDL_HasAVX2()? "detected" : "not detected");
   363         SDL_Log("System RAM %d MB\n", SDL_GetSystemRAM());
   364     }
   365     return (0);
   366 }
   367 
   368 int
   369 TestAssertions(SDL_bool verbose)
   370 {
   371     SDL_assert(1);
   372     SDL_assert_release(1);
   373     SDL_assert_paranoid(1);
   374     SDL_assert(0 || 1);
   375     SDL_assert_release(0 || 1);
   376     SDL_assert_paranoid(0 || 1);
   377 
   378 #if 0   /* enable this to test assertion failures. */
   379     SDL_assert_release(1 == 2);
   380     SDL_assert_release(5 < 4);
   381     SDL_assert_release(0 && "This is a test");
   382 #endif
   383 
   384     {
   385         const SDL_AssertData *item = SDL_GetAssertionReport();
   386         while (item) {
   387             SDL_Log("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\n",
   388                 item->condition, item->function, item->filename,
   389                 item->linenum, item->trigger_count,
   390                 item->always_ignore ? "yes" : "no");
   391             item = item->next;
   392         }
   393     }
   394     return (0);
   395 }
   396 
   397 int
   398 main(int argc, char *argv[])
   399 {
   400     SDL_bool verbose = SDL_TRUE;
   401     int status = 0;
   402 
   403     /* Enable standard application logging */
   404     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
   405 
   406     if (argv[1] && (SDL_strcmp(argv[1], "-q") == 0)) {
   407         verbose = SDL_FALSE;
   408     }
   409     if (verbose) {
   410         SDL_Log("This system is running %s\n", SDL_GetPlatform());
   411     }
   412 
   413     status += TestTypes(verbose);
   414     status += TestEndian(verbose);
   415     status += Test64Bit(verbose);
   416     status += TestCPUInfo(verbose);
   417     status += TestAssertions(verbose);
   418 
   419     return status;
   420 }