OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [spu/] [spu.md] - Blame information for rev 378

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

Line No. Rev Author Line
1 282 jeremybenn
;; Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
2
 
3
;; This file is free software; you can redistribute it and/or modify it under
4
;; the terms of the GNU General Public License as published by the Free
5
;; Software Foundation; either version 3 of the License, or (at your option)
6
;; any later version.
7
 
8
;; This file is distributed in the hope that it will be useful, but WITHOUT
9
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11
;; for more details.
12
 
13
;; You should have received a copy of the GNU General Public License
14
;; along with GCC; see the file COPYING3.  If not see
15
;; .
16
 
17
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
18
 
19
 
20
;; Define an insn type attribute.  This is used in function unit delay
21
;; computations.
22
;; multi0 is a multiple insn rtl whose first insn is in pipe0
23
;; multi1 is a multiple insn rtl whose first insn is in pipe1
24
(define_attr "type" "fx2,shuf,fx3,load,store,br,spr,lnop,nop,fxb,fp6,fp7,fpd,iprefetch,multi0,multi1,hbr,convert"
25
  (const_string "fx2"))
26
 
27
;; Length (in bytes).
28
(define_attr "length" ""
29
                (const_int 4))
30
 
31
(define_attr "tune" "cell,celledp" (const (symbol_ref "spu_tune")))
32
;; Processor type -- this attribute must exactly match the processor_type
33
;; enumeration in spu.h.
34
 
35
(define_attr "cpu" "spu"
36
  (const (symbol_ref "spu_cpu_attr")))
37
 
38
; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
39
;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
40
 
41
(define_cpu_unit "pipe0,pipe1,fp,ls")
42
 
43
(define_insn_reservation "NOP" 1 (eq_attr "type" "nop")
44
    "pipe0")
45
 
46
(define_insn_reservation "FX2" 2 (eq_attr "type" "fx2")
47
    "pipe0, nothing")
48
 
49
(define_insn_reservation "FX3" 4 (eq_attr "type" "fx3,fxb")
50
    "pipe0, nothing*3")
51
 
52
(define_insn_reservation "FP6" 6 (eq_attr "type" "fp6")
53
    "pipe0 + fp, nothing*5")
54
 
55
(define_insn_reservation "FP7" 7 (eq_attr "type" "fp7")
56
    "pipe0, fp, nothing*5")
57
 
58
;; The behavior of the double precision is that both pipes stall
59
;; for 6 cycles and the rest of the operation pipelines for
60
;; 7 cycles.  The simplest way to model this is to simply ignore
61
;; the 6 cyle stall.
62
(define_insn_reservation "FPD" 7
63
  (and (eq_attr "tune" "cell")
64
       (eq_attr "type" "fpd"))
65
    "pipe0 + pipe1, fp, nothing*5")
66
 
67
;; Tune for CELLEDP, 9 cycles, dual-issuable, fully pipelined
68
(define_insn_reservation "FPD_CELLEDP" 9
69
  (and (eq_attr "tune" "celledp")
70
       (eq_attr "type" "fpd"))
71
  "pipe0 + fp, nothing*8")
72
 
73
(define_insn_reservation "LNOP" 1 (eq_attr "type" "lnop")
74
    "pipe1")
75
 
76
(define_insn_reservation "STORE" 1 (eq_attr "type" "store")
77
    "pipe1 + ls")
78
 
79
(define_insn_reservation "IPREFETCH" 1 (eq_attr "type" "iprefetch")
80
    "pipe1 + ls")
81
 
82
(define_insn_reservation "SHUF" 4 (eq_attr "type" "shuf,br,spr")
83
    "pipe1, nothing*3")
84
 
85
(define_insn_reservation "LOAD" 6 (eq_attr "type" "load")
86
    "pipe1 + ls, nothing*5")
87
 
88
(define_insn_reservation "HBR" 18 (eq_attr "type" "hbr")
89
    "pipe1, nothing*15")
90
 
91
(define_insn_reservation "MULTI0" 4 (eq_attr "type" "multi0")
92
    "pipe0+pipe1, nothing*3")
93
 
94
(define_insn_reservation "MULTI1" 4 (eq_attr "type" "multi1")
95
    "pipe1, nothing*3")
96
 
97
(define_insn_reservation "CONVERT" 0 (eq_attr "type" "convert")
98
    "nothing")
99
 
100
;; Force pipe0 to occur before pipe 1 in a cycle.
101
(absence_set "pipe0" "pipe1")
102
 
103
 
104
(define_constants [
105
 (UNSPEC_BLOCKAGE       0)
106
 (UNSPEC_IPREFETCH      1)
107
 (UNSPEC_FREST          2)
108
 (UNSPEC_FRSQEST        3)
109
 (UNSPEC_FI             4)
110
 (UNSPEC_EXTEND_CMP     5)
111
 (UNSPEC_CG             6)
112
 (UNSPEC_CGX            7)
113
 (UNSPEC_ADDX           8)
114
 (UNSPEC_BG             9)
115
 (UNSPEC_BGX            10)
116
 (UNSPEC_SFX            11)
117
 (UNSPEC_FSM            12)
118
 (UNSPEC_HBR            13)
119
 (UNSPEC_LNOP           14)
120
 (UNSPEC_NOP            15)
121
 (UNSPEC_CONVERT        16)
122
 (UNSPEC_SELB           17)
123
 (UNSPEC_SHUFB          18)
124
 (UNSPEC_CPAT           19)
125
 (UNSPEC_SYNC           20)
126
 (UNSPEC_CNTB           21)
127
 (UNSPEC_SUMB           22)
128
 (UNSPEC_FSMB           23)
129
 (UNSPEC_FSMH           24)
130
 (UNSPEC_GBB            25)
131
 (UNSPEC_GBH            26)
132
 (UNSPEC_GB             27)
133
 (UNSPEC_AVGB           28)
134
 (UNSPEC_ABSDB          29)
135
 (UNSPEC_ORX            30)
136
 (UNSPEC_HEQ            31)
137
 (UNSPEC_HGT            32)
138
 (UNSPEC_HLGT           33)
139
 (UNSPEC_STOP           38)
140
 (UNSPEC_STOPD          39)
141
 (UNSPEC_SET_INTR       40)
142
 (UNSPEC_FSCRRD         42)
143
 (UNSPEC_FSCRWR         43)
144
 (UNSPEC_MFSPR          44)
145
 (UNSPEC_MTSPR          45)
146
 (UNSPEC_RDCH           46)
147
 (UNSPEC_RCHCNT         47)
148
 (UNSPEC_WRCH           48)
149
 (UNSPEC_SPU_REALIGN_LOAD 49)
150
 (UNSPEC_SPU_MASK_FOR_LOAD 50)
151
 (UNSPEC_DFTSV           51)
152
 (UNSPEC_FLOAT_EXTEND    52)
153
 (UNSPEC_FLOAT_TRUNCATE  53)
154
 (UNSPEC_SP_SET         54)
155
 (UNSPEC_SP_TEST        55)
156
])
157
 
158
(include "predicates.md")
159
(include "constraints.md")
160
 
161
 
162
;; Mode iterators
163
 
164
(define_mode_iterator ALL [QI V16QI
165
                        HI V8HI
166
                        SI V4SI
167
                        DI V2DI
168
                        TI
169
                        SF V4SF
170
                        DF V2DF])
171
 
172
; Everything except DI and TI which are handled separately because
173
; they need different constraints to correctly test VOIDmode constants
174
(define_mode_iterator MOV [QI V16QI
175
                        HI V8HI
176
                        SI V4SI
177
                        V2DI
178
                        SF V4SF
179
                        DF V2DF])
180
 
181
(define_mode_iterator QHSI  [QI HI SI])
182
(define_mode_iterator QHSDI  [QI HI SI DI])
183
(define_mode_iterator DTI  [DI TI])
184
 
185
(define_mode_iterator VINT [QI V16QI
186
                         HI V8HI
187
                         SI V4SI
188
                         DI V2DI
189
                         TI])
190
 
191
(define_mode_iterator VQHSI [QI V16QI
192
                          HI V8HI
193
                          SI V4SI])
194
 
195
(define_mode_iterator VHSI [HI V8HI
196
                         SI V4SI])
197
 
198
(define_mode_iterator VSDF [SF V4SF
199
                         DF V2DF])
200
 
201
(define_mode_iterator VSI [SI V4SI])
202
(define_mode_iterator VDI [DI V2DI])
203
(define_mode_iterator VSF [SF V4SF])
204
(define_mode_iterator VDF [DF V2DF])
205
 
206
(define_mode_iterator VCMP [V16QI
207
                         V8HI
208
                         V4SI
209
                         V4SF
210
                         V2DF])
211
 
212
(define_mode_iterator VCMPU [V16QI
213
                          V8HI
214
                          V4SI])
215
 
216
(define_mode_attr v      [(V8HI  "v") (V4SI  "v")
217
                          (HI    "") (SI    "")])
218
 
219
(define_mode_attr bh  [(QI "b")  (V16QI "b")
220
                       (HI "h")  (V8HI "h")
221
                       (SI "")   (V4SI "")])
222
 
223
(define_mode_attr d   [(SF "")   (V4SF "")
224
                       (DF "d")  (V2DF "d")])
225
(define_mode_attr d6  [(SF "6")  (V4SF "6")
226
                       (DF "d")  (V2DF "d")])
227
 
228
(define_mode_attr f2i [(SF "si") (V4SF "v4si")
229
                       (DF "di") (V2DF "v2di")])
230
(define_mode_attr F2I [(SF "SI") (V4SF "V4SI")
231
                       (DF "DI") (V2DF "V2DI")])
232
(define_mode_attr i2f [(SI "sf") (V4SI "v4sf")
233
                       (DI "df") (V2DI "v2df")])
234
(define_mode_attr I2F [(SI "SF") (V4SI "V4SF")
235
                       (DI "DF") (V2DI "V2DF")])
236
 
237
(define_mode_attr DF2I [(DF "SI") (V2DF "V2DI")])
238
 
239
(define_mode_attr umask  [(HI "f")  (V8HI "f")
240
                          (SI "g")  (V4SI "g")])
241
(define_mode_attr nmask  [(HI "F")  (V8HI "F")
242
                          (SI "G")  (V4SI "G")])
243
 
244
;; Used for carry and borrow instructions.
245
(define_mode_iterator CBOP  [SI DI V4SI V2DI])
246
 
247
;; Used in vec_set and vec_extract
248
(define_mode_iterator V [V2DI V4SI V8HI V16QI V2DF V4SF])
249
(define_mode_attr inner  [(V16QI "QI")
250
                          (V8HI  "HI")
251
                          (V4SI  "SI")
252
                          (V2DI  "DI")
253
                          (V4SF  "SF")
254
                          (V2DF  "DF")])
255
(define_mode_attr vmult  [(V16QI "1")
256
                          (V8HI  "2")
257
                          (V4SI  "4")
258
                          (V2DI  "8")
259
                          (V4SF  "4")
260
                          (V2DF  "8")])
261
(define_mode_attr voff   [(V16QI "13")
262
                          (V8HI  "14")
263
                          (V4SI  "0")
264
                          (V2DI  "0")
265
                          (V4SF  "0")
266
                          (V2DF  "0")])
267
 
268
 
269
;; mov
270
 
271
(define_expand "mov"
272
  [(set (match_operand:ALL 0 "spu_nonimm_operand" "=r,r,r,m")
273
        (match_operand:ALL 1 "general_operand" "r,i,m,r"))]
274
  ""
275
  {
276
    if (spu_expand_mov(operands, mode))
277
      DONE;
278
  })
279
 
280
(define_split
281
  [(set (match_operand 0 "spu_reg_operand")
282
        (match_operand 1 "immediate_operand"))]
283
 
284
  ""
285
  [(set (match_dup 0)
286
        (high (match_dup 1)))
287
   (set (match_dup 0)
288
        (lo_sum (match_dup 0)
289
                (match_dup 1)))]
290
  {
291
    if (spu_split_immediate (operands))
292
      DONE;
293
    FAIL;
294
  })
295
 
296
(define_insn "pic"
297
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
298
        (match_operand:SI 1 "immediate_operand" "s"))
299
   (use (const_int 0))]
300
  "flag_pic"
301
  "ila\t%0,%%pic(%1)")
302
 
303
;; Whenever a function generates the 'pic' pattern above we need to
304
;; load the pic_offset_table register.
305
;; GCC doesn't deal well with labels in the middle of a block so we
306
;; hardcode the offsets in the asm here.
307
(define_insn "load_pic_offset"
308
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
309
        (unspec:SI [(const_int 0)] 0))
310
   (set (match_operand:SI 1 "spu_reg_operand" "=r")
311
        (unspec:SI [(const_int 0)] 0))]
312
  "flag_pic"
313
  "ila\t%1,.+8\;brsl\t%0,4"
314
  [(set_attr "length" "8")
315
   (set_attr "type" "multi0")])
316
 
317
 
318
;; move internal
319
 
320
(define_insn "_mov"
321
  [(set (match_operand:MOV 0 "spu_dest_operand" "=r,r,r,r,r,m")
322
        (match_operand:MOV 1 "spu_mov_operand" "r,A,f,j,m,r"))]
323
  "register_operand(operands[0], mode)
324
   || register_operand(operands[1], mode)"
325
  "@
326
   ori\t%0,%1,0
327
   il%s1\t%0,%S1
328
   fsmbi\t%0,%S1
329
   c%s1d\t%0,%S1($sp)
330
   lq%p1\t%0,%1
331
   stq%p0\t%1,%0"
332
  [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
333
 
334
(define_insn "low_"
335
  [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
336
        (lo_sum:VSI (match_operand:VSI 1 "spu_reg_operand" "0")
337
                    (match_operand:VSI 2 "immediate_operand" "i")))]
338
  ""
339
  "iohl\t%0,%2@l")
340
 
341
(define_insn "_movdi"
342
  [(set (match_operand:DI 0 "spu_dest_operand" "=r,r,r,r,r,m")
343
        (match_operand:DI 1 "spu_mov_operand" "r,a,f,k,m,r"))]
344
  "register_operand(operands[0], DImode)
345
   || register_operand(operands[1], DImode)"
346
  "@
347
   ori\t%0,%1,0
348
   il%d1\t%0,%D1
349
   fsmbi\t%0,%D1
350
   c%d1d\t%0,%D1($sp)
351
   lq%p1\t%0,%1
352
   stq%p0\t%1,%0"
353
  [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
354
 
355
(define_insn "_movti"
356
  [(set (match_operand:TI 0 "spu_dest_operand" "=r,r,r,r,r,m")
357
        (match_operand:TI 1 "spu_mov_operand" "r,U,f,l,m,r"))]
358
  "register_operand(operands[0], TImode)
359
   || register_operand(operands[1], TImode)"
360
  "@
361
   ori\t%0,%1,0
362
   il%t1\t%0,%T1
363
   fsmbi\t%0,%T1
364
   c%t1d\t%0,%T1($sp)
365
   lq%p1\t%0,%1
366
   stq%p0\t%1,%0"
367
  [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
368
 
369
(define_split
370
  [(set (match_operand 0 "spu_reg_operand")
371
        (match_operand 1 "memory_operand"))]
372
  "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
373
   && GET_MODE(operands[0]) == GET_MODE(operands[1])
374
   && !reload_in_progress && !reload_completed"
375
  [(set (match_dup 0)
376
        (match_dup 1))]
377
  { if (spu_split_load(operands))
378
      DONE;
379
  })
380
 
381
(define_split
382
  [(set (match_operand 0 "memory_operand")
383
        (match_operand 1 "spu_reg_operand"))]
384
  "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
385
   && GET_MODE(operands[0]) == GET_MODE(operands[1])
386
   && !reload_in_progress && !reload_completed"
387
  [(set (match_dup 0)
388
        (match_dup 1))]
389
  { if (spu_split_store(operands))
390
      DONE;
391
  })
392
;; Operand 3 is the number of bytes. 1:b 2:h 4:w 8:d
393
 
394
(define_expand "cpat"
395
  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
396
        (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
397
                    (match_operand:SI 2 "spu_nonmem_operand" "r,n")
398
                    (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
399
  ""
400
  {
401
    rtx x = gen_cpat_const (operands);
402
    if (x)
403
      {
404
        emit_move_insn (operands[0], x);
405
        DONE;
406
      }
407
  })
408
 
409
(define_insn "_cpat"
410
  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
411
        (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
412
                    (match_operand:SI 2 "spu_nonmem_operand" "r,n")
413
                    (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
414
  ""
415
  "@
416
   c%M3x\t%0,%1,%2
417
   c%M3d\t%0,%C2(%1)"
418
  [(set_attr "type" "shuf")])
419
 
420
(define_split
421
  [(set (match_operand:TI 0 "spu_reg_operand")
422
        (unspec:TI [(match_operand:SI 1 "spu_nonmem_operand")
423
                    (match_operand:SI 2 "immediate_operand")
424
                    (match_operand:SI 3 "immediate_operand")] UNSPEC_CPAT))]
425
  ""
426
  [(set (match_dup:TI 0)
427
        (match_dup:TI 4))]
428
  {
429
    operands[4] = gen_cpat_const (operands);
430
    if (!operands[4])
431
      FAIL;
432
  })
433
 
434
;; extend
435
 
436
(define_insn "extendqihi2"
437
  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
438
        (sign_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
439
  ""
440
  "xsbh\t%0,%1")
441
 
442
(define_insn "extendhisi2"
443
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
444
        (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))]
445
  ""
446
  "xshw\t%0,%1")
447
 
448
(define_expand "extendsidi2"
449
  [(set (match_dup:DI 2)
450
        (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "")))
451
   (set (match_operand:DI 0 "spu_reg_operand" "")
452
        (sign_extend:DI (vec_select:SI (match_dup:V2SI 3)
453
                                       (parallel [(const_int 1)]))))]
454
  ""
455
  {
456
    operands[2] = gen_reg_rtx (DImode);
457
    operands[3] = spu_gen_subreg (V2SImode, operands[2]);
458
  })
459
 
460
(define_insn "xswd"
461
  [(set (match_operand:DI 0 "spu_reg_operand" "=r")
462
        (sign_extend:DI
463
          (vec_select:SI
464
            (match_operand:V2SI 1 "spu_reg_operand" "r")
465
            (parallel [(const_int 1) ]))))]
466
  ""
467
  "xswd\t%0,%1");
468
 
469
;; By splitting this late we don't allow much opportunity for sharing of
470
;; constants.  That's ok because this should really be optimized away.
471
(define_insn_and_split "extendti2"
472
  [(set (match_operand:TI 0 "register_operand" "")
473
        (sign_extend:TI (match_operand:QHSDI 1 "register_operand" "")))]
474
  ""
475
  "#"
476
  ""
477
  [(set (match_dup:TI 0)
478
        (sign_extend:TI (match_dup:QHSDI 1)))]
479
  {
480
    spu_expand_sign_extend(operands);
481
    DONE;
482
  })
483
 
484
 
485
;; zero_extend
486
 
487
(define_insn "zero_extendqihi2"
488
  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
489
        (zero_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
490
  ""
491
  "andi\t%0,%1,0x00ff")
492
 
493
(define_insn "zero_extendqisi2"
494
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
495
        (zero_extend:SI (match_operand:QI 1 "spu_reg_operand" "r")))]
496
  ""
497
  "andi\t%0,%1,0x00ff")
498
 
499
(define_expand "zero_extendhisi2"
500
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
501
        (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))
502
   (clobber (match_scratch:SI 2 "=&r"))]
503
  ""
504
  {
505
    rtx mask = gen_reg_rtx (SImode);
506
    rtx op1 = simplify_gen_subreg (SImode, operands[1], HImode, 0);
507
    emit_move_insn (mask, GEN_INT (0xffff));
508
    emit_insn (gen_andsi3(operands[0], op1, mask));
509
    DONE;
510
  })
511
 
512
(define_insn "zero_extendsidi2"
513
  [(set (match_operand:DI 0 "spu_reg_operand" "=r")
514
        (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "r")))]
515
  ""
516
  "rotqmbyi\t%0,%1,-4"
517
  [(set_attr "type" "shuf")])
518
 
519
(define_insn "zero_extendqiti2"
520
  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
521
        (zero_extend:TI (match_operand:QI 1 "spu_reg_operand" "r")))]
522
  ""
523
  "andi\t%0,%1,0x00ff\;rotqmbyi\t%0,%0,-12"
524
  [(set_attr "type" "multi0")
525
   (set_attr "length" "8")])
526
 
527
(define_insn "zero_extendhiti2"
528
  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
529
        (zero_extend:TI (match_operand:HI 1 "spu_reg_operand" "r")))]
530
  ""
531
  "shli\t%0,%1,16\;rotqmbyi\t%0,%0,-14"
532
  [(set_attr "type" "multi1")
533
   (set_attr "length" "8")])
534
 
535
(define_insn "zero_extendsiti2"
536
  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
537
        (zero_extend:TI (match_operand:SI 1 "spu_reg_operand" "r")))]
538
  ""
539
  "rotqmbyi\t%0,%1,-12"
540
  [(set_attr "type" "shuf")])
541
 
542
(define_insn "zero_extendditi2"
543
  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
544
        (zero_extend:TI (match_operand:DI 1 "spu_reg_operand" "r")))]
545
  ""
546
  "rotqmbyi\t%0,%1,-8"
547
  [(set_attr "type" "shuf")])
548
 
549
 
550
;; trunc
551
 
552
(define_insn "truncdiqi2"
553
  [(set (match_operand:QI 0 "spu_reg_operand" "=r")
554
        (truncate:QI (match_operand:DI 1 "spu_reg_operand" "r")))]
555
  ""
556
  "shlqbyi\t%0,%1,4"
557
  [(set_attr "type" "shuf")])
558
 
559
(define_insn "truncdihi2"
560
  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
561
        (truncate:HI (match_operand:DI 1 "spu_reg_operand" "r")))]
562
  ""
563
  "shlqbyi\t%0,%1,4"
564
  [(set_attr "type" "shuf")])
565
 
566
(define_insn "truncdisi2"
567
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
568
        (truncate:SI (match_operand:DI 1 "spu_reg_operand" "r")))]
569
  ""
570
  "shlqbyi\t%0,%1,4"
571
  [(set_attr "type" "shuf")])
572
 
573
(define_insn "trunctiqi2"
574
  [(set (match_operand:QI 0 "spu_reg_operand" "=r")
575
        (truncate:QI (match_operand:TI 1 "spu_reg_operand" "r")))]
576
  ""
577
  "shlqbyi\t%0,%1,12"
578
  [(set_attr "type" "shuf")])
579
 
580
(define_insn "trunctihi2"
581
  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
582
        (truncate:HI (match_operand:TI 1 "spu_reg_operand" "r")))]
583
  ""
584
  "shlqbyi\t%0,%1,12"
585
  [(set_attr "type" "shuf")])
586
 
587
(define_insn "trunctisi2"
588
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
589
        (truncate:SI (match_operand:TI 1 "spu_reg_operand" "r")))]
590
  ""
591
  "shlqbyi\t%0,%1,12"
592
  [(set_attr "type" "shuf")])
593
 
594
(define_insn "trunctidi2"
595
  [(set (match_operand:DI 0 "spu_reg_operand" "=r")
596
        (truncate:DI (match_operand:TI 1 "spu_reg_operand" "r")))]
597
  ""
598
  "shlqbyi\t%0,%1,8"
599
  [(set_attr "type" "shuf")])
600
 
601
 
602
;; float conversions
603
 
604
(define_insn "float2"
605
  [(set (match_operand: 0 "spu_reg_operand" "=r")
606
        (float: (match_operand:VSI 1 "spu_reg_operand" "r")))]
607
  ""
608
  "csflt\t%0,%1,0"
609
  [(set_attr "type" "fp7")])
610
 
611
(define_insn "fix_trunc2"
612
  [(set (match_operand: 0 "spu_reg_operand" "=r")
613
        (fix: (match_operand:VSF 1 "spu_reg_operand" "r")))]
614
  ""
615
  "cflts\t%0,%1,0"
616
  [(set_attr "type" "fp7")])
617
 
618
(define_insn "floatuns2"
619
  [(set (match_operand: 0 "spu_reg_operand" "=r")
620
        (unsigned_float: (match_operand:VSI 1 "spu_reg_operand" "r")))]
621
  ""
622
  "cuflt\t%0,%1,0"
623
  [(set_attr "type" "fp7")])
624
 
625
(define_insn "fixuns_trunc2"
626
  [(set (match_operand: 0 "spu_reg_operand" "=r")
627
        (unsigned_fix: (match_operand:VSF 1 "spu_reg_operand" "r")))]
628
  ""
629
  "cfltu\t%0,%1,0"
630
  [(set_attr "type" "fp7")])
631
 
632
(define_insn "float2_mul"
633
  [(set (match_operand: 0 "spu_reg_operand" "=r")
634
        (mult: (float: (match_operand:VSI 1 "spu_reg_operand" "r"))
635
                    (match_operand: 2 "spu_inv_exp2_operand" "w")))]
636
  ""
637
  "csflt\t%0,%1,%w2"
638
  [(set_attr "type" "fp7")])
639
 
640
(define_insn "float2_div"
641
  [(set (match_operand: 0 "spu_reg_operand" "=r")
642
        (div: (float: (match_operand:VSI 1 "spu_reg_operand" "r"))
643
                   (match_operand: 2 "spu_exp2_operand" "v")))]
644
  ""
645
  "csflt\t%0,%1,%v2"
646
  [(set_attr "type" "fp7")])
647
 
648
 
649
(define_insn "fix_trunc2_mul"
650
  [(set (match_operand: 0 "spu_reg_operand" "=r")
651
        (fix: (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
652
                             (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
653
  ""
654
  "cflts\t%0,%1,%v2"
655
  [(set_attr "type" "fp7")])
656
 
657
(define_insn "floatuns2_mul"
658
  [(set (match_operand: 0 "spu_reg_operand" "=r")
659
        (mult: (unsigned_float: (match_operand:VSI 1 "spu_reg_operand" "r"))
660
                    (match_operand: 2 "spu_inv_exp2_operand" "w")))]
661
  ""
662
  "cuflt\t%0,%1,%w2"
663
  [(set_attr "type" "fp7")])
664
 
665
(define_insn "floatuns2_div"
666
  [(set (match_operand: 0 "spu_reg_operand" "=r")
667
        (div: (unsigned_float: (match_operand:VSI 1 "spu_reg_operand" "r"))
668
                   (match_operand: 2 "spu_exp2_operand" "v")))]
669
  ""
670
  "cuflt\t%0,%1,%v2"
671
  [(set_attr "type" "fp7")])
672
 
673
(define_insn "fixuns_trunc2_mul"
674
  [(set (match_operand: 0 "spu_reg_operand" "=r")
675
        (unsigned_fix: (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
676
                                      (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
677
  ""
678
  "cfltu\t%0,%1,%v2"
679
  [(set_attr "type" "fp7")])
680
 
681
(define_insn "extendsfdf2"
682
  [(set (match_operand:DF 0 "spu_reg_operand" "=r")
683
        (unspec:DF [(match_operand:SF 1 "spu_reg_operand" "r")]
684
                   UNSPEC_FLOAT_EXTEND))]
685
  ""
686
  "fesd\t%0,%1"
687
  [(set_attr "type" "fpd")])
688
 
689
(define_insn "truncdfsf2"
690
  [(set (match_operand:SF 0 "spu_reg_operand" "=r")
691
        (unspec:SF [(match_operand:DF 1 "spu_reg_operand" "r")]
692
                   UNSPEC_FLOAT_TRUNCATE))]
693
  ""
694
  "frds\t%0,%1"
695
  [(set_attr "type" "fpd")])
696
 
697
(define_expand "floatdisf2"
698
  [(set (match_operand:SF 0 "register_operand" "")
699
        (float:SF (match_operand:DI 1 "register_operand" "")))]
700
  ""
701
  {
702
    rtx c0 = gen_reg_rtx (SImode);
703
    rtx r0 = gen_reg_rtx (DImode);
704
    rtx r1 = gen_reg_rtx (SFmode);
705
    rtx r2 = gen_reg_rtx (SImode);
706
    rtx setneg = gen_reg_rtx (SImode);
707
    rtx isneg = gen_reg_rtx (SImode);
708
    rtx neg = gen_reg_rtx (DImode);
709
    rtx mask = gen_reg_rtx (DImode);
710
 
711
    emit_move_insn (c0, GEN_INT (-0x80000000ll));
712
 
713
    emit_insn (gen_negdi2 (neg, operands[1]));
714
    emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
715
    emit_insn (gen_extend_compare (mask, isneg));
716
    emit_insn (gen_selb (r0, neg, operands[1], mask));
717
    emit_insn (gen_andc_si (setneg, c0, isneg));
718
 
719
    emit_insn (gen_floatunsdisf2 (r1, r0));
720
 
721
    emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg));
722
    emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0));
723
    DONE;
724
  })
725
 
726
(define_insn_and_split "floatunsdisf2"
727
  [(set (match_operand:SF 0 "register_operand" "=r")
728
        (unsigned_float:SF (match_operand:DI 1 "register_operand" "r")))
729
   (clobber (match_scratch:SF 2 "=r"))
730
   (clobber (match_scratch:SF 3 "=r"))
731
   (clobber (match_scratch:SF 4 "=r"))]
732
  ""
733
  "#"
734
  "reload_completed"
735
  [(set (match_dup:SF 0)
736
        (unsigned_float:SF (match_dup:DI 1)))]
737
  {
738
    rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1]));
739
    rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2]));
740
    rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2]));
741
    rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3]));
742
 
743
    REAL_VALUE_TYPE scale;
744
    real_2expN (&scale, 32, SFmode);
745
 
746
    emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si));
747
    emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4)));
748
 
749
    emit_move_insn (operands[4],
750
                    CONST_DOUBLE_FROM_REAL_VALUE (scale, SFmode));
751
    emit_insn (gen_fma_sf (operands[0],
752
                           operands[2], operands[4], operands[3]));
753
    DONE;
754
  })
755
 
756
;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
757
(define_expand "floatsidf2"
758
  [(set (match_operand:DF 0 "register_operand" "")
759
        (float:DF (match_operand:SI 1 "register_operand" "")))]
760
  ""
761
  {
762
    rtx c0 = gen_reg_rtx (SImode);
763
    rtx c1 = gen_reg_rtx (DFmode);
764
    rtx r0 = gen_reg_rtx (SImode);
765
    rtx r1 = gen_reg_rtx (DFmode);
766
 
767
    emit_move_insn (c0, GEN_INT (-0x80000000ll));
768
    emit_move_insn (c1, spu_float_const ("2147483648", DFmode));
769
    emit_insn (gen_xorsi3 (r0, operands[1], c0));
770
    emit_insn (gen_floatunssidf2 (r1, r0));
771
    emit_insn (gen_subdf3 (operands[0], r1, c1));
772
    DONE;
773
  })
774
 
775
(define_expand "floatunssidf2"
776
  [(set (match_operand:DF 0 "register_operand"  "=r")
777
        (unsigned_float:DF (match_operand:SI 1 "register_operand"   "r")))]
778
  ""
779
  "{
780
    rtx value, insns;
781
    rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
782
                                             0x06071415, 0x16178080);
783
    rtx r0 = gen_reg_rtx (V16QImode);
784
 
785
    if (optimize_size)
786
    {
787
       start_sequence ();
788
       value =
789
         emit_library_call_value (convert_optab_libfunc (ufloat_optab,
790
                                                         DFmode, SImode),
791
                   NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], SImode);
792
       insns = get_insns ();
793
       end_sequence ();
794
       emit_libcall_block (insns, operands[0], value,
795
                           gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
796
     }
797
     else
798
     {
799
      emit_move_insn (r0, c0);
800
      emit_insn (gen_floatunssidf2_internal (operands[0], operands[1], r0));
801
     }
802
    DONE;
803
  }")
804
 
805
(define_insn_and_split "floatunssidf2_internal"
806
  [(set (match_operand:DF 0 "register_operand"  "=r")
807
        (unsigned_float:DF (match_operand:SI 1 "register_operand"   "r")))
808
   (use (match_operand:V16QI 2 "register_operand" "r"))
809
   (clobber (match_scratch:V4SI 3 "=&r"))
810
   (clobber (match_scratch:V4SI 4 "=&r"))
811
   (clobber (match_scratch:V4SI 5 "=&r"))
812
   (clobber (match_scratch:V4SI 6 "=&r"))]
813
  ""
814
  "clz\t%3,%1\;il\t%6,1023+31\;shl\t%4,%1,%3\;ceqi\t%5,%3,32\;sf\t%6,%3,%6\;a\t%4,%4,%4\;andc\t%6,%6,%5\;shufb\t%6,%6,%4,%2\;shlqbii\t%0,%6,4"
815
  "reload_completed"
816
  [(set (match_dup:DF 0)
817
        (unsigned_float:DF (match_dup:SI 1)))]
818
 "{
819
    rtx *ops = operands;
820
    rtx op1_v4si = gen_rtx_REG(V4SImode, REGNO(ops[1]));
821
    rtx op0_ti = gen_rtx_REG (TImode, REGNO (ops[0]));
822
    rtx op2_ti = gen_rtx_REG (TImode, REGNO (ops[2]));
823
    rtx op6_ti = gen_rtx_REG (TImode, REGNO (ops[6]));
824
    emit_insn (gen_clzv4si2 (ops[3],op1_v4si));
825
    emit_move_insn (ops[6], spu_const (V4SImode, 1023+31));
826
    emit_insn (gen_vashlv4si3 (ops[4],op1_v4si,ops[3]));
827
    emit_insn (gen_ceq_v4si (ops[5],ops[3],spu_const (V4SImode, 32)));
828
    emit_insn (gen_subv4si3 (ops[6],ops[6],ops[3]));
829
    emit_insn (gen_addv4si3 (ops[4],ops[4],ops[4]));
830
    emit_insn (gen_andc_v4si  (ops[6],ops[6],ops[5]));
831
    emit_insn (gen_shufb (ops[6],ops[6],ops[4],op2_ti));
832
    emit_insn (gen_shlqbi_ti (op0_ti,op6_ti,GEN_INT(4)));
833
    DONE;
834
  }"
835
 [(set_attr "length" "32")])
836
 
837
(define_expand "floatdidf2"
838
  [(set (match_operand:DF 0 "register_operand" "")
839
        (float:DF (match_operand:DI 1 "register_operand" "")))]
840
  ""
841
  {
842
    rtx c0 = gen_reg_rtx (DImode);
843
    rtx r0 = gen_reg_rtx (DImode);
844
    rtx r1 = gen_reg_rtx (DFmode);
845
    rtx r2 = gen_reg_rtx (DImode);
846
    rtx setneg = gen_reg_rtx (DImode);
847
    rtx isneg = gen_reg_rtx (SImode);
848
    rtx neg = gen_reg_rtx (DImode);
849
    rtx mask = gen_reg_rtx (DImode);
850
 
851
    emit_move_insn (c0, GEN_INT (0x8000000000000000ull));
852
 
853
    emit_insn (gen_negdi2 (neg, operands[1]));
854
    emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
855
    emit_insn (gen_extend_compare (mask, isneg));
856
    emit_insn (gen_selb (r0, neg, operands[1], mask));
857
    emit_insn (gen_andc_di (setneg, c0, mask));
858
 
859
    emit_insn (gen_floatunsdidf2 (r1, r0));
860
 
861
    emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg));
862
    emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0));
863
    DONE;
864
  })
865
 
866
(define_expand "floatunsdidf2"
867
  [(set (match_operand:DF 0 "register_operand"  "=r")
868
        (unsigned_float:DF (match_operand:DI 1 "register_operand"   "r")))]
869
  ""
870
  "{
871
    rtx value, insns;
872
    rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
873
                                             0x06071415, 0x16178080);
874
    rtx c1 = spu_const_from_ints (V4SImode, 1023+63, 1023+31, 0, 0);
875
    rtx r0 = gen_reg_rtx (V16QImode);
876
    rtx r1 = gen_reg_rtx (V4SImode);
877
 
878
    if (optimize_size)
879
    {
880
      start_sequence ();
881
      value =
882
         emit_library_call_value (convert_optab_libfunc (ufloat_optab,
883
                                                         DFmode, DImode),
884
                   NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], DImode);
885
      insns = get_insns ();
886
      end_sequence ();
887
      emit_libcall_block (insns, operands[0], value,
888
                          gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
889
    }
890
    else
891
    {
892
      emit_move_insn (r1, c1);
893
      emit_move_insn (r0, c0);
894
      emit_insn (gen_floatunsdidf2_internal (operands[0], operands[1], r0, r1));
895
    }
896
    DONE;
897
  }")
898
 
899
(define_insn_and_split "floatunsdidf2_internal"
900
  [(set (match_operand:DF 0 "register_operand"  "=r")
901
        (unsigned_float:DF (match_operand:DI 1 "register_operand"   "r")))
902
   (use (match_operand:V16QI 2 "register_operand" "r"))
903
   (use (match_operand:V4SI 3 "register_operand" "r"))
904
   (clobber (match_scratch:V4SI 4 "=&r"))
905
   (clobber (match_scratch:V4SI 5 "=&r"))
906
   (clobber (match_scratch:V4SI 6 "=&r"))]
907
  ""
908
  "clz\t%4,%1\;shl\t%5,%1,%4\;ceqi\t%6,%4,32\;sf\t%4,%4,%3\;a\t%5,%5,%5\;andc\t%4,%4,%6\;shufb\t%4,%4,%5,%2\;shlqbii\t%4,%4,4\;shlqbyi\t%5,%4,8\;dfa\t%0,%4,%5"
909
  "reload_completed"
910
  [(set (match_operand:DF 0 "register_operand"  "=r")
911
        (unsigned_float:DF (match_operand:DI 1 "register_operand"   "r")))]
912
  "{
913
    rtx *ops = operands;
914
    rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO(ops[1]));
915
    rtx op2_ti = gen_rtx_REG (TImode, REGNO(ops[2]));
916
    rtx op4_ti = gen_rtx_REG (TImode, REGNO(ops[4]));
917
    rtx op5_ti = gen_rtx_REG (TImode, REGNO(ops[5]));
918
    rtx op4_df = gen_rtx_REG (DFmode, REGNO(ops[4]));
919
    rtx op5_df = gen_rtx_REG (DFmode, REGNO(ops[5]));
920
    emit_insn (gen_clzv4si2 (ops[4],op1_v4si));
921
    emit_insn (gen_vashlv4si3 (ops[5],op1_v4si,ops[4]));
922
    emit_insn (gen_ceq_v4si (ops[6],ops[4],spu_const (V4SImode, 32)));
923
    emit_insn (gen_subv4si3 (ops[4],ops[3],ops[4]));
924
    emit_insn (gen_addv4si3 (ops[5],ops[5],ops[5]));
925
    emit_insn (gen_andc_v4si (ops[4],ops[4],ops[6]));
926
    emit_insn (gen_shufb (ops[4],ops[4],ops[5],op2_ti));
927
    emit_insn (gen_shlqbi_ti (op4_ti,op4_ti,GEN_INT(4)));
928
    emit_insn (gen_shlqby_ti (op5_ti,op4_ti,GEN_INT(8)));
929
    emit_insn (gen_adddf3 (ops[0],op4_df,op5_df));
930
    DONE;
931
  }"
932
  [(set_attr "length" "40")])
933
 
934
 
935
;; add
936
 
937
(define_expand "addv16qi3"
938
  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
939
        (plus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
940
                    (match_operand:V16QI 2 "spu_reg_operand" "r")))]
941
  ""
942
  "{
943
    rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
944
    rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
945
    rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
946
    rtx rhs_and = gen_reg_rtx (V8HImode);
947
    rtx hi_char = gen_reg_rtx (V8HImode);
948
    rtx lo_char = gen_reg_rtx (V8HImode);
949
    rtx mask = gen_reg_rtx (V8HImode);
950
 
951
    emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
952
    emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
953
    emit_insn (gen_addv8hi3 (hi_char, lhs_short, rhs_and));
954
    emit_insn (gen_addv8hi3 (lo_char, lhs_short, rhs_short));
955
    emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
956
    DONE;
957
   }")
958
 
959
(define_insn "add3"
960
  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
961
        (plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
962
                   (match_operand:VHSI 2 "spu_arith_operand" "r,B")))]
963
  ""
964
  "@
965
  a\t%0,%1,%2
966
  ai\t%0,%1,%2")
967
 
968
(define_expand "add3"
969
  [(set (match_dup:VDI 3)
970
        (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
971
                     (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG))
972
   (set (match_dup:VDI 5)
973
        (unspec:VDI [(match_dup 3)
974
                     (match_dup 3)
975
                     (match_dup:TI 4)] UNSPEC_SHUFB))
976
   (set (match_operand:VDI 0 "spu_reg_operand" "")
977
        (unspec:VDI [(match_dup 1)
978
                     (match_dup 2)
979
                     (match_dup 5)] UNSPEC_ADDX))]
980
  ""
981
  {
982
    unsigned char pat[16] = {
983
      0x04, 0x05, 0x06, 0x07,
984
      0x80, 0x80, 0x80, 0x80,
985
      0x0c, 0x0d, 0x0e, 0x0f,
986
      0x80, 0x80, 0x80, 0x80
987
    };
988
    operands[3] = gen_reg_rtx (mode);
989
    operands[4] = gen_reg_rtx (TImode);
990
    operands[5] = gen_reg_rtx (mode);
991
    emit_move_insn (operands[4], array_to_constant (TImode, pat));
992
  })
993
 
994
(define_insn "cg_"
995
  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
996
        (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
997
                      (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))]
998
  "operands"
999
  "cg\t%0,%1,%2")
1000
 
1001
(define_insn "cgx_"
1002
  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1003
        (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1004
                      (match_operand 2 "spu_reg_operand" "r")
1005
                      (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))]
1006
  "operands"
1007
  "cgx\t%0,%1,%2")
1008
 
1009
(define_insn "addx_"
1010
  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1011
        (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1012
                      (match_operand 2 "spu_reg_operand" "r")
1013
                      (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))]
1014
  "operands"
1015
  "addx\t%0,%1,%2")
1016
 
1017
 
1018
;; This is not the most efficient implementation of addti3.
1019
;; We include this here because 1) the compiler needs it to be
1020
;; defined as the word size is 128-bit and 2) sometimes gcc
1021
;; substitutes an add for a constant left-shift. 2) is unlikely
1022
;; because we also give addti3 a high cost. In case gcc does
1023
;; generate TImode add, here is the code to do it.
1024
;; operand 2 is a nonmemory because the compiler requires it.
1025
(define_insn "addti3"
1026
  [(set (match_operand:TI 0 "spu_reg_operand" "=&r")
1027
        (plus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1028
                 (match_operand:TI 2 "spu_nonmem_operand" "r")))
1029
   (clobber (match_scratch:TI 3 "=&r"))]
1030
  ""
1031
  "cg\t%3,%1,%2\n\\
1032
   shlqbyi\t%3,%3,4\n\\
1033
   cgx\t%3,%1,%2\n\\
1034
   shlqbyi\t%3,%3,4\n\\
1035
   cgx\t%3,%1,%2\n\\
1036
   shlqbyi\t%0,%3,4\n\\
1037
   addx\t%0,%1,%2"
1038
  [(set_attr "type" "multi0")
1039
   (set_attr "length" "28")])
1040
 
1041
(define_insn "add3"
1042
  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1043
        (plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1044
                  (match_operand:VSF 2 "spu_reg_operand" "r")))]
1045
  ""
1046
  "fa\t%0,%1,%2"
1047
  [(set_attr "type" "fp6")])
1048
 
1049
(define_insn "add3"
1050
  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1051
        (plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1052
                  (match_operand:VDF 2 "spu_reg_operand" "r")))]
1053
  ""
1054
  "dfa\t%0,%1,%2"
1055
  [(set_attr "type" "fpd")])
1056
 
1057
 
1058
;; sub
1059
 
1060
(define_expand "subv16qi3"
1061
  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1062
        (minus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
1063
                     (match_operand:V16QI 2 "spu_reg_operand" "r")))]
1064
  ""
1065
  "{
1066
    rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
1067
    rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
1068
    rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
1069
    rtx rhs_and = gen_reg_rtx (V8HImode);
1070
    rtx hi_char = gen_reg_rtx (V8HImode);
1071
    rtx lo_char = gen_reg_rtx (V8HImode);
1072
    rtx mask = gen_reg_rtx (V8HImode);
1073
 
1074
    emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
1075
    emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
1076
    emit_insn (gen_subv8hi3 (hi_char, lhs_short, rhs_and));
1077
    emit_insn (gen_subv8hi3 (lo_char, lhs_short, rhs_short));
1078
    emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
1079
    DONE;
1080
   }")
1081
 
1082
(define_insn "sub3"
1083
  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1084
        (minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B")
1085
                    (match_operand:VHSI 2 "spu_reg_operand" "r,r")))]
1086
  ""
1087
  "@
1088
  sf\t%0,%2,%1
1089
  sfi\t%0,%2,%1")
1090
 
1091
(define_expand "sub3"
1092
  [(set (match_dup:VDI 3)
1093
        (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
1094
                     (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG))
1095
   (set (match_dup:VDI 5)
1096
        (unspec:VDI [(match_dup 3)
1097
                     (match_dup 3)
1098
                     (match_dup:TI 4)] UNSPEC_SHUFB))
1099
   (set (match_operand:VDI 0 "spu_reg_operand" "")
1100
        (unspec:VDI [(match_dup 1)
1101
                     (match_dup 2)
1102
                     (match_dup 5)] UNSPEC_SFX))]
1103
  ""
1104
  {
1105
    unsigned char pat[16] = {
1106
      0x04, 0x05, 0x06, 0x07,
1107
      0xc0, 0xc0, 0xc0, 0xc0,
1108
      0x0c, 0x0d, 0x0e, 0x0f,
1109
      0xc0, 0xc0, 0xc0, 0xc0
1110
    };
1111
    operands[3] = gen_reg_rtx (mode);
1112
    operands[4] = gen_reg_rtx (TImode);
1113
    operands[5] = gen_reg_rtx (mode);
1114
    emit_move_insn (operands[4], array_to_constant (TImode, pat));
1115
  })
1116
 
1117
(define_insn "bg_"
1118
  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1119
        (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1120
                      (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))]
1121
  "operands"
1122
  "bg\t%0,%2,%1")
1123
 
1124
(define_insn "bgx_"
1125
  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1126
        (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1127
                      (match_operand 2 "spu_reg_operand" "r")
1128
                      (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))]
1129
  "operands"
1130
  "bgx\t%0,%2,%1")
1131
 
1132
(define_insn "sfx_"
1133
  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1134
        (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1135
                      (match_operand 2 "spu_reg_operand" "r")
1136
                      (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))]
1137
  "operands"
1138
  "sfx\t%0,%2,%1")
1139
 
1140
(define_insn "subti3"
1141
  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
1142
        (minus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1143
                  (match_operand:TI 2 "spu_reg_operand" "r")))
1144
   (clobber (match_scratch:TI 3 "=&r"))
1145
   (clobber (match_scratch:TI 4 "=&r"))
1146
   (clobber (match_scratch:TI 5 "=&r"))
1147
   (clobber (match_scratch:TI 6 "=&r"))]
1148
  ""
1149
  "il\t%6,1\n\\
1150
   bg\t%3,%2,%1\n\\
1151
   xor\t%3,%3,%6\n\\
1152
   sf\t%4,%2,%1\n\\
1153
   shlqbyi\t%5,%3,4\n\\
1154
   bg\t%3,%5,%4\n\\
1155
   xor\t%3,%3,%6\n\\
1156
   sf\t%4,%5,%4\n\\
1157
   shlqbyi\t%5,%3,4\n\\
1158
   bg\t%3,%5,%4\n\\
1159
   xor\t%3,%3,%6\n\\
1160
   sf\t%4,%5,%4\n\\
1161
   shlqbyi\t%5,%3,4\n\\
1162
   sf\t%0,%5,%4"
1163
  [(set_attr "type" "multi0")
1164
   (set_attr "length" "56")])
1165
 
1166
(define_insn "sub3"
1167
  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1168
        (minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1169
                   (match_operand:VSF 2 "spu_reg_operand" "r")))]
1170
  ""
1171
  "fs\t%0,%1,%2"
1172
  [(set_attr "type" "fp6")])
1173
 
1174
(define_insn "sub3"
1175
  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1176
        (minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1177
                   (match_operand:VDF 2 "spu_reg_operand" "r")))]
1178
  ""
1179
  "dfs\t%0,%1,%2"
1180
  [(set_attr "type" "fpd")])
1181
 
1182
 
1183
;; neg
1184
 
1185
(define_expand "negv16qi2"
1186
  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1187
        (neg:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")))]
1188
  ""
1189
  "{
1190
    rtx zero = gen_reg_rtx (V16QImode);
1191
    emit_move_insn (zero, CONST0_RTX (V16QImode));
1192
    emit_insn (gen_subv16qi3 (operands[0], zero, operands[1]));
1193
    DONE;
1194
   }")
1195
 
1196
(define_insn "neg2"
1197
  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
1198
        (neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))]
1199
  ""
1200
  "sfi\t%0,%1,0")
1201
 
1202
(define_expand "negdi2"
1203
  [(set (match_operand:DI 0 "spu_reg_operand" "")
1204
        (neg:DI (match_operand:DI 1 "spu_reg_operand" "")))]
1205
  ""
1206
  {
1207
    rtx zero = gen_reg_rtx(DImode);
1208
    emit_move_insn(zero, GEN_INT(0));
1209
    emit_insn (gen_subdi3(operands[0], zero, operands[1]));
1210
    DONE;
1211
  })
1212
 
1213
(define_expand "negti2"
1214
  [(set (match_operand:TI 0 "spu_reg_operand" "")
1215
        (neg:TI (match_operand:TI 1 "spu_reg_operand" "")))]
1216
  ""
1217
  {
1218
    rtx zero = gen_reg_rtx(TImode);
1219
    emit_move_insn(zero, GEN_INT(0));
1220
    emit_insn (gen_subti3(operands[0], zero, operands[1]));
1221
    DONE;
1222
  })
1223
 
1224
(define_expand "neg2"
1225
  [(parallel
1226
    [(set (match_operand:VSF 0 "spu_reg_operand" "")
1227
          (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1228
     (use (match_dup 2))])]
1229
  ""
1230
  "operands[2] = gen_reg_rtx (mode);
1231
   emit_move_insn (operands[2], spu_const (mode, -0x80000000ull));")
1232
 
1233
(define_expand "neg2"
1234
  [(parallel
1235
    [(set (match_operand:VDF 0 "spu_reg_operand" "")
1236
          (neg:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1237
     (use (match_dup 2))])]
1238
  ""
1239
  "operands[2] = gen_reg_rtx (mode);
1240
   emit_move_insn (operands[2], spu_const (mode, -0x8000000000000000ull));")
1241
 
1242
(define_insn_and_split "_neg2"
1243
  [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1244
        (neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1245
   (use (match_operand: 2 "spu_reg_operand" "r"))]
1246
  ""
1247
  "#"
1248
  ""
1249
  [(set (match_dup: 3)
1250
        (xor: (match_dup: 4)
1251
                   (match_dup: 2)))]
1252
  {
1253
    operands[3] = spu_gen_subreg (mode, operands[0]);
1254
    operands[4] = spu_gen_subreg (mode, operands[1]);
1255
  })
1256
 
1257
 
1258
;; abs
1259
 
1260
(define_expand "abs2"
1261
  [(parallel
1262
    [(set (match_operand:VSF 0 "spu_reg_operand" "")
1263
          (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1264
     (use (match_dup 2))])]
1265
  ""
1266
  "operands[2] = gen_reg_rtx (mode);
1267
   emit_move_insn (operands[2], spu_const (mode, 0x7fffffffull));")
1268
 
1269
(define_expand "abs2"
1270
  [(parallel
1271
    [(set (match_operand:VDF 0 "spu_reg_operand" "")
1272
          (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1273
     (use (match_dup 2))])]
1274
  ""
1275
  "operands[2] = gen_reg_rtx (mode);
1276
   emit_move_insn (operands[2], spu_const (mode, 0x7fffffffffffffffull));")
1277
 
1278
(define_insn_and_split "_abs2"
1279
  [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1280
        (abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1281
   (use (match_operand: 2 "spu_reg_operand" "r"))]
1282
  ""
1283
  "#"
1284
  ""
1285
  [(set (match_dup: 3)
1286
        (and: (match_dup: 4)
1287
                   (match_dup: 2)))]
1288
  {
1289
    operands[3] = spu_gen_subreg (mode, operands[0]);
1290
    operands[4] = spu_gen_subreg (mode, operands[1]);
1291
  })
1292
 
1293
 
1294
;; mul
1295
 
1296
(define_insn "mulhi3"
1297
  [(set (match_operand:HI 0 "spu_reg_operand" "=r,r")
1298
        (mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r")
1299
                 (match_operand:HI 2 "spu_arith_operand" "r,B")))]
1300
  ""
1301
  "@
1302
  mpy\t%0,%1,%2
1303
  mpyi\t%0,%1,%2"
1304
  [(set_attr "type" "fp7")])
1305
 
1306
(define_expand "mulv8hi3"
1307
  [(set (match_operand:V8HI 0 "spu_reg_operand" "")
1308
        (mult:V8HI (match_operand:V8HI 1 "spu_reg_operand" "")
1309
                   (match_operand:V8HI 2 "spu_reg_operand" "")))]
1310
  ""
1311
  "{
1312
    rtx result = simplify_gen_subreg (V4SImode, operands[0], V8HImode, 0);
1313
    rtx low = gen_reg_rtx (V4SImode);
1314
    rtx high = gen_reg_rtx (V4SImode);
1315
    rtx shift = gen_reg_rtx (V4SImode);
1316
    rtx mask = gen_reg_rtx (V4SImode);
1317
 
1318
    emit_move_insn (mask, spu_const (V4SImode, 0x0000ffff));
1319
    emit_insn (gen_spu_mpyhh (high, operands[1], operands[2]));
1320
    emit_insn (gen_spu_mpy (low, operands[1], operands[2]));
1321
    emit_insn (gen_vashlv4si3 (shift, high, spu_const(V4SImode, 16)));
1322
    emit_insn (gen_selb (result, shift, low, mask));
1323
    DONE;
1324
   }")
1325
 
1326
(define_expand "mul3"
1327
  [(parallel
1328
    [(set (match_operand:VSI 0 "spu_reg_operand" "")
1329
          (mult:VSI (match_operand:VSI 1 "spu_reg_operand" "")
1330
                    (match_operand:VSI 2 "spu_reg_operand" "")))
1331
     (clobber (match_dup:VSI 3))
1332
     (clobber (match_dup:VSI 4))
1333
     (clobber (match_dup:VSI 5))
1334
     (clobber (match_dup:VSI 6))])]
1335
  ""
1336
  {
1337
    operands[3] = gen_reg_rtx(mode);
1338
    operands[4] = gen_reg_rtx(mode);
1339
    operands[5] = gen_reg_rtx(mode);
1340
    operands[6] = gen_reg_rtx(mode);
1341
  })
1342
 
1343
(define_insn_and_split "_mulsi3"
1344
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1345
        (mult:SI (match_operand:SI 1 "spu_reg_operand" "r")
1346
                 (match_operand:SI 2 "spu_arith_operand" "rK")))
1347
   (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))
1348
   (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
1349
   (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))
1350
   (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))]
1351
  ""
1352
  "#"
1353
  ""
1354
  [(set (match_dup:SI 0)
1355
        (mult:SI (match_dup:SI 1)
1356
                 (match_dup:SI 2)))]
1357
  {
1358
    HOST_WIDE_INT val = 0;
1359
    rtx a = operands[3];
1360
    rtx b = operands[4];
1361
    rtx c = operands[5];
1362
    rtx d = operands[6];
1363
    if (GET_CODE(operands[2]) == CONST_INT)
1364
      {
1365
        val = INTVAL(operands[2]);
1366
        emit_move_insn(d, operands[2]);
1367
        operands[2] = d;
1368
      }
1369
    if (val && (val & 0xffff) == 0)
1370
      {
1371
        emit_insn (gen_mpyh_si(operands[0], operands[2], operands[1]));
1372
      }
1373
    else if (val > 0 && val < 0x10000)
1374
      {
1375
        rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d;
1376
        emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1377
        emit_insn (gen_mpyu_si(c, operands[1], cst));
1378
        emit_insn (gen_addsi3(operands[0], a, c));
1379
      }
1380
    else
1381
      {
1382
        emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1383
        emit_insn (gen_mpyh_si(b, operands[2], operands[1]));
1384
        emit_insn (gen_mpyu_si(c, operands[1], operands[2]));
1385
        emit_insn (gen_addsi3(d, a, b));
1386
        emit_insn (gen_addsi3(operands[0], d, c));
1387
      }
1388
    DONE;
1389
   })
1390
 
1391
(define_insn_and_split "_mulv4si3"
1392
  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
1393
        (mult:V4SI (match_operand:V4SI 1 "spu_reg_operand" "r")
1394
                   (match_operand:V4SI 2 "spu_reg_operand" "r")))
1395
   (clobber (match_operand:V4SI 3 "spu_reg_operand" "=&r"))
1396
   (clobber (match_operand:V4SI 4 "spu_reg_operand" "=&r"))
1397
   (clobber (match_operand:V4SI 5 "spu_reg_operand" "=&r"))
1398
   (clobber (match_operand:V4SI 6 "spu_reg_operand" "=&r"))]
1399
  ""
1400
  "#"
1401
  ""
1402
  [(set (match_dup:V4SI 0)
1403
        (mult:V4SI (match_dup:V4SI 1)
1404
                   (match_dup:V4SI 2)))]
1405
  {
1406
    rtx a = operands[3];
1407
    rtx b = operands[4];
1408
    rtx c = operands[5];
1409
    rtx d = operands[6];
1410
    rtx op1 = simplify_gen_subreg (V8HImode, operands[1], V4SImode, 0);
1411
    rtx op2 = simplify_gen_subreg (V8HImode, operands[2], V4SImode, 0);
1412
    emit_insn (gen_spu_mpyh(a, op1, op2));
1413
    emit_insn (gen_spu_mpyh(b, op2, op1));
1414
    emit_insn (gen_spu_mpyu(c, op1, op2));
1415
    emit_insn (gen_addv4si3(d, a, b));
1416
    emit_insn (gen_addv4si3(operands[0], d, c));
1417
    DONE;
1418
   })
1419
 
1420
(define_insn "mulhisi3"
1421
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1422
        (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1423
                 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1424
  ""
1425
  "mpy\t%0,%1,%2"
1426
  [(set_attr "type" "fp7")])
1427
 
1428
(define_insn "mulhisi3_imm"
1429
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1430
        (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1431
                 (match_operand:SI 2 "imm_K_operand" "K")))]
1432
  ""
1433
  "mpyi\t%0,%1,%2"
1434
  [(set_attr "type" "fp7")])
1435
 
1436
(define_insn "umulhisi3"
1437
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1438
        (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1439
                 (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1440
  ""
1441
  "mpyu\t%0,%1,%2"
1442
  [(set_attr "type" "fp7")])
1443
 
1444
(define_insn "umulhisi3_imm"
1445
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1446
        (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1447
                 (and:SI (match_operand:SI 2 "imm_K_operand" "K") (const_int 65535))))]
1448
  ""
1449
  "mpyui\t%0,%1,%2"
1450
  [(set_attr "type" "fp7")])
1451
 
1452
(define_insn "mpyu_si"
1453
  [(set (match_operand:SI 0 "spu_reg_operand" "=r,r")
1454
        (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r")
1455
                         (const_int 65535))
1456
                 (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K")
1457
                         (const_int 65535))))]
1458
  ""
1459
  "@
1460
   mpyu\t%0,%1,%2
1461
   mpyui\t%0,%1,%2"
1462
  [(set_attr "type" "fp7")])
1463
 
1464
;; This isn't always profitable to use.  Consider r = a * b + c * d.
1465
;; It's faster to do the multiplies in parallel then add them.  If we
1466
;; merge a multiply and add it prevents the multiplies from happening in
1467
;; parallel.
1468
(define_insn "mpya_si"
1469
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1470
        (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1471
                          (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1472
                 (match_operand:SI 3 "spu_reg_operand" "r")))]
1473
  "0"
1474
  "mpya\t%0,%1,%2,%3"
1475
  [(set_attr "type" "fp7")])
1476
 
1477
(define_insn "mpyh_si"
1478
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1479
        (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r")
1480
                         (const_int -65536))
1481
                 (and:SI (match_operand:SI 2 "spu_reg_operand" "r")
1482
                         (const_int 65535))))]
1483
  ""
1484
  "mpyh\t%0,%1,%2"
1485
  [(set_attr "type" "fp7")])
1486
 
1487
(define_insn "mpys_si"
1488
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1489
        (ashiftrt:SI
1490
            (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1491
                     (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1492
            (const_int 16)))]
1493
  ""
1494
  "mpys\t%0,%1,%2"
1495
  [(set_attr "type" "fp7")])
1496
 
1497
(define_insn "mpyhh_si"
1498
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1499
        (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1500
                              (const_int 16))
1501
                 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1502
                              (const_int 16))))]
1503
  ""
1504
  "mpyhh\t%0,%1,%2"
1505
  [(set_attr "type" "fp7")])
1506
 
1507
(define_insn "mpyhhu_si"
1508
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1509
        (mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1510
                              (const_int 16))
1511
                 (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1512
                              (const_int 16))))]
1513
  ""
1514
  "mpyhhu\t%0,%1,%2"
1515
  [(set_attr "type" "fp7")])
1516
 
1517
(define_insn "mpyhha_si"
1518
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1519
        (plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1520
                                       (const_int 16))
1521
                          (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1522
                                       (const_int 16)))
1523
                 (match_operand:SI 3 "spu_reg_operand" "0")))]
1524
  "0"
1525
  "mpyhha\t%0,%1,%2"
1526
  [(set_attr "type" "fp7")])
1527
 
1528
(define_insn "mul3"
1529
  [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1530
        (mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")
1531
                   (match_operand:VSDF 2 "spu_reg_operand" "r")))]
1532
  ""
1533
  "fm\t%0,%1,%2"
1534
  [(set_attr "type" "fp")])
1535
 
1536
(define_insn "fma_"
1537
  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1538
        (plus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1539
                              (match_operand:VSF 2 "spu_reg_operand" "r"))
1540
                   (match_operand:VSF 3 "spu_reg_operand" "r")))]
1541
  ""
1542
  "fma\t%0,%1,%2,%3"
1543
  [(set_attr "type"     "fp6")])
1544
 
1545
(define_insn "fnms_"
1546
  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1547
        (minus:VSF (match_operand:VSF 3 "spu_reg_operand" "r")
1548
                    (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1549
                               (match_operand:VSF 2 "spu_reg_operand" "r"))))]
1550
  ""
1551
  "fnms\t%0,%1,%2,%3"
1552
  [(set_attr "type" "fp6")])
1553
 
1554
(define_insn "fms_"
1555
  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1556
        (minus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1557
                               (match_operand:VSF 2 "spu_reg_operand" "r"))
1558
                    (match_operand:VSF 3 "spu_reg_operand" "r")))]
1559
  ""
1560
  "fms\t%0,%1,%2,%3"
1561
  [(set_attr "type" "fp6")])
1562
 
1563
(define_insn "fma_"
1564
  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1565
        (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1566
                            (match_operand:VDF 2 "spu_reg_operand" "r"))
1567
                  (match_operand:VDF 3 "spu_reg_operand" "0")))]
1568
  ""
1569
  "dfma\t%0,%1,%2"
1570
  [(set_attr "type"     "fpd")])
1571
 
1572
(define_insn "fnma_"
1573
  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1574
        (neg:VDF (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1575
                                     (match_operand:VDF 2 "spu_reg_operand" "r"))
1576
                           (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1577
  ""
1578
  "dfnma\t%0,%1,%2"
1579
  [(set_attr "type"     "fpd")])
1580
 
1581
(define_insn "fnms_"
1582
  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1583
        (minus:VDF (match_operand:VDF 3 "spu_reg_operand" "0")
1584
                   (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1585
                             (match_operand:VDF 2 "spu_reg_operand" "r"))))]
1586
  ""
1587
  "dfnms\t%0,%1,%2"
1588
  [(set_attr "type" "fpd")])
1589
 
1590
(define_insn "fms_"
1591
  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1592
        (minus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1593
                             (match_operand:VDF 2 "spu_reg_operand" "r"))
1594
                   (match_operand:VDF 3 "spu_reg_operand" "0")))]
1595
  ""
1596
  "dfms\t%0,%1,%2"
1597
  [(set_attr "type" "fpd")])
1598
 
1599
 
1600
;; mul highpart, used for divide by constant optimizations.
1601
 
1602
(define_expand "smulsi3_highpart"
1603
  [(set (match_operand:SI 0 "register_operand" "")
1604
        (truncate:SI
1605
          (ashiftrt:DI
1606
            (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1607
                     (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
1608
            (const_int 32))))]
1609
  ""
1610
  {
1611
    rtx t0 = gen_reg_rtx (SImode);
1612
    rtx t1 = gen_reg_rtx (SImode);
1613
    rtx t2 = gen_reg_rtx (SImode);
1614
    rtx t3 = gen_reg_rtx (SImode);
1615
    rtx t4 = gen_reg_rtx (SImode);
1616
    rtx t5 = gen_reg_rtx (SImode);
1617
    rtx t6 = gen_reg_rtx (SImode);
1618
    rtx t7 = gen_reg_rtx (SImode);
1619
    rtx t8 = gen_reg_rtx (SImode);
1620
    rtx t9 = gen_reg_rtx (SImode);
1621
    rtx t11 = gen_reg_rtx (SImode);
1622
    rtx t12 = gen_reg_rtx (SImode);
1623
    rtx t14 = gen_reg_rtx (SImode);
1624
    rtx t15 = gen_reg_rtx (HImode);
1625
    rtx t16 = gen_reg_rtx (HImode);
1626
    rtx t17 = gen_reg_rtx (HImode);
1627
    rtx t18 = gen_reg_rtx (HImode);
1628
    rtx t19 = gen_reg_rtx (SImode);
1629
    rtx t20 = gen_reg_rtx (SImode);
1630
    rtx t21 = gen_reg_rtx (SImode);
1631
    rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1632
    rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1633
    rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1634
    rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2);
1635
 
1636
    rtx insn = emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16)));
1637
    emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16)));
1638
    emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi));
1639
    emit_insn (gen_mpyh_si (t3, operands[1], operands[2]));
1640
    emit_insn (gen_mpyh_si (t4, operands[2], operands[1]));
1641
    emit_insn (gen_mpyhh_si (t5, operands[1], operands[2]));
1642
    emit_insn (gen_mpys_si (t6, t0_hi, op2_hi));
1643
    emit_insn (gen_mpys_si (t7, t1_hi, op1_hi));
1644
 
1645
    /* Gen carry bits (in t9 and t11). */
1646
    emit_insn (gen_addsi3 (t8, t2, t3));
1647
    emit_insn (gen_cg_si (t9, t2, t3));
1648
    emit_insn (gen_cg_si (t11, t8, t4));
1649
 
1650
    /* Gen high 32 bits in operand[0].  Correct for mpys. */
1651
    emit_insn (gen_addx_si (t12, t5, t6, t9));
1652
    emit_insn (gen_addx_si (t14, t12, t7, t11));
1653
 
1654
    /* mpys treats both operands as signed when we really want it to treat
1655
       the first operand as signed and the second operand as unsigned.
1656
       The code below corrects for that difference.  */
1657
    emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1)));
1658
    emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1)));
1659
    emit_insn (gen_andc_hi (t17, t1_hi, t15));
1660
    emit_insn (gen_andc_hi (t18, t0_hi, t16));
1661
    emit_insn (gen_extendhisi2 (t19, t17));
1662
    emit_insn (gen_extendhisi2 (t20, t18));
1663
    emit_insn (gen_addsi3 (t21, t19, t20));
1664
    emit_insn (gen_addsi3 (operands[0], t14, t21));
1665
    unshare_all_rtl_in_chain (insn);
1666
    DONE;
1667
  })
1668
 
1669
(define_expand "umulsi3_highpart"
1670
  [(set (match_operand:SI 0 "register_operand" "")
1671
        (truncate:SI
1672
          (ashiftrt:DI
1673
            (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1674
                     (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1675
            (const_int 32))))]
1676
  ""
1677
 
1678
  {
1679
    rtx t0 = gen_reg_rtx (SImode);
1680
    rtx t1 = gen_reg_rtx (SImode);
1681
    rtx t2 = gen_reg_rtx (SImode);
1682
    rtx t3 = gen_reg_rtx (SImode);
1683
    rtx t4 = gen_reg_rtx (SImode);
1684
    rtx t5 = gen_reg_rtx (SImode);
1685
    rtx t6 = gen_reg_rtx (SImode);
1686
    rtx t7 = gen_reg_rtx (SImode);
1687
    rtx t8 = gen_reg_rtx (SImode);
1688
    rtx t9 = gen_reg_rtx (SImode);
1689
    rtx t10 = gen_reg_rtx (SImode);
1690
    rtx t12 = gen_reg_rtx (SImode);
1691
    rtx t13 = gen_reg_rtx (SImode);
1692
    rtx t14 = gen_reg_rtx (SImode);
1693
    rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1694
    rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1695
    rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1696
 
1697
    rtx insn = emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16)));
1698
    emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi));
1699
    emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi));
1700
    emit_insn (gen_mpyhhu_si (t3, operands[1], t0));
1701
    emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2]));
1702
    emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16)));
1703
    emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16)));
1704
    emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16)));
1705
    emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16)));
1706
 
1707
    /* Gen carry bits (in t10 and t12). */
1708
    emit_insn (gen_addsi3 (t9, t1, t5));
1709
    emit_insn (gen_cg_si (t10, t1, t5));
1710
    emit_insn (gen_cg_si (t12, t9, t6));
1711
 
1712
    /* Gen high 32 bits in operand[0]. */
1713
    emit_insn (gen_addx_si (t13, t4, t7, t10));
1714
    emit_insn (gen_addx_si (t14, t13, t8, t12));
1715
    emit_insn (gen_movsi (operands[0], t14));
1716
    unshare_all_rtl_in_chain (insn);
1717
 
1718
    DONE;
1719
  })
1720
 
1721
;; div
1722
 
1723
;; Not necessarily the best implementation of divide but faster then
1724
;; the default that gcc provides because this is inlined and it uses
1725
;; clz.
1726
(define_insn "divmodsi4"
1727
      [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1728
            (div:SI (match_operand:SI 1 "spu_reg_operand" "r")
1729
                    (match_operand:SI 2 "spu_reg_operand" "r")))
1730
       (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1731
            (mod:SI (match_dup 1)
1732
                    (match_dup 2)))
1733
       (clobber (match_scratch:SI 4 "=&r"))
1734
       (clobber (match_scratch:SI 5 "=&r"))
1735
       (clobber (match_scratch:SI 6 "=&r"))
1736
       (clobber (match_scratch:SI 7 "=&r"))
1737
       (clobber (match_scratch:SI 8 "=&r"))
1738
       (clobber (match_scratch:SI 9 "=&r"))
1739
       (clobber (match_scratch:SI 10 "=&r"))
1740
       (clobber (match_scratch:SI 11 "=&r"))
1741
       (clobber (match_scratch:SI 12 "=&r"))
1742
       (clobber (reg:SI 130))]
1743
  ""
1744
  "heqi %2,0\\n\\
1745
        hbrr    3f,1f\\n\\
1746
        sfi     %8,%1,0\\n\\
1747
        sfi     %9,%2,0\\n\\
1748
        cgti    %10,%1,-1\\n\\
1749
        cgti    %11,%2,-1\\n\\
1750
        selb    %8,%8,%1,%10\\n\\
1751
        selb    %9,%9,%2,%11\\n\\
1752
        clz     %4,%8\\n\\
1753
        clz     %7,%9\\n\\
1754
        il      %5,1\\n\\
1755
        fsmbi   %0,0\\n\\
1756
        sf      %7,%4,%7\\n\\
1757
        shlqbyi %3,%8,0\\n\\
1758
        xor     %11,%10,%11\\n\\
1759
        shl     %5,%5,%7\\n\\
1760
        shl     %4,%9,%7\\n\\
1761
        lnop    \\n\\
1762
1:      or      %12,%0,%5\\n\\
1763
        rotqmbii        %5,%5,-1\\n\\
1764
        clgt    %6,%4,%3\\n\\
1765
        lnop    \\n\\
1766
        sf      %7,%4,%3\\n\\
1767
        rotqmbii        %4,%4,-1\\n\\
1768
        selb    %0,%12,%0,%6\\n\\
1769
        lnop    \\n\\
1770
        selb    %3,%7,%3,%6\\n\\
1771
3:      brnz    %5,1b\\n\\
1772
2:      sfi     %8,%3,0\\n\\
1773
        sfi     %9,%0,0\\n\\
1774
        selb    %3,%8,%3,%10\\n\\
1775
        selb    %0,%0,%9,%11"
1776
  [(set_attr "type" "multi0")
1777
   (set_attr "length" "128")])
1778
 
1779
(define_insn "udivmodsi4"
1780
      [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1781
            (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r")
1782
                     (match_operand:SI 2 "spu_reg_operand" "r")))
1783
       (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1784
            (umod:SI (match_dup 1)
1785
                     (match_dup 2)))
1786
       (clobber (match_scratch:SI 4 "=&r"))
1787
       (clobber (match_scratch:SI 5 "=&r"))
1788
       (clobber (match_scratch:SI 6 "=&r"))
1789
       (clobber (match_scratch:SI 7 "=&r"))
1790
       (clobber (match_scratch:SI 8 "=&r"))
1791
       (clobber (reg:SI 130))]
1792
  ""
1793
  "heqi %2,0\\n\\
1794
        hbrr    3f,1f\\n\\
1795
        clz     %7,%2\\n\\
1796
        clz     %4,%1\\n\\
1797
        il      %5,1\\n\\
1798
        fsmbi   %0,0\\n\\
1799
        sf      %7,%4,%7\\n\\
1800
        ori     %3,%1,0\\n\\
1801
        shl     %5,%5,%7\\n\\
1802
        shl     %4,%2,%7\\n\\
1803
1:      or      %8,%0,%5\\n\\
1804
        rotqmbii        %5,%5,-1\\n\\
1805
        clgt    %6,%4,%3\\n\\
1806
        lnop    \\n\\
1807
        sf      %7,%4,%3\\n\\
1808
        rotqmbii        %4,%4,-1\\n\\
1809
        selb    %0,%8,%0,%6\\n\\
1810
        lnop    \\n\\
1811
        selb    %3,%7,%3,%6\\n\\
1812
3:      brnz    %5,1b\\n\\
1813
2:"
1814
  [(set_attr "type" "multi0")
1815
   (set_attr "length" "80")])
1816
 
1817
(define_expand "div3"
1818
  [(parallel
1819
    [(set (match_operand:VSF 0 "spu_reg_operand" "")
1820
          (div:VSF (match_operand:VSF 1 "spu_reg_operand" "")
1821
                   (match_operand:VSF 2 "spu_reg_operand" "")))
1822
     (clobber (match_scratch:VSF 3 ""))
1823
     (clobber (match_scratch:VSF 4 ""))
1824
     (clobber (match_scratch:VSF 5 ""))])]
1825
  ""
1826
  "")
1827
 
1828
(define_insn_and_split "*div3_fast"
1829
  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1830
        (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1831
                 (match_operand:VSF 2 "spu_reg_operand" "r")))
1832
   (clobber (match_scratch:VSF 3 "=&r"))
1833
   (clobber (match_scratch:VSF 4 "=&r"))
1834
   (clobber (scratch:VSF))]
1835
  "flag_unsafe_math_optimizations"
1836
  "#"
1837
  "reload_completed"
1838
  [(set (match_dup:VSF 0)
1839
        (div:VSF (match_dup:VSF 1)
1840
                 (match_dup:VSF 2)))
1841
   (clobber (match_dup:VSF 3))
1842
   (clobber (match_dup:VSF 4))
1843
   (clobber (scratch:VSF))]
1844
  {
1845
    emit_insn (gen_frest_(operands[3], operands[2]));
1846
    emit_insn (gen_fi_(operands[3], operands[2], operands[3]));
1847
    emit_insn (gen_mul3(operands[4], operands[1], operands[3]));
1848
    emit_insn (gen_fnms_(operands[0], operands[4], operands[2], operands[1]));
1849
    emit_insn (gen_fma_(operands[0], operands[0], operands[3], operands[4]));
1850
    DONE;
1851
  })
1852
 
1853
(define_insn_and_split "*div3_adjusted"
1854
  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1855
        (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1856
                 (match_operand:VSF 2 "spu_reg_operand" "r")))
1857
   (clobber (match_scratch:VSF 3 "=&r"))
1858
   (clobber (match_scratch:VSF 4 "=&r"))
1859
   (clobber (match_scratch:VSF 5 "=&r"))]
1860
  "!flag_unsafe_math_optimizations"
1861
  "#"
1862
  "reload_completed"
1863
  [(set (match_dup:VSF 0)
1864
        (div:VSF (match_dup:VSF 1)
1865
                 (match_dup:VSF 2)))
1866
   (clobber (match_dup:VSF 3))
1867
   (clobber (match_dup:VSF 4))
1868
   (clobber (match_dup:VSF 5))]
1869
  {
1870
    emit_insn (gen_frest_ (operands[3], operands[2]));
1871
    emit_insn (gen_fi_ (operands[3], operands[2], operands[3]));
1872
    emit_insn (gen_mul3 (operands[4], operands[1], operands[3]));
1873
    emit_insn (gen_fnms_ (operands[5], operands[4], operands[2], operands[1]));
1874
    emit_insn (gen_fma_ (operands[3], operands[5], operands[3], operands[4]));
1875
 
1876
   /* Due to truncation error, the quotient result may be low by 1 ulp.
1877
      Conditionally add one if the estimate is too small in magnitude.  */
1878
 
1879
    emit_move_insn (gen_lowpart (mode, operands[4]),
1880
                    spu_const (mode, 0x80000000ULL));
1881
    emit_move_insn (gen_lowpart (mode, operands[5]),
1882
                    spu_const (mode, 0x3f800000ULL));
1883
    emit_insn (gen_selb (operands[5], operands[5], operands[1], operands[4]));
1884
 
1885
    emit_insn (gen_add3 (gen_lowpart (mode, operands[4]),
1886
                              gen_lowpart (mode, operands[3]),
1887
                              spu_const (mode, 1)));
1888
    emit_insn (gen_fnms_ (operands[0], operands[2], operands[4], operands[1]));
1889
    emit_insn (gen_mul3 (operands[0], operands[0], operands[5]));
1890
    emit_insn (gen_cgt_ (gen_lowpart (mode, operands[0]),
1891
                              gen_lowpart (mode, operands[0]),
1892
                              spu_const (mode, -1)));
1893
    emit_insn (gen_selb (operands[0], operands[3], operands[4], operands[0]));
1894
    DONE;
1895
  })
1896
 
1897
 
1898
;; sqrt
1899
 
1900
(define_insn_and_split "sqrtsf2"
1901
  [(set (match_operand:SF 0 "spu_reg_operand" "=r")
1902
        (sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r")))
1903
   (clobber (match_scratch:SF 2 "=&r"))
1904
   (clobber (match_scratch:SF 3 "=&r"))
1905
   (clobber (match_scratch:SF 4 "=&r"))
1906
   (clobber (match_scratch:SF 5 "=&r"))]
1907
  ""
1908
  "#"
1909
  "reload_completed"
1910
  [(set (match_dup:SF 0)
1911
        (sqrt:SF (match_dup:SF 1)))
1912
   (clobber (match_dup:SF 2))
1913
   (clobber (match_dup:SF 3))
1914
   (clobber (match_dup:SF 4))
1915
   (clobber (match_dup:SF 5))]
1916
  {
1917
    emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode));
1918
    emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode));
1919
    emit_insn (gen_frsqest_sf(operands[2],operands[1]));
1920
    emit_insn (gen_fi_sf(operands[2],operands[1],operands[2]));
1921
    emit_insn (gen_mulsf3(operands[5],operands[2],operands[1]));
1922
    emit_insn (gen_mulsf3(operands[3],operands[5],operands[3]));
1923
    emit_insn (gen_fnms_sf(operands[4],operands[2],operands[5],operands[4]));
1924
    emit_insn (gen_fma_sf(operands[0],operands[4],operands[3],operands[5]));
1925
    DONE;
1926
  })
1927
 
1928
(define_insn "frest_"
1929
  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1930
        (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))]
1931
  ""
1932
  "frest\t%0,%1"
1933
  [(set_attr "type" "shuf")])
1934
 
1935
(define_insn "frsqest_"
1936
  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1937
        (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))]
1938
  ""
1939
  "frsqest\t%0,%1"
1940
  [(set_attr "type" "shuf")])
1941
 
1942
(define_insn "fi_"
1943
  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1944
        (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")
1945
                    (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))]
1946
  ""
1947
  "fi\t%0,%1,%2"
1948
  [(set_attr "type" "fp7")])
1949
 
1950
 
1951
;; and
1952
 
1953
(define_insn "and3"
1954
  [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
1955
        (and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
1956
                 (match_operand:MOV 2 "spu_logical_operand" "r,C")))]
1957
  ""
1958
  "@
1959
  and\t%0,%1,%2
1960
  and%j2i\t%0,%1,%J2")
1961
 
1962
(define_insn "anddi3"
1963
  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1964
        (and:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1965
                (match_operand:DI 2 "spu_logical_operand" "r,c")))]
1966
  ""
1967
  "@
1968
  and\t%0,%1,%2
1969
  and%k2i\t%0,%1,%K2")
1970
 
1971
(define_insn "andti3"
1972
  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1973
        (and:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1974
                (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
1975
  ""
1976
  "@
1977
  and\t%0,%1,%2
1978
  and%m2i\t%0,%1,%L2")
1979
 
1980
(define_insn "andc_"
1981
  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1982
        (and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
1983
                 (match_operand:ALL 1 "spu_reg_operand" "r")))]
1984
  ""
1985
  "andc\t%0,%1,%2")
1986
 
1987
(define_insn "nand_"
1988
  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1989
        (not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r")
1990
                          (match_operand:ALL 1 "spu_reg_operand" "r"))))]
1991
  ""
1992
  "nand\t%0,%1,%2")
1993
 
1994
 
1995
;; ior
1996
 
1997
(define_insn "ior3"
1998
  [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
1999
        (ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0")
2000
                 (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))]
2001
  ""
2002
  "@
2003
  or\t%0,%1,%2
2004
  or%j2i\t%0,%1,%J2
2005
  iohl\t%0,%J2")
2006
 
2007
(define_insn "iordi3"
2008
  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
2009
        (ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0")
2010
                (match_operand:DI 2 "spu_ior_operand" "r,c,d")))]
2011
  ""
2012
  "@
2013
  or\t%0,%1,%2
2014
  or%k2i\t%0,%1,%K2
2015
  iohl\t%0,%K2")
2016
 
2017
(define_insn "iorti3"
2018
  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
2019
        (ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0")
2020
                (match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))]
2021
  ""
2022
  "@
2023
  or\t%0,%1,%2
2024
  or%m2i\t%0,%1,%L2
2025
  iohl\t%0,%L2")
2026
 
2027
(define_insn "orc_"
2028
  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2029
        (ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
2030
                 (match_operand:ALL 1 "spu_reg_operand" "r")))]
2031
  ""
2032
  "orc\t%0,%1,%2")
2033
 
2034
(define_insn "nor_"
2035
  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2036
        (not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2037
                          (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2038
  ""
2039
  "nor\t%0,%1,%2")
2040
 
2041
;; xor
2042
 
2043
(define_insn "xor3"
2044
  [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
2045
        (xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
2046
                 (match_operand:MOV 2 "spu_logical_operand" "r,B")))]
2047
  ""
2048
  "@
2049
  xor\t%0,%1,%2
2050
  xor%j2i\t%0,%1,%J2")
2051
 
2052
(define_insn "xordi3"
2053
  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2054
        (xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2055
                (match_operand:DI 2 "spu_logical_operand" "r,c")))]
2056
  ""
2057
  "@
2058
  xor\t%0,%1,%2
2059
  xor%k2i\t%0,%1,%K2")
2060
 
2061
(define_insn "xorti3"
2062
  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2063
        (xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2064
                (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
2065
  ""
2066
  "@
2067
  xor\t%0,%1,%2
2068
  xor%m2i\t%0,%1,%L2")
2069
 
2070
(define_insn "eqv_"
2071
  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2072
        (not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2073
                          (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2074
  ""
2075
  "eqv\t%0,%1,%2")
2076
 
2077
;; one_cmpl
2078
 
2079
(define_insn "one_cmpl2"
2080
  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2081
        (not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))]
2082
  ""
2083
  "nor\t%0,%1,%1")
2084
 
2085
 
2086
;; selb
2087
 
2088
(define_expand "selb"
2089
  [(set (match_operand 0 "spu_reg_operand" "")
2090
        (unspec [(match_operand 1 "spu_reg_operand" "")
2091
                 (match_operand 2 "spu_reg_operand" "")
2092
                 (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))]
2093
  ""
2094
  {
2095
    rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]);
2096
    PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
2097
    emit_insn (s);
2098
    DONE;
2099
  })
2100
 
2101
;; This could be defined as a combination of logical operations, but at
2102
;; one time it caused a crash due to recursive expansion of rtl during CSE.
2103
(define_insn "_selb"
2104
  [(set (match_operand 0 "spu_reg_operand" "=r")
2105
        (unspec [(match_operand 1 "spu_reg_operand" "r")
2106
                 (match_operand 2 "spu_reg_operand" "r")
2107
                 (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))]
2108
  "GET_MODE(operands[0]) == GET_MODE(operands[1])
2109
   && GET_MODE(operands[1]) == GET_MODE(operands[2])"
2110
  "selb\t%0,%1,%2,%3")
2111
 
2112
 
2113
;; Misc. byte/bit operations
2114
;; clz/ctz/ffs/popcount/parity
2115
;; cntb/sumb
2116
 
2117
(define_insn "clz2"
2118
  [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
2119
        (clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))]
2120
  ""
2121
  "clz\t%0,%1")
2122
 
2123
(define_expand "ctz2"
2124
  [(set (match_dup 2)
2125
        (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2126
   (set (match_dup 3) (and:VSI (match_dup 1)
2127
                               (match_dup 2)))
2128
   (set (match_dup 4) (clz:VSI (match_dup 3)))
2129
   (set (match_operand:VSI 0 "spu_reg_operand" "")
2130
        (minus:VSI (match_dup 5) (match_dup 4)))]
2131
  ""
2132
  {
2133
     operands[2] = gen_reg_rtx (mode);
2134
     operands[3] = gen_reg_rtx (mode);
2135
     operands[4] = gen_reg_rtx (mode);
2136
     operands[5] = spu_const(mode, 31);
2137
  })
2138
 
2139
(define_expand "ffs2"
2140
  [(set (match_dup 2)
2141
        (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2142
   (set (match_dup 3) (and:VSI (match_dup 1)
2143
                               (match_dup 2)))
2144
   (set (match_dup 4) (clz:VSI (match_dup 3)))
2145
   (set (match_operand:VSI 0 "spu_reg_operand" "")
2146
        (minus:VSI (match_dup 5) (match_dup 4)))]
2147
  ""
2148
  {
2149
     operands[2] = gen_reg_rtx (mode);
2150
     operands[3] = gen_reg_rtx (mode);
2151
     operands[4] = gen_reg_rtx (mode);
2152
     operands[5] = spu_const(mode, 32);
2153
  })
2154
 
2155
(define_expand "popcountsi2"
2156
  [(set (match_dup 2)
2157
        (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
2158
                     UNSPEC_CNTB))
2159
   (set (match_dup 3)
2160
        (unspec:HI [(match_dup 2)] UNSPEC_SUMB))
2161
   (set (match_operand:SI 0 "spu_reg_operand" "")
2162
        (sign_extend:SI (match_dup 3)))]
2163
  ""
2164
  {
2165
    operands[2] = gen_reg_rtx (SImode);
2166
    operands[3] = gen_reg_rtx (HImode);
2167
  })
2168
 
2169
(define_expand "paritysi2"
2170
  [(set (match_operand:SI 0 "spu_reg_operand" "")
2171
        (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
2172
  ""
2173
  {
2174
    operands[2] = gen_reg_rtx (SImode);
2175
    emit_insn (gen_popcountsi2(operands[2], operands[1]));
2176
    emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
2177
    DONE;
2178
  })
2179
 
2180
(define_insn "cntb_si"
2181
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2182
        (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
2183
                   UNSPEC_CNTB))]
2184
  ""
2185
  "cntb\t%0,%1"
2186
  [(set_attr "type" "fxb")])
2187
 
2188
(define_insn "cntb_v16qi"
2189
  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
2190
        (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
2191
                      UNSPEC_CNTB))]
2192
  ""
2193
  "cntb\t%0,%1"
2194
  [(set_attr "type" "fxb")])
2195
 
2196
(define_insn "sumb_si"
2197
  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
2198
        (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
2199
  ""
2200
  "sumb\t%0,%1,%1"
2201
  [(set_attr "type" "fxb")])
2202
 
2203
 
2204
;; ashl, vashl
2205
 
2206
(define_insn "ashl3"
2207
  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2208
        (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2209
                     (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2210
  ""
2211
  "@
2212
  shl\t%0,%1,%2
2213
  shli\t%0,%1,%2"
2214
  [(set_attr "type" "fx3")])
2215
 
2216
(define_insn_and_split "ashldi3"
2217
  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2218
        (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2219
                   (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2220
   (clobber (match_scratch:SI 3 "=&r,X"))]
2221
  ""
2222
  "#"
2223
  "reload_completed"
2224
  [(set (match_dup:DI 0)
2225
        (ashift:DI (match_dup:DI 1)
2226
                   (match_dup:SI 2)))]
2227
  {
2228
    rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2229
    rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2230
    rtx op2 = operands[2];
2231
    rtx op3 = operands[3];
2232
 
2233
    if (GET_CODE (operands[2]) == REG)
2234
      {
2235
        emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
2236
        emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2237
        emit_insn (gen_shlqbybi_ti (op0, op0, op3));
2238
        emit_insn (gen_shlqbi_ti (op0, op0, op3));
2239
      }
2240
    else
2241
      {
2242
        HOST_WIDE_INT val = INTVAL (operands[2]);
2243
        emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2244
        emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
2245
        if (val % 8)
2246
          emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
2247
      }
2248
    DONE;
2249
  })
2250
 
2251
(define_expand "ashlti3"
2252
  [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
2253
                   (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
2254
                              (match_operand:SI 2 "spu_nonmem_operand" "")))
2255
              (clobber (match_dup:TI 3))])]
2256
  ""
2257
  "if (GET_CODE (operands[2]) == CONST_INT)
2258
    {
2259
      emit_insn (gen_ashlti3_imm(operands[0], operands[1], operands[2]));
2260
      DONE;
2261
    }
2262
   operands[3] = gen_reg_rtx (TImode);")
2263
 
2264
(define_insn_and_split "ashlti3_imm"
2265
  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2266
        (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2267
                   (match_operand:SI 2 "immediate_operand" "O,P")))]
2268
  ""
2269
  "@
2270
   shlqbyi\t%0,%1,%h2
2271
   shlqbii\t%0,%1,%e2"
2272
  "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
2273
  [(set (match_dup:TI 0)
2274
        (ashift:TI (match_dup:TI 1)
2275
                   (match_dup:SI 3)))
2276
   (set (match_dup:TI 0)
2277
        (ashift:TI (match_dup:TI 0)
2278
                   (match_dup:SI 4)))]
2279
  {
2280
    HOST_WIDE_INT val = INTVAL(operands[2]);
2281
    operands[3] = GEN_INT (val&7);
2282
    operands[4] = GEN_INT (val&-8);
2283
  }
2284
  [(set_attr "type" "shuf,shuf")])
2285
 
2286
(define_insn_and_split "ashlti3_reg"
2287
  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2288
        (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
2289
                   (match_operand:SI 2 "spu_reg_operand" "r")))
2290
   (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
2291
  ""
2292
  "#"
2293
  ""
2294
  [(set (match_dup:TI 3)
2295
        (ashift:TI (match_dup:TI 1)
2296
                   (and:SI (match_dup:SI 2)
2297
                           (const_int 7))))
2298
   (set (match_dup:TI 0)
2299
        (ashift:TI (match_dup:TI 3)
2300
                   (and:SI (match_dup:SI 2)
2301
                           (const_int -8))))]
2302
  "")
2303
 
2304
(define_insn "shlqbybi_ti"
2305
  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2306
        (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2307
                   (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2308
                           (const_int -8))))]
2309
  ""
2310
  "@
2311
   shlqbybi\t%0,%1,%2
2312
   shlqbyi\t%0,%1,%h2"
2313
  [(set_attr "type" "shuf,shuf")])
2314
 
2315
(define_insn "shlqbi_ti"
2316
  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2317
        (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2318
                   (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2319
                           (const_int 7))))]
2320
  ""
2321
  "@
2322
   shlqbi\t%0,%1,%2
2323
   shlqbii\t%0,%1,%e2"
2324
  [(set_attr "type" "shuf,shuf")])
2325
 
2326
(define_insn "shlqby_ti"
2327
  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2328
        (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2329
                   (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2330
                            (const_int 8))))]
2331
  ""
2332
  "@
2333
   shlqby\t%0,%1,%2
2334
   shlqbyi\t%0,%1,%f2"
2335
  [(set_attr "type" "shuf,shuf")])
2336
 
2337
 
2338
;; lshr, vlshr
2339
 
2340
(define_insn_and_split "lshr3"
2341
  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2342
        (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2343
                       (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2344
   (clobber (match_scratch:VHSI 3 "=&r,X"))]
2345
  ""
2346
  "@
2347
   #
2348
   rotmi\t%0,%1,-%2"
2349
  "reload_completed && GET_CODE (operands[2]) == REG"
2350
  [(set (match_dup:VHSI 3)
2351
        (neg:VHSI (match_dup:VHSI 2)))
2352
   (set (match_dup:VHSI 0)
2353
        (lshiftrt:VHSI (match_dup:VHSI 1)
2354
                       (neg:VHSI (match_dup:VHSI 3))))]
2355
  ""
2356
  [(set_attr "type" "*,fx3")])
2357
 
2358
(define_insn "lshr3_imm"
2359
  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2360
        (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2361
                       (match_operand:VHSI 2 "immediate_operand" "W")))]
2362
  ""
2363
  "rotmi\t%0,%1,-%2"
2364
  [(set_attr "type" "fx3")])
2365
 
2366
(define_insn "rotm_"
2367
  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2368
        (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2369
                       (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2370
  ""
2371
  "@
2372
   rotm\t%0,%1,%2
2373
   rotmi\t%0,%1,-%2"
2374
  [(set_attr "type" "fx3")])
2375
 
2376
(define_insn_and_split "lshr3"
2377
  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r,r")
2378
        (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r,r")
2379
                      (match_operand:SI 2 "spu_nonmem_operand" "r,O,P")))]
2380
  ""
2381
  "@
2382
   #
2383
   rotqmbyi\t%0,%1,-%h2
2384
   rotqmbii\t%0,%1,-%e2"
2385
  "REG_P (operands[2]) || (!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2]))"
2386
  [(set (match_dup:DTI 3)
2387
        (lshiftrt:DTI (match_dup:DTI 1)
2388
                      (match_dup:SI 4)))
2389
   (set (match_dup:DTI 0)
2390
        (lshiftrt:DTI (match_dup:DTI 3)
2391
                      (match_dup:SI 5)))]
2392
  {
2393
    operands[3] = gen_reg_rtx (mode);
2394
    if (GET_CODE (operands[2]) == CONST_INT)
2395
      {
2396
        HOST_WIDE_INT val = INTVAL(operands[2]);
2397
        operands[4] = GEN_INT (val & 7);
2398
        operands[5] = GEN_INT (val & -8);
2399
      }
2400
    else
2401
      {
2402
        rtx t0 = gen_reg_rtx (SImode);
2403
        rtx t1 = gen_reg_rtx (SImode);
2404
        emit_insn (gen_subsi3(t0, GEN_INT(0), operands[2]));
2405
        emit_insn (gen_subsi3(t1, GEN_INT(7), operands[2]));
2406
        operands[4] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, t0), GEN_INT (7));
2407
        operands[5] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, gen_rtx_AND (SImode, t1, GEN_INT (-8))), GEN_INT (-8));
2408
      }
2409
  }
2410
  [(set_attr "type" "*,shuf,shuf")])
2411
 
2412
(define_expand "shrqbybi_"
2413
  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2414
        (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2415
                      (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2416
                                              (const_int -8)))
2417
                              (const_int -8))))]
2418
  ""
2419
  {
2420
    if (GET_CODE (operands[2]) == CONST_INT)
2421
      operands[2] = GEN_INT (7 - INTVAL (operands[2]));
2422
    else
2423
      {
2424
        rtx t0 = gen_reg_rtx (SImode);
2425
        emit_insn (gen_subsi3 (t0, GEN_INT (7), operands[2]));
2426
        operands[2] = t0;
2427
      }
2428
  })
2429
 
2430
(define_insn "rotqmbybi_"
2431
  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2432
        (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2433
                      (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2434
                                              (const_int -8)))
2435
                              (const_int -8))))]
2436
  ""
2437
  "@
2438
   rotqmbybi\t%0,%1,%2
2439
   rotqmbyi\t%0,%1,-%H2"
2440
  [(set_attr "type" "shuf")])
2441
 
2442
(define_insn_and_split "shrqbi_"
2443
  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2444
        (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2445
                      (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2446
                              (const_int 7))))
2447
   (clobber (match_scratch:SI 3 "=&r,X"))]
2448
  ""
2449
  "#"
2450
  "reload_completed"
2451
  [(set (match_dup:DTI 0)
2452
        (lshiftrt:DTI (match_dup:DTI 1)
2453
                      (and:SI (neg:SI (match_dup:SI 3)) (const_int 7))))]
2454
  {
2455
    if (GET_CODE (operands[2]) == CONST_INT)
2456
      operands[3] = GEN_INT (-INTVAL (operands[2]));
2457
    else
2458
      emit_insn (gen_subsi3 (operands[3], GEN_INT (0), operands[2]));
2459
  }
2460
  [(set_attr "type" "shuf")])
2461
 
2462
(define_insn "rotqmbi_"
2463
  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2464
        (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2465
                      (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2466
                              (const_int 7))))]
2467
  ""
2468
  "@
2469
   rotqmbi\t%0,%1,%2
2470
   rotqmbii\t%0,%1,-%E2"
2471
  [(set_attr "type" "shuf")])
2472
 
2473
(define_expand "shrqby_"
2474
  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2475
        (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2476
                      (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2477
                               (const_int 8))))]
2478
  ""
2479
  {
2480
    if (GET_CODE (operands[2]) == CONST_INT)
2481
      operands[2] = GEN_INT (-INTVAL (operands[2]));
2482
    else
2483
      {
2484
        rtx t0 = gen_reg_rtx (SImode);
2485
        emit_insn (gen_subsi3 (t0, GEN_INT (0), operands[2]));
2486
        operands[2] = t0;
2487
      }
2488
  })
2489
 
2490
(define_insn "rotqmby_"
2491
  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2492
        (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2493
                      (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2494
                               (const_int 8))))]
2495
  ""
2496
  "@
2497
   rotqmby\t%0,%1,%2
2498
   rotqmbyi\t%0,%1,-%F2"
2499
  [(set_attr "type" "shuf")])
2500
 
2501
 
2502
;; ashr, vashr
2503
 
2504
(define_insn_and_split "ashr3"
2505
  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2506
        (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2507
                       (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2508
   (clobber (match_scratch:VHSI 3 "=&r,X"))]
2509
  ""
2510
  "@
2511
   #
2512
   rotmai\t%0,%1,-%2"
2513
  "reload_completed && GET_CODE (operands[2]) == REG"
2514
  [(set (match_dup:VHSI 3)
2515
        (neg:VHSI (match_dup:VHSI 2)))
2516
   (set (match_dup:VHSI 0)
2517
        (ashiftrt:VHSI (match_dup:VHSI 1)
2518
                       (neg:VHSI (match_dup:VHSI 3))))]
2519
  ""
2520
  [(set_attr "type" "*,fx3")])
2521
 
2522
(define_insn "ashr3_imm"
2523
  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2524
        (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2525
                       (match_operand:VHSI 2 "immediate_operand" "W")))]
2526
  ""
2527
  "rotmai\t%0,%1,-%2"
2528
  [(set_attr "type" "fx3")])
2529
 
2530
 
2531
(define_insn "rotma_"
2532
  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2533
        (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2534
                       (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2535
  ""
2536
  "@
2537
   rotma\t%0,%1,%2
2538
   rotmai\t%0,%1,-%2"
2539
  [(set_attr "type" "fx3")])
2540
 
2541
(define_insn_and_split "ashrdi3"
2542
  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2543
        (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2544
                     (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2545
   (clobber (match_scratch:TI 3 "=&r,&r"))
2546
   (clobber (match_scratch:TI 4 "=&r,&r"))
2547
   (clobber (match_scratch:SI 5 "=&r,&r"))]
2548
  ""
2549
  "#"
2550
  "reload_completed"
2551
  [(set (match_dup:DI 0)
2552
        (ashiftrt:DI (match_dup:DI 1)
2553
                     (match_dup:SI 2)))]
2554
  {
2555
    rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2556
    rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
2557
    rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2558
    rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
2559
    rtx op2 = operands[2];
2560
    rtx op3 = operands[3];
2561
    rtx op4 = operands[4];
2562
    rtx op5 = operands[5];
2563
 
2564
    if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
2565
      {
2566
        rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
2567
        emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
2568
        emit_insn (gen_spu_fsm (op0v, op0s));
2569
      }
2570
    else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
2571
      {
2572
        rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
2573
        HOST_WIDE_INT val = INTVAL (op2);
2574
        emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
2575
        emit_insn (gen_spu_xswd (op0d, op0v));
2576
        if (val > 32)
2577
          emit_insn (gen_vashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
2578
      }
2579
    else
2580
      {
2581
        rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
2582
        unsigned char arr[16] = {
2583
          0xff, 0xff, 0xff, 0xff,
2584
          0xff, 0xff, 0xff, 0xff,
2585
          0x00, 0x00, 0x00, 0x00,
2586
          0x00, 0x00, 0x00, 0x00
2587
        };
2588
 
2589
        emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
2590
        emit_move_insn (op4, array_to_constant (TImode, arr));
2591
        emit_insn (gen_spu_fsm (op3v, op5));
2592
 
2593
        if (GET_CODE (operands[2]) == REG)
2594
          {
2595
            emit_insn (gen_selb (op4, op3, op1, op4));
2596
            emit_insn (gen_negsi2 (op5, op2));
2597
            emit_insn (gen_rotqbybi_ti (op0, op4, op5));
2598
            emit_insn (gen_rotqbi_ti (op0, op0, op5));
2599
          }
2600
        else
2601
          {
2602
            HOST_WIDE_INT val = -INTVAL (op2);
2603
            emit_insn (gen_selb (op0, op3, op1, op4));
2604
            if ((val - 7) / 8)
2605
              emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
2606
            if (val % 8)
2607
              emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
2608
          }
2609
      }
2610
    DONE;
2611
  })
2612
 
2613
 
2614
(define_insn_and_split "ashrti3"
2615
  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2616
        (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2617
                     (match_operand:SI 2 "spu_nonmem_operand" "r,i")))]
2618
  ""
2619
  "#"
2620
  ""
2621
  [(set (match_dup:TI 0)
2622
        (ashiftrt:TI (match_dup:TI 1)
2623
                     (match_dup:SI 2)))]
2624
  {
2625
    rtx sign_shift = gen_reg_rtx (SImode);
2626
    rtx sign_mask = gen_reg_rtx (TImode);
2627
    rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
2628
    rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
2629
    rtx t = gen_reg_rtx (TImode);
2630
    emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
2631
    emit_insn (gen_vashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
2632
    emit_insn (gen_fsm_ti (sign_mask, sign_mask));
2633
    emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
2634
    emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
2635
    emit_insn (gen_iorti3 (operands[0], t, sign_mask));
2636
    DONE;
2637
  })
2638
 
2639
;; fsm is used after rotam to replicate the sign across the whole register.
2640
(define_insn "fsm_ti"
2641
  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2642
        (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
2643
  ""
2644
  "fsm\t%0,%1"
2645
  [(set_attr "type" "shuf")])
2646
 
2647
 
2648
;; vrotl, rotl
2649
 
2650
(define_insn "rotl3"
2651
  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2652
        (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2653
                     (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2654
  ""
2655
  "@
2656
  rot\t%0,%1,%2
2657
  roti\t%0,%1,%2"
2658
  [(set_attr "type" "fx3")])
2659
 
2660
(define_insn "rotlti3"
2661
  [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
2662
        (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
2663
                   (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
2664
  ""
2665
  "@
2666
  rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
2667
  rotqbyi\t%0,%1,%h2
2668
  rotqbii\t%0,%1,%e2
2669
  rotqbyi\t%0,%1,%h2\;rotqbii\t%0,%0,%e2"
2670
  [(set_attr "length" "8,4,4,8")
2671
   (set_attr "type" "multi1,shuf,shuf,multi1")])
2672
 
2673
(define_insn "rotqbybi_ti"
2674
  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2675
        (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2676
                   (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2677
                           (const_int -8))))]
2678
  ""
2679
  "@
2680
  rotqbybi\t%0,%1,%2
2681
  rotqbyi\t%0,%1,%h2"
2682
  [(set_attr "type" "shuf,shuf")])
2683
 
2684
(define_insn "rotqby_ti"
2685
  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2686
        (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2687
                   (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2688
                            (const_int 8))))]
2689
  ""
2690
  "@
2691
  rotqby\t%0,%1,%2
2692
  rotqbyi\t%0,%1,%f2"
2693
  [(set_attr "type" "shuf,shuf")])
2694
 
2695
(define_insn "rotqbi_ti"
2696
  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2697
        (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2698
                   (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2699
                           (const_int 7))))]
2700
  ""
2701
  "@
2702
  rotqbi\t%0,%1,%2
2703
  rotqbii\t%0,%1,%e2"
2704
  [(set_attr "type" "shuf,shuf")])
2705
 
2706
 
2707
;; struct extract/insert
2708
;; We handle mem's because GCC will generate invalid SUBREG's
2709
;; and inefficient code.
2710
 
2711
(define_expand "extv"
2712
  [(set (match_operand:TI 0 "register_operand" "")
2713
        (sign_extract:TI (match_operand 1 "nonimmediate_operand" "")
2714
                         (match_operand:SI 2 "const_int_operand" "")
2715
                         (match_operand:SI 3 "const_int_operand" "")))]
2716
  ""
2717
  {
2718
    spu_expand_extv (operands, 0);
2719
    DONE;
2720
  })
2721
 
2722
(define_expand "extzv"
2723
  [(set (match_operand:TI 0 "register_operand" "")
2724
        (zero_extract:TI (match_operand 1 "nonimmediate_operand" "")
2725
                         (match_operand:SI 2 "const_int_operand" "")
2726
                         (match_operand:SI 3 "const_int_operand" "")))]
2727
  ""
2728
  {
2729
    spu_expand_extv (operands, 1);
2730
    DONE;
2731
  })
2732
 
2733
(define_expand "insv"
2734
  [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2735
                      (match_operand:SI 1 "const_int_operand" "")
2736
                      (match_operand:SI 2 "const_int_operand" ""))
2737
        (match_operand 3 "nonmemory_operand" ""))]
2738
  ""
2739
  { spu_expand_insv(operands); DONE; })
2740
 
2741
;; Simplify a number of patterns that get generated by extv, extzv,
2742
;; insv, and loads.
2743
(define_insn_and_split "trunc_shr_ti"
2744
  [(set (match_operand:QHSI 0 "spu_reg_operand" "=r")
2745
        (truncate:QHSI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2746
                                                                (const_int 96)])))]
2747
  ""
2748
  "#"
2749
  "reload_completed"
2750
  [(const_int 0)]
2751
  {
2752
    spu_split_convert (operands);
2753
    DONE;
2754
  }
2755
  [(set_attr "type" "convert")
2756
   (set_attr "length" "0")])
2757
 
2758
(define_insn_and_split "trunc_shr_tidi"
2759
  [(set (match_operand:DI 0 "spu_reg_operand" "=r")
2760
        (truncate:DI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2761
                                                              (const_int 64)])))]
2762
  ""
2763
  "#"
2764
  "reload_completed"
2765
  [(const_int 0)]
2766
  {
2767
    spu_split_convert (operands);
2768
    DONE;
2769
  }
2770
  [(set_attr "type" "convert")
2771
   (set_attr "length" "0")])
2772
 
2773
(define_insn_and_split "shl_ext_ti"
2774
  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2775
        (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:QHSI 1 "spu_reg_operand" "0")])
2776
                   (const_int 96)))]
2777
  ""
2778
  "#"
2779
  "reload_completed"
2780
  [(const_int 0)]
2781
  {
2782
    spu_split_convert (operands);
2783
    DONE;
2784
  }
2785
  [(set_attr "type" "convert")
2786
   (set_attr "length" "0")])
2787
 
2788
(define_insn_and_split "shl_ext_diti"
2789
  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2790
        (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:DI 1 "spu_reg_operand" "0")])
2791
                   (const_int 64)))]
2792
  ""
2793
  "#"
2794
  "reload_completed"
2795
  [(const_int 0)]
2796
  {
2797
    spu_split_convert (operands);
2798
    DONE;
2799
  }
2800
  [(set_attr "type" "convert")
2801
   (set_attr "length" "0")])
2802
 
2803
(define_insn "sext_trunc_lshr_tiqisi"
2804
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2805
        (sign_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2806
                                                                              (const_int 120)]))))]
2807
  ""
2808
  "rotmai\t%0,%1,-24"
2809
  [(set_attr "type" "fx3")])
2810
 
2811
(define_insn "zext_trunc_lshr_tiqisi"
2812
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2813
        (zero_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2814
                                                                              (const_int 120)]))))]
2815
  ""
2816
  "rotmi\t%0,%1,-24"
2817
  [(set_attr "type" "fx3")])
2818
 
2819
(define_insn "sext_trunc_lshr_tihisi"
2820
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2821
        (sign_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2822
                                                                              (const_int 112)]))))]
2823
  ""
2824
  "rotmai\t%0,%1,-16"
2825
  [(set_attr "type" "fx3")])
2826
 
2827
(define_insn "zext_trunc_lshr_tihisi"
2828
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2829
        (zero_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2830
                                                                              (const_int 112)]))))]
2831
  ""
2832
  "rotmi\t%0,%1,-16"
2833
  [(set_attr "type" "fx3")])
2834
 
2835
 
2836
;; String/block move insn.
2837
;; Argument 0 is the destination
2838
;; Argument 1 is the source
2839
;; Argument 2 is the length
2840
;; Argument 3 is the alignment
2841
 
2842
(define_expand "movstrsi"
2843
  [(parallel [(set (match_operand:BLK 0 "" "")
2844
                   (match_operand:BLK 1 "" ""))
2845
              (use (match_operand:SI 2 "" ""))
2846
              (use (match_operand:SI 3 "" ""))])]
2847
  ""
2848
  "
2849
  {
2850
    if (spu_expand_block_move (operands))
2851
      DONE;
2852
    else
2853
      FAIL;
2854
  }")
2855
 
2856
 
2857
;; jump
2858
 
2859
(define_insn "indirect_jump"
2860
  [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
2861
  ""
2862
  "bi\t%0"
2863
  [(set_attr "type" "br")])
2864
 
2865
(define_insn "jump"
2866
  [(set (pc)
2867
        (label_ref (match_operand 0 "" "")))]
2868
  ""
2869
  "br\t%0"
2870
  [(set_attr "type" "br")])
2871
 
2872
 
2873
;; return
2874
 
2875
;; This will be used for leaf functions, that don't save any regs and
2876
;; don't have locals on stack, maybe... that is for functions that
2877
;; don't change $sp and don't need to save $lr.
2878
(define_expand "return"
2879
    [(return)]
2880
  "direct_return()"
2881
  "")
2882
 
2883
;; used in spu_expand_epilogue to generate return from a function and
2884
;; explicitly set use of $lr.
2885
 
2886
(define_insn "_return"
2887
  [(return)]
2888
  ""
2889
  "bi\t$lr"
2890
  [(set_attr "type" "br")])
2891
 
2892
 
2893
 
2894
;; ceq
2895
 
2896
(define_insn "ceq_"
2897
  [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2898
        (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2899
                 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2900
  ""
2901
  "@
2902
  ceq\t%0,%1,%2
2903
  ceqi\t%0,%1,%2")
2904
 
2905
(define_insn_and_split "ceq_di"
2906
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2907
        (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
2908
               (match_operand:DI 2 "spu_reg_operand" "r")))]
2909
  ""
2910
  "#"
2911
  "reload_completed"
2912
  [(set (match_dup:SI 0)
2913
        (eq:SI (match_dup:DI 1)
2914
               (match_dup:DI 2)))]
2915
  {
2916
    rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2917
    rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2918
    rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2919
    emit_insn (gen_ceq_v4si (op0, op1, op2));
2920
    emit_insn (gen_spu_gb (op0, op0));
2921
    emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
2922
    DONE;
2923
  })
2924
 
2925
 
2926
;; We provide the TI compares for completeness and because some parts of
2927
;; gcc/libgcc use them, even though user code might never see it.
2928
(define_insn "ceq_ti"
2929
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2930
        (eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
2931
               (match_operand:TI 2 "spu_reg_operand" "r")))]
2932
  ""
2933
  "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
2934
  [(set_attr "type" "multi0")
2935
   (set_attr "length" "12")])
2936
 
2937
(define_insn "ceq_"
2938
  [(set (match_operand: 0 "spu_reg_operand" "=r")
2939
        (eq: (match_operand:VSF 1 "spu_reg_operand" "r")
2940
                  (match_operand:VSF 2 "spu_reg_operand" "r")))]
2941
  ""
2942
  "fceq\t%0,%1,%2")
2943
 
2944
(define_insn "cmeq_"
2945
  [(set (match_operand: 0 "spu_reg_operand" "=r")
2946
        (eq: (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
2947
                  (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
2948
  ""
2949
  "fcmeq\t%0,%1,%2")
2950
 
2951
;; These implementations will ignore checking of NaN or INF if
2952
;; compiled with option -ffinite-math-only.
2953
(define_expand "ceq_df"
2954
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2955
        (eq:SI (match_operand:DF 1 "spu_reg_operand" "r")
2956
               (match_operand:DF 2 "const_zero_operand" "i")))]
2957
  ""
2958
{
2959
  if (spu_arch == PROCESSOR_CELL)
2960
      {
2961
        rtx ra = gen_reg_rtx (V4SImode);
2962
        rtx rb = gen_reg_rtx (V4SImode);
2963
        rtx temp = gen_reg_rtx (TImode);
2964
        rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
2965
        rtx temp2 = gen_reg_rtx (V4SImode);
2966
        rtx biteq = gen_reg_rtx (V4SImode);
2967
        rtx ahi_inf = gen_reg_rtx (V4SImode);
2968
        rtx a_nan = gen_reg_rtx (V4SImode);
2969
        rtx a_abs = gen_reg_rtx (V4SImode);
2970
        rtx b_abs = gen_reg_rtx (V4SImode);
2971
        rtx iszero = gen_reg_rtx (V4SImode);
2972
        rtx sign_mask = gen_reg_rtx (V4SImode);
2973
        rtx nan_mask = gen_reg_rtx (V4SImode);
2974
        rtx hihi_promote = gen_reg_rtx (TImode);
2975
        rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
2976
                                                 0x7FFFFFFF, 0xFFFFFFFF);
2977
 
2978
        emit_move_insn (sign_mask, pat);
2979
        pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
2980
                                             0x7FF00000, 0x0);
2981
        emit_move_insn (nan_mask, pat);
2982
        pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
2983
                                           0x08090A0B, 0x18191A1B);
2984
        emit_move_insn (hihi_promote, pat);
2985
 
2986
        emit_insn (gen_spu_convert (ra, operands[1]));
2987
        emit_insn (gen_spu_convert (rb, operands[2]));
2988
        emit_insn (gen_ceq_v4si (biteq, ra, rb));
2989
        emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
2990
                                GEN_INT (4 * 8)));
2991
        emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
2992
 
2993
        emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
2994
        emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
2995
        if (!flag_finite_math_only)
2996
          {
2997
            emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
2998
            emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
2999
            emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3000
                                   GEN_INT (4 * 8)));
3001
            emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3002
            emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3003
          }
3004
        emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3005
        emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3006
        emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3007
                                GEN_INT (4 * 8)));
3008
        emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3009
        emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3010
        if (!flag_finite_math_only)
3011
          {
3012
            emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3013
          }
3014
        emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3015
        DONE;
3016
      }
3017
})
3018
 
3019
(define_insn "ceq__celledp"
3020
  [(set (match_operand: 0 "spu_reg_operand" "=r")
3021
        (eq: (match_operand:VDF 1 "spu_reg_operand" "r")
3022
                   (match_operand:VDF 2 "spu_reg_operand" "r")))]
3023
  "spu_arch == PROCESSOR_CELLEDP"
3024
  "dfceq\t%0,%1,%2"
3025
  [(set_attr "type" "fpd")])
3026
 
3027
(define_insn "cmeq__celledp"
3028
  [(set (match_operand: 0 "spu_reg_operand" "=r")
3029
        (eq: (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3030
                   (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3031
  "spu_arch == PROCESSOR_CELLEDP"
3032
  "dfcmeq\t%0,%1,%2"
3033
  [(set_attr "type" "fpd")])
3034
 
3035
(define_expand "ceq_v2df"
3036
  [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3037
        (eq:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3038
                 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3039
  ""
3040
{
3041
  if (spu_arch == PROCESSOR_CELL)
3042
    {
3043
      rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3044
      rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3045
      rtx temp = gen_reg_rtx (TImode);
3046
      rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3047
      rtx temp2 = gen_reg_rtx (V4SImode);
3048
      rtx biteq = gen_reg_rtx (V4SImode);
3049
      rtx ahi_inf = gen_reg_rtx (V4SImode);
3050
      rtx a_nan = gen_reg_rtx (V4SImode);
3051
      rtx a_abs = gen_reg_rtx (V4SImode);
3052
      rtx b_abs = gen_reg_rtx (V4SImode);
3053
      rtx iszero = gen_reg_rtx (V4SImode);
3054
      rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3055
                                               0x7FFFFFFF, 0xFFFFFFFF);
3056
      rtx sign_mask = gen_reg_rtx (V4SImode);
3057
      rtx nan_mask = gen_reg_rtx (V4SImode);
3058
      rtx hihi_promote = gen_reg_rtx (TImode);
3059
 
3060
      emit_move_insn (sign_mask, pat);
3061
      pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3062
                                             0x7FF00000, 0x0);
3063
      emit_move_insn (nan_mask, pat);
3064
      pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3065
                                           0x08090A0B, 0x18191A1B);
3066
      emit_move_insn (hihi_promote, pat);
3067
 
3068
      emit_insn (gen_ceq_v4si (biteq, ra, rb));
3069
      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3070
                              GEN_INT (4 * 8)));
3071
      emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3072
      emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3073
      emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3074
      emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3075
      emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3076
      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3077
                              GEN_INT (4 * 8)));
3078
      emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3079
      emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3080
      emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3081
      emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3082
      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3083
                              GEN_INT (4 * 8)));
3084
      emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3085
      emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3086
      emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3087
      emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3088
      DONE;
3089
  }
3090
})
3091
 
3092
(define_expand "cmeq_v2df"
3093
  [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3094
        (eq:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3095
                 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3096
  ""
3097
{
3098
  if (spu_arch == PROCESSOR_CELL)
3099
    {
3100
      rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3101
      rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3102
      rtx temp = gen_reg_rtx (TImode);
3103
      rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3104
      rtx temp2 = gen_reg_rtx (V4SImode);
3105
      rtx biteq = gen_reg_rtx (V4SImode);
3106
      rtx ahi_inf = gen_reg_rtx (V4SImode);
3107
      rtx a_nan = gen_reg_rtx (V4SImode);
3108
      rtx a_abs = gen_reg_rtx (V4SImode);
3109
      rtx b_abs = gen_reg_rtx (V4SImode);
3110
 
3111
      rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3112
                                               0x7FFFFFFF, 0xFFFFFFFF);
3113
      rtx sign_mask = gen_reg_rtx (V4SImode);
3114
      rtx nan_mask = gen_reg_rtx (V4SImode);
3115
      rtx hihi_promote = gen_reg_rtx (TImode);
3116
 
3117
      emit_move_insn (sign_mask, pat);
3118
 
3119
      pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3120
                                           0x7FF00000, 0x0);
3121
      emit_move_insn (nan_mask, pat);
3122
      pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3123
                                         0x08090A0B, 0x18191A1B);
3124
      emit_move_insn (hihi_promote, pat);
3125
 
3126
      emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3127
      emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3128
      emit_insn (gen_ceq_v4si (biteq, a_abs, b_abs));
3129
      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3130
                                                    GEN_INT (4 * 8)));
3131
      emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3132
      emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3133
      emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3134
      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3135
                                                    GEN_INT (4 * 8)));
3136
      emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3137
      emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3138
      emit_insn (gen_andc_v4si (temp2, biteq, a_nan));
3139
      emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3140
      DONE;
3141
  }
3142
})
3143
 
3144
 
3145
;; cgt
3146
 
3147
(define_insn "cgt_"
3148
  [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3149
        (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3150
                  (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3151
  ""
3152
  "@
3153
  cgt\t%0,%1,%2
3154
  cgti\t%0,%1,%2")
3155
 
3156
(define_insn "cgt_di_m1"
3157
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3158
        (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3159
               (const_int -1)))]
3160
  ""
3161
  "cgti\t%0,%1,-1")
3162
 
3163
(define_insn_and_split "cgt_di"
3164
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3165
        (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3166
               (match_operand:DI 2 "spu_reg_operand" "r")))
3167
   (clobber (match_scratch:V4SI 3 "=&r"))
3168
   (clobber (match_scratch:V4SI 4 "=&r"))
3169
   (clobber (match_scratch:V4SI 5 "=&r"))]
3170
  ""
3171
  "#"
3172
  "reload_completed"
3173
  [(set (match_dup:SI 0)
3174
        (gt:SI (match_dup:DI 1)
3175
               (match_dup:DI 2)))]
3176
  {
3177
    rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3178
    rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3179
    rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3180
    rtx op3 = operands[3];
3181
    rtx op4 = operands[4];
3182
    rtx op5 = operands[5];
3183
    rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
3184
    emit_insn (gen_clgt_v4si (op3, op1, op2));
3185
    emit_insn (gen_ceq_v4si (op4, op1, op2));
3186
    emit_insn (gen_cgt_v4si (op5, op1, op2));
3187
    emit_insn (gen_spu_xswd (op3d, op3));
3188
    emit_insn (gen_selb (op0, op5, op3, op4));
3189
    DONE;
3190
  })
3191
 
3192
(define_insn "cgt_ti"
3193
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3194
        (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
3195
               (match_operand:TI 2 "spu_reg_operand" "r")))
3196
   (clobber (match_scratch:V4SI 3 "=&r"))
3197
   (clobber (match_scratch:V4SI 4 "=&r"))
3198
   (clobber (match_scratch:V4SI 5 "=&r"))]
3199
  ""
3200
  "clgt\t%4,%1,%2\;\
3201
ceq\t%3,%1,%2\;\
3202
cgt\t%5,%1,%2\;\
3203
shlqbyi\t%0,%4,4\;\
3204
selb\t%0,%4,%0,%3\;\
3205
shlqbyi\t%0,%0,4\;\
3206
selb\t%0,%4,%0,%3\;\
3207
shlqbyi\t%0,%0,4\;\
3208
selb\t%0,%5,%0,%3"
3209
  [(set_attr "type" "multi0")
3210
   (set_attr "length" "36")])
3211
 
3212
(define_insn "cgt_"
3213
  [(set (match_operand: 0 "spu_reg_operand" "=r")
3214
        (gt: (match_operand:VSF 1 "spu_reg_operand" "r")
3215
                  (match_operand:VSF 2 "spu_reg_operand" "r")))]
3216
  ""
3217
  "fcgt\t%0,%1,%2")
3218
 
3219
(define_insn "cmgt_"
3220
  [(set (match_operand: 0 "spu_reg_operand" "=r")
3221
        (gt: (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
3222
                  (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
3223
  ""
3224
  "fcmgt\t%0,%1,%2")
3225
 
3226
(define_expand "cgt_df"
3227
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3228
        (gt:SI (match_operand:DF 1 "spu_reg_operand" "r")
3229
               (match_operand:DF 2 "const_zero_operand" "i")))]
3230
  ""
3231
{
3232
  if (spu_arch == PROCESSOR_CELL)
3233
    {
3234
      rtx ra = gen_reg_rtx (V4SImode);
3235
      rtx rb = gen_reg_rtx (V4SImode);
3236
      rtx zero = gen_reg_rtx (V4SImode);
3237
      rtx temp = gen_reg_rtx (TImode);
3238
      rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3239
      rtx temp2 = gen_reg_rtx (V4SImode);
3240
      rtx hi_inf = gen_reg_rtx (V4SImode);
3241
      rtx a_nan = gen_reg_rtx (V4SImode);
3242
      rtx b_nan = gen_reg_rtx (V4SImode);
3243
      rtx a_abs = gen_reg_rtx (V4SImode);
3244
      rtx b_abs = gen_reg_rtx (V4SImode);
3245
      rtx asel = gen_reg_rtx (V4SImode);
3246
      rtx bsel = gen_reg_rtx (V4SImode);
3247
      rtx abor = gen_reg_rtx (V4SImode);
3248
      rtx bbor = gen_reg_rtx (V4SImode);
3249
      rtx gt_hi = gen_reg_rtx (V4SImode);
3250
      rtx gt_lo = gen_reg_rtx (V4SImode);
3251
      rtx sign_mask = gen_reg_rtx (V4SImode);
3252
      rtx nan_mask = gen_reg_rtx (V4SImode);
3253
      rtx hi_promote = gen_reg_rtx (TImode);
3254
      rtx borrow_shuffle = gen_reg_rtx (TImode);
3255
 
3256
      rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3257
                                               0x7FFFFFFF, 0xFFFFFFFF);
3258
      emit_move_insn (sign_mask, pat);
3259
      pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3260
                                             0x7FF00000, 0x0);
3261
      emit_move_insn (nan_mask, pat);
3262
      pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3263
                                         0x08090A0B, 0x08090A0B);
3264
      emit_move_insn (hi_promote, pat);
3265
      pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3266
                                         0x0C0D0E0F, 0xC0C0C0C0);
3267
      emit_move_insn (borrow_shuffle, pat);
3268
 
3269
      emit_insn (gen_spu_convert (ra, operands[1]));
3270
      emit_insn (gen_spu_convert (rb, operands[2]));
3271
      emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3272
      emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3273
 
3274
      if (!flag_finite_math_only)
3275
        {
3276
          /* check if ra is NaN  */
3277
          emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3278
          emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3279
          emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3280
                                  GEN_INT (4 * 8)));
3281
          emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3282
          emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3283
          emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3284
 
3285
          /* check if rb is NaN  */
3286
          emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3287
          emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3288
          emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3289
                                  GEN_INT (4 * 8)));
3290
          emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3291
          emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3292
          emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3293
 
3294
          /* check if ra or rb is NaN  */
3295
          emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3296
        }
3297
      emit_move_insn (zero, CONST0_RTX (V4SImode));
3298
      emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3299
      emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3300
      emit_insn (gen_bg_v4si (abor, zero, a_abs));
3301
      emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3302
      emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3303
      emit_insn (gen_selb (abor, a_abs, abor, asel));
3304
 
3305
      emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3306
      emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3307
      emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3308
      emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3309
      emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3310
      emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3311
 
3312
      emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3313
      emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3314
      emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3315
      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3316
                                GEN_INT (4 * 8)));
3317
      emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3318
      emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3319
      emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3320
      if (!flag_finite_math_only)
3321
        {
3322
          /* correct for NaNs  */
3323
          emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3324
        }
3325
      emit_insn (gen_spu_convert (operands[0], temp2));
3326
      DONE;
3327
    }
3328
})
3329
 
3330
(define_insn "cgt__celledp"
3331
  [(set (match_operand: 0 "spu_reg_operand" "=r")
3332
        (gt: (match_operand:VDF 1 "spu_reg_operand" "r")
3333
                   (match_operand:VDF 2 "spu_reg_operand" "r")))]
3334
  "spu_arch == PROCESSOR_CELLEDP"
3335
  "dfcgt\t%0,%1,%2"
3336
  [(set_attr "type" "fpd")])
3337
 
3338
(define_insn "cmgt__celledp"
3339
  [(set (match_operand: 0 "spu_reg_operand" "=r")
3340
        (gt: (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3341
                   (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3342
  "spu_arch == PROCESSOR_CELLEDP"
3343
  "dfcmgt\t%0,%1,%2"
3344
  [(set_attr "type" "fpd")])
3345
 
3346
(define_expand "cgt_v2df"
3347
  [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3348
        (gt:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3349
                 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3350
  ""
3351
{
3352
  if (spu_arch == PROCESSOR_CELL)
3353
    {
3354
      rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3355
      rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3356
      rtx zero = gen_reg_rtx (V4SImode);
3357
      rtx temp = gen_reg_rtx (TImode);
3358
      rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3359
      rtx temp2 = gen_reg_rtx (V4SImode);
3360
      rtx hi_inf = gen_reg_rtx (V4SImode);
3361
      rtx a_nan = gen_reg_rtx (V4SImode);
3362
      rtx b_nan = gen_reg_rtx (V4SImode);
3363
      rtx a_abs = gen_reg_rtx (V4SImode);
3364
      rtx b_abs = gen_reg_rtx (V4SImode);
3365
      rtx asel = gen_reg_rtx (V4SImode);
3366
      rtx bsel = gen_reg_rtx (V4SImode);
3367
      rtx abor = gen_reg_rtx (V4SImode);
3368
      rtx bbor = gen_reg_rtx (V4SImode);
3369
      rtx gt_hi = gen_reg_rtx (V4SImode);
3370
      rtx gt_lo = gen_reg_rtx (V4SImode);
3371
      rtx sign_mask = gen_reg_rtx (V4SImode);
3372
      rtx nan_mask = gen_reg_rtx (V4SImode);
3373
      rtx hi_promote = gen_reg_rtx (TImode);
3374
      rtx borrow_shuffle = gen_reg_rtx (TImode);
3375
      rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3376
                                               0x7FFFFFFF, 0xFFFFFFFF);
3377
      emit_move_insn (sign_mask, pat);
3378
      pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3379
                                           0x7FF00000, 0x0);
3380
      emit_move_insn (nan_mask, pat);
3381
      pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3382
                                         0x08090A0B, 0x08090A0B);
3383
      emit_move_insn (hi_promote, pat);
3384
      pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3385
                                         0x0C0D0E0F, 0xC0C0C0C0);
3386
      emit_move_insn (borrow_shuffle, pat);
3387
 
3388
      emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3389
      emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3390
      emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3391
      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3392
                                                    GEN_INT (4 * 8)));
3393
      emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3394
      emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3395
      emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3396
      emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3397
      emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3398
      emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3399
      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3400
                                                    GEN_INT (4 * 8)));
3401
      emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3402
      emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3403
      emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3404
      emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3405
      emit_move_insn (zero, CONST0_RTX (V4SImode));
3406
      emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3407
      emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3408
      emit_insn (gen_bg_v4si (abor, zero, a_abs));
3409
      emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3410
      emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3411
      emit_insn (gen_selb (abor, a_abs, abor, asel));
3412
      emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3413
      emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3414
      emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3415
      emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3416
      emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3417
      emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3418
      emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3419
      emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3420
      emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3421
      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3422
                                                    GEN_INT (4 * 8)));
3423
      emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3424
      emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3425
 
3426
      emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3427
      emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3428
      emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3429
      DONE;
3430
    }
3431
})
3432
 
3433
(define_expand "cmgt_v2df"
3434
  [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3435
        (gt:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3436
                 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3437
  ""
3438
{
3439
  if (spu_arch == PROCESSOR_CELL)
3440
    {
3441
      rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3442
      rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3443
      rtx temp = gen_reg_rtx (TImode);
3444
      rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3445
      rtx temp2 = gen_reg_rtx (V4SImode);
3446
      rtx hi_inf = gen_reg_rtx (V4SImode);
3447
      rtx a_nan = gen_reg_rtx (V4SImode);
3448
      rtx b_nan = gen_reg_rtx (V4SImode);
3449
      rtx a_abs = gen_reg_rtx (V4SImode);
3450
      rtx b_abs = gen_reg_rtx (V4SImode);
3451
      rtx gt_hi = gen_reg_rtx (V4SImode);
3452
      rtx gt_lo = gen_reg_rtx (V4SImode);
3453
      rtx sign_mask = gen_reg_rtx (V4SImode);
3454
      rtx nan_mask = gen_reg_rtx (V4SImode);
3455
      rtx hi_promote = gen_reg_rtx (TImode);
3456
      rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3457
                                               0x7FFFFFFF, 0xFFFFFFFF);
3458
      emit_move_insn (sign_mask, pat);
3459
      pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3460
                                           0x7FF00000, 0x0);
3461
      emit_move_insn (nan_mask, pat);
3462
      pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3463
                                         0x08090A0B, 0x08090A0B);
3464
      emit_move_insn (hi_promote, pat);
3465
 
3466
      emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3467
      emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3468
      emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3469
      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3470
                                                    GEN_INT (4 * 8)));
3471
      emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3472
      emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3473
      emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3474
      emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3475
      emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3476
      emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3477
      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3478
                                                    GEN_INT (4 * 8)));
3479
      emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3480
      emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3481
      emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3482
      emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3483
 
3484
      emit_insn (gen_clgt_v4si (gt_hi, a_abs, b_abs));
3485
      emit_insn (gen_clgt_v4si (gt_lo, a_abs, b_abs));
3486
      emit_insn (gen_ceq_v4si (temp2, a_abs, b_abs));
3487
      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3488
                                                    GEN_INT (4 * 8)));
3489
      emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3490
      emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3491
      emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3492
      emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3493
      emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3494
      DONE;
3495
    }
3496
})
3497
 
3498
 
3499
;; clgt
3500
 
3501
(define_insn "clgt_"
3502
  [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3503
        (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3504
                   (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3505
  ""
3506
  "@
3507
  clgt\t%0,%1,%2
3508
  clgti\t%0,%1,%2")
3509
 
3510
(define_insn_and_split "clgt_di"
3511
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3512
        (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
3513
                (match_operand:DI 2 "spu_reg_operand" "r")))
3514
   (clobber (match_scratch:V4SI 3 "=&r"))
3515
   (clobber (match_scratch:V4SI 4 "=&r"))
3516
   (clobber (match_scratch:V4SI 5 "=&r"))]
3517
  ""
3518
  "#"
3519
  "reload_completed"
3520
  [(set (match_dup:SI 0)
3521
        (gtu:SI (match_dup:DI 1)
3522
                (match_dup:DI 2)))]
3523
  {
3524
    rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3525
    rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3526
    rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3527
    rtx op3 = operands[3];
3528
    rtx op4 = operands[4];
3529
    rtx op5 = operands[5];
3530
    rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
3531
    emit_insn (gen_clgt_v4si (op3, op1, op2));
3532
    emit_insn (gen_ceq_v4si (op4, op1, op2));
3533
    emit_insn (gen_spu_xswd (op5d, op3));
3534
    emit_insn (gen_selb (op0, op3, op5, op4));
3535
    DONE;
3536
  })
3537
 
3538
(define_insn "clgt_ti"
3539
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3540
        (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
3541
               (match_operand:TI 2 "spu_reg_operand" "r")))
3542
   (clobber (match_scratch:V4SI 3 "=&r"))
3543
   (clobber (match_scratch:V4SI 4 "=&r"))]
3544
  ""
3545
  "ceq\t%3,%1,%2\;\
3546
clgt\t%4,%1,%2\;\
3547
shlqbyi\t%0,%4,4\;\
3548
selb\t%0,%4,%0,%3\;\
3549
shlqbyi\t%0,%0,4\;\
3550
selb\t%0,%4,%0,%3\;\
3551
shlqbyi\t%0,%0,4\;\
3552
selb\t%0,%4,%0,%3"
3553
  [(set_attr "type" "multi0")
3554
   (set_attr "length" "32")])
3555
 
3556
 
3557
;; dftsv
3558
(define_insn "dftsv_celledp"
3559
  [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3560
        (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand"  "r")
3561
                      (match_operand:SI   2 "const_int_operand" "i")]
3562
                      UNSPEC_DFTSV))]
3563
  "spu_arch == PROCESSOR_CELLEDP"
3564
  "dftsv\t%0,%1,%2"
3565
  [(set_attr "type" "fpd")])
3566
 
3567
(define_expand "dftsv"
3568
  [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3569
        (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3570
                      (match_operand:SI   2 "const_int_operand" "i")]
3571
                      UNSPEC_DFTSV))]
3572
  ""
3573
{
3574
  if (spu_arch == PROCESSOR_CELL)
3575
    {
3576
      rtx result = gen_reg_rtx (V4SImode);
3577
      emit_move_insn (result, CONST0_RTX (V4SImode));
3578
 
3579
      if (INTVAL (operands[2]))
3580
        {
3581
          rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3582
          rtx abs = gen_reg_rtx (V4SImode);
3583
          rtx sign = gen_reg_rtx (V4SImode);
3584
          rtx temp = gen_reg_rtx (TImode);
3585
          rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3586
          rtx temp2 = gen_reg_rtx (V4SImode);
3587
          rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3588
                                                   0x7FFFFFFF, 0xFFFFFFFF);
3589
          rtx sign_mask = gen_reg_rtx (V4SImode);
3590
          rtx hi_promote = gen_reg_rtx (TImode);
3591
          emit_move_insn (sign_mask, pat);
3592
          pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3593
                                             0x08090A0B, 0x08090A0B);
3594
          emit_move_insn (hi_promote, pat);
3595
 
3596
          emit_insn (gen_vashrv4si3 (sign, ra, spu_const (V4SImode, 31)));
3597
          emit_insn (gen_shufb (sign, sign, sign, hi_promote));
3598
          emit_insn (gen_andv4si3 (abs, ra, sign_mask));
3599
 
3600
          /* NaN  or +inf or -inf */
3601
          if (INTVAL (operands[2]) & 0x70)
3602
            {
3603
              rtx nan_mask = gen_reg_rtx (V4SImode);
3604
              rtx isinf = gen_reg_rtx (V4SImode);
3605
              pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3606
                                                   0x7FF00000, 0x0);
3607
              emit_move_insn (nan_mask, pat);
3608
              emit_insn (gen_ceq_v4si (isinf, abs, nan_mask));
3609
 
3610
              /* NaN  */
3611
              if (INTVAL (operands[2]) & 0x40)
3612
                {
3613
                  rtx isnan = gen_reg_rtx (V4SImode);
3614
                  emit_insn (gen_clgt_v4si (isnan, abs, nan_mask));
3615
                  emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isnan),
3616
                                                             GEN_INT (4 * 8)));
3617
                  emit_insn (gen_andv4si3 (temp2, temp_v4si, isinf));
3618
                  emit_insn (gen_iorv4si3 (isnan, isnan, temp2));
3619
                  emit_insn (gen_shufb (isnan, isnan, isnan, hi_promote));
3620
                  emit_insn (gen_iorv4si3 (result, result, isnan));
3621
                }
3622
              /* +inf or -inf  */
3623
              if (INTVAL (operands[2]) & 0x30)
3624
                {
3625
                  emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isinf),
3626
                                                             GEN_INT (4 * 8)));
3627
                  emit_insn (gen_andv4si3 (isinf, isinf, temp_v4si));
3628
                  emit_insn (gen_shufb (isinf, isinf, isinf, hi_promote));
3629
 
3630
                  /* +inf  */
3631
                  if (INTVAL (operands[2]) & 0x20)
3632
                    {
3633
                      emit_insn (gen_andc_v4si (temp2, isinf, sign));
3634
                      emit_insn (gen_iorv4si3 (result, result, temp2));
3635
                    }
3636
                  /* -inf  */
3637
                  if (INTVAL (operands[2]) & 0x10)
3638
                    {
3639
                      emit_insn (gen_andv4si3 (temp2, isinf, sign));
3640
                      emit_insn (gen_iorv4si3 (result, result, temp2));
3641
                    }
3642
                }
3643
            }
3644
 
3645
          /* 0 or denorm  */
3646
          if (INTVAL (operands[2]) & 0xF)
3647
            {
3648
              rtx iszero = gen_reg_rtx (V4SImode);
3649
              emit_insn (gen_ceq_v4si (iszero, abs, CONST0_RTX (V4SImode)));
3650
              emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3651
                                                          GEN_INT (4 * 8)));
3652
              emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3653
 
3654
              /* denorm  */
3655
              if (INTVAL (operands[2]) & 0x3)
3656
                {
3657
                  rtx isdenorm = gen_reg_rtx (V4SImode);
3658
                  rtx denorm_mask = gen_reg_rtx (V4SImode);
3659
                  emit_move_insn (denorm_mask, spu_const (V4SImode, 0xFFFFF));
3660
                  emit_insn (gen_clgt_v4si (isdenorm, abs, denorm_mask));
3661
                  emit_insn (gen_nor_v4si (isdenorm, isdenorm, iszero));
3662
                  emit_insn (gen_shufb (isdenorm, isdenorm,
3663
                                        isdenorm, hi_promote));
3664
                  /* +denorm  */
3665
                  if (INTVAL (operands[2]) & 0x2)
3666
                    {
3667
                      emit_insn (gen_andc_v4si (temp2, isdenorm, sign));
3668
                      emit_insn (gen_iorv4si3 (result, result, temp2));
3669
                    }
3670
                  /* -denorm  */
3671
                  if (INTVAL (operands[2]) & 0x1)
3672
                    {
3673
                      emit_insn (gen_andv4si3 (temp2, isdenorm, sign));
3674
                      emit_insn (gen_iorv4si3 (result, result, temp2));
3675
                    }
3676
                }
3677
 
3678
              /* 0  */
3679
              if (INTVAL (operands[2]) & 0xC)
3680
                {
3681
                  emit_insn (gen_shufb (iszero, iszero, iszero, hi_promote));
3682
                  /* +0  */
3683
                  if (INTVAL (operands[2]) & 0x8)
3684
                    {
3685
                      emit_insn (gen_andc_v4si (temp2, iszero, sign));
3686
                      emit_insn (gen_iorv4si3 (result, result, temp2));
3687
                    }
3688
                  /* -0  */
3689
                  if (INTVAL (operands[2]) & 0x4)
3690
                    {
3691
                      emit_insn (gen_andv4si3 (temp2, iszero, sign));
3692
                      emit_insn (gen_iorv4si3 (result, result, temp2));
3693
                    }
3694
                }
3695
             }
3696
          }
3697
      emit_move_insn (operands[0], spu_gen_subreg (V2DImode, result));
3698
      DONE;
3699
    }
3700
})
3701
 
3702
 
3703
;; branches
3704
 
3705
(define_insn ""
3706
  [(set (pc)
3707
        (if_then_else (match_operator 1 "branch_comparison_operator"
3708
                                      [(match_operand 2
3709
                                                      "spu_reg_operand" "r")
3710
                                       (const_int 0)])
3711
                      (label_ref (match_operand 0 "" ""))
3712
                      (pc)))]
3713
  ""
3714
  "br%b2%b1z\t%2,%0"
3715
  [(set_attr "type" "br")])
3716
 
3717
(define_insn ""
3718
  [(set (pc)
3719
        (if_then_else (match_operator 0 "branch_comparison_operator"
3720
                                      [(match_operand 1
3721
                                                      "spu_reg_operand" "r")
3722
                                       (const_int 0)])
3723
                      (return)
3724
                      (pc)))]
3725
  "direct_return ()"
3726
  "bi%b1%b0z\t%1,$lr"
3727
  [(set_attr "type" "br")])
3728
 
3729
(define_insn ""
3730
  [(set (pc)
3731
        (if_then_else (match_operator 1 "branch_comparison_operator"
3732
                                      [(match_operand 2
3733
                                                      "spu_reg_operand" "r")
3734
                                       (const_int 0)])
3735
                      (pc)
3736
                      (label_ref (match_operand 0 "" ""))))]
3737
  ""
3738
  "br%b2%b1z\t%2,%0"
3739
  [(set_attr "type" "br")])
3740
 
3741
(define_insn ""
3742
  [(set (pc)
3743
        (if_then_else (match_operator 0 "branch_comparison_operator"
3744
                                      [(match_operand 1
3745
                                                      "spu_reg_operand" "r")
3746
                                       (const_int 0)])
3747
                      (pc)
3748
                      (return)))]
3749
  "direct_return ()"
3750
  "bi%b1%b0z\t%1,$lr"
3751
  [(set_attr "type" "br")])
3752
 
3753
 
3754
;; vector conditional compare patterns
3755
(define_expand "vcond"
3756
  [(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
3757
        (if_then_else:VCMP
3758
          (match_operator 3 "comparison_operator"
3759
            [(match_operand:VCMP 4 "spu_reg_operand" "r")
3760
             (match_operand:VCMP 5 "spu_reg_operand" "r")])
3761
          (match_operand:VCMP 1 "spu_reg_operand" "r")
3762
          (match_operand:VCMP 2 "spu_reg_operand" "r")))]
3763
  ""
3764
  {
3765
    if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3766
                                   operands[3], operands[4], operands[5]))
3767
    DONE;
3768
    else
3769
    FAIL;
3770
  })
3771
 
3772
(define_expand "vcondu"
3773
  [(set (match_operand:VCMPU 0 "spu_reg_operand" "=r")
3774
        (if_then_else:VCMPU
3775
          (match_operator 3 "comparison_operator"
3776
            [(match_operand:VCMPU 4 "spu_reg_operand" "r")
3777
             (match_operand:VCMPU 5 "spu_reg_operand" "r")])
3778
          (match_operand:VCMPU 1 "spu_reg_operand" "r")
3779
          (match_operand:VCMPU 2 "spu_reg_operand" "r")))]
3780
  ""
3781
  {
3782
    if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3783
                                   operands[3], operands[4], operands[5]))
3784
    DONE;
3785
    else
3786
    FAIL;
3787
  })
3788
 
3789
 
3790
;; branch on condition
3791
 
3792
(define_expand "cbranch4"
3793
  [(use (match_operator 0 "ordered_comparison_operator"
3794
         [(match_operand:VQHSI 1 "spu_reg_operand" "")
3795
          (match_operand:VQHSI 2 "spu_nonmem_operand" "")]))
3796
   (use (match_operand 3 ""))]
3797
  ""
3798
  { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3799
 
3800
(define_expand "cbranch4"
3801
  [(use (match_operator 0 "ordered_comparison_operator"
3802
         [(match_operand:DTI 1 "spu_reg_operand" "")
3803
          (match_operand:DTI 2 "spu_reg_operand" "")]))
3804
   (use (match_operand 3 ""))]
3805
  ""
3806
  { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3807
 
3808
(define_expand "cbranch4"
3809
  [(use (match_operator 0 "ordered_comparison_operator"
3810
         [(match_operand:VSF 1 "spu_reg_operand" "")
3811
          (match_operand:VSF 2 "spu_reg_operand" "")]))
3812
   (use (match_operand 3 ""))]
3813
  ""
3814
  { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3815
 
3816
(define_expand "cbranchdf4"
3817
  [(use (match_operator 0 "ordered_comparison_operator"
3818
         [(match_operand:DF 1 "spu_reg_operand" "")
3819
          (match_operand:DF 2 "spu_reg_operand" "")]))
3820
   (use (match_operand 3 ""))]
3821
  ""
3822
  { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3823
 
3824
 
3825
;; set on condition
3826
 
3827
(define_expand "cstore4"
3828
  [(use (match_operator 1 "ordered_comparison_operator"
3829
         [(match_operand:VQHSI 2 "spu_reg_operand" "")
3830
          (match_operand:VQHSI 3 "spu_nonmem_operand" "")]))
3831
   (clobber (match_operand:SI 0 "spu_reg_operand"))]
3832
  ""
3833
  { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3834
 
3835
(define_expand "cstore4"
3836
  [(use (match_operator 1 "ordered_comparison_operator"
3837
         [(match_operand:DTI 2 "spu_reg_operand" "")
3838
          (match_operand:DTI 3 "spu_reg_operand" "")]))
3839
   (clobber (match_operand:SI 0 "spu_reg_operand"))]
3840
  ""
3841
  { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3842
 
3843
(define_expand "cstore4"
3844
  [(use (match_operator 1 "ordered_comparison_operator"
3845
         [(match_operand:VSF 2 "spu_reg_operand" "")
3846
          (match_operand:VSF 3 "spu_reg_operand" "")]))
3847
   (clobber (match_operand:SI 0 "spu_reg_operand"))]
3848
  ""
3849
  { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3850
 
3851
(define_expand "cstoredf4"
3852
  [(use (match_operator 1 "ordered_comparison_operator"
3853
         [(match_operand:DF 2 "spu_reg_operand" "")
3854
          (match_operand:DF 3 "spu_reg_operand" "")]))
3855
   (clobber (match_operand:SI 0 "spu_reg_operand"))]
3856
  ""
3857
  { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3858
 
3859
 
3860
;; conditional move
3861
 
3862
;; Define this first one so HAVE_conditional_move is defined.
3863
(define_insn "movcc_dummy"
3864
  [(set (match_operand 0 "" "")
3865
       (if_then_else (match_operand 1 "" "")
3866
                     (match_operand 2 "" "")
3867
                     (match_operand 3 "" "")))]
3868
  "!operands[0]"
3869
  "")
3870
 
3871
(define_expand "movcc"
3872
  [(set (match_operand:ALL 0 "spu_reg_operand" "")
3873
        (if_then_else:ALL (match_operand 1 "ordered_comparison_operator" "")
3874
                      (match_operand:ALL 2 "spu_reg_operand" "")
3875
                      (match_operand:ALL 3 "spu_reg_operand" "")))]
3876
  ""
3877
  {
3878
    spu_emit_branch_or_set(2, operands[1], operands);
3879
    DONE;
3880
  })
3881
 
3882
;; This pattern is used when the result of a compare is not large
3883
;; enough to use in a selb when expanding conditional moves.
3884
(define_expand "extend_compare"
3885
  [(set (match_operand 0 "spu_reg_operand" "=r")
3886
        (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
3887
  ""
3888
  {
3889
    emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3890
                            gen_rtx_UNSPEC (GET_MODE (operands[0]),
3891
                                            gen_rtvec (1, operands[1]),
3892
                                            UNSPEC_EXTEND_CMP)));
3893
    DONE;
3894
  })
3895
 
3896
(define_insn "extend_compare"
3897
  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
3898
        (unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
3899
  "operands"
3900
  "fsm\t%0,%1"
3901
  [(set_attr "type" "shuf")])
3902
 
3903
 
3904
;; case
3905
 
3906
;; operand 0 is index
3907
;; operand 1 is the minimum bound
3908
;; operand 2 is the maximum bound - minimum bound + 1
3909
;; operand 3 is CODE_LABEL for the table;
3910
;; operand 4 is the CODE_LABEL to go to if index out of range.
3911
(define_expand "casesi"
3912
  [(match_operand:SI 0 "spu_reg_operand" "")
3913
   (match_operand:SI 1 "immediate_operand" "")
3914
   (match_operand:SI 2 "immediate_operand" "")
3915
   (match_operand 3 "" "")
3916
   (match_operand 4 "" "")]
3917
  ""
3918
  {
3919
    rtx table = gen_reg_rtx (SImode);
3920
    rtx index = gen_reg_rtx (SImode);
3921
    rtx sindex = gen_reg_rtx (SImode);
3922
    rtx addr = gen_reg_rtx (Pmode);
3923
 
3924
    emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
3925
 
3926
    emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
3927
    emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
3928
    emit_move_insn (addr, gen_rtx_MEM (SImode,
3929
                                       gen_rtx_PLUS (SImode, table, sindex)));
3930
    if (flag_pic)
3931
      emit_insn (gen_addsi3 (addr, addr, table));
3932
 
3933
    emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
3934
    emit_jump_insn (gen_tablejump (addr, operands[3]));
3935
    DONE;
3936
  })
3937
 
3938
(define_insn "tablejump"
3939
  [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
3940
   (use (label_ref (match_operand 1 "" "")))]
3941
  ""
3942
  "bi\t%0"
3943
  [(set_attr "type" "br")])
3944
 
3945
 
3946
;; call
3947
 
3948
;; Note that operand 1 is total size of args, in bytes,
3949
;; and what the call insn wants is the number of words.
3950
(define_expand "sibcall"
3951
  [(parallel
3952
    [(call (match_operand:QI 0 "call_operand" "")
3953
           (match_operand:QI 1 "" ""))
3954
     (use (reg:SI 0))])]
3955
  ""
3956
  {
3957
    if (! call_operand (operands[0], QImode))
3958
      XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
3959
  })
3960
 
3961
(define_insn "_sibcall"
3962
  [(parallel
3963
    [(call (match_operand:QI 0 "call_operand" "R,S")
3964
           (match_operand:QI 1 "" "i,i"))
3965
     (use (reg:SI 0))])]
3966
  "SIBLING_CALL_P(insn)"
3967
  "@
3968
   bi\t%i0
3969
   br\t%0"
3970
   [(set_attr "type" "br,br")])
3971
 
3972
(define_expand "sibcall_value"
3973
  [(parallel
3974
    [(set (match_operand 0 "" "")
3975
          (call (match_operand:QI 1 "call_operand" "")
3976
                (match_operand:QI 2 "" "")))
3977
     (use (reg:SI 0))])]
3978
  ""
3979
  {
3980
    if (! call_operand (operands[1], QImode))
3981
      XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
3982
  })
3983
 
3984
(define_insn "_sibcall_value"
3985
  [(parallel
3986
    [(set (match_operand 0 "" "")
3987
          (call (match_operand:QI 1 "call_operand" "R,S")
3988
                (match_operand:QI 2 "" "i,i")))
3989
     (use (reg:SI 0))])]
3990
  "SIBLING_CALL_P(insn)"
3991
  "@
3992
   bi\t%i1
3993
   br\t%1"
3994
   [(set_attr "type" "br,br")])
3995
 
3996
;; Note that operand 1 is total size of args, in bytes,
3997
;; and what the call insn wants is the number of words.
3998
(define_expand "call"
3999
  [(parallel
4000
    [(call (match_operand:QI 0 "call_operand" "")
4001
           (match_operand:QI 1 "" ""))
4002
     (clobber (reg:SI 0))
4003
     (clobber (reg:SI 130))])]
4004
  ""
4005
  {
4006
    if (! call_operand (operands[0], QImode))
4007
      XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
4008
  })
4009
 
4010
(define_insn "_call"
4011
  [(parallel
4012
    [(call (match_operand:QI 0 "call_operand" "R,S,T")
4013
           (match_operand:QI 1 "" "i,i,i"))
4014
     (clobber (reg:SI 0))
4015
     (clobber (reg:SI 130))])]
4016
  ""
4017
  "@
4018
   bisl\t$lr,%i0
4019
   brsl\t$lr,%0
4020
   brasl\t$lr,%0"
4021
   [(set_attr "type" "br")])
4022
 
4023
(define_expand "call_value"
4024
  [(parallel
4025
    [(set (match_operand 0 "" "")
4026
          (call (match_operand:QI 1 "call_operand" "")
4027
                (match_operand:QI 2 "" "")))
4028
     (clobber (reg:SI 0))
4029
     (clobber (reg:SI 130))])]
4030
  ""
4031
  {
4032
    if (! call_operand (operands[1], QImode))
4033
      XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
4034
  })
4035
 
4036
(define_insn "_call_value"
4037
  [(parallel
4038
    [(set (match_operand 0 "" "")
4039
          (call (match_operand:QI 1 "call_operand" "R,S,T")
4040
                (match_operand:QI 2 "" "i,i,i")))
4041
     (clobber (reg:SI 0))
4042
     (clobber (reg:SI 130))])]
4043
  ""
4044
  "@
4045
   bisl\t$lr,%i1
4046
   brsl\t$lr,%1
4047
   brasl\t$lr,%1"
4048
   [(set_attr "type" "br")])
4049
 
4050
(define_expand "untyped_call"
4051
  [(parallel [(call (match_operand 0 "" "")
4052
                    (const_int 0))
4053
              (match_operand 1 "" "")
4054
              (match_operand 2 "" "")])]
4055
  ""
4056
  {
4057
    int i;
4058
    rtx reg = gen_rtx_REG (TImode, 3);
4059
 
4060
    /* We need to use call_value so the return value registers don't get
4061
     * clobbered. */
4062
    emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
4063
 
4064
    for (i = 0; i < XVECLEN (operands[2], 0); i++)
4065
      {
4066
        rtx set = XVECEXP (operands[2], 0, i);
4067
        emit_move_insn (SET_DEST (set), SET_SRC (set));
4068
      }
4069
 
4070
    /* The optimizer does not know that the call sets the function value
4071
       registers we stored in the result block.  We avoid problems by
4072
       claiming that all hard registers are used and clobbered at this
4073
       point.  */
4074
    emit_insn (gen_blockage ());
4075
 
4076
    DONE;
4077
  })
4078
 
4079
 
4080
;; Patterns used for splitting and combining.
4081
 
4082
 
4083
;; Function prologue and epilogue.
4084
 
4085
(define_expand "prologue"
4086
  [(const_int 1)]
4087
  ""
4088
  { spu_expand_prologue (); DONE; })
4089
 
4090
;; "blockage" is only emited in epilogue.  This is what it took to
4091
;; make "basic block reordering" work with the insns sequence
4092
;; generated by the spu_expand_epilogue (taken from mips.md)
4093
 
4094
(define_insn "blockage"
4095
  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
4096
  ""
4097
  ""
4098
  [(set_attr "type" "convert")
4099
   (set_attr "length" "0")])
4100
 
4101
(define_expand "epilogue"
4102
  [(const_int 2)]
4103
  ""
4104
  { spu_expand_epilogue (false); DONE; })
4105
 
4106
(define_expand "sibcall_epilogue"
4107
  [(const_int 2)]
4108
  ""
4109
  { spu_expand_epilogue (true); DONE; })
4110
 
4111
 
4112
;; stack manipulations
4113
 
4114
;; An insn to allocate new stack space for dynamic use (e.g., alloca).
4115
;; We move the back-chain and decrement the stack pointer.
4116
(define_expand "allocate_stack"
4117
  [(set (match_operand 0 "spu_reg_operand" "")
4118
        (minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
4119
   (set (reg 1)
4120
        (minus (reg 1) (match_dup 1)))]
4121
  ""
4122
  "spu_allocate_stack (operands[0], operands[1]); DONE;")
4123
 
4124
;; These patterns say how to save and restore the stack pointer.  We need not
4125
;; save the stack pointer at function level since we are careful to preserve
4126
;; the backchain.
4127
;;
4128
 
4129
;; At block level the stack pointer is saved and restored, so that the
4130
;; stack space allocated within a block is deallocated when leaving
4131
;; block scope.  By default, according to the SPU ABI, the stack
4132
;; pointer and available stack size are saved in a register. Upon
4133
;; restoration, the stack pointer is simply copied back, and the
4134
;; current available stack size is calculated against the restored
4135
;; stack pointer.
4136
;;
4137
;; For nonlocal gotos, we must save the stack pointer and its
4138
;; backchain and restore both.  Note that in the nonlocal case, the
4139
;; save area is a memory location.
4140
 
4141
(define_expand "save_stack_function"
4142
  [(match_operand 0 "general_operand" "")
4143
   (match_operand 1 "general_operand" "")]
4144
  ""
4145
  "DONE;")
4146
 
4147
(define_expand "restore_stack_function"
4148
  [(match_operand 0 "general_operand" "")
4149
   (match_operand 1 "general_operand" "")]
4150
  ""
4151
  "DONE;")
4152
 
4153
(define_expand "restore_stack_block"
4154
  [(match_operand 0 "spu_reg_operand" "")
4155
   (match_operand 1 "memory_operand" "")]
4156
  ""
4157
  "
4158
  {
4159
    spu_restore_stack_block (operands[0], operands[1]);
4160
    DONE;
4161
  }")
4162
 
4163
(define_expand "save_stack_nonlocal"
4164
  [(match_operand 0 "memory_operand" "")
4165
   (match_operand 1 "spu_reg_operand" "")]
4166
  ""
4167
  "
4168
  {
4169
    rtx temp = gen_reg_rtx (Pmode);
4170
 
4171
    /* Copy the backchain to the first word, sp to the second.  We need to
4172
       save the back chain because __builtin_apply appears to clobber it. */
4173
    emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
4174
    emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
4175
    emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
4176
    DONE;
4177
  }")
4178
 
4179
(define_expand "restore_stack_nonlocal"
4180
  [(match_operand 0 "spu_reg_operand" "")
4181
   (match_operand 1 "memory_operand" "")]
4182
  ""
4183
  "
4184
  {
4185
    spu_restore_stack_nonlocal(operands[0], operands[1]);
4186
    DONE;
4187
  }")
4188
 
4189
 
4190
;; vector patterns
4191
 
4192
;; Vector initialization
4193
(define_expand "vec_init"
4194
  [(match_operand:V 0 "register_operand" "")
4195
   (match_operand 1 "" "")]
4196
  ""
4197
  {
4198
    spu_expand_vector_init (operands[0], operands[1]);
4199
    DONE;
4200
  })
4201
 
4202
(define_expand "vec_set"
4203
  [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
4204
   (set (match_dup:TI 3)
4205
        (unspec:TI [(match_dup:SI 4)
4206
                    (match_dup:SI 5)
4207
                    (match_dup:SI 6)] UNSPEC_CPAT))
4208
   (set (match_operand:V 0 "spu_reg_operand" "")
4209
        (unspec:V [(match_operand: 1 "spu_reg_operand" "")
4210
                   (match_dup:V 0)
4211
                   (match_dup:TI 3)] UNSPEC_SHUFB))]
4212
  ""
4213
  {
4214
    HOST_WIDE_INT size = GET_MODE_SIZE (mode);
4215
    rtx offset = GEN_INT (INTVAL (operands[2]) * size);
4216
    operands[3] = gen_reg_rtx (TImode);
4217
    operands[4] = stack_pointer_rtx;
4218
    operands[5] = offset;
4219
    operands[6] = GEN_INT (size);
4220
  })
4221
 
4222
(define_expand "vec_extract"
4223
  [(set (match_operand: 0 "spu_reg_operand" "=r")
4224
        (vec_select: (match_operand:V 1 "spu_reg_operand" "r")
4225
                            (parallel [(match_operand 2 "const_int_operand" "i")])))]
4226
  ""
4227
  {
4228
    if ((INTVAL (operands[2]) *  + ) % 16 == 0)
4229
      {
4230
        emit_insn (gen_spu_convert (operands[0], operands[1]));
4231
        DONE;
4232
      }
4233
  })
4234
 
4235
(define_insn "_vec_extract"
4236
  [(set (match_operand: 0 "spu_reg_operand" "=r")
4237
        (vec_select: (match_operand:V 1 "spu_reg_operand" "r")
4238
                            (parallel [(match_operand 2 "const_int_operand" "i")])))]
4239
  ""
4240
  "rotqbyi\t%0,%1,(%2*+)%%16"
4241
  [(set_attr "type" "shuf")])
4242
 
4243
(define_insn "_vec_extractv8hi_ze"
4244
  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
4245
        (zero_extend:SI (vec_select:HI (match_operand:V8HI 1 "spu_reg_operand" "r")
4246
                                       (parallel [(const_int 0)]))))]
4247
  ""
4248
  "rotqmbyi\t%0,%1,-2"
4249
  [(set_attr "type" "shuf")])
4250
 
4251
 
4252
;; misc
4253
 
4254
(define_expand "shufb"
4255
  [(set (match_operand 0 "spu_reg_operand" "")
4256
        (unspec [(match_operand 1 "spu_reg_operand" "")
4257
                 (match_operand 2 "spu_reg_operand" "")
4258
                 (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
4259
  ""
4260
  {
4261
    rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
4262
    PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
4263
    emit_insn (s);
4264
    DONE;
4265
  })
4266
 
4267
(define_insn "_shufb"
4268
  [(set (match_operand 0 "spu_reg_operand" "=r")
4269
        (unspec [(match_operand 1 "spu_reg_operand" "r")
4270
                 (match_operand 2 "spu_reg_operand" "r")
4271
                 (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
4272
  "operands"
4273
  "shufb\t%0,%1,%2,%3"
4274
  [(set_attr "type" "shuf")])
4275
 
4276
(define_insn "nop"
4277
  [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
4278
  ""
4279
  "nop"
4280
  [(set_attr "type" "nop")])
4281
 
4282
(define_insn "nopn"
4283
  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPEC_NOP)]
4284
  ""
4285
  "nop\t%0"
4286
  [(set_attr "type" "nop")])
4287
 
4288
(define_insn "lnop"
4289
  [(unspec_volatile [(const_int 0)] UNSPEC_LNOP)]
4290
  ""
4291
  "lnop"
4292
  [(set_attr "type" "lnop")])
4293
 
4294
;; The operand is so we know why we generated this hbrp.
4295
;; We clobber mem to make sure it isn't moved over any
4296
;; loads, stores or calls while scheduling.
4297
(define_insn "iprefetch"
4298
  [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH)
4299
   (clobber (mem:BLK (scratch)))]
4300
  ""
4301
  "hbrp\t# %0"
4302
  [(set_attr "type" "iprefetch")])
4303
 
4304
;; A non-volatile version so it gets scheduled
4305
(define_insn "nopn_nv"
4306
  [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_NOP)]
4307
  ""
4308
  "nop\t%0"
4309
  [(set_attr "type" "nop")])
4310
 
4311
(define_insn "hbr"
4312
  [(set (reg:SI 130)
4313
        (unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i,i")
4314
                    (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
4315
   (unspec [(const_int 0)] UNSPEC_HBR)]
4316
  ""
4317
  "@
4318
   hbr\t%0,%1
4319
   hbrr\t%0,%1
4320
   hbra\t%0,%1"
4321
  [(set_attr "type" "hbr")])
4322
 
4323
(define_insn "sync"
4324
  [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)
4325
   (clobber (mem:BLK (scratch)))]
4326
  ""
4327
  "sync"
4328
  [(set_attr "type" "br")])
4329
 
4330
(define_insn "syncc"
4331
  [(unspec_volatile [(const_int 1)] UNSPEC_SYNC)
4332
   (clobber (mem:BLK (scratch)))]
4333
  ""
4334
  "syncc"
4335
  [(set_attr "type" "br")])
4336
 
4337
(define_insn "dsync"
4338
  [(unspec_volatile [(const_int 2)] UNSPEC_SYNC)
4339
   (clobber (mem:BLK (scratch)))]
4340
  ""
4341
  "dsync"
4342
  [(set_attr "type" "br")])
4343
 
4344
 
4345
 
4346
 ;; Define the subtract-one-and-jump insns so loop.c
4347
 ;; knows what to generate.
4348
 (define_expand "doloop_end"
4349
   [(use (match_operand 0 "" ""))      ; loop pseudo
4350
    (use (match_operand 1 "" ""))      ; iterations; zero if unknown
4351
    (use (match_operand 2 "" ""))      ; max iterations
4352
    (use (match_operand 3 "" ""))      ; loop level
4353
    (use (match_operand 4 "" ""))]     ; label
4354
   ""
4355
   "
4356
 {
4357
   /* Currently SMS relies on the do-loop pattern to recognize loops
4358
      where (1) the control part comprises of all insns defining and/or
4359
      using a certain 'count' register and (2) the loop count can be
4360
      adjusted by modifying this register prior to the loop.
4361
.     ??? The possible introduction of a new block to initialize the
4362
      new IV can potentially effects branch optimizations.  */
4363
   if (optimize > 0 && flag_modulo_sched)
4364
   {
4365
     rtx s0;
4366
     rtx bcomp;
4367
     rtx loc_ref;
4368
 
4369
     /* Only use this on innermost loops.  */
4370
     if (INTVAL (operands[3]) > 1)
4371
       FAIL;
4372
     if (GET_MODE (operands[0]) != SImode)
4373
       FAIL;
4374
 
4375
     s0 = operands [0];
4376
     emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
4377
     bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
4378
     loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
4379
     emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4380
                                  gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4381
                                                        loc_ref, pc_rtx)));
4382
 
4383
     DONE;
4384
   }else
4385
      FAIL;
4386
 }")
4387
 
4388
;; convert between any two modes, avoiding any GCC assumptions
4389
(define_expand "spu_convert"
4390
  [(set (match_operand 0 "spu_reg_operand" "")
4391
        (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
4392
  ""
4393
  {
4394
    rtx c = gen__spu_convert (operands[0], operands[1]);
4395
    PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
4396
    emit_insn (c);
4397
    DONE;
4398
  })
4399
 
4400
(define_insn_and_split "_spu_convert"
4401
  [(set (match_operand 0 "spu_reg_operand" "=r")
4402
        (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
4403
  ""
4404
  "#"
4405
  "reload_completed"
4406
  [(const_int 0)]
4407
  {
4408
    spu_split_convert (operands);
4409
    DONE;
4410
  }
4411
  [(set_attr "type" "convert")
4412
   (set_attr "length" "0")])
4413
 
4414
 
4415
;;
4416
(include "spu-builtins.md")
4417
 
4418
 
4419
(define_expand "smaxv4sf3"
4420
  [(set (match_operand:V4SF 0 "register_operand" "=r")
4421
        (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
4422
                 (match_operand:V4SF 2 "register_operand" "r")))]
4423
  ""
4424
  "
4425
{
4426
  rtx mask = gen_reg_rtx (V4SImode);
4427
 
4428
  emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4429
  emit_insn (gen_selb (operands[0], operands[2], operands[1], mask));
4430
  DONE;
4431
}")
4432
 
4433
(define_expand "sminv4sf3"
4434
  [(set (match_operand:V4SF 0 "register_operand" "=r")
4435
        (smin:V4SF (match_operand:V4SF 1 "register_operand" "r")
4436
                 (match_operand:V4SF 2 "register_operand" "r")))]
4437
  ""
4438
  "
4439
{
4440
  rtx mask = gen_reg_rtx (V4SImode);
4441
 
4442
  emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4443
  emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));
4444
  DONE;
4445
}")
4446
 
4447
(define_expand "smaxv2df3"
4448
  [(set (match_operand:V2DF 0 "register_operand" "=r")
4449
        (smax:V2DF (match_operand:V2DF 1 "register_operand" "r")
4450
                 (match_operand:V2DF 2 "register_operand" "r")))]
4451
  ""
4452
  "
4453
{
4454
  rtx mask = gen_reg_rtx (V2DImode);
4455
  emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4456
  emit_insn (gen_selb (operands[0], operands[2], operands[1],
4457
                       spu_gen_subreg (V4SImode, mask)));
4458
  DONE;
4459
}")
4460
 
4461
(define_expand "sminv2df3"
4462
  [(set (match_operand:V2DF 0 "register_operand" "=r")
4463
        (smin:V2DF (match_operand:V2DF 1 "register_operand" "r")
4464
                 (match_operand:V2DF 2 "register_operand" "r")))]
4465
  ""
4466
  "
4467
{
4468
  rtx mask = gen_reg_rtx (V2DImode);
4469
  emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4470
  emit_insn (gen_selb (operands[0], operands[1], operands[2],
4471
                       spu_gen_subreg (V4SImode, mask)));
4472
  DONE;
4473
}")
4474
 
4475
(define_expand "vec_widen_umult_hi_v8hi"
4476
  [(set (match_operand:V4SI 0 "register_operand"   "=r")
4477
        (mult:V4SI
4478
          (zero_extend:V4SI
4479
            (vec_select:V4HI
4480
              (match_operand:V8HI 1 "register_operand" "r")
4481
              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4482
          (zero_extend:V4SI
4483
            (vec_select:V4HI
4484
              (match_operand:V8HI 2 "register_operand" "r")
4485
              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4486
  ""
4487
  "
4488
{
4489
  rtx ve = gen_reg_rtx (V4SImode);
4490
  rtx vo = gen_reg_rtx (V4SImode);
4491
  rtx mask = gen_reg_rtx (TImode);
4492
  unsigned char arr[16] = {
4493
    0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4494
    0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4495
 
4496
  emit_move_insn (mask, array_to_constant (TImode, arr));
4497
  emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4498
  emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4499
  emit_insn (gen_shufb (operands[0], ve, vo, mask));
4500
  DONE;
4501
}")
4502
 
4503
(define_expand "vec_widen_umult_lo_v8hi"
4504
  [(set (match_operand:V4SI 0 "register_operand"   "=r")
4505
        (mult:V4SI
4506
          (zero_extend:V4SI
4507
            (vec_select:V4HI
4508
              (match_operand:V8HI 1 "register_operand" "r")
4509
              (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4510
          (zero_extend:V4SI
4511
            (vec_select:V4HI
4512
              (match_operand:V8HI 2 "register_operand" "r")
4513
              (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4514
  ""
4515
  "
4516
{
4517
  rtx ve = gen_reg_rtx (V4SImode);
4518
  rtx vo = gen_reg_rtx (V4SImode);
4519
  rtx mask = gen_reg_rtx (TImode);
4520
  unsigned char arr[16] = {
4521
    0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4522
    0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4523
 
4524
  emit_move_insn (mask, array_to_constant (TImode, arr));
4525
  emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4526
  emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4527
  emit_insn (gen_shufb (operands[0], ve, vo, mask));
4528
  DONE;
4529
}")
4530
 
4531
(define_expand "vec_widen_smult_hi_v8hi"
4532
  [(set (match_operand:V4SI 0 "register_operand"   "=r")
4533
        (mult:V4SI
4534
          (sign_extend:V4SI
4535
            (vec_select:V4HI
4536
              (match_operand:V8HI 1 "register_operand" "r")
4537
              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4538
          (sign_extend:V4SI
4539
            (vec_select:V4HI
4540
              (match_operand:V8HI 2 "register_operand" "r")
4541
              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4542
  ""
4543
  "
4544
{
4545
  rtx ve = gen_reg_rtx (V4SImode);
4546
  rtx vo = gen_reg_rtx (V4SImode);
4547
  rtx mask = gen_reg_rtx (TImode);
4548
  unsigned char arr[16] = {
4549
    0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4550
    0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4551
 
4552
  emit_move_insn (mask, array_to_constant (TImode, arr));
4553
  emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4554
  emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4555
  emit_insn (gen_shufb (operands[0], ve, vo, mask));
4556
  DONE;
4557
}")
4558
 
4559
(define_expand "vec_widen_smult_lo_v8hi"
4560
  [(set (match_operand:V4SI 0 "register_operand"   "=r")
4561
        (mult:V4SI
4562
          (sign_extend:V4SI
4563
            (vec_select:V4HI
4564
              (match_operand:V8HI 1 "register_operand" "r")
4565
              (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4566
          (sign_extend:V4SI
4567
            (vec_select:V4HI
4568
              (match_operand:V8HI 2 "register_operand" "r")
4569
              (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4570
  ""
4571
  "
4572
{
4573
  rtx ve = gen_reg_rtx (V4SImode);
4574
  rtx vo = gen_reg_rtx (V4SImode);
4575
  rtx mask = gen_reg_rtx (TImode);
4576
  unsigned char arr[16] = {
4577
    0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4578
    0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4579
 
4580
  emit_move_insn (mask, array_to_constant (TImode, arr));
4581
  emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4582
  emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4583
  emit_insn (gen_shufb (operands[0], ve, vo, mask));
4584
  DONE;
4585
}")
4586
 
4587
(define_expand "vec_realign_load_"
4588
  [(set (match_operand:ALL 0 "register_operand" "=r")
4589
        (unspec:ALL [(match_operand:ALL 1 "register_operand" "r")
4590
                     (match_operand:ALL 2 "register_operand" "r")
4591
                     (match_operand:TI 3 "register_operand" "r")] UNSPEC_SPU_REALIGN_LOAD))]
4592
  ""
4593
  "
4594
{
4595
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], operands[3]));
4596
  DONE;
4597
}")
4598
 
4599
(define_expand "spu_lvsr"
4600
  [(set (match_operand:V16QI 0 "register_operand" "")
4601
        (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_SPU_MASK_FOR_LOAD))]
4602
  ""
4603
  "
4604
{
4605
  rtx addr;
4606
  rtx offset = gen_reg_rtx (V8HImode);
4607
  rtx addr_bits = gen_reg_rtx (SImode);
4608
  rtx addr_bits_vec = gen_reg_rtx (V8HImode);
4609
  rtx splatqi = gen_reg_rtx (TImode);
4610
  rtx result = gen_reg_rtx (V8HImode);
4611
  unsigned char arr[16] = {
4612
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
4613
    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
4614
  unsigned char arr2[16] = {
4615
    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
4616
    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
4617
 
4618
  emit_move_insn (offset, array_to_constant (V8HImode, arr));
4619
  emit_move_insn (splatqi, array_to_constant (TImode, arr2));
4620
 
4621
  gcc_assert (GET_CODE (operands[1]) == MEM);
4622
  addr = force_reg (Pmode, XEXP (operands[1], 0));
4623
  emit_insn (gen_andsi3 (addr_bits, addr, GEN_INT (0xF)));
4624
  emit_insn (gen_shufb (addr_bits_vec, addr_bits, addr_bits, splatqi));
4625
 
4626
  /* offset - (addr & 0xF)
4627
     It is safe to use a single sfh, because each byte of offset is > 15 and
4628
     each byte of addr is <= 15. */
4629
  emit_insn (gen_subv8hi3 (result, offset, addr_bits_vec));
4630
 
4631
  result = simplify_gen_subreg (V16QImode, result, V8HImode, 0);
4632
  emit_move_insn (operands[0], result);
4633
 
4634
  DONE;
4635
}")
4636
 
4637
(define_expand "vec_unpacku_hi_v8hi"
4638
  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4639
        (zero_extend:V4SI
4640
          (vec_select:V4HI
4641
            (match_operand:V8HI 1 "spu_reg_operand" "r")
4642
            (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4643
  ""
4644
{
4645
  rtx mask = gen_reg_rtx (TImode);
4646
  unsigned char arr[16] = {
4647
    0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4648
    0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4649
 
4650
  emit_move_insn (mask, array_to_constant (TImode, arr));
4651
  emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4652
 
4653
  DONE;
4654
})
4655
 
4656
(define_expand "vec_unpacku_lo_v8hi"
4657
  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4658
         (zero_extend:V4SI
4659
          (vec_select:V4HI
4660
            (match_operand:V8HI 1 "spu_reg_operand" "r")
4661
            (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4662
""
4663
{
4664
  rtx mask = gen_reg_rtx (TImode);
4665
  unsigned char arr[16] = {
4666
    0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4667
    0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4668
 
4669
  emit_move_insn (mask, array_to_constant (TImode, arr));
4670
  emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4671
 
4672
  DONE;
4673
})
4674
 
4675
(define_expand "vec_unpacks_hi_v8hi"
4676
  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4677
         (sign_extend:V4SI
4678
          (vec_select:V4HI
4679
            (match_operand:V8HI 1 "spu_reg_operand" "r")
4680
            (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4681
  ""
4682
{
4683
  rtx tmp1 = gen_reg_rtx (V8HImode);
4684
  rtx tmp2 = gen_reg_rtx (V4SImode);
4685
  rtx mask = gen_reg_rtx (TImode);
4686
  unsigned char arr[16] = {
4687
    0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4688
    0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4689
 
4690
  emit_move_insn (mask, array_to_constant (TImode, arr));
4691
  emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4692
  emit_insn (gen_spu_xshw (tmp2, tmp1));
4693
  emit_move_insn (operands[0], tmp2);
4694
 
4695
  DONE;
4696
})
4697
 
4698
(define_expand "vec_unpacks_lo_v8hi"
4699
  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4700
         (sign_extend:V4SI
4701
          (vec_select:V4HI
4702
            (match_operand:V8HI 1 "spu_reg_operand" "r")
4703
            (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4704
""
4705
{
4706
  rtx tmp1 = gen_reg_rtx (V8HImode);
4707
  rtx tmp2 = gen_reg_rtx (V4SImode);
4708
  rtx mask = gen_reg_rtx (TImode);
4709
  unsigned char arr[16] = {
4710
    0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4711
    0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4712
 
4713
  emit_move_insn (mask, array_to_constant (TImode, arr));
4714
  emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4715
  emit_insn (gen_spu_xshw (tmp2, tmp1));
4716
  emit_move_insn (operands[0], tmp2);
4717
 
4718
DONE;
4719
})
4720
 
4721
(define_expand "vec_unpacku_hi_v16qi"
4722
  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4723
        (zero_extend:V8HI
4724
          (vec_select:V8QI
4725
            (match_operand:V16QI 1 "spu_reg_operand" "r")
4726
            (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4727
                       (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4728
  ""
4729
{
4730
  rtx mask = gen_reg_rtx (TImode);
4731
  unsigned char arr[16] = {
4732
    0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4733
    0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4734
 
4735
  emit_move_insn (mask, array_to_constant (TImode, arr));
4736
  emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4737
 
4738
  DONE;
4739
})
4740
 
4741
(define_expand "vec_unpacku_lo_v16qi"
4742
  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4743
          (zero_extend:V8HI
4744
          (vec_select:V8QI
4745
            (match_operand:V16QI 1 "spu_reg_operand" "r")
4746
            (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4747
                       (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4748
""
4749
{
4750
  rtx mask = gen_reg_rtx (TImode);
4751
  unsigned char arr[16] = {
4752
    0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4753
    0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4754
 
4755
  emit_move_insn (mask, array_to_constant (TImode, arr));
4756
  emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4757
 
4758
  DONE;
4759
})
4760
 
4761
(define_expand "vec_unpacks_hi_v16qi"
4762
  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4763
         (sign_extend:V8HI
4764
          (vec_select:V8QI
4765
            (match_operand:V16QI 1 "spu_reg_operand" "r")
4766
            (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4767
                       (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4768
""
4769
{
4770
  rtx tmp1 = gen_reg_rtx (V16QImode);
4771
  rtx tmp2 = gen_reg_rtx (V8HImode);
4772
  rtx mask = gen_reg_rtx (TImode);
4773
  unsigned char arr[16] = {
4774
    0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4775
    0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4776
 
4777
  emit_move_insn (mask, array_to_constant (TImode, arr));
4778
  emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4779
  emit_insn (gen_spu_xsbh (tmp2, tmp1));
4780
  emit_move_insn (operands[0], tmp2);
4781
 
4782
  DONE;
4783
})
4784
 
4785
(define_expand "vec_unpacks_lo_v16qi"
4786
  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4787
         (sign_extend:V8HI
4788
          (vec_select:V8QI
4789
            (match_operand:V16QI 1 "spu_reg_operand" "r")
4790
            (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4791
                       (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4792
""
4793
{
4794
  rtx tmp1 = gen_reg_rtx (V16QImode);
4795
  rtx tmp2 = gen_reg_rtx (V8HImode);
4796
  rtx mask = gen_reg_rtx (TImode);
4797
  unsigned char arr[16] = {
4798
    0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4799
    0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4800
 
4801
  emit_move_insn (mask, array_to_constant (TImode, arr));
4802
  emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4803
  emit_insn (gen_spu_xsbh (tmp2, tmp1));
4804
  emit_move_insn (operands[0], tmp2);
4805
 
4806
DONE;
4807
})
4808
 
4809
 
4810
(define_expand "vec_extract_evenv4si"
4811
 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4812
       (vec_concat:V4SI
4813
         (vec_select:V2SI
4814
           (match_operand:V4SI 1 "spu_reg_operand" "r")
4815
           (parallel [(const_int 0)(const_int 2)]))
4816
         (vec_select:V2SI
4817
           (match_operand:V4SI 2 "spu_reg_operand" "r")
4818
           (parallel [(const_int 0)(const_int 2)]))))]
4819
 
4820
  ""
4821
  "
4822
{
4823
  rtx mask = gen_reg_rtx (TImode);
4824
  unsigned char arr[16] = {
4825
        0x00, 0x01, 0x02, 0x03,
4826
        0x08, 0x09, 0x0A, 0x0B,
4827
        0x10, 0x11, 0x12, 0x13,
4828
        0x18, 0x19, 0x1A, 0x1B};
4829
 
4830
  emit_move_insn (mask, array_to_constant (TImode, arr));
4831
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4832
  DONE;
4833
}")
4834
 
4835
 
4836
(define_expand "vec_extract_evenv4sf"
4837
 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
4838
       (vec_concat:V4SF
4839
         (vec_select:V2SF
4840
           (match_operand:V4SF 1 "spu_reg_operand" "r")
4841
           (parallel [(const_int 0)(const_int 2)]))
4842
         (vec_select:V2SF
4843
           (match_operand:V4SF 2 "spu_reg_operand" "r")
4844
           (parallel [(const_int 0)(const_int 2)]))))]
4845
 
4846
  ""
4847
  "
4848
{
4849
  rtx mask = gen_reg_rtx (TImode);
4850
  unsigned char arr[16] = {
4851
        0x00, 0x01, 0x02, 0x03,
4852
        0x08, 0x09, 0x0A, 0x0B,
4853
        0x10, 0x11, 0x12, 0x13,
4854
        0x18, 0x19, 0x1A, 0x1B};
4855
 
4856
  emit_move_insn (mask, array_to_constant (TImode, arr));
4857
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4858
  DONE;
4859
}")
4860
 
4861
(define_expand "vec_extract_evenv8hi"
4862
 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4863
       (vec_concat:V8HI
4864
         (vec_select:V4HI
4865
           (match_operand:V8HI 1 "spu_reg_operand" "r")
4866
           (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))
4867
         (vec_select:V4HI
4868
           (match_operand:V8HI 2 "spu_reg_operand" "r")
4869
           (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))))]
4870
 
4871
  ""
4872
  "
4873
{
4874
  rtx mask = gen_reg_rtx (TImode);
4875
  unsigned char arr[16] = {
4876
        0x00, 0x01, 0x04, 0x05,
4877
        0x08, 0x09, 0x0C, 0x0D,
4878
        0x10, 0x11, 0x14, 0x15,
4879
        0x18, 0x19, 0x1C, 0x1D};
4880
 
4881
  emit_move_insn (mask, array_to_constant (TImode, arr));
4882
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4883
  DONE;
4884
}")
4885
 
4886
(define_expand "vec_extract_evenv16qi"
4887
 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
4888
       (vec_concat:V16QI
4889
         (vec_select:V8QI
4890
           (match_operand:V16QI 1 "spu_reg_operand" "r")
4891
           (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)
4892
                      (const_int 8)(const_int 10)(const_int 12)(const_int 14)]))
4893
         (vec_select:V8QI
4894
           (match_operand:V16QI 2 "spu_reg_operand" "r")
4895
           (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)
4896
                      (const_int 8)(const_int 10)(const_int 12)(const_int 14)]))))]
4897
 
4898
  ""
4899
  "
4900
{
4901
  rtx mask = gen_reg_rtx (TImode);
4902
  unsigned char arr[16] = {
4903
        0x00, 0x02, 0x04, 0x06,
4904
        0x08, 0x0A, 0x0C, 0x0E,
4905
        0x10, 0x12, 0x14, 0x16,
4906
        0x18, 0x1A, 0x1C, 0x1E};
4907
 
4908
  emit_move_insn (mask, array_to_constant (TImode, arr));
4909
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4910
  DONE;
4911
}")
4912
 
4913
(define_expand "vec_extract_oddv4si"
4914
 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4915
       (vec_concat:V4SI
4916
         (vec_select:V2SI
4917
           (match_operand:V4SI 1 "spu_reg_operand" "r")
4918
           (parallel [(const_int 1)(const_int 3)]))
4919
         (vec_select:V2SI
4920
           (match_operand:V4SI 2 "spu_reg_operand" "r")
4921
           (parallel [(const_int 1)(const_int 3)]))))]
4922
 
4923
  ""
4924
  "
4925
{
4926
  rtx mask = gen_reg_rtx (TImode);
4927
  unsigned char arr[16] = {
4928
        0x04, 0x05, 0x06, 0x07,
4929
        0x0C, 0x0D, 0x0E, 0x0F,
4930
        0x14, 0x15, 0x16, 0x17,
4931
        0x1C, 0x1D, 0x1E, 0x1F};
4932
 
4933
  emit_move_insn (mask, array_to_constant (TImode, arr));
4934
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4935
  DONE;
4936
}")
4937
 
4938
(define_expand "vec_extract_oddv4sf"
4939
 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
4940
       (vec_concat:V4SF
4941
         (vec_select:V2SF
4942
           (match_operand:V4SF 1 "spu_reg_operand" "r")
4943
           (parallel [(const_int 1)(const_int 3)]))
4944
         (vec_select:V2SF
4945
           (match_operand:V4SF 2 "spu_reg_operand" "r")
4946
           (parallel [(const_int 1)(const_int 3)]))))]
4947
 
4948
  ""
4949
  "
4950
{
4951
  rtx mask = gen_reg_rtx (TImode);
4952
  unsigned char arr[16] = {
4953
        0x04, 0x05, 0x06, 0x07,
4954
        0x0C, 0x0D, 0x0E, 0x0F,
4955
        0x14, 0x15, 0x16, 0x17,
4956
        0x1C, 0x1D, 0x1E, 0x1F};
4957
 
4958
  emit_move_insn (mask, array_to_constant (TImode, arr));
4959
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4960
  DONE;
4961
}")
4962
 
4963
(define_expand "vec_extract_oddv8hi"
4964
 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4965
       (vec_concat:V8HI
4966
         (vec_select:V4HI
4967
           (match_operand:V8HI 1 "spu_reg_operand" "r")
4968
           (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))
4969
         (vec_select:V4HI
4970
           (match_operand:V8HI 2 "spu_reg_operand" "r")
4971
           (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))]
4972
 
4973
  ""
4974
  "
4975
{
4976
  rtx mask = gen_reg_rtx (TImode);
4977
  unsigned char arr[16] = {
4978
        0x02, 0x03, 0x06, 0x07,
4979
        0x0A, 0x0B, 0x0E, 0x0F,
4980
        0x12, 0x13, 0x16, 0x17,
4981
        0x1A, 0x1B, 0x1E, 0x1F};
4982
 
4983
  emit_move_insn (mask, array_to_constant (TImode, arr));
4984
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4985
  DONE;
4986
}")
4987
 
4988
(define_expand "vec_extract_oddv16qi"
4989
 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
4990
       (vec_concat:V16QI
4991
         (vec_select:V8QI
4992
           (match_operand:V16QI 1 "spu_reg_operand" "r")
4993
           (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
4994
                      (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))
4995
         (vec_select:V8QI
4996
           (match_operand:V16QI 2 "spu_reg_operand" "r")
4997
           (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
4998
                      (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))))]
4999
 
5000
  ""
5001
  "
5002
{
5003
  rtx mask = gen_reg_rtx (TImode);
5004
  unsigned char arr[16] = {
5005
        0x01, 0x03, 0x05, 0x07,
5006
        0x09, 0x0B, 0x0D, 0x0F,
5007
        0x11, 0x13, 0x15, 0x17,
5008
        0x19, 0x1B, 0x1D, 0x1F};
5009
 
5010
  emit_move_insn (mask, array_to_constant (TImode, arr));
5011
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5012
  DONE;
5013
}")
5014
 
5015
(define_expand "vec_interleave_highv4sf"
5016
 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5017
       (vec_select:V4SF
5018
         (vec_concat:V4SF
5019
           (vec_select:V2SF
5020
             (match_operand:V4SF 1 "spu_reg_operand" "r")
5021
             (parallel [(const_int 0)(const_int 1)]))
5022
           (vec_select:V2SF
5023
             (match_operand:V4SF 2 "spu_reg_operand" "r")
5024
             (parallel [(const_int 0)(const_int 1)])))
5025
         (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5026
 
5027
  ""
5028
  "
5029
{
5030
  rtx mask = gen_reg_rtx (TImode);
5031
  unsigned char arr[16] = {
5032
        0x00, 0x01, 0x02, 0x03,
5033
        0x10, 0x11, 0x12, 0x13,
5034
        0x04, 0x05, 0x06, 0x07,
5035
        0x14, 0x15, 0x16, 0x17};
5036
 
5037
  emit_move_insn (mask, array_to_constant (TImode, arr));
5038
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5039
  DONE;
5040
}")
5041
 
5042
(define_expand "vec_interleave_lowv4sf"
5043
 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5044
       (vec_select:V4SF
5045
         (vec_concat:V4SF
5046
           (vec_select:V2SF
5047
             (match_operand:V4SF 1 "spu_reg_operand" "r")
5048
             (parallel [(const_int 2)(const_int 3)]))
5049
           (vec_select:V2SF
5050
             (match_operand:V4SF 2 "spu_reg_operand" "r")
5051
             (parallel [(const_int 2)(const_int 3)])))
5052
         (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5053
 
5054
  ""
5055
  "
5056
{
5057
  rtx mask = gen_reg_rtx (TImode);
5058
  unsigned char arr[16] = {
5059
        0x08, 0x09, 0x0A, 0x0B,
5060
        0x18, 0x19, 0x1A, 0x1B,
5061
        0x0C, 0x0D, 0x0E, 0x0F,
5062
        0x1C, 0x1D, 0x1E, 0x1F};
5063
 
5064
  emit_move_insn (mask, array_to_constant (TImode, arr));
5065
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5066
  DONE;
5067
}")
5068
 
5069
(define_expand "vec_interleave_highv4si"
5070
 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5071
       (vec_select:V4SI
5072
         (vec_concat:V4SI
5073
           (vec_select:V2SI
5074
             (match_operand:V4SI 1 "spu_reg_operand" "r")
5075
             (parallel [(const_int 0)(const_int 1)]))
5076
           (vec_select:V2SI
5077
             (match_operand:V4SI 2 "spu_reg_operand" "r")
5078
             (parallel [(const_int 0)(const_int 1)])))
5079
         (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5080
 
5081
  ""
5082
  "
5083
{
5084
  rtx mask = gen_reg_rtx (TImode);
5085
  unsigned char arr[16] = {
5086
        0x00, 0x01, 0x02, 0x03,
5087
        0x10, 0x11, 0x12, 0x13,
5088
        0x04, 0x05, 0x06, 0x07,
5089
        0x14, 0x15, 0x16, 0x17};
5090
 
5091
  emit_move_insn (mask, array_to_constant (TImode, arr));
5092
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5093
  DONE;
5094
}")
5095
 
5096
(define_expand "vec_interleave_lowv4si"
5097
 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5098
       (vec_select:V4SI
5099
         (vec_concat:V4SI
5100
           (vec_select:V2SI
5101
             (match_operand:V4SI 1 "spu_reg_operand" "r")
5102
             (parallel [(const_int 2)(const_int 3)]))
5103
           (vec_select:V2SI
5104
             (match_operand:V4SI 2 "spu_reg_operand" "r")
5105
             (parallel [(const_int 2)(const_int 3)])))
5106
         (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5107
 
5108
  ""
5109
  "
5110
{
5111
  rtx mask = gen_reg_rtx (TImode);
5112
  unsigned char arr[16] = {
5113
        0x08, 0x09, 0x0A, 0x0B,
5114
        0x18, 0x19, 0x1A, 0x1B,
5115
        0x0C, 0x0D, 0x0E, 0x0F,
5116
        0x1C, 0x1D, 0x1E, 0x1F};
5117
 
5118
  emit_move_insn (mask, array_to_constant (TImode, arr));
5119
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5120
  DONE;
5121
}")
5122
 
5123
(define_expand "vec_interleave_highv8hi"
5124
 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5125
       (vec_select:V8HI
5126
         (vec_concat:V8HI
5127
           (vec_select:V4HI
5128
             (match_operand:V8HI 1 "spu_reg_operand" "r")
5129
             (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))
5130
           (vec_select:V4HI
5131
             (match_operand:V8HI 2 "spu_reg_operand" "r")
5132
             (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
5133
         (parallel [(const_int 0)(const_int 4)(const_int 1)(const_int 5)
5134
                    (const_int 2)(const_int 6)(const_int 3)(const_int 7)])))]
5135
 
5136
  ""
5137
  "
5138
{
5139
  rtx mask = gen_reg_rtx (TImode);
5140
  unsigned char arr[16] = {
5141
        0x00, 0x01, 0x10, 0x11,
5142
        0x02, 0x03, 0x12, 0x13,
5143
        0x04, 0x05, 0x14, 0x15,
5144
        0x06, 0x07, 0x16, 0x17};
5145
 
5146
  emit_move_insn (mask, array_to_constant (TImode, arr));
5147
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5148
  DONE;
5149
 }")
5150
 
5151
(define_expand "vec_interleave_lowv8hi"
5152
 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5153
       (vec_select:V8HI
5154
         (vec_concat:V8HI
5155
           (vec_select:V4HI
5156
             (match_operand:V8HI 1 "spu_reg_operand" "r")
5157
             (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))
5158
           (vec_select:V4HI
5159
             (match_operand:V8HI 2 "spu_reg_operand" "r")
5160
             (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
5161
         (parallel [(const_int 0)(const_int 4)(const_int 1)(const_int 5)
5162
                    (const_int 2)(const_int 6)(const_int 3)(const_int 7)])))]
5163
 
5164
  ""
5165
  "
5166
{
5167
  rtx mask = gen_reg_rtx (TImode);
5168
  unsigned char arr[16] = {
5169
        0x08, 0x09, 0x18, 0x19,
5170
        0x0A, 0x0B, 0x1A, 0x1B,
5171
        0x0C, 0x0D, 0x1C, 0x1D,
5172
        0x0E, 0x0F, 0x1E, 0x1F};
5173
 
5174
  emit_move_insn (mask, array_to_constant (TImode, arr));
5175
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5176
  DONE;
5177
}")
5178
 
5179
(define_expand "vec_interleave_highv16qi"
5180
 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5181
       (vec_select:V16QI
5182
         (vec_concat:V16QI
5183
           (vec_select:V8QI
5184
             (match_operand:V16QI 1 "spu_reg_operand" "r")
5185
             (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
5186
                        (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))
5187
           (vec_select:V8QI
5188
             (match_operand:V16QI 2 "spu_reg_operand" "r")
5189
             (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
5190
                        (const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
5191
         (parallel [(const_int 0)(const_int 8)(const_int 1)(const_int 9)
5192
                    (const_int 2)(const_int 10)(const_int 3)(const_int 11)
5193
                    (const_int 4)(const_int 12)(const_int 5)(const_int 13)
5194
                    (const_int 6)(const_int 14)(const_int 7)(const_int 15)])))]
5195
 
5196
  ""
5197
  "
5198
{
5199
  rtx mask = gen_reg_rtx (TImode);
5200
  unsigned char arr[16] = {
5201
        0x00, 0x10, 0x01, 0x11,
5202
        0x02, 0x12, 0x03, 0x13,
5203
        0x04, 0x14, 0x05, 0x15,
5204
        0x06, 0x16, 0x07, 0x17};
5205
 
5206
  emit_move_insn (mask, array_to_constant (TImode, arr));
5207
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5208
  DONE;
5209
}")
5210
 
5211
(define_expand "vec_interleave_lowv16qi"
5212
 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5213
       (vec_select:V16QI
5214
         (vec_concat:V16QI
5215
           (vec_select:V8QI
5216
             (match_operand:V16QI 1 "spu_reg_operand" "r")
5217
             (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
5218
                        (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))
5219
           (vec_select:V8QI
5220
             (match_operand:V16QI 2 "spu_reg_operand" "r")
5221
             (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
5222
                        (const_int 12)(const_int 13)(const_int 14)(const_int 15)])))
5223
         (parallel [(const_int 0)(const_int 8)(const_int 1)(const_int 9)
5224
                    (const_int 2)(const_int 10)(const_int 3)(const_int 11)
5225
                    (const_int 4)(const_int 12)(const_int 5)(const_int 13)
5226
                    (const_int 6)(const_int 14)(const_int 7)(const_int 15)])))]
5227
 
5228
  ""
5229
  "
5230
{
5231
  rtx mask = gen_reg_rtx (TImode);
5232
  unsigned char arr[16] = {
5233
         0x08, 0x18, 0x09, 0x19,
5234
         0x0A, 0x1A, 0x0B, 0x1B,
5235
         0x0C, 0x1C, 0x0D, 0x1D,
5236
         0x0E, 0x1E, 0x0F, 0x1F};
5237
 
5238
  emit_move_insn (mask, array_to_constant (TImode, arr));
5239
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5240
  DONE;
5241
}")
5242
 
5243
(define_expand "vec_pack_trunc_v8hi"
5244
  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5245
        (vec_concat:V16QI
5246
          (truncate:V8QI (match_operand:V8HI 1 "spu_reg_operand" "r"))
5247
          (truncate:V8QI (match_operand:V8HI 2 "spu_reg_operand" "r"))))]
5248
  ""
5249
  "
5250
{
5251
  rtx mask = gen_reg_rtx (TImode);
5252
  unsigned char arr[16] = {
5253
    0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
5254
    0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F};
5255
 
5256
  emit_move_insn (mask, array_to_constant (TImode, arr));
5257
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5258
 
5259
  DONE;
5260
}")
5261
 
5262
(define_expand "vec_pack_trunc_v4si"
5263
  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5264
        (vec_concat:V8HI
5265
          (truncate:V4HI (match_operand:V4SI 1 "spu_reg_operand" "r"))
5266
          (truncate:V4HI (match_operand:V4SI 2 "spu_reg_operand" "r"))))]
5267
  ""
5268
  "
5269
{
5270
  rtx mask = gen_reg_rtx (TImode);
5271
  unsigned char arr[16] = {
5272
    0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
5273
    0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F};
5274
 
5275
  emit_move_insn (mask, array_to_constant (TImode, arr));
5276
  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5277
 
5278
  DONE;
5279
}")
5280
 
5281
(define_insn "stack_protect_set"
5282
  [(set (match_operand:SI 0 "memory_operand" "=m")
5283
        (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
5284
   (set (match_scratch:SI 2 "=&r") (const_int 0))]
5285
  ""
5286
  "lq%p1\t%2,%1\;stq%p0\t%2,%0\;xor\t%2,%2,%2"
5287
  [(set_attr "length" "12")
5288
   (set_attr "type" "multi1")]
5289
)
5290
 
5291
(define_expand "stack_protect_test"
5292
  [(match_operand 0 "memory_operand" "")
5293
   (match_operand 1 "memory_operand" "")
5294
   (match_operand 2 "" "")]
5295
  ""
5296
{
5297
  rtx compare_result;
5298
  rtx bcomp, loc_ref;
5299
 
5300
  compare_result = gen_reg_rtx (SImode);
5301
 
5302
  emit_insn (gen_stack_protect_test_si (compare_result,
5303
                                        operands[0],
5304
                                        operands[1]));
5305
 
5306
  bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
5307
 
5308
  loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
5309
 
5310
  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
5311
                                   gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
5312
                                                         loc_ref, pc_rtx)));
5313
 
5314
  DONE;
5315
})
5316
 
5317
(define_insn "stack_protect_test_si"
5318
  [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
5319
        (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
5320
                    (match_operand:SI 2 "memory_operand" "m")]
5321
                   UNSPEC_SP_TEST))
5322
   (set (match_scratch:SI 3 "=&r") (const_int 0))]
5323
  ""
5324
  "lq%p1\t%0,%1\;lq%p2\t%3,%2\;ceq\t%0,%0,%3\;xor\t%3,%3,%3"
5325
  [(set_attr "length" "16")
5326
   (set_attr "type" "multi1")]
5327
)
5328
 

powered by: WebSVN 2.1.0

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