Merged revisions 208012,208018-208019,208021,208023-208030,208033,208037,208040-20804...
[official-gcc.git] / main / gcc / testsuite / gcc.target / powerpc / p8vector-int128-2.c
blob1064894dc4cde25862abea751f100d30257cb564
1 /* { dg-do run { target { powerpc*-*-linux* && lp64 } } } */
2 /* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
3 /* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
4 /* { dg-require-effective-target p8vector_hw } */
5 /* { dg-options "-mcpu=power8 -O2" } */
7 #include <stddef.h>
8 #include <stdlib.h>
9 #include <altivec.h>
11 #ifdef DEBUG
12 #include <stdio.h>
13 #define UNUSED
15 #ifdef __LITTLE_ENDIAN__
16 #define HI_WORD 1
17 #define LO_WORD 0
18 #else
19 #define HI_WORD 0
20 #define LO_WORD 1
21 #endif
23 #else
24 #define UNUSED __attribute__((__unused__))
25 #endif
27 #ifndef S_TYPE
28 #define S_TYPE __uint128_t
29 #endif
31 #ifndef V_TYPE
32 #define V_TYPE vector S_TYPE
33 #endif
35 static int compare (S_TYPE, V_TYPE, const char *, const char *)
36 __attribute__((__noinline__));
38 static int
39 compare (S_TYPE scalar,
40 V_TYPE vect,
41 const char *nl UNUSED,
42 const char *which UNUSED)
44 unsigned long scalar_lo = (unsigned long) scalar;
45 unsigned long scalar_hi = (unsigned long) (scalar >> 64);
46 unsigned long vect_lo;
47 unsigned long vect_hi;
48 vector long long tmp;
49 int ret;
51 __asm__ ("mfvsrd %0,%x3\n\t"
52 "xxpermdi %x2,%x3,%x3,3\n\t"
53 "mfvsrd %1,%x2"
54 : "=r" (vect_hi),
55 "=r" (vect_lo),
56 "=wa" (tmp)
57 : "wa" (vect));
59 ret = (scalar_lo != vect_lo) || (scalar_hi != vect_hi);
61 #ifdef DEBUG
62 printf ("%s%s: 0x%.16lx %.16lx %s 0x%.16lx %.16lx\n",
63 nl, which,
64 scalar_hi, scalar_lo,
65 (ret) ? "!=" : "==",
66 vect_hi, vect_lo);
68 fflush (stdout);
69 #endif
71 return ret;
74 static void convert_via_mem (V_TYPE *, S_TYPE *)
75 __attribute__((__noinline__));
77 static void
78 convert_via_mem (V_TYPE *v, S_TYPE *s)
80 *v = (V_TYPE) { *s };
81 __asm__ volatile ("nop"
82 : "+m" (*s), "+m" (*v)
84 : "memory");
89 /* Check if vadduqm returns the same values as normal 128-bit add. */
91 /* Values to add together. */
92 const static struct {
93 unsigned long hi_1;
94 unsigned long lo_1;
95 unsigned long hi_2;
96 unsigned long lo_2;
97 } values[] = {
98 { 0x0000000000000000UL, 0xfffffffffffffffeUL,
99 0x0000000000000000UL, 0x0000000000000002UL },
100 { 0x0000000000000000UL, 0x0000000000000002UL,
101 0x0000000000000000UL, 0xfffffffffffffffeUL },
102 { 0xffffffffffffffffUL, 0xfffffffffffffffeUL,
103 0x0000000000000000UL, 0x0000000000000002UL },
104 { 0xfffffffffffffff2UL, 0xffffffffffffffffUL,
105 0x0000000000000002UL, 0x0000000000000000UL },
106 { 0x7fffffffffffffffUL, 0xfffffffffffffffeUL,
107 0x0000000000000000UL, 0x0000000000000002UL },
108 { 0x7ffffffffffffff2UL, 0xffffffffffffffffUL,
109 0x0000000000000002UL, 0x0000000000000000UL },
113 main (void)
115 int reg_errors = 0;
116 int mem_errors = 0;
117 size_t i;
118 const char *nl = "";
120 for (i = 0; i < sizeof (values) / sizeof (values[0]); i++)
122 S_TYPE s_reg_res, s_reg_in1, s_reg_in2, s_mem_res, s_mem_in1, s_mem_in2;
123 V_TYPE v_reg_res, v_reg_in1, v_reg_in2, v_mem_res, v_mem_in1, v_mem_in2;
125 s_reg_in1 = ((((S_TYPE)values[i].hi_1 << 64)) + ((S_TYPE)values[i].lo_1));
126 reg_errors += compare (s_reg_in1, (V_TYPE) { s_reg_in1 }, nl, "reg, in1");
128 s_reg_in2 = ((((S_TYPE)values[i].hi_2 << 64)) + ((S_TYPE)values[i].lo_2));
129 reg_errors += compare (s_reg_in2, (V_TYPE) { s_reg_in2 }, "", "reg, in2");
131 s_reg_res = s_reg_in1 + s_reg_in2;
133 v_reg_in1 = (V_TYPE) { s_reg_in1 };
134 v_reg_in2 = (V_TYPE) { s_reg_in2 };
135 v_reg_res = vec_vadduqm (v_reg_in1, v_reg_in2);
136 reg_errors += compare (s_reg_res, v_reg_res, "", "reg, res");
138 s_mem_in1 = s_reg_in1;
139 convert_via_mem (&v_mem_in1, &s_mem_in1);
140 mem_errors += compare (s_mem_in1, (V_TYPE) { s_mem_in1 }, "\n", "mem, in1");
142 s_mem_in2 = s_reg_in2;
143 convert_via_mem (&v_mem_in2, &s_mem_in2);
144 mem_errors += compare (s_mem_in2, (V_TYPE) { s_mem_in2 }, "", "mem, in2");
146 s_mem_res = s_mem_in1 + s_mem_in2;
147 v_mem_res = vec_vadduqm (v_mem_in1, v_mem_in2);
148 mem_errors += compare (s_mem_res, v_mem_res, "", "mem, res");
150 nl = "\n";
153 #ifdef DEBUG
154 putchar ('\n');
156 if (!reg_errors)
157 fputs ("no errors found on register operations\n", stdout);
158 else
159 printf ("%d error%s found on register operations\n",
160 reg_errors,
161 (reg_errors == 1) ? "s" : "");
163 if (!mem_errors)
164 fputs ("no errors found on memory operations\n", stdout);
165 else
166 printf ("%d error%s found on memory operations\n",
167 mem_errors,
168 (mem_errors == 1) ? "s" : "");
170 fflush (stdout);
171 #endif
173 if ((reg_errors + mem_errors) != 0)
174 abort ();
176 return 0;