2018-02-09 Sebastian Perta <sebastian.perta@renesas.com>
[official-gcc.git] / gcc / config / tilegx / tilegx.md
blob17af2e7692939001760a2052bab9a4545dfede93
1 ;; Machine description for Tilera TILE-Gx chip for GCC.
2 ;; Copyright (C) 2011-2018 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.
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.
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/>.
21 (define_constants [
22   ;;
23   ;; The following represent intrinsic insns, organized by latency.
24   ;;
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)
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)
134   ;; 11 cycles
135   (UNSPEC_INSN_CMPEXCH                 200)
137   ;;
138   ;; The following are special insns.
139   ;;
141   ;; Blockage
142   (UNSPEC_BLOCKAGE                     201)
144   ;; Lnk and its label
145   (UNSPEC_LNK_AND_LABEL                202)
147   ;; Memory fence
148   (UNSPEC_MF                           203)
150   ;; Insns generating difference of two labels
151   (UNSPEC_MOV_PCREL_STEP3              204)
152   (UNSPEC_MOV_LARGE_PCREL_STEP4        205)
154   ;; Latency specifying loads.
155   (UNSPEC_LATENCY_L2                   206)
156   (UNSPEC_LATENCY_MISS                 207)
158   ;; A pseudo-op that prevents network operations from being ordered.
159   (UNSPEC_NETWORK_BARRIER              208)
161   ;; Operations that access network registers.
162   (UNSPEC_NETWORK_RECEIVE              209)
163   (UNSPEC_NETWORK_SEND                 210)
165   ;; Stack protector operations
166   (UNSPEC_SP_SET                       211)
167   (UNSPEC_SP_TEST                      212)
169   ;; This is used to move a value to a SPR.
170   (UNSPEC_SPR_MOVE                     213)
172   ;; A call to __tls_get_addr
173   (UNSPEC_TLS_GD_CALL                  214)
175   ;; An opaque TLS "add" operation for TLS general dynamic model
176   ;; access.
177   (UNSPEC_TLS_GD_ADD                   215)
179   ;; An opaque TLS "load" operation for TLS initial exec model access.
180   (UNSPEC_TLS_IE_LOAD                  216)
182   ;; An opaque TLS "add" operation for TLS access.
183   (UNSPEC_TLS_ADD                      217)
185   ;; Atomics
186   (UNSPEC_ATOMIC                       218)
187   (UNSPEC_CMPXCHG                      219)
188   (UNSPEC_XCHG                         220)
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)
201   (UNSPEC_HW0_PCREL                    307)
202   (UNSPEC_HW1_PCREL                    308)
203   (UNSPEC_HW1_LAST_PCREL               309)
204   (UNSPEC_HW2_LAST_PCREL               310)
206   (UNSPEC_HW0_GOT                      311)
207   (UNSPEC_HW0_LAST_GOT                 312)
208   (UNSPEC_HW1_LAST_GOT                 313)
210   (UNSPEC_HW0_TLS_GD                   314)
211   (UNSPEC_HW1_LAST_TLS_GD              315)
213   (UNSPEC_HW0_TLS_IE                   316)
214   (UNSPEC_HW1_LAST_TLS_IE              317)
216   (UNSPEC_HW0_TLS_LE                   318)
217   (UNSPEC_HW1_LAST_TLS_LE              319)
219   (UNSPEC_HW0_PLT_PCREL                320)
220   (UNSPEC_HW1_PLT_PCREL                321)
222   (UNSPEC_HW1_LAST_PLT_PCREL           322)
223   (UNSPEC_HW2_LAST_PLT_PCREL           323)
225   ;; This is used to wrap around the addresses of non-temporal load/store
226   ;; intrinsics.
227   (UNSPEC_NON_TEMPORAL                 324)
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)
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)
247 (define_constants [
248   (TILEGX_CMPEXCH_REG  66)
249   (TILEGX_NETORDER_REG 67)
253 ;; Operand and operator predicates and constraints
255 (include "predicates.md")
256 (include "constraints.md")
257 (include "tilegx-generic.md")
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"))
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)))
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])
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 "*")])
294 ;; Code iterator for either extend.
295 (define_code_iterator any_extend [sign_extend zero_extend])
297 ;; Code iterator for all three shifts.
298 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
300 ;; Code iterator for all byte ops without immediate variants.
301 (define_code_iterator v1op [us_minus us_plus minus ne le leu mult])
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])
306 ;; Code iterator for all 4-byte vector ops without immediate variants.
307 (define_code_iterator v4op [ss_minus ss_plus minus plus])
309 ;; Code iterator for all byte vector ops with immediate variants.
310 (define_code_iterator v1op_immed [plus umax umin eq lt ltu])
312 ;; Code iterator for all 2-byte vector ops with immediate variants.
313 (define_code_iterator v2op_immed [plus smax smin eq lt ltu])
315 ;; Code iterator for all 2-byte vector shifts without immediate variants.
316 (define_code_iterator v2shift [ss_ashift])
318 ;; Code iterator for all 4-byte vector shifts without immediate variants.
319 (define_code_iterator v4shift [ashift ashiftrt lshiftrt ss_ashift])
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                          ])
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                         ])
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                         ])
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                         ])
420 ;; <s> is the load/store extension suffix.
421 (define_code_attr s [(zero_extend "u")
422                      (sign_extend "s")])
424 ;; Code for packing two 2-byte vectors.
425 (define_code_iterator v2pack [truncate us_truncate])
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")])
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")])
440 ;; The basic data move insns.
443 (define_expand "movqi"
444   [(set (match_operand:QI 0 "nonimmediate_operand" "")
445         (match_operand:QI 1 "nonautoinc_operand" ""))]
446   ""
448   if (tilegx_expand_mov (QImode, operands))
449     DONE;
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")])
466 (define_expand "movhi"
467   [(set (match_operand:HI 0 "nonimmediate_operand" "")
468         (match_operand:HI 1 "nonautoinc_operand" ""))]
469   ""
471   if (tilegx_expand_mov (HImode, operands))
472     DONE;
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")])
490 (define_expand "movsi"
491   [(set (match_operand:SI 0 "nonimmediate_operand" "")
492         (match_operand:SI 1 "nonautoinc_operand" ""))]
493   ""
495   if (tilegx_expand_mov (SImode, operands))
496     DONE;
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")])
515 (define_expand "movdi"
516   [(set (match_operand:DI 0 "nonimmediate_operand" "")
517         (match_operand:DI 1 "nonautoinc_operand" ""))]
518   ""
520   if (tilegx_expand_mov (DImode, operands))
521     DONE;
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")])
542 (define_expand "movmisalign<mode>"
543   [(set (match_operand:VEC248MODE 0 "nonautoincmem_nonimmediate_operand" "")
544         (match_operand:VEC248MODE 1 "nonautoincmem_general_operand" ""))]
545   ""
547   tilegx_expand_movmisalign (<MODE>mode, operands);
548   DONE;
551 (define_expand "movsf"
552   [(set (match_operand:SF 0 "nonimmediate_operand" "")
553         (match_operand:SF 1 "general_operand" ""))]
554   ""
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     }
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")])
582 (define_expand "movdf"
583   [(set (match_operand:DF 0 "nonimmediate_operand" "")
584         (match_operand:DF 1 "general_operand" ""))]
585   ""
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     }
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")])
613 (define_expand "mov<mode>"
614   [(set (match_operand:VEC248MODE 0 "nonimmediate_operand" "")
615         (match_operand:VEC248MODE 1 "general_operand" ""))]
616   ""
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     }
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")])
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")])
667 ;; Bit-field extracts/inserts
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   ""
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];
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;
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;
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             }
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             }
719           if (!can_create_pseudo_p ())
720             FAIL;
722           operands[3] = force_reg (DImode, GEN_INT (n));
723         }
724     }
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")])
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")])
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")])
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")])
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")])
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   ""
797   int n;
799   operands[1] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]));
801   n = INTVAL (operands[2]);
802   n = (n == 0) ? 63 : n - 1;
803   operands[2] = GEN_INT (n);
805   return "mm\t%0, %r3, %1, %2";
807   [(set_attr "type" "X0")])
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   ""
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;
821       if (GET_MODE (operands[1]) != QImode)
822         FAIL;
824       bit_width = INTVAL (operands[2]);
825       bit_offset = INTVAL (operands[3]);
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;
833       /* Reject bitfields that can be done with a normal load.  */
834       if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
835         FAIL;
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;
843       tilegx_expand_unaligned_load (operands[0], operands[1],
844                                     bit_width, bit_offset, 1);
846       DONE;
847     }
849   operands[1] = force_reg (DImode, operands[1]);
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   ""
859   HOST_WIDE_INT bit_width = INTVAL (operands[2]);
860   HOST_WIDE_INT bit_offset = INTVAL (operands[3]);
862   if (MEM_P (operands[1]))
863     {
864       HOST_WIDE_INT first_byte_offset, last_byte_offset;
866       if (GET_MODE (operands[1]) != QImode)
867         FAIL;
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;
875       /* Reject bitfields that can be done with a normal load.  */
876       if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
877         FAIL;
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;
885       tilegx_expand_unaligned_load (operands[0], operands[1],
886                                     bit_width, bit_offset, 0);
888       DONE;
889     }
891     operands[1] = force_reg (DImode, operands[1]);
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       }
904 ;; Addresses
907 ;; The next three patterns are used 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)))])
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))])
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))])
951 ;; pic related instructions
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")])
967 ;; The next three patterns are used 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")
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")
1000 ;; The next three patterns are used 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")
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")
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")
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")
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")
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")
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")
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")
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")
1128 ;; TLS
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")
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")
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")
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")
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")
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")
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    ""
1196   cfun->machine->calls_tls_get_addr = true;
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")])
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)")
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)")
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")])
1240 (define_insn_and_split "*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   "&& reload_completed"
1249   [(set (match_dup 0) (zero_extract:I48MODE
1250                        (match_dup 1)
1251                        (match_dup 2)
1252                        (match_dup 3)))]
1254   HOST_WIDE_INT bit_width = INTVAL (operands[2]);
1255   HOST_WIDE_INT bit_offset = INTVAL (operands[3]);
1257   if (bit_offset + bit_width > 64)
1258     operands[2] = GEN_INT (64 - bit_offset);
1260   [(set_attr "type" "X0")])
1262 (define_insn "*sign_extract_low32"
1263   [(set (match_operand:DI 0 "register_operand" "=r")
1264         (sign_extract:DI
1265          (match_operand:DI 1 "reg_or_0_operand" "r")
1266          (match_operand:DI 2 "u6bit_cint_operand" "n")
1267          (match_operand:DI 3 "u6bit_cint_operand" "n")))]
1268   "INTVAL (operands[3]) == 0 && INTVAL (operands[2]) == 32"
1269   "addxi\t%0, %r1, 0")
1271 (define_insn_and_split "*sign_extract"
1272   [(set (match_operand:I48MODE 0 "register_operand" "=r")
1273         (sign_extract:I48MODE
1274          (match_operand:I48MODE 1 "reg_or_0_operand" "r")
1275          (match_operand:I48MODE 2 "u6bit_cint_operand" "n")
1276          (match_operand:I48MODE 3 "u6bit_cint_operand" "n")))]
1277   ""
1278   "bfexts\t%0, %r1, %3, %3+%2-1"
1279   "&& reload_completed"
1280   [(set (match_dup 0) (sign_extract:I48MODE
1281                        (match_dup 1)
1282                        (match_dup 2)
1283                        (match_dup 3)))]
1285   HOST_WIDE_INT bit_width = INTVAL (operands[2]);
1286   HOST_WIDE_INT bit_offset = INTVAL (operands[3]);
1288   if (bit_offset + bit_width > 64)
1289     operands[2] = GEN_INT (64 - bit_offset);
1291   [(set_attr "type" "X0")])
1295 ;; Arithmetic ops
1298 (define_insn "add<mode>3"
1299   [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1300         (plus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rO,rO,rO")
1301                       (match_operand:I48MODE 2 "add_operand" "r,I,JT")))]
1302   ""
1303   "@
1304    add<x>\t%0, %r1, %r2
1305    add<x>i\t%0, %r1, %2
1306    add<x>li\t%0, %r1, %H2"
1307   [(set_attr "type" "*,*,X01")])
1309 (define_insn "*addsi3_sext"
1310   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1311         (sign_extend:DI
1312          (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO")
1313                   (match_operand:SI 2 "add_operand" "r,I,JT"))))]
1314   ""
1315   "@
1316    addx\t%0, %r1, %r2
1317    addxi\t%0, %r1, %2
1318    addxli\t%0, %r1, %H2"
1319   [(set_attr "type" "*,*,X01")])
1321 (define_insn "sub<mode>3"
1322   [(set (match_operand:I48MODE 0 "register_operand" "=r")
1323         (minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
1324                        (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
1325   ""
1326   "sub<x>\t%0, %r1, %r2")
1328 (define_insn "*subsi3_sext"
1329   [(set (match_operand:DI 0 "register_operand" "=r")
1330         (sign_extend:DI
1331          (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1332                    (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
1333   ""
1334   "subx\t%0, %r1, %r2")
1336 (define_insn "neg<mode>2"
1337   [(set (match_operand:I48MODE 0 "register_operand" "=r")
1338         (neg:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO")))]
1339   ""
1340   "sub<x>\t%0, zero, %r1")
1342 (define_insn "*negsi2_sext"
1343   [(set (match_operand:DI 0 "register_operand" "=r")
1344         (sign_extend:DI
1345          (neg:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))))]
1346   ""
1347   "subx\t%0, zero, %r1")
1349 (define_insn "ssaddsi3"
1350   [(set (match_operand:SI 0 "register_operand" "=r")
1351         (ss_plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1352                     (match_operand:SI 2 "reg_or_0_operand" "rO")))]
1353   ""
1354   "addxsc\t%0, %r1, %r2"
1355   [(set_attr "type" "X01")])
1357 (define_insn "*ssaddsi3_sext"
1358   [(set (match_operand:DI 0 "register_operand" "=r")
1359         (sign_extend:DI
1360          (ss_plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1361                      (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
1362   ""
1363   "addxsc\t%0, %r1, %r2"
1364   [(set_attr "type" "X01")])
1366 (define_insn "sssubsi3"
1367   [(set (match_operand:SI 0 "register_operand" "=r")
1368         (ss_minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1369                      (match_operand:SI 2 "reg_or_0_operand" "rO")))]
1370   ""
1371   "subxsc\t%0, %r1, %r2"
1372   [(set_attr "type" "X01")])
1374 (define_insn "*sssubsi3_sext"
1375   [(set (match_operand:DI 0 "register_operand" "=r")
1376         (sign_extend:DI
1377          (ss_minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1378                       (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
1379   ""
1380   "subxsc\t%0, %r1, %r2"
1381   [(set_attr "type" "X01")])
1383 (define_expand "addsf3"
1384   [(set (match_operand:SF 0 "register_operand" "")
1385         (plus:SF (match_operand:SF 1 "register_operand" "")
1386                  (match_operand:SF 2 "register_operand" "")))]
1387   ""
1389   rtx result = gen_lowpart (DImode, operands[0]);
1390   rtx a = gen_lowpart (DImode, operands[1]);
1391   rtx b = gen_lowpart (DImode, operands[2]);
1393   rtx tmp = gen_reg_rtx (DImode);
1394   rtx flags = gen_reg_rtx (DImode);
1396   emit_insn (gen_insn_fsingle_add1 (tmp, a, b));
1397   emit_insn (gen_insn_fsingle_addsub2 (tmp, tmp, a, b));
1398   emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
1399   emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
1401   DONE;
1404 (define_expand "subsf3"
1405   [(set (match_operand:SF 0 "register_operand" "")
1406         (minus:SF (match_operand:SF 1 "register_operand" "")
1407                   (match_operand:SF 2 "register_operand" "")))]
1408   ""
1410   rtx result = gen_lowpart (DImode, operands[0]);
1411   rtx a = gen_lowpart (DImode, operands[1]);
1412   rtx b = gen_lowpart (DImode, operands[2]);
1414   rtx tmp = gen_reg_rtx (DImode);
1415   rtx flags = gen_reg_rtx (DImode);
1417   emit_insn (gen_insn_fsingle_sub1 (tmp, a, b));
1418   emit_insn (gen_insn_fsingle_addsub2 (tmp, tmp, a, b));
1419   emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
1420   emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
1422   DONE;
1425 (define_expand "mulsf3"
1426   [(set (match_operand:SF 0 "register_operand" "")
1427         (mult:SF (match_operand:SF 1 "register_operand" "")
1428                  (match_operand:SF 2 "register_operand" "")))]
1429   ""
1431   rtx result = gen_lowpart (DImode, operands[0]);
1432   rtx a = gen_lowpart (DImode, operands[1]);
1433   rtx b = gen_lowpart (DImode, operands[2]);
1435   rtx tmp1 = gen_reg_rtx (DImode);
1436   rtx tmp2 = gen_reg_rtx (DImode);
1437   rtx flags = gen_reg_rtx (DImode);
1439   emit_insn (gen_insn_fsingle_mul1 (tmp1, a, b));
1440   emit_insn (gen_insn_fsingle_mul2 (tmp2, tmp1, b));
1441   emit_insn (gen_insn_fsingle_pack1 (flags, tmp2));
1442   emit_insn (gen_insn_fsingle_pack2 (result, tmp2, flags));
1444   DONE;
1447 (define_expand "adddf3"
1448   [(set (match_operand:DF 0 "register_operand" "")
1449         (plus:DF (match_operand:DF 1 "register_operand" "")
1450                  (match_operand:DF 2 "register_operand" "")))]
1451   ""
1453   rtx result = gen_lowpart (DImode, operands[0]);
1454   rtx a = gen_lowpart (DImode, operands[1]);
1455   rtx b = gen_lowpart (DImode, operands[2]);
1457   rtx min = gen_reg_rtx (DImode);
1458   rtx max = gen_reg_rtx (DImode);
1459   rtx flags = gen_reg_rtx (DImode);
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_add_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));
1468   DONE;
1471 (define_expand "subdf3"
1472   [(set (match_operand:DF 0 "register_operand" "")
1473         (minus:DF (match_operand:DF 1 "register_operand" "")
1474                   (match_operand:DF 2 "register_operand" "")))]
1475   ""
1477   rtx result = gen_lowpart (DImode, operands[0]);
1478   rtx a = gen_lowpart (DImode, operands[1]);
1479   rtx b = gen_lowpart (DImode, operands[2]);
1481   rtx min = gen_reg_rtx (DImode);
1482   rtx max = gen_reg_rtx (DImode);
1483   rtx flags = gen_reg_rtx (DImode);
1485   emit_insn (gen_insn_fdouble_unpack_min (min, a, b));
1486   emit_insn (gen_insn_fdouble_unpack_max (max, a, b));
1487   emit_insn (gen_insn_fdouble_sub_flags (flags, a, b));
1488   emit_insn (gen_insn_fdouble_addsub (max, max, min, flags));
1489   emit_insn (gen_insn_fdouble_pack1 (result, max, flags));
1490   emit_insn (gen_insn_fdouble_pack2 (result, result, max, const0_rtx));
1492   DONE;
1495 (define_expand "muldf3"
1496   [(set (match_operand:DF 0 "register_operand" "")
1497         (mult:DF (match_operand:DF 1 "register_operand" "")
1498                  (match_operand:DF 2 "register_operand" "")))]
1499   ""
1500   ;; TODO: Decide if we should not inline this with -Os.
1501   ;; "optimize_function_for_speed_p (cfun)"
1503   rtx result = gen_lowpart (DImode, operands[0]);
1504   rtx a = gen_lowpart (DImode, operands[1]);
1505   rtx b = gen_lowpart (DImode, operands[2]);
1507   rtx a_unpacked = gen_reg_rtx (DImode);
1508   rtx b_unpacked = gen_reg_rtx (DImode);
1509   rtx flags = gen_reg_rtx (DImode);
1511   rtx low1 = gen_reg_rtx (DImode);
1512   rtx low = gen_reg_rtx (DImode);
1513   rtx low_carry = gen_reg_rtx (DImode);
1515   rtx mid = gen_reg_rtx (DImode);
1516   rtx mid_l32 = gen_reg_rtx (DImode);
1517   rtx mid_r32 = gen_reg_rtx (DImode);
1519   rtx high1 = gen_reg_rtx (DImode);
1520   rtx high = gen_reg_rtx (DImode);
1521   rtx high1_plus_mid_r32 = gen_reg_rtx (DImode);
1523   /* NOTE: We compute using max(a, 0) and max(b, 0) rather than
1524      min(a, b) and max(a, b) because for multiply we just need to unpack,
1525      we don't actually care which is min and which is max. And this
1526      formulation gives the scheduler more freedom in case one of a or b
1527      would stall at the start of this code sequence. */
1528   emit_insn (gen_insn_fdouble_unpack_max (a_unpacked, a, const0_rtx));
1529   emit_insn (gen_insn_fdouble_unpack_max (b_unpacked, b, const0_rtx));
1530   emit_insn (gen_insn_fdouble_mul_flags (flags, a, b));
1532   /* This depends on the fact that the high few bits of the unpacked
1533      mantissa are zero, so we can't have a carry out from the mid sum. */
1534   emit_insn (gen_insn_mul_lu_lu (low1, a_unpacked, b_unpacked));
1535   emit_insn (gen_insn_mul_hu_lu (mid, a_unpacked, b_unpacked));
1536   emit_insn (gen_insn_mula_hu_lu (mid, mid, b_unpacked, a_unpacked));
1537   emit_insn (gen_insn_mul_hu_hu (high1, a_unpacked, b_unpacked));
1539   emit_insn (gen_ashldi3 (mid_l32, mid, GEN_INT (32)));
1540   emit_insn (gen_lshrdi3 (mid_r32, mid, GEN_INT (32)));
1542   emit_insn (gen_adddi3 (high1_plus_mid_r32, high1, mid_r32));
1544   emit_insn (gen_adddi3 (low, low1, mid_l32));
1545   emit_insn (gen_insn_cmpltu_didi (low_carry, low, mid_l32));
1547   emit_insn (gen_adddi3 (high, high1_plus_mid_r32, low_carry));
1549   emit_insn (gen_insn_fdouble_pack1 (result, high, flags));
1550   emit_insn (gen_insn_fdouble_pack2 (result, result, high, low));
1552   DONE;
1557 ;; Shifts
1560 (define_insn "ashl<mode>3"
1561   [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
1562         (ashift:I48MODE
1563          (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1564          (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
1565   ""
1566   "@
1567   shl<x>i\t%0, %r1, %2
1568   shl<x>\t%0, %r1, %r2"
1569   [(set_attr "type" "<shift_pipe>,<shift_pipe>")])
1571 (define_insn "*ashlsi3_sext"
1572   [(set (match_operand:DI 0 "register_operand" "=r,r")
1573         (sign_extend:DI
1574          (ashift:SI
1575           (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1576           (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
1577   ""
1578   "@
1579   shlxi\t%0, %r1, %2
1580   shlx\t%0, %r1, %r2"
1581   [(set_attr "type" "X01,X01")])
1583 (define_insn "ashr<mode>3"
1584   [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
1585         (ashiftrt:I48MODE
1586          (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1587          (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
1588   ""
1589   "@
1590   shrsi\t%0, %r1, %2
1591   shrs\t%0, %r1, %r2")
1593 (define_insn "*ashrsi3_sext"
1594   [(set (match_operand:DI 0 "register_operand" "=r,r")
1595         (sign_extend:DI
1596          (ashiftrt:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1597                       (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
1598   ""
1599   "@
1600   shrsi\t%0, %r1, %2
1601   shrs\t%0, %r1, %r2")
1603 (define_insn "lshr<mode>3"
1604   [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
1605         (lshiftrt:I48MODE
1606          (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1607          (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
1608   ""
1609   "@
1610   shru<x>i\t%0, %r1, %2
1611   shru<x>\t%0, %r1, %r2"
1612   [(set_attr "type" "<shift_pipe>,<shift_pipe>")])
1613   
1614 (define_insn "*lshrsi3_sext"
1615   [(set (match_operand:DI 0 "register_operand" "=r,r")
1616         (sign_extend:DI
1617          (lshiftrt:SI
1618           (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1619           (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
1620   ""
1621   "@
1622   shruxi\t%0, %r1, %2
1623   shrux\t%0, %r1, %r2"
1624   [(set_attr "type" "X01,X01")])
1625   
1626 (define_insn "rotldi3"
1627   [(set (match_operand:DI 0 "register_operand" "=r,r")
1628         (rotate:DI (match_operand:DI 1 "reg_or_0_operand" "rO,rO")
1629                    (match_operand:SI 2 "reg_or_u6bit_operand" "I,rO")))]
1630   ""
1631   "@
1632   rotli\t%0, %r1, %2
1633   rotl\t%0, %r1, %r2")
1635 (define_insn "insn_shl16insli"
1636   [(set (match_operand:DI 0 "register_operand" "=r,r")
1637         (ior:DI
1638          (ashift:DI
1639           (match_operand:DI 1 "reg_or_0_operand" "rO,rO")
1640           (const_int 16))
1641          (match_operand:DI 2 "u16bit_or_const_symbolic_operand" "O,KT")))]
1642   ""
1643   "@
1644    shli\t%0, %r1, 16
1645    shl16insli\t%0, %r1, %H2"
1646   [(set_attr "type" "*,X01")])
1648 (define_insn "insn_addr_shl16insli<bitsuffix>"
1649   [(set (match_operand:I48MODE 0 "register_operand" "=r")
1650         (unspec:I48MODE
1651          [(match_operand:I48MODE 1 "reg_or_0_operand" "rO")
1652           (match_operand:I48MODE 2 "const_symbolic_operand" "T")]
1653          UNSPEC_INSN_ADDR_SHL16INSLI))]
1654   ""
1655   "shl16insli\t%0, %r1, %H2"
1656   [(set_attr "type" "X01")])
1660 ;; Compares
1663 (define_expand "cstore<mode>4"
1664   [(set (match_operand:DI 0 "register_operand" "")
1665       (match_operator:DI 1 "ordered_comparison_operator"
1666          [(match_operand:FI48MODE 2 "reg_or_cint_operand" "")
1667           (match_operand:FI48MODE 3 "reg_or_cint_operand" "")]))]
1668   ""
1670   if (!tilegx_emit_setcc (operands, GET_MODE (operands[2])))
1671     FAIL;
1672   else
1673     DONE;
1677 (define_insn "insn_cmpne_<I48MODE:mode><I48MODE2:mode>"
1678   [(set (match_operand:I48MODE2 0 "register_operand" "=r")
1679         (ne:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
1680                      (match_operand:I48MODE 2 "reg_or_cint_operand" "rO")))]
1681   ""
1682   "cmpne\t%0, %r1, %r2")
1684 (define_insn "insn_cmpeq_<I48MODE:mode><I48MODE2:mode>"
1685   [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1686         (eq:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "%rO,rO")
1687                      (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
1688   ""
1689   "@
1690    cmpeqi\t%0, %r1, %2
1691    cmpeq\t%0, %r1, %r2")
1693 (define_insn "insn_cmplts_<I48MODE:mode><I48MODE2:mode>"
1694   [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1695         (lt:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1696                      (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
1697   ""
1698   "@
1699    cmpltsi\t%0, %r1, %2
1700    cmplts\t%0, %r1, %r2")
1702 (define_insn "insn_cmpltu_<I48MODE:mode><I48MODE2:mode>"
1703   [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1704         (ltu:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1705                       (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
1706   ""
1707   "@
1708    cmpltui\t%0, %r1, %2
1709    cmpltu\t%0, %r1, %r2"
1710   [(set_attr "type" "X01,*")])
1712 (define_insn "insn_cmples_<I48MODE:mode><I48MODE2:mode>"
1713   [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1714         (le:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1715                      (match_operand:I48MODE 2 "reg_or_cint_operand" "L,rO")))]
1716   ""
1717   "@
1718    cmpltsi\t%0, %r1, %P2
1719    cmples\t%0, %r1, %r2")
1721 (define_insn "insn_cmpleu_<I48MODE:mode><I48MODE2:mode>"
1722   [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1723         (leu:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1724                       (match_operand:I48MODE 2 "reg_or_cint_operand" "Q,rO")))]
1725   ""
1726   "@
1727    cmpltui\t%0, %r1, %P2
1728    cmpleu\t%0, %r1, %r2"
1729   [(set_attr "type" "X01,*")])
1733 ;; Logical ops
1736 (define_insn "and<mode>3"
1737   [(set (match_operand:IVNMODE 0 "register_operand" "=r,r,r,r")
1738         (and:IVNMODE (match_operand:IVNMODE 1 "reg_or_0_operand" "%rO,rO,0,rO")
1739                      (match_operand:IVNMODE 2 "and_operand" "I,S,M,rO")))]
1740   ""
1741   "@
1742    andi\t%0, %r1, %2
1743    bfextu\t%0, %r1, %M2
1744    bfins\t%0, zero, %m2
1745    and\t%0, %r1, %r2"
1746   [(set_attr "type" "*,X0,X0,*")])
1747   
1748 (define_insn "*andsi3_sext"
1749   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
1750         (sign_extend:DI
1751          (and:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,0,rO")
1752                  (match_operand:SI 2 "and_operand" "I,S,M,rO"))))]
1753   ""
1754   "@
1755    andi\t%0, %r1, %2
1756    bfextu\t%0, %r1, %M2
1757    bfins\t%0, zero, %m2
1758    and\t%0, %r1, %r2"
1759   [(set_attr "type" "*,X0,X0,*")])
1760   
1761 (define_insn "anddi3"
1762   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
1763         (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO,rO,0,rO")
1764                     (match_operand:DI 2 "and_operand" "I,Z0,Z1,S,M,rO")))]
1765   ""
1766   "@
1767    andi\t%0, %r1, %2
1768    v4int_l\t%0, zero, %r1
1769    v4int_h\t%0, %r1, zero
1770    bfextu\t%0, %r1, %M2
1771    bfins\t%0, zero, %m2
1772    and\t%0, %r1, %r2"
1773   [(set_attr "type" "*,X01,X01,X0,X0,*")])
1774   
1775 (define_insn "ior<mode>3"
1776   [(set (match_operand:IVMODE 0 "register_operand" "=r,r")
1777         (ior:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "%rO,rO")
1778                     (match_operand:IVMODE 2 "reg_or_s8bit_operand" "rO,I")))]
1779   ""
1780   "@
1781    or\t%0, %r1, %r2
1782    ori\t%0, %r1, %2"
1783   [(set_attr "type" "*,X01")])
1784   
1785 (define_insn "*iorsi3_sext"
1786   [(set (match_operand:DI 0 "register_operand" "=r,r")
1787         (sign_extend:DI
1788          (ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
1789                  (match_operand:SI 2 "reg_or_s8bit_operand" "rO,I"))))]
1790   ""
1791   "@
1792    or\t%0, %r1, %r2
1793    ori\t%0, %r1, %2"
1794   [(set_attr "type" "*,X01")])
1795   
1796 (define_insn "xor<mode>3"
1797   [(set (match_operand:IVMODE 0 "register_operand" "=r,r")
1798         (xor:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "%rO,rO")
1799                     (match_operand:IVMODE 2 "reg_or_s8bit_operand" "rO,I")))]
1800   ""
1801   "@
1802    xor\t%0, %r1, %r2
1803    xori\t%0, %r1, %2"
1804   [(set_attr "type" "*,X01")])
1806 (define_insn "*xorsi3_sext"
1807   [(set (match_operand:DI 0 "register_operand" "=r,r")
1808         (sign_extend:DI
1809          (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
1810                  (match_operand:SI 2 "reg_or_s8bit_operand" "rO,I"))))]
1811   ""
1812   "@
1813    xor\t%0, %r1, %r2
1814    xori\t%0, %r1, %2"
1815   [(set_attr "type" "*,X01")])
1817 (define_insn "clzdi2"
1818   [(set (match_operand:DI 0 "register_operand" "=r")
1819         (clz:DI (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1820   ""
1821   "clz\t%0, %r1"
1822   [(set_attr "type" "Y0")])
1824 (define_expand "clzsi2"
1825   [(set (match_operand:SI 0 "register_operand" "=r")
1826        (clz:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))]
1827   ""
1828   {
1829     rtx tmp1 = gen_reg_rtx (DImode);
1830     rtx tmp2 = gen_reg_rtx (DImode);
1831     rtx tmp3 = gen_reg_rtx (DImode);
1833     emit_insn (gen_zero_extendsidi2 (tmp1, operands[1]));
1834     emit_insn (gen_ashldi3 (tmp2, tmp1, (GEN_INT (32))));
1835     emit_insn (gen_clzdi2 (tmp3, tmp2));
1836     emit_move_insn (operands[0], gen_lowpart (SImode, tmp3));
1837     DONE;
1838   })
1840 (define_insn "ctz<mode>2"
1841   [(set (match_operand:I48MODE 0 "register_operand" "=r")
1842         (ctz:I48MODE (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1843   ""
1844   "ctz\t%0, %r1"
1845   [(set_attr "type" "Y0")])
1847 (define_insn "popcount<mode>2"
1848   [(set (match_operand:I48MODE 0 "register_operand" "=r")
1849         (popcount:I48MODE (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1850   ""
1851   "pcnt\t%0, %r1"
1852   [(set_attr "type" "Y0")])
1854 (define_expand "parity<mode>2"
1855   [(set (match_operand:I48MODE 0 "register_operand" "")
1856         (parity:I48MODE (match_operand:DI 1 "reg_or_0_operand" "")))]
1857   ""
1858   {
1859     rtx tmp = gen_reg_rtx (<MODE>mode);
1860     emit_insn (gen_popcount<mode>2 (tmp, operands[1]));
1861     emit_insn (gen_and<mode>3 (operands[0], tmp, const1_rtx));
1862     DONE;
1863   })
1865 (define_insn "bswapdi2"
1866   [(set (match_operand:DI 0 "register_operand" "=r")
1867         (bswap:DI (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1868   ""
1869   "revbytes\t%0, %r1"
1870   [(set_attr "type" "Y0")])
1872 (define_expand "bswapsi2"
1873   [(set (match_operand:SI 0 "register_operand" "")
1874         (bswap:SI (match_operand:SI 1 "reg_or_0_operand" "")))]
1875   ""
1876   {
1877     rtx tmp = gen_reg_rtx (DImode);
1878     emit_insn (gen_bswapdi2 (tmp, gen_lowpart (DImode, operands[1])));
1879     emit_insn (gen_ashrdi3 (gen_lowpart (DImode, operands[0]),
1880                             tmp, GEN_INT (32)));
1881     DONE;
1882   })
1884 (define_insn "one_cmpl<mode>2"
1885   [(set (match_operand:IVMODE 0 "register_operand" "=r")
1886         (not:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "rO")))]
1887   ""
1888   "nor\t%0, %r1, zero")
1892 ;; Conditional moves
1895 (define_expand "mov<mode>cc"
1896   [(set (match_operand:I48MODE 0 "register_operand" "")
1897         (if_then_else:I48MODE
1898          (match_operand 1 "comparison_operator" "")
1899          (match_operand:I48MODE 2 "reg_or_0_operand" "")
1900          (match_operand:I48MODE 3 "reg_or_0_operand" "")))]
1901   ""
1902   { operands[1] = tilegx_emit_conditional_move (operands[1]); })
1904 (define_insn "movcc_insn_<I48MODE2:mode><I48MODE:mode>"
1905   [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r,r")
1906         (if_then_else:I48MODE
1907          (match_operator 4 "eqne_operator"
1908           [(match_operand:I48MODE2 1 "reg_or_0_operand" "rO,rO,rO,rO")
1909            (const_int 0)])
1910          (match_operand:I48MODE 2 "reg_or_0_operand"    "rO,O,rO,0")
1911          (match_operand:I48MODE 3 "reg_or_0_operand"    "O,rO,0,rO")))]
1912   ""
1913   "@
1914    m%c4\t%0, %r1, %r2
1915    m%C4\t%0, %r1, %r3
1916    cmov%d4z\t%0, %r1, %r2
1917    cmov%D4z\t%0, %r1, %r3"
1918   [(set_attr "type" "*,*,Y0,Y0")])
1920 (define_expand "insn_mz"
1921   [(set (match_operand:DI 0 "register_operand" "")
1922         (if_then_else:DI
1923          (eq (match_operand:DI 1 "reg_or_0_operand" "")
1924              (const_int 0))
1925          (match_operand:DI 2 "reg_or_0_operand" "")
1926          (const_int 0)))])
1928 (define_expand "insn_mnz"
1929   [(set (match_operand:DI 0 "register_operand" "")
1930         (if_then_else:DI
1931          (ne (match_operand:DI 1 "reg_or_0_operand" "")
1932              (const_int 0))
1933          (match_operand:DI 2 "reg_or_0_operand" "")
1934          (const_int 0)))])
1936 (define_expand "insn_cmoveqz"
1937   [(set (match_operand:DI 0 "register_operand" "")
1938         (if_then_else:DI
1939          (eq (match_operand:DI 2 "reg_or_0_operand" "")
1940              (const_int 0))
1941          (match_operand:DI 3 "reg_or_0_operand" "")
1942          (match_operand:DI 1 "reg_or_0_operand" "")))])
1944 (define_expand "insn_cmovnez"
1945   [(set (match_operand:DI 0 "register_operand" "")
1946         (if_then_else:DI
1947          (ne (match_operand:DI 2 "reg_or_0_operand" "")
1948              (const_int 0))
1949          (match_operand:DI 3 "reg_or_0_operand" "")
1950          (match_operand:DI 1 "reg_or_0_operand" "")))])
1954 ;; Conversions
1957 (define_insn "zero_extendqi<mode>2"
1958   [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1959         (zero_extend:I48MODE (match_operand:QI 1 "move_operand" "rO,U,m")))]
1960   ""
1961   "@
1962    bfextu\t%0, %r1, 0, 7
1963    ld1u\t%0, %1
1964    ld1u_add\t%0, %I1, %i1"
1965   [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1966   
1967 (define_insn "zero_extendhi<mode>2"
1968   [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1969         (zero_extend:I48MODE (match_operand:HI 1 "move_operand" "rO,U,m")))]
1970   ""
1971   "@
1972    bfextu\t%0, %r1, 0, 15
1973    ld2u\t%0, %1
1974    ld2u_add\t%0, %I1, %i1"
1975   [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1977 (define_insn "zero_extendsidi2"
1978   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1979         (zero_extend:DI (match_operand:SI 1 "move_operand" "rO,U,m")))]
1980   ""
1981   "@
1982    v4int_l\t%0, zero, %r1
1983    ld4u\t%0, %1
1984    ld4u_add\t%0, %I1, %i1"
1985   [(set_attr "type" "X01,Y2_2cycle,X1_2cycle")])
1987 (define_insn "extendqi<mode>2"
1988   [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1989         (sign_extend:I48MODE (match_operand:QI 1 "move_operand" "rO,U,m")))]
1990   ""
1991   "@
1992    bfexts\t%0, %r1, 0, 7
1993    ld1s\t%0, %1
1994    ld1s_add\t%0, %I1, %i1"
1995   [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1997 (define_insn "extendhi<mode>2"
1998   [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1999         (sign_extend:I48MODE (match_operand:HI 1 "move_operand" "rO,U,m")))]
2000   ""
2001   "@
2002    bfexts\t%0, %r1, 0, 15
2003    ld2s\t%0, %1
2004    ld2s_add\t%0, %I1, %i1"
2005   [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
2007 ;; All SImode integer registers should already be in sign-extended form
2008 ;; (see TARGET_TRULY_NOOP_TRUNCATION and truncdisi2).  We can therefore
2009 ;; get rid of register->register instructions if we constrain the
2010 ;; source to be in the same register as the destination.
2011 (define_insn_and_split "extendsidi2"
2012   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
2013         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,U,m")))]
2014   ""
2015   "@
2016    #
2017    ld4s\t%0, %1
2018    ld4s_add\t%0, %I1, %i1"
2019   "&& reload_completed && register_operand (operands[1], VOIDmode)"
2020   [(const_int 0)]
2022   emit_note (NOTE_INSN_DELETED);
2023   DONE;
2025   [(set_attr "type" "*,Y2_2cycle,X1_2cycle")])
2027 ;; Integer truncation patterns.  Truncating SImode values to smaller
2028 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
2029 ;; DImode values to SImode is not a no-op since we
2030 ;; need to make sure that the lower 32 bits are properly sign-extended
2031 ;; (see TARGET_TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2032 ;; smaller than SImode is equivalent to two separate truncations:
2034 ;;                        A       B
2035 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2036 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2038 ;; Step A needs a real instruction but step B does not.
2040 (define_insn "truncdisi2"
2041   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,U,m")
2042         (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
2043   ""
2044   "@
2045    addxi\t%0, %r1, 0
2046    st4\t%0, %r1
2047    st4_add\t%I0, %r1, %i0"
2048   [(set_attr "type" "Y01,Y2,X1")])
2050 (define_insn "truncdihi2"
2051   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,U,m")
2052         (truncate:HI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
2053   ""
2054   "@
2055    addxi\t%0, %r1, 0
2056    st2\t%0, %r1
2057    st2_add\t%I0, %r1, %i0"
2058   [(set_attr "type" "Y01,Y2,X1")])
2060 (define_insn "truncdiqi2"
2061   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,U,m")
2062         (truncate:QI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
2063   ""
2064   "@
2065    addxi\t%0, %r1, 0
2066    st1\t%0, %r1
2067    st1_add\t%I0, %r1, %i0"
2068   [(set_attr "type" "Y01,Y2,X1")])
2070 ;; Combiner patterns to optimize away unnecessary truncates.
2072 (define_insn "*zero_extendsidi_truncdisi"
2073   [(set (match_operand:DI 0 "register_operand" "=r")
2074         (zero_extend:DI
2075          (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))))]
2076   ""
2077   "v4int_l\t%0, zero, %r1"
2078   [(set_attr "type" "X01")])
2080 (define_insn "*addsi_truncdisi"
2081   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2082         (plus:SI
2083          (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO"))
2084          (match_operand:SI 2 "add_operand" "r,I,JT")))]
2085   ""
2086   "@
2087    addx\t%0, %r1, %r2
2088    addxi\t%0, %r1, %2
2089    addxli\t%0, %r1, %H2"
2090   [(set_attr "type" "*,*,X01")])
2092 (define_insn "*addsi_truncdisi2"
2093   [(set (match_operand:SI 0 "register_operand" "=r")
2094         (plus:SI
2095          (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))
2096          (truncate:SI (match_operand:DI 2 "reg_or_0_operand" "rO"))))]
2097   ""
2098   "addx\t%0, %r1, %r2")
2100 (define_insn "*ashldi_truncdisi"
2101   [(set (match_operand:DI 0 "register_operand" "=r")
2102         (ashift: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   "shl\t%0, %r1, %r2")
2108 (define_insn "*ashlsi_truncdisi"
2109   [(set (match_operand:SI 0 "register_operand" "=r,r")
2110         (ashift: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   shlxi\t%0, %r1, %2
2116   shlx\t%0, %r1, %r2"
2117   [(set_attr "type" "X01,X01")])
2119 (define_insn "*ashlsi_truncdisi2"
2120   [(set (match_operand:SI 0 "register_operand" "=r")
2121         (ashift: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   "shlx\t%0, %r1, %r2"
2126   [(set_attr "type" "X01")])
2128 (define_insn "*ashrdi3_truncdisi"
2129   [(set (match_operand:DI 0 "register_operand" "=r")
2130         (ashiftrt: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   "shrs\t%0, %r1, %r2")
2136 (define_insn "*lshrsi_truncdisi"
2137   [(set (match_operand:SI 0 "register_operand" "=r,r")
2138         (lshiftrt:SI
2139          (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO,rO"))
2140          (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
2141   ""
2142   "@
2143   shruxi\t%0, %r1, %2
2144   shrux\t%0, %r1, %r2"
2145   [(set_attr "type" "X01,X01")])
2147 (define_insn "*lshrsi_truncdisi2"
2148   [(set (match_operand:SI 0 "register_operand" "=r")
2149         (lshiftrt:SI
2150          (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))
2151          (truncate:SI (match_operand:DI 2 "reg_or_0_operand" "rO"))))]
2152   ""
2153   "shrux\t%0, %r1, %r2"
2154   [(set_attr "type" "X01")])
2156 (define_insn "*lshrdi_truncdisi"
2157   [(set (match_operand:DI 0 "register_operand" "=r")
2158         (lshiftrt:DI
2159          (match_operand:DI 1 "reg_or_0_operand" "rO")
2160          (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
2161   ""
2162   "shru\t%0, %r1, %r2")
2164 (define_insn "*rotldi_truncdisi"
2165   [(set (match_operand:DI 0 "register_operand" "=r")
2166         (rotate:DI
2167          (match_operand:DI 1 "reg_or_0_operand" "rO")
2168          (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
2169   ""
2170   "rotl\t%0, %r1, %r2")
2172 ;; Integer to floating point conversions
2174 (define_expand "floatsisf2"
2175   [(set (match_operand:SF 0 "register_operand" "")
2176         (float:SI (match_operand:SI 1 "register_operand" "")))]
2177   ""
2179   rtx result = gen_lowpart (DImode, operands[0]);
2180   rtx a = operands[1];
2182   rtx nega = gen_reg_rtx (SImode);
2183   rtx exp = gen_reg_rtx (DImode);
2184   rtx sign = gen_reg_rtx (DImode);
2185   rtx abs = gen_reg_rtx (DImode);
2186   rtx flags = gen_reg_rtx (DImode);
2187   rtx tmp1 = gen_reg_rtx (DImode);
2188   rtx tmp2 = gen_reg_rtx (DImode);
2190   emit_move_insn (exp, GEN_INT (0x9e));
2192   emit_insn (gen_negsi2 (nega, a));
2194   emit_insn (gen_insn_cmplts_sisi (gen_lowpart (SImode, sign), a, const0_rtx));
2195   emit_insn (gen_insn_cmoveqz (abs, gen_lowpart (DImode, nega), sign,
2196                                gen_lowpart (DImode, a)));
2198   emit_insn (gen_insn_bfins (tmp1, exp, sign, GEN_INT (10), GEN_INT (10)));
2199   emit_insn (gen_insn_bfins (tmp2, tmp1, abs, GEN_INT (32), GEN_INT (63)));
2200   emit_insn (gen_insn_fsingle_pack1 (flags, tmp2));
2201   emit_insn (gen_insn_fsingle_pack2 (result, tmp2, flags));
2202   DONE;
2204   
2205 (define_expand "floatunssisf2"
2206   [(set (match_operand:SF 0 "register_operand" "")
2207         (float:SI (match_operand:SI 1 "register_operand" "")))]
2208   ""
2210   rtx result = gen_lowpart (DImode, operands[0]);
2211   rtx a = operands[1];
2213   rtx exp = gen_reg_rtx (DImode);
2214   rtx flags = gen_reg_rtx (DImode);
2215   rtx tmp = gen_reg_rtx (DImode);
2217   emit_move_insn (exp, GEN_INT (0x9e));
2218   emit_insn (gen_insn_bfins (tmp, exp, gen_lowpart (DImode, a),
2219                              GEN_INT (32), GEN_INT (63)));
2220   emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
2221   emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
2222   DONE;
2225 (define_expand "floatsidf2"
2226   [(set (match_operand:DF 0 "register_operand" "")
2227         (float:SI (match_operand:SI 1 "register_operand" "")))]
2228   ""
2230   rtx result = gen_lowpart (DImode, operands[0]);
2231   rtx a = gen_lowpart (DImode, operands[1]);
2233   rtx nega = gen_reg_rtx (DImode);
2234   rtx exp = gen_reg_rtx (DImode);
2235   rtx sign = gen_reg_rtx (DImode);
2236   rtx abs = gen_reg_rtx (DImode);
2237   rtx tmp1 = gen_reg_rtx (DImode);
2238   rtx tmp2 = gen_reg_rtx (DImode);
2239   rtx tmp3 = gen_reg_rtx (DImode);
2241   emit_move_insn (exp, GEN_INT (0x21b00));
2243   emit_insn (gen_negdi2 (nega, a));
2245   emit_insn (gen_insn_cmplts_didi (sign, a, const0_rtx));
2246   emit_insn (gen_insn_cmovnez (abs, a, sign, nega));
2248   emit_insn (gen_ashldi3 (tmp1, abs, GEN_INT (4)));
2249   emit_insn (gen_insn_bfins (tmp2, exp, sign, GEN_INT (20), GEN_INT (20)));
2250   emit_insn (gen_insn_fdouble_pack1 (tmp3, tmp1, tmp2));
2251   emit_insn (gen_insn_fdouble_pack2 (result, tmp3, tmp1, const0_rtx));
2252   DONE;
2254   
2255 (define_expand "floatunssidf2"
2256   [(set (match_operand:DF 0 "register_operand" "")
2257         (float:SI (match_operand:SI 1 "register_operand" "")))]
2258   ""
2260   rtx result = gen_lowpart (DImode, operands[0]);
2261   rtx a = gen_lowpart (DImode, operands[1]);
2263   rtx exp = gen_reg_rtx (DImode);
2264   rtx tmp1 = gen_reg_rtx (DImode);
2265   rtx tmp2 = gen_reg_rtx (DImode);
2267   emit_move_insn (exp, GEN_INT (0x21b00));
2268   emit_insn (gen_insn_bfins (tmp1, const0_rtx, a, GEN_INT (4), GEN_INT (35)));
2269   emit_insn (gen_insn_fdouble_pack1 (tmp2, tmp1, exp));
2270   emit_insn (gen_insn_fdouble_pack2 (result, tmp2, tmp1, const0_rtx));
2271   DONE;
2273   
2276 ;; Multiplies
2279 (define_insn "mulsi3"
2280   [(set (match_operand:SI 0 "register_operand" "=r")
2281         (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rO")
2282                  (match_operand:SI 2 "reg_or_0_operand" "rO")))]
2283   ""
2284   "mulx\t%0, %r1, %r2"
2285   [(set_attr "type" "Y0_2cycle")])
2287 (define_insn "mulsidi3"
2288   [(set (match_operand:DI 0 "register_operand" "=r")
2289         (mult:DI (sign_extend:DI
2290                   (match_operand:SI 1 "reg_or_0_operand" "%rO"))
2291                  (sign_extend:DI
2292                   (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
2293   ""
2294   "mul_ls_ls\t%0, %r1, %r2"
2295   [(set_attr "type" "Y0_2cycle")])
2297 (define_insn "umulsidi3"
2298   [(set (match_operand:DI 0 "register_operand" "=r")
2299         (mult:DI (zero_extend:DI
2300                   (match_operand:SI 1 "reg_or_0_operand" "%rO"))
2301                  (zero_extend:DI
2302                   (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
2303   ""
2304   "mul_lu_lu\t%0, %r1, %r2"
2305   [(set_attr "type" "Y0_2cycle")])
2307 (define_expand "muldi3"
2308   [(set (match_operand:DI 0 "register_operand" "")
2309         (unspec:DI [(match_operand:DI 1 "nonmemory_operand" "")
2310                     (match_operand:DI 2 "nonmemory_operand" "")]
2311                    UNSPEC_INSN_MUL_HU_LU))
2312    (set (match_dup 0)
2313         (unspec:DI [(match_dup 0) (match_dup 2) (match_dup 1)]
2314                    UNSPEC_INSN_MULA_HU_LU))
2315    (set (match_dup 0)
2316         (ashift:DI (match_dup 0) (const_int 32)))
2317    (set (match_dup 0)
2318         (unspec:DI [(match_dup 0) (match_dup 2) (match_dup 1)]
2319                    UNSPEC_INSN_MULA_LU_LU))]
2320   ""
2321   {
2322     operands[1] = force_reg (DImode, operands[1]);
2323     operands[1] = make_safe_from (operands[1], operands[0]);
2325     if (tilegx_expand_muldi (operands[0], operands[1], operands[2]))
2326       DONE;
2327     else
2328       {
2329         operands[2] = force_reg (DImode, operands[2]);
2330         operands[2] = make_safe_from (operands[2], operands[0]);
2331       }
2332   })
2334 (define_insn "usmulsidi3"
2335   [(set (match_operand:DI 0 "register_operand" "=r")
2336         (mult:DI (zero_extend:DI
2337                   (match_operand:SI 1 "reg_or_0_operand" "rO"))
2338                  (sign_extend:DI
2339                   (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
2340   ""
2341   "mul_ls_lu\t%0, %r2, %r1"
2342   [(set_attr "type" "X0_2cycle")])
2343   
2344 (define_insn "maddsidi4"
2345   [(set (match_operand:DI 0 "register_operand" "=r")
2346         (plus:DI
2347          (mult:DI (sign_extend:DI
2348                    (match_operand:SI 1 "reg_or_0_operand" "rO"))
2349                   (sign_extend:DI
2350                    (match_operand:SI 2 "reg_or_0_operand" "rO")))
2351          (match_operand:DI 3 "register_operand" "0")))]
2352   ""
2353   "mula_ls_ls\t%0, %r1, %r2"
2354   [(set_attr "type" "Y0_2cycle")])
2356 (define_insn "umaddsidi4"
2357   [(set (match_operand:DI 0 "register_operand" "=r")
2358         (plus:DI
2359          (mult:DI (zero_extend:DI
2360                    (match_operand:SI 1 "reg_or_0_operand" "rO"))
2361                   (zero_extend:DI
2362                    (match_operand:SI 2 "reg_or_0_operand" "rO")))
2363          (match_operand:DI 3 "register_operand" "0")))]
2364   ""
2365   "mula_lu_lu\t%0, %r1, %r2"
2366   [(set_attr "type" "Y0_2cycle")])
2368 (define_expand "smulsi3_highpart"
2369   [(set (match_dup 3)
2370         (mult:DI (sign_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
2371                  (sign_extend:DI (match_operand:SI 2 "reg_or_0_operand" ""))))
2372    (set (match_dup 4)
2373         (ashiftrt:DI (match_dup 3) (const_int 32)))
2374    (set (match_operand:SI 0 "register_operand" "")
2375         (truncate:SI (match_dup 4)))]
2376   ""
2377   {
2378     operands[3] = gen_reg_rtx (DImode);
2379     operands[4] = gen_reg_rtx (DImode);
2380   })
2382 (define_expand "umulsi3_highpart"
2383   [(set (match_dup 3)
2384         (mult:DI (zero_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
2385                  (zero_extend:DI (match_operand:SI 2 "reg_or_0_operand" ""))))
2386    (set (match_dup 4)
2387         (lshiftrt:DI (match_dup 3) (const_int 32)))
2388    (set (match_operand:SI 0 "register_operand" "")
2389         (truncate:SI (match_dup 4)))]
2390   ""
2391   {
2392     operands[3] = gen_reg_rtx (DImode);
2393     operands[4] = gen_reg_rtx (DImode);
2394   })
2396 (define_expand "smuldi3_highpart"
2397   [(set (match_operand:DI 0 "register_operand" "")
2398         (truncate:DI
2399          (ashiftrt:TI 
2400           (mult:TI (sign_extend:TI (match_operand:DI 1 "reg_or_0_operand" ""))
2401                    (sign_extend:TI (match_operand:DI 2 "reg_or_0_operand" "")))
2402           (const_int 64))))]
2403   ""
2404   {
2405     tilegx_expand_smuldi3_highpart (operands[0], operands[1], operands[2]);
2406     DONE;
2407   })
2409 (define_expand "umuldi3_highpart"
2410   [(set (match_operand:DI 0 "register_operand" "")
2411         (truncate:DI
2412          (lshiftrt:TI
2413           (mult:TI (zero_extend:TI (match_operand:DI 1 "reg_or_0_operand" ""))
2414                    (zero_extend:TI (match_operand:DI 2 "reg_or_0_operand" "")))
2415           (const_int 64))))]
2416   ""
2418   tilegx_expand_umuldi3_highpart (operands[0], operands[1], operands[2]);
2419   DONE;
2424 ;; Divide stubs.  These exist to work around a bug in expmed.c, which
2425 ;; will not attempt to convert a divide by constant into a multiply
2426 ;; unless there is a pattern for a divide of the same mode.  The end
2427 ;; result is a 32-bit divide turns into 64-bit multiply.
2430 (define_expand "divsi3"
2431   [(set (match_operand:SI 0 "register_operand" "")
2432         (div:SI (match_operand:SI 1 "reg_or_0_operand" "")
2433                 (match_operand:SI 2 "reg_or_0_operand" "")))]
2434   ""
2436   FAIL;
2439 (define_expand "udivsi3"
2440   [(set (match_operand:SI 0 "register_operand" "")
2441         (udiv:SI (match_operand:SI 1 "reg_or_0_operand" "")
2442                  (match_operand:SI 2 "reg_or_0_operand" "")))]
2443   ""
2445   FAIL;
2450 ;; Loops
2453 ;; Define the subtract-one-and-jump insns so loop.c knows what to
2454 ;; generate.
2455 (define_expand "doloop_end"
2456   [(use (match_operand 0 "" ""))    ;; loop pseudo
2457    (use (match_operand 1 "" ""))]   ;; label
2458    ""
2460   if (optimize > 0 && flag_modulo_sched)
2461   {
2462      rtx s0;
2463      rtx bcomp;
2464      rtx loc_ref;
2465      machine_mode mode = GET_MODE (operands[0]);
2467      /* only deal with loop counters in SImode or DImode  */
2468      if (mode != SImode && mode != DImode)
2469        FAIL;
2471      s0 = operands [0];
2472      emit_move_insn (s0, gen_rtx_PLUS (mode, s0, GEN_INT (-1)));
2473      bcomp = gen_rtx_NE(mode, s0, const0_rtx);
2474      loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
2475      emit_jump_insn (gen_rtx_SET (pc_rtx,
2476                                   gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
2477                                                         loc_ref, pc_rtx)));
2478      DONE;
2479   }
2480   else
2481      FAIL;
2486 ;; Prologue/epilogue
2488 (define_expand "prologue"
2489   [(const_int 0)]
2490   ""
2492   tilegx_expand_prologue ();
2493   DONE;
2496 (define_expand "epilogue"
2497   [(const_int 0)]
2498   ""
2500   tilegx_expand_epilogue (false);
2501   DONE;
2504 (define_expand "sibcall_epilogue"
2505   [(const_int 0)]
2506   ""
2508   tilegx_expand_epilogue (true);
2509   DONE;
2513 ;; Stack manipulations
2516 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
2517 (define_expand "allocate_stack"
2518   [(set (match_operand 0 "register_operand" "")
2519         (minus (reg 54) (match_operand 1 "nonmemory_operand" "")))
2520    (set (reg 54)
2521         (minus (reg 54) (match_dup 1)))]
2522   ""
2523   "tilegx_allocate_stack (operands[0], operands[1]); DONE;")
2526 ;; Branches
2529 (define_expand "call"
2530   [(parallel [(call (match_operand:DI 0 "call_operand" "")
2531                     (match_operand 1 "" ""))
2532               (use (reg:DI 54))
2533               (clobber (reg:DI 55))])]
2534   ""
2536   rtx orig_addr = XEXP (operands[0], 0);
2537   rtx addr;
2538   if (GET_CODE (orig_addr) == SYMBOL_REF)
2539     {
2540       if (tilegx_cmodel == CM_LARGE)
2541         {
2542           addr = gen_reg_rtx (Pmode);
2543           tilegx_expand_set_const64 (addr, orig_addr);
2544           operands[0] = gen_rtx_MEM (DImode, addr);
2545         }
2546       else if (tilegx_cmodel == CM_LARGE_PIC)
2547         {
2548           crtl->uses_pic_offset_table = 1;
2549           addr = gen_reg_rtx (Pmode);
2550           if (SYMBOL_REF_LOCAL_P (orig_addr))
2551             tilegx_compute_pcrel_address (addr, orig_addr);
2552           else
2553             tilegx_compute_pcrel_plt_address (addr, orig_addr);
2554           operands[0] = gen_rtx_MEM (DImode, addr);
2555         }
2556     }
2559 (define_insn "*call_insn"
2560   [(call (mem:DI (match_operand:I48MODE 0 "call_address_operand" "rO,i"))
2561          (match_operand 1 "" ""))
2562    (use (reg:DI 54))
2563    (clobber (reg:DI 55))]
2564   ""
2565   "@
2566    jalr\t%r0
2567    jal\t%p0"
2568   [(set_attr "type" "Y1,X1")])
2570 (define_expand "call_value"
2571   [(parallel [(set (match_operand 0 "register_operand" "")
2572                    (call (match_operand:DI 1 "call_operand" "")
2573                          (match_operand 2 "" "")))
2574               (use (reg:DI 54))
2575               (clobber (reg:DI 55))])]
2576   ""
2578   rtx orig_addr = XEXP (operands[1], 0);
2579   rtx addr;
2580   if (GET_CODE (orig_addr) == SYMBOL_REF)
2581     {
2582       if (tilegx_cmodel == CM_LARGE)
2583         {
2584           addr = gen_reg_rtx (Pmode);
2585           tilegx_expand_set_const64 (addr, orig_addr);
2586           operands[1] = gen_rtx_MEM (DImode, addr);
2587         }
2588       else if (tilegx_cmodel == CM_LARGE_PIC)
2589         {
2590           crtl->uses_pic_offset_table = 1;
2591           addr = gen_reg_rtx (Pmode);
2592           if (SYMBOL_REF_LOCAL_P (orig_addr))
2593             tilegx_compute_pcrel_address (addr, orig_addr);
2594           else
2595             tilegx_compute_pcrel_plt_address (addr, orig_addr);
2596           operands[1] = gen_rtx_MEM (DImode, addr);
2597         }
2598     }
2601 (define_insn "*call_value_insn"
2602   [(set (match_operand 0 "register_operand" "=r,r")
2603         (call (mem:DI (match_operand:I48MODE 1 "call_address_operand" "rO,i"))
2604               (match_operand 2 "" "")))
2605    (use (reg:DI 54))
2606    (clobber (reg:DI 55))]
2607   ""
2608   "@
2609    jalr\t%r1
2610    jal\t%p1"
2611   [(set_attr "type" "Y1,X1")])
2613 (define_expand "sibcall"
2614   [(parallel [(call (match_operand:DI 0 "call_operand" "")
2615                     (match_operand 1 "" ""))
2616               (use (reg:DI 54))])]
2617   ""
2618   "")
2620 (define_insn "*sibcall_insn"
2621   [(call (mem:DI (match_operand:I48MODE 0 "call_address_operand" "rO,i"))
2622          (match_operand 1 "" ""))
2623    (use (reg:DI 54))]
2624   "SIBLING_CALL_P(insn)"
2625   "@
2626    jr\t%r0
2627    j\t%p0"
2628   [(set_attr "type" "Y1,X1")])
2630 (define_expand "sibcall_value"
2631   [(parallel [(set (match_operand 0 "" "")
2632                    (call (match_operand:DI 1 "call_operand" "")
2633                          (match_operand 2 "" "")))
2634               (use (reg:DI 54))])]
2635   ""
2636   "")
2638 (define_insn "*sibcall_value"
2639   [(set (match_operand 0 "" "")
2640         (call (mem:DI (match_operand:I48MODE 1 "call_address_operand" "rO,i"))
2641               (match_operand 2 "" "")))
2642    (use (reg:DI 54))]
2643   "SIBLING_CALL_P(insn)"
2644   "@
2645    jr\t%r1
2646    j\t%p1"
2647   [(set_attr "type" "Y1,X1")])
2649 (define_insn "jump"
2650   [(set (pc) (label_ref (match_operand 0 "" "")))]
2651   ""
2652   "j\t%l0"
2653   [(set_attr "type" "X1")])
2655 (define_insn "indirect_jump"
2656   [(set (pc) (match_operand 0 "pointer_operand" "rO"))]
2657   ""
2658   "jr\t%r0"
2659   [(set_attr "type" "Y1")])
2661 (define_expand "return"
2662   [(parallel
2663     [(return)
2664      (use (reg:DI 55))])]
2665   "tilegx_can_use_return_insn_p ()"
2666   "")
2668 (define_insn "_return"
2669   [(return)
2670    (use (reg:DI 55))]
2671   "reload_completed"
2672   "jrp\tlr"
2673   [(set_attr "type" "Y1")])
2675 (define_expand "tablejump"
2676   [(set (pc) (match_operand 0 "pointer_operand" ""))
2677    (use (label_ref (match_operand 1 "" "")))]
2678   ""
2680   tilegx_expand_tablejump (operands[0], operands[1]);
2681   DONE;
2684 (define_insn "tablejump_aux"
2685   [(set (pc) (match_operand 0 "pointer_operand" "rO"))
2686    (use (label_ref (match_operand 1 "" "")))]
2687   ""
2688   "jr\t%r0"
2689   [(set_attr "type" "Y1")])
2691 ;; Call subroutine returning any type.
2692 (define_expand "untyped_call"
2693   [(parallel [(call (match_operand 0 "" "")
2694                     (const_int 0))
2695               (match_operand 1 "" "")
2696               (match_operand 2 "" "")])]
2697   ""
2699   int i;
2701   emit_call_insn (gen_call (operands[0], const0_rtx));
2703   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2704     {
2705       rtx set = XVECEXP (operands[2], 0, i);
2706       emit_move_insn (SET_DEST (set), SET_SRC (set));
2707     }
2709   /* The optimizer does not know that the call sets the function value
2710      registers we stored in the result block.  We avoid problems by
2711      claiming that all hard registers are used and clobbered at this
2712      point.  */
2713   emit_insn (gen_blockage ());
2715   DONE;
2718 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers
2719 ;; and all of memory.  This blocks insns from being moved across this
2720 ;; point.
2721 (define_insn "blockage"
2722   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
2723   ""
2724   "pseudo"
2725   [(set_attr "type" "nothing")
2726    (set_attr "length" "0")])
2728 ;; Internal expanders to prevent memory ops from moving around frame
2729 ;; allocation/deallocation.
2731 ;; TODO: really this clobber should just clobber the frame memory.  Is
2732 ;; this possibly by clobbering memory @ the sp reg (as alpha does?)
2733 ;; or by explicitly setting the alias set to the frame?
2734 (define_insn "sp_adjust"
2735   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
2736         (plus:DI
2737          (match_operand:DI 1 "register_operand" "%r,r,r")
2738          (match_operand:DI 2 "add_operand" "r,I,JT")))
2739    (clobber (mem:BLK (scratch)))]
2740  ""
2741  "@
2742   add\t%0, %1, %2
2743   addi\t%0, %1, %2
2744   addli\t%0, %1, %H2"
2745  [(set_attr "type" "*,*,X01")])
2747 (define_insn "sp_adjust_32bit"
2748   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2749         (plus:SI
2750          (match_operand:SI 1 "register_operand" "%r,r,r")
2751          (match_operand:SI 2 "add_operand" "r,I,JT")))
2752    (clobber (mem:BLK (scratch)))]
2753  ""
2754  "@
2755   addx\t%0, %1, %2
2756   addxi\t%0, %1, %2
2757   addxli\t%0, %1, %H2"
2758  [(set_attr "type" "*,*,X01")])
2760 ;; Used for move sp, r52, to pop a stack frame.  We need to make sure
2761 ;; that stack frame memory operations have been issued before we do
2762 ;; this.  TODO: see above TODO.
2763 (define_insn "sp_restore<bitsuffix>"
2764   [(set (match_operand:I48MODE 0 "register_operand" "=r")
2765         (match_operand:I48MODE 1 "register_operand" "r"))
2766    (clobber (mem:BLK (scratch)))]
2767  ""
2768  "move\t%0, %1")
2770 (define_insn "nop"
2771   [(const_int 0)]
2772   ""
2773   "nop"
2774   [(set_attr "type" "Y01")])
2776 (define_insn "trap"
2777   [(trap_if (const_int 1) (const_int 0))]
2778   ""
2779   "raise; moveli zero, 6"
2780   [(set_attr "type" "cannot_bundle")])
2784 ;; Conditional branches
2787 (define_expand "cbranch<mode>4"
2788   [(set (pc)
2789       (if_then_else (match_operator 0 "ordered_comparison_operator"
2790                      [(match_operand:FI48MODE 1 "reg_or_cint_operand")
2791                         (match_operand:FI48MODE 2 "reg_or_cint_operand")])
2792                       (label_ref (match_operand 3 ""))
2793                     (pc)))]
2794    ""
2796   tilegx_emit_conditional_branch (operands, GET_MODE (operands[1]));
2797   DONE;
2800 (define_insn "*bcc_normal<mode>"
2801   [(set (pc)
2802         (if_then_else
2803          (match_operator 1 "signed_comparison_operator"
2804                          [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
2805                           (const_int 0)])
2806          (label_ref (match_operand 0 "" ""))
2807          (pc)))]
2808   ""
2809   { return tilegx_output_cbranch (insn, operands, false); }
2810   [(set_attr "type" "X1_branch")])
2812 (define_insn "*bcc_reverse<mode>"
2813   [(set (pc)
2814         (if_then_else
2815          (match_operator 1 "signed_comparison_operator"
2816                          [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
2817                           (const_int 0)])
2818          (pc)
2819          (label_ref (match_operand 0 "" ""))))]
2820   ""
2821   { return tilegx_output_cbranch (insn, operands, true); }
2822   [(set_attr "type" "X1_branch")])
2824 (define_insn "*blbs_normal<mode>"
2825   [(set (pc)
2826         (if_then_else
2827          (ne (zero_extract:I48MODE
2828               (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
2829               (const_int 1)
2830               (const_int 0))
2831              (const_int 0))
2832          (label_ref (match_operand 0 "" ""))
2833          (pc)))]
2834   ""
2835   { return tilegx_output_cbranch_with_opcode (insn, operands, "blbs", "blbc",
2836                                               1); }
2837   [(set_attr "type" "X1_branch")])
2839 (define_insn "*blbc_normal<mode>"
2840   [(set (pc)
2841         (if_then_else
2842          (eq (zero_extract:I48MODE
2843               (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
2844               (const_int 1)
2845               (const_int 0))
2846              (const_int 0))
2847          (label_ref (match_operand 0 "" ""))
2848          (pc)))]
2849   ""
2850   { return tilegx_output_cbranch_with_opcode (insn, operands, "blbc", "blbs",
2851                                               1); }
2852   [(set_attr "type" "X1_branch")])
2854 ;; Note that __insn_mf() expands to this.
2855 (define_expand "memory_barrier"
2856   [(set (match_dup 0)
2857         (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
2858   ""
2860   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
2861   MEM_VOLATILE_P (operands[0]) = 1;
2864 (define_insn "*memory_barrier"
2865   [(set (match_operand:BLK 0 "" "")
2866         (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
2867   ""
2868   "mf"
2869   [(set_attr "type" "X1")])
2871 (define_insn "prefetch"
2872   [(prefetch (match_operand 0 "address_operand" "rO")
2873              (match_operand 1 "const_int_operand" "")
2874              (match_operand 2 "const_int_operand" ""))]
2875   ""
2877   switch (INTVAL (operands[2]))
2878     {
2879       case 0:
2880       case 1: return "prefetch_l3\t%r0";
2881       case 2: return "prefetch_l2\t%r0";
2882       case 3: return "prefetch_l1\t%r0";
2883       default: gcc_unreachable ();
2884     }
2886   [(set_attr "type" "Y2")])
2890 ;; "__insn" Intrinsics (some expand directly to normal patterns above).
2893 (define_insn "insn_bfexts"
2894   [(set (match_operand:DI 0 "register_operand" "=r")
2895         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2896                     (match_operand:DI 2 "u6bit_cint_operand" "n")
2897                     (match_operand:DI 3 "u6bit_cint_operand" "n")]
2898                    UNSPEC_INSN_BFEXTS))]
2899   ""
2900   "bfexts\t%0, %r1, %2, %3"
2901   [(set_attr "type" "X0")])
2903 (define_insn "insn_bfextu"
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 "u6bit_cint_operand" "n")
2907                     (match_operand:DI 3 "u6bit_cint_operand" "n")]
2908                    UNSPEC_INSN_BFEXTU))]
2909   ""
2910   "bfextu\t%0, %r1, %2, %3"
2911   [(set_attr "type" "X0")])
2913 (define_insn "insn_bfins"
2914   [(set (match_operand:DI 0 "register_operand" "=r")
2915         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2916                     (match_operand:DI 2 "reg_or_0_operand" "rO")
2917                     (match_operand:DI 3 "u6bit_cint_operand" "n")
2918                     (match_operand:DI 4 "u6bit_cint_operand" "n")]
2919                    UNSPEC_INSN_BFINS))]
2920    ""
2921    "bfins\t%0, %r2, %3, %4"
2922    [(set_attr "type" "X0")])
2924 (define_insn "insn_cmpexch<four_if_si>"
2925   [(set (match_operand:I48MODE 0 "register_operand" "=r")
2926         (mem:I48MODE (match_operand 1 "pointer_operand" "rO")))
2927    (set (mem:I48MODE (match_dup 1))
2928         (unspec_volatile:I48MODE
2929          [(mem:I48MODE (match_dup 1))
2930           (reg:I48MODE TILEGX_CMPEXCH_REG)
2931           (match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
2932          UNSPEC_INSN_CMPEXCH))]
2933   ""
2934   "cmpexch<four_if_si>\t%0, %r1, %r2"
2935   [(set_attr "type" "X1_remote")])
2937 (define_insn "insn_cmul"
2938   [(set (match_operand:DI 0 "register_operand" "=r")
2939         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2940                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
2941                    UNSPEC_INSN_CMUL))]
2942   ""
2943   "cmul\t%0, %r1, %r2"
2944   [(set_attr "type" "X0_2cycle")])
2946 (define_insn "insn_cmula"
2947   [(set (match_operand:DI 0 "register_operand" "=r")
2948         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2949                     (match_operand:DI 2 "reg_or_0_operand" "rO")
2950                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
2951                    UNSPEC_INSN_CMULA))]
2952   ""
2953   "cmula\t%0, %r2, %r3"
2954   [(set_attr "type" "X0_2cycle")])
2956 (define_insn "insn_cmulaf"
2957   [(set (match_operand:DI 0 "register_operand" "=r")
2958         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2959                     (match_operand:DI 2 "reg_or_0_operand" "rO")
2960                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
2961                    UNSPEC_INSN_CMULAF))]
2962   ""
2963   "cmulaf\t%0, %r2, %r3"
2964   [(set_attr "type" "X0_2cycle")])
2966 (define_insn "insn_cmulf"
2967   [(set (match_operand:DI 0 "register_operand" "=r")
2968         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2969                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
2970                    UNSPEC_INSN_CMULF))]
2971   ""
2972   "cmulf\t%0, %r1, %r2"
2973   [(set_attr "type" "X0_2cycle")])
2975 (define_insn "insn_cmulfr"
2976   [(set (match_operand:DI 0 "register_operand" "=r")
2977         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2978                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
2979                    UNSPEC_INSN_CMULFR))]
2980   ""
2981   "cmulfr\t%0, %r1, %r2"
2982   [(set_attr "type" "X0_2cycle")])
2984 (define_insn "insn_cmulh"
2985   [(set (match_operand:DI 0 "register_operand" "=r")
2986         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2987                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
2988                    UNSPEC_INSN_CMULH))]
2989   ""
2990   "cmulh\t%0, %r1, %r2"
2991   [(set_attr "type" "X0_2cycle")])
2993 (define_insn "insn_cmulhr"
2994   [(set (match_operand:DI 0 "register_operand" "=r")
2995         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2996                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
2997                    UNSPEC_INSN_CMULHR))]
2998   ""
2999   "cmulhr\t%0, %r1, %r2"
3000   [(set_attr "type" "X0_2cycle")])
3002 (define_insn "insn_crc32_32"
3003   [(set (match_operand:DI 0 "register_operand" "=r")
3004         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3005                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3006                    UNSPEC_INSN_CRC32_32))]
3007   ""
3008   "crc32_32\t%0, %r1, %r2"
3009   [(set_attr "type" "X0")])
3011 (define_insn "insn_crc32_8"
3012   [(set (match_operand:DI 0 "register_operand" "=r")
3013         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3014                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3015                    UNSPEC_INSN_CRC32_8))]
3016   ""
3017   "crc32_8\t%0, %r1, %r2"
3018   [(set_attr "type" "X0")])
3020 (define_insn "insn_dblalign"
3021   [(set (match_operand:DI 0 "register_operand" "=r")
3022         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3023                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3024                     (match_operand 3 "pointer_operand" "rO")]
3025                    UNSPEC_INSN_DBLALIGN))]
3026   ""
3027   "dblalign\t%0, %r2, %r3"
3028   [(set_attr "type" "X0")])
3030 (define_insn "insn_dblalign2"
3031   [(set (match_operand:DI 0 "register_operand" "=r")
3032         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3033                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3034                    UNSPEC_INSN_DBLALIGN2))]
3035   ""
3036   "dblalign2\t%0, %r1, %r2"
3037   [(set_attr "type" "X01")])
3039 (define_insn "insn_dblalign4"
3040   [(set (match_operand:DI 0 "register_operand" "=r")
3041         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3042                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3043                    UNSPEC_INSN_DBLALIGN4))]
3044   ""
3045   "dblalign4\t%0, %r1, %r2"
3046   [(set_attr "type" "X01")])
3048 (define_insn "insn_dblalign6"
3049   [(set (match_operand:DI 0 "register_operand" "=r")
3050         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3051                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3052                    UNSPEC_INSN_DBLALIGN6))]
3053   ""
3054   "dblalign6\t%0, %r1, %r2"
3055   [(set_attr "type" "X01")])
3057 (define_insn "insn_dtlbpr"
3058   [(unspec_volatile:VOID [(match_operand:DI 0 "reg_or_0_operand" "rO")]
3059                          UNSPEC_INSN_DTLBPR)]
3060   ""
3061   "dtlbpr\t%r0"
3062   [(set_attr "type" "X1")])
3064 (define_insn "insn_exch<four_if_si>"
3065   [(set (match_operand:I48MODE 0 "register_operand" "=r")
3066         (mem:I48MODE (match_operand 1 "pointer_operand" "rO")))
3067    (set (mem:I48MODE (match_dup 1))
3068         (unspec_volatile:I48MODE
3069          [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
3070          UNSPEC_INSN_EXCH))]
3071   ""
3072   "exch<four_if_si>\t%0, %r1, %r2"
3073   [(set_attr "type" "X1_remote")])
3075 (define_insn "insn_fdouble_add_flags"
3076   [(set (match_operand:DI 0 "register_operand" "=r")
3077         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3078                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3079                    UNSPEC_INSN_FDOUBLE_ADD_FLAGS))]
3080   ""
3081   "fdouble_add_flags\t%0, %r1, %r2"
3082   [(set_attr "type" "X0_2cycle")])
3084 (define_insn "insn_fdouble_addsub"
3085   [(set (match_operand:DI 0 "register_operand" "=r")
3086         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3087                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3088                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3089                    UNSPEC_INSN_FDOUBLE_ADDSUB))]
3090   ""
3091   "fdouble_addsub\t%0, %r2, %r3"
3092   [(set_attr "type" "X0_2cycle")])
3094 (define_insn "insn_fdouble_mul_flags"
3095   [(set (match_operand:DI 0 "register_operand" "=r")
3096         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3097                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3098                    UNSPEC_INSN_FDOUBLE_MUL_FLAGS))]
3099   ""
3100   "fdouble_mul_flags\t%0, %r1, %r2"
3101   [(set_attr "type" "X0_2cycle")])
3103 (define_insn "insn_fdouble_pack1"
3104   [(set (match_operand:DI 0 "register_operand" "=r")
3105         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3106                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3107                    UNSPEC_INSN_FDOUBLE_PACK1))]
3108   ""
3109   "fdouble_pack1\t%0, %r1, %r2"
3110   [(set_attr "type" "X0_2cycle")])
3112 (define_insn "insn_fdouble_pack2"
3113   [(set (match_operand:DI 0 "register_operand" "=r")
3114         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3115                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3116                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3117                    UNSPEC_INSN_FDOUBLE_PACK2))]
3118   ""
3119   "fdouble_pack2\t%0, %r2, %r3"
3120   [(set_attr "type" "X0_2cycle")])
3122 (define_insn "insn_fdouble_sub_flags"
3123   [(set (match_operand:DI 0 "register_operand" "=r")
3124         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3125                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3126                    UNSPEC_INSN_FDOUBLE_SUB_FLAGS))]
3127   ""
3128   "fdouble_sub_flags\t%0, %r1, %r2"
3129   [(set_attr "type" "X0_2cycle")])
3131 (define_insn "insn_fdouble_unpack_max"
3132   [(set (match_operand:DI 0 "register_operand" "=r")
3133         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3134                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3135                    UNSPEC_INSN_FDOUBLE_UNPACK_MAX))]
3136   ""
3137   "fdouble_unpack_max\t%0, %r1, %r2"
3138   [(set_attr "type" "X0_2cycle")])
3140 (define_insn "insn_fdouble_unpack_min"
3141   [(set (match_operand:DI 0 "register_operand" "=r")
3142         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3143                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3144                    UNSPEC_INSN_FDOUBLE_UNPACK_MIN))]
3145   ""
3146   "fdouble_unpack_min\t%0, %r1, %r2"
3147   [(set_attr "type" "X0_2cycle")])
3149 (define_insn "insn_fetchadd<four_if_si>"
3150   [(set (match_operand:I48MODE 0 "register_operand" "=r")
3151         (unspec_volatile:I48MODE
3152          [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3153          UNSPEC_ATOMIC))
3154    (set (mem:I48MODE (match_dup 1))
3155         (plus:I48MODE (mem:I48MODE (match_dup 1))
3156                       (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
3157   ""
3158   "fetchadd<four_if_si>\t%0, %r1, %r2"
3159   [(set_attr "type" "X1_remote")])
3161 (define_insn "insn_fetchaddgez<four_if_si>"
3162   [(set (match_operand:I48MODE 0 "register_operand" "=r")
3163         (unspec_volatile:I48MODE
3164          [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3165          UNSPEC_ATOMIC))
3166    (set (mem:I48MODE (match_dup 1))
3167         (unspec:I48MODE [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
3168                          (mem:I48MODE (match_dup 1))]
3169                         UNSPEC_INSN_FETCHADDGEZ))]
3170   ""
3171   "fetchaddgez<four_if_si>\t%0, %r1, %r2"
3172   [(set_attr "type" "X1_remote")])
3174 (define_insn "insn_fetchand<four_if_si>"
3175   [(set (match_operand:I48MODE 0 "register_operand" "=r")
3176         (unspec_volatile:I48MODE
3177          [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3178          UNSPEC_ATOMIC))
3179    (set (mem:I48MODE (match_dup 1))
3180         (and:I48MODE (mem:I48MODE (match_dup 1))
3181                      (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
3182   ""
3183   "fetchand<four_if_si>\t%0, %r1, %r2"
3184   [(set_attr "type" "X1_remote")])
3186 (define_insn "insn_fetchor<four_if_si>"
3187   [(set (match_operand:I48MODE 0 "register_operand" "=r")
3188         (unspec_volatile:I48MODE
3189          [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3190          UNSPEC_ATOMIC))
3191    (set (mem:I48MODE (match_dup 1))
3192         (ior:I48MODE (mem:I48MODE (match_dup 1))
3193                      (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
3194   ""
3195   "fetchor<four_if_si>\t%0, %r1, %r2"
3196   [(set_attr "type" "X1_remote")])
3198 (define_insn "insn_finv"
3199   [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3200                          UNSPEC_INSN_FINV)]
3201   ""
3202   "finv\t%r0"
3203   [(set_attr "type" "X1")])
3205 (define_insn "insn_flush"
3206   [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3207                          UNSPEC_INSN_FLUSH)]
3208   ""
3209   "flush\t%r0"
3210   [(set_attr "type" "X1")])
3212 (define_insn "insn_flushwb"
3213   [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FLUSHWB)]
3214   ""
3215   "flushwb"
3216   [(set_attr "type" "X1")])
3218 (define_insn "insn_fnop"
3219   [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FNOP)]
3220   ""
3221   "fnop")
3223 (define_insn "insn_fsingle_add1"
3224   [(set (match_operand:DI 0 "register_operand" "=r")
3225         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3226                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3227                    UNSPEC_INSN_FSINGLE_ADD1))]
3228   ""
3229   "fsingle_add1\t%0, %r1, %r2"
3230   [(set_attr "type" "X0")])
3232 (define_insn "insn_fsingle_addsub2"
3233   [(set (match_operand:DI 0 "register_operand" "=r")
3234         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3235                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3236                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3237                    UNSPEC_INSN_FSINGLE_ADDSUB2))]
3238   ""
3239   "fsingle_addsub2\t%0, %r2, %r3"
3240   [(set_attr "type" "X0_2cycle")])
3242 (define_insn "insn_fsingle_mul1"
3243   [(set (match_operand:DI 0 "register_operand" "=r")
3244         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3245                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3246                    UNSPEC_INSN_FSINGLE_MUL1))]
3247   ""
3248   "fsingle_mul1\t%0, %r1, %r2"
3249   [(set_attr "type" "X0")])
3251 (define_insn "insn_fsingle_mul2"
3252   [(set (match_operand:DI 0 "register_operand" "=r")
3253         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3254                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3255                    UNSPEC_INSN_FSINGLE_MUL2))]
3256   ""
3257   "fsingle_mul2\t%0, %r1, %r2"
3258   [(set_attr "type" "X0_2cycle")])
3260 (define_insn "insn_fsingle_pack1"
3261   [(set (match_operand:DI 0 "register_operand" "=r")
3262         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")]
3263                    UNSPEC_INSN_FSINGLE_PACK1))]
3264   ""
3265   "fsingle_pack1\t%0, %r1"
3266   [(set_attr "type" "Y0_2cycle")])
3268 (define_insn "insn_fsingle_pack2"
3269   [(set (match_operand:DI 0 "register_operand" "=r")
3270         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3271                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3272                    UNSPEC_INSN_FSINGLE_PACK2))]
3273   ""
3274   "fsingle_pack2\t%0, %r1, %r2"
3275   [(set_attr "type" "X0_2cycle")])
3277 (define_insn "insn_fsingle_sub1"
3278   [(set (match_operand:DI 0 "register_operand" "=r")
3279         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3280                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3281                    UNSPEC_INSN_FSINGLE_SUB1))]
3282   ""
3283   "fsingle_sub1\t%0, %r1, %r2"
3284   [(set_attr "type" "X0")])
3286 (define_insn "insn_drain"
3287   [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_DRAIN)]
3288   ""
3289   "drain"
3290   [(set_attr "type" "cannot_bundle")])
3292 (define_insn "insn_icoh"
3293   [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")] 
3294                          UNSPEC_INSN_ICOH)]
3295   ""
3296   "icoh\t%r0"
3297   [(set_attr "type" "X1")])
3299 (define_insn "insn_ill"
3300   [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_ILL)]
3301   ""
3302   "ill"
3303   [(set_attr "type" "cannot_bundle")])
3305 (define_insn "insn_info"
3306   [(unspec_volatile:VOID [(match_operand:DI 0 "s8bit_cint_operand" "i")]
3307                          UNSPEC_INSN_INFO)]
3308   ""
3309   "info\t%0")
3311 (define_insn "insn_infol"
3312   [(unspec_volatile:VOID [(match_operand:DI 0 "s16bit_cint_operand" "i")]
3313                          UNSPEC_INSN_INFOL)]
3314   ""
3315   "infol\t%0"
3316   [(set_attr "type" "X01")])
3318 (define_insn "insn_inv"
3319   [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3320                          UNSPEC_INSN_INV)]
3321   ""
3322   "inv\t%r0"
3323   [(set_attr "type" "X1")])
3325 ;; loads
3327 (define_expand "insn_ld"
3328   [(set (match_operand:DI 0 "register_operand" "")
3329         (mem:DI (match_operand 1 "pointer_operand" "")))]
3330   "")
3332 (define_insn "insn_ld_add<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         (mem:DI (match_dup 3)))]
3338   ""
3339   "ld_add\t%0, %1, %2"
3340   [(set_attr "type" "X1_2cycle")])
3342 (define_insn "insn_ldna"
3343   [(set (match_operand:DI 0 "register_operand" "=r")
3344         (mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
3345                         (const_int -8))))]
3346   ""
3347   "ldna\t%0, %r1"
3348   [(set_attr "type" "X1_2cycle")])
3350 (define_insn "insn_ldna_add<bitsuffix>"
3351   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3352         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3353                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3354    (set (match_operand:DI 0 "register_operand" "=r")
3355         (mem:DI (and:DI (match_dup 3) (const_int -8))))]
3356   ""
3357   "ldna_add\t%0, %1, %2"
3358   [(set_attr "type" "X1_2cycle")])
3360 (define_expand "insn_ld<n><s>"
3361   [(set (match_operand:DI 0 "register_operand" "")
3362         (any_extend:DI
3363          (mem:I124MODE (match_operand 1 "pointer_operand" ""))))]
3364   "")
3366 (define_insn "insn_ld<I124MODE:n><s>_add<I48MODE:bitsuffix>"
3367   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3368         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3369                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3370    (set (match_operand:DI 0 "register_operand" "=r")
3371         (any_extend:DI (mem:I124MODE (match_dup 3))))]
3372   ""
3373   "ld<I124MODE:n><s>_add\t%0, %1, %2"
3374   [(set_attr "type" "X1_2cycle")])
3376 ;; non temporal loads
3378 (define_insn "insn_ldnt"
3379   [(set (match_operand:DI 0 "register_operand" "=r")
3380         (unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3381                    UNSPEC_NON_TEMPORAL))]
3382   ""
3383   "ldnt\t%0, %r1"
3384   [(set_attr "type" "X1_2cycle")])
3386 (define_insn "insn_ldnt_add<bitsuffix>"
3387   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3388         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3389                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3390    (set (match_operand:DI 0 "register_operand" "=r")
3391         (unspec:DI [(mem:DI (match_dup 3))]
3392                    UNSPEC_NON_TEMPORAL))]
3393   ""
3394   "ldnt_add\t%0, %1, %2"
3395   [(set_attr "type" "X1_2cycle")])
3397 (define_insn "insn_ldnt<n><s>"
3398   [(set (match_operand:DI 0 "register_operand" "=r")
3399         (any_extend:DI
3400          (unspec:I124MODE
3401           [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3402           UNSPEC_NON_TEMPORAL)))]
3403   ""
3404   "ldnt<n><s>\t%0, %r1"
3405   [(set_attr "type" "X1_2cycle")])
3407 (define_insn "insn_ldnt<I124MODE:n><s>_add<I48MODE:bitsuffix>"
3408   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3409         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3410                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3411    (set (match_operand:DI 0 "register_operand" "=r")
3412         (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
3413                                         UNSPEC_NON_TEMPORAL)))]
3414   ""
3415   "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
3416   [(set_attr "type" "X1_2cycle")])
3418 ;; L2 hits
3420 (define_insn "insn_ld_L2"
3421   [(set (match_operand:DI 0 "register_operand" "=r")
3422         (unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3423                    UNSPEC_LATENCY_L2))]
3424   ""
3425   "ld\t%0, %r1"
3426   [(set_attr "type" "Y2_L2")])
3428 (define_insn "insn_ld_add_L2<bitsuffix>"
3429   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3430         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3431                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3432    (set (match_operand:DI 0 "register_operand" "=r")
3433         (unspec:DI [(mem:DI (match_dup 3))]
3434                    UNSPEC_LATENCY_L2))]
3435   ""
3436   "ld_add\t%0, %1, %2"
3437   [(set_attr "type" "X1_L2")])
3439 (define_insn "insn_ldna_L2"
3440   [(set (match_operand:DI 0 "register_operand" "=r")
3441         (unspec:DI [(mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
3442                                     (const_int -8)))]
3443                    UNSPEC_LATENCY_L2))]
3444   ""
3445   "ldna\t%0, %r1"
3446   [(set_attr "type" "X1_L2")])
3448 (define_insn "insn_ldna_add_L2<bitsuffix>"
3449   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3450         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3451                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3452    (set (match_operand:DI 0 "register_operand" "=r")
3453         (unspec:DI [(mem:DI (and:DI (match_dup 3) (const_int -8)))]
3454                    UNSPEC_LATENCY_L2))]
3455   ""
3456   "ldna_add\t%0, %1, %2"
3457   [(set_attr "type" "X1_L2")])
3459 (define_insn "insn_ld<n><s>_L2"
3460   [(set (match_operand:DI 0 "register_operand" "=r")
3461         (any_extend:DI 
3462          (unspec:I124MODE
3463           [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3464           UNSPEC_LATENCY_L2)))]
3465   ""
3466   "ld<n><s>\t%0, %r1"
3467   [(set_attr "type" "Y2_L2")])
3469 (define_insn "insn_ld<I124MODE:n><s>_add_L2<I48MODE:bitsuffix>"
3470   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3471         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3472                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3473    (set (match_operand:DI 0 "register_operand" "=r")
3474         (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
3475                                         UNSPEC_LATENCY_L2)))]
3476   ""
3477   "ld<I124MODE:n><s>_add\t%0, %1, %2"
3478   [(set_attr "type" "X1_L2")])
3480 ;; L2 hits, non temporal loads
3482 (define_insn "insn_ldnt_L2"
3483   [(set (match_operand:DI 0 "register_operand" "=r")
3484         (unspec:DI [(unspec:DI
3485                      [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3486                      UNSPEC_NON_TEMPORAL)]
3487                    UNSPEC_LATENCY_L2))]
3488   ""
3489   "ldnt\t%0, %r1"
3490   [(set_attr "type" "X1_L2")])
3492 (define_insn "insn_ldnt_add_L2<bitsuffix>"
3493   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3494         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3495                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3496    (set (match_operand:DI 0 "register_operand" "=r")
3497         (unspec:DI [(unspec:DI
3498                      [(mem:DI (match_dup 3))]
3499                      UNSPEC_NON_TEMPORAL)]
3500                    UNSPEC_LATENCY_L2))]
3501                    ""
3502   "ldnt_add\t%0, %1, %2"
3503   [(set_attr "type" "X1_L2")])
3505 (define_insn "insn_ldnt<n><s>_L2"
3506   [(set (match_operand:DI 0 "register_operand" "=r")
3507         (any_extend:DI
3508          (unspec:I124MODE
3509           [(unspec:I124MODE
3510             [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3511             UNSPEC_NON_TEMPORAL)]
3512           UNSPEC_LATENCY_L2)))]
3513   ""
3514   "ldnt<n><s>\t%0, %r1"
3515   [(set_attr "type" "X1_L2")])
3517 (define_insn "insn_ldnt<I124MODE:n><s>_add_L2<I48MODE:bitsuffix>"
3518   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3519         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3520                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3521    (set (match_operand:DI 0 "register_operand" "=r")
3522         (any_extend:DI
3523          (unspec:I124MODE [(unspec:I124MODE
3524                             [(mem:I124MODE (match_dup 3))]
3525                             UNSPEC_NON_TEMPORAL)]
3526                           UNSPEC_LATENCY_L2)))]
3527   ""
3528   "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
3529   [(set_attr "type" "X1_L2")])
3531 ;; L2 miss
3533 (define_insn "insn_ld_miss"
3534   [(set (match_operand:DI 0 "register_operand" "=r")
3535         (unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3536                    UNSPEC_LATENCY_MISS))]
3537   ""
3538   "ld\t%0, %r1"
3539   [(set_attr "type" "Y2_miss")])
3541 (define_insn "insn_ld_add_miss<bitsuffix>"
3542   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3543         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3544                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3545    (set (match_operand:DI 0 "register_operand" "=r")
3546         (unspec:DI [(mem:DI (match_dup 3))]
3547                    UNSPEC_LATENCY_MISS))]
3548   ""
3549   "ld_add\t%0, %1, %2"
3550   [(set_attr "type" "X1_miss")])
3552 (define_insn "insn_ldna_miss"
3553   [(set (match_operand:DI 0 "register_operand" "=r")
3554         (unspec:DI [(mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
3555                                     (const_int -8)))]
3556                    UNSPEC_LATENCY_MISS))]
3557   ""
3558   "ldna\t%0, %r1"
3559   [(set_attr "type" "X1_miss")])
3561 (define_insn "insn_ldna_add_miss<bitsuffix>"
3562   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3563         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3564                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3565    (set (match_operand:DI 0 "register_operand" "=r")
3566         (unspec:DI [(mem:DI (and:DI (match_dup 3) (const_int -8)))]
3567                    UNSPEC_LATENCY_MISS))]
3568   ""
3569   "ldna_add\t%0, %1, %2"
3570   [(set_attr "type" "X1_miss")])
3572 (define_insn "insn_ld<n><s>_miss"
3573   [(set (match_operand:DI 0 "register_operand" "=r")
3574         (any_extend:DI 
3575          (unspec:I124MODE
3576           [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3577           UNSPEC_LATENCY_MISS)))]
3578   ""
3579   "ld<n><s>\t%0, %r1"
3580   [(set_attr "type" "Y2_miss")])
3582 (define_insn "insn_ld<I124MODE:n><s>_add_miss<I48MODE:bitsuffix>"
3583   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3584         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3585                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3586    (set (match_operand:DI 0 "register_operand" "=r")
3587         (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
3588                                         UNSPEC_LATENCY_MISS)))]
3589   ""
3590   "ld<I124MODE:n><s>_add\t%0, %1, %2"
3591   [(set_attr "type" "X1_miss")])
3593 ;; L2 miss, non temporal loads
3595 (define_insn "insn_ldnt_miss"
3596   [(set (match_operand:DI 0 "register_operand" "=r")
3597         (unspec:DI [(unspec:DI
3598                      [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3599                      UNSPEC_NON_TEMPORAL)]
3600                    UNSPEC_LATENCY_MISS))]
3601   ""
3602   "ldnt\t%0, %r1"
3603   [(set_attr "type" "X1_miss")])
3605 (define_insn "insn_ldnt_add_miss<bitsuffix>"
3606   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3607         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3608                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3609    (set (match_operand:DI 0 "register_operand" "=r")
3610         (unspec:DI [(unspec:DI
3611                      [(mem:DI (match_dup 3))]
3612                      UNSPEC_NON_TEMPORAL)]
3613                    UNSPEC_LATENCY_MISS))]
3614                    ""
3615   "ldnt_add\t%0, %1, %2"
3616   [(set_attr "type" "X1_miss")])
3618 (define_insn "insn_ldnt<n><s>_miss"
3619   [(set (match_operand:DI 0 "register_operand" "=r")
3620         (any_extend:DI
3621          (unspec:I124MODE
3622           [(unspec:I124MODE
3623             [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3624             UNSPEC_NON_TEMPORAL)]
3625           UNSPEC_LATENCY_MISS)))]
3626   ""
3627   "ldnt<n><s>\t%0, %r1"
3628   [(set_attr "type" "X1_miss")])
3630 (define_insn "insn_ldnt<I124MODE:n><s>_add_miss<I48MODE:bitsuffix>"
3631   [(set (match_operand:I48MODE 1 "register_operand" "=r")
3632         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3633                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3634    (set (match_operand:DI 0 "register_operand" "=r")
3635         (any_extend:DI
3636          (unspec:I124MODE [(unspec:I124MODE
3637                       [(mem:I124MODE (match_dup 3))]
3638                       UNSPEC_NON_TEMPORAL)]
3639                     UNSPEC_LATENCY_MISS)))]
3640   ""
3641   "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
3642   [(set_attr "type" "X1_miss")])
3644 ;; end loads
3646 (define_insn "insn_lnk"
3647   [(set (match_operand:DI 0 "register_operand" "=r")
3648         (unspec:DI [(const_int 0)] UNSPEC_INSN_LNK))]
3649   ""
3650   "lnk\t%0"
3651   [(set_attr "type" "Y1")])
3653 (define_insn "insn_mfspr"
3654   [(set (match_operand:DI 0 "register_operand" "=r")
3655         (unspec_volatile:DI [(match_operand:DI 1 "u14bit_cint_operand" "i")]
3656                             UNSPEC_INSN_MFSPR))
3657    (clobber (mem:BLK (const_int 0)))]
3658   ""
3659   "mfspr\t%0, %1"
3660   [(set_attr "type" "X1")])
3662 (define_insn "insn_mtspr"
3663   [(unspec_volatile:DI [(match_operand:DI 0 "u14bit_cint_operand" "i")
3664                         (match_operand:DI 1 "reg_or_0_operand" "rO")]
3665                        UNSPEC_INSN_MTSPR)
3666    (clobber (mem:BLK (const_int 0)))]
3667   ""
3668   "mtspr\t%0, %r1"
3669   [(set_attr "type" "X1")])
3671 (define_insn "insn_mm"
3672   [(set (match_operand:DI 0 "register_operand" "=r")
3673         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3674                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3675                     (match_operand:DI 3 "u6bit_cint_operand" "i")
3676                     (match_operand:DI 4 "u6bit_cint_operand" "i")]
3677                    UNSPEC_INSN_MM))]
3678   ""
3679   "mm\t%0, %r2, %3, %4"
3680   [(set_attr "type" "X0")])
3682 (define_insn "insn_mul_hs_hs"
3683   [(set (match_operand:DI 0 "register_operand" "=r")
3684         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3685                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3686                    UNSPEC_INSN_MUL_HS_HS))]
3687   ""
3688   "mul_hs_hs\t%0, %r1, %r2"
3689   [(set_attr "type" "Y0_2cycle")])
3691 (define_insn "insn_mul_hs_hu"
3692   [(set (match_operand:DI 0 "register_operand" "=r")
3693         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3694                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3695                    UNSPEC_INSN_MUL_HS_HU))]
3696   ""
3697   "mul_hs_hu\t%0, %r1, %r2"
3698   [(set_attr "type" "X0_2cycle")])
3700 (define_insn "insn_mul_hs_ls"
3701   [(set (match_operand:DI 0 "register_operand" "=r")
3702         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3703                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3704                    UNSPEC_INSN_MUL_HS_LS))]
3705   ""
3706   "mul_hs_ls\t%0, %r1, %r2"
3707   [(set_attr "type" "X0_2cycle")])
3709 (define_insn "insn_mul_hs_lu"
3710   [(set (match_operand:DI 0 "register_operand" "=r")
3711         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3712                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3713                    UNSPEC_INSN_MUL_HS_LU))]
3714   ""
3715   "mul_hs_lu\t%0, %r1, %r2"
3716   [(set_attr "type" "X0_2cycle")])
3718 (define_insn "insn_mul_hu_hu"
3719   [(set (match_operand:DI 0 "register_operand" "=r")
3720         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3721                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3722                    UNSPEC_INSN_MUL_HU_HU))]
3723   ""
3724   "mul_hu_hu\t%0, %r1, %r2"
3725   [(set_attr "type" "Y0_2cycle")])
3727 (define_insn "insn_mul_hu_ls"
3728   [(set (match_operand:DI 0 "register_operand" "=r")
3729         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3730                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3731                    UNSPEC_INSN_MUL_HU_LS))]
3732   ""
3733   "mul_hu_ls\t%0, %r1, %r2"
3734   [(set_attr "type" "X0_2cycle")])
3736 (define_insn "insn_mul_hu_lu"
3737   [(set (match_operand:DI 0 "register_operand" "=r")
3738         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3739                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3740                    UNSPEC_INSN_MUL_HU_LU))]
3741   ""
3742   "mul_hu_lu\t%0, %r1, %r2"
3743   [(set_attr "type" "X0_2cycle")])
3745 (define_insn "insn_mul_ls_ls"
3746   [(set (match_operand:DI 0 "register_operand" "=r")
3747         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3748                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3749                    UNSPEC_INSN_MUL_LS_LS))]
3750   ""
3751   "mul_ls_ls\t%0, %r1, %r2"
3752   [(set_attr "type" "Y0_2cycle")])
3754 (define_insn "insn_mul_ls_lu"
3755   [(set (match_operand:DI 0 "register_operand" "=r")
3756         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3757                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3758                    UNSPEC_INSN_MUL_LS_LU))]
3759   ""
3760   "mul_ls_lu\t%0, %r1, %r2"
3761   [(set_attr "type" "X0_2cycle")])
3763 (define_insn "insn_mul_lu_lu"
3764   [(set (match_operand:DI 0 "register_operand" "=r")
3765         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3766                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
3767                    UNSPEC_INSN_MUL_LU_LU))]
3768   ""
3769   "mul_lu_lu\t%0, %r1, %r2"
3770   [(set_attr "type" "Y0_2cycle")])
3772 (define_insn "insn_mula_hs_hs"
3773   [(set (match_operand:DI 0 "register_operand" "=r")
3774         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3775                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3776                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3777                    UNSPEC_INSN_MULA_HS_HS))]
3778   ""
3779   "mula_hs_hs\t%0, %r2, %r3"
3780   [(set_attr "type" "Y0_2cycle")])
3782 (define_insn "insn_mula_hs_hu"
3783   [(set (match_operand:DI 0 "register_operand" "=r")
3784         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3785                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3786                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3787                    UNSPEC_INSN_MULA_HS_HU))]
3788   ""
3789   "mula_hs_hu\t%0, %r2, %r3"
3790   [(set_attr "type" "X0_2cycle")])
3792 (define_insn "insn_mula_hs_ls"
3793   [(set (match_operand:DI 0 "register_operand" "=r")
3794         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3795                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3796                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3797                    UNSPEC_INSN_MULA_HS_LS))]
3798   ""
3799   "mula_hs_ls\t%0, %r2, %r3"
3800   [(set_attr "type" "X0_2cycle")])
3802 (define_insn "insn_mula_hs_lu"
3803   [(set (match_operand:DI 0 "register_operand" "=r")
3804         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3805                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3806                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3807                    UNSPEC_INSN_MULA_HS_LU))]
3808   ""
3809   "mula_hs_lu\t%0, %r2, %r3"
3810   [(set_attr "type" "X0_2cycle")])
3812 (define_insn "insn_mula_hu_hu"
3813   [(set (match_operand:DI 0 "register_operand" "=r")
3814         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3815                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3816                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3817                    UNSPEC_INSN_MULA_HU_HU))]
3818   ""
3819   "mula_hu_hu\t%0, %r2, %r3"
3820   [(set_attr "type" "Y0_2cycle")])
3822 (define_insn "insn_mula_hu_ls"
3823   [(set (match_operand:DI 0 "register_operand" "=r")
3824         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3825                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3826                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3827                    UNSPEC_INSN_MULA_HU_LS))]
3828   ""
3829   "mula_hu_ls\t%0, %r2, %r3"
3830   [(set_attr "type" "X0_2cycle")])
3832 (define_insn "insn_mula_hu_lu"
3833   [(set (match_operand:DI 0 "register_operand" "=r")
3834         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3835                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3836                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3837                    UNSPEC_INSN_MULA_HU_LU))]
3838   ""
3839   "mula_hu_lu\t%0, %r2, %r3"
3840   [(set_attr "type" "X0_2cycle")])
3842 (define_insn "insn_mula_ls_ls"
3843   [(set (match_operand:DI 0 "register_operand" "=r")
3844         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3845                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3846                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3847                    UNSPEC_INSN_MULA_LS_LS))]
3848   ""
3849   "mula_ls_ls\t%0, %r2, %r3"
3850   [(set_attr "type" "Y0_2cycle")])
3852 (define_insn "insn_mula_ls_lu"
3853   [(set (match_operand:DI 0 "register_operand" "=r")
3854         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3855                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3856                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3857                    UNSPEC_INSN_MULA_LS_LU))]
3858   ""
3859   "mula_ls_lu\t%0, %r2, %r3"
3860   [(set_attr "type" "X0_2cycle")])
3862 (define_insn "insn_mula_lu_lu"
3863   [(set (match_operand:DI 0 "register_operand" "=r")
3864         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3865                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3866                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3867                    UNSPEC_INSN_MULA_LU_LU))]
3868   ""
3869   "mula_lu_lu\t%0, %r2, %r3"
3870   [(set_attr "type" "Y0_2cycle")])
3872 (define_insn "insn_mulax"
3873   [(set (match_operand:SI 0 "register_operand" "=r")
3874         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3875                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3876                     (match_operand:SI 3 "reg_or_0_operand" "rO")]
3877                    UNSPEC_INSN_MULAX))]
3878   ""
3879   "mulax\t%0, %r2, %r3"
3880   [(set_attr "type" "Y0_2cycle")])
3882 (define_insn "insn_nap"
3883   [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_NAP)]
3884   ""
3885   "nap"
3886   [(set_attr "type" "cannot_bundle")])
3888 (define_insn "insn_nor_<mode>"
3889   [(set (match_operand:I48MODE 0 "register_operand" "=r")
3890         (and:I48MODE
3891          (not:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO"))
3892          (not:I48MODE (match_operand:I48MODE 2 "reg_or_0_operand" "rO"))))]
3893   ""
3894   "nor\t%0, %r1, %r2")
3896 (define_expand "insn_prefetch_l1"
3897   [(prefetch (match_operand 0 "pointer_operand" "")
3898              (const_int 0)
3899              (const_int 3))]
3900   "")
3902 (define_expand "insn_prefetch_l2"
3903   [(prefetch (match_operand 0 "pointer_operand" "")
3904              (const_int 0)
3905              (const_int 2))]
3906   "")
3908 (define_expand "insn_prefetch_l3"
3909   [(prefetch (match_operand 0 "pointer_operand" "")
3910              (const_int 0)
3911              (const_int 1))]
3912   "")
3914 (define_insn "insn_prefetch_l1_fault"
3915   [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3916                          UNSPEC_INSN_PREFETCH_L1_FAULT)]
3917   ""
3918   "prefetch_l1_fault\t%r0"
3919   [(set_attr "type" "Y2")])
3921 (define_insn "insn_prefetch_l2_fault"
3922   [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3923                          UNSPEC_INSN_PREFETCH_L2_FAULT)]
3924   ""
3925   "prefetch_l2_fault\t%r0"
3926   [(set_attr "type" "Y2")])
3928 (define_insn "insn_prefetch_l3_fault"
3929   [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3930                          UNSPEC_INSN_PREFETCH_L3_FAULT)]
3931   ""
3932   "prefetch_l3_fault\t%r0"
3933   [(set_attr "type" "Y2")])
3935 (define_insn "insn_revbits"
3936   [(set (match_operand:DI 0 "register_operand" "=r")
3937         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")]
3938                    UNSPEC_INSN_REVBITS))]
3939   ""
3940   "revbits\t%0, %r1"
3941   [(set_attr "type" "Y0")])
3943 (define_insn "insn_shl1add"
3944   [(set (match_operand:DI 0 "register_operand" "=r")
3945         (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
3946                           (const_int 2))
3947                  (match_operand:DI 2 "reg_or_0_operand" "rO")))]
3948   ""
3949   "shl1add\t%0, %r1, %r2")
3951 (define_insn "insn_shl1addx"
3952   [(set (match_operand:SI 0 "register_operand" "=r")
3953         (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
3954                           (const_int 2))
3955                  (match_operand:SI 2 "reg_or_0_operand" "rO")))]
3956   ""
3957   "shl1addx\t%0, %r1, %r2")
3959 (define_insn "insn_shl2add"
3960   [(set (match_operand:DI 0 "register_operand" "=r")
3961         (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
3962                           (const_int 4))
3963                  (match_operand:DI 2 "reg_or_0_operand" "rO")))]
3964   ""
3965   "shl2add\t%0, %r1, %r2")
3967 (define_insn "insn_shl2addx"
3968   [(set (match_operand:SI 0 "register_operand" "=r")
3969         (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
3970                           (const_int 4))
3971                  (match_operand:SI 2 "reg_or_0_operand" "rO")))]
3972   ""
3973   "shl2addx\t%0, %r1, %r2")
3975 (define_insn "insn_shl3add"
3976   [(set (match_operand:DI 0 "register_operand" "=r")
3977         (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
3978                           (const_int 8))
3979                  (match_operand:DI 2 "reg_or_0_operand" "rO")))]
3980   ""
3981   "shl3add\t%0, %r1, %r2")
3983 (define_insn "insn_shl3addx"
3984   [(set (match_operand:SI 0 "register_operand" "=r")
3985         (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
3986                           (const_int 8))
3987                  (match_operand:SI 2 "reg_or_0_operand" "rO")))]
3988   ""
3989   "shl3addx\t%0, %r1, %r2")
3991 (define_insn "insn_shufflebytes"
3992   [(set (match_operand:DI 0 "register_operand" "=r")
3993         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3994                     (match_operand:DI 2 "reg_or_0_operand" "rO")
3995                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
3996                    UNSPEC_INSN_SHUFFLEBYTES))]
3997   ""
3998   "shufflebytes\t%0, %r2, %r3"
3999   [(set_attr "type" "X0")])
4001 (define_insn "insn_shufflebytes1"
4002   [(set (match_operand:DI 0 "register_operand" "=r")
4003         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
4004                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
4005                    UNSPEC_INSN_SHUFFLEBYTES))]
4006   ""
4007   "shufflebytes\t%0, %r1, %r2"
4008   [(set_attr "type" "X0")])
4010 ;; stores
4012 (define_expand "insn_st"
4013   [(set (mem:DI (match_operand 0 "pointer_operand" ""))
4014         (match_operand:DI 1 "reg_or_0_operand" ""))]
4015   "")
4017 (define_insn "insn_st_add<bitsuffix>"
4018   [(set (match_operand:I48MODE 0 "register_operand" "=r")
4019         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4020                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
4021    (set (mem:DI (match_dup 3))
4022         (match_operand:DI 1 "reg_or_0_operand" "rO"))]
4023   ""
4024   "st_add\t%0, %r1, %2"
4025   [(set_attr "type" "X1")])
4027 (define_expand "insn_st<n>"
4028   [(set (mem:I124MODE (match_operand 0 "pointer_operand" ""))
4029         (match_operand:DI 1 "reg_or_0_operand" ""))]
4030   ""
4032   operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], DImode,
4033                                      BYTES_BIG_ENDIAN
4034                                      ? UNITS_PER_WORD - <n>  : 0);
4037 (define_expand "insn_st<I124MODE:n>_add<I48MODE:bitsuffix>"
4038   [(parallel
4039     [(set (match_operand:I48MODE 0 "register_operand" "")
4040           (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "")
4041                         (match_operand:I48MODE 2 "s8bit_cint_operand" "")))
4042      (set (mem:I124MODE (match_dup 3))
4043           (match_operand:DI 1 "reg_or_0_operand" ""))])]
4044   ""
4046   operands[1] = simplify_gen_subreg (<I124MODE:MODE>mode, operands[1],
4047                                      DImode,
4048                                      BYTES_BIG_ENDIAN
4049                                      ? UNITS_PER_WORD - <I124MODE:n> : 0);
4052 (define_insn "*insn_st<I124MODE:n>_add<I48MODE:bitsuffix>"
4053   [(set (match_operand:I48MODE 0 "register_operand" "=r")
4054         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4055                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
4056    (set (mem:I124MODE (match_dup 3))
4057         (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
4058   ""
4059   "st<I124MODE:n>_add\t%0, %r1, %2"
4060   [(set_attr "type" "X1")])
4062 ;; non-temporal stores
4064 (define_insn "insn_stnt"
4065   [(set (mem:DI (unspec [(match_operand 0 "pointer_operand" "rO")]
4066                         UNSPEC_NON_TEMPORAL))
4067         (match_operand:DI 1 "reg_or_0_operand" "rO"))]
4068   ""
4069   "stnt\t%0, %r1"
4070   [(set_attr "type" "X1")])
4072 (define_insn "insn_stnt_add<bitsuffix>"
4073   [(set (match_operand:I48MODE 0 "register_operand" "=r")
4074         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4075                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
4076    (set (mem:DI (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
4077         (match_operand:DI 1 "reg_or_0_operand" "rO"))]
4078   ""
4079   "stnt_add\t%0, %r1, %2"
4080   [(set_attr "type" "X1")])
4082 (define_expand "insn_stnt<n>"
4083   [(set (mem:I124MODE (unspec [(match_operand 0 "pointer_operand" "")]
4084                               UNSPEC_NON_TEMPORAL))
4085         (match_operand:DI 1 "reg_or_0_operand" ""))]
4086   ""
4088   operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], DImode,
4089                                      BYTES_BIG_ENDIAN
4090                                      ? UNITS_PER_WORD - <n> : 0);
4093 (define_insn "*insn_stnt<n>"
4094   [(set (mem:I124MODE (unspec [(match_operand 0 "pointer_operand" "rO")]
4095                               UNSPEC_NON_TEMPORAL))
4096         (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
4097   ""
4098   "stnt<n>\t%0, %r1"
4099   [(set_attr "type" "X1")])
4101 (define_expand "insn_stnt<I124MODE:n>_add<I48MODE:bitsuffix>"
4102   [(parallel
4103     [(set (match_operand:I48MODE 0 "register_operand" "")
4104           (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "")
4105                         (match_operand:I48MODE 2 "s8bit_cint_operand" "")))
4106      (set (mem:I124MODE (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
4107           (match_operand:DI 1 "reg_or_0_operand" "rO"))])]
4108   ""
4110   operands[1] = simplify_gen_subreg (<I124MODE:MODE>mode, operands[1],
4111                                      DImode,
4112                                      BYTES_BIG_ENDIAN
4113                                      ? UNITS_PER_WORD - <n> : 0);
4116 (define_insn "*insn_stnt<I124MODE:n>_add<I48MODE:bitsuffix>"
4117   [(set (match_operand:I48MODE 0 "register_operand" "=r")
4118         (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4119                       (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
4120    (set (mem:I124MODE (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
4121         (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
4122   ""
4123   "stnt<I124MODE:n>_add\t%0, %r1, %2"
4124   [(set_attr "type" "X1")])
4126 ;; end stores
4128 (define_insn "insn_tblidxb0"
4129   [(set (match_operand:DI 0 "register_operand" "=r")
4130         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4131                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
4132                    UNSPEC_INSN_TBLIDXB0))]
4133   ""
4134   "tblidxb0\t%0, %r2"
4135   [(set_attr "type" "Y0")])
4137 (define_insn "insn_tblidxb1"
4138   [(set (match_operand:DI 0 "register_operand" "=r")
4139         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4140                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
4141                    UNSPEC_INSN_TBLIDXB1))]
4142   ""
4143   "tblidxb1\t%0, %r2"
4144   [(set_attr "type" "Y0")])
4146 (define_insn "insn_tblidxb2"
4147   [(set (match_operand:DI 0 "register_operand" "=r")
4148         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4149                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
4150                    UNSPEC_INSN_TBLIDXB2))]
4151   ""
4152   "tblidxb2\t%0, %r2"
4153   [(set_attr "type" "Y0")])
4155 (define_insn "insn_tblidxb3"
4156   [(set (match_operand:DI 0 "register_operand" "=r")
4157         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4158                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
4159                    UNSPEC_INSN_TBLIDXB3))]
4160   ""
4161   "tblidxb3\t%0, %r2"
4162   [(set_attr "type" "Y0")])
4164 ;; insn_v1add
4165 ;; insn_v1addi
4166 ;; insn_v1cmpeq
4167 ;; insn_v1cmpeqi
4168 ;; insn_v1cmplts
4169 ;; insn_v1cmpltsi
4170 ;; insn_v1cmpltu
4171 ;; insn_v1cmpltui
4172 ;; insn_v1maxu
4173 ;; insn_v1maxui
4174 ;; insn_v1minu
4175 ;; insn_v1minui
4176 (define_insn "<optab>v8qi3"
4177   [(set (match_operand:V8QI 0 "register_operand" "=r,r")
4178         (v1op_immed:V8QI
4179          (match_operand:V8QI 1 "reg_or_0_operand" "<comm>rO,rO")
4180          (match_operand:V8QI 2 "reg_or_v8s8bit_operand" "W,rO")))]
4181   ""
4182   "@
4183    v1<insn>i\t%0, %r1, %j2
4184    v1<insn>\t%0, %r1, %r2"
4185   [(set_attr "type" "<pipe>,<pipe>")])
4187 (define_expand "insn_v1<insn>"
4188   [(set (match_operand:DI 0 "register_operand" "")
4189         (v1op_immed:V8QI
4190          (match_operand:DI 1 "reg_or_0_operand" "")
4191          (match_operand:DI 2 "reg_or_0_operand" "")))]
4192   ""
4194   tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4195                                       V8QImode, operands[1], operands[2], true);
4196   DONE;
4199 (define_expand "insn_v1<insn>i"
4200   [(set (match_operand:DI 0 "register_operand" "")
4201         (v1op_immed:V8QI
4202          (match_operand:DI 1 "reg_or_0_operand" "")
4203          (match_operand:DI 2 "s8bit_cint_operand" "")))]
4204   ""
4206   /* Tile out immediate and expand to general case. */
4207   rtx n = tilegx_simd_int (operands[2], QImode);
4208   tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4209                                       V8QImode, operands[1], n, true);
4210   DONE;
4213 ;; insn_v1shl
4214 ;; insn_v1shli
4215 ;; insn_v1shrs
4216 ;; insn_v1shrsi
4217 ;; insn_v1shru
4218 ;; insn_v1shrui
4219 (define_insn "<optab>v8qi3"
4220   [(set (match_operand:V8QI 0 "register_operand" "=r,r")
4221         (any_shift:V8QI
4222          (match_operand:V8QI 1 "reg_or_0_operand" "rO,rO")
4223          (match_operand:DI 2 "reg_or_u5bit_operand" "I,rO")))]
4224   ""
4225   "@
4226    v1<insn>i\t%0, %r1, %2
4227    v1<insn>\t%0, %r1, %r2"
4228   [(set_attr "type" "<pipe>,<pipe>")])
4230 (define_expand "insn_v1<insn>"
4231   [(set (match_operand:DI 0 "register_operand" "")
4232         (any_shift:V8QI
4233          (match_operand:DI 1 "reg_or_0_operand" "")
4234          (match_operand:DI 2 "reg_or_u5bit_operand" "")))]
4235   ""
4237   tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4238                                       V8QImode, operands[1], operands[2], false);
4239   DONE;
4242 ;; insn_v2add
4243 ;; insn_v2addi
4244 ;; insn_v2maxs
4245 ;; insn_v2maxsi
4246 ;; insn_v2mins
4247 ;; insn_v2minsi
4248 ;; insn_v2cmpeq
4249 ;; insn_v2cmpeqi
4250 ;; insn_v2cmplts
4251 ;; insn_v2cmpltsi
4252 ;; insn_v2cmpltu
4253 ;; insn_v2cmpltui
4254 (define_insn "<optab>v4hi3"
4255   [(set (match_operand:V4HI 0 "register_operand" "=r,r")
4256         (v2op_immed:V4HI
4257          (match_operand:V4HI 1 "reg_or_0_operand" "<comm>rO,rO")
4258          (match_operand:V4HI 2 "reg_or_v4s8bit_operand" "Y,rO")))]
4259   ""
4260   "@
4261    v2<insn>i\t%0, %r1, %j2
4262    v2<insn>\t%0, %r1, %r2"
4263   [(set_attr "type" "<pipe>,<pipe>")])
4265 (define_expand "insn_v2<insn>"
4266   [(set (match_operand:DI 0 "register_operand" "")
4267         (v2op_immed:V4HI
4268          (match_operand:DI 1 "reg_or_0_operand" "")
4269          (match_operand:DI 2 "reg_or_0_operand" "")))]
4270   ""
4272   tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4273                                       V4HImode, operands[1], operands[2], true);
4274   DONE;
4277 (define_expand "insn_v2<insn>i"
4278   [(set (match_operand:DI 0 "register_operand" "")
4279         (v2op_immed:V4HI
4280          (match_operand:DI 1 "reg_or_0_operand" "")
4281          (match_operand:DI 2 "s8bit_cint_operand" "")))]
4282   ""
4284   /* Tile out immediate and expand to general case. */
4285   rtx n = tilegx_simd_int (operands[2], HImode);
4286   tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4287                                       V4HImode, operands[1], n, true);
4288   DONE;
4291 ;; insn_v2shl
4292 ;; insn_v2shli
4293 ;; insn_v2shrs
4294 ;; insn_v2shrsi
4295 ;; insn_v2shru
4296 ;; insn_v2shrui
4297 (define_insn "<optab>v4hi3"
4298   [(set (match_operand:V4HI 0 "register_operand" "=r,r")
4299         (any_shift:V4HI
4300          (match_operand:V4HI 1 "reg_or_0_operand" "rO,rO")
4301          (match_operand:DI 2 "reg_or_u5bit_operand" "I,rO")))]
4302   ""
4303   "@
4304    v2<insn>i\t%0, %r1, %2
4305    v2<insn>\t%0, %r1, %r2"
4306   [(set_attr "type" "<pipe>,<pipe>")])
4308 (define_expand "insn_v2<insn>"
4309   [(set (match_operand:DI 0 "register_operand" "")
4310         (any_shift:V4HI
4311          (match_operand:DI 1 "reg_or_0_operand" "")
4312          (match_operand:DI 2 "reg_or_u5bit_operand" "")))]
4313   ""
4315   tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4316                                       V4HImode, operands[1], operands[2], false);
4317   DONE;
4320 ;; insn_v1adduc
4321 ;; insn_v1subuc
4322 ;; insn_v1sub
4323 ;; insn_v1cmpne
4324 ;; insn_v1cmples
4325 ;; insn_v1cmpleu
4326 ;; insn_v1multu
4327 (define_insn "<optab>v8qi3"
4328   [(set (match_operand:V8QI 0 "register_operand" "=r")
4329         (v1op:V8QI
4330          (match_operand:V8QI 1 "reg_or_0_operand" "<comm>rO")
4331          (match_operand:V8QI 2 "reg_or_0_operand" "rO")))]
4332   ""
4333   "v1<insn>\t%0, %r1, %r2"
4334   [(set_attr "type" "<pipe>")])
4336 (define_expand "insn_v1<insn>"
4337   [(set (match_operand:DI 0 "register_operand" "")
4338         (v1op:V8QI
4339          (match_operand:DI 1 "reg_or_0_operand" "")
4340          (match_operand:DI 2 "reg_or_0_operand" "")))]
4341   ""
4343   tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4344                                       V8QImode, operands[1], operands[2], true);
4345   DONE;
4348 ;; insn_v2addsc
4349 ;; insn_v2subsc
4350 ;; insn_v2sub
4351 ;; insn_v2cmpne
4352 ;; insn_v2cmples
4353 ;; insn_v2cmpleu
4354 (define_insn "<optab>v4hi3"
4355   [(set (match_operand:V4HI 0 "register_operand" "=r")
4356         (v2op:V4HI
4357          (match_operand:V4HI 1 "reg_or_0_operand" "<comm>rO")
4358          (match_operand:V4HI 2 "reg_or_0_operand" "rO")))]
4359   ""
4360   "v2<insn>\t%0, %r1, %r2"
4361   [(set_attr "type" "<pipe>")])
4363 (define_expand "insn_v2<insn>"
4364   [(set (match_operand:DI 0 "register_operand" "")
4365         (v2op:V4HI
4366          (match_operand:DI 1 "reg_or_0_operand" "")
4367          (match_operand:DI 2 "reg_or_0_operand" "")))]
4368   ""
4370   tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4371                                       V4HImode, operands[1], operands[2], true);
4372   DONE;
4375 ;; insn_v2mults
4376 (define_insn "mulv4hi3"
4377   [(set (match_operand:V4HI 0 "register_operand" "=r")
4378         (mult:V4HI
4379          (match_operand:V4HI 1 "reg_or_0_operand" "%rO")
4380          (match_operand:V4HI 2 "reg_or_0_operand" "rO")))]
4381   ""
4382   "v2mults\t%0, %r1, %r2"
4383   [(set_attr "type" "X0_2cycle")])
4385 (define_expand "insn_v2mults"
4386   [(set (match_operand:DI 0 "register_operand" "")
4387         (mult:V4HI
4388          (match_operand:DI 1 "reg_or_0_operand" "")
4389          (match_operand:DI 2 "reg_or_0_operand" "")))]
4390   ""
4392   tilegx_expand_builtin_vector_binop (gen_mulv4hi3, V4HImode, operands[0],
4393                                       V4HImode, operands[1], operands[2], true);
4394   DONE;
4397 ;; insn_v2shlsc
4398 (define_insn "<optab>v4hi3"
4399   [(set (match_operand:V4HI 0 "register_operand" "=r")
4400         (v2shift:V4HI
4401          (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4402          (match_operand:DI 2 "reg_or_0_operand" "rO")))]
4403   ""
4404   "v2<insn>\t%0, %r1, %r2"
4405   [(set_attr "type" "<pipe>")])
4407 (define_expand "insn_v2<insn>"
4408   [(set (match_operand:DI 0 "register_operand" "")
4409         (v2shift:V4HI
4410          (match_operand:DI 1 "reg_or_0_operand" "")
4411          (match_operand:DI 2 "reg_or_0_operand" "")))]
4412   ""
4414   tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4415                                       V4HImode, operands[1], operands[2], false);
4416   DONE;
4419 ;; insn_v4addsc
4420 ;; insn_v4subsc
4421 ;; insn_v4add
4422 ;; insn_v4sub
4423 (define_insn "<optab>v2si3"
4424   [(set (match_operand:V2SI 0 "register_operand" "=r")
4425         (v4op:V2SI
4426          (match_operand:V2SI 1 "reg_or_0_operand" "<comm>rO")
4427          (match_operand:V2SI 2 "reg_or_0_operand" "rO")))]
4428   ""
4429   "v4<insn>\t%0, %r1, %r2"
4430   [(set_attr "type" "<pipe>")])
4432 (define_expand "insn_v4<insn>"
4433   [(set (match_operand:DI 0 "register_operand" "")
4434         (v4op:V2SI
4435          (match_operand:DI 1 "reg_or_0_operand" "")
4436          (match_operand:DI 2 "reg_or_0_operand" "")))]
4437   ""
4439   tilegx_expand_builtin_vector_binop (gen_<optab>v2si3, V2SImode, operands[0],
4440                                       V2SImode, operands[1], operands[2], true);
4441   DONE;
4444 ;; insn_v4shl
4445 ;; insn_v4shrs
4446 ;; insn_v4shru
4447 ;; insn_v4shlsc
4448 (define_insn "<optab>v2si3"
4449   [(set (match_operand:V2SI 0 "register_operand" "=r")
4450         (v4shift:V2SI
4451          (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4452          (match_operand:DI 2 "reg_or_0_operand" "rO")))]
4453   ""
4454   "v4<insn>\t%0, %r1, %r2"
4455   [(set_attr "type" "<pipe>")])
4457 (define_expand "insn_v4<insn>"
4458   [(set (match_operand:DI 0 "register_operand" "")
4459         (v4shift:V2SI
4460          (match_operand:DI 1 "reg_or_0_operand" "")
4461          (match_operand:DI 2 "reg_or_0_operand" "")))]
4462   ""
4464   tilegx_expand_builtin_vector_binop (gen_<optab>v2si3, V2SImode, operands[0],
4465                                       V2SImode, operands[1], operands[2], false);
4466   DONE;
4469 ;; Byte ordering of these vectors is endian dependent.  gcc concats
4470 ;; right-to-left for little endian, and left-to-right for big endian.
4471 ;; So we need different patterns that depend on endianness.  Our
4472 ;; instructions concat and interleave the way a big-endian target would
4473 ;; work in gcc, so for little endian, we need to reverse the source
4474 ;; operands.
4476 ;; insn_v1int_h
4477 ;;    {B7,B6,B5,B4,B3,B2,B1,B0} {A7,A6,A5,A4,A3,A2,A1,A0}
4478 ;; => {A7,A6,A5,A4,A3,A2,A1,A0,B7,B6,B5,B4,B3,B2,B1,B0}
4479 ;; => {A7,B7,A6,B6,A5,B5,A4,B4}
4480 (define_expand "vec_interleave_highv8qi"
4481   [(match_operand:V8QI 0 "register_operand" "")
4482    (match_operand:V8QI 1 "reg_or_0_operand" "")
4483    (match_operand:V8QI 2 "reg_or_0_operand" "")]
4484   ""
4486   if (BYTES_BIG_ENDIAN)
4487     emit_insn (gen_vec_interleave_highv8qi_be (operands[0], operands[1],
4488                                                operands[2]));
4489   else
4490     emit_insn (gen_vec_interleave_highv8qi_le (operands[0], operands[1],
4491                                                operands[2]));
4492   DONE;
4495 (define_insn "vec_interleave_highv8qi_be"
4496   [(set (match_operand:V8QI 0 "register_operand" "=r")
4497         (vec_select:V8QI
4498          (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4499                            (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4500          (parallel [(const_int 0) (const_int 8)
4501                     (const_int 1) (const_int 9)
4502                     (const_int 2) (const_int 10)
4503                     (const_int 3) (const_int 11)])))]
4504   "BYTES_BIG_ENDIAN"
4505   "v1int_h\t%0, %r1, %r2"
4506   [(set_attr "type" "X01")])
4508 (define_insn "vec_interleave_highv8qi_le"
4509   [(set (match_operand:V8QI 0 "register_operand" "=r")
4510         (vec_select:V8QI
4511          (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4512                            (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4513          (parallel [(const_int 4) (const_int 12) 
4514                     (const_int 5) (const_int 13) 
4515                     (const_int 6) (const_int 14) 
4516                     (const_int 7) (const_int 15)])))]
4517   "!BYTES_BIG_ENDIAN"
4518   "v1int_h\t%0, %r2, %r1"
4519   [(set_attr "type" "X01")])
4521 (define_expand "insn_v1int_h"
4522   [(match_operand:DI 0 "register_operand" "")
4523    (match_operand:DI 1 "reg_or_0_operand" "")
4524    (match_operand:DI 2 "reg_or_0_operand" "")]
4525   ""
4527   /* For little endian, our instruction interleaves opposite of the
4528      way vec_interleave works, so we need to reverse the source
4529      operands.  */
4530   rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4531   rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4532   tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv8qi, V8QImode,
4533                                       operands[0], V8QImode, opnd1, opnd2,
4534                                       true);
4535   DONE;
4538 ;; insn_v1int_l
4539 ;;    {B7,B6,B5,B4,B3,B2,B1,B0} {A7,A6,A5,A4,A3,A2,A1,A0}
4540 ;; => {A7,A6,A5,A4,A3,A2,A1,A0,B7,B6,B5,B4,B3,B2,B1,B0}
4541 ;; => {A3,B3,A2,B2,A1,B1,A0,B0}
4542 (define_expand "vec_interleave_lowv8qi"
4543   [(match_operand:V8QI 0 "register_operand" "")
4544    (match_operand:V8QI 1 "reg_or_0_operand" "")
4545    (match_operand:V8QI 2 "reg_or_0_operand" "")]
4546   ""
4548   if (BYTES_BIG_ENDIAN)
4549     emit_insn (gen_vec_interleave_lowv8qi_be (operands[0], operands[1],
4550                                               operands[2]));
4551   else
4552     emit_insn (gen_vec_interleave_lowv8qi_le (operands[0], operands[1],
4553                                               operands[2]));
4554   DONE;
4557 (define_insn "vec_interleave_lowv8qi_be"
4558   [(set (match_operand:V8QI 0 "register_operand" "=r")
4559         (vec_select:V8QI
4560          (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4561                            (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4562          (parallel [(const_int 4) (const_int 12)
4563                     (const_int 5) (const_int 13)
4564                     (const_int 6) (const_int 14)
4565                     (const_int 7) (const_int 15)])))]
4566   "BYTES_BIG_ENDIAN"
4567   "v1int_l\t%0, %r1, %r2"
4568   [(set_attr "type" "X01")])
4570 (define_insn "vec_interleave_lowv8qi_le"
4571   [(set (match_operand:V8QI 0 "register_operand" "=r")
4572         (vec_select:V8QI
4573          (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4574                            (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4575          (parallel [(const_int 0) (const_int 8)
4576                     (const_int 1) (const_int 9)
4577                     (const_int 2) (const_int 10)
4578                     (const_int 3) (const_int 11)])))]
4579   "!BYTES_BIG_ENDIAN"
4580   "v1int_l\t%0, %r2, %r1"
4581   [(set_attr "type" "X01")])
4583 (define_expand "insn_v1int_l"
4584   [(match_operand:DI 0 "register_operand" "")
4585    (match_operand:DI 1 "reg_or_0_operand" "")
4586    (match_operand:DI 2 "reg_or_0_operand" "")]
4587   ""
4589   /* For little endian, our instruction interleaves opposite of the
4590      way vec_interleave works, so we need to reverse the source
4591      operands.  */
4592   rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4593   rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4594   tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv8qi, V8QImode,
4595                                       operands[0], V8QImode, opnd1, opnd2,
4596                                       true);
4597   DONE;
4600 ;; insn_v2int_h
4601 ;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
4602 ;; => {A3,A2,A1,A0,B3,B2,B1,B0}
4603 ;; => {A3,B3,A2,B2}
4604 (define_expand "vec_interleave_highv4hi"
4605   [(match_operand:V4HI 0 "register_operand" "")
4606    (match_operand:V4HI 1 "reg_or_0_operand" "")
4607    (match_operand:V4HI 2 "reg_or_0_operand" "")]
4608   ""
4610   if (BYTES_BIG_ENDIAN)
4611     emit_insn (gen_vec_interleave_highv4hi_be (operands[0], operands[1],
4612                                                operands[2]));
4613   else
4614     emit_insn (gen_vec_interleave_highv4hi_le (operands[0], operands[1],
4615                                                operands[2]));
4616   DONE;
4619 (define_insn "vec_interleave_highv4hi_be"
4620   [(set (match_operand:V4HI 0 "register_operand" "=r")
4621         (vec_select:V4HI
4622          (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4623                           (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4624          (parallel [(const_int 0) (const_int 4)
4625                     (const_int 1) (const_int 5)])))]
4626   "BYTES_BIG_ENDIAN"
4627   "v2int_h\t%0, %r1, %r2"
4628   [(set_attr "type" "X01")])
4630 (define_insn "vec_interleave_highv4hi_le"
4631   [(set (match_operand:V4HI 0 "register_operand" "=r")
4632         (vec_select:V4HI
4633          (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4634                           (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4635          (parallel [(const_int 2) (const_int 6)
4636                     (const_int 3) (const_int 7)])))]
4637   "!BYTES_BIG_ENDIAN"
4638   "v2int_h\t%0, %r2, %r1"
4639   [(set_attr "type" "X01")])
4641 (define_expand "insn_v2int_h"
4642   [(match_operand:DI 0 "register_operand" "")
4643    (match_operand:DI 1 "reg_or_0_operand" "")
4644    (match_operand:DI 2 "reg_or_0_operand" "")]
4645   ""
4647   /* For little endian, our instruction interleaves opposite of the
4648      way vec_interleave works, so we need to reverse the source
4649      operands.  */
4650   rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4651   rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4652   tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv4hi, V4HImode,
4653                                       operands[0], V4HImode, opnd1, opnd2,
4654                                       true);
4655   DONE;
4658 ;; insn_v2int_l
4659 ;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
4660 ;; => {A3,A2,A1,A0,B3,B2,B1,B0}
4661 ;; => {A1,B1,A0,B0}
4662 (define_expand "vec_interleave_lowv4hi"
4663   [(match_operand:V4HI 0 "register_operand" "")
4664    (match_operand:V4HI 1 "reg_or_0_operand" "")
4665    (match_operand:V4HI 2 "reg_or_0_operand" "")]
4666   ""
4668   if (BYTES_BIG_ENDIAN)
4669     emit_insn (gen_vec_interleave_lowv4hi_be (operands[0], operands[1],
4670                                               operands[2]));
4671   else
4672     emit_insn (gen_vec_interleave_lowv4hi_le (operands[0], operands[1],
4673                                               operands[2]));
4674   DONE;
4677 (define_insn "vec_interleave_lowv4hi_be"
4678   [(set (match_operand:V4HI 0 "register_operand" "=r")
4679         (vec_select:V4HI
4680          (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4681                           (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4682          (parallel [(const_int 2) (const_int 6)
4683                     (const_int 3) (const_int 7)])))]
4684   "BYTES_BIG_ENDIAN"
4685   "v2int_l\t%0, %r1, %r2"
4686   [(set_attr "type" "X01")])
4688 (define_insn "vec_interleave_lowv4hi_le"
4689   [(set (match_operand:V4HI 0 "register_operand" "=r")
4690         (vec_select:V4HI
4691          (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4692                           (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4693          (parallel [(const_int 0) (const_int 4)
4694                     (const_int 1) (const_int 5)])))]
4695   "!BYTES_BIG_ENDIAN"
4696   "v2int_l\t%0, %r2, %r1"
4697   [(set_attr "type" "X01")])
4699 (define_expand "insn_v2int_l"
4700   [(match_operand:DI 0 "register_operand" "")
4701    (match_operand:DI 1 "reg_or_0_operand" "")
4702    (match_operand:DI 2 "reg_or_0_operand" "")]
4703   ""
4705   /* For little endian, our instruction interleaves opposite of the
4706      way vec_interleave works, so we need to reverse the source
4707      operands.  */
4708   rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4709   rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4710   tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv4hi, V4HImode,
4711                                       operands[0], V4HImode, opnd1, opnd2,
4712                                       true);
4713   DONE;
4716 ;; insn_v4int_h
4717 ;;    {B1,B0} {A1,A0}
4718 ;; => {A1,A0,B1,B0}
4719 ;; => {A1,B1}
4720 (define_expand "vec_interleave_highv2si"
4721   [(match_operand:V2SI 0 "register_operand" "")
4722    (match_operand:V2SI 1 "reg_or_0_operand" "")
4723    (match_operand:V2SI 2 "reg_or_0_operand" "")]
4724   ""
4726   if (BYTES_BIG_ENDIAN)
4727     emit_insn (gen_vec_interleave_highv2si_be (operands[0], operands[1],
4728                                                operands[2]));
4729   else
4730     emit_insn (gen_vec_interleave_highv2si_le (operands[0], operands[1],
4731                                                operands[2]));
4732   DONE;
4735 (define_insn "vec_interleave_highv2si_be"
4736   [(set (match_operand:V2SI 0 "register_operand" "=r")
4737         (vec_select:V2SI
4738          (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4739                           (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4740          (parallel [(const_int 0) (const_int 2)])))]
4741   "BYTES_BIG_ENDIAN"
4742   "v4int_h\t%0, %r1, %r2"
4743   [(set_attr "type" "X01")])
4745 (define_insn "vec_interleave_highv2si_le"
4746   [(set (match_operand:V2SI 0 "register_operand" "=r")
4747         (vec_select:V2SI
4748          (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4749                           (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4750          (parallel [(const_int 1) (const_int 3)])))]
4751   "!BYTES_BIG_ENDIAN"
4752   "v4int_h\t%0, %r2, %r1"
4753   [(set_attr "type" "X01")])
4755 (define_expand "insn_v4int_h"
4756   [(match_operand:DI 0 "register_operand" "")
4757    (match_operand:DI 1 "reg_or_0_operand" "")
4758    (match_operand:DI 2 "reg_or_0_operand" "")]
4759   ""
4761   /* For little endian, our instruction interleaves opposite of the
4762      way vec_interleave works, so we need to reverse the source
4763      operands.  */
4764   rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4765   rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4766   tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv2si, V2SImode,
4767                                       operands[0], V2SImode, opnd1, opnd2,
4768                                       true);
4769   DONE;
4772 ;; insn_v4int_l
4773 ;;    {B1,B0} {A1,A0}
4774 ;; => {A1,A0,B1,B0}
4775 ;; => {A0,B0}
4776 (define_expand "vec_interleave_lowv2si"
4777   [(match_operand:V2SI 0 "register_operand" "")
4778    (match_operand:V2SI 1 "reg_or_0_operand" "")
4779    (match_operand:V2SI 2 "reg_or_0_operand" "")]
4780   ""
4782   if (BYTES_BIG_ENDIAN)
4783     emit_insn (gen_vec_interleave_lowv2si_be (operands[0], operands[1],
4784                                               operands[2]));
4785   else
4786     emit_insn (gen_vec_interleave_lowv2si_le (operands[0], operands[1],
4787                                               operands[2]));
4788   DONE;
4791 (define_insn "vec_interleave_lowv2si_be"
4792   [(set (match_operand:V2SI 0 "register_operand" "=r")
4793         (vec_select:V2SI
4794          (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4795                           (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4796          (parallel [(const_int 1) (const_int 3)])))]
4797   "BYTES_BIG_ENDIAN"
4798   "v4int_l\t%0, %r1, %r2"
4799   [(set_attr "type" "X01")])
4801 (define_insn "vec_interleave_lowv2si_le"
4802   [(set (match_operand:V2SI 0 "register_operand" "=r")
4803         (vec_select:V2SI
4804          (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4805                           (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4806          (parallel [(const_int 0) (const_int 2)])))]
4807   "!BYTES_BIG_ENDIAN"
4808   "v4int_l\t%0, %r2, %r1"
4809   [(set_attr "type" "X01")])
4811 (define_expand "insn_v4int_l"
4812   [(match_operand:DI 0 "register_operand" "")
4813    (match_operand:DI 1 "reg_or_0_operand" "")
4814    (match_operand:DI 2 "reg_or_0_operand" "")]
4815   ""
4817   /* For little endian, our instruction interleaves opposite of the
4818      way vec_interleave works, so we need to reverse the source
4819      operands.  */
4820   rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4821   rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4822   tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv2si, V2SImode,
4823                                       operands[0], V2SImode, opnd1, opnd2,
4824                                       true);
4825   DONE;
4828 ;; insn_v1mnz
4829 ;; insn_v1mz
4830 ;; insn_v2mnz
4831 ;; insn_v2mz
4832 (define_insn "insn_mnz_v8qi"
4833   [(set (match_operand:V8QI 0 "register_operand" "=r")
4834         (if_then_else:V8QI
4835          (ne:V8QI
4836           (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4837           (const_vector:V8QI [(const_int 0) (const_int 0)
4838                               (const_int 0) (const_int 0)
4839                               (const_int 0) (const_int 0)
4840                               (const_int 0) (const_int 0)]))
4841          (match_operand:V8QI 2 "reg_or_0_operand" "rO")
4842          (const_vector:V8QI [(const_int 0) (const_int 0)
4843                              (const_int 0) (const_int 0)
4844                              (const_int 0) (const_int 0)
4845                              (const_int 0) (const_int 0)])))]
4846   ""
4847   "v1mnz\t%0, %r1, %r2"
4848   [(set_attr "type" "X01")])
4850 (define_expand "insn_v1mnz"
4851   [(set (match_operand:DI 0 "register_operand" "")
4852         (if_then_else:V8QI
4853          (ne:V8QI
4854           (match_operand:DI 1 "reg_or_0_operand" "")
4855           (const_vector:V8QI [(const_int 0) (const_int 0)
4856                               (const_int 0) (const_int 0)
4857                               (const_int 0) (const_int 0)
4858                               (const_int 0) (const_int 0)])
4859           )
4860          (match_operand:DI 2 "reg_or_0_operand" "")
4861          (const_vector:V8QI [(const_int 0) (const_int 0)
4862                              (const_int 0) (const_int 0)
4863                              (const_int 0) (const_int 0)
4864                              (const_int 0) (const_int 0)])))]
4865   ""
4867   tilegx_expand_builtin_vector_binop (gen_insn_mnz_v8qi, V8QImode,
4868                                       operands[0], V8QImode, operands[1],
4869                                       operands[2], true);
4870   DONE;
4873 (define_insn "insn_mz_v8qi"
4874   [(set (match_operand:V8QI 0 "register_operand" "=r")
4875         (if_then_else:V8QI
4876          (ne:V8QI
4877           (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4878           (const_vector:V8QI [(const_int 0) (const_int 0)
4879                               (const_int 0) (const_int 0)
4880                               (const_int 0) (const_int 0)
4881                               (const_int 0) (const_int 0)]))
4882          (const_vector:V8QI [(const_int 0) (const_int 0)
4883                              (const_int 0) (const_int 0)
4884                              (const_int 0) (const_int 0)
4885                              (const_int 0) (const_int 0)])
4886          (match_operand:V8QI 2 "reg_or_0_operand" "rO")))]
4887   ""
4888   "v1mz\t%0, %r1, %r2"
4889   [(set_attr "type" "X01")])
4891 (define_expand "insn_v1mz"
4892   [(set (match_operand:DI 0 "register_operand" "")
4893         (if_then_else:V8QI
4894          (ne:V8QI
4895           (match_operand:DI 1 "reg_or_0_operand" "")
4896           (const_vector:V8QI [(const_int 0) (const_int 0)
4897                               (const_int 0) (const_int 0)
4898                               (const_int 0) (const_int 0)
4899                               (const_int 0) (const_int 0)]))
4900          (const_vector:V8QI [(const_int 0) (const_int 0)
4901                               (const_int 0) (const_int 0)
4902                               (const_int 0) (const_int 0)
4903                               (const_int 0) (const_int 0)])
4904          (match_operand:DI 2 "reg_or_0_operand" "")))]
4905   ""
4907   tilegx_expand_builtin_vector_binop (gen_insn_mz_v8qi, V8QImode,
4908                                       operands[0], V8QImode, operands[1],
4909                                       operands[2], true);
4910   DONE;
4913 (define_insn "insn_mnz_v4hi"
4914   [(set (match_operand:V4HI 0 "register_operand" "=r")
4915         (if_then_else:V4HI
4916          (ne:V4HI
4917           (match_operand:V4HI 1 "reg_or_0_operand" "rO")
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          (const_vector:V4HI [(const_int 0) (const_int 0)
4922                              (const_int 0) (const_int 0)])))]
4923   ""
4924   "v2mnz\t%0, %r1, %r2"
4925   [(set_attr "type" "X01")])
4927 (define_expand "insn_v2mnz"
4928   [(set (match_operand:DI 0 "register_operand" "")
4929         (if_then_else:V4HI
4930          (ne:V4HI
4931           (match_operand:DI 1 "reg_or_0_operand" "")
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          (const_vector:V4HI [(const_int 0) (const_int 0)
4936                              (const_int 0) (const_int 0)])))]
4937   ""
4939   tilegx_expand_builtin_vector_binop (gen_insn_mnz_v4hi, V4HImode,
4940                                       operands[0], V4HImode, operands[1],
4941                                       operands[2], true);
4942   DONE;
4945 (define_insn "insn_mz_v4hi"
4946   [(set (match_operand:V4HI 0 "register_operand" "=r")
4947         (if_then_else:V4HI
4948          (ne:V4HI
4949           (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4950           (const_vector:V4HI [(const_int 0) (const_int 0)
4951                               (const_int 0) (const_int 0)]))
4952          (const_vector:V4HI [(const_int 0) (const_int 0)
4953                              (const_int 0) (const_int 0)])
4954          (match_operand:V4HI 2 "reg_or_0_operand" "rO")))]
4955   ""
4956   "v2mz\t%0, %r1, %r2"
4957   [(set_attr "type" "X01")])
4959 (define_expand "insn_v2mz"
4960   [(set (match_operand:DI 0 "register_operand" "")
4961         (if_then_else:V4HI
4962          (ne:V4HI
4963           (match_operand:DI 1 "reg_or_0_operand" "")
4964           (const_vector:V4HI [(const_int 0) (const_int 0)
4965                               (const_int 0) (const_int 0)]))
4966          (const_vector:V4HI [(const_int 0) (const_int 0)
4967                               (const_int 0) (const_int 0)])
4968          (match_operand:DI 2 "reg_or_0_operand" "")))]
4969   ""
4971   tilegx_expand_builtin_vector_binop (gen_insn_mz_v4hi, V4HImode,
4972                                       operands[0], V4HImode, operands[1],
4973                                       operands[2], true);
4974   DONE;
4977 ;; insn_v1mulu
4978 (define_insn "vec_widen_umult_lo_v8qi"
4979   [(set (match_operand:V4HI 0 "register_operand" "=r")
4980         (mult:V4HI
4981          (zero_extend:V4HI
4982           (vec_select:V4QI
4983            (match_operand:V8QI 1 "register_operand" "r")
4984            (parallel [(const_int 0) (const_int 1)
4985                       (const_int 2) (const_int 3)])))
4986          (zero_extend:V4HI
4987           (vec_select:V4QI
4988            (match_operand:V8QI 2 "register_operand" "r")
4989            (parallel [(const_int 0) (const_int 1)
4990                       (const_int 2) (const_int 3)])))))]
4991   ""
4992   "v1mulu\t%0, %r1, %r2"
4993   [(set_attr "type" "X0_2cycle")])
4995 (define_expand "insn_v1mulu"
4996   [(match_operand:DI 0 "register_operand" "")
4997    (match_operand:DI 1 "register_operand" "")
4998    (match_operand:DI 2 "register_operand" "")]
4999   ""
5001   tilegx_expand_builtin_vector_binop (gen_vec_widen_umult_lo_v8qi, V4HImode,
5002                                       operands[0], V8QImode, operands[1],
5003                                       operands[2], true);
5004   DONE;
5007 ;; insn_v1mulus
5008 (define_insn "vec_widen_usmult_lo_v8qi"
5009   [(set (match_operand:V4HI 0 "register_operand" "=r")
5010         (mult:V4HI
5011          (zero_extend:V4HI
5012           (vec_select:V4QI
5013            (match_operand:V8QI 1 "register_operand" "r")
5014            (parallel [(const_int 0) (const_int 1)
5015                       (const_int 2) (const_int 3)])))
5016          (sign_extend:V4HI
5017           (vec_select:V4QI
5018            (match_operand:V8QI 2 "register_operand" "r")
5019            (parallel [(const_int 0) (const_int 1)
5020                       (const_int 2) (const_int 3)])))))]
5021   ""
5022   "v1mulus\t%0, %r1, %r2"
5023   [(set_attr "type" "X0_2cycle")])
5025 (define_expand "insn_v1mulus"
5026   [(match_operand:DI 0 "register_operand" "")
5027    (match_operand:DI 1 "register_operand" "")
5028    (match_operand:DI 2 "register_operand" "")]
5029   ""
5031   tilegx_expand_builtin_vector_binop (gen_vec_widen_usmult_lo_v8qi, V4HImode,
5032                                       operands[0], V8QImode, operands[1],
5033                                       operands[2], true);
5034   DONE;
5037 ;; insn_v2muls
5038 (define_insn "vec_widen_smult_lo_v4qi"
5039   [(set (match_operand:V2SI 0 "register_operand" "=r")
5040         (mult:V2SI
5041          (sign_extend:V2SI
5042           (vec_select:V2HI
5043            (match_operand:V4HI 1 "register_operand" "r")
5044            (parallel [(const_int 0) (const_int 1)])))
5045          (sign_extend:V2SI
5046           (vec_select:V2HI
5047            (match_operand:V4HI 2 "register_operand" "r")
5048            (parallel [(const_int 0) (const_int 1)])))))]
5049   ""
5050   "v2muls\t%0, %r1, %r2"
5051   [(set_attr "type" "X0_2cycle")])
5053 (define_expand "insn_v2muls"
5054   [(match_operand:DI 0 "register_operand" "")
5055    (match_operand:DI 1 "register_operand" "")
5056    (match_operand:DI 2 "register_operand" "")]
5057   ""
5059   tilegx_expand_builtin_vector_binop (gen_vec_widen_smult_lo_v4qi, V2SImode,
5060                                       operands[0], V4HImode, operands[1],
5061                                       operands[2], true);
5062   DONE;
5065 ;; v2packl
5066 ;; v2packuc
5067 ;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
5068 ;; => {A3,A2,A1,A0,B3,B2,B1,B0}
5069 (define_insn "vec_pack_<pack_optab>_v4hi"
5070   [(set (match_operand:V8QI 0 "register_operand" "=r")
5071         (vec_concat:V8QI
5072          (v2pack:V4QI (match_operand:V4HI 1 "reg_or_0_operand" "rO"))
5073          (v2pack:V4QI (match_operand:V4HI 2 "reg_or_0_operand" "rO"))))]
5074   ""
5075   "v2<pack_insn>\t%0, %r2, %r1"
5076   [(set_attr "type" "X01")])
5078 (define_expand "insn_v2<pack_insn>"
5079   [(set (match_operand:DI 0 "register_operand" "")
5080         (vec_concat:V8QI
5081          (v2pack:V4QI (match_operand:DI 2 "reg_or_0_operand" ""))
5082          (v2pack:V4QI (match_operand:DI 1 "reg_or_0_operand" ""))))]
5083   ""
5085   /* Our instruction concats opposite of the way vec_pack works, so we
5086      need to reverse the source operands.  */
5087   tilegx_expand_builtin_vector_binop (gen_vec_pack_<pack_optab>_v4hi,
5088                                       V8QImode, operands[0], V4HImode,
5089                                       operands[2], operands[1], true);
5090   DONE;
5093 ;; v2packh
5094 ;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
5095 ;; => {A3_hi,A2_hi,A1_hi,A0_hi,B3_hi,B2_hi,B1_hi,B0_hi}
5096 (define_insn "vec_pack_hipart_v4hi"
5097   [(set (match_operand:V8QI 0 "register_operand" "=r")
5098         (vec_concat:V8QI
5099          (truncate:V4QI
5100           (ashiftrt:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
5101                          (const_int 8)))
5102          (truncate:V4QI
5103           (ashiftrt:V4HI (match_operand:V4HI 2 "reg_or_0_operand" "rO")
5104                          (const_int 8)))))]
5105   ""
5106   "v2packh\t%0, %r2, %r1"
5107   [(set_attr "type" "X01")])
5109 (define_expand "insn_v2packh"
5110   [(set (match_operand:DI 0 "register_operand" "")
5111         (vec_concat:V8QI
5112          (truncate:V4QI
5113           (ashiftrt:V4HI (match_operand:DI 2 "reg_or_0_operand" "")
5114                          (const_int 8)))
5115          (truncate:V4QI
5116           (ashiftrt:V4HI (match_operand:DI 1 "reg_or_0_operand" "")
5117                          (const_int 8)))))]
5118   ""
5120   /* Our instruction concats opposite of the way vec_pack works, so we
5121      need to reverse the source operands.  */
5122   tilegx_expand_builtin_vector_binop (gen_vec_pack_hipart_v4hi, V8QImode,
5123                                       operands[0], V4HImode, operands[2],
5124                                       operands[1], true);
5125   DONE;
5128 ;; v4packsc
5129 ;;    {B1,B0} {A1,A0}
5130 ;; => {A1,A0,B1,B0}
5131 (define_insn "vec_pack_ssat_v2si"
5132   [(set (match_operand:V4HI 0 "register_operand" "=r")
5133         (vec_concat:V4HI
5134          (us_truncate:V2HI (match_operand:V2SI 1 "reg_or_0_operand" "rO"))
5135          (us_truncate:V2HI (match_operand:V2SI 2 "reg_or_0_operand" "rO"))))]
5136   ""
5137   "v4packsc\t%0, %r2, %r1"
5138   [(set_attr "type" "X01")])
5140 (define_expand "insn_v4packsc"
5141   [(set (match_operand:DI 0 "register_operand" "")
5142         (vec_concat:V4HI
5143          (us_truncate:V2HI (match_operand:DI 2 "reg_or_0_operand" ""))
5144          (us_truncate:V2HI (match_operand:DI 1 "reg_or_0_operand" ""))))]
5145   ""
5147   /* Our instruction concats opposite of the way vec_pack works, so we
5148      need to reverse the source operands.  */
5149   tilegx_expand_builtin_vector_binop (gen_vec_pack_ssat_v2si, V4HImode,
5150                                       operands[0], V2SImode, operands[2],
5151                                       operands[1], true);
5152   DONE;
5155 ;; Rest of the vector intrinsics
5156 (define_insn "insn_v1adiffu"
5157   [(set (match_operand:DI 0 "register_operand" "=r")
5158         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5159                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5160                    UNSPEC_INSN_V1ADIFFU))]
5161   ""
5162   "v1adiffu\t%0, %r1, %r2"
5163   [(set_attr "type" "X0_2cycle")])
5165 (define_insn "insn_v1avgu"
5166   [(set (match_operand:DI 0 "register_operand" "=r")
5167         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5168                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5169                    UNSPEC_INSN_V1AVGU))]
5170   ""
5171   "v1avgu\t%0, %r1, %r2"
5172   [(set_attr "type" "X0")])
5174 (define_insn "insn_v1ddotpu"
5175   [(set (match_operand:DI 0 "register_operand" "=r")
5176         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5177                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5178                    UNSPEC_INSN_V1DDOTPU))]
5179   ""
5180   "v1ddotpu\t%0, %r1, %r2"
5181   [(set_attr "type" "X0_2cycle")])
5183 (define_insn "insn_v1ddotpua"
5184   [(set (match_operand:DI 0 "register_operand" "=r")
5185         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5186                     (match_operand:DI 2 "reg_or_0_operand" "rO")
5187                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
5188                    UNSPEC_INSN_V1DDOTPUA))]
5189   ""
5190   "v1ddotpua\t%0, %r2, %r3"
5191   [(set_attr "type" "X0_2cycle")])
5193 (define_insn "insn_v1ddotpus"
5194   [(set (match_operand:DI 0 "register_operand" "=r")
5195         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5196                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5197                    UNSPEC_INSN_V1DDOTPUS))]
5198   ""
5199   "v1ddotpus\t%0, %r1, %r2"
5200   [(set_attr "type" "X0_2cycle")])
5202 (define_insn "insn_v1ddotpusa"
5203   [(set (match_operand:DI 0 "register_operand" "=r")
5204         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5205                     (match_operand:DI 2 "reg_or_0_operand" "rO")
5206                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
5207                    UNSPEC_INSN_V1DDOTPUSA))]
5208   ""
5209   "v1ddotpusa\t%0, %r2, %r3"
5210   [(set_attr "type" "X0_2cycle")])
5212 (define_insn "insn_v1dotp"
5213   [(set (match_operand:DI 0 "register_operand" "=r")
5214         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5215                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5216                    UNSPEC_INSN_V1DOTP))]
5217   ""
5218   "v1dotp\t%0, %r1, %r2"
5219   [(set_attr "type" "X0_2cycle")])
5221 (define_insn "insn_v1dotpa"
5222   [(set (match_operand:DI 0 "register_operand" "=r")
5223         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5224                     (match_operand:DI 2 "reg_or_0_operand" "rO")
5225                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
5226                    UNSPEC_INSN_V1DOTPA))]
5227   ""
5228   "v1dotpa\t%0, %r2, %r3"
5229   [(set_attr "type" "X0_2cycle")])
5231 (define_insn "insn_v1dotpu"
5232   [(set (match_operand:DI 0 "register_operand" "=r")
5233         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5234                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5235                    UNSPEC_INSN_V1DOTPU))]
5236   ""
5237   "v1dotpu\t%0, %r1, %r2"
5238   [(set_attr "type" "X0_2cycle")])
5240 (define_insn "insn_v1dotpua"
5241   [(set (match_operand:DI 0 "register_operand" "=r")
5242         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5243                     (match_operand:DI 2 "reg_or_0_operand" "rO")
5244                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
5245                    UNSPEC_INSN_V1DOTPUA))]
5246   ""
5247   "v1dotpua\t%0, %r2, %r3"
5248   [(set_attr "type" "X0_2cycle")])
5250 (define_insn "insn_v1dotpus"
5251   [(set (match_operand:DI 0 "register_operand" "=r")
5252         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5253                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5254                    UNSPEC_INSN_V1DOTPUS))]
5255   ""
5256   "v1dotpus\t%0, %r1, %r2"
5257   [(set_attr "type" "X0_2cycle")])
5259 (define_insn "insn_v1dotpusa"
5260   [(set (match_operand:DI 0 "register_operand" "=r")
5261         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5262                     (match_operand:DI 2 "reg_or_0_operand" "rO")
5263                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
5264                    UNSPEC_INSN_V1DOTPUSA))]
5265   ""
5266   "v1dotpusa\t%0, %r2, %r3"
5267   [(set_attr "type" "X0_2cycle")])
5269 (define_insn "insn_v1sadau"
5270   [(set (match_operand:DI 0 "register_operand" "=r")
5271         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5272                     (match_operand:DI 2 "reg_or_0_operand" "rO")
5273                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
5274                    UNSPEC_INSN_V1SADAU))]
5275   ""
5276   "v1sadau\t%0, %r2, %r3"
5277   [(set_attr "type" "X0_2cycle")])
5279 (define_insn "insn_v1sadu"
5280   [(set (match_operand:DI 0 "register_operand" "=r")
5281         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5282                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5283                    UNSPEC_INSN_V1SADU))]
5284   ""
5285   "v1sadu\t%0, %r1, %r2"
5286   [(set_attr "type" "X0_2cycle")])
5288 (define_insn "*insn_v1sadu"
5289   [(set (match_operand:SI 0 "register_operand" "=r")
5290         (truncate:SI
5291          (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5292                      (match_operand:DI 2 "reg_or_0_operand" "rO")]
5293                     UNSPEC_INSN_V1SADU)))]
5294    ""
5295   "v1sadu\t%0, %r1, %r2"
5296   [(set_attr "type" "X0_2cycle")])
5298 (define_insn "insn_v2adiffs"
5299   [(set (match_operand:DI 0 "register_operand" "=r")
5300         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5301                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5302                    UNSPEC_INSN_V2ADIFFS))]
5303   ""
5304   "v2adiffs\t%0, %r1, %r2"
5305   [(set_attr "type" "X0_2cycle")])
5307 (define_insn "insn_v2avgs"
5308   [(set (match_operand:DI 0 "register_operand" "=r")
5309         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5310                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5311                    UNSPEC_INSN_V2AVGS))]
5312   ""
5313   "v2avgs\t%0, %r1, %r2"
5314   [(set_attr "type" "X0")])
5316 (define_insn "insn_v2dotp"
5317   [(set (match_operand:DI 0 "register_operand" "=r")
5318         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5319                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5320                    UNSPEC_INSN_V2DOTP))]
5321   ""
5322   "v2dotp\t%0, %r1, %r2"
5323   [(set_attr "type" "X0_2cycle")])
5325 (define_insn "insn_v2dotpa"
5326   [(set (match_operand:DI 0 "register_operand" "=r")
5327         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5328                     (match_operand:DI 2 "reg_or_0_operand" "rO")
5329                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
5330                    UNSPEC_INSN_V2DOTPA))]
5331   ""
5332   "v2dotpa\t%0, %r2, %r3"
5333   [(set_attr "type" "X0_2cycle")])
5335 (define_insn "insn_v2mulfsc"
5336   [(set (match_operand:DI 0 "register_operand" "=r")
5337         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5338                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5339                    UNSPEC_INSN_V2MULFSC))]
5340   ""
5341   "v2mulfsc\t%0, %r1, %r2"
5342   [(set_attr "type" "X0_2cycle")])
5344 (define_insn "insn_v2sadas"
5345   [(set (match_operand:DI 0 "register_operand" "=r")
5346         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5347                     (match_operand:DI 2 "reg_or_0_operand" "rO")
5348                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
5349                    UNSPEC_INSN_V2SADAS))]
5350   ""
5351   "v2sadas\t%0, %r2, %r3"
5352   [(set_attr "type" "X0_2cycle")])
5354 (define_insn "insn_v2sadau"
5355   [(set (match_operand:DI 0 "register_operand" "=r")
5356         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5357                     (match_operand:DI 2 "reg_or_0_operand" "rO")
5358                     (match_operand:DI 3 "reg_or_0_operand" "rO")]
5359                    UNSPEC_INSN_V2SADAU))]
5360   ""
5361   "v2sadau\t%0, %r2, %r3"
5362   [(set_attr "type" "X0_2cycle")])
5364 (define_insn "insn_v2sads"
5365   [(set (match_operand:DI 0 "register_operand" "=r")
5366         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5367                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5368                    UNSPEC_INSN_V2SADS))]
5369   ""
5370   "v2sads\t%0, %r1, %r2"
5371   [(set_attr "type" "X0_2cycle")])
5373 (define_insn "*insn_v2sads"
5374   [(set (match_operand:SI 0 "register_operand" "=r")
5375         (truncate:SI
5376          (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5377                      (match_operand:DI 2 "reg_or_0_operand" "rO")]
5378                     UNSPEC_INSN_V2SADS)))]
5379   ""
5380   "v2sads\t%0, %r1, %r2"
5381   [(set_attr "type" "X0_2cycle")])
5383 (define_insn "insn_v2sadu"
5384   [(set (match_operand:DI 0 "register_operand" "=r")
5385         (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5386                     (match_operand:DI 2 "reg_or_0_operand" "rO")]
5387                    UNSPEC_INSN_V2SADU))]
5388   ""
5389   "v2sadu\t%0, %r1, %r2"
5390   [(set_attr "type" "X0_2cycle")])
5392 (define_insn "*insn_v2sadu"
5393   [(set (match_operand:SI 0 "register_operand" "=r")
5394         (truncate:SI
5395          (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5396                      (match_operand:DI 2 "reg_or_0_operand" "rO")]
5397                     UNSPEC_INSN_V2SADU)))]
5398   ""
5399   "v2sadu\t%0, %r1, %r2"
5400   [(set_attr "type" "X0_2cycle")])
5402 (define_insn "insn_wh64"
5403   [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
5404                          UNSPEC_INSN_WH64)
5405    (clobber (mem:BLK (const_int 0)))]
5406   ""
5407   "wh64\t%r0"
5408   [(set_attr "type" "X1")])
5411 ;; Network intrinsics
5413 ;; Note the this barrier is of type "nothing," which is deleted after
5414 ;; the final scheduling pass so that nothing is emitted for it.
5415 (define_insn "tilegx_network_barrier"
5416   [(unspec_volatile:SI [(const_int 0)] UNSPEC_NETWORK_BARRIER)]
5417   ""
5418   "pseudo"
5419   [(set_attr "type" "nothing")
5420    (set_attr "length" "0")])
5422 (define_insn "*netreg_receive"
5423   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,U,m")
5424         (unspec_volatile:DI [(match_operand:DI 1 "netreg_operand" "i,i,i")
5425                              (reg:DI TILEGX_NETORDER_REG)]
5426                             UNSPEC_NETWORK_RECEIVE))
5427    (clobber (reg:DI TILEGX_NETORDER_REG))]
5429   ""
5430   "@
5431    move\t%0, %N1
5432    st\t%0, %N1
5433    st_add\t%I0, %N1, %i0"
5434   [(set_attr "type" "*,Y2,X1")])
5436 (define_insn "*netreg_send"
5437   [(unspec_volatile:DI
5438     [(match_operand:DI 0 "netreg_operand"  "i,i,i,i,i,i")
5439      (match_operand:DI 1 "reg_or_cint_operand" "r,I,J,K,N,P")
5440      (reg:DI TILEGX_NETORDER_REG)]
5441      UNSPEC_NETWORK_SEND)
5442    (clobber (reg:DI TILEGX_NETORDER_REG))]
5443   ""
5444   "@
5445    move\t%N0, %r1
5446    movei\t%N0, %1
5447    moveli\t%N0, %1
5448    shl16insli\t%N0, zero, %h1
5449    v1addi\t%N0, zero, %j1
5450    v2addi\t%N0, zero, %h1"
5451   [(set_attr "type" "*,*,X01,X01,X01,X01")])
5453 (define_expand "tilegx_idn0_receive"
5454   [(parallel
5455     [(set (match_operand:DI 0 "register_operand" "")
5456           (unspec_volatile:DI [(const_int TILEGX_NETREG_IDN0)
5457                                (reg:DI TILEGX_NETORDER_REG)]
5458                               UNSPEC_NETWORK_RECEIVE))
5459      (clobber (reg:DI TILEGX_NETORDER_REG))])]
5460   "")
5462 (define_expand "tilegx_idn1_receive"
5463   [(parallel
5464     [(set (match_operand:DI 0 "register_operand" "")
5465           (unspec_volatile:DI [(const_int TILEGX_NETREG_IDN1)
5466                                (reg:DI TILEGX_NETORDER_REG)]
5467                               UNSPEC_NETWORK_RECEIVE))
5468      (clobber (reg:DI TILEGX_NETORDER_REG))])]
5469   "")
5471 (define_expand "tilegx_idn_send"
5472   [(parallel
5473     [(unspec_volatile:DI [(const_int TILEGX_NETREG_IDN0)
5474                           (match_operand:DI 0 "reg_or_cint_operand" "")
5475                           (reg:DI TILEGX_NETORDER_REG)]
5476                          UNSPEC_NETWORK_SEND)
5477      (clobber (reg:DI TILEGX_NETORDER_REG))])]
5478   "")
5480 (define_expand "tilegx_udn0_receive"
5481   [(parallel
5482     [(set (match_operand:DI 0 "register_operand" "")
5483           (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN0)
5484                                (reg:DI TILEGX_NETORDER_REG)]
5485                               UNSPEC_NETWORK_RECEIVE))
5486      (clobber (reg:DI TILEGX_NETORDER_REG))])]
5487   "")
5489 (define_expand "tilegx_udn1_receive"
5490   [(parallel
5491     [(set (match_operand:DI 0 "register_operand" "")
5492           (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN1)
5493                                (reg:DI TILEGX_NETORDER_REG)]
5494                               UNSPEC_NETWORK_RECEIVE))
5495      (clobber (reg:DI TILEGX_NETORDER_REG))])]
5496   "")
5498 (define_expand "tilegx_udn2_receive"
5499   [(parallel
5500     [(set (match_operand:DI 0 "register_operand" "")
5501           (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN2)
5502                                (reg:DI TILEGX_NETORDER_REG)]
5503                               UNSPEC_NETWORK_RECEIVE))
5504      (clobber (reg:DI TILEGX_NETORDER_REG))])]
5505   "")
5507 (define_expand "tilegx_udn3_receive"
5508   [(parallel
5509     [(set (match_operand:DI 0 "register_operand" "")
5510           (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN3)
5511                                (reg:DI TILEGX_NETORDER_REG)]
5512                               UNSPEC_NETWORK_RECEIVE))
5513      (clobber (reg:DI TILEGX_NETORDER_REG))])]
5514   "")
5516 (define_expand "tilegx_udn_send"
5517   [(parallel
5518     [(unspec_volatile:DI [(const_int TILEGX_NETREG_UDN0)
5519                           (match_operand:DI 0 "reg_or_cint_operand" "")
5520                           (reg:DI TILEGX_NETORDER_REG)]
5521                          UNSPEC_NETWORK_SEND)
5522     (clobber (reg:DI TILEGX_NETORDER_REG))])]
5523   "")
5525 (define_insn "*netreg_adddi_to_network"
5526   [(unspec_volatile:DI
5527     [(match_operand:DI 0 "netreg_operand" "i,i,i")
5528      (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO")
5529               (match_operand:DI 2 "add_operand" "r,I,JT"))
5530      (reg:DI TILEGX_NETORDER_REG)]
5531     UNSPEC_NETWORK_SEND)
5532    (clobber (reg:DI TILEGX_NETORDER_REG))]
5533   ""
5534   "@
5535    add\t%N0, %r1, %2
5536    addi\t%N0, %r1, %2
5537    addli\t%N0, %r1, %H2"
5538   [(set_attr "type" "*,*,X01")])
5540 (define_insn "*netreg_adddi_from_network"
5541   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5542         (plus:DI (unspec_volatile:DI
5543                   [(match_operand:DI 1 "netreg_operand" "%i,i,i")
5544                    (reg:DI TILEGX_NETORDER_REG)]
5545                   UNSPEC_NETWORK_RECEIVE)
5546                  (match_operand:DI 2 "add_operand" "rO,I,JT")))
5547    (clobber (reg:DI TILEGX_NETORDER_REG))]
5548   ""
5549   "@
5550    add\t%0, %N1, %r2
5551    addi\t%0, %N1, %2
5552    addli\t%0, %N1, %H2"
5553   [(set_attr "type" "*,*,X01")])
5557 ;; Stack protector instructions.
5560 (define_expand "stack_protect_set"
5561   [(set (match_operand 0 "nonautoincmem_operand" "")
5562         (match_operand 1 "nonautoincmem_operand" ""))]
5563   ""
5565 #ifdef TARGET_THREAD_SSP_OFFSET
5566   rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
5567   rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
5568   rtx ssp = gen_reg_rtx (Pmode);
5569   
5570   emit_insn (gen_rtx_SET (ssp, ssp_addr));
5572   operands[1] = gen_rtx_MEM (Pmode, ssp);
5573 #endif
5575   if (TARGET_32BIT)
5576     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
5577   else
5578     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
5580   DONE;
5583 (define_insn "stack_protect_setsi"
5584   [(set (match_operand:SI 0 "nonautoincmem_operand" "=U")
5585         (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")]
5586                    UNSPEC_SP_SET))
5587    (set (match_scratch:SI 2 "=&r") (const_int 0))]
5588   ""
5589   "ld4s\t%2, %1; { st4\t%0, %2; move\t%2, zero }"
5590   [(set_attr "length" "16")
5591    (set_attr "type" "cannot_bundle_3cycle")])
5593 (define_insn "stack_protect_setdi"
5594   [(set (match_operand:DI 0 "nonautoincmem_operand" "=U")
5595         (unspec:DI [(match_operand:DI 1 "nonautoincmem_operand" "U")]
5596                    UNSPEC_SP_SET))
5597    (set (match_scratch:DI 2 "=&r") (const_int 0))]
5598   ""
5599   "ld\t%2, %1; { st\t%0, %2; move\t%2, zero }"
5600   [(set_attr "length" "16")
5601    (set_attr "type" "cannot_bundle_3cycle")])
5603 (define_expand "stack_protect_test"
5604   [(match_operand 0 "nonautoincmem_operand" "")
5605    (match_operand 1 "nonautoincmem_operand" "")
5606    (match_operand 2 "" "")]
5607   ""
5609   rtx compare_result;
5610   rtx bcomp, loc_ref;
5612 #ifdef TARGET_THREAD_SSP_OFFSET
5613   rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
5614   rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
5615   rtx ssp = gen_reg_rtx (Pmode);
5616   
5617   emit_insn (gen_rtx_SET (ssp, ssp_addr));
5619   operands[1] = gen_rtx_MEM (Pmode, ssp);
5620 #endif
5622   compare_result = gen_reg_rtx (Pmode);
5624   if (TARGET_32BIT)
5625     emit_insn (gen_stack_protect_testsi (compare_result, operands[0],
5626                                          operands[1]));
5627   else
5628     emit_insn (gen_stack_protect_testdi (compare_result, operands[0],
5629                                          operands[1]));
5631   bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
5633   loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
5635   emit_jump_insn (gen_rtx_SET (pc_rtx,
5636                                gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
5637                                                      loc_ref, pc_rtx)));
5639   DONE;
5642 (define_insn "stack_protect_testsi"
5643   [(set (match_operand:SI 0 "register_operand" "=&r")
5644         (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")
5645                     (match_operand:SI 2 "nonautoincmem_operand" "U")]
5646                    UNSPEC_SP_TEST))
5647    (set (match_scratch:SI 3 "=&r") (const_int 0))]
5648   ""
5649   "ld4s\t%0, %1; ld4s\t%3, %2; { cmpeq\t%0, %0, %3; move\t%3, zero }"
5650   [(set_attr "length" "24")
5651    (set_attr "type" "cannot_bundle_4cycle")])
5653 (define_insn "stack_protect_testdi"
5654   [(set (match_operand:DI 0 "register_operand" "=&r")
5655         (unspec:DI [(match_operand:DI 1 "nonautoincmem_operand" "U")
5656                     (match_operand:DI 2 "nonautoincmem_operand" "U")]
5657                    UNSPEC_SP_TEST))
5658    (set (match_scratch:DI 3 "=&r") (const_int 0))]
5659   ""
5660   "ld\t%0, %1; ld\t%3, %2; { cmpeq\t%0, %0, %3; move\t%3, zero }"
5661   [(set_attr "length" "24")
5662    (set_attr "type" "cannot_bundle_4cycle")])
5664 (include "sync.md")