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