xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/tilegx/tilegx.md (revision 16dce51364ebe8aeafbae46bc5aa167b8115bc45)
1;; Machine description for Tilera TILE-Gx chip for GCC.
2;; Copyright (C) 2011-2015 Free Software Foundation, Inc.
3;; Contributed by Walter Lee (walt@tilera.com)
4;;
5;; This file is part of GCC.
6;;
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published
9;; by the Free Software Foundation; either version 3, or (at your
10;; option) any later version.
11;;
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15;; License for more details.
16;;
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3.  If not see
19;; <http://www.gnu.org/licenses/>.
20
21(define_constants [
22  ;;
23  ;; The following represent intrinsic insns, organized by latency.
24  ;;
25
26  ;; single cycle
27  (UNSPEC_INSN_ADDR_SHL16INSLI         1)
28  (UNSPEC_INSN_BFEXTS                  2)
29  (UNSPEC_INSN_BFEXTU                  3)
30  (UNSPEC_INSN_BFINS                   4)
31  (UNSPEC_INSN_CRC32_32                5)
32  (UNSPEC_INSN_CRC32_8                 6)
33  (UNSPEC_INSN_DBLALIGN                7)
34  (UNSPEC_INSN_DBLALIGN2               8)
35  (UNSPEC_INSN_DBLALIGN4               9)
36  (UNSPEC_INSN_DBLALIGN6               10)
37  (UNSPEC_INSN_DRAIN                   11)
38  (UNSPEC_INSN_DTLBPR                  12)
39  (UNSPEC_INSN_FINV                    13)
40  (UNSPEC_INSN_FLUSH                   14)
41  (UNSPEC_INSN_FLUSHWB                 15)
42  (UNSPEC_INSN_FNOP                    16)
43  (UNSPEC_INSN_ICOH                    17)
44  (UNSPEC_INSN_ILL                     18)
45  (UNSPEC_INSN_INFO                    19)
46  (UNSPEC_INSN_INFOL                   20)
47  (UNSPEC_INSN_INV                     21)
48  (UNSPEC_INSN_LNK                     22)
49  (UNSPEC_INSN_MFSPR                   23)
50  (UNSPEC_INSN_MM                      24)
51  (UNSPEC_INSN_MTSPR                   25)
52  (UNSPEC_INSN_NAP                     26)
53  (UNSPEC_INSN_PREFETCH_L1_FAULT       27)
54  (UNSPEC_INSN_PREFETCH_L2_FAULT       28)
55  (UNSPEC_INSN_PREFETCH_L3_FAULT       29)
56  (UNSPEC_INSN_REVBITS                 30)
57  (UNSPEC_INSN_SHUFFLEBYTES            31)
58  (UNSPEC_INSN_TBLIDXB0                32)
59  (UNSPEC_INSN_TBLIDXB1                33)
60  (UNSPEC_INSN_TBLIDXB2                34)
61  (UNSPEC_INSN_TBLIDXB3                35)
62  (UNSPEC_INSN_V1AVGU                  36)
63  (UNSPEC_INSN_V2AVGS                  37)
64  (UNSPEC_INSN_WH64                    38)
65
66  ;; 2 cycles
67  (UNSPEC_INSN_CMUL                    100)
68  (UNSPEC_INSN_CMULA                   101)
69  (UNSPEC_INSN_CMULAF                  102)
70  (UNSPEC_INSN_CMULFR                  103)
71  (UNSPEC_INSN_CMULHR                  104)
72  (UNSPEC_INSN_CMULF                   105)
73  (UNSPEC_INSN_CMULH                   106)
74  (UNSPEC_INSN_EXCH                    107)
75  (UNSPEC_INSN_FDOUBLE_ADDSUB          108)
76  (UNSPEC_INSN_FDOUBLE_ADD_FLAGS       109)
77  (UNSPEC_INSN_FDOUBLE_MUL_FLAGS       110)
78  (UNSPEC_INSN_FDOUBLE_PACK1           111)
79  (UNSPEC_INSN_FDOUBLE_PACK2           112)
80  (UNSPEC_INSN_FDOUBLE_SUB_FLAGS       113)
81  (UNSPEC_INSN_FDOUBLE_UNPACK_MAX      114)
82  (UNSPEC_INSN_FDOUBLE_UNPACK_MIN      115)
83  (UNSPEC_INSN_FETCHADDGEZ             116)
84  (UNSPEC_INSN_FSINGLE_ADD1            117)
85  (UNSPEC_INSN_FSINGLE_ADDSUB2         118)
86  (UNSPEC_INSN_FSINGLE_MUL1            119)
87  (UNSPEC_INSN_FSINGLE_MUL2            120)
88  (UNSPEC_INSN_FSINGLE_PACK1           121)
89  (UNSPEC_INSN_FSINGLE_PACK2           122)
90  (UNSPEC_INSN_FSINGLE_SUB1            123)
91  (UNSPEC_INSN_MULAX                   124)
92  (UNSPEC_INSN_MULA_HS_HS              125)
93  (UNSPEC_INSN_MULA_HS_HU              126)
94  (UNSPEC_INSN_MULA_HS_LS              127)
95  (UNSPEC_INSN_MULA_HS_LU              128)
96  (UNSPEC_INSN_MULA_HU_HU              129)
97  (UNSPEC_INSN_MULA_HU_LS              130)
98  (UNSPEC_INSN_MULA_HU_LU              131)
99  (UNSPEC_INSN_MULA_LS_LS              132)
100  (UNSPEC_INSN_MULA_LS_LU              133)
101  (UNSPEC_INSN_MULA_LU_LU              134)
102  (UNSPEC_INSN_MUL_HS_HS               135)
103  (UNSPEC_INSN_MUL_HS_HU               136)
104  (UNSPEC_INSN_MUL_HS_LS               137)
105  (UNSPEC_INSN_MUL_HS_LU               138)
106  (UNSPEC_INSN_MUL_HU_HU               139)
107  (UNSPEC_INSN_MUL_HU_LS               140)
108  (UNSPEC_INSN_MUL_HU_LU               141)
109  (UNSPEC_INSN_MUL_LS_LS               142)
110  (UNSPEC_INSN_MUL_LS_LU               143)
111  (UNSPEC_INSN_MUL_LU_LU               144)
112  (UNSPEC_INSN_V1ADIFFU                145)
113  (UNSPEC_INSN_V1DDOTPU                146)
114  (UNSPEC_INSN_V1DDOTPUA               147)
115  (UNSPEC_INSN_V1DDOTPUS               148)
116  (UNSPEC_INSN_V1DDOTPUSA              149)
117  (UNSPEC_INSN_V1DOTP                  150)
118  (UNSPEC_INSN_V1DOTPA                 151)
119  (UNSPEC_INSN_V1DOTPU                 152)
120  (UNSPEC_INSN_V1DOTPUA                153)
121  (UNSPEC_INSN_V1DOTPUS                154)
122  (UNSPEC_INSN_V1DOTPUSA               155)
123  (UNSPEC_INSN_V1SADAU                 156)
124  (UNSPEC_INSN_V1SADU                  157)
125  (UNSPEC_INSN_V2ADIFFS                158)
126  (UNSPEC_INSN_V2DOTP                  159)
127  (UNSPEC_INSN_V2DOTPA                 160)
128  (UNSPEC_INSN_V2MULFSC                161)
129  (UNSPEC_INSN_V2SADAS                 162)
130  (UNSPEC_INSN_V2SADAU                 163)
131  (UNSPEC_INSN_V2SADS                  164)
132  (UNSPEC_INSN_V2SADU                  165)
133
134  ;; 11 cycles
135  (UNSPEC_INSN_CMPEXCH                 200)
136
137  ;;
138  ;; The following are special insns.
139  ;;
140
141  ;; Blockage
142  (UNSPEC_BLOCKAGE                     201)
143
144  ;; Lnk and its label
145  (UNSPEC_LNK_AND_LABEL                202)
146
147  ;; Memory fence
148  (UNSPEC_MF		               203)
149
150  ;; Insns generating difference of two labels
151  (UNSPEC_MOV_PCREL_STEP3              204)
152  (UNSPEC_MOV_LARGE_PCREL_STEP4        205)
153
154  ;; Latency specifying loads.
155  (UNSPEC_LATENCY_L2                   206)
156  (UNSPEC_LATENCY_MISS                 207)
157
158  ;; A pseudo-op that prevents network operations from being ordered.
159  (UNSPEC_NETWORK_BARRIER              208)
160
161  ;; Operations that access network registers.
162  (UNSPEC_NETWORK_RECEIVE              209)
163  (UNSPEC_NETWORK_SEND                 210)
164
165  ;; Stack protector operations
166  (UNSPEC_SP_SET                       211)
167  (UNSPEC_SP_TEST                      212)
168
169  ;; This is used to move a value to a SPR.
170  (UNSPEC_SPR_MOVE                     213)
171
172  ;; A call to __tls_get_addr
173  (UNSPEC_TLS_GD_CALL                  214)
174
175  ;; An opaque TLS "add" operation for TLS general dynamic model
176  ;; access.
177  (UNSPEC_TLS_GD_ADD                   215)
178
179  ;; An opaque TLS "load" operation for TLS initial exec model access.
180  (UNSPEC_TLS_IE_LOAD                  216)
181
182  ;; An opaque TLS "add" operation for TLS access.
183  (UNSPEC_TLS_ADD                      217)
184
185  ;; Atomics
186  (UNSPEC_ATOMIC                       218)
187  (UNSPEC_CMPXCHG                      219)
188  (UNSPEC_XCHG                         220)
189
190  ;;
191  ;; The following are operands.
192  ;;
193  (UNSPEC_HW0                          300)
194  (UNSPEC_HW1                          301)
195  (UNSPEC_HW2                          302)
196  (UNSPEC_HW3                          303)
197  (UNSPEC_HW0_LAST                     304)
198  (UNSPEC_HW1_LAST                     305)
199  (UNSPEC_HW2_LAST                     306)
200
201  (UNSPEC_HW0_PCREL                    307)
202  (UNSPEC_HW1_PCREL                    308)
203  (UNSPEC_HW1_LAST_PCREL               309)
204  (UNSPEC_HW2_LAST_PCREL               310)
205
206  (UNSPEC_HW0_GOT                      311)
207  (UNSPEC_HW0_LAST_GOT                 312)
208  (UNSPEC_HW1_LAST_GOT                 313)
209
210  (UNSPEC_HW0_TLS_GD                   314)
211  (UNSPEC_HW1_LAST_TLS_GD              315)
212
213  (UNSPEC_HW0_TLS_IE                   316)
214  (UNSPEC_HW1_LAST_TLS_IE              317)
215
216  (UNSPEC_HW0_TLS_LE                   318)
217  (UNSPEC_HW1_LAST_TLS_LE              319)
218
219  (UNSPEC_HW0_PLT_PCREL                320)
220  (UNSPEC_HW1_PLT_PCREL                321)
221
222  (UNSPEC_HW1_LAST_PLT_PCREL           322)
223  (UNSPEC_HW2_LAST_PLT_PCREL           323)
224
225  ;; This is used to wrap around the addresses of non-temporal load/store
226  ;; intrinsics.
227  (UNSPEC_NON_TEMPORAL                 324)
228])
229
230;; Mark the last instruction of various latencies, used to
231;; determine the rtx costs of unspec insns.
232(define_constants [
233  (TILEGX_LAST_LATENCY_1_INSN           99)
234  (TILEGX_LAST_LATENCY_2_INSN          199)
235  (TILEGX_LAST_LATENCY_INSN            299)
236])
237
238(define_constants [
239  (TILEGX_NETREG_IDN0 0)
240  (TILEGX_NETREG_IDN1 1)
241  (TILEGX_NETREG_UDN0 2)
242  (TILEGX_NETREG_UDN1 3)
243  (TILEGX_NETREG_UDN2 4)
244  (TILEGX_NETREG_UDN3 5)
245])
246
247(define_constants [
248  (TILEGX_CMPEXCH_REG  66)
249  (TILEGX_NETORDER_REG 67)
250])
251
252
253;; Operand and operator predicates and constraints
254
255(include "predicates.md")
256(include "constraints.md")
257(include "tilegx-generic.md")
258
259;; Define an insn type attribute.  This defines what pipes things can go in.
260(define_attr "type"
261  "X0,X0_2cycle,X1,X1_branch,X1_2cycle,X1_L2,X1_remote,X1_miss,X01,Y0,Y0_2cycle,Y1,Y2,Y2_2cycle,Y2_L2,Y2_miss,Y01,cannot_bundle,cannot_bundle_3cycle,cannot_bundle_4cycle,nothing"
262  (const_string "Y01"))
263
264(define_attr "length" ""
265   (cond [(eq_attr "type" "X1_branch")
266	  (if_then_else
267	   (and (le (minus (match_dup 0) (pc)) (const_int 524280))
268		(le (minus (pc) (match_dup 0)) (const_int 524288)))
269	   (const_int 8)
270	   (const_int 16))
271	  ]
272	 (const_int 8)))
273
274
275;; Define some iterators.
276(define_mode_iterator IVMODE [SI DI V8QI V4HI V2SI])
277(define_mode_iterator IVNMODE [SI V8QI V4HI V2SI])
278(define_mode_iterator I48MODE [SI DI])
279(define_mode_iterator I48MODE2 [SI DI])
280(define_mode_iterator I124MODE [QI HI SI])
281(define_mode_iterator FI48MODE [SF DF SI DI])
282(define_mode_iterator VEC48MODE [V8QI V4HI])
283(define_mode_iterator VEC248MODE [V8QI V4HI V2SI])
284
285(define_mode_attr n [(QI "1") (HI "2") (SI "4") (DI "")
286		     (V8QI "1") (V4HI "2") (V2SI "4")])
287(define_mode_attr x [(SI "x") (DI "")])
288(define_mode_attr bitsuffix [(SI "_32bit") (DI "")])
289(define_mode_attr four_if_si [(SI "4") (DI "")])
290(define_mode_attr four_s_if_si [(SI "4s") (DI "")])
291(define_mode_attr nbits [(SI "5") (DI "6")])
292(define_mode_attr shift_pipe [(SI "X01") (DI "*")])
293
294;; Code iterator for either extend.
295(define_code_iterator any_extend [sign_extend zero_extend])
296
297;; Code iterator for all three shifts.
298(define_code_iterator any_shift [ashift ashiftrt lshiftrt])
299
300;; Code iterator for all byte ops without immediate variants.
301(define_code_iterator v1op [us_minus us_plus minus ne le leu mult])
302
303;; Code iterator for all 2-byte vector ops without immediate variants.
304(define_code_iterator v2op [ss_minus ss_plus minus ne le leu])
305
306;; Code iterator for all 4-byte vector ops without immediate variants.
307(define_code_iterator v4op [ss_minus ss_plus minus plus])
308
309;; Code iterator for all byte vector ops with immediate variants.
310(define_code_iterator v1op_immed [plus umax umin eq lt ltu])
311
312;; Code iterator for all 2-byte vector ops with immediate variants.
313(define_code_iterator v2op_immed [plus smax smin eq lt ltu])
314
315;; Code iterator for all 2-byte vector shifts without immediate variants.
316(define_code_iterator v2shift [ss_ashift])
317
318;; Code iterator for all 4-byte vector shifts without immediate variants.
319(define_code_iterator v4shift [ashift ashiftrt lshiftrt ss_ashift])
320
321;; <optab> expands to the name of the optab for a particular code.
322(define_code_attr optab [(ashift "ashl")
323			 (ashiftrt "ashr")
324			 (lshiftrt "lshr")
325			 (ss_ashift "ssashl")
326			 (eq "seq")
327			 (ne "sne")
328			 (lt "slt")
329			 (ltu "sltu")
330			 (le "sle")
331			 (leu "sleu")
332			 (minus "sub")
333			 (plus "add")
334			 (mult "mul")
335			 (smax "smax")
336			 (smin "smin")
337			 (ss_minus "sssub")
338			 (ss_plus "ssadd")
339			 (umax "umax")
340			 (umin "umin")
341			 (us_minus "ussub")
342			 (us_plus "usadd")
343			 ])
344
345;; <insn> expands to the name of the insn that implements a particular
346;; code.
347(define_code_attr insn [(ashift "shl")
348			(ashiftrt "shrs")
349			(lshiftrt "shru")
350			(ss_ashift "shlsc")
351			(eq "cmpeq")
352			(ne "cmpne")
353			(lt "cmplts")
354			(ltu "cmpltu")
355			(le "cmples")
356			(leu "cmpleu")
357			(minus "sub")
358			(plus "add")
359			(mult "multu")
360			(smax "maxs")
361			(smin "mins")
362			(umax "maxu")
363			(umin "minu")
364			(ss_minus "subsc")
365			(ss_plus  "addsc")
366                        (us_minus "subuc")
367                        (us_plus  "adduc")
368			])
369
370;; <pipe> expands to the pipeline resource that contains the
371;; particular code.
372(define_code_attr pipe [(ashift "X01")
373			(ashiftrt "X01")
374			(lshiftrt "X01")
375			(ss_ashift "X01")
376			(eq "X01")
377			(ne "X01")
378			(lt "X01")
379			(ltu "X01")
380			(le "X01")
381			(leu "X01")
382			(minus "X01")
383			(plus "X01")
384			(mult "X0_2cycle")
385			(smax "X01")
386			(smin "X01")
387			(umax "X01")
388			(umin "X01")
389			(ss_minus "X01")
390			(ss_plus  "X01")
391                        (us_minus "X01")
392                        (us_plus  "X01")
393			])
394
395;; <comm> indicates whether a particular code is commutative, using
396;; the "%" commutative opterator constraint.
397(define_code_attr comm [(ashift "")
398			(ashiftrt "")
399			(lshiftrt "")
400			(ss_ashift "")
401			(eq "%")
402			(ne "%")
403			(lt "")
404			(ltu "")
405			(le "")
406			(leu "")
407			(minus "")
408			(plus "%")
409			(mult "%")
410			(smin "%")
411			(umin "%")
412			(smax "%")
413			(umax "%")
414			(ss_plus "%")
415			(us_plus "%")
416			(ss_minus "")
417			(us_minus "")
418			])
419
420;; <s> is the load/store extension suffix.
421(define_code_attr s [(zero_extend "u")
422		     (sign_extend "s")])
423
424;; Code for packing two 2-byte vectors.
425(define_code_iterator v2pack [truncate us_truncate])
426
427;; <pack_optab> expands to the part of the optab name describing how
428;; two vectors are packed.
429(define_code_attr pack_optab [(truncate "trunc")
430			      (us_truncate "usat")
431			      (ss_truncate "ssat")])
432
433;; <pack_insn> expands to the insn that implements a particular vector
434;; packing code.
435(define_code_attr pack_insn [(truncate "packl")
436			     (us_truncate "packuc")
437			     (ss_truncate "packsc")])
438
439;;
440;; The basic data move insns.
441;;
442
443(define_expand "movqi"
444  [(set (match_operand:QI 0 "nonimmediate_operand" "")
445	(match_operand:QI 1 "nonautoinc_operand" ""))]
446  ""
447{
448  if (tilegx_expand_mov (QImode, operands))
449    DONE;
450})
451
452(define_insn "*movqi_insn"
453  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,U,m")
454	(match_operand:QI 1 "move_operand"         "r,I,U,m,rO,rO"))]
455  "(register_operand (operands[0], QImode)
456    || reg_or_0_operand (operands[1], QImode))"
457  "@
458   move\t%0, %r1
459   movei\t%0, %1
460   ld1u\t%0, %1
461   ld1u_add\t%0, %I1, %i1
462   st1\t%0, %r1
463   st1_add\t%I0, %r1, %i0"
464  [(set_attr "type" "*,*,Y2_2cycle,X1_2cycle,Y2,X1")])
465
466(define_expand "movhi"
467  [(set (match_operand:HI 0 "nonimmediate_operand" "")
468	(match_operand:HI 1 "nonautoinc_operand" ""))]
469  ""
470{
471  if (tilegx_expand_mov (HImode, operands))
472    DONE;
473})
474
475(define_insn "*movhi_insn"
476  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,r,U,m")
477	(match_operand:HI 1 "move_operand"         "r,I,JT,U,m,rO,rO"))]
478  "(register_operand (operands[0], HImode)
479    || reg_or_0_operand (operands[1], HImode))"
480  "@
481   move\t%0, %r1
482   movei\t%0, %1
483   moveli\t%0, %H1
484   ld2u\t%0, %1
485   ld2u_add\t%0, %I1, %i1
486   st2\t%0, %r1
487   st2_add\t%I0, %r1, %i0"
488  [(set_attr "type" "*,*,X01,Y2_2cycle,X1_2cycle,Y2,X1")])
489
490(define_expand "movsi"
491  [(set (match_operand:SI 0 "nonimmediate_operand" "")
492	(match_operand:SI 1 "nonautoinc_operand" ""))]
493  ""
494{
495  if (tilegx_expand_mov (SImode, operands))
496    DONE;
497})
498
499(define_insn "*movsi_insn"
500  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,U,m")
501	(match_operand:SI 1 "move_operand"         "r,I,JT,K,U,m,rO,rO"))]
502  "(register_operand (operands[0], SImode)
503    || reg_or_0_operand (operands[1], SImode))"
504  "@
505   move\t%0, %r1
506   movei\t%0, %1
507   moveli\t%0, %H1
508   shl16insli\t%0, zero, %h1
509   ld4s\t%0, %1
510   ld4s_add\t%0, %I1, %i1
511   st4\t%0, %r1
512   st4_add\t%I0, %r1, %i0"
513  [(set_attr "type" "*,*,X01,X01,Y2_2cycle,X1_2cycle,Y2,X1")])
514
515(define_expand "movdi"
516  [(set (match_operand:DI 0 "nonimmediate_operand" "")
517	(match_operand:DI 1 "nonautoinc_operand" ""))]
518  ""
519{
520  if (tilegx_expand_mov (DImode, operands))
521    DONE;
522})
523
524(define_insn "*movdi_insn"
525  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,r,U,m")
526	(match_operand:DI 1 "move_operand"         "r,I,JT,K,N,P,U,m,rO,rO"))]
527  "(register_operand (operands[0], DImode)
528    || reg_or_0_operand (operands[1], DImode))"
529  "@
530   move\t%0, %r1
531   movei\t%0, %1
532   moveli\t%0, %H1
533   shl16insli\t%0, zero, %h1
534   v1addi\t%0, zero, %j1
535   v2addi\t%0, zero, %h1
536   ld\t%0, %1
537   ld_add\t%0, %I1, %i1
538   st\t%0, %r1
539   st_add\t%I0, %r1, %i0"
540  [(set_attr "type" "*,*,X01,X01,X01,X01,Y2_2cycle,X1_2cycle,Y2,X1")])
541
542(define_expand "movmisalign<mode>"
543  [(set (match_operand:VEC248MODE 0 "nonautoincmem_nonimmediate_operand" "")
544        (match_operand:VEC248MODE 1 "nonautoincmem_general_operand" ""))]
545  ""
546{
547  tilegx_expand_movmisalign (<MODE>mode, operands);
548  DONE;
549})
550
551(define_expand "movsf"
552  [(set (match_operand:SF 0 "nonimmediate_operand" "")
553	(match_operand:SF 1 "general_operand" ""))]
554  ""
555{
556  /* Materialize immediates using clever SImode code, but don't
557     do this after reload starts, since gen_lowpart will choke
558     during reload if given an illegitimate address. */
559  if (immediate_operand (operands[1], SFmode)
560      && operands[1] != const0_rtx
561      && (register_operand (operands[0], SFmode)
562          || (!reload_in_progress && !reload_completed)))
563    {
564      emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
565                            gen_lowpart (SImode, operands[1])));
566      DONE;
567    }
568})
569
570(define_insn "*movsf"
571  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,U,m")
572	(match_operand:SF 1 "general_operand" "rO,U,m,rO,rO"))]
573  ""
574  "@
575   move\t%0, %r1
576   ld4s\t%0, %1
577   ld4s_add\t%0, %I1, %i1
578   st4\t%0, %r1
579   st4_add\t%I0, %r1, %i0"
580  [(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")])
581
582(define_expand "movdf"
583  [(set (match_operand:DF 0 "nonimmediate_operand" "")
584	(match_operand:DF 1 "general_operand" ""))]
585  ""
586{
587  /* Materialize immediates using clever DImode code, but don't
588     do this after reload starts, since gen_lowpart will choke
589     during reload if given an illegitimate address. */
590  if (immediate_operand (operands[1], DFmode)
591      && operands[1] != const0_rtx
592      && (register_operand (operands[0], DFmode)
593          || (!reload_in_progress && !reload_completed)))
594    {
595      emit_insn (gen_movdi (gen_lowpart (DImode, operands[0]),
596                            gen_lowpart (DImode, operands[1])));
597      DONE;
598    }
599})
600
601(define_insn "*movdf"
602  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r,U,m")
603	(match_operand:DF 1 "general_operand" "rO,U,m,rO,rO"))]
604  ""
605  "@
606   move\t%0, %r1
607   ld\t%0, %1
608   ld_add\t%0, %I1, %i1
609   st\t%0, %r1
610   st_add\t%I0, %r1, %i0"
611  [(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")])
612
613(define_expand "mov<mode>"
614  [(set (match_operand:VEC248MODE 0 "nonimmediate_operand" "")
615        (match_operand:VEC248MODE 1 "general_operand" ""))]
616  ""
617{
618  /* Materialize immediates using clever DImode code, but don't
619     do this after reload starts, since gen_lowpart will choke
620     during reload if given an illegitimate address. */
621  if (immediate_operand (operands[1], <MODE>mode)
622      && operands[1] != const0_rtx
623      && (register_operand (operands[0], <MODE>mode)
624          || (!reload_in_progress && !reload_completed)))
625    {
626      emit_insn (gen_movdi (gen_lowpart (DImode, operands[0]),
627                            gen_lowpart (DImode, operands[1])));
628      DONE;
629    }
630})
631
632(define_insn "*mov<mode>"
633  [(set (match_operand:VEC248MODE 0 "nonimmediate_operand" "=r,r,r,U,m")
634	(match_operand:VEC248MODE 1 "general_operand" "rO,U,m,rO,rO"))]
635  ""
636  "@
637   move\t%0, %r1
638   ld\t%0, %1
639   ld_add\t%0, %I1, %i1
640   st\t%0, %r1
641   st_add\t%I0, %r1, %i0"
642  [(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")])
643
644(define_insn "movstrictqi"
645  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
646	(match_operand:QI 1 "reg_or_0_operand" "rO"))]
647  ""
648  "bfins\t%0, %r1, 0, 7"
649  [(set_attr "type" "X0")])
650
651(define_insn "movstricthi"
652  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
653	(match_operand:HI 1 "reg_or_0_operand" "rO"))]
654  ""
655  "bfins\t%0, %r1, 0, 15"
656  [(set_attr "type" "X0")])
657
658(define_insn "movstrictsi"
659  [(set (strict_low_part (match_operand:SI 0 "register_operand" "+r"))
660	(match_operand:SI 1 "reg_or_0_operand" "rO"))]
661  ""
662  "bfins\t%0, %r1, 0, 31"
663  [(set_attr "type" "X0")])
664
665
666;;
667;; Bit-field extracts/inserts
668;;
669
670(define_expand "insv"
671  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
672			 (match_operand:DI 1 "u6bit_cint_operand" "")
673			 (match_operand:DI 2 "u6bit_cint_operand" ""))
674	(match_operand:DI 3 "reg_or_cint_operand" ""))]
675  ""
676{
677  rtx first_rtx = operands[2];
678  HOST_WIDE_INT first = INTVAL (first_rtx);
679  HOST_WIDE_INT width = INTVAL (operands[1]);
680  rtx v = operands[3];
681
682  if (CONST_INT_P (v))
683    {
684      /* Which bits are we affecting? */
685      HOST_WIDE_INT mask = ((((HOST_WIDE_INT) 1) << width) - 1) << first;
686
687      /* Extract just the bits we need, sign extending them to make the
688         constant easier to materialize in a register. */
689      int shift = sizeof(HOST_WIDE_INT) * 8 - width;
690      HOST_WIDE_INT n = (INTVAL (v) << shift) >> shift;
691
692      if (n == 0)
693        {
694	  /* We are setting every bit in the bitfield to zero. Try to use
695             andi instead, since that is more efficient. */
696	  rtx mask_rtx = GEN_INT (~mask);
697	  if (satisfies_constraint_I (mask_rtx))
698            {
699	      emit_insn (gen_anddi3 (operands[0], operands[0], mask_rtx));
700	      DONE;
701            }
702
703	  operands[3] = const0_rtx;
704	}
705      else
706        {
707	  if (n == -1)
708	    {
709	      /* We are setting every bit in the bitfield to one. Try to use
710	         ori instead, since that is more efficient. */
711	      rtx mask_rtx = GEN_INT (mask);
712	      if (satisfies_constraint_I (mask_rtx))
713	        {
714		  emit_insn (gen_iordi3 (operands[0], operands[0], mask_rtx));
715		  DONE;
716		}
717	    }
718
719	  if (!can_create_pseudo_p ())
720            FAIL;
721
722	  operands[3] = force_reg (DImode, GEN_INT (n));
723	}
724    }
725})
726
727(define_insn "*insv_tblidxb0"
728  [(set (zero_extract:DI
729	 (match_operand:DI 0 "register_operand" "+r")
730	 (const_int 8)
731	 (const_int 2))
732	(match_operand:DI 1 "register_operand" "rO"))]
733  ""
734  "tblidxb0\t%0, %r1"
735  [(set_attr "type" "Y0")])
736
737(define_insn "*insv_tblidxb1"
738  [(set (zero_extract:DI
739	 (match_operand:DI 0 "register_operand" "+r")
740	 (const_int 8)
741	 (const_int 2))
742	(zero_extract:DI
743	 (const_int 8)
744	 (const_int 8)
745	(match_operand:DI 1 "register_operand" "rO")))]
746  ""
747  "tblidxb1\t%0, %r1"
748  [(set_attr "type" "Y0")])
749
750(define_insn "*insv_tblidxb2"
751  [(set (zero_extract:DI
752	 (match_operand:DI 0 "register_operand" "+r")
753	 (const_int 8)
754	 (const_int 2))
755	(zero_extract:DI
756	 (const_int 8)
757	 (const_int 16)
758	(match_operand:DI 1 "register_operand" "rO")))]
759  ""
760  "tblidxb2\t%0, %r1"
761  [(set_attr "type" "Y0")])
762
763(define_insn "*insv_tblidxb3"
764  [(set (zero_extract:DI
765	 (match_operand:DI 0 "register_operand" "+r")
766	 (const_int 8)
767	 (const_int 2))
768	(zero_extract:DI
769	 (const_int 8)
770	 (const_int 24)
771	(match_operand:DI 1 "register_operand" "rO")))]
772  ""
773  "tblidxb3\t%0, %r1"
774  [(set_attr "type" "Y0")])
775
776(define_insn "*insv_bfins"
777  [(set (zero_extract:DI
778	 (match_operand:DI 0 "register_operand" "+r")
779	 (match_operand:DI 1 "u6bit_cint_operand" "n")
780	 (match_operand:DI 2 "u6bit_cint_operand" "n"))
781	(match_operand:DI 3 "reg_or_cint_operand" "rO"))]
782  ""
783  "bfins\t%0, %r3, %2, %2+%1-1"
784  [(set_attr "type" "X0")])
785
786(define_insn "*insv_mm"
787  [(set (zero_extract:DI
788	 (match_operand:DI 0 "register_operand" "+r")
789	 (match_operand:DI 1 "u6bit_cint_operand" "n")
790	 (match_operand:DI 2 "u6bit_cint_operand" "n"))
791	(zero_extract:DI
792	 (match_operand:DI 3 "register_operand" "rO")
793	 (match_dup 1)
794	 (match_dup 2)))]
795  ""
796{
797  int n;
798
799  operands[1] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]));
800
801  n = INTVAL (operands[2]);
802  n = (n == 0) ? 63 : n - 1;
803  operands[2] = GEN_INT (n);
804
805  return "mm\t%0, %r3, %1, %2";
806}
807  [(set_attr "type" "X0")])
808
809(define_expand "extv"
810  [(set (match_operand:DI 0 "register_operand" "")
811	(sign_extract:DI (match_operand 1 "nonautoincmem_general_operand" "")
812			 (match_operand:DI 2 "immediate_operand" "")
813			 (match_operand:DI 3 "immediate_operand" "")))]
814  ""
815{
816  if (MEM_P (operands[1]))
817    {
818      HOST_WIDE_INT bit_offset, bit_width;
819      HOST_WIDE_INT first_byte_offset, last_byte_offset;
820
821      if (GET_MODE (operands[1]) != QImode)
822        FAIL;
823
824      bit_width = INTVAL (operands[2]);
825      bit_offset = INTVAL (operands[3]);
826
827      /* NOTE: bit_offset is relative to the mode of operand
828         1 (QImode).  It will be negative in big-endian mode
829         here.  Convert that back to the real offset.  */
830      if (BYTES_BIG_ENDIAN)
831        bit_offset = GET_MODE_BITSIZE (QImode) - bit_width - bit_offset;
832
833      /* Reject bitfields that can be done with a normal load.  */
834      if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
835        FAIL;
836
837      /* The value in memory cannot span more than 8 bytes.  */
838      first_byte_offset = bit_offset / BITS_PER_UNIT;
839      last_byte_offset = (bit_offset + bit_width - 1) / BITS_PER_UNIT;
840      if (last_byte_offset - first_byte_offset > 7)
841        FAIL;
842
843      tilegx_expand_unaligned_load (operands[0], operands[1],
844                                    bit_width, bit_offset, 1);
845
846      DONE;
847    }
848
849  operands[1] = force_reg (DImode, operands[1]);
850})
851
852(define_expand "extzv"
853  [(set (match_operand:DI 0 "register_operand" "")
854	(zero_extract:DI (match_operand 1 "nonautoincmem_general_operand" "")
855			 (match_operand:DI 2 "immediate_operand" "")
856			 (match_operand:DI 3 "immediate_operand" "")))]
857  ""
858{
859  HOST_WIDE_INT bit_width = INTVAL (operands[2]);
860  HOST_WIDE_INT bit_offset = INTVAL (operands[3]);
861
862  if (MEM_P (operands[1]))
863    {
864      HOST_WIDE_INT first_byte_offset, last_byte_offset;
865
866      if (GET_MODE (operands[1]) != QImode)
867        FAIL;
868
869      /* NOTE: bit_offset is relative to the mode of operand
870         1 (QImode).  It will be negative in big-endian mode
871         here. */
872      if (BYTES_BIG_ENDIAN)
873        bit_offset = GET_MODE_BITSIZE (QImode) - bit_width - bit_offset;
874
875      /* Reject bitfields that can be done with a normal load.  */
876      if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
877        FAIL;
878
879      /* The value in memory cannot span more than 8 bytes.  */
880      first_byte_offset = bit_offset / BITS_PER_UNIT;
881      last_byte_offset = (bit_offset + bit_width - 1) / BITS_PER_UNIT;
882      if (last_byte_offset - first_byte_offset > 7)
883        FAIL;
884
885      tilegx_expand_unaligned_load (operands[0], operands[1],
886                                    bit_width, bit_offset, 0);
887
888      DONE;
889    }
890
891    operands[1] = force_reg (DImode, operands[1]);
892
893    if (bit_offset == 0)
894      {
895	 /* Extracting the low bits is just a bitwise AND.  */
896	 HOST_WIDE_INT mask = ((HOST_WIDE_INT)1 << bit_width) - 1;
897	 emit_insn (gen_anddi3 (operands[0], operands[1], GEN_INT (mask)));
898	 DONE;
899      }
900})
901
902
903;;
904;; Addresses
905;;
906
907;; The next three patterns are used to to materialize a position
908;; independent address by adding the difference of two labels to a base
909;; label in the text segment, assuming that the difference fits in 32
910;; signed bits.
911(define_expand "mov_address_step1"
912  [(set (match_operand:DI 0 "register_operand" "")
913	(const:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
914			     UNSPEC_HW2_LAST)))])
915
916(define_expand "mov_address_step2"
917  [(set (match_operand:DI 0 "register_operand" "")
918	(unspec:DI
919	 [(match_operand:DI 1 "reg_or_0_operand" "")
920	  (const:DI (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
921			       UNSPEC_HW1))]
922	 UNSPEC_INSN_ADDR_SHL16INSLI))])
923
924(define_expand "mov_address_step3"
925  [(set (match_operand:DI 0 "register_operand" "")
926	(unspec:DI
927	 [(match_operand:DI 1 "reg_or_0_operand" "")
928	  (const:DI (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
929			       UNSPEC_HW0))]
930	 UNSPEC_INSN_ADDR_SHL16INSLI))])
931
932;; First step of the 2-insn sequence to materialize a 32-bit symbolic
933;; address.
934(define_expand "mov_address_32bit_step1"
935  [(set (match_operand:SI 0 "register_operand" "")
936        (const:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "")]
937			     UNSPEC_HW1_LAST)))])
938
939;; Second step of the 2-insn sequence to materialize a 32-bit symbolic
940;; address.
941(define_expand "mov_address_32bit_step2"
942  [(set (match_operand:SI 0 "register_operand" "")
943	(unspec:SI
944	 [(match_operand:SI 1 "reg_or_0_operand" "")
945	  (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
946			       UNSPEC_HW0))]
947	 UNSPEC_INSN_ADDR_SHL16INSLI))])
948
949
950;;
951;; pic related instructions
952;;
953
954;; NOTE: We compute the label in this unusual way because if we place
955;; the label after the lnk, whether it is at the same address as the
956;; lnk will vary depending on whether the optimization level chooses
957;; to insert bundling braces.
958(define_insn "insn_lnk_and_label<bitsuffix>"
959  [(set (match_operand:I48MODE 0 "register_operand" "=r")
960        (unspec_volatile:I48MODE
961         [(match_operand:I48MODE 1 "symbolic_operand" "")]
962         UNSPEC_LNK_AND_LABEL))]
963  ""
964  "%1 = . + 8\n\tlnk\t%0"
965  [(set_attr "type" "Y1")])
966
967;; The next three patterns are used to to materialize a position
968;; independent address by adding the difference of two labels to a
969;; base label in the text segment, assuming that the difference fits
970;; in 32 signed bits.
971(define_expand "mov_pcrel_step1<bitsuffix>"
972  [(set (match_operand:I48MODE 0 "register_operand" "")
973	(const:I48MODE (unspec:I48MODE
974			[(match_operand:I48MODE 1 "symbolic_operand" "")
975			 (match_operand:I48MODE 2 "symbolic_operand" "")]
976                        UNSPEC_HW1_LAST_PCREL)))]
977  "flag_pic")
978
979(define_expand "mov_pcrel_step2<bitsuffix>"
980  [(set (match_operand:I48MODE 0 "register_operand" "")
981	(unspec:I48MODE
982	 [(match_operand:I48MODE 1 "reg_or_0_operand" "")
983	  (const:I48MODE
984	   (unspec:I48MODE [(match_operand:I48MODE 2 "symbolic_operand" "")
985			    (match_operand:I48MODE 3 "symbolic_operand" "")]
986			   UNSPEC_HW0_PCREL))]
987	 UNSPEC_INSN_ADDR_SHL16INSLI))]
988  "flag_pic")
989
990(define_insn "mov_pcrel_step3<bitsuffix>"
991  [(set (match_operand:I48MODE 0 "register_operand" "=r")
992        (unspec:I48MODE [(match_operand:I48MODE 1 "reg_or_0_operand" "rO")
993			 (match_operand:I48MODE 2 "reg_or_0_operand" "rO")
994			 (match_operand:I48MODE 3 "symbolic_operand" "in")
995			 (match_operand:I48MODE 4 "symbolic_operand" "in")]
996                        UNSPEC_MOV_PCREL_STEP3))]
997  "flag_pic"
998  "add<x>\t%0, %r1, %r2")
999
1000;; The next three patterns are used to to materialize a position
1001;; independent 64-bit address by adding the difference of two labels to
1002;; a base label in the text segment, without any limitation on the size
1003;; of the difference.
1004(define_expand "mov_large_pcrel_step1"
1005  [(set (match_operand:DI 0 "register_operand" "")
1006	(const:DI (unspec:DI
1007		   [(match_operand:DI 1 "symbolic_operand" "")
1008		    (match_operand:DI 2 "symbolic_operand" "")]
1009		   UNSPEC_HW2_LAST_PCREL)))]
1010  "flag_pic")
1011
1012(define_expand "mov_large_pcrel_step2"
1013  [(set (match_operand:DI 0 "register_operand" "")
1014	(unspec:DI
1015	 [(match_operand:DI 1 "reg_or_0_operand" "")
1016	  (const:DI
1017	   (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
1018		       (match_operand:DI 3 "symbolic_operand" "")]
1019		      UNSPEC_HW1_PCREL))]
1020	 UNSPEC_INSN_ADDR_SHL16INSLI))]
1021  "flag_pic")
1022
1023;; Note: step 3 is same as move_pcrel_step2.
1024(define_expand "mov_large_pcrel_step3"
1025  [(set (match_operand:DI 0 "register_operand" "")
1026	(unspec:DI
1027	 [(match_operand:DI 1 "reg_or_0_operand" "")
1028	  (const:DI
1029	   (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
1030		       (match_operand:DI 3 "symbolic_operand" "")]
1031		      UNSPEC_HW0_PCREL))]
1032	 UNSPEC_INSN_ADDR_SHL16INSLI))]
1033  "flag_pic")
1034
1035(define_insn "mov_large_pcrel_step4"
1036  [(set (match_operand:DI 0 "register_operand" "=r")
1037        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
1038		    (match_operand:DI 2 "reg_or_0_operand" "rO")
1039			 (match_operand:DI 3 "symbolic_operand" "in")
1040			 (match_operand:DI 4 "symbolic_operand" "in")]
1041		   UNSPEC_MOV_LARGE_PCREL_STEP4))]
1042  "flag_pic"
1043  "add\t%0, %r1, %r2")
1044
1045;; The next three patterns are used to materialize a position
1046;; independent 64-bit plt address by adding the difference of two
1047;; labels to a base label in the text segment.
1048(define_expand "mov_plt_pcrel_step1"
1049  [(set (match_operand:DI 0 "register_operand" "")
1050	(const:DI (unspec:DI
1051			[(match_operand:DI 1 "symbolic_operand" "")
1052			 (match_operand:DI 2 "symbolic_operand" "")]
1053                        UNSPEC_HW2_LAST_PLT_PCREL)))]
1054  "flag_pic")
1055
1056(define_expand "mov_plt_pcrel_step2"
1057  [(set (match_operand:DI 0 "register_operand" "")
1058	(unspec:DI
1059	 [(match_operand:DI 1 "reg_or_0_operand" "")
1060	  (const:DI
1061	   (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
1062			    (match_operand:DI 3 "symbolic_operand" "")]
1063		      UNSPEC_HW1_PLT_PCREL))]
1064	 UNSPEC_INSN_ADDR_SHL16INSLI))]
1065  "flag_pic")
1066
1067(define_expand "mov_plt_pcrel_step3"
1068  [(set (match_operand:DI 0 "register_operand" "")
1069	(unspec:DI
1070	 [(match_operand:DI 1 "reg_or_0_operand" "")
1071	  (const:DI
1072	   (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
1073			    (match_operand:DI 3 "symbolic_operand" "")]
1074		      UNSPEC_HW0_PLT_PCREL))]
1075	 UNSPEC_INSN_ADDR_SHL16INSLI))]
1076  "flag_pic")
1077
1078;; The next two patterns are used to materialize a position independent
1079;; 32-bit plt address by adding the difference of two labels to a base
1080;; label in the text segment.
1081(define_expand "mov_plt_pcrel_step1_32bit"
1082  [(set (match_operand:SI 0 "register_operand" "")
1083	(const:SI (unspec:SI
1084			[(match_operand:SI 1 "symbolic_operand" "")
1085			 (match_operand:SI 2 "symbolic_operand" "")]
1086                        UNSPEC_HW1_LAST_PLT_PCREL)))]
1087  "flag_pic")
1088
1089(define_expand "mov_plt_pcrel_step2_32bit"
1090  [(set (match_operand:SI 0 "register_operand" "")
1091	(unspec:SI
1092	 [(match_operand:SI 1 "reg_or_0_operand" "")
1093	  (const:SI
1094	   (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
1095			    (match_operand:SI 3 "symbolic_operand" "")]
1096		      UNSPEC_HW0_PLT_PCREL))]
1097	 UNSPEC_INSN_ADDR_SHL16INSLI))]
1098  "flag_pic")
1099
1100(define_expand "add_got16<bitsuffix>"
1101  [(set (match_operand:I48MODE 0 "register_operand" "")
1102        (plus:I48MODE
1103	 (match_operand:I48MODE 1 "reg_or_0_operand" "")
1104	 (const:I48MODE
1105	  (unspec:I48MODE [(match_operand:I48MODE 2 "symbolic_operand" "")]
1106			  UNSPEC_HW0_LAST_GOT))))]
1107  "flag_pic == 1")
1108
1109(define_expand "mov_got32_step1<bitsuffix>"
1110  [(set (match_operand:I48MODE 0 "register_operand" "")
1111	(const:I48MODE
1112	 (unspec:I48MODE [(match_operand:I48MODE 1 "symbolic_operand" "")]
1113			 UNSPEC_HW1_LAST_GOT)))]
1114  "flag_pic == 2")
1115
1116(define_expand "mov_got32_step2<bitsuffix>"
1117  [(set (match_operand:I48MODE 0 "register_operand" "")
1118	(unspec:I48MODE
1119	 [(match_operand:I48MODE 1 "reg_or_0_operand" "")
1120	  (const:I48MODE
1121	   (unspec:I48MODE [(match_operand:I48MODE 2 "symbolic_operand" "")]
1122			   UNSPEC_HW0_GOT))]
1123	 UNSPEC_INSN_ADDR_SHL16INSLI))]
1124  "flag_pic == 2")
1125
1126
1127;;
1128;; TLS
1129;;
1130
1131(define_expand "mov_tls_gd_step1<bitsuffix>"
1132  [(set (match_operand:I48MODE 0 "register_operand" "")
1133	(const:I48MODE
1134	 (unspec:I48MODE [(match_operand:I48MODE 1 "tls_symbolic_operand" "")]
1135			 UNSPEC_HW1_LAST_TLS_GD)))]
1136  "HAVE_AS_TLS")
1137
1138(define_expand "mov_tls_gd_step2<bitsuffix>"
1139  [(set (match_operand:I48MODE 0 "register_operand" "")
1140	(unspec:I48MODE
1141	 [(match_operand:I48MODE 1 "reg_or_0_operand" "")
1142	  (const:I48MODE
1143	   (unspec:I48MODE [(match_operand:I48MODE 2 "tls_symbolic_operand" "")]
1144			   UNSPEC_HW0_TLS_GD))]
1145	 UNSPEC_INSN_ADDR_SHL16INSLI))]
1146  "HAVE_AS_TLS")
1147
1148(define_expand "mov_tls_ie_step1<bitsuffix>"
1149  [(set (match_operand:I48MODE 0 "register_operand" "")
1150	(const:I48MODE
1151	 (unspec:I48MODE [(match_operand:I48MODE 1 "tls_symbolic_operand" "")]
1152			 UNSPEC_HW1_LAST_TLS_IE)))]
1153  "HAVE_AS_TLS")
1154
1155(define_expand "mov_tls_ie_step2<bitsuffix>"
1156  [(set (match_operand:I48MODE 0 "register_operand" "")
1157	(unspec:I48MODE
1158	 [(match_operand:I48MODE 1 "reg_or_0_operand" "")
1159	  (const:I48MODE
1160	   (unspec:I48MODE [(match_operand:I48MODE 2 "tls_symbolic_operand" "")]
1161			   UNSPEC_HW0_TLS_IE))]
1162	 UNSPEC_INSN_ADDR_SHL16INSLI))]
1163  "HAVE_AS_TLS")
1164
1165(define_expand "mov_tls_le_step1<bitsuffix>"
1166  [(set (match_operand:I48MODE 0 "register_operand" "")
1167	(const:I48MODE
1168	 (unspec:I48MODE [(match_operand:I48MODE 1 "tls_symbolic_operand" "")]
1169			 UNSPEC_HW1_LAST_TLS_LE)))]
1170  "HAVE_AS_TLS")
1171
1172(define_expand "mov_tls_le_step2<bitsuffix>"
1173  [(set (match_operand:I48MODE 0 "register_operand" "")
1174	(unspec:I48MODE
1175	 [(match_operand:I48MODE 1 "reg_or_0_operand" "")
1176	  (const:I48MODE
1177	   (unspec:I48MODE [(match_operand:I48MODE 2 "tls_symbolic_operand" "")]
1178			   UNSPEC_HW0_TLS_LE))]
1179	 UNSPEC_INSN_ADDR_SHL16INSLI))]
1180  "HAVE_AS_TLS")
1181
1182(define_expand "tls_gd_call<bitsuffix>"
1183  [(parallel
1184    [(set (reg:I48MODE 0)
1185	  (unspec:I48MODE [(match_operand:I48MODE 0 "tls_symbolic_operand" "")
1186			   (reg:I48MODE 0)]
1187			   UNSPEC_TLS_GD_CALL))
1188     (clobber (reg:I48MODE 25))
1189     (clobber (reg:I48MODE 26))
1190     (clobber (reg:I48MODE 27))
1191     (clobber (reg:I48MODE 28))
1192     (clobber (reg:I48MODE 29))
1193     (clobber (reg:I48MODE 55))])]
1194   ""
1195{
1196  cfun->machine->calls_tls_get_addr = true;
1197})
1198
1199(define_insn "*tls_gd_call<bitsuffix>"
1200  [(set (reg:I48MODE 0)
1201	(unspec:I48MODE [(match_operand:I48MODE 0 "tls_symbolic_operand" "")
1202			 (reg:I48MODE 0)]
1203			UNSPEC_TLS_GD_CALL))
1204   (clobber (reg:I48MODE 25))
1205   (clobber (reg:I48MODE 26))
1206   (clobber (reg:I48MODE 27))
1207   (clobber (reg:I48MODE 28))
1208   (clobber (reg:I48MODE 29))
1209   (clobber (reg:I48MODE 55))]
1210  ""
1211  "jal\ttls_gd_call(%0)"
1212  [(set_attr "type" "X1")])
1213
1214(define_insn "tls_gd_add<bitsuffix>"
1215  [(set (match_operand:I48MODE 0 "register_operand" "=r")
1216	(unspec:I48MODE [(match_operand:I48MODE 1 "register_operand" "r")
1217			 (match_operand:I48MODE 2 "tls_symbolic_operand" "")]
1218			UNSPEC_TLS_GD_ADD))]
1219  "HAVE_AS_TLS"
1220  "add<x>i\t%0, %1, tls_gd_add(%2)")
1221
1222(define_insn "tls_add<bitsuffix>"
1223  [(set (match_operand:I48MODE 0 "register_operand" "=r")
1224	(unspec:I48MODE [(match_operand:I48MODE 1 "register_operand" "r")
1225			 (match_operand:I48MODE 2 "register_operand" "0")
1226			 (match_operand:I48MODE 3 "tls_symbolic_operand" "")]
1227			UNSPEC_TLS_ADD))]
1228  "HAVE_AS_TLS"
1229  "add<x>i\t%0, %1, tls_add(%3)")
1230
1231(define_insn "tls_ie_load<bitsuffix>"
1232  [(set (match_operand:I48MODE 0 "register_operand" "=r")
1233	(unspec:I48MODE [(match_operand:I48MODE 1 "register_operand" "r")
1234			 (match_operand:I48MODE 2 "tls_symbolic_operand" "")]
1235			UNSPEC_TLS_IE_LOAD))]
1236  "HAVE_AS_TLS"
1237  "ld<four_s_if_si>_tls\t%0, %1, tls_ie_load(%2)"
1238  [(set_attr "type" "X1_2cycle")])
1239
1240(define_insn "*zero_extract<mode>"
1241  [(set (match_operand:I48MODE 0 "register_operand" "=r")
1242	(zero_extract:I48MODE
1243         (match_operand:I48MODE 1 "reg_or_0_operand" "r")
1244         (match_operand:I48MODE 2 "u6bit_cint_operand" "n")
1245         (match_operand:I48MODE 3 "u6bit_cint_operand" "n")))]
1246  ""
1247  "bfextu\t%0, %r1, %3, %3+%2-1"
1248  [(set_attr "type" "X0")])
1249
1250(define_insn "*sign_extract_low32"
1251  [(set (match_operand:DI 0 "register_operand" "=r")
1252	(sign_extract:DI
1253         (match_operand:DI 1 "reg_or_0_operand" "r")
1254         (match_operand:DI 2 "u6bit_cint_operand" "n")
1255         (match_operand:DI 3 "u6bit_cint_operand" "n")))]
1256  "INTVAL (operands[3]) == 0 && INTVAL (operands[2]) == 32"
1257  "addxi\t%0, %r1, 0")
1258
1259(define_insn "*sign_extract"
1260  [(set (match_operand:I48MODE 0 "register_operand" "=r")
1261	(sign_extract:I48MODE
1262         (match_operand:I48MODE 1 "reg_or_0_operand" "r")
1263         (match_operand:I48MODE 2 "u6bit_cint_operand" "n")
1264         (match_operand:I48MODE 3 "u6bit_cint_operand" "n")))]
1265  ""
1266  "bfexts\t%0, %r1, %3, %3+%2-1"
1267  [(set_attr "type" "X0")])
1268
1269
1270;;
1271;; Arithmetic ops
1272;;
1273
1274(define_insn "add<mode>3"
1275  [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1276	(plus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rO,rO,rO")
1277		      (match_operand:I48MODE 2 "add_operand" "r,I,JT")))]
1278  ""
1279  "@
1280   add<x>\t%0, %r1, %r2
1281   add<x>i\t%0, %r1, %2
1282   add<x>li\t%0, %r1, %H2"
1283  [(set_attr "type" "*,*,X01")])
1284
1285(define_insn "*addsi3_sext"
1286  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1287	(sign_extend:DI
1288	 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO")
1289		  (match_operand:SI 2 "add_operand" "r,I,JT"))))]
1290  ""
1291  "@
1292   addx\t%0, %r1, %r2
1293   addxi\t%0, %r1, %2
1294   addxli\t%0, %r1, %H2"
1295  [(set_attr "type" "*,*,X01")])
1296
1297(define_insn "sub<mode>3"
1298  [(set (match_operand:I48MODE 0 "register_operand" "=r")
1299	(minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
1300                       (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
1301  ""
1302  "sub<x>\t%0, %r1, %r2")
1303
1304(define_insn "*subsi3_sext"
1305  [(set (match_operand:DI 0 "register_operand" "=r")
1306	(sign_extend:DI
1307	 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1308		   (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
1309  ""
1310  "subx\t%0, %r1, %r2")
1311
1312(define_insn "neg<mode>2"
1313  [(set (match_operand:I48MODE 0 "register_operand" "=r")
1314	(neg:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO")))]
1315  ""
1316  "sub<x>\t%0, zero, %r1")
1317
1318(define_insn "*negsi2_sext"
1319  [(set (match_operand:DI 0 "register_operand" "=r")
1320	(sign_extend:DI
1321	 (neg:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))))]
1322  ""
1323  "subx\t%0, zero, %r1")
1324
1325(define_insn "ssaddsi3"
1326  [(set (match_operand:SI 0 "register_operand" "=r")
1327	(ss_plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1328                    (match_operand:SI 2 "reg_or_0_operand" "rO")))]
1329  ""
1330  "addxsc\t%0, %r1, %r2"
1331  [(set_attr "type" "X01")])
1332
1333(define_insn "*ssaddsi3_sext"
1334  [(set (match_operand:DI 0 "register_operand" "=r")
1335	(sign_extend:DI
1336	 (ss_plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1337		     (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
1338  ""
1339  "addxsc\t%0, %r1, %r2"
1340  [(set_attr "type" "X01")])
1341
1342(define_insn "sssubsi3"
1343  [(set (match_operand:SI 0 "register_operand" "=r")
1344	(ss_minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1345                     (match_operand:SI 2 "reg_or_0_operand" "rO")))]
1346  ""
1347  "subxsc\t%0, %r1, %r2"
1348  [(set_attr "type" "X01")])
1349
1350(define_insn "*sssubsi3_sext"
1351  [(set (match_operand:DI 0 "register_operand" "=r")
1352	(sign_extend:DI
1353	 (ss_minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1354		      (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
1355  ""
1356  "subxsc\t%0, %r1, %r2"
1357  [(set_attr "type" "X01")])
1358
1359(define_expand "addsf3"
1360  [(set (match_operand:SF 0 "register_operand" "")
1361        (plus:SF (match_operand:SF 1 "register_operand" "")
1362                 (match_operand:SF 2 "register_operand" "")))]
1363  ""
1364{
1365  rtx result = gen_lowpart (DImode, operands[0]);
1366  rtx a = gen_lowpart (DImode, operands[1]);
1367  rtx b = gen_lowpart (DImode, operands[2]);
1368
1369  rtx tmp = gen_reg_rtx (DImode);
1370  rtx flags = gen_reg_rtx (DImode);
1371
1372  emit_insn (gen_insn_fsingle_add1 (tmp, a, b));
1373  emit_insn (gen_insn_fsingle_addsub2 (tmp, tmp, a, b));
1374  emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
1375  emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
1376
1377  DONE;
1378})
1379
1380(define_expand "subsf3"
1381  [(set (match_operand:SF 0 "register_operand" "")
1382        (minus:SF (match_operand:SF 1 "register_operand" "")
1383                  (match_operand:SF 2 "register_operand" "")))]
1384  ""
1385{
1386  rtx result = gen_lowpart (DImode, operands[0]);
1387  rtx a = gen_lowpart (DImode, operands[1]);
1388  rtx b = gen_lowpart (DImode, operands[2]);
1389
1390  rtx tmp = gen_reg_rtx (DImode);
1391  rtx flags = gen_reg_rtx (DImode);
1392
1393  emit_insn (gen_insn_fsingle_sub1 (tmp, a, b));
1394  emit_insn (gen_insn_fsingle_addsub2 (tmp, tmp, a, b));
1395  emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
1396  emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
1397
1398  DONE;
1399})
1400
1401(define_expand "mulsf3"
1402  [(set (match_operand:SF 0 "register_operand" "")
1403        (mult:SF (match_operand:SF 1 "register_operand" "")
1404                 (match_operand:SF 2 "register_operand" "")))]
1405  ""
1406{
1407  rtx result = gen_lowpart (DImode, operands[0]);
1408  rtx a = gen_lowpart (DImode, operands[1]);
1409  rtx b = gen_lowpart (DImode, operands[2]);
1410
1411  rtx tmp1 = gen_reg_rtx (DImode);
1412  rtx tmp2 = gen_reg_rtx (DImode);
1413  rtx flags = gen_reg_rtx (DImode);
1414
1415  emit_insn (gen_insn_fsingle_mul1 (tmp1, a, b));
1416  emit_insn (gen_insn_fsingle_mul2 (tmp2, tmp1, b));
1417  emit_insn (gen_insn_fsingle_pack1 (flags, tmp2));
1418  emit_insn (gen_insn_fsingle_pack2 (result, tmp2, flags));
1419
1420  DONE;
1421})
1422
1423(define_expand "adddf3"
1424  [(set (match_operand:DF 0 "register_operand" "")
1425        (plus:DF (match_operand:DF 1 "register_operand" "")
1426                 (match_operand:DF 2 "register_operand" "")))]
1427  ""
1428{
1429  rtx result = gen_lowpart (DImode, operands[0]);
1430  rtx a = gen_lowpart (DImode, operands[1]);
1431  rtx b = gen_lowpart (DImode, operands[2]);
1432
1433  rtx min = gen_reg_rtx (DImode);
1434  rtx max = gen_reg_rtx (DImode);
1435  rtx flags = gen_reg_rtx (DImode);
1436
1437  emit_insn (gen_insn_fdouble_unpack_min (min, a, b));
1438  emit_insn (gen_insn_fdouble_unpack_max (max, a, b));
1439  emit_insn (gen_insn_fdouble_add_flags (flags, a, b));
1440  emit_insn (gen_insn_fdouble_addsub (max, max, min, flags));
1441  emit_insn (gen_insn_fdouble_pack1 (result, max, flags));
1442  emit_insn (gen_insn_fdouble_pack2 (result, result, max, const0_rtx));
1443
1444  DONE;
1445})
1446
1447(define_expand "subdf3"
1448  [(set (match_operand:DF 0 "register_operand" "")
1449        (minus:DF (match_operand:DF 1 "register_operand" "")
1450                  (match_operand:DF 2 "register_operand" "")))]
1451  ""
1452{
1453  rtx result = gen_lowpart (DImode, operands[0]);
1454  rtx a = gen_lowpart (DImode, operands[1]);
1455  rtx b = gen_lowpart (DImode, operands[2]);
1456
1457  rtx min = gen_reg_rtx (DImode);
1458  rtx max = gen_reg_rtx (DImode);
1459  rtx flags = gen_reg_rtx (DImode);
1460
1461  emit_insn (gen_insn_fdouble_unpack_min (min, a, b));
1462  emit_insn (gen_insn_fdouble_unpack_max (max, a, b));
1463  emit_insn (gen_insn_fdouble_sub_flags (flags, a, b));
1464  emit_insn (gen_insn_fdouble_addsub (max, max, min, flags));
1465  emit_insn (gen_insn_fdouble_pack1 (result, max, flags));
1466  emit_insn (gen_insn_fdouble_pack2 (result, result, max, const0_rtx));
1467
1468  DONE;
1469})
1470
1471(define_expand "muldf3"
1472  [(set (match_operand:DF 0 "register_operand" "")
1473        (mult:DF (match_operand:DF 1 "register_operand" "")
1474                 (match_operand:DF 2 "register_operand" "")))]
1475  ""
1476  ;; TODO: Decide if we should not inline this with -Os.
1477  ;; "optimize_function_for_speed_p (cfun)"
1478{
1479  rtx result = gen_lowpart (DImode, operands[0]);
1480  rtx a = gen_lowpart (DImode, operands[1]);
1481  rtx b = gen_lowpart (DImode, operands[2]);
1482
1483  rtx a_unpacked = gen_reg_rtx (DImode);
1484  rtx b_unpacked = gen_reg_rtx (DImode);
1485  rtx flags = gen_reg_rtx (DImode);
1486
1487  rtx low1 = gen_reg_rtx (DImode);
1488  rtx low = gen_reg_rtx (DImode);
1489  rtx low_carry = gen_reg_rtx (DImode);
1490
1491  rtx mid = gen_reg_rtx (DImode);
1492  rtx mid_l32 = gen_reg_rtx (DImode);
1493  rtx mid_r32 = gen_reg_rtx (DImode);
1494
1495  rtx high1 = gen_reg_rtx (DImode);
1496  rtx high = gen_reg_rtx (DImode);
1497  rtx high1_plus_mid_r32 = gen_reg_rtx (DImode);
1498
1499  /* NOTE: We compute using max(a, 0) and max(b, 0) rather than
1500     min(a, b) and max(a, b) because for multiply we just need to unpack,
1501     we don't actually care which is min and which is max. And this
1502     formulation gives the scheduler more freedom in case one of a or b
1503     would stall at the start of this code sequence. */
1504  emit_insn (gen_insn_fdouble_unpack_max (a_unpacked, a, const0_rtx));
1505  emit_insn (gen_insn_fdouble_unpack_max (b_unpacked, b, const0_rtx));
1506  emit_insn (gen_insn_fdouble_mul_flags (flags, a, b));
1507
1508  /* This depends on the fact that the high few bits of the unpacked
1509     mantissa are zero, so we can't have a carry out from the mid sum. */
1510  emit_insn (gen_insn_mul_lu_lu (low1, a_unpacked, b_unpacked));
1511  emit_insn (gen_insn_mul_hu_lu (mid, a_unpacked, b_unpacked));
1512  emit_insn (gen_insn_mula_hu_lu (mid, mid, b_unpacked, a_unpacked));
1513  emit_insn (gen_insn_mul_hu_hu (high1, a_unpacked, b_unpacked));
1514
1515  emit_insn (gen_ashldi3 (mid_l32, mid, GEN_INT (32)));
1516  emit_insn (gen_lshrdi3 (mid_r32, mid, GEN_INT (32)));
1517
1518  emit_insn (gen_adddi3 (high1_plus_mid_r32, high1, mid_r32));
1519
1520  emit_insn (gen_adddi3 (low, low1, mid_l32));
1521  emit_insn (gen_insn_cmpltu_didi (low_carry, low, mid_l32));
1522
1523  emit_insn (gen_adddi3 (high, high1_plus_mid_r32, low_carry));
1524
1525  emit_insn (gen_insn_fdouble_pack1 (result, high, flags));
1526  emit_insn (gen_insn_fdouble_pack2 (result, result, high, low));
1527
1528  DONE;
1529})
1530
1531
1532;;
1533;; Shifts
1534;;
1535
1536(define_insn "ashl<mode>3"
1537  [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
1538	(ashift:I48MODE
1539	 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1540	 (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
1541  ""
1542  "@
1543  shl<x>i\t%0, %r1, %2
1544  shl<x>\t%0, %r1, %r2"
1545  [(set_attr "type" "<shift_pipe>,<shift_pipe>")])
1546
1547(define_insn "*ashlsi3_sext"
1548  [(set (match_operand:DI 0 "register_operand" "=r,r")
1549	(sign_extend:DI
1550	 (ashift:SI
1551	  (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1552	  (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
1553  ""
1554  "@
1555  shlxi\t%0, %r1, %2
1556  shlx\t%0, %r1, %r2"
1557  [(set_attr "type" "X01,X01")])
1558
1559(define_insn "ashr<mode>3"
1560  [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
1561	(ashiftrt:I48MODE
1562	 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1563	 (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
1564  ""
1565  "@
1566  shrsi\t%0, %r1, %2
1567  shrs\t%0, %r1, %r2")
1568
1569(define_insn "*ashrsi3_sext"
1570  [(set (match_operand:DI 0 "register_operand" "=r,r")
1571	(sign_extend:DI
1572	 (ashiftrt:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1573		      (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
1574  ""
1575  "@
1576  shrsi\t%0, %r1, %2
1577  shrs\t%0, %r1, %r2")
1578
1579(define_insn "lshr<mode>3"
1580  [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
1581	(lshiftrt:I48MODE
1582	 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1583	 (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
1584  ""
1585  "@
1586  shru<x>i\t%0, %r1, %2
1587  shru<x>\t%0, %r1, %r2"
1588  [(set_attr "type" "<shift_pipe>,<shift_pipe>")])
1589
1590(define_insn "*lshrsi3_sext"
1591  [(set (match_operand:DI 0 "register_operand" "=r,r")
1592	(sign_extend:DI
1593	 (lshiftrt:SI
1594	  (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1595	  (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
1596  ""
1597  "@
1598  shruxi\t%0, %r1, %2
1599  shrux\t%0, %r1, %r2"
1600  [(set_attr "type" "X01,X01")])
1601
1602(define_insn "rotldi3"
1603  [(set (match_operand:DI 0 "register_operand" "=r,r")
1604	(rotate:DI (match_operand:DI 1 "reg_or_0_operand" "rO,rO")
1605                   (match_operand:SI 2 "reg_or_u6bit_operand" "I,rO")))]
1606  ""
1607  "@
1608  rotli\t%0, %r1, %2
1609  rotl\t%0, %r1, %r2")
1610
1611(define_insn "insn_shl16insli"
1612  [(set (match_operand:DI 0 "register_operand" "=r,r")
1613        (ior:DI
1614         (ashift:DI
1615	  (match_operand:DI 1 "reg_or_0_operand" "rO,rO")
1616	  (const_int 16))
1617         (match_operand:DI 2 "u16bit_or_const_symbolic_operand" "O,KT")))]
1618  ""
1619  "@
1620   shli\t%0, %r1, 16
1621   shl16insli\t%0, %r1, %H2"
1622  [(set_attr "type" "*,X01")])
1623
1624(define_insn "insn_addr_shl16insli<bitsuffix>"
1625  [(set (match_operand:I48MODE 0 "register_operand" "=r")
1626	(unspec:I48MODE
1627	 [(match_operand:I48MODE 1 "reg_or_0_operand" "rO")
1628	  (match_operand:I48MODE 2 "const_symbolic_operand" "T")]
1629	 UNSPEC_INSN_ADDR_SHL16INSLI))]
1630  ""
1631  "shl16insli\t%0, %r1, %H2"
1632  [(set_attr "type" "X01")])
1633
1634
1635;;
1636;; Compares
1637;;
1638
1639(define_expand "cstore<mode>4"
1640  [(set (match_operand:DI 0 "register_operand" "")
1641      (match_operator:DI 1 "ordered_comparison_operator"
1642         [(match_operand:FI48MODE 2 "reg_or_cint_operand" "")
1643          (match_operand:FI48MODE 3 "reg_or_cint_operand" "")]))]
1644  ""
1645{
1646  if (!tilegx_emit_setcc (operands, GET_MODE (operands[2])))
1647    FAIL;
1648  else
1649    DONE;
1650})
1651
1652
1653(define_insn "insn_cmpne_<I48MODE:mode><I48MODE2:mode>"
1654  [(set (match_operand:I48MODE2 0 "register_operand" "=r")
1655	(ne:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
1656		     (match_operand:I48MODE 2 "reg_or_cint_operand" "rO")))]
1657  ""
1658  "cmpne\t%0, %r1, %r2")
1659
1660(define_insn "insn_cmpeq_<I48MODE:mode><I48MODE2:mode>"
1661  [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1662	(eq:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "%rO,rO")
1663		     (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
1664  ""
1665  "@
1666   cmpeqi\t%0, %r1, %2
1667   cmpeq\t%0, %r1, %r2")
1668
1669(define_insn "insn_cmplts_<I48MODE:mode><I48MODE2:mode>"
1670  [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1671	(lt:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1672		     (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
1673  ""
1674  "@
1675   cmpltsi\t%0, %r1, %2
1676   cmplts\t%0, %r1, %r2")
1677
1678(define_insn "insn_cmpltu_<I48MODE:mode><I48MODE2:mode>"
1679  [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1680	(ltu:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1681		      (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
1682  ""
1683  "@
1684   cmpltui\t%0, %r1, %2
1685   cmpltu\t%0, %r1, %r2"
1686  [(set_attr "type" "X01,*")])
1687
1688(define_insn "insn_cmples_<I48MODE:mode><I48MODE2:mode>"
1689  [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1690	(le:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1691		     (match_operand:I48MODE 2 "reg_or_cint_operand" "L,rO")))]
1692  ""
1693  "@
1694   cmpltsi\t%0, %r1, %P2
1695   cmples\t%0, %r1, %r2")
1696
1697(define_insn "insn_cmpleu_<I48MODE:mode><I48MODE2:mode>"
1698  [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1699	(leu:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1700		      (match_operand:I48MODE 2 "reg_or_cint_operand" "Q,rO")))]
1701  ""
1702  "@
1703   cmpltui\t%0, %r1, %P2
1704   cmpleu\t%0, %r1, %r2"
1705  [(set_attr "type" "X01,*")])
1706
1707
1708;;
1709;; Logical ops
1710;;
1711
1712(define_insn "and<mode>3"
1713  [(set (match_operand:IVNMODE 0 "register_operand" "=r,r,r,r")
1714	(and:IVNMODE (match_operand:IVNMODE 1 "reg_or_0_operand" "%rO,rO,0,rO")
1715		     (match_operand:IVNMODE 2 "and_operand" "I,S,M,rO")))]
1716  ""
1717  "@
1718   andi\t%0, %r1, %2
1719   bfextu\t%0, %r1, %M2
1720   bfins\t%0, zero, %m2
1721   and\t%0, %r1, %r2"
1722  [(set_attr "type" "*,X0,X0,*")])
1723
1724(define_insn "*andsi3_sext"
1725  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
1726	(sign_extend:DI
1727	 (and:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,0,rO")
1728		 (match_operand:SI 2 "and_operand" "I,S,M,rO"))))]
1729  ""
1730  "@
1731   andi\t%0, %r1, %2
1732   bfextu\t%0, %r1, %M2
1733   bfins\t%0, zero, %m2
1734   and\t%0, %r1, %r2"
1735  [(set_attr "type" "*,X0,X0,*")])
1736
1737(define_insn "anddi3"
1738  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
1739	(and:DI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO,rO,0,rO")
1740                    (match_operand:DI 2 "and_operand" "I,Z0,Z1,S,M,rO")))]
1741  ""
1742  "@
1743   andi\t%0, %r1, %2
1744   v4int_l\t%0, zero, %r1
1745   v4int_h\t%0, %r1, zero
1746   bfextu\t%0, %r1, %M2
1747   bfins\t%0, zero, %m2
1748   and\t%0, %r1, %r2"
1749  [(set_attr "type" "*,X01,X01,X0,X0,*")])
1750
1751(define_insn "ior<mode>3"
1752  [(set (match_operand:IVMODE 0 "register_operand" "=r,r")
1753	(ior:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "%rO,rO")
1754                    (match_operand:IVMODE 2 "reg_or_s8bit_operand" "rO,I")))]
1755  ""
1756  "@
1757   or\t%0, %r1, %r2
1758   ori\t%0, %r1, %2"
1759  [(set_attr "type" "*,X01")])
1760
1761(define_insn "*iorsi3_sext"
1762  [(set (match_operand:DI 0 "register_operand" "=r,r")
1763	(sign_extend:DI
1764	 (ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
1765		 (match_operand:SI 2 "reg_or_s8bit_operand" "rO,I"))))]
1766  ""
1767  "@
1768   or\t%0, %r1, %r2
1769   ori\t%0, %r1, %2"
1770  [(set_attr "type" "*,X01")])
1771
1772(define_insn "xor<mode>3"
1773  [(set (match_operand:IVMODE 0 "register_operand" "=r,r")
1774	(xor:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "%rO,rO")
1775                    (match_operand:IVMODE 2 "reg_or_s8bit_operand" "rO,I")))]
1776  ""
1777  "@
1778   xor\t%0, %r1, %r2
1779   xori\t%0, %r1, %2"
1780  [(set_attr "type" "*,X01")])
1781
1782(define_insn "*xorsi3_sext"
1783  [(set (match_operand:DI 0 "register_operand" "=r,r")
1784	(sign_extend:DI
1785	 (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
1786		 (match_operand:SI 2 "reg_or_s8bit_operand" "rO,I"))))]
1787  ""
1788  "@
1789   xor\t%0, %r1, %r2
1790   xori\t%0, %r1, %2"
1791  [(set_attr "type" "*,X01")])
1792
1793(define_insn "clzdi2"
1794  [(set (match_operand:DI 0 "register_operand" "=r")
1795	(clz:DI (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1796  ""
1797  "clz\t%0, %r1"
1798  [(set_attr "type" "Y0")])
1799
1800(define_expand "clzsi2"
1801  [(set (match_dup 2)
1802        (ashift:DI (match_operand:SI 1 "reg_or_0_operand" "")
1803                   (const_int 32)))
1804   (set (subreg:DI (match_operand:SI 0 "register_operand" "") 0)
1805	(clz:DI (match_dup 2)))]
1806   ""
1807   {
1808     operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);
1809     operands[2] = gen_reg_rtx (DImode);
1810   })
1811
1812(define_insn "ctz<mode>2"
1813  [(set (match_operand:I48MODE 0 "register_operand" "=r")
1814	(ctz:I48MODE (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1815  ""
1816  "ctz\t%0, %r1"
1817  [(set_attr "type" "Y0")])
1818
1819(define_insn "popcount<mode>2"
1820  [(set (match_operand:I48MODE 0 "register_operand" "=r")
1821	(popcount:I48MODE (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1822  ""
1823  "pcnt\t%0, %r1"
1824  [(set_attr "type" "Y0")])
1825
1826(define_expand "parity<mode>2"
1827  [(set (match_operand:I48MODE 0 "register_operand" "")
1828	(parity:I48MODE (match_operand:DI 1 "reg_or_0_operand" "")))]
1829  ""
1830  {
1831    rtx tmp = gen_reg_rtx (<MODE>mode);
1832    emit_insn (gen_popcount<mode>2 (tmp, operands[1]));
1833    emit_insn (gen_and<mode>3 (operands[0], tmp, const1_rtx));
1834    DONE;
1835  })
1836
1837(define_insn "bswapdi2"
1838  [(set (match_operand:DI 0 "register_operand" "=r")
1839	(bswap:DI (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1840  ""
1841  "revbytes\t%0, %r1"
1842  [(set_attr "type" "Y0")])
1843
1844(define_expand "bswapsi2"
1845  [(set (match_operand:SI 0 "register_operand" "")
1846	(bswap:SI (match_operand:SI 1 "reg_or_0_operand" "")))]
1847  ""
1848  {
1849    rtx tmp = gen_reg_rtx (DImode);
1850    emit_insn (gen_bswapdi2 (tmp, gen_lowpart (DImode, operands[1])));
1851    emit_insn (gen_ashrdi3 (gen_lowpart (DImode, operands[0]),
1852			    tmp, GEN_INT (32)));
1853    DONE;
1854  })
1855
1856(define_insn "one_cmpl<mode>2"
1857  [(set (match_operand:IVMODE 0 "register_operand" "=r")
1858	(not:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "rO")))]
1859  ""
1860  "nor\t%0, %r1, zero")
1861
1862
1863;;
1864;; Conditional moves
1865;;
1866
1867(define_expand "mov<mode>cc"
1868  [(set (match_operand:I48MODE 0 "register_operand" "")
1869	(if_then_else:I48MODE
1870         (match_operand 1 "comparison_operator" "")
1871         (match_operand:I48MODE 2 "reg_or_0_operand" "")
1872         (match_operand:I48MODE 3 "reg_or_0_operand" "")))]
1873  ""
1874  { operands[1] = tilegx_emit_conditional_move (operands[1]); })
1875
1876(define_insn "movcc_insn_<I48MODE2:mode><I48MODE:mode>"
1877  [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r,r")
1878	(if_then_else:I48MODE
1879	 (match_operator 4 "eqne_operator"
1880	  [(match_operand:I48MODE2 1 "reg_or_0_operand" "rO,rO,rO,rO")
1881	   (const_int 0)])
1882	 (match_operand:I48MODE 2 "reg_or_0_operand"	"rO,O,rO,0")
1883	 (match_operand:I48MODE 3 "reg_or_0_operand"	"O,rO,0,rO")))]
1884  ""
1885  "@
1886   m%c4\t%0, %r1, %r2
1887   m%C4\t%0, %r1, %r3
1888   cmov%d4z\t%0, %r1, %r2
1889   cmov%D4z\t%0, %r1, %r3"
1890  [(set_attr "type" "*,*,Y0,Y0")])
1891
1892(define_expand "insn_mz"
1893  [(set (match_operand:DI 0 "register_operand" "")
1894	(if_then_else:DI
1895         (eq (match_operand:DI 1 "reg_or_0_operand" "")
1896             (const_int 0))
1897         (match_operand:DI 2 "reg_or_0_operand" "")
1898         (const_int 0)))])
1899
1900(define_expand "insn_mnz"
1901  [(set (match_operand:DI 0 "register_operand" "")
1902	(if_then_else:DI
1903         (ne (match_operand:DI 1 "reg_or_0_operand" "")
1904             (const_int 0))
1905         (match_operand:DI 2 "reg_or_0_operand" "")
1906         (const_int 0)))])
1907
1908(define_expand "insn_cmoveqz"
1909  [(set (match_operand:DI 0 "register_operand" "")
1910	(if_then_else:DI
1911         (eq (match_operand:DI 2 "reg_or_0_operand" "")
1912             (const_int 0))
1913         (match_operand:DI 3 "reg_or_0_operand" "")
1914         (match_operand:DI 1 "reg_or_0_operand" "")))])
1915
1916(define_expand "insn_cmovnez"
1917  [(set (match_operand:DI 0 "register_operand" "")
1918	(if_then_else:DI
1919         (ne (match_operand:DI 2 "reg_or_0_operand" "")
1920             (const_int 0))
1921         (match_operand:DI 3 "reg_or_0_operand" "")
1922         (match_operand:DI 1 "reg_or_0_operand" "")))])
1923
1924
1925;;
1926;; Conversions
1927;;
1928
1929(define_insn "zero_extendqi<mode>2"
1930  [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1931	(zero_extend:I48MODE (match_operand:QI 1 "move_operand" "rO,U,m")))]
1932  ""
1933  "@
1934   bfextu\t%0, %r1, 0, 7
1935   ld1u\t%0, %1
1936   ld1u_add\t%0, %I1, %i1"
1937  [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1938
1939(define_insn "zero_extendhi<mode>2"
1940  [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1941	(zero_extend:I48MODE (match_operand:HI 1 "move_operand" "rO,U,m")))]
1942  ""
1943  "@
1944   bfextu\t%0, %r1, 0, 15
1945   ld2u\t%0, %1
1946   ld2u_add\t%0, %I1, %i1"
1947  [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1948
1949(define_insn "zero_extendsidi2"
1950  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1951	(zero_extend:DI (match_operand:SI 1 "move_operand" "rO,U,m")))]
1952  ""
1953  "@
1954   v4int_l\t%0, zero, %r1
1955   ld4u\t%0, %1
1956   ld4u_add\t%0, %I1, %i1"
1957  [(set_attr "type" "X01,Y2_2cycle,X1_2cycle")])
1958
1959(define_insn "extendqi<mode>2"
1960  [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1961	(sign_extend:I48MODE (match_operand:QI 1 "move_operand" "rO,U,m")))]
1962  ""
1963  "@
1964   bfexts\t%0, %r1, 0, 7
1965   ld1s\t%0, %1
1966   ld1s_add\t%0, %I1, %i1"
1967  [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1968
1969(define_insn "extendhi<mode>2"
1970  [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1971	(sign_extend:I48MODE (match_operand:HI 1 "move_operand" "rO,U,m")))]
1972  ""
1973  "@
1974   bfexts\t%0, %r1, 0, 15
1975   ld2s\t%0, %1
1976   ld2s_add\t%0, %I1, %i1"
1977  [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1978
1979;; All SImode integer registers should already be in sign-extended
1980;; form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can therefore
1981;; get rid of register->register instructions if we constrain the
1982;; source to be in the same register as the destination.
1983(define_insn_and_split "extendsidi2"
1984  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1985        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,U,m")))]
1986  ""
1987  "@
1988   #
1989   ld4s\t%0, %1
1990   ld4s_add\t%0, %I1, %i1"
1991  "&& reload_completed && register_operand (operands[1], VOIDmode)"
1992  [(const_int 0)]
1993{
1994  emit_note (NOTE_INSN_DELETED);
1995  DONE;
1996}
1997  [(set_attr "type" "*,Y2_2cycle,X1_2cycle")])
1998
1999;; Integer truncation patterns.  Truncating SImode values to smaller
2000;; modes is a no-op, as it is for most other GCC ports.  Truncating
2001;; DImode values to SImode is not a no-op since we
2002;; need to make sure that the lower 32 bits are properly sign-extended
2003;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2004;; smaller than SImode is equivalent to two separate truncations:
2005;;
2006;;                        A       B
2007;;    DI ---> HI  ==  DI ---> SI ---> HI
2008;;    DI ---> QI  ==  DI ---> SI ---> QI
2009;;
2010;; Step A needs a real instruction but step B does not.
2011
2012(define_insn "truncdisi2"
2013  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,U,m")
2014        (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
2015  ""
2016  "@
2017   addxi\t%0, %r1, 0
2018   st4\t%0, %r1
2019   st4_add\t%I0, %r1, %i0"
2020  [(set_attr "type" "Y01,Y2,X1")])
2021
2022(define_insn "truncdihi2"
2023  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,U,m")
2024        (truncate:HI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
2025  ""
2026  "@
2027   addxi\t%0, %r1, 0
2028   st2\t%0, %r1
2029   st2_add\t%I0, %r1, %i0"
2030  [(set_attr "type" "Y01,Y2,X1")])
2031
2032(define_insn "truncdiqi2"
2033  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,U,m")
2034        (truncate:QI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
2035  ""
2036  "@
2037   addxi\t%0, %r1, 0
2038   st1\t%0, %r1
2039   st1_add\t%I0, %r1, %i0"
2040  [(set_attr "type" "Y01,Y2,X1")])
2041
2042;; Combiner patterns to optimize away unnecessary truncates.
2043
2044(define_insn "*zero_extendsidi_truncdisi"
2045  [(set (match_operand:DI 0 "register_operand" "=r")
2046	(zero_extend:DI
2047	 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))))]
2048  ""
2049  "v4int_l\t%0, zero, %r1"
2050  [(set_attr "type" "X01")])
2051
2052(define_insn "*addsi_truncdisi"
2053  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2054	(plus:SI
2055	 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO"))
2056	 (match_operand:SI 2 "add_operand" "r,I,JT")))]
2057  ""
2058  "@
2059   addx\t%0, %r1, %r2
2060   addxi\t%0, %r1, %2
2061   addxli\t%0, %r1, %H2"
2062  [(set_attr "type" "*,*,X01")])
2063
2064(define_insn "*addsi_truncdisi2"
2065  [(set (match_operand:SI 0 "register_operand" "=r")
2066	(plus:SI
2067	 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))
2068	 (truncate:SI (match_operand:DI 2 "reg_or_0_operand" "rO"))))]
2069  ""
2070  "addx\t%0, %r1, %r2")
2071
2072(define_insn "*ashldi_truncdisi"
2073  [(set (match_operand:DI 0 "register_operand" "=r")
2074	(ashift:DI
2075	 (match_operand:DI 1 "reg_or_0_operand" "rO")
2076	 (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
2077  ""
2078  "shl\t%0, %r1, %r2")
2079
2080(define_insn "*ashlsi_truncdisi"
2081  [(set (match_operand:SI 0 "register_operand" "=r,r")
2082	(ashift:SI
2083	 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO,rO"))
2084	 (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
2085  ""
2086  "@
2087  shlxi\t%0, %r1, %2
2088  shlx\t%0, %r1, %r2"
2089  [(set_attr "type" "X01,X01")])
2090
2091(define_insn "*ashlsi_truncdisi2"
2092  [(set (match_operand:SI 0 "register_operand" "=r")
2093	(ashift:SI
2094	 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))
2095	 (truncate:SI (match_operand:DI 2 "reg_or_0_operand" "rO"))))]
2096  ""
2097  "shlx\t%0, %r1, %r2"
2098  [(set_attr "type" "X01")])
2099
2100(define_insn "*ashrdi3_truncdisi"
2101  [(set (match_operand:DI 0 "register_operand" "=r")
2102	(ashiftrt:DI
2103	 (match_operand:DI 1 "reg_or_0_operand" "rO")
2104	 (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
2105  ""
2106  "shrs\t%0, %r1, %r2")
2107
2108(define_insn "*lshrsi_truncdisi"
2109  [(set (match_operand:SI 0 "register_operand" "=r,r")
2110	(lshiftrt:SI
2111	 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO,rO"))
2112	 (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
2113  ""
2114  "@
2115  shruxi\t%0, %r1, %2
2116  shrux\t%0, %r1, %r2"
2117  [(set_attr "type" "X01,X01")])
2118
2119(define_insn "*lshrsi_truncdisi2"
2120  [(set (match_operand:SI 0 "register_operand" "=r")
2121	(lshiftrt:SI
2122	 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))
2123	 (truncate:SI (match_operand:DI 2 "reg_or_0_operand" "rO"))))]
2124  ""
2125  "shrux\t%0, %r1, %r2"
2126  [(set_attr "type" "X01")])
2127
2128(define_insn "*lshrdi_truncdisi"
2129  [(set (match_operand:DI 0 "register_operand" "=r")
2130	(lshiftrt:DI
2131	 (match_operand:DI 1 "reg_or_0_operand" "rO")
2132	 (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
2133  ""
2134  "shru\t%0, %r1, %r2")
2135
2136(define_insn "*rotldi_truncdisi"
2137  [(set (match_operand:DI 0 "register_operand" "=r")
2138	(rotate:DI
2139	 (match_operand:DI 1 "reg_or_0_operand" "rO")
2140	 (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
2141  ""
2142  "rotl\t%0, %r1, %r2")
2143
2144;; Integer to floating point conversions
2145
2146(define_expand "floatsisf2"
2147  [(set (match_operand:SF 0 "register_operand" "")
2148	(float:SI (match_operand:SI 1 "register_operand" "")))]
2149  ""
2150{
2151  rtx result = gen_lowpart (DImode, operands[0]);
2152  rtx a = operands[1];
2153
2154  rtx nega = gen_reg_rtx (SImode);
2155  rtx exp = gen_reg_rtx (DImode);
2156  rtx sign = gen_reg_rtx (DImode);
2157  rtx abs = gen_reg_rtx (DImode);
2158  rtx flags = gen_reg_rtx (DImode);
2159  rtx tmp1 = gen_reg_rtx (DImode);
2160  rtx tmp2 = gen_reg_rtx (DImode);
2161
2162  emit_move_insn (exp, GEN_INT (0x9e));
2163
2164  emit_insn (gen_negsi2 (nega, a));
2165
2166  emit_insn (gen_insn_cmplts_sisi (gen_lowpart (SImode, sign), a, const0_rtx));
2167  emit_insn (gen_insn_cmoveqz (abs, gen_lowpart (DImode, nega), sign,
2168			       gen_lowpart (DImode, a)));
2169
2170  emit_insn (gen_insn_bfins (tmp1, exp, sign, GEN_INT (10), GEN_INT (10)));
2171  emit_insn (gen_insn_bfins (tmp2, tmp1, abs, GEN_INT (32), GEN_INT (63)));
2172  emit_insn (gen_insn_fsingle_pack1 (flags, tmp2));
2173  emit_insn (gen_insn_fsingle_pack2 (result, tmp2, flags));
2174  DONE;
2175})
2176
2177(define_expand "floatunssisf2"
2178  [(set (match_operand:SF 0 "register_operand" "")
2179	(float:SI (match_operand:SI 1 "register_operand" "")))]
2180  ""
2181{
2182  rtx result = gen_lowpart (DImode, operands[0]);
2183  rtx a = operands[1];
2184
2185  rtx exp = gen_reg_rtx (DImode);
2186  rtx flags = gen_reg_rtx (DImode);
2187  rtx tmp = gen_reg_rtx (DImode);
2188
2189  emit_move_insn (exp, GEN_INT (0x9e));
2190  emit_insn (gen_insn_bfins (tmp, exp, gen_lowpart (DImode, a),
2191                             GEN_INT (32), GEN_INT (63)));
2192  emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
2193  emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
2194  DONE;
2195})
2196
2197(define_expand "floatsidf2"
2198  [(set (match_operand:DF 0 "register_operand" "")
2199	(float:SI (match_operand:SI 1 "register_operand" "")))]
2200  ""
2201{
2202  rtx result = gen_lowpart (DImode, operands[0]);
2203  rtx a = gen_lowpart (DImode, operands[1]);
2204
2205  rtx nega = gen_reg_rtx (DImode);
2206  rtx exp = gen_reg_rtx (DImode);
2207  rtx sign = gen_reg_rtx (DImode);
2208  rtx abs = gen_reg_rtx (DImode);
2209  rtx tmp1 = gen_reg_rtx (DImode);
2210  rtx tmp2 = gen_reg_rtx (DImode);
2211  rtx tmp3 = gen_reg_rtx (DImode);
2212
2213  emit_move_insn (exp, GEN_INT (0x21b00));
2214
2215  emit_insn (gen_negdi2 (nega, a));
2216
2217  emit_insn (gen_insn_cmplts_didi (sign, a, const0_rtx));
2218  emit_insn (gen_insn_cmovnez (abs, a, sign, nega));
2219
2220  emit_insn (gen_ashldi3 (tmp1, abs, GEN_INT (4)));
2221  emit_insn (gen_insn_bfins (tmp2, exp, sign, GEN_INT (20), GEN_INT (20)));
2222  emit_insn (gen_insn_fdouble_pack1 (tmp3, tmp1, tmp2));
2223  emit_insn (gen_insn_fdouble_pack2 (result, tmp3, tmp1, const0_rtx));
2224  DONE;
2225})
2226
2227(define_expand "floatunssidf2"
2228  [(set (match_operand:DF 0 "register_operand" "")
2229	(float:SI (match_operand:SI 1 "register_operand" "")))]
2230  ""
2231{
2232  rtx result = gen_lowpart (DImode, operands[0]);
2233  rtx a = gen_lowpart (DImode, operands[1]);
2234
2235  rtx exp = gen_reg_rtx (DImode);
2236  rtx tmp1 = gen_reg_rtx (DImode);
2237  rtx tmp2 = gen_reg_rtx (DImode);
2238
2239  emit_move_insn (exp, GEN_INT (0x21b00));
2240  emit_insn (gen_insn_bfins (tmp1, const0_rtx, a, GEN_INT (4), GEN_INT (35)));
2241  emit_insn (gen_insn_fdouble_pack1 (tmp2, tmp1, exp));
2242  emit_insn (gen_insn_fdouble_pack2 (result, tmp2, tmp1, const0_rtx));
2243  DONE;
2244})
2245
2246
2247;;
2248;; Multiplies
2249;;
2250
2251(define_insn "mulsi3"
2252  [(set (match_operand:SI 0 "register_operand" "=r")
2253	(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rO")
2254                 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
2255  ""
2256  "mulx\t%0, %r1, %r2"
2257  [(set_attr "type" "Y0_2cycle")])
2258
2259(define_insn "mulsidi3"
2260  [(set (match_operand:DI 0 "register_operand" "=r")
2261	(mult:DI (sign_extend:DI
2262                  (match_operand:SI 1 "reg_or_0_operand" "%rO"))
2263		 (sign_extend:DI
2264                  (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
2265  ""
2266  "mul_ls_ls\t%0, %r1, %r2"
2267  [(set_attr "type" "Y0_2cycle")])
2268
2269(define_insn "umulsidi3"
2270  [(set (match_operand:DI 0 "register_operand" "=r")
2271	(mult:DI (zero_extend:DI
2272                  (match_operand:SI 1 "reg_or_0_operand" "%rO"))
2273		 (zero_extend:DI
2274                  (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
2275  ""
2276  "mul_lu_lu\t%0, %r1, %r2"
2277  [(set_attr "type" "Y0_2cycle")])
2278
2279(define_expand "muldi3"
2280  [(set (match_operand:DI 0 "register_operand" "")
2281        (unspec:DI [(match_operand:DI 1 "nonmemory_operand" "")
2282                    (match_operand:DI 2 "nonmemory_operand" "")]
2283                   UNSPEC_INSN_MUL_HU_LU))
2284   (set (match_dup 0)
2285        (unspec:DI [(match_dup 0) (match_dup 2) (match_dup 1)]
2286                   UNSPEC_INSN_MULA_HU_LU))
2287   (set (match_dup 0)
2288        (ashift:DI (match_dup 0) (const_int 32)))
2289   (set (match_dup 0)
2290        (unspec:DI [(match_dup 0) (match_dup 2) (match_dup 1)]
2291                   UNSPEC_INSN_MULA_LU_LU))]
2292  ""
2293  {
2294    operands[1] = force_reg (DImode, operands[1]);
2295    operands[1] = make_safe_from (operands[1], operands[0]);
2296
2297    if (tilegx_expand_muldi (operands[0], operands[1], operands[2]))
2298      DONE;
2299    else
2300      {
2301        operands[2] = force_reg (DImode, operands[2]);
2302        operands[2] = make_safe_from (operands[2], operands[0]);
2303      }
2304  })
2305
2306(define_insn "usmulsidi3"
2307  [(set (match_operand:DI 0 "register_operand" "=r")
2308	(mult:DI (zero_extend:DI
2309		  (match_operand:SI 1 "reg_or_0_operand" "rO"))
2310		 (sign_extend:DI
2311		  (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
2312  ""
2313  "mul_ls_lu\t%0, %r2, %r1"
2314  [(set_attr "type" "X0_2cycle")])
2315
2316(define_insn "maddsidi4"
2317  [(set (match_operand:DI 0 "register_operand" "=r")
2318        (plus:DI
2319         (mult:DI (sign_extend:DI
2320                   (match_operand:SI 1 "reg_or_0_operand" "rO"))
2321                  (sign_extend:DI
2322                   (match_operand:SI 2 "reg_or_0_operand" "rO")))
2323         (match_operand:DI 3 "register_operand" "0")))]
2324  ""
2325  "mula_ls_ls\t%0, %r1, %r2"
2326  [(set_attr "type" "Y0_2cycle")])
2327
2328(define_insn "umaddsidi4"
2329  [(set (match_operand:DI 0 "register_operand" "=r")
2330        (plus:DI
2331         (mult:DI (zero_extend:DI
2332                   (match_operand:SI 1 "reg_or_0_operand" "rO"))
2333                  (zero_extend:DI
2334                   (match_operand:SI 2 "reg_or_0_operand" "rO")))
2335         (match_operand:DI 3 "register_operand" "0")))]
2336  ""
2337  "mula_lu_lu\t%0, %r1, %r2"
2338  [(set_attr "type" "Y0_2cycle")])
2339
2340(define_expand "smulsi3_highpart"
2341  [(set (match_dup 3)
2342        (mult:DI (sign_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
2343                 (sign_extend:DI (match_operand:SI 2 "reg_or_0_operand" ""))))
2344   (set (match_dup 4)
2345        (ashiftrt:DI (match_dup 3) (const_int 32)))
2346   (set (match_operand:SI 0 "register_operand" "")
2347	(truncate:SI (match_dup 4)))]
2348  ""
2349  {
2350    operands[3] = gen_reg_rtx (DImode);
2351    operands[4] = gen_reg_rtx (DImode);
2352  })
2353
2354(define_expand "umulsi3_highpart"
2355  [(set (match_dup 3)
2356        (mult:DI (zero_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
2357                 (zero_extend:DI (match_operand:SI 2 "reg_or_0_operand" ""))))
2358   (set (match_dup 4)
2359        (lshiftrt:DI (match_dup 3) (const_int 32)))
2360   (set (match_operand:SI 0 "register_operand" "")
2361	(truncate:SI (match_dup 4)))]
2362  ""
2363  {
2364    operands[3] = gen_reg_rtx (DImode);
2365    operands[4] = gen_reg_rtx (DImode);
2366  })
2367
2368(define_expand "smuldi3_highpart"
2369  [(set (match_operand:DI 0 "register_operand" "")
2370        (truncate:DI
2371         (ashiftrt:TI
2372          (mult:TI (sign_extend:TI (match_operand:DI 1 "reg_or_0_operand" ""))
2373                   (sign_extend:TI (match_operand:DI 2 "reg_or_0_operand" "")))
2374          (const_int 64))))]
2375  ""
2376  {
2377    tilegx_expand_smuldi3_highpart (operands[0], operands[1], operands[2]);
2378    DONE;
2379  })
2380
2381(define_expand "umuldi3_highpart"
2382  [(set (match_operand:DI 0 "register_operand" "")
2383	(truncate:DI
2384	 (lshiftrt:TI
2385	  (mult:TI (zero_extend:TI (match_operand:DI 1 "reg_or_0_operand" ""))
2386		   (zero_extend:TI (match_operand:DI 2 "reg_or_0_operand" "")))
2387	  (const_int 64))))]
2388  ""
2389{
2390  tilegx_expand_umuldi3_highpart (operands[0], operands[1], operands[2]);
2391  DONE;
2392})
2393
2394
2395;;
2396;; Divide stubs.  These exist to work around a bug in expmed.c, which
2397;; will not attempt to convert a divide by constant into a multiply
2398;; unless there is a pattern for a divide of the same mode.  The end
2399;; result is a 32-bit divide turns into 64-bit multiply.
2400;;
2401
2402(define_expand "divsi3"
2403  [(set (match_operand:SI 0 "register_operand" "")
2404        (div:SI (match_operand:SI 1 "reg_or_0_operand" "")
2405                (match_operand:SI 2 "reg_or_0_operand" "")))]
2406  ""
2407{
2408  FAIL;
2409})
2410
2411(define_expand "udivsi3"
2412  [(set (match_operand:SI 0 "register_operand" "")
2413        (udiv:SI (match_operand:SI 1 "reg_or_0_operand" "")
2414                 (match_operand:SI 2 "reg_or_0_operand" "")))]
2415  ""
2416{
2417  FAIL;
2418})
2419
2420
2421;;
2422;; Loops
2423;;
2424
2425;; Define the subtract-one-and-jump insns so loop.c knows what to
2426;; generate.
2427(define_expand "doloop_end"
2428  [(use (match_operand 0 "" ""))    ;; loop pseudo
2429   (use (match_operand 1 "" ""))]   ;; label
2430   ""
2431{
2432  if (optimize > 0 && flag_modulo_sched)
2433  {
2434     rtx s0;
2435     rtx bcomp;
2436     rtx loc_ref;
2437     machine_mode mode = GET_MODE (operands[0]);
2438
2439     /* only deal with loop counters in SImode or DImode  */
2440     if (mode != SImode && mode != DImode)
2441       FAIL;
2442
2443     s0 = operands [0];
2444     emit_move_insn (s0, gen_rtx_PLUS (mode, s0, GEN_INT (-1)));
2445     bcomp = gen_rtx_NE(mode, s0, const0_rtx);
2446     loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
2447     emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2448                                  gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
2449                                                        loc_ref, pc_rtx)));
2450     DONE;
2451  }
2452  else
2453     FAIL;
2454
2455})
2456
2457;;
2458;; Prologue/epilogue
2459;;
2460(define_expand "prologue"
2461  [(const_int 0)]
2462  ""
2463{
2464  tilegx_expand_prologue ();
2465  DONE;
2466})
2467
2468(define_expand "epilogue"
2469  [(const_int 0)]
2470  ""
2471{
2472  tilegx_expand_epilogue (false);
2473  DONE;
2474})
2475
2476(define_expand "sibcall_epilogue"
2477  [(const_int 0)]
2478  ""
2479{
2480  tilegx_expand_epilogue (true);
2481  DONE;
2482})
2483
2484;;
2485;; Stack manipulations
2486;;
2487
2488;; An insn to allocate new stack space for dynamic use (e.g., alloca).
2489(define_expand "allocate_stack"
2490  [(set (match_operand 0 "register_operand" "")
2491	(minus (reg 54) (match_operand 1 "nonmemory_operand" "")))
2492   (set (reg 54)
2493	(minus (reg 54) (match_dup 1)))]
2494  ""
2495  "tilegx_allocate_stack (operands[0], operands[1]); DONE;")
2496
2497;;
2498;; Branches
2499;;
2500
2501(define_expand "call"
2502  [(parallel [(call (match_operand:DI 0 "call_operand" "")
2503		    (match_operand 1 "" ""))
2504              (use (reg:DI 54))
2505	      (clobber (reg:DI 55))])]
2506  ""
2507{
2508  rtx orig_addr = XEXP (operands[0], 0);
2509  rtx addr;
2510  if (GET_CODE (orig_addr) == SYMBOL_REF)
2511    {
2512      if (tilegx_cmodel == CM_LARGE)
2513        {
2514          addr = gen_reg_rtx (Pmode);
2515          tilegx_expand_set_const64 (addr, orig_addr);
2516          operands[0] = gen_rtx_MEM (DImode, addr);
2517        }
2518      else if (tilegx_cmodel == CM_LARGE_PIC)
2519        {
2520          crtl->uses_pic_offset_table = 1;
2521          addr = gen_reg_rtx (Pmode);
2522	  if (SYMBOL_REF_LOCAL_P (orig_addr))
2523	    tilegx_compute_pcrel_address (addr, orig_addr);
2524	  else
2525	    tilegx_compute_pcrel_plt_address (addr, orig_addr);
2526          operands[0] = gen_rtx_MEM (DImode, addr);
2527        }
2528    }
2529})
2530
2531(define_insn "*call_insn"
2532  [(call (mem:DI (match_operand:I48MODE 0 "call_address_operand" "rO,i"))
2533	 (match_operand 1 "" ""))
2534   (use (reg:DI 54))
2535   (clobber (reg:DI 55))]
2536  ""
2537  "@
2538   jalr\t%r0
2539   jal\t%p0"
2540  [(set_attr "type" "Y1,X1")])
2541
2542(define_expand "call_value"
2543  [(parallel [(set (match_operand 0 "register_operand" "")
2544		   (call (match_operand:DI 1 "call_operand" "")
2545			 (match_operand 2 "" "")))
2546              (use (reg:DI 54))
2547	      (clobber (reg:DI 55))])]
2548  ""
2549{
2550  rtx orig_addr = XEXP (operands[1], 0);
2551  rtx addr;
2552  if (GET_CODE (orig_addr) == SYMBOL_REF)
2553    {
2554      if (tilegx_cmodel == CM_LARGE)
2555        {
2556          addr = gen_reg_rtx (Pmode);
2557          tilegx_expand_set_const64 (addr, orig_addr);
2558          operands[1] = gen_rtx_MEM (DImode, addr);
2559        }
2560      else if (tilegx_cmodel == CM_LARGE_PIC)
2561        {
2562          crtl->uses_pic_offset_table = 1;
2563          addr = gen_reg_rtx (Pmode);
2564	  if (SYMBOL_REF_LOCAL_P (orig_addr))
2565	    tilegx_compute_pcrel_address (addr, orig_addr);
2566	  else
2567	    tilegx_compute_pcrel_plt_address (addr, orig_addr);
2568          operands[1] = gen_rtx_MEM (DImode, addr);
2569        }
2570    }
2571})
2572
2573(define_insn "*call_value_insn"
2574  [(set (match_operand 0 "register_operand" "=r,r")
2575	(call (mem:DI (match_operand:I48MODE 1 "call_address_operand" "rO,i"))
2576	      (match_operand 2 "" "")))
2577   (use (reg:DI 54))
2578   (clobber (reg:DI 55))]
2579  ""
2580  "@
2581   jalr\t%r1
2582   jal\t%p1"
2583  [(set_attr "type" "Y1,X1")])
2584
2585(define_expand "sibcall"
2586  [(parallel [(call (match_operand:DI 0 "call_operand" "")
2587		    (match_operand 1 "" ""))
2588	      (use (reg:DI 54))])]
2589  ""
2590  "")
2591
2592(define_insn "*sibcall_insn"
2593  [(call (mem:DI (match_operand:I48MODE 0 "call_address_operand" "rO,i"))
2594	 (match_operand 1 "" ""))
2595   (use (reg:DI 54))]
2596  "SIBLING_CALL_P(insn)"
2597  "@
2598   jr\t%r0
2599   j\t%p0"
2600  [(set_attr "type" "Y1,X1")])
2601
2602(define_expand "sibcall_value"
2603  [(parallel [(set (match_operand 0 "" "")
2604		   (call (match_operand:DI 1 "call_operand" "")
2605			 (match_operand 2 "" "")))
2606	      (use (reg:DI 54))])]
2607  ""
2608  "")
2609
2610(define_insn "*sibcall_value"
2611  [(set (match_operand 0 "" "")
2612	(call (mem:DI (match_operand:I48MODE 1 "call_address_operand" "rO,i"))
2613	      (match_operand 2 "" "")))
2614   (use (reg:DI 54))]
2615  "SIBLING_CALL_P(insn)"
2616  "@
2617   jr\t%r1
2618   j\t%p1"
2619  [(set_attr "type" "Y1,X1")])
2620
2621(define_insn "jump"
2622  [(set (pc) (label_ref (match_operand 0 "" "")))]
2623  ""
2624  "j\t%l0"
2625  [(set_attr "type" "X1")])
2626
2627(define_insn "indirect_jump"
2628  [(set (pc) (match_operand 0 "pointer_operand" "rO"))]
2629  ""
2630  "jr\t%r0"
2631  [(set_attr "type" "Y1")])
2632
2633(define_expand "return"
2634  [(parallel
2635    [(return)
2636     (use (reg:DI 55))])]
2637  "tilegx_can_use_return_insn_p ()"
2638  "")
2639
2640(define_insn "_return"
2641  [(return)
2642   (use (reg:DI 55))]
2643  "reload_completed"
2644  "jrp\tlr"
2645  [(set_attr "type" "Y1")])
2646
2647(define_expand "tablejump"
2648  [(set (pc) (match_operand 0 "pointer_operand" ""))
2649   (use (label_ref (match_operand 1 "" "")))]
2650  ""
2651{
2652  tilegx_expand_tablejump (operands[0], operands[1]);
2653  DONE;
2654})
2655
2656(define_insn "tablejump_aux"
2657  [(set (pc) (match_operand 0 "pointer_operand" "rO"))
2658   (use (label_ref (match_operand 1 "" "")))]
2659  ""
2660  "jr\t%r0"
2661  [(set_attr "type" "Y1")])
2662
2663;; Call subroutine returning any type.
2664(define_expand "untyped_call"
2665  [(parallel [(call (match_operand 0 "" "")
2666		    (const_int 0))
2667	      (match_operand 1 "" "")
2668	      (match_operand 2 "" "")])]
2669  ""
2670{
2671  int i;
2672
2673  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
2674
2675  for (i = 0; i < XVECLEN (operands[2], 0); i++)
2676    {
2677      rtx set = XVECEXP (operands[2], 0, i);
2678      emit_move_insn (SET_DEST (set), SET_SRC (set));
2679    }
2680
2681  /* The optimizer does not know that the call sets the function value
2682     registers we stored in the result block.  We avoid problems by
2683     claiming that all hard registers are used and clobbered at this
2684     point.  */
2685  emit_insn (gen_blockage ());
2686
2687  DONE;
2688})
2689
2690;; UNSPEC_VOLATILE is considered to use and clobber all hard registers
2691;; and all of memory.  This blocks insns from being moved across this
2692;; point.
2693(define_insn "blockage"
2694  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
2695  ""
2696  "pseudo"
2697  [(set_attr "type" "nothing")
2698   (set_attr "length" "0")])
2699
2700;; Internal expanders to prevent memory ops from moving around frame
2701;; allocation/deallocation.
2702;;
2703;; TODO: really this clobber should just clobber the frame memory.  Is
2704;; this possibly by clobbering memory @ the sp reg (as alpha does?)
2705;; or by explicitly setting the alias set to the frame?
2706(define_insn "sp_adjust"
2707  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
2708        (plus:DI
2709         (match_operand:DI 1 "register_operand" "%r,r,r")
2710         (match_operand:DI 2 "add_operand" "r,I,JT")))
2711   (clobber (mem:BLK (scratch)))]
2712 ""
2713 "@
2714  add\t%0, %1, %2
2715  addi\t%0, %1, %2
2716  addli\t%0, %1, %H2"
2717 [(set_attr "type" "*,*,X01")])
2718
2719(define_insn "sp_adjust_32bit"
2720  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2721        (plus:SI
2722         (match_operand:SI 1 "register_operand" "%r,r,r")
2723         (match_operand:SI 2 "add_operand" "r,I,JT")))
2724   (clobber (mem:BLK (scratch)))]
2725 ""
2726 "@
2727  addx\t%0, %1, %2
2728  addxi\t%0, %1, %2
2729  addxli\t%0, %1, %H2"
2730 [(set_attr "type" "*,*,X01")])
2731
2732;; Used for move sp, r52, to pop a stack frame.  We need to make sure
2733;; that stack frame memory operations have been issued before we do
2734;; this.  TODO: see above TODO.
2735(define_insn "sp_restore<bitsuffix>"
2736  [(set (match_operand:I48MODE 0 "register_operand" "=r")
2737        (match_operand:I48MODE 1 "register_operand" "r"))
2738   (clobber (mem:BLK (scratch)))]
2739 ""
2740 "move\t%0, %1")
2741
2742(define_insn "nop"
2743  [(const_int 0)]
2744  ""
2745  "nop"
2746  [(set_attr "type" "Y01")])
2747
2748
2749;;
2750;; Conditional branches
2751;;
2752
2753(define_expand "cbranch<mode>4"
2754  [(set (pc)
2755      (if_then_else (match_operator 0 "ordered_comparison_operator"
2756                     [(match_operand:FI48MODE 1 "reg_or_cint_operand")
2757                        (match_operand:FI48MODE 2 "reg_or_cint_operand")])
2758                      (label_ref (match_operand 3 ""))
2759                    (pc)))]
2760   ""
2761{
2762  tilegx_emit_conditional_branch (operands, GET_MODE (operands[1]));
2763  DONE;
2764})
2765
2766(define_insn "*bcc_normal<mode>"
2767  [(set (pc)
2768	(if_then_else
2769	 (match_operator 1 "signed_comparison_operator"
2770			 [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
2771			  (const_int 0)])
2772	 (label_ref (match_operand 0 "" ""))
2773	 (pc)))]
2774  ""
2775  { return tilegx_output_cbranch (insn, operands, false); }
2776  [(set_attr "type" "X1_branch")])
2777
2778(define_insn "*bcc_reverse<mode>"
2779  [(set (pc)
2780	(if_then_else
2781	 (match_operator 1 "signed_comparison_operator"
2782			 [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
2783			  (const_int 0)])
2784	 (pc)
2785	 (label_ref (match_operand 0 "" ""))))]
2786  ""
2787  { return tilegx_output_cbranch (insn, operands, true); }
2788  [(set_attr "type" "X1_branch")])
2789
2790(define_insn "*blbs_normal<mode>"
2791  [(set (pc)
2792	(if_then_else
2793	 (ne (zero_extract:I48MODE
2794              (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
2795              (const_int 1)
2796              (const_int 0))
2797	     (const_int 0))
2798	 (label_ref (match_operand 0 "" ""))
2799	 (pc)))]
2800  ""
2801  { return tilegx_output_cbranch_with_opcode (insn, operands, "blbs", "blbc",
2802					      1); }
2803  [(set_attr "type" "X1_branch")])
2804
2805(define_insn "*blbc_normal<mode>"
2806  [(set (pc)
2807	(if_then_else
2808	 (eq (zero_extract:I48MODE
2809              (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
2810              (const_int 1)
2811              (const_int 0))
2812	     (const_int 0))
2813	 (label_ref (match_operand 0 "" ""))
2814	 (pc)))]
2815  ""
2816  { return tilegx_output_cbranch_with_opcode (insn, operands, "blbc", "blbs",
2817					      1); }
2818  [(set_attr "type" "X1_branch")])
2819
2820;; Note that __insn_mf() expands to this.
2821(define_expand "memory_barrier"
2822  [(set (match_dup 0)
2823	(unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
2824  ""
2825{
2826  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
2827  MEM_VOLATILE_P (operands[0]) = 1;
2828})
2829
2830(define_insn "*memory_barrier"
2831  [(set (match_operand:BLK 0 "" "")
2832	(unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
2833  ""
2834  "mf"
2835  [(set_attr "type" "X1")])
2836
2837(define_insn "prefetch"
2838  [(prefetch (match_operand 0 "address_operand" "rO")
2839             (match_operand 1 "const_int_operand" "")
2840             (match_operand 2 "const_int_operand" ""))]
2841  ""
2842{
2843  switch (INTVAL (operands[2]))
2844    {
2845      case 0:
2846      case 1: return "prefetch_l3\t%r0";
2847      case 2: return "prefetch_l2\t%r0";
2848      case 3: return "prefetch_l1\t%r0";
2849      default: gcc_unreachable ();
2850    }
2851}
2852  [(set_attr "type" "Y2")])
2853
2854
2855;;
2856;; "__insn" Intrinsics (some expand directly to normal patterns above).
2857;;
2858
2859(define_insn "insn_bfexts"
2860  [(set (match_operand:DI 0 "register_operand" "=r")
2861        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2862                    (match_operand:DI 2 "u6bit_cint_operand" "n")
2863                    (match_operand:DI 3 "u6bit_cint_operand" "n")]
2864                   UNSPEC_INSN_BFEXTS))]
2865  ""
2866  "bfexts\t%0, %r1, %2, %3"
2867  [(set_attr "type" "X0")])
2868
2869(define_insn "insn_bfextu"
2870  [(set (match_operand:DI 0 "register_operand" "=r")
2871        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2872                    (match_operand:DI 2 "u6bit_cint_operand" "n")
2873                    (match_operand:DI 3 "u6bit_cint_operand" "n")]
2874                   UNSPEC_INSN_BFEXTU))]
2875  ""
2876  "bfextu\t%0, %r1, %2, %3"
2877  [(set_attr "type" "X0")])
2878
2879(define_insn "insn_bfins"
2880  [(set (match_operand:DI 0 "register_operand" "=r")
2881        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2882                    (match_operand:DI 2 "reg_or_0_operand" "rO")
2883                    (match_operand:DI 3 "u6bit_cint_operand" "n")
2884                    (match_operand:DI 4 "u6bit_cint_operand" "n")]
2885                   UNSPEC_INSN_BFINS))]
2886   ""
2887   "bfins\t%0, %r2, %3, %4"
2888   [(set_attr "type" "X0")])
2889
2890(define_insn "insn_cmpexch<four_if_si>"
2891  [(set (match_operand:I48MODE 0 "register_operand" "=r")
2892        (mem:I48MODE (match_operand 1 "pointer_operand" "rO")))
2893   (set (mem:I48MODE (match_dup 1))
2894        (unspec_volatile:I48MODE
2895	 [(mem:I48MODE (match_dup 1))
2896	  (reg:I48MODE TILEGX_CMPEXCH_REG)
2897	  (match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
2898	 UNSPEC_INSN_CMPEXCH))]
2899  ""
2900  "cmpexch<four_if_si>\t%0, %r1, %r2"
2901  [(set_attr "type" "X1_remote")])
2902
2903(define_insn "insn_cmul"
2904  [(set (match_operand:DI 0 "register_operand" "=r")
2905        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2906                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
2907                   UNSPEC_INSN_CMUL))]
2908  ""
2909  "cmul\t%0, %r1, %r2"
2910  [(set_attr "type" "X0_2cycle")])
2911
2912(define_insn "insn_cmula"
2913  [(set (match_operand:DI 0 "register_operand" "=r")
2914        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2915                    (match_operand:DI 2 "reg_or_0_operand" "rO")
2916                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
2917                   UNSPEC_INSN_CMULA))]
2918  ""
2919  "cmula\t%0, %r2, %r3"
2920  [(set_attr "type" "X0_2cycle")])
2921
2922(define_insn "insn_cmulaf"
2923  [(set (match_operand:DI 0 "register_operand" "=r")
2924        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2925                    (match_operand:DI 2 "reg_or_0_operand" "rO")
2926                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
2927                   UNSPEC_INSN_CMULAF))]
2928  ""
2929  "cmulaf\t%0, %r2, %r3"
2930  [(set_attr "type" "X0_2cycle")])
2931
2932(define_insn "insn_cmulf"
2933  [(set (match_operand:DI 0 "register_operand" "=r")
2934        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2935                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
2936                   UNSPEC_INSN_CMULF))]
2937  ""
2938  "cmulf\t%0, %r1, %r2"
2939  [(set_attr "type" "X0_2cycle")])
2940
2941(define_insn "insn_cmulfr"
2942  [(set (match_operand:DI 0 "register_operand" "=r")
2943        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2944                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
2945                   UNSPEC_INSN_CMULFR))]
2946  ""
2947  "cmulfr\t%0, %r1, %r2"
2948  [(set_attr "type" "X0_2cycle")])
2949
2950(define_insn "insn_cmulh"
2951  [(set (match_operand:DI 0 "register_operand" "=r")
2952        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2953                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
2954                   UNSPEC_INSN_CMULH))]
2955  ""
2956  "cmulh\t%0, %r1, %r2"
2957  [(set_attr "type" "X0_2cycle")])
2958
2959(define_insn "insn_cmulhr"
2960  [(set (match_operand:DI 0 "register_operand" "=r")
2961        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2962                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
2963                   UNSPEC_INSN_CMULHR))]
2964  ""
2965  "cmulhr\t%0, %r1, %r2"
2966  [(set_attr "type" "X0_2cycle")])
2967
2968(define_insn "insn_crc32_32"
2969  [(set (match_operand:DI 0 "register_operand" "=r")
2970        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2971                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
2972                   UNSPEC_INSN_CRC32_32))]
2973  ""
2974  "crc32_32\t%0, %r1, %r2"
2975  [(set_attr "type" "X0")])
2976
2977(define_insn "insn_crc32_8"
2978  [(set (match_operand:DI 0 "register_operand" "=r")
2979        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2980                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
2981                   UNSPEC_INSN_CRC32_8))]
2982  ""
2983  "crc32_8\t%0, %r1, %r2"
2984  [(set_attr "type" "X0")])
2985
2986(define_insn "insn_dblalign"
2987  [(set (match_operand:DI 0 "register_operand" "=r")
2988        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2989                    (match_operand:DI 2 "reg_or_0_operand" "rO")
2990                    (match_operand 3 "pointer_operand" "rO")]
2991                   UNSPEC_INSN_DBLALIGN))]
2992  ""
2993  "dblalign\t%0, %r2, %r3"
2994  [(set_attr "type" "X0")])
2995
2996(define_insn "insn_dblalign2"
2997  [(set (match_operand:DI 0 "register_operand" "=r")
2998        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2999                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3000                   UNSPEC_INSN_DBLALIGN2))]
3001  ""
3002  "dblalign2\t%0, %r1, %r2"
3003  [(set_attr "type" "X01")])
3004
3005(define_insn "insn_dblalign4"
3006  [(set (match_operand:DI 0 "register_operand" "=r")
3007        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3008                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3009                   UNSPEC_INSN_DBLALIGN4))]
3010  ""
3011  "dblalign4\t%0, %r1, %r2"
3012  [(set_attr "type" "X01")])
3013
3014(define_insn "insn_dblalign6"
3015  [(set (match_operand:DI 0 "register_operand" "=r")
3016        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3017                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3018                   UNSPEC_INSN_DBLALIGN6))]
3019  ""
3020  "dblalign6\t%0, %r1, %r2"
3021  [(set_attr "type" "X01")])
3022
3023(define_insn "insn_dtlbpr"
3024  [(unspec_volatile:VOID [(match_operand:DI 0 "reg_or_0_operand" "rO")]
3025                         UNSPEC_INSN_DTLBPR)]
3026  ""
3027  "dtlbpr\t%r0"
3028  [(set_attr "type" "X1")])
3029
3030(define_insn "insn_exch<four_if_si>"
3031  [(set (match_operand:I48MODE 0 "register_operand" "=r")
3032        (mem:I48MODE (match_operand 1 "pointer_operand" "rO")))
3033   (set (mem:I48MODE (match_dup 1))
3034	(unspec_volatile:I48MODE
3035	 [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
3036	 UNSPEC_INSN_EXCH))]
3037  ""
3038  "exch<four_if_si>\t%0, %r1, %r2"
3039  [(set_attr "type" "X1_remote")])
3040
3041(define_insn "insn_fdouble_add_flags"
3042  [(set (match_operand:DI 0 "register_operand" "=r")
3043        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3044                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3045                   UNSPEC_INSN_FDOUBLE_ADD_FLAGS))]
3046  ""
3047  "fdouble_add_flags\t%0, %r1, %r2"
3048  [(set_attr "type" "X0_2cycle")])
3049
3050(define_insn "insn_fdouble_addsub"
3051  [(set (match_operand:DI 0 "register_operand" "=r")
3052        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3053                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3054                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3055                   UNSPEC_INSN_FDOUBLE_ADDSUB))]
3056  ""
3057  "fdouble_addsub\t%0, %r2, %r3"
3058  [(set_attr "type" "X0_2cycle")])
3059
3060(define_insn "insn_fdouble_mul_flags"
3061  [(set (match_operand:DI 0 "register_operand" "=r")
3062        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3063                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3064                   UNSPEC_INSN_FDOUBLE_MUL_FLAGS))]
3065  ""
3066  "fdouble_mul_flags\t%0, %r1, %r2"
3067  [(set_attr "type" "X0_2cycle")])
3068
3069(define_insn "insn_fdouble_pack1"
3070  [(set (match_operand:DI 0 "register_operand" "=r")
3071        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3072                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3073                   UNSPEC_INSN_FDOUBLE_PACK1))]
3074  ""
3075  "fdouble_pack1\t%0, %r1, %r2"
3076  [(set_attr "type" "X0_2cycle")])
3077
3078(define_insn "insn_fdouble_pack2"
3079  [(set (match_operand:DI 0 "register_operand" "=r")
3080        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3081                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3082                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3083                   UNSPEC_INSN_FDOUBLE_PACK2))]
3084  ""
3085  "fdouble_pack2\t%0, %r2, %r3"
3086  [(set_attr "type" "X0_2cycle")])
3087
3088(define_insn "insn_fdouble_sub_flags"
3089  [(set (match_operand:DI 0 "register_operand" "=r")
3090        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3091                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3092                   UNSPEC_INSN_FDOUBLE_SUB_FLAGS))]
3093  ""
3094  "fdouble_sub_flags\t%0, %r1, %r2"
3095  [(set_attr "type" "X0_2cycle")])
3096
3097(define_insn "insn_fdouble_unpack_max"
3098  [(set (match_operand:DI 0 "register_operand" "=r")
3099        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3100                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3101                   UNSPEC_INSN_FDOUBLE_UNPACK_MAX))]
3102  ""
3103  "fdouble_unpack_max\t%0, %r1, %r2"
3104  [(set_attr "type" "X0_2cycle")])
3105
3106(define_insn "insn_fdouble_unpack_min"
3107  [(set (match_operand:DI 0 "register_operand" "=r")
3108        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3109                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3110                   UNSPEC_INSN_FDOUBLE_UNPACK_MIN))]
3111  ""
3112  "fdouble_unpack_min\t%0, %r1, %r2"
3113  [(set_attr "type" "X0_2cycle")])
3114
3115(define_insn "insn_fetchadd<four_if_si>"
3116  [(set (match_operand:I48MODE 0 "register_operand" "=r")
3117        (unspec_volatile:I48MODE
3118	 [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3119	 UNSPEC_ATOMIC))
3120   (set (mem:I48MODE (match_dup 1))
3121        (plus:I48MODE (mem:I48MODE (match_dup 1))
3122                      (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
3123  ""
3124  "fetchadd<four_if_si>\t%0, %r1, %r2"
3125  [(set_attr "type" "X1_remote")])
3126
3127(define_insn "insn_fetchaddgez<four_if_si>"
3128  [(set (match_operand:I48MODE 0 "register_operand" "=r")
3129        (unspec_volatile:I48MODE
3130	 [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3131	 UNSPEC_ATOMIC))
3132   (set (mem:I48MODE (match_dup 1))
3133        (unspec:I48MODE [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
3134                         (mem:I48MODE (match_dup 1))]
3135                        UNSPEC_INSN_FETCHADDGEZ))]
3136  ""
3137  "fetchaddgez<four_if_si>\t%0, %r1, %r2"
3138  [(set_attr "type" "X1_remote")])
3139
3140(define_insn "insn_fetchand<four_if_si>"
3141  [(set (match_operand:I48MODE 0 "register_operand" "=r")
3142        (unspec_volatile:I48MODE
3143	 [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3144	 UNSPEC_ATOMIC))
3145   (set (mem:I48MODE (match_dup 1))
3146        (and:I48MODE (mem:I48MODE (match_dup 1))
3147                     (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
3148  ""
3149  "fetchand<four_if_si>\t%0, %r1, %r2"
3150  [(set_attr "type" "X1_remote")])
3151
3152(define_insn "insn_fetchor<four_if_si>"
3153  [(set (match_operand:I48MODE 0 "register_operand" "=r")
3154        (unspec_volatile:I48MODE
3155	 [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3156	 UNSPEC_ATOMIC))
3157   (set (mem:I48MODE (match_dup 1))
3158        (ior:I48MODE (mem:I48MODE (match_dup 1))
3159                     (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
3160  ""
3161  "fetchor<four_if_si>\t%0, %r1, %r2"
3162  [(set_attr "type" "X1_remote")])
3163
3164(define_insn "insn_finv"
3165  [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3166                         UNSPEC_INSN_FINV)]
3167  ""
3168  "finv\t%r0"
3169  [(set_attr "type" "X1")])
3170
3171(define_insn "insn_flush"
3172  [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3173                         UNSPEC_INSN_FLUSH)]
3174  ""
3175  "flush\t%r0"
3176  [(set_attr "type" "X1")])
3177
3178(define_insn "insn_flushwb"
3179  [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FLUSHWB)]
3180  ""
3181  "flushwb"
3182  [(set_attr "type" "X1")])
3183
3184(define_insn "insn_fnop"
3185  [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FNOP)]
3186  ""
3187  "fnop")
3188
3189(define_insn "insn_fsingle_add1"
3190  [(set (match_operand:DI 0 "register_operand" "=r")
3191        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3192                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3193                   UNSPEC_INSN_FSINGLE_ADD1))]
3194  ""
3195  "fsingle_add1\t%0, %r1, %r2"
3196  [(set_attr "type" "X0")])
3197
3198(define_insn "insn_fsingle_addsub2"
3199  [(set (match_operand:DI 0 "register_operand" "=r")
3200        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3201                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3202                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3203                   UNSPEC_INSN_FSINGLE_ADDSUB2))]
3204  ""
3205  "fsingle_addsub2\t%0, %r2, %r3"
3206  [(set_attr "type" "X0_2cycle")])
3207
3208(define_insn "insn_fsingle_mul1"
3209  [(set (match_operand:DI 0 "register_operand" "=r")
3210        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3211                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3212                   UNSPEC_INSN_FSINGLE_MUL1))]
3213  ""
3214  "fsingle_mul1\t%0, %r1, %r2"
3215  [(set_attr "type" "X0")])
3216
3217(define_insn "insn_fsingle_mul2"
3218  [(set (match_operand:DI 0 "register_operand" "=r")
3219        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3220                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3221                   UNSPEC_INSN_FSINGLE_MUL2))]
3222  ""
3223  "fsingle_mul2\t%0, %r1, %r2"
3224  [(set_attr "type" "X0_2cycle")])
3225
3226(define_insn "insn_fsingle_pack1"
3227  [(set (match_operand:DI 0 "register_operand" "=r")
3228        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")]
3229                   UNSPEC_INSN_FSINGLE_PACK1))]
3230  ""
3231  "fsingle_pack1\t%0, %r1"
3232  [(set_attr "type" "Y0_2cycle")])
3233
3234(define_insn "insn_fsingle_pack2"
3235  [(set (match_operand:DI 0 "register_operand" "=r")
3236        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3237                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3238                   UNSPEC_INSN_FSINGLE_PACK2))]
3239  ""
3240  "fsingle_pack2\t%0, %r1, %r2"
3241  [(set_attr "type" "X0_2cycle")])
3242
3243(define_insn "insn_fsingle_sub1"
3244  [(set (match_operand:DI 0 "register_operand" "=r")
3245        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3246                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3247                   UNSPEC_INSN_FSINGLE_SUB1))]
3248  ""
3249  "fsingle_sub1\t%0, %r1, %r2"
3250  [(set_attr "type" "X0")])
3251
3252(define_insn "insn_drain"
3253  [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_DRAIN)]
3254  ""
3255  "drain"
3256  [(set_attr "type" "cannot_bundle")])
3257
3258(define_insn "insn_icoh"
3259  [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3260                         UNSPEC_INSN_ICOH)]
3261  ""
3262  "icoh\t%r0"
3263  [(set_attr "type" "X1")])
3264
3265(define_insn "insn_ill"
3266  [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_ILL)]
3267  ""
3268  "ill"
3269  [(set_attr "type" "cannot_bundle")])
3270
3271(define_insn "insn_info"
3272  [(unspec_volatile:VOID [(match_operand:DI 0 "s8bit_cint_operand" "i")]
3273                         UNSPEC_INSN_INFO)]
3274  ""
3275  "info\t%0")
3276
3277(define_insn "insn_infol"
3278  [(unspec_volatile:VOID [(match_operand:DI 0 "s16bit_cint_operand" "i")]
3279                         UNSPEC_INSN_INFOL)]
3280  ""
3281  "infol\t%0"
3282  [(set_attr "type" "X01")])
3283
3284(define_insn "insn_inv"
3285  [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3286                         UNSPEC_INSN_INV)]
3287  ""
3288  "inv\t%r0"
3289  [(set_attr "type" "X1")])
3290
3291;; loads
3292
3293(define_expand "insn_ld"
3294  [(set (match_operand:DI 0 "register_operand" "")
3295	(mem:DI (match_operand 1 "pointer_operand" "")))]
3296  "")
3297
3298(define_insn "insn_ld_add<bitsuffix>"
3299  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3300        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3301		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3302   (set (match_operand:DI 0 "register_operand" "=r")
3303        (mem:DI (match_dup 3)))]
3304  ""
3305  "ld_add\t%0, %1, %2"
3306  [(set_attr "type" "X1_2cycle")])
3307
3308(define_insn "insn_ldna"
3309  [(set (match_operand:DI 0 "register_operand" "=r")
3310	(mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
3311                        (const_int -8))))]
3312  ""
3313  "ldna\t%0, %r1"
3314  [(set_attr "type" "X1_2cycle")])
3315
3316(define_insn "insn_ldna_add<bitsuffix>"
3317  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3318        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3319		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3320   (set (match_operand:DI 0 "register_operand" "=r")
3321        (mem:DI (and:DI (match_dup 3) (const_int -8))))]
3322  ""
3323  "ldna_add\t%0, %1, %2"
3324  [(set_attr "type" "X1_2cycle")])
3325
3326(define_expand "insn_ld<n><s>"
3327  [(set (match_operand:DI 0 "register_operand" "")
3328	(any_extend:DI
3329	 (mem:I124MODE (match_operand 1 "pointer_operand" ""))))]
3330  "")
3331
3332(define_insn "insn_ld<I124MODE:n><s>_add<I48MODE:bitsuffix>"
3333  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3334        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3335		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3336   (set (match_operand:DI 0 "register_operand" "=r")
3337        (any_extend:DI (mem:I124MODE (match_dup 3))))]
3338  ""
3339  "ld<I124MODE:n><s>_add\t%0, %1, %2"
3340  [(set_attr "type" "X1_2cycle")])
3341
3342;; non temporal loads
3343
3344(define_insn "insn_ldnt"
3345  [(set (match_operand:DI 0 "register_operand" "=r")
3346	(unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3347                   UNSPEC_NON_TEMPORAL))]
3348  ""
3349  "ldnt\t%0, %r1"
3350  [(set_attr "type" "X1_2cycle")])
3351
3352(define_insn "insn_ldnt_add<bitsuffix>"
3353  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3354        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3355		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3356   (set (match_operand:DI 0 "register_operand" "=r")
3357        (unspec:DI [(mem:DI (match_dup 3))]
3358                   UNSPEC_NON_TEMPORAL))]
3359  ""
3360  "ldnt_add\t%0, %1, %2"
3361  [(set_attr "type" "X1_2cycle")])
3362
3363(define_insn "insn_ldnt<n><s>"
3364  [(set (match_operand:DI 0 "register_operand" "=r")
3365	(any_extend:DI
3366	 (unspec:I124MODE
3367	  [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3368	  UNSPEC_NON_TEMPORAL)))]
3369  ""
3370  "ldnt<n><s>\t%0, %r1"
3371  [(set_attr "type" "X1_2cycle")])
3372
3373(define_insn "insn_ldnt<I124MODE:n><s>_add<I48MODE:bitsuffix>"
3374  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3375        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3376		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3377   (set (match_operand:DI 0 "register_operand" "=r")
3378        (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
3379					UNSPEC_NON_TEMPORAL)))]
3380  ""
3381  "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
3382  [(set_attr "type" "X1_2cycle")])
3383
3384;; L2 hits
3385
3386(define_insn "insn_ld_L2"
3387  [(set (match_operand:DI 0 "register_operand" "=r")
3388	(unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3389		   UNSPEC_LATENCY_L2))]
3390  ""
3391  "ld\t%0, %r1"
3392  [(set_attr "type" "Y2_L2")])
3393
3394(define_insn "insn_ld_add_L2<bitsuffix>"
3395  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3396        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3397		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3398   (set (match_operand:DI 0 "register_operand" "=r")
3399        (unspec:DI [(mem:DI (match_dup 3))]
3400		   UNSPEC_LATENCY_L2))]
3401  ""
3402  "ld_add\t%0, %1, %2"
3403  [(set_attr "type" "X1_L2")])
3404
3405(define_insn "insn_ldna_L2"
3406  [(set (match_operand:DI 0 "register_operand" "=r")
3407	(unspec:DI [(mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
3408				    (const_int -8)))]
3409		   UNSPEC_LATENCY_L2))]
3410  ""
3411  "ldna\t%0, %r1"
3412  [(set_attr "type" "X1_L2")])
3413
3414(define_insn "insn_ldna_add_L2<bitsuffix>"
3415  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3416        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3417		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3418   (set (match_operand:DI 0 "register_operand" "=r")
3419        (unspec:DI [(mem:DI (and:DI (match_dup 3) (const_int -8)))]
3420		   UNSPEC_LATENCY_L2))]
3421  ""
3422  "ldna_add\t%0, %1, %2"
3423  [(set_attr "type" "X1_L2")])
3424
3425(define_insn "insn_ld<n><s>_L2"
3426  [(set (match_operand:DI 0 "register_operand" "=r")
3427	(any_extend:DI
3428	 (unspec:I124MODE
3429	  [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3430	  UNSPEC_LATENCY_L2)))]
3431  ""
3432  "ld<n><s>\t%0, %r1"
3433  [(set_attr "type" "Y2_L2")])
3434
3435(define_insn "insn_ld<I124MODE:n><s>_add_L2<I48MODE:bitsuffix>"
3436  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3437        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3438		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3439   (set (match_operand:DI 0 "register_operand" "=r")
3440        (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
3441					UNSPEC_LATENCY_L2)))]
3442  ""
3443  "ld<I124MODE:n><s>_add\t%0, %1, %2"
3444  [(set_attr "type" "X1_L2")])
3445
3446;; L2 hits, non temporal loads
3447
3448(define_insn "insn_ldnt_L2"
3449  [(set (match_operand:DI 0 "register_operand" "=r")
3450	(unspec:DI [(unspec:DI
3451                     [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3452                     UNSPEC_NON_TEMPORAL)]
3453                   UNSPEC_LATENCY_L2))]
3454  ""
3455  "ldnt\t%0, %r1"
3456  [(set_attr "type" "X1_L2")])
3457
3458(define_insn "insn_ldnt_add_L2<bitsuffix>"
3459  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3460        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3461		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3462   (set (match_operand:DI 0 "register_operand" "=r")
3463        (unspec:DI [(unspec:DI
3464                     [(mem:DI (match_dup 3))]
3465                     UNSPEC_NON_TEMPORAL)]
3466                   UNSPEC_LATENCY_L2))]
3467                   ""
3468  "ldnt_add\t%0, %1, %2"
3469  [(set_attr "type" "X1_L2")])
3470
3471(define_insn "insn_ldnt<n><s>_L2"
3472  [(set (match_operand:DI 0 "register_operand" "=r")
3473	(any_extend:DI
3474	 (unspec:I124MODE
3475	  [(unspec:I124MODE
3476	    [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3477	    UNSPEC_NON_TEMPORAL)]
3478	  UNSPEC_LATENCY_L2)))]
3479  ""
3480  "ldnt<n><s>\t%0, %r1"
3481  [(set_attr "type" "X1_L2")])
3482
3483(define_insn "insn_ldnt<I124MODE:n><s>_add_L2<I48MODE:bitsuffix>"
3484  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3485        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3486		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3487   (set (match_operand:DI 0 "register_operand" "=r")
3488        (any_extend:DI
3489	 (unspec:I124MODE [(unspec:I124MODE
3490			    [(mem:I124MODE (match_dup 3))]
3491			    UNSPEC_NON_TEMPORAL)]
3492			  UNSPEC_LATENCY_L2)))]
3493  ""
3494  "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
3495  [(set_attr "type" "X1_L2")])
3496
3497;; L2 miss
3498
3499(define_insn "insn_ld_miss"
3500  [(set (match_operand:DI 0 "register_operand" "=r")
3501	(unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3502		   UNSPEC_LATENCY_MISS))]
3503  ""
3504  "ld\t%0, %r1"
3505  [(set_attr "type" "Y2_miss")])
3506
3507(define_insn "insn_ld_add_miss<bitsuffix>"
3508  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3509        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3510		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3511   (set (match_operand:DI 0 "register_operand" "=r")
3512        (unspec:DI [(mem:DI (match_dup 3))]
3513		   UNSPEC_LATENCY_MISS))]
3514  ""
3515  "ld_add\t%0, %1, %2"
3516  [(set_attr "type" "X1_miss")])
3517
3518(define_insn "insn_ldna_miss"
3519  [(set (match_operand:DI 0 "register_operand" "=r")
3520	(unspec:DI [(mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
3521				    (const_int -8)))]
3522		   UNSPEC_LATENCY_MISS))]
3523  ""
3524  "ldna\t%0, %r1"
3525  [(set_attr "type" "X1_miss")])
3526
3527(define_insn "insn_ldna_add_miss<bitsuffix>"
3528  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3529        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3530		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3531   (set (match_operand:DI 0 "register_operand" "=r")
3532        (unspec:DI [(mem:DI (and:DI (match_dup 3) (const_int -8)))]
3533		   UNSPEC_LATENCY_MISS))]
3534  ""
3535  "ldna_add\t%0, %1, %2"
3536  [(set_attr "type" "X1_miss")])
3537
3538(define_insn "insn_ld<n><s>_miss"
3539  [(set (match_operand:DI 0 "register_operand" "=r")
3540	(any_extend:DI
3541	 (unspec:I124MODE
3542	  [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3543	  UNSPEC_LATENCY_MISS)))]
3544  ""
3545  "ld<n><s>\t%0, %r1"
3546  [(set_attr "type" "Y2_miss")])
3547
3548(define_insn "insn_ld<I124MODE:n><s>_add_miss<I48MODE:bitsuffix>"
3549  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3550        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3551		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3552   (set (match_operand:DI 0 "register_operand" "=r")
3553        (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
3554					UNSPEC_LATENCY_MISS)))]
3555  ""
3556  "ld<I124MODE:n><s>_add\t%0, %1, %2"
3557  [(set_attr "type" "X1_miss")])
3558
3559;; L2 miss, non temporal loads
3560
3561(define_insn "insn_ldnt_miss"
3562  [(set (match_operand:DI 0 "register_operand" "=r")
3563	(unspec:DI [(unspec:DI
3564                     [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3565                     UNSPEC_NON_TEMPORAL)]
3566                   UNSPEC_LATENCY_MISS))]
3567  ""
3568  "ldnt\t%0, %r1"
3569  [(set_attr "type" "X1_miss")])
3570
3571(define_insn "insn_ldnt_add_miss<bitsuffix>"
3572  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3573        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3574		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3575   (set (match_operand:DI 0 "register_operand" "=r")
3576        (unspec:DI [(unspec:DI
3577                     [(mem:DI (match_dup 3))]
3578                     UNSPEC_NON_TEMPORAL)]
3579                   UNSPEC_LATENCY_MISS))]
3580                   ""
3581  "ldnt_add\t%0, %1, %2"
3582  [(set_attr "type" "X1_miss")])
3583
3584(define_insn "insn_ldnt<n><s>_miss"
3585  [(set (match_operand:DI 0 "register_operand" "=r")
3586	(any_extend:DI
3587	 (unspec:I124MODE
3588	  [(unspec:I124MODE
3589	    [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3590	    UNSPEC_NON_TEMPORAL)]
3591	  UNSPEC_LATENCY_MISS)))]
3592  ""
3593  "ldnt<n><s>\t%0, %r1"
3594  [(set_attr "type" "X1_miss")])
3595
3596(define_insn "insn_ldnt<I124MODE:n><s>_add_miss<I48MODE:bitsuffix>"
3597  [(set (match_operand:I48MODE 1 "register_operand" "=r")
3598        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3599		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3600   (set (match_operand:DI 0 "register_operand" "=r")
3601        (any_extend:DI
3602	 (unspec:I124MODE [(unspec:I124MODE
3603                      [(mem:I124MODE (match_dup 3))]
3604                      UNSPEC_NON_TEMPORAL)]
3605                    UNSPEC_LATENCY_MISS)))]
3606  ""
3607  "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
3608  [(set_attr "type" "X1_miss")])
3609
3610;; end loads
3611
3612(define_insn "insn_lnk"
3613  [(set (match_operand:DI 0 "register_operand" "=r")
3614        (unspec:DI [(const_int 0)] UNSPEC_INSN_LNK))]
3615  ""
3616  "lnk\t%0"
3617  [(set_attr "type" "Y1")])
3618
3619(define_insn "insn_mfspr"
3620  [(set (match_operand:DI 0 "register_operand" "=r")
3621        (unspec_volatile:DI [(match_operand:DI 1 "u14bit_cint_operand" "i")]
3622                            UNSPEC_INSN_MFSPR))
3623   (clobber (mem:BLK (const_int 0)))]
3624  ""
3625  "mfspr\t%0, %1"
3626  [(set_attr "type" "X1")])
3627
3628(define_insn "insn_mtspr"
3629  [(unspec_volatile:DI [(match_operand:DI 0 "u14bit_cint_operand" "i")
3630                        (match_operand:DI 1 "reg_or_0_operand" "rO")]
3631                       UNSPEC_INSN_MTSPR)
3632   (clobber (mem:BLK (const_int 0)))]
3633  ""
3634  "mtspr\t%0, %r1"
3635  [(set_attr "type" "X1")])
3636
3637(define_insn "insn_mm"
3638  [(set (match_operand:DI 0 "register_operand" "=r")
3639        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3640                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3641                    (match_operand:DI 3 "u6bit_cint_operand" "i")
3642                    (match_operand:DI 4 "u6bit_cint_operand" "i")]
3643                   UNSPEC_INSN_MM))]
3644  ""
3645  "mm\t%0, %r2, %3, %4"
3646  [(set_attr "type" "X0")])
3647
3648(define_insn "insn_mul_hs_hs"
3649  [(set (match_operand:DI 0 "register_operand" "=r")
3650        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3651                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3652                   UNSPEC_INSN_MUL_HS_HS))]
3653  ""
3654  "mul_hs_hs\t%0, %r1, %r2"
3655  [(set_attr "type" "Y0_2cycle")])
3656
3657(define_insn "insn_mul_hs_hu"
3658  [(set (match_operand:DI 0 "register_operand" "=r")
3659        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3660                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3661                   UNSPEC_INSN_MUL_HS_HU))]
3662  ""
3663  "mul_hs_hu\t%0, %r1, %r2"
3664  [(set_attr "type" "X0_2cycle")])
3665
3666(define_insn "insn_mul_hs_ls"
3667  [(set (match_operand:DI 0 "register_operand" "=r")
3668        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3669                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3670                   UNSPEC_INSN_MUL_HS_LS))]
3671  ""
3672  "mul_hs_ls\t%0, %r1, %r2"
3673  [(set_attr "type" "X0_2cycle")])
3674
3675(define_insn "insn_mul_hs_lu"
3676  [(set (match_operand:DI 0 "register_operand" "=r")
3677        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3678                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3679                   UNSPEC_INSN_MUL_HS_LU))]
3680  ""
3681  "mul_hs_lu\t%0, %r1, %r2"
3682  [(set_attr "type" "X0_2cycle")])
3683
3684(define_insn "insn_mul_hu_hu"
3685  [(set (match_operand:DI 0 "register_operand" "=r")
3686        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3687                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3688                   UNSPEC_INSN_MUL_HU_HU))]
3689  ""
3690  "mul_hu_hu\t%0, %r1, %r2"
3691  [(set_attr "type" "Y0_2cycle")])
3692
3693(define_insn "insn_mul_hu_ls"
3694  [(set (match_operand:DI 0 "register_operand" "=r")
3695        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3696                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3697                   UNSPEC_INSN_MUL_HU_LS))]
3698  ""
3699  "mul_hu_ls\t%0, %r1, %r2"
3700  [(set_attr "type" "X0_2cycle")])
3701
3702(define_insn "insn_mul_hu_lu"
3703  [(set (match_operand:DI 0 "register_operand" "=r")
3704        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3705                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3706                   UNSPEC_INSN_MUL_HU_LU))]
3707  ""
3708  "mul_hu_lu\t%0, %r1, %r2"
3709  [(set_attr "type" "X0_2cycle")])
3710
3711(define_insn "insn_mul_ls_ls"
3712  [(set (match_operand:DI 0 "register_operand" "=r")
3713        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3714                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3715                   UNSPEC_INSN_MUL_LS_LS))]
3716  ""
3717  "mul_ls_ls\t%0, %r1, %r2"
3718  [(set_attr "type" "Y0_2cycle")])
3719
3720(define_insn "insn_mul_ls_lu"
3721  [(set (match_operand:DI 0 "register_operand" "=r")
3722        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3723                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3724                   UNSPEC_INSN_MUL_LS_LU))]
3725  ""
3726  "mul_ls_lu\t%0, %r1, %r2"
3727  [(set_attr "type" "X0_2cycle")])
3728
3729(define_insn "insn_mul_lu_lu"
3730  [(set (match_operand:DI 0 "register_operand" "=r")
3731        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3732                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3733                   UNSPEC_INSN_MUL_LU_LU))]
3734  ""
3735  "mul_lu_lu\t%0, %r1, %r2"
3736  [(set_attr "type" "Y0_2cycle")])
3737
3738(define_insn "insn_mula_hs_hs"
3739  [(set (match_operand:DI 0 "register_operand" "=r")
3740        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3741                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3742                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3743                   UNSPEC_INSN_MULA_HS_HS))]
3744  ""
3745  "mula_hs_hs\t%0, %r2, %r3"
3746  [(set_attr "type" "Y0_2cycle")])
3747
3748(define_insn "insn_mula_hs_hu"
3749  [(set (match_operand:DI 0 "register_operand" "=r")
3750        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3751                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3752                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3753                   UNSPEC_INSN_MULA_HS_HU))]
3754  ""
3755  "mula_hs_hu\t%0, %r2, %r3"
3756  [(set_attr "type" "X0_2cycle")])
3757
3758(define_insn "insn_mula_hs_ls"
3759  [(set (match_operand:DI 0 "register_operand" "=r")
3760        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3761                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3762                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3763                   UNSPEC_INSN_MULA_HS_LS))]
3764  ""
3765  "mula_hs_ls\t%0, %r2, %r3"
3766  [(set_attr "type" "X0_2cycle")])
3767
3768(define_insn "insn_mula_hs_lu"
3769  [(set (match_operand:DI 0 "register_operand" "=r")
3770        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3771                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3772                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3773                   UNSPEC_INSN_MULA_HS_LU))]
3774  ""
3775  "mula_hs_lu\t%0, %r2, %r3"
3776  [(set_attr "type" "X0_2cycle")])
3777
3778(define_insn "insn_mula_hu_hu"
3779  [(set (match_operand:DI 0 "register_operand" "=r")
3780        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3781                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3782                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3783                   UNSPEC_INSN_MULA_HU_HU))]
3784  ""
3785  "mula_hu_hu\t%0, %r2, %r3"
3786  [(set_attr "type" "Y0_2cycle")])
3787
3788(define_insn "insn_mula_hu_ls"
3789  [(set (match_operand:DI 0 "register_operand" "=r")
3790        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3791                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3792                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3793                   UNSPEC_INSN_MULA_HU_LS))]
3794  ""
3795  "mula_hu_ls\t%0, %r2, %r3"
3796  [(set_attr "type" "X0_2cycle")])
3797
3798(define_insn "insn_mula_hu_lu"
3799  [(set (match_operand:DI 0 "register_operand" "=r")
3800        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3801                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3802                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3803                   UNSPEC_INSN_MULA_HU_LU))]
3804  ""
3805  "mula_hu_lu\t%0, %r2, %r3"
3806  [(set_attr "type" "X0_2cycle")])
3807
3808(define_insn "insn_mula_ls_ls"
3809  [(set (match_operand:DI 0 "register_operand" "=r")
3810        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3811                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3812                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3813                   UNSPEC_INSN_MULA_LS_LS))]
3814  ""
3815  "mula_ls_ls\t%0, %r2, %r3"
3816  [(set_attr "type" "Y0_2cycle")])
3817
3818(define_insn "insn_mula_ls_lu"
3819  [(set (match_operand:DI 0 "register_operand" "=r")
3820        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3821                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3822                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3823                   UNSPEC_INSN_MULA_LS_LU))]
3824  ""
3825  "mula_ls_lu\t%0, %r2, %r3"
3826  [(set_attr "type" "X0_2cycle")])
3827
3828(define_insn "insn_mula_lu_lu"
3829  [(set (match_operand:DI 0 "register_operand" "=r")
3830        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3831                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3832                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3833                   UNSPEC_INSN_MULA_LU_LU))]
3834  ""
3835  "mula_lu_lu\t%0, %r2, %r3"
3836  [(set_attr "type" "Y0_2cycle")])
3837
3838(define_insn "insn_mulax"
3839  [(set (match_operand:SI 0 "register_operand" "=r")
3840        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3841                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3842                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3843                   UNSPEC_INSN_MULAX))]
3844  ""
3845  "mulax\t%0, %r2, %r3"
3846  [(set_attr "type" "Y0_2cycle")])
3847
3848(define_insn "insn_nap"
3849  [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_NAP)]
3850  ""
3851  "nap"
3852  [(set_attr "type" "cannot_bundle")])
3853
3854(define_insn "insn_nor_<mode>"
3855  [(set (match_operand:I48MODE 0 "register_operand" "=r")
3856	(and:I48MODE
3857         (not:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO"))
3858         (not:I48MODE (match_operand:I48MODE 2 "reg_or_0_operand" "rO"))))]
3859  ""
3860  "nor\t%0, %r1, %r2")
3861
3862(define_expand "insn_prefetch_l1"
3863  [(prefetch (match_operand 0 "pointer_operand" "")
3864             (const_int 0)
3865             (const_int 3))]
3866  "")
3867
3868(define_expand "insn_prefetch_l2"
3869  [(prefetch (match_operand 0 "pointer_operand" "")
3870             (const_int 0)
3871             (const_int 2))]
3872  "")
3873
3874(define_expand "insn_prefetch_l3"
3875  [(prefetch (match_operand 0 "pointer_operand" "")
3876             (const_int 0)
3877             (const_int 1))]
3878  "")
3879
3880(define_insn "insn_prefetch_l1_fault"
3881  [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3882                         UNSPEC_INSN_PREFETCH_L1_FAULT)]
3883  ""
3884  "prefetch_l1_fault\t%r0"
3885  [(set_attr "type" "Y2")])
3886
3887(define_insn "insn_prefetch_l2_fault"
3888  [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3889                         UNSPEC_INSN_PREFETCH_L2_FAULT)]
3890  ""
3891  "prefetch_l2_fault\t%r0"
3892  [(set_attr "type" "Y2")])
3893
3894(define_insn "insn_prefetch_l3_fault"
3895  [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3896                         UNSPEC_INSN_PREFETCH_L3_FAULT)]
3897  ""
3898  "prefetch_l3_fault\t%r0"
3899  [(set_attr "type" "Y2")])
3900
3901(define_insn "insn_revbits"
3902  [(set (match_operand:DI 0 "register_operand" "=r")
3903        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")]
3904                   UNSPEC_INSN_REVBITS))]
3905  ""
3906  "revbits\t%0, %r1"
3907  [(set_attr "type" "Y0")])
3908
3909(define_insn "insn_shl1add"
3910  [(set (match_operand:DI 0 "register_operand" "=r")
3911        (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
3912                          (const_int 2))
3913                 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
3914  ""
3915  "shl1add\t%0, %r1, %r2")
3916
3917(define_insn "insn_shl1addx"
3918  [(set (match_operand:SI 0 "register_operand" "=r")
3919        (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
3920                          (const_int 2))
3921                 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
3922  ""
3923  "shl1addx\t%0, %r1, %r2")
3924
3925(define_insn "insn_shl2add"
3926  [(set (match_operand:DI 0 "register_operand" "=r")
3927        (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
3928                          (const_int 4))
3929                 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
3930  ""
3931  "shl2add\t%0, %r1, %r2")
3932
3933(define_insn "insn_shl2addx"
3934  [(set (match_operand:SI 0 "register_operand" "=r")
3935        (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
3936                          (const_int 4))
3937                 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
3938  ""
3939  "shl2addx\t%0, %r1, %r2")
3940
3941(define_insn "insn_shl3add"
3942  [(set (match_operand:DI 0 "register_operand" "=r")
3943        (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
3944                          (const_int 8))
3945                 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
3946  ""
3947  "shl3add\t%0, %r1, %r2")
3948
3949(define_insn "insn_shl3addx"
3950  [(set (match_operand:SI 0 "register_operand" "=r")
3951        (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
3952                          (const_int 8))
3953                 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
3954  ""
3955  "shl3addx\t%0, %r1, %r2")
3956
3957(define_insn "insn_shufflebytes"
3958  [(set (match_operand:DI 0 "register_operand" "=r")
3959        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3960                    (match_operand:DI 2 "reg_or_0_operand" "rO")
3961                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
3962                   UNSPEC_INSN_SHUFFLEBYTES))]
3963  ""
3964  "shufflebytes\t%0, %r2, %r3"
3965  [(set_attr "type" "X0")])
3966
3967(define_insn "insn_shufflebytes1"
3968  [(set (match_operand:DI 0 "register_operand" "=r")
3969        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3970                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
3971                   UNSPEC_INSN_SHUFFLEBYTES))]
3972  ""
3973  "shufflebytes\t%0, %r1, %r2"
3974  [(set_attr "type" "X0")])
3975
3976;; stores
3977
3978(define_expand "insn_st"
3979  [(set (mem:DI (match_operand 0 "pointer_operand" ""))
3980        (match_operand:DI 1 "reg_or_0_operand" ""))]
3981  "")
3982
3983(define_insn "insn_st_add<bitsuffix>"
3984  [(set (match_operand:I48MODE 0 "register_operand" "=r")
3985        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
3986		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3987   (set (mem:DI (match_dup 3))
3988        (match_operand:DI 1 "reg_or_0_operand" "rO"))]
3989  ""
3990  "st_add\t%0, %r1, %2"
3991  [(set_attr "type" "X1")])
3992
3993(define_expand "insn_st<n>"
3994  [(set (mem:I124MODE (match_operand 0 "pointer_operand" ""))
3995        (match_operand:DI 1 "reg_or_0_operand" ""))]
3996  ""
3997{
3998  operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], DImode,
3999                                     BYTES_BIG_ENDIAN
4000				     ? UNITS_PER_WORD - <n>  : 0);
4001})
4002
4003(define_expand "insn_st<I124MODE:n>_add<I48MODE:bitsuffix>"
4004  [(parallel
4005    [(set (match_operand:I48MODE 0 "register_operand" "")
4006	  (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "")
4007			(match_operand:I48MODE 2 "s8bit_cint_operand" "")))
4008     (set (mem:I124MODE (match_dup 3))
4009	  (match_operand:DI 1 "reg_or_0_operand" ""))])]
4010  ""
4011{
4012  operands[1] = simplify_gen_subreg (<I124MODE:MODE>mode, operands[1],
4013				     DImode,
4014				     BYTES_BIG_ENDIAN
4015				     ? UNITS_PER_WORD - <I124MODE:n> : 0);
4016})
4017
4018(define_insn "*insn_st<I124MODE:n>_add<I48MODE:bitsuffix>"
4019  [(set (match_operand:I48MODE 0 "register_operand" "=r")
4020        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4021		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
4022   (set (mem:I124MODE (match_dup 3))
4023        (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
4024  ""
4025  "st<I124MODE:n>_add\t%0, %r1, %2"
4026  [(set_attr "type" "X1")])
4027
4028;; non-temporal stores
4029
4030(define_insn "insn_stnt"
4031  [(set (mem:DI (unspec [(match_operand 0 "pointer_operand" "rO")]
4032			UNSPEC_NON_TEMPORAL))
4033        (match_operand:DI 1 "reg_or_0_operand" "rO"))]
4034  ""
4035  "stnt\t%0, %r1"
4036  [(set_attr "type" "X1")])
4037
4038(define_insn "insn_stnt_add<bitsuffix>"
4039  [(set (match_operand:I48MODE 0 "register_operand" "=r")
4040        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4041		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
4042   (set (mem:DI (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
4043        (match_operand:DI 1 "reg_or_0_operand" "rO"))]
4044  ""
4045  "stnt_add\t%0, %r1, %2"
4046  [(set_attr "type" "X1")])
4047
4048(define_expand "insn_stnt<n>"
4049  [(set (mem:I124MODE (unspec [(match_operand 0 "pointer_operand" "")]
4050			      UNSPEC_NON_TEMPORAL))
4051        (match_operand:DI 1 "reg_or_0_operand" ""))]
4052  ""
4053{
4054  operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], DImode,
4055                                     BYTES_BIG_ENDIAN
4056				     ? UNITS_PER_WORD - <n> : 0);
4057})
4058
4059(define_insn "*insn_stnt<n>"
4060  [(set (mem:I124MODE (unspec [(match_operand 0 "pointer_operand" "rO")]
4061			      UNSPEC_NON_TEMPORAL))
4062	(match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
4063  ""
4064  "stnt<n>\t%0, %r1"
4065  [(set_attr "type" "X1")])
4066
4067(define_expand "insn_stnt<I124MODE:n>_add<I48MODE:bitsuffix>"
4068  [(parallel
4069    [(set (match_operand:I48MODE 0 "register_operand" "")
4070	  (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "")
4071			(match_operand:I48MODE 2 "s8bit_cint_operand" "")))
4072     (set (mem:I124MODE (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
4073	  (match_operand:DI 1 "reg_or_0_operand" "rO"))])]
4074  ""
4075{
4076  operands[1] = simplify_gen_subreg (<I124MODE:MODE>mode, operands[1],
4077				     DImode,
4078				     BYTES_BIG_ENDIAN
4079				     ? UNITS_PER_WORD - <n> : 0);
4080})
4081
4082(define_insn "*insn_stnt<I124MODE:n>_add<I48MODE:bitsuffix>"
4083  [(set (match_operand:I48MODE 0 "register_operand" "=r")
4084        (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4085		      (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
4086   (set (mem:I124MODE (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
4087        (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
4088  ""
4089  "stnt<I124MODE:n>_add\t%0, %r1, %2"
4090  [(set_attr "type" "X1")])
4091
4092;; end stores
4093
4094(define_insn "insn_tblidxb0"
4095  [(set (match_operand:DI 0 "register_operand" "=r")
4096        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4097                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
4098                   UNSPEC_INSN_TBLIDXB0))]
4099  ""
4100  "tblidxb0\t%0, %r2"
4101  [(set_attr "type" "Y0")])
4102
4103(define_insn "insn_tblidxb1"
4104  [(set (match_operand:DI 0 "register_operand" "=r")
4105        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4106                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
4107                   UNSPEC_INSN_TBLIDXB1))]
4108  ""
4109  "tblidxb1\t%0, %r2"
4110  [(set_attr "type" "Y0")])
4111
4112(define_insn "insn_tblidxb2"
4113  [(set (match_operand:DI 0 "register_operand" "=r")
4114        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4115                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
4116                   UNSPEC_INSN_TBLIDXB2))]
4117  ""
4118  "tblidxb2\t%0, %r2"
4119  [(set_attr "type" "Y0")])
4120
4121(define_insn "insn_tblidxb3"
4122  [(set (match_operand:DI 0 "register_operand" "=r")
4123        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4124                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
4125                   UNSPEC_INSN_TBLIDXB3))]
4126  ""
4127  "tblidxb3\t%0, %r2"
4128  [(set_attr "type" "Y0")])
4129
4130;; insn_v1add
4131;; insn_v1addi
4132;; insn_v1cmpeq
4133;; insn_v1cmpeqi
4134;; insn_v1cmplts
4135;; insn_v1cmpltsi
4136;; insn_v1cmpltu
4137;; insn_v1cmpltui
4138;; insn_v1maxu
4139;; insn_v1maxui
4140;; insn_v1minu
4141;; insn_v1minui
4142(define_insn "<optab>v8qi3"
4143  [(set (match_operand:V8QI 0 "register_operand" "=r,r")
4144	(v1op_immed:V8QI
4145	 (match_operand:V8QI 1 "reg_or_0_operand" "<comm>rO,rO")
4146	 (match_operand:V8QI 2 "reg_or_v8s8bit_operand" "W,rO")))]
4147  ""
4148  "@
4149   v1<insn>i\t%0, %r1, %j2
4150   v1<insn>\t%0, %r1, %r2"
4151  [(set_attr "type" "<pipe>,<pipe>")])
4152
4153(define_expand "insn_v1<insn>"
4154  [(set (match_operand:DI 0 "register_operand" "")
4155	(v1op_immed:V8QI
4156	 (match_operand:DI 1 "reg_or_0_operand" "")
4157	 (match_operand:DI 2 "reg_or_0_operand" "")))]
4158  ""
4159{
4160  tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4161				      V8QImode, operands[1], operands[2], true);
4162  DONE;
4163})
4164
4165(define_expand "insn_v1<insn>i"
4166  [(set (match_operand:DI 0 "register_operand" "")
4167	(v1op_immed:V8QI
4168	 (match_operand:DI 1 "reg_or_0_operand" "")
4169	 (match_operand:DI 2 "s8bit_cint_operand" "")))]
4170  ""
4171{
4172  /* Tile out immediate and expand to general case. */
4173  rtx n = tilegx_simd_int (operands[2], QImode);
4174  tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4175				      V8QImode, operands[1], n, true);
4176  DONE;
4177})
4178
4179;; insn_v1shl
4180;; insn_v1shli
4181;; insn_v1shrs
4182;; insn_v1shrsi
4183;; insn_v1shru
4184;; insn_v1shrui
4185(define_insn "<optab>v8qi3"
4186  [(set (match_operand:V8QI 0 "register_operand" "=r,r")
4187	(any_shift:V8QI
4188	 (match_operand:V8QI 1 "reg_or_0_operand" "rO,rO")
4189	 (match_operand:DI 2 "reg_or_u5bit_operand" "I,rO")))]
4190  ""
4191  "@
4192   v1<insn>i\t%0, %r1, %2
4193   v1<insn>\t%0, %r1, %r2"
4194  [(set_attr "type" "<pipe>,<pipe>")])
4195
4196(define_expand "insn_v1<insn>"
4197  [(set (match_operand:DI 0 "register_operand" "")
4198	(any_shift:V8QI
4199	 (match_operand:DI 1 "reg_or_0_operand" "")
4200	 (match_operand:DI 2 "reg_or_u5bit_operand" "")))]
4201  ""
4202{
4203  tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4204				      V8QImode, operands[1], operands[2], false);
4205  DONE;
4206})
4207
4208;; insn_v2add
4209;; insn_v2addi
4210;; insn_v2maxs
4211;; insn_v2maxsi
4212;; insn_v2mins
4213;; insn_v2minsi
4214;; insn_v2cmpeq
4215;; insn_v2cmpeqi
4216;; insn_v2cmplts
4217;; insn_v2cmpltsi
4218;; insn_v2cmpltu
4219;; insn_v2cmpltui
4220(define_insn "<optab>v4hi3"
4221  [(set (match_operand:V4HI 0 "register_operand" "=r,r")
4222	(v2op_immed:V4HI
4223	 (match_operand:V4HI 1 "reg_or_0_operand" "<comm>rO,rO")
4224	 (match_operand:V4HI 2 "reg_or_v4s8bit_operand" "Y,rO")))]
4225  ""
4226  "@
4227   v2<insn>i\t%0, %r1, %j2
4228   v2<insn>\t%0, %r1, %r2"
4229  [(set_attr "type" "<pipe>,<pipe>")])
4230
4231(define_expand "insn_v2<insn>"
4232  [(set (match_operand:DI 0 "register_operand" "")
4233	(v2op_immed:V4HI
4234	 (match_operand:DI 1 "reg_or_0_operand" "")
4235	 (match_operand:DI 2 "reg_or_0_operand" "")))]
4236  ""
4237{
4238  tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4239				      V4HImode, operands[1], operands[2], true);
4240  DONE;
4241})
4242
4243(define_expand "insn_v2<insn>i"
4244  [(set (match_operand:DI 0 "register_operand" "")
4245	(v2op_immed:V4HI
4246	 (match_operand:DI 1 "reg_or_0_operand" "")
4247	 (match_operand:DI 2 "s8bit_cint_operand" "")))]
4248  ""
4249{
4250  /* Tile out immediate and expand to general case. */
4251  rtx n = tilegx_simd_int (operands[2], HImode);
4252  tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4253				      V4HImode, operands[1], n, true);
4254  DONE;
4255})
4256
4257;; insn_v2shl
4258;; insn_v2shli
4259;; insn_v2shrs
4260;; insn_v2shrsi
4261;; insn_v2shru
4262;; insn_v2shrui
4263(define_insn "<optab>v4hi3"
4264  [(set (match_operand:V4HI 0 "register_operand" "=r,r")
4265	(any_shift:V4HI
4266	 (match_operand:V4HI 1 "reg_or_0_operand" "rO,rO")
4267	 (match_operand:DI 2 "reg_or_u5bit_operand" "I,rO")))]
4268  ""
4269  "@
4270   v2<insn>i\t%0, %r1, %2
4271   v2<insn>\t%0, %r1, %r2"
4272  [(set_attr "type" "<pipe>,<pipe>")])
4273
4274(define_expand "insn_v2<insn>"
4275  [(set (match_operand:DI 0 "register_operand" "")
4276	(any_shift:V4HI
4277	 (match_operand:DI 1 "reg_or_0_operand" "")
4278	 (match_operand:DI 2 "reg_or_u5bit_operand" "")))]
4279  ""
4280{
4281  tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4282				      V4HImode, operands[1], operands[2], false);
4283  DONE;
4284})
4285
4286;; insn_v1adduc
4287;; insn_v1subuc
4288;; insn_v1sub
4289;; insn_v1cmpne
4290;; insn_v1cmples
4291;; insn_v1cmpleu
4292;; insn_v1multu
4293(define_insn "<optab>v8qi3"
4294  [(set (match_operand:V8QI 0 "register_operand" "=r")
4295	(v1op:V8QI
4296	 (match_operand:V8QI 1 "reg_or_0_operand" "<comm>rO")
4297	 (match_operand:V8QI 2 "reg_or_0_operand" "rO")))]
4298  ""
4299  "v1<insn>\t%0, %r1, %r2"
4300  [(set_attr "type" "<pipe>")])
4301
4302(define_expand "insn_v1<insn>"
4303  [(set (match_operand:DI 0 "register_operand" "")
4304	(v1op:V8QI
4305	 (match_operand:DI 1 "reg_or_0_operand" "")
4306	 (match_operand:DI 2 "reg_or_0_operand" "")))]
4307  ""
4308{
4309  tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4310				      V8QImode, operands[1], operands[2], true);
4311  DONE;
4312})
4313
4314;; insn_v2addsc
4315;; insn_v2subsc
4316;; insn_v2sub
4317;; insn_v2cmpne
4318;; insn_v2cmples
4319;; insn_v2cmpleu
4320(define_insn "<optab>v4hi3"
4321  [(set (match_operand:V4HI 0 "register_operand" "=r")
4322	(v2op:V4HI
4323	 (match_operand:V4HI 1 "reg_or_0_operand" "<comm>rO")
4324	 (match_operand:V4HI 2 "reg_or_0_operand" "rO")))]
4325  ""
4326  "v2<insn>\t%0, %r1, %r2"
4327  [(set_attr "type" "<pipe>")])
4328
4329(define_expand "insn_v2<insn>"
4330  [(set (match_operand:DI 0 "register_operand" "")
4331	(v2op:V4HI
4332	 (match_operand:DI 1 "reg_or_0_operand" "")
4333	 (match_operand:DI 2 "reg_or_0_operand" "")))]
4334  ""
4335{
4336  tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4337				      V4HImode, operands[1], operands[2], true);
4338  DONE;
4339})
4340
4341;; insn_v2mults
4342(define_insn "mulv4hi3"
4343  [(set (match_operand:V4HI 0 "register_operand" "=r")
4344	(mult:V4HI
4345	 (match_operand:V4HI 1 "reg_or_0_operand" "%rO")
4346	 (match_operand:V4HI 2 "reg_or_0_operand" "rO")))]
4347  ""
4348  "v2mults\t%0, %r1, %r2"
4349  [(set_attr "type" "X0_2cycle")])
4350
4351(define_expand "insn_v2mults"
4352  [(set (match_operand:DI 0 "register_operand" "")
4353	(mult:V4HI
4354	 (match_operand:DI 1 "reg_or_0_operand" "")
4355	 (match_operand:DI 2 "reg_or_0_operand" "")))]
4356  ""
4357{
4358  tilegx_expand_builtin_vector_binop (gen_mulv4hi3, V4HImode, operands[0],
4359				      V4HImode, operands[1], operands[2], true);
4360  DONE;
4361})
4362
4363;; insn_v2shlsc
4364(define_insn "<optab>v4hi3"
4365  [(set (match_operand:V4HI 0 "register_operand" "=r")
4366	(v2shift:V4HI
4367	 (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4368	 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
4369  ""
4370  "v2<insn>\t%0, %r1, %r2"
4371  [(set_attr "type" "<pipe>")])
4372
4373(define_expand "insn_v2<insn>"
4374  [(set (match_operand:DI 0 "register_operand" "")
4375	(v2shift:V4HI
4376	 (match_operand:DI 1 "reg_or_0_operand" "")
4377	 (match_operand:DI 2 "reg_or_0_operand" "")))]
4378  ""
4379{
4380  tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4381				      V4HImode, operands[1], operands[2], false);
4382  DONE;
4383})
4384
4385;; insn_v4addsc
4386;; insn_v4subsc
4387;; insn_v4add
4388;; insn_v4sub
4389(define_insn "<optab>v2si3"
4390  [(set (match_operand:V2SI 0 "register_operand" "=r")
4391	(v4op:V2SI
4392	 (match_operand:V2SI 1 "reg_or_0_operand" "<comm>rO")
4393	 (match_operand:V2SI 2 "reg_or_0_operand" "rO")))]
4394  ""
4395  "v4<insn>\t%0, %r1, %r2"
4396  [(set_attr "type" "<pipe>")])
4397
4398(define_expand "insn_v4<insn>"
4399  [(set (match_operand:DI 0 "register_operand" "")
4400	(v4op:V2SI
4401	 (match_operand:DI 1 "reg_or_0_operand" "")
4402	 (match_operand:DI 2 "reg_or_0_operand" "")))]
4403  ""
4404{
4405  tilegx_expand_builtin_vector_binop (gen_<optab>v2si3, V2SImode, operands[0],
4406				      V2SImode, operands[1], operands[2], true);
4407  DONE;
4408})
4409
4410;; insn_v4shl
4411;; insn_v4shrs
4412;; insn_v4shru
4413;; insn_v4shlsc
4414(define_insn "<optab>v2si3"
4415  [(set (match_operand:V2SI 0 "register_operand" "=r")
4416	(v4shift:V2SI
4417	 (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4418	 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
4419  ""
4420  "v4<insn>\t%0, %r1, %r2"
4421  [(set_attr "type" "<pipe>")])
4422
4423(define_expand "insn_v4<insn>"
4424  [(set (match_operand:DI 0 "register_operand" "")
4425	(v4shift:V2SI
4426	 (match_operand:DI 1 "reg_or_0_operand" "")
4427	 (match_operand:DI 2 "reg_or_0_operand" "")))]
4428  ""
4429{
4430  tilegx_expand_builtin_vector_binop (gen_<optab>v2si3, V2SImode, operands[0],
4431				      V2SImode, operands[1], operands[2], false);
4432  DONE;
4433})
4434
4435;; Byte ordering of these vectors is endian dependent.  gcc concats
4436;; right-to-left for little endian, and left-to-right for big endian.
4437;; So we need different patterns that depend on endianness.  Our
4438;; instructions concat and interleave the way a big-endian target would
4439;; work in gcc, so for little endian, we need to reverse the source
4440;; operands.
4441
4442;; insn_v1int_h
4443;;    {B7,B6,B5,B4,B3,B2,B1,B0} {A7,A6,A5,A4,A3,A2,A1,A0}
4444;; => {A7,A6,A5,A4,A3,A2,A1,A0,B7,B6,B5,B4,B3,B2,B1,B0}
4445;; => {A7,B7,A6,B6,A5,B5,A4,B4}
4446(define_expand "vec_interleave_highv8qi"
4447  [(match_operand:V8QI 0 "register_operand" "")
4448   (match_operand:V8QI 1 "reg_or_0_operand" "")
4449   (match_operand:V8QI 2 "reg_or_0_operand" "")]
4450  ""
4451{
4452  if (BYTES_BIG_ENDIAN)
4453    emit_insn (gen_vec_interleave_highv8qi_be (operands[0], operands[1],
4454					       operands[2]));
4455  else
4456    emit_insn (gen_vec_interleave_highv8qi_le (operands[0], operands[1],
4457					       operands[2]));
4458  DONE;
4459})
4460
4461(define_insn "vec_interleave_highv8qi_be"
4462  [(set (match_operand:V8QI 0 "register_operand" "=r")
4463	(vec_select:V8QI
4464	 (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4465			   (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4466	 (parallel [(const_int 0) (const_int 8)
4467		    (const_int 1) (const_int 9)
4468		    (const_int 2) (const_int 10)
4469		    (const_int 3) (const_int 11)])))]
4470  "BYTES_BIG_ENDIAN"
4471  "v1int_h\t%0, %r1, %r2"
4472  [(set_attr "type" "X01")])
4473
4474(define_insn "vec_interleave_highv8qi_le"
4475  [(set (match_operand:V8QI 0 "register_operand" "=r")
4476	(vec_select:V8QI
4477	 (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4478			   (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4479	 (parallel [(const_int 4) (const_int 12)
4480		    (const_int 5) (const_int 13)
4481		    (const_int 6) (const_int 14)
4482		    (const_int 7) (const_int 15)])))]
4483  "!BYTES_BIG_ENDIAN"
4484  "v1int_h\t%0, %r2, %r1"
4485  [(set_attr "type" "X01")])
4486
4487(define_expand "insn_v1int_h"
4488  [(match_operand:DI 0 "register_operand" "")
4489   (match_operand:DI 1 "reg_or_0_operand" "")
4490   (match_operand:DI 2 "reg_or_0_operand" "")]
4491  ""
4492{
4493  /* For little endian, our instruction interleaves opposite of the
4494     way vec_interleave works, so we need to reverse the source
4495     operands.  */
4496  rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4497  rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4498  tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv8qi, V8QImode,
4499				      operands[0], V8QImode, opnd1, opnd2,
4500				      true);
4501  DONE;
4502})
4503
4504;; insn_v1int_l
4505;;    {B7,B6,B5,B4,B3,B2,B1,B0} {A7,A6,A5,A4,A3,A2,A1,A0}
4506;; => {A7,A6,A5,A4,A3,A2,A1,A0,B7,B6,B5,B4,B3,B2,B1,B0}
4507;; => {A3,B3,A2,B2,A1,B1,A0,B0}
4508(define_expand "vec_interleave_lowv8qi"
4509  [(match_operand:V8QI 0 "register_operand" "")
4510   (match_operand:V8QI 1 "reg_or_0_operand" "")
4511   (match_operand:V8QI 2 "reg_or_0_operand" "")]
4512  ""
4513{
4514  if (BYTES_BIG_ENDIAN)
4515    emit_insn (gen_vec_interleave_lowv8qi_be (operands[0], operands[1],
4516					      operands[2]));
4517  else
4518    emit_insn (gen_vec_interleave_lowv8qi_le (operands[0], operands[1],
4519					      operands[2]));
4520  DONE;
4521})
4522
4523(define_insn "vec_interleave_lowv8qi_be"
4524  [(set (match_operand:V8QI 0 "register_operand" "=r")
4525	(vec_select:V8QI
4526	 (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4527			   (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4528	 (parallel [(const_int 4) (const_int 12)
4529		    (const_int 5) (const_int 13)
4530		    (const_int 6) (const_int 14)
4531		    (const_int 7) (const_int 15)])))]
4532  "BYTES_BIG_ENDIAN"
4533  "v1int_l\t%0, %r1, %r2"
4534  [(set_attr "type" "X01")])
4535
4536(define_insn "vec_interleave_lowv8qi_le"
4537  [(set (match_operand:V8QI 0 "register_operand" "=r")
4538	(vec_select:V8QI
4539	 (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4540			   (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4541	 (parallel [(const_int 0) (const_int 8)
4542		    (const_int 1) (const_int 9)
4543		    (const_int 2) (const_int 10)
4544		    (const_int 3) (const_int 11)])))]
4545  "!BYTES_BIG_ENDIAN"
4546  "v1int_l\t%0, %r2, %r1"
4547  [(set_attr "type" "X01")])
4548
4549(define_expand "insn_v1int_l"
4550  [(match_operand:DI 0 "register_operand" "")
4551   (match_operand:DI 1 "reg_or_0_operand" "")
4552   (match_operand:DI 2 "reg_or_0_operand" "")]
4553  ""
4554{
4555  /* For little endian, our instruction interleaves opposite of the
4556     way vec_interleave works, so we need to reverse the source
4557     operands.  */
4558  rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4559  rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4560  tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv8qi, V8QImode,
4561				      operands[0], V8QImode, opnd1, opnd2,
4562				      true);
4563  DONE;
4564})
4565
4566;; insn_v2int_h
4567;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
4568;; => {A3,A2,A1,A0,B3,B2,B1,B0}
4569;; => {A3,B3,A2,B2}
4570(define_expand "vec_interleave_highv4hi"
4571  [(match_operand:V4HI 0 "register_operand" "")
4572   (match_operand:V4HI 1 "reg_or_0_operand" "")
4573   (match_operand:V4HI 2 "reg_or_0_operand" "")]
4574  ""
4575{
4576  if (BYTES_BIG_ENDIAN)
4577    emit_insn (gen_vec_interleave_highv4hi_be (operands[0], operands[1],
4578					       operands[2]));
4579  else
4580    emit_insn (gen_vec_interleave_highv4hi_le (operands[0], operands[1],
4581					       operands[2]));
4582  DONE;
4583})
4584
4585(define_insn "vec_interleave_highv4hi_be"
4586  [(set (match_operand:V4HI 0 "register_operand" "=r")
4587	(vec_select:V4HI
4588	 (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4589			  (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4590	 (parallel [(const_int 0) (const_int 4)
4591		    (const_int 1) (const_int 5)])))]
4592  "BYTES_BIG_ENDIAN"
4593  "v2int_h\t%0, %r1, %r2"
4594  [(set_attr "type" "X01")])
4595
4596(define_insn "vec_interleave_highv4hi_le"
4597  [(set (match_operand:V4HI 0 "register_operand" "=r")
4598	(vec_select:V4HI
4599	 (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4600			  (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4601	 (parallel [(const_int 2) (const_int 6)
4602		    (const_int 3) (const_int 7)])))]
4603  "!BYTES_BIG_ENDIAN"
4604  "v2int_h\t%0, %r2, %r1"
4605  [(set_attr "type" "X01")])
4606
4607(define_expand "insn_v2int_h"
4608  [(match_operand:DI 0 "register_operand" "")
4609   (match_operand:DI 1 "reg_or_0_operand" "")
4610   (match_operand:DI 2 "reg_or_0_operand" "")]
4611  ""
4612{
4613  /* For little endian, our instruction interleaves opposite of the
4614     way vec_interleave works, so we need to reverse the source
4615     operands.  */
4616  rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4617  rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4618  tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv4hi, V4HImode,
4619                                      operands[0], V4HImode, opnd1, opnd2,
4620				      true);
4621  DONE;
4622})
4623
4624;; insn_v2int_l
4625;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
4626;; => {A3,A2,A1,A0,B3,B2,B1,B0}
4627;; => {A1,B1,A0,B0}
4628(define_expand "vec_interleave_lowv4hi"
4629  [(match_operand:V4HI 0 "register_operand" "")
4630   (match_operand:V4HI 1 "reg_or_0_operand" "")
4631   (match_operand:V4HI 2 "reg_or_0_operand" "")]
4632  ""
4633{
4634  if (BYTES_BIG_ENDIAN)
4635    emit_insn (gen_vec_interleave_lowv4hi_be (operands[0], operands[1],
4636					      operands[2]));
4637  else
4638    emit_insn (gen_vec_interleave_lowv4hi_le (operands[0], operands[1],
4639					      operands[2]));
4640  DONE;
4641})
4642
4643(define_insn "vec_interleave_lowv4hi_be"
4644  [(set (match_operand:V4HI 0 "register_operand" "=r")
4645	(vec_select:V4HI
4646	 (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4647			  (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4648	 (parallel [(const_int 2) (const_int 6)
4649		    (const_int 3) (const_int 7)])))]
4650  "BYTES_BIG_ENDIAN"
4651  "v2int_l\t%0, %r1, %r2"
4652  [(set_attr "type" "X01")])
4653
4654(define_insn "vec_interleave_lowv4hi_le"
4655  [(set (match_operand:V4HI 0 "register_operand" "=r")
4656	(vec_select:V4HI
4657	 (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4658			  (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4659	 (parallel [(const_int 0) (const_int 4)
4660		    (const_int 1) (const_int 5)])))]
4661  "!BYTES_BIG_ENDIAN"
4662  "v2int_l\t%0, %r2, %r1"
4663  [(set_attr "type" "X01")])
4664
4665(define_expand "insn_v2int_l"
4666  [(match_operand:DI 0 "register_operand" "")
4667   (match_operand:DI 1 "reg_or_0_operand" "")
4668   (match_operand:DI 2 "reg_or_0_operand" "")]
4669  ""
4670{
4671  /* For little endian, our instruction interleaves opposite of the
4672     way vec_interleave works, so we need to reverse the source
4673     operands.  */
4674  rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4675  rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4676  tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv4hi, V4HImode,
4677                                      operands[0], V4HImode, opnd1, opnd2,
4678				      true);
4679  DONE;
4680})
4681
4682;; insn_v4int_h
4683;;    {B1,B0} {A1,A0}
4684;; => {A1,A0,B1,B0}
4685;; => {A1,B1}
4686(define_expand "vec_interleave_highv2si"
4687  [(match_operand:V2SI 0 "register_operand" "")
4688   (match_operand:V2SI 1 "reg_or_0_operand" "")
4689   (match_operand:V2SI 2 "reg_or_0_operand" "")]
4690  ""
4691{
4692  if (BYTES_BIG_ENDIAN)
4693    emit_insn (gen_vec_interleave_highv2si_be (operands[0], operands[1],
4694					       operands[2]));
4695  else
4696    emit_insn (gen_vec_interleave_highv2si_le (operands[0], operands[1],
4697					       operands[2]));
4698  DONE;
4699})
4700
4701(define_insn "vec_interleave_highv2si_be"
4702  [(set (match_operand:V2SI 0 "register_operand" "=r")
4703	(vec_select:V2SI
4704	 (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4705			  (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4706	 (parallel [(const_int 0) (const_int 2)])))]
4707  "BYTES_BIG_ENDIAN"
4708  "v4int_h\t%0, %r1, %r2"
4709  [(set_attr "type" "X01")])
4710
4711(define_insn "vec_interleave_highv2si_le"
4712  [(set (match_operand:V2SI 0 "register_operand" "=r")
4713	(vec_select:V2SI
4714	 (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4715			  (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4716	 (parallel [(const_int 1) (const_int 3)])))]
4717  "!BYTES_BIG_ENDIAN"
4718  "v4int_h\t%0, %r2, %r1"
4719  [(set_attr "type" "X01")])
4720
4721(define_expand "insn_v4int_h"
4722  [(match_operand:DI 0 "register_operand" "")
4723   (match_operand:DI 1 "reg_or_0_operand" "")
4724   (match_operand:DI 2 "reg_or_0_operand" "")]
4725  ""
4726{
4727  /* For little endian, our instruction interleaves opposite of the
4728     way vec_interleave works, so we need to reverse the source
4729     operands.  */
4730  rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4731  rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4732  tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv2si, V2SImode,
4733                                      operands[0], V2SImode, opnd1, opnd2,
4734				      true);
4735  DONE;
4736})
4737
4738;; insn_v4int_l
4739;;    {B1,B0} {A1,A0}
4740;; => {A1,A0,B1,B0}
4741;; => {A0,B0}
4742(define_expand "vec_interleave_lowv2si"
4743  [(match_operand:V2SI 0 "register_operand" "")
4744   (match_operand:V2SI 1 "reg_or_0_operand" "")
4745   (match_operand:V2SI 2 "reg_or_0_operand" "")]
4746  ""
4747{
4748  if (BYTES_BIG_ENDIAN)
4749    emit_insn (gen_vec_interleave_lowv2si_be (operands[0], operands[1],
4750					      operands[2]));
4751  else
4752    emit_insn (gen_vec_interleave_lowv2si_le (operands[0], operands[1],
4753					      operands[2]));
4754  DONE;
4755})
4756
4757(define_insn "vec_interleave_lowv2si_be"
4758  [(set (match_operand:V2SI 0 "register_operand" "=r")
4759	(vec_select:V2SI
4760	 (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4761			  (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4762	 (parallel [(const_int 1) (const_int 3)])))]
4763  "BYTES_BIG_ENDIAN"
4764  "v4int_l\t%0, %r1, %r2"
4765  [(set_attr "type" "X01")])
4766
4767(define_insn "vec_interleave_lowv2si_le"
4768  [(set (match_operand:V2SI 0 "register_operand" "=r")
4769	(vec_select:V2SI
4770	 (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4771			  (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4772	 (parallel [(const_int 0) (const_int 2)])))]
4773  "!BYTES_BIG_ENDIAN"
4774  "v4int_l\t%0, %r2, %r1"
4775  [(set_attr "type" "X01")])
4776
4777(define_expand "insn_v4int_l"
4778  [(match_operand:DI 0 "register_operand" "")
4779   (match_operand:DI 1 "reg_or_0_operand" "")
4780   (match_operand:DI 2 "reg_or_0_operand" "")]
4781  ""
4782{
4783  /* For little endian, our instruction interleaves opposite of the
4784     way vec_interleave works, so we need to reverse the source
4785     operands.  */
4786  rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4787  rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4788  tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv2si, V2SImode,
4789                                      operands[0], V2SImode, opnd1, opnd2,
4790				      true);
4791  DONE;
4792})
4793
4794;; insn_v1mnz
4795;; insn_v1mz
4796;; insn_v2mnz
4797;; insn_v2mz
4798(define_insn "insn_mnz_v8qi"
4799  [(set (match_operand:V8QI 0 "register_operand" "=r")
4800	(if_then_else:V8QI
4801         (ne:V8QI
4802	  (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4803	  (const_vector:V8QI [(const_int 0) (const_int 0)
4804			      (const_int 0) (const_int 0)
4805			      (const_int 0) (const_int 0)
4806			      (const_int 0) (const_int 0)]))
4807         (match_operand:V8QI 2 "reg_or_0_operand" "rO")
4808	 (const_vector:V8QI [(const_int 0) (const_int 0)
4809			     (const_int 0) (const_int 0)
4810			     (const_int 0) (const_int 0)
4811			     (const_int 0) (const_int 0)])))]
4812  ""
4813  "v1mnz\t%0, %r1, %r2"
4814  [(set_attr "type" "X01")])
4815
4816(define_expand "insn_v1mnz"
4817  [(set (match_operand:DI 0 "register_operand" "")
4818	(if_then_else:V8QI
4819         (ne:V8QI
4820	  (match_operand:DI 1 "reg_or_0_operand" "")
4821	  (const_vector:V8QI [(const_int 0) (const_int 0)
4822			      (const_int 0) (const_int 0)
4823			      (const_int 0) (const_int 0)
4824			      (const_int 0) (const_int 0)])
4825	  )
4826         (match_operand:DI 2 "reg_or_0_operand" "")
4827	 (const_vector:V8QI [(const_int 0) (const_int 0)
4828			     (const_int 0) (const_int 0)
4829			     (const_int 0) (const_int 0)
4830			     (const_int 0) (const_int 0)])))]
4831  ""
4832{
4833  tilegx_expand_builtin_vector_binop (gen_insn_mnz_v8qi, V8QImode,
4834                                      operands[0], V8QImode, operands[1],
4835				      operands[2], true);
4836  DONE;
4837})
4838
4839(define_insn "insn_mz_v8qi"
4840  [(set (match_operand:V8QI 0 "register_operand" "=r")
4841	(if_then_else:V8QI
4842         (ne:V8QI
4843	  (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4844	  (const_vector:V8QI [(const_int 0) (const_int 0)
4845			      (const_int 0) (const_int 0)
4846			      (const_int 0) (const_int 0)
4847			      (const_int 0) (const_int 0)]))
4848	 (const_vector:V8QI [(const_int 0) (const_int 0)
4849			     (const_int 0) (const_int 0)
4850			     (const_int 0) (const_int 0)
4851			     (const_int 0) (const_int 0)])
4852         (match_operand:V8QI 2 "reg_or_0_operand" "rO")))]
4853  ""
4854  "v1mz\t%0, %r1, %r2"
4855  [(set_attr "type" "X01")])
4856
4857(define_expand "insn_v1mz"
4858  [(set (match_operand:DI 0 "register_operand" "")
4859	(if_then_else:V8QI
4860         (ne:V8QI
4861	  (match_operand:DI 1 "reg_or_0_operand" "")
4862	  (const_vector:V8QI [(const_int 0) (const_int 0)
4863			      (const_int 0) (const_int 0)
4864			      (const_int 0) (const_int 0)
4865			      (const_int 0) (const_int 0)]))
4866	 (const_vector:V8QI [(const_int 0) (const_int 0)
4867			      (const_int 0) (const_int 0)
4868			      (const_int 0) (const_int 0)
4869			      (const_int 0) (const_int 0)])
4870         (match_operand:DI 2 "reg_or_0_operand" "")))]
4871  ""
4872{
4873  tilegx_expand_builtin_vector_binop (gen_insn_mz_v8qi, V8QImode,
4874                                      operands[0], V8QImode, operands[1],
4875				      operands[2], true);
4876  DONE;
4877})
4878
4879(define_insn "insn_mnz_v4hi"
4880  [(set (match_operand:V4HI 0 "register_operand" "=r")
4881	(if_then_else:V4HI
4882         (ne:V4HI
4883	  (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4884	  (const_vector:V4HI [(const_int 0) (const_int 0)
4885			      (const_int 0) (const_int 0)]))
4886         (match_operand:V4HI 2 "reg_or_0_operand" "rO")
4887	 (const_vector:V4HI [(const_int 0) (const_int 0)
4888			     (const_int 0) (const_int 0)])))]
4889  ""
4890  "v2mnz\t%0, %r1, %r2"
4891  [(set_attr "type" "X01")])
4892
4893(define_expand "insn_v2mnz"
4894  [(set (match_operand:DI 0 "register_operand" "")
4895	(if_then_else:V4HI
4896         (ne:V4HI
4897	  (match_operand:DI 1 "reg_or_0_operand" "")
4898	  (const_vector:V4HI [(const_int 0) (const_int 0)
4899			      (const_int 0) (const_int 0)]))
4900         (match_operand:DI 2 "reg_or_0_operand" "")
4901	 (const_vector:V4HI [(const_int 0) (const_int 0)
4902			     (const_int 0) (const_int 0)])))]
4903  ""
4904{
4905  tilegx_expand_builtin_vector_binop (gen_insn_mnz_v4hi, V4HImode,
4906                                      operands[0], V4HImode, operands[1],
4907				      operands[2], true);
4908  DONE;
4909})
4910
4911(define_insn "insn_mz_v4hi"
4912  [(set (match_operand:V4HI 0 "register_operand" "=r")
4913	(if_then_else:V4HI
4914         (ne:V4HI
4915	  (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4916	  (const_vector:V4HI [(const_int 0) (const_int 0)
4917			      (const_int 0) (const_int 0)]))
4918	 (const_vector:V4HI [(const_int 0) (const_int 0)
4919			     (const_int 0) (const_int 0)])
4920         (match_operand:V4HI 2 "reg_or_0_operand" "rO")))]
4921  ""
4922  "v2mz\t%0, %r1, %r2"
4923  [(set_attr "type" "X01")])
4924
4925(define_expand "insn_v2mz"
4926  [(set (match_operand:DI 0 "register_operand" "")
4927	(if_then_else:V4HI
4928         (ne:V4HI
4929	  (match_operand:DI 1 "reg_or_0_operand" "")
4930	  (const_vector:V4HI [(const_int 0) (const_int 0)
4931			      (const_int 0) (const_int 0)]))
4932	 (const_vector:V4HI [(const_int 0) (const_int 0)
4933			      (const_int 0) (const_int 0)])
4934         (match_operand:DI 2 "reg_or_0_operand" "")))]
4935  ""
4936{
4937  tilegx_expand_builtin_vector_binop (gen_insn_mz_v4hi, V4HImode,
4938                                      operands[0], V4HImode, operands[1],
4939				      operands[2], true);
4940  DONE;
4941})
4942
4943;; insn_v1mulu
4944(define_insn "vec_widen_umult_lo_v8qi"
4945  [(set (match_operand:V4HI 0 "register_operand" "=r")
4946        (mult:V4HI
4947	 (zero_extend:V4HI
4948	  (vec_select:V4QI
4949	   (match_operand:V8QI 1 "register_operand" "r")
4950	   (parallel [(const_int 0) (const_int 1)
4951		      (const_int 2) (const_int 3)])))
4952	 (zero_extend:V4HI
4953	  (vec_select:V4QI
4954	   (match_operand:V8QI 2 "register_operand" "r")
4955	   (parallel [(const_int 0) (const_int 1)
4956		      (const_int 2) (const_int 3)])))))]
4957  ""
4958  "v1mulu\t%0, %r1, %r2"
4959  [(set_attr "type" "X0_2cycle")])
4960
4961(define_expand "insn_v1mulu"
4962  [(match_operand:DI 0 "register_operand" "")
4963   (match_operand:DI 1 "register_operand" "")
4964   (match_operand:DI 2 "register_operand" "")]
4965  ""
4966{
4967  tilegx_expand_builtin_vector_binop (gen_vec_widen_umult_lo_v8qi, V4HImode,
4968                                      operands[0], V8QImode, operands[1],
4969				      operands[2], true);
4970  DONE;
4971})
4972
4973;; insn_v1mulus
4974(define_insn "vec_widen_usmult_lo_v8qi"
4975  [(set (match_operand:V4HI 0 "register_operand" "=r")
4976        (mult:V4HI
4977	 (zero_extend:V4HI
4978	  (vec_select:V4QI
4979	   (match_operand:V8QI 1 "register_operand" "r")
4980	   (parallel [(const_int 0) (const_int 1)
4981		      (const_int 2) (const_int 3)])))
4982	 (sign_extend:V4HI
4983	  (vec_select:V4QI
4984	   (match_operand:V8QI 2 "register_operand" "r")
4985	   (parallel [(const_int 0) (const_int 1)
4986		      (const_int 2) (const_int 3)])))))]
4987  ""
4988  "v1mulus\t%0, %r1, %r2"
4989  [(set_attr "type" "X0_2cycle")])
4990
4991(define_expand "insn_v1mulus"
4992  [(match_operand:DI 0 "register_operand" "")
4993   (match_operand:DI 1 "register_operand" "")
4994   (match_operand:DI 2 "register_operand" "")]
4995  ""
4996{
4997  tilegx_expand_builtin_vector_binop (gen_vec_widen_usmult_lo_v8qi, V4HImode,
4998                                      operands[0], V8QImode, operands[1],
4999				      operands[2], true);
5000  DONE;
5001})
5002
5003;; insn_v2muls
5004(define_insn "vec_widen_smult_lo_v4qi"
5005  [(set (match_operand:V2SI 0 "register_operand" "=r")
5006        (mult:V2SI
5007	 (sign_extend:V2SI
5008	  (vec_select:V2HI
5009	   (match_operand:V4HI 1 "register_operand" "r")
5010	   (parallel [(const_int 0) (const_int 1)])))
5011	 (sign_extend:V2SI
5012	  (vec_select:V2HI
5013	   (match_operand:V4HI 2 "register_operand" "r")
5014	   (parallel [(const_int 0) (const_int 1)])))))]
5015  ""
5016  "v2muls\t%0, %r1, %r2"
5017  [(set_attr "type" "X0_2cycle")])
5018
5019(define_expand "insn_v2muls"
5020  [(match_operand:DI 0 "register_operand" "")
5021   (match_operand:DI 1 "register_operand" "")
5022   (match_operand:DI 2 "register_operand" "")]
5023  ""
5024{
5025  tilegx_expand_builtin_vector_binop (gen_vec_widen_smult_lo_v4qi, V2SImode,
5026                                      operands[0], V4HImode, operands[1],
5027				      operands[2], true);
5028  DONE;
5029})
5030
5031;; v2packl
5032;; v2packuc
5033;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
5034;; => {A3,A2,A1,A0,B3,B2,B1,B0}
5035(define_insn "vec_pack_<pack_optab>_v4hi"
5036  [(set (match_operand:V8QI 0 "register_operand" "=r")
5037	(vec_concat:V8QI
5038	 (v2pack:V4QI (match_operand:V4HI 1 "reg_or_0_operand" "rO"))
5039	 (v2pack:V4QI (match_operand:V4HI 2 "reg_or_0_operand" "rO"))))]
5040  ""
5041  "v2<pack_insn>\t%0, %r2, %r1"
5042  [(set_attr "type" "X01")])
5043
5044(define_expand "insn_v2<pack_insn>"
5045  [(set (match_operand:DI 0 "register_operand" "")
5046	(vec_concat:V8QI
5047	 (v2pack:V4QI (match_operand:DI 2 "reg_or_0_operand" ""))
5048	 (v2pack:V4QI (match_operand:DI 1 "reg_or_0_operand" ""))))]
5049  ""
5050{
5051  /* Our instruction concats opposite of the way vec_pack works, so we
5052     need to reverse the source operands.  */
5053  tilegx_expand_builtin_vector_binop (gen_vec_pack_<pack_optab>_v4hi,
5054				      V8QImode, operands[0], V4HImode,
5055				      operands[2], operands[1], true);
5056  DONE;
5057})
5058
5059;; v2packh
5060;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
5061;; => {A3_hi,A2_hi,A1_hi,A0_hi,B3_hi,B2_hi,B1_hi,B0_hi}
5062(define_insn "vec_pack_hipart_v4hi"
5063  [(set (match_operand:V8QI 0 "register_operand" "=r")
5064	(vec_concat:V8QI
5065	 (truncate:V4QI
5066	  (ashiftrt:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
5067			 (const_int 8)))
5068	 (truncate:V4QI
5069	  (ashiftrt:V4HI (match_operand:V4HI 2 "reg_or_0_operand" "rO")
5070			 (const_int 8)))))]
5071  ""
5072  "v2packh\t%0, %r2, %r1"
5073  [(set_attr "type" "X01")])
5074
5075(define_expand "insn_v2packh"
5076  [(set (match_operand:DI 0 "register_operand" "")
5077	(vec_concat:V8QI
5078	 (truncate:V4QI
5079	  (ashiftrt:V4HI (match_operand:DI 2 "reg_or_0_operand" "")
5080			 (const_int 8)))
5081	 (truncate:V4QI
5082	  (ashiftrt:V4HI (match_operand:DI 1 "reg_or_0_operand" "")
5083			 (const_int 8)))))]
5084  ""
5085{
5086  /* Our instruction concats opposite of the way vec_pack works, so we
5087     need to reverse the source operands.  */
5088  tilegx_expand_builtin_vector_binop (gen_vec_pack_hipart_v4hi, V8QImode,
5089                                      operands[0], V4HImode, operands[2],
5090				      operands[1], true);
5091  DONE;
5092})
5093
5094;; v4packsc
5095;;    {B1,B0} {A1,A0}
5096;; => {A1,A0,B1,B0}
5097(define_insn "vec_pack_ssat_v2si"
5098  [(set (match_operand:V4HI 0 "register_operand" "=r")
5099	(vec_concat:V4HI
5100	 (us_truncate:V2HI (match_operand:V2SI 1 "reg_or_0_operand" "rO"))
5101	 (us_truncate:V2HI (match_operand:V2SI 2 "reg_or_0_operand" "rO"))))]
5102  ""
5103  "v4packsc\t%0, %r2, %r1"
5104  [(set_attr "type" "X01")])
5105
5106(define_expand "insn_v4packsc"
5107  [(set (match_operand:DI 0 "register_operand" "")
5108	(vec_concat:V4HI
5109	 (us_truncate:V2HI (match_operand:DI 2 "reg_or_0_operand" ""))
5110	 (us_truncate:V2HI (match_operand:DI 1 "reg_or_0_operand" ""))))]
5111  ""
5112{
5113  /* Our instruction concats opposite of the way vec_pack works, so we
5114     need to reverse the source operands.  */
5115  tilegx_expand_builtin_vector_binop (gen_vec_pack_ssat_v2si, V4HImode,
5116                                      operands[0], V2SImode, operands[2],
5117				      operands[1], true);
5118  DONE;
5119})
5120
5121;; Rest of the vector intrinsics
5122(define_insn "insn_v1adiffu"
5123  [(set (match_operand:DI 0 "register_operand" "=r")
5124        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5125                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5126                   UNSPEC_INSN_V1ADIFFU))]
5127  ""
5128  "v1adiffu\t%0, %r1, %r2"
5129  [(set_attr "type" "X0_2cycle")])
5130
5131(define_insn "insn_v1avgu"
5132  [(set (match_operand:DI 0 "register_operand" "=r")
5133        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5134                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5135                   UNSPEC_INSN_V1AVGU))]
5136  ""
5137  "v1avgu\t%0, %r1, %r2"
5138  [(set_attr "type" "X0")])
5139
5140(define_insn "insn_v1ddotpu"
5141  [(set (match_operand:DI 0 "register_operand" "=r")
5142        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5143                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5144                   UNSPEC_INSN_V1DDOTPU))]
5145  ""
5146  "v1ddotpu\t%0, %r1, %r2"
5147  [(set_attr "type" "X0_2cycle")])
5148
5149(define_insn "insn_v1ddotpua"
5150  [(set (match_operand:DI 0 "register_operand" "=r")
5151        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5152                    (match_operand:DI 2 "reg_or_0_operand" "rO")
5153                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
5154                   UNSPEC_INSN_V1DDOTPUA))]
5155  ""
5156  "v1ddotpua\t%0, %r2, %r3"
5157  [(set_attr "type" "X0_2cycle")])
5158
5159(define_insn "insn_v1ddotpus"
5160  [(set (match_operand:DI 0 "register_operand" "=r")
5161        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5162                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5163                   UNSPEC_INSN_V1DDOTPUS))]
5164  ""
5165  "v1ddotpus\t%0, %r1, %r2"
5166  [(set_attr "type" "X0_2cycle")])
5167
5168(define_insn "insn_v1ddotpusa"
5169  [(set (match_operand:DI 0 "register_operand" "=r")
5170        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5171                    (match_operand:DI 2 "reg_or_0_operand" "rO")
5172                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
5173                   UNSPEC_INSN_V1DDOTPUSA))]
5174  ""
5175  "v1ddotpusa\t%0, %r2, %r3"
5176  [(set_attr "type" "X0_2cycle")])
5177
5178(define_insn "insn_v1dotp"
5179  [(set (match_operand:DI 0 "register_operand" "=r")
5180        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5181                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5182                   UNSPEC_INSN_V1DOTP))]
5183  ""
5184  "v1dotp\t%0, %r1, %r2"
5185  [(set_attr "type" "X0_2cycle")])
5186
5187(define_insn "insn_v1dotpa"
5188  [(set (match_operand:DI 0 "register_operand" "=r")
5189        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5190                    (match_operand:DI 2 "reg_or_0_operand" "rO")
5191                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
5192                   UNSPEC_INSN_V1DOTPA))]
5193  ""
5194  "v1dotpa\t%0, %r2, %r3"
5195  [(set_attr "type" "X0_2cycle")])
5196
5197(define_insn "insn_v1dotpu"
5198  [(set (match_operand:DI 0 "register_operand" "=r")
5199        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5200                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5201                   UNSPEC_INSN_V1DOTPU))]
5202  ""
5203  "v1dotpu\t%0, %r1, %r2"
5204  [(set_attr "type" "X0_2cycle")])
5205
5206(define_insn "insn_v1dotpua"
5207  [(set (match_operand:DI 0 "register_operand" "=r")
5208        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5209                    (match_operand:DI 2 "reg_or_0_operand" "rO")
5210                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
5211                   UNSPEC_INSN_V1DOTPUA))]
5212  ""
5213  "v1dotpua\t%0, %r2, %r3"
5214  [(set_attr "type" "X0_2cycle")])
5215
5216(define_insn "insn_v1dotpus"
5217  [(set (match_operand:DI 0 "register_operand" "=r")
5218        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5219                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5220                   UNSPEC_INSN_V1DOTPUS))]
5221  ""
5222  "v1dotpus\t%0, %r1, %r2"
5223  [(set_attr "type" "X0_2cycle")])
5224
5225(define_insn "insn_v1dotpusa"
5226  [(set (match_operand:DI 0 "register_operand" "=r")
5227        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5228                    (match_operand:DI 2 "reg_or_0_operand" "rO")
5229                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
5230                   UNSPEC_INSN_V1DOTPUSA))]
5231  ""
5232  "v1dotpusa\t%0, %r2, %r3"
5233  [(set_attr "type" "X0_2cycle")])
5234
5235(define_insn "insn_v1sadau"
5236  [(set (match_operand:DI 0 "register_operand" "=r")
5237        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5238                    (match_operand:DI 2 "reg_or_0_operand" "rO")
5239                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
5240                   UNSPEC_INSN_V1SADAU))]
5241  ""
5242  "v1sadau\t%0, %r2, %r3"
5243  [(set_attr "type" "X0_2cycle")])
5244
5245(define_insn "insn_v1sadu"
5246  [(set (match_operand:DI 0 "register_operand" "=r")
5247        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5248                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5249                   UNSPEC_INSN_V1SADU))]
5250  ""
5251  "v1sadu\t%0, %r1, %r2"
5252  [(set_attr "type" "X0_2cycle")])
5253
5254(define_insn "*insn_v1sadu"
5255  [(set (match_operand:SI 0 "register_operand" "=r")
5256	(truncate:SI
5257	 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5258		     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5259		    UNSPEC_INSN_V1SADU)))]
5260   ""
5261  "v1sadu\t%0, %r1, %r2"
5262  [(set_attr "type" "X0_2cycle")])
5263
5264(define_insn "insn_v2adiffs"
5265  [(set (match_operand:DI 0 "register_operand" "=r")
5266        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5267                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5268                   UNSPEC_INSN_V2ADIFFS))]
5269  ""
5270  "v2adiffs\t%0, %r1, %r2"
5271  [(set_attr "type" "X0_2cycle")])
5272
5273(define_insn "insn_v2avgs"
5274  [(set (match_operand:DI 0 "register_operand" "=r")
5275        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5276                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5277                   UNSPEC_INSN_V2AVGS))]
5278  ""
5279  "v2avgs\t%0, %r1, %r2"
5280  [(set_attr "type" "X0")])
5281
5282(define_insn "insn_v2dotp"
5283  [(set (match_operand:DI 0 "register_operand" "=r")
5284        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5285                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5286                   UNSPEC_INSN_V2DOTP))]
5287  ""
5288  "v2dotp\t%0, %r1, %r2"
5289  [(set_attr "type" "X0_2cycle")])
5290
5291(define_insn "insn_v2dotpa"
5292  [(set (match_operand:DI 0 "register_operand" "=r")
5293        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5294                    (match_operand:DI 2 "reg_or_0_operand" "rO")
5295                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
5296                   UNSPEC_INSN_V2DOTPA))]
5297  ""
5298  "v2dotpa\t%0, %r2, %r3"
5299  [(set_attr "type" "X0_2cycle")])
5300
5301(define_insn "insn_v2mulfsc"
5302  [(set (match_operand:DI 0 "register_operand" "=r")
5303        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5304                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5305                   UNSPEC_INSN_V2MULFSC))]
5306  ""
5307  "v2mulfsc\t%0, %r1, %r2"
5308  [(set_attr "type" "X0_2cycle")])
5309
5310(define_insn "insn_v2sadas"
5311  [(set (match_operand:DI 0 "register_operand" "=r")
5312        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5313                    (match_operand:DI 2 "reg_or_0_operand" "rO")
5314                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
5315                   UNSPEC_INSN_V2SADAS))]
5316  ""
5317  "v2sadas\t%0, %r2, %r3"
5318  [(set_attr "type" "X0_2cycle")])
5319
5320(define_insn "insn_v2sadau"
5321  [(set (match_operand:DI 0 "register_operand" "=r")
5322        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5323                    (match_operand:DI 2 "reg_or_0_operand" "rO")
5324                    (match_operand:DI 3 "reg_or_0_operand" "rO")]
5325                   UNSPEC_INSN_V2SADAU))]
5326  ""
5327  "v2sadau\t%0, %r2, %r3"
5328  [(set_attr "type" "X0_2cycle")])
5329
5330(define_insn "insn_v2sads"
5331  [(set (match_operand:DI 0 "register_operand" "=r")
5332        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5333                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5334                   UNSPEC_INSN_V2SADS))]
5335  ""
5336  "v2sads\t%0, %r1, %r2"
5337  [(set_attr "type" "X0_2cycle")])
5338
5339(define_insn "*insn_v2sads"
5340  [(set (match_operand:SI 0 "register_operand" "=r")
5341	(truncate:SI
5342	 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5343		     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5344		    UNSPEC_INSN_V2SADS)))]
5345  ""
5346  "v2sads\t%0, %r1, %r2"
5347  [(set_attr "type" "X0_2cycle")])
5348
5349(define_insn "insn_v2sadu"
5350  [(set (match_operand:DI 0 "register_operand" "=r")
5351        (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5352                    (match_operand:DI 2 "reg_or_0_operand" "rO")]
5353                   UNSPEC_INSN_V2SADU))]
5354  ""
5355  "v2sadu\t%0, %r1, %r2"
5356  [(set_attr "type" "X0_2cycle")])
5357
5358(define_insn "*insn_v2sadu"
5359  [(set (match_operand:SI 0 "register_operand" "=r")
5360	(truncate:SI
5361	 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5362		     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5363		    UNSPEC_INSN_V2SADU)))]
5364  ""
5365  "v2sadu\t%0, %r1, %r2"
5366  [(set_attr "type" "X0_2cycle")])
5367
5368(define_insn "insn_wh64"
5369  [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
5370                         UNSPEC_INSN_WH64)
5371   (clobber (mem:BLK (const_int 0)))]
5372  ""
5373  "wh64\t%r0"
5374  [(set_attr "type" "X1")])
5375
5376
5377;; Network intrinsics
5378
5379;; Note the this barrier is of type "nothing," which is deleted after
5380;; the final scheduling pass so that nothing is emitted for it.
5381(define_insn "tilegx_network_barrier"
5382  [(unspec_volatile:SI [(const_int 0)] UNSPEC_NETWORK_BARRIER)]
5383  ""
5384  "pseudo"
5385  [(set_attr "type" "nothing")
5386   (set_attr "length" "0")])
5387
5388(define_insn "*netreg_receive"
5389  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,U,m")
5390        (unspec_volatile:DI [(match_operand:DI 1 "netreg_operand" "i,i,i")
5391			     (reg:DI TILEGX_NETORDER_REG)]
5392                            UNSPEC_NETWORK_RECEIVE))
5393   (clobber (reg:DI TILEGX_NETORDER_REG))]
5394
5395  ""
5396  "@
5397   move\t%0, %N1
5398   st\t%0, %N1
5399   st_add\t%I0, %N1, %i0"
5400  [(set_attr "type" "*,Y2,X1")])
5401
5402(define_insn "*netreg_send"
5403  [(unspec_volatile:DI
5404    [(match_operand:DI 0 "netreg_operand"  "i,i,i,i,i,i")
5405     (match_operand:DI 1 "reg_or_cint_operand" "r,I,J,K,N,P")
5406     (reg:DI TILEGX_NETORDER_REG)]
5407     UNSPEC_NETWORK_SEND)
5408   (clobber (reg:DI TILEGX_NETORDER_REG))]
5409  ""
5410  "@
5411   move\t%N0, %r1
5412   movei\t%N0, %1
5413   moveli\t%N0, %1
5414   shl16insli\t%N0, zero, %h1
5415   v1addi\t%N0, zero, %j1
5416   v2addi\t%N0, zero, %h1"
5417  [(set_attr "type" "*,*,X01,X01,X01,X01")])
5418
5419(define_expand "tilegx_idn0_receive"
5420  [(parallel
5421    [(set (match_operand:DI 0 "register_operand" "")
5422	  (unspec_volatile:DI [(const_int TILEGX_NETREG_IDN0)
5423			       (reg:DI TILEGX_NETORDER_REG)]
5424			      UNSPEC_NETWORK_RECEIVE))
5425     (clobber (reg:DI TILEGX_NETORDER_REG))])]
5426  "")
5427
5428(define_expand "tilegx_idn1_receive"
5429  [(parallel
5430    [(set (match_operand:DI 0 "register_operand" "")
5431	  (unspec_volatile:DI [(const_int TILEGX_NETREG_IDN1)
5432			       (reg:DI TILEGX_NETORDER_REG)]
5433			      UNSPEC_NETWORK_RECEIVE))
5434     (clobber (reg:DI TILEGX_NETORDER_REG))])]
5435  "")
5436
5437(define_expand "tilegx_idn_send"
5438  [(parallel
5439    [(unspec_volatile:DI [(const_int TILEGX_NETREG_IDN0)
5440			  (match_operand:DI 0 "reg_or_cint_operand" "")
5441			  (reg:DI TILEGX_NETORDER_REG)]
5442			 UNSPEC_NETWORK_SEND)
5443     (clobber (reg:DI TILEGX_NETORDER_REG))])]
5444  "")
5445
5446(define_expand "tilegx_udn0_receive"
5447  [(parallel
5448    [(set (match_operand:DI 0 "register_operand" "")
5449	  (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN0)
5450			       (reg:DI TILEGX_NETORDER_REG)]
5451			      UNSPEC_NETWORK_RECEIVE))
5452     (clobber (reg:DI TILEGX_NETORDER_REG))])]
5453  "")
5454
5455(define_expand "tilegx_udn1_receive"
5456  [(parallel
5457    [(set (match_operand:DI 0 "register_operand" "")
5458	  (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN1)
5459			       (reg:DI TILEGX_NETORDER_REG)]
5460			      UNSPEC_NETWORK_RECEIVE))
5461     (clobber (reg:DI TILEGX_NETORDER_REG))])]
5462  "")
5463
5464(define_expand "tilegx_udn2_receive"
5465  [(parallel
5466    [(set (match_operand:DI 0 "register_operand" "")
5467	  (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN2)
5468			       (reg:DI TILEGX_NETORDER_REG)]
5469			      UNSPEC_NETWORK_RECEIVE))
5470     (clobber (reg:DI TILEGX_NETORDER_REG))])]
5471  "")
5472
5473(define_expand "tilegx_udn3_receive"
5474  [(parallel
5475    [(set (match_operand:DI 0 "register_operand" "")
5476	  (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN3)
5477			       (reg:DI TILEGX_NETORDER_REG)]
5478			      UNSPEC_NETWORK_RECEIVE))
5479     (clobber (reg:DI TILEGX_NETORDER_REG))])]
5480  "")
5481
5482(define_expand "tilegx_udn_send"
5483  [(parallel
5484    [(unspec_volatile:DI [(const_int TILEGX_NETREG_UDN0)
5485			  (match_operand:DI 0 "reg_or_cint_operand" "")
5486			  (reg:DI TILEGX_NETORDER_REG)]
5487			 UNSPEC_NETWORK_SEND)
5488    (clobber (reg:DI TILEGX_NETORDER_REG))])]
5489  "")
5490
5491(define_insn "*netreg_adddi_to_network"
5492  [(unspec_volatile:DI
5493    [(match_operand:DI 0 "netreg_operand" "i,i,i")
5494     (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO")
5495              (match_operand:DI 2 "add_operand" "r,I,JT"))
5496     (reg:DI TILEGX_NETORDER_REG)]
5497    UNSPEC_NETWORK_SEND)
5498   (clobber (reg:DI TILEGX_NETORDER_REG))]
5499  ""
5500  "@
5501   add\t%N0, %r1, %2
5502   addi\t%N0, %r1, %2
5503   addli\t%N0, %r1, %H2"
5504  [(set_attr "type" "*,*,X01")])
5505
5506(define_insn "*netreg_adddi_from_network"
5507  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5508	(plus:DI (unspec_volatile:DI
5509                  [(match_operand:DI 1 "netreg_operand" "%i,i,i")
5510		   (reg:DI TILEGX_NETORDER_REG)]
5511                  UNSPEC_NETWORK_RECEIVE)
5512		 (match_operand:DI 2 "add_operand" "rO,I,JT")))
5513   (clobber (reg:DI TILEGX_NETORDER_REG))]
5514  ""
5515  "@
5516   add\t%0, %N1, %r2
5517   addi\t%0, %N1, %2
5518   addli\t%0, %N1, %H2"
5519  [(set_attr "type" "*,*,X01")])
5520
5521
5522;;
5523;; Stack protector instructions.
5524;;
5525
5526(define_expand "stack_protect_set"
5527  [(set (match_operand 0 "nonautoincmem_operand" "")
5528	(match_operand 1 "nonautoincmem_operand" ""))]
5529  ""
5530{
5531#ifdef TARGET_THREAD_SSP_OFFSET
5532  rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
5533  rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
5534  rtx ssp = gen_reg_rtx (Pmode);
5535
5536  emit_insn (gen_rtx_SET (VOIDmode, ssp, ssp_addr));
5537
5538  operands[1] = gen_rtx_MEM (Pmode, ssp);
5539#endif
5540
5541  if (TARGET_32BIT)
5542    emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
5543  else
5544    emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
5545
5546  DONE;
5547})
5548
5549(define_insn "stack_protect_setsi"
5550  [(set (match_operand:SI 0 "nonautoincmem_operand" "=U")
5551        (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")]
5552		   UNSPEC_SP_SET))
5553   (set (match_scratch:SI 2 "=&r") (const_int 0))]
5554  ""
5555  "ld4s\t%2, %1; { st4\t%0, %2; move\t%2, zero }"
5556  [(set_attr "length" "16")
5557   (set_attr "type" "cannot_bundle_3cycle")])
5558
5559(define_insn "stack_protect_setdi"
5560  [(set (match_operand:DI 0 "nonautoincmem_operand" "=U")
5561        (unspec:DI [(match_operand:DI 1 "nonautoincmem_operand" "U")]
5562		   UNSPEC_SP_SET))
5563   (set (match_scratch:DI 2 "=&r") (const_int 0))]
5564  ""
5565  "ld\t%2, %1; { st\t%0, %2; move\t%2, zero }"
5566  [(set_attr "length" "16")
5567   (set_attr "type" "cannot_bundle_3cycle")])
5568
5569(define_expand "stack_protect_test"
5570  [(match_operand 0 "nonautoincmem_operand" "")
5571   (match_operand 1 "nonautoincmem_operand" "")
5572   (match_operand 2 "" "")]
5573  ""
5574{
5575  rtx compare_result;
5576  rtx bcomp, loc_ref;
5577
5578#ifdef TARGET_THREAD_SSP_OFFSET
5579  rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
5580  rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
5581  rtx ssp = gen_reg_rtx (Pmode);
5582
5583  emit_insn (gen_rtx_SET (VOIDmode, ssp, ssp_addr));
5584
5585  operands[1] = gen_rtx_MEM (Pmode, ssp);
5586#endif
5587
5588  compare_result = gen_reg_rtx (Pmode);
5589
5590  if (TARGET_32BIT)
5591    emit_insn (gen_stack_protect_testsi (compare_result, operands[0],
5592					 operands[1]));
5593  else
5594    emit_insn (gen_stack_protect_testdi (compare_result, operands[0],
5595					 operands[1]));
5596
5597  bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
5598
5599  loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
5600
5601  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
5602			       gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
5603						     loc_ref, pc_rtx)));
5604
5605  DONE;
5606})
5607
5608(define_insn "stack_protect_testsi"
5609  [(set (match_operand:SI 0 "register_operand" "=&r")
5610        (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")
5611                    (match_operand:SI 2 "nonautoincmem_operand" "U")]
5612                   UNSPEC_SP_TEST))
5613   (set (match_scratch:SI 3 "=&r") (const_int 0))]
5614  ""
5615  "ld4s\t%0, %1; ld4s\t%3, %2; { cmpeq\t%0, %0, %3; move\t%3, zero }"
5616  [(set_attr "length" "24")
5617   (set_attr "type" "cannot_bundle_4cycle")])
5618
5619(define_insn "stack_protect_testdi"
5620  [(set (match_operand:DI 0 "register_operand" "=&r")
5621        (unspec:DI [(match_operand:DI 1 "nonautoincmem_operand" "U")
5622                    (match_operand:DI 2 "nonautoincmem_operand" "U")]
5623                   UNSPEC_SP_TEST))
5624   (set (match_scratch:DI 3 "=&r") (const_int 0))]
5625  ""
5626  "ld\t%0, %1; ld\t%3, %2; { cmpeq\t%0, %0, %3; move\t%3, zero }"
5627  [(set_attr "length" "24")
5628   (set_attr "type" "cannot_bundle_4cycle")])
5629
5630(include "sync.md")
5631