Statistics
| Branch: | Revision:

root / tests / test-i386.c @ 5439779e

History | View | Annotate | Download (68.2 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 8aadfbf0 bellard
        : "0" (op0));\
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 8aadfbf0 bellard
        : "0" (op0), "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 8aadfbf0 bellard
    TEST_XCHG(xchgq, "", "+q");
1090 776f2227 bellard
#endif
1091 8aadfbf0 bellard
    TEST_XCHG(xchgl, "k", "+q");
1092 8aadfbf0 bellard
    TEST_XCHG(xchgw, "w", "+q");
1093 8aadfbf0 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 8aadfbf0 bellard
    TEST_XCHG(xchgl, "k", "+m");
1099 8aadfbf0 bellard
    TEST_XCHG(xchgw, "w", "+m");
1100 8aadfbf0 bellard
    TEST_XCHG(xchgb, "b", "+m");
1101 e5918247 bellard
1102 776f2227 bellard
#if defined(__x86_64__)
1103 8aadfbf0 bellard
    TEST_XCHG(xaddq, "", "+q");
1104 776f2227 bellard
#endif
1105 8aadfbf0 bellard
    TEST_XCHG(xaddl, "k", "+q");
1106 8aadfbf0 bellard
    TEST_XCHG(xaddw, "w", "+q");
1107 8aadfbf0 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 8aadfbf0 bellard
    TEST_XCHG(xaddq, "", "+m");
1118 776f2227 bellard
#endif
1119 8aadfbf0 bellard
    TEST_XCHG(xaddl, "k", "+m");
1120 8aadfbf0 bellard
    TEST_XCHG(xaddw, "w", "+m");
1121 8aadfbf0 bellard
    TEST_XCHG(xaddb, "b", "+m");
1122 e5918247 bellard
1123 776f2227 bellard
#if defined(__x86_64__)
1124 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgq, "", "+q", 0xfbca7654);
1125 776f2227 bellard
#endif
1126 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "+q", 0xfbca7654);
1127 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "+q", 0xfbca7654);
1128 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "+q", 0xfbca7654);
1129 e5918247 bellard
1130 776f2227 bellard
#if defined(__x86_64__)
1131 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgq, "", "+q", 0xfffefdfc);
1132 776f2227 bellard
#endif
1133 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "+q", 0xfffefdfc);
1134 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "+q", 0xfffefdfc);
1135 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "+q", 0xfffefdfc);
1136 e5918247 bellard
1137 776f2227 bellard
#if defined(__x86_64__)
1138 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgq, "", "+m", 0xfbca7654);
1139 776f2227 bellard
#endif
1140 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "+m", 0xfbca7654);
1141 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "+m", 0xfbca7654);
1142 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "+m", 0xfbca7654);
1143 e5918247 bellard
1144 776f2227 bellard
#if defined(__x86_64__)
1145 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgq, "", "+m", 0xfffefdfc);
1146 776f2227 bellard
#endif
1147 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "+m", 0xfffefdfc);
1148 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "+m", 0xfffefdfc);
1149 8aadfbf0 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 8aadfbf0 bellard
#if 0
1373 e06e5259 bellard
    {
1374 8aadfbf0 bellard
        /* XXX: see if Intel Core2 and AMD64 behavior really
1375 8aadfbf0 bellard
           differ. Here we implemented the Intel way which is not
1376 8aadfbf0 bellard
           compatible yet with QEMU. */
1377 e06e5259 bellard
        static struct __attribute__((packed)) {
1378 8aadfbf0 bellard
            uint64_t offset;
1379 e06e5259 bellard
            uint16_t seg;
1380 e06e5259 bellard
        } desc;
1381 e06e5259 bellard
        long cs_sel;
1382 e06e5259 bellard

1383 e06e5259 bellard
        asm volatile ("mov %%cs, %0" : "=r" (cs_sel));
1384 e06e5259 bellard

1385 e06e5259 bellard
        asm volatile ("push %1\n"
1386 5fafdf24 ths
                      "call func_lret\n"
1387 e06e5259 bellard
                      : "=a" (res)
1388 e06e5259 bellard
                      : "r" (cs_sel) : "memory", "cc");
1389 e06e5259 bellard
        printf("func_lret=" FMTLX "\n", res);
1390 e06e5259 bellard

1391 e06e5259 bellard
        desc.offset = (long)&func_lret;
1392 e06e5259 bellard
        desc.seg = cs_sel;
1393 3b46e624 ths

1394 e06e5259 bellard
        asm volatile ("xor %%rax, %%rax\n"
1395 8aadfbf0 bellard
                      "rex64 lcall *(%%rcx)\n"
1396 e06e5259 bellard
                      : "=a" (res)
1397 8aadfbf0 bellard
                      : "c" (&desc)
1398 e06e5259 bellard
                      : "memory", "cc");
1399 e06e5259 bellard
        printf("func_lret2=" FMTLX "\n", res);
1400 e06e5259 bellard

1401 e06e5259 bellard
        asm volatile ("push %2\n"
1402 e06e5259 bellard
                      "mov $ 1f, %%rax\n"
1403 e06e5259 bellard
                      "push %%rax\n"
1404 8aadfbf0 bellard
                      "rex64 ljmp *(%%rcx)\n"
1405 e06e5259 bellard
                      "1:\n"
1406 e06e5259 bellard
                      : "=a" (res)
1407 8aadfbf0 bellard
                      : "c" (&desc), "b" (cs_sel)
1408 e06e5259 bellard
                      : "memory", "cc");
1409 e06e5259 bellard
        printf("func_lret3=" FMTLX "\n", res);
1410 e06e5259 bellard
    }
1411 8aadfbf0 bellard
#endif
1412 e06e5259 bellard
#else
1413 5fafdf24 ths
    asm volatile ("push %%cs ; call %1"
1414 dd3587f3 bellard
                  : "=a" (res)
1415 e06e5259 bellard
                  : "m" (func_lret): "memory", "cc");
1416 e06e5259 bellard
    printf("func_lret=" FMTLX "\n", res);
1417 dd3587f3 bellard
1418 5fafdf24 ths
    asm volatile ("pushf ; push %%cs ; call %1"
1419 dd3587f3 bellard
                  : "=a" (res)
1420 e06e5259 bellard
                  : "m" (func_iret): "memory", "cc");
1421 e06e5259 bellard
    printf("func_iret=" FMTLX "\n", res);
1422 776f2227 bellard
#endif
1423 dd3587f3 bellard
1424 776f2227 bellard
#if defined(__x86_64__)
1425 776f2227 bellard
    /* specific popl test */
1426 776f2227 bellard
    asm volatile ("push $12345432 ; push $0x9abcdef ; pop (%%rsp) ; pop %0"
1427 776f2227 bellard
                  : "=g" (res));
1428 776f2227 bellard
    printf("popl esp=" FMTLX "\n", res);
1429 776f2227 bellard
#else
1430 dd3587f3 bellard
    /* specific popl test */
1431 dd3587f3 bellard
    asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popl (%%esp) ; popl %0"
1432 dd3587f3 bellard
                  : "=g" (res));
1433 776f2227 bellard
    printf("popl esp=" FMTLX "\n", res);
1434 b2b5fb22 bellard
1435 b2b5fb22 bellard
    /* specific popw test */
1436 b2b5fb22 bellard
    asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popw (%%esp) ; addl $2, %%esp ; popl %0"
1437 b2b5fb22 bellard
                  : "=g" (res));
1438 776f2227 bellard
    printf("popw esp=" FMTLX "\n", res);
1439 776f2227 bellard
#endif
1440 e1d4294a bellard
}
1441 e1d4294a bellard
1442 e1d4294a bellard
uint8_t str_buffer[4096];
1443 e1d4294a bellard
1444 e1d4294a bellard
#define TEST_STRING1(OP, size, DF, REP)\
1445 e1d4294a bellard
{\
1446 776f2227 bellard
    long esi, edi, eax, ecx, eflags;\
1447 e1d4294a bellard
\
1448 e1d4294a bellard
    esi = (long)(str_buffer + sizeof(str_buffer) / 2);\
1449 e1d4294a bellard
    edi = (long)(str_buffer + sizeof(str_buffer) / 2) + 16;\
1450 776f2227 bellard
    eax = i2l(0x12345678);\
1451 e1d4294a bellard
    ecx = 17;\
1452 e1d4294a bellard
\
1453 776f2227 bellard
    asm volatile ("push $0\n\t"\
1454 e1d4294a bellard
                  "popf\n\t"\
1455 e1d4294a bellard
                  DF "\n\t"\
1456 e1d4294a bellard
                  REP #OP size "\n\t"\
1457 e1d4294a bellard
                  "cld\n\t"\
1458 e1d4294a bellard
                  "pushf\n\t"\
1459 776f2227 bellard
                  "pop %4\n\t"\
1460 e1d4294a bellard
                  : "=S" (esi), "=D" (edi), "=a" (eax), "=c" (ecx), "=g" (eflags)\
1461 e1d4294a bellard
                  : "0" (esi), "1" (edi), "2" (eax), "3" (ecx));\
1462 776f2227 bellard
    printf("%-10s ESI=" FMTLX " EDI=" FMTLX " EAX=" FMTLX " ECX=" FMTLX " EFL=%04x\n",\
1463 e1d4294a bellard
           REP #OP size, esi, edi, eax, ecx,\
1464 776f2227 bellard
           (int)(eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)));\
1465 e1d4294a bellard
}
1466 e1d4294a bellard
1467 e1d4294a bellard
#define TEST_STRING(OP, REP)\
1468 e1d4294a bellard
    TEST_STRING1(OP, "b", "", REP);\
1469 e1d4294a bellard
    TEST_STRING1(OP, "w", "", REP);\
1470 e1d4294a bellard
    TEST_STRING1(OP, "l", "", REP);\
1471 776f2227 bellard
    X86_64_ONLY(TEST_STRING1(OP, "q", "", REP));\
1472 e1d4294a bellard
    TEST_STRING1(OP, "b", "std", REP);\
1473 e1d4294a bellard
    TEST_STRING1(OP, "w", "std", REP);\
1474 776f2227 bellard
    TEST_STRING1(OP, "l", "std", REP);\
1475 776f2227 bellard
    X86_64_ONLY(TEST_STRING1(OP, "q", "std", REP))
1476 e1d4294a bellard
1477 e1d4294a bellard
void test_string(void)
1478 e1d4294a bellard
{
1479 e1d4294a bellard
    int i;
1480 e1d4294a bellard
    for(i = 0;i < sizeof(str_buffer); i++)
1481 e1d4294a bellard
        str_buffer[i] = i + 0x56;
1482 e1d4294a bellard
   TEST_STRING(stos, "");
1483 e1d4294a bellard
   TEST_STRING(stos, "rep ");
1484 e1d4294a bellard
   TEST_STRING(lods, ""); /* to verify stos */
1485 5fafdf24 ths
   TEST_STRING(lods, "rep ");
1486 e1d4294a bellard
   TEST_STRING(movs, "");
1487 e1d4294a bellard
   TEST_STRING(movs, "rep ");
1488 e1d4294a bellard
   TEST_STRING(lods, ""); /* to verify stos */
1489 e1d4294a bellard
1490 e1d4294a bellard
   /* XXX: better tests */
1491 e1d4294a bellard
   TEST_STRING(scas, "");
1492 e1d4294a bellard
   TEST_STRING(scas, "repz ");
1493 e1d4294a bellard
   TEST_STRING(scas, "repnz ");
1494 e1d4294a bellard
   TEST_STRING(cmps, "");
1495 e1d4294a bellard
   TEST_STRING(cmps, "repz ");
1496 e1d4294a bellard
   TEST_STRING(cmps, "repnz ");
1497 e1d4294a bellard
}
1498 e5918247 bellard
1499 776f2227 bellard
#ifdef TEST_VM86
1500 3a27ad0b bellard
/* VM86 test */
1501 3a27ad0b bellard
1502 3a27ad0b bellard
static inline void set_bit(uint8_t *a, unsigned int bit)
1503 3a27ad0b bellard
{
1504 3a27ad0b bellard
    a[bit / 8] |= (1 << (bit % 8));
1505 3a27ad0b bellard
}
1506 3a27ad0b bellard
1507 3a27ad0b bellard
static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
1508 3a27ad0b bellard
{
1509 3a27ad0b bellard
    return (uint8_t *)((seg << 4) + (reg & 0xffff));
1510 3a27ad0b bellard
}
1511 3a27ad0b bellard
1512 3a27ad0b bellard
static inline void pushw(struct vm86_regs *r, int val)
1513 3a27ad0b bellard
{
1514 3a27ad0b bellard
    r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff);
1515 3a27ad0b bellard
    *(uint16_t *)seg_to_linear(r->ss, r->esp) = val;
1516 3a27ad0b bellard
}
1517 3a27ad0b bellard
1518 be98f1f8 bellard
static inline int vm86(int func, struct vm86plus_struct *v86)
1519 be98f1f8 bellard
{
1520 be98f1f8 bellard
    return syscall(__NR_vm86, func, v86);
1521 be98f1f8 bellard
}
1522 3a27ad0b bellard
1523 3a27ad0b bellard
extern char vm86_code_start;
1524 3a27ad0b bellard
extern char vm86_code_end;
1525 3a27ad0b bellard
1526 3a27ad0b bellard
#define VM86_CODE_CS 0x100
1527 3a27ad0b bellard
#define VM86_CODE_IP 0x100
1528 3a27ad0b bellard
1529 3a27ad0b bellard
void test_vm86(void)
1530 3a27ad0b bellard
{
1531 3a27ad0b bellard
    struct vm86plus_struct ctx;
1532 3a27ad0b bellard
    struct vm86_regs *r;
1533 3a27ad0b bellard
    uint8_t *vm86_mem;
1534 3a27ad0b bellard
    int seg, ret;
1535 3a27ad0b bellard
1536 5fafdf24 ths
    vm86_mem = mmap((void *)0x00000000, 0x110000,
1537 5fafdf24 ths
                    PROT_WRITE | PROT_READ | PROT_EXEC,
1538 3a27ad0b bellard
                    MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
1539 3a27ad0b bellard
    if (vm86_mem == MAP_FAILED) {
1540 3a27ad0b bellard
        printf("ERROR: could not map vm86 memory");
1541 3a27ad0b bellard
        return;
1542 3a27ad0b bellard
    }
1543 3a27ad0b bellard
    memset(&ctx, 0, sizeof(ctx));
1544 3a27ad0b bellard
1545 3a27ad0b bellard
    /* init basic registers */
1546 3a27ad0b bellard
    r = &ctx.regs;
1547 3a27ad0b bellard
    r->eip = VM86_CODE_IP;
1548 3a27ad0b bellard
    r->esp = 0xfffe;
1549 3a27ad0b bellard
    seg = VM86_CODE_CS;
1550 3a27ad0b bellard
    r->cs = seg;
1551 3a27ad0b bellard
    r->ss = seg;
1552 3a27ad0b bellard
    r->ds = seg;
1553 3a27ad0b bellard
    r->es = seg;
1554 3a27ad0b bellard
    r->fs = seg;
1555 3a27ad0b bellard
    r->gs = seg;
1556 3a27ad0b bellard
    r->eflags = VIF_MASK;
1557 3a27ad0b bellard
1558 3a27ad0b bellard
    /* move code to proper address. We use the same layout as a .com
1559 3a27ad0b bellard
       dos program. */
1560 5fafdf24 ths
    memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP,
1561 3a27ad0b bellard
           &vm86_code_start, &vm86_code_end - &vm86_code_start);
1562 3a27ad0b bellard
1563 3a27ad0b bellard
    /* mark int 0x21 as being emulated */
1564 3a27ad0b bellard
    set_bit((uint8_t *)&ctx.int_revectored, 0x21);
1565 3a27ad0b bellard
1566 3a27ad0b bellard
    for(;;) {
1567 3a27ad0b bellard
        ret = vm86(VM86_ENTER, &ctx);
1568 3a27ad0b bellard
        switch(VM86_TYPE(ret)) {
1569 3a27ad0b bellard
        case VM86_INTx:
1570 3a27ad0b bellard
            {
1571 3ff0631e bellard
                int int_num, ah, v;
1572 3b46e624 ths
1573 3a27ad0b bellard
                int_num = VM86_ARG(ret);
1574 3a27ad0b bellard
                if (int_num != 0x21)
1575 3a27ad0b bellard
                    goto unknown_int;
1576 3a27ad0b bellard
                ah = (r->eax >> 8) & 0xff;
1577 3a27ad0b bellard
                switch(ah) {
1578 3a27ad0b bellard
                case 0x00: /* exit */
1579 3a27ad0b bellard
                    goto the_end;
1580 3a27ad0b bellard
                case 0x02: /* write char */
1581 3a27ad0b bellard
                    {
1582 3a27ad0b bellard
                        uint8_t c = r->edx;
1583 3a27ad0b bellard
                        putchar(c);
1584 3a27ad0b bellard
                    }
1585 3a27ad0b bellard
                    break;
1586 3a27ad0b bellard
                case 0x09: /* write string */
1587 3a27ad0b bellard
                    {
1588 3a27ad0b bellard
                        uint8_t c, *ptr;
1589 3a27ad0b bellard
                        ptr = seg_to_linear(r->ds, r->edx);
1590 3a27ad0b bellard
                        for(;;) {
1591 3a27ad0b bellard
                            c = *ptr++;
1592 3a27ad0b bellard
                            if (c == '$')
1593 3a27ad0b bellard
                                break;
1594 3a27ad0b bellard
                            putchar(c);
1595 3a27ad0b bellard
                        }
1596 3a27ad0b bellard
                        r->eax = (r->eax & ~0xff) | '$';
1597 3a27ad0b bellard
                    }
1598 3a27ad0b bellard
                    break;
1599 3ff0631e bellard
                case 0xff: /* extension: write eflags number in edx */
1600 3ff0631e bellard
                    v = (int)r->edx;
1601 3ff0631e bellard
#ifndef LINUX_VM86_IOPL_FIX
1602 3ff0631e bellard
                    v &= ~0x3000;
1603 3ff0631e bellard
#endif
1604 3ff0631e bellard
                    printf("%08x\n", v);
1605 3a27ad0b bellard
                    break;
1606 3a27ad0b bellard
                default:
1607 3a27ad0b bellard
                unknown_int:
1608 3a27ad0b bellard
                    printf("unsupported int 0x%02x\n", int_num);
1609 3a27ad0b bellard
                    goto the_end;
1610 3a27ad0b bellard
                }
1611 3a27ad0b bellard
            }
1612 3a27ad0b bellard
            break;
1613 3a27ad0b bellard
        case VM86_SIGNAL:
1614 3a27ad0b bellard
            /* a signal came, we just ignore that */
1615 3a27ad0b bellard
            break;
1616 3a27ad0b bellard
        case VM86_STI:
1617 3a27ad0b bellard
            break;
1618 3a27ad0b bellard
        default:
1619 3a27ad0b bellard
            printf("ERROR: unhandled vm86 return code (0x%x)\n", ret);
1620 3a27ad0b bellard
            goto the_end;
1621 3a27ad0b bellard
        }
1622 3a27ad0b bellard
    }
1623 3a27ad0b bellard
 the_end:
1624 3a27ad0b bellard
    printf("VM86 end\n");
1625 3a27ad0b bellard
    munmap(vm86_mem, 0x110000);
1626 3a27ad0b bellard
}
1627 776f2227 bellard
#endif
1628 3a27ad0b bellard
1629 3a27ad0b bellard
/* exception tests */
1630 776f2227 bellard
#if defined(__i386__) && !defined(REG_EAX)
1631 3a27ad0b bellard
#define REG_EAX EAX
1632 3a27ad0b bellard
#define REG_EBX EBX
1633 3a27ad0b bellard
#define REG_ECX ECX
1634 3a27ad0b bellard
#define REG_EDX EDX
1635 3a27ad0b bellard
#define REG_ESI ESI
1636 3a27ad0b bellard
#define REG_EDI EDI
1637 3a27ad0b bellard
#define REG_EBP EBP
1638 3a27ad0b bellard
#define REG_ESP ESP
1639 3a27ad0b bellard
#define REG_EIP EIP
1640 3a27ad0b bellard
#define REG_EFL EFL
1641 3a27ad0b bellard
#define REG_TRAPNO TRAPNO
1642 3a27ad0b bellard
#define REG_ERR ERR
1643 3a27ad0b bellard
#endif
1644 3a27ad0b bellard
1645 776f2227 bellard
#if defined(__x86_64__)
1646 776f2227 bellard
#define REG_EIP REG_RIP
1647 776f2227 bellard
#endif
1648 776f2227 bellard
1649 3a27ad0b bellard
jmp_buf jmp_env;
1650 3a27ad0b bellard
int v1;
1651 3a27ad0b bellard
int tab[2];
1652 3a27ad0b bellard
1653 3a27ad0b bellard
void sig_handler(int sig, siginfo_t *info, void *puc)
1654 3a27ad0b bellard
{
1655 3a27ad0b bellard
    struct ucontext *uc = puc;
1656 3a27ad0b bellard
1657 3a27ad0b bellard
    printf("si_signo=%d si_errno=%d si_code=%d",
1658 3a27ad0b bellard
           info->si_signo, info->si_errno, info->si_code);
1659 e3b32540 bellard
    printf(" si_addr=0x%08lx",
1660 e3b32540 bellard
           (unsigned long)info->si_addr);
1661 3a27ad0b bellard
    printf("\n");
1662 3a27ad0b bellard
1663 776f2227 bellard
    printf("trapno=" FMTLX " err=" FMTLX,
1664 776f2227 bellard
           (long)uc->uc_mcontext.gregs[REG_TRAPNO],
1665 776f2227 bellard
           (long)uc->uc_mcontext.gregs[REG_ERR]);
1666 776f2227 bellard
    printf(" EIP=" FMTLX, (long)uc->uc_mcontext.gregs[REG_EIP]);
1667 3a27ad0b bellard
    printf("\n");
1668 3a27ad0b bellard
    longjmp(jmp_env, 1);
1669 3a27ad0b bellard
}
1670 3a27ad0b bellard
1671 3a27ad0b bellard
void test_exceptions(void)
1672 3a27ad0b bellard
{
1673 3a27ad0b bellard
    struct sigaction act;
1674 3a27ad0b bellard
    volatile int val;
1675 3b46e624 ths
1676 3a27ad0b bellard
    act.sa_sigaction = sig_handler;
1677 3a27ad0b bellard
    sigemptyset(&act.sa_mask);
1678 776f2227 bellard
    act.sa_flags = SA_SIGINFO | SA_NODEFER;
1679 3a27ad0b bellard
    sigaction(SIGFPE, &act, NULL);
1680 3a27ad0b bellard
    sigaction(SIGILL, &act, NULL);
1681 3a27ad0b bellard
    sigaction(SIGSEGV, &act, NULL);
1682 e3b32540 bellard
    sigaction(SIGBUS, &act, NULL);
1683 3a27ad0b bellard
    sigaction(SIGTRAP, &act, NULL);
1684 3a27ad0b bellard
1685 3a27ad0b bellard
    /* test division by zero reporting */
1686 e3b32540 bellard
    printf("DIVZ exception:\n");
1687 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1688 3a27ad0b bellard
        /* now divide by zero */
1689 3a27ad0b bellard
        v1 = 0;
1690 3a27ad0b bellard
        v1 = 2 / v1;
1691 3a27ad0b bellard
    }
1692 3a27ad0b bellard
1693 776f2227 bellard
#if !defined(__x86_64__)
1694 e3b32540 bellard
    printf("BOUND exception:\n");
1695 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1696 3a27ad0b bellard
        /* bound exception */
1697 3a27ad0b bellard
        tab[0] = 1;
1698 3a27ad0b bellard
        tab[1] = 10;
1699 e82d8ade bellard
        asm volatile ("bound %0, %1" : : "r" (11), "m" (tab[0]));
1700 3a27ad0b bellard
    }
1701 776f2227 bellard
#endif
1702 3a27ad0b bellard
1703 776f2227 bellard
#ifdef TEST_SEGS
1704 e3b32540 bellard
    printf("segment exceptions:\n");
1705 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1706 e3b32540 bellard
        /* load an invalid segment */
1707 e3b32540 bellard
        asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 1));
1708 e3b32540 bellard
    }
1709 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1710 e3b32540 bellard
        /* null data segment is valid */
1711 e3b32540 bellard
        asm volatile ("movl %0, %%fs" : : "r" (3));
1712 e3b32540 bellard
        /* null stack segment */
1713 e3b32540 bellard
        asm volatile ("movl %0, %%ss" : : "r" (3));
1714 e3b32540 bellard
    }
1715 e3b32540 bellard
1716 776f2227 bellard
    {
1717 776f2227 bellard
        struct modify_ldt_ldt_s ldt;
1718 776f2227 bellard
        ldt.entry_number = 1;
1719 776f2227 bellard
        ldt.base_addr = (unsigned long)&seg_data1;
1720 776f2227 bellard
        ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
1721 776f2227 bellard
        ldt.seg_32bit = 1;
1722 776f2227 bellard
        ldt.contents = MODIFY_LDT_CONTENTS_DATA;
1723 776f2227 bellard
        ldt.read_exec_only = 0;
1724 776f2227 bellard
        ldt.limit_in_pages = 1;
1725 776f2227 bellard
        ldt.seg_not_present = 1;
1726 776f2227 bellard
        ldt.useable = 1;
1727 776f2227 bellard
        modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
1728 3b46e624 ths
1729 776f2227 bellard
        if (setjmp(jmp_env) == 0) {
1730 776f2227 bellard
            /* segment not present */
1731 776f2227 bellard
            asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
1732 776f2227 bellard
        }
1733 e3b32540 bellard
    }
1734 776f2227 bellard
#endif
1735 e3b32540 bellard
1736 3a27ad0b bellard
    /* test SEGV reporting */
1737 e3b32540 bellard
    printf("PF exception:\n");
1738 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1739 e3b32540 bellard
        val = 1;
1740 ede28208 bellard
        /* we add a nop to test a weird PC retrieval case */
1741 ede28208 bellard
        asm volatile ("nop");
1742 3a27ad0b bellard
        /* now store in an invalid address */
1743 3a27ad0b bellard
        *(char *)0x1234 = 1;
1744 3a27ad0b bellard
    }
1745 3a27ad0b bellard
1746 3a27ad0b bellard
    /* test SEGV reporting */
1747 e3b32540 bellard
    printf("PF exception:\n");
1748 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1749 e3b32540 bellard
        val = 1;
1750 3a27ad0b bellard
        /* read from an invalid address */
1751 3a27ad0b bellard
        v1 = *(char *)0x1234;
1752 3a27ad0b bellard
    }
1753 3b46e624 ths
1754 3a27ad0b bellard
    /* test illegal instruction reporting */
1755 3a27ad0b bellard
    printf("UD2 exception:\n");
1756 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1757 3a27ad0b bellard
        /* now execute an invalid instruction */
1758 3a27ad0b bellard
        asm volatile("ud2");
1759 3a27ad0b bellard
    }
1760 4120b61d bellard
    printf("lock nop exception:\n");
1761 4120b61d bellard
    if (setjmp(jmp_env) == 0) {
1762 4120b61d bellard
        /* now execute an invalid instruction */
1763 4120b61d bellard
        asm volatile("lock nop");
1764 4120b61d bellard
    }
1765 3b46e624 ths
1766 3a27ad0b bellard
    printf("INT exception:\n");
1767 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1768 3a27ad0b bellard
        asm volatile ("int $0xfd");
1769 3a27ad0b bellard
    }
1770 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1771 e3b32540 bellard
        asm volatile ("int $0x01");
1772 e3b32540 bellard
    }
1773 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1774 e3b32540 bellard
        asm volatile (".byte 0xcd, 0x03");
1775 e3b32540 bellard
    }
1776 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1777 e3b32540 bellard
        asm volatile ("int $0x04");
1778 e3b32540 bellard
    }
1779 e3b32540 bellard
    if (setjmp(jmp_env) == 0) {
1780 e3b32540 bellard
        asm volatile ("int $0x05");
1781 e3b32540 bellard
    }
1782 3a27ad0b bellard
1783 3a27ad0b bellard
    printf("INT3 exception:\n");
1784 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1785 3a27ad0b bellard
        asm volatile ("int3");
1786 3a27ad0b bellard
    }
1787 3a27ad0b bellard
1788 3a27ad0b bellard
    printf("CLI exception:\n");
1789 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1790 3a27ad0b bellard
        asm volatile ("cli");
1791 3a27ad0b bellard
    }
1792 3a27ad0b bellard
1793 3a27ad0b bellard
    printf("STI exception:\n");
1794 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1795 3a27ad0b bellard
        asm volatile ("cli");
1796 3a27ad0b bellard
    }
1797 3a27ad0b bellard
1798 776f2227 bellard
#if !defined(__x86_64__)
1799 3a27ad0b bellard
    printf("INTO exception:\n");
1800 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1801 3a27ad0b bellard
        /* overflow exception */
1802 3a27ad0b bellard
        asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff));
1803 3a27ad0b bellard
    }
1804 776f2227 bellard
#endif
1805 3a27ad0b bellard
1806 3a27ad0b bellard
    printf("OUTB exception:\n");
1807 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1808 3a27ad0b bellard
        asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0));
1809 3a27ad0b bellard
    }
1810 3a27ad0b bellard
1811 3a27ad0b bellard
    printf("INB exception:\n");
1812 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1813 3a27ad0b bellard
        asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321));
1814 3a27ad0b bellard
    }
1815 3a27ad0b bellard
1816 3a27ad0b bellard
    printf("REP OUTSB exception:\n");
1817 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1818 3a27ad0b bellard
        asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1));
1819 3a27ad0b bellard
    }
1820 3a27ad0b bellard
1821 3a27ad0b bellard
    printf("REP INSB exception:\n");
1822 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1823 3a27ad0b bellard
        asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1));
1824 3a27ad0b bellard
    }
1825 3a27ad0b bellard
1826 3a27ad0b bellard
    printf("HLT exception:\n");
1827 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1828 3a27ad0b bellard
        asm volatile ("hlt");
1829 3a27ad0b bellard
    }
1830 3a27ad0b bellard
1831 3a27ad0b bellard
    printf("single step exception:\n");
1832 3a27ad0b bellard
    val = 0;
1833 3a27ad0b bellard
    if (setjmp(jmp_env) == 0) {
1834 3a27ad0b bellard
        asm volatile ("pushf\n"
1835 3a27ad0b bellard
                      "orl $0x00100, (%%esp)\n"
1836 3a27ad0b bellard
                      "popf\n"
1837 5fafdf24 ths
                      "movl $0xabcd, %0\n"
1838 3a27ad0b bellard
                      "movl $0x0, %0\n" : "=m" (val) : : "cc", "memory");
1839 3a27ad0b bellard
    }
1840 3a27ad0b bellard
    printf("val=0x%x\n", val);
1841 3a27ad0b bellard
}
1842 3a27ad0b bellard
1843 776f2227 bellard
#if !defined(__x86_64__)
1844 3ff0631e bellard
/* specific precise single step test */
1845 3ff0631e bellard
void sig_trap_handler(int sig, siginfo_t *info, void *puc)
1846 3ff0631e bellard
{
1847 3ff0631e bellard
    struct ucontext *uc = puc;
1848 776f2227 bellard
    printf("EIP=" FMTLX "\n", (long)uc->uc_mcontext.gregs[REG_EIP]);
1849 3ff0631e bellard
}
1850 3ff0631e bellard
1851 3ff0631e bellard
const uint8_t sstep_buf1[4] = { 1, 2, 3, 4};
1852 3ff0631e bellard
uint8_t sstep_buf2[4];
1853 3ff0631e bellard
1854 3ff0631e bellard
void test_single_step(void)
1855 3ff0631e bellard
{
1856 3ff0631e bellard
    struct sigaction act;
1857 3ff0631e bellard
    volatile int val;
1858 3ff0631e bellard
    int i;
1859 3ff0631e bellard
1860 3ff0631e bellard
    val = 0;
1861 3ff0631e bellard
    act.sa_sigaction = sig_trap_handler;
1862 3ff0631e bellard
    sigemptyset(&act.sa_mask);
1863 3ff0631e bellard
    act.sa_flags = SA_SIGINFO;
1864 3ff0631e bellard
    sigaction(SIGTRAP, &act, NULL);
1865 3ff0631e bellard
    asm volatile ("pushf\n"
1866 3ff0631e bellard
                  "orl $0x00100, (%%esp)\n"
1867 3ff0631e bellard
                  "popf\n"
1868 5fafdf24 ths
                  "movl $0xabcd, %0\n"
1869 3ff0631e bellard
1870 3ff0631e bellard
                  /* jmp test */
1871 3ff0631e bellard
                  "movl $3, %%ecx\n"
1872 3ff0631e bellard
                  "1:\n"
1873 3ff0631e bellard
                  "addl $1, %0\n"
1874 3ff0631e bellard
                  "decl %%ecx\n"
1875 3ff0631e bellard
                  "jnz 1b\n"
1876 3ff0631e bellard
1877 3ff0631e bellard
                  /* movsb: the single step should stop at each movsb iteration */
1878 3ff0631e bellard
                  "movl $sstep_buf1, %%esi\n"
1879 3ff0631e bellard
                  "movl $sstep_buf2, %%edi\n"
1880 3ff0631e bellard
                  "movl $0, %%ecx\n"
1881 3ff0631e bellard
                  "rep movsb\n"
1882 3ff0631e bellard
                  "movl $3, %%ecx\n"
1883 3ff0631e bellard
                  "rep movsb\n"
1884 3ff0631e bellard
                  "movl $1, %%ecx\n"
1885 3ff0631e bellard
                  "rep movsb\n"
1886 3ff0631e bellard
1887 3ff0631e bellard
                  /* cmpsb: the single step should stop at each cmpsb iteration */
1888 3ff0631e bellard
                  "movl $sstep_buf1, %%esi\n"
1889 3ff0631e bellard
                  "movl $sstep_buf2, %%edi\n"
1890 3ff0631e bellard
                  "movl $0, %%ecx\n"
1891 3ff0631e bellard
                  "rep cmpsb\n"
1892 3ff0631e bellard
                  "movl $4, %%ecx\n"
1893 3ff0631e bellard
                  "rep cmpsb\n"
1894 3b46e624 ths
1895 3ff0631e bellard
                  /* getpid() syscall: single step should skip one
1896 3ff0631e bellard
                     instruction */
1897 3ff0631e bellard
                  "movl $20, %%eax\n"
1898 3ff0631e bellard
                  "int $0x80\n"
1899 3ff0631e bellard
                  "movl $0, %%eax\n"
1900 3b46e624 ths
1901 3ff0631e bellard
                  /* when modifying SS, trace is not done on the next
1902 3ff0631e bellard
                     instruction */
1903 3ff0631e bellard
                  "movl %%ss, %%ecx\n"
1904 3ff0631e bellard
                  "movl %%ecx, %%ss\n"
1905 3ff0631e bellard
                  "addl $1, %0\n"
1906 3ff0631e bellard
                  "movl $1, %%eax\n"
1907 3ff0631e bellard
                  "movl %%ecx, %%ss\n"
1908 3ff0631e bellard
                  "jmp 1f\n"
1909 3ff0631e bellard
                  "addl $1, %0\n"
1910 3ff0631e bellard
                  "1:\n"
1911 3ff0631e bellard
                  "movl $1, %%eax\n"
1912 3ff0631e bellard
                  "pushl %%ecx\n"
1913 3ff0631e bellard
                  "popl %%ss\n"
1914 3ff0631e bellard
                  "addl $1, %0\n"
1915 3ff0631e bellard
                  "movl $1, %%eax\n"
1916 3b46e624 ths
1917 3ff0631e bellard
                  "pushf\n"
1918 3ff0631e bellard
                  "andl $~0x00100, (%%esp)\n"
1919 3ff0631e bellard
                  "popf\n"
1920 5fafdf24 ths
                  : "=m" (val)
1921 5fafdf24 ths
                  :
1922 3ff0631e bellard
                  : "cc", "memory", "eax", "ecx", "esi", "edi");
1923 3ff0631e bellard
    printf("val=%d\n", val);
1924 3ff0631e bellard
    for(i = 0; i < 4; i++)
1925 3ff0631e bellard
        printf("sstep_buf2[%d] = %d\n", i, sstep_buf2[i]);
1926 3ff0631e bellard
}
1927 3ff0631e bellard
1928 3a27ad0b bellard
/* self modifying code test */
1929 3a27ad0b bellard
uint8_t code[] = {
1930 3a27ad0b bellard
    0xb8, 0x1, 0x00, 0x00, 0x00, /* movl $1, %eax */
1931 3a27ad0b bellard
    0xc3, /* ret */
1932 3a27ad0b bellard
};
1933 3a27ad0b bellard
1934 1190935d bellard
asm("smc_code2:\n"
1935 1190935d bellard
    "movl 4(%esp), %eax\n"
1936 1190935d bellard
    "movl %eax, smc_patch_addr2 + 1\n"
1937 1190935d bellard
    "nop\n"
1938 1190935d bellard
    "nop\n"
1939 1190935d bellard
    "nop\n"
1940 1190935d bellard
    "nop\n"
1941 1190935d bellard
    "nop\n"
1942 1190935d bellard
    "nop\n"
1943 1190935d bellard
    "nop\n"
1944 1190935d bellard
    "nop\n"
1945 1190935d bellard
    "smc_patch_addr2:\n"
1946 1190935d bellard
    "movl $1, %eax\n"
1947 1190935d bellard
    "ret\n");
1948 d1fe2b24 bellard
1949 1190935d bellard
typedef int FuncType(void);
1950 1190935d bellard
extern int smc_code2(int);
1951 3a27ad0b bellard
void test_self_modifying_code(void)
1952 3a27ad0b bellard
{
1953 d1fe2b24 bellard
    int i;
1954 3a27ad0b bellard
1955 3a27ad0b bellard
    printf("self modifying code:\n");
1956 d1fe2b24 bellard
    printf("func1 = 0x%x\n", ((FuncType *)code)());
1957 d1fe2b24 bellard
    for(i = 2; i <= 4; i++) {
1958 d1fe2b24 bellard
        code[1] = i;
1959 d1fe2b24 bellard
        printf("func%d = 0x%x\n", i, ((FuncType *)code)());
1960 d1fe2b24 bellard
    }
1961 1190935d bellard
1962 1190935d bellard
    /* more difficult test : the modified code is just after the
1963 1190935d bellard
       modifying instruction. It is forbidden in Intel specs, but it
1964 1190935d bellard
       is used by old DOS programs */
1965 1190935d bellard
    for(i = 2; i <= 4; i++) {
1966 1190935d bellard
        printf("smc_code2(%d) = %d\n", i, smc_code2(i));
1967 1190935d bellard
    }
1968 3a27ad0b bellard
}
1969 776f2227 bellard
#endif
1970 61a8c4ec bellard
1971 776f2227 bellard
long enter_stack[4096];
1972 776f2227 bellard
1973 776f2227 bellard
#if defined(__x86_64__)
1974 776f2227 bellard
#define RSP "%%rsp"
1975 776f2227 bellard
#define RBP "%%rbp"
1976 776f2227 bellard
#else
1977 776f2227 bellard
#define RSP "%%esp"
1978 776f2227 bellard
#define RBP "%%ebp"
1979 776f2227 bellard
#endif
1980 61a8c4ec bellard
1981 61a8c4ec bellard
#define TEST_ENTER(size, stack_type, level)\
1982 61a8c4ec bellard
{\
1983 776f2227 bellard
    long esp_save, esp_val, ebp_val, ebp_save, i;\
1984 61a8c4ec bellard
    stack_type *ptr, *stack_end, *stack_ptr;\
1985 61a8c4ec bellard
    memset(enter_stack, 0, sizeof(enter_stack));\
1986 61a8c4ec bellard
    stack_end = stack_ptr = (stack_type *)(enter_stack + 4096);\
1987 61a8c4ec bellard
    ebp_val = (long)stack_ptr;\
1988 61a8c4ec bellard
    for(i=1;i<=32;i++)\
1989 61a8c4ec bellard
       *--stack_ptr = i;\
1990 61a8c4ec bellard
    esp_val = (long)stack_ptr;\
1991 776f2227 bellard
    asm("mov " RSP ", %[esp_save]\n"\
1992 776f2227 bellard
        "mov " RBP ", %[ebp_save]\n"\
1993 776f2227 bellard
        "mov %[esp_val], " RSP "\n"\
1994 776f2227 bellard
        "mov %[ebp_val], " RBP "\n"\
1995 776f2227 bellard
        "enter" size " $8, $" #level "\n"\
1996 776f2227 bellard
        "mov " RSP ", %[esp_val]\n"\
1997 776f2227 bellard
        "mov " RBP ", %[ebp_val]\n"\
1998 776f2227 bellard
        "mov %[esp_save], " RSP "\n"\
1999 776f2227 bellard
        "mov %[ebp_save], " RBP "\n"\
2000 61a8c4ec bellard
        : [esp_save] "=r" (esp_save),\
2001 61a8c4ec bellard
        [ebp_save] "=r" (ebp_save),\
2002 61a8c4ec bellard
        [esp_val] "=r" (esp_val),\
2003 61a8c4ec bellard
        [ebp_val] "=r" (ebp_val)\
2004 61a8c4ec bellard
        :  "[esp_val]" (esp_val),\
2005 61a8c4ec bellard
        "[ebp_val]" (ebp_val));\
2006 61a8c4ec bellard
    printf("level=%d:\n", level);\
2007 776f2227 bellard
    printf("esp_val=" FMTLX "\n", esp_val - (long)stack_end);\
2008 776f2227 bellard
    printf("ebp_val=" FMTLX "\n", ebp_val - (long)stack_end);\
2009 61a8c4ec bellard
    for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\
2010 776f2227 bellard
        printf(FMTLX "\n", (long)ptr[0]);\
2011 61a8c4ec bellard
}
2012 61a8c4ec bellard
2013 61a8c4ec bellard
static void test_enter(void)
2014 61a8c4ec bellard
{
2015 776f2227 bellard
#if defined(__x86_64__)
2016 776f2227 bellard
    TEST_ENTER("q", uint64_t, 0);
2017 776f2227 bellard
    TEST_ENTER("q", uint64_t, 1);
2018 776f2227 bellard
    TEST_ENTER("q", uint64_t, 2);
2019 776f2227 bellard
    TEST_ENTER("q", uint64_t, 31);
2020 776f2227 bellard
#else
2021 61a8c4ec bellard
    TEST_ENTER("l", uint32_t, 0);
2022 61a8c4ec bellard
    TEST_ENTER("l", uint32_t, 1);
2023 61a8c4ec bellard
    TEST_ENTER("l", uint32_t, 2);
2024 61a8c4ec bellard
    TEST_ENTER("l", uint32_t, 31);
2025 776f2227 bellard
#endif
2026 61a8c4ec bellard
2027 61a8c4ec bellard
    TEST_ENTER("w", uint16_t, 0);
2028 61a8c4ec bellard
    TEST_ENTER("w", uint16_t, 1);
2029 61a8c4ec bellard
    TEST_ENTER("w", uint16_t, 2);
2030 61a8c4ec bellard
    TEST_ENTER("w", uint16_t, 31);
2031 61a8c4ec bellard
}
2032 61a8c4ec bellard
2033 085339a1 bellard
#ifdef TEST_SSE
2034 085339a1 bellard
2035 085339a1 bellard
typedef int __m64 __attribute__ ((__mode__ (__V2SI__)));
2036 8aadfbf0 bellard
typedef float __m128 __attribute__ ((__mode__(__V4SF__)));
2037 085339a1 bellard
2038 085339a1 bellard
typedef union {
2039 085339a1 bellard
    double d[2];
2040 085339a1 bellard
    float s[4];
2041 085339a1 bellard
    uint32_t l[4];
2042 085339a1 bellard
    uint64_t q[2];
2043 085339a1 bellard
    __m128 dq;
2044 085339a1 bellard
} XMMReg;
2045 085339a1 bellard
2046 085339a1 bellard
static uint64_t __attribute__((aligned(16))) test_values[4][2] = {
2047 085339a1 bellard
    { 0x456723c698694873, 0xdc515cff944a58ec },
2048 085339a1 bellard
    { 0x1f297ccd58bad7ab, 0x41f21efba9e3e146 },
2049 085339a1 bellard
    { 0x007c62c2085427f8, 0x231be9e8cde7438d },
2050 085339a1 bellard
    { 0x0f76255a085427f8, 0xc233e9e8c4c9439a },
2051 085339a1 bellard
};
2052 085339a1 bellard
2053 085339a1 bellard
#define SSE_OP(op)\
2054 085339a1 bellard
{\
2055 085339a1 bellard
    asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
2056 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\
2057 085339a1 bellard
           #op,\
2058 085339a1 bellard
           a.q[1], a.q[0],\
2059 085339a1 bellard
           b.q[1], b.q[0],\
2060 085339a1 bellard
           r.q[1], r.q[0]);\
2061 085339a1 bellard
}
2062 085339a1 bellard
2063 085339a1 bellard
#define SSE_OP2(op)\
2064 085339a1 bellard
{\
2065 085339a1 bellard
    int i;\
2066 085339a1 bellard
    for(i=0;i<2;i++) {\
2067 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
2068 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
2069 085339a1 bellard
    b.q[0] = test_values[2*i+1][0];\
2070 085339a1 bellard
    b.q[1] = test_values[2*i+1][1];\
2071 085339a1 bellard
    SSE_OP(op);\
2072 085339a1 bellard
    }\
2073 085339a1 bellard
}
2074 085339a1 bellard
2075 085339a1 bellard
#define MMX_OP2(op)\
2076 085339a1 bellard
{\
2077 085339a1 bellard
    int i;\
2078 085339a1 bellard
    for(i=0;i<2;i++) {\
2079 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
2080 085339a1 bellard
    b.q[0] = test_values[2*i+1][0];\
2081 085339a1 bellard
    asm volatile (#op " %2, %0" : "=y" (r.q[0]) : "0" (a.q[0]), "y" (b.q[0]));\
2082 776f2227 bellard
    printf("%-9s: a=" FMT64X " b=" FMT64X " r=" FMT64X "\n",\
2083 085339a1 bellard
           #op,\
2084 085339a1 bellard
           a.q[0],\
2085 085339a1 bellard
           b.q[0],\
2086 085339a1 bellard
           r.q[0]);\
2087 085339a1 bellard
    }\
2088 085339a1 bellard
    SSE_OP2(op);\
2089 085339a1 bellard
}
2090 085339a1 bellard
2091 97ed14ae bellard
#define SHUF_OP(op, ib)\
2092 97ed14ae bellard
{\
2093 97ed14ae bellard
    a.q[0] = test_values[0][0];\
2094 97ed14ae bellard
    a.q[1] = test_values[0][1];\
2095 97ed14ae bellard
    b.q[0] = test_values[1][0];\
2096 97ed14ae bellard
    b.q[1] = test_values[1][1];\
2097 97ed14ae bellard
    asm volatile (#op " $" #ib ", %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
2098 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\
2099 97ed14ae bellard
           #op,\
2100 97ed14ae bellard
           a.q[1], a.q[0],\
2101 97ed14ae bellard
           b.q[1], b.q[0],\
2102 97ed14ae bellard
           ib,\
2103 97ed14ae bellard
           r.q[1], r.q[0]);\
2104 97ed14ae bellard
}
2105 97ed14ae bellard
2106 085339a1 bellard
#define PSHUF_OP(op, ib)\
2107 085339a1 bellard
{\
2108 085339a1 bellard
    int i;\
2109 085339a1 bellard
    for(i=0;i<2;i++) {\
2110 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
2111 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
2112 085339a1 bellard
    asm volatile (#op " $" #ib ", %1, %0" : "=x" (r.dq) : "x" (a.dq));\
2113 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\
2114 085339a1 bellard
           #op,\
2115 085339a1 bellard
           a.q[1], a.q[0],\
2116 085339a1 bellard
           ib,\
2117 085339a1 bellard
           r.q[1], r.q[0]);\
2118 085339a1 bellard
    }\
2119 085339a1 bellard
}
2120 085339a1 bellard
2121 085339a1 bellard
#define SHIFT_IM(op, ib)\
2122 085339a1 bellard
{\
2123 085339a1 bellard
    int i;\
2124 085339a1 bellard
    for(i=0;i<2;i++) {\
2125 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
2126 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
2127 085339a1 bellard
    asm volatile (#op " $" #ib ", %0" : "=x" (r.dq) : "0" (a.dq));\
2128 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\
2129 085339a1 bellard
           #op,\
2130 085339a1 bellard
           a.q[1], a.q[0],\
2131 085339a1 bellard
           ib,\
2132 085339a1 bellard
           r.q[1], r.q[0]);\
2133 085339a1 bellard
    }\
2134 085339a1 bellard
}
2135 085339a1 bellard
2136 085339a1 bellard
#define SHIFT_OP(op, ib)\
2137 085339a1 bellard
{\
2138 085339a1 bellard
    int i;\
2139 085339a1 bellard
    SHIFT_IM(op, ib);\
2140 085339a1 bellard
    for(i=0;i<2;i++) {\
2141 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
2142 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
2143 085339a1 bellard
    b.q[0] = ib;\
2144 085339a1 bellard
    b.q[1] = 0;\
2145 085339a1 bellard
    asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
2146 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\
2147 085339a1 bellard
           #op,\
2148 085339a1 bellard
           a.q[1], a.q[0],\
2149 085339a1 bellard
           b.q[1], b.q[0],\
2150 085339a1 bellard
           r.q[1], r.q[0]);\
2151 085339a1 bellard
    }\
2152 085339a1 bellard
}
2153 085339a1 bellard
2154 085339a1 bellard
#define MOVMSK(op)\
2155 085339a1 bellard
{\
2156 085339a1 bellard
    int i, reg;\
2157 085339a1 bellard
    for(i=0;i<2;i++) {\
2158 085339a1 bellard
    a.q[0] = test_values[2*i][0];\
2159 085339a1 bellard
    a.q[1] = test_values[2*i][1];\
2160 085339a1 bellard
    asm volatile (#op " %1, %0" : "=r" (reg) : "x" (a.dq));\
2161 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\
2162 085339a1 bellard
           #op,\
2163 085339a1 bellard
           a.q[1], a.q[0],\
2164 085339a1 bellard
           reg);\
2165 085339a1 bellard
    }\
2166 085339a1 bellard
}
2167 085339a1 bellard
2168 085339a1 bellard
#define SSE_OPS(a) \
2169 085339a1 bellard
SSE_OP(a ## ps);\
2170 085339a1 bellard
SSE_OP(a ## ss);
2171 085339a1 bellard
2172 085339a1 bellard
#define SSE_OPD(a) \
2173 085339a1 bellard
SSE_OP(a ## pd);\
2174 085339a1 bellard
SSE_OP(a ## sd);
2175 085339a1 bellard
2176 085339a1 bellard
#define SSE_COMI(op, field)\
2177 085339a1 bellard
{\
2178 085339a1 bellard
    unsigned int eflags;\
2179 085339a1 bellard
    XMMReg a, b;\
2180 085339a1 bellard
    a.field[0] = a1;\
2181 085339a1 bellard
    b.field[0] = b1;\
2182 085339a1 bellard
    asm volatile (#op " %2, %1\n"\
2183 085339a1 bellard
        "pushf\n"\
2184 085339a1 bellard
        "pop %0\n"\
2185 085339a1 bellard
        : "=m" (eflags)\
2186 085339a1 bellard
        : "x" (a.dq), "x" (b.dq));\
2187 085339a1 bellard
    printf("%-9s: a=%f b=%f cc=%04x\n",\
2188 085339a1 bellard
           #op, a1, b1,\
2189 085339a1 bellard
           eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\
2190 085339a1 bellard
}
2191 085339a1 bellard
2192 085339a1 bellard
void test_sse_comi(double a1, double b1)
2193 085339a1 bellard
{
2194 085339a1 bellard
    SSE_COMI(ucomiss, s);
2195 085339a1 bellard
    SSE_COMI(ucomisd, d);
2196 085339a1 bellard
    SSE_COMI(comiss, s);
2197 085339a1 bellard
    SSE_COMI(comisd, d);
2198 085339a1 bellard
}
2199 085339a1 bellard
2200 085339a1 bellard
#define CVT_OP_XMM(op)\
2201 085339a1 bellard
{\
2202 085339a1 bellard
    asm volatile (#op " %1, %0" : "=x" (r.dq) : "x" (a.dq));\
2203 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\
2204 085339a1 bellard
           #op,\
2205 085339a1 bellard
           a.q[1], a.q[0],\
2206 085339a1 bellard
           r.q[1], r.q[0]);\
2207 085339a1 bellard
}
2208 085339a1 bellard
2209 80e7d521 bellard
/* Force %xmm0 usage to avoid the case where both register index are 0
2210 80e7d521 bellard
   to test intruction decoding more extensively */
2211 085339a1 bellard
#define CVT_OP_XMM2MMX(op)\
2212 085339a1 bellard
{\
2213 80e7d521 bellard
    asm volatile (#op " %1, %0" : "=y" (r.q[0]) : "x" (a.dq) \
2214 80e7d521 bellard
                  : "%xmm0");\
2215 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "\n",\
2216 085339a1 bellard
           #op,\
2217 085339a1 bellard
           a.q[1], a.q[0],\
2218 085339a1 bellard
           r.q[0]);\
2219 085339a1 bellard
}
2220 085339a1 bellard
2221 085339a1 bellard
#define CVT_OP_MMX2XMM(op)\
2222 085339a1 bellard
{\
2223 085339a1 bellard
    asm volatile (#op " %1, %0" : "=x" (r.dq) : "y" (a.q[0]));\
2224 776f2227 bellard
    printf("%-9s: a=" FMT64X " r=" FMT64X "" FMT64X "\n",\
2225 085339a1 bellard
           #op,\
2226 085339a1 bellard
           a.q[0],\
2227 085339a1 bellard
           r.q[1], r.q[0]);\
2228 085339a1 bellard
}
2229 085339a1 bellard
2230 085339a1 bellard
#define CVT_OP_REG2XMM(op)\
2231 085339a1 bellard
{\
2232 085339a1 bellard
    asm volatile (#op " %1, %0" : "=x" (r.dq) : "r" (a.l[0]));\
2233 776f2227 bellard
    printf("%-9s: a=%08x r=" FMT64X "" FMT64X "\n",\
2234 085339a1 bellard
           #op,\
2235 085339a1 bellard
           a.l[0],\
2236 085339a1 bellard
           r.q[1], r.q[0]);\
2237 085339a1 bellard
}
2238 085339a1 bellard
2239 085339a1 bellard
#define CVT_OP_XMM2REG(op)\
2240 085339a1 bellard
{\
2241 085339a1 bellard
    asm volatile (#op " %1, %0" : "=r" (r.l[0]) : "x" (a.dq));\
2242 776f2227 bellard
    printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\
2243 085339a1 bellard
           #op,\
2244 085339a1 bellard
           a.q[1], a.q[0],\
2245 085339a1 bellard
           r.l[0]);\
2246 085339a1 bellard
}
2247 085339a1 bellard
2248 a4682cc2 bellard
struct fpxstate {
2249 a4682cc2 bellard
    uint16_t fpuc;
2250 a4682cc2 bellard
    uint16_t fpus;
2251 a4682cc2 bellard
    uint16_t fptag;
2252 a4682cc2 bellard
    uint16_t fop;
2253 a4682cc2 bellard
    uint32_t fpuip;
2254 a4682cc2 bellard
    uint16_t cs_sel;
2255 a4682cc2 bellard
    uint16_t dummy0;
2256 a4682cc2 bellard
    uint32_t fpudp;
2257 a4682cc2 bellard
    uint16_t ds_sel;
2258 a4682cc2 bellard
    uint16_t dummy1;
2259 a4682cc2 bellard
    uint32_t mxcsr;
2260 a4682cc2 bellard
    uint32_t mxcsr_mask;
2261 a4682cc2 bellard
    uint8_t fpregs1[8 * 16];
2262 a4682cc2 bellard
    uint8_t xmm_regs[8 * 16];
2263 a4682cc2 bellard
    uint8_t dummy2[224];
2264 a4682cc2 bellard
};
2265 a4682cc2 bellard
2266 a4682cc2 bellard
static struct fpxstate fpx_state __attribute__((aligned(16)));
2267 a4682cc2 bellard
static struct fpxstate fpx_state2 __attribute__((aligned(16)));
2268 a4682cc2 bellard
2269 a4682cc2 bellard
void test_fxsave(void)
2270 a4682cc2 bellard
{
2271 a4682cc2 bellard
    struct fpxstate *fp = &fpx_state;
2272 a4682cc2 bellard
    struct fpxstate *fp2 = &fpx_state2;
2273 776f2227 bellard
    int i, nb_xmm;
2274 a4682cc2 bellard
    XMMReg a, b;
2275 a4682cc2 bellard
    a.q[0] = test_values[0][0];
2276 a4682cc2 bellard
    a.q[1] = test_values[0][1];
2277 a4682cc2 bellard
    b.q[0] = test_values[1][0];
2278 a4682cc2 bellard
    b.q[1] = test_values[1][1];
2279 a4682cc2 bellard
2280 a4682cc2 bellard
    asm("movdqa %2, %%xmm0\n"
2281 a4682cc2 bellard
        "movdqa %3, %%xmm7\n"
2282 776f2227 bellard
#if defined(__x86_64__)
2283 776f2227 bellard
        "movdqa %2, %%xmm15\n"
2284 776f2227 bellard
#endif
2285 a4682cc2 bellard
        " fld1\n"
2286 a4682cc2 bellard
        " fldpi\n"
2287 a4682cc2 bellard
        " fldln2\n"
2288 a4682cc2 bellard
        " fxsave %0\n"
2289 a4682cc2 bellard
        " fxrstor %0\n"
2290 a4682cc2 bellard
        " fxsave %1\n"
2291 a4682cc2 bellard
        " fninit\n"
2292 5fafdf24 ths
        : "=m" (*(uint32_t *)fp2), "=m" (*(uint32_t *)fp)
2293 a4682cc2 bellard
        : "m" (a), "m" (b));
2294 a4682cc2 bellard
    printf("fpuc=%04x\n", fp->fpuc);
2295 a4682cc2 bellard
    printf("fpus=%04x\n", fp->fpus);
2296 a4682cc2 bellard
    printf("fptag=%04x\n", fp->fptag);
2297 a4682cc2 bellard
    for(i = 0; i < 3; i++) {
2298 776f2227 bellard
        printf("ST%d: " FMT64X " %04x\n",
2299 5fafdf24 ths
               i,
2300 a4682cc2 bellard
               *(uint64_t *)&fp->fpregs1[i * 16],
2301 a4682cc2 bellard
               *(uint16_t *)&fp->fpregs1[i * 16 + 8]);
2302 a4682cc2 bellard
    }
2303 a4682cc2 bellard
    printf("mxcsr=%08x\n", fp->mxcsr & 0x1f80);
2304 776f2227 bellard
#if defined(__x86_64__)
2305 776f2227 bellard
    nb_xmm = 16;
2306 776f2227 bellard
#else
2307 776f2227 bellard
    nb_xmm = 8;
2308 776f2227 bellard
#endif
2309 776f2227 bellard
    for(i = 0; i < nb_xmm; i++) {
2310 776f2227 bellard
        printf("xmm%d: " FMT64X "" FMT64X "\n",
2311 5fafdf24 ths
               i,
2312 a4682cc2 bellard
               *(uint64_t *)&fp->xmm_regs[i * 16],
2313 a4682cc2 bellard
               *(uint64_t *)&fp->xmm_regs[i * 16 + 8]);
2314 a4682cc2 bellard
    }
2315 a4682cc2 bellard
}
2316 a4682cc2 bellard
2317 085339a1 bellard
void test_sse(void)
2318 085339a1 bellard
{
2319 085339a1 bellard
    XMMReg r, a, b;
2320 86bd2ca5 bellard
    int i;
2321 085339a1 bellard
2322 085339a1 bellard
    MMX_OP2(punpcklbw);
2323 085339a1 bellard
    MMX_OP2(punpcklwd);
2324 085339a1 bellard
    MMX_OP2(punpckldq);
2325 085339a1 bellard
    MMX_OP2(packsswb);
2326 085339a1 bellard
    MMX_OP2(pcmpgtb);
2327 085339a1 bellard
    MMX_OP2(pcmpgtw);
2328 085339a1 bellard
    MMX_OP2(pcmpgtd);
2329 085339a1 bellard
    MMX_OP2(packuswb);
2330 085339a1 bellard
    MMX_OP2(punpckhbw);
2331 085339a1 bellard
    MMX_OP2(punpckhwd);
2332 085339a1 bellard
    MMX_OP2(punpckhdq);
2333 085339a1 bellard
    MMX_OP2(packssdw);
2334 085339a1 bellard
    MMX_OP2(pcmpeqb);
2335 085339a1 bellard
    MMX_OP2(pcmpeqw);
2336 085339a1 bellard
    MMX_OP2(pcmpeqd);
2337 085339a1 bellard
2338 085339a1 bellard
    MMX_OP2(paddq);
2339 085339a1 bellard
    MMX_OP2(pmullw);
2340 085339a1 bellard
    MMX_OP2(psubusb);
2341 085339a1 bellard
    MMX_OP2(psubusw);
2342 085339a1 bellard
    MMX_OP2(pminub);
2343 085339a1 bellard
    MMX_OP2(pand);
2344 085339a1 bellard
    MMX_OP2(paddusb);
2345 085339a1 bellard
    MMX_OP2(paddusw);
2346 085339a1 bellard
    MMX_OP2(pmaxub);
2347 085339a1 bellard
    MMX_OP2(pandn);
2348 085339a1 bellard
2349 085339a1 bellard
    MMX_OP2(pmulhuw);
2350 085339a1 bellard
    MMX_OP2(pmulhw);
2351 3b46e624 ths
2352 085339a1 bellard
    MMX_OP2(psubsb);
2353 085339a1 bellard
    MMX_OP2(psubsw);
2354 085339a1 bellard
    MMX_OP2(pminsw);
2355 085339a1 bellard
    MMX_OP2(por);
2356 085339a1 bellard
    MMX_OP2(paddsb);
2357 085339a1 bellard
    MMX_OP2(paddsw);
2358 085339a1 bellard
    MMX_OP2(pmaxsw);
2359 085339a1 bellard
    MMX_OP2(pxor);
2360 085339a1 bellard
    MMX_OP2(pmuludq);
2361 085339a1 bellard
    MMX_OP2(pmaddwd);
2362 085339a1 bellard
    MMX_OP2(psadbw);
2363 085339a1 bellard
    MMX_OP2(psubb);
2364 085339a1 bellard
    MMX_OP2(psubw);
2365 085339a1 bellard
    MMX_OP2(psubd);
2366 085339a1 bellard
    MMX_OP2(psubq);
2367 085339a1 bellard
    MMX_OP2(paddb);
2368 085339a1 bellard
    MMX_OP2(paddw);
2369 085339a1 bellard
    MMX_OP2(paddd);
2370 085339a1 bellard
2371 085339a1 bellard
    MMX_OP2(pavgb);
2372 085339a1 bellard
    MMX_OP2(pavgw);
2373 085339a1 bellard
2374 085339a1 bellard
    asm volatile ("pinsrw $1, %1, %0" : "=y" (r.q[0]) : "r" (0x12345678));
2375 776f2227 bellard
    printf("%-9s: r=" FMT64X "\n", "pinsrw", r.q[0]);
2376 085339a1 bellard
2377 085339a1 bellard
    asm volatile ("pinsrw $5, %1, %0" : "=x" (r.dq) : "r" (0x12345678));
2378 776f2227 bellard
    printf("%-9s: r=" FMT64X "" FMT64X "\n", "pinsrw", r.q[1], r.q[0]);
2379 085339a1 bellard
2380 085339a1 bellard
    a.q[0] = test_values[0][0];
2381 085339a1 bellard
    a.q[1] = test_values[0][1];
2382 085339a1 bellard
    asm volatile ("pextrw $1, %1, %0" : "=r" (r.l[0]) : "y" (a.q[0]));
2383 085339a1 bellard
    printf("%-9s: r=%08x\n", "pextrw", r.l[0]);
2384 085339a1 bellard
2385 085339a1 bellard
    asm volatile ("pextrw $5, %1, %0" : "=r" (r.l[0]) : "x" (a.dq));
2386 085339a1 bellard
    printf("%-9s: r=%08x\n", "pextrw", r.l[0]);
2387 085339a1 bellard
2388 085339a1 bellard
    asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "y" (a.q[0]));
2389 085339a1 bellard
    printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
2390 3b46e624 ths
2391 085339a1 bellard
    asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "x" (a.dq));
2392 085339a1 bellard
    printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
2393 085339a1 bellard
2394 97ed14ae bellard
    {
2395 97ed14ae bellard
        r.q[0] = -1;
2396 97ed14ae bellard
        r.q[1] = -1;
2397 97ed14ae bellard
2398 97ed14ae bellard
        a.q[0] = test_values[0][0];
2399 97ed14ae bellard
        a.q[1] = test_values[0][1];
2400 97ed14ae bellard
        b.q[0] = test_values[1][0];
2401 97ed14ae bellard
        b.q[1] = test_values[1][1];
2402 5fafdf24 ths
        asm volatile("maskmovq %1, %0" :
2403 97ed14ae bellard
                     : "y" (a.q[0]), "y" (b.q[0]), "D" (&r)
2404 5fafdf24 ths
                     : "memory");
2405 5fafdf24 ths
        printf("%-9s: r=" FMT64X " a=" FMT64X " b=" FMT64X "\n",
2406 5fafdf24 ths
               "maskmov",
2407 5fafdf24 ths
               r.q[0],
2408 5fafdf24 ths
               a.q[0],
2409 97ed14ae bellard
               b.q[0]);
2410 5fafdf24 ths
        asm volatile("maskmovdqu %1, %0" :
2411 97ed14ae bellard
                     : "x" (a.dq), "x" (b.dq), "D" (&r)
2412 5fafdf24 ths
                     : "memory");
2413 5fafdf24 ths
        printf("%-9s: r=" FMT64X "" FMT64X " a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X "\n",
2414 5fafdf24 ths
               "maskmov",
2415 5fafdf24 ths
               r.q[1], r.q[0],
2416 5fafdf24 ths
               a.q[1], a.q[0],
2417 97ed14ae bellard
               b.q[1], b.q[0]);
2418 97ed14ae bellard
    }
2419 97ed14ae bellard
2420 085339a1 bellard
    asm volatile ("emms");
2421 085339a1 bellard
2422 085339a1 bellard
    SSE_OP2(punpcklqdq);
2423 085339a1 bellard
    SSE_OP2(punpckhqdq);
2424 085339a1 bellard
    SSE_OP2(andps);
2425 085339a1 bellard
    SSE_OP2(andpd);
2426 085339a1 bellard
    SSE_OP2(andnps);
2427 085339a1 bellard
    SSE_OP2(andnpd);
2428 085339a1 bellard
    SSE_OP2(orps);
2429 085339a1 bellard
    SSE_OP2(orpd);
2430 085339a1 bellard
    SSE_OP2(xorps);
2431 085339a1 bellard
    SSE_OP2(xorpd);
2432 085339a1 bellard
2433 085339a1 bellard
    SSE_OP2(unpcklps);
2434 085339a1 bellard
    SSE_OP2(unpcklpd);
2435 085339a1 bellard
    SSE_OP2(unpckhps);
2436 085339a1 bellard
    SSE_OP2(unpckhpd);
2437 085339a1 bellard
2438 97ed14ae bellard
    SHUF_OP(shufps, 0x78);
2439 97ed14ae bellard
    SHUF_OP(shufpd, 0x02);
2440 085339a1 bellard
2441 085339a1 bellard
    PSHUF_OP(pshufd, 0x78);
2442 085339a1 bellard
    PSHUF_OP(pshuflw, 0x78);
2443 085339a1 bellard
    PSHUF_OP(pshufhw, 0x78);
2444 085339a1 bellard
2445 085339a1 bellard
    SHIFT_OP(psrlw, 7);
2446 085339a1 bellard
    SHIFT_OP(psrlw, 16);
2447 085339a1 bellard
    SHIFT_OP(psraw, 7);
2448 085339a1 bellard
    SHIFT_OP(psraw, 16);
2449 085339a1 bellard
    SHIFT_OP(psllw, 7);
2450 085339a1 bellard
    SHIFT_OP(psllw, 16);
2451 085339a1 bellard
2452 085339a1 bellard
    SHIFT_OP(psrld, 7);
2453 085339a1 bellard
    SHIFT_OP(psrld, 32);
2454 085339a1 bellard
    SHIFT_OP(psrad, 7);
2455 085339a1 bellard
    SHIFT_OP(psrad, 32);
2456 085339a1 bellard
    SHIFT_OP(pslld, 7);
2457 085339a1 bellard
    SHIFT_OP(pslld, 32);
2458 085339a1 bellard
2459 085339a1 bellard
    SHIFT_OP(psrlq, 7);
2460 085339a1 bellard
    SHIFT_OP(psrlq, 32);
2461 085339a1 bellard
    SHIFT_OP(psllq, 7);
2462 085339a1 bellard
    SHIFT_OP(psllq, 32);
2463 085339a1 bellard
2464 085339a1 bellard
    SHIFT_IM(psrldq, 16);
2465 085339a1 bellard
    SHIFT_IM(psrldq, 7);
2466 085339a1 bellard
    SHIFT_IM(pslldq, 16);
2467 085339a1 bellard
    SHIFT_IM(pslldq, 7);
2468 085339a1 bellard
2469 085339a1 bellard
    MOVMSK(movmskps);
2470 085339a1 bellard
    MOVMSK(movmskpd);
2471 085339a1 bellard
2472 085339a1 bellard
    /* FPU specific ops */
2473 085339a1 bellard
2474 085339a1 bellard
    {
2475 085339a1 bellard
        uint32_t mxcsr;
2476 085339a1 bellard
        asm volatile("stmxcsr %0" : "=m" (mxcsr));
2477 085339a1 bellard
        printf("mxcsr=%08x\n", mxcsr & 0x1f80);
2478 085339a1 bellard
        asm volatile("ldmxcsr %0" : : "m" (mxcsr));
2479 085339a1 bellard
    }
2480 085339a1 bellard
2481 085339a1 bellard
    test_sse_comi(2, -1);
2482 085339a1 bellard
    test_sse_comi(2, 2);
2483 085339a1 bellard
    test_sse_comi(2, 3);
2484 86bd2ca5 bellard
    test_sse_comi(2, q_nan.d);
2485 86bd2ca5 bellard
    test_sse_comi(q_nan.d, -1);
2486 86bd2ca5 bellard
2487 86bd2ca5 bellard
    for(i = 0; i < 2; i++) {
2488 86bd2ca5 bellard
        a.s[0] = 2.7;
2489 86bd2ca5 bellard
        a.s[1] = 3.4;
2490 86bd2ca5 bellard
        a.s[2] = 4;
2491 86bd2ca5 bellard
        a.s[3] = -6.3;
2492 86bd2ca5 bellard
        b.s[0] = 45.7;
2493 86bd2ca5 bellard
        b.s[1] = 353.4;
2494 86bd2ca5 bellard
        b.s[2] = 4;
2495 86bd2ca5 bellard
        b.s[3] = 56.3;
2496 86bd2ca5 bellard
        if (i == 1) {
2497 86bd2ca5 bellard
            a.s[0] = q_nan.d;
2498 86bd2ca5 bellard
            b.s[3] = q_nan.d;
2499 86bd2ca5 bellard
        }
2500 86bd2ca5 bellard
2501 86bd2ca5 bellard
        SSE_OPS(add);
2502 86bd2ca5 bellard
        SSE_OPS(mul);
2503 86bd2ca5 bellard
        SSE_OPS(sub);
2504 86bd2ca5 bellard
        SSE_OPS(min);
2505 86bd2ca5 bellard
        SSE_OPS(div);
2506 86bd2ca5 bellard
        SSE_OPS(max);
2507 86bd2ca5 bellard
        SSE_OPS(sqrt);
2508 86bd2ca5 bellard
        SSE_OPS(cmpeq);
2509 86bd2ca5 bellard
        SSE_OPS(cmplt);
2510 86bd2ca5 bellard
        SSE_OPS(cmple);
2511 86bd2ca5 bellard
        SSE_OPS(cmpunord);
2512 86bd2ca5 bellard
        SSE_OPS(cmpneq);
2513 86bd2ca5 bellard
        SSE_OPS(cmpnlt);
2514 86bd2ca5 bellard
        SSE_OPS(cmpnle);
2515 86bd2ca5 bellard
        SSE_OPS(cmpord);
2516 3b46e624 ths
2517 3b46e624 ths
2518 86bd2ca5 bellard
        a.d[0] = 2.7;
2519 86bd2ca5 bellard
        a.d[1] = -3.4;
2520 86bd2ca5 bellard
        b.d[0] = 45.7;
2521 86bd2ca5 bellard
        b.d[1] = -53.4;
2522 86bd2ca5 bellard
        if (i == 1) {
2523 86bd2ca5 bellard
            a.d[0] = q_nan.d;
2524 86bd2ca5 bellard
            b.d[1] = q_nan.d;
2525 86bd2ca5 bellard
        }
2526 86bd2ca5 bellard
        SSE_OPD(add);
2527 86bd2ca5 bellard
        SSE_OPD(mul);
2528 86bd2ca5 bellard
        SSE_OPD(sub);
2529 86bd2ca5 bellard
        SSE_OPD(min);
2530 86bd2ca5 bellard
        SSE_OPD(div);
2531 86bd2ca5 bellard
        SSE_OPD(max);
2532 86bd2ca5 bellard
        SSE_OPD(sqrt);
2533 86bd2ca5 bellard
        SSE_OPD(cmpeq);
2534 86bd2ca5 bellard
        SSE_OPD(cmplt);
2535 86bd2ca5 bellard
        SSE_OPD(cmple);
2536 86bd2ca5 bellard
        SSE_OPD(cmpunord);
2537 86bd2ca5 bellard
        SSE_OPD(cmpneq);
2538 86bd2ca5 bellard
        SSE_OPD(cmpnlt);
2539 86bd2ca5 bellard
        SSE_OPD(cmpnle);
2540 86bd2ca5 bellard
        SSE_OPD(cmpord);
2541 86bd2ca5 bellard
    }
2542 085339a1 bellard
2543 085339a1 bellard
    /* float to float/int */
2544 085339a1 bellard
    a.s[0] = 2.7;
2545 085339a1 bellard
    a.s[1] = 3.4;
2546 085339a1 bellard
    a.s[2] = 4;
2547 085339a1 bellard
    a.s[3] = -6.3;
2548 085339a1 bellard
    CVT_OP_XMM(cvtps2pd);
2549 085339a1 bellard
    CVT_OP_XMM(cvtss2sd);
2550 085339a1 bellard
    CVT_OP_XMM2MMX(cvtps2pi);
2551 085339a1 bellard
    CVT_OP_XMM2MMX(cvttps2pi);
2552 085339a1 bellard
    CVT_OP_XMM2REG(cvtss2si);
2553 085339a1 bellard
    CVT_OP_XMM2REG(cvttss2si);
2554 085339a1 bellard
    CVT_OP_XMM(cvtps2dq);
2555 085339a1 bellard
    CVT_OP_XMM(cvttps2dq);
2556 085339a1 bellard
2557 085339a1 bellard
    a.d[0] = 2.6;
2558 085339a1 bellard
    a.d[1] = -3.4;
2559 085339a1 bellard
    CVT_OP_XMM(cvtpd2ps);
2560 085339a1 bellard
    CVT_OP_XMM(cvtsd2ss);
2561 085339a1 bellard
    CVT_OP_XMM2MMX(cvtpd2pi);
2562 085339a1 bellard
    CVT_OP_XMM2MMX(cvttpd2pi);
2563 085339a1 bellard
    CVT_OP_XMM2REG(cvtsd2si);
2564 085339a1 bellard
    CVT_OP_XMM2REG(cvttsd2si);
2565 085339a1 bellard
    CVT_OP_XMM(cvtpd2dq);
2566 085339a1 bellard
    CVT_OP_XMM(cvttpd2dq);
2567 085339a1 bellard
2568 80e7d521 bellard
    /* sse/mmx moves */
2569 80e7d521 bellard
    CVT_OP_XMM2MMX(movdq2q);
2570 80e7d521 bellard
    CVT_OP_MMX2XMM(movq2dq);
2571 80e7d521 bellard
2572 085339a1 bellard
    /* int to float */
2573 085339a1 bellard
    a.l[0] = -6;
2574 085339a1 bellard
    a.l[1] = 2;
2575 085339a1 bellard
    a.l[2] = 100;
2576 085339a1 bellard
    a.l[3] = -60000;
2577 085339a1 bellard
    CVT_OP_MMX2XMM(cvtpi2ps);
2578 085339a1 bellard
    CVT_OP_MMX2XMM(cvtpi2pd);
2579 085339a1 bellard
    CVT_OP_REG2XMM(cvtsi2ss);
2580 085339a1 bellard
    CVT_OP_REG2XMM(cvtsi2sd);
2581 085339a1 bellard
    CVT_OP_XMM(cvtdq2ps);
2582 085339a1 bellard
    CVT_OP_XMM(cvtdq2pd);
2583 085339a1 bellard
2584 085339a1 bellard
    /* XXX: test PNI insns */
2585 085339a1 bellard
#if 0
2586 085339a1 bellard
    SSE_OP2(movshdup);
2587 085339a1 bellard
#endif
2588 a4682cc2 bellard
    asm volatile ("emms");
2589 085339a1 bellard
}
2590 085339a1 bellard
2591 085339a1 bellard
#endif
2592 085339a1 bellard
2593 df517cec bellard
#define TEST_CONV_RAX(op)\
2594 df517cec bellard
{\
2595 df517cec bellard
    unsigned long a, r;\
2596 df517cec bellard
    a = i2l(0x8234a6f8);\
2597 df517cec bellard
    r = a;\
2598 df517cec bellard
    asm volatile(#op : "=a" (r) : "0" (r));\
2599 df517cec bellard
    printf("%-10s A=" FMTLX " R=" FMTLX "\n", #op, a, r);\
2600 df517cec bellard
}
2601 df517cec bellard
2602 df517cec bellard
#define TEST_CONV_RAX_RDX(op)\
2603 df517cec bellard
{\
2604 df517cec bellard
    unsigned long a, d, r, rh;                   \
2605 df517cec bellard
    a = i2l(0x8234a6f8);\
2606 df517cec bellard
    d = i2l(0x8345a1f2);\
2607 df517cec bellard
    r = a;\
2608 df517cec bellard
    rh = d;\
2609 df517cec bellard
    asm volatile(#op : "=a" (r), "=d" (rh) : "0" (r), "1" (rh));   \
2610 df517cec bellard
    printf("%-10s A=" FMTLX " R=" FMTLX ":" FMTLX "\n", #op, a, r, rh);  \
2611 df517cec bellard
}
2612 df517cec bellard
2613 df517cec bellard
void test_conv(void)
2614 df517cec bellard
{
2615 df517cec bellard
    TEST_CONV_RAX(cbw);
2616 df517cec bellard
    TEST_CONV_RAX(cwde);
2617 df517cec bellard
#if defined(__x86_64__)
2618 df517cec bellard
    TEST_CONV_RAX(cdqe);
2619 df517cec bellard
#endif
2620 df517cec bellard
2621 df517cec bellard
    TEST_CONV_RAX_RDX(cwd);
2622 df517cec bellard
    TEST_CONV_RAX_RDX(cdq);
2623 df517cec bellard
#if defined(__x86_64__)
2624 df517cec bellard
    TEST_CONV_RAX_RDX(cqo);
2625 df517cec bellard
#endif
2626 8aadfbf0 bellard
2627 8aadfbf0 bellard
    {
2628 8aadfbf0 bellard
        unsigned long a, r;
2629 8aadfbf0 bellard
        a = i2l(0x12345678);
2630 8aadfbf0 bellard
        asm volatile("bswapl %k0" : "=r" (r) : "0" (a));
2631 8aadfbf0 bellard
        printf("%-10s: A=" FMTLX " R=" FMTLX "\n", "bswapl", a, r);
2632 8aadfbf0 bellard
    }
2633 8aadfbf0 bellard
#if defined(__x86_64__)
2634 8aadfbf0 bellard
    {
2635 8aadfbf0 bellard
        unsigned long a, r;
2636 8aadfbf0 bellard
        a = i2l(0x12345678);
2637 8aadfbf0 bellard
        asm volatile("bswapq %0" : "=r" (r) : "0" (a));
2638 8aadfbf0 bellard
        printf("%-10s: A=" FMTLX " R=" FMTLX "\n", "bswapq", a, r);
2639 8aadfbf0 bellard
    }
2640 8aadfbf0 bellard
#endif
2641 df517cec bellard
}
2642 df517cec bellard
2643 776f2227 bellard
extern void *__start_initcall;
2644 776f2227 bellard
extern void *__stop_initcall;
2645 776f2227 bellard
2646 4d1135e4 bellard
2647 4d1135e4 bellard
int main(int argc, char **argv)
2648 4d1135e4 bellard
{
2649 4d1135e4 bellard
    void **ptr;
2650 4d1135e4 bellard
    void (*func)(void);
2651 4b74fe1f bellard
2652 776f2227 bellard
    ptr = &__start_initcall;
2653 776f2227 bellard
    while (ptr != &__stop_initcall) {
2654 4d1135e4 bellard
        func = *ptr++;
2655 4d1135e4 bellard
        func();
2656 4d1135e4 bellard
    }
2657 9d8e9c09 bellard
    test_bsx();
2658 d57c4e01 bellard
    test_mul();
2659 4d1135e4 bellard
    test_jcc();
2660 9d8e9c09 bellard
    test_floats();
2661 776f2227 bellard
#if !defined(__x86_64__)
2662 55480af8 bellard
    test_bcd();
2663 776f2227 bellard
#endif
2664 1a9353d2 bellard
    test_xchg();
2665 e1d4294a bellard
    test_string();
2666 e1d4294a bellard
    test_misc();
2667 6dbad63e bellard
    test_lea();
2668 776f2227 bellard
#ifdef TEST_SEGS
2669 6dbad63e bellard
    test_segs();
2670 e5918247 bellard
    test_code16();
2671 776f2227 bellard
#endif
2672 acae4681 bellard
#ifdef TEST_VM86
2673 3a27ad0b bellard
    test_vm86();
2674 acae4681 bellard
#endif
2675 776f2227 bellard
#if !defined(__x86_64__)
2676 8aadfbf0 bellard
    test_exceptions();
2677 3a27ad0b bellard
    test_self_modifying_code();
2678 3ff0631e bellard
    test_single_step();
2679 776f2227 bellard
#endif
2680 61a8c4ec bellard
    test_enter();
2681 df517cec bellard
    test_conv();
2682 085339a1 bellard
#ifdef TEST_SSE
2683 085339a1 bellard
    test_sse();
2684 a4682cc2 bellard
    test_fxsave();
2685 085339a1 bellard
#endif
2686 4d1135e4 bellard
    return 0;
2687 4d1135e4 bellard
}