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-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
6 /* { dg-options "-mcpu=power8 -O2" } */
16 #ifdef __LITTLE_ENDIAN__
25 #define UNUSED __attribute__((__unused__))
29 #define S_TYPE __uint128_t
33 #define V_TYPE vector S_TYPE
36 static int compare (S_TYPE
, V_TYPE
, const char *, const char *)
37 __attribute__((__noinline__
));
40 compare (S_TYPE scalar
,
42 const char *nl UNUSED
,
43 const char *which UNUSED
)
45 unsigned long scalar_lo
= (unsigned long) scalar
;
46 unsigned long scalar_hi
= (unsigned long) (scalar
>> 64);
47 unsigned long vect_lo
;
48 unsigned long vect_hi
;
52 __asm__ ("mfvsrd %0,%x3\n\t"
53 "xxpermdi %x2,%x3,%x3,3\n\t"
60 ret
= (scalar_lo
!= vect_lo
) || (scalar_hi
!= vect_hi
);
63 printf ("%s%s: 0x%.16lx %.16lx %s 0x%.16lx %.16lx\n",
75 static void convert_via_mem (V_TYPE
*, S_TYPE
*)
76 __attribute__((__noinline__
));
79 convert_via_mem (V_TYPE
*v
, S_TYPE
*s
)
82 __asm__
volatile ("nop"
83 : "+m" (*s
), "+m" (*v
)
90 /* Check if vadduqm returns the same values as normal 128-bit add. */
92 /* Values to add together. */
99 { 0x0000000000000000UL
, 0xfffffffffffffffeUL
,
100 0x0000000000000000UL
, 0x0000000000000002UL
},
101 { 0x0000000000000000UL
, 0x0000000000000002UL
,
102 0x0000000000000000UL
, 0xfffffffffffffffeUL
},
103 { 0xffffffffffffffffUL
, 0xfffffffffffffffeUL
,
104 0x0000000000000000UL
, 0x0000000000000002UL
},
105 { 0xfffffffffffffff2UL
, 0xffffffffffffffffUL
,
106 0x0000000000000002UL
, 0x0000000000000000UL
},
107 { 0x7fffffffffffffffUL
, 0xfffffffffffffffeUL
,
108 0x0000000000000000UL
, 0x0000000000000002UL
},
109 { 0x7ffffffffffffff2UL
, 0xffffffffffffffffUL
,
110 0x0000000000000002UL
, 0x0000000000000000UL
},
121 for (i
= 0; i
< sizeof (values
) / sizeof (values
[0]); i
++)
123 S_TYPE s_reg_res
, s_reg_in1
, s_reg_in2
, s_mem_res
, s_mem_in1
, s_mem_in2
;
124 V_TYPE v_reg_res
, v_reg_in1
, v_reg_in2
, v_mem_res
, v_mem_in1
, v_mem_in2
;
126 s_reg_in1
= ((((S_TYPE
)values
[i
].hi_1
<< 64)) + ((S_TYPE
)values
[i
].lo_1
));
127 reg_errors
+= compare (s_reg_in1
, (V_TYPE
) { s_reg_in1
}, nl
, "reg, in1");
129 s_reg_in2
= ((((S_TYPE
)values
[i
].hi_2
<< 64)) + ((S_TYPE
)values
[i
].lo_2
));
130 reg_errors
+= compare (s_reg_in2
, (V_TYPE
) { s_reg_in2
}, "", "reg, in2");
132 s_reg_res
= s_reg_in1
+ s_reg_in2
;
134 v_reg_in1
= (V_TYPE
) { s_reg_in1
};
135 v_reg_in2
= (V_TYPE
) { s_reg_in2
};
136 v_reg_res
= vec_vadduqm (v_reg_in1
, v_reg_in2
);
137 reg_errors
+= compare (s_reg_res
, v_reg_res
, "", "reg, res");
139 s_mem_in1
= s_reg_in1
;
140 convert_via_mem (&v_mem_in1
, &s_mem_in1
);
141 mem_errors
+= compare (s_mem_in1
, (V_TYPE
) { s_mem_in1
}, "\n", "mem, in1");
143 s_mem_in2
= s_reg_in2
;
144 convert_via_mem (&v_mem_in2
, &s_mem_in2
);
145 mem_errors
+= compare (s_mem_in2
, (V_TYPE
) { s_mem_in2
}, "", "mem, in2");
147 s_mem_res
= s_mem_in1
+ s_mem_in2
;
148 v_mem_res
= vec_vadduqm (v_mem_in1
, v_mem_in2
);
149 mem_errors
+= compare (s_mem_res
, v_mem_res
, "", "mem, res");
158 fputs ("no errors found on register operations\n", stdout
);
160 printf ("%d error%s found on register operations\n",
162 (reg_errors
== 1) ? "s" : "");
165 fputs ("no errors found on memory operations\n", stdout
);
167 printf ("%d error%s found on memory operations\n",
169 (mem_errors
== 1) ? "s" : "");
174 if ((reg_errors
+ mem_errors
) != 0)