OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [rs6000/] [vector.md] - Blame information for rev 717

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
;; Expander definitions for vector support between altivec & vsx.  No
2
;; instructions are in this file, this file provides the generic vector
3
;; expander, and the actual vector instructions will be in altivec.md and
4
;; vsx.md
5
 
6
;; Copyright (C) 2009, 2010, 2011
7
;; Free Software Foundation, Inc.
8
;; Contributed by Michael Meissner 
9
 
10
;; This file is part of GCC.
11
 
12
;; GCC is free software; you can redistribute it and/or modify it
13
;; under the terms of the GNU General Public License as published
14
;; by the Free Software Foundation; either version 3, or (at your
15
;; option) any later version.
16
 
17
;; GCC is distributed in the hope that it will be useful, but WITHOUT
18
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19
;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
20
;; License for more details.
21
 
22
;; You should have received a copy of the GNU General Public License
23
;; along with GCC; see the file COPYING3.  If not see
24
;; .
25
 
26
 
27
;; Vector int modes
28
(define_mode_iterator VEC_I [V16QI V8HI V4SI])
29
 
30
;; Vector float modes
31
(define_mode_iterator VEC_F [V4SF V2DF])
32
 
33
;; Vector arithmetic modes
34
(define_mode_iterator VEC_A [V16QI V8HI V4SI V4SF V2DF])
35
 
36
;; Vector modes that need alginment via permutes
37
(define_mode_iterator VEC_K [V16QI V8HI V4SI V4SF])
38
 
39
;; Vector logical modes
40
(define_mode_iterator VEC_L [V16QI V8HI V4SI V2DI V4SF V2DF TI])
41
 
42
;; Vector modes for moves.  Don't do TImode here.
43
(define_mode_iterator VEC_M [V16QI V8HI V4SI V2DI V4SF V2DF])
44
 
45
;; Vector modes for types that don't need a realignment under VSX
46
(define_mode_iterator VEC_N [V4SI V4SF V2DI V2DF])
47
 
48
;; Vector comparison modes
49
(define_mode_iterator VEC_C [V16QI V8HI V4SI V4SF V2DF])
50
 
51
;; Vector init/extract modes
52
(define_mode_iterator VEC_E [V16QI V8HI V4SI V2DI V4SF V2DF])
53
 
54
;; Vector modes for 64-bit base types
55
(define_mode_iterator VEC_64 [V2DI V2DF])
56
 
57
;; Vector reload iterator
58
(define_mode_iterator VEC_R [V16QI V8HI V4SI V2DI V4SF V2DF DF TI])
59
 
60
;; Base type from vector mode
61
(define_mode_attr VEC_base [(V16QI "QI")
62
                            (V8HI  "HI")
63
                            (V4SI  "SI")
64
                            (V2DI  "DI")
65
                            (V4SF  "SF")
66
                            (V2DF  "DF")
67
                            (TI    "TI")])
68
 
69
;; Same size integer type for floating point data
70
(define_mode_attr VEC_int [(V4SF  "v4si")
71
                           (V2DF  "v2di")])
72
 
73
(define_mode_attr VEC_INT [(V4SF  "V4SI")
74
                           (V2DF  "V2DI")])
75
 
76
;; constants for unspec
77
(define_c_enum "unspec" [UNSPEC_PREDICATE
78
                         UNSPEC_REDUC])
79
 
80
;; Vector reduction code iterators
81
(define_code_iterator VEC_reduc [plus smin smax])
82
 
83
(define_code_attr VEC_reduc_name [(plus "splus")
84
                                  (smin "smin")
85
                                  (smax "smax")])
86
 
87
(define_code_attr VEC_reduc_rtx [(plus "add")
88
                                 (smin "smin")
89
                                 (smax "smax")])
90
 
91
 
92
;; Vector move instructions.
93
(define_expand "mov"
94
  [(set (match_operand:VEC_M 0 "nonimmediate_operand" "")
95
        (match_operand:VEC_M 1 "any_operand" ""))]
96
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
97
{
98
  if (can_create_pseudo_p ())
99
    {
100
      if (CONSTANT_P (operands[1])
101
          && !easy_vector_constant (operands[1], mode))
102
        operands[1] = force_const_mem (mode, operands[1]);
103
 
104
      else if (!vlogical_operand (operands[0], mode)
105
               && !vlogical_operand (operands[1], mode))
106
        operands[1] = force_reg (mode, operands[1]);
107
    }
108
})
109
 
110
;; Generic vector floating point load/store instructions.  These will match
111
;; insns defined in vsx.md or altivec.md depending on the switches.
112
(define_expand "vector_load_"
113
  [(set (match_operand:VEC_M 0 "vfloat_operand" "")
114
        (match_operand:VEC_M 1 "memory_operand" ""))]
115
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
116
  "")
117
 
118
(define_expand "vector_store_"
119
  [(set (match_operand:VEC_M 0 "memory_operand" "")
120
        (match_operand:VEC_M 1 "vfloat_operand" ""))]
121
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
122
  "")
123
 
124
;; Splits if a GPR register was chosen for the move
125
(define_split
126
  [(set (match_operand:VEC_L 0 "nonimmediate_operand" "")
127
        (match_operand:VEC_L 1 "input_operand" ""))]
128
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
129
   && reload_completed
130
   && gpr_or_gpr_p (operands[0], operands[1])"
131
  [(pc)]
132
{
133
  rs6000_split_multireg_move (operands[0], operands[1]);
134
  DONE;
135
})
136
 
137
;; Vector floating point load/store instructions that uses the Altivec
138
;; instructions even if we are compiling for VSX, since the Altivec
139
;; instructions silently ignore the bottom 3 bits of the address, and VSX does
140
;; not.
141
(define_expand "vector_altivec_load_"
142
  [(set (match_operand:VEC_M 0 "vfloat_operand" "")
143
        (match_operand:VEC_M 1 "memory_operand" ""))]
144
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
145
  "
146
{
147
  gcc_assert (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode));
148
 
149
  if (VECTOR_MEM_VSX_P (mode))
150
    {
151
      operands[1] = rs6000_address_for_altivec (operands[1]);
152
      emit_insn (gen_altivec_lvx_ (operands[0], operands[1]));
153
      DONE;
154
    }
155
}")
156
 
157
(define_expand "vector_altivec_store_"
158
  [(set (match_operand:VEC_M 0 "memory_operand" "")
159
        (match_operand:VEC_M 1 "vfloat_operand" ""))]
160
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
161
  "
162
{
163
  gcc_assert (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode));
164
 
165
  if (VECTOR_MEM_VSX_P (mode))
166
    {
167
      operands[0] = rs6000_address_for_altivec (operands[0]);
168
      emit_insn (gen_altivec_stvx_ (operands[0], operands[1]));
169
      DONE;
170
    }
171
}")
172
 
173
 
174
 
175
;; Reload patterns for vector operations.  We may need an addtional base
176
;; register to convert the reg+offset addressing to reg+reg for vector
177
;; registers and reg+reg or (reg+reg)&(-16) addressing to just an index
178
;; register for gpr registers.
179
(define_expand "reload___store"
180
  [(parallel [(match_operand:VEC_R 0 "memory_operand" "m")
181
              (match_operand:VEC_R 1 "gpc_reg_operand" "r")
182
              (match_operand:P 2 "register_operand" "=&b")])]
183
  ""
184
{
185
  rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
186
  DONE;
187
})
188
 
189
(define_expand "reload___load"
190
  [(parallel [(match_operand:VEC_R 0 "gpc_reg_operand" "=&r")
191
              (match_operand:VEC_R 1 "memory_operand" "m")
192
              (match_operand:P 2 "register_operand" "=&b")])]
193
  ""
194
{
195
  rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
196
  DONE;
197
})
198
 
199
;; Reload sometimes tries to move the address to a GPR, and can generate
200
;; invalid RTL for addresses involving AND -16.  Allow addresses involving
201
;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
202
 
203
(define_insn_and_split "*vec_reload_and_plus_"
204
  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
205
        (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
206
                       (match_operand:P 2 "reg_or_cint_operand" "rI"))
207
               (const_int -16)))]
208
  "(TARGET_ALTIVEC || TARGET_VSX) && (reload_in_progress || reload_completed)"
209
  "#"
210
  "&& reload_completed"
211
  [(set (match_dup 0)
212
        (plus:P (match_dup 1)
213
                (match_dup 2)))
214
   (parallel [(set (match_dup 0)
215
                   (and:P (match_dup 0)
216
                          (const_int -16)))
217
              (clobber:CC (scratch:CC))])])
218
 
219
;; The normal ANDSI3/ANDDI3 won't match if reload decides to move an AND -16
220
;; address to a register because there is no clobber of a (scratch), so we add
221
;; it here.
222
(define_insn_and_split "*vec_reload_and_reg_"
223
  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
224
        (and:P (match_operand:P 1 "gpc_reg_operand" "r")
225
               (const_int -16)))]
226
  "(TARGET_ALTIVEC || TARGET_VSX) && (reload_in_progress || reload_completed)"
227
  "#"
228
  "&& reload_completed"
229
  [(parallel [(set (match_dup 0)
230
                   (and:P (match_dup 1)
231
                          (const_int -16)))
232
              (clobber:CC (scratch:CC))])])
233
 
234
;; Generic floating point vector arithmetic support
235
(define_expand "add3"
236
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
237
        (plus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")
238
                    (match_operand:VEC_F 2 "vfloat_operand" "")))]
239
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
240
  "")
241
 
242
(define_expand "sub3"
243
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
244
        (minus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")
245
                     (match_operand:VEC_F 2 "vfloat_operand" "")))]
246
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
247
  "")
248
 
249
(define_expand "mul3"
250
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
251
        (mult:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")
252
                    (match_operand:VEC_F 2 "vfloat_operand" "")))]
253
  "VECTOR_UNIT_VSX_P (mode) || VECTOR_UNIT_ALTIVEC_P (mode)"
254
{
255
  if (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (mode))
256
    {
257
      emit_insn (gen_altivec_mulv4sf3 (operands[0], operands[1], operands[2]));
258
      DONE;
259
    }
260
})
261
 
262
(define_expand "div3"
263
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
264
        (div:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")
265
                   (match_operand:VEC_F 2 "vfloat_operand" "")))]
266
  "VECTOR_UNIT_VSX_P (mode)"
267
  "")
268
 
269
(define_expand "neg2"
270
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
271
        (neg:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))]
272
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
273
  "
274
{
275
  if (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (mode))
276
    {
277
      emit_insn (gen_altivec_negv4sf2 (operands[0], operands[1]));
278
      DONE;
279
    }
280
}")
281
 
282
(define_expand "abs2"
283
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
284
        (abs:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))]
285
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
286
  "
287
{
288
  if (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (mode))
289
    {
290
      emit_insn (gen_altivec_absv4sf2 (operands[0], operands[1]));
291
      DONE;
292
    }
293
}")
294
 
295
(define_expand "smin3"
296
  [(set (match_operand:VEC_F 0 "register_operand" "")
297
        (smin:VEC_F (match_operand:VEC_F 1 "register_operand" "")
298
                    (match_operand:VEC_F 2 "register_operand" "")))]
299
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
300
  "")
301
 
302
(define_expand "smax3"
303
  [(set (match_operand:VEC_F 0 "register_operand" "")
304
        (smax:VEC_F (match_operand:VEC_F 1 "register_operand" "")
305
                    (match_operand:VEC_F 2 "register_operand" "")))]
306
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
307
  "")
308
 
309
 
310
(define_expand "sqrt2"
311
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
312
        (sqrt:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))]
313
  "VECTOR_UNIT_VSX_P (mode)"
314
  "")
315
 
316
(define_expand "rsqrte2"
317
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
318
        (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")]
319
                      UNSPEC_RSQRT))]
320
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
321
  "")
322
 
323
(define_expand "re2"
324
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
325
        (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "f")]
326
                      UNSPEC_FRES))]
327
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
328
  "")
329
 
330
(define_expand "ftrunc2"
331
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
332
        (fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))]
333
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
334
  "")
335
 
336
(define_expand "vector_ceil2"
337
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
338
        (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")]
339
                      UNSPEC_FRIP))]
340
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
341
  "")
342
 
343
(define_expand "vector_floor2"
344
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
345
        (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")]
346
                      UNSPEC_FRIM))]
347
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
348
  "")
349
 
350
(define_expand "vector_btrunc2"
351
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
352
        (fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))]
353
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
354
  "")
355
 
356
(define_expand "vector_copysign3"
357
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
358
        (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")
359
                       (match_operand:VEC_F 2 "vfloat_operand" "")] UNSPEC_COPYSIGN))]
360
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
361
  "
362
{
363
  if (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (mode))
364
    {
365
      emit_insn (gen_altivec_copysign_v4sf3 (operands[0], operands[1],
366
                                             operands[2]));
367
      DONE;
368
    }
369
}")
370
 
371
 
372
;; Vector comparisons
373
(define_expand "vcond"
374
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
375
        (if_then_else:VEC_F
376
         (match_operator 3 "comparison_operator"
377
                         [(match_operand:VEC_F 4 "vfloat_operand" "")
378
                          (match_operand:VEC_F 5 "vfloat_operand" "")])
379
         (match_operand:VEC_F 1 "vfloat_operand" "")
380
         (match_operand:VEC_F 2 "vfloat_operand" "")))]
381
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
382
  "
383
{
384
  if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
385
                                    operands[3], operands[4], operands[5]))
386
    DONE;
387
  else
388
    FAIL;
389
}")
390
 
391
(define_expand "vcond"
392
  [(set (match_operand:VEC_I 0 "vint_operand" "")
393
        (if_then_else:VEC_I
394
         (match_operator 3 "comparison_operator"
395
                         [(match_operand:VEC_I 4 "vint_operand" "")
396
                          (match_operand:VEC_I 5 "vint_operand" "")])
397
         (match_operand:VEC_I 1 "vint_operand" "")
398
         (match_operand:VEC_I 2 "vint_operand" "")))]
399
  "VECTOR_UNIT_ALTIVEC_P (mode)"
400
  "
401
{
402
  if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
403
                                    operands[3], operands[4], operands[5]))
404
    DONE;
405
  else
406
    FAIL;
407
}")
408
 
409
(define_expand "vcondv4sfv4si"
410
  [(set (match_operand:V4SF 0 "vfloat_operand" "")
411
        (if_then_else:V4SF
412
         (match_operator 3 "comparison_operator"
413
                         [(match_operand:V4SI 4 "vint_operand" "")
414
                          (match_operand:V4SI 5 "vint_operand" "")])
415
         (match_operand:V4SF 1 "vfloat_operand" "")
416
         (match_operand:V4SF 2 "vfloat_operand" "")))]
417
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
418
   && VECTOR_UNIT_ALTIVEC_P (V4SImode)"
419
  "
420
{
421
  if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
422
                                    operands[3], operands[4], operands[5]))
423
    DONE;
424
  else
425
    FAIL;
426
}")
427
 
428
(define_expand "vcondv4siv4sf"
429
  [(set (match_operand:V4SI 0 "vint_operand" "")
430
        (if_then_else:V4SI
431
         (match_operator 3 "comparison_operator"
432
                         [(match_operand:V4SF 4 "vfloat_operand" "")
433
                          (match_operand:V4SF 5 "vfloat_operand" "")])
434
         (match_operand:V4SI 1 "vint_operand" "")
435
         (match_operand:V4SI 2 "vint_operand" "")))]
436
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
437
   && VECTOR_UNIT_ALTIVEC_P (V4SImode)"
438
  "
439
{
440
  if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
441
                                    operands[3], operands[4], operands[5]))
442
    DONE;
443
  else
444
    FAIL;
445
}")
446
 
447
(define_expand "vcondu"
448
  [(set (match_operand:VEC_I 0 "vint_operand" "")
449
        (if_then_else:VEC_I
450
         (match_operator 3 "comparison_operator"
451
                         [(match_operand:VEC_I 4 "vint_operand" "")
452
                          (match_operand:VEC_I 5 "vint_operand" "")])
453
         (match_operand:VEC_I 1 "vint_operand" "")
454
         (match_operand:VEC_I 2 "vint_operand" "")))]
455
  "VECTOR_UNIT_ALTIVEC_P (mode)"
456
  "
457
{
458
  if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
459
                                    operands[3], operands[4], operands[5]))
460
    DONE;
461
  else
462
    FAIL;
463
}")
464
 
465
(define_expand "vconduv4sfv4si"
466
  [(set (match_operand:V4SF 0 "vfloat_operand" "")
467
        (if_then_else:V4SF
468
         (match_operator 3 "comparison_operator"
469
                         [(match_operand:V4SI 4 "vint_operand" "")
470
                          (match_operand:V4SI 5 "vint_operand" "")])
471
         (match_operand:V4SF 1 "vfloat_operand" "")
472
         (match_operand:V4SF 2 "vfloat_operand" "")))]
473
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
474
   && VECTOR_UNIT_ALTIVEC_P (V4SImode)"
475
  "
476
{
477
  if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
478
                                    operands[3], operands[4], operands[5]))
479
    DONE;
480
  else
481
    FAIL;
482
}")
483
 
484
(define_expand "vector_eq"
485
  [(set (match_operand:VEC_C 0 "vlogical_operand" "")
486
        (eq:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "")
487
                  (match_operand:VEC_C 2 "vlogical_operand" "")))]
488
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
489
  "")
490
 
491
(define_expand "vector_gt"
492
  [(set (match_operand:VEC_C 0 "vlogical_operand" "")
493
        (gt:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "")
494
                  (match_operand:VEC_C 2 "vlogical_operand" "")))]
495
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
496
  "")
497
 
498
(define_expand "vector_ge"
499
  [(set (match_operand:VEC_C 0 "vlogical_operand" "")
500
        (ge:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "")
501
                  (match_operand:VEC_C 2 "vlogical_operand" "")))]
502
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
503
  "")
504
 
505
(define_expand "vector_gtu"
506
  [(set (match_operand:VEC_I 0 "vint_operand" "")
507
        (gtu:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
508
                   (match_operand:VEC_I 2 "vint_operand" "")))]
509
  "VECTOR_UNIT_ALTIVEC_P (mode)"
510
  "")
511
 
512
(define_expand "vector_geu"
513
  [(set (match_operand:VEC_I 0 "vint_operand" "")
514
        (geu:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
515
                   (match_operand:VEC_I 2 "vint_operand" "")))]
516
  "VECTOR_UNIT_ALTIVEC_P (mode)"
517
  "")
518
 
519
;; Note the arguments for __builtin_altivec_vsel are op2, op1, mask
520
;; which is in the reverse order that we want
521
(define_expand "vector_select_"
522
  [(set (match_operand:VEC_L 0 "vlogical_operand" "")
523
        (if_then_else:VEC_L
524
         (ne:CC (match_operand:VEC_L 3 "vlogical_operand" "")
525
                (match_dup 4))
526
         (match_operand:VEC_L 2 "vlogical_operand" "")
527
         (match_operand:VEC_L 1 "vlogical_operand" "")))]
528
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
529
  "operands[4] = CONST0_RTX (mode);")
530
 
531
(define_expand "vector_select__uns"
532
  [(set (match_operand:VEC_L 0 "vlogical_operand" "")
533
        (if_then_else:VEC_L
534
         (ne:CCUNS (match_operand:VEC_L 3 "vlogical_operand" "")
535
                   (match_dup 4))
536
         (match_operand:VEC_L 2 "vlogical_operand" "")
537
         (match_operand:VEC_L 1 "vlogical_operand" "")))]
538
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
539
  "operands[4] = CONST0_RTX (mode);")
540
 
541
;; Expansions that compare vectors producing a vector result and a predicate,
542
;; setting CR6 to indicate a combined status
543
(define_expand "vector_eq__p"
544
  [(parallel
545
    [(set (reg:CC 74)
546
          (unspec:CC [(eq:CC (match_operand:VEC_A 1 "vlogical_operand" "")
547
                             (match_operand:VEC_A 2 "vlogical_operand" ""))]
548
                     UNSPEC_PREDICATE))
549
     (set (match_operand:VEC_A 0 "vlogical_operand" "")
550
          (eq:VEC_A (match_dup 1)
551
                    (match_dup 2)))])]
552
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
553
  "")
554
 
555
(define_expand "vector_gt__p"
556
  [(parallel
557
    [(set (reg:CC 74)
558
          (unspec:CC [(gt:CC (match_operand:VEC_A 1 "vlogical_operand" "")
559
                             (match_operand:VEC_A 2 "vlogical_operand" ""))]
560
                     UNSPEC_PREDICATE))
561
     (set (match_operand:VEC_A 0 "vlogical_operand" "")
562
          (gt:VEC_A (match_dup 1)
563
                    (match_dup 2)))])]
564
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
565
  "")
566
 
567
(define_expand "vector_ge__p"
568
  [(parallel
569
    [(set (reg:CC 74)
570
          (unspec:CC [(ge:CC (match_operand:VEC_F 1 "vfloat_operand" "")
571
                             (match_operand:VEC_F 2 "vfloat_operand" ""))]
572
                     UNSPEC_PREDICATE))
573
     (set (match_operand:VEC_F 0 "vfloat_operand" "")
574
          (ge:VEC_F (match_dup 1)
575
                    (match_dup 2)))])]
576
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
577
  "")
578
 
579
(define_expand "vector_gtu__p"
580
  [(parallel
581
    [(set (reg:CC 74)
582
          (unspec:CC [(gtu:CC (match_operand:VEC_I 1 "vint_operand" "")
583
                              (match_operand:VEC_I 2 "vint_operand" ""))]
584
                     UNSPEC_PREDICATE))
585
     (set (match_operand:VEC_I 0 "vlogical_operand" "")
586
          (gtu:VEC_I (match_dup 1)
587
                     (match_dup 2)))])]
588
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
589
  "")
590
 
591
;; AltiVec/VSX predicates.
592
 
593
(define_expand "cr6_test_for_zero"
594
  [(set (match_operand:SI 0 "register_operand" "=r")
595
        (eq:SI (reg:CC 74)
596
               (const_int 0)))]
597
  "TARGET_ALTIVEC || TARGET_VSX"
598
  "")
599
 
600
(define_expand "cr6_test_for_zero_reverse"
601
  [(set (match_operand:SI 0 "register_operand" "=r")
602
        (eq:SI (reg:CC 74)
603
               (const_int 0)))
604
   (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))]
605
  "TARGET_ALTIVEC || TARGET_VSX"
606
  "")
607
 
608
(define_expand "cr6_test_for_lt"
609
  [(set (match_operand:SI 0 "register_operand" "=r")
610
        (lt:SI (reg:CC 74)
611
               (const_int 0)))]
612
  "TARGET_ALTIVEC || TARGET_VSX"
613
  "")
614
 
615
(define_expand "cr6_test_for_lt_reverse"
616
  [(set (match_operand:SI 0 "register_operand" "=r")
617
        (lt:SI (reg:CC 74)
618
               (const_int 0)))
619
   (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))]
620
  "TARGET_ALTIVEC || TARGET_VSX"
621
  "")
622
 
623
 
624
;; Vector logical instructions
625
(define_expand "xor3"
626
  [(set (match_operand:VEC_L 0 "vlogical_operand" "")
627
        (xor:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
628
                   (match_operand:VEC_L 2 "vlogical_operand" "")))]
629
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
630
  "")
631
 
632
(define_expand "ior3"
633
  [(set (match_operand:VEC_L 0 "vlogical_operand" "")
634
        (ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
635
                   (match_operand:VEC_L 2 "vlogical_operand" "")))]
636
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
637
  "")
638
 
639
(define_expand "and3"
640
  [(set (match_operand:VEC_L 0 "vlogical_operand" "")
641
        (and:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
642
                   (match_operand:VEC_L 2 "vlogical_operand" "")))]
643
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
644
  "")
645
 
646
(define_expand "one_cmpl2"
647
  [(set (match_operand:VEC_L 0 "vlogical_operand" "")
648
        (not:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")))]
649
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
650
  "")
651
 
652
(define_expand "nor3"
653
  [(set (match_operand:VEC_L 0 "vlogical_operand" "")
654
        (not:VEC_L (ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
655
                              (match_operand:VEC_L 2 "vlogical_operand" ""))))]
656
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
657
  "")
658
 
659
(define_expand "andc3"
660
  [(set (match_operand:VEC_L 0 "vlogical_operand" "")
661
        (and:VEC_L (not:VEC_L (match_operand:VEC_L 2 "vlogical_operand" ""))
662
                   (match_operand:VEC_L 1 "vlogical_operand" "")))]
663
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
664
  "")
665
 
666
;; Same size conversions
667
(define_expand "float2"
668
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
669
        (float:VEC_F (match_operand: 1 "vint_operand" "")))]
670
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
671
  "
672
{
673
  if (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (mode))
674
    {
675
      emit_insn (gen_altivec_vcfsx (operands[0], operands[1], const0_rtx));
676
      DONE;
677
    }
678
}")
679
 
680
(define_expand "floatuns2"
681
  [(set (match_operand:VEC_F 0 "vfloat_operand" "")
682
        (unsigned_float:VEC_F (match_operand: 1 "vint_operand" "")))]
683
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
684
  "
685
{
686
  if (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (mode))
687
    {
688
      emit_insn (gen_altivec_vcfux (operands[0], operands[1], const0_rtx));
689
      DONE;
690
    }
691
}")
692
 
693
(define_expand "fix_trunc2"
694
  [(set (match_operand: 0 "vint_operand" "")
695
        (fix: (match_operand:VEC_F 1 "vfloat_operand" "")))]
696
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
697
  "
698
{
699
  if (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (mode))
700
    {
701
      emit_insn (gen_altivec_vctsxs (operands[0], operands[1], const0_rtx));
702
      DONE;
703
    }
704
}")
705
 
706
(define_expand "fixuns_trunc2"
707
  [(set (match_operand: 0 "vint_operand" "")
708
        (unsigned_fix: (match_operand:VEC_F 1 "vfloat_operand" "")))]
709
  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)"
710
  "
711
{
712
  if (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (mode))
713
    {
714
      emit_insn (gen_altivec_vctuxs (operands[0], operands[1], const0_rtx));
715
      DONE;
716
    }
717
}")
718
 
719
 
720
;; Vector initialization, set, extract
721
(define_expand "vec_init"
722
  [(match_operand:VEC_E 0 "vlogical_operand" "")
723
   (match_operand:VEC_E 1 "" "")]
724
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
725
{
726
  rs6000_expand_vector_init (operands[0], operands[1]);
727
  DONE;
728
})
729
 
730
(define_expand "vec_set"
731
  [(match_operand:VEC_E 0 "vlogical_operand" "")
732
   (match_operand: 1 "register_operand" "")
733
   (match_operand 2 "const_int_operand" "")]
734
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
735
{
736
  rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
737
  DONE;
738
})
739
 
740
(define_expand "vec_extract"
741
  [(match_operand: 0 "register_operand" "")
742
   (match_operand:VEC_E 1 "vlogical_operand" "")
743
   (match_operand 2 "const_int_operand" "")]
744
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
745
{
746
  rs6000_expand_vector_extract (operands[0], operands[1],
747
                                INTVAL (operands[2]));
748
  DONE;
749
})
750
 
751
;; Convert double word types to single word types
752
(define_expand "vec_pack_trunc_v2df"
753
  [(match_operand:V4SF 0 "vfloat_operand" "")
754
   (match_operand:V2DF 1 "vfloat_operand" "")
755
   (match_operand:V2DF 2 "vfloat_operand" "")]
756
  "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC"
757
{
758
  rtx r1 = gen_reg_rtx (V4SFmode);
759
  rtx r2 = gen_reg_rtx (V4SFmode);
760
 
761
  emit_insn (gen_vsx_xvcvdpsp (r1, operands[1]));
762
  emit_insn (gen_vsx_xvcvdpsp (r2, operands[2]));
763
  rs6000_expand_extract_even (operands[0], r1, r2);
764
  DONE;
765
})
766
 
767
(define_expand "vec_pack_sfix_trunc_v2df"
768
  [(match_operand:V4SI 0 "vint_operand" "")
769
   (match_operand:V2DF 1 "vfloat_operand" "")
770
   (match_operand:V2DF 2 "vfloat_operand" "")]
771
  "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC"
772
{
773
  rtx r1 = gen_reg_rtx (V4SImode);
774
  rtx r2 = gen_reg_rtx (V4SImode);
775
 
776
  emit_insn (gen_vsx_xvcvdpsxws (r1, operands[1]));
777
  emit_insn (gen_vsx_xvcvdpsxws (r2, operands[2]));
778
  rs6000_expand_extract_even (operands[0], r1, r2);
779
  DONE;
780
})
781
 
782
(define_expand "vec_pack_ufix_trunc_v2df"
783
  [(match_operand:V4SI 0 "vint_operand" "")
784
   (match_operand:V2DF 1 "vfloat_operand" "")
785
   (match_operand:V2DF 2 "vfloat_operand" "")]
786
  "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC"
787
{
788
  rtx r1 = gen_reg_rtx (V4SImode);
789
  rtx r2 = gen_reg_rtx (V4SImode);
790
 
791
  emit_insn (gen_vsx_xvcvdpuxws (r1, operands[1]));
792
  emit_insn (gen_vsx_xvcvdpuxws (r2, operands[2]));
793
  rs6000_expand_extract_even (operands[0], r1, r2);
794
  DONE;
795
})
796
 
797
;; Convert single word types to double word
798
(define_expand "vec_unpacks_hi_v4sf"
799
  [(match_operand:V2DF 0 "vfloat_operand" "")
800
   (match_operand:V4SF 1 "vfloat_operand" "")]
801
  "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
802
{
803
  rtx reg = gen_reg_rtx (V4SFmode);
804
 
805
  rs6000_expand_interleave (reg, operands[1], operands[1], true);
806
  emit_insn (gen_vsx_xvcvspdp (operands[0], reg));
807
  DONE;
808
})
809
 
810
(define_expand "vec_unpacks_lo_v4sf"
811
  [(match_operand:V2DF 0 "vfloat_operand" "")
812
   (match_operand:V4SF 1 "vfloat_operand" "")]
813
  "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
814
{
815
  rtx reg = gen_reg_rtx (V4SFmode);
816
 
817
  rs6000_expand_interleave (reg, operands[1], operands[1], false);
818
  emit_insn (gen_vsx_xvcvspdp (operands[0], reg));
819
  DONE;
820
})
821
 
822
(define_expand "vec_unpacks_float_hi_v4si"
823
  [(match_operand:V2DF 0 "vfloat_operand" "")
824
   (match_operand:V4SI 1 "vint_operand" "")]
825
  "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
826
{
827
  rtx reg = gen_reg_rtx (V4SImode);
828
 
829
  rs6000_expand_interleave (reg, operands[1], operands[1], true);
830
  emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg));
831
  DONE;
832
})
833
 
834
(define_expand "vec_unpacks_float_lo_v4si"
835
  [(match_operand:V2DF 0 "vfloat_operand" "")
836
   (match_operand:V4SI 1 "vint_operand" "")]
837
  "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
838
{
839
  rtx reg = gen_reg_rtx (V4SImode);
840
 
841
  rs6000_expand_interleave (reg, operands[1], operands[1], false);
842
  emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg));
843
  DONE;
844
})
845
 
846
(define_expand "vec_unpacku_float_hi_v4si"
847
  [(match_operand:V2DF 0 "vfloat_operand" "")
848
   (match_operand:V4SI 1 "vint_operand" "")]
849
  "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
850
{
851
  rtx reg = gen_reg_rtx (V4SImode);
852
 
853
  rs6000_expand_interleave (reg, operands[1], operands[1], true);
854
  emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg));
855
  DONE;
856
})
857
 
858
(define_expand "vec_unpacku_float_lo_v4si"
859
  [(match_operand:V2DF 0 "vfloat_operand" "")
860
   (match_operand:V4SI 1 "vint_operand" "")]
861
  "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
862
{
863
  rtx reg = gen_reg_rtx (V4SImode);
864
 
865
  rs6000_expand_interleave (reg, operands[1], operands[1], false);
866
  emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg));
867
  DONE;
868
})
869
 
870
 
871
;; Align vector loads with a permute.
872
(define_expand "vec_realign_load_"
873
  [(match_operand:VEC_K 0 "vlogical_operand" "")
874
   (match_operand:VEC_K 1 "vlogical_operand" "")
875
   (match_operand:VEC_K 2 "vlogical_operand" "")
876
   (match_operand:V16QI 3 "vlogical_operand" "")]
877
  "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)"
878
{
879
  emit_insn (gen_altivec_vperm_ (operands[0], operands[1], operands[2],
880
                                       operands[3]));
881
  DONE;
882
})
883
 
884
;; Under VSX, vectors of 4/8 byte alignments do not need to be aligned
885
;; since the load already handles it.
886
(define_expand "movmisalign"
887
 [(set (match_operand:VEC_N 0 "nonimmediate_operand" "")
888
       (match_operand:VEC_N 1 "any_operand" ""))]
889
 "VECTOR_MEM_VSX_P (mode) && TARGET_ALLOW_MOVMISALIGN"
890
 "")
891
 
892
 
893
;; Vector shift left in bits.  Currently supported ony for shift
894
;; amounts that can be expressed as byte shifts (divisible by 8).
895
;; General shift amounts can be supported using vslo + vsl. We're
896
;; not expecting to see these yet (the vectorizer currently
897
;; generates only shifts divisible by byte_size).
898
(define_expand "vec_shl_"
899
  [(match_operand:VEC_L 0 "vlogical_operand" "")
900
   (match_operand:VEC_L 1 "vlogical_operand" "")
901
   (match_operand:QI 2 "reg_or_short_operand" "")]
902
  "TARGET_ALTIVEC"
903
  "
904
{
905
  rtx bitshift = operands[2];
906
  rtx shift;
907
  rtx insn;
908
  HOST_WIDE_INT bitshift_val;
909
  HOST_WIDE_INT byteshift_val;
910
 
911
  if (! CONSTANT_P (bitshift))
912
    FAIL;
913
  bitshift_val = INTVAL (bitshift);
914
  if (bitshift_val & 0x7)
915
    FAIL;
916
  byteshift_val = bitshift_val >> 3;
917
  if (TARGET_VSX && (byteshift_val & 0x3) == 0)
918
    {
919
      shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2);
920
      insn = gen_vsx_xxsldwi_ (operands[0], operands[1], operands[1],
921
                                     shift);
922
    }
923
  else
924
    {
925
      shift = gen_rtx_CONST_INT (QImode, byteshift_val);
926
      insn = gen_altivec_vsldoi_ (operands[0], operands[1], operands[1],
927
                                        shift);
928
    }
929
 
930
  emit_insn (insn);
931
  DONE;
932
}")
933
 
934
;; Vector shift right in bits. Currently supported ony for shift
935
;; amounts that can be expressed as byte shifts (divisible by 8).
936
;; General shift amounts can be supported using vsro + vsr. We're
937
;; not expecting to see these yet (the vectorizer currently
938
;; generates only shifts divisible by byte_size).
939
(define_expand "vec_shr_"
940
  [(match_operand:VEC_L 0 "vlogical_operand" "")
941
   (match_operand:VEC_L 1 "vlogical_operand" "")
942
   (match_operand:QI 2 "reg_or_short_operand" "")]
943
  "TARGET_ALTIVEC"
944
  "
945
{
946
  rtx bitshift = operands[2];
947
  rtx shift;
948
  rtx insn;
949
  HOST_WIDE_INT bitshift_val;
950
  HOST_WIDE_INT byteshift_val;
951
 
952
  if (! CONSTANT_P (bitshift))
953
    FAIL;
954
  bitshift_val = INTVAL (bitshift);
955
  if (bitshift_val & 0x7)
956
    FAIL;
957
  byteshift_val = 16 - (bitshift_val >> 3);
958
  if (TARGET_VSX && (byteshift_val & 0x3) == 0)
959
    {
960
      shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2);
961
      insn = gen_vsx_xxsldwi_ (operands[0], operands[1], operands[1],
962
                                     shift);
963
    }
964
  else
965
    {
966
      shift = gen_rtx_CONST_INT (QImode, byteshift_val);
967
      insn = gen_altivec_vsldoi_ (operands[0], operands[1], operands[1],
968
                                        shift);
969
    }
970
 
971
  emit_insn (insn);
972
  DONE;
973
}")
974
 
975
;; Expanders for rotate each element in a vector
976
(define_expand "vrotl3"
977
  [(set (match_operand:VEC_I 0 "vint_operand" "")
978
        (rotate:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
979
                      (match_operand:VEC_I 2 "vint_operand" "")))]
980
  "TARGET_ALTIVEC"
981
  "")
982
 
983
;; Expanders for arithmetic shift left on each vector element
984
(define_expand "vashl3"
985
  [(set (match_operand:VEC_I 0 "vint_operand" "")
986
        (ashift:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
987
                      (match_operand:VEC_I 2 "vint_operand" "")))]
988
  "TARGET_ALTIVEC"
989
  "")
990
 
991
;; Expanders for logical shift right on each vector element
992
(define_expand "vlshr3"
993
  [(set (match_operand:VEC_I 0 "vint_operand" "")
994
        (lshiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
995
                        (match_operand:VEC_I 2 "vint_operand" "")))]
996
  "TARGET_ALTIVEC"
997
  "")
998
 
999
;; Expanders for arithmetic shift right on each vector element
1000
(define_expand "vashr3"
1001
  [(set (match_operand:VEC_I 0 "vint_operand" "")
1002
        (ashiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
1003
                        (match_operand:VEC_I 2 "vint_operand" "")))]
1004
  "TARGET_ALTIVEC"
1005
  "")
1006
 
1007
;; Vector reduction expanders for VSX
1008
 
1009
(define_expand "reduc__v2df"
1010
  [(parallel [(set (match_operand:V2DF 0 "vfloat_operand" "")
1011
                   (VEC_reduc:V2DF
1012
                    (vec_concat:V2DF
1013
                     (vec_select:DF
1014
                      (match_operand:V2DF 1 "vfloat_operand" "")
1015
                      (parallel [(const_int 1)]))
1016
                     (vec_select:DF
1017
                      (match_dup 1)
1018
                      (parallel [(const_int 0)])))
1019
                    (match_dup 1)))
1020
              (clobber (match_scratch:V2DF 2 ""))])]
1021
  "VECTOR_UNIT_VSX_P (V2DFmode)"
1022
  "")
1023
 
1024
; The (VEC_reduc:V4SF
1025
;       (op1)
1026
;       (unspec:V4SF [(const_int 0)] UNSPEC_REDUC))
1027
;
1028
; is to allow us to use a code iterator, but not completely list all of the
1029
; vector rotates, etc. to prevent canonicalization
1030
 
1031
(define_expand "reduc__v4sf"
1032
  [(parallel [(set (match_operand:V4SF 0 "vfloat_operand" "")
1033
                   (VEC_reduc:V4SF
1034
                    (unspec:V4SF [(const_int 0)] UNSPEC_REDUC)
1035
                    (match_operand:V4SF 1 "vfloat_operand" "")))
1036
              (clobber (match_scratch:V4SF 2 ""))
1037
              (clobber (match_scratch:V4SF 3 ""))])]
1038
  "VECTOR_UNIT_VSX_P (V4SFmode)"
1039
  "")
1040
 
1041
 
1042
;;; Expanders for vector insn patterns shared between the SPE and TARGET_PAIRED systems.
1043
 
1044
(define_expand "absv2sf2"
1045
  [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
1046
        (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")))]
1047
  "TARGET_PAIRED_FLOAT || TARGET_SPE"
1048
  "")
1049
 
1050
(define_expand "negv2sf2"
1051
  [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
1052
        (neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")))]
1053
  "TARGET_PAIRED_FLOAT || TARGET_SPE"
1054
  "")
1055
 
1056
(define_expand "addv2sf3"
1057
  [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
1058
        (plus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")
1059
                   (match_operand:V2SF 2 "gpc_reg_operand" "")))]
1060
  "TARGET_PAIRED_FLOAT || TARGET_SPE"
1061
  "
1062
{
1063
  if (TARGET_SPE)
1064
    {
1065
      /* We need to make a note that we clobber SPEFSCR.  */
1066
      rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
1067
 
1068
      XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0],
1069
                                         gen_rtx_PLUS (V2SFmode, operands[1], operands[2]));
1070
      XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO));
1071
      emit_insn (par);
1072
      DONE;
1073
    }
1074
}")
1075
 
1076
(define_expand "subv2sf3"
1077
  [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
1078
        (minus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")
1079
                    (match_operand:V2SF 2 "gpc_reg_operand" "")))]
1080
  "TARGET_PAIRED_FLOAT || TARGET_SPE"
1081
  "
1082
{
1083
  if (TARGET_SPE)
1084
    {
1085
      /* We need to make a note that we clobber SPEFSCR.  */
1086
      rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
1087
 
1088
      XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0],
1089
                                         gen_rtx_MINUS (V2SFmode, operands[1], operands[2]));
1090
      XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO));
1091
      emit_insn (par);
1092
      DONE;
1093
    }
1094
}")
1095
 
1096
(define_expand "mulv2sf3"
1097
  [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
1098
        (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")
1099
                   (match_operand:V2SF 2 "gpc_reg_operand" "")))]
1100
  "TARGET_PAIRED_FLOAT || TARGET_SPE"
1101
  "
1102
{
1103
  if (TARGET_SPE)
1104
    {
1105
      /* We need to make a note that we clobber SPEFSCR.  */
1106
      rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
1107
 
1108
      XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0],
1109
                                         gen_rtx_MULT (V2SFmode, operands[1], operands[2]));
1110
      XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO));
1111
      emit_insn (par);
1112
      DONE;
1113
    }
1114
}")
1115
 
1116
(define_expand "divv2sf3"
1117
  [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
1118
        (div:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")
1119
                  (match_operand:V2SF 2 "gpc_reg_operand" "")))]
1120
  "TARGET_PAIRED_FLOAT || TARGET_SPE"
1121
  "
1122
{
1123
  if (TARGET_SPE)
1124
    {
1125
      /* We need to make a note that we clobber SPEFSCR.  */
1126
      rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
1127
 
1128
      XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0],
1129
                                         gen_rtx_DIV (V2SFmode, operands[1], operands[2]));
1130
      XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO));
1131
      emit_insn (par);
1132
      DONE;
1133
    }
1134
}")

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.