]> gcc.gnu.org Git - gcc.git/blob - gcc/config/tilegx/tilegx.md
Update copyright years.
[gcc.git] / gcc / config / tilegx / tilegx.md
1 ;; Machine description for Tilera TILE-Gx chip for GCC.
2 ;; Copyright (C) 2011-2015 Free Software Foundation, Inc.
3 ;; Contributed by Walter Lee (walt@tilera.com)
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 ;; License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 (define_constants [
22 ;;
23 ;; The following represent intrinsic insns, organized by latency.
24 ;;
25
26 ;; single cycle
27 (UNSPEC_INSN_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)
152 (UNSPEC_MOV_LARGE_PCREL_STEP4 205)
153
154 ;; Latency specifying loads.
155 (UNSPEC_LATENCY_L2 206)
156 (UNSPEC_LATENCY_MISS 207)
157
158 ;; A pseudo-op that prevents network operations from being ordered.
159 (UNSPEC_NETWORK_BARRIER 208)
160
161 ;; Operations that access network registers.
162 (UNSPEC_NETWORK_RECEIVE 209)
163 (UNSPEC_NETWORK_SEND 210)
164
165 ;; Stack protector operations
166 (UNSPEC_SP_SET 211)
167 (UNSPEC_SP_TEST 212)
168
169 ;; This is used to move a value to a SPR.
170 (UNSPEC_SPR_MOVE 213)
171
172 ;; A call to __tls_get_addr
173 (UNSPEC_TLS_GD_CALL 214)
174
175 ;; An opaque TLS "add" operation for TLS general dynamic model
176 ;; access.
177 (UNSPEC_TLS_GD_ADD 215)
178
179 ;; An opaque TLS "load" operation for TLS initial exec model access.
180 (UNSPEC_TLS_IE_LOAD 216)
181
182 ;; An opaque TLS "add" operation for TLS access.
183 (UNSPEC_TLS_ADD 217)
184
185 ;; Atomics
186 (UNSPEC_ATOMIC 218)
187 (UNSPEC_CMPXCHG 219)
188 (UNSPEC_XCHG 220)
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)
202 (UNSPEC_HW1_PCREL 308)
203 (UNSPEC_HW1_LAST_PCREL 309)
204 (UNSPEC_HW2_LAST_PCREL 310)
205
206 (UNSPEC_HW0_GOT 311)
207 (UNSPEC_HW0_LAST_GOT 312)
208 (UNSPEC_HW1_LAST_GOT 313)
209
210 (UNSPEC_HW0_TLS_GD 314)
211 (UNSPEC_HW1_LAST_TLS_GD 315)
212
213 (UNSPEC_HW0_TLS_IE 316)
214 (UNSPEC_HW1_LAST_TLS_IE 317)
215
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)
224
225 ;; This is used to wrap around the addresses of non-temporal load/store
226 ;; intrinsics.
227 (UNSPEC_NON_TEMPORAL 324)
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"
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"
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 ])
419
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
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
833 /* Reject bitfields that can be done with a normal load. */
834 if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
835 FAIL;
836
837 /* The value in memory cannot span more than 8 bytes. */
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
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
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
875 /* Reject bitfields that can be done with a normal load. */
876 if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
877 FAIL;
878
879 /* The value in memory cannot span more than 8 bytes. */
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 {
895 /* Extracting the low bits is just a bitwise AND. */
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
907 ;; The next three patterns are used to to materialize a position
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.
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)))])
915
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
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
967 ;; The next three patterns are used to to materialize a position
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
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")
989
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
1000 ;; The next three patterns are used to to materialize a position
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
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
1240 (define_insn "*zero_extract<mode>"
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"
1248 [(set_attr "type" "X0")])
1249
1250 (define_insn "*sign_extract_low32"
1251 [(set (match_operand:DI 0 "register_operand" "=r")
1252 (sign_extract:DI
1253 (match_operand:DI 1 "reg_or_0_operand" "r")
1254 (match_operand:DI 2 "u6bit_cint_operand" "n")
1255 (match_operand:DI 3 "u6bit_cint_operand" "n")))]
1256 "INTVAL (operands[3]) == 0 && INTVAL (operands[2]) == 32"
1257 "addxi\t%0, %r1, 0")
1258
1259 (define_insn "*sign_extract"
1260 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1261 (sign_extract:I48MODE
1262 (match_operand:I48MODE 1 "reg_or_0_operand" "r")
1263 (match_operand:I48MODE 2 "u6bit_cint_operand" "n")
1264 (match_operand:I48MODE 3 "u6bit_cint_operand" "n")))]
1265 ""
1266 "bfexts\t%0, %r1, %3, %3+%2-1"
1267 [(set_attr "type" "X0")])
1268
1269 \f
1270 ;;
1271 ;; Arithmetic ops
1272 ;;
1273
1274 (define_insn "add<mode>3"
1275 [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1276 (plus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rO,rO,rO")
1277 (match_operand:I48MODE 2 "add_operand" "r,I,JT")))]
1278 ""
1279 "@
1280 add<x>\t%0, %r1, %r2
1281 add<x>i\t%0, %r1, %2
1282 add<x>li\t%0, %r1, %H2"
1283 [(set_attr "type" "*,*,X01")])
1284
1285 (define_insn "*addsi3_sext"
1286 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1287 (sign_extend:DI
1288 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO")
1289 (match_operand:SI 2 "add_operand" "r,I,JT"))))]
1290 ""
1291 "@
1292 addx\t%0, %r1, %r2
1293 addxi\t%0, %r1, %2
1294 addxli\t%0, %r1, %H2"
1295 [(set_attr "type" "*,*,X01")])
1296
1297 (define_insn "sub<mode>3"
1298 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1299 (minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
1300 (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
1301 ""
1302 "sub<x>\t%0, %r1, %r2")
1303
1304 (define_insn "*subsi3_sext"
1305 [(set (match_operand:DI 0 "register_operand" "=r")
1306 (sign_extend:DI
1307 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1308 (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
1309 ""
1310 "subx\t%0, %r1, %r2")
1311
1312 (define_insn "neg<mode>2"
1313 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1314 (neg:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO")))]
1315 ""
1316 "sub<x>\t%0, zero, %r1")
1317
1318 (define_insn "*negsi2_sext"
1319 [(set (match_operand:DI 0 "register_operand" "=r")
1320 (sign_extend:DI
1321 (neg:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))))]
1322 ""
1323 "subx\t%0, zero, %r1")
1324
1325 (define_insn "ssaddsi3"
1326 [(set (match_operand:SI 0 "register_operand" "=r")
1327 (ss_plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1328 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
1329 ""
1330 "addxsc\t%0, %r1, %r2"
1331 [(set_attr "type" "X01")])
1332
1333 (define_insn "*ssaddsi3_sext"
1334 [(set (match_operand:DI 0 "register_operand" "=r")
1335 (sign_extend:DI
1336 (ss_plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1337 (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
1338 ""
1339 "addxsc\t%0, %r1, %r2"
1340 [(set_attr "type" "X01")])
1341
1342 (define_insn "sssubsi3"
1343 [(set (match_operand:SI 0 "register_operand" "=r")
1344 (ss_minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1345 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
1346 ""
1347 "subxsc\t%0, %r1, %r2"
1348 [(set_attr "type" "X01")])
1349
1350 (define_insn "*sssubsi3_sext"
1351 [(set (match_operand:DI 0 "register_operand" "=r")
1352 (sign_extend:DI
1353 (ss_minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1354 (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
1355 ""
1356 "subxsc\t%0, %r1, %r2"
1357 [(set_attr "type" "X01")])
1358
1359 (define_expand "addsf3"
1360 [(set (match_operand:SF 0 "register_operand" "")
1361 (plus:SF (match_operand:SF 1 "register_operand" "")
1362 (match_operand:SF 2 "register_operand" "")))]
1363 ""
1364 {
1365 rtx result = gen_lowpart (DImode, operands[0]);
1366 rtx a = gen_lowpart (DImode, operands[1]);
1367 rtx b = gen_lowpart (DImode, operands[2]);
1368
1369 rtx tmp = gen_reg_rtx (DImode);
1370 rtx flags = gen_reg_rtx (DImode);
1371
1372 emit_insn (gen_insn_fsingle_add1 (tmp, a, b));
1373 emit_insn (gen_insn_fsingle_addsub2 (tmp, tmp, a, b));
1374 emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
1375 emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
1376
1377 DONE;
1378 })
1379
1380 (define_expand "subsf3"
1381 [(set (match_operand:SF 0 "register_operand" "")
1382 (minus:SF (match_operand:SF 1 "register_operand" "")
1383 (match_operand:SF 2 "register_operand" "")))]
1384 ""
1385 {
1386 rtx result = gen_lowpart (DImode, operands[0]);
1387 rtx a = gen_lowpart (DImode, operands[1]);
1388 rtx b = gen_lowpart (DImode, operands[2]);
1389
1390 rtx tmp = gen_reg_rtx (DImode);
1391 rtx flags = gen_reg_rtx (DImode);
1392
1393 emit_insn (gen_insn_fsingle_sub1 (tmp, a, b));
1394 emit_insn (gen_insn_fsingle_addsub2 (tmp, tmp, a, b));
1395 emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
1396 emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
1397
1398 DONE;
1399 })
1400
1401 (define_expand "mulsf3"
1402 [(set (match_operand:SF 0 "register_operand" "")
1403 (mult:SF (match_operand:SF 1 "register_operand" "")
1404 (match_operand:SF 2 "register_operand" "")))]
1405 ""
1406 {
1407 rtx result = gen_lowpart (DImode, operands[0]);
1408 rtx a = gen_lowpart (DImode, operands[1]);
1409 rtx b = gen_lowpart (DImode, operands[2]);
1410
1411 rtx tmp1 = gen_reg_rtx (DImode);
1412 rtx tmp2 = gen_reg_rtx (DImode);
1413 rtx flags = gen_reg_rtx (DImode);
1414
1415 emit_insn (gen_insn_fsingle_mul1 (tmp1, a, b));
1416 emit_insn (gen_insn_fsingle_mul2 (tmp2, tmp1, b));
1417 emit_insn (gen_insn_fsingle_pack1 (flags, tmp2));
1418 emit_insn (gen_insn_fsingle_pack2 (result, tmp2, flags));
1419
1420 DONE;
1421 })
1422
1423 (define_expand "adddf3"
1424 [(set (match_operand:DF 0 "register_operand" "")
1425 (plus:DF (match_operand:DF 1 "register_operand" "")
1426 (match_operand:DF 2 "register_operand" "")))]
1427 ""
1428 {
1429 rtx result = gen_lowpart (DImode, operands[0]);
1430 rtx a = gen_lowpart (DImode, operands[1]);
1431 rtx b = gen_lowpart (DImode, operands[2]);
1432
1433 rtx min = gen_reg_rtx (DImode);
1434 rtx max = gen_reg_rtx (DImode);
1435 rtx flags = gen_reg_rtx (DImode);
1436
1437 emit_insn (gen_insn_fdouble_unpack_min (min, a, b));
1438 emit_insn (gen_insn_fdouble_unpack_max (max, a, b));
1439 emit_insn (gen_insn_fdouble_add_flags (flags, a, b));
1440 emit_insn (gen_insn_fdouble_addsub (max, max, min, flags));
1441 emit_insn (gen_insn_fdouble_pack1 (result, max, flags));
1442 emit_insn (gen_insn_fdouble_pack2 (result, result, max, const0_rtx));
1443
1444 DONE;
1445 })
1446
1447 (define_expand "subdf3"
1448 [(set (match_operand:DF 0 "register_operand" "")
1449 (minus: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_sub_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
1471 (define_expand "muldf3"
1472 [(set (match_operand:DF 0 "register_operand" "")
1473 (mult:DF (match_operand:DF 1 "register_operand" "")
1474 (match_operand:DF 2 "register_operand" "")))]
1475 ""
1476 ;; TODO: Decide if we should not inline this with -Os.
1477 ;; "optimize_function_for_speed_p (cfun)"
1478 {
1479 rtx result = gen_lowpart (DImode, operands[0]);
1480 rtx a = gen_lowpart (DImode, operands[1]);
1481 rtx b = gen_lowpart (DImode, operands[2]);
1482
1483 rtx a_unpacked = gen_reg_rtx (DImode);
1484 rtx b_unpacked = gen_reg_rtx (DImode);
1485 rtx flags = gen_reg_rtx (DImode);
1486
1487 rtx low1 = gen_reg_rtx (DImode);
1488 rtx low = gen_reg_rtx (DImode);
1489 rtx low_carry = gen_reg_rtx (DImode);
1490
1491 rtx mid = gen_reg_rtx (DImode);
1492 rtx mid_l32 = gen_reg_rtx (DImode);
1493 rtx mid_r32 = gen_reg_rtx (DImode);
1494
1495 rtx high1 = gen_reg_rtx (DImode);
1496 rtx high = gen_reg_rtx (DImode);
1497 rtx high1_plus_mid_r32 = gen_reg_rtx (DImode);
1498
1499 /* NOTE: We compute using max(a, 0) and max(b, 0) rather than
1500 min(a, b) and max(a, b) because for multiply we just need to unpack,
1501 we don't actually care which is min and which is max. And this
1502 formulation gives the scheduler more freedom in case one of a or b
1503 would stall at the start of this code sequence. */
1504 emit_insn (gen_insn_fdouble_unpack_max (a_unpacked, a, const0_rtx));
1505 emit_insn (gen_insn_fdouble_unpack_max (b_unpacked, b, const0_rtx));
1506 emit_insn (gen_insn_fdouble_mul_flags (flags, a, b));
1507
1508 /* This depends on the fact that the high few bits of the unpacked
1509 mantissa are zero, so we can't have a carry out from the mid sum. */
1510 emit_insn (gen_insn_mul_lu_lu (low1, a_unpacked, b_unpacked));
1511 emit_insn (gen_insn_mul_hu_lu (mid, a_unpacked, b_unpacked));
1512 emit_insn (gen_insn_mula_hu_lu (mid, mid, b_unpacked, a_unpacked));
1513 emit_insn (gen_insn_mul_hu_hu (high1, a_unpacked, b_unpacked));
1514
1515 emit_insn (gen_ashldi3 (mid_l32, mid, GEN_INT (32)));
1516 emit_insn (gen_lshrdi3 (mid_r32, mid, GEN_INT (32)));
1517
1518 emit_insn (gen_adddi3 (high1_plus_mid_r32, high1, mid_r32));
1519
1520 emit_insn (gen_adddi3 (low, low1, mid_l32));
1521 emit_insn (gen_insn_cmpltu_didi (low_carry, low, mid_l32));
1522
1523 emit_insn (gen_adddi3 (high, high1_plus_mid_r32, low_carry));
1524
1525 emit_insn (gen_insn_fdouble_pack1 (result, high, flags));
1526 emit_insn (gen_insn_fdouble_pack2 (result, result, high, low));
1527
1528 DONE;
1529 })
1530
1531 \f
1532 ;;
1533 ;; Shifts
1534 ;;
1535
1536 (define_insn "ashl<mode>3"
1537 [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
1538 (ashift:I48MODE
1539 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1540 (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
1541 ""
1542 "@
1543 shl<x>i\t%0, %r1, %2
1544 shl<x>\t%0, %r1, %r2"
1545 [(set_attr "type" "<shift_pipe>,<shift_pipe>")])
1546
1547 (define_insn "*ashlsi3_sext"
1548 [(set (match_operand:DI 0 "register_operand" "=r,r")
1549 (sign_extend:DI
1550 (ashift:SI
1551 (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1552 (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
1553 ""
1554 "@
1555 shlxi\t%0, %r1, %2
1556 shlx\t%0, %r1, %r2"
1557 [(set_attr "type" "X01,X01")])
1558
1559 (define_insn "ashr<mode>3"
1560 [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
1561 (ashiftrt:I48MODE
1562 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1563 (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
1564 ""
1565 "@
1566 shrsi\t%0, %r1, %2
1567 shrs\t%0, %r1, %r2")
1568
1569 (define_insn "*ashrsi3_sext"
1570 [(set (match_operand:DI 0 "register_operand" "=r,r")
1571 (sign_extend:DI
1572 (ashiftrt:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1573 (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
1574 ""
1575 "@
1576 shrsi\t%0, %r1, %2
1577 shrs\t%0, %r1, %r2")
1578
1579 (define_insn "lshr<mode>3"
1580 [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
1581 (lshiftrt:I48MODE
1582 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1583 (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
1584 ""
1585 "@
1586 shru<x>i\t%0, %r1, %2
1587 shru<x>\t%0, %r1, %r2"
1588 [(set_attr "type" "<shift_pipe>,<shift_pipe>")])
1589
1590 (define_insn "*lshrsi3_sext"
1591 [(set (match_operand:DI 0 "register_operand" "=r,r")
1592 (sign_extend:DI
1593 (lshiftrt:SI
1594 (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
1595 (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
1596 ""
1597 "@
1598 shruxi\t%0, %r1, %2
1599 shrux\t%0, %r1, %r2"
1600 [(set_attr "type" "X01,X01")])
1601
1602 (define_insn "rotldi3"
1603 [(set (match_operand:DI 0 "register_operand" "=r,r")
1604 (rotate:DI (match_operand:DI 1 "reg_or_0_operand" "rO,rO")
1605 (match_operand:SI 2 "reg_or_u6bit_operand" "I,rO")))]
1606 ""
1607 "@
1608 rotli\t%0, %r1, %2
1609 rotl\t%0, %r1, %r2")
1610
1611 (define_insn "insn_shl16insli"
1612 [(set (match_operand:DI 0 "register_operand" "=r,r")
1613 (ior:DI
1614 (ashift:DI
1615 (match_operand:DI 1 "reg_or_0_operand" "rO,rO")
1616 (const_int 16))
1617 (match_operand:DI 2 "u16bit_or_const_symbolic_operand" "O,KT")))]
1618 ""
1619 "@
1620 shli\t%0, %r1, 16
1621 shl16insli\t%0, %r1, %H2"
1622 [(set_attr "type" "*,X01")])
1623
1624 (define_insn "insn_addr_shl16insli<bitsuffix>"
1625 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1626 (unspec:I48MODE
1627 [(match_operand:I48MODE 1 "reg_or_0_operand" "rO")
1628 (match_operand:I48MODE 2 "const_symbolic_operand" "T")]
1629 UNSPEC_INSN_ADDR_SHL16INSLI))]
1630 ""
1631 "shl16insli\t%0, %r1, %H2"
1632 [(set_attr "type" "X01")])
1633
1634 \f
1635 ;;
1636 ;; Compares
1637 ;;
1638
1639 (define_expand "cstore<mode>4"
1640 [(set (match_operand:DI 0 "register_operand" "")
1641 (match_operator:DI 1 "ordered_comparison_operator"
1642 [(match_operand:FI48MODE 2 "reg_or_cint_operand" "")
1643 (match_operand:FI48MODE 3 "reg_or_cint_operand" "")]))]
1644 ""
1645 {
1646 if (!tilegx_emit_setcc (operands, GET_MODE (operands[2])))
1647 FAIL;
1648 else
1649 DONE;
1650 })
1651
1652
1653 (define_insn "insn_cmpne_<I48MODE:mode><I48MODE2:mode>"
1654 [(set (match_operand:I48MODE2 0 "register_operand" "=r")
1655 (ne:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
1656 (match_operand:I48MODE 2 "reg_or_cint_operand" "rO")))]
1657 ""
1658 "cmpne\t%0, %r1, %r2")
1659
1660 (define_insn "insn_cmpeq_<I48MODE:mode><I48MODE2:mode>"
1661 [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1662 (eq:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "%rO,rO")
1663 (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
1664 ""
1665 "@
1666 cmpeqi\t%0, %r1, %2
1667 cmpeq\t%0, %r1, %r2")
1668
1669 (define_insn "insn_cmplts_<I48MODE:mode><I48MODE2:mode>"
1670 [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1671 (lt:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1672 (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
1673 ""
1674 "@
1675 cmpltsi\t%0, %r1, %2
1676 cmplts\t%0, %r1, %r2")
1677
1678 (define_insn "insn_cmpltu_<I48MODE:mode><I48MODE2:mode>"
1679 [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1680 (ltu:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1681 (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
1682 ""
1683 "@
1684 cmpltui\t%0, %r1, %2
1685 cmpltu\t%0, %r1, %r2"
1686 [(set_attr "type" "X01,*")])
1687
1688 (define_insn "insn_cmples_<I48MODE:mode><I48MODE2:mode>"
1689 [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1690 (le:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1691 (match_operand:I48MODE 2 "reg_or_cint_operand" "L,rO")))]
1692 ""
1693 "@
1694 cmpltsi\t%0, %r1, %P2
1695 cmples\t%0, %r1, %r2")
1696
1697 (define_insn "insn_cmpleu_<I48MODE:mode><I48MODE2:mode>"
1698 [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
1699 (leu:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
1700 (match_operand:I48MODE 2 "reg_or_cint_operand" "Q,rO")))]
1701 ""
1702 "@
1703 cmpltui\t%0, %r1, %P2
1704 cmpleu\t%0, %r1, %r2"
1705 [(set_attr "type" "X01,*")])
1706
1707 \f
1708 ;;
1709 ;; Logical ops
1710 ;;
1711
1712 (define_insn "and<mode>3"
1713 [(set (match_operand:IVNMODE 0 "register_operand" "=r,r,r,r")
1714 (and:IVNMODE (match_operand:IVNMODE 1 "reg_or_0_operand" "%rO,rO,0,rO")
1715 (match_operand:IVNMODE 2 "and_operand" "I,S,M,rO")))]
1716 ""
1717 "@
1718 andi\t%0, %r1, %2
1719 bfextu\t%0, %r1, %M2
1720 bfins\t%0, zero, %m2
1721 and\t%0, %r1, %r2"
1722 [(set_attr "type" "*,X0,X0,*")])
1723
1724 (define_insn "*andsi3_sext"
1725 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
1726 (sign_extend:DI
1727 (and:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,0,rO")
1728 (match_operand:SI 2 "and_operand" "I,S,M,rO"))))]
1729 ""
1730 "@
1731 andi\t%0, %r1, %2
1732 bfextu\t%0, %r1, %M2
1733 bfins\t%0, zero, %m2
1734 and\t%0, %r1, %r2"
1735 [(set_attr "type" "*,X0,X0,*")])
1736
1737 (define_insn "anddi3"
1738 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
1739 (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO,rO,0,rO")
1740 (match_operand:DI 2 "and_operand" "I,Z0,Z1,S,M,rO")))]
1741 ""
1742 "@
1743 andi\t%0, %r1, %2
1744 v4int_l\t%0, zero, %r1
1745 v4int_h\t%0, %r1, zero
1746 bfextu\t%0, %r1, %M2
1747 bfins\t%0, zero, %m2
1748 and\t%0, %r1, %r2"
1749 [(set_attr "type" "*,X01,X01,X0,X0,*")])
1750
1751 (define_insn "ior<mode>3"
1752 [(set (match_operand:IVMODE 0 "register_operand" "=r,r")
1753 (ior:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "%rO,rO")
1754 (match_operand:IVMODE 2 "reg_or_s8bit_operand" "rO,I")))]
1755 ""
1756 "@
1757 or\t%0, %r1, %r2
1758 ori\t%0, %r1, %2"
1759 [(set_attr "type" "*,X01")])
1760
1761 (define_insn "*iorsi3_sext"
1762 [(set (match_operand:DI 0 "register_operand" "=r,r")
1763 (sign_extend:DI
1764 (ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
1765 (match_operand:SI 2 "reg_or_s8bit_operand" "rO,I"))))]
1766 ""
1767 "@
1768 or\t%0, %r1, %r2
1769 ori\t%0, %r1, %2"
1770 [(set_attr "type" "*,X01")])
1771
1772 (define_insn "xor<mode>3"
1773 [(set (match_operand:IVMODE 0 "register_operand" "=r,r")
1774 (xor:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "%rO,rO")
1775 (match_operand:IVMODE 2 "reg_or_s8bit_operand" "rO,I")))]
1776 ""
1777 "@
1778 xor\t%0, %r1, %r2
1779 xori\t%0, %r1, %2"
1780 [(set_attr "type" "*,X01")])
1781
1782 (define_insn "*xorsi3_sext"
1783 [(set (match_operand:DI 0 "register_operand" "=r,r")
1784 (sign_extend:DI
1785 (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
1786 (match_operand:SI 2 "reg_or_s8bit_operand" "rO,I"))))]
1787 ""
1788 "@
1789 xor\t%0, %r1, %r2
1790 xori\t%0, %r1, %2"
1791 [(set_attr "type" "*,X01")])
1792
1793 (define_insn "clzdi2"
1794 [(set (match_operand:DI 0 "register_operand" "=r")
1795 (clz:DI (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1796 ""
1797 "clz\t%0, %r1"
1798 [(set_attr "type" "Y0")])
1799
1800 (define_expand "clzsi2"
1801 [(set (match_dup 2)
1802 (ashift:DI (match_operand:SI 1 "reg_or_0_operand" "")
1803 (const_int 32)))
1804 (set (subreg:DI (match_operand:SI 0 "register_operand" "") 0)
1805 (clz:DI (match_dup 2)))]
1806 ""
1807 {
1808 operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);
1809 operands[2] = gen_reg_rtx (DImode);
1810 })
1811
1812 (define_insn "ctz<mode>2"
1813 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1814 (ctz:I48MODE (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1815 ""
1816 "ctz\t%0, %r1"
1817 [(set_attr "type" "Y0")])
1818
1819 (define_insn "popcount<mode>2"
1820 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1821 (popcount:I48MODE (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1822 ""
1823 "pcnt\t%0, %r1"
1824 [(set_attr "type" "Y0")])
1825
1826 (define_expand "parity<mode>2"
1827 [(set (match_operand:I48MODE 0 "register_operand" "")
1828 (parity:I48MODE (match_operand:DI 1 "reg_or_0_operand" "")))]
1829 ""
1830 {
1831 rtx tmp = gen_reg_rtx (<MODE>mode);
1832 emit_insn (gen_popcount<mode>2 (tmp, operands[1]));
1833 emit_insn (gen_and<mode>3 (operands[0], tmp, const1_rtx));
1834 DONE;
1835 })
1836
1837 (define_insn "bswapdi2"
1838 [(set (match_operand:DI 0 "register_operand" "=r")
1839 (bswap:DI (match_operand:DI 1 "reg_or_0_operand" "rO")))]
1840 ""
1841 "revbytes\t%0, %r1"
1842 [(set_attr "type" "Y0")])
1843
1844 (define_expand "bswapsi2"
1845 [(set (match_operand:SI 0 "register_operand" "")
1846 (bswap:SI (match_operand:SI 1 "reg_or_0_operand" "")))]
1847 ""
1848 {
1849 rtx tmp = gen_reg_rtx (DImode);
1850 emit_insn (gen_bswapdi2 (tmp, gen_lowpart (DImode, operands[1])));
1851 emit_insn (gen_ashrdi3 (gen_lowpart (DImode, operands[0]),
1852 tmp, GEN_INT (32)));
1853 DONE;
1854 })
1855
1856 (define_insn "one_cmpl<mode>2"
1857 [(set (match_operand:IVMODE 0 "register_operand" "=r")
1858 (not:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "rO")))]
1859 ""
1860 "nor\t%0, %r1, zero")
1861
1862 \f
1863 ;;
1864 ;; Conditional moves
1865 ;;
1866
1867 (define_expand "mov<mode>cc"
1868 [(set (match_operand:I48MODE 0 "register_operand" "")
1869 (if_then_else:I48MODE
1870 (match_operand 1 "comparison_operator" "")
1871 (match_operand:I48MODE 2 "reg_or_0_operand" "")
1872 (match_operand:I48MODE 3 "reg_or_0_operand" "")))]
1873 ""
1874 { operands[1] = tilegx_emit_conditional_move (operands[1]); })
1875
1876 (define_insn "movcc_insn_<I48MODE2:mode><I48MODE:mode>"
1877 [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r,r")
1878 (if_then_else:I48MODE
1879 (match_operator 4 "eqne_operator"
1880 [(match_operand:I48MODE2 1 "reg_or_0_operand" "rO,rO,rO,rO")
1881 (const_int 0)])
1882 (match_operand:I48MODE 2 "reg_or_0_operand" "rO,O,rO,0")
1883 (match_operand:I48MODE 3 "reg_or_0_operand" "O,rO,0,rO")))]
1884 ""
1885 "@
1886 m%c4\t%0, %r1, %r2
1887 m%C4\t%0, %r1, %r3
1888 cmov%d4z\t%0, %r1, %r2
1889 cmov%D4z\t%0, %r1, %r3"
1890 [(set_attr "type" "*,*,Y0,Y0")])
1891
1892 (define_expand "insn_mz"
1893 [(set (match_operand:DI 0 "register_operand" "")
1894 (if_then_else:DI
1895 (eq (match_operand:DI 1 "reg_or_0_operand" "")
1896 (const_int 0))
1897 (match_operand:DI 2 "reg_or_0_operand" "")
1898 (const_int 0)))])
1899
1900 (define_expand "insn_mnz"
1901 [(set (match_operand:DI 0 "register_operand" "")
1902 (if_then_else:DI
1903 (ne (match_operand:DI 1 "reg_or_0_operand" "")
1904 (const_int 0))
1905 (match_operand:DI 2 "reg_or_0_operand" "")
1906 (const_int 0)))])
1907
1908 (define_expand "insn_cmoveqz"
1909 [(set (match_operand:DI 0 "register_operand" "")
1910 (if_then_else:DI
1911 (eq (match_operand:DI 2 "reg_or_0_operand" "")
1912 (const_int 0))
1913 (match_operand:DI 3 "reg_or_0_operand" "")
1914 (match_operand:DI 1 "reg_or_0_operand" "")))])
1915
1916 (define_expand "insn_cmovnez"
1917 [(set (match_operand:DI 0 "register_operand" "")
1918 (if_then_else:DI
1919 (ne (match_operand:DI 2 "reg_or_0_operand" "")
1920 (const_int 0))
1921 (match_operand:DI 3 "reg_or_0_operand" "")
1922 (match_operand:DI 1 "reg_or_0_operand" "")))])
1923
1924 \f
1925 ;;
1926 ;; Conversions
1927 ;;
1928
1929 (define_insn "zero_extendqi<mode>2"
1930 [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1931 (zero_extend:I48MODE (match_operand:QI 1 "move_operand" "rO,U,m")))]
1932 ""
1933 "@
1934 bfextu\t%0, %r1, 0, 7
1935 ld1u\t%0, %1
1936 ld1u_add\t%0, %I1, %i1"
1937 [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1938
1939 (define_insn "zero_extendhi<mode>2"
1940 [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1941 (zero_extend:I48MODE (match_operand:HI 1 "move_operand" "rO,U,m")))]
1942 ""
1943 "@
1944 bfextu\t%0, %r1, 0, 15
1945 ld2u\t%0, %1
1946 ld2u_add\t%0, %I1, %i1"
1947 [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1948
1949 (define_insn "zero_extendsidi2"
1950 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1951 (zero_extend:DI (match_operand:SI 1 "move_operand" "rO,U,m")))]
1952 ""
1953 "@
1954 v4int_l\t%0, zero, %r1
1955 ld4u\t%0, %1
1956 ld4u_add\t%0, %I1, %i1"
1957 [(set_attr "type" "X01,Y2_2cycle,X1_2cycle")])
1958
1959 (define_insn "extendqi<mode>2"
1960 [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1961 (sign_extend:I48MODE (match_operand:QI 1 "move_operand" "rO,U,m")))]
1962 ""
1963 "@
1964 bfexts\t%0, %r1, 0, 7
1965 ld1s\t%0, %1
1966 ld1s_add\t%0, %I1, %i1"
1967 [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1968
1969 (define_insn "extendhi<mode>2"
1970 [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
1971 (sign_extend:I48MODE (match_operand:HI 1 "move_operand" "rO,U,m")))]
1972 ""
1973 "@
1974 bfexts\t%0, %r1, 0, 15
1975 ld2s\t%0, %1
1976 ld2s_add\t%0, %I1, %i1"
1977 [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
1978
1979 ;; All SImode integer registers should already be in sign-extended
1980 ;; form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can therefore
1981 ;; get rid of register->register instructions if we constrain the
1982 ;; source to be in the same register as the destination.
1983 (define_insn_and_split "extendsidi2"
1984 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1985 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,U,m")))]
1986 ""
1987 "@
1988 #
1989 ld4s\t%0, %1
1990 ld4s_add\t%0, %I1, %i1"
1991 "&& reload_completed && register_operand (operands[1], VOIDmode)"
1992 [(const_int 0)]
1993 {
1994 emit_note (NOTE_INSN_DELETED);
1995 DONE;
1996 }
1997 [(set_attr "type" "*,Y2_2cycle,X1_2cycle")])
1998
1999 ;; Integer truncation patterns. Truncating SImode values to smaller
2000 ;; modes is a no-op, as it is for most other GCC ports. Truncating
2001 ;; DImode values to SImode is not a no-op since we
2002 ;; need to make sure that the lower 32 bits are properly sign-extended
2003 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2004 ;; smaller than SImode is equivalent to two separate truncations:
2005 ;;
2006 ;; A B
2007 ;; DI ---> HI == DI ---> SI ---> HI
2008 ;; DI ---> QI == DI ---> SI ---> QI
2009 ;;
2010 ;; Step A needs a real instruction but step B does not.
2011
2012 (define_insn "truncdisi2"
2013 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,U,m")
2014 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
2015 ""
2016 "@
2017 addxi\t%0, %r1, 0
2018 st4\t%0, %r1
2019 st4_add\t%I0, %r1, %i0"
2020 [(set_attr "type" "Y01,Y2,X1")])
2021
2022 (define_insn "truncdihi2"
2023 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,U,m")
2024 (truncate:HI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
2025 ""
2026 "@
2027 addxi\t%0, %r1, 0
2028 st2\t%0, %r1
2029 st2_add\t%I0, %r1, %i0"
2030 [(set_attr "type" "Y01,Y2,X1")])
2031
2032 (define_insn "truncdiqi2"
2033 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,U,m")
2034 (truncate:QI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
2035 ""
2036 "@
2037 addxi\t%0, %r1, 0
2038 st1\t%0, %r1
2039 st1_add\t%I0, %r1, %i0"
2040 [(set_attr "type" "Y01,Y2,X1")])
2041
2042 ;; Combiner patterns to optimize away unnecessary truncates.
2043
2044 (define_insn "*zero_extendsidi_truncdisi"
2045 [(set (match_operand:DI 0 "register_operand" "=r")
2046 (zero_extend:DI
2047 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))))]
2048 ""
2049 "v4int_l\t%0, zero, %r1"
2050 [(set_attr "type" "X01")])
2051
2052 (define_insn "*addsi_truncdisi"
2053 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2054 (plus:SI
2055 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO"))
2056 (match_operand:SI 2 "add_operand" "r,I,JT")))]
2057 ""
2058 "@
2059 addx\t%0, %r1, %r2
2060 addxi\t%0, %r1, %2
2061 addxli\t%0, %r1, %H2"
2062 [(set_attr "type" "*,*,X01")])
2063
2064 (define_insn "*addsi_truncdisi2"
2065 [(set (match_operand:SI 0 "register_operand" "=r")
2066 (plus:SI
2067 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))
2068 (truncate:SI (match_operand:DI 2 "reg_or_0_operand" "rO"))))]
2069 ""
2070 "addx\t%0, %r1, %r2")
2071
2072 (define_insn "*ashldi_truncdisi"
2073 [(set (match_operand:DI 0 "register_operand" "=r")
2074 (ashift:DI
2075 (match_operand:DI 1 "reg_or_0_operand" "rO")
2076 (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
2077 ""
2078 "shl\t%0, %r1, %r2")
2079
2080 (define_insn "*ashlsi_truncdisi"
2081 [(set (match_operand:SI 0 "register_operand" "=r,r")
2082 (ashift:SI
2083 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO,rO"))
2084 (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
2085 ""
2086 "@
2087 shlxi\t%0, %r1, %2
2088 shlx\t%0, %r1, %r2"
2089 [(set_attr "type" "X01,X01")])
2090
2091 (define_insn "*ashlsi_truncdisi2"
2092 [(set (match_operand:SI 0 "register_operand" "=r")
2093 (ashift:SI
2094 (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))
2095 (truncate:SI (match_operand:DI 2 "reg_or_0_operand" "rO"))))]
2096 ""
2097 "shlx\t%0, %r1, %r2"
2098 [(set_attr "type" "X01")])
2099
2100 (define_insn "*ashrdi3_truncdisi"
2101 [(set (match_operand:DI 0 "register_operand" "=r")
2102 (ashiftrt: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 "shrs\t%0, %r1, %r2")
2107
2108 (define_insn "*lshrsi_truncdisi"
2109 [(set (match_operand:SI 0 "register_operand" "=r,r")
2110 (lshiftrt: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 shruxi\t%0, %r1, %2
2116 shrux\t%0, %r1, %r2"
2117 [(set_attr "type" "X01,X01")])
2118
2119 (define_insn "*lshrsi_truncdisi2"
2120 [(set (match_operand:SI 0 "register_operand" "=r")
2121 (lshiftrt: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 "shrux\t%0, %r1, %r2"
2126 [(set_attr "type" "X01")])
2127
2128 (define_insn "*lshrdi_truncdisi"
2129 [(set (match_operand:DI 0 "register_operand" "=r")
2130 (lshiftrt: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 "shru\t%0, %r1, %r2")
2135
2136 (define_insn "*rotldi_truncdisi"
2137 [(set (match_operand:DI 0 "register_operand" "=r")
2138 (rotate:DI
2139 (match_operand:DI 1 "reg_or_0_operand" "rO")
2140 (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
2141 ""
2142 "rotl\t%0, %r1, %r2")
2143
2144 ;; Integer to floating point conversions
2145
2146 (define_expand "floatsisf2"
2147 [(set (match_operand:SF 0 "register_operand" "")
2148 (float:SI (match_operand:SI 1 "register_operand" "")))]
2149 ""
2150 {
2151 rtx result = gen_lowpart (DImode, operands[0]);
2152 rtx a = operands[1];
2153
2154 rtx nega = gen_reg_rtx (SImode);
2155 rtx exp = gen_reg_rtx (DImode);
2156 rtx sign = gen_reg_rtx (DImode);
2157 rtx abs = gen_reg_rtx (DImode);
2158 rtx flags = gen_reg_rtx (DImode);
2159 rtx tmp1 = gen_reg_rtx (DImode);
2160 rtx tmp2 = gen_reg_rtx (DImode);
2161
2162 emit_move_insn (exp, GEN_INT (0x9e));
2163
2164 emit_insn (gen_negsi2 (nega, a));
2165
2166 emit_insn (gen_insn_cmplts_sisi (gen_lowpart (SImode, sign), a, const0_rtx));
2167 emit_insn (gen_insn_cmoveqz (abs, gen_lowpart (DImode, nega), sign,
2168 gen_lowpart (DImode, a)));
2169
2170 emit_insn (gen_insn_bfins (tmp1, exp, sign, GEN_INT (10), GEN_INT (10)));
2171 emit_insn (gen_insn_bfins (tmp2, tmp1, abs, GEN_INT (32), GEN_INT (63)));
2172 emit_insn (gen_insn_fsingle_pack1 (flags, tmp2));
2173 emit_insn (gen_insn_fsingle_pack2 (result, tmp2, flags));
2174 DONE;
2175 })
2176
2177 (define_expand "floatunssisf2"
2178 [(set (match_operand:SF 0 "register_operand" "")
2179 (float:SI (match_operand:SI 1 "register_operand" "")))]
2180 ""
2181 {
2182 rtx result = gen_lowpart (DImode, operands[0]);
2183 rtx a = operands[1];
2184
2185 rtx exp = gen_reg_rtx (DImode);
2186 rtx flags = gen_reg_rtx (DImode);
2187 rtx tmp = gen_reg_rtx (DImode);
2188
2189 emit_move_insn (exp, GEN_INT (0x9e));
2190 emit_insn (gen_insn_bfins (tmp, exp, gen_lowpart (DImode, a),
2191 GEN_INT (32), GEN_INT (63)));
2192 emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
2193 emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
2194 DONE;
2195 })
2196
2197 (define_expand "floatsidf2"
2198 [(set (match_operand:DF 0 "register_operand" "")
2199 (float:SI (match_operand:SI 1 "register_operand" "")))]
2200 ""
2201 {
2202 rtx result = gen_lowpart (DImode, operands[0]);
2203 rtx a = gen_lowpart (DImode, operands[1]);
2204
2205 rtx nega = gen_reg_rtx (DImode);
2206 rtx exp = gen_reg_rtx (DImode);
2207 rtx sign = gen_reg_rtx (DImode);
2208 rtx abs = gen_reg_rtx (DImode);
2209 rtx tmp1 = gen_reg_rtx (DImode);
2210 rtx tmp2 = gen_reg_rtx (DImode);
2211 rtx tmp3 = gen_reg_rtx (DImode);
2212
2213 emit_move_insn (exp, GEN_INT (0x21b00));
2214
2215 emit_insn (gen_negdi2 (nega, a));
2216
2217 emit_insn (gen_insn_cmplts_didi (sign, a, const0_rtx));
2218 emit_insn (gen_insn_cmovnez (abs, a, sign, nega));
2219
2220 emit_insn (gen_ashldi3 (tmp1, abs, GEN_INT (4)));
2221 emit_insn (gen_insn_bfins (tmp2, exp, sign, GEN_INT (20), GEN_INT (20)));
2222 emit_insn (gen_insn_fdouble_pack1 (tmp3, tmp1, tmp2));
2223 emit_insn (gen_insn_fdouble_pack2 (result, tmp3, tmp1, const0_rtx));
2224 DONE;
2225 })
2226
2227 (define_expand "floatunssidf2"
2228 [(set (match_operand:DF 0 "register_operand" "")
2229 (float:SI (match_operand:SI 1 "register_operand" "")))]
2230 ""
2231 {
2232 rtx result = gen_lowpart (DImode, operands[0]);
2233 rtx a = gen_lowpart (DImode, operands[1]);
2234
2235 rtx exp = gen_reg_rtx (DImode);
2236 rtx tmp1 = gen_reg_rtx (DImode);
2237 rtx tmp2 = gen_reg_rtx (DImode);
2238
2239 emit_move_insn (exp, GEN_INT (0x21b00));
2240 emit_insn (gen_insn_bfins (tmp1, const0_rtx, a, GEN_INT (4), GEN_INT (35)));
2241 emit_insn (gen_insn_fdouble_pack1 (tmp2, tmp1, exp));
2242 emit_insn (gen_insn_fdouble_pack2 (result, tmp2, tmp1, const0_rtx));
2243 DONE;
2244 })
2245
2246 \f
2247 ;;
2248 ;; Multiplies
2249 ;;
2250
2251 (define_insn "mulsi3"
2252 [(set (match_operand:SI 0 "register_operand" "=r")
2253 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rO")
2254 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
2255 ""
2256 "mulx\t%0, %r1, %r2"
2257 [(set_attr "type" "Y0_2cycle")])
2258
2259 (define_insn "mulsidi3"
2260 [(set (match_operand:DI 0 "register_operand" "=r")
2261 (mult:DI (sign_extend:DI
2262 (match_operand:SI 1 "reg_or_0_operand" "%rO"))
2263 (sign_extend:DI
2264 (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
2265 ""
2266 "mul_ls_ls\t%0, %r1, %r2"
2267 [(set_attr "type" "Y0_2cycle")])
2268
2269 (define_insn "umulsidi3"
2270 [(set (match_operand:DI 0 "register_operand" "=r")
2271 (mult:DI (zero_extend:DI
2272 (match_operand:SI 1 "reg_or_0_operand" "%rO"))
2273 (zero_extend:DI
2274 (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
2275 ""
2276 "mul_lu_lu\t%0, %r1, %r2"
2277 [(set_attr "type" "Y0_2cycle")])
2278
2279 (define_expand "muldi3"
2280 [(set (match_operand:DI 0 "register_operand" "")
2281 (unspec:DI [(match_operand:DI 1 "nonmemory_operand" "")
2282 (match_operand:DI 2 "nonmemory_operand" "")]
2283 UNSPEC_INSN_MUL_HU_LU))
2284 (set (match_dup 0)
2285 (unspec:DI [(match_dup 0) (match_dup 2) (match_dup 1)]
2286 UNSPEC_INSN_MULA_HU_LU))
2287 (set (match_dup 0)
2288 (ashift:DI (match_dup 0) (const_int 32)))
2289 (set (match_dup 0)
2290 (unspec:DI [(match_dup 0) (match_dup 2) (match_dup 1)]
2291 UNSPEC_INSN_MULA_LU_LU))]
2292 ""
2293 {
2294 operands[1] = force_reg (DImode, operands[1]);
2295 operands[1] = make_safe_from (operands[1], operands[0]);
2296
2297 if (tilegx_expand_muldi (operands[0], operands[1], operands[2]))
2298 DONE;
2299 else
2300 {
2301 operands[2] = force_reg (DImode, operands[2]);
2302 operands[2] = make_safe_from (operands[2], operands[0]);
2303 }
2304 })
2305
2306 (define_insn "usmulsidi3"
2307 [(set (match_operand:DI 0 "register_operand" "=r")
2308 (mult:DI (zero_extend:DI
2309 (match_operand:SI 1 "reg_or_0_operand" "rO"))
2310 (sign_extend:DI
2311 (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
2312 ""
2313 "mul_ls_lu\t%0, %r2, %r1"
2314 [(set_attr "type" "X0_2cycle")])
2315
2316 (define_insn "maddsidi4"
2317 [(set (match_operand:DI 0 "register_operand" "=r")
2318 (plus:DI
2319 (mult:DI (sign_extend:DI
2320 (match_operand:SI 1 "reg_or_0_operand" "rO"))
2321 (sign_extend:DI
2322 (match_operand:SI 2 "reg_or_0_operand" "rO")))
2323 (match_operand:DI 3 "register_operand" "0")))]
2324 ""
2325 "mula_ls_ls\t%0, %r1, %r2"
2326 [(set_attr "type" "Y0_2cycle")])
2327
2328 (define_insn "umaddsidi4"
2329 [(set (match_operand:DI 0 "register_operand" "=r")
2330 (plus:DI
2331 (mult:DI (zero_extend:DI
2332 (match_operand:SI 1 "reg_or_0_operand" "rO"))
2333 (zero_extend:DI
2334 (match_operand:SI 2 "reg_or_0_operand" "rO")))
2335 (match_operand:DI 3 "register_operand" "0")))]
2336 ""
2337 "mula_lu_lu\t%0, %r1, %r2"
2338 [(set_attr "type" "Y0_2cycle")])
2339
2340 (define_expand "smulsi3_highpart"
2341 [(set (match_dup 3)
2342 (mult:DI (sign_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
2343 (sign_extend:DI (match_operand:SI 2 "reg_or_0_operand" ""))))
2344 (set (match_dup 4)
2345 (ashiftrt:DI (match_dup 3) (const_int 32)))
2346 (set (match_operand:SI 0 "register_operand" "")
2347 (truncate:SI (match_dup 4)))]
2348 ""
2349 {
2350 operands[3] = gen_reg_rtx (DImode);
2351 operands[4] = gen_reg_rtx (DImode);
2352 })
2353
2354 (define_expand "umulsi3_highpart"
2355 [(set (match_dup 3)
2356 (mult:DI (zero_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
2357 (zero_extend:DI (match_operand:SI 2 "reg_or_0_operand" ""))))
2358 (set (match_dup 4)
2359 (lshiftrt:DI (match_dup 3) (const_int 32)))
2360 (set (match_operand:SI 0 "register_operand" "")
2361 (truncate:SI (match_dup 4)))]
2362 ""
2363 {
2364 operands[3] = gen_reg_rtx (DImode);
2365 operands[4] = gen_reg_rtx (DImode);
2366 })
2367
2368 (define_expand "smuldi3_highpart"
2369 [(set (match_operand:DI 0 "register_operand" "")
2370 (truncate:DI
2371 (ashiftrt:TI
2372 (mult:TI (sign_extend:TI (match_operand:DI 1 "reg_or_0_operand" ""))
2373 (sign_extend:TI (match_operand:DI 2 "reg_or_0_operand" "")))
2374 (const_int 64))))]
2375 ""
2376 {
2377 tilegx_expand_smuldi3_highpart (operands[0], operands[1], operands[2]);
2378 DONE;
2379 })
2380
2381 (define_expand "umuldi3_highpart"
2382 [(set (match_operand:DI 0 "register_operand" "")
2383 (truncate:DI
2384 (lshiftrt:TI
2385 (mult:TI (zero_extend:TI (match_operand:DI 1 "reg_or_0_operand" ""))
2386 (zero_extend:TI (match_operand:DI 2 "reg_or_0_operand" "")))
2387 (const_int 64))))]
2388 ""
2389 {
2390 tilegx_expand_umuldi3_highpart (operands[0], operands[1], operands[2]);
2391 DONE;
2392 })
2393
2394 \f
2395 ;;
2396 ;; Divide stubs. These exist to work around a bug in expmed.c, which
2397 ;; will not attempt to convert a divide by constant into a multiply
2398 ;; unless there is a pattern for a divide of the same mode. The end
2399 ;; result is a 32-bit divide turns into 64-bit multiply.
2400 ;;
2401
2402 (define_expand "divsi3"
2403 [(set (match_operand:SI 0 "register_operand" "")
2404 (div:SI (match_operand:SI 1 "reg_or_0_operand" "")
2405 (match_operand:SI 2 "reg_or_0_operand" "")))]
2406 ""
2407 {
2408 FAIL;
2409 })
2410
2411 (define_expand "udivsi3"
2412 [(set (match_operand:SI 0 "register_operand" "")
2413 (udiv:SI (match_operand:SI 1 "reg_or_0_operand" "")
2414 (match_operand:SI 2 "reg_or_0_operand" "")))]
2415 ""
2416 {
2417 FAIL;
2418 })
2419
2420 \f
2421 ;;
2422 ;; Loops
2423 ;;
2424
2425 ;; Define the subtract-one-and-jump insns so loop.c knows what to
2426 ;; generate.
2427 (define_expand "doloop_end"
2428 [(use (match_operand 0 "" "")) ;; loop pseudo
2429 (use (match_operand 1 "" ""))] ;; label
2430 ""
2431 {
2432 if (optimize > 0 && flag_modulo_sched)
2433 {
2434 rtx s0;
2435 rtx bcomp;
2436 rtx loc_ref;
2437 machine_mode mode = GET_MODE (operands[0]);
2438
2439 /* only deal with loop counters in SImode or DImode */
2440 if (mode != SImode && mode != DImode)
2441 FAIL;
2442
2443 s0 = operands [0];
2444 emit_move_insn (s0, gen_rtx_PLUS (mode, s0, GEN_INT (-1)));
2445 bcomp = gen_rtx_NE(mode, s0, const0_rtx);
2446 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
2447 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2448 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
2449 loc_ref, pc_rtx)));
2450 DONE;
2451 }
2452 else
2453 FAIL;
2454
2455 })
2456
2457 ;;
2458 ;; Prologue/epilogue
2459 ;;
2460 (define_expand "prologue"
2461 [(const_int 0)]
2462 ""
2463 {
2464 tilegx_expand_prologue ();
2465 DONE;
2466 })
2467
2468 (define_expand "epilogue"
2469 [(const_int 0)]
2470 ""
2471 {
2472 tilegx_expand_epilogue (false);
2473 DONE;
2474 })
2475
2476 (define_expand "sibcall_epilogue"
2477 [(const_int 0)]
2478 ""
2479 {
2480 tilegx_expand_epilogue (true);
2481 DONE;
2482 })
2483
2484 ;;
2485 ;; Stack manipulations
2486 ;;
2487
2488 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
2489 (define_expand "allocate_stack"
2490 [(set (match_operand 0 "register_operand" "")
2491 (minus (reg 54) (match_operand 1 "nonmemory_operand" "")))
2492 (set (reg 54)
2493 (minus (reg 54) (match_dup 1)))]
2494 ""
2495 "tilegx_allocate_stack (operands[0], operands[1]); DONE;")
2496
2497 ;;
2498 ;; Branches
2499 ;;
2500
2501 (define_expand "call"
2502 [(parallel [(call (match_operand:DI 0 "call_operand" "")
2503 (match_operand 1 "" ""))
2504 (use (reg:DI 54))
2505 (clobber (reg:DI 55))])]
2506 ""
2507 {
2508 rtx orig_addr = XEXP (operands[0], 0);
2509 rtx addr;
2510 if (GET_CODE (orig_addr) == SYMBOL_REF)
2511 {
2512 if (tilegx_cmodel == CM_LARGE)
2513 {
2514 addr = gen_reg_rtx (Pmode);
2515 tilegx_expand_set_const64 (addr, orig_addr);
2516 operands[0] = gen_rtx_MEM (DImode, addr);
2517 }
2518 else if (tilegx_cmodel == CM_LARGE_PIC)
2519 {
2520 crtl->uses_pic_offset_table = 1;
2521 addr = gen_reg_rtx (Pmode);
2522 if (SYMBOL_REF_LOCAL_P (orig_addr))
2523 tilegx_compute_pcrel_address (addr, orig_addr);
2524 else
2525 tilegx_compute_pcrel_plt_address (addr, orig_addr);
2526 operands[0] = gen_rtx_MEM (DImode, addr);
2527 }
2528 }
2529 })
2530
2531 (define_insn "*call_insn"
2532 [(call (mem:DI (match_operand:I48MODE 0 "call_address_operand" "rO,i"))
2533 (match_operand 1 "" ""))
2534 (use (reg:DI 54))
2535 (clobber (reg:DI 55))]
2536 ""
2537 "@
2538 jalr\t%r0
2539 jal\t%p0"
2540 [(set_attr "type" "Y1,X1")])
2541
2542 (define_expand "call_value"
2543 [(parallel [(set (match_operand 0 "register_operand" "")
2544 (call (match_operand:DI 1 "call_operand" "")
2545 (match_operand 2 "" "")))
2546 (use (reg:DI 54))
2547 (clobber (reg:DI 55))])]
2548 ""
2549 {
2550 rtx orig_addr = XEXP (operands[1], 0);
2551 rtx addr;
2552 if (GET_CODE (orig_addr) == SYMBOL_REF)
2553 {
2554 if (tilegx_cmodel == CM_LARGE)
2555 {
2556 addr = gen_reg_rtx (Pmode);
2557 tilegx_expand_set_const64 (addr, orig_addr);
2558 operands[1] = gen_rtx_MEM (DImode, addr);
2559 }
2560 else if (tilegx_cmodel == CM_LARGE_PIC)
2561 {
2562 crtl->uses_pic_offset_table = 1;
2563 addr = gen_reg_rtx (Pmode);
2564 if (SYMBOL_REF_LOCAL_P (orig_addr))
2565 tilegx_compute_pcrel_address (addr, orig_addr);
2566 else
2567 tilegx_compute_pcrel_plt_address (addr, orig_addr);
2568 operands[1] = gen_rtx_MEM (DImode, addr);
2569 }
2570 }
2571 })
2572
2573 (define_insn "*call_value_insn"
2574 [(set (match_operand 0 "register_operand" "=r,r")
2575 (call (mem:DI (match_operand:I48MODE 1 "call_address_operand" "rO,i"))
2576 (match_operand 2 "" "")))
2577 (use (reg:DI 54))
2578 (clobber (reg:DI 55))]
2579 ""
2580 "@
2581 jalr\t%r1
2582 jal\t%p1"
2583 [(set_attr "type" "Y1,X1")])
2584
2585 (define_expand "sibcall"
2586 [(parallel [(call (match_operand:DI 0 "call_operand" "")
2587 (match_operand 1 "" ""))
2588 (use (reg:DI 54))])]
2589 ""
2590 "")
2591
2592 (define_insn "*sibcall_insn"
2593 [(call (mem:DI (match_operand:I48MODE 0 "call_address_operand" "rO,i"))
2594 (match_operand 1 "" ""))
2595 (use (reg:DI 54))]
2596 "SIBLING_CALL_P(insn)"
2597 "@
2598 jr\t%r0
2599 j\t%p0"
2600 [(set_attr "type" "Y1,X1")])
2601
2602 (define_expand "sibcall_value"
2603 [(parallel [(set (match_operand 0 "" "")
2604 (call (match_operand:DI 1 "call_operand" "")
2605 (match_operand 2 "" "")))
2606 (use (reg:DI 54))])]
2607 ""
2608 "")
2609
2610 (define_insn "*sibcall_value"
2611 [(set (match_operand 0 "" "")
2612 (call (mem:DI (match_operand:I48MODE 1 "call_address_operand" "rO,i"))
2613 (match_operand 2 "" "")))
2614 (use (reg:DI 54))]
2615 "SIBLING_CALL_P(insn)"
2616 "@
2617 jr\t%r1
2618 j\t%p1"
2619 [(set_attr "type" "Y1,X1")])
2620
2621 (define_insn "jump"
2622 [(set (pc) (label_ref (match_operand 0 "" "")))]
2623 ""
2624 "j\t%l0"
2625 [(set_attr "type" "X1")])
2626
2627 (define_insn "indirect_jump"
2628 [(set (pc) (match_operand 0 "pointer_operand" "rO"))]
2629 ""
2630 "jr\t%r0"
2631 [(set_attr "type" "Y1")])
2632
2633 (define_expand "return"
2634 [(parallel
2635 [(return)
2636 (use (reg:DI 55))])]
2637 "tilegx_can_use_return_insn_p ()"
2638 "")
2639
2640 (define_insn "_return"
2641 [(return)
2642 (use (reg:DI 55))]
2643 "reload_completed"
2644 "jrp\tlr"
2645 [(set_attr "type" "Y1")])
2646
2647 (define_expand "tablejump"
2648 [(set (pc) (match_operand 0 "pointer_operand" ""))
2649 (use (label_ref (match_operand 1 "" "")))]
2650 ""
2651 {
2652 tilegx_expand_tablejump (operands[0], operands[1]);
2653 DONE;
2654 })
2655
2656 (define_insn "tablejump_aux"
2657 [(set (pc) (match_operand 0 "pointer_operand" "rO"))
2658 (use (label_ref (match_operand 1 "" "")))]
2659 ""
2660 "jr\t%r0"
2661 [(set_attr "type" "Y1")])
2662
2663 ;; Call subroutine returning any type.
2664 (define_expand "untyped_call"
2665 [(parallel [(call (match_operand 0 "" "")
2666 (const_int 0))
2667 (match_operand 1 "" "")
2668 (match_operand 2 "" "")])]
2669 ""
2670 {
2671 int i;
2672
2673 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
2674
2675 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2676 {
2677 rtx set = XVECEXP (operands[2], 0, i);
2678 emit_move_insn (SET_DEST (set), SET_SRC (set));
2679 }
2680
2681 /* The optimizer does not know that the call sets the function value
2682 registers we stored in the result block. We avoid problems by
2683 claiming that all hard registers are used and clobbered at this
2684 point. */
2685 emit_insn (gen_blockage ());
2686
2687 DONE;
2688 })
2689
2690 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers
2691 ;; and all of memory. This blocks insns from being moved across this
2692 ;; point.
2693 (define_insn "blockage"
2694 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
2695 ""
2696 "pseudo"
2697 [(set_attr "type" "nothing")
2698 (set_attr "length" "0")])
2699
2700 ;; Internal expanders to prevent memory ops from moving around frame
2701 ;; allocation/deallocation.
2702 ;;
2703 ;; TODO: really this clobber should just clobber the frame memory. Is
2704 ;; this possibly by clobbering memory @ the sp reg (as alpha does?)
2705 ;; or by explicitly setting the alias set to the frame?
2706 (define_insn "sp_adjust"
2707 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
2708 (plus:DI
2709 (match_operand:DI 1 "register_operand" "%r,r,r")
2710 (match_operand:DI 2 "add_operand" "r,I,JT")))
2711 (clobber (mem:BLK (scratch)))]
2712 ""
2713 "@
2714 add\t%0, %1, %2
2715 addi\t%0, %1, %2
2716 addli\t%0, %1, %H2"
2717 [(set_attr "type" "*,*,X01")])
2718
2719 (define_insn "sp_adjust_32bit"
2720 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2721 (plus:SI
2722 (match_operand:SI 1 "register_operand" "%r,r,r")
2723 (match_operand:SI 2 "add_operand" "r,I,JT")))
2724 (clobber (mem:BLK (scratch)))]
2725 ""
2726 "@
2727 addx\t%0, %1, %2
2728 addxi\t%0, %1, %2
2729 addxli\t%0, %1, %H2"
2730 [(set_attr "type" "*,*,X01")])
2731
2732 ;; Used for move sp, r52, to pop a stack frame. We need to make sure
2733 ;; that stack frame memory operations have been issued before we do
2734 ;; this. TODO: see above TODO.
2735 (define_insn "sp_restore<bitsuffix>"
2736 [(set (match_operand:I48MODE 0 "register_operand" "=r")
2737 (match_operand:I48MODE 1 "register_operand" "r"))
2738 (clobber (mem:BLK (scratch)))]
2739 ""
2740 "move\t%0, %1")
2741
2742 (define_insn "nop"
2743 [(const_int 0)]
2744 ""
2745 "nop"
2746 [(set_attr "type" "Y01")])
2747
2748 \f
2749 ;;
2750 ;; Conditional branches
2751 ;;
2752
2753 (define_expand "cbranch<mode>4"
2754 [(set (pc)
2755 (if_then_else (match_operator 0 "ordered_comparison_operator"
2756 [(match_operand:FI48MODE 1 "reg_or_cint_operand")
2757 (match_operand:FI48MODE 2 "reg_or_cint_operand")])
2758 (label_ref (match_operand 3 ""))
2759 (pc)))]
2760 ""
2761 {
2762 tilegx_emit_conditional_branch (operands, GET_MODE (operands[1]));
2763 DONE;
2764 })
2765
2766 (define_insn "*bcc_normal<mode>"
2767 [(set (pc)
2768 (if_then_else
2769 (match_operator 1 "signed_comparison_operator"
2770 [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
2771 (const_int 0)])
2772 (label_ref (match_operand 0 "" ""))
2773 (pc)))]
2774 ""
2775 { return tilegx_output_cbranch (insn, operands, false); }
2776 [(set_attr "type" "X1_branch")])
2777
2778 (define_insn "*bcc_reverse<mode>"
2779 [(set (pc)
2780 (if_then_else
2781 (match_operator 1 "signed_comparison_operator"
2782 [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
2783 (const_int 0)])
2784 (pc)
2785 (label_ref (match_operand 0 "" ""))))]
2786 ""
2787 { return tilegx_output_cbranch (insn, operands, true); }
2788 [(set_attr "type" "X1_branch")])
2789
2790 (define_insn "*blbs_normal<mode>"
2791 [(set (pc)
2792 (if_then_else
2793 (ne (zero_extract:I48MODE
2794 (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
2795 (const_int 1)
2796 (const_int 0))
2797 (const_int 0))
2798 (label_ref (match_operand 0 "" ""))
2799 (pc)))]
2800 ""
2801 { return tilegx_output_cbranch_with_opcode (insn, operands, "blbs", "blbc",
2802 1); }
2803 [(set_attr "type" "X1_branch")])
2804
2805 (define_insn "*blbc_normal<mode>"
2806 [(set (pc)
2807 (if_then_else
2808 (eq (zero_extract:I48MODE
2809 (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
2810 (const_int 1)
2811 (const_int 0))
2812 (const_int 0))
2813 (label_ref (match_operand 0 "" ""))
2814 (pc)))]
2815 ""
2816 { return tilegx_output_cbranch_with_opcode (insn, operands, "blbc", "blbs",
2817 1); }
2818 [(set_attr "type" "X1_branch")])
2819
2820 ;; Note that __insn_mf() expands to this.
2821 (define_expand "memory_barrier"
2822 [(set (match_dup 0)
2823 (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
2824 ""
2825 {
2826 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
2827 MEM_VOLATILE_P (operands[0]) = 1;
2828 })
2829
2830 (define_insn "*memory_barrier"
2831 [(set (match_operand:BLK 0 "" "")
2832 (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
2833 ""
2834 "mf"
2835 [(set_attr "type" "X1")])
2836
2837 (define_insn "prefetch"
2838 [(prefetch (match_operand 0 "address_operand" "rO")
2839 (match_operand 1 "const_int_operand" "")
2840 (match_operand 2 "const_int_operand" ""))]
2841 ""
2842 {
2843 switch (INTVAL (operands[2]))
2844 {
2845 case 0:
2846 case 1: return "prefetch_l3\t%r0";
2847 case 2: return "prefetch_l2\t%r0";
2848 case 3: return "prefetch_l1\t%r0";
2849 default: gcc_unreachable ();
2850 }
2851 }
2852 [(set_attr "type" "Y2")])
2853
2854 \f
2855 ;;
2856 ;; "__insn" Intrinsics (some expand directly to normal patterns above).
2857 ;;
2858
2859 (define_insn "insn_bfexts"
2860 [(set (match_operand:DI 0 "register_operand" "=r")
2861 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2862 (match_operand:DI 2 "u6bit_cint_operand" "n")
2863 (match_operand:DI 3 "u6bit_cint_operand" "n")]
2864 UNSPEC_INSN_BFEXTS))]
2865 ""
2866 "bfexts\t%0, %r1, %2, %3"
2867 [(set_attr "type" "X0")])
2868
2869 (define_insn "insn_bfextu"
2870 [(set (match_operand:DI 0 "register_operand" "=r")
2871 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2872 (match_operand:DI 2 "u6bit_cint_operand" "n")
2873 (match_operand:DI 3 "u6bit_cint_operand" "n")]
2874 UNSPEC_INSN_BFEXTU))]
2875 ""
2876 "bfextu\t%0, %r1, %2, %3"
2877 [(set_attr "type" "X0")])
2878
2879 (define_insn "insn_bfins"
2880 [(set (match_operand:DI 0 "register_operand" "=r")
2881 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2882 (match_operand:DI 2 "reg_or_0_operand" "rO")
2883 (match_operand:DI 3 "u6bit_cint_operand" "n")
2884 (match_operand:DI 4 "u6bit_cint_operand" "n")]
2885 UNSPEC_INSN_BFINS))]
2886 ""
2887 "bfins\t%0, %r2, %3, %4"
2888 [(set_attr "type" "X0")])
2889
2890 (define_insn "insn_cmpexch<four_if_si>"
2891 [(set (match_operand:I48MODE 0 "register_operand" "=r")
2892 (mem:I48MODE (match_operand 1 "pointer_operand" "rO")))
2893 (set (mem:I48MODE (match_dup 1))
2894 (unspec_volatile:I48MODE
2895 [(mem:I48MODE (match_dup 1))
2896 (reg:I48MODE TILEGX_CMPEXCH_REG)
2897 (match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
2898 UNSPEC_INSN_CMPEXCH))]
2899 ""
2900 "cmpexch<four_if_si>\t%0, %r1, %r2"
2901 [(set_attr "type" "X1_remote")])
2902
2903 (define_insn "insn_cmul"
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 "reg_or_0_operand" "rO")]
2907 UNSPEC_INSN_CMUL))]
2908 ""
2909 "cmul\t%0, %r1, %r2"
2910 [(set_attr "type" "X0_2cycle")])
2911
2912 (define_insn "insn_cmula"
2913 [(set (match_operand:DI 0 "register_operand" "=r")
2914 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2915 (match_operand:DI 2 "reg_or_0_operand" "rO")
2916 (match_operand:DI 3 "reg_or_0_operand" "rO")]
2917 UNSPEC_INSN_CMULA))]
2918 ""
2919 "cmula\t%0, %r2, %r3"
2920 [(set_attr "type" "X0_2cycle")])
2921
2922 (define_insn "insn_cmulaf"
2923 [(set (match_operand:DI 0 "register_operand" "=r")
2924 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2925 (match_operand:DI 2 "reg_or_0_operand" "rO")
2926 (match_operand:DI 3 "reg_or_0_operand" "rO")]
2927 UNSPEC_INSN_CMULAF))]
2928 ""
2929 "cmulaf\t%0, %r2, %r3"
2930 [(set_attr "type" "X0_2cycle")])
2931
2932 (define_insn "insn_cmulf"
2933 [(set (match_operand:DI 0 "register_operand" "=r")
2934 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2935 (match_operand:DI 2 "reg_or_0_operand" "rO")]
2936 UNSPEC_INSN_CMULF))]
2937 ""
2938 "cmulf\t%0, %r1, %r2"
2939 [(set_attr "type" "X0_2cycle")])
2940
2941 (define_insn "insn_cmulfr"
2942 [(set (match_operand:DI 0 "register_operand" "=r")
2943 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2944 (match_operand:DI 2 "reg_or_0_operand" "rO")]
2945 UNSPEC_INSN_CMULFR))]
2946 ""
2947 "cmulfr\t%0, %r1, %r2"
2948 [(set_attr "type" "X0_2cycle")])
2949
2950 (define_insn "insn_cmulh"
2951 [(set (match_operand:DI 0 "register_operand" "=r")
2952 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2953 (match_operand:DI 2 "reg_or_0_operand" "rO")]
2954 UNSPEC_INSN_CMULH))]
2955 ""
2956 "cmulh\t%0, %r1, %r2"
2957 [(set_attr "type" "X0_2cycle")])
2958
2959 (define_insn "insn_cmulhr"
2960 [(set (match_operand:DI 0 "register_operand" "=r")
2961 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2962 (match_operand:DI 2 "reg_or_0_operand" "rO")]
2963 UNSPEC_INSN_CMULHR))]
2964 ""
2965 "cmulhr\t%0, %r1, %r2"
2966 [(set_attr "type" "X0_2cycle")])
2967
2968 (define_insn "insn_crc32_32"
2969 [(set (match_operand:DI 0 "register_operand" "=r")
2970 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2971 (match_operand:DI 2 "reg_or_0_operand" "rO")]
2972 UNSPEC_INSN_CRC32_32))]
2973 ""
2974 "crc32_32\t%0, %r1, %r2"
2975 [(set_attr "type" "X0")])
2976
2977 (define_insn "insn_crc32_8"
2978 [(set (match_operand:DI 0 "register_operand" "=r")
2979 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2980 (match_operand:DI 2 "reg_or_0_operand" "rO")]
2981 UNSPEC_INSN_CRC32_8))]
2982 ""
2983 "crc32_8\t%0, %r1, %r2"
2984 [(set_attr "type" "X0")])
2985
2986 (define_insn "insn_dblalign"
2987 [(set (match_operand:DI 0 "register_operand" "=r")
2988 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
2989 (match_operand:DI 2 "reg_or_0_operand" "rO")
2990 (match_operand 3 "pointer_operand" "rO")]
2991 UNSPEC_INSN_DBLALIGN))]
2992 ""
2993 "dblalign\t%0, %r2, %r3"
2994 [(set_attr "type" "X0")])
2995
2996 (define_insn "insn_dblalign2"
2997 [(set (match_operand:DI 0 "register_operand" "=r")
2998 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
2999 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3000 UNSPEC_INSN_DBLALIGN2))]
3001 ""
3002 "dblalign2\t%0, %r1, %r2"
3003 [(set_attr "type" "X01")])
3004
3005 (define_insn "insn_dblalign4"
3006 [(set (match_operand:DI 0 "register_operand" "=r")
3007 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3008 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3009 UNSPEC_INSN_DBLALIGN4))]
3010 ""
3011 "dblalign4\t%0, %r1, %r2"
3012 [(set_attr "type" "X01")])
3013
3014 (define_insn "insn_dblalign6"
3015 [(set (match_operand:DI 0 "register_operand" "=r")
3016 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3017 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3018 UNSPEC_INSN_DBLALIGN6))]
3019 ""
3020 "dblalign6\t%0, %r1, %r2"
3021 [(set_attr "type" "X01")])
3022
3023 (define_insn "insn_dtlbpr"
3024 [(unspec_volatile:VOID [(match_operand:DI 0 "reg_or_0_operand" "rO")]
3025 UNSPEC_INSN_DTLBPR)]
3026 ""
3027 "dtlbpr\t%r0"
3028 [(set_attr "type" "X1")])
3029
3030 (define_insn "insn_exch<four_if_si>"
3031 [(set (match_operand:I48MODE 0 "register_operand" "=r")
3032 (mem:I48MODE (match_operand 1 "pointer_operand" "rO")))
3033 (set (mem:I48MODE (match_dup 1))
3034 (unspec_volatile:I48MODE
3035 [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
3036 UNSPEC_INSN_EXCH))]
3037 ""
3038 "exch<four_if_si>\t%0, %r1, %r2"
3039 [(set_attr "type" "X1_remote")])
3040
3041 (define_insn "insn_fdouble_add_flags"
3042 [(set (match_operand:DI 0 "register_operand" "=r")
3043 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3044 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3045 UNSPEC_INSN_FDOUBLE_ADD_FLAGS))]
3046 ""
3047 "fdouble_add_flags\t%0, %r1, %r2"
3048 [(set_attr "type" "X0_2cycle")])
3049
3050 (define_insn "insn_fdouble_addsub"
3051 [(set (match_operand:DI 0 "register_operand" "=r")
3052 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3053 (match_operand:DI 2 "reg_or_0_operand" "rO")
3054 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3055 UNSPEC_INSN_FDOUBLE_ADDSUB))]
3056 ""
3057 "fdouble_addsub\t%0, %r2, %r3"
3058 [(set_attr "type" "X0_2cycle")])
3059
3060 (define_insn "insn_fdouble_mul_flags"
3061 [(set (match_operand:DI 0 "register_operand" "=r")
3062 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3063 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3064 UNSPEC_INSN_FDOUBLE_MUL_FLAGS))]
3065 ""
3066 "fdouble_mul_flags\t%0, %r1, %r2"
3067 [(set_attr "type" "X0_2cycle")])
3068
3069 (define_insn "insn_fdouble_pack1"
3070 [(set (match_operand:DI 0 "register_operand" "=r")
3071 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3072 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3073 UNSPEC_INSN_FDOUBLE_PACK1))]
3074 ""
3075 "fdouble_pack1\t%0, %r1, %r2"
3076 [(set_attr "type" "X0_2cycle")])
3077
3078 (define_insn "insn_fdouble_pack2"
3079 [(set (match_operand:DI 0 "register_operand" "=r")
3080 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3081 (match_operand:DI 2 "reg_or_0_operand" "rO")
3082 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3083 UNSPEC_INSN_FDOUBLE_PACK2))]
3084 ""
3085 "fdouble_pack2\t%0, %r2, %r3"
3086 [(set_attr "type" "X0_2cycle")])
3087
3088 (define_insn "insn_fdouble_sub_flags"
3089 [(set (match_operand:DI 0 "register_operand" "=r")
3090 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3091 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3092 UNSPEC_INSN_FDOUBLE_SUB_FLAGS))]
3093 ""
3094 "fdouble_sub_flags\t%0, %r1, %r2"
3095 [(set_attr "type" "X0_2cycle")])
3096
3097 (define_insn "insn_fdouble_unpack_max"
3098 [(set (match_operand:DI 0 "register_operand" "=r")
3099 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3100 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3101 UNSPEC_INSN_FDOUBLE_UNPACK_MAX))]
3102 ""
3103 "fdouble_unpack_max\t%0, %r1, %r2"
3104 [(set_attr "type" "X0_2cycle")])
3105
3106 (define_insn "insn_fdouble_unpack_min"
3107 [(set (match_operand:DI 0 "register_operand" "=r")
3108 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3109 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3110 UNSPEC_INSN_FDOUBLE_UNPACK_MIN))]
3111 ""
3112 "fdouble_unpack_min\t%0, %r1, %r2"
3113 [(set_attr "type" "X0_2cycle")])
3114
3115 (define_insn "insn_fetchadd<four_if_si>"
3116 [(set (match_operand:I48MODE 0 "register_operand" "=r")
3117 (unspec_volatile:I48MODE
3118 [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3119 UNSPEC_ATOMIC))
3120 (set (mem:I48MODE (match_dup 1))
3121 (plus:I48MODE (mem:I48MODE (match_dup 1))
3122 (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
3123 ""
3124 "fetchadd<four_if_si>\t%0, %r1, %r2"
3125 [(set_attr "type" "X1_remote")])
3126
3127 (define_insn "insn_fetchaddgez<four_if_si>"
3128 [(set (match_operand:I48MODE 0 "register_operand" "=r")
3129 (unspec_volatile:I48MODE
3130 [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3131 UNSPEC_ATOMIC))
3132 (set (mem:I48MODE (match_dup 1))
3133 (unspec:I48MODE [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
3134 (mem:I48MODE (match_dup 1))]
3135 UNSPEC_INSN_FETCHADDGEZ))]
3136 ""
3137 "fetchaddgez<four_if_si>\t%0, %r1, %r2"
3138 [(set_attr "type" "X1_remote")])
3139
3140 (define_insn "insn_fetchand<four_if_si>"
3141 [(set (match_operand:I48MODE 0 "register_operand" "=r")
3142 (unspec_volatile:I48MODE
3143 [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3144 UNSPEC_ATOMIC))
3145 (set (mem:I48MODE (match_dup 1))
3146 (and:I48MODE (mem:I48MODE (match_dup 1))
3147 (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
3148 ""
3149 "fetchand<four_if_si>\t%0, %r1, %r2"
3150 [(set_attr "type" "X1_remote")])
3151
3152 (define_insn "insn_fetchor<four_if_si>"
3153 [(set (match_operand:I48MODE 0 "register_operand" "=r")
3154 (unspec_volatile:I48MODE
3155 [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
3156 UNSPEC_ATOMIC))
3157 (set (mem:I48MODE (match_dup 1))
3158 (ior:I48MODE (mem:I48MODE (match_dup 1))
3159 (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
3160 ""
3161 "fetchor<four_if_si>\t%0, %r1, %r2"
3162 [(set_attr "type" "X1_remote")])
3163
3164 (define_insn "insn_finv"
3165 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3166 UNSPEC_INSN_FINV)]
3167 ""
3168 "finv\t%r0"
3169 [(set_attr "type" "X1")])
3170
3171 (define_insn "insn_flush"
3172 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3173 UNSPEC_INSN_FLUSH)]
3174 ""
3175 "flush\t%r0"
3176 [(set_attr "type" "X1")])
3177
3178 (define_insn "insn_flushwb"
3179 [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FLUSHWB)]
3180 ""
3181 "flushwb"
3182 [(set_attr "type" "X1")])
3183
3184 (define_insn "insn_fnop"
3185 [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FNOP)]
3186 ""
3187 "fnop")
3188
3189 (define_insn "insn_fsingle_add1"
3190 [(set (match_operand:DI 0 "register_operand" "=r")
3191 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3192 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3193 UNSPEC_INSN_FSINGLE_ADD1))]
3194 ""
3195 "fsingle_add1\t%0, %r1, %r2"
3196 [(set_attr "type" "X0")])
3197
3198 (define_insn "insn_fsingle_addsub2"
3199 [(set (match_operand:DI 0 "register_operand" "=r")
3200 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3201 (match_operand:DI 2 "reg_or_0_operand" "rO")
3202 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3203 UNSPEC_INSN_FSINGLE_ADDSUB2))]
3204 ""
3205 "fsingle_addsub2\t%0, %r2, %r3"
3206 [(set_attr "type" "X0_2cycle")])
3207
3208 (define_insn "insn_fsingle_mul1"
3209 [(set (match_operand:DI 0 "register_operand" "=r")
3210 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3211 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3212 UNSPEC_INSN_FSINGLE_MUL1))]
3213 ""
3214 "fsingle_mul1\t%0, %r1, %r2"
3215 [(set_attr "type" "X0")])
3216
3217 (define_insn "insn_fsingle_mul2"
3218 [(set (match_operand:DI 0 "register_operand" "=r")
3219 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3220 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3221 UNSPEC_INSN_FSINGLE_MUL2))]
3222 ""
3223 "fsingle_mul2\t%0, %r1, %r2"
3224 [(set_attr "type" "X0_2cycle")])
3225
3226 (define_insn "insn_fsingle_pack1"
3227 [(set (match_operand:DI 0 "register_operand" "=r")
3228 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")]
3229 UNSPEC_INSN_FSINGLE_PACK1))]
3230 ""
3231 "fsingle_pack1\t%0, %r1"
3232 [(set_attr "type" "Y0_2cycle")])
3233
3234 (define_insn "insn_fsingle_pack2"
3235 [(set (match_operand:DI 0 "register_operand" "=r")
3236 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3237 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3238 UNSPEC_INSN_FSINGLE_PACK2))]
3239 ""
3240 "fsingle_pack2\t%0, %r1, %r2"
3241 [(set_attr "type" "X0_2cycle")])
3242
3243 (define_insn "insn_fsingle_sub1"
3244 [(set (match_operand:DI 0 "register_operand" "=r")
3245 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3246 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3247 UNSPEC_INSN_FSINGLE_SUB1))]
3248 ""
3249 "fsingle_sub1\t%0, %r1, %r2"
3250 [(set_attr "type" "X0")])
3251
3252 (define_insn "insn_drain"
3253 [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_DRAIN)]
3254 ""
3255 "drain"
3256 [(set_attr "type" "cannot_bundle")])
3257
3258 (define_insn "insn_icoh"
3259 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3260 UNSPEC_INSN_ICOH)]
3261 ""
3262 "icoh\t%r0"
3263 [(set_attr "type" "X1")])
3264
3265 (define_insn "insn_ill"
3266 [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_ILL)]
3267 ""
3268 "ill"
3269 [(set_attr "type" "cannot_bundle")])
3270
3271 (define_insn "insn_info"
3272 [(unspec_volatile:VOID [(match_operand:DI 0 "s8bit_cint_operand" "i")]
3273 UNSPEC_INSN_INFO)]
3274 ""
3275 "info\t%0")
3276
3277 (define_insn "insn_infol"
3278 [(unspec_volatile:VOID [(match_operand:DI 0 "s16bit_cint_operand" "i")]
3279 UNSPEC_INSN_INFOL)]
3280 ""
3281 "infol\t%0"
3282 [(set_attr "type" "X01")])
3283
3284 (define_insn "insn_inv"
3285 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3286 UNSPEC_INSN_INV)]
3287 ""
3288 "inv\t%r0"
3289 [(set_attr "type" "X1")])
3290
3291 ;; loads
3292
3293 (define_expand "insn_ld"
3294 [(set (match_operand:DI 0 "register_operand" "")
3295 (mem:DI (match_operand 1 "pointer_operand" "")))]
3296 "")
3297
3298 (define_insn "insn_ld_add<bitsuffix>"
3299 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3300 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3301 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3302 (set (match_operand:DI 0 "register_operand" "=r")
3303 (mem:DI (match_dup 3)))]
3304 ""
3305 "ld_add\t%0, %1, %2"
3306 [(set_attr "type" "X1_2cycle")])
3307
3308 (define_insn "insn_ldna"
3309 [(set (match_operand:DI 0 "register_operand" "=r")
3310 (mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
3311 (const_int -8))))]
3312 ""
3313 "ldna\t%0, %r1"
3314 [(set_attr "type" "X1_2cycle")])
3315
3316 (define_insn "insn_ldna_add<bitsuffix>"
3317 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3318 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3319 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3320 (set (match_operand:DI 0 "register_operand" "=r")
3321 (mem:DI (and:DI (match_dup 3) (const_int -8))))]
3322 ""
3323 "ldna_add\t%0, %1, %2"
3324 [(set_attr "type" "X1_2cycle")])
3325
3326 (define_expand "insn_ld<n><s>"
3327 [(set (match_operand:DI 0 "register_operand" "")
3328 (any_extend:DI
3329 (mem:I124MODE (match_operand 1 "pointer_operand" ""))))]
3330 "")
3331
3332 (define_insn "insn_ld<I124MODE:n><s>_add<I48MODE:bitsuffix>"
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")))
3336 (set (match_operand:DI 0 "register_operand" "=r")
3337 (any_extend:DI (mem:I124MODE (match_dup 3))))]
3338 ""
3339 "ld<I124MODE:n><s>_add\t%0, %1, %2"
3340 [(set_attr "type" "X1_2cycle")])
3341
3342 ;; non temporal loads
3343
3344 (define_insn "insn_ldnt"
3345 [(set (match_operand:DI 0 "register_operand" "=r")
3346 (unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3347 UNSPEC_NON_TEMPORAL))]
3348 ""
3349 "ldnt\t%0, %r1"
3350 [(set_attr "type" "X1_2cycle")])
3351
3352 (define_insn "insn_ldnt_add<bitsuffix>"
3353 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3354 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3355 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3356 (set (match_operand:DI 0 "register_operand" "=r")
3357 (unspec:DI [(mem:DI (match_dup 3))]
3358 UNSPEC_NON_TEMPORAL))]
3359 ""
3360 "ldnt_add\t%0, %1, %2"
3361 [(set_attr "type" "X1_2cycle")])
3362
3363 (define_insn "insn_ldnt<n><s>"
3364 [(set (match_operand:DI 0 "register_operand" "=r")
3365 (any_extend:DI
3366 (unspec:I124MODE
3367 [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3368 UNSPEC_NON_TEMPORAL)))]
3369 ""
3370 "ldnt<n><s>\t%0, %r1"
3371 [(set_attr "type" "X1_2cycle")])
3372
3373 (define_insn "insn_ldnt<I124MODE:n><s>_add<I48MODE:bitsuffix>"
3374 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3375 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3376 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3377 (set (match_operand:DI 0 "register_operand" "=r")
3378 (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
3379 UNSPEC_NON_TEMPORAL)))]
3380 ""
3381 "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
3382 [(set_attr "type" "X1_2cycle")])
3383
3384 ;; L2 hits
3385
3386 (define_insn "insn_ld_L2"
3387 [(set (match_operand:DI 0 "register_operand" "=r")
3388 (unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3389 UNSPEC_LATENCY_L2))]
3390 ""
3391 "ld\t%0, %r1"
3392 [(set_attr "type" "Y2_L2")])
3393
3394 (define_insn "insn_ld_add_L2<bitsuffix>"
3395 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3396 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3397 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3398 (set (match_operand:DI 0 "register_operand" "=r")
3399 (unspec:DI [(mem:DI (match_dup 3))]
3400 UNSPEC_LATENCY_L2))]
3401 ""
3402 "ld_add\t%0, %1, %2"
3403 [(set_attr "type" "X1_L2")])
3404
3405 (define_insn "insn_ldna_L2"
3406 [(set (match_operand:DI 0 "register_operand" "=r")
3407 (unspec:DI [(mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
3408 (const_int -8)))]
3409 UNSPEC_LATENCY_L2))]
3410 ""
3411 "ldna\t%0, %r1"
3412 [(set_attr "type" "X1_L2")])
3413
3414 (define_insn "insn_ldna_add_L2<bitsuffix>"
3415 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3416 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3417 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3418 (set (match_operand:DI 0 "register_operand" "=r")
3419 (unspec:DI [(mem:DI (and:DI (match_dup 3) (const_int -8)))]
3420 UNSPEC_LATENCY_L2))]
3421 ""
3422 "ldna_add\t%0, %1, %2"
3423 [(set_attr "type" "X1_L2")])
3424
3425 (define_insn "insn_ld<n><s>_L2"
3426 [(set (match_operand:DI 0 "register_operand" "=r")
3427 (any_extend:DI
3428 (unspec:I124MODE
3429 [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3430 UNSPEC_LATENCY_L2)))]
3431 ""
3432 "ld<n><s>\t%0, %r1"
3433 [(set_attr "type" "Y2_L2")])
3434
3435 (define_insn "insn_ld<I124MODE:n><s>_add_L2<I48MODE:bitsuffix>"
3436 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3437 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3438 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3439 (set (match_operand:DI 0 "register_operand" "=r")
3440 (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
3441 UNSPEC_LATENCY_L2)))]
3442 ""
3443 "ld<I124MODE:n><s>_add\t%0, %1, %2"
3444 [(set_attr "type" "X1_L2")])
3445
3446 ;; L2 hits, non temporal loads
3447
3448 (define_insn "insn_ldnt_L2"
3449 [(set (match_operand:DI 0 "register_operand" "=r")
3450 (unspec:DI [(unspec:DI
3451 [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3452 UNSPEC_NON_TEMPORAL)]
3453 UNSPEC_LATENCY_L2))]
3454 ""
3455 "ldnt\t%0, %r1"
3456 [(set_attr "type" "X1_L2")])
3457
3458 (define_insn "insn_ldnt_add_L2<bitsuffix>"
3459 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3460 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3461 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3462 (set (match_operand:DI 0 "register_operand" "=r")
3463 (unspec:DI [(unspec:DI
3464 [(mem:DI (match_dup 3))]
3465 UNSPEC_NON_TEMPORAL)]
3466 UNSPEC_LATENCY_L2))]
3467 ""
3468 "ldnt_add\t%0, %1, %2"
3469 [(set_attr "type" "X1_L2")])
3470
3471 (define_insn "insn_ldnt<n><s>_L2"
3472 [(set (match_operand:DI 0 "register_operand" "=r")
3473 (any_extend:DI
3474 (unspec:I124MODE
3475 [(unspec:I124MODE
3476 [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3477 UNSPEC_NON_TEMPORAL)]
3478 UNSPEC_LATENCY_L2)))]
3479 ""
3480 "ldnt<n><s>\t%0, %r1"
3481 [(set_attr "type" "X1_L2")])
3482
3483 (define_insn "insn_ldnt<I124MODE:n><s>_add_L2<I48MODE:bitsuffix>"
3484 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3485 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3486 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3487 (set (match_operand:DI 0 "register_operand" "=r")
3488 (any_extend:DI
3489 (unspec:I124MODE [(unspec:I124MODE
3490 [(mem:I124MODE (match_dup 3))]
3491 UNSPEC_NON_TEMPORAL)]
3492 UNSPEC_LATENCY_L2)))]
3493 ""
3494 "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
3495 [(set_attr "type" "X1_L2")])
3496
3497 ;; L2 miss
3498
3499 (define_insn "insn_ld_miss"
3500 [(set (match_operand:DI 0 "register_operand" "=r")
3501 (unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3502 UNSPEC_LATENCY_MISS))]
3503 ""
3504 "ld\t%0, %r1"
3505 [(set_attr "type" "Y2_miss")])
3506
3507 (define_insn "insn_ld_add_miss<bitsuffix>"
3508 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3509 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3510 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3511 (set (match_operand:DI 0 "register_operand" "=r")
3512 (unspec:DI [(mem:DI (match_dup 3))]
3513 UNSPEC_LATENCY_MISS))]
3514 ""
3515 "ld_add\t%0, %1, %2"
3516 [(set_attr "type" "X1_miss")])
3517
3518 (define_insn "insn_ldna_miss"
3519 [(set (match_operand:DI 0 "register_operand" "=r")
3520 (unspec:DI [(mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
3521 (const_int -8)))]
3522 UNSPEC_LATENCY_MISS))]
3523 ""
3524 "ldna\t%0, %r1"
3525 [(set_attr "type" "X1_miss")])
3526
3527 (define_insn "insn_ldna_add_miss<bitsuffix>"
3528 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3529 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3530 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3531 (set (match_operand:DI 0 "register_operand" "=r")
3532 (unspec:DI [(mem:DI (and:DI (match_dup 3) (const_int -8)))]
3533 UNSPEC_LATENCY_MISS))]
3534 ""
3535 "ldna_add\t%0, %1, %2"
3536 [(set_attr "type" "X1_miss")])
3537
3538 (define_insn "insn_ld<n><s>_miss"
3539 [(set (match_operand:DI 0 "register_operand" "=r")
3540 (any_extend:DI
3541 (unspec:I124MODE
3542 [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3543 UNSPEC_LATENCY_MISS)))]
3544 ""
3545 "ld<n><s>\t%0, %r1"
3546 [(set_attr "type" "Y2_miss")])
3547
3548 (define_insn "insn_ld<I124MODE:n><s>_add_miss<I48MODE:bitsuffix>"
3549 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3550 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3551 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3552 (set (match_operand:DI 0 "register_operand" "=r")
3553 (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
3554 UNSPEC_LATENCY_MISS)))]
3555 ""
3556 "ld<I124MODE:n><s>_add\t%0, %1, %2"
3557 [(set_attr "type" "X1_miss")])
3558
3559 ;; L2 miss, non temporal loads
3560
3561 (define_insn "insn_ldnt_miss"
3562 [(set (match_operand:DI 0 "register_operand" "=r")
3563 (unspec:DI [(unspec:DI
3564 [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
3565 UNSPEC_NON_TEMPORAL)]
3566 UNSPEC_LATENCY_MISS))]
3567 ""
3568 "ldnt\t%0, %r1"
3569 [(set_attr "type" "X1_miss")])
3570
3571 (define_insn "insn_ldnt_add_miss<bitsuffix>"
3572 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3573 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3574 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3575 (set (match_operand:DI 0 "register_operand" "=r")
3576 (unspec:DI [(unspec:DI
3577 [(mem:DI (match_dup 3))]
3578 UNSPEC_NON_TEMPORAL)]
3579 UNSPEC_LATENCY_MISS))]
3580 ""
3581 "ldnt_add\t%0, %1, %2"
3582 [(set_attr "type" "X1_miss")])
3583
3584 (define_insn "insn_ldnt<n><s>_miss"
3585 [(set (match_operand:DI 0 "register_operand" "=r")
3586 (any_extend:DI
3587 (unspec:I124MODE
3588 [(unspec:I124MODE
3589 [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
3590 UNSPEC_NON_TEMPORAL)]
3591 UNSPEC_LATENCY_MISS)))]
3592 ""
3593 "ldnt<n><s>\t%0, %r1"
3594 [(set_attr "type" "X1_miss")])
3595
3596 (define_insn "insn_ldnt<I124MODE:n><s>_add_miss<I48MODE:bitsuffix>"
3597 [(set (match_operand:I48MODE 1 "register_operand" "=r")
3598 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "1")
3599 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3600 (set (match_operand:DI 0 "register_operand" "=r")
3601 (any_extend:DI
3602 (unspec:I124MODE [(unspec:I124MODE
3603 [(mem:I124MODE (match_dup 3))]
3604 UNSPEC_NON_TEMPORAL)]
3605 UNSPEC_LATENCY_MISS)))]
3606 ""
3607 "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
3608 [(set_attr "type" "X1_miss")])
3609
3610 ;; end loads
3611
3612 (define_insn "insn_lnk"
3613 [(set (match_operand:DI 0 "register_operand" "=r")
3614 (unspec:DI [(const_int 0)] UNSPEC_INSN_LNK))]
3615 ""
3616 "lnk\t%0"
3617 [(set_attr "type" "Y1")])
3618
3619 (define_insn "insn_mfspr"
3620 [(set (match_operand:DI 0 "register_operand" "=r")
3621 (unspec_volatile:DI [(match_operand:DI 1 "u14bit_cint_operand" "i")]
3622 UNSPEC_INSN_MFSPR))
3623 (clobber (mem:BLK (const_int 0)))]
3624 ""
3625 "mfspr\t%0, %1"
3626 [(set_attr "type" "X1")])
3627
3628 (define_insn "insn_mtspr"
3629 [(unspec_volatile:DI [(match_operand:DI 0 "u14bit_cint_operand" "i")
3630 (match_operand:DI 1 "reg_or_0_operand" "rO")]
3631 UNSPEC_INSN_MTSPR)
3632 (clobber (mem:BLK (const_int 0)))]
3633 ""
3634 "mtspr\t%0, %r1"
3635 [(set_attr "type" "X1")])
3636
3637 (define_insn "insn_mm"
3638 [(set (match_operand:DI 0 "register_operand" "=r")
3639 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3640 (match_operand:DI 2 "reg_or_0_operand" "rO")
3641 (match_operand:DI 3 "u6bit_cint_operand" "i")
3642 (match_operand:DI 4 "u6bit_cint_operand" "i")]
3643 UNSPEC_INSN_MM))]
3644 ""
3645 "mm\t%0, %r2, %3, %4"
3646 [(set_attr "type" "X0")])
3647
3648 (define_insn "insn_mul_hs_hs"
3649 [(set (match_operand:DI 0 "register_operand" "=r")
3650 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3651 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3652 UNSPEC_INSN_MUL_HS_HS))]
3653 ""
3654 "mul_hs_hs\t%0, %r1, %r2"
3655 [(set_attr "type" "Y0_2cycle")])
3656
3657 (define_insn "insn_mul_hs_hu"
3658 [(set (match_operand:DI 0 "register_operand" "=r")
3659 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3660 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3661 UNSPEC_INSN_MUL_HS_HU))]
3662 ""
3663 "mul_hs_hu\t%0, %r1, %r2"
3664 [(set_attr "type" "X0_2cycle")])
3665
3666 (define_insn "insn_mul_hs_ls"
3667 [(set (match_operand:DI 0 "register_operand" "=r")
3668 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3669 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3670 UNSPEC_INSN_MUL_HS_LS))]
3671 ""
3672 "mul_hs_ls\t%0, %r1, %r2"
3673 [(set_attr "type" "X0_2cycle")])
3674
3675 (define_insn "insn_mul_hs_lu"
3676 [(set (match_operand:DI 0 "register_operand" "=r")
3677 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3678 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3679 UNSPEC_INSN_MUL_HS_LU))]
3680 ""
3681 "mul_hs_lu\t%0, %r1, %r2"
3682 [(set_attr "type" "X0_2cycle")])
3683
3684 (define_insn "insn_mul_hu_hu"
3685 [(set (match_operand:DI 0 "register_operand" "=r")
3686 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3687 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3688 UNSPEC_INSN_MUL_HU_HU))]
3689 ""
3690 "mul_hu_hu\t%0, %r1, %r2"
3691 [(set_attr "type" "Y0_2cycle")])
3692
3693 (define_insn "insn_mul_hu_ls"
3694 [(set (match_operand:DI 0 "register_operand" "=r")
3695 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3696 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3697 UNSPEC_INSN_MUL_HU_LS))]
3698 ""
3699 "mul_hu_ls\t%0, %r1, %r2"
3700 [(set_attr "type" "X0_2cycle")])
3701
3702 (define_insn "insn_mul_hu_lu"
3703 [(set (match_operand:DI 0 "register_operand" "=r")
3704 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3705 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3706 UNSPEC_INSN_MUL_HU_LU))]
3707 ""
3708 "mul_hu_lu\t%0, %r1, %r2"
3709 [(set_attr "type" "X0_2cycle")])
3710
3711 (define_insn "insn_mul_ls_ls"
3712 [(set (match_operand:DI 0 "register_operand" "=r")
3713 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3714 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3715 UNSPEC_INSN_MUL_LS_LS))]
3716 ""
3717 "mul_ls_ls\t%0, %r1, %r2"
3718 [(set_attr "type" "Y0_2cycle")])
3719
3720 (define_insn "insn_mul_ls_lu"
3721 [(set (match_operand:DI 0 "register_operand" "=r")
3722 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3723 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3724 UNSPEC_INSN_MUL_LS_LU))]
3725 ""
3726 "mul_ls_lu\t%0, %r1, %r2"
3727 [(set_attr "type" "X0_2cycle")])
3728
3729 (define_insn "insn_mul_lu_lu"
3730 [(set (match_operand:DI 0 "register_operand" "=r")
3731 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3732 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3733 UNSPEC_INSN_MUL_LU_LU))]
3734 ""
3735 "mul_lu_lu\t%0, %r1, %r2"
3736 [(set_attr "type" "Y0_2cycle")])
3737
3738 (define_insn "insn_mula_hs_hs"
3739 [(set (match_operand:DI 0 "register_operand" "=r")
3740 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3741 (match_operand:DI 2 "reg_or_0_operand" "rO")
3742 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3743 UNSPEC_INSN_MULA_HS_HS))]
3744 ""
3745 "mula_hs_hs\t%0, %r2, %r3"
3746 [(set_attr "type" "Y0_2cycle")])
3747
3748 (define_insn "insn_mula_hs_hu"
3749 [(set (match_operand:DI 0 "register_operand" "=r")
3750 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3751 (match_operand:DI 2 "reg_or_0_operand" "rO")
3752 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3753 UNSPEC_INSN_MULA_HS_HU))]
3754 ""
3755 "mula_hs_hu\t%0, %r2, %r3"
3756 [(set_attr "type" "X0_2cycle")])
3757
3758 (define_insn "insn_mula_hs_ls"
3759 [(set (match_operand:DI 0 "register_operand" "=r")
3760 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3761 (match_operand:DI 2 "reg_or_0_operand" "rO")
3762 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3763 UNSPEC_INSN_MULA_HS_LS))]
3764 ""
3765 "mula_hs_ls\t%0, %r2, %r3"
3766 [(set_attr "type" "X0_2cycle")])
3767
3768 (define_insn "insn_mula_hs_lu"
3769 [(set (match_operand:DI 0 "register_operand" "=r")
3770 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3771 (match_operand:DI 2 "reg_or_0_operand" "rO")
3772 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3773 UNSPEC_INSN_MULA_HS_LU))]
3774 ""
3775 "mula_hs_lu\t%0, %r2, %r3"
3776 [(set_attr "type" "X0_2cycle")])
3777
3778 (define_insn "insn_mula_hu_hu"
3779 [(set (match_operand:DI 0 "register_operand" "=r")
3780 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3781 (match_operand:DI 2 "reg_or_0_operand" "rO")
3782 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3783 UNSPEC_INSN_MULA_HU_HU))]
3784 ""
3785 "mula_hu_hu\t%0, %r2, %r3"
3786 [(set_attr "type" "Y0_2cycle")])
3787
3788 (define_insn "insn_mula_hu_ls"
3789 [(set (match_operand:DI 0 "register_operand" "=r")
3790 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3791 (match_operand:DI 2 "reg_or_0_operand" "rO")
3792 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3793 UNSPEC_INSN_MULA_HU_LS))]
3794 ""
3795 "mula_hu_ls\t%0, %r2, %r3"
3796 [(set_attr "type" "X0_2cycle")])
3797
3798 (define_insn "insn_mula_hu_lu"
3799 [(set (match_operand:DI 0 "register_operand" "=r")
3800 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3801 (match_operand:DI 2 "reg_or_0_operand" "rO")
3802 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3803 UNSPEC_INSN_MULA_HU_LU))]
3804 ""
3805 "mula_hu_lu\t%0, %r2, %r3"
3806 [(set_attr "type" "X0_2cycle")])
3807
3808 (define_insn "insn_mula_ls_ls"
3809 [(set (match_operand:DI 0 "register_operand" "=r")
3810 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3811 (match_operand:DI 2 "reg_or_0_operand" "rO")
3812 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3813 UNSPEC_INSN_MULA_LS_LS))]
3814 ""
3815 "mula_ls_ls\t%0, %r2, %r3"
3816 [(set_attr "type" "Y0_2cycle")])
3817
3818 (define_insn "insn_mula_ls_lu"
3819 [(set (match_operand:DI 0 "register_operand" "=r")
3820 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3821 (match_operand:DI 2 "reg_or_0_operand" "rO")
3822 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3823 UNSPEC_INSN_MULA_LS_LU))]
3824 ""
3825 "mula_ls_lu\t%0, %r2, %r3"
3826 [(set_attr "type" "X0_2cycle")])
3827
3828 (define_insn "insn_mula_lu_lu"
3829 [(set (match_operand:DI 0 "register_operand" "=r")
3830 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3831 (match_operand:DI 2 "reg_or_0_operand" "rO")
3832 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3833 UNSPEC_INSN_MULA_LU_LU))]
3834 ""
3835 "mula_lu_lu\t%0, %r2, %r3"
3836 [(set_attr "type" "Y0_2cycle")])
3837
3838 (define_insn "insn_mulax"
3839 [(set (match_operand:SI 0 "register_operand" "=r")
3840 (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
3841 (match_operand:SI 2 "reg_or_0_operand" "rO")
3842 (match_operand:SI 3 "reg_or_0_operand" "rO")]
3843 UNSPEC_INSN_MULAX))]
3844 ""
3845 "mulax\t%0, %r2, %r3"
3846 [(set_attr "type" "Y0_2cycle")])
3847
3848 (define_insn "insn_nap"
3849 [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_NAP)]
3850 ""
3851 "nap"
3852 [(set_attr "type" "cannot_bundle")])
3853
3854 (define_insn "insn_nor_<mode>"
3855 [(set (match_operand:I48MODE 0 "register_operand" "=r")
3856 (and:I48MODE
3857 (not:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO"))
3858 (not:I48MODE (match_operand:I48MODE 2 "reg_or_0_operand" "rO"))))]
3859 ""
3860 "nor\t%0, %r1, %r2")
3861
3862 (define_expand "insn_prefetch_l1"
3863 [(prefetch (match_operand 0 "pointer_operand" "")
3864 (const_int 0)
3865 (const_int 3))]
3866 "")
3867
3868 (define_expand "insn_prefetch_l2"
3869 [(prefetch (match_operand 0 "pointer_operand" "")
3870 (const_int 0)
3871 (const_int 2))]
3872 "")
3873
3874 (define_expand "insn_prefetch_l3"
3875 [(prefetch (match_operand 0 "pointer_operand" "")
3876 (const_int 0)
3877 (const_int 1))]
3878 "")
3879
3880 (define_insn "insn_prefetch_l1_fault"
3881 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3882 UNSPEC_INSN_PREFETCH_L1_FAULT)]
3883 ""
3884 "prefetch_l1_fault\t%r0"
3885 [(set_attr "type" "Y2")])
3886
3887 (define_insn "insn_prefetch_l2_fault"
3888 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3889 UNSPEC_INSN_PREFETCH_L2_FAULT)]
3890 ""
3891 "prefetch_l2_fault\t%r0"
3892 [(set_attr "type" "Y2")])
3893
3894 (define_insn "insn_prefetch_l3_fault"
3895 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
3896 UNSPEC_INSN_PREFETCH_L3_FAULT)]
3897 ""
3898 "prefetch_l3_fault\t%r0"
3899 [(set_attr "type" "Y2")])
3900
3901 (define_insn "insn_revbits"
3902 [(set (match_operand:DI 0 "register_operand" "=r")
3903 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")]
3904 UNSPEC_INSN_REVBITS))]
3905 ""
3906 "revbits\t%0, %r1"
3907 [(set_attr "type" "Y0")])
3908
3909 (define_insn "insn_shl1add"
3910 [(set (match_operand:DI 0 "register_operand" "=r")
3911 (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
3912 (const_int 2))
3913 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
3914 ""
3915 "shl1add\t%0, %r1, %r2")
3916
3917 (define_insn "insn_shl1addx"
3918 [(set (match_operand:SI 0 "register_operand" "=r")
3919 (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
3920 (const_int 2))
3921 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
3922 ""
3923 "shl1addx\t%0, %r1, %r2")
3924
3925 (define_insn "insn_shl2add"
3926 [(set (match_operand:DI 0 "register_operand" "=r")
3927 (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
3928 (const_int 4))
3929 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
3930 ""
3931 "shl2add\t%0, %r1, %r2")
3932
3933 (define_insn "insn_shl2addx"
3934 [(set (match_operand:SI 0 "register_operand" "=r")
3935 (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
3936 (const_int 4))
3937 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
3938 ""
3939 "shl2addx\t%0, %r1, %r2")
3940
3941 (define_insn "insn_shl3add"
3942 [(set (match_operand:DI 0 "register_operand" "=r")
3943 (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
3944 (const_int 8))
3945 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
3946 ""
3947 "shl3add\t%0, %r1, %r2")
3948
3949 (define_insn "insn_shl3addx"
3950 [(set (match_operand:SI 0 "register_operand" "=r")
3951 (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
3952 (const_int 8))
3953 (match_operand:SI 2 "reg_or_0_operand" "rO")))]
3954 ""
3955 "shl3addx\t%0, %r1, %r2")
3956
3957 (define_insn "insn_shufflebytes"
3958 [(set (match_operand:DI 0 "register_operand" "=r")
3959 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
3960 (match_operand:DI 2 "reg_or_0_operand" "rO")
3961 (match_operand:DI 3 "reg_or_0_operand" "rO")]
3962 UNSPEC_INSN_SHUFFLEBYTES))]
3963 ""
3964 "shufflebytes\t%0, %r2, %r3"
3965 [(set_attr "type" "X0")])
3966
3967 (define_insn "insn_shufflebytes1"
3968 [(set (match_operand:DI 0 "register_operand" "=r")
3969 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
3970 (match_operand:DI 2 "reg_or_0_operand" "rO")]
3971 UNSPEC_INSN_SHUFFLEBYTES))]
3972 ""
3973 "shufflebytes\t%0, %r1, %r2"
3974 [(set_attr "type" "X0")])
3975
3976 ;; stores
3977
3978 (define_expand "insn_st"
3979 [(set (mem:DI (match_operand 0 "pointer_operand" ""))
3980 (match_operand:DI 1 "reg_or_0_operand" ""))]
3981 "")
3982
3983 (define_insn "insn_st_add<bitsuffix>"
3984 [(set (match_operand:I48MODE 0 "register_operand" "=r")
3985 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
3986 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
3987 (set (mem:DI (match_dup 3))
3988 (match_operand:DI 1 "reg_or_0_operand" "rO"))]
3989 ""
3990 "st_add\t%0, %r1, %2"
3991 [(set_attr "type" "X1")])
3992
3993 (define_expand "insn_st<n>"
3994 [(set (mem:I124MODE (match_operand 0 "pointer_operand" ""))
3995 (match_operand:DI 1 "reg_or_0_operand" ""))]
3996 ""
3997 {
3998 operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], DImode,
3999 BYTES_BIG_ENDIAN
4000 ? UNITS_PER_WORD - <n> : 0);
4001 })
4002
4003 (define_expand "insn_st<I124MODE:n>_add<I48MODE:bitsuffix>"
4004 [(parallel
4005 [(set (match_operand:I48MODE 0 "register_operand" "")
4006 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "")
4007 (match_operand:I48MODE 2 "s8bit_cint_operand" "")))
4008 (set (mem:I124MODE (match_dup 3))
4009 (match_operand:DI 1 "reg_or_0_operand" ""))])]
4010 ""
4011 {
4012 operands[1] = simplify_gen_subreg (<I124MODE:MODE>mode, operands[1],
4013 DImode,
4014 BYTES_BIG_ENDIAN
4015 ? UNITS_PER_WORD - <I124MODE:n> : 0);
4016 })
4017
4018 (define_insn "*insn_st<I124MODE:n>_add<I48MODE:bitsuffix>"
4019 [(set (match_operand:I48MODE 0 "register_operand" "=r")
4020 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4021 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
4022 (set (mem:I124MODE (match_dup 3))
4023 (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
4024 ""
4025 "st<I124MODE:n>_add\t%0, %r1, %2"
4026 [(set_attr "type" "X1")])
4027
4028 ;; non-temporal stores
4029
4030 (define_insn "insn_stnt"
4031 [(set (mem:DI (unspec [(match_operand 0 "pointer_operand" "rO")]
4032 UNSPEC_NON_TEMPORAL))
4033 (match_operand:DI 1 "reg_or_0_operand" "rO"))]
4034 ""
4035 "stnt\t%0, %r1"
4036 [(set_attr "type" "X1")])
4037
4038 (define_insn "insn_stnt_add<bitsuffix>"
4039 [(set (match_operand:I48MODE 0 "register_operand" "=r")
4040 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4041 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
4042 (set (mem:DI (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
4043 (match_operand:DI 1 "reg_or_0_operand" "rO"))]
4044 ""
4045 "stnt_add\t%0, %r1, %2"
4046 [(set_attr "type" "X1")])
4047
4048 (define_expand "insn_stnt<n>"
4049 [(set (mem:I124MODE (unspec [(match_operand 0 "pointer_operand" "")]
4050 UNSPEC_NON_TEMPORAL))
4051 (match_operand:DI 1 "reg_or_0_operand" ""))]
4052 ""
4053 {
4054 operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], DImode,
4055 BYTES_BIG_ENDIAN
4056 ? UNITS_PER_WORD - <n> : 0);
4057 })
4058
4059 (define_insn "*insn_stnt<n>"
4060 [(set (mem:I124MODE (unspec [(match_operand 0 "pointer_operand" "rO")]
4061 UNSPEC_NON_TEMPORAL))
4062 (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
4063 ""
4064 "stnt<n>\t%0, %r1"
4065 [(set_attr "type" "X1")])
4066
4067 (define_expand "insn_stnt<I124MODE:n>_add<I48MODE:bitsuffix>"
4068 [(parallel
4069 [(set (match_operand:I48MODE 0 "register_operand" "")
4070 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "")
4071 (match_operand:I48MODE 2 "s8bit_cint_operand" "")))
4072 (set (mem:I124MODE (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
4073 (match_operand:DI 1 "reg_or_0_operand" "rO"))])]
4074 ""
4075 {
4076 operands[1] = simplify_gen_subreg (<I124MODE:MODE>mode, operands[1],
4077 DImode,
4078 BYTES_BIG_ENDIAN
4079 ? UNITS_PER_WORD - <n> : 0);
4080 })
4081
4082 (define_insn "*insn_stnt<I124MODE:n>_add<I48MODE:bitsuffix>"
4083 [(set (match_operand:I48MODE 0 "register_operand" "=r")
4084 (plus:I48MODE (match_operand:I48MODE 3 "register_operand" "0")
4085 (match_operand:I48MODE 2 "s8bit_cint_operand" "i")))
4086 (set (mem:I124MODE (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
4087 (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
4088 ""
4089 "stnt<I124MODE:n>_add\t%0, %r1, %2"
4090 [(set_attr "type" "X1")])
4091
4092 ;; end stores
4093
4094 (define_insn "insn_tblidxb0"
4095 [(set (match_operand:DI 0 "register_operand" "=r")
4096 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4097 (match_operand:DI 2 "reg_or_0_operand" "rO")]
4098 UNSPEC_INSN_TBLIDXB0))]
4099 ""
4100 "tblidxb0\t%0, %r2"
4101 [(set_attr "type" "Y0")])
4102
4103 (define_insn "insn_tblidxb1"
4104 [(set (match_operand:DI 0 "register_operand" "=r")
4105 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4106 (match_operand:DI 2 "reg_or_0_operand" "rO")]
4107 UNSPEC_INSN_TBLIDXB1))]
4108 ""
4109 "tblidxb1\t%0, %r2"
4110 [(set_attr "type" "Y0")])
4111
4112 (define_insn "insn_tblidxb2"
4113 [(set (match_operand:DI 0 "register_operand" "=r")
4114 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4115 (match_operand:DI 2 "reg_or_0_operand" "rO")]
4116 UNSPEC_INSN_TBLIDXB2))]
4117 ""
4118 "tblidxb2\t%0, %r2"
4119 [(set_attr "type" "Y0")])
4120
4121 (define_insn "insn_tblidxb3"
4122 [(set (match_operand:DI 0 "register_operand" "=r")
4123 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
4124 (match_operand:DI 2 "reg_or_0_operand" "rO")]
4125 UNSPEC_INSN_TBLIDXB3))]
4126 ""
4127 "tblidxb3\t%0, %r2"
4128 [(set_attr "type" "Y0")])
4129
4130 ;; insn_v1add
4131 ;; insn_v1addi
4132 ;; insn_v1cmpeq
4133 ;; insn_v1cmpeqi
4134 ;; insn_v1cmplts
4135 ;; insn_v1cmpltsi
4136 ;; insn_v1cmpltu
4137 ;; insn_v1cmpltui
4138 ;; insn_v1maxu
4139 ;; insn_v1maxui
4140 ;; insn_v1minu
4141 ;; insn_v1minui
4142 (define_insn "<optab>v8qi3"
4143 [(set (match_operand:V8QI 0 "register_operand" "=r,r")
4144 (v1op_immed:V8QI
4145 (match_operand:V8QI 1 "reg_or_0_operand" "<comm>rO,rO")
4146 (match_operand:V8QI 2 "reg_or_v8s8bit_operand" "W,rO")))]
4147 ""
4148 "@
4149 v1<insn>i\t%0, %r1, %j2
4150 v1<insn>\t%0, %r1, %r2"
4151 [(set_attr "type" "<pipe>,<pipe>")])
4152
4153 (define_expand "insn_v1<insn>"
4154 [(set (match_operand:DI 0 "register_operand" "")
4155 (v1op_immed:V8QI
4156 (match_operand:DI 1 "reg_or_0_operand" "")
4157 (match_operand:DI 2 "reg_or_0_operand" "")))]
4158 ""
4159 {
4160 tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4161 V8QImode, operands[1], operands[2], true);
4162 DONE;
4163 })
4164
4165 (define_expand "insn_v1<insn>i"
4166 [(set (match_operand:DI 0 "register_operand" "")
4167 (v1op_immed:V8QI
4168 (match_operand:DI 1 "reg_or_0_operand" "")
4169 (match_operand:DI 2 "s8bit_cint_operand" "")))]
4170 ""
4171 {
4172 /* Tile out immediate and expand to general case. */
4173 rtx n = tilegx_simd_int (operands[2], QImode);
4174 tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4175 V8QImode, operands[1], n, true);
4176 DONE;
4177 })
4178
4179 ;; insn_v1shl
4180 ;; insn_v1shli
4181 ;; insn_v1shrs
4182 ;; insn_v1shrsi
4183 ;; insn_v1shru
4184 ;; insn_v1shrui
4185 (define_insn "<optab>v8qi3"
4186 [(set (match_operand:V8QI 0 "register_operand" "=r,r")
4187 (any_shift:V8QI
4188 (match_operand:V8QI 1 "reg_or_0_operand" "rO,rO")
4189 (match_operand:DI 2 "reg_or_u5bit_operand" "I,rO")))]
4190 ""
4191 "@
4192 v1<insn>i\t%0, %r1, %2
4193 v1<insn>\t%0, %r1, %r2"
4194 [(set_attr "type" "<pipe>,<pipe>")])
4195
4196 (define_expand "insn_v1<insn>"
4197 [(set (match_operand:DI 0 "register_operand" "")
4198 (any_shift:V8QI
4199 (match_operand:DI 1 "reg_or_0_operand" "")
4200 (match_operand:DI 2 "reg_or_u5bit_operand" "")))]
4201 ""
4202 {
4203 tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4204 V8QImode, operands[1], operands[2], false);
4205 DONE;
4206 })
4207
4208 ;; insn_v2add
4209 ;; insn_v2addi
4210 ;; insn_v2maxs
4211 ;; insn_v2maxsi
4212 ;; insn_v2mins
4213 ;; insn_v2minsi
4214 ;; insn_v2cmpeq
4215 ;; insn_v2cmpeqi
4216 ;; insn_v2cmplts
4217 ;; insn_v2cmpltsi
4218 ;; insn_v2cmpltu
4219 ;; insn_v2cmpltui
4220 (define_insn "<optab>v4hi3"
4221 [(set (match_operand:V4HI 0 "register_operand" "=r,r")
4222 (v2op_immed:V4HI
4223 (match_operand:V4HI 1 "reg_or_0_operand" "<comm>rO,rO")
4224 (match_operand:V4HI 2 "reg_or_v4s8bit_operand" "Y,rO")))]
4225 ""
4226 "@
4227 v2<insn>i\t%0, %r1, %j2
4228 v2<insn>\t%0, %r1, %r2"
4229 [(set_attr "type" "<pipe>,<pipe>")])
4230
4231 (define_expand "insn_v2<insn>"
4232 [(set (match_operand:DI 0 "register_operand" "")
4233 (v2op_immed:V4HI
4234 (match_operand:DI 1 "reg_or_0_operand" "")
4235 (match_operand:DI 2 "reg_or_0_operand" "")))]
4236 ""
4237 {
4238 tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4239 V4HImode, operands[1], operands[2], true);
4240 DONE;
4241 })
4242
4243 (define_expand "insn_v2<insn>i"
4244 [(set (match_operand:DI 0 "register_operand" "")
4245 (v2op_immed:V4HI
4246 (match_operand:DI 1 "reg_or_0_operand" "")
4247 (match_operand:DI 2 "s8bit_cint_operand" "")))]
4248 ""
4249 {
4250 /* Tile out immediate and expand to general case. */
4251 rtx n = tilegx_simd_int (operands[2], HImode);
4252 tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4253 V4HImode, operands[1], n, true);
4254 DONE;
4255 })
4256
4257 ;; insn_v2shl
4258 ;; insn_v2shli
4259 ;; insn_v2shrs
4260 ;; insn_v2shrsi
4261 ;; insn_v2shru
4262 ;; insn_v2shrui
4263 (define_insn "<optab>v4hi3"
4264 [(set (match_operand:V4HI 0 "register_operand" "=r,r")
4265 (any_shift:V4HI
4266 (match_operand:V4HI 1 "reg_or_0_operand" "rO,rO")
4267 (match_operand:DI 2 "reg_or_u5bit_operand" "I,rO")))]
4268 ""
4269 "@
4270 v2<insn>i\t%0, %r1, %2
4271 v2<insn>\t%0, %r1, %r2"
4272 [(set_attr "type" "<pipe>,<pipe>")])
4273
4274 (define_expand "insn_v2<insn>"
4275 [(set (match_operand:DI 0 "register_operand" "")
4276 (any_shift:V4HI
4277 (match_operand:DI 1 "reg_or_0_operand" "")
4278 (match_operand:DI 2 "reg_or_u5bit_operand" "")))]
4279 ""
4280 {
4281 tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4282 V4HImode, operands[1], operands[2], false);
4283 DONE;
4284 })
4285
4286 ;; insn_v1adduc
4287 ;; insn_v1subuc
4288 ;; insn_v1sub
4289 ;; insn_v1cmpne
4290 ;; insn_v1cmples
4291 ;; insn_v1cmpleu
4292 ;; insn_v1multu
4293 (define_insn "<optab>v8qi3"
4294 [(set (match_operand:V8QI 0 "register_operand" "=r")
4295 (v1op:V8QI
4296 (match_operand:V8QI 1 "reg_or_0_operand" "<comm>rO")
4297 (match_operand:V8QI 2 "reg_or_0_operand" "rO")))]
4298 ""
4299 "v1<insn>\t%0, %r1, %r2"
4300 [(set_attr "type" "<pipe>")])
4301
4302 (define_expand "insn_v1<insn>"
4303 [(set (match_operand:DI 0 "register_operand" "")
4304 (v1op:V8QI
4305 (match_operand:DI 1 "reg_or_0_operand" "")
4306 (match_operand:DI 2 "reg_or_0_operand" "")))]
4307 ""
4308 {
4309 tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
4310 V8QImode, operands[1], operands[2], true);
4311 DONE;
4312 })
4313
4314 ;; insn_v2addsc
4315 ;; insn_v2subsc
4316 ;; insn_v2sub
4317 ;; insn_v2cmpne
4318 ;; insn_v2cmples
4319 ;; insn_v2cmpleu
4320 (define_insn "<optab>v4hi3"
4321 [(set (match_operand:V4HI 0 "register_operand" "=r")
4322 (v2op:V4HI
4323 (match_operand:V4HI 1 "reg_or_0_operand" "<comm>rO")
4324 (match_operand:V4HI 2 "reg_or_0_operand" "rO")))]
4325 ""
4326 "v2<insn>\t%0, %r1, %r2"
4327 [(set_attr "type" "<pipe>")])
4328
4329 (define_expand "insn_v2<insn>"
4330 [(set (match_operand:DI 0 "register_operand" "")
4331 (v2op:V4HI
4332 (match_operand:DI 1 "reg_or_0_operand" "")
4333 (match_operand:DI 2 "reg_or_0_operand" "")))]
4334 ""
4335 {
4336 tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4337 V4HImode, operands[1], operands[2], true);
4338 DONE;
4339 })
4340
4341 ;; insn_v2mults
4342 (define_insn "mulv4hi3"
4343 [(set (match_operand:V4HI 0 "register_operand" "=r")
4344 (mult:V4HI
4345 (match_operand:V4HI 1 "reg_or_0_operand" "%rO")
4346 (match_operand:V4HI 2 "reg_or_0_operand" "rO")))]
4347 ""
4348 "v2mults\t%0, %r1, %r2"
4349 [(set_attr "type" "X0_2cycle")])
4350
4351 (define_expand "insn_v2mults"
4352 [(set (match_operand:DI 0 "register_operand" "")
4353 (mult:V4HI
4354 (match_operand:DI 1 "reg_or_0_operand" "")
4355 (match_operand:DI 2 "reg_or_0_operand" "")))]
4356 ""
4357 {
4358 tilegx_expand_builtin_vector_binop (gen_mulv4hi3, V4HImode, operands[0],
4359 V4HImode, operands[1], operands[2], true);
4360 DONE;
4361 })
4362
4363 ;; insn_v2shlsc
4364 (define_insn "<optab>v4hi3"
4365 [(set (match_operand:V4HI 0 "register_operand" "=r")
4366 (v2shift:V4HI
4367 (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4368 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
4369 ""
4370 "v2<insn>\t%0, %r1, %r2"
4371 [(set_attr "type" "<pipe>")])
4372
4373 (define_expand "insn_v2<insn>"
4374 [(set (match_operand:DI 0 "register_operand" "")
4375 (v2shift:V4HI
4376 (match_operand:DI 1 "reg_or_0_operand" "")
4377 (match_operand:DI 2 "reg_or_0_operand" "")))]
4378 ""
4379 {
4380 tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
4381 V4HImode, operands[1], operands[2], false);
4382 DONE;
4383 })
4384
4385 ;; insn_v4addsc
4386 ;; insn_v4subsc
4387 ;; insn_v4add
4388 ;; insn_v4sub
4389 (define_insn "<optab>v2si3"
4390 [(set (match_operand:V2SI 0 "register_operand" "=r")
4391 (v4op:V2SI
4392 (match_operand:V2SI 1 "reg_or_0_operand" "<comm>rO")
4393 (match_operand:V2SI 2 "reg_or_0_operand" "rO")))]
4394 ""
4395 "v4<insn>\t%0, %r1, %r2"
4396 [(set_attr "type" "<pipe>")])
4397
4398 (define_expand "insn_v4<insn>"
4399 [(set (match_operand:DI 0 "register_operand" "")
4400 (v4op:V2SI
4401 (match_operand:DI 1 "reg_or_0_operand" "")
4402 (match_operand:DI 2 "reg_or_0_operand" "")))]
4403 ""
4404 {
4405 tilegx_expand_builtin_vector_binop (gen_<optab>v2si3, V2SImode, operands[0],
4406 V2SImode, operands[1], operands[2], true);
4407 DONE;
4408 })
4409
4410 ;; insn_v4shl
4411 ;; insn_v4shrs
4412 ;; insn_v4shru
4413 ;; insn_v4shlsc
4414 (define_insn "<optab>v2si3"
4415 [(set (match_operand:V2SI 0 "register_operand" "=r")
4416 (v4shift:V2SI
4417 (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4418 (match_operand:DI 2 "reg_or_0_operand" "rO")))]
4419 ""
4420 "v4<insn>\t%0, %r1, %r2"
4421 [(set_attr "type" "<pipe>")])
4422
4423 (define_expand "insn_v4<insn>"
4424 [(set (match_operand:DI 0 "register_operand" "")
4425 (v4shift:V2SI
4426 (match_operand:DI 1 "reg_or_0_operand" "")
4427 (match_operand:DI 2 "reg_or_0_operand" "")))]
4428 ""
4429 {
4430 tilegx_expand_builtin_vector_binop (gen_<optab>v2si3, V2SImode, operands[0],
4431 V2SImode, operands[1], operands[2], false);
4432 DONE;
4433 })
4434
4435 ;; Byte ordering of these vectors is endian dependent. gcc concats
4436 ;; right-to-left for little endian, and left-to-right for big endian.
4437 ;; So we need different patterns that depend on endianness. Our
4438 ;; instructions concat and interleave the way a big-endian target would
4439 ;; work in gcc, so for little endian, we need to reverse the source
4440 ;; operands.
4441
4442 ;; insn_v1int_h
4443 ;; {B7,B6,B5,B4,B3,B2,B1,B0} {A7,A6,A5,A4,A3,A2,A1,A0}
4444 ;; => {A7,A6,A5,A4,A3,A2,A1,A0,B7,B6,B5,B4,B3,B2,B1,B0}
4445 ;; => {A7,B7,A6,B6,A5,B5,A4,B4}
4446 (define_expand "vec_interleave_highv8qi"
4447 [(match_operand:V8QI 0 "register_operand" "")
4448 (match_operand:V8QI 1 "reg_or_0_operand" "")
4449 (match_operand:V8QI 2 "reg_or_0_operand" "")]
4450 ""
4451 {
4452 if (BYTES_BIG_ENDIAN)
4453 emit_insn (gen_vec_interleave_highv8qi_be (operands[0], operands[1],
4454 operands[2]));
4455 else
4456 emit_insn (gen_vec_interleave_highv8qi_le (operands[0], operands[1],
4457 operands[2]));
4458 DONE;
4459 })
4460
4461 (define_insn "vec_interleave_highv8qi_be"
4462 [(set (match_operand:V8QI 0 "register_operand" "=r")
4463 (vec_select:V8QI
4464 (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4465 (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4466 (parallel [(const_int 0) (const_int 8)
4467 (const_int 1) (const_int 9)
4468 (const_int 2) (const_int 10)
4469 (const_int 3) (const_int 11)])))]
4470 "BYTES_BIG_ENDIAN"
4471 "v1int_h\t%0, %r1, %r2"
4472 [(set_attr "type" "X01")])
4473
4474 (define_insn "vec_interleave_highv8qi_le"
4475 [(set (match_operand:V8QI 0 "register_operand" "=r")
4476 (vec_select:V8QI
4477 (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4478 (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4479 (parallel [(const_int 4) (const_int 12)
4480 (const_int 5) (const_int 13)
4481 (const_int 6) (const_int 14)
4482 (const_int 7) (const_int 15)])))]
4483 "!BYTES_BIG_ENDIAN"
4484 "v1int_h\t%0, %r2, %r1"
4485 [(set_attr "type" "X01")])
4486
4487 (define_expand "insn_v1int_h"
4488 [(match_operand:DI 0 "register_operand" "")
4489 (match_operand:DI 1 "reg_or_0_operand" "")
4490 (match_operand:DI 2 "reg_or_0_operand" "")]
4491 ""
4492 {
4493 /* For little endian, our instruction interleaves opposite of the
4494 way vec_interleave works, so we need to reverse the source
4495 operands. */
4496 rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4497 rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4498 tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv8qi, V8QImode,
4499 operands[0], V8QImode, opnd1, opnd2,
4500 true);
4501 DONE;
4502 })
4503
4504 ;; insn_v1int_l
4505 ;; {B7,B6,B5,B4,B3,B2,B1,B0} {A7,A6,A5,A4,A3,A2,A1,A0}
4506 ;; => {A7,A6,A5,A4,A3,A2,A1,A0,B7,B6,B5,B4,B3,B2,B1,B0}
4507 ;; => {A3,B3,A2,B2,A1,B1,A0,B0}
4508 (define_expand "vec_interleave_lowv8qi"
4509 [(match_operand:V8QI 0 "register_operand" "")
4510 (match_operand:V8QI 1 "reg_or_0_operand" "")
4511 (match_operand:V8QI 2 "reg_or_0_operand" "")]
4512 ""
4513 {
4514 if (BYTES_BIG_ENDIAN)
4515 emit_insn (gen_vec_interleave_lowv8qi_be (operands[0], operands[1],
4516 operands[2]));
4517 else
4518 emit_insn (gen_vec_interleave_lowv8qi_le (operands[0], operands[1],
4519 operands[2]));
4520 DONE;
4521 })
4522
4523 (define_insn "vec_interleave_lowv8qi_be"
4524 [(set (match_operand:V8QI 0 "register_operand" "=r")
4525 (vec_select:V8QI
4526 (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4527 (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4528 (parallel [(const_int 4) (const_int 12)
4529 (const_int 5) (const_int 13)
4530 (const_int 6) (const_int 14)
4531 (const_int 7) (const_int 15)])))]
4532 "BYTES_BIG_ENDIAN"
4533 "v1int_l\t%0, %r1, %r2"
4534 [(set_attr "type" "X01")])
4535
4536 (define_insn "vec_interleave_lowv8qi_le"
4537 [(set (match_operand:V8QI 0 "register_operand" "=r")
4538 (vec_select:V8QI
4539 (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4540 (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
4541 (parallel [(const_int 0) (const_int 8)
4542 (const_int 1) (const_int 9)
4543 (const_int 2) (const_int 10)
4544 (const_int 3) (const_int 11)])))]
4545 "!BYTES_BIG_ENDIAN"
4546 "v1int_l\t%0, %r2, %r1"
4547 [(set_attr "type" "X01")])
4548
4549 (define_expand "insn_v1int_l"
4550 [(match_operand:DI 0 "register_operand" "")
4551 (match_operand:DI 1 "reg_or_0_operand" "")
4552 (match_operand:DI 2 "reg_or_0_operand" "")]
4553 ""
4554 {
4555 /* For little endian, our instruction interleaves opposite of the
4556 way vec_interleave works, so we need to reverse the source
4557 operands. */
4558 rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4559 rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4560 tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv8qi, V8QImode,
4561 operands[0], V8QImode, opnd1, opnd2,
4562 true);
4563 DONE;
4564 })
4565
4566 ;; insn_v2int_h
4567 ;; {B3,B2,B1,B0} {A3,A2,A1,A0}
4568 ;; => {A3,A2,A1,A0,B3,B2,B1,B0}
4569 ;; => {A3,B3,A2,B2}
4570 (define_expand "vec_interleave_highv4hi"
4571 [(match_operand:V4HI 0 "register_operand" "")
4572 (match_operand:V4HI 1 "reg_or_0_operand" "")
4573 (match_operand:V4HI 2 "reg_or_0_operand" "")]
4574 ""
4575 {
4576 if (BYTES_BIG_ENDIAN)
4577 emit_insn (gen_vec_interleave_highv4hi_be (operands[0], operands[1],
4578 operands[2]));
4579 else
4580 emit_insn (gen_vec_interleave_highv4hi_le (operands[0], operands[1],
4581 operands[2]));
4582 DONE;
4583 })
4584
4585 (define_insn "vec_interleave_highv4hi_be"
4586 [(set (match_operand:V4HI 0 "register_operand" "=r")
4587 (vec_select:V4HI
4588 (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4589 (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4590 (parallel [(const_int 0) (const_int 4)
4591 (const_int 1) (const_int 5)])))]
4592 "BYTES_BIG_ENDIAN"
4593 "v2int_h\t%0, %r1, %r2"
4594 [(set_attr "type" "X01")])
4595
4596 (define_insn "vec_interleave_highv4hi_le"
4597 [(set (match_operand:V4HI 0 "register_operand" "=r")
4598 (vec_select:V4HI
4599 (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4600 (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4601 (parallel [(const_int 2) (const_int 6)
4602 (const_int 3) (const_int 7)])))]
4603 "!BYTES_BIG_ENDIAN"
4604 "v2int_h\t%0, %r2, %r1"
4605 [(set_attr "type" "X01")])
4606
4607 (define_expand "insn_v2int_h"
4608 [(match_operand:DI 0 "register_operand" "")
4609 (match_operand:DI 1 "reg_or_0_operand" "")
4610 (match_operand:DI 2 "reg_or_0_operand" "")]
4611 ""
4612 {
4613 /* For little endian, our instruction interleaves opposite of the
4614 way vec_interleave works, so we need to reverse the source
4615 operands. */
4616 rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4617 rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4618 tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv4hi, V4HImode,
4619 operands[0], V4HImode, opnd1, opnd2,
4620 true);
4621 DONE;
4622 })
4623
4624 ;; insn_v2int_l
4625 ;; {B3,B2,B1,B0} {A3,A2,A1,A0}
4626 ;; => {A3,A2,A1,A0,B3,B2,B1,B0}
4627 ;; => {A1,B1,A0,B0}
4628 (define_expand "vec_interleave_lowv4hi"
4629 [(match_operand:V4HI 0 "register_operand" "")
4630 (match_operand:V4HI 1 "reg_or_0_operand" "")
4631 (match_operand:V4HI 2 "reg_or_0_operand" "")]
4632 ""
4633 {
4634 if (BYTES_BIG_ENDIAN)
4635 emit_insn (gen_vec_interleave_lowv4hi_be (operands[0], operands[1],
4636 operands[2]));
4637 else
4638 emit_insn (gen_vec_interleave_lowv4hi_le (operands[0], operands[1],
4639 operands[2]));
4640 DONE;
4641 })
4642
4643 (define_insn "vec_interleave_lowv4hi_be"
4644 [(set (match_operand:V4HI 0 "register_operand" "=r")
4645 (vec_select:V4HI
4646 (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4647 (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4648 (parallel [(const_int 2) (const_int 6)
4649 (const_int 3) (const_int 7)])))]
4650 "BYTES_BIG_ENDIAN"
4651 "v2int_l\t%0, %r1, %r2"
4652 [(set_attr "type" "X01")])
4653
4654 (define_insn "vec_interleave_lowv4hi_le"
4655 [(set (match_operand:V4HI 0 "register_operand" "=r")
4656 (vec_select:V4HI
4657 (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4658 (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
4659 (parallel [(const_int 0) (const_int 4)
4660 (const_int 1) (const_int 5)])))]
4661 "!BYTES_BIG_ENDIAN"
4662 "v2int_l\t%0, %r2, %r1"
4663 [(set_attr "type" "X01")])
4664
4665 (define_expand "insn_v2int_l"
4666 [(match_operand:DI 0 "register_operand" "")
4667 (match_operand:DI 1 "reg_or_0_operand" "")
4668 (match_operand:DI 2 "reg_or_0_operand" "")]
4669 ""
4670 {
4671 /* For little endian, our instruction interleaves opposite of the
4672 way vec_interleave works, so we need to reverse the source
4673 operands. */
4674 rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4675 rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4676 tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv4hi, V4HImode,
4677 operands[0], V4HImode, opnd1, opnd2,
4678 true);
4679 DONE;
4680 })
4681
4682 ;; insn_v4int_h
4683 ;; {B1,B0} {A1,A0}
4684 ;; => {A1,A0,B1,B0}
4685 ;; => {A1,B1}
4686 (define_expand "vec_interleave_highv2si"
4687 [(match_operand:V2SI 0 "register_operand" "")
4688 (match_operand:V2SI 1 "reg_or_0_operand" "")
4689 (match_operand:V2SI 2 "reg_or_0_operand" "")]
4690 ""
4691 {
4692 if (BYTES_BIG_ENDIAN)
4693 emit_insn (gen_vec_interleave_highv2si_be (operands[0], operands[1],
4694 operands[2]));
4695 else
4696 emit_insn (gen_vec_interleave_highv2si_le (operands[0], operands[1],
4697 operands[2]));
4698 DONE;
4699 })
4700
4701 (define_insn "vec_interleave_highv2si_be"
4702 [(set (match_operand:V2SI 0 "register_operand" "=r")
4703 (vec_select:V2SI
4704 (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4705 (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4706 (parallel [(const_int 0) (const_int 2)])))]
4707 "BYTES_BIG_ENDIAN"
4708 "v4int_h\t%0, %r1, %r2"
4709 [(set_attr "type" "X01")])
4710
4711 (define_insn "vec_interleave_highv2si_le"
4712 [(set (match_operand:V2SI 0 "register_operand" "=r")
4713 (vec_select:V2SI
4714 (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4715 (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4716 (parallel [(const_int 1) (const_int 3)])))]
4717 "!BYTES_BIG_ENDIAN"
4718 "v4int_h\t%0, %r2, %r1"
4719 [(set_attr "type" "X01")])
4720
4721 (define_expand "insn_v4int_h"
4722 [(match_operand:DI 0 "register_operand" "")
4723 (match_operand:DI 1 "reg_or_0_operand" "")
4724 (match_operand:DI 2 "reg_or_0_operand" "")]
4725 ""
4726 {
4727 /* For little endian, our instruction interleaves opposite of the
4728 way vec_interleave works, so we need to reverse the source
4729 operands. */
4730 rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4731 rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4732 tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv2si, V2SImode,
4733 operands[0], V2SImode, opnd1, opnd2,
4734 true);
4735 DONE;
4736 })
4737
4738 ;; insn_v4int_l
4739 ;; {B1,B0} {A1,A0}
4740 ;; => {A1,A0,B1,B0}
4741 ;; => {A0,B0}
4742 (define_expand "vec_interleave_lowv2si"
4743 [(match_operand:V2SI 0 "register_operand" "")
4744 (match_operand:V2SI 1 "reg_or_0_operand" "")
4745 (match_operand:V2SI 2 "reg_or_0_operand" "")]
4746 ""
4747 {
4748 if (BYTES_BIG_ENDIAN)
4749 emit_insn (gen_vec_interleave_lowv2si_be (operands[0], operands[1],
4750 operands[2]));
4751 else
4752 emit_insn (gen_vec_interleave_lowv2si_le (operands[0], operands[1],
4753 operands[2]));
4754 DONE;
4755 })
4756
4757 (define_insn "vec_interleave_lowv2si_be"
4758 [(set (match_operand:V2SI 0 "register_operand" "=r")
4759 (vec_select:V2SI
4760 (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4761 (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4762 (parallel [(const_int 1) (const_int 3)])))]
4763 "BYTES_BIG_ENDIAN"
4764 "v4int_l\t%0, %r1, %r2"
4765 [(set_attr "type" "X01")])
4766
4767 (define_insn "vec_interleave_lowv2si_le"
4768 [(set (match_operand:V2SI 0 "register_operand" "=r")
4769 (vec_select:V2SI
4770 (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
4771 (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
4772 (parallel [(const_int 0) (const_int 2)])))]
4773 "!BYTES_BIG_ENDIAN"
4774 "v4int_l\t%0, %r2, %r1"
4775 [(set_attr "type" "X01")])
4776
4777 (define_expand "insn_v4int_l"
4778 [(match_operand:DI 0 "register_operand" "")
4779 (match_operand:DI 1 "reg_or_0_operand" "")
4780 (match_operand:DI 2 "reg_or_0_operand" "")]
4781 ""
4782 {
4783 /* For little endian, our instruction interleaves opposite of the
4784 way vec_interleave works, so we need to reverse the source
4785 operands. */
4786 rtx opnd1 = BYTES_BIG_ENDIAN ? operands[1] : operands[2];
4787 rtx opnd2 = BYTES_BIG_ENDIAN ? operands[2] : operands[1];
4788 tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv2si, V2SImode,
4789 operands[0], V2SImode, opnd1, opnd2,
4790 true);
4791 DONE;
4792 })
4793
4794 ;; insn_v1mnz
4795 ;; insn_v1mz
4796 ;; insn_v2mnz
4797 ;; insn_v2mz
4798 (define_insn "insn_mnz_v8qi"
4799 [(set (match_operand:V8QI 0 "register_operand" "=r")
4800 (if_then_else:V8QI
4801 (ne:V8QI
4802 (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4803 (const_vector:V8QI [(const_int 0) (const_int 0)
4804 (const_int 0) (const_int 0)
4805 (const_int 0) (const_int 0)
4806 (const_int 0) (const_int 0)]))
4807 (match_operand:V8QI 2 "reg_or_0_operand" "rO")
4808 (const_vector:V8QI [(const_int 0) (const_int 0)
4809 (const_int 0) (const_int 0)
4810 (const_int 0) (const_int 0)
4811 (const_int 0) (const_int 0)])))]
4812 ""
4813 "v1mnz\t%0, %r1, %r2"
4814 [(set_attr "type" "X01")])
4815
4816 (define_expand "insn_v1mnz"
4817 [(set (match_operand:DI 0 "register_operand" "")
4818 (if_then_else:V8QI
4819 (ne:V8QI
4820 (match_operand:DI 1 "reg_or_0_operand" "")
4821 (const_vector:V8QI [(const_int 0) (const_int 0)
4822 (const_int 0) (const_int 0)
4823 (const_int 0) (const_int 0)
4824 (const_int 0) (const_int 0)])
4825 )
4826 (match_operand:DI 2 "reg_or_0_operand" "")
4827 (const_vector:V8QI [(const_int 0) (const_int 0)
4828 (const_int 0) (const_int 0)
4829 (const_int 0) (const_int 0)
4830 (const_int 0) (const_int 0)])))]
4831 ""
4832 {
4833 tilegx_expand_builtin_vector_binop (gen_insn_mnz_v8qi, V8QImode,
4834 operands[0], V8QImode, operands[1],
4835 operands[2], true);
4836 DONE;
4837 })
4838
4839 (define_insn "insn_mz_v8qi"
4840 [(set (match_operand:V8QI 0 "register_operand" "=r")
4841 (if_then_else:V8QI
4842 (ne:V8QI
4843 (match_operand:V8QI 1 "reg_or_0_operand" "rO")
4844 (const_vector:V8QI [(const_int 0) (const_int 0)
4845 (const_int 0) (const_int 0)
4846 (const_int 0) (const_int 0)
4847 (const_int 0) (const_int 0)]))
4848 (const_vector:V8QI [(const_int 0) (const_int 0)
4849 (const_int 0) (const_int 0)
4850 (const_int 0) (const_int 0)
4851 (const_int 0) (const_int 0)])
4852 (match_operand:V8QI 2 "reg_or_0_operand" "rO")))]
4853 ""
4854 "v1mz\t%0, %r1, %r2"
4855 [(set_attr "type" "X01")])
4856
4857 (define_expand "insn_v1mz"
4858 [(set (match_operand:DI 0 "register_operand" "")
4859 (if_then_else:V8QI
4860 (ne:V8QI
4861 (match_operand:DI 1 "reg_or_0_operand" "")
4862 (const_vector:V8QI [(const_int 0) (const_int 0)
4863 (const_int 0) (const_int 0)
4864 (const_int 0) (const_int 0)
4865 (const_int 0) (const_int 0)]))
4866 (const_vector:V8QI [(const_int 0) (const_int 0)
4867 (const_int 0) (const_int 0)
4868 (const_int 0) (const_int 0)
4869 (const_int 0) (const_int 0)])
4870 (match_operand:DI 2 "reg_or_0_operand" "")))]
4871 ""
4872 {
4873 tilegx_expand_builtin_vector_binop (gen_insn_mz_v8qi, V8QImode,
4874 operands[0], V8QImode, operands[1],
4875 operands[2], true);
4876 DONE;
4877 })
4878
4879 (define_insn "insn_mnz_v4hi"
4880 [(set (match_operand:V4HI 0 "register_operand" "=r")
4881 (if_then_else:V4HI
4882 (ne:V4HI
4883 (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4884 (const_vector:V4HI [(const_int 0) (const_int 0)
4885 (const_int 0) (const_int 0)]))
4886 (match_operand:V4HI 2 "reg_or_0_operand" "rO")
4887 (const_vector:V4HI [(const_int 0) (const_int 0)
4888 (const_int 0) (const_int 0)])))]
4889 ""
4890 "v2mnz\t%0, %r1, %r2"
4891 [(set_attr "type" "X01")])
4892
4893 (define_expand "insn_v2mnz"
4894 [(set (match_operand:DI 0 "register_operand" "")
4895 (if_then_else:V4HI
4896 (ne:V4HI
4897 (match_operand:DI 1 "reg_or_0_operand" "")
4898 (const_vector:V4HI [(const_int 0) (const_int 0)
4899 (const_int 0) (const_int 0)]))
4900 (match_operand:DI 2 "reg_or_0_operand" "")
4901 (const_vector:V4HI [(const_int 0) (const_int 0)
4902 (const_int 0) (const_int 0)])))]
4903 ""
4904 {
4905 tilegx_expand_builtin_vector_binop (gen_insn_mnz_v4hi, V4HImode,
4906 operands[0], V4HImode, operands[1],
4907 operands[2], true);
4908 DONE;
4909 })
4910
4911 (define_insn "insn_mz_v4hi"
4912 [(set (match_operand:V4HI 0 "register_operand" "=r")
4913 (if_then_else:V4HI
4914 (ne:V4HI
4915 (match_operand:V4HI 1 "reg_or_0_operand" "rO")
4916 (const_vector:V4HI [(const_int 0) (const_int 0)
4917 (const_int 0) (const_int 0)]))
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 ""
4922 "v2mz\t%0, %r1, %r2"
4923 [(set_attr "type" "X01")])
4924
4925 (define_expand "insn_v2mz"
4926 [(set (match_operand:DI 0 "register_operand" "")
4927 (if_then_else:V4HI
4928 (ne:V4HI
4929 (match_operand:DI 1 "reg_or_0_operand" "")
4930 (const_vector:V4HI [(const_int 0) (const_int 0)
4931 (const_int 0) (const_int 0)]))
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 ""
4936 {
4937 tilegx_expand_builtin_vector_binop (gen_insn_mz_v4hi, V4HImode,
4938 operands[0], V4HImode, operands[1],
4939 operands[2], true);
4940 DONE;
4941 })
4942
4943 ;; insn_v1mulu
4944 (define_insn "vec_widen_umult_lo_v8qi"
4945 [(set (match_operand:V4HI 0 "register_operand" "=r")
4946 (mult:V4HI
4947 (zero_extend:V4HI
4948 (vec_select:V4QI
4949 (match_operand:V8QI 1 "register_operand" "r")
4950 (parallel [(const_int 0) (const_int 1)
4951 (const_int 2) (const_int 3)])))
4952 (zero_extend:V4HI
4953 (vec_select:V4QI
4954 (match_operand:V8QI 2 "register_operand" "r")
4955 (parallel [(const_int 0) (const_int 1)
4956 (const_int 2) (const_int 3)])))))]
4957 ""
4958 "v1mulu\t%0, %r1, %r2"
4959 [(set_attr "type" "X0_2cycle")])
4960
4961 (define_expand "insn_v1mulu"
4962 [(match_operand:DI 0 "register_operand" "")
4963 (match_operand:DI 1 "register_operand" "")
4964 (match_operand:DI 2 "register_operand" "")]
4965 ""
4966 {
4967 tilegx_expand_builtin_vector_binop (gen_vec_widen_umult_lo_v8qi, V4HImode,
4968 operands[0], V8QImode, operands[1],
4969 operands[2], true);
4970 DONE;
4971 })
4972
4973 ;; insn_v1mulus
4974 (define_insn "vec_widen_usmult_lo_v8qi"
4975 [(set (match_operand:V4HI 0 "register_operand" "=r")
4976 (mult:V4HI
4977 (zero_extend:V4HI
4978 (vec_select:V4QI
4979 (match_operand:V8QI 1 "register_operand" "r")
4980 (parallel [(const_int 0) (const_int 1)
4981 (const_int 2) (const_int 3)])))
4982 (sign_extend:V4HI
4983 (vec_select:V4QI
4984 (match_operand:V8QI 2 "register_operand" "r")
4985 (parallel [(const_int 0) (const_int 1)
4986 (const_int 2) (const_int 3)])))))]
4987 ""
4988 "v1mulus\t%0, %r1, %r2"
4989 [(set_attr "type" "X0_2cycle")])
4990
4991 (define_expand "insn_v1mulus"
4992 [(match_operand:DI 0 "register_operand" "")
4993 (match_operand:DI 1 "register_operand" "")
4994 (match_operand:DI 2 "register_operand" "")]
4995 ""
4996 {
4997 tilegx_expand_builtin_vector_binop (gen_vec_widen_usmult_lo_v8qi, V4HImode,
4998 operands[0], V8QImode, operands[1],
4999 operands[2], true);
5000 DONE;
5001 })
5002
5003 ;; insn_v2muls
5004 (define_insn "vec_widen_smult_lo_v4qi"
5005 [(set (match_operand:V2SI 0 "register_operand" "=r")
5006 (mult:V2SI
5007 (sign_extend:V2SI
5008 (vec_select:V2HI
5009 (match_operand:V4HI 1 "register_operand" "r")
5010 (parallel [(const_int 0) (const_int 1)])))
5011 (sign_extend:V2SI
5012 (vec_select:V2HI
5013 (match_operand:V4HI 2 "register_operand" "r")
5014 (parallel [(const_int 0) (const_int 1)])))))]
5015 ""
5016 "v2muls\t%0, %r1, %r2"
5017 [(set_attr "type" "X0_2cycle")])
5018
5019 (define_expand "insn_v2muls"
5020 [(match_operand:DI 0 "register_operand" "")
5021 (match_operand:DI 1 "register_operand" "")
5022 (match_operand:DI 2 "register_operand" "")]
5023 ""
5024 {
5025 tilegx_expand_builtin_vector_binop (gen_vec_widen_smult_lo_v4qi, V2SImode,
5026 operands[0], V4HImode, operands[1],
5027 operands[2], true);
5028 DONE;
5029 })
5030
5031 ;; v2packl
5032 ;; v2packuc
5033 ;; {B3,B2,B1,B0} {A3,A2,A1,A0}
5034 ;; => {A3,A2,A1,A0,B3,B2,B1,B0}
5035 (define_insn "vec_pack_<pack_optab>_v4hi"
5036 [(set (match_operand:V8QI 0 "register_operand" "=r")
5037 (vec_concat:V8QI
5038 (v2pack:V4QI (match_operand:V4HI 1 "reg_or_0_operand" "rO"))
5039 (v2pack:V4QI (match_operand:V4HI 2 "reg_or_0_operand" "rO"))))]
5040 ""
5041 "v2<pack_insn>\t%0, %r2, %r1"
5042 [(set_attr "type" "X01")])
5043
5044 (define_expand "insn_v2<pack_insn>"
5045 [(set (match_operand:DI 0 "register_operand" "")
5046 (vec_concat:V8QI
5047 (v2pack:V4QI (match_operand:DI 2 "reg_or_0_operand" ""))
5048 (v2pack:V4QI (match_operand:DI 1 "reg_or_0_operand" ""))))]
5049 ""
5050 {
5051 /* Our instruction concats opposite of the way vec_pack works, so we
5052 need to reverse the source operands. */
5053 tilegx_expand_builtin_vector_binop (gen_vec_pack_<pack_optab>_v4hi,
5054 V8QImode, operands[0], V4HImode,
5055 operands[2], operands[1], true);
5056 DONE;
5057 })
5058
5059 ;; v2packh
5060 ;; {B3,B2,B1,B0} {A3,A2,A1,A0}
5061 ;; => {A3_hi,A2_hi,A1_hi,A0_hi,B3_hi,B2_hi,B1_hi,B0_hi}
5062 (define_insn "vec_pack_hipart_v4hi"
5063 [(set (match_operand:V8QI 0 "register_operand" "=r")
5064 (vec_concat:V8QI
5065 (truncate:V4QI
5066 (ashiftrt:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
5067 (const_int 8)))
5068 (truncate:V4QI
5069 (ashiftrt:V4HI (match_operand:V4HI 2 "reg_or_0_operand" "rO")
5070 (const_int 8)))))]
5071 ""
5072 "v2packh\t%0, %r2, %r1"
5073 [(set_attr "type" "X01")])
5074
5075 (define_expand "insn_v2packh"
5076 [(set (match_operand:DI 0 "register_operand" "")
5077 (vec_concat:V8QI
5078 (truncate:V4QI
5079 (ashiftrt:V4HI (match_operand:DI 2 "reg_or_0_operand" "")
5080 (const_int 8)))
5081 (truncate:V4QI
5082 (ashiftrt:V4HI (match_operand:DI 1 "reg_or_0_operand" "")
5083 (const_int 8)))))]
5084 ""
5085 {
5086 /* Our instruction concats opposite of the way vec_pack works, so we
5087 need to reverse the source operands. */
5088 tilegx_expand_builtin_vector_binop (gen_vec_pack_hipart_v4hi, V8QImode,
5089 operands[0], V4HImode, operands[2],
5090 operands[1], true);
5091 DONE;
5092 })
5093
5094 ;; v4packsc
5095 ;; {B1,B0} {A1,A0}
5096 ;; => {A1,A0,B1,B0}
5097 (define_insn "vec_pack_ssat_v2si"
5098 [(set (match_operand:V4HI 0 "register_operand" "=r")
5099 (vec_concat:V4HI
5100 (us_truncate:V2HI (match_operand:V2SI 1 "reg_or_0_operand" "rO"))
5101 (us_truncate:V2HI (match_operand:V2SI 2 "reg_or_0_operand" "rO"))))]
5102 ""
5103 "v4packsc\t%0, %r2, %r1"
5104 [(set_attr "type" "X01")])
5105
5106 (define_expand "insn_v4packsc"
5107 [(set (match_operand:DI 0 "register_operand" "")
5108 (vec_concat:V4HI
5109 (us_truncate:V2HI (match_operand:DI 2 "reg_or_0_operand" ""))
5110 (us_truncate:V2HI (match_operand:DI 1 "reg_or_0_operand" ""))))]
5111 ""
5112 {
5113 /* Our instruction concats opposite of the way vec_pack works, so we
5114 need to reverse the source operands. */
5115 tilegx_expand_builtin_vector_binop (gen_vec_pack_ssat_v2si, V4HImode,
5116 operands[0], V2SImode, operands[2],
5117 operands[1], true);
5118 DONE;
5119 })
5120
5121 ;; Rest of the vector intrinsics
5122 (define_insn "insn_v1adiffu"
5123 [(set (match_operand:DI 0 "register_operand" "=r")
5124 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5125 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5126 UNSPEC_INSN_V1ADIFFU))]
5127 ""
5128 "v1adiffu\t%0, %r1, %r2"
5129 [(set_attr "type" "X0_2cycle")])
5130
5131 (define_insn "insn_v1avgu"
5132 [(set (match_operand:DI 0 "register_operand" "=r")
5133 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5134 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5135 UNSPEC_INSN_V1AVGU))]
5136 ""
5137 "v1avgu\t%0, %r1, %r2"
5138 [(set_attr "type" "X0")])
5139
5140 (define_insn "insn_v1ddotpu"
5141 [(set (match_operand:DI 0 "register_operand" "=r")
5142 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5143 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5144 UNSPEC_INSN_V1DDOTPU))]
5145 ""
5146 "v1ddotpu\t%0, %r1, %r2"
5147 [(set_attr "type" "X0_2cycle")])
5148
5149 (define_insn "insn_v1ddotpua"
5150 [(set (match_operand:DI 0 "register_operand" "=r")
5151 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5152 (match_operand:DI 2 "reg_or_0_operand" "rO")
5153 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5154 UNSPEC_INSN_V1DDOTPUA))]
5155 ""
5156 "v1ddotpua\t%0, %r2, %r3"
5157 [(set_attr "type" "X0_2cycle")])
5158
5159 (define_insn "insn_v1ddotpus"
5160 [(set (match_operand:DI 0 "register_operand" "=r")
5161 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5162 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5163 UNSPEC_INSN_V1DDOTPUS))]
5164 ""
5165 "v1ddotpus\t%0, %r1, %r2"
5166 [(set_attr "type" "X0_2cycle")])
5167
5168 (define_insn "insn_v1ddotpusa"
5169 [(set (match_operand:DI 0 "register_operand" "=r")
5170 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5171 (match_operand:DI 2 "reg_or_0_operand" "rO")
5172 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5173 UNSPEC_INSN_V1DDOTPUSA))]
5174 ""
5175 "v1ddotpusa\t%0, %r2, %r3"
5176 [(set_attr "type" "X0_2cycle")])
5177
5178 (define_insn "insn_v1dotp"
5179 [(set (match_operand:DI 0 "register_operand" "=r")
5180 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5181 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5182 UNSPEC_INSN_V1DOTP))]
5183 ""
5184 "v1dotp\t%0, %r1, %r2"
5185 [(set_attr "type" "X0_2cycle")])
5186
5187 (define_insn "insn_v1dotpa"
5188 [(set (match_operand:DI 0 "register_operand" "=r")
5189 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5190 (match_operand:DI 2 "reg_or_0_operand" "rO")
5191 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5192 UNSPEC_INSN_V1DOTPA))]
5193 ""
5194 "v1dotpa\t%0, %r2, %r3"
5195 [(set_attr "type" "X0_2cycle")])
5196
5197 (define_insn "insn_v1dotpu"
5198 [(set (match_operand:DI 0 "register_operand" "=r")
5199 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5200 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5201 UNSPEC_INSN_V1DOTPU))]
5202 ""
5203 "v1dotpu\t%0, %r1, %r2"
5204 [(set_attr "type" "X0_2cycle")])
5205
5206 (define_insn "insn_v1dotpua"
5207 [(set (match_operand:DI 0 "register_operand" "=r")
5208 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5209 (match_operand:DI 2 "reg_or_0_operand" "rO")
5210 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5211 UNSPEC_INSN_V1DOTPUA))]
5212 ""
5213 "v1dotpua\t%0, %r2, %r3"
5214 [(set_attr "type" "X0_2cycle")])
5215
5216 (define_insn "insn_v1dotpus"
5217 [(set (match_operand:DI 0 "register_operand" "=r")
5218 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5219 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5220 UNSPEC_INSN_V1DOTPUS))]
5221 ""
5222 "v1dotpus\t%0, %r1, %r2"
5223 [(set_attr "type" "X0_2cycle")])
5224
5225 (define_insn "insn_v1dotpusa"
5226 [(set (match_operand:DI 0 "register_operand" "=r")
5227 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5228 (match_operand:DI 2 "reg_or_0_operand" "rO")
5229 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5230 UNSPEC_INSN_V1DOTPUSA))]
5231 ""
5232 "v1dotpusa\t%0, %r2, %r3"
5233 [(set_attr "type" "X0_2cycle")])
5234
5235 (define_insn "insn_v1sadau"
5236 [(set (match_operand:DI 0 "register_operand" "=r")
5237 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5238 (match_operand:DI 2 "reg_or_0_operand" "rO")
5239 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5240 UNSPEC_INSN_V1SADAU))]
5241 ""
5242 "v1sadau\t%0, %r2, %r3"
5243 [(set_attr "type" "X0_2cycle")])
5244
5245 (define_insn "insn_v1sadu"
5246 [(set (match_operand:DI 0 "register_operand" "=r")
5247 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5248 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5249 UNSPEC_INSN_V1SADU))]
5250 ""
5251 "v1sadu\t%0, %r1, %r2"
5252 [(set_attr "type" "X0_2cycle")])
5253
5254 (define_insn "*insn_v1sadu"
5255 [(set (match_operand:SI 0 "register_operand" "=r")
5256 (truncate:SI
5257 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5258 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5259 UNSPEC_INSN_V1SADU)))]
5260 ""
5261 "v1sadu\t%0, %r1, %r2"
5262 [(set_attr "type" "X0_2cycle")])
5263
5264 (define_insn "insn_v2adiffs"
5265 [(set (match_operand:DI 0 "register_operand" "=r")
5266 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5267 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5268 UNSPEC_INSN_V2ADIFFS))]
5269 ""
5270 "v2adiffs\t%0, %r1, %r2"
5271 [(set_attr "type" "X0_2cycle")])
5272
5273 (define_insn "insn_v2avgs"
5274 [(set (match_operand:DI 0 "register_operand" "=r")
5275 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5276 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5277 UNSPEC_INSN_V2AVGS))]
5278 ""
5279 "v2avgs\t%0, %r1, %r2"
5280 [(set_attr "type" "X0")])
5281
5282 (define_insn "insn_v2dotp"
5283 [(set (match_operand:DI 0 "register_operand" "=r")
5284 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5285 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5286 UNSPEC_INSN_V2DOTP))]
5287 ""
5288 "v2dotp\t%0, %r1, %r2"
5289 [(set_attr "type" "X0_2cycle")])
5290
5291 (define_insn "insn_v2dotpa"
5292 [(set (match_operand:DI 0 "register_operand" "=r")
5293 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5294 (match_operand:DI 2 "reg_or_0_operand" "rO")
5295 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5296 UNSPEC_INSN_V2DOTPA))]
5297 ""
5298 "v2dotpa\t%0, %r2, %r3"
5299 [(set_attr "type" "X0_2cycle")])
5300
5301 (define_insn "insn_v2mulfsc"
5302 [(set (match_operand:DI 0 "register_operand" "=r")
5303 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5304 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5305 UNSPEC_INSN_V2MULFSC))]
5306 ""
5307 "v2mulfsc\t%0, %r1, %r2"
5308 [(set_attr "type" "X0_2cycle")])
5309
5310 (define_insn "insn_v2sadas"
5311 [(set (match_operand:DI 0 "register_operand" "=r")
5312 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5313 (match_operand:DI 2 "reg_or_0_operand" "rO")
5314 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5315 UNSPEC_INSN_V2SADAS))]
5316 ""
5317 "v2sadas\t%0, %r2, %r3"
5318 [(set_attr "type" "X0_2cycle")])
5319
5320 (define_insn "insn_v2sadau"
5321 [(set (match_operand:DI 0 "register_operand" "=r")
5322 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
5323 (match_operand:DI 2 "reg_or_0_operand" "rO")
5324 (match_operand:DI 3 "reg_or_0_operand" "rO")]
5325 UNSPEC_INSN_V2SADAU))]
5326 ""
5327 "v2sadau\t%0, %r2, %r3"
5328 [(set_attr "type" "X0_2cycle")])
5329
5330 (define_insn "insn_v2sads"
5331 [(set (match_operand:DI 0 "register_operand" "=r")
5332 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5333 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5334 UNSPEC_INSN_V2SADS))]
5335 ""
5336 "v2sads\t%0, %r1, %r2"
5337 [(set_attr "type" "X0_2cycle")])
5338
5339 (define_insn "*insn_v2sads"
5340 [(set (match_operand:SI 0 "register_operand" "=r")
5341 (truncate:SI
5342 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5343 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5344 UNSPEC_INSN_V2SADS)))]
5345 ""
5346 "v2sads\t%0, %r1, %r2"
5347 [(set_attr "type" "X0_2cycle")])
5348
5349 (define_insn "insn_v2sadu"
5350 [(set (match_operand:DI 0 "register_operand" "=r")
5351 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5352 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5353 UNSPEC_INSN_V2SADU))]
5354 ""
5355 "v2sadu\t%0, %r1, %r2"
5356 [(set_attr "type" "X0_2cycle")])
5357
5358 (define_insn "*insn_v2sadu"
5359 [(set (match_operand:SI 0 "register_operand" "=r")
5360 (truncate:SI
5361 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
5362 (match_operand:DI 2 "reg_or_0_operand" "rO")]
5363 UNSPEC_INSN_V2SADU)))]
5364 ""
5365 "v2sadu\t%0, %r1, %r2"
5366 [(set_attr "type" "X0_2cycle")])
5367
5368 (define_insn "insn_wh64"
5369 [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
5370 UNSPEC_INSN_WH64)
5371 (clobber (mem:BLK (const_int 0)))]
5372 ""
5373 "wh64\t%r0"
5374 [(set_attr "type" "X1")])
5375
5376 \f
5377 ;; Network intrinsics
5378
5379 ;; Note the this barrier is of type "nothing," which is deleted after
5380 ;; the final scheduling pass so that nothing is emitted for it.
5381 (define_insn "tilegx_network_barrier"
5382 [(unspec_volatile:SI [(const_int 0)] UNSPEC_NETWORK_BARRIER)]
5383 ""
5384 "pseudo"
5385 [(set_attr "type" "nothing")
5386 (set_attr "length" "0")])
5387
5388 (define_insn "*netreg_receive"
5389 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,U,m")
5390 (unspec_volatile:DI [(match_operand:DI 1 "netreg_operand" "i,i,i")
5391 (reg:DI TILEGX_NETORDER_REG)]
5392 UNSPEC_NETWORK_RECEIVE))
5393 (clobber (reg:DI TILEGX_NETORDER_REG))]
5394
5395 ""
5396 "@
5397 move\t%0, %N1
5398 st\t%0, %N1
5399 st_add\t%I0, %N1, %i0"
5400 [(set_attr "type" "*,Y2,X1")])
5401
5402 (define_insn "*netreg_send"
5403 [(unspec_volatile:DI
5404 [(match_operand:DI 0 "netreg_operand" "i,i,i,i,i,i")
5405 (match_operand:DI 1 "reg_or_cint_operand" "r,I,J,K,N,P")
5406 (reg:DI TILEGX_NETORDER_REG)]
5407 UNSPEC_NETWORK_SEND)
5408 (clobber (reg:DI TILEGX_NETORDER_REG))]
5409 ""
5410 "@
5411 move\t%N0, %r1
5412 movei\t%N0, %1
5413 moveli\t%N0, %1
5414 shl16insli\t%N0, zero, %h1
5415 v1addi\t%N0, zero, %j1
5416 v2addi\t%N0, zero, %h1"
5417 [(set_attr "type" "*,*,X01,X01,X01,X01")])
5418
5419 (define_expand "tilegx_idn0_receive"
5420 [(parallel
5421 [(set (match_operand:DI 0 "register_operand" "")
5422 (unspec_volatile:DI [(const_int TILEGX_NETREG_IDN0)
5423 (reg:DI TILEGX_NETORDER_REG)]
5424 UNSPEC_NETWORK_RECEIVE))
5425 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5426 "")
5427
5428 (define_expand "tilegx_idn1_receive"
5429 [(parallel
5430 [(set (match_operand:DI 0 "register_operand" "")
5431 (unspec_volatile:DI [(const_int TILEGX_NETREG_IDN1)
5432 (reg:DI TILEGX_NETORDER_REG)]
5433 UNSPEC_NETWORK_RECEIVE))
5434 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5435 "")
5436
5437 (define_expand "tilegx_idn_send"
5438 [(parallel
5439 [(unspec_volatile:DI [(const_int TILEGX_NETREG_IDN0)
5440 (match_operand:DI 0 "reg_or_cint_operand" "")
5441 (reg:DI TILEGX_NETORDER_REG)]
5442 UNSPEC_NETWORK_SEND)
5443 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5444 "")
5445
5446 (define_expand "tilegx_udn0_receive"
5447 [(parallel
5448 [(set (match_operand:DI 0 "register_operand" "")
5449 (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN0)
5450 (reg:DI TILEGX_NETORDER_REG)]
5451 UNSPEC_NETWORK_RECEIVE))
5452 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5453 "")
5454
5455 (define_expand "tilegx_udn1_receive"
5456 [(parallel
5457 [(set (match_operand:DI 0 "register_operand" "")
5458 (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN1)
5459 (reg:DI TILEGX_NETORDER_REG)]
5460 UNSPEC_NETWORK_RECEIVE))
5461 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5462 "")
5463
5464 (define_expand "tilegx_udn2_receive"
5465 [(parallel
5466 [(set (match_operand:DI 0 "register_operand" "")
5467 (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN2)
5468 (reg:DI TILEGX_NETORDER_REG)]
5469 UNSPEC_NETWORK_RECEIVE))
5470 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5471 "")
5472
5473 (define_expand "tilegx_udn3_receive"
5474 [(parallel
5475 [(set (match_operand:DI 0 "register_operand" "")
5476 (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN3)
5477 (reg:DI TILEGX_NETORDER_REG)]
5478 UNSPEC_NETWORK_RECEIVE))
5479 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5480 "")
5481
5482 (define_expand "tilegx_udn_send"
5483 [(parallel
5484 [(unspec_volatile:DI [(const_int TILEGX_NETREG_UDN0)
5485 (match_operand:DI 0 "reg_or_cint_operand" "")
5486 (reg:DI TILEGX_NETORDER_REG)]
5487 UNSPEC_NETWORK_SEND)
5488 (clobber (reg:DI TILEGX_NETORDER_REG))])]
5489 "")
5490
5491 (define_insn "*netreg_adddi_to_network"
5492 [(unspec_volatile:DI
5493 [(match_operand:DI 0 "netreg_operand" "i,i,i")
5494 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO")
5495 (match_operand:DI 2 "add_operand" "r,I,JT"))
5496 (reg:DI TILEGX_NETORDER_REG)]
5497 UNSPEC_NETWORK_SEND)
5498 (clobber (reg:DI TILEGX_NETORDER_REG))]
5499 ""
5500 "@
5501 add\t%N0, %r1, %2
5502 addi\t%N0, %r1, %2
5503 addli\t%N0, %r1, %H2"
5504 [(set_attr "type" "*,*,X01")])
5505
5506 (define_insn "*netreg_adddi_from_network"
5507 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5508 (plus:DI (unspec_volatile:DI
5509 [(match_operand:DI 1 "netreg_operand" "%i,i,i")
5510 (reg:DI TILEGX_NETORDER_REG)]
5511 UNSPEC_NETWORK_RECEIVE)
5512 (match_operand:DI 2 "add_operand" "rO,I,JT")))
5513 (clobber (reg:DI TILEGX_NETORDER_REG))]
5514 ""
5515 "@
5516 add\t%0, %N1, %r2
5517 addi\t%0, %N1, %2
5518 addli\t%0, %N1, %H2"
5519 [(set_attr "type" "*,*,X01")])
5520
5521 \f
5522 ;;
5523 ;; Stack protector instructions.
5524 ;;
5525
5526 (define_expand "stack_protect_set"
5527 [(set (match_operand 0 "nonautoincmem_operand" "")
5528 (match_operand 1 "nonautoincmem_operand" ""))]
5529 ""
5530 {
5531 #ifdef TARGET_THREAD_SSP_OFFSET
5532 rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
5533 rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
5534 rtx ssp = gen_reg_rtx (Pmode);
5535
5536 emit_insn (gen_rtx_SET (VOIDmode, ssp, ssp_addr));
5537
5538 operands[1] = gen_rtx_MEM (Pmode, ssp);
5539 #endif
5540
5541 if (TARGET_32BIT)
5542 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
5543 else
5544 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
5545
5546 DONE;
5547 })
5548
5549 (define_insn "stack_protect_setsi"
5550 [(set (match_operand:SI 0 "nonautoincmem_operand" "=U")
5551 (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")]
5552 UNSPEC_SP_SET))
5553 (set (match_scratch:SI 2 "=&r") (const_int 0))]
5554 ""
5555 "ld4s\t%2, %1; { st4\t%0, %2; move\t%2, zero }"
5556 [(set_attr "length" "16")
5557 (set_attr "type" "cannot_bundle_3cycle")])
5558
5559 (define_insn "stack_protect_setdi"
5560 [(set (match_operand:DI 0 "nonautoincmem_operand" "=U")
5561 (unspec:DI [(match_operand:DI 1 "nonautoincmem_operand" "U")]
5562 UNSPEC_SP_SET))
5563 (set (match_scratch:DI 2 "=&r") (const_int 0))]
5564 ""
5565 "ld\t%2, %1; { st\t%0, %2; move\t%2, zero }"
5566 [(set_attr "length" "16")
5567 (set_attr "type" "cannot_bundle_3cycle")])
5568
5569 (define_expand "stack_protect_test"
5570 [(match_operand 0 "nonautoincmem_operand" "")
5571 (match_operand 1 "nonautoincmem_operand" "")
5572 (match_operand 2 "" "")]
5573 ""
5574 {
5575 rtx compare_result;
5576 rtx bcomp, loc_ref;
5577
5578 #ifdef TARGET_THREAD_SSP_OFFSET
5579 rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
5580 rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
5581 rtx ssp = gen_reg_rtx (Pmode);
5582
5583 emit_insn (gen_rtx_SET (VOIDmode, ssp, ssp_addr));
5584
5585 operands[1] = gen_rtx_MEM (Pmode, ssp);
5586 #endif
5587
5588 compare_result = gen_reg_rtx (Pmode);
5589
5590 if (TARGET_32BIT)
5591 emit_insn (gen_stack_protect_testsi (compare_result, operands[0],
5592 operands[1]));
5593 else
5594 emit_insn (gen_stack_protect_testdi (compare_result, operands[0],
5595 operands[1]));
5596
5597 bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
5598
5599 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
5600
5601 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
5602 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
5603 loc_ref, pc_rtx)));
5604
5605 DONE;
5606 })
5607
5608 (define_insn "stack_protect_testsi"
5609 [(set (match_operand:SI 0 "register_operand" "=&r")
5610 (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")
5611 (match_operand:SI 2 "nonautoincmem_operand" "U")]
5612 UNSPEC_SP_TEST))
5613 (set (match_scratch:SI 3 "=&r") (const_int 0))]
5614 ""
5615 "ld4s\t%0, %1; ld4s\t%3, %2; { cmpeq\t%0, %0, %3; move\t%3, zero }"
5616 [(set_attr "length" "24")
5617 (set_attr "type" "cannot_bundle_4cycle")])
5618
5619 (define_insn "stack_protect_testdi"
5620 [(set (match_operand:DI 0 "register_operand" "=&r")
5621 (unspec:DI [(match_operand:DI 1 "nonautoincmem_operand" "U")
5622 (match_operand:DI 2 "nonautoincmem_operand" "U")]
5623 UNSPEC_SP_TEST))
5624 (set (match_scratch:DI 3 "=&r") (const_int 0))]
5625 ""
5626 "ld\t%0, %1; ld\t%3, %2; { cmpeq\t%0, %0, %3; move\t%3, zero }"
5627 [(set_attr "length" "24")
5628 (set_attr "type" "cannot_bundle_4cycle")])
5629
5630 (include "sync.md")
This page took 0.289236 seconds and 5 git commands to generate.