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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [rs6000/] [vsx.md] - Blame information for rev 298

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

Line No. Rev Author Line
1 282 jeremybenn
;; VSX patterns.
2
;; Copyright (C) 2009
3
;; Free Software Foundation, Inc.
4
;; Contributed by Michael Meissner 
5
 
6
;; This file is part of GCC.
7
 
8
;; GCC is free software; you can redistribute it and/or modify it
9
;; under the terms of the GNU General Public License as published
10
;; by the Free Software Foundation; either version 3, or (at your
11
;; option) any later version.
12
 
13
;; GCC is distributed in the hope that it will be useful, but WITHOUT
14
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16
;; License for more details.
17
 
18
;; You should have received a copy of the GNU General Public License
19
;; along with GCC; see the file COPYING3.  If not see
20
;; .
21
 
22
;; Iterator for both scalar and vector floating point types supported by VSX
23
(define_mode_iterator VSX_B [DF V4SF V2DF])
24
 
25
;; Iterator for the 2 64-bit vector types
26
(define_mode_iterator VSX_D [V2DF V2DI])
27
 
28
;; Iterator for the 2 32-bit vector types
29
(define_mode_iterator VSX_W [V4SF V4SI])
30
 
31
;; Iterator for vector floating point types supported by VSX
32
(define_mode_iterator VSX_F [V4SF V2DF])
33
 
34
;; Iterator for logical types supported by VSX
35
(define_mode_iterator VSX_L [V16QI V8HI V4SI V2DI V4SF V2DF TI])
36
 
37
;; Iterator for memory move.  Handle TImode specially to allow
38
;; it to use gprs as well as vsx registers.
39
(define_mode_iterator VSX_M [V16QI V8HI V4SI V2DI V4SF V2DF])
40
 
41
;; Map into the appropriate load/store name based on the type
42
(define_mode_attr VSm  [(V16QI "vw4")
43
                        (V8HI  "vw4")
44
                        (V4SI  "vw4")
45
                        (V4SF  "vw4")
46
                        (V2DF  "vd2")
47
                        (V2DI  "vd2")
48
                        (DF    "d")
49
                        (TI    "vw4")])
50
 
51
;; Map into the appropriate suffix based on the type
52
(define_mode_attr VSs   [(V16QI "sp")
53
                         (V8HI  "sp")
54
                         (V4SI  "sp")
55
                         (V4SF  "sp")
56
                         (V2DF  "dp")
57
                         (V2DI  "dp")
58
                         (DF    "dp")
59
                         (SF    "sp")
60
                         (TI    "sp")])
61
 
62
;; Map the register class used
63
(define_mode_attr VSr   [(V16QI "v")
64
                         (V8HI  "v")
65
                         (V4SI  "v")
66
                         (V4SF  "wf")
67
                         (V2DI  "wd")
68
                         (V2DF  "wd")
69
                         (DF    "ws")
70
                         (SF    "d")
71
                         (TI    "wd")])
72
 
73
;; Map the register class used for float<->int conversions
74
(define_mode_attr VSr2  [(V2DF  "wd")
75
                         (V4SF  "wf")
76
                         (DF    "!f#r")])
77
 
78
(define_mode_attr VSr3  [(V2DF  "wa")
79
                         (V4SF  "wa")
80
                         (DF    "!f#r")])
81
 
82
;; Map the register class for sp<->dp float conversions, destination
83
(define_mode_attr VSr4  [(SF    "ws")
84
                         (DF    "f")
85
                         (V2DF  "wd")
86
                         (V4SF  "v")])
87
 
88
;; Map the register class for sp<->dp float conversions, destination
89
(define_mode_attr VSr5  [(SF    "ws")
90
                         (DF    "f")
91
                         (V2DF  "v")
92
                         (V4SF  "wd")])
93
 
94
;; Same size integer type for floating point data
95
(define_mode_attr VSi [(V4SF  "v4si")
96
                       (V2DF  "v2di")
97
                       (DF    "di")])
98
 
99
(define_mode_attr VSI [(V4SF  "V4SI")
100
                       (V2DF  "V2DI")
101
                       (DF    "DI")])
102
 
103
;; Word size for same size conversion
104
(define_mode_attr VSc [(V4SF "w")
105
                       (V2DF "d")
106
                       (DF   "d")])
107
 
108
;; Map into either s or v, depending on whether this is a scalar or vector
109
;; operation
110
(define_mode_attr VSv   [(V16QI "v")
111
                         (V8HI  "v")
112
                         (V4SI  "v")
113
                         (V4SF  "v")
114
                         (V2DI  "v")
115
                         (V2DF  "v")
116
                         (TI    "v")
117
                         (DF    "s")])
118
 
119
;; Appropriate type for add ops (and other simple FP ops)
120
(define_mode_attr VStype_simple [(V2DF "vecfloat")
121
                                 (V4SF "vecfloat")
122
                                 (DF   "fp")])
123
 
124
(define_mode_attr VSfptype_simple [(V2DF "fp_addsub_d")
125
                                   (V4SF "fp_addsub_s")
126
                                   (DF   "fp_addsub_d")])
127
 
128
;; Appropriate type for multiply ops
129
(define_mode_attr VStype_mul    [(V2DF "vecfloat")
130
                                 (V4SF "vecfloat")
131
                                 (DF   "dmul")])
132
 
133
(define_mode_attr VSfptype_mul  [(V2DF "fp_mul_d")
134
                                 (V4SF "fp_mul_s")
135
                                 (DF   "fp_mul_d")])
136
 
137
;; Appropriate type for divide ops.  For now, just lump the vector divide with
138
;; the scalar divides
139
(define_mode_attr VStype_div    [(V2DF "ddiv")
140
                                 (V4SF "sdiv")
141
                                 (DF   "ddiv")])
142
 
143
(define_mode_attr VSfptype_div  [(V2DF "fp_div_d")
144
                                 (V4SF "fp_div_s")
145
                                 (DF   "fp_div_d")])
146
 
147
;; Appropriate type for sqrt ops.  For now, just lump the vector sqrt with
148
;; the scalar sqrt
149
(define_mode_attr VStype_sqrt   [(V2DF "dsqrt")
150
                                 (V4SF "sdiv")
151
                                 (DF   "ddiv")])
152
 
153
(define_mode_attr VSfptype_sqrt [(V2DF "fp_sqrt_d")
154
                                 (V4SF "fp_sqrt_s")
155
                                 (DF   "fp_sqrt_d")])
156
 
157
;; Iterator and modes for sp<->dp conversions
158
;; Because scalar SF values are represented internally as double, use the
159
;; V4SF type to represent this than SF.
160
(define_mode_iterator VSX_SPDP [DF V4SF V2DF])
161
 
162
(define_mode_attr VS_spdp_res [(DF      "V4SF")
163
                               (V4SF    "V2DF")
164
                               (V2DF    "V4SF")])
165
 
166
(define_mode_attr VS_spdp_insn [(DF     "xscvdpsp")
167
                                (V4SF   "xvcvspdp")
168
                                (V2DF   "xvcvdpsp")])
169
 
170
(define_mode_attr VS_spdp_type [(DF     "fp")
171
                                (V4SF   "vecfloat")
172
                                (V2DF   "vecfloat")])
173
 
174
;; Map the scalar mode for a vector type
175
(define_mode_attr VS_scalar [(V2DF      "DF")
176
                             (V2DI      "DI")
177
                             (V4SF      "SF")
178
                             (V4SI      "SI")
179
                             (V8HI      "HI")
180
                             (V16QI     "QI")])
181
 
182
;; Constants for creating unspecs
183
(define_constants
184
  [(UNSPEC_VSX_CONCAT           500)
185
   (UNSPEC_VSX_CVDPSXWS         501)
186
   (UNSPEC_VSX_CVDPUXWS         502)
187
   (UNSPEC_VSX_CVSPDP           503)
188
   (UNSPEC_VSX_CVSXWDP          504)
189
   (UNSPEC_VSX_CVUXWDP          505)
190
   (UNSPEC_VSX_CVSXDSP          506)
191
   (UNSPEC_VSX_CVUXDSP          507)
192
   (UNSPEC_VSX_CVSPSXDS         508)
193
   (UNSPEC_VSX_CVSPUXDS         509)
194
   (UNSPEC_VSX_MADD             510)
195
   (UNSPEC_VSX_MSUB             511)
196
   (UNSPEC_VSX_NMADD            512)
197
   (UNSPEC_VSX_NMSUB            513)
198
   (UNSPEC_VSX_RSQRTE           514)
199
   (UNSPEC_VSX_TDIV             515)
200
   (UNSPEC_VSX_TSQRT            516)
201
   (UNSPEC_VSX_XXPERMDI         517)
202
   (UNSPEC_VSX_SET              518)
203
   (UNSPEC_VSX_ROUND_I          519)
204
   (UNSPEC_VSX_ROUND_IC         520)
205
   (UNSPEC_VSX_SLDWI            521)])
206
 
207
;; VSX moves
208
(define_insn "*vsx_mov"
209
  [(set (match_operand:VSX_M 0 "nonimmediate_operand" "=Z,,,?Z,?wa,?wa,*o,*r,*r,,?wa,v,wZ,v")
210
        (match_operand:VSX_M 1 "input_operand" ",Z,,wa,Z,wa,r,o,r,j,j,W,v,wZ"))]
211
  "VECTOR_MEM_VSX_P (mode)
212
   && (register_operand (operands[0], mode)
213
       || register_operand (operands[1], mode))"
214
{
215
  switch (which_alternative)
216
    {
217
    case 0:
218
    case 3:
219
      gcc_assert (MEM_P (operands[0])
220
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_INC
221
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_DEC
222
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_MODIFY);
223
      return "stxx %x1,%y0";
224
 
225
    case 1:
226
    case 4:
227
      gcc_assert (MEM_P (operands[1])
228
                  && GET_CODE (XEXP (operands[1], 0)) != PRE_INC
229
                  && GET_CODE (XEXP (operands[1], 0)) != PRE_DEC
230
                  && GET_CODE (XEXP (operands[1], 0)) != PRE_MODIFY);
231
      return "lxx %x0,%y1";
232
 
233
    case 2:
234
    case 5:
235
      return "xxlor %x0,%x1,%x1";
236
 
237
    case 6:
238
    case 7:
239
    case 8:
240
      return "#";
241
 
242
    case 9:
243
    case 10:
244
      return "xxlxor %x0,%x0,%x0";
245
 
246
    case 11:
247
      return output_vec_const_move (operands);
248
 
249
    case 12:
250
      gcc_assert (MEM_P (operands[0])
251
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_INC
252
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_DEC
253
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_MODIFY);
254
      return "stvx %1,%y0";
255
 
256
    case 13:
257
      gcc_assert (MEM_P (operands[0])
258
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_INC
259
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_DEC
260
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_MODIFY);
261
      return "lvx %0,%y1";
262
 
263
    default:
264
      gcc_unreachable ();
265
    }
266
}
267
  [(set_attr "type" "vecstore,vecload,vecsimple,vecstore,vecload,vecsimple,*,*,*,vecsimple,vecsimple,*,vecstore,vecload")])
268
 
269
;; Unlike other VSX moves, allow the GPRs, since a normal use of TImode is for
270
;; unions.  However for plain data movement, slightly favor the vector loads
271
(define_insn "*vsx_movti"
272
  [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,wa,wa,?o,?r,?r,wa,v,v,wZ")
273
        (match_operand:TI 1 "input_operand" "wa,Z,wa,r,o,r,j,W,wZ,v"))]
274
  "VECTOR_MEM_VSX_P (TImode)
275
   && (register_operand (operands[0], TImode)
276
       || register_operand (operands[1], TImode))"
277
{
278
  switch (which_alternative)
279
    {
280
    case 0:
281
      return "stxvd2x %x1,%y0";
282
 
283
    case 1:
284
      return "lxvd2x %x0,%y1";
285
 
286
    case 2:
287
      return "xxlor %x0,%x1,%x1";
288
 
289
    case 3:
290
    case 4:
291
    case 5:
292
      return "#";
293
 
294
    case 6:
295
      return "xxlxor %x0,%x0,%x0";
296
 
297
    case 7:
298
      return output_vec_const_move (operands);
299
 
300
    case 8:
301
      return "stvx %1,%y0";
302
 
303
    case 9:
304
      return "lvx %0,%y1";
305
 
306
    default:
307
      gcc_unreachable ();
308
    }
309
}
310
  [(set_attr "type" "vecstore,vecload,vecsimple,*,*,*,vecsimple,*,vecstore,vecload")])
311
 
312
 
313
;; VSX scalar and vector floating point arithmetic instructions
314
(define_insn "*vsx_add3"
315
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
316
        (plus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
317
                    (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
318
  "VECTOR_UNIT_VSX_P (mode)"
319
  "xadd %x0,%x1,%x2"
320
  [(set_attr "type" "")
321
   (set_attr "fp_type" "")])
322
 
323
(define_insn "*vsx_sub3"
324
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
325
        (minus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
326
                     (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
327
  "VECTOR_UNIT_VSX_P (mode)"
328
  "xsub %x0,%x1,%x2"
329
  [(set_attr "type" "")
330
   (set_attr "fp_type" "")])
331
 
332
(define_insn "*vsx_mul3"
333
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
334
        (mult:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
335
                    (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
336
  "VECTOR_UNIT_VSX_P (mode)"
337
  "xmul %x0,%x1,%x2"
338
  [(set_attr "type" "")
339
   (set_attr "fp_type" "")])
340
 
341
(define_insn "*vsx_div3"
342
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
343
        (div:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
344
                   (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
345
  "VECTOR_UNIT_VSX_P (mode)"
346
  "xdiv %x0,%x1,%x2"
347
  [(set_attr "type" "")
348
   (set_attr "fp_type" "")])
349
 
350
;; *tdiv* instruction returning the FG flag
351
(define_expand "vsx_tdiv3_fg"
352
  [(set (match_dup 3)
353
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")
354
                      (match_operand:VSX_B 2 "vsx_register_operand" "")]
355
                     UNSPEC_VSX_TDIV))
356
   (set (match_operand:SI 0 "gpc_reg_operand" "")
357
        (gt:SI (match_dup 3)
358
               (const_int 0)))]
359
  "VECTOR_UNIT_VSX_P (mode)"
360
{
361
  operands[3] = gen_reg_rtx (CCFPmode);
362
})
363
 
364
;; *tdiv* instruction returning the FE flag
365
(define_expand "vsx_tdiv3_fe"
366
  [(set (match_dup 3)
367
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")
368
                      (match_operand:VSX_B 2 "vsx_register_operand" "")]
369
                     UNSPEC_VSX_TDIV))
370
   (set (match_operand:SI 0 "gpc_reg_operand" "")
371
        (eq:SI (match_dup 3)
372
               (const_int 0)))]
373
  "VECTOR_UNIT_VSX_P (mode)"
374
{
375
  operands[3] = gen_reg_rtx (CCFPmode);
376
})
377
 
378
(define_insn "*vsx_tdiv3_internal"
379
  [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x")
380
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")
381
                      (match_operand:VSX_B 2 "vsx_register_operand" ",wa")]
382
                   UNSPEC_VSX_TDIV))]
383
  "VECTOR_UNIT_VSX_P (mode)"
384
  "xtdiv %0,%x1,%x2"
385
  [(set_attr "type" "")
386
   (set_attr "fp_type" "")])
387
 
388
(define_insn "vsx_fre2"
389
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
390
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
391
                      UNSPEC_FRES))]
392
  "VECTOR_UNIT_VSX_P (mode)"
393
  "xre %x0,%x1"
394
  [(set_attr "type" "")
395
   (set_attr "fp_type" "")])
396
 
397
(define_insn "*vsx_neg2"
398
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
399
        (neg:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
400
  "VECTOR_UNIT_VSX_P (mode)"
401
  "xneg %x0,%x1"
402
  [(set_attr "type" "")
403
   (set_attr "fp_type" "")])
404
 
405
(define_insn "*vsx_abs2"
406
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
407
        (abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
408
  "VECTOR_UNIT_VSX_P (mode)"
409
  "xabs %x0,%x1"
410
  [(set_attr "type" "")
411
   (set_attr "fp_type" "")])
412
 
413
(define_insn "vsx_nabs2"
414
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
415
        (neg:VSX_B
416
         (abs:VSX_B
417
          (match_operand:VSX_B 1 "vsx_register_operand" ",wa"))))]
418
  "VECTOR_UNIT_VSX_P (mode)"
419
  "xnabs %x0,%x1"
420
  [(set_attr "type" "")
421
   (set_attr "fp_type" "")])
422
 
423
(define_insn "vsx_smax3"
424
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
425
        (smax:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
426
                    (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
427
  "VECTOR_UNIT_VSX_P (mode)"
428
  "xmax %x0,%x1,%x2"
429
  [(set_attr "type" "")
430
   (set_attr "fp_type" "")])
431
 
432
(define_insn "*vsx_smin3"
433
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
434
        (smin:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
435
                    (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
436
  "VECTOR_UNIT_VSX_P (mode)"
437
  "xmin %x0,%x1,%x2"
438
  [(set_attr "type" "")
439
   (set_attr "fp_type" "")])
440
 
441
(define_insn "*vsx_sqrt2"
442
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
443
        (sqrt:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
444
  "VECTOR_UNIT_VSX_P (mode)"
445
  "xsqrt %x0,%x1"
446
  [(set_attr "type" "")
447
   (set_attr "fp_type" "")])
448
 
449
(define_insn "vsx_rsqrte2"
450
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
451
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
452
                      UNSPEC_VSX_RSQRTE))]
453
  "VECTOR_UNIT_VSX_P (mode)"
454
  "xrsqrte %x0,%x1"
455
  [(set_attr "type" "")
456
   (set_attr "fp_type" "")])
457
 
458
;; *tsqrt* returning the fg flag
459
(define_expand "vsx_tsqrt2_fg"
460
  [(set (match_dup 3)
461
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")]
462
                     UNSPEC_VSX_TSQRT))
463
   (set (match_operand:SI 0 "gpc_reg_operand" "")
464
        (gt:SI (match_dup 3)
465
               (const_int 0)))]
466
  "VECTOR_UNIT_VSX_P (mode)"
467
{
468
  operands[3] = gen_reg_rtx (CCFPmode);
469
})
470
 
471
;; *tsqrt* returning the fe flag
472
(define_expand "vsx_tsqrt2_fe"
473
  [(set (match_dup 3)
474
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")]
475
                     UNSPEC_VSX_TSQRT))
476
   (set (match_operand:SI 0 "gpc_reg_operand" "")
477
        (eq:SI (match_dup 3)
478
               (const_int 0)))]
479
  "VECTOR_UNIT_VSX_P (mode)"
480
{
481
  operands[3] = gen_reg_rtx (CCFPmode);
482
})
483
 
484
(define_insn "*vsx_tsqrt2_internal"
485
  [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x")
486
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
487
                     UNSPEC_VSX_TSQRT))]
488
  "VECTOR_UNIT_VSX_P (mode)"
489
  "xtsqrt %0,%x1"
490
  [(set_attr "type" "")
491
   (set_attr "fp_type" "")])
492
 
493
;; Fused vector multiply/add instructions
494
 
495
;; Note we have a pattern for the multiply/add operations that uses unspec and
496
;; does not check -mfused-madd to allow users to use these ops when they know
497
;; they want the fused multiply/add.
498
 
499
(define_expand "vsx_fmadd4"
500
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "")
501
        (plus:VSX_B
502
         (mult:VSX_B
503
          (match_operand:VSX_B 1 "vsx_register_operand" "")
504
          (match_operand:VSX_B 2 "vsx_register_operand" ""))
505
         (match_operand:VSX_B 3 "vsx_register_operand" "")))]
506
  "VECTOR_UNIT_VSX_P (mode)"
507
{
508
  if (!TARGET_FUSED_MADD)
509
    {
510
      emit_insn (gen_vsx_fmadd4_2 (operands[0], operands[1], operands[2],
511
                                         operands[3]));
512
      DONE;
513
    }
514
})
515
 
516
(define_insn "*vsx_fmadd4_1"
517
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
518
        (plus:VSX_B
519
         (mult:VSX_B
520
          (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
521
          (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))
522
         (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")))]
523
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD"
524
  "@
525
   xmadda %x0,%x1,%x2
526
   xmaddm %x0,%x1,%x3
527
   xmadda %x0,%x1,%x2
528
   xmaddm %x0,%x1,%x3"
529
  [(set_attr "type" "")
530
   (set_attr "fp_type" "")])
531
 
532
(define_insn "vsx_fmadd4_2"
533
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
534
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
535
                       (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")
536
                       (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")]
537
                      UNSPEC_VSX_MADD))]
538
  "VECTOR_UNIT_VSX_P (mode)"
539
  "@
540
   xmadda %x0,%x1,%x2
541
   xmaddm %x0,%x1,%x3
542
   xmadda %x0,%x1,%x2
543
   xmaddm %x0,%x1,%x3"
544
  [(set_attr "type" "")
545
   (set_attr "fp_type" "")])
546
 
547
(define_expand "vsx_fmsub4"
548
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "")
549
        (minus:VSX_B
550
         (mult:VSX_B
551
          (match_operand:VSX_B 1 "vsx_register_operand" "")
552
          (match_operand:VSX_B 2 "vsx_register_operand" ""))
553
         (match_operand:VSX_B 3 "vsx_register_operand" "")))]
554
  "VECTOR_UNIT_VSX_P (mode)"
555
{
556
  if (!TARGET_FUSED_MADD)
557
    {
558
      emit_insn (gen_vsx_fmsub4_2 (operands[0], operands[1], operands[2],
559
                                         operands[3]));
560
      DONE;
561
    }
562
})
563
 
564
(define_insn "*vsx_fmsub4_1"
565
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
566
        (minus:VSX_B
567
         (mult:VSX_B
568
          (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
569
          (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))
570
         (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")))]
571
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD"
572
  "@
573
   xmsuba %x0,%x1,%x2
574
   xmsubm %x0,%x1,%x3
575
   xmsuba %x0,%x1,%x2
576
   xmsubm %x0,%x1,%x3"
577
  [(set_attr "type" "")
578
   (set_attr "fp_type" "")])
579
 
580
(define_insn "vsx_fmsub4_2"
581
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
582
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
583
                       (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")
584
                       (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")]
585
                      UNSPEC_VSX_MSUB))]
586
  "VECTOR_UNIT_VSX_P (mode)"
587
  "@
588
   xmsuba %x0,%x1,%x2
589
   xmsubm %x0,%x1,%x3
590
   xmsuba %x0,%x1,%x2
591
   xmsubm %x0,%x1,%x3"
592
  [(set_attr "type" "")
593
   (set_attr "fp_type" "")])
594
 
595
(define_expand "vsx_fnmadd4"
596
  [(match_operand:VSX_B 0 "vsx_register_operand" "")
597
   (match_operand:VSX_B 1 "vsx_register_operand" "")
598
   (match_operand:VSX_B 2 "vsx_register_operand" "")
599
   (match_operand:VSX_B 3 "vsx_register_operand" "")]
600
  "VECTOR_UNIT_VSX_P (mode)"
601
{
602
  if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode))
603
    {
604
       emit_insn (gen_vsx_fnmadd4_1 (operands[0], operands[1],
605
                                           operands[2], operands[3]));
606
       DONE;
607
    }
608
  else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode))
609
    {
610
       emit_insn (gen_vsx_fnmadd4_2 (operands[0], operands[1],
611
                                           operands[2], operands[3]));
612
       DONE;
613
    }
614
  else
615
    {
616
       emit_insn (gen_vsx_fnmadd4_3 (operands[0], operands[1],
617
                                           operands[2], operands[3]));
618
       DONE;
619
    }
620
})
621
 
622
(define_insn "vsx_fnmadd4_1"
623
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
624
        (neg:VSX_B
625
         (plus:VSX_B
626
          (mult:VSX_B
627
           (match_operand:VSX_B 1 "vsx_register_operand" ",,wa,wa")
628
           (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))
629
          (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa"))))]
630
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD
631
   && HONOR_SIGNED_ZEROS (DFmode)"
632
  "@
633
   xnmadda %x0,%x1,%x2
634
   xnmaddm %x0,%x1,%x3
635
   xnmadda %x0,%x1,%x2
636
   xnmaddm %x0,%x1,%x3"
637
  [(set_attr "type" "")
638
   (set_attr "fp_type" "")])
639
 
640
(define_insn "vsx_fnmadd4_2"
641
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
642
        (minus:VSX_B
643
         (mult:VSX_B
644
          (neg:VSX_B
645
           (match_operand:VSX_B 1 "gpc_reg_operand" ",,wa,wa"))
646
          (match_operand:VSX_B 2 "gpc_reg_operand" ",0,wa,0"))
647
         (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")))]
648
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD
649
   && !HONOR_SIGNED_ZEROS (DFmode)"
650
  "@
651
   xnmadda %x0,%x1,%x2
652
   xnmaddm %x0,%x1,%x3
653
   xnmadda %x0,%x1,%x2
654
   xnmaddm %x0,%x1,%x3"
655
  [(set_attr "type" "")
656
   (set_attr "fp_type" "")])
657
 
658
(define_insn "vsx_fnmadd4_3"
659
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
660
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",,wa,wa")
661
                       (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")
662
                       (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")]
663
                      UNSPEC_VSX_NMADD))]
664
  "VECTOR_UNIT_VSX_P (mode)"
665
  "@
666
   xnmadda %x0,%x1,%x2
667
   xnmaddm %x0,%x1,%x3
668
   xnmadda %x0,%x1,%x2
669
   xnmaddm %x0,%x1,%x3"
670
  [(set_attr "type" "")
671
   (set_attr "fp_type" "")])
672
 
673
(define_expand "vsx_fnmsub4"
674
  [(match_operand:VSX_B 0 "vsx_register_operand" "")
675
   (match_operand:VSX_B 1 "vsx_register_operand" "")
676
   (match_operand:VSX_B 2 "vsx_register_operand" "")
677
   (match_operand:VSX_B 3 "vsx_register_operand" "")]
678
  "VECTOR_UNIT_VSX_P (mode)"
679
{
680
  if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode))
681
    {
682
       emit_insn (gen_vsx_fnmsub4_1 (operands[0], operands[1],
683
                                           operands[2], operands[3]));
684
       DONE;
685
    }
686
  else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode))
687
    {
688
       emit_insn (gen_vsx_fnmsub4_2 (operands[0], operands[1],
689
                                           operands[2], operands[3]));
690
       DONE;
691
    }
692
  else
693
    {
694
       emit_insn (gen_vsx_fnmsub4_3 (operands[0], operands[1],
695
                                           operands[2], operands[3]));
696
       DONE;
697
    }
698
})
699
 
700
(define_insn "vsx_fnmsub4_1"
701
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
702
        (neg:VSX_B
703
         (minus:VSX_B
704
          (mult:VSX_B
705
           (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
706
           (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))
707
          (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa"))))]
708
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD
709
   && HONOR_SIGNED_ZEROS (DFmode)"
710
  "@
711
   xnmsuba %x0,%x1,%x2
712
   xnmsubm %x0,%x1,%x3
713
   xnmsuba %x0,%x1,%x2
714
   xnmsubm %x0,%x1,%x3"
715
  [(set_attr "type" "")
716
   (set_attr "fp_type" "")])
717
 
718
(define_insn "vsx_fnmsub4_2"
719
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
720
        (minus:VSX_B
721
         (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")
722
         (mult:VSX_B
723
          (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
724
          (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))))]
725
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD
726
   && !HONOR_SIGNED_ZEROS (DFmode)"
727
  "@
728
   xnmsuba %x0,%x1,%x2
729
   xnmsubm %x0,%x1,%x3
730
   xnmsuba %x0,%x1,%x2
731
   xnmsubm %x0,%x1,%x3"
732
  [(set_attr "type" "")
733
   (set_attr "fp_type" "")])
734
 
735
(define_insn "vsx_fnmsub4_3"
736
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
737
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
738
                       (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")
739
                       (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")]
740
                      UNSPEC_VSX_NMSUB))]
741
  "VECTOR_UNIT_VSX_P (mode)"
742
  "@
743
   xnmsuba %x0,%x1,%x2
744
   xnmsubm %x0,%x1,%x3
745
   xnmsuba %x0,%x1,%x2
746
   xnmsubm %x0,%x1,%x3"
747
  [(set_attr "type" "")
748
   (set_attr "fp_type" "")])
749
 
750
;; Vector conditional expressions (no scalar version for these instructions)
751
(define_insn "vsx_eq"
752
  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
753
        (eq:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" ",wa")
754
                  (match_operand:VSX_F 2 "vsx_register_operand" ",wa")))]
755
  "VECTOR_UNIT_VSX_P (mode)"
756
  "xvcmpeq %x0,%x1,%x2"
757
  [(set_attr "type" "")
758
   (set_attr "fp_type" "")])
759
 
760
(define_insn "vsx_gt"
761
  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
762
        (gt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" ",wa")
763
                  (match_operand:VSX_F 2 "vsx_register_operand" ",wa")))]
764
  "VECTOR_UNIT_VSX_P (mode)"
765
  "xvcmpgt %x0,%x1,%x2"
766
  [(set_attr "type" "")
767
   (set_attr "fp_type" "")])
768
 
769
(define_insn "*vsx_ge"
770
  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
771
        (ge:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" ",wa")
772
                  (match_operand:VSX_F 2 "vsx_register_operand" ",wa")))]
773
  "VECTOR_UNIT_VSX_P (mode)"
774
  "xvcmpge %x0,%x1,%x2"
775
  [(set_attr "type" "")
776
   (set_attr "fp_type" "")])
777
 
778
;; Floating point scalar compare
779
(define_insn "*vsx_cmpdf_internal1"
780
  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,?y")
781
        (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "ws,wa")
782
                      (match_operand:DF 2 "gpc_reg_operand" "ws,wa")))]
783
  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
784
   && VECTOR_UNIT_VSX_P (DFmode)"
785
  "xscmpudp %0,%x1,%x2"
786
  [(set_attr "type" "fpcompare")])
787
 
788
;; Compare vectors producing a vector result and a predicate, setting CR6 to
789
;; indicate a combined status
790
(define_insn "*vsx_eq__p"
791
  [(set (reg:CC 74)
792
        (unspec:CC
793
         [(eq:CC (match_operand:VSX_F 1 "vsx_register_operand" ",?wa")
794
                 (match_operand:VSX_F 2 "vsx_register_operand" ",?wa"))]
795
         UNSPEC_PREDICATE))
796
   (set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
797
        (eq:VSX_F (match_dup 1)
798
                  (match_dup 2)))]
799
  "VECTOR_UNIT_VSX_P (mode)"
800
  "xvcmpeq. %x0,%x1,%x2"
801
  [(set_attr "type" "veccmp")])
802
 
803
(define_insn "*vsx_gt__p"
804
  [(set (reg:CC 74)
805
        (unspec:CC
806
         [(gt:CC (match_operand:VSX_F 1 "vsx_register_operand" ",?wa")
807
                 (match_operand:VSX_F 2 "vsx_register_operand" ",?wa"))]
808
         UNSPEC_PREDICATE))
809
   (set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
810
        (gt:VSX_F (match_dup 1)
811
                  (match_dup 2)))]
812
  "VECTOR_UNIT_VSX_P (mode)"
813
  "xvcmpgt. %x0,%x1,%x2"
814
  [(set_attr "type" "veccmp")])
815
 
816
(define_insn "*vsx_ge__p"
817
  [(set (reg:CC 74)
818
        (unspec:CC
819
         [(ge:CC (match_operand:VSX_F 1 "vsx_register_operand" ",?wa")
820
                 (match_operand:VSX_F 2 "vsx_register_operand" ",?wa"))]
821
         UNSPEC_PREDICATE))
822
   (set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
823
        (ge:VSX_F (match_dup 1)
824
                  (match_dup 2)))]
825
  "VECTOR_UNIT_VSX_P (mode)"
826
  "xvcmpge. %x0,%x1,%x2"
827
  [(set_attr "type" "veccmp")])
828
 
829
;; Vector select
830
(define_insn "*vsx_xxsel"
831
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
832
        (if_then_else:VSX_L
833
         (ne:CC (match_operand:VSX_L 1 "vsx_register_operand" ",wa")
834
                (const_int 0))
835
         (match_operand:VSX_L 2 "vsx_register_operand" ",wa")
836
         (match_operand:VSX_L 3 "vsx_register_operand" ",wa")))]
837
  "VECTOR_MEM_VSX_P (mode)"
838
  "xxsel %x0,%x3,%x2,%x1"
839
  [(set_attr "type" "vecperm")])
840
 
841
(define_insn "*vsx_xxsel_uns"
842
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
843
        (if_then_else:VSX_L
844
         (ne:CCUNS (match_operand:VSX_L 1 "vsx_register_operand" ",wa")
845
                   (const_int 0))
846
         (match_operand:VSX_L 2 "vsx_register_operand" ",wa")
847
         (match_operand:VSX_L 3 "vsx_register_operand" ",wa")))]
848
  "VECTOR_MEM_VSX_P (mode)"
849
  "xxsel %x0,%x3,%x2,%x1"
850
  [(set_attr "type" "vecperm")])
851
 
852
;; Copy sign
853
(define_insn "vsx_copysign3"
854
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
855
        (if_then_else:VSX_B
856
         (ge:VSX_B (match_operand:VSX_B 2 "vsx_register_operand" ",wa")
857
                   (match_operand:VSX_B 3 "zero_constant" "j,j"))
858
         (abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa"))
859
         (neg:VSX_B (abs:VSX_B (match_dup 1)))))]
860
  "VECTOR_UNIT_VSX_P (mode)"
861
  "xcpsgn %x0,%x2,%x1"
862
  [(set_attr "type" "")
863
   (set_attr "fp_type" "")])
864
 
865
;; For the conversions, limit the register class for the integer value to be
866
;; the fprs because we don't want to add the altivec registers to movdi/movsi.
867
;; For the unsigned tests, there isn't a generic double -> unsigned conversion
868
;; in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against VSX.
869
(define_insn "vsx_float2"
870
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
871
        (float:VSX_B (match_operand: 1 "vsx_register_operand" ",")))]
872
  "VECTOR_UNIT_VSX_P (mode)"
873
  "xcvsx %x0,%x1"
874
  [(set_attr "type" "")
875
   (set_attr "fp_type" "")])
876
 
877
(define_insn "vsx_floatuns2"
878
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
879
        (unsigned_float:VSX_B (match_operand: 1 "vsx_register_operand" ",")))]
880
  "VECTOR_UNIT_VSX_P (mode)"
881
  "xcvux %x0,%x1"
882
  [(set_attr "type" "")
883
   (set_attr "fp_type" "")])
884
 
885
(define_insn "vsx_fix_trunc2"
886
  [(set (match_operand: 0 "vsx_register_operand" "=,?")
887
        (fix: (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
888
  "VECTOR_UNIT_VSX_P (mode)"
889
  "xcvsxs %x0,%x1"
890
  [(set_attr "type" "")
891
   (set_attr "fp_type" "")])
892
 
893
(define_insn "vsx_fixuns_trunc2"
894
  [(set (match_operand: 0 "vsx_register_operand" "=,?")
895
        (unsigned_fix: (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
896
  "VECTOR_UNIT_VSX_P (mode)"
897
  "xcvuxs %x0,%x1"
898
  [(set_attr "type" "")
899
   (set_attr "fp_type" "")])
900
 
901
;; Math rounding functions
902
(define_insn "vsx_xri"
903
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
904
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
905
                      UNSPEC_VSX_ROUND_I))]
906
  "VECTOR_UNIT_VSX_P (mode)"
907
  "xri %x0,%x1"
908
  [(set_attr "type" "")
909
   (set_attr "fp_type" "")])
910
 
911
(define_insn "vsx_xric"
912
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
913
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
914
                      UNSPEC_VSX_ROUND_IC))]
915
  "VECTOR_UNIT_VSX_P (mode)"
916
  "xric %x0,%x1"
917
  [(set_attr "type" "")
918
   (set_attr "fp_type" "")])
919
 
920
(define_insn "vsx_btrunc2"
921
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
922
        (fix:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
923
  "VECTOR_UNIT_VSX_P (mode)"
924
  "xriz %x0,%x1"
925
  [(set_attr "type" "")
926
   (set_attr "fp_type" "")])
927
 
928
(define_insn "*vsx_b2trunc2"
929
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
930
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
931
                      UNSPEC_FRIZ))]
932
  "VECTOR_UNIT_VSX_P (mode)"
933
  "xriz %x0,%x1"
934
  [(set_attr "type" "")
935
   (set_attr "fp_type" "")])
936
 
937
(define_insn "vsx_floor2"
938
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
939
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
940
                      UNSPEC_FRIM))]
941
  "VECTOR_UNIT_VSX_P (mode)"
942
  "xrim %x0,%x1"
943
  [(set_attr "type" "")
944
   (set_attr "fp_type" "")])
945
 
946
(define_insn "vsx_ceil2"
947
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
948
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
949
                      UNSPEC_FRIP))]
950
  "VECTOR_UNIT_VSX_P (mode)"
951
  "xrip %x0,%x1"
952
  [(set_attr "type" "")
953
   (set_attr "fp_type" "")])
954
 
955
 
956
;; VSX convert to/from double vector
957
 
958
;; Convert between single and double precision
959
;; Don't use xscvspdp and xscvdpsp for scalar conversions, since the normal
960
;; scalar single precision instructions internally use the double format.
961
;; Prefer the altivec registers, since we likely will need to do a vperm
962
(define_insn "vsx_"
963
  [(set (match_operand: 0 "vsx_register_operand" "=,?wa")
964
        (unspec: [(match_operand:VSX_SPDP 1 "vsx_register_operand" ",wa")]
965
                              UNSPEC_VSX_CVSPDP))]
966
  "VECTOR_UNIT_VSX_P (mode)"
967
  " %x0,%x1"
968
  [(set_attr "type" "")])
969
 
970
;; xscvspdp, represent the scalar SF type as V4SF
971
(define_insn "vsx_xscvspdp"
972
  [(set (match_operand:DF 0 "vsx_register_operand" "=ws,?wa")
973
        (unspec:DF [(match_operand:V4SF 1 "vsx_register_operand" "wa,wa")]
974
                   UNSPEC_VSX_CVSPDP))]
975
  "VECTOR_UNIT_VSX_P (DFmode)"
976
  "xscvspdp %x0,%x1"
977
  [(set_attr "type" "fp")])
978
 
979
;; xscvdpsp used for splat'ing a scalar to V4SF, knowing that the internal SF
980
;; format of scalars is actually DF.
981
(define_insn "vsx_xscvdpsp_scalar"
982
  [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa")
983
        (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "f")]
984
                     UNSPEC_VSX_CVSPDP))]
985
  "VECTOR_UNIT_VSX_P (DFmode)"
986
  "xscvdpsp %x0,%x1"
987
  [(set_attr "type" "fp")])
988
 
989
;; Convert from 64-bit to 32-bit types
990
;; Note, favor the Altivec registers since the usual use of these instructions
991
;; is in vector converts and we need to use the Altivec vperm instruction.
992
 
993
(define_insn "vsx_xvcvdpsxws"
994
  [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
995
        (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
996
                     UNSPEC_VSX_CVDPSXWS))]
997
  "VECTOR_UNIT_VSX_P (V2DFmode)"
998
  "xvcvdpsxws %x0,%x1"
999
  [(set_attr "type" "vecfloat")])
1000
 
1001
(define_insn "vsx_xvcvdpuxws"
1002
  [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
1003
        (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
1004
                     UNSPEC_VSX_CVDPUXWS))]
1005
  "VECTOR_UNIT_VSX_P (V2DFmode)"
1006
  "xvcvdpuxws %x0,%x1"
1007
  [(set_attr "type" "vecfloat")])
1008
 
1009
(define_insn "vsx_xvcvsxdsp"
1010
  [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa")
1011
        (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")]
1012
                     UNSPEC_VSX_CVSXDSP))]
1013
  "VECTOR_UNIT_VSX_P (V2DFmode)"
1014
  "xvcvsxdsp %x0,%x1"
1015
  [(set_attr "type" "vecfloat")])
1016
 
1017
(define_insn "vsx_xvcvuxdsp"
1018
  [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa")
1019
        (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")]
1020
                     UNSPEC_VSX_CVUXDSP))]
1021
  "VECTOR_UNIT_VSX_P (V2DFmode)"
1022
  "xvcvuxwdp %x0,%x1"
1023
  [(set_attr "type" "vecfloat")])
1024
 
1025
;; Convert from 32-bit to 64-bit types
1026
(define_insn "vsx_xvcvsxwdp"
1027
  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
1028
        (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")]
1029
                     UNSPEC_VSX_CVSXWDP))]
1030
  "VECTOR_UNIT_VSX_P (V2DFmode)"
1031
  "xvcvsxwdp %x0,%x1"
1032
  [(set_attr "type" "vecfloat")])
1033
 
1034
(define_insn "vsx_xvcvuxwdp"
1035
  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
1036
        (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")]
1037
                     UNSPEC_VSX_CVUXWDP))]
1038
  "VECTOR_UNIT_VSX_P (V2DFmode)"
1039
  "xvcvuxwdp %x0,%x1"
1040
  [(set_attr "type" "vecfloat")])
1041
 
1042
(define_insn "vsx_xvcvspsxds"
1043
  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
1044
        (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")]
1045
                     UNSPEC_VSX_CVSPSXDS))]
1046
  "VECTOR_UNIT_VSX_P (V2DFmode)"
1047
  "xvcvspsxds %x0,%x1"
1048
  [(set_attr "type" "vecfloat")])
1049
 
1050
(define_insn "vsx_xvcvspuxds"
1051
  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
1052
        (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")]
1053
                     UNSPEC_VSX_CVSPUXDS))]
1054
  "VECTOR_UNIT_VSX_P (V2DFmode)"
1055
  "xvcvspuxds %x0,%x1"
1056
  [(set_attr "type" "vecfloat")])
1057
 
1058
;; Logical and permute operations
1059
(define_insn "*vsx_and3"
1060
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
1061
        (and:VSX_L
1062
         (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")
1063
         (match_operand:VSX_L 2 "vsx_register_operand" ",?wa")))]
1064
  "VECTOR_MEM_VSX_P (mode)"
1065
  "xxland %x0,%x1,%x2"
1066
  [(set_attr "type" "vecsimple")])
1067
 
1068
(define_insn "*vsx_ior3"
1069
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
1070
        (ior:VSX_L (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")
1071
                   (match_operand:VSX_L 2 "vsx_register_operand" ",?wa")))]
1072
  "VECTOR_MEM_VSX_P (mode)"
1073
  "xxlor %x0,%x1,%x2"
1074
  [(set_attr "type" "vecsimple")])
1075
 
1076
(define_insn "*vsx_xor3"
1077
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
1078
        (xor:VSX_L
1079
         (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")
1080
         (match_operand:VSX_L 2 "vsx_register_operand" ",?wa")))]
1081
  "VECTOR_MEM_VSX_P (mode)"
1082
  "xxlxor %x0,%x1,%x2"
1083
  [(set_attr "type" "vecsimple")])
1084
 
1085
(define_insn "*vsx_one_cmpl2"
1086
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
1087
        (not:VSX_L
1088
         (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")))]
1089
  "VECTOR_MEM_VSX_P (mode)"
1090
  "xxlnor %x0,%x1,%x1"
1091
  [(set_attr "type" "vecsimple")])
1092
 
1093
(define_insn "*vsx_nor3"
1094
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
1095
        (not:VSX_L
1096
         (ior:VSX_L
1097
          (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")
1098
          (match_operand:VSX_L 2 "vsx_register_operand" ",?wa"))))]
1099
  "VECTOR_MEM_VSX_P (mode)"
1100
  "xxlnor %x0,%x1,%x2"
1101
  [(set_attr "type" "vecsimple")])
1102
 
1103
(define_insn "*vsx_andc3"
1104
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
1105
        (and:VSX_L
1106
         (not:VSX_L
1107
          (match_operand:VSX_L 2 "vsx_register_operand" ",?wa"))
1108
         (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")))]
1109
  "VECTOR_MEM_VSX_P (mode)"
1110
  "xxlandc %x0,%x1,%x2"
1111
  [(set_attr "type" "vecsimple")])
1112
 
1113
 
1114
;; Permute operations
1115
 
1116
;; Build a V2DF/V2DI vector from two scalars
1117
(define_insn "vsx_concat_"
1118
  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa")
1119
        (unspec:VSX_D
1120
         [(match_operand: 1 "vsx_register_operand" "ws,wa")
1121
          (match_operand: 2 "vsx_register_operand" "ws,wa")]
1122
         UNSPEC_VSX_CONCAT))]
1123
  "VECTOR_MEM_VSX_P (mode)"
1124
  "xxpermdi %x0,%x1,%x2,0"
1125
  [(set_attr "type" "vecperm")])
1126
 
1127
;; Special purpose concat using xxpermdi to glue two single precision values
1128
;; together, relying on the fact that internally scalar floats are represented
1129
;; as doubles.  This is used to initialize a V4SF vector with 4 floats
1130
(define_insn "vsx_concat_v2sf"
1131
  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
1132
        (unspec:V2DF
1133
         [(match_operand:SF 1 "vsx_register_operand" "f,f")
1134
          (match_operand:SF 2 "vsx_register_operand" "f,f")]
1135
         UNSPEC_VSX_CONCAT))]
1136
  "VECTOR_MEM_VSX_P (V2DFmode)"
1137
  "xxpermdi %x0,%x1,%x2,0"
1138
  [(set_attr "type" "vecperm")])
1139
 
1140
;; Set the element of a V2DI/VD2F mode
1141
(define_insn "vsx_set_"
1142
  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa")
1143
        (unspec:VSX_D [(match_operand:VSX_D 1 "vsx_register_operand" "wd,wa")
1144
                       (match_operand: 2 "vsx_register_operand" "ws,wa")
1145
                       (match_operand:QI 3 "u5bit_cint_operand" "i,i")]
1146
                      UNSPEC_VSX_SET))]
1147
  "VECTOR_MEM_VSX_P (mode)"
1148
{
1149
  if (INTVAL (operands[3]) == 0)
1150
    return \"xxpermdi %x0,%x1,%x2,1\";
1151
  else if (INTVAL (operands[3]) == 1)
1152
    return \"xxpermdi %x0,%x2,%x1,0\";
1153
  else
1154
    gcc_unreachable ();
1155
}
1156
  [(set_attr "type" "vecperm")])
1157
 
1158
;; Extract a DF/DI element from V2DF/V2DI
1159
(define_insn "vsx_extract_"
1160
  [(set (match_operand: 0 "vsx_register_operand" "=ws,d,?wa")
1161
        (vec_select: (match_operand:VSX_D 1 "vsx_register_operand" "wd,wd,wa")
1162
                       (parallel
1163
                        [(match_operand:QI 2 "u5bit_cint_operand" "i,i,i")])))]
1164
  "VECTOR_MEM_VSX_P (mode)"
1165
{
1166
  gcc_assert (UINTVAL (operands[2]) <= 1);
1167
  operands[3] = GEN_INT (INTVAL (operands[2]) << 1);
1168
  return \"xxpermdi %x0,%x1,%x1,%3\";
1169
}
1170
  [(set_attr "type" "vecperm")])
1171
 
1172
;; Optimize extracting element 0 from memory
1173
(define_insn "*vsx_extract__zero"
1174
  [(set (match_operand: 0 "vsx_register_operand" "=ws,d,?wa")
1175
        (vec_select:
1176
         (match_operand:VSX_D 1 "indexed_or_indirect_operand" "Z,Z,Z")
1177
         (parallel [(const_int 0)])))]
1178
  "VECTOR_MEM_VSX_P (mode) && WORDS_BIG_ENDIAN"
1179
  "lxsd%U1x %x0,%y1"
1180
  [(set_attr "type" "fpload")
1181
   (set_attr "length" "4")])
1182
 
1183
;; General double word oriented permute, allow the other vector types for
1184
;; optimizing the permute instruction.
1185
(define_insn "vsx_xxpermdi_"
1186
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=wd,?wa")
1187
        (unspec:VSX_L [(match_operand:VSX_L 1 "vsx_register_operand" "wd,wa")
1188
                       (match_operand:VSX_L 2 "vsx_register_operand" "wd,wa")
1189
                       (match_operand:QI 3 "u5bit_cint_operand" "i,i")]
1190
                      UNSPEC_VSX_XXPERMDI))]
1191
  "VECTOR_MEM_VSX_P (mode)"
1192
  "xxpermdi %x0,%x1,%x2,%3"
1193
  [(set_attr "type" "vecperm")])
1194
 
1195
;; Varient of xxpermdi that is emitted by the vec_interleave functions
1196
(define_insn "*vsx_xxpermdi2_"
1197
  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd")
1198
        (vec_concat:VSX_D
1199
         (vec_select:
1200
          (match_operand:VSX_D 1 "vsx_register_operand" "wd")
1201
          (parallel
1202
           [(match_operand:QI 2 "u5bit_cint_operand" "i")]))
1203
         (vec_select:
1204
          (match_operand:VSX_D 3 "vsx_register_operand" "wd")
1205
          (parallel
1206
           [(match_operand:QI 4 "u5bit_cint_operand" "i")]))))]
1207
  "VECTOR_MEM_VSX_P (mode)"
1208
{
1209
  gcc_assert ((UINTVAL (operands[2]) <= 1) && (UINTVAL (operands[4]) <= 1));
1210
  operands[5] = GEN_INT (((INTVAL (operands[2]) & 1) << 1)
1211
                         | (INTVAL (operands[4]) & 1));
1212
  return \"xxpermdi %x0,%x1,%x3,%5\";
1213
}
1214
  [(set_attr "type" "vecperm")])
1215
 
1216
;; V2DF/V2DI splat
1217
(define_insn "vsx_splat_"
1218
  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,wd,wd,?wa,?wa,?wa")
1219
        (vec_duplicate:VSX_D
1220
         (match_operand: 1 "input_operand" "ws,f,Z,wa,wa,Z")))]
1221
  "VECTOR_MEM_VSX_P (mode)"
1222
  "@
1223
   xxpermdi %x0,%x1,%x1,0
1224
   xxpermdi %x0,%x1,%x1,0
1225
   lxvdsx %x0,%y1
1226
   xxpermdi %x0,%x1,%x1,0
1227
   xxpermdi %x0,%x1,%x1,0
1228
   lxvdsx %x0,%y1"
1229
  [(set_attr "type" "vecperm,vecperm,vecload,vecperm,vecperm,vecload")])
1230
 
1231
;; V4SF/V4SI splat
1232
(define_insn "vsx_xxspltw_"
1233
  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
1234
        (vec_duplicate:VSX_W
1235
         (vec_select:
1236
          (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
1237
          (parallel
1238
           [(match_operand:QI 2 "u5bit_cint_operand" "i,i")]))))]
1239
  "VECTOR_MEM_VSX_P (mode)"
1240
  "xxspltw %x0,%x1,%2"
1241
  [(set_attr "type" "vecperm")])
1242
 
1243
;; V4SF/V4SI interleave
1244
(define_insn "vsx_xxmrghw_"
1245
  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
1246
        (vec_merge:VSX_W
1247
         (vec_select:VSX_W
1248
          (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
1249
          (parallel [(const_int 0)
1250
                     (const_int 2)
1251
                     (const_int 1)
1252
                     (const_int 3)]))
1253
         (vec_select:VSX_W
1254
          (match_operand:VSX_W 2 "vsx_register_operand" "wf,wa")
1255
          (parallel [(const_int 2)
1256
                     (const_int 0)
1257
                     (const_int 3)
1258
                     (const_int 1)]))
1259
         (const_int 5)))]
1260
  "VECTOR_MEM_VSX_P (mode)"
1261
  "xxmrghw %x0,%x1,%x2"
1262
  [(set_attr "type" "vecperm")])
1263
 
1264
(define_insn "vsx_xxmrglw_"
1265
  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
1266
        (vec_merge:VSX_W
1267
         (vec_select:VSX_W
1268
          (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
1269
          (parallel [(const_int 2)
1270
                     (const_int 0)
1271
                     (const_int 3)
1272
                     (const_int 1)]))
1273
         (vec_select:VSX_W
1274
          (match_operand:VSX_W 2 "vsx_register_operand" "wf,?wa")
1275
          (parallel [(const_int 0)
1276
                     (const_int 2)
1277
                     (const_int 1)
1278
                     (const_int 3)]))
1279
         (const_int 5)))]
1280
  "VECTOR_MEM_VSX_P (mode)"
1281
  "xxmrglw %x0,%x1,%x2"
1282
  [(set_attr "type" "vecperm")])
1283
 
1284
;; Shift left double by word immediate
1285
(define_insn "vsx_xxsldwi_"
1286
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=wa")
1287
        (unspec:VSX_L [(match_operand:VSX_L 1 "vsx_register_operand" "wa")
1288
                       (match_operand:VSX_L 2 "vsx_register_operand" "wa")
1289
                       (match_operand:QI 3 "u5bit_cint_operand" "i")]
1290
                      UNSPEC_VSX_SLDWI))]
1291
  "VECTOR_MEM_VSX_P (mode)"
1292
  "xxsldwi %x0,%x1,%x2,%3"
1293
  [(set_attr "type" "vecperm")])

powered by: WebSVN 2.1.0

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