28 |
#include <errno.h> |
#include <errno.h> |
29 |
#include <sys/ucontext.h> |
#include <sys/ucontext.h> |
30 |
#include <sys/mman.h> |
#include <sys/mman.h> |
|
#include <asm/vm86.h> |
|
31 |
|
|
32 |
#define TEST_CMOV 0 |
#if !defined(__x86_64__) |
|
#define TEST_FCOMI 0 |
|
33 |
#define TEST_VM86 |
#define TEST_VM86 |
34 |
|
#define TEST_SEGS |
35 |
|
#endif |
36 |
//#define LINUX_VM86_IOPL_FIX |
//#define LINUX_VM86_IOPL_FIX |
37 |
//#define TEST_P4_FLAGS |
//#define TEST_P4_FLAGS |
38 |
//#define TEST_SSE |
#if defined(__x86_64__) |
39 |
|
#define TEST_SSE |
40 |
|
#define TEST_CMOV 1 |
41 |
|
#define TEST_FCOMI 1 |
42 |
|
#else |
43 |
|
#define TEST_CMOV 0 |
44 |
|
#define TEST_FCOMI 0 |
45 |
|
#endif |
46 |
|
|
47 |
|
#if defined(__x86_64__) |
48 |
|
#define FMT64X "%016lx" |
49 |
|
#define FMTLX "%016lx" |
50 |
|
#define X86_64_ONLY(x) x |
51 |
|
#else |
52 |
|
#define FMT64X "%016llx" |
53 |
|
#define FMTLX "%08lx" |
54 |
|
#define X86_64_ONLY(x) |
55 |
|
#endif |
56 |
|
|
57 |
|
#ifdef TEST_VM86 |
58 |
|
#include <asm/vm86.h> |
59 |
|
#endif |
60 |
|
|
61 |
#define xglue(x, y) x ## y |
#define xglue(x, y) x ## y |
62 |
#define glue(x, y) xglue(x, y) |
#define glue(x, y) xglue(x, y) |
70 |
#define CC_S 0x0080 |
#define CC_S 0x0080 |
71 |
#define CC_O 0x0800 |
#define CC_O 0x0800 |
72 |
|
|
73 |
#define __init_call __attribute__ ((unused,__section__ (".initcall.init"))) |
#define __init_call __attribute__ ((unused,__section__ ("initcall"))) |
|
|
|
|
static void *call_start __init_call = NULL; |
|
74 |
|
|
75 |
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A) |
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A) |
76 |
|
|
77 |
|
#if defined(__x86_64__) |
78 |
|
static inline long i2l(long v) |
79 |
|
{ |
80 |
|
return v | ((v ^ 0xabcd) << 32); |
81 |
|
} |
82 |
|
#else |
83 |
|
static inline long i2l(long v) |
84 |
|
{ |
85 |
|
return v; |
86 |
|
} |
87 |
|
#endif |
88 |
|
|
89 |
#define OP add |
#define OP add |
90 |
#include "test-i386.h" |
#include "test-i386.h" |
91 |
|
|
189 |
#include "test-i386-shift.h" |
#include "test-i386-shift.h" |
190 |
|
|
191 |
/* lea test (modrm support) */ |
/* lea test (modrm support) */ |
192 |
|
#define TEST_LEAQ(STR)\ |
193 |
|
{\ |
194 |
|
asm("lea " STR ", %0"\ |
195 |
|
: "=r" (res)\ |
196 |
|
: "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ |
197 |
|
printf("lea %s = " FMTLX "\n", STR, res);\ |
198 |
|
} |
199 |
|
|
200 |
#define TEST_LEA(STR)\ |
#define TEST_LEA(STR)\ |
201 |
{\ |
{\ |
202 |
asm("leal " STR ", %0"\ |
asm("lea " STR ", %0"\ |
203 |
: "=r" (res)\ |
: "=r" (res)\ |
204 |
: "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ |
: "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ |
205 |
printf("lea %s = %08x\n", STR, res);\ |
printf("lea %s = " FMTLX "\n", STR, res);\ |
206 |
} |
} |
207 |
|
|
208 |
#define TEST_LEA16(STR)\ |
#define TEST_LEA16(STR)\ |
210 |
asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\ |
asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\ |
211 |
: "=wq" (res)\ |
: "=wq" (res)\ |
212 |
: "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ |
: "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ |
213 |
printf("lea %s = %08x\n", STR, res);\ |
printf("lea %s = %08lx\n", STR, res);\ |
214 |
} |
} |
215 |
|
|
216 |
|
|
217 |
void test_lea(void) |
void test_lea(void) |
218 |
{ |
{ |
219 |
int eax, ebx, ecx, edx, esi, edi, res; |
long eax, ebx, ecx, edx, esi, edi, res; |
220 |
eax = 0x0001; |
eax = i2l(0x0001); |
221 |
ebx = 0x0002; |
ebx = i2l(0x0002); |
222 |
ecx = 0x0004; |
ecx = i2l(0x0004); |
223 |
edx = 0x0008; |
edx = i2l(0x0008); |
224 |
esi = 0x0010; |
esi = i2l(0x0010); |
225 |
edi = 0x0020; |
edi = i2l(0x0020); |
226 |
|
|
227 |
TEST_LEA("0x4000"); |
TEST_LEA("0x4000"); |
228 |
|
|
278 |
TEST_LEA("0x4000(%%edx, %%ecx, 4)"); |
TEST_LEA("0x4000(%%edx, %%ecx, 4)"); |
279 |
TEST_LEA("0x4000(%%esi, %%ecx, 8)"); |
TEST_LEA("0x4000(%%esi, %%ecx, 8)"); |
280 |
|
|
281 |
|
#if defined(__x86_64__) |
282 |
|
TEST_LEAQ("0x4000"); |
283 |
|
TEST_LEAQ("0x4000(%%rip)"); |
284 |
|
|
285 |
|
TEST_LEAQ("(%%rax)"); |
286 |
|
TEST_LEAQ("(%%rbx)"); |
287 |
|
TEST_LEAQ("(%%rcx)"); |
288 |
|
TEST_LEAQ("(%%rdx)"); |
289 |
|
TEST_LEAQ("(%%rsi)"); |
290 |
|
TEST_LEAQ("(%%rdi)"); |
291 |
|
|
292 |
|
TEST_LEAQ("0x40(%%rax)"); |
293 |
|
TEST_LEAQ("0x40(%%rbx)"); |
294 |
|
TEST_LEAQ("0x40(%%rcx)"); |
295 |
|
TEST_LEAQ("0x40(%%rdx)"); |
296 |
|
TEST_LEAQ("0x40(%%rsi)"); |
297 |
|
TEST_LEAQ("0x40(%%rdi)"); |
298 |
|
|
299 |
|
TEST_LEAQ("0x4000(%%rax)"); |
300 |
|
TEST_LEAQ("0x4000(%%rbx)"); |
301 |
|
TEST_LEAQ("0x4000(%%rcx)"); |
302 |
|
TEST_LEAQ("0x4000(%%rdx)"); |
303 |
|
TEST_LEAQ("0x4000(%%rsi)"); |
304 |
|
TEST_LEAQ("0x4000(%%rdi)"); |
305 |
|
|
306 |
|
TEST_LEAQ("(%%rax, %%rcx)"); |
307 |
|
TEST_LEAQ("(%%rbx, %%rdx)"); |
308 |
|
TEST_LEAQ("(%%rcx, %%rcx)"); |
309 |
|
TEST_LEAQ("(%%rdx, %%rcx)"); |
310 |
|
TEST_LEAQ("(%%rsi, %%rcx)"); |
311 |
|
TEST_LEAQ("(%%rdi, %%rcx)"); |
312 |
|
|
313 |
|
TEST_LEAQ("0x40(%%rax, %%rcx)"); |
314 |
|
TEST_LEAQ("0x4000(%%rbx, %%rdx)"); |
315 |
|
|
316 |
|
TEST_LEAQ("(%%rcx, %%rcx, 2)"); |
317 |
|
TEST_LEAQ("(%%rdx, %%rcx, 4)"); |
318 |
|
TEST_LEAQ("(%%rsi, %%rcx, 8)"); |
319 |
|
|
320 |
|
TEST_LEAQ("(,%%rax, 2)"); |
321 |
|
TEST_LEAQ("(,%%rbx, 4)"); |
322 |
|
TEST_LEAQ("(,%%rcx, 8)"); |
323 |
|
|
324 |
|
TEST_LEAQ("0x40(,%%rax, 2)"); |
325 |
|
TEST_LEAQ("0x40(,%%rbx, 4)"); |
326 |
|
TEST_LEAQ("0x40(,%%rcx, 8)"); |
327 |
|
|
328 |
|
|
329 |
|
TEST_LEAQ("-10(%%rcx, %%rcx, 2)"); |
330 |
|
TEST_LEAQ("-10(%%rdx, %%rcx, 4)"); |
331 |
|
TEST_LEAQ("-10(%%rsi, %%rcx, 8)"); |
332 |
|
|
333 |
|
TEST_LEAQ("0x4000(%%rcx, %%rcx, 2)"); |
334 |
|
TEST_LEAQ("0x4000(%%rdx, %%rcx, 4)"); |
335 |
|
TEST_LEAQ("0x4000(%%rsi, %%rcx, 8)"); |
336 |
|
#else |
337 |
/* limited 16 bit addressing test */ |
/* limited 16 bit addressing test */ |
338 |
TEST_LEA16("0x4000"); |
TEST_LEA16("0x4000"); |
339 |
TEST_LEA16("(%%bx)"); |
TEST_LEA16("(%%bx)"); |
350 |
TEST_LEA16("0x40(%%bx,%%di)"); |
TEST_LEA16("0x40(%%bx,%%di)"); |
351 |
TEST_LEA16("0x4000(%%bx,%%si)"); |
TEST_LEA16("0x4000(%%bx,%%si)"); |
352 |
TEST_LEA16("0x4000(%%bx,%%di)"); |
TEST_LEA16("0x4000(%%bx,%%di)"); |
353 |
|
#endif |
354 |
} |
} |
355 |
|
|
356 |
#define TEST_JCC(JCC, v1, v2)\ |
#define TEST_JCC(JCC, v1, v2)\ |
372 |
: "r" (v1), "r" (v2));\ |
: "r" (v1), "r" (v2));\ |
373 |
printf("%-10s %d\n", "set" JCC, res);\ |
printf("%-10s %d\n", "set" JCC, res);\ |
374 |
if (TEST_CMOV) {\ |
if (TEST_CMOV) {\ |
375 |
asm("movl $0x12345678, %0\n\t"\ |
long val = i2l(1);\ |
376 |
"cmpl %2, %1\n\t"\ |
long res = i2l(0x12345678);\ |
377 |
"cmov" JCC "l %3, %0\n\t"\ |
X86_64_ONLY(\ |
378 |
|
asm("cmpl %2, %1\n\t"\ |
379 |
|
"cmov" JCC "q %3, %0\n\t"\ |
380 |
: "=r" (res)\ |
: "=r" (res)\ |
381 |
: "r" (v1), "r" (v2), "m" (1));\ |
: "r" (v1), "r" (v2), "m" (val), "0" (res));\ |
382 |
printf("%-10s R=0x%08x\n", "cmov" JCC "l", res);\ |
printf("%-10s R=" FMTLX "\n", "cmov" JCC "l", res);)\ |
383 |
asm("movl $0x12345678, %0\n\t"\ |
asm("cmpl %2, %1\n\t"\ |
384 |
"cmpl %2, %1\n\t"\ |
"cmov" JCC "l %k3, %k0\n\t"\ |
385 |
|
: "=r" (res)\ |
386 |
|
: "r" (v1), "r" (v2), "m" (val), "0" (res));\ |
387 |
|
printf("%-10s R=" FMTLX "\n", "cmov" JCC "l", res);\ |
388 |
|
asm("cmpl %2, %1\n\t"\ |
389 |
"cmov" JCC "w %w3, %w0\n\t"\ |
"cmov" JCC "w %w3, %w0\n\t"\ |
390 |
: "=r" (res)\ |
: "=r" (res)\ |
391 |
: "r" (v1), "r" (v2), "r" (1));\ |
: "r" (v1), "r" (v2), "r" (1), "0" (res));\ |
392 |
printf("%-10s R=0x%08x\n", "cmov" JCC "w", res);\ |
printf("%-10s R=" FMTLX "\n", "cmov" JCC "w", res);\ |
393 |
} \ |
} \ |
394 |
} |
} |
395 |
|
|
469 |
#define OP imul |
#define OP imul |
470 |
#include "test-i386-muldiv.h" |
#include "test-i386-muldiv.h" |
471 |
|
|
472 |
void test_imulw2(int op0, int op1) |
void test_imulw2(long op0, long op1) |
473 |
{ |
{ |
474 |
int res, s1, s0, flags; |
long res, s1, s0, flags; |
475 |
s0 = op0; |
s0 = op0; |
476 |
s1 = op1; |
s1 = op1; |
477 |
res = s0; |
res = s0; |
480 |
"popf\n\t" |
"popf\n\t" |
481 |
"imulw %w2, %w0\n\t" |
"imulw %w2, %w0\n\t" |
482 |
"pushf\n\t" |
"pushf\n\t" |
483 |
"popl %1\n\t" |
"pop %1\n\t" |
484 |
: "=q" (res), "=g" (flags) |
: "=q" (res), "=g" (flags) |
485 |
: "q" (s1), "0" (res), "1" (flags)); |
: "q" (s1), "0" (res), "1" (flags)); |
486 |
printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n", |
printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n", |
487 |
"imulw", s0, s1, res, flags & CC_MASK); |
"imulw", s0, s1, res, flags & CC_MASK); |
488 |
} |
} |
489 |
|
|
490 |
void test_imull2(int op0, int op1) |
void test_imull2(long op0, long op1) |
491 |
{ |
{ |
492 |
int res, s1, s0, flags; |
long res, s1, s0, flags; |
493 |
s0 = op0; |
s0 = op0; |
494 |
s1 = op1; |
s1 = op1; |
495 |
res = s0; |
res = s0; |
496 |
flags = 0; |
flags = 0; |
497 |
asm volatile ("push %4\n\t" |
asm volatile ("push %4\n\t" |
498 |
"popf\n\t" |
"popf\n\t" |
499 |
"imull %2, %0\n\t" |
"imull %k2, %k0\n\t" |
500 |
"pushf\n\t" |
"pushf\n\t" |
501 |
"popl %1\n\t" |
"pop %1\n\t" |
502 |
: "=q" (res), "=g" (flags) |
: "=q" (res), "=g" (flags) |
503 |
: "q" (s1), "0" (res), "1" (flags)); |
: "q" (s1), "0" (res), "1" (flags)); |
504 |
printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n", |
printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n", |
505 |
"imull", s0, s1, res, flags & CC_MASK); |
"imull", s0, s1, res, flags & CC_MASK); |
506 |
} |
} |
507 |
|
|
508 |
#define TEST_IMUL_IM(size, size1, op0, op1)\ |
#if defined(__x86_64__) |
509 |
|
void test_imulq2(long op0, long op1) |
510 |
|
{ |
511 |
|
long res, s1, s0, flags; |
512 |
|
s0 = op0; |
513 |
|
s1 = op1; |
514 |
|
res = s0; |
515 |
|
flags = 0; |
516 |
|
asm volatile ("push %4\n\t" |
517 |
|
"popf\n\t" |
518 |
|
"imulq %2, %0\n\t" |
519 |
|
"pushf\n\t" |
520 |
|
"pop %1\n\t" |
521 |
|
: "=q" (res), "=g" (flags) |
522 |
|
: "q" (s1), "0" (res), "1" (flags)); |
523 |
|
printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n", |
524 |
|
"imulq", s0, s1, res, flags & CC_MASK); |
525 |
|
} |
526 |
|
#endif |
527 |
|
|
528 |
|
#define TEST_IMUL_IM(size, rsize, op0, op1)\ |
529 |
{\ |
{\ |
530 |
int res, flags;\ |
long res, flags, s1;\ |
531 |
flags = 0;\ |
flags = 0;\ |
532 |
res = 0;\ |
res = 0;\ |
533 |
|
s1 = op1;\ |
534 |
asm volatile ("push %3\n\t"\ |
asm volatile ("push %3\n\t"\ |
535 |
"popf\n\t"\ |
"popf\n\t"\ |
536 |
"imul" size " $" #op0 ", %" size1 "2, %" size1 "0\n\t" \ |
"imul" size " $" #op0 ", %" rsize "2, %" rsize "0\n\t" \ |
537 |
"pushf\n\t"\ |
"pushf\n\t"\ |
538 |
"popl %1\n\t"\ |
"pop %1\n\t"\ |
539 |
: "=r" (res), "=g" (flags)\ |
: "=r" (res), "=g" (flags)\ |
540 |
: "r" (op1), "1" (flags), "0" (res));\ |
: "r" (s1), "1" (flags), "0" (res));\ |
541 |
printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",\ |
printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",\ |
542 |
"imul" size " im", op0, op1, res, flags & CC_MASK);\ |
"imul" size " im", (long)op0, (long)op1, res, flags & CC_MASK);\ |
543 |
} |
} |
544 |
|
|
545 |
|
|
599 |
TEST_IMUL_IM("w", "w", 0x8000, 0x80000000); |
TEST_IMUL_IM("w", "w", 0x8000, 0x80000000); |
600 |
TEST_IMUL_IM("w", "w", 0x7fff, 0x1000); |
TEST_IMUL_IM("w", "w", 0x7fff, 0x1000); |
601 |
|
|
602 |
TEST_IMUL_IM("l", "", 45, 0x1234); |
TEST_IMUL_IM("l", "k", 45, 0x1234); |
603 |
TEST_IMUL_IM("l", "", -45, 23); |
TEST_IMUL_IM("l", "k", -45, 23); |
604 |
TEST_IMUL_IM("l", "", 0x8000, 0x80000000); |
TEST_IMUL_IM("l", "k", 0x8000, 0x80000000); |
605 |
TEST_IMUL_IM("l", "", 0x7fff, 0x1000); |
TEST_IMUL_IM("l", "k", 0x7fff, 0x1000); |
606 |
|
|
607 |
test_idivb(0x12341678, 0x127e); |
test_idivb(0x12341678, 0x127e); |
608 |
test_idivb(0x43210123, -5); |
test_idivb(0x43210123, -5); |
631 |
test_divl(0, -233223, -45); |
test_divl(0, -233223, -45); |
632 |
test_divl(0, 0x80000000, -1); |
test_divl(0, 0x80000000, -1); |
633 |
test_divl(0x12343, 0x12345678, 0x81234567); |
test_divl(0x12343, 0x12345678, 0x81234567); |
634 |
|
|
635 |
|
#if defined(__x86_64__) |
636 |
|
test_imulq(0, 0x1234001d1234001d, 45); |
637 |
|
test_imulq(0, 23, -45); |
638 |
|
test_imulq(0, 0x8000000000000000, 0x8000000000000000); |
639 |
|
test_imulq(0, 0x100000000, 0x100000000); |
640 |
|
|
641 |
|
test_mulq(0, 0x1234001d1234001d, 45); |
642 |
|
test_mulq(0, 23, -45); |
643 |
|
test_mulq(0, 0x8000000000000000, 0x8000000000000000); |
644 |
|
test_mulq(0, 0x100000000, 0x100000000); |
645 |
|
|
646 |
|
test_imulq2(0x1234001d1234001d, 45); |
647 |
|
test_imulq2(23, -45); |
648 |
|
test_imulq2(0x8000000000000000, 0x8000000000000000); |
649 |
|
test_imulq2(0x100000000, 0x100000000); |
650 |
|
|
651 |
|
TEST_IMUL_IM("q", "", 45, 0x12341234); |
652 |
|
TEST_IMUL_IM("q", "", -45, 23); |
653 |
|
TEST_IMUL_IM("q", "", 0x8000, 0x8000000000000000); |
654 |
|
TEST_IMUL_IM("q", "", 0x7fff, 0x10000000); |
655 |
|
|
656 |
|
test_idivq(0, 0x12345678abcdef, 12347); |
657 |
|
test_idivq(0, -233223, -45); |
658 |
|
test_idivq(0, 0x8000000000000000, -1); |
659 |
|
test_idivq(0x12343, 0x12345678, 0x81234567); |
660 |
|
|
661 |
|
test_divq(0, 0x12345678abcdef, 12347); |
662 |
|
test_divq(0, -233223, -45); |
663 |
|
test_divq(0, 0x8000000000000000, -1); |
664 |
|
test_divq(0x12343, 0x12345678, 0x81234567); |
665 |
|
#endif |
666 |
} |
} |
667 |
|
|
668 |
#define TEST_BSX(op, size, op0)\ |
#define TEST_BSX(op, size, op0)\ |
669 |
{\ |
{\ |
670 |
int res, val, resz;\ |
long res, val, resz;\ |
671 |
val = op0;\ |
val = op0;\ |
672 |
asm("xorl %1, %1\n"\ |
asm("xor %1, %1\n"\ |
673 |
"movl $0x12345678, %0\n"\ |
"mov $0x12345678, %0\n"\ |
674 |
#op " %" size "2, %" size "0 ; setz %b1" \ |
#op " %" size "2, %" size "0 ; setz %b1" \ |
675 |
: "=r" (res), "=q" (resz)\ |
: "=r" (res), "=q" (resz)\ |
676 |
: "g" (val));\ |
: "g" (val));\ |
677 |
printf("%-10s A=%08x R=%08x %d\n", #op, val, res, resz);\ |
printf("%-10s A=" FMTLX " R=" FMTLX " %ld\n", #op, val, res, resz);\ |
678 |
} |
} |
679 |
|
|
680 |
void test_bsx(void) |
void test_bsx(void) |
681 |
{ |
{ |
682 |
TEST_BSX(bsrw, "w", 0); |
TEST_BSX(bsrw, "w", 0); |
683 |
TEST_BSX(bsrw, "w", 0x12340128); |
TEST_BSX(bsrw, "w", 0x12340128); |
|
TEST_BSX(bsrl, "", 0); |
|
|
TEST_BSX(bsrl, "", 0x00340128); |
|
684 |
TEST_BSX(bsfw, "w", 0); |
TEST_BSX(bsfw, "w", 0); |
685 |
TEST_BSX(bsfw, "w", 0x12340128); |
TEST_BSX(bsfw, "w", 0x12340128); |
686 |
TEST_BSX(bsfl, "", 0); |
TEST_BSX(bsrl, "k", 0); |
687 |
TEST_BSX(bsfl, "", 0x00340128); |
TEST_BSX(bsrl, "k", 0x00340128); |
688 |
|
TEST_BSX(bsfl, "k", 0); |
689 |
|
TEST_BSX(bsfl, "k", 0x00340128); |
690 |
|
#if defined(__x86_64__) |
691 |
|
TEST_BSX(bsrq, "", 0); |
692 |
|
TEST_BSX(bsrq, "", 0x003401281234); |
693 |
|
TEST_BSX(bsfq, "", 0); |
694 |
|
TEST_BSX(bsfq, "", 0x003401281234); |
695 |
|
#endif |
696 |
} |
} |
697 |
|
|
698 |
/**********************************************/ |
/**********************************************/ |
731 |
printf("(%f<=%f)=%d\n", |
printf("(%f<=%f)=%d\n", |
732 |
a, b, a >= b); |
a, b, a >= b); |
733 |
if (TEST_FCOMI) { |
if (TEST_FCOMI) { |
734 |
unsigned int eflags; |
long eflags; |
735 |
/* test f(u)comi instruction */ |
/* test f(u)comi instruction */ |
736 |
asm("fcomi %2, %1\n" |
asm("fcomi %2, %1\n" |
737 |
"pushf\n" |
"pushf\n" |
738 |
"pop %0\n" |
"pop %0\n" |
739 |
: "=r" (eflags) |
: "=r" (eflags) |
740 |
: "t" (a), "u" (b)); |
: "t" (a), "u" (b)); |
741 |
printf("fcomi(%f %f)=%08x\n", a, b, eflags & (CC_Z | CC_P | CC_C)); |
printf("fcomi(%f %f)=%08lx\n", a, b, eflags & (CC_Z | CC_P | CC_C)); |
742 |
} |
} |
743 |
} |
} |
744 |
|
|
757 |
la = a; |
la = a; |
758 |
printf("(float)%f = %f\n", a, fa); |
printf("(float)%f = %f\n", a, fa); |
759 |
printf("(long double)%f = %Lf\n", a, la); |
printf("(long double)%f = %Lf\n", a, la); |
760 |
printf("a=%016Lx\n", *(long long *)&a); |
printf("a=" FMT64X "\n", *(uint64_t *)&a); |
761 |
printf("la=%016Lx %04x\n", *(long long *)&la, |
printf("la=" FMT64X " %04x\n", *(uint64_t *)&la, |
762 |
*(unsigned short *)((char *)(&la) + 8)); |
*(unsigned short *)((char *)(&la) + 8)); |
763 |
|
|
764 |
/* test all roundings */ |
/* test all roundings */ |
772 |
asm volatile ("fldcw %0" : : "m" (fpuc)); |
asm volatile ("fldcw %0" : : "m" (fpuc)); |
773 |
printf("(short)a = %d\n", wa); |
printf("(short)a = %d\n", wa); |
774 |
printf("(int)a = %d\n", ia); |
printf("(int)a = %d\n", ia); |
775 |
printf("(int64_t)a = %Ld\n", lla); |
printf("(int64_t)a = " FMT64X "\n", lla); |
776 |
printf("rint(a) = %f\n", ra); |
printf("rint(a) = %f\n", ra); |
777 |
} |
} |
778 |
} |
} |
870 |
"fcmov" CC " %2, %0\n"\ |
"fcmov" CC " %2, %0\n"\ |
871 |
: "=t" (res)\ |
: "=t" (res)\ |
872 |
: "0" (a), "u" (b), "g" (eflags));\ |
: "0" (a), "u" (b), "g" (eflags));\ |
873 |
printf("fcmov%s eflags=0x%04x-> %f\n", \ |
printf("fcmov%s eflags=0x%04lx-> %f\n", \ |
874 |
CC, eflags, res);\ |
CC, (long)eflags, res);\ |
875 |
} |
} |
876 |
|
|
877 |
void test_fcmov(void) |
void test_fcmov(void) |
878 |
{ |
{ |
879 |
double a, b; |
double a, b; |
880 |
int eflags, i; |
long eflags, i; |
881 |
|
|
882 |
a = 1.0; |
a = 1.0; |
883 |
b = 2.0; |
b = 2.0; |
923 |
} |
} |
924 |
|
|
925 |
/**********************************************/ |
/**********************************************/ |
926 |
|
#if !defined(__x86_64__) |
927 |
|
|
928 |
#define TEST_BCD(op, op0, cc_in, cc_mask)\ |
#define TEST_BCD(op, op0, cc_in, cc_mask)\ |
929 |
{\ |
{\ |
934 |
"popf\n\t"\ |
"popf\n\t"\ |
935 |
#op "\n\t"\ |
#op "\n\t"\ |
936 |
"pushf\n\t"\ |
"pushf\n\t"\ |
937 |
"popl %1\n\t"\ |
"pop %1\n\t"\ |
938 |
: "=a" (res), "=g" (flags)\ |
: "=a" (res), "=g" (flags)\ |
939 |
: "0" (res), "1" (flags));\ |
: "0" (res), "1" (flags));\ |
940 |
printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\ |
printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\ |
992 |
TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); |
TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); |
993 |
TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); |
TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); |
994 |
} |
} |
995 |
|
#endif |
996 |
|
|
997 |
#define TEST_XCHG(op, size, opconst)\ |
#define TEST_XCHG(op, size, opconst)\ |
998 |
{\ |
{\ |
999 |
int op0, op1;\ |
long op0, op1;\ |
1000 |
op0 = 0x12345678;\ |
op0 = i2l(0x12345678);\ |
1001 |
op1 = 0xfbca7654;\ |
op1 = i2l(0xfbca7654);\ |
1002 |
asm(#op " %" size "0, %" size "1" \ |
asm(#op " %" size "0, %" size "1" \ |
1003 |
: "=q" (op0), opconst (op1) \ |
: "=q" (op0), opconst (op1) \ |
1004 |
: "0" (op0), "1" (op1));\ |
: "0" (op0), "1" (op1));\ |
1005 |
printf("%-10s A=%08x B=%08x\n",\ |
printf("%-10s A=" FMTLX " B=" FMTLX "\n",\ |
1006 |
#op, op0, op1);\ |
#op, op0, op1);\ |
1007 |
} |
} |
1008 |
|
|
1009 |
#define TEST_CMPXCHG(op, size, opconst, eax)\ |
#define TEST_CMPXCHG(op, size, opconst, eax)\ |
1010 |
{\ |
{\ |
1011 |
int op0, op1;\ |
long op0, op1, op2;\ |
1012 |
op0 = 0x12345678;\ |
op0 = i2l(0x12345678);\ |
1013 |
op1 = 0xfbca7654;\ |
op1 = i2l(0xfbca7654);\ |
1014 |
|
op2 = i2l(eax);\ |
1015 |
asm(#op " %" size "0, %" size "1" \ |
asm(#op " %" size "0, %" size "1" \ |
1016 |
: "=q" (op0), opconst (op1) \ |
: "=q" (op0), opconst (op1) \ |
1017 |
: "0" (op0), "1" (op1), "a" (eax));\ |
: "0" (op0), "1" (op1), "a" (op2));\ |
1018 |
printf("%-10s EAX=%08x A=%08x C=%08x\n",\ |
printf("%-10s EAX=" FMTLX " A=" FMTLX " C=" FMTLX "\n",\ |
1019 |
#op, eax, op0, op1);\ |
#op, op2, op0, op1);\ |
1020 |
} |
} |
1021 |
|
|
1022 |
void test_xchg(void) |
void test_xchg(void) |
1023 |
{ |
{ |
1024 |
TEST_XCHG(xchgl, "", "=q"); |
#if defined(__x86_64__) |
1025 |
|
TEST_XCHG(xchgq, "", "=q"); |
1026 |
|
#endif |
1027 |
|
TEST_XCHG(xchgl, "k", "=q"); |
1028 |
TEST_XCHG(xchgw, "w", "=q"); |
TEST_XCHG(xchgw, "w", "=q"); |
1029 |
TEST_XCHG(xchgb, "b", "=q"); |
TEST_XCHG(xchgb, "b", "=q"); |
1030 |
|
|
1031 |
TEST_XCHG(xchgl, "", "=m"); |
#if defined(__x86_64__) |
1032 |
|
TEST_XCHG(xchgq, "", "=m"); |
1033 |
|
#endif |
1034 |
|
TEST_XCHG(xchgl, "k", "=m"); |
1035 |
TEST_XCHG(xchgw, "w", "=m"); |
TEST_XCHG(xchgw, "w", "=m"); |
1036 |
TEST_XCHG(xchgb, "b", "=m"); |
TEST_XCHG(xchgb, "b", "=m"); |
1037 |
|
|
1038 |
TEST_XCHG(xaddl, "", "=q"); |
#if defined(__x86_64__) |
1039 |
|
TEST_XCHG(xaddq, "", "=q"); |
1040 |
|
#endif |
1041 |
|
TEST_XCHG(xaddl, "k", "=q"); |
1042 |
TEST_XCHG(xaddw, "w", "=q"); |
TEST_XCHG(xaddw, "w", "=q"); |
1043 |
TEST_XCHG(xaddb, "b", "=q"); |
TEST_XCHG(xaddb, "b", "=q"); |
1044 |
|
|
1049 |
printf("xaddl same res=%08x\n", res); |
printf("xaddl same res=%08x\n", res); |
1050 |
} |
} |
1051 |
|
|
1052 |
TEST_XCHG(xaddl, "", "=m"); |
#if defined(__x86_64__) |
1053 |
|
TEST_XCHG(xaddq, "", "=m"); |
1054 |
|
#endif |
1055 |
|
TEST_XCHG(xaddl, "k", "=m"); |
1056 |
TEST_XCHG(xaddw, "w", "=m"); |
TEST_XCHG(xaddw, "w", "=m"); |
1057 |
TEST_XCHG(xaddb, "b", "=m"); |
TEST_XCHG(xaddb, "b", "=m"); |
1058 |
|
|
1059 |
TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654); |
#if defined(__x86_64__) |
1060 |
|
TEST_CMPXCHG(cmpxchgq, "", "=q", 0xfbca7654); |
1061 |
|
#endif |
1062 |
|
TEST_CMPXCHG(cmpxchgl, "k", "=q", 0xfbca7654); |
1063 |
TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654); |
TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654); |
1064 |
TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654); |
TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654); |
1065 |
|
|
1066 |
TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc); |
#if defined(__x86_64__) |
1067 |
|
TEST_CMPXCHG(cmpxchgq, "", "=q", 0xfffefdfc); |
1068 |
|
#endif |
1069 |
|
TEST_CMPXCHG(cmpxchgl, "k", "=q", 0xfffefdfc); |
1070 |
TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc); |
TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc); |
1071 |
TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc); |
TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc); |
1072 |
|
|
1073 |
TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfbca7654); |
#if defined(__x86_64__) |
1074 |
|
TEST_CMPXCHG(cmpxchgq, "", "=m", 0xfbca7654); |
1075 |
|
#endif |
1076 |
|
TEST_CMPXCHG(cmpxchgl, "k", "=m", 0xfbca7654); |
1077 |
TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654); |
TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654); |
1078 |
TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654); |
TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654); |
1079 |
|
|
1080 |
TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfffefdfc); |
#if defined(__x86_64__) |
1081 |
|
TEST_CMPXCHG(cmpxchgq, "", "=m", 0xfffefdfc); |
1082 |
|
#endif |
1083 |
|
TEST_CMPXCHG(cmpxchgl, "k", "=m", 0xfffefdfc); |
1084 |
TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc); |
TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc); |
1085 |
TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc); |
TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc); |
1086 |
|
|
1087 |
{ |
{ |
1088 |
uint64_t op0, op1, op2; |
uint64_t op0, op1, op2; |
1089 |
int i, eflags; |
long i, eflags; |
1090 |
|
|
1091 |
for(i = 0; i < 2; i++) { |
for(i = 0; i < 2; i++) { |
1092 |
op0 = 0x123456789abcd; |
op0 = 0x123456789abcd; |
1097 |
op2 = 0x6532432432434; |
op2 = 0x6532432432434; |
1098 |
asm("cmpxchg8b %1\n" |
asm("cmpxchg8b %1\n" |
1099 |
"pushf\n" |
"pushf\n" |
1100 |
"popl %2\n" |
"pop %2\n" |
1101 |
: "=A" (op0), "=m" (op1), "=g" (eflags) |
: "=A" (op0), "=m" (op1), "=g" (eflags) |
1102 |
: "0" (op0), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32))); |
: "0" (op0), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32))); |
1103 |
printf("cmpxchg8b: op0=%016llx op1=%016llx CC=%02x\n", |
printf("cmpxchg8b: op0=" FMT64X " op1=" FMT64X " CC=%02lx\n", |
1104 |
op0, op1, eflags & CC_Z); |
op0, op1, eflags & CC_Z); |
1105 |
} |
} |
1106 |
} |
} |
1107 |
} |
} |
1108 |
|
|
1109 |
|
#ifdef TEST_SEGS |
1110 |
/**********************************************/ |
/**********************************************/ |
1111 |
/* segmentation tests */ |
/* segmentation tests */ |
1112 |
|
|
1120 |
#define modify_ldt_ldt_s user_desc |
#define modify_ldt_ldt_s user_desc |
1121 |
#endif |
#endif |
1122 |
|
|
1123 |
|
#define MK_SEL(n) (((n) << 3) | 7) |
1124 |
|
|
1125 |
uint8_t seg_data1[4096]; |
uint8_t seg_data1[4096]; |
1126 |
uint8_t seg_data2[4096]; |
uint8_t seg_data2[4096]; |
1127 |
|
|
|
#define MK_SEL(n) (((n) << 3) | 7) |
|
|
|
|
1128 |
#define TEST_LR(op, size, seg, mask)\ |
#define TEST_LR(op, size, seg, mask)\ |
1129 |
{\ |
{\ |
1130 |
int res, res2;\ |
int res, res2;\ |
1268 |
: "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc"); |
: "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc"); |
1269 |
printf("func3() = 0x%08x\n", res); |
printf("func3() = 0x%08x\n", res); |
1270 |
} |
} |
1271 |
|
#endif |
1272 |
|
|
1273 |
extern char func_lret32; |
extern char func_lret32; |
1274 |
extern char func_iret32; |
extern char func_iret32; |
1276 |
void test_misc(void) |
void test_misc(void) |
1277 |
{ |
{ |
1278 |
char table[256]; |
char table[256]; |
1279 |
int res, i; |
long res, i; |
1280 |
|
|
1281 |
for(i=0;i<256;i++) table[i] = 256 - i; |
for(i=0;i<256;i++) table[i] = 256 - i; |
1282 |
res = 0x12345678; |
res = 0x12345678; |
1283 |
asm ("xlat" : "=a" (res) : "b" (table), "0" (res)); |
asm ("xlat" : "=a" (res) : "b" (table), "0" (res)); |
1284 |
printf("xlat: EAX=%08x\n", res); |
printf("xlat: EAX=" FMTLX "\n", res); |
1285 |
|
|
1286 |
asm volatile ("pushl %%cs ; call %1" |
#if !defined(__x86_64__) |
1287 |
|
asm volatile ("push %%cs ; call %1" |
1288 |
: "=a" (res) |
: "=a" (res) |
1289 |
: "m" (func_lret32): "memory", "cc"); |
: "m" (func_lret32): "memory", "cc"); |
1290 |
printf("func_lret32=%x\n", res); |
printf("func_lret32=" FMTLX "\n", res); |
1291 |
|
|
1292 |
asm volatile ("pushfl ; pushl %%cs ; call %1" |
asm volatile ("pushf ; push %%cs ; call %1" |
1293 |
: "=a" (res) |
: "=a" (res) |
1294 |
: "m" (func_iret32): "memory", "cc"); |
: "m" (func_iret32): "memory", "cc"); |
1295 |
printf("func_iret32=%x\n", res); |
printf("func_iret32=" FMTLX "\n", res); |
1296 |
|
#endif |
1297 |
|
|
1298 |
|
#if defined(__x86_64__) |
1299 |
|
/* specific popl test */ |
1300 |
|
asm volatile ("push $12345432 ; push $0x9abcdef ; pop (%%rsp) ; pop %0" |
1301 |
|
: "=g" (res)); |
1302 |
|
printf("popl esp=" FMTLX "\n", res); |
1303 |
|
#else |
1304 |
/* specific popl test */ |
/* specific popl test */ |
1305 |
asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popl (%%esp) ; popl %0" |
asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popl (%%esp) ; popl %0" |
1306 |
: "=g" (res)); |
: "=g" (res)); |
1307 |
printf("popl esp=%x\n", res); |
printf("popl esp=" FMTLX "\n", res); |
1308 |
|
|
1309 |
/* specific popw test */ |
/* specific popw test */ |
1310 |
asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popw (%%esp) ; addl $2, %%esp ; popl %0" |
asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popw (%%esp) ; addl $2, %%esp ; popl %0" |
1311 |
: "=g" (res)); |
: "=g" (res)); |
1312 |
printf("popw esp=%x\n", res); |
printf("popw esp=" FMTLX "\n", res); |
1313 |
|
#endif |
1314 |
} |
} |
1315 |
|
|
1316 |
uint8_t str_buffer[4096]; |
uint8_t str_buffer[4096]; |
1317 |
|
|
1318 |
#define TEST_STRING1(OP, size, DF, REP)\ |
#define TEST_STRING1(OP, size, DF, REP)\ |
1319 |
{\ |
{\ |
1320 |
int esi, edi, eax, ecx, eflags;\ |
long esi, edi, eax, ecx, eflags;\ |
1321 |
\ |
\ |
1322 |
esi = (long)(str_buffer + sizeof(str_buffer) / 2);\ |
esi = (long)(str_buffer + sizeof(str_buffer) / 2);\ |
1323 |
edi = (long)(str_buffer + sizeof(str_buffer) / 2) + 16;\ |
edi = (long)(str_buffer + sizeof(str_buffer) / 2) + 16;\ |
1324 |
eax = 0x12345678;\ |
eax = i2l(0x12345678);\ |
1325 |
ecx = 17;\ |
ecx = 17;\ |
1326 |
\ |
\ |
1327 |
asm volatile ("pushl $0\n\t"\ |
asm volatile ("push $0\n\t"\ |
1328 |
"popf\n\t"\ |
"popf\n\t"\ |
1329 |
DF "\n\t"\ |
DF "\n\t"\ |
1330 |
REP #OP size "\n\t"\ |
REP #OP size "\n\t"\ |
1331 |
"cld\n\t"\ |
"cld\n\t"\ |
1332 |
"pushf\n\t"\ |
"pushf\n\t"\ |
1333 |
"popl %4\n\t"\ |
"pop %4\n\t"\ |
1334 |
: "=S" (esi), "=D" (edi), "=a" (eax), "=c" (ecx), "=g" (eflags)\ |
: "=S" (esi), "=D" (edi), "=a" (eax), "=c" (ecx), "=g" (eflags)\ |
1335 |
: "0" (esi), "1" (edi), "2" (eax), "3" (ecx));\ |
: "0" (esi), "1" (edi), "2" (eax), "3" (ecx));\ |
1336 |
printf("%-10s ESI=%08x EDI=%08x EAX=%08x ECX=%08x EFL=%04x\n",\ |
printf("%-10s ESI=" FMTLX " EDI=" FMTLX " EAX=" FMTLX " ECX=" FMTLX " EFL=%04x\n",\ |
1337 |
REP #OP size, esi, edi, eax, ecx,\ |
REP #OP size, esi, edi, eax, ecx,\ |
1338 |
eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\ |
(int)(eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)));\ |
1339 |
} |
} |
1340 |
|
|
1341 |
#define TEST_STRING(OP, REP)\ |
#define TEST_STRING(OP, REP)\ |
1342 |
TEST_STRING1(OP, "b", "", REP);\ |
TEST_STRING1(OP, "b", "", REP);\ |
1343 |
TEST_STRING1(OP, "w", "", REP);\ |
TEST_STRING1(OP, "w", "", REP);\ |
1344 |
TEST_STRING1(OP, "l", "", REP);\ |
TEST_STRING1(OP, "l", "", REP);\ |
1345 |
|
X86_64_ONLY(TEST_STRING1(OP, "q", "", REP));\ |
1346 |
TEST_STRING1(OP, "b", "std", REP);\ |
TEST_STRING1(OP, "b", "std", REP);\ |
1347 |
TEST_STRING1(OP, "w", "std", REP);\ |
TEST_STRING1(OP, "w", "std", REP);\ |
1348 |
TEST_STRING1(OP, "l", "std", REP) |
TEST_STRING1(OP, "l", "std", REP);\ |
1349 |
|
X86_64_ONLY(TEST_STRING1(OP, "q", "std", REP)) |
1350 |
|
|
1351 |
void test_string(void) |
void test_string(void) |
1352 |
{ |
{ |
1370 |
TEST_STRING(cmps, "repnz "); |
TEST_STRING(cmps, "repnz "); |
1371 |
} |
} |
1372 |
|
|
1373 |
|
#ifdef TEST_VM86 |
1374 |
/* VM86 test */ |
/* VM86 test */ |
1375 |
|
|
1376 |
static inline void set_bit(uint8_t *a, unsigned int bit) |
static inline void set_bit(uint8_t *a, unsigned int bit) |
1501 |
printf("VM86 end\n"); |
printf("VM86 end\n"); |
1502 |
munmap(vm86_mem, 0x110000); |
munmap(vm86_mem, 0x110000); |
1503 |
} |
} |
1504 |
|
#endif |
1505 |
|
|
1506 |
/* exception tests */ |
/* exception tests */ |
1507 |
#ifndef REG_EAX |
#if defined(__i386__) && !defined(REG_EAX) |
1508 |
#define REG_EAX EAX |
#define REG_EAX EAX |
1509 |
#define REG_EBX EBX |
#define REG_EBX EBX |
1510 |
#define REG_ECX ECX |
#define REG_ECX ECX |
1519 |
#define REG_ERR ERR |
#define REG_ERR ERR |
1520 |
#endif |
#endif |
1521 |
|
|
1522 |
|
#if defined(__x86_64__) |
1523 |
|
#define REG_EIP REG_RIP |
1524 |
|
#endif |
1525 |
|
|
1526 |
jmp_buf jmp_env; |
jmp_buf jmp_env; |
1527 |
int v1; |
int v1; |
1528 |
int tab[2]; |
int tab[2]; |
1537 |
(unsigned long)info->si_addr); |
(unsigned long)info->si_addr); |
1538 |
printf("\n"); |
printf("\n"); |
1539 |
|
|
1540 |
printf("trapno=0x%02x err=0x%08x", |
printf("trapno=" FMTLX " err=" FMTLX, |
1541 |
uc->uc_mcontext.gregs[REG_TRAPNO], |
(long)uc->uc_mcontext.gregs[REG_TRAPNO], |
1542 |
uc->uc_mcontext.gregs[REG_ERR]); |
(long)uc->uc_mcontext.gregs[REG_ERR]); |
1543 |
printf(" EIP=0x%08x", uc->uc_mcontext.gregs[REG_EIP]); |
printf(" EIP=" FMTLX, (long)uc->uc_mcontext.gregs[REG_EIP]); |
1544 |
printf("\n"); |
printf("\n"); |
1545 |
longjmp(jmp_env, 1); |
longjmp(jmp_env, 1); |
1546 |
} |
} |
1547 |
|
|
1548 |
void test_exceptions(void) |
void test_exceptions(void) |
1549 |
{ |
{ |
|
struct modify_ldt_ldt_s ldt; |
|
1550 |
struct sigaction act; |
struct sigaction act; |
1551 |
volatile int val; |
volatile int val; |
1552 |
|
|
1553 |
act.sa_sigaction = sig_handler; |
act.sa_sigaction = sig_handler; |
1554 |
sigemptyset(&act.sa_mask); |
sigemptyset(&act.sa_mask); |
1555 |
act.sa_flags = SA_SIGINFO; |
act.sa_flags = SA_SIGINFO | SA_NODEFER; |
1556 |
sigaction(SIGFPE, &act, NULL); |
sigaction(SIGFPE, &act, NULL); |
1557 |
sigaction(SIGILL, &act, NULL); |
sigaction(SIGILL, &act, NULL); |
1558 |
sigaction(SIGSEGV, &act, NULL); |
sigaction(SIGSEGV, &act, NULL); |
1567 |
v1 = 2 / v1; |
v1 = 2 / v1; |
1568 |
} |
} |
1569 |
|
|
1570 |
|
#if !defined(__x86_64__) |
1571 |
printf("BOUND exception:\n"); |
printf("BOUND exception:\n"); |
1572 |
if (setjmp(jmp_env) == 0) { |
if (setjmp(jmp_env) == 0) { |
1573 |
/* bound exception */ |
/* bound exception */ |
1575 |
tab[1] = 10; |
tab[1] = 10; |
1576 |
asm volatile ("bound %0, %1" : : "r" (11), "m" (tab[0])); |
asm volatile ("bound %0, %1" : : "r" (11), "m" (tab[0])); |
1577 |
} |
} |
1578 |
|
#endif |
1579 |
|
|
1580 |
|
#ifdef TEST_SEGS |
1581 |
printf("segment exceptions:\n"); |
printf("segment exceptions:\n"); |
1582 |
if (setjmp(jmp_env) == 0) { |
if (setjmp(jmp_env) == 0) { |
1583 |
/* load an invalid segment */ |
/* load an invalid segment */ |
1590 |
asm volatile ("movl %0, %%ss" : : "r" (3)); |
asm volatile ("movl %0, %%ss" : : "r" (3)); |
1591 |
} |
} |
1592 |
|
|
1593 |
ldt.entry_number = 1; |
{ |
1594 |
ldt.base_addr = (unsigned long)&seg_data1; |
struct modify_ldt_ldt_s ldt; |
1595 |
ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12; |
ldt.entry_number = 1; |
1596 |
ldt.seg_32bit = 1; |
ldt.base_addr = (unsigned long)&seg_data1; |
1597 |
ldt.contents = MODIFY_LDT_CONTENTS_DATA; |
ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12; |
1598 |
ldt.read_exec_only = 0; |
ldt.seg_32bit = 1; |
1599 |
ldt.limit_in_pages = 1; |
ldt.contents = MODIFY_LDT_CONTENTS_DATA; |
1600 |
ldt.seg_not_present = 1; |
ldt.read_exec_only = 0; |
1601 |
ldt.useable = 1; |
ldt.limit_in_pages = 1; |
1602 |
modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ |
ldt.seg_not_present = 1; |
1603 |
|
ldt.useable = 1; |
1604 |
if (setjmp(jmp_env) == 0) { |
modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ |
1605 |
/* segment not present */ |
|
1606 |
asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1))); |
if (setjmp(jmp_env) == 0) { |
1607 |
|
/* segment not present */ |
1608 |
|
asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1))); |
1609 |
|
} |
1610 |
} |
} |
1611 |
|
#endif |
1612 |
|
|
1613 |
/* test SEGV reporting */ |
/* test SEGV reporting */ |
1614 |
printf("PF exception:\n"); |
printf("PF exception:\n"); |
1672 |
asm volatile ("cli"); |
asm volatile ("cli"); |
1673 |
} |
} |
1674 |
|
|
1675 |
|
#if !defined(__x86_64__) |
1676 |
printf("INTO exception:\n"); |
printf("INTO exception:\n"); |
1677 |
if (setjmp(jmp_env) == 0) { |
if (setjmp(jmp_env) == 0) { |
1678 |
/* overflow exception */ |
/* overflow exception */ |
1679 |
asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff)); |
asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff)); |
1680 |
} |
} |
1681 |
|
#endif |
1682 |
|
|
1683 |
printf("OUTB exception:\n"); |
printf("OUTB exception:\n"); |
1684 |
if (setjmp(jmp_env) == 0) { |
if (setjmp(jmp_env) == 0) { |
1717 |
printf("val=0x%x\n", val); |
printf("val=0x%x\n", val); |
1718 |
} |
} |
1719 |
|
|
1720 |
|
#if !defined(__x86_64__) |
1721 |
/* specific precise single step test */ |
/* specific precise single step test */ |
1722 |
void sig_trap_handler(int sig, siginfo_t *info, void *puc) |
void sig_trap_handler(int sig, siginfo_t *info, void *puc) |
1723 |
{ |
{ |
1724 |
struct ucontext *uc = puc; |
struct ucontext *uc = puc; |
1725 |
printf("EIP=0x%08x\n", uc->uc_mcontext.gregs[REG_EIP]); |
printf("EIP=" FMTLX "\n", (long)uc->uc_mcontext.gregs[REG_EIP]); |
1726 |
} |
} |
1727 |
|
|
1728 |
const uint8_t sstep_buf1[4] = { 1, 2, 3, 4}; |
const uint8_t sstep_buf1[4] = { 1, 2, 3, 4}; |
1843 |
printf("smc_code2(%d) = %d\n", i, smc_code2(i)); |
printf("smc_code2(%d) = %d\n", i, smc_code2(i)); |
1844 |
} |
} |
1845 |
} |
} |
1846 |
|
#endif |
1847 |
|
|
1848 |
int enter_stack[4096]; |
long enter_stack[4096]; |
1849 |
|
|
1850 |
|
#if defined(__x86_64__) |
1851 |
|
#define RSP "%%rsp" |
1852 |
|
#define RBP "%%rbp" |
1853 |
|
#else |
1854 |
|
#define RSP "%%esp" |
1855 |
|
#define RBP "%%ebp" |
1856 |
|
#endif |
1857 |
|
|
1858 |
#define TEST_ENTER(size, stack_type, level)\ |
#define TEST_ENTER(size, stack_type, level)\ |
1859 |
{\ |
{\ |
1860 |
int esp_save, esp_val, ebp_val, ebp_save, i;\ |
long esp_save, esp_val, ebp_val, ebp_save, i;\ |
1861 |
stack_type *ptr, *stack_end, *stack_ptr;\ |
stack_type *ptr, *stack_end, *stack_ptr;\ |
1862 |
memset(enter_stack, 0, sizeof(enter_stack));\ |
memset(enter_stack, 0, sizeof(enter_stack));\ |
1863 |
stack_end = stack_ptr = (stack_type *)(enter_stack + 4096);\ |
stack_end = stack_ptr = (stack_type *)(enter_stack + 4096);\ |
1865 |
for(i=1;i<=32;i++)\ |
for(i=1;i<=32;i++)\ |
1866 |
*--stack_ptr = i;\ |
*--stack_ptr = i;\ |
1867 |
esp_val = (long)stack_ptr;\ |
esp_val = (long)stack_ptr;\ |
1868 |
asm("movl %%esp, %[esp_save]\n"\ |
asm("mov " RSP ", %[esp_save]\n"\ |
1869 |
"movl %%ebp, %[ebp_save]\n"\ |
"mov " RBP ", %[ebp_save]\n"\ |
1870 |
"movl %[esp_val], %%esp\n"\ |
"mov %[esp_val], " RSP "\n"\ |
1871 |
"movl %[ebp_val], %%ebp\n"\ |
"mov %[ebp_val], " RBP "\n"\ |
1872 |
"enter" size " $12, $" #level "\n"\ |
"enter" size " $8, $" #level "\n"\ |
1873 |
"movl %%esp, %[esp_val]\n"\ |
"mov " RSP ", %[esp_val]\n"\ |
1874 |
"movl %%ebp, %[ebp_val]\n"\ |
"mov " RBP ", %[ebp_val]\n"\ |
1875 |
"movl %[esp_save], %%esp\n"\ |
"mov %[esp_save], " RSP "\n"\ |
1876 |
"movl %[ebp_save], %%ebp\n"\ |
"mov %[ebp_save], " RBP "\n"\ |
1877 |
: [esp_save] "=r" (esp_save),\ |
: [esp_save] "=r" (esp_save),\ |
1878 |
[ebp_save] "=r" (ebp_save),\ |
[ebp_save] "=r" (ebp_save),\ |
1879 |
[esp_val] "=r" (esp_val),\ |
[esp_val] "=r" (esp_val),\ |
1881 |
: "[esp_val]" (esp_val),\ |
: "[esp_val]" (esp_val),\ |
1882 |
"[ebp_val]" (ebp_val));\ |
"[ebp_val]" (ebp_val));\ |
1883 |
printf("level=%d:\n", level);\ |
printf("level=%d:\n", level);\ |
1884 |
printf("esp_val=0x%08lx\n", esp_val - (long)stack_end);\ |
printf("esp_val=" FMTLX "\n", esp_val - (long)stack_end);\ |
1885 |
printf("ebp_val=0x%08lx\n", ebp_val - (long)stack_end);\ |
printf("ebp_val=" FMTLX "\n", ebp_val - (long)stack_end);\ |
1886 |
for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\ |
for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\ |
1887 |
printf("%08x\n", ptr[0]);\ |
printf(FMTLX "\n", (long)ptr[0]);\ |
1888 |
} |
} |
1889 |
|
|
1890 |
static void test_enter(void) |
static void test_enter(void) |
1891 |
{ |
{ |
1892 |
|
#if defined(__x86_64__) |
1893 |
|
TEST_ENTER("q", uint64_t, 0); |
1894 |
|
TEST_ENTER("q", uint64_t, 1); |
1895 |
|
TEST_ENTER("q", uint64_t, 2); |
1896 |
|
TEST_ENTER("q", uint64_t, 31); |
1897 |
|
#else |
1898 |
TEST_ENTER("l", uint32_t, 0); |
TEST_ENTER("l", uint32_t, 0); |
1899 |
TEST_ENTER("l", uint32_t, 1); |
TEST_ENTER("l", uint32_t, 1); |
1900 |
TEST_ENTER("l", uint32_t, 2); |
TEST_ENTER("l", uint32_t, 2); |
1901 |
TEST_ENTER("l", uint32_t, 31); |
TEST_ENTER("l", uint32_t, 31); |
1902 |
|
#endif |
1903 |
|
|
1904 |
TEST_ENTER("w", uint16_t, 0); |
TEST_ENTER("w", uint16_t, 0); |
1905 |
TEST_ENTER("w", uint16_t, 1); |
TEST_ENTER("w", uint16_t, 1); |
1930 |
#define SSE_OP(op)\ |
#define SSE_OP(op)\ |
1931 |
{\ |
{\ |
1932 |
asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\ |
asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\ |
1933 |
printf("%-9s: a=%016llx%016llx b=%016llx%016llx r=%016llx%016llx\n",\ |
printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\ |
1934 |
#op,\ |
#op,\ |
1935 |
a.q[1], a.q[0],\ |
a.q[1], a.q[0],\ |
1936 |
b.q[1], b.q[0],\ |
b.q[1], b.q[0],\ |
1956 |
a.q[0] = test_values[2*i][0];\ |
a.q[0] = test_values[2*i][0];\ |
1957 |
b.q[0] = test_values[2*i+1][0];\ |
b.q[0] = test_values[2*i+1][0];\ |
1958 |
asm volatile (#op " %2, %0" : "=y" (r.q[0]) : "0" (a.q[0]), "y" (b.q[0]));\ |
asm volatile (#op " %2, %0" : "=y" (r.q[0]) : "0" (a.q[0]), "y" (b.q[0]));\ |
1959 |
printf("%-9s: a=%016llx b=%016llx r=%016llx\n",\ |
printf("%-9s: a=" FMT64X " b=" FMT64X " r=" FMT64X "\n",\ |
1960 |
#op,\ |
#op,\ |
1961 |
a.q[0],\ |
a.q[0],\ |
1962 |
b.q[0],\ |
b.q[0],\ |
1972 |
b.q[0] = test_values[1][0];\ |
b.q[0] = test_values[1][0];\ |
1973 |
b.q[1] = test_values[1][1];\ |
b.q[1] = test_values[1][1];\ |
1974 |
asm volatile (#op " $" #ib ", %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\ |
asm volatile (#op " $" #ib ", %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\ |
1975 |
printf("%-9s: a=%016llx%016llx b=%016llx%016llx ib=%02x r=%016llx%016llx\n",\ |
printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\ |
1976 |
#op,\ |
#op,\ |
1977 |
a.q[1], a.q[0],\ |
a.q[1], a.q[0],\ |
1978 |
b.q[1], b.q[0],\ |
b.q[1], b.q[0],\ |
1987 |
a.q[0] = test_values[2*i][0];\ |
a.q[0] = test_values[2*i][0];\ |
1988 |
a.q[1] = test_values[2*i][1];\ |
a.q[1] = test_values[2*i][1];\ |
1989 |
asm volatile (#op " $" #ib ", %1, %0" : "=x" (r.dq) : "x" (a.dq));\ |
asm volatile (#op " $" #ib ", %1, %0" : "=x" (r.dq) : "x" (a.dq));\ |
1990 |
printf("%-9s: a=%016llx%016llx ib=%02x r=%016llx%016llx\n",\ |
printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\ |
1991 |
#op,\ |
#op,\ |
1992 |
a.q[1], a.q[0],\ |
a.q[1], a.q[0],\ |
1993 |
ib,\ |
ib,\ |
2002 |
a.q[0] = test_values[2*i][0];\ |
a.q[0] = test_values[2*i][0];\ |
2003 |
a.q[1] = test_values[2*i][1];\ |
a.q[1] = test_values[2*i][1];\ |
2004 |
asm volatile (#op " $" #ib ", %0" : "=x" (r.dq) : "0" (a.dq));\ |
asm volatile (#op " $" #ib ", %0" : "=x" (r.dq) : "0" (a.dq));\ |
2005 |
printf("%-9s: a=%016llx%016llx ib=%02x r=%016llx%016llx\n",\ |
printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\ |
2006 |
#op,\ |
#op,\ |
2007 |
a.q[1], a.q[0],\ |
a.q[1], a.q[0],\ |
2008 |
ib,\ |
ib,\ |
2020 |
b.q[0] = ib;\ |
b.q[0] = ib;\ |
2021 |
b.q[1] = 0;\ |
b.q[1] = 0;\ |
2022 |
asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\ |
asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\ |
2023 |
printf("%-9s: a=%016llx%016llx b=%016llx%016llx r=%016llx%016llx\n",\ |
printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\ |
2024 |
#op,\ |
#op,\ |
2025 |
a.q[1], a.q[0],\ |
a.q[1], a.q[0],\ |
2026 |
b.q[1], b.q[0],\ |
b.q[1], b.q[0],\ |
2035 |
a.q[0] = test_values[2*i][0];\ |
a.q[0] = test_values[2*i][0];\ |
2036 |
a.q[1] = test_values[2*i][1];\ |
a.q[1] = test_values[2*i][1];\ |
2037 |
asm volatile (#op " %1, %0" : "=r" (reg) : "x" (a.dq));\ |
asm volatile (#op " %1, %0" : "=r" (reg) : "x" (a.dq));\ |
2038 |
printf("%-9s: a=%016llx%016llx r=%08x\n",\ |
printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\ |
2039 |
#op,\ |
#op,\ |
2040 |
a.q[1], a.q[0],\ |
a.q[1], a.q[0],\ |
2041 |
reg);\ |
reg);\ |
2077 |
#define CVT_OP_XMM(op)\ |
#define CVT_OP_XMM(op)\ |
2078 |
{\ |
{\ |
2079 |
asm volatile (#op " %1, %0" : "=x" (r.dq) : "x" (a.dq));\ |
asm volatile (#op " %1, %0" : "=x" (r.dq) : "x" (a.dq));\ |
2080 |
printf("%-9s: a=%016llx%016llx r=%016llx%016llx\n",\ |
printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\ |
2081 |
#op,\ |
#op,\ |
2082 |
a.q[1], a.q[0],\ |
a.q[1], a.q[0],\ |
2083 |
r.q[1], r.q[0]);\ |
r.q[1], r.q[0]);\ |
2086 |
#define CVT_OP_XMM2MMX(op)\ |
#define CVT_OP_XMM2MMX(op)\ |
2087 |
{\ |
{\ |
2088 |
asm volatile (#op " %1, %0" : "=y" (r.q[0]) : "x" (a.dq));\ |
asm volatile (#op " %1, %0" : "=y" (r.q[0]) : "x" (a.dq));\ |
2089 |
printf("%-9s: a=%016llx%016llx r=%016llx\n",\ |
printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "\n",\ |
2090 |
#op,\ |
#op,\ |
2091 |
a.q[1], a.q[0],\ |
a.q[1], a.q[0],\ |
2092 |
r.q[0]);\ |
r.q[0]);\ |
2095 |
#define CVT_OP_MMX2XMM(op)\ |
#define CVT_OP_MMX2XMM(op)\ |
2096 |
{\ |
{\ |
2097 |
asm volatile (#op " %1, %0" : "=x" (r.dq) : "y" (a.q[0]));\ |
asm volatile (#op " %1, %0" : "=x" (r.dq) : "y" (a.q[0]));\ |
2098 |
printf("%-9s: a=%016llx r=%016llx%016llx\n",\ |
printf("%-9s: a=" FMT64X " r=" FMT64X "" FMT64X "\n",\ |
2099 |
#op,\ |
#op,\ |
2100 |
a.q[0],\ |
a.q[0],\ |
2101 |
r.q[1], r.q[0]);\ |
r.q[1], r.q[0]);\ |
2104 |
#define CVT_OP_REG2XMM(op)\ |
#define CVT_OP_REG2XMM(op)\ |
2105 |
{\ |
{\ |
2106 |
asm volatile (#op " %1, %0" : "=x" (r.dq) : "r" (a.l[0]));\ |
asm volatile (#op " %1, %0" : "=x" (r.dq) : "r" (a.l[0]));\ |
2107 |
printf("%-9s: a=%08x r=%016llx%016llx\n",\ |
printf("%-9s: a=%08x r=" FMT64X "" FMT64X "\n",\ |
2108 |
#op,\ |
#op,\ |
2109 |
a.l[0],\ |
a.l[0],\ |
2110 |
r.q[1], r.q[0]);\ |
r.q[1], r.q[0]);\ |
2113 |
#define CVT_OP_XMM2REG(op)\ |
#define CVT_OP_XMM2REG(op)\ |
2114 |
{\ |
{\ |
2115 |
asm volatile (#op " %1, %0" : "=r" (r.l[0]) : "x" (a.dq));\ |
asm volatile (#op " %1, %0" : "=r" (r.l[0]) : "x" (a.dq));\ |
2116 |
printf("%-9s: a=%016llx%016llx r=%08x\n",\ |
printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\ |
2117 |
#op,\ |
#op,\ |
2118 |
a.q[1], a.q[0],\ |
a.q[1], a.q[0],\ |
2119 |
r.l[0]);\ |
r.l[0]);\ |
2144 |
{ |
{ |
2145 |
struct fpxstate *fp = &fpx_state; |
struct fpxstate *fp = &fpx_state; |
2146 |
struct fpxstate *fp2 = &fpx_state2; |
struct fpxstate *fp2 = &fpx_state2; |
2147 |
int i; |
int i, nb_xmm; |
2148 |
XMMReg a, b; |
XMMReg a, b; |
2149 |
a.q[0] = test_values[0][0]; |
a.q[0] = test_values[0][0]; |
2150 |
a.q[1] = test_values[0][1]; |
a.q[1] = test_values[0][1]; |
2153 |
|
|
2154 |
asm("movdqa %2, %%xmm0\n" |
asm("movdqa %2, %%xmm0\n" |
2155 |
"movdqa %3, %%xmm7\n" |
"movdqa %3, %%xmm7\n" |
2156 |
|
#if defined(__x86_64__) |
2157 |
|
"movdqa %2, %%xmm15\n" |
2158 |
|
#endif |
2159 |
" fld1\n" |
" fld1\n" |
2160 |
" fldpi\n" |
" fldpi\n" |
2161 |
" fldln2\n" |
" fldln2\n" |
2169 |
printf("fpus=%04x\n", fp->fpus); |
printf("fpus=%04x\n", fp->fpus); |
2170 |
printf("fptag=%04x\n", fp->fptag); |
printf("fptag=%04x\n", fp->fptag); |
2171 |
for(i = 0; i < 3; i++) { |
for(i = 0; i < 3; i++) { |
2172 |
printf("ST%d: %016llx %04x\n", |
printf("ST%d: " FMT64X " %04x\n", |
2173 |
i, |
i, |
2174 |
*(uint64_t *)&fp->fpregs1[i * 16], |
*(uint64_t *)&fp->fpregs1[i * 16], |
2175 |
*(uint16_t *)&fp->fpregs1[i * 16 + 8]); |
*(uint16_t *)&fp->fpregs1[i * 16 + 8]); |
2176 |
} |
} |
2177 |
printf("mxcsr=%08x\n", fp->mxcsr & 0x1f80); |
printf("mxcsr=%08x\n", fp->mxcsr & 0x1f80); |
2178 |
for(i = 0; i < 8; i++) { |
#if defined(__x86_64__) |
2179 |
printf("xmm%d: %016llx%016llx\n", |
nb_xmm = 16; |
2180 |
|
#else |
2181 |
|
nb_xmm = 8; |
2182 |
|
#endif |
2183 |
|
for(i = 0; i < nb_xmm; i++) { |
2184 |
|
printf("xmm%d: " FMT64X "" FMT64X "\n", |
2185 |
i, |
i, |
2186 |
*(uint64_t *)&fp->xmm_regs[i * 16], |
*(uint64_t *)&fp->xmm_regs[i * 16], |
2187 |
*(uint64_t *)&fp->xmm_regs[i * 16 + 8]); |
*(uint64_t *)&fp->xmm_regs[i * 16 + 8]); |
2245 |
MMX_OP2(pavgw); |
MMX_OP2(pavgw); |
2246 |
|
|
2247 |
asm volatile ("pinsrw $1, %1, %0" : "=y" (r.q[0]) : "r" (0x12345678)); |
asm volatile ("pinsrw $1, %1, %0" : "=y" (r.q[0]) : "r" (0x12345678)); |
2248 |
printf("%-9s: r=%016llx\n", "pinsrw", r.q[0]); |
printf("%-9s: r=" FMT64X "\n", "pinsrw", r.q[0]); |
2249 |
|
|
2250 |
asm volatile ("pinsrw $5, %1, %0" : "=x" (r.dq) : "r" (0x12345678)); |
asm volatile ("pinsrw $5, %1, %0" : "=x" (r.dq) : "r" (0x12345678)); |
2251 |
printf("%-9s: r=%016llx%016llx\n", "pinsrw", r.q[1], r.q[0]); |
printf("%-9s: r=" FMT64X "" FMT64X "\n", "pinsrw", r.q[1], r.q[0]); |
2252 |
|
|
2253 |
a.q[0] = test_values[0][0]; |
a.q[0] = test_values[0][0]; |
2254 |
a.q[1] = test_values[0][1]; |
a.q[1] = test_values[0][1]; |
2275 |
asm volatile("maskmovq %1, %0" : |
asm volatile("maskmovq %1, %0" : |
2276 |
: "y" (a.q[0]), "y" (b.q[0]), "D" (&r) |
: "y" (a.q[0]), "y" (b.q[0]), "D" (&r) |
2277 |
: "memory"); |
: "memory"); |
2278 |
printf("%-9s: r=%016llx a=%016llx b=%016llx\n", |
printf("%-9s: r=" FMT64X " a=" FMT64X " b=" FMT64X "\n", |
2279 |
"maskmov", |
"maskmov", |
2280 |
r.q[0], |
r.q[0], |
2281 |
a.q[0], |
a.q[0], |
2283 |
asm volatile("maskmovdqu %1, %0" : |
asm volatile("maskmovdqu %1, %0" : |
2284 |
: "x" (a.dq), "x" (b.dq), "D" (&r) |
: "x" (a.dq), "x" (b.dq), "D" (&r) |
2285 |
: "memory"); |
: "memory"); |
2286 |
printf("%-9s: r=%016llx%016llx a=%016llx%016llx b=%016llx%016llx\n", |
printf("%-9s: r=" FMT64X "" FMT64X " a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X "\n", |
2287 |
"maskmov", |
"maskmov", |
2288 |
r.q[1], r.q[0], |
r.q[1], r.q[0], |
2289 |
a.q[1], a.q[0], |
a.q[1], a.q[0], |
2445 |
|
|
2446 |
#endif |
#endif |
2447 |
|
|
2448 |
static void *call_end __init_call = NULL; |
extern void *__start_initcall; |
2449 |
|
extern void *__stop_initcall; |
2450 |
|
|
2451 |
|
|
2452 |
int main(int argc, char **argv) |
int main(int argc, char **argv) |
2453 |
{ |
{ |
2454 |
void **ptr; |
void **ptr; |
2455 |
void (*func)(void); |
void (*func)(void); |
2456 |
|
|
2457 |
ptr = &call_start + 1; |
ptr = &__start_initcall; |
2458 |
while (*ptr != NULL) { |
while (ptr != &__stop_initcall) { |
2459 |
func = *ptr++; |
func = *ptr++; |
2460 |
func(); |
func(); |
2461 |
} |
} |
2463 |
test_mul(); |
test_mul(); |
2464 |
test_jcc(); |
test_jcc(); |
2465 |
test_floats(); |
test_floats(); |
2466 |
|
#if !defined(__x86_64__) |
2467 |
test_bcd(); |
test_bcd(); |
2468 |
|
#endif |
2469 |
test_xchg(); |
test_xchg(); |
2470 |
test_string(); |
test_string(); |
2471 |
test_misc(); |
test_misc(); |
2472 |
test_lea(); |
test_lea(); |
2473 |
|
#ifdef TEST_SEGS |
2474 |
test_segs(); |
test_segs(); |
2475 |
test_code16(); |
test_code16(); |
2476 |
|
#endif |
2477 |
#ifdef TEST_VM86 |
#ifdef TEST_VM86 |
2478 |
test_vm86(); |
test_vm86(); |
2479 |
#endif |
#endif |
2480 |
test_exceptions(); |
test_exceptions(); |
2481 |
|
#if !defined(__x86_64__) |
2482 |
test_self_modifying_code(); |
test_self_modifying_code(); |
2483 |
test_single_step(); |
test_single_step(); |
2484 |
|
#endif |
2485 |
test_enter(); |
test_enter(); |
2486 |
#ifdef TEST_SSE |
#ifdef TEST_SSE |
2487 |
test_sse(); |
test_sse(); |