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