]>
Commit | Line | Data |
---|---|---|
dd552284 | 1 | ;; Machine description for Tilera TILEPro chip for GCC. |
7adcbafe | 2 | ;; Copyright (C) 2011-2022 Free Software Foundation, Inc. |
dd552284 WL |
3 | ;; Contributed by Walter Lee (walt@tilera.com) |
4 | ;; | |
5 | ;; This file is part of GCC. | |
6 | ;; | |
7 | ;; GCC is free software; you can redistribute it and/or modify it | |
8 | ;; under the terms of the GNU General Public License as published | |
9 | ;; by the Free Software Foundation; either version 3, or (at your | |
10 | ;; option) any later version. | |
11 | ;; | |
12 | ;; GCC is distributed in the hope that it will be useful, but WITHOUT | |
13 | ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
14 | ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
15 | ;; License for more details. | |
16 | ;; | |
17 | ;; You should have received a copy of the GNU General Public License | |
18 | ;; along with GCC; see the file COPYING3. If not see | |
19 | ;; <http://www.gnu.org/licenses/>. | |
20 | ||
21 | (define_constants [ | |
22 | ;; | |
23 | ;; The following represent intrinsic insns, organized by latency. | |
24 | ;; | |
25 | ||
26 | ;; single cycle | |
27 | (UNSPEC_INSN_ADDLIS 1) | |
28 | (UNSPEC_INSN_AULI 2) | |
29 | (UNSPEC_INSN_AVGB_U 3) | |
30 | (UNSPEC_INSN_AVGH 4) | |
31 | (UNSPEC_INSN_BITX 5) | |
32 | (UNSPEC_INSN_CRC32_32 6) | |
33 | (UNSPEC_INSN_CRC32_8 7) | |
34 | (UNSPEC_INSN_DRAIN 8) | |
35 | (UNSPEC_INSN_DTLBPR 9) | |
36 | (UNSPEC_INSN_DWORD_ALIGN 10) | |
37 | (UNSPEC_INSN_FINV 11) | |
38 | (UNSPEC_INSN_FLUSH 12) | |
39 | (UNSPEC_INSN_FNOP 13) | |
40 | (UNSPEC_INSN_ICOH 14) | |
41 | (UNSPEC_INSN_ILL 15) | |
42 | (UNSPEC_INSN_INFO 16) | |
43 | (UNSPEC_INSN_INFOL 17) | |
44 | (UNSPEC_INSN_INV 18) | |
45 | (UNSPEC_INSN_LNK 19) | |
46 | (UNSPEC_INSN_MFSPR 20) | |
47 | (UNSPEC_INSN_MNZB 21) | |
48 | (UNSPEC_INSN_MNZH 22) | |
49 | (UNSPEC_INSN_MOVELIS 23) | |
50 | (UNSPEC_INSN_MTSPR 24) | |
51 | (UNSPEC_INSN_MZB 25) | |
52 | (UNSPEC_INSN_MZH 26) | |
53 | (UNSPEC_INSN_NAP 27) | |
54 | (UNSPEC_INSN_PACKBS_U 28) | |
55 | (UNSPEC_INSN_PACKHB 29) | |
56 | (UNSPEC_INSN_PACKHS 30) | |
57 | (UNSPEC_INSN_PACKLB 31) | |
58 | (UNSPEC_INSN_PREFETCH_L1 32) | |
59 | (UNSPEC_INSN_TBLIDXB0 33) | |
60 | (UNSPEC_INSN_TBLIDXB1 34) | |
61 | (UNSPEC_INSN_TBLIDXB2 35) | |
62 | (UNSPEC_INSN_TBLIDXB3 36) | |
63 | (UNSPEC_INSN_WH64 37) | |
64 | ||
65 | ;; 2 cycles | |
66 | (UNSPEC_INSN_ADIFFB_U 100) | |
67 | (UNSPEC_INSN_ADIFFH 101) | |
68 | (UNSPEC_INSN_MULHHA_SS 102) | |
69 | (UNSPEC_INSN_MULHHA_SU 103) | |
70 | (UNSPEC_INSN_MULHHA_UU 104) | |
71 | (UNSPEC_INSN_MULHHSA_UU 105) | |
72 | (UNSPEC_INSN_MULHH_SS 106) | |
73 | (UNSPEC_INSN_MULHH_SU 107) | |
74 | (UNSPEC_INSN_MULHH_UU 108) | |
75 | (UNSPEC_INSN_MULHLA_SS 109) | |
76 | (UNSPEC_INSN_MULHLA_SU 110) | |
77 | (UNSPEC_INSN_MULHLA_US 111) | |
78 | (UNSPEC_INSN_MULHLA_UU 112) | |
79 | (UNSPEC_INSN_MULHLSA_UU 113) | |
80 | (UNSPEC_INSN_MULHL_SS 114) | |
81 | (UNSPEC_INSN_MULHL_SU 115) | |
82 | (UNSPEC_INSN_MULHL_US 116) | |
83 | (UNSPEC_INSN_MULHL_UU 117) | |
84 | (UNSPEC_INSN_MULLLA_SS 118) | |
85 | (UNSPEC_INSN_MULLLA_SU 119) | |
86 | (UNSPEC_INSN_MULLLA_UU 120) | |
87 | (UNSPEC_INSN_MULLLSA_UU 121) | |
88 | (UNSPEC_INSN_MULLL_SU 122) | |
89 | (UNSPEC_INSN_MULLL_SS 123) | |
90 | (UNSPEC_INSN_MULLL_UU 124) | |
91 | (UNSPEC_INSN_SADAB_U 125) | |
92 | (UNSPEC_INSN_SADAH 126) | |
93 | (UNSPEC_INSN_SADAH_U 127) | |
94 | (UNSPEC_INSN_SADB_U 128) | |
95 | (UNSPEC_INSN_SADH 129) | |
96 | (UNSPEC_INSN_SADH_U 130) | |
97 | ||
98 | ;; | |
99 | ;; The following are special insns. | |
100 | ;; | |
101 | ||
102 | ;; Blockage | |
103 | (UNSPEC_BLOCKAGE 200) | |
104 | ||
105 | ;; Latency specifying loads. | |
106 | (UNSPEC_LATENCY_L2 201) | |
107 | (UNSPEC_LATENCY_MISS 202) | |
108 | ||
109 | ;; Lnk and its label | |
110 | (UNSPEC_LNK_AND_LABEL 203) | |
111 | ||
112 | ;; Memory fence | |
113 | (UNSPEC_MF 204) | |
114 | ||
115 | ;; A pseudo-op that prevents network operations from being ordered. | |
116 | (UNSPEC_NETWORK_BARRIER 205) | |
117 | ||
118 | ;; Operations that access network registers. | |
119 | (UNSPEC_NETWORK_RECEIVE 206) | |
120 | (UNSPEC_NETWORK_SEND 207) | |
121 | ||
122 | ;; Stack protector operations | |
123 | (UNSPEC_SP_SET 208) | |
124 | (UNSPEC_SP_TEST 209) | |
125 | ||
126 | ;; A call to __tls_get_addr | |
127 | (UNSPEC_TLS_GD_CALL 210) | |
128 | ||
129 | ;; An opaque TLS "add" operation for TLS general dynamic model | |
130 | ;; access. | |
131 | (UNSPEC_TLS_GD_ADD 211) | |
132 | ||
133 | ;; An opaque TLS "load" operation for TLS initial exec model access. | |
134 | (UNSPEC_TLS_IE_LOAD 212) | |
135 | ||
136 | ;; | |
137 | ;; The following are operands. | |
138 | ;; | |
139 | (UNSPEC_PCREL_SYM 300) | |
140 | (UNSPEC_GOT16_SYM 301) | |
141 | (UNSPEC_GOT32_SYM 302) | |
142 | (UNSPEC_TLS_GD 303) | |
143 | (UNSPEC_TLS_IE 304) | |
144 | (UNSPEC_TLS_LE 305) | |
145 | ]) | |
146 | ||
147 | ;; Mark the last instruction of various latencies, used to | |
148 | ;; determine the rtx costs of unspec insns. | |
149 | (define_constants [ | |
150 | (TILEPRO_LAST_LATENCY_1_INSN 99) | |
151 | (TILEPRO_LAST_LATENCY_2_INSN 199) | |
152 | (TILEPRO_LAST_LATENCY_INSN 299) | |
153 | ]) | |
154 | ||
155 | ;; Constants for network registers. | |
156 | (define_constants [ | |
157 | (TILEPRO_NETREG_IDN0 0) | |
158 | (TILEPRO_NETREG_IDN1 1) | |
159 | (TILEPRO_NETREG_SN 2) | |
160 | (TILEPRO_NETREG_UDN0 3) | |
161 | (TILEPRO_NETREG_UDN1 4) | |
162 | (TILEPRO_NETREG_UDN2 5) | |
163 | (TILEPRO_NETREG_UDN3 6) | |
164 | ]) | |
165 | ||
166 | ;; Constants for special purpose registers. | |
167 | (define_constants [ | |
168 | (TILEPRO_NETORDER_REG 66)]) | |
169 | ||
170 | ||
171 | ;; Operand and operator predicates and constraints | |
172 | ||
173 | (include "predicates.md") | |
174 | (include "constraints.md") | |
175 | (include "tilepro-generic.md") | |
176 | ||
177 | ;; Define an insn type attribute. This defines what pipes things can | |
178 | ;; go in. | |
179 | (define_attr "type" | |
180 | "X0,X0_2cycle,X1,X1_branch,X1_2cycle,X1_L2,X1_miss,X01,Y0,Y0_2cycle,Y2,Y2_2cycle,Y2_L2,Y2_miss,Y01,cannot_bundle,cannot_bundle_3cycle,cannot_bundle_4cycle,nothing" | |
181 | (const_string "Y01")) | |
182 | ||
183 | (define_attr "length" "" | |
184 | (cond [(eq_attr "type" "X1_branch") | |
185 | (if_then_else | |
186 | (and (le (minus (match_dup 0) (pc)) (const_int 524280)) | |
187 | (le (minus (pc) (match_dup 0)) (const_int 524288))) | |
188 | (const_int 8) | |
189 | (const_int 16)) | |
190 | ] | |
191 | (const_int 8))) | |
192 | ||
193 | \f | |
194 | ;; Define iterators. | |
195 | (define_mode_iterator I48MODE [SI DI]) | |
196 | (define_mode_iterator I12MODE [QI HI]) | |
197 | ||
198 | (define_code_iterator binop_u5bit [ashift ashiftrt lshiftrt rotate]) | |
199 | (define_code_iterator binop_with_imm | |
200 | [ashift lshiftrt ashiftrt rotate eq lt and ior xor]) | |
201 | (define_code_iterator unop [bswap clz ctz popcount]) | |
202 | ||
203 | (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw")]) | |
204 | (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw")]) | |
205 | ||
206 | ;; <optab> expands to the name of the optab for a particular code. | |
207 | (define_code_attr optab [(ashift "ashl") | |
208 | (ashiftrt "ashr") | |
209 | (lshiftrt "lshr") | |
210 | (eq "seq") | |
211 | (ne "sne") | |
212 | (lt "slt") | |
213 | (ltu "sltu") | |
214 | (le "sle") | |
215 | (leu "sleu") | |
216 | (minus "sub") | |
217 | (plus "add") | |
218 | (rotate "rotl") | |
219 | (smax "smax") | |
220 | (smin "smin") | |
221 | (umax "umax") | |
222 | (umin "umin") | |
223 | (ss_minus "sssub") | |
224 | (ss_plus "ssadd") | |
225 | (us_minus "ussub") | |
226 | (us_plus "usadd") | |
227 | (and "and") | |
228 | (ior "ior") | |
229 | (xor "xor") | |
230 | (bswap "bswap") | |
231 | (clz "clz") | |
232 | (ctz "ctz") | |
233 | (popcount "popcount")]) | |
234 | ||
235 | ;; <insn> expands to the name of the insn that implements a particular | |
236 | ;; code. | |
237 | (define_code_attr insn [(ashift "shl") | |
238 | (ashiftrt "sra") | |
239 | (lshiftrt "shr") | |
240 | (eq "seq") | |
241 | (ne "sne") | |
242 | (lt "slt") | |
243 | (ltu "slt") | |
244 | (le "slte") | |
245 | (leu "slte") | |
246 | (minus "sub") | |
247 | (plus "add") | |
248 | (rotate "rl") | |
249 | (smax "max") | |
250 | (smin "min") | |
251 | (umax "max") | |
252 | (umin "min") | |
253 | (ss_minus "sub") | |
254 | (ss_plus "add") | |
255 | (us_minus "sub") | |
256 | (us_plus "add") | |
257 | (and "and") | |
258 | (ior "or") | |
259 | (xor "xor") | |
260 | (bswap "bytex") | |
261 | (clz "clz") | |
262 | (ctz "ctz") | |
263 | (popcount "pcnt")]) | |
264 | ||
265 | ;; <u> expands to the suffix of the insn that implements a particular | |
266 | ;; code. | |
267 | (define_code_attr u [(ashift "") | |
268 | (ashiftrt "") | |
269 | (lshiftrt "") | |
270 | (eq "") | |
271 | (ne "") | |
272 | (lt "") | |
273 | (ltu "_u") | |
274 | (le "") | |
275 | (leu "_u") | |
276 | (minus "") | |
277 | (plus "") | |
278 | (rotate "") | |
279 | (smax "") | |
280 | (smin "") | |
281 | (umax "_u") | |
282 | (umin "_u") | |
283 | (ss_minus "s") | |
284 | (ss_plus "s") | |
285 | (us_minus "s_u") | |
286 | (us_plus "s_u") | |
287 | (and "") | |
288 | (ior "") | |
289 | (xor "")]) | |
290 | ||
291 | ;; <comm> indicates whether a particular code is commutative, using | |
292 | ;; the "%" commutative opterator constraint. | |
293 | (define_code_attr comm [(ashift "") | |
294 | (ashiftrt "") | |
295 | (lshiftrt "") | |
296 | (eq "%") | |
297 | (ne "%") | |
298 | (lt "") | |
299 | (ltu "") | |
300 | (le "") | |
301 | (leu "") | |
302 | (minus "") | |
303 | (plus "%") | |
304 | (rotate "") | |
305 | (smax "%") | |
306 | (umax "%") | |
307 | (smin "%") | |
308 | (umin "%") | |
309 | (ss_plus "%") | |
310 | (us_plus "%") | |
311 | (ss_minus "") | |
312 | (us_minus "") | |
313 | (and "%") | |
314 | (ior "%") | |
315 | (xor "%")]) | |
316 | ||
317 | (define_mode_iterator VEC [V4QI V2HI]) | |
318 | ||
319 | ;; Code iterator for all three shifts. | |
320 | (define_code_iterator any_shift [ashift ashiftrt lshiftrt]) | |
321 | ||
322 | ;; Code iterator for all byte ops without immediate variants. | |
323 | (define_code_iterator v1op [us_plus ne le leu minus us_minus]) | |
324 | ||
325 | ;; Code iterator for all 2-byte vector ops without immediate variants. | |
326 | (define_code_iterator v2op [ss_plus ne le leu minus ss_minus]) | |
327 | ||
328 | ;; Code iterator for all byte vector ops with immediate variants. | |
329 | (define_code_iterator v1op_immed [plus umax umin eq lt ltu]) | |
330 | ||
331 | ;; Code iterator for all 2-byte vector ops with immediate variants. | |
332 | (define_code_iterator v2op_immed [plus smax smin eq lt ltu]) | |
333 | ||
334 | ;; Code for packing two 2-byte vectors. | |
335 | (define_code_iterator v2pack [truncate us_truncate]) | |
336 | ||
337 | ;; <pack_optab> expands to the part of the optab name describing how | |
338 | ;; two vectors are packed. | |
339 | (define_code_attr pack_optab [(truncate "trunc") | |
340 | (us_truncate "usat") | |
341 | (ss_truncate "ssat")]) | |
342 | ||
343 | ;; <pack_insn> expands to the insn that implements a particular vector | |
344 | ;; packing code. | |
345 | (define_code_attr pack_insn [(truncate "packl") | |
346 | (us_truncate "pack") | |
347 | (ss_truncate "pack")]) | |
348 | ||
349 | ;; <pack_u> expands to the suffix of the insn that implements a | |
350 | ;; particular vector packing code. | |
351 | (define_code_attr pack_u [(truncate "") | |
352 | (us_truncate "s_u") | |
353 | (ss_truncate "s")]) | |
354 | ||
355 | \f | |
356 | ;; | |
357 | ;; The basic data move insns. | |
358 | ;; | |
359 | ||
360 | (define_expand "movqi" | |
361 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
362 | (match_operand:QI 1 "nonautoinc_operand" ""))] | |
363 | "" | |
364 | { | |
365 | if (tilepro_expand_mov (QImode, operands)) | |
366 | DONE; | |
367 | }) | |
368 | ||
369 | (define_insn "*movqi_insn" | |
370 | [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,U,m") | |
371 | (match_operand:QI 1 "move_operand" "r,I,U,m,rO,rO"))] | |
372 | "(register_operand (operands[0], QImode) | |
373 | || reg_or_0_operand (operands[1], QImode))" | |
374 | "@ | |
375 | move\t%0, %r1 | |
376 | movei\t%0, %1 | |
377 | lb_u\t%0, %1 | |
378 | lbadd_u\t%0, %I1, %i1 | |
379 | sb\t%0, %r1 | |
380 | sbadd\t%I0, %r1, %i0" | |
381 | [(set_attr "type" "*,*,Y2_2cycle,X1_2cycle,Y2,X1")]) | |
382 | ||
383 | (define_expand "movhi" | |
384 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
385 | (match_operand:HI 1 "nonautoinc_operand" ""))] | |
386 | "" | |
387 | { | |
388 | if (tilepro_expand_mov (HImode, operands)) | |
389 | DONE; | |
390 | }) | |
391 | ||
392 | (define_insn "*movhi_insn" | |
393 | [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,r,U,m") | |
394 | (match_operand:HI 1 "move_operand" "r,I,J,U,m,rO,rO"))] | |
395 | "(register_operand (operands[0], HImode) | |
396 | || reg_or_0_operand (operands[1], HImode))" | |
397 | "@ | |
398 | move\t%0, %r1 | |
399 | movei\t%0, %1 | |
400 | moveli\t%0, %1 | |
401 | lh_u\t%0, %1 | |
402 | lhadd_u\t%0, %I1, %i1 | |
403 | sh\t%0, %r1 | |
404 | shadd\t%I0, %r1, %i0" | |
405 | [(set_attr "type" "*,*,X01,Y2_2cycle,X1_2cycle,Y2,X1")]) | |
406 | ||
407 | ||
408 | (define_expand "movsi" | |
409 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
410 | (match_operand:SI 1 "nonautoinc_operand" ""))] | |
411 | "" | |
412 | { | |
413 | if (tilepro_expand_mov (SImode, operands)) | |
414 | DONE; | |
415 | }) | |
416 | ||
417 | (define_insn "*movsi_high_insn" | |
418 | [(set (match_operand:SI 0 "register_operand" "=r") | |
419 | (high:SI (match_operand:SI 1 "symbolic_operand" "in")))] | |
420 | "" | |
421 | "auli\t%0, zero, ha16(%1)" | |
422 | [(set_attr "type" "X01")]) | |
423 | ||
424 | (define_insn "*movsi_insn" | |
425 | [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,r,U,m") | |
426 | (match_operand:SI 1 "move_operand" "r,I,J,K,N,P,U,m,rO,rO"))] | |
427 | "(register_operand (operands[0], SImode) | |
428 | || reg_or_0_operand (operands[1], SImode))" | |
429 | "@ | |
430 | move\t%0, %r1 | |
431 | movei\t%0, %1 | |
432 | moveli\t%0, %1 | |
433 | auli\t%0, zero, %h1 | |
434 | addib\t%0, zero, %j1 | |
435 | addih\t%0, zero, %h1 | |
436 | lw\t%0, %1 | |
437 | lwadd\t%0, %I1, %i1 | |
438 | sw\t%0, %r1 | |
439 | swadd\t%I0, %r1, %i0" | |
440 | [(set_attr "type" "*,*,X01,X01,X01,X01,Y2_2cycle,X1_2cycle,Y2,X1")]) | |
441 | ||
442 | (define_insn "movstrictqi" | |
443 | [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r")) | |
444 | (match_operand:QI 1 "reg_or_0_operand" "rO"))] | |
445 | "" | |
446 | "mm\t%r0, %r1, %r0, 0, 7" | |
447 | [(set_attr "type" "X01")]) | |
448 | ||
449 | (define_insn "movstricthi" | |
450 | [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) | |
451 | (match_operand:HI 1 "reg_or_0_operand" "rO"))] | |
452 | "" | |
453 | "mm\t%r0, %r1, %r0, 0, 15" | |
454 | [(set_attr "type" "X01")]) | |
455 | ||
456 | (define_expand "movmisalign<mode>" | |
457 | [(set (match_operand:VEC 0 "nonautoincmem_nonimmediate_operand" "") | |
458 | (match_operand:VEC 1 "nonautoincmem_general_operand" ""))] | |
459 | "" | |
460 | { | |
461 | tilepro_expand_movmisalign (<MODE>mode, operands); | |
462 | DONE; | |
463 | }) | |
464 | ||
465 | (define_expand "movsf" | |
466 | [(set (match_operand:SF 0 "nonimmediate_operand" "") | |
467 | (match_operand:SF 1 "general_operand" ""))] | |
468 | "" | |
469 | { | |
470 | /* Materialize immediates using clever SImode code, but don't | |
471 | do this after reload starts, since gen_lowpart will choke | |
472 | during reload if given an illegitimate address. */ | |
473 | if (immediate_operand (operands[1], SFmode) | |
474 | && operands[1] != const0_rtx | |
475 | && (register_operand (operands[0], SFmode) | |
476 | || (!reload_in_progress && !reload_completed))) | |
477 | { | |
478 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), | |
479 | gen_lowpart (SImode, operands[1]))); | |
480 | DONE; | |
481 | } | |
482 | }) | |
483 | ||
484 | (define_insn "*movsf" | |
485 | [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,U,m") | |
486 | (match_operand:SF 1 "general_operand" "rO,U,m,rO,rO"))] | |
487 | "" | |
488 | "@ | |
489 | move\t%0, %r1 | |
490 | lw\t%0, %1 | |
491 | lwadd\t%0, %I1, %i1 | |
492 | sw\t%0, %r1 | |
493 | swadd\t%I0, %r1, %i0" | |
494 | [(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")]) | |
495 | ||
496 | (define_expand "mov<mode>" | |
497 | [(set (match_operand:VEC 0 "nonimmediate_operand" "") | |
498 | (match_operand:VEC 1 "general_operand" ""))] | |
499 | "" | |
500 | { | |
501 | /* Materialize immediates using clever SImode code, but don't | |
502 | do this after reload starts, since gen_lowpart will choke | |
503 | during reload if given an illegitimate address. */ | |
504 | if (immediate_operand (operands[1], <MODE>mode) | |
505 | && operands[1] != const0_rtx | |
506 | && (register_operand (operands[0], <MODE>mode) | |
507 | || (!reload_in_progress && !reload_completed))) | |
508 | { | |
509 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), | |
510 | gen_lowpart (SImode, operands[1]))); | |
511 | DONE; | |
512 | } | |
513 | }) | |
514 | ||
515 | (define_insn "*mov<mode>" | |
516 | [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,U,m") | |
517 | (match_operand:VEC 1 "general_operand" "rO,U,m,rO,rO"))] | |
518 | "" | |
519 | "@ | |
520 | move\t%0, %r1 | |
521 | lw\t%0, %1 | |
522 | lwadd\t%0, %I1, %i1 | |
523 | sw\t%0, %r1 | |
524 | swadd\t%I0, %r1, %i0" | |
525 | [(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")]) | |
526 | ||
527 | \f | |
528 | ;; | |
529 | ;; Bit-field extracts | |
530 | ;; | |
531 | ||
532 | (define_expand "extv" | |
533 | [(set (match_operand:SI 0 "register_operand" "") | |
534 | (sign_extract:SI | |
535 | (match_operand:QI 1 "nonautoincmem_operand" "") | |
536 | (match_operand:SI 2 "immediate_operand" "") | |
537 | (match_operand:SI 3 "immediate_operand" "")))] | |
538 | "" | |
539 | { | |
540 | HOST_WIDE_INT bit_offset, bit_width; | |
541 | HOST_WIDE_INT first_byte_offset, last_byte_offset; | |
542 | ||
543 | bit_width = INTVAL (operands[2]); | |
544 | bit_offset = INTVAL (operands[3]); | |
545 | ||
546 | /* Reject bitfields that can be done with a normal load */ | |
547 | if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width) | |
548 | FAIL; | |
549 | ||
550 | /* The value in memory cannot span more than 4 bytes. */ | |
551 | first_byte_offset = bit_offset / BITS_PER_UNIT; | |
552 | last_byte_offset = (bit_offset + bit_width - 1) / BITS_PER_UNIT; | |
553 | if (last_byte_offset - first_byte_offset > 3) | |
554 | FAIL; | |
555 | ||
556 | tilepro_expand_unaligned_load (operands[0], operands[1], | |
557 | bit_width, bit_offset, 1); | |
558 | ||
559 | DONE; | |
560 | }) | |
561 | ||
562 | (define_expand "extzv" | |
563 | [(set (match_operand:SI 0 "register_operand" "") | |
564 | (zero_extract:SI | |
565 | (match_operand:QI 1 "nonautoincmem_operand" "") | |
566 | (match_operand:SI 2 "immediate_operand" "") | |
567 | (match_operand:SI 3 "immediate_operand" "")))] | |
568 | "" | |
569 | { | |
570 | HOST_WIDE_INT bit_offset, bit_width; | |
571 | HOST_WIDE_INT first_byte_offset, last_byte_offset; | |
572 | ||
573 | bit_width = INTVAL (operands[2]); | |
574 | bit_offset = INTVAL (operands[3]); | |
575 | ||
576 | /* Reject bitfields that can be done with a normal load */ | |
577 | if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width) | |
578 | FAIL; | |
579 | ||
580 | /* The value in memory cannot span more than 4 bytes. */ | |
581 | first_byte_offset = bit_offset / BITS_PER_UNIT; | |
582 | last_byte_offset = (bit_offset + bit_width - 1) / BITS_PER_UNIT; | |
583 | if (last_byte_offset - first_byte_offset > 3) | |
584 | FAIL; | |
585 | ||
586 | tilepro_expand_unaligned_load (operands[0], operands[1], | |
587 | bit_width, bit_offset, 0); | |
588 | ||
589 | DONE; | |
590 | }) | |
591 | ||
592 | \f | |
593 | ;; | |
594 | ;; Arithmetic ops | |
595 | ;; | |
596 | ||
597 | (define_insn "*s123a_insn" | |
598 | [(set (match_operand:SI 0 "register_operand" "=r") | |
599 | (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO") | |
600 | (match_operand:SI 2 "cint_248_operand" "I")) | |
601 | (match_operand:SI 3 "reg_or_0_operand" "rO")))] | |
602 | "" | |
603 | "s%t2a\t%0, %r1, %r3") | |
604 | ||
605 | (define_expand "addsi3" | |
606 | [(set (match_operand:SI 0 "register_operand" "") | |
607 | (plus:SI (match_operand:SI 1 "register_operand" "") | |
608 | (match_operand:SI 2 "reg_or_cint_operand" "")))] | |
609 | "" | |
610 | " | |
611 | if (tilepro_expand_addsi (operands[0], operands[1], operands[2])) | |
612 | DONE; | |
613 | ") | |
614 | ||
615 | (define_insn "*addsi_high_insn" | |
616 | [(set (match_operand:SI 0 "register_operand" "=r") | |
617 | (plus:SI | |
618 | (match_operand:SI 1 "reg_or_0_operand" "%rO") | |
619 | (high:SI (match_operand:SI 2 "const_symbolic_operand" "T"))))] | |
620 | "" | |
621 | "auli\t%0, %r1, %H2" | |
622 | [(set_attr "type" "X01")]) | |
623 | ||
624 | (define_insn "*addsi_lo_sum_insn" | |
625 | [(set (match_operand:SI 0 "register_operand" "=r") | |
626 | (lo_sum:SI | |
627 | (match_operand:SI 1 "reg_or_0_operand" "%rO") | |
628 | (match_operand:SI 2 "const_symbolic_operand" "T")))] | |
629 | "" | |
630 | "addli\t%0, %r1, %L2" | |
631 | [(set_attr "type" "X01")]) | |
632 | ||
633 | (define_insn "*addsi3_insn" | |
634 | [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") | |
635 | (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO,rO") | |
636 | (match_operand:SI 2 "add_operand" "r,I,J,K")))] | |
637 | "" | |
638 | "@ | |
639 | add\t%0, %r1, %r2 | |
640 | addi\t%0, %r1, %2 | |
641 | addli\t%0, %r1, %2 | |
642 | auli\t%0, %r1, %h2" | |
643 | [(set_attr "type" "*,*,X01,X01")]) | |
644 | ||
645 | (define_insn "subsi3" | |
646 | [(set (match_operand:SI 0 "register_operand" "=r") | |
647 | (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") | |
648 | (match_operand:SI 2 "reg_or_0_operand" "rO")))] | |
649 | "" | |
650 | "sub\t%0, %r1, %r2") | |
651 | ||
652 | (define_insn "negsi2" | |
653 | [(set (match_operand:SI 0 "register_operand" "=r") | |
654 | (neg:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))] | |
655 | "" | |
656 | "sub\t%0, zero, %r1") | |
657 | ||
658 | (define_insn "ssaddsi3" | |
659 | [(set (match_operand:SI 0 "register_operand" "=r") | |
660 | (ss_plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") | |
661 | (match_operand:SI 2 "reg_or_0_operand" "rO")))] | |
662 | "" | |
663 | "adds\t%0, %r1, %r2" | |
664 | [(set_attr "type" "X01")]) | |
665 | ||
666 | (define_insn "sssubsi3" | |
667 | [(set (match_operand:SI 0 "register_operand" "=r") | |
668 | (ss_minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") | |
669 | (match_operand:SI 2 "reg_or_0_operand" "rO")))] | |
670 | "" | |
671 | "subs\t%0, %r1, %r2" | |
672 | [(set_attr "type" "X01")]) | |
673 | ||
674 | ;; | |
675 | ;; Shifts | |
676 | ;; | |
677 | ||
678 | ;; ashift, ashiftrt, lshiftrt, rotate. | |
679 | (define_insn "<optab>si3" | |
680 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
681 | (binop_u5bit:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO") | |
682 | (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))] | |
683 | "" | |
684 | "@ | |
685 | <insn>i\t%0, %r1, %2 | |
686 | <insn>\t%0, %r1, %r2") | |
687 | ||
688 | \f | |
689 | ;; | |
690 | ;; Compares | |
691 | ;; | |
692 | ||
693 | (define_expand "cstore<mode>4" | |
694 | [(set (match_operand:SI 0 "register_operand" "") | |
695 | (match_operator:SI 1 "ordered_comparison_operator" | |
696 | [(match_operand:I48MODE 2 "reg_or_cint_operand" "") | |
697 | (match_operand:I48MODE 3 "reg_or_cint_operand" "")]))] | |
698 | "" | |
699 | { if (!tilepro_emit_setcc (operands, <MODE>mode)) FAIL; else DONE; }) | |
700 | ||
701 | (define_insn "insn_seq" | |
702 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
703 | (eq:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO") | |
704 | (match_operand:SI 2 "reg_or_cint_operand" "I,rO")))] | |
705 | "" | |
706 | "@ | |
707 | seqi\t%0, %r1, %2 | |
708 | seq\t%0, %r1, %r2") | |
709 | ||
710 | (define_insn "insn_sne" | |
711 | [(set (match_operand:SI 0 "register_operand" "=r") | |
712 | (ne:SI (match_operand:SI 1 "reg_or_0_operand" "rO") | |
713 | (match_operand:SI 2 "reg_or_cint_operand" "rO")))] | |
714 | "" | |
715 | "sne\t%0, %r1, %r2") | |
716 | ||
717 | (define_insn "insn_slt" | |
718 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
719 | (lt:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO") | |
720 | (match_operand:SI 2 "reg_or_cint_operand" "I,rO")))] | |
721 | "" | |
722 | "@ | |
723 | slti\t%0, %r1, %2 | |
724 | slt\t%0, %r1, %r2") | |
725 | ||
726 | (define_insn "insn_slte" | |
727 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
728 | (le:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO") | |
729 | (match_operand:SI 2 "reg_or_cint_operand" "L,rO")))] | |
730 | "" | |
731 | "@ | |
732 | slti\t%0, %r1, %P2 | |
733 | slte\t%0, %r1, %r2") | |
734 | ||
735 | (define_insn "insn_slt_u" | |
736 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
737 | (ltu:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO") | |
738 | (match_operand:SI 2 "reg_or_cint_operand" "I,rO")))] | |
739 | "" | |
740 | "@ | |
741 | slti_u\t%0, %r1, %2 | |
742 | slt_u\t%0, %r1, %r2") | |
743 | ||
744 | (define_insn "insn_slte_u" | |
745 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
746 | (leu:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO") | |
747 | (match_operand:SI 2 "reg_or_cint_operand" "Q,rO")))] | |
748 | "" | |
749 | "@ | |
750 | slti_u\t%0, %r1, %P2 | |
751 | slte_u\t%0, %r1, %r2") | |
752 | ||
753 | \f | |
754 | ;; | |
755 | ;; Logical ops | |
756 | ;; | |
757 | ||
758 | (define_insn "andsi3" | |
759 | [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
760 | (and:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO") | |
761 | (match_operand:SI 2 "and_operand" "I,M,rO")))] | |
762 | "" | |
763 | "@ | |
764 | andi\t%0, %r1, %2 | |
765 | mm\t%0, %r1, zero, %M2 | |
766 | and\t%0, %r1, %r2" | |
767 | [(set_attr "type" "*,X01,*")]) | |
768 | ||
769 | (define_insn "iorsi3" | |
770 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
771 | (ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO") | |
772 | (match_operand:SI 2 "reg_or_s8bit_operand" "I,rO")))] | |
773 | "" | |
774 | "@ | |
775 | ori\t%0, %r1, %2 | |
776 | or\t%0, %r1, %r2") | |
777 | ||
778 | (define_insn "xorsi3" | |
779 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
780 | (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO") | |
781 | (match_operand:SI 2 "reg_or_s8bit_operand" "rO,I")))] | |
782 | "" | |
783 | "@ | |
784 | xor\t%0, %r1, %r2 | |
785 | xori\t%0, %r1, %2" | |
786 | [(set_attr "type" "*,X01")]) | |
787 | ||
788 | ;; bswap, clz, ctz, popcount | |
789 | (define_insn "<optab>si2" | |
790 | [(set (match_operand:SI 0 "register_operand" "=r") | |
791 | (unop:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))] | |
792 | "" | |
793 | "<insn>\t%0, %r1" | |
794 | [(set_attr "type" "Y0")]) | |
795 | ||
796 | (define_expand "ctzdi2" | |
797 | [(set (match_operand:DI 0 "register_operand" "") | |
3abe9053 | 798 | (ctz:DI (match_operand:DI 1 "register_operand" "")))] |
dd552284 WL |
799 | "" |
800 | { | |
801 | rtx lo, hi, ctz_lo, ctz_hi, ctz_hi_plus_32, result; | |
802 | ||
803 | split_di (&operands[1], 1, &lo, &hi); | |
804 | lo = force_reg (SImode, lo); | |
805 | hi = force_reg (SImode, hi); | |
806 | ||
807 | ctz_lo = gen_reg_rtx (SImode); | |
808 | emit_insn (gen_ctzsi2 (ctz_lo, lo)); | |
809 | ||
810 | ctz_hi = gen_reg_rtx (SImode); | |
811 | emit_insn (gen_ctzsi2 (ctz_hi, hi)); | |
812 | ||
813 | ctz_hi_plus_32 = gen_reg_rtx (SImode); | |
814 | emit_insn (gen_addsi3 (ctz_hi_plus_32, ctz_hi, GEN_INT (32))); | |
815 | ||
816 | result = gen_reg_rtx (SImode); | |
817 | emit_insn (gen_insn_mvz (result, ctz_lo, lo, ctz_hi_plus_32)); | |
818 | ||
819 | emit_move_insn (operands[0], convert_to_mode (DImode, result, 1)); | |
820 | ||
821 | DONE; | |
822 | }) | |
823 | ||
824 | (define_expand "clzdi2" | |
825 | [(set (match_operand:DI 0 "register_operand" "") | |
3abe9053 | 826 | (clz:DI (match_operand:DI 1 "register_operand" "")))] |
dd552284 WL |
827 | "" |
828 | { | |
829 | rtx lo, hi, clz_lo, clz_hi, clz_lo_plus_32, result; | |
830 | ||
831 | split_di (&operands[1], 1, &lo, &hi); | |
832 | lo = force_reg (SImode, lo); | |
833 | hi = force_reg (SImode, hi); | |
834 | ||
835 | clz_lo = gen_reg_rtx (SImode); | |
836 | emit_insn (gen_clzsi2 (clz_lo, lo)); | |
837 | ||
838 | clz_hi = gen_reg_rtx (SImode); | |
839 | emit_insn (gen_clzsi2 (clz_hi, hi)); | |
840 | ||
841 | clz_lo_plus_32 = gen_reg_rtx (SImode); | |
842 | emit_insn (gen_addsi3 (clz_lo_plus_32, clz_lo, GEN_INT (32))); | |
843 | ||
844 | result = gen_reg_rtx (SImode); | |
845 | emit_insn (gen_insn_mvz (result, clz_hi, hi, clz_lo_plus_32)); | |
846 | ||
847 | emit_move_insn (operands[0], convert_to_mode (DImode, result, 1)); | |
848 | ||
849 | DONE; | |
850 | }) | |
851 | ||
852 | (define_expand "ffsdi2" | |
853 | [(set (match_operand:DI 0 "register_operand" "") | |
3abe9053 | 854 | (ffs:DI (match_operand:DI 1 "register_operand" "")))] |
dd552284 WL |
855 | "" |
856 | { | |
857 | rtx lo, hi, ctz_lo, ctz_hi, ctz_hi_plus_32, ctz, ctz_plus_1,ctz_cond; | |
858 | rtx result; | |
859 | ||
860 | split_di (&operands[1], 1, &lo, &hi); | |
861 | lo = force_reg (SImode, lo); | |
862 | hi = force_reg (SImode, hi); | |
863 | ||
864 | ctz_lo = gen_reg_rtx (SImode); | |
865 | emit_insn (gen_ctzsi2 (ctz_lo, lo)); | |
866 | ||
867 | ctz_hi = gen_reg_rtx (SImode); | |
868 | emit_insn (gen_ctzsi2 (ctz_hi, hi)); | |
869 | ||
870 | ctz_hi_plus_32 = gen_reg_rtx (SImode); | |
871 | emit_insn (gen_addsi3 (ctz_hi_plus_32, ctz_hi, GEN_INT (32))); | |
872 | ||
873 | ctz = gen_reg_rtx (SImode); | |
874 | emit_insn (gen_insn_mvz (ctz, ctz_lo, lo, ctz_hi_plus_32)); | |
875 | ||
876 | ctz_plus_1 = gen_reg_rtx (SImode); | |
877 | emit_insn (gen_addsi3 (ctz_plus_1, ctz, GEN_INT (1))); | |
878 | ||
879 | ctz_cond = gen_reg_rtx (SImode); | |
880 | emit_insn (gen_iorsi3 (ctz_cond, lo, hi)); | |
881 | ||
882 | result = gen_reg_rtx (SImode); | |
883 | emit_insn (gen_insn_mvz (result, ctz_plus_1, ctz_cond, const0_rtx)); | |
884 | ||
885 | emit_move_insn (operands[0], convert_to_mode (DImode, result, 1)); | |
886 | ||
887 | DONE; | |
888 | }) | |
889 | ||
890 | (define_expand "popcountdi2" | |
891 | [(set (match_operand:DI 0 "register_operand" "") | |
892 | (popcount:DI (match_operand:DI 1 "nonmemory_operand" "")))] | |
893 | "" | |
894 | { | |
895 | rtx lo, hi, popcount_lo, popcount_hi, result; | |
896 | ||
897 | split_di (&operands[1], 1, &lo, &hi); | |
898 | lo = force_reg (SImode, lo); | |
899 | hi = force_reg (SImode, hi); | |
900 | ||
901 | popcount_lo = gen_reg_rtx (SImode); | |
902 | emit_insn (gen_popcountsi2 (popcount_lo, lo)); | |
903 | ||
904 | popcount_hi = gen_reg_rtx (SImode); | |
905 | emit_insn (gen_popcountsi2 (popcount_hi, hi)); | |
906 | ||
907 | result = gen_reg_rtx (SImode); | |
908 | emit_insn (gen_addsi3 (result, popcount_lo, popcount_hi)); | |
909 | ||
910 | emit_move_insn (operands[0], convert_to_mode (DImode, result, 1)); | |
911 | ||
912 | DONE; | |
913 | }) | |
914 | ||
915 | (define_expand "paritysi2" | |
916 | [(set (match_operand:SI 0 "register_operand" "") | |
917 | (parity:SI (match_operand:SI 1 "reg_or_0_operand" "")))] | |
918 | "" | |
919 | { | |
920 | operands[2] = gen_reg_rtx (SImode); | |
921 | emit_insn (gen_popcountsi2 (operands[2], operands[1])); | |
922 | emit_insn (gen_andsi3 (operands[0], operands[2], const1_rtx)); | |
923 | DONE; | |
924 | }) | |
925 | ||
926 | (define_expand "paritydi2" | |
927 | [(set (match_operand:DI 0 "register_operand" "") | |
928 | (parity:DI (match_operand:DI 1 "nonmemory_operand" "")))] | |
929 | "" | |
930 | { | |
931 | rtx lo, hi, xor_lohi, result; | |
932 | ||
933 | split_di (&operands[1], 1, &lo, &hi); | |
934 | lo = force_reg (SImode, lo); | |
935 | hi = force_reg (SImode, hi); | |
936 | ||
937 | xor_lohi = gen_reg_rtx (SImode); | |
938 | emit_insn (gen_xorsi3 (xor_lohi, lo, hi)); | |
939 | ||
940 | result = gen_reg_rtx (SImode); | |
941 | emit_insn (gen_paritysi2 (result, xor_lohi)); | |
942 | ||
943 | emit_move_insn (operands[0], convert_to_mode (DImode, result, 1)); | |
944 | ||
945 | DONE; | |
946 | }) | |
947 | ||
948 | (define_insn "one_cmplsi2" | |
949 | [(set (match_operand:SI 0 "register_operand" "=r") | |
950 | (not:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))] | |
951 | "" | |
952 | "nor\t%0, %r1, zero") | |
953 | ||
954 | \f | |
955 | ;; | |
956 | ;; Conditional moves. | |
957 | ;; | |
958 | ||
959 | (define_expand "movsicc" | |
960 | [(set (match_operand:SI 0 "register_operand" "") | |
961 | (if_then_else:SI (match_operand 1 "comparison_operator" "") | |
962 | (match_operand:SI 2 "reg_or_0_operand" "") | |
963 | (match_operand:SI 3 "reg_or_0_operand" "")))] | |
964 | "" | |
965 | { operands[1] = tilepro_emit_conditional_move (operands[1]); }) | |
966 | ||
967 | (define_insn "movcc_insn" | |
968 | [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") | |
969 | (if_then_else:SI | |
970 | (match_operator 4 "eqne_operator" | |
971 | [(match_operand:SI 1 "reg_or_0_operand" "rO,rO,rO,rO") | |
972 | (const_int 0)]) | |
973 | (match_operand:SI 2 "reg_or_0_operand" "rO,O,rO,0") | |
974 | (match_operand:SI 3 "reg_or_0_operand" "O,rO,0,rO")))] | |
975 | "" | |
976 | "@ | |
977 | m%c4\t%0, %r1, %r2 | |
978 | m%C4\t%0, %r1, %r3 | |
979 | mv%c4\t%0, %r1, %r2 | |
980 | mv%C4\t%0, %r1, %r3" | |
981 | [(set_attr "type" "*,*,Y0,Y0")]) | |
982 | ||
983 | (define_expand "insn_mz" | |
984 | [(set (match_operand:SI 0 "register_operand" "") | |
985 | (if_then_else:SI | |
986 | (eq (match_operand:SI 1 "reg_or_0_operand" "") | |
987 | (const_int 0)) | |
988 | (match_operand:SI 2 "reg_or_0_operand" "") | |
989 | (const_int 0)))]) | |
990 | ||
991 | (define_expand "insn_mnz" | |
992 | [(set (match_operand:SI 0 "register_operand" "") | |
993 | (if_then_else:SI | |
994 | (ne (match_operand:SI 1 "reg_or_0_operand" "") | |
995 | (const_int 0)) | |
996 | (match_operand:SI 2 "reg_or_0_operand" "") | |
997 | (const_int 0)))]) | |
998 | ||
999 | (define_expand "insn_mvz" | |
1000 | [(set (match_operand:SI 0 "register_operand" "") | |
1001 | (if_then_else:SI | |
1002 | (eq (match_operand:SI 2 "reg_or_0_operand" "") | |
1003 | (const_int 0)) | |
1004 | (match_operand:SI 3 "reg_or_0_operand" "") | |
1005 | (match_operand:SI 1 "reg_or_0_operand" "")))]) | |
1006 | ||
1007 | (define_expand "insn_mvnz" | |
1008 | [(set (match_operand:SI 0 "register_operand" "") | |
1009 | (if_then_else:SI | |
1010 | (ne (match_operand:SI 2 "reg_or_0_operand" "") | |
1011 | (const_int 0)) | |
1012 | (match_operand:SI 3 "reg_or_0_operand" "") | |
1013 | (match_operand:SI 1 "reg_or_0_operand" "")))]) | |
1014 | ||
1015 | \f | |
1016 | ;; | |
1017 | ;; Conversions | |
1018 | ;; | |
1019 | ||
1020 | (define_insn "zero_extendqisi2" | |
1021 | [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
1022 | (zero_extend:SI (match_operand:QI 1 "move_operand" "rO,U,m")))] | |
1023 | "" | |
1024 | "@ | |
1025 | mm\t%0, %r1, zero, 0, 7 | |
1026 | lb_u\t%0, %1 | |
1027 | lbadd_u\t%0, %I1, %i1" | |
1028 | [(set_attr "type" "X01,Y2_2cycle,X1_2cycle")]) | |
1029 | ||
1030 | (define_insn "zero_extendhisi2" | |
1031 | [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
1032 | (zero_extend:SI (match_operand:HI 1 "move_operand" "rO,U,m")))] | |
1033 | "" | |
1034 | "@ | |
1035 | mm\t%0, %r1, zero, 0, 15 | |
1036 | lh_u\t%0, %1 | |
1037 | lhadd_u\t%0, %I1, %i1" | |
1038 | [(set_attr "type" "X01,Y2_2cycle,X1_2cycle")]) | |
1039 | ||
1040 | (define_expand "extendhisi2" | |
1041 | [(set (match_operand:SI 0 "register_operand" "") | |
1042 | (sign_extend:SI (match_operand:HI 1 "move_operand" "")))] | |
1043 | "" | |
1044 | { | |
1045 | if (!memory_operand (operands[1], HImode)) | |
1046 | { | |
1047 | operands[1] = gen_lowpart (SImode, operands[1]); | |
1048 | operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0]; | |
1049 | ||
1050 | emit_move_insn (operands[2], gen_rtx_ASHIFT (SImode, operands[1], | |
1051 | GEN_INT (16))); | |
1052 | emit_move_insn (operands[0], gen_rtx_ASHIFTRT (SImode, operands[2], | |
1053 | GEN_INT (16))); | |
1054 | DONE; | |
1055 | } | |
1056 | }) | |
1057 | ||
1058 | (define_insn "*lh" | |
1059 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1060 | (sign_extend:SI (match_operand:HI 1 "memory_operand" "U,m")))] | |
1061 | "" | |
1062 | "@ | |
1063 | lh\t%0, %1 | |
1064 | lhadd\t%0, %I1, %i1" | |
1065 | [(set_attr "type" "Y2_2cycle,X1_2cycle")]) | |
1066 | ||
1067 | (define_expand "extendqisi2" | |
1068 | [(set (match_operand:SI 0 "register_operand" "") | |
1069 | (sign_extend:SI (match_operand:QI 1 "move_operand" "")))] | |
1070 | "" | |
1071 | { | |
1072 | if (!memory_operand (operands[1], QImode)) | |
1073 | { | |
1074 | operands[1] = gen_lowpart (SImode, operands[1]); | |
1075 | operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0]; | |
1076 | ||
1077 | emit_move_insn (operands[2], gen_rtx_ASHIFT (SImode, operands[1], | |
1078 | GEN_INT (24))); | |
1079 | emit_move_insn (operands[0], gen_rtx_ASHIFTRT (SImode, operands[2], | |
1080 | GEN_INT (24))); | |
1081 | DONE; | |
1082 | } | |
1083 | }) | |
1084 | ||
1085 | (define_insn "*lb" | |
1086 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1087 | (sign_extend:SI (match_operand:QI 1 "memory_operand" "U,m")))] | |
1088 | "" | |
1089 | "@ | |
1090 | lb\t%0, %1 | |
1091 | lbadd\t%0, %I1, %i1" | |
1092 | [(set_attr "type" "Y2_2cycle,X1_2cycle")]) | |
1093 | ||
1094 | ;; | |
1095 | ;; insv patterns | |
1096 | ;; | |
1097 | (define_expand "insv" | |
1098 | [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "") | |
1099 | (match_operand:SI 1 "u5bit_cint_operand" "") | |
1100 | (match_operand:SI 2 "u5bit_cint_operand" "")) | |
1101 | (match_operand:SI 3 "reg_or_cint_operand" ""))] | |
1102 | "" | |
1103 | { | |
1104 | tilepro_expand_insv (operands); | |
1105 | DONE; | |
1106 | }) | |
1107 | ||
1108 | (define_insn "*insv_tblidxb0" | |
1109 | [(set (zero_extract:SI | |
1110 | (match_operand:SI 0 "register_operand" "+r") | |
1111 | (const_int 8) | |
1112 | (const_int 2)) | |
1113 | (match_operand:SI 1 "register_operand" "rO"))] | |
1114 | "" | |
1115 | "tblidxb0\t%0, %r1" | |
1116 | [(set_attr "type" "Y0")]) | |
1117 | ||
1118 | (define_insn "*insv_tblidxb1" | |
1119 | [(set (zero_extract:SI | |
1120 | (match_operand:SI 0 "register_operand" "+r") | |
1121 | (const_int 8) | |
1122 | (const_int 2)) | |
1123 | (zero_extract:SI | |
1124 | (const_int 8) | |
1125 | (const_int 8) | |
1126 | (match_operand:SI 1 "register_operand" "rO")))] | |
1127 | "" | |
1128 | "tblidxb1\t%0, %r1" | |
1129 | [(set_attr "type" "Y0")]) | |
1130 | ||
1131 | (define_insn "*insv_tblidxb2" | |
1132 | [(set (zero_extract:SI | |
1133 | (match_operand:SI 0 "register_operand" "+r") | |
1134 | (const_int 8) | |
1135 | (const_int 2)) | |
1136 | (zero_extract:SI | |
1137 | (const_int 8) | |
1138 | (const_int 16) | |
1139 | (match_operand:SI 1 "register_operand" "rO")))] | |
1140 | "" | |
1141 | "tblidxb2\t%0, %r1" | |
1142 | [(set_attr "type" "Y0")]) | |
1143 | ||
1144 | (define_insn "*insv_tblidxb3" | |
1145 | [(set (zero_extract:SI | |
1146 | (match_operand:SI 0 "register_operand" "+r") | |
1147 | (const_int 8) | |
1148 | (const_int 2)) | |
1149 | (zero_extract:SI | |
1150 | (const_int 8) | |
1151 | (const_int 24) | |
1152 | (match_operand:SI 1 "register_operand" "rO")))] | |
1153 | "" | |
1154 | "tblidxb3\t%0, %r1" | |
1155 | [(set_attr "type" "Y0")]) | |
1156 | ||
1157 | (define_insn "*insv_mm1" | |
1158 | [(set (zero_extract:SI | |
1159 | (match_operand:SI 0 "register_operand" "+r") | |
1160 | (match_operand:SI 1 "u5bit_cint_operand" "n") | |
1161 | (const_int 0)) | |
1162 | (match_operand:SI 2 "register_operand" "rO"))] | |
1163 | "" | |
1164 | "mm\t%0, %r2, %0, 0, %1-1" | |
1165 | [(set_attr "type" "X01")]) | |
1166 | ||
1167 | (define_insn "*insv_mm2" | |
1168 | [(set (zero_extract:SI | |
1169 | (match_operand:SI 0 "register_operand" "+r") | |
1170 | (match_operand:SI 1 "u5bit_cint_operand" "n") | |
1171 | (match_operand:SI 2 "u5bit_cint_operand" "n")) | |
1172 | (zero_extract:SI | |
1173 | (match_operand:SI 3 "register_operand" "rO") | |
1174 | (match_dup 1) | |
1175 | (match_dup 2)))] | |
1176 | "" | |
1177 | "mm\t%0, %r3, %0, %2, %2+%1-1" | |
1178 | [(set_attr "type" "X01")]) | |
1179 | ||
1180 | \f | |
1181 | ;; | |
1182 | ;; Multiplies | |
1183 | ;; | |
1184 | ||
1185 | (define_expand "mulsi3" | |
1186 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1187 | (mult:SI (zero_extend:SI | |
1188 | (subreg:HI (match_operand:SI 1 "nonmemory_operand" "") 0)) | |
1189 | (zero_extend:SI | |
1190 | (subreg:HI (match_operand:SI 2 "nonmemory_operand" "") 0)))) | |
1191 | (set (match_dup 0) | |
1192 | (unspec:SI [(match_dup 0) (match_dup 1) (match_dup 2)] | |
1193 | UNSPEC_INSN_MULHLSA_UU)) | |
1194 | (set (match_dup 0) | |
1195 | (unspec:SI [(match_dup 0) (match_dup 2) (match_dup 1)] | |
1196 | UNSPEC_INSN_MULHLSA_UU))] | |
1197 | "" | |
1198 | { | |
1199 | operands[1] = force_reg (SImode, operands[1]); | |
1200 | operands[1] = make_safe_from (operands[1], operands[0]); | |
1201 | ||
1202 | if (tilepro_expand_mulsi (operands[0], operands[1], operands[2])) | |
1203 | DONE; | |
1204 | else | |
1205 | { | |
1206 | operands[2] = force_reg (SImode, operands[2]); | |
1207 | operands[2] = make_safe_from (operands[2], operands[0]); | |
1208 | } | |
1209 | }) | |
1210 | ||
1211 | (define_insn "mulhisi3" | |
1212 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1213 | (mult:SI (sign_extend:SI | |
1214 | (match_operand:HI 1 "reg_or_0_operand" "rO")) | |
1215 | (sign_extend:SI | |
1216 | (match_operand:HI 2 "reg_or_0_operand" "rO"))))] | |
1217 | "" | |
1218 | "mulll_ss\t%0, %r1, %r2" | |
1219 | [(set_attr "type" "Y0_2cycle")]) | |
1220 | ||
1221 | (define_insn "umulhisi3" | |
1222 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1223 | (mult:SI (zero_extend:SI | |
1224 | (match_operand:HI 1 "reg_or_0_operand" "rO")) | |
1225 | (zero_extend:SI | |
1226 | (match_operand:HI 2 "reg_or_0_operand" "rO"))))] | |
1227 | "" | |
1228 | "mulll_uu\t%0, %r1, %r2" | |
1229 | [(set_attr "type" "Y0_2cycle")]) | |
1230 | ||
1231 | (define_insn "usmulhisi3" | |
1232 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1233 | (mult:SI (zero_extend:SI | |
1234 | (match_operand:HI 1 "reg_or_0_operand" "rO")) | |
1235 | (sign_extend:SI | |
1236 | (match_operand:HI 2 "reg_or_0_operand" "rO"))))] | |
1237 | "" | |
1238 | "mulll_su\t%0, %r2, %r1" | |
1239 | [(set_attr "type" "X0_2cycle")]) | |
1240 | ||
1241 | (define_insn "maddhisi4" | |
1242 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1243 | (plus:SI | |
1244 | (mult:SI (sign_extend:SI | |
1245 | (match_operand:HI 1 "reg_or_0_operand" "rO")) | |
1246 | (sign_extend:SI | |
1247 | (match_operand:HI 2 "reg_or_0_operand" "rO"))) | |
1248 | (match_operand:SI 3 "register_operand" "0")))] | |
1249 | "" | |
1250 | "mullla_ss\t%0, %r1, %r2" | |
1251 | [(set_attr "type" "Y0_2cycle")]) | |
1252 | ||
1253 | (define_insn "umaddhisi4" | |
1254 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1255 | (plus:SI | |
1256 | (mult:SI (zero_extend:SI | |
1257 | (match_operand:HI 1 "reg_or_0_operand" "rO")) | |
1258 | (zero_extend:SI | |
1259 | (match_operand:HI 2 "reg_or_0_operand" "rO"))) | |
1260 | (match_operand:SI 3 "register_operand" "0")))] | |
1261 | "" | |
1262 | "mullla_uu\t%0, %r1, %r2" | |
1263 | [(set_attr "type" "Y0_2cycle")]) | |
1264 | ||
1265 | ||
1266 | (define_insn "mulqihi3" | |
1267 | [(set (match_operand:HI 0 "register_operand" "=r") | |
1268 | (mult:HI (sign_extend:HI | |
1269 | (match_operand:QI 1 "reg_or_0_operand" "rO")) | |
1270 | (sign_extend:HI | |
1271 | (match_operand:QI 2 "reg_or_0_operand" "rO"))))] | |
1272 | "" | |
1273 | "mulll_ss\t%0, %r1, %r2" | |
1274 | [(set_attr "type" "Y0_2cycle")]) | |
1275 | ||
1276 | (define_insn "umulqihi3" | |
1277 | [(set (match_operand:HI 0 "register_operand" "=r") | |
1278 | (mult:HI (zero_extend:HI | |
1279 | (match_operand:QI 1 "reg_or_0_operand" "rO")) | |
1280 | (zero_extend:HI | |
1281 | (match_operand:QI 2 "reg_or_0_operand" "rO"))))] | |
1282 | "" | |
1283 | "mulll_uu\t%0, %r1, %r2" | |
1284 | [(set_attr "type" "Y0_2cycle")]) | |
1285 | ||
1286 | (define_expand "smulsi3_highpart" | |
1287 | [(set (match_operand:SI 0 "register_operand" "") | |
1288 | (truncate:SI | |
1289 | (ashiftrt:DI | |
1290 | (mult:DI (sign_extend:DI (match_operand:SI 1 "reg_or_0_operand" "")) | |
1291 | (sign_extend:DI (match_operand:SI 2 "reg_or_0_operand" ""))) | |
1292 | (const_int 32))))] | |
1293 | "" | |
1294 | { | |
1295 | tilepro_expand_smulsi3_highpart (operands[0], operands[1], operands[2]); | |
1296 | DONE; | |
1297 | }) | |
1298 | ||
1299 | (define_expand "umulsi3_highpart" | |
1300 | [(set (match_operand:SI 0 "register_operand" "") | |
1301 | (truncate:SI | |
1302 | (lshiftrt:DI | |
1303 | (mult:DI (zero_extend:DI (match_operand:SI 1 "reg_or_0_operand" "")) | |
1304 | (zero_extend:DI (match_operand:SI 2 "reg_or_0_operand" ""))) | |
1305 | (const_int 32))))] | |
1306 | "" | |
1307 | { | |
1308 | tilepro_expand_umulsi3_highpart (operands[0], operands[1], operands[2]); | |
1309 | DONE; | |
1310 | }) | |
1311 | ||
1312 | \f | |
1313 | ;; | |
1314 | ;; Loops | |
1315 | ;; | |
1316 | ||
1317 | ;; Define the subtract-one-and-jump insns so loop.c knows what to | |
1318 | ;; generate. | |
1319 | (define_expand "doloop_end" | |
1320 | [(use (match_operand 0 "" "")) ;; loop pseudo | |
1d0216c8 | 1321 | (use (match_operand 1 "" ""))] ;; label |
dd552284 WL |
1322 | "" |
1323 | { | |
1324 | if (optimize > 0) | |
1325 | { | |
1326 | rtx s0; | |
1327 | rtx bcomp; | |
1328 | rtx loc_ref; | |
1329 | ||
dd552284 WL |
1330 | /* only deal with loop counters in SImode */ |
1331 | if (GET_MODE (operands[0]) != SImode) | |
1332 | FAIL; | |
1333 | ||
1334 | s0 = operands [0]; | |
1335 | ||
1336 | emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1))); | |
1337 | bcomp = gen_rtx_NE(SImode, s0, const0_rtx); | |
1d0216c8 | 1338 | loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]); |
f7df4a84 | 1339 | emit_jump_insn (gen_rtx_SET (pc_rtx, |
dd552284 WL |
1340 | gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp, |
1341 | loc_ref, pc_rtx))); | |
1342 | DONE; | |
1343 | } | |
1344 | else | |
1345 | FAIL; | |
1346 | ||
1347 | }) | |
1348 | ||
1349 | ;; | |
1350 | ;; Prologue/epilogue | |
1351 | ;; | |
1352 | (define_expand "prologue" | |
1353 | [(const_int 0)] | |
1354 | "" | |
1355 | { | |
1356 | tilepro_expand_prologue (); | |
1357 | DONE; | |
1358 | }) | |
1359 | ||
1360 | (define_expand "epilogue" | |
1361 | [(const_int 0)] | |
1362 | "" | |
1363 | { | |
1364 | tilepro_expand_epilogue (false); | |
1365 | DONE; | |
1366 | }) | |
1367 | ||
1368 | (define_expand "sibcall_epilogue" | |
1369 | [(const_int 0)] | |
1370 | "" | |
1371 | { | |
1372 | tilepro_expand_epilogue (true); | |
1373 | DONE; | |
1374 | }) | |
1375 | ||
1376 | ;; | |
1377 | ;; Stack manipulations | |
1378 | ;; | |
1379 | ||
1380 | ;; An insn to allocate new stack space for dynamic use (e.g., alloca). | |
1381 | (define_expand "allocate_stack" | |
1382 | [(set (match_operand 0 "register_operand" "") | |
1383 | (minus (reg 54) (match_operand 1 "nonmemory_operand" ""))) | |
1384 | (set (reg 54) | |
1385 | (minus (reg 54) (match_dup 1)))] | |
1386 | "" | |
1387 | "tilepro_allocate_stack (operands[0], operands[1]); DONE;") | |
1388 | ||
1389 | ;; | |
1390 | ;; Branches | |
1391 | ;; | |
1392 | (define_expand "call" | |
1393 | [(parallel [(call (match_operand:SI 0 "call_operand" "") | |
1394 | (match_operand 1 "" "")) | |
1395 | (use (reg:SI 54)) | |
1396 | (clobber (reg:SI 55))])] | |
1397 | "" | |
1398 | "") | |
1399 | ||
1400 | (define_insn "*call_insn" | |
1401 | [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rO,i")) | |
1402 | (match_operand 1 "" "")) | |
1403 | (use (reg:SI 54)) | |
1404 | (clobber (reg:SI 55))] | |
1405 | "" | |
1406 | "@ | |
1407 | jalr\t%r0 | |
1408 | jal\t%p0" | |
1409 | [(set_attr "type" "X1,X1")]) | |
1410 | ||
1411 | (define_expand "call_value" | |
1412 | [(parallel [(set (match_operand 0 "register_operand" "") | |
1413 | (call (match_operand:SI 1 "call_operand" "") | |
1414 | (match_operand 2 "" ""))) | |
1415 | (use (reg:SI 54)) | |
1416 | (clobber (reg:SI 55))])] | |
1417 | "") | |
1418 | ||
1419 | (define_insn "*call_value_insn" | |
1420 | [(set (match_operand 0 "register_operand" "=r,r") | |
1421 | (call (mem:SI (match_operand:SI 1 "call_address_operand" "rO,i")) | |
1422 | (match_operand 2 "" ""))) | |
1423 | (use (reg:SI 54)) | |
1424 | (clobber (reg:SI 55))] | |
1425 | "" | |
1426 | "@ | |
1427 | jalr\t%r1 | |
1428 | jal\t%p1" | |
1429 | [(set_attr "type" "X1,X1")]) | |
1430 | ||
1431 | (define_expand "sibcall" | |
1432 | [(parallel [(call (match_operand:SI 0 "call_operand" "") | |
1433 | (match_operand 1 "" "")) | |
1434 | (use (reg:SI 54))])] | |
1435 | "" | |
1436 | "") | |
1437 | ||
1438 | (define_insn "*sibcall_insn" | |
1439 | [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rO,i")) | |
1440 | (match_operand 1 "" "")) | |
1441 | (use (reg:SI 54))] | |
1442 | "SIBLING_CALL_P(insn)" | |
1443 | "@ | |
1444 | jr\t%r0 | |
1445 | j\t%p0" | |
1446 | [(set_attr "type" "X1,X1")]) | |
1447 | ||
1448 | (define_expand "sibcall_value" | |
1449 | [(parallel [(set (match_operand 0 "" "") | |
1450 | (call (match_operand:SI 1 "call_operand" "") | |
1451 | (match_operand:SI 2 "" ""))) | |
1452 | (use (reg:SI 54))])] | |
1453 | "" | |
1454 | "") | |
1455 | ||
1456 | (define_insn "*sibcall_value" | |
1457 | [(set (match_operand 0 "" "") | |
1458 | (call (mem:SI (match_operand:SI 1 "call_address_operand" "rO,i")) | |
1459 | (match_operand:SI 2 "" ""))) | |
1460 | (use (reg:SI 54))] | |
1461 | "SIBLING_CALL_P(insn)" | |
1462 | "@ | |
1463 | jr\t%r1 | |
1464 | j\t%p1" | |
1465 | [(set_attr "type" "X1,X1")]) | |
1466 | ||
1467 | (define_insn "jump" | |
1468 | [(set (pc) (label_ref (match_operand 0 "" "")))] | |
1469 | "" | |
1470 | "j\t%l0" | |
1471 | [(set_attr "type" "X1")]) | |
1472 | ||
1473 | (define_insn "indirect_jump" | |
1474 | [(set (pc) (match_operand:SI 0 "register_operand" "rO"))] | |
1475 | "" | |
1476 | "jr\t%r0" | |
1477 | [(set_attr "type" "X1")]) | |
1478 | ||
1479 | (define_expand "return" | |
1480 | [(parallel | |
1481 | [(return) | |
1482 | (use (reg:SI 55))])] | |
1483 | "tilepro_can_use_return_insn_p ()" | |
1484 | "") | |
1485 | ||
1486 | (define_insn "_return" | |
1487 | [(return) | |
1488 | (use (reg:SI 55))] | |
1489 | "reload_completed" | |
1490 | "jrp\tlr" | |
1491 | [(set_attr "type" "X1")]) | |
1492 | ||
1493 | (define_expand "tablejump" | |
1494 | [(set (pc) (match_operand:SI 0 "register_operand" "")) | |
1495 | (use (label_ref (match_operand 1 "" "")))] | |
1496 | "" | |
1497 | { | |
1498 | tilepro_expand_tablejump (operands[0], operands[1]); | |
1499 | DONE; | |
1500 | }) | |
1501 | ||
1502 | (define_insn "tablejump_aux" | |
1503 | [(set (pc) (match_operand:SI 0 "register_operand" "r")) | |
1504 | (use (label_ref (match_operand 1 "" "")))] | |
1505 | "" | |
1506 | "jr\t%0" | |
1507 | [(set_attr "type" "X1")]) | |
1508 | ||
1509 | ;; Call subroutine returning any type. | |
1510 | (define_expand "untyped_call" | |
1511 | [(parallel [(call (match_operand 0 "" "") | |
1512 | (const_int 0)) | |
1513 | (match_operand 1 "" "") | |
1514 | (match_operand 2 "" "")])] | |
1515 | "" | |
1516 | { | |
1517 | int i; | |
1518 | ||
58d745ec | 1519 | emit_call_insn (gen_call (operands[0], const0_rtx)); |
dd552284 WL |
1520 | |
1521 | for (i = 0; i < XVECLEN (operands[2], 0); i++) | |
1522 | { | |
1523 | rtx set = XVECEXP (operands[2], 0, i); | |
1524 | emit_move_insn (SET_DEST (set), SET_SRC (set)); | |
1525 | } | |
1526 | ||
1527 | /* The optimizer does not know that the call sets the function value | |
1528 | registers we stored in the result block. We avoid problems by | |
1529 | claiming that all hard registers are used and clobbered at this | |
1530 | point. */ | |
1531 | emit_insn (gen_blockage ()); | |
1532 | ||
1533 | DONE; | |
1534 | }) | |
1535 | ||
1536 | ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers | |
1537 | ;; and all of memory. This blocks insns from being moved across this | |
1538 | ;; point. | |
1539 | (define_insn "blockage" | |
1540 | [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)] | |
1541 | "" | |
1542 | "pseudo" | |
1543 | [(set_attr "type" "nothing") | |
1544 | (set_attr "length" "0")]) | |
1545 | ||
1546 | ;; Internal expanders to prevent memory ops from moving around frame | |
1547 | ;; allocation/deallocation. | |
1548 | ;; | |
1549 | ;; TODO: really this clobber should just clobber the frame memory. Is | |
1550 | ;; this possibly by clobbering memory @ the sp reg (as alpha does?) | |
1551 | ;; or by explicitly setting the alias set to the frame? | |
1552 | (define_insn "sp_adjust" | |
1553 | [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
1554 | (plus:SI | |
1555 | (match_operand:SI 1 "register_operand" "%r,r,r") | |
1556 | (match_operand:SI 2 "add_operand" "r,I,J"))) | |
1557 | (clobber (mem:BLK (scratch)))] | |
1558 | "" | |
1559 | "@ | |
1560 | add\t%0, %1, %2 | |
1561 | addi\t%0, %1, %2 | |
1562 | addli\t%0, %1, %2" | |
1563 | [(set_attr "type" "*,*,X01")]) | |
1564 | ||
1565 | ;; Used for move sp, r52, to pop a stack frame. We need to make sure | |
1566 | ;; that stack frame memory operations have been issued before we do | |
1567 | ;; this. TODO: see above TODO. | |
1568 | (define_insn "sp_restore" | |
1569 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1570 | (match_operand:SI 1 "register_operand" "r")) | |
1571 | (clobber (mem:BLK (scratch)))] | |
1572 | "" | |
1573 | "move\t%0, %1") | |
1574 | ||
1575 | (define_insn "nop" | |
1576 | [(const_int 0)] | |
1577 | "" | |
1578 | "nop" | |
1579 | [(set_attr "type" "Y01")]) | |
1580 | ||
90b9beed WL |
1581 | (define_insn "trap" |
1582 | [(trap_if (const_int 1) (const_int 0))] | |
1583 | "" | |
1584 | "raise; moveli zero, 6" | |
1585 | [(set_attr "type" "cannot_bundle")]) | |
1586 | ||
dd552284 WL |
1587 | \f |
1588 | ;; | |
1589 | ;; Conditional branches | |
1590 | ;; | |
1591 | ||
1592 | (define_expand "cbranchsi4" | |
1593 | [(set (pc) | |
1594 | (if_then_else (match_operator 0 "ordered_comparison_operator" | |
1595 | [(match_operand:SI 1 "reg_or_cint_operand") | |
1596 | (match_operand:SI 2 "reg_or_cint_operand")]) | |
1597 | (label_ref (match_operand 3 "")) | |
1598 | (pc)))] | |
1599 | "" | |
1600 | { tilepro_emit_conditional_branch (operands, SImode); DONE; }) | |
1601 | ||
1602 | ||
1603 | (define_expand "cbranchdi4" | |
1604 | [(set (pc) | |
1605 | (if_then_else (match_operator 0 "ordered_comparison_operator" | |
1606 | [(match_operand:DI 1 "reg_or_cint_operand") | |
1607 | (match_operand:DI 2 "reg_or_cint_operand")]) | |
1608 | (label_ref (match_operand 3 "")) | |
1609 | (pc)))] | |
1610 | "" | |
1611 | { tilepro_emit_conditional_branch (operands, DImode); DONE; }) | |
1612 | ||
1613 | ||
1614 | (define_insn "*bcc_normal" | |
1615 | [(set (pc) | |
1616 | (if_then_else | |
1617 | (match_operator 1 "signed_comparison_operator" | |
1618 | [(match_operand:SI 2 "reg_or_0_operand" "rO") | |
1619 | (const_int 0)]) | |
1620 | (label_ref (match_operand 0 "" "")) | |
1621 | (pc)))] | |
1622 | "" | |
1623 | { return tilepro_output_cbranch (insn, operands, false); } | |
1624 | [(set_attr "type" "X1_branch")]) | |
1625 | ||
1626 | (define_insn "*bcc_reverse" | |
1627 | [(set (pc) | |
1628 | (if_then_else | |
1629 | (match_operator 1 "signed_comparison_operator" | |
1630 | [(match_operand:SI 2 "reg_or_0_operand" "rO") | |
1631 | (const_int 0)]) | |
1632 | (pc) | |
1633 | (label_ref (match_operand 0 "" ""))))] | |
1634 | "" | |
1635 | { return tilepro_output_cbranch (insn, operands, true); } | |
1636 | [(set_attr "type" "X1_branch")]) | |
1637 | ||
1638 | ;; FIXME: the straight forward versions which do not include the | |
1639 | ;; subreg:QI does not match for some unknown reason. | |
1640 | (define_insn "*bbs_normal" | |
1641 | [(set (pc) | |
1642 | (if_then_else | |
1643 | (ne (zero_extract:SI (subreg:QI | |
1644 | (match_operand:SI 1 "reg_or_0_operand" "rO") 0) | |
1645 | (const_int 1) | |
1646 | (const_int 0)) | |
1647 | (const_int 0)) | |
1648 | (label_ref (match_operand 0 "" "")) | |
1649 | (pc)))] | |
1650 | "" | |
1651 | { return tilepro_output_cbranch_with_opcode (insn, operands, "bbs", "bbns", | |
1652 | 1, 0); } | |
1653 | [(set_attr "type" "X1_branch")]) | |
1654 | ||
1655 | (define_insn "*bbc_normal" | |
1656 | [(set (pc) | |
1657 | (if_then_else | |
1658 | (eq (zero_extract:SI (subreg:QI | |
1659 | (match_operand:SI 1 "reg_or_0_operand" "rO") 0) | |
1660 | (const_int 1) | |
1661 | (const_int 0)) | |
1662 | (const_int 0)) | |
1663 | (label_ref (match_operand 0 "" "")) | |
1664 | (pc)))] | |
1665 | "" | |
1666 | { return tilepro_output_cbranch_with_opcode (insn, operands, "bbns", "bbs", | |
1667 | 1, 0); } | |
1668 | [(set_attr "type" "X1_branch")]) | |
1669 | ||
1670 | ;; Note that __insn_mf() expands to this. | |
1671 | (define_expand "memory_barrier" | |
1672 | [(set (match_dup 0) | |
1673 | (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))] | |
1674 | "" | |
1675 | { | |
1676 | operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); | |
1677 | MEM_VOLATILE_P (operands[0]) = 1; | |
1678 | }) | |
1679 | ||
1680 | (define_insn "*memory_barrier" | |
1681 | [(set (match_operand:BLK 0 "" "") | |
1682 | (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))] | |
1683 | "" | |
1684 | "mf" | |
1685 | [(set_attr "type" "X1")]) | |
1686 | ||
1687 | (define_insn "prefetch" | |
1688 | [(prefetch (match_operand:SI 0 "address_operand" "rO") | |
1689 | (match_operand:SI 1 "const_int_operand" "") | |
1690 | (match_operand:SI 2 "const_int_operand" ""))] | |
1691 | "" | |
1692 | "prefetch\t%r0" | |
1693 | [(set_attr "type" "Y2")]) | |
1694 | ||
1695 | \f | |
1696 | ;; | |
1697 | ;; Network intrinsics | |
1698 | ;; | |
1699 | ||
1700 | ;; Note the "pseudo" text is handled specially by the | |
1701 | ;; asm_output_opcode routine. If the output is an empty string, the | |
1702 | ;; instruction would bypass the asm_output_opcode routine, bypassing | |
1703 | ;; the bundle handling code. | |
1704 | (define_insn "tilepro_network_barrier" | |
1705 | [(unspec_volatile:SI [(const_int 0)] UNSPEC_NETWORK_BARRIER)] | |
1706 | "" | |
1707 | "pseudo" | |
1708 | [(set_attr "type" "nothing") | |
1709 | (set_attr "length" "0")]) | |
1710 | ||
1711 | (define_insn "*netreg_receive" | |
1712 | [(set (match_operand:SI 0 "nonimmediate_operand" "=r,U,m") | |
1713 | (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i") | |
1714 | (reg:SI TILEPRO_NETORDER_REG)] | |
1715 | UNSPEC_NETWORK_RECEIVE)) | |
1716 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
1717 | "" | |
1718 | "@ | |
1719 | move\t%0, %N1 | |
1720 | sw\t%0, %N1 | |
1721 | swadd\t%I0, %N1, %i0" | |
1722 | [(set_attr "type" "*,Y2,X1")]) | |
1723 | ||
1724 | (define_insn "*netreg_send" | |
1725 | [(unspec_volatile:SI | |
1726 | [(match_operand:SI 0 "netreg_operand" "i,i,i,i,i,i") | |
1727 | (match_operand:SI 1 "reg_or_cint_operand" "rO,I,J,K,N,P") | |
1728 | (reg:SI TILEPRO_NETORDER_REG)] | |
1729 | UNSPEC_NETWORK_SEND) | |
1730 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
1731 | "" | |
1732 | "@ | |
1733 | move\t%N0, %r1 | |
1734 | movei\t%N0, %1 | |
1735 | moveli\t%N0, %1 | |
1736 | auli\t%N0, zero, %h1 | |
1737 | addib\t%N0, zero, %j1 | |
1738 | addih\t%N0, zero, %h1" | |
1739 | [(set_attr "type" "*,*,X01,X01,X01,X01")]) | |
1740 | ||
1741 | (define_insn "*netreg_copy" | |
1742 | [(unspec_volatile:SI | |
1743 | [(match_operand:SI 0 "netreg_operand" "i") | |
1744 | (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i") | |
1745 | (reg:SI TILEPRO_NETORDER_REG)] | |
1746 | UNSPEC_NETWORK_RECEIVE) | |
1747 | (reg:SI TILEPRO_NETORDER_REG)] | |
1748 | UNSPEC_NETWORK_SEND) | |
1749 | (clobber (reg:SI TILEPRO_NETORDER_REG)) | |
1750 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
1751 | "" | |
1752 | "move %N0, %N1") | |
1753 | ||
1754 | (define_expand "tilepro_idn0_receive" | |
1755 | [(parallel | |
1756 | [(set (match_operand:SI 0 "register_operand" "") | |
1757 | (unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN0) | |
1758 | (reg:SI TILEPRO_NETORDER_REG)] | |
1759 | UNSPEC_NETWORK_RECEIVE)) | |
1760 | (clobber (reg:SI TILEPRO_NETORDER_REG))])] | |
1761 | "") | |
1762 | ||
1763 | (define_expand "tilepro_idn1_receive" | |
1764 | [(parallel | |
1765 | [(set (match_operand:SI 0 "register_operand" "") | |
1766 | (unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN1) | |
1767 | (reg:SI TILEPRO_NETORDER_REG)] | |
1768 | UNSPEC_NETWORK_RECEIVE)) | |
1769 | (clobber (reg:SI TILEPRO_NETORDER_REG))])] | |
1770 | "") | |
1771 | ||
1772 | (define_expand "tilepro_idn_send" | |
1773 | [(parallel | |
1774 | [(unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN0) | |
1775 | (match_operand:SI 0 "reg_or_cint_operand" "") | |
1776 | (reg:SI TILEPRO_NETORDER_REG)] | |
1777 | UNSPEC_NETWORK_SEND) | |
1778 | (clobber (reg:SI TILEPRO_NETORDER_REG))])] | |
1779 | "") | |
1780 | ||
1781 | (define_expand "tilepro_sn_receive" | |
1782 | [(parallel | |
1783 | [(set (match_operand:SI 0 "register_operand" "") | |
1784 | (unspec_volatile:SI [(const_int TILEPRO_NETREG_SN) | |
1785 | (reg:SI TILEPRO_NETORDER_REG)] | |
1786 | UNSPEC_NETWORK_RECEIVE)) | |
1787 | (clobber (reg:SI TILEPRO_NETORDER_REG))])] | |
1788 | "") | |
1789 | ||
1790 | (define_expand "tilepro_sn_send" | |
1791 | [(parallel | |
1792 | [(unspec_volatile:SI [(const_int TILEPRO_NETREG_SN) | |
1793 | (match_operand:SI 0 "reg_or_cint_operand" "") | |
1794 | (reg:SI TILEPRO_NETORDER_REG)] | |
1795 | UNSPEC_NETWORK_SEND) | |
1796 | (clobber (reg:SI TILEPRO_NETORDER_REG))])] | |
1797 | "") | |
1798 | ||
1799 | (define_expand "tilepro_udn0_receive" | |
1800 | [(parallel | |
1801 | [(set (match_operand:SI 0 "register_operand" "") | |
1802 | (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN0) | |
1803 | (reg:SI TILEPRO_NETORDER_REG)] | |
1804 | UNSPEC_NETWORK_RECEIVE)) | |
1805 | (clobber (reg:SI TILEPRO_NETORDER_REG))])] | |
1806 | "") | |
1807 | ||
1808 | (define_expand "tilepro_udn1_receive" | |
1809 | [(parallel | |
1810 | [(set (match_operand:SI 0 "register_operand" "") | |
1811 | (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN1) | |
1812 | (reg:SI TILEPRO_NETORDER_REG)] | |
1813 | UNSPEC_NETWORK_RECEIVE)) | |
1814 | (clobber (reg:SI TILEPRO_NETORDER_REG))])] | |
1815 | "") | |
1816 | ||
1817 | (define_expand "tilepro_udn2_receive" | |
1818 | [(parallel | |
1819 | [(set (match_operand:SI 0 "register_operand" "") | |
1820 | (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN2) | |
1821 | (reg:SI TILEPRO_NETORDER_REG)] | |
1822 | UNSPEC_NETWORK_RECEIVE)) | |
1823 | (clobber (reg:SI TILEPRO_NETORDER_REG))])] | |
1824 | "") | |
1825 | ||
1826 | (define_expand "tilepro_udn3_receive" | |
1827 | [(parallel | |
1828 | [(set (match_operand:SI 0 "register_operand" "") | |
1829 | (unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN3) | |
1830 | (reg:SI TILEPRO_NETORDER_REG)] | |
1831 | UNSPEC_NETWORK_RECEIVE)) | |
1832 | (clobber (reg:SI TILEPRO_NETORDER_REG))])] | |
1833 | "") | |
1834 | ||
1835 | (define_expand "tilepro_udn_send" | |
1836 | [(parallel | |
1837 | [(unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN0) | |
1838 | (match_operand:SI 0 "reg_or_cint_operand" "") | |
1839 | (reg:SI TILEPRO_NETORDER_REG)] | |
1840 | UNSPEC_NETWORK_SEND) | |
1841 | (clobber (reg:SI TILEPRO_NETORDER_REG))])] | |
1842 | "") | |
1843 | ||
1844 | (define_insn "*netreg_add_to_network" | |
1845 | [(unspec_volatile:SI | |
1846 | [(match_operand:SI 0 "netreg_operand" "i,i,i,i") | |
1847 | (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO,rO") | |
1848 | (match_operand:SI 2 "add_operand" "r,I,J,K")) | |
1849 | (reg:SI TILEPRO_NETORDER_REG)] | |
1850 | UNSPEC_NETWORK_SEND) | |
1851 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
1852 | "" | |
1853 | "@ | |
1854 | add\t%N0, %r1, %2 | |
1855 | addi\t%N0, %r1, %2 | |
1856 | addli\t%N0, %r1, %2 | |
1857 | auli\t%N0, %r1, %h2" | |
1858 | [(set_attr "type" "*,*,X01,X01")]) | |
1859 | ||
1860 | (define_insn "*netreg_add_from_network" | |
1861 | [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") | |
1862 | (plus:SI | |
1863 | (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i,i") | |
1864 | (reg:SI TILEPRO_NETORDER_REG)] | |
1865 | UNSPEC_NETWORK_RECEIVE) | |
1866 | (match_operand:SI 2 "add_operand" "rO,I,J,K"))) | |
1867 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
1868 | "" | |
1869 | "@ | |
1870 | add\t%0, %N1, %r2 | |
1871 | addi\t%0, %N1, %2 | |
1872 | addli\t%0, %N1, %2 | |
1873 | auli\t%0, %N1, %h2" | |
1874 | [(set_attr "type" "*,*,X01,X01")]) | |
1875 | ||
1876 | (define_insn "*netreg_add_from_to_network" | |
1877 | [(unspec_volatile:SI | |
1878 | [(match_operand:SI 0 "netreg_operand" "i,i,i,i") | |
1879 | (plus:SI | |
1880 | (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i,i") | |
1881 | (reg:SI TILEPRO_NETORDER_REG)] | |
1882 | UNSPEC_NETWORK_RECEIVE) | |
1883 | (match_operand:SI 2 "add_operand" "rO,I,J,K")) | |
1884 | (reg:SI TILEPRO_NETORDER_REG)] | |
1885 | UNSPEC_NETWORK_SEND) | |
1886 | (clobber (reg:SI TILEPRO_NETORDER_REG)) | |
1887 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
1888 | "" | |
1889 | "@ | |
1890 | add\t%N0, %N1, %r2 | |
1891 | addi\t%N0, %N1, %2 | |
1892 | addli\t%N0, %N1, %2 | |
1893 | auli\t%N0, %N1, %h2" | |
1894 | [(set_attr "type" "*,*,X01,X01")]) | |
1895 | ||
1896 | (define_code_iterator netreg_binop | |
1897 | [minus]) | |
1898 | ||
1899 | (define_insn "*netreg_binop_to_network" | |
1900 | [(unspec_volatile:SI | |
1901 | [(match_operand:SI 0 "netreg_operand" "i") | |
1902 | (netreg_binop:SI (match_operand:SI 1 "reg_or_0_operand" "rO") | |
1903 | (match_operand:SI 2 "reg_or_0_operand" "rO")) | |
1904 | (reg:SI TILEPRO_NETORDER_REG)] | |
1905 | UNSPEC_NETWORK_SEND) | |
1906 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
1907 | "" | |
1908 | "<insn>\t%N0, %r1, %r2") | |
1909 | ||
1910 | (define_insn "*netreg_binop_from_network0" | |
1911 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1912 | (netreg_binop:SI | |
1913 | (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i") | |
1914 | (reg:SI TILEPRO_NETORDER_REG)] | |
1915 | UNSPEC_NETWORK_RECEIVE) | |
1916 | (match_operand:SI 2 "reg_or_0_operand" "rO"))) | |
1917 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
1918 | "" | |
1919 | "<insn>\t%0, %N1, %r2") | |
1920 | ||
1921 | (define_insn "*netreg_binop_from_network1" | |
1922 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1923 | (netreg_binop:SI | |
1924 | (match_operand:SI 1 "reg_or_0_operand" "rO") | |
1925 | (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i") | |
1926 | (reg:SI TILEPRO_NETORDER_REG)] | |
1927 | UNSPEC_NETWORK_RECEIVE))) | |
1928 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
1929 | "" | |
1930 | "<insn>\t%0, %r1, %N2") | |
1931 | ||
1932 | (define_insn "*netreg_binop_from_to_network0" | |
1933 | [(unspec_volatile:SI | |
1934 | [(match_operand:SI 0 "netreg_operand" "i") | |
1935 | (netreg_binop:SI | |
1936 | (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i") | |
1937 | (reg:SI TILEPRO_NETORDER_REG)] | |
1938 | UNSPEC_NETWORK_RECEIVE) | |
1939 | (match_operand:SI 2 "reg_or_0_operand" "rO")) | |
1940 | (reg:SI TILEPRO_NETORDER_REG)] | |
1941 | UNSPEC_NETWORK_SEND) | |
1942 | (clobber (reg:SI TILEPRO_NETORDER_REG)) | |
1943 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
1944 | "" | |
1945 | "<insn>\t%N0, %N1, %r2") | |
1946 | ||
1947 | (define_insn "*netreg_binop_from_to_network1" | |
1948 | [(unspec_volatile:SI | |
1949 | [(match_operand:SI 0 "netreg_operand" "i") | |
1950 | (netreg_binop:SI | |
1951 | (match_operand:SI 1 "reg_or_0_operand" "rO") | |
1952 | (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i") | |
1953 | (reg:SI TILEPRO_NETORDER_REG)] | |
1954 | UNSPEC_NETWORK_RECEIVE)) | |
1955 | (reg:SI TILEPRO_NETORDER_REG)] | |
1956 | UNSPEC_NETWORK_SEND) | |
1957 | (clobber (reg:SI TILEPRO_NETORDER_REG)) | |
1958 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
1959 | "" | |
1960 | "<insn>\t%N0, %r1, %N2") | |
1961 | ||
1962 | (define_insn "*netreg_binop_to_network" | |
1963 | [(unspec_volatile:SI | |
1964 | [(match_operand:SI 0 "netreg_operand" "i,i") | |
1965 | (binop_with_imm:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO") | |
1966 | (match_operand:SI 2 "reg_or_cint_operand" "I,rO")) | |
1967 | (reg:SI TILEPRO_NETORDER_REG)] | |
1968 | UNSPEC_NETWORK_SEND) | |
1969 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
1970 | "" | |
1971 | "@ | |
1972 | <insn>i<u>\t%N0, %r1, %2 | |
1973 | <insn><u>\t%N0, %r1, %r2") | |
1974 | ||
1975 | (define_insn "*netreg_binop_from_network" | |
1976 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1977 | (binop_with_imm:SI | |
1978 | (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i") | |
1979 | (reg:SI TILEPRO_NETORDER_REG)] | |
1980 | UNSPEC_NETWORK_RECEIVE) | |
1981 | (match_operand:SI 2 "reg_or_cint_operand" "I,rO"))) | |
1982 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
1983 | "" | |
1984 | "@ | |
1985 | <insn>i<u>\t%0, %N1, %2 | |
1986 | <insn><u>\t%0, %N1, %r2") | |
1987 | ||
1988 | (define_insn "*netreg_binop_from_to_network" | |
1989 | [(unspec_volatile:SI | |
1990 | [(match_operand:SI 0 "netreg_operand" "i,i") | |
1991 | (binop_with_imm:SI | |
1992 | (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i") | |
1993 | (reg:SI TILEPRO_NETORDER_REG)] | |
1994 | UNSPEC_NETWORK_RECEIVE) | |
1995 | (match_operand:SI 2 "reg_or_cint_operand" "I,rO")) | |
1996 | (reg:SI TILEPRO_NETORDER_REG)] | |
1997 | UNSPEC_NETWORK_SEND) | |
1998 | (clobber (reg:SI TILEPRO_NETORDER_REG)) | |
1999 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
2000 | "" | |
2001 | "@ | |
2002 | <insn>i<u>\t%N0, %N1, %2 | |
2003 | <insn><u>\t%N0, %N1, %r2") | |
2004 | ||
2005 | (define_insn "*netreg_unop_to_network" | |
2006 | [(unspec_volatile:SI [(match_operand:SI 0 "netreg_operand" "i") | |
2007 | (unop:SI (match_operand:SI 1 "reg_or_0_operand" "rO")) | |
2008 | (reg:SI TILEPRO_NETORDER_REG)] | |
2009 | UNSPEC_NETWORK_SEND) | |
2010 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
2011 | "" | |
2012 | "<insn>\t%N0, %r1" | |
2013 | [(set_attr "type" "Y0")]) | |
2014 | ||
2015 | (define_insn "*netreg_unop_from_network" | |
2016 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2017 | (unop:SI | |
2018 | (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i") | |
2019 | (reg:SI TILEPRO_NETORDER_REG)] | |
2020 | UNSPEC_NETWORK_RECEIVE))) | |
2021 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
2022 | "" | |
2023 | "<insn>\t%0, %N1" | |
2024 | [(set_attr "type" "Y0")]) | |
2025 | ||
2026 | (define_insn "*netreg_unop_from_to_network" | |
2027 | [(unspec_volatile:SI | |
2028 | [(match_operand:SI 0 "netreg_operand" "i") | |
2029 | (unop:SI | |
2030 | (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i") | |
2031 | (reg:SI TILEPRO_NETORDER_REG)] | |
2032 | UNSPEC_NETWORK_RECEIVE)) | |
2033 | (reg:SI TILEPRO_NETORDER_REG)] | |
2034 | UNSPEC_NETWORK_SEND) | |
2035 | (clobber (reg:SI TILEPRO_NETORDER_REG)) | |
2036 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
2037 | "" | |
2038 | "<insn>\t%N0, %N1" | |
2039 | [(set_attr "type" "Y0")]) | |
2040 | ||
2041 | (define_insn "*netreg_sadh_u_from_network0" | |
2042 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2043 | (unspec:SI | |
2044 | [(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i") | |
2045 | (reg:SI TILEPRO_NETORDER_REG)] | |
2046 | UNSPEC_NETWORK_RECEIVE) | |
2047 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
2048 | UNSPEC_INSN_SADH_U)) | |
2049 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
2050 | "" | |
2051 | "sadh_u\t%0, %N1, %r2" | |
2052 | [(set_attr "type" "X0_2cycle")]) | |
2053 | ||
2054 | (define_insn "*netreg_sadh_u_from_network1" | |
2055 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2056 | (unspec:SI | |
2057 | [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
2058 | (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i") | |
2059 | (reg:SI TILEPRO_NETORDER_REG)] | |
2060 | UNSPEC_NETWORK_RECEIVE)] | |
2061 | UNSPEC_INSN_SADH_U)) | |
2062 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
2063 | "" | |
2064 | "sadh_u\t%0, %r1, %N2" | |
2065 | [(set_attr "type" "X0_2cycle")]) | |
2066 | ||
2067 | (define_insn "*netreg_sadah_u_from_network0" | |
2068 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2069 | (unspec:SI | |
2070 | [(match_operand:SI 1 "reg_or_0_operand" "0") | |
2071 | (unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i") | |
2072 | (reg:SI TILEPRO_NETORDER_REG)] | |
2073 | UNSPEC_NETWORK_RECEIVE) | |
2074 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
2075 | UNSPEC_INSN_SADAH_U)) | |
2076 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
2077 | "" | |
2078 | "sadah_u\t%0, %N2, %r3" | |
2079 | [(set_attr "type" "X0_2cycle")]) | |
2080 | ||
2081 | (define_insn "*netreg_sadah_u_from_network1" | |
2082 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2083 | (unspec:SI | |
2084 | [(match_operand:SI 1 "reg_or_0_operand" "0") | |
2085 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
2086 | (unspec_volatile:SI [(match_operand:SI 3 "netreg_operand" "i") | |
2087 | (reg:SI TILEPRO_NETORDER_REG)] | |
2088 | UNSPEC_NETWORK_RECEIVE)] | |
2089 | UNSPEC_INSN_SADAH_U)) | |
2090 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
2091 | "" | |
2092 | "sadah_u\t%0, %r2, %N3" | |
2093 | [(set_attr "type" "X0_2cycle")]) | |
2094 | ||
2095 | (define_code_iterator mm_combiner [ior xor plus]) | |
2096 | ||
2097 | ;; This doesn't seem to match -- too complex for 'combine'? | |
2098 | ;; | |
2099 | ;; (define_insn "*netreg_mm_to_network" | |
2100 | ;; [(unspec_volatile:SI | |
2101 | ;; [(match_operand:SI 0 "netreg_operand" "i") | |
2102 | ;; (mm_combiner:SI | |
2103 | ;; (and:SI (match_operand:SI 1 "reg_or_0_operand" "rO") | |
2104 | ;; (match_operand:SI 3 "const_int_operand" "n")) | |
2105 | ;; (and:SI (match_operand:SI 2 "reg_or_0_operand" "rO") | |
2106 | ;; (match_operand:SI 4 "const_int_operand" "n")))] | |
2107 | ;; UNSPEC_NETWORK_SEND)] | |
2108 | ;; "tilepro_bitfield_operand_p (INTVAL (operands[3]), NULL, NULL) | |
2109 | ;; && INTVAL (operands[3]) == ~INTVAL (operands[4])" | |
2110 | ;; "mm\t%N0, %r1, %r2, %M3" | |
2111 | ;; [(set_attr "type" "X01")]) | |
2112 | ||
2113 | ;; FIXME: the straight forward versions which do not include the | |
2114 | ;; subreg:QI does not match for some unknown reason. | |
2115 | (define_insn "*netreg_bbs_normal" | |
2116 | [(set (pc) | |
2117 | (if_then_else | |
2118 | (ne (zero_extract:SI | |
2119 | (subreg:QI | |
2120 | (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i") | |
2121 | (reg:SI TILEPRO_NETORDER_REG)] | |
2122 | UNSPEC_NETWORK_RECEIVE) 0) | |
2123 | (const_int 1) | |
2124 | (const_int 0)) | |
2125 | (const_int 0)) | |
2126 | (label_ref (match_operand 0 "" "")) | |
2127 | (pc))) | |
2128 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
2129 | "" | |
2130 | { return tilepro_output_cbranch_with_opcode (insn, operands, "bbs", "bbns", | |
2131 | 1, 1); } | |
2132 | [(set_attr "type" "X1_branch")]) | |
2133 | ||
2134 | (define_insn "*netreg_bbc_normal" | |
2135 | [(set (pc) | |
2136 | (if_then_else | |
2137 | (eq (zero_extract:SI | |
2138 | (subreg:QI | |
2139 | (unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i") | |
2140 | (reg:SI TILEPRO_NETORDER_REG)] | |
2141 | UNSPEC_NETWORK_RECEIVE) 0) | |
2142 | (const_int 1) | |
2143 | (const_int 0)) | |
2144 | (const_int 0)) | |
2145 | (label_ref (match_operand 0 "" "")) | |
2146 | (pc))) | |
2147 | (clobber (reg:SI TILEPRO_NETORDER_REG))] | |
2148 | "" | |
2149 | { return tilepro_output_cbranch_with_opcode (insn, operands, "bbns", "bbns", | |
2150 | 1, 1); } | |
2151 | [(set_attr "type" "X1_branch")]) | |
2152 | ||
2153 | \f | |
2154 | ;; | |
2155 | ;; "__insn" Intrinsics (some expand directly to normal patterns above). | |
2156 | ;; | |
2157 | ||
2158 | (define_insn "insn_addlis" | |
2159 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2160 | (unspec_volatile:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
2161 | (match_operand:SI 2 "s16bit_cint_operand" "i")] | |
2162 | UNSPEC_INSN_ADDLIS))] | |
2163 | "" | |
2164 | "addlis\t%0, %r1, %2" | |
2165 | [(set_attr "type" "X01")]) | |
2166 | ||
2167 | (define_insn "insn_auli" | |
2168 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2169 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
2170 | (match_operand:SI 2 "s16bit_cint_operand" "i")] | |
2171 | UNSPEC_INSN_AULI))] | |
2172 | "" | |
2173 | "auli\t%0, %r1, %2" | |
2174 | [(set_attr "type" "X01")]) | |
2175 | ||
2176 | (define_insn "insn_drain" | |
2177 | [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_DRAIN)] | |
2178 | "" | |
2179 | "drain" | |
2180 | [(set_attr "type" "cannot_bundle")]) | |
2181 | ||
2182 | (define_insn "insn_icoh" | |
2183 | [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] | |
2184 | UNSPEC_INSN_ICOH)] | |
2185 | "" | |
2186 | "icoh\t%r0" | |
2187 | [(set_attr "type" "X1")]) | |
2188 | ||
2189 | ||
2190 | (define_insn "insn_info" | |
2191 | [(unspec_volatile:VOID [(match_operand:SI 0 "s8bit_cint_operand" "i")] | |
2192 | UNSPEC_INSN_INFO)] | |
2193 | "" | |
2194 | "info\t%0") | |
2195 | ||
2196 | (define_insn "insn_infol" | |
2197 | [(unspec_volatile:VOID [(match_operand:SI 0 "s16bit_cint_operand" "i")] | |
2198 | UNSPEC_INSN_INFOL)] | |
2199 | "" | |
2200 | "infol\t%0" | |
2201 | [(set_attr "type" "X01")]) | |
2202 | ||
2203 | ;; loads | |
2204 | ||
2205 | (define_expand "insn_<load>" | |
2206 | [(set (match_operand:SI 0 "register_operand" "") | |
2207 | (sign_extend:SI | |
2208 | (mem:I12MODE (match_operand:SI 1 "address_operand" ""))))] | |
2209 | "") | |
2210 | ||
2211 | (define_expand "insn_<load>_u" | |
2212 | [(set (match_operand:SI 0 "register_operand" "") | |
2213 | (zero_extend:SI | |
2214 | (mem:I12MODE (match_operand:SI 1 "address_operand" ""))))] | |
2215 | "") | |
2216 | ||
2217 | (define_insn "insn_<load>add" | |
2218 | [(set (match_operand:SI 1 "register_operand" "=r") | |
2219 | (plus:SI (match_operand:SI 3 "register_operand" "1") | |
2220 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2221 | (set (match_operand:SI 0 "register_operand" "=r") | |
2222 | (sign_extend:SI (mem:I12MODE (match_dup 3))))] | |
2223 | "" | |
2224 | "<load>add\t%0, %1, %2" | |
2225 | [(set_attr "type" "X1_2cycle")]) | |
2226 | ||
2227 | (define_insn "insn_<load>add_u" | |
2228 | [(set (match_operand:SI 1 "register_operand" "=r") | |
2229 | (plus:SI (match_operand:SI 3 "register_operand" "1") | |
2230 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2231 | (set (match_operand:SI 0 "register_operand" "=r") | |
2232 | (zero_extend:SI (mem:I12MODE (match_dup 3))))] | |
2233 | "" | |
2234 | "<load>add_u\t%0, %1, %2" | |
2235 | [(set_attr "type" "X1_2cycle")]) | |
2236 | ||
2237 | (define_expand "insn_lw" | |
2238 | [(set (match_operand:SI 0 "register_operand" "") | |
2239 | (mem:SI (match_operand:SI 1 "address_operand" "")))] | |
2240 | "") | |
2241 | ||
2242 | (define_insn "insn_lwadd" | |
2243 | [(set (match_operand:SI 1 "register_operand" "=r") | |
2244 | (plus:SI (match_operand:SI 3 "register_operand" "1") | |
2245 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2246 | (set (match_operand:SI 0 "register_operand" "=r") | |
2247 | (mem:SI (match_dup 3)))] | |
2248 | "" | |
2249 | "lwadd\t%0, %1, %2" | |
2250 | [(set_attr "type" "X1_2cycle")]) | |
2251 | ||
2252 | (define_insn "insn_lwadd_na" | |
2253 | [(set (match_operand:SI 1 "register_operand" "=r") | |
2254 | (plus:SI (match_operand:SI 3 "register_operand" "1") | |
2255 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2256 | (set (match_operand:SI 0 "register_operand" "=r") | |
2257 | (mem:SI (and:SI (match_dup 3) (const_int -4))))] | |
2258 | "" | |
2259 | "lwadd_na\t%0, %1, %2" | |
2260 | [(set_attr "type" "X1_2cycle")]) | |
2261 | ||
2262 | (define_insn "insn_lw_na" | |
2263 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2264 | (mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO") | |
2265 | (const_int -4))))] | |
2266 | "" | |
2267 | "lw_na\t%0, %r1" | |
2268 | [(set_attr "type" "X1_2cycle")]) | |
2269 | ||
2270 | ;; L2 hits | |
2271 | ||
2272 | (define_insn "insn_<load>_L2" | |
2273 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2274 | (sign_extend:SI | |
2275 | (unspec:I12MODE | |
2276 | [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))] | |
2277 | UNSPEC_LATENCY_L2)))] | |
2278 | "" | |
2279 | "<load>\t%0, %r1" | |
2280 | [(set_attr "type" "Y2_L2")]) | |
2281 | ||
2282 | (define_insn "insn_<load>_u_L2" | |
2283 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2284 | (zero_extend:SI | |
2285 | (unspec:I12MODE | |
2286 | [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))] | |
2287 | UNSPEC_LATENCY_L2)))] | |
2288 | "" | |
2289 | "<load>_u\t%0, %r1" | |
2290 | [(set_attr "type" "Y2_L2")]) | |
2291 | ||
2292 | (define_insn "insn_<load>add_L2" | |
2293 | [(set (match_operand:SI 1 "register_operand" "=r") | |
2294 | (plus:SI (match_operand:SI 3 "register_operand" "1") | |
2295 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2296 | (set (match_operand:SI 0 "register_operand" "=r") | |
2297 | (sign_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))] | |
2298 | UNSPEC_LATENCY_L2)))] | |
2299 | "" | |
2300 | "<load>add\t%0, %1, %2" | |
2301 | [(set_attr "type" "X1_L2")]) | |
2302 | ||
2303 | (define_insn "insn_<load>add_u_L2" | |
2304 | [(set (match_operand:SI 1 "register_operand" "=r") | |
2305 | (plus:SI (match_operand:SI 3 "register_operand" "1") | |
2306 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2307 | (set (match_operand:SI 0 "register_operand" "=r") | |
2308 | (zero_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))] | |
2309 | UNSPEC_LATENCY_L2)))] | |
2310 | "" | |
2311 | "<load>add_u\t%0, %1, %2" | |
2312 | [(set_attr "type" "X1_L2")]) | |
2313 | ||
2314 | (define_insn "insn_lwadd_L2" | |
2315 | [(set (match_operand:SI 1 "register_operand" "=r") | |
2316 | (plus:SI (match_operand:SI 3 "register_operand" "1") | |
2317 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2318 | (set (match_operand:SI 0 "register_operand" "=r") | |
2319 | (unspec:SI [(mem:SI (match_dup 3))] UNSPEC_LATENCY_L2))] | |
2320 | "" | |
2321 | "lwadd\t%0, %1, %2" | |
2322 | [(set_attr "type" "X1_L2")]) | |
2323 | ||
2324 | (define_insn "insn_lwadd_na_L2" | |
2325 | [(set (match_operand:SI 1 "register_operand" "=r") | |
2326 | (plus:SI (match_operand:SI 3 "register_operand" "1") | |
2327 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2328 | (set (match_operand:SI 0 "register_operand" "=r") | |
2329 | (unspec:SI [(mem:SI (and:SI (match_dup 3) (const_int -4)))] | |
2330 | UNSPEC_LATENCY_L2))] | |
2331 | "" | |
2332 | "lwadd_na\t%0, %1, %2" | |
2333 | [(set_attr "type" "X1_L2")]) | |
2334 | ||
2335 | (define_insn "insn_lw_na_L2" | |
2336 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2337 | (unspec:SI [(mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO") | |
2338 | (const_int -4)))] | |
2339 | UNSPEC_LATENCY_L2))] | |
2340 | "" | |
2341 | "lw_na\t%0, %r1" | |
2342 | [(set_attr "type" "X1_L2")]) | |
2343 | ||
2344 | (define_insn "insn_lw_L2" | |
2345 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2346 | (unspec:SI [(mem:SI (match_operand:SI 1 "address_operand" "rO"))] | |
2347 | UNSPEC_LATENCY_L2))] | |
2348 | "" | |
2349 | "lw\t%0, %r1" | |
2350 | [(set_attr "type" "Y2_L2")]) | |
2351 | ||
2352 | ;; L2 miss | |
2353 | ||
2354 | (define_insn "insn_<load>_miss" | |
2355 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2356 | (sign_extend:SI | |
2357 | (unspec:I12MODE | |
2358 | [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))] | |
2359 | UNSPEC_LATENCY_MISS)))] | |
2360 | "" | |
2361 | "<load>\t%0, %r1" | |
2362 | [(set_attr "type" "Y2_miss")]) | |
2363 | ||
2364 | (define_insn "insn_<load>_u_miss" | |
2365 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2366 | (zero_extend:SI | |
2367 | (unspec:I12MODE | |
2368 | [(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))] | |
2369 | UNSPEC_LATENCY_MISS)))] | |
2370 | "" | |
2371 | "<load>_u\t%0, %r1" | |
2372 | [(set_attr "type" "Y2_miss")]) | |
2373 | ||
2374 | (define_insn "insn_<load>add_miss" | |
2375 | [(set (match_operand:SI 1 "register_operand" "=r") | |
2376 | (plus:SI (match_operand:SI 3 "register_operand" "1") | |
2377 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2378 | (set (match_operand:SI 0 "register_operand" "=r") | |
2379 | (sign_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))] | |
2380 | UNSPEC_LATENCY_MISS)))] | |
2381 | "" | |
2382 | "<load>add\t%0, %1, %2" | |
2383 | [(set_attr "type" "X1_miss")]) | |
2384 | ||
2385 | (define_insn "insn_<load>add_u_miss" | |
2386 | [(set (match_operand:SI 1 "register_operand" "=r") | |
2387 | (plus:SI (match_operand:SI 3 "register_operand" "1") | |
2388 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2389 | (set (match_operand:SI 0 "register_operand" "=r") | |
2390 | (zero_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))] | |
2391 | UNSPEC_LATENCY_MISS)))] | |
2392 | "" | |
2393 | "<load>add_u\t%0, %1, %2" | |
2394 | [(set_attr "type" "X1_miss")]) | |
2395 | ||
2396 | (define_insn "insn_lwadd_miss" | |
2397 | [(set (match_operand:SI 1 "register_operand" "=r") | |
2398 | (plus:SI (match_operand:SI 3 "register_operand" "1") | |
2399 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2400 | (set (match_operand:SI 0 "register_operand" "=r") | |
2401 | (unspec:SI [(mem:SI (match_dup 3))] UNSPEC_LATENCY_MISS))] | |
2402 | "" | |
2403 | "lwadd\t%0, %1, %2" | |
2404 | [(set_attr "type" "X1_miss")]) | |
2405 | ||
2406 | (define_insn "insn_lwadd_na_miss" | |
2407 | [(set (match_operand:SI 1 "register_operand" "=r") | |
2408 | (plus:SI (match_operand:SI 3 "register_operand" "1") | |
2409 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2410 | (set (match_operand:SI 0 "register_operand" "=r") | |
2411 | (unspec:SI [(mem:SI (and:SI (match_dup 3) (const_int -4)))] | |
2412 | UNSPEC_LATENCY_MISS))] | |
2413 | "" | |
2414 | "lwadd_na\t%0, %1, %2" | |
2415 | [(set_attr "type" "X1_miss")]) | |
2416 | ||
2417 | (define_insn "insn_lw_na_miss" | |
2418 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2419 | (unspec:SI [(mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO") | |
2420 | (const_int -4)))] | |
2421 | UNSPEC_LATENCY_MISS))] | |
2422 | "" | |
2423 | "lw_na\t%0, %r1" | |
2424 | [(set_attr "type" "X1_miss")]) | |
2425 | ||
2426 | (define_insn "insn_lw_miss" | |
2427 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2428 | (unspec:SI [(mem:SI (match_operand:SI 1 "address_operand" "rO"))] | |
2429 | UNSPEC_LATENCY_MISS))] | |
2430 | "" | |
2431 | "lw\t%0, %r1" | |
2432 | [(set_attr "type" "Y2_miss")]) | |
2433 | ||
2434 | ;; end loads | |
2435 | ||
2436 | (define_insn "insn_mfspr" | |
2437 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2438 | (unspec_volatile:SI [(match_operand:SI 1 "u15bit_cint_operand" "i")] | |
2439 | UNSPEC_INSN_MFSPR)) | |
2440 | (clobber (mem:BLK (const_int 0)))] | |
2441 | "" | |
2442 | "mfspr\t%0, %1" | |
2443 | [(set_attr "type" "X1")]) | |
2444 | ||
2445 | (define_insn "*mm" | |
2446 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2447 | (mm_combiner:SI | |
2448 | (and:SI (match_operand:SI 1 "reg_or_0_operand" "rO") | |
2449 | (match_operand:SI 3 "const_int_operand" "n")) | |
2450 | (and:SI (match_operand:SI 2 "reg_or_0_operand" "rO") | |
2451 | (match_operand:SI 4 "const_int_operand" "n"))))] | |
2452 | "tilepro_bitfield_operand_p (INTVAL (operands[3]), NULL, NULL) | |
2453 | && INTVAL (operands[3]) == ~INTVAL (operands[4])" | |
2454 | "mm\t%0, %r1, %r2, %M3" | |
2455 | [(set_attr "type" "X01")]) | |
2456 | ||
2457 | (define_expand "insn_mm" | |
2458 | [(set (match_operand:SI 0 "register_operand" "") | |
2459 | (ior:SI | |
2460 | (and:SI (match_operand:SI 1 "reg_or_cint_operand" "") | |
2461 | (match_operand:SI 3 "u5bit_cint_operand" "")) | |
2462 | (and:SI (match_operand:SI 2 "reg_or_cint_operand" "") | |
2463 | (match_operand:SI 4 "u5bit_cint_operand" ""))))] | |
2464 | "" | |
2465 | { | |
2466 | int first, last, i; | |
2467 | HOST_WIDE_INT mask; | |
2468 | ||
2469 | first = INTVAL (operands[3]) & 31; | |
2470 | last = INTVAL (operands[4]) & 31; | |
2471 | ||
2472 | if (((last + 1) & 31) == first) | |
2473 | { | |
2474 | /* Handle pathological case of a mask that includes only the | |
2475 | first operand. The reordering code below can't handle this. */ | |
2476 | emit_move_insn (operands[0], operands[1]); | |
2477 | DONE; | |
2478 | } | |
2479 | ||
2480 | /* Canonicalize order by putting constant second, if any. */ | |
2481 | if (CONST_INT_P (operands[1])) | |
2482 | { | |
2483 | int tmp_first; | |
2484 | ||
2485 | rtx tmp = operands[1]; | |
2486 | operands[1] = operands[2]; | |
2487 | operands[2] = tmp; | |
2488 | ||
2489 | /* Invert the bit range. */ | |
2490 | tmp_first = first; | |
2491 | first = (last + 1) & 31; | |
2492 | last = (tmp_first - 1) & 31; | |
2493 | } | |
2494 | ||
2495 | /* Convert the first/last bit range into a bit mask. */ | |
2496 | mask = 0; | |
2497 | ||
2498 | for (i = first; ; i = (i + 1) & 31) | |
2499 | { | |
2500 | mask |= ((HOST_WIDE_INT)1) << i; | |
2501 | if (i == last) | |
2502 | break; | |
2503 | } | |
2504 | ||
2505 | mask = trunc_int_for_mode (mask, SImode); | |
2506 | ||
2507 | operands[1] = force_reg (SImode, operands[1]); | |
2508 | operands[3] = GEN_INT (mask); | |
2509 | operands[4] = GEN_INT (~mask); | |
2510 | ||
2511 | if (CONST_INT_P (operands[2])) | |
2512 | { | |
2513 | HOST_WIDE_INT inserted_bits = INTVAL (operands[2]) & ~mask; | |
2514 | ||
2515 | if (inserted_bits == 0) | |
2516 | { | |
2517 | /* All inserted bits are zero. Use a bitwise AND. */ | |
2518 | emit_insn (gen_andsi3 (operands[0], operands[1], operands[3])); | |
2519 | DONE; | |
2520 | } | |
2521 | else if (inserted_bits == ~mask) | |
2522 | { | |
2523 | /* All inserted bits are ones. Use a bitwise IOR if we can. */ | |
2524 | if (satisfies_constraint_I (operands[4])) | |
2525 | { | |
2526 | emit_insn (gen_iorsi3 (operands[0], operands[1], operands[4])); | |
2527 | DONE; | |
2528 | } | |
2529 | ||
2530 | /* Canonicalize to inserting -1 when setting all masked bits | |
2531 | to 1, to facilitate CSE. */ | |
2532 | inserted_bits = -1; | |
2533 | } | |
2534 | ||
2535 | /* Sign extend the inserted bits to make them easier to materialize | |
2536 | in a register, but only if the inserted bits (~mask) do not already | |
2537 | include the high bits. */ | |
2538 | if ((~mask & 0x80000000) == 0) | |
2539 | { | |
2540 | int shift = sizeof (HOST_WIDE_INT) * 8 - first; | |
2541 | inserted_bits = (inserted_bits << shift) >> shift; | |
2542 | } | |
2543 | ||
2544 | operands[2] = GEN_INT (inserted_bits); | |
2545 | } | |
2546 | ||
2547 | operands[2] = force_reg (SImode, operands[2]); | |
2548 | }) | |
2549 | ||
2550 | (define_insn "insn_movelis" | |
2551 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2552 | (unspec_volatile:SI [(match_operand:SI 1 "s16bit_cint_operand" "i")] | |
2553 | UNSPEC_INSN_MOVELIS))] | |
2554 | "" | |
2555 | "movelis\t%0, %1" | |
2556 | [(set_attr "type" "X01")]) | |
2557 | ||
2558 | (define_insn "insn_mtspr" | |
2559 | [(unspec_volatile:SI [(match_operand:SI 0 "u15bit_cint_operand" "i") | |
2560 | (match_operand:SI 1 "reg_or_0_operand" "rO")] | |
2561 | UNSPEC_INSN_MTSPR) | |
2562 | (clobber (mem:BLK (const_int 0)))] | |
2563 | "" | |
2564 | "mtspr\t%0, %r1" | |
2565 | [(set_attr "type" "X1")]) | |
2566 | ||
2567 | (define_expand "insn_prefetch" | |
2568 | [(prefetch (match_operand:SI 0 "address_operand" "") | |
2569 | (const_int 0) | |
2570 | (const_int 2))]) | |
2571 | ||
2572 | (define_expand "insn_prefetch_L1" | |
2573 | [(use (match_operand:SI 0 "address_operand" ""))] | |
2574 | "" | |
2575 | { | |
2576 | /* Generate a volatile byte load to a dummy register. */ | |
2577 | rtx mem = gen_rtx_MEM (QImode, operands[0]); | |
2578 | MEM_VOLATILE_P (mem) = 1; | |
2579 | ||
2580 | emit_insn (gen_zero_extendqisi2 (gen_reg_rtx (SImode), mem)); | |
2581 | DONE; | |
2582 | }) | |
2583 | ||
2584 | (define_expand "insn_s1a" | |
2585 | [(set (match_operand:SI 0 "register_operand" "") | |
2586 | (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "") | |
2587 | (const_int 2)) | |
2588 | (match_operand:SI 2 "reg_or_0_operand" "")))] | |
2589 | "") | |
2590 | ||
2591 | (define_expand "insn_s2a" | |
2592 | [(set (match_operand:SI 0 "register_operand" "") | |
2593 | (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "") | |
2594 | (const_int 4)) | |
2595 | (match_operand:SI 2 "reg_or_0_operand" "")))] | |
2596 | "") | |
2597 | ||
2598 | (define_expand "insn_s3a" | |
2599 | [(set (match_operand:SI 0 "register_operand" "") | |
2600 | (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "") | |
2601 | (const_int 8)) | |
2602 | (match_operand:SI 2 "reg_or_0_operand" "")))] | |
2603 | "") | |
2604 | ||
2605 | (define_expand "insn_<store>" | |
2606 | [(set (mem:I12MODE (match_operand:SI 0 "address_operand" "")) | |
2607 | (match_operand:SI 1 "reg_or_0_operand" ""))] | |
2608 | "" | |
2609 | { | |
2610 | operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], SImode, 0); | |
2611 | }) | |
2612 | ||
2613 | (define_expand "insn_sw" | |
2614 | [(set (mem:SI (match_operand:SI 0 "address_operand" "")) | |
2615 | (match_operand:SI 1 "reg_or_0_operand" ""))] | |
2616 | "") | |
2617 | ||
2618 | (define_expand "insn_<store>add" | |
2619 | [(parallel | |
2620 | [(set (match_operand:SI 0 "register_operand" "") | |
2621 | (plus:SI (match_operand:SI 3 "register_operand" "") | |
2622 | (match_operand:SI 2 "s8bit_cint_operand" ""))) | |
2623 | (set (mem:I12MODE (match_dup 3)) | |
2624 | (match_operand:SI 1 "reg_or_0_operand" ""))])] | |
2625 | "" | |
2626 | { | |
2627 | operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], SImode, 0); | |
2628 | }) | |
2629 | ||
2630 | (define_insn "*insn_<store>add" | |
2631 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2632 | (plus:SI (match_operand:SI 3 "register_operand" "0") | |
2633 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2634 | (set (mem:I12MODE (match_dup 3)) | |
2635 | (match_operand:I12MODE 1 "reg_or_0_operand" "rO"))] | |
2636 | "" | |
2637 | "<store>add\t%0, %r1, %2" | |
2638 | [(set_attr "type" "X1")]) | |
2639 | ||
2640 | (define_insn "insn_swadd" | |
2641 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2642 | (plus:SI (match_operand:SI 3 "register_operand" "0") | |
2643 | (match_operand:SI 2 "s8bit_cint_operand" "i"))) | |
2644 | (set (mem:SI (match_dup 3)) | |
2645 | (match_operand:SI 1 "reg_or_0_operand" "rO"))] | |
2646 | "" | |
2647 | "swadd\t%0, %r1, %2" | |
2648 | [(set_attr "type" "X1")]) | |
2649 | ||
2650 | (define_insn "insn_wh64" | |
2651 | [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] | |
2652 | UNSPEC_INSN_WH64) | |
2653 | (clobber (mem:BLK (const_int 0)))] | |
2654 | "" | |
2655 | "wh64\t%r0" | |
2656 | [(set_attr "type" "X1")]) | |
2657 | ||
2658 | (define_insn "insn_tns" | |
2659 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2660 | (mem:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))) | |
2661 | (set (mem:SI (match_dup 1)) (const_int 1))] | |
2662 | "" | |
2663 | "tns\t%0, %1" | |
2664 | [(set_attr "type" "X1")]) | |
2665 | ||
2666 | ;; insn_addb | |
2667 | ;; insn_addib | |
2668 | ;; insn_maxb_u | |
2669 | ;; insn_maxib_u | |
2670 | ;; insn_minb_u | |
2671 | ;; insn_minib_u | |
2672 | ;; insn_seqb | |
2673 | ;; insn_seqib | |
2674 | ;; insn_sltb | |
2675 | ;; insn_sltib | |
2676 | ;; insn_sltb_u | |
2677 | ;; insn_sltib_u | |
2678 | (define_insn "<optab>v4qi3" | |
2679 | [(set (match_operand:V4QI 0 "register_operand" "=r,r") | |
2680 | (v1op_immed:V4QI | |
2681 | (match_operand:V4QI 1 "reg_or_0_operand" "<comm>rO,rO") | |
2682 | (match_operand:V4QI 2 "reg_or_v4s8bit_operand" "W,rO")))] | |
2683 | "" | |
2684 | "@ | |
2685 | <insn>ib<u>\t%0, %r1, %j2 | |
2686 | <insn>b<u>\t%0, %r1, %r2" | |
2687 | [(set_attr "type" "X01,X01")]) | |
2688 | ||
2689 | (define_expand "insn_<insn>b<u>" | |
2690 | [(set (match_operand:SI 0 "register_operand" "") | |
2691 | (v1op_immed:V4QI | |
2692 | (match_operand:SI 1 "reg_or_0_operand" "") | |
2693 | (match_operand:SI 2 "reg_or_0_operand" "")))] | |
2694 | "" | |
2695 | { | |
2696 | tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0], | |
2697 | V4QImode, operands[1], operands[2], true); | |
2698 | DONE; | |
2699 | }) | |
2700 | ||
2701 | (define_expand "insn_<insn>ib<u>" | |
2702 | [(set (match_operand:SI 0 "register_operand" "") | |
2703 | (v1op_immed:V4QI | |
2704 | (match_operand:SI 1 "reg_or_0_operand" "") | |
2705 | (match_operand:SI 2 "s8bit_cint_operand" "")))] | |
2706 | "" | |
2707 | { | |
2708 | /* Tile out immediate and expand to general case. */ | |
2709 | rtx n = tilepro_simd_int (operands[2], QImode); | |
2710 | tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0], | |
2711 | V4QImode, operands[1], n, true); | |
2712 | DONE; | |
2713 | }) | |
2714 | ||
2715 | ;; insn_shlb | |
2716 | ;; insn_shlib | |
2717 | ;; insn_shrb | |
2718 | ;; insn_shrib | |
2719 | ;; insn_srab | |
2720 | ;; insn_sraib | |
2721 | (define_insn "<optab>v4qi3" | |
2722 | [(set (match_operand:V4QI 0 "register_operand" "=r,r") | |
2723 | (any_shift:V4QI | |
2724 | (match_operand:V4QI 1 "reg_or_0_operand" "rO,rO") | |
2725 | (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))] | |
2726 | "" | |
2727 | "@ | |
2728 | <insn>ib<u>\t%0, %r1, %2 | |
2729 | <insn>b<u>\t%0, %r1, %r2" | |
2730 | [(set_attr "type" "X01,X01")]) | |
2731 | ||
2732 | (define_expand "insn_<insn>b<u>" | |
2733 | [(set (match_operand:SI 0 "register_operand" "") | |
2734 | (any_shift:V4QI | |
2735 | (match_operand:SI 1 "reg_or_0_operand" "") | |
2736 | (match_operand:SI 2 "reg_or_u5bit_operand" "")))] | |
2737 | "" | |
2738 | { | |
2739 | tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0], | |
2740 | V4QImode, operands[1], operands[2], false); | |
2741 | DONE; | |
2742 | }) | |
2743 | ||
2744 | ;; insn_addh | |
2745 | ;; insn_addih | |
2746 | ;; insn_maxh | |
2747 | ;; insn_maxih | |
2748 | ;; insn_minh | |
2749 | ;; insn_minih | |
2750 | ;; insn_seqh | |
2751 | ;; insn_seqih | |
2752 | ;; insn_slth | |
2753 | ;; insn_sltih | |
2754 | ;; insn_slth_u | |
2755 | ;; insn_sltih_u | |
2756 | (define_insn "<optab>v2hi3" | |
2757 | [(set (match_operand:V2HI 0 "register_operand" "=r,r") | |
2758 | (v2op_immed:V2HI | |
2759 | (match_operand:V2HI 1 "reg_or_0_operand" "<comm>rO,rO") | |
2760 | (match_operand:V2HI 2 "reg_or_v2s8bit_operand" "Y,rO")))] | |
2761 | "" | |
2762 | "@ | |
2763 | <insn>ih<u>\t%0, %r1, %j2 | |
2764 | <insn>h<u>\t%0, %r1, %r2" | |
2765 | [(set_attr "type" "X01,X01")]) | |
2766 | ||
2767 | (define_expand "insn_<insn>h<u>" | |
2768 | [(set (match_operand:SI 0 "register_operand" "") | |
2769 | (v2op_immed:V2HI | |
2770 | (match_operand:SI 1 "reg_or_0_operand" "") | |
2771 | (match_operand:SI 2 "reg_or_0_operand" "")))] | |
2772 | "" | |
2773 | { | |
2774 | tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0], | |
2775 | V2HImode, operands[1], operands[2], true); | |
2776 | DONE; | |
2777 | }) | |
2778 | ||
2779 | (define_expand "insn_<insn>ih<u>" | |
2780 | [(set (match_operand:SI 0 "register_operand" "") | |
2781 | (v2op_immed:V2HI | |
2782 | (match_operand:SI 1 "reg_or_0_operand" "") | |
2783 | (match_operand:SI 2 "s8bit_cint_operand" "")))] | |
2784 | "" | |
2785 | { | |
2786 | /* Tile out immediate and expand to general case. */ | |
2787 | rtx n = tilepro_simd_int (operands[2], HImode); | |
2788 | tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0], | |
2789 | V2HImode, operands[1], n, true); | |
2790 | DONE; | |
2791 | }) | |
2792 | ||
2793 | ;; insn_shlh | |
2794 | ;; insn_shlih | |
2795 | ;; insn_shrh | |
2796 | ;; insn_shrih | |
2797 | ;; insn_srah | |
2798 | ;; insn_sraih | |
2799 | (define_insn "<optab>v2hi3" | |
2800 | [(set (match_operand:V2HI 0 "register_operand" "=r,r") | |
2801 | (any_shift:V2HI | |
2802 | (match_operand:V2HI 1 "reg_or_0_operand" "rO,rO") | |
2803 | (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))] | |
2804 | "" | |
2805 | "@ | |
2806 | <insn>ih<u>\t%0, %r1, %2 | |
2807 | <insn>h<u>\t%0, %r1, %r2" | |
2808 | [(set_attr "type" "X01,X01")]) | |
2809 | ||
2810 | (define_expand "insn_<insn>h<u>" | |
2811 | [(set (match_operand:SI 0 "register_operand" "") | |
2812 | (any_shift:V2HI | |
2813 | (match_operand:SI 1 "reg_or_0_operand" "") | |
2814 | (match_operand:SI 2 "reg_or_0_operand" "")))] | |
2815 | "" | |
2816 | { | |
2817 | tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0], | |
2818 | V2HImode, operands[1], operands[2], false); | |
2819 | DONE; | |
2820 | }) | |
2821 | ||
2822 | ;; insn_addbs_u | |
2823 | ;; insn_subbs_u | |
2824 | ;; insn_subb | |
2825 | ;; insn_slteb | |
2826 | ;; insn_slteb_u | |
2827 | ;; insn_sneb | |
2828 | (define_insn "<optab>v4qi3" | |
2829 | [(set (match_operand:V4QI 0 "register_operand" "=r") | |
2830 | (v1op:V4QI | |
2831 | (match_operand:V4QI 1 "reg_or_0_operand" "<comm>rO") | |
2832 | (match_operand:V4QI 2 "reg_or_0_operand" "rO")))] | |
2833 | "" | |
2834 | "<insn>b<u>\t%0, %r1, %r2" | |
2835 | [(set_attr "type" "X01")]) | |
2836 | ||
2837 | (define_expand "insn_<insn>b<u>" | |
2838 | [(set (match_operand:SI 0 "register_operand" "") | |
2839 | (v1op:V4QI | |
2840 | (match_operand:SI 1 "reg_or_0_operand" "") | |
2841 | (match_operand:SI 2 "reg_or_0_operand" "")))] | |
2842 | "" | |
2843 | { | |
2844 | tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0], | |
2845 | V4QImode, operands[1], operands[2], true); | |
2846 | DONE; | |
2847 | }) | |
2848 | ||
2849 | ;; insn_addhs | |
2850 | ;; insn_subhs | |
2851 | ;; insn_subh | |
2852 | ;; insn_slteh | |
2853 | ;; insn_slteh_u | |
2854 | ;; insn_sneh | |
2855 | (define_insn "<optab>v2hi3" | |
2856 | [(set (match_operand:V2HI 0 "register_operand" "=r") | |
2857 | (v2op:V2HI | |
2858 | (match_operand:V2HI 1 "reg_or_0_operand" "<comm>rO") | |
2859 | (match_operand:V2HI 2 "reg_or_0_operand" "rO")))] | |
2860 | "" | |
2861 | "<insn>h<u>\t%0, %r1, %r2" | |
2862 | [(set_attr "type" "X01")]) | |
2863 | ||
2864 | (define_expand "insn_<insn>h<u>" | |
2865 | [(set (match_operand:SI 0 "register_operand" "") | |
2866 | (v2op:V2HI | |
2867 | (match_operand:SI 1 "reg_or_0_operand" "") | |
2868 | (match_operand:SI 2 "reg_or_0_operand" "")))] | |
2869 | "" | |
2870 | { | |
2871 | tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0], | |
2872 | V2HImode, operands[1], operands[2], true); | |
2873 | DONE; | |
2874 | }) | |
2875 | ||
2876 | ;; insn_inthb | |
2877 | ||
2878 | ;; Byte ordering of these vectors is endian dependent. We concat | |
2879 | ;; right-to-left for little endian. We concat and interleave in the | |
2880 | ;; opposite way gcc's vector patterns work, so we need to reverse the | |
2881 | ;; order of source operands. | |
2882 | ||
2883 | ;; {B3,B2,B1,B0} {A3,A2,A1,A0} | |
2884 | ;; => {A3,A2,A1,A0,B3,B2,B1,B0} | |
2885 | ;; => {A3,B3,A2,B2} | |
2886 | (define_insn "vec_interleave_highv4qi" | |
2887 | [(set (match_operand:V4QI 0 "register_operand" "=r") | |
2888 | (vec_select:V4QI | |
2889 | (vec_concat:V8QI (match_operand:V4QI 1 "reg_or_0_operand" "rO") | |
2890 | (match_operand:V4QI 2 "reg_or_0_operand" "rO")) | |
2891 | (parallel [(const_int 2) (const_int 6) | |
2892 | (const_int 3) (const_int 7)])))] | |
2893 | "" | |
2894 | "inthb\t%0, %r2, %r1" | |
2895 | [(set_attr "type" "X01")]) | |
2896 | ||
2897 | (define_expand "insn_inthb" | |
2898 | [(match_operand:SI 0 "register_operand" "") | |
2899 | (match_operand:SI 1 "reg_or_0_operand" "") | |
2900 | (match_operand:SI 2 "reg_or_0_operand" "")] | |
2901 | "" | |
2902 | { | |
2903 | /* Our instruction interleaves opposite of the way vec_interleave | |
2904 | works, so we need to reverse the source operands. */ | |
2905 | tilepro_expand_builtin_vector_binop (gen_vec_interleave_highv4qi, V4QImode, | |
2906 | operands[0], V4QImode, operands[2], | |
2907 | operands[1], true); | |
2908 | DONE; | |
2909 | }) | |
2910 | ||
2911 | ;; insn_intlb | |
2912 | ;; {B3,B2,B1,B0} {A3,A2,A1,A0} | |
2913 | ;; => {A3,A2,A1,A0,B3,B2,B1,B0} | |
2914 | ;; => {A1,B1,A0,B0} | |
2915 | (define_insn "vec_interleave_lowv4qi" | |
2916 | [(set (match_operand:V4QI 0 "register_operand" "=r") | |
2917 | (vec_select:V4QI | |
2918 | (vec_concat:V8QI (match_operand:V4QI 1 "reg_or_0_operand" "rO") | |
2919 | (match_operand:V4QI 2 "reg_or_0_operand" "rO")) | |
2920 | (parallel [(const_int 0) (const_int 4) | |
2921 | (const_int 1) (const_int 5)])))] | |
2922 | "" | |
2923 | "intlb\t%0, %r2, %r1" | |
2924 | [(set_attr "type" "X01")]) | |
2925 | ||
2926 | (define_expand "insn_intlb" | |
2927 | [(match_operand:SI 0 "register_operand" "") | |
2928 | (match_operand:SI 1 "reg_or_0_operand" "") | |
2929 | (match_operand:SI 2 "reg_or_0_operand" "")] | |
2930 | "" | |
2931 | { | |
2932 | /* Our instruction interleaves opposite of the way vec_interleave | |
2933 | works, so we need to reverse the source operands. */ | |
2934 | tilepro_expand_builtin_vector_binop (gen_vec_interleave_lowv4qi, V4QImode, | |
2935 | operands[0], V4QImode, operands[2], | |
2936 | operands[1], true); | |
2937 | DONE; | |
2938 | }) | |
2939 | ||
2940 | ;; insn_inthh | |
2941 | ;; {B1,B0} {A1,A0} | |
2942 | ;; => {A1,A0,B1,B0} | |
2943 | ;; => {A1,B1} | |
2944 | (define_insn "vec_interleave_highv2hi" | |
2945 | [(set (match_operand:V2HI 0 "register_operand" "=r") | |
2946 | (vec_select:V2HI | |
2947 | (vec_concat:V4HI (match_operand:V2HI 1 "reg_or_0_operand" "rO") | |
2948 | (match_operand:V2HI 2 "reg_or_0_operand" "rO")) | |
2949 | (parallel [(const_int 1) (const_int 3)])))] | |
2950 | "" | |
2951 | "inthh\t%0, %r2, %r1" | |
2952 | [(set_attr "type" "X01")]) | |
2953 | ||
2954 | (define_expand "insn_inthh" | |
2955 | [(match_operand:SI 0 "register_operand" "") | |
2956 | (match_operand:SI 1 "reg_or_0_operand" "") | |
2957 | (match_operand:SI 2 "reg_or_0_operand" "")] | |
2958 | "" | |
2959 | { | |
2960 | /* Our instruction interleaves opposite of the way vec_interleave | |
2961 | works, so we need to reverse the source operands. */ | |
2962 | tilepro_expand_builtin_vector_binop (gen_vec_interleave_highv2hi, V2HImode, | |
2963 | operands[0], V2HImode, operands[2], | |
2964 | operands[1], true); | |
2965 | DONE; | |
2966 | }) | |
2967 | ||
2968 | ;; insn_intlh | |
2969 | ;; {B1,B0} {A1,A0} | |
2970 | ;; => {A1,A0,B1,B0} | |
2971 | ;; => {A0,B0} | |
2972 | (define_insn "vec_interleave_lowv2hi" | |
2973 | [(set (match_operand:V2HI 0 "register_operand" "=r") | |
2974 | (vec_select:V2HI | |
2975 | (vec_concat:V4HI (match_operand:V2HI 1 "reg_or_0_operand" "rO") | |
2976 | (match_operand:V2HI 2 "reg_or_0_operand" "rO")) | |
2977 | (parallel [(const_int 0) (const_int 2)])))] | |
2978 | "" | |
2979 | "intlh\t%0, %r2, %r1" | |
2980 | [(set_attr "type" "X01")]) | |
2981 | ||
2982 | (define_expand "insn_intlh" | |
2983 | [(match_operand:SI 0 "register_operand" "") | |
2984 | (match_operand:SI 1 "reg_or_0_operand" "") | |
2985 | (match_operand:SI 2 "reg_or_0_operand" "")] | |
2986 | "" | |
2987 | { | |
2988 | /* Our instruction interleaves opposite of the way vec_interleave | |
2989 | works, so we need to reverse the source operands. */ | |
2990 | tilepro_expand_builtin_vector_binop (gen_vec_interleave_lowv2hi, V2HImode, | |
2991 | operands[0], V2HImode, operands[2], | |
2992 | operands[1], true); | |
2993 | DONE; | |
2994 | }) | |
2995 | ||
2996 | ;; insn_packbs_u | |
2997 | ;; insn_packlb | |
2998 | ;; {B1,B0} {A1,A0} | |
2999 | ;; => {A1,A0,B1,B0} | |
3000 | (define_insn "vec_pack_<pack_optab>_v2hi" | |
3001 | [(set (match_operand:V4QI 0 "register_operand" "=r") | |
3002 | (vec_concat:V4QI | |
3003 | (v2pack:V2QI (match_operand:V2HI 1 "reg_or_0_operand" "rO")) | |
3004 | (v2pack:V2QI (match_operand:V2HI 2 "reg_or_0_operand" "rO"))))] | |
3005 | "" | |
3006 | "<pack_insn>b<pack_u>\t%0, %r2, %r1" | |
3007 | [(set_attr "type" "X01")]) | |
3008 | ||
3009 | (define_expand "insn_<pack_insn>b<pack_u>" | |
3010 | [(set (match_operand:SI 0 "register_operand" "") | |
3011 | (vec_concat:V4QI | |
3012 | (v2pack:V2QI (match_operand:SI 1 "reg_or_0_operand" "")) | |
3013 | (v2pack:V2QI (match_operand:SI 2 "reg_or_0_operand" ""))))] | |
3014 | "" | |
3015 | { | |
3016 | /* Our instruction concats opposite of the way vec_pack works, so we | |
3017 | need to reverse the source operands. */ | |
3018 | tilepro_expand_builtin_vector_binop (gen_vec_pack_<pack_optab>_v2hi, | |
3019 | V4QImode, operands[0], | |
3020 | V2HImode, operands[2], operands[1], true); | |
3021 | DONE; | |
3022 | }) | |
3023 | ||
3024 | ;; insn_packhb | |
3025 | ;; {B1,B0} {A1,A0} | |
3026 | ;; => {A1,A0,B1,B0} | |
3027 | (define_insn "vec_pack_hipart_v2hi" | |
3028 | [(set (match_operand:V4QI 0 "register_operand" "=r") | |
3029 | (vec_concat:V4QI | |
3030 | (truncate:V2QI | |
3031 | (ashiftrt:V2HI (match_operand:V2HI 1 "reg_or_0_operand" "rO") | |
3032 | (const_int 8))) | |
3033 | (truncate:V2QI | |
3034 | (ashiftrt:V2HI (match_operand:V2HI 2 "reg_or_0_operand" "rO") | |
3035 | (const_int 8)))))] | |
3036 | "" | |
3037 | "packhb\t%0, %r2, %r1" | |
3038 | [(set_attr "type" "X01")]) | |
3039 | ||
3040 | (define_expand "insn_packhb" | |
3041 | [(set (match_operand:SI 0 "register_operand" "") | |
3042 | (vec_concat:V4QI | |
3043 | (truncate:V2QI | |
3044 | (ashiftrt:V2HI (match_operand:SI 2 "reg_or_0_operand" "") | |
3045 | (const_int 8))) | |
3046 | (truncate:V2QI | |
3047 | (ashiftrt:V2HI (match_operand:SI 1 "reg_or_0_operand" "") | |
3048 | (const_int 8)))))] | |
3049 | "" | |
3050 | { | |
3051 | /* Our instruction concats opposite of the way vec_pack works, so we | |
3052 | need to reverse the source operands. */ | |
3053 | tilepro_expand_builtin_vector_binop (gen_vec_pack_hipart_v2hi, | |
3054 | V4QImode, operands[0], | |
3055 | V2HImode, operands[2], operands[1], true); | |
3056 | DONE; | |
3057 | }) | |
3058 | ||
3059 | ;; insn_packhs | |
3060 | ;; {B0} {A0} | |
3061 | ;; => {A0,B0} | |
3062 | (define_insn "vec_pack_ssat_si" | |
3063 | [(set (match_operand:V2HI 0 "register_operand" "=r") | |
3064 | (vec_concat:V2HI | |
3065 | (ss_truncate:HI (match_operand:SI 1 "reg_or_0_operand" "rO")) | |
3066 | (ss_truncate:HI (match_operand:SI 2 "reg_or_0_operand" "rO"))))] | |
3067 | "" | |
3068 | "packhs\t%0, %r2, %r1" | |
3069 | [(set_attr "type" "X01")]) | |
3070 | ||
3071 | (define_expand "insn_packhs" | |
3072 | [(set (match_operand:SI 0 "register_operand" "") | |
3073 | (vec_concat:V2HI | |
3074 | (ss_truncate:HI (match_operand:SI 2 "reg_or_0_operand" "")) | |
3075 | (ss_truncate:HI (match_operand:SI 1 "reg_or_0_operand" ""))))] | |
3076 | "" | |
3077 | { | |
3078 | /* Our instruction concats opposite of the way vec_pack works, so we | |
3079 | need to reverse the source operands. */ | |
3080 | tilepro_expand_builtin_vector_binop (gen_vec_pack_ssat_si, | |
3081 | V2HImode, operands[0], | |
3082 | SImode, operands[2], operands[1], true); | |
3083 | DONE; | |
3084 | }) | |
3085 | ||
3086 | ;; Rest of the intrinsics | |
3087 | (define_insn "insn_adiffb_u" | |
3088 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3089 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3090 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3091 | UNSPEC_INSN_ADIFFB_U))] | |
3092 | "" | |
3093 | "adiffb_u\t%0, %r1, %r2" | |
3094 | [(set_attr "type" "X0_2cycle")]) | |
3095 | ||
3096 | (define_insn "insn_adiffh" | |
3097 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3098 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3099 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3100 | UNSPEC_INSN_ADIFFH))] | |
3101 | "" | |
3102 | "adiffh\t%0, %r1, %r2" | |
3103 | [(set_attr "type" "X0_2cycle")]) | |
3104 | ||
3105 | (define_insn "insn_avgb_u" | |
3106 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3107 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3108 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3109 | UNSPEC_INSN_AVGB_U))] | |
3110 | "" | |
3111 | "avgb_u\t%0, %r1, %r2" | |
3112 | [(set_attr "type" "X0")]) | |
3113 | ||
3114 | (define_insn "insn_avgh" | |
3115 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3116 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3117 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3118 | UNSPEC_INSN_AVGH))] | |
3119 | "" | |
3120 | "avgh\t%0, %r1, %r2" | |
3121 | [(set_attr "type" "X0")]) | |
3122 | ||
3123 | (define_insn "insn_bitx" | |
3124 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3125 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")] | |
3126 | UNSPEC_INSN_BITX))] | |
3127 | "" | |
3128 | "bitx\t%0, %r1" | |
3129 | [(set_attr "type" "Y0")]) | |
3130 | ||
3131 | (define_insn "insn_crc32_32" | |
3132 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3133 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3134 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3135 | UNSPEC_INSN_CRC32_32))] | |
3136 | "" | |
3137 | "crc32_32\t%0, %r1, %r2" | |
3138 | [(set_attr "type" "X0")]) | |
3139 | ||
3140 | (define_insn "insn_crc32_8" | |
3141 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3142 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3143 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3144 | UNSPEC_INSN_CRC32_8))] | |
3145 | "" | |
3146 | "crc32_8\t%0, %r1, %r2" | |
3147 | [(set_attr "type" "X0")]) | |
3148 | ||
3149 | (define_insn "insn_dtlbpr" | |
3150 | [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] | |
3151 | UNSPEC_INSN_DTLBPR)] | |
3152 | "" | |
3153 | "dtlbpr\t%r0" | |
3154 | [(set_attr "type" "X1")]) | |
3155 | ||
3156 | (define_insn "insn_dword_align" | |
3157 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3158 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3159 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3160 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3161 | UNSPEC_INSN_DWORD_ALIGN))] | |
3162 | "" | |
3163 | "dword_align\t%0, %r2, %r3" | |
3164 | [(set_attr "type" "X0")]) | |
3165 | ||
3166 | (define_insn "insn_finv" | |
3167 | [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] | |
3168 | UNSPEC_INSN_FINV)] | |
3169 | "" | |
3170 | "finv\t%r0" | |
3171 | [(set_attr "type" "X1")]) | |
3172 | ||
3173 | (define_insn "insn_flush" | |
3174 | [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] | |
3175 | UNSPEC_INSN_FLUSH)] | |
3176 | "" | |
3177 | "flush\t%r0" | |
3178 | [(set_attr "type" "X1")]) | |
3179 | ||
3180 | (define_insn "insn_fnop" | |
3181 | [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FNOP)] | |
3182 | "" | |
3183 | "fnop") | |
3184 | ||
3185 | (define_insn "insn_ill" | |
3186 | [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_ILL)] | |
3187 | "" | |
3188 | "ill" | |
3189 | [(set_attr "type" "cannot_bundle")]) | |
3190 | ||
3191 | (define_insn "insn_inv" | |
3192 | [(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")] | |
3193 | UNSPEC_INSN_INV)] | |
3194 | "" | |
3195 | "inv\t%r0" | |
3196 | [(set_attr "type" "X1")]) | |
3197 | ||
3198 | (define_insn "insn_lnk" | |
3199 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3200 | (unspec:SI [(const_int 0)] UNSPEC_INSN_LNK))] | |
3201 | "" | |
3202 | "lnk\t%0" | |
3203 | [(set_attr "type" "X1")]) | |
3204 | ||
3205 | (define_insn "insn_mnzb" | |
3206 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3207 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3208 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3209 | UNSPEC_INSN_MNZB))] | |
3210 | "" | |
3211 | "mnzb\t%0, %r1, %r2" | |
3212 | [(set_attr "type" "X01")]) | |
3213 | ||
3214 | (define_insn "insn_mnzh" | |
3215 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3216 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3217 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3218 | UNSPEC_INSN_MNZH))] | |
3219 | "" | |
3220 | "mnzh\t%0, %r1, %r2" | |
3221 | [(set_attr "type" "X01")]) | |
3222 | ||
3223 | (define_insn "insn_mulhh_ss" | |
3224 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3225 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3226 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3227 | UNSPEC_INSN_MULHH_SS))] | |
3228 | "" | |
3229 | "mulhh_ss\t%0, %r1, %r2" | |
3230 | [(set_attr "type" "Y0_2cycle")]) | |
3231 | ||
3232 | (define_insn "insn_mulhh_su" | |
3233 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3234 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3235 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3236 | UNSPEC_INSN_MULHH_SU))] | |
3237 | "" | |
3238 | "mulhh_su\t%0, %r1, %r2" | |
3239 | [(set_attr "type" "X0_2cycle")]) | |
3240 | ||
3241 | (define_insn "insn_mulhh_uu" | |
3242 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3243 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3244 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3245 | UNSPEC_INSN_MULHH_UU))] | |
3246 | "" | |
3247 | "mulhh_uu\t%0, %r1, %r2" | |
3248 | [(set_attr "type" "Y0_2cycle")]) | |
3249 | ||
3250 | (define_insn "insn_mulhha_ss" | |
3251 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3252 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3253 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3254 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3255 | UNSPEC_INSN_MULHHA_SS))] | |
3256 | "" | |
3257 | "mulhha_ss\t%0, %r2, %r3" | |
3258 | [(set_attr "type" "Y0_2cycle")]) | |
3259 | ||
3260 | (define_insn "insn_mulhha_su" | |
3261 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3262 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3263 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3264 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3265 | UNSPEC_INSN_MULHHA_SU))] | |
3266 | "" | |
3267 | "mulhha_su\t%0, %r2, %r3" | |
3268 | [(set_attr "type" "X0_2cycle")]) | |
3269 | ||
3270 | (define_insn "insn_mulhha_uu" | |
3271 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3272 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3273 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3274 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3275 | UNSPEC_INSN_MULHHA_UU))] | |
3276 | "" | |
3277 | "mulhha_uu\t%0, %r2, %r3" | |
3278 | [(set_attr "type" "Y0_2cycle")]) | |
3279 | ||
3280 | (define_insn "insn_mulhhsa_uu" | |
3281 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3282 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3283 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3284 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3285 | UNSPEC_INSN_MULHHSA_UU))] | |
3286 | "" | |
3287 | "mulhhsa_uu\t%0, %r2, %r3" | |
3288 | [(set_attr "type" "X0_2cycle")]) | |
3289 | ||
3290 | (define_insn "insn_mulhl_ss" | |
3291 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3292 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3293 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3294 | UNSPEC_INSN_MULHL_SS))] | |
3295 | "" | |
3296 | "mulhl_ss\t%0, %r1, %r2" | |
3297 | [(set_attr "type" "X0_2cycle")]) | |
3298 | ||
3299 | (define_insn "insn_mulhl_su" | |
3300 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3301 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3302 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3303 | UNSPEC_INSN_MULHL_SU))] | |
3304 | "" | |
3305 | "mulhl_su\t%0, %r1, %r2" | |
3306 | [(set_attr "type" "X0_2cycle")]) | |
3307 | ||
3308 | (define_insn "insn_mulhl_us" | |
3309 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3310 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3311 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3312 | UNSPEC_INSN_MULHL_US))] | |
3313 | "" | |
3314 | "mulhl_us\t%0, %r1, %r2" | |
3315 | [(set_attr "type" "X0_2cycle")]) | |
3316 | ||
3317 | (define_insn "insn_mulhl_uu" | |
3318 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3319 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3320 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3321 | UNSPEC_INSN_MULHL_UU))] | |
3322 | "" | |
3323 | "mulhl_uu\t%0, %r1, %r2" | |
3324 | [(set_attr "type" "X0_2cycle")]) | |
3325 | ||
3326 | (define_insn "insn_mulhla_ss" | |
3327 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3328 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3329 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3330 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3331 | UNSPEC_INSN_MULHLA_SS))] | |
3332 | "" | |
3333 | "mulhla_ss\t%0, %r2, %r3" | |
3334 | [(set_attr "type" "X0_2cycle")]) | |
3335 | ||
3336 | (define_insn "insn_mulhla_su" | |
3337 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3338 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3339 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3340 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3341 | UNSPEC_INSN_MULHLA_SU))] | |
3342 | "" | |
3343 | "mulhla_su\t%0, %r2, %r3" | |
3344 | [(set_attr "type" "X0_2cycle")]) | |
3345 | ||
3346 | (define_insn "insn_mulhla_us" | |
3347 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3348 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3349 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3350 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3351 | UNSPEC_INSN_MULHLA_US))] | |
3352 | "" | |
3353 | "mulhla_us\t%0, %r2, %r3" | |
3354 | [(set_attr "type" "X0_2cycle")]) | |
3355 | ||
3356 | (define_insn "insn_mulhla_uu" | |
3357 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3358 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3359 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3360 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3361 | UNSPEC_INSN_MULHLA_UU))] | |
3362 | "" | |
3363 | "mulhla_uu\t%0, %r2, %r3" | |
3364 | [(set_attr "type" "X0_2cycle")]) | |
3365 | ||
3366 | (define_insn "insn_mulhlsa_uu" | |
3367 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3368 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3369 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3370 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3371 | UNSPEC_INSN_MULHLSA_UU))] | |
3372 | "" | |
3373 | "mulhlsa_uu\t%0, %r2, %r3" | |
3374 | [(set_attr "type" "Y0_2cycle")]) | |
3375 | ||
3376 | (define_insn "insn_mulll_ss" | |
3377 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3378 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3379 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3380 | UNSPEC_INSN_MULLL_SS))] | |
3381 | "" | |
3382 | "mulll_ss\t%0, %r1, %r2" | |
3383 | [(set_attr "type" "Y0_2cycle")]) | |
3384 | ||
3385 | (define_insn "insn_mulll_su" | |
3386 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3387 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3388 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3389 | UNSPEC_INSN_MULLL_SU))] | |
3390 | "" | |
3391 | "mulll_su\t%0, %r1, %r2" | |
3392 | [(set_attr "type" "X0_2cycle")]) | |
3393 | ||
3394 | (define_insn "insn_mulll_uu" | |
3395 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3396 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3397 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3398 | UNSPEC_INSN_MULLL_UU))] | |
3399 | "" | |
3400 | "mulll_uu\t%0, %r1, %r2" | |
3401 | [(set_attr "type" "Y0_2cycle")]) | |
3402 | ||
3403 | (define_insn "insn_mullla_ss" | |
3404 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3405 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3406 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3407 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3408 | UNSPEC_INSN_MULLLA_SS))] | |
3409 | "" | |
3410 | "mullla_ss\t%0, %r2, %r3" | |
3411 | [(set_attr "type" "Y0_2cycle")]) | |
3412 | ||
3413 | (define_insn "insn_mullla_su" | |
3414 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3415 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3416 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3417 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3418 | UNSPEC_INSN_MULLLA_SU))] | |
3419 | "" | |
3420 | "mullla_su\t%0, %r2, %r3" | |
3421 | [(set_attr "type" "X0_2cycle")]) | |
3422 | ||
3423 | (define_insn "insn_mullla_uu" | |
3424 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3425 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3426 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3427 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3428 | UNSPEC_INSN_MULLLA_UU))] | |
3429 | "" | |
3430 | "mullla_uu\t%0, %r2, %r3" | |
3431 | [(set_attr "type" "Y0_2cycle")]) | |
3432 | ||
3433 | (define_insn "insn_mulllsa_uu" | |
3434 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3435 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3436 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3437 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3438 | UNSPEC_INSN_MULLLSA_UU))] | |
3439 | "" | |
3440 | "mulllsa_uu\t%0, %r2, %r3" | |
3441 | [(set_attr "type" "X0_2cycle")]) | |
3442 | ||
3443 | (define_insn "insn_mzb" | |
3444 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3445 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3446 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3447 | UNSPEC_INSN_MZB))] | |
3448 | "" | |
3449 | "mzb\t%0, %r1, %r2" | |
3450 | [(set_attr "type" "X01")]) | |
3451 | ||
3452 | (define_insn "insn_mzh" | |
3453 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3454 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3455 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3456 | UNSPEC_INSN_MZH))] | |
3457 | "" | |
3458 | "mzh\t%0, %r1, %r2" | |
3459 | [(set_attr "type" "X01")]) | |
3460 | ||
3461 | (define_insn "insn_nap" | |
3462 | [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_NAP)] | |
3463 | "" | |
3464 | "nap" | |
3465 | [(set_attr "type" "cannot_bundle")]) | |
3466 | ||
3467 | (define_insn "insn_nor" | |
3468 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3469 | (and:SI (not:SI (match_operand:SI 1 "reg_or_0_operand" "rO")) | |
3470 | (not:SI (match_operand:SI 2 "reg_or_0_operand" "rO"))))] | |
3471 | "" | |
3472 | "nor\t%0, %r1, %r2") | |
3473 | ||
3474 | (define_insn "insn_sadab_u" | |
3475 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3476 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3477 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3478 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3479 | UNSPEC_INSN_SADAB_U))] | |
3480 | "" | |
3481 | "sadab_u\t%0, %r2, %r3" | |
3482 | [(set_attr "type" "X0_2cycle")]) | |
3483 | ||
3484 | (define_insn "insn_sadah" | |
3485 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3486 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3487 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3488 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3489 | UNSPEC_INSN_SADAH))] | |
3490 | "" | |
3491 | "sadah\t%0, %r2, %r3" | |
3492 | [(set_attr "type" "X0_2cycle")]) | |
3493 | ||
3494 | (define_insn "insn_sadah_u" | |
3495 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3496 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3497 | (match_operand:SI 2 "reg_or_0_operand" "rO") | |
3498 | (match_operand:SI 3 "reg_or_0_operand" "rO")] | |
3499 | UNSPEC_INSN_SADAH_U))] | |
3500 | "" | |
3501 | "sadah_u\t%0, %r2, %r3" | |
3502 | [(set_attr "type" "X0_2cycle")]) | |
3503 | ||
3504 | (define_insn "insn_sadb_u" | |
3505 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3506 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3507 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3508 | UNSPEC_INSN_SADB_U))] | |
3509 | "" | |
3510 | "sadb_u\t%0, %r1, %r2" | |
3511 | [(set_attr "type" "X0_2cycle")]) | |
3512 | ||
3513 | (define_insn "insn_sadh" | |
3514 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3515 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3516 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3517 | UNSPEC_INSN_SADH))] | |
3518 | "" | |
3519 | "sadh\t%0, %r1, %r2" | |
3520 | [(set_attr "type" "X0_2cycle")]) | |
3521 | ||
3522 | (define_insn "insn_sadh_u" | |
3523 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3524 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO") | |
3525 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3526 | UNSPEC_INSN_SADH_U))] | |
3527 | "" | |
3528 | "sadh_u\t%0, %r1, %r2" | |
3529 | [(set_attr "type" "X0_2cycle")]) | |
3530 | ||
3531 | (define_insn "insn_tblidxb0" | |
3532 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3533 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3534 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3535 | UNSPEC_INSN_TBLIDXB0))] | |
3536 | "" | |
3537 | "tblidxb0\t%0, %r2" | |
3538 | [(set_attr "type" "Y0")]) | |
3539 | ||
3540 | (define_insn "insn_tblidxb1" | |
3541 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3542 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3543 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3544 | UNSPEC_INSN_TBLIDXB1))] | |
3545 | "" | |
3546 | "tblidxb1\t%0, %r2" | |
3547 | [(set_attr "type" "Y0")]) | |
3548 | ||
3549 | (define_insn "insn_tblidxb2" | |
3550 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3551 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3552 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3553 | UNSPEC_INSN_TBLIDXB2))] | |
3554 | "" | |
3555 | "tblidxb2\t%0, %r2" | |
3556 | [(set_attr "type" "Y0")]) | |
3557 | ||
3558 | (define_insn "insn_tblidxb3" | |
3559 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3560 | (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0") | |
3561 | (match_operand:SI 2 "reg_or_0_operand" "rO")] | |
3562 | UNSPEC_INSN_TBLIDXB3))] | |
3563 | "" | |
3564 | "tblidxb3\t%0, %r2" | |
3565 | [(set_attr "type" "Y0")]) | |
3566 | ||
3567 | \f | |
3568 | ;; | |
3569 | ;; pic related instructions | |
3570 | ;; | |
3571 | ||
3572 | ;; NOTE: We compute the label in this unusual way because if we place | |
3573 | ;; the label after the lnk, whether it is at the same address as the | |
3574 | ;; lnk will vary depending on whether the optimization level chooses to | |
3575 | ;; insert bundling braces. | |
3576 | (define_insn "insn_lnk_and_label" | |
3577 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3578 | (unspec_volatile:SI [(match_operand:SI 1 "symbolic_operand" "")] | |
3579 | UNSPEC_LNK_AND_LABEL))] | |
3580 | "" | |
3581 | "%1 = . + 8\n\tlnk\t%0" | |
3582 | [(set_attr "type" "X1")]) | |
3583 | ||
3584 | (define_expand "addli_pcrel" | |
3585 | [(set (match_operand:SI 0 "register_operand" "") | |
3586 | (lo_sum:SI | |
3587 | (match_operand:SI 1 "register_operand" "") | |
3588 | (const:SI | |
3589 | (unspec:SI [(match_operand:SI 2 "symbolic_operand" "") | |
3590 | (match_operand:SI 3 "symbolic_operand" "")] | |
3591 | UNSPEC_PCREL_SYM))))] | |
3592 | "flag_pic") | |
3593 | ||
3594 | (define_expand "auli_pcrel" | |
3595 | [(set (match_operand:SI 0 "register_operand" "") | |
3596 | (plus:SI | |
3597 | (match_operand:SI 1 "reg_or_0_operand" "") | |
3598 | (high:SI | |
3599 | (const:SI | |
3600 | (unspec:SI [(match_operand:SI 2 "symbolic_operand" "") | |
3601 | (match_operand:SI 3 "symbolic_operand" "")] | |
3602 | UNSPEC_PCREL_SYM)))))] | |
3603 | "flag_pic") | |
3604 | ||
3605 | (define_expand "add_got16" | |
3606 | [(set (match_operand:SI 0 "register_operand" "") | |
3607 | (lo_sum:SI | |
3608 | (match_operand:SI 1 "reg_or_0_operand" "") | |
3609 | (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")] | |
3610 | UNSPEC_GOT16_SYM))))] | |
3611 | "flag_pic == 1") | |
3612 | ||
3613 | (define_expand "addhi_got32" | |
3614 | [(set (match_operand:SI 0 "register_operand" "") | |
3615 | (plus:SI | |
3616 | (match_operand:SI 1 "reg_or_0_operand" "") | |
3617 | (high:SI | |
3618 | (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")] | |
3619 | UNSPEC_GOT32_SYM)))))] | |
3620 | "flag_pic == 2") | |
3621 | ||
3622 | (define_expand "addlo_got32" | |
3623 | [(set (match_operand:SI 0 "register_operand" "") | |
3624 | (lo_sum:SI | |
3625 | (match_operand:SI 1 "reg_or_0_operand" "") | |
3626 | (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")] | |
3627 | UNSPEC_GOT32_SYM))))] | |
3628 | "flag_pic == 2") | |
3629 | ||
3630 | \f | |
3631 | ;; | |
3632 | ;; TLS | |
3633 | ;; | |
3634 | ||
3635 | (define_expand "tls_gd_addhi" | |
3636 | [(set (match_operand:SI 0 "register_operand" "") | |
3637 | (plus:SI | |
3638 | (match_operand:SI 1 "reg_or_0_operand" "") | |
3639 | (high:SI | |
3640 | (const:SI (unspec:SI [(match_operand 2 "tls_symbolic_operand" "")] | |
3641 | UNSPEC_TLS_GD)))))] | |
3642 | "HAVE_AS_TLS") | |
3643 | ||
3644 | (define_expand "tls_gd_addlo" | |
3645 | [(set (match_operand:SI 0 "register_operand" "") | |
3646 | (lo_sum:SI | |
3647 | (match_operand:SI 1 "reg_or_0_operand" "") | |
3648 | (const:SI (unspec:SI [(match_operand 2 "tls_symbolic_operand" "")] | |
3649 | UNSPEC_TLS_GD))))] | |
3650 | "HAVE_AS_TLS") | |
3651 | ||
3652 | (define_expand "tls_gd_call" | |
3653 | [(parallel | |
3654 | [(set (reg:SI 0) | |
3655 | (unspec:SI [(match_operand:SI 0 "tls_symbolic_operand" "") | |
3656 | (reg:SI 0)] | |
3657 | UNSPEC_TLS_GD_CALL)) | |
3658 | (clobber (reg:SI 25)) | |
3659 | (clobber (reg:SI 26)) | |
3660 | (clobber (reg:SI 27)) | |
3661 | (clobber (reg:SI 28)) | |
3662 | (clobber (reg:SI 29)) | |
3663 | (clobber (reg:SI 55))])] | |
3664 | "" | |
3665 | { | |
3666 | cfun->machine->calls_tls_get_addr = true; | |
3667 | }) | |
3668 | ||
3669 | (define_insn "*tls_gd_call" | |
3670 | [(set (reg:SI 0) | |
3671 | (unspec:SI [(match_operand:SI 0 "tls_symbolic_operand" "") | |
3672 | (reg:SI 0)] | |
3673 | UNSPEC_TLS_GD_CALL)) | |
3674 | (clobber (reg:SI 25)) | |
3675 | (clobber (reg:SI 26)) | |
3676 | (clobber (reg:SI 27)) | |
3677 | (clobber (reg:SI 28)) | |
3678 | (clobber (reg:SI 29)) | |
3679 | (clobber (reg:SI 55))] | |
3680 | "" | |
3681 | "jal\ttls_gd_call(%0)" | |
3682 | [(set_attr "type" "X1")]) | |
3683 | ||
3684 | (define_insn "tls_gd_add" | |
3685 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3686 | (unspec:SI [(match_operand:SI 1 "register_operand" "r") | |
3687 | (match_operand:SI 2 "tls_symbolic_operand" "")] | |
3688 | UNSPEC_TLS_GD_ADD))] | |
3689 | "HAVE_AS_TLS" | |
3690 | "addi\t%0, %1, tls_gd_add(%2)") | |
3691 | ||
3692 | (define_insn "tls_ie_load" | |
3693 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3694 | (unspec:SI [(match_operand:SI 1 "register_operand" "r") | |
3695 | (match_operand:SI 2 "tls_symbolic_operand" "")] | |
3696 | UNSPEC_TLS_IE_LOAD))] | |
3697 | "HAVE_AS_TLS" | |
3698 | "lw_tls\t%0, %1, tls_ie_load(%2)" | |
3699 | [(set_attr "type" "X1_2cycle")]) | |
3700 | ||
3701 | (define_expand "tls_ie_addhi" | |
3702 | [(set (match_operand:SI 0 "register_operand" "") | |
3703 | (plus:SI | |
3704 | (match_operand:SI 1 "register_operand" "") | |
3705 | (high:SI | |
3706 | (const:SI (unspec:SI [(match_operand 2 "tls_ie_symbolic_operand" "")] | |
3707 | UNSPEC_TLS_IE)))))] | |
3708 | "HAVE_AS_TLS") | |
3709 | ||
3710 | (define_expand "tls_ie_addlo" | |
3711 | [(set (match_operand:SI 0 "register_operand" "") | |
3712 | (lo_sum:SI | |
3713 | (match_operand:SI 1 "register_operand" "") | |
3714 | (const:SI (unspec:SI [(match_operand 2 "tls_ie_symbolic_operand" "")] | |
3715 | UNSPEC_TLS_IE))))] | |
3716 | "HAVE_AS_TLS") | |
3717 | ||
3718 | (define_expand "tls_le_addhi" | |
3719 | [(set (match_operand:SI 0 "register_operand" "") | |
3720 | (plus:SI | |
3721 | (match_operand:SI 1 "register_operand" "") | |
3722 | (high:SI | |
3723 | (const:SI (unspec:SI [(match_operand 2 "tls_le_symbolic_operand" "")] | |
3724 | UNSPEC_TLS_LE)))))] | |
3725 | "HAVE_AS_TLS") | |
3726 | ||
3727 | (define_expand "tls_le_addlo" | |
3728 | [(set (match_operand:SI 0 "register_operand" "") | |
3729 | (lo_sum:SI | |
3730 | (match_operand:SI 1 "register_operand" "") | |
3731 | (const:SI (unspec:SI [(match_operand 2 "tls_le_symbolic_operand" "")] | |
3732 | UNSPEC_TLS_LE))))] | |
3733 | "HAVE_AS_TLS") | |
3734 | ||
3735 | \f | |
3736 | ;; | |
3737 | ;; Stack protector instructions. | |
3738 | ;; | |
3739 | ||
3740 | (define_expand "stack_protect_set" | |
3741 | [(set (match_operand 0 "nonautoincmem_operand" "") | |
3742 | (match_operand 1 "nonautoincmem_operand" ""))] | |
3743 | "" | |
3744 | { | |
3745 | #ifdef TARGET_THREAD_SSP_OFFSET | |
3746 | rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM); | |
3747 | rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET)); | |
3748 | rtx ssp = gen_reg_rtx (Pmode); | |
3749 | ||
f7df4a84 | 3750 | emit_insn (gen_rtx_SET (ssp, ssp_addr)); |
dd552284 WL |
3751 | |
3752 | operands[1] = gen_rtx_MEM (Pmode, ssp); | |
3753 | #endif | |
3754 | ||
3755 | emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); | |
3756 | ||
3757 | DONE; | |
3758 | }) | |
3759 | ||
3760 | (define_insn "stack_protect_setsi" | |
3761 | [(set (match_operand:SI 0 "nonautoincmem_operand" "=U") | |
3762 | (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")] | |
3763 | UNSPEC_SP_SET)) | |
3764 | (set (match_scratch:SI 2 "=&r") (const_int 0))] | |
3765 | "" | |
3766 | "lw\t%2, %1; { sw\t%0, %2; move\t%2, zero }" | |
3767 | [(set_attr "length" "16") | |
3768 | (set_attr "type" "cannot_bundle_3cycle")]) | |
3769 | ||
3770 | ||
3771 | (define_expand "stack_protect_test" | |
3772 | [(match_operand 0 "nonautoincmem_operand" "") | |
3773 | (match_operand 1 "nonautoincmem_operand" "") | |
3774 | (match_operand 2 "" "")] | |
3775 | "" | |
3776 | { | |
3777 | rtx compare_result; | |
3778 | rtx bcomp, loc_ref; | |
3779 | ||
3780 | #ifdef TARGET_THREAD_SSP_OFFSET | |
3781 | rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM); | |
3782 | rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET)); | |
3783 | rtx ssp = gen_reg_rtx (Pmode); | |
3784 | ||
f7df4a84 | 3785 | emit_insn (gen_rtx_SET (ssp, ssp_addr)); |
dd552284 WL |
3786 | |
3787 | operands[1] = gen_rtx_MEM (Pmode, ssp); | |
3788 | #endif | |
3789 | ||
3790 | compare_result = gen_reg_rtx (SImode); | |
3791 | ||
3792 | emit_insn (gen_stack_protect_testsi (compare_result, operands[0], | |
3793 | operands[1])); | |
3794 | ||
3795 | bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx); | |
3796 | ||
3797 | loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]); | |
3798 | ||
f7df4a84 | 3799 | emit_jump_insn (gen_rtx_SET (pc_rtx, |
dd552284 WL |
3800 | gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp, |
3801 | loc_ref, pc_rtx))); | |
3802 | ||
3803 | DONE; | |
3804 | }) | |
3805 | ||
3806 | (define_insn "stack_protect_testsi" | |
3807 | [(set (match_operand:SI 0 "register_operand" "=&r") | |
3808 | (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U") | |
3809 | (match_operand:SI 2 "nonautoincmem_operand" "U")] | |
3810 | UNSPEC_SP_TEST)) | |
3811 | (set (match_scratch:SI 3 "=&r") (const_int 0))] | |
3812 | "" | |
3813 | "lw\t%0, %1; lw\t%3, %2; { seq\t%0, %0, %3; move\t%3, zero }" | |
3814 | [(set_attr "length" "24") | |
3815 | (set_attr "type" "cannot_bundle_4cycle")]) | |
3816 |