xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

validate.c (43112B)


      1 /****************************************************************************
      2 *
      3 *						Realmode X86 Emulator Library
      4 *
      5 *            	Copyright (C) 1996-1999 SciTech Software, Inc.
      6 * 				     Copyright (C) David Mosberger-Tang
      7 * 					   Copyright (C) 1999 Egbert Eich
      8 *
      9 *  ========================================================================
     10 *
     11 *  Permission to use, copy, modify, distribute, and sell this software and
     12 *  its documentation for any purpose is hereby granted without fee,
     13 *  provided that the above copyright notice appear in all copies and that
     14 *  both that copyright notice and this permission notice appear in
     15 *  supporting documentation, and that the name of the authors not be used
     16 *  in advertising or publicity pertaining to distribution of the software
     17 *  without specific, written prior permission.  The authors makes no
     18 *  representations about the suitability of this software for any purpose.
     19 *  It is provided "as is" without express or implied warranty.
     20 *
     21 *  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     22 *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     23 *  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     24 *  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
     25 *  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
     26 *  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     27 *  PERFORMANCE OF THIS SOFTWARE.
     28 *
     29 *  ========================================================================
     30 *
     31 * Language:     Watcom C 10.6 or later
     32 * Environment:  32-bit DOS
     33 * Developer:    Kendall Bennett
     34 *
     35 * Description:  Program to validate the x86 emulator library for
     36 *               correctness. We run the emulator primitive operations
     37 *               functions against the real x86 CPU, and compare the result
     38 *               and flags to ensure correctness.
     39 *
     40 *               We use inline assembler to compile and build this program.
     41 *
     42 ****************************************************************************/
     43 
     44 #include <stdio.h>
     45 #include <stdlib.h>
     46 #include <string.h>
     47 #include <stdarg.h>
     48 #include "x86emu.h"
     49 #include "x86emu/prim_asm.h"
     50 
     51 /*-------------------------- Implementation -------------------------------*/
     52 
     53 #define true 1
     54 #define false 0
     55 
     56 #define ALL_FLAGS   (F_CF | F_PF | F_AF | F_ZF | F_SF | F_OF)
     57 
     58 #define VAL_START_BINARY(parm_type,res_type,dmax,smax,dincr,sincr)  \
     59 {                                                                   \
     60     parm_type   d,s;                                                \
     61     res_type    r,r_asm;                                            \
     62 	ulong     	flags,inflags;                                      \
     63 	int         f,failed = false;                                   \
     64     char        buf1[80],buf2[80];                                  \
     65     for (d = 0; d < dmax; d += dincr) {                             \
     66         for (s = 0; s < smax; s += sincr) {                         \
     67             M.x86.R_EFLG = inflags = flags = def_flags;             \
     68             for (f = 0; f < 2; f++) {
     69 
     70 #define VAL_TEST_BINARY(name)                                           \
     71                 r_asm = name##_asm(&flags,d,s);                         \
     72                 r = name(d,s);                                  \
     73                 if (r != r_asm || M.x86.R_EFLG != flags)                \
     74                     failed = true;                                      \
     75                 if (failed || trace) {
     76 
     77 #define VAL_TEST_BINARY_VOID(name)                                      \
     78                 name##_asm(&flags,d,s);                                 \
     79                 name(d,s);                                      \
     80                 r = r_asm = 0;                                          \
     81                 if (M.x86.R_EFLG != flags)                              \
     82                     failed = true;                                      \
     83                 if (failed || trace) {
     84 
     85 #define VAL_FAIL_BYTE_BYTE_BINARY(name)                                                                 \
     86                     if (failed)                                                                         \
     87                         printk("fail\n");                                                               \
     88                     printk("0x%02X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n",                         \
     89                         r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));     \
     90                     printk("0x%02X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n",                         \
     91                         r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));
     92 
     93 #define VAL_FAIL_WORD_WORD_BINARY(name)                                                                 \
     94                     if (failed)                                                                         \
     95                         printk("fail\n");                                                               \
     96                     printk("0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n",                         \
     97                         r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));   \
     98                     printk("0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n",                         \
     99                         r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));
    100 
    101 #define VAL_FAIL_LONG_LONG_BINARY(name)                                                                 \
    102                     if (failed)                                                                         \
    103                         printk("fail\n");                                                               \
    104                     printk("0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n",                         \
    105                         r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
    106                     printk("0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n",                         \
    107                         r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));
    108 
    109 #define VAL_END_BINARY()                                                    \
    110                     }                                                       \
    111                 M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
    112                 if (failed)                                                 \
    113                     break;                                                  \
    114                 }                                                           \
    115             if (failed)                                                     \
    116                 break;                                                      \
    117             }                                                               \
    118         if (failed)                                                         \
    119             break;                                                          \
    120         }                                                                   \
    121     if (!failed)                                                            \
    122         printk("passed\n");                                                 \
    123 }
    124 
    125 #define VAL_BYTE_BYTE_BINARY(name)          \
    126     printk("Validating %s ... ", #name);    \
    127     VAL_START_BINARY(u8,u8,0xFF,0xFF,1,1)   \
    128     VAL_TEST_BINARY(name)                   \
    129     VAL_FAIL_BYTE_BYTE_BINARY(name)         \
    130     VAL_END_BINARY()
    131 
    132 #define VAL_WORD_WORD_BINARY(name)                      \
    133     printk("Validating %s ... ", #name);                \
    134     VAL_START_BINARY(u16,u16,0xFF00,0xFF00,0x100,0x100) \
    135     VAL_TEST_BINARY(name)                               \
    136     VAL_FAIL_WORD_WORD_BINARY(name)                     \
    137     VAL_END_BINARY()
    138 
    139 #define VAL_LONG_LONG_BINARY(name)                                      \
    140     printk("Validating %s ... ", #name);                                \
    141     VAL_START_BINARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000) \
    142     VAL_TEST_BINARY(name)                                               \
    143     VAL_FAIL_LONG_LONG_BINARY(name)                                     \
    144     VAL_END_BINARY()
    145 
    146 #define VAL_VOID_BYTE_BINARY(name)          \
    147     printk("Validating %s ... ", #name);    \
    148     VAL_START_BINARY(u8,u8,0xFF,0xFF,1,1)   \
    149     VAL_TEST_BINARY_VOID(name)              \
    150     VAL_FAIL_BYTE_BYTE_BINARY(name)         \
    151     VAL_END_BINARY()
    152 
    153 #define VAL_VOID_WORD_BINARY(name)                      \
    154     printk("Validating %s ... ", #name);                \
    155     VAL_START_BINARY(u16,u16,0xFF00,0xFF00,0x100,0x100) \
    156     VAL_TEST_BINARY_VOID(name)                          \
    157     VAL_FAIL_WORD_WORD_BINARY(name)                     \
    158     VAL_END_BINARY()
    159 
    160 #define VAL_VOID_LONG_BINARY(name)                                      \
    161     printk("Validating %s ... ", #name);                                \
    162     VAL_START_BINARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000) \
    163     VAL_TEST_BINARY_VOID(name)                                          \
    164     VAL_FAIL_LONG_LONG_BINARY(name)                                     \
    165     VAL_END_BINARY()
    166 
    167 #define VAL_BYTE_ROTATE(name)               \
    168     printk("Validating %s ... ", #name);    \
    169     VAL_START_BINARY(u8,u8,0xFF,8,1,1)      \
    170     VAL_TEST_BINARY(name)                   \
    171     VAL_FAIL_BYTE_BYTE_BINARY(name)         \
    172     VAL_END_BINARY()
    173 
    174 #define VAL_WORD_ROTATE(name)                           \
    175     printk("Validating %s ... ", #name);                \
    176     VAL_START_BINARY(u16,u16,0xFF00,16,0x100,1)         \
    177     VAL_TEST_BINARY(name)                               \
    178     VAL_FAIL_WORD_WORD_BINARY(name)                     \
    179     VAL_END_BINARY()
    180 
    181 #define VAL_LONG_ROTATE(name)                                           \
    182     printk("Validating %s ... ", #name);                                \
    183     VAL_START_BINARY(u32,u32,0xFF000000,32,0x1000000,1)                 \
    184     VAL_TEST_BINARY(name)                                               \
    185     VAL_FAIL_LONG_LONG_BINARY(name)                                     \
    186     VAL_END_BINARY()
    187 
    188 #define VAL_START_TERNARY(parm_type,res_type,dmax,smax,dincr,sincr,maxshift)\
    189 {                                                                   \
    190     parm_type   d,s;                                                \
    191     res_type    r,r_asm;                                            \
    192     u8          shift;                                              \
    193 	u32         flags,inflags;                                      \
    194     int         f,failed = false;                                   \
    195     char        buf1[80],buf2[80];                                  \
    196     for (d = 0; d < dmax; d += dincr) {                             \
    197         for (s = 0; s < smax; s += sincr) {                         \
    198             for (shift = 0; shift < maxshift; shift += 1) {        \
    199                 M.x86.R_EFLG = inflags = flags = def_flags;         \
    200                 for (f = 0; f < 2; f++) {
    201 
    202 #define VAL_TEST_TERNARY(name)                                          \
    203                     r_asm = name##_asm(&flags,d,s,shift);               \
    204                     r = name(d,s,shift);                           \
    205                     if (r != r_asm || M.x86.R_EFLG != flags)            \
    206                         failed = true;                                  \
    207                     if (failed || trace) {
    208 
    209 #define VAL_FAIL_WORD_WORD_TERNARY(name)                                                                \
    210                         if (failed)                                                                         \
    211                             printk("fail\n");                                                               \
    212                         printk("0x%04X = %-15s(0x%04X,0x%04X,%d), flags = %s -> %s\n",                      \
    213                             r, #name, d, s, shift, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));   \
    214                         printk("0x%04X = %-15s(0x%04X,0x%04X,%d), flags = %s -> %s\n",                      \
    215                             r_asm, #name"_asm", d, s, shift, print_flags(buf1,inflags), print_flags(buf2,flags));
    216 
    217 #define VAL_FAIL_LONG_LONG_TERNARY(name)                                                                \
    218                         if (failed)                                                                         \
    219                             printk("fail\n");                                                               \
    220                         printk("0x%08X = %-15s(0x%08X,0x%08X,%d), flags = %s -> %s\n",                      \
    221                             r, #name, d, s, shift, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));  \
    222                         printk("0x%08X = %-15s(0x%08X,0x%08X,%d), flags = %s -> %s\n",                      \
    223                             r_asm, #name"_asm", d, s, shift, print_flags(buf1,inflags), print_flags(buf2,flags));
    224 
    225 #define VAL_END_TERNARY()                                                   \
    226                         }                                                       \
    227                     M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
    228                     if (failed)                                                 \
    229                         break;                                                  \
    230                     }                                                           \
    231                 if (failed)                                                     \
    232                     break;                                                      \
    233                 }                                                               \
    234             if (failed)                                                     \
    235                 break;                                                      \
    236             }                                                               \
    237         if (failed)                                                         \
    238             break;                                                          \
    239         }                                                                   \
    240     if (!failed)                                                            \
    241         printk("passed\n");                                                 \
    242 }
    243 
    244 #define VAL_WORD_ROTATE_DBL(name)                           \
    245     printk("Validating %s ... ", #name);                    \
    246     VAL_START_TERNARY(u16,u16,0xFF00,0xFF00,0x100,0x100,16) \
    247     VAL_TEST_TERNARY(name)                                  \
    248     VAL_FAIL_WORD_WORD_TERNARY(name)                        \
    249     VAL_END_TERNARY()
    250 
    251 #define VAL_LONG_ROTATE_DBL(name)                                           \
    252     printk("Validating %s ... ", #name);                                    \
    253     VAL_START_TERNARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000,32) \
    254     VAL_TEST_TERNARY(name)                                                  \
    255     VAL_FAIL_LONG_LONG_TERNARY(name)                                        \
    256     VAL_END_TERNARY()
    257 
    258 #define VAL_START_UNARY(parm_type,max,incr)                 \
    259 {                                                           \
    260     parm_type   d,r,r_asm;                                  \
    261 	u32         flags,inflags;                              \
    262     int         f,failed = false;                           \
    263     char        buf1[80],buf2[80];                          \
    264     for (d = 0; d < max; d += incr) {                       \
    265         M.x86.R_EFLG = inflags = flags = def_flags;         \
    266         for (f = 0; f < 2; f++) {
    267 
    268 #define VAL_TEST_UNARY(name)                                \
    269             r_asm = name##_asm(&flags,d);                   \
    270             r = name(d);                                \
    271             if (r != r_asm || M.x86.R_EFLG != flags) {      \
    272                 failed = true;
    273 
    274 #define VAL_FAIL_BYTE_UNARY(name)                                                               \
    275                 printk("fail\n");                                                               \
    276                 printk("0x%02X = %-15s(0x%02X), flags = %s -> %s\n",                            \
    277                     r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));    \
    278                 printk("0x%02X = %-15s(0x%02X), flags = %s -> %s\n",                            \
    279                     r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags));
    280 
    281 #define VAL_FAIL_WORD_UNARY(name)                                                               \
    282                 printk("fail\n");                                                               \
    283                 printk("0x%04X = %-15s(0x%04X), flags = %s -> %s\n",                            \
    284                     r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));  \
    285                 printk("0x%04X = %-15s(0x%04X), flags = %s -> %s\n",                            \
    286                     r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags));
    287 
    288 #define VAL_FAIL_LONG_UNARY(name)                                                               \
    289                 printk("fail\n");                                                               \
    290                 printk("0x%08X = %-15s(0x%08X), flags = %s -> %s\n",                            \
    291                     r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));    \
    292                 printk("0x%08X = %-15s(0x%08X), flags = %s -> %s\n",                            \
    293                     r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags));
    294 
    295 #define VAL_END_UNARY()                                                 \
    296                 }                                                       \
    297             M.x86.R_EFLG = inflags = flags = def_flags | ALL_FLAGS;     \
    298             if (failed)                                                 \
    299                 break;                                                  \
    300             }                                                           \
    301         if (failed)                                                     \
    302             break;                                                      \
    303         }                                                               \
    304     if (!failed)                                                        \
    305         printk("passed\n");                                             \
    306 }
    307 
    308 #define VAL_BYTE_UNARY(name)                \
    309     printk("Validating %s ... ", #name);    \
    310     VAL_START_UNARY(u8,0xFF,0x1)            \
    311     VAL_TEST_UNARY(name)                    \
    312     VAL_FAIL_BYTE_UNARY(name)               \
    313     VAL_END_UNARY()
    314 
    315 #define VAL_WORD_UNARY(name)                \
    316     printk("Validating %s ... ", #name);    \
    317     VAL_START_UNARY(u16,0xFF00,0x100)       \
    318     VAL_TEST_UNARY(name)                    \
    319     VAL_FAIL_WORD_UNARY(name)               \
    320     VAL_END_UNARY()
    321 
    322 #define VAL_WORD_BYTE_UNARY(name)           \
    323     printk("Validating %s ... ", #name);    \
    324     VAL_START_UNARY(u16,0xFF,0x1)           \
    325     VAL_TEST_UNARY(name)                    \
    326     VAL_FAIL_WORD_UNARY(name)               \
    327     VAL_END_UNARY()
    328 
    329 #define VAL_LONG_UNARY(name)                \
    330     printk("Validating %s ... ", #name);    \
    331     VAL_START_UNARY(u32,0xFF000000,0x1000000) \
    332     VAL_TEST_UNARY(name)                    \
    333     VAL_FAIL_LONG_UNARY(name)               \
    334     VAL_END_UNARY()
    335 
    336 #define VAL_BYTE_MUL(name)                                              \
    337     printk("Validating %s ... ", #name);                                \
    338 {                                                                       \
    339     u8          d,s;                                                    \
    340     u16         r,r_asm;                                                \
    341 	u32         flags,inflags;                                          \
    342     int         f,failed = false;                                       \
    343     char        buf1[80],buf2[80];                                      \
    344     for (d = 0; d < 0xFF; d += 1) {                                     \
    345         for (s = 0; s < 0xFF; s += 1) {                                 \
    346             M.x86.R_EFLG = inflags = flags = def_flags;                 \
    347             for (f = 0; f < 2; f++) {                                   \
    348                 name##_asm(&flags,&r_asm,d,s);                          \
    349                 M.x86.R_AL = d;                                         \
    350                 name(s);                                            \
    351                 r = M.x86.R_AX;                                         \
    352                 if (r != r_asm || M.x86.R_EFLG != flags)                \
    353                     failed = true;                                      \
    354                 if (failed || trace) {                                  \
    355                     if (failed)                                         \
    356                         printk("fail\n");                               \
    357                     printk("0x%04X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n",                         \
    358                         r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));     \
    359                     printk("0x%04X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n",                         \
    360                         r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
    361                     }                                                       \
    362                 M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
    363                 if (failed)                                                 \
    364                     break;                                                  \
    365                 }                                                           \
    366             if (failed)                                                     \
    367                 break;                                                      \
    368             }                                                               \
    369         if (failed)                                                         \
    370             break;                                                          \
    371         }                                                                   \
    372     if (!failed)                                                            \
    373         printk("passed\n");                                                 \
    374 }
    375 
    376 #define VAL_WORD_MUL(name)                                              \
    377     printk("Validating %s ... ", #name);                                \
    378 {                                                                       \
    379     u16         d,s;                                                    \
    380     u16         r_lo,r_asm_lo;                                          \
    381     u16         r_hi,r_asm_hi;                                          \
    382 	u32         flags,inflags;                                          \
    383     int         f,failed = false;                                       \
    384     char        buf1[80],buf2[80];                                      \
    385     for (d = 0; d < 0xFF00; d += 0x100) {                               \
    386         for (s = 0; s < 0xFF00; s += 0x100) {                           \
    387             M.x86.R_EFLG = inflags = flags = def_flags;                 \
    388             for (f = 0; f < 2; f++) {                                   \
    389                 name##_asm(&flags,&r_asm_lo,&r_asm_hi,d,s);             \
    390                 M.x86.R_AX = d;                                         \
    391                 name(s);                                            \
    392                 r_lo = M.x86.R_AX;                                      \
    393                 r_hi = M.x86.R_DX;                                      \
    394                 if (r_lo != r_asm_lo || r_hi != r_asm_hi || M.x86.R_EFLG != flags)\
    395                     failed = true;                                      \
    396                 if (failed || trace) {                                  \
    397                     if (failed)                                         \
    398                         printk("fail\n");                               \
    399                     printk("0x%04X:0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n",                              \
    400                         r_hi,r_lo, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));       \
    401                     printk("0x%04X:0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n",                              \
    402                         r_asm_hi,r_asm_lo, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
    403                     }                                                                                               \
    404                 M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
    405                 if (failed)                                                 \
    406                     break;                                                  \
    407                 }                                                           \
    408             if (failed)                                                     \
    409                 break;                                                      \
    410             }                                                               \
    411         if (failed)                                                         \
    412             break;                                                          \
    413         }                                                                   \
    414     if (!failed)                                                            \
    415         printk("passed\n");                                                 \
    416 }
    417 
    418 #define VAL_LONG_MUL(name)                                              \
    419     printk("Validating %s ... ", #name);                                \
    420 {                                                                       \
    421     u32         d,s;                                                    \
    422     u32         r_lo,r_asm_lo;                                          \
    423     u32         r_hi,r_asm_hi;                                          \
    424 	u32         flags,inflags;                                          \
    425     int         f,failed = false;                                       \
    426     char        buf1[80],buf2[80];                                      \
    427     for (d = 0; d < 0xFF000000; d += 0x1000000) {                       \
    428         for (s = 0; s < 0xFF000000; s += 0x1000000) {                   \
    429             M.x86.R_EFLG = inflags = flags = def_flags;                 \
    430             for (f = 0; f < 2; f++) {                                   \
    431                 name##_asm(&flags,&r_asm_lo,&r_asm_hi,d,s);             \
    432                 M.x86.R_EAX = d;                                        \
    433                 name(s);                                            \
    434                 r_lo = M.x86.R_EAX;                                     \
    435                 r_hi = M.x86.R_EDX;                                     \
    436                 if (r_lo != r_asm_lo || r_hi != r_asm_hi || M.x86.R_EFLG != flags)\
    437                     failed = true;                                      \
    438                 if (failed || trace) {                                  \
    439                     if (failed)                                         \
    440                         printk("fail\n");                               \
    441                     printk("0x%08X:0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n",                              \
    442                         r_hi,r_lo, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));       \
    443                     printk("0x%08X:0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n",                              \
    444                         r_asm_hi,r_asm_lo, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
    445                     }                                                                                               \
    446                 M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
    447                 if (failed)                                                 \
    448                     break;                                                  \
    449                 }                                                           \
    450             if (failed)                                                     \
    451                 break;                                                      \
    452             }                                                               \
    453         if (failed)                                                         \
    454             break;                                                          \
    455         }                                                                   \
    456     if (!failed)                                                            \
    457         printk("passed\n");                                                 \
    458 }
    459 
    460 #define VAL_BYTE_DIV(name)                                              \
    461     printk("Validating %s ... ", #name);                                \
    462 {                                                                       \
    463     u16         d,s;                                                    \
    464     u8          r_quot,r_rem,r_asm_quot,r_asm_rem;                      \
    465 	u32         flags,inflags;                                          \
    466     int         f,failed = false;                                       \
    467     char        buf1[80],buf2[80];                                      \
    468     for (d = 0; d < 0xFF00; d += 0x100) {                               \
    469         for (s = 1; s < 0xFF; s += 1) {                                 \
    470             M.x86.R_EFLG = inflags = flags = def_flags;                 \
    471             for (f = 0; f < 2; f++) {                                   \
    472                 M.x86.intr = 0;                                         \
    473                 M.x86.R_AX = d;                                         \
    474                 name(s);                                            \
    475                 r_quot = M.x86.R_AL;                                    \
    476                 r_rem = M.x86.R_AH;                                     \
    477                 if (M.x86.intr & INTR_SYNCH)                            \
    478                     continue;                                           \
    479                 name##_asm(&flags,&r_asm_quot,&r_asm_rem,d,s);          \
    480                 if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \
    481                     failed = true;                                      \
    482                 if (failed || trace) {                                  \
    483                     if (failed)                                         \
    484                         printk("fail\n");                               \
    485                     printk("0x%02X:0x%02X = %-15s(0x%04X,0x%02X), flags = %s -> %s\n",                      \
    486                         r_quot, r_rem, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));     \
    487                     printk("0x%02X:0x%02X = %-15s(0x%04X,0x%02X), flags = %s -> %s\n",                      \
    488                         r_asm_quot, r_asm_rem, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
    489                     }                                                       \
    490                 M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
    491                 if (failed)                                                 \
    492                     break;                                                  \
    493                 }                                                           \
    494             if (failed)                                                     \
    495                 break;                                                      \
    496             }                                                               \
    497         if (failed)                                                         \
    498             break;                                                          \
    499         }                                                                   \
    500     if (!failed)                                                            \
    501         printk("passed\n");                                                 \
    502 }
    503 
    504 #define VAL_WORD_DIV(name)                                              \
    505     printk("Validating %s ... ", #name);                                \
    506 {                                                                       \
    507     u32         d,s;                                                    \
    508     u16         r_quot,r_rem,r_asm_quot,r_asm_rem;                      \
    509 	u32         flags,inflags;                                          \
    510     int         f,failed = false;                                       \
    511     char        buf1[80],buf2[80];                                      \
    512     for (d = 0; d < 0xFF000000; d += 0x1000000) {                       \
    513         for (s = 0x100; s < 0xFF00; s += 0x100) {                       \
    514             M.x86.R_EFLG = inflags = flags = def_flags;                 \
    515             for (f = 0; f < 2; f++) {                                   \
    516                 M.x86.intr = 0;                                         \
    517                 M.x86.R_AX = d & 0xFFFF;                                \
    518                 M.x86.R_DX = d >> 16;                                   \
    519                 name(s);                                            \
    520                 r_quot = M.x86.R_AX;                                    \
    521                 r_rem = M.x86.R_DX;                                     \
    522                 if (M.x86.intr & INTR_SYNCH)                            \
    523                     continue;                                           \
    524                 name##_asm(&flags,&r_asm_quot,&r_asm_rem,d & 0xFFFF,d >> 16,s);\
    525                 if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \
    526                     failed = true;                                      \
    527                 if (failed || trace) {                                  \
    528                     if (failed)                                         \
    529                         printk("fail\n");                               \
    530                     printk("0x%04X:0x%04X = %-15s(0x%08X,0x%04X), flags = %s -> %s\n",                      \
    531                         r_quot, r_rem, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));     \
    532                     printk("0x%04X:0x%04X = %-15s(0x%08X,0x%04X), flags = %s -> %s\n",                      \
    533                         r_asm_quot, r_asm_rem, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
    534                     }                                                       \
    535                 M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
    536                 if (failed)                                                 \
    537                     break;                                                  \
    538                 }                                                           \
    539             if (failed)                                                     \
    540                 break;                                                      \
    541             }                                                               \
    542         if (failed)                                                         \
    543             break;                                                          \
    544         }                                                                   \
    545     if (!failed)                                                            \
    546         printk("passed\n");                                                 \
    547 }
    548 
    549 #define VAL_LONG_DIV(name)                                              \
    550     printk("Validating %s ... ", #name);                                \
    551 {                                                                       \
    552     u32         d,s;                                                    \
    553     u32         r_quot,r_rem,r_asm_quot,r_asm_rem;                      \
    554 	u32         flags,inflags;                                          \
    555     int         f,failed = false;                                       \
    556     char        buf1[80],buf2[80];                                      \
    557     for (d = 0; d < 0xFF000000; d += 0x1000000) {                       \
    558         for (s = 0x100; s < 0xFF00; s += 0x100) {                       \
    559             M.x86.R_EFLG = inflags = flags = def_flags;                 \
    560             for (f = 0; f < 2; f++) {                                   \
    561                 M.x86.intr = 0;                                         \
    562                 M.x86.R_EAX = d;                                        \
    563                 M.x86.R_EDX = 0;                                        \
    564                 name(s);                                            \
    565                 r_quot = M.x86.R_EAX;                                   \
    566                 r_rem = M.x86.R_EDX;                                    \
    567                 if (M.x86.intr & INTR_SYNCH)                            \
    568                     continue;                                           \
    569                 name##_asm(&flags,&r_asm_quot,&r_asm_rem,d,0,s);        \
    570                 if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \
    571                     failed = true;                                      \
    572                 if (failed || trace) {                                  \
    573                     if (failed)                                         \
    574                         printk("fail\n");                               \
    575                     printk("0x%08X:0x%08X = %-15s(0x%08X:0x%08X,0x%08X), flags = %s -> %s\n",                       \
    576                         r_quot, r_rem, #name, 0, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));  \
    577                     printk("0x%08X:0x%08X = %-15s(0x%08X:0x%08X,0x%08X), flags = %s -> %s\n",                       \
    578                         r_asm_quot, r_asm_rem, #name"_asm", 0, d, s, print_flags(buf1,inflags), print_flags(buf2,flags));   \
    579                     }                                                       \
    580                 M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
    581                 if (failed)                                                 \
    582                     break;                                                  \
    583                 }                                                           \
    584             if (failed)                                                     \
    585                 break;                                                      \
    586             }                                                               \
    587         if (failed)                                                         \
    588             break;                                                          \
    589         }                                                                   \
    590     if (!failed)                                                            \
    591         printk("passed\n");                                                 \
    592 }
    593 
    594 void
    595 printk(const char *fmt, ...)
    596 {
    597     va_list argptr;
    598 
    599     va_start(argptr, fmt);
    600     vfprintf(stdout, fmt, argptr);
    601     fflush(stdout);
    602     va_end(argptr);
    603 }
    604 
    605 char *
    606 print_flags(char *buf, ulong flags)
    607 {
    608     char *separator = "";
    609 
    610     buf[0] = 0;
    611     if (flags & F_CF) {
    612         strcat(buf, separator);
    613         strcat(buf, "CF");
    614         separator = ",";
    615     }
    616     if (flags & F_PF) {
    617         strcat(buf, separator);
    618         strcat(buf, "PF");
    619         separator = ",";
    620     }
    621     if (flags & F_AF) {
    622         strcat(buf, separator);
    623         strcat(buf, "AF");
    624         separator = ",";
    625     }
    626     if (flags & F_ZF) {
    627         strcat(buf, separator);
    628         strcat(buf, "ZF");
    629         separator = ",";
    630     }
    631     if (flags & F_SF) {
    632         strcat(buf, separator);
    633         strcat(buf, "SF");
    634         separator = ",";
    635     }
    636     if (flags & F_OF) {
    637         strcat(buf, separator);
    638         strcat(buf, "OF");
    639         separator = ",";
    640     }
    641     if (separator[0] == 0)
    642         strcpy(buf, "None");
    643     return buf;
    644 }
    645 
    646 int
    647 main(int argc)
    648 {
    649     ulong def_flags;
    650     int trace = false;
    651 
    652     if (argc > 1)
    653         trace = true;
    654     memset(&M, 0, sizeof(M));
    655     def_flags = get_flags_asm() & ~ALL_FLAGS;
    656 
    657     VAL_WORD_UNARY(aaa_word);
    658     VAL_WORD_UNARY(aas_word);
    659 
    660     VAL_WORD_UNARY(aad_word);
    661     VAL_WORD_UNARY(aam_word);
    662 
    663     VAL_BYTE_BYTE_BINARY(adc_byte);
    664     VAL_WORD_WORD_BINARY(adc_word);
    665     VAL_LONG_LONG_BINARY(adc_long);
    666 
    667     VAL_BYTE_BYTE_BINARY(add_byte);
    668     VAL_WORD_WORD_BINARY(add_word);
    669     VAL_LONG_LONG_BINARY(add_long);
    670 
    671     VAL_BYTE_BYTE_BINARY(and_byte);
    672     VAL_WORD_WORD_BINARY(and_word);
    673     VAL_LONG_LONG_BINARY(and_long);
    674 
    675     VAL_BYTE_BYTE_BINARY(cmp_byte);
    676     VAL_WORD_WORD_BINARY(cmp_word);
    677     VAL_LONG_LONG_BINARY(cmp_long);
    678 
    679     VAL_BYTE_UNARY(daa_byte);
    680     VAL_BYTE_UNARY(das_byte);   /* Fails for 0x9A (out of range anyway) */
    681 
    682     VAL_BYTE_UNARY(dec_byte);
    683     VAL_WORD_UNARY(dec_word);
    684     VAL_LONG_UNARY(dec_long);
    685 
    686     VAL_BYTE_UNARY(inc_byte);
    687     VAL_WORD_UNARY(inc_word);
    688     VAL_LONG_UNARY(inc_long);
    689 
    690     VAL_BYTE_BYTE_BINARY(or_byte);
    691     VAL_WORD_WORD_BINARY(or_word);
    692     VAL_LONG_LONG_BINARY(or_long);
    693 
    694     VAL_BYTE_UNARY(neg_byte);
    695     VAL_WORD_UNARY(neg_word);
    696     VAL_LONG_UNARY(neg_long);
    697 
    698     VAL_BYTE_UNARY(not_byte);
    699     VAL_WORD_UNARY(not_word);
    700     VAL_LONG_UNARY(not_long);
    701 
    702     VAL_BYTE_ROTATE(rcl_byte);
    703     VAL_WORD_ROTATE(rcl_word);
    704     VAL_LONG_ROTATE(rcl_long);
    705 
    706     VAL_BYTE_ROTATE(rcr_byte);
    707     VAL_WORD_ROTATE(rcr_word);
    708     VAL_LONG_ROTATE(rcr_long);
    709 
    710     VAL_BYTE_ROTATE(rol_byte);
    711     VAL_WORD_ROTATE(rol_word);
    712     VAL_LONG_ROTATE(rol_long);
    713 
    714     VAL_BYTE_ROTATE(ror_byte);
    715     VAL_WORD_ROTATE(ror_word);
    716     VAL_LONG_ROTATE(ror_long);
    717 
    718     VAL_BYTE_ROTATE(shl_byte);
    719     VAL_WORD_ROTATE(shl_word);
    720     VAL_LONG_ROTATE(shl_long);
    721 
    722     VAL_BYTE_ROTATE(shr_byte);
    723     VAL_WORD_ROTATE(shr_word);
    724     VAL_LONG_ROTATE(shr_long);
    725 
    726     VAL_BYTE_ROTATE(sar_byte);
    727     VAL_WORD_ROTATE(sar_word);
    728     VAL_LONG_ROTATE(sar_long);
    729 
    730     VAL_WORD_ROTATE_DBL(shld_word);
    731     VAL_LONG_ROTATE_DBL(shld_long);
    732 
    733     VAL_WORD_ROTATE_DBL(shrd_word);
    734     VAL_LONG_ROTATE_DBL(shrd_long);
    735 
    736     VAL_BYTE_BYTE_BINARY(sbb_byte);
    737     VAL_WORD_WORD_BINARY(sbb_word);
    738     VAL_LONG_LONG_BINARY(sbb_long);
    739 
    740     VAL_BYTE_BYTE_BINARY(sub_byte);
    741     VAL_WORD_WORD_BINARY(sub_word);
    742     VAL_LONG_LONG_BINARY(sub_long);
    743 
    744     VAL_BYTE_BYTE_BINARY(xor_byte);
    745     VAL_WORD_WORD_BINARY(xor_word);
    746     VAL_LONG_LONG_BINARY(xor_long);
    747 
    748     VAL_VOID_BYTE_BINARY(test_byte);
    749     VAL_VOID_WORD_BINARY(test_word);
    750     VAL_VOID_LONG_BINARY(test_long);
    751 
    752     VAL_BYTE_MUL(imul_byte);
    753     VAL_WORD_MUL(imul_word);
    754     VAL_LONG_MUL(imul_long);
    755 
    756     VAL_BYTE_MUL(mul_byte);
    757     VAL_WORD_MUL(mul_word);
    758     VAL_LONG_MUL(mul_long);
    759 
    760     VAL_BYTE_DIV(idiv_byte);
    761     VAL_WORD_DIV(idiv_word);
    762     VAL_LONG_DIV(idiv_long);
    763 
    764     VAL_BYTE_DIV(div_byte);
    765     VAL_WORD_DIV(div_word);
    766     VAL_LONG_DIV(div_long);
    767 
    768     return 0;
    769 }