Statistics
| Branch: | Revision:

root / tests / tcg / test-i386.c @ 49cdaea1

History | View | Annotate | Download (70.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 8167ee88 Blue Swirl
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18 78d6da97 bellard
 */
19 3a27ad0b bellard
#define _GNU_SOURCE
20 f62cb1b6 Catalin Patulea
#include "compiler.h"
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 a5973fbf 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 a5973fbf bellard
#ifdef __SSE__
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 a5973fbf bellard
#undef TEST_SSE
44 a5973fbf bellard
#define TEST_CMOV  1
45 a5973fbf bellard
#define TEST_FCOMI 1
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 a5973fbf bellard
#define TEST_LOOP(insn) \
461 a5973fbf bellard
{\
462 a5973fbf bellard
    for(i = 0; i < sizeof(ecx_vals) / sizeof(long); i++) {\
463 a5973fbf bellard
        ecx = ecx_vals[i];\
464 a5973fbf bellard
        for(zf = 0; zf < 2; zf++) {\
465 a5973fbf bellard
    asm("test %2, %2\n\t"\
466 a5973fbf bellard
        "movl $1, %0\n\t"\
467 a5973fbf bellard
          insn " 1f\n\t" \
468 a5973fbf bellard
        "movl $0, %0\n\t"\
469 a5973fbf bellard
        "1:\n\t"\
470 a5973fbf bellard
        : "=a" (res)\
471 a5973fbf bellard
        : "c" (ecx), "b" (!zf)); \
472 a5973fbf bellard
    printf("%-10s ECX=" FMTLX " ZF=%ld r=%d\n", insn, ecx, zf, res);      \
473 a5973fbf bellard
        }\
474 a5973fbf bellard
   }\
475 a5973fbf bellard
}
476 a5973fbf bellard
477 a5973fbf bellard
void test_loop(void)
478 a5973fbf bellard
{
479 a5973fbf bellard
    long ecx, zf;
480 a5973fbf bellard
    const long ecx_vals[] = {
481 a5973fbf bellard
        0,
482 a5973fbf bellard
        1,
483 a5973fbf bellard
        0x10000,
484 a5973fbf bellard
        0x10001,
485 a5973fbf bellard
#if defined(__x86_64__)
486 a5973fbf bellard
        0x100000000L,
487 a5973fbf bellard
        0x100000001L,
488 a5973fbf bellard
#endif
489 a5973fbf bellard
    };
490 a5973fbf bellard
    int i, res;
491 a5973fbf bellard
492 872ea0c0 balrog
#if !defined(__x86_64__)
493 a5973fbf bellard
    TEST_LOOP("jcxz");
494 a5973fbf bellard
    TEST_LOOP("loopw");
495 a5973fbf bellard
    TEST_LOOP("loopzw");
496 a5973fbf bellard
    TEST_LOOP("loopnzw");
497 872ea0c0 balrog
#endif
498 a5973fbf bellard
499 a5973fbf bellard
    TEST_LOOP("jecxz");
500 a5973fbf bellard
    TEST_LOOP("loopl");
501 a5973fbf bellard
    TEST_LOOP("loopzl");
502 a5973fbf bellard
    TEST_LOOP("loopnzl");
503 a5973fbf bellard
}
504 a5973fbf bellard
505 4b74fe1f bellard
#undef CC_MASK
506 791c2261 bellard
#ifdef TEST_P4_FLAGS
507 791c2261 bellard
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
508 791c2261 bellard
#else
509 4b74fe1f bellard
#define CC_MASK (CC_O | CC_C)
510 791c2261 bellard
#endif
511 4b74fe1f bellard
512 4b74fe1f bellard
#define OP mul
513 4b74fe1f bellard
#include "test-i386-muldiv.h"
514 4b74fe1f bellard
515 4b74fe1f bellard
#define OP imul
516 4b74fe1f bellard
#include "test-i386-muldiv.h"
517 4b74fe1f bellard
518 5fafdf24 ths
void test_imulw2(long op0, long op1)
519 4b74fe1f bellard
{
520 776f2227 bellard
    long res, s1, s0, flags;
521 4b74fe1f bellard
    s0 = op0;
522 4b74fe1f bellard
    s1 = op1;
523 4b74fe1f bellard
    res = s0;
524 4b74fe1f bellard
    flags = 0;
525 acae4681 bellard
    asm volatile ("push %4\n\t"
526 4b74fe1f bellard
         "popf\n\t"
527 5fafdf24 ths
         "imulw %w2, %w0\n\t"
528 4b74fe1f bellard
         "pushf\n\t"
529 776f2227 bellard
         "pop %1\n\t"
530 4b74fe1f bellard
         : "=q" (res), "=g" (flags)
531 4b74fe1f bellard
         : "q" (s1), "0" (res), "1" (flags));
532 776f2227 bellard
    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
533 4b74fe1f bellard
           "imulw", s0, s1, res, flags & CC_MASK);
534 4b74fe1f bellard
}
535 4b74fe1f bellard
536 5fafdf24 ths
void test_imull2(long op0, long op1)
537 4b74fe1f bellard
{
538 776f2227 bellard
    long res, s1, s0, flags;
539 4b74fe1f bellard
    s0 = op0;
540 4b74fe1f bellard
    s1 = op1;
541 4b74fe1f bellard
    res = s0;
542 4b74fe1f bellard
    flags = 0;
543 acae4681 bellard
    asm volatile ("push %4\n\t"
544 4b74fe1f bellard
         "popf\n\t"
545 5fafdf24 ths
         "imull %k2, %k0\n\t"
546 4b74fe1f bellard
         "pushf\n\t"
547 776f2227 bellard
         "pop %1\n\t"
548 4b74fe1f bellard
         : "=q" (res), "=g" (flags)
549 4b74fe1f bellard
         : "q" (s1), "0" (res), "1" (flags));
550 776f2227 bellard
    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
551 4b74fe1f bellard
           "imull", s0, s1, res, flags & CC_MASK);
552 4b74fe1f bellard
}
553 4b74fe1f bellard
554 776f2227 bellard
#if defined(__x86_64__)
555 5fafdf24 ths
void test_imulq2(long op0, long op1)
556 776f2227 bellard
{
557 776f2227 bellard
    long res, s1, s0, flags;
558 776f2227 bellard
    s0 = op0;
559 776f2227 bellard
    s1 = op1;
560 776f2227 bellard
    res = s0;
561 776f2227 bellard
    flags = 0;
562 776f2227 bellard
    asm volatile ("push %4\n\t"
563 776f2227 bellard
         "popf\n\t"
564 5fafdf24 ths
         "imulq %2, %0\n\t"
565 776f2227 bellard
         "pushf\n\t"
566 776f2227 bellard
         "pop %1\n\t"
567 776f2227 bellard
         : "=q" (res), "=g" (flags)
568 776f2227 bellard
         : "q" (s1), "0" (res), "1" (flags));
569 776f2227 bellard
    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
570 776f2227 bellard
           "imulq", s0, s1, res, flags & CC_MASK);
571 776f2227 bellard
}
572 776f2227 bellard
#endif
573 776f2227 bellard
574 776f2227 bellard
#define TEST_IMUL_IM(size, rsize, op0, op1)\
575 b5075d29 bellard
{\
576 776f2227 bellard
    long res, flags, s1;\
577 b5075d29 bellard
    flags = 0;\
578 b5075d29 bellard
    res = 0;\
579 776f2227 bellard
    s1 = op1;\
580 acae4681 bellard
    asm volatile ("push %3\n\t"\
581 b5075d29 bellard
         "popf\n\t"\
582 776f2227 bellard
         "imul" size " $" #op0 ", %" rsize "2, %" rsize "0\n\t" \
583 b5075d29 bellard
         "pushf\n\t"\
584 776f2227 bellard
         "pop %1\n\t"\
585 b5075d29 bellard
         : "=r" (res), "=g" (flags)\
586 776f2227 bellard
         : "r" (s1), "1" (flags), "0" (res));\
587 776f2227 bellard
    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",\
588 776f2227 bellard
           "imul" size " im", (long)op0, (long)op1, res, flags & CC_MASK);\
589 b5075d29 bellard
}
590 b5075d29 bellard
591 b5075d29 bellard
592 791c2261 bellard
#undef CC_MASK
593 791c2261 bellard
#define CC_MASK (0)
594 791c2261 bellard
595 791c2261 bellard
#define OP div
596 791c2261 bellard
#include "test-i386-muldiv.h"
597 791c2261 bellard
598 791c2261 bellard
#define OP idiv
599 791c2261 bellard
#include "test-i386-muldiv.h"
600 791c2261 bellard
601 4b74fe1f bellard
void test_mul(void)
602 4b74fe1f bellard
{
603 4b74fe1f bellard
    test_imulb(0x1234561d, 4);
604 4b74fe1f bellard
    test_imulb(3, -4);
605 4b74fe1f bellard
    test_imulb(0x80, 0x80);
606 4b74fe1f bellard
    test_imulb(0x10, 0x10);
607 4b74fe1f bellard
608 4b74fe1f bellard
    test_imulw(0, 0x1234001d, 45);
609 4b74fe1f bellard
    test_imulw(0, 23, -45);
610 4b74fe1f bellard
    test_imulw(0, 0x8000, 0x8000);
611 4b74fe1f bellard
    test_imulw(0, 0x100, 0x100);
612 4b74fe1f bellard
613 4b74fe1f bellard
    test_imull(0, 0x1234001d, 45);
614 4b74fe1f bellard
    test_imull(0, 23, -45);
615 4b74fe1f bellard
    test_imull(0, 0x80000000, 0x80000000);
616 4b74fe1f bellard
    test_imull(0, 0x10000, 0x10000);
617 4b74fe1f bellard
618 4b74fe1f bellard
    test_mulb(0x1234561d, 4);
619 4b74fe1f bellard
    test_mulb(3, -4);
620 4b74fe1f bellard
    test_mulb(0x80, 0x80);
621 4b74fe1f bellard
    test_mulb(0x10, 0x10);
622 4b74fe1f bellard
623 4b74fe1f bellard
    test_mulw(0, 0x1234001d, 45);
624 4b74fe1f bellard
    test_mulw(0, 23, -45);
625 4b74fe1f bellard
    test_mulw(0, 0x8000, 0x8000);
626 4b74fe1f bellard
    test_mulw(0, 0x100, 0x100);
627 4b74fe1f bellard
628 4b74fe1f bellard
    test_mull(0, 0x1234001d, 45);
629 4b74fe1f bellard
    test_mull(0, 23, -45);
630 4b74fe1f bellard
    test_mull(0, 0x80000000, 0x80000000);
631 4b74fe1f bellard
    test_mull(0, 0x10000, 0x10000);
632 4b74fe1f bellard
633 4b74fe1f bellard
    test_imulw2(0x1234001d, 45);
634 4b74fe1f bellard
    test_imulw2(23, -45);
635 4b74fe1f bellard
    test_imulw2(0x8000, 0x8000);
636 4b74fe1f bellard
    test_imulw2(0x100, 0x100);
637 4b74fe1f bellard
638 4b74fe1f bellard
    test_imull2(0x1234001d, 45);
639 4b74fe1f bellard
    test_imull2(23, -45);
640 4b74fe1f bellard
    test_imull2(0x80000000, 0x80000000);
641 4b74fe1f bellard
    test_imull2(0x10000, 0x10000);
642 4b74fe1f bellard
643 b5075d29 bellard
    TEST_IMUL_IM("w", "w", 45, 0x1234);
644 b5075d29 bellard
    TEST_IMUL_IM("w", "w", -45, 23);
645 b5075d29 bellard
    TEST_IMUL_IM("w", "w", 0x8000, 0x80000000);
646 b5075d29 bellard
    TEST_IMUL_IM("w", "w", 0x7fff, 0x1000);
647 b5075d29 bellard
648 776f2227 bellard
    TEST_IMUL_IM("l", "k", 45, 0x1234);
649 776f2227 bellard
    TEST_IMUL_IM("l", "k", -45, 23);
650 776f2227 bellard
    TEST_IMUL_IM("l", "k", 0x8000, 0x80000000);
651 776f2227 bellard
    TEST_IMUL_IM("l", "k", 0x7fff, 0x1000);
652 b5075d29 bellard
653 4b74fe1f bellard
    test_idivb(0x12341678, 0x127e);
654 4b74fe1f bellard
    test_idivb(0x43210123, -5);
655 4b74fe1f bellard
    test_idivb(0x12340004, -1);
656 4b74fe1f bellard
657 4b74fe1f bellard
    test_idivw(0, 0x12345678, 12347);
658 4b74fe1f bellard
    test_idivw(0, -23223, -45);
659 4b74fe1f bellard
    test_idivw(0, 0x12348000, -1);
660 4b74fe1f bellard
    test_idivw(0x12343, 0x12345678, 0x81238567);
661 4b74fe1f bellard
662 4b74fe1f bellard
    test_idivl(0, 0x12345678, 12347);
663 4b74fe1f bellard
    test_idivl(0, -233223, -45);
664 4b74fe1f bellard
    test_idivl(0, 0x80000000, -1);
665 4b74fe1f bellard
    test_idivl(0x12343, 0x12345678, 0x81234567);
666 4b74fe1f bellard
667 4b74fe1f bellard
    test_divb(0x12341678, 0x127e);
668 4b74fe1f bellard
    test_divb(0x43210123, -5);
669 4b74fe1f bellard
    test_divb(0x12340004, -1);
670 4b74fe1f bellard
671 4b74fe1f bellard
    test_divw(0, 0x12345678, 12347);
672 4b74fe1f bellard
    test_divw(0, -23223, -45);
673 4b74fe1f bellard
    test_divw(0, 0x12348000, -1);
674 4b74fe1f bellard
    test_divw(0x12343, 0x12345678, 0x81238567);
675 4b74fe1f bellard
676 4b74fe1f bellard
    test_divl(0, 0x12345678, 12347);
677 4b74fe1f bellard
    test_divl(0, -233223, -45);
678 4b74fe1f bellard
    test_divl(0, 0x80000000, -1);
679 4b74fe1f bellard
    test_divl(0x12343, 0x12345678, 0x81234567);
680 776f2227 bellard
681 776f2227 bellard
#if defined(__x86_64__)
682 776f2227 bellard
    test_imulq(0, 0x1234001d1234001d, 45);
683 776f2227 bellard
    test_imulq(0, 23, -45);
684 776f2227 bellard
    test_imulq(0, 0x8000000000000000, 0x8000000000000000);
685 776f2227 bellard
    test_imulq(0, 0x100000000, 0x100000000);
686 776f2227 bellard
687 776f2227 bellard
    test_mulq(0, 0x1234001d1234001d, 45);
688 776f2227 bellard
    test_mulq(0, 23, -45);
689 776f2227 bellard
    test_mulq(0, 0x8000000000000000, 0x8000000000000000);
690 776f2227 bellard
    test_mulq(0, 0x100000000, 0x100000000);
691 776f2227 bellard
692 776f2227 bellard
    test_imulq2(0x1234001d1234001d, 45);
693 776f2227 bellard
    test_imulq2(23, -45);
694 776f2227 bellard
    test_imulq2(0x8000000000000000, 0x8000000000000000);
695 776f2227 bellard
    test_imulq2(0x100000000, 0x100000000);
696 776f2227 bellard
697 776f2227 bellard
    TEST_IMUL_IM("q", "", 45, 0x12341234);
698 776f2227 bellard
    TEST_IMUL_IM("q", "", -45, 23);
699 776f2227 bellard
    TEST_IMUL_IM("q", "", 0x8000, 0x8000000000000000);
700 776f2227 bellard
    TEST_IMUL_IM("q", "", 0x7fff, 0x10000000);
701 776f2227 bellard
702 776f2227 bellard
    test_idivq(0, 0x12345678abcdef, 12347);
703 776f2227 bellard
    test_idivq(0, -233223, -45);
704 776f2227 bellard
    test_idivq(0, 0x8000000000000000, -1);
705 776f2227 bellard
    test_idivq(0x12343, 0x12345678, 0x81234567);
706 776f2227 bellard
707 776f2227 bellard
    test_divq(0, 0x12345678abcdef, 12347);
708 776f2227 bellard
    test_divq(0, -233223, -45);
709 776f2227 bellard
    test_divq(0, 0x8000000000000000, -1);
710 776f2227 bellard
    test_divq(0x12343, 0x12345678, 0x81234567);
711 776f2227 bellard
#endif
712 4b74fe1f bellard
}
713 4b74fe1f bellard
714 9d8e9c09 bellard
#define TEST_BSX(op, size, op0)\
715 9d8e9c09 bellard
{\
716 776f2227 bellard
    long res, val, resz;\
717 9d8e9c09 bellard
    val = op0;\
718 776f2227 bellard
    asm("xor %1, %1\n"\
719 776f2227 bellard
        "mov $0x12345678, %0\n"\
720 7f5e1452 bellard
        #op " %" size "2, %" size "0 ; setz %b1" \
721 7058bfa6 balrog
        : "=&r" (res), "=&q" (resz)\
722 7058bfa6 balrog
        : "r" (val));\
723 776f2227 bellard
    printf("%-10s A=" FMTLX " R=" FMTLX " %ld\n", #op, val, res, resz);\
724 9d8e9c09 bellard
}
725 9d8e9c09 bellard
726 9d8e9c09 bellard
void test_bsx(void)
727 9d8e9c09 bellard
{
728 9d8e9c09 bellard
    TEST_BSX(bsrw, "w", 0);
729 9d8e9c09 bellard
    TEST_BSX(bsrw, "w", 0x12340128);
730 9d8e9c09 bellard
    TEST_BSX(bsfw, "w", 0);
731 9d8e9c09 bellard
    TEST_BSX(bsfw, "w", 0x12340128);
732 776f2227 bellard
    TEST_BSX(bsrl, "k", 0);
733 776f2227 bellard
    TEST_BSX(bsrl, "k", 0x00340128);
734 776f2227 bellard
    TEST_BSX(bsfl, "k", 0);
735 776f2227 bellard
    TEST_BSX(bsfl, "k", 0x00340128);
736 776f2227 bellard
#if defined(__x86_64__)
737 776f2227 bellard
    TEST_BSX(bsrq, "", 0);
738 776f2227 bellard
    TEST_BSX(bsrq, "", 0x003401281234);
739 776f2227 bellard
    TEST_BSX(bsfq, "", 0);
740 776f2227 bellard
    TEST_BSX(bsfq, "", 0x003401281234);
741 776f2227 bellard
#endif
742 9d8e9c09 bellard
}
743 9d8e9c09 bellard
744 55480af8 bellard
/**********************************************/
745 55480af8 bellard
746 86bd2ca5 bellard
union float64u {
747 86bd2ca5 bellard
    double d;
748 86bd2ca5 bellard
    uint64_t l;
749 86bd2ca5 bellard
};
750 86bd2ca5 bellard
751 be98f1f8 bellard
union float64u q_nan = { .l = 0xFFF8000000000000LL };
752 be98f1f8 bellard
union float64u s_nan = { .l = 0xFFF0000000000000LL };
753 86bd2ca5 bellard
754 9d8e9c09 bellard
void test_fops(double a, double b)
755 9d8e9c09 bellard
{
756 9d8e9c09 bellard
    printf("a=%f b=%f a+b=%f\n", a, b, a + b);
757 9d8e9c09 bellard
    printf("a=%f b=%f a-b=%f\n", a, b, a - b);
758 9d8e9c09 bellard
    printf("a=%f b=%f a*b=%f\n", a, b, a * b);
759 9d8e9c09 bellard
    printf("a=%f b=%f a/b=%f\n", a, b, a / b);
760 9d8e9c09 bellard
    printf("a=%f b=%f fmod(a, b)=%f\n", a, b, fmod(a, b));
761 9d8e9c09 bellard
    printf("a=%f sqrt(a)=%f\n", a, sqrt(a));
762 9d8e9c09 bellard
    printf("a=%f sin(a)=%f\n", a, sin(a));
763 9d8e9c09 bellard
    printf("a=%f cos(a)=%f\n", a, cos(a));
764 9d8e9c09 bellard
    printf("a=%f tan(a)=%f\n", a, tan(a));
765 9d8e9c09 bellard
    printf("a=%f log(a)=%f\n", a, log(a));
766 9d8e9c09 bellard
    printf("a=%f exp(a)=%f\n", a, exp(a));
767 9d8e9c09 bellard
    printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b));
768 9d8e9c09 bellard
    /* just to test some op combining */
769 9d8e9c09 bellard
    printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a)));
770 9d8e9c09 bellard
    printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a)));
771 9d8e9c09 bellard
    printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a)));
772 9d8e9c09 bellard
773 9d8e9c09 bellard
}
774 9d8e9c09 bellard
775 86bd2ca5 bellard
void fpu_clear_exceptions(void)
776 86bd2ca5 bellard
{
777 541dc0d4 Stefan Weil
    struct QEMU_PACKED {
778 86bd2ca5 bellard
        uint16_t fpuc;
779 86bd2ca5 bellard
        uint16_t dummy1;
780 86bd2ca5 bellard
        uint16_t fpus;
781 86bd2ca5 bellard
        uint16_t dummy2;
782 86bd2ca5 bellard
        uint16_t fptag;
783 86bd2ca5 bellard
        uint16_t dummy3;
784 86bd2ca5 bellard
        uint32_t ignored[4];
785 86bd2ca5 bellard
        long double fpregs[8];
786 86bd2ca5 bellard
    } float_env32;
787 3b46e624 ths
788 49cdaea1 Catalin Patulea
    asm volatile ("fnstenv %0\n" : "=m" (float_env32));
789 86bd2ca5 bellard
    float_env32.fpus &= ~0x7f;
790 86bd2ca5 bellard
    asm volatile ("fldenv %0\n" : : "m" (float_env32));
791 86bd2ca5 bellard
}
792 86bd2ca5 bellard
793 86bd2ca5 bellard
/* XXX: display exception bits when supported */
794 86bd2ca5 bellard
#define FPUS_EMASK 0x0000
795 86bd2ca5 bellard
//#define FPUS_EMASK 0x007f
796 86bd2ca5 bellard
797 9d8e9c09 bellard
void test_fcmp(double a, double b)
798 9d8e9c09 bellard
{
799 86bd2ca5 bellard
    long eflags, fpus;
800 86bd2ca5 bellard
801 86bd2ca5 bellard
    fpu_clear_exceptions();
802 86bd2ca5 bellard
    asm("fcom %2\n"
803 86bd2ca5 bellard
        "fstsw %%ax\n"
804 86bd2ca5 bellard
        : "=a" (fpus)
805 86bd2ca5 bellard
        : "t" (a), "u" (b));
806 b2bedb21 Stefan Weil
    printf("fcom(%f %f)=%04lx\n",
807 86bd2ca5 bellard
           a, b, fpus & (0x4500 | FPUS_EMASK));
808 86bd2ca5 bellard
    fpu_clear_exceptions();
809 86bd2ca5 bellard
    asm("fucom %2\n"
810 86bd2ca5 bellard
        "fstsw %%ax\n"
811 86bd2ca5 bellard
        : "=a" (fpus)
812 86bd2ca5 bellard
        : "t" (a), "u" (b));
813 5fafdf24 ths
    printf("fucom(%f %f)=%04lx\n",
814 86bd2ca5 bellard
           a, b, fpus & (0x4500 | FPUS_EMASK));
815 03bfca94 bellard
    if (TEST_FCOMI) {
816 03bfca94 bellard
        /* test f(u)comi instruction */
817 86bd2ca5 bellard
        fpu_clear_exceptions();
818 86bd2ca5 bellard
        asm("fcomi %3, %2\n"
819 86bd2ca5 bellard
            "fstsw %%ax\n"
820 03bfca94 bellard
            "pushf\n"
821 03bfca94 bellard
            "pop %0\n"
822 86bd2ca5 bellard
            : "=r" (eflags), "=a" (fpus)
823 03bfca94 bellard
            : "t" (a), "u" (b));
824 5fafdf24 ths
        printf("fcomi(%f %f)=%04lx %02lx\n",
825 86bd2ca5 bellard
               a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));
826 86bd2ca5 bellard
        fpu_clear_exceptions();
827 86bd2ca5 bellard
        asm("fucomi %3, %2\n"
828 86bd2ca5 bellard
            "fstsw %%ax\n"
829 86bd2ca5 bellard
            "pushf\n"
830 86bd2ca5 bellard
            "pop %0\n"
831 86bd2ca5 bellard
            : "=r" (eflags), "=a" (fpus)
832 86bd2ca5 bellard
            : "t" (a), "u" (b));
833 5fafdf24 ths
        printf("fucomi(%f %f)=%04lx %02lx\n",
834 86bd2ca5 bellard
               a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));
835 03bfca94 bellard
    }
836 86bd2ca5 bellard
    fpu_clear_exceptions();
837 b2a8e592 bellard
    asm volatile("fxam\n"
838 b2a8e592 bellard
                 "fstsw %%ax\n"
839 b2a8e592 bellard
                 : "=a" (fpus)
840 b2a8e592 bellard
                 : "t" (a));
841 b2a8e592 bellard
    printf("fxam(%f)=%04lx\n", a, fpus & 0x4700);
842 b2a8e592 bellard
    fpu_clear_exceptions();
843 9d8e9c09 bellard
}
844 9d8e9c09 bellard
845 9d8e9c09 bellard
void test_fcvt(double a)
846 9d8e9c09 bellard
{
847 9d8e9c09 bellard
    float fa;
848 9d8e9c09 bellard
    long double la;
849 ea768640 bellard
    int16_t fpuc;
850 ea768640 bellard
    int i;
851 ea768640 bellard
    int64_t lla;
852 ea768640 bellard
    int ia;
853 ea768640 bellard
    int16_t wa;
854 ea768640 bellard
    double ra;
855 9d8e9c09 bellard
856 9d8e9c09 bellard
    fa = a;
857 9d8e9c09 bellard
    la = a;
858 9d8e9c09 bellard
    printf("(float)%f = %f\n", a, fa);
859 9d8e9c09 bellard
    printf("(long double)%f = %Lf\n", a, la);
860 776f2227 bellard
    printf("a=" FMT64X "\n", *(uint64_t *)&a);
861 5fafdf24 ths
    printf("la=" FMT64X " %04x\n", *(uint64_t *)&la,
862 c5e9815d bellard
           *(unsigned short *)((char *)(&la) + 8));
863 ea768640 bellard
864 ea768640 bellard
    /* test all roundings */
865 ea768640 bellard
    asm volatile ("fstcw %0" : "=m" (fpuc));
866 ea768640 bellard
    for(i=0;i<4;i++) {
867 be98f1f8 bellard
        uint16_t val16;
868 be98f1f8 bellard
        val16 = (fpuc & ~0x0c00) | (i << 10);
869 be98f1f8 bellard
        asm volatile ("fldcw %0" : : "m" (val16));
870 ea768640 bellard
        asm volatile ("fist %0" : "=m" (wa) : "t" (a));
871 ea768640 bellard
        asm volatile ("fistl %0" : "=m" (ia) : "t" (a));
872 ea768640 bellard
        asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st");
873 ea768640 bellard
        asm volatile ("frndint ; fstl %0" : "=m" (ra) : "t" (a));
874 ea768640 bellard
        asm volatile ("fldcw %0" : : "m" (fpuc));
875 ea768640 bellard
        printf("(short)a = %d\n", wa);
876 ea768640 bellard
        printf("(int)a = %d\n", ia);
877 776f2227 bellard
        printf("(int64_t)a = " FMT64X "\n", lla);
878 ea768640 bellard
        printf("rint(a) = %f\n", ra);
879 ea768640 bellard
    }
880 9d8e9c09 bellard
}
881 9d8e9c09 bellard
882 9d8e9c09 bellard
#define TEST(N) \
883 9d8e9c09 bellard
    asm("fld" #N : "=t" (a)); \
884 9d8e9c09 bellard
    printf("fld" #N "= %f\n", a);
885 9d8e9c09 bellard
886 9d8e9c09 bellard
void test_fconst(void)
887 9d8e9c09 bellard
{
888 9d8e9c09 bellard
    double a;
889 9d8e9c09 bellard
    TEST(1);
890 9d8e9c09 bellard
    TEST(l2t);
891 9d8e9c09 bellard
    TEST(l2e);
892 9d8e9c09 bellard
    TEST(pi);
893 9d8e9c09 bellard
    TEST(lg2);
894 9d8e9c09 bellard
    TEST(ln2);
895 9d8e9c09 bellard
    TEST(z);
896 9d8e9c09 bellard
}
897 9d8e9c09 bellard
898 c5e9815d bellard
void test_fbcd(double a)
899 c5e9815d bellard
{
900 c5e9815d bellard
    unsigned short bcd[5];
901 c5e9815d bellard
    double b;
902 c5e9815d bellard
903 c5e9815d bellard
    asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
904 c5e9815d bellard
    asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
905 5fafdf24 ths
    printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",
906 c5e9815d bellard
           a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
907 c5e9815d bellard
}
908 c5e9815d bellard
909 6b2b6112 bellard
#define TEST_ENV(env, save, restore)\
910 03bfca94 bellard
{\
911 03bfca94 bellard
    memset((env), 0xaa, sizeof(*(env)));\
912 6b2b6112 bellard
    for(i=0;i<5;i++)\
913 6b2b6112 bellard
        asm volatile ("fldl %0" : : "m" (dtab[i]));\
914 085339a1 bellard
    asm volatile (save " %0\n" : : "m" (*(env)));\
915 085339a1 bellard
    asm volatile (restore " %0\n": : "m" (*(env)));\
916 6b2b6112 bellard
    for(i=0;i<5;i++)\
917 6b2b6112 bellard
        asm volatile ("fstpl %0" : "=m" (rtab[i]));\
918 6b2b6112 bellard
    for(i=0;i<5;i++)\
919 6b2b6112 bellard
        printf("res[%d]=%f\n", i, rtab[i]);\
920 03bfca94 bellard
    printf("fpuc=%04x fpus=%04x fptag=%04x\n",\
921 03bfca94 bellard
           (env)->fpuc,\
922 03bfca94 bellard
           (env)->fpus & 0xff00,\
923 03bfca94 bellard
           (env)->fptag);\
924 03bfca94 bellard
}
925 03bfca94 bellard
926 03bfca94 bellard
void test_fenv(void)
927 03bfca94 bellard
{
928 541dc0d4 Stefan Weil
    struct QEMU_PACKED {
929 03bfca94 bellard
        uint16_t fpuc;
930 03bfca94 bellard
        uint16_t dummy1;
931 03bfca94 bellard
        uint16_t fpus;
932 03bfca94 bellard
        uint16_t dummy2;
933 03bfca94 bellard
        uint16_t fptag;
934 03bfca94 bellard
        uint16_t dummy3;
935 03bfca94 bellard
        uint32_t ignored[4];
936 03bfca94 bellard
        long double fpregs[8];
937 03bfca94 bellard
    } float_env32;
938 541dc0d4 Stefan Weil
    struct QEMU_PACKED {
939 03bfca94 bellard
        uint16_t fpuc;
940 03bfca94 bellard
        uint16_t fpus;
941 03bfca94 bellard
        uint16_t fptag;
942 03bfca94 bellard
        uint16_t ignored[4];
943 03bfca94 bellard
        long double fpregs[8];
944 03bfca94 bellard
    } float_env16;
945 6b2b6112 bellard
    double dtab[8];
946 6b2b6112 bellard
    double rtab[8];
947 6b2b6112 bellard
    int i;
948 6b2b6112 bellard
949 6b2b6112 bellard
    for(i=0;i<8;i++)
950 6b2b6112 bellard
        dtab[i] = i + 1;
951 03bfca94 bellard
952 6b2b6112 bellard
    TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv");
953 6b2b6112 bellard
    TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor");
954 6b2b6112 bellard
    TEST_ENV(&float_env32, "fnstenv", "fldenv");
955 6b2b6112 bellard
    TEST_ENV(&float_env32, "fnsave", "frstor");
956 665656a9 bellard
957 665656a9 bellard
    /* test for ffree */
958 665656a9 bellard
    for(i=0;i<5;i++)
959 665656a9 bellard
        asm volatile ("fldl %0" : : "m" (dtab[i]));
960 665656a9 bellard
    asm volatile("ffree %st(2)");
961 665656a9 bellard
    asm volatile ("fnstenv %0\n" : : "m" (float_env32));
962 665656a9 bellard
    asm volatile ("fninit");
963 665656a9 bellard
    printf("fptag=%04x\n", float_env32.fptag);
964 03bfca94 bellard
}
965 03bfca94 bellard
966 75175024 bellard
967 75175024 bellard
#define TEST_FCMOV(a, b, eflags, CC)\
968 75175024 bellard
{\
969 75175024 bellard
    double res;\
970 75175024 bellard
    asm("push %3\n"\
971 75175024 bellard
        "popf\n"\
972 75175024 bellard
        "fcmov" CC " %2, %0\n"\
973 75175024 bellard
        : "=t" (res)\
974 75175024 bellard
        : "0" (a), "u" (b), "g" (eflags));\
975 776f2227 bellard
    printf("fcmov%s eflags=0x%04lx-> %f\n", \
976 776f2227 bellard
           CC, (long)eflags, res);\
977 75175024 bellard
}
978 75175024 bellard
979 75175024 bellard
void test_fcmov(void)
980 75175024 bellard
{
981 75175024 bellard
    double a, b;
982 776f2227 bellard
    long eflags, i;
983 75175024 bellard
984 75175024 bellard
    a = 1.0;
985 75175024 bellard
    b = 2.0;
986 75175024 bellard
    for(i = 0; i < 4; i++) {
987 75175024 bellard
        eflags = 0;
988 75175024 bellard
        if (i & 1)
989 75175024 bellard
            eflags |= CC_C;
990 75175024 bellard
        if (i & 2)
991 75175024 bellard
            eflags |= CC_Z;
992 75175024 bellard
        TEST_FCMOV(a, b, eflags, "b");
993 75175024 bellard
        TEST_FCMOV(a, b, eflags, "e");
994 75175024 bellard
        TEST_FCMOV(a, b, eflags, "be");
995 75175024 bellard
        TEST_FCMOV(a, b, eflags, "nb");
996 75175024 bellard
        TEST_FCMOV(a, b, eflags, "ne");
997 75175024 bellard
        TEST_FCMOV(a, b, eflags, "nbe");
998 75175024 bellard
    }
999 75175024 bellard
    TEST_FCMOV(a, b, 0, "u");
1000 9cdf757f bellard
    TEST_FCMOV(a, b, CC_P, "u");
1001 9cdf757f bellard
    TEST_FCMOV(a, b, 0, "nu");
1002 75175024 bellard
    TEST_FCMOV(a, b, CC_P, "nu");
1003 75175024 bellard
}
1004 75175024 bellard
1005 9d8e9c09 bellard
void test_floats(void)
1006 9d8e9c09 bellard
{
1007 9d8e9c09 bellard
    test_fops(2, 3);
1008 9d8e9c09 bellard
    test_fops(1.4, -5);
1009 9d8e9c09 bellard
    test_fcmp(2, -1);
1010 9d8e9c09 bellard
    test_fcmp(2, 2);
1011 9d8e9c09 bellard
    test_fcmp(2, 3);
1012 86bd2ca5 bellard
    test_fcmp(2, q_nan.d);
1013 86bd2ca5 bellard
    test_fcmp(q_nan.d, -1);
1014 b2a8e592 bellard
    test_fcmp(-1.0/0.0, -1);
1015 b2a8e592 bellard
    test_fcmp(1.0/0.0, -1);
1016 ea768640 bellard
    test_fcvt(0.5);
1017 ea768640 bellard
    test_fcvt(-0.5);
1018 9d8e9c09 bellard
    test_fcvt(1.0/7.0);
1019 9d8e9c09 bellard
    test_fcvt(-1.0/9.0);
1020 ea768640 bellard
    test_fcvt(32768);
1021 ea768640 bellard
    test_fcvt(-1e20);
1022 b2a8e592 bellard
    test_fcvt(-1.0/0.0);
1023 b2a8e592 bellard
    test_fcvt(1.0/0.0);
1024 b2a8e592 bellard
    test_fcvt(q_nan.d);
1025 9d8e9c09 bellard
    test_fconst();
1026 be98f1f8 bellard
    test_fbcd(1234567890123456.0);
1027 be98f1f8 bellard
    test_fbcd(-123451234567890.0);
1028 03bfca94 bellard
    test_fenv();
1029 75175024 bellard
    if (TEST_CMOV) {
1030 75175024 bellard
        test_fcmov();
1031 75175024 bellard
    }
1032 9d8e9c09 bellard
}
1033 4b74fe1f bellard
1034 55480af8 bellard
/**********************************************/
1035 776f2227 bellard
#if !defined(__x86_64__)
1036 55480af8 bellard
1037 55480af8 bellard
#define TEST_BCD(op, op0, cc_in, cc_mask)\
1038 55480af8 bellard
{\
1039 55480af8 bellard
    int res, flags;\
1040 55480af8 bellard
    res = op0;\
1041 55480af8 bellard
    flags = cc_in;\
1042 55480af8 bellard
    asm ("push %3\n\t"\
1043 55480af8 bellard
         "popf\n\t"\
1044 55480af8 bellard
         #op "\n\t"\
1045 55480af8 bellard
         "pushf\n\t"\
1046 776f2227 bellard
         "pop %1\n\t"\
1047 55480af8 bellard
        : "=a" (res), "=g" (flags)\
1048 55480af8 bellard
        : "0" (res), "1" (flags));\
1049 55480af8 bellard
    printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\
1050 55480af8 bellard
           #op, op0, res, cc_in, flags & cc_mask);\
1051 55480af8 bellard
}
1052 55480af8 bellard
1053 55480af8 bellard
void test_bcd(void)
1054 55480af8 bellard
{
1055 55480af8 bellard
    TEST_BCD(daa, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1056 55480af8 bellard
    TEST_BCD(daa, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1057 55480af8 bellard
    TEST_BCD(daa, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1058 55480af8 bellard
    TEST_BCD(daa, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1059 55480af8 bellard
    TEST_BCD(daa, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1060 55480af8 bellard
    TEST_BCD(daa, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1061 55480af8 bellard
    TEST_BCD(daa, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1062 55480af8 bellard
    TEST_BCD(daa, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1063 55480af8 bellard
    TEST_BCD(daa, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1064 55480af8 bellard
    TEST_BCD(daa, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1065 55480af8 bellard
    TEST_BCD(daa, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1066 55480af8 bellard
    TEST_BCD(daa, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1067 55480af8 bellard
    TEST_BCD(daa, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1068 55480af8 bellard
1069 55480af8 bellard
    TEST_BCD(das, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1070 55480af8 bellard
    TEST_BCD(das, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1071 55480af8 bellard
    TEST_BCD(das, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1072 55480af8 bellard
    TEST_BCD(das, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1073 55480af8 bellard
    TEST_BCD(das, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1074 55480af8 bellard
    TEST_BCD(das, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1075 55480af8 bellard
    TEST_BCD(das, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1076 55480af8 bellard
    TEST_BCD(das, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1077 55480af8 bellard
    TEST_BCD(das, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1078 55480af8 bellard
    TEST_BCD(das, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1079 55480af8 bellard
    TEST_BCD(das, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1080 55480af8 bellard
    TEST_BCD(das, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1081 55480af8 bellard
    TEST_BCD(das, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1082 55480af8 bellard
1083 55480af8 bellard
    TEST_BCD(aaa, 0x12340205, CC_A, (CC_C | CC_A));
1084 55480af8 bellard
    TEST_BCD(aaa, 0x12340306, CC_A, (CC_C | CC_A));
1085 55480af8 bellard
    TEST_BCD(aaa, 0x1234040a, CC_A, (CC_C | CC_A));
1086 55480af8 bellard
    TEST_BCD(aaa, 0x123405fa, CC_A, (CC_C | CC_A));
1087 55480af8 bellard
    TEST_BCD(aaa, 0x12340205, 0, (CC_C | CC_A));
1088 55480af8 bellard
    TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A));
1089 55480af8 bellard
    TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A));
1090 55480af8 bellard
    TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A));
1091 3b46e624 ths
1092 55480af8 bellard
    TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A));
1093 55480af8 bellard
    TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A));
1094 55480af8 bellard
    TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A));
1095 55480af8 bellard
    TEST_BCD(aas, 0x123405fa, CC_A, (CC_C | CC_A));
1096 55480af8 bellard
    TEST_BCD(aas, 0x12340205, 0, (CC_C | CC_A));
1097 55480af8 bellard
    TEST_BCD(aas, 0x12340306, 0, (CC_C | CC_A));
1098 55480af8 bellard
    TEST_BCD(aas, 0x1234040a, 0, (CC_C | CC_A));
1099 55480af8 bellard
    TEST_BCD(aas, 0x123405fa, 0, (CC_C | CC_A));
1100 55480af8 bellard
1101 55480af8 bellard
    TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
1102 55480af8 bellard
    TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
1103 55480af8 bellard
}
1104 776f2227 bellard
#endif
1105 55480af8 bellard
1106 e5918247 bellard
#define TEST_XCHG(op, size, opconst)\
1107 e5918247 bellard
{\
1108 776f2227 bellard
    long op0, op1;\
1109 776f2227 bellard
    op0 = i2l(0x12345678);\
1110 776f2227 bellard
    op1 = i2l(0xfbca7654);\
1111 e5918247 bellard
    asm(#op " %" size "0, %" size "1" \
1112 e5918247 bellard
        : "=q" (op0), opconst (op1) \
1113 8aadfbf0 bellard
        : "0" (op0));\
1114 776f2227 bellard
    printf("%-10s A=" FMTLX " B=" FMTLX "\n",\
1115 e5918247 bellard
           #op, op0, op1);\
1116 e5918247 bellard
}
1117 e5918247 bellard
1118 e5918247 bellard
#define TEST_CMPXCHG(op, size, opconst, eax)\
1119 e5918247 bellard
{\
1120 776f2227 bellard
    long op0, op1, op2;\
1121 776f2227 bellard
    op0 = i2l(0x12345678);\
1122 776f2227 bellard
    op1 = i2l(0xfbca7654);\
1123 776f2227 bellard
    op2 = i2l(eax);\
1124 e5918247 bellard
    asm(#op " %" size "0, %" size "1" \
1125 e5918247 bellard
        : "=q" (op0), opconst (op1) \
1126 8aadfbf0 bellard
        : "0" (op0), "a" (op2));\
1127 776f2227 bellard
    printf("%-10s EAX=" FMTLX " A=" FMTLX " C=" FMTLX "\n",\
1128 776f2227 bellard
           #op, op2, op0, op1);\
1129 e5918247 bellard
}
1130 e5918247 bellard
1131 e5918247 bellard
void test_xchg(void)
1132 e5918247 bellard
{
1133 776f2227 bellard
#if defined(__x86_64__)
1134 8aadfbf0 bellard
    TEST_XCHG(xchgq, "", "+q");
1135 776f2227 bellard
#endif
1136 8aadfbf0 bellard
    TEST_XCHG(xchgl, "k", "+q");
1137 8aadfbf0 bellard
    TEST_XCHG(xchgw, "w", "+q");
1138 8aadfbf0 bellard
    TEST_XCHG(xchgb, "b", "+q");
1139 e5918247 bellard
1140 776f2227 bellard
#if defined(__x86_64__)
1141 776f2227 bellard
    TEST_XCHG(xchgq, "", "=m");
1142 776f2227 bellard
#endif
1143 8aadfbf0 bellard
    TEST_XCHG(xchgl, "k", "+m");
1144 8aadfbf0 bellard
    TEST_XCHG(xchgw, "w", "+m");
1145 8aadfbf0 bellard
    TEST_XCHG(xchgb, "b", "+m");
1146 e5918247 bellard
1147 776f2227 bellard
#if defined(__x86_64__)
1148 8aadfbf0 bellard
    TEST_XCHG(xaddq, "", "+q");
1149 776f2227 bellard
#endif
1150 8aadfbf0 bellard
    TEST_XCHG(xaddl, "k", "+q");
1151 8aadfbf0 bellard
    TEST_XCHG(xaddw, "w", "+q");
1152 8aadfbf0 bellard
    TEST_XCHG(xaddb, "b", "+q");
1153 e5918247 bellard
1154 d575b78a bellard
    {
1155 d575b78a bellard
        int res;
1156 d575b78a bellard
        res = 0x12345678;
1157 d575b78a bellard
        asm("xaddl %1, %0" : "=r" (res) : "0" (res));
1158 d575b78a bellard
        printf("xaddl same res=%08x\n", res);
1159 d575b78a bellard
    }
1160 d575b78a bellard
1161 776f2227 bellard
#if defined(__x86_64__)
1162 8aadfbf0 bellard
    TEST_XCHG(xaddq, "", "+m");
1163 776f2227 bellard
#endif
1164 8aadfbf0 bellard
    TEST_XCHG(xaddl, "k", "+m");
1165 8aadfbf0 bellard
    TEST_XCHG(xaddw, "w", "+m");
1166 8aadfbf0 bellard
    TEST_XCHG(xaddb, "b", "+m");
1167 e5918247 bellard
1168 776f2227 bellard
#if defined(__x86_64__)
1169 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgq, "", "+q", 0xfbca7654);
1170 776f2227 bellard
#endif
1171 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "+q", 0xfbca7654);
1172 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "+q", 0xfbca7654);
1173 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "+q", 0xfbca7654);
1174 e5918247 bellard
1175 776f2227 bellard
#if defined(__x86_64__)
1176 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgq, "", "+q", 0xfffefdfc);
1177 776f2227 bellard
#endif
1178 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "+q", 0xfffefdfc);
1179 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "+q", 0xfffefdfc);
1180 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "+q", 0xfffefdfc);
1181 e5918247 bellard
1182 776f2227 bellard
#if defined(__x86_64__)
1183 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgq, "", "+m", 0xfbca7654);
1184 776f2227 bellard
#endif
1185 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "+m", 0xfbca7654);
1186 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "+m", 0xfbca7654);
1187 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "+m", 0xfbca7654);
1188 e5918247 bellard
1189 776f2227 bellard
#if defined(__x86_64__)
1190 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgq, "", "+m", 0xfffefdfc);
1191 776f2227 bellard
#endif
1192 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "+m", 0xfffefdfc);
1193 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "+m", 0xfffefdfc);
1194 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "+m", 0xfffefdfc);
1195 d575b78a bellard
1196 d575b78a bellard
    {
1197 d575b78a bellard
        uint64_t op0, op1, op2;
1198 a5973fbf bellard
        long eax, edx;
1199 776f2227 bellard
        long i, eflags;
1200 d575b78a bellard
1201 d575b78a bellard
        for(i = 0; i < 2; i++) {
1202 be98f1f8 bellard
            op0 = 0x123456789abcdLL;
1203 a5973fbf bellard
            eax = i2l(op0 & 0xffffffff);
1204 a5973fbf bellard
            edx = i2l(op0 >> 32);
1205 d575b78a bellard
            if (i == 0)
1206 be98f1f8 bellard
                op1 = 0xfbca765423456LL;
1207 d575b78a bellard
            else
1208 d575b78a bellard
                op1 = op0;
1209 be98f1f8 bellard
            op2 = 0x6532432432434LL;
1210 a5973fbf bellard
            asm("cmpxchg8b %2\n"
1211 d575b78a bellard
                "pushf\n"
1212 a5973fbf bellard
                "pop %3\n"
1213 a5973fbf bellard
                : "=a" (eax), "=d" (edx), "=m" (op1), "=g" (eflags)
1214 a5973fbf bellard
                : "0" (eax), "1" (edx), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32)));
1215 a5973fbf bellard
            printf("cmpxchg8b: eax=" FMTLX " edx=" FMTLX " op1=" FMT64X " CC=%02lx\n",
1216 a5973fbf bellard
                   eax, edx, op1, eflags & CC_Z);
1217 d575b78a bellard
        }
1218 d575b78a bellard
    }
1219 e5918247 bellard
}
1220 e5918247 bellard
1221 776f2227 bellard
#ifdef TEST_SEGS
1222 6dbad63e bellard
/**********************************************/
1223 6dbad63e bellard
/* segmentation tests */
1224 6dbad63e bellard
1225 be98f1f8 bellard
#include <sys/syscall.h>
1226 be98f1f8 bellard
#include <unistd.h>
1227 6dbad63e bellard
#include <asm/ldt.h>
1228 73bdea19 bellard
#include <linux/version.h>
1229 6dbad63e bellard
1230 be98f1f8 bellard
static inline int modify_ldt(int func, void * ptr, unsigned long bytecount)
1231 be98f1f8 bellard
{
1232 be98f1f8 bellard
    return syscall(__NR_modify_ldt, func, ptr, bytecount);
1233 be98f1f8 bellard
}
1234 6dbad63e bellard
1235 73bdea19 bellard
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
1236 73bdea19 bellard
#define modify_ldt_ldt_s user_desc
1237 73bdea19 bellard
#endif
1238 73bdea19 bellard
1239 776f2227 bellard
#define MK_SEL(n) (((n) << 3) | 7)
1240 776f2227 bellard
1241 6dbad63e bellard
uint8_t seg_data1[4096];
1242 6dbad63e bellard
uint8_t seg_data2[4096];
1243 6dbad63e bellard
1244 288426fe bellard
#define TEST_LR(op, size, seg, mask)\
1245 288426fe bellard
{\
1246 288426fe bellard
    int res, res2;\
1247 a5973fbf bellard
    uint16_t mseg = seg;\
1248 288426fe bellard
    res = 0x12345678;\
1249 288426fe bellard
    asm (op " %" size "2, %" size "0\n" \
1250 288426fe bellard
         "movl $0, %1\n"\
1251 288426fe bellard
         "jnz 1f\n"\
1252 288426fe bellard
         "movl $1, %1\n"\
1253 288426fe bellard
         "1:\n"\
1254 a5973fbf bellard
         : "=r" (res), "=r" (res2) : "m" (mseg), "0" (res));\
1255 288426fe bellard
    printf(op ": Z=%d %08x\n", res2, res & ~(mask));\
1256 288426fe bellard
}
1257 288426fe bellard
1258 a5973fbf bellard
#define TEST_ARPL(op, size, op1, op2)\
1259 a5973fbf bellard
{\
1260 a5973fbf bellard
    long a, b, c;                               \
1261 a5973fbf bellard
    a = (op1);                                  \
1262 a5973fbf bellard
    b = (op2);                                  \
1263 a5973fbf bellard
    asm volatile(op " %" size "3, %" size "0\n"\
1264 a5973fbf bellard
                 "movl $0,%1\n"\
1265 a5973fbf bellard
                 "jnz 1f\n"\
1266 a5973fbf bellard
                 "movl $1,%1\n"\
1267 a5973fbf bellard
                 "1:\n"\
1268 a5973fbf bellard
                 : "=r" (a), "=r" (c) : "0" (a), "r" (b));    \
1269 a5973fbf bellard
    printf(op size " A=" FMTLX " B=" FMTLX " R=" FMTLX " z=%ld\n",\
1270 a5973fbf bellard
           (long)(op1), (long)(op2), a, c);\
1271 a5973fbf bellard
}
1272 a5973fbf bellard
1273 6dbad63e bellard
/* NOTE: we use Linux modify_ldt syscall */
1274 6dbad63e bellard
void test_segs(void)
1275 6dbad63e bellard
{
1276 6dbad63e bellard
    struct modify_ldt_ldt_s ldt;
1277 6dbad63e bellard
    long long ldt_table[3];
1278 04369ff2 bellard
    int res, res2;
1279 6dbad63e bellard
    char tmp;
1280 e1d4294a bellard
    struct {
1281 e1d4294a bellard
        uint32_t offset;
1282 e1d4294a bellard
        uint16_t seg;
1283 541dc0d4 Stefan Weil
    } QEMU_PACKED segoff;
1284 6dbad63e bellard
1285 6dbad63e bellard
    ldt.entry_number = 1;
1286 6dbad63e bellard
    ldt.base_addr = (unsigned long)&seg_data1;
1287 6dbad63e bellard
    ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
1288 6dbad63e bellard
    ldt.seg_32bit = 1;
1289 6dbad63e bellard
    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
1290 6dbad63e bellard
    ldt.read_exec_only = 0;
1291 6dbad63e bellard
    ldt.limit_in_pages = 1;
1292 6dbad63e bellard
    ldt.seg_not_present = 0;
1293 6dbad63e bellard
    ldt.useable = 1;
1294 6dbad63e bellard
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
1295 6dbad63e bellard
1296 6dbad63e bellard
    ldt.entry_number = 2;
1297 6dbad63e bellard
    ldt.base_addr = (unsigned long)&seg_data2;
1298 6dbad63e bellard
    ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12;
1299 6dbad63e bellard
    ldt.seg_32bit = 1;
1300 6dbad63e bellard
    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
1301 6dbad63e bellard
    ldt.read_exec_only = 0;
1302 6dbad63e bellard
    ldt.limit_in_pages = 1;
1303 6dbad63e bellard
    ldt.seg_not_present = 0;
1304 6dbad63e bellard
    ldt.useable = 1;
1305 6dbad63e bellard
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
1306 6dbad63e bellard
1307 6dbad63e bellard
    modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */
1308 04369ff2 bellard
#if 0
1309 04369ff2 bellard
    {
1310 04369ff2 bellard
        int i;
1311 04369ff2 bellard
        for(i=0;i<3;i++)
1312 04369ff2 bellard
            printf("%d: %016Lx\n", i, ldt_table[i]);
1313 04369ff2 bellard
    }
1314 04369ff2 bellard
#endif
1315 6dbad63e bellard
    /* do some tests with fs or gs */
1316 6dbad63e bellard
    asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
1317 6dbad63e bellard
1318 6dbad63e bellard
    seg_data1[1] = 0xaa;
1319 6dbad63e bellard
    seg_data2[1] = 0x55;
1320 6dbad63e bellard
1321 6dbad63e bellard
    asm volatile ("fs movzbl 0x1, %0" : "=r" (res));
1322 6dbad63e bellard
    printf("FS[1] = %02x\n", res);
1323 6dbad63e bellard
1324 070893f4 bellard
    asm volatile ("pushl %%gs\n"
1325 070893f4 bellard
                  "movl %1, %%gs\n"
1326 070893f4 bellard
                  "gs movzbl 0x1, %0\n"
1327 070893f4 bellard
                  "popl %%gs\n"
1328 070893f4 bellard
                  : "=r" (res)
1329 070893f4 bellard
                  : "r" (MK_SEL(2)));
1330 6dbad63e bellard
    printf("GS[1] = %02x\n", res);
1331 6dbad63e bellard
1332 6dbad63e bellard
    /* tests with ds/ss (implicit segment case) */
1333 6dbad63e bellard
    tmp = 0xa5;
1334 6dbad63e bellard
    asm volatile ("pushl %%ebp\n\t"
1335 6dbad63e bellard
                  "pushl %%ds\n\t"
1336 6dbad63e bellard
                  "movl %2, %%ds\n\t"
1337 6dbad63e bellard
                  "movl %3, %%ebp\n\t"
1338 6dbad63e bellard
                  "movzbl 0x1, %0\n\t"
1339 6dbad63e bellard
                  "movzbl (%%ebp), %1\n\t"
1340 6dbad63e bellard
                  "popl %%ds\n\t"
1341 6dbad63e bellard
                  "popl %%ebp\n\t"
1342 6dbad63e bellard
                  : "=r" (res), "=r" (res2)
1343 6dbad63e bellard
                  : "r" (MK_SEL(1)), "r" (&tmp));
1344 6dbad63e bellard
    printf("DS[1] = %02x\n", res);
1345 6dbad63e bellard
    printf("SS[tmp] = %02x\n", res2);
1346 e1d4294a bellard
1347 e1d4294a bellard
    segoff.seg = MK_SEL(2);
1348 e1d4294a bellard
    segoff.offset = 0xabcdef12;
1349 5fafdf24 ths
    asm volatile("lfs %2, %0\n\t"
1350 e1d4294a bellard
                 "movl %%fs, %1\n\t"
1351 5fafdf24 ths
                 : "=r" (res), "=g" (res2)
1352 e1d4294a bellard
                 : "m" (segoff));
1353 e1d4294a bellard
    printf("FS:reg = %04x:%08x\n", res2, res);
1354 288426fe bellard
1355 288426fe bellard
    TEST_LR("larw", "w", MK_SEL(2), 0x0100);
1356 288426fe bellard
    TEST_LR("larl", "", MK_SEL(2), 0x0100);
1357 288426fe bellard
    TEST_LR("lslw", "w", MK_SEL(2), 0);
1358 288426fe bellard
    TEST_LR("lsll", "", MK_SEL(2), 0);
1359 288426fe bellard
1360 288426fe bellard
    TEST_LR("larw", "w", 0xfff8, 0);
1361 288426fe bellard
    TEST_LR("larl", "", 0xfff8, 0);
1362 288426fe bellard
    TEST_LR("lslw", "w", 0xfff8, 0);
1363 288426fe bellard
    TEST_LR("lsll", "", 0xfff8, 0);
1364 a5973fbf bellard
1365 a5973fbf bellard
    TEST_ARPL("arpl", "w", 0x12345678 | 3, 0x762123c | 1);
1366 a5973fbf bellard
    TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 3);
1367 a5973fbf bellard
    TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 1);
1368 6dbad63e bellard
}
1369 55480af8 bellard
1370 e5918247 bellard
/* 16 bit code test */
1371 e5918247 bellard
extern char code16_start, code16_end;
1372 e5918247 bellard
extern char code16_func1;
1373 e5918247 bellard
extern char code16_func2;
1374 e5918247 bellard
extern char code16_func3;
1375 a300e691 bellard
1376 e5918247 bellard
void test_code16(void)
1377 1a9353d2 bellard
{
1378 e5918247 bellard
    struct modify_ldt_ldt_s ldt;
1379 e5918247 bellard
    int res, res2;
1380 a300e691 bellard
1381 e5918247 bellard
    /* build a code segment */
1382 e5918247 bellard
    ldt.entry_number = 1;
1383 e5918247 bellard
    ldt.base_addr = (unsigned long)&code16_start;
1384 e5918247 bellard
    ldt.limit = &code16_end - &code16_start;
1385 e5918247 bellard
    ldt.seg_32bit = 0;
1386 e5918247 bellard
    ldt.contents = MODIFY_LDT_CONTENTS_CODE;
1387 e5918247 bellard
    ldt.read_exec_only = 0;
1388 e5918247 bellard
    ldt.limit_in_pages = 0;
1389 e5918247 bellard
    ldt.seg_not_present = 0;
1390 e5918247 bellard
    ldt.useable = 1;
1391 e5918247 bellard
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
1392 a300e691 bellard
1393 e5918247 bellard
    /* call the first function */
1394 5fafdf24 ths
    asm volatile ("lcall %1, %2"
1395 e5918247 bellard
                  : "=a" (res)
1396 e5918247 bellard
                  : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc");
1397 e5918247 bellard
    printf("func1() = 0x%08x\n", res);
1398 5fafdf24 ths
    asm volatile ("lcall %2, %3"
1399 e5918247 bellard
                  : "=a" (res), "=c" (res2)
1400 e5918247 bellard
                  : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc");
1401 e5918247 bellard
    printf("func2() = 0x%08x spdec=%d\n", res, res2);
1402 5fafdf24 ths
    asm volatile ("lcall %1, %2"
1403 e5918247 bellard
                  : "=a" (res)
1404 e5918247 bellard
                  : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc");
1405 e5918247 bellard
    printf("func3() = 0x%08x\n", res);
1406 1a9353d2 bellard
}
1407 776f2227 bellard
#endif
1408 1a9353d2 bellard
1409 e06e5259 bellard
#if defined(__x86_64__)
1410 e06e5259 bellard
asm(".globl func_lret\n"
1411 e06e5259 bellard
    "func_lret:\n"
1412 e06e5259 bellard
    "movl $0x87654641, %eax\n"
1413 e06e5259 bellard
    "lretq\n");
1414 e06e5259 bellard
#else
1415 e06e5259 bellard
asm(".globl func_lret\n"
1416 e06e5259 bellard
    "func_lret:\n"
1417 e06e5259 bellard
    "movl $0x87654321, %eax\n"
1418 e06e5259 bellard
    "lret\n"
1419 e06e5259 bellard
1420 e06e5259 bellard
    ".globl func_iret\n"
1421 e06e5259 bellard
    "func_iret:\n"
1422 e06e5259 bellard
    "movl $0xabcd4321, %eax\n"
1423 e06e5259 bellard
    "iret\n");
1424 e06e5259 bellard
#endif
1425 e06e5259 bellard
1426 e06e5259 bellard
extern char func_lret;
1427 e06e5259 bellard
extern char func_iret;
1428 dd3587f3 bellard
1429 e1d4294a bellard
void test_misc(void)
1430 e1d4294a bellard
{
1431 e1d4294a bellard
    char table[256];
1432 776f2227 bellard
    long res, i;
1433 e1d4294a bellard
1434 e1d4294a bellard
    for(i=0;i<256;i++) table[i] = 256 - i;
1435 e1d4294a bellard
    res = 0x12345678;
1436 e1d4294a bellard
    asm ("xlat" : "=a" (res) : "b" (table), "0" (res));
1437 776f2227 bellard
    printf("xlat: EAX=" FMTLX "\n", res);
1438 dd3587f3 bellard
1439 e06e5259 bellard
#if defined(__x86_64__)
1440 8aadfbf0 bellard
#if 0
1441 e06e5259 bellard
    {
1442 8aadfbf0 bellard
        /* XXX: see if Intel Core2 and AMD64 behavior really
1443 8aadfbf0 bellard
           differ. Here we implemented the Intel way which is not
1444 8aadfbf0 bellard
           compatible yet with QEMU. */
1445 541dc0d4 Stefan Weil
        static struct QEMU_PACKED {
1446 8aadfbf0 bellard
            uint64_t offset;
1447 e06e5259 bellard
            uint16_t seg;
1448 e06e5259 bellard
        } desc;
1449 e06e5259 bellard
        long cs_sel;
1450 e06e5259 bellard

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

1453 e06e5259 bellard
        asm volatile ("push %1\n"
1454 5fafdf24 ths
                      "call func_lret\n"
1455 e06e5259 bellard
                      : "=a" (res)
1456 e06e5259 bellard
                      : "r" (cs_sel) : "memory", "cc");
1457 e06e5259 bellard
        printf("func_lret=" FMTLX "\n", res);
1458 e06e5259 bellard

1459 e06e5259 bellard
        desc.offset = (long)&func_lret;
1460 e06e5259 bellard
        desc.seg = cs_sel;
1461 3b46e624 ths

1462 e06e5259 bellard
        asm volatile ("xor %%rax, %%rax\n"
1463 8aadfbf0 bellard
                      "rex64 lcall *(%%rcx)\n"
1464 e06e5259 bellard
                      : "=a" (res)
1465 8aadfbf0 bellard
                      : "c" (&desc)
1466 e06e5259 bellard
                      : "memory", "cc");
1467 e06e5259 bellard
        printf("func_lret2=" FMTLX "\n", res);
1468 e06e5259 bellard

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