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