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