1 /* { dg-do run } */
2 /* { dg-require-effective-target p9vector_hw } */
3 /* { dg-options "-O2 -mdejagnu-cpu=power9 -save-temps" } */
4
5 /* Verify the vec_rlm and vec_rlmi builtins works correctly. */
6 /* { dg-final { scan-assembler-times {\mvrldmi\M} 1 } } */
7
8 #include <altivec.h>
9
10 #ifdef DEBUG
11 #include <stdio.h>
12 #include <stdlib.h>
13 #endif
14
15 void abort (void);
16
main()17 int main ()
18 {
19 int i;
20
21 vector unsigned int vec_arg1_int, vec_arg2_int, vec_arg3_int;
22 vector unsigned int vec_result_int, vec_expected_result_int;
23
24 vector unsigned long long int vec_arg1_di, vec_arg2_di, vec_arg3_di;
25 vector unsigned long long int vec_result_di, vec_expected_result_di;
26
27 unsigned int mask_begin, mask_end, shift;
28 unsigned long long int mask;
29
30 /* Check vec int version of vec_rlmi builtin */
31 mask = 0;
32 mask_begin = 0;
33 mask_end = 4;
34 shift = 16;
35
36 for (i = 0; i < 31; i++)
37 if ((i >= mask_begin) && (i <= mask_end))
38 mask |= 0x80000000ULL >> i;
39
40 for (i = 0; i < 4; i++) {
41 vec_arg1_int[i] = 0x12345678 + i*0x11111111;
42 vec_arg2_int[i] = 0xA1B1CDEF;
43 vec_arg3_int[i] = mask_begin << 16 | mask_end << 8 | shift;
44
45 /* do rotate */
46 vec_expected_result_int[i] = ( vec_arg2_int[i] & ~mask)
47 | ((vec_arg1_int[i] << shift) | (vec_arg1_int[i] >> (32-shift))) & mask;
48
49 }
50
51 /* vec_rlmi(arg1, arg2, arg3)
52 result - rotate each element of arg2 left and inserts it into arg1
53 element based on the mask specified in arg3. The shift, mask
54 start and end is specified in arg3. */
55 vec_result_int = vec_rlmi (vec_arg1_int, vec_arg2_int, vec_arg3_int);
56
57 for (i = 0; i < 4; i++) {
58 if (vec_result_int[i] != vec_expected_result_int[i])
59 #ifdef DEBUG
60 printf("ERROR: i = %d, vec_rlmi int result 0x%x, does not match "
61 "expected result 0x%x\n", i, vec_result_int[i],
62 vec_expected_result_int[i]);
63 #else
64 abort();
65 #endif
66 }
67
68 /* Check vec long long int version of vec_rlmi builtin */
69 mask = 0;
70 mask_begin = 0;
71 mask_end = 4;
72 shift = 16;
73
74 for (i = 0; i < 31; i++)
75 if ((i >= mask_begin) && (i <= mask_end))
76 mask |= 0x8000000000000000ULL >> i;
77
78 for (i = 0; i < 2; i++) {
79 vec_arg1_di[i] = 0x1234567800000000 + i*0x11111111;
80 vec_arg2_di[i] = 0xA1B1C1D1E1F12345;
81 vec_arg3_di[i] = mask_begin << 16 | mask_end << 8 | shift;
82
83 /* do rotate */
84 vec_expected_result_di[i] = ( vec_arg2_di[i] & ~mask)
85 | ((vec_arg1_di[i] << shift) | (vec_arg1_di[i] >> (64-shift))) & mask;
86 }
87
88 /* vec_rlmi(arg1, arg2, arg3)
89 result - rotate each element of arg1 left and inserts it into arg2
90 element based on the mask specified in arg3. The shift, mask, start
91 and end is specified in arg3. */
92 vec_result_di = vec_rlmi (vec_arg1_di, vec_arg2_di, vec_arg3_di);
93
94 for (i = 0; i < 2; i++) {
95 if (vec_result_di[i] != vec_expected_result_di[i])
96 #ifdef DEBUG
97 printf("ERROR: i = %d, vec_rlmi int long long result 0x%llx, does not match "
98 "expected result 0x%llx\n", i, vec_result_di[i],
99 vec_expected_result_di[i]);
100 #else
101 abort();
102 #endif
103 }
104
105 /* Check vec int version of vec_rlnm builtin */
106 mask = 0;
107 mask_begin = 0;
108 mask_end = 4;
109 shift = 16;
110
111 for (i = 0; i < 31; i++)
112 if ((i >= mask_begin) && (i <= mask_end))
113 mask |= 0x80000000ULL >> i;
114
115 for (i = 0; i < 4; i++) {
116 vec_arg1_int[i] = 0x12345678 + i*0x11111111;
117 vec_arg2_int[i] = shift;
118 vec_arg3_int[i] = mask_begin << 8 | mask_end;
119 vec_expected_result_int[i] = (vec_arg1_int[i] << shift) & mask;
120 }
121
122 /* vec_rlnm(arg1, arg2, arg3)
123 result - rotate each element of arg1 left by shift in element of arg2.
124 Then AND with mask whose start/stop bits are specified in element of
125 arg3. */
126 vec_result_int = vec_rlnm (vec_arg1_int, vec_arg2_int, vec_arg3_int);
127 for (i = 0; i < 4; i++) {
128 if (vec_result_int[i] != vec_expected_result_int[i])
129 #ifdef DEBUG
130 printf("ERROR: vec_rlnm, i = %d, int result 0x%x does not match "
131 "expected result 0x%x\n", i, vec_result_int[i],
132 vec_expected_result_int[i]);
133 #else
134 abort();
135 #endif
136 }
137
138 /* Check vec long int version of builtin */
139 mask = 0;
140 mask_begin = 0;
141 mask_end = 4;
142 shift = 20;
143
144 for (i = 0; i < 63; i++)
145 if ((i >= mask_begin) && (i <= mask_end))
146 mask |= 0x8000000000000000ULL >> i;
147
148 for (i = 0; i < 2; i++) {
149 vec_arg1_di[i] = 0x123456789ABCDE00ULL + i*0x1111111111111111ULL;
150 vec_arg2_di[i] = shift;
151 vec_arg3_di[i] = mask_begin << 8 | mask_end;
152 vec_expected_result_di[i] = (vec_arg1_di[i] << shift) & mask;
153 }
154
155 vec_result_di = vec_rlnm (vec_arg1_di, vec_arg2_di, vec_arg3_di);
156
157 for (i = 0; i < 2; i++) {
158 if (vec_result_di[i] != vec_expected_result_di[i])
159 #ifdef DEBUG
160 printf("ERROR: vec_rlnm, i = %d, long long int result 0x%llx does not "
161 "match expected result 0x%llx\n", i, vec_result_di[i],
162 vec_expected_result_di[i]);
163 #else
164 abort();
165 #endif
166 }
167
168 /* Check vec int version of vec_vrlnm builtin */
169 mask = 0;
170 mask_begin = 0;
171 mask_end = 4;
172 shift = 16;
173
174 for (i = 0; i < 31; i++)
175 if ((i >= mask_begin) && (i <= mask_end))
176 mask |= 0x80000000ULL >> i;
177
178 for (i = 0; i < 4; i++) {
179 vec_arg1_int[i] = 0x12345678 + i*0x11111111;
180 vec_arg2_int[i] = mask_begin << 16 | mask_end << 8 | shift;
181 vec_expected_result_int[i] = (vec_arg1_int[i] << shift) & mask;
182 }
183
184 /* vec_vrlnm(arg1, arg2, arg3)
185 result - rotate each element of arg1 left then AND with mask. The mask
186 start, stop bits is specified in the second argument. The shift amount
187 is also specified in the second argument. */
188 vec_result_int = vec_vrlnm (vec_arg1_int, vec_arg2_int);
189
190 for (i = 0; i < 4; i++) {
191 if (vec_result_int[i] != vec_expected_result_int[i])
192 #ifdef DEBUG
193 printf("ERROR: vec_vrlnm, i = %d, int result 0x%x does not match "
194 "expected result 0x%x\n", i, vec_result_int[i],
195 vec_expected_result_int[i]);
196 #else
197 abort();
198 #endif
199 }
200
201 /* Check vec long int version of vec_vrlnm builtin */
202 mask = 0;
203 mask_begin = 0;
204 mask_end = 4;
205 shift = 20;
206
207 for (i = 0; i < 63; i++)
208 if ((i >= mask_begin) && (i <= mask_end))
209 mask |= 0x8000000000000000ULL >> i;
210
211 for (i = 0; i < 2; i++) {
212 vec_arg1_di[i] = 0x123456789ABCDE00ULL + i*0x1111111111111111ULL;
213 vec_arg2_di[i] = mask_begin << 16 | mask_end << 8 | shift;
214 vec_expected_result_di[i] = (vec_arg1_di[i] << shift) & mask;
215 }
216
217 vec_result_di = vec_vrlnm (vec_arg1_di, vec_arg2_di);
218
219 for (i = 0; i < 2; i++) {
220 if (vec_result_di[i] != vec_expected_result_di[i])
221 #ifdef DEBUG
222 printf("ERROR: vec_vrlnm, i = %d, long long int result 0x%llx does not "
223 "match expected result 0x%llx\n", i, vec_result_di[i],
224 vec_expected_result_di[i]);
225 #else
226 abort();
227 #endif
228 }
229
230 return 0;
231 }
232