Bug 497723 - forgot to restore callgrind output cleanup
[valgrind.git] / none / tests / ppc64 / subnormal_test.c
blob6e033706fe08ebbe172ae0fdfaeeb26c41b60820
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <stdlib.h>
5 #ifdef HAS_ISA_2_06
7 #include <string.h>
8 #include <malloc.h>
9 #include <altivec.h>
11 #define NUM_ARGS 14
12 #define MAX_RESULTS NUM_ARGS
13 #define START_i 0
14 #define STOP_i 14
16 #define START_j 0
17 #define STOP_j 14
19 #define START_k 0
20 #define STOP_k 14
22 union convert_t {
23 unsigned int u;
24 float f;
25 } convert;
27 #define PRINT_FLOAT 0
28 #define PRINT_HEX 1
30 void print_vector_elements(vector unsigned long src) {
31 unsigned int element0, element1, element2, element3;
33 element0 = (unsigned int)((src[0] >> 32) & 0xFFFFFFFF);
34 element1 = (unsigned int)(src[0] & 0xFFFFFFFF);
35 element2 = (unsigned int)((src[1] >> 32) & 0xFFFFFFFF);
36 element3 = (unsigned int)(src[1] & 0xFFFFFFFF);
38 convert.u = element0;
40 #if PRINT_FLOAT
41 printf(" %8.4e,", convert.f);
42 #endif
43 #if PRINT_HEX
44 printf(" 0x%08x,", convert.u);
45 #endif
47 convert.u = element1;
48 #if PRINT_FLOAT
49 printf(" %8.4e,", convert.f);
50 #endif
51 #if PRINT_HEX
52 printf(" 0x%08x,", convert.u);
53 #endif
55 convert.u = element2;
56 #if PRINT_FLOAT
57 printf(" %8.4e,", convert.f);
58 #endif
59 #if PRINT_HEX
60 printf(" 0x%08x,", convert.u);
61 #endif
63 convert.u = element3;
64 #if PRINT_FLOAT
65 printf(" %8.4e", convert.f);
66 #endif
67 #if PRINT_HEX
68 printf(" 0x%08x", convert.u);
69 #endif
70 printf("\n");
73 void do_tests( void ) {
75 vector unsigned long srcA, srcB, srcC, arg_list[NUM_ARGS], dst;
76 int i, j, k;
78 srcA[0] = 0; // initialize to remove compiler warnings
79 srcA[1] = 0;
80 srcB[0] = 0; // initialize to remove compiler warnings
81 srcB[1] = 0;
82 srcC[0] = 0; // initialize to remove compiler warnings
83 srcC[1] = 0;
85 arg_list[0][0] = 0x8000012480000124ULL;
86 arg_list[0][1] = 0x8000012480000124ULL;
88 arg_list[1][0] = 0x8000012480000124ULL;
89 arg_list[1][1] = 0x8000012480000124ULL;
91 arg_list[2][0] = 0x000000060000000CULL;
92 arg_list[2][1] = 0x000000080000000AULL;
94 arg_list[3][0] = 0xFFFFFAFAFFFFFBFBULL;
95 arg_list[3][1] = 0xFFFFFEFCFFFFFDFDULL;
97 arg_list[4][0] = 0x0000024800000258ULL;
98 arg_list[4][1] = 0x0000026800000278ULL;
100 arg_list[5][0] = 0x0000000200000002ULL;
101 arg_list[5][1] = 0x0000000400000008ULL;
103 arg_list[6][0] = 0xC3000000C3020000ULL;
104 arg_list[6][1] = 0xC2FE0000C2FD0000ULL;
106 arg_list[7][0] = 0xc3000000c3020000ULL;
107 arg_list[7][1] = 0xc2fe0000c2fd0000ULL;
109 arg_list[8][0] = 0xC2FE0000C2FD0000ULL;
110 arg_list[8][1] = 0x0000000400000002ULL;
112 arg_list[9][0] = 0xC2FE0000C2FD0000ULL;
113 arg_list[9][1] = 0x7E9676997E700022ULL;
115 arg_list[10][0] = 0x80B0000180B00002ULL;
116 arg_list[10][1] = 0x80B0000480B00006ULL;
118 arg_list[11][0] = 0x80B0000080B00001ULL;
119 arg_list[11][1] = 0x80B0000280B00004ULL;
121 arg_list[12][0] = 0x4E8000004E800000ULL;
122 arg_list[12][1] = 0x4E8000004E800000ULL;
124 arg_list[13][0] = 0xB0000000B0000000ULL;
125 arg_list[13][1] = 0xB0000000B0000000ULL;
127 for ( i = START_i; i < STOP_i; i++) {
128 dst[0] = 0xFFFFFFFFFFFFFFFF;
129 dst[1] = 0xFFFFFFFFFFFFFFFF;
131 srcA[0] = arg_list[i][0];
132 srcA[1] = arg_list[i][1];
134 printf ("srcA = 0x%016lx 0x%016lx\n\n", (unsigned long)srcA[1],
135 (unsigned long) srcA[0]);
136 __asm__ __volatile__ ("vcfsx %0,%1,31" : "=v" (dst): "v" (srcA));
137 printf (" vcfsx(srcA) result = ");
138 print_vector_elements(dst);
140 __asm__ __volatile__ ("vcfux %0,%1,31" : "=v" (dst): "v" (srcA));
141 printf (" vcfux(srcA) result = ");
142 print_vector_elements(dst);
144 __asm__ __volatile__ ("vrfim %0,%1" : "=v" (dst): "v" (srcA));
145 printf (" vrfim(srcA) result = ");
146 print_vector_elements(dst);
148 __asm__ __volatile__ ("vrfin %0,%1" : "=v" (dst): "v" (srcA));
149 printf (" vrfin(srcA) result = ");
150 print_vector_elements(dst);
152 __asm__ __volatile__ ("vrfiz %0,%1" : "=v" (dst): "v" (srcA));
153 printf (" vrfiz(srcA) result = ");
154 print_vector_elements(dst);
157 __asm__ __volatile__ ("vexptefp %0,%1" : "=v" (dst): "v" (srcA));
158 printf (" vexptefp(srcA) result = ");
159 print_vector_elements(dst);
161 /* Smallest representable floating point input does not generate
162 a subnormal result. */
163 __asm__ __volatile__ ("vlogefp %0,%1" : "=v" (dst): "v" (srcA));
164 printf (" vlogefp(srcA) result = ");
165 print_vector_elements(dst);
167 __asm__ __volatile__ ("vrefp %0,%1" : "=v" (dst): "v" (srcA));
168 printf (" vrefp(srcA) result = ");
170 print_vector_elements(dst);
172 /* Square root of the smallest representable number is a normal
173 number. Square root can't generate a subnormal result. */
174 __asm__ __volatile__ ("vrsqrtefp %0,%1" : "=v" (dst): "v" (srcA));
175 printf (" vrsqrtefp(srcA) result = 0x%016lx 0x%016lx\n\n",
176 (unsigned long) dst[1], (unsigned long) dst[0]);
178 for ( j = START_j; j < STOP_j; j++) {
179 srcB[0] = arg_list[j][0];
180 srcB[1] = arg_list[j][1];
181 dst[0] = 0xFFFFFFFFFFFFFFFF;
182 dst[1] = 0xFFFFFFFFFFFFFFFF;
184 printf ("srcB = 0x%016lx 0x%016lx\n\n", (unsigned long) srcB[1],
185 (unsigned long) srcB[0]);
186 __asm__ __volatile__ ("vaddfp %0,%1,%2" : "=v" (dst): "v" (srcA), "v" (srcB));
187 printf (" vaddfp(srcA,srcB) result = ");
188 print_vector_elements(dst);
190 __asm__ __volatile__ ("vsubfp %0,%1,%2" : "=v" (dst): "v" (srcA), "v" (srcB));
191 printf (" vsubfp(srcA,srcB) result = ");
192 print_vector_elements(dst);
194 __asm__ __volatile__ ("vmaxfp %0,%1,%2" : "=v" (dst): "v" (srcA), "v" (srcB));
195 printf (" vmax(srcA,srcB) result = ");
196 print_vector_elements(dst);
198 __asm__ __volatile__ ("vminfp %0,%1,%2" : "=v" (dst): "v" (srcA), "v" (srcB));
199 printf (" vmin(srcA,srcB) result = ");
200 print_vector_elements(dst);
202 __asm__ __volatile__ ("vcmpbfp %0,%1,%2" : "=v" (dst): "v" (srcA), "v" (srcB));
203 printf (" vcmpbfp(srcA,srcB) result = ");
204 print_vector_elements(dst);
206 __asm__ __volatile__ ("vcmpeqfp %0,%1,%2" : "=v" (dst): "v" (srcA), "v" (srcB));
207 printf (" vcmpeqfp(srcA,srcB) result = ");
208 print_vector_elements(dst);
210 __asm__ __volatile__ ("vcmpgefp %0,%1,%2" : "=v" (dst): "v" (srcA), "v" (srcB));
211 printf (" vcmpgefp(srcA,srcB) result = ");
212 print_vector_elements(dst);
214 __asm__ __volatile__ ("vcmpgtfp %0,%1,%2" : "=v" (dst): "v" (srcA), "v" (srcB));
215 printf (" vcmpgtfp(srcA,srcB) result = ");
216 print_vector_elements(dst);
219 for ( k = START_k; k < STOP_k; k++) {
220 srcC[0] = arg_list[k][0];
221 srcC[1] = arg_list[k][1];
223 dst[0] = 0xFFFFFFFFFFFFFFFF;
224 dst[1] = 0xFFFFFFFFFFFFFFFF;
226 printf ("srcC = 0x%016lx 0x%016lx\n\n", (unsigned long) srcC[1],
227 (unsigned long) srcC[0]);
229 __asm__ __volatile__ ("vmaddfp %0,%1,%2,%3" : "=v" (dst): "v" (srcA), "v" (srcC), "v" (srcB));
230 printf("i=%d, j=%d, k=%d ", i, j, k);
231 printf (" vmaddfp(srcA,srcC,srcB) result = ");
232 print_vector_elements(dst);
234 __asm__ __volatile__ ("vnmsubfp %0,%1,%2,%3" : "=v" (dst): "v" (srcA), "v" (srcC), "v" (srcB));
235 printf("i=%d, j=%d, k=%d ", i, j, k);
236 printf (" vnmsubfp(srcA,srcC,srcB) result = ");
237 print_vector_elements(dst);
241 return;
243 #endif
245 int main()
247 #ifdef HAS_ISA_2_06
248 register vector unsigned long vreg, initial_vscr_value;
250 /* The VSCR[NJ] bit controlls how subnormal (denormal) results are handled
251 * by the various vector float instructions.
253 * If VSCR[NJ] = 0 then the subnormal result is returned.
254 * If VSCR[NJ] = 1 then the subnormal result is set to zero the sign is
255 * not changed.
257 * This tests verifies the VSCR[NJ] functionality for the vector float
258 * instructions.
261 /* Save the VSCR setting and restore it at the end. Don't want to screw
262 * up other tests with a different setting of the VSCR. */
263 __asm__ __volatile__ ("mfvscr %0" : "=v"(initial_vscr_value));
265 // set VSCR[nj] to 0 and run test
266 printf("Attempt to set VSR[NJ] to 0, run test\n");
268 vreg[0] = 0;
269 vreg[1] = 0;
270 __asm__ __volatile__ ("mtvscr %0" :: "v"(vreg));
272 // Read VSCR
273 __asm__ __volatile__ ("mfvscr %0" : "=v"(vreg));
275 #ifdef VGP_ppc64le_linux
276 printf("vscr set to 0x%lx\n", (unsigned long) vreg[0]);
277 #else
278 printf("vscr set to 0x%lx\n", (unsigned long) vreg[1]);
279 #endif
281 do_tests();
283 // set VSCR[nj] to 1 and run test
284 printf("Attempt to set VSR[NJ] to 1, run test\n");
286 /* The upper 95 bits are set to zero when writting to the register. So,
287 I can get away with setting the NJ bit for BE and LE and the HW will
288 take care of clearing the one I don't want.
290 vreg[0] = 1 << (127 - 111); // Sets bit for LE case
291 vreg[1] = 1 << (127 - 111); // Sets bit for BE case
293 __asm__ __volatile__ ("mtvscr %0" :: "v"(vreg));
295 vreg[0] = 0;
296 vreg[1] = 0;
298 // Read VSCR
299 __asm__ __volatile__ ("mfvscr %0" : "=v"(vreg));
301 #ifdef VGP_ppc64le_linux
302 printf("vscr set to 0x%lx\n", (unsigned long) vreg[0]);
303 #else
304 printf("vscr set to 0x%lx\n", (unsigned long) vreg[1]);
305 #endif
307 do_tests();
309 /* Restore the VSCR settings. */
310 __asm__ __volatile__ ("mtvscr %0" :: "v"(initial_vscr_value));
311 #else
312 printf("No ISA 2.06 support\n");
313 #endif
315 return 0;