2 /* { dg-skip-if "" { powerpc*-*-darwin* } } */
3 /* { dg-require-effective-target p8vector_hw } */
4 /* { dg-require-effective-target int128 } */
5 /* { dg-options "-mdejagnu-cpu=power8 -O2" } */
15 #ifdef __LITTLE_ENDIAN__
24 #define UNUSED __attribute__((__unused__))
28 #define S_TYPE __uint128_t
32 #define V_TYPE vector S_TYPE
35 static int compare (S_TYPE
, V_TYPE
, const char *, const char *)
36 __attribute__((__noinline__
));
39 compare (S_TYPE scalar
,
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
;
51 __asm__ ("mfvsrd %0,%x3\n\t"
52 "xxpermdi %x2,%x3,%x3,3\n\t"
59 ret
= (scalar_lo
!= vect_lo
) || (scalar_hi
!= vect_hi
);
62 printf ("%s%s: 0x%.16lx %.16lx %s 0x%.16lx %.16lx\n",
74 static void convert_via_mem (V_TYPE
*, S_TYPE
*)
75 __attribute__((__noinline__
));
78 convert_via_mem (V_TYPE
*v
, S_TYPE
*s
)
81 __asm__
volatile ("nop"
82 : "+m" (*s
), "+m" (*v
)
89 /* Check if vadduqm returns the same values as normal 128-bit add. */
91 /* Values to add together. */
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
},
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");
157 fputs ("no errors found on register operations\n", stdout
);
159 printf ("%d error%s found on register operations\n",
161 (reg_errors
== 1) ? "s" : "");
164 fputs ("no errors found on memory operations\n", stdout
);
166 printf ("%d error%s found on memory operations\n",
168 (mem_errors
== 1) ? "s" : "");
173 if ((reg_errors
+ mem_errors
) != 0)