Coding style cleanup
[platform/kernel/u-boot.git] / board / MAI / bios_emulator / scitech / src / x86emu / validate.c
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 printk(const char *fmt, ...)
595 {
596     va_list argptr;
597     va_start(argptr, fmt);
598     vfprintf(stdout, fmt, argptr);
599     fflush(stdout);
600     va_end(argptr);
601 }
602
603 char * print_flags(char *buf,ulong flags)
604 {
605     char *separator = "";
606
607     buf[0] = 0;
608     if (flags & F_CF) {
609         strcat(buf,separator);
610         strcat(buf,"CF");
611         separator = ",";
612         }
613     if (flags & F_PF) {
614         strcat(buf,separator);
615         strcat(buf,"PF");
616         separator = ",";
617         }
618     if (flags & F_AF) {
619         strcat(buf,separator);
620         strcat(buf,"AF");
621         separator = ",";
622         }
623     if (flags & F_ZF) {
624         strcat(buf,separator);
625         strcat(buf,"ZF");
626         separator = ",";
627         }
628     if (flags & F_SF) {
629         strcat(buf,separator);
630         strcat(buf,"SF");
631         separator = ",";
632         }
633     if (flags & F_OF) {
634         strcat(buf,separator);
635         strcat(buf,"OF");
636         separator = ",";
637         }
638     if (separator[0] == 0)
639         strcpy(buf,"None");
640     return buf;
641 }
642
643 int main(int argc)
644 {
645     ulong   def_flags;
646     int trace = false;
647
648     if (argc > 1)
649         trace = true;
650     memset(&M, 0, sizeof(M));
651     def_flags = get_flags_asm() & ~ALL_FLAGS;
652
653     VAL_WORD_UNARY(aaa_word);
654     VAL_WORD_UNARY(aas_word);
655
656     VAL_WORD_UNARY(aad_word);
657     VAL_WORD_UNARY(aam_word);
658
659     VAL_BYTE_BYTE_BINARY(adc_byte);
660     VAL_WORD_WORD_BINARY(adc_word);
661     VAL_LONG_LONG_BINARY(adc_long);
662
663     VAL_BYTE_BYTE_BINARY(add_byte);
664     VAL_WORD_WORD_BINARY(add_word);
665     VAL_LONG_LONG_BINARY(add_long);
666
667     VAL_BYTE_BYTE_BINARY(and_byte);
668     VAL_WORD_WORD_BINARY(and_word);
669     VAL_LONG_LONG_BINARY(and_long);
670
671     VAL_BYTE_BYTE_BINARY(cmp_byte);
672     VAL_WORD_WORD_BINARY(cmp_word);
673     VAL_LONG_LONG_BINARY(cmp_long);
674
675     VAL_BYTE_UNARY(daa_byte);
676     VAL_BYTE_UNARY(das_byte);   /* Fails for 0x9A (out of range anyway) */
677
678     VAL_BYTE_UNARY(dec_byte);
679     VAL_WORD_UNARY(dec_word);
680     VAL_LONG_UNARY(dec_long);
681
682     VAL_BYTE_UNARY(inc_byte);
683     VAL_WORD_UNARY(inc_word);
684     VAL_LONG_UNARY(inc_long);
685
686     VAL_BYTE_BYTE_BINARY(or_byte);
687     VAL_WORD_WORD_BINARY(or_word);
688     VAL_LONG_LONG_BINARY(or_long);
689
690     VAL_BYTE_UNARY(neg_byte);
691     VAL_WORD_UNARY(neg_word);
692     VAL_LONG_UNARY(neg_long);
693
694     VAL_BYTE_UNARY(not_byte);
695     VAL_WORD_UNARY(not_word);
696     VAL_LONG_UNARY(not_long);
697
698     VAL_BYTE_ROTATE(rcl_byte);
699     VAL_WORD_ROTATE(rcl_word);
700     VAL_LONG_ROTATE(rcl_long);
701
702     VAL_BYTE_ROTATE(rcr_byte);
703     VAL_WORD_ROTATE(rcr_word);
704     VAL_LONG_ROTATE(rcr_long);
705
706     VAL_BYTE_ROTATE(rol_byte);
707     VAL_WORD_ROTATE(rol_word);
708     VAL_LONG_ROTATE(rol_long);
709
710     VAL_BYTE_ROTATE(ror_byte);
711     VAL_WORD_ROTATE(ror_word);
712     VAL_LONG_ROTATE(ror_long);
713
714     VAL_BYTE_ROTATE(shl_byte);
715     VAL_WORD_ROTATE(shl_word);
716     VAL_LONG_ROTATE(shl_long);
717
718     VAL_BYTE_ROTATE(shr_byte);
719     VAL_WORD_ROTATE(shr_word);
720     VAL_LONG_ROTATE(shr_long);
721
722     VAL_BYTE_ROTATE(sar_byte);
723     VAL_WORD_ROTATE(sar_word);
724     VAL_LONG_ROTATE(sar_long);
725
726     VAL_WORD_ROTATE_DBL(shld_word);
727     VAL_LONG_ROTATE_DBL(shld_long);
728
729     VAL_WORD_ROTATE_DBL(shrd_word);
730     VAL_LONG_ROTATE_DBL(shrd_long);
731
732     VAL_BYTE_BYTE_BINARY(sbb_byte);
733     VAL_WORD_WORD_BINARY(sbb_word);
734     VAL_LONG_LONG_BINARY(sbb_long);
735
736     VAL_BYTE_BYTE_BINARY(sub_byte);
737     VAL_WORD_WORD_BINARY(sub_word);
738     VAL_LONG_LONG_BINARY(sub_long);
739
740     VAL_BYTE_BYTE_BINARY(xor_byte);
741     VAL_WORD_WORD_BINARY(xor_word);
742     VAL_LONG_LONG_BINARY(xor_long);
743
744     VAL_VOID_BYTE_BINARY(test_byte);
745     VAL_VOID_WORD_BINARY(test_word);
746     VAL_VOID_LONG_BINARY(test_long);
747
748     VAL_BYTE_MUL(imul_byte);
749     VAL_WORD_MUL(imul_word);
750     VAL_LONG_MUL(imul_long);
751
752     VAL_BYTE_MUL(mul_byte);
753     VAL_WORD_MUL(mul_word);
754     VAL_LONG_MUL(mul_long);
755
756     VAL_BYTE_DIV(idiv_byte);
757     VAL_WORD_DIV(idiv_word);
758     VAL_LONG_DIV(idiv_long);
759
760     VAL_BYTE_DIV(div_byte);
761     VAL_WORD_DIV(div_word);
762     VAL_LONG_DIV(div_long);
763
764     return 0;
765 }