]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/tilegx/tilegx.md
testsuite, Darwin: Fix darwin-comm-1.c error messages for Darwin <= 10.
[thirdparty/gcc.git] / gcc / config / tilegx / tilegx.md
CommitLineData
dd552284 1;; Machine description for Tilera TILE-Gx chip for GCC.
7adcbafe 2;; Copyright (C) 2011-2022 Free Software Foundation, Inc.
dd552284
WL
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_ADDR_SHL16INSLI 1)
28 (UNSPEC_INSN_BFEXTS 2)
29 (UNSPEC_INSN_BFEXTU 3)
30 (UNSPEC_INSN_BFINS 4)
31 (UNSPEC_INSN_CRC32_32 5)
32 (UNSPEC_INSN_CRC32_8 6)
33 (UNSPEC_INSN_DBLALIGN 7)
34 (UNSPEC_INSN_DBLALIGN2 8)
35 (UNSPEC_INSN_DBLALIGN4 9)
36 (UNSPEC_INSN_DBLALIGN6 10)
37 (UNSPEC_INSN_DRAIN 11)
38 (UNSPEC_INSN_DTLBPR 12)
39 (UNSPEC_INSN_FINV 13)
40 (UNSPEC_INSN_FLUSH 14)
41 (UNSPEC_INSN_FLUSHWB 15)
42 (UNSPEC_INSN_FNOP 16)
43 (UNSPEC_INSN_ICOH 17)
44 (UNSPEC_INSN_ILL 18)
45 (UNSPEC_INSN_INFO 19)
46 (UNSPEC_INSN_INFOL 20)
47 (UNSPEC_INSN_INV 21)
48 (UNSPEC_INSN_LNK 22)
49 (UNSPEC_INSN_MFSPR 23)
50 (UNSPEC_INSN_MM 24)
51 (UNSPEC_INSN_MTSPR 25)
52 (UNSPEC_INSN_NAP 26)
53 (UNSPEC_INSN_PREFETCH_L1_FAULT 27)
54 (UNSPEC_INSN_PREFETCH_L2_FAULT 28)
55 (UNSPEC_INSN_PREFETCH_L3_FAULT 29)
56 (UNSPEC_INSN_REVBITS 30)
57 (UNSPEC_INSN_SHUFFLEBYTES 31)
58 (UNSPEC_INSN_TBLIDXB0 32)
59 (UNSPEC_INSN_TBLIDXB1 33)
60 (UNSPEC_INSN_TBLIDXB2 34)
61 (UNSPEC_INSN_TBLIDXB3 35)
62 (UNSPEC_INSN_V1AVGU 36)
63 (UNSPEC_INSN_V2AVGS 37)
64 (UNSPEC_INSN_WH64 38)
65
66 ;; 2 cycles
67 (UNSPEC_INSN_CMUL 100)
68 (UNSPEC_INSN_CMULA 101)
69 (UNSPEC_INSN_CMULAF 102)
70 (UNSPEC_INSN_CMULFR 103)
71 (UNSPEC_INSN_CMULHR 104)
72 (UNSPEC_INSN_CMULF 105)
73 (UNSPEC_INSN_CMULH 106)
74 (UNSPEC_INSN_EXCH 107)
75 (UNSPEC_INSN_FDOUBLE_ADDSUB 108)
76 (UNSPEC_INSN_FDOUBLE_ADD_FLAGS 109)
77 (UNSPEC_INSN_FDOUBLE_MUL_FLAGS 110)
78 (UNSPEC_INSN_FDOUBLE_PACK1 111)
79 (UNSPEC_INSN_FDOUBLE_PACK2 112)
80 (UNSPEC_INSN_FDOUBLE_SUB_FLAGS 113)
81 (UNSPEC_INSN_FDOUBLE_UNPACK_MAX 114)
82 (UNSPEC_INSN_FDOUBLE_UNPACK_MIN 115)
83 (UNSPEC_INSN_FETCHADDGEZ 116)
84 (UNSPEC_INSN_FSINGLE_ADD1 117)
85 (UNSPEC_INSN_FSINGLE_ADDSUB2 118)
86 (UNSPEC_INSN_FSINGLE_MUL1 119)
87 (UNSPEC_INSN_FSINGLE_MUL2 120)
88 (UNSPEC_INSN_FSINGLE_PACK1 121)
89 (UNSPEC_INSN_FSINGLE_PACK2 122)
90 (UNSPEC_INSN_FSINGLE_SUB1 123)
91 (UNSPEC_INSN_MULAX 124)
92 (UNSPEC_INSN_MULA_HS_HS 125)
93 (UNSPEC_INSN_MULA_HS_HU 126)
94 (UNSPEC_INSN_MULA_HS_LS 127)
95 (UNSPEC_INSN_MULA_HS_LU 128)
96 (UNSPEC_INSN_MULA_HU_HU 129)
97 (UNSPEC_INSN_MULA_HU_LS 130)
98 (UNSPEC_INSN_MULA_HU_LU 131)
99 (UNSPEC_INSN_MULA_LS_LS 132)
100 (UNSPEC_INSN_MULA_LS_LU 133)
101 (UNSPEC_INSN_MULA_LU_LU 134)
102 (UNSPEC_INSN_MUL_HS_HS 135)
103 (UNSPEC_INSN_MUL_HS_HU 136)
104 (UNSPEC_INSN_MUL_HS_LS 137)
105 (UNSPEC_INSN_MUL_HS_LU 138)
106 (UNSPEC_INSN_MUL_HU_HU 139)
107 (UNSPEC_INSN_MUL_HU_LS 140)
108 (UNSPEC_INSN_MUL_HU_LU 141)
109 (UNSPEC_INSN_MUL_LS_LS 142)
110 (UNSPEC_INSN_MUL_LS_LU 143)
111 (UNSPEC_INSN_MUL_LU_LU 144)
112 (UNSPEC_INSN_V1ADIFFU 145)
113 (UNSPEC_INSN_V1DDOTPU 146)
114 (UNSPEC_INSN_V1DDOTPUA 147)
115 (UNSPEC_INSN_V1DDOTPUS 148)
116 (UNSPEC_INSN_V1DDOTPUSA 149)
117 (UNSPEC_INSN_V1DOTP 150)
118 (UNSPEC_INSN_V1DOTPA 151)
119 (UNSPEC_INSN_V1DOTPU 152)
120 (UNSPEC_INSN_V1DOTPUA 153)
121 (UNSPEC_INSN_V1DOTPUS 154)
122 (UNSPEC_INSN_V1DOTPUSA 155)
123 (UNSPEC_INSN_V1SADAU 156)
124 (UNSPEC_INSN_V1SADU 157)
125 (UNSPEC_INSN_V2ADIFFS 158)
126 (UNSPEC_INSN_V2DOTP 159)
127 (UNSPEC_INSN_V2DOTPA 160)
128 (UNSPEC_INSN_V2MULFSC 161)
129 (UNSPEC_INSN_V2SADAS 162)
130 (UNSPEC_INSN_V2SADAU 163)
131 (UNSPEC_INSN_V2SADS 164)
132 (UNSPEC_INSN_V2SADU 165)
133
134 ;; 11 cycles
135 (UNSPEC_INSN_CMPEXCH 200)
136
137 ;;
138 ;; The following are special insns.
139 ;;
140
141 ;; Blockage
142 (UNSPEC_BLOCKAGE 201)
143
144 ;; Lnk and its label
145 (UNSPEC_LNK_AND_LABEL 202)
146
147 ;; Memory fence
148 (UNSPEC_MF 203)
149
150 ;; Insns generating difference of two labels
151 (UNSPEC_MOV_PCREL_STEP3 204)
1773cd77 152 (UNSPEC_MOV_LARGE_PCREL_STEP4 205)
dd552284
WL
153
154 ;; Latency specifying loads.
1773cd77
WL
155 (UNSPEC_LATENCY_L2 206)
156 (UNSPEC_LATENCY_MISS 207)
dd552284
WL
157
158 ;; A pseudo-op that prevents network operations from being ordered.
1773cd77 159 (UNSPEC_NETWORK_BARRIER 208)
dd552284
WL
160
161 ;; Operations that access network registers.
1773cd77
WL
162 (UNSPEC_NETWORK_RECEIVE 209)
163 (UNSPEC_NETWORK_SEND 210)
dd552284
WL
164
165 ;; Stack protector operations
1773cd77
WL
166 (UNSPEC_SP_SET 211)
167 (UNSPEC_SP_TEST 212)
dd552284
WL
168
169 ;; This is used to move a value to a SPR.
1773cd77 170 (UNSPEC_SPR_MOVE 213)
dd552284
WL
171
172 ;; A call to __tls_get_addr
1773cd77 173 (UNSPEC_TLS_GD_CALL 214)
dd552284
WL
174
175 ;; An opaque TLS "add" operation for TLS general dynamic model
176 ;; access.
1773cd77 177 (UNSPEC_TLS_GD_ADD 215)
dd552284
WL
178
179 ;; An opaque TLS "load" operation for TLS initial exec model access.
1773cd77 180 (UNSPEC_TLS_IE_LOAD 216)
dd552284
WL
181
182 ;; An opaque TLS "add" operation for TLS access.
1773cd77 183 (UNSPEC_TLS_ADD 217)
dd552284
WL
184
185 ;; Atomics
1773cd77
WL
186 (UNSPEC_ATOMIC 218)
187 (UNSPEC_CMPXCHG 219)
188 (UNSPEC_XCHG 220)
dd552284
WL
189
190 ;;
191 ;; The following are operands.
192 ;;
193 (UNSPEC_HW0 300)
194 (UNSPEC_HW1 301)
195 (UNSPEC_HW2 302)
196 (UNSPEC_HW3 303)
197 (UNSPEC_HW0_LAST 304)
198 (UNSPEC_HW1_LAST 305)
199 (UNSPEC_HW2_LAST 306)
200
201 (UNSPEC_HW0_PCREL 307)
1773cd77
WL
202 (UNSPEC_HW1_PCREL 308)
203 (UNSPEC_HW1_LAST_PCREL 309)
204 (UNSPEC_HW2_LAST_PCREL 310)
dd552284 205
1773cd77
WL
206 (UNSPEC_HW0_GOT 311)
207 (UNSPEC_HW0_LAST_GOT 312)
208 (UNSPEC_HW1_LAST_GOT 313)
dd552284 209
1773cd77
WL
210 (UNSPEC_HW0_TLS_GD 314)
211 (UNSPEC_HW1_LAST_TLS_GD 315)
dd552284 212
1773cd77
WL
213 (UNSPEC_HW0_TLS_IE 316)
214 (UNSPEC_HW1_LAST_TLS_IE 317)
dd552284 215
1773cd77
WL
216 (UNSPEC_HW0_TLS_LE 318)
217 (UNSPEC_HW1_LAST_TLS_LE 319)
218
219 (UNSPEC_HW0_PLT_PCREL 320)
220 (UNSPEC_HW1_PLT_PCREL 321)
221
222 (UNSPEC_HW1_LAST_PLT_PCREL 322)
223 (UNSPEC_HW2_LAST_PLT_PCREL 323)
dd552284
WL
224
225 ;; This is used to wrap around the addresses of non-temporal load/store
226 ;; intrinsics.
1773cd77 227 (UNSPEC_NON_TEMPORAL 324)
dd552284
WL
228])
229
230;; Mark the last instruction of various latencies, used to
231;; determine the rtx costs of unspec insns.
232(define_constants [
233 (TILEGX_LAST_LATENCY_1_INSN 99)
234 (TILEGX_LAST_LATENCY_2_INSN 199)
235 (TILEGX_LAST_LATENCY_INSN 299)
236])
237
238(define_constants [
239 (TILEGX_NETREG_IDN0 0)
240 (TILEGX_NETREG_IDN1 1)
241 (TILEGX_NETREG_UDN0 2)
242 (TILEGX_NETREG_UDN1 3)
243 (TILEGX_NETREG_UDN2 4)
244 (TILEGX_NETREG_UDN3 5)
245])
246
247(define_constants [
248 (TILEGX_CMPEXCH_REG 66)
249 (TILEGX_NETORDER_REG 67)
250])
251
252
253;; Operand and operator predicates and constraints
254
255(include "predicates.md")
256(include "constraints.md")
257(include "tilegx-generic.md")
258
259;; Define an insn type attribute. This defines what pipes things can go in.
260(define_attr "type"
9b0370aa 261 "X0,X0_2cycle,X1,X1_branch,X1_2cycle,X1_L2,X1_remote,X1_miss,X01,Y0,Y0_2cycle,Y1,Y2,Y2_2cycle,Y2_L2,Y2_miss,Y01,cannot_bundle,cannot_bundle_3cycle,cannot_bundle_4cycle,nothing"
dd552284
WL
262 (const_string "Y01"))
263
264(define_attr "length" ""
265 (cond [(eq_attr "type" "X1_branch")
266 (if_then_else
267 (and (le (minus (match_dup 0) (pc)) (const_int 524280))
268 (le (minus (pc) (match_dup 0)) (const_int 524288)))
269 (const_int 8)
270 (const_int 16))
271 ]
272 (const_int 8)))
273
274
275;; Define some iterators.
276(define_mode_iterator IVMODE [SI DI V8QI V4HI V2SI])
277(define_mode_iterator IVNMODE [SI V8QI V4HI V2SI])
278(define_mode_iterator I48MODE [SI DI])
279(define_mode_iterator I48MODE2 [SI DI])
280(define_mode_iterator I124MODE [QI HI SI])
281(define_mode_iterator FI48MODE [SF DF SI DI])
282(define_mode_iterator VEC48MODE [V8QI V4HI])
283(define_mode_iterator VEC248MODE [V8QI V4HI V2SI])
284
285(define_mode_attr n [(QI "1") (HI "2") (SI "4") (DI "")
286 (V8QI "1") (V4HI "2") (V2SI "4")])
287(define_mode_attr x [(SI "x") (DI "")])
288(define_mode_attr bitsuffix [(SI "_32bit") (DI "")])
289(define_mode_attr four_if_si [(SI "4") (DI "")])
290(define_mode_attr four_s_if_si [(SI "4s") (DI "")])
291(define_mode_attr nbits [(SI "5") (DI "6")])
292(define_mode_attr shift_pipe [(SI "X01") (DI "*")])
293
294;; Code iterator for either extend.
295(define_code_iterator any_extend [sign_extend zero_extend])
296
297;; Code iterator for all three shifts.
298(define_code_iterator any_shift [ashift ashiftrt lshiftrt])
299
300;; Code iterator for all byte ops without immediate variants.
301(define_code_iterator v1op [us_minus us_plus minus ne le leu mult])
302
303;; Code iterator for all 2-byte vector ops without immediate variants.
304(define_code_iterator v2op [ss_minus ss_plus minus ne le leu])
305
306;; Code iterator for all 4-byte vector ops without immediate variants.
307(define_code_iterator v4op [ss_minus ss_plus minus plus])
308
309;; Code iterator for all byte vector ops with immediate variants.
310(define_code_iterator v1op_immed [plus umax umin eq lt ltu])
311
312;; Code iterator for all 2-byte vector ops with immediate variants.
313(define_code_iterator v2op_immed [plus smax smin eq lt ltu])
314
315;; Code iterator for all 2-byte vector shifts without immediate variants.
316(define_code_iterator v2shift [ss_ashift])
317
318;; Code iterator for all 4-byte vector shifts without immediate variants.
319(define_code_iterator v4shift [ashift ashiftrt lshiftrt ss_ashift])
320
321;; <optab> expands to the name of the optab for a particular code.
322(define_code_attr optab [(ashift "ashl")
323 (ashiftrt "ashr")
324 (lshiftrt "lshr")
325 (ss_ashift "ssashl")
326 (eq "seq")
327 (ne "sne")
328 (lt "slt")
329 (ltu "sltu")
330 (le "sle")
331 (leu "sleu")
332 (minus "sub")
333 (plus "add")
334 (mult "mul")
335 (smax "smax")
336 (smin "smin")
337 (ss_minus "sssub")
338 (ss_plus "ssadd")
339 (umax "umax")
340 (umin "umin")
341 (us_minus "ussub")
342 (us_plus "usadd")
343 ])
344
345;; <insn> expands to the name of the insn that implements a particular
346;; code.
347(define_code_attr insn [(ashift "shl")
348 (ashiftrt "shrs")
349 (lshiftrt "shru")
350 (ss_ashift "shlsc")
351 (eq "cmpeq")
352 (ne "cmpne")
353 (lt "cmplts")
354 (ltu "cmpltu")
355 (le "cmples")
356 (leu "cmpleu")
357 (minus "sub")
358 (plus "add")
359 (mult "multu")
360 (smax "maxs")
361 (smin "mins")
362 (umax "maxu")
363 (umin "minu")
364 (ss_minus "subsc")
365 (ss_plus "addsc")
366 (us_minus "subuc")
367 (us_plus "adduc")
368 ])
369
370;; <pipe> expands to the pipeline resource that contains the
371;; particular code.
372(define_code_attr pipe [(ashift "X01")
373 (ashiftrt "X01")
374 (lshiftrt "X01")
375 (ss_ashift "X01")
376 (eq "X01")
377 (ne "X01")
378 (lt "X01")
379 (ltu "X01")
380 (le "X01")
381 (leu "X01")
382 (minus "X01")
383 (plus "X01")
384 (mult "X0_2cycle")
385 (smax "X01")
386 (smin "X01")
387 (umax "X01")
388 (umin "X01")
389 (ss_minus "X01")
390 (ss_plus "X01")
391 (us_minus "X01")
392 (us_plus "X01")
393 ])
394
395;; <comm> indicates whether a particular code is commutative, using
396;; the "%" commutative opterator constraint.
397(define_code_attr comm [(ashift "")
398 (ashiftrt "")
399 (lshiftrt "")
400 (ss_ashift "")
401 (eq "%")
402 (ne "%")
403 (lt "")
404 (ltu "")
405 (le "")
406 (leu "")
407 (minus "")
408 (plus "%")
409 (mult "%")
410 (smin "%")
411 (umin "%")
412 (smax "%")
413 (umax "%")
414 (ss_plus "%")
415 (us_plus "%")
416 (ss_minus "")
417 (us_minus "")
418 ])
3aa775d6 419
dd552284
WL
420;; <s> is the load/store extension suffix.
421(define_code_attr s [(zero_extend "u")
422 (sign_extend "s")])
423
424;; Code for packing two 2-byte vectors.
425(define_code_iterator v2pack [truncate us_truncate])
426
427;; <pack_optab> expands to the part of the optab name describing how
428;; two vectors are packed.
429(define_code_attr pack_optab [(truncate "trunc")
430 (us_truncate "usat")
431 (ss_truncate "ssat")])
432
433;; <pack_insn> expands to the insn that implements a particular vector
434;; packing code.
435(define_code_attr pack_insn [(truncate "packl")
436 (us_truncate "packuc")
437 (ss_truncate "packsc")])
438\f
439;;
440;; The basic data move insns.
441;;
442
443(define_expand "movqi"
444 [(set (match_operand:QI 0 "nonimmediate_operand" "")
445 (match_operand:QI 1 "nonautoinc_operand" ""))]
446 ""
447{
448 if (tilegx_expand_mov (QImode, operands))
449 DONE;
450})
451
452(define_insn "*movqi_insn"
453 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,U,m")
454 (match_operand:QI 1 "move_operand" "r,I,U,m,rO,rO"))]
455 "(register_operand (operands[0], QImode)
456 || reg_or_0_operand (operands[1], QImode))"
457 "@
458 move\t%0, %r1
459 movei\t%0, %1
460 ld1u\t%0, %1
461 ld1u_add\t%0, %I1, %i1
462 st1\t%0, %r1
463 st1_add\t%I0, %r1, %i0"
464 [(set_attr "type" "*,*,Y2_2cycle,X1_2cycle,Y2,X1")])
465
466(define_expand "movhi"
467 [(set (match_operand:HI 0 "nonimmediate_operand" "")
468 (match_operand:HI 1 "nonautoinc_operand" ""))]
469 ""
470{
471 if (tilegx_expand_mov (HImode, operands))
472 DONE;
473})
474
475(define_insn "*movhi_insn"
476 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,r,U,m")
477 (match_operand:HI 1 "move_operand" "r,I,JT,U,m,rO,rO"))]
478 "(register_operand (operands[0], HImode)
479 || reg_or_0_operand (operands[1], HImode))"
480 "@
481 move\t%0, %r1
482 movei\t%0, %1
483 moveli\t%0, %H1
484 ld2u\t%0, %1
485 ld2u_add\t%0, %I1, %i1
486 st2\t%0, %r1
487 st2_add\t%I0, %r1, %i0"
488 [(set_attr "type" "*,*,X01,Y2_2cycle,X1_2cycle,Y2,X1")])
489
490(define_expand "movsi"
491 [(set (match_operand:SI 0 "nonimmediate_operand" "")
492 (match_operand:SI 1 "nonautoinc_operand" ""))]
493 ""
494{
495 if (tilegx_expand_mov (SImode, operands))
496 DONE;
497})
498
499(define_insn "*movsi_insn"
500 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,U,m")
501 (match_operand:SI 1 "move_operand" "r,I,JT,K,U,m,rO,rO"))]
502 "(register_operand (operands[0], SImode)
503 || reg_or_0_operand (operands[1], SImode))"
504 "@
505 move\t%0, %r1
506 movei\t%0, %1
507 moveli\t%0, %H1
508 shl16insli\t%0, zero, %h1
509 ld4s\t%0, %1
510 ld4s_add\t%0, %I1, %i1
511 st4\t%0, %r1
512 st4_add\t%I0, %r1, %i0"
513 [(set_attr "type" "*,*,X01,X01,Y2_2cycle,X1_2cycle,Y2,X1")])
514
515(define_expand "movdi"
516 [(set (match_operand:DI 0 "nonimmediate_operand" "")
517 (match_operand:DI 1 "nonautoinc_operand" ""))]
518 ""
519{
520 if (tilegx_expand_mov (DImode, operands))
521 DONE;
522})
523
524(define_insn "*movdi_insn"
525 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,r,U,m")
526 (match_operand:DI 1 "move_operand" "r,I,JT,K,N,P,U,m,rO,rO"))]
527 "(register_operand (operands[0], DImode)
528 || reg_or_0_operand (operands[1], DImode))"
529 "@
530 move\t%0, %r1
531 movei\t%0, %1
532 moveli\t%0, %H1
533 shl16insli\t%0, zero, %h1
534 v1addi\t%0, zero, %j1
535 v2addi\t%0, zero, %h1
536 ld\t%0, %1
537 ld_add\t%0, %I1, %i1
538 st\t%0, %r1
539 st_add\t%I0, %r1, %i0"
540 [(set_attr "type" "*,*,X01,X01,X01,X01,Y2_2cycle,X1_2cycle,Y2,X1")])
541
542(define_expand "movmisalign<mode>"
543 [(set (match_operand:VEC248MODE 0 "nonautoincmem_nonimmediate_operand" "")
544 (match_operand:VEC248MODE 1 "nonautoincmem_general_operand" ""))]
545 ""
546{
547 tilegx_expand_movmisalign (<MODE>mode, operands);
548 DONE;
549})
550
551(define_expand "movsf"
552 [(set (match_operand:SF 0 "nonimmediate_operand" "")
553 (match_operand:SF 1 "general_operand" ""))]
554 ""
555{
556 /* Materialize immediates using clever SImode code, but don't
557 do this after reload starts, since gen_lowpart will choke
558 during reload if given an illegitimate address. */
559 if (immediate_operand (operands[1], SFmode)
560 && operands[1] != const0_rtx
561 && (register_operand (operands[0], SFmode)
562 || (!reload_in_progress && !reload_completed)))
563 {
564 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
565 gen_lowpart (SImode, operands[1])));
566 DONE;
567 }
568})
569
570(define_insn "*movsf"
571 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,U,m")
572 (match_operand:SF 1 "general_operand" "rO,U,m,rO,rO"))]
573 ""
574 "@
575 move\t%0, %r1
576 ld4s\t%0, %1
577 ld4s_add\t%0, %I1, %i1
578 st4\t%0, %r1
579 st4_add\t%I0, %r1, %i0"
580 [(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")])
581
582(define_expand "movdf"
583 [(set (match_operand:DF 0 "nonimmediate_operand" "")
584 (match_operand:DF 1 "general_operand" ""))]
585 ""
586{
587 /* Materialize immediates using clever DImode code, but don't
588 do this after reload starts, since gen_lowpart will choke
589 during reload if given an illegitimate address. */
590 if (immediate_operand (operands[1], DFmode)
591 && operands[1] != const0_rtx
592 && (register_operand (operands[0], DFmode)
593 || (!reload_in_progress && !reload_completed)))
594 {
595 emit_insn (gen_movdi (gen_lowpart (DImode, operands[0]),
596 gen_lowpart (DImode, operands[1])));
597 DONE;
598 }
599})
600
601(define_insn "*movdf"
602 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r,U,m")
603 (match_operand:DF 1 "general_operand" "rO,U,m,rO,rO"))]
604 ""
605 "@
606 move\t%0, %r1
607 ld\t%0, %1
608 ld_add\t%0, %I1, %i1
609 st\t%0, %r1
610 st_add\t%I0, %r1, %i0"
611 [(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")])
612
613(define_expand "mov<mode>"
614 [(set (match_operand:VEC248MODE 0 "nonimmediate_operand" "")
615 (match_operand:VEC248MODE 1 "general_operand" ""))]
616 ""
617{
618 /* Materialize immediates using clever DImode code, but don't
619 do this after reload starts, since gen_lowpart will choke
620 during reload if given an illegitimate address. */
621 if (immediate_operand (operands[1], <MODE>mode)
622 && operands[1] != const0_rtx
623 && (register_operand (operands[0], <MODE>mode)
624 || (!reload_in_progress && !reload_completed)))
625 {
626 emit_insn (gen_movdi (gen_lowpart (DImode, operands[0]),
627 gen_lowpart (DImode, operands[1])));
628 DONE;
629 }
630})
631
632(define_insn "*mov<mode>"
633 [(set (match_operand:VEC248MODE 0 "nonimmediate_operand" "=r,r,r,U,m")
634 (match_operand:VEC248MODE 1 "general_operand" "rO,U,m,rO,rO"))]
635 ""
636 "@
637 move\t%0, %r1
638 ld\t%0, %1
639 ld_add\t%0, %I1, %i1
640 st\t%0, %r1
641 st_add\t%I0, %r1, %i0"
642 [(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")])
643
644(define_insn "movstrictqi"
645 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
646 (match_operand:QI 1 "reg_or_0_operand" "rO"))]
647 ""
648 "bfins\t%0, %r1, 0, 7"
649 [(set_attr "type" "X0")])
650
651(define_insn "movstricthi"
652 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
653 (match_operand:HI 1 "reg_or_0_operand" "rO"))]
654 ""
655 "bfins\t%0, %r1, 0, 15"
656 [(set_attr "type" "X0")])
657
658(define_insn "movstrictsi"
659 [(set (strict_low_part (match_operand:SI 0 "register_operand" "+r"))
660 (match_operand:SI 1 "reg_or_0_operand" "rO"))]
661 ""
662 "bfins\t%0, %r1, 0, 31"
663 [(set_attr "type" "X0")])
664
665\f
666;;
667;; Bit-field extracts/inserts
668;;
669
670(define_expand "insv"
671 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
672 (match_operand:DI 1 "u6bit_cint_operand" "")
673 (match_operand:DI 2 "u6bit_cint_operand" ""))
674 (match_operand:DI 3 "reg_or_cint_operand" ""))]
675 ""
676{
677 rtx first_rtx = operands[2];
678 HOST_WIDE_INT first = INTVAL (first_rtx);
679 HOST_WIDE_INT width = INTVAL (operands[1]);
680 rtx v = operands[3];
681
682 if (CONST_INT_P (v))
683 {
684 /* Which bits are we affecting? */
685 HOST_WIDE_INT mask = ((((HOST_WIDE_INT) 1) << width) - 1) << first;
686
687 /* Extract just the bits we need, sign extending them to make the
688 constant easier to materialize in a register. */
689 int shift = sizeof(HOST_WIDE_INT) * 8 - width;
690 HOST_WIDE_INT n = (INTVAL (v) << shift) >> shift;
691
692 if (n == 0)
693 {
694 /* We are setting every bit in the bitfield to zero. Try to use
695 andi instead, since that is more efficient. */
696 rtx mask_rtx = GEN_INT (~mask);
697 if (satisfies_constraint_I (mask_rtx))
698 {
699 emit_insn (gen_anddi3 (operands[0], operands[0], mask_rtx));
700 DONE;
701 }
702
703 operands[3] = const0_rtx;
704 }
705 else
706 {
707 if (n == -1)
708 {
709 /* We are setting every bit in the bitfield to one. Try to use
710 ori instead, since that is more efficient. */
711 rtx mask_rtx = GEN_INT (mask);
712 if (satisfies_constraint_I (mask_rtx))
713 {
714 emit_insn (gen_iordi3 (operands[0], operands[0], mask_rtx));
715 DONE;
716 }
717 }
718
719 if (!can_create_pseudo_p ())
720 FAIL;
721
722 operands[3] = force_reg (DImode, GEN_INT (n));
723 }
724 }
725})
726
727(define_insn "*insv_tblidxb0"
728 [(set (zero_extract:DI
729 (match_operand:DI 0 "register_operand" "+r")
730 (const_int 8)
731 (const_int 2))
732 (match_operand:DI 1 "register_operand" "rO"))]
733 ""
734 "tblidxb0\t%0, %r1"
735 [(set_attr "type" "Y0")])
736
737(define_insn "*insv_tblidxb1"
738 [(set (zero_extract:DI
739 (match_operand:DI 0 "register_operand" "+r")
740 (const_int 8)
741 (const_int 2))
742 (zero_extract:DI
743 (const_int 8)
744 (const_int 8)
745 (match_operand:DI 1 "register_operand" "rO")))]
746 ""
747 "tblidxb1\t%0, %r1"
748 [(set_attr "type" "Y0")])
749
750(define_insn "*insv_tblidxb2"
751 [(set (zero_extract:DI
752 (match_operand:DI 0 "register_operand" "+r")
753 (const_int 8)
754 (const_int 2))
755 (zero_extract:DI
756 (const_int 8)
757 (const_int 16)
758 (match_operand:DI 1 "register_operand" "rO")))]
759 ""
760 "tblidxb2\t%0, %r1"
761 [(set_attr "type" "Y0")])
762
763(define_insn "*insv_tblidxb3"
764 [(set (zero_extract:DI
765 (match_operand:DI 0 "register_operand" "+r")
766 (const_int 8)
767 (const_int 2))
768 (zero_extract:DI
769 (const_int 8)
770 (const_int 24)
771 (match_operand:DI 1 "register_operand" "rO")))]
772 ""
773 "tblidxb3\t%0, %r1"
774 [(set_attr "type" "Y0")])
775
776(define_insn "*insv_bfins"
777 [(set (zero_extract:DI
778 (match_operand:DI 0 "register_operand" "+r")
779 (match_operand:DI 1 "u6bit_cint_operand" "n")
780 (match_operand:DI 2 "u6bit_cint_operand" "n"))
781 (match_operand:DI 3 "reg_or_cint_operand" "rO"))]
782 ""
783 "bfins\t%0, %r3, %2, %2+%1-1"
784 [(set_attr "type" "X0")])
785
786(define_insn "*insv_mm"
787 [(set (zero_extract:DI
788 (match_operand:DI 0 "register_operand" "+r")
789 (match_operand:DI 1 "u6bit_cint_operand" "n")
790 (match_operand:DI 2 "u6bit_cint_operand" "n"))
791 (zero_extract:DI
792 (match_operand:DI 3 "register_operand" "rO")
793 (match_dup 1)
794 (match_dup 2)))]
795 ""
796{
797 int n;
798
799 operands[1] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]));
800
801 n = INTVAL (operands[2]);
802 n = (n == 0) ? 63 : n - 1;
803 operands[2] = GEN_INT (n);
804
805 return "mm\t%0, %r3, %1, %2";
806}
807 [(set_attr "type" "X0")])
808
809(define_expand "extv"
810 [(set (match_operand:DI 0 "register_operand" "")
811 (sign_extract:DI (match_operand 1 "nonautoincmem_general_operand" "")
812 (match_operand:DI 2 "immediate_operand" "")
813 (match_operand:DI 3 "immediate_operand" "")))]
814 ""
815{
816 if (MEM_P (operands[1]))
817 {
818 HOST_WIDE_INT bit_offset, bit_width;
819 HOST_WIDE_INT first_byte_offset, last_byte_offset;
820
821 if (GET_MODE (operands[1]) != QImode)
822 FAIL;
823
824 bit_width = INTVAL (operands[2]);
825 bit_offset = INTVAL (operands[3]);
826
341c653c
WL
827 /* NOTE: bit_offset is relative to the mode of operand
828 1 (QImode). It will be negative in big-endian mode
829 here. Convert that back to the real offset. */
830 if (BYTES_BIG_ENDIAN)
831 bit_offset = GET_MODE_BITSIZE (QImode) - bit_width - bit_offset;
832
3aa775d6 833 /* Reject bitfields that can be done with a normal load. */
dd552284
WL
834 if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
835 FAIL;
836
3aa775d6 837 /* The value in memory cannot span more than 8 bytes. */
dd552284
WL
838 first_byte_offset = bit_offset / BITS_PER_UNIT;
839 last_byte_offset = (bit_offset + bit_width - 1) / BITS_PER_UNIT;
840 if (last_byte_offset - first_byte_offset > 7)
841 FAIL;
842
843 tilegx_expand_unaligned_load (operands[0], operands[1],
844 bit_width, bit_offset, 1);
845
846 DONE;
847 }
848
849 operands[1] = force_reg (DImode, operands[1]);
850})
851
852(define_expand "extzv"
853 [(set (match_operand:DI 0 "register_operand" "")
854 (zero_extract:DI (match_operand 1 "nonautoincmem_general_operand" "")
855 (match_operand:DI 2 "immediate_operand" "")
856 (match_operand:DI 3 "immediate_operand" "")))]
857 ""
858{
859 HOST_WIDE_INT bit_width = INTVAL (operands[2]);
860 HOST_WIDE_INT bit_offset = INTVAL (operands[3]);
861
dd552284
WL
862 if (MEM_P (operands[1]))
863 {
864 HOST_WIDE_INT first_byte_offset, last_byte_offset;
865
866 if (GET_MODE (operands[1]) != QImode)
867 FAIL;
868
341c653c
WL
869 /* NOTE: bit_offset is relative to the mode of operand
870 1 (QImode). It will be negative in big-endian mode
871 here. */
872 if (BYTES_BIG_ENDIAN)
873 bit_offset = GET_MODE_BITSIZE (QImode) - bit_width - bit_offset;
874
3aa775d6 875 /* Reject bitfields that can be done with a normal load. */
dd552284
WL
876 if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
877 FAIL;
878
3aa775d6 879 /* The value in memory cannot span more than 8 bytes. */
dd552284
WL
880 first_byte_offset = bit_offset / BITS_PER_UNIT;
881 last_byte_offset = (bit_offset + bit_width - 1) / BITS_PER_UNIT;
882 if (last_byte_offset - first_byte_offset > 7)
883 FAIL;
884
885 tilegx_expand_unaligned_load (operands[0], operands[1],
886 bit_width, bit_offset, 0);
887
888 DONE;
889 }
890
891 operands[1] = force_reg (DImode, operands[1]);
892
893 if (bit_offset == 0)
894 {
3aa775d6 895 /* Extracting the low bits is just a bitwise AND. */
dd552284
WL
896 HOST_WIDE_INT mask = ((HOST_WIDE_INT)1 << bit_width) - 1;
897 emit_insn (gen_anddi3 (operands[0], operands[1], GEN_INT (mask)));
898 DONE;
899 }
900})
901
902\f
903;;
904;; Addresses
905;;
906
026c3cfd 907;; The next three patterns are used to materialize a position
1773cd77
WL
908;; independent address by adding the difference of two labels to a base
909;; label in the text segment, assuming that the difference fits in 32
910;; signed bits.
dd552284
WL
911(define_expand "mov_address_step1"
912 [(set (match_operand:DI 0 "register_operand" "")
913 (const:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
914 UNSPEC_HW2_LAST)))])
3aa775d6 915
dd552284
WL
916(define_expand "mov_address_step2"
917 [(set (match_operand:DI 0 "register_operand" "")
918 (unspec:DI
919 [(match_operand:DI 1 "reg_or_0_operand" "")
920 (const:DI (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
921 UNSPEC_HW1))]
922 UNSPEC_INSN_ADDR_SHL16INSLI))])
923
dd552284
WL
924(define_expand "mov_address_step3"
925 [(set (match_operand:DI 0 "register_operand" "")
926 (unspec:DI
927 [(match_operand:DI 1 "reg_or_0_operand" "")
928 (const:DI (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
929 UNSPEC_HW0))]
930 UNSPEC_INSN_ADDR_SHL16INSLI))])
931
932;; First step of the 2-insn sequence to materialize a 32-bit symbolic
933;; address.
934(define_expand "mov_address_32bit_step1"
935 [(set (match_operand:SI 0 "register_operand" "")
936 (const:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "")]
937 UNSPEC_HW1_LAST)))])
938
939;; Second step of the 2-insn sequence to materialize a 32-bit symbolic
940;; address.
941(define_expand "mov_address_32bit_step2"
942 [(set (match_operand:SI 0 "register_operand" "")
943 (unspec:SI
944 [(match_operand:SI 1 "reg_or_0_operand" "")
945 (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
946 UNSPEC_HW0))]
947 UNSPEC_INSN_ADDR_SHL16INSLI))])
948
949\f
950;;
951;; pic related instructions
952;;
953
954;; NOTE: We compute the label in this unusual way because if we place
955;; the label after the lnk, whether it is at the same address as the
956;; lnk will vary depending on whether the optimization level chooses
957;; to insert bundling braces.
958(define_insn "insn_lnk_and_label<bitsuffix>"
959 [(set (match_operand:I48MODE 0 "register_operand" "=r")
960 (unspec_volatile:I48MODE
961 [(match_operand:I48MODE 1 "symbolic_operand" "")]
962 UNSPEC_LNK_AND_LABEL))]
963 ""
964 "%1 = . + 8\n\tlnk\t%0"
965 [(set_attr "type" "Y1")])
966
026c3cfd 967;; The next three patterns are used to materialize a position
dd552284
WL
968;; independent address by adding the difference of two labels to a
969;; base label in the text segment, assuming that the difference fits
970;; in 32 signed bits.
971(define_expand "mov_pcrel_step1<bitsuffix>"
972 [(set (match_operand:I48MODE 0 "register_operand" "")
973 (const:I48MODE (unspec:I48MODE
974 [(match_operand:I48MODE 1 "symbolic_operand" "")
975 (match_operand:I48MODE 2 "symbolic_operand" "")]
976 UNSPEC_HW1_LAST_PCREL)))]
977 "flag_pic")
978
dd552284
WL
979(define_expand "mov_pcrel_step2<bitsuffix>"
980 [(set (match_operand:I48MODE 0 "register_operand" "")
981 (unspec:I48MODE
982 [(match_operand:I48MODE 1 "reg_or_0_operand" "")
983 (const:I48MODE
984 (unspec:I48MODE [(match_operand:I48MODE 2 "symbolic_operand" "")
985 (match_operand:I48MODE 3 "symbolic_operand" "")]
986 UNSPEC_HW0_PCREL))]
987 UNSPEC_INSN_ADDR_SHL16INSLI))]
988 "flag_pic")
3aa775d6 989
dd552284
WL
990(define_insn "mov_pcrel_step3<bitsuffix>"
991 [(set (match_operand:I48MODE 0 "register_operand" "=r")
992 (unspec:I48MODE [(match_operand:I48MODE 1 "reg_or_0_operand" "rO")
993 (match_operand:I48MODE 2 "reg_or_0_operand" "rO")
994 (match_operand:I48MODE 3 "symbolic_operand" "in")
995 (match_operand:I48MODE 4 "symbolic_operand" "in")]
996 UNSPEC_MOV_PCREL_STEP3))]
997 "flag_pic"
998 "add<x>\t%0, %r1, %r2")
999
026c3cfd 1000;; The next three patterns are used to materialize a position
1773cd77
WL
1001;; independent 64-bit address by adding the difference of two labels to
1002;; a base label in the text segment, without any limitation on the size
1003;; of the difference.
1004(define_expand "mov_large_pcrel_step1"
1005 [(set (match_operand:DI 0 "register_operand" "")
1006 (const:DI (unspec:DI
1007 [(match_operand:DI 1 "symbolic_operand" "")
1008 (match_operand:DI 2 "symbolic_operand" "")]
1009 UNSPEC_HW2_LAST_PCREL)))]
1010 "flag_pic")
1011
1012(define_expand "mov_large_pcrel_step2"
1013 [(set (match_operand:DI 0 "register_operand" "")
1014 (unspec:DI
1015 [(match_operand:DI 1 "reg_or_0_operand" "")
1016 (const:DI
1017 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
1018 (match_operand:DI 3 "symbolic_operand" "")]
1019 UNSPEC_HW1_PCREL))]
1020 UNSPEC_INSN_ADDR_SHL16INSLI))]
1021 "flag_pic")
1022
1023;; Note: step 3 is same as move_pcrel_step2.
1024(define_expand "mov_large_pcrel_step3"
1025 [(set (match_operand:DI 0 "register_operand" "")
1026 (unspec:DI
1027 [(match_operand:DI 1 "reg_or_0_operand" "")
1028 (const:DI
1029 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
1030 (match_operand:DI 3 "symbolic_operand" "")]
1031 UNSPEC_HW0_PCREL))]
1032 UNSPEC_INSN_ADDR_SHL16INSLI))]
1033 "flag_pic")
1034
1035(define_insn "mov_large_pcrel_step4"
1036 [(set (match_operand:DI 0 "register_operand" "=r")
1037 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
1038 (match_operand:DI 2 "reg_or_0_operand" "rO")
1039 (match_operand:DI 3 "symbolic_operand" "in")
1040 (match_operand:DI 4 "symbolic_operand" "in")]
1041 UNSPEC_MOV_LARGE_PCREL_STEP4))]
1042 "flag_pic"
1043 "add\t%0, %r1, %r2")
1044
1045;; The next three patterns are used to materialize a position
1046;; independent 64-bit plt address by adding the difference of two
1047;; labels to a base label in the text segment.
1048(define_expand "mov_plt_pcrel_step1"
1049 [(set (match_operand:DI 0 "register_operand" "")
1050 (const:DI (unspec:DI
1051 [(match_operand:DI 1 "symbolic_operand" "")
1052 (match_operand:DI 2 "symbolic_operand" "")]
1053 UNSPEC_HW2_LAST_PLT_PCREL)))]
1054 "flag_pic")
1055
1056(define_expand "mov_plt_pcrel_step2"
1057 [(set (match_operand:DI 0 "register_operand" "")
1058 (unspec:DI
1059 [(match_operand:DI 1 "reg_or_0_operand" "")
1060 (const:DI
1061 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
1062 (match_operand:DI 3 "symbolic_operand" "")]
1063 UNSPEC_HW1_PLT_PCREL))]
1064 UNSPEC_INSN_ADDR_SHL16INSLI))]
1065 "flag_pic")
1066
1067(define_expand "mov_plt_pcrel_step3"
1068 [(set (match_operand:DI 0 "register_operand" "")
1069 (unspec:DI
1070 [(match_operand:DI 1 "reg_or_0_operand" "")
1071 (const:DI
1072 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
1073 (match_operand:DI 3 "symbolic_operand" "")]
1074 UNSPEC_HW0_PLT_PCREL))]
1075 UNSPEC_INSN_ADDR_SHL16INSLI))]
1076 "flag_pic")
1077
1078;; The next two patterns are used to materialize a position independent
1079;; 32-bit plt address by adding the difference of two labels to a base
1080;; label in the text segment.
1081(define_expand "mov_plt_pcrel_step1_32bit"
1082 [(set (match_operand:SI 0 "register_operand" "")
1083 (const:SI (unspec:SI
1084 [(match_operand:SI 1 "symbolic_operand" "")
1085 (match_operand:SI 2 "symbolic_operand" "")]
1086 UNSPEC_HW1_LAST_PLT_PCREL)))]
1087 "flag_pic")
1088
1089(define_expand "mov_plt_pcrel_step2_32bit"
1090 [(set (match_operand:SI 0 "register_operand" "")
1091 (unspec:SI
1092 [(match_operand:SI 1 "reg_or_0_operand" "")
1093 (const:SI
1094 (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
1095 (match_operand:SI 3 "symbolic_operand" "")]
1096 UNSPEC_HW0_PLT_PCREL))]
1097 UNSPEC_INSN_ADDR_SHL16INSLI))]
1098 "flag_pic")
1099
dd552284
WL
1100(define_expand "add_got16<bitsuffix>"
1101 [(set (match_operand:I48MODE 0 "register_operand" "")
1102 (plus:I48MODE
1103 (match_operand:I48MODE 1 "reg_or_0_operand" "")
1104 (const:I48MODE
1105 (unspec:I48MODE [(match_operand:I48MODE 2 "symbolic_operand" "")]
1106 UNSPEC_HW0_LAST_GOT))))]
1107 "flag_pic == 1")
1108
1109(define_expand "mov_got32_step1<bitsuffix>"
1110 [(set (match_operand:I48MODE 0 "register_operand" "")
1111 (const:I48MODE
1112 (unspec:I48MODE [(match_operand:I48MODE 1 "symbolic_operand" "")]
1113 UNSPEC_HW1_LAST_GOT)))]
1114 "flag_pic == 2")
1115
1116(define_expand "mov_got32_step2<bitsuffix>"
1117 [(set (match_operand:I48MODE 0 "register_operand" "")
1118 (unspec:I48MODE
1119 [(match_operand:I48MODE 1 "reg_or_0_operand" "")
1120 (const:I48MODE
1121 (unspec:I48MODE [(match_operand:I48MODE 2 "symbolic_operand" "")]
1122 UNSPEC_HW0_GOT))]
1123 UNSPEC_INSN_ADDR_SHL16INSLI))]
1124 "flag_pic == 2")
1125
1126\f
1127;;
1128;; TLS
1129;;
1130
1131(define_expand "mov_tls_gd_step1<bitsuffix>"
1132 [(set (match_operand:I48MODE 0 "register_operand" "")
1133 (const:I48MODE
1134 (unspec:I48MODE [(match_operand:I48MODE 1 "tls_symbolic_operand" "")]
1135 UNSPEC_HW1_LAST_TLS_GD)))]
1136 "HAVE_AS_TLS")
1137
1138(define_expand "mov_tls_gd_step2<bitsuffix>"
1139 [(set (match_operand:I48MODE 0 "register_operand" "")
1140 (unspec:I48MODE
1141 [(match_operand:I48MODE 1 "reg_or_0_operand" "")
1142 (const:I48MODE
1143 (unspec:I48MODE [(match_operand:I48MODE 2 "tls_symbolic_operand" "")]
1144 UNSPEC_HW0_TLS_GD))]
1145 UNSPEC_INSN_ADDR_SHL16INSLI))]
1146 "HAVE_AS_TLS")
1147
1148(define_expand "mov_tls_ie_step1<bitsuffix>"
1149 [(set (match_operand:I48MODE 0 "register_operand" "")
1150 (const:I48MODE
1151 (unspec:I48MODE [(match_operand:I48MODE 1 "tls_symbolic_operand" "")]
1152 UNSPEC_HW1_LAST_TLS_IE)))]
1153 "HAVE_AS_TLS")
1154
1155(define_expand "mov_tls_ie_step2<bitsuffix>"
1156 [(set (match_operand:I48MODE 0 "register_operand" "")
1157 (unspec:I48MODE
1158 [(match_operand:I48MODE 1 "reg_or_0_operand" "")
1159 (const:I48MODE
1160 (unspec:I48MODE [(match_operand:I48MODE 2 "tls_symbolic_operand" "")]
1161 UNSPEC_HW0_TLS_IE))]
1162 UNSPEC_INSN_ADDR_SHL16INSLI))]
1163 "HAVE_AS_TLS")
1164
1165(define_expand "mov_tls_le_step1<bitsuffix>"
1166 [(set (match_operand:I48MODE 0 "register_operand" "")
1167 (const:I48MODE
1168 (unspec:I48MODE [(match_operand:I48MODE 1 "tls_symbolic_operand" "")]
1169 UNSPEC_HW1_LAST_TLS_LE)))]
1170 "HAVE_AS_TLS")
1171
1172(define_expand "mov_tls_le_step2<bitsuffix>"
1173 [(set (match_operand:I48MODE 0 "register_operand" "")
1174 (unspec:I48MODE
1175 [(match_operand:I48MODE 1 "reg_or_0_operand" "")
1176 (const:I48MODE
1177 (unspec:I48MODE [(match_operand:I48MODE 2 "tls_symbolic_operand" "")]
1178 UNSPEC_HW0_TLS_LE))]
1179 UNSPEC_INSN_ADDR_SHL16INSLI))]
1180 "HAVE_AS_TLS")
1181
1182(define_expand "tls_gd_call<bitsuffix>"
1183 [(parallel
1184 [(set (reg:I48MODE 0)
1185 (unspec:I48MODE [(match_operand:I48MODE 0 "tls_symbolic_operand" "")
1186 (reg:I48MODE 0)]
1187 UNSPEC_TLS_GD_CALL))
1188 (clobber (reg:I48MODE 25))
1189 (clobber (reg:I48MODE 26))
1190 (clobber (reg:I48MODE 27))
1191 (clobber (reg:I48MODE 28))
1192 (clobber (reg:I48MODE 29))
1193 (clobber (reg:I48MODE 55))])]
1194 ""
1195{
1196 cfun->machine->calls_tls_get_addr = true;
1197})
1198
1199(define_insn "*tls_gd_call<bitsuffix>"
1200 [(set (reg:I48MODE 0)
1201 (unspec:I48MODE [(match_operand:I48MODE 0 "tls_symbolic_operand" "")
1202 (reg:I48MODE 0)]
1203 UNSPEC_TLS_GD_CALL))
1204 (clobber (reg:I48MODE 25))
1205 (clobber (reg:I48MODE 26))
1206 (clobber (reg:I48MODE 27))
1207 (clobber (reg:I48MODE 28))
1208 (clobber (reg:I48MODE 29))
1209 (clobber (reg:I48MODE 55))]
1210 ""
1211 "jal\ttls_gd_call(%0)"
1212 [(set_attr "type" "X1")])
1213
1214(define_insn "tls_gd_add<bitsuffix>"
1215 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1216 (unspec:I48MODE [(match_operand:I48MODE 1 "register_operand" "r")
1217 (match_operand:I48MODE 2 "tls_symbolic_operand" "")]
1218 UNSPEC_TLS_GD_ADD))]
1219 "HAVE_AS_TLS"
1220 "add<x>i\t%0, %1, tls_gd_add(%2)")
1221
1222(define_insn "tls_add<bitsuffix>"
1223 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1224 (unspec:I48MODE [(match_operand:I48MODE 1 "register_operand" "r")
1225 (match_operand:I48MODE 2 "register_operand" "0")
1226 (match_operand:I48MODE 3 "tls_symbolic_operand" "")]
1227 UNSPEC_TLS_ADD))]
1228 "HAVE_AS_TLS"
1229 "add<x>i\t%0, %1, tls_add(%3)")
1230
1231(define_insn "tls_ie_load<bitsuffix>"
1232 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1233 (unspec:I48MODE [(match_operand:I48MODE 1 "register_operand" "r")
1234 (match_operand:I48MODE 2 "tls_symbolic_operand" "")]
1235 UNSPEC_TLS_IE_LOAD))]
1236 "HAVE_AS_TLS"
1237 "ld<four_s_if_si>_tls\t%0, %1, tls_ie_load(%2)"
1238 [(set_attr "type" "X1_2cycle")])
1239
0f525c3e 1240(define_insn_and_split "*zero_extract<mode>"
dd552284
WL
1241 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1242 (zero_extract:I48MODE
1243 (match_operand:I48MODE 1 "reg_or_0_operand" "r")
1244 (match_operand:I48MODE 2 "u6bit_cint_operand" "n")
1245 (match_operand:I48MODE 3 "u6bit_cint_operand" "n")))]
1246 ""
1247 "bfextu\t%0, %r1, %3, %3+%2-1"
0f525c3e
WL
1248 "&& reload_completed"
1249 [(set (match_dup 0) (zero_extract:I48MODE
1250 (match_dup 1)
1251 (match_dup 2)
1252 (match_dup 3)))]
1253{
1254 HOST_WIDE_INT bit_width = INTVAL (operands[2]);
1255 HOST_WIDE_INT bit_offset = INTVAL (operands[3]);
1256
1257 if (bit_offset + bit_width > 64)
1258 operands[2] = GEN_INT (64 - bit_offset);
1259}
dd552284
WL
1260 [(set_attr "type" "X0")])
1261
1262(define_insn "*sign_extract_low32"
1263 [(set (match_operand:DI 0 "register_operand" "=r")
1264 (sign_extract:DI
1265 (match_operand:DI 1 "reg_or_0_operand" "r")
1266 (match_operand:DI 2 "u6bit_cint_operand" "n")
1267 (match_operand:DI 3 "u6bit_cint_operand" "n")))]
1268 "INTVAL (operands[3]) == 0 && INTVAL (operands[2]) == 32"
1269 "addxi\t%0, %r1, 0")
1270
0f525c3e 1271(define_insn_and_split "*sign_extract"
dd552284
WL
1272 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1273 (sign_extract:I48MODE
1274 (match_operand:I48MODE 1 "reg_or_0_operand" "r")
1275 (match_operand:I48MODE 2 "u6bit_cint_operand" "n")
1276 (match_operand:I48MODE 3 "u6bit_cint_operand" "n")))]
1277 ""
1278 "bfexts\t%0, %r1, %3, %3+%2-1"
0f525c3e
WL
1279 "&& reload_completed"
1280 [(set (match_dup 0) (sign_extract:I48MODE
1281 (match_dup 1)
1282 (match_dup 2)
1283 (match_dup 3)))]
1284{
1285 HOST_WIDE_INT bit_width = INTVAL (operands[2]);
1286 HOST_WIDE_INT bit_offset = INTVAL (operands[3]);
1287
1288 if (bit_offset + bit_width > 64)
1289 operands[2] = GEN_INT (64 - bit_offset);
1290}
dd552284
WL
1291 [(set_attr "type" "X0")])
1292
1293\f
1294;;
1295;; Arithmetic ops
1296;;
1297
1298(define_insn "add<mode>3"
1299 [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1300 (plus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rO,rO,rO")
1301 (match_operand:I48MODE 2 "add_operand" "r,I,JT")))]
1302 ""
1303 "@
1304 add<x>\t%0, %r1, %r2
1305 add<x>i\t%0, %r1, %2
1306 add<x>li\t%0, %r1, %H2"
1307 [(set_attr "type" "*,*,X01")])
1308
1309(define_insn "*addsi3_sext"
1310 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1311 (sign_extend:DI
1312 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO")
1313 (match_operand:SI 2 "add_operand" "r,I,JT"))))]
1314 ""
1315 "@
1316 addx\t%0, %r1, %r2
1317 addxi\t%0, %r1, %2
1318 addxli\t%0, %r1, %H2"
1319 [(set_attr "type" "*,*,X01")])
1320
1321(define_insn "sub<mode>3"
1322 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1323 (minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
1324 (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
1325 ""
1326 "sub<x>\t%0, %r1, %r2")
1327
1328(define_insn "*subsi3_sext"
1329 [(set (match_operand:DI 0 "register_operand" "=r")
1330 (sign_extend:DI
1331 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1332 (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
1333 ""
1334 "subx\t%0, %r1, %r2")
1335
1336(define_insn "neg<mode>2"
1337 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1338 (neg:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO")))]
1339 ""
1340 "sub<x>\t%0, zero, %r1")
1341
1342(define_insn "*negsi2_sext"
1343 [(set (match_operand:DI 0 "register_operand" "=r")
1344 (sign_extend:DI
1345 (neg:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))))]
1346 ""
1347 "subx\t%0, zero, %r1")
1348
1349(define_insn "ssaddsi3"
1350 [(set (match_operand:SI 0 "register_operand" "=r")
1351 (ss_plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1352 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
1353 ""
1354 "addxsc\t%0, %r1, %r2"
1355 [(set_attr "type" "X01")])
1356
1357(define_insn "*ssaddsi3_sext"
1358 [(set (match_operand:DI 0 "register_operand" "=r")
1359 (sign_extend:DI
1360 (ss_plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1361 (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
1362 ""
1363 "addxsc\t%0, %r1, %r2"
1364 [(set_attr "type" "X01")])
1365
1366(define_insn "sssubsi3"
1367 [(set (match_operand:SI 0 "register_operand" "=r")
1368 (ss_minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1369 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
1370 ""
1371 "subxsc\t%0, %r1, %r2"
1372 [(set_attr "type" "X01")])
1373
1374(define_insn "*sssubsi3_sext"
1375 [(set (match_operand:DI 0 "register_operand" "=r")
1376 (sign_extend:DI
1377 (ss_minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1378 (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
1379 ""
1380 "subxsc\t%0, %r1, %r2"
1381 [(set_attr "type" "X01")])
1382
1383(define_expand "addsf3"
1384 [(set (match_operand:SF 0 "register_operand" "")
1385 (plus:SF (match_operand:SF 1 "register_operand" "")
1386 (match_operand:SF 2 "register_operand" "")))]
1387 ""
1388{
1389 rtx result = gen_lowpart (DImode, operands[0]);
1390 rtx a = gen_lowpart (DImode, operands[1]);
1391 rtx b = gen_lowpart (DImode, operands[2]);
1392
1393 rtx tmp = gen_reg_rtx (DImode);
1394 rtx flags = gen_reg_rtx (DImode);
1395
1396 emit_insn (gen_insn_fsingle_add1 (tmp, a, b));
1397 emit_insn (gen_insn_fsingle_addsub2 (tmp, tmp, a, b));
1398 emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
1399 emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
1400
1401 DONE;
1402})
1403
1404(define_expand "subsf3"
1405 [(set (match_operand:SF 0 "register_operand" "")
1406 (minus:SF (match_operand:SF 1 "register_operand" "")
1407 (match_operand:SF 2 "register_operand" "")))]
1408 ""
1409{
1410 rtx result = gen_lowpart (DImode, operands[0]);
1411 rtx a = gen_lowpart (DImode, operands[1]);
1412 rtx b = gen_lowpart (DImode, operands[2]);
1413
1414 rtx tmp = gen_reg_rtx (DImode);
1415 rtx flags = gen_reg_rtx (DImode);
1416
1417 emit_insn (gen_insn_fsingle_sub1 (tmp, a, b));
1418 emit_insn (gen_insn_fsingle_addsub2 (tmp, tmp, a, b));
1419 emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
1420 emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
1421
1422 DONE;
1423})
1424
1425(define_expand "mulsf3"
1426 [(set (match_operand:SF 0 "register_operand" "")
1427 (mult:SF (match_operand:SF 1 "register_operand" "")
1428 (match_operand:SF 2 "register_operand" "")))]
1429 ""
1430{
1431 rtx result = gen_lowpart (DImode, operands[0]);
1432 rtx a = gen_lowpart (DImode, operands[1]);
1433 rtx b = gen_lowpart (DImode, operands[2]);
1434
1435 rtx tmp1 = gen_reg_rtx (DImode);
1436 rtx tmp2 = gen_reg_rtx (DImode);
1437 rtx flags = gen_reg_rtx (DImode);
1438
1439 emit_insn (gen_insn_fsingle_mul1 (tmp1, a, b));
1440 emit_insn (gen_insn_fsingle_mul2 (tmp2, tmp1, b));
1441 emit_insn (gen_insn_fsingle_pack1 (flags, tmp2));
1442 emit_insn (gen_insn_fsingle_pack2 (result, tmp2, flags));
1443
1444 DONE;
1445})
1446
1447(define_expand "adddf3"
1448 [(set (match_operand:DF 0 "register_operand" "")
1449 (plus:DF (match_operand:DF 1 "register_operand" "")
1450 (match_operand:DF 2 "register_operand" "")))]
1451 ""
1452{
1453 rtx result = gen_lowpart (DImode, operands[0]);
1454 rtx a = gen_lowpart (DImode, operands[1]);
1455 rtx b = gen_lowpart (DImode, operands[2]);
1456
1457 rtx min = gen_reg_rtx (DImode);
1458 rtx max = gen_reg_rtx (DImode);
1459 rtx flags = gen_reg_rtx (DImode);
1460
1461 emit_insn (gen_insn_fdouble_unpack_min (min, a, b));
1462 emit_insn (gen_insn_fdouble_unpack_max (max, a, b));
1463 emit_insn (gen_insn_fdouble_add_flags (flags, a, b));
1464 emit_insn (gen_insn_fdouble_addsub (max, max, min, flags));
1465 emit_insn (gen_insn_fdouble_pack1 (result, max, flags));
1466 emit_insn (gen_insn_fdouble_pack2 (result, result, max, const0_rtx));
1467
1468 DONE;
1469})
1470
dd552284
WL
1471(define_expand "subdf3"
1472 [(set (match_operand:DF 0 "register_operand" "")
1473 (minus:DF (match_operand:DF 1 "register_operand" "")
1474 (match_operand:DF 2 "register_operand" "")))]
1475 ""
1476{
1477 rtx result = gen_lowpart (DImode, operands[0]);
1478 rtx a = gen_lowpart (DImode, operands[1]);
1479 rtx b = gen_lowpart (DImode, operands[2]);
1480
1481 rtx min = gen_reg_rtx (DImode);
1482 rtx max = gen_reg_rtx (DImode);
1483 rtx flags = gen_reg_rtx (DImode);
1484
1485 emit_insn (gen_insn_fdouble_unpack_min (min, a, b));
1486 emit_insn (gen_insn_fdouble_unpack_max (max, a, b));
1487 emit_insn (gen_insn_fdouble_sub_flags (flags, a, b));
1488 emit_insn (gen_insn_fdouble_addsub (max, max, min, flags));
1489 emit_insn (gen_insn_fdouble_pack1 (result, max, flags));
1490 emit_insn (gen_insn_fdouble_pack2 (result, result, max, const0_rtx));
1491
1492 DONE;
1493})
1494
1495(define_expand "muldf3"
1496 [(set (match_operand:DF 0 "register_operand" "")
1497 (mult:DF (match_operand:DF 1 "register_operand" "")
1498 (match_operand:DF 2 "register_operand" "")))]
1499 ""
1500 ;; TODO: Decide if we should not inline this with -Os.
1501 ;; "optimize_function_for_speed_p (cfun)"
1502{
1503 rtx result = gen_lowpart (DImode, operands[0]);
1504 rtx a = gen_lowpart (DImode, operands[1]);
1505 rtx b = gen_lowpart (DImode, operands[2]);
1506
1507 rtx a_unpacked = gen_reg_rtx (DImode);
1508 rtx b_unpacked = gen_reg_rtx (DImode);
1509 rtx flags = gen_reg_rtx (DImode);
1510
1511 rtx low1 = gen_reg_rtx (DImode);
1512 rtx low = gen_reg_rtx (DImode);
1513 rtx low_carry = gen_reg_rtx (DImode);
1514
1515 rtx mid = gen_reg_rtx (DImode);
1516 rtx mid_l32 = gen_reg_rtx (DImode);
1517 rtx mid_r32 = gen_reg_rtx (DImode);
1518
1519 rtx high1 = gen_reg_rtx (DImode);
1520 rtx high = gen_reg_rtx (DImode);
1521 rtx high1_plus_mid_r32 = gen_reg_rtx (DImode);
1522
1523 /* NOTE: We compute using max(a, 0) and max(b, 0) rather than
1524 min(a, b) and max(a, b) because for multiply we just need to unpack,
1525 we don't actually care which is min and which is max. And this
1526 formulation gives the scheduler more freedom in case one of a or b
1527 would stall at the start of this code sequence. */
1528 emit_insn (gen_insn_fdouble_unpack_max (a_unpacked, a, const0_rtx));
1529 emit_insn (gen_insn_fdouble_unpack_max (b_unpacked, b, const0_rtx));
1530 emit_insn (gen_insn_fdouble_mul_flags (flags, a, b));
1531
1532 /* This depends on the fact that the high few bits of the unpacked
1533 mantissa are zero, so we can't have a carry out from the mid sum. */
1534 emit_insn (gen_insn_mul_lu_lu (low1, a_unpacked, b_unpacked));
1535 emit_insn (gen_insn_mul_hu_lu (mid, a_unpacked, b_unpacked));
1536 emit_insn (gen_insn_mula_hu_lu (mid, mid, b_unpacked, a_unpacked));
1537 emit_insn (gen_insn_mul_hu_hu (high1, a_unpacked, b_unpacked));
1538
1539 emit_insn (gen_ashldi3 (mid_l32, mid, GEN_INT (32)));
1540 emit_insn (gen_lshrdi3 (mid_r32, mid, GEN_INT (32)));
1541
1542 emit_insn (gen_adddi3 (high1_plus_mid_r32, high1, mid_r32));
1543
1544 emit_insn (gen_adddi3 (low, low1, mid_l32));
1545 emit_insn (gen_insn_cmpltu_didi (low_carry, low, mid_l32));
1546
1547 emit_insn (gen_adddi3 (high, high1_plus_mid_r32, low_carry));
1548
1549 emit_insn (gen_insn_fdouble_pack1 (result, high, flags));
1550 emit_insn (gen_insn_fdouble_pack2 (result, result, high, low));
1551
1552 DONE;
1553})
1554
1555\f
1556;;
1557;; Shifts
1558;;
1559
1560(define_insn "ashl<mode>3"
1561 [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
1562 (ashift:I48MODE
1563 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1564 (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
1565 ""
1566 "@
1567 shl<x>i\t%0, %r1, %2
1568 shl<x>\t%0, %r1, %r2"
1569 [(set_attr "type" "<shift_pipe>,<shift_pipe>")])
1570
1571(define_insn "*ashlsi3_sext"
1572 [(set (match_operand:DI 0 "register_operand" "=r,r")
1573 (sign_extend:DI
1574 (ashift:SI
1575 (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1576 (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
1577 ""
1578 "@
1579 shlxi\t%0, %r1, %2
1580 shlx\t%0, %r1, %r2"
1581 [(set_attr "type" "X01,X01")])
1582
1583(define_insn "ashr<mode>3"
1584 [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
1585 (ashiftrt:I48MODE
1586 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1587 (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
1588 ""
1589 "@
1590 shrsi\t%0, %r1, %2
1591 shrs\t%0, %r1, %r2")
1592
1593(define_insn "*ashrsi3_sext"
1594 [(set (match_operand:DI 0 "register_operand" "=r,r")
1595 (sign_extend:DI
1596 (ashiftrt:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1597 (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
1598 ""
1599 "@
1600 shrsi\t%0, %r1, %2
1601 shrs\t%0, %r1, %r2")
1602
1603(define_insn "lshr<mode>3"
1604 [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
1605 (lshiftrt:I48MODE
1606 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1607 (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
1608 ""
1609 "@
1610 shru<x>i\t%0, %r1, %2
1611 shru<x>\t%0, %r1, %r2"
1612 [(set_attr "type" "<shift_pipe>,<shift_pipe>")])
1613
1614(define_insn "*lshrsi3_sext"
1615 [(set (match_operand:DI 0 "register_operand" "=r,r")
1616 (sign_extend:DI
1617 (lshiftrt:SI
1618 (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1619 (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
1620 ""
1621 "@
1622 shruxi\t%0, %r1, %2
1623 shrux\t%0, %r1, %r2"
1624 [(set_attr "type" "X01,X01")])
1625
1626(define_insn "rotldi3"
1627 [(set (match_operand:DI 0 "register_operand" "=r,r")
1628 (rotate:DI (match_operand:DI 1 "reg_or_0_operand" "rO,rO")
1629 (match_operand:SI 2 "reg_or_u6bit_operand" "I,rO")))]
1630 ""
1631 "@
1632 rotli\t%0, %r1, %2
1633 rotl\t%0, %r1, %r2")
1634
1635(define_insn "insn_shl16insli"
1636 [(set (match_operand:DI 0 "register_operand" "=r,r")
1637 (ior:DI
1638 (ashift:DI
1639 (match_operand:DI 1 "reg_or_0_operand" "rO,rO")
1640 (const_int 16))
1641 (match_operand:DI 2 "u16bit_or_const_symbolic_operand" "O,KT")))]
1642 ""
1643 "@
1644 shli\t%0, %r1, 16
1645 shl16insli\t%0, %r1, %H2"
1646 [(set_attr "type" "*,X01")])
1647
1648(define_insn "insn_addr_shl16insli<bitsuffix>"
1649 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1650 (unspec:I48MODE
1651 [(match_operand:I48MODE 1 "reg_or_0_operand" "rO")
1652 (match_operand:I48MODE 2 "const_symbolic_operand" "T")]
1653 UNSPEC_INSN_ADDR_SHL16INSLI))]
1654 ""
1655 "shl16insli\t%0, %r1, %H2"
1656 [(set_attr "type" "X01")])
1657
1658\f
1659;;
1660;; Compares
1661;;
1662
1663(define_expand "cstore<mode>4"
1664 [(set (match_operand:DI 0 "register_operand" "")
1665 (match_operator:DI 1 "ordered_comparison_operator"
1666 [(match_operand:FI48MODE 2 "reg_or_cint_operand" "")
1667 (match_operand:FI48MODE 3 "reg_or_cint_operand" "")]))]
1668 ""
1669{
1670 if (!tilegx_emit_setcc (operands, GET_MODE (operands[2])))
1671 FAIL;
1672 else
1673 DONE;
1674})
1675
1676
1677(define_insn "insn_cmpne_<I48MODE:mode><I48MODE2:mode>"
1678 [(set (match_operand:I48MODE2 0 "register_operand" "=r")
1679 (ne:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
1680 (match_operand:I48MODE 2 "reg_or_cint_operand" "rO")))]
1681 ""
1682 "cmpne\t%0, %r1, %r2")
1683
1684(define_insn "insn_cmpeq_<I48MODE:mode><I48MODE2:mode>"
1685 [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1686 (eq:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "%rO,rO")
1687 (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
1688 ""
1689 "@
1690 cmpeqi\t%0, %r1, %2
1691 cmpeq\t%0, %r1, %r2")
1692
1693(define_insn "insn_cmplts_<I48MODE:mode><I48MODE2:mode>"
1694 [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1695 (lt:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1696 (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
1697 ""
1698 "@
1699 cmpltsi\t%0, %r1, %2
1700 cmplts\t%0, %r1, %r2")
1701
1702(define_insn "insn_cmpltu_<I48MODE:mode><I48MODE2:mode>"
1703 [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1704 (ltu:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1705 (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
1706 ""
1707 "@
1708 cmpltui\t%0, %r1, %2
1709 cmpltu\t%0, %r1, %r2"
1710 [(set_attr "type" "X01,*")])
1711
1712(define_insn "insn_cmples_<I48MODE:mode><I48MODE2:mode>"
1713 [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1714 (le:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1715 (match_operand:I48MODE 2 "reg_or_cint_operand" "L,rO")))]
1716 ""
1717 "@
1718 cmpltsi\t%0, %r1, %P2
1719 cmples\t%0, %r1, %r2")
1720
1721(define_insn "insn_cmpleu_<I48MODE:mode><I48MODE2:mode>"
1722 [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1723 (leu:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1724 (match_operand:I48MODE 2 "reg_or_cint_operand" "Q,rO")))]
1725 ""
1726 "@
1727 cmpltui\t%0, %r1, %P2
1728 cmpleu\t%0, %r1, %r2"
1729 [(set_attr "type" "X01,*")])
1730
1731\f
1732;;
1733;; Logical ops
1734;;
1735
1736(define_insn "and<mode>3"
1737 [(set (match_operand:IVNMODE 0 "register_operand" "=r,r,r,r")
1738 (and:IVNMODE (match_operand:IVNMODE 1 "reg_or_0_operand" "%rO,rO,0,rO")
1739 (match_operand:IVNMODE 2 "and_operand" "I,S,M,rO")))]
1740 ""
1741 "@
1742 andi\t%0, %r1, %2
1743 bfextu\t%0, %r1, %M2
1744 bfins\t%0, zero, %m2
1745 and\t%0, %r1, %r2"
1746 [(set_attr "type" "*,X0,X0,*")])
1747
1748(define_insn "*andsi3_sext"
1749 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
1750 (sign_extend:DI
1751 (and:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,0,rO")
1752 (match_operand:SI 2 "and_operand" "I,S,M,rO"))))]
1753 ""
1754 "@
1755 andi\t%0, %r1, %2
1756 bfextu\t%0, %r1, %M2
1757 bfins\t%0, zero, %m2
1758 and\t%0, %r1, %r2"
1759 [(set_attr "type" "*,X0,X0,*")])
1760
1761(define_insn "anddi3"
1762 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
1763 (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO,rO,0,rO")
1764 (match_operand:DI 2 "and_operand" "I,Z0,Z1,S,M,rO")))]
1765 ""
1766 "@
1767 andi\t%0, %r1, %2
1768 v4int_l\t%0, zero, %r1
1769 v4int_h\t%0, %r1, zero
1770 bfextu\t%0, %r1, %M2
1771 bfins\t%0, zero, %m2
1772 and\t%0, %r1, %r2"
1773 [(set_attr "type" "*,X01,X01,X0,X0,*")])
1774
1775(define_insn "ior<mode>3"
1776 [(set (match_operand:IVMODE 0 "register_operand" "=r,r")
1777 (ior:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "%rO,rO")
1778 (match_operand:IVMODE 2 "reg_or_s8bit_operand" "rO,I")))]
1779 ""
1780 "@
1781 or\t%0, %r1, %r2
1782 ori\t%0, %r1, %2"
1783 [(set_attr "type" "*,X01")])
1784
1785(define_insn "*iorsi3_sext"
1786 [(set (match_operand:DI 0 "register_operand" "=r,r")
1787 (sign_extend:DI
1788 (ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
1789 (match_operand:SI 2 "reg_or_s8bit_operand" "rO,I"))))]
1790 ""
1791 "@
1792 or\t%0, %r1, %r2
1793 ori\t%0, %r1, %2"
1794 [(set_attr "type" "*,X01")])
1795
1796(define_insn "xor<mode>3"
1797 [(set (match_operand:IVMODE 0 "register_operand" "=r,r")
1798 (xor:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "%rO,rO")
1799 (match_operand:IVMODE 2 "reg_or_s8bit_operand" "rO,I")))]
1800 ""
1801 "@
1802 xor\t%0, %r1, %r2
1803 xori\t%0, %r1, %2"
1804 [(set_attr "type" "*,X01")])
1805
1806(define_insn "*xorsi3_sext"
1807 [(set (match_operand:DI 0 "register_operand" "=r,r")
1808 (sign_extend:DI
1809 (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
1810 (match_operand:SI 2 "reg_or_s8bit_operand" "rO,I"))))]
1811 ""
1812 "@
1813 xor\t%0, %r1, %r2
1814 xori\t%0, %r1, %2"
1815 [(set_attr "type" "*,X01")])
1816
1817(define_insn "clzdi2"
1818 [(set (match_operand:DI 0 "register_operand" "=r")
1819 (clz:DI (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1820 ""
1821 "clz\t%0, %r1"
1822 [(set_attr "type" "Y0")])
1823
1824(define_expand "clzsi2"
814049be
WL
1825 [(set (match_operand:SI 0 "register_operand" "=r")
1826 (clz:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))]
1827 ""
1828 {
1829 rtx tmp1 = gen_reg_rtx (DImode);
1830 rtx tmp2 = gen_reg_rtx (DImode);
1831 rtx tmp3 = gen_reg_rtx (DImode);
1832
1833 emit_insn (gen_zero_extendsidi2 (tmp1, operands[1]));
1834 emit_insn (gen_ashldi3 (tmp2, tmp1, (GEN_INT (32))));
1835 emit_insn (gen_clzdi2 (tmp3, tmp2));
1836 emit_move_insn (operands[0], gen_lowpart (SImode, tmp3));
1837 DONE;
1838 })
dd552284
WL
1839
1840(define_insn "ctz<mode>2"
1841 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1842 (ctz:I48MODE (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1843 ""
1844 "ctz\t%0, %r1"
1845 [(set_attr "type" "Y0")])
1846
dd552284
WL
1847(define_insn "popcount<mode>2"
1848 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1849 (popcount:I48MODE (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1850 ""
1851 "pcnt\t%0, %r1"
1852 [(set_attr "type" "Y0")])
1853
1854(define_expand "parity<mode>2"
1855 [(set (match_operand:I48MODE 0 "register_operand" "")
1856 (parity:I48MODE (match_operand:DI 1 "reg_or_0_operand" "")))]
1857 ""
1858 {
1859 rtx tmp = gen_reg_rtx (<MODE>mode);
1860 emit_insn (gen_popcount<mode>2 (tmp, operands[1]));
1861 emit_insn (gen_and<mode>3 (operands[0], tmp, const1_rtx));
1862 DONE;
1863 })
1864
1865(define_insn "bswapdi2"
1866 [(set (match_operand:DI 0 "register_operand" "=r")
1867 (bswap:DI (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1868 ""
1869 "revbytes\t%0, %r1"
1870 [(set_attr "type" "Y0")])
1871
1872(define_expand "bswapsi2"
1873 [(set (match_operand:SI 0 "register_operand" "")
1874 (bswap:SI (match_operand:SI 1 "reg_or_0_operand" "")))]
1875 ""
1876 {
1877 rtx tmp = gen_reg_rtx (DImode);
1878 emit_insn (gen_bswapdi2 (tmp, gen_lowpart (DImode, operands[1])));
1879 emit_insn (gen_ashrdi3 (gen_lowpart (DImode, operands[0]),
1880 tmp, GEN_INT (32)));
1881 DONE;
1882 })
1883
1884(define_insn "one_cmpl<mode>2"
1885 [(set (match_operand:IVMODE 0 "register_operand" "=r")
1886 (not:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "rO")))]
1887 ""
1888 "nor\t%0, %r1, zero")
1889
1890\f
1891;;
1892;; Conditional moves
1893;;
1894
1895(define_expand "mov<mode>cc"
1896 [(set (match_operand:I48MODE 0 "register_operand" "")
1897 (if_then_else:I48MODE
1898 (match_operand 1 "comparison_operator" "")
1899 (match_operand:I48MODE 2 "reg_or_0_operand" "")
1900 (match_operand:I48MODE 3 "reg_or_0_operand" "")))]
1901 ""
1902 { operands[1] = tilegx_emit_conditional_move (operands[1]); })
1903
1904(define_insn "movcc_insn_<I48MODE2:mode><I48MODE:mode>"
1905 [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r,r")
1906 (if_then_else:I48MODE
1907 (match_operator 4 "eqne_operator"
1908 [(match_operand:I48MODE2 1 "reg_or_0_operand" "rO,rO,rO,rO")
1909 (const_int 0)])
1910 (match_operand:I48MODE 2 "reg_or_0_operand" "rO,O,rO,0")
1911 (match_operand:I48MODE 3 "reg_or_0_operand" "O,rO,0,rO")))]
1912 ""
1913 "@
1914 m%c4\t%0, %r1, %r2
1915 m%C4\t%0, %r1, %r3
1916 cmov%d4z\t%0, %r1, %r2
1917 cmov%D4z\t%0, %r1, %r3"
1918 [(set_attr "type" "*,*,Y0,Y0")])
1919
1920(define_expand "insn_mz"
1921 [(set (match_operand:DI 0 "register_operand" "")
1922 (if_then_else:DI
1923 (eq (match_operand:DI 1 "reg_or_0_operand" "")
1924 (const_int 0))
1925 (match_operand:DI 2 "reg_or_0_operand" "")
1926 (const_int 0)))])
1927
1928(define_expand "insn_mnz"
1929 [(set (match_operand:DI 0 "register_operand" "")
1930 (if_then_else:DI
1931 (ne (match_operand:DI 1 "reg_or_0_operand" "")
1932 (const_int 0))
1933 (match_operand:DI 2 "reg_or_0_operand" "")
1934 (const_int 0)))])
1935
1936(define_expand "insn_cmoveqz"
1937 [(set (match_operand:DI 0 "register_operand" "")
1938 (if_then_else:DI
1939 (eq (match_operand:DI 2 "reg_or_0_operand" "")
1940 (const_int 0))
1941 (match_operand:DI 3 "reg_or_0_operand" "")
1942 (match_operand:DI 1 "reg_or_0_operand" "")))])
1943
1944(define_expand "insn_cmovnez"
1945 [(set (match_operand:DI 0 "register_operand" "")
1946 (if_then_else:DI
1947 (ne (match_operand:DI 2 "reg_or_0_operand" "")
1948 (const_int 0))
1949 (match_operand:DI 3 "reg_or_0_operand" "")
1950 (match_operand:DI 1 "reg_or_0_operand" "")))])
1951
1952\f
1953;;
1954;; Conversions
1955;;
1956
1957(define_insn "zero_extendqi<mode>2"
1958 [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1959 (zero_extend:I48MODE (match_operand:QI 1 "move_operand" "rO,U,m")))]
1960 ""
1961 "@
1962 bfextu\t%0, %r1, 0, 7
1963 ld1u\t%0, %1
1964 ld1u_add\t%0, %I1, %i1"
1965 [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1966
1967(define_insn "zero_extendhi<mode>2"
1968 [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1969 (zero_extend:I48MODE (match_operand:HI 1 "move_operand" "rO,U,m")))]
1970 ""
1971 "@
1972 bfextu\t%0, %r1, 0, 15
1973 ld2u\t%0, %1
1974 ld2u_add\t%0, %I1, %i1"
1975 [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1976
1977(define_insn "zero_extendsidi2"
1978 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1979 (zero_extend:DI (match_operand:SI 1 "move_operand" "rO,U,m")))]
1980 ""
1981 "@
1982 v4int_l\t%0, zero, %r1
1983 ld4u\t%0, %1
1984 ld4u_add\t%0, %I1, %i1"
1985 [(set_attr "type" "X01,Y2_2cycle,X1_2cycle")])
1986
1987(define_insn "extendqi<mode>2"
1988 [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1989 (sign_extend:I48MODE (match_operand:QI 1 "move_operand" "rO,U,m")))]
1990 ""
1991 "@
1992 bfexts\t%0, %r1, 0, 7
1993 ld1s\t%0, %1
1994 ld1s_add\t%0, %I1, %i1"
1995 [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1996
1997(define_insn "extendhi<mode>2"
1998 [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1999 (sign_extend:I48MODE (match_operand:HI 1 "move_operand" "rO,U,m")))]
2000 ""
2001 "@
2002 bfexts\t%0, %r1, 0, 15
2003 ld2s\t%0, %1
2004 ld2s_add\t%0, %I1, %i1"
2005 [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
2006
bb149ca2
RS
2007;; All SImode integer registers should already be in sign-extended form
2008;; (see TARGET_TRULY_NOOP_TRUNCATION and truncdisi2). We can therefore
dd552284
WL
2009;; get rid of register->register instructions if we constrain the
2010;; source to be in the same register as the destination.
2011(define_insn_and_split "extendsidi2"
2012 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
2013 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,U,m")))]
2014 ""
2015 "@
2016 #
2017 ld4s\t%0, %1
2018 ld4s_add\t%0, %I1, %i1"
2019 "&& reload_completed && register_operand (operands[1], VOIDmode)"
2020 [(const_int 0)]
2021{
2022 emit_note (NOTE_INSN_DELETED);
2023 DONE;
2024}
2025 [(set_attr "type" "*,Y2_2cycle,X1_2cycle")])
2026
2027;; Integer truncation patterns. Truncating SImode values to smaller
2028;; modes is a no-op, as it is for most other GCC ports. Truncating
2029;; DImode values to SImode is not a no-op since we
2030;; need to make sure that the lower 32 bits are properly sign-extended
bb149ca2 2031;; (see TARGET_TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
dd552284
WL
2032;; smaller than SImode is equivalent to two separate truncations:
2033;;
2034;; A B
2035;; DI ---> HI == DI ---> SI ---> HI
2036;; DI ---> QI == DI ---> SI ---> QI
2037;;
2038;; Step A needs a real instruction but step B does not.
2039
2040(define_insn "truncdisi2"
2041 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,U,m")
2042 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
2043 ""
2044 "@
2045 addxi\t%0, %r1, 0
2046 st4\t%0, %r1
2047 st4_add\t%I0, %r1, %i0"
2048 [(set_attr "type" "Y01,Y2,X1")])
2049
2050(define_insn "truncdihi2"
2051 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,U,m")
2052 (truncate:HI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
2053 ""
2054 "@
2055 addxi\t%0, %r1, 0
2056 st2\t%0, %r1
2057 st2_add\t%I0, %r1, %i0"
2058 [(set_attr "type" "Y01,Y2,X1")])
2059
2060(define_insn "truncdiqi2"
2061 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,U,m")
2062 (truncate:QI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
2063 ""
2064 "@
2065 addxi\t%0, %r1, 0
2066 st1\t%0, %r1
2067 st1_add\t%I0, %r1, %i0"
2068 [(set_attr "type" "Y01,Y2,X1")])
2069
2070;; Combiner patterns to optimize away unnecessary truncates.
2071
2072(define_insn "*zero_extendsidi_truncdisi"
2073 [(set (match_operand:DI 0 "register_operand" "=r")
2074 (zero_extend:DI
3aa775d6 2075 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))))]
dd552284
WL
2076 ""
2077 "v4int_l\t%0, zero, %r1"
2078 [(set_attr "type" "X01")])
2079
2080(define_insn "*addsi_truncdisi"
2081 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2082 (plus:SI
2083 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO"))
2084 (match_operand:SI 2 "add_operand" "r,I,JT")))]
2085 ""
2086 "@
2087 addx\t%0, %r1, %r2
2088 addxi\t%0, %r1, %2
2089 addxli\t%0, %r1, %H2"
2090 [(set_attr "type" "*,*,X01")])
2091
2092(define_insn "*addsi_truncdisi2"
2093 [(set (match_operand:SI 0 "register_operand" "=r")
2094 (plus:SI
2095 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))
2096 (truncate:SI (match_operand:DI 2 "reg_or_0_operand" "rO"))))]
2097 ""
2098 "addx\t%0, %r1, %r2")
2099
2100(define_insn "*ashldi_truncdisi"
2101 [(set (match_operand:DI 0 "register_operand" "=r")
2102 (ashift:DI
2103 (match_operand:DI 1 "reg_or_0_operand" "rO")
2104 (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
2105 ""
2106 "shl\t%0, %r1, %r2")
2107
2108(define_insn "*ashlsi_truncdisi"
2109 [(set (match_operand:SI 0 "register_operand" "=r,r")
2110 (ashift:SI
2111 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO,rO"))
2112 (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
2113 ""
2114 "@
2115 shlxi\t%0, %r1, %2
2116 shlx\t%0, %r1, %r2"
2117 [(set_attr "type" "X01,X01")])
2118
2119(define_insn "*ashlsi_truncdisi2"
2120 [(set (match_operand:SI 0 "register_operand" "=r")
2121 (ashift:SI
2122 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))
2123 (truncate:SI (match_operand:DI 2 "reg_or_0_operand" "rO"))))]
2124 ""
2125 "shlx\t%0, %r1, %r2"
2126 [(set_attr "type" "X01")])
2127
2128(define_insn "*ashrdi3_truncdisi"
2129 [(set (match_operand:DI 0 "register_operand" "=r")
2130 (ashiftrt:DI
2131 (match_operand:DI 1 "reg_or_0_operand" "rO")
2132 (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
2133 ""
2134 "shrs\t%0, %r1, %r2")
2135
2136(define_insn "*lshrsi_truncdisi"
2137 [(set (match_operand:SI 0 "register_operand" "=r,r")
2138 (lshiftrt:SI
2139 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO,rO"))
2140 (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
2141 ""
2142 "@
2143 shruxi\t%0, %r1, %2
2144 shrux\t%0, %r1, %r2"
2145 [(set_attr "type" "X01,X01")])
3aa775d6 2146
dd552284
WL
2147(define_insn "*lshrsi_truncdisi2"
2148 [(set (match_operand:SI 0 "register_operand" "=r")
2149 (lshiftrt:SI
2150 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))
2151 (truncate:SI (match_operand:DI 2 "reg_or_0_operand" "rO"))))]
2152 ""
2153 "shrux\t%0, %r1, %r2"
2154 [(set_attr "type" "X01")])
2155
2156(define_insn "*lshrdi_truncdisi"
2157 [(set (match_operand:DI 0 "register_operand" "=r")
2158 (lshiftrt:DI
2159 (match_operand:DI 1 "reg_or_0_operand" "rO")
2160 (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
2161 ""
2162 "shru\t%0, %r1, %r2")
2163
2164(define_insn "*rotldi_truncdisi"
2165 [(set (match_operand:DI 0 "register_operand" "=r")
2166 (rotate:DI
2167 (match_operand:DI 1 "reg_or_0_operand" "rO")
2168 (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
2169 ""
2170 "rotl\t%0, %r1, %r2")
2171
065a3605
WL
2172;; Integer to floating point conversions
2173
2174(define_expand "floatsisf2"
2175 [(set (match_operand:SF 0 "register_operand" "")
2176 (float:SI (match_operand:SI 1 "register_operand" "")))]
2177 ""
2178{
2179 rtx result = gen_lowpart (DImode, operands[0]);
2180 rtx a = operands[1];
2181
2182 rtx nega = gen_reg_rtx (SImode);
2183 rtx exp = gen_reg_rtx (DImode);
2184 rtx sign = gen_reg_rtx (DImode);
2185 rtx abs = gen_reg_rtx (DImode);
2186 rtx flags = gen_reg_rtx (DImode);
2187 rtx tmp1 = gen_reg_rtx (DImode);
2188 rtx tmp2 = gen_reg_rtx (DImode);
2189
2190 emit_move_insn (exp, GEN_INT (0x9e));
2191
2192 emit_insn (gen_negsi2 (nega, a));
2193
2194 emit_insn (gen_insn_cmplts_sisi (gen_lowpart (SImode, sign), a, const0_rtx));
2195 emit_insn (gen_insn_cmoveqz (abs, gen_lowpart (DImode, nega), sign,
2196 gen_lowpart (DImode, a)));
2197
2198 emit_insn (gen_insn_bfins (tmp1, exp, sign, GEN_INT (10), GEN_INT (10)));
2199 emit_insn (gen_insn_bfins (tmp2, tmp1, abs, GEN_INT (32), GEN_INT (63)));
2200 emit_insn (gen_insn_fsingle_pack1 (flags, tmp2));
2201 emit_insn (gen_insn_fsingle_pack2 (result, tmp2, flags));
2202 DONE;
2203})
2204
2205(define_expand "floatunssisf2"
2206 [(set (match_operand:SF 0 "register_operand" "")
2207 (float:SI (match_operand:SI 1 "register_operand" "")))]
2208 ""
2209{
2210 rtx result = gen_lowpart (DImode, operands[0]);
2211 rtx a = operands[1];
2212
2213 rtx exp = gen_reg_rtx (DImode);
2214 rtx flags = gen_reg_rtx (DImode);
2215 rtx tmp = gen_reg_rtx (DImode);
2216
2217 emit_move_insn (exp, GEN_INT (0x9e));
2218 emit_insn (gen_insn_bfins (tmp, exp, gen_lowpart (DImode, a),
2219 GEN_INT (32), GEN_INT (63)));
2220 emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
2221 emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
2222 DONE;
2223})
2224
2225(define_expand "floatsidf2"
2226 [(set (match_operand:DF 0 "register_operand" "")
2227 (float:SI (match_operand:SI 1 "register_operand" "")))]
2228 ""
2229{
2230 rtx result = gen_lowpart (DImode, operands[0]);
2231 rtx a = gen_lowpart (DImode, operands[1]);
2232
2233 rtx nega = gen_reg_rtx (DImode);
2234 rtx exp = gen_reg_rtx (DImode);
2235 rtx sign = gen_reg_rtx (DImode);
2236 rtx abs = gen_reg_rtx (DImode);
2237 rtx tmp1 = gen_reg_rtx (DImode);
2238 rtx tmp2 = gen_reg_rtx (DImode);
2239 rtx tmp3 = gen_reg_rtx (DImode);
2240
2241 emit_move_insn (exp, GEN_INT (0x21b00));
2242
2243 emit_insn (gen_negdi2 (nega, a));
2244
2245 emit_insn (gen_insn_cmplts_didi (sign, a, const0_rtx));
2246 emit_insn (gen_insn_cmovnez (abs, a, sign, nega));
2247
2248 emit_insn (gen_ashldi3 (tmp1, abs, GEN_INT (4)));
2249 emit_insn (gen_insn_bfins (tmp2, exp, sign, GEN_INT (20), GEN_INT (20)));
2250 emit_insn (gen_insn_fdouble_pack1 (tmp3, tmp1, tmp2));
2251 emit_insn (gen_insn_fdouble_pack2 (result, tmp3, tmp1, const0_rtx));
2252 DONE;
2253})
2254
2255(define_expand "floatunssidf2"
2256 [(set (match_operand:DF 0 "register_operand" "")
2257 (float:SI (match_operand:SI 1 "register_operand" "")))]
2258 ""
2259{
2260 rtx result = gen_lowpart (DImode, operands[0]);
2261 rtx a = gen_lowpart (DImode, operands[1]);
2262
2263 rtx exp = gen_reg_rtx (DImode);
2264 rtx tmp1 = gen_reg_rtx (DImode);
2265 rtx tmp2 = gen_reg_rtx (DImode);
2266
2267 emit_move_insn (exp, GEN_INT (0x21b00));
2268 emit_insn (gen_insn_bfins (tmp1, const0_rtx, a, GEN_INT (4), GEN_INT (35)));
2269 emit_insn (gen_insn_fdouble_pack1 (tmp2, tmp1, exp));
2270 emit_insn (gen_insn_fdouble_pack2 (result, tmp2, tmp1, const0_rtx));
2271 DONE;
2272})
2273
dd552284
WL
2274\f
2275;;
2276;; Multiplies
2277;;
2278
2279(define_insn "mulsi3"
2280 [(set (match_operand:SI 0 "register_operand" "=r")
2281 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rO")
2282 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
2283 ""
2284 "mulx\t%0, %r1, %r2"
2285 [(set_attr "type" "Y0_2cycle")])
2286
2287(define_insn "mulsidi3"
2288 [(set (match_operand:DI 0 "register_operand" "=r")
2289 (mult:DI (sign_extend:DI
2290 (match_operand:SI 1 "reg_or_0_operand" "%rO"))
2291 (sign_extend:DI
2292 (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
2293 ""
2294 "mul_ls_ls\t%0, %r1, %r2"
2295 [(set_attr "type" "Y0_2cycle")])
2296
2297(define_insn "umulsidi3"
2298 [(set (match_operand:DI 0 "register_operand" "=r")
2299 (mult:DI (zero_extend:DI
2300 (match_operand:SI 1 "reg_or_0_operand" "%rO"))
2301 (zero_extend:DI
2302 (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
2303 ""
2304 "mul_lu_lu\t%0, %r1, %r2"
2305 [(set_attr "type" "Y0_2cycle")])
2306
2307(define_expand "muldi3"
2308 [(set (match_operand:DI 0 "register_operand" "")
2309 (unspec:DI [(match_operand:DI 1 "nonmemory_operand" "")
2310 (match_operand:DI 2 "nonmemory_operand" "")]
2311 UNSPEC_INSN_MUL_HU_LU))
2312 (set (match_dup 0)
2313 (unspec:DI [(match_dup 0) (match_dup 2) (match_dup 1)]
2314 UNSPEC_INSN_MULA_HU_LU))
2315 (set (match_dup 0)
2316 (ashift:DI (match_dup 0) (const_int 32)))
2317 (set (match_dup 0)
2318 (unspec:DI [(match_dup 0) (match_dup 2) (match_dup 1)]
2319 UNSPEC_INSN_MULA_LU_LU))]
2320 ""
2321 {
2322 operands[1] = force_reg (DImode, operands[1]);
2323 operands[1] = make_safe_from (operands[1], operands[0]);
2324
2325 if (tilegx_expand_muldi (operands[0], operands[1], operands[2]))
2326 DONE;
2327 else
2328 {
2329 operands[2] = force_reg (DImode, operands[2]);
2330 operands[2] = make_safe_from (operands[2], operands[0]);
2331 }
2332 })
2333
2334(define_insn "usmulsidi3"
2335 [(set (match_operand:DI 0 "register_operand" "=r")
2336 (mult:DI (zero_extend:DI
2337 (match_operand:SI 1 "reg_or_0_operand" "rO"))
2338 (sign_extend:DI
2339 (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
2340 ""
2341 "mul_ls_lu\t%0, %r2, %r1"
2342 [(set_attr "type" "X0_2cycle")])
2343
2344(define_insn "maddsidi4"
2345 [(set (match_operand:DI 0 "register_operand" "=r")
2346 (plus:DI
2347 (mult:DI (sign_extend:DI
2348 (match_operand:SI 1 "reg_or_0_operand" "rO"))
2349 (sign_extend:DI
2350 (match_operand:SI 2 "reg_or_0_operand" "rO")))
2351 (match_operand:DI 3 "register_operand" "0")))]
2352 ""
2353 "mula_ls_ls\t%0, %r1, %r2"
2354 [(set_attr "type" "Y0_2cycle")])
2355
2356(define_insn "umaddsidi4"
2357 [(set (match_operand:DI 0 "register_operand" "=r")
2358 (plus:DI
2359 (mult:DI (zero_extend:DI
2360 (match_operand:SI 1 "reg_or_0_operand" "rO"))
2361 (zero_extend:DI
2362 (match_operand:SI 2 "reg_or_0_operand" "rO")))
2363 (match_operand:DI 3 "register_operand" "0")))]
2364 ""
2365 "mula_lu_lu\t%0, %r1, %r2"
2366 [(set_attr "type" "Y0_2cycle")])
2367
2368(define_expand "smulsi3_highpart"
2369 [(set (match_dup 3)
2370 (mult:DI (sign_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
2371 (sign_extend:DI (match_operand:SI 2 "reg_or_0_operand" ""))))
2372 (set (match_dup 4)
2373 (ashiftrt:DI (match_dup 3) (const_int 32)))
2374 (set (match_operand:SI 0 "register_operand" "")
2375 (truncate:SI (match_dup 4)))]
2376 ""
2377 {
2378 operands[3] = gen_reg_rtx (DImode);
2379 operands[4] = gen_reg_rtx (DImode);
2380 })
2381
2382(define_expand "umulsi3_highpart"
2383 [(set (match_dup 3)
2384 (mult:DI (zero_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
2385 (zero_extend:DI (match_operand:SI 2 "reg_or_0_operand" ""))))
2386 (set (match_dup 4)
2387 (lshiftrt:DI (match_dup 3) (const_int 32)))
2388 (set (match_operand:SI 0 "register_operand" "")
2389 (truncate:SI (match_dup 4)))]
2390 ""
2391 {
2392 operands[3] = gen_reg_rtx (DImode);
2393 operands[4] = gen_reg_rtx (DImode);
2394 })
2395
2396(define_expand "smuldi3_highpart"
2397 [(set (match_operand:DI 0 "register_operand" "")
2398 (truncate:DI
2399 (ashiftrt:TI
2400 (mult:TI (sign_extend:TI (match_operand:DI 1 "reg_or_0_operand" ""))
2401 (sign_extend:TI (match_operand:DI 2 "reg_or_0_operand" "")))
2402 (const_int 64))))]
2403 ""
2404 {
2405 tilegx_expand_smuldi3_highpart (operands[0], operands[1], operands[2]);
2406 DONE;
2407 })
2408
2409(define_expand "umuldi3_highpart"
2410 [(set (match_operand:DI 0 "register_operand" "")
2411 (truncate:DI
2412 (lshiftrt:TI
2413 (mult:TI (zero_extend:TI (match_operand:DI 1 "reg_or_0_operand" ""))
2414 (zero_extend:TI (match_operand:DI 2 "reg_or_0_operand" "")))
2415 (const_int 64))))]
2416 ""
2417{
2418 tilegx_expand_umuldi3_highpart (operands[0], operands[1], operands[2]);
2419 DONE;
2420})
2421
2422\f
2423;;
e53b6e56 2424;; Divide stubs. These exist to work around a bug in expmed.cc, which
dd552284
WL
2425;; will not attempt to convert a divide by constant into a multiply
2426;; unless there is a pattern for a divide of the same mode. The end
2427;; result is a 32-bit divide turns into 64-bit multiply.
2428;;
2429
2430(define_expand "divsi3"
2431 [(set (match_operand:SI 0 "register_operand" "")
2432 (div:SI (match_operand:SI 1 "reg_or_0_operand" "")
2433 (match_operand:SI 2 "reg_or_0_operand" "")))]
2434 ""
2435{
2436 FAIL;
2437})
2438
2439(define_expand "udivsi3"
2440 [(set (match_operand:SI 0 "register_operand" "")
2441 (udiv:SI (match_operand:SI 1 "reg_or_0_operand" "")
2442 (match_operand:SI 2 "reg_or_0_operand" "")))]
2443 ""
2444{
2445 FAIL;
2446})
2447
2448\f
2449;;
2450;; Loops
2451;;
2452
3aa775d6
WL
2453;; Define the subtract-one-and-jump insns so loop.c knows what to
2454;; generate.
dd552284
WL
2455(define_expand "doloop_end"
2456 [(use (match_operand 0 "" "")) ;; loop pseudo
1d0216c8 2457 (use (match_operand 1 "" ""))] ;; label
dd552284
WL
2458 ""
2459{
2460 if (optimize > 0 && flag_modulo_sched)
2461 {
2462 rtx s0;
2463 rtx bcomp;
2464 rtx loc_ref;
ef4bddc2 2465 machine_mode mode = GET_MODE (operands[0]);
dd552284 2466
dd552284
WL
2467 /* only deal with loop counters in SImode or DImode */
2468 if (mode != SImode && mode != DImode)
2469 FAIL;
2470
2471 s0 = operands [0];
2472 emit_move_insn (s0, gen_rtx_PLUS (mode, s0, GEN_INT (-1)));
2473 bcomp = gen_rtx_NE(mode, s0, const0_rtx);
1d0216c8 2474 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
f7df4a84 2475 emit_jump_insn (gen_rtx_SET (pc_rtx,
dd552284
WL
2476 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
2477 loc_ref, pc_rtx)));
2478 DONE;
2479 }
2480 else
2481 FAIL;
2482
2483})
2484
2485;;
2486;; Prologue/epilogue
2487;;
2488(define_expand "prologue"
2489 [(const_int 0)]
2490 ""
2491{
2492 tilegx_expand_prologue ();
2493 DONE;
2494})
2495
2496(define_expand "epilogue"
2497 [(const_int 0)]
2498 ""
2499{
2500 tilegx_expand_epilogue (false);
2501 DONE;
2502})
2503
2504(define_expand "sibcall_epilogue"
2505 [(const_int 0)]
2506 ""
2507{
2508 tilegx_expand_epilogue (true);
2509 DONE;
2510})
2511
2512;;
2513;; Stack manipulations
2514;;
2515
2516;; An insn to allocate new stack space for dynamic use (e.g., alloca).
2517(define_expand "allocate_stack"
2518 [(set (match_operand 0 "register_operand" "")
2519 (minus (reg 54) (match_operand 1 "nonmemory_operand" "")))
2520 (set (reg 54)
2521 (minus (reg 54) (match_dup 1)))]
2522 ""
2523 "tilegx_allocate_stack (operands[0], operands[1]); DONE;")
2524
2525;;
2526;; Branches
2527;;
2528
2529(define_expand "call"
2530 [(parallel [(call (match_operand:DI 0 "call_operand" "")
2531 (match_operand 1 "" ""))
2532 (use (reg:DI 54))
2533 (clobber (reg:DI 55))])]
2534 ""
1773cd77
WL
2535{
2536 rtx orig_addr = XEXP (operands[0], 0);
2537 rtx addr;
2538 if (GET_CODE (orig_addr) == SYMBOL_REF)
2539 {
2540 if (tilegx_cmodel == CM_LARGE)
2541 {
2542 addr = gen_reg_rtx (Pmode);
2543 tilegx_expand_set_const64 (addr, orig_addr);
2544 operands[0] = gen_rtx_MEM (DImode, addr);
2545 }
2546 else if (tilegx_cmodel == CM_LARGE_PIC)
2547 {
2548 crtl->uses_pic_offset_table = 1;
2549 addr = gen_reg_rtx (Pmode);
2550 if (SYMBOL_REF_LOCAL_P (orig_addr))
2551 tilegx_compute_pcrel_address (addr, orig_addr);
2552 else
2553 tilegx_compute_pcrel_plt_address (addr, orig_addr);
2554 operands[0] = gen_rtx_MEM (DImode, addr);
2555 }
2556 }
2557})
dd552284
WL
2558
2559(define_insn "*call_insn"
2560 [(call (mem:DI (match_operand:I48MODE 0 "call_address_operand" "rO,i"))
2561 (match_operand 1 "" ""))
2562 (use (reg:DI 54))
2563 (clobber (reg:DI 55))]
2564 ""
2565 "@
2566 jalr\t%r0
2567 jal\t%p0"
2568 [(set_attr "type" "Y1,X1")])
2569
2570(define_expand "call_value"
2571 [(parallel [(set (match_operand 0 "register_operand" "")
2572 (call (match_operand:DI 1 "call_operand" "")
2573 (match_operand 2 "" "")))
2574 (use (reg:DI 54))
2575 (clobber (reg:DI 55))])]
1773cd77
WL
2576 ""
2577{
2578 rtx orig_addr = XEXP (operands[1], 0);
2579 rtx addr;
2580 if (GET_CODE (orig_addr) == SYMBOL_REF)
2581 {
2582 if (tilegx_cmodel == CM_LARGE)
2583 {
2584 addr = gen_reg_rtx (Pmode);
2585 tilegx_expand_set_const64 (addr, orig_addr);
2586 operands[1] = gen_rtx_MEM (DImode, addr);
2587 }
2588 else if (tilegx_cmodel == CM_LARGE_PIC)
2589 {
2590 crtl->uses_pic_offset_table = 1;
2591 addr = gen_reg_rtx (Pmode);
2592 if (SYMBOL_REF_LOCAL_P (orig_addr))
2593 tilegx_compute_pcrel_address (addr, orig_addr);
2594 else
2595 tilegx_compute_pcrel_plt_address (addr, orig_addr);
2596 operands[1] = gen_rtx_MEM (DImode, addr);
2597 }
3aa775d6 2598 }
1773cd77 2599})
dd552284
WL
2600
2601(define_insn "*call_value_insn"
2602 [(set (match_operand 0 "register_operand" "=r,r")
2603 (call (mem:DI (match_operand:I48MODE 1 "call_address_operand" "rO,i"))
2604 (match_operand 2 "" "")))
2605 (use (reg:DI 54))
2606 (clobber (reg:DI 55))]
2607 ""
2608 "@
2609 jalr\t%r1
2610 jal\t%p1"
2611 [(set_attr "type" "Y1,X1")])
2612
2613(define_expand "sibcall"
2614 [(parallel [(call (match_operand:DI 0 "call_operand" "")
2615 (match_operand 1 "" ""))
2616 (use (reg:DI 54))])]
2617 ""
2618 "")
2619
2620(define_insn "*sibcall_insn"
2621 [(call (mem:DI (match_operand:I48MODE 0 "call_address_operand" "rO,i"))
2622 (match_operand 1 "" ""))
2623 (use (reg:DI 54))]
2624 "SIBLING_CALL_P(insn)"
2625 "@
2626 jr\t%r0
2627 j\t%p0"
bf60f4ca 2628 [(set_attr "type" "Y1,X1")])
dd552284
WL
2629
2630(define_expand "sibcall_value"
2631 [(parallel [(set (match_operand 0 "" "")
2632 (call (match_operand:DI 1 "call_operand" "")
2633 (match_operand 2 "" "")))
2634 (use (reg:DI 54))])]
2635 ""
2636 "")
2637
2638(define_insn "*sibcall_value"
2639 [(set (match_operand 0 "" "")
2640 (call (mem:DI (match_operand:I48MODE 1 "call_address_operand" "rO,i"))
2641 (match_operand 2 "" "")))
2642 (use (reg:DI 54))]
2643 "SIBLING_CALL_P(insn)"
2644 "@
2645 jr\t%r1
2646 j\t%p1"
bf60f4ca 2647 [(set_attr "type" "Y1,X1")])
dd552284
WL
2648
2649(define_insn "jump"
2650 [(set (pc) (label_ref (match_operand 0 "" "")))]
2651 ""
2652 "j\t%l0"
2653 [(set_attr "type" "X1")])
2654
2655(define_insn "indirect_jump"
2656 [(set (pc) (match_operand 0 "pointer_operand" "rO"))]
2657 ""
2658 "jr\t%r0"
2659 [(set_attr "type" "Y1")])
2660
2661(define_expand "return"
2662 [(parallel
2663 [(return)
2664 (use (reg:DI 55))])]
2665 "tilegx_can_use_return_insn_p ()"
2666 "")
2667
2668(define_insn "_return"
2669 [(return)
2670 (use (reg:DI 55))]
2671 "reload_completed"
2672 "jrp\tlr"
2673 [(set_attr "type" "Y1")])
2674
2675(define_expand "tablejump"
2676 [(set (pc) (match_operand 0 "pointer_operand" ""))
2677 (use (label_ref (match_operand 1 "" "")))]
2678 ""
2679{
2680 tilegx_expand_tablejump (operands[0], operands[1]);
2681 DONE;
2682})
2683
2684(define_insn "tablejump_aux"
2685 [(set (pc) (match_operand 0 "pointer_operand" "rO"))
2686 (use (label_ref (match_operand 1 "" "")))]
2687 ""
2688 "jr\t%r0"
2689 [(set_attr "type" "Y1")])
2690
2691;; Call subroutine returning any type.
2692(define_expand "untyped_call"
2693 [(parallel [(call (match_operand 0 "" "")
2694 (const_int 0))
2695 (match_operand 1 "" "")
2696 (match_operand 2 "" "")])]
2697 ""
2698{
2699 int i;
2700
58d745ec 2701 emit_call_insn (gen_call (operands[0], const0_rtx));
dd552284
WL
2702
2703 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2704 {
2705 rtx set = XVECEXP (operands[2], 0, i);
2706 emit_move_insn (SET_DEST (set), SET_SRC (set));
2707 }
2708
2709 /* The optimizer does not know that the call sets the function value
2710 registers we stored in the result block. We avoid problems by
2711 claiming that all hard registers are used and clobbered at this
2712 point. */
2713 emit_insn (gen_blockage ());
2714
2715 DONE;
2716})
2717
2718;; UNSPEC_VOLATILE is considered to use and clobber all hard registers
2719;; and all of memory. This blocks insns from being moved across this
2720;; point.
2721(define_insn "blockage"
2722 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
2723 ""
2724 "pseudo"
2725 [(set_attr "type" "nothing")
2726 (set_attr "length" "0")])
2727
2728;; Internal expanders to prevent memory ops from moving around frame
2729;; allocation/deallocation.
2730;;
2731;; TODO: really this clobber should just clobber the frame memory. Is
2732;; this possibly by clobbering memory @ the sp reg (as alpha does?)
2733;; or by explicitly setting the alias set to the frame?
2734(define_insn "sp_adjust"
2735 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
2736 (plus:DI
2737 (match_operand:DI 1 "register_operand" "%r,r,r")
2738 (match_operand:DI 2 "add_operand" "r,I,JT")))
2739 (clobber (mem:BLK (scratch)))]
2740 ""
2741 "@
2742 add\t%0, %1, %2
2743 addi\t%0, %1, %2
2744 addli\t%0, %1, %H2"
2745 [(set_attr "type" "*,*,X01")])
2746
2747(define_insn "sp_adjust_32bit"
2748 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2749 (plus:SI
2750 (match_operand:SI 1 "register_operand" "%r,r,r")
2751 (match_operand:SI 2 "add_operand" "r,I,JT")))
2752 (clobber (mem:BLK (scratch)))]
2753 ""
2754 "@
2755 addx\t%0, %1, %2
2756 addxi\t%0, %1, %2
2757 addxli\t%0, %1, %H2"
2758 [(set_attr "type" "*,*,X01")])
2759
2760;; Used for move sp, r52, to pop a stack frame. We need to make sure
3aa775d6
WL
2761;; that stack frame memory operations have been issued before we do
2762;; this. TODO: see above TODO.
dd552284
WL
2763(define_insn "sp_restore<bitsuffix>"
2764 [(set (match_operand:I48MODE 0 "register_operand" "=r")
2765 (match_operand:I48MODE 1 "register_operand" "r"))
2766 (clobber (mem:BLK (scratch)))]
2767 ""
2768 "move\t%0, %1")
2769
2770(define_insn "nop"
2771 [(const_int 0)]
2772 ""
2773 "nop"
2774 [(set_attr "type" "Y01")])
2775
90b9beed
WL
2776(define_insn "trap"
2777 [(trap_if (const_int 1) (const_int 0))]
2778 ""
2779 "raise; moveli zero, 6"
2780 [(set_attr "type" "cannot_bundle")])
2781
dd552284
WL
2782\f
2783;;
2784;; Conditional branches
2785;;
2786
2787(define_expand "cbranch<mode>4"
2788 [(set (pc)
2789 (if_then_else (match_operator 0 "ordered_comparison_operator"
2790 [(match_operand:FI48MODE 1 "reg_or_cint_operand")
2791 (match_operand:FI48MODE 2 "reg_or_cint_operand")])
2792 (label_ref (match_operand 3 ""))
2793 (pc)))]
2794 ""
2795{
2796 tilegx_emit_conditional_branch (operands, GET_MODE (operands[1]));
2797 DONE;
2798})
2799
2800(define_insn "*bcc_normal<mode>"
2801 [(set (pc)
2802 (if_then_else
2803 (match_operator 1 "signed_comparison_operator"
2804 [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
2805 (const_int 0)])
2806 (label_ref (match_operand 0 "" ""))
2807 (pc)))]
2808 ""
2809 { return tilegx_output_cbranch (insn, operands, false); }
2810 [(set_attr "type" "X1_branch")])
2811
2812(define_insn "*bcc_reverse<mode>"
2813 [(set (pc)
2814 (if_then_else
2815 (match_operator 1 "signed_comparison_operator"
2816 [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
2817 (const_int 0)])
2818 (pc)
2819 (label_ref (match_operand 0 "" ""))))]
2820 ""
2821 { return tilegx_output_cbranch (insn, operands, true); }
2822 [(set_attr "type" "X1_branch")])
2823
2824(define_insn "*blbs_normal<mode>"
2825 [(set (pc)
2826 (if_then_else
2827 (ne (zero_extract:I48MODE
2828 (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
2829 (const_int 1)
2830 (const_int 0))
2831 (const_int 0))
2832 (label_ref (match_operand 0 "" ""))
2833 (pc)))]
2834 ""
2835 { return tilegx_output_cbranch_with_opcode (insn, operands, "blbs", "blbc",
2836 1); }
2837 [(set_attr "type" "X1_branch")])
2838
2839(define_insn "*blbc_normal<mode>"
2840 [(set (pc)
2841 (if_then_else
2842 (eq (zero_extract:I48MODE
2843 (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
2844 (const_int 1)
2845 (const_int 0))
2846 (const_int 0))
2847 (label_ref (match_operand 0 "" ""))
2848 (pc)))]
2849 ""
2850 { return tilegx_output_cbranch_with_opcode (insn, operands, "blbc", "blbs",
2851 1); }
2852 [(set_attr "type" "X1_branch")])
2853
2854;; Note that __insn_mf() expands to this.
2855(define_expand "memory_barrier"
2856 [(set (match_dup 0)
2857 (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
2858 ""
2859{
2860 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
2861 MEM_VOLATILE_P (operands[0]) = 1;
2862})
2863
2864(define_insn "*memory_barrier"
2865 [(set (match_operand:BLK 0 "" "")
2866 (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
2867 ""
2868 "mf"
2869 [(set_attr "type" "X1")])
2870
2871(define_insn "prefetch"
2872 [(prefetch (match_operand 0 "address_operand" "rO")
2873 (match_operand 1 "const_int_operand" "")
2874 (match_operand 2 "const_int_operand" ""))]
2875 ""
2876{
2877 switch (INTVAL (operands[2]))
2878 {
2879 case 0:
2880 case 1: return "prefetch_l3\t%r0";
2881 case 2: return "prefetch_l2\t%r0";
2882 case 3: return "prefetch_l1\t%r0";
2883 default: gcc_unreachable ();
2884 }
2885}
2886 [(set_attr "type" "Y2")])
2887
2888\f
2889;;
2890;; "__insn" Intrinsics (some expand directly to normal patterns above).
2891;;
2892
2893(define_insn "insn_bfexts"
2894 [(set (match_operand:DI 0 "register_operand" "=r")
2895 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2896 (match_operand:DI 2 "u6bit_cint_operand" "n")
2897 (match_operand:DI 3 "u6bit_cint_operand" "n")]
2898 UNSPEC_INSN_BFEXTS))]
2899 ""
2900 "bfexts\t%0, %r1, %2, %3"
2901 [(set_attr "type" "X0")])
2902
2903(define_insn "insn_bfextu"
2904 [(set (match_operand:DI 0 "register_operand" "=r")
2905 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2906 (match_operand:DI 2 "u6bit_cint_operand" "n")
2907 (match_operand:DI 3 "u6bit_cint_operand" "n")]
2908 UNSPEC_INSN_BFEXTU))]
2909 ""
2910 "bfextu\t%0, %r1, %2, %3"
2911 [(set_attr "type" "X0")])
2912
848c312c 2913(define_insn "insn_bfins"
dd552284
WL
2914 [(set (match_operand:DI 0 "register_operand" "=r")
2915 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2916 (match_operand:DI 2 "reg_or_0_operand" "rO")
2917 (match_operand:DI 3 "u6bit_cint_operand" "n")
2918 (match_operand:DI 4 "u6bit_cint_operand" "n")]
2919 UNSPEC_INSN_BFINS))]
2920 ""
2921 "bfins\t%0, %r2, %3, %4"
2922 [(set_attr "type" "X0")])
2923
dd552284
WL
2924(define_insn "insn_cmpexch<four_if_si>"
2925 [(set (match_operand:I48MODE 0 "register_operand" "=r")
2926 (mem:I48MODE (match_operand 1 "pointer_operand" "rO")))
2927 (set (mem:I48MODE (match_dup 1))
2928 (unspec_volatile:I48MODE
2929 [(mem:I48MODE (match_dup 1))
2930 (reg:I48MODE TILEGX_CMPEXCH_REG)
2931 (match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
2932 UNSPEC_INSN_CMPEXCH))]
2933 ""
2934 "cmpexch<four_if_si>\t%0, %r1, %r2"
9b0370aa 2935 [(set_attr "type" "X1_remote")])
dd552284
WL
2936
2937(define_insn "insn_cmul"
2938 [(set (match_operand:DI 0 "register_operand" "=r")
2939 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2940 (match_operand:DI 2 "reg_or_0_operand" "rO")]
2941 UNSPEC_INSN_CMUL))]
2942 ""
2943 "cmul\t%0, %r1, %r2"
2944 [(set_attr "type" "X0_2cycle")])
2945
2946(define_insn "insn_cmula"
2947 [(set (match_operand:DI 0 "register_operand" "=r")
2948 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2949 (match_operand:DI 2 "reg_or_0_operand" "rO")
2950 (match_operand:DI 3 "reg_or_0_operand" "rO")]
2951 UNSPEC_INSN_CMULA))]
2952 ""
2953 "cmula\t%0, %r2, %r3"
2954 [(set_attr "type" "X0_2cycle")])
2955
2956(define_insn "insn_cmulaf"
2957 [(set (match_operand:DI 0 "register_operand" "=r")
2958 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2959 (match_operand:DI 2 "reg_or_0_operand" "rO")
2960 (match_operand:DI 3 "reg_or_0_operand" "rO")]
2961 UNSPEC_INSN_CMULAF))]
2962 ""
2963 "cmulaf\t%0, %r2, %r3"
2964 [(set_attr "type" "X0_2cycle")])
2965
2966(define_insn "insn_cmulf"
2967 [(set (match_operand:DI 0 "register_operand" "=r")
2968 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2969 (match_operand:DI 2 "reg_or_0_operand" "rO")]
2970 UNSPEC_INSN_CMULF))]
2971 ""
2972 "cmulf\t%0, %r1, %r2"
2973 [(set_attr "type" "X0_2cycle")])
2974
2975(define_insn "insn_cmulfr"
2976 [(set (match_operand:DI 0 "register_operand" "=r")
2977 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2978 (match_operand:DI 2 "reg_or_0_operand" "rO")]
2979 UNSPEC_INSN_CMULFR))]
2980 ""
2981 "cmulfr\t%0, %r1, %r2"
2982 [(set_attr "type" "X0_2cycle")])
2983
2984(define_insn "insn_cmulh"
2985 [(set (match_operand:DI 0 "register_operand" "=r")
2986 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2987 (match_operand:DI 2 "reg_or_0_operand" "rO")]
2988 UNSPEC_INSN_CMULH))]
2989 ""
2990 "cmulh\t%0, %r1, %r2"
2991 [(set_attr "type" "X0_2cycle")])
2992
2993(define_insn "insn_cmulhr"
2994 [(set (match_operand:DI 0 "register_operand" "=r")
2995 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2996 (match_operand:DI 2 "reg_or_0_operand" "rO")]
2997 UNSPEC_INSN_CMULHR))]
2998 ""
2999 "cmulhr\t%0, %r1, %r2"
3000 [(set_attr "type" "X0_2cycle")])
3001
3002(define_insn "insn_crc32_32"
3003 [(set (match_operand:DI 0 "register_operand" "=r")
3004 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3005 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3006 UNSPEC_INSN_CRC32_32))]
3007 ""
3008 "crc32_32\t%0, %r1, %r2"
3009 [(set_attr "type" "X0")])
3010
3011(define_insn "insn_crc32_8"
3012 [(set (match_operand:DI 0 "register_operand" "=r")
3013 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3014 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3015 UNSPEC_INSN_CRC32_8))]
3016 ""
3017 "crc32_8\t%0, %r1, %r2"
3018 [(set_attr "type" "X0")])
3019
3020(define_insn "insn_dblalign"
3021 [(set (match_operand:DI 0 "register_operand" "=r")
3022 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3023 (match_operand:DI 2 "reg_or_0_operand" "rO")
3024 (match_operand 3 "pointer_operand" "rO")]
3025 UNSPEC_INSN_DBLALIGN))]
3026 ""
3027 "dblalign\t%0, %r2, %r3"
3028 [(set_attr "type" "X0")])
3029
3030(define_insn "insn_dblalign2"
3031 [(set (match_operand:DI 0 "register_operand" "=r")
3032 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3033 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3034 UNSPEC_INSN_DBLALIGN2))]
3035 ""
3036 "dblalign2\t%0, %r1, %r2"
3037 [(set_attr "type" "X01")])
3038
3039(define_insn "insn_dblalign4"
3040 [(set (match_operand:DI 0 "register_operand" "=r")
3041 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3042 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3043 UNSPEC_INSN_DBLALIGN4))]
3044 ""
3045 "dblalign4\t%0, %r1, %r2"
3046 [(set_attr "type" "X01")])
3047
3048(define_insn "insn_dblalign6"
3049 [(set (match_operand:DI 0 "register_operand" "=r")
3050 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3051 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3052 UNSPEC_INSN_DBLALIGN6))]
3053 ""
3054 "dblalign6\t%0, %r1, %r2"
3055 [(set_attr "type" "X01")])
3056
3057(define_insn "insn_dtlbpr"
3058 [(unspec_volatile:VOID [(match_operand:DI 0 "reg_or_0_operand" "rO")]
3059 UNSPEC_INSN_DTLBPR)]
3060 ""
3061 "dtlbpr\t%r0"
3062 [(set_attr "type" "X1")])
3063
3064(define_insn "insn_exch<four_if_si>"
3065 [(set (match_operand:I48MODE 0 "register_operand" "=r")
3066 (mem:I48MODE (match_operand 1 "pointer_operand" "rO")))
3067 (set (mem:I48MODE (match_dup 1))
3068 (unspec_volatile:I48MODE
3069 [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
3070 UNSPEC_INSN_EXCH))]
3071 ""
3072 "exch<four_if_si>\t%0, %r1, %r2"
9b0370aa 3073 [(set_attr "type" "X1_remote")])
dd552284
WL
3074
3075(define_insn "insn_fdouble_add_flags"
3076 [(set (match_operand:DI 0 "register_operand" "=r")
3077 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3078 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3079 UNSPEC_INSN_FDOUBLE_ADD_FLAGS))]
3080 ""
3081 "fdouble_add_flags\t%0, %r1, %r2"
3082 [(set_attr "type" "X0_2cycle")])
3083
3084(define_insn "insn_fdouble_addsub"
3085 [(set (match_operand:DI 0 "register_operand" "=r")
3086 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3087 (match_operand:DI 2 "reg_or_0_operand" "rO")
3088 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3089 UNSPEC_INSN_FDOUBLE_ADDSUB))]
3090 ""
3091 "fdouble_addsub\t%0, %r2, %r3"
3092 [(set_attr "type" "X0_2cycle")])
3093
3094(define_insn "insn_fdouble_mul_flags"
3095 [(set (match_operand:DI 0 "register_operand" "=r")
3096 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3097 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3098 UNSPEC_INSN_FDOUBLE_MUL_FLAGS))]
3099 ""
3100 "fdouble_mul_flags\t%0, %r1, %r2"
3101 [(set_attr "type" "X0_2cycle")])
3102
3103(define_insn "insn_fdouble_pack1"
3104 [(set (match_operand:DI 0 "register_operand" "=r")
3105 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3106 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3107 UNSPEC_INSN_FDOUBLE_PACK1))]
3108 ""
3109 "fdouble_pack1\t%0, %r1, %r2"
3110 [(set_attr "type" "X0_2cycle")])
3111
3112(define_insn "insn_fdouble_pack2"
3113 [(set (match_operand:DI 0 "register_operand" "=r")
3114 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3115 (match_operand:DI 2 "reg_or_0_operand" "rO")
3116 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3117 UNSPEC_INSN_FDOUBLE_PACK2))]
3118 ""
3119 "fdouble_pack2\t%0, %r2, %r3"
3120 [(set_attr "type" "X0_2cycle")])
3121
3122(define_insn "insn_fdouble_sub_flags"
3123 [(set (match_operand:DI 0 "register_operand" "=r")
3124 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3125 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3126 UNSPEC_INSN_FDOUBLE_SUB_FLAGS))]
3127 ""
3128 "fdouble_sub_flags\t%0, %r1, %r2"
3129 [(set_attr "type" "X0_2cycle")])
3130
3131(define_insn "insn_fdouble_unpack_max"
3132 [(set (match_operand:DI 0 "register_operand" "=r")
3133 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3134 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3135 UNSPEC_INSN_FDOUBLE_UNPACK_MAX))]
3136 ""
3137 "fdouble_unpack_max\t%0, %r1, %r2"
3138 [(set_attr "type" "X0_2cycle")])
3139
3140(define_insn "insn_fdouble_unpack_min"
3141 [(set (match_operand:DI 0 "register_operand" "=r")
3142 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3143 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3144 UNSPEC_INSN_FDOUBLE_UNPACK_MIN))]
3145 ""
3146 "fdouble_unpack_min\t%0, %r1, %r2"
3147 [(set_attr "type" "X0_2cycle")])
3148
3149(define_insn "insn_fetchadd<four_if_si>"
3150 [(set (match_operand:I48MODE 0 "register_operand" "=r")
3151 (unspec_volatile:I48MODE
3152 [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3153 UNSPEC_ATOMIC))
3154 (set (mem:I48MODE (match_dup 1))
3155 (plus:I48MODE (mem:I48MODE (match_dup 1))
3156 (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
3157 ""
3158 "fetchadd<four_if_si>\t%0, %r1, %r2"
9b0370aa 3159 [(set_attr "type" "X1_remote")])
dd552284
WL
3160
3161(define_insn "insn_fetchaddgez<four_if_si>"
3162 [(set (match_operand:I48MODE 0 "register_operand" "=r")
3163 (unspec_volatile:I48MODE
3164 [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3165 UNSPEC_ATOMIC))
3166 (set (mem:I48MODE (match_dup 1))
3167 (unspec:I48MODE [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
3168 (mem:I48MODE (match_dup 1))]
3169 UNSPEC_INSN_FETCHADDGEZ))]
3170 ""
3171 "fetchaddgez<four_if_si>\t%0, %r1, %r2"
9b0370aa 3172 [(set_attr "type" "X1_remote")])
dd552284
WL
3173
3174(define_insn "insn_fetchand<four_if_si>"
3175 [(set (match_operand:I48MODE 0 "register_operand" "=r")
3176 (unspec_volatile:I48MODE
3177 [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3178 UNSPEC_ATOMIC))
3179 (set (mem:I48MODE (match_dup 1))
3180 (and:I48MODE (mem:I48MODE (match_dup 1))
3181 (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
3182 ""
3183 "fetchand<four_if_si>\t%0, %r1, %r2"
9b0370aa 3184 [(set_attr "type" "X1_remote")])
dd552284
WL
3185
3186(define_insn "insn_fetchor<four_if_si>"
3187 [(set (match_operand:I48MODE 0 "register_operand" "=r")
3188 (unspec_volatile:I48MODE
3189 [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3190 UNSPEC_ATOMIC))
3191 (set (mem:I48MODE (match_dup 1))
3192 (ior:I48MODE (mem:I48MODE (match_dup 1))
3193 (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
3194 ""
3195 "fetchor<four_if_si>\t%0, %r1, %r2"
9b0370aa 3196 [(set_attr "type" "X1_remote")])
dd552284
WL
3197
3198(define_insn "insn_finv"
3199 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3200 UNSPEC_INSN_FINV)]
3201 ""
3202 "finv\t%r0"
3203 [(set_attr "type" "X1")])
3204
3205(define_insn "insn_flush"
3206 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3207 UNSPEC_INSN_FLUSH)]
3208 ""
3209 "flush\t%r0"
3210 [(set_attr "type" "X1")])
3211
3212(define_insn "insn_flushwb"
3213 [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FLUSHWB)]
3214 ""
3215 "flushwb"
3216 [(set_attr "type" "X1")])
3217
3218(define_insn "insn_fnop"
3219 [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FNOP)]
3220 ""
3221 "fnop")
3222
3223(define_insn "insn_fsingle_add1"
3224 [(set (match_operand:DI 0 "register_operand" "=r")
3225 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3226 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3227 UNSPEC_INSN_FSINGLE_ADD1))]
3228 ""
3229 "fsingle_add1\t%0, %r1, %r2"
3230 [(set_attr "type" "X0")])
3231
3232(define_insn "insn_fsingle_addsub2"
3233 [(set (match_operand:DI 0 "register_operand" "=r")
3234 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3235 (match_operand:DI 2 "reg_or_0_operand" "rO")
3236 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3237 UNSPEC_INSN_FSINGLE_ADDSUB2))]
3238 ""
3239 "fsingle_addsub2\t%0, %r2, %r3"
3240 [(set_attr "type" "X0_2cycle")])
3241
3242(define_insn "insn_fsingle_mul1"
3243 [(set (match_operand:DI 0 "register_operand" "=r")
3244 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3245 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3246 UNSPEC_INSN_FSINGLE_MUL1))]
3247 ""
3248 "fsingle_mul1\t%0, %r1, %r2"
3249 [(set_attr "type" "X0")])
3250
3251(define_insn "insn_fsingle_mul2"
3252 [(set (match_operand:DI 0 "register_operand" "=r")
3253 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3254 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3255 UNSPEC_INSN_FSINGLE_MUL2))]
3256 ""
3257 "fsingle_mul2\t%0, %r1, %r2"
3258 [(set_attr "type" "X0_2cycle")])
3259
3260(define_insn "insn_fsingle_pack1"
3261 [(set (match_operand:DI 0 "register_operand" "=r")
3262 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")]
3263 UNSPEC_INSN_FSINGLE_PACK1))]
3264 ""
3265 "fsingle_pack1\t%0, %r1"
3266 [(set_attr "type" "Y0_2cycle")])
3267
3268(define_insn "insn_fsingle_pack2"
3269 [(set (match_operand:DI 0 "register_operand" "=r")
3270 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3271 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3272 UNSPEC_INSN_FSINGLE_PACK2))]
3273 ""
3274 "fsingle_pack2\t%0, %r1, %r2"
3275 [(set_attr "type" "X0_2cycle")])
3276
3277(define_insn "insn_fsingle_sub1"
3278 [(set (match_operand:DI 0 "register_operand" "=r")
3279 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3280 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3281 UNSPEC_INSN_FSINGLE_SUB1))]
3282 ""
3283 "fsingle_sub1\t%0, %r1, %r2"
3284 [(set_attr "type" "X0")])
3285
3286(define_insn "insn_drain"
3287 [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_DRAIN)]
3288 ""
3289 "drain"
3290 [(set_attr "type" "cannot_bundle")])
3291
3292(define_insn "insn_icoh"
3293 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3294 UNSPEC_INSN_ICOH)]
3295 ""
3296 "icoh\t%r0"
3297 [(set_attr "type" "X1")])
3298
3299(define_insn "insn_ill"
3300 [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_ILL)]
3301 ""
3302 "ill"
3303 [(set_attr "type" "cannot_bundle")])
3304
3305(define_insn "insn_info"
3306 [(unspec_volatile:VOID [(match_operand:DI 0 "s8bit_cint_operand" "i")]
3307 UNSPEC_INSN_INFO)]
3308 ""
3309 "info\t%0")
3310
3311(define_insn "insn_infol"
3312 [(unspec_volatile:VOID [(match_operand:DI 0 "s16bit_cint_operand" "i")]
3313 UNSPEC_INSN_INFOL)]
3314 ""
3315 "infol\t%0"
3316 [(set_attr "type" "X01")])
3317
3318(define_insn "insn_inv"
3319 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3320 UNSPEC_INSN_INV)]
3321 ""
3322 "inv\t%r0"
3323 [(set_attr "type" "X1")])
3324
3325;; loads
3326
3327(define_expand "insn_ld"
3328 [(set (match_operand:DI 0 "register_operand" "")
3329 (mem:DI (match_operand 1 "pointer_operand" "")))]
3330 "")
3331
3332(define_insn "insn_ld_add<bitsuffix>"
1a79721f
RS
3333 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3334 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3335 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3336 (set (match_operand:DI 0 "register_operand" "=r")
3337 (mem:DI (match_dup 3)))]
3338 ""
3339 "ld_add\t%0, %1, %2"
3340 [(set_attr "type" "X1_2cycle")])
3341
3342(define_insn "insn_ldna"
3343 [(set (match_operand:DI 0 "register_operand" "=r")
3344 (mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
3345 (const_int -8))))]
3346 ""
3347 "ldna\t%0, %r1"
3348 [(set_attr "type" "X1_2cycle")])
3349
3350(define_insn "insn_ldna_add<bitsuffix>"
1a79721f
RS
3351 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3352 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3353 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3354 (set (match_operand:DI 0 "register_operand" "=r")
3355 (mem:DI (and:DI (match_dup 3) (const_int -8))))]
3356 ""
3357 "ldna_add\t%0, %1, %2"
3358 [(set_attr "type" "X1_2cycle")])
3359
3360(define_expand "insn_ld<n><s>"
3361 [(set (match_operand:DI 0 "register_operand" "")
3362 (any_extend:DI
3363 (mem:I124MODE (match_operand 1 "pointer_operand" ""))))]
3364 "")
3365
3366(define_insn "insn_ld<I124MODE:n><s>_add<I48MODE:bitsuffix>"
1a79721f
RS
3367 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3368 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3369 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3370 (set (match_operand:DI 0 "register_operand" "=r")
3371 (any_extend:DI (mem:I124MODE (match_dup 3))))]
3372 ""
3373 "ld<I124MODE:n><s>_add\t%0, %1, %2"
3374 [(set_attr "type" "X1_2cycle")])
3375
3376;; non temporal loads
3377
3378(define_insn "insn_ldnt"
3379 [(set (match_operand:DI 0 "register_operand" "=r")
3380 (unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3381 UNSPEC_NON_TEMPORAL))]
3382 ""
3383 "ldnt\t%0, %r1"
3384 [(set_attr "type" "X1_2cycle")])
3385
3386(define_insn "insn_ldnt_add<bitsuffix>"
1a79721f
RS
3387 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3388 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3389 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3390 (set (match_operand:DI 0 "register_operand" "=r")
3391 (unspec:DI [(mem:DI (match_dup 3))]
3392 UNSPEC_NON_TEMPORAL))]
3393 ""
3394 "ldnt_add\t%0, %1, %2"
3395 [(set_attr "type" "X1_2cycle")])
3396
3397(define_insn "insn_ldnt<n><s>"
3398 [(set (match_operand:DI 0 "register_operand" "=r")
3399 (any_extend:DI
3400 (unspec:I124MODE
3401 [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3402 UNSPEC_NON_TEMPORAL)))]
3403 ""
3404 "ldnt<n><s>\t%0, %r1"
3405 [(set_attr "type" "X1_2cycle")])
3406
3407(define_insn "insn_ldnt<I124MODE:n><s>_add<I48MODE:bitsuffix>"
1a79721f
RS
3408 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3409 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3410 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3411 (set (match_operand:DI 0 "register_operand" "=r")
3412 (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
3413 UNSPEC_NON_TEMPORAL)))]
3414 ""
3415 "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
3416 [(set_attr "type" "X1_2cycle")])
3417
3418;; L2 hits
3419
3420(define_insn "insn_ld_L2"
3421 [(set (match_operand:DI 0 "register_operand" "=r")
3422 (unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3423 UNSPEC_LATENCY_L2))]
3424 ""
3425 "ld\t%0, %r1"
3426 [(set_attr "type" "Y2_L2")])
3427
3428(define_insn "insn_ld_add_L2<bitsuffix>"
1a79721f
RS
3429 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3430 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3431 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3432 (set (match_operand:DI 0 "register_operand" "=r")
3433 (unspec:DI [(mem:DI (match_dup 3))]
3434 UNSPEC_LATENCY_L2))]
3435 ""
3436 "ld_add\t%0, %1, %2"
3437 [(set_attr "type" "X1_L2")])
3438
3439(define_insn "insn_ldna_L2"
3440 [(set (match_operand:DI 0 "register_operand" "=r")
3441 (unspec:DI [(mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
3442 (const_int -8)))]
3443 UNSPEC_LATENCY_L2))]
3444 ""
3445 "ldna\t%0, %r1"
3446 [(set_attr "type" "X1_L2")])
3447
3448(define_insn "insn_ldna_add_L2<bitsuffix>"
1a79721f
RS
3449 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3450 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3451 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3452 (set (match_operand:DI 0 "register_operand" "=r")
3453 (unspec:DI [(mem:DI (and:DI (match_dup 3) (const_int -8)))]
3454 UNSPEC_LATENCY_L2))]
3455 ""
3456 "ldna_add\t%0, %1, %2"
3457 [(set_attr "type" "X1_L2")])
3458
3459(define_insn "insn_ld<n><s>_L2"
3460 [(set (match_operand:DI 0 "register_operand" "=r")
3461 (any_extend:DI
3462 (unspec:I124MODE
3463 [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3464 UNSPEC_LATENCY_L2)))]
3465 ""
3466 "ld<n><s>\t%0, %r1"
3467 [(set_attr "type" "Y2_L2")])
3468
3469(define_insn "insn_ld<I124MODE:n><s>_add_L2<I48MODE:bitsuffix>"
1a79721f
RS
3470 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3471 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3472 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3473 (set (match_operand:DI 0 "register_operand" "=r")
3474 (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
3475 UNSPEC_LATENCY_L2)))]
3476 ""
3477 "ld<I124MODE:n><s>_add\t%0, %1, %2"
3478 [(set_attr "type" "X1_L2")])
3479
3480;; L2 hits, non temporal loads
3481
3482(define_insn "insn_ldnt_L2"
3483 [(set (match_operand:DI 0 "register_operand" "=r")
3484 (unspec:DI [(unspec:DI
3485 [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3486 UNSPEC_NON_TEMPORAL)]
3487 UNSPEC_LATENCY_L2))]
3488 ""
3489 "ldnt\t%0, %r1"
3490 [(set_attr "type" "X1_L2")])
3491
3492(define_insn "insn_ldnt_add_L2<bitsuffix>"
1a79721f
RS
3493 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3494 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3495 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3496 (set (match_operand:DI 0 "register_operand" "=r")
3497 (unspec:DI [(unspec:DI
3498 [(mem:DI (match_dup 3))]
3499 UNSPEC_NON_TEMPORAL)]
3500 UNSPEC_LATENCY_L2))]
3501 ""
3502 "ldnt_add\t%0, %1, %2"
3503 [(set_attr "type" "X1_L2")])
3504
3505(define_insn "insn_ldnt<n><s>_L2"
3506 [(set (match_operand:DI 0 "register_operand" "=r")
3507 (any_extend:DI
3508 (unspec:I124MODE
3509 [(unspec:I124MODE
3510 [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3511 UNSPEC_NON_TEMPORAL)]
3512 UNSPEC_LATENCY_L2)))]
3513 ""
3514 "ldnt<n><s>\t%0, %r1"
3515 [(set_attr "type" "X1_L2")])
3516
3517(define_insn "insn_ldnt<I124MODE:n><s>_add_L2<I48MODE:bitsuffix>"
1a79721f
RS
3518 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3519 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3520 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3521 (set (match_operand:DI 0 "register_operand" "=r")
3522 (any_extend:DI
3523 (unspec:I124MODE [(unspec:I124MODE
3524 [(mem:I124MODE (match_dup 3))]
3525 UNSPEC_NON_TEMPORAL)]
3526 UNSPEC_LATENCY_L2)))]
3527 ""
3528 "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
3529 [(set_attr "type" "X1_L2")])
3530
3531;; L2 miss
3532
3533(define_insn "insn_ld_miss"
3534 [(set (match_operand:DI 0 "register_operand" "=r")
3535 (unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3536 UNSPEC_LATENCY_MISS))]
3537 ""
3538 "ld\t%0, %r1"
3539 [(set_attr "type" "Y2_miss")])
3540
3541(define_insn "insn_ld_add_miss<bitsuffix>"
1a79721f
RS
3542 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3543 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3544 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3545 (set (match_operand:DI 0 "register_operand" "=r")
3546 (unspec:DI [(mem:DI (match_dup 3))]
3547 UNSPEC_LATENCY_MISS))]
3548 ""
3549 "ld_add\t%0, %1, %2"
3550 [(set_attr "type" "X1_miss")])
3551
3552(define_insn "insn_ldna_miss"
3553 [(set (match_operand:DI 0 "register_operand" "=r")
3554 (unspec:DI [(mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
3555 (const_int -8)))]
3556 UNSPEC_LATENCY_MISS))]
3557 ""
3558 "ldna\t%0, %r1"
3559 [(set_attr "type" "X1_miss")])
3560
3561(define_insn "insn_ldna_add_miss<bitsuffix>"
1a79721f
RS
3562 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3563 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3564 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3565 (set (match_operand:DI 0 "register_operand" "=r")
3566 (unspec:DI [(mem:DI (and:DI (match_dup 3) (const_int -8)))]
3567 UNSPEC_LATENCY_MISS))]
3568 ""
3569 "ldna_add\t%0, %1, %2"
3570 [(set_attr "type" "X1_miss")])
3571
3572(define_insn "insn_ld<n><s>_miss"
3573 [(set (match_operand:DI 0 "register_operand" "=r")
3574 (any_extend:DI
3575 (unspec:I124MODE
3576 [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3577 UNSPEC_LATENCY_MISS)))]
3578 ""
3579 "ld<n><s>\t%0, %r1"
3580 [(set_attr "type" "Y2_miss")])
3581
3582(define_insn "insn_ld<I124MODE:n><s>_add_miss<I48MODE:bitsuffix>"
1a79721f
RS
3583 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3584 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3585 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3586 (set (match_operand:DI 0 "register_operand" "=r")
3587 (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
3588 UNSPEC_LATENCY_MISS)))]
3589 ""
3590 "ld<I124MODE:n><s>_add\t%0, %1, %2"
3591 [(set_attr "type" "X1_miss")])
3592
3593;; L2 miss, non temporal loads
3594
3595(define_insn "insn_ldnt_miss"
3596 [(set (match_operand:DI 0 "register_operand" "=r")
3597 (unspec:DI [(unspec:DI
3598 [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3599 UNSPEC_NON_TEMPORAL)]
3600 UNSPEC_LATENCY_MISS))]
3601 ""
3602 "ldnt\t%0, %r1"
3603 [(set_attr "type" "X1_miss")])
3604
3605(define_insn "insn_ldnt_add_miss<bitsuffix>"
1a79721f
RS
3606 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3607 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3608 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3609 (set (match_operand:DI 0 "register_operand" "=r")
3610 (unspec:DI [(unspec:DI
3611 [(mem:DI (match_dup 3))]
3612 UNSPEC_NON_TEMPORAL)]
3613 UNSPEC_LATENCY_MISS))]
3614 ""
3615 "ldnt_add\t%0, %1, %2"
3616 [(set_attr "type" "X1_miss")])
3617
3618(define_insn "insn_ldnt<n><s>_miss"
3619 [(set (match_operand:DI 0 "register_operand" "=r")
3620 (any_extend:DI
3621 (unspec:I124MODE
3622 [(unspec:I124MODE
3623 [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3624 UNSPEC_NON_TEMPORAL)]
3625 UNSPEC_LATENCY_MISS)))]
3626 ""
3627 "ldnt<n><s>\t%0, %r1"
3628 [(set_attr "type" "X1_miss")])
3629
3630(define_insn "insn_ldnt<I124MODE:n><s>_add_miss<I48MODE:bitsuffix>"
1a79721f
RS
3631 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3632 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3633 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
3634 (set (match_operand:DI 0 "register_operand" "=r")
3635 (any_extend:DI
3636 (unspec:I124MODE [(unspec:I124MODE
3637 [(mem:I124MODE (match_dup 3))]
3638 UNSPEC_NON_TEMPORAL)]
3639 UNSPEC_LATENCY_MISS)))]
3640 ""
3641 "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
3642 [(set_attr "type" "X1_miss")])
3643
3644;; end loads
3645
3646(define_insn "insn_lnk"
3647 [(set (match_operand:DI 0 "register_operand" "=r")
3648 (unspec:DI [(const_int 0)] UNSPEC_INSN_LNK))]
3649 ""
3650 "lnk\t%0"
3651 [(set_attr "type" "Y1")])
3652
3653(define_insn "insn_mfspr"
3654 [(set (match_operand:DI 0 "register_operand" "=r")
3655 (unspec_volatile:DI [(match_operand:DI 1 "u14bit_cint_operand" "i")]
3656 UNSPEC_INSN_MFSPR))
3657 (clobber (mem:BLK (const_int 0)))]
3658 ""
3659 "mfspr\t%0, %1"
3660 [(set_attr "type" "X1")])
3661
3662(define_insn "insn_mtspr"
3663 [(unspec_volatile:DI [(match_operand:DI 0 "u14bit_cint_operand" "i")
3664 (match_operand:DI 1 "reg_or_0_operand" "rO")]
3665 UNSPEC_INSN_MTSPR)
3666 (clobber (mem:BLK (const_int 0)))]
3667 ""
3668 "mtspr\t%0, %r1"
3669 [(set_attr "type" "X1")])
3670
3671(define_insn "insn_mm"
3672 [(set (match_operand:DI 0 "register_operand" "=r")
3673 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3674 (match_operand:DI 2 "reg_or_0_operand" "rO")
3675 (match_operand:DI 3 "u6bit_cint_operand" "i")
3676 (match_operand:DI 4 "u6bit_cint_operand" "i")]
3677 UNSPEC_INSN_MM))]
3678 ""
3679 "mm\t%0, %r2, %3, %4"
3680 [(set_attr "type" "X0")])
3681
3682(define_insn "insn_mul_hs_hs"
3683 [(set (match_operand:DI 0 "register_operand" "=r")
3684 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3685 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3686 UNSPEC_INSN_MUL_HS_HS))]
3687 ""
3688 "mul_hs_hs\t%0, %r1, %r2"
3689 [(set_attr "type" "Y0_2cycle")])
3690
3691(define_insn "insn_mul_hs_hu"
3692 [(set (match_operand:DI 0 "register_operand" "=r")
3693 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3694 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3695 UNSPEC_INSN_MUL_HS_HU))]
3696 ""
3697 "mul_hs_hu\t%0, %r1, %r2"
3698 [(set_attr "type" "X0_2cycle")])
3699
3700(define_insn "insn_mul_hs_ls"
3701 [(set (match_operand:DI 0 "register_operand" "=r")
3702 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3703 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3704 UNSPEC_INSN_MUL_HS_LS))]
3705 ""
3706 "mul_hs_ls\t%0, %r1, %r2"
3707 [(set_attr "type" "X0_2cycle")])
3708
3709(define_insn "insn_mul_hs_lu"
3710 [(set (match_operand:DI 0 "register_operand" "=r")
3711 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3712 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3713 UNSPEC_INSN_MUL_HS_LU))]
3714 ""
3715 "mul_hs_lu\t%0, %r1, %r2"
3716 [(set_attr "type" "X0_2cycle")])
3717
3718(define_insn "insn_mul_hu_hu"
3719 [(set (match_operand:DI 0 "register_operand" "=r")
3720 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3721 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3722 UNSPEC_INSN_MUL_HU_HU))]
3723 ""
3724 "mul_hu_hu\t%0, %r1, %r2"
3725 [(set_attr "type" "Y0_2cycle")])
3726
3727(define_insn "insn_mul_hu_ls"
3728 [(set (match_operand:DI 0 "register_operand" "=r")
3729 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3730 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3731 UNSPEC_INSN_MUL_HU_LS))]
3732 ""
3733 "mul_hu_ls\t%0, %r1, %r2"
3734 [(set_attr "type" "X0_2cycle")])
3735
3736(define_insn "insn_mul_hu_lu"
3737 [(set (match_operand:DI 0 "register_operand" "=r")
3738 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3739 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3740 UNSPEC_INSN_MUL_HU_LU))]
3741 ""
3742 "mul_hu_lu\t%0, %r1, %r2"
3743 [(set_attr "type" "X0_2cycle")])
3744
3745(define_insn "insn_mul_ls_ls"
3746 [(set (match_operand:DI 0 "register_operand" "=r")
3747 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3748 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3749 UNSPEC_INSN_MUL_LS_LS))]
3750 ""
3751 "mul_ls_ls\t%0, %r1, %r2"
3752 [(set_attr "type" "Y0_2cycle")])
3753
3754(define_insn "insn_mul_ls_lu"
3755 [(set (match_operand:DI 0 "register_operand" "=r")
3756 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3757 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3758 UNSPEC_INSN_MUL_LS_LU))]
3759 ""
3760 "mul_ls_lu\t%0, %r1, %r2"
3761 [(set_attr "type" "X0_2cycle")])
3762
3763(define_insn "insn_mul_lu_lu"
3764 [(set (match_operand:DI 0 "register_operand" "=r")
3765 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3766 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3767 UNSPEC_INSN_MUL_LU_LU))]
3768 ""
3769 "mul_lu_lu\t%0, %r1, %r2"
3770 [(set_attr "type" "Y0_2cycle")])
3771
3772(define_insn "insn_mula_hs_hs"
3773 [(set (match_operand:DI 0 "register_operand" "=r")
3774 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3775 (match_operand:DI 2 "reg_or_0_operand" "rO")
3776 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3777 UNSPEC_INSN_MULA_HS_HS))]
3778 ""
3779 "mula_hs_hs\t%0, %r2, %r3"
3780 [(set_attr "type" "Y0_2cycle")])
3781
3782(define_insn "insn_mula_hs_hu"
3783 [(set (match_operand:DI 0 "register_operand" "=r")
3784 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3785 (match_operand:DI 2 "reg_or_0_operand" "rO")
3786 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3787 UNSPEC_INSN_MULA_HS_HU))]
3788 ""
3789 "mula_hs_hu\t%0, %r2, %r3"
3790 [(set_attr "type" "X0_2cycle")])
3791
3792(define_insn "insn_mula_hs_ls"
3793 [(set (match_operand:DI 0 "register_operand" "=r")
3794 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3795 (match_operand:DI 2 "reg_or_0_operand" "rO")
3796 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3797 UNSPEC_INSN_MULA_HS_LS))]
3798 ""
3799 "mula_hs_ls\t%0, %r2, %r3"
3800 [(set_attr "type" "X0_2cycle")])
3801
3802(define_insn "insn_mula_hs_lu"
3803 [(set (match_operand:DI 0 "register_operand" "=r")
3804 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3805 (match_operand:DI 2 "reg_or_0_operand" "rO")
3806 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3807 UNSPEC_INSN_MULA_HS_LU))]
3808 ""
3809 "mula_hs_lu\t%0, %r2, %r3"
3810 [(set_attr "type" "X0_2cycle")])
3811
3812(define_insn "insn_mula_hu_hu"
3813 [(set (match_operand:DI 0 "register_operand" "=r")
3814 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3815 (match_operand:DI 2 "reg_or_0_operand" "rO")
3816 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3817 UNSPEC_INSN_MULA_HU_HU))]
3818 ""
3819 "mula_hu_hu\t%0, %r2, %r3"
3820 [(set_attr "type" "Y0_2cycle")])
3821
3822(define_insn "insn_mula_hu_ls"
3823 [(set (match_operand:DI 0 "register_operand" "=r")
3824 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3825 (match_operand:DI 2 "reg_or_0_operand" "rO")
3826 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3827 UNSPEC_INSN_MULA_HU_LS))]
3828 ""
3829 "mula_hu_ls\t%0, %r2, %r3"
3830 [(set_attr "type" "X0_2cycle")])
3831
3832(define_insn "insn_mula_hu_lu"
3833 [(set (match_operand:DI 0 "register_operand" "=r")
3834 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3835 (match_operand:DI 2 "reg_or_0_operand" "rO")
3836 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3837 UNSPEC_INSN_MULA_HU_LU))]
3838 ""
3839 "mula_hu_lu\t%0, %r2, %r3"
3840 [(set_attr "type" "X0_2cycle")])
3841
3842(define_insn "insn_mula_ls_ls"
3843 [(set (match_operand:DI 0 "register_operand" "=r")
3844 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3845 (match_operand:DI 2 "reg_or_0_operand" "rO")
3846 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3847 UNSPEC_INSN_MULA_LS_LS))]
3848 ""
3849 "mula_ls_ls\t%0, %r2, %r3"
3850 [(set_attr "type" "Y0_2cycle")])
3851
3852(define_insn "insn_mula_ls_lu"
3853 [(set (match_operand:DI 0 "register_operand" "=r")
3854 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3855 (match_operand:DI 2 "reg_or_0_operand" "rO")
3856 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3857 UNSPEC_INSN_MULA_LS_LU))]
3858 ""
3859 "mula_ls_lu\t%0, %r2, %r3"
3860 [(set_attr "type" "X0_2cycle")])
3861
3862(define_insn "insn_mula_lu_lu"
3863 [(set (match_operand:DI 0 "register_operand" "=r")
3864 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3865 (match_operand:DI 2 "reg_or_0_operand" "rO")
3866 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3867 UNSPEC_INSN_MULA_LU_LU))]
3868 ""
3869 "mula_lu_lu\t%0, %r2, %r3"
3870 [(set_attr "type" "Y0_2cycle")])
3871
3872(define_insn "insn_mulax"
3873 [(set (match_operand:SI 0 "register_operand" "=r")
3874 (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3875 (match_operand:SI 2 "reg_or_0_operand" "rO")
3876 (match_operand:SI 3 "reg_or_0_operand" "rO")]
3877 UNSPEC_INSN_MULAX))]
3878 ""
3879 "mulax\t%0, %r2, %r3"
3880 [(set_attr "type" "Y0_2cycle")])
3881
3882(define_insn "insn_nap"
3883 [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_NAP)]
3884 ""
3885 "nap"
3886 [(set_attr "type" "cannot_bundle")])
3887
3888(define_insn "insn_nor_<mode>"
3889 [(set (match_operand:I48MODE 0 "register_operand" "=r")
3890 (and:I48MODE
3891 (not:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO"))
3892 (not:I48MODE (match_operand:I48MODE 2 "reg_or_0_operand" "rO"))))]
3893 ""
3894 "nor\t%0, %r1, %r2")
3895
3896(define_expand "insn_prefetch_l1"
3897 [(prefetch (match_operand 0 "pointer_operand" "")
3898 (const_int 0)
3899 (const_int 3))]
3900 "")
3901
3902(define_expand "insn_prefetch_l2"
3903 [(prefetch (match_operand 0 "pointer_operand" "")
3904 (const_int 0)
3905 (const_int 2))]
3906 "")
3907
3908(define_expand "insn_prefetch_l3"
3909 [(prefetch (match_operand 0 "pointer_operand" "")
3910 (const_int 0)
3911 (const_int 1))]
3912 "")
3913
3914(define_insn "insn_prefetch_l1_fault"
3915 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3916 UNSPEC_INSN_PREFETCH_L1_FAULT)]
3917 ""
3918 "prefetch_l1_fault\t%r0"
3919 [(set_attr "type" "Y2")])
3920
3921(define_insn "insn_prefetch_l2_fault"
3922 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3923 UNSPEC_INSN_PREFETCH_L2_FAULT)]
3924 ""
3925 "prefetch_l2_fault\t%r0"
3926 [(set_attr "type" "Y2")])
3927
3928(define_insn "insn_prefetch_l3_fault"
3929 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3930 UNSPEC_INSN_PREFETCH_L3_FAULT)]
3931 ""
3932 "prefetch_l3_fault\t%r0"
3933 [(set_attr "type" "Y2")])
3934
3935(define_insn "insn_revbits"
3936 [(set (match_operand:DI 0 "register_operand" "=r")
3937 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")]
3938 UNSPEC_INSN_REVBITS))]
3939 ""
3940 "revbits\t%0, %r1"
3941 [(set_attr "type" "Y0")])
3942
3943(define_insn "insn_shl1add"
3944 [(set (match_operand:DI 0 "register_operand" "=r")
3945 (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
3946 (const_int 2))
3947 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
3948 ""
3949 "shl1add\t%0, %r1, %r2")
3950
3951(define_insn "insn_shl1addx"
3952 [(set (match_operand:SI 0 "register_operand" "=r")
3953 (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
3954 (const_int 2))
3955 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
3956 ""
3957 "shl1addx\t%0, %r1, %r2")
3958
3959(define_insn "insn_shl2add"
3960 [(set (match_operand:DI 0 "register_operand" "=r")
3961 (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
3962 (const_int 4))
3963 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
3964 ""
3965 "shl2add\t%0, %r1, %r2")
3966
3967(define_insn "insn_shl2addx"
3968 [(set (match_operand:SI 0 "register_operand" "=r")
3969 (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
3970 (const_int 4))
3971 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
3972 ""
3973 "shl2addx\t%0, %r1, %r2")
3974
3975(define_insn "insn_shl3add"
3976 [(set (match_operand:DI 0 "register_operand" "=r")
3977 (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
3978 (const_int 8))
3979 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
3980 ""
3981 "shl3add\t%0, %r1, %r2")
3982
3983(define_insn "insn_shl3addx"
3984 [(set (match_operand:SI 0 "register_operand" "=r")
3985 (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
3986 (const_int 8))
3987 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
3988 ""
3989 "shl3addx\t%0, %r1, %r2")
3990
3991(define_insn "insn_shufflebytes"
3992 [(set (match_operand:DI 0 "register_operand" "=r")
3993 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3994 (match_operand:DI 2 "reg_or_0_operand" "rO")
3995 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3996 UNSPEC_INSN_SHUFFLEBYTES))]
3997 ""
3998 "shufflebytes\t%0, %r2, %r3"
3999 [(set_attr "type" "X0")])
0051d3ec
WL
4000
4001(define_insn "insn_shufflebytes1"
4002 [(set (match_operand:DI 0 "register_operand" "=r")
4003 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
4004 (match_operand:DI 2 "reg_or_0_operand" "rO")]
4005 UNSPEC_INSN_SHUFFLEBYTES))]
4006 ""
4007 "shufflebytes\t%0, %r1, %r2"
4008 [(set_attr "type" "X0")])
dd552284
WL
4009
4010;; stores
4011
4012(define_expand "insn_st"
4013 [(set (mem:DI (match_operand 0 "pointer_operand" ""))
4014 (match_operand:DI 1 "reg_or_0_operand" ""))]
4015 "")
4016
4017(define_insn "insn_st_add<bitsuffix>"
1a79721f
RS
4018 [(set (match_operand:I48MODE 0 "register_operand" "=r")
4019 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4020 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
4021 (set (mem:DI (match_dup 3))
4022 (match_operand:DI 1 "reg_or_0_operand" "rO"))]
4023 ""
4024 "st_add\t%0, %r1, %2"
4025 [(set_attr "type" "X1")])
4026
4027(define_expand "insn_st<n>"
4028 [(set (mem:I124MODE (match_operand 0 "pointer_operand" ""))
4029 (match_operand:DI 1 "reg_or_0_operand" ""))]
4030 ""
4031{
341c653c
WL
4032 operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], DImode,
4033 BYTES_BIG_ENDIAN
4034 ? UNITS_PER_WORD - <n> : 0);
dd552284
WL
4035})
4036
4037(define_expand "insn_st<I124MODE:n>_add<I48MODE:bitsuffix>"
4038 [(parallel
1a79721f
RS
4039 [(set (match_operand:I48MODE 0 "register_operand" "")
4040 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "")
4041 (match_operand:I48MODE 2 "s8bit_cint_operand" "")))
dd552284
WL
4042 (set (mem:I124MODE (match_dup 3))
4043 (match_operand:DI 1 "reg_or_0_operand" ""))])]
4044 ""
4045{
4046 operands[1] = simplify_gen_subreg (<I124MODE:MODE>mode, operands[1],
341c653c
WL
4047 DImode,
4048 BYTES_BIG_ENDIAN
4049 ? UNITS_PER_WORD - <I124MODE:n> : 0);
dd552284
WL
4050})
4051
4052(define_insn "*insn_st<I124MODE:n>_add<I48MODE:bitsuffix>"
1a79721f
RS
4053 [(set (match_operand:I48MODE 0 "register_operand" "=r")
4054 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4055 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
4056 (set (mem:I124MODE (match_dup 3))
4057 (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
4058 ""
4059 "st<I124MODE:n>_add\t%0, %r1, %2"
4060 [(set_attr "type" "X1")])
4061
4062;; non-temporal stores
4063
4064(define_insn "insn_stnt"
4065 [(set (mem:DI (unspec [(match_operand 0 "pointer_operand" "rO")]
4066 UNSPEC_NON_TEMPORAL))
4067 (match_operand:DI 1 "reg_or_0_operand" "rO"))]
4068 ""
4069 "stnt\t%0, %r1"
4070 [(set_attr "type" "X1")])
4071
4072(define_insn "insn_stnt_add<bitsuffix>"
1a79721f
RS
4073 [(set (match_operand:I48MODE 0 "register_operand" "=r")
4074 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4075 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
4076 (set (mem:DI (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
4077 (match_operand:DI 1 "reg_or_0_operand" "rO"))]
4078 ""
4079 "stnt_add\t%0, %r1, %2"
4080 [(set_attr "type" "X1")])
4081
4082(define_expand "insn_stnt<n>"
4083 [(set (mem:I124MODE (unspec [(match_operand 0 "pointer_operand" "")]
4084 UNSPEC_NON_TEMPORAL))
4085 (match_operand:DI 1 "reg_or_0_operand" ""))]
4086 ""
4087{
341c653c
WL
4088 operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], DImode,
4089 BYTES_BIG_ENDIAN
4090 ? UNITS_PER_WORD - <n> : 0);
dd552284
WL
4091})
4092
4093(define_insn "*insn_stnt<n>"
4094 [(set (mem:I124MODE (unspec [(match_operand 0 "pointer_operand" "rO")]
4095 UNSPEC_NON_TEMPORAL))
4096 (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
4097 ""
4098 "stnt<n>\t%0, %r1"
4099 [(set_attr "type" "X1")])
4100
4101(define_expand "insn_stnt<I124MODE:n>_add<I48MODE:bitsuffix>"
4102 [(parallel
1a79721f
RS
4103 [(set (match_operand:I48MODE 0 "register_operand" "")
4104 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "")
4105 (match_operand:I48MODE 2 "s8bit_cint_operand" "")))
dd552284
WL
4106 (set (mem:I124MODE (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
4107 (match_operand:DI 1 "reg_or_0_operand" "rO"))])]
4108 ""
4109{
4110 operands[1] = simplify_gen_subreg (<I124MODE:MODE>mode, operands[1],
341c653c
WL
4111 DImode,
4112 BYTES_BIG_ENDIAN
dcbf228e 4113 ? UNITS_PER_WORD - <I124MODE:n> : 0);
dd552284
WL
4114})
4115
4116(define_insn "*insn_stnt<I124MODE:n>_add<I48MODE:bitsuffix>"
1a79721f
RS
4117 [(set (match_operand:I48MODE 0 "register_operand" "=r")
4118 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4119 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
dd552284
WL
4120 (set (mem:I124MODE (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
4121 (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
4122 ""
4123 "stnt<I124MODE:n>_add\t%0, %r1, %2"
4124 [(set_attr "type" "X1")])
4125
4126;; end stores
4127
4128(define_insn "insn_tblidxb0"
4129 [(set (match_operand:DI 0 "register_operand" "=r")
4130 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4131 (match_operand:DI 2 "reg_or_0_operand" "rO")]
4132 UNSPEC_INSN_TBLIDXB0))]
4133 ""
4134 "tblidxb0\t%0, %r2"
4135 [(set_attr "type" "Y0")])
4136
4137(define_insn "insn_tblidxb1"
4138 [(set (match_operand:DI 0 "register_operand" "=r")
4139 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4140 (match_operand:DI 2 "reg_or_0_operand" "rO")]
4141 UNSPEC_INSN_TBLIDXB1))]
4142 ""
4143 "tblidxb1\t%0, %r2"
4144 [(set_attr "type" "Y0")])
4145
4146(define_insn "insn_tblidxb2"
4147 [(set (match_operand:DI 0 "register_operand" "=r")
4148 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4149 (match_operand:DI 2 "reg_or_0_operand" "rO")]
4150 UNSPEC_INSN_TBLIDXB2))]
4151 ""
4152 "tblidxb2\t%0, %r2"
4153 [(set_attr "type" "Y0")])
4154
4155(define_insn "insn_tblidxb3"
4156 [(set (match_operand:DI 0 "register_operand" "=r")
4157 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4158 (match_operand:DI 2 "reg_or_0_operand" "rO")]
4159 UNSPEC_INSN_TBLIDXB3))]
4160 ""
4161 "tblidxb3\t%0, %r2"
4162 [(set_attr "type" "Y0")])
4163
4164;; insn_v1add
4165;; insn_v1addi
4166;; insn_v1cmpeq
4167;; insn_v1cmpeqi
4168;; insn_v1cmplts
4169;; insn_v1cmpltsi
4170;; insn_v1cmpltu
4171;; insn_v1cmpltui
4172;; insn_v1maxu
4173;; insn_v1maxui
4174;; insn_v1minu
4175;; insn_v1minui
4176(define_insn "<optab>v8qi3"
4177 [(set (match_operand:V8QI 0 "register_operand" "=r,r")
4178 (v1op_immed:V8QI
4179 (match_operand:V8QI 1 "reg_or_0_operand" "<comm>rO,rO")
4180 (match_operand:V8QI 2 "reg_or_v8s8bit_operand" "W,rO")))]
4181 ""
4182 "@
4183 v1<insn>i\t%0, %r1, %j2
4184 v1<insn>\t%0, %r1, %r2"
4185 [(set_attr "type" "<pipe>,<pipe>")])
4186
4187(define_expand "insn_v1<insn>"
4188 [(set (match_operand:DI 0 "register_operand" "")
4189 (v1op_immed:V8QI
4190 (match_operand:DI 1 "reg_or_0_operand" "")
4191 (match_operand:DI 2 "reg_or_0_operand" "")))]
4192 ""
4193{
4194 tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4195 V8QImode, operands[1], operands[2], true);
4196 DONE;
4197})
4198
4199(define_expand "insn_v1<insn>i"
4200 [(set (match_operand:DI 0 "register_operand" "")
4201 (v1op_immed:V8QI
4202 (match_operand:DI 1 "reg_or_0_operand" "")
4203 (match_operand:DI 2 "s8bit_cint_operand" "")))]
4204 ""
4205{
4206 /* Tile out immediate and expand to general case. */
4207 rtx n = tilegx_simd_int (operands[2], QImode);
4208 tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4209 V8QImode, operands[1], n, true);
4210 DONE;
4211})
4212
4213;; insn_v1shl
4214;; insn_v1shli
4215;; insn_v1shrs
4216;; insn_v1shrsi
4217;; insn_v1shru
4218;; insn_v1shrui
4219(define_insn "<optab>v8qi3"
4220 [(set (match_operand:V8QI 0 "register_operand" "=r,r")
4221 (any_shift:V8QI
4222 (match_operand:V8QI 1 "reg_or_0_operand" "rO,rO")
4223 (match_operand:DI 2 "reg_or_u5bit_operand" "I,rO")))]
4224 ""
4225 "@
4226 v1<insn>i\t%0, %r1, %2
4227 v1<insn>\t%0, %r1, %r2"
4228 [(set_attr "type" "<pipe>,<pipe>")])
4229
4230(define_expand "insn_v1<insn>"
4231 [(set (match_operand:DI 0 "register_operand" "")
4232 (any_shift:V8QI
4233 (match_operand:DI 1 "reg_or_0_operand" "")
4234 (match_operand:DI 2 "reg_or_u5bit_operand" "")))]
4235 ""
4236{
4237 tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4238 V8QImode, operands[1], operands[2], false);
4239 DONE;
4240})
4241
4242;; insn_v2add
4243;; insn_v2addi
4244;; insn_v2maxs
4245;; insn_v2maxsi
4246;; insn_v2mins
4247;; insn_v2minsi
4248;; insn_v2cmpeq
4249;; insn_v2cmpeqi
4250;; insn_v2cmplts
4251;; insn_v2cmpltsi
4252;; insn_v2cmpltu
4253;; insn_v2cmpltui
4254(define_insn "<optab>v4hi3"
4255 [(set (match_operand:V4HI 0 "register_operand" "=r,r")
4256 (v2op_immed:V4HI
4257 (match_operand:V4HI 1 "reg_or_0_operand" "<comm>rO,rO")
4258 (match_operand:V4HI 2 "reg_or_v4s8bit_operand" "Y,rO")))]
4259 ""
4260 "@
4261 v2<insn>i\t%0, %r1, %j2
4262 v2<insn>\t%0, %r1, %r2"
4263 [(set_attr "type" "<pipe>,<pipe>")])
4264
4265(define_expand "insn_v2<insn>"
4266 [(set (match_operand:DI 0 "register_operand" "")
4267 (v2op_immed:V4HI
4268 (match_operand:DI 1 "reg_or_0_operand" "")
4269 (match_operand:DI 2 "reg_or_0_operand" "")))]
4270 ""
4271{
4272 tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4273 V4HImode, operands[1], operands[2], true);
4274 DONE;
4275})
4276
4277(define_expand "insn_v2<insn>i"
4278 [(set (match_operand:DI 0 "register_operand" "")
4279 (v2op_immed:V4HI
4280 (match_operand:DI 1 "reg_or_0_operand" "")
4281 (match_operand:DI 2 "s8bit_cint_operand" "")))]
4282 ""
4283{
4284 /* Tile out immediate and expand to general case. */
4285 rtx n = tilegx_simd_int (operands[2], HImode);
4286 tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4287 V4HImode, operands[1], n, true);
4288 DONE;
4289})
4290
4291;; insn_v2shl
4292;; insn_v2shli
4293;; insn_v2shrs
4294;; insn_v2shrsi
4295;; insn_v2shru
4296;; insn_v2shrui
4297(define_insn "<optab>v4hi3"
4298 [(set (match_operand:V4HI 0 "register_operand" "=r,r")
4299 (any_shift:V4HI
4300 (match_operand:V4HI 1 "reg_or_0_operand" "rO,rO")
4301 (match_operand:DI 2 "reg_or_u5bit_operand" "I,rO")))]
4302 ""
4303 "@
4304 v2<insn>i\t%0, %r1, %2
4305 v2<insn>\t%0, %r1, %r2"
4306 [(set_attr "type" "<pipe>,<pipe>")])
4307
4308(define_expand "insn_v2<insn>"
4309 [(set (match_operand:DI 0 "register_operand" "")
4310 (any_shift:V4HI
4311 (match_operand:DI 1 "reg_or_0_operand" "")
4312 (match_operand:DI 2 "reg_or_u5bit_operand" "")))]
4313 ""
4314{
4315 tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4316 V4HImode, operands[1], operands[2], false);
4317 DONE;
4318})
4319
4320;; insn_v1adduc
4321;; insn_v1subuc
4322;; insn_v1sub
4323;; insn_v1cmpne
4324;; insn_v1cmples
4325;; insn_v1cmpleu
4326;; insn_v1multu
4327(define_insn "<optab>v8qi3"
4328 [(set (match_operand:V8QI 0 "register_operand" "=r")
4329 (v1op:V8QI
4330 (match_operand:V8QI 1 "reg_or_0_operand" "<comm>rO")
4331 (match_operand:V8QI 2 "reg_or_0_operand" "rO")))]
4332 ""
4333 "v1<insn>\t%0, %r1, %r2"
4334 [(set_attr "type" "<pipe>")])
4335
4336(define_expand "insn_v1<insn>"
4337 [(set (match_operand:DI 0 "register_operand" "")
4338 (v1op:V8QI
4339 (match_operand:DI 1 "reg_or_0_operand" "")
4340 (match_operand:DI 2 "reg_or_0_operand" "")))]
4341 ""
4342{
4343 tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4344 V8QImode, operands[1], operands[2], true);
4345 DONE;
4346})
4347
4348;; insn_v2addsc
4349;; insn_v2subsc
4350;; insn_v2sub
4351;; insn_v2cmpne
4352;; insn_v2cmples
4353;; insn_v2cmpleu
4354(define_insn "<optab>v4hi3"
4355 [(set (match_operand:V4HI 0 "register_operand" "=r")
4356 (v2op:V4HI
4357 (match_operand:V4HI 1 "reg_or_0_operand" "<comm>rO")
4358 (match_operand:V4HI 2 "reg_or_0_operand" "rO")))]
4359 ""
4360 "v2<insn>\t%0, %r1, %r2"
4361 [(set_attr "type" "<pipe>")])
4362
4363(define_expand "insn_v2<insn>"
4364 [(set (match_operand:DI 0 "register_operand" "")
4365 (v2op:V4HI
4366 (match_operand:DI 1 "reg_or_0_operand" "")
4367 (match_operand:DI 2 "reg_or_0_operand" "")))]
4368 ""
4369{
4370 tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4371 V4HImode, operands[1], operands[2], true);
4372 DONE;
4373})
4374
4375;; insn_v2mults
4376(define_insn "mulv4hi3"
4377 [(set (match_operand:V4HI 0 "register_operand" "=r")
4378 (mult:V4HI
4379 (match_operand:V4HI 1 "reg_or_0_operand" "%rO")
4380 (match_operand:V4HI 2 "reg_or_0_operand" "rO")))]
4381 ""
4382 "v2mults\t%0, %r1, %r2"
4383 [(set_attr "type" "X0_2cycle")])
4384
4385(define_expand "insn_v2mults"
4386 [(set (match_operand:DI 0 "register_operand" "")
4387 (mult:V4HI
4388 (match_operand:DI 1 "reg_or_0_operand" "")
4389 (match_operand:DI 2 "reg_or_0_operand" "")))]
4390 ""
4391{
4392 tilegx_expand_builtin_vector_binop (gen_mulv4hi3, V4HImode, operands[0],
4393 V4HImode, operands[1], operands[2], true);
4394 DONE;
4395})
4396
4397;; insn_v2shlsc
4398(define_insn "<optab>v4hi3"
4399 [(set (match_operand:V4HI 0 "register_operand" "=r")
4400 (v2shift:V4HI
4401 (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4402 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
4403 ""
4404 "v2<insn>\t%0, %r1, %r2"
4405 [(set_attr "type" "<pipe>")])
4406
4407(define_expand "insn_v2<insn>"
4408 [(set (match_operand:DI 0 "register_operand" "")
4409 (v2shift:V4HI
4410 (match_operand:DI 1 "reg_or_0_operand" "")
4411 (match_operand:DI 2 "reg_or_0_operand" "")))]
4412 ""
4413{
4414 tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4415 V4HImode, operands[1], operands[2], false);
4416 DONE;
4417})
4418
4419;; insn_v4addsc
4420;; insn_v4subsc
4421;; insn_v4add
4422;; insn_v4sub
4423(define_insn "<optab>v2si3"
4424 [(set (match_operand:V2SI 0 "register_operand" "=r")
4425 (v4op:V2SI
4426 (match_operand:V2SI 1 "reg_or_0_operand" "<comm>rO")
4427 (match_operand:V2SI 2 "reg_or_0_operand" "rO")))]
4428 ""
4429 "v4<insn>\t%0, %r1, %r2"
4430 [(set_attr "type" "<pipe>")])
4431
4432(define_expand "insn_v4<insn>"
4433 [(set (match_operand:DI 0 "register_operand" "")
4434 (v4op:V2SI
4435 (match_operand:DI 1 "reg_or_0_operand" "")
4436 (match_operand:DI 2 "reg_or_0_operand" "")))]
4437 ""
4438{
4439 tilegx_expand_builtin_vector_binop (gen_<optab>v2si3, V2SImode, operands[0],
4440 V2SImode, operands[1], operands[2], true);
4441 DONE;
4442})
4443
4444;; insn_v4shl
4445;; insn_v4shrs
4446;; insn_v4shru
4447;; insn_v4shlsc
4448(define_insn "<optab>v2si3"
4449 [(set (match_operand:V2SI 0 "register_operand" "=r")
4450 (v4shift:V2SI
4451 (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4452 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
4453 ""
4454 "v4<insn>\t%0, %r1, %r2"
4455 [(set_attr "type" "<pipe>")])
4456
4457(define_expand "insn_v4<insn>"
4458 [(set (match_operand:DI 0 "register_operand" "")
4459 (v4shift:V2SI
4460 (match_operand:DI 1 "reg_or_0_operand" "")
4461 (match_operand:DI 2 "reg_or_0_operand" "")))]
4462 ""
4463{
4464 tilegx_expand_builtin_vector_binop (gen_<optab>v2si3, V2SImode, operands[0],
4465 V2SImode, operands[1], operands[2], false);
4466 DONE;
4467})
4468
341c653c
WL
4469;; Byte ordering of these vectors is endian dependent. gcc concats
4470;; right-to-left for little endian, and left-to-right for big endian.
4471;; So we need different patterns that depend on endianness. Our
4472;; instructions concat and interleave the way a big-endian target would
4473;; work in gcc, so for little endian, we need to reverse the source
4474;; operands.
4475
dd552284
WL
4476;; insn_v1int_h
4477;; {B7,B6,B5,B4,B3,B2,B1,B0} {A7,A6,A5,A4,A3,A2,A1,A0}
4478;; => {A7,A6,A5,A4,A3,A2,A1,A0,B7,B6,B5,B4,B3,B2,B1,B0}
4479;; => {A7,B7,A6,B6,A5,B5,A4,B4}
341c653c
WL
4480(define_expand "vec_interleave_highv8qi"
4481 [(match_operand:V8QI 0 "register_operand" "")
4482 (match_operand:V8QI 1 "reg_or_0_operand" "")
4483 (match_operand:V8QI 2 "reg_or_0_operand" "")]
4484 ""
4485{
4486 if (BYTES_BIG_ENDIAN)
4487 emit_insn (gen_vec_interleave_highv8qi_be (operands[0], operands[1],
4488 operands[2]));
4489 else
4490 emit_insn (gen_vec_interleave_highv8qi_le (operands[0], operands[1],
4491 operands[2]));
4492 DONE;
4493})
4494
4495(define_insn "vec_interleave_highv8qi_be"
4496 [(set (match_operand:V8QI 0 "register_operand" "=r")
4497 (vec_select:V8QI
4498 (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4499 (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4500 (parallel [(const_int 0) (const_int 8)
4501 (const_int 1) (const_int 9)
4502 (const_int 2) (const_int 10)
4503 (const_int 3) (const_int 11)])))]
4504 "BYTES_BIG_ENDIAN"
4505 "v1int_h\t%0, %r1, %r2"
4506 [(set_attr "type" "X01")])
4507
4508(define_insn "vec_interleave_highv8qi_le"
dd552284
WL
4509 [(set (match_operand:V8QI 0 "register_operand" "=r")
4510 (vec_select:V8QI
4511 (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4512 (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4513 (parallel [(const_int 4) (const_int 12)
4514 (const_int 5) (const_int 13)
4515 (const_int 6) (const_int 14)
4516 (const_int 7) (const_int 15)])))]
341c653c 4517 "!BYTES_BIG_ENDIAN"
dd552284
WL
4518 "v1int_h\t%0, %r2, %r1"
4519 [(set_attr "type" "X01")])
4520
4521(define_expand "insn_v1int_h"
4522 [(match_operand:DI 0 "register_operand" "")
4523 (match_operand:DI 1 "reg_or_0_operand" "")
4524 (match_operand:DI 2 "reg_or_0_operand" "")]
4525 ""
4526{
341c653c
WL
4527 /* For little endian, our instruction interleaves opposite of the
4528 way vec_interleave works, so we need to reverse the source
4529 operands. */
4530 rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4531 rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
dd552284 4532 tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv8qi, V8QImode,
341c653c
WL
4533 operands[0], V8QImode, opnd1, opnd2,
4534 true);
dd552284
WL
4535 DONE;
4536})
4537
4538;; insn_v1int_l
4539;; {B7,B6,B5,B4,B3,B2,B1,B0} {A7,A6,A5,A4,A3,A2,A1,A0}
4540;; => {A7,A6,A5,A4,A3,A2,A1,A0,B7,B6,B5,B4,B3,B2,B1,B0}
4541;; => {A3,B3,A2,B2,A1,B1,A0,B0}
341c653c
WL
4542(define_expand "vec_interleave_lowv8qi"
4543 [(match_operand:V8QI 0 "register_operand" "")
4544 (match_operand:V8QI 1 "reg_or_0_operand" "")
4545 (match_operand:V8QI 2 "reg_or_0_operand" "")]
4546 ""
4547{
4548 if (BYTES_BIG_ENDIAN)
4549 emit_insn (gen_vec_interleave_lowv8qi_be (operands[0], operands[1],
4550 operands[2]));
4551 else
4552 emit_insn (gen_vec_interleave_lowv8qi_le (operands[0], operands[1],
4553 operands[2]));
4554 DONE;
4555})
4556
4557(define_insn "vec_interleave_lowv8qi_be"
4558 [(set (match_operand:V8QI 0 "register_operand" "=r")
4559 (vec_select:V8QI
4560 (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4561 (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4562 (parallel [(const_int 4) (const_int 12)
4563 (const_int 5) (const_int 13)
4564 (const_int 6) (const_int 14)
4565 (const_int 7) (const_int 15)])))]
4566 "BYTES_BIG_ENDIAN"
4567 "v1int_l\t%0, %r1, %r2"
4568 [(set_attr "type" "X01")])
4569
4570(define_insn "vec_interleave_lowv8qi_le"
dd552284
WL
4571 [(set (match_operand:V8QI 0 "register_operand" "=r")
4572 (vec_select:V8QI
4573 (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4574 (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4575 (parallel [(const_int 0) (const_int 8)
4576 (const_int 1) (const_int 9)
4577 (const_int 2) (const_int 10)
4578 (const_int 3) (const_int 11)])))]
341c653c 4579 "!BYTES_BIG_ENDIAN"
dd552284
WL
4580 "v1int_l\t%0, %r2, %r1"
4581 [(set_attr "type" "X01")])
4582
4583(define_expand "insn_v1int_l"
4584 [(match_operand:DI 0 "register_operand" "")
4585 (match_operand:DI 1 "reg_or_0_operand" "")
4586 (match_operand:DI 2 "reg_or_0_operand" "")]
4587 ""
4588{
341c653c
WL
4589 /* For little endian, our instruction interleaves opposite of the
4590 way vec_interleave works, so we need to reverse the source
4591 operands. */
4592 rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4593 rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
dd552284 4594 tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv8qi, V8QImode,
341c653c
WL
4595 operands[0], V8QImode, opnd1, opnd2,
4596 true);
dd552284
WL
4597 DONE;
4598})
4599
4600;; insn_v2int_h
4601;; {B3,B2,B1,B0} {A3,A2,A1,A0}
4602;; => {A3,A2,A1,A0,B3,B2,B1,B0}
4603;; => {A3,B3,A2,B2}
341c653c
WL
4604(define_expand "vec_interleave_highv4hi"
4605 [(match_operand:V4HI 0 "register_operand" "")
4606 (match_operand:V4HI 1 "reg_or_0_operand" "")
4607 (match_operand:V4HI 2 "reg_or_0_operand" "")]
4608 ""
4609{
4610 if (BYTES_BIG_ENDIAN)
4611 emit_insn (gen_vec_interleave_highv4hi_be (operands[0], operands[1],
4612 operands[2]));
4613 else
4614 emit_insn (gen_vec_interleave_highv4hi_le (operands[0], operands[1],
4615 operands[2]));
4616 DONE;
4617})
4618
4619(define_insn "vec_interleave_highv4hi_be"
4620 [(set (match_operand:V4HI 0 "register_operand" "=r")
4621 (vec_select:V4HI
4622 (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4623 (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4624 (parallel [(const_int 0) (const_int 4)
4625 (const_int 1) (const_int 5)])))]
4626 "BYTES_BIG_ENDIAN"
4627 "v2int_h\t%0, %r1, %r2"
4628 [(set_attr "type" "X01")])
4629
4630(define_insn "vec_interleave_highv4hi_le"
dd552284
WL
4631 [(set (match_operand:V4HI 0 "register_operand" "=r")
4632 (vec_select:V4HI
4633 (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4634 (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4635 (parallel [(const_int 2) (const_int 6)
4636 (const_int 3) (const_int 7)])))]
341c653c 4637 "!BYTES_BIG_ENDIAN"
dd552284
WL
4638 "v2int_h\t%0, %r2, %r1"
4639 [(set_attr "type" "X01")])
4640
4641(define_expand "insn_v2int_h"
4642 [(match_operand:DI 0 "register_operand" "")
4643 (match_operand:DI 1 "reg_or_0_operand" "")
4644 (match_operand:DI 2 "reg_or_0_operand" "")]
4645 ""
4646{
341c653c
WL
4647 /* For little endian, our instruction interleaves opposite of the
4648 way vec_interleave works, so we need to reverse the source
4649 operands. */
4650 rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4651 rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
dd552284 4652 tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv4hi, V4HImode,
341c653c
WL
4653 operands[0], V4HImode, opnd1, opnd2,
4654 true);
dd552284
WL
4655 DONE;
4656})
4657
4658;; insn_v2int_l
4659;; {B3,B2,B1,B0} {A3,A2,A1,A0}
4660;; => {A3,A2,A1,A0,B3,B2,B1,B0}
4661;; => {A1,B1,A0,B0}
341c653c
WL
4662(define_expand "vec_interleave_lowv4hi"
4663 [(match_operand:V4HI 0 "register_operand" "")
4664 (match_operand:V4HI 1 "reg_or_0_operand" "")
4665 (match_operand:V4HI 2 "reg_or_0_operand" "")]
4666 ""
4667{
4668 if (BYTES_BIG_ENDIAN)
4669 emit_insn (gen_vec_interleave_lowv4hi_be (operands[0], operands[1],
4670 operands[2]));
4671 else
4672 emit_insn (gen_vec_interleave_lowv4hi_le (operands[0], operands[1],
4673 operands[2]));
4674 DONE;
4675})
4676
4677(define_insn "vec_interleave_lowv4hi_be"
4678 [(set (match_operand:V4HI 0 "register_operand" "=r")
4679 (vec_select:V4HI
4680 (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4681 (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4682 (parallel [(const_int 2) (const_int 6)
4683 (const_int 3) (const_int 7)])))]
4684 "BYTES_BIG_ENDIAN"
4685 "v2int_l\t%0, %r1, %r2"
4686 [(set_attr "type" "X01")])
4687
4688(define_insn "vec_interleave_lowv4hi_le"
dd552284
WL
4689 [(set (match_operand:V4HI 0 "register_operand" "=r")
4690 (vec_select:V4HI
4691 (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4692 (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4693 (parallel [(const_int 0) (const_int 4)
4694 (const_int 1) (const_int 5)])))]
341c653c 4695 "!BYTES_BIG_ENDIAN"
dd552284
WL
4696 "v2int_l\t%0, %r2, %r1"
4697 [(set_attr "type" "X01")])
4698
4699(define_expand "insn_v2int_l"
4700 [(match_operand:DI 0 "register_operand" "")
4701 (match_operand:DI 1 "reg_or_0_operand" "")
4702 (match_operand:DI 2 "reg_or_0_operand" "")]
4703 ""
4704{
341c653c
WL
4705 /* For little endian, our instruction interleaves opposite of the
4706 way vec_interleave works, so we need to reverse the source
4707 operands. */
4708 rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4709 rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
dd552284 4710 tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv4hi, V4HImode,
341c653c
WL
4711 operands[0], V4HImode, opnd1, opnd2,
4712 true);
dd552284
WL
4713 DONE;
4714})
4715
4716;; insn_v4int_h
4717;; {B1,B0} {A1,A0}
4718;; => {A1,A0,B1,B0}
4719;; => {A1,B1}
341c653c
WL
4720(define_expand "vec_interleave_highv2si"
4721 [(match_operand:V2SI 0 "register_operand" "")
4722 (match_operand:V2SI 1 "reg_or_0_operand" "")
4723 (match_operand:V2SI 2 "reg_or_0_operand" "")]
4724 ""
4725{
4726 if (BYTES_BIG_ENDIAN)
4727 emit_insn (gen_vec_interleave_highv2si_be (operands[0], operands[1],
4728 operands[2]));
4729 else
4730 emit_insn (gen_vec_interleave_highv2si_le (operands[0], operands[1],
4731 operands[2]));
4732 DONE;
4733})
4734
4735(define_insn "vec_interleave_highv2si_be"
4736 [(set (match_operand:V2SI 0 "register_operand" "=r")
4737 (vec_select:V2SI
4738 (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4739 (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4740 (parallel [(const_int 0) (const_int 2)])))]
4741 "BYTES_BIG_ENDIAN"
4742 "v4int_h\t%0, %r1, %r2"
4743 [(set_attr "type" "X01")])
4744
4745(define_insn "vec_interleave_highv2si_le"
dd552284
WL
4746 [(set (match_operand:V2SI 0 "register_operand" "=r")
4747 (vec_select:V2SI
4748 (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4749 (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4750 (parallel [(const_int 1) (const_int 3)])))]
341c653c 4751 "!BYTES_BIG_ENDIAN"
dd552284
WL
4752 "v4int_h\t%0, %r2, %r1"
4753 [(set_attr "type" "X01")])
4754
4755(define_expand "insn_v4int_h"
4756 [(match_operand:DI 0 "register_operand" "")
4757 (match_operand:DI 1 "reg_or_0_operand" "")
4758 (match_operand:DI 2 "reg_or_0_operand" "")]
4759 ""
4760{
341c653c
WL
4761 /* For little endian, our instruction interleaves opposite of the
4762 way vec_interleave works, so we need to reverse the source
4763 operands. */
4764 rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4765 rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
dd552284 4766 tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv2si, V2SImode,
341c653c
WL
4767 operands[0], V2SImode, opnd1, opnd2,
4768 true);
dd552284
WL
4769 DONE;
4770})
4771
4772;; insn_v4int_l
4773;; {B1,B0} {A1,A0}
4774;; => {A1,A0,B1,B0}
4775;; => {A0,B0}
341c653c
WL
4776(define_expand "vec_interleave_lowv2si"
4777 [(match_operand:V2SI 0 "register_operand" "")
4778 (match_operand:V2SI 1 "reg_or_0_operand" "")
4779 (match_operand:V2SI 2 "reg_or_0_operand" "")]
4780 ""
4781{
4782 if (BYTES_BIG_ENDIAN)
4783 emit_insn (gen_vec_interleave_lowv2si_be (operands[0], operands[1],
4784 operands[2]));
4785 else
4786 emit_insn (gen_vec_interleave_lowv2si_le (operands[0], operands[1],
4787 operands[2]));
4788 DONE;
4789})
4790
4791(define_insn "vec_interleave_lowv2si_be"
4792 [(set (match_operand:V2SI 0 "register_operand" "=r")
4793 (vec_select:V2SI
4794 (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4795 (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4796 (parallel [(const_int 1) (const_int 3)])))]
4797 "BYTES_BIG_ENDIAN"
4798 "v4int_l\t%0, %r1, %r2"
4799 [(set_attr "type" "X01")])
4800
4801(define_insn "vec_interleave_lowv2si_le"
dd552284
WL
4802 [(set (match_operand:V2SI 0 "register_operand" "=r")
4803 (vec_select:V2SI
4804 (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4805 (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4806 (parallel [(const_int 0) (const_int 2)])))]
341c653c 4807 "!BYTES_BIG_ENDIAN"
dd552284
WL
4808 "v4int_l\t%0, %r2, %r1"
4809 [(set_attr "type" "X01")])
4810
4811(define_expand "insn_v4int_l"
4812 [(match_operand:DI 0 "register_operand" "")
4813 (match_operand:DI 1 "reg_or_0_operand" "")
4814 (match_operand:DI 2 "reg_or_0_operand" "")]
4815 ""
4816{
341c653c
WL
4817 /* For little endian, our instruction interleaves opposite of the
4818 way vec_interleave works, so we need to reverse the source
4819 operands. */
4820 rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4821 rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
dd552284 4822 tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv2si, V2SImode,
341c653c
WL
4823 operands[0], V2SImode, opnd1, opnd2,
4824 true);
dd552284
WL
4825 DONE;
4826})
4827
4828;; insn_v1mnz
4829;; insn_v1mz
4830;; insn_v2mnz
4831;; insn_v2mz
e3b51eeb
WL
4832(define_insn "insn_mnz_v8qi"
4833 [(set (match_operand:V8QI 0 "register_operand" "=r")
4834 (if_then_else:V8QI
4835 (ne:V8QI
4836 (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4837 (const_vector:V8QI [(const_int 0) (const_int 0)
4838 (const_int 0) (const_int 0)
4839 (const_int 0) (const_int 0)
4840 (const_int 0) (const_int 0)]))
4841 (match_operand:V8QI 2 "reg_or_0_operand" "rO")
4842 (const_vector:V8QI [(const_int 0) (const_int 0)
4843 (const_int 0) (const_int 0)
4844 (const_int 0) (const_int 0)
4845 (const_int 0) (const_int 0)])))]
4846 ""
4847 "v1mnz\t%0, %r1, %r2"
dd552284
WL
4848 [(set_attr "type" "X01")])
4849
e3b51eeb 4850(define_expand "insn_v1mnz"
dd552284 4851 [(set (match_operand:DI 0 "register_operand" "")
e3b51eeb
WL
4852 (if_then_else:V8QI
4853 (ne:V8QI
dd552284 4854 (match_operand:DI 1 "reg_or_0_operand" "")
e3b51eeb
WL
4855 (const_vector:V8QI [(const_int 0) (const_int 0)
4856 (const_int 0) (const_int 0)
4857 (const_int 0) (const_int 0)
4858 (const_int 0) (const_int 0)])
4859 )
dd552284 4860 (match_operand:DI 2 "reg_or_0_operand" "")
e3b51eeb
WL
4861 (const_vector:V8QI [(const_int 0) (const_int 0)
4862 (const_int 0) (const_int 0)
4863 (const_int 0) (const_int 0)
4864 (const_int 0) (const_int 0)])))]
4865 ""
4866{
4867 tilegx_expand_builtin_vector_binop (gen_insn_mnz_v8qi, V8QImode,
4868 operands[0], V8QImode, operands[1],
4869 operands[2], true);
4870 DONE;
4871})
4872
4873(define_insn "insn_mz_v8qi"
4874 [(set (match_operand:V8QI 0 "register_operand" "=r")
4875 (if_then_else:V8QI
4876 (ne:V8QI
4877 (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4878 (const_vector:V8QI [(const_int 0) (const_int 0)
4879 (const_int 0) (const_int 0)
4880 (const_int 0) (const_int 0)
4881 (const_int 0) (const_int 0)]))
4882 (const_vector:V8QI [(const_int 0) (const_int 0)
4883 (const_int 0) (const_int 0)
4884 (const_int 0) (const_int 0)
4885 (const_int 0) (const_int 0)])
4886 (match_operand:V8QI 2 "reg_or_0_operand" "rO")))]
4887 ""
4888 "v1mz\t%0, %r1, %r2"
4889 [(set_attr "type" "X01")])
4890
4891(define_expand "insn_v1mz"
4892 [(set (match_operand:DI 0 "register_operand" "")
4893 (if_then_else:V8QI
4894 (ne:V8QI
4895 (match_operand:DI 1 "reg_or_0_operand" "")
4896 (const_vector:V8QI [(const_int 0) (const_int 0)
4897 (const_int 0) (const_int 0)
4898 (const_int 0) (const_int 0)
4899 (const_int 0) (const_int 0)]))
4900 (const_vector:V8QI [(const_int 0) (const_int 0)
4901 (const_int 0) (const_int 0)
4902 (const_int 0) (const_int 0)
4903 (const_int 0) (const_int 0)])
4904 (match_operand:DI 2 "reg_or_0_operand" "")))]
dd552284
WL
4905 ""
4906{
e3b51eeb
WL
4907 tilegx_expand_builtin_vector_binop (gen_insn_mz_v8qi, V8QImode,
4908 operands[0], V8QImode, operands[1],
dd552284
WL
4909 operands[2], true);
4910 DONE;
4911})
4912
e3b51eeb
WL
4913(define_insn "insn_mnz_v4hi"
4914 [(set (match_operand:V4HI 0 "register_operand" "=r")
4915 (if_then_else:V4HI
4916 (ne:V4HI
4917 (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4918 (const_vector:V4HI [(const_int 0) (const_int 0)
4919 (const_int 0) (const_int 0)]))
4920 (match_operand:V4HI 2 "reg_or_0_operand" "rO")
4921 (const_vector:V4HI [(const_int 0) (const_int 0)
4922 (const_int 0) (const_int 0)])))]
4923 ""
4924 "v2mnz\t%0, %r1, %r2"
4925 [(set_attr "type" "X01")])
4926
4927(define_expand "insn_v2mnz"
4928 [(set (match_operand:DI 0 "register_operand" "")
4929 (if_then_else:V4HI
4930 (ne:V4HI
4931 (match_operand:DI 1 "reg_or_0_operand" "")
4932 (const_vector:V4HI [(const_int 0) (const_int 0)
4933 (const_int 0) (const_int 0)]))
4934 (match_operand:DI 2 "reg_or_0_operand" "")
4935 (const_vector:V4HI [(const_int 0) (const_int 0)
4936 (const_int 0) (const_int 0)])))]
dd552284 4937 ""
e3b51eeb
WL
4938{
4939 tilegx_expand_builtin_vector_binop (gen_insn_mnz_v4hi, V4HImode,
4940 operands[0], V4HImode, operands[1],
4941 operands[2], true);
4942 DONE;
4943})
4944
4945(define_insn "insn_mz_v4hi"
4946 [(set (match_operand:V4HI 0 "register_operand" "=r")
4947 (if_then_else:V4HI
4948 (ne:V4HI
4949 (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4950 (const_vector:V4HI [(const_int 0) (const_int 0)
4951 (const_int 0) (const_int 0)]))
4952 (const_vector:V4HI [(const_int 0) (const_int 0)
4953 (const_int 0) (const_int 0)])
4954 (match_operand:V4HI 2 "reg_or_0_operand" "rO")))]
4955 ""
4956 "v2mz\t%0, %r1, %r2"
dd552284 4957 [(set_attr "type" "X01")])
e3b51eeb
WL
4958
4959(define_expand "insn_v2mz"
dd552284 4960 [(set (match_operand:DI 0 "register_operand" "")
e3b51eeb
WL
4961 (if_then_else:V4HI
4962 (ne:V4HI
dd552284 4963 (match_operand:DI 1 "reg_or_0_operand" "")
e3b51eeb
WL
4964 (const_vector:V4HI [(const_int 0) (const_int 0)
4965 (const_int 0) (const_int 0)]))
4966 (const_vector:V4HI [(const_int 0) (const_int 0)
4967 (const_int 0) (const_int 0)])
dd552284
WL
4968 (match_operand:DI 2 "reg_or_0_operand" "")))]
4969 ""
4970{
e3b51eeb
WL
4971 tilegx_expand_builtin_vector_binop (gen_insn_mz_v4hi, V4HImode,
4972 operands[0], V4HImode, operands[1],
dd552284
WL
4973 operands[2], true);
4974 DONE;
4975})
4976
4977;; insn_v1mulu
4978(define_insn "vec_widen_umult_lo_v8qi"
4979 [(set (match_operand:V4HI 0 "register_operand" "=r")
4980 (mult:V4HI
4981 (zero_extend:V4HI
4982 (vec_select:V4QI
4983 (match_operand:V8QI 1 "register_operand" "r")
4984 (parallel [(const_int 0) (const_int 1)
4985 (const_int 2) (const_int 3)])))
4986 (zero_extend:V4HI
4987 (vec_select:V4QI
4988 (match_operand:V8QI 2 "register_operand" "r")
4989 (parallel [(const_int 0) (const_int 1)
4990 (const_int 2) (const_int 3)])))))]
4991 ""
4992 "v1mulu\t%0, %r1, %r2"
4993 [(set_attr "type" "X0_2cycle")])
4994
4995(define_expand "insn_v1mulu"
4996 [(match_operand:DI 0 "register_operand" "")
9332b0d2
WL
4997 (match_operand:DI 1 "register_operand" "")
4998 (match_operand:DI 2 "register_operand" "")]
dd552284
WL
4999 ""
5000{
5001 tilegx_expand_builtin_vector_binop (gen_vec_widen_umult_lo_v8qi, V4HImode,
5002 operands[0], V8QImode, operands[1],
5003 operands[2], true);
5004 DONE;
5005})
5006
5007;; insn_v1mulus
5008(define_insn "vec_widen_usmult_lo_v8qi"
5009 [(set (match_operand:V4HI 0 "register_operand" "=r")
5010 (mult:V4HI
5011 (zero_extend:V4HI
5012 (vec_select:V4QI
5013 (match_operand:V8QI 1 "register_operand" "r")
5014 (parallel [(const_int 0) (const_int 1)
5015 (const_int 2) (const_int 3)])))
5016 (sign_extend:V4HI
5017 (vec_select:V4QI
5018 (match_operand:V8QI 2 "register_operand" "r")
5019 (parallel [(const_int 0) (const_int 1)
5020 (const_int 2) (const_int 3)])))))]
5021 ""
5022 "v1mulus\t%0, %r1, %r2"
5023 [(set_attr "type" "X0_2cycle")])
5024
5025(define_expand "insn_v1mulus"
5026 [(match_operand:DI 0 "register_operand" "")
9332b0d2
WL
5027 (match_operand:DI 1 "register_operand" "")
5028 (match_operand:DI 2 "register_operand" "")]
dd552284
WL
5029 ""
5030{
5031 tilegx_expand_builtin_vector_binop (gen_vec_widen_usmult_lo_v8qi, V4HImode,
5032 operands[0], V8QImode, operands[1],
5033 operands[2], true);
5034 DONE;
5035})
5036
5037;; insn_v2muls
5038(define_insn "vec_widen_smult_lo_v4qi"
5039 [(set (match_operand:V2SI 0 "register_operand" "=r")
5040 (mult:V2SI
5041 (sign_extend:V2SI
5042 (vec_select:V2HI
5043 (match_operand:V4HI 1 "register_operand" "r")
5044 (parallel [(const_int 0) (const_int 1)])))
5045 (sign_extend:V2SI
5046 (vec_select:V2HI
5047 (match_operand:V4HI 2 "register_operand" "r")
5048 (parallel [(const_int 0) (const_int 1)])))))]
5049 ""
5050 "v2muls\t%0, %r1, %r2"
5051 [(set_attr "type" "X0_2cycle")])
5052
5053(define_expand "insn_v2muls"
5054 [(match_operand:DI 0 "register_operand" "")
9332b0d2
WL
5055 (match_operand:DI 1 "register_operand" "")
5056 (match_operand:DI 2 "register_operand" "")]
dd552284
WL
5057 ""
5058{
5059 tilegx_expand_builtin_vector_binop (gen_vec_widen_smult_lo_v4qi, V2SImode,
5060 operands[0], V4HImode, operands[1],
5061 operands[2], true);
5062 DONE;
5063})
5064
5065;; v2packl
5066;; v2packuc
5067;; {B3,B2,B1,B0} {A3,A2,A1,A0}
5068;; => {A3,A2,A1,A0,B3,B2,B1,B0}
5069(define_insn "vec_pack_<pack_optab>_v4hi"
1a79721f 5070 [(set (match_operand:V8QI 0 "register_operand" "=r")
dd552284
WL
5071 (vec_concat:V8QI
5072 (v2pack:V4QI (match_operand:V4HI 1 "reg_or_0_operand" "rO"))
5073 (v2pack:V4QI (match_operand:V4HI 2 "reg_or_0_operand" "rO"))))]
5074 ""
5075 "v2<pack_insn>\t%0, %r2, %r1"
5076 [(set_attr "type" "X01")])
5077
5078(define_expand "insn_v2<pack_insn>"
1a79721f 5079 [(set (match_operand:DI 0 "register_operand" "")
dd552284
WL
5080 (vec_concat:V8QI
5081 (v2pack:V4QI (match_operand:DI 2 "reg_or_0_operand" ""))
5082 (v2pack:V4QI (match_operand:DI 1 "reg_or_0_operand" ""))))]
5083 ""
5084{
5085 /* Our instruction concats opposite of the way vec_pack works, so we
5086 need to reverse the source operands. */
5087 tilegx_expand_builtin_vector_binop (gen_vec_pack_<pack_optab>_v4hi,
5088 V8QImode, operands[0], V4HImode,
5089 operands[2], operands[1], true);
5090 DONE;
5091})
5092
5093;; v2packh
5094;; {B3,B2,B1,B0} {A3,A2,A1,A0}
5095;; => {A3_hi,A2_hi,A1_hi,A0_hi,B3_hi,B2_hi,B1_hi,B0_hi}
5096(define_insn "vec_pack_hipart_v4hi"
1a79721f 5097 [(set (match_operand:V8QI 0 "register_operand" "=r")
dd552284
WL
5098 (vec_concat:V8QI
5099 (truncate:V4QI
5100 (ashiftrt:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
5101 (const_int 8)))
5102 (truncate:V4QI
5103 (ashiftrt:V4HI (match_operand:V4HI 2 "reg_or_0_operand" "rO")
5104 (const_int 8)))))]
5105 ""
5106 "v2packh\t%0, %r2, %r1"
5107 [(set_attr "type" "X01")])
5108
5109(define_expand "insn_v2packh"
1a79721f 5110 [(set (match_operand:DI 0 "register_operand" "")
dd552284
WL
5111 (vec_concat:V8QI
5112 (truncate:V4QI
5113 (ashiftrt:V4HI (match_operand:DI 2 "reg_or_0_operand" "")
5114 (const_int 8)))
5115 (truncate:V4QI
5116 (ashiftrt:V4HI (match_operand:DI 1 "reg_or_0_operand" "")
5117 (const_int 8)))))]
5118 ""
5119{
5120 /* Our instruction concats opposite of the way vec_pack works, so we
5121 need to reverse the source operands. */
5122 tilegx_expand_builtin_vector_binop (gen_vec_pack_hipart_v4hi, V8QImode,
5123 operands[0], V4HImode, operands[2],
5124 operands[1], true);
5125 DONE;
5126})
5127
5128;; v4packsc
5129;; {B1,B0} {A1,A0}
5130;; => {A1,A0,B1,B0}
5131(define_insn "vec_pack_ssat_v2si"
1a79721f 5132 [(set (match_operand:V4HI 0 "register_operand" "=r")
dd552284
WL
5133 (vec_concat:V4HI
5134 (us_truncate:V2HI (match_operand:V2SI 1 "reg_or_0_operand" "rO"))
5135 (us_truncate:V2HI (match_operand:V2SI 2 "reg_or_0_operand" "rO"))))]
5136 ""
5137 "v4packsc\t%0, %r2, %r1"
5138 [(set_attr "type" "X01")])
5139
5140(define_expand "insn_v4packsc"
1a79721f 5141 [(set (match_operand:DI 0 "register_operand" "")
dd552284
WL
5142 (vec_concat:V4HI
5143 (us_truncate:V2HI (match_operand:DI 2 "reg_or_0_operand" ""))
5144 (us_truncate:V2HI (match_operand:DI 1 "reg_or_0_operand" ""))))]
5145 ""
5146{
5147 /* Our instruction concats opposite of the way vec_pack works, so we
5148 need to reverse the source operands. */
5149 tilegx_expand_builtin_vector_binop (gen_vec_pack_ssat_v2si, V4HImode,
5150 operands[0], V2SImode, operands[2],
5151 operands[1], true);
5152 DONE;
5153})
5154
5155;; Rest of the vector intrinsics
5156(define_insn "insn_v1adiffu"
5157 [(set (match_operand:DI 0 "register_operand" "=r")
5158 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5159 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5160 UNSPEC_INSN_V1ADIFFU))]
5161 ""
5162 "v1adiffu\t%0, %r1, %r2"
5163 [(set_attr "type" "X0_2cycle")])
5164
5165(define_insn "insn_v1avgu"
5166 [(set (match_operand:DI 0 "register_operand" "=r")
5167 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5168 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5169 UNSPEC_INSN_V1AVGU))]
5170 ""
5171 "v1avgu\t%0, %r1, %r2"
5172 [(set_attr "type" "X0")])
5173
5174(define_insn "insn_v1ddotpu"
5175 [(set (match_operand:DI 0 "register_operand" "=r")
5176 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5177 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5178 UNSPEC_INSN_V1DDOTPU))]
5179 ""
5180 "v1ddotpu\t%0, %r1, %r2"
5181 [(set_attr "type" "X0_2cycle")])
5182
5183(define_insn "insn_v1ddotpua"
5184 [(set (match_operand:DI 0 "register_operand" "=r")
5185 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5186 (match_operand:DI 2 "reg_or_0_operand" "rO")
5187 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5188 UNSPEC_INSN_V1DDOTPUA))]
5189 ""
5190 "v1ddotpua\t%0, %r2, %r3"
5191 [(set_attr "type" "X0_2cycle")])
5192
5193(define_insn "insn_v1ddotpus"
5194 [(set (match_operand:DI 0 "register_operand" "=r")
5195 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5196 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5197 UNSPEC_INSN_V1DDOTPUS))]
5198 ""
5199 "v1ddotpus\t%0, %r1, %r2"
5200 [(set_attr "type" "X0_2cycle")])
5201
5202(define_insn "insn_v1ddotpusa"
5203 [(set (match_operand:DI 0 "register_operand" "=r")
5204 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5205 (match_operand:DI 2 "reg_or_0_operand" "rO")
5206 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5207 UNSPEC_INSN_V1DDOTPUSA))]
5208 ""
5209 "v1ddotpusa\t%0, %r2, %r3"
5210 [(set_attr "type" "X0_2cycle")])
5211
5212(define_insn "insn_v1dotp"
5213 [(set (match_operand:DI 0 "register_operand" "=r")
5214 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5215 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5216 UNSPEC_INSN_V1DOTP))]
5217 ""
5218 "v1dotp\t%0, %r1, %r2"
5219 [(set_attr "type" "X0_2cycle")])
5220
5221(define_insn "insn_v1dotpa"
5222 [(set (match_operand:DI 0 "register_operand" "=r")
5223 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5224 (match_operand:DI 2 "reg_or_0_operand" "rO")
5225 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5226 UNSPEC_INSN_V1DOTPA))]
5227 ""
5228 "v1dotpa\t%0, %r2, %r3"
5229 [(set_attr "type" "X0_2cycle")])
5230
5231(define_insn "insn_v1dotpu"
5232 [(set (match_operand:DI 0 "register_operand" "=r")
5233 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5234 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5235 UNSPEC_INSN_V1DOTPU))]
5236 ""
5237 "v1dotpu\t%0, %r1, %r2"
5238 [(set_attr "type" "X0_2cycle")])
5239
5240(define_insn "insn_v1dotpua"
5241 [(set (match_operand:DI 0 "register_operand" "=r")
5242 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5243 (match_operand:DI 2 "reg_or_0_operand" "rO")
5244 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5245 UNSPEC_INSN_V1DOTPUA))]
5246 ""
5247 "v1dotpua\t%0, %r2, %r3"
5248 [(set_attr "type" "X0_2cycle")])
5249
5250(define_insn "insn_v1dotpus"
5251 [(set (match_operand:DI 0 "register_operand" "=r")
5252 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5253 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5254 UNSPEC_INSN_V1DOTPUS))]
5255 ""
5256 "v1dotpus\t%0, %r1, %r2"
5257 [(set_attr "type" "X0_2cycle")])
5258
5259(define_insn "insn_v1dotpusa"
5260 [(set (match_operand:DI 0 "register_operand" "=r")
5261 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5262 (match_operand:DI 2 "reg_or_0_operand" "rO")
5263 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5264 UNSPEC_INSN_V1DOTPUSA))]
5265 ""
5266 "v1dotpusa\t%0, %r2, %r3"
5267 [(set_attr "type" "X0_2cycle")])
5268
5269(define_insn "insn_v1sadau"
5270 [(set (match_operand:DI 0 "register_operand" "=r")
5271 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5272 (match_operand:DI 2 "reg_or_0_operand" "rO")
5273 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5274 UNSPEC_INSN_V1SADAU))]
5275 ""
5276 "v1sadau\t%0, %r2, %r3"
5277 [(set_attr "type" "X0_2cycle")])
5278
5279(define_insn "insn_v1sadu"
5280 [(set (match_operand:DI 0 "register_operand" "=r")
5281 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5282 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5283 UNSPEC_INSN_V1SADU))]
5284 ""
5285 "v1sadu\t%0, %r1, %r2"
5286 [(set_attr "type" "X0_2cycle")])
5287
5288(define_insn "*insn_v1sadu"
5289 [(set (match_operand:SI 0 "register_operand" "=r")
5290 (truncate:SI
5291 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5292 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5293 UNSPEC_INSN_V1SADU)))]
5294 ""
5295 "v1sadu\t%0, %r1, %r2"
5296 [(set_attr "type" "X0_2cycle")])
5297
5298(define_insn "insn_v2adiffs"
5299 [(set (match_operand:DI 0 "register_operand" "=r")
5300 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5301 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5302 UNSPEC_INSN_V2ADIFFS))]
5303 ""
5304 "v2adiffs\t%0, %r1, %r2"
5305 [(set_attr "type" "X0_2cycle")])
5306
5307(define_insn "insn_v2avgs"
5308 [(set (match_operand:DI 0 "register_operand" "=r")
5309 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5310 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5311 UNSPEC_INSN_V2AVGS))]
5312 ""
5313 "v2avgs\t%0, %r1, %r2"
5314 [(set_attr "type" "X0")])
5315
5316(define_insn "insn_v2dotp"
5317 [(set (match_operand:DI 0 "register_operand" "=r")
5318 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5319 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5320 UNSPEC_INSN_V2DOTP))]
5321 ""
5322 "v2dotp\t%0, %r1, %r2"
5323 [(set_attr "type" "X0_2cycle")])
5324
5325(define_insn "insn_v2dotpa"
5326 [(set (match_operand:DI 0 "register_operand" "=r")
5327 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5328 (match_operand:DI 2 "reg_or_0_operand" "rO")
5329 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5330 UNSPEC_INSN_V2DOTPA))]
5331 ""
5332 "v2dotpa\t%0, %r2, %r3"
5333 [(set_attr "type" "X0_2cycle")])
5334
5335(define_insn "insn_v2mulfsc"
5336 [(set (match_operand:DI 0 "register_operand" "=r")
5337 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5338 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5339 UNSPEC_INSN_V2MULFSC))]
5340 ""
5341 "v2mulfsc\t%0, %r1, %r2"
5342 [(set_attr "type" "X0_2cycle")])
5343
5344(define_insn "insn_v2sadas"
5345 [(set (match_operand:DI 0 "register_operand" "=r")
5346 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5347 (match_operand:DI 2 "reg_or_0_operand" "rO")
5348 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5349 UNSPEC_INSN_V2SADAS))]
5350 ""
5351 "v2sadas\t%0, %r2, %r3"
5352 [(set_attr "type" "X0_2cycle")])
5353
5354(define_insn "insn_v2sadau"
5355 [(set (match_operand:DI 0 "register_operand" "=r")
5356 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5357 (match_operand:DI 2 "reg_or_0_operand" "rO")
5358 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5359 UNSPEC_INSN_V2SADAU))]
5360 ""
5361 "v2sadau\t%0, %r2, %r3"
5362 [(set_attr "type" "X0_2cycle")])
5363
5364(define_insn "insn_v2sads"
5365 [(set (match_operand:DI 0 "register_operand" "=r")
5366 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5367 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5368 UNSPEC_INSN_V2SADS))]
5369 ""
5370 "v2sads\t%0, %r1, %r2"
5371 [(set_attr "type" "X0_2cycle")])
5372
5373(define_insn "*insn_v2sads"
5374 [(set (match_operand:SI 0 "register_operand" "=r")
5375 (truncate:SI
5376 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5377 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5378 UNSPEC_INSN_V2SADS)))]
5379 ""
5380 "v2sads\t%0, %r1, %r2"
5381 [(set_attr "type" "X0_2cycle")])
5382
5383(define_insn "insn_v2sadu"
5384 [(set (match_operand:DI 0 "register_operand" "=r")
5385 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5386 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5387 UNSPEC_INSN_V2SADU))]
5388 ""
5389 "v2sadu\t%0, %r1, %r2"
5390 [(set_attr "type" "X0_2cycle")])
5391
5392(define_insn "*insn_v2sadu"
5393 [(set (match_operand:SI 0 "register_operand" "=r")
5394 (truncate:SI
5395 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5396 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5397 UNSPEC_INSN_V2SADU)))]
5398 ""
5399 "v2sadu\t%0, %r1, %r2"
5400 [(set_attr "type" "X0_2cycle")])
5401
5402(define_insn "insn_wh64"
5403 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
5404 UNSPEC_INSN_WH64)
5405 (clobber (mem:BLK (const_int 0)))]
5406 ""
5407 "wh64\t%r0"
5408 [(set_attr "type" "X1")])
5409
5410\f
5411;; Network intrinsics
5412
8e90a625
WL
5413;; Note the this barrier is of type "nothing," which is deleted after
5414;; the final scheduling pass so that nothing is emitted for it.
dd552284
WL
5415(define_insn "tilegx_network_barrier"
5416 [(unspec_volatile:SI [(const_int 0)] UNSPEC_NETWORK_BARRIER)]
5417 ""
5418 "pseudo"
5419 [(set_attr "type" "nothing")
5420 (set_attr "length" "0")])
5421
5422(define_insn "*netreg_receive"
5423 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,U,m")
5424 (unspec_volatile:DI [(match_operand:DI 1 "netreg_operand" "i,i,i")
5425 (reg:DI TILEGX_NETORDER_REG)]
5426 UNSPEC_NETWORK_RECEIVE))
5427 (clobber (reg:DI TILEGX_NETORDER_REG))]
5428
5429 ""
5430 "@
5431 move\t%0, %N1
5432 st\t%0, %N1
5433 st_add\t%I0, %N1, %i0"
5434 [(set_attr "type" "*,Y2,X1")])
5435
5436(define_insn "*netreg_send"
5437 [(unspec_volatile:DI
5438 [(match_operand:DI 0 "netreg_operand" "i,i,i,i,i,i")
5439 (match_operand:DI 1 "reg_or_cint_operand" "r,I,J,K,N,P")
5440 (reg:DI TILEGX_NETORDER_REG)]
5441 UNSPEC_NETWORK_SEND)
5442 (clobber (reg:DI TILEGX_NETORDER_REG))]
5443 ""
5444 "@
5445 move\t%N0, %r1
5446 movei\t%N0, %1
5447 moveli\t%N0, %1
5448 shl16insli\t%N0, zero, %h1
5449 v1addi\t%N0, zero, %j1
5450 v2addi\t%N0, zero, %h1"
5451 [(set_attr "type" "*,*,X01,X01,X01,X01")])
5452
5453(define_expand "tilegx_idn0_receive"
5454 [(parallel
5455 [(set (match_operand:DI 0 "register_operand" "")
5456 (unspec_volatile:DI [(const_int TILEGX_NETREG_IDN0)
5457 (reg:DI TILEGX_NETORDER_REG)]
5458 UNSPEC_NETWORK_RECEIVE))
5459 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5460 "")
5461
5462(define_expand "tilegx_idn1_receive"
5463 [(parallel
5464 [(set (match_operand:DI 0 "register_operand" "")
5465 (unspec_volatile:DI [(const_int TILEGX_NETREG_IDN1)
5466 (reg:DI TILEGX_NETORDER_REG)]
5467 UNSPEC_NETWORK_RECEIVE))
5468 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5469 "")
5470
5471(define_expand "tilegx_idn_send"
5472 [(parallel
5473 [(unspec_volatile:DI [(const_int TILEGX_NETREG_IDN0)
5474 (match_operand:DI 0 "reg_or_cint_operand" "")
5475 (reg:DI TILEGX_NETORDER_REG)]
5476 UNSPEC_NETWORK_SEND)
5477 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5478 "")
5479
5480(define_expand "tilegx_udn0_receive"
5481 [(parallel
5482 [(set (match_operand:DI 0 "register_operand" "")
5483 (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN0)
5484 (reg:DI TILEGX_NETORDER_REG)]
5485 UNSPEC_NETWORK_RECEIVE))
5486 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5487 "")
5488
5489(define_expand "tilegx_udn1_receive"
5490 [(parallel
5491 [(set (match_operand:DI 0 "register_operand" "")
5492 (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN1)
5493 (reg:DI TILEGX_NETORDER_REG)]
5494 UNSPEC_NETWORK_RECEIVE))
5495 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5496 "")
5497
5498(define_expand "tilegx_udn2_receive"
5499 [(parallel
5500 [(set (match_operand:DI 0 "register_operand" "")
5501 (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN2)
5502 (reg:DI TILEGX_NETORDER_REG)]
5503 UNSPEC_NETWORK_RECEIVE))
5504 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5505 "")
5506
5507(define_expand "tilegx_udn3_receive"
5508 [(parallel
5509 [(set (match_operand:DI 0 "register_operand" "")
5510 (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN3)
5511 (reg:DI TILEGX_NETORDER_REG)]
5512 UNSPEC_NETWORK_RECEIVE))
5513 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5514 "")
5515
5516(define_expand "tilegx_udn_send"
5517 [(parallel
5518 [(unspec_volatile:DI [(const_int TILEGX_NETREG_UDN0)
5519 (match_operand:DI 0 "reg_or_cint_operand" "")
5520 (reg:DI TILEGX_NETORDER_REG)]
5521 UNSPEC_NETWORK_SEND)
5522 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5523 "")
5524
5525(define_insn "*netreg_adddi_to_network"
5526 [(unspec_volatile:DI
5527 [(match_operand:DI 0 "netreg_operand" "i,i,i")
5528 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO")
5529 (match_operand:DI 2 "add_operand" "r,I,JT"))
5530 (reg:DI TILEGX_NETORDER_REG)]
5531 UNSPEC_NETWORK_SEND)
5532 (clobber (reg:DI TILEGX_NETORDER_REG))]
5533 ""
5534 "@
5535 add\t%N0, %r1, %2
5536 addi\t%N0, %r1, %2
5537 addli\t%N0, %r1, %H2"
5538 [(set_attr "type" "*,*,X01")])
5539
5540(define_insn "*netreg_adddi_from_network"
5541 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5542 (plus:DI (unspec_volatile:DI
5543 [(match_operand:DI 1 "netreg_operand" "%i,i,i")
5544 (reg:DI TILEGX_NETORDER_REG)]
5545 UNSPEC_NETWORK_RECEIVE)
5546 (match_operand:DI 2 "add_operand" "rO,I,JT")))
5547 (clobber (reg:DI TILEGX_NETORDER_REG))]
5548 ""
5549 "@
5550 add\t%0, %N1, %r2
5551 addi\t%0, %N1, %2
5552 addli\t%0, %N1, %H2"
5553 [(set_attr "type" "*,*,X01")])
5554
5555\f
5556;;
5557;; Stack protector instructions.
5558;;
5559
5560(define_expand "stack_protect_set"
5561 [(set (match_operand 0 "nonautoincmem_operand" "")
5562 (match_operand 1 "nonautoincmem_operand" ""))]
5563 ""
5564{
5565#ifdef TARGET_THREAD_SSP_OFFSET
5566 rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
5567 rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
5568 rtx ssp = gen_reg_rtx (Pmode);
5569
f7df4a84 5570 emit_insn (gen_rtx_SET (ssp, ssp_addr));
dd552284
WL
5571
5572 operands[1] = gen_rtx_MEM (Pmode, ssp);
5573#endif
5574
5575 if (TARGET_32BIT)
5576 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
5577 else
5578 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
5579
5580 DONE;
5581})
5582
5583(define_insn "stack_protect_setsi"
5584 [(set (match_operand:SI 0 "nonautoincmem_operand" "=U")
5585 (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")]
5586 UNSPEC_SP_SET))
5587 (set (match_scratch:SI 2 "=&r") (const_int 0))]
5588 ""
5589 "ld4s\t%2, %1; { st4\t%0, %2; move\t%2, zero }"
5590 [(set_attr "length" "16")
5591 (set_attr "type" "cannot_bundle_3cycle")])
5592
5593(define_insn "stack_protect_setdi"
5594 [(set (match_operand:DI 0 "nonautoincmem_operand" "=U")
5595 (unspec:DI [(match_operand:DI 1 "nonautoincmem_operand" "U")]
5596 UNSPEC_SP_SET))
5597 (set (match_scratch:DI 2 "=&r") (const_int 0))]
5598 ""
5599 "ld\t%2, %1; { st\t%0, %2; move\t%2, zero }"
5600 [(set_attr "length" "16")
5601 (set_attr "type" "cannot_bundle_3cycle")])
5602
5603(define_expand "stack_protect_test"
5604 [(match_operand 0 "nonautoincmem_operand" "")
5605 (match_operand 1 "nonautoincmem_operand" "")
5606 (match_operand 2 "" "")]
5607 ""
5608{
5609 rtx compare_result;
5610 rtx bcomp, loc_ref;
5611
5612#ifdef TARGET_THREAD_SSP_OFFSET
5613 rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
5614 rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
5615 rtx ssp = gen_reg_rtx (Pmode);
5616
f7df4a84 5617 emit_insn (gen_rtx_SET (ssp, ssp_addr));
dd552284
WL
5618
5619 operands[1] = gen_rtx_MEM (Pmode, ssp);
5620#endif
5621
5622 compare_result = gen_reg_rtx (Pmode);
5623
5624 if (TARGET_32BIT)
5625 emit_insn (gen_stack_protect_testsi (compare_result, operands[0],
5626 operands[1]));
5627 else
5628 emit_insn (gen_stack_protect_testdi (compare_result, operands[0],
5629 operands[1]));
5630
5631 bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
5632
5633 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
5634
f7df4a84 5635 emit_jump_insn (gen_rtx_SET (pc_rtx,
dd552284
WL
5636 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
5637 loc_ref, pc_rtx)));
5638
5639 DONE;
5640})
5641
5642(define_insn "stack_protect_testsi"
5643 [(set (match_operand:SI 0 "register_operand" "=&r")
5644 (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")
5645 (match_operand:SI 2 "nonautoincmem_operand" "U")]
5646 UNSPEC_SP_TEST))
5647 (set (match_scratch:SI 3 "=&r") (const_int 0))]
5648 ""
5649 "ld4s\t%0, %1; ld4s\t%3, %2; { cmpeq\t%0, %0, %3; move\t%3, zero }"
5650 [(set_attr "length" "24")
5651 (set_attr "type" "cannot_bundle_4cycle")])
5652
5653(define_insn "stack_protect_testdi"
5654 [(set (match_operand:DI 0 "register_operand" "=&r")
5655 (unspec:DI [(match_operand:DI 1 "nonautoincmem_operand" "U")
5656 (match_operand:DI 2 "nonautoincmem_operand" "U")]
5657 UNSPEC_SP_TEST))
5658 (set (match_scratch:DI 3 "=&r") (const_int 0))]
5659 ""
5660 "ld\t%0, %1; ld\t%3, %2; { cmpeq\t%0, %0, %3; move\t%3, zero }"
5661 [(set_attr "length" "24")
5662 (set_attr "type" "cannot_bundle_4cycle")])
5663
5664(include "sync.md")