Statistics
| Branch: | Revision:

root / tests / test-i386.c @ 579a97f7

History | View | Annotate | Download (67.6 kB)

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