Statistics
| Branch: | Revision:

root / tests / tcg / test-i386.c @ c09015dd

History | View | Annotate | Download (70.1 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 4d1135e4 bellard
#include <stdlib.h>
21 4d1135e4 bellard
#include <stdio.h>
22 e3e86d56 bellard
#include <string.h>
23 6dbad63e bellard
#include <inttypes.h>
24 4d1135e4 bellard
#include <math.h>
25 3a27ad0b bellard
#include <signal.h>
26 3a27ad0b bellard
#include <setjmp.h>
27 070893f4 bellard
#include <errno.h>
28 3a27ad0b bellard
#include <sys/ucontext.h>
29 3a27ad0b bellard
#include <sys/mman.h>
30 4d1135e4 bellard
31 776f2227 bellard
#if !defined(__x86_64__)
32 a5973fbf bellard
//#define TEST_VM86
33 776f2227 bellard
#define TEST_SEGS
34 776f2227 bellard
#endif
35 3ff0631e bellard
//#define LINUX_VM86_IOPL_FIX
36 791c2261 bellard
//#define TEST_P4_FLAGS
37 a5973fbf bellard
#ifdef __SSE__
38 776f2227 bellard
#define TEST_SSE
39 776f2227 bellard
#define TEST_CMOV  1
40 776f2227 bellard
#define TEST_FCOMI 1
41 776f2227 bellard
#else
42 a5973fbf bellard
#undef TEST_SSE
43 a5973fbf bellard
#define TEST_CMOV  1
44 a5973fbf bellard
#define TEST_FCOMI 1
45 776f2227 bellard
#endif
46 776f2227 bellard
47 776f2227 bellard
#if defined(__x86_64__)
48 776f2227 bellard
#define FMT64X "%016lx"
49 776f2227 bellard
#define FMTLX "%016lx"
50 776f2227 bellard
#define X86_64_ONLY(x) x
51 776f2227 bellard
#else
52 26a76461 bellard
#define FMT64X "%016" PRIx64
53 776f2227 bellard
#define FMTLX "%08lx"
54 776f2227 bellard
#define X86_64_ONLY(x)
55 776f2227 bellard
#endif
56 776f2227 bellard
57 776f2227 bellard
#ifdef TEST_VM86
58 776f2227 bellard
#include <asm/vm86.h>
59 776f2227 bellard
#endif
60 5dd9488c bellard
61 4d1135e4 bellard
#define xglue(x, y) x ## y
62 4d1135e4 bellard
#define glue(x, y) xglue(x, y)
63 4d1135e4 bellard
#define stringify(s)        tostring(s)
64 4d1135e4 bellard
#define tostring(s)        #s
65 4d1135e4 bellard
66 4d1135e4 bellard
#define CC_C           0x0001
67 4d1135e4 bellard
#define CC_P         0x0004
68 4d1135e4 bellard
#define CC_A        0x0010
69 4d1135e4 bellard
#define CC_Z        0x0040
70 4d1135e4 bellard
#define CC_S    0x0080
71 4d1135e4 bellard
#define CC_O    0x0800
72 4d1135e4 bellard
73 776f2227 bellard
#define __init_call        __attribute__ ((unused,__section__ ("initcall")))
74 4d1135e4 bellard
75 4b74fe1f bellard
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
76 4b74fe1f bellard
77 776f2227 bellard
#if defined(__x86_64__)
78 776f2227 bellard
static inline long i2l(long v)
79 776f2227 bellard
{
80 776f2227 bellard
    return v | ((v ^ 0xabcd) << 32);
81 776f2227 bellard
}
82 776f2227 bellard
#else
83 776f2227 bellard
static inline long i2l(long v)
84 776f2227 bellard
{
85 776f2227 bellard
    return v;
86 776f2227 bellard
}
87 776f2227 bellard
#endif
88 776f2227 bellard
89 4d1135e4 bellard
#define OP add
90 4d1135e4 bellard
#include "test-i386.h"
91 4d1135e4 bellard
92 4d1135e4 bellard
#define OP sub
93 4d1135e4 bellard
#include "test-i386.h"
94 4d1135e4 bellard
95 4d1135e4 bellard
#define OP xor
96 4d1135e4 bellard
#include "test-i386.h"
97 4d1135e4 bellard
98 4d1135e4 bellard
#define OP and
99 4d1135e4 bellard
#include "test-i386.h"
100 4d1135e4 bellard
101 4d1135e4 bellard
#define OP or
102 4d1135e4 bellard
#include "test-i386.h"
103 4d1135e4 bellard
104 4d1135e4 bellard
#define OP cmp
105 4d1135e4 bellard
#include "test-i386.h"
106 4d1135e4 bellard
107 4d1135e4 bellard
#define OP adc
108 4d1135e4 bellard
#define OP_CC
109 4d1135e4 bellard
#include "test-i386.h"
110 4d1135e4 bellard
111 4d1135e4 bellard
#define OP sbb
112 4d1135e4 bellard
#define OP_CC
113 4d1135e4 bellard
#include "test-i386.h"
114 4d1135e4 bellard
115 4d1135e4 bellard
#define OP inc
116 4d1135e4 bellard
#define OP_CC
117 4d1135e4 bellard
#define OP1
118 4d1135e4 bellard
#include "test-i386.h"
119 4d1135e4 bellard
120 4d1135e4 bellard
#define OP dec
121 4d1135e4 bellard
#define OP_CC
122 4d1135e4 bellard
#define OP1
123 4d1135e4 bellard
#include "test-i386.h"
124 4d1135e4 bellard
125 4d1135e4 bellard
#define OP neg
126 4d1135e4 bellard
#define OP_CC
127 4d1135e4 bellard
#define OP1
128 4d1135e4 bellard
#include "test-i386.h"
129 4d1135e4 bellard
130 4d1135e4 bellard
#define OP not
131 4d1135e4 bellard
#define OP_CC
132 4d1135e4 bellard
#define OP1
133 4d1135e4 bellard
#include "test-i386.h"
134 4d1135e4 bellard
135 4b74fe1f bellard
#undef CC_MASK
136 4b74fe1f bellard
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O)
137 4b74fe1f bellard
138 379ca80d bellard
#define OP shl
139 379ca80d bellard
#include "test-i386-shift.h"
140 379ca80d bellard
141 379ca80d bellard
#define OP shr
142 379ca80d bellard
#include "test-i386-shift.h"
143 379ca80d bellard
144 379ca80d bellard
#define OP sar
145 379ca80d bellard
#include "test-i386-shift.h"
146 379ca80d bellard
147 379ca80d bellard
#define OP rol
148 379ca80d bellard
#include "test-i386-shift.h"
149 379ca80d bellard
150 379ca80d bellard
#define OP ror
151 379ca80d bellard
#include "test-i386-shift.h"
152 379ca80d bellard
153 379ca80d bellard
#define OP rcr
154 379ca80d bellard
#define OP_CC
155 379ca80d bellard
#include "test-i386-shift.h"
156 379ca80d bellard
157 379ca80d bellard
#define OP rcl
158 379ca80d bellard
#define OP_CC
159 379ca80d bellard
#include "test-i386-shift.h"
160 379ca80d bellard
161 d57c4e01 bellard
#define OP shld
162 d57c4e01 bellard
#define OP_SHIFTD
163 d57c4e01 bellard
#define OP_NOBYTE
164 d57c4e01 bellard
#include "test-i386-shift.h"
165 d57c4e01 bellard
166 d57c4e01 bellard
#define OP shrd
167 d57c4e01 bellard
#define OP_SHIFTD
168 d57c4e01 bellard
#define OP_NOBYTE
169 d57c4e01 bellard
#include "test-i386-shift.h"
170 d57c4e01 bellard
171 d57c4e01 bellard
/* XXX: should be more precise ? */
172 d57c4e01 bellard
#undef CC_MASK
173 d57c4e01 bellard
#define CC_MASK (CC_C)
174 d57c4e01 bellard
175 d57c4e01 bellard
#define OP bt
176 d57c4e01 bellard
#define OP_NOBYTE
177 d57c4e01 bellard
#include "test-i386-shift.h"
178 d57c4e01 bellard
179 d57c4e01 bellard
#define OP bts
180 d57c4e01 bellard
#define OP_NOBYTE
181 d57c4e01 bellard
#include "test-i386-shift.h"
182 d57c4e01 bellard
183 d57c4e01 bellard
#define OP btr
184 d57c4e01 bellard
#define OP_NOBYTE
185 d57c4e01 bellard
#include "test-i386-shift.h"
186 d57c4e01 bellard
187 d57c4e01 bellard
#define OP btc
188 d57c4e01 bellard
#define OP_NOBYTE
189 d57c4e01 bellard
#include "test-i386-shift.h"
190 379ca80d bellard
191 4d1135e4 bellard
/* lea test (modrm support) */
192 776f2227 bellard
#define TEST_LEAQ(STR)\
193 776f2227 bellard
{\
194 776f2227 bellard
    asm("lea " STR ", %0"\
195 776f2227 bellard
        : "=r" (res)\
196 776f2227 bellard
        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
197 776f2227 bellard
    printf("lea %s = " FMTLX "\n", STR, res);\
198 776f2227 bellard
}
199 776f2227 bellard
200 4d1135e4 bellard
#define TEST_LEA(STR)\
201 4d1135e4 bellard
{\
202 776f2227 bellard
    asm("lea " STR ", %0"\
203 4d1135e4 bellard
        : "=r" (res)\
204 4d1135e4 bellard
        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
205 776f2227 bellard
    printf("lea %s = " FMTLX "\n", STR, res);\
206 4d1135e4 bellard
}
207 4d1135e4 bellard
208 4d1135e4 bellard
#define TEST_LEA16(STR)\
209 4d1135e4 bellard
{\
210 4d1135e4 bellard
    asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\
211 4d1135e4 bellard
        : "=wq" (res)\
212 4d1135e4 bellard
        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
213 776f2227 bellard
    printf("lea %s = %08lx\n", STR, res);\
214 4d1135e4 bellard
}
215 4d1135e4 bellard
216 4d1135e4 bellard
217 4d1135e4 bellard
void test_lea(void)
218 4d1135e4 bellard
{
219 776f2227 bellard
    long eax, ebx, ecx, edx, esi, edi, res;
220 776f2227 bellard
    eax = i2l(0x0001);
221 776f2227 bellard
    ebx = i2l(0x0002);
222 776f2227 bellard
    ecx = i2l(0x0004);
223 776f2227 bellard
    edx = i2l(0x0008);
224 776f2227 bellard
    esi = i2l(0x0010);
225 776f2227 bellard
    edi = i2l(0x0020);
226 4d1135e4 bellard
227 4d1135e4 bellard
    TEST_LEA("0x4000");
228 4d1135e4 bellard
229 4d1135e4 bellard
    TEST_LEA("(%%eax)");
230 4d1135e4 bellard
    TEST_LEA("(%%ebx)");
231 4d1135e4 bellard
    TEST_LEA("(%%ecx)");
232 4d1135e4 bellard
    TEST_LEA("(%%edx)");
233 4d1135e4 bellard
    TEST_LEA("(%%esi)");
234 4d1135e4 bellard
    TEST_LEA("(%%edi)");
235 4d1135e4 bellard
236 4d1135e4 bellard
    TEST_LEA("0x40(%%eax)");
237 4d1135e4 bellard
    TEST_LEA("0x40(%%ebx)");
238 4d1135e4 bellard
    TEST_LEA("0x40(%%ecx)");
239 4d1135e4 bellard
    TEST_LEA("0x40(%%edx)");
240 4d1135e4 bellard
    TEST_LEA("0x40(%%esi)");
241 4d1135e4 bellard
    TEST_LEA("0x40(%%edi)");
242 4d1135e4 bellard
243 4d1135e4 bellard
    TEST_LEA("0x4000(%%eax)");
244 4d1135e4 bellard
    TEST_LEA("0x4000(%%ebx)");
245 4d1135e4 bellard
    TEST_LEA("0x4000(%%ecx)");
246 4d1135e4 bellard
    TEST_LEA("0x4000(%%edx)");
247 4d1135e4 bellard
    TEST_LEA("0x4000(%%esi)");
248 4d1135e4 bellard
    TEST_LEA("0x4000(%%edi)");
249 4d1135e4 bellard
250 4d1135e4 bellard
    TEST_LEA("(%%eax, %%ecx)");
251 4d1135e4 bellard
    TEST_LEA("(%%ebx, %%edx)");
252 4d1135e4 bellard
    TEST_LEA("(%%ecx, %%ecx)");
253 4d1135e4 bellard
    TEST_LEA("(%%edx, %%ecx)");
254 4d1135e4 bellard
    TEST_LEA("(%%esi, %%ecx)");
255 4d1135e4 bellard
    TEST_LEA("(%%edi, %%ecx)");
256 4d1135e4 bellard
257 4d1135e4 bellard
    TEST_LEA("0x40(%%eax, %%ecx)");
258 4d1135e4 bellard
    TEST_LEA("0x4000(%%ebx, %%edx)");
259 4d1135e4 bellard
260 4d1135e4 bellard
    TEST_LEA("(%%ecx, %%ecx, 2)");
261 4d1135e4 bellard
    TEST_LEA("(%%edx, %%ecx, 4)");
262 4d1135e4 bellard
    TEST_LEA("(%%esi, %%ecx, 8)");
263 4d1135e4 bellard
264 4d1135e4 bellard
    TEST_LEA("(,%%eax, 2)");
265 4d1135e4 bellard
    TEST_LEA("(,%%ebx, 4)");
266 4d1135e4 bellard
    TEST_LEA("(,%%ecx, 8)");
267 4d1135e4 bellard
268 4d1135e4 bellard
    TEST_LEA("0x40(,%%eax, 2)");
269 4d1135e4 bellard
    TEST_LEA("0x40(,%%ebx, 4)");
270 4d1135e4 bellard
    TEST_LEA("0x40(,%%ecx, 8)");
271 4d1135e4 bellard
272 4d1135e4 bellard
273 4d1135e4 bellard
    TEST_LEA("-10(%%ecx, %%ecx, 2)");
274 4d1135e4 bellard
    TEST_LEA("-10(%%edx, %%ecx, 4)");
275 4d1135e4 bellard
    TEST_LEA("-10(%%esi, %%ecx, 8)");
276 4d1135e4 bellard
277 4d1135e4 bellard
    TEST_LEA("0x4000(%%ecx, %%ecx, 2)");
278 4d1135e4 bellard
    TEST_LEA("0x4000(%%edx, %%ecx, 4)");
279 4d1135e4 bellard
    TEST_LEA("0x4000(%%esi, %%ecx, 8)");
280 4d1135e4 bellard
281 776f2227 bellard
#if defined(__x86_64__)
282 776f2227 bellard
    TEST_LEAQ("0x4000");
283 776f2227 bellard
    TEST_LEAQ("0x4000(%%rip)");
284 776f2227 bellard
285 776f2227 bellard
    TEST_LEAQ("(%%rax)");
286 776f2227 bellard
    TEST_LEAQ("(%%rbx)");
287 776f2227 bellard
    TEST_LEAQ("(%%rcx)");
288 776f2227 bellard
    TEST_LEAQ("(%%rdx)");
289 776f2227 bellard
    TEST_LEAQ("(%%rsi)");
290 776f2227 bellard
    TEST_LEAQ("(%%rdi)");
291 776f2227 bellard
292 776f2227 bellard
    TEST_LEAQ("0x40(%%rax)");
293 776f2227 bellard
    TEST_LEAQ("0x40(%%rbx)");
294 776f2227 bellard
    TEST_LEAQ("0x40(%%rcx)");
295 776f2227 bellard
    TEST_LEAQ("0x40(%%rdx)");
296 776f2227 bellard
    TEST_LEAQ("0x40(%%rsi)");
297 776f2227 bellard
    TEST_LEAQ("0x40(%%rdi)");
298 776f2227 bellard
299 776f2227 bellard
    TEST_LEAQ("0x4000(%%rax)");
300 776f2227 bellard
    TEST_LEAQ("0x4000(%%rbx)");
301 776f2227 bellard
    TEST_LEAQ("0x4000(%%rcx)");
302 776f2227 bellard
    TEST_LEAQ("0x4000(%%rdx)");
303 776f2227 bellard
    TEST_LEAQ("0x4000(%%rsi)");
304 776f2227 bellard
    TEST_LEAQ("0x4000(%%rdi)");
305 776f2227 bellard
306 776f2227 bellard
    TEST_LEAQ("(%%rax, %%rcx)");
307 776f2227 bellard
    TEST_LEAQ("(%%rbx, %%rdx)");
308 776f2227 bellard
    TEST_LEAQ("(%%rcx, %%rcx)");
309 776f2227 bellard
    TEST_LEAQ("(%%rdx, %%rcx)");
310 776f2227 bellard
    TEST_LEAQ("(%%rsi, %%rcx)");
311 776f2227 bellard
    TEST_LEAQ("(%%rdi, %%rcx)");
312 776f2227 bellard
313 776f2227 bellard
    TEST_LEAQ("0x40(%%rax, %%rcx)");
314 776f2227 bellard
    TEST_LEAQ("0x4000(%%rbx, %%rdx)");
315 776f2227 bellard
316 776f2227 bellard
    TEST_LEAQ("(%%rcx, %%rcx, 2)");
317 776f2227 bellard
    TEST_LEAQ("(%%rdx, %%rcx, 4)");
318 776f2227 bellard
    TEST_LEAQ("(%%rsi, %%rcx, 8)");
319 776f2227 bellard
320 776f2227 bellard
    TEST_LEAQ("(,%%rax, 2)");
321 776f2227 bellard
    TEST_LEAQ("(,%%rbx, 4)");
322 776f2227 bellard
    TEST_LEAQ("(,%%rcx, 8)");
323 776f2227 bellard
324 776f2227 bellard
    TEST_LEAQ("0x40(,%%rax, 2)");
325 776f2227 bellard
    TEST_LEAQ("0x40(,%%rbx, 4)");
326 776f2227 bellard
    TEST_LEAQ("0x40(,%%rcx, 8)");
327 776f2227 bellard
328 776f2227 bellard
329 776f2227 bellard
    TEST_LEAQ("-10(%%rcx, %%rcx, 2)");
330 776f2227 bellard
    TEST_LEAQ("-10(%%rdx, %%rcx, 4)");
331 776f2227 bellard
    TEST_LEAQ("-10(%%rsi, %%rcx, 8)");
332 776f2227 bellard
333 776f2227 bellard
    TEST_LEAQ("0x4000(%%rcx, %%rcx, 2)");
334 776f2227 bellard
    TEST_LEAQ("0x4000(%%rdx, %%rcx, 4)");
335 776f2227 bellard
    TEST_LEAQ("0x4000(%%rsi, %%rcx, 8)");
336 776f2227 bellard
#else
337 4d1135e4 bellard
    /* limited 16 bit addressing test */
338 4d1135e4 bellard
    TEST_LEA16("0x4000");
339 4d1135e4 bellard
    TEST_LEA16("(%%bx)");
340 4d1135e4 bellard
    TEST_LEA16("(%%si)");
341 4d1135e4 bellard
    TEST_LEA16("(%%di)");
342 4d1135e4 bellard
    TEST_LEA16("0x40(%%bx)");
343 4d1135e4 bellard
    TEST_LEA16("0x40(%%si)");
344 4d1135e4 bellard
    TEST_LEA16("0x40(%%di)");
345 4d1135e4 bellard
    TEST_LEA16("0x4000(%%bx)");
346 4d1135e4 bellard
    TEST_LEA16("0x4000(%%si)");
347 4d1135e4 bellard
    TEST_LEA16("(%%bx,%%si)");
348 4d1135e4 bellard
    TEST_LEA16("(%%bx,%%di)");
349 4d1135e4 bellard
    TEST_LEA16("0x40(%%bx,%%si)");
350 4d1135e4 bellard
    TEST_LEA16("0x40(%%bx,%%di)");
351 4d1135e4 bellard
    TEST_LEA16("0x4000(%%bx,%%si)");
352 4d1135e4 bellard
    TEST_LEA16("0x4000(%%bx,%%di)");
353 776f2227 bellard
#endif
354 4d1135e4 bellard
}
355 4d1135e4 bellard
356 4d1135e4 bellard
#define TEST_JCC(JCC, v1, v2)\
357 4d1135e4 bellard
{\
358 5dd9488c bellard
    int res;\
359 4d1135e4 bellard
    asm("movl $1, %0\n\t"\
360 4d1135e4 bellard
        "cmpl %2, %1\n\t"\
361 5dd9488c bellard
        "j" JCC " 1f\n\t"\
362 4d1135e4 bellard
        "movl $0, %0\n\t"\
363 4d1135e4 bellard
        "1:\n\t"\
364 4d1135e4 bellard
        : "=r" (res)\
365 4d1135e4 bellard
        : "r" (v1), "r" (v2));\
366 5dd9488c bellard
    printf("%-10s %d\n", "j" JCC, res);\
367 5dd9488c bellard
\
368 5dd9488c bellard
    asm("movl $0, %0\n\t"\
369 5dd9488c bellard
        "cmpl %2, %1\n\t"\
370 5dd9488c bellard
        "set" JCC " %b0\n\t"\
371 5dd9488c bellard
        : "=r" (res)\
372 5dd9488c bellard
        : "r" (v1), "r" (v2));\
373 5dd9488c bellard
    printf("%-10s %d\n", "set" JCC, res);\
374 5dd9488c bellard
 if (TEST_CMOV) {\
375 776f2227 bellard
    long val = i2l(1);\
376 776f2227 bellard
    long res = i2l(0x12345678);\
377 776f2227 bellard
X86_64_ONLY(\
378 776f2227 bellard
    asm("cmpl %2, %1\n\t"\
379 776f2227 bellard
        "cmov" JCC "q %3, %0\n\t"\
380 5dd9488c bellard
        : "=r" (res)\
381 776f2227 bellard
        : "r" (v1), "r" (v2), "m" (val), "0" (res));\
382 d057099a bellard
        printf("%-10s R=" FMTLX "\n", "cmov" JCC "q", res);)\
383 776f2227 bellard
    asm("cmpl %2, %1\n\t"\
384 776f2227 bellard
        "cmov" JCC "l %k3, %k0\n\t"\
385 776f2227 bellard
        : "=r" (res)\
386 776f2227 bellard
        : "r" (v1), "r" (v2), "m" (val), "0" (res));\
387 776f2227 bellard
        printf("%-10s R=" FMTLX "\n", "cmov" JCC "l", res);\
388 776f2227 bellard
    asm("cmpl %2, %1\n\t"\
389 5dd9488c bellard
        "cmov" JCC "w %w3, %w0\n\t"\
390 5dd9488c bellard
        : "=r" (res)\
391 776f2227 bellard
        : "r" (v1), "r" (v2), "r" (1), "0" (res));\
392 776f2227 bellard
        printf("%-10s R=" FMTLX "\n", "cmov" JCC "w", res);\
393 5dd9488c bellard
 } \
394 4d1135e4 bellard
}
395 4d1135e4 bellard
396 4d1135e4 bellard
/* various jump tests */
397 4d1135e4 bellard
void test_jcc(void)
398 4d1135e4 bellard
{
399 5dd9488c bellard
    TEST_JCC("ne", 1, 1);
400 5dd9488c bellard
    TEST_JCC("ne", 1, 0);
401 4d1135e4 bellard
402 5dd9488c bellard
    TEST_JCC("e", 1, 1);
403 5dd9488c bellard
    TEST_JCC("e", 1, 0);
404 4d1135e4 bellard
405 5dd9488c bellard
    TEST_JCC("l", 1, 1);
406 5dd9488c bellard
    TEST_JCC("l", 1, 0);
407 5dd9488c bellard
    TEST_JCC("l", 1, -1);
408 4d1135e4 bellard
409 5dd9488c bellard
    TEST_JCC("le", 1, 1);
410 5dd9488c bellard
    TEST_JCC("le", 1, 0);
411 5dd9488c bellard
    TEST_JCC("le", 1, -1);
412 4d1135e4 bellard
413 5dd9488c bellard
    TEST_JCC("ge", 1, 1);
414 5dd9488c bellard
    TEST_JCC("ge", 1, 0);
415 5dd9488c bellard
    TEST_JCC("ge", -1, 1);
416 4d1135e4 bellard
417 5dd9488c bellard
    TEST_JCC("g", 1, 1);
418 5dd9488c bellard
    TEST_JCC("g", 1, 0);
419 5dd9488c bellard
    TEST_JCC("g", 1, -1);
420 4d1135e4 bellard
421 5dd9488c bellard
    TEST_JCC("b", 1, 1);
422 5dd9488c bellard
    TEST_JCC("b", 1, 0);
423 5dd9488c bellard
    TEST_JCC("b", 1, -1);
424 4d1135e4 bellard
425 5dd9488c bellard
    TEST_JCC("be", 1, 1);
426 5dd9488c bellard
    TEST_JCC("be", 1, 0);
427 5dd9488c bellard
    TEST_JCC("be", 1, -1);
428 4d1135e4 bellard
429 5dd9488c bellard
    TEST_JCC("ae", 1, 1);
430 5dd9488c bellard
    TEST_JCC("ae", 1, 0);
431 5dd9488c bellard
    TEST_JCC("ae", 1, -1);
432 4d1135e4 bellard
433 5dd9488c bellard
    TEST_JCC("a", 1, 1);
434 5dd9488c bellard
    TEST_JCC("a", 1, 0);
435 5dd9488c bellard
    TEST_JCC("a", 1, -1);
436 4d1135e4 bellard
437 4d1135e4 bellard
438 5dd9488c bellard
    TEST_JCC("p", 1, 1);
439 5dd9488c bellard
    TEST_JCC("p", 1, 0);
440 4d1135e4 bellard
441 5dd9488c bellard
    TEST_JCC("np", 1, 1);
442 5dd9488c bellard
    TEST_JCC("np", 1, 0);
443 4d1135e4 bellard
444 5dd9488c bellard
    TEST_JCC("o", 0x7fffffff, 0);
445 5dd9488c bellard
    TEST_JCC("o", 0x7fffffff, -1);
446 4d1135e4 bellard
447 5dd9488c bellard
    TEST_JCC("no", 0x7fffffff, 0);
448 5dd9488c bellard
    TEST_JCC("no", 0x7fffffff, -1);
449 4d1135e4 bellard
450 5dd9488c bellard
    TEST_JCC("s", 0, 1);
451 5dd9488c bellard
    TEST_JCC("s", 0, -1);
452 5dd9488c bellard
    TEST_JCC("s", 0, 0);
453 4d1135e4 bellard
454 5dd9488c bellard
    TEST_JCC("ns", 0, 1);
455 5dd9488c bellard
    TEST_JCC("ns", 0, -1);
456 5dd9488c bellard
    TEST_JCC("ns", 0, 0);
457 4d1135e4 bellard
}
458 4d1135e4 bellard
459 a5973fbf bellard
#define TEST_LOOP(insn) \
460 a5973fbf bellard
{\
461 a5973fbf bellard
    for(i = 0; i < sizeof(ecx_vals) / sizeof(long); i++) {\
462 a5973fbf bellard
        ecx = ecx_vals[i];\
463 a5973fbf bellard
        for(zf = 0; zf < 2; zf++) {\
464 a5973fbf bellard
    asm("test %2, %2\n\t"\
465 a5973fbf bellard
        "movl $1, %0\n\t"\
466 a5973fbf bellard
          insn " 1f\n\t" \
467 a5973fbf bellard
        "movl $0, %0\n\t"\
468 a5973fbf bellard
        "1:\n\t"\
469 a5973fbf bellard
        : "=a" (res)\
470 a5973fbf bellard
        : "c" (ecx), "b" (!zf)); \
471 a5973fbf bellard
    printf("%-10s ECX=" FMTLX " ZF=%ld r=%d\n", insn, ecx, zf, res);      \
472 a5973fbf bellard
        }\
473 a5973fbf bellard
   }\
474 a5973fbf bellard
}
475 a5973fbf bellard
476 a5973fbf bellard
void test_loop(void)
477 a5973fbf bellard
{
478 a5973fbf bellard
    long ecx, zf;
479 a5973fbf bellard
    const long ecx_vals[] = {
480 a5973fbf bellard
        0,
481 a5973fbf bellard
        1,
482 a5973fbf bellard
        0x10000,
483 a5973fbf bellard
        0x10001,
484 a5973fbf bellard
#if defined(__x86_64__)
485 a5973fbf bellard
        0x100000000L,
486 a5973fbf bellard
        0x100000001L,
487 a5973fbf bellard
#endif
488 a5973fbf bellard
    };
489 a5973fbf bellard
    int i, res;
490 a5973fbf bellard
491 872ea0c0 balrog
#if !defined(__x86_64__)
492 a5973fbf bellard
    TEST_LOOP("jcxz");
493 a5973fbf bellard
    TEST_LOOP("loopw");
494 a5973fbf bellard
    TEST_LOOP("loopzw");
495 a5973fbf bellard
    TEST_LOOP("loopnzw");
496 872ea0c0 balrog
#endif
497 a5973fbf bellard
498 a5973fbf bellard
    TEST_LOOP("jecxz");
499 a5973fbf bellard
    TEST_LOOP("loopl");
500 a5973fbf bellard
    TEST_LOOP("loopzl");
501 a5973fbf bellard
    TEST_LOOP("loopnzl");
502 a5973fbf bellard
}
503 a5973fbf bellard
504 4b74fe1f bellard
#undef CC_MASK
505 791c2261 bellard
#ifdef TEST_P4_FLAGS
506 791c2261 bellard
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
507 791c2261 bellard
#else
508 4b74fe1f bellard
#define CC_MASK (CC_O | CC_C)
509 791c2261 bellard
#endif
510 4b74fe1f bellard
511 4b74fe1f bellard
#define OP mul
512 4b74fe1f bellard
#include "test-i386-muldiv.h"
513 4b74fe1f bellard
514 4b74fe1f bellard
#define OP imul
515 4b74fe1f bellard
#include "test-i386-muldiv.h"
516 4b74fe1f bellard
517 5fafdf24 ths
void test_imulw2(long op0, long op1)
518 4b74fe1f bellard
{
519 776f2227 bellard
    long res, s1, s0, flags;
520 4b74fe1f bellard
    s0 = op0;
521 4b74fe1f bellard
    s1 = op1;
522 4b74fe1f bellard
    res = s0;
523 4b74fe1f bellard
    flags = 0;
524 acae4681 bellard
    asm volatile ("push %4\n\t"
525 4b74fe1f bellard
         "popf\n\t"
526 5fafdf24 ths
         "imulw %w2, %w0\n\t"
527 4b74fe1f bellard
         "pushf\n\t"
528 776f2227 bellard
         "pop %1\n\t"
529 4b74fe1f bellard
         : "=q" (res), "=g" (flags)
530 4b74fe1f bellard
         : "q" (s1), "0" (res), "1" (flags));
531 776f2227 bellard
    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
532 4b74fe1f bellard
           "imulw", s0, s1, res, flags & CC_MASK);
533 4b74fe1f bellard
}
534 4b74fe1f bellard
535 5fafdf24 ths
void test_imull2(long op0, long op1)
536 4b74fe1f bellard
{
537 776f2227 bellard
    long res, s1, s0, flags;
538 4b74fe1f bellard
    s0 = op0;
539 4b74fe1f bellard
    s1 = op1;
540 4b74fe1f bellard
    res = s0;
541 4b74fe1f bellard
    flags = 0;
542 acae4681 bellard
    asm volatile ("push %4\n\t"
543 4b74fe1f bellard
         "popf\n\t"
544 5fafdf24 ths
         "imull %k2, %k0\n\t"
545 4b74fe1f bellard
         "pushf\n\t"
546 776f2227 bellard
         "pop %1\n\t"
547 4b74fe1f bellard
         : "=q" (res), "=g" (flags)
548 4b74fe1f bellard
         : "q" (s1), "0" (res), "1" (flags));
549 776f2227 bellard
    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
550 4b74fe1f bellard
           "imull", s0, s1, res, flags & CC_MASK);
551 4b74fe1f bellard
}
552 4b74fe1f bellard
553 776f2227 bellard
#if defined(__x86_64__)
554 5fafdf24 ths
void test_imulq2(long op0, long op1)
555 776f2227 bellard
{
556 776f2227 bellard
    long res, s1, s0, flags;
557 776f2227 bellard
    s0 = op0;
558 776f2227 bellard
    s1 = op1;
559 776f2227 bellard
    res = s0;
560 776f2227 bellard
    flags = 0;
561 776f2227 bellard
    asm volatile ("push %4\n\t"
562 776f2227 bellard
         "popf\n\t"
563 5fafdf24 ths
         "imulq %2, %0\n\t"
564 776f2227 bellard
         "pushf\n\t"
565 776f2227 bellard
         "pop %1\n\t"
566 776f2227 bellard
         : "=q" (res), "=g" (flags)
567 776f2227 bellard
         : "q" (s1), "0" (res), "1" (flags));
568 776f2227 bellard
    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
569 776f2227 bellard
           "imulq", s0, s1, res, flags & CC_MASK);
570 776f2227 bellard
}
571 776f2227 bellard
#endif
572 776f2227 bellard
573 776f2227 bellard
#define TEST_IMUL_IM(size, rsize, op0, op1)\
574 b5075d29 bellard
{\
575 776f2227 bellard
    long res, flags, s1;\
576 b5075d29 bellard
    flags = 0;\
577 b5075d29 bellard
    res = 0;\
578 776f2227 bellard
    s1 = op1;\
579 acae4681 bellard
    asm volatile ("push %3\n\t"\
580 b5075d29 bellard
         "popf\n\t"\
581 776f2227 bellard
         "imul" size " $" #op0 ", %" rsize "2, %" rsize "0\n\t" \
582 b5075d29 bellard
         "pushf\n\t"\
583 776f2227 bellard
         "pop %1\n\t"\
584 b5075d29 bellard
         : "=r" (res), "=g" (flags)\
585 776f2227 bellard
         : "r" (s1), "1" (flags), "0" (res));\
586 776f2227 bellard
    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",\
587 776f2227 bellard
           "imul" size " im", (long)op0, (long)op1, res, flags & CC_MASK);\
588 b5075d29 bellard
}
589 b5075d29 bellard
590 b5075d29 bellard
591 791c2261 bellard
#undef CC_MASK
592 791c2261 bellard
#define CC_MASK (0)
593 791c2261 bellard
594 791c2261 bellard
#define OP div
595 791c2261 bellard
#include "test-i386-muldiv.h"
596 791c2261 bellard
597 791c2261 bellard
#define OP idiv
598 791c2261 bellard
#include "test-i386-muldiv.h"
599 791c2261 bellard
600 4b74fe1f bellard
void test_mul(void)
601 4b74fe1f bellard
{
602 4b74fe1f bellard
    test_imulb(0x1234561d, 4);
603 4b74fe1f bellard
    test_imulb(3, -4);
604 4b74fe1f bellard
    test_imulb(0x80, 0x80);
605 4b74fe1f bellard
    test_imulb(0x10, 0x10);
606 4b74fe1f bellard
607 4b74fe1f bellard
    test_imulw(0, 0x1234001d, 45);
608 4b74fe1f bellard
    test_imulw(0, 23, -45);
609 4b74fe1f bellard
    test_imulw(0, 0x8000, 0x8000);
610 4b74fe1f bellard
    test_imulw(0, 0x100, 0x100);
611 4b74fe1f bellard
612 4b74fe1f bellard
    test_imull(0, 0x1234001d, 45);
613 4b74fe1f bellard
    test_imull(0, 23, -45);
614 4b74fe1f bellard
    test_imull(0, 0x80000000, 0x80000000);
615 4b74fe1f bellard
    test_imull(0, 0x10000, 0x10000);
616 4b74fe1f bellard
617 4b74fe1f bellard
    test_mulb(0x1234561d, 4);
618 4b74fe1f bellard
    test_mulb(3, -4);
619 4b74fe1f bellard
    test_mulb(0x80, 0x80);
620 4b74fe1f bellard
    test_mulb(0x10, 0x10);
621 4b74fe1f bellard
622 4b74fe1f bellard
    test_mulw(0, 0x1234001d, 45);
623 4b74fe1f bellard
    test_mulw(0, 23, -45);
624 4b74fe1f bellard
    test_mulw(0, 0x8000, 0x8000);
625 4b74fe1f bellard
    test_mulw(0, 0x100, 0x100);
626 4b74fe1f bellard
627 4b74fe1f bellard
    test_mull(0, 0x1234001d, 45);
628 4b74fe1f bellard
    test_mull(0, 23, -45);
629 4b74fe1f bellard
    test_mull(0, 0x80000000, 0x80000000);
630 4b74fe1f bellard
    test_mull(0, 0x10000, 0x10000);
631 4b74fe1f bellard
632 4b74fe1f bellard
    test_imulw2(0x1234001d, 45);
633 4b74fe1f bellard
    test_imulw2(23, -45);
634 4b74fe1f bellard
    test_imulw2(0x8000, 0x8000);
635 4b74fe1f bellard
    test_imulw2(0x100, 0x100);
636 4b74fe1f bellard
637 4b74fe1f bellard
    test_imull2(0x1234001d, 45);
638 4b74fe1f bellard
    test_imull2(23, -45);
639 4b74fe1f bellard
    test_imull2(0x80000000, 0x80000000);
640 4b74fe1f bellard
    test_imull2(0x10000, 0x10000);
641 4b74fe1f bellard
642 b5075d29 bellard
    TEST_IMUL_IM("w", "w", 45, 0x1234);
643 b5075d29 bellard
    TEST_IMUL_IM("w", "w", -45, 23);
644 b5075d29 bellard
    TEST_IMUL_IM("w", "w", 0x8000, 0x80000000);
645 b5075d29 bellard
    TEST_IMUL_IM("w", "w", 0x7fff, 0x1000);
646 b5075d29 bellard
647 776f2227 bellard
    TEST_IMUL_IM("l", "k", 45, 0x1234);
648 776f2227 bellard
    TEST_IMUL_IM("l", "k", -45, 23);
649 776f2227 bellard
    TEST_IMUL_IM("l", "k", 0x8000, 0x80000000);
650 776f2227 bellard
    TEST_IMUL_IM("l", "k", 0x7fff, 0x1000);
651 b5075d29 bellard
652 4b74fe1f bellard
    test_idivb(0x12341678, 0x127e);
653 4b74fe1f bellard
    test_idivb(0x43210123, -5);
654 4b74fe1f bellard
    test_idivb(0x12340004, -1);
655 4b74fe1f bellard
656 4b74fe1f bellard
    test_idivw(0, 0x12345678, 12347);
657 4b74fe1f bellard
    test_idivw(0, -23223, -45);
658 4b74fe1f bellard
    test_idivw(0, 0x12348000, -1);
659 4b74fe1f bellard
    test_idivw(0x12343, 0x12345678, 0x81238567);
660 4b74fe1f bellard
661 4b74fe1f bellard
    test_idivl(0, 0x12345678, 12347);
662 4b74fe1f bellard
    test_idivl(0, -233223, -45);
663 4b74fe1f bellard
    test_idivl(0, 0x80000000, -1);
664 4b74fe1f bellard
    test_idivl(0x12343, 0x12345678, 0x81234567);
665 4b74fe1f bellard
666 4b74fe1f bellard
    test_divb(0x12341678, 0x127e);
667 4b74fe1f bellard
    test_divb(0x43210123, -5);
668 4b74fe1f bellard
    test_divb(0x12340004, -1);
669 4b74fe1f bellard
670 4b74fe1f bellard
    test_divw(0, 0x12345678, 12347);
671 4b74fe1f bellard
    test_divw(0, -23223, -45);
672 4b74fe1f bellard
    test_divw(0, 0x12348000, -1);
673 4b74fe1f bellard
    test_divw(0x12343, 0x12345678, 0x81238567);
674 4b74fe1f bellard
675 4b74fe1f bellard
    test_divl(0, 0x12345678, 12347);
676 4b74fe1f bellard
    test_divl(0, -233223, -45);
677 4b74fe1f bellard
    test_divl(0, 0x80000000, -1);
678 4b74fe1f bellard
    test_divl(0x12343, 0x12345678, 0x81234567);
679 776f2227 bellard
680 776f2227 bellard
#if defined(__x86_64__)
681 776f2227 bellard
    test_imulq(0, 0x1234001d1234001d, 45);
682 776f2227 bellard
    test_imulq(0, 23, -45);
683 776f2227 bellard
    test_imulq(0, 0x8000000000000000, 0x8000000000000000);
684 776f2227 bellard
    test_imulq(0, 0x100000000, 0x100000000);
685 776f2227 bellard
686 776f2227 bellard
    test_mulq(0, 0x1234001d1234001d, 45);
687 776f2227 bellard
    test_mulq(0, 23, -45);
688 776f2227 bellard
    test_mulq(0, 0x8000000000000000, 0x8000000000000000);
689 776f2227 bellard
    test_mulq(0, 0x100000000, 0x100000000);
690 776f2227 bellard
691 776f2227 bellard
    test_imulq2(0x1234001d1234001d, 45);
692 776f2227 bellard
    test_imulq2(23, -45);
693 776f2227 bellard
    test_imulq2(0x8000000000000000, 0x8000000000000000);
694 776f2227 bellard
    test_imulq2(0x100000000, 0x100000000);
695 776f2227 bellard
696 776f2227 bellard
    TEST_IMUL_IM("q", "", 45, 0x12341234);
697 776f2227 bellard
    TEST_IMUL_IM("q", "", -45, 23);
698 776f2227 bellard
    TEST_IMUL_IM("q", "", 0x8000, 0x8000000000000000);
699 776f2227 bellard
    TEST_IMUL_IM("q", "", 0x7fff, 0x10000000);
700 776f2227 bellard
701 776f2227 bellard
    test_idivq(0, 0x12345678abcdef, 12347);
702 776f2227 bellard
    test_idivq(0, -233223, -45);
703 776f2227 bellard
    test_idivq(0, 0x8000000000000000, -1);
704 776f2227 bellard
    test_idivq(0x12343, 0x12345678, 0x81234567);
705 776f2227 bellard
706 776f2227 bellard
    test_divq(0, 0x12345678abcdef, 12347);
707 776f2227 bellard
    test_divq(0, -233223, -45);
708 776f2227 bellard
    test_divq(0, 0x8000000000000000, -1);
709 776f2227 bellard
    test_divq(0x12343, 0x12345678, 0x81234567);
710 776f2227 bellard
#endif
711 4b74fe1f bellard
}
712 4b74fe1f bellard
713 9d8e9c09 bellard
#define TEST_BSX(op, size, op0)\
714 9d8e9c09 bellard
{\
715 776f2227 bellard
    long res, val, resz;\
716 9d8e9c09 bellard
    val = op0;\
717 776f2227 bellard
    asm("xor %1, %1\n"\
718 776f2227 bellard
        "mov $0x12345678, %0\n"\
719 7f5e1452 bellard
        #op " %" size "2, %" size "0 ; setz %b1" \
720 7058bfa6 balrog
        : "=&r" (res), "=&q" (resz)\
721 7058bfa6 balrog
        : "r" (val));\
722 776f2227 bellard
    printf("%-10s A=" FMTLX " R=" FMTLX " %ld\n", #op, val, res, resz);\
723 9d8e9c09 bellard
}
724 9d8e9c09 bellard
725 9d8e9c09 bellard
void test_bsx(void)
726 9d8e9c09 bellard
{
727 9d8e9c09 bellard
    TEST_BSX(bsrw, "w", 0);
728 9d8e9c09 bellard
    TEST_BSX(bsrw, "w", 0x12340128);
729 9d8e9c09 bellard
    TEST_BSX(bsfw, "w", 0);
730 9d8e9c09 bellard
    TEST_BSX(bsfw, "w", 0x12340128);
731 776f2227 bellard
    TEST_BSX(bsrl, "k", 0);
732 776f2227 bellard
    TEST_BSX(bsrl, "k", 0x00340128);
733 776f2227 bellard
    TEST_BSX(bsfl, "k", 0);
734 776f2227 bellard
    TEST_BSX(bsfl, "k", 0x00340128);
735 776f2227 bellard
#if defined(__x86_64__)
736 776f2227 bellard
    TEST_BSX(bsrq, "", 0);
737 776f2227 bellard
    TEST_BSX(bsrq, "", 0x003401281234);
738 776f2227 bellard
    TEST_BSX(bsfq, "", 0);
739 776f2227 bellard
    TEST_BSX(bsfq, "", 0x003401281234);
740 776f2227 bellard
#endif
741 9d8e9c09 bellard
}
742 9d8e9c09 bellard
743 55480af8 bellard
/**********************************************/
744 55480af8 bellard
745 86bd2ca5 bellard
union float64u {
746 86bd2ca5 bellard
    double d;
747 86bd2ca5 bellard
    uint64_t l;
748 86bd2ca5 bellard
};
749 86bd2ca5 bellard
750 be98f1f8 bellard
union float64u q_nan = { .l = 0xFFF8000000000000LL };
751 be98f1f8 bellard
union float64u s_nan = { .l = 0xFFF0000000000000LL };
752 86bd2ca5 bellard
753 9d8e9c09 bellard
void test_fops(double a, double b)
754 9d8e9c09 bellard
{
755 9d8e9c09 bellard
    printf("a=%f b=%f a+b=%f\n", a, b, a + b);
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 fmod(a, b)=%f\n", a, b, fmod(a, b));
760 9d8e9c09 bellard
    printf("a=%f sqrt(a)=%f\n", a, sqrt(a));
761 9d8e9c09 bellard
    printf("a=%f sin(a)=%f\n", a, sin(a));
762 9d8e9c09 bellard
    printf("a=%f cos(a)=%f\n", a, cos(a));
763 9d8e9c09 bellard
    printf("a=%f tan(a)=%f\n", a, tan(a));
764 9d8e9c09 bellard
    printf("a=%f log(a)=%f\n", a, log(a));
765 9d8e9c09 bellard
    printf("a=%f exp(a)=%f\n", a, exp(a));
766 9d8e9c09 bellard
    printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b));
767 9d8e9c09 bellard
    /* just to test some op combining */
768 9d8e9c09 bellard
    printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a)));
769 9d8e9c09 bellard
    printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a)));
770 9d8e9c09 bellard
    printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a)));
771 9d8e9c09 bellard
772 9d8e9c09 bellard
}
773 9d8e9c09 bellard
774 86bd2ca5 bellard
void fpu_clear_exceptions(void)
775 86bd2ca5 bellard
{
776 541dc0d4 Stefan Weil
    struct QEMU_PACKED {
777 86bd2ca5 bellard
        uint16_t fpuc;
778 86bd2ca5 bellard
        uint16_t dummy1;
779 86bd2ca5 bellard
        uint16_t fpus;
780 86bd2ca5 bellard
        uint16_t dummy2;
781 86bd2ca5 bellard
        uint16_t fptag;
782 86bd2ca5 bellard
        uint16_t dummy3;
783 86bd2ca5 bellard
        uint32_t ignored[4];
784 86bd2ca5 bellard
        long double fpregs[8];
785 86bd2ca5 bellard
    } float_env32;
786 3b46e624 ths
787 86bd2ca5 bellard
    asm volatile ("fnstenv %0\n" : : "m" (float_env32));
788 86bd2ca5 bellard
    float_env32.fpus &= ~0x7f;
789 86bd2ca5 bellard
    asm volatile ("fldenv %0\n" : : "m" (float_env32));
790 86bd2ca5 bellard
}
791 86bd2ca5 bellard
792 86bd2ca5 bellard
/* XXX: display exception bits when supported */
793 86bd2ca5 bellard
#define FPUS_EMASK 0x0000
794 86bd2ca5 bellard
//#define FPUS_EMASK 0x007f
795 86bd2ca5 bellard
796 9d8e9c09 bellard
void test_fcmp(double a, double b)
797 9d8e9c09 bellard
{
798 86bd2ca5 bellard
    long eflags, fpus;
799 86bd2ca5 bellard
800 86bd2ca5 bellard
    fpu_clear_exceptions();
801 86bd2ca5 bellard
    asm("fcom %2\n"
802 86bd2ca5 bellard
        "fstsw %%ax\n"
803 86bd2ca5 bellard
        : "=a" (fpus)
804 86bd2ca5 bellard
        : "t" (a), "u" (b));
805 b2bedb21 Stefan Weil
    printf("fcom(%f %f)=%04lx\n",
806 86bd2ca5 bellard
           a, b, fpus & (0x4500 | FPUS_EMASK));
807 86bd2ca5 bellard
    fpu_clear_exceptions();
808 86bd2ca5 bellard
    asm("fucom %2\n"
809 86bd2ca5 bellard
        "fstsw %%ax\n"
810 86bd2ca5 bellard
        : "=a" (fpus)
811 86bd2ca5 bellard
        : "t" (a), "u" (b));
812 5fafdf24 ths
    printf("fucom(%f %f)=%04lx\n",
813 86bd2ca5 bellard
           a, b, fpus & (0x4500 | FPUS_EMASK));
814 03bfca94 bellard
    if (TEST_FCOMI) {
815 03bfca94 bellard
        /* test f(u)comi instruction */
816 86bd2ca5 bellard
        fpu_clear_exceptions();
817 86bd2ca5 bellard
        asm("fcomi %3, %2\n"
818 86bd2ca5 bellard
            "fstsw %%ax\n"
819 03bfca94 bellard
            "pushf\n"
820 03bfca94 bellard
            "pop %0\n"
821 86bd2ca5 bellard
            : "=r" (eflags), "=a" (fpus)
822 03bfca94 bellard
            : "t" (a), "u" (b));
823 5fafdf24 ths
        printf("fcomi(%f %f)=%04lx %02lx\n",
824 86bd2ca5 bellard
               a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));
825 86bd2ca5 bellard
        fpu_clear_exceptions();
826 86bd2ca5 bellard
        asm("fucomi %3, %2\n"
827 86bd2ca5 bellard
            "fstsw %%ax\n"
828 86bd2ca5 bellard
            "pushf\n"
829 86bd2ca5 bellard
            "pop %0\n"
830 86bd2ca5 bellard
            : "=r" (eflags), "=a" (fpus)
831 86bd2ca5 bellard
            : "t" (a), "u" (b));
832 5fafdf24 ths
        printf("fucomi(%f %f)=%04lx %02lx\n",
833 86bd2ca5 bellard
               a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));
834 03bfca94 bellard
    }
835 86bd2ca5 bellard
    fpu_clear_exceptions();
836 b2a8e592 bellard
    asm volatile("fxam\n"
837 b2a8e592 bellard
                 "fstsw %%ax\n"
838 b2a8e592 bellard
                 : "=a" (fpus)
839 b2a8e592 bellard
                 : "t" (a));
840 b2a8e592 bellard
    printf("fxam(%f)=%04lx\n", a, fpus & 0x4700);
841 b2a8e592 bellard
    fpu_clear_exceptions();
842 9d8e9c09 bellard
}
843 9d8e9c09 bellard
844 9d8e9c09 bellard
void test_fcvt(double a)
845 9d8e9c09 bellard
{
846 9d8e9c09 bellard
    float fa;
847 9d8e9c09 bellard
    long double la;
848 ea768640 bellard
    int16_t fpuc;
849 ea768640 bellard
    int i;
850 ea768640 bellard
    int64_t lla;
851 ea768640 bellard
    int ia;
852 ea768640 bellard
    int16_t wa;
853 ea768640 bellard
    double ra;
854 9d8e9c09 bellard
855 9d8e9c09 bellard
    fa = a;
856 9d8e9c09 bellard
    la = a;
857 9d8e9c09 bellard
    printf("(float)%f = %f\n", a, fa);
858 9d8e9c09 bellard
    printf("(long double)%f = %Lf\n", a, la);
859 776f2227 bellard
    printf("a=" FMT64X "\n", *(uint64_t *)&a);
860 5fafdf24 ths
    printf("la=" FMT64X " %04x\n", *(uint64_t *)&la,
861 c5e9815d bellard
           *(unsigned short *)((char *)(&la) + 8));
862 ea768640 bellard
863 ea768640 bellard
    /* test all roundings */
864 ea768640 bellard
    asm volatile ("fstcw %0" : "=m" (fpuc));
865 ea768640 bellard
    for(i=0;i<4;i++) {
866 be98f1f8 bellard
        uint16_t val16;
867 be98f1f8 bellard
        val16 = (fpuc & ~0x0c00) | (i << 10);
868 be98f1f8 bellard
        asm volatile ("fldcw %0" : : "m" (val16));
869 ea768640 bellard
        asm volatile ("fist %0" : "=m" (wa) : "t" (a));
870 ea768640 bellard
        asm volatile ("fistl %0" : "=m" (ia) : "t" (a));
871 ea768640 bellard
        asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st");
872 ea768640 bellard
        asm volatile ("frndint ; fstl %0" : "=m" (ra) : "t" (a));
873 ea768640 bellard
        asm volatile ("fldcw %0" : : "m" (fpuc));
874 ea768640 bellard
        printf("(short)a = %d\n", wa);
875 ea768640 bellard
        printf("(int)a = %d\n", ia);
876 776f2227 bellard
        printf("(int64_t)a = " FMT64X "\n", lla);
877 ea768640 bellard
        printf("rint(a) = %f\n", ra);
878 ea768640 bellard
    }
879 9d8e9c09 bellard
}
880 9d8e9c09 bellard
881 9d8e9c09 bellard
#define TEST(N) \
882 9d8e9c09 bellard
    asm("fld" #N : "=t" (a)); \
883 9d8e9c09 bellard
    printf("fld" #N "= %f\n", a);
884 9d8e9c09 bellard
885 9d8e9c09 bellard
void test_fconst(void)
886 9d8e9c09 bellard
{
887 9d8e9c09 bellard
    double a;
888 9d8e9c09 bellard
    TEST(1);
889 9d8e9c09 bellard
    TEST(l2t);
890 9d8e9c09 bellard
    TEST(l2e);
891 9d8e9c09 bellard
    TEST(pi);
892 9d8e9c09 bellard
    TEST(lg2);
893 9d8e9c09 bellard
    TEST(ln2);
894 9d8e9c09 bellard
    TEST(z);
895 9d8e9c09 bellard
}
896 9d8e9c09 bellard
897 c5e9815d bellard
void test_fbcd(double a)
898 c5e9815d bellard
{
899 c5e9815d bellard
    unsigned short bcd[5];
900 c5e9815d bellard
    double b;
901 c5e9815d bellard
902 c5e9815d bellard
    asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
903 c5e9815d bellard
    asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
904 5fafdf24 ths
    printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",
905 c5e9815d bellard
           a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
906 c5e9815d bellard
}
907 c5e9815d bellard
908 6b2b6112 bellard
#define TEST_ENV(env, save, restore)\
909 03bfca94 bellard
{\
910 03bfca94 bellard
    memset((env), 0xaa, sizeof(*(env)));\
911 6b2b6112 bellard
    for(i=0;i<5;i++)\
912 6b2b6112 bellard
        asm volatile ("fldl %0" : : "m" (dtab[i]));\
913 085339a1 bellard
    asm volatile (save " %0\n" : : "m" (*(env)));\
914 085339a1 bellard
    asm volatile (restore " %0\n": : "m" (*(env)));\
915 6b2b6112 bellard
    for(i=0;i<5;i++)\
916 6b2b6112 bellard
        asm volatile ("fstpl %0" : "=m" (rtab[i]));\
917 6b2b6112 bellard
    for(i=0;i<5;i++)\
918 6b2b6112 bellard
        printf("res[%d]=%f\n", i, rtab[i]);\
919 03bfca94 bellard
    printf("fpuc=%04x fpus=%04x fptag=%04x\n",\
920 03bfca94 bellard
           (env)->fpuc,\
921 03bfca94 bellard
           (env)->fpus & 0xff00,\
922 03bfca94 bellard
           (env)->fptag);\
923 03bfca94 bellard
}
924 03bfca94 bellard
925 03bfca94 bellard
void test_fenv(void)
926 03bfca94 bellard
{
927 541dc0d4 Stefan Weil
    struct QEMU_PACKED {
928 03bfca94 bellard
        uint16_t fpuc;
929 03bfca94 bellard
        uint16_t dummy1;
930 03bfca94 bellard
        uint16_t fpus;
931 03bfca94 bellard
        uint16_t dummy2;
932 03bfca94 bellard
        uint16_t fptag;
933 03bfca94 bellard
        uint16_t dummy3;
934 03bfca94 bellard
        uint32_t ignored[4];
935 03bfca94 bellard
        long double fpregs[8];
936 03bfca94 bellard
    } float_env32;
937 541dc0d4 Stefan Weil
    struct QEMU_PACKED {
938 03bfca94 bellard
        uint16_t fpuc;
939 03bfca94 bellard
        uint16_t fpus;
940 03bfca94 bellard
        uint16_t fptag;
941 03bfca94 bellard
        uint16_t ignored[4];
942 03bfca94 bellard
        long double fpregs[8];
943 03bfca94 bellard
    } float_env16;
944 6b2b6112 bellard
    double dtab[8];
945 6b2b6112 bellard
    double rtab[8];
946 6b2b6112 bellard
    int i;
947 6b2b6112 bellard
948 6b2b6112 bellard
    for(i=0;i<8;i++)
949 6b2b6112 bellard
        dtab[i] = i + 1;
950 03bfca94 bellard
951 6b2b6112 bellard
    TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv");
952 6b2b6112 bellard
    TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor");
953 6b2b6112 bellard
    TEST_ENV(&float_env32, "fnstenv", "fldenv");
954 6b2b6112 bellard
    TEST_ENV(&float_env32, "fnsave", "frstor");
955 665656a9 bellard
956 665656a9 bellard
    /* test for ffree */
957 665656a9 bellard
    for(i=0;i<5;i++)
958 665656a9 bellard
        asm volatile ("fldl %0" : : "m" (dtab[i]));
959 665656a9 bellard
    asm volatile("ffree %st(2)");
960 665656a9 bellard
    asm volatile ("fnstenv %0\n" : : "m" (float_env32));
961 665656a9 bellard
    asm volatile ("fninit");
962 665656a9 bellard
    printf("fptag=%04x\n", float_env32.fptag);
963 03bfca94 bellard
}
964 03bfca94 bellard
965 75175024 bellard
966 75175024 bellard
#define TEST_FCMOV(a, b, eflags, CC)\
967 75175024 bellard
{\
968 75175024 bellard
    double res;\
969 75175024 bellard
    asm("push %3\n"\
970 75175024 bellard
        "popf\n"\
971 75175024 bellard
        "fcmov" CC " %2, %0\n"\
972 75175024 bellard
        : "=t" (res)\
973 75175024 bellard
        : "0" (a), "u" (b), "g" (eflags));\
974 776f2227 bellard
    printf("fcmov%s eflags=0x%04lx-> %f\n", \
975 776f2227 bellard
           CC, (long)eflags, res);\
976 75175024 bellard
}
977 75175024 bellard
978 75175024 bellard
void test_fcmov(void)
979 75175024 bellard
{
980 75175024 bellard
    double a, b;
981 776f2227 bellard
    long eflags, i;
982 75175024 bellard
983 75175024 bellard
    a = 1.0;
984 75175024 bellard
    b = 2.0;
985 75175024 bellard
    for(i = 0; i < 4; i++) {
986 75175024 bellard
        eflags = 0;
987 75175024 bellard
        if (i & 1)
988 75175024 bellard
            eflags |= CC_C;
989 75175024 bellard
        if (i & 2)
990 75175024 bellard
            eflags |= CC_Z;
991 75175024 bellard
        TEST_FCMOV(a, b, eflags, "b");
992 75175024 bellard
        TEST_FCMOV(a, b, eflags, "e");
993 75175024 bellard
        TEST_FCMOV(a, b, eflags, "be");
994 75175024 bellard
        TEST_FCMOV(a, b, eflags, "nb");
995 75175024 bellard
        TEST_FCMOV(a, b, eflags, "ne");
996 75175024 bellard
        TEST_FCMOV(a, b, eflags, "nbe");
997 75175024 bellard
    }
998 75175024 bellard
    TEST_FCMOV(a, b, 0, "u");
999 9cdf757f bellard
    TEST_FCMOV(a, b, CC_P, "u");
1000 9cdf757f bellard
    TEST_FCMOV(a, b, 0, "nu");
1001 75175024 bellard
    TEST_FCMOV(a, b, CC_P, "nu");
1002 75175024 bellard
}
1003 75175024 bellard
1004 9d8e9c09 bellard
void test_floats(void)
1005 9d8e9c09 bellard
{
1006 9d8e9c09 bellard
    test_fops(2, 3);
1007 9d8e9c09 bellard
    test_fops(1.4, -5);
1008 9d8e9c09 bellard
    test_fcmp(2, -1);
1009 9d8e9c09 bellard
    test_fcmp(2, 2);
1010 9d8e9c09 bellard
    test_fcmp(2, 3);
1011 86bd2ca5 bellard
    test_fcmp(2, q_nan.d);
1012 86bd2ca5 bellard
    test_fcmp(q_nan.d, -1);
1013 b2a8e592 bellard
    test_fcmp(-1.0/0.0, -1);
1014 b2a8e592 bellard
    test_fcmp(1.0/0.0, -1);
1015 ea768640 bellard
    test_fcvt(0.5);
1016 ea768640 bellard
    test_fcvt(-0.5);
1017 9d8e9c09 bellard
    test_fcvt(1.0/7.0);
1018 9d8e9c09 bellard
    test_fcvt(-1.0/9.0);
1019 ea768640 bellard
    test_fcvt(32768);
1020 ea768640 bellard
    test_fcvt(-1e20);
1021 b2a8e592 bellard
    test_fcvt(-1.0/0.0);
1022 b2a8e592 bellard
    test_fcvt(1.0/0.0);
1023 b2a8e592 bellard
    test_fcvt(q_nan.d);
1024 9d8e9c09 bellard
    test_fconst();
1025 be98f1f8 bellard
    test_fbcd(1234567890123456.0);
1026 be98f1f8 bellard
    test_fbcd(-123451234567890.0);
1027 03bfca94 bellard
    test_fenv();
1028 75175024 bellard
    if (TEST_CMOV) {
1029 75175024 bellard
        test_fcmov();
1030 75175024 bellard
    }
1031 9d8e9c09 bellard
}
1032 4b74fe1f bellard
1033 55480af8 bellard
/**********************************************/
1034 776f2227 bellard
#if !defined(__x86_64__)
1035 55480af8 bellard
1036 55480af8 bellard
#define TEST_BCD(op, op0, cc_in, cc_mask)\
1037 55480af8 bellard
{\
1038 55480af8 bellard
    int res, flags;\
1039 55480af8 bellard
    res = op0;\
1040 55480af8 bellard
    flags = cc_in;\
1041 55480af8 bellard
    asm ("push %3\n\t"\
1042 55480af8 bellard
         "popf\n\t"\
1043 55480af8 bellard
         #op "\n\t"\
1044 55480af8 bellard
         "pushf\n\t"\
1045 776f2227 bellard
         "pop %1\n\t"\
1046 55480af8 bellard
        : "=a" (res), "=g" (flags)\
1047 55480af8 bellard
        : "0" (res), "1" (flags));\
1048 55480af8 bellard
    printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\
1049 55480af8 bellard
           #op, op0, res, cc_in, flags & cc_mask);\
1050 55480af8 bellard
}
1051 55480af8 bellard
1052 55480af8 bellard
void test_bcd(void)
1053 55480af8 bellard
{
1054 55480af8 bellard
    TEST_BCD(daa, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1055 55480af8 bellard
    TEST_BCD(daa, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1056 55480af8 bellard
    TEST_BCD(daa, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1057 55480af8 bellard
    TEST_BCD(daa, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1058 55480af8 bellard
    TEST_BCD(daa, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1059 55480af8 bellard
    TEST_BCD(daa, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1060 55480af8 bellard
    TEST_BCD(daa, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1061 55480af8 bellard
    TEST_BCD(daa, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1062 55480af8 bellard
    TEST_BCD(daa, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1063 55480af8 bellard
    TEST_BCD(daa, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1064 55480af8 bellard
    TEST_BCD(daa, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1065 55480af8 bellard
    TEST_BCD(daa, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1066 55480af8 bellard
    TEST_BCD(daa, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1067 55480af8 bellard
1068 55480af8 bellard
    TEST_BCD(das, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1069 55480af8 bellard
    TEST_BCD(das, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1070 55480af8 bellard
    TEST_BCD(das, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1071 55480af8 bellard
    TEST_BCD(das, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1072 55480af8 bellard
    TEST_BCD(das, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1073 55480af8 bellard
    TEST_BCD(das, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1074 55480af8 bellard
    TEST_BCD(das, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1075 55480af8 bellard
    TEST_BCD(das, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1076 55480af8 bellard
    TEST_BCD(das, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1077 55480af8 bellard
    TEST_BCD(das, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1078 55480af8 bellard
    TEST_BCD(das, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1079 55480af8 bellard
    TEST_BCD(das, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1080 55480af8 bellard
    TEST_BCD(das, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
1081 55480af8 bellard
1082 55480af8 bellard
    TEST_BCD(aaa, 0x12340205, CC_A, (CC_C | CC_A));
1083 55480af8 bellard
    TEST_BCD(aaa, 0x12340306, CC_A, (CC_C | CC_A));
1084 55480af8 bellard
    TEST_BCD(aaa, 0x1234040a, CC_A, (CC_C | CC_A));
1085 55480af8 bellard
    TEST_BCD(aaa, 0x123405fa, CC_A, (CC_C | CC_A));
1086 55480af8 bellard
    TEST_BCD(aaa, 0x12340205, 0, (CC_C | CC_A));
1087 55480af8 bellard
    TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A));
1088 55480af8 bellard
    TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A));
1089 55480af8 bellard
    TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A));
1090 3b46e624 ths
1091 55480af8 bellard
    TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A));
1092 55480af8 bellard
    TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A));
1093 55480af8 bellard
    TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A));
1094 55480af8 bellard
    TEST_BCD(aas, 0x123405fa, CC_A, (CC_C | CC_A));
1095 55480af8 bellard
    TEST_BCD(aas, 0x12340205, 0, (CC_C | CC_A));
1096 55480af8 bellard
    TEST_BCD(aas, 0x12340306, 0, (CC_C | CC_A));
1097 55480af8 bellard
    TEST_BCD(aas, 0x1234040a, 0, (CC_C | CC_A));
1098 55480af8 bellard
    TEST_BCD(aas, 0x123405fa, 0, (CC_C | CC_A));
1099 55480af8 bellard
1100 55480af8 bellard
    TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
1101 55480af8 bellard
    TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
1102 55480af8 bellard
}
1103 776f2227 bellard
#endif
1104 55480af8 bellard
1105 e5918247 bellard
#define TEST_XCHG(op, size, opconst)\
1106 e5918247 bellard
{\
1107 776f2227 bellard
    long op0, op1;\
1108 776f2227 bellard
    op0 = i2l(0x12345678);\
1109 776f2227 bellard
    op1 = i2l(0xfbca7654);\
1110 e5918247 bellard
    asm(#op " %" size "0, %" size "1" \
1111 e5918247 bellard
        : "=q" (op0), opconst (op1) \
1112 8aadfbf0 bellard
        : "0" (op0));\
1113 776f2227 bellard
    printf("%-10s A=" FMTLX " B=" FMTLX "\n",\
1114 e5918247 bellard
           #op, op0, op1);\
1115 e5918247 bellard
}
1116 e5918247 bellard
1117 e5918247 bellard
#define TEST_CMPXCHG(op, size, opconst, eax)\
1118 e5918247 bellard
{\
1119 776f2227 bellard
    long op0, op1, op2;\
1120 776f2227 bellard
    op0 = i2l(0x12345678);\
1121 776f2227 bellard
    op1 = i2l(0xfbca7654);\
1122 776f2227 bellard
    op2 = i2l(eax);\
1123 e5918247 bellard
    asm(#op " %" size "0, %" size "1" \
1124 e5918247 bellard
        : "=q" (op0), opconst (op1) \
1125 8aadfbf0 bellard
        : "0" (op0), "a" (op2));\
1126 776f2227 bellard
    printf("%-10s EAX=" FMTLX " A=" FMTLX " C=" FMTLX "\n",\
1127 776f2227 bellard
           #op, op2, op0, op1);\
1128 e5918247 bellard
}
1129 e5918247 bellard
1130 e5918247 bellard
void test_xchg(void)
1131 e5918247 bellard
{
1132 776f2227 bellard
#if defined(__x86_64__)
1133 8aadfbf0 bellard
    TEST_XCHG(xchgq, "", "+q");
1134 776f2227 bellard
#endif
1135 8aadfbf0 bellard
    TEST_XCHG(xchgl, "k", "+q");
1136 8aadfbf0 bellard
    TEST_XCHG(xchgw, "w", "+q");
1137 8aadfbf0 bellard
    TEST_XCHG(xchgb, "b", "+q");
1138 e5918247 bellard
1139 776f2227 bellard
#if defined(__x86_64__)
1140 776f2227 bellard
    TEST_XCHG(xchgq, "", "=m");
1141 776f2227 bellard
#endif
1142 8aadfbf0 bellard
    TEST_XCHG(xchgl, "k", "+m");
1143 8aadfbf0 bellard
    TEST_XCHG(xchgw, "w", "+m");
1144 8aadfbf0 bellard
    TEST_XCHG(xchgb, "b", "+m");
1145 e5918247 bellard
1146 776f2227 bellard
#if defined(__x86_64__)
1147 8aadfbf0 bellard
    TEST_XCHG(xaddq, "", "+q");
1148 776f2227 bellard
#endif
1149 8aadfbf0 bellard
    TEST_XCHG(xaddl, "k", "+q");
1150 8aadfbf0 bellard
    TEST_XCHG(xaddw, "w", "+q");
1151 8aadfbf0 bellard
    TEST_XCHG(xaddb, "b", "+q");
1152 e5918247 bellard
1153 d575b78a bellard
    {
1154 d575b78a bellard
        int res;
1155 d575b78a bellard
        res = 0x12345678;
1156 d575b78a bellard
        asm("xaddl %1, %0" : "=r" (res) : "0" (res));
1157 d575b78a bellard
        printf("xaddl same res=%08x\n", res);
1158 d575b78a bellard
    }
1159 d575b78a bellard
1160 776f2227 bellard
#if defined(__x86_64__)
1161 8aadfbf0 bellard
    TEST_XCHG(xaddq, "", "+m");
1162 776f2227 bellard
#endif
1163 8aadfbf0 bellard
    TEST_XCHG(xaddl, "k", "+m");
1164 8aadfbf0 bellard
    TEST_XCHG(xaddw, "w", "+m");
1165 8aadfbf0 bellard
    TEST_XCHG(xaddb, "b", "+m");
1166 e5918247 bellard
1167 776f2227 bellard
#if defined(__x86_64__)
1168 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgq, "", "+q", 0xfbca7654);
1169 776f2227 bellard
#endif
1170 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "+q", 0xfbca7654);
1171 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "+q", 0xfbca7654);
1172 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "+q", 0xfbca7654);
1173 e5918247 bellard
1174 776f2227 bellard
#if defined(__x86_64__)
1175 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgq, "", "+q", 0xfffefdfc);
1176 776f2227 bellard
#endif
1177 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "+q", 0xfffefdfc);
1178 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "+q", 0xfffefdfc);
1179 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "+q", 0xfffefdfc);
1180 e5918247 bellard
1181 776f2227 bellard
#if defined(__x86_64__)
1182 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgq, "", "+m", 0xfbca7654);
1183 776f2227 bellard
#endif
1184 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "+m", 0xfbca7654);
1185 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "+m", 0xfbca7654);
1186 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "+m", 0xfbca7654);
1187 e5918247 bellard
1188 776f2227 bellard
#if defined(__x86_64__)
1189 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgq, "", "+m", 0xfffefdfc);
1190 776f2227 bellard
#endif
1191 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgl, "k", "+m", 0xfffefdfc);
1192 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgw, "w", "+m", 0xfffefdfc);
1193 8aadfbf0 bellard
    TEST_CMPXCHG(cmpxchgb, "b", "+m", 0xfffefdfc);
1194 d575b78a bellard
1195 d575b78a bellard
    {
1196 d575b78a bellard
        uint64_t op0, op1, op2;
1197 a5973fbf bellard
        long eax, edx;
1198 776f2227 bellard
        long i, eflags;
1199 d575b78a bellard
1200 d575b78a bellard
        for(i = 0; i < 2; i++) {
1201 be98f1f8 bellard
            op0 = 0x123456789abcdLL;
1202 a5973fbf bellard
            eax = i2l(op0 & 0xffffffff);
1203 a5973fbf bellard
            edx = i2l(op0 >> 32);
1204 d575b78a bellard
            if (i == 0)
1205 be98f1f8 bellard
                op1 = 0xfbca765423456LL;
1206 d575b78a bellard
            else
1207 d575b78a bellard
                op1 = op0;
1208 be98f1f8 bellard
            op2 = 0x6532432432434LL;
1209 a5973fbf bellard
            asm("cmpxchg8b %2\n"
1210 d575b78a bellard
                "pushf\n"
1211 a5973fbf bellard
                "pop %3\n"
1212 a5973fbf bellard
                : "=a" (eax), "=d" (edx), "=m" (op1), "=g" (eflags)
1213 a5973fbf bellard
                : "0" (eax), "1" (edx), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32)));
1214 a5973fbf bellard
            printf("cmpxchg8b: eax=" FMTLX " edx=" FMTLX " op1=" FMT64X " CC=%02lx\n",
1215 a5973fbf bellard
                   eax, edx, op1, eflags & CC_Z);
1216 d575b78a bellard
        }
1217 d575b78a bellard
    }
1218 e5918247 bellard
}
1219 e5918247 bellard
1220 776f2227 bellard
#ifdef TEST_SEGS
1221 6dbad63e bellard
/**********************************************/
1222 6dbad63e bellard
/* segmentation tests */
1223 6dbad63e bellard
1224 be98f1f8 bellard
#include <sys/syscall.h>
1225 be98f1f8 bellard
#include <unistd.h>
1226 6dbad63e bellard
#include <asm/ldt.h>
1227 73bdea19 bellard
#include <linux/version.h>
1228 6dbad63e bellard
1229 be98f1f8 bellard
static inline int modify_ldt(int func, void * ptr, unsigned long bytecount)
1230 be98f1f8 bellard
{
1231 be98f1f8 bellard
    return syscall(__NR_modify_ldt, func, ptr, bytecount);
1232 be98f1f8 bellard
}
1233 6dbad63e bellard
1234 73bdea19 bellard
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
1235 73bdea19 bellard
#define modify_ldt_ldt_s user_desc
1236 73bdea19 bellard
#endif
1237 73bdea19 bellard
1238 776f2227 bellard
#define MK_SEL(n) (((n) << 3) | 7)
1239 776f2227 bellard
1240 6dbad63e bellard
uint8_t seg_data1[4096];
1241 6dbad63e bellard
uint8_t seg_data2[4096];
1242 6dbad63e bellard
1243 288426fe bellard
#define TEST_LR(op, size, seg, mask)\
1244 288426fe bellard
{\
1245 288426fe bellard
    int res, res2;\
1246 a5973fbf bellard
    uint16_t mseg = seg;\
1247 288426fe bellard
    res = 0x12345678;\
1248 288426fe bellard
    asm (op " %" size "2, %" size "0\n" \
1249 288426fe bellard
         "movl $0, %1\n"\
1250 288426fe bellard
         "jnz 1f\n"\
1251 288426fe bellard
         "movl $1, %1\n"\
1252 288426fe bellard
         "1:\n"\
1253 a5973fbf bellard
         : "=r" (res), "=r" (res2) : "m" (mseg), "0" (res));\
1254 288426fe bellard
    printf(op ": Z=%d %08x\n", res2, res & ~(mask));\
1255 288426fe bellard
}
1256 288426fe bellard
1257 a5973fbf bellard
#define TEST_ARPL(op, size, op1, op2)\
1258 a5973fbf bellard
{\
1259 a5973fbf bellard
    long a, b, c;                               \
1260 a5973fbf bellard
    a = (op1);                                  \
1261 a5973fbf bellard
    b = (op2);                                  \
1262 a5973fbf bellard
    asm volatile(op " %" size "3, %" size "0\n"\
1263 a5973fbf bellard
                 "movl $0,%1\n"\
1264 a5973fbf bellard
                 "jnz 1f\n"\
1265 a5973fbf bellard
                 "movl $1,%1\n"\
1266 a5973fbf bellard
                 "1:\n"\
1267 a5973fbf bellard
                 : "=r" (a), "=r" (c) : "0" (a), "r" (b));    \
1268 a5973fbf bellard
    printf(op size " A=" FMTLX " B=" FMTLX " R=" FMTLX " z=%ld\n",\
1269 a5973fbf bellard
           (long)(op1), (long)(op2), a, c);\
1270 a5973fbf bellard
}
1271 a5973fbf bellard
1272 6dbad63e bellard
/* NOTE: we use Linux modify_ldt syscall */
1273 6dbad63e bellard
void test_segs(void)
1274 6dbad63e bellard
{
1275 6dbad63e bellard
    struct modify_ldt_ldt_s ldt;
1276 6dbad63e bellard
    long long ldt_table[3];
1277 04369ff2 bellard
    int res, res2;
1278 6dbad63e bellard
    char tmp;
1279 e1d4294a bellard
    struct {
1280 e1d4294a bellard
        uint32_t offset;
1281 e1d4294a bellard
        uint16_t seg;
1282 541dc0d4 Stefan Weil
    } QEMU_PACKED segoff;
1283 6dbad63e bellard
1284 6dbad63e bellard
    ldt.entry_number = 1;
1285 6dbad63e bellard
    ldt.base_addr = (unsigned long)&seg_data1;
1286 6dbad63e bellard
    ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
1287 6dbad63e bellard
    ldt.seg_32bit = 1;
1288 6dbad63e bellard
    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
1289 6dbad63e bellard
    ldt.read_exec_only = 0;
1290 6dbad63e bellard
    ldt.limit_in_pages = 1;
1291 6dbad63e bellard
    ldt.seg_not_present = 0;
1292 6dbad63e bellard
    ldt.useable = 1;
1293 6dbad63e bellard
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
1294 6dbad63e bellard
1295 6dbad63e bellard
    ldt.entry_number = 2;
1296 6dbad63e bellard
    ldt.base_addr = (unsigned long)&seg_data2;
1297 6dbad63e bellard
    ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12;
1298 6dbad63e bellard
    ldt.seg_32bit = 1;
1299 6dbad63e bellard
    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
1300 6dbad63e bellard
    ldt.read_exec_only = 0;
1301 6dbad63e bellard
    ldt.limit_in_pages = 1;
1302 6dbad63e bellard
    ldt.seg_not_present = 0;
1303 6dbad63e bellard
    ldt.useable = 1;
1304 6dbad63e bellard
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
1305 6dbad63e bellard
1306 6dbad63e bellard
    modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */
1307 04369ff2 bellard
#if 0
1308 04369ff2 bellard
    {
1309 04369ff2 bellard
        int i;
1310 04369ff2 bellard
        for(i=0;i<3;i++)
1311 04369ff2 bellard
            printf("%d: %016Lx\n", i, ldt_table[i]);
1312 04369ff2 bellard
    }
1313 04369ff2 bellard
#endif
1314 6dbad63e bellard
    /* do some tests with fs or gs */
1315 6dbad63e bellard
    asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
1316 6dbad63e bellard
1317 6dbad63e bellard
    seg_data1[1] = 0xaa;
1318 6dbad63e bellard
    seg_data2[1] = 0x55;
1319 6dbad63e bellard
1320 6dbad63e bellard
    asm volatile ("fs movzbl 0x1, %0" : "=r" (res));
1321 6dbad63e bellard
    printf("FS[1] = %02x\n", res);
1322 6dbad63e bellard
1323 070893f4 bellard
    asm volatile ("pushl %%gs\n"
1324 070893f4 bellard
                  "movl %1, %%gs\n"
1325 070893f4 bellard
                  "gs movzbl 0x1, %0\n"
1326 070893f4 bellard
                  "popl %%gs\n"
1327 070893f4 bellard
                  : "=r" (res)
1328 070893f4 bellard
                  : "r" (MK_SEL(2)));
1329 6dbad63e bellard
    printf("GS[1] = %02x\n", res);
1330 6dbad63e bellard
1331 6dbad63e bellard
    /* tests with ds/ss (implicit segment case) */
1332 6dbad63e bellard
    tmp = 0xa5;
1333 6dbad63e bellard
    asm volatile ("pushl %%ebp\n\t"
1334 6dbad63e bellard
                  "pushl %%ds\n\t"
1335 6dbad63e bellard
                  "movl %2, %%ds\n\t"
1336 6dbad63e bellard
                  "movl %3, %%ebp\n\t"
1337 6dbad63e bellard
                  "movzbl 0x1, %0\n\t"
1338 6dbad63e bellard
                  "movzbl (%%ebp), %1\n\t"
1339 6dbad63e bellard
                  "popl %%ds\n\t"
1340 6dbad63e bellard
                  "popl %%ebp\n\t"
1341 6dbad63e bellard
                  : "=r" (res), "=r" (res2)
1342 6dbad63e bellard
                  : "r" (MK_SEL(1)), "r" (&tmp));
1343 6dbad63e bellard
    printf("DS[1] = %02x\n", res);
1344 6dbad63e bellard
    printf("SS[tmp] = %02x\n", res2);
1345 e1d4294a bellard
1346 e1d4294a bellard
    segoff.seg = MK_SEL(2);
1347 e1d4294a bellard
    segoff.offset = 0xabcdef12;
1348 5fafdf24 ths
    asm volatile("lfs %2, %0\n\t"
1349 e1d4294a bellard
                 "movl %%fs, %1\n\t"
1350 5fafdf24 ths
                 : "=r" (res), "=g" (res2)
1351 e1d4294a bellard
                 : "m" (segoff));
1352 e1d4294a bellard
    printf("FS:reg = %04x:%08x\n", res2, res);
1353 288426fe bellard
1354 288426fe bellard
    TEST_LR("larw", "w", MK_SEL(2), 0x0100);
1355 288426fe bellard
    TEST_LR("larl", "", MK_SEL(2), 0x0100);
1356 288426fe bellard
    TEST_LR("lslw", "w", MK_SEL(2), 0);
1357 288426fe bellard
    TEST_LR("lsll", "", MK_SEL(2), 0);
1358 288426fe bellard
1359 288426fe bellard
    TEST_LR("larw", "w", 0xfff8, 0);
1360 288426fe bellard
    TEST_LR("larl", "", 0xfff8, 0);
1361 288426fe bellard
    TEST_LR("lslw", "w", 0xfff8, 0);
1362 288426fe bellard
    TEST_LR("lsll", "", 0xfff8, 0);
1363 a5973fbf bellard
1364 a5973fbf bellard
    TEST_ARPL("arpl", "w", 0x12345678 | 3, 0x762123c | 1);
1365 a5973fbf bellard
    TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 3);
1366 a5973fbf bellard
    TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 1);
1367 6dbad63e bellard
}
1368 55480af8 bellard
1369 e5918247 bellard
/* 16 bit code test */
1370 e5918247 bellard
extern char code16_start, code16_end;
1371 e5918247 bellard
extern char code16_func1;
1372 e5918247 bellard
extern char code16_func2;
1373 e5918247 bellard
extern char code16_func3;
1374 a300e691 bellard
1375 e5918247 bellard
void test_code16(void)
1376 1a9353d2 bellard
{
1377 e5918247 bellard
    struct modify_ldt_ldt_s ldt;
1378 e5918247 bellard
    int res, res2;
1379 a300e691 bellard
1380 e5918247 bellard
    /* build a code segment */
1381 e5918247 bellard
    ldt.entry_number = 1;
1382 e5918247 bellard
    ldt.base_addr = (unsigned long)&code16_start;
1383 e5918247 bellard
    ldt.limit = &code16_end - &code16_start;
1384 e5918247 bellard
    ldt.seg_32bit = 0;
1385 e5918247 bellard
    ldt.contents = MODIFY_LDT_CONTENTS_CODE;
1386 e5918247 bellard
    ldt.read_exec_only = 0;
1387 e5918247 bellard
    ldt.limit_in_pages = 0;
1388 e5918247 bellard
    ldt.seg_not_present = 0;
1389 e5918247 bellard
    ldt.useable = 1;
1390 e5918247 bellard
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
1391 a300e691 bellard
1392 e5918247 bellard
    /* call the first function */
1393 5fafdf24 ths
    asm volatile ("lcall %1, %2"
1394 e5918247 bellard
                  : "=a" (res)
1395 e5918247 bellard
                  : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc");
1396 e5918247 bellard
    printf("func1() = 0x%08x\n", res);
1397 5fafdf24 ths
    asm volatile ("lcall %2, %3"
1398 e5918247 bellard
                  : "=a" (res), "=c" (res2)
1399 e5918247 bellard
                  : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc");
1400 e5918247 bellard
    printf("func2() = 0x%08x spdec=%d\n", res, res2);
1401 5fafdf24 ths
    asm volatile ("lcall %1, %2"
1402 e5918247 bellard
                  : "=a" (res)
1403 e5918247 bellard
                  : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc");
1404 e5918247 bellard
    printf("func3() = 0x%08x\n", res);
1405 1a9353d2 bellard
}
1406 776f2227 bellard
#endif
1407 1a9353d2 bellard
1408 e06e5259 bellard
#if defined(__x86_64__)
1409 e06e5259 bellard
asm(".globl func_lret\n"
1410 e06e5259 bellard
    "func_lret:\n"
1411 e06e5259 bellard
    "movl $0x87654641, %eax\n"
1412 e06e5259 bellard
    "lretq\n");
1413 e06e5259 bellard
#else
1414 e06e5259 bellard
asm(".globl func_lret\n"
1415 e06e5259 bellard
    "func_lret:\n"
1416 e06e5259 bellard
    "movl $0x87654321, %eax\n"
1417 e06e5259 bellard
    "lret\n"
1418 e06e5259 bellard
1419 e06e5259 bellard
    ".globl func_iret\n"
1420 e06e5259 bellard
    "func_iret:\n"
1421 e06e5259 bellard
    "movl $0xabcd4321, %eax\n"
1422 e06e5259 bellard
    "iret\n");
1423 e06e5259 bellard
#endif
1424 e06e5259 bellard
1425 e06e5259 bellard
extern char func_lret;
1426 e06e5259 bellard
extern char func_iret;
1427 dd3587f3 bellard
1428 e1d4294a bellard
void test_misc(void)
1429 e1d4294a bellard
{
1430 e1d4294a bellard
    char table[256];
1431 776f2227 bellard
    long res, i;
1432 e1d4294a bellard
1433 e1d4294a bellard
    for(i=0;i<256;i++) table[i] = 256 - i;
1434 e1d4294a bellard
    res = 0x12345678;
1435 e1d4294a bellard
    asm ("xlat" : "=a" (res) : "b" (table), "0" (res));
1436 776f2227 bellard
    printf("xlat: EAX=" FMTLX "\n", res);
1437 dd3587f3 bellard
1438 e06e5259 bellard
#if defined(__x86_64__)
1439 8aadfbf0 bellard
#if 0
1440 e06e5259 bellard
    {
1441 8aadfbf0 bellard
        /* XXX: see if Intel Core2 and AMD64 behavior really
1442 8aadfbf0 bellard
           differ. Here we implemented the Intel way which is not
1443 8aadfbf0 bellard
           compatible yet with QEMU. */
1444 541dc0d4 Stefan Weil
        static struct QEMU_PACKED {
1445 8aadfbf0 bellard
            uint64_t offset;
1446 e06e5259 bellard
            uint16_t seg;
1447 e06e5259 bellard
        } desc;
1448 e06e5259 bellard
        long cs_sel;
1449 e06e5259 bellard

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

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

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

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

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