[PR c++/84492] stmt expr ending with overload
[official-gcc.git] / gcc / config / tilepro / tilepro.md
blob5993eed8fd0e07a9c57fd003f9636c0ab7f76dc3
1 ;; Machine description for Tilera TILEPro chip for GCC.
2 ;; Copyright (C) 2011-2018 Free Software Foundation, Inc.
3 ;; Contributed by Walter Lee (walt@tilera.com)
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 (define_constants [
22   ;;
23   ;; The following represent intrinsic insns, organized by latency.
24   ;;
26   ;; single cycle
27   (UNSPEC_INSN_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 (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));
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")])
1581 (define_insn "trap"
1582   [(trap_if (const_int 1) (const_int 0))]
1583   ""
1584   "raise; moveli zero, 6"
1585   [(set_attr "type" "cannot_bundle")])
1589 ;; Conditional branches
1592 (define_expand "cbranchsi4"
1593   [(set (pc)
1594         (if_then_else (match_operator 0 "ordered_comparison_operator"
1595                        [(match_operand:SI 1 "reg_or_cint_operand")
1596                         (match_operand:SI 2 "reg_or_cint_operand")])
1597                       (label_ref (match_operand 3 ""))
1598                       (pc)))]
1599   ""
1600   { tilepro_emit_conditional_branch (operands, SImode); DONE; })
1603 (define_expand "cbranchdi4"
1604   [(set (pc)
1605         (if_then_else (match_operator 0 "ordered_comparison_operator"
1606                        [(match_operand:DI 1 "reg_or_cint_operand")
1607                         (match_operand:DI 2 "reg_or_cint_operand")])
1608                       (label_ref (match_operand 3 ""))
1609                       (pc)))]
1610   ""
1611   { tilepro_emit_conditional_branch (operands, DImode); DONE; })
1612   
1614 (define_insn "*bcc_normal"
1615   [(set (pc)
1616         (if_then_else
1617          (match_operator 1 "signed_comparison_operator"
1618                          [(match_operand:SI 2 "reg_or_0_operand" "rO")
1619                           (const_int 0)])
1620          (label_ref (match_operand 0 "" ""))
1621          (pc)))]
1622   ""
1623   { return tilepro_output_cbranch (insn, operands, false); }
1624   [(set_attr "type" "X1_branch")])
1626 (define_insn "*bcc_reverse"
1627   [(set (pc)
1628         (if_then_else
1629          (match_operator 1 "signed_comparison_operator"
1630                          [(match_operand:SI 2 "reg_or_0_operand" "rO")
1631                           (const_int 0)])
1632          (pc)
1633          (label_ref (match_operand 0 "" ""))))]
1634   ""
1635   { return tilepro_output_cbranch (insn, operands, true); }
1636   [(set_attr "type" "X1_branch")])
1638 ;; FIXME: the straight forward versions which do not include the
1639 ;; subreg:QI does not match for some unknown reason.
1640 (define_insn "*bbs_normal"
1641   [(set (pc)
1642         (if_then_else
1643          (ne (zero_extract:SI (subreg:QI 
1644                                (match_operand:SI 1 "reg_or_0_operand" "rO") 0)
1645                               (const_int 1)
1646                               (const_int 0))
1647              (const_int 0))
1648          (label_ref (match_operand 0 "" ""))
1649          (pc)))]
1650   ""
1651   { return tilepro_output_cbranch_with_opcode (insn, operands, "bbs", "bbns",
1652                                             1, 0); }
1653   [(set_attr "type" "X1_branch")])
1655 (define_insn "*bbc_normal"
1656   [(set (pc)
1657         (if_then_else
1658          (eq (zero_extract:SI (subreg:QI
1659                                (match_operand:SI 1 "reg_or_0_operand" "rO") 0)
1660                               (const_int 1)
1661                               (const_int 0))
1662              (const_int 0))
1663          (label_ref (match_operand 0 "" ""))
1664          (pc)))]
1665   ""
1666   { return tilepro_output_cbranch_with_opcode (insn, operands, "bbns", "bbs",
1667                                             1, 0); }
1668   [(set_attr "type" "X1_branch")])
1670 ;; Note that __insn_mf() expands to this.
1671 (define_expand "memory_barrier"
1672   [(set (match_dup 0)
1673         (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
1674   ""
1676   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
1677   MEM_VOLATILE_P (operands[0]) = 1;
1680 (define_insn "*memory_barrier"
1681   [(set (match_operand:BLK 0 "" "")
1682         (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
1683   ""
1684   "mf"
1685   [(set_attr "type" "X1")])
1687 (define_insn "prefetch"
1688   [(prefetch (match_operand:SI 0 "address_operand" "rO")
1689              (match_operand:SI 1 "const_int_operand" "")
1690              (match_operand:SI 2 "const_int_operand" ""))]
1691   ""
1692   "prefetch\t%r0"
1693   [(set_attr "type" "Y2")])
1697 ;; Network intrinsics
1700 ;; Note the "pseudo" text is handled specially by the
1701 ;; asm_output_opcode routine.  If the output is an empty string, the
1702 ;; instruction would bypass the asm_output_opcode routine, bypassing
1703 ;; the bundle handling code.
1704 (define_insn "tilepro_network_barrier"
1705   [(unspec_volatile:SI [(const_int 0)] UNSPEC_NETWORK_BARRIER)]
1706   ""
1707   "pseudo"
1708   [(set_attr "type" "nothing")
1709    (set_attr "length" "0")])
1711 (define_insn "*netreg_receive"
1712   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,U,m")
1713         (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i")
1714                              (reg:SI TILEPRO_NETORDER_REG)]
1715                             UNSPEC_NETWORK_RECEIVE))
1716    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1717   ""
1718   "@
1719    move\t%0, %N1
1720    sw\t%0, %N1
1721    swadd\t%I0, %N1, %i0"
1722   [(set_attr "type" "*,Y2,X1")])
1723   
1724 (define_insn "*netreg_send"
1725   [(unspec_volatile:SI
1726     [(match_operand:SI 0 "netreg_operand" "i,i,i,i,i,i")
1727      (match_operand:SI 1 "reg_or_cint_operand" "rO,I,J,K,N,P")
1728      (reg:SI TILEPRO_NETORDER_REG)]
1729     UNSPEC_NETWORK_SEND)
1730    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1731   ""
1732   "@
1733    move\t%N0, %r1
1734    movei\t%N0, %1
1735    moveli\t%N0, %1
1736    auli\t%N0, zero, %h1
1737    addib\t%N0, zero, %j1
1738    addih\t%N0, zero, %h1"
1739   [(set_attr "type" "*,*,X01,X01,X01,X01")])
1741 (define_insn "*netreg_copy"
1742   [(unspec_volatile:SI
1743     [(match_operand:SI 0 "netreg_operand" "i")
1744      (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
1745                           (reg:SI TILEPRO_NETORDER_REG)]
1746                          UNSPEC_NETWORK_RECEIVE)
1747      (reg:SI TILEPRO_NETORDER_REG)]
1748     UNSPEC_NETWORK_SEND)
1749    (clobber (reg:SI TILEPRO_NETORDER_REG))
1750    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1751   ""
1752   "move %N0, %N1")
1754 (define_expand "tilepro_idn0_receive"
1755   [(parallel
1756     [(set (match_operand:SI 0 "register_operand" "")
1757           (unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN0)
1758                                (reg:SI TILEPRO_NETORDER_REG)]
1759                               UNSPEC_NETWORK_RECEIVE))
1760      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1761   "")
1763 (define_expand "tilepro_idn1_receive"
1764   [(parallel
1765     [(set (match_operand:SI 0 "register_operand" "")
1766           (unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN1)
1767                                (reg:SI TILEPRO_NETORDER_REG)]
1768                               UNSPEC_NETWORK_RECEIVE))
1769      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1770   "")
1772 (define_expand "tilepro_idn_send"
1773   [(parallel
1774     [(unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN0)
1775                           (match_operand:SI 0 "reg_or_cint_operand" "")
1776                           (reg:SI TILEPRO_NETORDER_REG)]
1777                          UNSPEC_NETWORK_SEND)
1778      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1779   "")
1781 (define_expand "tilepro_sn_receive"
1782   [(parallel
1783     [(set (match_operand:SI 0 "register_operand" "")
1784           (unspec_volatile:SI [(const_int TILEPRO_NETREG_SN)
1785                                (reg:SI TILEPRO_NETORDER_REG)]
1786                               UNSPEC_NETWORK_RECEIVE))
1787      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1788   "")
1790 (define_expand "tilepro_sn_send"
1791   [(parallel
1792     [(unspec_volatile:SI [(const_int TILEPRO_NETREG_SN)
1793                           (match_operand:SI 0 "reg_or_cint_operand" "")
1794                           (reg:SI TILEPRO_NETORDER_REG)]
1795                          UNSPEC_NETWORK_SEND)
1796      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1797   "")
1799 (define_expand "tilepro_udn0_receive"
1800   [(parallel
1801     [(set (match_operand:SI 0 "register_operand" "")
1802           (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN0)
1803                                (reg:SI TILEPRO_NETORDER_REG)]
1804                               UNSPEC_NETWORK_RECEIVE))
1805      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1806   "")
1808 (define_expand "tilepro_udn1_receive"
1809   [(parallel
1810     [(set (match_operand:SI 0 "register_operand" "")
1811           (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN1)
1812                                (reg:SI TILEPRO_NETORDER_REG)]
1813                               UNSPEC_NETWORK_RECEIVE))
1814      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1815   "")
1817 (define_expand "tilepro_udn2_receive"
1818   [(parallel
1819     [(set (match_operand:SI 0 "register_operand" "")
1820           (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN2)
1821                                (reg:SI TILEPRO_NETORDER_REG)]
1822                               UNSPEC_NETWORK_RECEIVE))
1823      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1824   "")
1826 (define_expand "tilepro_udn3_receive"
1827   [(parallel
1828     [(set (match_operand:SI 0 "register_operand" "")
1829           (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN3)
1830                                (reg:SI TILEPRO_NETORDER_REG)]
1831                               UNSPEC_NETWORK_RECEIVE))
1832      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1833   "")
1835 (define_expand "tilepro_udn_send"
1836   [(parallel
1837     [(unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN0)
1838                           (match_operand:SI 0 "reg_or_cint_operand" "")
1839                           (reg:SI TILEPRO_NETORDER_REG)]
1840                          UNSPEC_NETWORK_SEND)
1841      (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1842   "")
1844 (define_insn "*netreg_add_to_network"
1845   [(unspec_volatile:SI
1846     [(match_operand:SI 0 "netreg_operand" "i,i,i,i")
1847      (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO,rO")
1848               (match_operand:SI 2 "add_operand" "r,I,J,K"))
1849      (reg:SI TILEPRO_NETORDER_REG)]
1850     UNSPEC_NETWORK_SEND)
1851    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1852   ""
1853   "@
1854    add\t%N0, %r1, %2
1855    addi\t%N0, %r1, %2
1856    addli\t%N0, %r1, %2
1857    auli\t%N0, %r1, %h2"
1858   [(set_attr "type" "*,*,X01,X01")])
1860 (define_insn "*netreg_add_from_network"
1861   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1862         (plus:SI
1863          (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i,i")
1864                               (reg:SI TILEPRO_NETORDER_REG)]
1865                              UNSPEC_NETWORK_RECEIVE)
1866          (match_operand:SI 2 "add_operand" "rO,I,J,K")))
1867    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1868   ""
1869   "@
1870    add\t%0, %N1, %r2
1871    addi\t%0, %N1, %2
1872    addli\t%0, %N1, %2
1873    auli\t%0, %N1, %h2"
1874   [(set_attr "type" "*,*,X01,X01")])
1876 (define_insn "*netreg_add_from_to_network"
1877   [(unspec_volatile:SI
1878     [(match_operand:SI 0 "netreg_operand" "i,i,i,i")
1879      (plus:SI
1880       (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i,i")
1881                            (reg:SI TILEPRO_NETORDER_REG)]
1882                           UNSPEC_NETWORK_RECEIVE)
1883       (match_operand:SI 2 "add_operand" "rO,I,J,K"))
1884      (reg:SI TILEPRO_NETORDER_REG)]
1885     UNSPEC_NETWORK_SEND)
1886    (clobber (reg:SI TILEPRO_NETORDER_REG))
1887    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1888   ""
1889   "@
1890    add\t%N0, %N1, %r2
1891    addi\t%N0, %N1, %2
1892    addli\t%N0, %N1, %2
1893    auli\t%N0, %N1, %h2"
1894   [(set_attr "type" "*,*,X01,X01")])
1896 (define_code_iterator netreg_binop
1897   [minus])
1899 (define_insn "*netreg_binop_to_network"
1900   [(unspec_volatile:SI
1901     [(match_operand:SI 0 "netreg_operand" "i")
1902     (netreg_binop:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1903                      (match_operand:SI 2 "reg_or_0_operand" "rO"))
1904     (reg:SI TILEPRO_NETORDER_REG)]
1905     UNSPEC_NETWORK_SEND)
1906    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1907   ""
1908   "<insn>\t%N0, %r1, %r2")
1910 (define_insn "*netreg_binop_from_network0"
1911   [(set (match_operand:SI 0 "register_operand" "=r")
1912         (netreg_binop:SI
1913          (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
1914                               (reg:SI TILEPRO_NETORDER_REG)]
1915                              UNSPEC_NETWORK_RECEIVE)
1916          (match_operand:SI 2 "reg_or_0_operand" "rO")))
1917    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1918   ""
1919   "<insn>\t%0, %N1, %r2")
1921 (define_insn "*netreg_binop_from_network1"
1922   [(set (match_operand:SI 0 "register_operand" "=r")
1923         (netreg_binop:SI
1924          (match_operand:SI 1 "reg_or_0_operand" "rO")
1925          (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
1926                               (reg:SI TILEPRO_NETORDER_REG)]
1927                              UNSPEC_NETWORK_RECEIVE)))
1928    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1929   ""
1930   "<insn>\t%0, %r1, %N2")
1932 (define_insn "*netreg_binop_from_to_network0"
1933   [(unspec_volatile:SI
1934     [(match_operand:SI 0 "netreg_operand" "i")
1935      (netreg_binop:SI
1936       (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
1937                            (reg:SI TILEPRO_NETORDER_REG)]
1938                           UNSPEC_NETWORK_RECEIVE)
1939       (match_operand:SI 2 "reg_or_0_operand" "rO"))
1940      (reg:SI TILEPRO_NETORDER_REG)]
1941     UNSPEC_NETWORK_SEND)
1942    (clobber (reg:SI TILEPRO_NETORDER_REG))
1943    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1944   ""
1945   "<insn>\t%N0, %N1, %r2")
1947 (define_insn "*netreg_binop_from_to_network1"
1948   [(unspec_volatile:SI
1949     [(match_operand:SI 0 "netreg_operand" "i")
1950      (netreg_binop:SI
1951       (match_operand:SI 1 "reg_or_0_operand" "rO")
1952       (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
1953                            (reg:SI TILEPRO_NETORDER_REG)]
1954                           UNSPEC_NETWORK_RECEIVE))
1955      (reg:SI TILEPRO_NETORDER_REG)]
1956     UNSPEC_NETWORK_SEND)
1957    (clobber (reg:SI TILEPRO_NETORDER_REG))
1958    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1959   ""
1960   "<insn>\t%N0, %r1, %N2")
1962 (define_insn "*netreg_binop_to_network"
1963   [(unspec_volatile:SI
1964     [(match_operand:SI 0 "netreg_operand" "i,i")
1965      (binop_with_imm:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1966                         (match_operand:SI 2 "reg_or_cint_operand" "I,rO"))
1967      (reg:SI TILEPRO_NETORDER_REG)]
1968     UNSPEC_NETWORK_SEND)
1969    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1970   ""
1971   "@
1972    <insn>i<u>\t%N0, %r1, %2
1973    <insn><u>\t%N0, %r1, %r2")
1975 (define_insn "*netreg_binop_from_network"
1976   [(set (match_operand:SI 0 "register_operand" "=r,r")
1977         (binop_with_imm:SI
1978          (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i")
1979                               (reg:SI TILEPRO_NETORDER_REG)]
1980                              UNSPEC_NETWORK_RECEIVE)
1981          (match_operand:SI 2 "reg_or_cint_operand" "I,rO")))
1982    (clobber (reg:SI TILEPRO_NETORDER_REG))]
1983   ""
1984   "@
1985    <insn>i<u>\t%0, %N1, %2
1986    <insn><u>\t%0, %N1, %r2")
1988 (define_insn "*netreg_binop_from_to_network"
1989   [(unspec_volatile:SI
1990     [(match_operand:SI 0 "netreg_operand" "i,i")
1991      (binop_with_imm:SI
1992       (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i")
1993                            (reg:SI TILEPRO_NETORDER_REG)]
1994                           UNSPEC_NETWORK_RECEIVE)
1995       (match_operand:SI 2 "reg_or_cint_operand" "I,rO"))
1996      (reg:SI TILEPRO_NETORDER_REG)]
1997     UNSPEC_NETWORK_SEND)
1998    (clobber (reg:SI TILEPRO_NETORDER_REG))
1999    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2000   ""
2001   "@
2002    <insn>i<u>\t%N0, %N1, %2
2003    <insn><u>\t%N0, %N1, %r2")
2005 (define_insn "*netreg_unop_to_network"
2006   [(unspec_volatile:SI [(match_operand:SI 0 "netreg_operand" "i")
2007                         (unop:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))
2008                         (reg:SI TILEPRO_NETORDER_REG)]
2009                        UNSPEC_NETWORK_SEND)
2010    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2011   ""
2012   "<insn>\t%N0, %r1"
2013   [(set_attr "type" "Y0")])
2015 (define_insn "*netreg_unop_from_network"
2016   [(set (match_operand:SI 0 "register_operand" "=r")
2017         (unop:SI
2018          (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2019                               (reg:SI TILEPRO_NETORDER_REG)]
2020                              UNSPEC_NETWORK_RECEIVE)))
2021    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2022   ""
2023   "<insn>\t%0, %N1"
2024   [(set_attr "type" "Y0")])
2026 (define_insn "*netreg_unop_from_to_network"
2027   [(unspec_volatile:SI
2028     [(match_operand:SI 0 "netreg_operand" "i")
2029      (unop:SI
2030       (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2031                            (reg:SI TILEPRO_NETORDER_REG)]
2032                           UNSPEC_NETWORK_RECEIVE))
2033      (reg:SI TILEPRO_NETORDER_REG)]
2034     UNSPEC_NETWORK_SEND)
2035    (clobber (reg:SI TILEPRO_NETORDER_REG))
2036    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2037   ""
2038   "<insn>\t%N0, %N1"
2039   [(set_attr "type" "Y0")])
2041 (define_insn "*netreg_sadh_u_from_network0"
2042   [(set (match_operand:SI 0 "register_operand" "=r")
2043         (unspec:SI
2044          [(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2045                                (reg:SI TILEPRO_NETORDER_REG)]
2046                               UNSPEC_NETWORK_RECEIVE)
2047           (match_operand:SI 2 "reg_or_0_operand" "rO")]
2048          UNSPEC_INSN_SADH_U))
2049    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2050   ""
2051   "sadh_u\t%0, %N1, %r2"
2052   [(set_attr "type" "X0_2cycle")])
2054 (define_insn "*netreg_sadh_u_from_network1"
2055   [(set (match_operand:SI 0 "register_operand" "=r")
2056         (unspec:SI
2057          [(match_operand:SI 1 "reg_or_0_operand" "rO")
2058           (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
2059                                (reg:SI TILEPRO_NETORDER_REG)]
2060                               UNSPEC_NETWORK_RECEIVE)]
2061          UNSPEC_INSN_SADH_U))
2062    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2063   ""
2064   "sadh_u\t%0, %r1, %N2"
2065   [(set_attr "type" "X0_2cycle")])
2067 (define_insn "*netreg_sadah_u_from_network0"
2068   [(set (match_operand:SI 0 "register_operand" "=r")
2069         (unspec:SI
2070          [(match_operand:SI 1 "reg_or_0_operand" "0")
2071           (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
2072                                (reg:SI TILEPRO_NETORDER_REG)]
2073                               UNSPEC_NETWORK_RECEIVE)
2074           (match_operand:SI 3 "reg_or_0_operand" "rO")]
2075          UNSPEC_INSN_SADAH_U))
2076    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2077   ""
2078   "sadah_u\t%0, %N2, %r3"
2079   [(set_attr "type" "X0_2cycle")])
2081 (define_insn "*netreg_sadah_u_from_network1"
2082   [(set (match_operand:SI 0 "register_operand" "=r")
2083         (unspec:SI
2084          [(match_operand:SI 1 "reg_or_0_operand" "0")
2085           (match_operand:SI 2 "reg_or_0_operand" "rO")
2086           (unspec_volatile:SI [(match_operand:SI 3 "netreg_operand" "i")
2087                                (reg:SI TILEPRO_NETORDER_REG)]
2088                               UNSPEC_NETWORK_RECEIVE)]
2089          UNSPEC_INSN_SADAH_U))
2090    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2091   ""
2092   "sadah_u\t%0, %r2, %N3"
2093   [(set_attr "type" "X0_2cycle")])
2095 (define_code_iterator mm_combiner [ior xor plus])
2097 ;; This doesn't seem to match -- too complex for 'combine'?
2099 ;; (define_insn "*netreg_mm_to_network"
2100 ;;   [(unspec_volatile:SI
2101 ;;     [(match_operand:SI 0 "netreg_operand" "i")
2102 ;;      (mm_combiner:SI
2103 ;;       (and:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2104 ;;               (match_operand:SI 3 "const_int_operand" "n"))
2105 ;;       (and:SI (match_operand:SI 2 "reg_or_0_operand" "rO")
2106 ;;               (match_operand:SI 4 "const_int_operand" "n")))]
2107 ;;     UNSPEC_NETWORK_SEND)]
2108 ;;   "tilepro_bitfield_operand_p (INTVAL (operands[3]), NULL, NULL)
2109 ;;    && INTVAL (operands[3]) == ~INTVAL (operands[4])"
2110 ;;   "mm\t%N0, %r1, %r2, %M3"
2111 ;;   [(set_attr "type" "X01")])
2113 ;; FIXME: the straight forward versions which do not include the
2114 ;; subreg:QI does not match for some unknown reason.
2115 (define_insn "*netreg_bbs_normal"
2116   [(set (pc)
2117         (if_then_else
2118          (ne (zero_extract:SI
2119               (subreg:QI 
2120                (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2121                                     (reg:SI TILEPRO_NETORDER_REG)]
2122                                    UNSPEC_NETWORK_RECEIVE) 0)
2123               (const_int 1)
2124               (const_int 0))
2125              (const_int 0))
2126          (label_ref (match_operand 0 "" ""))
2127          (pc)))
2128    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2129   ""
2130   { return tilepro_output_cbranch_with_opcode (insn, operands, "bbs", "bbns",
2131                                             1, 1); }
2132   [(set_attr "type" "X1_branch")])
2134 (define_insn "*netreg_bbc_normal"
2135   [(set (pc)
2136         (if_then_else
2137          (eq (zero_extract:SI
2138               (subreg:QI 
2139                (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2140                                     (reg:SI TILEPRO_NETORDER_REG)]
2141                                    UNSPEC_NETWORK_RECEIVE) 0)
2142               (const_int 1)
2143               (const_int 0))
2144              (const_int 0))
2145          (label_ref (match_operand 0 "" ""))
2146          (pc)))
2147    (clobber (reg:SI TILEPRO_NETORDER_REG))]
2148   ""
2149   { return tilepro_output_cbranch_with_opcode (insn, operands, "bbns", "bbns",
2150                                             1, 1); }
2151   [(set_attr "type" "X1_branch")])
2155 ;; "__insn" Intrinsics (some expand directly to normal patterns above).
2158 (define_insn "insn_addlis"
2159   [(set (match_operand:SI 0 "register_operand" "=r")
2160         (unspec_volatile:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
2161                              (match_operand:SI 2 "s16bit_cint_operand" "i")] 
2162                             UNSPEC_INSN_ADDLIS))]
2163   ""
2164   "addlis\t%0, %r1, %2"
2165   [(set_attr "type" "X01")])
2167 (define_insn "insn_auli"
2168   [(set (match_operand:SI 0 "register_operand" "=r")
2169         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
2170                     (match_operand:SI 2 "s16bit_cint_operand" "i")] 
2171                    UNSPEC_INSN_AULI))]
2172   ""
2173   "auli\t%0, %r1, %2"
2174   [(set_attr "type" "X01")])
2176 (define_insn "insn_drain"
2177   [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_DRAIN)]
2178   ""
2179   "drain"
2180   [(set_attr "type" "cannot_bundle")])
2182 (define_insn "insn_icoh"
2183   [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] 
2184                          UNSPEC_INSN_ICOH)]
2185   ""
2186   "icoh\t%r0"
2187   [(set_attr "type" "X1")])
2190 (define_insn "insn_info"
2191   [(unspec_volatile:VOID [(match_operand:SI 0 "s8bit_cint_operand" "i")] 
2192                          UNSPEC_INSN_INFO)]
2193   ""
2194   "info\t%0")
2196 (define_insn "insn_infol"
2197   [(unspec_volatile:VOID [(match_operand:SI 0 "s16bit_cint_operand" "i")] 
2198                          UNSPEC_INSN_INFOL)]
2199   ""
2200   "infol\t%0"
2201   [(set_attr "type" "X01")])
2203 ;; loads
2205 (define_expand "insn_<load>"
2206   [(set (match_operand:SI 0 "register_operand" "")
2207         (sign_extend:SI
2208          (mem:I12MODE (match_operand:SI 1 "address_operand" ""))))]
2209   "")
2211 (define_expand "insn_<load>_u"
2212   [(set (match_operand:SI 0 "register_operand" "")
2213         (zero_extend:SI
2214          (mem:I12MODE (match_operand:SI 1 "address_operand" ""))))]
2215   "")
2217 (define_insn "insn_<load>add"
2218   [(set (match_operand:SI 1 "register_operand" "=r")
2219         (plus:SI (match_operand:SI 3 "register_operand" "1")
2220                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2221    (set (match_operand:SI 0 "register_operand" "=r")
2222         (sign_extend:SI (mem:I12MODE (match_dup 3))))]
2223   ""
2224   "<load>add\t%0, %1, %2"
2225   [(set_attr "type" "X1_2cycle")])
2227 (define_insn "insn_<load>add_u"
2228   [(set (match_operand:SI 1 "register_operand" "=r")
2229         (plus:SI (match_operand:SI 3 "register_operand" "1")
2230                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2231    (set (match_operand:SI 0 "register_operand" "=r")
2232         (zero_extend:SI (mem:I12MODE (match_dup 3))))]
2233   ""
2234   "<load>add_u\t%0, %1, %2"
2235   [(set_attr "type" "X1_2cycle")])
2237 (define_expand "insn_lw"
2238   [(set (match_operand:SI 0 "register_operand" "")
2239         (mem:SI (match_operand:SI 1 "address_operand" "")))]
2240   "")
2242 (define_insn "insn_lwadd"
2243   [(set (match_operand:SI 1 "register_operand" "=r")
2244         (plus:SI (match_operand:SI 3 "register_operand" "1")
2245                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2246    (set (match_operand:SI 0 "register_operand" "=r")
2247         (mem:SI (match_dup 3)))]
2248   ""
2249   "lwadd\t%0, %1, %2"
2250   [(set_attr "type" "X1_2cycle")])
2252 (define_insn "insn_lwadd_na"
2253   [(set (match_operand:SI 1 "register_operand" "=r")
2254         (plus:SI (match_operand:SI 3 "register_operand" "1")
2255                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2256    (set (match_operand:SI 0 "register_operand" "=r")
2257         (mem:SI (and:SI (match_dup 3) (const_int -4))))]
2258   ""
2259   "lwadd_na\t%0, %1, %2"
2260   [(set_attr "type" "X1_2cycle")])
2262 (define_insn "insn_lw_na"
2263   [(set (match_operand:SI 0 "register_operand" "=r")
2264         (mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO")
2265                         (const_int -4))))]
2266   ""
2267   "lw_na\t%0, %r1"
2268   [(set_attr "type" "X1_2cycle")])
2270 ;; L2 hits
2272 (define_insn "insn_<load>_L2"
2273   [(set (match_operand:SI 0 "register_operand" "=r")
2274         (sign_extend:SI
2275          (unspec:I12MODE
2276           [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
2277           UNSPEC_LATENCY_L2)))]
2278   ""
2279   "<load>\t%0, %r1"
2280   [(set_attr "type" "Y2_L2")])
2282 (define_insn "insn_<load>_u_L2"
2283   [(set (match_operand:SI 0 "register_operand" "=r")
2284         (zero_extend:SI
2285          (unspec:I12MODE
2286           [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
2287           UNSPEC_LATENCY_L2)))]
2288   ""
2289   "<load>_u\t%0, %r1"
2290   [(set_attr "type" "Y2_L2")])
2292 (define_insn "insn_<load>add_L2"
2293   [(set (match_operand:SI 1 "register_operand" "=r")
2294         (plus:SI (match_operand:SI 3 "register_operand" "1")
2295                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2296    (set (match_operand:SI 0 "register_operand" "=r")
2297         (sign_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
2298                                         UNSPEC_LATENCY_L2)))]
2299   ""
2300   "<load>add\t%0, %1, %2"
2301   [(set_attr "type" "X1_L2")])
2303 (define_insn "insn_<load>add_u_L2"
2304   [(set (match_operand:SI 1 "register_operand" "=r")
2305         (plus:SI (match_operand:SI 3 "register_operand" "1")
2306                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2307    (set (match_operand:SI 0 "register_operand" "=r")
2308         (zero_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
2309                                         UNSPEC_LATENCY_L2)))]
2310   ""
2311   "<load>add_u\t%0, %1, %2"
2312   [(set_attr "type" "X1_L2")])
2314 (define_insn "insn_lwadd_L2"
2315   [(set (match_operand:SI 1 "register_operand" "=r")
2316         (plus:SI (match_operand:SI 3 "register_operand" "1")
2317                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2318    (set (match_operand:SI 0 "register_operand" "=r")
2319         (unspec:SI [(mem:SI (match_dup 3))] UNSPEC_LATENCY_L2))]
2320   ""
2321   "lwadd\t%0, %1, %2"
2322   [(set_attr "type" "X1_L2")])
2324 (define_insn "insn_lwadd_na_L2"
2325   [(set (match_operand:SI 1 "register_operand" "=r")
2326         (plus:SI (match_operand:SI 3 "register_operand" "1")
2327                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2328    (set (match_operand:SI 0 "register_operand" "=r")
2329         (unspec:SI [(mem:SI (and:SI (match_dup 3) (const_int -4)))]
2330                    UNSPEC_LATENCY_L2))]
2331   ""
2332   "lwadd_na\t%0, %1, %2"
2333   [(set_attr "type" "X1_L2")])
2335 (define_insn "insn_lw_na_L2"
2336   [(set (match_operand:SI 0 "register_operand" "=r")
2337         (unspec:SI [(mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO")
2338                                     (const_int -4)))]
2339                    UNSPEC_LATENCY_L2))]
2340   ""
2341   "lw_na\t%0, %r1"
2342   [(set_attr "type" "X1_L2")])
2344 (define_insn "insn_lw_L2"
2345   [(set (match_operand:SI 0 "register_operand" "=r")
2346         (unspec:SI [(mem:SI (match_operand:SI 1 "address_operand" "rO"))]
2347                    UNSPEC_LATENCY_L2))]
2348   ""
2349   "lw\t%0, %r1"
2350   [(set_attr "type" "Y2_L2")])
2352 ;; L2 miss
2354 (define_insn "insn_<load>_miss"
2355   [(set (match_operand:SI 0 "register_operand" "=r")
2356         (sign_extend:SI
2357          (unspec:I12MODE
2358           [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
2359           UNSPEC_LATENCY_MISS)))]
2360   ""
2361   "<load>\t%0, %r1"
2362   [(set_attr "type" "Y2_miss")])
2364 (define_insn "insn_<load>_u_miss"
2365   [(set (match_operand:SI 0 "register_operand" "=r")
2366         (zero_extend:SI
2367          (unspec:I12MODE
2368           [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
2369           UNSPEC_LATENCY_MISS)))]
2370   ""
2371   "<load>_u\t%0, %r1"
2372   [(set_attr "type" "Y2_miss")])
2374 (define_insn "insn_<load>add_miss"
2375   [(set (match_operand:SI 1 "register_operand" "=r")
2376         (plus:SI (match_operand:SI 3 "register_operand" "1")
2377                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2378    (set (match_operand:SI 0 "register_operand" "=r")
2379         (sign_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
2380                                         UNSPEC_LATENCY_MISS)))]
2381   ""
2382   "<load>add\t%0, %1, %2"
2383   [(set_attr "type" "X1_miss")])
2385 (define_insn "insn_<load>add_u_miss"
2386   [(set (match_operand:SI 1 "register_operand" "=r")
2387         (plus:SI (match_operand:SI 3 "register_operand" "1")
2388                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2389    (set (match_operand:SI 0 "register_operand" "=r")
2390         (zero_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
2391                                         UNSPEC_LATENCY_MISS)))]
2392   ""
2393   "<load>add_u\t%0, %1, %2"
2394   [(set_attr "type" "X1_miss")])
2396 (define_insn "insn_lwadd_miss"
2397   [(set (match_operand:SI 1 "register_operand" "=r")
2398         (plus:SI (match_operand:SI 3 "register_operand" "1")
2399                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2400    (set (match_operand:SI 0 "register_operand" "=r")
2401         (unspec:SI [(mem:SI (match_dup 3))] UNSPEC_LATENCY_MISS))]
2402   ""
2403   "lwadd\t%0, %1, %2"
2404   [(set_attr "type" "X1_miss")])
2406 (define_insn "insn_lwadd_na_miss"
2407   [(set (match_operand:SI 1 "register_operand" "=r")
2408         (plus:SI (match_operand:SI 3 "register_operand" "1")
2409                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2410    (set (match_operand:SI 0 "register_operand" "=r")
2411         (unspec:SI [(mem:SI (and:SI (match_dup 3) (const_int -4)))]
2412                    UNSPEC_LATENCY_MISS))]
2413   ""
2414   "lwadd_na\t%0, %1, %2"
2415   [(set_attr "type" "X1_miss")])
2417 (define_insn "insn_lw_na_miss"
2418   [(set (match_operand:SI 0 "register_operand" "=r")
2419         (unspec:SI [(mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO")
2420                                     (const_int -4)))]
2421                    UNSPEC_LATENCY_MISS))]
2422   ""
2423   "lw_na\t%0, %r1"
2424   [(set_attr "type" "X1_miss")])
2426 (define_insn "insn_lw_miss"
2427   [(set (match_operand:SI 0 "register_operand" "=r")
2428         (unspec:SI [(mem:SI (match_operand:SI 1 "address_operand" "rO"))]
2429                    UNSPEC_LATENCY_MISS))]
2430   ""
2431   "lw\t%0, %r1"
2432   [(set_attr "type" "Y2_miss")])
2434 ;; end loads
2436 (define_insn "insn_mfspr"
2437   [(set (match_operand:SI 0 "register_operand" "=r")
2438         (unspec_volatile:SI [(match_operand:SI 1 "u15bit_cint_operand" "i")]
2439                             UNSPEC_INSN_MFSPR))
2440    (clobber (mem:BLK (const_int 0)))]
2441   ""
2442   "mfspr\t%0, %1"
2443   [(set_attr "type" "X1")])
2445 (define_insn "*mm"
2446   [(set (match_operand:SI 0 "register_operand" "=r")
2447         (mm_combiner:SI
2448          (and:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2449                  (match_operand:SI 3 "const_int_operand" "n"))
2450          (and:SI (match_operand:SI 2 "reg_or_0_operand" "rO")
2451                  (match_operand:SI 4 "const_int_operand" "n"))))]
2452   "tilepro_bitfield_operand_p (INTVAL (operands[3]), NULL, NULL)
2453    && INTVAL (operands[3]) == ~INTVAL (operands[4])"
2454   "mm\t%0, %r1, %r2, %M3"
2455   [(set_attr "type" "X01")])
2457 (define_expand "insn_mm"
2458   [(set (match_operand:SI 0 "register_operand" "")
2459         (ior:SI
2460          (and:SI (match_operand:SI 1 "reg_or_cint_operand" "")
2461                  (match_operand:SI 3 "u5bit_cint_operand" ""))
2462          (and:SI (match_operand:SI 2 "reg_or_cint_operand" "")
2463                  (match_operand:SI 4 "u5bit_cint_operand" ""))))]
2464   ""
2466   int first, last, i;
2467   HOST_WIDE_INT mask;
2469   first = INTVAL (operands[3]) & 31;
2470   last = INTVAL (operands[4]) & 31;
2472   if (((last + 1) & 31) == first)
2473     {
2474       /* Handle pathological case of a mask that includes only the
2475          first operand. The reordering code below can't handle this. */
2476       emit_move_insn (operands[0], operands[1]);
2477       DONE;
2478     }
2480   /* Canonicalize order by putting constant second, if any. */
2481   if (CONST_INT_P (operands[1]))
2482     {
2483       int tmp_first;
2485       rtx tmp = operands[1];
2486       operands[1] = operands[2];
2487       operands[2] = tmp;
2489       /* Invert the bit range. */
2490       tmp_first = first;
2491       first = (last + 1) & 31;
2492       last = (tmp_first - 1) & 31;
2493     }
2495   /* Convert the first/last bit range into a bit mask. */
2496   mask = 0;
2498   for (i = first; ; i = (i + 1) & 31)
2499     {
2500       mask |= ((HOST_WIDE_INT)1) << i;
2501       if (i == last)
2502         break;
2503     }
2505   mask = trunc_int_for_mode (mask, SImode);
2507   operands[1] = force_reg (SImode, operands[1]);
2508   operands[3] = GEN_INT (mask);
2509   operands[4] = GEN_INT (~mask);
2511   if (CONST_INT_P (operands[2]))
2512     {
2513       HOST_WIDE_INT inserted_bits = INTVAL (operands[2]) & ~mask;
2515       if (inserted_bits == 0)
2516         {
2517           /* All inserted bits are zero. Use a bitwise AND. */
2518           emit_insn (gen_andsi3 (operands[0], operands[1], operands[3]));
2519           DONE;
2520         }
2521       else if (inserted_bits == ~mask)
2522         {
2523           /* All inserted bits are ones. Use a bitwise IOR if we can. */
2524           if (satisfies_constraint_I (operands[4]))
2525             {
2526               emit_insn (gen_iorsi3 (operands[0], operands[1], operands[4]));
2527               DONE;
2528             }
2530           /* Canonicalize to inserting -1 when setting all masked bits
2531              to 1, to facilitate CSE. */
2532           inserted_bits = -1;
2533         }
2535       /* Sign extend the inserted bits to make them easier to materialize
2536          in a register, but only if the inserted bits (~mask) do not already
2537          include the high bits. */
2538       if ((~mask & 0x80000000) == 0)
2539         {
2540           int shift = sizeof (HOST_WIDE_INT) * 8 - first;
2541           inserted_bits = (inserted_bits << shift) >> shift;
2542         }
2544       operands[2] = GEN_INT (inserted_bits);
2545     }
2547   operands[2] = force_reg (SImode, operands[2]);
2550 (define_insn "insn_movelis"
2551   [(set (match_operand:SI 0 "register_operand" "=r")
2552         (unspec_volatile:SI [(match_operand:SI 1 "s16bit_cint_operand" "i")] 
2553                             UNSPEC_INSN_MOVELIS))]
2554   ""
2555   "movelis\t%0, %1"
2556   [(set_attr "type" "X01")])
2558 (define_insn "insn_mtspr"
2559   [(unspec_volatile:SI [(match_operand:SI 0 "u15bit_cint_operand" "i")
2560                         (match_operand:SI 1 "reg_or_0_operand" "rO")]
2561                        UNSPEC_INSN_MTSPR)
2562    (clobber (mem:BLK (const_int 0)))]
2563   ""
2564   "mtspr\t%0, %r1"
2565   [(set_attr "type" "X1")])
2567 (define_expand "insn_prefetch"
2568   [(prefetch (match_operand:SI 0 "address_operand" "")
2569              (const_int 0)
2570              (const_int 2))])
2572 (define_expand "insn_prefetch_L1"
2573   [(use (match_operand:SI 0 "address_operand" ""))]
2574   ""
2576   /* Generate a volatile byte load to a dummy register. */
2577   rtx mem = gen_rtx_MEM (QImode, operands[0]);
2578   MEM_VOLATILE_P (mem) = 1;
2580   emit_insn (gen_zero_extendqisi2 (gen_reg_rtx (SImode), mem));
2581   DONE;
2584 (define_expand "insn_s1a"
2585   [(set (match_operand:SI 0 "register_operand" "")
2586         (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
2587                           (const_int 2))
2588                  (match_operand:SI 2 "reg_or_0_operand" "")))]
2589   "")
2591 (define_expand "insn_s2a"
2592   [(set (match_operand:SI 0 "register_operand" "")
2593         (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
2594                           (const_int 4))
2595                  (match_operand:SI 2 "reg_or_0_operand" "")))]
2596   "")
2598 (define_expand "insn_s3a"
2599   [(set (match_operand:SI 0 "register_operand" "")
2600         (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
2601                           (const_int 8))
2602                  (match_operand:SI 2 "reg_or_0_operand" "")))]
2603   "")
2605 (define_expand "insn_<store>"
2606   [(set (mem:I12MODE (match_operand:SI 0 "address_operand" ""))
2607         (match_operand:SI 1 "reg_or_0_operand" ""))]
2608   ""
2610   operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], SImode, 0);
2613 (define_expand "insn_sw"
2614   [(set (mem:SI (match_operand:SI 0 "address_operand" ""))
2615         (match_operand:SI 1 "reg_or_0_operand" ""))]
2616   "")
2618 (define_expand "insn_<store>add"
2619   [(parallel
2620     [(set (match_operand:SI 0 "register_operand" "")
2621           (plus:SI (match_operand:SI 3 "register_operand" "")
2622                    (match_operand:SI 2 "s8bit_cint_operand" "")))
2623      (set (mem:I12MODE (match_dup 3))
2624           (match_operand:SI 1 "reg_or_0_operand" ""))])]
2625   ""
2627   operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], SImode, 0);
2630 (define_insn "*insn_<store>add"
2631   [(set (match_operand:SI 0 "register_operand" "=r")
2632         (plus:SI (match_operand:SI 3 "register_operand" "0")
2633                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2634    (set (mem:I12MODE (match_dup 3))
2635         (match_operand:I12MODE 1 "reg_or_0_operand" "rO"))]
2636   ""
2637   "<store>add\t%0, %r1, %2"
2638   [(set_attr "type" "X1")])
2640 (define_insn "insn_swadd"
2641   [(set (match_operand:SI 0 "register_operand" "=r")
2642         (plus:SI (match_operand:SI 3 "register_operand" "0")
2643                  (match_operand:SI 2 "s8bit_cint_operand" "i")))
2644    (set (mem:SI (match_dup 3))
2645         (match_operand:SI 1 "reg_or_0_operand" "rO"))]
2646   ""
2647   "swadd\t%0, %r1, %2"
2648   [(set_attr "type" "X1")])
2650 (define_insn "insn_wh64"
2651   [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")]
2652                          UNSPEC_INSN_WH64)
2653    (clobber (mem:BLK (const_int 0)))]
2654   ""
2655   "wh64\t%r0"
2656   [(set_attr "type" "X1")])
2658 (define_insn "insn_tns"
2659   [(set (match_operand:SI 0 "register_operand" "=r")
2660         (mem:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))
2661    (set (mem:SI (match_dup 1)) (const_int 1))]
2662   ""
2663   "tns\t%0, %1"
2664   [(set_attr "type" "X1")])
2666 ;; insn_addb
2667 ;; insn_addib
2668 ;; insn_maxb_u
2669 ;; insn_maxib_u
2670 ;; insn_minb_u
2671 ;; insn_minib_u
2672 ;; insn_seqb
2673 ;; insn_seqib
2674 ;; insn_sltb
2675 ;; insn_sltib
2676 ;; insn_sltb_u
2677 ;; insn_sltib_u
2678 (define_insn "<optab>v4qi3"
2679   [(set (match_operand:V4QI 0 "register_operand" "=r,r")
2680         (v1op_immed:V4QI
2681          (match_operand:V4QI 1 "reg_or_0_operand" "<comm>rO,rO")
2682          (match_operand:V4QI 2 "reg_or_v4s8bit_operand" "W,rO")))]
2683   ""
2684   "@
2685    <insn>ib<u>\t%0, %r1, %j2
2686    <insn>b<u>\t%0, %r1, %r2"
2687   [(set_attr "type" "X01,X01")])
2689 (define_expand "insn_<insn>b<u>"
2690   [(set (match_operand:SI 0 "register_operand" "")
2691         (v1op_immed:V4QI
2692          (match_operand:SI 1 "reg_or_0_operand" "")
2693          (match_operand:SI 2 "reg_or_0_operand" "")))]
2694   ""
2696   tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
2697                                        V4QImode, operands[1], operands[2], true);
2698   DONE;
2701 (define_expand "insn_<insn>ib<u>"
2702   [(set (match_operand:SI 0 "register_operand" "")
2703         (v1op_immed:V4QI
2704          (match_operand:SI 1 "reg_or_0_operand" "")
2705          (match_operand:SI 2 "s8bit_cint_operand" "")))]
2706   ""
2708   /* Tile out immediate and expand to general case. */
2709   rtx n = tilepro_simd_int (operands[2], QImode);
2710   tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
2711                                        V4QImode, operands[1], n, true);
2712   DONE;
2715 ;; insn_shlb
2716 ;; insn_shlib
2717 ;; insn_shrb
2718 ;; insn_shrib
2719 ;; insn_srab
2720 ;; insn_sraib
2721 (define_insn "<optab>v4qi3"
2722   [(set (match_operand:V4QI 0 "register_operand" "=r,r")
2723         (any_shift:V4QI
2724          (match_operand:V4QI 1 "reg_or_0_operand" "rO,rO")
2725          (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
2726   ""
2727   "@
2728    <insn>ib<u>\t%0, %r1, %2
2729    <insn>b<u>\t%0, %r1, %r2"
2730   [(set_attr "type" "X01,X01")])
2732 (define_expand "insn_<insn>b<u>"
2733   [(set (match_operand:SI 0 "register_operand" "")
2734         (any_shift:V4QI
2735          (match_operand:SI 1 "reg_or_0_operand" "")
2736          (match_operand:SI 2 "reg_or_u5bit_operand" "")))]
2737   ""
2739   tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
2740                                     V4QImode, operands[1], operands[2], false);
2741   DONE;
2744 ;; insn_addh
2745 ;; insn_addih
2746 ;; insn_maxh
2747 ;; insn_maxih
2748 ;; insn_minh
2749 ;; insn_minih
2750 ;; insn_seqh
2751 ;; insn_seqih
2752 ;; insn_slth
2753 ;; insn_sltih
2754 ;; insn_slth_u
2755 ;; insn_sltih_u
2756 (define_insn "<optab>v2hi3"
2757   [(set (match_operand:V2HI 0 "register_operand" "=r,r")
2758         (v2op_immed:V2HI
2759          (match_operand:V2HI 1 "reg_or_0_operand" "<comm>rO,rO")
2760          (match_operand:V2HI 2 "reg_or_v2s8bit_operand" "Y,rO")))]
2761   ""
2762   "@
2763    <insn>ih<u>\t%0, %r1, %j2
2764    <insn>h<u>\t%0, %r1, %r2"
2765   [(set_attr "type" "X01,X01")])
2767 (define_expand "insn_<insn>h<u>"
2768   [(set (match_operand:SI 0 "register_operand" "")
2769         (v2op_immed:V2HI
2770          (match_operand:SI 1 "reg_or_0_operand" "")
2771          (match_operand:SI 2 "reg_or_0_operand" "")))]
2772   ""
2774   tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
2775                                        V2HImode, operands[1], operands[2], true);
2776   DONE;
2779 (define_expand "insn_<insn>ih<u>"
2780   [(set (match_operand:SI 0 "register_operand" "")
2781         (v2op_immed:V2HI
2782          (match_operand:SI 1 "reg_or_0_operand" "")
2783          (match_operand:SI 2 "s8bit_cint_operand" "")))]
2784   ""
2786   /* Tile out immediate and expand to general case. */
2787   rtx n = tilepro_simd_int (operands[2], HImode);
2788   tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
2789                                        V2HImode, operands[1], n, true);
2790   DONE;
2793 ;; insn_shlh
2794 ;; insn_shlih
2795 ;; insn_shrh
2796 ;; insn_shrih
2797 ;; insn_srah
2798 ;; insn_sraih
2799 (define_insn "<optab>v2hi3"
2800   [(set (match_operand:V2HI 0 "register_operand" "=r,r")
2801         (any_shift:V2HI
2802          (match_operand:V2HI 1 "reg_or_0_operand" "rO,rO")
2803          (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
2804   ""
2805   "@
2806    <insn>ih<u>\t%0, %r1, %2
2807    <insn>h<u>\t%0, %r1, %r2"
2808   [(set_attr "type" "X01,X01")])
2810 (define_expand "insn_<insn>h<u>"
2811   [(set (match_operand:SI 0 "register_operand" "")
2812         (any_shift:V2HI
2813          (match_operand:SI 1 "reg_or_0_operand" "")
2814          (match_operand:SI 2 "reg_or_0_operand" "")))]
2815   ""
2817   tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
2818                                        V2HImode, operands[1], operands[2], false);
2819   DONE;
2822 ;; insn_addbs_u
2823 ;; insn_subbs_u
2824 ;; insn_subb
2825 ;; insn_slteb
2826 ;; insn_slteb_u
2827 ;; insn_sneb
2828 (define_insn "<optab>v4qi3"
2829   [(set (match_operand:V4QI 0 "register_operand" "=r")
2830         (v1op:V4QI
2831          (match_operand:V4QI 1 "reg_or_0_operand" "<comm>rO")
2832          (match_operand:V4QI 2 "reg_or_0_operand" "rO")))]
2833   ""
2834   "<insn>b<u>\t%0, %r1, %r2"
2835   [(set_attr "type" "X01")])
2837 (define_expand "insn_<insn>b<u>"
2838   [(set (match_operand:SI 0 "register_operand" "")
2839         (v1op:V4QI
2840          (match_operand:SI 1 "reg_or_0_operand" "")
2841          (match_operand:SI 2 "reg_or_0_operand" "")))]
2842   ""
2844   tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
2845                                        V4QImode, operands[1], operands[2], true);
2846   DONE;
2849 ;; insn_addhs
2850 ;; insn_subhs
2851 ;; insn_subh
2852 ;; insn_slteh
2853 ;; insn_slteh_u
2854 ;; insn_sneh
2855 (define_insn "<optab>v2hi3"
2856   [(set (match_operand:V2HI 0 "register_operand" "=r")
2857         (v2op:V2HI
2858          (match_operand:V2HI 1 "reg_or_0_operand" "<comm>rO")
2859          (match_operand:V2HI 2 "reg_or_0_operand" "rO")))]
2860   ""
2861   "<insn>h<u>\t%0, %r1, %r2"
2862   [(set_attr "type" "X01")])
2864 (define_expand "insn_<insn>h<u>"
2865   [(set (match_operand:SI 0 "register_operand" "")
2866         (v2op:V2HI
2867          (match_operand:SI 1 "reg_or_0_operand" "")
2868          (match_operand:SI 2 "reg_or_0_operand" "")))]
2869   ""
2871   tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
2872                                        V2HImode, operands[1], operands[2], true);
2873   DONE;
2876 ;; insn_inthb
2878 ;; Byte ordering of these vectors is endian dependent.  We concat
2879 ;; right-to-left for little endian.  We concat and interleave in the
2880 ;; opposite way gcc's vector patterns work, so we need to reverse the
2881 ;; order of source operands.
2883 ;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
2884 ;; => {A3,A2,A1,A0,B3,B2,B1,B0}
2885 ;; => {A3,B3,A2,B2}
2886 (define_insn "vec_interleave_highv4qi"
2887   [(set (match_operand:V4QI 0 "register_operand" "=r")
2888         (vec_select:V4QI
2889          (vec_concat:V8QI (match_operand:V4QI 1 "reg_or_0_operand" "rO")
2890                           (match_operand:V4QI 2 "reg_or_0_operand" "rO"))
2891          (parallel [(const_int 2) (const_int 6)
2892                     (const_int 3) (const_int 7)])))]
2893   ""
2894   "inthb\t%0, %r2, %r1"
2895   [(set_attr "type" "X01")])
2897 (define_expand "insn_inthb"
2898   [(match_operand:SI 0 "register_operand" "")
2899    (match_operand:SI 1 "reg_or_0_operand" "")
2900    (match_operand:SI 2 "reg_or_0_operand" "")]
2901   ""
2903   /* Our instruction interleaves opposite of the way vec_interleave
2904      works, so we need to reverse the source operands.  */
2905   tilepro_expand_builtin_vector_binop (gen_vec_interleave_highv4qi, V4QImode,
2906                                        operands[0], V4QImode, operands[2],
2907                                        operands[1], true);
2908   DONE;
2911 ;; insn_intlb
2912 ;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
2913 ;; => {A3,A2,A1,A0,B3,B2,B1,B0}
2914 ;; => {A1,B1,A0,B0}
2915 (define_insn "vec_interleave_lowv4qi"
2916   [(set (match_operand:V4QI 0 "register_operand" "=r")
2917         (vec_select:V4QI
2918          (vec_concat:V8QI (match_operand:V4QI 1 "reg_or_0_operand" "rO")
2919                           (match_operand:V4QI 2 "reg_or_0_operand" "rO"))
2920          (parallel [(const_int 0) (const_int 4)
2921                     (const_int 1) (const_int 5)])))]
2922   ""
2923   "intlb\t%0, %r2, %r1"
2924   [(set_attr "type" "X01")])
2926 (define_expand "insn_intlb"
2927   [(match_operand:SI 0 "register_operand" "")
2928    (match_operand:SI 1 "reg_or_0_operand" "")
2929    (match_operand:SI 2 "reg_or_0_operand" "")]
2930   ""
2932   /* Our instruction interleaves opposite of the way vec_interleave
2933      works, so we need to reverse the source operands.  */
2934   tilepro_expand_builtin_vector_binop (gen_vec_interleave_lowv4qi, V4QImode,
2935                                        operands[0], V4QImode, operands[2],
2936                                        operands[1], true);
2937   DONE;
2940 ;; insn_inthh
2941 ;;    {B1,B0} {A1,A0}
2942 ;; => {A1,A0,B1,B0}
2943 ;; => {A1,B1}
2944 (define_insn "vec_interleave_highv2hi"
2945   [(set (match_operand:V2HI 0 "register_operand" "=r")
2946         (vec_select:V2HI
2947          (vec_concat:V4HI (match_operand:V2HI 1 "reg_or_0_operand" "rO")
2948                           (match_operand:V2HI 2 "reg_or_0_operand" "rO"))
2949          (parallel [(const_int 1) (const_int 3)])))]
2950   ""
2951   "inthh\t%0, %r2, %r1"
2952   [(set_attr "type" "X01")])
2954 (define_expand "insn_inthh"
2955   [(match_operand:SI 0 "register_operand" "")
2956    (match_operand:SI 1 "reg_or_0_operand" "")
2957    (match_operand:SI 2 "reg_or_0_operand" "")]
2958   ""
2960   /* Our instruction interleaves opposite of the way vec_interleave
2961      works, so we need to reverse the source operands.  */
2962   tilepro_expand_builtin_vector_binop (gen_vec_interleave_highv2hi, V2HImode,
2963                                        operands[0], V2HImode, operands[2],
2964                                        operands[1], true);
2965   DONE;
2968 ;; insn_intlh
2969 ;;    {B1,B0} {A1,A0}
2970 ;; => {A1,A0,B1,B0}
2971 ;; => {A0,B0}
2972 (define_insn "vec_interleave_lowv2hi"
2973   [(set (match_operand:V2HI 0 "register_operand" "=r")
2974         (vec_select:V2HI
2975          (vec_concat:V4HI (match_operand:V2HI 1 "reg_or_0_operand" "rO")
2976                           (match_operand:V2HI 2 "reg_or_0_operand" "rO"))
2977          (parallel [(const_int 0) (const_int 2)])))]
2978   ""
2979   "intlh\t%0, %r2, %r1"
2980   [(set_attr "type" "X01")])
2982 (define_expand "insn_intlh"
2983   [(match_operand:SI 0 "register_operand" "")
2984    (match_operand:SI 1 "reg_or_0_operand" "")
2985    (match_operand:SI 2 "reg_or_0_operand" "")]
2986   ""
2988   /* Our instruction interleaves opposite of the way vec_interleave
2989      works, so we need to reverse the source operands.  */
2990   tilepro_expand_builtin_vector_binop (gen_vec_interleave_lowv2hi, V2HImode,
2991                                        operands[0], V2HImode, operands[2],
2992                                        operands[1], true);
2993   DONE;
2996 ;; insn_packbs_u
2997 ;; insn_packlb
2998 ;;    {B1,B0} {A1,A0}
2999 ;; => {A1,A0,B1,B0}
3000 (define_insn "vec_pack_<pack_optab>_v2hi"
3001   [(set (match_operand:V4QI 0 "register_operand" "=r")
3002         (vec_concat:V4QI
3003          (v2pack:V2QI (match_operand:V2HI 1 "reg_or_0_operand" "rO"))
3004          (v2pack:V2QI (match_operand:V2HI 2 "reg_or_0_operand" "rO"))))]
3005   ""
3006   "<pack_insn>b<pack_u>\t%0, %r2, %r1"
3007   [(set_attr "type" "X01")])
3009 (define_expand "insn_<pack_insn>b<pack_u>"
3010   [(set (match_operand:SI 0 "register_operand" "")
3011         (vec_concat:V4QI
3012          (v2pack:V2QI (match_operand:SI 1 "reg_or_0_operand" ""))
3013          (v2pack:V2QI (match_operand:SI 2 "reg_or_0_operand" ""))))]
3014   ""
3016   /* Our instruction concats opposite of the way vec_pack works, so we
3017      need to reverse the source operands.  */
3018   tilepro_expand_builtin_vector_binop (gen_vec_pack_<pack_optab>_v2hi,
3019                                        V4QImode, operands[0],
3020                                        V2HImode, operands[2], operands[1], true);
3021   DONE;
3024 ;; insn_packhb
3025 ;;    {B1,B0} {A1,A0}
3026 ;; => {A1,A0,B1,B0}
3027 (define_insn "vec_pack_hipart_v2hi"
3028   [(set (match_operand:V4QI 0 "register_operand" "=r")
3029         (vec_concat:V4QI
3030          (truncate:V2QI
3031           (ashiftrt:V2HI (match_operand:V2HI 1 "reg_or_0_operand" "rO")
3032                          (const_int 8)))
3033          (truncate:V2QI
3034           (ashiftrt:V2HI (match_operand:V2HI 2 "reg_or_0_operand" "rO")
3035                          (const_int 8)))))]
3036   ""
3037   "packhb\t%0, %r2, %r1"
3038   [(set_attr "type" "X01")])
3040 (define_expand "insn_packhb"
3041   [(set (match_operand:SI 0 "register_operand" "")
3042         (vec_concat:V4QI
3043          (truncate:V2QI
3044           (ashiftrt:V2HI (match_operand:SI 2 "reg_or_0_operand" "")
3045                          (const_int 8)))
3046          (truncate:V2QI
3047           (ashiftrt:V2HI (match_operand:SI 1 "reg_or_0_operand" "")
3048                          (const_int 8)))))]
3049   ""
3051   /* Our instruction concats opposite of the way vec_pack works, so we
3052      need to reverse the source operands.  */
3053   tilepro_expand_builtin_vector_binop (gen_vec_pack_hipart_v2hi,
3054                                        V4QImode, operands[0],
3055                                        V2HImode, operands[2], operands[1], true);
3056   DONE;
3059 ;; insn_packhs
3060 ;;    {B0} {A0}
3061 ;; => {A0,B0}
3062 (define_insn "vec_pack_ssat_si"
3063   [(set (match_operand:V2HI 0 "register_operand" "=r")
3064         (vec_concat:V2HI
3065          (ss_truncate:HI (match_operand:SI 1 "reg_or_0_operand" "rO"))
3066          (ss_truncate:HI (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
3067   ""
3068   "packhs\t%0, %r2, %r1"
3069   [(set_attr "type" "X01")])
3071 (define_expand "insn_packhs"
3072   [(set (match_operand:SI 0 "register_operand" "")
3073         (vec_concat:V2HI
3074          (ss_truncate:HI (match_operand:SI 2 "reg_or_0_operand" ""))
3075          (ss_truncate:HI (match_operand:SI 1 "reg_or_0_operand" ""))))]
3076   ""
3078   /* Our instruction concats opposite of the way vec_pack works, so we
3079      need to reverse the source operands.  */
3080   tilepro_expand_builtin_vector_binop (gen_vec_pack_ssat_si,
3081                                        V2HImode, operands[0],
3082                                        SImode, operands[2], operands[1], true);
3083   DONE;
3086 ;; Rest of the intrinsics
3087 (define_insn "insn_adiffb_u"
3088   [(set (match_operand:SI 0 "register_operand" "=r")
3089         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3090                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3091                    UNSPEC_INSN_ADIFFB_U))]
3092   ""
3093   "adiffb_u\t%0, %r1, %r2"
3094   [(set_attr "type" "X0_2cycle")])
3096 (define_insn "insn_adiffh"
3097   [(set (match_operand:SI 0 "register_operand" "=r")
3098         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3099                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3100                    UNSPEC_INSN_ADIFFH))]
3101   ""
3102   "adiffh\t%0, %r1, %r2"
3103   [(set_attr "type" "X0_2cycle")])
3105 (define_insn "insn_avgb_u"
3106   [(set (match_operand:SI 0 "register_operand" "=r")
3107         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3108                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3109                    UNSPEC_INSN_AVGB_U))]
3110   ""
3111   "avgb_u\t%0, %r1, %r2"
3112   [(set_attr "type" "X0")])
3114 (define_insn "insn_avgh"
3115   [(set (match_operand:SI 0 "register_operand" "=r")
3116         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3117                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3118                    UNSPEC_INSN_AVGH))]
3119   ""
3120   "avgh\t%0, %r1, %r2"
3121   [(set_attr "type" "X0")])
3123 (define_insn "insn_bitx"
3124   [(set (match_operand:SI 0 "register_operand" "=r")
3125         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")]
3126                     UNSPEC_INSN_BITX))]
3127   ""
3128   "bitx\t%0, %r1"
3129   [(set_attr "type" "Y0")])
3131 (define_insn "insn_crc32_32"
3132   [(set (match_operand:SI 0 "register_operand" "=r")
3133         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3134                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3135                    UNSPEC_INSN_CRC32_32))]
3136   ""
3137   "crc32_32\t%0, %r1, %r2"
3138   [(set_attr "type" "X0")])
3140 (define_insn "insn_crc32_8"
3141   [(set (match_operand:SI 0 "register_operand" "=r")
3142         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3143                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3144                    UNSPEC_INSN_CRC32_8))]
3145   ""
3146   "crc32_8\t%0, %r1, %r2"
3147   [(set_attr "type" "X0")])
3149 (define_insn "insn_dtlbpr"
3150   [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] 
3151                          UNSPEC_INSN_DTLBPR)]
3152   ""
3153   "dtlbpr\t%r0"
3154   [(set_attr "type" "X1")])
3156 (define_insn "insn_dword_align"
3157   [(set (match_operand:SI 0 "register_operand" "=r")
3158         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3159                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3160                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3161                    UNSPEC_INSN_DWORD_ALIGN))]
3162   ""
3163   "dword_align\t%0, %r2, %r3"
3164   [(set_attr "type" "X0")])
3166 (define_insn "insn_finv"
3167   [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] 
3168                          UNSPEC_INSN_FINV)]
3169   ""
3170   "finv\t%r0"
3171   [(set_attr "type" "X1")])
3173 (define_insn "insn_flush"
3174   [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] 
3175                          UNSPEC_INSN_FLUSH)]
3176   ""
3177   "flush\t%r0"
3178   [(set_attr "type" "X1")])
3180 (define_insn "insn_fnop"
3181   [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FNOP)]
3182   ""
3183   "fnop")
3185 (define_insn "insn_ill"
3186   [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_ILL)]
3187   ""
3188   "ill"
3189   [(set_attr "type" "cannot_bundle")])
3191 (define_insn "insn_inv"
3192   [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] 
3193                          UNSPEC_INSN_INV)]
3194   ""
3195   "inv\t%r0"
3196   [(set_attr "type" "X1")])
3198 (define_insn "insn_lnk"
3199   [(set (match_operand:SI 0 "register_operand" "=r")
3200         (unspec:SI [(const_int 0)] UNSPEC_INSN_LNK))]
3201   ""
3202   "lnk\t%0"
3203   [(set_attr "type" "X1")])
3205 (define_insn "insn_mnzb"
3206   [(set (match_operand:SI 0 "register_operand" "=r")
3207         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3208                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3209                    UNSPEC_INSN_MNZB))]
3210   ""
3211   "mnzb\t%0, %r1, %r2"
3212   [(set_attr "type" "X01")])
3214 (define_insn "insn_mnzh"
3215   [(set (match_operand:SI 0 "register_operand" "=r")
3216         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3217                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3218                    UNSPEC_INSN_MNZH))]
3219   ""
3220   "mnzh\t%0, %r1, %r2"
3221   [(set_attr "type" "X01")])
3223 (define_insn "insn_mulhh_ss"
3224   [(set (match_operand:SI 0 "register_operand" "=r")
3225         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3226                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3227                    UNSPEC_INSN_MULHH_SS))]
3228   ""
3229   "mulhh_ss\t%0, %r1, %r2"
3230   [(set_attr "type" "Y0_2cycle")])
3232 (define_insn "insn_mulhh_su"
3233   [(set (match_operand:SI 0 "register_operand" "=r")
3234         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3235                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3236                    UNSPEC_INSN_MULHH_SU))]
3237   ""
3238   "mulhh_su\t%0, %r1, %r2"
3239   [(set_attr "type" "X0_2cycle")])
3241 (define_insn "insn_mulhh_uu"
3242   [(set (match_operand:SI 0 "register_operand" "=r")
3243         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3244                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3245                    UNSPEC_INSN_MULHH_UU))]
3246   ""
3247   "mulhh_uu\t%0, %r1, %r2"
3248   [(set_attr "type" "Y0_2cycle")])
3250 (define_insn "insn_mulhha_ss"
3251   [(set (match_operand:SI 0 "register_operand" "=r")
3252         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3253                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3254                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3255                    UNSPEC_INSN_MULHHA_SS))]
3256   ""
3257   "mulhha_ss\t%0, %r2, %r3"
3258   [(set_attr "type" "Y0_2cycle")])
3260 (define_insn "insn_mulhha_su"
3261   [(set (match_operand:SI 0 "register_operand" "=r")
3262         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3263                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3264                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3265                    UNSPEC_INSN_MULHHA_SU))]
3266   ""
3267   "mulhha_su\t%0, %r2, %r3"
3268   [(set_attr "type" "X0_2cycle")])
3270 (define_insn "insn_mulhha_uu"
3271   [(set (match_operand:SI 0 "register_operand" "=r")
3272         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3273                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3274                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3275                    UNSPEC_INSN_MULHHA_UU))]
3276   ""
3277   "mulhha_uu\t%0, %r2, %r3"
3278   [(set_attr "type" "Y0_2cycle")])
3280 (define_insn "insn_mulhhsa_uu"
3281   [(set (match_operand:SI 0 "register_operand" "=r")
3282         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3283                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3284                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3285                    UNSPEC_INSN_MULHHSA_UU))]
3286   ""
3287   "mulhhsa_uu\t%0, %r2, %r3"
3288   [(set_attr "type" "X0_2cycle")])
3290 (define_insn "insn_mulhl_ss"
3291   [(set (match_operand:SI 0 "register_operand" "=r")
3292         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3293                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3294                    UNSPEC_INSN_MULHL_SS))]
3295   ""
3296   "mulhl_ss\t%0, %r1, %r2"
3297   [(set_attr "type" "X0_2cycle")])
3299 (define_insn "insn_mulhl_su"
3300   [(set (match_operand:SI 0 "register_operand" "=r")
3301         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3302                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3303                    UNSPEC_INSN_MULHL_SU))]
3304   ""
3305   "mulhl_su\t%0, %r1, %r2"
3306   [(set_attr "type" "X0_2cycle")])
3308 (define_insn "insn_mulhl_us"
3309   [(set (match_operand:SI 0 "register_operand" "=r")
3310         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3311                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3312                    UNSPEC_INSN_MULHL_US))]
3313   ""
3314   "mulhl_us\t%0, %r1, %r2"
3315   [(set_attr "type" "X0_2cycle")])
3317 (define_insn "insn_mulhl_uu"
3318   [(set (match_operand:SI 0 "register_operand" "=r")
3319         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3320                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3321                    UNSPEC_INSN_MULHL_UU))]
3322   ""
3323   "mulhl_uu\t%0, %r1, %r2"
3324   [(set_attr "type" "X0_2cycle")])
3326 (define_insn "insn_mulhla_ss"
3327   [(set (match_operand:SI 0 "register_operand" "=r")
3328         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3329                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3330                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3331                    UNSPEC_INSN_MULHLA_SS))]
3332   ""
3333   "mulhla_ss\t%0, %r2, %r3"
3334   [(set_attr "type" "X0_2cycle")])
3336 (define_insn "insn_mulhla_su"
3337   [(set (match_operand:SI 0 "register_operand" "=r")
3338         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3339                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3340                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3341                    UNSPEC_INSN_MULHLA_SU))]
3342   ""
3343   "mulhla_su\t%0, %r2, %r3"
3344   [(set_attr "type" "X0_2cycle")])
3346 (define_insn "insn_mulhla_us"
3347   [(set (match_operand:SI 0 "register_operand" "=r")
3348         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3349                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3350                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3351                    UNSPEC_INSN_MULHLA_US))]
3352   ""
3353   "mulhla_us\t%0, %r2, %r3"
3354   [(set_attr "type" "X0_2cycle")])
3356 (define_insn "insn_mulhla_uu"
3357   [(set (match_operand:SI 0 "register_operand" "=r")
3358         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3359                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3360                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3361                    UNSPEC_INSN_MULHLA_UU))]
3362   ""
3363   "mulhla_uu\t%0, %r2, %r3"
3364   [(set_attr "type" "X0_2cycle")])
3366 (define_insn "insn_mulhlsa_uu"
3367   [(set (match_operand:SI 0 "register_operand" "=r")
3368         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3369                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3370                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3371                    UNSPEC_INSN_MULHLSA_UU))]
3372   ""
3373   "mulhlsa_uu\t%0, %r2, %r3"
3374   [(set_attr "type" "Y0_2cycle")])
3376 (define_insn "insn_mulll_ss"
3377   [(set (match_operand:SI 0 "register_operand" "=r")
3378         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3379                     (match_operand:SI 2 "reg_or_0_operand" "rO")]
3380                     UNSPEC_INSN_MULLL_SS))]
3381   ""
3382   "mulll_ss\t%0, %r1, %r2"
3383   [(set_attr "type" "Y0_2cycle")])
3384   
3385 (define_insn "insn_mulll_su"
3386   [(set (match_operand:SI 0 "register_operand" "=r")
3387         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3388                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3389                    UNSPEC_INSN_MULLL_SU))]
3390   ""
3391   "mulll_su\t%0, %r1, %r2"
3392   [(set_attr "type" "X0_2cycle")])
3394 (define_insn "insn_mulll_uu"
3395   [(set (match_operand:SI 0 "register_operand" "=r")
3396         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3397                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3398                    UNSPEC_INSN_MULLL_UU))]
3399   ""
3400   "mulll_uu\t%0, %r1, %r2"
3401   [(set_attr "type" "Y0_2cycle")])
3403 (define_insn "insn_mullla_ss"
3404   [(set (match_operand:SI 0 "register_operand" "=r")
3405         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3406                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3407                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3408                    UNSPEC_INSN_MULLLA_SS))]
3409   ""
3410   "mullla_ss\t%0, %r2, %r3"
3411   [(set_attr "type" "Y0_2cycle")])
3413 (define_insn "insn_mullla_su"
3414   [(set (match_operand:SI 0 "register_operand" "=r")
3415         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3416                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3417                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3418                    UNSPEC_INSN_MULLLA_SU))]
3419   ""
3420   "mullla_su\t%0, %r2, %r3"
3421   [(set_attr "type" "X0_2cycle")])
3423 (define_insn "insn_mullla_uu"
3424   [(set (match_operand:SI 0 "register_operand" "=r")
3425         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3426                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3427                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3428                    UNSPEC_INSN_MULLLA_UU))]
3429   ""
3430   "mullla_uu\t%0, %r2, %r3"
3431   [(set_attr "type" "Y0_2cycle")])
3433 (define_insn "insn_mulllsa_uu"
3434   [(set (match_operand:SI 0 "register_operand" "=r")
3435         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3436                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3437                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3438                    UNSPEC_INSN_MULLLSA_UU))]
3439   ""
3440   "mulllsa_uu\t%0, %r2, %r3"
3441   [(set_attr "type" "X0_2cycle")])
3443 (define_insn "insn_mzb"
3444   [(set (match_operand:SI 0 "register_operand" "=r")
3445         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3446                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3447                    UNSPEC_INSN_MZB))]
3448   ""
3449   "mzb\t%0, %r1, %r2"
3450   [(set_attr "type" "X01")])
3452 (define_insn "insn_mzh"
3453   [(set (match_operand:SI 0 "register_operand" "=r")
3454         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3455                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3456                    UNSPEC_INSN_MZH))]
3457   ""
3458   "mzh\t%0, %r1, %r2"
3459   [(set_attr "type" "X01")])
3461 (define_insn "insn_nap"
3462   [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_NAP)]
3463   ""
3464   "nap"
3465   [(set_attr "type" "cannot_bundle")])
3467 (define_insn "insn_nor"
3468   [(set (match_operand:SI 0 "register_operand" "=r")
3469         (and:SI (not:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))
3470                 (not:SI (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
3471   ""
3472   "nor\t%0, %r1, %r2")
3474 (define_insn "insn_sadab_u"
3475   [(set (match_operand:SI 0 "register_operand" "=r")
3476         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3477                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3478                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3479                    UNSPEC_INSN_SADAB_U))]
3480   ""
3481   "sadab_u\t%0, %r2, %r3"
3482   [(set_attr "type" "X0_2cycle")])
3484 (define_insn "insn_sadah"
3485   [(set (match_operand:SI 0 "register_operand" "=r")
3486         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3487                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3488                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3489                    UNSPEC_INSN_SADAH))]
3490   ""
3491   "sadah\t%0, %r2, %r3"
3492   [(set_attr "type" "X0_2cycle")])
3494 (define_insn "insn_sadah_u"
3495   [(set (match_operand:SI 0 "register_operand" "=r")
3496         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3497                     (match_operand:SI 2 "reg_or_0_operand" "rO")
3498                     (match_operand:SI 3 "reg_or_0_operand" "rO")] 
3499                    UNSPEC_INSN_SADAH_U))]
3500   ""
3501   "sadah_u\t%0, %r2, %r3"
3502   [(set_attr "type" "X0_2cycle")])
3504 (define_insn "insn_sadb_u"
3505   [(set (match_operand:SI 0 "register_operand" "=r")
3506         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3507                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3508                    UNSPEC_INSN_SADB_U))]
3509   ""
3510   "sadb_u\t%0, %r1, %r2"
3511   [(set_attr "type" "X0_2cycle")])
3513 (define_insn "insn_sadh"
3514   [(set (match_operand:SI 0 "register_operand" "=r")
3515         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3516                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3517                    UNSPEC_INSN_SADH))]
3518   ""
3519   "sadh\t%0, %r1, %r2"
3520   [(set_attr "type" "X0_2cycle")])
3522 (define_insn "insn_sadh_u"
3523   [(set (match_operand:SI 0 "register_operand" "=r")
3524         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3525                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3526                    UNSPEC_INSN_SADH_U))]
3527   ""
3528   "sadh_u\t%0, %r1, %r2"
3529   [(set_attr "type" "X0_2cycle")])
3531 (define_insn "insn_tblidxb0"
3532   [(set (match_operand:SI 0 "register_operand" "=r")
3533         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3534                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3535                    UNSPEC_INSN_TBLIDXB0))]
3536   ""
3537   "tblidxb0\t%0, %r2"
3538   [(set_attr "type" "Y0")])
3540 (define_insn "insn_tblidxb1"
3541   [(set (match_operand:SI 0 "register_operand" "=r")
3542         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3543                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3544                    UNSPEC_INSN_TBLIDXB1))]
3545   ""
3546   "tblidxb1\t%0, %r2"
3547   [(set_attr "type" "Y0")])
3549 (define_insn "insn_tblidxb2"
3550   [(set (match_operand:SI 0 "register_operand" "=r")
3551         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3552                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3553                    UNSPEC_INSN_TBLIDXB2))]
3554   ""
3555   "tblidxb2\t%0, %r2"
3556   [(set_attr "type" "Y0")])
3558 (define_insn "insn_tblidxb3"
3559   [(set (match_operand:SI 0 "register_operand" "=r")
3560         (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3561                     (match_operand:SI 2 "reg_or_0_operand" "rO")] 
3562                    UNSPEC_INSN_TBLIDXB3))]
3563   ""
3564   "tblidxb3\t%0, %r2"
3565   [(set_attr "type" "Y0")])
3569 ;; pic related instructions
3572 ;; NOTE: We compute the label in this unusual way because if we place
3573 ;; the label after the lnk, whether it is at the same address as the
3574 ;; lnk will vary depending on whether the optimization level chooses to
3575 ;; insert bundling braces.
3576 (define_insn "insn_lnk_and_label"
3577   [(set (match_operand:SI 0 "register_operand" "=r")
3578         (unspec_volatile:SI [(match_operand:SI 1 "symbolic_operand" "")]
3579                             UNSPEC_LNK_AND_LABEL))]
3580   ""
3581   "%1 = . + 8\n\tlnk\t%0"
3582   [(set_attr "type" "X1")])
3584 (define_expand "addli_pcrel"
3585   [(set (match_operand:SI 0 "register_operand" "")
3586         (lo_sum:SI
3587          (match_operand:SI 1 "register_operand" "")
3588          (const:SI
3589           (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
3590                       (match_operand:SI 3 "symbolic_operand" "")]
3591                      UNSPEC_PCREL_SYM))))]
3592   "flag_pic")
3594 (define_expand "auli_pcrel"
3595   [(set (match_operand:SI 0 "register_operand" "")
3596         (plus:SI
3597          (match_operand:SI 1 "reg_or_0_operand" "")
3598          (high:SI
3599           (const:SI
3600            (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
3601                        (match_operand:SI 3 "symbolic_operand" "")]
3602                       UNSPEC_PCREL_SYM)))))]
3603   "flag_pic")
3605 (define_expand "add_got16"
3606   [(set (match_operand:SI 0 "register_operand" "")
3607         (lo_sum:SI
3608          (match_operand:SI 1 "reg_or_0_operand" "")
3609          (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
3610                               UNSPEC_GOT16_SYM))))]
3611   "flag_pic == 1")
3613 (define_expand "addhi_got32"
3614   [(set (match_operand:SI 0 "register_operand" "")
3615         (plus:SI
3616          (match_operand:SI 1 "reg_or_0_operand" "")
3617          (high:SI
3618           (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
3619                                UNSPEC_GOT32_SYM)))))]
3620   "flag_pic == 2")
3622 (define_expand "addlo_got32"
3623   [(set (match_operand:SI 0 "register_operand" "")
3624         (lo_sum:SI
3625          (match_operand:SI 1 "reg_or_0_operand" "")
3626          (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
3627                               UNSPEC_GOT32_SYM))))]
3628   "flag_pic == 2")
3632 ;; TLS
3635 (define_expand "tls_gd_addhi"
3636   [(set (match_operand:SI 0 "register_operand" "")
3637         (plus:SI
3638          (match_operand:SI 1 "reg_or_0_operand" "")
3639          (high:SI
3640           (const:SI (unspec:SI [(match_operand 2 "tls_symbolic_operand" "")]
3641                                UNSPEC_TLS_GD)))))]
3642   "HAVE_AS_TLS")
3644 (define_expand "tls_gd_addlo"
3645   [(set (match_operand:SI 0 "register_operand" "")
3646         (lo_sum:SI
3647          (match_operand:SI 1 "reg_or_0_operand" "")
3648          (const:SI (unspec:SI [(match_operand 2 "tls_symbolic_operand" "")]
3649                               UNSPEC_TLS_GD))))]
3650   "HAVE_AS_TLS")
3652 (define_expand "tls_gd_call"
3653   [(parallel
3654     [(set (reg:SI 0)
3655           (unspec:SI [(match_operand:SI 0 "tls_symbolic_operand" "")
3656                      (reg:SI 0)]
3657                      UNSPEC_TLS_GD_CALL))
3658      (clobber (reg:SI 25))
3659      (clobber (reg:SI 26))
3660      (clobber (reg:SI 27))
3661      (clobber (reg:SI 28))
3662      (clobber (reg:SI 29))
3663      (clobber (reg:SI 55))])]
3664    ""
3666   cfun->machine->calls_tls_get_addr = true;
3669 (define_insn "*tls_gd_call"
3670   [(set (reg:SI 0)
3671         (unspec:SI [(match_operand:SI 0 "tls_symbolic_operand" "")
3672                     (reg:SI 0)]
3673                    UNSPEC_TLS_GD_CALL))
3674    (clobber (reg:SI 25))
3675    (clobber (reg:SI 26))
3676    (clobber (reg:SI 27))
3677    (clobber (reg:SI 28))
3678    (clobber (reg:SI 29))
3679    (clobber (reg:SI 55))]
3680   ""
3681   "jal\ttls_gd_call(%0)"
3682   [(set_attr "type" "X1")])
3684 (define_insn "tls_gd_add"
3685   [(set (match_operand:SI 0 "register_operand" "=r")
3686        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
3687                    (match_operand:SI 2 "tls_symbolic_operand" "")]
3688                   UNSPEC_TLS_GD_ADD))]
3689   "HAVE_AS_TLS"
3690   "addi\t%0, %1, tls_gd_add(%2)")
3692 (define_insn "tls_ie_load"
3693   [(set (match_operand:SI 0 "register_operand" "=r")
3694        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
3695                    (match_operand:SI 2 "tls_symbolic_operand" "")]
3696                   UNSPEC_TLS_IE_LOAD))]
3697   "HAVE_AS_TLS"
3698   "lw_tls\t%0, %1, tls_ie_load(%2)"
3699   [(set_attr "type" "X1_2cycle")])
3701 (define_expand "tls_ie_addhi"
3702   [(set (match_operand:SI 0 "register_operand" "")
3703         (plus:SI
3704          (match_operand:SI 1 "register_operand" "")
3705          (high:SI
3706           (const:SI (unspec:SI [(match_operand 2 "tls_ie_symbolic_operand" "")]
3707                                UNSPEC_TLS_IE)))))]
3708   "HAVE_AS_TLS")
3710 (define_expand "tls_ie_addlo"
3711   [(set (match_operand:SI 0 "register_operand" "")
3712         (lo_sum:SI
3713          (match_operand:SI 1 "register_operand" "")
3714          (const:SI (unspec:SI [(match_operand 2 "tls_ie_symbolic_operand" "")]
3715                               UNSPEC_TLS_IE))))]
3716   "HAVE_AS_TLS")
3718 (define_expand "tls_le_addhi"
3719   [(set (match_operand:SI 0 "register_operand" "")
3720         (plus:SI
3721          (match_operand:SI 1 "register_operand" "")
3722          (high:SI
3723           (const:SI (unspec:SI [(match_operand 2 "tls_le_symbolic_operand" "")]
3724                                UNSPEC_TLS_LE)))))]
3725   "HAVE_AS_TLS")
3727 (define_expand "tls_le_addlo"
3728   [(set (match_operand:SI 0 "register_operand" "")
3729         (lo_sum:SI
3730          (match_operand:SI 1 "register_operand" "")
3731          (const:SI (unspec:SI [(match_operand 2 "tls_le_symbolic_operand" "")]
3732                               UNSPEC_TLS_LE))))]
3733   "HAVE_AS_TLS")
3737 ;; Stack protector instructions.
3740 (define_expand "stack_protect_set"
3741   [(set (match_operand 0 "nonautoincmem_operand" "")
3742         (match_operand 1 "nonautoincmem_operand" ""))]
3743   ""
3745 #ifdef TARGET_THREAD_SSP_OFFSET
3746   rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
3747   rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
3748   rtx ssp = gen_reg_rtx (Pmode);
3749   
3750   emit_insn (gen_rtx_SET (ssp, ssp_addr));
3752   operands[1] = gen_rtx_MEM (Pmode, ssp);
3753 #endif
3755   emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
3757   DONE;
3760 (define_insn "stack_protect_setsi"
3761   [(set (match_operand:SI 0 "nonautoincmem_operand" "=U")
3762         (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")]
3763                    UNSPEC_SP_SET))
3764    (set (match_scratch:SI 2 "=&r") (const_int 0))]
3765   ""
3766   "lw\t%2, %1; { sw\t%0, %2; move\t%2, zero }"
3767   [(set_attr "length" "16")
3768    (set_attr "type" "cannot_bundle_3cycle")])
3771 (define_expand "stack_protect_test"
3772   [(match_operand 0 "nonautoincmem_operand" "")
3773    (match_operand 1 "nonautoincmem_operand" "")
3774    (match_operand 2 "" "")]
3775   ""
3777   rtx compare_result;
3778   rtx bcomp, loc_ref;
3780 #ifdef TARGET_THREAD_SSP_OFFSET
3781   rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
3782   rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
3783   rtx ssp = gen_reg_rtx (Pmode);
3784   
3785   emit_insn (gen_rtx_SET (ssp, ssp_addr));
3787   operands[1] = gen_rtx_MEM (Pmode, ssp);
3788 #endif
3790   compare_result = gen_reg_rtx (SImode);
3792   emit_insn (gen_stack_protect_testsi (compare_result, operands[0],
3793                                        operands[1]));
3795   bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
3797   loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
3799   emit_jump_insn (gen_rtx_SET (pc_rtx,
3800                                gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
3801                                                      loc_ref, pc_rtx)));
3803   DONE;
3806 (define_insn "stack_protect_testsi"
3807   [(set (match_operand:SI 0 "register_operand" "=&r")
3808         (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")
3809                     (match_operand:SI 2 "nonautoincmem_operand" "U")]
3810                    UNSPEC_SP_TEST))
3811    (set (match_scratch:SI 3 "=&r") (const_int 0))]
3812   ""
3813   "lw\t%0, %1; lw\t%3, %2; { seq\t%0, %0, %3; move\t%3, zero }"
3814   [(set_attr "length" "24")
3815    (set_attr "type" "cannot_bundle_4cycle")])