]>
Commit | Line | Data |
---|---|---|
4d8af13f | 1 | ;; Machine description for SPARC chip for GCC |
23a5b65a | 2 | ;; Copyright (C) 1987-2014 Free Software Foundation, Inc. |
8dffbc60 | 3 | ;; Contributed by Michael Tiemann (tiemann@cygnus.com) |
5fddd9fe | 4 | ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans, |
8dffbc60 | 5 | ;; at Cygnus Support. |
7a768814 | 6 | |
4d8af13f | 7 | ;; This file is part of GCC. |
7a768814 | 8 | |
4d8af13f | 9 | ;; GCC is free software; you can redistribute it and/or modify |
7a768814 | 10 | ;; it under the terms of the GNU General Public License as published by |
2f83c7d6 | 11 | ;; the Free Software Foundation; either version 3, or (at your option) |
7a768814 RS |
12 | ;; any later version. |
13 | ||
4d8af13f | 14 | ;; GCC is distributed in the hope that it will be useful, |
7a768814 RS |
15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | ;; GNU General Public License for more details. | |
18 | ||
19 | ;; You should have received a copy of the GNU General Public License | |
2f83c7d6 NC |
20 | ;; along with GCC; see the file COPYING3. If not see |
21 | ;; <http://www.gnu.org/licenses/>. | |
7a768814 | 22 | |
7a768814 RS |
23 | ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. |
24 | ||
48eecbee SB |
25 | (define_c_enum "unspec" [ |
26 | UNSPEC_MOVE_PIC | |
27 | UNSPEC_UPDATE_RETURN | |
28 | UNSPEC_LOAD_PCREL_SYM | |
29 | UNSPEC_FRAME_BLOCKAGE | |
30 | UNSPEC_MOVE_PIC_LABEL | |
31 | UNSPEC_SETH44 | |
32 | UNSPEC_SETM44 | |
33 | UNSPEC_SETHH | |
34 | UNSPEC_SETLM | |
35 | UNSPEC_EMB_HISUM | |
36 | UNSPEC_EMB_TEXTUHI | |
37 | UNSPEC_EMB_TEXTHI | |
38 | UNSPEC_EMB_TEXTULO | |
39 | UNSPEC_EMB_SETHM | |
40 | UNSPEC_MOVE_GOTDATA | |
5751a10b | 41 | |
48eecbee SB |
42 | UNSPEC_MEMBAR |
43 | UNSPEC_ATOMIC | |
1a8c13b3 | 44 | |
48eecbee SB |
45 | UNSPEC_TLSGD |
46 | UNSPEC_TLSLDM | |
47 | UNSPEC_TLSLDO | |
48 | UNSPEC_TLSIE | |
49 | UNSPEC_TLSLE | |
50 | UNSPEC_TLSLD_BASE | |
16f59241 | 51 | |
48eecbee SB |
52 | UNSPEC_FPACK16 |
53 | UNSPEC_FPACK32 | |
54 | UNSPEC_FPACKFIX | |
55 | UNSPEC_FEXPAND | |
56 | UNSPEC_MUL16AU | |
57 | UNSPEC_MUL16AL | |
58 | UNSPEC_MUL8UL | |
59 | UNSPEC_MULDUL | |
60 | UNSPEC_ALIGNDATA | |
61 | UNSPEC_FCMP | |
62 | UNSPEC_PDIST | |
63 | UNSPEC_EDGE8 | |
64 | UNSPEC_EDGE8L | |
65 | UNSPEC_EDGE16 | |
66 | UNSPEC_EDGE16L | |
67 | UNSPEC_EDGE32 | |
68 | UNSPEC_EDGE32L | |
69 | UNSPEC_ARRAY8 | |
70 | UNSPEC_ARRAY16 | |
71 | UNSPEC_ARRAY32 | |
8ec11fe9 | 72 | |
48eecbee SB |
73 | UNSPEC_SP_SET |
74 | UNSPEC_SP_TEST | |
c4728c6b | 75 | |
48eecbee SB |
76 | UNSPEC_EDGE8N |
77 | UNSPEC_EDGE8LN | |
78 | UNSPEC_EDGE16N | |
79 | UNSPEC_EDGE16LN | |
80 | UNSPEC_EDGE32N | |
81 | UNSPEC_EDGE32LN | |
82 | UNSPEC_BSHUFFLE | |
83 | UNSPEC_CMASK8 | |
84 | UNSPEC_CMASK16 | |
85 | UNSPEC_CMASK32 | |
86 | UNSPEC_FCHKSM16 | |
87 | UNSPEC_PDISTN | |
88 | UNSPEC_FUCMP | |
89 | UNSPEC_FHADD | |
90 | UNSPEC_FHSUB | |
91 | UNSPEC_XMUL | |
92 | UNSPEC_MUL8 | |
93 | UNSPEC_MUL8SU | |
94 | UNSPEC_MULDSU | |
95 | ]) | |
4f4778ee | 96 | |
48eecbee SB |
97 | (define_c_enum "unspecv" [ |
98 | UNSPECV_BLOCKAGE | |
fde66fde EB |
99 | UNSPECV_PROBE_STACK_RANGE |
100 | ||
48eecbee | 101 | UNSPECV_FLUSHW |
48eecbee | 102 | UNSPECV_SAVEW |
fde66fde EB |
103 | |
104 | UNSPECV_FLUSH | |
105 | ||
48eecbee | 106 | UNSPECV_LDSTUB |
fde66fde EB |
107 | UNSPECV_SWAP |
108 | UNSPECV_CAS | |
109 | ||
110 | UNSPECV_LDFSR | |
111 | UNSPECV_STFSR | |
48eecbee | 112 | ]) |
e0d80184 | 113 | |
45a7dd80 DM |
114 | (define_constants |
115 | [(G0_REG 0) | |
116 | (G1_REG 1) | |
117 | (G2_REG 2) | |
118 | (G3_REG 3) | |
119 | (G4_REG 4) | |
120 | (G5_REG 5) | |
121 | (G6_REG 6) | |
122 | (G7_REG 7) | |
123 | (O0_REG 8) | |
124 | (O1_REG 9) | |
125 | (O2_REG 10) | |
126 | (O3_REG 11) | |
127 | (O4_REG 12) | |
128 | (O5_REG 13) | |
129 | (O6_REG 14) | |
130 | (O7_REG 15) | |
131 | (L0_REG 16) | |
132 | (L1_REG 17) | |
133 | (L2_REG 18) | |
134 | (L3_REG 19) | |
135 | (L4_REG 20) | |
136 | (L5_REG 21) | |
137 | (L6_REG 22) | |
138 | (L7_REG 23) | |
139 | (I0_REG 24) | |
140 | (I1_REG 25) | |
141 | (I2_REG 26) | |
142 | (I3_REG 27) | |
143 | (I4_REG 28) | |
144 | (I5_REG 29) | |
145 | (I6_REG 30) | |
146 | (I7_REG 31) | |
147 | (F0_REG 32) | |
148 | (F1_REG 33) | |
149 | (F2_REG 34) | |
150 | (F3_REG 35) | |
151 | (F4_REG 36) | |
152 | (F5_REG 37) | |
153 | (F6_REG 38) | |
154 | (F7_REG 39) | |
155 | (F8_REG 40) | |
156 | (F9_REG 41) | |
157 | (F10_REG 42) | |
158 | (F11_REG 43) | |
159 | (F12_REG 44) | |
160 | (F13_REG 45) | |
161 | (F14_REG 46) | |
162 | (F15_REG 47) | |
163 | (F16_REG 48) | |
164 | (F17_REG 49) | |
165 | (F18_REG 50) | |
166 | (F19_REG 51) | |
167 | (F20_REG 52) | |
168 | (F21_REG 53) | |
169 | (F22_REG 54) | |
170 | (F23_REG 55) | |
171 | (F24_REG 56) | |
172 | (F25_REG 57) | |
173 | (F26_REG 58) | |
174 | (F27_REG 59) | |
175 | (F28_REG 60) | |
176 | (F29_REG 61) | |
177 | (F30_REG 62) | |
178 | (F31_REG 63) | |
179 | (F32_REG 64) | |
180 | (F34_REG 66) | |
181 | (F36_REG 68) | |
182 | (F38_REG 70) | |
183 | (F40_REG 72) | |
184 | (F42_REG 74) | |
185 | (F44_REG 76) | |
186 | (F46_REG 78) | |
187 | (F48_REG 80) | |
188 | (F50_REG 82) | |
189 | (F52_REG 84) | |
190 | (F54_REG 86) | |
191 | (F56_REG 88) | |
192 | (F58_REG 90) | |
193 | (F60_REG 92) | |
194 | (F62_REG 94) | |
195 | (FCC0_REG 96) | |
196 | (FCC1_REG 97) | |
197 | (FCC2_REG 98) | |
198 | (FCC3_REG 99) | |
199 | (CC_REG 100) | |
200 | (SFP_REG 101) | |
10b859c0 | 201 | (GSR_REG 102) |
45a7dd80 | 202 | ]) |
f90b7a5a PB |
203 | |
204 | (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) | |
205 | (define_mode_iterator I [QI HI SI DI]) | |
206 | (define_mode_iterator F [SF DF TF]) | |
207 | ||
b6d3c4ba JW |
208 | ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this |
209 | ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name | |
210 | ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding | |
211 | ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of | |
212 | ;; 'f' for all DF/TFmode values, including those that are specific to the v8. | |
213 | ||
0f1f080e | 214 | ;; Attribute for cpu type. |
38ae58ca | 215 | ;; These must match the values of the enum processor_type in sparc-opts.h. |
c6172f14 DM |
216 | (define_attr "cpu" |
217 | "v7, | |
218 | cypress, | |
219 | v8, | |
220 | supersparc, | |
07981468 KE |
221 | hypersparc, |
222 | leon, | |
38ae58ca | 223 | leon3, |
07981468 KE |
224 | sparclite, |
225 | f930, | |
226 | f934, | |
227 | sparclite86x, | |
228 | sparclet, | |
229 | tsc701, | |
c6172f14 DM |
230 | v9, |
231 | ultrasparc, | |
4c837a1e | 232 | ultrasparc3, |
9eeaed6e | 233 | niagara, |
3e64c239 DM |
234 | niagara2, |
235 | niagara3, | |
236 | niagara4" | |
6cab8731 | 237 | (const (symbol_ref "sparc_cpu_attr"))) |
0f1f080e | 238 | |
eb582c5d DE |
239 | ;; Attribute for the instruction set. |
240 | ;; At present we only need to distinguish v9/!v9, but for clarity we | |
241 | ;; test TARGET_V8 too. | |
60b85c4c | 242 | (define_attr "isa" "v7,v8,v9,sparclet" |
eb582c5d DE |
243 | (const |
244 | (cond [(symbol_ref "TARGET_V9") (const_string "v9") | |
6d29fc41 DE |
245 | (symbol_ref "TARGET_V8") (const_string "v8") |
246 | (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")] | |
60b85c4c | 247 | (const_string "v7")))) |
eb582c5d | 248 | |
1b43bc82 DM |
249 | (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3" (const_string "none")) |
250 | ||
251 | (define_attr "enabled" "" | |
252 | (cond [(eq_attr "cpu_feature" "none") (const_int 1) | |
253 | (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU") | |
254 | (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && ! TARGET_V9") | |
255 | (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9") | |
256 | (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS") | |
257 | (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")] | |
258 | (const_int 0))) | |
259 | ||
7fbb2f84 | 260 | ;; Insn type. |
7a768814 | 261 | (define_attr "type" |
c6172f14 DM |
262 | "ialu,compare,shift, |
263 | load,sload,store, | |
9ac617d4 | 264 | uncond_branch,branch,call,sibcall,call_no_delay_slot,return, |
8b98b5fd | 265 | cbcond,uncond_cbcond, |
c6172f14 DM |
266 | imul,idiv, |
267 | fpload,fpstore, | |
268 | fp,fpmove, | |
269 | fpcmove,fpcrmove, | |
270 | fpcmp, | |
271 | fpmul,fpdivs,fpdivd, | |
272 | fpsqrts,fpsqrtd, | |
f298688c | 273 | fga,visl,vismv,fgm_pack,fgm_mul,pdist,pdistn,edge,edgen,gsr,array, |
c6172f14 DM |
274 | cmove, |
275 | ialuX, | |
9ac617d4 | 276 | multi,savew,flushw,iflush,trap" |
7fbb2f84 | 277 | (const_string "ialu")) |
7a768814 | 278 | |
50711d27 | 279 | ;; True if branch/call has empty delay slot and will emit a nop in it |
f17f9332 | 280 | (define_attr "empty_delay_slot" "false,true" |
81f40b79 ILT |
281 | (symbol_ref "(empty_delay_slot (insn) |
282 | ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)")) | |
f17f9332 | 283 | |
8b98b5fd DM |
284 | ;; True if we are making use of compare-and-branch instructions. |
285 | ;; True if we should emit a nop after a cbcond instruction | |
286 | (define_attr "emit_cbcond_nop" "false,true" | |
287 | (symbol_ref "(emit_cbcond_nop (insn) | |
288 | ? EMIT_CBCOND_NOP_TRUE : EMIT_CBCOND_NOP_FALSE)")) | |
289 | ||
50711d27 EB |
290 | (define_attr "branch_type" "none,icc,fcc,reg" |
291 | (const_string "none")) | |
f17f9332 | 292 | |
ffd386b0 | 293 | (define_attr "pic" "false,true" |
81f40b79 | 294 | (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)")) |
ffd386b0 | 295 | |
50711d27 | 296 | (define_attr "calls_alloca" "false,true" |
81f40b79 ILT |
297 | (symbol_ref "(cfun->calls_alloca != 0 |
298 | ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)")) | |
2f937369 | 299 | |
50711d27 | 300 | (define_attr "calls_eh_return" "false,true" |
81f40b79 ILT |
301 | (symbol_ref "(crtl->calls_eh_return != 0 |
302 | ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)")) | |
b11b0904 | 303 | |
50711d27 | 304 | (define_attr "leaf_function" "false,true" |
416ff32e | 305 | (symbol_ref "(crtl->uses_only_leaf_regs != 0 |
81f40b79 | 306 | ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)")) |
50711d27 | 307 | |
951661a1 | 308 | (define_attr "delayed_branch" "false,true" |
81f40b79 ILT |
309 | (symbol_ref "(flag_delayed_branch != 0 |
310 | ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)")) | |
951661a1 | 311 | |
b11b0904 EB |
312 | (define_attr "flat" "false,true" |
313 | (symbol_ref "(TARGET_FLAT != 0 | |
314 | ? FLAT_TRUE : FLAT_FALSE)")) | |
315 | ||
7a768814 | 316 | ;; Length (in # of insns). |
883d9e0c EB |
317 | ;; Beware that setting a length greater or equal to 3 for conditional branches |
318 | ;; has a side-effect (see output_cbranch and output_v9branch). | |
f17f9332 | 319 | (define_attr "length" "" |
50711d27 | 320 | (cond [(eq_attr "type" "uncond_branch,call") |
f17f9332 JJ |
321 | (if_then_else (eq_attr "empty_delay_slot" "true") |
322 | (const_int 2) | |
323 | (const_int 1)) | |
50711d27 EB |
324 | (eq_attr "type" "sibcall") |
325 | (if_then_else (eq_attr "leaf_function" "true") | |
326 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
327 | (const_int 3) | |
328 | (const_int 2)) | |
329 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
330 | (const_int 2) | |
331 | (const_int 1))) | |
f17f9332 | 332 | (eq_attr "branch_type" "icc") |
0e5d569c | 333 | (if_then_else (match_operand 0 "noov_compare64_operator" "") |
f17f9332 JJ |
334 | (if_then_else (lt (pc) (match_dup 1)) |
335 | (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000)) | |
336 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
337 | (const_int 2) | |
338 | (const_int 1)) | |
339 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
340 | (const_int 4) | |
341 | (const_int 3))) | |
342 | (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000)) | |
343 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
344 | (const_int 2) | |
345 | (const_int 1)) | |
346 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
347 | (const_int 4) | |
348 | (const_int 3)))) | |
349 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
350 | (const_int 2) | |
351 | (const_int 1))) | |
352 | (eq_attr "branch_type" "fcc") | |
0e5d569c | 353 | (if_then_else (match_operand 0 "fcc0_register_operand" "") |
f17f9332 | 354 | (if_then_else (eq_attr "empty_delay_slot" "true") |
fe0aee6c | 355 | (if_then_else (not (match_test "TARGET_V9")) |
8ee37f15 EB |
356 | (const_int 3) |
357 | (const_int 2)) | |
fe0aee6c | 358 | (if_then_else (not (match_test "TARGET_V9")) |
8ee37f15 EB |
359 | (const_int 2) |
360 | (const_int 1))) | |
f17f9332 JJ |
361 | (if_then_else (lt (pc) (match_dup 2)) |
362 | (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000)) | |
363 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
364 | (const_int 2) | |
365 | (const_int 1)) | |
366 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
367 | (const_int 4) | |
368 | (const_int 3))) | |
369 | (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000)) | |
370 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
371 | (const_int 2) | |
372 | (const_int 1)) | |
373 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
374 | (const_int 4) | |
375 | (const_int 3))))) | |
376 | (eq_attr "branch_type" "reg") | |
377 | (if_then_else (lt (pc) (match_dup 2)) | |
378 | (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000)) | |
379 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
380 | (const_int 2) | |
381 | (const_int 1)) | |
382 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
383 | (const_int 4) | |
384 | (const_int 3))) | |
385 | (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000)) | |
386 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
387 | (const_int 2) | |
388 | (const_int 1)) | |
389 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
390 | (const_int 4) | |
391 | (const_int 3)))) | |
8b98b5fd DM |
392 | (eq_attr "type" "cbcond") |
393 | (if_then_else (lt (pc) (match_dup 3)) | |
394 | (if_then_else (lt (minus (match_dup 3) (pc)) (const_int 500)) | |
395 | (if_then_else (eq_attr "emit_cbcond_nop" "true") | |
396 | (const_int 2) | |
397 | (const_int 1)) | |
398 | (const_int 4)) | |
399 | (if_then_else (lt (minus (pc) (match_dup 3)) (const_int 500)) | |
400 | (if_then_else (eq_attr "emit_cbcond_nop" "true") | |
401 | (const_int 2) | |
402 | (const_int 1)) | |
403 | (const_int 4))) | |
404 | (eq_attr "type" "uncond_cbcond") | |
405 | (if_then_else (lt (pc) (match_dup 0)) | |
406 | (if_then_else (lt (minus (match_dup 0) (pc)) (const_int 500)) | |
407 | (if_then_else (eq_attr "emit_cbcond_nop" "true") | |
408 | (const_int 2) | |
409 | (const_int 1)) | |
410 | (const_int 1)) | |
411 | (if_then_else (lt (minus (pc) (match_dup 0)) (const_int 500)) | |
412 | (if_then_else (eq_attr "emit_cbcond_nop" "true") | |
413 | (const_int 2) | |
414 | (const_int 1)) | |
415 | (const_int 1))) | |
f17f9332 | 416 | ] (const_int 1))) |
7a768814 | 417 | |
24697ca0 | 418 | ;; FP precision. |
50711d27 EB |
419 | (define_attr "fptype" "single,double" |
420 | (const_string "single")) | |
7a768814 | 421 | |
fae15c93 | 422 | ;; UltraSPARC-III integer load type. |
50711d27 EB |
423 | (define_attr "us3load_type" "2cycle,3cycle" |
424 | (const_string "2cycle")) | |
fae15c93 | 425 | |
7a768814 | 426 | (define_asm_attributes |
24697ca0 | 427 | [(set_attr "length" "2") |
7a768814 RS |
428 | (set_attr "type" "multi")]) |
429 | ||
430 | ;; Attributes for instruction and branch scheduling | |
5751a10b | 431 | (define_attr "tls_call_delay" "false,true" |
81f40b79 ILT |
432 | (symbol_ref "(tls_call_delay (insn) |
433 | ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)")) | |
5751a10b | 434 | |
7a768814 | 435 | (define_attr "in_call_delay" "false,true" |
8b98b5fd | 436 | (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi") |
b75eeb37 | 437 | (const_string "false") |
7a768814 | 438 | (eq_attr "type" "load,fpload,store,fpstore") |
b75eeb37 | 439 | (if_then_else (eq_attr "length" "1") |
7a768814 RS |
440 | (const_string "true") |
441 | (const_string "false"))] | |
b75eeb37 EB |
442 | (if_then_else (and (eq_attr "length" "1") |
443 | (eq_attr "tls_call_delay" "true")) | |
444 | (const_string "true") | |
445 | (const_string "false")))) | |
7a768814 | 446 | |
7d167afd | 447 | (define_attr "eligible_for_sibcall_delay" "false,true" |
81f40b79 ILT |
448 | (symbol_ref "(eligible_for_sibcall_delay (insn) |
449 | ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE | |
450 | : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)")) | |
7d167afd | 451 | |
9ac617d4 | 452 | (define_attr "eligible_for_return_delay" "false,true" |
81f40b79 ILT |
453 | (symbol_ref "(eligible_for_return_delay (insn) |
454 | ? ELIGIBLE_FOR_RETURN_DELAY_TRUE | |
455 | : ELIGIBLE_FOR_RETURN_DELAY_FALSE)")) | |
284d86e9 | 456 | |
9ac617d4 | 457 | ;; ??? !v9: Should implement the notion of predelay slots for floating-point |
7a768814 RS |
458 | ;; branches. This would allow us to remove the nop always inserted before |
459 | ;; a floating point branch. | |
460 | ||
cab55461 JW |
461 | ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions |
462 | ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so. | |
463 | ;; This is because doing so will add several pipeline stalls to the path | |
464 | ;; that the load/store did not come from. Unfortunately, there is no way | |
465 | ;; to prevent fill_eager_delay_slots from using load/store without completely | |
466 | ;; disabling them. For the SPEC benchmark set, this is a serious lose, | |
467 | ;; because it prevents us from moving back the final store of inner loops. | |
e8d6096c | 468 | |
7a768814 | 469 | (define_attr "in_branch_delay" "false,true" |
8b98b5fd | 470 | (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi") |
e8d6096c JL |
471 | (eq_attr "length" "1")) |
472 | (const_string "true") | |
473 | (const_string "false"))) | |
474 | ||
475 | (define_attr "in_uncond_branch_delay" "false,true" | |
8b98b5fd | 476 | (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi") |
e8d6096c JL |
477 | (eq_attr "length" "1")) |
478 | (const_string "true") | |
479 | (const_string "false"))) | |
480 | ||
481 | (define_attr "in_annul_branch_delay" "false,true" | |
8b98b5fd | 482 | (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi") |
7a768814 RS |
483 | (eq_attr "length" "1")) |
484 | (const_string "true") | |
485 | (const_string "false"))) | |
486 | ||
9ac617d4 EB |
487 | (define_delay (eq_attr "type" "call") |
488 | [(eq_attr "in_call_delay" "true") (nil) (nil)]) | |
489 | ||
490 | (define_delay (eq_attr "type" "sibcall") | |
491 | [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)]) | |
492 | ||
7a768814 RS |
493 | (define_delay (eq_attr "type" "branch") |
494 | [(eq_attr "in_branch_delay" "true") | |
e8d6096c | 495 | (nil) (eq_attr "in_annul_branch_delay" "true")]) |
7a768814 | 496 | |
e8d6096c JL |
497 | (define_delay (eq_attr "type" "uncond_branch") |
498 | [(eq_attr "in_uncond_branch_delay" "true") | |
499 | (nil) (nil)]) | |
9ac617d4 EB |
500 | |
501 | (define_delay (eq_attr "type" "return") | |
502 | [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)]) | |
503 | ||
f8ece000 | 504 | |
a1d9bd0c DM |
505 | ;; Include SPARC DFA schedulers |
506 | ||
507 | (include "cypress.md") | |
508 | (include "supersparc.md") | |
509 | (include "hypersparc.md") | |
07981468 | 510 | (include "leon.md") |
a1d9bd0c DM |
511 | (include "sparclet.md") |
512 | (include "ultra1_2.md") | |
513 | (include "ultra3.md") | |
4c837a1e | 514 | (include "niagara.md") |
9eeaed6e | 515 | (include "niagara2.md") |
851634c7 | 516 | (include "niagara4.md") |
fae15c93 | 517 | |
f8ece000 | 518 | |
157891a3 | 519 | ;; Operand and operator predicates and constraints |
0e5d569c EB |
520 | |
521 | (include "predicates.md") | |
157891a3 | 522 | (include "constraints.md") |
0e5d569c EB |
523 | |
524 | ||
7a768814 | 525 | ;; Compare instructions. |
7a768814 | 526 | |
f90b7a5a PB |
527 | ;; These are just the DEFINE_INSNs to match the patterns and the |
528 | ;; DEFINE_SPLITs for some of the scc insns that actually require | |
529 | ;; more than one machine instruction. DEFINE_EXPANDs are further down. | |
795068a4 | 530 | |
f90b7a5a | 531 | ;; The compare DEFINE_INSNs. |
967ba98d | 532 | |
2a01c939 | 533 | (define_insn "*cmpsi_insn" |
45a7dd80 | 534 | [(set (reg:CC CC_REG) |
967ba98d DE |
535 | (compare:CC (match_operand:SI 0 "register_operand" "r") |
536 | (match_operand:SI 1 "arith_operand" "rI")))] | |
2a01c939 | 537 | "" |
16b46035 | 538 | "cmp\t%0, %1" |
967ba98d DE |
539 | [(set_attr "type" "compare")]) |
540 | ||
967ba98d | 541 | (define_insn "*cmpdi_sp64" |
45a7dd80 | 542 | [(set (reg:CCX CC_REG) |
967ba98d | 543 | (compare:CCX (match_operand:DI 0 "register_operand" "r") |
0e5d569c | 544 | (match_operand:DI 1 "arith_operand" "rI")))] |
967ba98d | 545 | "TARGET_ARCH64" |
16b46035 | 546 | "cmp\t%0, %1" |
967ba98d DE |
547 | [(set_attr "type" "compare")]) |
548 | ||
c4ce6853 | 549 | (define_insn "*cmpsf_fpe" |
0e5d569c | 550 | [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c") |
967ba98d DE |
551 | (compare:CCFPE (match_operand:SF 1 "register_operand" "f") |
552 | (match_operand:SF 2 "register_operand" "f")))] | |
c4ce6853 | 553 | "TARGET_FPU" |
c4ce6853 DE |
554 | { |
555 | if (TARGET_V9) | |
16b46035 DM |
556 | return "fcmpes\t%0, %1, %2"; |
557 | return "fcmpes\t%1, %2"; | |
563facba | 558 | } |
967ba98d DE |
559 | [(set_attr "type" "fpcmp")]) |
560 | ||
c4ce6853 | 561 | (define_insn "*cmpdf_fpe" |
0e5d569c | 562 | [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c") |
967ba98d DE |
563 | (compare:CCFPE (match_operand:DF 1 "register_operand" "e") |
564 | (match_operand:DF 2 "register_operand" "e")))] | |
c4ce6853 | 565 | "TARGET_FPU" |
c4ce6853 DE |
566 | { |
567 | if (TARGET_V9) | |
16b46035 DM |
568 | return "fcmped\t%0, %1, %2"; |
569 | return "fcmped\t%1, %2"; | |
563facba | 570 | } |
24697ca0 DM |
571 | [(set_attr "type" "fpcmp") |
572 | (set_attr "fptype" "double")]) | |
967ba98d | 573 | |
c4ce6853 | 574 | (define_insn "*cmptf_fpe" |
0e5d569c | 575 | [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c") |
967ba98d DE |
576 | (compare:CCFPE (match_operand:TF 1 "register_operand" "e") |
577 | (match_operand:TF 2 "register_operand" "e")))] | |
c4ce6853 | 578 | "TARGET_FPU && TARGET_HARD_QUAD" |
c4ce6853 DE |
579 | { |
580 | if (TARGET_V9) | |
16b46035 DM |
581 | return "fcmpeq\t%0, %1, %2"; |
582 | return "fcmpeq\t%1, %2"; | |
563facba | 583 | } |
967ba98d DE |
584 | [(set_attr "type" "fpcmp")]) |
585 | ||
c4ce6853 | 586 | (define_insn "*cmpsf_fp" |
0e5d569c | 587 | [(set (match_operand:CCFP 0 "fcc_register_operand" "=c") |
967ba98d DE |
588 | (compare:CCFP (match_operand:SF 1 "register_operand" "f") |
589 | (match_operand:SF 2 "register_operand" "f")))] | |
c4ce6853 | 590 | "TARGET_FPU" |
c4ce6853 DE |
591 | { |
592 | if (TARGET_V9) | |
16b46035 DM |
593 | return "fcmps\t%0, %1, %2"; |
594 | return "fcmps\t%1, %2"; | |
563facba | 595 | } |
967ba98d DE |
596 | [(set_attr "type" "fpcmp")]) |
597 | ||
c4ce6853 | 598 | (define_insn "*cmpdf_fp" |
0e5d569c | 599 | [(set (match_operand:CCFP 0 "fcc_register_operand" "=c") |
967ba98d DE |
600 | (compare:CCFP (match_operand:DF 1 "register_operand" "e") |
601 | (match_operand:DF 2 "register_operand" "e")))] | |
c4ce6853 | 602 | "TARGET_FPU" |
c4ce6853 DE |
603 | { |
604 | if (TARGET_V9) | |
16b46035 DM |
605 | return "fcmpd\t%0, %1, %2"; |
606 | return "fcmpd\t%1, %2"; | |
563facba | 607 | } |
24697ca0 DM |
608 | [(set_attr "type" "fpcmp") |
609 | (set_attr "fptype" "double")]) | |
967ba98d | 610 | |
c4ce6853 | 611 | (define_insn "*cmptf_fp" |
0e5d569c | 612 | [(set (match_operand:CCFP 0 "fcc_register_operand" "=c") |
967ba98d DE |
613 | (compare:CCFP (match_operand:TF 1 "register_operand" "e") |
614 | (match_operand:TF 2 "register_operand" "e")))] | |
c4ce6853 | 615 | "TARGET_FPU && TARGET_HARD_QUAD" |
c4ce6853 DE |
616 | { |
617 | if (TARGET_V9) | |
16b46035 DM |
618 | return "fcmpq\t%0, %1, %2"; |
619 | return "fcmpq\t%1, %2"; | |
563facba | 620 | } |
967ba98d DE |
621 | [(set_attr "type" "fpcmp")]) |
622 | \f | |
f90b7a5a PB |
623 | ;; Next come the scc insns. |
624 | ||
42e37616 DM |
625 | ;; Note that the boolean result (operand 0) takes on DImode |
626 | ;; (not SImode) when TARGET_ARCH64. | |
627 | ||
f90b7a5a PB |
628 | (define_expand "cstoresi4" |
629 | [(use (match_operator 1 "comparison_operator" | |
630 | [(match_operand:SI 2 "compare_operand" "") | |
631 | (match_operand:SI 3 "arith_operand" "")])) | |
42e37616 | 632 | (clobber (match_operand:SI 0 "cstore_result_operand"))] |
f90b7a5a PB |
633 | "" |
634 | { | |
635 | if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx) | |
636 | operands[2] = force_reg (SImode, operands[2]); | |
637 | if (emit_scc_insn (operands)) DONE; else FAIL; | |
638 | }) | |
639 | ||
640 | (define_expand "cstoredi4" | |
641 | [(use (match_operator 1 "comparison_operator" | |
642 | [(match_operand:DI 2 "compare_operand" "") | |
643 | (match_operand:DI 3 "arith_operand" "")])) | |
42e37616 | 644 | (clobber (match_operand:SI 0 "cstore_result_operand"))] |
f90b7a5a PB |
645 | "TARGET_ARCH64" |
646 | { | |
647 | if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx) | |
648 | operands[2] = force_reg (DImode, operands[2]); | |
649 | if (emit_scc_insn (operands)) DONE; else FAIL; | |
650 | }) | |
651 | ||
652 | (define_expand "cstore<F:mode>4" | |
653 | [(use (match_operator 1 "comparison_operator" | |
654 | [(match_operand:F 2 "register_operand" "") | |
655 | (match_operand:F 3 "register_operand" "")])) | |
42e37616 | 656 | (clobber (match_operand:SI 0 "cstore_result_operand"))] |
f90b7a5a PB |
657 | "TARGET_FPU" |
658 | { if (emit_scc_insn (operands)) DONE; else FAIL; }) | |
659 | ||
660 | \f | |
a8d2b752 DE |
661 | |
662 | ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they | |
7a768814 RS |
663 | ;; generate addcc/subcc instructions. |
664 | ||
42e37616 | 665 | (define_expand "seqsi<P:mode>_special" |
a8d2b752 DE |
666 | [(set (match_dup 3) |
667 | (xor:SI (match_operand:SI 1 "register_operand" "") | |
668 | (match_operand:SI 2 "register_operand" ""))) | |
42e37616 DM |
669 | (parallel [(set (match_operand:P 0 "register_operand" "") |
670 | (eq:P (match_dup 3) (const_int 0))) | |
45a7dd80 | 671 | (clobber (reg:CC CC_REG))])] |
e6c1be7e | 672 | "" |
563facba | 673 | { operands[3] = gen_reg_rtx (SImode); }) |
7a768814 | 674 | |
a8d2b752 DE |
675 | (define_expand "seqdi_special" |
676 | [(set (match_dup 3) | |
677 | (xor:DI (match_operand:DI 1 "register_operand" "") | |
678 | (match_operand:DI 2 "register_operand" ""))) | |
42e37616 DM |
679 | (set (match_operand:DI 0 "register_operand" "") |
680 | (eq:DI (match_dup 3) (const_int 0)))] | |
fa0f39e4 | 681 | "TARGET_ARCH64" |
563facba | 682 | { operands[3] = gen_reg_rtx (DImode); }) |
a8d2b752 | 683 | |
42e37616 | 684 | (define_expand "snesi<P:mode>_special" |
a8d2b752 DE |
685 | [(set (match_dup 3) |
686 | (xor:SI (match_operand:SI 1 "register_operand" "") | |
687 | (match_operand:SI 2 "register_operand" ""))) | |
42e37616 DM |
688 | (parallel [(set (match_operand:P 0 "register_operand" "") |
689 | (ne:P (match_dup 3) (const_int 0))) | |
45a7dd80 | 690 | (clobber (reg:CC CC_REG))])] |
e6c1be7e | 691 | "" |
563facba | 692 | { operands[3] = gen_reg_rtx (SImode); }) |
7a768814 | 693 | |
a8d2b752 | 694 | (define_expand "snedi_special" |
a8d2b752 DE |
695 | [(set (match_dup 3) |
696 | (xor:DI (match_operand:DI 1 "register_operand" "") | |
697 | (match_operand:DI 2 "register_operand" ""))) | |
42e37616 DM |
698 | (set (match_operand:DI 0 "register_operand" "") |
699 | (ne:DI (match_dup 3) (const_int 0)))] | |
1864ee35 DM |
700 | "TARGET_ARCH64 && ! TARGET_VIS3" |
701 | { operands[3] = gen_reg_rtx (DImode); }) | |
702 | ||
703 | (define_expand "snedi_special_vis3" | |
704 | [(set (match_dup 3) | |
705 | (xor:DI (match_operand:DI 1 "register_operand" "") | |
706 | (match_operand:DI 2 "register_operand" ""))) | |
42e37616 DM |
707 | (parallel [(set (match_operand:DI 0 "register_operand" "") |
708 | (ne:DI (match_dup 3) (const_int 0))) | |
1864ee35 DM |
709 | (clobber (reg:CCX CC_REG))])] |
710 | "TARGET_ARCH64 && TARGET_VIS3" | |
563facba | 711 | { operands[3] = gen_reg_rtx (DImode); }) |
a8d2b752 | 712 | |
7a768814 | 713 | |
967ba98d | 714 | ;; Now the DEFINE_INSNs for the scc cases. |
a8d2b752 | 715 | |
7a768814 | 716 | ;; The SEQ and SNE patterns are special because they can be done |
e0d80184 | 717 | ;; without any branching and do not involve a COMPARE. We want |
0fa2e4df | 718 | ;; them to always use the splits below so the results can be |
e0d80184 | 719 | ;; scheduled. |
7a768814 | 720 | |
42e37616 DM |
721 | (define_insn_and_split "*snesi<P:mode>_zero" |
722 | [(set (match_operand:P 0 "register_operand" "=r") | |
723 | (ne:P (match_operand:SI 1 "register_operand" "r") | |
a8d2b752 | 724 | (const_int 0))) |
45a7dd80 | 725 | (clobber (reg:CC CC_REG))] |
e6c1be7e | 726 | "" |
e0d80184 | 727 | "#" |
e0d80184 | 728 | "" |
45a7dd80 | 729 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
e0d80184 | 730 | (const_int 0))) |
42e37616 | 731 | (set (match_dup 0) (ltu:P (reg:CC CC_REG) (const_int 0)))] |
b776892b DM |
732 | "" |
733 | [(set_attr "length" "2")]) | |
7a768814 | 734 | |
42e37616 | 735 | (define_insn_and_split "*neg_snesisi_zero" |
7a768814 RS |
736 | [(set (match_operand:SI 0 "register_operand" "=r") |
737 | (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r") | |
738 | (const_int 0)))) | |
45a7dd80 | 739 | (clobber (reg:CC CC_REG))] |
e6c1be7e | 740 | "" |
e0d80184 | 741 | "#" |
e0d80184 | 742 | "" |
45a7dd80 | 743 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
e0d80184 | 744 | (const_int 0))) |
45a7dd80 | 745 | (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))] |
b776892b | 746 | "" |
7fbb2f84 | 747 | [(set_attr "length" "2")]) |
44965bad | 748 | |
42e37616 | 749 | (define_insn_and_split "*neg_snesidi_zero" |
b776892b | 750 | [(set (match_operand:DI 0 "register_operand" "=r") |
42e37616 DM |
751 | (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r") |
752 | (const_int 0)))) | |
45a7dd80 | 753 | (clobber (reg:CC CC_REG))] |
71648202 | 754 | "TARGET_ARCH64" |
b776892b | 755 | "#" |
b776892b | 756 | "" |
42e37616 DM |
757 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
758 | (const_int 0))) | |
9aa6a9b5 DM |
759 | (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) |
760 | (const_int 0)))))] | |
761 | "" | |
762 | [(set_attr "length" "2")]) | |
763 | ||
b776892b | 764 | (define_insn_and_split "*snedi_zero" |
2808652a | 765 | [(set (match_operand:DI 0 "register_operand" "=&r") |
b776892b DM |
766 | (ne:DI (match_operand:DI 1 "register_operand" "r") |
767 | (const_int 0)))] | |
1864ee35 | 768 | "TARGET_ARCH64 && ! TARGET_VIS3" |
e0d80184 | 769 | "#" |
b776892b | 770 | "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" |
e0d80184 DM |
771 | [(set (match_dup 0) (const_int 0)) |
772 | (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1) | |
773 | (const_int 0)) | |
774 | (const_int 1) | |
775 | (match_dup 0)))] | |
b776892b DM |
776 | "" |
777 | [(set_attr "length" "2")]) | |
e0d80184 | 778 | |
1864ee35 DM |
779 | (define_insn_and_split "*snedi_zero_vis3" |
780 | [(set (match_operand:DI 0 "register_operand" "=r") | |
781 | (ne:DI (match_operand:DI 1 "register_operand" "r") | |
782 | (const_int 0))) | |
783 | (clobber (reg:CCX CC_REG))] | |
784 | "TARGET_ARCH64 && TARGET_VIS3" | |
785 | "#" | |
786 | "" | |
787 | [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1)) | |
788 | (const_int 0))) | |
789 | (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))] | |
790 | "" | |
791 | [(set_attr "length" "2")]) | |
792 | ||
b776892b | 793 | (define_insn_and_split "*neg_snedi_zero" |
2808652a | 794 | [(set (match_operand:DI 0 "register_operand" "=&r") |
b776892b DM |
795 | (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r") |
796 | (const_int 0))))] | |
fa0f39e4 | 797 | "TARGET_ARCH64" |
e0d80184 | 798 | "#" |
b776892b | 799 | "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" |
e0d80184 DM |
800 | [(set (match_dup 0) (const_int 0)) |
801 | (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1) | |
802 | (const_int 0)) | |
803 | (const_int -1) | |
804 | (match_dup 0)))] | |
b776892b DM |
805 | "" |
806 | [(set_attr "length" "2")]) | |
e0d80184 | 807 | |
b776892b | 808 | (define_insn_and_split "*snedi_zero_trunc" |
2808652a | 809 | [(set (match_operand:SI 0 "register_operand" "=&r") |
b776892b DM |
810 | (ne:SI (match_operand:DI 1 "register_operand" "r") |
811 | (const_int 0)))] | |
1864ee35 | 812 | "TARGET_ARCH64 && ! TARGET_VIS3" |
e0d80184 | 813 | "#" |
b776892b | 814 | "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" |
e0d80184 | 815 | [(set (match_dup 0) (const_int 0)) |
638e8b1f | 816 | (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1) |
e0d80184 DM |
817 | (const_int 0)) |
818 | (const_int 1) | |
819 | (match_dup 0)))] | |
b776892b DM |
820 | "" |
821 | [(set_attr "length" "2")]) | |
e0d80184 | 822 | |
1864ee35 DM |
823 | (define_insn_and_split "*snedi_zero_trunc_vis3" |
824 | [(set (match_operand:SI 0 "register_operand" "=r") | |
825 | (ne:SI (match_operand:DI 1 "register_operand" "r") | |
826 | (const_int 0))) | |
827 | (clobber (reg:CCX CC_REG))] | |
828 | "TARGET_ARCH64 && TARGET_VIS3" | |
829 | "#" | |
830 | "" | |
831 | [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1)) | |
832 | (const_int 0))) | |
833 | (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))] | |
834 | "" | |
835 | [(set_attr "length" "2")]) | |
836 | ||
42e37616 DM |
837 | (define_insn_and_split "*seqsi<P:mode>_zero" |
838 | [(set (match_operand:P 0 "register_operand" "=r") | |
839 | (eq:P (match_operand:SI 1 "register_operand" "r") | |
a8d2b752 | 840 | (const_int 0))) |
45a7dd80 | 841 | (clobber (reg:CC CC_REG))] |
e6c1be7e | 842 | "" |
e0d80184 | 843 | "#" |
e0d80184 | 844 | "" |
45a7dd80 | 845 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
e0d80184 | 846 | (const_int 0))) |
42e37616 | 847 | (set (match_dup 0) (geu:P (reg:CC CC_REG) (const_int 0)))] |
b776892b DM |
848 | "" |
849 | [(set_attr "length" "2")]) | |
7a768814 | 850 | |
42e37616 | 851 | (define_insn_and_split "*neg_seqsisi_zero" |
7a768814 RS |
852 | [(set (match_operand:SI 0 "register_operand" "=r") |
853 | (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r") | |
854 | (const_int 0)))) | |
45a7dd80 | 855 | (clobber (reg:CC CC_REG))] |
e6c1be7e | 856 | "" |
e0d80184 | 857 | "#" |
e0d80184 | 858 | "" |
45a7dd80 | 859 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
e0d80184 | 860 | (const_int 0))) |
45a7dd80 | 861 | (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))] |
b776892b | 862 | "" |
7fbb2f84 | 863 | [(set_attr "length" "2")]) |
44965bad | 864 | |
42e37616 | 865 | (define_insn_and_split "*neg_seqsidi_zero" |
9aa6a9b5 DM |
866 | [(set (match_operand:DI 0 "register_operand" "=r") |
867 | (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r") | |
868 | (const_int 0)))) | |
869 | (clobber (reg:CC CC_REG))] | |
870 | "TARGET_ARCH64" | |
871 | "#" | |
872 | "&& 1" | |
873 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) | |
874 | (const_int 0))) | |
875 | (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) | |
876 | (const_int 0)))))] | |
877 | "" | |
878 | [(set_attr "length" "2")]) | |
879 | ||
b776892b | 880 | (define_insn_and_split "*seqdi_zero" |
2808652a | 881 | [(set (match_operand:DI 0 "register_operand" "=&r") |
b776892b DM |
882 | (eq:DI (match_operand:DI 1 "register_operand" "r") |
883 | (const_int 0)))] | |
fa0f39e4 | 884 | "TARGET_ARCH64" |
e0d80184 | 885 | "#" |
b776892b | 886 | "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" |
e0d80184 DM |
887 | [(set (match_dup 0) (const_int 0)) |
888 | (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1) | |
889 | (const_int 0)) | |
890 | (const_int 1) | |
891 | (match_dup 0)))] | |
b776892b DM |
892 | "" |
893 | [(set_attr "length" "2")]) | |
e0d80184 | 894 | |
b776892b | 895 | (define_insn_and_split "*neg_seqdi_zero" |
2808652a | 896 | [(set (match_operand:DI 0 "register_operand" "=&r") |
b776892b DM |
897 | (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r") |
898 | (const_int 0))))] | |
fa0f39e4 | 899 | "TARGET_ARCH64" |
e0d80184 | 900 | "#" |
b776892b | 901 | "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" |
e0d80184 DM |
902 | [(set (match_dup 0) (const_int 0)) |
903 | (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1) | |
904 | (const_int 0)) | |
905 | (const_int -1) | |
906 | (match_dup 0)))] | |
b776892b DM |
907 | "" |
908 | [(set_attr "length" "2")]) | |
e0d80184 | 909 | |
b776892b | 910 | (define_insn_and_split "*seqdi_zero_trunc" |
2808652a | 911 | [(set (match_operand:SI 0 "register_operand" "=&r") |
b776892b DM |
912 | (eq:SI (match_operand:DI 1 "register_operand" "r") |
913 | (const_int 0)))] | |
fa0f39e4 | 914 | "TARGET_ARCH64" |
e0d80184 | 915 | "#" |
b776892b | 916 | "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" |
e0d80184 | 917 | [(set (match_dup 0) (const_int 0)) |
638e8b1f | 918 | (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1) |
e0d80184 DM |
919 | (const_int 0)) |
920 | (const_int 1) | |
921 | (match_dup 0)))] | |
b776892b DM |
922 | "" |
923 | [(set_attr "length" "2")]) | |
e0d80184 | 924 | |
7a768814 | 925 | ;; We can also do (x + (i == 0)) and related, so put them in. |
a8d2b752 DE |
926 | ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode |
927 | ;; versions for v9. | |
7a768814 | 928 | |
b776892b | 929 | (define_insn_and_split "*x_plus_i_ne_0" |
7a768814 RS |
930 | [(set (match_operand:SI 0 "register_operand" "=r") |
931 | (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r") | |
932 | (const_int 0)) | |
933 | (match_operand:SI 2 "register_operand" "r"))) | |
45a7dd80 | 934 | (clobber (reg:CC CC_REG))] |
e6c1be7e | 935 | "" |
e0d80184 | 936 | "#" |
e6c1be7e | 937 | "" |
45a7dd80 | 938 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
e0d80184 | 939 | (const_int 0))) |
45a7dd80 | 940 | (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) |
e0d80184 | 941 | (match_dup 2)))] |
b776892b DM |
942 | "" |
943 | [(set_attr "length" "2")]) | |
e0d80184 | 944 | |
b776892b | 945 | (define_insn_and_split "*x_minus_i_ne_0" |
7a768814 RS |
946 | [(set (match_operand:SI 0 "register_operand" "=r") |
947 | (minus:SI (match_operand:SI 2 "register_operand" "r") | |
948 | (ne:SI (match_operand:SI 1 "register_operand" "r") | |
949 | (const_int 0)))) | |
45a7dd80 | 950 | (clobber (reg:CC CC_REG))] |
e6c1be7e | 951 | "" |
e0d80184 | 952 | "#" |
e6c1be7e | 953 | "" |
45a7dd80 | 954 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
e0d80184 DM |
955 | (const_int 0))) |
956 | (set (match_dup 0) (minus:SI (match_dup 2) | |
45a7dd80 | 957 | (ltu:SI (reg:CC CC_REG) (const_int 0))))] |
b776892b DM |
958 | "" |
959 | [(set_attr "length" "2")]) | |
e0d80184 | 960 | |
b776892b | 961 | (define_insn_and_split "*x_plus_i_eq_0" |
7a768814 RS |
962 | [(set (match_operand:SI 0 "register_operand" "=r") |
963 | (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r") | |
964 | (const_int 0)) | |
965 | (match_operand:SI 2 "register_operand" "r"))) | |
45a7dd80 | 966 | (clobber (reg:CC CC_REG))] |
e6c1be7e | 967 | "" |
e0d80184 | 968 | "#" |
e6c1be7e | 969 | "" |
45a7dd80 | 970 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
e0d80184 | 971 | (const_int 0))) |
45a7dd80 | 972 | (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0)) |
e0d80184 | 973 | (match_dup 2)))] |
b776892b DM |
974 | "" |
975 | [(set_attr "length" "2")]) | |
e0d80184 | 976 | |
b776892b | 977 | (define_insn_and_split "*x_minus_i_eq_0" |
7a768814 RS |
978 | [(set (match_operand:SI 0 "register_operand" "=r") |
979 | (minus:SI (match_operand:SI 2 "register_operand" "r") | |
980 | (eq:SI (match_operand:SI 1 "register_operand" "r") | |
981 | (const_int 0)))) | |
45a7dd80 | 982 | (clobber (reg:CC CC_REG))] |
e6c1be7e | 983 | "" |
e0d80184 | 984 | "#" |
e6c1be7e | 985 | "" |
45a7dd80 | 986 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
e0d80184 DM |
987 | (const_int 0))) |
988 | (set (match_dup 0) (minus:SI (match_dup 2) | |
45a7dd80 | 989 | (geu:SI (reg:CC CC_REG) (const_int 0))))] |
b776892b DM |
990 | "" |
991 | [(set_attr "length" "2")]) | |
e0d80184 | 992 | |
a8d2b752 DE |
993 | ;; We can also do GEU and LTU directly, but these operate after a compare. |
994 | ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode | |
995 | ;; versions for v9. | |
7a768814 | 996 | |
42e37616 DM |
997 | (define_insn "*sltu<P:mode>_insn" |
998 | [(set (match_operand:P 0 "register_operand" "=r") | |
999 | (ltu:P (reg:CC CC_REG) (const_int 0)))] | |
e6c1be7e | 1000 | "" |
16b46035 | 1001 | "addx\t%%g0, 0, %0" |
c6172f14 | 1002 | [(set_attr "type" "ialuX")]) |
7a768814 | 1003 | |
1864ee35 DM |
1004 | (define_insn "*sltu_insn_vis3" |
1005 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1006 | (ltu:DI (reg:CCX CC_REG) (const_int 0)))] | |
1007 | "TARGET_ARCH64 && TARGET_VIS3" | |
1008 | "addxc\t%%g0, %%g0, %0" | |
1009 | [(set_attr "type" "ialuX")]) | |
1010 | ||
1011 | (define_insn "*sltu_insn_vis3_trunc" | |
1012 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1013 | (ltu:SI (reg:CCX CC_REG) (const_int 0)))] | |
1014 | "TARGET_ARCH64 && TARGET_VIS3" | |
1015 | "addxc\t%%g0, %%g0, %0" | |
1016 | [(set_attr "type" "ialuX")]) | |
1017 | ||
42e37616 | 1018 | (define_insn "*neg_sltusi_insn" |
7a768814 | 1019 | [(set (match_operand:SI 0 "register_operand" "=r") |
45a7dd80 | 1020 | (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))] |
e6c1be7e | 1021 | "" |
16b46035 | 1022 | "subx\t%%g0, 0, %0" |
c6172f14 | 1023 | [(set_attr "type" "ialuX")]) |
7a768814 | 1024 | |
42e37616 | 1025 | (define_insn "*neg_sltudi_insn" |
9aa6a9b5 DM |
1026 | [(set (match_operand:DI 0 "register_operand" "=r") |
1027 | (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))] | |
1028 | "TARGET_ARCH64" | |
1029 | "subx\t%%g0, 0, %0" | |
1030 | [(set_attr "type" "ialuX")]) | |
1031 | ||
c8b3b7d6 | 1032 | (define_insn "*neg_sltu_minus_x" |
7a768814 | 1033 | [(set (match_operand:SI 0 "register_operand" "=r") |
45a7dd80 | 1034 | (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))) |
7a768814 | 1035 | (match_operand:SI 1 "arith_operand" "rI")))] |
e6c1be7e | 1036 | "" |
16b46035 | 1037 | "subx\t%%g0, %1, %0" |
c6172f14 | 1038 | [(set_attr "type" "ialuX")]) |
7a768814 | 1039 | |
c8b3b7d6 | 1040 | (define_insn "*neg_sltu_plus_x" |
7a768814 | 1041 | [(set (match_operand:SI 0 "register_operand" "=r") |
45a7dd80 | 1042 | (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) |
7a768814 | 1043 | (match_operand:SI 1 "arith_operand" "rI"))))] |
e6c1be7e | 1044 | "" |
16b46035 | 1045 | "subx\t%%g0, %1, %0" |
c6172f14 | 1046 | [(set_attr "type" "ialuX")]) |
7a768814 | 1047 | |
42e37616 DM |
1048 | (define_insn "*sgeu<P:mode>_insn" |
1049 | [(set (match_operand:P 0 "register_operand" "=r") | |
1050 | (geu:P (reg:CC CC_REG) (const_int 0)))] | |
e6c1be7e | 1051 | "" |
16b46035 | 1052 | "subx\t%%g0, -1, %0" |
c6172f14 | 1053 | [(set_attr "type" "ialuX")]) |
7a768814 | 1054 | |
42e37616 | 1055 | (define_insn "*neg_sgeusi_insn" |
7a768814 | 1056 | [(set (match_operand:SI 0 "register_operand" "=r") |
45a7dd80 | 1057 | (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))] |
e6c1be7e | 1058 | "" |
16b46035 | 1059 | "addx\t%%g0, -1, %0" |
c6172f14 | 1060 | [(set_attr "type" "ialuX")]) |
7a768814 | 1061 | |
42e37616 | 1062 | (define_insn "*neg_sgeudi_insn" |
9aa6a9b5 DM |
1063 | [(set (match_operand:DI 0 "register_operand" "=r") |
1064 | (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))] | |
1065 | "TARGET_ARCH64" | |
1066 | "addx\t%%g0, -1, %0" | |
1067 | [(set_attr "type" "ialuX")]) | |
1068 | ||
7a768814 | 1069 | ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in. |
a8d2b752 DE |
1070 | ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode |
1071 | ;; versions for v9. | |
7a768814 | 1072 | |
c8b3b7d6 | 1073 | (define_insn "*sltu_plus_x" |
7a768814 | 1074 | [(set (match_operand:SI 0 "register_operand" "=r") |
45a7dd80 | 1075 | (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) |
7a768814 | 1076 | (match_operand:SI 1 "arith_operand" "rI")))] |
e6c1be7e | 1077 | "" |
16b46035 | 1078 | "addx\t%%g0, %1, %0" |
c6172f14 | 1079 | [(set_attr "type" "ialuX")]) |
7a768814 | 1080 | |
c8b3b7d6 | 1081 | (define_insn "*sltu_plus_x_plus_y" |
7a768814 | 1082 | [(set (match_operand:SI 0 "register_operand" "=r") |
45a7dd80 | 1083 | (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) |
7a768814 RS |
1084 | (plus:SI (match_operand:SI 1 "arith_operand" "%r") |
1085 | (match_operand:SI 2 "arith_operand" "rI"))))] | |
1086 | "" | |
16b46035 | 1087 | "addx\t%1, %2, %0" |
c6172f14 | 1088 | [(set_attr "type" "ialuX")]) |
7a768814 | 1089 | |
c8b3b7d6 | 1090 | (define_insn "*x_minus_sltu" |
7a768814 RS |
1091 | [(set (match_operand:SI 0 "register_operand" "=r") |
1092 | (minus:SI (match_operand:SI 1 "register_operand" "r") | |
45a7dd80 | 1093 | (ltu:SI (reg:CC CC_REG) (const_int 0))))] |
7a768814 | 1094 | "" |
16b46035 | 1095 | "subx\t%1, 0, %0" |
c6172f14 | 1096 | [(set_attr "type" "ialuX")]) |
7a768814 RS |
1097 | |
1098 | ;; ??? Combine should canonicalize these next two to the same pattern. | |
c8b3b7d6 | 1099 | (define_insn "*x_minus_y_minus_sltu" |
7a768814 | 1100 | [(set (match_operand:SI 0 "register_operand" "=r") |
0e5d569c | 1101 | (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") |
7a768814 | 1102 | (match_operand:SI 2 "arith_operand" "rI")) |
45a7dd80 | 1103 | (ltu:SI (reg:CC CC_REG) (const_int 0))))] |
7a768814 | 1104 | "" |
16b46035 | 1105 | "subx\t%r1, %2, %0" |
c6172f14 | 1106 | [(set_attr "type" "ialuX")]) |
7a768814 | 1107 | |
c8b3b7d6 | 1108 | (define_insn "*x_minus_sltu_plus_y" |
7a768814 | 1109 | [(set (match_operand:SI 0 "register_operand" "=r") |
0e5d569c | 1110 | (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") |
45a7dd80 | 1111 | (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) |
7a768814 RS |
1112 | (match_operand:SI 2 "arith_operand" "rI"))))] |
1113 | "" | |
16b46035 | 1114 | "subx\t%r1, %2, %0" |
c6172f14 | 1115 | [(set_attr "type" "ialuX")]) |
7a768814 | 1116 | |
c8b3b7d6 | 1117 | (define_insn "*sgeu_plus_x" |
7a768814 | 1118 | [(set (match_operand:SI 0 "register_operand" "=r") |
45a7dd80 | 1119 | (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0)) |
7a768814 RS |
1120 | (match_operand:SI 1 "register_operand" "r")))] |
1121 | "" | |
16b46035 | 1122 | "subx\t%1, -1, %0" |
c6172f14 | 1123 | [(set_attr "type" "ialuX")]) |
7a768814 | 1124 | |
c8b3b7d6 | 1125 | (define_insn "*x_minus_sgeu" |
7a768814 RS |
1126 | [(set (match_operand:SI 0 "register_operand" "=r") |
1127 | (minus:SI (match_operand:SI 1 "register_operand" "r") | |
45a7dd80 | 1128 | (geu:SI (reg:CC CC_REG) (const_int 0))))] |
7a768814 | 1129 | "" |
16b46035 | 1130 | "addx\t%1, -1, %0" |
c6172f14 | 1131 | [(set_attr "type" "ialuX")]) |
a8d2b752 | 1132 | |
c6b0465b | 1133 | (define_split |
f7df2b9d | 1134 | [(set (match_operand:SI 0 "register_operand" "") |
0e5d569c EB |
1135 | (match_operator:SI 2 "noov_compare_operator" |
1136 | [(match_operand 1 "icc_or_fcc_register_operand" "") | |
c6b0465b | 1137 | (const_int 0)]))] |
ba652ba9 EB |
1138 | "TARGET_V9 |
1139 | && REGNO (operands[1]) == SPARC_ICC_REG | |
c6b0465b | 1140 | && (GET_MODE (operands[1]) == CCXmode |
a7b376ee | 1141 | /* 32-bit LTU/GEU are better implemented using addx/subx. */ |
c6b0465b JC |
1142 | || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))" |
1143 | [(set (match_dup 0) (const_int 0)) | |
1144 | (set (match_dup 0) | |
1145 | (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)]) | |
1146 | (const_int 1) | |
1147 | (match_dup 0)))] | |
1148 | "") | |
1149 | ||
7a768814 RS |
1150 | \f |
1151 | ;; These control RTL generation for conditional jump insns | |
1152 | ||
f90b7a5a | 1153 | (define_expand "cbranchcc4" |
7a768814 | 1154 | [(set (pc) |
f90b7a5a PB |
1155 | (if_then_else (match_operator 0 "comparison_operator" |
1156 | [(match_operand 1 "compare_operand" "") | |
1157 | (match_operand 2 "const_zero_operand" "")]) | |
1158 | (label_ref (match_operand 3 "" "")) | |
7a768814 RS |
1159 | (pc)))] |
1160 | "" | |
f90b7a5a | 1161 | "") |
e267e177 | 1162 | |
f90b7a5a PB |
1163 | (define_expand "cbranchsi4" |
1164 | [(use (match_operator 0 "comparison_operator" | |
1165 | [(match_operand:SI 1 "compare_operand" "") | |
1166 | (match_operand:SI 2 "arith_operand" "")])) | |
1167 | (use (match_operand 3 ""))] | |
e267e177 | 1168 | "" |
e267e177 | 1169 | { |
f90b7a5a PB |
1170 | if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx) |
1171 | operands[1] = force_reg (SImode, operands[1]); | |
1172 | emit_conditional_branch_insn (operands); | |
1173 | DONE; | |
563facba | 1174 | }) |
e267e177 | 1175 | |
f90b7a5a PB |
1176 | (define_expand "cbranchdi4" |
1177 | [(use (match_operator 0 "comparison_operator" | |
1178 | [(match_operand:DI 1 "compare_operand" "") | |
1179 | (match_operand:DI 2 "arith_operand" "")])) | |
1180 | (use (match_operand 3 ""))] | |
1181 | "TARGET_ARCH64" | |
e267e177 | 1182 | { |
f90b7a5a PB |
1183 | if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx) |
1184 | operands[1] = force_reg (DImode, operands[1]); | |
1185 | emit_conditional_branch_insn (operands); | |
1186 | DONE; | |
563facba | 1187 | }) |
e267e177 | 1188 | |
f90b7a5a PB |
1189 | (define_expand "cbranch<F:mode>4" |
1190 | [(use (match_operator 0 "comparison_operator" | |
1191 | [(match_operand:F 1 "register_operand" "") | |
1192 | (match_operand:F 2 "register_operand" "")])) | |
1193 | (use (match_operand 3 ""))] | |
1194 | "TARGET_FPU" | |
1195 | { emit_conditional_branch_insn (operands); DONE; }) | |
e267e177 | 1196 | |
7913f3d0 | 1197 | |
7a768814 RS |
1198 | ;; Now match both normal and inverted jump. |
1199 | ||
e0d80184 | 1200 | ;; XXX fpcmp nop braindamage |
c8b3b7d6 | 1201 | (define_insn "*normal_branch" |
7a768814 | 1202 | [(set (pc) |
0e5d569c | 1203 | (if_then_else (match_operator 0 "noov_compare_operator" |
45a7dd80 | 1204 | [(reg CC_REG) (const_int 0)]) |
7a768814 RS |
1205 | (label_ref (match_operand 1 "" "")) |
1206 | (pc)))] | |
1207 | "" | |
7a768814 | 1208 | { |
0b82d204 | 1209 | return output_cbranch (operands[0], operands[1], 1, 0, |
7a768814 | 1210 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
4e5b002b | 1211 | insn); |
563facba | 1212 | } |
0b82d204 | 1213 | [(set_attr "type" "branch") |
f17f9332 | 1214 | (set_attr "branch_type" "icc")]) |
7a768814 | 1215 | |
e0d80184 | 1216 | ;; XXX fpcmp nop braindamage |
c8b3b7d6 | 1217 | (define_insn "*inverted_branch" |
7a768814 | 1218 | [(set (pc) |
0e5d569c | 1219 | (if_then_else (match_operator 0 "noov_compare_operator" |
45a7dd80 | 1220 | [(reg CC_REG) (const_int 0)]) |
7a768814 RS |
1221 | (pc) |
1222 | (label_ref (match_operand 1 "" ""))))] | |
1223 | "" | |
7a768814 | 1224 | { |
0b82d204 | 1225 | return output_cbranch (operands[0], operands[1], 1, 1, |
7a768814 | 1226 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
4e5b002b | 1227 | insn); |
563facba | 1228 | } |
0b82d204 | 1229 | [(set_attr "type" "branch") |
f17f9332 | 1230 | (set_attr "branch_type" "icc")]) |
7a768814 | 1231 | |
e0d80184 | 1232 | ;; XXX fpcmp nop braindamage |
c4ce6853 | 1233 | (define_insn "*normal_fp_branch" |
a8d2b752 | 1234 | [(set (pc) |
c4ce6853 | 1235 | (if_then_else (match_operator 1 "comparison_operator" |
0e5d569c | 1236 | [(match_operand:CCFP 0 "fcc_register_operand" "c") |
a8d2b752 DE |
1237 | (const_int 0)]) |
1238 | (label_ref (match_operand 2 "" "")) | |
1239 | (pc)))] | |
c4ce6853 | 1240 | "" |
6a4bb1fa | 1241 | { |
0b82d204 | 1242 | return output_cbranch (operands[1], operands[2], 2, 0, |
a8d2b752 | 1243 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
4e5b002b | 1244 | insn); |
563facba | 1245 | } |
0b82d204 | 1246 | [(set_attr "type" "branch") |
f17f9332 | 1247 | (set_attr "branch_type" "fcc")]) |
6a4bb1fa | 1248 | |
e0d80184 | 1249 | ;; XXX fpcmp nop braindamage |
c4ce6853 | 1250 | (define_insn "*inverted_fp_branch" |
a8d2b752 | 1251 | [(set (pc) |
c4ce6853 | 1252 | (if_then_else (match_operator 1 "comparison_operator" |
0e5d569c | 1253 | [(match_operand:CCFP 0 "fcc_register_operand" "c") |
a8d2b752 DE |
1254 | (const_int 0)]) |
1255 | (pc) | |
1256 | (label_ref (match_operand 2 "" ""))))] | |
c4ce6853 | 1257 | "" |
a8d2b752 | 1258 | { |
0b82d204 | 1259 | return output_cbranch (operands[1], operands[2], 2, 1, |
a8d2b752 | 1260 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
4e5b002b | 1261 | insn); |
563facba | 1262 | } |
0b82d204 | 1263 | [(set_attr "type" "branch") |
f17f9332 | 1264 | (set_attr "branch_type" "fcc")]) |
6a4bb1fa | 1265 | |
e0d80184 | 1266 | ;; XXX fpcmp nop braindamage |
c4ce6853 | 1267 | (define_insn "*normal_fpe_branch" |
a8d2b752 | 1268 | [(set (pc) |
c4ce6853 | 1269 | (if_then_else (match_operator 1 "comparison_operator" |
0e5d569c | 1270 | [(match_operand:CCFPE 0 "fcc_register_operand" "c") |
a8d2b752 DE |
1271 | (const_int 0)]) |
1272 | (label_ref (match_operand 2 "" "")) | |
1273 | (pc)))] | |
c4ce6853 | 1274 | "" |
a8d2b752 | 1275 | { |
0b82d204 | 1276 | return output_cbranch (operands[1], operands[2], 2, 0, |
a8d2b752 | 1277 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
4e5b002b | 1278 | insn); |
563facba | 1279 | } |
0b82d204 | 1280 | [(set_attr "type" "branch") |
f17f9332 | 1281 | (set_attr "branch_type" "fcc")]) |
6a4bb1fa | 1282 | |
e0d80184 | 1283 | ;; XXX fpcmp nop braindamage |
c4ce6853 | 1284 | (define_insn "*inverted_fpe_branch" |
a8d2b752 | 1285 | [(set (pc) |
c4ce6853 | 1286 | (if_then_else (match_operator 1 "comparison_operator" |
0e5d569c | 1287 | [(match_operand:CCFPE 0 "fcc_register_operand" "c") |
a8d2b752 DE |
1288 | (const_int 0)]) |
1289 | (pc) | |
1290 | (label_ref (match_operand 2 "" ""))))] | |
c4ce6853 | 1291 | "" |
a8d2b752 | 1292 | { |
0b82d204 | 1293 | return output_cbranch (operands[1], operands[2], 2, 1, |
a8d2b752 | 1294 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
4e5b002b | 1295 | insn); |
563facba | 1296 | } |
0b82d204 | 1297 | [(set_attr "type" "branch") |
f17f9332 | 1298 | (set_attr "branch_type" "fcc")]) |
6a4bb1fa | 1299 | |
56149abc | 1300 | ;; SPARC V9-specific jump insns. None of these are guaranteed to be |
a8d2b752 DE |
1301 | ;; in the architecture. |
1302 | ||
8b98b5fd DM |
1303 | (define_insn "*cbcond_sp32" |
1304 | [(set (pc) | |
1305 | (if_then_else (match_operator 0 "noov_compare_operator" | |
1306 | [(match_operand:SI 1 "register_operand" "r") | |
1307 | (match_operand:SI 2 "arith5_operand" "rA")]) | |
1308 | (label_ref (match_operand 3 "" "")) | |
1309 | (pc)))] | |
1310 | "TARGET_CBCOND" | |
1311 | { | |
1312 | return output_cbcond (operands[0], operands[3], insn); | |
1313 | } | |
1314 | [(set_attr "type" "cbcond")]) | |
1315 | ||
1316 | (define_insn "*cbcond_sp64" | |
1317 | [(set (pc) | |
1318 | (if_then_else (match_operator 0 "noov_compare_operator" | |
1319 | [(match_operand:DI 1 "register_operand" "r") | |
1320 | (match_operand:DI 2 "arith5_operand" "rA")]) | |
1321 | (label_ref (match_operand 3 "" "")) | |
1322 | (pc)))] | |
1323 | "TARGET_ARCH64 && TARGET_CBCOND" | |
1324 | { | |
1325 | return output_cbcond (operands[0], operands[3], insn); | |
1326 | } | |
1327 | [(set_attr "type" "cbcond")]) | |
1328 | ||
a8d2b752 DE |
1329 | ;; There are no 32 bit brreg insns. |
1330 | ||
e0d80184 | 1331 | ;; XXX |
c8b3b7d6 | 1332 | (define_insn "*normal_int_branch_sp64" |
a8d2b752 | 1333 | [(set (pc) |
0e5d569c | 1334 | (if_then_else (match_operator 0 "v9_register_compare_operator" |
a8d2b752 DE |
1335 | [(match_operand:DI 1 "register_operand" "r") |
1336 | (const_int 0)]) | |
1337 | (label_ref (match_operand 2 "" "")) | |
1338 | (pc)))] | |
fa0f39e4 | 1339 | "TARGET_ARCH64" |
6a4bb1fa | 1340 | { |
0b82d204 | 1341 | return output_v9branch (operands[0], operands[2], 1, 2, 0, |
a8d2b752 | 1342 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
4e5b002b | 1343 | insn); |
563facba | 1344 | } |
0b82d204 | 1345 | [(set_attr "type" "branch") |
f17f9332 | 1346 | (set_attr "branch_type" "reg")]) |
6a4bb1fa | 1347 | |
e0d80184 | 1348 | ;; XXX |
c8b3b7d6 | 1349 | (define_insn "*inverted_int_branch_sp64" |
a8d2b752 | 1350 | [(set (pc) |
0e5d569c | 1351 | (if_then_else (match_operator 0 "v9_register_compare_operator" |
a8d2b752 DE |
1352 | [(match_operand:DI 1 "register_operand" "r") |
1353 | (const_int 0)]) | |
1354 | (pc) | |
1355 | (label_ref (match_operand 2 "" ""))))] | |
fa0f39e4 | 1356 | "TARGET_ARCH64" |
a8d2b752 | 1357 | { |
0b82d204 | 1358 | return output_v9branch (operands[0], operands[2], 1, 2, 1, |
a8d2b752 | 1359 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
4e5b002b | 1360 | insn); |
563facba | 1361 | } |
0b82d204 | 1362 | [(set_attr "type" "branch") |
f17f9332 | 1363 | (set_attr "branch_type" "reg")]) |
f8ece000 EB |
1364 | |
1365 | ||
ef573211 EB |
1366 | ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic |
1367 | ;; value subject to a PC-relative relocation. Operand 2 is a helper function | |
a6fed83f | 1368 | ;; that adds the PC value at the call point to register #(operand 3). |
3ed27cf5 DM |
1369 | ;; |
1370 | ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..." | |
1371 | ;; because the RDPC instruction is extremely expensive and incurs a complete | |
1372 | ;; instruction pipeline flush. | |
6a4bb1fa | 1373 | |
eb7a7903 EB |
1374 | (define_insn "load_pcrel_sym<P:mode>" |
1375 | [(set (match_operand:P 0 "register_operand" "=r") | |
1376 | (unspec:P [(match_operand:P 1 "symbolic_operand" "") | |
a6fed83f EB |
1377 | (match_operand:P 2 "call_address_operand" "") |
1378 | (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM)) | |
45a7dd80 | 1379 | (clobber (reg:P O7_REG))] |
a6fed83f | 1380 | "REGNO (operands[0]) == INTVAL (operands[3])" |
951661a1 EB |
1381 | { |
1382 | if (flag_delayed_branch) | |
1383 | return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0"; | |
1384 | else | |
1385 | return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop"; | |
1386 | } | |
1387 | [(set (attr "type") (const_string "multi")) | |
1388 | (set (attr "length") | |
1389 | (if_then_else (eq_attr "delayed_branch" "true") | |
1390 | (const_int 3) | |
1391 | (const_int 4)))]) | |
f8ece000 EB |
1392 | |
1393 | ||
1394 | ;; Integer move instructions | |
7a768814 | 1395 | |
e0d80184 | 1396 | (define_expand "movqi" |
bea5071f | 1397 | [(set (match_operand:QI 0 "nonimmediate_operand" "") |
e0d80184 DM |
1398 | (match_operand:QI 1 "general_operand" ""))] |
1399 | "" | |
e0d80184 | 1400 | { |
bea5071f EB |
1401 | if (sparc_expand_move (QImode, operands)) |
1402 | DONE; | |
563facba | 1403 | }) |
e0d80184 DM |
1404 | |
1405 | (define_insn "*movqi_insn" | |
db7eb3e8 | 1406 | [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m") |
e0d80184 DM |
1407 | (match_operand:QI 1 "input_operand" "rI,m,rJ"))] |
1408 | "(register_operand (operands[0], QImode) | |
0e5d569c | 1409 | || register_or_zero_operand (operands[1], QImode))" |
e0d80184 | 1410 | "@ |
16b46035 DM |
1411 | mov\t%1, %0 |
1412 | ldub\t%1, %0 | |
1413 | stb\t%r1, %0" | |
fae15c93 VM |
1414 | [(set_attr "type" "*,load,store") |
1415 | (set_attr "us3load_type" "*,3cycle,*")]) | |
e0d80184 DM |
1416 | |
1417 | (define_expand "movhi" | |
bea5071f | 1418 | [(set (match_operand:HI 0 "nonimmediate_operand" "") |
e0d80184 DM |
1419 | (match_operand:HI 1 "general_operand" ""))] |
1420 | "" | |
95726648 | 1421 | { |
bea5071f EB |
1422 | if (sparc_expand_move (HImode, operands)) |
1423 | DONE; | |
563facba | 1424 | }) |
a8d2b752 | 1425 | |
e0d80184 | 1426 | (define_insn "*movhi_insn" |
db7eb3e8 | 1427 | [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") |
e0d80184 DM |
1428 | (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))] |
1429 | "(register_operand (operands[0], HImode) | |
0e5d569c | 1430 | || register_or_zero_operand (operands[1], HImode))" |
e0d80184 | 1431 | "@ |
16b46035 DM |
1432 | mov\t%1, %0 |
1433 | sethi\t%%hi(%a1), %0 | |
1434 | lduh\t%1, %0 | |
1435 | sth\t%r1, %0" | |
fae15c93 VM |
1436 | [(set_attr "type" "*,*,load,store") |
1437 | (set_attr "us3load_type" "*,*,3cycle,*")]) | |
e0d80184 | 1438 | |
71648202 | 1439 | ;; We always work with constants here. |
e0d80184 | 1440 | (define_insn "*movhi_lo_sum" |
200d7a32 | 1441 | [(set (match_operand:HI 0 "register_operand" "=r") |
5fddd9fe | 1442 | (ior:HI (match_operand:HI 1 "register_operand" "%r") |
0e5d569c | 1443 | (match_operand:HI 2 "small_int_operand" "I")))] |
e0d80184 | 1444 | "" |
16b46035 | 1445 | "or\t%1, %2, %0") |
200d7a32 | 1446 | |
e0d80184 | 1447 | (define_expand "movsi" |
bea5071f | 1448 | [(set (match_operand:SI 0 "nonimmediate_operand" "") |
e0d80184 DM |
1449 | (match_operand:SI 1 "general_operand" ""))] |
1450 | "" | |
a8d2b752 | 1451 | { |
bea5071f EB |
1452 | if (sparc_expand_move (SImode, operands)) |
1453 | DONE; | |
563facba | 1454 | }) |
e0d80184 | 1455 | |
1b43bc82 | 1456 | (define_insn "*movsi_insn" |
bb12a72a DM |
1457 | [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d") |
1458 | (match_operand:SI 1 "input_operand" "rI,K,m,rJ,*f, r, f, m,*f,J,P"))] | |
1b43bc82 DM |
1459 | "register_operand (operands[0], SImode) |
1460 | || register_or_zero_or_all_ones_operand (operands[1], SImode)" | |
bb12a72a DM |
1461 | "@ |
1462 | mov\t%1, %0 | |
1463 | sethi\t%%hi(%a1), %0 | |
1464 | ld\t%1, %0 | |
1465 | st\t%r1, %0 | |
1466 | movstouw\t%1, %0 | |
1467 | movwtos\t%1, %0 | |
1468 | fmovs\t%1, %0 | |
1469 | ld\t%1, %0 | |
1470 | st\t%1, %0 | |
1471 | fzeros\t%0 | |
1472 | fones\t%0" | |
f298688c | 1473 | [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl") |
1b43bc82 | 1474 | (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")]) |
bb12a72a | 1475 | |
e0d80184 DM |
1476 | (define_insn "*movsi_lo_sum" |
1477 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1478 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
1479 | (match_operand:SI 2 "immediate_operand" "in")))] | |
1480 | "" | |
16b46035 | 1481 | "or\t%1, %%lo(%a2), %0") |
e0d80184 DM |
1482 | |
1483 | (define_insn "*movsi_high" | |
1484 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1485 | (high:SI (match_operand:SI 1 "immediate_operand" "in")))] | |
1486 | "" | |
16b46035 | 1487 | "sethi\t%%hi(%a1), %0") |
7a768814 | 1488 | |
e0d80184 DM |
1489 | ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC |
1490 | ;; so that CSE won't optimize the address computation away. | |
1491 | (define_insn "movsi_lo_sum_pic" | |
1492 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1493 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
4f4778ee | 1494 | (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))] |
e0d80184 | 1495 | "flag_pic" |
878ee0ab DM |
1496 | { |
1497 | #ifdef HAVE_AS_SPARC_GOTDATA_OP | |
1498 | return "xor\t%1, %%gdop_lox10(%a2), %0"; | |
1499 | #else | |
1500 | return "or\t%1, %%lo(%a2), %0"; | |
1501 | #endif | |
1502 | }) | |
a8d2b752 | 1503 | |
e0d80184 DM |
1504 | (define_insn "movsi_high_pic" |
1505 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4f4778ee | 1506 | (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))] |
e0d80184 | 1507 | "flag_pic && check_pic (1)" |
878ee0ab DM |
1508 | { |
1509 | #ifdef HAVE_AS_SPARC_GOTDATA_OP | |
1510 | return "sethi\t%%gdop_hix22(%a1), %0"; | |
1511 | #else | |
1512 | return "sethi\t%%hi(%a1), %0"; | |
1513 | #endif | |
1514 | }) | |
1515 | ||
1516 | (define_insn "movsi_pic_gotdata_op" | |
1517 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1518 | (unspec:SI [(match_operand:SI 1 "register_operand" "r") | |
1519 | (match_operand:SI 2 "register_operand" "r") | |
1520 | (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))] | |
1521 | "flag_pic && check_pic (1)" | |
1522 | { | |
1523 | #ifdef HAVE_AS_SPARC_GOTDATA_OP | |
1524 | return "ld\t[%1 + %2], %0, %%gdop(%a3)"; | |
1525 | #else | |
1526 | return "ld\t[%1 + %2], %0"; | |
1527 | #endif | |
1528 | } | |
1529 | [(set_attr "type" "load")]) | |
e0d80184 DM |
1530 | |
1531 | (define_expand "movsi_pic_label_ref" | |
1532 | [(set (match_dup 3) (high:SI | |
1533 | (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") | |
4f4778ee | 1534 | (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) |
e0d80184 | 1535 | (set (match_dup 4) (lo_sum:SI (match_dup 3) |
4f4778ee | 1536 | (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) |
e0d80184 DM |
1537 | (set (match_operand:SI 0 "register_operand" "=r") |
1538 | (minus:SI (match_dup 5) (match_dup 4)))] | |
1539 | "flag_pic" | |
a8d2b752 | 1540 | { |
e3b5732b | 1541 | crtl->uses_pic_offset_table = 1; |
563facba | 1542 | operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); |
b3a13419 | 1543 | if (!can_create_pseudo_p ()) |
7652adb5 JJ |
1544 | { |
1545 | operands[3] = operands[0]; | |
1546 | operands[4] = operands[0]; | |
1547 | } | |
1548 | else | |
1549 | { | |
1550 | operands[3] = gen_reg_rtx (SImode); | |
1551 | operands[4] = gen_reg_rtx (SImode); | |
1552 | } | |
e0d80184 | 1553 | operands[5] = pic_offset_table_rtx; |
563facba | 1554 | }) |
a8d2b752 | 1555 | |
e0d80184 DM |
1556 | (define_insn "*movsi_high_pic_label_ref" |
1557 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1558 | (high:SI | |
1559 | (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") | |
4f4778ee | 1560 | (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))] |
e0d80184 | 1561 | "flag_pic" |
16b46035 | 1562 | "sethi\t%%hi(%a2-(%a1-.)), %0") |
e0d80184 DM |
1563 | |
1564 | (define_insn "*movsi_lo_sum_pic_label_ref" | |
1565 | [(set (match_operand:SI 0 "register_operand" "=r") | |
67111044 | 1566 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") |
e0d80184 | 1567 | (unspec:SI [(match_operand:SI 2 "label_ref_operand" "") |
4f4778ee | 1568 | (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))] |
e0d80184 | 1569 | "flag_pic" |
16b46035 | 1570 | "or\t%1, %%lo(%a3-(%a2-.)), %0") |
e0d80184 | 1571 | |
1910440e RS |
1572 | ;; Set up the PIC register for VxWorks. |
1573 | ||
1574 | (define_expand "vxworks_load_got" | |
1575 | [(set (match_dup 0) | |
1576 | (high:SI (match_dup 1))) | |
1577 | (set (match_dup 0) | |
1578 | (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1)))) | |
1579 | (set (match_dup 0) | |
1580 | (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))] | |
1581 | "TARGET_VXWORKS_RTP" | |
1582 | { | |
1583 | operands[0] = pic_offset_table_rtx; | |
1584 | operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE); | |
1585 | operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX); | |
1586 | }) | |
1587 | ||
e0d80184 | 1588 | (define_expand "movdi" |
bea5071f | 1589 | [(set (match_operand:DI 0 "nonimmediate_operand" "") |
e0d80184 DM |
1590 | (match_operand:DI 1 "general_operand" ""))] |
1591 | "" | |
e0d80184 | 1592 | { |
bea5071f EB |
1593 | if (sparc_expand_move (DImode, operands)) |
1594 | DONE; | |
563facba | 1595 | }) |
e0d80184 | 1596 | |
88d0be17 | 1597 | ;; Be careful, fmovd does not exist when !v9. |
e0d80184 DM |
1598 | ;; We match MEM moves directly when we have correct even |
1599 | ;; numbered registers, but fall into splits otherwise. | |
1600 | ;; The constraint ordering here is really important to | |
1601 | ;; avoid insane problems in reload, especially for patterns | |
1602 | ;; of the form: | |
1603 | ;; | |
1604 | ;; (set (mem:DI (plus:SI (reg:SI 30 %fp) | |
1605 | ;; (const_int -5016))) | |
1606 | ;; (reg:DI 2 %g2)) | |
1607 | ;; | |
c453325c | 1608 | |
f8ece000 | 1609 | (define_insn "*movdi_insn_sp32" |
c453325c | 1610 | [(set (match_operand:DI 0 "nonimmediate_operand" |
aaa050aa | 1611 | "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e, r,?*f,?*e,?W,b,b") |
c453325c | 1612 | (match_operand:DI 1 "input_operand" |
aaa050aa | 1613 | " J,J,U,T,r,o,i,r,*f, T, o,*f, *e, *e,?*f, r, W,*e,J,P"))] |
f8ece000 | 1614 | "! TARGET_ARCH64 |
bb12a72a DM |
1615 | && (register_operand (operands[0], DImode) |
1616 | || register_or_zero_operand (operands[1], DImode))" | |
1617 | "@ | |
1618 | stx\t%%g0, %0 | |
1619 | # | |
1620 | std\t%1, %0 | |
1621 | ldd\t%1, %0 | |
1622 | # | |
1623 | # | |
1624 | # | |
1625 | # | |
1626 | std\t%1, %0 | |
1627 | ldd\t%1, %0 | |
1628 | # | |
1629 | # | |
1630 | fmovd\t%1, %0 | |
1631 | # | |
1632 | # | |
1b43bc82 | 1633 | # |
bb12a72a DM |
1634 | ldd\t%1, %0 |
1635 | std\t%1, %0 | |
1636 | fzero\t%0 | |
1637 | fone\t%0" | |
f298688c | 1638 | [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl") |
1b43bc82 DM |
1639 | (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*") |
1640 | (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double") | |
1641 | (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")]) | |
e0d80184 | 1642 | |
1b43bc82 | 1643 | (define_insn "*movdi_insn_sp64" |
bb12a72a DM |
1644 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b") |
1645 | (match_operand:DI 1 "input_operand" "rI,N,m,rJ,*e, r, *e, W,*e,J,P"))] | |
1646 | "TARGET_ARCH64 | |
bb12a72a DM |
1647 | && (register_operand (operands[0], DImode) |
1648 | || register_or_zero_or_all_ones_operand (operands[1], DImode))" | |
1649 | "@ | |
1650 | mov\t%1, %0 | |
1651 | sethi\t%%hi(%a1), %0 | |
1652 | ldx\t%1, %0 | |
1653 | stx\t%r1, %0 | |
1654 | movdtox\t%1, %0 | |
1655 | movxtod\t%1, %0 | |
1656 | fmovd\t%1, %0 | |
1657 | ldd\t%1, %0 | |
1658 | std\t%1, %0 | |
1659 | fzero\t%0 | |
1660 | fone\t%0" | |
f298688c | 1661 | [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl") |
1b43bc82 DM |
1662 | (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double") |
1663 | (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")]) | |
bb12a72a | 1664 | |
56420c2c DM |
1665 | (define_expand "movdi_pic_label_ref" |
1666 | [(set (match_dup 3) (high:DI | |
1667 | (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") | |
4f4778ee | 1668 | (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) |
56420c2c | 1669 | (set (match_dup 4) (lo_sum:DI (match_dup 3) |
4f4778ee | 1670 | (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) |
56420c2c DM |
1671 | (set (match_operand:DI 0 "register_operand" "=r") |
1672 | (minus:DI (match_dup 5) (match_dup 4)))] | |
1673 | "TARGET_ARCH64 && flag_pic" | |
e0d80184 | 1674 | { |
e3b5732b | 1675 | crtl->uses_pic_offset_table = 1; |
563facba | 1676 | operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); |
b3a13419 | 1677 | if (!can_create_pseudo_p ()) |
7652adb5 JJ |
1678 | { |
1679 | operands[3] = operands[0]; | |
1680 | operands[4] = operands[0]; | |
1681 | } | |
1682 | else | |
1683 | { | |
1684 | operands[3] = gen_reg_rtx (DImode); | |
1685 | operands[4] = gen_reg_rtx (DImode); | |
1686 | } | |
56420c2c | 1687 | operands[5] = pic_offset_table_rtx; |
563facba | 1688 | }) |
56420c2c DM |
1689 | |
1690 | (define_insn "*movdi_high_pic_label_ref" | |
1691 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1692 | (high:DI | |
1693 | (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") | |
4f4778ee | 1694 | (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))] |
56420c2c | 1695 | "TARGET_ARCH64 && flag_pic" |
16b46035 | 1696 | "sethi\t%%hi(%a2-(%a1-.)), %0") |
56420c2c DM |
1697 | |
1698 | (define_insn "*movdi_lo_sum_pic_label_ref" | |
1699 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1700 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
1701 | (unspec:DI [(match_operand:DI 2 "label_ref_operand" "") | |
4f4778ee | 1702 | (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))] |
56420c2c | 1703 | "TARGET_ARCH64 && flag_pic" |
16b46035 | 1704 | "or\t%1, %%lo(%a3-(%a2-.)), %0") |
a8d2b752 | 1705 | |
56149abc | 1706 | ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64 |
e0d80184 DM |
1707 | ;; in sparc.c to see what is going on here... PIC stuff comes first. |
1708 | ||
be3f1ff5 | 1709 | (define_insn "movdi_lo_sum_pic" |
e0d80184 | 1710 | [(set (match_operand:DI 0 "register_operand" "=r") |
638e8b1f | 1711 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") |
4f4778ee | 1712 | (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))] |
e0d80184 | 1713 | "TARGET_ARCH64 && flag_pic" |
878ee0ab DM |
1714 | { |
1715 | #ifdef HAVE_AS_SPARC_GOTDATA_OP | |
1716 | return "xor\t%1, %%gdop_lox10(%a2), %0"; | |
1717 | #else | |
1718 | return "or\t%1, %%lo(%a2), %0"; | |
1719 | #endif | |
1720 | }) | |
e0d80184 | 1721 | |
be3f1ff5 | 1722 | (define_insn "movdi_high_pic" |
e0d80184 | 1723 | [(set (match_operand:DI 0 "register_operand" "=r") |
4f4778ee | 1724 | (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))] |
e0d80184 | 1725 | "TARGET_ARCH64 && flag_pic && check_pic (1)" |
878ee0ab DM |
1726 | { |
1727 | #ifdef HAVE_AS_SPARC_GOTDATA_OP | |
1728 | return "sethi\t%%gdop_hix22(%a1), %0"; | |
1729 | #else | |
1730 | return "sethi\t%%hi(%a1), %0"; | |
1731 | #endif | |
1732 | }) | |
1733 | ||
1734 | (define_insn "movdi_pic_gotdata_op" | |
1735 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1736 | (unspec:DI [(match_operand:DI 1 "register_operand" "r") | |
1737 | (match_operand:DI 2 "register_operand" "r") | |
1738 | (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))] | |
1739 | "TARGET_ARCH64 && flag_pic && check_pic (1)" | |
1740 | { | |
1741 | #ifdef HAVE_AS_SPARC_GOTDATA_OP | |
1742 | return "ldx\t[%1 + %2], %0, %%gdop(%a3)"; | |
1743 | #else | |
1744 | return "ldx\t[%1 + %2], %0"; | |
1745 | #endif | |
1746 | } | |
1747 | [(set_attr "type" "load")]) | |
e0d80184 DM |
1748 | |
1749 | (define_insn "*sethi_di_medlow_embmedany_pic" | |
1750 | [(set (match_operand:DI 0 "register_operand" "=r") | |
0e5d569c | 1751 | (high:DI (match_operand:DI 1 "medium_pic_operand" "")))] |
e0d80184 | 1752 | "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)" |
16b46035 | 1753 | "sethi\t%%hi(%a1), %0") |
b4ac57ab | 1754 | |
c8b3b7d6 | 1755 | (define_insn "*sethi_di_medlow" |
a8d2b752 | 1756 | [(set (match_operand:DI 0 "register_operand" "=r") |
e1a2f7ae | 1757 | (high:DI (match_operand:DI 1 "symbolic_operand" "")))] |
a0a301fc | 1758 | "TARGET_CM_MEDLOW && check_pic (1)" |
16b46035 | 1759 | "sethi\t%%hi(%a1), %0") |
7a768814 | 1760 | |
e0d80184 | 1761 | (define_insn "*losum_di_medlow" |
95726648 | 1762 | [(set (match_operand:DI 0 "register_operand" "=r") |
e0d80184 | 1763 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") |
f710f868 | 1764 | (match_operand:DI 2 "symbolic_operand" "")))] |
e0d80184 | 1765 | "TARGET_CM_MEDLOW" |
16b46035 | 1766 | "or\t%1, %%lo(%a2), %0") |
e0d80184 DM |
1767 | |
1768 | (define_insn "seth44" | |
1769 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4f4778ee | 1770 | (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))] |
e0d80184 | 1771 | "TARGET_CM_MEDMID" |
16b46035 | 1772 | "sethi\t%%h44(%a1), %0") |
95726648 | 1773 | |
e0d80184 DM |
1774 | (define_insn "setm44" |
1775 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1776 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
4f4778ee | 1777 | (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))] |
e0d80184 | 1778 | "TARGET_CM_MEDMID" |
16b46035 | 1779 | "or\t%1, %%m44(%a2), %0") |
a8d2b752 | 1780 | |
e0d80184 | 1781 | (define_insn "setl44" |
a8d2b752 | 1782 | [(set (match_operand:DI 0 "register_operand" "=r") |
e0d80184 DM |
1783 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") |
1784 | (match_operand:DI 2 "symbolic_operand" "")))] | |
1785 | "TARGET_CM_MEDMID" | |
16b46035 | 1786 | "or\t%1, %%l44(%a2), %0") |
e0d80184 DM |
1787 | |
1788 | (define_insn "sethh" | |
1789 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4f4778ee | 1790 | (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))] |
e0d80184 | 1791 | "TARGET_CM_MEDANY" |
16b46035 | 1792 | "sethi\t%%hh(%a1), %0") |
a8d2b752 | 1793 | |
e0d80184 | 1794 | (define_insn "setlm" |
a8d2b752 | 1795 | [(set (match_operand:DI 0 "register_operand" "=r") |
4f4778ee | 1796 | (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))] |
e0d80184 | 1797 | "TARGET_CM_MEDANY" |
16b46035 | 1798 | "sethi\t%%lm(%a1), %0") |
a8d2b752 | 1799 | |
e0d80184 DM |
1800 | (define_insn "sethm" |
1801 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1802 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
4f4778ee | 1803 | (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))] |
e0d80184 | 1804 | "TARGET_CM_MEDANY" |
16b46035 | 1805 | "or\t%1, %%hm(%a2), %0") |
a8d2b752 | 1806 | |
e0d80184 DM |
1807 | (define_insn "setlo" |
1808 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1809 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
f710f868 | 1810 | (match_operand:DI 2 "symbolic_operand" "")))] |
e0d80184 | 1811 | "TARGET_CM_MEDANY" |
16b46035 | 1812 | "or\t%1, %%lo(%a2), %0") |
e0d80184 DM |
1813 | |
1814 | (define_insn "embmedany_sethi" | |
1815 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4f4778ee | 1816 | (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))] |
e0d80184 | 1817 | "TARGET_CM_EMBMEDANY && check_pic (1)" |
16b46035 | 1818 | "sethi\t%%hi(%a1), %0") |
a8d2b752 | 1819 | |
e0d80184 DM |
1820 | (define_insn "embmedany_losum" |
1821 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1822 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
1823 | (match_operand:DI 2 "data_segment_operand" "")))] | |
1824 | "TARGET_CM_EMBMEDANY" | |
16b46035 | 1825 | "add\t%1, %%lo(%a2), %0") |
a8d2b752 | 1826 | |
e0d80184 DM |
1827 | (define_insn "embmedany_brsum" |
1828 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4f4778ee | 1829 | (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))] |
e0d80184 | 1830 | "TARGET_CM_EMBMEDANY" |
16b46035 | 1831 | "add\t%1, %_, %0") |
a8d2b752 | 1832 | |
e0d80184 DM |
1833 | (define_insn "embmedany_textuhi" |
1834 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4f4778ee | 1835 | (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))] |
e0d80184 | 1836 | "TARGET_CM_EMBMEDANY && check_pic (1)" |
16b46035 | 1837 | "sethi\t%%uhi(%a1), %0") |
a8d2b752 | 1838 | |
e0d80184 DM |
1839 | (define_insn "embmedany_texthi" |
1840 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4f4778ee | 1841 | (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))] |
e0d80184 | 1842 | "TARGET_CM_EMBMEDANY && check_pic (1)" |
16b46035 | 1843 | "sethi\t%%hi(%a1), %0") |
a8d2b752 | 1844 | |
e0d80184 DM |
1845 | (define_insn "embmedany_textulo" |
1846 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1847 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
4f4778ee | 1848 | (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))] |
e0d80184 | 1849 | "TARGET_CM_EMBMEDANY" |
16b46035 | 1850 | "or\t%1, %%ulo(%a2), %0") |
b4ac57ab | 1851 | |
e0d80184 DM |
1852 | (define_insn "embmedany_textlo" |
1853 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1854 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
1855 | (match_operand:DI 2 "text_segment_operand" "")))] | |
1856 | "TARGET_CM_EMBMEDANY" | |
16b46035 | 1857 | "or\t%1, %%lo(%a2), %0") |
a8d2b752 | 1858 | |
e0d80184 DM |
1859 | ;; Now some patterns to help reload out a bit. |
1860 | (define_expand "reload_indi" | |
1861 | [(parallel [(match_operand:DI 0 "register_operand" "=r") | |
1862 | (match_operand:DI 1 "immediate_operand" "") | |
1863 | (match_operand:TI 2 "register_operand" "=&r")])] | |
1864 | "(TARGET_CM_MEDANY | |
1865 | || TARGET_CM_EMBMEDANY) | |
1866 | && ! flag_pic" | |
a8d2b752 | 1867 | { |
3968de80 | 1868 | sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]); |
e0d80184 | 1869 | DONE; |
563facba | 1870 | }) |
a8d2b752 | 1871 | |
e0d80184 DM |
1872 | (define_expand "reload_outdi" |
1873 | [(parallel [(match_operand:DI 0 "register_operand" "=r") | |
1874 | (match_operand:DI 1 "immediate_operand" "") | |
1875 | (match_operand:TI 2 "register_operand" "=&r")])] | |
1876 | "(TARGET_CM_MEDANY | |
1877 | || TARGET_CM_EMBMEDANY) | |
1878 | && ! flag_pic" | |
7a768814 | 1879 | { |
3968de80 | 1880 | sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]); |
e0d80184 | 1881 | DONE; |
563facba | 1882 | }) |
7a768814 | 1883 | |
e0d80184 DM |
1884 | ;; Split up putting CONSTs and REGs into DI regs when !arch64 |
1885 | (define_split | |
1886 | [(set (match_operand:DI 0 "register_operand" "") | |
1887 | (match_operand:DI 1 "const_int_operand" ""))] | |
1255f800 DM |
1888 | "! TARGET_ARCH64 |
1889 | && ((GET_CODE (operands[0]) == REG | |
1890 | && SPARC_INT_REG_P (REGNO (operands[0]))) | |
1891 | || (GET_CODE (operands[0]) == SUBREG | |
1892 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
1893 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0]))))) | |
1894 | && reload_completed" | |
e0d80184 | 1895 | [(clobber (const_int 0))] |
bfd6bc60 | 1896 | { |
93b7b953 | 1897 | #if HOST_BITS_PER_WIDE_INT == 32 |
e0d80184 DM |
1898 | emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), |
1899 | (INTVAL (operands[1]) < 0) ? | |
1900 | constm1_rtx : | |
1901 | const0_rtx)); | |
1902 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), | |
1903 | operands[1])); | |
93b7b953 JJ |
1904 | #else |
1905 | unsigned int low, high; | |
1906 | ||
9e0625a3 AO |
1907 | low = trunc_int_for_mode (INTVAL (operands[1]), SImode); |
1908 | high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode); | |
93b7b953 JJ |
1909 | emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high))); |
1910 | ||
1911 | /* Slick... but this trick loses if this subreg constant part | |
1912 | can be done in one insn. */ | |
3193108e EB |
1913 | if (low == high |
1914 | && ! SPARC_SETHI32_P (high) | |
1915 | && ! SPARC_SIMM13_P (high)) | |
93b7b953 JJ |
1916 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), |
1917 | gen_highpart (SImode, operands[0]))); | |
1918 | else | |
1919 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low))); | |
1920 | #endif | |
e0d80184 | 1921 | DONE; |
563facba | 1922 | }) |
bfd6bc60 | 1923 | |
bfd6bc60 | 1924 | (define_split |
e0d80184 DM |
1925 | [(set (match_operand:DI 0 "register_operand" "") |
1926 | (match_operand:DI 1 "const_double_operand" ""))] | |
88d0be17 DM |
1927 | "reload_completed |
1928 | && (! TARGET_V9 | |
1929 | || (! TARGET_ARCH64 | |
1930 | && ((GET_CODE (operands[0]) == REG | |
5a53588f | 1931 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
88d0be17 DM |
1932 | || (GET_CODE (operands[0]) == SUBREG |
1933 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
5a53588f | 1934 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))" |
e0d80184 | 1935 | [(clobber (const_int 0))] |
6a4bb1fa | 1936 | { |
e0d80184 DM |
1937 | emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), |
1938 | GEN_INT (CONST_DOUBLE_HIGH (operands[1])))); | |
1939 | ||
1940 | /* Slick... but this trick loses if this subreg constant part | |
1941 | can be done in one insn. */ | |
1942 | if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1]) | |
8ca864d2 EB |
1943 | && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1])) |
1944 | && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))) | |
a8d2b752 | 1945 | { |
e0d80184 DM |
1946 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), |
1947 | gen_highpart (SImode, operands[0]))); | |
a8d2b752 | 1948 | } |
e0d80184 DM |
1949 | else |
1950 | { | |
1951 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), | |
1952 | GEN_INT (CONST_DOUBLE_LOW (operands[1])))); | |
1953 | } | |
1954 | DONE; | |
563facba | 1955 | }) |
7a768814 | 1956 | |
e0d80184 DM |
1957 | (define_split |
1958 | [(set (match_operand:DI 0 "register_operand" "") | |
1959 | (match_operand:DI 1 "register_operand" ""))] | |
f7670e7b EB |
1960 | "reload_completed |
1961 | && (! TARGET_V9 | |
1962 | || (! TARGET_ARCH64 | |
b1fc9f8b DM |
1963 | && sparc_split_regreg_legitimate (operands[0], |
1964 | operands[1])))" | |
e0d80184 | 1965 | [(clobber (const_int 0))] |
e0d80184 DM |
1966 | { |
1967 | rtx set_dest = operands[0]; | |
1968 | rtx set_src = operands[1]; | |
1969 | rtx dest1, dest2; | |
1970 | rtx src1, src2; | |
7a768814 | 1971 | |
e0d80184 DM |
1972 | dest1 = gen_highpart (SImode, set_dest); |
1973 | dest2 = gen_lowpart (SImode, set_dest); | |
1974 | src1 = gen_highpart (SImode, set_src); | |
1975 | src2 = gen_lowpart (SImode, set_src); | |
1976 | ||
1977 | /* Now emit using the real source and destination we found, swapping | |
1978 | the order if we detect overlap. */ | |
0e64f197 | 1979 | if (reg_overlap_mentioned_p (dest1, src2)) |
e0d80184 DM |
1980 | { |
1981 | emit_insn (gen_movsi (dest2, src2)); | |
1982 | emit_insn (gen_movsi (dest1, src1)); | |
1983 | } | |
1984 | else | |
1985 | { | |
1986 | emit_insn (gen_movsi (dest1, src1)); | |
1987 | emit_insn (gen_movsi (dest2, src2)); | |
1988 | } | |
1989 | DONE; | |
563facba | 1990 | }) |
e0d80184 DM |
1991 | |
1992 | ;; Now handle the cases of memory moves from/to non-even | |
1993 | ;; DI mode register pairs. | |
1994 | (define_split | |
1995 | [(set (match_operand:DI 0 "register_operand" "") | |
1996 | (match_operand:DI 1 "memory_operand" ""))] | |
1997 | "(! TARGET_ARCH64 | |
1998 | && reload_completed | |
1999 | && sparc_splitdi_legitimate (operands[0], operands[1]))" | |
2000 | [(clobber (const_int 0))] | |
795068a4 | 2001 | { |
f4ef873c | 2002 | rtx word0 = adjust_address (operands[1], SImode, 0); |
ed8908e7 | 2003 | rtx word1 = adjust_address (operands[1], SImode, 4); |
e0d80184 DM |
2004 | rtx high_part = gen_highpart (SImode, operands[0]); |
2005 | rtx low_part = gen_lowpart (SImode, operands[0]); | |
e0d80184 | 2006 | |
06424989 | 2007 | if (reg_overlap_mentioned_p (high_part, word1)) |
795068a4 | 2008 | { |
e0d80184 DM |
2009 | emit_insn (gen_movsi (low_part, word1)); |
2010 | emit_insn (gen_movsi (high_part, word0)); | |
795068a4 | 2011 | } |
e0d80184 DM |
2012 | else |
2013 | { | |
2014 | emit_insn (gen_movsi (high_part, word0)); | |
2015 | emit_insn (gen_movsi (low_part, word1)); | |
2016 | } | |
2017 | DONE; | |
563facba | 2018 | }) |
e0d80184 DM |
2019 | |
2020 | (define_split | |
2021 | [(set (match_operand:DI 0 "memory_operand" "") | |
2022 | (match_operand:DI 1 "register_operand" ""))] | |
2023 | "(! TARGET_ARCH64 | |
2024 | && reload_completed | |
2025 | && sparc_splitdi_legitimate (operands[1], operands[0]))" | |
2026 | [(clobber (const_int 0))] | |
e0d80184 | 2027 | { |
ed8908e7 RK |
2028 | emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), |
2029 | gen_highpart (SImode, operands[1]))); | |
2030 | emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), | |
2031 | gen_lowpart (SImode, operands[1]))); | |
e0d80184 | 2032 | DONE; |
563facba | 2033 | }) |
e0d80184 | 2034 | |
7425707d RH |
2035 | (define_split |
2036 | [(set (match_operand:DI 0 "memory_operand" "") | |
3193108e | 2037 | (match_operand:DI 1 "const_zero_operand" ""))] |
7425707d RH |
2038 | "reload_completed |
2039 | && (! TARGET_V9 | |
2040 | || (! TARGET_ARCH64 | |
2041 | && ! mem_min_alignment (operands[0], 8))) | |
2042 | && offsettable_memref_p (operands[0])" | |
2043 | [(clobber (const_int 0))] | |
7425707d RH |
2044 | { |
2045 | emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx)); | |
2046 | emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx)); | |
2047 | DONE; | |
563facba | 2048 | }) |
795068a4 | 2049 | |
03c432bd EB |
2050 | (define_expand "movti" |
2051 | [(set (match_operand:TI 0 "nonimmediate_operand" "") | |
2052 | (match_operand:TI 1 "general_operand" ""))] | |
2053 | "TARGET_ARCH64" | |
2054 | { | |
2055 | if (sparc_expand_move (TImode, operands)) | |
2056 | DONE; | |
2057 | }) | |
2058 | ||
2059 | ;; We need to prevent reload from splitting TImode moves, because it | |
2060 | ;; might decide to overwrite a pointer with the value it points to. | |
2061 | ;; In that case we have to do the loads in the appropriate order so | |
2062 | ;; that the pointer is not destroyed too early. | |
2063 | ||
2064 | (define_insn "*movti_insn_sp64" | |
2065 | [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b") | |
2066 | (match_operand:TI 1 "input_operand" "roJ,rJ, eo, e,J"))] | |
2067 | "TARGET_ARCH64 | |
2068 | && ! TARGET_HARD_QUAD | |
2069 | && (register_operand (operands[0], TImode) | |
2070 | || register_or_zero_operand (operands[1], TImode))" | |
2071 | "#" | |
2072 | [(set_attr "length" "2,2,2,2,2") | |
2073 | (set_attr "cpu_feature" "*,*,fpu,fpu,vis")]) | |
2074 | ||
2075 | (define_insn "*movti_insn_sp64_hq" | |
2076 | [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b") | |
2077 | (match_operand:TI 1 "input_operand" "roJ,rJ, e, m, e,J"))] | |
2078 | "TARGET_ARCH64 | |
2079 | && TARGET_HARD_QUAD | |
2080 | && (register_operand (operands[0], TImode) | |
2081 | || register_or_zero_operand (operands[1], TImode))" | |
2082 | "@ | |
2083 | # | |
2084 | # | |
2085 | fmovq\t%1, %0 | |
2086 | ldq\t%1, %0 | |
2087 | stq\t%1, %0 | |
2088 | #" | |
2089 | [(set_attr "type" "*,*,fpmove,fpload,fpstore,*") | |
2090 | (set_attr "length" "2,2,*,*,*,2")]) | |
2091 | ||
2092 | ;; Now all the splits to handle multi-insn TI mode moves. | |
2093 | (define_split | |
2094 | [(set (match_operand:TI 0 "register_operand" "") | |
2095 | (match_operand:TI 1 "register_operand" ""))] | |
2096 | "reload_completed | |
2097 | && ((TARGET_FPU | |
2098 | && ! TARGET_HARD_QUAD) | |
2099 | || (! fp_register_operand (operands[0], TImode) | |
2100 | && ! fp_register_operand (operands[1], TImode)))" | |
2101 | [(clobber (const_int 0))] | |
2102 | { | |
2103 | rtx set_dest = operands[0]; | |
2104 | rtx set_src = operands[1]; | |
2105 | rtx dest1, dest2; | |
2106 | rtx src1, src2; | |
2107 | ||
2108 | dest1 = gen_highpart (DImode, set_dest); | |
2109 | dest2 = gen_lowpart (DImode, set_dest); | |
2110 | src1 = gen_highpart (DImode, set_src); | |
2111 | src2 = gen_lowpart (DImode, set_src); | |
2112 | ||
2113 | /* Now emit using the real source and destination we found, swapping | |
2114 | the order if we detect overlap. */ | |
2115 | if (reg_overlap_mentioned_p (dest1, src2)) | |
2116 | { | |
2117 | emit_insn (gen_movdi (dest2, src2)); | |
2118 | emit_insn (gen_movdi (dest1, src1)); | |
2119 | } | |
2120 | else | |
2121 | { | |
2122 | emit_insn (gen_movdi (dest1, src1)); | |
2123 | emit_insn (gen_movdi (dest2, src2)); | |
2124 | } | |
2125 | DONE; | |
2126 | }) | |
2127 | ||
2128 | (define_split | |
2129 | [(set (match_operand:TI 0 "nonimmediate_operand" "") | |
2130 | (match_operand:TI 1 "const_zero_operand" ""))] | |
2131 | "reload_completed" | |
2132 | [(clobber (const_int 0))] | |
2133 | { | |
2134 | rtx set_dest = operands[0]; | |
2135 | rtx dest1, dest2; | |
2136 | ||
2137 | switch (GET_CODE (set_dest)) | |
2138 | { | |
2139 | case REG: | |
2140 | dest1 = gen_highpart (DImode, set_dest); | |
2141 | dest2 = gen_lowpart (DImode, set_dest); | |
2142 | break; | |
2143 | case MEM: | |
2144 | dest1 = adjust_address (set_dest, DImode, 0); | |
2145 | dest2 = adjust_address (set_dest, DImode, 8); | |
2146 | break; | |
2147 | default: | |
2148 | gcc_unreachable (); | |
2149 | } | |
2150 | ||
2151 | emit_insn (gen_movdi (dest1, const0_rtx)); | |
2152 | emit_insn (gen_movdi (dest2, const0_rtx)); | |
2153 | DONE; | |
2154 | }) | |
2155 | ||
2156 | (define_split | |
2157 | [(set (match_operand:TI 0 "register_operand" "") | |
2158 | (match_operand:TI 1 "memory_operand" ""))] | |
2159 | "reload_completed | |
2160 | && offsettable_memref_p (operands[1]) | |
2161 | && (! TARGET_HARD_QUAD | |
2162 | || ! fp_register_operand (operands[0], TImode))" | |
2163 | [(clobber (const_int 0))] | |
2164 | { | |
2165 | rtx word0 = adjust_address (operands[1], DImode, 0); | |
2166 | rtx word1 = adjust_address (operands[1], DImode, 8); | |
2167 | rtx set_dest, dest1, dest2; | |
2168 | ||
2169 | set_dest = operands[0]; | |
2170 | ||
2171 | dest1 = gen_highpart (DImode, set_dest); | |
2172 | dest2 = gen_lowpart (DImode, set_dest); | |
2173 | ||
2174 | /* Now output, ordering such that we don't clobber any registers | |
2175 | mentioned in the address. */ | |
2176 | if (reg_overlap_mentioned_p (dest1, word1)) | |
2177 | ||
2178 | { | |
2179 | emit_insn (gen_movdi (dest2, word1)); | |
2180 | emit_insn (gen_movdi (dest1, word0)); | |
2181 | } | |
2182 | else | |
2183 | { | |
2184 | emit_insn (gen_movdi (dest1, word0)); | |
2185 | emit_insn (gen_movdi (dest2, word1)); | |
2186 | } | |
2187 | DONE; | |
2188 | }) | |
2189 | ||
2190 | (define_split | |
2191 | [(set (match_operand:TI 0 "memory_operand" "") | |
2192 | (match_operand:TI 1 "register_operand" ""))] | |
2193 | "reload_completed | |
2194 | && offsettable_memref_p (operands[0]) | |
2195 | && (! TARGET_HARD_QUAD | |
2196 | || ! fp_register_operand (operands[1], TImode))" | |
2197 | [(clobber (const_int 0))] | |
2198 | { | |
2199 | rtx set_src = operands[1]; | |
2200 | ||
2201 | emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0), | |
2202 | gen_highpart (DImode, set_src))); | |
2203 | emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8), | |
2204 | gen_lowpart (DImode, set_src))); | |
2205 | DONE; | |
2206 | }) | |
2207 | ||
9a9e266b | 2208 | |
e00560c2 | 2209 | ;; Floating point move instructions |
9a9e266b | 2210 | |
e00560c2 DM |
2211 | (define_expand "movsf" |
2212 | [(set (match_operand:SF 0 "nonimmediate_operand" "") | |
2213 | (match_operand:SF 1 "general_operand" ""))] | |
2214 | "" | |
f8ece000 | 2215 | { |
e00560c2 | 2216 | if (sparc_expand_move (SFmode, operands)) |
bea5071f | 2217 | DONE; |
f8ece000 EB |
2218 | }) |
2219 | ||
1b43bc82 | 2220 | (define_insn "*movsf_insn" |
19e5fa42 EB |
2221 | [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m, m") |
2222 | (match_operand:SF 1 "input_operand" "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))] | |
1b43bc82 DM |
2223 | "(register_operand (operands[0], SFmode) |
2224 | || register_or_zero_or_all_ones_operand (operands[1], SFmode))" | |
bb12a72a DM |
2225 | { |
2226 | if (GET_CODE (operands[1]) == CONST_DOUBLE | |
2227 | && (which_alternative == 3 | |
2228 | || which_alternative == 4 | |
2229 | || which_alternative == 5)) | |
2230 | { | |
2231 | REAL_VALUE_TYPE r; | |
2232 | long i; | |
2233 | ||
2234 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); | |
2235 | REAL_VALUE_TO_TARGET_SINGLE (r, i); | |
2236 | operands[1] = GEN_INT (i); | |
2237 | } | |
2238 | ||
2239 | switch (which_alternative) | |
2240 | { | |
2241 | case 0: | |
2242 | return "fzeros\t%0"; | |
2243 | case 1: | |
2244 | return "fones\t%0"; | |
2245 | case 2: | |
2246 | return "fmovs\t%1, %0"; | |
2247 | case 3: | |
2248 | return "mov\t%1, %0"; | |
2249 | case 4: | |
2250 | return "sethi\t%%hi(%a1), %0"; | |
2251 | case 5: | |
2252 | return "#"; | |
2253 | case 6: | |
2254 | return "movstouw\t%1, %0"; | |
2255 | case 7: | |
2256 | return "movwtos\t%1, %0"; | |
2257 | case 8: | |
2258 | case 9: | |
2259 | return "ld\t%1, %0"; | |
2260 | case 10: | |
2261 | case 11: | |
2262 | return "st\t%r1, %0"; | |
2263 | default: | |
2264 | gcc_unreachable (); | |
2265 | } | |
2266 | } | |
f298688c | 2267 | [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store") |
1b43bc82 | 2268 | (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")]) |
fd2c87bd | 2269 | |
c75d6010 JM |
2270 | ;; The following 3 patterns build SFmode constants in integer registers. |
2271 | ||
62190128 | 2272 | (define_insn "*movsf_lo_sum" |
fd2c87bd GK |
2273 | [(set (match_operand:SF 0 "register_operand" "=r") |
2274 | (lo_sum:SF (match_operand:SF 1 "register_operand" "r") | |
9a9e266b EB |
2275 | (match_operand:SF 2 "fp_const_high_losum_operand" "S")))] |
2276 | "" | |
62190128 DM |
2277 | { |
2278 | REAL_VALUE_TYPE r; | |
2279 | long i; | |
2280 | ||
2281 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); | |
2282 | REAL_VALUE_TO_TARGET_SINGLE (r, i); | |
2283 | operands[2] = GEN_INT (i); | |
16b46035 | 2284 | return "or\t%1, %%lo(%a2), %0"; |
563facba | 2285 | }) |
45120407 | 2286 | |
62190128 | 2287 | (define_insn "*movsf_high" |
fd2c87bd | 2288 | [(set (match_operand:SF 0 "register_operand" "=r") |
9a9e266b EB |
2289 | (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))] |
2290 | "" | |
45120407 DM |
2291 | { |
2292 | REAL_VALUE_TYPE r; | |
2293 | long i; | |
2294 | ||
2295 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); | |
2296 | REAL_VALUE_TO_TARGET_SINGLE (r, i); | |
2297 | operands[1] = GEN_INT (i); | |
16b46035 | 2298 | return "sethi\t%%hi(%1), %0"; |
563facba | 2299 | }) |
62190128 DM |
2300 | |
2301 | (define_split | |
2302 | [(set (match_operand:SF 0 "register_operand" "") | |
9a9e266b | 2303 | (match_operand:SF 1 "fp_const_high_losum_operand" ""))] |
5a53588f | 2304 | "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))" |
62190128 DM |
2305 | [(set (match_dup 0) (high:SF (match_dup 1))) |
2306 | (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))]) | |
2307 | ||
e00560c2 DM |
2308 | (define_expand "movdf" |
2309 | [(set (match_operand:DF 0 "nonimmediate_operand" "") | |
2310 | (match_operand:DF 1 "general_operand" ""))] | |
2311 | "" | |
7a768814 | 2312 | { |
e00560c2 | 2313 | if (sparc_expand_move (DFmode, operands)) |
bea5071f | 2314 | DONE; |
563facba | 2315 | }) |
7a768814 | 2316 | |
e0d80184 | 2317 | (define_insn "*movdf_insn_sp32" |
aaa050aa DM |
2318 | [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f, e,T,W,U,T, f, *r, o,o") |
2319 | (match_operand:DF 1 "input_operand" "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))] | |
1b43bc82 | 2320 | "! TARGET_ARCH64 |
e00560c2 DM |
2321 | && (register_operand (operands[0], DFmode) |
2322 | || register_or_zero_or_all_ones_operand (operands[1], DFmode))" | |
71648202 | 2323 | "@ |
16b46035 | 2324 | fzero\t%0 |
7cbcf85b | 2325 | fone\t%0 |
16b46035 | 2326 | fmovd\t%1, %0 |
71648202 DM |
2327 | # |
2328 | # | |
bb12a72a DM |
2329 | # |
2330 | ldd\t%1, %0 | |
2331 | stx\t%r1, %0 | |
2332 | std\t%1, %0 | |
2333 | ldd\t%1, %0 | |
2334 | std\t%1, %0 | |
2335 | # | |
2336 | # | |
f8ece000 EB |
2337 | # |
2338 | #" | |
f298688c | 2339 | [(set_attr "type" "visl,visl,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*") |
1b43bc82 DM |
2340 | (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2") |
2341 | (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*") | |
2342 | (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")]) | |
ab5519b7 | 2343 | |
1b43bc82 | 2344 | (define_insn "*movdf_insn_sp64" |
cca3f03d | 2345 | [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r") |
19e5fa42 | 2346 | (match_operand:DF 1 "input_operand" "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))] |
1b43bc82 | 2347 | "TARGET_ARCH64 |
bb12a72a DM |
2348 | && (register_operand (operands[0], DFmode) |
2349 | || register_or_zero_or_all_ones_operand (operands[1], DFmode))" | |
2350 | "@ | |
2351 | fzero\t%0 | |
2352 | fone\t%0 | |
2353 | fmovd\t%1, %0 | |
2354 | movdtox\t%1, %0 | |
2355 | movxtod\t%1, %0 | |
2356 | ldd\t%1, %0 | |
2357 | std\t%1, %0 | |
2358 | mov\t%r1, %0 | |
2359 | ldx\t%1, %0 | |
2360 | stx\t%r1, %0 | |
2361 | #" | |
f298688c | 2362 | [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*") |
bb12a72a | 2363 | (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2") |
1b43bc82 DM |
2364 | (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*") |
2365 | (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")]) | |
9ad2334b | 2366 | |
e00560c2 | 2367 | ;; This pattern builds DFmode constants in integer registers. |
a5774a7d | 2368 | (define_split |
e00560c2 DM |
2369 | [(set (match_operand:DF 0 "register_operand" "") |
2370 | (match_operand:DF 1 "const_double_operand" ""))] | |
19e5fa42 EB |
2371 | "REG_P (operands[0]) |
2372 | && SPARC_INT_REG_P (REGNO (operands[0])) | |
66e62b49 | 2373 | && ! const_zero_operand (operands[1], GET_MODE (operands[0])) |
a5774a7d JJ |
2374 | && reload_completed" |
2375 | [(clobber (const_int 0))] | |
a5774a7d | 2376 | { |
a5774a7d JJ |
2377 | operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0])); |
2378 | ||
2379 | if (TARGET_ARCH64) | |
2380 | { | |
8ca864d2 EB |
2381 | #if HOST_BITS_PER_WIDE_INT == 32 |
2382 | gcc_unreachable (); | |
2383 | #else | |
66e62b49 KH |
2384 | enum machine_mode mode = GET_MODE (operands[1]); |
2385 | rtx tem = simplify_subreg (DImode, operands[1], mode, 0); | |
2386 | emit_insn (gen_movdi (operands[0], tem)); | |
a5774a7d JJ |
2387 | #endif |
2388 | } | |
2389 | else | |
2390 | { | |
66e62b49 KH |
2391 | enum machine_mode mode = GET_MODE (operands[1]); |
2392 | rtx hi = simplify_subreg (SImode, operands[1], mode, 0); | |
2393 | rtx lo = simplify_subreg (SImode, operands[1], mode, 4); | |
2394 | ||
2395 | gcc_assert (GET_CODE (hi) == CONST_INT); | |
2396 | gcc_assert (GET_CODE (lo) == CONST_INT); | |
2397 | ||
2398 | emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi)); | |
a5774a7d JJ |
2399 | |
2400 | /* Slick... but this trick loses if this subreg constant part | |
2401 | can be done in one insn. */ | |
66e62b49 KH |
2402 | if (lo == hi |
2403 | && ! SPARC_SETHI32_P (INTVAL (hi)) | |
2404 | && ! SPARC_SIMM13_P (INTVAL (hi))) | |
a5774a7d JJ |
2405 | { |
2406 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), | |
2407 | gen_highpart (SImode, operands[0]))); | |
2408 | } | |
2409 | else | |
2410 | { | |
66e62b49 | 2411 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo)); |
a5774a7d JJ |
2412 | } |
2413 | } | |
2414 | DONE; | |
563facba | 2415 | }) |
a5774a7d | 2416 | |
e0d80184 DM |
2417 | ;; Ok, now the splits to handle all the multi insn and |
2418 | ;; mis-aligned memory address cases. | |
71648202 DM |
2419 | ;; In these splits please take note that we must be |
2420 | ;; careful when V9 but not ARCH64 because the integer | |
2421 | ;; register DFmode cases must be handled. | |
ae0cab49 | 2422 | (define_split |
e00560c2 DM |
2423 | [(set (match_operand:DF 0 "register_operand" "") |
2424 | (match_operand:DF 1 "register_operand" ""))] | |
71648202 DM |
2425 | "(! TARGET_V9 |
2426 | || (! TARGET_ARCH64 | |
b1fc9f8b DM |
2427 | && sparc_split_regreg_legitimate (operands[0], |
2428 | operands[1]))) | |
71648202 | 2429 | && reload_completed" |
e0d80184 | 2430 | [(clobber (const_int 0))] |
63f7136f | 2431 | { |
e0d80184 DM |
2432 | rtx set_dest = operands[0]; |
2433 | rtx set_src = operands[1]; | |
2434 | rtx dest1, dest2; | |
2435 | rtx src1, src2; | |
2436 | ||
e00560c2 DM |
2437 | dest1 = gen_highpart (SFmode, set_dest); |
2438 | dest2 = gen_lowpart (SFmode, set_dest); | |
2439 | src1 = gen_highpart (SFmode, set_src); | |
2440 | src2 = gen_lowpart (SFmode, set_src); | |
e0d80184 DM |
2441 | |
2442 | /* Now emit using the real source and destination we found, swapping | |
2443 | the order if we detect overlap. */ | |
0e64f197 | 2444 | if (reg_overlap_mentioned_p (dest1, src2)) |
63f7136f | 2445 | { |
c75d6010 JM |
2446 | emit_move_insn_1 (dest2, src2); |
2447 | emit_move_insn_1 (dest1, src1); | |
63f7136f JW |
2448 | } |
2449 | else | |
2450 | { | |
c75d6010 JM |
2451 | emit_move_insn_1 (dest1, src1); |
2452 | emit_move_insn_1 (dest2, src2); | |
63f7136f | 2453 | } |
e0d80184 | 2454 | DONE; |
563facba | 2455 | }) |
ae0cab49 | 2456 | |
e0d80184 | 2457 | (define_split |
e00560c2 DM |
2458 | [(set (match_operand:DF 0 "register_operand" "") |
2459 | (match_operand:DF 1 "memory_operand" ""))] | |
a5774a7d JJ |
2460 | "reload_completed |
2461 | && ! TARGET_ARCH64 | |
2462 | && (((REGNO (operands[0]) % 2) != 0) | |
2463 | || ! mem_min_alignment (operands[1], 8)) | |
2464 | && offsettable_memref_p (operands[1])" | |
e0d80184 | 2465 | [(clobber (const_int 0))] |
7a768814 | 2466 | { |
c75d6010 JM |
2467 | rtx word0, word1; |
2468 | ||
e00560c2 DM |
2469 | word0 = adjust_address (operands[1], SFmode, 0); |
2470 | word1 = adjust_address (operands[1], SFmode, 4); | |
e0d80184 | 2471 | |
e00560c2 | 2472 | if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1)) |
e0d80184 | 2473 | { |
e00560c2 DM |
2474 | emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1); |
2475 | emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0); | |
e0d80184 | 2476 | } |
7a768814 | 2477 | else |
2b9a9aea | 2478 | { |
e00560c2 DM |
2479 | emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0); |
2480 | emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1); | |
2b9a9aea | 2481 | } |
e0d80184 | 2482 | DONE; |
563facba | 2483 | }) |
e0d80184 DM |
2484 | |
2485 | (define_split | |
e00560c2 DM |
2486 | [(set (match_operand:DF 0 "memory_operand" "") |
2487 | (match_operand:DF 1 "register_operand" ""))] | |
a5774a7d JJ |
2488 | "reload_completed |
2489 | && ! TARGET_ARCH64 | |
2490 | && (((REGNO (operands[1]) % 2) != 0) | |
2491 | || ! mem_min_alignment (operands[0], 8)) | |
2492 | && offsettable_memref_p (operands[0])" | |
e0d80184 | 2493 | [(clobber (const_int 0))] |
e0d80184 | 2494 | { |
c75d6010 | 2495 | rtx word0, word1; |
e0d80184 | 2496 | |
e00560c2 DM |
2497 | word0 = adjust_address (operands[0], SFmode, 0); |
2498 | word1 = adjust_address (operands[0], SFmode, 4); | |
c75d6010 | 2499 | |
e00560c2 DM |
2500 | emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1])); |
2501 | emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1])); | |
e0d80184 | 2502 | DONE; |
563facba | 2503 | }) |
2b9a9aea | 2504 | |
0f63333c | 2505 | (define_split |
e00560c2 DM |
2506 | [(set (match_operand:DF 0 "memory_operand" "") |
2507 | (match_operand:DF 1 "const_zero_operand" ""))] | |
a5774a7d JJ |
2508 | "reload_completed |
2509 | && (! TARGET_V9 | |
2510 | || (! TARGET_ARCH64 | |
2511 | && ! mem_min_alignment (operands[0], 8))) | |
2512 | && offsettable_memref_p (operands[0])" | |
2513 | [(clobber (const_int 0))] | |
0f63333c | 2514 | { |
a5774a7d | 2515 | rtx dest1, dest2; |
0f63333c | 2516 | |
e00560c2 DM |
2517 | dest1 = adjust_address (operands[0], SFmode, 0); |
2518 | dest2 = adjust_address (operands[0], SFmode, 4); | |
c75d6010 | 2519 | |
e00560c2 DM |
2520 | emit_move_insn_1 (dest1, CONST0_RTX (SFmode)); |
2521 | emit_move_insn_1 (dest2, CONST0_RTX (SFmode)); | |
a5774a7d | 2522 | DONE; |
563facba | 2523 | }) |
0f63333c JJ |
2524 | |
2525 | (define_split | |
e00560c2 DM |
2526 | [(set (match_operand:DF 0 "register_operand" "") |
2527 | (match_operand:DF 1 "const_zero_operand" ""))] | |
a5774a7d JJ |
2528 | "reload_completed |
2529 | && ! TARGET_ARCH64 | |
2530 | && ((GET_CODE (operands[0]) == REG | |
5a53588f | 2531 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
a5774a7d JJ |
2532 | || (GET_CODE (operands[0]) == SUBREG |
2533 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
5a53588f | 2534 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" |
a5774a7d | 2535 | [(clobber (const_int 0))] |
0f63333c | 2536 | { |
a5774a7d JJ |
2537 | rtx set_dest = operands[0]; |
2538 | rtx dest1, dest2; | |
2539 | ||
e00560c2 DM |
2540 | dest1 = gen_highpart (SFmode, set_dest); |
2541 | dest2 = gen_lowpart (SFmode, set_dest); | |
2542 | emit_move_insn_1 (dest1, CONST0_RTX (SFmode)); | |
2543 | emit_move_insn_1 (dest2, CONST0_RTX (SFmode)); | |
a5774a7d | 2544 | DONE; |
563facba | 2545 | }) |
0f63333c | 2546 | |
6a4bb1fa | 2547 | (define_expand "movtf" |
bea5071f | 2548 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
6a4bb1fa | 2549 | (match_operand:TF 1 "general_operand" ""))] |
7a768814 | 2550 | "" |
7a768814 | 2551 | { |
bea5071f EB |
2552 | if (sparc_expand_move (TFmode, operands)) |
2553 | DONE; | |
563facba | 2554 | }) |
7a768814 | 2555 | |
e0d80184 | 2556 | (define_insn "*movtf_insn_sp32" |
aaa050aa DM |
2557 | [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,U, r") |
2558 | (match_operand:TF 1 "input_operand" " G,oe,e,rGU,o,roG"))] | |
12e55ac7 | 2559 | "! TARGET_ARCH64 |
6a4bb1fa | 2560 | && (register_operand (operands[0], TFmode) |
9a9e266b | 2561 | || register_or_zero_operand (operands[1], TFmode))" |
e0d80184 | 2562 | "#" |
12e55ac7 EB |
2563 | [(set_attr "length" "4,4,4,4,4,4") |
2564 | (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")]) | |
e0d80184 | 2565 | |
f8ece000 | 2566 | (define_insn "*movtf_insn_sp64" |
12e55ac7 EB |
2567 | [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o, r") |
2568 | (match_operand:TF 1 "input_operand" "G,oe,e,rG,roG"))] | |
2569 | "TARGET_ARCH64 | |
f8ece000 EB |
2570 | && ! TARGET_HARD_QUAD |
2571 | && (register_operand (operands[0], TFmode) | |
2572 | || register_or_zero_operand (operands[1], TFmode))" | |
2573 | "#" | |
12e55ac7 EB |
2574 | [(set_attr "length" "2,2,2,2,2") |
2575 | (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")]) | |
f8ece000 | 2576 | |
9a9e266b | 2577 | (define_insn "*movtf_insn_sp64_hq" |
19e5fa42 EB |
2578 | [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o, r") |
2579 | (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))] | |
12e55ac7 | 2580 | "TARGET_ARCH64 |
e0d80184 DM |
2581 | && TARGET_HARD_QUAD |
2582 | && (register_operand (operands[0], TFmode) | |
9a9e266b | 2583 | || register_or_zero_operand (operands[1], TFmode))" |
a5774a7d | 2584 | "@ |
a5774a7d | 2585 | # |
16b46035 DM |
2586 | fmovq\t%1, %0 |
2587 | ldq\t%1, %0 | |
2588 | stq\t%1, %0 | |
e0d80184 | 2589 | # |
e0d80184 | 2590 | #" |
9a9e266b EB |
2591 | [(set_attr "type" "*,fpmove,fpload,fpstore,*,*") |
2592 | (set_attr "length" "2,*,*,*,2,2")]) | |
e0d80184 | 2593 | |
e0d80184 DM |
2594 | ;; Now all the splits to handle multi-insn TF mode moves. |
2595 | (define_split | |
2596 | [(set (match_operand:TF 0 "register_operand" "") | |
2597 | (match_operand:TF 1 "register_operand" ""))] | |
2598 | "reload_completed | |
2599 | && (! TARGET_ARCH64 | |
2600 | || (TARGET_FPU | |
2a732575 | 2601 | && ! TARGET_HARD_QUAD) |
bb12a72a DM |
2602 | || (! fp_register_operand (operands[0], TFmode) |
2603 | && ! fp_register_operand (operands[1], TFmode)))" | |
e0d80184 | 2604 | [(clobber (const_int 0))] |
6a4bb1fa | 2605 | { |
e0d80184 DM |
2606 | rtx set_dest = operands[0]; |
2607 | rtx set_src = operands[1]; | |
2608 | rtx dest1, dest2; | |
2609 | rtx src1, src2; | |
2610 | ||
7b1ac798 JJ |
2611 | dest1 = gen_df_reg (set_dest, 0); |
2612 | dest2 = gen_df_reg (set_dest, 1); | |
2613 | src1 = gen_df_reg (set_src, 0); | |
2614 | src2 = gen_df_reg (set_src, 1); | |
e0d80184 DM |
2615 | |
2616 | /* Now emit using the real source and destination we found, swapping | |
2617 | the order if we detect overlap. */ | |
0e64f197 | 2618 | if (reg_overlap_mentioned_p (dest1, src2)) |
e0d80184 DM |
2619 | { |
2620 | emit_insn (gen_movdf (dest2, src2)); | |
2621 | emit_insn (gen_movdf (dest1, src1)); | |
2622 | } | |
6a4bb1fa | 2623 | else |
e0d80184 DM |
2624 | { |
2625 | emit_insn (gen_movdf (dest1, src1)); | |
2626 | emit_insn (gen_movdf (dest2, src2)); | |
2627 | } | |
2628 | DONE; | |
563facba | 2629 | }) |
e0d80184 | 2630 | |
a5774a7d JJ |
2631 | (define_split |
2632 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
0e5d569c | 2633 | (match_operand:TF 1 "const_zero_operand" ""))] |
a5774a7d JJ |
2634 | "reload_completed" |
2635 | [(clobber (const_int 0))] | |
a5774a7d JJ |
2636 | { |
2637 | rtx set_dest = operands[0]; | |
2638 | rtx dest1, dest2; | |
2639 | ||
2640 | switch (GET_CODE (set_dest)) | |
2641 | { | |
a5774a7d JJ |
2642 | case REG: |
2643 | dest1 = gen_df_reg (set_dest, 0); | |
2644 | dest2 = gen_df_reg (set_dest, 1); | |
2645 | break; | |
2646 | case MEM: | |
f4ef873c | 2647 | dest1 = adjust_address (set_dest, DFmode, 0); |
ed8908e7 | 2648 | dest2 = adjust_address (set_dest, DFmode, 8); |
a5774a7d JJ |
2649 | break; |
2650 | default: | |
03c432bd | 2651 | gcc_unreachable (); |
a5774a7d JJ |
2652 | } |
2653 | ||
2654 | emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode))); | |
2655 | emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode))); | |
2656 | DONE; | |
563facba | 2657 | }) |
a5774a7d | 2658 | |
e0d80184 DM |
2659 | (define_split |
2660 | [(set (match_operand:TF 0 "register_operand" "") | |
2661 | (match_operand:TF 1 "memory_operand" ""))] | |
2662 | "(reload_completed | |
2a732575 JJ |
2663 | && offsettable_memref_p (operands[1]) |
2664 | && (! TARGET_ARCH64 | |
2665 | || ! TARGET_HARD_QUAD | |
2666 | || ! fp_register_operand (operands[0], TFmode)))" | |
e0d80184 | 2667 | [(clobber (const_int 0))] |
e0d80184 | 2668 | { |
f4ef873c | 2669 | rtx word0 = adjust_address (operands[1], DFmode, 0); |
ed8908e7 | 2670 | rtx word1 = adjust_address (operands[1], DFmode, 8); |
ccd61a80 DM |
2671 | rtx set_dest, dest1, dest2; |
2672 | ||
2673 | set_dest = operands[0]; | |
e0d80184 | 2674 | |
7b1ac798 JJ |
2675 | dest1 = gen_df_reg (set_dest, 0); |
2676 | dest2 = gen_df_reg (set_dest, 1); | |
994099bb DM |
2677 | |
2678 | /* Now output, ordering such that we don't clobber any registers | |
2679 | mentioned in the address. */ | |
06424989 JW |
2680 | if (reg_overlap_mentioned_p (dest1, word1)) |
2681 | ||
994099bb DM |
2682 | { |
2683 | emit_insn (gen_movdf (dest2, word1)); | |
2684 | emit_insn (gen_movdf (dest1, word0)); | |
2685 | } | |
2686 | else | |
2687 | { | |
2688 | emit_insn (gen_movdf (dest1, word0)); | |
2689 | emit_insn (gen_movdf (dest2, word1)); | |
2690 | } | |
e0d80184 | 2691 | DONE; |
563facba | 2692 | }) |
e0d80184 DM |
2693 | |
2694 | (define_split | |
2695 | [(set (match_operand:TF 0 "memory_operand" "") | |
2696 | (match_operand:TF 1 "register_operand" ""))] | |
2697 | "(reload_completed | |
2a732575 JJ |
2698 | && offsettable_memref_p (operands[0]) |
2699 | && (! TARGET_ARCH64 | |
2700 | || ! TARGET_HARD_QUAD | |
2701 | || ! fp_register_operand (operands[1], TFmode)))" | |
e0d80184 | 2702 | [(clobber (const_int 0))] |
e0d80184 | 2703 | { |
ed8908e7 | 2704 | rtx set_src = operands[1]; |
ccd61a80 | 2705 | |
ed8908e7 RK |
2706 | emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0), |
2707 | gen_df_reg (set_src, 0))); | |
2708 | emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8), | |
2709 | gen_df_reg (set_src, 1))); | |
e0d80184 | 2710 | DONE; |
563facba | 2711 | }) |
f8ece000 EB |
2712 | |
2713 | ||
19047e4a | 2714 | ;; SPARC-V9 conditional move instructions |
a8d2b752 | 2715 | |
57b7e1bf | 2716 | ;; We can handle larger constants here for some flavors, but for now we keep |
5e7a8ee0 | 2717 | ;; it simple and only allow those constants supported by all flavors. |
304b7a23 DE |
2718 | ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand |
2719 | ;; 3 contains the constant if one is present, but we handle either for | |
2720 | ;; generality (sparc.c puts a constant in operand 2). | |
bf84f42d DM |
2721 | ;; |
2722 | ;; Our instruction patterns, on the other hand, canonicalize such that | |
2723 | ;; operand 3 must be the set destination. | |
304b7a23 | 2724 | |
19047e4a EB |
2725 | (define_expand "mov<I:mode>cc" |
2726 | [(set (match_operand:I 0 "register_operand" "") | |
2727 | (if_then_else:I (match_operand 1 "comparison_operator" "") | |
2728 | (match_operand:I 2 "arith10_operand" "") | |
2729 | (match_operand:I 3 "arith10_operand" "")))] | |
2730 | "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)" | |
cd5fb1ee | 2731 | { |
bf84f42d | 2732 | if (! sparc_expand_conditional_move (<I:MODE>mode, operands)) |
304b7a23 | 2733 | FAIL; |
bf84f42d | 2734 | DONE; |
f90b7a5a | 2735 | }) |
cd5fb1ee | 2736 | |
19047e4a EB |
2737 | (define_expand "mov<F:mode>cc" |
2738 | [(set (match_operand:F 0 "register_operand" "") | |
2739 | (if_then_else:F (match_operand 1 "comparison_operator" "") | |
2740 | (match_operand:F 2 "register_operand" "") | |
2741 | (match_operand:F 3 "register_operand" "")))] | |
304b7a23 | 2742 | "TARGET_V9 && TARGET_FPU" |
cd5fb1ee | 2743 | { |
bf84f42d | 2744 | if (! sparc_expand_conditional_move (<F:MODE>mode, operands)) |
304b7a23 | 2745 | FAIL; |
bf84f42d | 2746 | DONE; |
563facba | 2747 | }) |
cd5fb1ee | 2748 | |
19047e4a | 2749 | ;; Conditional move define_insns |
a8d2b752 | 2750 | |
19047e4a | 2751 | (define_insn "*mov<I:mode>_cc_v9" |
bf84f42d | 2752 | [(set (match_operand:I 0 "register_operand" "=r") |
19047e4a | 2753 | (if_then_else:I (match_operator 1 "comparison_operator" |
bf84f42d | 2754 | [(match_operand 2 "icc_or_fcc_register_operand" "X") |
19047e4a | 2755 | (const_int 0)]) |
bf84f42d DM |
2756 | (match_operand:I 3 "arith11_operand" "rL") |
2757 | (match_operand:I 4 "register_operand" "0")))] | |
19047e4a | 2758 | "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)" |
bf84f42d | 2759 | "mov%C1\t%x2, %3, %0" |
24697ca0 | 2760 | [(set_attr "type" "cmove")]) |
e0d80184 | 2761 | |
19047e4a | 2762 | (define_insn "*mov<I:mode>_cc_reg_sp64" |
bf84f42d | 2763 | [(set (match_operand:I 0 "register_operand" "=r") |
19047e4a | 2764 | (if_then_else:I (match_operator 1 "v9_register_compare_operator" |
bf84f42d | 2765 | [(match_operand:DI 2 "register_operand" "r") |
e0d80184 | 2766 | (const_int 0)]) |
bf84f42d DM |
2767 | (match_operand:I 3 "arith10_operand" "rM") |
2768 | (match_operand:I 4 "register_operand" "0")))] | |
e0d80184 | 2769 | "TARGET_ARCH64" |
bf84f42d | 2770 | "movr%D1\t%2, %r3, %0" |
24697ca0 | 2771 | [(set_attr "type" "cmove")]) |
a8d2b752 | 2772 | |
19047e4a | 2773 | (define_insn "*movsf_cc_v9" |
bf84f42d | 2774 | [(set (match_operand:SF 0 "register_operand" "=f") |
304b7a23 | 2775 | (if_then_else:SF (match_operator 1 "comparison_operator" |
bf84f42d | 2776 | [(match_operand 2 "icc_or_fcc_register_operand" "X") |
a8d2b752 | 2777 | (const_int 0)]) |
bf84f42d DM |
2778 | (match_operand:SF 3 "register_operand" "f") |
2779 | (match_operand:SF 4 "register_operand" "0")))] | |
304b7a23 | 2780 | "TARGET_V9 && TARGET_FPU" |
bf84f42d | 2781 | "fmovs%C1\t%x2, %3, %0" |
24697ca0 | 2782 | [(set_attr "type" "fpcmove")]) |
a8d2b752 | 2783 | |
19047e4a | 2784 | (define_insn "*movsf_cc_reg_sp64" |
bf84f42d | 2785 | [(set (match_operand:SF 0 "register_operand" "=f") |
19047e4a | 2786 | (if_then_else:SF (match_operator 1 "v9_register_compare_operator" |
bf84f42d | 2787 | [(match_operand:DI 2 "register_operand" "r") |
19047e4a | 2788 | (const_int 0)]) |
bf84f42d DM |
2789 | (match_operand:SF 3 "register_operand" "f") |
2790 | (match_operand:SF 4 "register_operand" "0")))] | |
19047e4a | 2791 | "TARGET_ARCH64 && TARGET_FPU" |
bf84f42d | 2792 | "fmovrs%D1\t%2, %3, %0" |
19047e4a EB |
2793 | [(set_attr "type" "fpcrmove")]) |
2794 | ||
2795 | ;; Named because invoked by movtf_cc_v9 | |
2796 | (define_insn "movdf_cc_v9" | |
bf84f42d | 2797 | [(set (match_operand:DF 0 "register_operand" "=e") |
304b7a23 | 2798 | (if_then_else:DF (match_operator 1 "comparison_operator" |
bf84f42d | 2799 | [(match_operand 2 "icc_or_fcc_register_operand" "X") |
a8d2b752 | 2800 | (const_int 0)]) |
bf84f42d DM |
2801 | (match_operand:DF 3 "register_operand" "e") |
2802 | (match_operand:DF 4 "register_operand" "0")))] | |
304b7a23 | 2803 | "TARGET_V9 && TARGET_FPU" |
bf84f42d | 2804 | "fmovd%C1\t%x2, %3, %0" |
e0d80184 | 2805 | [(set_attr "type" "fpcmove") |
24697ca0 | 2806 | (set_attr "fptype" "double")]) |
a8d2b752 | 2807 | |
19047e4a EB |
2808 | ;; Named because invoked by movtf_cc_reg_sp64 |
2809 | (define_insn "movdf_cc_reg_sp64" | |
bf84f42d | 2810 | [(set (match_operand:DF 0 "register_operand" "=e") |
19047e4a | 2811 | (if_then_else:DF (match_operator 1 "v9_register_compare_operator" |
bf84f42d | 2812 | [(match_operand:DI 2 "register_operand" "r") |
19047e4a | 2813 | (const_int 0)]) |
bf84f42d DM |
2814 | (match_operand:DF 3 "register_operand" "e") |
2815 | (match_operand:DF 4 "register_operand" "0")))] | |
19047e4a | 2816 | "TARGET_ARCH64 && TARGET_FPU" |
bf84f42d | 2817 | "fmovrd%D1\t%2, %3, %0" |
19047e4a EB |
2818 | [(set_attr "type" "fpcrmove") |
2819 | (set_attr "fptype" "double")]) | |
2820 | ||
2821 | (define_insn "*movtf_cc_hq_v9" | |
bf84f42d | 2822 | [(set (match_operand:TF 0 "register_operand" "=e") |
304b7a23 | 2823 | (if_then_else:TF (match_operator 1 "comparison_operator" |
bf84f42d | 2824 | [(match_operand 2 "icc_or_fcc_register_operand" "X") |
a8d2b752 | 2825 | (const_int 0)]) |
bf84f42d DM |
2826 | (match_operand:TF 3 "register_operand" "e") |
2827 | (match_operand:TF 4 "register_operand" "0")))] | |
5d4f5e87 | 2828 | "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" |
bf84f42d | 2829 | "fmovq%C1\t%x2, %3, %0" |
24697ca0 | 2830 | [(set_attr "type" "fpcmove")]) |
304b7a23 | 2831 | |
19047e4a | 2832 | (define_insn "*movtf_cc_reg_hq_sp64" |
bf84f42d | 2833 | [(set (match_operand:TF 0 "register_operand" "=e") |
19047e4a | 2834 | (if_then_else:TF (match_operator 1 "v9_register_compare_operator" |
bf84f42d | 2835 | [(match_operand:DI 2 "register_operand" "r") |
19047e4a | 2836 | (const_int 0)]) |
bf84f42d DM |
2837 | (match_operand:TF 3 "register_operand" "e") |
2838 | (match_operand:TF 4 "register_operand" "0")))] | |
19047e4a | 2839 | "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD" |
bf84f42d | 2840 | "fmovrq%D1\t%2, %3, %0" |
19047e4a EB |
2841 | [(set_attr "type" "fpcrmove")]) |
2842 | ||
2843 | (define_insn_and_split "*movtf_cc_v9" | |
bf84f42d | 2844 | [(set (match_operand:TF 0 "register_operand" "=e") |
ccd61a80 | 2845 | (if_then_else:TF (match_operator 1 "comparison_operator" |
bf84f42d | 2846 | [(match_operand 2 "icc_or_fcc_register_operand" "X") |
b776892b | 2847 | (const_int 0)]) |
bf84f42d DM |
2848 | (match_operand:TF 3 "register_operand" "e") |
2849 | (match_operand:TF 4 "register_operand" "0")))] | |
ccd61a80 DM |
2850 | "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD" |
2851 | "#" | |
b776892b | 2852 | "&& reload_completed" |
ccd61a80 | 2853 | [(clobber (const_int 0))] |
ccd61a80 DM |
2854 | { |
2855 | rtx set_dest = operands[0]; | |
2856 | rtx set_srca = operands[3]; | |
ccd61a80 | 2857 | rtx dest1, dest2; |
bf84f42d | 2858 | rtx srca1, srca2; |
ccd61a80 | 2859 | |
7b1ac798 JJ |
2860 | dest1 = gen_df_reg (set_dest, 0); |
2861 | dest2 = gen_df_reg (set_dest, 1); | |
2862 | srca1 = gen_df_reg (set_srca, 0); | |
2863 | srca2 = gen_df_reg (set_srca, 1); | |
ccd61a80 | 2864 | |
bf84f42d | 2865 | if (reg_overlap_mentioned_p (dest1, srca2)) |
ccd61a80 | 2866 | { |
bf84f42d DM |
2867 | emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2)); |
2868 | emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1)); | |
ccd61a80 DM |
2869 | } |
2870 | else | |
2871 | { | |
bf84f42d DM |
2872 | emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1)); |
2873 | emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2)); | |
ccd61a80 DM |
2874 | } |
2875 | DONE; | |
563facba | 2876 | } |
b776892b | 2877 | [(set_attr "length" "2")]) |
ccd61a80 | 2878 | |
b776892b | 2879 | (define_insn_and_split "*movtf_cc_reg_sp64" |
bf84f42d | 2880 | [(set (match_operand:TF 0 "register_operand" "=e") |
0e5d569c | 2881 | (if_then_else:TF (match_operator 1 "v9_register_compare_operator" |
bf84f42d | 2882 | [(match_operand:DI 2 "register_operand" "r") |
ccd61a80 | 2883 | (const_int 0)]) |
bf84f42d DM |
2884 | (match_operand:TF 3 "register_operand" "e") |
2885 | (match_operand:TF 4 "register_operand" "0")))] | |
ccd61a80 DM |
2886 | "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD" |
2887 | "#" | |
b776892b | 2888 | "&& reload_completed" |
ccd61a80 | 2889 | [(clobber (const_int 0))] |
ccd61a80 DM |
2890 | { |
2891 | rtx set_dest = operands[0]; | |
2892 | rtx set_srca = operands[3]; | |
ccd61a80 | 2893 | rtx dest1, dest2; |
bf84f42d | 2894 | rtx srca1, srca2; |
ccd61a80 | 2895 | |
7b1ac798 JJ |
2896 | dest1 = gen_df_reg (set_dest, 0); |
2897 | dest2 = gen_df_reg (set_dest, 1); | |
2898 | srca1 = gen_df_reg (set_srca, 0); | |
2899 | srca2 = gen_df_reg (set_srca, 1); | |
ccd61a80 | 2900 | |
bf84f42d | 2901 | if (reg_overlap_mentioned_p (dest1, srca2)) |
ccd61a80 | 2902 | { |
bf84f42d DM |
2903 | emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2)); |
2904 | emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1)); | |
ccd61a80 DM |
2905 | } |
2906 | else | |
2907 | { | |
bf84f42d DM |
2908 | emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1)); |
2909 | emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2)); | |
ccd61a80 DM |
2910 | } |
2911 | DONE; | |
563facba | 2912 | } |
b776892b | 2913 | [(set_attr "length" "2")]) |
ccd61a80 | 2914 | |
a8d2b752 | 2915 | \f |
f8ece000 | 2916 | ;; Zero-extension instructions |
7a768814 RS |
2917 | |
2918 | ;; These patterns originally accepted general_operands, however, slightly | |
2919 | ;; better code is generated by only accepting register_operands, and then | |
2920 | ;; letting combine generate the ldu[hb] insns. | |
2921 | ||
2922 | (define_expand "zero_extendhisi2" | |
2923 | [(set (match_operand:SI 0 "register_operand" "") | |
2924 | (zero_extend:SI (match_operand:HI 1 "register_operand" "")))] | |
2925 | "" | |
7a768814 RS |
2926 | { |
2927 | rtx temp = gen_reg_rtx (SImode); | |
5d4f5e87 | 2928 | rtx shift_16 = GEN_INT (16); |
ddef6bc7 | 2929 | int op1_subbyte = 0; |
7a768814 RS |
2930 | |
2931 | if (GET_CODE (operand1) == SUBREG) | |
053e4cac | 2932 | { |
ddef6bc7 JJ |
2933 | op1_subbyte = SUBREG_BYTE (operand1); |
2934 | op1_subbyte /= GET_MODE_SIZE (SImode); | |
2935 | op1_subbyte *= GET_MODE_SIZE (SImode); | |
053e4cac JW |
2936 | operand1 = XEXP (operand1, 0); |
2937 | } | |
7a768814 | 2938 | |
ddef6bc7 | 2939 | emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), |
7a768814 RS |
2940 | shift_16)); |
2941 | emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); | |
2942 | DONE; | |
563facba | 2943 | }) |
7a768814 | 2944 | |
c8b3b7d6 | 2945 | (define_insn "*zero_extendhisi2_insn" |
7a768814 RS |
2946 | [(set (match_operand:SI 0 "register_operand" "=r") |
2947 | (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] | |
2948 | "" | |
16b46035 | 2949 | "lduh\t%1, %0" |
fae15c93 VM |
2950 | [(set_attr "type" "load") |
2951 | (set_attr "us3load_type" "3cycle")]) | |
7a768814 RS |
2952 | |
2953 | (define_expand "zero_extendqihi2" | |
2954 | [(set (match_operand:HI 0 "register_operand" "") | |
2955 | (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] | |
2956 | "" | |
2957 | "") | |
2958 | ||
c8b3b7d6 | 2959 | (define_insn "*zero_extendqihi2_insn" |
b67bfdf7 | 2960 | [(set (match_operand:HI 0 "register_operand" "=r,r") |
e0d80184 | 2961 | (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))] |
7a768814 RS |
2962 | "GET_CODE (operands[1]) != CONST_INT" |
2963 | "@ | |
16b46035 DM |
2964 | and\t%1, 0xff, %0 |
2965 | ldub\t%1, %0" | |
fae15c93 VM |
2966 | [(set_attr "type" "*,load") |
2967 | (set_attr "us3load_type" "*,3cycle")]) | |
7a768814 RS |
2968 | |
2969 | (define_expand "zero_extendqisi2" | |
2970 | [(set (match_operand:SI 0 "register_operand" "") | |
2971 | (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] | |
2972 | "" | |
2973 | "") | |
2974 | ||
c8b3b7d6 | 2975 | (define_insn "*zero_extendqisi2_insn" |
b67bfdf7 | 2976 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
e0d80184 | 2977 | (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))] |
7a768814 RS |
2978 | "GET_CODE (operands[1]) != CONST_INT" |
2979 | "@ | |
16b46035 DM |
2980 | and\t%1, 0xff, %0 |
2981 | ldub\t%1, %0" | |
fae15c93 VM |
2982 | [(set_attr "type" "*,load") |
2983 | (set_attr "us3load_type" "*,3cycle")]) | |
7a768814 | 2984 | |
a8d2b752 DE |
2985 | (define_expand "zero_extendqidi2" |
2986 | [(set (match_operand:DI 0 "register_operand" "") | |
2987 | (zero_extend:DI (match_operand:QI 1 "register_operand" "")))] | |
fa0f39e4 | 2988 | "TARGET_ARCH64" |
a8d2b752 DE |
2989 | "") |
2990 | ||
c8b3b7d6 | 2991 | (define_insn "*zero_extendqidi2_insn" |
a8d2b752 | 2992 | [(set (match_operand:DI 0 "register_operand" "=r,r") |
e0d80184 | 2993 | (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))] |
fa0f39e4 | 2994 | "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT" |
a8d2b752 | 2995 | "@ |
16b46035 DM |
2996 | and\t%1, 0xff, %0 |
2997 | ldub\t%1, %0" | |
fae15c93 VM |
2998 | [(set_attr "type" "*,load") |
2999 | (set_attr "us3load_type" "*,3cycle")]) | |
a8d2b752 DE |
3000 | |
3001 | (define_expand "zero_extendhidi2" | |
3002 | [(set (match_operand:DI 0 "register_operand" "") | |
3003 | (zero_extend:DI (match_operand:HI 1 "register_operand" "")))] | |
fa0f39e4 | 3004 | "TARGET_ARCH64" |
a8d2b752 DE |
3005 | { |
3006 | rtx temp = gen_reg_rtx (DImode); | |
5d4f5e87 | 3007 | rtx shift_48 = GEN_INT (48); |
ddef6bc7 | 3008 | int op1_subbyte = 0; |
a8d2b752 DE |
3009 | |
3010 | if (GET_CODE (operand1) == SUBREG) | |
3011 | { | |
ddef6bc7 JJ |
3012 | op1_subbyte = SUBREG_BYTE (operand1); |
3013 | op1_subbyte /= GET_MODE_SIZE (DImode); | |
3014 | op1_subbyte *= GET_MODE_SIZE (DImode); | |
a8d2b752 DE |
3015 | operand1 = XEXP (operand1, 0); |
3016 | } | |
3017 | ||
ddef6bc7 | 3018 | emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte), |
a8d2b752 DE |
3019 | shift_48)); |
3020 | emit_insn (gen_lshrdi3 (operand0, temp, shift_48)); | |
3021 | DONE; | |
563facba | 3022 | }) |
a8d2b752 | 3023 | |
c8b3b7d6 | 3024 | (define_insn "*zero_extendhidi2_insn" |
a8d2b752 DE |
3025 | [(set (match_operand:DI 0 "register_operand" "=r") |
3026 | (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))] | |
fa0f39e4 | 3027 | "TARGET_ARCH64" |
16b46035 | 3028 | "lduh\t%1, %0" |
fae15c93 VM |
3029 | [(set_attr "type" "load") |
3030 | (set_attr "us3load_type" "3cycle")]) | |
a8d2b752 DE |
3031 | |
3032 | ;; ??? Write truncdisi pattern using sra? | |
3033 | ||
3034 | (define_expand "zero_extendsidi2" | |
3035 | [(set (match_operand:DI 0 "register_operand" "") | |
3036 | (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] | |
2a01c939 | 3037 | "" |
a8d2b752 DE |
3038 | "") |
3039 | ||
1b43bc82 | 3040 | (define_insn "*zero_extendsidi2_insn_sp64" |
bb12a72a DM |
3041 | [(set (match_operand:DI 0 "register_operand" "=r,r,r") |
3042 | (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))] | |
3043 | "TARGET_ARCH64 | |
bb12a72a DM |
3044 | && GET_CODE (operands[1]) != CONST_INT" |
3045 | "@ | |
3046 | srl\t%1, 0, %0 | |
3047 | lduw\t%1, %0 | |
3048 | movstouw\t%1, %0" | |
1b43bc82 DM |
3049 | [(set_attr "type" "shift,load,*") |
3050 | (set_attr "cpu_feature" "*,*,vis3")]) | |
bb12a72a | 3051 | |
b776892b | 3052 | (define_insn_and_split "*zero_extendsidi2_insn_sp32" |
2a01c939 DM |
3053 | [(set (match_operand:DI 0 "register_operand" "=r") |
3054 | (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))] | |
3055 | "! TARGET_ARCH64" | |
3056 | "#" | |
b776892b | 3057 | "&& reload_completed" |
2a01c939 DM |
3058 | [(set (match_dup 2) (match_dup 3)) |
3059 | (set (match_dup 4) (match_dup 5))] | |
2a01c939 DM |
3060 | { |
3061 | rtx dest1, dest2; | |
3062 | ||
2a01c939 DM |
3063 | dest1 = gen_highpart (SImode, operands[0]); |
3064 | dest2 = gen_lowpart (SImode, operands[0]); | |
3065 | ||
3066 | /* Swap the order in case of overlap. */ | |
3067 | if (REGNO (dest1) == REGNO (operands[1])) | |
3068 | { | |
3069 | operands[2] = dest2; | |
3070 | operands[3] = operands[1]; | |
3071 | operands[4] = dest1; | |
3072 | operands[5] = const0_rtx; | |
3073 | } | |
3074 | else | |
3075 | { | |
3076 | operands[2] = dest1; | |
3077 | operands[3] = const0_rtx; | |
3078 | operands[4] = dest2; | |
3079 | operands[5] = operands[1]; | |
3080 | } | |
563facba | 3081 | } |
b776892b | 3082 | [(set_attr "length" "2")]) |
2a01c939 | 3083 | |
a8d2b752 DE |
3084 | ;; Simplify comparisons of extended values. |
3085 | ||
c8b3b7d6 | 3086 | (define_insn "*cmp_zero_extendqisi2" |
45a7dd80 | 3087 | [(set (reg:CC CC_REG) |
7a768814 RS |
3088 | (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r")) |
3089 | (const_int 0)))] | |
e6c1be7e | 3090 | "" |
16b46035 | 3091 | "andcc\t%0, 0xff, %%g0" |
24697ca0 | 3092 | [(set_attr "type" "compare")]) |
7a768814 | 3093 | |
ce1531ab | 3094 | (define_insn "*cmp_zero_qi" |
45a7dd80 | 3095 | [(set (reg:CC CC_REG) |
ce1531ab JJ |
3096 | (compare:CC (match_operand:QI 0 "register_operand" "r") |
3097 | (const_int 0)))] | |
e6c1be7e | 3098 | "" |
16b46035 | 3099 | "andcc\t%0, 0xff, %%g0" |
24697ca0 | 3100 | [(set_attr "type" "compare")]) |
ce1531ab | 3101 | |
c8b3b7d6 | 3102 | (define_insn "*cmp_zero_extendqisi2_set" |
45a7dd80 | 3103 | [(set (reg:CC CC_REG) |
7a768814 RS |
3104 | (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) |
3105 | (const_int 0))) | |
3106 | (set (match_operand:SI 0 "register_operand" "=r") | |
3107 | (zero_extend:SI (match_dup 1)))] | |
3108 | "" | |
16b46035 | 3109 | "andcc\t%1, 0xff, %0" |
24697ca0 | 3110 | [(set_attr "type" "compare")]) |
e0d80184 | 3111 | |
ce1531ab | 3112 | (define_insn "*cmp_zero_extendqisi2_andcc_set" |
45a7dd80 | 3113 | [(set (reg:CC CC_REG) |
ce1531ab JJ |
3114 | (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r") |
3115 | (const_int 255)) | |
3116 | (const_int 0))) | |
3117 | (set (match_operand:SI 0 "register_operand" "=r") | |
3118 | (zero_extend:SI (subreg:QI (match_dup 1) 0)))] | |
3119 | "" | |
16b46035 | 3120 | "andcc\t%1, 0xff, %0" |
24697ca0 | 3121 | [(set_attr "type" "compare")]) |
ce1531ab | 3122 | |
e0d80184 | 3123 | (define_insn "*cmp_zero_extendqidi2" |
45a7dd80 | 3124 | [(set (reg:CCX CC_REG) |
e0d80184 DM |
3125 | (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r")) |
3126 | (const_int 0)))] | |
3127 | "TARGET_ARCH64" | |
16b46035 | 3128 | "andcc\t%0, 0xff, %%g0" |
24697ca0 | 3129 | [(set_attr "type" "compare")]) |
e0d80184 | 3130 | |
ce1531ab | 3131 | (define_insn "*cmp_zero_qi_sp64" |
45a7dd80 | 3132 | [(set (reg:CCX CC_REG) |
ce1531ab JJ |
3133 | (compare:CCX (match_operand:QI 0 "register_operand" "r") |
3134 | (const_int 0)))] | |
3135 | "TARGET_ARCH64" | |
16b46035 | 3136 | "andcc\t%0, 0xff, %%g0" |
24697ca0 | 3137 | [(set_attr "type" "compare")]) |
ce1531ab | 3138 | |
e0d80184 | 3139 | (define_insn "*cmp_zero_extendqidi2_set" |
45a7dd80 | 3140 | [(set (reg:CCX CC_REG) |
e0d80184 DM |
3141 | (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r")) |
3142 | (const_int 0))) | |
3143 | (set (match_operand:DI 0 "register_operand" "=r") | |
3144 | (zero_extend:DI (match_dup 1)))] | |
3145 | "TARGET_ARCH64" | |
16b46035 | 3146 | "andcc\t%1, 0xff, %0" |
24697ca0 | 3147 | [(set_attr "type" "compare")]) |
d21a353d | 3148 | |
ce1531ab | 3149 | (define_insn "*cmp_zero_extendqidi2_andcc_set" |
45a7dd80 | 3150 | [(set (reg:CCX CC_REG) |
ce1531ab JJ |
3151 | (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r") |
3152 | (const_int 255)) | |
3153 | (const_int 0))) | |
3154 | (set (match_operand:DI 0 "register_operand" "=r") | |
3155 | (zero_extend:DI (subreg:QI (match_dup 1) 0)))] | |
3156 | "TARGET_ARCH64" | |
16b46035 | 3157 | "andcc\t%1, 0xff, %0" |
24697ca0 | 3158 | [(set_attr "type" "compare")]) |
ce1531ab | 3159 | |
e0d80184 | 3160 | ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare. |
d21a353d | 3161 | |
c8b3b7d6 | 3162 | (define_insn "*cmp_siqi_trunc" |
45a7dd80 | 3163 | [(set (reg:CC CC_REG) |
ddef6bc7 | 3164 | (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3) |
d21a353d | 3165 | (const_int 0)))] |
e6c1be7e | 3166 | "" |
16b46035 | 3167 | "andcc\t%0, 0xff, %%g0" |
24697ca0 | 3168 | [(set_attr "type" "compare")]) |
d21a353d | 3169 | |
c8b3b7d6 | 3170 | (define_insn "*cmp_siqi_trunc_set" |
45a7dd80 | 3171 | [(set (reg:CC CC_REG) |
ddef6bc7 | 3172 | (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3) |
d21a353d JW |
3173 | (const_int 0))) |
3174 | (set (match_operand:QI 0 "register_operand" "=r") | |
ddef6bc7 | 3175 | (subreg:QI (match_dup 1) 3))] |
d21a353d | 3176 | "" |
16b46035 | 3177 | "andcc\t%1, 0xff, %0" |
24697ca0 | 3178 | [(set_attr "type" "compare")]) |
e0d80184 DM |
3179 | |
3180 | (define_insn "*cmp_diqi_trunc" | |
45a7dd80 | 3181 | [(set (reg:CC CC_REG) |
ddef6bc7 | 3182 | (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7) |
e0d80184 DM |
3183 | (const_int 0)))] |
3184 | "TARGET_ARCH64" | |
16b46035 | 3185 | "andcc\t%0, 0xff, %%g0" |
24697ca0 | 3186 | [(set_attr "type" "compare")]) |
e0d80184 DM |
3187 | |
3188 | (define_insn "*cmp_diqi_trunc_set" | |
45a7dd80 | 3189 | [(set (reg:CC CC_REG) |
ddef6bc7 | 3190 | (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7) |
e0d80184 DM |
3191 | (const_int 0))) |
3192 | (set (match_operand:QI 0 "register_operand" "=r") | |
ddef6bc7 | 3193 | (subreg:QI (match_dup 1) 7))] |
e0d80184 | 3194 | "TARGET_ARCH64" |
16b46035 | 3195 | "andcc\t%1, 0xff, %0" |
24697ca0 | 3196 | [(set_attr "type" "compare")]) |
7a768814 | 3197 | \f |
f8ece000 EB |
3198 | |
3199 | ;; Sign-extension instructions | |
7a768814 RS |
3200 | |
3201 | ;; These patterns originally accepted general_operands, however, slightly | |
3202 | ;; better code is generated by only accepting register_operands, and then | |
3203 | ;; letting combine generate the lds[hb] insns. | |
3204 | ||
3205 | (define_expand "extendhisi2" | |
3206 | [(set (match_operand:SI 0 "register_operand" "") | |
3207 | (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] | |
3208 | "" | |
7a768814 RS |
3209 | { |
3210 | rtx temp = gen_reg_rtx (SImode); | |
5d4f5e87 | 3211 | rtx shift_16 = GEN_INT (16); |
ddef6bc7 | 3212 | int op1_subbyte = 0; |
7a768814 RS |
3213 | |
3214 | if (GET_CODE (operand1) == SUBREG) | |
053e4cac | 3215 | { |
ddef6bc7 JJ |
3216 | op1_subbyte = SUBREG_BYTE (operand1); |
3217 | op1_subbyte /= GET_MODE_SIZE (SImode); | |
3218 | op1_subbyte *= GET_MODE_SIZE (SImode); | |
053e4cac JW |
3219 | operand1 = XEXP (operand1, 0); |
3220 | } | |
7a768814 | 3221 | |
ddef6bc7 | 3222 | emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), |
7a768814 RS |
3223 | shift_16)); |
3224 | emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); | |
3225 | DONE; | |
563facba | 3226 | }) |
7a768814 | 3227 | |
c8b3b7d6 | 3228 | (define_insn "*sign_extendhisi2_insn" |
7a768814 RS |
3229 | [(set (match_operand:SI 0 "register_operand" "=r") |
3230 | (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] | |
3231 | "" | |
16b46035 | 3232 | "ldsh\t%1, %0" |
fae15c93 VM |
3233 | [(set_attr "type" "sload") |
3234 | (set_attr "us3load_type" "3cycle")]) | |
7a768814 | 3235 | |
a8d2b752 DE |
3236 | (define_expand "extendqihi2" |
3237 | [(set (match_operand:HI 0 "register_operand" "") | |
3238 | (sign_extend:HI (match_operand:QI 1 "register_operand" "")))] | |
3239 | "" | |
a8d2b752 DE |
3240 | { |
3241 | rtx temp = gen_reg_rtx (SImode); | |
5d4f5e87 | 3242 | rtx shift_24 = GEN_INT (24); |
ddef6bc7 JJ |
3243 | int op1_subbyte = 0; |
3244 | int op0_subbyte = 0; | |
a8d2b752 DE |
3245 | |
3246 | if (GET_CODE (operand1) == SUBREG) | |
3247 | { | |
ddef6bc7 JJ |
3248 | op1_subbyte = SUBREG_BYTE (operand1); |
3249 | op1_subbyte /= GET_MODE_SIZE (SImode); | |
3250 | op1_subbyte *= GET_MODE_SIZE (SImode); | |
a8d2b752 DE |
3251 | operand1 = XEXP (operand1, 0); |
3252 | } | |
3253 | if (GET_CODE (operand0) == SUBREG) | |
3254 | { | |
ddef6bc7 JJ |
3255 | op0_subbyte = SUBREG_BYTE (operand0); |
3256 | op0_subbyte /= GET_MODE_SIZE (SImode); | |
3257 | op0_subbyte *= GET_MODE_SIZE (SImode); | |
a8d2b752 DE |
3258 | operand0 = XEXP (operand0, 0); |
3259 | } | |
ddef6bc7 | 3260 | emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), |
a8d2b752 DE |
3261 | shift_24)); |
3262 | if (GET_MODE (operand0) != SImode) | |
ddef6bc7 | 3263 | operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte); |
a8d2b752 DE |
3264 | emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); |
3265 | DONE; | |
563facba | 3266 | }) |
a8d2b752 | 3267 | |
c8b3b7d6 | 3268 | (define_insn "*sign_extendqihi2_insn" |
a8d2b752 DE |
3269 | [(set (match_operand:HI 0 "register_operand" "=r") |
3270 | (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] | |
3271 | "" | |
16b46035 | 3272 | "ldsb\t%1, %0" |
fae15c93 VM |
3273 | [(set_attr "type" "sload") |
3274 | (set_attr "us3load_type" "3cycle")]) | |
a8d2b752 DE |
3275 | |
3276 | (define_expand "extendqisi2" | |
3277 | [(set (match_operand:SI 0 "register_operand" "") | |
3278 | (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] | |
3279 | "" | |
a8d2b752 DE |
3280 | { |
3281 | rtx temp = gen_reg_rtx (SImode); | |
5d4f5e87 | 3282 | rtx shift_24 = GEN_INT (24); |
ddef6bc7 | 3283 | int op1_subbyte = 0; |
a8d2b752 DE |
3284 | |
3285 | if (GET_CODE (operand1) == SUBREG) | |
3286 | { | |
ddef6bc7 JJ |
3287 | op1_subbyte = SUBREG_BYTE (operand1); |
3288 | op1_subbyte /= GET_MODE_SIZE (SImode); | |
3289 | op1_subbyte *= GET_MODE_SIZE (SImode); | |
a8d2b752 DE |
3290 | operand1 = XEXP (operand1, 0); |
3291 | } | |
3292 | ||
ddef6bc7 | 3293 | emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), |
a8d2b752 DE |
3294 | shift_24)); |
3295 | emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); | |
3296 | DONE; | |
563facba | 3297 | }) |
a8d2b752 | 3298 | |
c8b3b7d6 | 3299 | (define_insn "*sign_extendqisi2_insn" |
a8d2b752 DE |
3300 | [(set (match_operand:SI 0 "register_operand" "=r") |
3301 | (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] | |
3302 | "" | |
16b46035 | 3303 | "ldsb\t%1, %0" |
fae15c93 VM |
3304 | [(set_attr "type" "sload") |
3305 | (set_attr "us3load_type" "3cycle")]) | |
a8d2b752 DE |
3306 | |
3307 | (define_expand "extendqidi2" | |
3308 | [(set (match_operand:DI 0 "register_operand" "") | |
3309 | (sign_extend:DI (match_operand:QI 1 "register_operand" "")))] | |
fa0f39e4 | 3310 | "TARGET_ARCH64" |
7a768814 | 3311 | { |
a8d2b752 | 3312 | rtx temp = gen_reg_rtx (DImode); |
5d4f5e87 | 3313 | rtx shift_56 = GEN_INT (56); |
ddef6bc7 | 3314 | int op1_subbyte = 0; |
7a768814 RS |
3315 | |
3316 | if (GET_CODE (operand1) == SUBREG) | |
053e4cac | 3317 | { |
ddef6bc7 JJ |
3318 | op1_subbyte = SUBREG_BYTE (operand1); |
3319 | op1_subbyte /= GET_MODE_SIZE (DImode); | |
3320 | op1_subbyte *= GET_MODE_SIZE (DImode); | |
053e4cac JW |
3321 | operand1 = XEXP (operand1, 0); |
3322 | } | |
a8d2b752 | 3323 | |
ddef6bc7 | 3324 | emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte), |
a8d2b752 DE |
3325 | shift_56)); |
3326 | emit_insn (gen_ashrdi3 (operand0, temp, shift_56)); | |
7a768814 | 3327 | DONE; |
563facba | 3328 | }) |
7a768814 | 3329 | |
c8b3b7d6 | 3330 | (define_insn "*sign_extendqidi2_insn" |
a8d2b752 DE |
3331 | [(set (match_operand:DI 0 "register_operand" "=r") |
3332 | (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))] | |
fa0f39e4 | 3333 | "TARGET_ARCH64" |
16b46035 | 3334 | "ldsb\t%1, %0" |
fae15c93 VM |
3335 | [(set_attr "type" "sload") |
3336 | (set_attr "us3load_type" "3cycle")]) | |
7a768814 | 3337 | |
a8d2b752 DE |
3338 | (define_expand "extendhidi2" |
3339 | [(set (match_operand:DI 0 "register_operand" "") | |
3340 | (sign_extend:DI (match_operand:HI 1 "register_operand" "")))] | |
fa0f39e4 | 3341 | "TARGET_ARCH64" |
7a768814 | 3342 | { |
a8d2b752 | 3343 | rtx temp = gen_reg_rtx (DImode); |
5d4f5e87 | 3344 | rtx shift_48 = GEN_INT (48); |
ddef6bc7 | 3345 | int op1_subbyte = 0; |
7a768814 RS |
3346 | |
3347 | if (GET_CODE (operand1) == SUBREG) | |
053e4cac | 3348 | { |
ddef6bc7 JJ |
3349 | op1_subbyte = SUBREG_BYTE (operand1); |
3350 | op1_subbyte /= GET_MODE_SIZE (DImode); | |
3351 | op1_subbyte *= GET_MODE_SIZE (DImode); | |
053e4cac JW |
3352 | operand1 = XEXP (operand1, 0); |
3353 | } | |
3354 | ||
ddef6bc7 | 3355 | emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte), |
a8d2b752 DE |
3356 | shift_48)); |
3357 | emit_insn (gen_ashrdi3 (operand0, temp, shift_48)); | |
7a768814 | 3358 | DONE; |
563facba | 3359 | }) |
7a768814 | 3360 | |
c8b3b7d6 | 3361 | (define_insn "*sign_extendhidi2_insn" |
a8d2b752 DE |
3362 | [(set (match_operand:DI 0 "register_operand" "=r") |
3363 | (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))] | |
fa0f39e4 | 3364 | "TARGET_ARCH64" |
16b46035 | 3365 | "ldsh\t%1, %0" |
fae15c93 VM |
3366 | [(set_attr "type" "sload") |
3367 | (set_attr "us3load_type" "3cycle")]) | |
a8d2b752 DE |
3368 | |
3369 | (define_expand "extendsidi2" | |
3370 | [(set (match_operand:DI 0 "register_operand" "") | |
3371 | (sign_extend:DI (match_operand:SI 1 "register_operand" "")))] | |
fa0f39e4 | 3372 | "TARGET_ARCH64" |
a8d2b752 DE |
3373 | "") |
3374 | ||
1b43bc82 | 3375 | (define_insn "*sign_extendsidi2_insn" |
bb12a72a DM |
3376 | [(set (match_operand:DI 0 "register_operand" "=r,r,r") |
3377 | (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))] | |
1b43bc82 | 3378 | "TARGET_ARCH64" |
bb12a72a DM |
3379 | "@ |
3380 | sra\t%1, 0, %0 | |
3381 | ldsw\t%1, %0 | |
3382 | movstosw\t%1, %0" | |
3383 | [(set_attr "type" "shift,sload,*") | |
1b43bc82 DM |
3384 | (set_attr "us3load_type" "*,3cycle,*") |
3385 | (set_attr "cpu_feature" "*,*,vis3")]) | |
bb12a72a | 3386 | |
f8ece000 | 3387 | |
b4ac57ab RS |
3388 | ;; Special pattern for optimizing bit-field compares. This is needed |
3389 | ;; because combine uses this as a canonical form. | |
3390 | ||
c8b3b7d6 | 3391 | (define_insn "*cmp_zero_extract" |
45a7dd80 | 3392 | [(set (reg:CC CC_REG) |
b4ac57ab RS |
3393 | (compare:CC |
3394 | (zero_extract:SI (match_operand:SI 0 "register_operand" "r") | |
0e5d569c EB |
3395 | (match_operand:SI 1 "small_int_operand" "I") |
3396 | (match_operand:SI 2 "small_int_operand" "I")) | |
b4ac57ab | 3397 | (const_int 0)))] |
0e5d569c EB |
3398 | "INTVAL (operands[2]) > 19" |
3399 | { | |
3400 | int len = INTVAL (operands[1]); | |
3401 | int pos = 32 - INTVAL (operands[2]) - len; | |
f710f868 | 3402 | HOST_WIDE_INT mask = ((1 << len) - 1) << pos; |
5d4f5e87 | 3403 | operands[1] = GEN_INT (mask); |
16b46035 | 3404 | return "andcc\t%0, %1, %%g0"; |
563facba | 3405 | } |
24697ca0 | 3406 | [(set_attr "type" "compare")]) |
a8d2b752 | 3407 | |
c8b3b7d6 | 3408 | (define_insn "*cmp_zero_extract_sp64" |
45a7dd80 | 3409 | [(set (reg:CCX CC_REG) |
a8d2b752 DE |
3410 | (compare:CCX |
3411 | (zero_extract:DI (match_operand:DI 0 "register_operand" "r") | |
0e5d569c EB |
3412 | (match_operand:SI 1 "small_int_operand" "I") |
3413 | (match_operand:SI 2 "small_int_operand" "I")) | |
a8d2b752 | 3414 | (const_int 0)))] |
0e5d569c EB |
3415 | "TARGET_ARCH64 && INTVAL (operands[2]) > 51" |
3416 | { | |
3417 | int len = INTVAL (operands[1]); | |
3418 | int pos = 64 - INTVAL (operands[2]) - len; | |
f710f868 | 3419 | HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos; |
5d4f5e87 | 3420 | operands[1] = GEN_INT (mask); |
16b46035 | 3421 | return "andcc\t%0, %1, %%g0"; |
563facba | 3422 | } |
24697ca0 | 3423 | [(set_attr "type" "compare")]) |
f8ece000 EB |
3424 | |
3425 | ||
795068a4 | 3426 | ;; Conversions between float, double and long double. |
7a768814 RS |
3427 | |
3428 | (define_insn "extendsfdf2" | |
b6d3c4ba | 3429 | [(set (match_operand:DF 0 "register_operand" "=e") |
7a768814 RS |
3430 | (float_extend:DF |
3431 | (match_operand:SF 1 "register_operand" "f")))] | |
ab5519b7 | 3432 | "TARGET_FPU" |
16b46035 | 3433 | "fstod\t%1, %0" |
e0d80184 | 3434 | [(set_attr "type" "fp") |
24697ca0 | 3435 | (set_attr "fptype" "double")]) |
7a768814 | 3436 | |
47ac041c | 3437 | (define_expand "extendsftf2" |
73985940 | 3438 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
47ac041c | 3439 | (float_extend:TF |
73985940 | 3440 | (match_operand:SF 1 "register_operand" "")))] |
47ac041c | 3441 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
73985940 | 3442 | "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;") |
47ac041c JJ |
3443 | |
3444 | (define_insn "*extendsftf2_hq" | |
b6d3c4ba | 3445 | [(set (match_operand:TF 0 "register_operand" "=e") |
795068a4 JW |
3446 | (float_extend:TF |
3447 | (match_operand:SF 1 "register_operand" "f")))] | |
ef903eca | 3448 | "TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 3449 | "fstoq\t%1, %0" |
24697ca0 | 3450 | [(set_attr "type" "fp")]) |
795068a4 | 3451 | |
47ac041c | 3452 | (define_expand "extenddftf2" |
73985940 | 3453 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
47ac041c | 3454 | (float_extend:TF |
73985940 | 3455 | (match_operand:DF 1 "register_operand" "")))] |
47ac041c | 3456 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
73985940 | 3457 | "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;") |
47ac041c JJ |
3458 | |
3459 | (define_insn "*extenddftf2_hq" | |
b6d3c4ba | 3460 | [(set (match_operand:TF 0 "register_operand" "=e") |
795068a4 | 3461 | (float_extend:TF |
b6d3c4ba | 3462 | (match_operand:DF 1 "register_operand" "e")))] |
ef903eca | 3463 | "TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 3464 | "fdtoq\t%1, %0" |
24697ca0 | 3465 | [(set_attr "type" "fp")]) |
795068a4 | 3466 | |
7a768814 RS |
3467 | (define_insn "truncdfsf2" |
3468 | [(set (match_operand:SF 0 "register_operand" "=f") | |
3469 | (float_truncate:SF | |
b6d3c4ba | 3470 | (match_operand:DF 1 "register_operand" "e")))] |
ab5519b7 | 3471 | "TARGET_FPU" |
16b46035 | 3472 | "fdtos\t%1, %0" |
e0d80184 | 3473 | [(set_attr "type" "fp") |
24697ca0 | 3474 | (set_attr "fptype" "double")]) |
795068a4 | 3475 | |
47ac041c | 3476 | (define_expand "trunctfsf2" |
73985940 | 3477 | [(set (match_operand:SF 0 "register_operand" "") |
47ac041c | 3478 | (float_truncate:SF |
73985940 | 3479 | (match_operand:TF 1 "general_operand" "")))] |
47ac041c | 3480 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
73985940 | 3481 | "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;") |
47ac041c JJ |
3482 | |
3483 | (define_insn "*trunctfsf2_hq" | |
795068a4 JW |
3484 | [(set (match_operand:SF 0 "register_operand" "=f") |
3485 | (float_truncate:SF | |
b6d3c4ba | 3486 | (match_operand:TF 1 "register_operand" "e")))] |
ef903eca | 3487 | "TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 3488 | "fqtos\t%1, %0" |
24697ca0 | 3489 | [(set_attr "type" "fp")]) |
795068a4 | 3490 | |
47ac041c | 3491 | (define_expand "trunctfdf2" |
73985940 | 3492 | [(set (match_operand:DF 0 "register_operand" "") |
47ac041c | 3493 | (float_truncate:DF |
73985940 | 3494 | (match_operand:TF 1 "general_operand" "")))] |
47ac041c | 3495 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
73985940 | 3496 | "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;") |
47ac041c JJ |
3497 | |
3498 | (define_insn "*trunctfdf2_hq" | |
b6d3c4ba | 3499 | [(set (match_operand:DF 0 "register_operand" "=e") |
795068a4 | 3500 | (float_truncate:DF |
b6d3c4ba | 3501 | (match_operand:TF 1 "register_operand" "e")))] |
ef903eca | 3502 | "TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 3503 | "fqtod\t%1, %0" |
24697ca0 | 3504 | [(set_attr "type" "fp")]) |
f8ece000 EB |
3505 | |
3506 | ||
7a768814 RS |
3507 | ;; Conversion between fixed point and floating point. |
3508 | ||
3509 | (define_insn "floatsisf2" | |
ec08cf0a JW |
3510 | [(set (match_operand:SF 0 "register_operand" "=f") |
3511 | (float:SF (match_operand:SI 1 "register_operand" "f")))] | |
ab5519b7 | 3512 | "TARGET_FPU" |
16b46035 | 3513 | "fitos\t%1, %0" |
e0d80184 | 3514 | [(set_attr "type" "fp") |
24697ca0 | 3515 | (set_attr "fptype" "double")]) |
7a768814 RS |
3516 | |
3517 | (define_insn "floatsidf2" | |
b6d3c4ba | 3518 | [(set (match_operand:DF 0 "register_operand" "=e") |
ec08cf0a | 3519 | (float:DF (match_operand:SI 1 "register_operand" "f")))] |
ab5519b7 | 3520 | "TARGET_FPU" |
16b46035 | 3521 | "fitod\t%1, %0" |
e0d80184 | 3522 | [(set_attr "type" "fp") |
24697ca0 | 3523 | (set_attr "fptype" "double")]) |
7a768814 | 3524 | |
47ac041c | 3525 | (define_expand "floatsitf2" |
73985940 RH |
3526 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
3527 | (float:TF (match_operand:SI 1 "register_operand" "")))] | |
47ac041c | 3528 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
73985940 | 3529 | "emit_tfmode_cvt (FLOAT, operands); DONE;") |
47ac041c JJ |
3530 | |
3531 | (define_insn "*floatsitf2_hq" | |
b6d3c4ba | 3532 | [(set (match_operand:TF 0 "register_operand" "=e") |
ec08cf0a | 3533 | (float:TF (match_operand:SI 1 "register_operand" "f")))] |
ef903eca | 3534 | "TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 3535 | "fitoq\t%1, %0" |
24697ca0 | 3536 | [(set_attr "type" "fp")]) |
795068a4 | 3537 | |
47ac041c | 3538 | (define_expand "floatunssitf2" |
73985940 RH |
3539 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
3540 | (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))] | |
47ac041c | 3541 | "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" |
73985940 | 3542 | "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;") |
47ac041c | 3543 | |
a8d2b752 | 3544 | ;; Now the same for 64 bit sources. |
a8d2b752 | 3545 | |
284d86e9 | 3546 | (define_insn "floatdisf2" |
a8d2b752 | 3547 | [(set (match_operand:SF 0 "register_operand" "=f") |
b6d3c4ba | 3548 | (float:SF (match_operand:DI 1 "register_operand" "e")))] |
284d86e9 | 3549 | "TARGET_V9 && TARGET_FPU" |
16b46035 | 3550 | "fxtos\t%1, %0" |
e0d80184 | 3551 | [(set_attr "type" "fp") |
24697ca0 | 3552 | (set_attr "fptype" "double")]) |
a8d2b752 | 3553 | |
d88e57d1 RH |
3554 | (define_expand "floatunsdisf2" |
3555 | [(use (match_operand:SF 0 "register_operand" "")) | |
b178305d | 3556 | (use (match_operand:DI 1 "general_operand" ""))] |
d88e57d1 | 3557 | "TARGET_ARCH64 && TARGET_FPU" |
b178305d | 3558 | "sparc_emit_floatunsdi (operands, SFmode); DONE;") |
d88e57d1 | 3559 | |
284d86e9 | 3560 | (define_insn "floatdidf2" |
b6d3c4ba JW |
3561 | [(set (match_operand:DF 0 "register_operand" "=e") |
3562 | (float:DF (match_operand:DI 1 "register_operand" "e")))] | |
284d86e9 | 3563 | "TARGET_V9 && TARGET_FPU" |
16b46035 | 3564 | "fxtod\t%1, %0" |
e0d80184 | 3565 | [(set_attr "type" "fp") |
24697ca0 | 3566 | (set_attr "fptype" "double")]) |
a8d2b752 | 3567 | |
d88e57d1 RH |
3568 | (define_expand "floatunsdidf2" |
3569 | [(use (match_operand:DF 0 "register_operand" "")) | |
b178305d | 3570 | (use (match_operand:DI 1 "general_operand" ""))] |
d88e57d1 | 3571 | "TARGET_ARCH64 && TARGET_FPU" |
b178305d | 3572 | "sparc_emit_floatunsdi (operands, DFmode); DONE;") |
d88e57d1 | 3573 | |
47ac041c | 3574 | (define_expand "floatditf2" |
73985940 RH |
3575 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
3576 | (float:TF (match_operand:DI 1 "register_operand" "")))] | |
47ac041c | 3577 | "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
73985940 | 3578 | "emit_tfmode_cvt (FLOAT, operands); DONE;") |
47ac041c JJ |
3579 | |
3580 | (define_insn "*floatditf2_hq" | |
b6d3c4ba JW |
3581 | [(set (match_operand:TF 0 "register_operand" "=e") |
3582 | (float:TF (match_operand:DI 1 "register_operand" "e")))] | |
284d86e9 | 3583 | "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 3584 | "fxtoq\t%1, %0" |
24697ca0 | 3585 | [(set_attr "type" "fp")]) |
a8d2b752 | 3586 | |
47ac041c | 3587 | (define_expand "floatunsditf2" |
73985940 RH |
3588 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
3589 | (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))] | |
47ac041c | 3590 | "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" |
73985940 | 3591 | "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;") |
47ac041c | 3592 | |
7a768814 RS |
3593 | ;; Convert a float to an actual integer. |
3594 | ;; Truncation is performed as part of the conversion. | |
3595 | ||
3596 | (define_insn "fix_truncsfsi2" | |
ec08cf0a JW |
3597 | [(set (match_operand:SI 0 "register_operand" "=f") |
3598 | (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] | |
ab5519b7 | 3599 | "TARGET_FPU" |
16b46035 | 3600 | "fstoi\t%1, %0" |
e0d80184 | 3601 | [(set_attr "type" "fp") |
24697ca0 | 3602 | (set_attr "fptype" "double")]) |
7a768814 RS |
3603 | |
3604 | (define_insn "fix_truncdfsi2" | |
ec08cf0a | 3605 | [(set (match_operand:SI 0 "register_operand" "=f") |
b6d3c4ba | 3606 | (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))] |
ab5519b7 | 3607 | "TARGET_FPU" |
16b46035 | 3608 | "fdtoi\t%1, %0" |
e0d80184 | 3609 | [(set_attr "type" "fp") |
24697ca0 | 3610 | (set_attr "fptype" "double")]) |
a3ee5899 | 3611 | |
47ac041c | 3612 | (define_expand "fix_trunctfsi2" |
73985940 RH |
3613 | [(set (match_operand:SI 0 "register_operand" "") |
3614 | (fix:SI (match_operand:TF 1 "general_operand" "")))] | |
47ac041c | 3615 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
73985940 | 3616 | "emit_tfmode_cvt (FIX, operands); DONE;") |
47ac041c JJ |
3617 | |
3618 | (define_insn "*fix_trunctfsi2_hq" | |
ec08cf0a | 3619 | [(set (match_operand:SI 0 "register_operand" "=f") |
73985940 | 3620 | (fix:SI (match_operand:TF 1 "register_operand" "e")))] |
ef903eca | 3621 | "TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 3622 | "fqtoi\t%1, %0" |
24697ca0 | 3623 | [(set_attr "type" "fp")]) |
a8d2b752 | 3624 | |
47ac041c | 3625 | (define_expand "fixuns_trunctfsi2" |
73985940 RH |
3626 | [(set (match_operand:SI 0 "register_operand" "") |
3627 | (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))] | |
47ac041c | 3628 | "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" |
73985940 | 3629 | "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;") |
47ac041c | 3630 | |
284d86e9 | 3631 | ;; Now the same, for V9 targets |
a8d2b752 | 3632 | |
284d86e9 | 3633 | (define_insn "fix_truncsfdi2" |
b6d3c4ba | 3634 | [(set (match_operand:DI 0 "register_operand" "=e") |
a8d2b752 | 3635 | (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] |
284d86e9 | 3636 | "TARGET_V9 && TARGET_FPU" |
16b46035 | 3637 | "fstox\t%1, %0" |
e0d80184 | 3638 | [(set_attr "type" "fp") |
24697ca0 | 3639 | (set_attr "fptype" "double")]) |
a8d2b752 | 3640 | |
b178305d EB |
3641 | (define_expand "fixuns_truncsfdi2" |
3642 | [(use (match_operand:DI 0 "register_operand" "")) | |
3643 | (use (match_operand:SF 1 "general_operand" ""))] | |
3644 | "TARGET_ARCH64 && TARGET_FPU" | |
3645 | "sparc_emit_fixunsdi (operands, SFmode); DONE;") | |
3646 | ||
284d86e9 | 3647 | (define_insn "fix_truncdfdi2" |
b6d3c4ba JW |
3648 | [(set (match_operand:DI 0 "register_operand" "=e") |
3649 | (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))] | |
284d86e9 | 3650 | "TARGET_V9 && TARGET_FPU" |
16b46035 | 3651 | "fdtox\t%1, %0" |
e0d80184 | 3652 | [(set_attr "type" "fp") |
24697ca0 | 3653 | (set_attr "fptype" "double")]) |
a8d2b752 | 3654 | |
b178305d EB |
3655 | (define_expand "fixuns_truncdfdi2" |
3656 | [(use (match_operand:DI 0 "register_operand" "")) | |
3657 | (use (match_operand:DF 1 "general_operand" ""))] | |
3658 | "TARGET_ARCH64 && TARGET_FPU" | |
3659 | "sparc_emit_fixunsdi (operands, DFmode); DONE;") | |
3660 | ||
47ac041c | 3661 | (define_expand "fix_trunctfdi2" |
73985940 RH |
3662 | [(set (match_operand:DI 0 "register_operand" "") |
3663 | (fix:DI (match_operand:TF 1 "general_operand" "")))] | |
47ac041c | 3664 | "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
73985940 | 3665 | "emit_tfmode_cvt (FIX, operands); DONE;") |
47ac041c JJ |
3666 | |
3667 | (define_insn "*fix_trunctfdi2_hq" | |
b6d3c4ba | 3668 | [(set (match_operand:DI 0 "register_operand" "=e") |
73985940 | 3669 | (fix:DI (match_operand:TF 1 "register_operand" "e")))] |
284d86e9 | 3670 | "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 3671 | "fqtox\t%1, %0" |
24697ca0 | 3672 | [(set_attr "type" "fp")]) |
47ac041c JJ |
3673 | |
3674 | (define_expand "fixuns_trunctfdi2" | |
73985940 RH |
3675 | [(set (match_operand:DI 0 "register_operand" "") |
3676 | (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))] | |
47ac041c | 3677 | "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" |
73985940 | 3678 | "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;") |
0e5d569c | 3679 | |
f8ece000 EB |
3680 | |
3681 | ;; Integer addition/subtraction instructions. | |
7a768814 | 3682 | |
a8d2b752 | 3683 | (define_expand "adddi3" |
ef0139b1 EB |
3684 | [(set (match_operand:DI 0 "register_operand" "") |
3685 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
3686 | (match_operand:DI 2 "arith_double_add_operand" "")))] | |
a8d2b752 | 3687 | "" |
a8d2b752 | 3688 | { |
fa0f39e4 | 3689 | if (! TARGET_ARCH64) |
a8d2b752 | 3690 | { |
5b8e7fa3 DM |
3691 | emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, |
3692 | gen_rtx_SET (VOIDmode, operands[0], | |
3693 | gen_rtx_PLUS (DImode, operands[1], | |
3694 | operands[2])), | |
3695 | gen_rtx_CLOBBER (VOIDmode, | |
c6b0465b | 3696 | gen_rtx_REG (CCmode, SPARC_ICC_REG))))); |
a8d2b752 DE |
3697 | DONE; |
3698 | } | |
563facba | 3699 | }) |
a8d2b752 | 3700 | |
d761137f | 3701 | (define_insn_and_split "*adddi3_insn_sp32" |
cb40a885 | 3702 | [(set (match_operand:DI 0 "register_operand" "=&r") |
e6db6225 | 3703 | (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") |
7a768814 | 3704 | (match_operand:DI 2 "arith_double_operand" "rHI"))) |
45a7dd80 | 3705 | (clobber (reg:CC CC_REG))] |
fa0f39e4 | 3706 | "! TARGET_ARCH64" |
e0d80184 | 3707 | "#" |
b776892b | 3708 | "&& reload_completed" |
45a7dd80 | 3709 | [(parallel [(set (reg:CC_NOOV CC_REG) |
284d86e9 JC |
3710 | (compare:CC_NOOV (plus:SI (match_dup 4) |
3711 | (match_dup 5)) | |
3712 | (const_int 0))) | |
3713 | (set (match_dup 3) | |
3714 | (plus:SI (match_dup 4) (match_dup 5)))]) | |
3715 | (set (match_dup 6) | |
3716 | (plus:SI (plus:SI (match_dup 7) | |
3717 | (match_dup 8)) | |
45a7dd80 | 3718 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] |
1c44748c DM |
3719 | { |
3720 | operands[3] = gen_lowpart (SImode, operands[0]); | |
3721 | operands[4] = gen_lowpart (SImode, operands[1]); | |
3722 | operands[5] = gen_lowpart (SImode, operands[2]); | |
3723 | operands[6] = gen_highpart (SImode, operands[0]); | |
5222e470 | 3724 | operands[7] = gen_highpart_mode (SImode, DImode, operands[1]); |
93b7b953 | 3725 | #if HOST_BITS_PER_WIDE_INT == 32 |
1c44748c DM |
3726 | if (GET_CODE (operands[2]) == CONST_INT) |
3727 | { | |
3728 | if (INTVAL (operands[2]) < 0) | |
3729 | operands[8] = constm1_rtx; | |
3730 | else | |
3731 | operands[8] = const0_rtx; | |
3732 | } | |
3733 | else | |
93b7b953 | 3734 | #endif |
5222e470 | 3735 | operands[8] = gen_highpart_mode (SImode, DImode, operands[2]); |
563facba | 3736 | } |
b776892b | 3737 | [(set_attr "length" "2")]) |
284d86e9 | 3738 | |
284d86e9 | 3739 | ;; LTU here means "carry set" |
e0d80184 | 3740 | (define_insn "addx" |
284d86e9 | 3741 | [(set (match_operand:SI 0 "register_operand" "=r") |
e6db6225 | 3742 | (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r") |
284d86e9 | 3743 | (match_operand:SI 2 "arith_operand" "rI")) |
45a7dd80 | 3744 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] |
284d86e9 | 3745 | "" |
16b46035 | 3746 | "addx\t%1, %2, %0" |
c6172f14 | 3747 | [(set_attr "type" "ialuX")]) |
e0d80184 | 3748 | |
1864ee35 DM |
3749 | (define_insn "addxc" |
3750 | [(set (match_operand:DI 0 "register_operand" "=r") | |
3751 | (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ") | |
3752 | (match_operand:DI 2 "register_or_zero_operand" "rJ")) | |
3753 | (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))] | |
3754 | "TARGET_ARCH64 && TARGET_VIS3" | |
3755 | "addxc\t%r1, %r2, %0" | |
3756 | [(set_attr "type" "ialuX")]) | |
3757 | ||
b776892b | 3758 | (define_insn_and_split "*addx_extend_sp32" |
e0d80184 | 3759 | [(set (match_operand:DI 0 "register_operand" "=r") |
b776892b | 3760 | (zero_extend:DI (plus:SI (plus:SI |
0e5d569c | 3761 | (match_operand:SI 1 "register_or_zero_operand" "%rJ") |
b776892b | 3762 | (match_operand:SI 2 "arith_operand" "rI")) |
45a7dd80 | 3763 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] |
16cf8119 DM |
3764 | "! TARGET_ARCH64" |
3765 | "#" | |
b776892b | 3766 | "&& reload_completed" |
16cf8119 | 3767 | [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2)) |
45a7dd80 | 3768 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))) |
16cf8119 DM |
3769 | (set (match_dup 4) (const_int 0))] |
3770 | "operands[3] = gen_lowpart (SImode, operands[0]); | |
b776892b DM |
3771 | operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);" |
3772 | [(set_attr "length" "2")]) | |
16cf8119 DM |
3773 | |
3774 | (define_insn "*addx_extend_sp64" | |
3775 | [(set (match_operand:DI 0 "register_operand" "=r") | |
0e5d569c | 3776 | (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ") |
1864ee35 | 3777 | (match_operand:SI 2 "register_or_zero_operand" "rJ")) |
45a7dd80 | 3778 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] |
16cf8119 | 3779 | "TARGET_ARCH64" |
1864ee35 DM |
3780 | "addx\t%r1, %r2, %0" |
3781 | [(set_attr "type" "ialuX")]) | |
3782 | ||
3783 | (define_insn "*addxc_trunc_sp64_vis3" | |
3784 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3785 | (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ") | |
3786 | (match_operand:SI 2 "register_or_zero_operand" "rJ")) | |
3787 | (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))] | |
3788 | "TARGET_ARCH64 && TARGET_VIS3" | |
3789 | "addxc\t%r1, %r2, %0" | |
c6172f14 | 3790 | [(set_attr "type" "ialuX")]) |
284d86e9 | 3791 | |
d761137f | 3792 | (define_insn_and_split "*adddi3_extend_sp32" |
bfd6bc60 | 3793 | [(set (match_operand:DI 0 "register_operand" "=r") |
16cf8119 DM |
3794 | (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) |
3795 | (match_operand:DI 2 "register_operand" "r"))) | |
45a7dd80 | 3796 | (clobber (reg:CC CC_REG))] |
bfd6bc60 | 3797 | "! TARGET_ARCH64" |
e0d80184 | 3798 | "#" |
b776892b | 3799 | "&& reload_completed" |
45a7dd80 | 3800 | [(parallel [(set (reg:CC_NOOV CC_REG) |
16cf8119 DM |
3801 | (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1)) |
3802 | (const_int 0))) | |
3803 | (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))]) | |
3804 | (set (match_dup 6) | |
e0d80184 | 3805 | (plus:SI (plus:SI (match_dup 4) (const_int 0)) |
45a7dd80 | 3806 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] |
e0d80184 | 3807 | "operands[3] = gen_lowpart (SImode, operands[2]); |
16cf8119 DM |
3808 | operands[4] = gen_highpart (SImode, operands[2]); |
3809 | operands[5] = gen_lowpart (SImode, operands[0]); | |
b776892b DM |
3810 | operands[6] = gen_highpart (SImode, operands[0]);" |
3811 | [(set_attr "length" "2")]) | |
bfd6bc60 | 3812 | |
c8b3b7d6 | 3813 | (define_insn "*adddi3_sp64" |
ef0139b1 EB |
3814 | [(set (match_operand:DI 0 "register_operand" "=r,r") |
3815 | (plus:DI (match_operand:DI 1 "register_operand" "%r,r") | |
0e5d569c | 3816 | (match_operand:DI 2 "arith_add_operand" "rI,O")))] |
fa0f39e4 | 3817 | "TARGET_ARCH64" |
ef0139b1 EB |
3818 | "@ |
3819 | add\t%1, %2, %0 | |
3820 | sub\t%1, -%2, %0") | |
5d6d3339 | 3821 | |
ef0139b1 | 3822 | (define_insn "addsi3" |
e00560c2 DM |
3823 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
3824 | (plus:SI (match_operand:SI 1 "register_operand" "%r,r") | |
3825 | (match_operand:SI 2 "arith_add_operand" "rI,O")))] | |
7a768814 | 3826 | "" |
bfd6bc60 | 3827 | "@ |
16b46035 | 3828 | add\t%1, %2, %0 |
e00560c2 DM |
3829 | sub\t%1, -%2, %0" |
3830 | [(set_attr "type" "*,*") | |
3831 | (set_attr "fptype" "*,*")]) | |
7a768814 | 3832 | |
c8b3b7d6 | 3833 | (define_insn "*cmp_cc_plus" |
45a7dd80 | 3834 | [(set (reg:CC_NOOV CC_REG) |
e6db6225 | 3835 | (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r") |
7a768814 RS |
3836 | (match_operand:SI 1 "arith_operand" "rI")) |
3837 | (const_int 0)))] | |
e6c1be7e | 3838 | "" |
16b46035 | 3839 | "addcc\t%0, %1, %%g0" |
24697ca0 | 3840 | [(set_attr "type" "compare")]) |
7a768814 | 3841 | |
c8b3b7d6 | 3842 | (define_insn "*cmp_ccx_plus" |
45a7dd80 | 3843 | [(set (reg:CCX_NOOV CC_REG) |
e6db6225 | 3844 | (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r") |
0e5d569c | 3845 | (match_operand:DI 1 "arith_operand" "rI")) |
a8d2b752 | 3846 | (const_int 0)))] |
fa0f39e4 | 3847 | "TARGET_ARCH64" |
16b46035 | 3848 | "addcc\t%0, %1, %%g0" |
24697ca0 | 3849 | [(set_attr "type" "compare")]) |
a8d2b752 | 3850 | |
c8b3b7d6 | 3851 | (define_insn "*cmp_cc_plus_set" |
45a7dd80 | 3852 | [(set (reg:CC_NOOV CC_REG) |
e6db6225 | 3853 | (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r") |
7a768814 RS |
3854 | (match_operand:SI 2 "arith_operand" "rI")) |
3855 | (const_int 0))) | |
3856 | (set (match_operand:SI 0 "register_operand" "=r") | |
3857 | (plus:SI (match_dup 1) (match_dup 2)))] | |
3858 | "" | |
16b46035 | 3859 | "addcc\t%1, %2, %0" |
24697ca0 | 3860 | [(set_attr "type" "compare")]) |
7a768814 | 3861 | |
c8b3b7d6 | 3862 | (define_insn "*cmp_ccx_plus_set" |
45a7dd80 | 3863 | [(set (reg:CCX_NOOV CC_REG) |
e6db6225 | 3864 | (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r") |
0e5d569c | 3865 | (match_operand:DI 2 "arith_operand" "rI")) |
a8d2b752 DE |
3866 | (const_int 0))) |
3867 | (set (match_operand:DI 0 "register_operand" "=r") | |
3868 | (plus:DI (match_dup 1) (match_dup 2)))] | |
fa0f39e4 | 3869 | "TARGET_ARCH64" |
16b46035 | 3870 | "addcc\t%1, %2, %0" |
24697ca0 | 3871 | [(set_attr "type" "compare")]) |
a8d2b752 DE |
3872 | |
3873 | (define_expand "subdi3" | |
ef0139b1 EB |
3874 | [(set (match_operand:DI 0 "register_operand" "") |
3875 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
3876 | (match_operand:DI 2 "arith_double_add_operand" "")))] | |
a8d2b752 | 3877 | "" |
a8d2b752 | 3878 | { |
fa0f39e4 | 3879 | if (! TARGET_ARCH64) |
a8d2b752 | 3880 | { |
5b8e7fa3 DM |
3881 | emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, |
3882 | gen_rtx_SET (VOIDmode, operands[0], | |
3883 | gen_rtx_MINUS (DImode, operands[1], | |
3884 | operands[2])), | |
3885 | gen_rtx_CLOBBER (VOIDmode, | |
c6b0465b | 3886 | gen_rtx_REG (CCmode, SPARC_ICC_REG))))); |
a8d2b752 DE |
3887 | DONE; |
3888 | } | |
563facba | 3889 | }) |
a8d2b752 | 3890 | |
d761137f | 3891 | (define_insn_and_split "*subdi3_insn_sp32" |
7a768814 | 3892 | [(set (match_operand:DI 0 "register_operand" "=r") |
0e5d569c EB |
3893 | (minus:DI (match_operand:DI 1 "register_operand" "r") |
3894 | (match_operand:DI 2 "arith_double_operand" "rHI"))) | |
45a7dd80 | 3895 | (clobber (reg:CC CC_REG))] |
fa0f39e4 | 3896 | "! TARGET_ARCH64" |
e0d80184 | 3897 | "#" |
0e5d569c | 3898 | "&& reload_completed" |
45a7dd80 | 3899 | [(parallel [(set (reg:CC_NOOV CC_REG) |
0e5d569c EB |
3900 | (compare:CC_NOOV (minus:SI (match_dup 4) |
3901 | (match_dup 5)) | |
3902 | (const_int 0))) | |
3903 | (set (match_dup 3) | |
3904 | (minus:SI (match_dup 4) (match_dup 5)))]) | |
3905 | (set (match_dup 6) | |
3906 | (minus:SI (minus:SI (match_dup 7) | |
3907 | (match_dup 8)) | |
45a7dd80 | 3908 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] |
7a768814 | 3909 | { |
0e5d569c EB |
3910 | operands[3] = gen_lowpart (SImode, operands[0]); |
3911 | operands[4] = gen_lowpart (SImode, operands[1]); | |
3912 | operands[5] = gen_lowpart (SImode, operands[2]); | |
3913 | operands[6] = gen_highpart (SImode, operands[0]); | |
3914 | operands[7] = gen_highpart (SImode, operands[1]); | |
3915 | #if HOST_BITS_PER_WIDE_INT == 32 | |
3916 | if (GET_CODE (operands[2]) == CONST_INT) | |
7a768814 | 3917 | { |
0e5d569c EB |
3918 | if (INTVAL (operands[2]) < 0) |
3919 | operands[8] = constm1_rtx; | |
3920 | else | |
3921 | operands[8] = const0_rtx; | |
7a768814 | 3922 | } |
e0d80184 | 3923 | else |
0e5d569c EB |
3924 | #endif |
3925 | operands[8] = gen_highpart_mode (SImode, DImode, operands[2]); | |
563facba | 3926 | } |
b776892b | 3927 | [(set_attr "length" "2")]) |
e0d80184 | 3928 | |
0e5d569c EB |
3929 | ;; LTU here means "carry set" |
3930 | (define_insn "subx" | |
3931 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3932 | (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") | |
3933 | (match_operand:SI 2 "arith_operand" "rI")) | |
45a7dd80 | 3934 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] |
0e5d569c EB |
3935 | "" |
3936 | "subx\t%r1, %2, %0" | |
3937 | [(set_attr "type" "ialuX")]) | |
3938 | ||
3939 | (define_insn "*subx_extend_sp64" | |
3940 | [(set (match_operand:DI 0 "register_operand" "=r") | |
3941 | (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") | |
3942 | (match_operand:SI 2 "arith_operand" "rI")) | |
45a7dd80 | 3943 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] |
0e5d569c EB |
3944 | "TARGET_ARCH64" |
3945 | "subx\t%r1, %2, %0" | |
3946 | [(set_attr "type" "ialuX")]) | |
3947 | ||
3948 | (define_insn_and_split "*subx_extend" | |
3949 | [(set (match_operand:DI 0 "register_operand" "=r") | |
3950 | (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") | |
3951 | (match_operand:SI 2 "arith_operand" "rI")) | |
45a7dd80 | 3952 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] |
0e5d569c EB |
3953 | "! TARGET_ARCH64" |
3954 | "#" | |
3955 | "&& reload_completed" | |
3956 | [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2)) | |
45a7dd80 | 3957 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))) |
0e5d569c EB |
3958 | (set (match_dup 4) (const_int 0))] |
3959 | "operands[3] = gen_lowpart (SImode, operands[0]); | |
3960 | operands[4] = gen_highpart (SImode, operands[0]);" | |
3961 | [(set_attr "length" "2")]) | |
7a768814 | 3962 | |
d761137f | 3963 | (define_insn_and_split "*subdi3_extend_sp32" |
bfd6bc60 JC |
3964 | [(set (match_operand:DI 0 "register_operand" "=r") |
3965 | (minus:DI (match_operand:DI 1 "register_operand" "r") | |
3966 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))) | |
45a7dd80 | 3967 | (clobber (reg:CC CC_REG))] |
bfd6bc60 | 3968 | "! TARGET_ARCH64" |
e0d80184 | 3969 | "#" |
b776892b | 3970 | "&& reload_completed" |
45a7dd80 | 3971 | [(parallel [(set (reg:CC_NOOV CC_REG) |
16cf8119 DM |
3972 | (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2)) |
3973 | (const_int 0))) | |
3974 | (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))]) | |
3975 | (set (match_dup 6) | |
3976 | (minus:SI (minus:SI (match_dup 4) (const_int 0)) | |
45a7dd80 | 3977 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] |
e0d80184 | 3978 | "operands[3] = gen_lowpart (SImode, operands[1]); |
16cf8119 DM |
3979 | operands[4] = gen_highpart (SImode, operands[1]); |
3980 | operands[5] = gen_lowpart (SImode, operands[0]); | |
b776892b DM |
3981 | operands[6] = gen_highpart (SImode, operands[0]);" |
3982 | [(set_attr "length" "2")]) | |
bfd6bc60 | 3983 | |
c8b3b7d6 | 3984 | (define_insn "*subdi3_sp64" |
ef0139b1 EB |
3985 | [(set (match_operand:DI 0 "register_operand" "=r,r") |
3986 | (minus:DI (match_operand:DI 1 "register_operand" "r,r") | |
0e5d569c | 3987 | (match_operand:DI 2 "arith_add_operand" "rI,O")))] |
fa0f39e4 | 3988 | "TARGET_ARCH64" |
ef0139b1 EB |
3989 | "@ |
3990 | sub\t%1, %2, %0 | |
3991 | add\t%1, -%2, %0") | |
5d6d3339 | 3992 | |
ef0139b1 | 3993 | (define_insn "subsi3" |
e00560c2 DM |
3994 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
3995 | (minus:SI (match_operand:SI 1 "register_operand" "r,r") | |
3996 | (match_operand:SI 2 "arith_add_operand" "rI,O")))] | |
7a768814 | 3997 | "" |
bfd6bc60 | 3998 | "@ |
16b46035 | 3999 | sub\t%1, %2, %0 |
e00560c2 DM |
4000 | add\t%1, -%2, %0" |
4001 | [(set_attr "type" "*,*") | |
4002 | (set_attr "fptype" "*,*")]) | |
7a768814 | 4003 | |
c8b3b7d6 | 4004 | (define_insn "*cmp_minus_cc" |
45a7dd80 | 4005 | [(set (reg:CC_NOOV CC_REG) |
0e5d569c | 4006 | (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") |
7a768814 RS |
4007 | (match_operand:SI 1 "arith_operand" "rI")) |
4008 | (const_int 0)))] | |
e6c1be7e | 4009 | "" |
16b46035 | 4010 | "subcc\t%r0, %1, %%g0" |
24697ca0 | 4011 | [(set_attr "type" "compare")]) |
7a768814 | 4012 | |
c8b3b7d6 | 4013 | (define_insn "*cmp_minus_ccx" |
45a7dd80 | 4014 | [(set (reg:CCX_NOOV CC_REG) |
a8d2b752 | 4015 | (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r") |
0e5d569c | 4016 | (match_operand:DI 1 "arith_operand" "rI")) |
a8d2b752 | 4017 | (const_int 0)))] |
fa0f39e4 | 4018 | "TARGET_ARCH64" |
16b46035 | 4019 | "subcc\t%0, %1, %%g0" |
24697ca0 | 4020 | [(set_attr "type" "compare")]) |
a8d2b752 | 4021 | |
e0d80184 | 4022 | (define_insn "cmp_minus_cc_set" |
45a7dd80 | 4023 | [(set (reg:CC_NOOV CC_REG) |
0e5d569c | 4024 | (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") |
7a768814 RS |
4025 | (match_operand:SI 2 "arith_operand" "rI")) |
4026 | (const_int 0))) | |
4027 | (set (match_operand:SI 0 "register_operand" "=r") | |
4028 | (minus:SI (match_dup 1) (match_dup 2)))] | |
4029 | "" | |
16b46035 | 4030 | "subcc\t%r1, %2, %0" |
24697ca0 | 4031 | [(set_attr "type" "compare")]) |
7a768814 | 4032 | |
c8b3b7d6 | 4033 | (define_insn "*cmp_minus_ccx_set" |
45a7dd80 | 4034 | [(set (reg:CCX_NOOV CC_REG) |
a8d2b752 | 4035 | (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r") |
0e5d569c | 4036 | (match_operand:DI 2 "arith_operand" "rI")) |
a8d2b752 DE |
4037 | (const_int 0))) |
4038 | (set (match_operand:DI 0 "register_operand" "=r") | |
4039 | (minus:DI (match_dup 1) (match_dup 2)))] | |
fa0f39e4 | 4040 | "TARGET_ARCH64" |
16b46035 | 4041 | "subcc\t%1, %2, %0" |
24697ca0 | 4042 | [(set_attr "type" "compare")]) |
f8ece000 EB |
4043 | |
4044 | ||
4045 | ;; Integer multiply/divide instructions. | |
a8d2b752 | 4046 | |
a7b376ee | 4047 | ;; The 32-bit multiply/divide instructions are deprecated on v9, but at |
5cb01b65 | 4048 | ;; least in UltraSPARC I, II and IIi it is a win tick-wise. |
a8d2b752 | 4049 | |
77a02b01 JW |
4050 | (define_insn "mulsi3" |
4051 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4052 | (mult:SI (match_operand:SI 1 "arith_operand" "%r") | |
4053 | (match_operand:SI 2 "arith_operand" "rI")))] | |
bfd6bc60 | 4054 | "TARGET_HARD_MUL" |
16b46035 | 4055 | "smul\t%1, %2, %0" |
24697ca0 | 4056 | [(set_attr "type" "imul")]) |
77a02b01 | 4057 | |
284d86e9 | 4058 | (define_expand "muldi3" |
0e5d569c EB |
4059 | [(set (match_operand:DI 0 "register_operand" "") |
4060 | (mult:DI (match_operand:DI 1 "arith_operand" "") | |
4061 | (match_operand:DI 2 "arith_operand" "")))] | |
284d86e9 | 4062 | "TARGET_ARCH64 || TARGET_V8PLUS" |
284d86e9 JC |
4063 | { |
4064 | if (TARGET_V8PLUS) | |
4065 | { | |
4066 | emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2])); | |
4067 | DONE; | |
4068 | } | |
563facba | 4069 | }) |
284d86e9 JC |
4070 | |
4071 | (define_insn "*muldi3_sp64" | |
a8d2b752 | 4072 | [(set (match_operand:DI 0 "register_operand" "=r") |
0e5d569c EB |
4073 | (mult:DI (match_operand:DI 1 "arith_operand" "%r") |
4074 | (match_operand:DI 2 "arith_operand" "rI")))] | |
fa0f39e4 | 4075 | "TARGET_ARCH64" |
16b46035 | 4076 | "mulx\t%1, %2, %0" |
24697ca0 | 4077 | [(set_attr "type" "imul")]) |
a8d2b752 | 4078 | |
284d86e9 | 4079 | ;; V8plus wide multiply. |
e0d80184 | 4080 | ;; XXX |
284d86e9 JC |
4081 | (define_insn "muldi3_v8plus" |
4082 | [(set (match_operand:DI 0 "register_operand" "=r,h") | |
0e5d569c EB |
4083 | (mult:DI (match_operand:DI 1 "arith_operand" "%r,0") |
4084 | (match_operand:DI 2 "arith_operand" "rI,rI"))) | |
284d86e9 JC |
4085 | (clobber (match_scratch:SI 3 "=&h,X")) |
4086 | (clobber (match_scratch:SI 4 "=&h,X"))] | |
4087 | "TARGET_V8PLUS" | |
facb3fd7 | 4088 | "* return output_v8plus_mult (insn, operands, \"mulx\");" |
24697ca0 DM |
4089 | [(set_attr "type" "multi") |
4090 | (set_attr "length" "9,8")]) | |
284d86e9 | 4091 | |
c8b3b7d6 | 4092 | (define_insn "*cmp_mul_set" |
45a7dd80 | 4093 | [(set (reg:CC CC_REG) |
5cb01b65 JJ |
4094 | (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r") |
4095 | (match_operand:SI 2 "arith_operand" "rI")) | |
4096 | (const_int 0))) | |
4097 | (set (match_operand:SI 0 "register_operand" "=r") | |
4098 | (mult:SI (match_dup 1) (match_dup 2)))] | |
eb582c5d | 4099 | "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" |
16b46035 | 4100 | "smulcc\t%1, %2, %0" |
24697ca0 | 4101 | [(set_attr "type" "imul")]) |
77a02b01 | 4102 | |
ab5519b7 JW |
4103 | (define_expand "mulsidi3" |
4104 | [(set (match_operand:DI 0 "register_operand" "") | |
4105 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) | |
4106 | (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))] | |
bfd6bc60 | 4107 | "TARGET_HARD_MUL" |
ab5519b7 JW |
4108 | { |
4109 | if (CONSTANT_P (operands[2])) | |
4110 | { | |
2cea586a | 4111 | if (TARGET_V8PLUS) |
5cb01b65 JJ |
4112 | emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1], |
4113 | operands[2])); | |
b746b8cb | 4114 | else if (TARGET_ARCH32) |
5cb01b65 JJ |
4115 | emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1], |
4116 | operands[2])); | |
b746b8cb AK |
4117 | else |
4118 | emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1], | |
4119 | operands[2])); | |
ab5519b7 JW |
4120 | DONE; |
4121 | } | |
2cea586a JW |
4122 | if (TARGET_V8PLUS) |
4123 | { | |
4124 | emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2])); | |
4125 | DONE; | |
4126 | } | |
563facba | 4127 | }) |
ab5519b7 | 4128 | |
a7b376ee KH |
4129 | ;; V9 puts the 64-bit product in a 64-bit register. Only out or global |
4130 | ;; registers can hold 64-bit values in the V8plus environment. | |
e0d80184 | 4131 | ;; XXX |
2cea586a | 4132 | (define_insn "mulsidi3_v8plus" |
284d86e9 JC |
4133 | [(set (match_operand:DI 0 "register_operand" "=h,r") |
4134 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
4135 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))) | |
4136 | (clobber (match_scratch:SI 3 "=X,&h"))] | |
4137 | "TARGET_V8PLUS" | |
4138 | "@ | |
16b46035 DM |
4139 | smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0 |
4140 | smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0" | |
24697ca0 DM |
4141 | [(set_attr "type" "multi") |
4142 | (set_attr "length" "2,3")]) | |
284d86e9 | 4143 | |
e0d80184 | 4144 | ;; XXX |
2cea586a | 4145 | (define_insn "const_mulsidi3_v8plus" |
284d86e9 JC |
4146 | [(set (match_operand:DI 0 "register_operand" "=h,r") |
4147 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
0e5d569c | 4148 | (match_operand:DI 2 "small_int_operand" "I,I"))) |
284d86e9 JC |
4149 | (clobber (match_scratch:SI 3 "=X,&h"))] |
4150 | "TARGET_V8PLUS" | |
4151 | "@ | |
16b46035 DM |
4152 | smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0 |
4153 | smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0" | |
24697ca0 DM |
4154 | [(set_attr "type" "multi") |
4155 | (set_attr "length" "2,3")]) | |
284d86e9 | 4156 | |
e0d80184 | 4157 | ;; XXX |
c8b3b7d6 | 4158 | (define_insn "*mulsidi3_sp32" |
77a02b01 | 4159 | [(set (match_operand:DI 0 "register_operand" "=r") |
ab5519b7 JW |
4160 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) |
4161 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | |
284d86e9 | 4162 | "TARGET_HARD_MUL32" |
6d29fc41 | 4163 | { |
563facba | 4164 | return TARGET_SPARCLET |
16b46035 DM |
4165 | ? "smuld\t%1, %2, %L0" |
4166 | : "smul\t%1, %2, %L0\n\trd\t%%y, %H0"; | |
563facba | 4167 | } |
24697ca0 DM |
4168 | [(set (attr "type") |
4169 | (if_then_else (eq_attr "isa" "sparclet") | |
4170 | (const_string "imul") (const_string "multi"))) | |
4171 | (set (attr "length") | |
6d29fc41 DE |
4172 | (if_then_else (eq_attr "isa" "sparclet") |
4173 | (const_int 1) (const_int 2)))]) | |
77a02b01 | 4174 | |
5cb01b65 JJ |
4175 | (define_insn "*mulsidi3_sp64" |
4176 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4177 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
4178 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | |
4179 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
16b46035 | 4180 | "smul\t%1, %2, %0" |
24697ca0 | 4181 | [(set_attr "type" "imul")]) |
5cb01b65 | 4182 | |
3826a3da | 4183 | ;; Extra pattern, because sign_extend of a constant isn't valid. |
ab5519b7 | 4184 | |
e0d80184 | 4185 | ;; XXX |
5cb01b65 | 4186 | (define_insn "const_mulsidi3_sp32" |
77a02b01 | 4187 | [(set (match_operand:DI 0 "register_operand" "=r") |
ab5519b7 | 4188 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) |
0e5d569c | 4189 | (match_operand:DI 2 "small_int_operand" "I")))] |
5cb01b65 | 4190 | "TARGET_HARD_MUL32" |
6d29fc41 | 4191 | { |
563facba | 4192 | return TARGET_SPARCLET |
16b46035 DM |
4193 | ? "smuld\t%1, %2, %L0" |
4194 | : "smul\t%1, %2, %L0\n\trd\t%%y, %H0"; | |
563facba | 4195 | } |
24697ca0 DM |
4196 | [(set (attr "type") |
4197 | (if_then_else (eq_attr "isa" "sparclet") | |
4198 | (const_string "imul") (const_string "multi"))) | |
4199 | (set (attr "length") | |
6d29fc41 DE |
4200 | (if_then_else (eq_attr "isa" "sparclet") |
4201 | (const_int 1) (const_int 2)))]) | |
ab5519b7 | 4202 | |
5cb01b65 JJ |
4203 | (define_insn "const_mulsidi3_sp64" |
4204 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4205 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
0e5d569c | 4206 | (match_operand:DI 2 "small_int_operand" "I")))] |
5cb01b65 | 4207 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" |
16b46035 | 4208 | "smul\t%1, %2, %0" |
24697ca0 | 4209 | [(set_attr "type" "imul")]) |
5cb01b65 | 4210 | |
e783e4c2 JW |
4211 | (define_expand "smulsi3_highpart" |
4212 | [(set (match_operand:SI 0 "register_operand" "") | |
4213 | (truncate:SI | |
4214 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) | |
4215 | (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))) | |
4216 | (const_int 32))))] | |
5cb01b65 | 4217 | "TARGET_HARD_MUL && TARGET_ARCH32" |
e783e4c2 JW |
4218 | { |
4219 | if (CONSTANT_P (operands[2])) | |
4220 | { | |
2cea586a JW |
4221 | if (TARGET_V8PLUS) |
4222 | { | |
4223 | emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0], | |
4224 | operands[1], | |
4225 | operands[2], | |
4226 | GEN_INT (32))); | |
4227 | DONE; | |
4228 | } | |
e783e4c2 JW |
4229 | emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2])); |
4230 | DONE; | |
4231 | } | |
284d86e9 JC |
4232 | if (TARGET_V8PLUS) |
4233 | { | |
2cea586a JW |
4234 | emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1], |
4235 | operands[2], GEN_INT (32))); | |
284d86e9 JC |
4236 | DONE; |
4237 | } | |
563facba | 4238 | }) |
e783e4c2 | 4239 | |
e0d80184 | 4240 | ;; XXX |
2cea586a | 4241 | (define_insn "smulsi3_highpart_v8plus" |
284d86e9 JC |
4242 | [(set (match_operand:SI 0 "register_operand" "=h,r") |
4243 | (truncate:SI | |
4244 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
4245 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) | |
0e5d569c | 4246 | (match_operand:SI 3 "small_int_operand" "I,I")))) |
284d86e9 JC |
4247 | (clobber (match_scratch:SI 4 "=X,&h"))] |
4248 | "TARGET_V8PLUS" | |
4249 | "@ | |
16b46035 DM |
4250 | smul\t%1, %2, %0\;srlx\t%0, %3, %0 |
4251 | smul\t%1, %2, %4\;srlx\t%4, %3, %0" | |
24697ca0 DM |
4252 | [(set_attr "type" "multi") |
4253 | (set_attr "length" "2")]) | |
284d86e9 | 4254 | |
c6b0465b | 4255 | ;; The combiner changes TRUNCATE in the previous pattern to SUBREG. |
e0d80184 | 4256 | ;; XXX |
c6b0465b JC |
4257 | (define_insn "" |
4258 | [(set (match_operand:SI 0 "register_operand" "=h,r") | |
4259 | (subreg:SI | |
4260 | (lshiftrt:DI | |
4261 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
4262 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) | |
0e5d569c | 4263 | (match_operand:SI 3 "small_int_operand" "I,I")) |
ddef6bc7 | 4264 | 4)) |
c6b0465b JC |
4265 | (clobber (match_scratch:SI 4 "=X,&h"))] |
4266 | "TARGET_V8PLUS" | |
4267 | "@ | |
16b46035 DM |
4268 | smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0 |
4269 | smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0" | |
24697ca0 DM |
4270 | [(set_attr "type" "multi") |
4271 | (set_attr "length" "2")]) | |
c6b0465b | 4272 | |
e0d80184 | 4273 | ;; XXX |
2cea586a JW |
4274 | (define_insn "const_smulsi3_highpart_v8plus" |
4275 | [(set (match_operand:SI 0 "register_operand" "=h,r") | |
4276 | (truncate:SI | |
4277 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
0e5d569c EB |
4278 | (match_operand:DI 2 "small_int_operand" "I,I")) |
4279 | (match_operand:SI 3 "small_int_operand" "I,I")))) | |
2cea586a JW |
4280 | (clobber (match_scratch:SI 4 "=X,&h"))] |
4281 | "TARGET_V8PLUS" | |
4282 | "@ | |
16b46035 DM |
4283 | smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0 |
4284 | smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0" | |
24697ca0 DM |
4285 | [(set_attr "type" "multi") |
4286 | (set_attr "length" "2")]) | |
2cea586a | 4287 | |
e0d80184 | 4288 | ;; XXX |
2cea586a | 4289 | (define_insn "*smulsi3_highpart_sp32" |
e783e4c2 JW |
4290 | [(set (match_operand:SI 0 "register_operand" "=r") |
4291 | (truncate:SI | |
4292 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
4293 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) | |
4294 | (const_int 32))))] | |
e6c1be7e | 4295 | "TARGET_HARD_MUL32" |
16b46035 | 4296 | "smul\t%1, %2, %%g0\n\trd\t%%y, %0" |
24697ca0 DM |
4297 | [(set_attr "type" "multi") |
4298 | (set_attr "length" "2")]) | |
e783e4c2 | 4299 | |
e0d80184 | 4300 | ;; XXX |
e783e4c2 JW |
4301 | (define_insn "const_smulsi3_highpart" |
4302 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4303 | (truncate:SI | |
4304 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
0e5d569c | 4305 | (match_operand:DI 2 "small_int_operand" "i")) |
e783e4c2 | 4306 | (const_int 32))))] |
e6c1be7e | 4307 | "TARGET_HARD_MUL32" |
16b46035 | 4308 | "smul\t%1, %2, %%g0\n\trd\t%%y, %0" |
24697ca0 DM |
4309 | [(set_attr "type" "multi") |
4310 | (set_attr "length" "2")]) | |
e783e4c2 | 4311 | |
ab5519b7 JW |
4312 | (define_expand "umulsidi3" |
4313 | [(set (match_operand:DI 0 "register_operand" "") | |
4314 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) | |
13a7eb33 | 4315 | (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))] |
bfd6bc60 | 4316 | "TARGET_HARD_MUL" |
ab5519b7 JW |
4317 | { |
4318 | if (CONSTANT_P (operands[2])) | |
4319 | { | |
2cea586a | 4320 | if (TARGET_V8PLUS) |
5cb01b65 JJ |
4321 | emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1], |
4322 | operands[2])); | |
b746b8cb | 4323 | else if (TARGET_ARCH32) |
5cb01b65 JJ |
4324 | emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1], |
4325 | operands[2])); | |
b746b8cb AK |
4326 | else |
4327 | emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1], | |
4328 | operands[2])); | |
ab5519b7 JW |
4329 | DONE; |
4330 | } | |
284d86e9 JC |
4331 | if (TARGET_V8PLUS) |
4332 | { | |
4333 | emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2])); | |
4334 | DONE; | |
4335 | } | |
563facba | 4336 | }) |
ab5519b7 | 4337 | |
e0d80184 | 4338 | ;; XXX |
284d86e9 JC |
4339 | (define_insn "umulsidi3_v8plus" |
4340 | [(set (match_operand:DI 0 "register_operand" "=h,r") | |
4341 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
4342 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))) | |
4343 | (clobber (match_scratch:SI 3 "=X,&h"))] | |
4344 | "TARGET_V8PLUS" | |
4345 | "@ | |
16b46035 DM |
4346 | umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0 |
4347 | umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0" | |
24697ca0 DM |
4348 | [(set_attr "type" "multi") |
4349 | (set_attr "length" "2,3")]) | |
284d86e9 | 4350 | |
e0d80184 | 4351 | ;; XXX |
c8b3b7d6 | 4352 | (define_insn "*umulsidi3_sp32" |
ab5519b7 JW |
4353 | [(set (match_operand:DI 0 "register_operand" "=r") |
4354 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
4355 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | |
284d86e9 | 4356 | "TARGET_HARD_MUL32" |
6d29fc41 | 4357 | { |
563facba | 4358 | return TARGET_SPARCLET |
16b46035 DM |
4359 | ? "umuld\t%1, %2, %L0" |
4360 | : "umul\t%1, %2, %L0\n\trd\t%%y, %H0"; | |
563facba | 4361 | } |
24697ca0 DM |
4362 | [(set (attr "type") |
4363 | (if_then_else (eq_attr "isa" "sparclet") | |
4364 | (const_string "imul") (const_string "multi"))) | |
4365 | (set (attr "length") | |
6d29fc41 DE |
4366 | (if_then_else (eq_attr "isa" "sparclet") |
4367 | (const_int 1) (const_int 2)))]) | |
ab5519b7 | 4368 | |
5cb01b65 JJ |
4369 | (define_insn "*umulsidi3_sp64" |
4370 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4371 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
4372 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | |
4373 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
16b46035 | 4374 | "umul\t%1, %2, %0" |
24697ca0 | 4375 | [(set_attr "type" "imul")]) |
5cb01b65 | 4376 | |
3826a3da | 4377 | ;; Extra pattern, because sign_extend of a constant isn't valid. |
ab5519b7 | 4378 | |
e0d80184 | 4379 | ;; XXX |
5cb01b65 | 4380 | (define_insn "const_umulsidi3_sp32" |
ab5519b7 JW |
4381 | [(set (match_operand:DI 0 "register_operand" "=r") |
4382 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
0e5d569c | 4383 | (match_operand:DI 2 "uns_small_int_operand" "")))] |
284d86e9 | 4384 | "TARGET_HARD_MUL32" |
6d29fc41 | 4385 | { |
563facba | 4386 | return TARGET_SPARCLET |
8707fe93 RH |
4387 | ? "umuld\t%1, %s2, %L0" |
4388 | : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0"; | |
563facba | 4389 | } |
24697ca0 DM |
4390 | [(set (attr "type") |
4391 | (if_then_else (eq_attr "isa" "sparclet") | |
4392 | (const_string "imul") (const_string "multi"))) | |
4393 | (set (attr "length") | |
6d29fc41 DE |
4394 | (if_then_else (eq_attr "isa" "sparclet") |
4395 | (const_int 1) (const_int 2)))]) | |
77a02b01 | 4396 | |
5cb01b65 JJ |
4397 | (define_insn "const_umulsidi3_sp64" |
4398 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4399 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
0e5d569c | 4400 | (match_operand:DI 2 "uns_small_int_operand" "")))] |
5cb01b65 | 4401 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" |
8707fe93 | 4402 | "umul\t%1, %s2, %0" |
24697ca0 | 4403 | [(set_attr "type" "imul")]) |
5cb01b65 | 4404 | |
e0d80184 | 4405 | ;; XXX |
284d86e9 JC |
4406 | (define_insn "const_umulsidi3_v8plus" |
4407 | [(set (match_operand:DI 0 "register_operand" "=h,r") | |
4408 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
0e5d569c | 4409 | (match_operand:DI 2 "uns_small_int_operand" ""))) |
284d86e9 JC |
4410 | (clobber (match_scratch:SI 3 "=X,h"))] |
4411 | "TARGET_V8PLUS" | |
4412 | "@ | |
8707fe93 RH |
4413 | umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0 |
4414 | umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0" | |
24697ca0 DM |
4415 | [(set_attr "type" "multi") |
4416 | (set_attr "length" "2,3")]) | |
284d86e9 | 4417 | |
e783e4c2 JW |
4418 | (define_expand "umulsi3_highpart" |
4419 | [(set (match_operand:SI 0 "register_operand" "") | |
4420 | (truncate:SI | |
4421 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) | |
4422 | (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))) | |
4423 | (const_int 32))))] | |
5cb01b65 | 4424 | "TARGET_HARD_MUL && TARGET_ARCH32" |
e783e4c2 | 4425 | { |
2cea586a | 4426 | if (CONSTANT_P (operands[2])) |
284d86e9 | 4427 | { |
2cea586a JW |
4428 | if (TARGET_V8PLUS) |
4429 | { | |
4430 | emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0], | |
4431 | operands[1], | |
4432 | operands[2], | |
4433 | GEN_INT (32))); | |
4434 | DONE; | |
4435 | } | |
4436 | emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2])); | |
284d86e9 JC |
4437 | DONE; |
4438 | } | |
2cea586a | 4439 | if (TARGET_V8PLUS) |
e783e4c2 | 4440 | { |
2cea586a JW |
4441 | emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1], |
4442 | operands[2], GEN_INT (32))); | |
e783e4c2 JW |
4443 | DONE; |
4444 | } | |
563facba | 4445 | }) |
e783e4c2 | 4446 | |
e0d80184 | 4447 | ;; XXX |
2cea586a | 4448 | (define_insn "umulsi3_highpart_v8plus" |
284d86e9 JC |
4449 | [(set (match_operand:SI 0 "register_operand" "=h,r") |
4450 | (truncate:SI | |
4451 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
4452 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) | |
0e5d569c | 4453 | (match_operand:SI 3 "small_int_operand" "I,I")))) |
284d86e9 JC |
4454 | (clobber (match_scratch:SI 4 "=X,h"))] |
4455 | "TARGET_V8PLUS" | |
4456 | "@ | |
16b46035 DM |
4457 | umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0 |
4458 | umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0" | |
24697ca0 DM |
4459 | [(set_attr "type" "multi") |
4460 | (set_attr "length" "2")]) | |
284d86e9 | 4461 | |
e0d80184 | 4462 | ;; XXX |
284d86e9 JC |
4463 | (define_insn "const_umulsi3_highpart_v8plus" |
4464 | [(set (match_operand:SI 0 "register_operand" "=h,r") | |
4465 | (truncate:SI | |
4466 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
0e5d569c EB |
4467 | (match_operand:DI 2 "uns_small_int_operand" "")) |
4468 | (match_operand:SI 3 "small_int_operand" "I,I")))) | |
284d86e9 JC |
4469 | (clobber (match_scratch:SI 4 "=X,h"))] |
4470 | "TARGET_V8PLUS" | |
4471 | "@ | |
8707fe93 RH |
4472 | umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0 |
4473 | umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0" | |
24697ca0 DM |
4474 | [(set_attr "type" "multi") |
4475 | (set_attr "length" "2")]) | |
284d86e9 | 4476 | |
e0d80184 | 4477 | ;; XXX |
2cea586a | 4478 | (define_insn "*umulsi3_highpart_sp32" |
e783e4c2 JW |
4479 | [(set (match_operand:SI 0 "register_operand" "=r") |
4480 | (truncate:SI | |
4481 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
4482 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) | |
4483 | (const_int 32))))] | |
e6c1be7e | 4484 | "TARGET_HARD_MUL32" |
16b46035 | 4485 | "umul\t%1, %2, %%g0\n\trd\t%%y, %0" |
24697ca0 DM |
4486 | [(set_attr "type" "multi") |
4487 | (set_attr "length" "2")]) | |
e783e4c2 | 4488 | |
e0d80184 | 4489 | ;; XXX |
e783e4c2 JW |
4490 | (define_insn "const_umulsi3_highpart" |
4491 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4492 | (truncate:SI | |
4493 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
0e5d569c | 4494 | (match_operand:DI 2 "uns_small_int_operand" "")) |
e783e4c2 | 4495 | (const_int 32))))] |
e6c1be7e | 4496 | "TARGET_HARD_MUL32" |
8707fe93 | 4497 | "umul\t%1, %s2, %%g0\n\trd\t%%y, %0" |
24697ca0 DM |
4498 | [(set_attr "type" "multi") |
4499 | (set_attr "length" "2")]) | |
e783e4c2 | 4500 | |
5cb01b65 | 4501 | (define_expand "divsi3" |
72b415c5 EB |
4502 | [(parallel [(set (match_operand:SI 0 "register_operand" "") |
4503 | (div:SI (match_operand:SI 1 "register_operand" "") | |
4504 | (match_operand:SI 2 "input_operand" ""))) | |
4505 | (clobber (match_scratch:SI 3 ""))])] | |
5cb01b65 | 4506 | "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" |
5cb01b65 JJ |
4507 | { |
4508 | if (TARGET_ARCH64) | |
4509 | { | |
4510 | operands[3] = gen_reg_rtx(SImode); | |
4511 | emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31))); | |
4512 | emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2], | |
4513 | operands[3])); | |
4514 | DONE; | |
4515 | } | |
563facba | 4516 | }) |
5cb01b65 | 4517 | |
72b415c5 EB |
4518 | ;; The V8 architecture specifies that there must be at least 3 instructions |
4519 | ;; between a write to the Y register and a use of it for correct results. | |
4520 | ;; We try to fill one of them with a simple constant or a memory load. | |
4521 | ||
5cb01b65 | 4522 | (define_insn "divsi3_sp32" |
72b415c5 EB |
4523 | [(set (match_operand:SI 0 "register_operand" "=r,r,r") |
4524 | (div:SI (match_operand:SI 1 "register_operand" "r,r,r") | |
4525 | (match_operand:SI 2 "input_operand" "rI,K,m"))) | |
4526 | (clobber (match_scratch:SI 3 "=&r,&r,&r"))] | |
4527 | "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32" | |
eb582c5d | 4528 | { |
72b415c5 EB |
4529 | output_asm_insn ("sra\t%1, 31, %3", operands); |
4530 | output_asm_insn ("wr\t%3, 0, %%y", operands); | |
4531 | ||
4532 | switch (which_alternative) | |
4533 | { | |
4534 | case 0: | |
4535 | if (TARGET_V9) | |
4536 | return "sdiv\t%1, %2, %0"; | |
4537 | else | |
4538 | return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0"; | |
4539 | case 1: | |
4540 | if (TARGET_V9) | |
4541 | return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0"; | |
4542 | else | |
4543 | return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0"; | |
4544 | case 2: | |
4545 | if (TARGET_V9) | |
4546 | return "ld\t%2, %3\n\tsdiv\t%1, %3, %0"; | |
4547 | else | |
4548 | return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0"; | |
4549 | default: | |
4550 | gcc_unreachable (); | |
4551 | } | |
563facba | 4552 | } |
24697ca0 DM |
4553 | [(set_attr "type" "multi") |
4554 | (set (attr "length") | |
eb582c5d | 4555 | (if_then_else (eq_attr "isa" "v9") |
f17f9332 | 4556 | (const_int 4) (const_int 6)))]) |
77a02b01 | 4557 | |
5cb01b65 JJ |
4558 | (define_insn "divsi3_sp64" |
4559 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4560 | (div:SI (match_operand:SI 1 "register_operand" "r") | |
4561 | (match_operand:SI 2 "input_operand" "rI"))) | |
4562 | (use (match_operand:SI 3 "register_operand" "r"))] | |
4563 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
16b46035 | 4564 | "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0" |
24697ca0 DM |
4565 | [(set_attr "type" "multi") |
4566 | (set_attr "length" "2")]) | |
5cb01b65 | 4567 | |
a8d2b752 DE |
4568 | (define_insn "divdi3" |
4569 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4570 | (div:DI (match_operand:DI 1 "register_operand" "r") | |
0e5d569c | 4571 | (match_operand:DI 2 "arith_operand" "rI")))] |
fa0f39e4 | 4572 | "TARGET_ARCH64" |
16b46035 | 4573 | "sdivx\t%1, %2, %0" |
24697ca0 | 4574 | [(set_attr "type" "idiv")]) |
a8d2b752 | 4575 | |
c8b3b7d6 | 4576 | (define_insn "*cmp_sdiv_cc_set" |
45a7dd80 | 4577 | [(set (reg:CC CC_REG) |
5cb01b65 JJ |
4578 | (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r") |
4579 | (match_operand:SI 2 "arith_operand" "rI")) | |
77a02b01 | 4580 | (const_int 0))) |
5cb01b65 JJ |
4581 | (set (match_operand:SI 0 "register_operand" "=r") |
4582 | (div:SI (match_dup 1) (match_dup 2))) | |
77a02b01 | 4583 | (clobber (match_scratch:SI 3 "=&r"))] |
5cb01b65 | 4584 | "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" |
eb582c5d | 4585 | { |
72b415c5 EB |
4586 | output_asm_insn ("sra\t%1, 31, %3", operands); |
4587 | output_asm_insn ("wr\t%3, 0, %%y", operands); | |
4588 | ||
eb582c5d | 4589 | if (TARGET_V9) |
72b415c5 | 4590 | return "sdivcc\t%1, %2, %0"; |
eb582c5d | 4591 | else |
72b415c5 | 4592 | return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0"; |
563facba | 4593 | } |
24697ca0 DM |
4594 | [(set_attr "type" "multi") |
4595 | (set (attr "length") | |
eb582c5d DE |
4596 | (if_then_else (eq_attr "isa" "v9") |
4597 | (const_int 3) (const_int 6)))]) | |
77a02b01 | 4598 | |
e0d80184 | 4599 | ;; XXX |
5cb01b65 JJ |
4600 | (define_expand "udivsi3" |
4601 | [(set (match_operand:SI 0 "register_operand" "") | |
0e5d569c | 4602 | (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "") |
5cb01b65 | 4603 | (match_operand:SI 2 "input_operand" "")))] |
e6c1be7e | 4604 | "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" |
5cb01b65 JJ |
4605 | "") |
4606 | ||
72b415c5 EB |
4607 | ;; The V8 architecture specifies that there must be at least 3 instructions |
4608 | ;; between a write to the Y register and a use of it for correct results. | |
4609 | ;; We try to fill one of them with a simple constant or a memory load. | |
0e5d569c | 4610 | |
5cb01b65 | 4611 | (define_insn "udivsi3_sp32" |
72b415c5 EB |
4612 | [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r") |
4613 | (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m") | |
4614 | (match_operand:SI 2 "input_operand" "rI,K,m,r")))] | |
4615 | "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32" | |
eb582c5d | 4616 | { |
72b415c5 EB |
4617 | output_asm_insn ("wr\t%%g0, 0, %%y", operands); |
4618 | ||
284d86e9 JC |
4619 | switch (which_alternative) |
4620 | { | |
72b415c5 EB |
4621 | case 0: |
4622 | if (TARGET_V9) | |
4623 | return "udiv\t%1, %2, %0"; | |
4624 | else | |
4625 | return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0"; | |
284d86e9 | 4626 | case 1: |
72b415c5 EB |
4627 | if (TARGET_V9) |
4628 | return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0"; | |
4629 | else | |
4630 | return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0"; | |
284d86e9 | 4631 | case 2: |
72b415c5 EB |
4632 | if (TARGET_V9) |
4633 | return "ld\t%2, %0\n\tudiv\t%1, %0, %0"; | |
4634 | else | |
4635 | return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0"; | |
4636 | case 3: | |
4637 | if (TARGET_V9) | |
4638 | return "ld\t%1, %0\n\tudiv\t%0, %2, %0"; | |
4639 | else | |
4640 | return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0"; | |
4641 | default: | |
4642 | gcc_unreachable (); | |
284d86e9 | 4643 | } |
563facba | 4644 | } |
24697ca0 | 4645 | [(set_attr "type" "multi") |
72b415c5 EB |
4646 | (set (attr "length") |
4647 | (if_then_else (eq_attr "isa" "v9") | |
4648 | (const_int 3) (const_int 5)))]) | |
5cb01b65 JJ |
4649 | |
4650 | (define_insn "udivsi3_sp64" | |
4651 | [(set (match_operand:SI 0 "register_operand" "=r") | |
0e5d569c | 4652 | (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r") |
5cb01b65 JJ |
4653 | (match_operand:SI 2 "input_operand" "rI")))] |
4654 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
16b46035 | 4655 | "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0" |
24697ca0 DM |
4656 | [(set_attr "type" "multi") |
4657 | (set_attr "length" "2")]) | |
77a02b01 | 4658 | |
a8d2b752 DE |
4659 | (define_insn "udivdi3" |
4660 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4661 | (udiv:DI (match_operand:DI 1 "register_operand" "r") | |
0e5d569c | 4662 | (match_operand:DI 2 "arith_operand" "rI")))] |
fa0f39e4 | 4663 | "TARGET_ARCH64" |
16b46035 | 4664 | "udivx\t%1, %2, %0" |
24697ca0 | 4665 | [(set_attr "type" "idiv")]) |
a8d2b752 | 4666 | |
c8b3b7d6 | 4667 | (define_insn "*cmp_udiv_cc_set" |
45a7dd80 | 4668 | [(set (reg:CC CC_REG) |
5cb01b65 JJ |
4669 | (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r") |
4670 | (match_operand:SI 2 "arith_operand" "rI")) | |
4671 | (const_int 0))) | |
4672 | (set (match_operand:SI 0 "register_operand" "=r") | |
4673 | (udiv:SI (match_dup 1) (match_dup 2)))] | |
72b415c5 | 4674 | "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" |
eb582c5d | 4675 | { |
72b415c5 EB |
4676 | output_asm_insn ("wr\t%%g0, 0, %%y", operands); |
4677 | ||
eb582c5d | 4678 | if (TARGET_V9) |
72b415c5 | 4679 | return "udivcc\t%1, %2, %0"; |
eb582c5d | 4680 | else |
72b415c5 | 4681 | return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0"; |
563facba | 4682 | } |
24697ca0 DM |
4683 | [(set_attr "type" "multi") |
4684 | (set (attr "length") | |
eb582c5d DE |
4685 | (if_then_else (eq_attr "isa" "v9") |
4686 | (const_int 2) (const_int 5)))]) | |
967ba98d DE |
4687 | |
4688 | ; sparclet multiply/accumulate insns | |
4689 | ||
4690 | (define_insn "*smacsi" | |
637166fe | 4691 | [(set (match_operand:SI 0 "register_operand" "=r") |
967ba98d DE |
4692 | (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r") |
4693 | (match_operand:SI 2 "arith_operand" "rI")) | |
6d29fc41 | 4694 | (match_operand:SI 3 "register_operand" "0")))] |
967ba98d | 4695 | "TARGET_SPARCLET" |
16b46035 | 4696 | "smac\t%1, %2, %0" |
24697ca0 | 4697 | [(set_attr "type" "imul")]) |
967ba98d DE |
4698 | |
4699 | (define_insn "*smacdi" | |
637166fe | 4700 | [(set (match_operand:DI 0 "register_operand" "=r") |
967ba98d DE |
4701 | (plus:DI (mult:DI (sign_extend:DI |
4702 | (match_operand:SI 1 "register_operand" "%r")) | |
4703 | (sign_extend:DI | |
4704 | (match_operand:SI 2 "register_operand" "r"))) | |
6d29fc41 | 4705 | (match_operand:DI 3 "register_operand" "0")))] |
967ba98d | 4706 | "TARGET_SPARCLET" |
16b46035 | 4707 | "smacd\t%1, %2, %L0" |
24697ca0 | 4708 | [(set_attr "type" "imul")]) |
967ba98d DE |
4709 | |
4710 | (define_insn "*umacdi" | |
637166fe | 4711 | [(set (match_operand:DI 0 "register_operand" "=r") |
967ba98d DE |
4712 | (plus:DI (mult:DI (zero_extend:DI |
4713 | (match_operand:SI 1 "register_operand" "%r")) | |
4714 | (zero_extend:DI | |
4715 | (match_operand:SI 2 "register_operand" "r"))) | |
6d29fc41 | 4716 | (match_operand:DI 3 "register_operand" "0")))] |
967ba98d | 4717 | "TARGET_SPARCLET" |
16b46035 | 4718 | "umacd\t%1, %2, %L0" |
24697ca0 | 4719 | [(set_attr "type" "imul")]) |
f8ece000 EB |
4720 | |
4721 | ||
4722 | ;; Boolean instructions. | |
4723 | ||
967ba98d DE |
4724 | ;; We define DImode `and' so with DImode `not' we can get |
4725 | ;; DImode `andn'. Other combinations are possible. | |
7a768814 | 4726 | |
e00560c2 DM |
4727 | (define_expand "anddi3" |
4728 | [(set (match_operand:DI 0 "register_operand" "") | |
4729 | (and:DI (match_operand:DI 1 "arith_double_operand" "") | |
4730 | (match_operand:DI 2 "arith_double_operand" "")))] | |
7a768814 RS |
4731 | "" |
4732 | "") | |
4733 | ||
e00560c2 DM |
4734 | (define_insn "*anddi3_sp32" |
4735 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4736 | (and:DI (match_operand:DI 1 "arith_double_operand" "%r") | |
4737 | (match_operand:DI 2 "arith_double_operand" "rHI")))] | |
fa0f39e4 | 4738 | "! TARGET_ARCH64" |
e00560c2 DM |
4739 | "#") |
4740 | ||
4741 | (define_insn "*anddi3_sp64" | |
4742 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4743 | (and:DI (match_operand:DI 1 "arith_operand" "%r") | |
4744 | (match_operand:DI 2 "arith_operand" "rI")))] | |
fa0f39e4 | 4745 | "TARGET_ARCH64" |
e00560c2 | 4746 | "and\t%1, %2, %0") |
a8d2b752 | 4747 | |
e00560c2 DM |
4748 | (define_insn "andsi3" |
4749 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4750 | (and:SI (match_operand:SI 1 "arith_operand" "%r") | |
4751 | (match_operand:SI 2 "arith_operand" "rI")))] | |
7a768814 | 4752 | "" |
e00560c2 | 4753 | "and\t%1, %2, %0") |
7a768814 | 4754 | |
95edfef2 JW |
4755 | (define_split |
4756 | [(set (match_operand:SI 0 "register_operand" "") | |
4757 | (and:SI (match_operand:SI 1 "register_operand" "") | |
9bb3323d | 4758 | (match_operand:SI 2 "const_compl_high_operand" ""))) |
5584677e | 4759 | (clobber (match_operand:SI 3 "register_operand" ""))] |
9bb3323d | 4760 | "" |
5584677e JW |
4761 | [(set (match_dup 3) (match_dup 4)) |
4762 | (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))] | |
95edfef2 | 4763 | { |
9e0625a3 | 4764 | operands[4] = GEN_INT (~INTVAL (operands[2])); |
563facba | 4765 | }) |
95edfef2 | 4766 | |
e00560c2 DM |
4767 | (define_insn_and_split "*and_not_di_sp32" |
4768 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4769 | (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r")) | |
4770 | (match_operand:DI 2 "register_operand" "r")))] | |
fa0f39e4 | 4771 | "! TARGET_ARCH64" |
e00560c2 | 4772 | "#" |
b776892b | 4773 | "&& reload_completed |
e61c29e9 | 4774 | && ((GET_CODE (operands[0]) == REG |
5a53588f | 4775 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
e61c29e9 DM |
4776 | || (GET_CODE (operands[0]) == SUBREG |
4777 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
5a53588f | 4778 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" |
e0d80184 DM |
4779 | [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5))) |
4780 | (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))] | |
0e1638d4 | 4781 | "operands[3] = gen_highpart (SImode, operands[0]); |
e0d80184 DM |
4782 | operands[4] = gen_highpart (SImode, operands[1]); |
4783 | operands[5] = gen_highpart (SImode, operands[2]); | |
4784 | operands[6] = gen_lowpart (SImode, operands[0]); | |
4785 | operands[7] = gen_lowpart (SImode, operands[1]); | |
b776892b | 4786 | operands[8] = gen_lowpart (SImode, operands[2]);" |
e00560c2 DM |
4787 | [(set_attr "length" "2")]) |
4788 | ||
4789 | (define_insn "*and_not_di_sp64" | |
4790 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4791 | (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r")) | |
4792 | (match_operand:DI 2 "register_operand" "r")))] | |
fa0f39e4 | 4793 | "TARGET_ARCH64" |
e00560c2 | 4794 | "andn\t%2, %1, %0") |
a8d2b752 | 4795 | |
e00560c2 DM |
4796 | (define_insn "*and_not_si" |
4797 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4798 | (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r")) | |
4799 | (match_operand:SI 2 "register_operand" "r")))] | |
7a768814 | 4800 | "" |
e00560c2 | 4801 | "andn\t%2, %1, %0") |
7a768814 | 4802 | |
e00560c2 DM |
4803 | (define_expand "iordi3" |
4804 | [(set (match_operand:DI 0 "register_operand" "") | |
4805 | (ior:DI (match_operand:DI 1 "arith_double_operand" "") | |
4806 | (match_operand:DI 2 "arith_double_operand" "")))] | |
7a768814 RS |
4807 | "" |
4808 | "") | |
4809 | ||
e00560c2 DM |
4810 | (define_insn "*iordi3_sp32" |
4811 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4812 | (ior:DI (match_operand:DI 1 "arith_double_operand" "%r") | |
4813 | (match_operand:DI 2 "arith_double_operand" "rHI")))] | |
fa0f39e4 | 4814 | "! TARGET_ARCH64" |
e00560c2 DM |
4815 | "#" |
4816 | [(set_attr "length" "2")]) | |
4817 | ||
4818 | (define_insn "*iordi3_sp64" | |
4819 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4820 | (ior:DI (match_operand:DI 1 "arith_operand" "%r") | |
4821 | (match_operand:DI 2 "arith_operand" "rI")))] | |
fa0f39e4 | 4822 | "TARGET_ARCH64" |
e00560c2 | 4823 | "or\t%1, %2, %0") |
a8d2b752 | 4824 | |
e00560c2 DM |
4825 | (define_insn "iorsi3" |
4826 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4827 | (ior:SI (match_operand:SI 1 "arith_operand" "%r") | |
4828 | (match_operand:SI 2 "arith_operand" "rI")))] | |
7a768814 | 4829 | "" |
e00560c2 | 4830 | "or\t%1, %2, %0") |
7a768814 | 4831 | |
95edfef2 JW |
4832 | (define_split |
4833 | [(set (match_operand:SI 0 "register_operand" "") | |
4834 | (ior:SI (match_operand:SI 1 "register_operand" "") | |
9bb3323d | 4835 | (match_operand:SI 2 "const_compl_high_operand" ""))) |
5584677e | 4836 | (clobber (match_operand:SI 3 "register_operand" ""))] |
9bb3323d | 4837 | "" |
5584677e JW |
4838 | [(set (match_dup 3) (match_dup 4)) |
4839 | (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))] | |
95edfef2 | 4840 | { |
9e0625a3 | 4841 | operands[4] = GEN_INT (~INTVAL (operands[2])); |
563facba | 4842 | }) |
95edfef2 | 4843 | |
e00560c2 DM |
4844 | (define_insn_and_split "*or_not_di_sp32" |
4845 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4846 | (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) | |
4847 | (match_operand:DI 2 "register_operand" "r")))] | |
fa0f39e4 | 4848 | "! TARGET_ARCH64" |
e00560c2 | 4849 | "#" |
b776892b | 4850 | "&& reload_completed |
e61c29e9 | 4851 | && ((GET_CODE (operands[0]) == REG |
5a53588f | 4852 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
e61c29e9 DM |
4853 | || (GET_CODE (operands[0]) == SUBREG |
4854 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
5a53588f | 4855 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" |
e0d80184 DM |
4856 | [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5))) |
4857 | (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))] | |
0e1638d4 | 4858 | "operands[3] = gen_highpart (SImode, operands[0]); |
e0d80184 DM |
4859 | operands[4] = gen_highpart (SImode, operands[1]); |
4860 | operands[5] = gen_highpart (SImode, operands[2]); | |
4861 | operands[6] = gen_lowpart (SImode, operands[0]); | |
4862 | operands[7] = gen_lowpart (SImode, operands[1]); | |
b776892b | 4863 | operands[8] = gen_lowpart (SImode, operands[2]);" |
e00560c2 DM |
4864 | [(set_attr "length" "2")]) |
4865 | ||
4866 | (define_insn "*or_not_di_sp64" | |
4867 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4868 | (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) | |
4869 | (match_operand:DI 2 "register_operand" "r")))] | |
fa0f39e4 | 4870 | "TARGET_ARCH64" |
e00560c2 | 4871 | "orn\t%2, %1, %0") |
a8d2b752 | 4872 | |
e00560c2 DM |
4873 | (define_insn "*or_not_si" |
4874 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4875 | (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r")) | |
4876 | (match_operand:SI 2 "register_operand" "r")))] | |
7a768814 | 4877 | "" |
e00560c2 | 4878 | "orn\t%2, %1, %0") |
7a768814 | 4879 | |
e00560c2 DM |
4880 | (define_expand "xordi3" |
4881 | [(set (match_operand:DI 0 "register_operand" "") | |
4882 | (xor:DI (match_operand:DI 1 "arith_double_operand" "") | |
4883 | (match_operand:DI 2 "arith_double_operand" "")))] | |
7a768814 RS |
4884 | "" |
4885 | "") | |
4886 | ||
e00560c2 DM |
4887 | (define_insn "*xordi3_sp32" |
4888 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4889 | (xor:DI (match_operand:DI 1 "arith_double_operand" "%r") | |
4890 | (match_operand:DI 2 "arith_double_operand" "rHI")))] | |
fa0f39e4 | 4891 | "! TARGET_ARCH64" |
e00560c2 DM |
4892 | "#" |
4893 | [(set_attr "length" "2")]) | |
4894 | ||
4895 | (define_insn "*xordi3_sp64" | |
4896 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4897 | (xor:DI (match_operand:DI 1 "arith_operand" "%rJ") | |
4898 | (match_operand:DI 2 "arith_operand" "rI")))] | |
fa0f39e4 | 4899 | "TARGET_ARCH64" |
e00560c2 | 4900 | "xor\t%r1, %2, %0") |
e0d80184 | 4901 | |
e00560c2 DM |
4902 | (define_insn "xorsi3" |
4903 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4904 | (xor:SI (match_operand:SI 1 "arith_operand" "%rJ") | |
4905 | (match_operand:SI 2 "arith_operand" "rI")))] | |
7a768814 | 4906 | "" |
e00560c2 | 4907 | "xor\t%r1, %2, %0") |
7a768814 | 4908 | |
95edfef2 JW |
4909 | (define_split |
4910 | [(set (match_operand:SI 0 "register_operand" "") | |
4911 | (xor:SI (match_operand:SI 1 "register_operand" "") | |
9bb3323d | 4912 | (match_operand:SI 2 "const_compl_high_operand" ""))) |
5584677e | 4913 | (clobber (match_operand:SI 3 "register_operand" ""))] |
9bb3323d | 4914 | "" |
5584677e JW |
4915 | [(set (match_dup 3) (match_dup 4)) |
4916 | (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))] | |
95edfef2 | 4917 | { |
9e0625a3 | 4918 | operands[4] = GEN_INT (~INTVAL (operands[2])); |
563facba | 4919 | }) |
95edfef2 JW |
4920 | |
4921 | (define_split | |
4922 | [(set (match_operand:SI 0 "register_operand" "") | |
4923 | (not:SI (xor:SI (match_operand:SI 1 "register_operand" "") | |
9bb3323d | 4924 | (match_operand:SI 2 "const_compl_high_operand" "")))) |
5584677e | 4925 | (clobber (match_operand:SI 3 "register_operand" ""))] |
9bb3323d | 4926 | "" |
5584677e JW |
4927 | [(set (match_dup 3) (match_dup 4)) |
4928 | (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))] | |
95edfef2 | 4929 | { |
9e0625a3 | 4930 | operands[4] = GEN_INT (~INTVAL (operands[2])); |
563facba | 4931 | }) |
95edfef2 | 4932 | |
893e18a5 JM |
4933 | ;; Split DImode logical operations requiring two instructions. |
4934 | (define_split | |
e00560c2 DM |
4935 | [(set (match_operand:DI 0 "register_operand" "") |
4936 | (match_operator:DI 1 "cc_arith_operator" ; AND, IOR, XOR | |
4937 | [(match_operand:DI 2 "register_operand" "") | |
4938 | (match_operand:DI 3 "arith_double_operand" "")]))] | |
893e18a5 JM |
4939 | "! TARGET_ARCH64 |
4940 | && reload_completed | |
4941 | && ((GET_CODE (operands[0]) == REG | |
5a53588f | 4942 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
893e18a5 JM |
4943 | || (GET_CODE (operands[0]) == SUBREG |
4944 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
5a53588f | 4945 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" |
893e18a5 JM |
4946 | [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)])) |
4947 | (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))] | |
4948 | { | |
4949 | operands[4] = gen_highpart (SImode, operands[0]); | |
4950 | operands[5] = gen_lowpart (SImode, operands[0]); | |
4951 | operands[6] = gen_highpart (SImode, operands[2]); | |
4952 | operands[7] = gen_lowpart (SImode, operands[2]); | |
4953 | #if HOST_BITS_PER_WIDE_INT == 32 | |
e00560c2 | 4954 | if (GET_CODE (operands[3]) == CONST_INT) |
893e18a5 JM |
4955 | { |
4956 | if (INTVAL (operands[3]) < 0) | |
4957 | operands[8] = constm1_rtx; | |
4958 | else | |
4959 | operands[8] = const0_rtx; | |
4960 | } | |
4961 | else | |
4962 | #endif | |
e00560c2 | 4963 | operands[8] = gen_highpart_mode (SImode, DImode, operands[3]); |
893e18a5 JM |
4964 | operands[9] = gen_lowpart (SImode, operands[3]); |
4965 | }) | |
4966 | ||
7a768814 RS |
4967 | ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b). |
4968 | ;; Combine now canonicalizes to the rightmost expression. | |
e00560c2 DM |
4969 | (define_insn_and_split "*xor_not_di_sp32" |
4970 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4971 | (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r") | |
4972 | (match_operand:DI 2 "register_operand" "r"))))] | |
fa0f39e4 | 4973 | "! TARGET_ARCH64" |
e00560c2 | 4974 | "#" |
b776892b | 4975 | "&& reload_completed |
e61c29e9 | 4976 | && ((GET_CODE (operands[0]) == REG |
5a53588f | 4977 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
e61c29e9 DM |
4978 | || (GET_CODE (operands[0]) == SUBREG |
4979 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
5a53588f | 4980 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" |
e0d80184 DM |
4981 | [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5)))) |
4982 | (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))] | |
0e1638d4 | 4983 | "operands[3] = gen_highpart (SImode, operands[0]); |
e0d80184 DM |
4984 | operands[4] = gen_highpart (SImode, operands[1]); |
4985 | operands[5] = gen_highpart (SImode, operands[2]); | |
4986 | operands[6] = gen_lowpart (SImode, operands[0]); | |
4987 | operands[7] = gen_lowpart (SImode, operands[1]); | |
b776892b | 4988 | operands[8] = gen_lowpart (SImode, operands[2]);" |
e00560c2 DM |
4989 | [(set_attr "length" "2")]) |
4990 | ||
4991 | (define_insn "*xor_not_di_sp64" | |
4992 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4993 | (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") | |
4994 | (match_operand:DI 2 "arith_operand" "rI"))))] | |
fa0f39e4 | 4995 | "TARGET_ARCH64" |
e00560c2 | 4996 | "xnor\t%r1, %2, %0") |
a8d2b752 | 4997 | |
e00560c2 DM |
4998 | (define_insn "*xor_not_si" |
4999 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5000 | (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") | |
5001 | (match_operand:SI 2 "arith_operand" "rI"))))] | |
7a768814 | 5002 | "" |
e00560c2 | 5003 | "xnor\t%r1, %2, %0") |
7a768814 RS |
5004 | |
5005 | ;; These correspond to the above in the case where we also (or only) | |
5006 | ;; want to set the condition code. | |
5007 | ||
c8b3b7d6 | 5008 | (define_insn "*cmp_cc_arith_op" |
45a7dd80 | 5009 | [(set (reg:CC CC_REG) |
7a768814 | 5010 | (compare:CC |
0e5d569c | 5011 | (match_operator:SI 2 "cc_arith_operator" |
7a768814 RS |
5012 | [(match_operand:SI 0 "arith_operand" "%r") |
5013 | (match_operand:SI 1 "arith_operand" "rI")]) | |
5014 | (const_int 0)))] | |
e6c1be7e | 5015 | "" |
16b46035 | 5016 | "%A2cc\t%0, %1, %%g0" |
24697ca0 | 5017 | [(set_attr "type" "compare")]) |
7a768814 | 5018 | |
c8b3b7d6 | 5019 | (define_insn "*cmp_ccx_arith_op" |
45a7dd80 | 5020 | [(set (reg:CCX CC_REG) |
a8d2b752 | 5021 | (compare:CCX |
0e5d569c EB |
5022 | (match_operator:DI 2 "cc_arith_operator" |
5023 | [(match_operand:DI 0 "arith_operand" "%r") | |
5024 | (match_operand:DI 1 "arith_operand" "rI")]) | |
a8d2b752 | 5025 | (const_int 0)))] |
fa0f39e4 | 5026 | "TARGET_ARCH64" |
16b46035 | 5027 | "%A2cc\t%0, %1, %%g0" |
24697ca0 | 5028 | [(set_attr "type" "compare")]) |
a8d2b752 | 5029 | |
c8b3b7d6 | 5030 | (define_insn "*cmp_cc_arith_op_set" |
45a7dd80 | 5031 | [(set (reg:CC CC_REG) |
7a768814 | 5032 | (compare:CC |
0e5d569c | 5033 | (match_operator:SI 3 "cc_arith_operator" |
7a768814 RS |
5034 | [(match_operand:SI 1 "arith_operand" "%r") |
5035 | (match_operand:SI 2 "arith_operand" "rI")]) | |
5036 | (const_int 0))) | |
5037 | (set (match_operand:SI 0 "register_operand" "=r") | |
0e5d569c | 5038 | (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))] |
1b9ea8eb | 5039 | "GET_CODE (operands[3]) == GET_CODE (operands[4])" |
16b46035 | 5040 | "%A3cc\t%1, %2, %0" |
24697ca0 | 5041 | [(set_attr "type" "compare")]) |
a8d2b752 | 5042 | |
c8b3b7d6 | 5043 | (define_insn "*cmp_ccx_arith_op_set" |
45a7dd80 | 5044 | [(set (reg:CCX CC_REG) |
a8d2b752 | 5045 | (compare:CCX |
0e5d569c EB |
5046 | (match_operator:DI 3 "cc_arith_operator" |
5047 | [(match_operand:DI 1 "arith_operand" "%r") | |
5048 | (match_operand:DI 2 "arith_operand" "rI")]) | |
a8d2b752 DE |
5049 | (const_int 0))) |
5050 | (set (match_operand:DI 0 "register_operand" "=r") | |
0e5d569c | 5051 | (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))] |
1b9ea8eb | 5052 | "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])" |
16b46035 | 5053 | "%A3cc\t%1, %2, %0" |
24697ca0 | 5054 | [(set_attr "type" "compare")]) |
7a768814 | 5055 | |
c8b3b7d6 | 5056 | (define_insn "*cmp_cc_xor_not" |
45a7dd80 | 5057 | [(set (reg:CC CC_REG) |
7a768814 | 5058 | (compare:CC |
0e5d569c | 5059 | (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ") |
7a768814 RS |
5060 | (match_operand:SI 1 "arith_operand" "rI"))) |
5061 | (const_int 0)))] | |
e6c1be7e | 5062 | "" |
16b46035 | 5063 | "xnorcc\t%r0, %1, %%g0" |
24697ca0 | 5064 | [(set_attr "type" "compare")]) |
7a768814 | 5065 | |
c8b3b7d6 | 5066 | (define_insn "*cmp_ccx_xor_not" |
45a7dd80 | 5067 | [(set (reg:CCX CC_REG) |
a8d2b752 | 5068 | (compare:CCX |
0e5d569c EB |
5069 | (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ") |
5070 | (match_operand:DI 1 "arith_operand" "rI"))) | |
a8d2b752 | 5071 | (const_int 0)))] |
fa0f39e4 | 5072 | "TARGET_ARCH64" |
16b46035 | 5073 | "xnorcc\t%r0, %1, %%g0" |
24697ca0 | 5074 | [(set_attr "type" "compare")]) |
a8d2b752 | 5075 | |
c8b3b7d6 | 5076 | (define_insn "*cmp_cc_xor_not_set" |
45a7dd80 | 5077 | [(set (reg:CC CC_REG) |
7a768814 | 5078 | (compare:CC |
0e5d569c | 5079 | (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ") |
7a768814 RS |
5080 | (match_operand:SI 2 "arith_operand" "rI"))) |
5081 | (const_int 0))) | |
5082 | (set (match_operand:SI 0 "register_operand" "=r") | |
5083 | (not:SI (xor:SI (match_dup 1) (match_dup 2))))] | |
5084 | "" | |
16b46035 | 5085 | "xnorcc\t%r1, %2, %0" |
24697ca0 | 5086 | [(set_attr "type" "compare")]) |
7a768814 | 5087 | |
c8b3b7d6 | 5088 | (define_insn "*cmp_ccx_xor_not_set" |
45a7dd80 | 5089 | [(set (reg:CCX CC_REG) |
a8d2b752 | 5090 | (compare:CCX |
0e5d569c EB |
5091 | (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ") |
5092 | (match_operand:DI 2 "arith_operand" "rI"))) | |
a8d2b752 DE |
5093 | (const_int 0))) |
5094 | (set (match_operand:DI 0 "register_operand" "=r") | |
5095 | (not:DI (xor:DI (match_dup 1) (match_dup 2))))] | |
fa0f39e4 | 5096 | "TARGET_ARCH64" |
16b46035 | 5097 | "xnorcc\t%r1, %2, %0" |
24697ca0 | 5098 | [(set_attr "type" "compare")]) |
a8d2b752 | 5099 | |
c8b3b7d6 | 5100 | (define_insn "*cmp_cc_arith_op_not" |
45a7dd80 | 5101 | [(set (reg:CC CC_REG) |
7a768814 | 5102 | (compare:CC |
0e5d569c | 5103 | (match_operator:SI 2 "cc_arith_not_operator" |
7a768814 | 5104 | [(not:SI (match_operand:SI 0 "arith_operand" "rI")) |
0e5d569c | 5105 | (match_operand:SI 1 "register_or_zero_operand" "rJ")]) |
7a768814 | 5106 | (const_int 0)))] |
e6c1be7e | 5107 | "" |
16b46035 | 5108 | "%B2cc\t%r1, %0, %%g0" |
24697ca0 | 5109 | [(set_attr "type" "compare")]) |
7a768814 | 5110 | |
c8b3b7d6 | 5111 | (define_insn "*cmp_ccx_arith_op_not" |
45a7dd80 | 5112 | [(set (reg:CCX CC_REG) |
a8d2b752 | 5113 | (compare:CCX |
0e5d569c EB |
5114 | (match_operator:DI 2 "cc_arith_not_operator" |
5115 | [(not:DI (match_operand:DI 0 "arith_operand" "rI")) | |
5116 | (match_operand:DI 1 "register_or_zero_operand" "rJ")]) | |
a8d2b752 | 5117 | (const_int 0)))] |
fa0f39e4 | 5118 | "TARGET_ARCH64" |
16b46035 | 5119 | "%B2cc\t%r1, %0, %%g0" |
24697ca0 | 5120 | [(set_attr "type" "compare")]) |
a8d2b752 | 5121 | |
c8b3b7d6 | 5122 | (define_insn "*cmp_cc_arith_op_not_set" |
45a7dd80 | 5123 | [(set (reg:CC CC_REG) |
7a768814 | 5124 | (compare:CC |
0e5d569c | 5125 | (match_operator:SI 3 "cc_arith_not_operator" |
7a768814 | 5126 | [(not:SI (match_operand:SI 1 "arith_operand" "rI")) |
0e5d569c | 5127 | (match_operand:SI 2 "register_or_zero_operand" "rJ")]) |
7a768814 RS |
5128 | (const_int 0))) |
5129 | (set (match_operand:SI 0 "register_operand" "=r") | |
0e5d569c | 5130 | (match_operator:SI 4 "cc_arith_not_operator" |
1b9ea8eb RH |
5131 | [(not:SI (match_dup 1)) (match_dup 2)]))] |
5132 | "GET_CODE (operands[3]) == GET_CODE (operands[4])" | |
16b46035 | 5133 | "%B3cc\t%r2, %1, %0" |
24697ca0 | 5134 | [(set_attr "type" "compare")]) |
7a768814 | 5135 | |
c8b3b7d6 | 5136 | (define_insn "*cmp_ccx_arith_op_not_set" |
45a7dd80 | 5137 | [(set (reg:CCX CC_REG) |
a8d2b752 | 5138 | (compare:CCX |
0e5d569c EB |
5139 | (match_operator:DI 3 "cc_arith_not_operator" |
5140 | [(not:DI (match_operand:DI 1 "arith_operand" "rI")) | |
5141 | (match_operand:DI 2 "register_or_zero_operand" "rJ")]) | |
a8d2b752 DE |
5142 | (const_int 0))) |
5143 | (set (match_operand:DI 0 "register_operand" "=r") | |
0e5d569c | 5144 | (match_operator:DI 4 "cc_arith_not_operator" |
1b9ea8eb RH |
5145 | [(not:DI (match_dup 1)) (match_dup 2)]))] |
5146 | "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])" | |
16b46035 | 5147 | "%B3cc\t%r2, %1, %0" |
24697ca0 | 5148 | [(set_attr "type" "compare")]) |
a8d2b752 | 5149 | |
7a768814 RS |
5150 | ;; We cannot use the "neg" pseudo insn because the Sun assembler |
5151 | ;; does not know how to make it work for constants. | |
5152 | ||
a8d2b752 DE |
5153 | (define_expand "negdi2" |
5154 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5155 | (neg:DI (match_operand:DI 1 "register_operand" "r")))] | |
5156 | "" | |
a8d2b752 | 5157 | { |
fa0f39e4 | 5158 | if (! TARGET_ARCH64) |
a8d2b752 | 5159 | { |
c5c76735 JL |
5160 | emit_insn (gen_rtx_PARALLEL |
5161 | (VOIDmode, | |
5162 | gen_rtvec (2, | |
5163 | gen_rtx_SET (VOIDmode, operand0, | |
5164 | gen_rtx_NEG (DImode, operand1)), | |
5165 | gen_rtx_CLOBBER (VOIDmode, | |
5166 | gen_rtx_REG (CCmode, | |
5167 | SPARC_ICC_REG))))); | |
a8d2b752 DE |
5168 | DONE; |
5169 | } | |
563facba | 5170 | }) |
a8d2b752 | 5171 | |
b776892b | 5172 | (define_insn_and_split "*negdi2_sp32" |
7a768814 RS |
5173 | [(set (match_operand:DI 0 "register_operand" "=r") |
5174 | (neg:DI (match_operand:DI 1 "register_operand" "r"))) | |
45a7dd80 | 5175 | (clobber (reg:CC CC_REG))] |
d761137f | 5176 | "! TARGET_ARCH64" |
e0d80184 | 5177 | "#" |
b776892b | 5178 | "&& reload_completed" |
45a7dd80 | 5179 | [(parallel [(set (reg:CC_NOOV CC_REG) |
e0d80184 DM |
5180 | (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5)) |
5181 | (const_int 0))) | |
5182 | (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))]) | |
5183 | (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3)) | |
45a7dd80 | 5184 | (ltu:SI (reg:CC CC_REG) (const_int 0))))] |
e0d80184 DM |
5185 | "operands[2] = gen_highpart (SImode, operands[0]); |
5186 | operands[3] = gen_highpart (SImode, operands[1]); | |
5187 | operands[4] = gen_lowpart (SImode, operands[0]); | |
b776892b DM |
5188 | operands[5] = gen_lowpart (SImode, operands[1]);" |
5189 | [(set_attr "length" "2")]) | |
e0d80184 | 5190 | |
c8b3b7d6 | 5191 | (define_insn "*negdi2_sp64" |
a8d2b752 DE |
5192 | [(set (match_operand:DI 0 "register_operand" "=r") |
5193 | (neg:DI (match_operand:DI 1 "register_operand" "r")))] | |
fa0f39e4 | 5194 | "TARGET_ARCH64" |
16b46035 | 5195 | "sub\t%%g0, %1, %0") |
a8d2b752 | 5196 | |
e6c1be7e | 5197 | (define_insn "negsi2" |
e0d80184 | 5198 | [(set (match_operand:SI 0 "register_operand" "=r") |
e6c1be7e JJ |
5199 | (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] |
5200 | "" | |
16b46035 | 5201 | "sub\t%%g0, %1, %0") |
7a768814 | 5202 | |
c8b3b7d6 | 5203 | (define_insn "*cmp_cc_neg" |
45a7dd80 | 5204 | [(set (reg:CC_NOOV CC_REG) |
7a768814 RS |
5205 | (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI")) |
5206 | (const_int 0)))] | |
e6c1be7e | 5207 | "" |
16b46035 | 5208 | "subcc\t%%g0, %0, %%g0" |
24697ca0 | 5209 | [(set_attr "type" "compare")]) |
7a768814 | 5210 | |
c8b3b7d6 | 5211 | (define_insn "*cmp_ccx_neg" |
45a7dd80 | 5212 | [(set (reg:CCX_NOOV CC_REG) |
0e5d569c | 5213 | (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI")) |
a8d2b752 | 5214 | (const_int 0)))] |
fa0f39e4 | 5215 | "TARGET_ARCH64" |
16b46035 | 5216 | "subcc\t%%g0, %0, %%g0" |
24697ca0 | 5217 | [(set_attr "type" "compare")]) |
a8d2b752 | 5218 | |
c8b3b7d6 | 5219 | (define_insn "*cmp_cc_set_neg" |
45a7dd80 | 5220 | [(set (reg:CC_NOOV CC_REG) |
7a768814 RS |
5221 | (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI")) |
5222 | (const_int 0))) | |
5223 | (set (match_operand:SI 0 "register_operand" "=r") | |
5224 | (neg:SI (match_dup 1)))] | |
e6c1be7e | 5225 | "" |
16b46035 | 5226 | "subcc\t%%g0, %1, %0" |
24697ca0 | 5227 | [(set_attr "type" "compare")]) |
7a768814 | 5228 | |
c8b3b7d6 | 5229 | (define_insn "*cmp_ccx_set_neg" |
45a7dd80 | 5230 | [(set (reg:CCX_NOOV CC_REG) |
0e5d569c | 5231 | (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI")) |
a8d2b752 DE |
5232 | (const_int 0))) |
5233 | (set (match_operand:DI 0 "register_operand" "=r") | |
5234 | (neg:DI (match_dup 1)))] | |
fa0f39e4 | 5235 | "TARGET_ARCH64" |
16b46035 | 5236 | "subcc\t%%g0, %1, %0" |
24697ca0 | 5237 | [(set_attr "type" "compare")]) |
a8d2b752 | 5238 | |
7a768814 RS |
5239 | ;; We cannot use the "not" pseudo insn because the Sun assembler |
5240 | ;; does not know how to make it work for constants. | |
e00560c2 DM |
5241 | (define_expand "one_cmpldi2" |
5242 | [(set (match_operand:DI 0 "register_operand" "") | |
5243 | (not:DI (match_operand:DI 1 "register_operand" "")))] | |
7a768814 RS |
5244 | "" |
5245 | "") | |
5246 | ||
e00560c2 DM |
5247 | (define_insn_and_split "*one_cmpldi2_sp32" |
5248 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5249 | (not:DI (match_operand:DI 1 "register_operand" "r")))] | |
fa0f39e4 | 5250 | "! TARGET_ARCH64" |
e00560c2 | 5251 | "#" |
b776892b | 5252 | "&& reload_completed |
e61c29e9 | 5253 | && ((GET_CODE (operands[0]) == REG |
5a53588f | 5254 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
e61c29e9 DM |
5255 | || (GET_CODE (operands[0]) == SUBREG |
5256 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
5a53588f | 5257 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" |
e0d80184 DM |
5258 | [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0)))) |
5259 | (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))] | |
0e1638d4 | 5260 | "operands[2] = gen_highpart (SImode, operands[0]); |
e0d80184 DM |
5261 | operands[3] = gen_highpart (SImode, operands[1]); |
5262 | operands[4] = gen_lowpart (SImode, operands[0]); | |
b776892b | 5263 | operands[5] = gen_lowpart (SImode, operands[1]);" |
e00560c2 | 5264 | [(set_attr "length" "2")]) |
e0d80184 | 5265 | |
e00560c2 DM |
5266 | (define_insn "*one_cmpldi2_sp64" |
5267 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5268 | (not:DI (match_operand:DI 1 "arith_operand" "rI")))] | |
fa0f39e4 | 5269 | "TARGET_ARCH64" |
e00560c2 | 5270 | "xnor\t%%g0, %1, %0") |
a8d2b752 | 5271 | |
e00560c2 DM |
5272 | (define_insn "one_cmplsi2" |
5273 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5274 | (not:SI (match_operand:SI 1 "arith_operand" "rI")))] | |
e6c1be7e | 5275 | "" |
e00560c2 | 5276 | "xnor\t%%g0, %1, %0") |
e0d80184 | 5277 | |
c8b3b7d6 | 5278 | (define_insn "*cmp_cc_not" |
45a7dd80 | 5279 | [(set (reg:CC CC_REG) |
7a768814 RS |
5280 | (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI")) |
5281 | (const_int 0)))] | |
e6c1be7e | 5282 | "" |
16b46035 | 5283 | "xnorcc\t%%g0, %0, %%g0" |
24697ca0 | 5284 | [(set_attr "type" "compare")]) |
7a768814 | 5285 | |
c8b3b7d6 | 5286 | (define_insn "*cmp_ccx_not" |
45a7dd80 | 5287 | [(set (reg:CCX CC_REG) |
0e5d569c | 5288 | (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI")) |
a8d2b752 | 5289 | (const_int 0)))] |
fa0f39e4 | 5290 | "TARGET_ARCH64" |
16b46035 | 5291 | "xnorcc\t%%g0, %0, %%g0" |
24697ca0 | 5292 | [(set_attr "type" "compare")]) |
a8d2b752 | 5293 | |
c8b3b7d6 | 5294 | (define_insn "*cmp_cc_set_not" |
45a7dd80 | 5295 | [(set (reg:CC CC_REG) |
7a768814 RS |
5296 | (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI")) |
5297 | (const_int 0))) | |
5298 | (set (match_operand:SI 0 "register_operand" "=r") | |
5299 | (not:SI (match_dup 1)))] | |
e6c1be7e | 5300 | "" |
16b46035 | 5301 | "xnorcc\t%%g0, %1, %0" |
24697ca0 | 5302 | [(set_attr "type" "compare")]) |
a8d2b752 | 5303 | |
c8b3b7d6 | 5304 | (define_insn "*cmp_ccx_set_not" |
45a7dd80 | 5305 | [(set (reg:CCX CC_REG) |
0e5d569c | 5306 | (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI")) |
a8d2b752 DE |
5307 | (const_int 0))) |
5308 | (set (match_operand:DI 0 "register_operand" "=r") | |
5309 | (not:DI (match_dup 1)))] | |
fa0f39e4 | 5310 | "TARGET_ARCH64" |
16b46035 | 5311 | "xnorcc\t%%g0, %1, %0" |
24697ca0 | 5312 | [(set_attr "type" "compare")]) |
2aad5d68 DN |
5313 | |
5314 | (define_insn "*cmp_cc_set" | |
5315 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5316 | (match_operand:SI 1 "register_operand" "r")) | |
45a7dd80 | 5317 | (set (reg:CC CC_REG) |
2aad5d68 DN |
5318 | (compare:CC (match_dup 1) |
5319 | (const_int 0)))] | |
5320 | "" | |
16b46035 | 5321 | "orcc\t%1, 0, %0" |
2aad5d68 DN |
5322 | [(set_attr "type" "compare")]) |
5323 | ||
5324 | (define_insn "*cmp_ccx_set64" | |
5325 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5326 | (match_operand:DI 1 "register_operand" "r")) | |
45a7dd80 | 5327 | (set (reg:CCX CC_REG) |
2aad5d68 DN |
5328 | (compare:CCX (match_dup 1) |
5329 | (const_int 0)))] | |
5330 | "TARGET_ARCH64" | |
16b46035 | 5331 | "orcc\t%1, 0, %0" |
2aad5d68 | 5332 | [(set_attr "type" "compare")]) |
f8ece000 EB |
5333 | |
5334 | ||
7a768814 RS |
5335 | ;; Floating point arithmetic instructions. |
5336 | ||
47ac041c JJ |
5337 | (define_expand "addtf3" |
5338 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
5339 | (plus:TF (match_operand:TF 1 "general_operand" "") | |
5340 | (match_operand:TF 2 "general_operand" "")))] | |
5341 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
73985940 | 5342 | "emit_tfmode_binop (PLUS, operands); DONE;") |
47ac041c JJ |
5343 | |
5344 | (define_insn "*addtf3_hq" | |
b6d3c4ba JW |
5345 | [(set (match_operand:TF 0 "register_operand" "=e") |
5346 | (plus:TF (match_operand:TF 1 "register_operand" "e") | |
5347 | (match_operand:TF 2 "register_operand" "e")))] | |
ef903eca | 5348 | "TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 5349 | "faddq\t%1, %2, %0" |
24697ca0 | 5350 | [(set_attr "type" "fp")]) |
795068a4 | 5351 | |
7a768814 | 5352 | (define_insn "adddf3" |
b6d3c4ba JW |
5353 | [(set (match_operand:DF 0 "register_operand" "=e") |
5354 | (plus:DF (match_operand:DF 1 "register_operand" "e") | |
5355 | (match_operand:DF 2 "register_operand" "e")))] | |
ab5519b7 | 5356 | "TARGET_FPU" |
16b46035 | 5357 | "faddd\t%1, %2, %0" |
e0d80184 | 5358 | [(set_attr "type" "fp") |
24697ca0 | 5359 | (set_attr "fptype" "double")]) |
7a768814 RS |
5360 | |
5361 | (define_insn "addsf3" | |
5362 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5363 | (plus:SF (match_operand:SF 1 "register_operand" "f") | |
5364 | (match_operand:SF 2 "register_operand" "f")))] | |
ab5519b7 | 5365 | "TARGET_FPU" |
16b46035 | 5366 | "fadds\t%1, %2, %0" |
24697ca0 | 5367 | [(set_attr "type" "fp")]) |
7a768814 | 5368 | |
47ac041c JJ |
5369 | (define_expand "subtf3" |
5370 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
5371 | (minus:TF (match_operand:TF 1 "general_operand" "") | |
5372 | (match_operand:TF 2 "general_operand" "")))] | |
5373 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
73985940 | 5374 | "emit_tfmode_binop (MINUS, operands); DONE;") |
47ac041c JJ |
5375 | |
5376 | (define_insn "*subtf3_hq" | |
b6d3c4ba JW |
5377 | [(set (match_operand:TF 0 "register_operand" "=e") |
5378 | (minus:TF (match_operand:TF 1 "register_operand" "e") | |
5379 | (match_operand:TF 2 "register_operand" "e")))] | |
ef903eca | 5380 | "TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 5381 | "fsubq\t%1, %2, %0" |
24697ca0 | 5382 | [(set_attr "type" "fp")]) |
795068a4 | 5383 | |
7a768814 | 5384 | (define_insn "subdf3" |
b6d3c4ba JW |
5385 | [(set (match_operand:DF 0 "register_operand" "=e") |
5386 | (minus:DF (match_operand:DF 1 "register_operand" "e") | |
5387 | (match_operand:DF 2 "register_operand" "e")))] | |
ab5519b7 | 5388 | "TARGET_FPU" |
16b46035 | 5389 | "fsubd\t%1, %2, %0" |
e0d80184 | 5390 | [(set_attr "type" "fp") |
24697ca0 | 5391 | (set_attr "fptype" "double")]) |
7a768814 RS |
5392 | |
5393 | (define_insn "subsf3" | |
5394 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5395 | (minus:SF (match_operand:SF 1 "register_operand" "f") | |
5396 | (match_operand:SF 2 "register_operand" "f")))] | |
ab5519b7 | 5397 | "TARGET_FPU" |
16b46035 | 5398 | "fsubs\t%1, %2, %0" |
24697ca0 | 5399 | [(set_attr "type" "fp")]) |
7a768814 | 5400 | |
47ac041c JJ |
5401 | (define_expand "multf3" |
5402 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
5403 | (mult:TF (match_operand:TF 1 "general_operand" "") | |
5404 | (match_operand:TF 2 "general_operand" "")))] | |
5405 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
73985940 | 5406 | "emit_tfmode_binop (MULT, operands); DONE;") |
47ac041c JJ |
5407 | |
5408 | (define_insn "*multf3_hq" | |
b6d3c4ba JW |
5409 | [(set (match_operand:TF 0 "register_operand" "=e") |
5410 | (mult:TF (match_operand:TF 1 "register_operand" "e") | |
5411 | (match_operand:TF 2 "register_operand" "e")))] | |
ef903eca | 5412 | "TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 5413 | "fmulq\t%1, %2, %0" |
24697ca0 | 5414 | [(set_attr "type" "fpmul")]) |
795068a4 | 5415 | |
7a768814 | 5416 | (define_insn "muldf3" |
b6d3c4ba JW |
5417 | [(set (match_operand:DF 0 "register_operand" "=e") |
5418 | (mult:DF (match_operand:DF 1 "register_operand" "e") | |
5419 | (match_operand:DF 2 "register_operand" "e")))] | |
ab5519b7 | 5420 | "TARGET_FPU" |
16b46035 | 5421 | "fmuld\t%1, %2, %0" |
e0d80184 | 5422 | [(set_attr "type" "fpmul") |
24697ca0 | 5423 | (set_attr "fptype" "double")]) |
7a768814 RS |
5424 | |
5425 | (define_insn "mulsf3" | |
5426 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5427 | (mult:SF (match_operand:SF 1 "register_operand" "f") | |
5428 | (match_operand:SF 2 "register_operand" "f")))] | |
ab5519b7 | 5429 | "TARGET_FPU" |
16b46035 | 5430 | "fmuls\t%1, %2, %0" |
24697ca0 | 5431 | [(set_attr "type" "fpmul")]) |
7a768814 | 5432 | |
e8b141b5 DM |
5433 | (define_insn "fmadf4" |
5434 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5435 | (fma:DF (match_operand:DF 1 "register_operand" "e") | |
5436 | (match_operand:DF 2 "register_operand" "e") | |
5437 | (match_operand:DF 3 "register_operand" "e")))] | |
5438 | "TARGET_FMAF" | |
5439 | "fmaddd\t%1, %2, %3, %0" | |
5440 | [(set_attr "type" "fpmul")]) | |
5441 | ||
5442 | (define_insn "fmsdf4" | |
5443 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5444 | (fma:DF (match_operand:DF 1 "register_operand" "e") | |
5445 | (match_operand:DF 2 "register_operand" "e") | |
5446 | (neg:DF (match_operand:DF 3 "register_operand" "e"))))] | |
5447 | "TARGET_FMAF" | |
5448 | "fmsubd\t%1, %2, %3, %0" | |
5449 | [(set_attr "type" "fpmul")]) | |
5450 | ||
5451 | (define_insn "*nfmadf4" | |
5452 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5453 | (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e") | |
5454 | (match_operand:DF 2 "register_operand" "e") | |
5455 | (match_operand:DF 3 "register_operand" "e"))))] | |
5456 | "TARGET_FMAF" | |
5457 | "fnmaddd\t%1, %2, %3, %0" | |
5458 | [(set_attr "type" "fpmul")]) | |
5459 | ||
5460 | (define_insn "*nfmsdf4" | |
5461 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5462 | (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e") | |
5463 | (match_operand:DF 2 "register_operand" "e") | |
5464 | (neg:DF (match_operand:DF 3 "register_operand" "e")))))] | |
5465 | "TARGET_FMAF" | |
5466 | "fnmsubd\t%1, %2, %3, %0" | |
5467 | [(set_attr "type" "fpmul")]) | |
5468 | ||
5469 | (define_insn "fmasf4" | |
5470 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5471 | (fma:SF (match_operand:SF 1 "register_operand" "f") | |
5472 | (match_operand:SF 2 "register_operand" "f") | |
5473 | (match_operand:SF 3 "register_operand" "f")))] | |
5474 | "TARGET_FMAF" | |
5475 | "fmadds\t%1, %2, %3, %0" | |
5476 | [(set_attr "type" "fpmul")]) | |
5477 | ||
5478 | (define_insn "fmssf4" | |
5479 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5480 | (fma:SF (match_operand:SF 1 "register_operand" "f") | |
5481 | (match_operand:SF 2 "register_operand" "f") | |
5482 | (neg:SF (match_operand:SF 3 "register_operand" "f"))))] | |
5483 | "TARGET_FMAF" | |
5484 | "fmsubs\t%1, %2, %3, %0" | |
5485 | [(set_attr "type" "fpmul")]) | |
5486 | ||
5487 | (define_insn "*nfmasf4" | |
5488 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5489 | (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f") | |
5490 | (match_operand:SF 2 "register_operand" "f") | |
5491 | (match_operand:SF 3 "register_operand" "f"))))] | |
5492 | "TARGET_FMAF" | |
5493 | "fnmadds\t%1, %2, %3, %0" | |
5494 | [(set_attr "type" "fpmul")]) | |
5495 | ||
5496 | (define_insn "*nfmssf4" | |
5497 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5498 | (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f") | |
5499 | (match_operand:SF 2 "register_operand" "f") | |
5500 | (neg:SF (match_operand:SF 3 "register_operand" "f")))))] | |
5501 | "TARGET_FMAF" | |
5502 | "fnmsubs\t%1, %2, %3, %0" | |
5503 | [(set_attr "type" "fpmul")]) | |
5504 | ||
c8b3b7d6 | 5505 | (define_insn "*muldf3_extend" |
b6d3c4ba | 5506 | [(set (match_operand:DF 0 "register_operand" "=e") |
8d2f4374 JW |
5507 | (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f")) |
5508 | (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))] | |
5c3eacbb | 5509 | "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699" |
16b46035 | 5510 | "fsmuld\t%1, %2, %0" |
e0d80184 | 5511 | [(set_attr "type" "fpmul") |
24697ca0 | 5512 | (set_attr "fptype" "double")]) |
8d2f4374 | 5513 | |
c8b3b7d6 | 5514 | (define_insn "*multf3_extend" |
b6d3c4ba JW |
5515 | [(set (match_operand:TF 0 "register_operand" "=e") |
5516 | (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e")) | |
5517 | (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))] | |
fa0f39e4 | 5518 | "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 5519 | "fdmulq\t%1, %2, %0" |
24697ca0 | 5520 | [(set_attr "type" "fpmul")]) |
8d2f4374 | 5521 | |
47ac041c JJ |
5522 | (define_expand "divtf3" |
5523 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
5524 | (div:TF (match_operand:TF 1 "general_operand" "") | |
5525 | (match_operand:TF 2 "general_operand" "")))] | |
5526 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
73985940 | 5527 | "emit_tfmode_binop (DIV, operands); DONE;") |
47ac041c | 5528 | |
c180bd1e | 5529 | ;; don't have timing for quad-prec. divide. |
47ac041c | 5530 | (define_insn "*divtf3_hq" |
b6d3c4ba JW |
5531 | [(set (match_operand:TF 0 "register_operand" "=e") |
5532 | (div:TF (match_operand:TF 1 "register_operand" "e") | |
5533 | (match_operand:TF 2 "register_operand" "e")))] | |
ef903eca | 5534 | "TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 5535 | "fdivq\t%1, %2, %0" |
24697ca0 | 5536 | [(set_attr "type" "fpdivd")]) |
795068a4 | 5537 | |
5c3eacbb | 5538 | (define_expand "divdf3" |
b6d3c4ba JW |
5539 | [(set (match_operand:DF 0 "register_operand" "=e") |
5540 | (div:DF (match_operand:DF 1 "register_operand" "e") | |
5541 | (match_operand:DF 2 "register_operand" "e")))] | |
ab5519b7 | 5542 | "TARGET_FPU" |
5c3eacbb EB |
5543 | "") |
5544 | ||
5545 | (define_insn "*divdf3_nofix" | |
5546 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5547 | (div:DF (match_operand:DF 1 "register_operand" "e") | |
5548 | (match_operand:DF 2 "register_operand" "e")))] | |
5549 | "TARGET_FPU && !sparc_fix_ut699" | |
16b46035 | 5550 | "fdivd\t%1, %2, %0" |
e0d80184 | 5551 | [(set_attr "type" "fpdivd") |
24697ca0 | 5552 | (set_attr "fptype" "double")]) |
7a768814 | 5553 | |
5c3eacbb EB |
5554 | (define_insn "*divdf3_fix" |
5555 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5556 | (div:DF (match_operand:DF 1 "register_operand" "e") | |
5557 | (match_operand:DF 2 "register_operand" "e")))] | |
5558 | "TARGET_FPU && sparc_fix_ut699" | |
5559 | "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]" | |
5560 | [(set_attr "type" "fpdivd") | |
5561 | (set_attr "fptype" "double") | |
5562 | (set_attr "length" "2")]) | |
5563 | ||
7a768814 RS |
5564 | (define_insn "divsf3" |
5565 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5566 | (div:SF (match_operand:SF 1 "register_operand" "f") | |
5567 | (match_operand:SF 2 "register_operand" "f")))] | |
5c3eacbb | 5568 | "TARGET_FPU && !sparc_fix_ut699" |
16b46035 | 5569 | "fdivs\t%1, %2, %0" |
24697ca0 | 5570 | [(set_attr "type" "fpdivs")]) |
7a768814 | 5571 | |
45120407 | 5572 | (define_expand "negtf2" |
b6d3c4ba JW |
5573 | [(set (match_operand:TF 0 "register_operand" "=e,e") |
5574 | (neg:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
ab5519b7 | 5575 | "TARGET_FPU" |
45120407 DM |
5576 | "") |
5577 | ||
b776892b | 5578 | (define_insn_and_split "*negtf2_notv9" |
45120407 DM |
5579 | [(set (match_operand:TF 0 "register_operand" "=e,e") |
5580 | (neg:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
5581 | ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD. | |
5582 | "TARGET_FPU | |
5583 | && ! TARGET_V9" | |
5584 | "@ | |
16b46035 | 5585 | fnegs\t%0, %0 |
45120407 | 5586 | #" |
b776892b | 5587 | "&& reload_completed |
d5e8c40c | 5588 | && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" |
031fec00 | 5589 | [(set (match_dup 2) (neg:SF (match_dup 3))) |
45120407 DM |
5590 | (set (match_dup 4) (match_dup 5)) |
5591 | (set (match_dup 6) (match_dup 7))] | |
0e1638d4 | 5592 | "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0])); |
45120407 DM |
5593 | operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1])); |
5594 | operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1); | |
5595 | operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1); | |
06424989 | 5596 | operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2); |
b776892b DM |
5597 | operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);" |
5598 | [(set_attr "type" "fpmove,*") | |
5599 | (set_attr "length" "*,2")]) | |
45120407 | 5600 | |
b776892b | 5601 | (define_insn_and_split "*negtf2_v9" |
45120407 DM |
5602 | [(set (match_operand:TF 0 "register_operand" "=e,e") |
5603 | (neg:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
5604 | ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD. | |
5605 | "TARGET_FPU && TARGET_V9" | |
5606 | "@ | |
16b46035 | 5607 | fnegd\t%0, %0 |
45120407 | 5608 | #" |
b776892b | 5609 | "&& reload_completed |
d5e8c40c | 5610 | && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" |
45120407 DM |
5611 | [(set (match_dup 2) (neg:DF (match_dup 3))) |
5612 | (set (match_dup 4) (match_dup 5))] | |
0e1638d4 | 5613 | "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0])); |
45120407 DM |
5614 | operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1])); |
5615 | operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2); | |
b776892b DM |
5616 | operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);" |
5617 | [(set_attr "type" "fpmove,*") | |
5618 | (set_attr "length" "*,2") | |
5619 | (set_attr "fptype" "double")]) | |
45120407 DM |
5620 | |
5621 | (define_expand "negdf2" | |
5622 | [(set (match_operand:DF 0 "register_operand" "") | |
5623 | (neg:DF (match_operand:DF 1 "register_operand" "")))] | |
5624 | "TARGET_FPU" | |
5625 | "") | |
5626 | ||
b776892b | 5627 | (define_insn_and_split "*negdf2_notv9" |
b6d3c4ba JW |
5628 | [(set (match_operand:DF 0 "register_operand" "=e,e") |
5629 | (neg:DF (match_operand:DF 1 "register_operand" "0,e")))] | |
45120407 DM |
5630 | "TARGET_FPU && ! TARGET_V9" |
5631 | "@ | |
16b46035 | 5632 | fnegs\t%0, %0 |
45120407 | 5633 | #" |
b776892b | 5634 | "&& reload_completed |
d5e8c40c | 5635 | && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" |
45120407 DM |
5636 | [(set (match_dup 2) (neg:SF (match_dup 3))) |
5637 | (set (match_dup 4) (match_dup 5))] | |
0e1638d4 | 5638 | "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0])); |
45120407 DM |
5639 | operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1])); |
5640 | operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1); | |
b776892b DM |
5641 | operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);" |
5642 | [(set_attr "type" "fpmove,*") | |
5643 | (set_attr "length" "*,2")]) | |
45120407 DM |
5644 | |
5645 | (define_insn "*negdf2_v9" | |
5646 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5647 | (neg:DF (match_operand:DF 1 "register_operand" "e")))] | |
5648 | "TARGET_FPU && TARGET_V9" | |
16b46035 | 5649 | "fnegd\t%1, %0" |
45120407 | 5650 | [(set_attr "type" "fpmove") |
24697ca0 | 5651 | (set_attr "fptype" "double")]) |
7a768814 | 5652 | |
7a768814 RS |
5653 | (define_insn "negsf2" |
5654 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5655 | (neg:SF (match_operand:SF 1 "register_operand" "f")))] | |
ab5519b7 | 5656 | "TARGET_FPU" |
16b46035 | 5657 | "fnegs\t%1, %0" |
24697ca0 | 5658 | [(set_attr "type" "fpmove")]) |
7a768814 | 5659 | |
6570c0bd | 5660 | (define_expand "abstf2" |
45120407 DM |
5661 | [(set (match_operand:TF 0 "register_operand" "") |
5662 | (abs:TF (match_operand:TF 1 "register_operand" "")))] | |
5663 | "TARGET_FPU" | |
5664 | "") | |
5665 | ||
b776892b | 5666 | (define_insn_and_split "*abstf2_notv9" |
b6d3c4ba JW |
5667 | [(set (match_operand:TF 0 "register_operand" "=e,e") |
5668 | (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
49a7ec10 | 5669 | ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD. |
45120407 DM |
5670 | "TARGET_FPU && ! TARGET_V9" |
5671 | "@ | |
16b46035 | 5672 | fabss\t%0, %0 |
45120407 | 5673 | #" |
b776892b | 5674 | "&& reload_completed |
d5e8c40c | 5675 | && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" |
45120407 DM |
5676 | [(set (match_dup 2) (abs:SF (match_dup 3))) |
5677 | (set (match_dup 4) (match_dup 5)) | |
5678 | (set (match_dup 6) (match_dup 7))] | |
0e1638d4 | 5679 | "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0])); |
45120407 DM |
5680 | operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1])); |
5681 | operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1); | |
5682 | operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1); | |
6570c0bd | 5683 | operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2); |
b776892b DM |
5684 | operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);" |
5685 | [(set_attr "type" "fpmove,*") | |
5686 | (set_attr "length" "*,2")]) | |
6570c0bd JJ |
5687 | |
5688 | (define_insn "*abstf2_hq_v9" | |
5689 | [(set (match_operand:TF 0 "register_operand" "=e,e") | |
5690 | (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
5691 | "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD" | |
5692 | "@ | |
16b46035 DM |
5693 | fabsd\t%0, %0 |
5694 | fabsq\t%1, %0" | |
6570c0bd | 5695 | [(set_attr "type" "fpmove") |
24697ca0 | 5696 | (set_attr "fptype" "double,*")]) |
45120407 | 5697 | |
b776892b | 5698 | (define_insn_and_split "*abstf2_v9" |
45120407 DM |
5699 | [(set (match_operand:TF 0 "register_operand" "=e,e") |
5700 | (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
6570c0bd | 5701 | "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD" |
45120407 | 5702 | "@ |
16b46035 | 5703 | fabsd\t%0, %0 |
45120407 | 5704 | #" |
b776892b | 5705 | "&& reload_completed |
d5e8c40c | 5706 | && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" |
45120407 DM |
5707 | [(set (match_dup 2) (abs:DF (match_dup 3))) |
5708 | (set (match_dup 4) (match_dup 5))] | |
0e1638d4 | 5709 | "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0])); |
45120407 DM |
5710 | operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1])); |
5711 | operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2); | |
b776892b DM |
5712 | operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);" |
5713 | [(set_attr "type" "fpmove,*") | |
5714 | (set_attr "length" "*,2") | |
5715 | (set_attr "fptype" "double,*")]) | |
45120407 DM |
5716 | |
5717 | (define_expand "absdf2" | |
5718 | [(set (match_operand:DF 0 "register_operand" "") | |
5719 | (abs:DF (match_operand:DF 1 "register_operand" "")))] | |
ab5519b7 | 5720 | "TARGET_FPU" |
45120407 DM |
5721 | "") |
5722 | ||
b776892b | 5723 | (define_insn_and_split "*absdf2_notv9" |
45120407 DM |
5724 | [(set (match_operand:DF 0 "register_operand" "=e,e") |
5725 | (abs:DF (match_operand:DF 1 "register_operand" "0,e")))] | |
5726 | "TARGET_FPU && ! TARGET_V9" | |
5727 | "@ | |
16b46035 | 5728 | fabss\t%0, %0 |
45120407 | 5729 | #" |
b776892b | 5730 | "&& reload_completed |
d5e8c40c | 5731 | && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" |
45120407 DM |
5732 | [(set (match_dup 2) (abs:SF (match_dup 3))) |
5733 | (set (match_dup 4) (match_dup 5))] | |
0e1638d4 | 5734 | "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0])); |
45120407 DM |
5735 | operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1])); |
5736 | operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1); | |
b776892b DM |
5737 | operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);" |
5738 | [(set_attr "type" "fpmove,*") | |
5739 | (set_attr "length" "*,2")]) | |
45120407 DM |
5740 | |
5741 | (define_insn "*absdf2_v9" | |
5742 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5743 | (abs:DF (match_operand:DF 1 "register_operand" "e")))] | |
5744 | "TARGET_FPU && TARGET_V9" | |
16b46035 | 5745 | "fabsd\t%1, %0" |
bfd6bc60 | 5746 | [(set_attr "type" "fpmove") |
24697ca0 | 5747 | (set_attr "fptype" "double")]) |
7a768814 RS |
5748 | |
5749 | (define_insn "abssf2" | |
5750 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5751 | (abs:SF (match_operand:SF 1 "register_operand" "f")))] | |
ab5519b7 | 5752 | "TARGET_FPU" |
16b46035 | 5753 | "fabss\t%1, %0" |
24697ca0 | 5754 | [(set_attr "type" "fpmove")]) |
7a768814 | 5755 | |
47ac041c | 5756 | (define_expand "sqrttf2" |
73985940 RH |
5757 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
5758 | (sqrt:TF (match_operand:TF 1 "general_operand" "")))] | |
47ac041c | 5759 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
73985940 | 5760 | "emit_tfmode_unop (SQRT, operands); DONE;") |
47ac041c JJ |
5761 | |
5762 | (define_insn "*sqrttf2_hq" | |
b6d3c4ba JW |
5763 | [(set (match_operand:TF 0 "register_operand" "=e") |
5764 | (sqrt:TF (match_operand:TF 1 "register_operand" "e")))] | |
ef903eca | 5765 | "TARGET_FPU && TARGET_HARD_QUAD" |
16b46035 | 5766 | "fsqrtq\t%1, %0" |
24697ca0 | 5767 | [(set_attr "type" "fpsqrtd")]) |
795068a4 | 5768 | |
5c3eacbb | 5769 | (define_expand "sqrtdf2" |
b6d3c4ba JW |
5770 | [(set (match_operand:DF 0 "register_operand" "=e") |
5771 | (sqrt:DF (match_operand:DF 1 "register_operand" "e")))] | |
ab5519b7 | 5772 | "TARGET_FPU" |
5c3eacbb EB |
5773 | "") |
5774 | ||
5775 | (define_insn "*sqrtdf2_nofix" | |
5776 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5777 | (sqrt:DF (match_operand:DF 1 "register_operand" "e")))] | |
5778 | "TARGET_FPU && !sparc_fix_ut699" | |
16b46035 | 5779 | "fsqrtd\t%1, %0" |
c0ec7a75 | 5780 | [(set_attr "type" "fpsqrtd") |
24697ca0 | 5781 | (set_attr "fptype" "double")]) |
7a768814 | 5782 | |
5c3eacbb EB |
5783 | (define_insn "*sqrtdf2_fix" |
5784 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5785 | (sqrt:DF (match_operand:DF 1 "register_operand" "e")))] | |
5786 | "TARGET_FPU && sparc_fix_ut699" | |
5787 | "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]" | |
5788 | [(set_attr "type" "fpsqrtd") | |
5789 | (set_attr "fptype" "double") | |
5790 | (set_attr "length" "2")]) | |
5791 | ||
7a768814 RS |
5792 | (define_insn "sqrtsf2" |
5793 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5794 | (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] | |
5c3eacbb | 5795 | "TARGET_FPU && !sparc_fix_ut699" |
16b46035 | 5796 | "fsqrts\t%1, %0" |
24697ca0 | 5797 | [(set_attr "type" "fpsqrts")]) |
f8ece000 EB |
5798 | |
5799 | ||
5800 | ;; Arithmetic shift instructions. | |
7a768814 | 5801 | |
7a768814 RS |
5802 | (define_insn "ashlsi3" |
5803 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5804 | (ashift:SI (match_operand:SI 1 "register_operand" "r") | |
0088e8ba | 5805 | (match_operand:SI 2 "arith_operand" "rI")))] |
7a768814 | 5806 | "" |
0088e8ba | 5807 | { |
1c8b4e29 EB |
5808 | if (GET_CODE (operands[2]) == CONST_INT) |
5809 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); | |
16b46035 | 5810 | return "sll\t%1, %2, %0"; |
563facba | 5811 | } |
5422cd26 RH |
5812 | [(set_attr "type" "shift")]) |
5813 | ||
5814 | (define_insn "*ashlsi3_extend" | |
5815 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5816 | (zero_extend:DI | |
5817 | (ashift:SI (match_operand:SI 1 "register_operand" "r") | |
5818 | (match_operand:SI 2 "arith_operand" "rI"))))] | |
5819 | "TARGET_ARCH64" | |
5820 | { | |
5821 | if (GET_CODE (operands[2]) == CONST_INT) | |
5822 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); | |
5823 | return "sll\t%1, %2, %0"; | |
5824 | } | |
5825 | [(set_attr "type" "shift")]) | |
295c5559 | 5826 | |
284d86e9 JC |
5827 | (define_expand "ashldi3" |
5828 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5829 | (ashift:DI (match_operand:DI 1 "register_operand" "r") | |
5830 | (match_operand:SI 2 "arith_operand" "rI")))] | |
5831 | "TARGET_ARCH64 || TARGET_V8PLUS" | |
284d86e9 JC |
5832 | { |
5833 | if (! TARGET_ARCH64) | |
5834 | { | |
5835 | if (GET_CODE (operands[2]) == CONST_INT) | |
5836 | FAIL; | |
5837 | emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2])); | |
5838 | DONE; | |
5839 | } | |
563facba | 5840 | }) |
284d86e9 | 5841 | |
295c5559 | 5842 | (define_insn "*ashldi3_sp64" |
a8d2b752 DE |
5843 | [(set (match_operand:DI 0 "register_operand" "=r") |
5844 | (ashift:DI (match_operand:DI 1 "register_operand" "r") | |
5845 | (match_operand:SI 2 "arith_operand" "rI")))] | |
fa0f39e4 | 5846 | "TARGET_ARCH64" |
a8d2b752 | 5847 | { |
1c8b4e29 EB |
5848 | if (GET_CODE (operands[2]) == CONST_INT) |
5849 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); | |
16b46035 | 5850 | return "sllx\t%1, %2, %0"; |
563facba | 5851 | } |
5422cd26 | 5852 | [(set_attr "type" "shift")]) |
a8d2b752 | 5853 | |
e0d80184 | 5854 | ;; XXX UGH! |
284d86e9 JC |
5855 | (define_insn "ashldi3_v8plus" |
5856 | [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") | |
c6b0465b | 5857 | (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") |
284d86e9 JC |
5858 | (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) |
5859 | (clobber (match_scratch:SI 3 "=X,X,&h"))] | |
5860 | "TARGET_V8PLUS" | |
68126bad | 5861 | "* return output_v8plus_shift (insn ,operands, \"sllx\");" |
24697ca0 DM |
5862 | [(set_attr "type" "multi") |
5863 | (set_attr "length" "5,5,6")]) | |
284d86e9 | 5864 | |
c6b0465b | 5865 | ;; Optimize (1LL<<x)-1 |
e61c29e9 DM |
5866 | ;; XXX this also needs to be fixed to handle equal subregs |
5867 | ;; XXX first before we could re-enable it. | |
c77e04ae RH |
5868 | ;(define_insn "" |
5869 | ; [(set (match_operand:DI 0 "register_operand" "=h") | |
5870 | ; (plus:DI (ashift:DI (const_int 1) | |
5871 | ; (match_operand:SI 1 "arith_operand" "rI")) | |
5872 | ; (const_int -1)))] | |
5873 | ; "0 && TARGET_V8PLUS" | |
c77e04ae RH |
5874 | ;{ |
5875 | ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0])) | |
16b46035 DM |
5876 | ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0"; |
5877 | ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0"; | |
563facba | 5878 | ;} |
24697ca0 DM |
5879 | ; [(set_attr "type" "multi") |
5880 | ; (set_attr "length" "4")]) | |
c6b0465b | 5881 | |
c8b3b7d6 | 5882 | (define_insn "*cmp_cc_ashift_1" |
45a7dd80 | 5883 | [(set (reg:CC_NOOV CC_REG) |
13a7eb33 JW |
5884 | (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r") |
5885 | (const_int 1)) | |
5886 | (const_int 0)))] | |
e6c1be7e | 5887 | "" |
16b46035 | 5888 | "addcc\t%0, %0, %%g0" |
24697ca0 | 5889 | [(set_attr "type" "compare")]) |
13a7eb33 | 5890 | |
c8b3b7d6 | 5891 | (define_insn "*cmp_cc_set_ashift_1" |
45a7dd80 | 5892 | [(set (reg:CC_NOOV CC_REG) |
13a7eb33 JW |
5893 | (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r") |
5894 | (const_int 1)) | |
5895 | (const_int 0))) | |
5896 | (set (match_operand:SI 0 "register_operand" "=r") | |
5897 | (ashift:SI (match_dup 1) (const_int 1)))] | |
5898 | "" | |
16b46035 | 5899 | "addcc\t%1, %1, %0" |
24697ca0 | 5900 | [(set_attr "type" "compare")]) |
13a7eb33 | 5901 | |
7a768814 RS |
5902 | (define_insn "ashrsi3" |
5903 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5904 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
0088e8ba | 5905 | (match_operand:SI 2 "arith_operand" "rI")))] |
7a768814 | 5906 | "" |
1c8b4e29 EB |
5907 | { |
5908 | if (GET_CODE (operands[2]) == CONST_INT) | |
5909 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); | |
5910 | return "sra\t%1, %2, %0"; | |
5911 | } | |
24697ca0 | 5912 | [(set_attr "type" "shift")]) |
7a768814 | 5913 | |
295c5559 | 5914 | (define_insn "*ashrsi3_extend" |
6570c0bd | 5915 | [(set (match_operand:DI 0 "register_operand" "=r") |
295c5559 JJ |
5916 | (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") |
5917 | (match_operand:SI 2 "arith_operand" "r"))))] | |
5918 | "TARGET_ARCH64" | |
16b46035 | 5919 | "sra\t%1, %2, %0" |
24697ca0 | 5920 | [(set_attr "type" "shift")]) |
295c5559 JJ |
5921 | |
5922 | ;; This handles the case as above, but with constant shift instead of | |
5923 | ;; register. Combiner "simplifies" it for us a little bit though. | |
5924 | (define_insn "*ashrsi3_extend2" | |
6570c0bd | 5925 | [(set (match_operand:DI 0 "register_operand" "=r") |
295c5559 JJ |
5926 | (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0) |
5927 | (const_int 32)) | |
0e5d569c EB |
5928 | (match_operand:SI 2 "small_int_operand" "I")))] |
5929 | "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64" | |
295c5559 JJ |
5930 | { |
5931 | operands[2] = GEN_INT (INTVAL (operands[2]) - 32); | |
16b46035 | 5932 | return "sra\t%1, %2, %0"; |
563facba | 5933 | } |
24697ca0 | 5934 | [(set_attr "type" "shift")]) |
295c5559 | 5935 | |
284d86e9 JC |
5936 | (define_expand "ashrdi3" |
5937 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5938 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
5939 | (match_operand:SI 2 "arith_operand" "rI")))] | |
5940 | "TARGET_ARCH64 || TARGET_V8PLUS" | |
e0d80184 DM |
5941 | { |
5942 | if (! TARGET_ARCH64) | |
5943 | { | |
5944 | if (GET_CODE (operands[2]) == CONST_INT) | |
5945 | FAIL; /* prefer generic code in this case */ | |
5946 | emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2])); | |
5947 | DONE; | |
5948 | } | |
563facba | 5949 | }) |
284d86e9 | 5950 | |
1c8b4e29 | 5951 | (define_insn "*ashrdi3_sp64" |
a8d2b752 DE |
5952 | [(set (match_operand:DI 0 "register_operand" "=r") |
5953 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
5954 | (match_operand:SI 2 "arith_operand" "rI")))] | |
fa0f39e4 | 5955 | "TARGET_ARCH64" |
1c8b4e29 EB |
5956 | |
5957 | { | |
5958 | if (GET_CODE (operands[2]) == CONST_INT) | |
5959 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); | |
5960 | return "srax\t%1, %2, %0"; | |
5961 | } | |
24697ca0 | 5962 | [(set_attr "type" "shift")]) |
a8d2b752 | 5963 | |
e0d80184 | 5964 | ;; XXX |
284d86e9 JC |
5965 | (define_insn "ashrdi3_v8plus" |
5966 | [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") | |
c6b0465b | 5967 | (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") |
284d86e9 JC |
5968 | (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) |
5969 | (clobber (match_scratch:SI 3 "=X,X,&h"))] | |
5970 | "TARGET_V8PLUS" | |
68126bad | 5971 | "* return output_v8plus_shift (insn, operands, \"srax\");" |
24697ca0 DM |
5972 | [(set_attr "type" "multi") |
5973 | (set_attr "length" "5,5,6")]) | |
284d86e9 | 5974 | |
7a768814 RS |
5975 | (define_insn "lshrsi3" |
5976 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5977 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
0088e8ba | 5978 | (match_operand:SI 2 "arith_operand" "rI")))] |
7a768814 | 5979 | "" |
1c8b4e29 EB |
5980 | { |
5981 | if (GET_CODE (operands[2]) == CONST_INT) | |
5982 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); | |
5983 | return "srl\t%1, %2, %0"; | |
5984 | } | |
24697ca0 | 5985 | [(set_attr "type" "shift")]) |
a8d2b752 | 5986 | |
5422cd26 RH |
5987 | (define_insn "*lshrsi3_extend0" |
5988 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5989 | (zero_extend:DI | |
5990 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
5991 | (match_operand:SI 2 "arith_operand" "rI"))))] | |
5992 | "TARGET_ARCH64" | |
5993 | { | |
5994 | if (GET_CODE (operands[2]) == CONST_INT) | |
5995 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); | |
5996 | return "srl\t%1, %2, %0"; | |
5997 | } | |
5998 | [(set_attr "type" "shift")]) | |
5999 | ||
295c5559 JJ |
6000 | ;; This handles the case where |
6001 | ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))), | |
6002 | ;; but combiner "simplifies" it for us. | |
5422cd26 | 6003 | (define_insn "*lshrsi3_extend1" |
6570c0bd | 6004 | [(set (match_operand:DI 0 "register_operand" "=r") |
295c5559 JJ |
6005 | (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") |
6006 | (match_operand:SI 2 "arith_operand" "r")) 0) | |
8ca864d2 EB |
6007 | (match_operand 3 "const_int_operand" "")))] |
6008 | "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff" | |
16b46035 | 6009 | "srl\t%1, %2, %0" |
24697ca0 | 6010 | [(set_attr "type" "shift")]) |
295c5559 JJ |
6011 | |
6012 | ;; This handles the case where | |
6013 | ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32)) | |
6014 | ;; but combiner "simplifies" it for us. | |
6015 | (define_insn "*lshrsi3_extend2" | |
6570c0bd | 6016 | [(set (match_operand:DI 0 "register_operand" "=r") |
295c5559 | 6017 | (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0) |
0e5d569c | 6018 | (match_operand 2 "small_int_operand" "I") |
295c5559 | 6019 | (const_int 32)))] |
0e5d569c | 6020 | "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32" |
295c5559 JJ |
6021 | { |
6022 | operands[2] = GEN_INT (32 - INTVAL (operands[2])); | |
16b46035 | 6023 | return "srl\t%1, %2, %0"; |
563facba | 6024 | } |
24697ca0 | 6025 | [(set_attr "type" "shift")]) |
295c5559 | 6026 | |
284d86e9 JC |
6027 | (define_expand "lshrdi3" |
6028 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6029 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
6030 | (match_operand:SI 2 "arith_operand" "rI")))] | |
6031 | "TARGET_ARCH64 || TARGET_V8PLUS" | |
e0d80184 DM |
6032 | { |
6033 | if (! TARGET_ARCH64) | |
6034 | { | |
6035 | if (GET_CODE (operands[2]) == CONST_INT) | |
6036 | FAIL; | |
6037 | emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2])); | |
6038 | DONE; | |
6039 | } | |
563facba | 6040 | }) |
284d86e9 | 6041 | |
1c8b4e29 | 6042 | (define_insn "*lshrdi3_sp64" |
a8d2b752 DE |
6043 | [(set (match_operand:DI 0 "register_operand" "=r") |
6044 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
6045 | (match_operand:SI 2 "arith_operand" "rI")))] | |
fa0f39e4 | 6046 | "TARGET_ARCH64" |
1c8b4e29 EB |
6047 | { |
6048 | if (GET_CODE (operands[2]) == CONST_INT) | |
6049 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); | |
6050 | return "srlx\t%1, %2, %0"; | |
6051 | } | |
24697ca0 | 6052 | [(set_attr "type" "shift")]) |
284d86e9 | 6053 | |
e0d80184 | 6054 | ;; XXX |
284d86e9 JC |
6055 | (define_insn "lshrdi3_v8plus" |
6056 | [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") | |
c6b0465b | 6057 | (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") |
284d86e9 JC |
6058 | (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) |
6059 | (clobber (match_scratch:SI 3 "=X,X,&h"))] | |
6060 | "TARGET_V8PLUS" | |
68126bad | 6061 | "* return output_v8plus_shift (insn, operands, \"srlx\");" |
24697ca0 DM |
6062 | [(set_attr "type" "multi") |
6063 | (set_attr "length" "5,5,6")]) | |
5cb01b65 JJ |
6064 | |
6065 | (define_insn "" | |
6066 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6067 | (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
ddef6bc7 | 6068 | (const_int 32)) 4) |
0e5d569c EB |
6069 | (match_operand:SI 2 "small_int_operand" "I")))] |
6070 | "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32" | |
5cb01b65 JJ |
6071 | { |
6072 | operands[2] = GEN_INT (INTVAL (operands[2]) + 32); | |
16b46035 | 6073 | return "srax\t%1, %2, %0"; |
563facba | 6074 | } |
24697ca0 | 6075 | [(set_attr "type" "shift")]) |
5cb01b65 JJ |
6076 | |
6077 | (define_insn "" | |
6078 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6079 | (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
ddef6bc7 | 6080 | (const_int 32)) 4) |
0e5d569c EB |
6081 | (match_operand:SI 2 "small_int_operand" "I")))] |
6082 | "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32" | |
5cb01b65 JJ |
6083 | { |
6084 | operands[2] = GEN_INT (INTVAL (operands[2]) + 32); | |
16b46035 | 6085 | return "srlx\t%1, %2, %0"; |
563facba | 6086 | } |
24697ca0 | 6087 | [(set_attr "type" "shift")]) |
5cb01b65 JJ |
6088 | |
6089 | (define_insn "" | |
6090 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6091 | (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
0e5d569c EB |
6092 | (match_operand:SI 2 "small_int_operand" "I")) 4) |
6093 | (match_operand:SI 3 "small_int_operand" "I")))] | |
5cb01b65 | 6094 | "TARGET_ARCH64 |
5cb01b65 JJ |
6095 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32 |
6096 | && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32 | |
6097 | && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64" | |
5cb01b65 JJ |
6098 | { |
6099 | operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])); | |
6100 | ||
16b46035 | 6101 | return "srax\t%1, %2, %0"; |
563facba | 6102 | } |
24697ca0 | 6103 | [(set_attr "type" "shift")]) |
5cb01b65 JJ |
6104 | |
6105 | (define_insn "" | |
6106 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6107 | (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
0e5d569c EB |
6108 | (match_operand:SI 2 "small_int_operand" "I")) 4) |
6109 | (match_operand:SI 3 "small_int_operand" "I")))] | |
5cb01b65 | 6110 | "TARGET_ARCH64 |
5cb01b65 JJ |
6111 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32 |
6112 | && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32 | |
6113 | && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64" | |
5cb01b65 JJ |
6114 | { |
6115 | operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])); | |
6116 | ||
16b46035 | 6117 | return "srlx\t%1, %2, %0"; |
563facba | 6118 | } |
24697ca0 | 6119 | [(set_attr "type" "shift")]) |
f8ece000 EB |
6120 | |
6121 | ||
6122 | ;; Unconditional and other jump instructions. | |
6123 | ||
8b98b5fd | 6124 | (define_expand "jump" |
7a768814 | 6125 | [(set (pc) (label_ref (match_operand 0 "" "")))] |
8b98b5fd DM |
6126 | "") |
6127 | ||
6128 | (define_insn "*jump_ubranch" | |
6129 | [(set (pc) (label_ref (match_operand 0 "" "")))] | |
6130 | "! TARGET_CBCOND" | |
6131 | "* return output_ubranch (operands[0], insn);" | |
e8d6096c | 6132 | [(set_attr "type" "uncond_branch")]) |
7a768814 | 6133 | |
8b98b5fd DM |
6134 | (define_insn "*jump_cbcond" |
6135 | [(set (pc) (label_ref (match_operand 0 "" "")))] | |
6136 | "TARGET_CBCOND" | |
6137 | "* return output_ubranch (operands[0], insn);" | |
6138 | [(set_attr "type" "uncond_cbcond")]) | |
6139 | ||
7a768814 | 6140 | (define_expand "tablejump" |
a8d2b752 | 6141 | [(parallel [(set (pc) (match_operand 0 "register_operand" "r")) |
7a768814 | 6142 | (use (label_ref (match_operand 1 "" "")))])] |
95726648 | 6143 | "" |
7a768814 | 6144 | { |
f5f7d171 | 6145 | gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE); |
a8d2b752 | 6146 | |
e0d80184 DM |
6147 | /* In pic mode, our address differences are against the base of the |
6148 | table. Add that base value back in; CSE ought to be able to combine | |
6149 | the two address loads. */ | |
7a768814 RS |
6150 | if (flag_pic) |
6151 | { | |
67cb8900 | 6152 | rtx tmp, tmp2; |
e0d80184 | 6153 | tmp = gen_rtx_LABEL_REF (Pmode, operands[1]); |
67cb8900 JJ |
6154 | tmp2 = operands[0]; |
6155 | if (CASE_VECTOR_MODE != Pmode) | |
6156 | tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2); | |
6157 | tmp = gen_rtx_PLUS (Pmode, tmp2, tmp); | |
e0d80184 | 6158 | operands[0] = memory_address (Pmode, tmp); |
7a768814 | 6159 | } |
563facba | 6160 | }) |
7a768814 | 6161 | |
c8b3b7d6 | 6162 | (define_insn "*tablejump_sp32" |
7a768814 RS |
6163 | [(set (pc) (match_operand:SI 0 "address_operand" "p")) |
6164 | (use (label_ref (match_operand 1 "" "")))] | |
7a2bf7af | 6165 | "! TARGET_ARCH64" |
16b46035 | 6166 | "jmp\t%a0%#" |
a8d2b752 DE |
6167 | [(set_attr "type" "uncond_branch")]) |
6168 | ||
c8b3b7d6 | 6169 | (define_insn "*tablejump_sp64" |
a8d2b752 DE |
6170 | [(set (pc) (match_operand:DI 0 "address_operand" "p")) |
6171 | (use (label_ref (match_operand 1 "" "")))] | |
7a2bf7af | 6172 | "TARGET_ARCH64" |
16b46035 | 6173 | "jmp\t%a0%#" |
e8d6096c | 6174 | [(set_attr "type" "uncond_branch")]) |
7a768814 | 6175 | |
f8ece000 EB |
6176 | |
6177 | ;; Jump to subroutine instructions. | |
6178 | ||
7a768814 RS |
6179 | (define_expand "call" |
6180 | ;; Note that this expression is not used for generating RTL. | |
6181 | ;; All the RTL is generated explicitly below. | |
a8d2b752 | 6182 | [(call (match_operand 0 "call_operand" "") |
7a768814 RS |
6183 | (match_operand 3 "" "i"))] |
6184 | ;; operands[2] is next_arg_register | |
6185 | ;; operands[3] is struct_value_size_rtx. | |
6186 | "" | |
7a768814 | 6187 | { |
9e1395f1 | 6188 | rtx fn_rtx; |
7a768814 | 6189 | |
1910440e | 6190 | gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE); |
a8d2b752 | 6191 | |
f5f7d171 | 6192 | gcc_assert (GET_CODE (operands[3]) == CONST_INT); |
bfb23806 | 6193 | |
60801f0b | 6194 | if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF) |
7a768814 RS |
6195 | { |
6196 | /* This is really a PIC sequence. We want to represent | |
9ec36da5 | 6197 | it as a funny jump so its delay slots can be filled. |
7a768814 RS |
6198 | |
6199 | ??? But if this really *is* a CALL, will not it clobber the | |
6200 | call-clobbered registers? We lose this if it is a JUMP_INSN. | |
6201 | Why cannot we have delay slots filled if it were a CALL? */ | |
6202 | ||
bfb23806 | 6203 | /* We accept negative sizes for untyped calls. */ |
fa0f39e4 | 6204 | if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0) |
60801f0b | 6205 | emit_jump_insn |
c5c76735 JL |
6206 | (gen_rtx_PARALLEL |
6207 | (VOIDmode, | |
6208 | gen_rtvec (3, | |
6209 | gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)), | |
8232d28f | 6210 | operands[3], |
c5c76735 | 6211 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); |
7a768814 | 6212 | else |
60801f0b | 6213 | emit_jump_insn |
c5c76735 JL |
6214 | (gen_rtx_PARALLEL |
6215 | (VOIDmode, | |
6216 | gen_rtvec (2, | |
6217 | gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)), | |
6218 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); | |
7a768814 RS |
6219 | goto finish_call; |
6220 | } | |
6221 | ||
6222 | fn_rtx = operands[0]; | |
6223 | ||
bfb23806 | 6224 | /* We accept negative sizes for untyped calls. */ |
fa0f39e4 | 6225 | if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0) |
1910440e | 6226 | sparc_emit_call_insn |
c5c76735 JL |
6227 | (gen_rtx_PARALLEL |
6228 | (VOIDmode, | |
9e1395f1 | 6229 | gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx), |
8232d28f | 6230 | operands[3], |
1910440e RS |
6231 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))), |
6232 | XEXP (fn_rtx, 0)); | |
7a768814 | 6233 | else |
1910440e | 6234 | sparc_emit_call_insn |
c5c76735 JL |
6235 | (gen_rtx_PARALLEL |
6236 | (VOIDmode, | |
9e1395f1 | 6237 | gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx), |
1910440e RS |
6238 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))), |
6239 | XEXP (fn_rtx, 0)); | |
7a768814 RS |
6240 | |
6241 | finish_call: | |
7a768814 RS |
6242 | |
6243 | DONE; | |
563facba | 6244 | }) |
7a768814 | 6245 | |
bf97b967 JW |
6246 | ;; We can't use the same pattern for these two insns, because then registers |
6247 | ;; in the address may not be properly reloaded. | |
6248 | ||
c8b3b7d6 | 6249 | (define_insn "*call_address_sp32" |
bf97b967 JW |
6250 | [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) |
6251 | (match_operand 1 "" "")) | |
45a7dd80 | 6252 | (clobber (reg:SI O7_REG))] |
bf97b967 | 6253 | ;;- Do not use operand 1 for most machines. |
7a2bf7af | 6254 | "! TARGET_ARCH64" |
16b46035 | 6255 | "call\t%a0, %1%#" |
bf97b967 JW |
6256 | [(set_attr "type" "call")]) |
6257 | ||
c8b3b7d6 | 6258 | (define_insn "*call_symbolic_sp32" |
2c435002 | 6259 | [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) |
7a768814 | 6260 | (match_operand 1 "" "")) |
45a7dd80 | 6261 | (clobber (reg:SI O7_REG))] |
7a768814 | 6262 | ;;- Do not use operand 1 for most machines. |
7a2bf7af | 6263 | "! TARGET_ARCH64" |
16b46035 | 6264 | "call\t%a0, %1%#" |
a8d2b752 DE |
6265 | [(set_attr "type" "call")]) |
6266 | ||
c8b3b7d6 | 6267 | (define_insn "*call_address_sp64" |
3276910d | 6268 | [(call (mem:DI (match_operand:DI 0 "address_operand" "p")) |
a8d2b752 | 6269 | (match_operand 1 "" "")) |
45a7dd80 | 6270 | (clobber (reg:DI O7_REG))] |
a8d2b752 | 6271 | ;;- Do not use operand 1 for most machines. |
7a2bf7af | 6272 | "TARGET_ARCH64" |
16b46035 | 6273 | "call\t%a0, %1%#" |
a8d2b752 DE |
6274 | [(set_attr "type" "call")]) |
6275 | ||
c8b3b7d6 | 6276 | (define_insn "*call_symbolic_sp64" |
3276910d | 6277 | [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s")) |
a8d2b752 | 6278 | (match_operand 1 "" "")) |
45a7dd80 | 6279 | (clobber (reg:DI O7_REG))] |
a8d2b752 | 6280 | ;;- Do not use operand 1 for most machines. |
7a2bf7af | 6281 | "TARGET_ARCH64" |
16b46035 | 6282 | "call\t%a0, %1%#" |
7a768814 RS |
6283 | [(set_attr "type" "call")]) |
6284 | ||
6285 | ;; This is a call that wants a structure value. | |
a8d2b752 | 6286 | ;; There is no such critter for v9 (??? we may need one anyway). |
c8b3b7d6 | 6287 | (define_insn "*call_address_struct_value_sp32" |
bf97b967 JW |
6288 | [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) |
6289 | (match_operand 1 "" "")) | |
6290 | (match_operand 2 "immediate_operand" "") | |
45a7dd80 | 6291 | (clobber (reg:SI O7_REG))] |
bf97b967 | 6292 | ;;- Do not use operand 1 for most machines. |
bfb23806 | 6293 | "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" |
ecaa611b EB |
6294 | { |
6295 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff); | |
6296 | return "call\t%a0, %1\n\t nop\n\tunimp\t%2"; | |
6297 | } | |
fba0947d | 6298 | [(set_attr "type" "call_no_delay_slot") |
f17f9332 | 6299 | (set_attr "length" "3")]) |
bf97b967 JW |
6300 | |
6301 | ;; This is a call that wants a structure value. | |
a8d2b752 | 6302 | ;; There is no such critter for v9 (??? we may need one anyway). |
c8b3b7d6 | 6303 | (define_insn "*call_symbolic_struct_value_sp32" |
2c435002 | 6304 | [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) |
7a768814 RS |
6305 | (match_operand 1 "" "")) |
6306 | (match_operand 2 "immediate_operand" "") | |
45a7dd80 | 6307 | (clobber (reg:SI O7_REG))] |
7a768814 | 6308 | ;;- Do not use operand 1 for most machines. |
bfb23806 | 6309 | "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" |
ecaa611b EB |
6310 | { |
6311 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff); | |
6312 | return "call\t%a0, %1\n\t nop\n\tunimp\t%2"; | |
6313 | } | |
fba0947d | 6314 | [(set_attr "type" "call_no_delay_slot") |
f17f9332 | 6315 | (set_attr "length" "3")]) |
7a768814 | 6316 | |
d18d5ca2 JW |
6317 | ;; This is a call that may want a structure value. This is used for |
6318 | ;; untyped_calls. | |
c8b3b7d6 | 6319 | (define_insn "*call_address_untyped_struct_value_sp32" |
d18d5ca2 JW |
6320 | [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) |
6321 | (match_operand 1 "" "")) | |
6322 | (match_operand 2 "immediate_operand" "") | |
45a7dd80 | 6323 | (clobber (reg:SI O7_REG))] |
d18d5ca2 | 6324 | ;;- Do not use operand 1 for most machines. |
fa0f39e4 | 6325 | "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" |
a6163c22 | 6326 | "call\t%a0, %1\n\t nop\n\tnop" |
fba0947d | 6327 | [(set_attr "type" "call_no_delay_slot") |
f17f9332 | 6328 | (set_attr "length" "3")]) |
d18d5ca2 | 6329 | |
bfb23806 EB |
6330 | ;; This is a call that may want a structure value. This is used for |
6331 | ;; untyped_calls. | |
c8b3b7d6 | 6332 | (define_insn "*call_symbolic_untyped_struct_value_sp32" |
d18d5ca2 JW |
6333 | [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) |
6334 | (match_operand 1 "" "")) | |
6335 | (match_operand 2 "immediate_operand" "") | |
45a7dd80 | 6336 | (clobber (reg:SI O7_REG))] |
d18d5ca2 | 6337 | ;;- Do not use operand 1 for most machines. |
fa0f39e4 | 6338 | "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" |
a6163c22 | 6339 | "call\t%a0, %1\n\t nop\n\tnop" |
fba0947d | 6340 | [(set_attr "type" "call_no_delay_slot") |
f17f9332 | 6341 | (set_attr "length" "3")]) |
d18d5ca2 | 6342 | |
7a768814 | 6343 | (define_expand "call_value" |
a8d2b752 DE |
6344 | ;; Note that this expression is not used for generating RTL. |
6345 | ;; All the RTL is generated explicitly below. | |
7a768814 | 6346 | [(set (match_operand 0 "register_operand" "=rf") |
3276910d | 6347 | (call (match_operand 1 "" "") |
7a768814 | 6348 | (match_operand 4 "" "")))] |
a8d2b752 | 6349 | ;; operand 2 is stack_size_rtx |
7a768814 RS |
6350 | ;; operand 3 is next_arg_register |
6351 | "" | |
7a768814 | 6352 | { |
9e1395f1 | 6353 | rtx fn_rtx; |
7a768814 RS |
6354 | rtvec vec; |
6355 | ||
1910440e | 6356 | gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE); |
a8d2b752 | 6357 | |
7a768814 RS |
6358 | fn_rtx = operands[1]; |
6359 | ||
7a768814 | 6360 | vec = gen_rtvec (2, |
5b8e7fa3 | 6361 | gen_rtx_SET (VOIDmode, operands[0], |
9e1395f1 | 6362 | gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)), |
254110c2 | 6363 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))); |
7a768814 | 6364 | |
1910440e | 6365 | sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0)); |
7a768814 RS |
6366 | |
6367 | DONE; | |
563facba | 6368 | }) |
7a768814 | 6369 | |
c8b3b7d6 | 6370 | (define_insn "*call_value_address_sp32" |
7a768814 | 6371 | [(set (match_operand 0 "" "=rf") |
bf97b967 JW |
6372 | (call (mem:SI (match_operand:SI 1 "address_operand" "p")) |
6373 | (match_operand 2 "" ""))) | |
45a7dd80 | 6374 | (clobber (reg:SI O7_REG))] |
bf97b967 | 6375 | ;;- Do not use operand 2 for most machines. |
7a2bf7af | 6376 | "! TARGET_ARCH64" |
16b46035 | 6377 | "call\t%a1, %2%#" |
bf97b967 JW |
6378 | [(set_attr "type" "call")]) |
6379 | ||
c8b3b7d6 | 6380 | (define_insn "*call_value_symbolic_sp32" |
bf97b967 | 6381 | [(set (match_operand 0 "" "=rf") |
2c435002 | 6382 | (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s")) |
7a768814 | 6383 | (match_operand 2 "" ""))) |
45a7dd80 | 6384 | (clobber (reg:SI O7_REG))] |
7a768814 | 6385 | ;;- Do not use operand 2 for most machines. |
7a2bf7af | 6386 | "! TARGET_ARCH64" |
16b46035 | 6387 | "call\t%a1, %2%#" |
a8d2b752 DE |
6388 | [(set_attr "type" "call")]) |
6389 | ||
c8b3b7d6 | 6390 | (define_insn "*call_value_address_sp64" |
82d6b402 | 6391 | [(set (match_operand 0 "" "") |
3276910d | 6392 | (call (mem:DI (match_operand:DI 1 "address_operand" "p")) |
a8d2b752 | 6393 | (match_operand 2 "" ""))) |
45a7dd80 | 6394 | (clobber (reg:DI O7_REG))] |
a8d2b752 | 6395 | ;;- Do not use operand 2 for most machines. |
7a2bf7af | 6396 | "TARGET_ARCH64" |
16b46035 | 6397 | "call\t%a1, %2%#" |
a8d2b752 DE |
6398 | [(set_attr "type" "call")]) |
6399 | ||
c8b3b7d6 | 6400 | (define_insn "*call_value_symbolic_sp64" |
82d6b402 | 6401 | [(set (match_operand 0 "" "") |
3276910d | 6402 | (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s")) |
a8d2b752 | 6403 | (match_operand 2 "" ""))) |
45a7dd80 | 6404 | (clobber (reg:DI O7_REG))] |
a8d2b752 | 6405 | ;;- Do not use operand 2 for most machines. |
7a2bf7af | 6406 | "TARGET_ARCH64" |
16b46035 | 6407 | "call\t%a1, %2%#" |
7a768814 | 6408 | [(set_attr "type" "call")]) |
576182a3 TW |
6409 | |
6410 | (define_expand "untyped_call" | |
d18d5ca2 | 6411 | [(parallel [(call (match_operand 0 "" "") |
576182a3 | 6412 | (const_int 0)) |
d24088cc | 6413 | (match_operand:BLK 1 "memory_operand" "") |
d18d5ca2 | 6414 | (match_operand 2 "" "")])] |
576182a3 | 6415 | "" |
576182a3 | 6416 | { |
d24088cc EB |
6417 | rtx valreg1 = gen_rtx_REG (DImode, 8); |
6418 | rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32); | |
6419 | rtx result = operands[1]; | |
576182a3 | 6420 | |
d18d5ca2 JW |
6421 | /* Pass constm1 to indicate that it may expect a structure value, but |
6422 | we don't know what size it is. */ | |
0499c2e4 | 6423 | emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx)); |
bf97b967 | 6424 | |
d24088cc EB |
6425 | /* Save the function value registers. */ |
6426 | emit_move_insn (adjust_address (result, DImode, 0), valreg1); | |
6427 | emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8), | |
6428 | valreg2); | |
bf97b967 | 6429 | |
d18d5ca2 JW |
6430 | /* The optimizer does not know that the call sets the function value |
6431 | registers we stored in the result block. We avoid problems by | |
6432 | claiming that all hard registers are used and clobbered at this | |
6433 | point. */ | |
6434 | emit_insn (gen_blockage ()); | |
576182a3 | 6435 | |
d18d5ca2 | 6436 | DONE; |
563facba | 6437 | }) |
a8d2b752 | 6438 | |
f8ece000 EB |
6439 | ;; Tail call instructions. |
6440 | ||
7d167afd JJ |
6441 | (define_expand "sibcall" |
6442 | [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0)) | |
6443 | (return)])] | |
6444 | "" | |
6445 | "") | |
6446 | ||
6447 | (define_insn "*sibcall_symbolic_sp32" | |
6448 | [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) | |
6449 | (match_operand 1 "" "")) | |
6450 | (return)] | |
7a2bf7af | 6451 | "! TARGET_ARCH64" |
7d167afd JJ |
6452 | "* return output_sibcall(insn, operands[0]);" |
6453 | [(set_attr "type" "sibcall")]) | |
6454 | ||
6455 | (define_insn "*sibcall_symbolic_sp64" | |
3276910d | 6456 | [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s")) |
7d167afd JJ |
6457 | (match_operand 1 "" "")) |
6458 | (return)] | |
7a2bf7af | 6459 | "TARGET_ARCH64" |
7d167afd JJ |
6460 | "* return output_sibcall(insn, operands[0]);" |
6461 | [(set_attr "type" "sibcall")]) | |
6462 | ||
6463 | (define_expand "sibcall_value" | |
6464 | [(parallel [(set (match_operand 0 "register_operand" "=rf") | |
3276910d | 6465 | (call (match_operand 1 "" "") (const_int 0))) |
7d167afd JJ |
6466 | (return)])] |
6467 | "" | |
6468 | "") | |
6469 | ||
6470 | (define_insn "*sibcall_value_symbolic_sp32" | |
6471 | [(set (match_operand 0 "" "=rf") | |
6472 | (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s")) | |
6473 | (match_operand 2 "" ""))) | |
6474 | (return)] | |
7a2bf7af | 6475 | "! TARGET_ARCH64" |
7d167afd JJ |
6476 | "* return output_sibcall(insn, operands[1]);" |
6477 | [(set_attr "type" "sibcall")]) | |
6478 | ||
6479 | (define_insn "*sibcall_value_symbolic_sp64" | |
6480 | [(set (match_operand 0 "" "") | |
3276910d | 6481 | (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s")) |
7d167afd JJ |
6482 | (match_operand 2 "" ""))) |
6483 | (return)] | |
7a2bf7af | 6484 | "TARGET_ARCH64" |
7d167afd JJ |
6485 | "* return output_sibcall(insn, operands[1]);" |
6486 | [(set_attr "type" "sibcall")]) | |
6487 | ||
f8ece000 EB |
6488 | |
6489 | ;; Special instructions. | |
9ac617d4 EB |
6490 | |
6491 | (define_expand "prologue" | |
7d167afd JJ |
6492 | [(const_int 0)] |
6493 | "" | |
9ac617d4 | 6494 | { |
b11b0904 EB |
6495 | if (TARGET_FLAT) |
6496 | sparc_flat_expand_prologue (); | |
6497 | else | |
6498 | sparc_expand_prologue (); | |
9ac617d4 EB |
6499 | DONE; |
6500 | }) | |
6501 | ||
18970372 EB |
6502 | ;; The "register window save" insn is modelled as follows. The dwarf2 |
6503 | ;; information is manually added in emit_window_save. | |
78a8eb4e | 6504 | |
18970372 | 6505 | (define_insn "window_save" |
78a8eb4e RH |
6506 | [(unspec_volatile |
6507 | [(match_operand 0 "arith_operand" "rI")] | |
6508 | UNSPECV_SAVEW)] | |
b11b0904 | 6509 | "!TARGET_FLAT" |
9ac617d4 EB |
6510 | "save\t%%sp, %0, %%sp" |
6511 | [(set_attr "type" "savew")]) | |
6512 | ||
6513 | (define_expand "epilogue" | |
6514 | [(return)] | |
6515 | "" | |
6516 | { | |
b11b0904 EB |
6517 | if (TARGET_FLAT) |
6518 | sparc_flat_expand_epilogue (false); | |
6519 | else | |
6520 | sparc_expand_epilogue (false); | |
9ac617d4 EB |
6521 | }) |
6522 | ||
f8ece000 EB |
6523 | (define_expand "sibcall_epilogue" |
6524 | [(return)] | |
6525 | "" | |
6526 | { | |
b11b0904 EB |
6527 | if (TARGET_FLAT) |
6528 | sparc_flat_expand_epilogue (false); | |
6529 | else | |
6530 | sparc_expand_epilogue (false); | |
6531 | DONE; | |
6532 | }) | |
6533 | ||
6534 | (define_expand "eh_return" | |
6535 | [(use (match_operand 0 "general_operand" ""))] | |
6536 | "" | |
6537 | { | |
6538 | emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]); | |
6539 | emit_jump_insn (gen_eh_return_internal ()); | |
6540 | emit_barrier (); | |
f8ece000 EB |
6541 | DONE; |
6542 | }) | |
6543 | ||
b11b0904 EB |
6544 | (define_insn_and_split "eh_return_internal" |
6545 | [(eh_return)] | |
6546 | "" | |
6547 | "#" | |
6548 | "epilogue_completed" | |
6549 | [(return)] | |
6550 | { | |
6551 | if (TARGET_FLAT) | |
6552 | sparc_flat_expand_epilogue (true); | |
6553 | else | |
6554 | sparc_expand_epilogue (true); | |
6555 | }) | |
6556 | ||
5be9b7a1 EB |
6557 | (define_expand "return" |
6558 | [(return)] | |
6559 | "sparc_can_use_return_insn_p ()" | |
6560 | "") | |
6561 | ||
9ac617d4 EB |
6562 | (define_insn "*return_internal" |
6563 | [(return)] | |
6564 | "" | |
6565 | "* return output_return (insn);" | |
6566 | [(set_attr "type" "return") | |
50711d27 | 6567 | (set (attr "length") |
b11b0904 EB |
6568 | (cond [(eq_attr "calls_eh_return" "true") |
6569 | (if_then_else (eq_attr "delayed_branch" "true") | |
6570 | (if_then_else (ior (eq_attr "isa" "v9") | |
6571 | (eq_attr "flat" "true")) | |
6572 | (const_int 2) | |
6573 | (const_int 3)) | |
6574 | (if_then_else (eq_attr "flat" "true") | |
6575 | (const_int 3) | |
6576 | (const_int 4))) | |
6577 | (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true")) | |
854f240e EB |
6578 | (if_then_else (eq_attr "empty_delay_slot" "true") |
6579 | (const_int 2) | |
6580 | (const_int 1)) | |
854f240e EB |
6581 | (eq_attr "empty_delay_slot" "true") |
6582 | (if_then_else (eq_attr "delayed_branch" "true") | |
6583 | (const_int 2) | |
6584 | (const_int 3)) | |
6585 | ] (const_int 1)))]) | |
7d167afd | 6586 | |
d18d5ca2 JW |
6587 | ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and |
6588 | ;; all of memory. This blocks insns from being moved across this point. | |
a8d2b752 | 6589 | |
d18d5ca2 | 6590 | (define_insn "blockage" |
4f4778ee | 6591 | [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] |
d18d5ca2 | 6592 | "" |
532eedf4 RH |
6593 | "" |
6594 | [(set_attr "length" "0")]) | |
a8d2b752 | 6595 | |
e98b1def EB |
6596 | ;; Do not schedule instructions accessing memory before this point. |
6597 | ||
6598 | (define_expand "frame_blockage" | |
6599 | [(set (match_dup 0) | |
6600 | (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))] | |
6601 | "" | |
6602 | { | |
6603 | operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); | |
6604 | MEM_VOLATILE_P (operands[0]) = 1; | |
6605 | operands[1] = stack_pointer_rtx; | |
6606 | }) | |
6607 | ||
6608 | (define_insn "*frame_blockage<P:mode>" | |
6609 | [(set (match_operand:BLK 0 "" "") | |
6610 | (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))] | |
6611 | "" | |
6612 | "" | |
6613 | [(set_attr "length" "0")]) | |
6614 | ||
949fa04c EB |
6615 | (define_expand "probe_stack" |
6616 | [(set (match_operand 0 "memory_operand" "") (const_int 0))] | |
6617 | "" | |
6618 | { | |
6619 | operands[0] | |
6620 | = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS); | |
6621 | }) | |
6622 | ||
260c8ba3 EB |
6623 | (define_insn "probe_stack_range<P:mode>" |
6624 | [(set (match_operand:P 0 "register_operand" "=r") | |
6625 | (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") | |
6626 | (match_operand:P 2 "register_operand" "r")] | |
6627 | UNSPECV_PROBE_STACK_RANGE))] | |
6628 | "" | |
6629 | "* return output_probe_stack_range (operands[0], operands[2]);" | |
6630 | [(set_attr "type" "multi")]) | |
6631 | ||
576182a3 TW |
6632 | ;; Prepare to return any type including a structure value. |
6633 | ||
6634 | (define_expand "untyped_return" | |
6635 | [(match_operand:BLK 0 "memory_operand" "") | |
6636 | (match_operand 1 "" "")] | |
6637 | "" | |
576182a3 | 6638 | { |
254110c2 DM |
6639 | rtx valreg1 = gen_rtx_REG (DImode, 24); |
6640 | rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32); | |
576182a3 | 6641 | rtx result = operands[0]; |
576182a3 | 6642 | |
fa0f39e4 | 6643 | if (! TARGET_ARCH64) |
a8d2b752 | 6644 | { |
b11b0904 | 6645 | rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM); |
a8d2b752 DE |
6646 | rtx value = gen_reg_rtx (SImode); |
6647 | ||
6648 | /* Fetch the instruction where we will return to and see if it's an unimp | |
6649 | instruction (the most significant 10 bits will be zero). If so, | |
6650 | update the return address to skip the unimp instruction. */ | |
6651 | emit_move_insn (value, | |
0a81f074 | 6652 | gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8))); |
a8d2b752 DE |
6653 | emit_insn (gen_lshrsi3 (value, value, GEN_INT (22))); |
6654 | emit_insn (gen_update_return (rtnreg, value)); | |
6655 | } | |
576182a3 TW |
6656 | |
6657 | /* Reload the function value registers. */ | |
f4ef873c | 6658 | emit_move_insn (valreg1, adjust_address (result, DImode, 0)); |
576182a3 | 6659 | emit_move_insn (valreg2, |
f4ef873c | 6660 | adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8)); |
576182a3 TW |
6661 | |
6662 | /* Put USE insns before the return. */ | |
c41c1387 RS |
6663 | emit_use (valreg1); |
6664 | emit_use (valreg2); | |
576182a3 TW |
6665 | |
6666 | /* Construct the return. */ | |
6e3077c6 | 6667 | expand_naked_return (); |
576182a3 TW |
6668 | |
6669 | DONE; | |
563facba | 6670 | }) |
576182a3 | 6671 | |
2225b57c CD |
6672 | ;; Adjust the return address conditionally. If the value of op1 is equal |
6673 | ;; to all zero then adjust the return address i.e. op0 = op0 + 4. | |
6674 | ;; This is technically *half* the check required by the 32-bit SPARC | |
6675 | ;; psABI. This check only ensures that an "unimp" insn was written by | |
6676 | ;; the caller, but doesn't check to see if the expected size matches | |
6677 | ;; (this is encoded in the 12 lower bits). This check is obsolete and | |
6678 | ;; only used by the above code "untyped_return". | |
576182a3 TW |
6679 | |
6680 | (define_insn "update_return" | |
6681 | [(unspec:SI [(match_operand:SI 0 "register_operand" "r") | |
4f4778ee | 6682 | (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)] |
fa0f39e4 | 6683 | "! TARGET_ARCH64" |
afdbd485 EB |
6684 | { |
6685 | if (flag_delayed_branch) | |
6686 | return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0"; | |
6687 | else | |
6688 | return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0"; | |
6689 | } | |
6690 | [(set (attr "type") (const_string "multi")) | |
6691 | (set (attr "length") | |
6692 | (if_then_else (eq_attr "delayed_branch" "true") | |
6693 | (const_int 3) | |
6694 | (const_int 4)))]) | |
7a768814 | 6695 | \f |
7a768814 RS |
6696 | (define_insn "nop" |
6697 | [(const_int 0)] | |
6698 | "" | |
24697ca0 | 6699 | "nop") |
7a768814 | 6700 | |
a8d2b752 DE |
6701 | (define_expand "indirect_jump" |
6702 | [(set (pc) (match_operand 0 "address_operand" "p"))] | |
7a768814 | 6703 | "" |
a8d2b752 DE |
6704 | "") |
6705 | ||
c8b3b7d6 | 6706 | (define_insn "*branch_sp32" |
a8d2b752 | 6707 | [(set (pc) (match_operand:SI 0 "address_operand" "p"))] |
7a2bf7af | 6708 | "! TARGET_ARCH64" |
16b46035 | 6709 | "jmp\t%a0%#" |
e8d6096c | 6710 | [(set_attr "type" "uncond_branch")]) |
7a768814 | 6711 | |
c8b3b7d6 | 6712 | (define_insn "*branch_sp64" |
a8d2b752 | 6713 | [(set (pc) (match_operand:DI 0 "address_operand" "p"))] |
7a2bf7af | 6714 | "TARGET_ARCH64" |
16b46035 | 6715 | "jmp\t%a0%#" |
a8d2b752 DE |
6716 | [(set_attr "type" "uncond_branch")]) |
6717 | ||
bc6d3f91 EB |
6718 | (define_expand "save_stack_nonlocal" |
6719 | [(set (match_operand 0 "memory_operand" "") | |
6720 | (match_operand 1 "register_operand" "")) | |
6721 | (set (match_dup 2) (match_dup 3))] | |
6722 | "" | |
6723 | { | |
6724 | operands[0] = adjust_address_nv (operands[0], Pmode, 0); | |
6725 | operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode)); | |
b11b0904 | 6726 | operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); |
bc6d3f91 EB |
6727 | }) |
6728 | ||
6729 | (define_expand "restore_stack_nonlocal" | |
6730 | [(set (match_operand 0 "register_operand" "") | |
6731 | (match_operand 1 "memory_operand" ""))] | |
6732 | "" | |
6733 | { | |
6734 | operands[1] = adjust_address_nv (operands[1], Pmode, 0); | |
6735 | }) | |
6736 | ||
7a768814 | 6737 | (define_expand "nonlocal_goto" |
bc6d3f91 EB |
6738 | [(match_operand 0 "general_operand" "") |
6739 | (match_operand 1 "general_operand" "") | |
6740 | (match_operand 2 "memory_operand" "") | |
6741 | (match_operand 3 "memory_operand" "")] | |
7a768814 | 6742 | "" |
7a768814 | 6743 | { |
8c92f3e8 | 6744 | rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); |
bc6d3f91 EB |
6745 | rtx r_label = copy_to_reg (operands[1]); |
6746 | rtx r_sp = adjust_address_nv (operands[2], Pmode, 0); | |
6747 | rtx r_fp = operands[3]; | |
6748 | rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode)); | |
6fd1c67b | 6749 | |
bc6d3f91 EB |
6750 | /* We need to flush all the register windows so that their contents will |
6751 | be re-synchronized by the restore insn of the target function. */ | |
b11b0904 EB |
6752 | if (!TARGET_FLAT) |
6753 | emit_insn (gen_flush_register_windows ()); | |
6fd1c67b | 6754 | |
bc6d3f91 EB |
6755 | emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); |
6756 | emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); | |
6fd1c67b | 6757 | |
bc6d3f91 EB |
6758 | /* Restore frame pointer for containing function. */ |
6759 | emit_move_insn (hard_frame_pointer_rtx, r_fp); | |
6760 | emit_stack_restore (SAVE_NONLOCAL, r_sp); | |
8c92f3e8 | 6761 | emit_move_insn (i7, r_i7); |
6fd1c67b | 6762 | |
bc6d3f91 EB |
6763 | /* USE of hard_frame_pointer_rtx added for consistency; |
6764 | not clear if really needed. */ | |
6765 | emit_use (hard_frame_pointer_rtx); | |
c41c1387 | 6766 | emit_use (stack_pointer_rtx); |
8c92f3e8 | 6767 | emit_use (i7); |
6109c659 | 6768 | |
8c92f3e8 | 6769 | emit_jump_insn (gen_indirect_jump (r_label)); |
bf1b20da | 6770 | emit_barrier (); |
7a768814 | 6771 | DONE; |
563facba | 6772 | }) |
7a768814 | 6773 | |
bc6d3f91 EB |
6774 | (define_expand "builtin_setjmp_receiver" |
6775 | [(label_ref (match_operand 0 "" ""))] | |
6776 | "flag_pic" | |
f36d6244 | 6777 | { |
bc6d3f91 | 6778 | load_got_register (); |
f36d6244 | 6779 | DONE; |
563facba | 6780 | }) |
f36d6244 | 6781 | |
bc6d3f91 | 6782 | ;; Special insn to flush register windows. |
bf1b20da | 6783 | |
bc6d3f91 EB |
6784 | (define_insn "flush_register_windows" |
6785 | [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)] | |
bf1b20da | 6786 | "" |
bc6d3f91 EB |
6787 | { return TARGET_V9 ? "flushw" : "ta\t3"; } |
6788 | [(set_attr "type" "flushw")]) | |
bf1b20da | 6789 | |
94698f4d RS |
6790 | ;; Special pattern for the FLUSH instruction. |
6791 | ||
fde66fde EB |
6792 | (define_insn "flush<P:mode>" |
6793 | [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)] | |
94698f4d | 6794 | "" |
16b46035 | 6795 | { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; } |
c6172f14 | 6796 | [(set_attr "type" "iflush")]) |
c219ddf7 | 6797 | |
fde66fde EB |
6798 | ;; Special insns to load and store the 32-bit FP Status Register. |
6799 | ||
6800 | (define_insn "ldfsr" | |
6801 | [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)] | |
6802 | "TARGET_FPU" | |
6803 | "ld\t%0, %%fsr" | |
6804 | [(set_attr "type" "load")]) | |
6805 | ||
6806 | (define_insn "stfsr" | |
6807 | [(set (match_operand:SI 0 "memory_operand" "=m") | |
6808 | (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))] | |
6809 | "TARGET_FPU" | |
6810 | "st\t%%fsr, %0" | |
6811 | [(set_attr "type" "store")]) | |
c219ddf7 | 6812 | |
f8ece000 EB |
6813 | |
6814 | ;; Find first set instructions. | |
114b9aa4 JW |
6815 | |
6816 | ;; The scan instruction searches from the most significant bit while ffs | |
6817 | ;; searches from the least significant bit. The bit index and treatment of | |
6818 | ;; zero also differ. It takes at least 7 instructions to get the proper | |
ddd5a7c1 | 6819 | ;; result. Here is an obvious 8 instruction sequence. |
114b9aa4 | 6820 | |
e0d80184 | 6821 | ;; XXX |
114b9aa4 JW |
6822 | (define_insn "ffssi2" |
6823 | [(set (match_operand:SI 0 "register_operand" "=&r") | |
6824 | (ffs:SI (match_operand:SI 1 "register_operand" "r"))) | |
6825 | (clobber (match_scratch:SI 2 "=&r"))] | |
967ba98d | 6826 | "TARGET_SPARCLITE || TARGET_SPARCLET" |
c4ce6853 | 6827 | { |
16b46035 | 6828 | return "sub\t%%g0, %1, %0\;and\t%0, %1, %0\;scan\t%0, 0, %0\;mov\t32, %2\;sub\t%2, %0, %0\;sra\t%0, 31, %2\;and\t%2, 31, %2\;add\t%2, %0, %0"; |
563facba | 6829 | } |
114b9aa4 JW |
6830 | [(set_attr "type" "multi") |
6831 | (set_attr "length" "8")]) | |
a8d2b752 | 6832 | |
908e19d0 DM |
6833 | (define_expand "popcountdi2" |
6834 | [(set (match_operand:DI 0 "register_operand" "") | |
6835 | (popcount:DI (match_operand:DI 1 "register_operand" "")))] | |
dc78280f DM |
6836 | "TARGET_POPC" |
6837 | { | |
6838 | if (! TARGET_ARCH64) | |
6839 | { | |
908e19d0 | 6840 | emit_insn (gen_popcountdi_v8plus (operands[0], operands[1])); |
dc78280f DM |
6841 | DONE; |
6842 | } | |
6843 | }) | |
6844 | ||
908e19d0 DM |
6845 | (define_insn "*popcountdi_sp64" |
6846 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6847 | (popcount:DI (match_operand:DI 1 "register_operand" "r")))] | |
dc78280f DM |
6848 | "TARGET_POPC && TARGET_ARCH64" |
6849 | "popc\t%1, %0") | |
6850 | ||
dc78280f DM |
6851 | (define_insn "popcountdi_v8plus" |
6852 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6853 | (popcount:DI (match_operand:DI 1 "register_operand" "r"))) | |
6854 | (clobber (match_scratch:SI 2 "=&h"))] | |
6855 | "TARGET_POPC && ! TARGET_ARCH64" | |
6856 | { | |
6857 | if (sparc_check_64 (operands[1], insn) <= 0) | |
6858 | output_asm_insn ("srl\t%L1, 0, %L1", operands); | |
6859 | return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0"; | |
6860 | } | |
6861 | [(set_attr "type" "multi") | |
6862 | (set_attr "length" "5")]) | |
6863 | ||
908e19d0 DM |
6864 | (define_expand "popcountsi2" |
6865 | [(set (match_dup 2) | |
6866 | (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) | |
6867 | (set (match_operand:SI 0 "register_operand" "") | |
6868 | (truncate:SI (popcount:DI (match_dup 2))))] | |
6869 | "TARGET_POPC" | |
6870 | { | |
6871 | if (! TARGET_ARCH64) | |
6872 | { | |
6873 | emit_insn (gen_popcountsi_v8plus (operands[0], operands[1])); | |
6874 | DONE; | |
6875 | } | |
6876 | else | |
6877 | operands[2] = gen_reg_rtx (DImode); | |
6878 | }) | |
6879 | ||
6880 | (define_insn "*popcountsi_sp64" | |
6881 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6882 | (truncate:SI | |
6883 | (popcount:DI (match_operand:DI 1 "register_operand" "r"))))] | |
6884 | "TARGET_POPC && TARGET_ARCH64" | |
6885 | "popc\t%1, %0") | |
6886 | ||
6887 | (define_insn "popcountsi_v8plus" | |
6888 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6889 | (popcount:SI (match_operand:SI 1 "register_operand" "r")))] | |
6890 | "TARGET_POPC && ! TARGET_ARCH64" | |
6891 | { | |
6892 | if (sparc_check_64 (operands[1], insn) <= 0) | |
6893 | output_asm_insn ("srl\t%1, 0, %1", operands); | |
6894 | return "popc\t%1, %0"; | |
6895 | } | |
6896 | [(set_attr "type" "multi") | |
6897 | (set_attr "length" "2")]) | |
6898 | ||
6899 | (define_expand "clzdi2" | |
6900 | [(set (match_operand:DI 0 "register_operand" "") | |
6901 | (clz:DI (match_operand:DI 1 "register_operand" "")))] | |
dc78280f DM |
6902 | "TARGET_VIS3" |
6903 | { | |
6904 | if (! TARGET_ARCH64) | |
6905 | { | |
908e19d0 | 6906 | emit_insn (gen_clzdi_v8plus (operands[0], operands[1])); |
dc78280f DM |
6907 | DONE; |
6908 | } | |
6909 | }) | |
6910 | ||
6911 | (define_insn "*clzdi_sp64" | |
6912 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6913 | (clz:DI (match_operand:DI 1 "register_operand" "r")))] | |
6914 | "TARGET_VIS3 && TARGET_ARCH64" | |
6915 | "lzd\t%1, %0") | |
6916 | ||
6917 | (define_insn "clzdi_v8plus" | |
6918 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6919 | (clz:DI (match_operand:DI 1 "register_operand" "r"))) | |
6920 | (clobber (match_scratch:SI 2 "=&h"))] | |
6921 | "TARGET_VIS3 && ! TARGET_ARCH64" | |
6922 | { | |
6923 | if (sparc_check_64 (operands[1], insn) <= 0) | |
6924 | output_asm_insn ("srl\t%L1, 0, %L1", operands); | |
6925 | return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0"; | |
6926 | } | |
6927 | [(set_attr "type" "multi") | |
6928 | (set_attr "length" "5")]) | |
6929 | ||
908e19d0 DM |
6930 | (define_expand "clzsi2" |
6931 | [(set (match_dup 2) | |
6932 | (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) | |
6933 | (set (match_dup 3) | |
6934 | (truncate:SI (clz:DI (match_dup 2)))) | |
6935 | (set (match_operand:SI 0 "register_operand" "") | |
6936 | (minus:SI (match_dup 3) (const_int 32)))] | |
6937 | "TARGET_VIS3" | |
6938 | { | |
6939 | if (! TARGET_ARCH64) | |
6940 | { | |
6941 | emit_insn (gen_clzsi_v8plus (operands[0], operands[1])); | |
6942 | DONE; | |
6943 | } | |
6944 | else | |
6945 | { | |
6946 | operands[2] = gen_reg_rtx (DImode); | |
6947 | operands[3] = gen_reg_rtx (SImode); | |
6948 | } | |
6949 | }) | |
6950 | ||
dc78280f DM |
6951 | (define_insn "*clzsi_sp64" |
6952 | [(set (match_operand:SI 0 "register_operand" "=r") | |
908e19d0 DM |
6953 | (truncate:SI |
6954 | (clz:DI (match_operand:DI 1 "register_operand" "r"))))] | |
dc78280f | 6955 | "TARGET_VIS3 && TARGET_ARCH64" |
908e19d0 | 6956 | "lzd\t%1, %0") |
7a768814 | 6957 | |
dc78280f DM |
6958 | (define_insn "clzsi_v8plus" |
6959 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6960 | (clz:SI (match_operand:SI 1 "register_operand" "r")))] | |
6961 | "TARGET_VIS3 && ! TARGET_ARCH64" | |
6962 | { | |
6963 | if (sparc_check_64 (operands[1], insn) <= 0) | |
6964 | output_asm_insn ("srl\t%1, 0, %1", operands); | |
6965 | return "lzd\t%1, %0\n\tsub\t%0, 32, %0"; | |
6966 | } | |
6967 | [(set_attr "type" "multi") | |
6968 | (set_attr "length" "3")]) | |
c5c76735 | 6969 | |
7a768814 RS |
6970 | \f |
6971 | ;; Peepholes go at the end. | |
6972 | ||
35016322 JW |
6973 | ;; Optimize consecutive loads or stores into ldd and std when possible. |
6974 | ;; The conditions in which we do this are very restricted and are | |
6975 | ;; explained in the code for {registers,memory}_ok_for_ldd functions. | |
6976 | ||
2aad5d68 | 6977 | (define_peephole2 |
bfd6bc60 JC |
6978 | [(set (match_operand:SI 0 "memory_operand" "") |
6979 | (const_int 0)) | |
6980 | (set (match_operand:SI 1 "memory_operand" "") | |
6981 | (const_int 0))] | |
6982 | "TARGET_V9 | |
303f8933 | 6983 | && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)" |
b5ccb9ed EB |
6984 | [(set (match_dup 0) (const_int 0))] |
6985 | { | |
6986 | operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode); | |
6987 | }) | |
bfd6bc60 | 6988 | |
2aad5d68 | 6989 | (define_peephole2 |
bfd6bc60 JC |
6990 | [(set (match_operand:SI 0 "memory_operand" "") |
6991 | (const_int 0)) | |
6992 | (set (match_operand:SI 1 "memory_operand" "") | |
6993 | (const_int 0))] | |
6994 | "TARGET_V9 | |
303f8933 | 6995 | && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)" |
b5ccb9ed EB |
6996 | [(set (match_dup 1) (const_int 0))] |
6997 | { | |
6998 | operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode); | |
6999 | }) | |
bfd6bc60 | 7000 | |
2aad5d68 DN |
7001 | (define_peephole2 |
7002 | [(set (match_operand:SI 0 "register_operand" "") | |
35016322 | 7003 | (match_operand:SI 1 "memory_operand" "")) |
2aad5d68 | 7004 | (set (match_operand:SI 2 "register_operand" "") |
35016322 | 7005 | (match_operand:SI 3 "memory_operand" ""))] |
e0d80184 | 7006 | "registers_ok_for_ldd_peep (operands[0], operands[2]) |
303f8933 | 7007 | && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" |
b5ccb9ed EB |
7008 | [(set (match_dup 0) (match_dup 1))] |
7009 | { | |
7010 | operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode); | |
7011 | operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); | |
7012 | }) | |
35016322 | 7013 | |
2aad5d68 | 7014 | (define_peephole2 |
35016322 | 7015 | [(set (match_operand:SI 0 "memory_operand" "") |
2aad5d68 | 7016 | (match_operand:SI 1 "register_operand" "")) |
35016322 | 7017 | (set (match_operand:SI 2 "memory_operand" "") |
2aad5d68 | 7018 | (match_operand:SI 3 "register_operand" ""))] |
e0d80184 | 7019 | "registers_ok_for_ldd_peep (operands[1], operands[3]) |
303f8933 | 7020 | && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)" |
b5ccb9ed EB |
7021 | [(set (match_dup 0) (match_dup 1))] |
7022 | { | |
7023 | operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode); | |
7024 | operands[1] = gen_rtx_REG (DImode, REGNO (operands[1])); | |
7025 | }) | |
2aad5d68 DN |
7026 | |
7027 | (define_peephole2 | |
7028 | [(set (match_operand:SF 0 "register_operand" "") | |
35016322 | 7029 | (match_operand:SF 1 "memory_operand" "")) |
2aad5d68 | 7030 | (set (match_operand:SF 2 "register_operand" "") |
35016322 | 7031 | (match_operand:SF 3 "memory_operand" ""))] |
e0d80184 | 7032 | "registers_ok_for_ldd_peep (operands[0], operands[2]) |
303f8933 | 7033 | && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" |
b5ccb9ed EB |
7034 | [(set (match_dup 0) (match_dup 1))] |
7035 | { | |
7036 | operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode); | |
7037 | operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0])); | |
7038 | }) | |
35016322 | 7039 | |
2aad5d68 | 7040 | (define_peephole2 |
35016322 | 7041 | [(set (match_operand:SF 0 "memory_operand" "") |
2aad5d68 | 7042 | (match_operand:SF 1 "register_operand" "")) |
35016322 | 7043 | (set (match_operand:SF 2 "memory_operand" "") |
2aad5d68 | 7044 | (match_operand:SF 3 "register_operand" ""))] |
e0d80184 | 7045 | "registers_ok_for_ldd_peep (operands[1], operands[3]) |
303f8933 | 7046 | && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)" |
b5ccb9ed EB |
7047 | [(set (match_dup 0) (match_dup 1))] |
7048 | { | |
7049 | operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode); | |
7050 | operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1])); | |
7051 | }) | |
35016322 | 7052 | |
2aad5d68 DN |
7053 | (define_peephole2 |
7054 | [(set (match_operand:SI 0 "register_operand" "") | |
35016322 | 7055 | (match_operand:SI 1 "memory_operand" "")) |
2aad5d68 | 7056 | (set (match_operand:SI 2 "register_operand" "") |
35016322 | 7057 | (match_operand:SI 3 "memory_operand" ""))] |
e0d80184 | 7058 | "registers_ok_for_ldd_peep (operands[2], operands[0]) |
0acf409f | 7059 | && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])" |
b5ccb9ed EB |
7060 | [(set (match_dup 2) (match_dup 3))] |
7061 | { | |
7062 | operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode); | |
7063 | operands[2] = gen_rtx_REG (DImode, REGNO (operands[2])); | |
7064 | }) | |
35016322 | 7065 | |
2aad5d68 | 7066 | (define_peephole2 |
35016322 | 7067 | [(set (match_operand:SI 0 "memory_operand" "") |
2aad5d68 | 7068 | (match_operand:SI 1 "register_operand" "")) |
35016322 | 7069 | (set (match_operand:SI 2 "memory_operand" "") |
2aad5d68 | 7070 | (match_operand:SI 3 "register_operand" ""))] |
e0d80184 | 7071 | "registers_ok_for_ldd_peep (operands[3], operands[1]) |
303f8933 | 7072 | && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" |
b5ccb9ed EB |
7073 | [(set (match_dup 2) (match_dup 3))] |
7074 | { | |
7075 | operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DImode); | |
7076 | operands[3] = gen_rtx_REG (DImode, REGNO (operands[3])); | |
7077 | }) | |
35016322 | 7078 | |
2aad5d68 DN |
7079 | (define_peephole2 |
7080 | [(set (match_operand:SF 0 "register_operand" "") | |
35016322 | 7081 | (match_operand:SF 1 "memory_operand" "")) |
2aad5d68 | 7082 | (set (match_operand:SF 2 "register_operand" "") |
35016322 | 7083 | (match_operand:SF 3 "memory_operand" ""))] |
e0d80184 | 7084 | "registers_ok_for_ldd_peep (operands[2], operands[0]) |
0acf409f | 7085 | && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])" |
b5ccb9ed EB |
7086 | [(set (match_dup 2) (match_dup 3))] |
7087 | { | |
7088 | operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode); | |
7089 | operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2])); | |
7090 | }) | |
35016322 | 7091 | |
2aad5d68 | 7092 | (define_peephole2 |
35016322 | 7093 | [(set (match_operand:SF 0 "memory_operand" "") |
2aad5d68 | 7094 | (match_operand:SF 1 "register_operand" "")) |
35016322 | 7095 | (set (match_operand:SF 2 "memory_operand" "") |
2aad5d68 | 7096 | (match_operand:SF 3 "register_operand" ""))] |
e0d80184 | 7097 | "registers_ok_for_ldd_peep (operands[3], operands[1]) |
303f8933 | 7098 | && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" |
b5ccb9ed EB |
7099 | [(set (match_dup 2) (match_dup 3))] |
7100 | { | |
7101 | operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode); | |
7102 | operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3])); | |
7103 | }) | |
35016322 | 7104 | |
7a768814 | 7105 | ;; Optimize the case of following a reg-reg move with a test |
1a1ba90e | 7106 | ;; of reg just moved. Don't allow floating point regs for operand 0 or 1. |
72f4648e | 7107 | ;; This can result from a float to fix conversion. |
7a768814 | 7108 | |
2aad5d68 DN |
7109 | (define_peephole2 |
7110 | [(set (match_operand:SI 0 "register_operand" "") | |
7111 | (match_operand:SI 1 "register_operand" "")) | |
45a7dd80 | 7112 | (set (reg:CC CC_REG) |
2aad5d68 | 7113 | (compare:CC (match_operand:SI 2 "register_operand" "") |
7a768814 | 7114 | (const_int 0)))] |
72f4648e JW |
7115 | "(rtx_equal_p (operands[2], operands[0]) |
7116 | || rtx_equal_p (operands[2], operands[1])) | |
2aad5d68 DN |
7117 | && ! SPARC_FP_REG_P (REGNO (operands[0])) |
7118 | && ! SPARC_FP_REG_P (REGNO (operands[1]))" | |
7119 | [(parallel [(set (match_dup 0) (match_dup 1)) | |
45a7dd80 | 7120 | (set (reg:CC CC_REG) |
2aad5d68 DN |
7121 | (compare:CC (match_dup 1) (const_int 0)))])] |
7122 | "") | |
7a768814 | 7123 | |
2aad5d68 DN |
7124 | (define_peephole2 |
7125 | [(set (match_operand:DI 0 "register_operand" "") | |
7126 | (match_operand:DI 1 "register_operand" "")) | |
45a7dd80 | 7127 | (set (reg:CCX CC_REG) |
2aad5d68 | 7128 | (compare:CCX (match_operand:DI 2 "register_operand" "") |
a8d2b752 | 7129 | (const_int 0)))] |
fa0f39e4 | 7130 | "TARGET_ARCH64 |
a8d2b752 DE |
7131 | && (rtx_equal_p (operands[2], operands[0]) |
7132 | || rtx_equal_p (operands[2], operands[1])) | |
2aad5d68 DN |
7133 | && ! SPARC_FP_REG_P (REGNO (operands[0])) |
7134 | && ! SPARC_FP_REG_P (REGNO (operands[1]))" | |
7135 | [(parallel [(set (match_dup 0) (match_dup 1)) | |
45a7dd80 | 7136 | (set (reg:CCX CC_REG) |
77e2c290 | 7137 | (compare:CCX (match_dup 1) (const_int 0)))])] |
2aad5d68 | 7138 | "") |
7a768814 | 7139 | |
f8ece000 EB |
7140 | |
7141 | ;; Prefetch instructions. | |
7142 | ||
1bbad4c6 DM |
7143 | ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register |
7144 | ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory | |
7145 | ;; ??? operations. With DFA we might be able to model this, but it requires a lot of | |
7146 | ;; ??? state. | |
7147 | (define_expand "prefetch" | |
7148 | [(match_operand 0 "address_operand" "") | |
7149 | (match_operand 1 "const_int_operand" "") | |
7150 | (match_operand 2 "const_int_operand" "")] | |
7151 | "TARGET_V9" | |
1bbad4c6 DM |
7152 | { |
7153 | if (TARGET_ARCH64) | |
7154 | emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2])); | |
7155 | else | |
7156 | emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2])); | |
7157 | DONE; | |
563facba | 7158 | }) |
1bbad4c6 DM |
7159 | |
7160 | (define_insn "prefetch_64" | |
f3bfd09c DN |
7161 | [(prefetch (match_operand:DI 0 "address_operand" "p") |
7162 | (match_operand:DI 1 "const_int_operand" "n") | |
7163 | (match_operand:DI 2 "const_int_operand" "n"))] | |
1bbad4c6 DM |
7164 | "" |
7165 | { | |
7166 | static const char * const prefetch_instr[2][2] = { | |
7167 | { | |
16b46035 DM |
7168 | "prefetch\t[%a0], 1", /* no locality: prefetch for one read */ |
7169 | "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */ | |
1bbad4c6 DM |
7170 | }, |
7171 | { | |
16b46035 DM |
7172 | "prefetch\t[%a0], 3", /* no locality: prefetch for one write */ |
7173 | "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */ | |
1bbad4c6 DM |
7174 | } |
7175 | }; | |
7176 | int read_or_write = INTVAL (operands[1]); | |
7177 | int locality = INTVAL (operands[2]); | |
7178 | ||
f5f7d171 JM |
7179 | gcc_assert (read_or_write == 0 || read_or_write == 1); |
7180 | gcc_assert (locality >= 0 && locality < 4); | |
1bbad4c6 DM |
7181 | return prefetch_instr [read_or_write][locality == 0 ? 0 : 1]; |
7182 | } | |
7183 | [(set_attr "type" "load")]) | |
7184 | ||
7185 | (define_insn "prefetch_32" | |
7186 | [(prefetch (match_operand:SI 0 "address_operand" "p") | |
7187 | (match_operand:SI 1 "const_int_operand" "n") | |
7188 | (match_operand:SI 2 "const_int_operand" "n"))] | |
7189 | "" | |
f3bfd09c | 7190 | { |
1bbad4c6 | 7191 | static const char * const prefetch_instr[2][2] = { |
f3bfd09c | 7192 | { |
16b46035 DM |
7193 | "prefetch\t[%a0], 1", /* no locality: prefetch for one read */ |
7194 | "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */ | |
f3bfd09c DN |
7195 | }, |
7196 | { | |
16b46035 DM |
7197 | "prefetch\t[%a0], 3", /* no locality: prefetch for one write */ |
7198 | "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */ | |
f3bfd09c DN |
7199 | } |
7200 | }; | |
7201 | int read_or_write = INTVAL (operands[1]); | |
7202 | int locality = INTVAL (operands[2]); | |
7203 | ||
f5f7d171 JM |
7204 | gcc_assert (read_or_write == 0 || read_or_write == 1); |
7205 | gcc_assert (locality >= 0 && locality < 4); | |
1bbad4c6 | 7206 | return prefetch_instr [read_or_write][locality == 0 ? 0 : 1]; |
f3bfd09c DN |
7207 | } |
7208 | [(set_attr "type" "load")]) | |
f8ece000 EB |
7209 | |
7210 | ||
7211 | ;; Trap instructions. | |
7212 | ||
e0cd0770 JC |
7213 | (define_insn "trap" |
7214 | [(trap_if (const_int 1) (const_int 5))] | |
7215 | "" | |
16b46035 | 7216 | "ta\t5" |
c6172f14 | 7217 | [(set_attr "type" "trap")]) |
e0cd0770 | 7218 | |
f90b7a5a PB |
7219 | (define_expand "ctrapsi4" |
7220 | [(trap_if (match_operator 0 "noov_compare_operator" | |
7221 | [(match_operand:SI 1 "compare_operand" "") | |
7222 | (match_operand:SI 2 "arith_operand" "")]) | |
b9aaf52e | 7223 | (match_operand 3 "arith_operand"))] |
e0cd0770 | 7224 | "" |
f90b7a5a PB |
7225 | "operands[1] = gen_compare_reg (operands[0]); |
7226 | if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode) | |
ba652ba9 | 7227 | FAIL; |
f90b7a5a PB |
7228 | operands[2] = const0_rtx;") |
7229 | ||
7230 | (define_expand "ctrapdi4" | |
7231 | [(trap_if (match_operator 0 "noov_compare_operator" | |
7232 | [(match_operand:DI 1 "compare_operand" "") | |
7233 | (match_operand:DI 2 "arith_operand" "")]) | |
b9aaf52e | 7234 | (match_operand 3 "arith_operand"))] |
f90b7a5a PB |
7235 | "TARGET_ARCH64" |
7236 | "operands[1] = gen_compare_reg (operands[0]); | |
7237 | if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode) | |
7238 | FAIL; | |
7239 | operands[2] = const0_rtx;") | |
7240 | ||
e0cd0770 JC |
7241 | |
7242 | (define_insn "" | |
45a7dd80 | 7243 | [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)]) |
e0cd0770 JC |
7244 | (match_operand:SI 1 "arith_operand" "rM"))] |
7245 | "" | |
ba652ba9 EB |
7246 | { |
7247 | if (TARGET_V9) | |
7248 | return "t%C0\t%%icc, %1"; | |
7249 | else | |
7250 | return "t%C0\t%1"; | |
7251 | } | |
c6172f14 | 7252 | [(set_attr "type" "trap")]) |
e0cd0770 JC |
7253 | |
7254 | (define_insn "" | |
45a7dd80 | 7255 | [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)]) |
e0cd0770 JC |
7256 | (match_operand:SI 1 "arith_operand" "rM"))] |
7257 | "TARGET_V9" | |
16b46035 | 7258 | "t%C0\t%%xcc, %1" |
c6172f14 | 7259 | [(set_attr "type" "trap")]) |
5751a10b | 7260 | |
f8ece000 EB |
7261 | |
7262 | ;; TLS support instructions. | |
7263 | ||
5751a10b JJ |
7264 | (define_insn "tgd_hi22" |
7265 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7266 | (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] | |
7267 | UNSPEC_TLSGD)))] | |
7268 | "TARGET_TLS" | |
7269 | "sethi\\t%%tgd_hi22(%a1), %0") | |
7270 | ||
7271 | (define_insn "tgd_lo10" | |
7272 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7273 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
7274 | (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")] | |
7275 | UNSPEC_TLSGD)))] | |
7276 | "TARGET_TLS" | |
7277 | "add\\t%1, %%tgd_lo10(%a2), %0") | |
7278 | ||
7279 | (define_insn "tgd_add32" | |
7280 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7281 | (plus:SI (match_operand:SI 1 "register_operand" "r") | |
7282 | (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7283 | (match_operand 3 "tgd_symbolic_operand" "")] | |
7284 | UNSPEC_TLSGD)))] | |
7285 | "TARGET_TLS && TARGET_ARCH32" | |
7286 | "add\\t%1, %2, %0, %%tgd_add(%a3)") | |
7287 | ||
7288 | (define_insn "tgd_add64" | |
7289 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7290 | (plus:DI (match_operand:DI 1 "register_operand" "r") | |
7291 | (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7292 | (match_operand 3 "tgd_symbolic_operand" "")] | |
7293 | UNSPEC_TLSGD)))] | |
7294 | "TARGET_TLS && TARGET_ARCH64" | |
7295 | "add\\t%1, %2, %0, %%tgd_add(%a3)") | |
7296 | ||
7297 | (define_insn "tgd_call32" | |
7298 | [(set (match_operand 0 "register_operand" "=r") | |
7299 | (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s") | |
7300 | (match_operand 2 "tgd_symbolic_operand" "")] | |
7301 | UNSPEC_TLSGD)) | |
7302 | (match_operand 3 "" ""))) | |
45a7dd80 | 7303 | (clobber (reg:SI O7_REG))] |
5751a10b JJ |
7304 | "TARGET_TLS && TARGET_ARCH32" |
7305 | "call\t%a1, %%tgd_call(%a2)%#" | |
7306 | [(set_attr "type" "call")]) | |
7307 | ||
7308 | (define_insn "tgd_call64" | |
7309 | [(set (match_operand 0 "register_operand" "=r") | |
7310 | (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s") | |
7311 | (match_operand 2 "tgd_symbolic_operand" "")] | |
7312 | UNSPEC_TLSGD)) | |
7313 | (match_operand 3 "" ""))) | |
45a7dd80 | 7314 | (clobber (reg:DI O7_REG))] |
5751a10b JJ |
7315 | "TARGET_TLS && TARGET_ARCH64" |
7316 | "call\t%a1, %%tgd_call(%a2)%#" | |
7317 | [(set_attr "type" "call")]) | |
7318 | ||
7319 | (define_insn "tldm_hi22" | |
7320 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7321 | (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))] | |
7322 | "TARGET_TLS" | |
7323 | "sethi\\t%%tldm_hi22(%&), %0") | |
7324 | ||
7325 | (define_insn "tldm_lo10" | |
7326 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7327 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
7328 | (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))] | |
7329 | "TARGET_TLS" | |
7330 | "add\\t%1, %%tldm_lo10(%&), %0") | |
7331 | ||
7332 | (define_insn "tldm_add32" | |
7333 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7334 | (plus:SI (match_operand:SI 1 "register_operand" "r") | |
7335 | (unspec:SI [(match_operand:SI 2 "register_operand" "r")] | |
7336 | UNSPEC_TLSLDM)))] | |
7337 | "TARGET_TLS && TARGET_ARCH32" | |
7338 | "add\\t%1, %2, %0, %%tldm_add(%&)") | |
7339 | ||
7340 | (define_insn "tldm_add64" | |
7341 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7342 | (plus:DI (match_operand:DI 1 "register_operand" "r") | |
7343 | (unspec:DI [(match_operand:SI 2 "register_operand" "r")] | |
7344 | UNSPEC_TLSLDM)))] | |
7345 | "TARGET_TLS && TARGET_ARCH64" | |
7346 | "add\\t%1, %2, %0, %%tldm_add(%&)") | |
7347 | ||
7348 | (define_insn "tldm_call32" | |
7349 | [(set (match_operand 0 "register_operand" "=r") | |
7350 | (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")] | |
7351 | UNSPEC_TLSLDM)) | |
7352 | (match_operand 2 "" ""))) | |
45a7dd80 | 7353 | (clobber (reg:SI O7_REG))] |
5751a10b JJ |
7354 | "TARGET_TLS && TARGET_ARCH32" |
7355 | "call\t%a1, %%tldm_call(%&)%#" | |
7356 | [(set_attr "type" "call")]) | |
7357 | ||
7358 | (define_insn "tldm_call64" | |
7359 | [(set (match_operand 0 "register_operand" "=r") | |
7360 | (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")] | |
7361 | UNSPEC_TLSLDM)) | |
7362 | (match_operand 2 "" ""))) | |
45a7dd80 | 7363 | (clobber (reg:DI O7_REG))] |
5751a10b JJ |
7364 | "TARGET_TLS && TARGET_ARCH64" |
7365 | "call\t%a1, %%tldm_call(%&)%#" | |
7366 | [(set_attr "type" "call")]) | |
7367 | ||
7368 | (define_insn "tldo_hix22" | |
7369 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7370 | (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] | |
7371 | UNSPEC_TLSLDO)))] | |
7372 | "TARGET_TLS" | |
7373 | "sethi\\t%%tldo_hix22(%a1), %0") | |
7374 | ||
7375 | (define_insn "tldo_lox10" | |
7376 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7377 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
7378 | (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")] | |
7379 | UNSPEC_TLSLDO)))] | |
7380 | "TARGET_TLS" | |
7381 | "xor\\t%1, %%tldo_lox10(%a2), %0") | |
7382 | ||
7383 | (define_insn "tldo_add32" | |
7384 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7385 | (plus:SI (match_operand:SI 1 "register_operand" "r") | |
7386 | (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7387 | (match_operand 3 "tld_symbolic_operand" "")] | |
7388 | UNSPEC_TLSLDO)))] | |
7389 | "TARGET_TLS && TARGET_ARCH32" | |
7390 | "add\\t%1, %2, %0, %%tldo_add(%a3)") | |
7391 | ||
7392 | (define_insn "tldo_add64" | |
7393 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7394 | (plus:DI (match_operand:DI 1 "register_operand" "r") | |
7395 | (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7396 | (match_operand 3 "tld_symbolic_operand" "")] | |
7397 | UNSPEC_TLSLDO)))] | |
7398 | "TARGET_TLS && TARGET_ARCH64" | |
7399 | "add\\t%1, %2, %0, %%tldo_add(%a3)") | |
7400 | ||
7401 | (define_insn "tie_hi22" | |
7402 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7403 | (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] | |
7404 | UNSPEC_TLSIE)))] | |
7405 | "TARGET_TLS" | |
7406 | "sethi\\t%%tie_hi22(%a1), %0") | |
7407 | ||
7408 | (define_insn "tie_lo10" | |
7409 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7410 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
7411 | (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")] | |
7412 | UNSPEC_TLSIE)))] | |
7413 | "TARGET_TLS" | |
7414 | "add\\t%1, %%tie_lo10(%a2), %0") | |
7415 | ||
7416 | (define_insn "tie_ld32" | |
7417 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7418 | (unspec:SI [(match_operand:SI 1 "register_operand" "r") | |
7419 | (match_operand:SI 2 "register_operand" "r") | |
7420 | (match_operand 3 "tie_symbolic_operand" "")] | |
7421 | UNSPEC_TLSIE))] | |
7422 | "TARGET_TLS && TARGET_ARCH32" | |
7423 | "ld\\t[%1 + %2], %0, %%tie_ld(%a3)" | |
7424 | [(set_attr "type" "load")]) | |
7425 | ||
7426 | (define_insn "tie_ld64" | |
7427 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7428 | (unspec:DI [(match_operand:DI 1 "register_operand" "r") | |
7429 | (match_operand:SI 2 "register_operand" "r") | |
7430 | (match_operand 3 "tie_symbolic_operand" "")] | |
7431 | UNSPEC_TLSIE))] | |
7432 | "TARGET_TLS && TARGET_ARCH64" | |
7433 | "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)" | |
7434 | [(set_attr "type" "load")]) | |
7435 | ||
7436 | (define_insn "tie_add32" | |
7437 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7438 | (plus:SI (match_operand:SI 1 "register_operand" "r") | |
7439 | (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
35d405cf | 7440 | (match_operand 3 "tie_symbolic_operand" "")] |
5751a10b JJ |
7441 | UNSPEC_TLSIE)))] |
7442 | "TARGET_SUN_TLS && TARGET_ARCH32" | |
7443 | "add\\t%1, %2, %0, %%tie_add(%a3)") | |
7444 | ||
7445 | (define_insn "tie_add64" | |
7446 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7447 | (plus:DI (match_operand:DI 1 "register_operand" "r") | |
7448 | (unspec:DI [(match_operand:DI 2 "register_operand" "r") | |
35d405cf | 7449 | (match_operand 3 "tie_symbolic_operand" "")] |
5751a10b JJ |
7450 | UNSPEC_TLSIE)))] |
7451 | "TARGET_SUN_TLS && TARGET_ARCH64" | |
7452 | "add\\t%1, %2, %0, %%tie_add(%a3)") | |
7453 | ||
7454 | (define_insn "tle_hix22_sp32" | |
7455 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7456 | (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")] | |
7457 | UNSPEC_TLSLE)))] | |
7458 | "TARGET_TLS && TARGET_ARCH32" | |
7459 | "sethi\\t%%tle_hix22(%a1), %0") | |
7460 | ||
7461 | (define_insn "tle_lox10_sp32" | |
7462 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7463 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
7464 | (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")] | |
7465 | UNSPEC_TLSLE)))] | |
7466 | "TARGET_TLS && TARGET_ARCH32" | |
7467 | "xor\\t%1, %%tle_lox10(%a2), %0") | |
7468 | ||
7469 | (define_insn "tle_hix22_sp64" | |
7470 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7471 | (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")] | |
7472 | UNSPEC_TLSLE)))] | |
7473 | "TARGET_TLS && TARGET_ARCH64" | |
7474 | "sethi\\t%%tle_hix22(%a1), %0") | |
7475 | ||
7476 | (define_insn "tle_lox10_sp64" | |
7477 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7478 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
7479 | (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")] | |
7480 | UNSPEC_TLSLE)))] | |
7481 | "TARGET_TLS && TARGET_ARCH64" | |
7482 | "xor\\t%1, %%tle_lox10(%a2), %0") | |
7483 | ||
839a4992 | 7484 | ;; Now patterns combining tldo_add{32,64} with some integer loads or stores |
5751a10b JJ |
7485 | (define_insn "*tldo_ldub_sp32" |
7486 | [(set (match_operand:QI 0 "register_operand" "=r") | |
7487 | (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7488 | (match_operand 3 "tld_symbolic_operand" "")] | |
7489 | UNSPEC_TLSLDO) | |
7490 | (match_operand:SI 1 "register_operand" "r"))))] | |
7491 | "TARGET_TLS && TARGET_ARCH32" | |
7492 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7493 | [(set_attr "type" "load") | |
7494 | (set_attr "us3load_type" "3cycle")]) | |
7495 | ||
7496 | (define_insn "*tldo_ldub1_sp32" | |
7497 | [(set (match_operand:HI 0 "register_operand" "=r") | |
7498 | (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7499 | (match_operand 3 "tld_symbolic_operand" "")] | |
7500 | UNSPEC_TLSLDO) | |
7501 | (match_operand:SI 1 "register_operand" "r")))))] | |
7502 | "TARGET_TLS && TARGET_ARCH32" | |
7503 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7504 | [(set_attr "type" "load") | |
7505 | (set_attr "us3load_type" "3cycle")]) | |
7506 | ||
7507 | (define_insn "*tldo_ldub2_sp32" | |
7508 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7509 | (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7510 | (match_operand 3 "tld_symbolic_operand" "")] | |
7511 | UNSPEC_TLSLDO) | |
7512 | (match_operand:SI 1 "register_operand" "r")))))] | |
7513 | "TARGET_TLS && TARGET_ARCH32" | |
7514 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7515 | [(set_attr "type" "load") | |
7516 | (set_attr "us3load_type" "3cycle")]) | |
7517 | ||
7518 | (define_insn "*tldo_ldsb1_sp32" | |
7519 | [(set (match_operand:HI 0 "register_operand" "=r") | |
7520 | (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7521 | (match_operand 3 "tld_symbolic_operand" "")] | |
7522 | UNSPEC_TLSLDO) | |
7523 | (match_operand:SI 1 "register_operand" "r")))))] | |
7524 | "TARGET_TLS && TARGET_ARCH32" | |
7525 | "ldsb\t[%1 + %2], %0, %%tldo_add(%3)" | |
7526 | [(set_attr "type" "sload") | |
7527 | (set_attr "us3load_type" "3cycle")]) | |
7528 | ||
7529 | (define_insn "*tldo_ldsb2_sp32" | |
7530 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7531 | (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7532 | (match_operand 3 "tld_symbolic_operand" "")] | |
7533 | UNSPEC_TLSLDO) | |
7534 | (match_operand:SI 1 "register_operand" "r")))))] | |
7535 | "TARGET_TLS && TARGET_ARCH32" | |
7536 | "ldsb\t[%1 + %2], %0, %%tldo_add(%3)" | |
7537 | [(set_attr "type" "sload") | |
7538 | (set_attr "us3load_type" "3cycle")]) | |
7539 | ||
7540 | (define_insn "*tldo_ldub_sp64" | |
7541 | [(set (match_operand:QI 0 "register_operand" "=r") | |
7542 | (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7543 | (match_operand 3 "tld_symbolic_operand" "")] | |
7544 | UNSPEC_TLSLDO) | |
7545 | (match_operand:DI 1 "register_operand" "r"))))] | |
7546 | "TARGET_TLS && TARGET_ARCH64" | |
7547 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7548 | [(set_attr "type" "load") | |
7549 | (set_attr "us3load_type" "3cycle")]) | |
7550 | ||
7551 | (define_insn "*tldo_ldub1_sp64" | |
7552 | [(set (match_operand:HI 0 "register_operand" "=r") | |
7553 | (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7554 | (match_operand 3 "tld_symbolic_operand" "")] | |
7555 | UNSPEC_TLSLDO) | |
7556 | (match_operand:DI 1 "register_operand" "r")))))] | |
7557 | "TARGET_TLS && TARGET_ARCH64" | |
7558 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7559 | [(set_attr "type" "load") | |
7560 | (set_attr "us3load_type" "3cycle")]) | |
7561 | ||
7562 | (define_insn "*tldo_ldub2_sp64" | |
7563 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7564 | (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7565 | (match_operand 3 "tld_symbolic_operand" "")] | |
7566 | UNSPEC_TLSLDO) | |
7567 | (match_operand:DI 1 "register_operand" "r")))))] | |
7568 | "TARGET_TLS && TARGET_ARCH64" | |
7569 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7570 | [(set_attr "type" "load") | |
7571 | (set_attr "us3load_type" "3cycle")]) | |
7572 | ||
7573 | (define_insn "*tldo_ldub3_sp64" | |
7574 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7575 | (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7576 | (match_operand 3 "tld_symbolic_operand" "")] | |
7577 | UNSPEC_TLSLDO) | |
7578 | (match_operand:DI 1 "register_operand" "r")))))] | |
7579 | "TARGET_TLS && TARGET_ARCH64" | |
7580 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7581 | [(set_attr "type" "load") | |
7582 | (set_attr "us3load_type" "3cycle")]) | |
7583 | ||
7584 | (define_insn "*tldo_ldsb1_sp64" | |
7585 | [(set (match_operand:HI 0 "register_operand" "=r") | |
7586 | (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7587 | (match_operand 3 "tld_symbolic_operand" "")] | |
7588 | UNSPEC_TLSLDO) | |
7589 | (match_operand:DI 1 "register_operand" "r")))))] | |
7590 | "TARGET_TLS && TARGET_ARCH64" | |
7591 | "ldsb\t[%1 + %2], %0, %%tldo_add(%3)" | |
7592 | [(set_attr "type" "sload") | |
7593 | (set_attr "us3load_type" "3cycle")]) | |
7594 | ||
7595 | (define_insn "*tldo_ldsb2_sp64" | |
7596 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7597 | (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7598 | (match_operand 3 "tld_symbolic_operand" "")] | |
7599 | UNSPEC_TLSLDO) | |
7600 | (match_operand:DI 1 "register_operand" "r")))))] | |
7601 | "TARGET_TLS && TARGET_ARCH64" | |
7602 | "ldsb\t[%1 + %2], %0, %%tldo_add(%3)" | |
7603 | [(set_attr "type" "sload") | |
7604 | (set_attr "us3load_type" "3cycle")]) | |
7605 | ||
7606 | (define_insn "*tldo_ldsb3_sp64" | |
7607 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7608 | (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7609 | (match_operand 3 "tld_symbolic_operand" "")] | |
7610 | UNSPEC_TLSLDO) | |
7611 | (match_operand:DI 1 "register_operand" "r")))))] | |
7612 | "TARGET_TLS && TARGET_ARCH64" | |
7613 | "ldsb\t[%1 + %2], %0, %%tldo_add(%3)" | |
7614 | [(set_attr "type" "sload") | |
7615 | (set_attr "us3load_type" "3cycle")]) | |
7616 | ||
7617 | (define_insn "*tldo_lduh_sp32" | |
7618 | [(set (match_operand:HI 0 "register_operand" "=r") | |
7619 | (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7620 | (match_operand 3 "tld_symbolic_operand" "")] | |
7621 | UNSPEC_TLSLDO) | |
7622 | (match_operand:SI 1 "register_operand" "r"))))] | |
7623 | "TARGET_TLS && TARGET_ARCH32" | |
7624 | "lduh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7625 | [(set_attr "type" "load") | |
7626 | (set_attr "us3load_type" "3cycle")]) | |
7627 | ||
7628 | (define_insn "*tldo_lduh1_sp32" | |
7629 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7630 | (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7631 | (match_operand 3 "tld_symbolic_operand" "")] | |
7632 | UNSPEC_TLSLDO) | |
7633 | (match_operand:SI 1 "register_operand" "r")))))] | |
7634 | "TARGET_TLS && TARGET_ARCH32" | |
7635 | "lduh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7636 | [(set_attr "type" "load") | |
7637 | (set_attr "us3load_type" "3cycle")]) | |
7638 | ||
7639 | (define_insn "*tldo_ldsh1_sp32" | |
7640 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7641 | (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7642 | (match_operand 3 "tld_symbolic_operand" "")] | |
7643 | UNSPEC_TLSLDO) | |
7644 | (match_operand:SI 1 "register_operand" "r")))))] | |
7645 | "TARGET_TLS && TARGET_ARCH32" | |
7646 | "ldsh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7647 | [(set_attr "type" "sload") | |
7648 | (set_attr "us3load_type" "3cycle")]) | |
7649 | ||
7650 | (define_insn "*tldo_lduh_sp64" | |
7651 | [(set (match_operand:HI 0 "register_operand" "=r") | |
7652 | (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7653 | (match_operand 3 "tld_symbolic_operand" "")] | |
7654 | UNSPEC_TLSLDO) | |
7655 | (match_operand:DI 1 "register_operand" "r"))))] | |
7656 | "TARGET_TLS && TARGET_ARCH64" | |
7657 | "lduh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7658 | [(set_attr "type" "load") | |
7659 | (set_attr "us3load_type" "3cycle")]) | |
7660 | ||
7661 | (define_insn "*tldo_lduh1_sp64" | |
7662 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7663 | (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7664 | (match_operand 3 "tld_symbolic_operand" "")] | |
7665 | UNSPEC_TLSLDO) | |
7666 | (match_operand:DI 1 "register_operand" "r")))))] | |
7667 | "TARGET_TLS && TARGET_ARCH64" | |
7668 | "lduh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7669 | [(set_attr "type" "load") | |
7670 | (set_attr "us3load_type" "3cycle")]) | |
7671 | ||
7672 | (define_insn "*tldo_lduh2_sp64" | |
7673 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7674 | (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7675 | (match_operand 3 "tld_symbolic_operand" "")] | |
7676 | UNSPEC_TLSLDO) | |
7677 | (match_operand:DI 1 "register_operand" "r")))))] | |
7678 | "TARGET_TLS && TARGET_ARCH64" | |
7679 | "lduh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7680 | [(set_attr "type" "load") | |
7681 | (set_attr "us3load_type" "3cycle")]) | |
7682 | ||
7683 | (define_insn "*tldo_ldsh1_sp64" | |
7684 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7685 | (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7686 | (match_operand 3 "tld_symbolic_operand" "")] | |
7687 | UNSPEC_TLSLDO) | |
7688 | (match_operand:DI 1 "register_operand" "r")))))] | |
7689 | "TARGET_TLS && TARGET_ARCH64" | |
7690 | "ldsh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7691 | [(set_attr "type" "sload") | |
7692 | (set_attr "us3load_type" "3cycle")]) | |
7693 | ||
7694 | (define_insn "*tldo_ldsh2_sp64" | |
7695 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7696 | (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7697 | (match_operand 3 "tld_symbolic_operand" "")] | |
7698 | UNSPEC_TLSLDO) | |
7699 | (match_operand:DI 1 "register_operand" "r")))))] | |
7700 | "TARGET_TLS && TARGET_ARCH64" | |
7701 | "ldsh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7702 | [(set_attr "type" "sload") | |
7703 | (set_attr "us3load_type" "3cycle")]) | |
7704 | ||
7705 | (define_insn "*tldo_lduw_sp32" | |
7706 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7707 | (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7708 | (match_operand 3 "tld_symbolic_operand" "")] | |
7709 | UNSPEC_TLSLDO) | |
7710 | (match_operand:SI 1 "register_operand" "r"))))] | |
7711 | "TARGET_TLS && TARGET_ARCH32" | |
7712 | "ld\t[%1 + %2], %0, %%tldo_add(%3)" | |
7713 | [(set_attr "type" "load")]) | |
7714 | ||
7715 | (define_insn "*tldo_lduw_sp64" | |
7716 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7717 | (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7718 | (match_operand 3 "tld_symbolic_operand" "")] | |
7719 | UNSPEC_TLSLDO) | |
7720 | (match_operand:DI 1 "register_operand" "r"))))] | |
7721 | "TARGET_TLS && TARGET_ARCH64" | |
7722 | "lduw\t[%1 + %2], %0, %%tldo_add(%3)" | |
7723 | [(set_attr "type" "load")]) | |
7724 | ||
7725 | (define_insn "*tldo_lduw1_sp64" | |
7726 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7727 | (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7728 | (match_operand 3 "tld_symbolic_operand" "")] | |
7729 | UNSPEC_TLSLDO) | |
7730 | (match_operand:DI 1 "register_operand" "r")))))] | |
7731 | "TARGET_TLS && TARGET_ARCH64" | |
7732 | "lduw\t[%1 + %2], %0, %%tldo_add(%3)" | |
7733 | [(set_attr "type" "load")]) | |
7734 | ||
7735 | (define_insn "*tldo_ldsw1_sp64" | |
7736 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7737 | (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7738 | (match_operand 3 "tld_symbolic_operand" "")] | |
7739 | UNSPEC_TLSLDO) | |
7740 | (match_operand:DI 1 "register_operand" "r")))))] | |
7741 | "TARGET_TLS && TARGET_ARCH64" | |
7742 | "ldsw\t[%1 + %2], %0, %%tldo_add(%3)" | |
7743 | [(set_attr "type" "sload") | |
7744 | (set_attr "us3load_type" "3cycle")]) | |
7745 | ||
7746 | (define_insn "*tldo_ldx_sp64" | |
7747 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7748 | (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7749 | (match_operand 3 "tld_symbolic_operand" "")] | |
7750 | UNSPEC_TLSLDO) | |
7751 | (match_operand:DI 1 "register_operand" "r"))))] | |
7752 | "TARGET_TLS && TARGET_ARCH64" | |
7753 | "ldx\t[%1 + %2], %0, %%tldo_add(%3)" | |
7754 | [(set_attr "type" "load")]) | |
7755 | ||
7756 | (define_insn "*tldo_stb_sp32" | |
7757 | [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7758 | (match_operand 3 "tld_symbolic_operand" "")] | |
7759 | UNSPEC_TLSLDO) | |
7760 | (match_operand:SI 1 "register_operand" "r"))) | |
e208b05b | 7761 | (match_operand:QI 0 "register_operand" "r"))] |
5751a10b JJ |
7762 | "TARGET_TLS && TARGET_ARCH32" |
7763 | "stb\t%0, [%1 + %2], %%tldo_add(%3)" | |
7764 | [(set_attr "type" "store")]) | |
7765 | ||
7766 | (define_insn "*tldo_stb_sp64" | |
7767 | [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7768 | (match_operand 3 "tld_symbolic_operand" "")] | |
7769 | UNSPEC_TLSLDO) | |
7770 | (match_operand:DI 1 "register_operand" "r"))) | |
e208b05b | 7771 | (match_operand:QI 0 "register_operand" "r"))] |
5751a10b JJ |
7772 | "TARGET_TLS && TARGET_ARCH64" |
7773 | "stb\t%0, [%1 + %2], %%tldo_add(%3)" | |
7774 | [(set_attr "type" "store")]) | |
7775 | ||
7776 | (define_insn "*tldo_sth_sp32" | |
7777 | [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7778 | (match_operand 3 "tld_symbolic_operand" "")] | |
7779 | UNSPEC_TLSLDO) | |
7780 | (match_operand:SI 1 "register_operand" "r"))) | |
e208b05b | 7781 | (match_operand:HI 0 "register_operand" "r"))] |
5751a10b JJ |
7782 | "TARGET_TLS && TARGET_ARCH32" |
7783 | "sth\t%0, [%1 + %2], %%tldo_add(%3)" | |
7784 | [(set_attr "type" "store")]) | |
7785 | ||
7786 | (define_insn "*tldo_sth_sp64" | |
7787 | [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7788 | (match_operand 3 "tld_symbolic_operand" "")] | |
7789 | UNSPEC_TLSLDO) | |
7790 | (match_operand:DI 1 "register_operand" "r"))) | |
e208b05b | 7791 | (match_operand:HI 0 "register_operand" "r"))] |
5751a10b JJ |
7792 | "TARGET_TLS && TARGET_ARCH64" |
7793 | "sth\t%0, [%1 + %2], %%tldo_add(%3)" | |
7794 | [(set_attr "type" "store")]) | |
7795 | ||
7796 | (define_insn "*tldo_stw_sp32" | |
7797 | [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7798 | (match_operand 3 "tld_symbolic_operand" "")] | |
7799 | UNSPEC_TLSLDO) | |
7800 | (match_operand:SI 1 "register_operand" "r"))) | |
e208b05b | 7801 | (match_operand:SI 0 "register_operand" "r"))] |
5751a10b JJ |
7802 | "TARGET_TLS && TARGET_ARCH32" |
7803 | "st\t%0, [%1 + %2], %%tldo_add(%3)" | |
7804 | [(set_attr "type" "store")]) | |
7805 | ||
7806 | (define_insn "*tldo_stw_sp64" | |
7807 | [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7808 | (match_operand 3 "tld_symbolic_operand" "")] | |
7809 | UNSPEC_TLSLDO) | |
7810 | (match_operand:DI 1 "register_operand" "r"))) | |
e208b05b | 7811 | (match_operand:SI 0 "register_operand" "r"))] |
5751a10b JJ |
7812 | "TARGET_TLS && TARGET_ARCH64" |
7813 | "stw\t%0, [%1 + %2], %%tldo_add(%3)" | |
7814 | [(set_attr "type" "store")]) | |
7815 | ||
7816 | (define_insn "*tldo_stx_sp64" | |
7817 | [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7818 | (match_operand 3 "tld_symbolic_operand" "")] | |
7819 | UNSPEC_TLSLDO) | |
7820 | (match_operand:DI 1 "register_operand" "r"))) | |
e208b05b | 7821 | (match_operand:DI 0 "register_operand" "r"))] |
5751a10b JJ |
7822 | "TARGET_TLS && TARGET_ARCH64" |
7823 | "stx\t%0, [%1 + %2], %%tldo_add(%3)" | |
7824 | [(set_attr "type" "store")]) | |
8393a290 | 7825 | |
f8ece000 | 7826 | |
8ec11fe9 JJ |
7827 | ;; Stack protector instructions. |
7828 | ||
7829 | (define_expand "stack_protect_set" | |
7830 | [(match_operand 0 "memory_operand" "") | |
7831 | (match_operand 1 "memory_operand" "")] | |
7832 | "" | |
7833 | { | |
7834 | #ifdef TARGET_THREAD_SSP_OFFSET | |
7835 | rtx tlsreg = gen_rtx_REG (Pmode, 7); | |
7836 | rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); | |
7837 | operands[1] = gen_rtx_MEM (Pmode, addr); | |
7838 | #endif | |
7839 | if (TARGET_ARCH64) | |
7840 | emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); | |
7841 | else | |
7842 | emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); | |
7843 | DONE; | |
7844 | }) | |
7845 | ||
7846 | (define_insn "stack_protect_setsi" | |
7847 | [(set (match_operand:SI 0 "memory_operand" "=m") | |
7848 | (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) | |
7849 | (set (match_scratch:SI 2 "=&r") (const_int 0))] | |
7850 | "TARGET_ARCH32" | |
7851 | "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2" | |
7852 | [(set_attr "type" "multi") | |
7853 | (set_attr "length" "3")]) | |
7854 | ||
7855 | (define_insn "stack_protect_setdi" | |
7856 | [(set (match_operand:DI 0 "memory_operand" "=m") | |
7857 | (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET)) | |
7858 | (set (match_scratch:DI 2 "=&r") (const_int 0))] | |
7859 | "TARGET_ARCH64" | |
7860 | "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2" | |
7861 | [(set_attr "type" "multi") | |
7862 | (set_attr "length" "3")]) | |
7863 | ||
7864 | (define_expand "stack_protect_test" | |
7865 | [(match_operand 0 "memory_operand" "") | |
7866 | (match_operand 1 "memory_operand" "") | |
7867 | (match_operand 2 "" "")] | |
7868 | "" | |
7869 | { | |
f90b7a5a | 7870 | rtx result, test; |
8ec11fe9 JJ |
7871 | #ifdef TARGET_THREAD_SSP_OFFSET |
7872 | rtx tlsreg = gen_rtx_REG (Pmode, 7); | |
7873 | rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); | |
7874 | operands[1] = gen_rtx_MEM (Pmode, addr); | |
7875 | #endif | |
7876 | if (TARGET_ARCH64) | |
7877 | { | |
f90b7a5a PB |
7878 | result = gen_reg_rtx (Pmode); |
7879 | emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1])); | |
7880 | test = gen_rtx_EQ (VOIDmode, result, const0_rtx); | |
7881 | emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2])); | |
8ec11fe9 JJ |
7882 | } |
7883 | else | |
7884 | { | |
7885 | emit_insn (gen_stack_protect_testsi (operands[0], operands[1])); | |
f90b7a5a PB |
7886 | result = gen_rtx_REG (CCmode, SPARC_ICC_REG); |
7887 | test = gen_rtx_EQ (VOIDmode, result, const0_rtx); | |
7888 | emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2])); | |
8ec11fe9 | 7889 | } |
8ec11fe9 JJ |
7890 | DONE; |
7891 | }) | |
7892 | ||
7893 | (define_insn "stack_protect_testsi" | |
45a7dd80 | 7894 | [(set (reg:CC CC_REG) |
8ec11fe9 JJ |
7895 | (unspec:CC [(match_operand:SI 0 "memory_operand" "m") |
7896 | (match_operand:SI 1 "memory_operand" "m")] | |
7897 | UNSPEC_SP_TEST)) | |
41f12ed0 JJ |
7898 | (set (match_scratch:SI 3 "=r") (const_int 0)) |
7899 | (clobber (match_scratch:SI 2 "=&r"))] | |
8ec11fe9 JJ |
7900 | "TARGET_ARCH32" |
7901 | "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3" | |
7902 | [(set_attr "type" "multi") | |
7903 | (set_attr "length" "4")]) | |
7904 | ||
7905 | (define_insn "stack_protect_testdi" | |
7906 | [(set (match_operand:DI 0 "register_operand" "=&r") | |
7907 | (unspec:DI [(match_operand:DI 1 "memory_operand" "m") | |
7908 | (match_operand:DI 2 "memory_operand" "m")] | |
7909 | UNSPEC_SP_TEST)) | |
7910 | (set (match_scratch:DI 3 "=r") (const_int 0))] | |
7911 | "TARGET_ARCH64" | |
7912 | "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3" | |
7913 | [(set_attr "type" "multi") | |
7914 | (set_attr "length" "4")]) | |
7915 | ||
8393a290 JM |
7916 | ;; Vector instructions. |
7917 | ||
e00560c2 DM |
7918 | (define_mode_iterator VM32 [V1SI V2HI V4QI]) |
7919 | (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI]) | |
7920 | (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI]) | |
7921 | ||
7922 | (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")]) | |
7923 | (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f") | |
7924 | (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")]) | |
7925 | (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single") | |
7926 | (V1DI "double") (V2SI "double") (V4HI "double") | |
7927 | (V8QI "double")]) | |
7928 | ||
7929 | (define_expand "mov<VMALL:mode>" | |
7930 | [(set (match_operand:VMALL 0 "nonimmediate_operand" "") | |
7931 | (match_operand:VMALL 1 "general_operand" ""))] | |
7932 | "TARGET_VIS" | |
7933 | { | |
7934 | if (sparc_expand_move (<VMALL:MODE>mode, operands)) | |
7935 | DONE; | |
7936 | }) | |
7937 | ||
1b43bc82 | 7938 | (define_insn "*mov<VM32:mode>_insn" |
cca3f03d DM |
7939 | [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f") |
7940 | (match_operand:VM32 1 "input_operand" "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))] | |
e00560c2 | 7941 | "TARGET_VIS |
bb12a72a DM |
7942 | && (register_operand (operands[0], <VM32:MODE>mode) |
7943 | || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))" | |
7944 | "@ | |
7945 | fzeros\t%0 | |
7946 | fones\t%0 | |
f298688c | 7947 | fsrc2s\t%1, %0 |
bb12a72a DM |
7948 | ld\t%1, %0 |
7949 | st\t%1, %0 | |
7950 | st\t%r1, %0 | |
7951 | ld\t%1, %0 | |
7952 | st\t%1, %0 | |
7953 | mov\t%1, %0 | |
7954 | movstouw\t%1, %0 | |
7955 | movwtos\t%1, %0" | |
f298688c | 7956 | [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv") |
1b43bc82 | 7957 | (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")]) |
e00560c2 | 7958 | |
1b43bc82 | 7959 | (define_insn "*mov<VM64:mode>_insn_sp64" |
0a940828 DM |
7960 | [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r") |
7961 | (match_operand:VM64 1 "input_operand" "Y,C,e,m,e,Y, m,*r, e,*r,*r"))] | |
e00560c2 | 7962 | "TARGET_VIS |
bb12a72a DM |
7963 | && TARGET_ARCH64 |
7964 | && (register_operand (operands[0], <VM64:MODE>mode) | |
7965 | || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))" | |
7966 | "@ | |
7967 | fzero\t%0 | |
7968 | fone\t%0 | |
f298688c | 7969 | fsrc2\t%1, %0 |
bb12a72a DM |
7970 | ldd\t%1, %0 |
7971 | std\t%1, %0 | |
7972 | stx\t%r1, %0 | |
7973 | ldx\t%1, %0 | |
7974 | stx\t%1, %0 | |
7975 | movdtox\t%1, %0 | |
7976 | movxtod\t%1, %0 | |
7977 | mov\t%1, %0" | |
f298688c | 7978 | [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*") |
1b43bc82 | 7979 | (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")]) |
bb12a72a | 7980 | |
1b43bc82 | 7981 | (define_insn "*mov<VM64:mode>_insn_sp32" |
aaa050aa DM |
7982 | [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r") |
7983 | (match_operand:VM64 1 "input_operand" "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))] | |
bb12a72a | 7984 | "TARGET_VIS |
bb12a72a DM |
7985 | && ! TARGET_ARCH64 |
7986 | && (register_operand (operands[0], <VM64:MODE>mode) | |
7987 | || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))" | |
7988 | "@ | |
7989 | fzero\t%0 | |
7990 | fone\t%0 | |
f298688c | 7991 | fsrc2\t%1, %0 |
bb12a72a DM |
7992 | # |
7993 | # | |
7994 | ldd\t%1, %0 | |
7995 | std\t%1, %0 | |
7996 | stx\t%r1, %0 | |
7997 | ldd\t%1, %0 | |
7998 | std\t%1, %0 | |
7999 | # | |
8000 | #" | |
f298688c | 8001 | [(set_attr "type" "visl,visl,vismv,*,*,fpload,fpstore,store,load,store,*,*") |
1b43bc82 DM |
8002 | (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2") |
8003 | (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")]) | |
e00560c2 DM |
8004 | |
8005 | (define_split | |
8006 | [(set (match_operand:VM64 0 "memory_operand" "") | |
8007 | (match_operand:VM64 1 "register_operand" ""))] | |
8008 | "reload_completed | |
8009 | && TARGET_VIS | |
8010 | && ! TARGET_ARCH64 | |
8011 | && (((REGNO (operands[1]) % 2) != 0) | |
8012 | || ! mem_min_alignment (operands[0], 8)) | |
8013 | && offsettable_memref_p (operands[0])" | |
8014 | [(clobber (const_int 0))] | |
8015 | { | |
8016 | rtx word0, word1; | |
8017 | ||
8018 | word0 = adjust_address (operands[0], SImode, 0); | |
8019 | word1 = adjust_address (operands[0], SImode, 4); | |
8020 | ||
8021 | emit_move_insn_1 (word0, gen_highpart (SImode, operands[1])); | |
8022 | emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1])); | |
8023 | DONE; | |
8024 | }) | |
8025 | ||
bb12a72a DM |
8026 | (define_split |
8027 | [(set (match_operand:VM64 0 "register_operand" "") | |
8028 | (match_operand:VM64 1 "register_operand" ""))] | |
8029 | "reload_completed | |
8030 | && TARGET_VIS | |
8031 | && ! TARGET_ARCH64 | |
8032 | && sparc_split_regreg_legitimate (operands[0], operands[1])" | |
8033 | [(clobber (const_int 0))] | |
8034 | { | |
8035 | rtx set_dest = operands[0]; | |
8036 | rtx set_src = operands[1]; | |
8037 | rtx dest1, dest2; | |
8038 | rtx src1, src2; | |
8039 | ||
8040 | dest1 = gen_highpart (SImode, set_dest); | |
8041 | dest2 = gen_lowpart (SImode, set_dest); | |
8042 | src1 = gen_highpart (SImode, set_src); | |
8043 | src2 = gen_lowpart (SImode, set_src); | |
8044 | ||
8045 | /* Now emit using the real source and destination we found, swapping | |
8046 | the order if we detect overlap. */ | |
8047 | if (reg_overlap_mentioned_p (dest1, src2)) | |
8048 | { | |
8049 | emit_insn (gen_movsi (dest2, src2)); | |
8050 | emit_insn (gen_movsi (dest1, src1)); | |
8051 | } | |
8052 | else | |
8053 | { | |
8054 | emit_insn (gen_movsi (dest1, src1)); | |
8055 | emit_insn (gen_movsi (dest2, src2)); | |
8056 | } | |
8057 | DONE; | |
8058 | }) | |
8059 | ||
e00560c2 DM |
8060 | (define_expand "vec_init<mode>" |
8061 | [(match_operand:VMALL 0 "register_operand" "") | |
8062 | (match_operand:VMALL 1 "" "")] | |
8063 | "TARGET_VIS" | |
8064 | { | |
8065 | sparc_expand_vector_init (operands[0], operands[1]); | |
8066 | DONE; | |
8067 | }) | |
8068 | ||
8e24e409 DM |
8069 | (define_code_iterator plusminus [plus minus]) |
8070 | (define_code_attr plusminus_insn [(plus "add") (minus "sub")]) | |
8393a290 | 8071 | |
e00560c2 DM |
8072 | (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI]) |
8073 | ||
8074 | (define_insn "<plusminus_insn><mode>3" | |
8075 | [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>") | |
8076 | (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>") | |
8077 | (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))] | |
8393a290 | 8078 | "TARGET_VIS" |
e00560c2 | 8079 | "fp<plusminus_insn><vbits>\t%1, %2, %0" |
8393a290 | 8080 | [(set_attr "type" "fga") |
e00560c2 DM |
8081 | (set_attr "fptype" "<vfptype>")]) |
8082 | ||
8083 | (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI]) | |
8084 | (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s") | |
8085 | (V1DI "") (V2SI "") (V4HI "") (V8QI "")]) | |
8086 | (define_code_iterator vlop [ior and xor]) | |
8087 | (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")]) | |
8088 | (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")]) | |
8089 | ||
8090 | (define_insn "<code><mode>3" | |
8091 | [(set (match_operand:VL 0 "register_operand" "=<vconstr>") | |
8092 | (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>") | |
8093 | (match_operand:VL 2 "register_operand" "<vconstr>")))] | |
8094 | "TARGET_VIS" | |
8095 | "f<vlinsn><vlsuf>\t%1, %2, %0" | |
f298688c | 8096 | [(set_attr "type" "visl") |
e00560c2 | 8097 | (set_attr "fptype" "<vfptype>")]) |
8393a290 | 8098 | |
e00560c2 DM |
8099 | (define_insn "*not_<code><mode>3" |
8100 | [(set (match_operand:VL 0 "register_operand" "=<vconstr>") | |
8101 | (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>") | |
8102 | (match_operand:VL 2 "register_operand" "<vconstr>"))))] | |
8393a290 | 8103 | "TARGET_VIS" |
e00560c2 | 8104 | "f<vlninsn><vlsuf>\t%1, %2, %0" |
f298688c | 8105 | [(set_attr "type" "visl") |
e00560c2 | 8106 | (set_attr "fptype" "<vfptype>")]) |
8393a290 | 8107 | |
e00560c2 DM |
8108 | ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND. |
8109 | (define_insn "*nand<mode>_vis" | |
8110 | [(set (match_operand:VL 0 "register_operand" "=<vconstr>") | |
8111 | (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")) | |
8112 | (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))] | |
8393a290 | 8113 | "TARGET_VIS" |
e00560c2 | 8114 | "fnand<vlsuf>\t%1, %2, %0" |
f298688c | 8115 | [(set_attr "type" "visl") |
e00560c2 | 8116 | (set_attr "fptype" "<vfptype>")]) |
893e18a5 | 8117 | |
e00560c2 | 8118 | (define_code_iterator vlnotop [ior and]) |
893e18a5 | 8119 | |
e00560c2 DM |
8120 | (define_insn "*<code>_not1<mode>_vis" |
8121 | [(set (match_operand:VL 0 "register_operand" "=<vconstr>") | |
8122 | (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")) | |
8123 | (match_operand:VL 2 "register_operand" "<vconstr>")))] | |
8124 | "TARGET_VIS" | |
8125 | "f<vlinsn>not1<vlsuf>\t%1, %2, %0" | |
f298688c | 8126 | [(set_attr "type" "visl") |
e00560c2 | 8127 | (set_attr "fptype" "<vfptype>")]) |
893e18a5 | 8128 | |
e00560c2 DM |
8129 | (define_insn "*<code>_not2<mode>_vis" |
8130 | [(set (match_operand:VL 0 "register_operand" "=<vconstr>") | |
8131 | (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>") | |
8132 | (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))] | |
893e18a5 | 8133 | "TARGET_VIS" |
e00560c2 | 8134 | "f<vlinsn>not2<vlsuf>\t%1, %2, %0" |
f298688c | 8135 | [(set_attr "type" "visl") |
e00560c2 | 8136 | (set_attr "fptype" "<vfptype>")]) |
893e18a5 | 8137 | |
e00560c2 DM |
8138 | (define_insn "one_cmpl<mode>2" |
8139 | [(set (match_operand:VL 0 "register_operand" "=<vconstr>") | |
8140 | (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))] | |
893e18a5 | 8141 | "TARGET_VIS" |
e00560c2 | 8142 | "fnot1<vlsuf>\t%1, %0" |
f298688c | 8143 | [(set_attr "type" "visl") |
e00560c2 | 8144 | (set_attr "fptype" "<vfptype>")]) |
16f59241 JM |
8145 | |
8146 | ;; Hard to generate VIS instructions. We have builtins for these. | |
8147 | ||
8148 | (define_insn "fpack16_vis" | |
8149 | [(set (match_operand:V4QI 0 "register_operand" "=f") | |
a4f713f5 DM |
8150 | (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e") |
8151 | (reg:DI GSR_REG)] | |
8152 | UNSPEC_FPACK16))] | |
16f59241 JM |
8153 | "TARGET_VIS" |
8154 | "fpack16\t%1, %0" | |
afa3ed85 | 8155 | [(set_attr "type" "fgm_pack") |
16f59241 JM |
8156 | (set_attr "fptype" "double")]) |
8157 | ||
8158 | (define_insn "fpackfix_vis" | |
8159 | [(set (match_operand:V2HI 0 "register_operand" "=f") | |
a4f713f5 DM |
8160 | (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e") |
8161 | (reg:DI GSR_REG)] | |
8162 | UNSPEC_FPACKFIX))] | |
16f59241 JM |
8163 | "TARGET_VIS" |
8164 | "fpackfix\t%1, %0" | |
afa3ed85 | 8165 | [(set_attr "type" "fgm_pack") |
16f59241 JM |
8166 | (set_attr "fptype" "double")]) |
8167 | ||
8168 | (define_insn "fpack32_vis" | |
8169 | [(set (match_operand:V8QI 0 "register_operand" "=e") | |
8170 | (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e") | |
a4f713f5 DM |
8171 | (match_operand:V8QI 2 "register_operand" "e") |
8172 | (reg:DI GSR_REG)] | |
8173 | UNSPEC_FPACK32))] | |
16f59241 JM |
8174 | "TARGET_VIS" |
8175 | "fpack32\t%1, %2, %0" | |
afa3ed85 | 8176 | [(set_attr "type" "fgm_pack") |
16f59241 JM |
8177 | (set_attr "fptype" "double")]) |
8178 | ||
8179 | (define_insn "fexpand_vis" | |
8180 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
8181 | (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")] | |
8182 | UNSPEC_FEXPAND))] | |
8183 | "TARGET_VIS" | |
8184 | "fexpand\t%1, %0" | |
8185 | [(set_attr "type" "fga") | |
8186 | (set_attr "fptype" "double")]) | |
8187 | ||
16f59241 JM |
8188 | (define_insn "fpmerge_vis" |
8189 | [(set (match_operand:V8QI 0 "register_operand" "=e") | |
f1c141a7 DM |
8190 | (vec_select:V8QI |
8191 | (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f") | |
8192 | (match_operand:V4QI 2 "register_operand" "f")) | |
8193 | (parallel [(const_int 0) (const_int 4) | |
8194 | (const_int 1) (const_int 5) | |
8195 | (const_int 2) (const_int 6) | |
8196 | (const_int 3) (const_int 7)])))] | |
16f59241 JM |
8197 | "TARGET_VIS" |
8198 | "fpmerge\t%1, %2, %0" | |
8199 | [(set_attr "type" "fga") | |
8200 | (set_attr "fptype" "double")]) | |
8201 | ||
f1c141a7 DM |
8202 | (define_insn "vec_interleave_lowv8qi" |
8203 | [(set (match_operand:V8QI 0 "register_operand" "=e") | |
8204 | (vec_select:V8QI | |
8205 | (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f") | |
8206 | (match_operand:V8QI 2 "register_operand" "f")) | |
8207 | (parallel [(const_int 0) (const_int 8) | |
8208 | (const_int 1) (const_int 9) | |
8209 | (const_int 2) (const_int 10) | |
8210 | (const_int 3) (const_int 11)])))] | |
8211 | "TARGET_VIS" | |
8212 | "fpmerge\t%L1, %L2, %0" | |
8213 | [(set_attr "type" "fga") | |
8214 | (set_attr "fptype" "double")]) | |
8215 | ||
8216 | (define_insn "vec_interleave_highv8qi" | |
8217 | [(set (match_operand:V8QI 0 "register_operand" "=e") | |
8218 | (vec_select:V8QI | |
8219 | (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f") | |
8220 | (match_operand:V8QI 2 "register_operand" "f")) | |
8221 | (parallel [(const_int 4) (const_int 12) | |
8222 | (const_int 5) (const_int 13) | |
8223 | (const_int 6) (const_int 14) | |
8224 | (const_int 7) (const_int 15)])))] | |
8225 | "TARGET_VIS" | |
8226 | "fpmerge\t%H1, %H2, %0" | |
8227 | [(set_attr "type" "fga") | |
8228 | (set_attr "fptype" "double")]) | |
8229 | ||
16f59241 JM |
8230 | ;; Partitioned multiply instructions |
8231 | (define_insn "fmul8x16_vis" | |
8232 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
f1c141a7 DM |
8233 | (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f") |
8234 | (match_operand:V4HI 2 "register_operand" "e")] | |
8235 | UNSPEC_MUL8))] | |
16f59241 JM |
8236 | "TARGET_VIS" |
8237 | "fmul8x16\t%1, %2, %0" | |
afa3ed85 | 8238 | [(set_attr "type" "fgm_mul") |
16f59241 JM |
8239 | (set_attr "fptype" "double")]) |
8240 | ||
16f59241 JM |
8241 | (define_insn "fmul8x16au_vis" |
8242 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
f1c141a7 DM |
8243 | (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f") |
8244 | (match_operand:V2HI 2 "register_operand" "f")] | |
8245 | UNSPEC_MUL16AU))] | |
16f59241 JM |
8246 | "TARGET_VIS" |
8247 | "fmul8x16au\t%1, %2, %0" | |
afa3ed85 | 8248 | [(set_attr "type" "fgm_mul") |
16f59241 JM |
8249 | (set_attr "fptype" "double")]) |
8250 | ||
8251 | (define_insn "fmul8x16al_vis" | |
8252 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
8253 | (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f") | |
8254 | (match_operand:V2HI 2 "register_operand" "f")] | |
8255 | UNSPEC_MUL16AL))] | |
8256 | "TARGET_VIS" | |
8257 | "fmul8x16al\t%1, %2, %0" | |
afa3ed85 | 8258 | [(set_attr "type" "fgm_mul") |
16f59241 JM |
8259 | (set_attr "fptype" "double")]) |
8260 | ||
16f59241 JM |
8261 | (define_insn "fmul8sux16_vis" |
8262 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
f1c141a7 DM |
8263 | (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e") |
8264 | (match_operand:V4HI 2 "register_operand" "e")] | |
8265 | UNSPEC_MUL8SU))] | |
16f59241 JM |
8266 | "TARGET_VIS" |
8267 | "fmul8sux16\t%1, %2, %0" | |
afa3ed85 | 8268 | [(set_attr "type" "fgm_mul") |
16f59241 JM |
8269 | (set_attr "fptype" "double")]) |
8270 | ||
8271 | (define_insn "fmul8ulx16_vis" | |
8272 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
8273 | (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e") | |
8274 | (match_operand:V4HI 2 "register_operand" "e")] | |
8275 | UNSPEC_MUL8UL))] | |
8276 | "TARGET_VIS" | |
8277 | "fmul8ulx16\t%1, %2, %0" | |
afa3ed85 | 8278 | [(set_attr "type" "fgm_mul") |
16f59241 JM |
8279 | (set_attr "fptype" "double")]) |
8280 | ||
16f59241 JM |
8281 | (define_insn "fmuld8sux16_vis" |
8282 | [(set (match_operand:V2SI 0 "register_operand" "=e") | |
f1c141a7 DM |
8283 | (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f") |
8284 | (match_operand:V2HI 2 "register_operand" "f")] | |
8285 | UNSPEC_MULDSU))] | |
16f59241 JM |
8286 | "TARGET_VIS" |
8287 | "fmuld8sux16\t%1, %2, %0" | |
afa3ed85 | 8288 | [(set_attr "type" "fgm_mul") |
16f59241 JM |
8289 | (set_attr "fptype" "double")]) |
8290 | ||
8291 | (define_insn "fmuld8ulx16_vis" | |
8292 | [(set (match_operand:V2SI 0 "register_operand" "=e") | |
8293 | (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f") | |
8294 | (match_operand:V2HI 2 "register_operand" "f")] | |
8295 | UNSPEC_MULDUL))] | |
8296 | "TARGET_VIS" | |
8297 | "fmuld8ulx16\t%1, %2, %0" | |
afa3ed85 | 8298 | [(set_attr "type" "fgm_mul") |
16f59241 JM |
8299 | (set_attr "fptype" "double")]) |
8300 | ||
10b859c0 | 8301 | (define_expand "wrgsr_vis" |
caa06916 | 8302 | [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))] |
10b859c0 DM |
8303 | "TARGET_VIS" |
8304 | { | |
8305 | if (! TARGET_ARCH64) | |
8306 | { | |
8307 | emit_insn (gen_wrgsr_v8plus (operands[0])); | |
8308 | DONE; | |
8309 | } | |
8310 | }) | |
8311 | ||
8312 | (define_insn "*wrgsr_sp64" | |
caa06916 | 8313 | [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))] |
10b859c0 DM |
8314 | "TARGET_VIS && TARGET_ARCH64" |
8315 | "wr\t%%g0, %0, %%gsr" | |
8316 | [(set_attr "type" "gsr")]) | |
8317 | ||
8318 | (define_insn "wrgsr_v8plus" | |
caa06916 | 8319 | [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r")) |
10b859c0 DM |
8320 | (clobber (match_scratch:SI 1 "=X,&h"))] |
8321 | "TARGET_VIS && ! TARGET_ARCH64" | |
8322 | { | |
8323 | if (GET_CODE (operands[0]) == CONST_INT | |
8324 | || sparc_check_64 (operands[0], insn)) | |
8325 | return "wr\t%%g0, %0, %%gsr"; | |
8326 | ||
8327 | output_asm_insn("srl\t%L0, 0, %L0", operands); | |
8328 | return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr"; | |
8329 | } | |
8330 | [(set_attr "type" "multi")]) | |
8331 | ||
8332 | (define_expand "rdgsr_vis" | |
8333 | [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))] | |
8334 | "TARGET_VIS" | |
8335 | { | |
8336 | if (! TARGET_ARCH64) | |
8337 | { | |
8338 | emit_insn (gen_rdgsr_v8plus (operands[0])); | |
8339 | DONE; | |
8340 | } | |
8341 | }) | |
8342 | ||
8343 | (define_insn "*rdgsr_sp64" | |
8344 | [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))] | |
8345 | "TARGET_VIS && TARGET_ARCH64" | |
8346 | "rd\t%%gsr, %0" | |
8347 | [(set_attr "type" "gsr")]) | |
8348 | ||
8349 | (define_insn "rdgsr_v8plus" | |
8350 | [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG)) | |
8351 | (clobber (match_scratch:SI 1 "=&h"))] | |
8352 | "TARGET_VIS && ! TARGET_ARCH64" | |
8353 | { | |
8354 | return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0"; | |
8355 | } | |
8356 | [(set_attr "type" "multi")]) | |
8357 | ||
16f59241 | 8358 | ;; Using faligndata only makes sense after an alignaddr since the choice of |
0fa2e4df | 8359 | ;; bytes to take out of each operand is dependent on the results of the last |
16f59241 | 8360 | ;; alignaddr. |
e00560c2 DM |
8361 | (define_insn "faligndata<VM64:mode>_vis" |
8362 | [(set (match_operand:VM64 0 "register_operand" "=e") | |
8363 | (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e") | |
8364 | (match_operand:VM64 2 "register_operand" "e") | |
a4f713f5 DM |
8365 | (reg:DI GSR_REG)] |
8366 | UNSPEC_ALIGNDATA))] | |
16f59241 JM |
8367 | "TARGET_VIS" |
8368 | "faligndata\t%1, %2, %0" | |
8369 | [(set_attr "type" "fga") | |
8370 | (set_attr "fptype" "double")]) | |
8371 | ||
10b859c0 DM |
8372 | (define_insn "alignaddrsi_vis" |
8373 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8374 | (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") | |
8375 | (match_operand:SI 2 "register_or_zero_operand" "rJ"))) | |
a4f713f5 DM |
8376 | (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) |
8377 | (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] | |
16f59241 | 8378 | "TARGET_VIS" |
afa3ed85 DM |
8379 | "alignaddr\t%r1, %r2, %0" |
8380 | [(set_attr "type" "gsr")]) | |
16f59241 | 8381 | |
10b859c0 DM |
8382 | (define_insn "alignaddrdi_vis" |
8383 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8384 | (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") | |
8385 | (match_operand:DI 2 "register_or_zero_operand" "rJ"))) | |
a4f713f5 DM |
8386 | (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) |
8387 | (plus:DI (match_dup 1) (match_dup 2)))] | |
10b859c0 | 8388 | "TARGET_VIS" |
afa3ed85 DM |
8389 | "alignaddr\t%r1, %r2, %0" |
8390 | [(set_attr "type" "gsr")]) | |
10b859c0 DM |
8391 | |
8392 | (define_insn "alignaddrlsi_vis" | |
8393 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8394 | (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") | |
8395 | (match_operand:SI 2 "register_or_zero_operand" "rJ"))) | |
a4f713f5 DM |
8396 | (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) |
8397 | (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))) | |
8398 | (const_int 7)))] | |
10b859c0 | 8399 | "TARGET_VIS" |
afa3ed85 DM |
8400 | "alignaddrl\t%r1, %r2, %0" |
8401 | [(set_attr "type" "gsr")]) | |
10b859c0 DM |
8402 | |
8403 | (define_insn "alignaddrldi_vis" | |
8404 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8405 | (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") | |
8406 | (match_operand:DI 2 "register_or_zero_operand" "rJ"))) | |
a4f713f5 DM |
8407 | (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) |
8408 | (xor:DI (plus:DI (match_dup 1) (match_dup 2)) | |
8409 | (const_int 7)))] | |
47640f40 | 8410 | "TARGET_VIS" |
afa3ed85 DM |
8411 | "alignaddrl\t%r1, %r2, %0" |
8412 | [(set_attr "type" "gsr")]) | |
47640f40 | 8413 | |
16f59241 JM |
8414 | (define_insn "pdist_vis" |
8415 | [(set (match_operand:DI 0 "register_operand" "=e") | |
8416 | (unspec:DI [(match_operand:V8QI 1 "register_operand" "e") | |
8417 | (match_operand:V8QI 2 "register_operand" "e") | |
8418 | (match_operand:DI 3 "register_operand" "0")] | |
8419 | UNSPEC_PDIST))] | |
8420 | "TARGET_VIS" | |
8421 | "pdist\t%1, %2, %0" | |
f298688c | 8422 | [(set_attr "type" "pdist") |
16f59241 | 8423 | (set_attr "fptype" "double")]) |
396b535a | 8424 | |
b1e4f4dd DM |
8425 | ;; Edge instructions produce condition codes equivalent to a 'subcc' |
8426 | ;; with the same operands. | |
47640f40 | 8427 | (define_insn "edge8<P:mode>_vis" |
45a7dd80 | 8428 | [(set (reg:CC_NOOV CC_REG) |
d1947945 RH |
8429 | (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") |
8430 | (match_operand:P 2 "register_or_zero_operand" "rJ")) | |
47640f40 | 8431 | (const_int 0))) |
cb8bbba8 DM |
8432 | (set (match_operand:P 0 "register_operand" "=r") |
8433 | (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))] | |
b1e4f4dd DM |
8434 | "TARGET_VIS" |
8435 | "edge8\t%r1, %r2, %0" | |
8436 | [(set_attr "type" "edge")]) | |
8437 | ||
47640f40 | 8438 | (define_insn "edge8l<P:mode>_vis" |
45a7dd80 | 8439 | [(set (reg:CC_NOOV CC_REG) |
d1947945 RH |
8440 | (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") |
8441 | (match_operand:P 2 "register_or_zero_operand" "rJ")) | |
47640f40 | 8442 | (const_int 0))) |
cb8bbba8 DM |
8443 | (set (match_operand:P 0 "register_operand" "=r") |
8444 | (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))] | |
b1e4f4dd DM |
8445 | "TARGET_VIS" |
8446 | "edge8l\t%r1, %r2, %0" | |
8447 | [(set_attr "type" "edge")]) | |
8448 | ||
47640f40 | 8449 | (define_insn "edge16<P:mode>_vis" |
45a7dd80 | 8450 | [(set (reg:CC_NOOV CC_REG) |
d1947945 RH |
8451 | (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") |
8452 | (match_operand:P 2 "register_or_zero_operand" "rJ")) | |
47640f40 | 8453 | (const_int 0))) |
cb8bbba8 DM |
8454 | (set (match_operand:P 0 "register_operand" "=r") |
8455 | (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))] | |
b1e4f4dd DM |
8456 | "TARGET_VIS" |
8457 | "edge16\t%r1, %r2, %0" | |
8458 | [(set_attr "type" "edge")]) | |
8459 | ||
47640f40 | 8460 | (define_insn "edge16l<P:mode>_vis" |
45a7dd80 | 8461 | [(set (reg:CC_NOOV CC_REG) |
d1947945 RH |
8462 | (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") |
8463 | (match_operand:P 2 "register_or_zero_operand" "rJ")) | |
47640f40 | 8464 | (const_int 0))) |
cb8bbba8 DM |
8465 | (set (match_operand:P 0 "register_operand" "=r") |
8466 | (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))] | |
b1e4f4dd DM |
8467 | "TARGET_VIS" |
8468 | "edge16l\t%r1, %r2, %0" | |
8469 | [(set_attr "type" "edge")]) | |
8470 | ||
47640f40 | 8471 | (define_insn "edge32<P:mode>_vis" |
45a7dd80 | 8472 | [(set (reg:CC_NOOV CC_REG) |
d1947945 RH |
8473 | (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") |
8474 | (match_operand:P 2 "register_or_zero_operand" "rJ")) | |
47640f40 | 8475 | (const_int 0))) |
cb8bbba8 DM |
8476 | (set (match_operand:P 0 "register_operand" "=r") |
8477 | (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))] | |
b1e4f4dd DM |
8478 | "TARGET_VIS" |
8479 | "edge32\t%r1, %r2, %0" | |
8480 | [(set_attr "type" "edge")]) | |
8481 | ||
47640f40 | 8482 | (define_insn "edge32l<P:mode>_vis" |
45a7dd80 | 8483 | [(set (reg:CC_NOOV CC_REG) |
d1947945 RH |
8484 | (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") |
8485 | (match_operand:P 2 "register_or_zero_operand" "rJ")) | |
47640f40 | 8486 | (const_int 0))) |
cb8bbba8 DM |
8487 | (set (match_operand:P 0 "register_operand" "=r") |
8488 | (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))] | |
b1e4f4dd DM |
8489 | "TARGET_VIS" |
8490 | "edge32l\t%r1, %r2, %0" | |
8491 | [(set_attr "type" "edge")]) | |
8492 | ||
b3304235 | 8493 | (define_code_iterator gcond [le ne gt eq]) |
b3304235 DM |
8494 | (define_mode_iterator GCM [V4HI V2SI]) |
8495 | (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")]) | |
f4d7f828 | 8496 | |
424dcc4f | 8497 | (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis" |
cb8bbba8 | 8498 | [(set (match_operand:P 0 "register_operand" "=r") |
b3304235 DM |
8499 | (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e") |
8500 | (match_operand:GCM 2 "register_operand" "e"))] | |
8501 | UNSPEC_FCMP))] | |
f4d7f828 | 8502 | "TARGET_VIS" |
424dcc4f | 8503 | "fcmp<code><GCM:gcm_name>\t%1, %2, %0" |
f298688c | 8504 | [(set_attr "type" "visl") |
f4d7f828 DM |
8505 | (set_attr "fptype" "double")]) |
8506 | ||
1f9ed162 DM |
8507 | (define_expand "vcond<mode><mode>" |
8508 | [(match_operand:GCM 0 "register_operand" "") | |
8509 | (match_operand:GCM 1 "register_operand" "") | |
8510 | (match_operand:GCM 2 "register_operand" "") | |
8511 | (match_operator 3 "" | |
8512 | [(match_operand:GCM 4 "register_operand" "") | |
8513 | (match_operand:GCM 5 "register_operand" "")])] | |
8514 | "TARGET_VIS3" | |
8515 | { | |
8516 | sparc_expand_vcond (<MODE>mode, operands, | |
8517 | UNSPEC_CMASK<gcm_name>, | |
8518 | UNSPEC_FCMP); | |
8519 | DONE; | |
8520 | }) | |
8521 | ||
8522 | (define_expand "vconduv8qiv8qi" | |
8523 | [(match_operand:V8QI 0 "register_operand" "") | |
8524 | (match_operand:V8QI 1 "register_operand" "") | |
8525 | (match_operand:V8QI 2 "register_operand" "") | |
8526 | (match_operator 3 "" | |
8527 | [(match_operand:V8QI 4 "register_operand" "") | |
8528 | (match_operand:V8QI 5 "register_operand" "")])] | |
8529 | "TARGET_VIS3" | |
8530 | { | |
8531 | sparc_expand_vcond (V8QImode, operands, | |
8532 | UNSPEC_CMASK8, | |
8533 | UNSPEC_FUCMP); | |
8534 | DONE; | |
8535 | }) | |
8536 | ||
1ec01ab2 DM |
8537 | (define_insn "array8<P:mode>_vis" |
8538 | [(set (match_operand:P 0 "register_operand" "=r") | |
d1947945 RH |
8539 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8540 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
1ec01ab2 DM |
8541 | UNSPEC_ARRAY8))] |
8542 | "TARGET_VIS" | |
8543 | "array8\t%r1, %r2, %0" | |
8544 | [(set_attr "type" "array")]) | |
8545 | ||
8546 | (define_insn "array16<P:mode>_vis" | |
8547 | [(set (match_operand:P 0 "register_operand" "=r") | |
d1947945 RH |
8548 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8549 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
1ec01ab2 DM |
8550 | UNSPEC_ARRAY16))] |
8551 | "TARGET_VIS" | |
8552 | "array16\t%r1, %r2, %0" | |
8553 | [(set_attr "type" "array")]) | |
8554 | ||
8555 | (define_insn "array32<P:mode>_vis" | |
8556 | [(set (match_operand:P 0 "register_operand" "=r") | |
d1947945 RH |
8557 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8558 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
1ec01ab2 DM |
8559 | UNSPEC_ARRAY32))] |
8560 | "TARGET_VIS" | |
8561 | "array32\t%r1, %r2, %0" | |
8562 | [(set_attr "type" "array")]) | |
8563 | ||
2b25763b DM |
8564 | (define_insn "bmaskdi_vis" |
8565 | [(set (match_operand:DI 0 "register_operand" "=r") | |
d1947945 RH |
8566 | (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") |
8567 | (match_operand:DI 2 "register_or_zero_operand" "rJ"))) | |
2b25763b DM |
8568 | (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32)) |
8569 | (plus:DI (match_dup 1) (match_dup 2)))] | |
8570 | "TARGET_VIS2" | |
8571 | "bmask\t%r1, %r2, %0" | |
8572 | [(set_attr "type" "array")]) | |
8573 | ||
8574 | (define_insn "bmasksi_vis" | |
8575 | [(set (match_operand:SI 0 "register_operand" "=r") | |
d1947945 RH |
8576 | (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") |
8577 | (match_operand:SI 2 "register_or_zero_operand" "rJ"))) | |
2b25763b DM |
8578 | (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32)) |
8579 | (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] | |
c4728c6b DM |
8580 | "TARGET_VIS2" |
8581 | "bmask\t%r1, %r2, %0" | |
8582 | [(set_attr "type" "array")]) | |
8583 | ||
e00560c2 DM |
8584 | (define_insn "bshuffle<VM64:mode>_vis" |
8585 | [(set (match_operand:VM64 0 "register_operand" "=e") | |
8586 | (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e") | |
8587 | (match_operand:VM64 2 "register_operand" "e") | |
a4f713f5 | 8588 | (reg:DI GSR_REG)] |
2b25763b | 8589 | UNSPEC_BSHUFFLE))] |
c4728c6b DM |
8590 | "TARGET_VIS2" |
8591 | "bshuffle\t%1, %2, %0" | |
8592 | [(set_attr "type" "fga") | |
8593 | (set_attr "fptype" "double")]) | |
8594 | ||
9d4dedaa RH |
8595 | ;; The rtl expanders will happily convert constant permutations on other |
8596 | ;; modes down to V8QI. Rely on this to avoid the complexity of the byte | |
8597 | ;; order of the permutation. | |
8598 | (define_expand "vec_perm_constv8qi" | |
8599 | [(match_operand:V8QI 0 "register_operand" "") | |
8600 | (match_operand:V8QI 1 "register_operand" "") | |
8601 | (match_operand:V8QI 2 "register_operand" "") | |
8602 | (match_operand:V8QI 3 "" "")] | |
8603 | "TARGET_VIS2" | |
8604 | { | |
8605 | unsigned int i, mask; | |
8606 | rtx sel = operands[3]; | |
8607 | ||
8608 | for (i = mask = 0; i < 8; ++i) | |
8609 | mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4); | |
8610 | sel = force_reg (SImode, gen_int_mode (mask, SImode)); | |
8611 | ||
2f56a311 | 8612 | emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx)); |
9d4dedaa RH |
8613 | emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2])); |
8614 | DONE; | |
8615 | }) | |
8616 | ||
8617 | ;; Unlike constant permutation, we can vastly simplify the compression of | |
8618 | ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the | |
8619 | ;; width of the input is. | |
8620 | (define_expand "vec_perm<mode>" | |
8621 | [(match_operand:VM64 0 "register_operand" "") | |
8622 | (match_operand:VM64 1 "register_operand" "") | |
8623 | (match_operand:VM64 2 "register_operand" "") | |
8624 | (match_operand:VM64 3 "register_operand" "")] | |
8625 | "TARGET_VIS2" | |
8626 | { | |
8627 | sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]); | |
8628 | emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2])); | |
8629 | DONE; | |
8630 | }) | |
8631 | ||
c4728c6b DM |
8632 | ;; VIS 2.0 adds edge variants which do not set the condition codes |
8633 | (define_insn "edge8n<P:mode>_vis" | |
8634 | [(set (match_operand:P 0 "register_operand" "=r") | |
d1947945 RH |
8635 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8636 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
c4728c6b DM |
8637 | UNSPEC_EDGE8N))] |
8638 | "TARGET_VIS2" | |
8639 | "edge8n\t%r1, %r2, %0" | |
8640 | [(set_attr "type" "edgen")]) | |
8641 | ||
8642 | (define_insn "edge8ln<P:mode>_vis" | |
8643 | [(set (match_operand:P 0 "register_operand" "=r") | |
d1947945 RH |
8644 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8645 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
c4728c6b DM |
8646 | UNSPEC_EDGE8LN))] |
8647 | "TARGET_VIS2" | |
8648 | "edge8ln\t%r1, %r2, %0" | |
8649 | [(set_attr "type" "edgen")]) | |
8650 | ||
8651 | (define_insn "edge16n<P:mode>_vis" | |
8652 | [(set (match_operand:P 0 "register_operand" "=r") | |
d1947945 RH |
8653 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8654 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
c4728c6b DM |
8655 | UNSPEC_EDGE16N))] |
8656 | "TARGET_VIS2" | |
8657 | "edge16n\t%r1, %r2, %0" | |
8658 | [(set_attr "type" "edgen")]) | |
8659 | ||
8660 | (define_insn "edge16ln<P:mode>_vis" | |
8661 | [(set (match_operand:P 0 "register_operand" "=r") | |
d1947945 RH |
8662 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8663 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
c4728c6b DM |
8664 | UNSPEC_EDGE16LN))] |
8665 | "TARGET_VIS2" | |
8666 | "edge16ln\t%r1, %r2, %0" | |
8667 | [(set_attr "type" "edgen")]) | |
8668 | ||
8669 | (define_insn "edge32n<P:mode>_vis" | |
8670 | [(set (match_operand:P 0 "register_operand" "=r") | |
d1947945 RH |
8671 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8672 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
c4728c6b DM |
8673 | UNSPEC_EDGE32N))] |
8674 | "TARGET_VIS2" | |
8675 | "edge32n\t%r1, %r2, %0" | |
8676 | [(set_attr "type" "edgen")]) | |
8677 | ||
8678 | (define_insn "edge32ln<P:mode>_vis" | |
8679 | [(set (match_operand:P 0 "register_operand" "=r") | |
d1947945 RH |
8680 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8681 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
c4728c6b DM |
8682 | UNSPEC_EDGE32LN))] |
8683 | "TARGET_VIS2" | |
8684 | "edge32ln\t%r1, %r2, %0" | |
8685 | [(set_attr "type" "edge")]) | |
8686 | ||
96d7b15f DM |
8687 | ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle |
8688 | (define_insn "cmask8<P:mode>_vis" | |
8689 | [(set (reg:DI GSR_REG) | |
015e8b63 | 8690 | (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ") |
96d7b15f DM |
8691 | (reg:DI GSR_REG)] |
8692 | UNSPEC_CMASK8))] | |
8693 | "TARGET_VIS3" | |
afa3ed85 DM |
8694 | "cmask8\t%r0" |
8695 | [(set_attr "type" "fga")]) | |
96d7b15f DM |
8696 | |
8697 | (define_insn "cmask16<P:mode>_vis" | |
8698 | [(set (reg:DI GSR_REG) | |
015e8b63 | 8699 | (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ") |
96d7b15f DM |
8700 | (reg:DI GSR_REG)] |
8701 | UNSPEC_CMASK16))] | |
8702 | "TARGET_VIS3" | |
afa3ed85 DM |
8703 | "cmask16\t%r0" |
8704 | [(set_attr "type" "fga")]) | |
96d7b15f DM |
8705 | |
8706 | (define_insn "cmask32<P:mode>_vis" | |
8707 | [(set (reg:DI GSR_REG) | |
015e8b63 | 8708 | (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ") |
96d7b15f DM |
8709 | (reg:DI GSR_REG)] |
8710 | UNSPEC_CMASK32))] | |
8711 | "TARGET_VIS3" | |
afa3ed85 DM |
8712 | "cmask32\t%r0" |
8713 | [(set_attr "type" "fga")]) | |
96d7b15f DM |
8714 | |
8715 | (define_insn "fchksm16_vis" | |
8716 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
8717 | (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e") | |
8718 | (match_operand:V4HI 2 "register_operand" "e")] | |
8719 | UNSPEC_FCHKSM16))] | |
8720 | "TARGET_VIS3" | |
afa3ed85 DM |
8721 | "fchksm16\t%1, %2, %0" |
8722 | [(set_attr "type" "fga")]) | |
96d7b15f DM |
8723 | |
8724 | (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt]) | |
8725 | (define_code_attr vis3_shift_insn | |
8726 | [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")]) | |
f1c141a7 DM |
8727 | (define_code_attr vis3_shift_patname |
8728 | [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")]) | |
96d7b15f | 8729 | |
f1c141a7 | 8730 | (define_insn "v<vis3_shift_patname><mode>3" |
e00560c2 DM |
8731 | [(set (match_operand:GCM 0 "register_operand" "=<vconstr>") |
8732 | (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>") | |
8733 | (match_operand:GCM 2 "register_operand" "<vconstr>")))] | |
96d7b15f | 8734 | "TARGET_VIS3" |
afa3ed85 DM |
8735 | "<vis3_shift_insn><vbits>\t%1, %2, %0" |
8736 | [(set_attr "type" "fga")]) | |
96d7b15f DM |
8737 | |
8738 | (define_insn "pdistn<mode>_vis" | |
8739 | [(set (match_operand:P 0 "register_operand" "=r") | |
8740 | (unspec:P [(match_operand:V8QI 1 "register_operand" "e") | |
8741 | (match_operand:V8QI 2 "register_operand" "e")] | |
8742 | UNSPEC_PDISTN))] | |
8743 | "TARGET_VIS3" | |
afa3ed85 | 8744 | "pdistn\t%1, %2, %0" |
f298688c | 8745 | [(set_attr "type" "pdistn") |
afa3ed85 | 8746 | (set_attr "fptype" "double")]) |
96d7b15f DM |
8747 | |
8748 | (define_insn "fmean16_vis" | |
8749 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
8750 | (truncate:V4HI | |
8751 | (lshiftrt:V4SI | |
8752 | (plus:V4SI | |
8753 | (plus:V4SI | |
8754 | (zero_extend:V4SI | |
8755 | (match_operand:V4HI 1 "register_operand" "e")) | |
8756 | (zero_extend:V4SI | |
8757 | (match_operand:V4HI 2 "register_operand" "e"))) | |
8758 | (const_vector:V4SI [(const_int 1) (const_int 1) | |
8759 | (const_int 1) (const_int 1)])) | |
8760 | (const_int 1))))] | |
8761 | "TARGET_VIS3" | |
afa3ed85 DM |
8762 | "fmean16\t%1, %2, %0" |
8763 | [(set_attr "type" "fga")]) | |
96d7b15f | 8764 | |
8e24e409 | 8765 | (define_insn "fp<plusminus_insn>64_vis" |
e00560c2 DM |
8766 | [(set (match_operand:V1DI 0 "register_operand" "=e") |
8767 | (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e") | |
8768 | (match_operand:V1DI 2 "register_operand" "e")))] | |
96d7b15f | 8769 | "TARGET_VIS3" |
afa3ed85 DM |
8770 | "fp<plusminus_insn>64\t%1, %2, %0" |
8771 | [(set_attr "type" "fga")]) | |
96d7b15f | 8772 | |
e00560c2 | 8773 | (define_mode_iterator VASS [V4HI V2SI V2HI V1SI]) |
96d7b15f DM |
8774 | (define_code_iterator vis3_addsub_ss [ss_plus ss_minus]) |
8775 | (define_code_attr vis3_addsub_ss_insn | |
8776 | [(ss_plus "fpadds") (ss_minus "fpsubs")]) | |
f1c141a7 DM |
8777 | (define_code_attr vis3_addsub_ss_patname |
8778 | [(ss_plus "ssadd") (ss_minus "sssub")]) | |
96d7b15f | 8779 | |
f1c141a7 | 8780 | (define_insn "<vis3_addsub_ss_patname><mode>3" |
96d7b15f DM |
8781 | [(set (match_operand:VASS 0 "register_operand" "=<vconstr>") |
8782 | (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>") | |
8783 | (match_operand:VASS 2 "register_operand" "<vconstr>")))] | |
8784 | "TARGET_VIS3" | |
afa3ed85 DM |
8785 | "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0" |
8786 | [(set_attr "type" "fga")]) | |
96d7b15f DM |
8787 | |
8788 | (define_insn "fucmp<code>8<P:mode>_vis" | |
8789 | [(set (match_operand:P 0 "register_operand" "=r") | |
8790 | (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e") | |
8791 | (match_operand:V8QI 2 "register_operand" "e"))] | |
8792 | UNSPEC_FUCMP))] | |
8793 | "TARGET_VIS3" | |
afa3ed85 | 8794 | "fucmp<code>8\t%1, %2, %0" |
f298688c | 8795 | [(set_attr "type" "visl")]) |
96d7b15f | 8796 | |
facb3fd7 DM |
8797 | (define_insn "*naddsf3" |
8798 | [(set (match_operand:SF 0 "register_operand" "=f") | |
8799 | (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f") | |
8800 | (match_operand:SF 2 "register_operand" "f"))))] | |
8801 | "TARGET_VIS3" | |
8802 | "fnadds\t%1, %2, %0" | |
8803 | [(set_attr "type" "fp")]) | |
8804 | ||
8805 | (define_insn "*nadddf3" | |
8806 | [(set (match_operand:DF 0 "register_operand" "=e") | |
8807 | (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e") | |
8808 | (match_operand:DF 2 "register_operand" "e"))))] | |
8809 | "TARGET_VIS3" | |
8810 | "fnaddd\t%1, %2, %0" | |
8811 | [(set_attr "type" "fp") | |
8812 | (set_attr "fptype" "double")]) | |
8813 | ||
8814 | (define_insn "*nmulsf3" | |
8815 | [(set (match_operand:SF 0 "register_operand" "=f") | |
8816 | (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f")) | |
8817 | (match_operand:SF 2 "register_operand" "f")))] | |
8818 | "TARGET_VIS3" | |
8819 | "fnmuls\t%1, %2, %0" | |
8820 | [(set_attr "type" "fpmul")]) | |
8821 | ||
8822 | (define_insn "*nmuldf3" | |
8823 | [(set (match_operand:DF 0 "register_operand" "=e") | |
8824 | (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e")) | |
8825 | (match_operand:DF 2 "register_operand" "e")))] | |
8826 | "TARGET_VIS3" | |
8827 | "fnmuld\t%1, %2, %0" | |
8828 | [(set_attr "type" "fpmul") | |
8829 | (set_attr "fptype" "double")]) | |
8830 | ||
8831 | (define_insn "*nmuldf3_extend" | |
8832 | [(set (match_operand:DF 0 "register_operand" "=e") | |
8833 | (mult:DF (neg:DF (float_extend:DF | |
8834 | (match_operand:SF 1 "register_operand" "f"))) | |
8835 | (float_extend:DF | |
8836 | (match_operand:SF 2 "register_operand" "f"))))] | |
8837 | "TARGET_VIS3" | |
8838 | "fnsmuld\t%1, %2, %0" | |
8839 | [(set_attr "type" "fpmul") | |
8840 | (set_attr "fptype" "double")]) | |
8841 | ||
8842 | (define_insn "fhaddsf_vis" | |
8843 | [(set (match_operand:SF 0 "register_operand" "=f") | |
8844 | (unspec:SF [(match_operand:SF 1 "register_operand" "f") | |
8845 | (match_operand:SF 2 "register_operand" "f")] | |
8846 | UNSPEC_FHADD))] | |
8847 | "TARGET_VIS3" | |
8848 | "fhadds\t%1, %2, %0" | |
8849 | [(set_attr "type" "fp")]) | |
8850 | ||
8851 | (define_insn "fhadddf_vis" | |
8852 | [(set (match_operand:DF 0 "register_operand" "=f") | |
8853 | (unspec:DF [(match_operand:DF 1 "register_operand" "f") | |
8854 | (match_operand:DF 2 "register_operand" "f")] | |
8855 | UNSPEC_FHADD))] | |
8856 | "TARGET_VIS3" | |
8857 | "fhaddd\t%1, %2, %0" | |
8858 | [(set_attr "type" "fp") | |
8859 | (set_attr "fptype" "double")]) | |
8860 | ||
8861 | (define_insn "fhsubsf_vis" | |
8862 | [(set (match_operand:SF 0 "register_operand" "=f") | |
8863 | (unspec:SF [(match_operand:SF 1 "register_operand" "f") | |
8864 | (match_operand:SF 2 "register_operand" "f")] | |
8865 | UNSPEC_FHSUB))] | |
8866 | "TARGET_VIS3" | |
8867 | "fhsubs\t%1, %2, %0" | |
8868 | [(set_attr "type" "fp")]) | |
8869 | ||
8870 | (define_insn "fhsubdf_vis" | |
8871 | [(set (match_operand:DF 0 "register_operand" "=f") | |
8872 | (unspec:DF [(match_operand:DF 1 "register_operand" "f") | |
8873 | (match_operand:DF 2 "register_operand" "f")] | |
8874 | UNSPEC_FHSUB))] | |
8875 | "TARGET_VIS3" | |
8876 | "fhsubd\t%1, %2, %0" | |
8877 | [(set_attr "type" "fp") | |
8878 | (set_attr "fptype" "double")]) | |
8879 | ||
8880 | (define_insn "fnhaddsf_vis" | |
8881 | [(set (match_operand:SF 0 "register_operand" "=f") | |
8882 | (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f") | |
8883 | (match_operand:SF 2 "register_operand" "f")] | |
8884 | UNSPEC_FHADD)))] | |
8885 | "TARGET_VIS3" | |
8886 | "fnhadds\t%1, %2, %0" | |
8887 | [(set_attr "type" "fp")]) | |
8888 | ||
8889 | (define_insn "fnhadddf_vis" | |
8890 | [(set (match_operand:DF 0 "register_operand" "=f") | |
8891 | (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f") | |
8892 | (match_operand:DF 2 "register_operand" "f")] | |
8893 | UNSPEC_FHADD)))] | |
8894 | "TARGET_VIS3" | |
8895 | "fnhaddd\t%1, %2, %0" | |
8896 | [(set_attr "type" "fp") | |
8897 | (set_attr "fptype" "double")]) | |
8898 | ||
8899 | (define_expand "umulxhi_vis" | |
8900 | [(set (match_operand:DI 0 "register_operand" "") | |
8901 | (truncate:DI | |
8902 | (lshiftrt:TI | |
8903 | (mult:TI (zero_extend:TI | |
8904 | (match_operand:DI 1 "arith_operand" "")) | |
8905 | (zero_extend:TI | |
8906 | (match_operand:DI 2 "arith_operand" ""))) | |
8907 | (const_int 64))))] | |
8908 | "TARGET_VIS3" | |
8909 | { | |
8910 | if (! TARGET_ARCH64) | |
8911 | { | |
8912 | emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2])); | |
8913 | DONE; | |
8914 | } | |
8915 | }) | |
8916 | ||
8917 | (define_insn "*umulxhi_sp64" | |
8918 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8919 | (truncate:DI | |
8920 | (lshiftrt:TI | |
8921 | (mult:TI (zero_extend:TI | |
8922 | (match_operand:DI 1 "arith_operand" "%r")) | |
8923 | (zero_extend:TI | |
8924 | (match_operand:DI 2 "arith_operand" "rI"))) | |
8925 | (const_int 64))))] | |
8926 | "TARGET_VIS3 && TARGET_ARCH64" | |
8927 | "umulxhi\t%1, %2, %0" | |
8928 | [(set_attr "type" "imul")]) | |
8929 | ||
8930 | (define_insn "umulxhi_v8plus" | |
8931 | [(set (match_operand:DI 0 "register_operand" "=r,h") | |
8932 | (truncate:DI | |
8933 | (lshiftrt:TI | |
8934 | (mult:TI (zero_extend:TI | |
8935 | (match_operand:DI 1 "arith_operand" "%r,0")) | |
8936 | (zero_extend:TI | |
8937 | (match_operand:DI 2 "arith_operand" "rI,rI"))) | |
8938 | (const_int 64)))) | |
8939 | (clobber (match_scratch:SI 3 "=&h,X")) | |
8940 | (clobber (match_scratch:SI 4 "=&h,X"))] | |
8941 | "TARGET_VIS3 && ! TARGET_ARCH64" | |
8942 | "* return output_v8plus_mult (insn, operands, \"umulxhi\");" | |
8943 | [(set_attr "type" "imul") | |
8944 | (set_attr "length" "9,8")]) | |
8945 | ||
8946 | (define_expand "xmulx_vis" | |
8947 | [(set (match_operand:DI 0 "register_operand" "") | |
8948 | (truncate:DI | |
8949 | (unspec:TI [(zero_extend:TI | |
8950 | (match_operand:DI 1 "arith_operand" "")) | |
8951 | (zero_extend:TI | |
8952 | (match_operand:DI 2 "arith_operand" ""))] | |
8953 | UNSPEC_XMUL)))] | |
8954 | "TARGET_VIS3" | |
8955 | { | |
8956 | if (! TARGET_ARCH64) | |
8957 | { | |
8958 | emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2])); | |
8959 | DONE; | |
8960 | } | |
8961 | }) | |
8962 | ||
8963 | (define_insn "*xmulx_sp64" | |
8964 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8965 | (truncate:DI | |
8966 | (unspec:TI [(zero_extend:TI | |
8967 | (match_operand:DI 1 "arith_operand" "%r")) | |
8968 | (zero_extend:TI | |
8969 | (match_operand:DI 2 "arith_operand" "rI"))] | |
8970 | UNSPEC_XMUL)))] | |
8971 | "TARGET_VIS3 && TARGET_ARCH64" | |
8972 | "xmulx\t%1, %2, %0" | |
8973 | [(set_attr "type" "imul")]) | |
8974 | ||
8975 | (define_insn "xmulx_v8plus" | |
8976 | [(set (match_operand:DI 0 "register_operand" "=r,h") | |
8977 | (truncate:DI | |
8978 | (unspec:TI [(zero_extend:TI | |
8979 | (match_operand:DI 1 "arith_operand" "%r,0")) | |
8980 | (zero_extend:TI | |
8981 | (match_operand:DI 2 "arith_operand" "rI,rI"))] | |
8982 | UNSPEC_XMUL))) | |
8983 | (clobber (match_scratch:SI 3 "=&h,X")) | |
8984 | (clobber (match_scratch:SI 4 "=&h,X"))] | |
8985 | "TARGET_VIS3 && ! TARGET_ARCH64" | |
8986 | "* return output_v8plus_mult (insn, operands, \"xmulx\");" | |
8987 | [(set_attr "type" "imul") | |
8988 | (set_attr "length" "9,8")]) | |
8989 | ||
8990 | (define_expand "xmulxhi_vis" | |
8991 | [(set (match_operand:DI 0 "register_operand" "") | |
8992 | (truncate:DI | |
8993 | (lshiftrt:TI | |
8994 | (unspec:TI [(zero_extend:TI | |
8995 | (match_operand:DI 1 "arith_operand" "")) | |
8996 | (zero_extend:TI | |
8997 | (match_operand:DI 2 "arith_operand" ""))] | |
8998 | UNSPEC_XMUL) | |
8999 | (const_int 64))))] | |
9000 | "TARGET_VIS3" | |
9001 | { | |
9002 | if (! TARGET_ARCH64) | |
9003 | { | |
9004 | emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2])); | |
9005 | DONE; | |
9006 | } | |
9007 | }) | |
9008 | ||
9009 | (define_insn "*xmulxhi_sp64" | |
9010 | [(set (match_operand:DI 0 "register_operand" "=r") | |
9011 | (truncate:DI | |
9012 | (lshiftrt:TI | |
9013 | (unspec:TI [(zero_extend:TI | |
9014 | (match_operand:DI 1 "arith_operand" "%r")) | |
9015 | (zero_extend:TI | |
9016 | (match_operand:DI 2 "arith_operand" "rI"))] | |
9017 | UNSPEC_XMUL) | |
9018 | (const_int 64))))] | |
9019 | "TARGET_VIS3 && TARGET_ARCH64" | |
9020 | "xmulxhi\t%1, %2, %0" | |
9021 | [(set_attr "type" "imul")]) | |
9022 | ||
9023 | (define_insn "xmulxhi_v8plus" | |
9024 | [(set (match_operand:DI 0 "register_operand" "=r,h") | |
9025 | (truncate:DI | |
9026 | (lshiftrt:TI | |
9027 | (unspec:TI [(zero_extend:TI | |
9028 | (match_operand:DI 1 "arith_operand" "%r,0")) | |
9029 | (zero_extend:TI | |
9030 | (match_operand:DI 2 "arith_operand" "rI,rI"))] | |
9031 | UNSPEC_XMUL) | |
9032 | (const_int 64)))) | |
9033 | (clobber (match_scratch:SI 3 "=&h,X")) | |
9034 | (clobber (match_scratch:SI 4 "=&h,X"))] | |
9035 | "TARGET_VIS3 && !TARGET_ARCH64" | |
9036 | "* return output_v8plus_mult (insn, operands, \"xmulxhi\");" | |
9037 | [(set_attr "type" "imul") | |
9038 | (set_attr "length" "9,8")]) | |
9039 | ||
396b535a | 9040 | (include "sync.md") |