Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/powerpcspe/altivec.md @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 ;; AltiVec patterns. | |
2 ;; Copyright (C) 2002-2017 Free Software Foundation, Inc. | |
3 ;; Contributed by Aldy Hernandez (aldy@quesejoda.com) | |
4 | |
5 ;; This file is part of GCC. | |
6 | |
7 ;; GCC is free software; you can redistribute it and/or modify it | |
8 ;; under the terms of the GNU General Public License as published | |
9 ;; by the Free Software Foundation; either version 3, or (at your | |
10 ;; option) any later version. | |
11 | |
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT | |
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
15 ;; License for more details. | |
16 | |
17 ;; You should have received a copy of the GNU General Public License | |
18 ;; along with GCC; see the file COPYING3. If not see | |
19 ;; <http://www.gnu.org/licenses/>. | |
20 | |
21 (define_c_enum "unspec" | |
22 [UNSPEC_VCMPBFP | |
23 UNSPEC_VMSUMU | |
24 UNSPEC_VMSUMM | |
25 UNSPEC_VMSUMSHM | |
26 UNSPEC_VMSUMUHS | |
27 UNSPEC_VMSUMSHS | |
28 UNSPEC_VMHADDSHS | |
29 UNSPEC_VMHRADDSHS | |
30 UNSPEC_VADDCUW | |
31 UNSPEC_VADDU | |
32 UNSPEC_VADDS | |
33 UNSPEC_VAVGU | |
34 UNSPEC_VAVGS | |
35 UNSPEC_VMULEUB | |
36 UNSPEC_VMULESB | |
37 UNSPEC_VMULEUH | |
38 UNSPEC_VMULESH | |
39 UNSPEC_VMULOUB | |
40 UNSPEC_VMULOSB | |
41 UNSPEC_VMULOUH | |
42 UNSPEC_VMULOSH | |
43 UNSPEC_VPKPX | |
44 UNSPEC_VPACK_SIGN_SIGN_SAT | |
45 UNSPEC_VPACK_SIGN_UNS_SAT | |
46 UNSPEC_VPACK_UNS_UNS_SAT | |
47 UNSPEC_VPACK_UNS_UNS_MOD | |
48 UNSPEC_VPACK_UNS_UNS_MOD_DIRECT | |
49 UNSPEC_VSLV4SI | |
50 UNSPEC_VSLO | |
51 UNSPEC_VSR | |
52 UNSPEC_VSRO | |
53 UNSPEC_VSUBCUW | |
54 UNSPEC_VSUBU | |
55 UNSPEC_VSUBS | |
56 UNSPEC_VSUM4UBS | |
57 UNSPEC_VSUM4S | |
58 UNSPEC_VSUM2SWS | |
59 UNSPEC_VSUMSWS | |
60 UNSPEC_VPERM | |
61 UNSPEC_VPERMR | |
62 UNSPEC_VPERM_UNS | |
63 UNSPEC_VRFIN | |
64 UNSPEC_VCFUX | |
65 UNSPEC_VCFSX | |
66 UNSPEC_VCTUXS | |
67 UNSPEC_VCTSXS | |
68 UNSPEC_VLOGEFP | |
69 UNSPEC_VEXPTEFP | |
70 UNSPEC_VSLDOI | |
71 UNSPEC_VUNPACK_HI_SIGN | |
72 UNSPEC_VUNPACK_LO_SIGN | |
73 UNSPEC_VUNPACK_HI_SIGN_DIRECT | |
74 UNSPEC_VUNPACK_LO_SIGN_DIRECT | |
75 UNSPEC_VUPKHPX | |
76 UNSPEC_VUPKLPX | |
77 UNSPEC_DARN | |
78 UNSPEC_DARN_32 | |
79 UNSPEC_DARN_RAW | |
80 UNSPEC_DST | |
81 UNSPEC_DSTT | |
82 UNSPEC_DSTST | |
83 UNSPEC_DSTSTT | |
84 UNSPEC_LVSL | |
85 UNSPEC_LVSR | |
86 UNSPEC_LVE | |
87 UNSPEC_STVX | |
88 UNSPEC_STVXL | |
89 UNSPEC_STVE | |
90 UNSPEC_SET_VSCR | |
91 UNSPEC_GET_VRSAVE | |
92 UNSPEC_LVX | |
93 UNSPEC_REDUC_PLUS | |
94 UNSPEC_VECSH | |
95 UNSPEC_EXTEVEN_V4SI | |
96 UNSPEC_EXTEVEN_V8HI | |
97 UNSPEC_EXTEVEN_V16QI | |
98 UNSPEC_EXTEVEN_V4SF | |
99 UNSPEC_EXTODD_V4SI | |
100 UNSPEC_EXTODD_V8HI | |
101 UNSPEC_EXTODD_V16QI | |
102 UNSPEC_EXTODD_V4SF | |
103 UNSPEC_INTERHI_V4SI | |
104 UNSPEC_INTERHI_V8HI | |
105 UNSPEC_INTERHI_V16QI | |
106 UNSPEC_INTERLO_V4SI | |
107 UNSPEC_INTERLO_V8HI | |
108 UNSPEC_INTERLO_V16QI | |
109 UNSPEC_LVLX | |
110 UNSPEC_LVLXL | |
111 UNSPEC_LVRX | |
112 UNSPEC_LVRXL | |
113 UNSPEC_STVLX | |
114 UNSPEC_STVLXL | |
115 UNSPEC_STVRX | |
116 UNSPEC_STVRXL | |
117 UNSPEC_VADU | |
118 UNSPEC_VSLV | |
119 UNSPEC_VSRV | |
120 UNSPEC_VMULWHUB | |
121 UNSPEC_VMULWLUB | |
122 UNSPEC_VMULWHSB | |
123 UNSPEC_VMULWLSB | |
124 UNSPEC_VMULWHUH | |
125 UNSPEC_VMULWLUH | |
126 UNSPEC_VMULWHSH | |
127 UNSPEC_VMULWLSH | |
128 UNSPEC_VUPKHUB | |
129 UNSPEC_VUPKHUH | |
130 UNSPEC_VUPKLUB | |
131 UNSPEC_VUPKLUH | |
132 UNSPEC_VPERMSI | |
133 UNSPEC_VPERMHI | |
134 UNSPEC_INTERHI | |
135 UNSPEC_INTERLO | |
136 UNSPEC_VUPKHS_V4SF | |
137 UNSPEC_VUPKLS_V4SF | |
138 UNSPEC_VUPKHU_V4SF | |
139 UNSPEC_VUPKLU_V4SF | |
140 UNSPEC_VGBBD | |
141 UNSPEC_VMRGH_DIRECT | |
142 UNSPEC_VMRGL_DIRECT | |
143 UNSPEC_VSPLT_DIRECT | |
144 UNSPEC_VMRGEW_DIRECT | |
145 UNSPEC_VSUMSWS_DIRECT | |
146 UNSPEC_VADDCUQ | |
147 UNSPEC_VADDEUQM | |
148 UNSPEC_VADDECUQ | |
149 UNSPEC_VSUBCUQ | |
150 UNSPEC_VSUBEUQM | |
151 UNSPEC_VSUBECUQ | |
152 UNSPEC_VBPERMQ | |
153 UNSPEC_VBPERMD | |
154 UNSPEC_BCDADD | |
155 UNSPEC_BCDSUB | |
156 UNSPEC_BCD_OVERFLOW | |
157 UNSPEC_CMPRB | |
158 UNSPEC_CMPRB2 | |
159 UNSPEC_CMPEQB | |
160 UNSPEC_VRLMI | |
161 UNSPEC_VRLNM | |
162 ]) | |
163 | |
164 (define_c_enum "unspecv" | |
165 [UNSPECV_SET_VRSAVE | |
166 UNSPECV_MTVSCR | |
167 UNSPECV_MFVSCR | |
168 UNSPECV_DSSALL | |
169 UNSPECV_DSS | |
170 ]) | |
171 | |
172 ;; Like VI, defined in vector.md, but add ISA 2.07 integer vector ops | |
173 (define_mode_iterator VI2 [V4SI V8HI V16QI V2DI]) | |
174 ;; Short vec int modes | |
175 (define_mode_iterator VIshort [V8HI V16QI]) | |
176 ;; Longer vec int modes for rotate/mask ops | |
177 (define_mode_iterator VIlong [V2DI V4SI]) | |
178 ;; Vec float modes | |
179 (define_mode_iterator VF [V4SF]) | |
180 ;; Vec modes, pity mode iterators are not composable | |
181 (define_mode_iterator V [V4SI V8HI V16QI V4SF]) | |
182 ;; Vec modes for move/logical/permute ops, include vector types for move not | |
183 ;; otherwise handled by altivec (v2df, v2di, ti) | |
184 (define_mode_iterator VM [V4SI | |
185 V8HI | |
186 V16QI | |
187 V4SF | |
188 V2DF | |
189 V2DI | |
190 V1TI | |
191 TI | |
192 (KF "FLOAT128_VECTOR_P (KFmode)") | |
193 (TF "FLOAT128_VECTOR_P (TFmode)")]) | |
194 | |
195 ;; Like VM, except don't do TImode | |
196 (define_mode_iterator VM2 [V4SI | |
197 V8HI | |
198 V16QI | |
199 V4SF | |
200 V2DF | |
201 V2DI | |
202 V1TI | |
203 (KF "FLOAT128_VECTOR_P (KFmode)") | |
204 (TF "FLOAT128_VECTOR_P (TFmode)")]) | |
205 | |
206 ;; Specific iterator for parity which does not have a byte/half-word form, but | |
207 ;; does have a quad word form | |
208 (define_mode_iterator VParity [V4SI | |
209 V2DI | |
210 V1TI | |
211 (TI "TARGET_VSX_TIMODE")]) | |
212 | |
213 (define_mode_attr VI_char [(V2DI "d") (V4SI "w") (V8HI "h") (V16QI "b")]) | |
214 (define_mode_attr VI_scalar [(V2DI "DI") (V4SI "SI") (V8HI "HI") (V16QI "QI")]) | |
215 (define_mode_attr VI_unit [(V16QI "VECTOR_UNIT_ALTIVEC_P (V16QImode)") | |
216 (V8HI "VECTOR_UNIT_ALTIVEC_P (V8HImode)") | |
217 (V4SI "VECTOR_UNIT_ALTIVEC_P (V4SImode)") | |
218 (V2DI "VECTOR_UNIT_P8_VECTOR_P (V2DImode)") | |
219 (V1TI "VECTOR_UNIT_ALTIVEC_P (V1TImode)")]) | |
220 | |
221 ;; Vector pack/unpack | |
222 (define_mode_iterator VP [V2DI V4SI V8HI]) | |
223 (define_mode_attr VP_small [(V2DI "V4SI") (V4SI "V8HI") (V8HI "V16QI")]) | |
224 (define_mode_attr VP_small_lc [(V2DI "v4si") (V4SI "v8hi") (V8HI "v16qi")]) | |
225 (define_mode_attr VU_char [(V2DI "w") (V4SI "h") (V8HI "b")]) | |
226 | |
227 ;; Vector negate | |
228 (define_mode_iterator VNEG [V4SI V2DI]) | |
229 | |
230 ;; Vector move instructions. | |
231 (define_insn "*altivec_mov<mode>" | |
232 [(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,?Y,?*r,?*r,v,v,?*r") | |
233 (match_operand:VM2 1 "input_operand" "v,Z,v,*r,Y,*r,j,W,W"))] | |
234 "VECTOR_MEM_ALTIVEC_P (<MODE>mode) | |
235 && (register_operand (operands[0], <MODE>mode) | |
236 || register_operand (operands[1], <MODE>mode))" | |
237 { | |
238 switch (which_alternative) | |
239 { | |
240 case 0: return "stvx %1,%y0"; | |
241 case 1: return "lvx %0,%y1"; | |
242 case 2: return "vor %0,%1,%1"; | |
243 case 3: return "#"; | |
244 case 4: return "#"; | |
245 case 5: return "#"; | |
246 case 6: return "vxor %0,%0,%0"; | |
247 case 7: return output_vec_const_move (operands); | |
248 case 8: return "#"; | |
249 default: gcc_unreachable (); | |
250 } | |
251 } | |
252 [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*,*") | |
253 (set_attr "length" "4,4,4,20,20,20,4,8,32")]) | |
254 | |
255 ;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode | |
256 ;; is for unions. However for plain data movement, slightly favor the vector | |
257 ;; loads | |
258 (define_insn "*altivec_movti" | |
259 [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,v,v,?Y,?r,?r,v,v") | |
260 (match_operand:TI 1 "input_operand" "v,Z,v,r,Y,r,j,W"))] | |
261 "VECTOR_MEM_ALTIVEC_P (TImode) | |
262 && (register_operand (operands[0], TImode) | |
263 || register_operand (operands[1], TImode))" | |
264 { | |
265 switch (which_alternative) | |
266 { | |
267 case 0: return "stvx %1,%y0"; | |
268 case 1: return "lvx %0,%y1"; | |
269 case 2: return "vor %0,%1,%1"; | |
270 case 3: return "#"; | |
271 case 4: return "#"; | |
272 case 5: return "#"; | |
273 case 6: return "vxor %0,%0,%0"; | |
274 case 7: return output_vec_const_move (operands); | |
275 default: gcc_unreachable (); | |
276 } | |
277 } | |
278 [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*")]) | |
279 | |
280 ;; Load up a vector with the most significant bit set by loading up -1 and | |
281 ;; doing a shift left | |
282 (define_split | |
283 [(set (match_operand:VM 0 "altivec_register_operand" "") | |
284 (match_operand:VM 1 "easy_vector_constant_msb" ""))] | |
285 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed" | |
286 [(const_int 0)] | |
287 { | |
288 rtx dest = operands[0]; | |
289 machine_mode mode = GET_MODE (operands[0]); | |
290 rtvec v; | |
291 int i, num_elements; | |
292 | |
293 if (mode == V4SFmode) | |
294 { | |
295 mode = V4SImode; | |
296 dest = gen_lowpart (V4SImode, dest); | |
297 } | |
298 | |
299 num_elements = GET_MODE_NUNITS (mode); | |
300 v = rtvec_alloc (num_elements); | |
301 for (i = 0; i < num_elements; i++) | |
302 RTVEC_ELT (v, i) = constm1_rtx; | |
303 | |
304 emit_insn (gen_vec_initv4sisi (dest, gen_rtx_PARALLEL (mode, v))); | |
305 emit_insn (gen_rtx_SET (dest, gen_rtx_ASHIFT (mode, dest, dest))); | |
306 DONE; | |
307 }) | |
308 | |
309 (define_split | |
310 [(set (match_operand:VM 0 "altivec_register_operand" "") | |
311 (match_operand:VM 1 "easy_vector_constant_add_self" ""))] | |
312 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed" | |
313 [(set (match_dup 0) (match_dup 3)) | |
314 (set (match_dup 0) (match_dup 4))] | |
315 { | |
316 rtx dup = gen_easy_altivec_constant (operands[1]); | |
317 rtx const_vec; | |
318 machine_mode op_mode = <MODE>mode; | |
319 | |
320 /* Divide the operand of the resulting VEC_DUPLICATE, and use | |
321 simplify_rtx to make a CONST_VECTOR. */ | |
322 XEXP (dup, 0) = simplify_const_binary_operation (ASHIFTRT, QImode, | |
323 XEXP (dup, 0), const1_rtx); | |
324 const_vec = simplify_rtx (dup); | |
325 | |
326 if (op_mode == V4SFmode) | |
327 { | |
328 op_mode = V4SImode; | |
329 operands[0] = gen_lowpart (op_mode, operands[0]); | |
330 } | |
331 if (GET_MODE (const_vec) == op_mode) | |
332 operands[3] = const_vec; | |
333 else | |
334 operands[3] = gen_lowpart (op_mode, const_vec); | |
335 operands[4] = gen_rtx_PLUS (op_mode, operands[0], operands[0]); | |
336 }) | |
337 | |
338 (define_split | |
339 [(set (match_operand:VM 0 "altivec_register_operand" "") | |
340 (match_operand:VM 1 "easy_vector_constant_vsldoi" ""))] | |
341 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && can_create_pseudo_p ()" | |
342 [(set (match_dup 2) (match_dup 3)) | |
343 (set (match_dup 4) (match_dup 5)) | |
344 (set (match_dup 0) | |
345 (unspec:VM [(match_dup 2) | |
346 (match_dup 4) | |
347 (match_dup 6)] | |
348 UNSPEC_VSLDOI))] | |
349 { | |
350 rtx op1 = operands[1]; | |
351 int elt = (BYTES_BIG_ENDIAN) ? 0 : GET_MODE_NUNITS (<MODE>mode) - 1; | |
352 HOST_WIDE_INT val = const_vector_elt_as_int (op1, elt); | |
353 rtx rtx_val = GEN_INT (val); | |
354 int shift = vspltis_shifted (op1); | |
355 int nunits = GET_MODE_NUNITS (<MODE>mode); | |
356 int i; | |
357 | |
358 gcc_assert (shift != 0); | |
359 operands[2] = gen_reg_rtx (<MODE>mode); | |
360 operands[3] = gen_rtx_CONST_VECTOR (<MODE>mode, rtvec_alloc (nunits)); | |
361 operands[4] = gen_reg_rtx (<MODE>mode); | |
362 | |
363 if (shift < 0) | |
364 { | |
365 operands[5] = CONSTM1_RTX (<MODE>mode); | |
366 operands[6] = GEN_INT (-shift); | |
367 } | |
368 else | |
369 { | |
370 operands[5] = CONST0_RTX (<MODE>mode); | |
371 operands[6] = GEN_INT (shift); | |
372 } | |
373 | |
374 /* Populate the constant vectors. */ | |
375 for (i = 0; i < nunits; i++) | |
376 XVECEXP (operands[3], 0, i) = rtx_val; | |
377 }) | |
378 | |
379 (define_insn "get_vrsave_internal" | |
380 [(set (match_operand:SI 0 "register_operand" "=r") | |
381 (unspec:SI [(reg:SI VRSAVE_REGNO)] UNSPEC_GET_VRSAVE))] | |
382 "TARGET_ALTIVEC" | |
383 { | |
384 if (TARGET_MACHO) | |
385 return "mfspr %0,256"; | |
386 else | |
387 return "mfvrsave %0"; | |
388 } | |
389 [(set_attr "type" "*")]) | |
390 | |
391 (define_insn "*set_vrsave_internal" | |
392 [(match_parallel 0 "vrsave_operation" | |
393 [(set (reg:SI VRSAVE_REGNO) | |
394 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r") | |
395 (reg:SI VRSAVE_REGNO)] UNSPECV_SET_VRSAVE))])] | |
396 "TARGET_ALTIVEC" | |
397 { | |
398 if (TARGET_MACHO) | |
399 return "mtspr 256,%1"; | |
400 else | |
401 return "mtvrsave %1"; | |
402 } | |
403 [(set_attr "type" "*")]) | |
404 | |
405 (define_insn "*save_world" | |
406 [(match_parallel 0 "save_world_operation" | |
407 [(clobber (reg:SI LR_REGNO)) | |
408 (use (match_operand:SI 1 "call_operand" "s"))])] | |
409 "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT" | |
410 "bl %z1" | |
411 [(set_attr "type" "branch") | |
412 (set_attr "length" "4")]) | |
413 | |
414 (define_insn "*restore_world" | |
415 [(match_parallel 0 "restore_world_operation" | |
416 [(return) | |
417 (use (reg:SI LR_REGNO)) | |
418 (use (match_operand:SI 1 "call_operand" "s")) | |
419 (clobber (match_operand:SI 2 "gpc_reg_operand" "=r"))])] | |
420 "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT" | |
421 "b %z1") | |
422 | |
423 ;; The save_vregs and restore_vregs patterns don't use memory_operand | |
424 ;; because (plus (reg) (const_int)) is not a valid vector address. | |
425 ;; This way is more compact than describing exactly what happens in | |
426 ;; the out-of-line functions, ie. loading the constant into r11/r12 | |
427 ;; then using indexed addressing, and requires less editing of rtl | |
428 ;; to describe the operation to dwarf2out_frame_debug_expr. | |
429 (define_insn "*save_vregs_<mode>_r11" | |
430 [(match_parallel 0 "any_parallel_operand" | |
431 [(clobber (reg:P LR_REGNO)) | |
432 (use (match_operand:P 1 "symbol_ref_operand" "s")) | |
433 (clobber (reg:P 11)) | |
434 (use (reg:P 0)) | |
435 (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b") | |
436 (match_operand:P 3 "short_cint_operand" "I"))) | |
437 (match_operand:V4SI 4 "altivec_register_operand" "v"))])] | |
438 "TARGET_ALTIVEC" | |
439 "bl %1" | |
440 [(set_attr "type" "branch") | |
441 (set_attr "length" "4")]) | |
442 | |
443 (define_insn "*save_vregs_<mode>_r12" | |
444 [(match_parallel 0 "any_parallel_operand" | |
445 [(clobber (reg:P LR_REGNO)) | |
446 (use (match_operand:P 1 "symbol_ref_operand" "s")) | |
447 (clobber (reg:P 12)) | |
448 (use (reg:P 0)) | |
449 (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b") | |
450 (match_operand:P 3 "short_cint_operand" "I"))) | |
451 (match_operand:V4SI 4 "altivec_register_operand" "v"))])] | |
452 "TARGET_ALTIVEC" | |
453 "bl %1" | |
454 [(set_attr "type" "branch") | |
455 (set_attr "length" "4")]) | |
456 | |
457 (define_insn "*restore_vregs_<mode>_r11" | |
458 [(match_parallel 0 "any_parallel_operand" | |
459 [(clobber (reg:P LR_REGNO)) | |
460 (use (match_operand:P 1 "symbol_ref_operand" "s")) | |
461 (clobber (reg:P 11)) | |
462 (use (reg:P 0)) | |
463 (set (match_operand:V4SI 2 "altivec_register_operand" "=v") | |
464 (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b") | |
465 (match_operand:P 4 "short_cint_operand" "I"))))])] | |
466 "TARGET_ALTIVEC" | |
467 "bl %1" | |
468 [(set_attr "type" "branch") | |
469 (set_attr "length" "4")]) | |
470 | |
471 (define_insn "*restore_vregs_<mode>_r12" | |
472 [(match_parallel 0 "any_parallel_operand" | |
473 [(clobber (reg:P LR_REGNO)) | |
474 (use (match_operand:P 1 "symbol_ref_operand" "s")) | |
475 (clobber (reg:P 12)) | |
476 (use (reg:P 0)) | |
477 (set (match_operand:V4SI 2 "altivec_register_operand" "=v") | |
478 (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b") | |
479 (match_operand:P 4 "short_cint_operand" "I"))))])] | |
480 "TARGET_ALTIVEC" | |
481 "bl %1" | |
482 [(set_attr "type" "branch") | |
483 (set_attr "length" "4")]) | |
484 | |
485 ;; Simple binary operations. | |
486 | |
487 ;; add | |
488 (define_insn "add<mode>3" | |
489 [(set (match_operand:VI2 0 "register_operand" "=v") | |
490 (plus:VI2 (match_operand:VI2 1 "register_operand" "v") | |
491 (match_operand:VI2 2 "register_operand" "v")))] | |
492 "<VI_unit>" | |
493 "vaddu<VI_char>m %0,%1,%2" | |
494 [(set_attr "type" "vecsimple")]) | |
495 | |
496 (define_insn "*altivec_addv4sf3" | |
497 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
498 (plus:V4SF (match_operand:V4SF 1 "register_operand" "v") | |
499 (match_operand:V4SF 2 "register_operand" "v")))] | |
500 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
501 "vaddfp %0,%1,%2" | |
502 [(set_attr "type" "vecfloat")]) | |
503 | |
504 (define_insn "altivec_vaddcuw" | |
505 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
506 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") | |
507 (match_operand:V4SI 2 "register_operand" "v")] | |
508 UNSPEC_VADDCUW))] | |
509 "VECTOR_UNIT_ALTIVEC_P (V4SImode)" | |
510 "vaddcuw %0,%1,%2" | |
511 [(set_attr "type" "vecsimple")]) | |
512 | |
513 (define_insn "altivec_vaddu<VI_char>s" | |
514 [(set (match_operand:VI 0 "register_operand" "=v") | |
515 (unspec:VI [(match_operand:VI 1 "register_operand" "v") | |
516 (match_operand:VI 2 "register_operand" "v")] | |
517 UNSPEC_VADDU)) | |
518 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] | |
519 "<VI_unit>" | |
520 "vaddu<VI_char>s %0,%1,%2" | |
521 [(set_attr "type" "vecsimple")]) | |
522 | |
523 (define_insn "altivec_vadds<VI_char>s" | |
524 [(set (match_operand:VI 0 "register_operand" "=v") | |
525 (unspec:VI [(match_operand:VI 1 "register_operand" "v") | |
526 (match_operand:VI 2 "register_operand" "v")] | |
527 UNSPEC_VADDS)) | |
528 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] | |
529 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" | |
530 "vadds<VI_char>s %0,%1,%2" | |
531 [(set_attr "type" "vecsimple")]) | |
532 | |
533 ;; sub | |
534 (define_insn "sub<mode>3" | |
535 [(set (match_operand:VI2 0 "register_operand" "=v") | |
536 (minus:VI2 (match_operand:VI2 1 "register_operand" "v") | |
537 (match_operand:VI2 2 "register_operand" "v")))] | |
538 "<VI_unit>" | |
539 "vsubu<VI_char>m %0,%1,%2" | |
540 [(set_attr "type" "vecsimple")]) | |
541 | |
542 (define_insn "*altivec_subv4sf3" | |
543 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
544 (minus:V4SF (match_operand:V4SF 1 "register_operand" "v") | |
545 (match_operand:V4SF 2 "register_operand" "v")))] | |
546 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
547 "vsubfp %0,%1,%2" | |
548 [(set_attr "type" "vecfloat")]) | |
549 | |
550 (define_insn "altivec_vsubcuw" | |
551 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
552 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") | |
553 (match_operand:V4SI 2 "register_operand" "v")] | |
554 UNSPEC_VSUBCUW))] | |
555 "VECTOR_UNIT_ALTIVEC_P (V4SImode)" | |
556 "vsubcuw %0,%1,%2" | |
557 [(set_attr "type" "vecsimple")]) | |
558 | |
559 (define_insn "altivec_vsubu<VI_char>s" | |
560 [(set (match_operand:VI 0 "register_operand" "=v") | |
561 (unspec:VI [(match_operand:VI 1 "register_operand" "v") | |
562 (match_operand:VI 2 "register_operand" "v")] | |
563 UNSPEC_VSUBU)) | |
564 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] | |
565 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" | |
566 "vsubu<VI_char>s %0,%1,%2" | |
567 [(set_attr "type" "vecsimple")]) | |
568 | |
569 (define_insn "altivec_vsubs<VI_char>s" | |
570 [(set (match_operand:VI 0 "register_operand" "=v") | |
571 (unspec:VI [(match_operand:VI 1 "register_operand" "v") | |
572 (match_operand:VI 2 "register_operand" "v")] | |
573 UNSPEC_VSUBS)) | |
574 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] | |
575 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" | |
576 "vsubs<VI_char>s %0,%1,%2" | |
577 [(set_attr "type" "vecsimple")]) | |
578 | |
579 ;; | |
580 (define_insn "altivec_vavgu<VI_char>" | |
581 [(set (match_operand:VI 0 "register_operand" "=v") | |
582 (unspec:VI [(match_operand:VI 1 "register_operand" "v") | |
583 (match_operand:VI 2 "register_operand" "v")] | |
584 UNSPEC_VAVGU))] | |
585 "TARGET_ALTIVEC" | |
586 "vavgu<VI_char> %0,%1,%2" | |
587 [(set_attr "type" "vecsimple")]) | |
588 | |
589 (define_insn "altivec_vavgs<VI_char>" | |
590 [(set (match_operand:VI 0 "register_operand" "=v") | |
591 (unspec:VI [(match_operand:VI 1 "register_operand" "v") | |
592 (match_operand:VI 2 "register_operand" "v")] | |
593 UNSPEC_VAVGS))] | |
594 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" | |
595 "vavgs<VI_char> %0,%1,%2" | |
596 [(set_attr "type" "vecsimple")]) | |
597 | |
598 (define_insn "altivec_vcmpbfp" | |
599 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
600 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") | |
601 (match_operand:V4SF 2 "register_operand" "v")] | |
602 UNSPEC_VCMPBFP))] | |
603 "VECTOR_UNIT_ALTIVEC_P (V4SImode)" | |
604 "vcmpbfp %0,%1,%2" | |
605 [(set_attr "type" "veccmp")]) | |
606 | |
607 (define_insn "*altivec_eq<mode>" | |
608 [(set (match_operand:VI2 0 "altivec_register_operand" "=v") | |
609 (eq:VI2 (match_operand:VI2 1 "altivec_register_operand" "v") | |
610 (match_operand:VI2 2 "altivec_register_operand" "v")))] | |
611 "<VI_unit>" | |
612 "vcmpequ<VI_char> %0,%1,%2" | |
613 [(set_attr "type" "veccmpfx")]) | |
614 | |
615 (define_insn "*altivec_gt<mode>" | |
616 [(set (match_operand:VI2 0 "altivec_register_operand" "=v") | |
617 (gt:VI2 (match_operand:VI2 1 "altivec_register_operand" "v") | |
618 (match_operand:VI2 2 "altivec_register_operand" "v")))] | |
619 "<VI_unit>" | |
620 "vcmpgts<VI_char> %0,%1,%2" | |
621 [(set_attr "type" "veccmpfx")]) | |
622 | |
623 (define_insn "*altivec_gtu<mode>" | |
624 [(set (match_operand:VI2 0 "altivec_register_operand" "=v") | |
625 (gtu:VI2 (match_operand:VI2 1 "altivec_register_operand" "v") | |
626 (match_operand:VI2 2 "altivec_register_operand" "v")))] | |
627 "<VI_unit>" | |
628 "vcmpgtu<VI_char> %0,%1,%2" | |
629 [(set_attr "type" "veccmpfx")]) | |
630 | |
631 (define_insn "*altivec_eqv4sf" | |
632 [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") | |
633 (eq:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v") | |
634 (match_operand:V4SF 2 "altivec_register_operand" "v")))] | |
635 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
636 "vcmpeqfp %0,%1,%2" | |
637 [(set_attr "type" "veccmp")]) | |
638 | |
639 (define_insn "*altivec_gtv4sf" | |
640 [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") | |
641 (gt:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v") | |
642 (match_operand:V4SF 2 "altivec_register_operand" "v")))] | |
643 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
644 "vcmpgtfp %0,%1,%2" | |
645 [(set_attr "type" "veccmp")]) | |
646 | |
647 (define_insn "*altivec_gev4sf" | |
648 [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") | |
649 (ge:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v") | |
650 (match_operand:V4SF 2 "altivec_register_operand" "v")))] | |
651 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
652 "vcmpgefp %0,%1,%2" | |
653 [(set_attr "type" "veccmp")]) | |
654 | |
655 (define_insn "*altivec_vsel<mode>" | |
656 [(set (match_operand:VM 0 "altivec_register_operand" "=v") | |
657 (if_then_else:VM | |
658 (ne:CC (match_operand:VM 1 "altivec_register_operand" "v") | |
659 (match_operand:VM 4 "zero_constant" "")) | |
660 (match_operand:VM 2 "altivec_register_operand" "v") | |
661 (match_operand:VM 3 "altivec_register_operand" "v")))] | |
662 "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" | |
663 "vsel %0,%3,%2,%1" | |
664 [(set_attr "type" "vecmove")]) | |
665 | |
666 (define_insn "*altivec_vsel<mode>_uns" | |
667 [(set (match_operand:VM 0 "altivec_register_operand" "=v") | |
668 (if_then_else:VM | |
669 (ne:CCUNS (match_operand:VM 1 "altivec_register_operand" "v") | |
670 (match_operand:VM 4 "zero_constant" "")) | |
671 (match_operand:VM 2 "altivec_register_operand" "v") | |
672 (match_operand:VM 3 "altivec_register_operand" "v")))] | |
673 "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" | |
674 "vsel %0,%3,%2,%1" | |
675 [(set_attr "type" "vecmove")]) | |
676 | |
677 ;; Fused multiply add. | |
678 | |
679 (define_insn "*altivec_fmav4sf4" | |
680 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
681 (fma:V4SF (match_operand:V4SF 1 "register_operand" "v") | |
682 (match_operand:V4SF 2 "register_operand" "v") | |
683 (match_operand:V4SF 3 "register_operand" "v")))] | |
684 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
685 "vmaddfp %0,%1,%2,%3" | |
686 [(set_attr "type" "vecfloat")]) | |
687 | |
688 ;; We do multiply as a fused multiply-add with an add of a -0.0 vector. | |
689 | |
690 (define_expand "altivec_mulv4sf3" | |
691 [(set (match_operand:V4SF 0 "register_operand" "") | |
692 (fma:V4SF (match_operand:V4SF 1 "register_operand" "") | |
693 (match_operand:V4SF 2 "register_operand" "") | |
694 (match_dup 3)))] | |
695 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
696 { | |
697 rtx neg0; | |
698 | |
699 /* Generate [-0.0, -0.0, -0.0, -0.0]. */ | |
700 neg0 = gen_reg_rtx (V4SImode); | |
701 emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx)); | |
702 emit_insn (gen_vashlv4si3 (neg0, neg0, neg0)); | |
703 | |
704 operands[3] = gen_lowpart (V4SFmode, neg0); | |
705 }) | |
706 | |
707 ;; 32-bit integer multiplication | |
708 ;; A_high = Operand_0 & 0xFFFF0000 >> 16 | |
709 ;; A_low = Operand_0 & 0xFFFF | |
710 ;; B_high = Operand_1 & 0xFFFF0000 >> 16 | |
711 ;; B_low = Operand_1 & 0xFFFF | |
712 ;; result = A_low * B_low + (A_high * B_low + B_high * A_low) << 16 | |
713 | |
714 ;; (define_insn "mulv4si3" | |
715 ;; [(set (match_operand:V4SI 0 "register_operand" "=v") | |
716 ;; (mult:V4SI (match_operand:V4SI 1 "register_operand" "v") | |
717 ;; (match_operand:V4SI 2 "register_operand" "v")))] | |
718 (define_insn "mulv4si3_p8" | |
719 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
720 (mult:V4SI (match_operand:V4SI 1 "register_operand" "v") | |
721 (match_operand:V4SI 2 "register_operand" "v")))] | |
722 "TARGET_P8_VECTOR" | |
723 "vmuluwm %0,%1,%2" | |
724 [(set_attr "type" "veccomplex")]) | |
725 | |
726 (define_expand "mulv4si3" | |
727 [(use (match_operand:V4SI 0 "register_operand" "")) | |
728 (use (match_operand:V4SI 1 "register_operand" "")) | |
729 (use (match_operand:V4SI 2 "register_operand" ""))] | |
730 "TARGET_ALTIVEC" | |
731 { | |
732 rtx zero; | |
733 rtx swap; | |
734 rtx small_swap; | |
735 rtx sixteen; | |
736 rtx one; | |
737 rtx two; | |
738 rtx low_product; | |
739 rtx high_product; | |
740 | |
741 if (TARGET_P8_VECTOR) | |
742 { | |
743 emit_insn (gen_mulv4si3_p8 (operands[0], operands[1], operands[2])); | |
744 DONE; | |
745 } | |
746 | |
747 zero = gen_reg_rtx (V4SImode); | |
748 emit_insn (gen_altivec_vspltisw (zero, const0_rtx)); | |
749 | |
750 sixteen = gen_reg_rtx (V4SImode); | |
751 emit_insn (gen_altivec_vspltisw (sixteen, gen_rtx_CONST_INT (V4SImode, -16))); | |
752 | |
753 swap = gen_reg_rtx (V4SImode); | |
754 emit_insn (gen_vrotlv4si3 (swap, operands[2], sixteen)); | |
755 | |
756 one = gen_reg_rtx (V8HImode); | |
757 convert_move (one, operands[1], 0); | |
758 | |
759 two = gen_reg_rtx (V8HImode); | |
760 convert_move (two, operands[2], 0); | |
761 | |
762 small_swap = gen_reg_rtx (V8HImode); | |
763 convert_move (small_swap, swap, 0); | |
764 | |
765 low_product = gen_reg_rtx (V4SImode); | |
766 emit_insn (gen_altivec_vmulouh (low_product, one, two)); | |
767 | |
768 high_product = gen_reg_rtx (V4SImode); | |
769 emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero)); | |
770 | |
771 emit_insn (gen_vashlv4si3 (high_product, high_product, sixteen)); | |
772 | |
773 emit_insn (gen_addv4si3 (operands[0], high_product, low_product)); | |
774 | |
775 DONE; | |
776 }) | |
777 | |
778 (define_expand "mulv8hi3" | |
779 [(use (match_operand:V8HI 0 "register_operand" "")) | |
780 (use (match_operand:V8HI 1 "register_operand" "")) | |
781 (use (match_operand:V8HI 2 "register_operand" ""))] | |
782 "TARGET_ALTIVEC" | |
783 { | |
784 rtx zero = gen_reg_rtx (V8HImode); | |
785 | |
786 emit_insn (gen_altivec_vspltish (zero, const0_rtx)); | |
787 emit_insn (gen_altivec_vmladduhm(operands[0], operands[1], operands[2], zero)); | |
788 | |
789 DONE; | |
790 }) | |
791 | |
792 ;; Fused multiply subtract | |
793 (define_insn "*altivec_vnmsubfp" | |
794 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
795 (neg:V4SF | |
796 (fma:V4SF (match_operand:V4SF 1 "register_operand" "v") | |
797 (match_operand:V4SF 2 "register_operand" "v") | |
798 (neg:V4SF | |
799 (match_operand:V4SF 3 "register_operand" "v")))))] | |
800 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
801 "vnmsubfp %0,%1,%2,%3" | |
802 [(set_attr "type" "vecfloat")]) | |
803 | |
804 (define_insn "altivec_vmsumu<VI_char>m" | |
805 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
806 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") | |
807 (match_operand:VIshort 2 "register_operand" "v") | |
808 (match_operand:V4SI 3 "register_operand" "v")] | |
809 UNSPEC_VMSUMU))] | |
810 "TARGET_ALTIVEC" | |
811 "vmsumu<VI_char>m %0,%1,%2,%3" | |
812 [(set_attr "type" "veccomplex")]) | |
813 | |
814 (define_insn "altivec_vmsumm<VI_char>m" | |
815 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
816 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") | |
817 (match_operand:VIshort 2 "register_operand" "v") | |
818 (match_operand:V4SI 3 "register_operand" "v")] | |
819 UNSPEC_VMSUMM))] | |
820 "TARGET_ALTIVEC" | |
821 "vmsumm<VI_char>m %0,%1,%2,%3" | |
822 [(set_attr "type" "veccomplex")]) | |
823 | |
824 (define_insn "altivec_vmsumshm" | |
825 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
826 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") | |
827 (match_operand:V8HI 2 "register_operand" "v") | |
828 (match_operand:V4SI 3 "register_operand" "v")] | |
829 UNSPEC_VMSUMSHM))] | |
830 "TARGET_ALTIVEC" | |
831 "vmsumshm %0,%1,%2,%3" | |
832 [(set_attr "type" "veccomplex")]) | |
833 | |
834 (define_insn "altivec_vmsumuhs" | |
835 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
836 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") | |
837 (match_operand:V8HI 2 "register_operand" "v") | |
838 (match_operand:V4SI 3 "register_operand" "v")] | |
839 UNSPEC_VMSUMUHS)) | |
840 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] | |
841 "TARGET_ALTIVEC" | |
842 "vmsumuhs %0,%1,%2,%3" | |
843 [(set_attr "type" "veccomplex")]) | |
844 | |
845 (define_insn "altivec_vmsumshs" | |
846 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
847 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") | |
848 (match_operand:V8HI 2 "register_operand" "v") | |
849 (match_operand:V4SI 3 "register_operand" "v")] | |
850 UNSPEC_VMSUMSHS)) | |
851 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] | |
852 "TARGET_ALTIVEC" | |
853 "vmsumshs %0,%1,%2,%3" | |
854 [(set_attr "type" "veccomplex")]) | |
855 | |
856 ;; max | |
857 | |
858 (define_insn "umax<mode>3" | |
859 [(set (match_operand:VI2 0 "register_operand" "=v") | |
860 (umax:VI2 (match_operand:VI2 1 "register_operand" "v") | |
861 (match_operand:VI2 2 "register_operand" "v")))] | |
862 "<VI_unit>" | |
863 "vmaxu<VI_char> %0,%1,%2" | |
864 [(set_attr "type" "vecsimple")]) | |
865 | |
866 (define_insn "smax<mode>3" | |
867 [(set (match_operand:VI2 0 "register_operand" "=v") | |
868 (smax:VI2 (match_operand:VI2 1 "register_operand" "v") | |
869 (match_operand:VI2 2 "register_operand" "v")))] | |
870 "<VI_unit>" | |
871 "vmaxs<VI_char> %0,%1,%2" | |
872 [(set_attr "type" "vecsimple")]) | |
873 | |
874 (define_insn "*altivec_smaxv4sf3" | |
875 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
876 (smax:V4SF (match_operand:V4SF 1 "register_operand" "v") | |
877 (match_operand:V4SF 2 "register_operand" "v")))] | |
878 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
879 "vmaxfp %0,%1,%2" | |
880 [(set_attr "type" "veccmp")]) | |
881 | |
882 (define_insn "umin<mode>3" | |
883 [(set (match_operand:VI2 0 "register_operand" "=v") | |
884 (umin:VI2 (match_operand:VI2 1 "register_operand" "v") | |
885 (match_operand:VI2 2 "register_operand" "v")))] | |
886 "<VI_unit>" | |
887 "vminu<VI_char> %0,%1,%2" | |
888 [(set_attr "type" "vecsimple")]) | |
889 | |
890 (define_insn "smin<mode>3" | |
891 [(set (match_operand:VI2 0 "register_operand" "=v") | |
892 (smin:VI2 (match_operand:VI2 1 "register_operand" "v") | |
893 (match_operand:VI2 2 "register_operand" "v")))] | |
894 "<VI_unit>" | |
895 "vmins<VI_char> %0,%1,%2" | |
896 [(set_attr "type" "vecsimple")]) | |
897 | |
898 (define_insn "*altivec_sminv4sf3" | |
899 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
900 (smin:V4SF (match_operand:V4SF 1 "register_operand" "v") | |
901 (match_operand:V4SF 2 "register_operand" "v")))] | |
902 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
903 "vminfp %0,%1,%2" | |
904 [(set_attr "type" "veccmp")]) | |
905 | |
906 (define_insn "altivec_vmhaddshs" | |
907 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
908 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") | |
909 (match_operand:V8HI 2 "register_operand" "v") | |
910 (match_operand:V8HI 3 "register_operand" "v")] | |
911 UNSPEC_VMHADDSHS)) | |
912 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] | |
913 "TARGET_ALTIVEC" | |
914 "vmhaddshs %0,%1,%2,%3" | |
915 [(set_attr "type" "veccomplex")]) | |
916 | |
917 (define_insn "altivec_vmhraddshs" | |
918 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
919 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") | |
920 (match_operand:V8HI 2 "register_operand" "v") | |
921 (match_operand:V8HI 3 "register_operand" "v")] | |
922 UNSPEC_VMHRADDSHS)) | |
923 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] | |
924 "TARGET_ALTIVEC" | |
925 "vmhraddshs %0,%1,%2,%3" | |
926 [(set_attr "type" "veccomplex")]) | |
927 | |
928 (define_insn "altivec_vmladduhm" | |
929 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
930 (plus:V8HI (mult:V8HI (match_operand:V8HI 1 "register_operand" "v") | |
931 (match_operand:V8HI 2 "register_operand" "v")) | |
932 (match_operand:V8HI 3 "register_operand" "v")))] | |
933 "TARGET_ALTIVEC" | |
934 "vmladduhm %0,%1,%2,%3" | |
935 [(set_attr "type" "veccomplex")]) | |
936 | |
937 (define_expand "altivec_vmrghb" | |
938 [(use (match_operand:V16QI 0 "register_operand" "")) | |
939 (use (match_operand:V16QI 1 "register_operand" "")) | |
940 (use (match_operand:V16QI 2 "register_operand" ""))] | |
941 "TARGET_ALTIVEC" | |
942 { | |
943 rtvec v; | |
944 rtx x; | |
945 | |
946 /* Special handling for LE with -maltivec=be. */ | |
947 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
948 { | |
949 v = gen_rtvec (16, GEN_INT (8), GEN_INT (24), GEN_INT (9), GEN_INT (25), | |
950 GEN_INT (10), GEN_INT (26), GEN_INT (11), GEN_INT (27), | |
951 GEN_INT (12), GEN_INT (28), GEN_INT (13), GEN_INT (29), | |
952 GEN_INT (14), GEN_INT (30), GEN_INT (15), GEN_INT (31)); | |
953 x = gen_rtx_VEC_CONCAT (V32QImode, operands[2], operands[1]); | |
954 } | |
955 else | |
956 { | |
957 v = gen_rtvec (16, GEN_INT (0), GEN_INT (16), GEN_INT (1), GEN_INT (17), | |
958 GEN_INT (2), GEN_INT (18), GEN_INT (3), GEN_INT (19), | |
959 GEN_INT (4), GEN_INT (20), GEN_INT (5), GEN_INT (21), | |
960 GEN_INT (6), GEN_INT (22), GEN_INT (7), GEN_INT (23)); | |
961 x = gen_rtx_VEC_CONCAT (V32QImode, operands[1], operands[2]); | |
962 } | |
963 | |
964 x = gen_rtx_VEC_SELECT (V16QImode, x, gen_rtx_PARALLEL (VOIDmode, v)); | |
965 emit_insn (gen_rtx_SET (operands[0], x)); | |
966 DONE; | |
967 }) | |
968 | |
969 (define_insn "*altivec_vmrghb_internal" | |
970 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
971 (vec_select:V16QI | |
972 (vec_concat:V32QI | |
973 (match_operand:V16QI 1 "register_operand" "v") | |
974 (match_operand:V16QI 2 "register_operand" "v")) | |
975 (parallel [(const_int 0) (const_int 16) | |
976 (const_int 1) (const_int 17) | |
977 (const_int 2) (const_int 18) | |
978 (const_int 3) (const_int 19) | |
979 (const_int 4) (const_int 20) | |
980 (const_int 5) (const_int 21) | |
981 (const_int 6) (const_int 22) | |
982 (const_int 7) (const_int 23)])))] | |
983 "TARGET_ALTIVEC" | |
984 { | |
985 if (BYTES_BIG_ENDIAN) | |
986 return "vmrghb %0,%1,%2"; | |
987 else | |
988 return "vmrglb %0,%2,%1"; | |
989 } | |
990 [(set_attr "type" "vecperm")]) | |
991 | |
992 (define_insn "altivec_vmrghb_direct" | |
993 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
994 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") | |
995 (match_operand:V16QI 2 "register_operand" "v")] | |
996 UNSPEC_VMRGH_DIRECT))] | |
997 "TARGET_ALTIVEC" | |
998 "vmrghb %0,%1,%2" | |
999 [(set_attr "type" "vecperm")]) | |
1000 | |
1001 (define_expand "altivec_vmrghh" | |
1002 [(use (match_operand:V8HI 0 "register_operand" "")) | |
1003 (use (match_operand:V8HI 1 "register_operand" "")) | |
1004 (use (match_operand:V8HI 2 "register_operand" ""))] | |
1005 "TARGET_ALTIVEC" | |
1006 { | |
1007 rtvec v; | |
1008 rtx x; | |
1009 | |
1010 /* Special handling for LE with -maltivec=be. */ | |
1011 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
1012 { | |
1013 v = gen_rtvec (8, GEN_INT (4), GEN_INT (12), GEN_INT (5), GEN_INT (13), | |
1014 GEN_INT (6), GEN_INT (14), GEN_INT (7), GEN_INT (15)); | |
1015 x = gen_rtx_VEC_CONCAT (V16HImode, operands[2], operands[1]); | |
1016 } | |
1017 else | |
1018 { | |
1019 v = gen_rtvec (8, GEN_INT (0), GEN_INT (8), GEN_INT (1), GEN_INT (9), | |
1020 GEN_INT (2), GEN_INT (10), GEN_INT (3), GEN_INT (11)); | |
1021 x = gen_rtx_VEC_CONCAT (V16HImode, operands[1], operands[2]); | |
1022 } | |
1023 | |
1024 x = gen_rtx_VEC_SELECT (V8HImode, x, gen_rtx_PARALLEL (VOIDmode, v)); | |
1025 emit_insn (gen_rtx_SET (operands[0], x)); | |
1026 DONE; | |
1027 }) | |
1028 | |
1029 (define_insn "*altivec_vmrghh_internal" | |
1030 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
1031 (vec_select:V8HI | |
1032 (vec_concat:V16HI | |
1033 (match_operand:V8HI 1 "register_operand" "v") | |
1034 (match_operand:V8HI 2 "register_operand" "v")) | |
1035 (parallel [(const_int 0) (const_int 8) | |
1036 (const_int 1) (const_int 9) | |
1037 (const_int 2) (const_int 10) | |
1038 (const_int 3) (const_int 11)])))] | |
1039 "TARGET_ALTIVEC" | |
1040 { | |
1041 if (BYTES_BIG_ENDIAN) | |
1042 return "vmrghh %0,%1,%2"; | |
1043 else | |
1044 return "vmrglh %0,%2,%1"; | |
1045 } | |
1046 [(set_attr "type" "vecperm")]) | |
1047 | |
1048 (define_insn "altivec_vmrghh_direct" | |
1049 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
1050 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") | |
1051 (match_operand:V8HI 2 "register_operand" "v")] | |
1052 UNSPEC_VMRGH_DIRECT))] | |
1053 "TARGET_ALTIVEC" | |
1054 "vmrghh %0,%1,%2" | |
1055 [(set_attr "type" "vecperm")]) | |
1056 | |
1057 (define_expand "altivec_vmrghw" | |
1058 [(use (match_operand:V4SI 0 "register_operand" "")) | |
1059 (use (match_operand:V4SI 1 "register_operand" "")) | |
1060 (use (match_operand:V4SI 2 "register_operand" ""))] | |
1061 "VECTOR_MEM_ALTIVEC_P (V4SImode)" | |
1062 { | |
1063 rtvec v; | |
1064 rtx x; | |
1065 | |
1066 /* Special handling for LE with -maltivec=be. */ | |
1067 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
1068 { | |
1069 v = gen_rtvec (4, GEN_INT (2), GEN_INT (6), GEN_INT (3), GEN_INT (7)); | |
1070 x = gen_rtx_VEC_CONCAT (V8SImode, operands[2], operands[1]); | |
1071 } | |
1072 else | |
1073 { | |
1074 v = gen_rtvec (4, GEN_INT (0), GEN_INT (4), GEN_INT (1), GEN_INT (5)); | |
1075 x = gen_rtx_VEC_CONCAT (V8SImode, operands[1], operands[2]); | |
1076 } | |
1077 | |
1078 x = gen_rtx_VEC_SELECT (V4SImode, x, gen_rtx_PARALLEL (VOIDmode, v)); | |
1079 emit_insn (gen_rtx_SET (operands[0], x)); | |
1080 DONE; | |
1081 }) | |
1082 | |
1083 (define_insn "*altivec_vmrghw_internal" | |
1084 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1085 (vec_select:V4SI | |
1086 (vec_concat:V8SI | |
1087 (match_operand:V4SI 1 "register_operand" "v") | |
1088 (match_operand:V4SI 2 "register_operand" "v")) | |
1089 (parallel [(const_int 0) (const_int 4) | |
1090 (const_int 1) (const_int 5)])))] | |
1091 "VECTOR_MEM_ALTIVEC_P (V4SImode)" | |
1092 { | |
1093 if (BYTES_BIG_ENDIAN) | |
1094 return "vmrghw %0,%1,%2"; | |
1095 else | |
1096 return "vmrglw %0,%2,%1"; | |
1097 } | |
1098 [(set_attr "type" "vecperm")]) | |
1099 | |
1100 (define_insn "altivec_vmrghw_direct" | |
1101 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1102 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") | |
1103 (match_operand:V4SI 2 "register_operand" "v")] | |
1104 UNSPEC_VMRGH_DIRECT))] | |
1105 "TARGET_ALTIVEC" | |
1106 "vmrghw %0,%1,%2" | |
1107 [(set_attr "type" "vecperm")]) | |
1108 | |
1109 (define_insn "*altivec_vmrghsf" | |
1110 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
1111 (vec_select:V4SF | |
1112 (vec_concat:V8SF | |
1113 (match_operand:V4SF 1 "register_operand" "v") | |
1114 (match_operand:V4SF 2 "register_operand" "v")) | |
1115 (parallel [(const_int 0) (const_int 4) | |
1116 (const_int 1) (const_int 5)])))] | |
1117 "VECTOR_MEM_ALTIVEC_P (V4SFmode)" | |
1118 { | |
1119 if (BYTES_BIG_ENDIAN) | |
1120 return "vmrghw %0,%1,%2"; | |
1121 else | |
1122 return "vmrglw %0,%2,%1"; | |
1123 } | |
1124 [(set_attr "type" "vecperm")]) | |
1125 | |
1126 (define_expand "altivec_vmrglb" | |
1127 [(use (match_operand:V16QI 0 "register_operand" "")) | |
1128 (use (match_operand:V16QI 1 "register_operand" "")) | |
1129 (use (match_operand:V16QI 2 "register_operand" ""))] | |
1130 "TARGET_ALTIVEC" | |
1131 { | |
1132 rtvec v; | |
1133 rtx x; | |
1134 | |
1135 /* Special handling for LE with -maltivec=be. */ | |
1136 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
1137 { | |
1138 v = gen_rtvec (16, GEN_INT (0), GEN_INT (16), GEN_INT (1), GEN_INT (17), | |
1139 GEN_INT (2), GEN_INT (18), GEN_INT (3), GEN_INT (19), | |
1140 GEN_INT (4), GEN_INT (20), GEN_INT (5), GEN_INT (21), | |
1141 GEN_INT (6), GEN_INT (22), GEN_INT (7), GEN_INT (23)); | |
1142 x = gen_rtx_VEC_CONCAT (V32QImode, operands[2], operands[1]); | |
1143 } | |
1144 else | |
1145 { | |
1146 v = gen_rtvec (16, GEN_INT (8), GEN_INT (24), GEN_INT (9), GEN_INT (25), | |
1147 GEN_INT (10), GEN_INT (26), GEN_INT (11), GEN_INT (27), | |
1148 GEN_INT (12), GEN_INT (28), GEN_INT (13), GEN_INT (29), | |
1149 GEN_INT (14), GEN_INT (30), GEN_INT (15), GEN_INT (31)); | |
1150 x = gen_rtx_VEC_CONCAT (V32QImode, operands[1], operands[2]); | |
1151 } | |
1152 | |
1153 x = gen_rtx_VEC_SELECT (V16QImode, x, gen_rtx_PARALLEL (VOIDmode, v)); | |
1154 emit_insn (gen_rtx_SET (operands[0], x)); | |
1155 DONE; | |
1156 }) | |
1157 | |
1158 (define_insn "*altivec_vmrglb_internal" | |
1159 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
1160 (vec_select:V16QI | |
1161 (vec_concat:V32QI | |
1162 (match_operand:V16QI 1 "register_operand" "v") | |
1163 (match_operand:V16QI 2 "register_operand" "v")) | |
1164 (parallel [(const_int 8) (const_int 24) | |
1165 (const_int 9) (const_int 25) | |
1166 (const_int 10) (const_int 26) | |
1167 (const_int 11) (const_int 27) | |
1168 (const_int 12) (const_int 28) | |
1169 (const_int 13) (const_int 29) | |
1170 (const_int 14) (const_int 30) | |
1171 (const_int 15) (const_int 31)])))] | |
1172 "TARGET_ALTIVEC" | |
1173 { | |
1174 if (BYTES_BIG_ENDIAN) | |
1175 return "vmrglb %0,%1,%2"; | |
1176 else | |
1177 return "vmrghb %0,%2,%1"; | |
1178 } | |
1179 [(set_attr "type" "vecperm")]) | |
1180 | |
1181 (define_insn "altivec_vmrglb_direct" | |
1182 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
1183 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") | |
1184 (match_operand:V16QI 2 "register_operand" "v")] | |
1185 UNSPEC_VMRGL_DIRECT))] | |
1186 "TARGET_ALTIVEC" | |
1187 "vmrglb %0,%1,%2" | |
1188 [(set_attr "type" "vecperm")]) | |
1189 | |
1190 (define_expand "altivec_vmrglh" | |
1191 [(use (match_operand:V8HI 0 "register_operand" "")) | |
1192 (use (match_operand:V8HI 1 "register_operand" "")) | |
1193 (use (match_operand:V8HI 2 "register_operand" ""))] | |
1194 "TARGET_ALTIVEC" | |
1195 { | |
1196 rtvec v; | |
1197 rtx x; | |
1198 | |
1199 /* Special handling for LE with -maltivec=be. */ | |
1200 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
1201 { | |
1202 v = gen_rtvec (8, GEN_INT (0), GEN_INT (8), GEN_INT (1), GEN_INT (9), | |
1203 GEN_INT (2), GEN_INT (10), GEN_INT (3), GEN_INT (11)); | |
1204 x = gen_rtx_VEC_CONCAT (V16HImode, operands[2], operands[1]); | |
1205 } | |
1206 else | |
1207 { | |
1208 v = gen_rtvec (8, GEN_INT (4), GEN_INT (12), GEN_INT (5), GEN_INT (13), | |
1209 GEN_INT (6), GEN_INT (14), GEN_INT (7), GEN_INT (15)); | |
1210 x = gen_rtx_VEC_CONCAT (V16HImode, operands[1], operands[2]); | |
1211 } | |
1212 | |
1213 x = gen_rtx_VEC_SELECT (V8HImode, x, gen_rtx_PARALLEL (VOIDmode, v)); | |
1214 emit_insn (gen_rtx_SET (operands[0], x)); | |
1215 DONE; | |
1216 }) | |
1217 | |
1218 (define_insn "*altivec_vmrglh_internal" | |
1219 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
1220 (vec_select:V8HI | |
1221 (vec_concat:V16HI | |
1222 (match_operand:V8HI 1 "register_operand" "v") | |
1223 (match_operand:V8HI 2 "register_operand" "v")) | |
1224 (parallel [(const_int 4) (const_int 12) | |
1225 (const_int 5) (const_int 13) | |
1226 (const_int 6) (const_int 14) | |
1227 (const_int 7) (const_int 15)])))] | |
1228 "TARGET_ALTIVEC" | |
1229 { | |
1230 if (BYTES_BIG_ENDIAN) | |
1231 return "vmrglh %0,%1,%2"; | |
1232 else | |
1233 return "vmrghh %0,%2,%1"; | |
1234 } | |
1235 [(set_attr "type" "vecperm")]) | |
1236 | |
1237 (define_insn "altivec_vmrglh_direct" | |
1238 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
1239 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") | |
1240 (match_operand:V8HI 2 "register_operand" "v")] | |
1241 UNSPEC_VMRGL_DIRECT))] | |
1242 "TARGET_ALTIVEC" | |
1243 "vmrglh %0,%1,%2" | |
1244 [(set_attr "type" "vecperm")]) | |
1245 | |
1246 (define_expand "altivec_vmrglw" | |
1247 [(use (match_operand:V4SI 0 "register_operand" "")) | |
1248 (use (match_operand:V4SI 1 "register_operand" "")) | |
1249 (use (match_operand:V4SI 2 "register_operand" ""))] | |
1250 "VECTOR_MEM_ALTIVEC_P (V4SImode)" | |
1251 { | |
1252 rtvec v; | |
1253 rtx x; | |
1254 | |
1255 /* Special handling for LE with -maltivec=be. */ | |
1256 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
1257 { | |
1258 v = gen_rtvec (4, GEN_INT (0), GEN_INT (4), GEN_INT (1), GEN_INT (5)); | |
1259 x = gen_rtx_VEC_CONCAT (V8SImode, operands[2], operands[1]); | |
1260 } | |
1261 else | |
1262 { | |
1263 v = gen_rtvec (4, GEN_INT (2), GEN_INT (6), GEN_INT (3), GEN_INT (7)); | |
1264 x = gen_rtx_VEC_CONCAT (V8SImode, operands[1], operands[2]); | |
1265 } | |
1266 | |
1267 x = gen_rtx_VEC_SELECT (V4SImode, x, gen_rtx_PARALLEL (VOIDmode, v)); | |
1268 emit_insn (gen_rtx_SET (operands[0], x)); | |
1269 DONE; | |
1270 }) | |
1271 | |
1272 (define_insn "*altivec_vmrglw_internal" | |
1273 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1274 (vec_select:V4SI | |
1275 (vec_concat:V8SI | |
1276 (match_operand:V4SI 1 "register_operand" "v") | |
1277 (match_operand:V4SI 2 "register_operand" "v")) | |
1278 (parallel [(const_int 2) (const_int 6) | |
1279 (const_int 3) (const_int 7)])))] | |
1280 "VECTOR_MEM_ALTIVEC_P (V4SImode)" | |
1281 { | |
1282 if (BYTES_BIG_ENDIAN) | |
1283 return "vmrglw %0,%1,%2"; | |
1284 else | |
1285 return "vmrghw %0,%2,%1"; | |
1286 } | |
1287 [(set_attr "type" "vecperm")]) | |
1288 | |
1289 (define_insn "altivec_vmrglw_direct" | |
1290 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1291 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") | |
1292 (match_operand:V4SI 2 "register_operand" "v")] | |
1293 UNSPEC_VMRGL_DIRECT))] | |
1294 "TARGET_ALTIVEC" | |
1295 "vmrglw %0,%1,%2" | |
1296 [(set_attr "type" "vecperm")]) | |
1297 | |
1298 (define_insn "*altivec_vmrglsf" | |
1299 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
1300 (vec_select:V4SF | |
1301 (vec_concat:V8SF | |
1302 (match_operand:V4SF 1 "register_operand" "v") | |
1303 (match_operand:V4SF 2 "register_operand" "v")) | |
1304 (parallel [(const_int 2) (const_int 6) | |
1305 (const_int 3) (const_int 7)])))] | |
1306 "VECTOR_MEM_ALTIVEC_P (V4SFmode)" | |
1307 { | |
1308 if (BYTES_BIG_ENDIAN) | |
1309 return "vmrglw %0,%1,%2"; | |
1310 else | |
1311 return "vmrghw %0,%2,%1"; | |
1312 } | |
1313 [(set_attr "type" "vecperm")]) | |
1314 | |
1315 ;; Power8 vector merge even/odd | |
1316 (define_insn "p8_vmrgew" | |
1317 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1318 (vec_select:V4SI | |
1319 (vec_concat:V8SI | |
1320 (match_operand:V4SI 1 "register_operand" "v") | |
1321 (match_operand:V4SI 2 "register_operand" "v")) | |
1322 (parallel [(const_int 0) (const_int 4) | |
1323 (const_int 2) (const_int 6)])))] | |
1324 "TARGET_P8_VECTOR" | |
1325 { | |
1326 if (BYTES_BIG_ENDIAN) | |
1327 return "vmrgew %0,%1,%2"; | |
1328 else | |
1329 return "vmrgow %0,%2,%1"; | |
1330 } | |
1331 [(set_attr "type" "vecperm")]) | |
1332 | |
1333 (define_insn "p8_vmrgow" | |
1334 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1335 (vec_select:V4SI | |
1336 (vec_concat:V8SI | |
1337 (match_operand:V4SI 1 "register_operand" "v") | |
1338 (match_operand:V4SI 2 "register_operand" "v")) | |
1339 (parallel [(const_int 1) (const_int 5) | |
1340 (const_int 3) (const_int 7)])))] | |
1341 "TARGET_P8_VECTOR" | |
1342 { | |
1343 if (BYTES_BIG_ENDIAN) | |
1344 return "vmrgow %0,%1,%2"; | |
1345 else | |
1346 return "vmrgew %0,%2,%1"; | |
1347 } | |
1348 [(set_attr "type" "vecperm")]) | |
1349 | |
1350 (define_insn "p8_vmrgew_v4sf_direct" | |
1351 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
1352 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v") | |
1353 (match_operand:V4SF 2 "register_operand" "v")] | |
1354 UNSPEC_VMRGEW_DIRECT))] | |
1355 "TARGET_P8_VECTOR" | |
1356 "vmrgew %0,%1,%2" | |
1357 [(set_attr "type" "vecperm")]) | |
1358 | |
1359 (define_expand "vec_widen_umult_even_v16qi" | |
1360 [(use (match_operand:V8HI 0 "register_operand" "")) | |
1361 (use (match_operand:V16QI 1 "register_operand" "")) | |
1362 (use (match_operand:V16QI 2 "register_operand" ""))] | |
1363 "TARGET_ALTIVEC" | |
1364 { | |
1365 if (VECTOR_ELT_ORDER_BIG) | |
1366 emit_insn (gen_altivec_vmuleub (operands[0], operands[1], operands[2])); | |
1367 else | |
1368 emit_insn (gen_altivec_vmuloub (operands[0], operands[1], operands[2])); | |
1369 DONE; | |
1370 }) | |
1371 | |
1372 (define_expand "vec_widen_smult_even_v16qi" | |
1373 [(use (match_operand:V8HI 0 "register_operand" "")) | |
1374 (use (match_operand:V16QI 1 "register_operand" "")) | |
1375 (use (match_operand:V16QI 2 "register_operand" ""))] | |
1376 "TARGET_ALTIVEC" | |
1377 { | |
1378 if (VECTOR_ELT_ORDER_BIG) | |
1379 emit_insn (gen_altivec_vmulesb (operands[0], operands[1], operands[2])); | |
1380 else | |
1381 emit_insn (gen_altivec_vmulosb (operands[0], operands[1], operands[2])); | |
1382 DONE; | |
1383 }) | |
1384 | |
1385 (define_expand "vec_widen_umult_even_v8hi" | |
1386 [(use (match_operand:V4SI 0 "register_operand" "")) | |
1387 (use (match_operand:V8HI 1 "register_operand" "")) | |
1388 (use (match_operand:V8HI 2 "register_operand" ""))] | |
1389 "TARGET_ALTIVEC" | |
1390 { | |
1391 if (VECTOR_ELT_ORDER_BIG) | |
1392 emit_insn (gen_altivec_vmuleuh (operands[0], operands[1], operands[2])); | |
1393 else | |
1394 emit_insn (gen_altivec_vmulouh (operands[0], operands[1], operands[2])); | |
1395 DONE; | |
1396 }) | |
1397 | |
1398 (define_expand "vec_widen_smult_even_v8hi" | |
1399 [(use (match_operand:V4SI 0 "register_operand" "")) | |
1400 (use (match_operand:V8HI 1 "register_operand" "")) | |
1401 (use (match_operand:V8HI 2 "register_operand" ""))] | |
1402 "TARGET_ALTIVEC" | |
1403 { | |
1404 if (VECTOR_ELT_ORDER_BIG) | |
1405 emit_insn (gen_altivec_vmulesh (operands[0], operands[1], operands[2])); | |
1406 else | |
1407 emit_insn (gen_altivec_vmulosh (operands[0], operands[1], operands[2])); | |
1408 DONE; | |
1409 }) | |
1410 | |
1411 (define_expand "vec_widen_umult_odd_v16qi" | |
1412 [(use (match_operand:V8HI 0 "register_operand" "")) | |
1413 (use (match_operand:V16QI 1 "register_operand" "")) | |
1414 (use (match_operand:V16QI 2 "register_operand" ""))] | |
1415 "TARGET_ALTIVEC" | |
1416 { | |
1417 if (VECTOR_ELT_ORDER_BIG) | |
1418 emit_insn (gen_altivec_vmuloub (operands[0], operands[1], operands[2])); | |
1419 else | |
1420 emit_insn (gen_altivec_vmuleub (operands[0], operands[1], operands[2])); | |
1421 DONE; | |
1422 }) | |
1423 | |
1424 (define_expand "vec_widen_smult_odd_v16qi" | |
1425 [(use (match_operand:V8HI 0 "register_operand" "")) | |
1426 (use (match_operand:V16QI 1 "register_operand" "")) | |
1427 (use (match_operand:V16QI 2 "register_operand" ""))] | |
1428 "TARGET_ALTIVEC" | |
1429 { | |
1430 if (VECTOR_ELT_ORDER_BIG) | |
1431 emit_insn (gen_altivec_vmulosb (operands[0], operands[1], operands[2])); | |
1432 else | |
1433 emit_insn (gen_altivec_vmulesb (operands[0], operands[1], operands[2])); | |
1434 DONE; | |
1435 }) | |
1436 | |
1437 (define_expand "vec_widen_umult_odd_v8hi" | |
1438 [(use (match_operand:V4SI 0 "register_operand" "")) | |
1439 (use (match_operand:V8HI 1 "register_operand" "")) | |
1440 (use (match_operand:V8HI 2 "register_operand" ""))] | |
1441 "TARGET_ALTIVEC" | |
1442 { | |
1443 if (VECTOR_ELT_ORDER_BIG) | |
1444 emit_insn (gen_altivec_vmulouh (operands[0], operands[1], operands[2])); | |
1445 else | |
1446 emit_insn (gen_altivec_vmuleuh (operands[0], operands[1], operands[2])); | |
1447 DONE; | |
1448 }) | |
1449 | |
1450 (define_expand "vec_widen_smult_odd_v8hi" | |
1451 [(use (match_operand:V4SI 0 "register_operand" "")) | |
1452 (use (match_operand:V8HI 1 "register_operand" "")) | |
1453 (use (match_operand:V8HI 2 "register_operand" ""))] | |
1454 "TARGET_ALTIVEC" | |
1455 { | |
1456 if (VECTOR_ELT_ORDER_BIG) | |
1457 emit_insn (gen_altivec_vmulosh (operands[0], operands[1], operands[2])); | |
1458 else | |
1459 emit_insn (gen_altivec_vmulesh (operands[0], operands[1], operands[2])); | |
1460 DONE; | |
1461 }) | |
1462 | |
1463 (define_insn "altivec_vmuleub" | |
1464 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
1465 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") | |
1466 (match_operand:V16QI 2 "register_operand" "v")] | |
1467 UNSPEC_VMULEUB))] | |
1468 "TARGET_ALTIVEC" | |
1469 "vmuleub %0,%1,%2" | |
1470 [(set_attr "type" "veccomplex")]) | |
1471 | |
1472 (define_insn "altivec_vmuloub" | |
1473 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
1474 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") | |
1475 (match_operand:V16QI 2 "register_operand" "v")] | |
1476 UNSPEC_VMULOUB))] | |
1477 "TARGET_ALTIVEC" | |
1478 "vmuloub %0,%1,%2" | |
1479 [(set_attr "type" "veccomplex")]) | |
1480 | |
1481 (define_insn "altivec_vmulesb" | |
1482 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
1483 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") | |
1484 (match_operand:V16QI 2 "register_operand" "v")] | |
1485 UNSPEC_VMULESB))] | |
1486 "TARGET_ALTIVEC" | |
1487 "vmulesb %0,%1,%2" | |
1488 [(set_attr "type" "veccomplex")]) | |
1489 | |
1490 (define_insn "altivec_vmulosb" | |
1491 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
1492 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") | |
1493 (match_operand:V16QI 2 "register_operand" "v")] | |
1494 UNSPEC_VMULOSB))] | |
1495 "TARGET_ALTIVEC" | |
1496 "vmulosb %0,%1,%2" | |
1497 [(set_attr "type" "veccomplex")]) | |
1498 | |
1499 (define_insn "altivec_vmuleuh" | |
1500 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1501 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") | |
1502 (match_operand:V8HI 2 "register_operand" "v")] | |
1503 UNSPEC_VMULEUH))] | |
1504 "TARGET_ALTIVEC" | |
1505 "vmuleuh %0,%1,%2" | |
1506 [(set_attr "type" "veccomplex")]) | |
1507 | |
1508 (define_insn "altivec_vmulouh" | |
1509 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1510 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") | |
1511 (match_operand:V8HI 2 "register_operand" "v")] | |
1512 UNSPEC_VMULOUH))] | |
1513 "TARGET_ALTIVEC" | |
1514 "vmulouh %0,%1,%2" | |
1515 [(set_attr "type" "veccomplex")]) | |
1516 | |
1517 (define_insn "altivec_vmulesh" | |
1518 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1519 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") | |
1520 (match_operand:V8HI 2 "register_operand" "v")] | |
1521 UNSPEC_VMULESH))] | |
1522 "TARGET_ALTIVEC" | |
1523 "vmulesh %0,%1,%2" | |
1524 [(set_attr "type" "veccomplex")]) | |
1525 | |
1526 (define_insn "altivec_vmulosh" | |
1527 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1528 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") | |
1529 (match_operand:V8HI 2 "register_operand" "v")] | |
1530 UNSPEC_VMULOSH))] | |
1531 "TARGET_ALTIVEC" | |
1532 "vmulosh %0,%1,%2" | |
1533 [(set_attr "type" "veccomplex")]) | |
1534 | |
1535 | |
1536 ;; Vector pack/unpack | |
1537 (define_insn "altivec_vpkpx" | |
1538 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
1539 (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") | |
1540 (match_operand:V4SI 2 "register_operand" "v")] | |
1541 UNSPEC_VPKPX))] | |
1542 "TARGET_ALTIVEC" | |
1543 "* | |
1544 { | |
1545 if (VECTOR_ELT_ORDER_BIG) | |
1546 return \"vpkpx %0,%1,%2\"; | |
1547 else | |
1548 return \"vpkpx %0,%2,%1\"; | |
1549 }" | |
1550 [(set_attr "type" "vecperm")]) | |
1551 | |
1552 (define_insn "altivec_vpks<VI_char>ss" | |
1553 [(set (match_operand:<VP_small> 0 "register_operand" "=v") | |
1554 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v") | |
1555 (match_operand:VP 2 "register_operand" "v")] | |
1556 UNSPEC_VPACK_SIGN_SIGN_SAT))] | |
1557 "<VI_unit>" | |
1558 "* | |
1559 { | |
1560 if (VECTOR_ELT_ORDER_BIG) | |
1561 return \"vpks<VI_char>ss %0,%1,%2\"; | |
1562 else | |
1563 return \"vpks<VI_char>ss %0,%2,%1\"; | |
1564 }" | |
1565 [(set_attr "type" "vecperm")]) | |
1566 | |
1567 (define_insn "altivec_vpks<VI_char>us" | |
1568 [(set (match_operand:<VP_small> 0 "register_operand" "=v") | |
1569 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v") | |
1570 (match_operand:VP 2 "register_operand" "v")] | |
1571 UNSPEC_VPACK_SIGN_UNS_SAT))] | |
1572 "<VI_unit>" | |
1573 "* | |
1574 { | |
1575 if (VECTOR_ELT_ORDER_BIG) | |
1576 return \"vpks<VI_char>us %0,%1,%2\"; | |
1577 else | |
1578 return \"vpks<VI_char>us %0,%2,%1\"; | |
1579 }" | |
1580 [(set_attr "type" "vecperm")]) | |
1581 | |
1582 (define_insn "altivec_vpku<VI_char>us" | |
1583 [(set (match_operand:<VP_small> 0 "register_operand" "=v") | |
1584 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v") | |
1585 (match_operand:VP 2 "register_operand" "v")] | |
1586 UNSPEC_VPACK_UNS_UNS_SAT))] | |
1587 "<VI_unit>" | |
1588 "* | |
1589 { | |
1590 if (VECTOR_ELT_ORDER_BIG) | |
1591 return \"vpku<VI_char>us %0,%1,%2\"; | |
1592 else | |
1593 return \"vpku<VI_char>us %0,%2,%1\"; | |
1594 }" | |
1595 [(set_attr "type" "vecperm")]) | |
1596 | |
1597 (define_insn "altivec_vpku<VI_char>um" | |
1598 [(set (match_operand:<VP_small> 0 "register_operand" "=v") | |
1599 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v") | |
1600 (match_operand:VP 2 "register_operand" "v")] | |
1601 UNSPEC_VPACK_UNS_UNS_MOD))] | |
1602 "<VI_unit>" | |
1603 "* | |
1604 { | |
1605 if (VECTOR_ELT_ORDER_BIG) | |
1606 return \"vpku<VI_char>um %0,%1,%2\"; | |
1607 else | |
1608 return \"vpku<VI_char>um %0,%2,%1\"; | |
1609 }" | |
1610 [(set_attr "type" "vecperm")]) | |
1611 | |
1612 (define_insn "altivec_vpku<VI_char>um_direct" | |
1613 [(set (match_operand:<VP_small> 0 "register_operand" "=v") | |
1614 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v") | |
1615 (match_operand:VP 2 "register_operand" "v")] | |
1616 UNSPEC_VPACK_UNS_UNS_MOD_DIRECT))] | |
1617 "<VI_unit>" | |
1618 "* | |
1619 { | |
1620 if (BYTES_BIG_ENDIAN) | |
1621 return \"vpku<VI_char>um %0,%1,%2\"; | |
1622 else | |
1623 return \"vpku<VI_char>um %0,%2,%1\"; | |
1624 }" | |
1625 [(set_attr "type" "vecperm")]) | |
1626 | |
1627 (define_insn "*altivec_vrl<VI_char>" | |
1628 [(set (match_operand:VI2 0 "register_operand" "=v") | |
1629 (rotate:VI2 (match_operand:VI2 1 "register_operand" "v") | |
1630 (match_operand:VI2 2 "register_operand" "v")))] | |
1631 "<VI_unit>" | |
1632 "vrl<VI_char> %0,%1,%2" | |
1633 [(set_attr "type" "vecsimple")]) | |
1634 | |
1635 (define_insn "altivec_vrl<VI_char>mi" | |
1636 [(set (match_operand:VIlong 0 "register_operand" "=v") | |
1637 (unspec:VIlong [(match_operand:VIlong 1 "register_operand" "0") | |
1638 (match_operand:VIlong 2 "register_operand" "v") | |
1639 (match_operand:VIlong 3 "register_operand" "v")] | |
1640 UNSPEC_VRLMI))] | |
1641 "TARGET_P9_VECTOR" | |
1642 "vrl<VI_char>mi %0,%2,%3" | |
1643 [(set_attr "type" "veclogical")]) | |
1644 | |
1645 (define_insn "altivec_vrl<VI_char>nm" | |
1646 [(set (match_operand:VIlong 0 "register_operand" "=v") | |
1647 (unspec:VIlong [(match_operand:VIlong 1 "register_operand" "v") | |
1648 (match_operand:VIlong 2 "register_operand" "v")] | |
1649 UNSPEC_VRLNM))] | |
1650 "TARGET_P9_VECTOR" | |
1651 "vrl<VI_char>nm %0,%1,%2" | |
1652 [(set_attr "type" "veclogical")]) | |
1653 | |
1654 (define_insn "altivec_vsl" | |
1655 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1656 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") | |
1657 (match_operand:V4SI 2 "register_operand" "v")] | |
1658 UNSPEC_VSLV4SI))] | |
1659 "TARGET_ALTIVEC" | |
1660 "vsl %0,%1,%2" | |
1661 [(set_attr "type" "vecperm")]) | |
1662 | |
1663 (define_insn "altivec_vslo" | |
1664 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1665 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") | |
1666 (match_operand:V4SI 2 "register_operand" "v")] | |
1667 UNSPEC_VSLO))] | |
1668 "TARGET_ALTIVEC" | |
1669 "vslo %0,%1,%2" | |
1670 [(set_attr "type" "vecperm")]) | |
1671 | |
1672 (define_insn "vslv" | |
1673 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
1674 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") | |
1675 (match_operand:V16QI 2 "register_operand" "v")] | |
1676 UNSPEC_VSLV))] | |
1677 "TARGET_P9_VECTOR" | |
1678 "vslv %0,%1,%2" | |
1679 [(set_attr "type" "vecsimple")]) | |
1680 | |
1681 (define_insn "vsrv" | |
1682 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
1683 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") | |
1684 (match_operand:V16QI 2 "register_operand" "v")] | |
1685 UNSPEC_VSRV))] | |
1686 "TARGET_P9_VECTOR" | |
1687 "vsrv %0,%1,%2" | |
1688 [(set_attr "type" "vecsimple")]) | |
1689 | |
1690 (define_insn "*altivec_vsl<VI_char>" | |
1691 [(set (match_operand:VI2 0 "register_operand" "=v") | |
1692 (ashift:VI2 (match_operand:VI2 1 "register_operand" "v") | |
1693 (match_operand:VI2 2 "register_operand" "v")))] | |
1694 "<VI_unit>" | |
1695 "vsl<VI_char> %0,%1,%2" | |
1696 [(set_attr "type" "vecsimple")]) | |
1697 | |
1698 (define_insn "*altivec_vsr<VI_char>" | |
1699 [(set (match_operand:VI2 0 "register_operand" "=v") | |
1700 (lshiftrt:VI2 (match_operand:VI2 1 "register_operand" "v") | |
1701 (match_operand:VI2 2 "register_operand" "v")))] | |
1702 "<VI_unit>" | |
1703 "vsr<VI_char> %0,%1,%2" | |
1704 [(set_attr "type" "vecsimple")]) | |
1705 | |
1706 (define_insn "*altivec_vsra<VI_char>" | |
1707 [(set (match_operand:VI2 0 "register_operand" "=v") | |
1708 (ashiftrt:VI2 (match_operand:VI2 1 "register_operand" "v") | |
1709 (match_operand:VI2 2 "register_operand" "v")))] | |
1710 "<VI_unit>" | |
1711 "vsra<VI_char> %0,%1,%2" | |
1712 [(set_attr "type" "vecsimple")]) | |
1713 | |
1714 (define_insn "altivec_vsr" | |
1715 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1716 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") | |
1717 (match_operand:V4SI 2 "register_operand" "v")] | |
1718 UNSPEC_VSR))] | |
1719 "TARGET_ALTIVEC" | |
1720 "vsr %0,%1,%2" | |
1721 [(set_attr "type" "vecperm")]) | |
1722 | |
1723 (define_insn "altivec_vsro" | |
1724 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1725 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") | |
1726 (match_operand:V4SI 2 "register_operand" "v")] | |
1727 UNSPEC_VSRO))] | |
1728 "TARGET_ALTIVEC" | |
1729 "vsro %0,%1,%2" | |
1730 [(set_attr "type" "vecperm")]) | |
1731 | |
1732 (define_insn "altivec_vsum4ubs" | |
1733 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1734 (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v") | |
1735 (match_operand:V4SI 2 "register_operand" "v")] | |
1736 UNSPEC_VSUM4UBS)) | |
1737 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] | |
1738 "TARGET_ALTIVEC" | |
1739 "vsum4ubs %0,%1,%2" | |
1740 [(set_attr "type" "veccomplex")]) | |
1741 | |
1742 (define_insn "altivec_vsum4s<VI_char>s" | |
1743 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1744 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") | |
1745 (match_operand:V4SI 2 "register_operand" "v")] | |
1746 UNSPEC_VSUM4S)) | |
1747 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] | |
1748 "TARGET_ALTIVEC" | |
1749 "vsum4s<VI_char>s %0,%1,%2" | |
1750 [(set_attr "type" "veccomplex")]) | |
1751 | |
1752 ;; FIXME: For the following two patterns, the scratch should only be | |
1753 ;; allocated for !VECTOR_ELT_ORDER_BIG, and the instructions should | |
1754 ;; be emitted separately. | |
1755 (define_insn "altivec_vsum2sws" | |
1756 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1757 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") | |
1758 (match_operand:V4SI 2 "register_operand" "v")] | |
1759 UNSPEC_VSUM2SWS)) | |
1760 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR)) | |
1761 (clobber (match_scratch:V4SI 3 "=v"))] | |
1762 "TARGET_ALTIVEC" | |
1763 { | |
1764 if (VECTOR_ELT_ORDER_BIG) | |
1765 return "vsum2sws %0,%1,%2"; | |
1766 else | |
1767 return "vsldoi %3,%2,%2,12\n\tvsum2sws %3,%1,%3\n\tvsldoi %0,%3,%3,4"; | |
1768 } | |
1769 [(set_attr "type" "veccomplex") | |
1770 (set (attr "length") | |
1771 (if_then_else | |
1772 (match_test "VECTOR_ELT_ORDER_BIG") | |
1773 (const_string "4") | |
1774 (const_string "12")))]) | |
1775 | |
1776 (define_insn "altivec_vsumsws" | |
1777 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1778 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") | |
1779 (match_operand:V4SI 2 "register_operand" "v")] | |
1780 UNSPEC_VSUMSWS)) | |
1781 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR)) | |
1782 (clobber (match_scratch:V4SI 3 "=v"))] | |
1783 "TARGET_ALTIVEC" | |
1784 { | |
1785 if (VECTOR_ELT_ORDER_BIG) | |
1786 return "vsumsws %0,%1,%2"; | |
1787 else | |
1788 return "vspltw %3,%2,0\n\tvsumsws %3,%1,%3\n\tvsldoi %0,%3,%3,12"; | |
1789 } | |
1790 [(set_attr "type" "veccomplex") | |
1791 (set (attr "length") | |
1792 (if_then_else | |
1793 (match_test "(VECTOR_ELT_ORDER_BIG)") | |
1794 (const_string "4") | |
1795 (const_string "12")))]) | |
1796 | |
1797 (define_insn "altivec_vsumsws_direct" | |
1798 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1799 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") | |
1800 (match_operand:V4SI 2 "register_operand" "v")] | |
1801 UNSPEC_VSUMSWS_DIRECT)) | |
1802 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] | |
1803 "TARGET_ALTIVEC" | |
1804 "vsumsws %0,%1,%2" | |
1805 [(set_attr "type" "veccomplex")]) | |
1806 | |
1807 (define_expand "altivec_vspltb" | |
1808 [(use (match_operand:V16QI 0 "register_operand" "")) | |
1809 (use (match_operand:V16QI 1 "register_operand" "")) | |
1810 (use (match_operand:QI 2 "u5bit_cint_operand" ""))] | |
1811 "TARGET_ALTIVEC" | |
1812 { | |
1813 rtvec v; | |
1814 rtx x; | |
1815 | |
1816 /* Special handling for LE with -maltivec=be. We have to reflect | |
1817 the actual selected index for the splat in the RTL. */ | |
1818 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
1819 operands[2] = GEN_INT (15 - INTVAL (operands[2])); | |
1820 | |
1821 v = gen_rtvec (1, operands[2]); | |
1822 x = gen_rtx_VEC_SELECT (QImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v)); | |
1823 x = gen_rtx_VEC_DUPLICATE (V16QImode, x); | |
1824 emit_insn (gen_rtx_SET (operands[0], x)); | |
1825 DONE; | |
1826 }) | |
1827 | |
1828 (define_insn "*altivec_vspltb_internal" | |
1829 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
1830 (vec_duplicate:V16QI | |
1831 (vec_select:QI (match_operand:V16QI 1 "register_operand" "v") | |
1832 (parallel | |
1833 [(match_operand:QI 2 "u5bit_cint_operand" "")]))))] | |
1834 "TARGET_ALTIVEC" | |
1835 { | |
1836 /* For true LE, this adjusts the selected index. For LE with | |
1837 -maltivec=be, this reverses what was done in the define_expand | |
1838 because the instruction already has big-endian bias. */ | |
1839 if (!BYTES_BIG_ENDIAN) | |
1840 operands[2] = GEN_INT (15 - INTVAL (operands[2])); | |
1841 | |
1842 return "vspltb %0,%1,%2"; | |
1843 } | |
1844 [(set_attr "type" "vecperm")]) | |
1845 | |
1846 (define_insn "altivec_vspltb_direct" | |
1847 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
1848 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") | |
1849 (match_operand:QI 2 "u5bit_cint_operand" "i")] | |
1850 UNSPEC_VSPLT_DIRECT))] | |
1851 "TARGET_ALTIVEC" | |
1852 "vspltb %0,%1,%2" | |
1853 [(set_attr "type" "vecperm")]) | |
1854 | |
1855 (define_expand "altivec_vsplth" | |
1856 [(use (match_operand:V8HI 0 "register_operand" "")) | |
1857 (use (match_operand:V8HI 1 "register_operand" "")) | |
1858 (use (match_operand:QI 2 "u5bit_cint_operand" ""))] | |
1859 "TARGET_ALTIVEC" | |
1860 { | |
1861 rtvec v; | |
1862 rtx x; | |
1863 | |
1864 /* Special handling for LE with -maltivec=be. We have to reflect | |
1865 the actual selected index for the splat in the RTL. */ | |
1866 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
1867 operands[2] = GEN_INT (7 - INTVAL (operands[2])); | |
1868 | |
1869 v = gen_rtvec (1, operands[2]); | |
1870 x = gen_rtx_VEC_SELECT (HImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v)); | |
1871 x = gen_rtx_VEC_DUPLICATE (V8HImode, x); | |
1872 emit_insn (gen_rtx_SET (operands[0], x)); | |
1873 DONE; | |
1874 }) | |
1875 | |
1876 (define_insn "*altivec_vsplth_internal" | |
1877 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
1878 (vec_duplicate:V8HI | |
1879 (vec_select:HI (match_operand:V8HI 1 "register_operand" "v") | |
1880 (parallel | |
1881 [(match_operand:QI 2 "u5bit_cint_operand" "")]))))] | |
1882 "TARGET_ALTIVEC" | |
1883 { | |
1884 /* For true LE, this adjusts the selected index. For LE with | |
1885 -maltivec=be, this reverses what was done in the define_expand | |
1886 because the instruction already has big-endian bias. */ | |
1887 if (!BYTES_BIG_ENDIAN) | |
1888 operands[2] = GEN_INT (7 - INTVAL (operands[2])); | |
1889 | |
1890 return "vsplth %0,%1,%2"; | |
1891 } | |
1892 [(set_attr "type" "vecperm")]) | |
1893 | |
1894 (define_insn "altivec_vsplth_direct" | |
1895 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
1896 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") | |
1897 (match_operand:QI 2 "u5bit_cint_operand" "i")] | |
1898 UNSPEC_VSPLT_DIRECT))] | |
1899 "TARGET_ALTIVEC" | |
1900 "vsplth %0,%1,%2" | |
1901 [(set_attr "type" "vecperm")]) | |
1902 | |
1903 (define_expand "altivec_vspltw" | |
1904 [(use (match_operand:V4SI 0 "register_operand" "")) | |
1905 (use (match_operand:V4SI 1 "register_operand" "")) | |
1906 (use (match_operand:QI 2 "u5bit_cint_operand" ""))] | |
1907 "TARGET_ALTIVEC" | |
1908 { | |
1909 rtvec v; | |
1910 rtx x; | |
1911 | |
1912 /* Special handling for LE with -maltivec=be. We have to reflect | |
1913 the actual selected index for the splat in the RTL. */ | |
1914 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
1915 operands[2] = GEN_INT (3 - INTVAL (operands[2])); | |
1916 | |
1917 v = gen_rtvec (1, operands[2]); | |
1918 x = gen_rtx_VEC_SELECT (SImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v)); | |
1919 x = gen_rtx_VEC_DUPLICATE (V4SImode, x); | |
1920 emit_insn (gen_rtx_SET (operands[0], x)); | |
1921 DONE; | |
1922 }) | |
1923 | |
1924 (define_insn "*altivec_vspltw_internal" | |
1925 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1926 (vec_duplicate:V4SI | |
1927 (vec_select:SI (match_operand:V4SI 1 "register_operand" "v") | |
1928 (parallel | |
1929 [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))] | |
1930 "TARGET_ALTIVEC" | |
1931 { | |
1932 /* For true LE, this adjusts the selected index. For LE with | |
1933 -maltivec=be, this reverses what was done in the define_expand | |
1934 because the instruction already has big-endian bias. */ | |
1935 if (!BYTES_BIG_ENDIAN) | |
1936 operands[2] = GEN_INT (3 - INTVAL (operands[2])); | |
1937 | |
1938 return "vspltw %0,%1,%2"; | |
1939 } | |
1940 [(set_attr "type" "vecperm")]) | |
1941 | |
1942 (define_insn "altivec_vspltw_direct" | |
1943 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
1944 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") | |
1945 (match_operand:QI 2 "u5bit_cint_operand" "i")] | |
1946 UNSPEC_VSPLT_DIRECT))] | |
1947 "TARGET_ALTIVEC" | |
1948 "vspltw %0,%1,%2" | |
1949 [(set_attr "type" "vecperm")]) | |
1950 | |
1951 (define_expand "altivec_vspltsf" | |
1952 [(use (match_operand:V4SF 0 "register_operand" "")) | |
1953 (use (match_operand:V4SF 1 "register_operand" "")) | |
1954 (use (match_operand:QI 2 "u5bit_cint_operand" ""))] | |
1955 "TARGET_ALTIVEC" | |
1956 { | |
1957 rtvec v; | |
1958 rtx x; | |
1959 | |
1960 /* Special handling for LE with -maltivec=be. We have to reflect | |
1961 the actual selected index for the splat in the RTL. */ | |
1962 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
1963 operands[2] = GEN_INT (3 - INTVAL (operands[2])); | |
1964 | |
1965 v = gen_rtvec (1, operands[2]); | |
1966 x = gen_rtx_VEC_SELECT (SFmode, operands[1], gen_rtx_PARALLEL (VOIDmode, v)); | |
1967 x = gen_rtx_VEC_DUPLICATE (V4SFmode, x); | |
1968 emit_insn (gen_rtx_SET (operands[0], x)); | |
1969 DONE; | |
1970 }) | |
1971 | |
1972 (define_insn "*altivec_vspltsf_internal" | |
1973 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
1974 (vec_duplicate:V4SF | |
1975 (vec_select:SF (match_operand:V4SF 1 "register_operand" "v") | |
1976 (parallel | |
1977 [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))] | |
1978 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
1979 { | |
1980 /* For true LE, this adjusts the selected index. For LE with | |
1981 -maltivec=be, this reverses what was done in the define_expand | |
1982 because the instruction already has big-endian bias. */ | |
1983 if (!BYTES_BIG_ENDIAN) | |
1984 operands[2] = GEN_INT (3 - INTVAL (operands[2])); | |
1985 | |
1986 return "vspltw %0,%1,%2"; | |
1987 } | |
1988 [(set_attr "type" "vecperm")]) | |
1989 | |
1990 (define_insn "altivec_vspltis<VI_char>" | |
1991 [(set (match_operand:VI 0 "register_operand" "=v") | |
1992 (vec_duplicate:VI | |
1993 (match_operand:QI 1 "s5bit_cint_operand" "i")))] | |
1994 "TARGET_ALTIVEC" | |
1995 "vspltis<VI_char> %0,%1" | |
1996 [(set_attr "type" "vecperm")]) | |
1997 | |
1998 (define_insn "*altivec_vrfiz" | |
1999 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
2000 (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))] | |
2001 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
2002 "vrfiz %0,%1" | |
2003 [(set_attr "type" "vecfloat")]) | |
2004 | |
2005 (define_expand "altivec_vperm_<mode>" | |
2006 [(set (match_operand:VM 0 "register_operand" "") | |
2007 (unspec:VM [(match_operand:VM 1 "register_operand" "") | |
2008 (match_operand:VM 2 "register_operand" "") | |
2009 (match_operand:V16QI 3 "register_operand" "")] | |
2010 UNSPEC_VPERM))] | |
2011 "TARGET_ALTIVEC" | |
2012 { | |
2013 if (!VECTOR_ELT_ORDER_BIG) | |
2014 { | |
2015 altivec_expand_vec_perm_le (operands); | |
2016 DONE; | |
2017 } | |
2018 }) | |
2019 | |
2020 ;; Slightly prefer vperm, since the target does not overlap the source | |
2021 (define_insn "*altivec_vperm_<mode>_internal" | |
2022 [(set (match_operand:VM 0 "register_operand" "=v,?wo") | |
2023 (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo") | |
2024 (match_operand:VM 2 "register_operand" "v,0") | |
2025 (match_operand:V16QI 3 "register_operand" "v,wo")] | |
2026 UNSPEC_VPERM))] | |
2027 "TARGET_ALTIVEC" | |
2028 "@ | |
2029 vperm %0,%1,%2,%3 | |
2030 xxperm %x0,%x1,%x3" | |
2031 [(set_attr "type" "vecperm") | |
2032 (set_attr "length" "4")]) | |
2033 | |
2034 (define_insn "altivec_vperm_v8hiv16qi" | |
2035 [(set (match_operand:V16QI 0 "register_operand" "=v,?wo") | |
2036 (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v,wo") | |
2037 (match_operand:V8HI 2 "register_operand" "v,0") | |
2038 (match_operand:V16QI 3 "register_operand" "v,wo")] | |
2039 UNSPEC_VPERM))] | |
2040 "TARGET_ALTIVEC" | |
2041 "@ | |
2042 vperm %0,%1,%2,%3 | |
2043 xxperm %x0,%x1,%x3" | |
2044 [(set_attr "type" "vecperm") | |
2045 (set_attr "length" "4")]) | |
2046 | |
2047 (define_expand "altivec_vperm_<mode>_uns" | |
2048 [(set (match_operand:VM 0 "register_operand" "") | |
2049 (unspec:VM [(match_operand:VM 1 "register_operand" "") | |
2050 (match_operand:VM 2 "register_operand" "") | |
2051 (match_operand:V16QI 3 "register_operand" "")] | |
2052 UNSPEC_VPERM_UNS))] | |
2053 "TARGET_ALTIVEC" | |
2054 { | |
2055 if (!VECTOR_ELT_ORDER_BIG) | |
2056 { | |
2057 altivec_expand_vec_perm_le (operands); | |
2058 DONE; | |
2059 } | |
2060 }) | |
2061 | |
2062 (define_insn "*altivec_vperm_<mode>_uns_internal" | |
2063 [(set (match_operand:VM 0 "register_operand" "=v,?wo") | |
2064 (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo") | |
2065 (match_operand:VM 2 "register_operand" "v,0") | |
2066 (match_operand:V16QI 3 "register_operand" "v,wo")] | |
2067 UNSPEC_VPERM_UNS))] | |
2068 "TARGET_ALTIVEC" | |
2069 "@ | |
2070 vperm %0,%1,%2,%3 | |
2071 xxperm %x0,%x1,%x3" | |
2072 [(set_attr "type" "vecperm") | |
2073 (set_attr "length" "4")]) | |
2074 | |
2075 (define_expand "vec_permv16qi" | |
2076 [(set (match_operand:V16QI 0 "register_operand" "") | |
2077 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "") | |
2078 (match_operand:V16QI 2 "register_operand" "") | |
2079 (match_operand:V16QI 3 "register_operand" "")] | |
2080 UNSPEC_VPERM))] | |
2081 "TARGET_ALTIVEC" | |
2082 { | |
2083 if (!BYTES_BIG_ENDIAN) { | |
2084 altivec_expand_vec_perm_le (operands); | |
2085 DONE; | |
2086 } | |
2087 }) | |
2088 | |
2089 (define_expand "vec_perm_constv16qi" | |
2090 [(match_operand:V16QI 0 "register_operand" "") | |
2091 (match_operand:V16QI 1 "register_operand" "") | |
2092 (match_operand:V16QI 2 "register_operand" "") | |
2093 (match_operand:V16QI 3 "" "")] | |
2094 "TARGET_ALTIVEC" | |
2095 { | |
2096 if (altivec_expand_vec_perm_const (operands)) | |
2097 DONE; | |
2098 else | |
2099 FAIL; | |
2100 }) | |
2101 | |
2102 (define_insn "*altivec_vpermr_<mode>_internal" | |
2103 [(set (match_operand:VM 0 "register_operand" "=v,?wo") | |
2104 (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo") | |
2105 (match_operand:VM 2 "register_operand" "v,0") | |
2106 (match_operand:V16QI 3 "register_operand" "v,wo")] | |
2107 UNSPEC_VPERMR))] | |
2108 "TARGET_P9_VECTOR" | |
2109 "@ | |
2110 vpermr %0,%2,%1,%3 | |
2111 xxpermr %x0,%x1,%x3" | |
2112 [(set_attr "type" "vecperm") | |
2113 (set_attr "length" "4")]) | |
2114 | |
2115 (define_insn "altivec_vrfip" ; ceil | |
2116 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
2117 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] | |
2118 UNSPEC_FRIP))] | |
2119 "TARGET_ALTIVEC" | |
2120 "vrfip %0,%1" | |
2121 [(set_attr "type" "vecfloat")]) | |
2122 | |
2123 (define_insn "altivec_vrfin" | |
2124 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
2125 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] | |
2126 UNSPEC_VRFIN))] | |
2127 "TARGET_ALTIVEC" | |
2128 "vrfin %0,%1" | |
2129 [(set_attr "type" "vecfloat")]) | |
2130 | |
2131 (define_insn "*altivec_vrfim" ; floor | |
2132 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
2133 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] | |
2134 UNSPEC_FRIM))] | |
2135 "TARGET_ALTIVEC" | |
2136 "vrfim %0,%1" | |
2137 [(set_attr "type" "vecfloat")]) | |
2138 | |
2139 (define_insn "altivec_vcfux" | |
2140 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
2141 (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") | |
2142 (match_operand:QI 2 "immediate_operand" "i")] | |
2143 UNSPEC_VCFUX))] | |
2144 "TARGET_ALTIVEC" | |
2145 "vcfux %0,%1,%2" | |
2146 [(set_attr "type" "vecfloat")]) | |
2147 | |
2148 (define_insn "altivec_vcfsx" | |
2149 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
2150 (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") | |
2151 (match_operand:QI 2 "immediate_operand" "i")] | |
2152 UNSPEC_VCFSX))] | |
2153 "TARGET_ALTIVEC" | |
2154 "vcfsx %0,%1,%2" | |
2155 [(set_attr "type" "vecfloat")]) | |
2156 | |
2157 (define_insn "altivec_vctuxs" | |
2158 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
2159 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") | |
2160 (match_operand:QI 2 "immediate_operand" "i")] | |
2161 UNSPEC_VCTUXS)) | |
2162 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] | |
2163 "TARGET_ALTIVEC" | |
2164 "vctuxs %0,%1,%2" | |
2165 [(set_attr "type" "vecfloat")]) | |
2166 | |
2167 (define_insn "altivec_vctsxs" | |
2168 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
2169 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") | |
2170 (match_operand:QI 2 "immediate_operand" "i")] | |
2171 UNSPEC_VCTSXS)) | |
2172 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] | |
2173 "TARGET_ALTIVEC" | |
2174 "vctsxs %0,%1,%2" | |
2175 [(set_attr "type" "vecfloat")]) | |
2176 | |
2177 (define_insn "altivec_vlogefp" | |
2178 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
2179 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] | |
2180 UNSPEC_VLOGEFP))] | |
2181 "TARGET_ALTIVEC" | |
2182 "vlogefp %0,%1" | |
2183 [(set_attr "type" "vecfloat")]) | |
2184 | |
2185 (define_insn "altivec_vexptefp" | |
2186 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
2187 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] | |
2188 UNSPEC_VEXPTEFP))] | |
2189 "TARGET_ALTIVEC" | |
2190 "vexptefp %0,%1" | |
2191 [(set_attr "type" "vecfloat")]) | |
2192 | |
2193 (define_insn "*altivec_vrsqrtefp" | |
2194 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
2195 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] | |
2196 UNSPEC_RSQRT))] | |
2197 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
2198 "vrsqrtefp %0,%1" | |
2199 [(set_attr "type" "vecfloat")]) | |
2200 | |
2201 (define_insn "altivec_vrefp" | |
2202 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
2203 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] | |
2204 UNSPEC_FRES))] | |
2205 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
2206 "vrefp %0,%1" | |
2207 [(set_attr "type" "vecfloat")]) | |
2208 | |
2209 (define_expand "altivec_copysign_v4sf3" | |
2210 [(use (match_operand:V4SF 0 "register_operand" "")) | |
2211 (use (match_operand:V4SF 1 "register_operand" "")) | |
2212 (use (match_operand:V4SF 2 "register_operand" ""))] | |
2213 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
2214 " | |
2215 { | |
2216 rtx mask = gen_reg_rtx (V4SImode); | |
2217 rtvec v = rtvec_alloc (4); | |
2218 unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31; | |
2219 | |
2220 RTVEC_ELT (v, 0) = GEN_INT (mask_val); | |
2221 RTVEC_ELT (v, 1) = GEN_INT (mask_val); | |
2222 RTVEC_ELT (v, 2) = GEN_INT (mask_val); | |
2223 RTVEC_ELT (v, 3) = GEN_INT (mask_val); | |
2224 | |
2225 emit_insn (gen_vec_initv4sisi (mask, gen_rtx_PARALLEL (V4SImode, v))); | |
2226 emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2], | |
2227 gen_lowpart (V4SFmode, mask))); | |
2228 DONE; | |
2229 }") | |
2230 | |
2231 (define_insn "altivec_vsldoi_<mode>" | |
2232 [(set (match_operand:VM 0 "register_operand" "=v") | |
2233 (unspec:VM [(match_operand:VM 1 "register_operand" "v") | |
2234 (match_operand:VM 2 "register_operand" "v") | |
2235 (match_operand:QI 3 "immediate_operand" "i")] | |
2236 UNSPEC_VSLDOI))] | |
2237 "TARGET_ALTIVEC" | |
2238 "vsldoi %0,%1,%2,%3" | |
2239 [(set_attr "type" "vecperm")]) | |
2240 | |
2241 (define_insn "altivec_vupkhs<VU_char>" | |
2242 [(set (match_operand:VP 0 "register_operand" "=v") | |
2243 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] | |
2244 UNSPEC_VUNPACK_HI_SIGN))] | |
2245 "<VI_unit>" | |
2246 { | |
2247 if (VECTOR_ELT_ORDER_BIG) | |
2248 return "vupkhs<VU_char> %0,%1"; | |
2249 else | |
2250 return "vupkls<VU_char> %0,%1"; | |
2251 } | |
2252 [(set_attr "type" "vecperm")]) | |
2253 | |
2254 (define_insn "*altivec_vupkhs<VU_char>_direct" | |
2255 [(set (match_operand:VP 0 "register_operand" "=v") | |
2256 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] | |
2257 UNSPEC_VUNPACK_HI_SIGN_DIRECT))] | |
2258 "<VI_unit>" | |
2259 "vupkhs<VU_char> %0,%1" | |
2260 [(set_attr "type" "vecperm")]) | |
2261 | |
2262 (define_insn "altivec_vupkls<VU_char>" | |
2263 [(set (match_operand:VP 0 "register_operand" "=v") | |
2264 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] | |
2265 UNSPEC_VUNPACK_LO_SIGN))] | |
2266 "<VI_unit>" | |
2267 { | |
2268 if (VECTOR_ELT_ORDER_BIG) | |
2269 return "vupkls<VU_char> %0,%1"; | |
2270 else | |
2271 return "vupkhs<VU_char> %0,%1"; | |
2272 } | |
2273 [(set_attr "type" "vecperm")]) | |
2274 | |
2275 (define_insn "*altivec_vupkls<VU_char>_direct" | |
2276 [(set (match_operand:VP 0 "register_operand" "=v") | |
2277 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] | |
2278 UNSPEC_VUNPACK_LO_SIGN_DIRECT))] | |
2279 "<VI_unit>" | |
2280 "vupkls<VU_char> %0,%1" | |
2281 [(set_attr "type" "vecperm")]) | |
2282 | |
2283 (define_insn "altivec_vupkhpx" | |
2284 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
2285 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] | |
2286 UNSPEC_VUPKHPX))] | |
2287 "TARGET_ALTIVEC" | |
2288 { | |
2289 if (VECTOR_ELT_ORDER_BIG) | |
2290 return "vupkhpx %0,%1"; | |
2291 else | |
2292 return "vupklpx %0,%1"; | |
2293 } | |
2294 [(set_attr "type" "vecperm")]) | |
2295 | |
2296 (define_insn "altivec_vupklpx" | |
2297 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
2298 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] | |
2299 UNSPEC_VUPKLPX))] | |
2300 "TARGET_ALTIVEC" | |
2301 { | |
2302 if (VECTOR_ELT_ORDER_BIG) | |
2303 return "vupklpx %0,%1"; | |
2304 else | |
2305 return "vupkhpx %0,%1"; | |
2306 } | |
2307 [(set_attr "type" "vecperm")]) | |
2308 | |
2309 ;; Compare vectors producing a vector result and a predicate, setting CR6 to | |
2310 ;; indicate a combined status | |
2311 (define_insn "*altivec_vcmpequ<VI_char>_p" | |
2312 [(set (reg:CC CR6_REGNO) | |
2313 (unspec:CC [(eq:CC (match_operand:VI2 1 "register_operand" "v") | |
2314 (match_operand:VI2 2 "register_operand" "v"))] | |
2315 UNSPEC_PREDICATE)) | |
2316 (set (match_operand:VI2 0 "register_operand" "=v") | |
2317 (eq:VI2 (match_dup 1) | |
2318 (match_dup 2)))] | |
2319 "<VI_unit>" | |
2320 "vcmpequ<VI_char>. %0,%1,%2" | |
2321 [(set_attr "type" "veccmpfx")]) | |
2322 | |
2323 (define_insn "*altivec_vcmpgts<VI_char>_p" | |
2324 [(set (reg:CC CR6_REGNO) | |
2325 (unspec:CC [(gt:CC (match_operand:VI2 1 "register_operand" "v") | |
2326 (match_operand:VI2 2 "register_operand" "v"))] | |
2327 UNSPEC_PREDICATE)) | |
2328 (set (match_operand:VI2 0 "register_operand" "=v") | |
2329 (gt:VI2 (match_dup 1) | |
2330 (match_dup 2)))] | |
2331 "<VI_unit>" | |
2332 "vcmpgts<VI_char>. %0,%1,%2" | |
2333 [(set_attr "type" "veccmpfx")]) | |
2334 | |
2335 (define_insn "*altivec_vcmpgtu<VI_char>_p" | |
2336 [(set (reg:CC CR6_REGNO) | |
2337 (unspec:CC [(gtu:CC (match_operand:VI2 1 "register_operand" "v") | |
2338 (match_operand:VI2 2 "register_operand" "v"))] | |
2339 UNSPEC_PREDICATE)) | |
2340 (set (match_operand:VI2 0 "register_operand" "=v") | |
2341 (gtu:VI2 (match_dup 1) | |
2342 (match_dup 2)))] | |
2343 "<VI_unit>" | |
2344 "vcmpgtu<VI_char>. %0,%1,%2" | |
2345 [(set_attr "type" "veccmpfx")]) | |
2346 | |
2347 (define_insn "*altivec_vcmpeqfp_p" | |
2348 [(set (reg:CC CR6_REGNO) | |
2349 (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v") | |
2350 (match_operand:V4SF 2 "register_operand" "v"))] | |
2351 UNSPEC_PREDICATE)) | |
2352 (set (match_operand:V4SF 0 "register_operand" "=v") | |
2353 (eq:V4SF (match_dup 1) | |
2354 (match_dup 2)))] | |
2355 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
2356 "vcmpeqfp. %0,%1,%2" | |
2357 [(set_attr "type" "veccmp")]) | |
2358 | |
2359 (define_insn "*altivec_vcmpgtfp_p" | |
2360 [(set (reg:CC CR6_REGNO) | |
2361 (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v") | |
2362 (match_operand:V4SF 2 "register_operand" "v"))] | |
2363 UNSPEC_PREDICATE)) | |
2364 (set (match_operand:V4SF 0 "register_operand" "=v") | |
2365 (gt:V4SF (match_dup 1) | |
2366 (match_dup 2)))] | |
2367 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
2368 "vcmpgtfp. %0,%1,%2" | |
2369 [(set_attr "type" "veccmp")]) | |
2370 | |
2371 (define_insn "*altivec_vcmpgefp_p" | |
2372 [(set (reg:CC CR6_REGNO) | |
2373 (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v") | |
2374 (match_operand:V4SF 2 "register_operand" "v"))] | |
2375 UNSPEC_PREDICATE)) | |
2376 (set (match_operand:V4SF 0 "register_operand" "=v") | |
2377 (ge:V4SF (match_dup 1) | |
2378 (match_dup 2)))] | |
2379 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" | |
2380 "vcmpgefp. %0,%1,%2" | |
2381 [(set_attr "type" "veccmp")]) | |
2382 | |
2383 (define_insn "altivec_vcmpbfp_p" | |
2384 [(set (reg:CC CR6_REGNO) | |
2385 (unspec:CC [(match_operand:V4SF 1 "register_operand" "v") | |
2386 (match_operand:V4SF 2 "register_operand" "v")] | |
2387 UNSPEC_VCMPBFP)) | |
2388 (set (match_operand:V4SF 0 "register_operand" "=v") | |
2389 (unspec:V4SF [(match_dup 1) | |
2390 (match_dup 2)] | |
2391 UNSPEC_VCMPBFP))] | |
2392 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" | |
2393 "vcmpbfp. %0,%1,%2" | |
2394 [(set_attr "type" "veccmp")]) | |
2395 | |
2396 (define_insn "altivec_mtvscr" | |
2397 [(set (reg:SI VSCR_REGNO) | |
2398 (unspec_volatile:SI | |
2399 [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))] | |
2400 "TARGET_ALTIVEC" | |
2401 "mtvscr %0" | |
2402 [(set_attr "type" "vecsimple")]) | |
2403 | |
2404 (define_insn "altivec_mfvscr" | |
2405 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
2406 (unspec_volatile:V8HI [(reg:SI VSCR_REGNO)] UNSPECV_MFVSCR))] | |
2407 "TARGET_ALTIVEC" | |
2408 "mfvscr %0" | |
2409 [(set_attr "type" "vecsimple")]) | |
2410 | |
2411 (define_insn "altivec_dssall" | |
2412 [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)] | |
2413 "TARGET_ALTIVEC" | |
2414 "dssall" | |
2415 [(set_attr "type" "vecsimple")]) | |
2416 | |
2417 (define_insn "altivec_dss" | |
2418 [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")] | |
2419 UNSPECV_DSS)] | |
2420 "TARGET_ALTIVEC" | |
2421 "dss %0" | |
2422 [(set_attr "type" "vecsimple")]) | |
2423 | |
2424 (define_insn "altivec_dst" | |
2425 [(unspec [(match_operand 0 "register_operand" "b") | |
2426 (match_operand:SI 1 "register_operand" "r") | |
2427 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)] | |
2428 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" | |
2429 "dst %0,%1,%2" | |
2430 [(set_attr "type" "vecsimple")]) | |
2431 | |
2432 (define_insn "altivec_dstt" | |
2433 [(unspec [(match_operand 0 "register_operand" "b") | |
2434 (match_operand:SI 1 "register_operand" "r") | |
2435 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)] | |
2436 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" | |
2437 "dstt %0,%1,%2" | |
2438 [(set_attr "type" "vecsimple")]) | |
2439 | |
2440 (define_insn "altivec_dstst" | |
2441 [(unspec [(match_operand 0 "register_operand" "b") | |
2442 (match_operand:SI 1 "register_operand" "r") | |
2443 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)] | |
2444 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" | |
2445 "dstst %0,%1,%2" | |
2446 [(set_attr "type" "vecsimple")]) | |
2447 | |
2448 (define_insn "altivec_dststt" | |
2449 [(unspec [(match_operand 0 "register_operand" "b") | |
2450 (match_operand:SI 1 "register_operand" "r") | |
2451 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)] | |
2452 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" | |
2453 "dststt %0,%1,%2" | |
2454 [(set_attr "type" "vecsimple")]) | |
2455 | |
2456 (define_expand "altivec_lvsl" | |
2457 [(use (match_operand:V16QI 0 "register_operand" "")) | |
2458 (use (match_operand:V16QI 1 "memory_operand" ""))] | |
2459 "TARGET_ALTIVEC" | |
2460 { | |
2461 if (VECTOR_ELT_ORDER_BIG) | |
2462 emit_insn (gen_altivec_lvsl_direct (operands[0], operands[1])); | |
2463 else | |
2464 { | |
2465 int i; | |
2466 rtx mask, perm[16], constv, vperm; | |
2467 mask = gen_reg_rtx (V16QImode); | |
2468 emit_insn (gen_altivec_lvsl_direct (mask, operands[1])); | |
2469 for (i = 0; i < 16; ++i) | |
2470 perm[i] = GEN_INT (i); | |
2471 constv = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm)); | |
2472 constv = force_reg (V16QImode, constv); | |
2473 vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv), | |
2474 UNSPEC_VPERM); | |
2475 emit_insn (gen_rtx_SET (operands[0], vperm)); | |
2476 } | |
2477 DONE; | |
2478 }) | |
2479 | |
2480 (define_insn "altivec_lvsl_direct" | |
2481 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
2482 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")] | |
2483 UNSPEC_LVSL))] | |
2484 "TARGET_ALTIVEC" | |
2485 "lvsl %0,%y1" | |
2486 [(set_attr "type" "vecload")]) | |
2487 | |
2488 (define_expand "altivec_lvsr" | |
2489 [(use (match_operand:V16QI 0 "register_operand" "")) | |
2490 (use (match_operand:V16QI 1 "memory_operand" ""))] | |
2491 "TARGET_ALTIVEC" | |
2492 { | |
2493 if (VECTOR_ELT_ORDER_BIG) | |
2494 emit_insn (gen_altivec_lvsr_direct (operands[0], operands[1])); | |
2495 else | |
2496 { | |
2497 int i; | |
2498 rtx mask, perm[16], constv, vperm; | |
2499 mask = gen_reg_rtx (V16QImode); | |
2500 emit_insn (gen_altivec_lvsr_direct (mask, operands[1])); | |
2501 for (i = 0; i < 16; ++i) | |
2502 perm[i] = GEN_INT (i); | |
2503 constv = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm)); | |
2504 constv = force_reg (V16QImode, constv); | |
2505 vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv), | |
2506 UNSPEC_VPERM); | |
2507 emit_insn (gen_rtx_SET (operands[0], vperm)); | |
2508 } | |
2509 DONE; | |
2510 }) | |
2511 | |
2512 (define_insn "altivec_lvsr_direct" | |
2513 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
2514 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")] | |
2515 UNSPEC_LVSR))] | |
2516 "TARGET_ALTIVEC" | |
2517 "lvsr %0,%y1" | |
2518 [(set_attr "type" "vecload")]) | |
2519 | |
2520 (define_expand "build_vector_mask_for_load" | |
2521 [(set (match_operand:V16QI 0 "register_operand" "") | |
2522 (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))] | |
2523 "TARGET_ALTIVEC" | |
2524 " | |
2525 { | |
2526 rtx addr; | |
2527 rtx temp; | |
2528 | |
2529 gcc_assert (GET_CODE (operands[1]) == MEM); | |
2530 | |
2531 addr = XEXP (operands[1], 0); | |
2532 temp = gen_reg_rtx (GET_MODE (addr)); | |
2533 emit_insn (gen_rtx_SET (temp, gen_rtx_NEG (GET_MODE (addr), addr))); | |
2534 emit_insn (gen_altivec_lvsr (operands[0], | |
2535 replace_equiv_address (operands[1], temp))); | |
2536 DONE; | |
2537 }") | |
2538 | |
2539 ;; Parallel some of the LVE* and STV*'s with unspecs because some have | |
2540 ;; identical rtl but different instructions-- and gcc gets confused. | |
2541 | |
2542 (define_expand "altivec_lve<VI_char>x" | |
2543 [(parallel | |
2544 [(set (match_operand:VI 0 "register_operand" "=v") | |
2545 (match_operand:VI 1 "memory_operand" "Z")) | |
2546 (unspec [(const_int 0)] UNSPEC_LVE)])] | |
2547 "TARGET_ALTIVEC" | |
2548 { | |
2549 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
2550 { | |
2551 altivec_expand_lvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_LVE); | |
2552 DONE; | |
2553 } | |
2554 }) | |
2555 | |
2556 (define_insn "*altivec_lve<VI_char>x_internal" | |
2557 [(parallel | |
2558 [(set (match_operand:VI 0 "register_operand" "=v") | |
2559 (match_operand:VI 1 "memory_operand" "Z")) | |
2560 (unspec [(const_int 0)] UNSPEC_LVE)])] | |
2561 "TARGET_ALTIVEC" | |
2562 "lve<VI_char>x %0,%y1" | |
2563 [(set_attr "type" "vecload")]) | |
2564 | |
2565 (define_insn "*altivec_lvesfx" | |
2566 [(parallel | |
2567 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
2568 (match_operand:V4SF 1 "memory_operand" "Z")) | |
2569 (unspec [(const_int 0)] UNSPEC_LVE)])] | |
2570 "TARGET_ALTIVEC" | |
2571 "lvewx %0,%y1" | |
2572 [(set_attr "type" "vecload")]) | |
2573 | |
2574 (define_expand "altivec_lvxl_<mode>" | |
2575 [(parallel | |
2576 [(set (match_operand:VM2 0 "register_operand" "=v") | |
2577 (match_operand:VM2 1 "memory_operand" "Z")) | |
2578 (unspec [(const_int 0)] UNSPEC_SET_VSCR)])] | |
2579 "TARGET_ALTIVEC" | |
2580 { | |
2581 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
2582 { | |
2583 altivec_expand_lvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_SET_VSCR); | |
2584 DONE; | |
2585 } | |
2586 }) | |
2587 | |
2588 (define_insn "*altivec_lvxl_<mode>_internal" | |
2589 [(parallel | |
2590 [(set (match_operand:VM2 0 "register_operand" "=v") | |
2591 (match_operand:VM2 1 "memory_operand" "Z")) | |
2592 (unspec [(const_int 0)] UNSPEC_SET_VSCR)])] | |
2593 "TARGET_ALTIVEC" | |
2594 "lvxl %0,%y1" | |
2595 [(set_attr "type" "vecload")]) | |
2596 | |
2597 ; This version of lvx is used only in cases where we need to force an lvx | |
2598 ; over any other load, and we don't care about losing CSE opportunities. | |
2599 ; Its primary use is for prologue register saves. | |
2600 (define_insn "altivec_lvx_<mode>_internal" | |
2601 [(parallel | |
2602 [(set (match_operand:VM2 0 "register_operand" "=v") | |
2603 (match_operand:VM2 1 "memory_operand" "Z")) | |
2604 (unspec [(const_int 0)] UNSPEC_LVX)])] | |
2605 "TARGET_ALTIVEC" | |
2606 "lvx %0,%y1" | |
2607 [(set_attr "type" "vecload")]) | |
2608 | |
2609 ; The next two patterns embody what lvx should usually look like. | |
2610 (define_insn "altivec_lvx_<mode>_2op" | |
2611 [(set (match_operand:VM2 0 "register_operand" "=v") | |
2612 (mem:VM2 (and:DI (plus:DI (match_operand:DI 1 "register_operand" "b") | |
2613 (match_operand:DI 2 "register_operand" "r")) | |
2614 (const_int -16))))] | |
2615 "TARGET_ALTIVEC && TARGET_64BIT" | |
2616 "lvx %0,%1,%2" | |
2617 [(set_attr "type" "vecload")]) | |
2618 | |
2619 (define_insn "altivec_lvx_<mode>_1op" | |
2620 [(set (match_operand:VM2 0 "register_operand" "=v") | |
2621 (mem:VM2 (and:DI (match_operand:DI 1 "register_operand" "r") | |
2622 (const_int -16))))] | |
2623 "TARGET_ALTIVEC && TARGET_64BIT" | |
2624 "lvx %0,0,%1" | |
2625 [(set_attr "type" "vecload")]) | |
2626 | |
2627 ; 32-bit versions of the above. | |
2628 (define_insn "altivec_lvx_<mode>_2op_si" | |
2629 [(set (match_operand:VM2 0 "register_operand" "=v") | |
2630 (mem:VM2 (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b") | |
2631 (match_operand:SI 2 "register_operand" "r")) | |
2632 (const_int -16))))] | |
2633 "TARGET_ALTIVEC && TARGET_32BIT" | |
2634 "lvx %0,%1,%2" | |
2635 [(set_attr "type" "vecload")]) | |
2636 | |
2637 (define_insn "altivec_lvx_<mode>_1op_si" | |
2638 [(set (match_operand:VM2 0 "register_operand" "=v") | |
2639 (mem:VM2 (and:SI (match_operand:SI 1 "register_operand" "r") | |
2640 (const_int -16))))] | |
2641 "TARGET_ALTIVEC && TARGET_32BIT" | |
2642 "lvx %0,0,%1" | |
2643 [(set_attr "type" "vecload")]) | |
2644 | |
2645 ; This version of stvx is used only in cases where we need to force an stvx | |
2646 ; over any other store, and we don't care about losing CSE opportunities. | |
2647 ; Its primary use is for epilogue register restores. | |
2648 (define_insn "altivec_stvx_<mode>_internal" | |
2649 [(parallel | |
2650 [(set (match_operand:VM2 0 "memory_operand" "=Z") | |
2651 (match_operand:VM2 1 "register_operand" "v")) | |
2652 (unspec [(const_int 0)] UNSPEC_STVX)])] | |
2653 "TARGET_ALTIVEC" | |
2654 "stvx %1,%y0" | |
2655 [(set_attr "type" "vecstore")]) | |
2656 | |
2657 ; The next two patterns embody what stvx should usually look like. | |
2658 (define_insn "altivec_stvx_<mode>_2op" | |
2659 [(set (mem:VM2 (and:DI (plus:DI (match_operand:DI 1 "register_operand" "b") | |
2660 (match_operand:DI 2 "register_operand" "r")) | |
2661 (const_int -16))) | |
2662 (match_operand:VM2 0 "register_operand" "v"))] | |
2663 "TARGET_ALTIVEC && TARGET_64BIT" | |
2664 "stvx %0,%1,%2" | |
2665 [(set_attr "type" "vecstore")]) | |
2666 | |
2667 (define_insn "altivec_stvx_<mode>_1op" | |
2668 [(set (mem:VM2 (and:DI (match_operand:DI 1 "register_operand" "r") | |
2669 (const_int -16))) | |
2670 (match_operand:VM2 0 "register_operand" "v"))] | |
2671 "TARGET_ALTIVEC && TARGET_64BIT" | |
2672 "stvx %0,0,%1" | |
2673 [(set_attr "type" "vecstore")]) | |
2674 | |
2675 ; 32-bit versions of the above. | |
2676 (define_insn "altivec_stvx_<mode>_2op_si" | |
2677 [(set (mem:VM2 (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b") | |
2678 (match_operand:SI 2 "register_operand" "r")) | |
2679 (const_int -16))) | |
2680 (match_operand:VM2 0 "register_operand" "v"))] | |
2681 "TARGET_ALTIVEC && TARGET_32BIT" | |
2682 "stvx %0,%1,%2" | |
2683 [(set_attr "type" "vecstore")]) | |
2684 | |
2685 (define_insn "altivec_stvx_<mode>_1op_si" | |
2686 [(set (mem:VM2 (and:SI (match_operand:SI 1 "register_operand" "r") | |
2687 (const_int -16))) | |
2688 (match_operand:VM2 0 "register_operand" "v"))] | |
2689 "TARGET_ALTIVEC && TARGET_32BIT" | |
2690 "stvx %0,0,%1" | |
2691 [(set_attr "type" "vecstore")]) | |
2692 | |
2693 (define_expand "altivec_stvxl_<mode>" | |
2694 [(parallel | |
2695 [(set (match_operand:VM2 0 "memory_operand" "=Z") | |
2696 (match_operand:VM2 1 "register_operand" "v")) | |
2697 (unspec [(const_int 0)] UNSPEC_STVXL)])] | |
2698 "TARGET_ALTIVEC" | |
2699 { | |
2700 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
2701 { | |
2702 altivec_expand_stvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_STVXL); | |
2703 DONE; | |
2704 } | |
2705 }) | |
2706 | |
2707 (define_insn "*altivec_stvxl_<mode>_internal" | |
2708 [(parallel | |
2709 [(set (match_operand:VM2 0 "memory_operand" "=Z") | |
2710 (match_operand:VM2 1 "register_operand" "v")) | |
2711 (unspec [(const_int 0)] UNSPEC_STVXL)])] | |
2712 "TARGET_ALTIVEC" | |
2713 "stvxl %1,%y0" | |
2714 [(set_attr "type" "vecstore")]) | |
2715 | |
2716 (define_expand "altivec_stve<VI_char>x" | |
2717 [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z") | |
2718 (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))] | |
2719 "TARGET_ALTIVEC" | |
2720 { | |
2721 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) | |
2722 { | |
2723 altivec_expand_stvex_be (operands[0], operands[1], <MODE>mode, UNSPEC_STVE); | |
2724 DONE; | |
2725 } | |
2726 }) | |
2727 | |
2728 (define_insn "*altivec_stve<VI_char>x_internal" | |
2729 [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z") | |
2730 (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))] | |
2731 "TARGET_ALTIVEC" | |
2732 "stve<VI_char>x %1,%y0" | |
2733 [(set_attr "type" "vecstore")]) | |
2734 | |
2735 (define_insn "*altivec_stvesfx" | |
2736 [(set (match_operand:SF 0 "memory_operand" "=Z") | |
2737 (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))] | |
2738 "TARGET_ALTIVEC" | |
2739 "stvewx %1,%y0" | |
2740 [(set_attr "type" "vecstore")]) | |
2741 | |
2742 ;; Generate | |
2743 ;; xxlxor/vxor SCRATCH0,SCRATCH0,SCRATCH0 | |
2744 ;; vsubu?m SCRATCH2,SCRATCH1,%1 | |
2745 ;; vmaxs? %0,%1,SCRATCH2" | |
2746 (define_expand "abs<mode>2" | |
2747 [(set (match_dup 2) (match_dup 3)) | |
2748 (set (match_dup 4) | |
2749 (minus:VI2 (match_dup 2) | |
2750 (match_operand:VI2 1 "register_operand" "v"))) | |
2751 (set (match_operand:VI2 0 "register_operand" "=v") | |
2752 (smax:VI2 (match_dup 1) (match_dup 4)))] | |
2753 "<VI_unit>" | |
2754 { | |
2755 int i, n_elt = GET_MODE_NUNITS (<MODE>mode); | |
2756 rtvec v = rtvec_alloc (n_elt); | |
2757 | |
2758 /* Create an all 0 constant. */ | |
2759 for (i = 0; i < n_elt; ++i) | |
2760 RTVEC_ELT (v, i) = const0_rtx; | |
2761 | |
2762 operands[2] = gen_reg_rtx (<MODE>mode); | |
2763 operands[3] = gen_rtx_CONST_VECTOR (<MODE>mode, v); | |
2764 operands[4] = gen_reg_rtx (<MODE>mode); | |
2765 }) | |
2766 | |
2767 ;; Generate | |
2768 ;; vspltisw SCRATCH1,0 | |
2769 ;; vsubu?m SCRATCH2,SCRATCH1,%1 | |
2770 ;; vmins? %0,%1,SCRATCH2" | |
2771 (define_expand "nabs<mode>2" | |
2772 [(set (match_dup 2) (match_dup 3)) | |
2773 (set (match_dup 4) | |
2774 (minus:VI2 (match_dup 2) | |
2775 (match_operand:VI2 1 "register_operand" "v"))) | |
2776 (set (match_operand:VI2 0 "register_operand" "=v") | |
2777 (smin:VI2 (match_dup 1) (match_dup 4)))] | |
2778 "<VI_unit>" | |
2779 { | |
2780 int i; | |
2781 int n_elt = GET_MODE_NUNITS (<MODE>mode); | |
2782 | |
2783 rtvec v = rtvec_alloc (n_elt); | |
2784 | |
2785 /* Create an all 0 constant. */ | |
2786 for (i = 0; i < n_elt; ++i) | |
2787 RTVEC_ELT (v, i) = const0_rtx; | |
2788 | |
2789 operands[2] = gen_reg_rtx (<MODE>mode); | |
2790 operands[3] = gen_rtx_CONST_VECTOR (<MODE>mode, v); | |
2791 operands[4] = gen_reg_rtx (<MODE>mode); | |
2792 }) | |
2793 | |
2794 ;; Generate | |
2795 ;; vspltisw SCRATCH1,-1 | |
2796 ;; vslw SCRATCH2,SCRATCH1,SCRATCH1 | |
2797 ;; vandc %0,%1,SCRATCH2 | |
2798 (define_expand "altivec_absv4sf2" | |
2799 [(set (match_dup 2) | |
2800 (vec_duplicate:V4SI (const_int -1))) | |
2801 (set (match_dup 3) | |
2802 (ashift:V4SI (match_dup 2) (match_dup 2))) | |
2803 (set (match_operand:V4SF 0 "register_operand" "=v") | |
2804 (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0)) | |
2805 (match_operand:V4SF 1 "register_operand" "v")))] | |
2806 "TARGET_ALTIVEC" | |
2807 { | |
2808 operands[2] = gen_reg_rtx (V4SImode); | |
2809 operands[3] = gen_reg_rtx (V4SImode); | |
2810 }) | |
2811 | |
2812 ;; Generate | |
2813 ;; vspltis? SCRATCH0,0 | |
2814 ;; vsubs?s SCRATCH2,SCRATCH1,%1 | |
2815 ;; vmaxs? %0,%1,SCRATCH2" | |
2816 (define_expand "altivec_abss_<mode>" | |
2817 [(set (match_dup 2) (vec_duplicate:VI (const_int 0))) | |
2818 (parallel [(set (match_dup 3) | |
2819 (unspec:VI [(match_dup 2) | |
2820 (match_operand:VI 1 "register_operand" "v")] | |
2821 UNSPEC_VSUBS)) | |
2822 (set (reg:SI VSCR_REGNO) | |
2823 (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]) | |
2824 (set (match_operand:VI 0 "register_operand" "=v") | |
2825 (smax:VI (match_dup 1) (match_dup 3)))] | |
2826 "TARGET_ALTIVEC" | |
2827 { | |
2828 operands[2] = gen_reg_rtx (GET_MODE (operands[0])); | |
2829 operands[3] = gen_reg_rtx (GET_MODE (operands[0])); | |
2830 }) | |
2831 | |
2832 (define_expand "reduc_plus_scal_<mode>" | |
2833 [(set (match_operand:<VI_scalar> 0 "register_operand" "=v") | |
2834 (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")] | |
2835 UNSPEC_REDUC_PLUS))] | |
2836 "TARGET_ALTIVEC" | |
2837 { | |
2838 rtx vzero = gen_reg_rtx (V4SImode); | |
2839 rtx vtmp1 = gen_reg_rtx (V4SImode); | |
2840 rtx vtmp2 = gen_reg_rtx (<MODE>mode); | |
2841 rtx dest = gen_lowpart (V4SImode, vtmp2); | |
2842 int elt = VECTOR_ELT_ORDER_BIG ? GET_MODE_NUNITS (<MODE>mode) - 1 : 0; | |
2843 | |
2844 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); | |
2845 emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero)); | |
2846 emit_insn (gen_altivec_vsumsws_direct (dest, vtmp1, vzero)); | |
2847 rs6000_expand_vector_extract (operands[0], vtmp2, GEN_INT (elt)); | |
2848 DONE; | |
2849 }) | |
2850 | |
2851 (define_insn "*p9_neg<mode>2" | |
2852 [(set (match_operand:VNEG 0 "altivec_register_operand" "=v") | |
2853 (neg:VNEG (match_operand:VNEG 1 "altivec_register_operand" "v")))] | |
2854 "TARGET_P9_VECTOR" | |
2855 "vneg<VI_char> %0,%1" | |
2856 [(set_attr "type" "vecsimple")]) | |
2857 | |
2858 (define_expand "neg<mode>2" | |
2859 [(set (match_operand:VI2 0 "register_operand" "") | |
2860 (neg:VI2 (match_operand:VI2 1 "register_operand" "")))] | |
2861 "<VI_unit>" | |
2862 { | |
2863 if (!TARGET_P9_VECTOR || (<MODE>mode != V4SImode && <MODE>mode != V2DImode)) | |
2864 { | |
2865 rtx vzero; | |
2866 | |
2867 vzero = gen_reg_rtx (GET_MODE (operands[0])); | |
2868 emit_move_insn (vzero, CONST0_RTX (<MODE>mode)); | |
2869 emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1])); | |
2870 DONE; | |
2871 } | |
2872 }) | |
2873 | |
2874 (define_expand "udot_prod<mode>" | |
2875 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
2876 (plus:V4SI (match_operand:V4SI 3 "register_operand" "v") | |
2877 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") | |
2878 (match_operand:VIshort 2 "register_operand" "v")] | |
2879 UNSPEC_VMSUMU)))] | |
2880 "TARGET_ALTIVEC" | |
2881 " | |
2882 { | |
2883 emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3])); | |
2884 DONE; | |
2885 }") | |
2886 | |
2887 (define_expand "sdot_prodv8hi" | |
2888 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
2889 (plus:V4SI (match_operand:V4SI 3 "register_operand" "v") | |
2890 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") | |
2891 (match_operand:V8HI 2 "register_operand" "v")] | |
2892 UNSPEC_VMSUMSHM)))] | |
2893 "TARGET_ALTIVEC" | |
2894 " | |
2895 { | |
2896 emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3])); | |
2897 DONE; | |
2898 }") | |
2899 | |
2900 (define_expand "widen_usum<mode>3" | |
2901 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
2902 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") | |
2903 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")] | |
2904 UNSPEC_VMSUMU)))] | |
2905 "TARGET_ALTIVEC" | |
2906 " | |
2907 { | |
2908 rtx vones = gen_reg_rtx (GET_MODE (operands[1])); | |
2909 | |
2910 emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx)); | |
2911 emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2])); | |
2912 DONE; | |
2913 }") | |
2914 | |
2915 (define_expand "widen_ssumv16qi3" | |
2916 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
2917 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") | |
2918 (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")] | |
2919 UNSPEC_VMSUMM)))] | |
2920 "TARGET_ALTIVEC" | |
2921 " | |
2922 { | |
2923 rtx vones = gen_reg_rtx (V16QImode); | |
2924 | |
2925 emit_insn (gen_altivec_vspltisb (vones, const1_rtx)); | |
2926 emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2])); | |
2927 DONE; | |
2928 }") | |
2929 | |
2930 (define_expand "widen_ssumv8hi3" | |
2931 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
2932 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") | |
2933 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] | |
2934 UNSPEC_VMSUMSHM)))] | |
2935 "TARGET_ALTIVEC" | |
2936 " | |
2937 { | |
2938 rtx vones = gen_reg_rtx (V8HImode); | |
2939 | |
2940 emit_insn (gen_altivec_vspltish (vones, const1_rtx)); | |
2941 emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2])); | |
2942 DONE; | |
2943 }") | |
2944 | |
2945 (define_expand "vec_unpacks_hi_<VP_small_lc>" | |
2946 [(set (match_operand:VP 0 "register_operand" "=v") | |
2947 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] | |
2948 UNSPEC_VUNPACK_HI_SIGN_DIRECT))] | |
2949 "<VI_unit>" | |
2950 "") | |
2951 | |
2952 (define_expand "vec_unpacks_lo_<VP_small_lc>" | |
2953 [(set (match_operand:VP 0 "register_operand" "=v") | |
2954 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] | |
2955 UNSPEC_VUNPACK_LO_SIGN_DIRECT))] | |
2956 "<VI_unit>" | |
2957 "") | |
2958 | |
2959 (define_insn "vperm_v8hiv4si" | |
2960 [(set (match_operand:V4SI 0 "register_operand" "=v,?wo") | |
2961 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v,wo") | |
2962 (match_operand:V4SI 2 "register_operand" "v,0") | |
2963 (match_operand:V16QI 3 "register_operand" "v,wo")] | |
2964 UNSPEC_VPERMSI))] | |
2965 "TARGET_ALTIVEC" | |
2966 "@ | |
2967 vperm %0,%1,%2,%3 | |
2968 xxperm %x0,%x1,%x3" | |
2969 [(set_attr "type" "vecperm") | |
2970 (set_attr "length" "4")]) | |
2971 | |
2972 (define_insn "vperm_v16qiv8hi" | |
2973 [(set (match_operand:V8HI 0 "register_operand" "=v,?wo") | |
2974 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v,wo") | |
2975 (match_operand:V8HI 2 "register_operand" "v,0") | |
2976 (match_operand:V16QI 3 "register_operand" "v,wo")] | |
2977 UNSPEC_VPERMHI))] | |
2978 "TARGET_ALTIVEC" | |
2979 "@ | |
2980 vperm %0,%1,%2,%3 | |
2981 xxperm %x0,%x1,%x3" | |
2982 [(set_attr "type" "vecperm") | |
2983 (set_attr "length" "4")]) | |
2984 | |
2985 | |
2986 (define_expand "vec_unpacku_hi_v16qi" | |
2987 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
2988 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] | |
2989 UNSPEC_VUPKHUB))] | |
2990 "TARGET_ALTIVEC" | |
2991 " | |
2992 { | |
2993 rtx vzero = gen_reg_rtx (V8HImode); | |
2994 rtx mask = gen_reg_rtx (V16QImode); | |
2995 rtvec v = rtvec_alloc (16); | |
2996 bool be = BYTES_BIG_ENDIAN; | |
2997 | |
2998 emit_insn (gen_altivec_vspltish (vzero, const0_rtx)); | |
2999 | |
3000 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7); | |
3001 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 0 : 16); | |
3002 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 6); | |
3003 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16); | |
3004 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5); | |
3005 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 2 : 16); | |
3006 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 4); | |
3007 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16); | |
3008 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3); | |
3009 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 4 : 16); | |
3010 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 2); | |
3011 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16); | |
3012 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1); | |
3013 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 6 : 16); | |
3014 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 0); | |
3015 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16); | |
3016 | |
3017 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); | |
3018 emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask)); | |
3019 DONE; | |
3020 }") | |
3021 | |
3022 (define_expand "vec_unpacku_hi_v8hi" | |
3023 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
3024 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] | |
3025 UNSPEC_VUPKHUH))] | |
3026 "TARGET_ALTIVEC" | |
3027 " | |
3028 { | |
3029 rtx vzero = gen_reg_rtx (V4SImode); | |
3030 rtx mask = gen_reg_rtx (V16QImode); | |
3031 rtvec v = rtvec_alloc (16); | |
3032 bool be = BYTES_BIG_ENDIAN; | |
3033 | |
3034 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); | |
3035 | |
3036 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7); | |
3037 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 6); | |
3038 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 0 : 17); | |
3039 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16); | |
3040 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5); | |
3041 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 4); | |
3042 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 2 : 17); | |
3043 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16); | |
3044 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3); | |
3045 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 2); | |
3046 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 4 : 17); | |
3047 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16); | |
3048 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1); | |
3049 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 0); | |
3050 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 6 : 17); | |
3051 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16); | |
3052 | |
3053 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); | |
3054 emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask)); | |
3055 DONE; | |
3056 }") | |
3057 | |
3058 (define_expand "vec_unpacku_lo_v16qi" | |
3059 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
3060 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] | |
3061 UNSPEC_VUPKLUB))] | |
3062 "TARGET_ALTIVEC" | |
3063 " | |
3064 { | |
3065 rtx vzero = gen_reg_rtx (V8HImode); | |
3066 rtx mask = gen_reg_rtx (V16QImode); | |
3067 rtvec v = rtvec_alloc (16); | |
3068 bool be = BYTES_BIG_ENDIAN; | |
3069 | |
3070 emit_insn (gen_altivec_vspltish (vzero, const0_rtx)); | |
3071 | |
3072 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15); | |
3073 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 8 : 16); | |
3074 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 14); | |
3075 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16); | |
3076 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13); | |
3077 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 10 : 16); | |
3078 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 12); | |
3079 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16); | |
3080 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11); | |
3081 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 12 : 16); | |
3082 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 10); | |
3083 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16); | |
3084 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9); | |
3085 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 14 : 16); | |
3086 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 8); | |
3087 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16); | |
3088 | |
3089 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); | |
3090 emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask)); | |
3091 DONE; | |
3092 }") | |
3093 | |
3094 (define_expand "vec_unpacku_lo_v8hi" | |
3095 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
3096 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] | |
3097 UNSPEC_VUPKLUH))] | |
3098 "TARGET_ALTIVEC" | |
3099 " | |
3100 { | |
3101 rtx vzero = gen_reg_rtx (V4SImode); | |
3102 rtx mask = gen_reg_rtx (V16QImode); | |
3103 rtvec v = rtvec_alloc (16); | |
3104 bool be = BYTES_BIG_ENDIAN; | |
3105 | |
3106 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); | |
3107 | |
3108 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15); | |
3109 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 14); | |
3110 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 8 : 17); | |
3111 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16); | |
3112 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13); | |
3113 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 12); | |
3114 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 10 : 17); | |
3115 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16); | |
3116 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11); | |
3117 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 10); | |
3118 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 12 : 17); | |
3119 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16); | |
3120 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9); | |
3121 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 8); | |
3122 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 14 : 17); | |
3123 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16); | |
3124 | |
3125 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); | |
3126 emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask)); | |
3127 DONE; | |
3128 }") | |
3129 | |
3130 (define_expand "vec_widen_umult_hi_v16qi" | |
3131 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
3132 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") | |
3133 (match_operand:V16QI 2 "register_operand" "v")] | |
3134 UNSPEC_VMULWHUB))] | |
3135 "TARGET_ALTIVEC" | |
3136 " | |
3137 { | |
3138 rtx ve = gen_reg_rtx (V8HImode); | |
3139 rtx vo = gen_reg_rtx (V8HImode); | |
3140 | |
3141 if (BYTES_BIG_ENDIAN) | |
3142 { | |
3143 emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2])); | |
3144 emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2])); | |
3145 emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo)); | |
3146 } | |
3147 else | |
3148 { | |
3149 emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2])); | |
3150 emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2])); | |
3151 emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve)); | |
3152 } | |
3153 DONE; | |
3154 }") | |
3155 | |
3156 (define_expand "vec_widen_umult_lo_v16qi" | |
3157 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
3158 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") | |
3159 (match_operand:V16QI 2 "register_operand" "v")] | |
3160 UNSPEC_VMULWLUB))] | |
3161 "TARGET_ALTIVEC" | |
3162 " | |
3163 { | |
3164 rtx ve = gen_reg_rtx (V8HImode); | |
3165 rtx vo = gen_reg_rtx (V8HImode); | |
3166 | |
3167 if (BYTES_BIG_ENDIAN) | |
3168 { | |
3169 emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2])); | |
3170 emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2])); | |
3171 emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo)); | |
3172 } | |
3173 else | |
3174 { | |
3175 emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2])); | |
3176 emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2])); | |
3177 emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve)); | |
3178 } | |
3179 DONE; | |
3180 }") | |
3181 | |
3182 (define_expand "vec_widen_smult_hi_v16qi" | |
3183 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
3184 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") | |
3185 (match_operand:V16QI 2 "register_operand" "v")] | |
3186 UNSPEC_VMULWHSB))] | |
3187 "TARGET_ALTIVEC" | |
3188 " | |
3189 { | |
3190 rtx ve = gen_reg_rtx (V8HImode); | |
3191 rtx vo = gen_reg_rtx (V8HImode); | |
3192 | |
3193 if (BYTES_BIG_ENDIAN) | |
3194 { | |
3195 emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2])); | |
3196 emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2])); | |
3197 emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo)); | |
3198 } | |
3199 else | |
3200 { | |
3201 emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2])); | |
3202 emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2])); | |
3203 emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve)); | |
3204 } | |
3205 DONE; | |
3206 }") | |
3207 | |
3208 (define_expand "vec_widen_smult_lo_v16qi" | |
3209 [(set (match_operand:V8HI 0 "register_operand" "=v") | |
3210 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") | |
3211 (match_operand:V16QI 2 "register_operand" "v")] | |
3212 UNSPEC_VMULWLSB))] | |
3213 "TARGET_ALTIVEC" | |
3214 " | |
3215 { | |
3216 rtx ve = gen_reg_rtx (V8HImode); | |
3217 rtx vo = gen_reg_rtx (V8HImode); | |
3218 | |
3219 if (BYTES_BIG_ENDIAN) | |
3220 { | |
3221 emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2])); | |
3222 emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2])); | |
3223 emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo)); | |
3224 } | |
3225 else | |
3226 { | |
3227 emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2])); | |
3228 emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2])); | |
3229 emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve)); | |
3230 } | |
3231 DONE; | |
3232 }") | |
3233 | |
3234 (define_expand "vec_widen_umult_hi_v8hi" | |
3235 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
3236 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") | |
3237 (match_operand:V8HI 2 "register_operand" "v")] | |
3238 UNSPEC_VMULWHUH))] | |
3239 "TARGET_ALTIVEC" | |
3240 " | |
3241 { | |
3242 rtx ve = gen_reg_rtx (V4SImode); | |
3243 rtx vo = gen_reg_rtx (V4SImode); | |
3244 | |
3245 if (BYTES_BIG_ENDIAN) | |
3246 { | |
3247 emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2])); | |
3248 emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2])); | |
3249 emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo)); | |
3250 } | |
3251 else | |
3252 { | |
3253 emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2])); | |
3254 emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2])); | |
3255 emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve)); | |
3256 } | |
3257 DONE; | |
3258 }") | |
3259 | |
3260 (define_expand "vec_widen_umult_lo_v8hi" | |
3261 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
3262 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") | |
3263 (match_operand:V8HI 2 "register_operand" "v")] | |
3264 UNSPEC_VMULWLUH))] | |
3265 "TARGET_ALTIVEC" | |
3266 " | |
3267 { | |
3268 rtx ve = gen_reg_rtx (V4SImode); | |
3269 rtx vo = gen_reg_rtx (V4SImode); | |
3270 | |
3271 if (BYTES_BIG_ENDIAN) | |
3272 { | |
3273 emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2])); | |
3274 emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2])); | |
3275 emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo)); | |
3276 } | |
3277 else | |
3278 { | |
3279 emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2])); | |
3280 emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2])); | |
3281 emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve)); | |
3282 } | |
3283 DONE; | |
3284 }") | |
3285 | |
3286 (define_expand "vec_widen_smult_hi_v8hi" | |
3287 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
3288 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") | |
3289 (match_operand:V8HI 2 "register_operand" "v")] | |
3290 UNSPEC_VMULWHSH))] | |
3291 "TARGET_ALTIVEC" | |
3292 " | |
3293 { | |
3294 rtx ve = gen_reg_rtx (V4SImode); | |
3295 rtx vo = gen_reg_rtx (V4SImode); | |
3296 | |
3297 if (BYTES_BIG_ENDIAN) | |
3298 { | |
3299 emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2])); | |
3300 emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2])); | |
3301 emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo)); | |
3302 } | |
3303 else | |
3304 { | |
3305 emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2])); | |
3306 emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2])); | |
3307 emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve)); | |
3308 } | |
3309 DONE; | |
3310 }") | |
3311 | |
3312 (define_expand "vec_widen_smult_lo_v8hi" | |
3313 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
3314 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") | |
3315 (match_operand:V8HI 2 "register_operand" "v")] | |
3316 UNSPEC_VMULWLSH))] | |
3317 "TARGET_ALTIVEC" | |
3318 " | |
3319 { | |
3320 rtx ve = gen_reg_rtx (V4SImode); | |
3321 rtx vo = gen_reg_rtx (V4SImode); | |
3322 | |
3323 if (BYTES_BIG_ENDIAN) | |
3324 { | |
3325 emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2])); | |
3326 emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2])); | |
3327 emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo)); | |
3328 } | |
3329 else | |
3330 { | |
3331 emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2])); | |
3332 emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2])); | |
3333 emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve)); | |
3334 } | |
3335 DONE; | |
3336 }") | |
3337 | |
3338 (define_expand "vec_pack_trunc_<mode>" | |
3339 [(set (match_operand:<VP_small> 0 "register_operand" "=v") | |
3340 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v") | |
3341 (match_operand:VP 2 "register_operand" "v")] | |
3342 UNSPEC_VPACK_UNS_UNS_MOD))] | |
3343 "<VI_unit>" | |
3344 "") | |
3345 | |
3346 (define_expand "mulv16qi3" | |
3347 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
3348 (mult:V16QI (match_operand:V16QI 1 "register_operand" "v") | |
3349 (match_operand:V16QI 2 "register_operand" "v")))] | |
3350 "TARGET_ALTIVEC" | |
3351 " | |
3352 { | |
3353 rtx even = gen_reg_rtx (V8HImode); | |
3354 rtx odd = gen_reg_rtx (V8HImode); | |
3355 rtx mask = gen_reg_rtx (V16QImode); | |
3356 rtvec v = rtvec_alloc (16); | |
3357 int i; | |
3358 | |
3359 for (i = 0; i < 8; ++i) { | |
3360 RTVEC_ELT (v, 2 * i) | |
3361 = gen_rtx_CONST_INT (QImode, BYTES_BIG_ENDIAN ? 2 * i + 1 : 31 - 2 * i); | |
3362 RTVEC_ELT (v, 2 * i + 1) | |
3363 = gen_rtx_CONST_INT (QImode, BYTES_BIG_ENDIAN ? 2 * i + 17 : 15 - 2 * i); | |
3364 } | |
3365 | |
3366 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); | |
3367 emit_insn (gen_altivec_vmulesb (even, operands[1], operands[2])); | |
3368 emit_insn (gen_altivec_vmulosb (odd, operands[1], operands[2])); | |
3369 emit_insn (gen_altivec_vperm_v8hiv16qi (operands[0], even, odd, mask)); | |
3370 DONE; | |
3371 }") | |
3372 | |
3373 (define_expand "altivec_negv4sf2" | |
3374 [(use (match_operand:V4SF 0 "register_operand" "")) | |
3375 (use (match_operand:V4SF 1 "register_operand" ""))] | |
3376 "TARGET_ALTIVEC" | |
3377 " | |
3378 { | |
3379 rtx neg0; | |
3380 | |
3381 /* Generate [-0.0, -0.0, -0.0, -0.0]. */ | |
3382 neg0 = gen_reg_rtx (V4SImode); | |
3383 emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx)); | |
3384 emit_insn (gen_vashlv4si3 (neg0, neg0, neg0)); | |
3385 | |
3386 /* XOR */ | |
3387 emit_insn (gen_xorv4sf3 (operands[0], | |
3388 gen_lowpart (V4SFmode, neg0), operands[1])); | |
3389 | |
3390 DONE; | |
3391 }") | |
3392 | |
3393 ;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL, | |
3394 ;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell. | |
3395 (define_insn "altivec_lvlx" | |
3396 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
3397 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] | |
3398 UNSPEC_LVLX))] | |
3399 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" | |
3400 "lvlx %0,%y1" | |
3401 [(set_attr "type" "vecload")]) | |
3402 | |
3403 (define_insn "altivec_lvlxl" | |
3404 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
3405 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] | |
3406 UNSPEC_LVLXL))] | |
3407 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" | |
3408 "lvlxl %0,%y1" | |
3409 [(set_attr "type" "vecload")]) | |
3410 | |
3411 (define_insn "altivec_lvrx" | |
3412 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
3413 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] | |
3414 UNSPEC_LVRX))] | |
3415 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" | |
3416 "lvrx %0,%y1" | |
3417 [(set_attr "type" "vecload")]) | |
3418 | |
3419 (define_insn "altivec_lvrxl" | |
3420 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
3421 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] | |
3422 UNSPEC_LVRXL))] | |
3423 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" | |
3424 "lvrxl %0,%y1" | |
3425 [(set_attr "type" "vecload")]) | |
3426 | |
3427 (define_insn "altivec_stvlx" | |
3428 [(parallel | |
3429 [(set (match_operand:V16QI 0 "memory_operand" "=Z") | |
3430 (match_operand:V16QI 1 "register_operand" "v")) | |
3431 (unspec [(const_int 0)] UNSPEC_STVLX)])] | |
3432 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" | |
3433 "stvlx %1,%y0" | |
3434 [(set_attr "type" "vecstore")]) | |
3435 | |
3436 (define_insn "altivec_stvlxl" | |
3437 [(parallel | |
3438 [(set (match_operand:V16QI 0 "memory_operand" "=Z") | |
3439 (match_operand:V16QI 1 "register_operand" "v")) | |
3440 (unspec [(const_int 0)] UNSPEC_STVLXL)])] | |
3441 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" | |
3442 "stvlxl %1,%y0" | |
3443 [(set_attr "type" "vecstore")]) | |
3444 | |
3445 (define_insn "altivec_stvrx" | |
3446 [(parallel | |
3447 [(set (match_operand:V16QI 0 "memory_operand" "=Z") | |
3448 (match_operand:V16QI 1 "register_operand" "v")) | |
3449 (unspec [(const_int 0)] UNSPEC_STVRX)])] | |
3450 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" | |
3451 "stvrx %1,%y0" | |
3452 [(set_attr "type" "vecstore")]) | |
3453 | |
3454 (define_insn "altivec_stvrxl" | |
3455 [(parallel | |
3456 [(set (match_operand:V16QI 0 "memory_operand" "=Z") | |
3457 (match_operand:V16QI 1 "register_operand" "v")) | |
3458 (unspec [(const_int 0)] UNSPEC_STVRXL)])] | |
3459 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" | |
3460 "stvrxl %1,%y0" | |
3461 [(set_attr "type" "vecstore")]) | |
3462 | |
3463 (define_expand "vec_unpacks_float_hi_v8hi" | |
3464 [(set (match_operand:V4SF 0 "register_operand" "") | |
3465 (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")] | |
3466 UNSPEC_VUPKHS_V4SF))] | |
3467 "TARGET_ALTIVEC" | |
3468 " | |
3469 { | |
3470 rtx tmp = gen_reg_rtx (V4SImode); | |
3471 | |
3472 emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1])); | |
3473 emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx)); | |
3474 DONE; | |
3475 }") | |
3476 | |
3477 (define_expand "vec_unpacks_float_lo_v8hi" | |
3478 [(set (match_operand:V4SF 0 "register_operand" "") | |
3479 (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")] | |
3480 UNSPEC_VUPKLS_V4SF))] | |
3481 "TARGET_ALTIVEC" | |
3482 " | |
3483 { | |
3484 rtx tmp = gen_reg_rtx (V4SImode); | |
3485 | |
3486 emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1])); | |
3487 emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx)); | |
3488 DONE; | |
3489 }") | |
3490 | |
3491 (define_expand "vec_unpacku_float_hi_v8hi" | |
3492 [(set (match_operand:V4SF 0 "register_operand" "") | |
3493 (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")] | |
3494 UNSPEC_VUPKHU_V4SF))] | |
3495 "TARGET_ALTIVEC" | |
3496 " | |
3497 { | |
3498 rtx tmp = gen_reg_rtx (V4SImode); | |
3499 | |
3500 emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1])); | |
3501 emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx)); | |
3502 DONE; | |
3503 }") | |
3504 | |
3505 (define_expand "vec_unpacku_float_lo_v8hi" | |
3506 [(set (match_operand:V4SF 0 "register_operand" "") | |
3507 (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")] | |
3508 UNSPEC_VUPKLU_V4SF))] | |
3509 "TARGET_ALTIVEC" | |
3510 " | |
3511 { | |
3512 rtx tmp = gen_reg_rtx (V4SImode); | |
3513 | |
3514 emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1])); | |
3515 emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx)); | |
3516 DONE; | |
3517 }") | |
3518 | |
3519 | |
3520 ;; Power8/power9 vector instructions encoded as Altivec instructions | |
3521 | |
3522 ;; Vector count leading zeros | |
3523 (define_insn "*p8v_clz<mode>2" | |
3524 [(set (match_operand:VI2 0 "register_operand" "=v") | |
3525 (clz:VI2 (match_operand:VI2 1 "register_operand" "v")))] | |
3526 "TARGET_P8_VECTOR" | |
3527 "vclz<wd> %0,%1" | |
3528 [(set_attr "length" "4") | |
3529 (set_attr "type" "vecsimple")]) | |
3530 | |
3531 ;; Vector absolute difference unsigned | |
3532 (define_expand "vadu<mode>3" | |
3533 [(set (match_operand:VI 0 "register_operand") | |
3534 (unspec:VI [(match_operand:VI 1 "register_operand") | |
3535 (match_operand:VI 2 "register_operand")] | |
3536 UNSPEC_VADU))] | |
3537 "TARGET_P9_VECTOR") | |
3538 | |
3539 ;; Vector absolute difference unsigned | |
3540 (define_insn "*p9_vadu<mode>3" | |
3541 [(set (match_operand:VI 0 "register_operand" "=v") | |
3542 (unspec:VI [(match_operand:VI 1 "register_operand" "v") | |
3543 (match_operand:VI 2 "register_operand" "v")] | |
3544 UNSPEC_VADU))] | |
3545 "TARGET_P9_VECTOR" | |
3546 "vabsdu<wd> %0,%1,%2" | |
3547 [(set_attr "type" "vecsimple")]) | |
3548 | |
3549 ;; Vector count trailing zeros | |
3550 (define_insn "*p9v_ctz<mode>2" | |
3551 [(set (match_operand:VI2 0 "register_operand" "=v") | |
3552 (ctz:VI2 (match_operand:VI2 1 "register_operand" "v")))] | |
3553 "TARGET_P9_VECTOR" | |
3554 "vctz<wd> %0,%1" | |
3555 [(set_attr "length" "4") | |
3556 (set_attr "type" "vecsimple")]) | |
3557 | |
3558 ;; Vector population count | |
3559 (define_insn "*p8v_popcount<mode>2" | |
3560 [(set (match_operand:VI2 0 "register_operand" "=v") | |
3561 (popcount:VI2 (match_operand:VI2 1 "register_operand" "v")))] | |
3562 "TARGET_P8_VECTOR" | |
3563 "vpopcnt<wd> %0,%1" | |
3564 [(set_attr "length" "4") | |
3565 (set_attr "type" "vecsimple")]) | |
3566 | |
3567 ;; Vector parity | |
3568 (define_insn "*p9v_parity<mode>2" | |
3569 [(set (match_operand:VParity 0 "register_operand" "=v") | |
3570 (parity:VParity (match_operand:VParity 1 "register_operand" "v")))] | |
3571 "TARGET_P9_VECTOR" | |
3572 "vprtyb<wd> %0,%1" | |
3573 [(set_attr "length" "4") | |
3574 (set_attr "type" "vecsimple")]) | |
3575 | |
3576 ;; Vector Gather Bits by Bytes by Doubleword | |
3577 (define_insn "p8v_vgbbd" | |
3578 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
3579 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")] | |
3580 UNSPEC_VGBBD))] | |
3581 "TARGET_P8_VECTOR" | |
3582 "vgbbd %0,%1" | |
3583 [(set_attr "length" "4") | |
3584 (set_attr "type" "vecsimple")]) | |
3585 | |
3586 | |
3587 ;; 128-bit binary integer arithmetic | |
3588 ;; We have a special container type (V1TImode) to allow operations using the | |
3589 ;; ISA 2.07 128-bit binary support to target the VMX/altivec registers without | |
3590 ;; having to worry about the register allocator deciding GPRs are better. | |
3591 | |
3592 (define_insn "altivec_vadduqm" | |
3593 [(set (match_operand:V1TI 0 "register_operand" "=v") | |
3594 (plus:V1TI (match_operand:V1TI 1 "register_operand" "v") | |
3595 (match_operand:V1TI 2 "register_operand" "v")))] | |
3596 "TARGET_VADDUQM" | |
3597 "vadduqm %0,%1,%2" | |
3598 [(set_attr "length" "4") | |
3599 (set_attr "type" "vecsimple")]) | |
3600 | |
3601 (define_insn "altivec_vaddcuq" | |
3602 [(set (match_operand:V1TI 0 "register_operand" "=v") | |
3603 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") | |
3604 (match_operand:V1TI 2 "register_operand" "v")] | |
3605 UNSPEC_VADDCUQ))] | |
3606 "TARGET_VADDUQM" | |
3607 "vaddcuq %0,%1,%2" | |
3608 [(set_attr "length" "4") | |
3609 (set_attr "type" "vecsimple")]) | |
3610 | |
3611 (define_insn "altivec_vsubuqm" | |
3612 [(set (match_operand:V1TI 0 "register_operand" "=v") | |
3613 (minus:V1TI (match_operand:V1TI 1 "register_operand" "v") | |
3614 (match_operand:V1TI 2 "register_operand" "v")))] | |
3615 "TARGET_VADDUQM" | |
3616 "vsubuqm %0,%1,%2" | |
3617 [(set_attr "length" "4") | |
3618 (set_attr "type" "vecsimple")]) | |
3619 | |
3620 (define_insn "altivec_vsubcuq" | |
3621 [(set (match_operand:V1TI 0 "register_operand" "=v") | |
3622 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") | |
3623 (match_operand:V1TI 2 "register_operand" "v")] | |
3624 UNSPEC_VSUBCUQ))] | |
3625 "TARGET_VADDUQM" | |
3626 "vsubcuq %0,%1,%2" | |
3627 [(set_attr "length" "4") | |
3628 (set_attr "type" "vecsimple")]) | |
3629 | |
3630 (define_insn "altivec_vaddeuqm" | |
3631 [(set (match_operand:V1TI 0 "register_operand" "=v") | |
3632 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") | |
3633 (match_operand:V1TI 2 "register_operand" "v") | |
3634 (match_operand:V1TI 3 "register_operand" "v")] | |
3635 UNSPEC_VADDEUQM))] | |
3636 "TARGET_VADDUQM" | |
3637 "vaddeuqm %0,%1,%2,%3" | |
3638 [(set_attr "length" "4") | |
3639 (set_attr "type" "vecsimple")]) | |
3640 | |
3641 (define_insn "altivec_vaddecuq" | |
3642 [(set (match_operand:V1TI 0 "register_operand" "=v") | |
3643 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") | |
3644 (match_operand:V1TI 2 "register_operand" "v") | |
3645 (match_operand:V1TI 3 "register_operand" "v")] | |
3646 UNSPEC_VADDECUQ))] | |
3647 "TARGET_VADDUQM" | |
3648 "vaddecuq %0,%1,%2,%3" | |
3649 [(set_attr "length" "4") | |
3650 (set_attr "type" "vecsimple")]) | |
3651 | |
3652 (define_insn "altivec_vsubeuqm" | |
3653 [(set (match_operand:V1TI 0 "register_operand" "=v") | |
3654 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") | |
3655 (match_operand:V1TI 2 "register_operand" "v") | |
3656 (match_operand:V1TI 3 "register_operand" "v")] | |
3657 UNSPEC_VSUBEUQM))] | |
3658 "TARGET_VADDUQM" | |
3659 "vsubeuqm %0,%1,%2,%3" | |
3660 [(set_attr "length" "4") | |
3661 (set_attr "type" "vecsimple")]) | |
3662 | |
3663 (define_insn "altivec_vsubecuq" | |
3664 [(set (match_operand:V1TI 0 "register_operand" "=v") | |
3665 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") | |
3666 (match_operand:V1TI 2 "register_operand" "v") | |
3667 (match_operand:V1TI 3 "register_operand" "v")] | |
3668 UNSPEC_VSUBECUQ))] | |
3669 "TARGET_VADDUQM" | |
3670 "vsubecuq %0,%1,%2,%3" | |
3671 [(set_attr "length" "4") | |
3672 (set_attr "type" "vecsimple")]) | |
3673 | |
3674 ;; We use V2DI as the output type to simplify converting the permute | |
3675 ;; bits into an integer | |
3676 (define_insn "altivec_vbpermq" | |
3677 [(set (match_operand:V2DI 0 "register_operand" "=v") | |
3678 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "v") | |
3679 (match_operand:V16QI 2 "register_operand" "v")] | |
3680 UNSPEC_VBPERMQ))] | |
3681 "TARGET_P8_VECTOR" | |
3682 "vbpermq %0,%1,%2" | |
3683 [(set_attr "type" "vecperm")]) | |
3684 | |
3685 ; One of the vector API interfaces requires returning vector unsigned char. | |
3686 (define_insn "altivec_vbpermq2" | |
3687 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
3688 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") | |
3689 (match_operand:V16QI 2 "register_operand" "v")] | |
3690 UNSPEC_VBPERMQ))] | |
3691 "TARGET_P8_VECTOR" | |
3692 "vbpermq %0,%1,%2" | |
3693 [(set_attr "type" "vecperm")]) | |
3694 | |
3695 (define_insn "altivec_vbpermd" | |
3696 [(set (match_operand:V2DI 0 "register_operand" "=v") | |
3697 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "v") | |
3698 (match_operand:V16QI 2 "register_operand" "v")] | |
3699 UNSPEC_VBPERMD))] | |
3700 "TARGET_P9_VECTOR" | |
3701 "vbpermd %0,%1,%2" | |
3702 [(set_attr "type" "vecsimple")]) | |
3703 | |
3704 ;; Decimal Integer operations | |
3705 (define_int_iterator UNSPEC_BCD_ADD_SUB [UNSPEC_BCDADD UNSPEC_BCDSUB]) | |
3706 | |
3707 (define_int_attr bcd_add_sub [(UNSPEC_BCDADD "add") | |
3708 (UNSPEC_BCDSUB "sub")]) | |
3709 | |
3710 (define_code_iterator BCD_TEST [eq lt gt unordered]) | |
3711 | |
3712 (define_insn "bcd<bcd_add_sub>" | |
3713 [(set (match_operand:V1TI 0 "gpc_reg_operand" "=v") | |
3714 (unspec:V1TI [(match_operand:V1TI 1 "gpc_reg_operand" "v") | |
3715 (match_operand:V1TI 2 "gpc_reg_operand" "v") | |
3716 (match_operand:QI 3 "const_0_to_1_operand" "n")] | |
3717 UNSPEC_BCD_ADD_SUB)) | |
3718 (clobber (reg:CCFP CR6_REGNO))] | |
3719 "TARGET_P8_VECTOR" | |
3720 "bcd<bcd_add_sub>. %0,%1,%2,%3" | |
3721 [(set_attr "length" "4") | |
3722 (set_attr "type" "vecsimple")]) | |
3723 | |
3724 ;; Use a floating point type (V2DFmode) for the compare to set CR6 so that we | |
3725 ;; can use the unordered test for BCD nans and add/subtracts that overflow. An | |
3726 ;; UNORDERED test on an integer type (like V1TImode) is not defined. The type | |
3727 ;; probably should be one that can go in the VMX (Altivec) registers, so we | |
3728 ;; can't use DDmode or DFmode. | |
3729 (define_insn "*bcd<bcd_add_sub>_test" | |
3730 [(set (reg:CCFP CR6_REGNO) | |
3731 (compare:CCFP | |
3732 (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "v") | |
3733 (match_operand:V1TI 2 "register_operand" "v") | |
3734 (match_operand:QI 3 "const_0_to_1_operand" "i")] | |
3735 UNSPEC_BCD_ADD_SUB) | |
3736 (match_operand:V2DF 4 "zero_constant" "j"))) | |
3737 (clobber (match_scratch:V1TI 0 "=v"))] | |
3738 "TARGET_P8_VECTOR" | |
3739 "bcd<bcd_add_sub>. %0,%1,%2,%3" | |
3740 [(set_attr "length" "4") | |
3741 (set_attr "type" "vecsimple")]) | |
3742 | |
3743 (define_insn "*bcd<bcd_add_sub>_test2" | |
3744 [(set (match_operand:V1TI 0 "register_operand" "=v") | |
3745 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") | |
3746 (match_operand:V1TI 2 "register_operand" "v") | |
3747 (match_operand:QI 3 "const_0_to_1_operand" "i")] | |
3748 UNSPEC_BCD_ADD_SUB)) | |
3749 (set (reg:CCFP CR6_REGNO) | |
3750 (compare:CCFP | |
3751 (unspec:V2DF [(match_dup 1) | |
3752 (match_dup 2) | |
3753 (match_dup 3)] | |
3754 UNSPEC_BCD_ADD_SUB) | |
3755 (match_operand:V2DF 4 "zero_constant" "j")))] | |
3756 "TARGET_P8_VECTOR" | |
3757 "bcd<bcd_add_sub>. %0,%1,%2,%3" | |
3758 [(set_attr "length" "4") | |
3759 (set_attr "type" "vecsimple")]) | |
3760 | |
3761 (define_insn "darn_32" | |
3762 [(set (match_operand:SI 0 "register_operand" "=r") | |
3763 (unspec:SI [(const_int 0)] UNSPEC_DARN_32))] | |
3764 "TARGET_P9_MISC" | |
3765 "darn %0,0" | |
3766 [(set_attr "type" "integer")]) | |
3767 | |
3768 (define_insn "darn_raw" | |
3769 [(set (match_operand:DI 0 "register_operand" "=r") | |
3770 (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))] | |
3771 "TARGET_P9_MISC && TARGET_64BIT" | |
3772 "darn %0,2" | |
3773 [(set_attr "type" "integer")]) | |
3774 | |
3775 (define_insn "darn" | |
3776 [(set (match_operand:DI 0 "register_operand" "=r") | |
3777 (unspec:DI [(const_int 0)] UNSPEC_DARN))] | |
3778 "TARGET_P9_MISC && TARGET_64BIT" | |
3779 "darn %0,1" | |
3780 [(set_attr "type" "integer")]) | |
3781 | |
3782 ;; Test byte within range. | |
3783 ;; | |
3784 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx | |
3785 ;; represents a byte whose value is ignored in this context and | |
3786 ;; vv, the least significant byte, holds the byte value that is to | |
3787 ;; be tested for membership within the range specified by operand 2. | |
3788 ;; The bytes of operand 2 are organized as xx:xx:hi:lo. | |
3789 ;; | |
3790 ;; Return in target register operand 0 a value of 1 if lo <= vv and | |
3791 ;; vv <= hi. Otherwise, set register operand 0 to 0. | |
3792 ;; | |
3793 ;; Though the instructions to which this expansion maps operate on | |
3794 ;; 64-bit registers, the current implementation only operates on | |
3795 ;; SI-mode operands as the high-order bits provide no information | |
3796 ;; that is not already available in the low-order bits. To avoid the | |
3797 ;; costs of data widening operations, future enhancements might allow | |
3798 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. | |
3799 (define_expand "cmprb" | |
3800 [(set (match_dup 3) | |
3801 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") | |
3802 (match_operand:SI 2 "gpc_reg_operand" "r")] | |
3803 UNSPEC_CMPRB)) | |
3804 (set (match_operand:SI 0 "gpc_reg_operand" "=r") | |
3805 (if_then_else:SI (lt (match_dup 3) | |
3806 (const_int 0)) | |
3807 (const_int -1) | |
3808 (if_then_else (gt (match_dup 3) | |
3809 (const_int 0)) | |
3810 (const_int 1) | |
3811 (const_int 0))))] | |
3812 "TARGET_P9_MISC" | |
3813 { | |
3814 operands[3] = gen_reg_rtx (CCmode); | |
3815 }) | |
3816 | |
3817 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx | |
3818 ;; represents a byte whose value is ignored in this context and | |
3819 ;; vv, the least significant byte, holds the byte value that is to | |
3820 ;; be tested for membership within the range specified by operand 2. | |
3821 ;; The bytes of operand 2 are organized as xx:xx:hi:lo. | |
3822 ;; | |
3823 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if | |
3824 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other | |
3825 ;; 3 bits of the target CR register are all set to 0. | |
3826 (define_insn "*cmprb_internal" | |
3827 [(set (match_operand:CC 0 "cc_reg_operand" "=y") | |
3828 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") | |
3829 (match_operand:SI 2 "gpc_reg_operand" "r")] | |
3830 UNSPEC_CMPRB))] | |
3831 "TARGET_P9_MISC" | |
3832 "cmprb %0,0,%1,%2" | |
3833 [(set_attr "type" "logical")]) | |
3834 | |
3835 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition | |
3836 ;; register operand 1 is on. Otherwise, set operand 0 register to 1 | |
3837 ;; if the GT bit (0x4) of condition register operand 1 is on. | |
3838 ;; Otherwise, set operand 0 to 0. Note that the result stored into | |
3839 ;; register operand 0 is non-zero iff either the LT or GT bits are on | |
3840 ;; within condition register operand 1. | |
3841 (define_insn "setb_signed" | |
3842 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") | |
3843 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y") | |
3844 (const_int 0)) | |
3845 (const_int -1) | |
3846 (if_then_else (gt (match_dup 1) | |
3847 (const_int 0)) | |
3848 (const_int 1) | |
3849 (const_int 0))))] | |
3850 "TARGET_P9_MISC" | |
3851 "setb %0,%1" | |
3852 [(set_attr "type" "logical")]) | |
3853 | |
3854 (define_insn "setb_unsigned" | |
3855 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") | |
3856 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y") | |
3857 (const_int 0)) | |
3858 (const_int -1) | |
3859 (if_then_else (gtu (match_dup 1) | |
3860 (const_int 0)) | |
3861 (const_int 1) | |
3862 (const_int 0))))] | |
3863 "TARGET_P9_MISC" | |
3864 "setb %0,%1" | |
3865 [(set_attr "type" "logical")]) | |
3866 | |
3867 ;; Test byte within two ranges. | |
3868 ;; | |
3869 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx | |
3870 ;; represents a byte whose value is ignored in this context and | |
3871 ;; vv, the least significant byte, holds the byte value that is to | |
3872 ;; be tested for membership within the range specified by operand 2. | |
3873 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. | |
3874 ;; | |
3875 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and | |
3876 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register | |
3877 ;; operand 0 to 0. | |
3878 ;; | |
3879 ;; Though the instructions to which this expansion maps operate on | |
3880 ;; 64-bit registers, the current implementation only operates on | |
3881 ;; SI-mode operands as the high-order bits provide no information | |
3882 ;; that is not already available in the low-order bits. To avoid the | |
3883 ;; costs of data widening operations, future enhancements might allow | |
3884 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. | |
3885 (define_expand "cmprb2" | |
3886 [(set (match_dup 3) | |
3887 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") | |
3888 (match_operand:SI 2 "gpc_reg_operand" "r")] | |
3889 UNSPEC_CMPRB2)) | |
3890 (set (match_operand:SI 0 "gpc_reg_operand" "=r") | |
3891 (if_then_else:SI (lt (match_dup 3) | |
3892 (const_int 0)) | |
3893 (const_int -1) | |
3894 (if_then_else (gt (match_dup 3) | |
3895 (const_int 0)) | |
3896 (const_int 1) | |
3897 (const_int 0))))] | |
3898 "TARGET_P9_MISC" | |
3899 { | |
3900 operands[3] = gen_reg_rtx (CCmode); | |
3901 }) | |
3902 | |
3903 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx | |
3904 ;; represents a byte whose value is ignored in this context and | |
3905 ;; vv, the least significant byte, holds the byte value that is to | |
3906 ;; be tested for membership within the ranges specified by operand 2. | |
3907 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. | |
3908 ;; | |
3909 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if | |
3910 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). | |
3911 ;; Otherwise, set the GT bit to 0. The other 3 bits of the target | |
3912 ;; CR register are all set to 0. | |
3913 (define_insn "*cmprb2_internal" | |
3914 [(set (match_operand:CC 0 "cc_reg_operand" "=y") | |
3915 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") | |
3916 (match_operand:SI 2 "gpc_reg_operand" "r")] | |
3917 UNSPEC_CMPRB2))] | |
3918 "TARGET_P9_MISC" | |
3919 "cmprb %0,1,%1,%2" | |
3920 [(set_attr "type" "logical")]) | |
3921 | |
3922 ;; Test byte membership within set of 8 bytes. | |
3923 ;; | |
3924 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx | |
3925 ;; represents a byte whose value is ignored in this context and | |
3926 ;; vv, the least significant byte, holds the byte value that is to | |
3927 ;; be tested for membership within the set specified by operand 2. | |
3928 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. | |
3929 ;; | |
3930 ;; Return in target register operand 0 a value of 1 if vv equals one | |
3931 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set | |
3932 ;; register operand 0 to 0. Note that the 8 byte values held within | |
3933 ;; operand 2 need not be unique. | |
3934 ;; | |
3935 ;; Though the instructions to which this expansion maps operate on | |
3936 ;; 64-bit registers, the current implementation requires that operands | |
3937 ;; 0 and 1 have mode SI as the high-order bits provide no information | |
3938 ;; that is not already available in the low-order bits. To avoid the | |
3939 ;; costs of data widening operations, future enhancements might allow | |
3940 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. | |
3941 (define_expand "cmpeqb" | |
3942 [(set (match_dup 3) | |
3943 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") | |
3944 (match_operand:DI 2 "gpc_reg_operand" "r")] | |
3945 UNSPEC_CMPEQB)) | |
3946 (set (match_operand:SI 0 "gpc_reg_operand" "=r") | |
3947 (if_then_else:SI (lt (match_dup 3) | |
3948 (const_int 0)) | |
3949 (const_int -1) | |
3950 (if_then_else (gt (match_dup 3) | |
3951 (const_int 0)) | |
3952 (const_int 1) | |
3953 (const_int 0))))] | |
3954 "TARGET_P9_MISC && TARGET_64BIT" | |
3955 { | |
3956 operands[3] = gen_reg_rtx (CCmode); | |
3957 }) | |
3958 | |
3959 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx | |
3960 ;; represents a byte whose value is ignored in this context and | |
3961 ;; vv, the least significant byte, holds the byte value that is to | |
3962 ;; be tested for membership within the set specified by operand 2. | |
3963 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. | |
3964 ;; | |
3965 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv | |
3966 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, | |
3967 ;; set the GT bit to zero. The other 3 bits of the target CR register | |
3968 ;; are all set to 0. | |
3969 (define_insn "*cmpeqb_internal" | |
3970 [(set (match_operand:CC 0 "cc_reg_operand" "=y") | |
3971 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") | |
3972 (match_operand:DI 2 "gpc_reg_operand" "r")] | |
3973 UNSPEC_CMPEQB))] | |
3974 "TARGET_P9_MISC && TARGET_64BIT" | |
3975 "cmpeqb %0,%1,%2" | |
3976 [(set_attr "type" "logical")]) | |
3977 | |
3978 (define_expand "bcd<bcd_add_sub>_<code>" | |
3979 [(parallel [(set (reg:CCFP CR6_REGNO) | |
3980 (compare:CCFP | |
3981 (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "") | |
3982 (match_operand:V1TI 2 "register_operand" "") | |
3983 (match_operand:QI 3 "const_0_to_1_operand" "")] | |
3984 UNSPEC_BCD_ADD_SUB) | |
3985 (match_dup 4))) | |
3986 (clobber (match_scratch:V1TI 5 ""))]) | |
3987 (set (match_operand:SI 0 "register_operand" "") | |
3988 (BCD_TEST:SI (reg:CCFP CR6_REGNO) | |
3989 (const_int 0)))] | |
3990 "TARGET_P8_VECTOR" | |
3991 { | |
3992 operands[4] = CONST0_RTX (V2DFmode); | |
3993 }) | |
3994 | |
3995 ;; Peephole2 pattern to combine a bcdadd/bcdsub that calculates the value and | |
3996 ;; the bcdadd/bcdsub that tests the value. The combiner won't work since | |
3997 ;; CR6 is a hard coded register. Unfortunately, all of the Altivec predicate | |
3998 ;; support is hard coded to use the fixed register CR6 instead of creating | |
3999 ;; a register class for CR6. | |
4000 | |
4001 (define_peephole2 | |
4002 [(parallel [(set (match_operand:V1TI 0 "register_operand" "") | |
4003 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "") | |
4004 (match_operand:V1TI 2 "register_operand" "") | |
4005 (match_operand:QI 3 "const_0_to_1_operand" "")] | |
4006 UNSPEC_BCD_ADD_SUB)) | |
4007 (clobber (reg:CCFP CR6_REGNO))]) | |
4008 (parallel [(set (reg:CCFP CR6_REGNO) | |
4009 (compare:CCFP | |
4010 (unspec:V2DF [(match_dup 1) | |
4011 (match_dup 2) | |
4012 (match_dup 3)] | |
4013 UNSPEC_BCD_ADD_SUB) | |
4014 (match_operand:V2DF 4 "zero_constant" ""))) | |
4015 (clobber (match_operand:V1TI 5 "register_operand" ""))])] | |
4016 "TARGET_P8_VECTOR" | |
4017 [(parallel [(set (match_dup 0) | |
4018 (unspec:V1TI [(match_dup 1) | |
4019 (match_dup 2) | |
4020 (match_dup 3)] | |
4021 UNSPEC_BCD_ADD_SUB)) | |
4022 (set (reg:CCFP CR6_REGNO) | |
4023 (compare:CCFP | |
4024 (unspec:V2DF [(match_dup 1) | |
4025 (match_dup 2) | |
4026 (match_dup 3)] | |
4027 UNSPEC_BCD_ADD_SUB) | |
4028 (match_dup 4)))])]) |