Statistics
| Branch: | Revision:

root / tests / test-i386.c @ 7aaabde7

History | View | Annotate | Download (67.7 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 be98f1f8 bellard
union float64u q_nan = { .l = 0xFFF8000000000000LL };
707 be98f1f8 bellard
union float64u s_nan = { .l = 0xFFF0000000000000LL };
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 be98f1f8 bellard
        uint16_t val16;
823 be98f1f8 bellard
        val16 = (fpuc & ~0x0c00) | (i << 10);
824 be98f1f8 bellard
        asm volatile ("fldcw %0" : : "m" (val16));
825 ea768640 bellard
        asm volatile ("fist %0" : "=m" (wa) : "t" (a));
826 ea768640 bellard
        asm volatile ("fistl %0" : "=m" (ia) : "t" (a));
827 ea768640 bellard
        asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st");
828 ea768640 bellard
        asm volatile ("frndint ; fstl %0" : "=m" (ra) : "t" (a));
829 ea768640 bellard
        asm volatile ("fldcw %0" : : "m" (fpuc));
830 ea768640 bellard
        printf("(short)a = %d\n", wa);
831 ea768640 bellard
        printf("(int)a = %d\n", ia);
832 776f2227 bellard
        printf("(int64_t)a = " FMT64X "\n", lla);
833 ea768640 bellard
        printf("rint(a) = %f\n", ra);
834 ea768640 bellard
    }
835 9d8e9c09 bellard
}
836 9d8e9c09 bellard
837 9d8e9c09 bellard
#define TEST(N) \
838 9d8e9c09 bellard
    asm("fld" #N : "=t" (a)); \
839 9d8e9c09 bellard
    printf("fld" #N "= %f\n", a);
840 9d8e9c09 bellard
841 9d8e9c09 bellard
void test_fconst(void)
842 9d8e9c09 bellard
{
843 9d8e9c09 bellard
    double a;
844 9d8e9c09 bellard
    TEST(1);
845 9d8e9c09 bellard
    TEST(l2t);
846 9d8e9c09 bellard
    TEST(l2e);
847 9d8e9c09 bellard
    TEST(pi);
848 9d8e9c09 bellard
    TEST(lg2);
849 9d8e9c09 bellard
    TEST(ln2);
850 9d8e9c09 bellard
    TEST(z);
851 9d8e9c09 bellard
}
852 9d8e9c09 bellard
853 c5e9815d bellard
void test_fbcd(double a)
854 c5e9815d bellard
{
855 c5e9815d bellard
    unsigned short bcd[5];
856 c5e9815d bellard
    double b;
857 c5e9815d bellard
858 c5e9815d bellard
    asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
859 c5e9815d bellard
    asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
860 5fafdf24 ths
    printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",
861 c5e9815d bellard
           a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
862 c5e9815d bellard
}
863 c5e9815d bellard
864 6b2b6112 bellard
#define TEST_ENV(env, save, restore)\
865 03bfca94 bellard
{\
866 03bfca94 bellard
    memset((env), 0xaa, sizeof(*(env)));\
867 6b2b6112 bellard
    for(i=0;i<5;i++)\
868 6b2b6112 bellard
        asm volatile ("fldl %0" : : "m" (dtab[i]));\
869 085339a1 bellard
    asm volatile (save " %0\n" : : "m" (*(env)));\
870 085339a1 bellard
    asm volatile (restore " %0\n": : "m" (*(env)));\
871 6b2b6112 bellard
    for(i=0;i<5;i++)\
872 6b2b6112 bellard
        asm volatile ("fstpl %0" : "=m" (rtab[i]));\
873 6b2b6112 bellard
    for(i=0;i<5;i++)\
874 6b2b6112 bellard
        printf("res[%d]=%f\n", i, rtab[i]);\
875 03bfca94 bellard
    printf("fpuc=%04x fpus=%04x fptag=%04x\n",\
876 03bfca94 bellard
           (env)->fpuc,\
877 03bfca94 bellard
           (env)->fpus & 0xff00,\
878 03bfca94 bellard
           (env)->fptag);\
879 03bfca94 bellard
}
880 03bfca94 bellard
881 03bfca94 bellard
void test_fenv(void)
882 03bfca94 bellard
{
883 03bfca94 bellard
    struct __attribute__((packed)) {
884 03bfca94 bellard
        uint16_t fpuc;
885 03bfca94 bellard
        uint16_t dummy1;
886 03bfca94 bellard
        uint16_t fpus;
887 03bfca94 bellard
        uint16_t dummy2;
888 03bfca94 bellard
        uint16_t fptag;
889 03bfca94 bellard
        uint16_t dummy3;
890 03bfca94 bellard
        uint32_t ignored[4];
891 03bfca94 bellard
        long double fpregs[8];
892 03bfca94 bellard
    } float_env32;
893 03bfca94 bellard
    struct __attribute__((packed)) {
894 03bfca94 bellard
        uint16_t fpuc;
895 03bfca94 bellard
        uint16_t fpus;
896 03bfca94 bellard
        uint16_t fptag;
897 03bfca94 bellard
        uint16_t ignored[4];
898 03bfca94 bellard
        long double fpregs[8];
899 03bfca94 bellard
    } float_env16;
900 6b2b6112 bellard
    double dtab[8];
901 6b2b6112 bellard
    double rtab[8];
902 6b2b6112 bellard
    int i;
903 6b2b6112 bellard
904 6b2b6112 bellard
    for(i=0;i<8;i++)
905 6b2b6112 bellard
        dtab[i] = i + 1;
906 03bfca94 bellard
907 6b2b6112 bellard
    TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv");
908 6b2b6112 bellard
    TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor");
909 6b2b6112 bellard
    TEST_ENV(&float_env32, "fnstenv", "fldenv");
910 6b2b6112 bellard
    TEST_ENV(&float_env32, "fnsave", "frstor");
911 665656a9 bellard
912 665656a9 bellard
    /* test for ffree */
913 665656a9 bellard
    for(i=0;i<5;i++)
914 665656a9 bellard
        asm volatile ("fldl %0" : : "m" (dtab[i]));
915 665656a9 bellard
    asm volatile("ffree %st(2)");
916 665656a9 bellard
    asm volatile ("fnstenv %0\n" : : "m" (float_env32));
917 665656a9 bellard
    asm volatile ("fninit");
918 665656a9 bellard
    printf("fptag=%04x\n", float_env32.fptag);
919 03bfca94 bellard
}
920 03bfca94 bellard
921 75175024 bellard
922 75175024 bellard
#define TEST_FCMOV(a, b, eflags, CC)\
923 75175024 bellard
{\
924 75175024 bellard
    double res;\
925 75175024 bellard
    asm("push %3\n"\
926 75175024 bellard
        "popf\n"\
927 75175024 bellard
        "fcmov" CC " %2, %0\n"\
928 75175024 bellard
        : "=t" (res)\
929 75175024 bellard
        : "0" (a), "u" (b), "g" (eflags));\
930 776f2227 bellard
    printf("fcmov%s eflags=0x%04lx-> %f\n", \
931 776f2227 bellard
           CC, (long)eflags, res);\
932 75175024 bellard
}
933 75175024 bellard
934 75175024 bellard
void test_fcmov(void)
935 75175024 bellard
{
936 75175024 bellard
    double a, b;
937 776f2227 bellard
    long eflags, i;
938 75175024 bellard
939 75175024 bellard
    a = 1.0;
940 75175024 bellard
    b = 2.0;
941 75175024 bellard
    for(i = 0; i < 4; i++) {
942 75175024 bellard
        eflags = 0;
943 75175024 bellard
        if (i & 1)
944 75175024 bellard
            eflags |= CC_C;
945 75175024 bellard
        if (i & 2)
946 75175024 bellard
            eflags |= CC_Z;
947 75175024 bellard
        TEST_FCMOV(a, b, eflags, "b");
948 75175024 bellard
        TEST_FCMOV(a, b, eflags, "e");
949 75175024 bellard
        TEST_FCMOV(a, b, eflags, "be");
950 75175024 bellard
        TEST_FCMOV(a, b, eflags, "nb");
951 75175024 bellard
        TEST_FCMOV(a, b, eflags, "ne");
952 75175024 bellard
        TEST_FCMOV(a, b, eflags, "nbe");
953 75175024 bellard
    }
954 75175024 bellard
    TEST_FCMOV(a, b, 0, "u");
955 9cdf757f bellard
    TEST_FCMOV(a, b, CC_P, "u");
956 9cdf757f bellard
    TEST_FCMOV(a, b, 0, "nu");
957 75175024 bellard
    TEST_FCMOV(a, b, CC_P, "nu");
958 75175024 bellard
}
959 75175024 bellard
960 9d8e9c09 bellard
void test_floats(void)
961 9d8e9c09 bellard
{
962 9d8e9c09 bellard
    test_fops(2, 3);
963 9d8e9c09 bellard
    test_fops(1.4, -5);
964 9d8e9c09 bellard
    test_fcmp(2, -1);
965 9d8e9c09 bellard
    test_fcmp(2, 2);
966 9d8e9c09 bellard
    test_fcmp(2, 3);
967 86bd2ca5 bellard
    test_fcmp(2, q_nan.d);
968 86bd2ca5 bellard
    test_fcmp(q_nan.d, -1);
969 b2a8e592 bellard
    test_fcmp(-1.0/0.0, -1);
970 b2a8e592 bellard
    test_fcmp(1.0/0.0, -1);
971 ea768640 bellard
    test_fcvt(0.5);
972 ea768640 bellard
    test_fcvt(-0.5);
973 9d8e9c09 bellard
    test_fcvt(1.0/7.0);
974 9d8e9c09 bellard
    test_fcvt(-1.0/9.0);
975 ea768640 bellard
    test_fcvt(32768);
976 ea768640 bellard
    test_fcvt(-1e20);
977 b2a8e592 bellard
    test_fcvt(-1.0/0.0);
978 b2a8e592 bellard
    test_fcvt(1.0/0.0);
979 b2a8e592 bellard
    test_fcvt(q_nan.d);
980 9d8e9c09 bellard
    test_fconst();
981 be98f1f8 bellard
    test_fbcd(1234567890123456.0);
982 be98f1f8 bellard
    test_fbcd(-123451234567890.0);
983 03bfca94 bellard
    test_fenv();
984 75175024 bellard
    if (TEST_CMOV) {
985 75175024 bellard
        test_fcmov();
986 75175024 bellard
    }
987 9d8e9c09 bellard
}
988 4b74fe1f bellard
989 55480af8 bellard
/**********************************************/
990 776f2227 bellard
#if !defined(__x86_64__)
991 55480af8 bellard
992 55480af8 bellard
#define TEST_BCD(op, op0, cc_in, cc_mask)\
993 55480af8 bellard
{\
994 55480af8 bellard
    int res, flags;\
995 55480af8 bellard
    res = op0;\
996 55480af8 bellard
    flags = cc_in;\
997 55480af8 bellard
    asm ("push %3\n\t"\
998 55480af8 bellard
         "popf\n\t"\
999 55480af8 bellard
         #op "\n\t"\
1000 55480af8 bellard
         "pushf\n\t"\
1001 776f2227 bellard
         "pop %1\n\t"\
1002 55480af8 bellard
        : "=a" (res), "=g" (flags)\
1003 55480af8 bellard
        : "0" (res), "1" (flags));\
1004 55480af8 bellard
    printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\
1005 55480af8 bellard
           #op, op0, res, cc_in, flags & cc_mask);\
1006 55480af8 bellard
}
1007 55480af8 bellard
1008 55480af8 bellard
void test_bcd(void)
1009 55480af8 bellard
{
1010 55480af8 bellard
    TEST_BCD(daa, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1011 55480af8 bellard
    TEST_BCD(daa, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1012 55480af8 bellard
    TEST_BCD(daa, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1013 55480af8 bellard
    TEST_BCD(daa, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1014 55480af8 bellard
    TEST_BCD(daa, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1015 55480af8 bellard
    TEST_BCD(daa, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1016 55480af8 bellard
    TEST_BCD(daa, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1017 55480af8 bellard
    TEST_BCD(daa, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1018 55480af8 bellard
    TEST_BCD(daa, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1019 55480af8 bellard
    TEST_BCD(daa, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1020 55480af8 bellard
    TEST_BCD(daa, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1021 55480af8 bellard
    TEST_BCD(daa, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1022 55480af8 bellard
    TEST_BCD(daa, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1023 55480af8 bellard
1024 55480af8 bellard
    TEST_BCD(das, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1025 55480af8 bellard
    TEST_BCD(das, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1026 55480af8 bellard
    TEST_BCD(das, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1027 55480af8 bellard
    TEST_BCD(das, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1028 55480af8 bellard
    TEST_BCD(das, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1029 55480af8 bellard
    TEST_BCD(das, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1030 55480af8 bellard
    TEST_BCD(das, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1031 55480af8 bellard
    TEST_BCD(das, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1032 55480af8 bellard
    TEST_BCD(das, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1033 55480af8 bellard
    TEST_BCD(das, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1034 55480af8 bellard
    TEST_BCD(das, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1035 55480af8 bellard
    TEST_BCD(das, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1036 55480af8 bellard
    TEST_BCD(das, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1037 55480af8 bellard
1038 55480af8 bellard
    TEST_BCD(aaa, 0x12340205, CC_A, (CC_C | CC_A));
1039 55480af8 bellard
    TEST_BCD(aaa, 0x12340306, CC_A, (CC_C | CC_A));
1040 55480af8 bellard
    TEST_BCD(aaa, 0x1234040a, CC_A, (CC_C | CC_A));
1041 55480af8 bellard
    TEST_BCD(aaa, 0x123405fa, CC_A, (CC_C | CC_A));
1042 55480af8 bellard
    TEST_BCD(aaa, 0x12340205, 0, (CC_C | CC_A));
1043 55480af8 bellard
    TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A));
1044 55480af8 bellard
    TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A));
1045 55480af8 bellard
    TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A));
1046 3b46e624 ths
1047 55480af8 bellard
    TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A));
1048 55480af8 bellard
    TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A));
1049 55480af8 bellard
    TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A));
1050 55480af8 bellard
    TEST_BCD(aas, 0x123405fa, CC_A, (CC_C | CC_A));
1051 55480af8 bellard
    TEST_BCD(aas, 0x12340205, 0, (CC_C | CC_A));
1052 55480af8 bellard
    TEST_BCD(aas, 0x12340306, 0, (CC_C | CC_A));
1053 55480af8 bellard
    TEST_BCD(aas, 0x1234040a, 0, (CC_C | CC_A));
1054 55480af8 bellard
    TEST_BCD(aas, 0x123405fa, 0, (CC_C | CC_A));
1055 55480af8 bellard
1056 55480af8 bellard
    TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
1057 55480af8 bellard
    TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
1058 55480af8 bellard
}
1059 776f2227 bellard
#endif
1060 55480af8 bellard
1061 e5918247 bellard
#define TEST_XCHG(op, size, opconst)\
1062 e5918247 bellard
{\
1063 776f2227 bellard
    long op0, op1;\
1064 776f2227 bellard
    op0 = i2l(0x12345678);\
1065 776f2227 bellard
    op1 = i2l(0xfbca7654);\
1066 e5918247 bellard
    asm(#op " %" size "0, %" size "1" \
1067 e5918247 bellard
        : "=q" (op0), opconst (op1) \
1068 e5918247 bellard
        : "0" (op0), "1" (op1));\
1069 776f2227 bellard
    printf("%-10s A=" FMTLX " B=" FMTLX "\n",\
1070 e5918247 bellard
           #op, op0, op1);\
1071 e5918247 bellard
}
1072 e5918247 bellard
1073 e5918247 bellard
#define TEST_CMPXCHG(op, size, opconst, eax)\
1074 e5918247 bellard
{\
1075 776f2227 bellard
    long op0, op1, op2;\
1076 776f2227 bellard
    op0 = i2l(0x12345678);\
1077 776f2227 bellard
    op1 = i2l(0xfbca7654);\
1078 776f2227 bellard
    op2 = i2l(eax);\
1079 e5918247 bellard
    asm(#op " %" size "0, %" size "1" \
1080 e5918247 bellard
        : "=q" (op0), opconst (op1) \
1081 776f2227 bellard
        : "0" (op0), "1" (op1), "a" (op2));\
1082 776f2227 bellard
    printf("%-10s EAX=" FMTLX " A=" FMTLX " C=" FMTLX "\n",\
1083 776f2227 bellard
           #op, op2, op0, op1);\
1084 e5918247 bellard
}
1085 e5918247 bellard
1086 e5918247 bellard
void test_xchg(void)
1087 e5918247 bellard
{
1088 776f2227 bellard
#if defined(__x86_64__)
1089 776f2227 bellard
    TEST_XCHG(xchgq, "", "=q");
1090 776f2227 bellard
#endif
1091 776f2227 bellard
    TEST_XCHG(xchgl, "k", "=q");
1092 e5918247 bellard
    TEST_XCHG(xchgw, "w", "=q");
1093 e5918247 bellard
    TEST_XCHG(xchgb, "b", "=q");
1094 e5918247 bellard
1095 776f2227 bellard
#if defined(__x86_64__)
1096 776f2227 bellard
    TEST_XCHG(xchgq, "", "=m");
1097 776f2227 bellard
#endif
1098 776f2227 bellard
    TEST_XCHG(xchgl, "k", "=m");
1099 e5918247 bellard
    TEST_XCHG(xchgw, "w", "=m");
1100 e5918247 bellard
    TEST_XCHG(xchgb, "b", "=m");
1101 e5918247 bellard
1102 776f2227 bellard
#if defined(__x86_64__)
1103 776f2227 bellard
    TEST_XCHG(xaddq, "", "=q");
1104 776f2227 bellard
#endif
1105 776f2227 bellard
    TEST_XCHG(xaddl, "k", "=q");
1106 e5918247 bellard
    TEST_XCHG(xaddw, "w", "=q");
1107 e5918247 bellard
    TEST_XCHG(xaddb, "b", "=q");
1108 e5918247 bellard
1109 d575b78a bellard
    {
1110 d575b78a bellard
        int res;
1111 d575b78a bellard
        res = 0x12345678;
1112 d575b78a bellard
        asm("xaddl %1, %0" : "=r" (res) : "0" (res));
1113 d575b78a bellard
        printf("xaddl same res=%08x\n", res);
1114 d575b78a bellard
    }
1115 d575b78a bellard
1116 776f2227 bellard
#if defined(__x86_64__)
1117 776f2227 bellard
    TEST_XCHG(xaddq, "", "=m");
1118 776f2227 bellard
#endif
1119 776f2227 bellard
    TEST_XCHG(xaddl, "k", "=m");
1120 e5918247 bellard
    TEST_XCHG(xaddw, "w", "=m");
1121 e5918247 bellard
    TEST_XCHG(xaddb, "b", "=m");
1122 e5918247 bellard
1123 776f2227 bellard
#if defined(__x86_64__)
1124 776f2227 bellard
    TEST_CMPXCHG(cmpxchgq, "", "=q", 0xfbca7654);
1125 776f2227 bellard
#endif
1126 776f2227 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "=q", 0xfbca7654);
1127 e5918247 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654);
1128 e5918247 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654);
1129 e5918247 bellard
1130 776f2227 bellard
#if defined(__x86_64__)
1131 776f2227 bellard
    TEST_CMPXCHG(cmpxchgq, "", "=q", 0xfffefdfc);
1132 776f2227 bellard
#endif
1133 776f2227 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "=q", 0xfffefdfc);
1134 e5918247 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc);
1135 e5918247 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc);
1136 e5918247 bellard
1137 776f2227 bellard
#if defined(__x86_64__)
1138 776f2227 bellard
    TEST_CMPXCHG(cmpxchgq, "", "=m", 0xfbca7654);
1139 776f2227 bellard
#endif
1140 776f2227 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "=m", 0xfbca7654);
1141 e5918247 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654);
1142 e5918247 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654);
1143 e5918247 bellard
1144 776f2227 bellard
#if defined(__x86_64__)
1145 776f2227 bellard
    TEST_CMPXCHG(cmpxchgq, "", "=m", 0xfffefdfc);
1146 776f2227 bellard
#endif
1147 776f2227 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "=m", 0xfffefdfc);
1148 e5918247 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc);
1149 e5918247 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc);
1150 d575b78a bellard
1151 d575b78a bellard
    {
1152 d575b78a bellard
        uint64_t op0, op1, op2;
1153 776f2227 bellard
        long i, eflags;
1154 d575b78a bellard
1155 d575b78a bellard
        for(i = 0; i < 2; i++) {
1156 be98f1f8 bellard
            op0 = 0x123456789abcdLL;
1157 d575b78a bellard
            if (i == 0)
1158 be98f1f8 bellard
                op1 = 0xfbca765423456LL;
1159 d575b78a bellard
            else
1160 d575b78a bellard
                op1 = op0;
1161 be98f1f8 bellard
            op2 = 0x6532432432434LL;
1162 5fafdf24 ths
            asm("cmpxchg8b %1\n"
1163 d575b78a bellard
                "pushf\n"
1164 776f2227 bellard
                "pop %2\n"
1165 d575b78a bellard
                : "=A" (op0), "=m" (op1), "=g" (eflags)
1166 d575b78a bellard
                : "0" (op0), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32)));
1167 5fafdf24 ths
            printf("cmpxchg8b: op0=" FMT64X " op1=" FMT64X " CC=%02lx\n",
1168 d575b78a bellard
                    op0, op1, eflags & CC_Z);
1169 d575b78a bellard
        }
1170 d575b78a bellard
    }
1171 e5918247 bellard
}
1172 e5918247 bellard
1173 776f2227 bellard
#ifdef TEST_SEGS
1174 6dbad63e bellard
/**********************************************/
1175 6dbad63e bellard
/* segmentation tests */
1176 6dbad63e bellard
1177 be98f1f8 bellard
#include <sys/syscall.h>
1178 be98f1f8 bellard
#include <unistd.h>
1179 6dbad63e bellard
#include <asm/ldt.h>
1180 73bdea19 bellard
#include <linux/version.h>
1181 6dbad63e bellard
1182 be98f1f8 bellard
static inline int modify_ldt(int func, void * ptr, unsigned long bytecount)
1183 be98f1f8 bellard
{
1184 be98f1f8 bellard
    return syscall(__NR_modify_ldt, func, ptr, bytecount);
1185 be98f1f8 bellard
}
1186 6dbad63e bellard
1187 73bdea19 bellard
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
1188 73bdea19 bellard
#define modify_ldt_ldt_s user_desc
1189 73bdea19 bellard
#endif
1190 73bdea19 bellard
1191 776f2227 bellard
#define MK_SEL(n) (((n) << 3) | 7)
1192 776f2227 bellard
1193 6dbad63e bellard
uint8_t seg_data1[4096];
1194 6dbad63e bellard
uint8_t seg_data2[4096];
1195 6dbad63e bellard
1196 288426fe bellard
#define TEST_LR(op, size, seg, mask)\
1197 288426fe bellard
{\
1198 288426fe bellard
    int res, res2;\
1199 288426fe bellard
    res = 0x12345678;\
1200 288426fe bellard
    asm (op " %" size "2, %" size "0\n" \
1201 288426fe bellard
         "movl $0, %1\n"\
1202 288426fe bellard
         "jnz 1f\n"\
1203 288426fe bellard
         "movl $1, %1\n"\
1204 288426fe bellard
         "1:\n"\
1205 288426fe bellard
         : "=r" (res), "=r" (res2) : "m" (seg), "0" (res));\
1206 288426fe bellard
    printf(op ": Z=%d %08x\n", res2, res & ~(mask));\
1207 288426fe bellard
}
1208 288426fe bellard
1209 6dbad63e bellard
/* NOTE: we use Linux modify_ldt syscall */
1210 6dbad63e bellard
void test_segs(void)
1211 6dbad63e bellard
{
1212 6dbad63e bellard
    struct modify_ldt_ldt_s ldt;
1213 6dbad63e bellard
    long long ldt_table[3];
1214 04369ff2 bellard
    int res, res2;
1215 6dbad63e bellard
    char tmp;
1216 e1d4294a bellard
    struct {
1217 e1d4294a bellard
        uint32_t offset;
1218 e1d4294a bellard
        uint16_t seg;
1219 e1d4294a bellard
    } __attribute__((packed)) segoff;
1220 6dbad63e bellard
1221 6dbad63e bellard
    ldt.entry_number = 1;
1222 6dbad63e bellard
    ldt.base_addr = (unsigned long)&seg_data1;
1223 6dbad63e bellard
    ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
1224 6dbad63e bellard
    ldt.seg_32bit = 1;
1225 6dbad63e bellard
    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
1226 6dbad63e bellard
    ldt.read_exec_only = 0;
1227 6dbad63e bellard
    ldt.limit_in_pages = 1;
1228 6dbad63e bellard
    ldt.seg_not_present = 0;
1229 6dbad63e bellard
    ldt.useable = 1;
1230 6dbad63e bellard
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
1231 6dbad63e bellard
1232 6dbad63e bellard
    ldt.entry_number = 2;
1233 6dbad63e bellard
    ldt.base_addr = (unsigned long)&seg_data2;
1234 6dbad63e bellard
    ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12;
1235 6dbad63e bellard
    ldt.seg_32bit = 1;
1236 6dbad63e bellard
    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
1237 6dbad63e bellard
    ldt.read_exec_only = 0;
1238 6dbad63e bellard
    ldt.limit_in_pages = 1;
1239 6dbad63e bellard
    ldt.seg_not_present = 0;
1240 6dbad63e bellard
    ldt.useable = 1;
1241 6dbad63e bellard
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
1242 6dbad63e bellard
1243 6dbad63e bellard
    modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */
1244 04369ff2 bellard
#if 0
1245 04369ff2 bellard
    {
1246 04369ff2 bellard
        int i;
1247 04369ff2 bellard
        for(i=0;i<3;i++)
1248 04369ff2 bellard
            printf("%d: %016Lx\n", i, ldt_table[i]);
1249 04369ff2 bellard
    }
1250 04369ff2 bellard
#endif
1251 6dbad63e bellard
    /* do some tests with fs or gs */
1252 6dbad63e bellard
    asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
1253 6dbad63e bellard
1254 6dbad63e bellard
    seg_data1[1] = 0xaa;
1255 6dbad63e bellard
    seg_data2[1] = 0x55;
1256 6dbad63e bellard
1257 6dbad63e bellard
    asm volatile ("fs movzbl 0x1, %0" : "=r" (res));
1258 6dbad63e bellard
    printf("FS[1] = %02x\n", res);
1259 6dbad63e bellard
1260 070893f4 bellard
    asm volatile ("pushl %%gs\n"
1261 070893f4 bellard
                  "movl %1, %%gs\n"
1262 070893f4 bellard
                  "gs movzbl 0x1, %0\n"
1263 070893f4 bellard
                  "popl %%gs\n"
1264 070893f4 bellard
                  : "=r" (res)
1265 070893f4 bellard
                  : "r" (MK_SEL(2)));
1266 6dbad63e bellard
    printf("GS[1] = %02x\n", res);
1267 6dbad63e bellard
1268 6dbad63e bellard
    /* tests with ds/ss (implicit segment case) */
1269 6dbad63e bellard
    tmp = 0xa5;
1270 6dbad63e bellard
    asm volatile ("pushl %%ebp\n\t"
1271 6dbad63e bellard
                  "pushl %%ds\n\t"
1272 6dbad63e bellard
                  "movl %2, %%ds\n\t"
1273 6dbad63e bellard
                  "movl %3, %%ebp\n\t"
1274 6dbad63e bellard
                  "movzbl 0x1, %0\n\t"
1275 6dbad63e bellard
                  "movzbl (%%ebp), %1\n\t"
1276 6dbad63e bellard
                  "popl %%ds\n\t"
1277 6dbad63e bellard
                  "popl %%ebp\n\t"
1278 6dbad63e bellard
                  : "=r" (res), "=r" (res2)
1279 6dbad63e bellard
                  : "r" (MK_SEL(1)), "r" (&tmp));
1280 6dbad63e bellard
    printf("DS[1] = %02x\n", res);
1281 6dbad63e bellard
    printf("SS[tmp] = %02x\n", res2);
1282 e1d4294a bellard
1283 e1d4294a bellard
    segoff.seg = MK_SEL(2);
1284 e1d4294a bellard
    segoff.offset = 0xabcdef12;
1285 5fafdf24 ths
    asm volatile("lfs %2, %0\n\t"
1286 e1d4294a bellard
                 "movl %%fs, %1\n\t"
1287 5fafdf24 ths
                 : "=r" (res), "=g" (res2)
1288 e1d4294a bellard
                 : "m" (segoff));
1289 e1d4294a bellard
    printf("FS:reg = %04x:%08x\n", res2, res);
1290 288426fe bellard
1291 288426fe bellard
    TEST_LR("larw", "w", MK_SEL(2), 0x0100);
1292 288426fe bellard
    TEST_LR("larl", "", MK_SEL(2), 0x0100);
1293 288426fe bellard
    TEST_LR("lslw", "w", MK_SEL(2), 0);
1294 288426fe bellard
    TEST_LR("lsll", "", MK_SEL(2), 0);
1295 288426fe bellard
1296 288426fe bellard
    TEST_LR("larw", "w", 0xfff8, 0);
1297 288426fe bellard
    TEST_LR("larl", "", 0xfff8, 0);
1298 288426fe bellard
    TEST_LR("lslw", "w", 0xfff8, 0);
1299 288426fe bellard
    TEST_LR("lsll", "", 0xfff8, 0);
1300 6dbad63e bellard
}
1301 55480af8 bellard
1302 e5918247 bellard
/* 16 bit code test */
1303 e5918247 bellard
extern char code16_start, code16_end;
1304 e5918247 bellard
extern char code16_func1;
1305 e5918247 bellard
extern char code16_func2;
1306 e5918247 bellard
extern char code16_func3;
1307 a300e691 bellard
1308 e5918247 bellard
void test_code16(void)
1309 1a9353d2 bellard
{
1310 e5918247 bellard
    struct modify_ldt_ldt_s ldt;
1311 e5918247 bellard
    int res, res2;
1312 a300e691 bellard
1313 e5918247 bellard
    /* build a code segment */
1314 e5918247 bellard
    ldt.entry_number = 1;
1315 e5918247 bellard
    ldt.base_addr = (unsigned long)&code16_start;
1316 e5918247 bellard
    ldt.limit = &code16_end - &code16_start;
1317 e5918247 bellard
    ldt.seg_32bit = 0;
1318 e5918247 bellard
    ldt.contents = MODIFY_LDT_CONTENTS_CODE;
1319 e5918247 bellard
    ldt.read_exec_only = 0;
1320 e5918247 bellard
    ldt.limit_in_pages = 0;
1321 e5918247 bellard
    ldt.seg_not_present = 0;
1322 e5918247 bellard
    ldt.useable = 1;
1323 e5918247 bellard
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
1324 a300e691 bellard
1325 e5918247 bellard
    /* call the first function */
1326 5fafdf24 ths
    asm volatile ("lcall %1, %2"
1327 e5918247 bellard
                  : "=a" (res)
1328 e5918247 bellard
                  : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc");
1329 e5918247 bellard
    printf("func1() = 0x%08x\n", res);
1330 5fafdf24 ths
    asm volatile ("lcall %2, %3"
1331 e5918247 bellard
                  : "=a" (res), "=c" (res2)
1332 e5918247 bellard
                  : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc");
1333 e5918247 bellard
    printf("func2() = 0x%08x spdec=%d\n", res, res2);
1334 5fafdf24 ths
    asm volatile ("lcall %1, %2"
1335 e5918247 bellard
                  : "=a" (res)
1336 e5918247 bellard
                  : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc");
1337 e5918247 bellard
    printf("func3() = 0x%08x\n", res);
1338 1a9353d2 bellard
}
1339 776f2227 bellard
#endif
1340 1a9353d2 bellard
1341 e06e5259 bellard
#if defined(__x86_64__)
1342 e06e5259 bellard
asm(".globl func_lret\n"
1343 e06e5259 bellard
    "func_lret:\n"
1344 e06e5259 bellard
    "movl $0x87654641, %eax\n"
1345 e06e5259 bellard
    "lretq\n");
1346 e06e5259 bellard
#else
1347 e06e5259 bellard
asm(".globl func_lret\n"
1348 e06e5259 bellard
    "func_lret:\n"
1349 e06e5259 bellard
    "movl $0x87654321, %eax\n"
1350 e06e5259 bellard
    "lret\n"
1351 e06e5259 bellard
1352 e06e5259 bellard
    ".globl func_iret\n"
1353 e06e5259 bellard
    "func_iret:\n"
1354 e06e5259 bellard
    "movl $0xabcd4321, %eax\n"
1355 e06e5259 bellard
    "iret\n");
1356 e06e5259 bellard
#endif
1357 e06e5259 bellard
1358 e06e5259 bellard
extern char func_lret;
1359 e06e5259 bellard
extern char func_iret;
1360 dd3587f3 bellard
1361 e1d4294a bellard
void test_misc(void)
1362 e1d4294a bellard
{
1363 e1d4294a bellard
    char table[256];
1364 776f2227 bellard
    long res, i;
1365 e1d4294a bellard
1366 e1d4294a bellard
    for(i=0;i<256;i++) table[i] = 256 - i;
1367 e1d4294a bellard
    res = 0x12345678;
1368 e1d4294a bellard
    asm ("xlat" : "=a" (res) : "b" (table), "0" (res));
1369 776f2227 bellard
    printf("xlat: EAX=" FMTLX "\n", res);
1370 dd3587f3 bellard
1371 e06e5259 bellard
#if defined(__x86_64__)
1372 e06e5259 bellard
    {
1373 e06e5259 bellard
        static struct __attribute__((packed)) {
1374 e06e5259 bellard
            uint32_t offset;
1375 e06e5259 bellard
            uint16_t seg;
1376 e06e5259 bellard
        } desc;
1377 e06e5259 bellard
        long cs_sel;
1378 e06e5259 bellard
1379 e06e5259 bellard
        asm volatile ("mov %%cs, %0" : "=r" (cs_sel));
1380 e06e5259 bellard
1381 e06e5259 bellard
        asm volatile ("push %1\n"
1382 5fafdf24 ths
                      "call func_lret\n"
1383 e06e5259 bellard
                      : "=a" (res)
1384 e06e5259 bellard
                      : "r" (cs_sel) : "memory", "cc");
1385 e06e5259 bellard
        printf("func_lret=" FMTLX "\n", res);
1386 e06e5259 bellard
1387 e06e5259 bellard
        /* NOTE: we assume that &func_lret < 4GB */
1388 e06e5259 bellard
        desc.offset = (long)&func_lret;
1389 e06e5259 bellard
        desc.seg = cs_sel;
1390 3b46e624 ths
1391 e06e5259 bellard
        asm volatile ("xor %%rax, %%rax\n"
1392 e06e5259 bellard
                      "rex64 lcall %1\n"
1393 e06e5259 bellard
                      : "=a" (res)
1394 5fafdf24 ths
                      : "m" (desc)
1395 e06e5259 bellard
                      : "memory", "cc");
1396 e06e5259 bellard
        printf("func_lret2=" FMTLX "\n", res);
1397 e06e5259 bellard
1398 e06e5259 bellard
        asm volatile ("push %2\n"
1399 e06e5259 bellard
                      "mov $ 1f, %%rax\n"
1400 e06e5259 bellard
                      "push %%rax\n"
1401 e06e5259 bellard
                      "ljmp %1\n"
1402 e06e5259 bellard
                      "1:\n"
1403 e06e5259 bellard
                      : "=a" (res)
1404 e06e5259 bellard
                      : "m" (desc), "b" (cs_sel)
1405 e06e5259 bellard
                      : "memory", "cc");
1406 e06e5259 bellard
        printf("func_lret3=" FMTLX "\n", res);
1407 e06e5259 bellard
    }
1408 e06e5259 bellard
#else
1409 5fafdf24 ths
    asm volatile ("push %%cs ; call %1"
1410 dd3587f3 bellard
                  : "=a" (res)
1411 e06e5259 bellard
                  : "m" (func_lret): "memory", "cc");
1412 e06e5259 bellard
    printf("func_lret=" FMTLX "\n", res);
1413 dd3587f3 bellard
1414 5fafdf24 ths
    asm volatile ("pushf ; push %%cs ; call %1"
1415 dd3587f3 bellard
                  : "=a" (res)
1416 e06e5259 bellard
                  : "m" (func_iret): "memory", "cc");
1417 e06e5259 bellard
    printf("func_iret=" FMTLX "\n", res);
1418 776f2227 bellard
#endif
1419 dd3587f3 bellard
1420 776f2227 bellard
#if defined(__x86_64__)
1421 776f2227 bellard
    /* specific popl test */
1422 776f2227 bellard
    asm volatile ("push $12345432 ; push $0x9abcdef ; pop (%%rsp) ; pop %0"
1423 776f2227 bellard
                  : "=g" (res));
1424 776f2227 bellard
    printf("popl esp=" FMTLX "\n", res);
1425 776f2227 bellard
#else
1426 dd3587f3 bellard
    /* specific popl test */
1427 dd3587f3 bellard
    asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popl (%%esp) ; popl %0"
1428 dd3587f3 bellard
                  : "=g" (res));
1429 776f2227 bellard
    printf("popl esp=" FMTLX "\n", res);
1430 b2b5fb22 bellard
1431 b2b5fb22 bellard
    /* specific popw test */
1432 b2b5fb22 bellard
    asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popw (%%esp) ; addl $2, %%esp ; popl %0"
1433 b2b5fb22 bellard
                  : "=g" (res));
1434 776f2227 bellard
    printf("popw esp=" FMTLX "\n", res);
1435 776f2227 bellard
#endif
1436 e1d4294a bellard
}
1437 e1d4294a bellard
1438 e1d4294a bellard
uint8_t str_buffer[4096];
1439 e1d4294a bellard
1440 e1d4294a bellard
#define TEST_STRING1(OP, size, DF, REP)\
1441 e1d4294a bellard
{\
1442 776f2227 bellard
    long esi, edi, eax, ecx, eflags;\
1443 e1d4294a bellard
\
1444 e1d4294a bellard
    esi = (long)(str_buffer + sizeof(str_buffer) / 2);\
1445 e1d4294a bellard
    edi = (long)(str_buffer + sizeof(str_buffer) / 2) + 16;\
1446 776f2227 bellard
    eax = i2l(0x12345678);\
1447 e1d4294a bellard
    ecx = 17;\
1448 e1d4294a bellard
\
1449 776f2227 bellard
    asm volatile ("push $0\n\t"\
1450 e1d4294a bellard
                  "popf\n\t"\
1451 e1d4294a bellard
                  DF "\n\t"\
1452 e1d4294a bellard
                  REP #OP size "\n\t"\
1453 e1d4294a bellard
                  "cld\n\t"\
1454 e1d4294a bellard
                  "pushf\n\t"\
1455 776f2227 bellard
                  "pop %4\n\t"\
1456 e1d4294a bellard
                  : "=S" (esi), "=D" (edi), "=a" (eax), "=c" (ecx), "=g" (eflags)\
1457 e1d4294a bellard
                  : "0" (esi), "1" (edi), "2" (eax), "3" (ecx));\
1458 776f2227 bellard
    printf("%-10s ESI=" FMTLX " EDI=" FMTLX " EAX=" FMTLX " ECX=" FMTLX " EFL=%04x\n",\
1459 e1d4294a bellard
           REP #OP size, esi, edi, eax, ecx,\
1460 776f2227 bellard
           (int)(eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)));\
1461 e1d4294a bellard
}
1462 e1d4294a bellard
1463 e1d4294a bellard
#define TEST_STRING(OP, REP)\
1464 e1d4294a bellard
    TEST_STRING1(OP, "b", "", REP);\
1465 e1d4294a bellard
    TEST_STRING1(OP, "w", "", REP);\
1466 e1d4294a bellard
    TEST_STRING1(OP, "l", "", REP);\
1467 776f2227 bellard
    X86_64_ONLY(TEST_STRING1(OP, "q", "", REP));\
1468 e1d4294a bellard
    TEST_STRING1(OP, "b", "std", REP);\
1469 e1d4294a bellard
    TEST_STRING1(OP, "w", "std", REP);\
1470 776f2227 bellard
    TEST_STRING1(OP, "l", "std", REP);\
1471 776f2227 bellard
    X86_64_ONLY(TEST_STRING1(OP, "q", "std", REP))
1472 e1d4294a bellard
1473 e1d4294a bellard
void test_string(void)
1474 e1d4294a bellard
{
1475 e1d4294a bellard
    int i;
1476 e1d4294a bellard
    for(i = 0;i < sizeof(str_buffer); i++)
1477 e1d4294a bellard
        str_buffer[i] = i + 0x56;
1478 e1d4294a bellard
   TEST_STRING(stos, "");
1479 e1d4294a bellard
   TEST_STRING(stos, "rep ");
1480 e1d4294a bellard
   TEST_STRING(lods, ""); /* to verify stos */
1481 5fafdf24 ths
   TEST_STRING(lods, "rep ");
1482 e1d4294a bellard
   TEST_STRING(movs, "");
1483 e1d4294a bellard
   TEST_STRING(movs, "rep ");
1484 e1d4294a bellard
   TEST_STRING(lods, ""); /* to verify stos */
1485 e1d4294a bellard
1486 e1d4294a bellard
   /* XXX: better tests */
1487 e1d4294a bellard
   TEST_STRING(scas, "");
1488 e1d4294a bellard
   TEST_STRING(scas, "repz ");
1489 e1d4294a bellard
   TEST_STRING(scas, "repnz ");
1490 e1d4294a bellard
   TEST_STRING(cmps, "");
1491 e1d4294a bellard
   TEST_STRING(cmps, "repz ");
1492 e1d4294a bellard
   TEST_STRING(cmps, "repnz ");
1493 e1d4294a bellard
}
1494 e5918247 bellard
1495 776f2227 bellard
#ifdef TEST_VM86
1496 3a27ad0b bellard
/* VM86 test */
1497 3a27ad0b bellard
1498 3a27ad0b bellard
static inline void set_bit(uint8_t *a, unsigned int bit)
1499 3a27ad0b bellard
{
1500 3a27ad0b bellard
    a[bit / 8] |= (1 << (bit % 8));
1501 3a27ad0b bellard
}
1502 3a27ad0b bellard
1503 3a27ad0b bellard
static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
1504 3a27ad0b bellard
{
1505 3a27ad0b bellard
    return (uint8_t *)((seg << 4) + (reg & 0xffff));
1506 3a27ad0b bellard
}
1507 3a27ad0b bellard
1508 3a27ad0b bellard
static inline void pushw(struct vm86_regs *r, int val)
1509 3a27ad0b bellard
{
1510 3a27ad0b bellard
    r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff);
1511 3a27ad0b bellard
    *(uint16_t *)seg_to_linear(r->ss, r->esp) = val;
1512 3a27ad0b bellard
}
1513 3a27ad0b bellard
1514 be98f1f8 bellard
static inline int vm86(int func, struct vm86plus_struct *v86)
1515 be98f1f8 bellard
{
1516 be98f1f8 bellard
    return syscall(__NR_vm86, func, v86);
1517 be98f1f8 bellard
}
1518 3a27ad0b bellard
1519 3a27ad0b bellard
extern char vm86_code_start;
1520 3a27ad0b bellard
extern char vm86_code_end;
1521 3a27ad0b bellard
1522 3a27ad0b bellard
#define VM86_CODE_CS 0x100
1523 3a27ad0b bellard
#define VM86_CODE_IP 0x100
1524 3a27ad0b bellard
1525 3a27ad0b bellard
void test_vm86(void)
1526 3a27ad0b bellard
{
1527 3a27ad0b bellard
    struct vm86plus_struct ctx;
1528 3a27ad0b bellard
    struct vm86_regs *r;
1529 3a27ad0b bellard
    uint8_t *vm86_mem;
1530 3a27ad0b bellard
    int seg, ret;
1531 3a27ad0b bellard
1532 5fafdf24 ths
    vm86_mem = mmap((void *)0x00000000, 0x110000,
1533 5fafdf24 ths
                    PROT_WRITE | PROT_READ | PROT_EXEC,
1534 3a27ad0b bellard
                    MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
1535 3a27ad0b bellard
    if (vm86_mem == MAP_FAILED) {
1536 3a27ad0b bellard
        printf("ERROR: could not map vm86 memory");
1537 3a27ad0b bellard
        return;
1538 3a27ad0b bellard
    }
1539 3a27ad0b bellard
    memset(&ctx, 0, sizeof(ctx));
1540 3a27ad0b bellard
1541 3a27ad0b bellard
    /* init basic registers */
1542 3a27ad0b bellard
    r = &ctx.regs;
1543 3a27ad0b bellard
    r->eip = VM86_CODE_IP;
1544 3a27ad0b bellard
    r->esp = 0xfffe;
1545 3a27ad0b bellard
    seg = VM86_CODE_CS;
1546 3a27ad0b bellard
    r->cs = seg;
1547 3a27ad0b bellard
    r->ss = seg;
1548 3a27ad0b bellard
    r->ds = seg;
1549 3a27ad0b bellard
    r->es = seg;
1550 3a27ad0b bellard
    r->fs = seg;
1551 3a27ad0b bellard
    r->gs = seg;
1552 3a27ad0b bellard
    r->eflags = VIF_MASK;
1553 3a27ad0b bellard
1554 3a27ad0b bellard
    /* move code to proper address. We use the same layout as a .com
1555 3a27ad0b bellard
       dos program. */
1556 5fafdf24 ths
    memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP,
1557 3a27ad0b bellard
           &vm86_code_start, &vm86_code_end - &vm86_code_start);
1558 3a27ad0b bellard
1559 3a27ad0b bellard
    /* mark int 0x21 as being emulated */
1560 3a27ad0b bellard
    set_bit((uint8_t *)&ctx.int_revectored, 0x21);
1561 3a27ad0b bellard
1562 3a27ad0b bellard
    for(;;) {
1563 3a27ad0b bellard
        ret = vm86(VM86_ENTER, &ctx);
1564 3a27ad0b bellard
        switch(VM86_TYPE(ret)) {
1565 3a27ad0b bellard
        case VM86_INTx:
1566 3a27ad0b bellard
            {
1567 3ff0631e bellard
                int int_num, ah, v;
1568 3b46e624 ths
1569 3a27ad0b bellard
                int_num = VM86_ARG(ret);
1570 3a27ad0b bellard
                if (int_num != 0x21)
1571 3a27ad0b bellard
                    goto unknown_int;
1572 3a27ad0b bellard
                ah = (r->eax >> 8) & 0xff;
1573 3a27ad0b bellard
                switch(ah) {
1574 3a27ad0b bellard
                case 0x00: /* exit */
1575 3a27ad0b bellard
                    goto the_end;
1576 3a27ad0b bellard
                case 0x02: /* write char */
1577 3a27ad0b bellard
                    {
1578 3a27ad0b bellard
                        uint8_t c = r->edx;
1579 3a27ad0b bellard
                        putchar(c);
1580 3a27ad0b bellard
                    }
1581 3a27ad0b bellard
                    break;
1582 3a27ad0b bellard
                case 0x09: /* write string */
1583 3a27ad0b bellard
                    {
1584 3a27ad0b bellard
                        uint8_t c, *ptr;
1585 3a27ad0b bellard
                        ptr = seg_to_linear(r->ds, r->edx);
1586 3a27ad0b bellard
                        for(;;) {
1587 3a27ad0b bellard
                            c = *ptr++;
1588 3a27ad0b bellard
                            if (c == '$')
1589 3a27ad0b bellard
                                break;
1590 3a27ad0b bellard
                            putchar(c);
1591 3a27ad0b bellard
                        }
1592 3a27ad0b bellard
                        r->eax = (r->eax & ~0xff) | '$';
1593 3a27ad0b bellard
                    }
1594 3a27ad0b bellard
                    break;
1595 3ff0631e bellard
                case 0xff: /* extension: write eflags number in edx */
1596 3ff0631e bellard
                    v = (int)r->edx;
1597 3ff0631e bellard
#ifndef LINUX_VM86_IOPL_FIX
1598 3ff0631e bellard
                    v &= ~0x3000;
1599 3ff0631e bellard
#endif
1600 3ff0631e bellard
                    printf("%08x\n", v);
1601 3a27ad0b bellard
                    break;
1602 3a27ad0b bellard
                default:
1603 3a27ad0b bellard
                unknown_int:
1604 3a27ad0b bellard
                    printf("unsupported int 0x%02x\n", int_num);
1605 3a27ad0b bellard
                    goto the_end;
1606 3a27ad0b bellard
                }
1607 3a27ad0b bellard
            }
1608 3a27ad0b bellard
            break;
1609 3a27ad0b bellard
        case VM86_SIGNAL:
1610 3a27ad0b bellard
            /* a signal came, we just ignore that */
1611 3a27ad0b bellard
            break;
1612 3a27ad0b bellard
        case VM86_STI:
1613 3a27ad0b bellard
            break;
1614 3a27ad0b bellard
        default:
1615 3a27ad0b bellard
            printf("ERROR: unhandled vm86 return code (0x%x)\n", ret);
1616 3a27ad0b bellard
            goto the_end;
1617 3a27ad0b bellard
        }
1618 3a27ad0b bellard
    }
1619 3a27ad0b bellard
 the_end:
1620 3a27ad0b bellard
    printf("VM86 end\n");
1621 3a27ad0b bellard
    munmap(vm86_mem, 0x110000);
1622 3a27ad0b bellard
}
1623 776f2227 bellard
#endif
1624 3a27ad0b bellard
1625 3a27ad0b bellard
/* exception tests */
1626 776f2227 bellard
#if defined(__i386__) && !defined(REG_EAX)
1627 3a27ad0b bellard
#define REG_EAX EAX
1628 3a27ad0b bellard
#define REG_EBX EBX
1629 3a27ad0b bellard
#define REG_ECX ECX
1630 3a27ad0b bellard
#define REG_EDX EDX
1631 3a27ad0b bellard
#define REG_ESI ESI
1632 3a27ad0b bellard
#define REG_EDI EDI
1633 3a27ad0b bellard
#define REG_EBP EBP
1634 3a27ad0b bellard
#define REG_ESP ESP
1635 3a27ad0b bellard
#define REG_EIP EIP
1636 3a27ad0b bellard
#define REG_EFL EFL
1637 3a27ad0b bellard
#define REG_TRAPNO TRAPNO
1638 3a27ad0b bellard
#define REG_ERR ERR
1639 3a27ad0b bellard
#endif
1640 3a27ad0b bellard
1641 776f2227 bellard
#if defined(__x86_64__)
1642 776f2227 bellard
#define REG_EIP REG_RIP
1643 776f2227 bellard
#endif
1644 776f2227 bellard
1645 3a27ad0b bellard
jmp_buf jmp_env;
1646 3a27ad0b bellard
int v1;
1647 3a27ad0b bellard
int tab[2];
1648 3a27ad0b bellard
1649 3a27ad0b bellard
void sig_handler(int sig, siginfo_t *info, void *puc)
1650 3a27ad0b bellard
{
1651 3a27ad0b bellard
    struct ucontext *uc = puc;
1652 3a27ad0b bellard
1653 3a27ad0b bellard
    printf("si_signo=%d si_errno=%d si_code=%d",
1654 3a27ad0b bellard
           info->si_signo, info->si_errno, info->si_code);
1655 e3b32540 bellard
    printf(" si_addr=0x%08lx",
1656 e3b32540 bellard
           (unsigned long)info->si_addr);
1657 3a27ad0b bellard
    printf("\n");
1658 3a27ad0b bellard
1659 776f2227 bellard
    printf("trapno=" FMTLX " err=" FMTLX,
1660 776f2227 bellard
           (long)uc->uc_mcontext.gregs[REG_TRAPNO],
1661 776f2227 bellard
           (long)uc->uc_mcontext.gregs[REG_ERR]);
1662 776f2227 bellard
    printf(" EIP=" FMTLX, (long)uc->uc_mcontext.gregs[REG_EIP]);
1663 3a27ad0b bellard
    printf("\n");
1664 3a27ad0b bellard
    longjmp(jmp_env, 1);
1665 3a27ad0b bellard
}
1666 3a27ad0b bellard
1667 3a27ad0b bellard
void test_exceptions(void)
1668 3a27ad0b bellard
{
1669 3a27ad0b bellard
    struct sigaction act;
1670 3a27ad0b bellard
    volatile int val;
1671 3b46e624 ths
1672 3a27ad0b bellard
    act.sa_sigaction = sig_handler;
1673 3a27ad0b bellard
    sigemptyset(&act.sa_mask);
1674 776f2227 bellard
    act.sa_flags = SA_SIGINFO | SA_NODEFER;
1675 3a27ad0b bellard
    sigaction(SIGFPE, &act, NULL);
1676 3a27ad0b bellard
    sigaction(SIGILL, &act, NULL);
1677 3a27ad0b bellard
    sigaction(SIGSEGV, &act, NULL);
1678 e3b32540 bellard
    sigaction(SIGBUS, &act, NULL);
1679 3a27ad0b bellard
    sigaction(SIGTRAP, &act, NULL);
1680 3a27ad0b bellard
1681 3a27ad0b bellard
    /* test division by zero reporting */
1682 e3b32540 bellard
    printf("DIVZ exception:\n");
1683 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1684 3a27ad0b bellard
        /* now divide by zero */
1685 3a27ad0b bellard
        v1 = 0;
1686 3a27ad0b bellard
        v1 = 2 / v1;
1687 3a27ad0b bellard
    }
1688 3a27ad0b bellard
1689 776f2227 bellard
#if !defined(__x86_64__)
1690 e3b32540 bellard
    printf("BOUND exception:\n");
1691 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1692 3a27ad0b bellard
        /* bound exception */
1693 3a27ad0b bellard
        tab[0] = 1;
1694 3a27ad0b bellard
        tab[1] = 10;
1695 e82d8ade bellard
        asm volatile ("bound %0, %1" : : "r" (11), "m" (tab[0]));
1696 3a27ad0b bellard
    }
1697 776f2227 bellard
#endif
1698 3a27ad0b bellard
1699 776f2227 bellard
#ifdef TEST_SEGS
1700 e3b32540 bellard
    printf("segment exceptions:\n");
1701 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1702 e3b32540 bellard
        /* load an invalid segment */
1703 e3b32540 bellard
        asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 1));
1704 e3b32540 bellard
    }
1705 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1706 e3b32540 bellard
        /* null data segment is valid */
1707 e3b32540 bellard
        asm volatile ("movl %0, %%fs" : : "r" (3));
1708 e3b32540 bellard
        /* null stack segment */
1709 e3b32540 bellard
        asm volatile ("movl %0, %%ss" : : "r" (3));
1710 e3b32540 bellard
    }
1711 e3b32540 bellard
1712 776f2227 bellard
    {
1713 776f2227 bellard
        struct modify_ldt_ldt_s ldt;
1714 776f2227 bellard
        ldt.entry_number = 1;
1715 776f2227 bellard
        ldt.base_addr = (unsigned long)&seg_data1;
1716 776f2227 bellard
        ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
1717 776f2227 bellard
        ldt.seg_32bit = 1;
1718 776f2227 bellard
        ldt.contents = MODIFY_LDT_CONTENTS_DATA;
1719 776f2227 bellard
        ldt.read_exec_only = 0;
1720 776f2227 bellard
        ldt.limit_in_pages = 1;
1721 776f2227 bellard
        ldt.seg_not_present = 1;
1722 776f2227 bellard
        ldt.useable = 1;
1723 776f2227 bellard
        modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
1724 3b46e624 ths
1725 776f2227 bellard
        if (setjmp(jmp_env) == 0) {
1726 776f2227 bellard
            /* segment not present */
1727 776f2227 bellard
            asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
1728 776f2227 bellard
        }
1729 e3b32540 bellard
    }
1730 776f2227 bellard
#endif
1731 e3b32540 bellard
1732 3a27ad0b bellard
    /* test SEGV reporting */
1733 e3b32540 bellard
    printf("PF exception:\n");
1734 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1735 e3b32540 bellard
        val = 1;
1736 ede28208 bellard
        /* we add a nop to test a weird PC retrieval case */
1737 ede28208 bellard
        asm volatile ("nop");
1738 3a27ad0b bellard
        /* now store in an invalid address */
1739 3a27ad0b bellard
        *(char *)0x1234 = 1;
1740 3a27ad0b bellard
    }
1741 3a27ad0b bellard
1742 3a27ad0b bellard
    /* test SEGV reporting */
1743 e3b32540 bellard
    printf("PF exception:\n");
1744 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1745 e3b32540 bellard
        val = 1;
1746 3a27ad0b bellard
        /* read from an invalid address */
1747 3a27ad0b bellard
        v1 = *(char *)0x1234;
1748 3a27ad0b bellard
    }
1749 3b46e624 ths
1750 3a27ad0b bellard
    /* test illegal instruction reporting */
1751 3a27ad0b bellard
    printf("UD2 exception:\n");
1752 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1753 3a27ad0b bellard
        /* now execute an invalid instruction */
1754 3a27ad0b bellard
        asm volatile("ud2");
1755 3a27ad0b bellard
    }
1756 4120b61d bellard
    printf("lock nop exception:\n");
1757 4120b61d bellard
    if (setjmp(jmp_env) == 0) {
1758 4120b61d bellard
        /* now execute an invalid instruction */
1759 4120b61d bellard
        asm volatile("lock nop");
1760 4120b61d bellard
    }
1761 3b46e624 ths
1762 3a27ad0b bellard
    printf("INT exception:\n");
1763 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1764 3a27ad0b bellard
        asm volatile ("int $0xfd");
1765 3a27ad0b bellard
    }
1766 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1767 e3b32540 bellard
        asm volatile ("int $0x01");
1768 e3b32540 bellard
    }
1769 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1770 e3b32540 bellard
        asm volatile (".byte 0xcd, 0x03");
1771 e3b32540 bellard
    }
1772 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1773 e3b32540 bellard
        asm volatile ("int $0x04");
1774 e3b32540 bellard
    }
1775 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1776 e3b32540 bellard
        asm volatile ("int $0x05");
1777 e3b32540 bellard
    }
1778 3a27ad0b bellard
1779 3a27ad0b bellard
    printf("INT3 exception:\n");
1780 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1781 3a27ad0b bellard
        asm volatile ("int3");
1782 3a27ad0b bellard
    }
1783 3a27ad0b bellard
1784 3a27ad0b bellard
    printf("CLI exception:\n");
1785 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1786 3a27ad0b bellard
        asm volatile ("cli");
1787 3a27ad0b bellard
    }
1788 3a27ad0b bellard
1789 3a27ad0b bellard
    printf("STI exception:\n");
1790 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1791 3a27ad0b bellard
        asm volatile ("cli");
1792 3a27ad0b bellard
    }
1793 3a27ad0b bellard
1794 776f2227 bellard
#if !defined(__x86_64__)
1795 3a27ad0b bellard
    printf("INTO exception:\n");
1796 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1797 3a27ad0b bellard
        /* overflow exception */
1798 3a27ad0b bellard
        asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff));
1799 3a27ad0b bellard
    }
1800 776f2227 bellard
#endif
1801 3a27ad0b bellard
1802 3a27ad0b bellard
    printf("OUTB exception:\n");
1803 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1804 3a27ad0b bellard
        asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0));
1805 3a27ad0b bellard
    }
1806 3a27ad0b bellard
1807 3a27ad0b bellard
    printf("INB exception:\n");
1808 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1809 3a27ad0b bellard
        asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321));
1810 3a27ad0b bellard
    }
1811 3a27ad0b bellard
1812 3a27ad0b bellard
    printf("REP OUTSB exception:\n");
1813 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1814 3a27ad0b bellard
        asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1));
1815 3a27ad0b bellard
    }
1816 3a27ad0b bellard
1817 3a27ad0b bellard
    printf("REP INSB exception:\n");
1818 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1819 3a27ad0b bellard
        asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1));
1820 3a27ad0b bellard
    }
1821 3a27ad0b bellard
1822 3a27ad0b bellard
    printf("HLT exception:\n");
1823 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1824 3a27ad0b bellard
        asm volatile ("hlt");
1825 3a27ad0b bellard
    }
1826 3a27ad0b bellard
1827 3a27ad0b bellard
    printf("single step exception:\n");
1828 3a27ad0b bellard
    val = 0;
1829 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1830 3a27ad0b bellard
        asm volatile ("pushf\n"
1831 3a27ad0b bellard
                      "orl $0x00100, (%%esp)\n"
1832 3a27ad0b bellard
                      "popf\n"
1833 5fafdf24 ths
                      "movl $0xabcd, %0\n"
1834 3a27ad0b bellard
                      "movl $0x0, %0\n" : "=m" (val) : : "cc", "memory");
1835 3a27ad0b bellard
    }
1836 3a27ad0b bellard
    printf("val=0x%x\n", val);
1837 3a27ad0b bellard
}
1838 3a27ad0b bellard
1839 776f2227 bellard
#if !defined(__x86_64__)
1840 3ff0631e bellard
/* specific precise single step test */
1841 3ff0631e bellard
void sig_trap_handler(int sig, siginfo_t *info, void *puc)
1842 3ff0631e bellard
{
1843 3ff0631e bellard
    struct ucontext *uc = puc;
1844 776f2227 bellard
    printf("EIP=" FMTLX "\n", (long)uc->uc_mcontext.gregs[REG_EIP]);
1845 3ff0631e bellard
}
1846 3ff0631e bellard
1847 3ff0631e bellard
const uint8_t sstep_buf1[4] = { 1, 2, 3, 4};
1848 3ff0631e bellard
uint8_t sstep_buf2[4];
1849 3ff0631e bellard
1850 3ff0631e bellard
void test_single_step(void)
1851 3ff0631e bellard
{
1852 3ff0631e bellard
    struct sigaction act;
1853 3ff0631e bellard
    volatile int val;
1854 3ff0631e bellard
    int i;
1855 3ff0631e bellard
1856 3ff0631e bellard
    val = 0;
1857 3ff0631e bellard
    act.sa_sigaction = sig_trap_handler;
1858 3ff0631e bellard
    sigemptyset(&act.sa_mask);
1859 3ff0631e bellard
    act.sa_flags = SA_SIGINFO;
1860 3ff0631e bellard
    sigaction(SIGTRAP, &act, NULL);
1861 3ff0631e bellard
    asm volatile ("pushf\n"
1862 3ff0631e bellard
                  "orl $0x00100, (%%esp)\n"
1863 3ff0631e bellard
                  "popf\n"
1864 5fafdf24 ths
                  "movl $0xabcd, %0\n"
1865 3ff0631e bellard
1866 3ff0631e bellard
                  /* jmp test */
1867 3ff0631e bellard
                  "movl $3, %%ecx\n"
1868 3ff0631e bellard
                  "1:\n"
1869 3ff0631e bellard
                  "addl $1, %0\n"
1870 3ff0631e bellard
                  "decl %%ecx\n"
1871 3ff0631e bellard
                  "jnz 1b\n"
1872 3ff0631e bellard
1873 3ff0631e bellard
                  /* movsb: the single step should stop at each movsb iteration */
1874 3ff0631e bellard
                  "movl $sstep_buf1, %%esi\n"
1875 3ff0631e bellard
                  "movl $sstep_buf2, %%edi\n"
1876 3ff0631e bellard
                  "movl $0, %%ecx\n"
1877 3ff0631e bellard
                  "rep movsb\n"
1878 3ff0631e bellard
                  "movl $3, %%ecx\n"
1879 3ff0631e bellard
                  "rep movsb\n"
1880 3ff0631e bellard
                  "movl $1, %%ecx\n"
1881 3ff0631e bellard
                  "rep movsb\n"
1882 3ff0631e bellard
1883 3ff0631e bellard
                  /* cmpsb: the single step should stop at each cmpsb iteration */
1884 3ff0631e bellard
                  "movl $sstep_buf1, %%esi\n"
1885 3ff0631e bellard
                  "movl $sstep_buf2, %%edi\n"
1886 3ff0631e bellard
                  "movl $0, %%ecx\n"
1887 3ff0631e bellard
                  "rep cmpsb\n"
1888 3ff0631e bellard
                  "movl $4, %%ecx\n"
1889 3ff0631e bellard
                  "rep cmpsb\n"
1890 3b46e624 ths
1891 3ff0631e bellard
                  /* getpid() syscall: single step should skip one
1892 3ff0631e bellard
                     instruction */
1893 3ff0631e bellard
                  "movl $20, %%eax\n"
1894 3ff0631e bellard
                  "int $0x80\n"
1895 3ff0631e bellard
                  "movl $0, %%eax\n"
1896 3b46e624 ths
1897 3ff0631e bellard
                  /* when modifying SS, trace is not done on the next
1898 3ff0631e bellard
                     instruction */
1899 3ff0631e bellard
                  "movl %%ss, %%ecx\n"
1900 3ff0631e bellard
                  "movl %%ecx, %%ss\n"
1901 3ff0631e bellard
                  "addl $1, %0\n"
1902 3ff0631e bellard
                  "movl $1, %%eax\n"
1903 3ff0631e bellard
                  "movl %%ecx, %%ss\n"
1904 3ff0631e bellard
                  "jmp 1f\n"
1905 3ff0631e bellard
                  "addl $1, %0\n"
1906 3ff0631e bellard
                  "1:\n"
1907 3ff0631e bellard
                  "movl $1, %%eax\n"
1908 3ff0631e bellard
                  "pushl %%ecx\n"
1909 3ff0631e bellard
                  "popl %%ss\n"
1910 3ff0631e bellard
                  "addl $1, %0\n"
1911 3ff0631e bellard
                  "movl $1, %%eax\n"
1912 3b46e624 ths
1913 3ff0631e bellard
                  "pushf\n"
1914 3ff0631e bellard
                  "andl $~0x00100, (%%esp)\n"
1915 3ff0631e bellard
                  "popf\n"
1916 5fafdf24 ths
                  : "=m" (val)
1917 5fafdf24 ths
                  :
1918 3ff0631e bellard
                  : "cc", "memory", "eax", "ecx", "esi", "edi");
1919 3ff0631e bellard
    printf("val=%d\n", val);
1920 3ff0631e bellard
    for(i = 0; i < 4; i++)
1921 3ff0631e bellard
        printf("sstep_buf2[%d] = %d\n", i, sstep_buf2[i]);
1922 3ff0631e bellard
}
1923 3ff0631e bellard
1924 3a27ad0b bellard
/* self modifying code test */
1925 3a27ad0b bellard
uint8_t code[] = {
1926 3a27ad0b bellard
    0xb8, 0x1, 0x00, 0x00, 0x00, /* movl $1, %eax */
1927 3a27ad0b bellard
    0xc3, /* ret */
1928 3a27ad0b bellard
};
1929 3a27ad0b bellard
1930 1190935d bellard
asm("smc_code2:\n"
1931 1190935d bellard
    "movl 4(%esp), %eax\n"
1932 1190935d bellard
    "movl %eax, smc_patch_addr2 + 1\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
    "nop\n"
1939 1190935d bellard
    "nop\n"
1940 1190935d bellard
    "nop\n"
1941 1190935d bellard
    "smc_patch_addr2:\n"
1942 1190935d bellard
    "movl $1, %eax\n"
1943 1190935d bellard
    "ret\n");
1944 d1fe2b24 bellard
1945 1190935d bellard
typedef int FuncType(void);
1946 1190935d bellard
extern int smc_code2(int);
1947 3a27ad0b bellard
void test_self_modifying_code(void)
1948 3a27ad0b bellard
{
1949 d1fe2b24 bellard
    int i;
1950 3a27ad0b bellard
1951 3a27ad0b bellard
    printf("self modifying code:\n");
1952 d1fe2b24 bellard
    printf("func1 = 0x%x\n", ((FuncType *)code)());
1953 d1fe2b24 bellard
    for(i = 2; i <= 4; i++) {
1954 d1fe2b24 bellard
        code[1] = i;
1955 d1fe2b24 bellard
        printf("func%d = 0x%x\n", i, ((FuncType *)code)());
1956 d1fe2b24 bellard
    }
1957 1190935d bellard
1958 1190935d bellard
    /* more difficult test : the modified code is just after the
1959 1190935d bellard
       modifying instruction. It is forbidden in Intel specs, but it
1960 1190935d bellard
       is used by old DOS programs */
1961 1190935d bellard
    for(i = 2; i <= 4; i++) {
1962 1190935d bellard
        printf("smc_code2(%d) = %d\n", i, smc_code2(i));
1963 1190935d bellard
    }
1964 3a27ad0b bellard
}
1965 776f2227 bellard
#endif
1966 61a8c4ec bellard
1967 776f2227 bellard
long enter_stack[4096];
1968 776f2227 bellard
1969 776f2227 bellard
#if defined(__x86_64__)
1970 776f2227 bellard
#define RSP "%%rsp"
1971 776f2227 bellard
#define RBP "%%rbp"
1972 776f2227 bellard
#else
1973 776f2227 bellard
#define RSP "%%esp"
1974 776f2227 bellard
#define RBP "%%ebp"
1975 776f2227 bellard
#endif
1976 61a8c4ec bellard
1977 61a8c4ec bellard
#define TEST_ENTER(size, stack_type, level)\
1978 61a8c4ec bellard
{\
1979 776f2227 bellard
    long esp_save, esp_val, ebp_val, ebp_save, i;\
1980 61a8c4ec bellard
    stack_type *ptr, *stack_end, *stack_ptr;\
1981 61a8c4ec bellard
    memset(enter_stack, 0, sizeof(enter_stack));\
1982 61a8c4ec bellard
    stack_end = stack_ptr = (stack_type *)(enter_stack + 4096);\
1983 61a8c4ec bellard
    ebp_val = (long)stack_ptr;\
1984 61a8c4ec bellard
    for(i=1;i<=32;i++)\
1985 61a8c4ec bellard
       *--stack_ptr = i;\
1986 61a8c4ec bellard
    esp_val = (long)stack_ptr;\
1987 776f2227 bellard
    asm("mov " RSP ", %[esp_save]\n"\
1988 776f2227 bellard
        "mov " RBP ", %[ebp_save]\n"\
1989 776f2227 bellard
        "mov %[esp_val], " RSP "\n"\
1990 776f2227 bellard
        "mov %[ebp_val], " RBP "\n"\
1991 776f2227 bellard
        "enter" size " $8, $" #level "\n"\
1992 776f2227 bellard
        "mov " RSP ", %[esp_val]\n"\
1993 776f2227 bellard
        "mov " RBP ", %[ebp_val]\n"\
1994 776f2227 bellard
        "mov %[esp_save], " RSP "\n"\
1995 776f2227 bellard
        "mov %[ebp_save], " RBP "\n"\
1996 61a8c4ec bellard
        : [esp_save] "=r" (esp_save),\
1997 61a8c4ec bellard
        [ebp_save] "=r" (ebp_save),\
1998 61a8c4ec bellard
        [esp_val] "=r" (esp_val),\
1999 61a8c4ec bellard
        [ebp_val] "=r" (ebp_val)\
2000 61a8c4ec bellard
        :  "[esp_val]" (esp_val),\
2001 61a8c4ec bellard
        "[ebp_val]" (ebp_val));\
2002 61a8c4ec bellard
    printf("level=%d:\n", level);\
2003 776f2227 bellard
    printf("esp_val=" FMTLX "\n", esp_val - (long)stack_end);\
2004 776f2227 bellard
    printf("ebp_val=" FMTLX "\n", ebp_val - (long)stack_end);\
2005 61a8c4ec bellard
    for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\
2006 776f2227 bellard
        printf(FMTLX "\n", (long)ptr[0]);\
2007 61a8c4ec bellard
}
2008 61a8c4ec bellard
2009 61a8c4ec bellard
static void test_enter(void)
2010 61a8c4ec bellard
{
2011 776f2227 bellard
#if defined(__x86_64__)
2012 776f2227 bellard
    TEST_ENTER("q", uint64_t, 0);
2013 776f2227 bellard
    TEST_ENTER("q", uint64_t, 1);
2014 776f2227 bellard
    TEST_ENTER("q", uint64_t, 2);
2015 776f2227 bellard
    TEST_ENTER("q", uint64_t, 31);
2016 776f2227 bellard
#else
2017 61a8c4ec bellard
    TEST_ENTER("l", uint32_t, 0);
2018 61a8c4ec bellard
    TEST_ENTER("l", uint32_t, 1);
2019 61a8c4ec bellard
    TEST_ENTER("l", uint32_t, 2);
2020 61a8c4ec bellard
    TEST_ENTER("l", uint32_t, 31);
2021 776f2227 bellard
#endif
2022 61a8c4ec bellard
2023 61a8c4ec bellard
    TEST_ENTER("w", uint16_t, 0);
2024 61a8c4ec bellard
    TEST_ENTER("w", uint16_t, 1);
2025 61a8c4ec bellard
    TEST_ENTER("w", uint16_t, 2);
2026 61a8c4ec bellard
    TEST_ENTER("w", uint16_t, 31);
2027 61a8c4ec bellard
}
2028 61a8c4ec bellard
2029 085339a1 bellard
#ifdef TEST_SSE
2030 085339a1 bellard
2031 085339a1 bellard
typedef int __m64 __attribute__ ((__mode__ (__V2SI__)));
2032 085339a1 bellard
typedef int __m128 __attribute__ ((__mode__(__V4SF__)));
2033 085339a1 bellard
2034 085339a1 bellard
typedef union {
2035 085339a1 bellard
    double d[2];
2036 085339a1 bellard
    float s[4];
2037 085339a1 bellard
    uint32_t l[4];
2038 085339a1 bellard
    uint64_t q[2];
2039 085339a1 bellard
    __m128 dq;
2040 085339a1 bellard
} XMMReg;
2041 085339a1 bellard
2042 085339a1 bellard
static uint64_t __attribute__((aligned(16))) test_values[4][2] = {
2043 085339a1 bellard
    { 0x456723c698694873, 0xdc515cff944a58ec },
2044 085339a1 bellard
    { 0x1f297ccd58bad7ab, 0x41f21efba9e3e146 },
2045 085339a1 bellard
    { 0x007c62c2085427f8, 0x231be9e8cde7438d },
2046 085339a1 bellard
    { 0x0f76255a085427f8, 0xc233e9e8c4c9439a },
2047 085339a1 bellard
};
2048 085339a1 bellard
2049 085339a1 bellard
#define SSE_OP(op)\
2050 085339a1 bellard
{\
2051 085339a1 bellard
    asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
2052 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\
2053 085339a1 bellard
           #op,\
2054 085339a1 bellard
           a.q[1], a.q[0],\
2055 085339a1 bellard
           b.q[1], b.q[0],\
2056 085339a1 bellard
           r.q[1], r.q[0]);\
2057 085339a1 bellard
}
2058 085339a1 bellard
2059 085339a1 bellard
#define SSE_OP2(op)\
2060 085339a1 bellard
{\
2061 085339a1 bellard
    int i;\
2062 085339a1 bellard
    for(i=0;i<2;i++) {\
2063 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
2064 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
2065 085339a1 bellard
    b.q[0] = test_values[2*i+1][0];\
2066 085339a1 bellard
    b.q[1] = test_values[2*i+1][1];\
2067 085339a1 bellard
    SSE_OP(op);\
2068 085339a1 bellard
    }\
2069 085339a1 bellard
}
2070 085339a1 bellard
2071 085339a1 bellard
#define MMX_OP2(op)\
2072 085339a1 bellard
{\
2073 085339a1 bellard
    int i;\
2074 085339a1 bellard
    for(i=0;i<2;i++) {\
2075 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
2076 085339a1 bellard
    b.q[0] = test_values[2*i+1][0];\
2077 085339a1 bellard
    asm volatile (#op " %2, %0" : "=y" (r.q[0]) : "0" (a.q[0]), "y" (b.q[0]));\
2078 776f2227 bellard
    printf("%-9s: a=" FMT64X " b=" FMT64X " r=" FMT64X "\n",\
2079 085339a1 bellard
           #op,\
2080 085339a1 bellard
           a.q[0],\
2081 085339a1 bellard
           b.q[0],\
2082 085339a1 bellard
           r.q[0]);\
2083 085339a1 bellard
    }\
2084 085339a1 bellard
    SSE_OP2(op);\
2085 085339a1 bellard
}
2086 085339a1 bellard
2087 97ed14ae bellard
#define SHUF_OP(op, ib)\
2088 97ed14ae bellard
{\
2089 97ed14ae bellard
    a.q[0] = test_values[0][0];\
2090 97ed14ae bellard
    a.q[1] = test_values[0][1];\
2091 97ed14ae bellard
    b.q[0] = test_values[1][0];\
2092 97ed14ae bellard
    b.q[1] = test_values[1][1];\
2093 97ed14ae bellard
    asm volatile (#op " $" #ib ", %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
2094 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\
2095 97ed14ae bellard
           #op,\
2096 97ed14ae bellard
           a.q[1], a.q[0],\
2097 97ed14ae bellard
           b.q[1], b.q[0],\
2098 97ed14ae bellard
           ib,\
2099 97ed14ae bellard
           r.q[1], r.q[0]);\
2100 97ed14ae bellard
}
2101 97ed14ae bellard
2102 085339a1 bellard
#define PSHUF_OP(op, ib)\
2103 085339a1 bellard
{\
2104 085339a1 bellard
    int i;\
2105 085339a1 bellard
    for(i=0;i<2;i++) {\
2106 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
2107 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
2108 085339a1 bellard
    asm volatile (#op " $" #ib ", %1, %0" : "=x" (r.dq) : "x" (a.dq));\
2109 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\
2110 085339a1 bellard
           #op,\
2111 085339a1 bellard
           a.q[1], a.q[0],\
2112 085339a1 bellard
           ib,\
2113 085339a1 bellard
           r.q[1], r.q[0]);\
2114 085339a1 bellard
    }\
2115 085339a1 bellard
}
2116 085339a1 bellard
2117 085339a1 bellard
#define SHIFT_IM(op, ib)\
2118 085339a1 bellard
{\
2119 085339a1 bellard
    int i;\
2120 085339a1 bellard
    for(i=0;i<2;i++) {\
2121 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
2122 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
2123 085339a1 bellard
    asm volatile (#op " $" #ib ", %0" : "=x" (r.dq) : "0" (a.dq));\
2124 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\
2125 085339a1 bellard
           #op,\
2126 085339a1 bellard
           a.q[1], a.q[0],\
2127 085339a1 bellard
           ib,\
2128 085339a1 bellard
           r.q[1], r.q[0]);\
2129 085339a1 bellard
    }\
2130 085339a1 bellard
}
2131 085339a1 bellard
2132 085339a1 bellard
#define SHIFT_OP(op, ib)\
2133 085339a1 bellard
{\
2134 085339a1 bellard
    int i;\
2135 085339a1 bellard
    SHIFT_IM(op, ib);\
2136 085339a1 bellard
    for(i=0;i<2;i++) {\
2137 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
2138 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
2139 085339a1 bellard
    b.q[0] = ib;\
2140 085339a1 bellard
    b.q[1] = 0;\
2141 085339a1 bellard
    asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
2142 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\
2143 085339a1 bellard
           #op,\
2144 085339a1 bellard
           a.q[1], a.q[0],\
2145 085339a1 bellard
           b.q[1], b.q[0],\
2146 085339a1 bellard
           r.q[1], r.q[0]);\
2147 085339a1 bellard
    }\
2148 085339a1 bellard
}
2149 085339a1 bellard
2150 085339a1 bellard
#define MOVMSK(op)\
2151 085339a1 bellard
{\
2152 085339a1 bellard
    int i, reg;\
2153 085339a1 bellard
    for(i=0;i<2;i++) {\
2154 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
2155 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
2156 085339a1 bellard
    asm volatile (#op " %1, %0" : "=r" (reg) : "x" (a.dq));\
2157 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\
2158 085339a1 bellard
           #op,\
2159 085339a1 bellard
           a.q[1], a.q[0],\
2160 085339a1 bellard
           reg);\
2161 085339a1 bellard
    }\
2162 085339a1 bellard
}
2163 085339a1 bellard
2164 085339a1 bellard
#define SSE_OPS(a) \
2165 085339a1 bellard
SSE_OP(a ## ps);\
2166 085339a1 bellard
SSE_OP(a ## ss);
2167 085339a1 bellard
2168 085339a1 bellard
#define SSE_OPD(a) \
2169 085339a1 bellard
SSE_OP(a ## pd);\
2170 085339a1 bellard
SSE_OP(a ## sd);
2171 085339a1 bellard
2172 085339a1 bellard
#define SSE_COMI(op, field)\
2173 085339a1 bellard
{\
2174 085339a1 bellard
    unsigned int eflags;\
2175 085339a1 bellard
    XMMReg a, b;\
2176 085339a1 bellard
    a.field[0] = a1;\
2177 085339a1 bellard
    b.field[0] = b1;\
2178 085339a1 bellard
    asm volatile (#op " %2, %1\n"\
2179 085339a1 bellard
        "pushf\n"\
2180 085339a1 bellard
        "pop %0\n"\
2181 085339a1 bellard
        : "=m" (eflags)\
2182 085339a1 bellard
        : "x" (a.dq), "x" (b.dq));\
2183 085339a1 bellard
    printf("%-9s: a=%f b=%f cc=%04x\n",\
2184 085339a1 bellard
           #op, a1, b1,\
2185 085339a1 bellard
           eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\
2186 085339a1 bellard
}
2187 085339a1 bellard
2188 085339a1 bellard
void test_sse_comi(double a1, double b1)
2189 085339a1 bellard
{
2190 085339a1 bellard
    SSE_COMI(ucomiss, s);
2191 085339a1 bellard
    SSE_COMI(ucomisd, d);
2192 085339a1 bellard
    SSE_COMI(comiss, s);
2193 085339a1 bellard
    SSE_COMI(comisd, d);
2194 085339a1 bellard
}
2195 085339a1 bellard
2196 085339a1 bellard
#define CVT_OP_XMM(op)\
2197 085339a1 bellard
{\
2198 085339a1 bellard
    asm volatile (#op " %1, %0" : "=x" (r.dq) : "x" (a.dq));\
2199 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\
2200 085339a1 bellard
           #op,\
2201 085339a1 bellard
           a.q[1], a.q[0],\
2202 085339a1 bellard
           r.q[1], r.q[0]);\
2203 085339a1 bellard
}
2204 085339a1 bellard
2205 80e7d521 bellard
/* Force %xmm0 usage to avoid the case where both register index are 0
2206 80e7d521 bellard
   to test intruction decoding more extensively */
2207 085339a1 bellard
#define CVT_OP_XMM2MMX(op)\
2208 085339a1 bellard
{\
2209 80e7d521 bellard
    asm volatile (#op " %1, %0" : "=y" (r.q[0]) : "x" (a.dq) \
2210 80e7d521 bellard
                  : "%xmm0");\
2211 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "\n",\
2212 085339a1 bellard
           #op,\
2213 085339a1 bellard
           a.q[1], a.q[0],\
2214 085339a1 bellard
           r.q[0]);\
2215 085339a1 bellard
}
2216 085339a1 bellard
2217 085339a1 bellard
#define CVT_OP_MMX2XMM(op)\
2218 085339a1 bellard
{\
2219 085339a1 bellard
    asm volatile (#op " %1, %0" : "=x" (r.dq) : "y" (a.q[0]));\
2220 776f2227 bellard
    printf("%-9s: a=" FMT64X " r=" FMT64X "" FMT64X "\n",\
2221 085339a1 bellard
           #op,\
2222 085339a1 bellard
           a.q[0],\
2223 085339a1 bellard
           r.q[1], r.q[0]);\
2224 085339a1 bellard
}
2225 085339a1 bellard
2226 085339a1 bellard
#define CVT_OP_REG2XMM(op)\
2227 085339a1 bellard
{\
2228 085339a1 bellard
    asm volatile (#op " %1, %0" : "=x" (r.dq) : "r" (a.l[0]));\
2229 776f2227 bellard
    printf("%-9s: a=%08x r=" FMT64X "" FMT64X "\n",\
2230 085339a1 bellard
           #op,\
2231 085339a1 bellard
           a.l[0],\
2232 085339a1 bellard
           r.q[1], r.q[0]);\
2233 085339a1 bellard
}
2234 085339a1 bellard
2235 085339a1 bellard
#define CVT_OP_XMM2REG(op)\
2236 085339a1 bellard
{\
2237 085339a1 bellard
    asm volatile (#op " %1, %0" : "=r" (r.l[0]) : "x" (a.dq));\
2238 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\
2239 085339a1 bellard
           #op,\
2240 085339a1 bellard
           a.q[1], a.q[0],\
2241 085339a1 bellard
           r.l[0]);\
2242 085339a1 bellard
}
2243 085339a1 bellard
2244 a4682cc2 bellard
struct fpxstate {
2245 a4682cc2 bellard
    uint16_t fpuc;
2246 a4682cc2 bellard
    uint16_t fpus;
2247 a4682cc2 bellard
    uint16_t fptag;
2248 a4682cc2 bellard
    uint16_t fop;
2249 a4682cc2 bellard
    uint32_t fpuip;
2250 a4682cc2 bellard
    uint16_t cs_sel;
2251 a4682cc2 bellard
    uint16_t dummy0;
2252 a4682cc2 bellard
    uint32_t fpudp;
2253 a4682cc2 bellard
    uint16_t ds_sel;
2254 a4682cc2 bellard
    uint16_t dummy1;
2255 a4682cc2 bellard
    uint32_t mxcsr;
2256 a4682cc2 bellard
    uint32_t mxcsr_mask;
2257 a4682cc2 bellard
    uint8_t fpregs1[8 * 16];
2258 a4682cc2 bellard
    uint8_t xmm_regs[8 * 16];
2259 a4682cc2 bellard
    uint8_t dummy2[224];
2260 a4682cc2 bellard
};
2261 a4682cc2 bellard
2262 a4682cc2 bellard
static struct fpxstate fpx_state __attribute__((aligned(16)));
2263 a4682cc2 bellard
static struct fpxstate fpx_state2 __attribute__((aligned(16)));
2264 a4682cc2 bellard
2265 a4682cc2 bellard
void test_fxsave(void)
2266 a4682cc2 bellard
{
2267 a4682cc2 bellard
    struct fpxstate *fp = &fpx_state;
2268 a4682cc2 bellard
    struct fpxstate *fp2 = &fpx_state2;
2269 776f2227 bellard
    int i, nb_xmm;
2270 a4682cc2 bellard
    XMMReg a, b;
2271 a4682cc2 bellard
    a.q[0] = test_values[0][0];
2272 a4682cc2 bellard
    a.q[1] = test_values[0][1];
2273 a4682cc2 bellard
    b.q[0] = test_values[1][0];
2274 a4682cc2 bellard
    b.q[1] = test_values[1][1];
2275 a4682cc2 bellard
2276 a4682cc2 bellard
    asm("movdqa %2, %%xmm0\n"
2277 a4682cc2 bellard
        "movdqa %3, %%xmm7\n"
2278 776f2227 bellard
#if defined(__x86_64__)
2279 776f2227 bellard
        "movdqa %2, %%xmm15\n"
2280 776f2227 bellard
#endif
2281 a4682cc2 bellard
        " fld1\n"
2282 a4682cc2 bellard
        " fldpi\n"
2283 a4682cc2 bellard
        " fldln2\n"
2284 a4682cc2 bellard
        " fxsave %0\n"
2285 a4682cc2 bellard
        " fxrstor %0\n"
2286 a4682cc2 bellard
        " fxsave %1\n"
2287 a4682cc2 bellard
        " fninit\n"
2288 5fafdf24 ths
        : "=m" (*(uint32_t *)fp2), "=m" (*(uint32_t *)fp)
2289 a4682cc2 bellard
        : "m" (a), "m" (b));
2290 a4682cc2 bellard
    printf("fpuc=%04x\n", fp->fpuc);
2291 a4682cc2 bellard
    printf("fpus=%04x\n", fp->fpus);
2292 a4682cc2 bellard
    printf("fptag=%04x\n", fp->fptag);
2293 a4682cc2 bellard
    for(i = 0; i < 3; i++) {
2294 776f2227 bellard
        printf("ST%d: " FMT64X " %04x\n",
2295 5fafdf24 ths
               i,
2296 a4682cc2 bellard
               *(uint64_t *)&fp->fpregs1[i * 16],
2297 a4682cc2 bellard
               *(uint16_t *)&fp->fpregs1[i * 16 + 8]);
2298 a4682cc2 bellard
    }
2299 a4682cc2 bellard
    printf("mxcsr=%08x\n", fp->mxcsr & 0x1f80);
2300 776f2227 bellard
#if defined(__x86_64__)
2301 776f2227 bellard
    nb_xmm = 16;
2302 776f2227 bellard
#else
2303 776f2227 bellard
    nb_xmm = 8;
2304 776f2227 bellard
#endif
2305 776f2227 bellard
    for(i = 0; i < nb_xmm; i++) {
2306 776f2227 bellard
        printf("xmm%d: " FMT64X "" FMT64X "\n",
2307 5fafdf24 ths
               i,
2308 a4682cc2 bellard
               *(uint64_t *)&fp->xmm_regs[i * 16],
2309 a4682cc2 bellard
               *(uint64_t *)&fp->xmm_regs[i * 16 + 8]);
2310 a4682cc2 bellard
    }
2311 a4682cc2 bellard
}
2312 a4682cc2 bellard
2313 085339a1 bellard
void test_sse(void)
2314 085339a1 bellard
{
2315 085339a1 bellard
    XMMReg r, a, b;
2316 86bd2ca5 bellard
    int i;
2317 085339a1 bellard
2318 085339a1 bellard
    MMX_OP2(punpcklbw);
2319 085339a1 bellard
    MMX_OP2(punpcklwd);
2320 085339a1 bellard
    MMX_OP2(punpckldq);
2321 085339a1 bellard
    MMX_OP2(packsswb);
2322 085339a1 bellard
    MMX_OP2(pcmpgtb);
2323 085339a1 bellard
    MMX_OP2(pcmpgtw);
2324 085339a1 bellard
    MMX_OP2(pcmpgtd);
2325 085339a1 bellard
    MMX_OP2(packuswb);
2326 085339a1 bellard
    MMX_OP2(punpckhbw);
2327 085339a1 bellard
    MMX_OP2(punpckhwd);
2328 085339a1 bellard
    MMX_OP2(punpckhdq);
2329 085339a1 bellard
    MMX_OP2(packssdw);
2330 085339a1 bellard
    MMX_OP2(pcmpeqb);
2331 085339a1 bellard
    MMX_OP2(pcmpeqw);
2332 085339a1 bellard
    MMX_OP2(pcmpeqd);
2333 085339a1 bellard
2334 085339a1 bellard
    MMX_OP2(paddq);
2335 085339a1 bellard
    MMX_OP2(pmullw);
2336 085339a1 bellard
    MMX_OP2(psubusb);
2337 085339a1 bellard
    MMX_OP2(psubusw);
2338 085339a1 bellard
    MMX_OP2(pminub);
2339 085339a1 bellard
    MMX_OP2(pand);
2340 085339a1 bellard
    MMX_OP2(paddusb);
2341 085339a1 bellard
    MMX_OP2(paddusw);
2342 085339a1 bellard
    MMX_OP2(pmaxub);
2343 085339a1 bellard
    MMX_OP2(pandn);
2344 085339a1 bellard
2345 085339a1 bellard
    MMX_OP2(pmulhuw);
2346 085339a1 bellard
    MMX_OP2(pmulhw);
2347 3b46e624 ths
2348 085339a1 bellard
    MMX_OP2(psubsb);
2349 085339a1 bellard
    MMX_OP2(psubsw);
2350 085339a1 bellard
    MMX_OP2(pminsw);
2351 085339a1 bellard
    MMX_OP2(por);
2352 085339a1 bellard
    MMX_OP2(paddsb);
2353 085339a1 bellard
    MMX_OP2(paddsw);
2354 085339a1 bellard
    MMX_OP2(pmaxsw);
2355 085339a1 bellard
    MMX_OP2(pxor);
2356 085339a1 bellard
    MMX_OP2(pmuludq);
2357 085339a1 bellard
    MMX_OP2(pmaddwd);
2358 085339a1 bellard
    MMX_OP2(psadbw);
2359 085339a1 bellard
    MMX_OP2(psubb);
2360 085339a1 bellard
    MMX_OP2(psubw);
2361 085339a1 bellard
    MMX_OP2(psubd);
2362 085339a1 bellard
    MMX_OP2(psubq);
2363 085339a1 bellard
    MMX_OP2(paddb);
2364 085339a1 bellard
    MMX_OP2(paddw);
2365 085339a1 bellard
    MMX_OP2(paddd);
2366 085339a1 bellard
2367 085339a1 bellard
    MMX_OP2(pavgb);
2368 085339a1 bellard
    MMX_OP2(pavgw);
2369 085339a1 bellard
2370 085339a1 bellard
    asm volatile ("pinsrw $1, %1, %0" : "=y" (r.q[0]) : "r" (0x12345678));
2371 776f2227 bellard
    printf("%-9s: r=" FMT64X "\n", "pinsrw", r.q[0]);
2372 085339a1 bellard
2373 085339a1 bellard
    asm volatile ("pinsrw $5, %1, %0" : "=x" (r.dq) : "r" (0x12345678));
2374 776f2227 bellard
    printf("%-9s: r=" FMT64X "" FMT64X "\n", "pinsrw", r.q[1], r.q[0]);
2375 085339a1 bellard
2376 085339a1 bellard
    a.q[0] = test_values[0][0];
2377 085339a1 bellard
    a.q[1] = test_values[0][1];
2378 085339a1 bellard
    asm volatile ("pextrw $1, %1, %0" : "=r" (r.l[0]) : "y" (a.q[0]));
2379 085339a1 bellard
    printf("%-9s: r=%08x\n", "pextrw", r.l[0]);
2380 085339a1 bellard
2381 085339a1 bellard
    asm volatile ("pextrw $5, %1, %0" : "=r" (r.l[0]) : "x" (a.dq));
2382 085339a1 bellard
    printf("%-9s: r=%08x\n", "pextrw", r.l[0]);
2383 085339a1 bellard
2384 085339a1 bellard
    asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "y" (a.q[0]));
2385 085339a1 bellard
    printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
2386 3b46e624 ths
2387 085339a1 bellard
    asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "x" (a.dq));
2388 085339a1 bellard
    printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
2389 085339a1 bellard
2390 97ed14ae bellard
    {
2391 97ed14ae bellard
        r.q[0] = -1;
2392 97ed14ae bellard
        r.q[1] = -1;
2393 97ed14ae bellard
2394 97ed14ae bellard
        a.q[0] = test_values[0][0];
2395 97ed14ae bellard
        a.q[1] = test_values[0][1];
2396 97ed14ae bellard
        b.q[0] = test_values[1][0];
2397 97ed14ae bellard
        b.q[1] = test_values[1][1];
2398 5fafdf24 ths
        asm volatile("maskmovq %1, %0" :
2399 97ed14ae bellard
                     : "y" (a.q[0]), "y" (b.q[0]), "D" (&r)
2400 5fafdf24 ths
                     : "memory");
2401 5fafdf24 ths
        printf("%-9s: r=" FMT64X " a=" FMT64X " b=" FMT64X "\n",
2402 5fafdf24 ths
               "maskmov",
2403 5fafdf24 ths
               r.q[0],
2404 5fafdf24 ths
               a.q[0],
2405 97ed14ae bellard
               b.q[0]);
2406 5fafdf24 ths
        asm volatile("maskmovdqu %1, %0" :
2407 97ed14ae bellard
                     : "x" (a.dq), "x" (b.dq), "D" (&r)
2408 5fafdf24 ths
                     : "memory");
2409 5fafdf24 ths
        printf("%-9s: r=" FMT64X "" FMT64X " a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X "\n",
2410 5fafdf24 ths
               "maskmov",
2411 5fafdf24 ths
               r.q[1], r.q[0],
2412 5fafdf24 ths
               a.q[1], a.q[0],
2413 97ed14ae bellard
               b.q[1], b.q[0]);
2414 97ed14ae bellard
    }
2415 97ed14ae bellard
2416 085339a1 bellard
    asm volatile ("emms");
2417 085339a1 bellard
2418 085339a1 bellard
    SSE_OP2(punpcklqdq);
2419 085339a1 bellard
    SSE_OP2(punpckhqdq);
2420 085339a1 bellard
    SSE_OP2(andps);
2421 085339a1 bellard
    SSE_OP2(andpd);
2422 085339a1 bellard
    SSE_OP2(andnps);
2423 085339a1 bellard
    SSE_OP2(andnpd);
2424 085339a1 bellard
    SSE_OP2(orps);
2425 085339a1 bellard
    SSE_OP2(orpd);
2426 085339a1 bellard
    SSE_OP2(xorps);
2427 085339a1 bellard
    SSE_OP2(xorpd);
2428 085339a1 bellard
2429 085339a1 bellard
    SSE_OP2(unpcklps);
2430 085339a1 bellard
    SSE_OP2(unpcklpd);
2431 085339a1 bellard
    SSE_OP2(unpckhps);
2432 085339a1 bellard
    SSE_OP2(unpckhpd);
2433 085339a1 bellard
2434 97ed14ae bellard
    SHUF_OP(shufps, 0x78);
2435 97ed14ae bellard
    SHUF_OP(shufpd, 0x02);
2436 085339a1 bellard
2437 085339a1 bellard
    PSHUF_OP(pshufd, 0x78);
2438 085339a1 bellard
    PSHUF_OP(pshuflw, 0x78);
2439 085339a1 bellard
    PSHUF_OP(pshufhw, 0x78);
2440 085339a1 bellard
2441 085339a1 bellard
    SHIFT_OP(psrlw, 7);
2442 085339a1 bellard
    SHIFT_OP(psrlw, 16);
2443 085339a1 bellard
    SHIFT_OP(psraw, 7);
2444 085339a1 bellard
    SHIFT_OP(psraw, 16);
2445 085339a1 bellard
    SHIFT_OP(psllw, 7);
2446 085339a1 bellard
    SHIFT_OP(psllw, 16);
2447 085339a1 bellard
2448 085339a1 bellard
    SHIFT_OP(psrld, 7);
2449 085339a1 bellard
    SHIFT_OP(psrld, 32);
2450 085339a1 bellard
    SHIFT_OP(psrad, 7);
2451 085339a1 bellard
    SHIFT_OP(psrad, 32);
2452 085339a1 bellard
    SHIFT_OP(pslld, 7);
2453 085339a1 bellard
    SHIFT_OP(pslld, 32);
2454 085339a1 bellard
2455 085339a1 bellard
    SHIFT_OP(psrlq, 7);
2456 085339a1 bellard
    SHIFT_OP(psrlq, 32);
2457 085339a1 bellard
    SHIFT_OP(psllq, 7);
2458 085339a1 bellard
    SHIFT_OP(psllq, 32);
2459 085339a1 bellard
2460 085339a1 bellard
    SHIFT_IM(psrldq, 16);
2461 085339a1 bellard
    SHIFT_IM(psrldq, 7);
2462 085339a1 bellard
    SHIFT_IM(pslldq, 16);
2463 085339a1 bellard
    SHIFT_IM(pslldq, 7);
2464 085339a1 bellard
2465 085339a1 bellard
    MOVMSK(movmskps);
2466 085339a1 bellard
    MOVMSK(movmskpd);
2467 085339a1 bellard
2468 085339a1 bellard
    /* FPU specific ops */
2469 085339a1 bellard
2470 085339a1 bellard
    {
2471 085339a1 bellard
        uint32_t mxcsr;
2472 085339a1 bellard
        asm volatile("stmxcsr %0" : "=m" (mxcsr));
2473 085339a1 bellard
        printf("mxcsr=%08x\n", mxcsr & 0x1f80);
2474 085339a1 bellard
        asm volatile("ldmxcsr %0" : : "m" (mxcsr));
2475 085339a1 bellard
    }
2476 085339a1 bellard
2477 085339a1 bellard
    test_sse_comi(2, -1);
2478 085339a1 bellard
    test_sse_comi(2, 2);
2479 085339a1 bellard
    test_sse_comi(2, 3);
2480 86bd2ca5 bellard
    test_sse_comi(2, q_nan.d);
2481 86bd2ca5 bellard
    test_sse_comi(q_nan.d, -1);
2482 86bd2ca5 bellard
2483 86bd2ca5 bellard
    for(i = 0; i < 2; i++) {
2484 86bd2ca5 bellard
        a.s[0] = 2.7;
2485 86bd2ca5 bellard
        a.s[1] = 3.4;
2486 86bd2ca5 bellard
        a.s[2] = 4;
2487 86bd2ca5 bellard
        a.s[3] = -6.3;
2488 86bd2ca5 bellard
        b.s[0] = 45.7;
2489 86bd2ca5 bellard
        b.s[1] = 353.4;
2490 86bd2ca5 bellard
        b.s[2] = 4;
2491 86bd2ca5 bellard
        b.s[3] = 56.3;
2492 86bd2ca5 bellard
        if (i == 1) {
2493 86bd2ca5 bellard
            a.s[0] = q_nan.d;
2494 86bd2ca5 bellard
            b.s[3] = q_nan.d;
2495 86bd2ca5 bellard
        }
2496 86bd2ca5 bellard
2497 86bd2ca5 bellard
        SSE_OPS(add);
2498 86bd2ca5 bellard
        SSE_OPS(mul);
2499 86bd2ca5 bellard
        SSE_OPS(sub);
2500 86bd2ca5 bellard
        SSE_OPS(min);
2501 86bd2ca5 bellard
        SSE_OPS(div);
2502 86bd2ca5 bellard
        SSE_OPS(max);
2503 86bd2ca5 bellard
        SSE_OPS(sqrt);
2504 86bd2ca5 bellard
        SSE_OPS(cmpeq);
2505 86bd2ca5 bellard
        SSE_OPS(cmplt);
2506 86bd2ca5 bellard
        SSE_OPS(cmple);
2507 86bd2ca5 bellard
        SSE_OPS(cmpunord);
2508 86bd2ca5 bellard
        SSE_OPS(cmpneq);
2509 86bd2ca5 bellard
        SSE_OPS(cmpnlt);
2510 86bd2ca5 bellard
        SSE_OPS(cmpnle);
2511 86bd2ca5 bellard
        SSE_OPS(cmpord);
2512 3b46e624 ths
2513 3b46e624 ths
2514 86bd2ca5 bellard
        a.d[0] = 2.7;
2515 86bd2ca5 bellard
        a.d[1] = -3.4;
2516 86bd2ca5 bellard
        b.d[0] = 45.7;
2517 86bd2ca5 bellard
        b.d[1] = -53.4;
2518 86bd2ca5 bellard
        if (i == 1) {
2519 86bd2ca5 bellard
            a.d[0] = q_nan.d;
2520 86bd2ca5 bellard
            b.d[1] = q_nan.d;
2521 86bd2ca5 bellard
        }
2522 86bd2ca5 bellard
        SSE_OPD(add);
2523 86bd2ca5 bellard
        SSE_OPD(mul);
2524 86bd2ca5 bellard
        SSE_OPD(sub);
2525 86bd2ca5 bellard
        SSE_OPD(min);
2526 86bd2ca5 bellard
        SSE_OPD(div);
2527 86bd2ca5 bellard
        SSE_OPD(max);
2528 86bd2ca5 bellard
        SSE_OPD(sqrt);
2529 86bd2ca5 bellard
        SSE_OPD(cmpeq);
2530 86bd2ca5 bellard
        SSE_OPD(cmplt);
2531 86bd2ca5 bellard
        SSE_OPD(cmple);
2532 86bd2ca5 bellard
        SSE_OPD(cmpunord);
2533 86bd2ca5 bellard
        SSE_OPD(cmpneq);
2534 86bd2ca5 bellard
        SSE_OPD(cmpnlt);
2535 86bd2ca5 bellard
        SSE_OPD(cmpnle);
2536 86bd2ca5 bellard
        SSE_OPD(cmpord);
2537 86bd2ca5 bellard
    }
2538 085339a1 bellard
2539 085339a1 bellard
    /* float to float/int */
2540 085339a1 bellard
    a.s[0] = 2.7;
2541 085339a1 bellard
    a.s[1] = 3.4;
2542 085339a1 bellard
    a.s[2] = 4;
2543 085339a1 bellard
    a.s[3] = -6.3;
2544 085339a1 bellard
    CVT_OP_XMM(cvtps2pd);
2545 085339a1 bellard
    CVT_OP_XMM(cvtss2sd);
2546 085339a1 bellard
    CVT_OP_XMM2MMX(cvtps2pi);
2547 085339a1 bellard
    CVT_OP_XMM2MMX(cvttps2pi);
2548 085339a1 bellard
    CVT_OP_XMM2REG(cvtss2si);
2549 085339a1 bellard
    CVT_OP_XMM2REG(cvttss2si);
2550 085339a1 bellard
    CVT_OP_XMM(cvtps2dq);
2551 085339a1 bellard
    CVT_OP_XMM(cvttps2dq);
2552 085339a1 bellard
2553 085339a1 bellard
    a.d[0] = 2.6;
2554 085339a1 bellard
    a.d[1] = -3.4;
2555 085339a1 bellard
    CVT_OP_XMM(cvtpd2ps);
2556 085339a1 bellard
    CVT_OP_XMM(cvtsd2ss);
2557 085339a1 bellard
    CVT_OP_XMM2MMX(cvtpd2pi);
2558 085339a1 bellard
    CVT_OP_XMM2MMX(cvttpd2pi);
2559 085339a1 bellard
    CVT_OP_XMM2REG(cvtsd2si);
2560 085339a1 bellard
    CVT_OP_XMM2REG(cvttsd2si);
2561 085339a1 bellard
    CVT_OP_XMM(cvtpd2dq);
2562 085339a1 bellard
    CVT_OP_XMM(cvttpd2dq);
2563 085339a1 bellard
2564 80e7d521 bellard
    /* sse/mmx moves */
2565 80e7d521 bellard
    CVT_OP_XMM2MMX(movdq2q);
2566 80e7d521 bellard
    CVT_OP_MMX2XMM(movq2dq);
2567 80e7d521 bellard
2568 085339a1 bellard
    /* int to float */
2569 085339a1 bellard
    a.l[0] = -6;
2570 085339a1 bellard
    a.l[1] = 2;
2571 085339a1 bellard
    a.l[2] = 100;
2572 085339a1 bellard
    a.l[3] = -60000;
2573 085339a1 bellard
    CVT_OP_MMX2XMM(cvtpi2ps);
2574 085339a1 bellard
    CVT_OP_MMX2XMM(cvtpi2pd);
2575 085339a1 bellard
    CVT_OP_REG2XMM(cvtsi2ss);
2576 085339a1 bellard
    CVT_OP_REG2XMM(cvtsi2sd);
2577 085339a1 bellard
    CVT_OP_XMM(cvtdq2ps);
2578 085339a1 bellard
    CVT_OP_XMM(cvtdq2pd);
2579 085339a1 bellard
2580 085339a1 bellard
    /* XXX: test PNI insns */
2581 085339a1 bellard
#if 0
2582 085339a1 bellard
    SSE_OP2(movshdup);
2583 085339a1 bellard
#endif
2584 a4682cc2 bellard
    asm volatile ("emms");
2585 085339a1 bellard
}
2586 085339a1 bellard
2587 085339a1 bellard
#endif
2588 085339a1 bellard
2589 df517cec bellard
#define TEST_CONV_RAX(op)\
2590 df517cec bellard
{\
2591 df517cec bellard
    unsigned long a, r;\
2592 df517cec bellard
    a = i2l(0x8234a6f8);\
2593 df517cec bellard
    r = a;\
2594 df517cec bellard
    asm volatile(#op : "=a" (r) : "0" (r));\
2595 df517cec bellard
    printf("%-10s A=" FMTLX " R=" FMTLX "\n", #op, a, r);\
2596 df517cec bellard
}
2597 df517cec bellard
2598 df517cec bellard
#define TEST_CONV_RAX_RDX(op)\
2599 df517cec bellard
{\
2600 df517cec bellard
    unsigned long a, d, r, rh;                   \
2601 df517cec bellard
    a = i2l(0x8234a6f8);\
2602 df517cec bellard
    d = i2l(0x8345a1f2);\
2603 df517cec bellard
    r = a;\
2604 df517cec bellard
    rh = d;\
2605 df517cec bellard
    asm volatile(#op : "=a" (r), "=d" (rh) : "0" (r), "1" (rh));   \
2606 df517cec bellard
    printf("%-10s A=" FMTLX " R=" FMTLX ":" FMTLX "\n", #op, a, r, rh);  \
2607 df517cec bellard
}
2608 df517cec bellard
2609 df517cec bellard
void test_conv(void)
2610 df517cec bellard
{
2611 df517cec bellard
    TEST_CONV_RAX(cbw);
2612 df517cec bellard
    TEST_CONV_RAX(cwde);
2613 df517cec bellard
#if defined(__x86_64__)
2614 df517cec bellard
    TEST_CONV_RAX(cdqe);
2615 df517cec bellard
#endif
2616 df517cec bellard
2617 df517cec bellard
    TEST_CONV_RAX_RDX(cwd);
2618 df517cec bellard
    TEST_CONV_RAX_RDX(cdq);
2619 df517cec bellard
#if defined(__x86_64__)
2620 df517cec bellard
    TEST_CONV_RAX_RDX(cqo);
2621 df517cec bellard
#endif
2622 df517cec bellard
}
2623 df517cec bellard
2624 776f2227 bellard
extern void *__start_initcall;
2625 776f2227 bellard
extern void *__stop_initcall;
2626 776f2227 bellard
2627 4d1135e4 bellard
2628 4d1135e4 bellard
int main(int argc, char **argv)
2629 4d1135e4 bellard
{
2630 4d1135e4 bellard
    void **ptr;
2631 4d1135e4 bellard
    void (*func)(void);
2632 4b74fe1f bellard
2633 776f2227 bellard
    ptr = &__start_initcall;
2634 776f2227 bellard
    while (ptr != &__stop_initcall) {
2635 4d1135e4 bellard
        func = *ptr++;
2636 4d1135e4 bellard
        func();
2637 4d1135e4 bellard
    }
2638 9d8e9c09 bellard
    test_bsx();
2639 d57c4e01 bellard
    test_mul();
2640 4d1135e4 bellard
    test_jcc();
2641 9d8e9c09 bellard
    test_floats();
2642 776f2227 bellard
#if !defined(__x86_64__)
2643 55480af8 bellard
    test_bcd();
2644 776f2227 bellard
#endif
2645 1a9353d2 bellard
    test_xchg();
2646 e1d4294a bellard
    test_string();
2647 e1d4294a bellard
    test_misc();
2648 6dbad63e bellard
    test_lea();
2649 776f2227 bellard
#ifdef TEST_SEGS
2650 6dbad63e bellard
    test_segs();
2651 e5918247 bellard
    test_code16();
2652 776f2227 bellard
#endif
2653 acae4681 bellard
#ifdef TEST_VM86
2654 3a27ad0b bellard
    test_vm86();
2655 acae4681 bellard
#endif
2656 3a27ad0b bellard
    test_exceptions();
2657 776f2227 bellard
#if !defined(__x86_64__)
2658 3a27ad0b bellard
    test_self_modifying_code();
2659 3ff0631e bellard
    test_single_step();
2660 776f2227 bellard
#endif
2661 61a8c4ec bellard
    test_enter();
2662 df517cec bellard
    test_conv();
2663 085339a1 bellard
#ifdef TEST_SSE
2664 085339a1 bellard
    test_sse();
2665 a4682cc2 bellard
    test_fxsave();
2666 085339a1 bellard
#endif
2667 4d1135e4 bellard
    return 0;
2668 4d1135e4 bellard
}