xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/tilepro/tilepro.md (revision fa28c6faa16e0b00edee7acdcaf4899797043def)
1;; Machine description for Tilera TILEPro chip for GCC.
2;; Copyright (C) 2011-2013 Free Software Foundation, Inc.
3;; Contributed by Walter Lee (walt@tilera.com)
4;;
5;; This file is part of GCC.
6;;
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published
9;; by the Free Software Foundation; either version 3, or (at your
10;; option) any later version.
11;;
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15;; License for more details.
16;;
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3.  If not see
19;; <http://www.gnu.org/licenses/>.
20
21(define_constants [
22  ;;
23  ;; The following represent intrinsic insns, organized by latency.
24  ;;
25
26  ;; single cycle
27  (UNSPEC_INSN_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)
64
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)
97
98  ;;
99  ;; The following are special insns.
100  ;;
101
102  ;; Blockage
103  (UNSPEC_BLOCKAGE                     200)
104
105  ;; Latency specifying loads.
106  (UNSPEC_LATENCY_L2                   201)
107  (UNSPEC_LATENCY_MISS                 202)
108
109  ;; Lnk and its label
110  (UNSPEC_LNK_AND_LABEL                203)
111
112  ;; Memory fence
113  (UNSPEC_MF                           204)
114
115  ;; A pseudo-op that prevents network operations from being ordered.
116  (UNSPEC_NETWORK_BARRIER              205)
117
118  ;; Operations that access network registers.
119  (UNSPEC_NETWORK_RECEIVE              206)
120  (UNSPEC_NETWORK_SEND                 207)
121
122  ;; Stack protector operations
123  (UNSPEC_SP_SET                       208)
124  (UNSPEC_SP_TEST                      209)
125
126  ;; A call to __tls_get_addr
127  (UNSPEC_TLS_GD_CALL                  210)
128
129  ;; An opaque TLS "add" operation for TLS general dynamic model
130  ;; access.
131  (UNSPEC_TLS_GD_ADD                   211)
132
133  ;; An opaque TLS "load" operation for TLS initial exec model access.
134  (UNSPEC_TLS_IE_LOAD                  212)
135
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)
145])
146
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)
153])
154
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)
164])
165
166;; Constants for special purpose registers.
167(define_constants [
168  (TILEPRO_NETORDER_REG 66)])
169
170
171;; Operand and operator predicates and constraints
172
173(include "predicates.md")
174(include "constraints.md")
175(include "tilepro-generic.md")
176
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"))
182
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)))
192
193
194;; Define iterators.
195(define_mode_iterator I48MODE [SI DI])
196(define_mode_iterator I12MODE [QI HI])
197
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])
202
203(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw")])
204(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw")])
205
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")])
234
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")])
264
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 "")])
290
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 "%")])
316
317(define_mode_iterator VEC [V4QI V2HI])
318
319;; Code iterator for all three shifts.
320(define_code_iterator any_shift [ashift ashiftrt lshiftrt])
321
322;; Code iterator for all byte ops without immediate variants.
323(define_code_iterator v1op [us_plus ne le leu minus us_minus])
324
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])
327
328;; Code iterator for all byte vector ops with immediate variants.
329(define_code_iterator v1op_immed [plus umax umin eq lt ltu])
330
331;; Code iterator for all 2-byte vector ops with immediate variants.
332(define_code_iterator v2op_immed [plus smax smin eq lt ltu])
333
334;; Code for packing two 2-byte vectors.
335(define_code_iterator v2pack [truncate us_truncate])
336
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")])
342
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")])
348
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")])
354
355
356;;
357;; The basic data move insns.
358;;
359
360(define_expand "movqi"
361  [(set (match_operand:QI 0 "nonimmediate_operand" "")
362	(match_operand:QI 1 "nonautoinc_operand" ""))]
363  ""
364{
365  if (tilepro_expand_mov (QImode, operands))
366    DONE;
367})
368
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")])
382
383(define_expand "movhi"
384  [(set (match_operand:HI 0 "nonimmediate_operand" "")
385	(match_operand:HI 1 "nonautoinc_operand" ""))]
386  ""
387{
388  if (tilepro_expand_mov (HImode, operands))
389    DONE;
390})
391
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")])
406
407
408(define_expand "movsi"
409  [(set (match_operand:SI 0 "nonimmediate_operand" "")
410	(match_operand:SI 1 "nonautoinc_operand" ""))]
411  ""
412{
413  if (tilepro_expand_mov (SImode, operands))
414    DONE;
415})
416
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")])
423
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")])
441
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  ""
460{
461  tilepro_expand_movmisalign (<MODE>mode, operands);
462  DONE;
463})
464
465(define_expand "movsf"
466  [(set (match_operand:SF 0 "nonimmediate_operand" "")
467	(match_operand:SF 1 "general_operand" ""))]
468  ""
469{
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    }
482})
483
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")])
495
496(define_expand "mov<mode>"
497  [(set (match_operand:VEC 0 "nonimmediate_operand" "")
498        (match_operand:VEC 1 "general_operand" ""))]
499  ""
500{
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    }
513})
514
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")])
526
527
528;;
529;; Bit-field extracts
530;;
531
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  ""
539{
540  HOST_WIDE_INT bit_offset, bit_width;
541  HOST_WIDE_INT first_byte_offset, last_byte_offset;
542
543  bit_width = INTVAL (operands[2]);
544  bit_offset = INTVAL (operands[3]);
545
546  /* Reject bitfields that can be done with a normal load */
547  if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
548    FAIL;
549
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;
555
556  tilepro_expand_unaligned_load (operands[0], operands[1],
557			         bit_width, bit_offset, 1);
558
559  DONE;
560})
561
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  ""
569{
570  HOST_WIDE_INT bit_offset, bit_width;
571  HOST_WIDE_INT first_byte_offset, last_byte_offset;
572
573  bit_width = INTVAL (operands[2]);
574  bit_offset = INTVAL (operands[3]);
575
576  /* Reject bitfields that can be done with a normal load */
577  if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
578    FAIL;
579
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;
585
586  tilepro_expand_unaligned_load (operands[0], operands[1],
587                                 bit_width, bit_offset, 0);
588
589  DONE;
590})
591
592
593;;
594;; Arithmetic ops
595;;
596
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")
604
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  ")
614
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")])
623
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")])
632
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")])
644
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")
651
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")
657
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")])
665
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")])
673
674;;
675;; Shifts
676;;
677
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")
687
688
689;;
690;; Compares
691;;
692
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; })
700
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")
709
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")
716
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")
725
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")
734
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")
743
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")
752
753
754;;
755;; Logical ops
756;;
757
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")])
795
796(define_expand "ctzdi2"
797  [(set (match_operand:DI 0 "register_operand" "")
798	(ctz:DI (match_operand:DI 1 "register_operand" "")))]
799  ""
800{
801  rtx lo, hi, ctz_lo, ctz_hi, ctz_hi_plus_32, result;
802
803  split_di (&operands[1], 1, &lo, &hi);
804  lo = force_reg (SImode, lo);
805  hi = force_reg (SImode, hi);
806
807  ctz_lo = gen_reg_rtx (SImode);
808  emit_insn (gen_ctzsi2 (ctz_lo, lo));
809
810  ctz_hi = gen_reg_rtx (SImode);
811  emit_insn (gen_ctzsi2 (ctz_hi, hi));
812
813  ctz_hi_plus_32 = gen_reg_rtx (SImode);
814  emit_insn (gen_addsi3 (ctz_hi_plus_32, ctz_hi, GEN_INT (32)));
815
816  result = gen_reg_rtx (SImode);
817  emit_insn (gen_insn_mvz (result, ctz_lo, lo, ctz_hi_plus_32));
818
819  emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
820
821  DONE;
822})
823
824(define_expand "clzdi2"
825  [(set (match_operand:DI 0 "register_operand" "")
826	(clz:DI (match_operand:DI 1 "register_operand" "")))]
827  ""
828{
829  rtx lo, hi, clz_lo, clz_hi, clz_lo_plus_32, result;
830
831  split_di (&operands[1], 1, &lo, &hi);
832  lo = force_reg (SImode, lo);
833  hi = force_reg (SImode, hi);
834
835  clz_lo = gen_reg_rtx (SImode);
836  emit_insn (gen_clzsi2 (clz_lo, lo));
837
838  clz_hi = gen_reg_rtx (SImode);
839  emit_insn (gen_clzsi2 (clz_hi, hi));
840
841  clz_lo_plus_32 = gen_reg_rtx (SImode);
842  emit_insn (gen_addsi3 (clz_lo_plus_32, clz_lo, GEN_INT (32)));
843
844  result = gen_reg_rtx (SImode);
845  emit_insn (gen_insn_mvz (result, clz_hi, hi, clz_lo_plus_32));
846
847  emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
848
849  DONE;
850})
851
852(define_expand "ffsdi2"
853  [(set (match_operand:DI 0 "register_operand" "")
854	(ffs:DI (match_operand:DI 1 "register_operand" "")))]
855  ""
856{
857  rtx lo, hi, ctz_lo, ctz_hi, ctz_hi_plus_32, ctz, ctz_plus_1,ctz_cond;
858  rtx result;
859
860  split_di (&operands[1], 1, &lo, &hi);
861  lo = force_reg (SImode, lo);
862  hi = force_reg (SImode, hi);
863
864  ctz_lo = gen_reg_rtx (SImode);
865  emit_insn (gen_ctzsi2 (ctz_lo, lo));
866
867  ctz_hi = gen_reg_rtx (SImode);
868  emit_insn (gen_ctzsi2 (ctz_hi, hi));
869
870  ctz_hi_plus_32 = gen_reg_rtx (SImode);
871  emit_insn (gen_addsi3 (ctz_hi_plus_32, ctz_hi, GEN_INT (32)));
872
873  ctz = gen_reg_rtx (SImode);
874  emit_insn (gen_insn_mvz (ctz, ctz_lo, lo, ctz_hi_plus_32));
875
876  ctz_plus_1 = gen_reg_rtx (SImode);
877  emit_insn (gen_addsi3 (ctz_plus_1, ctz, GEN_INT (1)));
878
879  ctz_cond = gen_reg_rtx (SImode);
880  emit_insn (gen_iorsi3 (ctz_cond, lo, hi));
881
882  result = gen_reg_rtx (SImode);
883  emit_insn (gen_insn_mvz (result, ctz_plus_1, ctz_cond, const0_rtx));
884
885  emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
886
887  DONE;
888})
889
890(define_expand "popcountdi2"
891  [(set (match_operand:DI 0 "register_operand" "")
892	(popcount:DI (match_operand:DI 1 "nonmemory_operand" "")))]
893  ""
894{
895  rtx lo, hi, popcount_lo, popcount_hi, result;
896
897  split_di (&operands[1], 1, &lo, &hi);
898  lo = force_reg (SImode, lo);
899  hi = force_reg (SImode, hi);
900
901  popcount_lo = gen_reg_rtx (SImode);
902  emit_insn (gen_popcountsi2 (popcount_lo, lo));
903
904  popcount_hi = gen_reg_rtx (SImode);
905  emit_insn (gen_popcountsi2 (popcount_hi, hi));
906
907  result = gen_reg_rtx (SImode);
908  emit_insn (gen_addsi3 (result, popcount_lo, popcount_hi));
909
910  emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
911
912  DONE;
913})
914
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  })
925
926(define_expand "paritydi2"
927  [(set (match_operand:DI 0 "register_operand" "")
928	(parity:DI (match_operand:DI 1 "nonmemory_operand" "")))]
929  ""
930{
931  rtx lo, hi, xor_lohi, result;
932
933  split_di (&operands[1], 1, &lo, &hi);
934  lo = force_reg (SImode, lo);
935  hi = force_reg (SImode, hi);
936
937  xor_lohi = gen_reg_rtx (SImode);
938  emit_insn (gen_xorsi3 (xor_lohi, lo, hi));
939
940  result = gen_reg_rtx (SImode);
941  emit_insn (gen_paritysi2 (result, xor_lohi));
942
943  emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
944
945  DONE;
946})
947
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")
953
954
955;;
956;; Conditional moves.
957;;
958
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]); })
966
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")])
982
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)))])
990
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)))])
998
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
1015
1016;;
1017;; Conversions
1018;;
1019
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")])
1039
1040(define_expand "extendhisi2"
1041  [(set (match_operand:SI 0 "register_operand" "")
1042	(sign_extend:SI (match_operand:HI 1 "move_operand" "")))]
1043  ""
1044{
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];
1049
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  }
1056})
1057
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")])
1066
1067(define_expand "extendqisi2"
1068  [(set (match_operand:SI 0 "register_operand" "")
1069	(sign_extend:SI (match_operand:QI 1 "move_operand" "")))]
1070  ""
1071{
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];
1076
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  }
1083})
1084
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")])
1093
1094;;
1095;; insv patterns
1096;;
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  ""
1103{
1104  tilepro_expand_insv (operands);
1105  DONE;
1106})
1107
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")])
1117
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")])
1130
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")])
1143
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")])
1156
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")])
1166
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")])
1179
1180
1181;;
1182;; Multiplies
1183;;
1184
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]);
1201
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  })
1210
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
1265
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")])
1285
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  })
1298
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  ""
1307{
1308  tilepro_expand_umulsi3_highpart (operands[0], operands[1], operands[2]);
1309  DONE;
1310})
1311
1312
1313;;
1314;; Loops
1315;;
1316
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 "" ""))    ;; iterations; zero if unknown
1322   (use (match_operand 2 "" ""))    ;; max iterations
1323   (use (match_operand 3 "" ""))    ;; loop level
1324   (use (match_operand 4 "" ""))    ;; label
1325   (use (match_operand 5 "" ""))]   ;; flag: 1 if loop entered at top, else 0
1326   ""
1327{
1328  if (optimize > 0)
1329  {
1330     rtx s0;
1331     rtx bcomp;
1332     rtx loc_ref;
1333
1334     /* only do inner loop  */
1335     if (INTVAL (operands[3]) > 1)
1336       FAIL;
1337     /* only deal with loop counters in SImode  */
1338     if (GET_MODE (operands[0]) != SImode)
1339       FAIL;
1340
1341     s0 = operands [0];
1342
1343     emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
1344     bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
1345     loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
1346     emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1347                                  gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
1348                                                        loc_ref, pc_rtx)));
1349     DONE;
1350  }
1351  else
1352     FAIL;
1353
1354})
1355
1356;;
1357;; Prologue/epilogue
1358;;
1359(define_expand "prologue"
1360  [(const_int 0)]
1361  ""
1362{
1363  tilepro_expand_prologue ();
1364  DONE;
1365})
1366
1367(define_expand "epilogue"
1368  [(const_int 0)]
1369  ""
1370{
1371  tilepro_expand_epilogue (false);
1372  DONE;
1373})
1374
1375(define_expand "sibcall_epilogue"
1376  [(const_int 0)]
1377  ""
1378{
1379  tilepro_expand_epilogue (true);
1380  DONE;
1381})
1382
1383;;
1384;; Stack manipulations
1385;;
1386
1387;; An insn to allocate new stack space for dynamic use (e.g., alloca).
1388(define_expand "allocate_stack"
1389  [(set (match_operand 0 "register_operand" "")
1390	(minus (reg 54) (match_operand 1 "nonmemory_operand" "")))
1391   (set (reg 54)
1392	(minus (reg 54) (match_dup 1)))]
1393  ""
1394  "tilepro_allocate_stack (operands[0], operands[1]); DONE;")
1395
1396;;
1397;; Branches
1398;;
1399(define_expand "call"
1400  [(parallel [(call (match_operand:SI 0 "call_operand" "")
1401		    (match_operand 1 "" ""))
1402              (use (reg:SI 54))
1403	      (clobber (reg:SI 55))])]
1404  ""
1405  "")
1406
1407(define_insn "*call_insn"
1408  [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rO,i"))
1409	 (match_operand 1 "" ""))
1410   (use (reg:SI 54))
1411   (clobber (reg:SI 55))]
1412  ""
1413  "@
1414   jalr\t%r0
1415   jal\t%p0"
1416  [(set_attr "type" "X1,X1")])
1417
1418(define_expand "call_value"
1419  [(parallel [(set (match_operand 0 "register_operand" "")
1420		   (call (match_operand:SI 1 "call_operand" "")
1421			 (match_operand 2 "" "")))
1422              (use (reg:SI 54))
1423	      (clobber (reg:SI 55))])]
1424  "")
1425
1426(define_insn "*call_value_insn"
1427  [(set (match_operand 0 "register_operand" "=r,r")
1428	(call (mem:SI (match_operand:SI 1 "call_address_operand" "rO,i"))
1429	      (match_operand 2 "" "")))
1430   (use (reg:SI 54))
1431   (clobber (reg:SI 55))]
1432  ""
1433  "@
1434   jalr\t%r1
1435   jal\t%p1"
1436  [(set_attr "type" "X1,X1")])
1437
1438(define_expand "sibcall"
1439  [(parallel [(call (match_operand:SI 0 "call_operand" "")
1440		    (match_operand 1 "" ""))
1441	      (use (reg:SI 54))])]
1442  ""
1443  "")
1444
1445(define_insn "*sibcall_insn"
1446  [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rO,i"))
1447	 (match_operand 1 "" ""))
1448   (use (reg:SI 54))]
1449  "SIBLING_CALL_P(insn)"
1450  "@
1451   jr\t%r0
1452   j\t%p0"
1453  [(set_attr "type" "X1,X1")])
1454
1455(define_expand "sibcall_value"
1456  [(parallel [(set (match_operand 0 "" "")
1457		   (call (match_operand:SI 1 "call_operand" "")
1458			 (match_operand:SI 2 "" "")))
1459	      (use (reg:SI 54))])]
1460  ""
1461  "")
1462
1463(define_insn "*sibcall_value"
1464  [(set (match_operand 0 "" "")
1465	(call (mem:SI (match_operand:SI 1 "call_address_operand" "rO,i"))
1466	      (match_operand:SI 2 "" "")))
1467   (use (reg:SI 54))]
1468  "SIBLING_CALL_P(insn)"
1469  "@
1470   jr\t%r1
1471   j\t%p1"
1472  [(set_attr "type" "X1,X1")])
1473
1474(define_insn "jump"
1475  [(set (pc) (label_ref (match_operand 0 "" "")))]
1476  ""
1477  "j\t%l0"
1478  [(set_attr "type" "X1")])
1479
1480(define_insn "indirect_jump"
1481  [(set (pc) (match_operand:SI 0 "register_operand" "rO"))]
1482  ""
1483  "jr\t%r0"
1484  [(set_attr "type" "X1")])
1485
1486(define_expand "return"
1487  [(parallel
1488    [(return)
1489     (use (reg:SI 55))])]
1490  "tilepro_can_use_return_insn_p ()"
1491  "")
1492
1493(define_insn "_return"
1494  [(return)
1495   (use (reg:SI 55))]
1496  "reload_completed"
1497  "jrp\tlr"
1498  [(set_attr "type" "X1")])
1499
1500(define_expand "tablejump"
1501  [(set (pc) (match_operand:SI 0 "register_operand" ""))
1502   (use (label_ref (match_operand 1 "" "")))]
1503  ""
1504{
1505  tilepro_expand_tablejump (operands[0], operands[1]);
1506  DONE;
1507})
1508
1509(define_insn "tablejump_aux"
1510  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1511   (use (label_ref (match_operand 1 "" "")))]
1512  ""
1513  "jr\t%0"
1514  [(set_attr "type" "X1")])
1515
1516;; Call subroutine returning any type.
1517(define_expand "untyped_call"
1518  [(parallel [(call (match_operand 0 "" "")
1519		    (const_int 0))
1520	      (match_operand 1 "" "")
1521	      (match_operand 2 "" "")])]
1522  ""
1523{
1524  int i;
1525
1526  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
1527
1528  for (i = 0; i < XVECLEN (operands[2], 0); i++)
1529    {
1530      rtx set = XVECEXP (operands[2], 0, i);
1531      emit_move_insn (SET_DEST (set), SET_SRC (set));
1532    }
1533
1534  /* The optimizer does not know that the call sets the function value
1535     registers we stored in the result block.  We avoid problems by
1536     claiming that all hard registers are used and clobbered at this
1537     point.  */
1538  emit_insn (gen_blockage ());
1539
1540  DONE;
1541})
1542
1543;; UNSPEC_VOLATILE is considered to use and clobber all hard registers
1544;; and all of memory.  This blocks insns from being moved across this
1545;; point.
1546(define_insn "blockage"
1547  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
1548  ""
1549  "pseudo"
1550  [(set_attr "type" "nothing")
1551   (set_attr "length" "0")])
1552
1553;; Internal expanders to prevent memory ops from moving around frame
1554;; allocation/deallocation.
1555;;
1556;; TODO: really this clobber should just clobber the frame memory.  Is
1557;; this possibly by clobbering memory @ the sp reg (as alpha does?)
1558;; or by explicitly setting the alias set to the frame?
1559(define_insn "sp_adjust"
1560  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1561        (plus:SI
1562         (match_operand:SI 1 "register_operand" "%r,r,r")
1563         (match_operand:SI 2 "add_operand" "r,I,J")))
1564   (clobber (mem:BLK (scratch)))]
1565 ""
1566 "@
1567  add\t%0, %1, %2
1568  addi\t%0, %1, %2
1569  addli\t%0, %1, %2"
1570 [(set_attr "type" "*,*,X01")])
1571
1572;; Used for move sp, r52, to pop a stack frame.  We need to make sure
1573;; that stack frame memory operations have been issued before we do
1574;; this.  TODO: see above TODO.
1575(define_insn "sp_restore"
1576  [(set (match_operand:SI 0 "register_operand" "=r")
1577        (match_operand:SI 1 "register_operand" "r"))
1578   (clobber (mem:BLK (scratch)))]
1579 ""
1580 "move\t%0, %1")
1581
1582(define_insn "nop"
1583  [(const_int 0)]
1584  ""
1585  "nop"
1586  [(set_attr "type" "Y01")])
1587
1588
1589;;
1590;; Conditional branches
1591;;
1592
1593(define_expand "cbranchsi4"
1594  [(set (pc)
1595	(if_then_else (match_operator 0 "ordered_comparison_operator"
1596		       [(match_operand:SI 1 "reg_or_cint_operand")
1597		        (match_operand:SI 2 "reg_or_cint_operand")])
1598		      (label_ref (match_operand 3 ""))
1599		      (pc)))]
1600  ""
1601  { tilepro_emit_conditional_branch (operands, SImode); DONE; })
1602
1603
1604(define_expand "cbranchdi4"
1605  [(set (pc)
1606	(if_then_else (match_operator 0 "ordered_comparison_operator"
1607		       [(match_operand:DI 1 "reg_or_cint_operand")
1608		        (match_operand:DI 2 "reg_or_cint_operand")])
1609		      (label_ref (match_operand 3 ""))
1610		      (pc)))]
1611  ""
1612  { tilepro_emit_conditional_branch (operands, DImode); DONE; })
1613
1614
1615(define_insn "*bcc_normal"
1616  [(set (pc)
1617	(if_then_else
1618	 (match_operator 1 "signed_comparison_operator"
1619			 [(match_operand:SI 2 "reg_or_0_operand" "rO")
1620			  (const_int 0)])
1621	 (label_ref (match_operand 0 "" ""))
1622	 (pc)))]
1623  ""
1624  { return tilepro_output_cbranch (insn, operands, false); }
1625  [(set_attr "type" "X1_branch")])
1626
1627(define_insn "*bcc_reverse"
1628  [(set (pc)
1629	(if_then_else
1630	 (match_operator 1 "signed_comparison_operator"
1631			 [(match_operand:SI 2 "reg_or_0_operand" "rO")
1632			  (const_int 0)])
1633	 (pc)
1634	 (label_ref (match_operand 0 "" ""))))]
1635  ""
1636  { return tilepro_output_cbranch (insn, operands, true); }
1637  [(set_attr "type" "X1_branch")])
1638
1639;; FIXME: the straight forward versions which do not include the
1640;; subreg:QI does not match for some unknown reason.
1641(define_insn "*bbs_normal"
1642  [(set (pc)
1643	(if_then_else
1644	 (ne (zero_extract:SI (subreg:QI
1645			       (match_operand:SI 1 "reg_or_0_operand" "rO") 0)
1646			      (const_int 1)
1647			      (const_int 0))
1648	     (const_int 0))
1649	 (label_ref (match_operand 0 "" ""))
1650	 (pc)))]
1651  ""
1652  { return tilepro_output_cbranch_with_opcode (insn, operands, "bbs", "bbns",
1653					    1, 0); }
1654  [(set_attr "type" "X1_branch")])
1655
1656(define_insn "*bbc_normal"
1657  [(set (pc)
1658	(if_then_else
1659	 (eq (zero_extract:SI (subreg:QI
1660			       (match_operand:SI 1 "reg_or_0_operand" "rO") 0)
1661			      (const_int 1)
1662			      (const_int 0))
1663	     (const_int 0))
1664	 (label_ref (match_operand 0 "" ""))
1665	 (pc)))]
1666  ""
1667  { return tilepro_output_cbranch_with_opcode (insn, operands, "bbns", "bbs",
1668					    1, 0); }
1669  [(set_attr "type" "X1_branch")])
1670
1671;; Note that __insn_mf() expands to this.
1672(define_expand "memory_barrier"
1673  [(set (match_dup 0)
1674	(unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
1675  ""
1676{
1677  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
1678  MEM_VOLATILE_P (operands[0]) = 1;
1679})
1680
1681(define_insn "*memory_barrier"
1682  [(set (match_operand:BLK 0 "" "")
1683	(unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
1684  ""
1685  "mf"
1686  [(set_attr "type" "X1")])
1687
1688(define_insn "prefetch"
1689  [(prefetch (match_operand:SI 0 "address_operand" "rO")
1690             (match_operand:SI 1 "const_int_operand" "")
1691             (match_operand:SI 2 "const_int_operand" ""))]
1692  ""
1693  "prefetch\t%r0"
1694  [(set_attr "type" "Y2")])
1695
1696
1697;;
1698;; Network intrinsics
1699;;
1700
1701;; Note the "pseudo" text is handled specially by the
1702;; asm_output_opcode routine.  If the output is an empty string, the
1703;; instruction would bypass the asm_output_opcode routine, bypassing
1704;; the bundle handling code.
1705(define_insn "tilepro_network_barrier"
1706  [(unspec_volatile:SI [(const_int 0)] UNSPEC_NETWORK_BARRIER)]
1707  ""
1708  "pseudo"
1709  [(set_attr "type" "nothing")
1710   (set_attr "length" "0")])
1711
1712(define_insn "*netreg_receive"
1713  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,U,m")
1714        (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i")
1715			     (reg:SI TILEPRO_NETORDER_REG)]
1716			    UNSPEC_NETWORK_RECEIVE))
1717   (clobber (reg:SI TILEPRO_NETORDER_REG))]
1718  ""
1719  "@
1720   move\t%0, %N1
1721   sw\t%0, %N1
1722   swadd\t%I0, %N1, %i0"
1723  [(set_attr "type" "*,Y2,X1")])
1724
1725(define_insn "*netreg_send"
1726  [(unspec_volatile:SI
1727    [(match_operand:SI 0 "netreg_operand" "i,i,i,i,i,i")
1728     (match_operand:SI 1 "reg_or_cint_operand" "rO,I,J,K,N,P")
1729     (reg:SI TILEPRO_NETORDER_REG)]
1730    UNSPEC_NETWORK_SEND)
1731   (clobber (reg:SI TILEPRO_NETORDER_REG))]
1732  ""
1733  "@
1734   move\t%N0, %r1
1735   movei\t%N0, %1
1736   moveli\t%N0, %1
1737   auli\t%N0, zero, %h1
1738   addib\t%N0, zero, %j1
1739   addih\t%N0, zero, %h1"
1740  [(set_attr "type" "*,*,X01,X01,X01,X01")])
1741
1742(define_insn "*netreg_copy"
1743  [(unspec_volatile:SI
1744    [(match_operand:SI 0 "netreg_operand" "i")
1745     (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
1746			  (reg:SI TILEPRO_NETORDER_REG)]
1747			 UNSPEC_NETWORK_RECEIVE)
1748     (reg:SI TILEPRO_NETORDER_REG)]
1749    UNSPEC_NETWORK_SEND)
1750   (clobber (reg:SI TILEPRO_NETORDER_REG))
1751   (clobber (reg:SI TILEPRO_NETORDER_REG))]
1752  ""
1753  "move %N0, %N1")
1754
1755(define_expand "tilepro_idn0_receive"
1756  [(parallel
1757    [(set (match_operand:SI 0 "register_operand" "")
1758	  (unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN0)
1759			       (reg:SI TILEPRO_NETORDER_REG)]
1760			      UNSPEC_NETWORK_RECEIVE))
1761     (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1762  "")
1763
1764(define_expand "tilepro_idn1_receive"
1765  [(parallel
1766    [(set (match_operand:SI 0 "register_operand" "")
1767	  (unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN1)
1768			       (reg:SI TILEPRO_NETORDER_REG)]
1769			      UNSPEC_NETWORK_RECEIVE))
1770     (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1771  "")
1772
1773(define_expand "tilepro_idn_send"
1774  [(parallel
1775    [(unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN0)
1776			  (match_operand:SI 0 "reg_or_cint_operand" "")
1777			  (reg:SI TILEPRO_NETORDER_REG)]
1778			 UNSPEC_NETWORK_SEND)
1779     (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1780  "")
1781
1782(define_expand "tilepro_sn_receive"
1783  [(parallel
1784    [(set (match_operand:SI 0 "register_operand" "")
1785	  (unspec_volatile:SI [(const_int TILEPRO_NETREG_SN)
1786			       (reg:SI TILEPRO_NETORDER_REG)]
1787			      UNSPEC_NETWORK_RECEIVE))
1788     (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1789  "")
1790
1791(define_expand "tilepro_sn_send"
1792  [(parallel
1793    [(unspec_volatile:SI [(const_int TILEPRO_NETREG_SN)
1794			  (match_operand:SI 0 "reg_or_cint_operand" "")
1795			  (reg:SI TILEPRO_NETORDER_REG)]
1796			 UNSPEC_NETWORK_SEND)
1797     (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1798  "")
1799
1800(define_expand "tilepro_udn0_receive"
1801  [(parallel
1802    [(set (match_operand:SI 0 "register_operand" "")
1803	  (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN0)
1804			       (reg:SI TILEPRO_NETORDER_REG)]
1805			      UNSPEC_NETWORK_RECEIVE))
1806     (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1807  "")
1808
1809(define_expand "tilepro_udn1_receive"
1810  [(parallel
1811    [(set (match_operand:SI 0 "register_operand" "")
1812	  (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN1)
1813			       (reg:SI TILEPRO_NETORDER_REG)]
1814			      UNSPEC_NETWORK_RECEIVE))
1815     (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1816  "")
1817
1818(define_expand "tilepro_udn2_receive"
1819  [(parallel
1820    [(set (match_operand:SI 0 "register_operand" "")
1821	  (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN2)
1822			       (reg:SI TILEPRO_NETORDER_REG)]
1823			      UNSPEC_NETWORK_RECEIVE))
1824     (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1825  "")
1826
1827(define_expand "tilepro_udn3_receive"
1828  [(parallel
1829    [(set (match_operand:SI 0 "register_operand" "")
1830	  (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN3)
1831			       (reg:SI TILEPRO_NETORDER_REG)]
1832			      UNSPEC_NETWORK_RECEIVE))
1833     (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1834  "")
1835
1836(define_expand "tilepro_udn_send"
1837  [(parallel
1838    [(unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN0)
1839			  (match_operand:SI 0 "reg_or_cint_operand" "")
1840			  (reg:SI TILEPRO_NETORDER_REG)]
1841			 UNSPEC_NETWORK_SEND)
1842     (clobber (reg:SI TILEPRO_NETORDER_REG))])]
1843  "")
1844
1845(define_insn "*netreg_add_to_network"
1846  [(unspec_volatile:SI
1847    [(match_operand:SI 0 "netreg_operand" "i,i,i,i")
1848     (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO,rO")
1849              (match_operand:SI 2 "add_operand" "r,I,J,K"))
1850     (reg:SI TILEPRO_NETORDER_REG)]
1851    UNSPEC_NETWORK_SEND)
1852   (clobber (reg:SI TILEPRO_NETORDER_REG))]
1853  ""
1854  "@
1855   add\t%N0, %r1, %2
1856   addi\t%N0, %r1, %2
1857   addli\t%N0, %r1, %2
1858   auli\t%N0, %r1, %h2"
1859  [(set_attr "type" "*,*,X01,X01")])
1860
1861(define_insn "*netreg_add_from_network"
1862  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1863	(plus:SI
1864	 (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i,i")
1865			      (reg:SI TILEPRO_NETORDER_REG)]
1866			     UNSPEC_NETWORK_RECEIVE)
1867	 (match_operand:SI 2 "add_operand" "rO,I,J,K")))
1868   (clobber (reg:SI TILEPRO_NETORDER_REG))]
1869  ""
1870  "@
1871   add\t%0, %N1, %r2
1872   addi\t%0, %N1, %2
1873   addli\t%0, %N1, %2
1874   auli\t%0, %N1, %h2"
1875  [(set_attr "type" "*,*,X01,X01")])
1876
1877(define_insn "*netreg_add_from_to_network"
1878  [(unspec_volatile:SI
1879    [(match_operand:SI 0 "netreg_operand" "i,i,i,i")
1880     (plus:SI
1881      (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i,i")
1882			   (reg:SI TILEPRO_NETORDER_REG)]
1883			  UNSPEC_NETWORK_RECEIVE)
1884      (match_operand:SI 2 "add_operand" "rO,I,J,K"))
1885     (reg:SI TILEPRO_NETORDER_REG)]
1886    UNSPEC_NETWORK_SEND)
1887   (clobber (reg:SI TILEPRO_NETORDER_REG))
1888   (clobber (reg:SI TILEPRO_NETORDER_REG))]
1889  ""
1890  "@
1891   add\t%N0, %N1, %r2
1892   addi\t%N0, %N1, %2
1893   addli\t%N0, %N1, %2
1894   auli\t%N0, %N1, %h2"
1895  [(set_attr "type" "*,*,X01,X01")])
1896
1897(define_code_iterator netreg_binop
1898  [minus])
1899
1900(define_insn "*netreg_binop_to_network"
1901  [(unspec_volatile:SI
1902    [(match_operand:SI 0 "netreg_operand" "i")
1903    (netreg_binop:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1904		     (match_operand:SI 2 "reg_or_0_operand" "rO"))
1905    (reg:SI TILEPRO_NETORDER_REG)]
1906    UNSPEC_NETWORK_SEND)
1907   (clobber (reg:SI TILEPRO_NETORDER_REG))]
1908  ""
1909  "<insn>\t%N0, %r1, %r2")
1910
1911(define_insn "*netreg_binop_from_network0"
1912  [(set (match_operand:SI 0 "register_operand" "=r")
1913	(netreg_binop:SI
1914	 (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
1915			      (reg:SI TILEPRO_NETORDER_REG)]
1916			     UNSPEC_NETWORK_RECEIVE)
1917	 (match_operand:SI 2 "reg_or_0_operand" "rO")))
1918   (clobber (reg:SI TILEPRO_NETORDER_REG))]
1919  ""
1920  "<insn>\t%0, %N1, %r2")
1921
1922(define_insn "*netreg_binop_from_network1"
1923  [(set (match_operand:SI 0 "register_operand" "=r")
1924	(netreg_binop:SI
1925         (match_operand:SI 1 "reg_or_0_operand" "rO")
1926	 (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
1927			      (reg:SI TILEPRO_NETORDER_REG)]
1928			     UNSPEC_NETWORK_RECEIVE)))
1929   (clobber (reg:SI TILEPRO_NETORDER_REG))]
1930  ""
1931  "<insn>\t%0, %r1, %N2")
1932
1933(define_insn "*netreg_binop_from_to_network0"
1934  [(unspec_volatile:SI
1935    [(match_operand:SI 0 "netreg_operand" "i")
1936     (netreg_binop:SI
1937      (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
1938			   (reg:SI TILEPRO_NETORDER_REG)]
1939			  UNSPEC_NETWORK_RECEIVE)
1940      (match_operand:SI 2 "reg_or_0_operand" "rO"))
1941     (reg:SI TILEPRO_NETORDER_REG)]
1942    UNSPEC_NETWORK_SEND)
1943   (clobber (reg:SI TILEPRO_NETORDER_REG))
1944   (clobber (reg:SI TILEPRO_NETORDER_REG))]
1945  ""
1946  "<insn>\t%N0, %N1, %r2")
1947
1948(define_insn "*netreg_binop_from_to_network1"
1949  [(unspec_volatile:SI
1950    [(match_operand:SI 0 "netreg_operand" "i")
1951     (netreg_binop:SI
1952      (match_operand:SI 1 "reg_or_0_operand" "rO")
1953      (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
1954			   (reg:SI TILEPRO_NETORDER_REG)]
1955			  UNSPEC_NETWORK_RECEIVE))
1956     (reg:SI TILEPRO_NETORDER_REG)]
1957    UNSPEC_NETWORK_SEND)
1958   (clobber (reg:SI TILEPRO_NETORDER_REG))
1959   (clobber (reg:SI TILEPRO_NETORDER_REG))]
1960  ""
1961  "<insn>\t%N0, %r1, %N2")
1962
1963(define_insn "*netreg_binop_to_network"
1964  [(unspec_volatile:SI
1965    [(match_operand:SI 0 "netreg_operand" "i,i")
1966     (binop_with_imm:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1967			(match_operand:SI 2 "reg_or_cint_operand" "I,rO"))
1968     (reg:SI TILEPRO_NETORDER_REG)]
1969    UNSPEC_NETWORK_SEND)
1970   (clobber (reg:SI TILEPRO_NETORDER_REG))]
1971  ""
1972  "@
1973   <insn>i<u>\t%N0, %r1, %2
1974   <insn><u>\t%N0, %r1, %r2")
1975
1976(define_insn "*netreg_binop_from_network"
1977  [(set (match_operand:SI 0 "register_operand" "=r,r")
1978	(binop_with_imm:SI
1979         (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i")
1980			      (reg:SI TILEPRO_NETORDER_REG)]
1981			     UNSPEC_NETWORK_RECEIVE)
1982         (match_operand:SI 2 "reg_or_cint_operand" "I,rO")))
1983   (clobber (reg:SI TILEPRO_NETORDER_REG))]
1984  ""
1985  "@
1986   <insn>i<u>\t%0, %N1, %2
1987   <insn><u>\t%0, %N1, %r2")
1988
1989(define_insn "*netreg_binop_from_to_network"
1990  [(unspec_volatile:SI
1991    [(match_operand:SI 0 "netreg_operand" "i,i")
1992     (binop_with_imm:SI
1993      (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i")
1994			   (reg:SI TILEPRO_NETORDER_REG)]
1995			  UNSPEC_NETWORK_RECEIVE)
1996      (match_operand:SI 2 "reg_or_cint_operand" "I,rO"))
1997     (reg:SI TILEPRO_NETORDER_REG)]
1998    UNSPEC_NETWORK_SEND)
1999   (clobber (reg:SI TILEPRO_NETORDER_REG))
2000   (clobber (reg:SI TILEPRO_NETORDER_REG))]
2001  ""
2002  "@
2003   <insn>i<u>\t%N0, %N1, %2
2004   <insn><u>\t%N0, %N1, %r2")
2005
2006(define_insn "*netreg_unop_to_network"
2007  [(unspec_volatile:SI [(match_operand:SI 0 "netreg_operand" "i")
2008			(unop:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))
2009			(reg:SI TILEPRO_NETORDER_REG)]
2010		       UNSPEC_NETWORK_SEND)
2011   (clobber (reg:SI TILEPRO_NETORDER_REG))]
2012  ""
2013  "<insn>\t%N0, %r1"
2014  [(set_attr "type" "Y0")])
2015
2016(define_insn "*netreg_unop_from_network"
2017  [(set (match_operand:SI 0 "register_operand" "=r")
2018	(unop:SI
2019	 (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2020			      (reg:SI TILEPRO_NETORDER_REG)]
2021			     UNSPEC_NETWORK_RECEIVE)))
2022   (clobber (reg:SI TILEPRO_NETORDER_REG))]
2023  ""
2024  "<insn>\t%0, %N1"
2025  [(set_attr "type" "Y0")])
2026
2027(define_insn "*netreg_unop_from_to_network"
2028  [(unspec_volatile:SI
2029    [(match_operand:SI 0 "netreg_operand" "i")
2030     (unop:SI
2031      (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2032			   (reg:SI TILEPRO_NETORDER_REG)]
2033			  UNSPEC_NETWORK_RECEIVE))
2034     (reg:SI TILEPRO_NETORDER_REG)]
2035    UNSPEC_NETWORK_SEND)
2036   (clobber (reg:SI TILEPRO_NETORDER_REG))
2037   (clobber (reg:SI TILEPRO_NETORDER_REG))]
2038  ""
2039  "<insn>\t%N0, %N1"
2040  [(set_attr "type" "Y0")])
2041
2042(define_insn "*netreg_sadh_u_from_network0"
2043  [(set (match_operand:SI 0 "register_operand" "=r")
2044	(unspec:SI
2045	 [(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2046			       (reg:SI TILEPRO_NETORDER_REG)]
2047			      UNSPEC_NETWORK_RECEIVE)
2048	  (match_operand:SI 2 "reg_or_0_operand" "rO")]
2049	 UNSPEC_INSN_SADH_U))
2050   (clobber (reg:SI TILEPRO_NETORDER_REG))]
2051  ""
2052  "sadh_u\t%0, %N1, %r2"
2053  [(set_attr "type" "X0_2cycle")])
2054
2055(define_insn "*netreg_sadh_u_from_network1"
2056  [(set (match_operand:SI 0 "register_operand" "=r")
2057	(unspec:SI
2058	 [(match_operand:SI 1 "reg_or_0_operand" "rO")
2059	  (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
2060			       (reg:SI TILEPRO_NETORDER_REG)]
2061			      UNSPEC_NETWORK_RECEIVE)]
2062	 UNSPEC_INSN_SADH_U))
2063   (clobber (reg:SI TILEPRO_NETORDER_REG))]
2064  ""
2065  "sadh_u\t%0, %r1, %N2"
2066  [(set_attr "type" "X0_2cycle")])
2067
2068(define_insn "*netreg_sadah_u_from_network0"
2069  [(set (match_operand:SI 0 "register_operand" "=r")
2070	(unspec:SI
2071	 [(match_operand:SI 1 "reg_or_0_operand" "0")
2072	  (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
2073			       (reg:SI TILEPRO_NETORDER_REG)]
2074			      UNSPEC_NETWORK_RECEIVE)
2075	  (match_operand:SI 3 "reg_or_0_operand" "rO")]
2076	 UNSPEC_INSN_SADAH_U))
2077   (clobber (reg:SI TILEPRO_NETORDER_REG))]
2078  ""
2079  "sadah_u\t%0, %N2, %r3"
2080  [(set_attr "type" "X0_2cycle")])
2081
2082(define_insn "*netreg_sadah_u_from_network1"
2083  [(set (match_operand:SI 0 "register_operand" "=r")
2084	(unspec:SI
2085	 [(match_operand:SI 1 "reg_or_0_operand" "0")
2086	  (match_operand:SI 2 "reg_or_0_operand" "rO")
2087	  (unspec_volatile:SI [(match_operand:SI 3 "netreg_operand" "i")
2088			       (reg:SI TILEPRO_NETORDER_REG)]
2089			      UNSPEC_NETWORK_RECEIVE)]
2090	 UNSPEC_INSN_SADAH_U))
2091   (clobber (reg:SI TILEPRO_NETORDER_REG))]
2092  ""
2093  "sadah_u\t%0, %r2, %N3"
2094  [(set_attr "type" "X0_2cycle")])
2095
2096(define_code_iterator mm_combiner [ior xor plus])
2097
2098;; This doesn't seem to match -- too complex for 'combine'?
2099;;
2100;; (define_insn "*netreg_mm_to_network"
2101;;   [(unspec_volatile:SI
2102;;     [(match_operand:SI 0 "netreg_operand" "i")
2103;;      (mm_combiner:SI
2104;;       (and:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2105;; 	         (match_operand:SI 3 "const_int_operand" "n"))
2106;;       (and:SI (match_operand:SI 2 "reg_or_0_operand" "rO")
2107;; 	         (match_operand:SI 4 "const_int_operand" "n")))]
2108;;     UNSPEC_NETWORK_SEND)]
2109;;   "tilepro_bitfield_operand_p (INTVAL (operands[3]), NULL, NULL)
2110;;    && INTVAL (operands[3]) == ~INTVAL (operands[4])"
2111;;   "mm\t%N0, %r1, %r2, %M3"
2112;;   [(set_attr "type" "X01")])
2113
2114;; FIXME: the straight forward versions which do not include the
2115;; subreg:QI does not match for some unknown reason.
2116(define_insn "*netreg_bbs_normal"
2117  [(set (pc)
2118	(if_then_else
2119	 (ne (zero_extract:SI
2120	      (subreg:QI
2121	       (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2122				    (reg:SI TILEPRO_NETORDER_REG)]
2123				   UNSPEC_NETWORK_RECEIVE) 0)
2124              (const_int 1)
2125              (const_int 0))
2126	     (const_int 0))
2127	 (label_ref (match_operand 0 "" ""))
2128	 (pc)))
2129   (clobber (reg:SI TILEPRO_NETORDER_REG))]
2130  ""
2131  { return tilepro_output_cbranch_with_opcode (insn, operands, "bbs", "bbns",
2132					    1, 1); }
2133  [(set_attr "type" "X1_branch")])
2134
2135(define_insn "*netreg_bbc_normal"
2136  [(set (pc)
2137	(if_then_else
2138	 (eq (zero_extract:SI
2139	      (subreg:QI
2140	       (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
2141				    (reg:SI TILEPRO_NETORDER_REG)]
2142				   UNSPEC_NETWORK_RECEIVE) 0)
2143              (const_int 1)
2144              (const_int 0))
2145	     (const_int 0))
2146	 (label_ref (match_operand 0 "" ""))
2147	 (pc)))
2148   (clobber (reg:SI TILEPRO_NETORDER_REG))]
2149  ""
2150  { return tilepro_output_cbranch_with_opcode (insn, operands, "bbns", "bbns",
2151					    1, 1); }
2152  [(set_attr "type" "X1_branch")])
2153
2154
2155;;
2156;; "__insn" Intrinsics (some expand directly to normal patterns above).
2157;;
2158
2159(define_insn "insn_addlis"
2160  [(set (match_operand:SI 0 "register_operand" "=r")
2161        (unspec_volatile:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
2162                             (match_operand:SI 2 "s16bit_cint_operand" "i")]
2163                            UNSPEC_INSN_ADDLIS))]
2164  ""
2165  "addlis\t%0, %r1, %2"
2166  [(set_attr "type" "X01")])
2167
2168(define_insn "insn_auli"
2169  [(set (match_operand:SI 0 "register_operand" "=r")
2170        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
2171                    (match_operand:SI 2 "s16bit_cint_operand" "i")]
2172                   UNSPEC_INSN_AULI))]
2173  ""
2174  "auli\t%0, %r1, %2"
2175  [(set_attr "type" "X01")])
2176
2177(define_insn "insn_drain"
2178  [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_DRAIN)]
2179  ""
2180  "drain"
2181  [(set_attr "type" "cannot_bundle")])
2182
2183(define_insn "insn_icoh"
2184  [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")]
2185                         UNSPEC_INSN_ICOH)]
2186  ""
2187  "icoh\t%r0"
2188  [(set_attr "type" "X1")])
2189
2190
2191(define_insn "insn_info"
2192  [(unspec_volatile:VOID [(match_operand:SI 0 "s8bit_cint_operand" "i")]
2193                         UNSPEC_INSN_INFO)]
2194  ""
2195  "info\t%0")
2196
2197(define_insn "insn_infol"
2198  [(unspec_volatile:VOID [(match_operand:SI 0 "s16bit_cint_operand" "i")]
2199                         UNSPEC_INSN_INFOL)]
2200  ""
2201  "infol\t%0"
2202  [(set_attr "type" "X01")])
2203
2204;; loads
2205
2206(define_expand "insn_<load>"
2207  [(set (match_operand:SI 0 "register_operand" "")
2208	(sign_extend:SI
2209	 (mem:I12MODE (match_operand:SI 1 "address_operand" ""))))]
2210  "")
2211
2212(define_expand "insn_<load>_u"
2213  [(set (match_operand:SI 0 "register_operand" "")
2214	(zero_extend:SI
2215	 (mem:I12MODE (match_operand:SI 1 "address_operand" ""))))]
2216  "")
2217
2218(define_insn "insn_<load>add"
2219  [(set (match_operand:SI 1 "register_operand" "=r")
2220        (plus:SI (match_operand:SI 3 "register_operand" "1")
2221                 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2222   (set (match_operand:SI 0 "register_operand" "=r")
2223	(sign_extend:SI (mem:I12MODE (match_dup 3))))]
2224  ""
2225  "<load>add\t%0, %1, %2"
2226  [(set_attr "type" "X1_2cycle")])
2227
2228(define_insn "insn_<load>add_u"
2229  [(set (match_operand:SI 1 "register_operand" "=r")
2230        (plus:SI (match_operand:SI 3 "register_operand" "1")
2231                 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2232   (set (match_operand:SI 0 "register_operand" "=r")
2233        (zero_extend:SI (mem:I12MODE (match_dup 3))))]
2234  ""
2235  "<load>add_u\t%0, %1, %2"
2236  [(set_attr "type" "X1_2cycle")])
2237
2238(define_expand "insn_lw"
2239  [(set (match_operand:SI 0 "register_operand" "")
2240	(mem:SI (match_operand:SI 1 "address_operand" "")))]
2241  "")
2242
2243(define_insn "insn_lwadd"
2244  [(set (match_operand:SI 1 "register_operand" "=r")
2245        (plus:SI (match_operand:SI 3 "register_operand" "1")
2246                 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2247   (set (match_operand:SI 0 "register_operand" "=r")
2248        (mem:SI (match_dup 3)))]
2249  ""
2250  "lwadd\t%0, %1, %2"
2251  [(set_attr "type" "X1_2cycle")])
2252
2253(define_insn "insn_lwadd_na"
2254  [(set (match_operand:SI 1 "register_operand" "=r")
2255        (plus:SI (match_operand:SI 3 "register_operand" "1")
2256                 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2257   (set (match_operand:SI 0 "register_operand" "=r")
2258        (mem:SI (and:SI (match_dup 3) (const_int -4))))]
2259  ""
2260  "lwadd_na\t%0, %1, %2"
2261  [(set_attr "type" "X1_2cycle")])
2262
2263(define_insn "insn_lw_na"
2264  [(set (match_operand:SI 0 "register_operand" "=r")
2265	(mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO")
2266                        (const_int -4))))]
2267  ""
2268  "lw_na\t%0, %r1"
2269  [(set_attr "type" "X1_2cycle")])
2270
2271;; L2 hits
2272
2273(define_insn "insn_<load>_L2"
2274  [(set (match_operand:SI 0 "register_operand" "=r")
2275	(sign_extend:SI
2276	 (unspec:I12MODE
2277	  [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
2278	  UNSPEC_LATENCY_L2)))]
2279  ""
2280  "<load>\t%0, %r1"
2281  [(set_attr "type" "Y2_L2")])
2282
2283(define_insn "insn_<load>_u_L2"
2284  [(set (match_operand:SI 0 "register_operand" "=r")
2285	(zero_extend:SI
2286	 (unspec:I12MODE
2287	  [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
2288	  UNSPEC_LATENCY_L2)))]
2289  ""
2290  "<load>_u\t%0, %r1"
2291  [(set_attr "type" "Y2_L2")])
2292
2293(define_insn "insn_<load>add_L2"
2294  [(set (match_operand:SI 1 "register_operand" "=r")
2295        (plus:SI (match_operand:SI 3 "register_operand" "1")
2296                 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2297   (set (match_operand:SI 0 "register_operand" "=r")
2298        (sign_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
2299					UNSPEC_LATENCY_L2)))]
2300  ""
2301  "<load>add\t%0, %1, %2"
2302  [(set_attr "type" "X1_L2")])
2303
2304(define_insn "insn_<load>add_u_L2"
2305  [(set (match_operand:SI 1 "register_operand" "=r")
2306        (plus:SI (match_operand:SI 3 "register_operand" "1")
2307                 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2308   (set (match_operand:SI 0 "register_operand" "=r")
2309        (zero_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
2310					UNSPEC_LATENCY_L2)))]
2311  ""
2312  "<load>add_u\t%0, %1, %2"
2313  [(set_attr "type" "X1_L2")])
2314
2315(define_insn "insn_lwadd_L2"
2316  [(set (match_operand:SI 1 "register_operand" "=r")
2317        (plus:SI (match_operand:SI 3 "register_operand" "1")
2318                 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2319   (set (match_operand:SI 0 "register_operand" "=r")
2320        (unspec:SI [(mem:SI (match_dup 3))] UNSPEC_LATENCY_L2))]
2321  ""
2322  "lwadd\t%0, %1, %2"
2323  [(set_attr "type" "X1_L2")])
2324
2325(define_insn "insn_lwadd_na_L2"
2326  [(set (match_operand:SI 1 "register_operand" "=r")
2327        (plus:SI (match_operand:SI 3 "register_operand" "1")
2328                 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2329   (set (match_operand:SI 0 "register_operand" "=r")
2330        (unspec:SI [(mem:SI (and:SI (match_dup 3) (const_int -4)))]
2331		   UNSPEC_LATENCY_L2))]
2332  ""
2333  "lwadd_na\t%0, %1, %2"
2334  [(set_attr "type" "X1_L2")])
2335
2336(define_insn "insn_lw_na_L2"
2337  [(set (match_operand:SI 0 "register_operand" "=r")
2338	(unspec:SI [(mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO")
2339				    (const_int -4)))]
2340		   UNSPEC_LATENCY_L2))]
2341  ""
2342  "lw_na\t%0, %r1"
2343  [(set_attr "type" "X1_L2")])
2344
2345(define_insn "insn_lw_L2"
2346  [(set (match_operand:SI 0 "register_operand" "=r")
2347	(unspec:SI [(mem:SI (match_operand:SI 1 "address_operand" "rO"))]
2348		   UNSPEC_LATENCY_L2))]
2349  ""
2350  "lw\t%0, %r1"
2351  [(set_attr "type" "Y2_L2")])
2352
2353;; L2 miss
2354
2355(define_insn "insn_<load>_miss"
2356  [(set (match_operand:SI 0 "register_operand" "=r")
2357	(sign_extend:SI
2358	 (unspec:I12MODE
2359	  [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
2360	  UNSPEC_LATENCY_MISS)))]
2361  ""
2362  "<load>\t%0, %r1"
2363  [(set_attr "type" "Y2_miss")])
2364
2365(define_insn "insn_<load>_u_miss"
2366  [(set (match_operand:SI 0 "register_operand" "=r")
2367	(zero_extend:SI
2368	 (unspec:I12MODE
2369	  [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
2370	  UNSPEC_LATENCY_MISS)))]
2371  ""
2372  "<load>_u\t%0, %r1"
2373  [(set_attr "type" "Y2_miss")])
2374
2375(define_insn "insn_<load>add_miss"
2376  [(set (match_operand:SI 1 "register_operand" "=r")
2377        (plus:SI (match_operand:SI 3 "register_operand" "1")
2378                 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2379   (set (match_operand:SI 0 "register_operand" "=r")
2380        (sign_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
2381					UNSPEC_LATENCY_MISS)))]
2382  ""
2383  "<load>add\t%0, %1, %2"
2384  [(set_attr "type" "X1_miss")])
2385
2386(define_insn "insn_<load>add_u_miss"
2387  [(set (match_operand:SI 1 "register_operand" "=r")
2388        (plus:SI (match_operand:SI 3 "register_operand" "1")
2389                 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2390   (set (match_operand:SI 0 "register_operand" "=r")
2391        (zero_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
2392					UNSPEC_LATENCY_MISS)))]
2393  ""
2394  "<load>add_u\t%0, %1, %2"
2395  [(set_attr "type" "X1_miss")])
2396
2397(define_insn "insn_lwadd_miss"
2398  [(set (match_operand:SI 1 "register_operand" "=r")
2399        (plus:SI (match_operand:SI 3 "register_operand" "1")
2400                 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2401   (set (match_operand:SI 0 "register_operand" "=r")
2402        (unspec:SI [(mem:SI (match_dup 3))] UNSPEC_LATENCY_MISS))]
2403  ""
2404  "lwadd\t%0, %1, %2"
2405  [(set_attr "type" "X1_miss")])
2406
2407(define_insn "insn_lwadd_na_miss"
2408  [(set (match_operand:SI 1 "register_operand" "=r")
2409        (plus:SI (match_operand:SI 3 "register_operand" "1")
2410                 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2411   (set (match_operand:SI 0 "register_operand" "=r")
2412        (unspec:SI [(mem:SI (and:SI (match_dup 3) (const_int -4)))]
2413		   UNSPEC_LATENCY_MISS))]
2414  ""
2415  "lwadd_na\t%0, %1, %2"
2416  [(set_attr "type" "X1_miss")])
2417
2418(define_insn "insn_lw_na_miss"
2419  [(set (match_operand:SI 0 "register_operand" "=r")
2420	(unspec:SI [(mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO")
2421				    (const_int -4)))]
2422		   UNSPEC_LATENCY_MISS))]
2423  ""
2424  "lw_na\t%0, %r1"
2425  [(set_attr "type" "X1_miss")])
2426
2427(define_insn "insn_lw_miss"
2428  [(set (match_operand:SI 0 "register_operand" "=r")
2429	(unspec:SI [(mem:SI (match_operand:SI 1 "address_operand" "rO"))]
2430		   UNSPEC_LATENCY_MISS))]
2431  ""
2432  "lw\t%0, %r1"
2433  [(set_attr "type" "Y2_miss")])
2434
2435;; end loads
2436
2437(define_insn "insn_mfspr"
2438  [(set (match_operand:SI 0 "register_operand" "=r")
2439        (unspec_volatile:SI [(match_operand:SI 1 "u15bit_cint_operand" "i")]
2440                            UNSPEC_INSN_MFSPR))
2441   (clobber (mem:BLK (const_int 0)))]
2442  ""
2443  "mfspr\t%0, %1"
2444  [(set_attr "type" "X1")])
2445
2446(define_insn "*mm"
2447  [(set (match_operand:SI 0 "register_operand" "=r")
2448	(mm_combiner:SI
2449	 (and:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2450		 (match_operand:SI 3 "const_int_operand" "n"))
2451	 (and:SI (match_operand:SI 2 "reg_or_0_operand" "rO")
2452		 (match_operand:SI 4 "const_int_operand" "n"))))]
2453  "tilepro_bitfield_operand_p (INTVAL (operands[3]), NULL, NULL)
2454   && INTVAL (operands[3]) == ~INTVAL (operands[4])"
2455  "mm\t%0, %r1, %r2, %M3"
2456  [(set_attr "type" "X01")])
2457
2458(define_expand "insn_mm"
2459  [(set (match_operand:SI 0 "register_operand" "")
2460	(ior:SI
2461	 (and:SI (match_operand:SI 1 "reg_or_cint_operand" "")
2462		 (match_operand:SI 3 "u5bit_cint_operand" ""))
2463	 (and:SI (match_operand:SI 2 "reg_or_cint_operand" "")
2464		 (match_operand:SI 4 "u5bit_cint_operand" ""))))]
2465  ""
2466{
2467  int first, last, i;
2468  HOST_WIDE_INT mask;
2469
2470  first = INTVAL (operands[3]) & 31;
2471  last = INTVAL (operands[4]) & 31;
2472
2473  if (((last + 1) & 31) == first)
2474    {
2475      /* Handle pathological case of a mask that includes only the
2476         first operand. The reordering code below can't handle this. */
2477      emit_move_insn (operands[0], operands[1]);
2478      DONE;
2479    }
2480
2481  /* Canonicalize order by putting constant second, if any. */
2482  if (CONST_INT_P (operands[1]))
2483    {
2484      int tmp_first;
2485
2486      rtx tmp = operands[1];
2487      operands[1] = operands[2];
2488      operands[2] = tmp;
2489
2490      /* Invert the bit range. */
2491      tmp_first = first;
2492      first = (last + 1) & 31;
2493      last = (tmp_first - 1) & 31;
2494    }
2495
2496  /* Convert the first/last bit range into a bit mask. */
2497  mask = 0;
2498
2499  for (i = first; ; i = (i + 1) & 31)
2500    {
2501      mask |= ((HOST_WIDE_INT)1) << i;
2502      if (i == last)
2503        break;
2504    }
2505
2506  mask = trunc_int_for_mode (mask, SImode);
2507
2508  operands[1] = force_reg (SImode, operands[1]);
2509  operands[3] = GEN_INT (mask);
2510  operands[4] = GEN_INT (~mask);
2511
2512  if (CONST_INT_P (operands[2]))
2513    {
2514      HOST_WIDE_INT inserted_bits = INTVAL (operands[2]) & ~mask;
2515
2516      if (inserted_bits == 0)
2517        {
2518	  /* All inserted bits are zero. Use a bitwise AND. */
2519          emit_insn (gen_andsi3 (operands[0], operands[1], operands[3]));
2520          DONE;
2521        }
2522      else if (inserted_bits == ~mask)
2523        {
2524	  /* All inserted bits are ones. Use a bitwise IOR if we can. */
2525	  if (satisfies_constraint_I (operands[4]))
2526	    {
2527              emit_insn (gen_iorsi3 (operands[0], operands[1], operands[4]));
2528              DONE;
2529	    }
2530
2531	  /* Canonicalize to inserting -1 when setting all masked bits
2532	     to 1, to facilitate CSE. */
2533	  inserted_bits = -1;
2534        }
2535
2536      /* Sign extend the inserted bits to make them easier to materialize
2537         in a register, but only if the inserted bits (~mask) do not already
2538	 include the high bits. */
2539      if ((~mask & 0x80000000) == 0)
2540        {
2541          int shift = sizeof (HOST_WIDE_INT) * 8 - first;
2542          inserted_bits = (inserted_bits << shift) >> shift;
2543        }
2544
2545      operands[2] = GEN_INT (inserted_bits);
2546    }
2547
2548  operands[2] = force_reg (SImode, operands[2]);
2549})
2550
2551(define_insn "insn_movelis"
2552  [(set (match_operand:SI 0 "register_operand" "=r")
2553        (unspec_volatile:SI [(match_operand:SI 1 "s16bit_cint_operand" "i")]
2554                            UNSPEC_INSN_MOVELIS))]
2555  ""
2556  "movelis\t%0, %1"
2557  [(set_attr "type" "X01")])
2558
2559(define_insn "insn_mtspr"
2560  [(unspec_volatile:SI [(match_operand:SI 0 "u15bit_cint_operand" "i")
2561                        (match_operand:SI 1 "reg_or_0_operand" "rO")]
2562                       UNSPEC_INSN_MTSPR)
2563   (clobber (mem:BLK (const_int 0)))]
2564  ""
2565  "mtspr\t%0, %r1"
2566  [(set_attr "type" "X1")])
2567
2568(define_expand "insn_prefetch"
2569  [(prefetch (match_operand:SI 0 "address_operand" "")
2570             (const_int 0)
2571             (const_int 2))])
2572
2573(define_expand "insn_prefetch_L1"
2574  [(use (match_operand:SI 0 "address_operand" ""))]
2575  ""
2576{
2577  /* Generate a volatile byte load to a dummy register. */
2578  rtx mem = gen_rtx_MEM (QImode, operands[0]);
2579  MEM_VOLATILE_P (mem) = 1;
2580
2581  emit_insn (gen_zero_extendqisi2 (gen_reg_rtx (SImode), mem));
2582  DONE;
2583})
2584
2585(define_expand "insn_s1a"
2586  [(set (match_operand:SI 0 "register_operand" "")
2587        (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
2588                          (const_int 2))
2589                 (match_operand:SI 2 "reg_or_0_operand" "")))]
2590  "")
2591
2592(define_expand "insn_s2a"
2593  [(set (match_operand:SI 0 "register_operand" "")
2594        (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
2595                          (const_int 4))
2596                 (match_operand:SI 2 "reg_or_0_operand" "")))]
2597  "")
2598
2599(define_expand "insn_s3a"
2600  [(set (match_operand:SI 0 "register_operand" "")
2601        (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
2602                          (const_int 8))
2603                 (match_operand:SI 2 "reg_or_0_operand" "")))]
2604  "")
2605
2606(define_expand "insn_<store>"
2607  [(set (mem:I12MODE (match_operand:SI 0 "address_operand" ""))
2608        (match_operand:SI 1 "reg_or_0_operand" ""))]
2609  ""
2610{
2611  operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], SImode, 0);
2612})
2613
2614(define_expand "insn_sw"
2615  [(set (mem:SI (match_operand:SI 0 "address_operand" ""))
2616        (match_operand:SI 1 "reg_or_0_operand" ""))]
2617  "")
2618
2619(define_expand "insn_<store>add"
2620  [(parallel
2621    [(set (match_operand:SI 0 "register_operand" "")
2622	  (plus:SI (match_operand:SI 3 "register_operand" "")
2623		   (match_operand:SI 2 "s8bit_cint_operand" "")))
2624     (set (mem:I12MODE (match_dup 3))
2625	  (match_operand:SI 1 "reg_or_0_operand" ""))])]
2626  ""
2627{
2628  operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], SImode, 0);
2629})
2630
2631(define_insn "*insn_<store>add"
2632  [(set (match_operand:SI 0 "register_operand" "=r")
2633	(plus:SI (match_operand:SI 3 "register_operand" "0")
2634		 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2635   (set (mem:I12MODE (match_dup 3))
2636	(match_operand:I12MODE 1 "reg_or_0_operand" "rO"))]
2637  ""
2638  "<store>add\t%0, %r1, %2"
2639  [(set_attr "type" "X1")])
2640
2641(define_insn "insn_swadd"
2642  [(set (match_operand:SI 0 "register_operand" "=r")
2643        (plus:SI (match_operand:SI 3 "register_operand" "0")
2644                 (match_operand:SI 2 "s8bit_cint_operand" "i")))
2645   (set (mem:SI (match_dup 3))
2646        (match_operand:SI 1 "reg_or_0_operand" "rO"))]
2647  ""
2648  "swadd\t%0, %r1, %2"
2649  [(set_attr "type" "X1")])
2650
2651(define_insn "insn_wh64"
2652  [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")]
2653                         UNSPEC_INSN_WH64)
2654   (clobber (mem:BLK (const_int 0)))]
2655  ""
2656  "wh64\t%r0"
2657  [(set_attr "type" "X1")])
2658
2659(define_insn "insn_tns"
2660  [(set (match_operand:SI 0 "register_operand" "=r")
2661        (mem:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))
2662   (set (mem:SI (match_dup 1)) (const_int 1))]
2663  ""
2664  "tns\t%0, %1"
2665  [(set_attr "type" "X1")])
2666
2667;; insn_addb
2668;; insn_addib
2669;; insn_maxb_u
2670;; insn_maxib_u
2671;; insn_minb_u
2672;; insn_minib_u
2673;; insn_seqb
2674;; insn_seqib
2675;; insn_sltb
2676;; insn_sltib
2677;; insn_sltb_u
2678;; insn_sltib_u
2679(define_insn "<optab>v4qi3"
2680  [(set (match_operand:V4QI 0 "register_operand" "=r,r")
2681	(v1op_immed:V4QI
2682	 (match_operand:V4QI 1 "reg_or_0_operand" "<comm>rO,rO")
2683	 (match_operand:V4QI 2 "reg_or_v4s8bit_operand" "W,rO")))]
2684  ""
2685  "@
2686   <insn>ib<u>\t%0, %r1, %j2
2687   <insn>b<u>\t%0, %r1, %r2"
2688  [(set_attr "type" "X01,X01")])
2689
2690(define_expand "insn_<insn>b<u>"
2691  [(set (match_operand:SI 0 "register_operand" "")
2692	(v1op_immed:V4QI
2693	 (match_operand:SI 1 "reg_or_0_operand" "")
2694	 (match_operand:SI 2 "reg_or_0_operand" "")))]
2695  ""
2696{
2697  tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
2698				       V4QImode, operands[1], operands[2], true);
2699  DONE;
2700})
2701
2702(define_expand "insn_<insn>ib<u>"
2703  [(set (match_operand:SI 0 "register_operand" "")
2704	(v1op_immed:V4QI
2705	 (match_operand:SI 1 "reg_or_0_operand" "")
2706	 (match_operand:SI 2 "s8bit_cint_operand" "")))]
2707  ""
2708{
2709  /* Tile out immediate and expand to general case. */
2710  rtx n = tilepro_simd_int (operands[2], QImode);
2711  tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
2712				       V4QImode, operands[1], n, true);
2713  DONE;
2714})
2715
2716;; insn_shlb
2717;; insn_shlib
2718;; insn_shrb
2719;; insn_shrib
2720;; insn_srab
2721;; insn_sraib
2722(define_insn "<optab>v4qi3"
2723  [(set (match_operand:V4QI 0 "register_operand" "=r,r")
2724	(any_shift:V4QI
2725	 (match_operand:V4QI 1 "reg_or_0_operand" "rO,rO")
2726	 (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
2727  ""
2728  "@
2729   <insn>ib<u>\t%0, %r1, %2
2730   <insn>b<u>\t%0, %r1, %r2"
2731  [(set_attr "type" "X01,X01")])
2732
2733(define_expand "insn_<insn>b<u>"
2734  [(set (match_operand:SI 0 "register_operand" "")
2735	(any_shift:V4QI
2736	 (match_operand:SI 1 "reg_or_0_operand" "")
2737	 (match_operand:SI 2 "reg_or_u5bit_operand" "")))]
2738  ""
2739{
2740  tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
2741				    V4QImode, operands[1], operands[2], false);
2742  DONE;
2743})
2744
2745;; insn_addh
2746;; insn_addih
2747;; insn_maxh
2748;; insn_maxih
2749;; insn_minh
2750;; insn_minih
2751;; insn_seqh
2752;; insn_seqih
2753;; insn_slth
2754;; insn_sltih
2755;; insn_slth_u
2756;; insn_sltih_u
2757(define_insn "<optab>v2hi3"
2758  [(set (match_operand:V2HI 0 "register_operand" "=r,r")
2759	(v2op_immed:V2HI
2760	 (match_operand:V2HI 1 "reg_or_0_operand" "<comm>rO,rO")
2761	 (match_operand:V2HI 2 "reg_or_v2s8bit_operand" "Y,rO")))]
2762  ""
2763  "@
2764   <insn>ih<u>\t%0, %r1, %j2
2765   <insn>h<u>\t%0, %r1, %r2"
2766  [(set_attr "type" "X01,X01")])
2767
2768(define_expand "insn_<insn>h<u>"
2769  [(set (match_operand:SI 0 "register_operand" "")
2770	(v2op_immed:V2HI
2771	 (match_operand:SI 1 "reg_or_0_operand" "")
2772	 (match_operand:SI 2 "reg_or_0_operand" "")))]
2773  ""
2774{
2775  tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
2776				       V2HImode, operands[1], operands[2], true);
2777  DONE;
2778})
2779
2780(define_expand "insn_<insn>ih<u>"
2781  [(set (match_operand:SI 0 "register_operand" "")
2782	(v2op_immed:V2HI
2783	 (match_operand:SI 1 "reg_or_0_operand" "")
2784	 (match_operand:SI 2 "s8bit_cint_operand" "")))]
2785  ""
2786{
2787  /* Tile out immediate and expand to general case. */
2788  rtx n = tilepro_simd_int (operands[2], HImode);
2789  tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
2790				       V2HImode, operands[1], n, true);
2791  DONE;
2792})
2793
2794;; insn_shlh
2795;; insn_shlih
2796;; insn_shrh
2797;; insn_shrih
2798;; insn_srah
2799;; insn_sraih
2800(define_insn "<optab>v2hi3"
2801  [(set (match_operand:V2HI 0 "register_operand" "=r,r")
2802	(any_shift:V2HI
2803	 (match_operand:V2HI 1 "reg_or_0_operand" "rO,rO")
2804	 (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
2805  ""
2806  "@
2807   <insn>ih<u>\t%0, %r1, %2
2808   <insn>h<u>\t%0, %r1, %r2"
2809  [(set_attr "type" "X01,X01")])
2810
2811(define_expand "insn_<insn>h<u>"
2812  [(set (match_operand:SI 0 "register_operand" "")
2813	(any_shift:V2HI
2814	 (match_operand:SI 1 "reg_or_0_operand" "")
2815	 (match_operand:SI 2 "reg_or_0_operand" "")))]
2816  ""
2817{
2818  tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
2819				       V2HImode, operands[1], operands[2], false);
2820  DONE;
2821})
2822
2823;; insn_addbs_u
2824;; insn_subbs_u
2825;; insn_subb
2826;; insn_slteb
2827;; insn_slteb_u
2828;; insn_sneb
2829(define_insn "<optab>v4qi3"
2830  [(set (match_operand:V4QI 0 "register_operand" "=r")
2831	(v1op:V4QI
2832	 (match_operand:V4QI 1 "reg_or_0_operand" "<comm>rO")
2833	 (match_operand:V4QI 2 "reg_or_0_operand" "rO")))]
2834  ""
2835  "<insn>b<u>\t%0, %r1, %r2"
2836  [(set_attr "type" "X01")])
2837
2838(define_expand "insn_<insn>b<u>"
2839  [(set (match_operand:SI 0 "register_operand" "")
2840	(v1op:V4QI
2841	 (match_operand:SI 1 "reg_or_0_operand" "")
2842	 (match_operand:SI 2 "reg_or_0_operand" "")))]
2843  ""
2844{
2845  tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
2846				       V4QImode, operands[1], operands[2], true);
2847  DONE;
2848})
2849
2850;; insn_addhs
2851;; insn_subhs
2852;; insn_subh
2853;; insn_slteh
2854;; insn_slteh_u
2855;; insn_sneh
2856(define_insn "<optab>v2hi3"
2857  [(set (match_operand:V2HI 0 "register_operand" "=r")
2858	(v2op:V2HI
2859	 (match_operand:V2HI 1 "reg_or_0_operand" "<comm>rO")
2860	 (match_operand:V2HI 2 "reg_or_0_operand" "rO")))]
2861  ""
2862  "<insn>h<u>\t%0, %r1, %r2"
2863  [(set_attr "type" "X01")])
2864
2865(define_expand "insn_<insn>h<u>"
2866  [(set (match_operand:SI 0 "register_operand" "")
2867	(v2op:V2HI
2868	 (match_operand:SI 1 "reg_or_0_operand" "")
2869	 (match_operand:SI 2 "reg_or_0_operand" "")))]
2870  ""
2871{
2872  tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
2873				       V2HImode, operands[1], operands[2], true);
2874  DONE;
2875})
2876
2877;; insn_inthb
2878
2879;; Byte ordering of these vectors is endian dependent.  We concat
2880;; right-to-left for little endian.  We concat and interleave in the
2881;; opposite way gcc's vector patterns work, so we need to reverse the
2882;; order of source operands.
2883
2884;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
2885;; => {A3,A2,A1,A0,B3,B2,B1,B0}
2886;; => {A3,B3,A2,B2}
2887(define_insn "vec_interleave_highv4qi"
2888  [(set (match_operand:V4QI 0 "register_operand" "=r")
2889	(vec_select:V4QI
2890	 (vec_concat:V8QI (match_operand:V4QI 1 "reg_or_0_operand" "rO")
2891			  (match_operand:V4QI 2 "reg_or_0_operand" "rO"))
2892	 (parallel [(const_int 2) (const_int 6)
2893		    (const_int 3) (const_int 7)])))]
2894  ""
2895  "inthb\t%0, %r2, %r1"
2896  [(set_attr "type" "X01")])
2897
2898(define_expand "insn_inthb"
2899  [(match_operand:SI 0 "register_operand" "")
2900   (match_operand:SI 1 "reg_or_0_operand" "")
2901   (match_operand:SI 2 "reg_or_0_operand" "")]
2902  ""
2903{
2904  /* Our instruction interleaves opposite of the way vec_interleave
2905     works, so we need to reverse the source operands.  */
2906  tilepro_expand_builtin_vector_binop (gen_vec_interleave_highv4qi, V4QImode,
2907                                       operands[0], V4QImode, operands[2],
2908				       operands[1], true);
2909  DONE;
2910})
2911
2912;; insn_intlb
2913;;    {B3,B2,B1,B0} {A3,A2,A1,A0}
2914;; => {A3,A2,A1,A0,B3,B2,B1,B0}
2915;; => {A1,B1,A0,B0}
2916(define_insn "vec_interleave_lowv4qi"
2917  [(set (match_operand:V4QI 0 "register_operand" "=r")
2918	(vec_select:V4QI
2919	 (vec_concat:V8QI (match_operand:V4QI 1 "reg_or_0_operand" "rO")
2920			  (match_operand:V4QI 2 "reg_or_0_operand" "rO"))
2921	 (parallel [(const_int 0) (const_int 4)
2922		    (const_int 1) (const_int 5)])))]
2923  ""
2924  "intlb\t%0, %r2, %r1"
2925  [(set_attr "type" "X01")])
2926
2927(define_expand "insn_intlb"
2928  [(match_operand:SI 0 "register_operand" "")
2929   (match_operand:SI 1 "reg_or_0_operand" "")
2930   (match_operand:SI 2 "reg_or_0_operand" "")]
2931  ""
2932{
2933  /* Our instruction interleaves opposite of the way vec_interleave
2934     works, so we need to reverse the source operands.  */
2935  tilepro_expand_builtin_vector_binop (gen_vec_interleave_lowv4qi, V4QImode,
2936				       operands[0], V4QImode, operands[2],
2937				       operands[1], true);
2938  DONE;
2939})
2940
2941;; insn_inthh
2942;;    {B1,B0} {A1,A0}
2943;; => {A1,A0,B1,B0}
2944;; => {A1,B1}
2945(define_insn "vec_interleave_highv2hi"
2946  [(set (match_operand:V2HI 0 "register_operand" "=r")
2947	(vec_select:V2HI
2948	 (vec_concat:V4HI (match_operand:V2HI 1 "reg_or_0_operand" "rO")
2949			  (match_operand:V2HI 2 "reg_or_0_operand" "rO"))
2950	 (parallel [(const_int 1) (const_int 3)])))]
2951  ""
2952  "inthh\t%0, %r2, %r1"
2953  [(set_attr "type" "X01")])
2954
2955(define_expand "insn_inthh"
2956  [(match_operand:SI 0 "register_operand" "")
2957   (match_operand:SI 1 "reg_or_0_operand" "")
2958   (match_operand:SI 2 "reg_or_0_operand" "")]
2959  ""
2960{
2961  /* Our instruction interleaves opposite of the way vec_interleave
2962     works, so we need to reverse the source operands.  */
2963  tilepro_expand_builtin_vector_binop (gen_vec_interleave_highv2hi, V2HImode,
2964                                       operands[0], V2HImode, operands[2],
2965				       operands[1], true);
2966  DONE;
2967})
2968
2969;; insn_intlh
2970;;    {B1,B0} {A1,A0}
2971;; => {A1,A0,B1,B0}
2972;; => {A0,B0}
2973(define_insn "vec_interleave_lowv2hi"
2974  [(set (match_operand:V2HI 0 "register_operand" "=r")
2975	(vec_select:V2HI
2976	 (vec_concat:V4HI (match_operand:V2HI 1 "reg_or_0_operand" "rO")
2977			  (match_operand:V2HI 2 "reg_or_0_operand" "rO"))
2978	 (parallel [(const_int 0) (const_int 2)])))]
2979  ""
2980  "intlh\t%0, %r2, %r1"
2981  [(set_attr "type" "X01")])
2982
2983(define_expand "insn_intlh"
2984  [(match_operand:SI 0 "register_operand" "")
2985   (match_operand:SI 1 "reg_or_0_operand" "")
2986   (match_operand:SI 2 "reg_or_0_operand" "")]
2987  ""
2988{
2989  /* Our instruction interleaves opposite of the way vec_interleave
2990     works, so we need to reverse the source operands.  */
2991  tilepro_expand_builtin_vector_binop (gen_vec_interleave_lowv2hi, V2HImode,
2992                                       operands[0], V2HImode, operands[2],
2993				       operands[1], true);
2994  DONE;
2995})
2996
2997;; insn_packbs_u
2998;; insn_packlb
2999;;    {B1,B0} {A1,A0}
3000;; => {A1,A0,B1,B0}
3001(define_insn "vec_pack_<pack_optab>_v2hi"
3002  [(set (match_operand:V4QI 0 "register_operand" "=r")
3003	(vec_concat:V4QI
3004	 (v2pack:V2QI (match_operand:V2HI 1 "reg_or_0_operand" "rO"))
3005	 (v2pack:V2QI (match_operand:V2HI 2 "reg_or_0_operand" "rO"))))]
3006  ""
3007  "<pack_insn>b<pack_u>\t%0, %r2, %r1"
3008  [(set_attr "type" "X01")])
3009
3010(define_expand "insn_<pack_insn>b<pack_u>"
3011  [(set (match_operand:SI 0 "register_operand" "")
3012	(vec_concat:V4QI
3013	 (v2pack:V2QI (match_operand:SI 1 "reg_or_0_operand" ""))
3014	 (v2pack:V2QI (match_operand:SI 2 "reg_or_0_operand" ""))))]
3015  ""
3016{
3017  /* Our instruction concats opposite of the way vec_pack works, so we
3018     need to reverse the source operands.  */
3019  tilepro_expand_builtin_vector_binop (gen_vec_pack_<pack_optab>_v2hi,
3020                                       V4QImode, operands[0],
3021                                       V2HImode, operands[2], operands[1], true);
3022  DONE;
3023})
3024
3025;; insn_packhb
3026;;    {B1,B0} {A1,A0}
3027;; => {A1,A0,B1,B0}
3028(define_insn "vec_pack_hipart_v2hi"
3029  [(set (match_operand:V4QI 0 "register_operand" "=r")
3030	(vec_concat:V4QI
3031	 (truncate:V2QI
3032	  (ashiftrt:V2HI (match_operand:V2HI 1 "reg_or_0_operand" "rO")
3033			 (const_int 8)))
3034	 (truncate:V2QI
3035	  (ashiftrt:V2HI (match_operand:V2HI 2 "reg_or_0_operand" "rO")
3036			 (const_int 8)))))]
3037  ""
3038  "packhb\t%0, %r2, %r1"
3039  [(set_attr "type" "X01")])
3040
3041(define_expand "insn_packhb"
3042  [(set (match_operand:SI 0 "register_operand" "")
3043	(vec_concat:V4QI
3044	 (truncate:V2QI
3045	  (ashiftrt:V2HI (match_operand:SI 2 "reg_or_0_operand" "")
3046			 (const_int 8)))
3047	 (truncate:V2QI
3048	  (ashiftrt:V2HI (match_operand:SI 1 "reg_or_0_operand" "")
3049			 (const_int 8)))))]
3050  ""
3051{
3052  /* Our instruction concats opposite of the way vec_pack works, so we
3053     need to reverse the source operands.  */
3054  tilepro_expand_builtin_vector_binop (gen_vec_pack_hipart_v2hi,
3055                                       V4QImode, operands[0],
3056                                       V2HImode, operands[2], operands[1], true);
3057  DONE;
3058})
3059
3060;; insn_packhs
3061;;    {B0} {A0}
3062;; => {A0,B0}
3063(define_insn "vec_pack_ssat_si"
3064  [(set (match_operand:V2HI 0 "register_operand" "=r")
3065	(vec_concat:V2HI
3066	 (ss_truncate:HI (match_operand:SI 1 "reg_or_0_operand" "rO"))
3067	 (ss_truncate:HI (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
3068  ""
3069  "packhs\t%0, %r2, %r1"
3070  [(set_attr "type" "X01")])
3071
3072(define_expand "insn_packhs"
3073  [(set (match_operand:SI 0 "register_operand" "")
3074	(vec_concat:V2HI
3075	 (ss_truncate:HI (match_operand:SI 2 "reg_or_0_operand" ""))
3076	 (ss_truncate:HI (match_operand:SI 1 "reg_or_0_operand" ""))))]
3077  ""
3078{
3079  /* Our instruction concats opposite of the way vec_pack works, so we
3080     need to reverse the source operands.  */
3081  tilepro_expand_builtin_vector_binop (gen_vec_pack_ssat_si,
3082                                       V2HImode, operands[0],
3083                                       SImode, operands[2], operands[1], true);
3084  DONE;
3085})
3086
3087;; Rest of the intrinsics
3088(define_insn "insn_adiffb_u"
3089  [(set (match_operand:SI 0 "register_operand" "=r")
3090        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3091                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3092                   UNSPEC_INSN_ADIFFB_U))]
3093  ""
3094  "adiffb_u\t%0, %r1, %r2"
3095  [(set_attr "type" "X0_2cycle")])
3096
3097(define_insn "insn_adiffh"
3098  [(set (match_operand:SI 0 "register_operand" "=r")
3099        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3100                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3101                   UNSPEC_INSN_ADIFFH))]
3102  ""
3103  "adiffh\t%0, %r1, %r2"
3104  [(set_attr "type" "X0_2cycle")])
3105
3106(define_insn "insn_avgb_u"
3107  [(set (match_operand:SI 0 "register_operand" "=r")
3108        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3109                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3110                   UNSPEC_INSN_AVGB_U))]
3111  ""
3112  "avgb_u\t%0, %r1, %r2"
3113  [(set_attr "type" "X0")])
3114
3115(define_insn "insn_avgh"
3116  [(set (match_operand:SI 0 "register_operand" "=r")
3117        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3118                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3119                   UNSPEC_INSN_AVGH))]
3120  ""
3121  "avgh\t%0, %r1, %r2"
3122  [(set_attr "type" "X0")])
3123
3124(define_insn "insn_bitx"
3125  [(set (match_operand:SI 0 "register_operand" "=r")
3126        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")]
3127                    UNSPEC_INSN_BITX))]
3128  ""
3129  "bitx\t%0, %r1"
3130  [(set_attr "type" "Y0")])
3131
3132(define_insn "insn_crc32_32"
3133  [(set (match_operand:SI 0 "register_operand" "=r")
3134        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3135                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3136                   UNSPEC_INSN_CRC32_32))]
3137  ""
3138  "crc32_32\t%0, %r1, %r2"
3139  [(set_attr "type" "X0")])
3140
3141(define_insn "insn_crc32_8"
3142  [(set (match_operand:SI 0 "register_operand" "=r")
3143        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3144                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3145                   UNSPEC_INSN_CRC32_8))]
3146  ""
3147  "crc32_8\t%0, %r1, %r2"
3148  [(set_attr "type" "X0")])
3149
3150(define_insn "insn_dtlbpr"
3151  [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")]
3152                         UNSPEC_INSN_DTLBPR)]
3153  ""
3154  "dtlbpr\t%r0"
3155  [(set_attr "type" "X1")])
3156
3157(define_insn "insn_dword_align"
3158  [(set (match_operand:SI 0 "register_operand" "=r")
3159        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3160                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3161                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3162                   UNSPEC_INSN_DWORD_ALIGN))]
3163  ""
3164  "dword_align\t%0, %r2, %r3"
3165  [(set_attr "type" "X0")])
3166
3167(define_insn "insn_finv"
3168  [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")]
3169                         UNSPEC_INSN_FINV)]
3170  ""
3171  "finv\t%r0"
3172  [(set_attr "type" "X1")])
3173
3174(define_insn "insn_flush"
3175  [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")]
3176                         UNSPEC_INSN_FLUSH)]
3177  ""
3178  "flush\t%r0"
3179  [(set_attr "type" "X1")])
3180
3181(define_insn "insn_fnop"
3182  [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FNOP)]
3183  ""
3184  "fnop")
3185
3186(define_insn "insn_ill"
3187  [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_ILL)]
3188  ""
3189  "ill"
3190  [(set_attr "type" "cannot_bundle")])
3191
3192(define_insn "insn_inv"
3193  [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")]
3194                         UNSPEC_INSN_INV)]
3195  ""
3196  "inv\t%r0"
3197  [(set_attr "type" "X1")])
3198
3199(define_insn "insn_lnk"
3200  [(set (match_operand:SI 0 "register_operand" "=r")
3201        (unspec:SI [(const_int 0)] UNSPEC_INSN_LNK))]
3202  ""
3203  "lnk\t%0"
3204  [(set_attr "type" "X1")])
3205
3206(define_insn "insn_mnzb"
3207  [(set (match_operand:SI 0 "register_operand" "=r")
3208        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3209                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3210                   UNSPEC_INSN_MNZB))]
3211  ""
3212  "mnzb\t%0, %r1, %r2"
3213  [(set_attr "type" "X01")])
3214
3215(define_insn "insn_mnzh"
3216  [(set (match_operand:SI 0 "register_operand" "=r")
3217        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3218                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3219                   UNSPEC_INSN_MNZH))]
3220  ""
3221  "mnzh\t%0, %r1, %r2"
3222  [(set_attr "type" "X01")])
3223
3224(define_insn "insn_mulhh_ss"
3225  [(set (match_operand:SI 0 "register_operand" "=r")
3226        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3227                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3228                   UNSPEC_INSN_MULHH_SS))]
3229  ""
3230  "mulhh_ss\t%0, %r1, %r2"
3231  [(set_attr "type" "Y0_2cycle")])
3232
3233(define_insn "insn_mulhh_su"
3234  [(set (match_operand:SI 0 "register_operand" "=r")
3235        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3236                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3237                   UNSPEC_INSN_MULHH_SU))]
3238  ""
3239  "mulhh_su\t%0, %r1, %r2"
3240  [(set_attr "type" "X0_2cycle")])
3241
3242(define_insn "insn_mulhh_uu"
3243  [(set (match_operand:SI 0 "register_operand" "=r")
3244        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3245                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3246                   UNSPEC_INSN_MULHH_UU))]
3247  ""
3248  "mulhh_uu\t%0, %r1, %r2"
3249  [(set_attr "type" "Y0_2cycle")])
3250
3251(define_insn "insn_mulhha_ss"
3252  [(set (match_operand:SI 0 "register_operand" "=r")
3253        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3254                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3255                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3256                   UNSPEC_INSN_MULHHA_SS))]
3257  ""
3258  "mulhha_ss\t%0, %r2, %r3"
3259  [(set_attr "type" "Y0_2cycle")])
3260
3261(define_insn "insn_mulhha_su"
3262  [(set (match_operand:SI 0 "register_operand" "=r")
3263        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3264                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3265                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3266                   UNSPEC_INSN_MULHHA_SU))]
3267  ""
3268  "mulhha_su\t%0, %r2, %r3"
3269  [(set_attr "type" "X0_2cycle")])
3270
3271(define_insn "insn_mulhha_uu"
3272  [(set (match_operand:SI 0 "register_operand" "=r")
3273        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3274                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3275                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3276                   UNSPEC_INSN_MULHHA_UU))]
3277  ""
3278  "mulhha_uu\t%0, %r2, %r3"
3279  [(set_attr "type" "Y0_2cycle")])
3280
3281(define_insn "insn_mulhhsa_uu"
3282  [(set (match_operand:SI 0 "register_operand" "=r")
3283        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3284                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3285                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3286                   UNSPEC_INSN_MULHHSA_UU))]
3287  ""
3288  "mulhhsa_uu\t%0, %r2, %r3"
3289  [(set_attr "type" "X0_2cycle")])
3290
3291(define_insn "insn_mulhl_ss"
3292  [(set (match_operand:SI 0 "register_operand" "=r")
3293        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3294                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3295                   UNSPEC_INSN_MULHL_SS))]
3296  ""
3297  "mulhl_ss\t%0, %r1, %r2"
3298  [(set_attr "type" "X0_2cycle")])
3299
3300(define_insn "insn_mulhl_su"
3301  [(set (match_operand:SI 0 "register_operand" "=r")
3302        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3303                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3304                   UNSPEC_INSN_MULHL_SU))]
3305  ""
3306  "mulhl_su\t%0, %r1, %r2"
3307  [(set_attr "type" "X0_2cycle")])
3308
3309(define_insn "insn_mulhl_us"
3310  [(set (match_operand:SI 0 "register_operand" "=r")
3311        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3312                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3313                   UNSPEC_INSN_MULHL_US))]
3314  ""
3315  "mulhl_us\t%0, %r1, %r2"
3316  [(set_attr "type" "X0_2cycle")])
3317
3318(define_insn "insn_mulhl_uu"
3319  [(set (match_operand:SI 0 "register_operand" "=r")
3320        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3321                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3322                   UNSPEC_INSN_MULHL_UU))]
3323  ""
3324  "mulhl_uu\t%0, %r1, %r2"
3325  [(set_attr "type" "X0_2cycle")])
3326
3327(define_insn "insn_mulhla_ss"
3328  [(set (match_operand:SI 0 "register_operand" "=r")
3329        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3330                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3331                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3332                   UNSPEC_INSN_MULHLA_SS))]
3333  ""
3334  "mulhla_ss\t%0, %r2, %r3"
3335  [(set_attr "type" "X0_2cycle")])
3336
3337(define_insn "insn_mulhla_su"
3338  [(set (match_operand:SI 0 "register_operand" "=r")
3339        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3340                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3341                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3342                   UNSPEC_INSN_MULHLA_SU))]
3343  ""
3344  "mulhla_su\t%0, %r2, %r3"
3345  [(set_attr "type" "X0_2cycle")])
3346
3347(define_insn "insn_mulhla_us"
3348  [(set (match_operand:SI 0 "register_operand" "=r")
3349        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3350                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3351                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3352                   UNSPEC_INSN_MULHLA_US))]
3353  ""
3354  "mulhla_us\t%0, %r2, %r3"
3355  [(set_attr "type" "X0_2cycle")])
3356
3357(define_insn "insn_mulhla_uu"
3358  [(set (match_operand:SI 0 "register_operand" "=r")
3359        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3360                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3361                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3362                   UNSPEC_INSN_MULHLA_UU))]
3363  ""
3364  "mulhla_uu\t%0, %r2, %r3"
3365  [(set_attr "type" "X0_2cycle")])
3366
3367(define_insn "insn_mulhlsa_uu"
3368  [(set (match_operand:SI 0 "register_operand" "=r")
3369        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3370                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3371                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3372                   UNSPEC_INSN_MULHLSA_UU))]
3373  ""
3374  "mulhlsa_uu\t%0, %r2, %r3"
3375  [(set_attr "type" "Y0_2cycle")])
3376
3377(define_insn "insn_mulll_ss"
3378  [(set (match_operand:SI 0 "register_operand" "=r")
3379	(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3380                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3381                    UNSPEC_INSN_MULLL_SS))]
3382  ""
3383  "mulll_ss\t%0, %r1, %r2"
3384  [(set_attr "type" "Y0_2cycle")])
3385
3386(define_insn "insn_mulll_su"
3387  [(set (match_operand:SI 0 "register_operand" "=r")
3388        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3389                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3390                   UNSPEC_INSN_MULLL_SU))]
3391  ""
3392  "mulll_su\t%0, %r1, %r2"
3393  [(set_attr "type" "X0_2cycle")])
3394
3395(define_insn "insn_mulll_uu"
3396  [(set (match_operand:SI 0 "register_operand" "=r")
3397        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3398                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3399                   UNSPEC_INSN_MULLL_UU))]
3400  ""
3401  "mulll_uu\t%0, %r1, %r2"
3402  [(set_attr "type" "Y0_2cycle")])
3403
3404(define_insn "insn_mullla_ss"
3405  [(set (match_operand:SI 0 "register_operand" "=r")
3406        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3407                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3408                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3409                   UNSPEC_INSN_MULLLA_SS))]
3410  ""
3411  "mullla_ss\t%0, %r2, %r3"
3412  [(set_attr "type" "Y0_2cycle")])
3413
3414(define_insn "insn_mullla_su"
3415  [(set (match_operand:SI 0 "register_operand" "=r")
3416        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3417                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3418                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3419                   UNSPEC_INSN_MULLLA_SU))]
3420  ""
3421  "mullla_su\t%0, %r2, %r3"
3422  [(set_attr "type" "X0_2cycle")])
3423
3424(define_insn "insn_mullla_uu"
3425  [(set (match_operand:SI 0 "register_operand" "=r")
3426        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3427                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3428                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3429                   UNSPEC_INSN_MULLLA_UU))]
3430  ""
3431  "mullla_uu\t%0, %r2, %r3"
3432  [(set_attr "type" "Y0_2cycle")])
3433
3434(define_insn "insn_mulllsa_uu"
3435  [(set (match_operand:SI 0 "register_operand" "=r")
3436        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3437                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3438                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3439                   UNSPEC_INSN_MULLLSA_UU))]
3440  ""
3441  "mulllsa_uu\t%0, %r2, %r3"
3442  [(set_attr "type" "X0_2cycle")])
3443
3444(define_insn "insn_mzb"
3445  [(set (match_operand:SI 0 "register_operand" "=r")
3446        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3447                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3448                   UNSPEC_INSN_MZB))]
3449  ""
3450  "mzb\t%0, %r1, %r2"
3451  [(set_attr "type" "X01")])
3452
3453(define_insn "insn_mzh"
3454  [(set (match_operand:SI 0 "register_operand" "=r")
3455        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3456                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3457                   UNSPEC_INSN_MZH))]
3458  ""
3459  "mzh\t%0, %r1, %r2"
3460  [(set_attr "type" "X01")])
3461
3462(define_insn "insn_nap"
3463  [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_NAP)]
3464  ""
3465  "nap"
3466  [(set_attr "type" "cannot_bundle")])
3467
3468(define_insn "insn_nor"
3469  [(set (match_operand:SI 0 "register_operand" "=r")
3470        (and:SI (not:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))
3471                (not:SI (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
3472  ""
3473  "nor\t%0, %r1, %r2")
3474
3475(define_insn "insn_sadab_u"
3476  [(set (match_operand:SI 0 "register_operand" "=r")
3477        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3478                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3479                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3480                   UNSPEC_INSN_SADAB_U))]
3481  ""
3482  "sadab_u\t%0, %r2, %r3"
3483  [(set_attr "type" "X0_2cycle")])
3484
3485(define_insn "insn_sadah"
3486  [(set (match_operand:SI 0 "register_operand" "=r")
3487        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3488                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3489                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3490                   UNSPEC_INSN_SADAH))]
3491  ""
3492  "sadah\t%0, %r2, %r3"
3493  [(set_attr "type" "X0_2cycle")])
3494
3495(define_insn "insn_sadah_u"
3496  [(set (match_operand:SI 0 "register_operand" "=r")
3497        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3498                    (match_operand:SI 2 "reg_or_0_operand" "rO")
3499                    (match_operand:SI 3 "reg_or_0_operand" "rO")]
3500                   UNSPEC_INSN_SADAH_U))]
3501  ""
3502  "sadah_u\t%0, %r2, %r3"
3503  [(set_attr "type" "X0_2cycle")])
3504
3505(define_insn "insn_sadb_u"
3506  [(set (match_operand:SI 0 "register_operand" "=r")
3507        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3508                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3509                   UNSPEC_INSN_SADB_U))]
3510  ""
3511  "sadb_u\t%0, %r1, %r2"
3512  [(set_attr "type" "X0_2cycle")])
3513
3514(define_insn "insn_sadh"
3515  [(set (match_operand:SI 0 "register_operand" "=r")
3516        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3517                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3518                   UNSPEC_INSN_SADH))]
3519  ""
3520  "sadh\t%0, %r1, %r2"
3521  [(set_attr "type" "X0_2cycle")])
3522
3523(define_insn "insn_sadh_u"
3524  [(set (match_operand:SI 0 "register_operand" "=r")
3525        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
3526                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3527                   UNSPEC_INSN_SADH_U))]
3528  ""
3529  "sadh_u\t%0, %r1, %r2"
3530  [(set_attr "type" "X0_2cycle")])
3531
3532(define_insn "insn_tblidxb0"
3533  [(set (match_operand:SI 0 "register_operand" "=r")
3534        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3535                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3536                   UNSPEC_INSN_TBLIDXB0))]
3537  ""
3538  "tblidxb0\t%0, %r2"
3539  [(set_attr "type" "Y0")])
3540
3541(define_insn "insn_tblidxb1"
3542  [(set (match_operand:SI 0 "register_operand" "=r")
3543        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3544                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3545                   UNSPEC_INSN_TBLIDXB1))]
3546  ""
3547  "tblidxb1\t%0, %r2"
3548  [(set_attr "type" "Y0")])
3549
3550(define_insn "insn_tblidxb2"
3551  [(set (match_operand:SI 0 "register_operand" "=r")
3552        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3553                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3554                   UNSPEC_INSN_TBLIDXB2))]
3555  ""
3556  "tblidxb2\t%0, %r2"
3557  [(set_attr "type" "Y0")])
3558
3559(define_insn "insn_tblidxb3"
3560  [(set (match_operand:SI 0 "register_operand" "=r")
3561        (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3562                    (match_operand:SI 2 "reg_or_0_operand" "rO")]
3563                   UNSPEC_INSN_TBLIDXB3))]
3564  ""
3565  "tblidxb3\t%0, %r2"
3566  [(set_attr "type" "Y0")])
3567
3568
3569;;
3570;; pic related instructions
3571;;
3572
3573;; NOTE: We compute the label in this unusual way because if we place
3574;; the label after the lnk, whether it is at the same address as the
3575;; lnk will vary depending on whether the optimization level chooses to
3576;; insert bundling braces.
3577(define_insn "insn_lnk_and_label"
3578  [(set (match_operand:SI 0 "register_operand" "=r")
3579        (unspec_volatile:SI [(match_operand:SI 1 "symbolic_operand" "")]
3580                            UNSPEC_LNK_AND_LABEL))]
3581  ""
3582  "%1 = . + 8\n\tlnk\t%0"
3583  [(set_attr "type" "X1")])
3584
3585(define_expand "addli_pcrel"
3586  [(set (match_operand:SI 0 "register_operand" "")
3587        (lo_sum:SI
3588	 (match_operand:SI 1 "register_operand" "")
3589	 (const:SI
3590	  (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
3591		      (match_operand:SI 3 "symbolic_operand" "")]
3592		     UNSPEC_PCREL_SYM))))]
3593  "flag_pic")
3594
3595(define_expand "auli_pcrel"
3596  [(set (match_operand:SI 0 "register_operand" "")
3597        (plus:SI
3598         (match_operand:SI 1 "reg_or_0_operand" "")
3599         (high:SI
3600	  (const:SI
3601	   (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
3602		       (match_operand:SI 3 "symbolic_operand" "")]
3603                      UNSPEC_PCREL_SYM)))))]
3604  "flag_pic")
3605
3606(define_expand "add_got16"
3607  [(set (match_operand:SI 0 "register_operand" "")
3608        (lo_sum:SI
3609	 (match_operand:SI 1 "reg_or_0_operand" "")
3610	 (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
3611			      UNSPEC_GOT16_SYM))))]
3612  "flag_pic == 1")
3613
3614(define_expand "addhi_got32"
3615  [(set (match_operand:SI 0 "register_operand" "")
3616	(plus:SI
3617	 (match_operand:SI 1 "reg_or_0_operand" "")
3618	 (high:SI
3619	  (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
3620			       UNSPEC_GOT32_SYM)))))]
3621  "flag_pic == 2")
3622
3623(define_expand "addlo_got32"
3624  [(set (match_operand:SI 0 "register_operand" "")
3625        (lo_sum:SI
3626	 (match_operand:SI 1 "reg_or_0_operand" "")
3627	 (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
3628			      UNSPEC_GOT32_SYM))))]
3629  "flag_pic == 2")
3630
3631
3632;;
3633;; TLS
3634;;
3635
3636(define_expand "tls_gd_addhi"
3637  [(set (match_operand:SI 0 "register_operand" "")
3638	(plus:SI
3639         (match_operand:SI 1 "reg_or_0_operand" "")
3640         (high:SI
3641	  (const:SI (unspec:SI [(match_operand 2 "tls_symbolic_operand" "")]
3642			       UNSPEC_TLS_GD)))))]
3643  "HAVE_AS_TLS")
3644
3645(define_expand "tls_gd_addlo"
3646  [(set (match_operand:SI 0 "register_operand" "")
3647        (lo_sum:SI
3648         (match_operand:SI 1 "reg_or_0_operand" "")
3649         (const:SI (unspec:SI [(match_operand 2 "tls_symbolic_operand" "")]
3650			      UNSPEC_TLS_GD))))]
3651  "HAVE_AS_TLS")
3652
3653(define_expand "tls_gd_call"
3654  [(parallel
3655    [(set (reg:SI 0)
3656	  (unspec:SI [(match_operand:SI 0 "tls_symbolic_operand" "")
3657		     (reg:SI 0)]
3658		     UNSPEC_TLS_GD_CALL))
3659     (clobber (reg:SI 25))
3660     (clobber (reg:SI 26))
3661     (clobber (reg:SI 27))
3662     (clobber (reg:SI 28))
3663     (clobber (reg:SI 29))
3664     (clobber (reg:SI 55))])]
3665   ""
3666{
3667  cfun->machine->calls_tls_get_addr = true;
3668})
3669
3670(define_insn "*tls_gd_call"
3671  [(set (reg:SI 0)
3672	(unspec:SI [(match_operand:SI 0 "tls_symbolic_operand" "")
3673		    (reg:SI 0)]
3674		   UNSPEC_TLS_GD_CALL))
3675   (clobber (reg:SI 25))
3676   (clobber (reg:SI 26))
3677   (clobber (reg:SI 27))
3678   (clobber (reg:SI 28))
3679   (clobber (reg:SI 29))
3680   (clobber (reg:SI 55))]
3681  ""
3682  "jal\ttls_gd_call(%0)"
3683  [(set_attr "type" "X1")])
3684
3685(define_insn "tls_gd_add"
3686  [(set (match_operand:SI 0 "register_operand" "=r")
3687       (unspec:SI [(match_operand:SI 1 "register_operand" "r")
3688                   (match_operand:SI 2 "tls_symbolic_operand" "")]
3689                  UNSPEC_TLS_GD_ADD))]
3690  "HAVE_AS_TLS"
3691  "addi\t%0, %1, tls_gd_add(%2)")
3692
3693(define_insn "tls_ie_load"
3694  [(set (match_operand:SI 0 "register_operand" "=r")
3695       (unspec:SI [(match_operand:SI 1 "register_operand" "r")
3696                   (match_operand:SI 2 "tls_symbolic_operand" "")]
3697                  UNSPEC_TLS_IE_LOAD))]
3698  "HAVE_AS_TLS"
3699  "lw_tls\t%0, %1, tls_ie_load(%2)"
3700  [(set_attr "type" "X1_2cycle")])
3701
3702(define_expand "tls_ie_addhi"
3703  [(set (match_operand:SI 0 "register_operand" "")
3704        (plus:SI
3705         (match_operand:SI 1 "register_operand" "")
3706         (high:SI
3707	  (const:SI (unspec:SI [(match_operand 2 "tls_ie_symbolic_operand" "")]
3708			       UNSPEC_TLS_IE)))))]
3709  "HAVE_AS_TLS")
3710
3711(define_expand "tls_ie_addlo"
3712  [(set (match_operand:SI 0 "register_operand" "")
3713        (lo_sum:SI
3714         (match_operand:SI 1 "register_operand" "")
3715         (const:SI (unspec:SI [(match_operand 2 "tls_ie_symbolic_operand" "")]
3716			      UNSPEC_TLS_IE))))]
3717  "HAVE_AS_TLS")
3718
3719(define_expand "tls_le_addhi"
3720  [(set (match_operand:SI 0 "register_operand" "")
3721        (plus:SI
3722         (match_operand:SI 1 "register_operand" "")
3723         (high:SI
3724	  (const:SI (unspec:SI [(match_operand 2 "tls_le_symbolic_operand" "")]
3725			       UNSPEC_TLS_LE)))))]
3726  "HAVE_AS_TLS")
3727
3728(define_expand "tls_le_addlo"
3729  [(set (match_operand:SI 0 "register_operand" "")
3730        (lo_sum:SI
3731         (match_operand:SI 1 "register_operand" "")
3732         (const:SI (unspec:SI [(match_operand 2 "tls_le_symbolic_operand" "")]
3733			      UNSPEC_TLS_LE))))]
3734  "HAVE_AS_TLS")
3735
3736
3737;;
3738;; Stack protector instructions.
3739;;
3740
3741(define_expand "stack_protect_set"
3742  [(set (match_operand 0 "nonautoincmem_operand" "")
3743	(match_operand 1 "nonautoincmem_operand" ""))]
3744  ""
3745{
3746#ifdef TARGET_THREAD_SSP_OFFSET
3747  rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
3748  rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
3749  rtx ssp = gen_reg_rtx (Pmode);
3750
3751  emit_insn (gen_rtx_SET (VOIDmode, ssp, ssp_addr));
3752
3753  operands[1] = gen_rtx_MEM (Pmode, ssp);
3754#endif
3755
3756  emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
3757
3758  DONE;
3759})
3760
3761(define_insn "stack_protect_setsi"
3762  [(set (match_operand:SI 0 "nonautoincmem_operand" "=U")
3763        (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")]
3764		   UNSPEC_SP_SET))
3765   (set (match_scratch:SI 2 "=&r") (const_int 0))]
3766  ""
3767  "lw\t%2, %1; { sw\t%0, %2; move\t%2, zero }"
3768  [(set_attr "length" "16")
3769   (set_attr "type" "cannot_bundle_3cycle")])
3770
3771
3772(define_expand "stack_protect_test"
3773  [(match_operand 0 "nonautoincmem_operand" "")
3774   (match_operand 1 "nonautoincmem_operand" "")
3775   (match_operand 2 "" "")]
3776  ""
3777{
3778  rtx compare_result;
3779  rtx bcomp, loc_ref;
3780
3781#ifdef TARGET_THREAD_SSP_OFFSET
3782  rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
3783  rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
3784  rtx ssp = gen_reg_rtx (Pmode);
3785
3786  emit_insn (gen_rtx_SET (VOIDmode, ssp, ssp_addr));
3787
3788  operands[1] = gen_rtx_MEM (Pmode, ssp);
3789#endif
3790
3791  compare_result = gen_reg_rtx (SImode);
3792
3793  emit_insn (gen_stack_protect_testsi (compare_result, operands[0],
3794				       operands[1]));
3795
3796  bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
3797
3798  loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
3799
3800  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3801			       gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
3802						     loc_ref, pc_rtx)));
3803
3804  DONE;
3805})
3806
3807(define_insn "stack_protect_testsi"
3808  [(set (match_operand:SI 0 "register_operand" "=&r")
3809        (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")
3810                    (match_operand:SI 2 "nonautoincmem_operand" "U")]
3811                   UNSPEC_SP_TEST))
3812   (set (match_scratch:SI 3 "=&r") (const_int 0))]
3813  ""
3814  "lw\t%0, %1; lw\t%3, %2; { seq\t%0, %0, %3; move\t%3, zero }"
3815  [(set_attr "length" "24")
3816   (set_attr "type" "cannot_bundle_4cycle")])
3817
3818