2014-03-25 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / config / tilepro / tilepro.md
blob314dd90bfe041ab727ad05381a1456eca6a0362a
1 ;; Machine description for Tilera TILEPro chip for GCC.
2 ;; Copyright (C) 2011-2014 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_ADDLIS                  1)
28   (UNSPEC_INSN_AULI                    2)
29   (UNSPEC_INSN_AVGB_U                  3)
30   (UNSPEC_INSN_AVGH                    4)
31   (UNSPEC_INSN_BITX                    5)
32   (UNSPEC_INSN_CRC32_32                6)
33   (UNSPEC_INSN_CRC32_8                 7)
34   (UNSPEC_INSN_DRAIN                   8)
35   (UNSPEC_INSN_DTLBPR                  9)
36   (UNSPEC_INSN_DWORD_ALIGN             10)
37   (UNSPEC_INSN_FINV                    11)
38   (UNSPEC_INSN_FLUSH                   12)
39   (UNSPEC_INSN_FNOP                    13)
40   (UNSPEC_INSN_ICOH                    14)
41   (UNSPEC_INSN_ILL                     15)
42   (UNSPEC_INSN_INFO                    16)
43   (UNSPEC_INSN_INFOL                   17)
44   (UNSPEC_INSN_INV                     18)
45   (UNSPEC_INSN_LNK                     19)
46   (UNSPEC_INSN_MFSPR                   20)
47   (UNSPEC_INSN_MNZB                    21)
48   (UNSPEC_INSN_MNZH                    22)
49   (UNSPEC_INSN_MOVELIS                 23)
50   (UNSPEC_INSN_MTSPR                   24)
51   (UNSPEC_INSN_MZB                     25)
52   (UNSPEC_INSN_MZH                     26)
53   (UNSPEC_INSN_NAP                     27)
54   (UNSPEC_INSN_PACKBS_U                28)
55   (UNSPEC_INSN_PACKHB                  29)
56   (UNSPEC_INSN_PACKHS                  30)
57   (UNSPEC_INSN_PACKLB                  31)
58   (UNSPEC_INSN_PREFETCH_L1             32)
59   (UNSPEC_INSN_TBLIDXB0                33)
60   (UNSPEC_INSN_TBLIDXB1                34)
61   (UNSPEC_INSN_TBLIDXB2                35)
62   (UNSPEC_INSN_TBLIDXB3                36)
63   (UNSPEC_INSN_WH64                    37)
65   ;; 2 cycles
66   (UNSPEC_INSN_ADIFFB_U                100)
67   (UNSPEC_INSN_ADIFFH                  101)
68   (UNSPEC_INSN_MULHHA_SS               102)
69   (UNSPEC_INSN_MULHHA_SU               103)
70   (UNSPEC_INSN_MULHHA_UU               104)
71   (UNSPEC_INSN_MULHHSA_UU              105)
72   (UNSPEC_INSN_MULHH_SS                106)
73   (UNSPEC_INSN_MULHH_SU                107)
74   (UNSPEC_INSN_MULHH_UU                108)
75   (UNSPEC_INSN_MULHLA_SS               109)
76   (UNSPEC_INSN_MULHLA_SU               110)
77   (UNSPEC_INSN_MULHLA_US               111)
78   (UNSPEC_INSN_MULHLA_UU               112)
79   (UNSPEC_INSN_MULHLSA_UU              113)
80   (UNSPEC_INSN_MULHL_SS                114)
81   (UNSPEC_INSN_MULHL_SU                115)
82   (UNSPEC_INSN_MULHL_US                116)
83   (UNSPEC_INSN_MULHL_UU                117)
84   (UNSPEC_INSN_MULLLA_SS               118)
85   (UNSPEC_INSN_MULLLA_SU               119)
86   (UNSPEC_INSN_MULLLA_UU               120)
87   (UNSPEC_INSN_MULLLSA_UU              121)
88   (UNSPEC_INSN_MULLL_SU                122)
89   (UNSPEC_INSN_MULLL_SS                123)
90   (UNSPEC_INSN_MULLL_UU                124)
91   (UNSPEC_INSN_SADAB_U                 125)
92   (UNSPEC_INSN_SADAH                   126)
93   (UNSPEC_INSN_SADAH_U                 127)
94   (UNSPEC_INSN_SADB_U                  128)
95   (UNSPEC_INSN_SADH                    129)
96   (UNSPEC_INSN_SADH_U                  130)
98   ;;
99   ;; The following are special insns.
100   ;;
102   ;; Blockage
103   (UNSPEC_BLOCKAGE                     200)
105   ;; Latency specifying loads.
106   (UNSPEC_LATENCY_L2                   201)
107   (UNSPEC_LATENCY_MISS                 202)
109   ;; Lnk and its label
110   (UNSPEC_LNK_AND_LABEL                203)
112   ;; Memory fence
113   (UNSPEC_MF                           204)
115   ;; A pseudo-op that prevents network operations from being ordered.
116   (UNSPEC_NETWORK_BARRIER              205)
118   ;; Operations that access network registers.
119   (UNSPEC_NETWORK_RECEIVE              206)
120   (UNSPEC_NETWORK_SEND                 207)
122   ;; Stack protector operations
123   (UNSPEC_SP_SET                       208)
124   (UNSPEC_SP_TEST                      209)
126   ;; A call to __tls_get_addr
127   (UNSPEC_TLS_GD_CALL                  210)
129   ;; An opaque TLS "add" operation for TLS general dynamic model
130   ;; access.
131   (UNSPEC_TLS_GD_ADD                   211)
133   ;; An opaque TLS "load" operation for TLS initial exec model access.
134   (UNSPEC_TLS_IE_LOAD                  212)
136   ;;
137   ;; The following are operands.
138   ;;
139   (UNSPEC_PCREL_SYM                    300)
140   (UNSPEC_GOT16_SYM                    301)
141   (UNSPEC_GOT32_SYM                    302)
142   (UNSPEC_TLS_GD                       303)
143   (UNSPEC_TLS_IE                       304)
144   (UNSPEC_TLS_LE                       305)
147 ;; Mark the last instruction of various latencies, used to
148 ;; determine the rtx costs of unspec insns.
149 (define_constants [
150   (TILEPRO_LAST_LATENCY_1_INSN             99)
151   (TILEPRO_LAST_LATENCY_2_INSN            199)
152   (TILEPRO_LAST_LATENCY_INSN              299)
155 ;; Constants for network registers.
156 (define_constants [
157   (TILEPRO_NETREG_IDN0 0)
158   (TILEPRO_NETREG_IDN1 1)
159   (TILEPRO_NETREG_SN   2)
160   (TILEPRO_NETREG_UDN0 3)
161   (TILEPRO_NETREG_UDN1 4)
162   (TILEPRO_NETREG_UDN2 5)
163   (TILEPRO_NETREG_UDN3 6)
166 ;; Constants for special purpose registers.
167 (define_constants [
168   (TILEPRO_NETORDER_REG 66)])
171 ;; Operand and operator predicates and constraints
173 (include "predicates.md")
174 (include "constraints.md")
175 (include "tilepro-generic.md")
177 ;; Define an insn type attribute.  This defines what pipes things can
178 ;; go in.
179 (define_attr "type"
180   "X0,X0_2cycle,X1,X1_branch,X1_2cycle,X1_L2,X1_miss,X01,Y0,Y0_2cycle,Y2,Y2_2cycle,Y2_L2,Y2_miss,Y01,cannot_bundle,cannot_bundle_3cycle,cannot_bundle_4cycle,nothing"
181   (const_string "Y01"))
183 (define_attr "length" ""
184    (cond [(eq_attr "type" "X1_branch")
185           (if_then_else
186            (and (le (minus (match_dup 0) (pc)) (const_int 524280))
187                 (le (minus (pc) (match_dup 0)) (const_int 524288)))
188            (const_int 8)
189            (const_int 16))
190           ]
191          (const_int 8)))
194 ;; Define iterators.
195 (define_mode_iterator I48MODE [SI DI])
196 (define_mode_iterator I12MODE [QI HI])
198 (define_code_iterator binop_u5bit [ashift ashiftrt lshiftrt rotate])
199 (define_code_iterator binop_with_imm
200   [ashift lshiftrt ashiftrt rotate eq lt and ior xor])
201 (define_code_iterator unop [bswap clz ctz popcount])
203 (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw")])
204 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw")])
206 ;; <optab> expands to the name of the optab for a particular code.
207 (define_code_attr optab [(ashift "ashl")
208                          (ashiftrt "ashr")
209                          (lshiftrt "lshr")
210                          (eq "seq")
211                          (ne "sne")
212                          (lt "slt")
213                          (ltu "sltu")
214                          (le "sle")
215                          (leu "sleu")
216                          (minus "sub")
217                          (plus "add")
218                          (rotate "rotl")
219                          (smax "smax")
220                          (smin "smin")
221                          (umax "umax")
222                          (umin "umin")
223                          (ss_minus "sssub")
224                          (ss_plus "ssadd")
225                          (us_minus "ussub")
226                          (us_plus "usadd")
227                          (and "and")
228                          (ior "ior")
229                          (xor "xor")
230                          (bswap "bswap")
231                          (clz "clz")
232                          (ctz "ctz")
233                          (popcount "popcount")])
235 ;; <insn> expands to the name of the insn that implements a particular
236 ;; code.
237 (define_code_attr insn [(ashift "shl")
238                         (ashiftrt "sra")
239                         (lshiftrt "shr")
240                         (eq "seq")
241                         (ne "sne")
242                         (lt "slt")
243                         (ltu "slt")
244                         (le "slte")
245                         (leu "slte")
246                         (minus "sub")
247                         (plus "add")
248                         (rotate "rl")
249                         (smax "max")
250                         (smin "min")
251                         (umax "max")
252                         (umin "min")
253                         (ss_minus "sub")
254                         (ss_plus "add")
255                         (us_minus "sub")
256                         (us_plus "add")
257                         (and "and")
258                         (ior "or")
259                         (xor "xor")
260                         (bswap "bytex")
261                         (clz "clz")
262                         (ctz "ctz")
263                         (popcount "pcnt")])
265 ;; <u> expands to the suffix of the insn that implements a particular
266 ;; code.
267 (define_code_attr u [(ashift "")
268                      (ashiftrt "")
269                      (lshiftrt "")
270                      (eq "")
271                      (ne "")
272                      (lt "")
273                      (ltu "_u")
274                      (le "")
275                      (leu "_u")
276                      (minus "")
277                      (plus "")
278                      (rotate "")
279                      (smax "")
280                      (smin "")
281                      (umax "_u")
282                      (umin "_u")
283                      (ss_minus "s")
284                      (ss_plus "s")
285                      (us_minus "s_u")
286                      (us_plus "s_u")
287                      (and "")
288                      (ior "")
289                      (xor "")])
291 ;; <comm> indicates whether a particular code is commutative, using
292 ;; the "%" commutative opterator constraint.
293 (define_code_attr comm [(ashift "")
294                         (ashiftrt "")
295                         (lshiftrt "")
296                         (eq "%")
297                         (ne "%")
298                         (lt "")
299                         (ltu "")
300                         (le "")
301                         (leu "")
302                         (minus "")
303                         (plus "%")
304                         (rotate "")
305                         (smax "%")
306                         (umax "%")
307                         (smin "%")
308                         (umin "%")
309                         (ss_plus "%")
310                         (us_plus "%")
311                         (ss_minus "")
312                         (us_minus "")
313                         (and "%")
314                         (ior "%")
315                         (xor "%")])
317 (define_mode_iterator VEC [V4QI V2HI])
319 ;; Code iterator for all three shifts.
320 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
322 ;; Code iterator for all byte ops without immediate variants.
323 (define_code_iterator v1op [us_plus ne le leu minus us_minus])
325 ;; Code iterator for all 2-byte vector ops without immediate variants.
326 (define_code_iterator v2op [ss_plus ne le leu minus ss_minus])
328 ;; Code iterator for all byte vector ops with immediate variants.
329 (define_code_iterator v1op_immed [plus umax umin eq lt ltu])
331 ;; Code iterator for all 2-byte vector ops with immediate variants.
332 (define_code_iterator v2op_immed [plus smax smin eq lt ltu])
334 ;; Code for packing two 2-byte vectors.
335 (define_code_iterator v2pack [truncate us_truncate])
337 ;; <pack_optab> expands to the part of the optab name describing how
338 ;; two vectors are packed.
339 (define_code_attr pack_optab [(truncate "trunc")
340                               (us_truncate "usat")
341                               (ss_truncate "ssat")])
343 ;; <pack_insn> expands to the insn that implements a particular vector
344 ;; packing code.
345 (define_code_attr pack_insn [(truncate "packl")
346                              (us_truncate "pack")
347                              (ss_truncate "pack")])
349 ;; <pack_u> expands to the suffix of the insn that implements a
350 ;; particular vector packing code.
351 (define_code_attr pack_u [(truncate "")
352                           (us_truncate "s_u")
353                           (ss_truncate "s")])
357 ;; The basic data move insns.
360 (define_expand "movqi"
361   [(set (match_operand:QI 0 "nonimmediate_operand" "")
362         (match_operand:QI 1 "nonautoinc_operand" ""))]
363   ""
365   if (tilepro_expand_mov (QImode, operands))
366     DONE;
369 (define_insn "*movqi_insn"
370   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,U,m")
371         (match_operand:QI 1 "move_operand"         "r,I,U,m,rO,rO"))]
372   "(register_operand (operands[0], QImode)
373     || reg_or_0_operand (operands[1], QImode))"
374   "@
375    move\t%0, %r1
376    movei\t%0, %1
377    lb_u\t%0, %1
378    lbadd_u\t%0, %I1, %i1
379    sb\t%0, %r1
380    sbadd\t%I0, %r1, %i0"
381   [(set_attr "type" "*,*,Y2_2cycle,X1_2cycle,Y2,X1")])
383 (define_expand "movhi"
384   [(set (match_operand:HI 0 "nonimmediate_operand" "")
385         (match_operand:HI 1 "nonautoinc_operand" ""))]
386   ""
388   if (tilepro_expand_mov (HImode, operands))
389     DONE;
392 (define_insn "*movhi_insn"
393   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,r,U,m")
394         (match_operand:HI 1 "move_operand"         "r,I,J,U,m,rO,rO"))]
395   "(register_operand (operands[0], HImode)
396     || reg_or_0_operand (operands[1], HImode))"
397   "@
398    move\t%0, %r1
399    movei\t%0, %1
400    moveli\t%0, %1
401    lh_u\t%0, %1
402    lhadd_u\t%0, %I1, %i1
403    sh\t%0, %r1
404    shadd\t%I0, %r1, %i0"
405   [(set_attr "type" "*,*,X01,Y2_2cycle,X1_2cycle,Y2,X1")])
408 (define_expand "movsi"
409   [(set (match_operand:SI 0 "nonimmediate_operand" "")
410         (match_operand:SI 1 "nonautoinc_operand" ""))]
411   ""
413   if (tilepro_expand_mov (SImode, operands))
414     DONE;
417 (define_insn "*movsi_high_insn"
418   [(set (match_operand:SI 0 "register_operand" "=r")
419         (high:SI (match_operand:SI 1 "symbolic_operand" "in")))]
420   ""
421   "auli\t%0, zero, ha16(%1)"
422   [(set_attr "type" "X01")])
424 (define_insn "*movsi_insn"
425   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,r,U,m")
426         (match_operand:SI 1 "move_operand"         "r,I,J,K,N,P,U,m,rO,rO"))]
427   "(register_operand (operands[0], SImode)
428     || reg_or_0_operand (operands[1], SImode))"
429   "@
430    move\t%0, %r1
431    movei\t%0, %1
432    moveli\t%0, %1
433    auli\t%0, zero, %h1
434    addib\t%0, zero, %j1
435    addih\t%0, zero, %h1
436    lw\t%0, %1
437    lwadd\t%0, %I1, %i1
438    sw\t%0, %r1
439    swadd\t%I0, %r1, %i0"
440   [(set_attr "type" "*,*,X01,X01,X01,X01,Y2_2cycle,X1_2cycle,Y2,X1")])
442 (define_insn "movstrictqi"
443   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
444         (match_operand:QI 1 "reg_or_0_operand" "rO"))]
445   ""
446   "mm\t%r0, %r1, %r0, 0, 7"
447   [(set_attr "type" "X01")])
448   
449 (define_insn "movstricthi"
450   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
451         (match_operand:HI 1 "reg_or_0_operand" "rO"))]
452   ""
453   "mm\t%r0, %r1, %r0, 0, 15"
454   [(set_attr "type" "X01")])
455   
456 (define_expand "movmisalign<mode>"
457   [(set (match_operand:VEC 0 "nonautoincmem_nonimmediate_operand" "")
458         (match_operand:VEC 1 "nonautoincmem_general_operand" ""))]
459   ""
461   tilepro_expand_movmisalign (<MODE>mode, operands);
462   DONE;
465 (define_expand "movsf"
466   [(set (match_operand:SF 0 "nonimmediate_operand" "")
467         (match_operand:SF 1 "general_operand" ""))]
468   ""
470   /* Materialize immediates using clever SImode code, but don't
471      do this after reload starts, since gen_lowpart will choke
472      during reload if given an illegitimate address. */
473   if (immediate_operand (operands[1], SFmode)
474       && operands[1] != const0_rtx
475       && (register_operand (operands[0], SFmode)
476           || (!reload_in_progress && !reload_completed)))
477     {
478       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
479                             gen_lowpart (SImode, operands[1])));
480       DONE;
481     }
484 (define_insn "*movsf"
485   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,U,m")
486         (match_operand:SF 1 "general_operand" "rO,U,m,rO,rO"))]
487   ""
488   "@
489    move\t%0, %r1
490    lw\t%0, %1
491    lwadd\t%0, %I1, %i1
492    sw\t%0, %r1
493    swadd\t%I0, %r1, %i0"
494   [(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")])
496 (define_expand "mov<mode>"
497   [(set (match_operand:VEC 0 "nonimmediate_operand" "")
498         (match_operand:VEC 1 "general_operand" ""))]
499   ""
501   /* Materialize immediates using clever SImode code, but don't
502      do this after reload starts, since gen_lowpart will choke
503      during reload if given an illegitimate address. */
504   if (immediate_operand (operands[1], <MODE>mode)
505       && operands[1] != const0_rtx
506       && (register_operand (operands[0], <MODE>mode)
507           || (!reload_in_progress && !reload_completed)))
508     {
509       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
510                             gen_lowpart (SImode, operands[1])));
511       DONE;
512     }
515 (define_insn "*mov<mode>"
516   [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,U,m")
517         (match_operand:VEC 1 "general_operand" "rO,U,m,rO,rO"))]
518   ""
519   "@
520    move\t%0, %r1
521    lw\t%0, %1
522    lwadd\t%0, %I1, %i1
523    sw\t%0, %r1
524    swadd\t%I0, %r1, %i0"
525   [(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")])
529 ;; Bit-field extracts
532 (define_expand "extv"
533   [(set (match_operand:SI 0 "register_operand" "")
534         (sign_extract:SI
535          (match_operand:QI 1 "nonautoincmem_operand" "")
536          (match_operand:SI 2 "immediate_operand" "")
537          (match_operand:SI 3 "immediate_operand" "")))]
538   ""
540   HOST_WIDE_INT bit_offset, bit_width;
541   HOST_WIDE_INT first_byte_offset, last_byte_offset;
543   bit_width = INTVAL (operands[2]);
544   bit_offset = INTVAL (operands[3]);
546   /* Reject bitfields that can be done with a normal load */
547   if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
548     FAIL;
550   /* The value in memory cannot span more than 4 bytes. */
551   first_byte_offset = bit_offset / BITS_PER_UNIT;
552   last_byte_offset = (bit_offset + bit_width - 1) / BITS_PER_UNIT;
553   if (last_byte_offset - first_byte_offset > 3)
554     FAIL;
556   tilepro_expand_unaligned_load (operands[0], operands[1],
557                                  bit_width, bit_offset, 1);
559   DONE;
562 (define_expand "extzv"
563   [(set (match_operand:SI 0 "register_operand" "")
564         (zero_extract:SI
565          (match_operand:QI 1 "nonautoincmem_operand" "")
566          (match_operand:SI 2 "immediate_operand" "")
567          (match_operand:SI 3 "immediate_operand" "")))]
568   ""
570   HOST_WIDE_INT bit_offset, bit_width;
571   HOST_WIDE_INT first_byte_offset, last_byte_offset;
573   bit_width = INTVAL (operands[2]);
574   bit_offset = INTVAL (operands[3]);
576   /* Reject bitfields that can be done with a normal load */
577   if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
578     FAIL;
580   /* The value in memory cannot span more than 4 bytes. */
581   first_byte_offset = bit_offset / BITS_PER_UNIT;
582   last_byte_offset = (bit_offset + bit_width - 1) / BITS_PER_UNIT;
583   if (last_byte_offset - first_byte_offset > 3)
584     FAIL;
586   tilepro_expand_unaligned_load (operands[0], operands[1],
587                                  bit_width, bit_offset, 0);
589   DONE;
594 ;; Arithmetic ops
597 (define_insn "*s123a_insn"
598   [(set (match_operand:SI 0 "register_operand" "=r")
599         (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
600                           (match_operand:SI 2 "cint_248_operand" "I"))
601                  (match_operand:SI 3 "reg_or_0_operand" "rO")))]
602   ""
603   "s%t2a\t%0, %r1, %r3")
605 (define_expand "addsi3"
606   [(set (match_operand:SI 0 "register_operand" "")
607         (plus:SI (match_operand:SI 1 "register_operand" "")
608                  (match_operand:SI 2 "reg_or_cint_operand" "")))]
609   ""
610   "
611     if (tilepro_expand_addsi (operands[0], operands[1], operands[2]))
612       DONE;
613   ")
615 (define_insn "*addsi_high_insn"
616   [(set (match_operand:SI 0 "register_operand" "=r")
617         (plus:SI
618          (match_operand:SI 1 "reg_or_0_operand" "%rO")
619          (high:SI (match_operand:SI 2 "const_symbolic_operand" "T"))))]
620   ""
621   "auli\t%0, %r1, %H2"
622   [(set_attr "type" "X01")])
624 (define_insn "*addsi_lo_sum_insn"
625   [(set (match_operand:SI 0 "register_operand" "=r")
626         (lo_sum:SI
627          (match_operand:SI 1 "reg_or_0_operand" "%rO")
628          (match_operand:SI 2 "const_symbolic_operand" "T")))]
629   ""
630   "addli\t%0, %r1, %L2"
631   [(set_attr "type" "X01")])
633 (define_insn "*addsi3_insn"
634   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
635         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO,rO")
636                  (match_operand:SI 2 "add_operand" "r,I,J,K")))]
637   ""
638   "@
639    add\t%0, %r1, %r2
640    addi\t%0, %r1, %2
641    addli\t%0, %r1, %2
642    auli\t%0, %r1, %h2"
643   [(set_attr "type" "*,*,X01,X01")])
645 (define_insn "subsi3"
646   [(set (match_operand:SI 0 "register_operand" "=r")
647         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
648                   (match_operand:SI 2 "reg_or_0_operand" "rO")))]
649   ""
650   "sub\t%0, %r1, %r2")
652 (define_insn "negsi2"
653   [(set (match_operand:SI 0 "register_operand" "=r")
654         (neg:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))]
655   ""
656   "sub\t%0, zero, %r1")
658 (define_insn "ssaddsi3"
659   [(set (match_operand:SI 0 "register_operand" "=r")
660         (ss_plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
661                     (match_operand:SI 2 "reg_or_0_operand" "rO")))]
662   ""
663   "adds\t%0, %r1, %r2"
664   [(set_attr "type" "X01")])
666 (define_insn "sssubsi3"
667   [(set (match_operand:SI 0 "register_operand" "=r")
668         (ss_minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
669                      (match_operand:SI 2 "reg_or_0_operand" "rO")))]
670   ""
671   "subs\t%0, %r1, %r2"
672   [(set_attr "type" "X01")])
675 ;; Shifts
678 ;; ashift, ashiftrt, lshiftrt, rotate.
679 (define_insn "<optab>si3"
680   [(set (match_operand:SI 0 "register_operand" "=r,r")
681         (binop_u5bit:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
682                         (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
683   ""
684   "@
685   <insn>i\t%0, %r1, %2
686   <insn>\t%0, %r1, %r2")
690 ;; Compares
693 (define_expand "cstore<mode>4"
694   [(set (match_operand:SI 0 "register_operand" "")
695         (match_operator:SI 1 "ordered_comparison_operator"
696          [(match_operand:I48MODE 2 "reg_or_cint_operand" "")
697           (match_operand:I48MODE 3 "reg_or_cint_operand" "")]))]
698   ""
699   { if (!tilepro_emit_setcc (operands, <MODE>mode)) FAIL; else DONE; })
701 (define_insn "insn_seq"
702   [(set (match_operand:SI 0 "register_operand" "=r,r")
703         (eq:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
704                (match_operand:SI 2 "reg_or_cint_operand" "I,rO")))]
705   ""
706   "@
707    seqi\t%0, %r1, %2
708    seq\t%0, %r1, %r2")
710 (define_insn "insn_sne"
711   [(set (match_operand:SI 0 "register_operand" "=r")
712         (ne:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
713                (match_operand:SI 2 "reg_or_cint_operand" "rO")))]
714   ""
715   "sne\t%0, %r1, %r2")
717 (define_insn "insn_slt"
718   [(set (match_operand:SI 0 "register_operand" "=r,r")
719         (lt:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
720                (match_operand:SI 2 "reg_or_cint_operand" "I,rO")))]
721   ""
722   "@
723    slti\t%0, %r1, %2
724    slt\t%0, %r1, %r2")
726 (define_insn "insn_slte"
727   [(set (match_operand:SI 0 "register_operand" "=r,r")
728         (le:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
729                (match_operand:SI 2 "reg_or_cint_operand" "L,rO")))]
730   ""
731   "@
732    slti\t%0, %r1, %P2
733    slte\t%0, %r1, %r2")
735 (define_insn "insn_slt_u"
736   [(set (match_operand:SI 0 "register_operand" "=r,r")
737         (ltu:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
738                 (match_operand:SI 2 "reg_or_cint_operand" "I,rO")))]
739   ""
740   "@
741    slti_u\t%0, %r1, %2
742    slt_u\t%0, %r1, %r2")
744 (define_insn "insn_slte_u"
745   [(set (match_operand:SI 0 "register_operand" "=r,r")
746         (leu:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
747                 (match_operand:SI 2 "reg_or_cint_operand" "Q,rO")))]
748   ""
749   "@
750    slti_u\t%0, %r1, %P2
751    slte_u\t%0, %r1, %r2")
755 ;; Logical ops
758 (define_insn "andsi3"
759   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
760         (and:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO")
761                 (match_operand:SI 2 "and_operand" "I,M,rO")))]
762   ""
763   "@
764    andi\t%0, %r1, %2
765    mm\t%0, %r1, zero, %M2
766    and\t%0, %r1, %r2"
767   [(set_attr "type" "*,X01,*")])
768   
769 (define_insn "iorsi3"
770   [(set (match_operand:SI 0 "register_operand" "=r,r")
771         (ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
772                 (match_operand:SI 2 "reg_or_s8bit_operand" "I,rO")))]
773   ""
774   "@
775    ori\t%0, %r1, %2
776    or\t%0, %r1, %r2")
777   
778 (define_insn "xorsi3"
779   [(set (match_operand:SI 0 "register_operand" "=r,r")
780         (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
781                 (match_operand:SI 2 "reg_or_s8bit_operand" "rO,I")))]
782   ""
783   "@
784    xor\t%0, %r1, %r2
785    xori\t%0, %r1, %2"
786   [(set_attr "type" "*,X01")])
787   
788 ;; bswap, clz, ctz, popcount
789 (define_insn "<optab>si2"
790   [(set (match_operand:SI 0 "register_operand" "=r")
791         (unop:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))]
792   ""
793   "<insn>\t%0, %r1"
794   [(set_attr "type" "Y0")])
796 (define_expand "ctzdi2"
797   [(set (match_operand:DI 0 "register_operand" "")
798         (ctz:DI (match_operand:DI 1 "register_operand" "")))]
799   ""
801   rtx lo, hi, ctz_lo, ctz_hi, ctz_hi_plus_32, result;
803   split_di (&operands[1], 1, &lo, &hi);
804   lo = force_reg (SImode, lo);
805   hi = force_reg (SImode, hi);
807   ctz_lo = gen_reg_rtx (SImode);
808   emit_insn (gen_ctzsi2 (ctz_lo, lo));
810   ctz_hi = gen_reg_rtx (SImode);
811   emit_insn (gen_ctzsi2 (ctz_hi, hi));
813   ctz_hi_plus_32 = gen_reg_rtx (SImode);
814   emit_insn (gen_addsi3 (ctz_hi_plus_32, ctz_hi, GEN_INT (32)));
816   result = gen_reg_rtx (SImode);
817   emit_insn (gen_insn_mvz (result, ctz_lo, lo, ctz_hi_plus_32));
819   emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
821   DONE;
824 (define_expand "clzdi2"
825   [(set (match_operand:DI 0 "register_operand" "")
826         (clz:DI (match_operand:DI 1 "register_operand" "")))]
827   ""
829   rtx lo, hi, clz_lo, clz_hi, clz_lo_plus_32, result;
831   split_di (&operands[1], 1, &lo, &hi);
832   lo = force_reg (SImode, lo);
833   hi = force_reg (SImode, hi);
835   clz_lo = gen_reg_rtx (SImode);
836   emit_insn (gen_clzsi2 (clz_lo, lo));
838   clz_hi = gen_reg_rtx (SImode);
839   emit_insn (gen_clzsi2 (clz_hi, hi));
841   clz_lo_plus_32 = gen_reg_rtx (SImode);
842   emit_insn (gen_addsi3 (clz_lo_plus_32, clz_lo, GEN_INT (32)));
844   result = gen_reg_rtx (SImode);
845   emit_insn (gen_insn_mvz (result, clz_hi, hi, clz_lo_plus_32));
847   emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
849   DONE;
852 (define_expand "ffsdi2"
853   [(set (match_operand:DI 0 "register_operand" "")
854         (ffs:DI (match_operand:DI 1 "register_operand" "")))]
855   ""
857   rtx lo, hi, ctz_lo, ctz_hi, ctz_hi_plus_32, ctz, ctz_plus_1,ctz_cond;
858   rtx result;
860   split_di (&operands[1], 1, &lo, &hi);
861   lo = force_reg (SImode, lo);
862   hi = force_reg (SImode, hi);
864   ctz_lo = gen_reg_rtx (SImode);
865   emit_insn (gen_ctzsi2 (ctz_lo, lo));
867   ctz_hi = gen_reg_rtx (SImode);
868   emit_insn (gen_ctzsi2 (ctz_hi, hi));
870   ctz_hi_plus_32 = gen_reg_rtx (SImode);
871   emit_insn (gen_addsi3 (ctz_hi_plus_32, ctz_hi, GEN_INT (32)));
873   ctz = gen_reg_rtx (SImode);
874   emit_insn (gen_insn_mvz (ctz, ctz_lo, lo, ctz_hi_plus_32));
876   ctz_plus_1 = gen_reg_rtx (SImode);
877   emit_insn (gen_addsi3 (ctz_plus_1, ctz, GEN_INT (1)));
879   ctz_cond = gen_reg_rtx (SImode);
880   emit_insn (gen_iorsi3 (ctz_cond, lo, hi));
882   result = gen_reg_rtx (SImode);
883   emit_insn (gen_insn_mvz (result, ctz_plus_1, ctz_cond, const0_rtx));
885   emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
887   DONE;
890 (define_expand "popcountdi2"
891   [(set (match_operand:DI 0 "register_operand" "")
892         (popcount:DI (match_operand:DI 1 "nonmemory_operand" "")))]
893   ""
895   rtx lo, hi, popcount_lo, popcount_hi, result;
897   split_di (&operands[1], 1, &lo, &hi);
898   lo = force_reg (SImode, lo);
899   hi = force_reg (SImode, hi);
901   popcount_lo = gen_reg_rtx (SImode);
902   emit_insn (gen_popcountsi2 (popcount_lo, lo));
904   popcount_hi = gen_reg_rtx (SImode);
905   emit_insn (gen_popcountsi2 (popcount_hi, hi));
907   result = gen_reg_rtx (SImode);
908   emit_insn (gen_addsi3 (result, popcount_lo, popcount_hi));
910   emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
912   DONE;
915 (define_expand "paritysi2"
916   [(set (match_operand:SI 0 "register_operand" "")
917         (parity:SI (match_operand:SI 1 "reg_or_0_operand" "")))]
918   ""
919   {
920     operands[2] = gen_reg_rtx (SImode);
921     emit_insn (gen_popcountsi2 (operands[2], operands[1]));
922     emit_insn (gen_andsi3 (operands[0], operands[2], const1_rtx));
923     DONE;
924   })
926 (define_expand "paritydi2"
927   [(set (match_operand:DI 0 "register_operand" "")
928         (parity:DI (match_operand:DI 1 "nonmemory_operand" "")))]
929   ""
931   rtx lo, hi, xor_lohi, result;
933   split_di (&operands[1], 1, &lo, &hi);
934   lo = force_reg (SImode, lo);
935   hi = force_reg (SImode, hi);
937   xor_lohi = gen_reg_rtx (SImode);
938   emit_insn (gen_xorsi3 (xor_lohi, lo, hi));
940   result = gen_reg_rtx (SImode);
941   emit_insn (gen_paritysi2 (result, xor_lohi));
943   emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
945   DONE;
948 (define_insn "one_cmplsi2"
949   [(set (match_operand:SI 0 "register_operand" "=r")
950         (not:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))]
951   ""
952   "nor\t%0, %r1, zero")
956 ;; Conditional moves.
959 (define_expand "movsicc"
960   [(set (match_operand:SI 0 "register_operand" "")
961         (if_then_else:SI (match_operand 1 "comparison_operator" "")
962                          (match_operand:SI 2 "reg_or_0_operand" "")
963                          (match_operand:SI 3 "reg_or_0_operand" "")))]
964   ""
965   { operands[1] = tilepro_emit_conditional_move (operands[1]); })
967 (define_insn "movcc_insn"
968   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
969         (if_then_else:SI
970          (match_operator 4 "eqne_operator"
971           [(match_operand:SI 1 "reg_or_0_operand" "rO,rO,rO,rO")
972            (const_int 0)])
973          (match_operand:SI 2 "reg_or_0_operand" "rO,O,rO,0")
974          (match_operand:SI 3 "reg_or_0_operand" "O,rO,0,rO")))]
975   ""
976   "@
977    m%c4\t%0, %r1, %r2
978    m%C4\t%0, %r1, %r3
979    mv%c4\t%0, %r1, %r2
980    mv%C4\t%0, %r1, %r3"
981   [(set_attr "type" "*,*,Y0,Y0")])
983 (define_expand "insn_mz"
984   [(set (match_operand:SI 0 "register_operand" "")
985         (if_then_else:SI
986          (eq (match_operand:SI 1 "reg_or_0_operand" "")
987              (const_int 0))
988          (match_operand:SI 2 "reg_or_0_operand" "")
989          (const_int 0)))])
991 (define_expand "insn_mnz"
992   [(set (match_operand:SI 0 "register_operand" "")
993         (if_then_else:SI
994          (ne (match_operand:SI 1 "reg_or_0_operand" "")
995              (const_int 0))
996          (match_operand:SI 2 "reg_or_0_operand" "")
997          (const_int 0)))])
999 (define_expand "insn_mvz"
1000   [(set (match_operand:SI 0 "register_operand" "")
1001         (if_then_else:SI
1002          (eq (match_operand:SI 2 "reg_or_0_operand" "")
1003              (const_int 0))
1004          (match_operand:SI 3 "reg_or_0_operand" "")
1005          (match_operand:SI 1 "reg_or_0_operand" "")))])
1006    
1007 (define_expand "insn_mvnz"
1008   [(set (match_operand:SI 0 "register_operand" "")
1009         (if_then_else:SI
1010          (ne (match_operand:SI 2 "reg_or_0_operand" "")
1011              (const_int 0))
1012          (match_operand:SI 3 "reg_or_0_operand" "")
1013          (match_operand:SI 1 "reg_or_0_operand" "")))])
1014    
1017 ;; Conversions
1020 (define_insn "zero_extendqisi2"
1021   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1022         (zero_extend:SI (match_operand:QI 1 "move_operand" "rO,U,m")))]
1023   ""
1024   "@
1025    mm\t%0, %r1, zero, 0, 7
1026    lb_u\t%0, %1
1027    lbadd_u\t%0, %I1, %i1"
1028   [(set_attr "type" "X01,Y2_2cycle,X1_2cycle")])
1029   
1030 (define_insn "zero_extendhisi2"
1031   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1032         (zero_extend:SI (match_operand:HI 1 "move_operand" "rO,U,m")))]
1033   ""
1034   "@
1035    mm\t%0, %r1, zero, 0, 15
1036    lh_u\t%0, %1
1037    lhadd_u\t%0, %I1, %i1"
1038   [(set_attr "type" "X01,Y2_2cycle,X1_2cycle")])
1040 (define_expand "extendhisi2"
1041   [(set (match_operand:SI 0 "register_operand" "")
1042         (sign_extend:SI (match_operand:HI 1 "move_operand" "")))]
1043   ""
1045   if (!memory_operand (operands[1], HImode))
1046   {
1047     operands[1] = gen_lowpart (SImode, operands[1]);
1048     operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
1050     emit_move_insn (operands[2], gen_rtx_ASHIFT (SImode, operands[1],
1051                                                  GEN_INT (16)));
1052     emit_move_insn (operands[0], gen_rtx_ASHIFTRT (SImode, operands[2],
1053                                                    GEN_INT (16)));
1054     DONE;
1055   }
1058 (define_insn "*lh"
1059   [(set (match_operand:SI 0 "register_operand" "=r,r")
1060         (sign_extend:SI (match_operand:HI 1 "memory_operand" "U,m")))]
1061   ""
1062   "@
1063    lh\t%0, %1
1064    lhadd\t%0, %I1, %i1"
1065   [(set_attr "type" "Y2_2cycle,X1_2cycle")])
1067 (define_expand "extendqisi2"
1068   [(set (match_operand:SI 0 "register_operand" "")
1069         (sign_extend:SI (match_operand:QI 1 "move_operand" "")))]
1070   ""
1072   if (!memory_operand (operands[1], QImode))
1073   {
1074     operands[1] = gen_lowpart (SImode, operands[1]);
1075     operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
1077     emit_move_insn (operands[2], gen_rtx_ASHIFT (SImode, operands[1],
1078                                                  GEN_INT (24)));
1079     emit_move_insn (operands[0], gen_rtx_ASHIFTRT (SImode, operands[2],
1080                                                    GEN_INT (24)));
1081     DONE;
1082   }
1085 (define_insn "*lb"
1086   [(set (match_operand:SI 0 "register_operand" "=r,r")
1087         (sign_extend:SI (match_operand:QI 1 "memory_operand" "U,m")))]
1088   ""
1089   "@
1090    lb\t%0, %1
1091    lbadd\t%0, %I1, %i1"
1092   [(set_attr "type" "Y2_2cycle,X1_2cycle")])
1095 ;; insv patterns
1097 (define_expand "insv"
1098   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
1099                          (match_operand:SI 1 "u5bit_cint_operand" "")
1100                          (match_operand:SI 2 "u5bit_cint_operand" ""))
1101         (match_operand:SI 3 "reg_or_cint_operand" ""))]
1102   ""
1104   tilepro_expand_insv (operands);
1105   DONE;
1108 (define_insn "*insv_tblidxb0"
1109   [(set (zero_extract:SI
1110          (match_operand:SI 0 "register_operand" "+r")
1111          (const_int 8)
1112          (const_int 2))
1113         (match_operand:SI 1 "register_operand" "rO"))]
1114   ""
1115   "tblidxb0\t%0, %r1"
1116   [(set_attr "type" "Y0")])
1118 (define_insn "*insv_tblidxb1"
1119   [(set (zero_extract:SI
1120          (match_operand:SI 0 "register_operand" "+r")
1121          (const_int 8)
1122          (const_int 2))
1123         (zero_extract:SI
1124          (const_int 8)
1125          (const_int 8)
1126         (match_operand:SI 1 "register_operand" "rO")))]
1127   ""
1128   "tblidxb1\t%0, %r1"
1129   [(set_attr "type" "Y0")])
1131 (define_insn "*insv_tblidxb2"
1132   [(set (zero_extract:SI
1133          (match_operand:SI 0 "register_operand" "+r")
1134          (const_int 8)
1135          (const_int 2))
1136         (zero_extract:SI
1137          (const_int 8)
1138          (const_int 16)
1139         (match_operand:SI 1 "register_operand" "rO")))]
1140   ""
1141   "tblidxb2\t%0, %r1"
1142   [(set_attr "type" "Y0")])
1144 (define_insn "*insv_tblidxb3"
1145   [(set (zero_extract:SI
1146          (match_operand:SI 0 "register_operand" "+r")
1147          (const_int 8)
1148          (const_int 2))
1149         (zero_extract:SI
1150          (const_int 8)
1151          (const_int 24)
1152         (match_operand:SI 1 "register_operand" "rO")))]
1153   ""
1154   "tblidxb3\t%0, %r1"
1155   [(set_attr "type" "Y0")])
1157 (define_insn "*insv_mm1"
1158   [(set (zero_extract:SI
1159          (match_operand:SI 0 "register_operand" "+r")
1160          (match_operand:SI 1 "u5bit_cint_operand" "n")
1161          (const_int 0))
1162         (match_operand:SI 2 "register_operand" "rO"))]
1163   ""
1164   "mm\t%0, %r2, %0, 0, %1-1"
1165   [(set_attr "type" "X01")])
1167 (define_insn "*insv_mm2"
1168   [(set (zero_extract:SI
1169          (match_operand:SI 0 "register_operand" "+r")
1170          (match_operand:SI 1 "u5bit_cint_operand" "n")
1171          (match_operand:SI 2 "u5bit_cint_operand" "n"))
1172         (zero_extract:SI
1173          (match_operand:SI 3 "register_operand" "rO")
1174          (match_dup 1)
1175          (match_dup 2)))]
1176   ""
1177   "mm\t%0, %r3, %0, %2, %2+%1-1"
1178   [(set_attr "type" "X01")])
1182 ;; Multiplies
1185 (define_expand "mulsi3"
1186   [(set (match_operand:SI 0 "register_operand" "=r")
1187         (mult:SI (zero_extend:SI
1188                   (subreg:HI (match_operand:SI 1 "nonmemory_operand" "") 0))
1189                  (zero_extend:SI
1190                   (subreg:HI (match_operand:SI 2 "nonmemory_operand" "") 0))))
1191    (set (match_dup 0)
1192         (unspec:SI [(match_dup 0) (match_dup 1) (match_dup 2)]
1193                    UNSPEC_INSN_MULHLSA_UU))
1194    (set (match_dup 0)
1195         (unspec:SI [(match_dup 0) (match_dup 2) (match_dup 1)]
1196                    UNSPEC_INSN_MULHLSA_UU))]
1197   ""
1198   {
1199     operands[1] = force_reg (SImode, operands[1]);
1200     operands[1] = make_safe_from (operands[1], operands[0]);
1202     if (tilepro_expand_mulsi (operands[0], operands[1], operands[2]))
1203       DONE;
1204     else
1205       {
1206         operands[2] = force_reg (SImode, operands[2]);
1207         operands[2] = make_safe_from (operands[2], operands[0]);
1208       }
1209   })
1211 (define_insn "mulhisi3"
1212   [(set (match_operand:SI 0 "register_operand" "=r")
1213         (mult:SI (sign_extend:SI
1214                   (match_operand:HI 1 "reg_or_0_operand" "rO"))
1215                  (sign_extend:SI
1216                   (match_operand:HI 2 "reg_or_0_operand" "rO"))))]
1217   ""
1218   "mulll_ss\t%0, %r1, %r2"
1219   [(set_attr "type" "Y0_2cycle")])
1220   
1221 (define_insn "umulhisi3"
1222   [(set (match_operand:SI 0 "register_operand" "=r")
1223         (mult:SI (zero_extend:SI
1224                   (match_operand:HI 1 "reg_or_0_operand" "rO"))
1225                  (zero_extend:SI
1226                   (match_operand:HI 2 "reg_or_0_operand" "rO"))))]
1227   ""
1228   "mulll_uu\t%0, %r1, %r2"
1229   [(set_attr "type" "Y0_2cycle")])
1230   
1231 (define_insn "usmulhisi3"
1232   [(set (match_operand:SI 0 "register_operand" "=r")
1233         (mult:SI (zero_extend:SI
1234                   (match_operand:HI 1 "reg_or_0_operand" "rO"))
1235                  (sign_extend:SI
1236                   (match_operand:HI 2 "reg_or_0_operand" "rO"))))]
1237   ""
1238   "mulll_su\t%0, %r2, %r1"
1239   [(set_attr "type" "X0_2cycle")])
1240   
1241 (define_insn "maddhisi4"
1242   [(set (match_operand:SI 0 "register_operand" "=r")
1243         (plus:SI
1244          (mult:SI (sign_extend:SI
1245                    (match_operand:HI 1 "reg_or_0_operand" "rO"))
1246                   (sign_extend:SI
1247                    (match_operand:HI 2 "reg_or_0_operand" "rO")))
1248          (match_operand:SI 3 "register_operand" "0")))]
1249   ""
1250   "mullla_ss\t%0, %r1, %r2"
1251   [(set_attr "type" "Y0_2cycle")])
1252   
1253 (define_insn "umaddhisi4"
1254   [(set (match_operand:SI 0 "register_operand" "=r")
1255         (plus:SI
1256          (mult:SI (zero_extend:SI
1257                    (match_operand:HI 1 "reg_or_0_operand" "rO"))
1258                   (zero_extend:SI
1259                    (match_operand:HI 2 "reg_or_0_operand" "rO")))
1260          (match_operand:SI 3 "register_operand" "0")))]
1261   ""
1262   "mullla_uu\t%0, %r1, %r2"
1263   [(set_attr "type" "Y0_2cycle")])
1264   
1266 (define_insn "mulqihi3"
1267   [(set (match_operand:HI 0 "register_operand" "=r")
1268         (mult:HI (sign_extend:HI
1269                   (match_operand:QI 1 "reg_or_0_operand" "rO"))
1270                  (sign_extend:HI
1271                   (match_operand:QI 2 "reg_or_0_operand" "rO"))))]
1272   ""
1273   "mulll_ss\t%0, %r1, %r2"
1274   [(set_attr "type" "Y0_2cycle")])
1275   
1276 (define_insn "umulqihi3"
1277   [(set (match_operand:HI 0 "register_operand" "=r")
1278         (mult:HI (zero_extend:HI
1279                   (match_operand:QI 1 "reg_or_0_operand" "rO"))
1280                  (zero_extend:HI
1281                   (match_operand:QI 2 "reg_or_0_operand" "rO"))))]
1282   ""
1283   "mulll_uu\t%0, %r1, %r2"
1284   [(set_attr "type" "Y0_2cycle")])
1286 (define_expand "smulsi3_highpart"
1287   [(set (match_operand:SI 0 "register_operand" "")
1288         (truncate:SI
1289          (ashiftrt:DI 
1290           (mult:DI (sign_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
1291                    (sign_extend:DI (match_operand:SI 2 "reg_or_0_operand" "")))
1292           (const_int 32))))]
1293   ""
1294   {
1295     tilepro_expand_smulsi3_highpart (operands[0], operands[1], operands[2]);
1296     DONE;
1297   })
1299 (define_expand "umulsi3_highpart"
1300   [(set (match_operand:SI 0 "register_operand" "")
1301         (truncate:SI
1302          (lshiftrt:DI
1303           (mult:DI (zero_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
1304                    (zero_extend:DI (match_operand:SI 2 "reg_or_0_operand" "")))
1305           (const_int 32))))]
1306   ""
1308   tilepro_expand_umulsi3_highpart (operands[0], operands[1], operands[2]);
1309   DONE;
1314 ;; Loops
1317 ;; Define the subtract-one-and-jump insns so loop.c knows what to
1318 ;; generate.
1319 (define_expand "doloop_end"
1320   [(use (match_operand 0 "" ""))    ;; loop pseudo
1321    (use (match_operand 1 "" ""))]   ;; label
1322    ""
1324   if (optimize > 0)
1325   {
1326      rtx s0;
1327      rtx bcomp;
1328      rtx loc_ref;
1330      /* only deal with loop counters in SImode  */
1331      if (GET_MODE (operands[0]) != SImode)
1332        FAIL;
1334      s0 = operands [0];
1336      emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
1337      bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
1338      loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
1339      emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1340                                   gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
1341                                                         loc_ref, pc_rtx)));
1342      DONE;
1343   }
1344   else
1345      FAIL;
1350 ;; Prologue/epilogue
1352 (define_expand "prologue"
1353   [(const_int 0)]
1354   ""
1356   tilepro_expand_prologue ();
1357   DONE;
1360 (define_expand "epilogue"
1361   [(const_int 0)]
1362   ""
1364   tilepro_expand_epilogue (false);
1365   DONE;
1368 (define_expand "sibcall_epilogue"
1369   [(const_int 0)]
1370   ""
1372   tilepro_expand_epilogue (true);
1373   DONE;
1377 ;; Stack manipulations
1380 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
1381 (define_expand "allocate_stack"
1382   [(set (match_operand 0 "register_operand" "")
1383         (minus (reg 54) (match_operand 1 "nonmemory_operand" "")))
1384    (set (reg 54)
1385         (minus (reg 54) (match_dup 1)))]
1386   ""
1387   "tilepro_allocate_stack (operands[0], operands[1]); DONE;")
1390 ;; Branches
1392 (define_expand "call"
1393   [(parallel [(call (match_operand:SI 0 "call_operand" "")
1394                     (match_operand 1 "" ""))
1395               (use (reg:SI 54))
1396               (clobber (reg:SI 55))])]
1397   ""
1398   "")
1400 (define_insn "*call_insn"
1401   [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rO,i"))
1402          (match_operand 1 "" ""))
1403    (use (reg:SI 54))
1404    (clobber (reg:SI 55))]
1405   ""
1406   "@
1407    jalr\t%r0
1408    jal\t%p0"
1409   [(set_attr "type" "X1,X1")])
1411 (define_expand "call_value"
1412   [(parallel [(set (match_operand 0 "register_operand" "")
1413                    (call (match_operand:SI 1 "call_operand" "")
1414                          (match_operand 2 "" "")))
1415               (use (reg:SI 54))
1416               (clobber (reg:SI 55))])]
1417   "")
1419 (define_insn "*call_value_insn"
1420   [(set (match_operand 0 "register_operand" "=r,r")
1421         (call (mem:SI (match_operand:SI 1 "call_address_operand" "rO,i"))
1422               (match_operand 2 "" "")))
1423    (use (reg:SI 54))
1424    (clobber (reg:SI 55))]
1425   ""
1426   "@
1427    jalr\t%r1
1428    jal\t%p1"
1429   [(set_attr "type" "X1,X1")])
1431 (define_expand "sibcall"
1432   [(parallel [(call (match_operand:SI 0 "call_operand" "")
1433                     (match_operand 1 "" ""))
1434               (use (reg:SI 54))])]
1435   ""
1436   "")
1438 (define_insn "*sibcall_insn"
1439   [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rO,i"))
1440          (match_operand 1 "" ""))
1441    (use (reg:SI 54))]
1442   "SIBLING_CALL_P(insn)"
1443   "@
1444    jr\t%r0
1445    j\t%p0"
1446   [(set_attr "type" "X1,X1")])
1448 (define_expand "sibcall_value"
1449   [(parallel [(set (match_operand 0 "" "")
1450                    (call (match_operand:SI 1 "call_operand" "")
1451                          (match_operand:SI 2 "" "")))
1452               (use (reg:SI 54))])]
1453   ""
1454   "")
1456 (define_insn "*sibcall_value"
1457   [(set (match_operand 0 "" "")
1458         (call (mem:SI (match_operand:SI 1 "call_address_operand" "rO,i"))
1459               (match_operand:SI 2 "" "")))
1460    (use (reg:SI 54))]
1461   "SIBLING_CALL_P(insn)"
1462   "@
1463    jr\t%r1
1464    j\t%p1"
1465   [(set_attr "type" "X1,X1")])
1467 (define_insn "jump"
1468   [(set (pc) (label_ref (match_operand 0 "" "")))]
1469   ""
1470   "j\t%l0"
1471   [(set_attr "type" "X1")])
1473 (define_insn "indirect_jump"
1474   [(set (pc) (match_operand:SI 0 "register_operand" "rO"))]
1475   ""
1476   "jr\t%r0"
1477   [(set_attr "type" "X1")])
1479 (define_expand "return"
1480   [(parallel
1481     [(return)
1482      (use (reg:SI 55))])]
1483   "tilepro_can_use_return_insn_p ()"
1484   "")
1486 (define_insn "_return"
1487   [(return)
1488    (use (reg:SI 55))]
1489   "reload_completed"
1490   "jrp\tlr"
1491   [(set_attr "type" "X1")])
1493 (define_expand "tablejump"
1494   [(set (pc) (match_operand:SI 0 "register_operand" ""))
1495    (use (label_ref (match_operand 1 "" "")))]
1496   ""
1498   tilepro_expand_tablejump (operands[0], operands[1]);
1499   DONE;
1502 (define_insn "tablejump_aux"
1503   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1504    (use (label_ref (match_operand 1 "" "")))]
1505   ""
1506   "jr\t%0"
1507   [(set_attr "type" "X1")])
1509 ;; Call subroutine returning any type.
1510 (define_expand "untyped_call"
1511   [(parallel [(call (match_operand 0 "" "")
1512                     (const_int 0))
1513               (match_operand 1 "" "")
1514               (match_operand 2 "" "")])]
1515   ""
1517   int i;
1519   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
1521   for (i = 0; i < XVECLEN (operands[2], 0); i++)
1522     {
1523       rtx set = XVECEXP (operands[2], 0, i);
1524       emit_move_insn (SET_DEST (set), SET_SRC (set));
1525     }
1527   /* The optimizer does not know that the call sets the function value
1528      registers we stored in the result block.  We avoid problems by
1529      claiming that all hard registers are used and clobbered at this
1530      point.  */
1531   emit_insn (gen_blockage ());
1533   DONE;
1536 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers
1537 ;; and all of memory.  This blocks insns from being moved across this
1538 ;; point.
1539 (define_insn "blockage"
1540   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
1541   ""
1542   "pseudo"
1543   [(set_attr "type" "nothing")
1544    (set_attr "length" "0")])
1546 ;; Internal expanders to prevent memory ops from moving around frame
1547 ;; allocation/deallocation.
1549 ;; TODO: really this clobber should just clobber the frame memory.  Is
1550 ;; this possibly by clobbering memory @ the sp reg (as alpha does?)
1551 ;; or by explicitly setting the alias set to the frame?
1552 (define_insn "sp_adjust"
1553   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1554         (plus:SI
1555          (match_operand:SI 1 "register_operand" "%r,r,r")
1556          (match_operand:SI 2 "add_operand" "r,I,J")))
1557    (clobber (mem:BLK (scratch)))]
1558  ""
1559  "@
1560   add\t%0, %1, %2
1561   addi\t%0, %1, %2
1562   addli\t%0, %1, %2"
1563  [(set_attr "type" "*,*,X01")])
1565 ;; Used for move sp, r52, to pop a stack frame.  We need to make sure
1566 ;; that stack frame memory operations have been issued before we do
1567 ;; this.  TODO: see above TODO.
1568 (define_insn "sp_restore"
1569   [(set (match_operand:SI 0 "register_operand" "=r")
1570         (match_operand:SI 1 "register_operand" "r"))
1571    (clobber (mem:BLK (scratch)))]
1572  ""
1573  "move\t%0, %1")
1575 (define_insn "nop"
1576   [(const_int 0)]
1577   ""
1578   "nop"
1579   [(set_attr "type" "Y01")])
1583 ;; Conditional branches
1586 (define_expand "cbranchsi4"
1587   [(set (pc)
1588         (if_then_else (match_operator 0 "ordered_comparison_operator"
1589                        [(match_operand:SI 1 "reg_or_cint_operand")
1590                         (match_operand:SI 2 "reg_or_cint_operand")])
1591                       (label_ref (match_operand 3 ""))
1592                       (pc)))]
1593   ""
1594   { tilepro_emit_conditional_branch (operands, SImode); DONE; })
1597 (define_expand "cbranchdi4"
1598   [(set (pc)
1599         (if_then_else (match_operator 0 "ordered_comparison_operator"
1600                        [(match_operand:DI 1 "reg_or_cint_operand")
1601                         (match_operand:DI 2 "reg_or_cint_operand")])
1602                       (label_ref (match_operand 3 ""))
1603                       (pc)))]
1604   ""
1605   { tilepro_emit_conditional_branch (operands, DImode); DONE; })
1606   
1608 (define_insn "*bcc_normal"
1609   [(set (pc)
1610         (if_then_else
1611          (match_operator 1 "signed_comparison_operator"
1612                          [(match_operand:SI 2 "reg_or_0_operand" "rO")
1613                           (const_int 0)])
1614          (label_ref (match_operand 0 "" ""))
1615          (pc)))]
1616   ""
1617   { return tilepro_output_cbranch (insn, operands, false); }
1618   [(set_attr "type" "X1_branch")])
1620 (define_insn "*bcc_reverse"
1621   [(set (pc)
1622         (if_then_else
1623          (match_operator 1 "signed_comparison_operator"
1624                          [(match_operand:SI 2 "reg_or_0_operand" "rO")
1625                           (const_int 0)])
1626          (pc)
1627          (label_ref (match_operand 0 "" ""))))]
1628   ""
1629   { return tilepro_output_cbranch (insn, operands, true); }
1630   [(set_attr "type" "X1_branch")])
1632 ;; FIXME: the straight forward versions which do not include the
1633 ;; subreg:QI does not match for some unknown reason.
1634 (define_insn "*bbs_normal"
1635   [(set (pc)
1636         (if_then_else
1637          (ne (zero_extract:SI (subreg:QI 
1638                                (match_operand:SI 1 "reg_or_0_operand" "rO") 0)
1639                               (const_int 1)
1640                               (const_int 0))
1641              (const_int 0))
1642          (label_ref (match_operand 0 "" ""))
1643          (pc)))]
1644   ""
1645   { return tilepro_output_cbranch_with_opcode (insn, operands, "bbs", "bbns",
1646                                             1, 0); }
1647   [(set_attr "type" "X1_branch")])
1649 (define_insn "*bbc_normal"
1650   [(set (pc)
1651         (if_then_else
1652          (eq (zero_extract:SI (subreg:QI
1653                                (match_operand:SI 1 "reg_or_0_operand" "rO") 0)
1654                               (const_int 1)
1655                               (const_int 0))
1656              (const_int 0))
1657          (label_ref (match_operand 0 "" ""))
1658          (pc)))]
1659   ""
1660   { return tilepro_output_cbranch_with_opcode (insn, operands, "bbns", "bbs",
1661                                             1, 0); }
1662   [(set_attr "type" "X1_branch")])
1664 ;; Note that __insn_mf() expands to this.
1665 (define_expand "memory_barrier"
1666   [(set (match_dup 0)
1667         (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
1668   ""
1670   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
1671   MEM_VOLATILE_P (operands[0]) = 1;
1674 (define_insn "*memory_barrier"
1675   [(set (match_operand:BLK 0 "" "")
1676         (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
1677   ""
1678   "mf"
1679   [(set_attr "type" "X1")])
1681 (define_insn "prefetch"
1682   [(prefetch (match_operand:SI 0 "address_operand" "rO")
1683              (match_operand:SI 1 "const_int_operand" "")
1684              (match_operand:SI 2 "const_int_operand" ""))]
1685   ""
1686   "prefetch\t%r0"
1687   [(set_attr "type" "Y2")])
1691 ;; Network intrinsics
1694 ;; Note the "pseudo" text is handled specially by the
1695 ;; asm_output_opcode routine.  If the output is an empty string, the
1696 ;; instruction would bypass the asm_output_opcode routine, bypassing
1697 ;; the bundle handling code.
1698 (define_insn "tilepro_network_barrier"
1699   [(unspec_volatile:SI [(const_int 0)] UNSPEC_NETWORK_BARRIER)]
1700   ""
1701   "pseudo"
1702   [(set_attr "type" "nothing")
1703    (set_attr "length" "0")])
1705 (define_insn "*netreg_receive"
1706   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,U,m")
1707         (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i")
1708                              (reg:SI TILEPRO_NETORDER_REG)]
1709                             UNSPEC_NETWORK_RECEIVE))
1710    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1711   ""
1712   "@
1713    move\t%0, %N1
1714    sw\t%0, %N1
1715    swadd\t%I0, %N1, %i0"
1716   [(set_attr "type" "*,Y2,X1")])
1717   
1718 (define_insn "*netreg_send"
1719   [(unspec_volatile:SI
1720     [(match_operand:SI 0 "netreg_operand" "i,i,i,i,i,i")
1721      (match_operand:SI 1 "reg_or_cint_operand" "rO,I,J,K,N,P")
1722      (reg:SI TILEPRO_NETORDER_REG)]
1723     UNSPEC_NETWORK_SEND)
1724    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1725   ""
1726   "@
1727    move\t%N0, %r1
1728    movei\t%N0, %1
1729    moveli\t%N0, %1
1730    auli\t%N0, zero, %h1
1731    addib\t%N0, zero, %j1
1732    addih\t%N0, zero, %h1"
1733   [(set_attr "type" "*,*,X01,X01,X01,X01")])
1735 (define_insn "*netreg_copy"
1736   [(unspec_volatile:SI
1737     [(match_operand:SI 0 "netreg_operand" "i")
1738      (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
1739                           (reg:SI TILEPRO_NETORDER_REG)]
1740                          UNSPEC_NETWORK_RECEIVE)
1741      (reg:SI TILEPRO_NETORDER_REG)]
1742     UNSPEC_NETWORK_SEND)
1743    (clobber (reg:SI TILEPRO_NETORDER_REG))
1744    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1745   ""
1746   "move %N0, %N1")
1748 (define_expand "tilepro_idn0_receive"
1749   [(parallel
1750     [(set (match_operand:SI 0 "register_operand" "")
1751           (unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN0)
1752                                (reg:SI TILEPRO_NETORDER_REG)]
1753                               UNSPEC_NETWORK_RECEIVE))
1754      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1755   "")
1757 (define_expand "tilepro_idn1_receive"
1758   [(parallel
1759     [(set (match_operand:SI 0 "register_operand" "")
1760           (unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN1)
1761                                (reg:SI TILEPRO_NETORDER_REG)]
1762                               UNSPEC_NETWORK_RECEIVE))
1763      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1764   "")
1766 (define_expand "tilepro_idn_send"
1767   [(parallel
1768     [(unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN0)
1769                           (match_operand:SI 0 "reg_or_cint_operand" "")
1770                           (reg:SI TILEPRO_NETORDER_REG)]
1771                          UNSPEC_NETWORK_SEND)
1772      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1773   "")
1775 (define_expand "tilepro_sn_receive"
1776   [(parallel
1777     [(set (match_operand:SI 0 "register_operand" "")
1778           (unspec_volatile:SI [(const_int TILEPRO_NETREG_SN)
1779                                (reg:SI TILEPRO_NETORDER_REG)]
1780                               UNSPEC_NETWORK_RECEIVE))
1781      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1782   "")
1784 (define_expand "tilepro_sn_send"
1785   [(parallel
1786     [(unspec_volatile:SI [(const_int TILEPRO_NETREG_SN)
1787                           (match_operand:SI 0 "reg_or_cint_operand" "")
1788                           (reg:SI TILEPRO_NETORDER_REG)]
1789                          UNSPEC_NETWORK_SEND)
1790      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1791   "")
1793 (define_expand "tilepro_udn0_receive"
1794   [(parallel
1795     [(set (match_operand:SI 0 "register_operand" "")
1796           (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN0)
1797                                (reg:SI TILEPRO_NETORDER_REG)]
1798                               UNSPEC_NETWORK_RECEIVE))
1799      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1800   "")
1802 (define_expand "tilepro_udn1_receive"
1803   [(parallel
1804     [(set (match_operand:SI 0 "register_operand" "")
1805           (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN1)
1806                                (reg:SI TILEPRO_NETORDER_REG)]
1807                               UNSPEC_NETWORK_RECEIVE))
1808      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1809   "")
1811 (define_expand "tilepro_udn2_receive"
1812   [(parallel
1813     [(set (match_operand:SI 0 "register_operand" "")
1814           (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN2)
1815                                (reg:SI TILEPRO_NETORDER_REG)]
1816                               UNSPEC_NETWORK_RECEIVE))
1817      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1818   "")
1820 (define_expand "tilepro_udn3_receive"
1821   [(parallel
1822     [(set (match_operand:SI 0 "register_operand" "")
1823           (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN3)
1824                                (reg:SI TILEPRO_NETORDER_REG)]
1825                               UNSPEC_NETWORK_RECEIVE))
1826      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1827   "")
1829 (define_expand "tilepro_udn_send"
1830   [(parallel
1831     [(unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN0)
1832                           (match_operand:SI 0 "reg_or_cint_operand" "")
1833                           (reg:SI TILEPRO_NETORDER_REG)]
1834                          UNSPEC_NETWORK_SEND)
1835      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1836   "")
1838 (define_insn "*netreg_add_to_network"
1839   [(unspec_volatile:SI
1840     [(match_operand:SI 0 "netreg_operand" "i,i,i,i")
1841      (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO,rO")
1842               (match_operand:SI 2 "add_operand" "r,I,J,K"))
1843      (reg:SI TILEPRO_NETORDER_REG)]
1844     UNSPEC_NETWORK_SEND)
1845    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1846   ""
1847   "@
1848    add\t%N0, %r1, %2
1849    addi\t%N0, %r1, %2
1850    addli\t%N0, %r1, %2
1851    auli\t%N0, %r1, %h2"
1852   [(set_attr "type" "*,*,X01,X01")])
1854 (define_insn "*netreg_add_from_network"
1855   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1856         (plus:SI
1857          (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i,i")
1858                               (reg:SI TILEPRO_NETORDER_REG)]
1859                              UNSPEC_NETWORK_RECEIVE)
1860          (match_operand:SI 2 "add_operand" "rO,I,J,K")))
1861    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1862   ""
1863   "@
1864    add\t%0, %N1, %r2
1865    addi\t%0, %N1, %2
1866    addli\t%0, %N1, %2
1867    auli\t%0, %N1, %h2"
1868   [(set_attr "type" "*,*,X01,X01")])
1870 (define_insn "*netreg_add_from_to_network"
1871   [(unspec_volatile:SI
1872     [(match_operand:SI 0 "netreg_operand" "i,i,i,i")
1873      (plus:SI
1874       (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i,i")
1875                            (reg:SI TILEPRO_NETORDER_REG)]
1876                           UNSPEC_NETWORK_RECEIVE)
1877       (match_operand:SI 2 "add_operand" "rO,I,J,K"))
1878      (reg:SI TILEPRO_NETORDER_REG)]
1879     UNSPEC_NETWORK_SEND)
1880    (clobber (reg:SI TILEPRO_NETORDER_REG))
1881    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1882   ""
1883   "@
1884    add\t%N0, %N1, %r2
1885    addi\t%N0, %N1, %2
1886    addli\t%N0, %N1, %2
1887    auli\t%N0, %N1, %h2"
1888   [(set_attr "type" "*,*,X01,X01")])
1890 (define_code_iterator netreg_binop
1891   [minus])
1893 (define_insn "*netreg_binop_to_network"
1894   [(unspec_volatile:SI
1895     [(match_operand:SI 0 "netreg_operand" "i")
1896     (netreg_binop:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1897                      (match_operand:SI 2 "reg_or_0_operand" "rO"))
1898     (reg:SI TILEPRO_NETORDER_REG)]
1899     UNSPEC_NETWORK_SEND)
1900    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1901   ""
1902   "<insn>\t%N0, %r1, %r2")
1904 (define_insn "*netreg_binop_from_network0"
1905   [(set (match_operand:SI 0 "register_operand" "=r")
1906         (netreg_binop:SI
1907          (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
1908                               (reg:SI TILEPRO_NETORDER_REG)]
1909                              UNSPEC_NETWORK_RECEIVE)
1910          (match_operand:SI 2 "reg_or_0_operand" "rO")))
1911    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1912   ""
1913   "<insn>\t%0, %N1, %r2")
1915 (define_insn "*netreg_binop_from_network1"
1916   [(set (match_operand:SI 0 "register_operand" "=r")
1917         (netreg_binop:SI
1918          (match_operand:SI 1 "reg_or_0_operand" "rO")
1919          (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
1920                               (reg:SI TILEPRO_NETORDER_REG)]
1921                              UNSPEC_NETWORK_RECEIVE)))
1922    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1923   ""
1924   "<insn>\t%0, %r1, %N2")
1926 (define_insn "*netreg_binop_from_to_network0"
1927   [(unspec_volatile:SI
1928     [(match_operand:SI 0 "netreg_operand" "i")
1929      (netreg_binop:SI
1930       (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
1931                            (reg:SI TILEPRO_NETORDER_REG)]
1932                           UNSPEC_NETWORK_RECEIVE)
1933       (match_operand:SI 2 "reg_or_0_operand" "rO"))
1934      (reg:SI TILEPRO_NETORDER_REG)]
1935     UNSPEC_NETWORK_SEND)
1936    (clobber (reg:SI TILEPRO_NETORDER_REG))
1937    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1938   ""
1939   "<insn>\t%N0, %N1, %r2")
1941 (define_insn "*netreg_binop_from_to_network1"
1942   [(unspec_volatile:SI
1943     [(match_operand:SI 0 "netreg_operand" "i")
1944      (netreg_binop:SI
1945       (match_operand:SI 1 "reg_or_0_operand" "rO")
1946       (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
1947                            (reg:SI TILEPRO_NETORDER_REG)]
1948                           UNSPEC_NETWORK_RECEIVE))
1949      (reg:SI TILEPRO_NETORDER_REG)]
1950     UNSPEC_NETWORK_SEND)
1951    (clobber (reg:SI TILEPRO_NETORDER_REG))
1952    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1953   ""
1954   "<insn>\t%N0, %r1, %N2")
1956 (define_insn "*netreg_binop_to_network"
1957   [(unspec_volatile:SI
1958     [(match_operand:SI 0 "netreg_operand" "i,i")
1959      (binop_with_imm:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1960                         (match_operand:SI 2 "reg_or_cint_operand" "I,rO"))
1961      (reg:SI TILEPRO_NETORDER_REG)]
1962     UNSPEC_NETWORK_SEND)
1963    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1964   ""
1965   "@
1966    <insn>i<u>\t%N0, %r1, %2
1967    <insn><u>\t%N0, %r1, %r2")
1969 (define_insn "*netreg_binop_from_network"
1970   [(set (match_operand:SI 0 "register_operand" "=r,r")
1971         (binop_with_imm:SI
1972          (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i")
1973                               (reg:SI TILEPRO_NETORDER_REG)]
1974                              UNSPEC_NETWORK_RECEIVE)
1975          (match_operand:SI 2 "reg_or_cint_operand" "I,rO")))
1976    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1977   ""
1978   "@
1979    <insn>i<u>\t%0, %N1, %2
1980    <insn><u>\t%0, %N1, %r2")
1982 (define_insn "*netreg_binop_from_to_network"
1983   [(unspec_volatile:SI
1984     [(match_operand:SI 0 "netreg_operand" "i,i")
1985      (binop_with_imm:SI
1986       (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i")
1987                            (reg:SI TILEPRO_NETORDER_REG)]
1988                           UNSPEC_NETWORK_RECEIVE)
1989       (match_operand:SI 2 "reg_or_cint_operand" "I,rO"))
1990      (reg:SI TILEPRO_NETORDER_REG)]
1991     UNSPEC_NETWORK_SEND)
1992    (clobber (reg:SI TILEPRO_NETORDER_REG))
1993    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1994   ""
1995   "@
1996    <insn>i<u>\t%N0, %N1, %2
1997    <insn><u>\t%N0, %N1, %r2")
1999 (define_insn "*netreg_unop_to_network"
2000   [(unspec_volatile:SI [(match_operand:SI 0 "netreg_operand" "i")
2001                         (unop:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))
2002                         (reg:SI TILEPRO_NETORDER_REG)]
2003                        UNSPEC_NETWORK_SEND)
2004    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2005   ""
2006   "<insn>\t%N0, %r1"
2007   [(set_attr "type" "Y0")])
2009 (define_insn "*netreg_unop_from_network"
2010   [(set (match_operand:SI 0 "register_operand" "=r")
2011         (unop:SI
2012          (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2013                               (reg:SI TILEPRO_NETORDER_REG)]
2014                              UNSPEC_NETWORK_RECEIVE)))
2015    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2016   ""
2017   "<insn>\t%0, %N1"
2018   [(set_attr "type" "Y0")])
2020 (define_insn "*netreg_unop_from_to_network"
2021   [(unspec_volatile:SI
2022     [(match_operand:SI 0 "netreg_operand" "i")
2023      (unop:SI
2024       (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2025                            (reg:SI TILEPRO_NETORDER_REG)]
2026                           UNSPEC_NETWORK_RECEIVE))
2027      (reg:SI TILEPRO_NETORDER_REG)]
2028     UNSPEC_NETWORK_SEND)
2029    (clobber (reg:SI TILEPRO_NETORDER_REG))
2030    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2031   ""
2032   "<insn>\t%N0, %N1"
2033   [(set_attr "type" "Y0")])
2035 (define_insn "*netreg_sadh_u_from_network0"
2036   [(set (match_operand:SI 0 "register_operand" "=r")
2037         (unspec:SI
2038          [(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2039                                (reg:SI TILEPRO_NETORDER_REG)]
2040                               UNSPEC_NETWORK_RECEIVE)
2041           (match_operand:SI 2 "reg_or_0_operand" "rO")]
2042          UNSPEC_INSN_SADH_U))
2043    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2044   ""
2045   "sadh_u\t%0, %N1, %r2"
2046   [(set_attr "type" "X0_2cycle")])
2048 (define_insn "*netreg_sadh_u_from_network1"
2049   [(set (match_operand:SI 0 "register_operand" "=r")
2050         (unspec:SI
2051          [(match_operand:SI 1 "reg_or_0_operand" "rO")
2052           (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
2053                                (reg:SI TILEPRO_NETORDER_REG)]
2054                               UNSPEC_NETWORK_RECEIVE)]
2055          UNSPEC_INSN_SADH_U))
2056    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2057   ""
2058   "sadh_u\t%0, %r1, %N2"
2059   [(set_attr "type" "X0_2cycle")])
2061 (define_insn "*netreg_sadah_u_from_network0"
2062   [(set (match_operand:SI 0 "register_operand" "=r")
2063         (unspec:SI
2064          [(match_operand:SI 1 "reg_or_0_operand" "0")
2065           (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
2066                                (reg:SI TILEPRO_NETORDER_REG)]
2067                               UNSPEC_NETWORK_RECEIVE)
2068           (match_operand:SI 3 "reg_or_0_operand" "rO")]
2069          UNSPEC_INSN_SADAH_U))
2070    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2071   ""
2072   "sadah_u\t%0, %N2, %r3"
2073   [(set_attr "type" "X0_2cycle")])
2075 (define_insn "*netreg_sadah_u_from_network1"
2076   [(set (match_operand:SI 0 "register_operand" "=r")
2077         (unspec:SI
2078          [(match_operand:SI 1 "reg_or_0_operand" "0")
2079           (match_operand:SI 2 "reg_or_0_operand" "rO")
2080           (unspec_volatile:SI [(match_operand:SI 3 "netreg_operand" "i")
2081                                (reg:SI TILEPRO_NETORDER_REG)]
2082                               UNSPEC_NETWORK_RECEIVE)]
2083          UNSPEC_INSN_SADAH_U))
2084    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2085   ""
2086   "sadah_u\t%0, %r2, %N3"
2087   [(set_attr "type" "X0_2cycle")])
2089 (define_code_iterator mm_combiner [ior xor plus])
2091 ;; This doesn't seem to match -- too complex for 'combine'?
2093 ;; (define_insn "*netreg_mm_to_network"
2094 ;;   [(unspec_volatile:SI
2095 ;;     [(match_operand:SI 0 "netreg_operand" "i")
2096 ;;      (mm_combiner:SI
2097 ;;       (and:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2098 ;;               (match_operand:SI 3 "const_int_operand" "n"))
2099 ;;       (and:SI (match_operand:SI 2 "reg_or_0_operand" "rO")
2100 ;;               (match_operand:SI 4 "const_int_operand" "n")))]
2101 ;;     UNSPEC_NETWORK_SEND)]
2102 ;;   "tilepro_bitfield_operand_p (INTVAL (operands[3]), NULL, NULL)
2103 ;;    && INTVAL (operands[3]) == ~INTVAL (operands[4])"
2104 ;;   "mm\t%N0, %r1, %r2, %M3"
2105 ;;   [(set_attr "type" "X01")])
2107 ;; FIXME: the straight forward versions which do not include the
2108 ;; subreg:QI does not match for some unknown reason.
2109 (define_insn "*netreg_bbs_normal"
2110   [(set (pc)
2111         (if_then_else
2112          (ne (zero_extract:SI
2113               (subreg:QI 
2114                (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2115                                     (reg:SI TILEPRO_NETORDER_REG)]
2116                                    UNSPEC_NETWORK_RECEIVE) 0)
2117               (const_int 1)
2118               (const_int 0))
2119              (const_int 0))
2120          (label_ref (match_operand 0 "" ""))
2121          (pc)))
2122    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2123   ""
2124   { return tilepro_output_cbranch_with_opcode (insn, operands, "bbs", "bbns",
2125                                             1, 1); }
2126   [(set_attr "type" "X1_branch")])
2128 (define_insn "*netreg_bbc_normal"
2129   [(set (pc)
2130         (if_then_else
2131          (eq (zero_extract:SI
2132               (subreg:QI 
2133                (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2134                                     (reg:SI TILEPRO_NETORDER_REG)]
2135                                    UNSPEC_NETWORK_RECEIVE) 0)
2136               (const_int 1)
2137               (const_int 0))
2138              (const_int 0))
2139          (label_ref (match_operand 0 "" ""))
2140          (pc)))
2141    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2142   ""
2143   { return tilepro_output_cbranch_with_opcode (insn, operands, "bbns", "bbns",
2144                                             1, 1); }
2145   [(set_attr "type" "X1_branch")])
2149 ;; "__insn" Intrinsics (some expand directly to normal patterns above).
2152 (define_insn "insn_addlis"
2153   [(set (match_operand:SI 0 "register_operand" "=r")
2154         (unspec_volatile:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
2155                              (match_operand:SI 2 "s16bit_cint_operand" "i")] 
2156                             UNSPEC_INSN_ADDLIS))]
2157   ""
2158   "addlis\t%0, %r1, %2"
2159   [(set_attr "type" "X01")])
2161 (define_insn "insn_auli"
2162   [(set (match_operand:SI 0 "register_operand" "=r")
2163         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
2164                     (match_operand:SI 2 "s16bit_cint_operand" "i")] 
2165                    UNSPEC_INSN_AULI))]
2166   ""
2167   "auli\t%0, %r1, %2"
2168   [(set_attr "type" "X01")])
2170 (define_insn "insn_drain"
2171   [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_DRAIN)]
2172   ""
2173   "drain"
2174   [(set_attr "type" "cannot_bundle")])
2176 (define_insn "insn_icoh"
2177   [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] 
2178                          UNSPEC_INSN_ICOH)]
2179   ""
2180   "icoh\t%r0"
2181   [(set_attr "type" "X1")])
2184 (define_insn "insn_info"
2185   [(unspec_volatile:VOID [(match_operand:SI 0 "s8bit_cint_operand" "i")] 
2186                          UNSPEC_INSN_INFO)]
2187   ""
2188   "info\t%0")
2190 (define_insn "insn_infol"
2191   [(unspec_volatile:VOID [(match_operand:SI 0 "s16bit_cint_operand" "i")] 
2192                          UNSPEC_INSN_INFOL)]
2193   ""
2194   "infol\t%0"
2195   [(set_attr "type" "X01")])
2197 ;; loads
2199 (define_expand "insn_<load>"
2200   [(set (match_operand:SI 0 "register_operand" "")
2201         (sign_extend:SI
2202          (mem:I12MODE (match_operand:SI 1 "address_operand" ""))))]
2203   "")
2205 (define_expand "insn_<load>_u"
2206   [(set (match_operand:SI 0 "register_operand" "")
2207         (zero_extend:SI
2208          (mem:I12MODE (match_operand:SI 1 "address_operand" ""))))]
2209   "")
2211 (define_insn "insn_<load>add"
2212   [(set (match_operand:SI 1 "register_operand" "=r")
2213         (plus:SI (match_operand:SI 3 "register_operand" "1")
2214                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2215    (set (match_operand:SI 0 "register_operand" "=r")
2216         (sign_extend:SI (mem:I12MODE (match_dup 3))))]
2217   ""
2218   "<load>add\t%0, %1, %2"
2219   [(set_attr "type" "X1_2cycle")])
2221 (define_insn "insn_<load>add_u"
2222   [(set (match_operand:SI 1 "register_operand" "=r")
2223         (plus:SI (match_operand:SI 3 "register_operand" "1")
2224                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2225    (set (match_operand:SI 0 "register_operand" "=r")
2226         (zero_extend:SI (mem:I12MODE (match_dup 3))))]
2227   ""
2228   "<load>add_u\t%0, %1, %2"
2229   [(set_attr "type" "X1_2cycle")])
2231 (define_expand "insn_lw"
2232   [(set (match_operand:SI 0 "register_operand" "")
2233         (mem:SI (match_operand:SI 1 "address_operand" "")))]
2234   "")
2236 (define_insn "insn_lwadd"
2237   [(set (match_operand:SI 1 "register_operand" "=r")
2238         (plus:SI (match_operand:SI 3 "register_operand" "1")
2239                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2240    (set (match_operand:SI 0 "register_operand" "=r")
2241         (mem:SI (match_dup 3)))]
2242   ""
2243   "lwadd\t%0, %1, %2"
2244   [(set_attr "type" "X1_2cycle")])
2246 (define_insn "insn_lwadd_na"
2247   [(set (match_operand:SI 1 "register_operand" "=r")
2248         (plus:SI (match_operand:SI 3 "register_operand" "1")
2249                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2250    (set (match_operand:SI 0 "register_operand" "=r")
2251         (mem:SI (and:SI (match_dup 3) (const_int -4))))]
2252   ""
2253   "lwadd_na\t%0, %1, %2"
2254   [(set_attr "type" "X1_2cycle")])
2256 (define_insn "insn_lw_na"
2257   [(set (match_operand:SI 0 "register_operand" "=r")
2258         (mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO")
2259                         (const_int -4))))]
2260   ""
2261   "lw_na\t%0, %r1"
2262   [(set_attr "type" "X1_2cycle")])
2264 ;; L2 hits
2266 (define_insn "insn_<load>_L2"
2267   [(set (match_operand:SI 0 "register_operand" "=r")
2268         (sign_extend:SI
2269          (unspec:I12MODE
2270           [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
2271           UNSPEC_LATENCY_L2)))]
2272   ""
2273   "<load>\t%0, %r1"
2274   [(set_attr "type" "Y2_L2")])
2276 (define_insn "insn_<load>_u_L2"
2277   [(set (match_operand:SI 0 "register_operand" "=r")
2278         (zero_extend:SI
2279          (unspec:I12MODE
2280           [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
2281           UNSPEC_LATENCY_L2)))]
2282   ""
2283   "<load>_u\t%0, %r1"
2284   [(set_attr "type" "Y2_L2")])
2286 (define_insn "insn_<load>add_L2"
2287   [(set (match_operand:SI 1 "register_operand" "=r")
2288         (plus:SI (match_operand:SI 3 "register_operand" "1")
2289                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2290    (set (match_operand:SI 0 "register_operand" "=r")
2291         (sign_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
2292                                         UNSPEC_LATENCY_L2)))]
2293   ""
2294   "<load>add\t%0, %1, %2"
2295   [(set_attr "type" "X1_L2")])
2297 (define_insn "insn_<load>add_u_L2"
2298   [(set (match_operand:SI 1 "register_operand" "=r")
2299         (plus:SI (match_operand:SI 3 "register_operand" "1")
2300                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2301    (set (match_operand:SI 0 "register_operand" "=r")
2302         (zero_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
2303                                         UNSPEC_LATENCY_L2)))]
2304   ""
2305   "<load>add_u\t%0, %1, %2"
2306   [(set_attr "type" "X1_L2")])
2308 (define_insn "insn_lwadd_L2"
2309   [(set (match_operand:SI 1 "register_operand" "=r")
2310         (plus:SI (match_operand:SI 3 "register_operand" "1")
2311                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2312    (set (match_operand:SI 0 "register_operand" "=r")
2313         (unspec:SI [(mem:SI (match_dup 3))] UNSPEC_LATENCY_L2))]
2314   ""
2315   "lwadd\t%0, %1, %2"
2316   [(set_attr "type" "X1_L2")])
2318 (define_insn "insn_lwadd_na_L2"
2319   [(set (match_operand:SI 1 "register_operand" "=r")
2320         (plus:SI (match_operand:SI 3 "register_operand" "1")
2321                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2322    (set (match_operand:SI 0 "register_operand" "=r")
2323         (unspec:SI [(mem:SI (and:SI (match_dup 3) (const_int -4)))]
2324                    UNSPEC_LATENCY_L2))]
2325   ""
2326   "lwadd_na\t%0, %1, %2"
2327   [(set_attr "type" "X1_L2")])
2329 (define_insn "insn_lw_na_L2"
2330   [(set (match_operand:SI 0 "register_operand" "=r")
2331         (unspec:SI [(mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO")
2332                                     (const_int -4)))]
2333                    UNSPEC_LATENCY_L2))]
2334   ""
2335   "lw_na\t%0, %r1"
2336   [(set_attr "type" "X1_L2")])
2338 (define_insn "insn_lw_L2"
2339   [(set (match_operand:SI 0 "register_operand" "=r")
2340         (unspec:SI [(mem:SI (match_operand:SI 1 "address_operand" "rO"))]
2341                    UNSPEC_LATENCY_L2))]
2342   ""
2343   "lw\t%0, %r1"
2344   [(set_attr "type" "Y2_L2")])
2346 ;; L2 miss
2348 (define_insn "insn_<load>_miss"
2349   [(set (match_operand:SI 0 "register_operand" "=r")
2350         (sign_extend:SI
2351          (unspec:I12MODE
2352           [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
2353           UNSPEC_LATENCY_MISS)))]
2354   ""
2355   "<load>\t%0, %r1"
2356   [(set_attr "type" "Y2_miss")])
2358 (define_insn "insn_<load>_u_miss"
2359   [(set (match_operand:SI 0 "register_operand" "=r")
2360         (zero_extend:SI
2361          (unspec:I12MODE
2362           [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
2363           UNSPEC_LATENCY_MISS)))]
2364   ""
2365   "<load>_u\t%0, %r1"
2366   [(set_attr "type" "Y2_miss")])
2368 (define_insn "insn_<load>add_miss"
2369   [(set (match_operand:SI 1 "register_operand" "=r")
2370         (plus:SI (match_operand:SI 3 "register_operand" "1")
2371                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2372    (set (match_operand:SI 0 "register_operand" "=r")
2373         (sign_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
2374                                         UNSPEC_LATENCY_MISS)))]
2375   ""
2376   "<load>add\t%0, %1, %2"
2377   [(set_attr "type" "X1_miss")])
2379 (define_insn "insn_<load>add_u_miss"
2380   [(set (match_operand:SI 1 "register_operand" "=r")
2381         (plus:SI (match_operand:SI 3 "register_operand" "1")
2382                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2383    (set (match_operand:SI 0 "register_operand" "=r")
2384         (zero_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
2385                                         UNSPEC_LATENCY_MISS)))]
2386   ""
2387   "<load>add_u\t%0, %1, %2"
2388   [(set_attr "type" "X1_miss")])
2390 (define_insn "insn_lwadd_miss"
2391   [(set (match_operand:SI 1 "register_operand" "=r")
2392         (plus:SI (match_operand:SI 3 "register_operand" "1")
2393                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2394    (set (match_operand:SI 0 "register_operand" "=r")
2395         (unspec:SI [(mem:SI (match_dup 3))] UNSPEC_LATENCY_MISS))]
2396   ""
2397   "lwadd\t%0, %1, %2"
2398   [(set_attr "type" "X1_miss")])
2400 (define_insn "insn_lwadd_na_miss"
2401   [(set (match_operand:SI 1 "register_operand" "=r")
2402         (plus:SI (match_operand:SI 3 "register_operand" "1")
2403                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2404    (set (match_operand:SI 0 "register_operand" "=r")
2405         (unspec:SI [(mem:SI (and:SI (match_dup 3) (const_int -4)))]
2406                    UNSPEC_LATENCY_MISS))]
2407   ""
2408   "lwadd_na\t%0, %1, %2"
2409   [(set_attr "type" "X1_miss")])
2411 (define_insn "insn_lw_na_miss"
2412   [(set (match_operand:SI 0 "register_operand" "=r")
2413         (unspec:SI [(mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO")
2414                                     (const_int -4)))]
2415                    UNSPEC_LATENCY_MISS))]
2416   ""
2417   "lw_na\t%0, %r1"
2418   [(set_attr "type" "X1_miss")])
2420 (define_insn "insn_lw_miss"
2421   [(set (match_operand:SI 0 "register_operand" "=r")
2422         (unspec:SI [(mem:SI (match_operand:SI 1 "address_operand" "rO"))]
2423                    UNSPEC_LATENCY_MISS))]
2424   ""
2425   "lw\t%0, %r1"
2426   [(set_attr "type" "Y2_miss")])
2428 ;; end loads
2430 (define_insn "insn_mfspr"
2431   [(set (match_operand:SI 0 "register_operand" "=r")
2432         (unspec_volatile:SI [(match_operand:SI 1 "u15bit_cint_operand" "i")]
2433                             UNSPEC_INSN_MFSPR))
2434    (clobber (mem:BLK (const_int 0)))]
2435   ""
2436   "mfspr\t%0, %1"
2437   [(set_attr "type" "X1")])
2439 (define_insn "*mm"
2440   [(set (match_operand:SI 0 "register_operand" "=r")
2441         (mm_combiner:SI
2442          (and:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2443                  (match_operand:SI 3 "const_int_operand" "n"))
2444          (and:SI (match_operand:SI 2 "reg_or_0_operand" "rO")
2445                  (match_operand:SI 4 "const_int_operand" "n"))))]
2446   "tilepro_bitfield_operand_p (INTVAL (operands[3]), NULL, NULL)
2447    && INTVAL (operands[3]) == ~INTVAL (operands[4])"
2448   "mm\t%0, %r1, %r2, %M3"
2449   [(set_attr "type" "X01")])
2451 (define_expand "insn_mm"
2452   [(set (match_operand:SI 0 "register_operand" "")
2453         (ior:SI
2454          (and:SI (match_operand:SI 1 "reg_or_cint_operand" "")
2455                  (match_operand:SI 3 "u5bit_cint_operand" ""))
2456          (and:SI (match_operand:SI 2 "reg_or_cint_operand" "")
2457                  (match_operand:SI 4 "u5bit_cint_operand" ""))))]
2458   ""
2460   int first, last, i;
2461   HOST_WIDE_INT mask;
2463   first = INTVAL (operands[3]) & 31;
2464   last = INTVAL (operands[4]) & 31;
2466   if (((last + 1) & 31) == first)
2467     {
2468       /* Handle pathological case of a mask that includes only the
2469          first operand. The reordering code below can't handle this. */
2470       emit_move_insn (operands[0], operands[1]);
2471       DONE;
2472     }
2474   /* Canonicalize order by putting constant second, if any. */
2475   if (CONST_INT_P (operands[1]))
2476     {
2477       int tmp_first;
2479       rtx tmp = operands[1];
2480       operands[1] = operands[2];
2481       operands[2] = tmp;
2483       /* Invert the bit range. */
2484       tmp_first = first;
2485       first = (last + 1) & 31;
2486       last = (tmp_first - 1) & 31;
2487     }
2489   /* Convert the first/last bit range into a bit mask. */
2490   mask = 0;
2492   for (i = first; ; i = (i + 1) & 31)
2493     {
2494       mask |= ((HOST_WIDE_INT)1) << i;
2495       if (i == last)
2496         break;
2497     }
2499   mask = trunc_int_for_mode (mask, SImode);
2501   operands[1] = force_reg (SImode, operands[1]);
2502   operands[3] = GEN_INT (mask);
2503   operands[4] = GEN_INT (~mask);
2505   if (CONST_INT_P (operands[2]))
2506     {
2507       HOST_WIDE_INT inserted_bits = INTVAL (operands[2]) & ~mask;
2509       if (inserted_bits == 0)
2510         {
2511           /* All inserted bits are zero. Use a bitwise AND. */
2512           emit_insn (gen_andsi3 (operands[0], operands[1], operands[3]));
2513           DONE;
2514         }
2515       else if (inserted_bits == ~mask)
2516         {
2517           /* All inserted bits are ones. Use a bitwise IOR if we can. */
2518           if (satisfies_constraint_I (operands[4]))
2519             {
2520               emit_insn (gen_iorsi3 (operands[0], operands[1], operands[4]));
2521               DONE;
2522             }
2524           /* Canonicalize to inserting -1 when setting all masked bits
2525              to 1, to facilitate CSE. */
2526           inserted_bits = -1;
2527         }
2529       /* Sign extend the inserted bits to make them easier to materialize
2530          in a register, but only if the inserted bits (~mask) do not already
2531          include the high bits. */
2532       if ((~mask & 0x80000000) == 0)
2533         {
2534           int shift = sizeof (HOST_WIDE_INT) * 8 - first;
2535           inserted_bits = (inserted_bits << shift) >> shift;
2536         }
2538       operands[2] = GEN_INT (inserted_bits);
2539     }
2541   operands[2] = force_reg (SImode, operands[2]);
2544 (define_insn "insn_movelis"
2545   [(set (match_operand:SI 0 "register_operand" "=r")
2546         (unspec_volatile:SI [(match_operand:SI 1 "s16bit_cint_operand" "i")] 
2547                             UNSPEC_INSN_MOVELIS))]
2548   ""
2549   "movelis\t%0, %1"
2550   [(set_attr "type" "X01")])
2552 (define_insn "insn_mtspr"
2553   [(unspec_volatile:SI [(match_operand:SI 0 "u15bit_cint_operand" "i")
2554                         (match_operand:SI 1 "reg_or_0_operand" "rO")]
2555                        UNSPEC_INSN_MTSPR)
2556    (clobber (mem:BLK (const_int 0)))]
2557   ""
2558   "mtspr\t%0, %r1"
2559   [(set_attr "type" "X1")])
2561 (define_expand "insn_prefetch"
2562   [(prefetch (match_operand:SI 0 "address_operand" "")
2563              (const_int 0)
2564              (const_int 2))])
2566 (define_expand "insn_prefetch_L1"
2567   [(use (match_operand:SI 0 "address_operand" ""))]
2568   ""
2570   /* Generate a volatile byte load to a dummy register. */
2571   rtx mem = gen_rtx_MEM (QImode, operands[0]);
2572   MEM_VOLATILE_P (mem) = 1;
2574   emit_insn (gen_zero_extendqisi2 (gen_reg_rtx (SImode), mem));
2575   DONE;
2578 (define_expand "insn_s1a"
2579   [(set (match_operand:SI 0 "register_operand" "")
2580         (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
2581                           (const_int 2))
2582                  (match_operand:SI 2 "reg_or_0_operand" "")))]
2583   "")
2585 (define_expand "insn_s2a"
2586   [(set (match_operand:SI 0 "register_operand" "")
2587         (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
2588                           (const_int 4))
2589                  (match_operand:SI 2 "reg_or_0_operand" "")))]
2590   "")
2592 (define_expand "insn_s3a"
2593   [(set (match_operand:SI 0 "register_operand" "")
2594         (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
2595                           (const_int 8))
2596                  (match_operand:SI 2 "reg_or_0_operand" "")))]
2597   "")
2599 (define_expand "insn_<store>"
2600   [(set (mem:I12MODE (match_operand:SI 0 "address_operand" ""))
2601         (match_operand:SI 1 "reg_or_0_operand" ""))]
2602   ""
2604   operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], SImode, 0);
2607 (define_expand "insn_sw"
2608   [(set (mem:SI (match_operand:SI 0 "address_operand" ""))
2609         (match_operand:SI 1 "reg_or_0_operand" ""))]
2610   "")
2612 (define_expand "insn_<store>add"
2613   [(parallel
2614     [(set (match_operand:SI 0 "register_operand" "")
2615           (plus:SI (match_operand:SI 3 "register_operand" "")
2616                    (match_operand:SI 2 "s8bit_cint_operand" "")))
2617      (set (mem:I12MODE (match_dup 3))
2618           (match_operand:SI 1 "reg_or_0_operand" ""))])]
2619   ""
2621   operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], SImode, 0);
2624 (define_insn "*insn_<store>add"
2625   [(set (match_operand:SI 0 "register_operand" "=r")
2626         (plus:SI (match_operand:SI 3 "register_operand" "0")
2627                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2628    (set (mem:I12MODE (match_dup 3))
2629         (match_operand:I12MODE 1 "reg_or_0_operand" "rO"))]
2630   ""
2631   "<store>add\t%0, %r1, %2"
2632   [(set_attr "type" "X1")])
2634 (define_insn "insn_swadd"
2635   [(set (match_operand:SI 0 "register_operand" "=r")
2636         (plus:SI (match_operand:SI 3 "register_operand" "0")
2637                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2638    (set (mem:SI (match_dup 3))
2639         (match_operand:SI 1 "reg_or_0_operand" "rO"))]
2640   ""
2641   "swadd\t%0, %r1, %2"
2642   [(set_attr "type" "X1")])
2644 (define_insn "insn_wh64"
2645   [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")]
2646                          UNSPEC_INSN_WH64)
2647    (clobber (mem:BLK (const_int 0)))]
2648   ""
2649   "wh64\t%r0"
2650   [(set_attr "type" "X1")])
2652 (define_insn "insn_tns"
2653   [(set (match_operand:SI 0 "register_operand" "=r")
2654         (mem:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))
2655    (set (mem:SI (match_dup 1)) (const_int 1))]
2656   ""
2657   "tns\t%0, %1"
2658   [(set_attr "type" "X1")])
2660 ;; insn_addb
2661 ;; insn_addib
2662 ;; insn_maxb_u
2663 ;; insn_maxib_u
2664 ;; insn_minb_u
2665 ;; insn_minib_u
2666 ;; insn_seqb
2667 ;; insn_seqib
2668 ;; insn_sltb
2669 ;; insn_sltib
2670 ;; insn_sltb_u
2671 ;; insn_sltib_u
2672 (define_insn "<optab>v4qi3"
2673   [(set (match_operand:V4QI 0 "register_operand" "=r,r")
2674         (v1op_immed:V4QI
2675          (match_operand:V4QI 1 "reg_or_0_operand" "<comm>rO,rO")
2676          (match_operand:V4QI 2 "reg_or_v4s8bit_operand" "W,rO")))]
2677   ""
2678   "@
2679    <insn>ib<u>\t%0, %r1, %j2
2680    <insn>b<u>\t%0, %r1, %r2"
2681   [(set_attr "type" "X01,X01")])
2683 (define_expand "insn_<insn>b<u>"
2684   [(set (match_operand:SI 0 "register_operand" "")
2685         (v1op_immed:V4QI
2686          (match_operand:SI 1 "reg_or_0_operand" "")
2687          (match_operand:SI 2 "reg_or_0_operand" "")))]
2688   ""
2690   tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
2691                                        V4QImode, operands[1], operands[2], true);
2692   DONE;
2695 (define_expand "insn_<insn>ib<u>"
2696   [(set (match_operand:SI 0 "register_operand" "")
2697         (v1op_immed:V4QI
2698          (match_operand:SI 1 "reg_or_0_operand" "")
2699          (match_operand:SI 2 "s8bit_cint_operand" "")))]
2700   ""
2702   /* Tile out immediate and expand to general case. */
2703   rtx n = tilepro_simd_int (operands[2], QImode);
2704   tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
2705                                        V4QImode, operands[1], n, true);
2706   DONE;
2709 ;; insn_shlb
2710 ;; insn_shlib
2711 ;; insn_shrb
2712 ;; insn_shrib
2713 ;; insn_srab
2714 ;; insn_sraib
2715 (define_insn "<optab>v4qi3"
2716   [(set (match_operand:V4QI 0 "register_operand" "=r,r")
2717         (any_shift:V4QI
2718          (match_operand:V4QI 1 "reg_or_0_operand" "rO,rO")
2719          (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
2720   ""
2721   "@
2722    <insn>ib<u>\t%0, %r1, %2
2723    <insn>b<u>\t%0, %r1, %r2"
2724   [(set_attr "type" "X01,X01")])
2726 (define_expand "insn_<insn>b<u>"
2727   [(set (match_operand:SI 0 "register_operand" "")
2728         (any_shift:V4QI
2729          (match_operand:SI 1 "reg_or_0_operand" "")
2730          (match_operand:SI 2 "reg_or_u5bit_operand" "")))]
2731   ""
2733   tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
2734                                     V4QImode, operands[1], operands[2], false);
2735   DONE;
2738 ;; insn_addh
2739 ;; insn_addih
2740 ;; insn_maxh
2741 ;; insn_maxih
2742 ;; insn_minh
2743 ;; insn_minih
2744 ;; insn_seqh
2745 ;; insn_seqih
2746 ;; insn_slth
2747 ;; insn_sltih
2748 ;; insn_slth_u
2749 ;; insn_sltih_u
2750 (define_insn "<optab>v2hi3"
2751   [(set (match_operand:V2HI 0 "register_operand" "=r,r")
2752         (v2op_immed:V2HI
2753          (match_operand:V2HI 1 "reg_or_0_operand" "<comm>rO,rO")
2754          (match_operand:V2HI 2 "reg_or_v2s8bit_operand" "Y,rO")))]
2755   ""
2756   "@
2757    <insn>ih<u>\t%0, %r1, %j2
2758    <insn>h<u>\t%0, %r1, %r2"
2759   [(set_attr "type" "X01,X01")])
2761 (define_expand "insn_<insn>h<u>"
2762   [(set (match_operand:SI 0 "register_operand" "")
2763         (v2op_immed:V2HI
2764          (match_operand:SI 1 "reg_or_0_operand" "")
2765          (match_operand:SI 2 "reg_or_0_operand" "")))]
2766   ""
2768   tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
2769                                        V2HImode, operands[1], operands[2], true);
2770   DONE;
2773 (define_expand "insn_<insn>ih<u>"
2774   [(set (match_operand:SI 0 "register_operand" "")
2775         (v2op_immed:V2HI
2776          (match_operand:SI 1 "reg_or_0_operand" "")
2777          (match_operand:SI 2 "s8bit_cint_operand" "")))]
2778   ""
2780   /* Tile out immediate and expand to general case. */
2781   rtx n = tilepro_simd_int (operands[2], HImode);
2782   tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
2783                                        V2HImode, operands[1], n, true);
2784   DONE;
2787 ;; insn_shlh
2788 ;; insn_shlih
2789 ;; insn_shrh
2790 ;; insn_shrih
2791 ;; insn_srah
2792 ;; insn_sraih
2793 (define_insn "<optab>v2hi3"
2794   [(set (match_operand:V2HI 0 "register_operand" "=r,r")
2795         (any_shift:V2HI
2796          (match_operand:V2HI 1 "reg_or_0_operand" "rO,rO")
2797          (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
2798   ""
2799   "@
2800    <insn>ih<u>\t%0, %r1, %2
2801    <insn>h<u>\t%0, %r1, %r2"
2802   [(set_attr "type" "X01,X01")])
2804 (define_expand "insn_<insn>h<u>"
2805   [(set (match_operand:SI 0 "register_operand" "")
2806         (any_shift:V2HI
2807          (match_operand:SI 1 "reg_or_0_operand" "")
2808          (match_operand:SI 2 "reg_or_0_operand" "")))]
2809   ""
2811   tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
2812                                        V2HImode, operands[1], operands[2], false);
2813   DONE;
2816 ;; insn_addbs_u
2817 ;; insn_subbs_u
2818 ;; insn_subb
2819 ;; insn_slteb
2820 ;; insn_slteb_u
2821 ;; insn_sneb
2822 (define_insn "<optab>v4qi3"
2823   [(set (match_operand:V4QI 0 "register_operand" "=r")
2824         (v1op:V4QI
2825          (match_operand:V4QI 1 "reg_or_0_operand" "<comm>rO")
2826          (match_operand:V4QI 2 "reg_or_0_operand" "rO")))]
2827   ""
2828   "<insn>b<u>\t%0, %r1, %r2"
2829   [(set_attr "type" "X01")])
2831 (define_expand "insn_<insn>b<u>"
2832   [(set (match_operand:SI 0 "register_operand" "")
2833         (v1op:V4QI
2834          (match_operand:SI 1 "reg_or_0_operand" "")
2835          (match_operand:SI 2 "reg_or_0_operand" "")))]
2836   ""
2838   tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
2839                                        V4QImode, operands[1], operands[2], true);
2840   DONE;
2843 ;; insn_addhs
2844 ;; insn_subhs
2845 ;; insn_subh
2846 ;; insn_slteh
2847 ;; insn_slteh_u
2848 ;; insn_sneh
2849 (define_insn "<optab>v2hi3"
2850   [(set (match_operand:V2HI 0 "register_operand" "=r")
2851         (v2op:V2HI
2852          (match_operand:V2HI 1 "reg_or_0_operand" "<comm>rO")
2853          (match_operand:V2HI 2 "reg_or_0_operand" "rO")))]
2854   ""
2855   "<insn>h<u>\t%0, %r1, %r2"
2856   [(set_attr "type" "X01")])
2858 (define_expand "insn_<insn>h<u>"
2859   [(set (match_operand:SI 0 "register_operand" "")
2860         (v2op:V2HI
2861          (match_operand:SI 1 "reg_or_0_operand" "")
2862          (match_operand:SI 2 "reg_or_0_operand" "")))]
2863   ""
2865   tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
2866                                        V2HImode, operands[1], operands[2], true);
2867   DONE;
2870 ;; insn_inthb
2872 ;; Byte ordering of these vectors is endian dependent.  We concat
2873 ;; right-to-left for little endian.  We concat and interleave in the
2874 ;; opposite way gcc's vector patterns work, so we need to reverse the
2875 ;; order of source operands.
2877 ;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
2878 ;; => {A3,A2,A1,A0,B3,B2,B1,B0}
2879 ;; => {A3,B3,A2,B2}
2880 (define_insn "vec_interleave_highv4qi"
2881   [(set (match_operand:V4QI 0 "register_operand" "=r")
2882         (vec_select:V4QI
2883          (vec_concat:V8QI (match_operand:V4QI 1 "reg_or_0_operand" "rO")
2884                           (match_operand:V4QI 2 "reg_or_0_operand" "rO"))
2885          (parallel [(const_int 2) (const_int 6)
2886                     (const_int 3) (const_int 7)])))]
2887   ""
2888   "inthb\t%0, %r2, %r1"
2889   [(set_attr "type" "X01")])
2891 (define_expand "insn_inthb"
2892   [(match_operand:SI 0 "register_operand" "")
2893    (match_operand:SI 1 "reg_or_0_operand" "")
2894    (match_operand:SI 2 "reg_or_0_operand" "")]
2895   ""
2897   /* Our instruction interleaves opposite of the way vec_interleave
2898      works, so we need to reverse the source operands.  */
2899   tilepro_expand_builtin_vector_binop (gen_vec_interleave_highv4qi, V4QImode,
2900                                        operands[0], V4QImode, operands[2],
2901                                        operands[1], true);
2902   DONE;
2905 ;; insn_intlb
2906 ;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
2907 ;; => {A3,A2,A1,A0,B3,B2,B1,B0}
2908 ;; => {A1,B1,A0,B0}
2909 (define_insn "vec_interleave_lowv4qi"
2910   [(set (match_operand:V4QI 0 "register_operand" "=r")
2911         (vec_select:V4QI
2912          (vec_concat:V8QI (match_operand:V4QI 1 "reg_or_0_operand" "rO")
2913                           (match_operand:V4QI 2 "reg_or_0_operand" "rO"))
2914          (parallel [(const_int 0) (const_int 4)
2915                     (const_int 1) (const_int 5)])))]
2916   ""
2917   "intlb\t%0, %r2, %r1"
2918   [(set_attr "type" "X01")])
2920 (define_expand "insn_intlb"
2921   [(match_operand:SI 0 "register_operand" "")
2922    (match_operand:SI 1 "reg_or_0_operand" "")
2923    (match_operand:SI 2 "reg_or_0_operand" "")]
2924   ""
2926   /* Our instruction interleaves opposite of the way vec_interleave
2927      works, so we need to reverse the source operands.  */
2928   tilepro_expand_builtin_vector_binop (gen_vec_interleave_lowv4qi, V4QImode,
2929                                        operands[0], V4QImode, operands[2],
2930                                        operands[1], true);
2931   DONE;
2934 ;; insn_inthh
2935 ;;    {B1,B0} {A1,A0}
2936 ;; => {A1,A0,B1,B0}
2937 ;; => {A1,B1}
2938 (define_insn "vec_interleave_highv2hi"
2939   [(set (match_operand:V2HI 0 "register_operand" "=r")
2940         (vec_select:V2HI
2941          (vec_concat:V4HI (match_operand:V2HI 1 "reg_or_0_operand" "rO")
2942                           (match_operand:V2HI 2 "reg_or_0_operand" "rO"))
2943          (parallel [(const_int 1) (const_int 3)])))]
2944   ""
2945   "inthh\t%0, %r2, %r1"
2946   [(set_attr "type" "X01")])
2948 (define_expand "insn_inthh"
2949   [(match_operand:SI 0 "register_operand" "")
2950    (match_operand:SI 1 "reg_or_0_operand" "")
2951    (match_operand:SI 2 "reg_or_0_operand" "")]
2952   ""
2954   /* Our instruction interleaves opposite of the way vec_interleave
2955      works, so we need to reverse the source operands.  */
2956   tilepro_expand_builtin_vector_binop (gen_vec_interleave_highv2hi, V2HImode,
2957                                        operands[0], V2HImode, operands[2],
2958                                        operands[1], true);
2959   DONE;
2962 ;; insn_intlh
2963 ;;    {B1,B0} {A1,A0}
2964 ;; => {A1,A0,B1,B0}
2965 ;; => {A0,B0}
2966 (define_insn "vec_interleave_lowv2hi"
2967   [(set (match_operand:V2HI 0 "register_operand" "=r")
2968         (vec_select:V2HI
2969          (vec_concat:V4HI (match_operand:V2HI 1 "reg_or_0_operand" "rO")
2970                           (match_operand:V2HI 2 "reg_or_0_operand" "rO"))
2971          (parallel [(const_int 0) (const_int 2)])))]
2972   ""
2973   "intlh\t%0, %r2, %r1"
2974   [(set_attr "type" "X01")])
2976 (define_expand "insn_intlh"
2977   [(match_operand:SI 0 "register_operand" "")
2978    (match_operand:SI 1 "reg_or_0_operand" "")
2979    (match_operand:SI 2 "reg_or_0_operand" "")]
2980   ""
2982   /* Our instruction interleaves opposite of the way vec_interleave
2983      works, so we need to reverse the source operands.  */
2984   tilepro_expand_builtin_vector_binop (gen_vec_interleave_lowv2hi, V2HImode,
2985                                        operands[0], V2HImode, operands[2],
2986                                        operands[1], true);
2987   DONE;
2990 ;; insn_packbs_u
2991 ;; insn_packlb
2992 ;;    {B1,B0} {A1,A0}
2993 ;; => {A1,A0,B1,B0}
2994 (define_insn "vec_pack_<pack_optab>_v2hi"
2995   [(set (match_operand:V4QI 0 "register_operand" "=r")
2996         (vec_concat:V4QI
2997          (v2pack:V2QI (match_operand:V2HI 1 "reg_or_0_operand" "rO"))
2998          (v2pack:V2QI (match_operand:V2HI 2 "reg_or_0_operand" "rO"))))]
2999   ""
3000   "<pack_insn>b<pack_u>\t%0, %r2, %r1"
3001   [(set_attr "type" "X01")])
3003 (define_expand "insn_<pack_insn>b<pack_u>"
3004   [(set (match_operand:SI 0 "register_operand" "")
3005         (vec_concat:V4QI
3006          (v2pack:V2QI (match_operand:SI 1 "reg_or_0_operand" ""))
3007          (v2pack:V2QI (match_operand:SI 2 "reg_or_0_operand" ""))))]
3008   ""
3010   /* Our instruction concats opposite of the way vec_pack works, so we
3011      need to reverse the source operands.  */
3012   tilepro_expand_builtin_vector_binop (gen_vec_pack_<pack_optab>_v2hi,
3013                                        V4QImode, operands[0],
3014                                        V2HImode, operands[2], operands[1], true);
3015   DONE;
3018 ;; insn_packhb
3019 ;;    {B1,B0} {A1,A0}
3020 ;; => {A1,A0,B1,B0}
3021 (define_insn "vec_pack_hipart_v2hi"
3022   [(set (match_operand:V4QI 0 "register_operand" "=r")
3023         (vec_concat:V4QI
3024          (truncate:V2QI
3025           (ashiftrt:V2HI (match_operand:V2HI 1 "reg_or_0_operand" "rO")
3026                          (const_int 8)))
3027          (truncate:V2QI
3028           (ashiftrt:V2HI (match_operand:V2HI 2 "reg_or_0_operand" "rO")
3029                          (const_int 8)))))]
3030   ""
3031   "packhb\t%0, %r2, %r1"
3032   [(set_attr "type" "X01")])
3034 (define_expand "insn_packhb"
3035   [(set (match_operand:SI 0 "register_operand" "")
3036         (vec_concat:V4QI
3037          (truncate:V2QI
3038           (ashiftrt:V2HI (match_operand:SI 2 "reg_or_0_operand" "")
3039                          (const_int 8)))
3040          (truncate:V2QI
3041           (ashiftrt:V2HI (match_operand:SI 1 "reg_or_0_operand" "")
3042                          (const_int 8)))))]
3043   ""
3045   /* Our instruction concats opposite of the way vec_pack works, so we
3046      need to reverse the source operands.  */
3047   tilepro_expand_builtin_vector_binop (gen_vec_pack_hipart_v2hi,
3048                                        V4QImode, operands[0],
3049                                        V2HImode, operands[2], operands[1], true);
3050   DONE;
3053 ;; insn_packhs
3054 ;;    {B0} {A0}
3055 ;; => {A0,B0}
3056 (define_insn "vec_pack_ssat_si"
3057   [(set (match_operand:V2HI 0 "register_operand" "=r")
3058         (vec_concat:V2HI
3059          (ss_truncate:HI (match_operand:SI 1 "reg_or_0_operand" "rO"))
3060          (ss_truncate:HI (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
3061   ""
3062   "packhs\t%0, %r2, %r1"
3063   [(set_attr "type" "X01")])
3065 (define_expand "insn_packhs"
3066   [(set (match_operand:SI 0 "register_operand" "")
3067         (vec_concat:V2HI
3068          (ss_truncate:HI (match_operand:SI 2 "reg_or_0_operand" ""))
3069          (ss_truncate:HI (match_operand:SI 1 "reg_or_0_operand" ""))))]
3070   ""
3072   /* Our instruction concats opposite of the way vec_pack works, so we
3073      need to reverse the source operands.  */
3074   tilepro_expand_builtin_vector_binop (gen_vec_pack_ssat_si,
3075                                        V2HImode, operands[0],
3076                                        SImode, operands[2], operands[1], true);
3077   DONE;
3080 ;; Rest of the intrinsics
3081 (define_insn "insn_adiffb_u"
3082   [(set (match_operand:SI 0 "register_operand" "=r")
3083         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3084                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3085                    UNSPEC_INSN_ADIFFB_U))]
3086   ""
3087   "adiffb_u\t%0, %r1, %r2"
3088   [(set_attr "type" "X0_2cycle")])
3090 (define_insn "insn_adiffh"
3091   [(set (match_operand:SI 0 "register_operand" "=r")
3092         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3093                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3094                    UNSPEC_INSN_ADIFFH))]
3095   ""
3096   "adiffh\t%0, %r1, %r2"
3097   [(set_attr "type" "X0_2cycle")])
3099 (define_insn "insn_avgb_u"
3100   [(set (match_operand:SI 0 "register_operand" "=r")
3101         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3102                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3103                    UNSPEC_INSN_AVGB_U))]
3104   ""
3105   "avgb_u\t%0, %r1, %r2"
3106   [(set_attr "type" "X0")])
3108 (define_insn "insn_avgh"
3109   [(set (match_operand:SI 0 "register_operand" "=r")
3110         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3111                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3112                    UNSPEC_INSN_AVGH))]
3113   ""
3114   "avgh\t%0, %r1, %r2"
3115   [(set_attr "type" "X0")])
3117 (define_insn "insn_bitx"
3118   [(set (match_operand:SI 0 "register_operand" "=r")
3119         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")]
3120                     UNSPEC_INSN_BITX))]
3121   ""
3122   "bitx\t%0, %r1"
3123   [(set_attr "type" "Y0")])
3125 (define_insn "insn_crc32_32"
3126   [(set (match_operand:SI 0 "register_operand" "=r")
3127         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3128                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3129                    UNSPEC_INSN_CRC32_32))]
3130   ""
3131   "crc32_32\t%0, %r1, %r2"
3132   [(set_attr "type" "X0")])
3134 (define_insn "insn_crc32_8"
3135   [(set (match_operand:SI 0 "register_operand" "=r")
3136         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3137                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3138                    UNSPEC_INSN_CRC32_8))]
3139   ""
3140   "crc32_8\t%0, %r1, %r2"
3141   [(set_attr "type" "X0")])
3143 (define_insn "insn_dtlbpr"
3144   [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] 
3145                          UNSPEC_INSN_DTLBPR)]
3146   ""
3147   "dtlbpr\t%r0"
3148   [(set_attr "type" "X1")])
3150 (define_insn "insn_dword_align"
3151   [(set (match_operand:SI 0 "register_operand" "=r")
3152         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3153                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3154                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3155                    UNSPEC_INSN_DWORD_ALIGN))]
3156   ""
3157   "dword_align\t%0, %r2, %r3"
3158   [(set_attr "type" "X0")])
3160 (define_insn "insn_finv"
3161   [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] 
3162                          UNSPEC_INSN_FINV)]
3163   ""
3164   "finv\t%r0"
3165   [(set_attr "type" "X1")])
3167 (define_insn "insn_flush"
3168   [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] 
3169                          UNSPEC_INSN_FLUSH)]
3170   ""
3171   "flush\t%r0"
3172   [(set_attr "type" "X1")])
3174 (define_insn "insn_fnop"
3175   [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FNOP)]
3176   ""
3177   "fnop")
3179 (define_insn "insn_ill"
3180   [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_ILL)]
3181   ""
3182   "ill"
3183   [(set_attr "type" "cannot_bundle")])
3185 (define_insn "insn_inv"
3186   [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] 
3187                          UNSPEC_INSN_INV)]
3188   ""
3189   "inv\t%r0"
3190   [(set_attr "type" "X1")])
3192 (define_insn "insn_lnk"
3193   [(set (match_operand:SI 0 "register_operand" "=r")
3194         (unspec:SI [(const_int 0)] UNSPEC_INSN_LNK))]
3195   ""
3196   "lnk\t%0"
3197   [(set_attr "type" "X1")])
3199 (define_insn "insn_mnzb"
3200   [(set (match_operand:SI 0 "register_operand" "=r")
3201         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3202                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3203                    UNSPEC_INSN_MNZB))]
3204   ""
3205   "mnzb\t%0, %r1, %r2"
3206   [(set_attr "type" "X01")])
3208 (define_insn "insn_mnzh"
3209   [(set (match_operand:SI 0 "register_operand" "=r")
3210         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3211                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3212                    UNSPEC_INSN_MNZH))]
3213   ""
3214   "mnzh\t%0, %r1, %r2"
3215   [(set_attr "type" "X01")])
3217 (define_insn "insn_mulhh_ss"
3218   [(set (match_operand:SI 0 "register_operand" "=r")
3219         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3220                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3221                    UNSPEC_INSN_MULHH_SS))]
3222   ""
3223   "mulhh_ss\t%0, %r1, %r2"
3224   [(set_attr "type" "Y0_2cycle")])
3226 (define_insn "insn_mulhh_su"
3227   [(set (match_operand:SI 0 "register_operand" "=r")
3228         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3229                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3230                    UNSPEC_INSN_MULHH_SU))]
3231   ""
3232   "mulhh_su\t%0, %r1, %r2"
3233   [(set_attr "type" "X0_2cycle")])
3235 (define_insn "insn_mulhh_uu"
3236   [(set (match_operand:SI 0 "register_operand" "=r")
3237         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3238                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3239                    UNSPEC_INSN_MULHH_UU))]
3240   ""
3241   "mulhh_uu\t%0, %r1, %r2"
3242   [(set_attr "type" "Y0_2cycle")])
3244 (define_insn "insn_mulhha_ss"
3245   [(set (match_operand:SI 0 "register_operand" "=r")
3246         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3247                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3248                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3249                    UNSPEC_INSN_MULHHA_SS))]
3250   ""
3251   "mulhha_ss\t%0, %r2, %r3"
3252   [(set_attr "type" "Y0_2cycle")])
3254 (define_insn "insn_mulhha_su"
3255   [(set (match_operand:SI 0 "register_operand" "=r")
3256         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3257                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3258                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3259                    UNSPEC_INSN_MULHHA_SU))]
3260   ""
3261   "mulhha_su\t%0, %r2, %r3"
3262   [(set_attr "type" "X0_2cycle")])
3264 (define_insn "insn_mulhha_uu"
3265   [(set (match_operand:SI 0 "register_operand" "=r")
3266         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3267                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3268                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3269                    UNSPEC_INSN_MULHHA_UU))]
3270   ""
3271   "mulhha_uu\t%0, %r2, %r3"
3272   [(set_attr "type" "Y0_2cycle")])
3274 (define_insn "insn_mulhhsa_uu"
3275   [(set (match_operand:SI 0 "register_operand" "=r")
3276         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3277                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3278                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3279                    UNSPEC_INSN_MULHHSA_UU))]
3280   ""
3281   "mulhhsa_uu\t%0, %r2, %r3"
3282   [(set_attr "type" "X0_2cycle")])
3284 (define_insn "insn_mulhl_ss"
3285   [(set (match_operand:SI 0 "register_operand" "=r")
3286         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3287                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3288                    UNSPEC_INSN_MULHL_SS))]
3289   ""
3290   "mulhl_ss\t%0, %r1, %r2"
3291   [(set_attr "type" "X0_2cycle")])
3293 (define_insn "insn_mulhl_su"
3294   [(set (match_operand:SI 0 "register_operand" "=r")
3295         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3296                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3297                    UNSPEC_INSN_MULHL_SU))]
3298   ""
3299   "mulhl_su\t%0, %r1, %r2"
3300   [(set_attr "type" "X0_2cycle")])
3302 (define_insn "insn_mulhl_us"
3303   [(set (match_operand:SI 0 "register_operand" "=r")
3304         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3305                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3306                    UNSPEC_INSN_MULHL_US))]
3307   ""
3308   "mulhl_us\t%0, %r1, %r2"
3309   [(set_attr "type" "X0_2cycle")])
3311 (define_insn "insn_mulhl_uu"
3312   [(set (match_operand:SI 0 "register_operand" "=r")
3313         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3314                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3315                    UNSPEC_INSN_MULHL_UU))]
3316   ""
3317   "mulhl_uu\t%0, %r1, %r2"
3318   [(set_attr "type" "X0_2cycle")])
3320 (define_insn "insn_mulhla_ss"
3321   [(set (match_operand:SI 0 "register_operand" "=r")
3322         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3323                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3324                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3325                    UNSPEC_INSN_MULHLA_SS))]
3326   ""
3327   "mulhla_ss\t%0, %r2, %r3"
3328   [(set_attr "type" "X0_2cycle")])
3330 (define_insn "insn_mulhla_su"
3331   [(set (match_operand:SI 0 "register_operand" "=r")
3332         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3333                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3334                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3335                    UNSPEC_INSN_MULHLA_SU))]
3336   ""
3337   "mulhla_su\t%0, %r2, %r3"
3338   [(set_attr "type" "X0_2cycle")])
3340 (define_insn "insn_mulhla_us"
3341   [(set (match_operand:SI 0 "register_operand" "=r")
3342         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3343                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3344                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3345                    UNSPEC_INSN_MULHLA_US))]
3346   ""
3347   "mulhla_us\t%0, %r2, %r3"
3348   [(set_attr "type" "X0_2cycle")])
3350 (define_insn "insn_mulhla_uu"
3351   [(set (match_operand:SI 0 "register_operand" "=r")
3352         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3353                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3354                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3355                    UNSPEC_INSN_MULHLA_UU))]
3356   ""
3357   "mulhla_uu\t%0, %r2, %r3"
3358   [(set_attr "type" "X0_2cycle")])
3360 (define_insn "insn_mulhlsa_uu"
3361   [(set (match_operand:SI 0 "register_operand" "=r")
3362         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3363                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3364                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3365                    UNSPEC_INSN_MULHLSA_UU))]
3366   ""
3367   "mulhlsa_uu\t%0, %r2, %r3"
3368   [(set_attr "type" "Y0_2cycle")])
3370 (define_insn "insn_mulll_ss"
3371   [(set (match_operand:SI 0 "register_operand" "=r")
3372         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3373                     (match_operand:SI 2 "reg_or_0_operand" "rO")]
3374                     UNSPEC_INSN_MULLL_SS))]
3375   ""
3376   "mulll_ss\t%0, %r1, %r2"
3377   [(set_attr "type" "Y0_2cycle")])
3378   
3379 (define_insn "insn_mulll_su"
3380   [(set (match_operand:SI 0 "register_operand" "=r")
3381         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3382                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3383                    UNSPEC_INSN_MULLL_SU))]
3384   ""
3385   "mulll_su\t%0, %r1, %r2"
3386   [(set_attr "type" "X0_2cycle")])
3388 (define_insn "insn_mulll_uu"
3389   [(set (match_operand:SI 0 "register_operand" "=r")
3390         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3391                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3392                    UNSPEC_INSN_MULLL_UU))]
3393   ""
3394   "mulll_uu\t%0, %r1, %r2"
3395   [(set_attr "type" "Y0_2cycle")])
3397 (define_insn "insn_mullla_ss"
3398   [(set (match_operand:SI 0 "register_operand" "=r")
3399         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3400                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3401                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3402                    UNSPEC_INSN_MULLLA_SS))]
3403   ""
3404   "mullla_ss\t%0, %r2, %r3"
3405   [(set_attr "type" "Y0_2cycle")])
3407 (define_insn "insn_mullla_su"
3408   [(set (match_operand:SI 0 "register_operand" "=r")
3409         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3410                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3411                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3412                    UNSPEC_INSN_MULLLA_SU))]
3413   ""
3414   "mullla_su\t%0, %r2, %r3"
3415   [(set_attr "type" "X0_2cycle")])
3417 (define_insn "insn_mullla_uu"
3418   [(set (match_operand:SI 0 "register_operand" "=r")
3419         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3420                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3421                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3422                    UNSPEC_INSN_MULLLA_UU))]
3423   ""
3424   "mullla_uu\t%0, %r2, %r3"
3425   [(set_attr "type" "Y0_2cycle")])
3427 (define_insn "insn_mulllsa_uu"
3428   [(set (match_operand:SI 0 "register_operand" "=r")
3429         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3430                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3431                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3432                    UNSPEC_INSN_MULLLSA_UU))]
3433   ""
3434   "mulllsa_uu\t%0, %r2, %r3"
3435   [(set_attr "type" "X0_2cycle")])
3437 (define_insn "insn_mzb"
3438   [(set (match_operand:SI 0 "register_operand" "=r")
3439         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3440                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3441                    UNSPEC_INSN_MZB))]
3442   ""
3443   "mzb\t%0, %r1, %r2"
3444   [(set_attr "type" "X01")])
3446 (define_insn "insn_mzh"
3447   [(set (match_operand:SI 0 "register_operand" "=r")
3448         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3449                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3450                    UNSPEC_INSN_MZH))]
3451   ""
3452   "mzh\t%0, %r1, %r2"
3453   [(set_attr "type" "X01")])
3455 (define_insn "insn_nap"
3456   [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_NAP)]
3457   ""
3458   "nap"
3459   [(set_attr "type" "cannot_bundle")])
3461 (define_insn "insn_nor"
3462   [(set (match_operand:SI 0 "register_operand" "=r")
3463         (and:SI (not:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))
3464                 (not:SI (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
3465   ""
3466   "nor\t%0, %r1, %r2")
3468 (define_insn "insn_sadab_u"
3469   [(set (match_operand:SI 0 "register_operand" "=r")
3470         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3471                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3472                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3473                    UNSPEC_INSN_SADAB_U))]
3474   ""
3475   "sadab_u\t%0, %r2, %r3"
3476   [(set_attr "type" "X0_2cycle")])
3478 (define_insn "insn_sadah"
3479   [(set (match_operand:SI 0 "register_operand" "=r")
3480         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3481                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3482                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3483                    UNSPEC_INSN_SADAH))]
3484   ""
3485   "sadah\t%0, %r2, %r3"
3486   [(set_attr "type" "X0_2cycle")])
3488 (define_insn "insn_sadah_u"
3489   [(set (match_operand:SI 0 "register_operand" "=r")
3490         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3491                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3492                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3493                    UNSPEC_INSN_SADAH_U))]
3494   ""
3495   "sadah_u\t%0, %r2, %r3"
3496   [(set_attr "type" "X0_2cycle")])
3498 (define_insn "insn_sadb_u"
3499   [(set (match_operand:SI 0 "register_operand" "=r")
3500         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3501                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3502                    UNSPEC_INSN_SADB_U))]
3503   ""
3504   "sadb_u\t%0, %r1, %r2"
3505   [(set_attr "type" "X0_2cycle")])
3507 (define_insn "insn_sadh"
3508   [(set (match_operand:SI 0 "register_operand" "=r")
3509         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3510                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3511                    UNSPEC_INSN_SADH))]
3512   ""
3513   "sadh\t%0, %r1, %r2"
3514   [(set_attr "type" "X0_2cycle")])
3516 (define_insn "insn_sadh_u"
3517   [(set (match_operand:SI 0 "register_operand" "=r")
3518         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3519                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3520                    UNSPEC_INSN_SADH_U))]
3521   ""
3522   "sadh_u\t%0, %r1, %r2"
3523   [(set_attr "type" "X0_2cycle")])
3525 (define_insn "insn_tblidxb0"
3526   [(set (match_operand:SI 0 "register_operand" "=r")
3527         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3528                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3529                    UNSPEC_INSN_TBLIDXB0))]
3530   ""
3531   "tblidxb0\t%0, %r2"
3532   [(set_attr "type" "Y0")])
3534 (define_insn "insn_tblidxb1"
3535   [(set (match_operand:SI 0 "register_operand" "=r")
3536         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3537                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3538                    UNSPEC_INSN_TBLIDXB1))]
3539   ""
3540   "tblidxb1\t%0, %r2"
3541   [(set_attr "type" "Y0")])
3543 (define_insn "insn_tblidxb2"
3544   [(set (match_operand:SI 0 "register_operand" "=r")
3545         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3546                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3547                    UNSPEC_INSN_TBLIDXB2))]
3548   ""
3549   "tblidxb2\t%0, %r2"
3550   [(set_attr "type" "Y0")])
3552 (define_insn "insn_tblidxb3"
3553   [(set (match_operand:SI 0 "register_operand" "=r")
3554         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3555                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3556                    UNSPEC_INSN_TBLIDXB3))]
3557   ""
3558   "tblidxb3\t%0, %r2"
3559   [(set_attr "type" "Y0")])
3563 ;; pic related instructions
3566 ;; NOTE: We compute the label in this unusual way because if we place
3567 ;; the label after the lnk, whether it is at the same address as the
3568 ;; lnk will vary depending on whether the optimization level chooses to
3569 ;; insert bundling braces.
3570 (define_insn "insn_lnk_and_label"
3571   [(set (match_operand:SI 0 "register_operand" "=r")
3572         (unspec_volatile:SI [(match_operand:SI 1 "symbolic_operand" "")]
3573                             UNSPEC_LNK_AND_LABEL))]
3574   ""
3575   "%1 = . + 8\n\tlnk\t%0"
3576   [(set_attr "type" "X1")])
3578 (define_expand "addli_pcrel"
3579   [(set (match_operand:SI 0 "register_operand" "")
3580         (lo_sum:SI
3581          (match_operand:SI 1 "register_operand" "")
3582          (const:SI
3583           (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
3584                       (match_operand:SI 3 "symbolic_operand" "")]
3585                      UNSPEC_PCREL_SYM))))]
3586   "flag_pic")
3588 (define_expand "auli_pcrel"
3589   [(set (match_operand:SI 0 "register_operand" "")
3590         (plus:SI
3591          (match_operand:SI 1 "reg_or_0_operand" "")
3592          (high:SI
3593           (const:SI
3594            (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
3595                        (match_operand:SI 3 "symbolic_operand" "")]
3596                       UNSPEC_PCREL_SYM)))))]
3597   "flag_pic")
3599 (define_expand "add_got16"
3600   [(set (match_operand:SI 0 "register_operand" "")
3601         (lo_sum:SI
3602          (match_operand:SI 1 "reg_or_0_operand" "")
3603          (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
3604                               UNSPEC_GOT16_SYM))))]
3605   "flag_pic == 1")
3607 (define_expand "addhi_got32"
3608   [(set (match_operand:SI 0 "register_operand" "")
3609         (plus:SI
3610          (match_operand:SI 1 "reg_or_0_operand" "")
3611          (high:SI
3612           (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
3613                                UNSPEC_GOT32_SYM)))))]
3614   "flag_pic == 2")
3616 (define_expand "addlo_got32"
3617   [(set (match_operand:SI 0 "register_operand" "")
3618         (lo_sum:SI
3619          (match_operand:SI 1 "reg_or_0_operand" "")
3620          (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
3621                               UNSPEC_GOT32_SYM))))]
3622   "flag_pic == 2")
3626 ;; TLS
3629 (define_expand "tls_gd_addhi"
3630   [(set (match_operand:SI 0 "register_operand" "")
3631         (plus:SI
3632          (match_operand:SI 1 "reg_or_0_operand" "")
3633          (high:SI
3634           (const:SI (unspec:SI [(match_operand 2 "tls_symbolic_operand" "")]
3635                                UNSPEC_TLS_GD)))))]
3636   "HAVE_AS_TLS")
3638 (define_expand "tls_gd_addlo"
3639   [(set (match_operand:SI 0 "register_operand" "")
3640         (lo_sum:SI
3641          (match_operand:SI 1 "reg_or_0_operand" "")
3642          (const:SI (unspec:SI [(match_operand 2 "tls_symbolic_operand" "")]
3643                               UNSPEC_TLS_GD))))]
3644   "HAVE_AS_TLS")
3646 (define_expand "tls_gd_call"
3647   [(parallel
3648     [(set (reg:SI 0)
3649           (unspec:SI [(match_operand:SI 0 "tls_symbolic_operand" "")
3650                      (reg:SI 0)]
3651                      UNSPEC_TLS_GD_CALL))
3652      (clobber (reg:SI 25))
3653      (clobber (reg:SI 26))
3654      (clobber (reg:SI 27))
3655      (clobber (reg:SI 28))
3656      (clobber (reg:SI 29))
3657      (clobber (reg:SI 55))])]
3658    ""
3660   cfun->machine->calls_tls_get_addr = true;
3663 (define_insn "*tls_gd_call"
3664   [(set (reg:SI 0)
3665         (unspec:SI [(match_operand:SI 0 "tls_symbolic_operand" "")
3666                     (reg:SI 0)]
3667                    UNSPEC_TLS_GD_CALL))
3668    (clobber (reg:SI 25))
3669    (clobber (reg:SI 26))
3670    (clobber (reg:SI 27))
3671    (clobber (reg:SI 28))
3672    (clobber (reg:SI 29))
3673    (clobber (reg:SI 55))]
3674   ""
3675   "jal\ttls_gd_call(%0)"
3676   [(set_attr "type" "X1")])
3678 (define_insn "tls_gd_add"
3679   [(set (match_operand:SI 0 "register_operand" "=r")
3680        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
3681                    (match_operand:SI 2 "tls_symbolic_operand" "")]
3682                   UNSPEC_TLS_GD_ADD))]
3683   "HAVE_AS_TLS"
3684   "addi\t%0, %1, tls_gd_add(%2)")
3686 (define_insn "tls_ie_load"
3687   [(set (match_operand:SI 0 "register_operand" "=r")
3688        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
3689                    (match_operand:SI 2 "tls_symbolic_operand" "")]
3690                   UNSPEC_TLS_IE_LOAD))]
3691   "HAVE_AS_TLS"
3692   "lw_tls\t%0, %1, tls_ie_load(%2)"
3693   [(set_attr "type" "X1_2cycle")])
3695 (define_expand "tls_ie_addhi"
3696   [(set (match_operand:SI 0 "register_operand" "")
3697         (plus:SI
3698          (match_operand:SI 1 "register_operand" "")
3699          (high:SI
3700           (const:SI (unspec:SI [(match_operand 2 "tls_ie_symbolic_operand" "")]
3701                                UNSPEC_TLS_IE)))))]
3702   "HAVE_AS_TLS")
3704 (define_expand "tls_ie_addlo"
3705   [(set (match_operand:SI 0 "register_operand" "")
3706         (lo_sum:SI
3707          (match_operand:SI 1 "register_operand" "")
3708          (const:SI (unspec:SI [(match_operand 2 "tls_ie_symbolic_operand" "")]
3709                               UNSPEC_TLS_IE))))]
3710   "HAVE_AS_TLS")
3712 (define_expand "tls_le_addhi"
3713   [(set (match_operand:SI 0 "register_operand" "")
3714         (plus:SI
3715          (match_operand:SI 1 "register_operand" "")
3716          (high:SI
3717           (const:SI (unspec:SI [(match_operand 2 "tls_le_symbolic_operand" "")]
3718                                UNSPEC_TLS_LE)))))]
3719   "HAVE_AS_TLS")
3721 (define_expand "tls_le_addlo"
3722   [(set (match_operand:SI 0 "register_operand" "")
3723         (lo_sum:SI
3724          (match_operand:SI 1 "register_operand" "")
3725          (const:SI (unspec:SI [(match_operand 2 "tls_le_symbolic_operand" "")]
3726                               UNSPEC_TLS_LE))))]
3727   "HAVE_AS_TLS")
3731 ;; Stack protector instructions.
3734 (define_expand "stack_protect_set"
3735   [(set (match_operand 0 "nonautoincmem_operand" "")
3736         (match_operand 1 "nonautoincmem_operand" ""))]
3737   ""
3739 #ifdef TARGET_THREAD_SSP_OFFSET
3740   rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
3741   rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
3742   rtx ssp = gen_reg_rtx (Pmode);
3743   
3744   emit_insn (gen_rtx_SET (VOIDmode, ssp, ssp_addr));
3746   operands[1] = gen_rtx_MEM (Pmode, ssp);
3747 #endif
3749   emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
3751   DONE;
3754 (define_insn "stack_protect_setsi"
3755   [(set (match_operand:SI 0 "nonautoincmem_operand" "=U")
3756         (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")]
3757                    UNSPEC_SP_SET))
3758    (set (match_scratch:SI 2 "=&r") (const_int 0))]
3759   ""
3760   "lw\t%2, %1; { sw\t%0, %2; move\t%2, zero }"
3761   [(set_attr "length" "16")
3762    (set_attr "type" "cannot_bundle_3cycle")])
3765 (define_expand "stack_protect_test"
3766   [(match_operand 0 "nonautoincmem_operand" "")
3767    (match_operand 1 "nonautoincmem_operand" "")
3768    (match_operand 2 "" "")]
3769   ""
3771   rtx compare_result;
3772   rtx bcomp, loc_ref;
3774 #ifdef TARGET_THREAD_SSP_OFFSET
3775   rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
3776   rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
3777   rtx ssp = gen_reg_rtx (Pmode);
3778   
3779   emit_insn (gen_rtx_SET (VOIDmode, ssp, ssp_addr));
3781   operands[1] = gen_rtx_MEM (Pmode, ssp);
3782 #endif
3784   compare_result = gen_reg_rtx (SImode);
3786   emit_insn (gen_stack_protect_testsi (compare_result, operands[0],
3787                                        operands[1]));
3789   bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
3791   loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
3793   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3794                                gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
3795                                                      loc_ref, pc_rtx)));
3797   DONE;
3800 (define_insn "stack_protect_testsi"
3801   [(set (match_operand:SI 0 "register_operand" "=&r")
3802         (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")
3803                     (match_operand:SI 2 "nonautoincmem_operand" "U")]
3804                    UNSPEC_SP_TEST))
3805    (set (match_scratch:SI 3 "=&r") (const_int 0))]
3806   ""
3807   "lw\t%0, %1; lw\t%3, %2; { seq\t%0, %0, %3; move\t%3, zero }"
3808   [(set_attr "length" "24")
3809    (set_attr "type" "cannot_bundle_4cycle")])