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