Statistics
| Branch: | Revision:

root / tests / test-i386.c @ d3c61721

History | View | Annotate | Download (55.7 kB)

1 78d6da97 bellard
/*
2 78d6da97 bellard
 *  x86 CPU test
3 78d6da97 bellard
 * 
4 78d6da97 bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 78d6da97 bellard
 *
6 78d6da97 bellard
 *  This program is free software; you can redistribute it and/or modify
7 78d6da97 bellard
 *  it under the terms of the GNU General Public License as published by
8 78d6da97 bellard
 *  the Free Software Foundation; either version 2 of the License, or
9 78d6da97 bellard
 *  (at your option) any later version.
10 78d6da97 bellard
 *
11 78d6da97 bellard
 *  This program is distributed in the hope that it will be useful,
12 78d6da97 bellard
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 78d6da97 bellard
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 78d6da97 bellard
 *  GNU General Public License for more details.
15 78d6da97 bellard
 *
16 78d6da97 bellard
 *  You should have received a copy of the GNU General Public License
17 78d6da97 bellard
 *  along with this program; if not, write to the Free Software
18 78d6da97 bellard
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 78d6da97 bellard
 */
20 3a27ad0b bellard
#define _GNU_SOURCE
21 4d1135e4 bellard
#include <stdlib.h>
22 4d1135e4 bellard
#include <stdio.h>
23 e3e86d56 bellard
#include <string.h>
24 6dbad63e bellard
#include <inttypes.h>
25 4d1135e4 bellard
#include <math.h>
26 3a27ad0b bellard
#include <signal.h>
27 3a27ad0b bellard
#include <setjmp.h>
28 070893f4 bellard
#include <errno.h>
29 3a27ad0b bellard
#include <sys/ucontext.h>
30 3a27ad0b bellard
#include <sys/mman.h>
31 3a27ad0b bellard
#include <asm/vm86.h>
32 4d1135e4 bellard
33 03bfca94 bellard
#define TEST_CMOV  0
34 03bfca94 bellard
#define TEST_FCOMI 0
35 acae4681 bellard
#define TEST_VM86
36 3ff0631e bellard
//#define LINUX_VM86_IOPL_FIX
37 791c2261 bellard
//#define TEST_P4_FLAGS
38 085339a1 bellard
//#define TEST_SSE
39 5dd9488c bellard
40 4d1135e4 bellard
#define xglue(x, y) x ## y
41 4d1135e4 bellard
#define glue(x, y) xglue(x, y)
42 4d1135e4 bellard
#define stringify(s)        tostring(s)
43 4d1135e4 bellard
#define tostring(s)        #s
44 4d1135e4 bellard
45 4d1135e4 bellard
#define CC_C           0x0001
46 4d1135e4 bellard
#define CC_P         0x0004
47 4d1135e4 bellard
#define CC_A        0x0010
48 4d1135e4 bellard
#define CC_Z        0x0040
49 4d1135e4 bellard
#define CC_S    0x0080
50 4d1135e4 bellard
#define CC_O    0x0800
51 4d1135e4 bellard
52 4d1135e4 bellard
#define __init_call        __attribute__ ((unused,__section__ (".initcall.init")))
53 4d1135e4 bellard
54 4d1135e4 bellard
static void *call_start __init_call = NULL;
55 4d1135e4 bellard
56 4b74fe1f bellard
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
57 4b74fe1f bellard
58 4d1135e4 bellard
#define OP add
59 4d1135e4 bellard
#include "test-i386.h"
60 4d1135e4 bellard
61 4d1135e4 bellard
#define OP sub
62 4d1135e4 bellard
#include "test-i386.h"
63 4d1135e4 bellard
64 4d1135e4 bellard
#define OP xor
65 4d1135e4 bellard
#include "test-i386.h"
66 4d1135e4 bellard
67 4d1135e4 bellard
#define OP and
68 4d1135e4 bellard
#include "test-i386.h"
69 4d1135e4 bellard
70 4d1135e4 bellard
#define OP or
71 4d1135e4 bellard
#include "test-i386.h"
72 4d1135e4 bellard
73 4d1135e4 bellard
#define OP cmp
74 4d1135e4 bellard
#include "test-i386.h"
75 4d1135e4 bellard
76 4d1135e4 bellard
#define OP adc
77 4d1135e4 bellard
#define OP_CC
78 4d1135e4 bellard
#include "test-i386.h"
79 4d1135e4 bellard
80 4d1135e4 bellard
#define OP sbb
81 4d1135e4 bellard
#define OP_CC
82 4d1135e4 bellard
#include "test-i386.h"
83 4d1135e4 bellard
84 4d1135e4 bellard
#define OP inc
85 4d1135e4 bellard
#define OP_CC
86 4d1135e4 bellard
#define OP1
87 4d1135e4 bellard
#include "test-i386.h"
88 4d1135e4 bellard
89 4d1135e4 bellard
#define OP dec
90 4d1135e4 bellard
#define OP_CC
91 4d1135e4 bellard
#define OP1
92 4d1135e4 bellard
#include "test-i386.h"
93 4d1135e4 bellard
94 4d1135e4 bellard
#define OP neg
95 4d1135e4 bellard
#define OP_CC
96 4d1135e4 bellard
#define OP1
97 4d1135e4 bellard
#include "test-i386.h"
98 4d1135e4 bellard
99 4d1135e4 bellard
#define OP not
100 4d1135e4 bellard
#define OP_CC
101 4d1135e4 bellard
#define OP1
102 4d1135e4 bellard
#include "test-i386.h"
103 4d1135e4 bellard
104 4b74fe1f bellard
#undef CC_MASK
105 4b74fe1f bellard
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O)
106 4b74fe1f bellard
107 379ca80d bellard
#define OP shl
108 379ca80d bellard
#include "test-i386-shift.h"
109 379ca80d bellard
110 379ca80d bellard
#define OP shr
111 379ca80d bellard
#include "test-i386-shift.h"
112 379ca80d bellard
113 379ca80d bellard
#define OP sar
114 379ca80d bellard
#include "test-i386-shift.h"
115 379ca80d bellard
116 379ca80d bellard
#define OP rol
117 379ca80d bellard
#include "test-i386-shift.h"
118 379ca80d bellard
119 379ca80d bellard
#define OP ror
120 379ca80d bellard
#include "test-i386-shift.h"
121 379ca80d bellard
122 379ca80d bellard
#define OP rcr
123 379ca80d bellard
#define OP_CC
124 379ca80d bellard
#include "test-i386-shift.h"
125 379ca80d bellard
126 379ca80d bellard
#define OP rcl
127 379ca80d bellard
#define OP_CC
128 379ca80d bellard
#include "test-i386-shift.h"
129 379ca80d bellard
130 d57c4e01 bellard
#define OP shld
131 d57c4e01 bellard
#define OP_SHIFTD
132 d57c4e01 bellard
#define OP_NOBYTE
133 d57c4e01 bellard
#include "test-i386-shift.h"
134 d57c4e01 bellard
135 d57c4e01 bellard
#define OP shrd
136 d57c4e01 bellard
#define OP_SHIFTD
137 d57c4e01 bellard
#define OP_NOBYTE
138 d57c4e01 bellard
#include "test-i386-shift.h"
139 d57c4e01 bellard
140 d57c4e01 bellard
/* XXX: should be more precise ? */
141 d57c4e01 bellard
#undef CC_MASK
142 d57c4e01 bellard
#define CC_MASK (CC_C)
143 d57c4e01 bellard
144 d57c4e01 bellard
#define OP bt
145 d57c4e01 bellard
#define OP_NOBYTE
146 d57c4e01 bellard
#include "test-i386-shift.h"
147 d57c4e01 bellard
148 d57c4e01 bellard
#define OP bts
149 d57c4e01 bellard
#define OP_NOBYTE
150 d57c4e01 bellard
#include "test-i386-shift.h"
151 d57c4e01 bellard
152 d57c4e01 bellard
#define OP btr
153 d57c4e01 bellard
#define OP_NOBYTE
154 d57c4e01 bellard
#include "test-i386-shift.h"
155 d57c4e01 bellard
156 d57c4e01 bellard
#define OP btc
157 d57c4e01 bellard
#define OP_NOBYTE
158 d57c4e01 bellard
#include "test-i386-shift.h"
159 379ca80d bellard
160 4d1135e4 bellard
/* lea test (modrm support) */
161 4d1135e4 bellard
#define TEST_LEA(STR)\
162 4d1135e4 bellard
{\
163 4d1135e4 bellard
    asm("leal " STR ", %0"\
164 4d1135e4 bellard
        : "=r" (res)\
165 4d1135e4 bellard
        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
166 4d1135e4 bellard
    printf("lea %s = %08x\n", STR, res);\
167 4d1135e4 bellard
}
168 4d1135e4 bellard
169 4d1135e4 bellard
#define TEST_LEA16(STR)\
170 4d1135e4 bellard
{\
171 4d1135e4 bellard
    asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\
172 4d1135e4 bellard
        : "=wq" (res)\
173 4d1135e4 bellard
        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
174 4d1135e4 bellard
    printf("lea %s = %08x\n", STR, res);\
175 4d1135e4 bellard
}
176 4d1135e4 bellard
177 4d1135e4 bellard
178 4d1135e4 bellard
void test_lea(void)
179 4d1135e4 bellard
{
180 4d1135e4 bellard
    int eax, ebx, ecx, edx, esi, edi, res;
181 4d1135e4 bellard
    eax = 0x0001;
182 4d1135e4 bellard
    ebx = 0x0002;
183 4d1135e4 bellard
    ecx = 0x0004;
184 4d1135e4 bellard
    edx = 0x0008;
185 4d1135e4 bellard
    esi = 0x0010;
186 4d1135e4 bellard
    edi = 0x0020;
187 4d1135e4 bellard
188 4d1135e4 bellard
    TEST_LEA("0x4000");
189 4d1135e4 bellard
190 4d1135e4 bellard
    TEST_LEA("(%%eax)");
191 4d1135e4 bellard
    TEST_LEA("(%%ebx)");
192 4d1135e4 bellard
    TEST_LEA("(%%ecx)");
193 4d1135e4 bellard
    TEST_LEA("(%%edx)");
194 4d1135e4 bellard
    TEST_LEA("(%%esi)");
195 4d1135e4 bellard
    TEST_LEA("(%%edi)");
196 4d1135e4 bellard
197 4d1135e4 bellard
    TEST_LEA("0x40(%%eax)");
198 4d1135e4 bellard
    TEST_LEA("0x40(%%ebx)");
199 4d1135e4 bellard
    TEST_LEA("0x40(%%ecx)");
200 4d1135e4 bellard
    TEST_LEA("0x40(%%edx)");
201 4d1135e4 bellard
    TEST_LEA("0x40(%%esi)");
202 4d1135e4 bellard
    TEST_LEA("0x40(%%edi)");
203 4d1135e4 bellard
204 4d1135e4 bellard
    TEST_LEA("0x4000(%%eax)");
205 4d1135e4 bellard
    TEST_LEA("0x4000(%%ebx)");
206 4d1135e4 bellard
    TEST_LEA("0x4000(%%ecx)");
207 4d1135e4 bellard
    TEST_LEA("0x4000(%%edx)");
208 4d1135e4 bellard
    TEST_LEA("0x4000(%%esi)");
209 4d1135e4 bellard
    TEST_LEA("0x4000(%%edi)");
210 4d1135e4 bellard
211 4d1135e4 bellard
    TEST_LEA("(%%eax, %%ecx)");
212 4d1135e4 bellard
    TEST_LEA("(%%ebx, %%edx)");
213 4d1135e4 bellard
    TEST_LEA("(%%ecx, %%ecx)");
214 4d1135e4 bellard
    TEST_LEA("(%%edx, %%ecx)");
215 4d1135e4 bellard
    TEST_LEA("(%%esi, %%ecx)");
216 4d1135e4 bellard
    TEST_LEA("(%%edi, %%ecx)");
217 4d1135e4 bellard
218 4d1135e4 bellard
    TEST_LEA("0x40(%%eax, %%ecx)");
219 4d1135e4 bellard
    TEST_LEA("0x4000(%%ebx, %%edx)");
220 4d1135e4 bellard
221 4d1135e4 bellard
    TEST_LEA("(%%ecx, %%ecx, 2)");
222 4d1135e4 bellard
    TEST_LEA("(%%edx, %%ecx, 4)");
223 4d1135e4 bellard
    TEST_LEA("(%%esi, %%ecx, 8)");
224 4d1135e4 bellard
225 4d1135e4 bellard
    TEST_LEA("(,%%eax, 2)");
226 4d1135e4 bellard
    TEST_LEA("(,%%ebx, 4)");
227 4d1135e4 bellard
    TEST_LEA("(,%%ecx, 8)");
228 4d1135e4 bellard
229 4d1135e4 bellard
    TEST_LEA("0x40(,%%eax, 2)");
230 4d1135e4 bellard
    TEST_LEA("0x40(,%%ebx, 4)");
231 4d1135e4 bellard
    TEST_LEA("0x40(,%%ecx, 8)");
232 4d1135e4 bellard
233 4d1135e4 bellard
234 4d1135e4 bellard
    TEST_LEA("-10(%%ecx, %%ecx, 2)");
235 4d1135e4 bellard
    TEST_LEA("-10(%%edx, %%ecx, 4)");
236 4d1135e4 bellard
    TEST_LEA("-10(%%esi, %%ecx, 8)");
237 4d1135e4 bellard
238 4d1135e4 bellard
    TEST_LEA("0x4000(%%ecx, %%ecx, 2)");
239 4d1135e4 bellard
    TEST_LEA("0x4000(%%edx, %%ecx, 4)");
240 4d1135e4 bellard
    TEST_LEA("0x4000(%%esi, %%ecx, 8)");
241 4d1135e4 bellard
242 4d1135e4 bellard
    /* limited 16 bit addressing test */
243 4d1135e4 bellard
    TEST_LEA16("0x4000");
244 4d1135e4 bellard
    TEST_LEA16("(%%bx)");
245 4d1135e4 bellard
    TEST_LEA16("(%%si)");
246 4d1135e4 bellard
    TEST_LEA16("(%%di)");
247 4d1135e4 bellard
    TEST_LEA16("0x40(%%bx)");
248 4d1135e4 bellard
    TEST_LEA16("0x40(%%si)");
249 4d1135e4 bellard
    TEST_LEA16("0x40(%%di)");
250 4d1135e4 bellard
    TEST_LEA16("0x4000(%%bx)");
251 4d1135e4 bellard
    TEST_LEA16("0x4000(%%si)");
252 4d1135e4 bellard
    TEST_LEA16("(%%bx,%%si)");
253 4d1135e4 bellard
    TEST_LEA16("(%%bx,%%di)");
254 4d1135e4 bellard
    TEST_LEA16("0x40(%%bx,%%si)");
255 4d1135e4 bellard
    TEST_LEA16("0x40(%%bx,%%di)");
256 4d1135e4 bellard
    TEST_LEA16("0x4000(%%bx,%%si)");
257 4d1135e4 bellard
    TEST_LEA16("0x4000(%%bx,%%di)");
258 4d1135e4 bellard
}
259 4d1135e4 bellard
260 4d1135e4 bellard
#define TEST_JCC(JCC, v1, v2)\
261 4d1135e4 bellard
{\
262 5dd9488c bellard
    int res;\
263 4d1135e4 bellard
    asm("movl $1, %0\n\t"\
264 4d1135e4 bellard
        "cmpl %2, %1\n\t"\
265 5dd9488c bellard
        "j" JCC " 1f\n\t"\
266 4d1135e4 bellard
        "movl $0, %0\n\t"\
267 4d1135e4 bellard
        "1:\n\t"\
268 4d1135e4 bellard
        : "=r" (res)\
269 4d1135e4 bellard
        : "r" (v1), "r" (v2));\
270 5dd9488c bellard
    printf("%-10s %d\n", "j" JCC, res);\
271 5dd9488c bellard
\
272 5dd9488c bellard
    asm("movl $0, %0\n\t"\
273 5dd9488c bellard
        "cmpl %2, %1\n\t"\
274 5dd9488c bellard
        "set" JCC " %b0\n\t"\
275 5dd9488c bellard
        : "=r" (res)\
276 5dd9488c bellard
        : "r" (v1), "r" (v2));\
277 5dd9488c bellard
    printf("%-10s %d\n", "set" JCC, res);\
278 5dd9488c bellard
 if (TEST_CMOV) {\
279 5dd9488c bellard
    asm("movl $0x12345678, %0\n\t"\
280 5dd9488c bellard
        "cmpl %2, %1\n\t"\
281 5dd9488c bellard
        "cmov" JCC "l %3, %0\n\t"\
282 5dd9488c bellard
        : "=r" (res)\
283 5dd9488c bellard
        : "r" (v1), "r" (v2), "m" (1));\
284 5dd9488c bellard
        printf("%-10s R=0x%08x\n", "cmov" JCC "l", res);\
285 5dd9488c bellard
    asm("movl $0x12345678, %0\n\t"\
286 5dd9488c bellard
        "cmpl %2, %1\n\t"\
287 5dd9488c bellard
        "cmov" JCC "w %w3, %w0\n\t"\
288 5dd9488c bellard
        : "=r" (res)\
289 5dd9488c bellard
        : "r" (v1), "r" (v2), "r" (1));\
290 5dd9488c bellard
        printf("%-10s R=0x%08x\n", "cmov" JCC "w", res);\
291 5dd9488c bellard
 } \
292 4d1135e4 bellard
}
293 4d1135e4 bellard
294 4d1135e4 bellard
/* various jump tests */
295 4d1135e4 bellard
void test_jcc(void)
296 4d1135e4 bellard
{
297 5dd9488c bellard
    TEST_JCC("ne", 1, 1);
298 5dd9488c bellard
    TEST_JCC("ne", 1, 0);
299 4d1135e4 bellard
300 5dd9488c bellard
    TEST_JCC("e", 1, 1);
301 5dd9488c bellard
    TEST_JCC("e", 1, 0);
302 4d1135e4 bellard
303 5dd9488c bellard
    TEST_JCC("l", 1, 1);
304 5dd9488c bellard
    TEST_JCC("l", 1, 0);
305 5dd9488c bellard
    TEST_JCC("l", 1, -1);
306 4d1135e4 bellard
307 5dd9488c bellard
    TEST_JCC("le", 1, 1);
308 5dd9488c bellard
    TEST_JCC("le", 1, 0);
309 5dd9488c bellard
    TEST_JCC("le", 1, -1);
310 4d1135e4 bellard
311 5dd9488c bellard
    TEST_JCC("ge", 1, 1);
312 5dd9488c bellard
    TEST_JCC("ge", 1, 0);
313 5dd9488c bellard
    TEST_JCC("ge", -1, 1);
314 4d1135e4 bellard
315 5dd9488c bellard
    TEST_JCC("g", 1, 1);
316 5dd9488c bellard
    TEST_JCC("g", 1, 0);
317 5dd9488c bellard
    TEST_JCC("g", 1, -1);
318 4d1135e4 bellard
319 5dd9488c bellard
    TEST_JCC("b", 1, 1);
320 5dd9488c bellard
    TEST_JCC("b", 1, 0);
321 5dd9488c bellard
    TEST_JCC("b", 1, -1);
322 4d1135e4 bellard
323 5dd9488c bellard
    TEST_JCC("be", 1, 1);
324 5dd9488c bellard
    TEST_JCC("be", 1, 0);
325 5dd9488c bellard
    TEST_JCC("be", 1, -1);
326 4d1135e4 bellard
327 5dd9488c bellard
    TEST_JCC("ae", 1, 1);
328 5dd9488c bellard
    TEST_JCC("ae", 1, 0);
329 5dd9488c bellard
    TEST_JCC("ae", 1, -1);
330 4d1135e4 bellard
331 5dd9488c bellard
    TEST_JCC("a", 1, 1);
332 5dd9488c bellard
    TEST_JCC("a", 1, 0);
333 5dd9488c bellard
    TEST_JCC("a", 1, -1);
334 4d1135e4 bellard
335 4d1135e4 bellard
336 5dd9488c bellard
    TEST_JCC("p", 1, 1);
337 5dd9488c bellard
    TEST_JCC("p", 1, 0);
338 4d1135e4 bellard
339 5dd9488c bellard
    TEST_JCC("np", 1, 1);
340 5dd9488c bellard
    TEST_JCC("np", 1, 0);
341 4d1135e4 bellard
342 5dd9488c bellard
    TEST_JCC("o", 0x7fffffff, 0);
343 5dd9488c bellard
    TEST_JCC("o", 0x7fffffff, -1);
344 4d1135e4 bellard
345 5dd9488c bellard
    TEST_JCC("no", 0x7fffffff, 0);
346 5dd9488c bellard
    TEST_JCC("no", 0x7fffffff, -1);
347 4d1135e4 bellard
348 5dd9488c bellard
    TEST_JCC("s", 0, 1);
349 5dd9488c bellard
    TEST_JCC("s", 0, -1);
350 5dd9488c bellard
    TEST_JCC("s", 0, 0);
351 4d1135e4 bellard
352 5dd9488c bellard
    TEST_JCC("ns", 0, 1);
353 5dd9488c bellard
    TEST_JCC("ns", 0, -1);
354 5dd9488c bellard
    TEST_JCC("ns", 0, 0);
355 4d1135e4 bellard
}
356 4d1135e4 bellard
357 4b74fe1f bellard
#undef CC_MASK
358 791c2261 bellard
#ifdef TEST_P4_FLAGS
359 791c2261 bellard
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
360 791c2261 bellard
#else
361 4b74fe1f bellard
#define CC_MASK (CC_O | CC_C)
362 791c2261 bellard
#endif
363 4b74fe1f bellard
364 4b74fe1f bellard
#define OP mul
365 4b74fe1f bellard
#include "test-i386-muldiv.h"
366 4b74fe1f bellard
367 4b74fe1f bellard
#define OP imul
368 4b74fe1f bellard
#include "test-i386-muldiv.h"
369 4b74fe1f bellard
370 4b74fe1f bellard
void test_imulw2(int op0, int op1) 
371 4b74fe1f bellard
{
372 4b74fe1f bellard
    int res, s1, s0, flags;
373 4b74fe1f bellard
    s0 = op0;
374 4b74fe1f bellard
    s1 = op1;
375 4b74fe1f bellard
    res = s0;
376 4b74fe1f bellard
    flags = 0;
377 acae4681 bellard
    asm volatile ("push %4\n\t"
378 4b74fe1f bellard
         "popf\n\t"
379 4b74fe1f bellard
         "imulw %w2, %w0\n\t" 
380 4b74fe1f bellard
         "pushf\n\t"
381 4b74fe1f bellard
         "popl %1\n\t"
382 4b74fe1f bellard
         : "=q" (res), "=g" (flags)
383 4b74fe1f bellard
         : "q" (s1), "0" (res), "1" (flags));
384 4b74fe1f bellard
    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
385 4b74fe1f bellard
           "imulw", s0, s1, res, flags & CC_MASK);
386 4b74fe1f bellard
}
387 4b74fe1f bellard
388 4b74fe1f bellard
void test_imull2(int op0, int op1) 
389 4b74fe1f bellard
{
390 4b74fe1f bellard
    int res, s1, s0, flags;
391 4b74fe1f bellard
    s0 = op0;
392 4b74fe1f bellard
    s1 = op1;
393 4b74fe1f bellard
    res = s0;
394 4b74fe1f bellard
    flags = 0;
395 acae4681 bellard
    asm volatile ("push %4\n\t"
396 4b74fe1f bellard
         "popf\n\t"
397 4b74fe1f bellard
         "imull %2, %0\n\t" 
398 4b74fe1f bellard
         "pushf\n\t"
399 4b74fe1f bellard
         "popl %1\n\t"
400 4b74fe1f bellard
         : "=q" (res), "=g" (flags)
401 4b74fe1f bellard
         : "q" (s1), "0" (res), "1" (flags));
402 4b74fe1f bellard
    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
403 4b74fe1f bellard
           "imull", s0, s1, res, flags & CC_MASK);
404 4b74fe1f bellard
}
405 4b74fe1f bellard
406 b5075d29 bellard
#define TEST_IMUL_IM(size, size1, op0, op1)\
407 b5075d29 bellard
{\
408 b5075d29 bellard
    int res, flags;\
409 b5075d29 bellard
    flags = 0;\
410 b5075d29 bellard
    res = 0;\
411 acae4681 bellard
    asm volatile ("push %3\n\t"\
412 b5075d29 bellard
         "popf\n\t"\
413 b5075d29 bellard
         "imul" size " $" #op0 ", %" size1 "2, %" size1 "0\n\t" \
414 b5075d29 bellard
         "pushf\n\t"\
415 b5075d29 bellard
         "popl %1\n\t"\
416 b5075d29 bellard
         : "=r" (res), "=g" (flags)\
417 b5075d29 bellard
         : "r" (op1), "1" (flags), "0" (res));\
418 b5075d29 bellard
    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",\
419 acae4681 bellard
           "imul" size " im", op0, op1, res, flags & CC_MASK);\
420 b5075d29 bellard
}
421 b5075d29 bellard
422 b5075d29 bellard
423 791c2261 bellard
#undef CC_MASK
424 791c2261 bellard
#define CC_MASK (0)
425 791c2261 bellard
426 791c2261 bellard
#define OP div
427 791c2261 bellard
#include "test-i386-muldiv.h"
428 791c2261 bellard
429 791c2261 bellard
#define OP idiv
430 791c2261 bellard
#include "test-i386-muldiv.h"
431 791c2261 bellard
432 4b74fe1f bellard
void test_mul(void)
433 4b74fe1f bellard
{
434 4b74fe1f bellard
    test_imulb(0x1234561d, 4);
435 4b74fe1f bellard
    test_imulb(3, -4);
436 4b74fe1f bellard
    test_imulb(0x80, 0x80);
437 4b74fe1f bellard
    test_imulb(0x10, 0x10);
438 4b74fe1f bellard
439 4b74fe1f bellard
    test_imulw(0, 0x1234001d, 45);
440 4b74fe1f bellard
    test_imulw(0, 23, -45);
441 4b74fe1f bellard
    test_imulw(0, 0x8000, 0x8000);
442 4b74fe1f bellard
    test_imulw(0, 0x100, 0x100);
443 4b74fe1f bellard
444 4b74fe1f bellard
    test_imull(0, 0x1234001d, 45);
445 4b74fe1f bellard
    test_imull(0, 23, -45);
446 4b74fe1f bellard
    test_imull(0, 0x80000000, 0x80000000);
447 4b74fe1f bellard
    test_imull(0, 0x10000, 0x10000);
448 4b74fe1f bellard
449 4b74fe1f bellard
    test_mulb(0x1234561d, 4);
450 4b74fe1f bellard
    test_mulb(3, -4);
451 4b74fe1f bellard
    test_mulb(0x80, 0x80);
452 4b74fe1f bellard
    test_mulb(0x10, 0x10);
453 4b74fe1f bellard
454 4b74fe1f bellard
    test_mulw(0, 0x1234001d, 45);
455 4b74fe1f bellard
    test_mulw(0, 23, -45);
456 4b74fe1f bellard
    test_mulw(0, 0x8000, 0x8000);
457 4b74fe1f bellard
    test_mulw(0, 0x100, 0x100);
458 4b74fe1f bellard
459 4b74fe1f bellard
    test_mull(0, 0x1234001d, 45);
460 4b74fe1f bellard
    test_mull(0, 23, -45);
461 4b74fe1f bellard
    test_mull(0, 0x80000000, 0x80000000);
462 4b74fe1f bellard
    test_mull(0, 0x10000, 0x10000);
463 4b74fe1f bellard
464 4b74fe1f bellard
    test_imulw2(0x1234001d, 45);
465 4b74fe1f bellard
    test_imulw2(23, -45);
466 4b74fe1f bellard
    test_imulw2(0x8000, 0x8000);
467 4b74fe1f bellard
    test_imulw2(0x100, 0x100);
468 4b74fe1f bellard
469 4b74fe1f bellard
    test_imull2(0x1234001d, 45);
470 4b74fe1f bellard
    test_imull2(23, -45);
471 4b74fe1f bellard
    test_imull2(0x80000000, 0x80000000);
472 4b74fe1f bellard
    test_imull2(0x10000, 0x10000);
473 4b74fe1f bellard
474 b5075d29 bellard
    TEST_IMUL_IM("w", "w", 45, 0x1234);
475 b5075d29 bellard
    TEST_IMUL_IM("w", "w", -45, 23);
476 b5075d29 bellard
    TEST_IMUL_IM("w", "w", 0x8000, 0x80000000);
477 b5075d29 bellard
    TEST_IMUL_IM("w", "w", 0x7fff, 0x1000);
478 b5075d29 bellard
479 b5075d29 bellard
    TEST_IMUL_IM("l", "", 45, 0x1234);
480 b5075d29 bellard
    TEST_IMUL_IM("l", "", -45, 23);
481 b5075d29 bellard
    TEST_IMUL_IM("l", "", 0x8000, 0x80000000);
482 b5075d29 bellard
    TEST_IMUL_IM("l", "", 0x7fff, 0x1000);
483 b5075d29 bellard
484 4b74fe1f bellard
    test_idivb(0x12341678, 0x127e);
485 4b74fe1f bellard
    test_idivb(0x43210123, -5);
486 4b74fe1f bellard
    test_idivb(0x12340004, -1);
487 4b74fe1f bellard
488 4b74fe1f bellard
    test_idivw(0, 0x12345678, 12347);
489 4b74fe1f bellard
    test_idivw(0, -23223, -45);
490 4b74fe1f bellard
    test_idivw(0, 0x12348000, -1);
491 4b74fe1f bellard
    test_idivw(0x12343, 0x12345678, 0x81238567);
492 4b74fe1f bellard
493 4b74fe1f bellard
    test_idivl(0, 0x12345678, 12347);
494 4b74fe1f bellard
    test_idivl(0, -233223, -45);
495 4b74fe1f bellard
    test_idivl(0, 0x80000000, -1);
496 4b74fe1f bellard
    test_idivl(0x12343, 0x12345678, 0x81234567);
497 4b74fe1f bellard
498 4b74fe1f bellard
    test_divb(0x12341678, 0x127e);
499 4b74fe1f bellard
    test_divb(0x43210123, -5);
500 4b74fe1f bellard
    test_divb(0x12340004, -1);
501 4b74fe1f bellard
502 4b74fe1f bellard
    test_divw(0, 0x12345678, 12347);
503 4b74fe1f bellard
    test_divw(0, -23223, -45);
504 4b74fe1f bellard
    test_divw(0, 0x12348000, -1);
505 4b74fe1f bellard
    test_divw(0x12343, 0x12345678, 0x81238567);
506 4b74fe1f bellard
507 4b74fe1f bellard
    test_divl(0, 0x12345678, 12347);
508 4b74fe1f bellard
    test_divl(0, -233223, -45);
509 4b74fe1f bellard
    test_divl(0, 0x80000000, -1);
510 4b74fe1f bellard
    test_divl(0x12343, 0x12345678, 0x81234567);
511 4b74fe1f bellard
}
512 4b74fe1f bellard
513 9d8e9c09 bellard
#define TEST_BSX(op, size, op0)\
514 9d8e9c09 bellard
{\
515 9d8e9c09 bellard
    int res, val, resz;\
516 9d8e9c09 bellard
    val = op0;\
517 7f5e1452 bellard
    asm("xorl %1, %1\n"\
518 7f5e1452 bellard
        "movl $0x12345678, %0\n"\
519 7f5e1452 bellard
        #op " %" size "2, %" size "0 ; setz %b1" \
520 9d8e9c09 bellard
        : "=r" (res), "=q" (resz)\
521 9d8e9c09 bellard
        : "g" (val));\
522 7f5e1452 bellard
    printf("%-10s A=%08x R=%08x %d\n", #op, val, res, resz);\
523 9d8e9c09 bellard
}
524 9d8e9c09 bellard
525 9d8e9c09 bellard
void test_bsx(void)
526 9d8e9c09 bellard
{
527 9d8e9c09 bellard
    TEST_BSX(bsrw, "w", 0);
528 9d8e9c09 bellard
    TEST_BSX(bsrw, "w", 0x12340128);
529 9d8e9c09 bellard
    TEST_BSX(bsrl, "", 0);
530 9d8e9c09 bellard
    TEST_BSX(bsrl, "", 0x00340128);
531 9d8e9c09 bellard
    TEST_BSX(bsfw, "w", 0);
532 9d8e9c09 bellard
    TEST_BSX(bsfw, "w", 0x12340128);
533 9d8e9c09 bellard
    TEST_BSX(bsfl, "", 0);
534 9d8e9c09 bellard
    TEST_BSX(bsfl, "", 0x00340128);
535 9d8e9c09 bellard
}
536 9d8e9c09 bellard
537 55480af8 bellard
/**********************************************/
538 55480af8 bellard
539 9d8e9c09 bellard
void test_fops(double a, double b)
540 9d8e9c09 bellard
{
541 9d8e9c09 bellard
    printf("a=%f b=%f a+b=%f\n", a, b, a + b);
542 9d8e9c09 bellard
    printf("a=%f b=%f a-b=%f\n", a, b, a - b);
543 9d8e9c09 bellard
    printf("a=%f b=%f a*b=%f\n", a, b, a * b);
544 9d8e9c09 bellard
    printf("a=%f b=%f a/b=%f\n", a, b, a / b);
545 9d8e9c09 bellard
    printf("a=%f b=%f fmod(a, b)=%f\n", a, b, fmod(a, b));
546 9d8e9c09 bellard
    printf("a=%f sqrt(a)=%f\n", a, sqrt(a));
547 9d8e9c09 bellard
    printf("a=%f sin(a)=%f\n", a, sin(a));
548 9d8e9c09 bellard
    printf("a=%f cos(a)=%f\n", a, cos(a));
549 9d8e9c09 bellard
    printf("a=%f tan(a)=%f\n", a, tan(a));
550 9d8e9c09 bellard
    printf("a=%f log(a)=%f\n", a, log(a));
551 9d8e9c09 bellard
    printf("a=%f exp(a)=%f\n", a, exp(a));
552 9d8e9c09 bellard
    printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b));
553 9d8e9c09 bellard
    /* just to test some op combining */
554 9d8e9c09 bellard
    printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a)));
555 9d8e9c09 bellard
    printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a)));
556 9d8e9c09 bellard
    printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a)));
557 9d8e9c09 bellard
558 9d8e9c09 bellard
}
559 9d8e9c09 bellard
560 9d8e9c09 bellard
void test_fcmp(double a, double b)
561 9d8e9c09 bellard
{
562 9d8e9c09 bellard
    printf("(%f<%f)=%d\n",
563 9d8e9c09 bellard
           a, b, a < b);
564 9d8e9c09 bellard
    printf("(%f<=%f)=%d\n",
565 9d8e9c09 bellard
           a, b, a <= b);
566 9d8e9c09 bellard
    printf("(%f==%f)=%d\n",
567 9d8e9c09 bellard
           a, b, a == b);
568 9d8e9c09 bellard
    printf("(%f>%f)=%d\n",
569 9d8e9c09 bellard
           a, b, a > b);
570 9d8e9c09 bellard
    printf("(%f<=%f)=%d\n",
571 9d8e9c09 bellard
           a, b, a >= b);
572 03bfca94 bellard
    if (TEST_FCOMI) {
573 03bfca94 bellard
        unsigned int eflags;
574 03bfca94 bellard
        /* test f(u)comi instruction */
575 03bfca94 bellard
        asm("fcomi %2, %1\n"
576 03bfca94 bellard
            "pushf\n"
577 03bfca94 bellard
            "pop %0\n"
578 03bfca94 bellard
            : "=r" (eflags)
579 03bfca94 bellard
            : "t" (a), "u" (b));
580 03bfca94 bellard
        printf("fcomi(%f %f)=%08x\n", a, b, eflags & (CC_Z | CC_P | CC_C));
581 03bfca94 bellard
    }
582 9d8e9c09 bellard
}
583 9d8e9c09 bellard
584 9d8e9c09 bellard
void test_fcvt(double a)
585 9d8e9c09 bellard
{
586 9d8e9c09 bellard
    float fa;
587 9d8e9c09 bellard
    long double la;
588 ea768640 bellard
    int16_t fpuc;
589 ea768640 bellard
    int i;
590 ea768640 bellard
    int64_t lla;
591 ea768640 bellard
    int ia;
592 ea768640 bellard
    int16_t wa;
593 ea768640 bellard
    double ra;
594 9d8e9c09 bellard
595 9d8e9c09 bellard
    fa = a;
596 9d8e9c09 bellard
    la = a;
597 9d8e9c09 bellard
    printf("(float)%f = %f\n", a, fa);
598 9d8e9c09 bellard
    printf("(long double)%f = %Lf\n", a, la);
599 c5e9815d bellard
    printf("a=%016Lx\n", *(long long *)&a);
600 c5e9815d bellard
    printf("la=%016Lx %04x\n", *(long long *)&la, 
601 c5e9815d bellard
           *(unsigned short *)((char *)(&la) + 8));
602 ea768640 bellard
603 ea768640 bellard
    /* test all roundings */
604 ea768640 bellard
    asm volatile ("fstcw %0" : "=m" (fpuc));
605 ea768640 bellard
    for(i=0;i<4;i++) {
606 ea768640 bellard
        asm volatile ("fldcw %0" : : "m" ((fpuc & ~0x0c00) | (i << 10)));
607 ea768640 bellard
        asm volatile ("fist %0" : "=m" (wa) : "t" (a));
608 ea768640 bellard
        asm volatile ("fistl %0" : "=m" (ia) : "t" (a));
609 ea768640 bellard
        asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st");
610 ea768640 bellard
        asm volatile ("frndint ; fstl %0" : "=m" (ra) : "t" (a));
611 ea768640 bellard
        asm volatile ("fldcw %0" : : "m" (fpuc));
612 ea768640 bellard
        printf("(short)a = %d\n", wa);
613 ea768640 bellard
        printf("(int)a = %d\n", ia);
614 ea768640 bellard
        printf("(int64_t)a = %Ld\n", lla);
615 ea768640 bellard
        printf("rint(a) = %f\n", ra);
616 ea768640 bellard
    }
617 9d8e9c09 bellard
}
618 9d8e9c09 bellard
619 9d8e9c09 bellard
#define TEST(N) \
620 9d8e9c09 bellard
    asm("fld" #N : "=t" (a)); \
621 9d8e9c09 bellard
    printf("fld" #N "= %f\n", a);
622 9d8e9c09 bellard
623 9d8e9c09 bellard
void test_fconst(void)
624 9d8e9c09 bellard
{
625 9d8e9c09 bellard
    double a;
626 9d8e9c09 bellard
    TEST(1);
627 9d8e9c09 bellard
    TEST(l2t);
628 9d8e9c09 bellard
    TEST(l2e);
629 9d8e9c09 bellard
    TEST(pi);
630 9d8e9c09 bellard
    TEST(lg2);
631 9d8e9c09 bellard
    TEST(ln2);
632 9d8e9c09 bellard
    TEST(z);
633 9d8e9c09 bellard
}
634 9d8e9c09 bellard
635 c5e9815d bellard
void test_fbcd(double a)
636 c5e9815d bellard
{
637 c5e9815d bellard
    unsigned short bcd[5];
638 c5e9815d bellard
    double b;
639 c5e9815d bellard
640 c5e9815d bellard
    asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
641 c5e9815d bellard
    asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
642 c5e9815d bellard
    printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n", 
643 c5e9815d bellard
           a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
644 c5e9815d bellard
}
645 c5e9815d bellard
646 6b2b6112 bellard
#define TEST_ENV(env, save, restore)\
647 03bfca94 bellard
{\
648 03bfca94 bellard
    memset((env), 0xaa, sizeof(*(env)));\
649 6b2b6112 bellard
    for(i=0;i<5;i++)\
650 6b2b6112 bellard
        asm volatile ("fldl %0" : : "m" (dtab[i]));\
651 085339a1 bellard
    asm volatile (save " %0\n" : : "m" (*(env)));\
652 085339a1 bellard
    asm volatile (restore " %0\n": : "m" (*(env)));\
653 6b2b6112 bellard
    for(i=0;i<5;i++)\
654 6b2b6112 bellard
        asm volatile ("fstpl %0" : "=m" (rtab[i]));\
655 6b2b6112 bellard
    for(i=0;i<5;i++)\
656 6b2b6112 bellard
        printf("res[%d]=%f\n", i, rtab[i]);\
657 03bfca94 bellard
    printf("fpuc=%04x fpus=%04x fptag=%04x\n",\
658 03bfca94 bellard
           (env)->fpuc,\
659 03bfca94 bellard
           (env)->fpus & 0xff00,\
660 03bfca94 bellard
           (env)->fptag);\
661 03bfca94 bellard
}
662 03bfca94 bellard
663 03bfca94 bellard
void test_fenv(void)
664 03bfca94 bellard
{
665 03bfca94 bellard
    struct __attribute__((packed)) {
666 03bfca94 bellard
        uint16_t fpuc;
667 03bfca94 bellard
        uint16_t dummy1;
668 03bfca94 bellard
        uint16_t fpus;
669 03bfca94 bellard
        uint16_t dummy2;
670 03bfca94 bellard
        uint16_t fptag;
671 03bfca94 bellard
        uint16_t dummy3;
672 03bfca94 bellard
        uint32_t ignored[4];
673 03bfca94 bellard
        long double fpregs[8];
674 03bfca94 bellard
    } float_env32;
675 03bfca94 bellard
    struct __attribute__((packed)) {
676 03bfca94 bellard
        uint16_t fpuc;
677 03bfca94 bellard
        uint16_t fpus;
678 03bfca94 bellard
        uint16_t fptag;
679 03bfca94 bellard
        uint16_t ignored[4];
680 03bfca94 bellard
        long double fpregs[8];
681 03bfca94 bellard
    } float_env16;
682 6b2b6112 bellard
    double dtab[8];
683 6b2b6112 bellard
    double rtab[8];
684 6b2b6112 bellard
    int i;
685 6b2b6112 bellard
686 6b2b6112 bellard
    for(i=0;i<8;i++)
687 6b2b6112 bellard
        dtab[i] = i + 1;
688 03bfca94 bellard
689 6b2b6112 bellard
    TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv");
690 6b2b6112 bellard
    TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor");
691 6b2b6112 bellard
    TEST_ENV(&float_env32, "fnstenv", "fldenv");
692 6b2b6112 bellard
    TEST_ENV(&float_env32, "fnsave", "frstor");
693 665656a9 bellard
694 665656a9 bellard
    /* test for ffree */
695 665656a9 bellard
    for(i=0;i<5;i++)
696 665656a9 bellard
        asm volatile ("fldl %0" : : "m" (dtab[i]));
697 665656a9 bellard
    asm volatile("ffree %st(2)");
698 665656a9 bellard
    asm volatile ("fnstenv %0\n" : : "m" (float_env32));
699 665656a9 bellard
    asm volatile ("fninit");
700 665656a9 bellard
    printf("fptag=%04x\n", float_env32.fptag);
701 03bfca94 bellard
}
702 03bfca94 bellard
703 75175024 bellard
704 75175024 bellard
#define TEST_FCMOV(a, b, eflags, CC)\
705 75175024 bellard
{\
706 75175024 bellard
    double res;\
707 75175024 bellard
    asm("push %3\n"\
708 75175024 bellard
        "popf\n"\
709 75175024 bellard
        "fcmov" CC " %2, %0\n"\
710 75175024 bellard
        : "=t" (res)\
711 75175024 bellard
        : "0" (a), "u" (b), "g" (eflags));\
712 75175024 bellard
    printf("fcmov%s eflags=0x%04x-> %f\n", \
713 75175024 bellard
           CC, eflags, res);\
714 75175024 bellard
}
715 75175024 bellard
716 75175024 bellard
void test_fcmov(void)
717 75175024 bellard
{
718 75175024 bellard
    double a, b;
719 75175024 bellard
    int eflags, i;
720 75175024 bellard
721 75175024 bellard
    a = 1.0;
722 75175024 bellard
    b = 2.0;
723 75175024 bellard
    for(i = 0; i < 4; i++) {
724 75175024 bellard
        eflags = 0;
725 75175024 bellard
        if (i & 1)
726 75175024 bellard
            eflags |= CC_C;
727 75175024 bellard
        if (i & 2)
728 75175024 bellard
            eflags |= CC_Z;
729 75175024 bellard
        TEST_FCMOV(a, b, eflags, "b");
730 75175024 bellard
        TEST_FCMOV(a, b, eflags, "e");
731 75175024 bellard
        TEST_FCMOV(a, b, eflags, "be");
732 75175024 bellard
        TEST_FCMOV(a, b, eflags, "nb");
733 75175024 bellard
        TEST_FCMOV(a, b, eflags, "ne");
734 75175024 bellard
        TEST_FCMOV(a, b, eflags, "nbe");
735 75175024 bellard
    }
736 75175024 bellard
    TEST_FCMOV(a, b, 0, "u");
737 9cdf757f bellard
    TEST_FCMOV(a, b, CC_P, "u");
738 9cdf757f bellard
    TEST_FCMOV(a, b, 0, "nu");
739 75175024 bellard
    TEST_FCMOV(a, b, CC_P, "nu");
740 75175024 bellard
}
741 75175024 bellard
742 9d8e9c09 bellard
void test_floats(void)
743 9d8e9c09 bellard
{
744 9d8e9c09 bellard
    test_fops(2, 3);
745 9d8e9c09 bellard
    test_fops(1.4, -5);
746 9d8e9c09 bellard
    test_fcmp(2, -1);
747 9d8e9c09 bellard
    test_fcmp(2, 2);
748 9d8e9c09 bellard
    test_fcmp(2, 3);
749 ea768640 bellard
    test_fcvt(0.5);
750 ea768640 bellard
    test_fcvt(-0.5);
751 9d8e9c09 bellard
    test_fcvt(1.0/7.0);
752 9d8e9c09 bellard
    test_fcvt(-1.0/9.0);
753 ea768640 bellard
    test_fcvt(32768);
754 ea768640 bellard
    test_fcvt(-1e20);
755 9d8e9c09 bellard
    test_fconst();
756 c5e9815d bellard
    test_fbcd(1234567890123456);
757 c5e9815d bellard
    test_fbcd(-123451234567890);
758 03bfca94 bellard
    test_fenv();
759 75175024 bellard
    if (TEST_CMOV) {
760 75175024 bellard
        test_fcmov();
761 75175024 bellard
    }
762 9d8e9c09 bellard
}
763 4b74fe1f bellard
764 55480af8 bellard
/**********************************************/
765 55480af8 bellard
766 55480af8 bellard
#define TEST_BCD(op, op0, cc_in, cc_mask)\
767 55480af8 bellard
{\
768 55480af8 bellard
    int res, flags;\
769 55480af8 bellard
    res = op0;\
770 55480af8 bellard
    flags = cc_in;\
771 55480af8 bellard
    asm ("push %3\n\t"\
772 55480af8 bellard
         "popf\n\t"\
773 55480af8 bellard
         #op "\n\t"\
774 55480af8 bellard
         "pushf\n\t"\
775 55480af8 bellard
         "popl %1\n\t"\
776 55480af8 bellard
        : "=a" (res), "=g" (flags)\
777 55480af8 bellard
        : "0" (res), "1" (flags));\
778 55480af8 bellard
    printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\
779 55480af8 bellard
           #op, op0, res, cc_in, flags & cc_mask);\
780 55480af8 bellard
}
781 55480af8 bellard
782 55480af8 bellard
void test_bcd(void)
783 55480af8 bellard
{
784 55480af8 bellard
    TEST_BCD(daa, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
785 55480af8 bellard
    TEST_BCD(daa, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
786 55480af8 bellard
    TEST_BCD(daa, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
787 55480af8 bellard
    TEST_BCD(daa, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
788 55480af8 bellard
    TEST_BCD(daa, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
789 55480af8 bellard
    TEST_BCD(daa, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
790 55480af8 bellard
    TEST_BCD(daa, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
791 55480af8 bellard
    TEST_BCD(daa, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
792 55480af8 bellard
    TEST_BCD(daa, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
793 55480af8 bellard
    TEST_BCD(daa, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
794 55480af8 bellard
    TEST_BCD(daa, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
795 55480af8 bellard
    TEST_BCD(daa, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
796 55480af8 bellard
    TEST_BCD(daa, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
797 55480af8 bellard
798 55480af8 bellard
    TEST_BCD(das, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
799 55480af8 bellard
    TEST_BCD(das, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
800 55480af8 bellard
    TEST_BCD(das, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
801 55480af8 bellard
    TEST_BCD(das, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
802 55480af8 bellard
    TEST_BCD(das, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
803 55480af8 bellard
    TEST_BCD(das, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
804 55480af8 bellard
    TEST_BCD(das, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
805 55480af8 bellard
    TEST_BCD(das, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
806 55480af8 bellard
    TEST_BCD(das, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
807 55480af8 bellard
    TEST_BCD(das, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
808 55480af8 bellard
    TEST_BCD(das, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
809 55480af8 bellard
    TEST_BCD(das, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
810 55480af8 bellard
    TEST_BCD(das, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
811 55480af8 bellard
812 55480af8 bellard
    TEST_BCD(aaa, 0x12340205, CC_A, (CC_C | CC_A));
813 55480af8 bellard
    TEST_BCD(aaa, 0x12340306, CC_A, (CC_C | CC_A));
814 55480af8 bellard
    TEST_BCD(aaa, 0x1234040a, CC_A, (CC_C | CC_A));
815 55480af8 bellard
    TEST_BCD(aaa, 0x123405fa, CC_A, (CC_C | CC_A));
816 55480af8 bellard
    TEST_BCD(aaa, 0x12340205, 0, (CC_C | CC_A));
817 55480af8 bellard
    TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A));
818 55480af8 bellard
    TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A));
819 55480af8 bellard
    TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A));
820 55480af8 bellard
    
821 55480af8 bellard
    TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A));
822 55480af8 bellard
    TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A));
823 55480af8 bellard
    TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A));
824 55480af8 bellard
    TEST_BCD(aas, 0x123405fa, CC_A, (CC_C | CC_A));
825 55480af8 bellard
    TEST_BCD(aas, 0x12340205, 0, (CC_C | CC_A));
826 55480af8 bellard
    TEST_BCD(aas, 0x12340306, 0, (CC_C | CC_A));
827 55480af8 bellard
    TEST_BCD(aas, 0x1234040a, 0, (CC_C | CC_A));
828 55480af8 bellard
    TEST_BCD(aas, 0x123405fa, 0, (CC_C | CC_A));
829 55480af8 bellard
830 55480af8 bellard
    TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
831 55480af8 bellard
    TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
832 55480af8 bellard
}
833 55480af8 bellard
834 e5918247 bellard
#define TEST_XCHG(op, size, opconst)\
835 e5918247 bellard
{\
836 e5918247 bellard
    int op0, op1;\
837 e5918247 bellard
    op0 = 0x12345678;\
838 e5918247 bellard
    op1 = 0xfbca7654;\
839 e5918247 bellard
    asm(#op " %" size "0, %" size "1" \
840 e5918247 bellard
        : "=q" (op0), opconst (op1) \
841 e5918247 bellard
        : "0" (op0), "1" (op1));\
842 e5918247 bellard
    printf("%-10s A=%08x B=%08x\n",\
843 e5918247 bellard
           #op, op0, op1);\
844 e5918247 bellard
}
845 e5918247 bellard
846 e5918247 bellard
#define TEST_CMPXCHG(op, size, opconst, eax)\
847 e5918247 bellard
{\
848 e5918247 bellard
    int op0, op1;\
849 e5918247 bellard
    op0 = 0x12345678;\
850 e5918247 bellard
    op1 = 0xfbca7654;\
851 e5918247 bellard
    asm(#op " %" size "0, %" size "1" \
852 e5918247 bellard
        : "=q" (op0), opconst (op1) \
853 e5918247 bellard
        : "0" (op0), "1" (op1), "a" (eax));\
854 e5918247 bellard
    printf("%-10s EAX=%08x A=%08x C=%08x\n",\
855 e5918247 bellard
           #op, eax, op0, op1);\
856 e5918247 bellard
}
857 e5918247 bellard
858 e5918247 bellard
void test_xchg(void)
859 e5918247 bellard
{
860 e5918247 bellard
    TEST_XCHG(xchgl, "", "=q");
861 e5918247 bellard
    TEST_XCHG(xchgw, "w", "=q");
862 e5918247 bellard
    TEST_XCHG(xchgb, "b", "=q");
863 e5918247 bellard
864 e5918247 bellard
    TEST_XCHG(xchgl, "", "=m");
865 e5918247 bellard
    TEST_XCHG(xchgw, "w", "=m");
866 e5918247 bellard
    TEST_XCHG(xchgb, "b", "=m");
867 e5918247 bellard
868 e5918247 bellard
    TEST_XCHG(xaddl, "", "=q");
869 e5918247 bellard
    TEST_XCHG(xaddw, "w", "=q");
870 e5918247 bellard
    TEST_XCHG(xaddb, "b", "=q");
871 e5918247 bellard
872 d575b78a bellard
    {
873 d575b78a bellard
        int res;
874 d575b78a bellard
        res = 0x12345678;
875 d575b78a bellard
        asm("xaddl %1, %0" : "=r" (res) : "0" (res));
876 d575b78a bellard
        printf("xaddl same res=%08x\n", res);
877 d575b78a bellard
    }
878 d575b78a bellard
879 e5918247 bellard
    TEST_XCHG(xaddl, "", "=m");
880 e5918247 bellard
    TEST_XCHG(xaddw, "w", "=m");
881 e5918247 bellard
    TEST_XCHG(xaddb, "b", "=m");
882 e5918247 bellard
883 e5918247 bellard
    TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654);
884 e5918247 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654);
885 e5918247 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654);
886 e5918247 bellard
887 e5918247 bellard
    TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc);
888 e5918247 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc);
889 e5918247 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc);
890 e5918247 bellard
891 e5918247 bellard
    TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfbca7654);
892 e5918247 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654);
893 e5918247 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654);
894 e5918247 bellard
895 e5918247 bellard
    TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfffefdfc);
896 e5918247 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc);
897 e5918247 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc);
898 d575b78a bellard
899 d575b78a bellard
    {
900 d575b78a bellard
        uint64_t op0, op1, op2;
901 d575b78a bellard
        int i, eflags;
902 d575b78a bellard
903 d575b78a bellard
        for(i = 0; i < 2; i++) {
904 d575b78a bellard
            op0 = 0x123456789abcd;
905 d575b78a bellard
            if (i == 0)
906 d575b78a bellard
                op1 = 0xfbca765423456;
907 d575b78a bellard
            else
908 d575b78a bellard
                op1 = op0;
909 d575b78a bellard
            op2 = 0x6532432432434;
910 d575b78a bellard
            asm("cmpxchg8b %1\n" 
911 d575b78a bellard
                "pushf\n"
912 d575b78a bellard
                "popl %2\n"
913 d575b78a bellard
                : "=A" (op0), "=m" (op1), "=g" (eflags)
914 d575b78a bellard
                : "0" (op0), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32)));
915 d575b78a bellard
            printf("cmpxchg8b: op0=%016llx op1=%016llx CC=%02x\n", 
916 d575b78a bellard
                    op0, op1, eflags & CC_Z);
917 d575b78a bellard
        }
918 d575b78a bellard
    }
919 e5918247 bellard
}
920 e5918247 bellard
921 6dbad63e bellard
/**********************************************/
922 6dbad63e bellard
/* segmentation tests */
923 6dbad63e bellard
924 6dbad63e bellard
#include <asm/ldt.h>
925 6dbad63e bellard
#include <linux/unistd.h>
926 73bdea19 bellard
#include <linux/version.h>
927 6dbad63e bellard
928 6dbad63e bellard
_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
929 6dbad63e bellard
930 73bdea19 bellard
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
931 73bdea19 bellard
#define modify_ldt_ldt_s user_desc
932 73bdea19 bellard
#endif
933 73bdea19 bellard
934 6dbad63e bellard
uint8_t seg_data1[4096];
935 6dbad63e bellard
uint8_t seg_data2[4096];
936 6dbad63e bellard
937 e5918247 bellard
#define MK_SEL(n) (((n) << 3) | 7)
938 6dbad63e bellard
939 288426fe bellard
#define TEST_LR(op, size, seg, mask)\
940 288426fe bellard
{\
941 288426fe bellard
    int res, res2;\
942 288426fe bellard
    res = 0x12345678;\
943 288426fe bellard
    asm (op " %" size "2, %" size "0\n" \
944 288426fe bellard
         "movl $0, %1\n"\
945 288426fe bellard
         "jnz 1f\n"\
946 288426fe bellard
         "movl $1, %1\n"\
947 288426fe bellard
         "1:\n"\
948 288426fe bellard
         : "=r" (res), "=r" (res2) : "m" (seg), "0" (res));\
949 288426fe bellard
    printf(op ": Z=%d %08x\n", res2, res & ~(mask));\
950 288426fe bellard
}
951 288426fe bellard
952 6dbad63e bellard
/* NOTE: we use Linux modify_ldt syscall */
953 6dbad63e bellard
void test_segs(void)
954 6dbad63e bellard
{
955 6dbad63e bellard
    struct modify_ldt_ldt_s ldt;
956 6dbad63e bellard
    long long ldt_table[3];
957 04369ff2 bellard
    int res, res2;
958 6dbad63e bellard
    char tmp;
959 e1d4294a bellard
    struct {
960 e1d4294a bellard
        uint32_t offset;
961 e1d4294a bellard
        uint16_t seg;
962 e1d4294a bellard
    } __attribute__((packed)) segoff;
963 6dbad63e bellard
964 6dbad63e bellard
    ldt.entry_number = 1;
965 6dbad63e bellard
    ldt.base_addr = (unsigned long)&seg_data1;
966 6dbad63e bellard
    ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
967 6dbad63e bellard
    ldt.seg_32bit = 1;
968 6dbad63e bellard
    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
969 6dbad63e bellard
    ldt.read_exec_only = 0;
970 6dbad63e bellard
    ldt.limit_in_pages = 1;
971 6dbad63e bellard
    ldt.seg_not_present = 0;
972 6dbad63e bellard
    ldt.useable = 1;
973 6dbad63e bellard
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
974 6dbad63e bellard
975 6dbad63e bellard
    ldt.entry_number = 2;
976 6dbad63e bellard
    ldt.base_addr = (unsigned long)&seg_data2;
977 6dbad63e bellard
    ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12;
978 6dbad63e bellard
    ldt.seg_32bit = 1;
979 6dbad63e bellard
    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
980 6dbad63e bellard
    ldt.read_exec_only = 0;
981 6dbad63e bellard
    ldt.limit_in_pages = 1;
982 6dbad63e bellard
    ldt.seg_not_present = 0;
983 6dbad63e bellard
    ldt.useable = 1;
984 6dbad63e bellard
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
985 6dbad63e bellard
986 6dbad63e bellard
    modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */
987 04369ff2 bellard
#if 0
988 04369ff2 bellard
    {
989 04369ff2 bellard
        int i;
990 04369ff2 bellard
        for(i=0;i<3;i++)
991 04369ff2 bellard
            printf("%d: %016Lx\n", i, ldt_table[i]);
992 04369ff2 bellard
    }
993 04369ff2 bellard
#endif
994 6dbad63e bellard
    /* do some tests with fs or gs */
995 6dbad63e bellard
    asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
996 6dbad63e bellard
997 6dbad63e bellard
    seg_data1[1] = 0xaa;
998 6dbad63e bellard
    seg_data2[1] = 0x55;
999 6dbad63e bellard
1000 6dbad63e bellard
    asm volatile ("fs movzbl 0x1, %0" : "=r" (res));
1001 6dbad63e bellard
    printf("FS[1] = %02x\n", res);
1002 6dbad63e bellard
1003 070893f4 bellard
    asm volatile ("pushl %%gs\n"
1004 070893f4 bellard
                  "movl %1, %%gs\n"
1005 070893f4 bellard
                  "gs movzbl 0x1, %0\n"
1006 070893f4 bellard
                  "popl %%gs\n"
1007 070893f4 bellard
                  : "=r" (res)
1008 070893f4 bellard
                  : "r" (MK_SEL(2)));
1009 6dbad63e bellard
    printf("GS[1] = %02x\n", res);
1010 6dbad63e bellard
1011 6dbad63e bellard
    /* tests with ds/ss (implicit segment case) */
1012 6dbad63e bellard
    tmp = 0xa5;
1013 6dbad63e bellard
    asm volatile ("pushl %%ebp\n\t"
1014 6dbad63e bellard
                  "pushl %%ds\n\t"
1015 6dbad63e bellard
                  "movl %2, %%ds\n\t"
1016 6dbad63e bellard
                  "movl %3, %%ebp\n\t"
1017 6dbad63e bellard
                  "movzbl 0x1, %0\n\t"
1018 6dbad63e bellard
                  "movzbl (%%ebp), %1\n\t"
1019 6dbad63e bellard
                  "popl %%ds\n\t"
1020 6dbad63e bellard
                  "popl %%ebp\n\t"
1021 6dbad63e bellard
                  : "=r" (res), "=r" (res2)
1022 6dbad63e bellard
                  : "r" (MK_SEL(1)), "r" (&tmp));
1023 6dbad63e bellard
    printf("DS[1] = %02x\n", res);
1024 6dbad63e bellard
    printf("SS[tmp] = %02x\n", res2);
1025 e1d4294a bellard
1026 e1d4294a bellard
    segoff.seg = MK_SEL(2);
1027 e1d4294a bellard
    segoff.offset = 0xabcdef12;
1028 e1d4294a bellard
    asm volatile("lfs %2, %0\n\t" 
1029 e1d4294a bellard
                 "movl %%fs, %1\n\t"
1030 e1d4294a bellard
                 : "=r" (res), "=g" (res2) 
1031 e1d4294a bellard
                 : "m" (segoff));
1032 e1d4294a bellard
    printf("FS:reg = %04x:%08x\n", res2, res);
1033 288426fe bellard
1034 288426fe bellard
    TEST_LR("larw", "w", MK_SEL(2), 0x0100);
1035 288426fe bellard
    TEST_LR("larl", "", MK_SEL(2), 0x0100);
1036 288426fe bellard
    TEST_LR("lslw", "w", MK_SEL(2), 0);
1037 288426fe bellard
    TEST_LR("lsll", "", MK_SEL(2), 0);
1038 288426fe bellard
1039 288426fe bellard
    TEST_LR("larw", "w", 0xfff8, 0);
1040 288426fe bellard
    TEST_LR("larl", "", 0xfff8, 0);
1041 288426fe bellard
    TEST_LR("lslw", "w", 0xfff8, 0);
1042 288426fe bellard
    TEST_LR("lsll", "", 0xfff8, 0);
1043 6dbad63e bellard
}
1044 55480af8 bellard
1045 e5918247 bellard
/* 16 bit code test */
1046 e5918247 bellard
extern char code16_start, code16_end;
1047 e5918247 bellard
extern char code16_func1;
1048 e5918247 bellard
extern char code16_func2;
1049 e5918247 bellard
extern char code16_func3;
1050 a300e691 bellard
1051 e5918247 bellard
void test_code16(void)
1052 1a9353d2 bellard
{
1053 e5918247 bellard
    struct modify_ldt_ldt_s ldt;
1054 e5918247 bellard
    int res, res2;
1055 a300e691 bellard
1056 e5918247 bellard
    /* build a code segment */
1057 e5918247 bellard
    ldt.entry_number = 1;
1058 e5918247 bellard
    ldt.base_addr = (unsigned long)&code16_start;
1059 e5918247 bellard
    ldt.limit = &code16_end - &code16_start;
1060 e5918247 bellard
    ldt.seg_32bit = 0;
1061 e5918247 bellard
    ldt.contents = MODIFY_LDT_CONTENTS_CODE;
1062 e5918247 bellard
    ldt.read_exec_only = 0;
1063 e5918247 bellard
    ldt.limit_in_pages = 0;
1064 e5918247 bellard
    ldt.seg_not_present = 0;
1065 e5918247 bellard
    ldt.useable = 1;
1066 e5918247 bellard
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
1067 a300e691 bellard
1068 e5918247 bellard
    /* call the first function */
1069 e5918247 bellard
    asm volatile ("lcall %1, %2" 
1070 e5918247 bellard
                  : "=a" (res)
1071 e5918247 bellard
                  : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc");
1072 e5918247 bellard
    printf("func1() = 0x%08x\n", res);
1073 e5918247 bellard
    asm volatile ("lcall %2, %3" 
1074 e5918247 bellard
                  : "=a" (res), "=c" (res2)
1075 e5918247 bellard
                  : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc");
1076 e5918247 bellard
    printf("func2() = 0x%08x spdec=%d\n", res, res2);
1077 e5918247 bellard
    asm volatile ("lcall %1, %2" 
1078 e5918247 bellard
                  : "=a" (res)
1079 e5918247 bellard
                  : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc");
1080 e5918247 bellard
    printf("func3() = 0x%08x\n", res);
1081 1a9353d2 bellard
}
1082 1a9353d2 bellard
1083 dd3587f3 bellard
extern char func_lret32;
1084 dd3587f3 bellard
extern char func_iret32;
1085 dd3587f3 bellard
1086 e1d4294a bellard
void test_misc(void)
1087 e1d4294a bellard
{
1088 e1d4294a bellard
    char table[256];
1089 e1d4294a bellard
    int res, i;
1090 e1d4294a bellard
1091 e1d4294a bellard
    for(i=0;i<256;i++) table[i] = 256 - i;
1092 e1d4294a bellard
    res = 0x12345678;
1093 e1d4294a bellard
    asm ("xlat" : "=a" (res) : "b" (table), "0" (res));
1094 e1d4294a bellard
    printf("xlat: EAX=%08x\n", res);
1095 dd3587f3 bellard
1096 dd3587f3 bellard
    asm volatile ("pushl %%cs ; call %1" 
1097 dd3587f3 bellard
                  : "=a" (res)
1098 dd3587f3 bellard
                  : "m" (func_lret32): "memory", "cc");
1099 dd3587f3 bellard
    printf("func_lret32=%x\n", res);
1100 dd3587f3 bellard
1101 dd3587f3 bellard
    asm volatile ("pushfl ; pushl %%cs ; call %1" 
1102 dd3587f3 bellard
                  : "=a" (res)
1103 dd3587f3 bellard
                  : "m" (func_iret32): "memory", "cc");
1104 dd3587f3 bellard
    printf("func_iret32=%x\n", res);
1105 dd3587f3 bellard
1106 dd3587f3 bellard
    /* specific popl test */
1107 dd3587f3 bellard
    asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popl (%%esp) ; popl %0"
1108 dd3587f3 bellard
                  : "=g" (res));
1109 dd3587f3 bellard
    printf("popl esp=%x\n", res);
1110 b2b5fb22 bellard
1111 b2b5fb22 bellard
    /* specific popw test */
1112 b2b5fb22 bellard
    asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popw (%%esp) ; addl $2, %%esp ; popl %0"
1113 b2b5fb22 bellard
                  : "=g" (res));
1114 b2b5fb22 bellard
    printf("popw esp=%x\n", res);
1115 e1d4294a bellard
}
1116 e1d4294a bellard
1117 e1d4294a bellard
uint8_t str_buffer[4096];
1118 e1d4294a bellard
1119 e1d4294a bellard
#define TEST_STRING1(OP, size, DF, REP)\
1120 e1d4294a bellard
{\
1121 e1d4294a bellard
    int esi, edi, eax, ecx, eflags;\
1122 e1d4294a bellard
\
1123 e1d4294a bellard
    esi = (long)(str_buffer + sizeof(str_buffer) / 2);\
1124 e1d4294a bellard
    edi = (long)(str_buffer + sizeof(str_buffer) / 2) + 16;\
1125 e1d4294a bellard
    eax = 0x12345678;\
1126 e1d4294a bellard
    ecx = 17;\
1127 e1d4294a bellard
\
1128 e1d4294a bellard
    asm volatile ("pushl $0\n\t"\
1129 e1d4294a bellard
                  "popf\n\t"\
1130 e1d4294a bellard
                  DF "\n\t"\
1131 e1d4294a bellard
                  REP #OP size "\n\t"\
1132 e1d4294a bellard
                  "cld\n\t"\
1133 e1d4294a bellard
                  "pushf\n\t"\
1134 e1d4294a bellard
                  "popl %4\n\t"\
1135 e1d4294a bellard
                  : "=S" (esi), "=D" (edi), "=a" (eax), "=c" (ecx), "=g" (eflags)\
1136 e1d4294a bellard
                  : "0" (esi), "1" (edi), "2" (eax), "3" (ecx));\
1137 e1d4294a bellard
    printf("%-10s ESI=%08x EDI=%08x EAX=%08x ECX=%08x EFL=%04x\n",\
1138 e1d4294a bellard
           REP #OP size, esi, edi, eax, ecx,\
1139 e1d4294a bellard
           eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\
1140 e1d4294a bellard
}
1141 e1d4294a bellard
1142 e1d4294a bellard
#define TEST_STRING(OP, REP)\
1143 e1d4294a bellard
    TEST_STRING1(OP, "b", "", REP);\
1144 e1d4294a bellard
    TEST_STRING1(OP, "w", "", REP);\
1145 e1d4294a bellard
    TEST_STRING1(OP, "l", "", REP);\
1146 e1d4294a bellard
    TEST_STRING1(OP, "b", "std", REP);\
1147 e1d4294a bellard
    TEST_STRING1(OP, "w", "std", REP);\
1148 e1d4294a bellard
    TEST_STRING1(OP, "l", "std", REP)
1149 e1d4294a bellard
1150 e1d4294a bellard
void test_string(void)
1151 e1d4294a bellard
{
1152 e1d4294a bellard
    int i;
1153 e1d4294a bellard
    for(i = 0;i < sizeof(str_buffer); i++)
1154 e1d4294a bellard
        str_buffer[i] = i + 0x56;
1155 e1d4294a bellard
   TEST_STRING(stos, "");
1156 e1d4294a bellard
   TEST_STRING(stos, "rep ");
1157 e1d4294a bellard
   TEST_STRING(lods, ""); /* to verify stos */
1158 e1d4294a bellard
   TEST_STRING(lods, "rep "); 
1159 e1d4294a bellard
   TEST_STRING(movs, "");
1160 e1d4294a bellard
   TEST_STRING(movs, "rep ");
1161 e1d4294a bellard
   TEST_STRING(lods, ""); /* to verify stos */
1162 e1d4294a bellard
1163 e1d4294a bellard
   /* XXX: better tests */
1164 e1d4294a bellard
   TEST_STRING(scas, "");
1165 e1d4294a bellard
   TEST_STRING(scas, "repz ");
1166 e1d4294a bellard
   TEST_STRING(scas, "repnz ");
1167 e1d4294a bellard
   TEST_STRING(cmps, "");
1168 e1d4294a bellard
   TEST_STRING(cmps, "repz ");
1169 e1d4294a bellard
   TEST_STRING(cmps, "repnz ");
1170 e1d4294a bellard
}
1171 e5918247 bellard
1172 3a27ad0b bellard
/* VM86 test */
1173 3a27ad0b bellard
1174 3a27ad0b bellard
static inline void set_bit(uint8_t *a, unsigned int bit)
1175 3a27ad0b bellard
{
1176 3a27ad0b bellard
    a[bit / 8] |= (1 << (bit % 8));
1177 3a27ad0b bellard
}
1178 3a27ad0b bellard
1179 3a27ad0b bellard
static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
1180 3a27ad0b bellard
{
1181 3a27ad0b bellard
    return (uint8_t *)((seg << 4) + (reg & 0xffff));
1182 3a27ad0b bellard
}
1183 3a27ad0b bellard
1184 3a27ad0b bellard
static inline void pushw(struct vm86_regs *r, int val)
1185 3a27ad0b bellard
{
1186 3a27ad0b bellard
    r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff);
1187 3a27ad0b bellard
    *(uint16_t *)seg_to_linear(r->ss, r->esp) = val;
1188 3a27ad0b bellard
}
1189 3a27ad0b bellard
1190 3a27ad0b bellard
#undef __syscall_return
1191 3a27ad0b bellard
#define __syscall_return(type, res) \
1192 3a27ad0b bellard
do { \
1193 3a27ad0b bellard
        return (type) (res); \
1194 3a27ad0b bellard
} while (0)
1195 3a27ad0b bellard
1196 3a27ad0b bellard
_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86)
1197 3a27ad0b bellard
1198 3a27ad0b bellard
extern char vm86_code_start;
1199 3a27ad0b bellard
extern char vm86_code_end;
1200 3a27ad0b bellard
1201 3a27ad0b bellard
#define VM86_CODE_CS 0x100
1202 3a27ad0b bellard
#define VM86_CODE_IP 0x100
1203 3a27ad0b bellard
1204 3a27ad0b bellard
void test_vm86(void)
1205 3a27ad0b bellard
{
1206 3a27ad0b bellard
    struct vm86plus_struct ctx;
1207 3a27ad0b bellard
    struct vm86_regs *r;
1208 3a27ad0b bellard
    uint8_t *vm86_mem;
1209 3a27ad0b bellard
    int seg, ret;
1210 3a27ad0b bellard
1211 3a27ad0b bellard
    vm86_mem = mmap((void *)0x00000000, 0x110000, 
1212 3a27ad0b bellard
                    PROT_WRITE | PROT_READ | PROT_EXEC, 
1213 3a27ad0b bellard
                    MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
1214 3a27ad0b bellard
    if (vm86_mem == MAP_FAILED) {
1215 3a27ad0b bellard
        printf("ERROR: could not map vm86 memory");
1216 3a27ad0b bellard
        return;
1217 3a27ad0b bellard
    }
1218 3a27ad0b bellard
    memset(&ctx, 0, sizeof(ctx));
1219 3a27ad0b bellard
1220 3a27ad0b bellard
    /* init basic registers */
1221 3a27ad0b bellard
    r = &ctx.regs;
1222 3a27ad0b bellard
    r->eip = VM86_CODE_IP;
1223 3a27ad0b bellard
    r->esp = 0xfffe;
1224 3a27ad0b bellard
    seg = VM86_CODE_CS;
1225 3a27ad0b bellard
    r->cs = seg;
1226 3a27ad0b bellard
    r->ss = seg;
1227 3a27ad0b bellard
    r->ds = seg;
1228 3a27ad0b bellard
    r->es = seg;
1229 3a27ad0b bellard
    r->fs = seg;
1230 3a27ad0b bellard
    r->gs = seg;
1231 3a27ad0b bellard
    r->eflags = VIF_MASK;
1232 3a27ad0b bellard
1233 3a27ad0b bellard
    /* move code to proper address. We use the same layout as a .com
1234 3a27ad0b bellard
       dos program. */
1235 3a27ad0b bellard
    memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP, 
1236 3a27ad0b bellard
           &vm86_code_start, &vm86_code_end - &vm86_code_start);
1237 3a27ad0b bellard
1238 3a27ad0b bellard
    /* mark int 0x21 as being emulated */
1239 3a27ad0b bellard
    set_bit((uint8_t *)&ctx.int_revectored, 0x21);
1240 3a27ad0b bellard
1241 3a27ad0b bellard
    for(;;) {
1242 3a27ad0b bellard
        ret = vm86(VM86_ENTER, &ctx);
1243 3a27ad0b bellard
        switch(VM86_TYPE(ret)) {
1244 3a27ad0b bellard
        case VM86_INTx:
1245 3a27ad0b bellard
            {
1246 3ff0631e bellard
                int int_num, ah, v;
1247 3a27ad0b bellard
                
1248 3a27ad0b bellard
                int_num = VM86_ARG(ret);
1249 3a27ad0b bellard
                if (int_num != 0x21)
1250 3a27ad0b bellard
                    goto unknown_int;
1251 3a27ad0b bellard
                ah = (r->eax >> 8) & 0xff;
1252 3a27ad0b bellard
                switch(ah) {
1253 3a27ad0b bellard
                case 0x00: /* exit */
1254 3a27ad0b bellard
                    goto the_end;
1255 3a27ad0b bellard
                case 0x02: /* write char */
1256 3a27ad0b bellard
                    {
1257 3a27ad0b bellard
                        uint8_t c = r->edx;
1258 3a27ad0b bellard
                        putchar(c);
1259 3a27ad0b bellard
                    }
1260 3a27ad0b bellard
                    break;
1261 3a27ad0b bellard
                case 0x09: /* write string */
1262 3a27ad0b bellard
                    {
1263 3a27ad0b bellard
                        uint8_t c, *ptr;
1264 3a27ad0b bellard
                        ptr = seg_to_linear(r->ds, r->edx);
1265 3a27ad0b bellard
                        for(;;) {
1266 3a27ad0b bellard
                            c = *ptr++;
1267 3a27ad0b bellard
                            if (c == '$')
1268 3a27ad0b bellard
                                break;
1269 3a27ad0b bellard
                            putchar(c);
1270 3a27ad0b bellard
                        }
1271 3a27ad0b bellard
                        r->eax = (r->eax & ~0xff) | '$';
1272 3a27ad0b bellard
                    }
1273 3a27ad0b bellard
                    break;
1274 3ff0631e bellard
                case 0xff: /* extension: write eflags number in edx */
1275 3ff0631e bellard
                    v = (int)r->edx;
1276 3ff0631e bellard
#ifndef LINUX_VM86_IOPL_FIX
1277 3ff0631e bellard
                    v &= ~0x3000;
1278 3ff0631e bellard
#endif
1279 3ff0631e bellard
                    printf("%08x\n", v);
1280 3a27ad0b bellard
                    break;
1281 3a27ad0b bellard
                default:
1282 3a27ad0b bellard
                unknown_int:
1283 3a27ad0b bellard
                    printf("unsupported int 0x%02x\n", int_num);
1284 3a27ad0b bellard
                    goto the_end;
1285 3a27ad0b bellard
                }
1286 3a27ad0b bellard
            }
1287 3a27ad0b bellard
            break;
1288 3a27ad0b bellard
        case VM86_SIGNAL:
1289 3a27ad0b bellard
            /* a signal came, we just ignore that */
1290 3a27ad0b bellard
            break;
1291 3a27ad0b bellard
        case VM86_STI:
1292 3a27ad0b bellard
            break;
1293 3a27ad0b bellard
        default:
1294 3a27ad0b bellard
            printf("ERROR: unhandled vm86 return code (0x%x)\n", ret);
1295 3a27ad0b bellard
            goto the_end;
1296 3a27ad0b bellard
        }
1297 3a27ad0b bellard
    }
1298 3a27ad0b bellard
 the_end:
1299 3a27ad0b bellard
    printf("VM86 end\n");
1300 3a27ad0b bellard
    munmap(vm86_mem, 0x110000);
1301 3a27ad0b bellard
}
1302 3a27ad0b bellard
1303 3a27ad0b bellard
/* exception tests */
1304 3a27ad0b bellard
#ifndef REG_EAX
1305 3a27ad0b bellard
#define REG_EAX EAX
1306 3a27ad0b bellard
#define REG_EBX EBX
1307 3a27ad0b bellard
#define REG_ECX ECX
1308 3a27ad0b bellard
#define REG_EDX EDX
1309 3a27ad0b bellard
#define REG_ESI ESI
1310 3a27ad0b bellard
#define REG_EDI EDI
1311 3a27ad0b bellard
#define REG_EBP EBP
1312 3a27ad0b bellard
#define REG_ESP ESP
1313 3a27ad0b bellard
#define REG_EIP EIP
1314 3a27ad0b bellard
#define REG_EFL EFL
1315 3a27ad0b bellard
#define REG_TRAPNO TRAPNO
1316 3a27ad0b bellard
#define REG_ERR ERR
1317 3a27ad0b bellard
#endif
1318 3a27ad0b bellard
1319 3a27ad0b bellard
jmp_buf jmp_env;
1320 3a27ad0b bellard
int v1;
1321 3a27ad0b bellard
int tab[2];
1322 3a27ad0b bellard
1323 3a27ad0b bellard
void sig_handler(int sig, siginfo_t *info, void *puc)
1324 3a27ad0b bellard
{
1325 3a27ad0b bellard
    struct ucontext *uc = puc;
1326 3a27ad0b bellard
1327 3a27ad0b bellard
    printf("si_signo=%d si_errno=%d si_code=%d",
1328 3a27ad0b bellard
           info->si_signo, info->si_errno, info->si_code);
1329 e3b32540 bellard
    printf(" si_addr=0x%08lx",
1330 e3b32540 bellard
           (unsigned long)info->si_addr);
1331 3a27ad0b bellard
    printf("\n");
1332 3a27ad0b bellard
1333 3a27ad0b bellard
    printf("trapno=0x%02x err=0x%08x",
1334 3a27ad0b bellard
           uc->uc_mcontext.gregs[REG_TRAPNO],
1335 3a27ad0b bellard
           uc->uc_mcontext.gregs[REG_ERR]);
1336 e3b32540 bellard
    printf(" EIP=0x%08x", uc->uc_mcontext.gregs[REG_EIP]);
1337 3a27ad0b bellard
    printf("\n");
1338 3a27ad0b bellard
    longjmp(jmp_env, 1);
1339 3a27ad0b bellard
}
1340 3a27ad0b bellard
1341 3a27ad0b bellard
void test_exceptions(void)
1342 3a27ad0b bellard
{
1343 e3b32540 bellard
    struct modify_ldt_ldt_s ldt;
1344 3a27ad0b bellard
    struct sigaction act;
1345 3a27ad0b bellard
    volatile int val;
1346 3a27ad0b bellard
    
1347 3a27ad0b bellard
    act.sa_sigaction = sig_handler;
1348 3a27ad0b bellard
    sigemptyset(&act.sa_mask);
1349 3a27ad0b bellard
    act.sa_flags = SA_SIGINFO;
1350 3a27ad0b bellard
    sigaction(SIGFPE, &act, NULL);
1351 3a27ad0b bellard
    sigaction(SIGILL, &act, NULL);
1352 3a27ad0b bellard
    sigaction(SIGSEGV, &act, NULL);
1353 e3b32540 bellard
    sigaction(SIGBUS, &act, NULL);
1354 3a27ad0b bellard
    sigaction(SIGTRAP, &act, NULL);
1355 3a27ad0b bellard
1356 3a27ad0b bellard
    /* test division by zero reporting */
1357 e3b32540 bellard
    printf("DIVZ exception:\n");
1358 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1359 3a27ad0b bellard
        /* now divide by zero */
1360 3a27ad0b bellard
        v1 = 0;
1361 3a27ad0b bellard
        v1 = 2 / v1;
1362 3a27ad0b bellard
    }
1363 3a27ad0b bellard
1364 e3b32540 bellard
    printf("BOUND exception:\n");
1365 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1366 3a27ad0b bellard
        /* bound exception */
1367 3a27ad0b bellard
        tab[0] = 1;
1368 3a27ad0b bellard
        tab[1] = 10;
1369 e82d8ade bellard
        asm volatile ("bound %0, %1" : : "r" (11), "m" (tab[0]));
1370 3a27ad0b bellard
    }
1371 3a27ad0b bellard
1372 e3b32540 bellard
    printf("segment exceptions:\n");
1373 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1374 e3b32540 bellard
        /* load an invalid segment */
1375 e3b32540 bellard
        asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 1));
1376 e3b32540 bellard
    }
1377 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1378 e3b32540 bellard
        /* null data segment is valid */
1379 e3b32540 bellard
        asm volatile ("movl %0, %%fs" : : "r" (3));
1380 e3b32540 bellard
        /* null stack segment */
1381 e3b32540 bellard
        asm volatile ("movl %0, %%ss" : : "r" (3));
1382 e3b32540 bellard
    }
1383 e3b32540 bellard
1384 e3b32540 bellard
    ldt.entry_number = 1;
1385 e3b32540 bellard
    ldt.base_addr = (unsigned long)&seg_data1;
1386 e3b32540 bellard
    ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
1387 e3b32540 bellard
    ldt.seg_32bit = 1;
1388 e3b32540 bellard
    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
1389 e3b32540 bellard
    ldt.read_exec_only = 0;
1390 e3b32540 bellard
    ldt.limit_in_pages = 1;
1391 e3b32540 bellard
    ldt.seg_not_present = 1;
1392 e3b32540 bellard
    ldt.useable = 1;
1393 e3b32540 bellard
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
1394 e3b32540 bellard
1395 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1396 e3b32540 bellard
        /* segment not present */
1397 e3b32540 bellard
        asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
1398 e3b32540 bellard
    }
1399 e3b32540 bellard
1400 3a27ad0b bellard
    /* test SEGV reporting */
1401 e3b32540 bellard
    printf("PF exception:\n");
1402 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1403 e3b32540 bellard
        val = 1;
1404 ede28208 bellard
        /* we add a nop to test a weird PC retrieval case */
1405 ede28208 bellard
        asm volatile ("nop");
1406 3a27ad0b bellard
        /* now store in an invalid address */
1407 3a27ad0b bellard
        *(char *)0x1234 = 1;
1408 3a27ad0b bellard
    }
1409 3a27ad0b bellard
1410 3a27ad0b bellard
    /* test SEGV reporting */
1411 e3b32540 bellard
    printf("PF exception:\n");
1412 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1413 e3b32540 bellard
        val = 1;
1414 3a27ad0b bellard
        /* read from an invalid address */
1415 3a27ad0b bellard
        v1 = *(char *)0x1234;
1416 3a27ad0b bellard
    }
1417 3a27ad0b bellard
    
1418 3a27ad0b bellard
    /* test illegal instruction reporting */
1419 3a27ad0b bellard
    printf("UD2 exception:\n");
1420 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1421 3a27ad0b bellard
        /* now execute an invalid instruction */
1422 3a27ad0b bellard
        asm volatile("ud2");
1423 3a27ad0b bellard
    }
1424 4120b61d bellard
    printf("lock nop exception:\n");
1425 4120b61d bellard
    if (setjmp(jmp_env) == 0) {
1426 4120b61d bellard
        /* now execute an invalid instruction */
1427 4120b61d bellard
        asm volatile("lock nop");
1428 4120b61d bellard
    }
1429 3a27ad0b bellard
    
1430 3a27ad0b bellard
    printf("INT exception:\n");
1431 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1432 3a27ad0b bellard
        asm volatile ("int $0xfd");
1433 3a27ad0b bellard
    }
1434 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1435 e3b32540 bellard
        asm volatile ("int $0x01");
1436 e3b32540 bellard
    }
1437 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1438 e3b32540 bellard
        asm volatile (".byte 0xcd, 0x03");
1439 e3b32540 bellard
    }
1440 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1441 e3b32540 bellard
        asm volatile ("int $0x04");
1442 e3b32540 bellard
    }
1443 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1444 e3b32540 bellard
        asm volatile ("int $0x05");
1445 e3b32540 bellard
    }
1446 3a27ad0b bellard
1447 3a27ad0b bellard
    printf("INT3 exception:\n");
1448 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1449 3a27ad0b bellard
        asm volatile ("int3");
1450 3a27ad0b bellard
    }
1451 3a27ad0b bellard
1452 3a27ad0b bellard
    printf("CLI exception:\n");
1453 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1454 3a27ad0b bellard
        asm volatile ("cli");
1455 3a27ad0b bellard
    }
1456 3a27ad0b bellard
1457 3a27ad0b bellard
    printf("STI exception:\n");
1458 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1459 3a27ad0b bellard
        asm volatile ("cli");
1460 3a27ad0b bellard
    }
1461 3a27ad0b bellard
1462 3a27ad0b bellard
    printf("INTO exception:\n");
1463 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1464 3a27ad0b bellard
        /* overflow exception */
1465 3a27ad0b bellard
        asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff));
1466 3a27ad0b bellard
    }
1467 3a27ad0b bellard
1468 3a27ad0b bellard
    printf("OUTB exception:\n");
1469 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1470 3a27ad0b bellard
        asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0));
1471 3a27ad0b bellard
    }
1472 3a27ad0b bellard
1473 3a27ad0b bellard
    printf("INB exception:\n");
1474 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1475 3a27ad0b bellard
        asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321));
1476 3a27ad0b bellard
    }
1477 3a27ad0b bellard
1478 3a27ad0b bellard
    printf("REP OUTSB exception:\n");
1479 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1480 3a27ad0b bellard
        asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1));
1481 3a27ad0b bellard
    }
1482 3a27ad0b bellard
1483 3a27ad0b bellard
    printf("REP INSB exception:\n");
1484 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1485 3a27ad0b bellard
        asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1));
1486 3a27ad0b bellard
    }
1487 3a27ad0b bellard
1488 3a27ad0b bellard
    printf("HLT exception:\n");
1489 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1490 3a27ad0b bellard
        asm volatile ("hlt");
1491 3a27ad0b bellard
    }
1492 3a27ad0b bellard
1493 3a27ad0b bellard
    printf("single step exception:\n");
1494 3a27ad0b bellard
    val = 0;
1495 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1496 3a27ad0b bellard
        asm volatile ("pushf\n"
1497 3a27ad0b bellard
                      "orl $0x00100, (%%esp)\n"
1498 3a27ad0b bellard
                      "popf\n"
1499 3a27ad0b bellard
                      "movl $0xabcd, %0\n" 
1500 3a27ad0b bellard
                      "movl $0x0, %0\n" : "=m" (val) : : "cc", "memory");
1501 3a27ad0b bellard
    }
1502 3a27ad0b bellard
    printf("val=0x%x\n", val);
1503 3a27ad0b bellard
}
1504 3a27ad0b bellard
1505 3ff0631e bellard
/* specific precise single step test */
1506 3ff0631e bellard
void sig_trap_handler(int sig, siginfo_t *info, void *puc)
1507 3ff0631e bellard
{
1508 3ff0631e bellard
    struct ucontext *uc = puc;
1509 3ff0631e bellard
    printf("EIP=0x%08x\n", uc->uc_mcontext.gregs[REG_EIP]);
1510 3ff0631e bellard
}
1511 3ff0631e bellard
1512 3ff0631e bellard
const uint8_t sstep_buf1[4] = { 1, 2, 3, 4};
1513 3ff0631e bellard
uint8_t sstep_buf2[4];
1514 3ff0631e bellard
1515 3ff0631e bellard
void test_single_step(void)
1516 3ff0631e bellard
{
1517 3ff0631e bellard
    struct sigaction act;
1518 3ff0631e bellard
    volatile int val;
1519 3ff0631e bellard
    int i;
1520 3ff0631e bellard
1521 3ff0631e bellard
    val = 0;
1522 3ff0631e bellard
    act.sa_sigaction = sig_trap_handler;
1523 3ff0631e bellard
    sigemptyset(&act.sa_mask);
1524 3ff0631e bellard
    act.sa_flags = SA_SIGINFO;
1525 3ff0631e bellard
    sigaction(SIGTRAP, &act, NULL);
1526 3ff0631e bellard
    asm volatile ("pushf\n"
1527 3ff0631e bellard
                  "orl $0x00100, (%%esp)\n"
1528 3ff0631e bellard
                  "popf\n"
1529 3ff0631e bellard
                  "movl $0xabcd, %0\n" 
1530 3ff0631e bellard
1531 3ff0631e bellard
                  /* jmp test */
1532 3ff0631e bellard
                  "movl $3, %%ecx\n"
1533 3ff0631e bellard
                  "1:\n"
1534 3ff0631e bellard
                  "addl $1, %0\n"
1535 3ff0631e bellard
                  "decl %%ecx\n"
1536 3ff0631e bellard
                  "jnz 1b\n"
1537 3ff0631e bellard
1538 3ff0631e bellard
                  /* movsb: the single step should stop at each movsb iteration */
1539 3ff0631e bellard
                  "movl $sstep_buf1, %%esi\n"
1540 3ff0631e bellard
                  "movl $sstep_buf2, %%edi\n"
1541 3ff0631e bellard
                  "movl $0, %%ecx\n"
1542 3ff0631e bellard
                  "rep movsb\n"
1543 3ff0631e bellard
                  "movl $3, %%ecx\n"
1544 3ff0631e bellard
                  "rep movsb\n"
1545 3ff0631e bellard
                  "movl $1, %%ecx\n"
1546 3ff0631e bellard
                  "rep movsb\n"
1547 3ff0631e bellard
1548 3ff0631e bellard
                  /* cmpsb: the single step should stop at each cmpsb iteration */
1549 3ff0631e bellard
                  "movl $sstep_buf1, %%esi\n"
1550 3ff0631e bellard
                  "movl $sstep_buf2, %%edi\n"
1551 3ff0631e bellard
                  "movl $0, %%ecx\n"
1552 3ff0631e bellard
                  "rep cmpsb\n"
1553 3ff0631e bellard
                  "movl $4, %%ecx\n"
1554 3ff0631e bellard
                  "rep cmpsb\n"
1555 3ff0631e bellard
                  
1556 3ff0631e bellard
                  /* getpid() syscall: single step should skip one
1557 3ff0631e bellard
                     instruction */
1558 3ff0631e bellard
                  "movl $20, %%eax\n"
1559 3ff0631e bellard
                  "int $0x80\n"
1560 3ff0631e bellard
                  "movl $0, %%eax\n"
1561 3ff0631e bellard
                  
1562 3ff0631e bellard
                  /* when modifying SS, trace is not done on the next
1563 3ff0631e bellard
                     instruction */
1564 3ff0631e bellard
                  "movl %%ss, %%ecx\n"
1565 3ff0631e bellard
                  "movl %%ecx, %%ss\n"
1566 3ff0631e bellard
                  "addl $1, %0\n"
1567 3ff0631e bellard
                  "movl $1, %%eax\n"
1568 3ff0631e bellard
                  "movl %%ecx, %%ss\n"
1569 3ff0631e bellard
                  "jmp 1f\n"
1570 3ff0631e bellard
                  "addl $1, %0\n"
1571 3ff0631e bellard
                  "1:\n"
1572 3ff0631e bellard
                  "movl $1, %%eax\n"
1573 3ff0631e bellard
                  "pushl %%ecx\n"
1574 3ff0631e bellard
                  "popl %%ss\n"
1575 3ff0631e bellard
                  "addl $1, %0\n"
1576 3ff0631e bellard
                  "movl $1, %%eax\n"
1577 3ff0631e bellard
                  
1578 3ff0631e bellard
                  "pushf\n"
1579 3ff0631e bellard
                  "andl $~0x00100, (%%esp)\n"
1580 3ff0631e bellard
                  "popf\n"
1581 3ff0631e bellard
                  : "=m" (val) 
1582 3ff0631e bellard
                  : 
1583 3ff0631e bellard
                  : "cc", "memory", "eax", "ecx", "esi", "edi");
1584 3ff0631e bellard
    printf("val=%d\n", val);
1585 3ff0631e bellard
    for(i = 0; i < 4; i++)
1586 3ff0631e bellard
        printf("sstep_buf2[%d] = %d\n", i, sstep_buf2[i]);
1587 3ff0631e bellard
}
1588 3ff0631e bellard
1589 3a27ad0b bellard
/* self modifying code test */
1590 3a27ad0b bellard
uint8_t code[] = {
1591 3a27ad0b bellard
    0xb8, 0x1, 0x00, 0x00, 0x00, /* movl $1, %eax */
1592 3a27ad0b bellard
    0xc3, /* ret */
1593 3a27ad0b bellard
};
1594 3a27ad0b bellard
1595 1190935d bellard
asm("smc_code2:\n"
1596 1190935d bellard
    "movl 4(%esp), %eax\n"
1597 1190935d bellard
    "movl %eax, smc_patch_addr2 + 1\n"
1598 1190935d bellard
    "nop\n"
1599 1190935d bellard
    "nop\n"
1600 1190935d bellard
    "nop\n"
1601 1190935d bellard
    "nop\n"
1602 1190935d bellard
    "nop\n"
1603 1190935d bellard
    "nop\n"
1604 1190935d bellard
    "nop\n"
1605 1190935d bellard
    "nop\n"
1606 1190935d bellard
    "smc_patch_addr2:\n"
1607 1190935d bellard
    "movl $1, %eax\n"
1608 1190935d bellard
    "ret\n");
1609 d1fe2b24 bellard
1610 1190935d bellard
typedef int FuncType(void);
1611 1190935d bellard
extern int smc_code2(int);
1612 3a27ad0b bellard
void test_self_modifying_code(void)
1613 3a27ad0b bellard
{
1614 d1fe2b24 bellard
    int i;
1615 3a27ad0b bellard
1616 3a27ad0b bellard
    printf("self modifying code:\n");
1617 d1fe2b24 bellard
    printf("func1 = 0x%x\n", ((FuncType *)code)());
1618 d1fe2b24 bellard
    for(i = 2; i <= 4; i++) {
1619 d1fe2b24 bellard
        code[1] = i;
1620 d1fe2b24 bellard
        printf("func%d = 0x%x\n", i, ((FuncType *)code)());
1621 d1fe2b24 bellard
    }
1622 1190935d bellard
1623 1190935d bellard
    /* more difficult test : the modified code is just after the
1624 1190935d bellard
       modifying instruction. It is forbidden in Intel specs, but it
1625 1190935d bellard
       is used by old DOS programs */
1626 1190935d bellard
    for(i = 2; i <= 4; i++) {
1627 1190935d bellard
        printf("smc_code2(%d) = %d\n", i, smc_code2(i));
1628 1190935d bellard
    }
1629 3a27ad0b bellard
}
1630 61a8c4ec bellard
1631 61a8c4ec bellard
int enter_stack[4096];
1632 61a8c4ec bellard
1633 61a8c4ec bellard
#define TEST_ENTER(size, stack_type, level)\
1634 61a8c4ec bellard
{\
1635 61a8c4ec bellard
    int esp_save, esp_val, ebp_val, ebp_save, i;\
1636 61a8c4ec bellard
    stack_type *ptr, *stack_end, *stack_ptr;\
1637 61a8c4ec bellard
    memset(enter_stack, 0, sizeof(enter_stack));\
1638 61a8c4ec bellard
    stack_end = stack_ptr = (stack_type *)(enter_stack + 4096);\
1639 61a8c4ec bellard
    ebp_val = (long)stack_ptr;\
1640 61a8c4ec bellard
    for(i=1;i<=32;i++)\
1641 61a8c4ec bellard
       *--stack_ptr = i;\
1642 61a8c4ec bellard
    esp_val = (long)stack_ptr;\
1643 61a8c4ec bellard
    asm("movl %%esp, %[esp_save]\n"\
1644 61a8c4ec bellard
        "movl %%ebp, %[ebp_save]\n"\
1645 61a8c4ec bellard
        "movl %[esp_val], %%esp\n"\
1646 61a8c4ec bellard
        "movl %[ebp_val], %%ebp\n"\
1647 61a8c4ec bellard
        "enter" size " $12, $" #level "\n"\
1648 61a8c4ec bellard
        "movl %%esp, %[esp_val]\n"\
1649 61a8c4ec bellard
        "movl %%ebp, %[ebp_val]\n"\
1650 61a8c4ec bellard
        "movl %[esp_save], %%esp\n"\
1651 61a8c4ec bellard
        "movl %[ebp_save], %%ebp\n"\
1652 61a8c4ec bellard
        : [esp_save] "=r" (esp_save),\
1653 61a8c4ec bellard
        [ebp_save] "=r" (ebp_save),\
1654 61a8c4ec bellard
        [esp_val] "=r" (esp_val),\
1655 61a8c4ec bellard
        [ebp_val] "=r" (ebp_val)\
1656 61a8c4ec bellard
        :  "[esp_val]" (esp_val),\
1657 61a8c4ec bellard
        "[ebp_val]" (ebp_val));\
1658 61a8c4ec bellard
    printf("level=%d:\n", level);\
1659 61a8c4ec bellard
    printf("esp_val=0x%08lx\n", esp_val - (long)stack_end);\
1660 61a8c4ec bellard
    printf("ebp_val=0x%08lx\n", ebp_val - (long)stack_end);\
1661 61a8c4ec bellard
    for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\
1662 61a8c4ec bellard
        printf("%08x\n", ptr[0]);\
1663 61a8c4ec bellard
}
1664 61a8c4ec bellard
1665 61a8c4ec bellard
static void test_enter(void)
1666 61a8c4ec bellard
{
1667 61a8c4ec bellard
    TEST_ENTER("l", uint32_t, 0);
1668 61a8c4ec bellard
    TEST_ENTER("l", uint32_t, 1);
1669 61a8c4ec bellard
    TEST_ENTER("l", uint32_t, 2);
1670 61a8c4ec bellard
    TEST_ENTER("l", uint32_t, 31);
1671 61a8c4ec bellard
1672 61a8c4ec bellard
    TEST_ENTER("w", uint16_t, 0);
1673 61a8c4ec bellard
    TEST_ENTER("w", uint16_t, 1);
1674 61a8c4ec bellard
    TEST_ENTER("w", uint16_t, 2);
1675 61a8c4ec bellard
    TEST_ENTER("w", uint16_t, 31);
1676 61a8c4ec bellard
}
1677 61a8c4ec bellard
1678 085339a1 bellard
#ifdef TEST_SSE
1679 085339a1 bellard
1680 085339a1 bellard
typedef int __m64 __attribute__ ((__mode__ (__V2SI__)));
1681 085339a1 bellard
typedef int __m128 __attribute__ ((__mode__(__V4SF__)));
1682 085339a1 bellard
1683 085339a1 bellard
typedef union {
1684 085339a1 bellard
    double d[2];
1685 085339a1 bellard
    float s[4];
1686 085339a1 bellard
    uint32_t l[4];
1687 085339a1 bellard
    uint64_t q[2];
1688 085339a1 bellard
    __m128 dq;
1689 085339a1 bellard
} XMMReg;
1690 085339a1 bellard
1691 085339a1 bellard
static uint64_t __attribute__((aligned(16))) test_values[4][2] = {
1692 085339a1 bellard
    { 0x456723c698694873, 0xdc515cff944a58ec },
1693 085339a1 bellard
    { 0x1f297ccd58bad7ab, 0x41f21efba9e3e146 },
1694 085339a1 bellard
    { 0x007c62c2085427f8, 0x231be9e8cde7438d },
1695 085339a1 bellard
    { 0x0f76255a085427f8, 0xc233e9e8c4c9439a },
1696 085339a1 bellard
};
1697 085339a1 bellard
1698 085339a1 bellard
#define SSE_OP(op)\
1699 085339a1 bellard
{\
1700 085339a1 bellard
    asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
1701 085339a1 bellard
    printf("%-9s: a=%016llx%016llx b=%016llx%016llx r=%016llx%016llx\n",\
1702 085339a1 bellard
           #op,\
1703 085339a1 bellard
           a.q[1], a.q[0],\
1704 085339a1 bellard
           b.q[1], b.q[0],\
1705 085339a1 bellard
           r.q[1], r.q[0]);\
1706 085339a1 bellard
}
1707 085339a1 bellard
1708 085339a1 bellard
#define SSE_OP2(op)\
1709 085339a1 bellard
{\
1710 085339a1 bellard
    int i;\
1711 085339a1 bellard
    for(i=0;i<2;i++) {\
1712 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
1713 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
1714 085339a1 bellard
    b.q[0] = test_values[2*i+1][0];\
1715 085339a1 bellard
    b.q[1] = test_values[2*i+1][1];\
1716 085339a1 bellard
    SSE_OP(op);\
1717 085339a1 bellard
    }\
1718 085339a1 bellard
}
1719 085339a1 bellard
1720 085339a1 bellard
#define MMX_OP2(op)\
1721 085339a1 bellard
{\
1722 085339a1 bellard
    int i;\
1723 085339a1 bellard
    for(i=0;i<2;i++) {\
1724 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
1725 085339a1 bellard
    b.q[0] = test_values[2*i+1][0];\
1726 085339a1 bellard
    asm volatile (#op " %2, %0" : "=y" (r.q[0]) : "0" (a.q[0]), "y" (b.q[0]));\
1727 085339a1 bellard
    printf("%-9s: a=%016llx b=%016llx r=%016llx\n",\
1728 085339a1 bellard
           #op,\
1729 085339a1 bellard
           a.q[0],\
1730 085339a1 bellard
           b.q[0],\
1731 085339a1 bellard
           r.q[0]);\
1732 085339a1 bellard
    }\
1733 085339a1 bellard
    SSE_OP2(op);\
1734 085339a1 bellard
}
1735 085339a1 bellard
1736 085339a1 bellard
#define PSHUF_OP(op, ib)\
1737 085339a1 bellard
{\
1738 085339a1 bellard
    int i;\
1739 085339a1 bellard
    for(i=0;i<2;i++) {\
1740 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
1741 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
1742 085339a1 bellard
    asm volatile (#op " $" #ib ", %1, %0" : "=x" (r.dq) : "x" (a.dq));\
1743 085339a1 bellard
    printf("%-9s: a=%016llx%016llx ib=%02x r=%016llx%016llx\n",\
1744 085339a1 bellard
           #op,\
1745 085339a1 bellard
           a.q[1], a.q[0],\
1746 085339a1 bellard
           ib,\
1747 085339a1 bellard
           r.q[1], r.q[0]);\
1748 085339a1 bellard
    }\
1749 085339a1 bellard
}
1750 085339a1 bellard
1751 085339a1 bellard
#define SHIFT_IM(op, ib)\
1752 085339a1 bellard
{\
1753 085339a1 bellard
    int i;\
1754 085339a1 bellard
    for(i=0;i<2;i++) {\
1755 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
1756 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
1757 085339a1 bellard
    asm volatile (#op " $" #ib ", %0" : "=x" (r.dq) : "0" (a.dq));\
1758 085339a1 bellard
    printf("%-9s: a=%016llx%016llx ib=%02x r=%016llx%016llx\n",\
1759 085339a1 bellard
           #op,\
1760 085339a1 bellard
           a.q[1], a.q[0],\
1761 085339a1 bellard
           ib,\
1762 085339a1 bellard
           r.q[1], r.q[0]);\
1763 085339a1 bellard
    }\
1764 085339a1 bellard
}
1765 085339a1 bellard
1766 085339a1 bellard
#define SHIFT_OP(op, ib)\
1767 085339a1 bellard
{\
1768 085339a1 bellard
    int i;\
1769 085339a1 bellard
    SHIFT_IM(op, ib);\
1770 085339a1 bellard
    for(i=0;i<2;i++) {\
1771 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
1772 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
1773 085339a1 bellard
    b.q[0] = ib;\
1774 085339a1 bellard
    b.q[1] = 0;\
1775 085339a1 bellard
    asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
1776 085339a1 bellard
    printf("%-9s: a=%016llx%016llx b=%016llx%016llx r=%016llx%016llx\n",\
1777 085339a1 bellard
           #op,\
1778 085339a1 bellard
           a.q[1], a.q[0],\
1779 085339a1 bellard
           b.q[1], b.q[0],\
1780 085339a1 bellard
           r.q[1], r.q[0]);\
1781 085339a1 bellard
    }\
1782 085339a1 bellard
}
1783 085339a1 bellard
1784 085339a1 bellard
#define MOVMSK(op)\
1785 085339a1 bellard
{\
1786 085339a1 bellard
    int i, reg;\
1787 085339a1 bellard
    for(i=0;i<2;i++) {\
1788 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
1789 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
1790 085339a1 bellard
    asm volatile (#op " %1, %0" : "=r" (reg) : "x" (a.dq));\
1791 085339a1 bellard
    printf("%-9s: a=%016llx%016llx r=%08x\n",\
1792 085339a1 bellard
           #op,\
1793 085339a1 bellard
           a.q[1], a.q[0],\
1794 085339a1 bellard
           reg);\
1795 085339a1 bellard
    }\
1796 085339a1 bellard
}
1797 085339a1 bellard
1798 085339a1 bellard
#define SSE_OPS(a) \
1799 085339a1 bellard
SSE_OP(a ## ps);\
1800 085339a1 bellard
SSE_OP(a ## ss);
1801 085339a1 bellard
1802 085339a1 bellard
#define SSE_OPD(a) \
1803 085339a1 bellard
SSE_OP(a ## pd);\
1804 085339a1 bellard
SSE_OP(a ## sd);
1805 085339a1 bellard
1806 085339a1 bellard
#define SSE_COMI(op, field)\
1807 085339a1 bellard
{\
1808 085339a1 bellard
    unsigned int eflags;\
1809 085339a1 bellard
    XMMReg a, b;\
1810 085339a1 bellard
    a.field[0] = a1;\
1811 085339a1 bellard
    b.field[0] = b1;\
1812 085339a1 bellard
    asm volatile (#op " %2, %1\n"\
1813 085339a1 bellard
        "pushf\n"\
1814 085339a1 bellard
        "pop %0\n"\
1815 085339a1 bellard
        : "=m" (eflags)\
1816 085339a1 bellard
        : "x" (a.dq), "x" (b.dq));\
1817 085339a1 bellard
    printf("%-9s: a=%f b=%f cc=%04x\n",\
1818 085339a1 bellard
           #op, a1, b1,\
1819 085339a1 bellard
           eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\
1820 085339a1 bellard
}
1821 085339a1 bellard
1822 085339a1 bellard
void test_sse_comi(double a1, double b1)
1823 085339a1 bellard
{
1824 085339a1 bellard
    SSE_COMI(ucomiss, s);
1825 085339a1 bellard
    SSE_COMI(ucomisd, d);
1826 085339a1 bellard
    SSE_COMI(comiss, s);
1827 085339a1 bellard
    SSE_COMI(comisd, d);
1828 085339a1 bellard
}
1829 085339a1 bellard
1830 085339a1 bellard
#define CVT_OP_XMM(op)\
1831 085339a1 bellard
{\
1832 085339a1 bellard
    asm volatile (#op " %1, %0" : "=x" (r.dq) : "x" (a.dq));\
1833 085339a1 bellard
    printf("%-9s: a=%016llx%016llx r=%016llx%016llx\n",\
1834 085339a1 bellard
           #op,\
1835 085339a1 bellard
           a.q[1], a.q[0],\
1836 085339a1 bellard
           r.q[1], r.q[0]);\
1837 085339a1 bellard
}
1838 085339a1 bellard
1839 085339a1 bellard
#define CVT_OP_XMM2MMX(op)\
1840 085339a1 bellard
{\
1841 085339a1 bellard
    asm volatile (#op " %1, %0" : "=y" (r.q[0]) : "x" (a.dq));\
1842 085339a1 bellard
    printf("%-9s: a=%016llx%016llx r=%016llx\n",\
1843 085339a1 bellard
           #op,\
1844 085339a1 bellard
           a.q[1], a.q[0],\
1845 085339a1 bellard
           r.q[0]);\
1846 085339a1 bellard
}
1847 085339a1 bellard
1848 085339a1 bellard
#define CVT_OP_MMX2XMM(op)\
1849 085339a1 bellard
{\
1850 085339a1 bellard
    asm volatile (#op " %1, %0" : "=x" (r.dq) : "y" (a.q[0]));\
1851 085339a1 bellard
    printf("%-9s: a=%016llx r=%016llx%016llx\n",\
1852 085339a1 bellard
           #op,\
1853 085339a1 bellard
           a.q[0],\
1854 085339a1 bellard
           r.q[1], r.q[0]);\
1855 085339a1 bellard
}
1856 085339a1 bellard
1857 085339a1 bellard
#define CVT_OP_REG2XMM(op)\
1858 085339a1 bellard
{\
1859 085339a1 bellard
    asm volatile (#op " %1, %0" : "=x" (r.dq) : "r" (a.l[0]));\
1860 085339a1 bellard
    printf("%-9s: a=%08x r=%016llx%016llx\n",\
1861 085339a1 bellard
           #op,\
1862 085339a1 bellard
           a.l[0],\
1863 085339a1 bellard
           r.q[1], r.q[0]);\
1864 085339a1 bellard
}
1865 085339a1 bellard
1866 085339a1 bellard
#define CVT_OP_XMM2REG(op)\
1867 085339a1 bellard
{\
1868 085339a1 bellard
    asm volatile (#op " %1, %0" : "=r" (r.l[0]) : "x" (a.dq));\
1869 085339a1 bellard
    printf("%-9s: a=%016llx%016llx r=%08x\n",\
1870 085339a1 bellard
           #op,\
1871 085339a1 bellard
           a.q[1], a.q[0],\
1872 085339a1 bellard
           r.l[0]);\
1873 085339a1 bellard
}
1874 085339a1 bellard
1875 a4682cc2 bellard
struct fpxstate {
1876 a4682cc2 bellard
    uint16_t fpuc;
1877 a4682cc2 bellard
    uint16_t fpus;
1878 a4682cc2 bellard
    uint16_t fptag;
1879 a4682cc2 bellard
    uint16_t fop;
1880 a4682cc2 bellard
    uint32_t fpuip;
1881 a4682cc2 bellard
    uint16_t cs_sel;
1882 a4682cc2 bellard
    uint16_t dummy0;
1883 a4682cc2 bellard
    uint32_t fpudp;
1884 a4682cc2 bellard
    uint16_t ds_sel;
1885 a4682cc2 bellard
    uint16_t dummy1;
1886 a4682cc2 bellard
    uint32_t mxcsr;
1887 a4682cc2 bellard
    uint32_t mxcsr_mask;
1888 a4682cc2 bellard
    uint8_t fpregs1[8 * 16];
1889 a4682cc2 bellard
    uint8_t xmm_regs[8 * 16];
1890 a4682cc2 bellard
    uint8_t dummy2[224];
1891 a4682cc2 bellard
};
1892 a4682cc2 bellard
1893 a4682cc2 bellard
static struct fpxstate fpx_state __attribute__((aligned(16)));
1894 a4682cc2 bellard
static struct fpxstate fpx_state2 __attribute__((aligned(16)));
1895 a4682cc2 bellard
1896 a4682cc2 bellard
void test_fxsave(void)
1897 a4682cc2 bellard
{
1898 a4682cc2 bellard
    struct fpxstate *fp = &fpx_state;
1899 a4682cc2 bellard
    struct fpxstate *fp2 = &fpx_state2;
1900 a4682cc2 bellard
    int i;
1901 a4682cc2 bellard
    XMMReg a, b;
1902 a4682cc2 bellard
    a.q[0] = test_values[0][0];
1903 a4682cc2 bellard
    a.q[1] = test_values[0][1];
1904 a4682cc2 bellard
    b.q[0] = test_values[1][0];
1905 a4682cc2 bellard
    b.q[1] = test_values[1][1];
1906 a4682cc2 bellard
1907 a4682cc2 bellard
    asm("movdqa %2, %%xmm0\n"
1908 a4682cc2 bellard
        "movdqa %3, %%xmm7\n"
1909 a4682cc2 bellard
        " fld1\n"
1910 a4682cc2 bellard
        " fldpi\n"
1911 a4682cc2 bellard
        " fldln2\n"
1912 a4682cc2 bellard
        " fxsave %0\n"
1913 a4682cc2 bellard
        " fxrstor %0\n"
1914 a4682cc2 bellard
        " fxsave %1\n"
1915 a4682cc2 bellard
        " fninit\n"
1916 a4682cc2 bellard
        : "=m" (*(uint32_t *)fp2), "=m" (*(uint32_t *)fp) 
1917 a4682cc2 bellard
        : "m" (a), "m" (b));
1918 a4682cc2 bellard
    printf("fpuc=%04x\n", fp->fpuc);
1919 a4682cc2 bellard
    printf("fpus=%04x\n", fp->fpus);
1920 a4682cc2 bellard
    printf("fptag=%04x\n", fp->fptag);
1921 a4682cc2 bellard
    for(i = 0; i < 3; i++) {
1922 a4682cc2 bellard
        printf("ST%d: %016llx %04x\n",
1923 a4682cc2 bellard
               i, 
1924 a4682cc2 bellard
               *(uint64_t *)&fp->fpregs1[i * 16],
1925 a4682cc2 bellard
               *(uint16_t *)&fp->fpregs1[i * 16 + 8]);
1926 a4682cc2 bellard
    }
1927 a4682cc2 bellard
    printf("mxcsr=%08x\n", fp->mxcsr & 0x1f80);
1928 a4682cc2 bellard
    for(i = 0; i < 8; i++) {
1929 a4682cc2 bellard
        printf("xmm%d: %016llx%016llx\n",
1930 a4682cc2 bellard
               i, 
1931 a4682cc2 bellard
               *(uint64_t *)&fp->xmm_regs[i * 16],
1932 a4682cc2 bellard
               *(uint64_t *)&fp->xmm_regs[i * 16 + 8]);
1933 a4682cc2 bellard
    }
1934 a4682cc2 bellard
}
1935 a4682cc2 bellard
1936 085339a1 bellard
void test_sse(void)
1937 085339a1 bellard
{
1938 085339a1 bellard
    XMMReg r, a, b;
1939 085339a1 bellard
1940 085339a1 bellard
    MMX_OP2(punpcklbw);
1941 085339a1 bellard
    MMX_OP2(punpcklwd);
1942 085339a1 bellard
    MMX_OP2(punpckldq);
1943 085339a1 bellard
    MMX_OP2(packsswb);
1944 085339a1 bellard
    MMX_OP2(pcmpgtb);
1945 085339a1 bellard
    MMX_OP2(pcmpgtw);
1946 085339a1 bellard
    MMX_OP2(pcmpgtd);
1947 085339a1 bellard
    MMX_OP2(packuswb);
1948 085339a1 bellard
    MMX_OP2(punpckhbw);
1949 085339a1 bellard
    MMX_OP2(punpckhwd);
1950 085339a1 bellard
    MMX_OP2(punpckhdq);
1951 085339a1 bellard
    MMX_OP2(packssdw);
1952 085339a1 bellard
    MMX_OP2(pcmpeqb);
1953 085339a1 bellard
    MMX_OP2(pcmpeqw);
1954 085339a1 bellard
    MMX_OP2(pcmpeqd);
1955 085339a1 bellard
1956 085339a1 bellard
    MMX_OP2(paddq);
1957 085339a1 bellard
    MMX_OP2(pmullw);
1958 085339a1 bellard
    MMX_OP2(psubusb);
1959 085339a1 bellard
    MMX_OP2(psubusw);
1960 085339a1 bellard
    MMX_OP2(pminub);
1961 085339a1 bellard
    MMX_OP2(pand);
1962 085339a1 bellard
    MMX_OP2(paddusb);
1963 085339a1 bellard
    MMX_OP2(paddusw);
1964 085339a1 bellard
    MMX_OP2(pmaxub);
1965 085339a1 bellard
    MMX_OP2(pandn);
1966 085339a1 bellard
1967 085339a1 bellard
    MMX_OP2(pmulhuw);
1968 085339a1 bellard
    MMX_OP2(pmulhw);
1969 085339a1 bellard
    
1970 085339a1 bellard
    MMX_OP2(psubsb);
1971 085339a1 bellard
    MMX_OP2(psubsw);
1972 085339a1 bellard
    MMX_OP2(pminsw);
1973 085339a1 bellard
    MMX_OP2(por);
1974 085339a1 bellard
    MMX_OP2(paddsb);
1975 085339a1 bellard
    MMX_OP2(paddsw);
1976 085339a1 bellard
    MMX_OP2(pmaxsw);
1977 085339a1 bellard
    MMX_OP2(pxor);
1978 085339a1 bellard
    MMX_OP2(pmuludq);
1979 085339a1 bellard
    MMX_OP2(pmaddwd);
1980 085339a1 bellard
    MMX_OP2(psadbw);
1981 085339a1 bellard
    MMX_OP2(psubb);
1982 085339a1 bellard
    MMX_OP2(psubw);
1983 085339a1 bellard
    MMX_OP2(psubd);
1984 085339a1 bellard
    MMX_OP2(psubq);
1985 085339a1 bellard
    MMX_OP2(paddb);
1986 085339a1 bellard
    MMX_OP2(paddw);
1987 085339a1 bellard
    MMX_OP2(paddd);
1988 085339a1 bellard
1989 085339a1 bellard
    MMX_OP2(pavgb);
1990 085339a1 bellard
    MMX_OP2(pavgw);
1991 085339a1 bellard
1992 085339a1 bellard
    asm volatile ("pinsrw $1, %1, %0" : "=y" (r.q[0]) : "r" (0x12345678));
1993 085339a1 bellard
    printf("%-9s: r=%016llx\n", "pinsrw", r.q[0]);
1994 085339a1 bellard
1995 085339a1 bellard
    asm volatile ("pinsrw $5, %1, %0" : "=x" (r.dq) : "r" (0x12345678));
1996 085339a1 bellard
    printf("%-9s: r=%016llx%016llx\n", "pinsrw", r.q[1], r.q[0]);
1997 085339a1 bellard
1998 085339a1 bellard
    a.q[0] = test_values[0][0];
1999 085339a1 bellard
    a.q[1] = test_values[0][1];
2000 085339a1 bellard
    asm volatile ("pextrw $1, %1, %0" : "=r" (r.l[0]) : "y" (a.q[0]));
2001 085339a1 bellard
    printf("%-9s: r=%08x\n", "pextrw", r.l[0]);
2002 085339a1 bellard
2003 085339a1 bellard
    asm volatile ("pextrw $5, %1, %0" : "=r" (r.l[0]) : "x" (a.dq));
2004 085339a1 bellard
    printf("%-9s: r=%08x\n", "pextrw", r.l[0]);
2005 085339a1 bellard
2006 085339a1 bellard
    asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "y" (a.q[0]));
2007 085339a1 bellard
    printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
2008 085339a1 bellard
    
2009 085339a1 bellard
    asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "x" (a.dq));
2010 085339a1 bellard
    printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
2011 085339a1 bellard
2012 085339a1 bellard
    asm volatile ("emms");
2013 085339a1 bellard
2014 085339a1 bellard
    SSE_OP2(punpcklqdq);
2015 085339a1 bellard
    SSE_OP2(punpckhqdq);
2016 085339a1 bellard
    SSE_OP2(andps);
2017 085339a1 bellard
    SSE_OP2(andpd);
2018 085339a1 bellard
    SSE_OP2(andnps);
2019 085339a1 bellard
    SSE_OP2(andnpd);
2020 085339a1 bellard
    SSE_OP2(orps);
2021 085339a1 bellard
    SSE_OP2(orpd);
2022 085339a1 bellard
    SSE_OP2(xorps);
2023 085339a1 bellard
    SSE_OP2(xorpd);
2024 085339a1 bellard
2025 085339a1 bellard
    SSE_OP2(unpcklps);
2026 085339a1 bellard
    SSE_OP2(unpcklpd);
2027 085339a1 bellard
    SSE_OP2(unpckhps);
2028 085339a1 bellard
    SSE_OP2(unpckhpd);
2029 085339a1 bellard
2030 085339a1 bellard
    PSHUF_OP(shufps, 0x78);
2031 085339a1 bellard
    PSHUF_OP(shufpd, 0x02);
2032 085339a1 bellard
2033 085339a1 bellard
    PSHUF_OP(pshufd, 0x78);
2034 085339a1 bellard
    PSHUF_OP(pshuflw, 0x78);
2035 085339a1 bellard
    PSHUF_OP(pshufhw, 0x78);
2036 085339a1 bellard
2037 085339a1 bellard
    SHIFT_OP(psrlw, 7);
2038 085339a1 bellard
    SHIFT_OP(psrlw, 16);
2039 085339a1 bellard
    SHIFT_OP(psraw, 7);
2040 085339a1 bellard
    SHIFT_OP(psraw, 16);
2041 085339a1 bellard
    SHIFT_OP(psllw, 7);
2042 085339a1 bellard
    SHIFT_OP(psllw, 16);
2043 085339a1 bellard
2044 085339a1 bellard
    SHIFT_OP(psrld, 7);
2045 085339a1 bellard
    SHIFT_OP(psrld, 32);
2046 085339a1 bellard
    SHIFT_OP(psrad, 7);
2047 085339a1 bellard
    SHIFT_OP(psrad, 32);
2048 085339a1 bellard
    SHIFT_OP(pslld, 7);
2049 085339a1 bellard
    SHIFT_OP(pslld, 32);
2050 085339a1 bellard
2051 085339a1 bellard
    SHIFT_OP(psrlq, 7);
2052 085339a1 bellard
    SHIFT_OP(psrlq, 32);
2053 085339a1 bellard
    SHIFT_OP(psllq, 7);
2054 085339a1 bellard
    SHIFT_OP(psllq, 32);
2055 085339a1 bellard
2056 085339a1 bellard
    SHIFT_IM(psrldq, 16);
2057 085339a1 bellard
    SHIFT_IM(psrldq, 7);
2058 085339a1 bellard
    SHIFT_IM(pslldq, 16);
2059 085339a1 bellard
    SHIFT_IM(pslldq, 7);
2060 085339a1 bellard
2061 085339a1 bellard
    MOVMSK(movmskps);
2062 085339a1 bellard
    MOVMSK(movmskpd);
2063 085339a1 bellard
2064 085339a1 bellard
    /* FPU specific ops */
2065 085339a1 bellard
2066 085339a1 bellard
    {
2067 085339a1 bellard
        uint32_t mxcsr;
2068 085339a1 bellard
        asm volatile("stmxcsr %0" : "=m" (mxcsr));
2069 085339a1 bellard
        printf("mxcsr=%08x\n", mxcsr & 0x1f80);
2070 085339a1 bellard
        asm volatile("ldmxcsr %0" : : "m" (mxcsr));
2071 085339a1 bellard
    }
2072 085339a1 bellard
2073 085339a1 bellard
    test_sse_comi(2, -1);
2074 085339a1 bellard
    test_sse_comi(2, 2);
2075 085339a1 bellard
    test_sse_comi(2, 3);
2076 085339a1 bellard
2077 085339a1 bellard
    a.s[0] = 2.7;
2078 085339a1 bellard
    a.s[1] = 3.4;
2079 085339a1 bellard
    a.s[2] = 4;
2080 085339a1 bellard
    a.s[3] = -6.3;
2081 085339a1 bellard
    b.s[0] = 45.7;
2082 085339a1 bellard
    b.s[1] = 353.4;
2083 085339a1 bellard
    b.s[2] = 4;
2084 085339a1 bellard
    b.s[3] = 56.3;
2085 085339a1 bellard
    SSE_OPS(add);
2086 085339a1 bellard
    SSE_OPS(mul);
2087 085339a1 bellard
    SSE_OPS(sub);
2088 085339a1 bellard
    SSE_OPS(min);
2089 085339a1 bellard
    SSE_OPS(div);
2090 085339a1 bellard
    SSE_OPS(max);
2091 085339a1 bellard
    SSE_OPS(sqrt);
2092 085339a1 bellard
    SSE_OPS(cmpeq);
2093 085339a1 bellard
    SSE_OPS(cmplt);
2094 085339a1 bellard
    SSE_OPS(cmple);
2095 085339a1 bellard
    SSE_OPS(cmpunord);
2096 085339a1 bellard
    SSE_OPS(cmpneq);
2097 085339a1 bellard
    SSE_OPS(cmpnlt);
2098 085339a1 bellard
    SSE_OPS(cmpnle);
2099 085339a1 bellard
    SSE_OPS(cmpord);
2100 085339a1 bellard
2101 085339a1 bellard
    a.d[0] = 2.7;
2102 085339a1 bellard
    a.d[1] = -3.4;
2103 085339a1 bellard
    b.d[0] = 45.7;
2104 085339a1 bellard
    b.d[1] = -53.4;
2105 085339a1 bellard
    SSE_OPD(add);
2106 085339a1 bellard
    SSE_OPD(mul);
2107 085339a1 bellard
    SSE_OPD(sub);
2108 085339a1 bellard
    SSE_OPD(min);
2109 085339a1 bellard
    SSE_OPD(div);
2110 085339a1 bellard
    SSE_OPD(max);
2111 085339a1 bellard
    SSE_OPD(sqrt);
2112 085339a1 bellard
    SSE_OPD(cmpeq);
2113 085339a1 bellard
    SSE_OPD(cmplt);
2114 085339a1 bellard
    SSE_OPD(cmple);
2115 085339a1 bellard
    SSE_OPD(cmpunord);
2116 085339a1 bellard
    SSE_OPD(cmpneq);
2117 085339a1 bellard
    SSE_OPD(cmpnlt);
2118 085339a1 bellard
    SSE_OPD(cmpnle);
2119 085339a1 bellard
    SSE_OPD(cmpord);
2120 085339a1 bellard
    
2121 085339a1 bellard
    /* float to float/int */
2122 085339a1 bellard
    a.s[0] = 2.7;
2123 085339a1 bellard
    a.s[1] = 3.4;
2124 085339a1 bellard
    a.s[2] = 4;
2125 085339a1 bellard
    a.s[3] = -6.3;
2126 085339a1 bellard
    CVT_OP_XMM(cvtps2pd);
2127 085339a1 bellard
    CVT_OP_XMM(cvtss2sd);
2128 085339a1 bellard
    CVT_OP_XMM2MMX(cvtps2pi);
2129 085339a1 bellard
    CVT_OP_XMM2MMX(cvttps2pi);
2130 085339a1 bellard
    CVT_OP_XMM2REG(cvtss2si);
2131 085339a1 bellard
    CVT_OP_XMM2REG(cvttss2si);
2132 085339a1 bellard
    CVT_OP_XMM(cvtps2dq);
2133 085339a1 bellard
    CVT_OP_XMM(cvttps2dq);
2134 085339a1 bellard
2135 085339a1 bellard
    a.d[0] = 2.6;
2136 085339a1 bellard
    a.d[1] = -3.4;
2137 085339a1 bellard
    CVT_OP_XMM(cvtpd2ps);
2138 085339a1 bellard
    CVT_OP_XMM(cvtsd2ss);
2139 085339a1 bellard
    CVT_OP_XMM2MMX(cvtpd2pi);
2140 085339a1 bellard
    CVT_OP_XMM2MMX(cvttpd2pi);
2141 085339a1 bellard
    CVT_OP_XMM2REG(cvtsd2si);
2142 085339a1 bellard
    CVT_OP_XMM2REG(cvttsd2si);
2143 085339a1 bellard
    CVT_OP_XMM(cvtpd2dq);
2144 085339a1 bellard
    CVT_OP_XMM(cvttpd2dq);
2145 085339a1 bellard
2146 085339a1 bellard
    /* int to float */
2147 085339a1 bellard
    a.l[0] = -6;
2148 085339a1 bellard
    a.l[1] = 2;
2149 085339a1 bellard
    a.l[2] = 100;
2150 085339a1 bellard
    a.l[3] = -60000;
2151 085339a1 bellard
    CVT_OP_MMX2XMM(cvtpi2ps);
2152 085339a1 bellard
    CVT_OP_MMX2XMM(cvtpi2pd);
2153 085339a1 bellard
    CVT_OP_REG2XMM(cvtsi2ss);
2154 085339a1 bellard
    CVT_OP_REG2XMM(cvtsi2sd);
2155 085339a1 bellard
    CVT_OP_XMM(cvtdq2ps);
2156 085339a1 bellard
    CVT_OP_XMM(cvtdq2pd);
2157 085339a1 bellard
2158 085339a1 bellard
    /* XXX: test PNI insns */
2159 085339a1 bellard
#if 0
2160 085339a1 bellard
    SSE_OP2(movshdup);
2161 085339a1 bellard
#endif
2162 a4682cc2 bellard
    asm volatile ("emms");
2163 085339a1 bellard
}
2164 085339a1 bellard
2165 085339a1 bellard
#endif
2166 085339a1 bellard
2167 4d1135e4 bellard
static void *call_end __init_call = NULL;
2168 4d1135e4 bellard
2169 4d1135e4 bellard
int main(int argc, char **argv)
2170 4d1135e4 bellard
{
2171 4d1135e4 bellard
    void **ptr;
2172 4d1135e4 bellard
    void (*func)(void);
2173 4b74fe1f bellard
2174 4d1135e4 bellard
    ptr = &call_start + 1;
2175 4d1135e4 bellard
    while (*ptr != NULL) {
2176 4d1135e4 bellard
        func = *ptr++;
2177 4d1135e4 bellard
        func();
2178 4d1135e4 bellard
    }
2179 9d8e9c09 bellard
    test_bsx();
2180 d57c4e01 bellard
    test_mul();
2181 4d1135e4 bellard
    test_jcc();
2182 9d8e9c09 bellard
    test_floats();
2183 55480af8 bellard
    test_bcd();
2184 1a9353d2 bellard
    test_xchg();
2185 e1d4294a bellard
    test_string();
2186 e1d4294a bellard
    test_misc();
2187 6dbad63e bellard
    test_lea();
2188 6dbad63e bellard
    test_segs();
2189 e5918247 bellard
    test_code16();
2190 acae4681 bellard
#ifdef TEST_VM86
2191 3a27ad0b bellard
    test_vm86();
2192 acae4681 bellard
#endif
2193 3a27ad0b bellard
    test_exceptions();
2194 3a27ad0b bellard
    test_self_modifying_code();
2195 3ff0631e bellard
    test_single_step();
2196 61a8c4ec bellard
    test_enter();
2197 085339a1 bellard
#ifdef TEST_SSE
2198 085339a1 bellard
    test_sse();
2199 a4682cc2 bellard
    test_fxsave();
2200 085339a1 bellard
#endif
2201 4d1135e4 bellard
    return 0;
2202 4d1135e4 bellard
}