Bug 497723 - forgot to restore callgrind output cleanup
[valgrind.git] / none / tests / ppc64 / test_lxvx_stxvx.c
blobe4525d46e1eab10f22fd4717dc4fc84abc4c0dca
1 /*
2 * test_lxvx_stxvx.c:
4 * The lxvx and stxvx instructions were extended mnemonics
5 * of the lxvd2x and stxvd2x instructions, which are Big-Endian
6 * by design in ISA 2.07 and earlier.
7 * Beginning with ISA 3.0 these are unique instructions and
8 * are endian aware.
9 * Tests of those instructions must be aware of which
10 * ISA level the code is being compiled to.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License V2
16 * as published by the Free Software Foundation
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <http://www.gnu.org/licenses/>.
27 #include <stdio.h>
28 #include <stdint.h>
30 #ifdef HAS_ISA_2_07
31 #include <assert.h>
32 #include <ctype.h> // isspace
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h> // getopt
36 #include <altivec.h> // vector
37 #include <malloc.h> // memalign
39 #undef DEBUG_VECTOR_PERMUTE
40 static int verbose = 0;
42 typedef uint64_t HWord_t;
44 /* Define a small memory range used to test load-from and store-to vsx */
45 #define BUFFER_SIZE 4
46 #define MAX_BUFFER_PATTERNS 6
47 unsigned long buffer[BUFFER_SIZE];
49 static void dump_small_buffer(void) {
50 int x;
52 printf("[ ");
54 for (x = 0; x < BUFFER_SIZE; x++)
55 printf("%016lx ", buffer[x] );
57 printf("]");
60 static void initialize_buffer(int t)
62 int x;
64 for (x = 0; x < BUFFER_SIZE; x++)
65 /* Don't want each of the 32-bit chunks to be identical. Loads of a
66 * byte from the wrong 32-bit chuck are not detectable if the chunks
67 * are identical.
69 switch((t+x)%BUFFER_SIZE) {
70 case 0:
71 buffer[x] = 0xffffffffffffffff;
72 break;
73 case 1:
74 buffer[x] = 0x0001020304050607;
75 break;
76 case 2:
77 buffer[x] = 0x5555555555555555;
78 break;
79 case 3:
80 buffer[x] = 0x0000000000000000;
81 break;
82 case 4:
83 buffer[x] = 0x5a05a05a05a05a05;
84 break;
85 case 5:
86 buffer[x] = 0x0102030405060708;
87 break;
88 default:
89 buffer[x] = 0x1010101010101010;
90 break;
94 #define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
96 #define SET_CR(_arg) \
97 __asm__ __volatile__ ("mtcr %0" : : "b"(_arg) : ALLCR );
99 #define SET_CR_ZERO \
100 SET_CR(0)
102 #define GET_CR(_lval) \
103 __asm__ __volatile__ ("mfcr %0" : "=b"(_lval) )
105 #define GET_XER(_lval) \
106 __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) )
108 #define SET_CR_ZERO \
109 SET_CR(0)
111 /* a table of exponent values for use in the float precision tests. */
112 unsigned long exponent_table[] = {
113 #ifdef EXHAUSTIVE_TESTS
114 0x0000, /* +/-0 or +/-DENormalized, depending on associated mantissa. */
115 0x1a, /* within NORmalized for 16,32,64,128-bit. */
116 0x1f, /* +/-INF or +/-NaN for 16bit, NORmalized for 32,64,128 */
117 0xff, /* +/-INF or +/-NaN for 32bit, NORmalized for 64,128 */
118 0x7ff, /* +/-INF or +/-NaN for 32 and 64bit, NORmalized for 128 */
119 0x7fff, /* +/-INF or +/-NaN for 128bit. */
120 #else
121 0x0000, /* +/-0 or +/-DENormalized, depending on associated mantissa. */
122 0xff, /* +/-INF or +/-NaN for 32bit, NORmalized for 64,128 */
123 0x7ff, /* +/-INF or +/-NaN for 32 and 64bit, NORmalized for 128 */
124 0x7fff, /* +/-INF or +/-NaN for 128bit. */
125 #endif
127 #define MAX_EXPONENTS (sizeof(exponent_table) / sizeof(unsigned long))
129 unsigned long nb_float_vsxargs;
131 #define MAX_FLOAT_VSX_ARRAY_SIZE (((MAX_EXPONENTS * MAX_MANTISSAS) * 2 + 1) * 2)
133 static unsigned long * vsxargs = NULL;
134 unsigned long nb_vargs;
136 #define MAX_VSX_ARRAY_SIZE 42
138 static void build_vsx_table (void)
140 long i = 0;
141 // A VSX register is 128-bits wide.
142 // We build contents here using pairs of 64-bit longs.
143 // Permutes work against two (non-paired) VSX regs, so these are
144 // also grouped by twos.
145 vsxargs = memalign(16, MAX_VSX_ARRAY_SIZE * sizeof(unsigned long));
146 #ifdef EXHAUSTIVE_TESTS
147 vsxargs[i++] = 0x0000000000000000UL; vsxargs[i++] = 0x0000000000000000UL;
148 vsxargs[i++] = 0x0102030405060708UL; vsxargs[i++] = 0x0102010201020102UL;
150 vsxargs[i++] = 0xaaaaaaaaaaaaaaaaUL; vsxargs[i++] = 0xaaaaaaaaaaaaaaaaUL;
151 vsxargs[i++] = 0x5555555555555555UL; vsxargs[i++] = 0x5555555555555555UL;
153 vsxargs[i++] = 0x08090a0b0c0d0e0fUL; vsxargs[i++] = 0x0102010201020102UL;
154 vsxargs[i++] = 0xf0f1f2f3f4f5f6f7UL; vsxargs[i++] = 0xf8f9fafbfcfdfeffUL;
156 vsxargs[i++] = 0x7ea1a5a7abadb0baUL; vsxargs[i++] = 0x070d111d1e555e70UL;
157 vsxargs[i++] = 0xe5e7ecedeff0f1faUL; vsxargs[i++] = 0xbeb1c0caced0dbdeUL;
159 vsxargs[i++] = 0x00115e7eadbabec0UL; vsxargs[i++] = 0xced0deede5ecef00UL;
160 vsxargs[i++] = 0x00111e7ea5abadb1UL; vsxargs[i++] = 0xbecad0deedeffe00UL;
162 vsxargs[i++] = 0x0011223344556677UL; vsxargs[i++] = 0x8899aabbccddeeffUL;
163 vsxargs[i++] = 0xf0e0d0c0b0a09080UL; vsxargs[i++] = 0x7060504030201000UL;
164 #else
165 vsxargs[i++] = 0x0000000000000000UL; vsxargs[i++] = 0x0000000000000000UL;
166 vsxargs[i++] = 0x0102030405060708UL; vsxargs[i++] = 0x0102010201020102UL;
168 vsxargs[i++] = 0x0011223344556677UL; vsxargs[i++] = 0x8899aabbccddeeffUL;
169 vsxargs[i++] = 0xf0e0d0c0b0a09080UL; vsxargs[i++] = 0x7060504030201000UL;
170 #endif
172 // these next three groups are specific for vector rotate tests.
173 // bits 11:15,19:23,27:31 of each 32-bit word contain mb,me,sh values.
174 vsxargs[i++] = 0x0000100000001002ULL; vsxargs[i++] = 0x0000100800001010ULL;
175 vsxargs[i++] = 0x0010100000101002ULL; vsxargs[i++] = 0x0010100800101010ULL;
177 // vector rotate special...
178 vsxargs[i++] = 0x00001c0000001c02ULL; vsxargs[i++] = 0x00001c0800001c10ULL;
179 vsxargs[i++] = 0x00101c0000101c02ULL; vsxargs[i++] = 0x00101c0800101c10ULL;
181 // vector rotate special...
182 vsxargs[i++] = 0x00001f0000001f02ULL; vsxargs[i++] = 0x00001f0800001f10ULL;
183 vsxargs[i++] = 0x00101f0000101f02ULL; vsxargs[i++] = 0x00101f0800101f10ULL;
185 nb_vargs = i;
188 #define VERBOSE_FUNCTION_CALLOUT \
189 if (verbose) \
190 printf("Test Harness Function: %s\n", __FUNCTION__);
192 /* XXXX these must all be callee-save regs! */
193 register HWord_t r14 __asm__ ("r14");
194 register HWord_t r15 __asm__ ("r15");
195 register HWord_t r16 __asm__ ("r16");
196 register HWord_t r17 __asm__ ("r17");
197 register double f14 __asm__ ("fr14");
198 register double f15 __asm__ ("fr15");
200 /* globals used for vector tests */
201 static vector unsigned long vec_xt;
203 /* globals for the condition register fields. These are used to
204 * capture the condition register values immediately after the
205 * instruction under test is tested.
206 * This is to help prevent other test overhead, switch statements,
207 * compares, what-not from interfering.
209 unsigned long local_cr;
210 unsigned long local_fpscr;
211 unsigned long local_xer;
212 volatile unsigned int cr_value;
214 /* global for holding the DFP values */
215 //dfp_val_t dfp_value;
217 /* individual instruction tests */
218 typedef void (*test_func_t) (void);
219 struct test_list_t {
220 test_func_t func;
221 const char *name;
223 typedef struct test_list_t test_list_t;
225 /* vector splat value */
226 volatile int x_splat;
227 //volatile int dfp_significance;
229 /* groups of instruction tests, calling individual tests */
230 typedef void (*test_group_t) (const char *name, test_func_t func,
231 unsigned int test_flags);
233 enum test_flags {
234 unused = 0,
235 /* Nb arguments */
238 static void test_lxvx(void) {
239 __asm__ __volatile__ ("lxvx %x0, 14, 15" : "=wa" (vec_xt));
243 static void test_stxvx(void) {
244 __asm__ __volatile__ ("stxvx %x0, 14, 15" :: "wa" (vec_xt));
247 static test_list_t testgroup_vector_loadstore[] = {
248 { &test_lxvx , "lxvx" },
249 { &test_stxvx , "stxvx" },
250 { NULL , NULL },
253 /* table containing all of the instruction groups */
254 struct test_group_table_t {
255 test_list_t *tests;
256 const char *name;
257 unsigned int flags;
260 typedef struct test_group_table_t test_group_table_t;
262 static test_group_table_t all_tests[] = {
264 testgroup_vector_loadstore,
265 "ppc vector load/store",
268 { NULL, NULL, 0x00000000, },
271 static void testfunction_vector_loadstore (const char* instruction_name,
272 test_func_t test_function,
273 unsigned int ignore_flags) {
274 /* exercises vector loads from memory, and vector stores from memory.
275 * <load or store instruction> XS, RA, RB
276 * For these tests, RA will be zero.
277 * EA is then, simply, RB. */
278 int i;
279 int buffer_pattern;
281 VERBOSE_FUNCTION_CALLOUT
283 for (i = 0; i < nb_vargs; i += 2) {
285 vec_xt = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
286 r14 = 0;
287 r15 = (unsigned long) & buffer;
289 for (buffer_pattern = 0; buffer_pattern < MAX_BUFFER_PATTERNS;
290 buffer_pattern++) {
292 /* set patterns on both ends */
293 initialize_buffer(buffer_pattern);
295 printf("%s ", instruction_name);
296 printf("%016lx %016lx ", (unsigned long)vec_xt[1],
297 (unsigned long)vec_xt[0]);
298 dump_small_buffer();
299 printf(" =>\n");
301 (*test_function)();
303 printf("\t\t\t\t%016lx %016lx ", (unsigned long)vec_xt[1],
304 (unsigned long)vec_xt[0]);
305 dump_small_buffer();
306 printf("\n");
311 typedef struct insn_sel_flags_t_struct {
312 unsigned int cr;
313 } insn_sel_flags_t;
315 static void do_tests ( insn_sel_flags_t seln_flags)
317 test_group_t group_function;
318 int n = 0;
319 int j = 0;
320 int i = 0;
322 test_list_t *tests;
324 printf("%s:\n", all_tests[i].name);
325 group_function = &testfunction_vector_loadstore;
326 tests = all_tests[i].tests;
328 for (j = 0; tests[j].name != NULL; j++) {
329 (*group_function)(tests[j].name, tests[j].func, 0);
330 printf("\n");
331 n++;
333 printf("\n");
334 n++;
336 if (verbose) printf("\n");
338 printf("All done. Tested %d different instructions\n", n);
340 #endif
342 int main (int argc, char **argv)
344 #ifdef HAS_ISA_2_07
345 insn_sel_flags_t flags;
347 build_vsx_table();
349 do_tests( flags );
350 #else
351 printf("HAS_ISA_2_07 not detected.\n");
352 #endif
353 return 0;