4 #include "tests/malloc.h"
6 typedef unsigned char UChar
;
7 typedef unsigned int UInt
;
8 typedef unsigned long int UWord
;
9 typedef unsigned long long int ULong
;
11 #define IS_32_ALIGNED(_ptr) (0 == (0x1F & (UWord)(_ptr)))
13 typedef union { UChar u8
[32]; UInt u32
[8]; } YMM
;
15 typedef struct { YMM a1
; YMM a2
; YMM a3
; YMM a4
; ULong u64
; } Block
;
17 void showYMM ( YMM
* vec
)
20 assert(IS_32_ALIGNED(vec
));
21 for (i
= 31; i
>= 0; i
--) {
22 printf("%02x", (UInt
)vec
->u8
[i
]);
23 if (i
> 0 && 0 == ((i
+0) & 7)) printf(".");
27 void showBlock ( char* msg
, Block
* block
)
30 printf(" "); showYMM(&block
->a1
); printf("\n");
31 printf(" "); showYMM(&block
->a2
); printf("\n");
32 printf(" "); showYMM(&block
->a3
); printf("\n");
33 printf(" "); showYMM(&block
->a4
); printf("\n");
34 printf(" %016llx\n", block
->u64
);
37 UChar
randUChar ( void )
39 static UInt seed
= 80021;
40 seed
= 1103515245 * seed
+ 12345;
41 return (seed
>> 17) & 0xFF;
44 void randBlock ( Block
* b
)
48 for (i
= 0; i
< sizeof(Block
); i
++)
52 /* Generate a function test_NAME, that tests the given insn, in both
53 its mem and reg forms. The reg form of the insn may mention, as
54 operands only %ymm6, %ymm7, %ymm8, %ymm9 and %r14. The mem form of
55 the insn may mention as operands only (%rsi), %ymm7, %ymm8, %ymm9
56 and %r14. It's OK for the insn to clobber ymm0, rax and rdx, as these
57 are needed for testing PCMPxSTRx, and ymm6, as this is needed for testing
60 #define GEN_test_RandM(_name, _reg_form, _mem_form) \
62 __attribute__ ((noinline)) static void test_##_name ( void ) \
64 Block* b = memalign32(sizeof(Block)); \
66 printf("%s(reg)\n", #_name); \
67 showBlock("before", b); \
68 __asm__ __volatile__( \
69 "vmovdqa 0(%0),%%ymm7" "\n\t" \
70 "vmovdqa 32(%0),%%ymm8" "\n\t" \
71 "vmovdqa 64(%0),%%ymm6" "\n\t" \
72 "vmovdqa 96(%0),%%ymm9" "\n\t" \
73 "movq 128(%0),%%r14" "\n\t" \
75 "vmovdqa %%ymm7, 0(%0)" "\n\t" \
76 "vmovdqa %%ymm8, 32(%0)" "\n\t" \
77 "vmovdqa %%ymm6, 64(%0)" "\n\t" \
78 "vmovdqa %%ymm9, 96(%0)" "\n\t" \
79 "movq %%r14, 128(%0)" "\n\t" \
82 : /*TRASH*/"xmm0","xmm7","xmm8","xmm6","xmm9","r14","memory","cc", \
85 showBlock("after", b); \
87 printf("%s(mem)\n", #_name); \
88 showBlock("before", b); \
89 __asm__ __volatile__( \
90 "leaq 0(%0),%%rsi" "\n\t" \
91 "vmovdqa 32(%0),%%ymm8" "\n\t" \
92 "vmovdqa 64(%0),%%ymm7" "\n\t" \
93 "vmovdqa 96(%0),%%ymm9" "\n\t" \
94 "movq 128(%0),%%r14" "\n\t" \
96 "vmovdqa %%ymm8, 32(%0)" "\n\t" \
97 "vmovdqa %%ymm7, 64(%0)" "\n\t" \
98 "vmovdqa %%ymm9, 96(%0)" "\n\t" \
99 "movq %%r14, 128(%0)" "\n\t" \
103 "xmm0","xmm8","xmm7","xmm9","r14","rsi","memory","cc", \
106 showBlock("after", b); \
111 #define GEN_test_Ronly(_name, _reg_form) \
112 GEN_test_RandM(_name, _reg_form, "")
113 #define GEN_test_Monly(_name, _mem_form) \
114 GEN_test_RandM(_name, "", _mem_form)
116 /* Comment duplicated above, for convenient reference:
117 Allowed operands in test insns:
118 Reg form: %ymm6, %ymm7, %ymm8, %ymm9 and %r14.
119 Mem form: (%rsi), %ymm7, %ymm8, %ymm9 and %r14.
120 Imm8 etc fields are also allowed, where they make sense.
121 Both forms may use ymm0, rax and rdx as scratch.
122 Mem form may also use ymm6 as scratch.
125 #define N_DEFAULT_ITERS 3
127 // Do the specified test some number of times
128 #define DO_N(_iters, _testfn) \
129 do { int i; for (i = 0; i < (_iters); i++) { test_##_testfn(); } } while (0)
131 // Do the specified test the default number of times
132 #define DO_D(_testfn) DO_N(N_DEFAULT_ITERS, _testfn)