caf84437ecfaf6e72cdfc97b3e1bf85d6d0175c3
[gcc.git] / gcc / config / sparc / sparc.md
1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
6 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
7 ;; at Cygnus Support.
8
9 ;; This file is part of GCC.
10
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; any later version.
15
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3. If not see
23 ;; <http://www.gnu.org/licenses/>.
24
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
27 (define_constants
28 [(UNSPEC_MOVE_PIC 0)
29 (UNSPEC_UPDATE_RETURN 1)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
32 (UNSPEC_SETH44 6)
33 (UNSPEC_SETM44 7)
34 (UNSPEC_SETHH 9)
35 (UNSPEC_SETLM 10)
36 (UNSPEC_EMB_HISUM 11)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
40 (UNSPEC_EMB_SETHM 18)
41
42 (UNSPEC_MEMBAR 20)
43
44 (UNSPEC_TLSGD 30)
45 (UNSPEC_TLSLDM 31)
46 (UNSPEC_TLSLDO 32)
47 (UNSPEC_TLSIE 33)
48 (UNSPEC_TLSLE 34)
49 (UNSPEC_TLSLD_BASE 35)
50
51 (UNSPEC_FPACK16 40)
52 (UNSPEC_FPACK32 41)
53 (UNSPEC_FPACKFIX 42)
54 (UNSPEC_FEXPAND 43)
55 (UNSPEC_FPMERGE 44)
56 (UNSPEC_MUL16AL 45)
57 (UNSPEC_MUL8UL 46)
58 (UNSPEC_MULDUL 47)
59 (UNSPEC_ALIGNDATA 48)
60 (UNSPEC_ALIGNADDR 49)
61 (UNSPEC_PDIST 50)
62
63 (UNSPEC_SP_SET 60)
64 (UNSPEC_SP_TEST 61)
65 ])
66
67 (define_constants
68 [(UNSPECV_BLOCKAGE 0)
69 (UNSPECV_FLUSHW 1)
70 (UNSPECV_GOTO 2)
71 (UNSPECV_FLUSH 4)
72 (UNSPECV_SETJMP 5)
73 (UNSPECV_SAVEW 6)
74 (UNSPECV_CAS 8)
75 (UNSPECV_SWAP 9)
76 (UNSPECV_LDSTUB 10)
77 ])
78
79
80 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
81 (define_mode_iterator I [QI HI SI DI])
82 (define_mode_iterator F [SF DF TF])
83
84 ;; We don't define V1SI because SI should work just fine.
85 (define_mode_iterator V32 [SF V2HI V4QI])
86 (define_mode_iterator V32I [SI V2HI V4QI])
87
88 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
89 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
90
91 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
92 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
93 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
94 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
95 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
96
97
98 ;; Attribute for cpu type.
99 ;; These must match the values for enum processor_type in sparc.h.
100 (define_attr "cpu"
101 "v7,
102 cypress,
103 v8,
104 supersparc,
105 sparclite,f930,f934,
106 hypersparc,sparclite86x,
107 sparclet,tsc701,
108 v9,
109 ultrasparc,
110 ultrasparc3,
111 niagara,
112 niagara2"
113 (const (symbol_ref "sparc_cpu_attr")))
114
115 ;; Attribute for the instruction set.
116 ;; At present we only need to distinguish v9/!v9, but for clarity we
117 ;; test TARGET_V8 too.
118 (define_attr "isa" "v7,v8,v9,sparclet"
119 (const
120 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
121 (symbol_ref "TARGET_V8") (const_string "v8")
122 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
123 (const_string "v7"))))
124
125 ;; Insn type.
126 (define_attr "type"
127 "ialu,compare,shift,
128 load,sload,store,
129 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
130 imul,idiv,
131 fpload,fpstore,
132 fp,fpmove,
133 fpcmove,fpcrmove,
134 fpcmp,
135 fpmul,fpdivs,fpdivd,
136 fpsqrts,fpsqrtd,
137 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
138 cmove,
139 ialuX,
140 multi,savew,flushw,iflush,trap"
141 (const_string "ialu"))
142
143 ;; True if branch/call has empty delay slot and will emit a nop in it
144 (define_attr "empty_delay_slot" "false,true"
145 (symbol_ref "(empty_delay_slot (insn)
146 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
147
148 (define_attr "branch_type" "none,icc,fcc,reg"
149 (const_string "none"))
150
151 (define_attr "pic" "false,true"
152 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
153
154 (define_attr "calls_alloca" "false,true"
155 (symbol_ref "(cfun->calls_alloca != 0
156 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
157
158 (define_attr "calls_eh_return" "false,true"
159 (symbol_ref "(crtl->calls_eh_return != 0
160 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
161
162 (define_attr "leaf_function" "false,true"
163 (symbol_ref "(current_function_uses_only_leaf_regs != 0
164 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
165
166 (define_attr "delayed_branch" "false,true"
167 (symbol_ref "(flag_delayed_branch != 0
168 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
169
170 ;; Length (in # of insns).
171 ;; Beware that setting a length greater or equal to 3 for conditional branches
172 ;; has a side-effect (see output_cbranch and output_v9branch).
173 (define_attr "length" ""
174 (cond [(eq_attr "type" "uncond_branch,call")
175 (if_then_else (eq_attr "empty_delay_slot" "true")
176 (const_int 2)
177 (const_int 1))
178 (eq_attr "type" "sibcall")
179 (if_then_else (eq_attr "leaf_function" "true")
180 (if_then_else (eq_attr "empty_delay_slot" "true")
181 (const_int 3)
182 (const_int 2))
183 (if_then_else (eq_attr "empty_delay_slot" "true")
184 (const_int 2)
185 (const_int 1)))
186 (eq_attr "branch_type" "icc")
187 (if_then_else (match_operand 0 "noov_compare64_operator" "")
188 (if_then_else (lt (pc) (match_dup 1))
189 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
190 (if_then_else (eq_attr "empty_delay_slot" "true")
191 (const_int 2)
192 (const_int 1))
193 (if_then_else (eq_attr "empty_delay_slot" "true")
194 (const_int 4)
195 (const_int 3)))
196 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
197 (if_then_else (eq_attr "empty_delay_slot" "true")
198 (const_int 2)
199 (const_int 1))
200 (if_then_else (eq_attr "empty_delay_slot" "true")
201 (const_int 4)
202 (const_int 3))))
203 (if_then_else (eq_attr "empty_delay_slot" "true")
204 (const_int 2)
205 (const_int 1)))
206 (eq_attr "branch_type" "fcc")
207 (if_then_else (match_operand 0 "fcc0_register_operand" "")
208 (if_then_else (eq_attr "empty_delay_slot" "true")
209 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
210 (const_int 3)
211 (const_int 2))
212 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
213 (const_int 2)
214 (const_int 1)))
215 (if_then_else (lt (pc) (match_dup 2))
216 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
217 (if_then_else (eq_attr "empty_delay_slot" "true")
218 (const_int 2)
219 (const_int 1))
220 (if_then_else (eq_attr "empty_delay_slot" "true")
221 (const_int 4)
222 (const_int 3)))
223 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
224 (if_then_else (eq_attr "empty_delay_slot" "true")
225 (const_int 2)
226 (const_int 1))
227 (if_then_else (eq_attr "empty_delay_slot" "true")
228 (const_int 4)
229 (const_int 3)))))
230 (eq_attr "branch_type" "reg")
231 (if_then_else (lt (pc) (match_dup 2))
232 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
233 (if_then_else (eq_attr "empty_delay_slot" "true")
234 (const_int 2)
235 (const_int 1))
236 (if_then_else (eq_attr "empty_delay_slot" "true")
237 (const_int 4)
238 (const_int 3)))
239 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
240 (if_then_else (eq_attr "empty_delay_slot" "true")
241 (const_int 2)
242 (const_int 1))
243 (if_then_else (eq_attr "empty_delay_slot" "true")
244 (const_int 4)
245 (const_int 3))))
246 ] (const_int 1)))
247
248 ;; FP precision.
249 (define_attr "fptype" "single,double"
250 (const_string "single"))
251
252 ;; UltraSPARC-III integer load type.
253 (define_attr "us3load_type" "2cycle,3cycle"
254 (const_string "2cycle"))
255
256 (define_asm_attributes
257 [(set_attr "length" "2")
258 (set_attr "type" "multi")])
259
260 ;; Attributes for instruction and branch scheduling
261 (define_attr "tls_call_delay" "false,true"
262 (symbol_ref "(tls_call_delay (insn)
263 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
264
265 (define_attr "in_call_delay" "false,true"
266 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
267 (const_string "false")
268 (eq_attr "type" "load,fpload,store,fpstore")
269 (if_then_else (eq_attr "length" "1")
270 (const_string "true")
271 (const_string "false"))]
272 (if_then_else (and (eq_attr "length" "1")
273 (eq_attr "tls_call_delay" "true"))
274 (const_string "true")
275 (const_string "false"))))
276
277 (define_attr "eligible_for_sibcall_delay" "false,true"
278 (symbol_ref "(eligible_for_sibcall_delay (insn)
279 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
280 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
281
282 (define_attr "eligible_for_return_delay" "false,true"
283 (symbol_ref "(eligible_for_return_delay (insn)
284 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
285 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
286
287 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
288 ;; branches. This would allow us to remove the nop always inserted before
289 ;; a floating point branch.
290
291 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
292 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
293 ;; This is because doing so will add several pipeline stalls to the path
294 ;; that the load/store did not come from. Unfortunately, there is no way
295 ;; to prevent fill_eager_delay_slots from using load/store without completely
296 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
297 ;; because it prevents us from moving back the final store of inner loops.
298
299 (define_attr "in_branch_delay" "false,true"
300 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
301 (eq_attr "length" "1"))
302 (const_string "true")
303 (const_string "false")))
304
305 (define_attr "in_uncond_branch_delay" "false,true"
306 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
307 (eq_attr "length" "1"))
308 (const_string "true")
309 (const_string "false")))
310
311 (define_attr "in_annul_branch_delay" "false,true"
312 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
313 (eq_attr "length" "1"))
314 (const_string "true")
315 (const_string "false")))
316
317 (define_delay (eq_attr "type" "call")
318 [(eq_attr "in_call_delay" "true") (nil) (nil)])
319
320 (define_delay (eq_attr "type" "sibcall")
321 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
322
323 (define_delay (eq_attr "type" "branch")
324 [(eq_attr "in_branch_delay" "true")
325 (nil) (eq_attr "in_annul_branch_delay" "true")])
326
327 (define_delay (eq_attr "type" "uncond_branch")
328 [(eq_attr "in_uncond_branch_delay" "true")
329 (nil) (nil)])
330
331 (define_delay (eq_attr "type" "return")
332 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
333
334
335 ;; Include SPARC DFA schedulers
336
337 (include "cypress.md")
338 (include "supersparc.md")
339 (include "hypersparc.md")
340 (include "sparclet.md")
341 (include "ultra1_2.md")
342 (include "ultra3.md")
343 (include "niagara.md")
344 (include "niagara2.md")
345
346
347 ;; Operand and operator predicates and constraints
348
349 (include "predicates.md")
350 (include "constraints.md")
351
352
353 ;; Compare instructions.
354
355 ;; These are just the DEFINE_INSNs to match the patterns and the
356 ;; DEFINE_SPLITs for some of the scc insns that actually require
357 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
358
359 ;; The compare DEFINE_INSNs.
360
361 (define_insn "*cmpsi_insn"
362 [(set (reg:CC 100)
363 (compare:CC (match_operand:SI 0 "register_operand" "r")
364 (match_operand:SI 1 "arith_operand" "rI")))]
365 ""
366 "cmp\t%0, %1"
367 [(set_attr "type" "compare")])
368
369 (define_insn "*cmpdi_sp64"
370 [(set (reg:CCX 100)
371 (compare:CCX (match_operand:DI 0 "register_operand" "r")
372 (match_operand:DI 1 "arith_operand" "rI")))]
373 "TARGET_ARCH64"
374 "cmp\t%0, %1"
375 [(set_attr "type" "compare")])
376
377 (define_insn "*cmpsf_fpe"
378 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
379 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
380 (match_operand:SF 2 "register_operand" "f")))]
381 "TARGET_FPU"
382 {
383 if (TARGET_V9)
384 return "fcmpes\t%0, %1, %2";
385 return "fcmpes\t%1, %2";
386 }
387 [(set_attr "type" "fpcmp")])
388
389 (define_insn "*cmpdf_fpe"
390 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
391 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
392 (match_operand:DF 2 "register_operand" "e")))]
393 "TARGET_FPU"
394 {
395 if (TARGET_V9)
396 return "fcmped\t%0, %1, %2";
397 return "fcmped\t%1, %2";
398 }
399 [(set_attr "type" "fpcmp")
400 (set_attr "fptype" "double")])
401
402 (define_insn "*cmptf_fpe"
403 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
404 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
405 (match_operand:TF 2 "register_operand" "e")))]
406 "TARGET_FPU && TARGET_HARD_QUAD"
407 {
408 if (TARGET_V9)
409 return "fcmpeq\t%0, %1, %2";
410 return "fcmpeq\t%1, %2";
411 }
412 [(set_attr "type" "fpcmp")])
413
414 (define_insn "*cmpsf_fp"
415 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
416 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
417 (match_operand:SF 2 "register_operand" "f")))]
418 "TARGET_FPU"
419 {
420 if (TARGET_V9)
421 return "fcmps\t%0, %1, %2";
422 return "fcmps\t%1, %2";
423 }
424 [(set_attr "type" "fpcmp")])
425
426 (define_insn "*cmpdf_fp"
427 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
428 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
429 (match_operand:DF 2 "register_operand" "e")))]
430 "TARGET_FPU"
431 {
432 if (TARGET_V9)
433 return "fcmpd\t%0, %1, %2";
434 return "fcmpd\t%1, %2";
435 }
436 [(set_attr "type" "fpcmp")
437 (set_attr "fptype" "double")])
438
439 (define_insn "*cmptf_fp"
440 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
441 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
442 (match_operand:TF 2 "register_operand" "e")))]
443 "TARGET_FPU && TARGET_HARD_QUAD"
444 {
445 if (TARGET_V9)
446 return "fcmpq\t%0, %1, %2";
447 return "fcmpq\t%1, %2";
448 }
449 [(set_attr "type" "fpcmp")])
450 \f
451 ;; Next come the scc insns.
452
453 (define_expand "cstoresi4"
454 [(use (match_operator 1 "comparison_operator"
455 [(match_operand:SI 2 "compare_operand" "")
456 (match_operand:SI 3 "arith_operand" "")]))
457 (clobber (match_operand:SI 0 "register_operand"))]
458 ""
459 {
460 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
461 operands[2] = force_reg (SImode, operands[2]);
462 if (emit_scc_insn (operands)) DONE; else FAIL;
463 })
464
465 (define_expand "cstoredi4"
466 [(use (match_operator 1 "comparison_operator"
467 [(match_operand:DI 2 "compare_operand" "")
468 (match_operand:DI 3 "arith_operand" "")]))
469 (clobber (match_operand:SI 0 "register_operand"))]
470 "TARGET_ARCH64"
471 {
472 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
473 operands[2] = force_reg (DImode, operands[2]);
474 if (emit_scc_insn (operands)) DONE; else FAIL;
475 })
476
477 (define_expand "cstore<F:mode>4"
478 [(use (match_operator 1 "comparison_operator"
479 [(match_operand:F 2 "register_operand" "")
480 (match_operand:F 3 "register_operand" "")]))
481 (clobber (match_operand:SI 0 "register_operand"))]
482 "TARGET_FPU"
483 { if (emit_scc_insn (operands)) DONE; else FAIL; })
484
485 \f
486
487 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
488 ;; generate addcc/subcc instructions.
489
490 (define_expand "seqsi_special"
491 [(set (match_dup 3)
492 (xor:SI (match_operand:SI 1 "register_operand" "")
493 (match_operand:SI 2 "register_operand" "")))
494 (parallel [(set (match_operand:SI 0 "register_operand" "")
495 (eq:SI (match_dup 3) (const_int 0)))
496 (clobber (reg:CC 100))])]
497 ""
498 { operands[3] = gen_reg_rtx (SImode); })
499
500 (define_expand "seqdi_special"
501 [(set (match_dup 3)
502 (xor:DI (match_operand:DI 1 "register_operand" "")
503 (match_operand:DI 2 "register_operand" "")))
504 (set (match_operand:SI 0 "register_operand" "")
505 (eq:SI (match_dup 3) (const_int 0)))]
506 "TARGET_ARCH64"
507 { operands[3] = gen_reg_rtx (DImode); })
508
509 (define_expand "snesi_special"
510 [(set (match_dup 3)
511 (xor:SI (match_operand:SI 1 "register_operand" "")
512 (match_operand:SI 2 "register_operand" "")))
513 (parallel [(set (match_operand:SI 0 "register_operand" "")
514 (ne:SI (match_dup 3) (const_int 0)))
515 (clobber (reg:CC 100))])]
516 ""
517 { operands[3] = gen_reg_rtx (SImode); })
518
519 (define_expand "snedi_special"
520 [(set (match_dup 3)
521 (xor:DI (match_operand:DI 1 "register_operand" "")
522 (match_operand:DI 2 "register_operand" "")))
523 (set (match_operand:SI 0 "register_operand" "")
524 (ne:SI (match_dup 3) (const_int 0)))]
525 "TARGET_ARCH64"
526 { operands[3] = gen_reg_rtx (DImode); })
527
528
529 ;; Now the DEFINE_INSNs for the scc cases.
530
531 ;; The SEQ and SNE patterns are special because they can be done
532 ;; without any branching and do not involve a COMPARE. We want
533 ;; them to always use the splits below so the results can be
534 ;; scheduled.
535
536 (define_insn_and_split "*snesi_zero"
537 [(set (match_operand:SI 0 "register_operand" "=r")
538 (ne:SI (match_operand:SI 1 "register_operand" "r")
539 (const_int 0)))
540 (clobber (reg:CC 100))]
541 ""
542 "#"
543 ""
544 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
545 (const_int 0)))
546 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
547 ""
548 [(set_attr "length" "2")])
549
550 (define_insn_and_split "*neg_snesi_zero"
551 [(set (match_operand:SI 0 "register_operand" "=r")
552 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
553 (const_int 0))))
554 (clobber (reg:CC 100))]
555 ""
556 "#"
557 ""
558 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
559 (const_int 0)))
560 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
561 ""
562 [(set_attr "length" "2")])
563
564 (define_insn_and_split "*snesi_zero_extend"
565 [(set (match_operand:DI 0 "register_operand" "=r")
566 (ne:DI (match_operand:SI 1 "register_operand" "r")
567 (const_int 0)))
568 (clobber (reg:CC 100))]
569 "TARGET_ARCH64"
570 "#"
571 "&& 1"
572 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
573 (match_dup 1))
574 (const_int 0)))
575 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
576 (const_int 0))
577 (ltu:SI (reg:CC_NOOV 100)
578 (const_int 0)))))]
579 ""
580 [(set_attr "length" "2")])
581
582 (define_insn_and_split "*snedi_zero"
583 [(set (match_operand:DI 0 "register_operand" "=&r")
584 (ne:DI (match_operand:DI 1 "register_operand" "r")
585 (const_int 0)))]
586 "TARGET_ARCH64"
587 "#"
588 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
589 [(set (match_dup 0) (const_int 0))
590 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
591 (const_int 0))
592 (const_int 1)
593 (match_dup 0)))]
594 ""
595 [(set_attr "length" "2")])
596
597 (define_insn_and_split "*neg_snedi_zero"
598 [(set (match_operand:DI 0 "register_operand" "=&r")
599 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
600 (const_int 0))))]
601 "TARGET_ARCH64"
602 "#"
603 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
604 [(set (match_dup 0) (const_int 0))
605 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
606 (const_int 0))
607 (const_int -1)
608 (match_dup 0)))]
609 ""
610 [(set_attr "length" "2")])
611
612 (define_insn_and_split "*snedi_zero_trunc"
613 [(set (match_operand:SI 0 "register_operand" "=&r")
614 (ne:SI (match_operand:DI 1 "register_operand" "r")
615 (const_int 0)))]
616 "TARGET_ARCH64"
617 "#"
618 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
619 [(set (match_dup 0) (const_int 0))
620 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
621 (const_int 0))
622 (const_int 1)
623 (match_dup 0)))]
624 ""
625 [(set_attr "length" "2")])
626
627 (define_insn_and_split "*seqsi_zero"
628 [(set (match_operand:SI 0 "register_operand" "=r")
629 (eq:SI (match_operand:SI 1 "register_operand" "r")
630 (const_int 0)))
631 (clobber (reg:CC 100))]
632 ""
633 "#"
634 ""
635 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
636 (const_int 0)))
637 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
638 ""
639 [(set_attr "length" "2")])
640
641 (define_insn_and_split "*neg_seqsi_zero"
642 [(set (match_operand:SI 0 "register_operand" "=r")
643 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
644 (const_int 0))))
645 (clobber (reg:CC 100))]
646 ""
647 "#"
648 ""
649 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
650 (const_int 0)))
651 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
652 ""
653 [(set_attr "length" "2")])
654
655 (define_insn_and_split "*seqsi_zero_extend"
656 [(set (match_operand:DI 0 "register_operand" "=r")
657 (eq:DI (match_operand:SI 1 "register_operand" "r")
658 (const_int 0)))
659 (clobber (reg:CC 100))]
660 "TARGET_ARCH64"
661 "#"
662 "&& 1"
663 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
664 (match_dup 1))
665 (const_int 0)))
666 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
667 (const_int -1))
668 (ltu:SI (reg:CC_NOOV 100)
669 (const_int 0)))))]
670 ""
671 [(set_attr "length" "2")])
672
673 (define_insn_and_split "*seqdi_zero"
674 [(set (match_operand:DI 0 "register_operand" "=&r")
675 (eq:DI (match_operand:DI 1 "register_operand" "r")
676 (const_int 0)))]
677 "TARGET_ARCH64"
678 "#"
679 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
680 [(set (match_dup 0) (const_int 0))
681 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
682 (const_int 0))
683 (const_int 1)
684 (match_dup 0)))]
685 ""
686 [(set_attr "length" "2")])
687
688 (define_insn_and_split "*neg_seqdi_zero"
689 [(set (match_operand:DI 0 "register_operand" "=&r")
690 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
691 (const_int 0))))]
692 "TARGET_ARCH64"
693 "#"
694 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
695 [(set (match_dup 0) (const_int 0))
696 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
697 (const_int 0))
698 (const_int -1)
699 (match_dup 0)))]
700 ""
701 [(set_attr "length" "2")])
702
703 (define_insn_and_split "*seqdi_zero_trunc"
704 [(set (match_operand:SI 0 "register_operand" "=&r")
705 (eq:SI (match_operand:DI 1 "register_operand" "r")
706 (const_int 0)))]
707 "TARGET_ARCH64"
708 "#"
709 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
710 [(set (match_dup 0) (const_int 0))
711 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
712 (const_int 0))
713 (const_int 1)
714 (match_dup 0)))]
715 ""
716 [(set_attr "length" "2")])
717
718 ;; We can also do (x + (i == 0)) and related, so put them in.
719 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
720 ;; versions for v9.
721
722 (define_insn_and_split "*x_plus_i_ne_0"
723 [(set (match_operand:SI 0 "register_operand" "=r")
724 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
725 (const_int 0))
726 (match_operand:SI 2 "register_operand" "r")))
727 (clobber (reg:CC 100))]
728 ""
729 "#"
730 ""
731 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
732 (const_int 0)))
733 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
734 (match_dup 2)))]
735 ""
736 [(set_attr "length" "2")])
737
738 (define_insn_and_split "*x_minus_i_ne_0"
739 [(set (match_operand:SI 0 "register_operand" "=r")
740 (minus:SI (match_operand:SI 2 "register_operand" "r")
741 (ne:SI (match_operand:SI 1 "register_operand" "r")
742 (const_int 0))))
743 (clobber (reg:CC 100))]
744 ""
745 "#"
746 ""
747 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
748 (const_int 0)))
749 (set (match_dup 0) (minus:SI (match_dup 2)
750 (ltu:SI (reg:CC 100) (const_int 0))))]
751 ""
752 [(set_attr "length" "2")])
753
754 (define_insn_and_split "*x_plus_i_eq_0"
755 [(set (match_operand:SI 0 "register_operand" "=r")
756 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
757 (const_int 0))
758 (match_operand:SI 2 "register_operand" "r")))
759 (clobber (reg:CC 100))]
760 ""
761 "#"
762 ""
763 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
764 (const_int 0)))
765 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
766 (match_dup 2)))]
767 ""
768 [(set_attr "length" "2")])
769
770 (define_insn_and_split "*x_minus_i_eq_0"
771 [(set (match_operand:SI 0 "register_operand" "=r")
772 (minus:SI (match_operand:SI 2 "register_operand" "r")
773 (eq:SI (match_operand:SI 1 "register_operand" "r")
774 (const_int 0))))
775 (clobber (reg:CC 100))]
776 ""
777 "#"
778 ""
779 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
780 (const_int 0)))
781 (set (match_dup 0) (minus:SI (match_dup 2)
782 (geu:SI (reg:CC 100) (const_int 0))))]
783 ""
784 [(set_attr "length" "2")])
785
786 ;; We can also do GEU and LTU directly, but these operate after a compare.
787 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
788 ;; versions for v9.
789
790 (define_insn "*sltu_insn"
791 [(set (match_operand:SI 0 "register_operand" "=r")
792 (ltu:SI (reg:CC 100) (const_int 0)))]
793 ""
794 "addx\t%%g0, 0, %0"
795 [(set_attr "type" "ialuX")])
796
797 (define_insn "*neg_sltu_insn"
798 [(set (match_operand:SI 0 "register_operand" "=r")
799 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
800 ""
801 "subx\t%%g0, 0, %0"
802 [(set_attr "type" "ialuX")])
803
804 ;; ??? Combine should canonicalize these next two to the same pattern.
805 (define_insn "*neg_sltu_minus_x"
806 [(set (match_operand:SI 0 "register_operand" "=r")
807 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
808 (match_operand:SI 1 "arith_operand" "rI")))]
809 ""
810 "subx\t%%g0, %1, %0"
811 [(set_attr "type" "ialuX")])
812
813 (define_insn "*neg_sltu_plus_x"
814 [(set (match_operand:SI 0 "register_operand" "=r")
815 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
816 (match_operand:SI 1 "arith_operand" "rI"))))]
817 ""
818 "subx\t%%g0, %1, %0"
819 [(set_attr "type" "ialuX")])
820
821 (define_insn "*sgeu_insn"
822 [(set (match_operand:SI 0 "register_operand" "=r")
823 (geu:SI (reg:CC 100) (const_int 0)))]
824 ""
825 "subx\t%%g0, -1, %0"
826 [(set_attr "type" "ialuX")])
827
828 (define_insn "*neg_sgeu_insn"
829 [(set (match_operand:SI 0 "register_operand" "=r")
830 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
831 ""
832 "addx\t%%g0, -1, %0"
833 [(set_attr "type" "ialuX")])
834
835 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
836 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
837 ;; versions for v9.
838
839 (define_insn "*sltu_plus_x"
840 [(set (match_operand:SI 0 "register_operand" "=r")
841 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
842 (match_operand:SI 1 "arith_operand" "rI")))]
843 ""
844 "addx\t%%g0, %1, %0"
845 [(set_attr "type" "ialuX")])
846
847 (define_insn "*sltu_plus_x_plus_y"
848 [(set (match_operand:SI 0 "register_operand" "=r")
849 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
850 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
851 (match_operand:SI 2 "arith_operand" "rI"))))]
852 ""
853 "addx\t%1, %2, %0"
854 [(set_attr "type" "ialuX")])
855
856 (define_insn "*x_minus_sltu"
857 [(set (match_operand:SI 0 "register_operand" "=r")
858 (minus:SI (match_operand:SI 1 "register_operand" "r")
859 (ltu:SI (reg:CC 100) (const_int 0))))]
860 ""
861 "subx\t%1, 0, %0"
862 [(set_attr "type" "ialuX")])
863
864 ;; ??? Combine should canonicalize these next two to the same pattern.
865 (define_insn "*x_minus_y_minus_sltu"
866 [(set (match_operand:SI 0 "register_operand" "=r")
867 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
868 (match_operand:SI 2 "arith_operand" "rI"))
869 (ltu:SI (reg:CC 100) (const_int 0))))]
870 ""
871 "subx\t%r1, %2, %0"
872 [(set_attr "type" "ialuX")])
873
874 (define_insn "*x_minus_sltu_plus_y"
875 [(set (match_operand:SI 0 "register_operand" "=r")
876 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
877 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
878 (match_operand:SI 2 "arith_operand" "rI"))))]
879 ""
880 "subx\t%r1, %2, %0"
881 [(set_attr "type" "ialuX")])
882
883 (define_insn "*sgeu_plus_x"
884 [(set (match_operand:SI 0 "register_operand" "=r")
885 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
886 (match_operand:SI 1 "register_operand" "r")))]
887 ""
888 "subx\t%1, -1, %0"
889 [(set_attr "type" "ialuX")])
890
891 (define_insn "*x_minus_sgeu"
892 [(set (match_operand:SI 0 "register_operand" "=r")
893 (minus:SI (match_operand:SI 1 "register_operand" "r")
894 (geu:SI (reg:CC 100) (const_int 0))))]
895 ""
896 "addx\t%1, -1, %0"
897 [(set_attr "type" "ialuX")])
898
899 (define_split
900 [(set (match_operand:SI 0 "register_operand" "")
901 (match_operator:SI 2 "noov_compare_operator"
902 [(match_operand 1 "icc_or_fcc_register_operand" "")
903 (const_int 0)]))]
904 "TARGET_V9
905 && REGNO (operands[1]) == SPARC_ICC_REG
906 && (GET_MODE (operands[1]) == CCXmode
907 /* 32-bit LTU/GEU are better implemented using addx/subx. */
908 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
909 [(set (match_dup 0) (const_int 0))
910 (set (match_dup 0)
911 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
912 (const_int 1)
913 (match_dup 0)))]
914 "")
915
916 \f
917 ;; These control RTL generation for conditional jump insns
918
919 (define_expand "cbranchcc4"
920 [(set (pc)
921 (if_then_else (match_operator 0 "comparison_operator"
922 [(match_operand 1 "compare_operand" "")
923 (match_operand 2 "const_zero_operand" "")])
924 (label_ref (match_operand 3 "" ""))
925 (pc)))]
926 ""
927 "")
928
929 (define_expand "cbranchsi4"
930 [(use (match_operator 0 "comparison_operator"
931 [(match_operand:SI 1 "compare_operand" "")
932 (match_operand:SI 2 "arith_operand" "")]))
933 (use (match_operand 3 ""))]
934 ""
935 {
936 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
937 operands[1] = force_reg (SImode, operands[1]);
938 emit_conditional_branch_insn (operands);
939 DONE;
940 })
941
942 (define_expand "cbranchdi4"
943 [(use (match_operator 0 "comparison_operator"
944 [(match_operand:DI 1 "compare_operand" "")
945 (match_operand:DI 2 "arith_operand" "")]))
946 (use (match_operand 3 ""))]
947 "TARGET_ARCH64"
948 {
949 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
950 operands[1] = force_reg (DImode, operands[1]);
951 emit_conditional_branch_insn (operands);
952 DONE;
953 })
954
955 (define_expand "cbranch<F:mode>4"
956 [(use (match_operator 0 "comparison_operator"
957 [(match_operand:F 1 "register_operand" "")
958 (match_operand:F 2 "register_operand" "")]))
959 (use (match_operand 3 ""))]
960 "TARGET_FPU"
961 { emit_conditional_branch_insn (operands); DONE; })
962
963
964 ;; Now match both normal and inverted jump.
965
966 ;; XXX fpcmp nop braindamage
967 (define_insn "*normal_branch"
968 [(set (pc)
969 (if_then_else (match_operator 0 "noov_compare_operator"
970 [(reg 100) (const_int 0)])
971 (label_ref (match_operand 1 "" ""))
972 (pc)))]
973 ""
974 {
975 return output_cbranch (operands[0], operands[1], 1, 0,
976 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
977 insn);
978 }
979 [(set_attr "type" "branch")
980 (set_attr "branch_type" "icc")])
981
982 ;; XXX fpcmp nop braindamage
983 (define_insn "*inverted_branch"
984 [(set (pc)
985 (if_then_else (match_operator 0 "noov_compare_operator"
986 [(reg 100) (const_int 0)])
987 (pc)
988 (label_ref (match_operand 1 "" ""))))]
989 ""
990 {
991 return output_cbranch (operands[0], operands[1], 1, 1,
992 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
993 insn);
994 }
995 [(set_attr "type" "branch")
996 (set_attr "branch_type" "icc")])
997
998 ;; XXX fpcmp nop braindamage
999 (define_insn "*normal_fp_branch"
1000 [(set (pc)
1001 (if_then_else (match_operator 1 "comparison_operator"
1002 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1003 (const_int 0)])
1004 (label_ref (match_operand 2 "" ""))
1005 (pc)))]
1006 ""
1007 {
1008 return output_cbranch (operands[1], operands[2], 2, 0,
1009 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1010 insn);
1011 }
1012 [(set_attr "type" "branch")
1013 (set_attr "branch_type" "fcc")])
1014
1015 ;; XXX fpcmp nop braindamage
1016 (define_insn "*inverted_fp_branch"
1017 [(set (pc)
1018 (if_then_else (match_operator 1 "comparison_operator"
1019 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1020 (const_int 0)])
1021 (pc)
1022 (label_ref (match_operand 2 "" ""))))]
1023 ""
1024 {
1025 return output_cbranch (operands[1], operands[2], 2, 1,
1026 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1027 insn);
1028 }
1029 [(set_attr "type" "branch")
1030 (set_attr "branch_type" "fcc")])
1031
1032 ;; XXX fpcmp nop braindamage
1033 (define_insn "*normal_fpe_branch"
1034 [(set (pc)
1035 (if_then_else (match_operator 1 "comparison_operator"
1036 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1037 (const_int 0)])
1038 (label_ref (match_operand 2 "" ""))
1039 (pc)))]
1040 ""
1041 {
1042 return output_cbranch (operands[1], operands[2], 2, 0,
1043 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1044 insn);
1045 }
1046 [(set_attr "type" "branch")
1047 (set_attr "branch_type" "fcc")])
1048
1049 ;; XXX fpcmp nop braindamage
1050 (define_insn "*inverted_fpe_branch"
1051 [(set (pc)
1052 (if_then_else (match_operator 1 "comparison_operator"
1053 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1054 (const_int 0)])
1055 (pc)
1056 (label_ref (match_operand 2 "" ""))))]
1057 ""
1058 {
1059 return output_cbranch (operands[1], operands[2], 2, 1,
1060 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1061 insn);
1062 }
1063 [(set_attr "type" "branch")
1064 (set_attr "branch_type" "fcc")])
1065
1066 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1067 ;; in the architecture.
1068
1069 ;; There are no 32 bit brreg insns.
1070
1071 ;; XXX
1072 (define_insn "*normal_int_branch_sp64"
1073 [(set (pc)
1074 (if_then_else (match_operator 0 "v9_register_compare_operator"
1075 [(match_operand:DI 1 "register_operand" "r")
1076 (const_int 0)])
1077 (label_ref (match_operand 2 "" ""))
1078 (pc)))]
1079 "TARGET_ARCH64"
1080 {
1081 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1082 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1083 insn);
1084 }
1085 [(set_attr "type" "branch")
1086 (set_attr "branch_type" "reg")])
1087
1088 ;; XXX
1089 (define_insn "*inverted_int_branch_sp64"
1090 [(set (pc)
1091 (if_then_else (match_operator 0 "v9_register_compare_operator"
1092 [(match_operand:DI 1 "register_operand" "r")
1093 (const_int 0)])
1094 (pc)
1095 (label_ref (match_operand 2 "" ""))))]
1096 "TARGET_ARCH64"
1097 {
1098 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1099 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1100 insn);
1101 }
1102 [(set_attr "type" "branch")
1103 (set_attr "branch_type" "reg")])
1104
1105
1106 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1107 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1108 ;; that adds the PC value at the call point to operand 0.
1109
1110 (define_insn "load_pcrel_sym<P:mode>"
1111 [(set (match_operand:P 0 "register_operand" "=r")
1112 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1113 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1114 (clobber (reg:P 15))]
1115 ""
1116 {
1117 if (flag_delayed_branch)
1118 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1119 else
1120 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1121 }
1122 [(set (attr "type") (const_string "multi"))
1123 (set (attr "length")
1124 (if_then_else (eq_attr "delayed_branch" "true")
1125 (const_int 3)
1126 (const_int 4)))])
1127
1128
1129 ;; Integer move instructions
1130
1131 (define_expand "movqi"
1132 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1133 (match_operand:QI 1 "general_operand" ""))]
1134 ""
1135 {
1136 if (sparc_expand_move (QImode, operands))
1137 DONE;
1138 })
1139
1140 (define_insn "*movqi_insn"
1141 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1142 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1143 "(register_operand (operands[0], QImode)
1144 || register_or_zero_operand (operands[1], QImode))"
1145 "@
1146 mov\t%1, %0
1147 ldub\t%1, %0
1148 stb\t%r1, %0"
1149 [(set_attr "type" "*,load,store")
1150 (set_attr "us3load_type" "*,3cycle,*")])
1151
1152 (define_expand "movhi"
1153 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1154 (match_operand:HI 1 "general_operand" ""))]
1155 ""
1156 {
1157 if (sparc_expand_move (HImode, operands))
1158 DONE;
1159 })
1160
1161 (define_insn "*movhi_insn"
1162 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1163 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1164 "(register_operand (operands[0], HImode)
1165 || register_or_zero_operand (operands[1], HImode))"
1166 "@
1167 mov\t%1, %0
1168 sethi\t%%hi(%a1), %0
1169 lduh\t%1, %0
1170 sth\t%r1, %0"
1171 [(set_attr "type" "*,*,load,store")
1172 (set_attr "us3load_type" "*,*,3cycle,*")])
1173
1174 ;; We always work with constants here.
1175 (define_insn "*movhi_lo_sum"
1176 [(set (match_operand:HI 0 "register_operand" "=r")
1177 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1178 (match_operand:HI 2 "small_int_operand" "I")))]
1179 ""
1180 "or\t%1, %2, %0")
1181
1182 (define_expand "movsi"
1183 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1184 (match_operand:SI 1 "general_operand" ""))]
1185 ""
1186 {
1187 if (sparc_expand_move (SImode, operands))
1188 DONE;
1189 })
1190
1191 (define_insn "*movsi_insn"
1192 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1193 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1194 "(register_operand (operands[0], SImode)
1195 || register_or_zero_operand (operands[1], SImode))"
1196 "@
1197 mov\t%1, %0
1198 sethi\t%%hi(%a1), %0
1199 ld\t%1, %0
1200 st\t%r1, %0
1201 fmovs\t%1, %0
1202 ld\t%1, %0
1203 st\t%1, %0
1204 fzeros\t%0"
1205 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1206
1207 (define_insn "*movsi_lo_sum"
1208 [(set (match_operand:SI 0 "register_operand" "=r")
1209 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1210 (match_operand:SI 2 "immediate_operand" "in")))]
1211 ""
1212 "or\t%1, %%lo(%a2), %0")
1213
1214 (define_insn "*movsi_high"
1215 [(set (match_operand:SI 0 "register_operand" "=r")
1216 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1217 ""
1218 "sethi\t%%hi(%a1), %0")
1219
1220 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1221 ;; so that CSE won't optimize the address computation away.
1222 (define_insn "movsi_lo_sum_pic"
1223 [(set (match_operand:SI 0 "register_operand" "=r")
1224 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1225 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1226 "flag_pic"
1227 "or\t%1, %%lo(%a2), %0")
1228
1229 (define_insn "movsi_high_pic"
1230 [(set (match_operand:SI 0 "register_operand" "=r")
1231 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1232 "flag_pic && check_pic (1)"
1233 "sethi\t%%hi(%a1), %0")
1234
1235 (define_expand "movsi_pic_label_ref"
1236 [(set (match_dup 3) (high:SI
1237 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1238 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1239 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1240 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1241 (set (match_operand:SI 0 "register_operand" "=r")
1242 (minus:SI (match_dup 5) (match_dup 4)))]
1243 "flag_pic"
1244 {
1245 crtl->uses_pic_offset_table = 1;
1246 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1247 if (!can_create_pseudo_p ())
1248 {
1249 operands[3] = operands[0];
1250 operands[4] = operands[0];
1251 }
1252 else
1253 {
1254 operands[3] = gen_reg_rtx (SImode);
1255 operands[4] = gen_reg_rtx (SImode);
1256 }
1257 operands[5] = pic_offset_table_rtx;
1258 })
1259
1260 (define_insn "*movsi_high_pic_label_ref"
1261 [(set (match_operand:SI 0 "register_operand" "=r")
1262 (high:SI
1263 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1264 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1265 "flag_pic"
1266 "sethi\t%%hi(%a2-(%a1-.)), %0")
1267
1268 (define_insn "*movsi_lo_sum_pic_label_ref"
1269 [(set (match_operand:SI 0 "register_operand" "=r")
1270 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1271 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1272 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1273 "flag_pic"
1274 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1275
1276 ;; Set up the PIC register for VxWorks.
1277
1278 (define_expand "vxworks_load_got"
1279 [(set (match_dup 0)
1280 (high:SI (match_dup 1)))
1281 (set (match_dup 0)
1282 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1283 (set (match_dup 0)
1284 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1285 "TARGET_VXWORKS_RTP"
1286 {
1287 operands[0] = pic_offset_table_rtx;
1288 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1289 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1290 })
1291
1292 (define_expand "movdi"
1293 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1294 (match_operand:DI 1 "general_operand" ""))]
1295 ""
1296 {
1297 if (sparc_expand_move (DImode, operands))
1298 DONE;
1299 })
1300
1301 ;; Be careful, fmovd does not exist when !v9.
1302 ;; We match MEM moves directly when we have correct even
1303 ;; numbered registers, but fall into splits otherwise.
1304 ;; The constraint ordering here is really important to
1305 ;; avoid insane problems in reload, especially for patterns
1306 ;; of the form:
1307 ;;
1308 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1309 ;; (const_int -5016)))
1310 ;; (reg:DI 2 %g2))
1311 ;;
1312
1313 (define_insn "*movdi_insn_sp32"
1314 [(set (match_operand:DI 0 "nonimmediate_operand"
1315 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1316 (match_operand:DI 1 "input_operand"
1317 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1318 "! TARGET_V9
1319 && (register_operand (operands[0], DImode)
1320 || register_or_zero_operand (operands[1], DImode))"
1321 "@
1322 #
1323 std\t%1, %0
1324 ldd\t%1, %0
1325 #
1326 #
1327 #
1328 #
1329 std\t%1, %0
1330 ldd\t%1, %0
1331 #
1332 #
1333 #"
1334 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1335 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1336
1337 (define_insn "*movdi_insn_sp32_v9"
1338 [(set (match_operand:DI 0 "nonimmediate_operand"
1339 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1340 (match_operand:DI 1 "input_operand"
1341 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1342 "! TARGET_ARCH64
1343 && TARGET_V9
1344 && (register_operand (operands[0], DImode)
1345 || register_or_zero_operand (operands[1], DImode))"
1346 "@
1347 stx\t%%g0, %0
1348 #
1349 std\t%1, %0
1350 ldd\t%1, %0
1351 #
1352 #
1353 #
1354 #
1355 std\t%1, %0
1356 ldd\t%1, %0
1357 #
1358 #
1359 fmovd\\t%1, %0
1360 ldd\\t%1, %0
1361 std\\t%1, %0"
1362 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1363 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1364 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1365
1366 (define_insn "*movdi_insn_sp64"
1367 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1368 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1369 "TARGET_ARCH64
1370 && (register_operand (operands[0], DImode)
1371 || register_or_zero_operand (operands[1], DImode))"
1372 "@
1373 mov\t%1, %0
1374 sethi\t%%hi(%a1), %0
1375 ldx\t%1, %0
1376 stx\t%r1, %0
1377 fmovd\t%1, %0
1378 ldd\t%1, %0
1379 std\t%1, %0
1380 fzero\t%0"
1381 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1382 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1383
1384 (define_expand "movdi_pic_label_ref"
1385 [(set (match_dup 3) (high:DI
1386 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1387 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1388 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1389 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1390 (set (match_operand:DI 0 "register_operand" "=r")
1391 (minus:DI (match_dup 5) (match_dup 4)))]
1392 "TARGET_ARCH64 && flag_pic"
1393 {
1394 crtl->uses_pic_offset_table = 1;
1395 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1396 if (!can_create_pseudo_p ())
1397 {
1398 operands[3] = operands[0];
1399 operands[4] = operands[0];
1400 }
1401 else
1402 {
1403 operands[3] = gen_reg_rtx (DImode);
1404 operands[4] = gen_reg_rtx (DImode);
1405 }
1406 operands[5] = pic_offset_table_rtx;
1407 })
1408
1409 (define_insn "*movdi_high_pic_label_ref"
1410 [(set (match_operand:DI 0 "register_operand" "=r")
1411 (high:DI
1412 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1413 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1414 "TARGET_ARCH64 && flag_pic"
1415 "sethi\t%%hi(%a2-(%a1-.)), %0")
1416
1417 (define_insn "*movdi_lo_sum_pic_label_ref"
1418 [(set (match_operand:DI 0 "register_operand" "=r")
1419 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1420 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1421 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1422 "TARGET_ARCH64 && flag_pic"
1423 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1424
1425 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1426 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1427
1428 (define_insn "movdi_lo_sum_pic"
1429 [(set (match_operand:DI 0 "register_operand" "=r")
1430 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1431 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1432 "TARGET_ARCH64 && flag_pic"
1433 "or\t%1, %%lo(%a2), %0")
1434
1435 (define_insn "movdi_high_pic"
1436 [(set (match_operand:DI 0 "register_operand" "=r")
1437 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1438 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1439 "sethi\t%%hi(%a1), %0")
1440
1441 (define_insn "*sethi_di_medlow_embmedany_pic"
1442 [(set (match_operand:DI 0 "register_operand" "=r")
1443 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1444 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1445 "sethi\t%%hi(%a1), %0")
1446
1447 (define_insn "*sethi_di_medlow"
1448 [(set (match_operand:DI 0 "register_operand" "=r")
1449 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1450 "TARGET_CM_MEDLOW && check_pic (1)"
1451 "sethi\t%%hi(%a1), %0")
1452
1453 (define_insn "*losum_di_medlow"
1454 [(set (match_operand:DI 0 "register_operand" "=r")
1455 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1456 (match_operand:DI 2 "symbolic_operand" "")))]
1457 "TARGET_CM_MEDLOW"
1458 "or\t%1, %%lo(%a2), %0")
1459
1460 (define_insn "seth44"
1461 [(set (match_operand:DI 0 "register_operand" "=r")
1462 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1463 "TARGET_CM_MEDMID"
1464 "sethi\t%%h44(%a1), %0")
1465
1466 (define_insn "setm44"
1467 [(set (match_operand:DI 0 "register_operand" "=r")
1468 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1469 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1470 "TARGET_CM_MEDMID"
1471 "or\t%1, %%m44(%a2), %0")
1472
1473 (define_insn "setl44"
1474 [(set (match_operand:DI 0 "register_operand" "=r")
1475 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1476 (match_operand:DI 2 "symbolic_operand" "")))]
1477 "TARGET_CM_MEDMID"
1478 "or\t%1, %%l44(%a2), %0")
1479
1480 (define_insn "sethh"
1481 [(set (match_operand:DI 0 "register_operand" "=r")
1482 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1483 "TARGET_CM_MEDANY"
1484 "sethi\t%%hh(%a1), %0")
1485
1486 (define_insn "setlm"
1487 [(set (match_operand:DI 0 "register_operand" "=r")
1488 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1489 "TARGET_CM_MEDANY"
1490 "sethi\t%%lm(%a1), %0")
1491
1492 (define_insn "sethm"
1493 [(set (match_operand:DI 0 "register_operand" "=r")
1494 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1495 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1496 "TARGET_CM_MEDANY"
1497 "or\t%1, %%hm(%a2), %0")
1498
1499 (define_insn "setlo"
1500 [(set (match_operand:DI 0 "register_operand" "=r")
1501 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1502 (match_operand:DI 2 "symbolic_operand" "")))]
1503 "TARGET_CM_MEDANY"
1504 "or\t%1, %%lo(%a2), %0")
1505
1506 (define_insn "embmedany_sethi"
1507 [(set (match_operand:DI 0 "register_operand" "=r")
1508 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1509 "TARGET_CM_EMBMEDANY && check_pic (1)"
1510 "sethi\t%%hi(%a1), %0")
1511
1512 (define_insn "embmedany_losum"
1513 [(set (match_operand:DI 0 "register_operand" "=r")
1514 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1515 (match_operand:DI 2 "data_segment_operand" "")))]
1516 "TARGET_CM_EMBMEDANY"
1517 "add\t%1, %%lo(%a2), %0")
1518
1519 (define_insn "embmedany_brsum"
1520 [(set (match_operand:DI 0 "register_operand" "=r")
1521 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1522 "TARGET_CM_EMBMEDANY"
1523 "add\t%1, %_, %0")
1524
1525 (define_insn "embmedany_textuhi"
1526 [(set (match_operand:DI 0 "register_operand" "=r")
1527 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1528 "TARGET_CM_EMBMEDANY && check_pic (1)"
1529 "sethi\t%%uhi(%a1), %0")
1530
1531 (define_insn "embmedany_texthi"
1532 [(set (match_operand:DI 0 "register_operand" "=r")
1533 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1534 "TARGET_CM_EMBMEDANY && check_pic (1)"
1535 "sethi\t%%hi(%a1), %0")
1536
1537 (define_insn "embmedany_textulo"
1538 [(set (match_operand:DI 0 "register_operand" "=r")
1539 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1540 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1541 "TARGET_CM_EMBMEDANY"
1542 "or\t%1, %%ulo(%a2), %0")
1543
1544 (define_insn "embmedany_textlo"
1545 [(set (match_operand:DI 0 "register_operand" "=r")
1546 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1547 (match_operand:DI 2 "text_segment_operand" "")))]
1548 "TARGET_CM_EMBMEDANY"
1549 "or\t%1, %%lo(%a2), %0")
1550
1551 ;; Now some patterns to help reload out a bit.
1552 (define_expand "reload_indi"
1553 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1554 (match_operand:DI 1 "immediate_operand" "")
1555 (match_operand:TI 2 "register_operand" "=&r")])]
1556 "(TARGET_CM_MEDANY
1557 || TARGET_CM_EMBMEDANY)
1558 && ! flag_pic"
1559 {
1560 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1561 DONE;
1562 })
1563
1564 (define_expand "reload_outdi"
1565 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1566 (match_operand:DI 1 "immediate_operand" "")
1567 (match_operand:TI 2 "register_operand" "=&r")])]
1568 "(TARGET_CM_MEDANY
1569 || TARGET_CM_EMBMEDANY)
1570 && ! flag_pic"
1571 {
1572 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1573 DONE;
1574 })
1575
1576 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1577 (define_split
1578 [(set (match_operand:DI 0 "register_operand" "")
1579 (match_operand:DI 1 "const_int_operand" ""))]
1580 "! TARGET_ARCH64 && reload_completed"
1581 [(clobber (const_int 0))]
1582 {
1583 #if HOST_BITS_PER_WIDE_INT == 32
1584 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1585 (INTVAL (operands[1]) < 0) ?
1586 constm1_rtx :
1587 const0_rtx));
1588 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1589 operands[1]));
1590 #else
1591 unsigned int low, high;
1592
1593 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1594 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1595 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1596
1597 /* Slick... but this trick loses if this subreg constant part
1598 can be done in one insn. */
1599 if (low == high
1600 && ! SPARC_SETHI32_P (high)
1601 && ! SPARC_SIMM13_P (high))
1602 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1603 gen_highpart (SImode, operands[0])));
1604 else
1605 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1606 #endif
1607 DONE;
1608 })
1609
1610 (define_split
1611 [(set (match_operand:DI 0 "register_operand" "")
1612 (match_operand:DI 1 "const_double_operand" ""))]
1613 "reload_completed
1614 && (! TARGET_V9
1615 || (! TARGET_ARCH64
1616 && ((GET_CODE (operands[0]) == REG
1617 && REGNO (operands[0]) < 32)
1618 || (GET_CODE (operands[0]) == SUBREG
1619 && GET_CODE (SUBREG_REG (operands[0])) == REG
1620 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1621 [(clobber (const_int 0))]
1622 {
1623 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1624 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1625
1626 /* Slick... but this trick loses if this subreg constant part
1627 can be done in one insn. */
1628 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1629 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1630 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1631 {
1632 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1633 gen_highpart (SImode, operands[0])));
1634 }
1635 else
1636 {
1637 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1638 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1639 }
1640 DONE;
1641 })
1642
1643 (define_split
1644 [(set (match_operand:DI 0 "register_operand" "")
1645 (match_operand:DI 1 "register_operand" ""))]
1646 "reload_completed
1647 && (! TARGET_V9
1648 || (! TARGET_ARCH64
1649 && ((GET_CODE (operands[0]) == REG
1650 && REGNO (operands[0]) < 32)
1651 || (GET_CODE (operands[0]) == SUBREG
1652 && GET_CODE (SUBREG_REG (operands[0])) == REG
1653 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1654 [(clobber (const_int 0))]
1655 {
1656 rtx set_dest = operands[0];
1657 rtx set_src = operands[1];
1658 rtx dest1, dest2;
1659 rtx src1, src2;
1660
1661 dest1 = gen_highpart (SImode, set_dest);
1662 dest2 = gen_lowpart (SImode, set_dest);
1663 src1 = gen_highpart (SImode, set_src);
1664 src2 = gen_lowpart (SImode, set_src);
1665
1666 /* Now emit using the real source and destination we found, swapping
1667 the order if we detect overlap. */
1668 if (reg_overlap_mentioned_p (dest1, src2))
1669 {
1670 emit_insn (gen_movsi (dest2, src2));
1671 emit_insn (gen_movsi (dest1, src1));
1672 }
1673 else
1674 {
1675 emit_insn (gen_movsi (dest1, src1));
1676 emit_insn (gen_movsi (dest2, src2));
1677 }
1678 DONE;
1679 })
1680
1681 ;; Now handle the cases of memory moves from/to non-even
1682 ;; DI mode register pairs.
1683 (define_split
1684 [(set (match_operand:DI 0 "register_operand" "")
1685 (match_operand:DI 1 "memory_operand" ""))]
1686 "(! TARGET_ARCH64
1687 && reload_completed
1688 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1689 [(clobber (const_int 0))]
1690 {
1691 rtx word0 = adjust_address (operands[1], SImode, 0);
1692 rtx word1 = adjust_address (operands[1], SImode, 4);
1693 rtx high_part = gen_highpart (SImode, operands[0]);
1694 rtx low_part = gen_lowpart (SImode, operands[0]);
1695
1696 if (reg_overlap_mentioned_p (high_part, word1))
1697 {
1698 emit_insn (gen_movsi (low_part, word1));
1699 emit_insn (gen_movsi (high_part, word0));
1700 }
1701 else
1702 {
1703 emit_insn (gen_movsi (high_part, word0));
1704 emit_insn (gen_movsi (low_part, word1));
1705 }
1706 DONE;
1707 })
1708
1709 (define_split
1710 [(set (match_operand:DI 0 "memory_operand" "")
1711 (match_operand:DI 1 "register_operand" ""))]
1712 "(! TARGET_ARCH64
1713 && reload_completed
1714 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1715 [(clobber (const_int 0))]
1716 {
1717 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1718 gen_highpart (SImode, operands[1])));
1719 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1720 gen_lowpart (SImode, operands[1])));
1721 DONE;
1722 })
1723
1724 (define_split
1725 [(set (match_operand:DI 0 "memory_operand" "")
1726 (match_operand:DI 1 "const_zero_operand" ""))]
1727 "reload_completed
1728 && (! TARGET_V9
1729 || (! TARGET_ARCH64
1730 && ! mem_min_alignment (operands[0], 8)))
1731 && offsettable_memref_p (operands[0])"
1732 [(clobber (const_int 0))]
1733 {
1734 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1735 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1736 DONE;
1737 })
1738
1739
1740 ;; Floating point and vector move instructions
1741
1742 ;; Yes, you guessed it right, the former movsf expander.
1743 (define_expand "mov<V32:mode>"
1744 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1745 (match_operand:V32 1 "general_operand" ""))]
1746 "<V32:MODE>mode == SFmode || TARGET_VIS"
1747 {
1748 if (sparc_expand_move (<V32:MODE>mode, operands))
1749 DONE;
1750 })
1751
1752 (define_insn "*movsf_insn"
1753 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
1754 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
1755 "TARGET_FPU
1756 && (register_operand (operands[0], <V32:MODE>mode)
1757 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
1758 {
1759 if (GET_CODE (operands[1]) == CONST_DOUBLE
1760 && (which_alternative == 2
1761 || which_alternative == 3
1762 || which_alternative == 4))
1763 {
1764 REAL_VALUE_TYPE r;
1765 long i;
1766
1767 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1768 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1769 operands[1] = GEN_INT (i);
1770 }
1771
1772 switch (which_alternative)
1773 {
1774 case 0:
1775 return "fzeros\t%0";
1776 case 1:
1777 return "fmovs\t%1, %0";
1778 case 2:
1779 return "mov\t%1, %0";
1780 case 3:
1781 return "sethi\t%%hi(%a1), %0";
1782 case 4:
1783 return "#";
1784 case 5:
1785 case 6:
1786 return "ld\t%1, %0";
1787 case 7:
1788 case 8:
1789 return "st\t%r1, %0";
1790 default:
1791 gcc_unreachable ();
1792 }
1793 }
1794 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1795
1796 ;; Exactly the same as above, except that all `f' cases are deleted.
1797 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1798 ;; when -mno-fpu.
1799
1800 (define_insn "*movsf_insn_no_fpu"
1801 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1802 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1803 "! TARGET_FPU
1804 && (register_operand (operands[0], SFmode)
1805 || register_or_zero_operand (operands[1], SFmode))"
1806 {
1807 if (GET_CODE (operands[1]) == CONST_DOUBLE
1808 && (which_alternative == 0
1809 || which_alternative == 1
1810 || which_alternative == 2))
1811 {
1812 REAL_VALUE_TYPE r;
1813 long i;
1814
1815 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1816 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1817 operands[1] = GEN_INT (i);
1818 }
1819
1820 switch (which_alternative)
1821 {
1822 case 0:
1823 return "mov\t%1, %0";
1824 case 1:
1825 return "sethi\t%%hi(%a1), %0";
1826 case 2:
1827 return "#";
1828 case 3:
1829 return "ld\t%1, %0";
1830 case 4:
1831 return "st\t%r1, %0";
1832 default:
1833 gcc_unreachable ();
1834 }
1835 }
1836 [(set_attr "type" "*,*,*,load,store")])
1837
1838 ;; The following 3 patterns build SFmode constants in integer registers.
1839
1840 (define_insn "*movsf_lo_sum"
1841 [(set (match_operand:SF 0 "register_operand" "=r")
1842 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
1843 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
1844 ""
1845 {
1846 REAL_VALUE_TYPE r;
1847 long i;
1848
1849 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
1850 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1851 operands[2] = GEN_INT (i);
1852 return "or\t%1, %%lo(%a2), %0";
1853 })
1854
1855 (define_insn "*movsf_high"
1856 [(set (match_operand:SF 0 "register_operand" "=r")
1857 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
1858 ""
1859 {
1860 REAL_VALUE_TYPE r;
1861 long i;
1862
1863 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1864 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1865 operands[1] = GEN_INT (i);
1866 return "sethi\t%%hi(%1), %0";
1867 })
1868
1869 (define_split
1870 [(set (match_operand:SF 0 "register_operand" "")
1871 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
1872 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
1873 [(set (match_dup 0) (high:SF (match_dup 1)))
1874 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
1875
1876 ;; Yes, you again guessed it right, the former movdf expander.
1877 (define_expand "mov<V64:mode>"
1878 [(set (match_operand:V64 0 "nonimmediate_operand" "")
1879 (match_operand:V64 1 "general_operand" ""))]
1880 "<V64:MODE>mode == DFmode || TARGET_VIS"
1881 {
1882 if (sparc_expand_move (<V64:MODE>mode, operands))
1883 DONE;
1884 })
1885
1886 ;; Be careful, fmovd does not exist when !v9.
1887 (define_insn "*movdf_insn_sp32"
1888 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
1889 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
1890 "TARGET_FPU
1891 && ! TARGET_V9
1892 && (register_operand (operands[0], DFmode)
1893 || register_or_zero_operand (operands[1], DFmode))"
1894 "@
1895 ldd\t%1, %0
1896 std\t%1, %0
1897 ldd\t%1, %0
1898 std\t%1, %0
1899 #
1900 #
1901 #
1902 #
1903 #
1904 #"
1905 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
1906 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
1907
1908 (define_insn "*movdf_insn_sp32_no_fpu"
1909 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
1910 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
1911 "! TARGET_FPU
1912 && ! TARGET_V9
1913 && (register_operand (operands[0], DFmode)
1914 || register_or_zero_operand (operands[1], DFmode))"
1915 "@
1916 ldd\t%1, %0
1917 std\t%1, %0
1918 #
1919 #
1920 #"
1921 [(set_attr "type" "load,store,*,*,*")
1922 (set_attr "length" "*,*,2,2,2")])
1923
1924 ;; We have available v9 double floats but not 64-bit integer registers.
1925 (define_insn "*movdf_insn_sp32_v9"
1926 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
1927 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
1928 "TARGET_FPU
1929 && TARGET_V9
1930 && ! TARGET_ARCH64
1931 && (register_operand (operands[0], <V64:MODE>mode)
1932 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
1933 "@
1934 fzero\t%0
1935 fmovd\t%1, %0
1936 ldd\t%1, %0
1937 stx\t%r1, %0
1938 std\t%1, %0
1939 ldd\t%1, %0
1940 std\t%1, %0
1941 #
1942 #
1943 #"
1944 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
1945 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
1946 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
1947
1948 (define_insn "*movdf_insn_sp32_v9_no_fpu"
1949 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
1950 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
1951 "! TARGET_FPU
1952 && TARGET_V9
1953 && ! TARGET_ARCH64
1954 && (register_operand (operands[0], DFmode)
1955 || register_or_zero_operand (operands[1], DFmode))"
1956 "@
1957 ldd\t%1, %0
1958 std\t%1, %0
1959 stx\t%r1, %0
1960 #
1961 #"
1962 [(set_attr "type" "load,store,store,*,*")
1963 (set_attr "length" "*,*,*,2,2")])
1964
1965 ;; We have available both v9 double floats and 64-bit integer registers.
1966 (define_insn "*movdf_insn_sp64"
1967 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
1968 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
1969 "TARGET_FPU
1970 && TARGET_ARCH64
1971 && (register_operand (operands[0], <V64:MODE>mode)
1972 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
1973 "@
1974 fzero\t%0
1975 fmovd\t%1, %0
1976 ldd\t%1, %0
1977 std\t%1, %0
1978 mov\t%r1, %0
1979 ldx\t%1, %0
1980 stx\t%r1, %0
1981 #"
1982 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
1983 (set_attr "length" "*,*,*,*,*,*,*,2")
1984 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
1985
1986 (define_insn "*movdf_insn_sp64_no_fpu"
1987 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
1988 (match_operand:DF 1 "input_operand" "r,m,rG"))]
1989 "! TARGET_FPU
1990 && TARGET_ARCH64
1991 && (register_operand (operands[0], DFmode)
1992 || register_or_zero_operand (operands[1], DFmode))"
1993 "@
1994 mov\t%1, %0
1995 ldx\t%1, %0
1996 stx\t%r1, %0"
1997 [(set_attr "type" "*,load,store")])
1998
1999 ;; This pattern builds V64mode constants in integer registers.
2000 (define_split
2001 [(set (match_operand:V64 0 "register_operand" "")
2002 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2003 "TARGET_FPU
2004 && (GET_CODE (operands[0]) == REG
2005 && REGNO (operands[0]) < 32)
2006 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2007 && reload_completed"
2008 [(clobber (const_int 0))]
2009 {
2010 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2011
2012 if (TARGET_ARCH64)
2013 {
2014 #if HOST_BITS_PER_WIDE_INT == 32
2015 gcc_unreachable ();
2016 #else
2017 enum machine_mode mode = GET_MODE (operands[1]);
2018 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2019 emit_insn (gen_movdi (operands[0], tem));
2020 #endif
2021 }
2022 else
2023 {
2024 enum machine_mode mode = GET_MODE (operands[1]);
2025 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2026 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2027
2028 gcc_assert (GET_CODE (hi) == CONST_INT);
2029 gcc_assert (GET_CODE (lo) == CONST_INT);
2030
2031 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2032
2033 /* Slick... but this trick loses if this subreg constant part
2034 can be done in one insn. */
2035 if (lo == hi
2036 && ! SPARC_SETHI32_P (INTVAL (hi))
2037 && ! SPARC_SIMM13_P (INTVAL (hi)))
2038 {
2039 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2040 gen_highpart (SImode, operands[0])));
2041 }
2042 else
2043 {
2044 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2045 }
2046 }
2047 DONE;
2048 })
2049
2050 ;; Ok, now the splits to handle all the multi insn and
2051 ;; mis-aligned memory address cases.
2052 ;; In these splits please take note that we must be
2053 ;; careful when V9 but not ARCH64 because the integer
2054 ;; register DFmode cases must be handled.
2055 (define_split
2056 [(set (match_operand:V64 0 "register_operand" "")
2057 (match_operand:V64 1 "register_operand" ""))]
2058 "(! TARGET_V9
2059 || (! TARGET_ARCH64
2060 && ((GET_CODE (operands[0]) == REG
2061 && REGNO (operands[0]) < 32)
2062 || (GET_CODE (operands[0]) == SUBREG
2063 && GET_CODE (SUBREG_REG (operands[0])) == REG
2064 && REGNO (SUBREG_REG (operands[0])) < 32))))
2065 && reload_completed"
2066 [(clobber (const_int 0))]
2067 {
2068 rtx set_dest = operands[0];
2069 rtx set_src = operands[1];
2070 rtx dest1, dest2;
2071 rtx src1, src2;
2072 enum machine_mode half_mode;
2073
2074 /* We can be expanded for DFmode or integral vector modes. */
2075 if (<V64:MODE>mode == DFmode)
2076 half_mode = SFmode;
2077 else
2078 half_mode = SImode;
2079
2080 dest1 = gen_highpart (half_mode, set_dest);
2081 dest2 = gen_lowpart (half_mode, set_dest);
2082 src1 = gen_highpart (half_mode, set_src);
2083 src2 = gen_lowpart (half_mode, set_src);
2084
2085 /* Now emit using the real source and destination we found, swapping
2086 the order if we detect overlap. */
2087 if (reg_overlap_mentioned_p (dest1, src2))
2088 {
2089 emit_move_insn_1 (dest2, src2);
2090 emit_move_insn_1 (dest1, src1);
2091 }
2092 else
2093 {
2094 emit_move_insn_1 (dest1, src1);
2095 emit_move_insn_1 (dest2, src2);
2096 }
2097 DONE;
2098 })
2099
2100 (define_split
2101 [(set (match_operand:V64 0 "register_operand" "")
2102 (match_operand:V64 1 "memory_operand" ""))]
2103 "reload_completed
2104 && ! TARGET_ARCH64
2105 && (((REGNO (operands[0]) % 2) != 0)
2106 || ! mem_min_alignment (operands[1], 8))
2107 && offsettable_memref_p (operands[1])"
2108 [(clobber (const_int 0))]
2109 {
2110 enum machine_mode half_mode;
2111 rtx word0, word1;
2112
2113 /* We can be expanded for DFmode or integral vector modes. */
2114 if (<V64:MODE>mode == DFmode)
2115 half_mode = SFmode;
2116 else
2117 half_mode = SImode;
2118
2119 word0 = adjust_address (operands[1], half_mode, 0);
2120 word1 = adjust_address (operands[1], half_mode, 4);
2121
2122 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2123 {
2124 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2125 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2126 }
2127 else
2128 {
2129 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2130 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2131 }
2132 DONE;
2133 })
2134
2135 (define_split
2136 [(set (match_operand:V64 0 "memory_operand" "")
2137 (match_operand:V64 1 "register_operand" ""))]
2138 "reload_completed
2139 && ! TARGET_ARCH64
2140 && (((REGNO (operands[1]) % 2) != 0)
2141 || ! mem_min_alignment (operands[0], 8))
2142 && offsettable_memref_p (operands[0])"
2143 [(clobber (const_int 0))]
2144 {
2145 enum machine_mode half_mode;
2146 rtx word0, word1;
2147
2148 /* We can be expanded for DFmode or integral vector modes. */
2149 if (<V64:MODE>mode == DFmode)
2150 half_mode = SFmode;
2151 else
2152 half_mode = SImode;
2153
2154 word0 = adjust_address (operands[0], half_mode, 0);
2155 word1 = adjust_address (operands[0], half_mode, 4);
2156
2157 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2158 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2159 DONE;
2160 })
2161
2162 (define_split
2163 [(set (match_operand:V64 0 "memory_operand" "")
2164 (match_operand:V64 1 "const_zero_operand" ""))]
2165 "reload_completed
2166 && (! TARGET_V9
2167 || (! TARGET_ARCH64
2168 && ! mem_min_alignment (operands[0], 8)))
2169 && offsettable_memref_p (operands[0])"
2170 [(clobber (const_int 0))]
2171 {
2172 enum machine_mode half_mode;
2173 rtx dest1, dest2;
2174
2175 /* We can be expanded for DFmode or integral vector modes. */
2176 if (<V64:MODE>mode == DFmode)
2177 half_mode = SFmode;
2178 else
2179 half_mode = SImode;
2180
2181 dest1 = adjust_address (operands[0], half_mode, 0);
2182 dest2 = adjust_address (operands[0], half_mode, 4);
2183
2184 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2185 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2186 DONE;
2187 })
2188
2189 (define_split
2190 [(set (match_operand:V64 0 "register_operand" "")
2191 (match_operand:V64 1 "const_zero_operand" ""))]
2192 "reload_completed
2193 && ! TARGET_ARCH64
2194 && ((GET_CODE (operands[0]) == REG
2195 && REGNO (operands[0]) < 32)
2196 || (GET_CODE (operands[0]) == SUBREG
2197 && GET_CODE (SUBREG_REG (operands[0])) == REG
2198 && REGNO (SUBREG_REG (operands[0])) < 32))"
2199 [(clobber (const_int 0))]
2200 {
2201 enum machine_mode half_mode;
2202 rtx set_dest = operands[0];
2203 rtx dest1, dest2;
2204
2205 /* We can be expanded for DFmode or integral vector modes. */
2206 if (<V64:MODE>mode == DFmode)
2207 half_mode = SFmode;
2208 else
2209 half_mode = SImode;
2210
2211 dest1 = gen_highpart (half_mode, set_dest);
2212 dest2 = gen_lowpart (half_mode, set_dest);
2213 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2214 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2215 DONE;
2216 })
2217
2218 (define_expand "movtf"
2219 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2220 (match_operand:TF 1 "general_operand" ""))]
2221 ""
2222 {
2223 if (sparc_expand_move (TFmode, operands))
2224 DONE;
2225 })
2226
2227 (define_insn "*movtf_insn_sp32"
2228 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2229 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2230 "TARGET_FPU
2231 && ! TARGET_ARCH64
2232 && (register_operand (operands[0], TFmode)
2233 || register_or_zero_operand (operands[1], TFmode))"
2234 "#"
2235 [(set_attr "length" "4")])
2236
2237 ;; Exactly the same as above, except that all `e' cases are deleted.
2238 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2239 ;; when -mno-fpu.
2240
2241 (define_insn "*movtf_insn_sp32_no_fpu"
2242 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2243 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2244 "! TARGET_FPU
2245 && ! TARGET_ARCH64
2246 && (register_operand (operands[0], TFmode)
2247 || register_or_zero_operand (operands[1], TFmode))"
2248 "#"
2249 [(set_attr "length" "4")])
2250
2251 (define_insn "*movtf_insn_sp64"
2252 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2253 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2254 "TARGET_FPU
2255 && TARGET_ARCH64
2256 && ! TARGET_HARD_QUAD
2257 && (register_operand (operands[0], TFmode)
2258 || register_or_zero_operand (operands[1], TFmode))"
2259 "#"
2260 [(set_attr "length" "2")])
2261
2262 (define_insn "*movtf_insn_sp64_hq"
2263 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2264 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2265 "TARGET_FPU
2266 && TARGET_ARCH64
2267 && TARGET_HARD_QUAD
2268 && (register_operand (operands[0], TFmode)
2269 || register_or_zero_operand (operands[1], TFmode))"
2270 "@
2271 #
2272 fmovq\t%1, %0
2273 ldq\t%1, %0
2274 stq\t%1, %0
2275 #
2276 #"
2277 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2278 (set_attr "length" "2,*,*,*,2,2")])
2279
2280 (define_insn "*movtf_insn_sp64_no_fpu"
2281 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2282 (match_operand:TF 1 "input_operand" "orG,rG"))]
2283 "! TARGET_FPU
2284 && TARGET_ARCH64
2285 && (register_operand (operands[0], TFmode)
2286 || register_or_zero_operand (operands[1], TFmode))"
2287 "#"
2288 [(set_attr "length" "2")])
2289
2290 ;; Now all the splits to handle multi-insn TF mode moves.
2291 (define_split
2292 [(set (match_operand:TF 0 "register_operand" "")
2293 (match_operand:TF 1 "register_operand" ""))]
2294 "reload_completed
2295 && (! TARGET_ARCH64
2296 || (TARGET_FPU
2297 && ! TARGET_HARD_QUAD)
2298 || ! fp_register_operand (operands[0], TFmode))"
2299 [(clobber (const_int 0))]
2300 {
2301 rtx set_dest = operands[0];
2302 rtx set_src = operands[1];
2303 rtx dest1, dest2;
2304 rtx src1, src2;
2305
2306 dest1 = gen_df_reg (set_dest, 0);
2307 dest2 = gen_df_reg (set_dest, 1);
2308 src1 = gen_df_reg (set_src, 0);
2309 src2 = gen_df_reg (set_src, 1);
2310
2311 /* Now emit using the real source and destination we found, swapping
2312 the order if we detect overlap. */
2313 if (reg_overlap_mentioned_p (dest1, src2))
2314 {
2315 emit_insn (gen_movdf (dest2, src2));
2316 emit_insn (gen_movdf (dest1, src1));
2317 }
2318 else
2319 {
2320 emit_insn (gen_movdf (dest1, src1));
2321 emit_insn (gen_movdf (dest2, src2));
2322 }
2323 DONE;
2324 })
2325
2326 (define_split
2327 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2328 (match_operand:TF 1 "const_zero_operand" ""))]
2329 "reload_completed"
2330 [(clobber (const_int 0))]
2331 {
2332 rtx set_dest = operands[0];
2333 rtx dest1, dest2;
2334
2335 switch (GET_CODE (set_dest))
2336 {
2337 case REG:
2338 dest1 = gen_df_reg (set_dest, 0);
2339 dest2 = gen_df_reg (set_dest, 1);
2340 break;
2341 case MEM:
2342 dest1 = adjust_address (set_dest, DFmode, 0);
2343 dest2 = adjust_address (set_dest, DFmode, 8);
2344 break;
2345 default:
2346 gcc_unreachable ();
2347 }
2348
2349 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2350 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2351 DONE;
2352 })
2353
2354 (define_split
2355 [(set (match_operand:TF 0 "register_operand" "")
2356 (match_operand:TF 1 "memory_operand" ""))]
2357 "(reload_completed
2358 && offsettable_memref_p (operands[1])
2359 && (! TARGET_ARCH64
2360 || ! TARGET_HARD_QUAD
2361 || ! fp_register_operand (operands[0], TFmode)))"
2362 [(clobber (const_int 0))]
2363 {
2364 rtx word0 = adjust_address (operands[1], DFmode, 0);
2365 rtx word1 = adjust_address (operands[1], DFmode, 8);
2366 rtx set_dest, dest1, dest2;
2367
2368 set_dest = operands[0];
2369
2370 dest1 = gen_df_reg (set_dest, 0);
2371 dest2 = gen_df_reg (set_dest, 1);
2372
2373 /* Now output, ordering such that we don't clobber any registers
2374 mentioned in the address. */
2375 if (reg_overlap_mentioned_p (dest1, word1))
2376
2377 {
2378 emit_insn (gen_movdf (dest2, word1));
2379 emit_insn (gen_movdf (dest1, word0));
2380 }
2381 else
2382 {
2383 emit_insn (gen_movdf (dest1, word0));
2384 emit_insn (gen_movdf (dest2, word1));
2385 }
2386 DONE;
2387 })
2388
2389 (define_split
2390 [(set (match_operand:TF 0 "memory_operand" "")
2391 (match_operand:TF 1 "register_operand" ""))]
2392 "(reload_completed
2393 && offsettable_memref_p (operands[0])
2394 && (! TARGET_ARCH64
2395 || ! TARGET_HARD_QUAD
2396 || ! fp_register_operand (operands[1], TFmode)))"
2397 [(clobber (const_int 0))]
2398 {
2399 rtx set_src = operands[1];
2400
2401 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2402 gen_df_reg (set_src, 0)));
2403 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2404 gen_df_reg (set_src, 1)));
2405 DONE;
2406 })
2407
2408
2409 ;; SPARC-V9 conditional move instructions
2410
2411 ;; We can handle larger constants here for some flavors, but for now we keep
2412 ;; it simple and only allow those constants supported by all flavors.
2413 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2414 ;; 3 contains the constant if one is present, but we handle either for
2415 ;; generality (sparc.c puts a constant in operand 2).
2416
2417 (define_expand "mov<I:mode>cc"
2418 [(set (match_operand:I 0 "register_operand" "")
2419 (if_then_else:I (match_operand 1 "comparison_operator" "")
2420 (match_operand:I 2 "arith10_operand" "")
2421 (match_operand:I 3 "arith10_operand" "")))]
2422 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2423 {
2424 enum rtx_code code = GET_CODE (operands[1]);
2425 rtx cc_reg;
2426
2427 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2428 && ! TARGET_ARCH64)
2429 FAIL;
2430
2431 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2432 operands[1]
2433 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2434 GET_CODE (operands[1]));
2435
2436 if (XEXP (operands[1], 1) == const0_rtx
2437 && GET_CODE (XEXP (operands[1], 0)) == REG
2438 && GET_MODE (XEXP (operands[1], 0)) == DImode
2439 && v9_regcmp_p (code))
2440 cc_reg = XEXP (operands[1], 0);
2441 else
2442 cc_reg = gen_compare_reg (operands[1]);
2443
2444 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2445 })
2446
2447 (define_expand "mov<F:mode>cc"
2448 [(set (match_operand:F 0 "register_operand" "")
2449 (if_then_else:F (match_operand 1 "comparison_operator" "")
2450 (match_operand:F 2 "register_operand" "")
2451 (match_operand:F 3 "register_operand" "")))]
2452 "TARGET_V9 && TARGET_FPU"
2453 {
2454 enum rtx_code code = GET_CODE (operands[1]);
2455 rtx cc_reg;
2456
2457 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2458 && ! TARGET_ARCH64)
2459 FAIL;
2460
2461 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2462 operands[1]
2463 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2464 GET_CODE (operands[1]));
2465
2466 if (XEXP (operands[1], 1) == const0_rtx
2467 && GET_CODE (XEXP (operands[1], 0)) == REG
2468 && GET_MODE (XEXP (operands[1], 0)) == DImode
2469 && v9_regcmp_p (code))
2470 cc_reg = XEXP (operands[1], 0);
2471 else
2472 cc_reg = gen_compare_reg (operands[1]);
2473
2474 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2475 })
2476
2477 ;; Conditional move define_insns
2478
2479 (define_insn "*mov<I:mode>_cc_v9"
2480 [(set (match_operand:I 0 "register_operand" "=r,r")
2481 (if_then_else:I (match_operator 1 "comparison_operator"
2482 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2483 (const_int 0)])
2484 (match_operand:I 3 "arith11_operand" "rL,0")
2485 (match_operand:I 4 "arith11_operand" "0,rL")))]
2486 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2487 "@
2488 mov%C1\t%x2, %3, %0
2489 mov%c1\t%x2, %4, %0"
2490 [(set_attr "type" "cmove")])
2491
2492 (define_insn "*mov<I:mode>_cc_reg_sp64"
2493 [(set (match_operand:I 0 "register_operand" "=r,r")
2494 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2495 [(match_operand:DI 2 "register_operand" "r,r")
2496 (const_int 0)])
2497 (match_operand:I 3 "arith10_operand" "rM,0")
2498 (match_operand:I 4 "arith10_operand" "0,rM")))]
2499 "TARGET_ARCH64"
2500 "@
2501 movr%D1\t%2, %r3, %0
2502 movr%d1\t%2, %r4, %0"
2503 [(set_attr "type" "cmove")])
2504
2505 (define_insn "*movsf_cc_v9"
2506 [(set (match_operand:SF 0 "register_operand" "=f,f")
2507 (if_then_else:SF (match_operator 1 "comparison_operator"
2508 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2509 (const_int 0)])
2510 (match_operand:SF 3 "register_operand" "f,0")
2511 (match_operand:SF 4 "register_operand" "0,f")))]
2512 "TARGET_V9 && TARGET_FPU"
2513 "@
2514 fmovs%C1\t%x2, %3, %0
2515 fmovs%c1\t%x2, %4, %0"
2516 [(set_attr "type" "fpcmove")])
2517
2518 (define_insn "*movsf_cc_reg_sp64"
2519 [(set (match_operand:SF 0 "register_operand" "=f,f")
2520 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2521 [(match_operand:DI 2 "register_operand" "r,r")
2522 (const_int 0)])
2523 (match_operand:SF 3 "register_operand" "f,0")
2524 (match_operand:SF 4 "register_operand" "0,f")))]
2525 "TARGET_ARCH64 && TARGET_FPU"
2526 "@
2527 fmovrs%D1\t%2, %3, %0
2528 fmovrs%d1\t%2, %4, %0"
2529 [(set_attr "type" "fpcrmove")])
2530
2531 ;; Named because invoked by movtf_cc_v9
2532 (define_insn "movdf_cc_v9"
2533 [(set (match_operand:DF 0 "register_operand" "=e,e")
2534 (if_then_else:DF (match_operator 1 "comparison_operator"
2535 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2536 (const_int 0)])
2537 (match_operand:DF 3 "register_operand" "e,0")
2538 (match_operand:DF 4 "register_operand" "0,e")))]
2539 "TARGET_V9 && TARGET_FPU"
2540 "@
2541 fmovd%C1\t%x2, %3, %0
2542 fmovd%c1\t%x2, %4, %0"
2543 [(set_attr "type" "fpcmove")
2544 (set_attr "fptype" "double")])
2545
2546 ;; Named because invoked by movtf_cc_reg_sp64
2547 (define_insn "movdf_cc_reg_sp64"
2548 [(set (match_operand:DF 0 "register_operand" "=e,e")
2549 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2550 [(match_operand:DI 2 "register_operand" "r,r")
2551 (const_int 0)])
2552 (match_operand:DF 3 "register_operand" "e,0")
2553 (match_operand:DF 4 "register_operand" "0,e")))]
2554 "TARGET_ARCH64 && TARGET_FPU"
2555 "@
2556 fmovrd%D1\t%2, %3, %0
2557 fmovrd%d1\t%2, %4, %0"
2558 [(set_attr "type" "fpcrmove")
2559 (set_attr "fptype" "double")])
2560
2561 (define_insn "*movtf_cc_hq_v9"
2562 [(set (match_operand:TF 0 "register_operand" "=e,e")
2563 (if_then_else:TF (match_operator 1 "comparison_operator"
2564 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2565 (const_int 0)])
2566 (match_operand:TF 3 "register_operand" "e,0")
2567 (match_operand:TF 4 "register_operand" "0,e")))]
2568 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2569 "@
2570 fmovq%C1\t%x2, %3, %0
2571 fmovq%c1\t%x2, %4, %0"
2572 [(set_attr "type" "fpcmove")])
2573
2574 (define_insn "*movtf_cc_reg_hq_sp64"
2575 [(set (match_operand:TF 0 "register_operand" "=e,e")
2576 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2577 [(match_operand:DI 2 "register_operand" "r,r")
2578 (const_int 0)])
2579 (match_operand:TF 3 "register_operand" "e,0")
2580 (match_operand:TF 4 "register_operand" "0,e")))]
2581 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2582 "@
2583 fmovrq%D1\t%2, %3, %0
2584 fmovrq%d1\t%2, %4, %0"
2585 [(set_attr "type" "fpcrmove")])
2586
2587 (define_insn_and_split "*movtf_cc_v9"
2588 [(set (match_operand:TF 0 "register_operand" "=e,e")
2589 (if_then_else:TF (match_operator 1 "comparison_operator"
2590 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2591 (const_int 0)])
2592 (match_operand:TF 3 "register_operand" "e,0")
2593 (match_operand:TF 4 "register_operand" "0,e")))]
2594 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2595 "#"
2596 "&& reload_completed"
2597 [(clobber (const_int 0))]
2598 {
2599 rtx set_dest = operands[0];
2600 rtx set_srca = operands[3];
2601 rtx set_srcb = operands[4];
2602 int third = rtx_equal_p (set_dest, set_srca);
2603 rtx dest1, dest2;
2604 rtx srca1, srca2, srcb1, srcb2;
2605
2606 dest1 = gen_df_reg (set_dest, 0);
2607 dest2 = gen_df_reg (set_dest, 1);
2608 srca1 = gen_df_reg (set_srca, 0);
2609 srca2 = gen_df_reg (set_srca, 1);
2610 srcb1 = gen_df_reg (set_srcb, 0);
2611 srcb2 = gen_df_reg (set_srcb, 1);
2612
2613 /* Now emit using the real source and destination we found, swapping
2614 the order if we detect overlap. */
2615 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2616 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2617 {
2618 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2619 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2620 }
2621 else
2622 {
2623 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2624 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2625 }
2626 DONE;
2627 }
2628 [(set_attr "length" "2")])
2629
2630 (define_insn_and_split "*movtf_cc_reg_sp64"
2631 [(set (match_operand:TF 0 "register_operand" "=e,e")
2632 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2633 [(match_operand:DI 2 "register_operand" "r,r")
2634 (const_int 0)])
2635 (match_operand:TF 3 "register_operand" "e,0")
2636 (match_operand:TF 4 "register_operand" "0,e")))]
2637 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2638 "#"
2639 "&& reload_completed"
2640 [(clobber (const_int 0))]
2641 {
2642 rtx set_dest = operands[0];
2643 rtx set_srca = operands[3];
2644 rtx set_srcb = operands[4];
2645 int third = rtx_equal_p (set_dest, set_srca);
2646 rtx dest1, dest2;
2647 rtx srca1, srca2, srcb1, srcb2;
2648
2649 dest1 = gen_df_reg (set_dest, 0);
2650 dest2 = gen_df_reg (set_dest, 1);
2651 srca1 = gen_df_reg (set_srca, 0);
2652 srca2 = gen_df_reg (set_srca, 1);
2653 srcb1 = gen_df_reg (set_srcb, 0);
2654 srcb2 = gen_df_reg (set_srcb, 1);
2655
2656 /* Now emit using the real source and destination we found, swapping
2657 the order if we detect overlap. */
2658 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2659 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2660 {
2661 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2662 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2663 }
2664 else
2665 {
2666 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2667 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2668 }
2669 DONE;
2670 }
2671 [(set_attr "length" "2")])
2672
2673 \f
2674 ;; Zero-extension instructions
2675
2676 ;; These patterns originally accepted general_operands, however, slightly
2677 ;; better code is generated by only accepting register_operands, and then
2678 ;; letting combine generate the ldu[hb] insns.
2679
2680 (define_expand "zero_extendhisi2"
2681 [(set (match_operand:SI 0 "register_operand" "")
2682 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2683 ""
2684 {
2685 rtx temp = gen_reg_rtx (SImode);
2686 rtx shift_16 = GEN_INT (16);
2687 int op1_subbyte = 0;
2688
2689 if (GET_CODE (operand1) == SUBREG)
2690 {
2691 op1_subbyte = SUBREG_BYTE (operand1);
2692 op1_subbyte /= GET_MODE_SIZE (SImode);
2693 op1_subbyte *= GET_MODE_SIZE (SImode);
2694 operand1 = XEXP (operand1, 0);
2695 }
2696
2697 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2698 shift_16));
2699 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2700 DONE;
2701 })
2702
2703 (define_insn "*zero_extendhisi2_insn"
2704 [(set (match_operand:SI 0 "register_operand" "=r")
2705 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2706 ""
2707 "lduh\t%1, %0"
2708 [(set_attr "type" "load")
2709 (set_attr "us3load_type" "3cycle")])
2710
2711 (define_expand "zero_extendqihi2"
2712 [(set (match_operand:HI 0 "register_operand" "")
2713 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2714 ""
2715 "")
2716
2717 (define_insn "*zero_extendqihi2_insn"
2718 [(set (match_operand:HI 0 "register_operand" "=r,r")
2719 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2720 "GET_CODE (operands[1]) != CONST_INT"
2721 "@
2722 and\t%1, 0xff, %0
2723 ldub\t%1, %0"
2724 [(set_attr "type" "*,load")
2725 (set_attr "us3load_type" "*,3cycle")])
2726
2727 (define_expand "zero_extendqisi2"
2728 [(set (match_operand:SI 0 "register_operand" "")
2729 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2730 ""
2731 "")
2732
2733 (define_insn "*zero_extendqisi2_insn"
2734 [(set (match_operand:SI 0 "register_operand" "=r,r")
2735 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2736 "GET_CODE (operands[1]) != CONST_INT"
2737 "@
2738 and\t%1, 0xff, %0
2739 ldub\t%1, %0"
2740 [(set_attr "type" "*,load")
2741 (set_attr "us3load_type" "*,3cycle")])
2742
2743 (define_expand "zero_extendqidi2"
2744 [(set (match_operand:DI 0 "register_operand" "")
2745 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2746 "TARGET_ARCH64"
2747 "")
2748
2749 (define_insn "*zero_extendqidi2_insn"
2750 [(set (match_operand:DI 0 "register_operand" "=r,r")
2751 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2752 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2753 "@
2754 and\t%1, 0xff, %0
2755 ldub\t%1, %0"
2756 [(set_attr "type" "*,load")
2757 (set_attr "us3load_type" "*,3cycle")])
2758
2759 (define_expand "zero_extendhidi2"
2760 [(set (match_operand:DI 0 "register_operand" "")
2761 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2762 "TARGET_ARCH64"
2763 {
2764 rtx temp = gen_reg_rtx (DImode);
2765 rtx shift_48 = GEN_INT (48);
2766 int op1_subbyte = 0;
2767
2768 if (GET_CODE (operand1) == SUBREG)
2769 {
2770 op1_subbyte = SUBREG_BYTE (operand1);
2771 op1_subbyte /= GET_MODE_SIZE (DImode);
2772 op1_subbyte *= GET_MODE_SIZE (DImode);
2773 operand1 = XEXP (operand1, 0);
2774 }
2775
2776 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2777 shift_48));
2778 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2779 DONE;
2780 })
2781
2782 (define_insn "*zero_extendhidi2_insn"
2783 [(set (match_operand:DI 0 "register_operand" "=r")
2784 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2785 "TARGET_ARCH64"
2786 "lduh\t%1, %0"
2787 [(set_attr "type" "load")
2788 (set_attr "us3load_type" "3cycle")])
2789
2790 ;; ??? Write truncdisi pattern using sra?
2791
2792 (define_expand "zero_extendsidi2"
2793 [(set (match_operand:DI 0 "register_operand" "")
2794 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2795 ""
2796 "")
2797
2798 (define_insn "*zero_extendsidi2_insn_sp64"
2799 [(set (match_operand:DI 0 "register_operand" "=r,r")
2800 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2801 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2802 "@
2803 srl\t%1, 0, %0
2804 lduw\t%1, %0"
2805 [(set_attr "type" "shift,load")])
2806
2807 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2808 [(set (match_operand:DI 0 "register_operand" "=r")
2809 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2810 "! TARGET_ARCH64"
2811 "#"
2812 "&& reload_completed"
2813 [(set (match_dup 2) (match_dup 3))
2814 (set (match_dup 4) (match_dup 5))]
2815 {
2816 rtx dest1, dest2;
2817
2818 dest1 = gen_highpart (SImode, operands[0]);
2819 dest2 = gen_lowpart (SImode, operands[0]);
2820
2821 /* Swap the order in case of overlap. */
2822 if (REGNO (dest1) == REGNO (operands[1]))
2823 {
2824 operands[2] = dest2;
2825 operands[3] = operands[1];
2826 operands[4] = dest1;
2827 operands[5] = const0_rtx;
2828 }
2829 else
2830 {
2831 operands[2] = dest1;
2832 operands[3] = const0_rtx;
2833 operands[4] = dest2;
2834 operands[5] = operands[1];
2835 }
2836 }
2837 [(set_attr "length" "2")])
2838
2839 ;; Simplify comparisons of extended values.
2840
2841 (define_insn "*cmp_zero_extendqisi2"
2842 [(set (reg:CC 100)
2843 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2844 (const_int 0)))]
2845 ""
2846 "andcc\t%0, 0xff, %%g0"
2847 [(set_attr "type" "compare")])
2848
2849 (define_insn "*cmp_zero_qi"
2850 [(set (reg:CC 100)
2851 (compare:CC (match_operand:QI 0 "register_operand" "r")
2852 (const_int 0)))]
2853 ""
2854 "andcc\t%0, 0xff, %%g0"
2855 [(set_attr "type" "compare")])
2856
2857 (define_insn "*cmp_zero_extendqisi2_set"
2858 [(set (reg:CC 100)
2859 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2860 (const_int 0)))
2861 (set (match_operand:SI 0 "register_operand" "=r")
2862 (zero_extend:SI (match_dup 1)))]
2863 ""
2864 "andcc\t%1, 0xff, %0"
2865 [(set_attr "type" "compare")])
2866
2867 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2868 [(set (reg:CC 100)
2869 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2870 (const_int 255))
2871 (const_int 0)))
2872 (set (match_operand:SI 0 "register_operand" "=r")
2873 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2874 ""
2875 "andcc\t%1, 0xff, %0"
2876 [(set_attr "type" "compare")])
2877
2878 (define_insn "*cmp_zero_extendqidi2"
2879 [(set (reg:CCX 100)
2880 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2881 (const_int 0)))]
2882 "TARGET_ARCH64"
2883 "andcc\t%0, 0xff, %%g0"
2884 [(set_attr "type" "compare")])
2885
2886 (define_insn "*cmp_zero_qi_sp64"
2887 [(set (reg:CCX 100)
2888 (compare:CCX (match_operand:QI 0 "register_operand" "r")
2889 (const_int 0)))]
2890 "TARGET_ARCH64"
2891 "andcc\t%0, 0xff, %%g0"
2892 [(set_attr "type" "compare")])
2893
2894 (define_insn "*cmp_zero_extendqidi2_set"
2895 [(set (reg:CCX 100)
2896 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2897 (const_int 0)))
2898 (set (match_operand:DI 0 "register_operand" "=r")
2899 (zero_extend:DI (match_dup 1)))]
2900 "TARGET_ARCH64"
2901 "andcc\t%1, 0xff, %0"
2902 [(set_attr "type" "compare")])
2903
2904 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2905 [(set (reg:CCX 100)
2906 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2907 (const_int 255))
2908 (const_int 0)))
2909 (set (match_operand:DI 0 "register_operand" "=r")
2910 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2911 "TARGET_ARCH64"
2912 "andcc\t%1, 0xff, %0"
2913 [(set_attr "type" "compare")])
2914
2915 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2916
2917 (define_insn "*cmp_siqi_trunc"
2918 [(set (reg:CC 100)
2919 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2920 (const_int 0)))]
2921 ""
2922 "andcc\t%0, 0xff, %%g0"
2923 [(set_attr "type" "compare")])
2924
2925 (define_insn "*cmp_siqi_trunc_set"
2926 [(set (reg:CC 100)
2927 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
2928 (const_int 0)))
2929 (set (match_operand:QI 0 "register_operand" "=r")
2930 (subreg:QI (match_dup 1) 3))]
2931 ""
2932 "andcc\t%1, 0xff, %0"
2933 [(set_attr "type" "compare")])
2934
2935 (define_insn "*cmp_diqi_trunc"
2936 [(set (reg:CC 100)
2937 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
2938 (const_int 0)))]
2939 "TARGET_ARCH64"
2940 "andcc\t%0, 0xff, %%g0"
2941 [(set_attr "type" "compare")])
2942
2943 (define_insn "*cmp_diqi_trunc_set"
2944 [(set (reg:CC 100)
2945 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
2946 (const_int 0)))
2947 (set (match_operand:QI 0 "register_operand" "=r")
2948 (subreg:QI (match_dup 1) 7))]
2949 "TARGET_ARCH64"
2950 "andcc\t%1, 0xff, %0"
2951 [(set_attr "type" "compare")])
2952 \f
2953
2954 ;; Sign-extension instructions
2955
2956 ;; These patterns originally accepted general_operands, however, slightly
2957 ;; better code is generated by only accepting register_operands, and then
2958 ;; letting combine generate the lds[hb] insns.
2959
2960 (define_expand "extendhisi2"
2961 [(set (match_operand:SI 0 "register_operand" "")
2962 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2963 ""
2964 {
2965 rtx temp = gen_reg_rtx (SImode);
2966 rtx shift_16 = GEN_INT (16);
2967 int op1_subbyte = 0;
2968
2969 if (GET_CODE (operand1) == SUBREG)
2970 {
2971 op1_subbyte = SUBREG_BYTE (operand1);
2972 op1_subbyte /= GET_MODE_SIZE (SImode);
2973 op1_subbyte *= GET_MODE_SIZE (SImode);
2974 operand1 = XEXP (operand1, 0);
2975 }
2976
2977 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2978 shift_16));
2979 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
2980 DONE;
2981 })
2982
2983 (define_insn "*sign_extendhisi2_insn"
2984 [(set (match_operand:SI 0 "register_operand" "=r")
2985 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2986 ""
2987 "ldsh\t%1, %0"
2988 [(set_attr "type" "sload")
2989 (set_attr "us3load_type" "3cycle")])
2990
2991 (define_expand "extendqihi2"
2992 [(set (match_operand:HI 0 "register_operand" "")
2993 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
2994 ""
2995 {
2996 rtx temp = gen_reg_rtx (SImode);
2997 rtx shift_24 = GEN_INT (24);
2998 int op1_subbyte = 0;
2999 int op0_subbyte = 0;
3000
3001 if (GET_CODE (operand1) == SUBREG)
3002 {
3003 op1_subbyte = SUBREG_BYTE (operand1);
3004 op1_subbyte /= GET_MODE_SIZE (SImode);
3005 op1_subbyte *= GET_MODE_SIZE (SImode);
3006 operand1 = XEXP (operand1, 0);
3007 }
3008 if (GET_CODE (operand0) == SUBREG)
3009 {
3010 op0_subbyte = SUBREG_BYTE (operand0);
3011 op0_subbyte /= GET_MODE_SIZE (SImode);
3012 op0_subbyte *= GET_MODE_SIZE (SImode);
3013 operand0 = XEXP (operand0, 0);
3014 }
3015 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3016 shift_24));
3017 if (GET_MODE (operand0) != SImode)
3018 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3019 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3020 DONE;
3021 })
3022
3023 (define_insn "*sign_extendqihi2_insn"
3024 [(set (match_operand:HI 0 "register_operand" "=r")
3025 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3026 ""
3027 "ldsb\t%1, %0"
3028 [(set_attr "type" "sload")
3029 (set_attr "us3load_type" "3cycle")])
3030
3031 (define_expand "extendqisi2"
3032 [(set (match_operand:SI 0 "register_operand" "")
3033 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3034 ""
3035 {
3036 rtx temp = gen_reg_rtx (SImode);
3037 rtx shift_24 = GEN_INT (24);
3038 int op1_subbyte = 0;
3039
3040 if (GET_CODE (operand1) == SUBREG)
3041 {
3042 op1_subbyte = SUBREG_BYTE (operand1);
3043 op1_subbyte /= GET_MODE_SIZE (SImode);
3044 op1_subbyte *= GET_MODE_SIZE (SImode);
3045 operand1 = XEXP (operand1, 0);
3046 }
3047
3048 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3049 shift_24));
3050 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3051 DONE;
3052 })
3053
3054 (define_insn "*sign_extendqisi2_insn"
3055 [(set (match_operand:SI 0 "register_operand" "=r")
3056 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3057 ""
3058 "ldsb\t%1, %0"
3059 [(set_attr "type" "sload")
3060 (set_attr "us3load_type" "3cycle")])
3061
3062 (define_expand "extendqidi2"
3063 [(set (match_operand:DI 0 "register_operand" "")
3064 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3065 "TARGET_ARCH64"
3066 {
3067 rtx temp = gen_reg_rtx (DImode);
3068 rtx shift_56 = GEN_INT (56);
3069 int op1_subbyte = 0;
3070
3071 if (GET_CODE (operand1) == SUBREG)
3072 {
3073 op1_subbyte = SUBREG_BYTE (operand1);
3074 op1_subbyte /= GET_MODE_SIZE (DImode);
3075 op1_subbyte *= GET_MODE_SIZE (DImode);
3076 operand1 = XEXP (operand1, 0);
3077 }
3078
3079 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3080 shift_56));
3081 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3082 DONE;
3083 })
3084
3085 (define_insn "*sign_extendqidi2_insn"
3086 [(set (match_operand:DI 0 "register_operand" "=r")
3087 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3088 "TARGET_ARCH64"
3089 "ldsb\t%1, %0"
3090 [(set_attr "type" "sload")
3091 (set_attr "us3load_type" "3cycle")])
3092
3093 (define_expand "extendhidi2"
3094 [(set (match_operand:DI 0 "register_operand" "")
3095 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3096 "TARGET_ARCH64"
3097 {
3098 rtx temp = gen_reg_rtx (DImode);
3099 rtx shift_48 = GEN_INT (48);
3100 int op1_subbyte = 0;
3101
3102 if (GET_CODE (operand1) == SUBREG)
3103 {
3104 op1_subbyte = SUBREG_BYTE (operand1);
3105 op1_subbyte /= GET_MODE_SIZE (DImode);
3106 op1_subbyte *= GET_MODE_SIZE (DImode);
3107 operand1 = XEXP (operand1, 0);
3108 }
3109
3110 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3111 shift_48));
3112 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3113 DONE;
3114 })
3115
3116 (define_insn "*sign_extendhidi2_insn"
3117 [(set (match_operand:DI 0 "register_operand" "=r")
3118 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3119 "TARGET_ARCH64"
3120 "ldsh\t%1, %0"
3121 [(set_attr "type" "sload")
3122 (set_attr "us3load_type" "3cycle")])
3123
3124 (define_expand "extendsidi2"
3125 [(set (match_operand:DI 0 "register_operand" "")
3126 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3127 "TARGET_ARCH64"
3128 "")
3129
3130 (define_insn "*sign_extendsidi2_insn"
3131 [(set (match_operand:DI 0 "register_operand" "=r,r")
3132 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3133 "TARGET_ARCH64"
3134 "@
3135 sra\t%1, 0, %0
3136 ldsw\t%1, %0"
3137 [(set_attr "type" "shift,sload")
3138 (set_attr "us3load_type" "*,3cycle")])
3139
3140
3141 ;; Special pattern for optimizing bit-field compares. This is needed
3142 ;; because combine uses this as a canonical form.
3143
3144 (define_insn "*cmp_zero_extract"
3145 [(set (reg:CC 100)
3146 (compare:CC
3147 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3148 (match_operand:SI 1 "small_int_operand" "I")
3149 (match_operand:SI 2 "small_int_operand" "I"))
3150 (const_int 0)))]
3151 "INTVAL (operands[2]) > 19"
3152 {
3153 int len = INTVAL (operands[1]);
3154 int pos = 32 - INTVAL (operands[2]) - len;
3155 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3156 operands[1] = GEN_INT (mask);
3157 return "andcc\t%0, %1, %%g0";
3158 }
3159 [(set_attr "type" "compare")])
3160
3161 (define_insn "*cmp_zero_extract_sp64"
3162 [(set (reg:CCX 100)
3163 (compare:CCX
3164 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3165 (match_operand:SI 1 "small_int_operand" "I")
3166 (match_operand:SI 2 "small_int_operand" "I"))
3167 (const_int 0)))]
3168 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3169 {
3170 int len = INTVAL (operands[1]);
3171 int pos = 64 - INTVAL (operands[2]) - len;
3172 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3173 operands[1] = GEN_INT (mask);
3174 return "andcc\t%0, %1, %%g0";
3175 }
3176 [(set_attr "type" "compare")])
3177
3178
3179 ;; Conversions between float, double and long double.
3180
3181 (define_insn "extendsfdf2"
3182 [(set (match_operand:DF 0 "register_operand" "=e")
3183 (float_extend:DF
3184 (match_operand:SF 1 "register_operand" "f")))]
3185 "TARGET_FPU"
3186 "fstod\t%1, %0"
3187 [(set_attr "type" "fp")
3188 (set_attr "fptype" "double")])
3189
3190 (define_expand "extendsftf2"
3191 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3192 (float_extend:TF
3193 (match_operand:SF 1 "register_operand" "")))]
3194 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3195 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3196
3197 (define_insn "*extendsftf2_hq"
3198 [(set (match_operand:TF 0 "register_operand" "=e")
3199 (float_extend:TF
3200 (match_operand:SF 1 "register_operand" "f")))]
3201 "TARGET_FPU && TARGET_HARD_QUAD"
3202 "fstoq\t%1, %0"
3203 [(set_attr "type" "fp")])
3204
3205 (define_expand "extenddftf2"
3206 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3207 (float_extend:TF
3208 (match_operand:DF 1 "register_operand" "")))]
3209 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3210 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3211
3212 (define_insn "*extenddftf2_hq"
3213 [(set (match_operand:TF 0 "register_operand" "=e")
3214 (float_extend:TF
3215 (match_operand:DF 1 "register_operand" "e")))]
3216 "TARGET_FPU && TARGET_HARD_QUAD"
3217 "fdtoq\t%1, %0"
3218 [(set_attr "type" "fp")])
3219
3220 (define_insn "truncdfsf2"
3221 [(set (match_operand:SF 0 "register_operand" "=f")
3222 (float_truncate:SF
3223 (match_operand:DF 1 "register_operand" "e")))]
3224 "TARGET_FPU"
3225 "fdtos\t%1, %0"
3226 [(set_attr "type" "fp")
3227 (set_attr "fptype" "double")])
3228
3229 (define_expand "trunctfsf2"
3230 [(set (match_operand:SF 0 "register_operand" "")
3231 (float_truncate:SF
3232 (match_operand:TF 1 "general_operand" "")))]
3233 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3234 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3235
3236 (define_insn "*trunctfsf2_hq"
3237 [(set (match_operand:SF 0 "register_operand" "=f")
3238 (float_truncate:SF
3239 (match_operand:TF 1 "register_operand" "e")))]
3240 "TARGET_FPU && TARGET_HARD_QUAD"
3241 "fqtos\t%1, %0"
3242 [(set_attr "type" "fp")])
3243
3244 (define_expand "trunctfdf2"
3245 [(set (match_operand:DF 0 "register_operand" "")
3246 (float_truncate:DF
3247 (match_operand:TF 1 "general_operand" "")))]
3248 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3249 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3250
3251 (define_insn "*trunctfdf2_hq"
3252 [(set (match_operand:DF 0 "register_operand" "=e")
3253 (float_truncate:DF
3254 (match_operand:TF 1 "register_operand" "e")))]
3255 "TARGET_FPU && TARGET_HARD_QUAD"
3256 "fqtod\t%1, %0"
3257 [(set_attr "type" "fp")])
3258
3259
3260 ;; Conversion between fixed point and floating point.
3261
3262 (define_insn "floatsisf2"
3263 [(set (match_operand:SF 0 "register_operand" "=f")
3264 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3265 "TARGET_FPU"
3266 "fitos\t%1, %0"
3267 [(set_attr "type" "fp")
3268 (set_attr "fptype" "double")])
3269
3270 (define_insn "floatsidf2"
3271 [(set (match_operand:DF 0 "register_operand" "=e")
3272 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3273 "TARGET_FPU"
3274 "fitod\t%1, %0"
3275 [(set_attr "type" "fp")
3276 (set_attr "fptype" "double")])
3277
3278 (define_expand "floatsitf2"
3279 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3280 (float:TF (match_operand:SI 1 "register_operand" "")))]
3281 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3282 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3283
3284 (define_insn "*floatsitf2_hq"
3285 [(set (match_operand:TF 0 "register_operand" "=e")
3286 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3287 "TARGET_FPU && TARGET_HARD_QUAD"
3288 "fitoq\t%1, %0"
3289 [(set_attr "type" "fp")])
3290
3291 (define_expand "floatunssitf2"
3292 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3293 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3294 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3295 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3296
3297 ;; Now the same for 64 bit sources.
3298
3299 (define_insn "floatdisf2"
3300 [(set (match_operand:SF 0 "register_operand" "=f")
3301 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3302 "TARGET_V9 && TARGET_FPU"
3303 "fxtos\t%1, %0"
3304 [(set_attr "type" "fp")
3305 (set_attr "fptype" "double")])
3306
3307 (define_expand "floatunsdisf2"
3308 [(use (match_operand:SF 0 "register_operand" ""))
3309 (use (match_operand:DI 1 "general_operand" ""))]
3310 "TARGET_ARCH64 && TARGET_FPU"
3311 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3312
3313 (define_insn "floatdidf2"
3314 [(set (match_operand:DF 0 "register_operand" "=e")
3315 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3316 "TARGET_V9 && TARGET_FPU"
3317 "fxtod\t%1, %0"
3318 [(set_attr "type" "fp")
3319 (set_attr "fptype" "double")])
3320
3321 (define_expand "floatunsdidf2"
3322 [(use (match_operand:DF 0 "register_operand" ""))
3323 (use (match_operand:DI 1 "general_operand" ""))]
3324 "TARGET_ARCH64 && TARGET_FPU"
3325 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3326
3327 (define_expand "floatditf2"
3328 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3329 (float:TF (match_operand:DI 1 "register_operand" "")))]
3330 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3331 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3332
3333 (define_insn "*floatditf2_hq"
3334 [(set (match_operand:TF 0 "register_operand" "=e")
3335 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3336 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3337 "fxtoq\t%1, %0"
3338 [(set_attr "type" "fp")])
3339
3340 (define_expand "floatunsditf2"
3341 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3342 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3343 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3344 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3345
3346 ;; Convert a float to an actual integer.
3347 ;; Truncation is performed as part of the conversion.
3348
3349 (define_insn "fix_truncsfsi2"
3350 [(set (match_operand:SI 0 "register_operand" "=f")
3351 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3352 "TARGET_FPU"
3353 "fstoi\t%1, %0"
3354 [(set_attr "type" "fp")
3355 (set_attr "fptype" "double")])
3356
3357 (define_insn "fix_truncdfsi2"
3358 [(set (match_operand:SI 0 "register_operand" "=f")
3359 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3360 "TARGET_FPU"
3361 "fdtoi\t%1, %0"
3362 [(set_attr "type" "fp")
3363 (set_attr "fptype" "double")])
3364
3365 (define_expand "fix_trunctfsi2"
3366 [(set (match_operand:SI 0 "register_operand" "")
3367 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3368 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3369 "emit_tfmode_cvt (FIX, operands); DONE;")
3370
3371 (define_insn "*fix_trunctfsi2_hq"
3372 [(set (match_operand:SI 0 "register_operand" "=f")
3373 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3374 "TARGET_FPU && TARGET_HARD_QUAD"
3375 "fqtoi\t%1, %0"
3376 [(set_attr "type" "fp")])
3377
3378 (define_expand "fixuns_trunctfsi2"
3379 [(set (match_operand:SI 0 "register_operand" "")
3380 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3381 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3382 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3383
3384 ;; Now the same, for V9 targets
3385
3386 (define_insn "fix_truncsfdi2"
3387 [(set (match_operand:DI 0 "register_operand" "=e")
3388 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3389 "TARGET_V9 && TARGET_FPU"
3390 "fstox\t%1, %0"
3391 [(set_attr "type" "fp")
3392 (set_attr "fptype" "double")])
3393
3394 (define_expand "fixuns_truncsfdi2"
3395 [(use (match_operand:DI 0 "register_operand" ""))
3396 (use (match_operand:SF 1 "general_operand" ""))]
3397 "TARGET_ARCH64 && TARGET_FPU"
3398 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3399
3400 (define_insn "fix_truncdfdi2"
3401 [(set (match_operand:DI 0 "register_operand" "=e")
3402 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3403 "TARGET_V9 && TARGET_FPU"
3404 "fdtox\t%1, %0"
3405 [(set_attr "type" "fp")
3406 (set_attr "fptype" "double")])
3407
3408 (define_expand "fixuns_truncdfdi2"
3409 [(use (match_operand:DI 0 "register_operand" ""))
3410 (use (match_operand:DF 1 "general_operand" ""))]
3411 "TARGET_ARCH64 && TARGET_FPU"
3412 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3413
3414 (define_expand "fix_trunctfdi2"
3415 [(set (match_operand:DI 0 "register_operand" "")
3416 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3417 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3418 "emit_tfmode_cvt (FIX, operands); DONE;")
3419
3420 (define_insn "*fix_trunctfdi2_hq"
3421 [(set (match_operand:DI 0 "register_operand" "=e")
3422 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3423 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3424 "fqtox\t%1, %0"
3425 [(set_attr "type" "fp")])
3426
3427 (define_expand "fixuns_trunctfdi2"
3428 [(set (match_operand:DI 0 "register_operand" "")
3429 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3430 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3431 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3432
3433
3434 ;; Integer addition/subtraction instructions.
3435
3436 (define_expand "adddi3"
3437 [(set (match_operand:DI 0 "register_operand" "")
3438 (plus:DI (match_operand:DI 1 "register_operand" "")
3439 (match_operand:DI 2 "arith_double_add_operand" "")))]
3440 ""
3441 {
3442 if (! TARGET_ARCH64)
3443 {
3444 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3445 gen_rtx_SET (VOIDmode, operands[0],
3446 gen_rtx_PLUS (DImode, operands[1],
3447 operands[2])),
3448 gen_rtx_CLOBBER (VOIDmode,
3449 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3450 DONE;
3451 }
3452 })
3453
3454 (define_insn_and_split "adddi3_insn_sp32"
3455 [(set (match_operand:DI 0 "register_operand" "=r")
3456 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3457 (match_operand:DI 2 "arith_double_operand" "rHI")))
3458 (clobber (reg:CC 100))]
3459 "! TARGET_ARCH64"
3460 "#"
3461 "&& reload_completed"
3462 [(parallel [(set (reg:CC_NOOV 100)
3463 (compare:CC_NOOV (plus:SI (match_dup 4)
3464 (match_dup 5))
3465 (const_int 0)))
3466 (set (match_dup 3)
3467 (plus:SI (match_dup 4) (match_dup 5)))])
3468 (set (match_dup 6)
3469 (plus:SI (plus:SI (match_dup 7)
3470 (match_dup 8))
3471 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3472 {
3473 operands[3] = gen_lowpart (SImode, operands[0]);
3474 operands[4] = gen_lowpart (SImode, operands[1]);
3475 operands[5] = gen_lowpart (SImode, operands[2]);
3476 operands[6] = gen_highpart (SImode, operands[0]);
3477 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3478 #if HOST_BITS_PER_WIDE_INT == 32
3479 if (GET_CODE (operands[2]) == CONST_INT)
3480 {
3481 if (INTVAL (operands[2]) < 0)
3482 operands[8] = constm1_rtx;
3483 else
3484 operands[8] = const0_rtx;
3485 }
3486 else
3487 #endif
3488 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3489 }
3490 [(set_attr "length" "2")])
3491
3492 ;; LTU here means "carry set"
3493 (define_insn "addx"
3494 [(set (match_operand:SI 0 "register_operand" "=r")
3495 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3496 (match_operand:SI 2 "arith_operand" "rI"))
3497 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3498 ""
3499 "addx\t%1, %2, %0"
3500 [(set_attr "type" "ialuX")])
3501
3502 (define_insn_and_split "*addx_extend_sp32"
3503 [(set (match_operand:DI 0 "register_operand" "=r")
3504 (zero_extend:DI (plus:SI (plus:SI
3505 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3506 (match_operand:SI 2 "arith_operand" "rI"))
3507 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3508 "! TARGET_ARCH64"
3509 "#"
3510 "&& reload_completed"
3511 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3512 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3513 (set (match_dup 4) (const_int 0))]
3514 "operands[3] = gen_lowpart (SImode, operands[0]);
3515 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3516 [(set_attr "length" "2")])
3517
3518 (define_insn "*addx_extend_sp64"
3519 [(set (match_operand:DI 0 "register_operand" "=r")
3520 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3521 (match_operand:SI 2 "arith_operand" "rI"))
3522 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3523 "TARGET_ARCH64"
3524 "addx\t%r1, %2, %0"
3525 [(set_attr "type" "ialuX")])
3526
3527 (define_insn_and_split ""
3528 [(set (match_operand:DI 0 "register_operand" "=r")
3529 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3530 (match_operand:DI 2 "register_operand" "r")))
3531 (clobber (reg:CC 100))]
3532 "! TARGET_ARCH64"
3533 "#"
3534 "&& reload_completed"
3535 [(parallel [(set (reg:CC_NOOV 100)
3536 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3537 (const_int 0)))
3538 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3539 (set (match_dup 6)
3540 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3541 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3542 "operands[3] = gen_lowpart (SImode, operands[2]);
3543 operands[4] = gen_highpart (SImode, operands[2]);
3544 operands[5] = gen_lowpart (SImode, operands[0]);
3545 operands[6] = gen_highpart (SImode, operands[0]);"
3546 [(set_attr "length" "2")])
3547
3548 (define_insn "*adddi3_sp64"
3549 [(set (match_operand:DI 0 "register_operand" "=r,r")
3550 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3551 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3552 "TARGET_ARCH64"
3553 "@
3554 add\t%1, %2, %0
3555 sub\t%1, -%2, %0")
3556
3557 (define_insn "addsi3"
3558 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3559 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3560 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3561 ""
3562 "@
3563 add\t%1, %2, %0
3564 sub\t%1, -%2, %0
3565 fpadd32s\t%1, %2, %0"
3566 [(set_attr "type" "*,*,fga")
3567 (set_attr "fptype" "*,*,single")])
3568
3569 (define_insn "*cmp_cc_plus"
3570 [(set (reg:CC_NOOV 100)
3571 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3572 (match_operand:SI 1 "arith_operand" "rI"))
3573 (const_int 0)))]
3574 ""
3575 "addcc\t%0, %1, %%g0"
3576 [(set_attr "type" "compare")])
3577
3578 (define_insn "*cmp_ccx_plus"
3579 [(set (reg:CCX_NOOV 100)
3580 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3581 (match_operand:DI 1 "arith_operand" "rI"))
3582 (const_int 0)))]
3583 "TARGET_ARCH64"
3584 "addcc\t%0, %1, %%g0"
3585 [(set_attr "type" "compare")])
3586
3587 (define_insn "*cmp_cc_plus_set"
3588 [(set (reg:CC_NOOV 100)
3589 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3590 (match_operand:SI 2 "arith_operand" "rI"))
3591 (const_int 0)))
3592 (set (match_operand:SI 0 "register_operand" "=r")
3593 (plus:SI (match_dup 1) (match_dup 2)))]
3594 ""
3595 "addcc\t%1, %2, %0"
3596 [(set_attr "type" "compare")])
3597
3598 (define_insn "*cmp_ccx_plus_set"
3599 [(set (reg:CCX_NOOV 100)
3600 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3601 (match_operand:DI 2 "arith_operand" "rI"))
3602 (const_int 0)))
3603 (set (match_operand:DI 0 "register_operand" "=r")
3604 (plus:DI (match_dup 1) (match_dup 2)))]
3605 "TARGET_ARCH64"
3606 "addcc\t%1, %2, %0"
3607 [(set_attr "type" "compare")])
3608
3609 (define_expand "subdi3"
3610 [(set (match_operand:DI 0 "register_operand" "")
3611 (minus:DI (match_operand:DI 1 "register_operand" "")
3612 (match_operand:DI 2 "arith_double_add_operand" "")))]
3613 ""
3614 {
3615 if (! TARGET_ARCH64)
3616 {
3617 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3618 gen_rtx_SET (VOIDmode, operands[0],
3619 gen_rtx_MINUS (DImode, operands[1],
3620 operands[2])),
3621 gen_rtx_CLOBBER (VOIDmode,
3622 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3623 DONE;
3624 }
3625 })
3626
3627 (define_insn_and_split "subdi3_insn_sp32"
3628 [(set (match_operand:DI 0 "register_operand" "=r")
3629 (minus:DI (match_operand:DI 1 "register_operand" "r")
3630 (match_operand:DI 2 "arith_double_operand" "rHI")))
3631 (clobber (reg:CC 100))]
3632 "! TARGET_ARCH64"
3633 "#"
3634 "&& reload_completed"
3635 [(parallel [(set (reg:CC_NOOV 100)
3636 (compare:CC_NOOV (minus:SI (match_dup 4)
3637 (match_dup 5))
3638 (const_int 0)))
3639 (set (match_dup 3)
3640 (minus:SI (match_dup 4) (match_dup 5)))])
3641 (set (match_dup 6)
3642 (minus:SI (minus:SI (match_dup 7)
3643 (match_dup 8))
3644 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3645 {
3646 operands[3] = gen_lowpart (SImode, operands[0]);
3647 operands[4] = gen_lowpart (SImode, operands[1]);
3648 operands[5] = gen_lowpart (SImode, operands[2]);
3649 operands[6] = gen_highpart (SImode, operands[0]);
3650 operands[7] = gen_highpart (SImode, operands[1]);
3651 #if HOST_BITS_PER_WIDE_INT == 32
3652 if (GET_CODE (operands[2]) == CONST_INT)
3653 {
3654 if (INTVAL (operands[2]) < 0)
3655 operands[8] = constm1_rtx;
3656 else
3657 operands[8] = const0_rtx;
3658 }
3659 else
3660 #endif
3661 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3662 }
3663 [(set_attr "length" "2")])
3664
3665 ;; LTU here means "carry set"
3666 (define_insn "subx"
3667 [(set (match_operand:SI 0 "register_operand" "=r")
3668 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3669 (match_operand:SI 2 "arith_operand" "rI"))
3670 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3671 ""
3672 "subx\t%r1, %2, %0"
3673 [(set_attr "type" "ialuX")])
3674
3675 (define_insn "*subx_extend_sp64"
3676 [(set (match_operand:DI 0 "register_operand" "=r")
3677 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3678 (match_operand:SI 2 "arith_operand" "rI"))
3679 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3680 "TARGET_ARCH64"
3681 "subx\t%r1, %2, %0"
3682 [(set_attr "type" "ialuX")])
3683
3684 (define_insn_and_split "*subx_extend"
3685 [(set (match_operand:DI 0 "register_operand" "=r")
3686 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3687 (match_operand:SI 2 "arith_operand" "rI"))
3688 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3689 "! TARGET_ARCH64"
3690 "#"
3691 "&& reload_completed"
3692 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3693 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3694 (set (match_dup 4) (const_int 0))]
3695 "operands[3] = gen_lowpart (SImode, operands[0]);
3696 operands[4] = gen_highpart (SImode, operands[0]);"
3697 [(set_attr "length" "2")])
3698
3699 (define_insn_and_split ""
3700 [(set (match_operand:DI 0 "register_operand" "=r")
3701 (minus:DI (match_operand:DI 1 "register_operand" "r")
3702 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3703 (clobber (reg:CC 100))]
3704 "! TARGET_ARCH64"
3705 "#"
3706 "&& reload_completed"
3707 [(parallel [(set (reg:CC_NOOV 100)
3708 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3709 (const_int 0)))
3710 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3711 (set (match_dup 6)
3712 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3713 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3714 "operands[3] = gen_lowpart (SImode, operands[1]);
3715 operands[4] = gen_highpart (SImode, operands[1]);
3716 operands[5] = gen_lowpart (SImode, operands[0]);
3717 operands[6] = gen_highpart (SImode, operands[0]);"
3718 [(set_attr "length" "2")])
3719
3720 (define_insn "*subdi3_sp64"
3721 [(set (match_operand:DI 0 "register_operand" "=r,r")
3722 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3723 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3724 "TARGET_ARCH64"
3725 "@
3726 sub\t%1, %2, %0
3727 add\t%1, -%2, %0")
3728
3729 (define_insn "subsi3"
3730 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3731 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3732 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3733 ""
3734 "@
3735 sub\t%1, %2, %0
3736 add\t%1, -%2, %0
3737 fpsub32s\t%1, %2, %0"
3738 [(set_attr "type" "*,*,fga")
3739 (set_attr "fptype" "*,*,single")])
3740
3741 (define_insn "*cmp_minus_cc"
3742 [(set (reg:CC_NOOV 100)
3743 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3744 (match_operand:SI 1 "arith_operand" "rI"))
3745 (const_int 0)))]
3746 ""
3747 "subcc\t%r0, %1, %%g0"
3748 [(set_attr "type" "compare")])
3749
3750 (define_insn "*cmp_minus_ccx"
3751 [(set (reg:CCX_NOOV 100)
3752 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3753 (match_operand:DI 1 "arith_operand" "rI"))
3754 (const_int 0)))]
3755 "TARGET_ARCH64"
3756 "subcc\t%0, %1, %%g0"
3757 [(set_attr "type" "compare")])
3758
3759 (define_insn "cmp_minus_cc_set"
3760 [(set (reg:CC_NOOV 100)
3761 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3762 (match_operand:SI 2 "arith_operand" "rI"))
3763 (const_int 0)))
3764 (set (match_operand:SI 0 "register_operand" "=r")
3765 (minus:SI (match_dup 1) (match_dup 2)))]
3766 ""
3767 "subcc\t%r1, %2, %0"
3768 [(set_attr "type" "compare")])
3769
3770 (define_insn "*cmp_minus_ccx_set"
3771 [(set (reg:CCX_NOOV 100)
3772 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3773 (match_operand:DI 2 "arith_operand" "rI"))
3774 (const_int 0)))
3775 (set (match_operand:DI 0 "register_operand" "=r")
3776 (minus:DI (match_dup 1) (match_dup 2)))]
3777 "TARGET_ARCH64"
3778 "subcc\t%1, %2, %0"
3779 [(set_attr "type" "compare")])
3780
3781
3782 ;; Integer multiply/divide instructions.
3783
3784 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3785 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3786
3787 (define_insn "mulsi3"
3788 [(set (match_operand:SI 0 "register_operand" "=r")
3789 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3790 (match_operand:SI 2 "arith_operand" "rI")))]
3791 "TARGET_HARD_MUL"
3792 "smul\t%1, %2, %0"
3793 [(set_attr "type" "imul")])
3794
3795 (define_expand "muldi3"
3796 [(set (match_operand:DI 0 "register_operand" "")
3797 (mult:DI (match_operand:DI 1 "arith_operand" "")
3798 (match_operand:DI 2 "arith_operand" "")))]
3799 "TARGET_ARCH64 || TARGET_V8PLUS"
3800 {
3801 if (TARGET_V8PLUS)
3802 {
3803 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3804 DONE;
3805 }
3806 })
3807
3808 (define_insn "*muldi3_sp64"
3809 [(set (match_operand:DI 0 "register_operand" "=r")
3810 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3811 (match_operand:DI 2 "arith_operand" "rI")))]
3812 "TARGET_ARCH64"
3813 "mulx\t%1, %2, %0"
3814 [(set_attr "type" "imul")])
3815
3816 ;; V8plus wide multiply.
3817 ;; XXX
3818 (define_insn "muldi3_v8plus"
3819 [(set (match_operand:DI 0 "register_operand" "=r,h")
3820 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3821 (match_operand:DI 2 "arith_operand" "rI,rI")))
3822 (clobber (match_scratch:SI 3 "=&h,X"))
3823 (clobber (match_scratch:SI 4 "=&h,X"))]
3824 "TARGET_V8PLUS"
3825 {
3826 if (sparc_check_64 (operands[1], insn) <= 0)
3827 output_asm_insn ("srl\t%L1, 0, %L1", operands);
3828 if (which_alternative == 1)
3829 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3830 if (GET_CODE (operands[2]) == CONST_INT)
3831 {
3832 if (which_alternative == 1)
3833 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
3834 else
3835 return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
3836 }
3837 else if (rtx_equal_p (operands[1], operands[2]))
3838 {
3839 if (which_alternative == 1)
3840 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
3841 else
3842 return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %3, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
3843 }
3844 if (sparc_check_64 (operands[2], insn) <= 0)
3845 output_asm_insn ("srl\t%L2, 0, %L2", operands);
3846 if (which_alternative == 1)
3847 return "or\t%L1, %H1, %H1\n\tsllx\t%H2, 32, %L1\n\tor\t%L2, %L1, %L1\n\tmulx\t%H1, %L1, %L0\;srlx\t%L0, 32, %H0";
3848 else
3849 return "sllx\t%H1, 32, %3\n\tsllx\t%H2, 32, %4\n\tor\t%L1, %3, %3\n\tor\t%L2, %4, %4\n\tmulx\t%3, %4, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
3850 }
3851 [(set_attr "type" "multi")
3852 (set_attr "length" "9,8")])
3853
3854 (define_insn "*cmp_mul_set"
3855 [(set (reg:CC 100)
3856 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3857 (match_operand:SI 2 "arith_operand" "rI"))
3858 (const_int 0)))
3859 (set (match_operand:SI 0 "register_operand" "=r")
3860 (mult:SI (match_dup 1) (match_dup 2)))]
3861 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3862 "smulcc\t%1, %2, %0"
3863 [(set_attr "type" "imul")])
3864
3865 (define_expand "mulsidi3"
3866 [(set (match_operand:DI 0 "register_operand" "")
3867 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3868 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3869 "TARGET_HARD_MUL"
3870 {
3871 if (CONSTANT_P (operands[2]))
3872 {
3873 if (TARGET_V8PLUS)
3874 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3875 operands[2]));
3876 else if (TARGET_ARCH32)
3877 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3878 operands[2]));
3879 else
3880 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3881 operands[2]));
3882 DONE;
3883 }
3884 if (TARGET_V8PLUS)
3885 {
3886 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3887 DONE;
3888 }
3889 })
3890
3891 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
3892 ;; registers can hold 64-bit values in the V8plus environment.
3893 ;; XXX
3894 (define_insn "mulsidi3_v8plus"
3895 [(set (match_operand:DI 0 "register_operand" "=h,r")
3896 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3897 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3898 (clobber (match_scratch:SI 3 "=X,&h"))]
3899 "TARGET_V8PLUS"
3900 "@
3901 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3902 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3903 [(set_attr "type" "multi")
3904 (set_attr "length" "2,3")])
3905
3906 ;; XXX
3907 (define_insn "const_mulsidi3_v8plus"
3908 [(set (match_operand:DI 0 "register_operand" "=h,r")
3909 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3910 (match_operand:DI 2 "small_int_operand" "I,I")))
3911 (clobber (match_scratch:SI 3 "=X,&h"))]
3912 "TARGET_V8PLUS"
3913 "@
3914 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3915 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3916 [(set_attr "type" "multi")
3917 (set_attr "length" "2,3")])
3918
3919 ;; XXX
3920 (define_insn "*mulsidi3_sp32"
3921 [(set (match_operand:DI 0 "register_operand" "=r")
3922 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3923 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3924 "TARGET_HARD_MUL32"
3925 {
3926 return TARGET_SPARCLET
3927 ? "smuld\t%1, %2, %L0"
3928 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3929 }
3930 [(set (attr "type")
3931 (if_then_else (eq_attr "isa" "sparclet")
3932 (const_string "imul") (const_string "multi")))
3933 (set (attr "length")
3934 (if_then_else (eq_attr "isa" "sparclet")
3935 (const_int 1) (const_int 2)))])
3936
3937 (define_insn "*mulsidi3_sp64"
3938 [(set (match_operand:DI 0 "register_operand" "=r")
3939 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3940 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3941 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
3942 "smul\t%1, %2, %0"
3943 [(set_attr "type" "imul")])
3944
3945 ;; Extra pattern, because sign_extend of a constant isn't valid.
3946
3947 ;; XXX
3948 (define_insn "const_mulsidi3_sp32"
3949 [(set (match_operand:DI 0 "register_operand" "=r")
3950 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3951 (match_operand:DI 2 "small_int_operand" "I")))]
3952 "TARGET_HARD_MUL32"
3953 {
3954 return TARGET_SPARCLET
3955 ? "smuld\t%1, %2, %L0"
3956 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3957 }
3958 [(set (attr "type")
3959 (if_then_else (eq_attr "isa" "sparclet")
3960 (const_string "imul") (const_string "multi")))
3961 (set (attr "length")
3962 (if_then_else (eq_attr "isa" "sparclet")
3963 (const_int 1) (const_int 2)))])
3964
3965 (define_insn "const_mulsidi3_sp64"
3966 [(set (match_operand:DI 0 "register_operand" "=r")
3967 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3968 (match_operand:DI 2 "small_int_operand" "I")))]
3969 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
3970 "smul\t%1, %2, %0"
3971 [(set_attr "type" "imul")])
3972
3973 (define_expand "smulsi3_highpart"
3974 [(set (match_operand:SI 0 "register_operand" "")
3975 (truncate:SI
3976 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3977 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
3978 (const_int 32))))]
3979 "TARGET_HARD_MUL && TARGET_ARCH32"
3980 {
3981 if (CONSTANT_P (operands[2]))
3982 {
3983 if (TARGET_V8PLUS)
3984 {
3985 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
3986 operands[1],
3987 operands[2],
3988 GEN_INT (32)));
3989 DONE;
3990 }
3991 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
3992 DONE;
3993 }
3994 if (TARGET_V8PLUS)
3995 {
3996 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
3997 operands[2], GEN_INT (32)));
3998 DONE;
3999 }
4000 })
4001
4002 ;; XXX
4003 (define_insn "smulsi3_highpart_v8plus"
4004 [(set (match_operand:SI 0 "register_operand" "=h,r")
4005 (truncate:SI
4006 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4007 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4008 (match_operand:SI 3 "small_int_operand" "I,I"))))
4009 (clobber (match_scratch:SI 4 "=X,&h"))]
4010 "TARGET_V8PLUS"
4011 "@
4012 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4013 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4014 [(set_attr "type" "multi")
4015 (set_attr "length" "2")])
4016
4017 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4018 ;; XXX
4019 (define_insn ""
4020 [(set (match_operand:SI 0 "register_operand" "=h,r")
4021 (subreg:SI
4022 (lshiftrt:DI
4023 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4024 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4025 (match_operand:SI 3 "small_int_operand" "I,I"))
4026 4))
4027 (clobber (match_scratch:SI 4 "=X,&h"))]
4028 "TARGET_V8PLUS"
4029 "@
4030 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4031 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4032 [(set_attr "type" "multi")
4033 (set_attr "length" "2")])
4034
4035 ;; XXX
4036 (define_insn "const_smulsi3_highpart_v8plus"
4037 [(set (match_operand:SI 0 "register_operand" "=h,r")
4038 (truncate:SI
4039 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4040 (match_operand:DI 2 "small_int_operand" "I,I"))
4041 (match_operand:SI 3 "small_int_operand" "I,I"))))
4042 (clobber (match_scratch:SI 4 "=X,&h"))]
4043 "TARGET_V8PLUS"
4044 "@
4045 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4046 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4047 [(set_attr "type" "multi")
4048 (set_attr "length" "2")])
4049
4050 ;; XXX
4051 (define_insn "*smulsi3_highpart_sp32"
4052 [(set (match_operand:SI 0 "register_operand" "=r")
4053 (truncate:SI
4054 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4055 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4056 (const_int 32))))]
4057 "TARGET_HARD_MUL32"
4058 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4059 [(set_attr "type" "multi")
4060 (set_attr "length" "2")])
4061
4062 ;; XXX
4063 (define_insn "const_smulsi3_highpart"
4064 [(set (match_operand:SI 0 "register_operand" "=r")
4065 (truncate:SI
4066 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4067 (match_operand:DI 2 "small_int_operand" "i"))
4068 (const_int 32))))]
4069 "TARGET_HARD_MUL32"
4070 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4071 [(set_attr "type" "multi")
4072 (set_attr "length" "2")])
4073
4074 (define_expand "umulsidi3"
4075 [(set (match_operand:DI 0 "register_operand" "")
4076 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4077 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4078 "TARGET_HARD_MUL"
4079 {
4080 if (CONSTANT_P (operands[2]))
4081 {
4082 if (TARGET_V8PLUS)
4083 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4084 operands[2]));
4085 else if (TARGET_ARCH32)
4086 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4087 operands[2]));
4088 else
4089 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4090 operands[2]));
4091 DONE;
4092 }
4093 if (TARGET_V8PLUS)
4094 {
4095 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4096 DONE;
4097 }
4098 })
4099
4100 ;; XXX
4101 (define_insn "umulsidi3_v8plus"
4102 [(set (match_operand:DI 0 "register_operand" "=h,r")
4103 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4104 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4105 (clobber (match_scratch:SI 3 "=X,&h"))]
4106 "TARGET_V8PLUS"
4107 "@
4108 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4109 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4110 [(set_attr "type" "multi")
4111 (set_attr "length" "2,3")])
4112
4113 ;; XXX
4114 (define_insn "*umulsidi3_sp32"
4115 [(set (match_operand:DI 0 "register_operand" "=r")
4116 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4117 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4118 "TARGET_HARD_MUL32"
4119 {
4120 return TARGET_SPARCLET
4121 ? "umuld\t%1, %2, %L0"
4122 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4123 }
4124 [(set (attr "type")
4125 (if_then_else (eq_attr "isa" "sparclet")
4126 (const_string "imul") (const_string "multi")))
4127 (set (attr "length")
4128 (if_then_else (eq_attr "isa" "sparclet")
4129 (const_int 1) (const_int 2)))])
4130
4131 (define_insn "*umulsidi3_sp64"
4132 [(set (match_operand:DI 0 "register_operand" "=r")
4133 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4134 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4135 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4136 "umul\t%1, %2, %0"
4137 [(set_attr "type" "imul")])
4138
4139 ;; Extra pattern, because sign_extend of a constant isn't valid.
4140
4141 ;; XXX
4142 (define_insn "const_umulsidi3_sp32"
4143 [(set (match_operand:DI 0 "register_operand" "=r")
4144 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4145 (match_operand:DI 2 "uns_small_int_operand" "")))]
4146 "TARGET_HARD_MUL32"
4147 {
4148 return TARGET_SPARCLET
4149 ? "umuld\t%1, %s2, %L0"
4150 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4151 }
4152 [(set (attr "type")
4153 (if_then_else (eq_attr "isa" "sparclet")
4154 (const_string "imul") (const_string "multi")))
4155 (set (attr "length")
4156 (if_then_else (eq_attr "isa" "sparclet")
4157 (const_int 1) (const_int 2)))])
4158
4159 (define_insn "const_umulsidi3_sp64"
4160 [(set (match_operand:DI 0 "register_operand" "=r")
4161 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4162 (match_operand:DI 2 "uns_small_int_operand" "")))]
4163 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4164 "umul\t%1, %s2, %0"
4165 [(set_attr "type" "imul")])
4166
4167 ;; XXX
4168 (define_insn "const_umulsidi3_v8plus"
4169 [(set (match_operand:DI 0 "register_operand" "=h,r")
4170 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4171 (match_operand:DI 2 "uns_small_int_operand" "")))
4172 (clobber (match_scratch:SI 3 "=X,h"))]
4173 "TARGET_V8PLUS"
4174 "@
4175 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4176 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4177 [(set_attr "type" "multi")
4178 (set_attr "length" "2,3")])
4179
4180 (define_expand "umulsi3_highpart"
4181 [(set (match_operand:SI 0 "register_operand" "")
4182 (truncate:SI
4183 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4184 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4185 (const_int 32))))]
4186 "TARGET_HARD_MUL && TARGET_ARCH32"
4187 {
4188 if (CONSTANT_P (operands[2]))
4189 {
4190 if (TARGET_V8PLUS)
4191 {
4192 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4193 operands[1],
4194 operands[2],
4195 GEN_INT (32)));
4196 DONE;
4197 }
4198 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4199 DONE;
4200 }
4201 if (TARGET_V8PLUS)
4202 {
4203 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4204 operands[2], GEN_INT (32)));
4205 DONE;
4206 }
4207 })
4208
4209 ;; XXX
4210 (define_insn "umulsi3_highpart_v8plus"
4211 [(set (match_operand:SI 0 "register_operand" "=h,r")
4212 (truncate:SI
4213 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4214 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4215 (match_operand:SI 3 "small_int_operand" "I,I"))))
4216 (clobber (match_scratch:SI 4 "=X,h"))]
4217 "TARGET_V8PLUS"
4218 "@
4219 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4220 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4221 [(set_attr "type" "multi")
4222 (set_attr "length" "2")])
4223
4224 ;; XXX
4225 (define_insn "const_umulsi3_highpart_v8plus"
4226 [(set (match_operand:SI 0 "register_operand" "=h,r")
4227 (truncate:SI
4228 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4229 (match_operand:DI 2 "uns_small_int_operand" ""))
4230 (match_operand:SI 3 "small_int_operand" "I,I"))))
4231 (clobber (match_scratch:SI 4 "=X,h"))]
4232 "TARGET_V8PLUS"
4233 "@
4234 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4235 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4236 [(set_attr "type" "multi")
4237 (set_attr "length" "2")])
4238
4239 ;; XXX
4240 (define_insn "*umulsi3_highpart_sp32"
4241 [(set (match_operand:SI 0 "register_operand" "=r")
4242 (truncate:SI
4243 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4244 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4245 (const_int 32))))]
4246 "TARGET_HARD_MUL32"
4247 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4248 [(set_attr "type" "multi")
4249 (set_attr "length" "2")])
4250
4251 ;; XXX
4252 (define_insn "const_umulsi3_highpart"
4253 [(set (match_operand:SI 0 "register_operand" "=r")
4254 (truncate:SI
4255 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4256 (match_operand:DI 2 "uns_small_int_operand" ""))
4257 (const_int 32))))]
4258 "TARGET_HARD_MUL32"
4259 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4260 [(set_attr "type" "multi")
4261 (set_attr "length" "2")])
4262
4263 (define_expand "divsi3"
4264 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4265 (div:SI (match_operand:SI 1 "register_operand" "")
4266 (match_operand:SI 2 "input_operand" "")))
4267 (clobber (match_scratch:SI 3 ""))])]
4268 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4269 {
4270 if (TARGET_ARCH64)
4271 {
4272 operands[3] = gen_reg_rtx(SImode);
4273 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4274 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4275 operands[3]));
4276 DONE;
4277 }
4278 })
4279
4280 ;; The V8 architecture specifies that there must be at least 3 instructions
4281 ;; between a write to the Y register and a use of it for correct results.
4282 ;; We try to fill one of them with a simple constant or a memory load.
4283
4284 (define_insn "divsi3_sp32"
4285 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4286 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4287 (match_operand:SI 2 "input_operand" "rI,K,m")))
4288 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4289 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4290 {
4291 output_asm_insn ("sra\t%1, 31, %3", operands);
4292 output_asm_insn ("wr\t%3, 0, %%y", operands);
4293
4294 switch (which_alternative)
4295 {
4296 case 0:
4297 if (TARGET_V9)
4298 return "sdiv\t%1, %2, %0";
4299 else
4300 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4301 case 1:
4302 if (TARGET_V9)
4303 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4304 else
4305 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4306 case 2:
4307 if (TARGET_V9)
4308 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4309 else
4310 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4311 default:
4312 gcc_unreachable ();
4313 }
4314 }
4315 [(set_attr "type" "multi")
4316 (set (attr "length")
4317 (if_then_else (eq_attr "isa" "v9")
4318 (const_int 4) (const_int 6)))])
4319
4320 (define_insn "divsi3_sp64"
4321 [(set (match_operand:SI 0 "register_operand" "=r")
4322 (div:SI (match_operand:SI 1 "register_operand" "r")
4323 (match_operand:SI 2 "input_operand" "rI")))
4324 (use (match_operand:SI 3 "register_operand" "r"))]
4325 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4326 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4327 [(set_attr "type" "multi")
4328 (set_attr "length" "2")])
4329
4330 (define_insn "divdi3"
4331 [(set (match_operand:DI 0 "register_operand" "=r")
4332 (div:DI (match_operand:DI 1 "register_operand" "r")
4333 (match_operand:DI 2 "arith_operand" "rI")))]
4334 "TARGET_ARCH64"
4335 "sdivx\t%1, %2, %0"
4336 [(set_attr "type" "idiv")])
4337
4338 (define_insn "*cmp_sdiv_cc_set"
4339 [(set (reg:CC 100)
4340 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4341 (match_operand:SI 2 "arith_operand" "rI"))
4342 (const_int 0)))
4343 (set (match_operand:SI 0 "register_operand" "=r")
4344 (div:SI (match_dup 1) (match_dup 2)))
4345 (clobber (match_scratch:SI 3 "=&r"))]
4346 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4347 {
4348 output_asm_insn ("sra\t%1, 31, %3", operands);
4349 output_asm_insn ("wr\t%3, 0, %%y", operands);
4350
4351 if (TARGET_V9)
4352 return "sdivcc\t%1, %2, %0";
4353 else
4354 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4355 }
4356 [(set_attr "type" "multi")
4357 (set (attr "length")
4358 (if_then_else (eq_attr "isa" "v9")
4359 (const_int 3) (const_int 6)))])
4360
4361 ;; XXX
4362 (define_expand "udivsi3"
4363 [(set (match_operand:SI 0 "register_operand" "")
4364 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4365 (match_operand:SI 2 "input_operand" "")))]
4366 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4367 "")
4368
4369 ;; The V8 architecture specifies that there must be at least 3 instructions
4370 ;; between a write to the Y register and a use of it for correct results.
4371 ;; We try to fill one of them with a simple constant or a memory load.
4372
4373 (define_insn "udivsi3_sp32"
4374 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4375 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4376 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4377 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4378 {
4379 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4380
4381 switch (which_alternative)
4382 {
4383 case 0:
4384 if (TARGET_V9)
4385 return "udiv\t%1, %2, %0";
4386 else
4387 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4388 case 1:
4389 if (TARGET_V9)
4390 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4391 else
4392 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4393 case 2:
4394 if (TARGET_V9)
4395 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4396 else
4397 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4398 case 3:
4399 if (TARGET_V9)
4400 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4401 else
4402 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4403 default:
4404 gcc_unreachable ();
4405 }
4406 }
4407 [(set_attr "type" "multi")
4408 (set (attr "length")
4409 (if_then_else (eq_attr "isa" "v9")
4410 (const_int 3) (const_int 5)))])
4411
4412 (define_insn "udivsi3_sp64"
4413 [(set (match_operand:SI 0 "register_operand" "=r")
4414 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4415 (match_operand:SI 2 "input_operand" "rI")))]
4416 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4417 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4418 [(set_attr "type" "multi")
4419 (set_attr "length" "2")])
4420
4421 (define_insn "udivdi3"
4422 [(set (match_operand:DI 0 "register_operand" "=r")
4423 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4424 (match_operand:DI 2 "arith_operand" "rI")))]
4425 "TARGET_ARCH64"
4426 "udivx\t%1, %2, %0"
4427 [(set_attr "type" "idiv")])
4428
4429 (define_insn "*cmp_udiv_cc_set"
4430 [(set (reg:CC 100)
4431 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4432 (match_operand:SI 2 "arith_operand" "rI"))
4433 (const_int 0)))
4434 (set (match_operand:SI 0 "register_operand" "=r")
4435 (udiv:SI (match_dup 1) (match_dup 2)))]
4436 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4437 {
4438 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4439
4440 if (TARGET_V9)
4441 return "udivcc\t%1, %2, %0";
4442 else
4443 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4444 }
4445 [(set_attr "type" "multi")
4446 (set (attr "length")
4447 (if_then_else (eq_attr "isa" "v9")
4448 (const_int 2) (const_int 5)))])
4449
4450 ; sparclet multiply/accumulate insns
4451
4452 (define_insn "*smacsi"
4453 [(set (match_operand:SI 0 "register_operand" "=r")
4454 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4455 (match_operand:SI 2 "arith_operand" "rI"))
4456 (match_operand:SI 3 "register_operand" "0")))]
4457 "TARGET_SPARCLET"
4458 "smac\t%1, %2, %0"
4459 [(set_attr "type" "imul")])
4460
4461 (define_insn "*smacdi"
4462 [(set (match_operand:DI 0 "register_operand" "=r")
4463 (plus:DI (mult:DI (sign_extend:DI
4464 (match_operand:SI 1 "register_operand" "%r"))
4465 (sign_extend:DI
4466 (match_operand:SI 2 "register_operand" "r")))
4467 (match_operand:DI 3 "register_operand" "0")))]
4468 "TARGET_SPARCLET"
4469 "smacd\t%1, %2, %L0"
4470 [(set_attr "type" "imul")])
4471
4472 (define_insn "*umacdi"
4473 [(set (match_operand:DI 0 "register_operand" "=r")
4474 (plus:DI (mult:DI (zero_extend:DI
4475 (match_operand:SI 1 "register_operand" "%r"))
4476 (zero_extend:DI
4477 (match_operand:SI 2 "register_operand" "r")))
4478 (match_operand:DI 3 "register_operand" "0")))]
4479 "TARGET_SPARCLET"
4480 "umacd\t%1, %2, %L0"
4481 [(set_attr "type" "imul")])
4482
4483
4484 ;; Boolean instructions.
4485
4486 ;; We define DImode `and' so with DImode `not' we can get
4487 ;; DImode `andn'. Other combinations are possible.
4488
4489 (define_expand "and<V64I:mode>3"
4490 [(set (match_operand:V64I 0 "register_operand" "")
4491 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4492 (match_operand:V64I 2 "arith_double_operand" "")))]
4493 ""
4494 "")
4495
4496 (define_insn "*and<V64I:mode>3_sp32"
4497 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4498 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4499 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4500 "! TARGET_ARCH64"
4501 "@
4502 #
4503 fand\t%1, %2, %0"
4504 [(set_attr "type" "*,fga")
4505 (set_attr "length" "2,*")
4506 (set_attr "fptype" "*,double")])
4507
4508 (define_insn "*and<V64I:mode>3_sp64"
4509 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4510 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4511 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4512 "TARGET_ARCH64"
4513 "@
4514 and\t%1, %2, %0
4515 fand\t%1, %2, %0"
4516 [(set_attr "type" "*,fga")
4517 (set_attr "fptype" "*,double")])
4518
4519 (define_insn "and<V32I:mode>3"
4520 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4521 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4522 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4523 ""
4524 "@
4525 and\t%1, %2, %0
4526 fands\t%1, %2, %0"
4527 [(set_attr "type" "*,fga")
4528 (set_attr "fptype" "*,single")])
4529
4530 (define_split
4531 [(set (match_operand:SI 0 "register_operand" "")
4532 (and:SI (match_operand:SI 1 "register_operand" "")
4533 (match_operand:SI 2 "const_compl_high_operand" "")))
4534 (clobber (match_operand:SI 3 "register_operand" ""))]
4535 ""
4536 [(set (match_dup 3) (match_dup 4))
4537 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4538 {
4539 operands[4] = GEN_INT (~INTVAL (operands[2]));
4540 })
4541
4542 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4543 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4544 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4545 (match_operand:V64I 2 "register_operand" "r,b")))]
4546 "! TARGET_ARCH64"
4547 "@
4548 #
4549 fandnot1\t%1, %2, %0"
4550 "&& reload_completed
4551 && ((GET_CODE (operands[0]) == REG
4552 && REGNO (operands[0]) < 32)
4553 || (GET_CODE (operands[0]) == SUBREG
4554 && GET_CODE (SUBREG_REG (operands[0])) == REG
4555 && REGNO (SUBREG_REG (operands[0])) < 32))"
4556 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4557 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4558 "operands[3] = gen_highpart (SImode, operands[0]);
4559 operands[4] = gen_highpart (SImode, operands[1]);
4560 operands[5] = gen_highpart (SImode, operands[2]);
4561 operands[6] = gen_lowpart (SImode, operands[0]);
4562 operands[7] = gen_lowpart (SImode, operands[1]);
4563 operands[8] = gen_lowpart (SImode, operands[2]);"
4564 [(set_attr "type" "*,fga")
4565 (set_attr "length" "2,*")
4566 (set_attr "fptype" "*,double")])
4567
4568 (define_insn "*and_not_<V64I:mode>_sp64"
4569 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4570 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4571 (match_operand:V64I 2 "register_operand" "r,b")))]
4572 "TARGET_ARCH64"
4573 "@
4574 andn\t%2, %1, %0
4575 fandnot1\t%1, %2, %0"
4576 [(set_attr "type" "*,fga")
4577 (set_attr "fptype" "*,double")])
4578
4579 (define_insn "*and_not_<V32I:mode>"
4580 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4581 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4582 (match_operand:V32I 2 "register_operand" "r,d")))]
4583 ""
4584 "@
4585 andn\t%2, %1, %0
4586 fandnot1s\t%1, %2, %0"
4587 [(set_attr "type" "*,fga")
4588 (set_attr "fptype" "*,single")])
4589
4590 (define_expand "ior<V64I:mode>3"
4591 [(set (match_operand:V64I 0 "register_operand" "")
4592 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4593 (match_operand:V64I 2 "arith_double_operand" "")))]
4594 ""
4595 "")
4596
4597 (define_insn "*ior<V64I:mode>3_sp32"
4598 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4599 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4600 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4601 "! TARGET_ARCH64"
4602 "@
4603 #
4604 for\t%1, %2, %0"
4605 [(set_attr "type" "*,fga")
4606 (set_attr "length" "2,*")
4607 (set_attr "fptype" "*,double")])
4608
4609 (define_insn "*ior<V64I:mode>3_sp64"
4610 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4611 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4612 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4613 "TARGET_ARCH64"
4614 "@
4615 or\t%1, %2, %0
4616 for\t%1, %2, %0"
4617 [(set_attr "type" "*,fga")
4618 (set_attr "fptype" "*,double")])
4619
4620 (define_insn "ior<V32I:mode>3"
4621 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4622 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4623 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4624 ""
4625 "@
4626 or\t%1, %2, %0
4627 fors\t%1, %2, %0"
4628 [(set_attr "type" "*,fga")
4629 (set_attr "fptype" "*,single")])
4630
4631 (define_split
4632 [(set (match_operand:SI 0 "register_operand" "")
4633 (ior:SI (match_operand:SI 1 "register_operand" "")
4634 (match_operand:SI 2 "const_compl_high_operand" "")))
4635 (clobber (match_operand:SI 3 "register_operand" ""))]
4636 ""
4637 [(set (match_dup 3) (match_dup 4))
4638 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4639 {
4640 operands[4] = GEN_INT (~INTVAL (operands[2]));
4641 })
4642
4643 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4644 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4645 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4646 (match_operand:V64I 2 "register_operand" "r,b")))]
4647 "! TARGET_ARCH64"
4648 "@
4649 #
4650 fornot1\t%1, %2, %0"
4651 "&& reload_completed
4652 && ((GET_CODE (operands[0]) == REG
4653 && REGNO (operands[0]) < 32)
4654 || (GET_CODE (operands[0]) == SUBREG
4655 && GET_CODE (SUBREG_REG (operands[0])) == REG
4656 && REGNO (SUBREG_REG (operands[0])) < 32))"
4657 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4658 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4659 "operands[3] = gen_highpart (SImode, operands[0]);
4660 operands[4] = gen_highpart (SImode, operands[1]);
4661 operands[5] = gen_highpart (SImode, operands[2]);
4662 operands[6] = gen_lowpart (SImode, operands[0]);
4663 operands[7] = gen_lowpart (SImode, operands[1]);
4664 operands[8] = gen_lowpart (SImode, operands[2]);"
4665 [(set_attr "type" "*,fga")
4666 (set_attr "length" "2,*")
4667 (set_attr "fptype" "*,double")])
4668
4669 (define_insn "*or_not_<V64I:mode>_sp64"
4670 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4671 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4672 (match_operand:V64I 2 "register_operand" "r,b")))]
4673 "TARGET_ARCH64"
4674 "@
4675 orn\t%2, %1, %0
4676 fornot1\t%1, %2, %0"
4677 [(set_attr "type" "*,fga")
4678 (set_attr "fptype" "*,double")])
4679
4680 (define_insn "*or_not_<V32I:mode>"
4681 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4682 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4683 (match_operand:V32I 2 "register_operand" "r,d")))]
4684 ""
4685 "@
4686 orn\t%2, %1, %0
4687 fornot1s\t%1, %2, %0"
4688 [(set_attr "type" "*,fga")
4689 (set_attr "fptype" "*,single")])
4690
4691 (define_expand "xor<V64I:mode>3"
4692 [(set (match_operand:V64I 0 "register_operand" "")
4693 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4694 (match_operand:V64I 2 "arith_double_operand" "")))]
4695 ""
4696 "")
4697
4698 (define_insn "*xor<V64I:mode>3_sp32"
4699 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4700 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4701 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4702 "! TARGET_ARCH64"
4703 "@
4704 #
4705 fxor\t%1, %2, %0"
4706 [(set_attr "type" "*,fga")
4707 (set_attr "length" "2,*")
4708 (set_attr "fptype" "*,double")])
4709
4710 (define_insn "*xor<V64I:mode>3_sp64"
4711 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4712 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4713 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4714 "TARGET_ARCH64"
4715 "@
4716 xor\t%r1, %2, %0
4717 fxor\t%1, %2, %0"
4718 [(set_attr "type" "*,fga")
4719 (set_attr "fptype" "*,double")])
4720
4721 (define_insn "xor<V32I:mode>3"
4722 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4723 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4724 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4725 ""
4726 "@
4727 xor\t%r1, %2, %0
4728 fxors\t%1, %2, %0"
4729 [(set_attr "type" "*,fga")
4730 (set_attr "fptype" "*,single")])
4731
4732 (define_split
4733 [(set (match_operand:SI 0 "register_operand" "")
4734 (xor:SI (match_operand:SI 1 "register_operand" "")
4735 (match_operand:SI 2 "const_compl_high_operand" "")))
4736 (clobber (match_operand:SI 3 "register_operand" ""))]
4737 ""
4738 [(set (match_dup 3) (match_dup 4))
4739 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4740 {
4741 operands[4] = GEN_INT (~INTVAL (operands[2]));
4742 })
4743
4744 (define_split
4745 [(set (match_operand:SI 0 "register_operand" "")
4746 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4747 (match_operand:SI 2 "const_compl_high_operand" ""))))
4748 (clobber (match_operand:SI 3 "register_operand" ""))]
4749 ""
4750 [(set (match_dup 3) (match_dup 4))
4751 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4752 {
4753 operands[4] = GEN_INT (~INTVAL (operands[2]));
4754 })
4755
4756 ;; Split DImode logical operations requiring two instructions.
4757 (define_split
4758 [(set (match_operand:V64I 0 "register_operand" "")
4759 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4760 [(match_operand:V64I 2 "register_operand" "")
4761 (match_operand:V64I 3 "arith_double_operand" "")]))]
4762 "! TARGET_ARCH64
4763 && reload_completed
4764 && ((GET_CODE (operands[0]) == REG
4765 && REGNO (operands[0]) < 32)
4766 || (GET_CODE (operands[0]) == SUBREG
4767 && GET_CODE (SUBREG_REG (operands[0])) == REG
4768 && REGNO (SUBREG_REG (operands[0])) < 32))"
4769 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4770 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4771 {
4772 operands[4] = gen_highpart (SImode, operands[0]);
4773 operands[5] = gen_lowpart (SImode, operands[0]);
4774 operands[6] = gen_highpart (SImode, operands[2]);
4775 operands[7] = gen_lowpart (SImode, operands[2]);
4776 #if HOST_BITS_PER_WIDE_INT == 32
4777 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4778 {
4779 if (INTVAL (operands[3]) < 0)
4780 operands[8] = constm1_rtx;
4781 else
4782 operands[8] = const0_rtx;
4783 }
4784 else
4785 #endif
4786 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4787 operands[9] = gen_lowpart (SImode, operands[3]);
4788 })
4789
4790 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4791 ;; Combine now canonicalizes to the rightmost expression.
4792 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4793 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4794 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4795 (match_operand:V64I 2 "register_operand" "r,b"))))]
4796 "! TARGET_ARCH64"
4797 "@
4798 #
4799 fxnor\t%1, %2, %0"
4800 "&& reload_completed
4801 && ((GET_CODE (operands[0]) == REG
4802 && REGNO (operands[0]) < 32)
4803 || (GET_CODE (operands[0]) == SUBREG
4804 && GET_CODE (SUBREG_REG (operands[0])) == REG
4805 && REGNO (SUBREG_REG (operands[0])) < 32))"
4806 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4807 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4808 "operands[3] = gen_highpart (SImode, operands[0]);
4809 operands[4] = gen_highpart (SImode, operands[1]);
4810 operands[5] = gen_highpart (SImode, operands[2]);
4811 operands[6] = gen_lowpart (SImode, operands[0]);
4812 operands[7] = gen_lowpart (SImode, operands[1]);
4813 operands[8] = gen_lowpart (SImode, operands[2]);"
4814 [(set_attr "type" "*,fga")
4815 (set_attr "length" "2,*")
4816 (set_attr "fptype" "*,double")])
4817
4818 (define_insn "*xor_not_<V64I:mode>_sp64"
4819 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4820 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4821 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4822 "TARGET_ARCH64"
4823 "@
4824 xnor\t%r1, %2, %0
4825 fxnor\t%1, %2, %0"
4826 [(set_attr "type" "*,fga")
4827 (set_attr "fptype" "*,double")])
4828
4829 (define_insn "*xor_not_<V32I:mode>"
4830 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4831 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
4832 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
4833 ""
4834 "@
4835 xnor\t%r1, %2, %0
4836 fxnors\t%1, %2, %0"
4837 [(set_attr "type" "*,fga")
4838 (set_attr "fptype" "*,single")])
4839
4840 ;; These correspond to the above in the case where we also (or only)
4841 ;; want to set the condition code.
4842
4843 (define_insn "*cmp_cc_arith_op"
4844 [(set (reg:CC 100)
4845 (compare:CC
4846 (match_operator:SI 2 "cc_arith_operator"
4847 [(match_operand:SI 0 "arith_operand" "%r")
4848 (match_operand:SI 1 "arith_operand" "rI")])
4849 (const_int 0)))]
4850 ""
4851 "%A2cc\t%0, %1, %%g0"
4852 [(set_attr "type" "compare")])
4853
4854 (define_insn "*cmp_ccx_arith_op"
4855 [(set (reg:CCX 100)
4856 (compare:CCX
4857 (match_operator:DI 2 "cc_arith_operator"
4858 [(match_operand:DI 0 "arith_operand" "%r")
4859 (match_operand:DI 1 "arith_operand" "rI")])
4860 (const_int 0)))]
4861 "TARGET_ARCH64"
4862 "%A2cc\t%0, %1, %%g0"
4863 [(set_attr "type" "compare")])
4864
4865 (define_insn "*cmp_cc_arith_op_set"
4866 [(set (reg:CC 100)
4867 (compare:CC
4868 (match_operator:SI 3 "cc_arith_operator"
4869 [(match_operand:SI 1 "arith_operand" "%r")
4870 (match_operand:SI 2 "arith_operand" "rI")])
4871 (const_int 0)))
4872 (set (match_operand:SI 0 "register_operand" "=r")
4873 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4874 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4875 "%A3cc\t%1, %2, %0"
4876 [(set_attr "type" "compare")])
4877
4878 (define_insn "*cmp_ccx_arith_op_set"
4879 [(set (reg:CCX 100)
4880 (compare:CCX
4881 (match_operator:DI 3 "cc_arith_operator"
4882 [(match_operand:DI 1 "arith_operand" "%r")
4883 (match_operand:DI 2 "arith_operand" "rI")])
4884 (const_int 0)))
4885 (set (match_operand:DI 0 "register_operand" "=r")
4886 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4887 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4888 "%A3cc\t%1, %2, %0"
4889 [(set_attr "type" "compare")])
4890
4891 (define_insn "*cmp_cc_xor_not"
4892 [(set (reg:CC 100)
4893 (compare:CC
4894 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4895 (match_operand:SI 1 "arith_operand" "rI")))
4896 (const_int 0)))]
4897 ""
4898 "xnorcc\t%r0, %1, %%g0"
4899 [(set_attr "type" "compare")])
4900
4901 (define_insn "*cmp_ccx_xor_not"
4902 [(set (reg:CCX 100)
4903 (compare:CCX
4904 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4905 (match_operand:DI 1 "arith_operand" "rI")))
4906 (const_int 0)))]
4907 "TARGET_ARCH64"
4908 "xnorcc\t%r0, %1, %%g0"
4909 [(set_attr "type" "compare")])
4910
4911 (define_insn "*cmp_cc_xor_not_set"
4912 [(set (reg:CC 100)
4913 (compare:CC
4914 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4915 (match_operand:SI 2 "arith_operand" "rI")))
4916 (const_int 0)))
4917 (set (match_operand:SI 0 "register_operand" "=r")
4918 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4919 ""
4920 "xnorcc\t%r1, %2, %0"
4921 [(set_attr "type" "compare")])
4922
4923 (define_insn "*cmp_ccx_xor_not_set"
4924 [(set (reg:CCX 100)
4925 (compare:CCX
4926 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4927 (match_operand:DI 2 "arith_operand" "rI")))
4928 (const_int 0)))
4929 (set (match_operand:DI 0 "register_operand" "=r")
4930 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4931 "TARGET_ARCH64"
4932 "xnorcc\t%r1, %2, %0"
4933 [(set_attr "type" "compare")])
4934
4935 (define_insn "*cmp_cc_arith_op_not"
4936 [(set (reg:CC 100)
4937 (compare:CC
4938 (match_operator:SI 2 "cc_arith_not_operator"
4939 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4940 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
4941 (const_int 0)))]
4942 ""
4943 "%B2cc\t%r1, %0, %%g0"
4944 [(set_attr "type" "compare")])
4945
4946 (define_insn "*cmp_ccx_arith_op_not"
4947 [(set (reg:CCX 100)
4948 (compare:CCX
4949 (match_operator:DI 2 "cc_arith_not_operator"
4950 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
4951 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
4952 (const_int 0)))]
4953 "TARGET_ARCH64"
4954 "%B2cc\t%r1, %0, %%g0"
4955 [(set_attr "type" "compare")])
4956
4957 (define_insn "*cmp_cc_arith_op_not_set"
4958 [(set (reg:CC 100)
4959 (compare:CC
4960 (match_operator:SI 3 "cc_arith_not_operator"
4961 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
4962 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
4963 (const_int 0)))
4964 (set (match_operand:SI 0 "register_operand" "=r")
4965 (match_operator:SI 4 "cc_arith_not_operator"
4966 [(not:SI (match_dup 1)) (match_dup 2)]))]
4967 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4968 "%B3cc\t%r2, %1, %0"
4969 [(set_attr "type" "compare")])
4970
4971 (define_insn "*cmp_ccx_arith_op_not_set"
4972 [(set (reg:CCX 100)
4973 (compare:CCX
4974 (match_operator:DI 3 "cc_arith_not_operator"
4975 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
4976 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
4977 (const_int 0)))
4978 (set (match_operand:DI 0 "register_operand" "=r")
4979 (match_operator:DI 4 "cc_arith_not_operator"
4980 [(not:DI (match_dup 1)) (match_dup 2)]))]
4981 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4982 "%B3cc\t%r2, %1, %0"
4983 [(set_attr "type" "compare")])
4984
4985 ;; We cannot use the "neg" pseudo insn because the Sun assembler
4986 ;; does not know how to make it work for constants.
4987
4988 (define_expand "negdi2"
4989 [(set (match_operand:DI 0 "register_operand" "=r")
4990 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4991 ""
4992 {
4993 if (! TARGET_ARCH64)
4994 {
4995 emit_insn (gen_rtx_PARALLEL
4996 (VOIDmode,
4997 gen_rtvec (2,
4998 gen_rtx_SET (VOIDmode, operand0,
4999 gen_rtx_NEG (DImode, operand1)),
5000 gen_rtx_CLOBBER (VOIDmode,
5001 gen_rtx_REG (CCmode,
5002 SPARC_ICC_REG)))));
5003 DONE;
5004 }
5005 })
5006
5007 (define_insn_and_split "*negdi2_sp32"
5008 [(set (match_operand:DI 0 "register_operand" "=r")
5009 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5010 (clobber (reg:CC 100))]
5011 "TARGET_ARCH32"
5012 "#"
5013 "&& reload_completed"
5014 [(parallel [(set (reg:CC_NOOV 100)
5015 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5016 (const_int 0)))
5017 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5018 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5019 (ltu:SI (reg:CC 100) (const_int 0))))]
5020 "operands[2] = gen_highpart (SImode, operands[0]);
5021 operands[3] = gen_highpart (SImode, operands[1]);
5022 operands[4] = gen_lowpart (SImode, operands[0]);
5023 operands[5] = gen_lowpart (SImode, operands[1]);"
5024 [(set_attr "length" "2")])
5025
5026 (define_insn "*negdi2_sp64"
5027 [(set (match_operand:DI 0 "register_operand" "=r")
5028 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5029 "TARGET_ARCH64"
5030 "sub\t%%g0, %1, %0")
5031
5032 (define_insn "negsi2"
5033 [(set (match_operand:SI 0 "register_operand" "=r")
5034 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5035 ""
5036 "sub\t%%g0, %1, %0")
5037
5038 (define_insn "*cmp_cc_neg"
5039 [(set (reg:CC_NOOV 100)
5040 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5041 (const_int 0)))]
5042 ""
5043 "subcc\t%%g0, %0, %%g0"
5044 [(set_attr "type" "compare")])
5045
5046 (define_insn "*cmp_ccx_neg"
5047 [(set (reg:CCX_NOOV 100)
5048 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5049 (const_int 0)))]
5050 "TARGET_ARCH64"
5051 "subcc\t%%g0, %0, %%g0"
5052 [(set_attr "type" "compare")])
5053
5054 (define_insn "*cmp_cc_set_neg"
5055 [(set (reg:CC_NOOV 100)
5056 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5057 (const_int 0)))
5058 (set (match_operand:SI 0 "register_operand" "=r")
5059 (neg:SI (match_dup 1)))]
5060 ""
5061 "subcc\t%%g0, %1, %0"
5062 [(set_attr "type" "compare")])
5063
5064 (define_insn "*cmp_ccx_set_neg"
5065 [(set (reg:CCX_NOOV 100)
5066 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5067 (const_int 0)))
5068 (set (match_operand:DI 0 "register_operand" "=r")
5069 (neg:DI (match_dup 1)))]
5070 "TARGET_ARCH64"
5071 "subcc\t%%g0, %1, %0"
5072 [(set_attr "type" "compare")])
5073
5074 ;; We cannot use the "not" pseudo insn because the Sun assembler
5075 ;; does not know how to make it work for constants.
5076 (define_expand "one_cmpl<V64I:mode>2"
5077 [(set (match_operand:V64I 0 "register_operand" "")
5078 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5079 ""
5080 "")
5081
5082 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5083 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5084 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5085 "! TARGET_ARCH64"
5086 "@
5087 #
5088 fnot1\t%1, %0"
5089 "&& reload_completed
5090 && ((GET_CODE (operands[0]) == REG
5091 && REGNO (operands[0]) < 32)
5092 || (GET_CODE (operands[0]) == SUBREG
5093 && GET_CODE (SUBREG_REG (operands[0])) == REG
5094 && REGNO (SUBREG_REG (operands[0])) < 32))"
5095 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5096 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5097 "operands[2] = gen_highpart (SImode, operands[0]);
5098 operands[3] = gen_highpart (SImode, operands[1]);
5099 operands[4] = gen_lowpart (SImode, operands[0]);
5100 operands[5] = gen_lowpart (SImode, operands[1]);"
5101 [(set_attr "type" "*,fga")
5102 (set_attr "length" "2,*")
5103 (set_attr "fptype" "*,double")])
5104
5105 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5106 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5107 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5108 "TARGET_ARCH64"
5109 "@
5110 xnor\t%%g0, %1, %0
5111 fnot1\t%1, %0"
5112 [(set_attr "type" "*,fga")
5113 (set_attr "fptype" "*,double")])
5114
5115 (define_insn "one_cmpl<V32I:mode>2"
5116 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5117 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5118 ""
5119 "@
5120 xnor\t%%g0, %1, %0
5121 fnot1s\t%1, %0"
5122 [(set_attr "type" "*,fga")
5123 (set_attr "fptype" "*,single")])
5124
5125 (define_insn "*cmp_cc_not"
5126 [(set (reg:CC 100)
5127 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5128 (const_int 0)))]
5129 ""
5130 "xnorcc\t%%g0, %0, %%g0"
5131 [(set_attr "type" "compare")])
5132
5133 (define_insn "*cmp_ccx_not"
5134 [(set (reg:CCX 100)
5135 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5136 (const_int 0)))]
5137 "TARGET_ARCH64"
5138 "xnorcc\t%%g0, %0, %%g0"
5139 [(set_attr "type" "compare")])
5140
5141 (define_insn "*cmp_cc_set_not"
5142 [(set (reg:CC 100)
5143 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5144 (const_int 0)))
5145 (set (match_operand:SI 0 "register_operand" "=r")
5146 (not:SI (match_dup 1)))]
5147 ""
5148 "xnorcc\t%%g0, %1, %0"
5149 [(set_attr "type" "compare")])
5150
5151 (define_insn "*cmp_ccx_set_not"
5152 [(set (reg:CCX 100)
5153 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5154 (const_int 0)))
5155 (set (match_operand:DI 0 "register_operand" "=r")
5156 (not:DI (match_dup 1)))]
5157 "TARGET_ARCH64"
5158 "xnorcc\t%%g0, %1, %0"
5159 [(set_attr "type" "compare")])
5160
5161 (define_insn "*cmp_cc_set"
5162 [(set (match_operand:SI 0 "register_operand" "=r")
5163 (match_operand:SI 1 "register_operand" "r"))
5164 (set (reg:CC 100)
5165 (compare:CC (match_dup 1)
5166 (const_int 0)))]
5167 ""
5168 "orcc\t%1, 0, %0"
5169 [(set_attr "type" "compare")])
5170
5171 (define_insn "*cmp_ccx_set64"
5172 [(set (match_operand:DI 0 "register_operand" "=r")
5173 (match_operand:DI 1 "register_operand" "r"))
5174 (set (reg:CCX 100)
5175 (compare:CCX (match_dup 1)
5176 (const_int 0)))]
5177 "TARGET_ARCH64"
5178 "orcc\t%1, 0, %0"
5179 [(set_attr "type" "compare")])
5180
5181
5182 ;; Floating point arithmetic instructions.
5183
5184 (define_expand "addtf3"
5185 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5186 (plus:TF (match_operand:TF 1 "general_operand" "")
5187 (match_operand:TF 2 "general_operand" "")))]
5188 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5189 "emit_tfmode_binop (PLUS, operands); DONE;")
5190
5191 (define_insn "*addtf3_hq"
5192 [(set (match_operand:TF 0 "register_operand" "=e")
5193 (plus:TF (match_operand:TF 1 "register_operand" "e")
5194 (match_operand:TF 2 "register_operand" "e")))]
5195 "TARGET_FPU && TARGET_HARD_QUAD"
5196 "faddq\t%1, %2, %0"
5197 [(set_attr "type" "fp")])
5198
5199 (define_insn "adddf3"
5200 [(set (match_operand:DF 0 "register_operand" "=e")
5201 (plus:DF (match_operand:DF 1 "register_operand" "e")
5202 (match_operand:DF 2 "register_operand" "e")))]
5203 "TARGET_FPU"
5204 "faddd\t%1, %2, %0"
5205 [(set_attr "type" "fp")
5206 (set_attr "fptype" "double")])
5207
5208 (define_insn "addsf3"
5209 [(set (match_operand:SF 0 "register_operand" "=f")
5210 (plus:SF (match_operand:SF 1 "register_operand" "f")
5211 (match_operand:SF 2 "register_operand" "f")))]
5212 "TARGET_FPU"
5213 "fadds\t%1, %2, %0"
5214 [(set_attr "type" "fp")])
5215
5216 (define_expand "subtf3"
5217 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5218 (minus:TF (match_operand:TF 1 "general_operand" "")
5219 (match_operand:TF 2 "general_operand" "")))]
5220 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5221 "emit_tfmode_binop (MINUS, operands); DONE;")
5222
5223 (define_insn "*subtf3_hq"
5224 [(set (match_operand:TF 0 "register_operand" "=e")
5225 (minus:TF (match_operand:TF 1 "register_operand" "e")
5226 (match_operand:TF 2 "register_operand" "e")))]
5227 "TARGET_FPU && TARGET_HARD_QUAD"
5228 "fsubq\t%1, %2, %0"
5229 [(set_attr "type" "fp")])
5230
5231 (define_insn "subdf3"
5232 [(set (match_operand:DF 0 "register_operand" "=e")
5233 (minus:DF (match_operand:DF 1 "register_operand" "e")
5234 (match_operand:DF 2 "register_operand" "e")))]
5235 "TARGET_FPU"
5236 "fsubd\t%1, %2, %0"
5237 [(set_attr "type" "fp")
5238 (set_attr "fptype" "double")])
5239
5240 (define_insn "subsf3"
5241 [(set (match_operand:SF 0 "register_operand" "=f")
5242 (minus:SF (match_operand:SF 1 "register_operand" "f")
5243 (match_operand:SF 2 "register_operand" "f")))]
5244 "TARGET_FPU"
5245 "fsubs\t%1, %2, %0"
5246 [(set_attr "type" "fp")])
5247
5248 (define_expand "multf3"
5249 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5250 (mult:TF (match_operand:TF 1 "general_operand" "")
5251 (match_operand:TF 2 "general_operand" "")))]
5252 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5253 "emit_tfmode_binop (MULT, operands); DONE;")
5254
5255 (define_insn "*multf3_hq"
5256 [(set (match_operand:TF 0 "register_operand" "=e")
5257 (mult:TF (match_operand:TF 1 "register_operand" "e")
5258 (match_operand:TF 2 "register_operand" "e")))]
5259 "TARGET_FPU && TARGET_HARD_QUAD"
5260 "fmulq\t%1, %2, %0"
5261 [(set_attr "type" "fpmul")])
5262
5263 (define_insn "muldf3"
5264 [(set (match_operand:DF 0 "register_operand" "=e")
5265 (mult:DF (match_operand:DF 1 "register_operand" "e")
5266 (match_operand:DF 2 "register_operand" "e")))]
5267 "TARGET_FPU"
5268 "fmuld\t%1, %2, %0"
5269 [(set_attr "type" "fpmul")
5270 (set_attr "fptype" "double")])
5271
5272 (define_insn "mulsf3"
5273 [(set (match_operand:SF 0 "register_operand" "=f")
5274 (mult:SF (match_operand:SF 1 "register_operand" "f")
5275 (match_operand:SF 2 "register_operand" "f")))]
5276 "TARGET_FPU"
5277 "fmuls\t%1, %2, %0"
5278 [(set_attr "type" "fpmul")])
5279
5280 (define_insn "*muldf3_extend"
5281 [(set (match_operand:DF 0 "register_operand" "=e")
5282 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5283 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5284 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5285 "fsmuld\t%1, %2, %0"
5286 [(set_attr "type" "fpmul")
5287 (set_attr "fptype" "double")])
5288
5289 (define_insn "*multf3_extend"
5290 [(set (match_operand:TF 0 "register_operand" "=e")
5291 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5292 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5293 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5294 "fdmulq\t%1, %2, %0"
5295 [(set_attr "type" "fpmul")])
5296
5297 (define_expand "divtf3"
5298 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5299 (div:TF (match_operand:TF 1 "general_operand" "")
5300 (match_operand:TF 2 "general_operand" "")))]
5301 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5302 "emit_tfmode_binop (DIV, operands); DONE;")
5303
5304 ;; don't have timing for quad-prec. divide.
5305 (define_insn "*divtf3_hq"
5306 [(set (match_operand:TF 0 "register_operand" "=e")
5307 (div:TF (match_operand:TF 1 "register_operand" "e")
5308 (match_operand:TF 2 "register_operand" "e")))]
5309 "TARGET_FPU && TARGET_HARD_QUAD"
5310 "fdivq\t%1, %2, %0"
5311 [(set_attr "type" "fpdivd")])
5312
5313 (define_insn "divdf3"
5314 [(set (match_operand:DF 0 "register_operand" "=e")
5315 (div:DF (match_operand:DF 1 "register_operand" "e")
5316 (match_operand:DF 2 "register_operand" "e")))]
5317 "TARGET_FPU"
5318 "fdivd\t%1, %2, %0"
5319 [(set_attr "type" "fpdivd")
5320 (set_attr "fptype" "double")])
5321
5322 (define_insn "divsf3"
5323 [(set (match_operand:SF 0 "register_operand" "=f")
5324 (div:SF (match_operand:SF 1 "register_operand" "f")
5325 (match_operand:SF 2 "register_operand" "f")))]
5326 "TARGET_FPU"
5327 "fdivs\t%1, %2, %0"
5328 [(set_attr "type" "fpdivs")])
5329
5330 (define_expand "negtf2"
5331 [(set (match_operand:TF 0 "register_operand" "=e,e")
5332 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5333 "TARGET_FPU"
5334 "")
5335
5336 (define_insn_and_split "*negtf2_notv9"
5337 [(set (match_operand:TF 0 "register_operand" "=e,e")
5338 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5339 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5340 "TARGET_FPU
5341 && ! TARGET_V9"
5342 "@
5343 fnegs\t%0, %0
5344 #"
5345 "&& reload_completed
5346 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5347 [(set (match_dup 2) (neg:SF (match_dup 3)))
5348 (set (match_dup 4) (match_dup 5))
5349 (set (match_dup 6) (match_dup 7))]
5350 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5351 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5352 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5353 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5354 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5355 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5356 [(set_attr "type" "fpmove,*")
5357 (set_attr "length" "*,2")])
5358
5359 (define_insn_and_split "*negtf2_v9"
5360 [(set (match_operand:TF 0 "register_operand" "=e,e")
5361 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5362 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5363 "TARGET_FPU && TARGET_V9"
5364 "@
5365 fnegd\t%0, %0
5366 #"
5367 "&& reload_completed
5368 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5369 [(set (match_dup 2) (neg:DF (match_dup 3)))
5370 (set (match_dup 4) (match_dup 5))]
5371 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5372 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5373 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5374 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5375 [(set_attr "type" "fpmove,*")
5376 (set_attr "length" "*,2")
5377 (set_attr "fptype" "double")])
5378
5379 (define_expand "negdf2"
5380 [(set (match_operand:DF 0 "register_operand" "")
5381 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5382 "TARGET_FPU"
5383 "")
5384
5385 (define_insn_and_split "*negdf2_notv9"
5386 [(set (match_operand:DF 0 "register_operand" "=e,e")
5387 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5388 "TARGET_FPU && ! TARGET_V9"
5389 "@
5390 fnegs\t%0, %0
5391 #"
5392 "&& reload_completed
5393 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5394 [(set (match_dup 2) (neg:SF (match_dup 3)))
5395 (set (match_dup 4) (match_dup 5))]
5396 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5397 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5398 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5399 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5400 [(set_attr "type" "fpmove,*")
5401 (set_attr "length" "*,2")])
5402
5403 (define_insn "*negdf2_v9"
5404 [(set (match_operand:DF 0 "register_operand" "=e")
5405 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5406 "TARGET_FPU && TARGET_V9"
5407 "fnegd\t%1, %0"
5408 [(set_attr "type" "fpmove")
5409 (set_attr "fptype" "double")])
5410
5411 (define_insn "negsf2"
5412 [(set (match_operand:SF 0 "register_operand" "=f")
5413 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5414 "TARGET_FPU"
5415 "fnegs\t%1, %0"
5416 [(set_attr "type" "fpmove")])
5417
5418 (define_expand "abstf2"
5419 [(set (match_operand:TF 0 "register_operand" "")
5420 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5421 "TARGET_FPU"
5422 "")
5423
5424 (define_insn_and_split "*abstf2_notv9"
5425 [(set (match_operand:TF 0 "register_operand" "=e,e")
5426 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5427 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5428 "TARGET_FPU && ! TARGET_V9"
5429 "@
5430 fabss\t%0, %0
5431 #"
5432 "&& reload_completed
5433 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5434 [(set (match_dup 2) (abs:SF (match_dup 3)))
5435 (set (match_dup 4) (match_dup 5))
5436 (set (match_dup 6) (match_dup 7))]
5437 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5438 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5439 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5440 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5441 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5442 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5443 [(set_attr "type" "fpmove,*")
5444 (set_attr "length" "*,2")])
5445
5446 (define_insn "*abstf2_hq_v9"
5447 [(set (match_operand:TF 0 "register_operand" "=e,e")
5448 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5449 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5450 "@
5451 fabsd\t%0, %0
5452 fabsq\t%1, %0"
5453 [(set_attr "type" "fpmove")
5454 (set_attr "fptype" "double,*")])
5455
5456 (define_insn_and_split "*abstf2_v9"
5457 [(set (match_operand:TF 0 "register_operand" "=e,e")
5458 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5459 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5460 "@
5461 fabsd\t%0, %0
5462 #"
5463 "&& reload_completed
5464 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5465 [(set (match_dup 2) (abs:DF (match_dup 3)))
5466 (set (match_dup 4) (match_dup 5))]
5467 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5468 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5469 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5470 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5471 [(set_attr "type" "fpmove,*")
5472 (set_attr "length" "*,2")
5473 (set_attr "fptype" "double,*")])
5474
5475 (define_expand "absdf2"
5476 [(set (match_operand:DF 0 "register_operand" "")
5477 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5478 "TARGET_FPU"
5479 "")
5480
5481 (define_insn_and_split "*absdf2_notv9"
5482 [(set (match_operand:DF 0 "register_operand" "=e,e")
5483 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5484 "TARGET_FPU && ! TARGET_V9"
5485 "@
5486 fabss\t%0, %0
5487 #"
5488 "&& reload_completed
5489 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5490 [(set (match_dup 2) (abs:SF (match_dup 3)))
5491 (set (match_dup 4) (match_dup 5))]
5492 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5493 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5494 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5495 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5496 [(set_attr "type" "fpmove,*")
5497 (set_attr "length" "*,2")])
5498
5499 (define_insn "*absdf2_v9"
5500 [(set (match_operand:DF 0 "register_operand" "=e")
5501 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5502 "TARGET_FPU && TARGET_V9"
5503 "fabsd\t%1, %0"
5504 [(set_attr "type" "fpmove")
5505 (set_attr "fptype" "double")])
5506
5507 (define_insn "abssf2"
5508 [(set (match_operand:SF 0 "register_operand" "=f")
5509 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5510 "TARGET_FPU"
5511 "fabss\t%1, %0"
5512 [(set_attr "type" "fpmove")])
5513
5514 (define_expand "sqrttf2"
5515 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5516 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5517 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5518 "emit_tfmode_unop (SQRT, operands); DONE;")
5519
5520 (define_insn "*sqrttf2_hq"
5521 [(set (match_operand:TF 0 "register_operand" "=e")
5522 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5523 "TARGET_FPU && TARGET_HARD_QUAD"
5524 "fsqrtq\t%1, %0"
5525 [(set_attr "type" "fpsqrtd")])
5526
5527 (define_insn "sqrtdf2"
5528 [(set (match_operand:DF 0 "register_operand" "=e")
5529 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5530 "TARGET_FPU"
5531 "fsqrtd\t%1, %0"
5532 [(set_attr "type" "fpsqrtd")
5533 (set_attr "fptype" "double")])
5534
5535 (define_insn "sqrtsf2"
5536 [(set (match_operand:SF 0 "register_operand" "=f")
5537 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5538 "TARGET_FPU"
5539 "fsqrts\t%1, %0"
5540 [(set_attr "type" "fpsqrts")])
5541
5542
5543 ;; Arithmetic shift instructions.
5544
5545 (define_insn "ashlsi3"
5546 [(set (match_operand:SI 0 "register_operand" "=r")
5547 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5548 (match_operand:SI 2 "arith_operand" "rI")))]
5549 ""
5550 {
5551 if (GET_CODE (operands[2]) == CONST_INT)
5552 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5553 return "sll\t%1, %2, %0";
5554 }
5555 [(set (attr "type")
5556 (if_then_else (match_operand 2 "const_one_operand" "")
5557 (const_string "ialu") (const_string "shift")))])
5558
5559 (define_expand "ashldi3"
5560 [(set (match_operand:DI 0 "register_operand" "=r")
5561 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5562 (match_operand:SI 2 "arith_operand" "rI")))]
5563 "TARGET_ARCH64 || TARGET_V8PLUS"
5564 {
5565 if (! TARGET_ARCH64)
5566 {
5567 if (GET_CODE (operands[2]) == CONST_INT)
5568 FAIL;
5569 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5570 DONE;
5571 }
5572 })
5573
5574 (define_insn "*ashldi3_sp64"
5575 [(set (match_operand:DI 0 "register_operand" "=r")
5576 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5577 (match_operand:SI 2 "arith_operand" "rI")))]
5578 "TARGET_ARCH64"
5579 {
5580 if (GET_CODE (operands[2]) == CONST_INT)
5581 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5582 return "sllx\t%1, %2, %0";
5583 }
5584 [(set (attr "type")
5585 (if_then_else (match_operand 2 "const_one_operand" "")
5586 (const_string "ialu") (const_string "shift")))])
5587
5588 ;; XXX UGH!
5589 (define_insn "ashldi3_v8plus"
5590 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5591 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5592 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5593 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5594 "TARGET_V8PLUS"
5595 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5596 [(set_attr "type" "multi")
5597 (set_attr "length" "5,5,6")])
5598
5599 ;; Optimize (1LL<<x)-1
5600 ;; XXX this also needs to be fixed to handle equal subregs
5601 ;; XXX first before we could re-enable it.
5602 ;(define_insn ""
5603 ; [(set (match_operand:DI 0 "register_operand" "=h")
5604 ; (plus:DI (ashift:DI (const_int 1)
5605 ; (match_operand:SI 1 "arith_operand" "rI"))
5606 ; (const_int -1)))]
5607 ; "0 && TARGET_V8PLUS"
5608 ;{
5609 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5610 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5611 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5612 ;}
5613 ; [(set_attr "type" "multi")
5614 ; (set_attr "length" "4")])
5615
5616 (define_insn "*cmp_cc_ashift_1"
5617 [(set (reg:CC_NOOV 100)
5618 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5619 (const_int 1))
5620 (const_int 0)))]
5621 ""
5622 "addcc\t%0, %0, %%g0"
5623 [(set_attr "type" "compare")])
5624
5625 (define_insn "*cmp_cc_set_ashift_1"
5626 [(set (reg:CC_NOOV 100)
5627 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5628 (const_int 1))
5629 (const_int 0)))
5630 (set (match_operand:SI 0 "register_operand" "=r")
5631 (ashift:SI (match_dup 1) (const_int 1)))]
5632 ""
5633 "addcc\t%1, %1, %0"
5634 [(set_attr "type" "compare")])
5635
5636 (define_insn "ashrsi3"
5637 [(set (match_operand:SI 0 "register_operand" "=r")
5638 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5639 (match_operand:SI 2 "arith_operand" "rI")))]
5640 ""
5641 {
5642 if (GET_CODE (operands[2]) == CONST_INT)
5643 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5644 return "sra\t%1, %2, %0";
5645 }
5646 [(set_attr "type" "shift")])
5647
5648 (define_insn "*ashrsi3_extend"
5649 [(set (match_operand:DI 0 "register_operand" "=r")
5650 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5651 (match_operand:SI 2 "arith_operand" "r"))))]
5652 "TARGET_ARCH64"
5653 "sra\t%1, %2, %0"
5654 [(set_attr "type" "shift")])
5655
5656 ;; This handles the case as above, but with constant shift instead of
5657 ;; register. Combiner "simplifies" it for us a little bit though.
5658 (define_insn "*ashrsi3_extend2"
5659 [(set (match_operand:DI 0 "register_operand" "=r")
5660 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5661 (const_int 32))
5662 (match_operand:SI 2 "small_int_operand" "I")))]
5663 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5664 {
5665 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5666 return "sra\t%1, %2, %0";
5667 }
5668 [(set_attr "type" "shift")])
5669
5670 (define_expand "ashrdi3"
5671 [(set (match_operand:DI 0 "register_operand" "=r")
5672 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5673 (match_operand:SI 2 "arith_operand" "rI")))]
5674 "TARGET_ARCH64 || TARGET_V8PLUS"
5675 {
5676 if (! TARGET_ARCH64)
5677 {
5678 if (GET_CODE (operands[2]) == CONST_INT)
5679 FAIL; /* prefer generic code in this case */
5680 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5681 DONE;
5682 }
5683 })
5684
5685 (define_insn "*ashrdi3_sp64"
5686 [(set (match_operand:DI 0 "register_operand" "=r")
5687 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5688 (match_operand:SI 2 "arith_operand" "rI")))]
5689 "TARGET_ARCH64"
5690
5691 {
5692 if (GET_CODE (operands[2]) == CONST_INT)
5693 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5694 return "srax\t%1, %2, %0";
5695 }
5696 [(set_attr "type" "shift")])
5697
5698 ;; XXX
5699 (define_insn "ashrdi3_v8plus"
5700 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5701 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5702 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5703 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5704 "TARGET_V8PLUS"
5705 "* return output_v8plus_shift (operands, insn, \"srax\");"
5706 [(set_attr "type" "multi")
5707 (set_attr "length" "5,5,6")])
5708
5709 (define_insn "lshrsi3"
5710 [(set (match_operand:SI 0 "register_operand" "=r")
5711 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5712 (match_operand:SI 2 "arith_operand" "rI")))]
5713 ""
5714 {
5715 if (GET_CODE (operands[2]) == CONST_INT)
5716 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5717 return "srl\t%1, %2, %0";
5718 }
5719 [(set_attr "type" "shift")])
5720
5721 ;; This handles the case where
5722 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5723 ;; but combiner "simplifies" it for us.
5724 (define_insn "*lshrsi3_extend"
5725 [(set (match_operand:DI 0 "register_operand" "=r")
5726 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5727 (match_operand:SI 2 "arith_operand" "r")) 0)
5728 (match_operand 3 "const_int_operand" "")))]
5729 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5730 "srl\t%1, %2, %0"
5731 [(set_attr "type" "shift")])
5732
5733 ;; This handles the case where
5734 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5735 ;; but combiner "simplifies" it for us.
5736 (define_insn "*lshrsi3_extend2"
5737 [(set (match_operand:DI 0 "register_operand" "=r")
5738 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5739 (match_operand 2 "small_int_operand" "I")
5740 (const_int 32)))]
5741 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5742 {
5743 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5744 return "srl\t%1, %2, %0";
5745 }
5746 [(set_attr "type" "shift")])
5747
5748 (define_expand "lshrdi3"
5749 [(set (match_operand:DI 0 "register_operand" "=r")
5750 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5751 (match_operand:SI 2 "arith_operand" "rI")))]
5752 "TARGET_ARCH64 || TARGET_V8PLUS"
5753 {
5754 if (! TARGET_ARCH64)
5755 {
5756 if (GET_CODE (operands[2]) == CONST_INT)
5757 FAIL;
5758 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5759 DONE;
5760 }
5761 })
5762
5763 (define_insn "*lshrdi3_sp64"
5764 [(set (match_operand:DI 0 "register_operand" "=r")
5765 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5766 (match_operand:SI 2 "arith_operand" "rI")))]
5767 "TARGET_ARCH64"
5768 {
5769 if (GET_CODE (operands[2]) == CONST_INT)
5770 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5771 return "srlx\t%1, %2, %0";
5772 }
5773 [(set_attr "type" "shift")])
5774
5775 ;; XXX
5776 (define_insn "lshrdi3_v8plus"
5777 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5778 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5779 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5780 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5781 "TARGET_V8PLUS"
5782 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5783 [(set_attr "type" "multi")
5784 (set_attr "length" "5,5,6")])
5785
5786 (define_insn ""
5787 [(set (match_operand:SI 0 "register_operand" "=r")
5788 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5789 (const_int 32)) 4)
5790 (match_operand:SI 2 "small_int_operand" "I")))]
5791 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5792 {
5793 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5794 return "srax\t%1, %2, %0";
5795 }
5796 [(set_attr "type" "shift")])
5797
5798 (define_insn ""
5799 [(set (match_operand:SI 0 "register_operand" "=r")
5800 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5801 (const_int 32)) 4)
5802 (match_operand:SI 2 "small_int_operand" "I")))]
5803 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5804 {
5805 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5806 return "srlx\t%1, %2, %0";
5807 }
5808 [(set_attr "type" "shift")])
5809
5810 (define_insn ""
5811 [(set (match_operand:SI 0 "register_operand" "=r")
5812 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5813 (match_operand:SI 2 "small_int_operand" "I")) 4)
5814 (match_operand:SI 3 "small_int_operand" "I")))]
5815 "TARGET_ARCH64
5816 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5817 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5818 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5819 {
5820 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5821
5822 return "srax\t%1, %2, %0";
5823 }
5824 [(set_attr "type" "shift")])
5825
5826 (define_insn ""
5827 [(set (match_operand:SI 0 "register_operand" "=r")
5828 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5829 (match_operand:SI 2 "small_int_operand" "I")) 4)
5830 (match_operand:SI 3 "small_int_operand" "I")))]
5831 "TARGET_ARCH64
5832 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5833 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5834 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5835 {
5836 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5837
5838 return "srlx\t%1, %2, %0";
5839 }
5840 [(set_attr "type" "shift")])
5841
5842
5843 ;; Unconditional and other jump instructions.
5844
5845 (define_insn "jump"
5846 [(set (pc) (label_ref (match_operand 0 "" "")))]
5847 ""
5848 "* return output_ubranch (operands[0], 0, insn);"
5849 [(set_attr "type" "uncond_branch")])
5850
5851 (define_expand "tablejump"
5852 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5853 (use (label_ref (match_operand 1 "" "")))])]
5854 ""
5855 {
5856 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5857
5858 /* In pic mode, our address differences are against the base of the
5859 table. Add that base value back in; CSE ought to be able to combine
5860 the two address loads. */
5861 if (flag_pic)
5862 {
5863 rtx tmp, tmp2;
5864 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5865 tmp2 = operands[0];
5866 if (CASE_VECTOR_MODE != Pmode)
5867 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5868 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5869 operands[0] = memory_address (Pmode, tmp);
5870 }
5871 })
5872
5873 (define_insn "*tablejump_sp32"
5874 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5875 (use (label_ref (match_operand 1 "" "")))]
5876 "! TARGET_ARCH64"
5877 "jmp\t%a0%#"
5878 [(set_attr "type" "uncond_branch")])
5879
5880 (define_insn "*tablejump_sp64"
5881 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5882 (use (label_ref (match_operand 1 "" "")))]
5883 "TARGET_ARCH64"
5884 "jmp\t%a0%#"
5885 [(set_attr "type" "uncond_branch")])
5886
5887
5888 ;; Jump to subroutine instructions.
5889
5890 (define_expand "call"
5891 ;; Note that this expression is not used for generating RTL.
5892 ;; All the RTL is generated explicitly below.
5893 [(call (match_operand 0 "call_operand" "")
5894 (match_operand 3 "" "i"))]
5895 ;; operands[2] is next_arg_register
5896 ;; operands[3] is struct_value_size_rtx.
5897 ""
5898 {
5899 rtx fn_rtx;
5900
5901 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5902
5903 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5904
5905 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5906 {
5907 /* This is really a PIC sequence. We want to represent
5908 it as a funny jump so its delay slots can be filled.
5909
5910 ??? But if this really *is* a CALL, will not it clobber the
5911 call-clobbered registers? We lose this if it is a JUMP_INSN.
5912 Why cannot we have delay slots filled if it were a CALL? */
5913
5914 /* We accept negative sizes for untyped calls. */
5915 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5916 emit_jump_insn
5917 (gen_rtx_PARALLEL
5918 (VOIDmode,
5919 gen_rtvec (3,
5920 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5921 operands[3],
5922 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5923 else
5924 emit_jump_insn
5925 (gen_rtx_PARALLEL
5926 (VOIDmode,
5927 gen_rtvec (2,
5928 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5929 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5930 goto finish_call;
5931 }
5932
5933 fn_rtx = operands[0];
5934
5935 /* We accept negative sizes for untyped calls. */
5936 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5937 sparc_emit_call_insn
5938 (gen_rtx_PARALLEL
5939 (VOIDmode,
5940 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
5941 operands[3],
5942 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
5943 XEXP (fn_rtx, 0));
5944 else
5945 sparc_emit_call_insn
5946 (gen_rtx_PARALLEL
5947 (VOIDmode,
5948 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
5949 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
5950 XEXP (fn_rtx, 0));
5951
5952 finish_call:
5953
5954 DONE;
5955 })
5956
5957 ;; We can't use the same pattern for these two insns, because then registers
5958 ;; in the address may not be properly reloaded.
5959
5960 (define_insn "*call_address_sp32"
5961 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
5962 (match_operand 1 "" ""))
5963 (clobber (reg:SI 15))]
5964 ;;- Do not use operand 1 for most machines.
5965 "! TARGET_ARCH64"
5966 "call\t%a0, %1%#"
5967 [(set_attr "type" "call")])
5968
5969 (define_insn "*call_symbolic_sp32"
5970 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
5971 (match_operand 1 "" ""))
5972 (clobber (reg:SI 15))]
5973 ;;- Do not use operand 1 for most machines.
5974 "! TARGET_ARCH64"
5975 "call\t%a0, %1%#"
5976 [(set_attr "type" "call")])
5977
5978 (define_insn "*call_address_sp64"
5979 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
5980 (match_operand 1 "" ""))
5981 (clobber (reg:DI 15))]
5982 ;;- Do not use operand 1 for most machines.
5983 "TARGET_ARCH64"
5984 "call\t%a0, %1%#"
5985 [(set_attr "type" "call")])
5986
5987 (define_insn "*call_symbolic_sp64"
5988 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
5989 (match_operand 1 "" ""))
5990 (clobber (reg:DI 15))]
5991 ;;- Do not use operand 1 for most machines.
5992 "TARGET_ARCH64"
5993 "call\t%a0, %1%#"
5994 [(set_attr "type" "call")])
5995
5996 ;; This is a call that wants a structure value.
5997 ;; There is no such critter for v9 (??? we may need one anyway).
5998 (define_insn "*call_address_struct_value_sp32"
5999 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6000 (match_operand 1 "" ""))
6001 (match_operand 2 "immediate_operand" "")
6002 (clobber (reg:SI 15))]
6003 ;;- Do not use operand 1 for most machines.
6004 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6005 {
6006 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6007 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6008 }
6009 [(set_attr "type" "call_no_delay_slot")
6010 (set_attr "length" "3")])
6011
6012 ;; This is a call that wants a structure value.
6013 ;; There is no such critter for v9 (??? we may need one anyway).
6014 (define_insn "*call_symbolic_struct_value_sp32"
6015 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6016 (match_operand 1 "" ""))
6017 (match_operand 2 "immediate_operand" "")
6018 (clobber (reg:SI 15))]
6019 ;;- Do not use operand 1 for most machines.
6020 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6021 {
6022 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6023 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6024 }
6025 [(set_attr "type" "call_no_delay_slot")
6026 (set_attr "length" "3")])
6027
6028 ;; This is a call that may want a structure value. This is used for
6029 ;; untyped_calls.
6030 (define_insn "*call_address_untyped_struct_value_sp32"
6031 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6032 (match_operand 1 "" ""))
6033 (match_operand 2 "immediate_operand" "")
6034 (clobber (reg:SI 15))]
6035 ;;- Do not use operand 1 for most machines.
6036 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6037 "call\t%a0, %1\n\t nop\n\tnop"
6038 [(set_attr "type" "call_no_delay_slot")
6039 (set_attr "length" "3")])
6040
6041 ;; This is a call that may want a structure value. This is used for
6042 ;; untyped_calls.
6043 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6044 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6045 (match_operand 1 "" ""))
6046 (match_operand 2 "immediate_operand" "")
6047 (clobber (reg:SI 15))]
6048 ;;- Do not use operand 1 for most machines.
6049 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6050 "call\t%a0, %1\n\t nop\n\tnop"
6051 [(set_attr "type" "call_no_delay_slot")
6052 (set_attr "length" "3")])
6053
6054 (define_expand "call_value"
6055 ;; Note that this expression is not used for generating RTL.
6056 ;; All the RTL is generated explicitly below.
6057 [(set (match_operand 0 "register_operand" "=rf")
6058 (call (match_operand 1 "" "")
6059 (match_operand 4 "" "")))]
6060 ;; operand 2 is stack_size_rtx
6061 ;; operand 3 is next_arg_register
6062 ""
6063 {
6064 rtx fn_rtx;
6065 rtvec vec;
6066
6067 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6068
6069 fn_rtx = operands[1];
6070
6071 vec = gen_rtvec (2,
6072 gen_rtx_SET (VOIDmode, operands[0],
6073 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6074 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6075
6076 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6077
6078 DONE;
6079 })
6080
6081 (define_insn "*call_value_address_sp32"
6082 [(set (match_operand 0 "" "=rf")
6083 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6084 (match_operand 2 "" "")))
6085 (clobber (reg:SI 15))]
6086 ;;- Do not use operand 2 for most machines.
6087 "! TARGET_ARCH64"
6088 "call\t%a1, %2%#"
6089 [(set_attr "type" "call")])
6090
6091 (define_insn "*call_value_symbolic_sp32"
6092 [(set (match_operand 0 "" "=rf")
6093 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6094 (match_operand 2 "" "")))
6095 (clobber (reg:SI 15))]
6096 ;;- Do not use operand 2 for most machines.
6097 "! TARGET_ARCH64"
6098 "call\t%a1, %2%#"
6099 [(set_attr "type" "call")])
6100
6101 (define_insn "*call_value_address_sp64"
6102 [(set (match_operand 0 "" "")
6103 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6104 (match_operand 2 "" "")))
6105 (clobber (reg:DI 15))]
6106 ;;- Do not use operand 2 for most machines.
6107 "TARGET_ARCH64"
6108 "call\t%a1, %2%#"
6109 [(set_attr "type" "call")])
6110
6111 (define_insn "*call_value_symbolic_sp64"
6112 [(set (match_operand 0 "" "")
6113 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6114 (match_operand 2 "" "")))
6115 (clobber (reg:DI 15))]
6116 ;;- Do not use operand 2 for most machines.
6117 "TARGET_ARCH64"
6118 "call\t%a1, %2%#"
6119 [(set_attr "type" "call")])
6120
6121 (define_expand "untyped_call"
6122 [(parallel [(call (match_operand 0 "" "")
6123 (const_int 0))
6124 (match_operand:BLK 1 "memory_operand" "")
6125 (match_operand 2 "" "")])]
6126 ""
6127 {
6128 rtx valreg1 = gen_rtx_REG (DImode, 8);
6129 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6130 rtx result = operands[1];
6131
6132 /* Pass constm1 to indicate that it may expect a structure value, but
6133 we don't know what size it is. */
6134 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6135
6136 /* Save the function value registers. */
6137 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6138 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6139 valreg2);
6140
6141 /* The optimizer does not know that the call sets the function value
6142 registers we stored in the result block. We avoid problems by
6143 claiming that all hard registers are used and clobbered at this
6144 point. */
6145 emit_insn (gen_blockage ());
6146
6147 DONE;
6148 })
6149
6150 ;; Tail call instructions.
6151
6152 (define_expand "sibcall"
6153 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6154 (return)])]
6155 ""
6156 "")
6157
6158 (define_insn "*sibcall_symbolic_sp32"
6159 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6160 (match_operand 1 "" ""))
6161 (return)]
6162 "! TARGET_ARCH64"
6163 "* return output_sibcall(insn, operands[0]);"
6164 [(set_attr "type" "sibcall")])
6165
6166 (define_insn "*sibcall_symbolic_sp64"
6167 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6168 (match_operand 1 "" ""))
6169 (return)]
6170 "TARGET_ARCH64"
6171 "* return output_sibcall(insn, operands[0]);"
6172 [(set_attr "type" "sibcall")])
6173
6174 (define_expand "sibcall_value"
6175 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6176 (call (match_operand 1 "" "") (const_int 0)))
6177 (return)])]
6178 ""
6179 "")
6180
6181 (define_insn "*sibcall_value_symbolic_sp32"
6182 [(set (match_operand 0 "" "=rf")
6183 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6184 (match_operand 2 "" "")))
6185 (return)]
6186 "! TARGET_ARCH64"
6187 "* return output_sibcall(insn, operands[1]);"
6188 [(set_attr "type" "sibcall")])
6189
6190 (define_insn "*sibcall_value_symbolic_sp64"
6191 [(set (match_operand 0 "" "")
6192 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6193 (match_operand 2 "" "")))
6194 (return)]
6195 "TARGET_ARCH64"
6196 "* return output_sibcall(insn, operands[1]);"
6197 [(set_attr "type" "sibcall")])
6198
6199
6200 ;; Special instructions.
6201
6202 (define_expand "prologue"
6203 [(const_int 0)]
6204 ""
6205 {
6206 sparc_expand_prologue ();
6207 DONE;
6208 })
6209
6210 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6211 ;; backend automatically emits the required call frame debugging information
6212 ;; while it is parsing it. Therefore, the pattern should not be modified
6213 ;; without first studying the impact of the changes on the debug info.
6214 ;; [(set (%fp) (%sp))
6215 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6216 ;; (set (%i7) (%o7))]
6217
6218 (define_insn "save_register_window<P:mode>"
6219 [(set (reg:P 30) (reg:P 14))
6220 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6221 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6222 (set (reg:P 31) (reg:P 15))]
6223 ""
6224 "save\t%%sp, %0, %%sp"
6225 [(set_attr "type" "savew")])
6226
6227 (define_expand "epilogue"
6228 [(return)]
6229 ""
6230 {
6231 sparc_expand_epilogue ();
6232 })
6233
6234 (define_expand "sibcall_epilogue"
6235 [(return)]
6236 ""
6237 {
6238 sparc_expand_epilogue ();
6239 DONE;
6240 })
6241
6242 (define_expand "return"
6243 [(return)]
6244 "sparc_can_use_return_insn_p ()"
6245 "")
6246
6247 (define_insn "*return_internal"
6248 [(return)]
6249 ""
6250 "* return output_return (insn);"
6251 [(set_attr "type" "return")
6252 (set (attr "length")
6253 (cond [(eq_attr "leaf_function" "true")
6254 (if_then_else (eq_attr "empty_delay_slot" "true")
6255 (const_int 2)
6256 (const_int 1))
6257 (eq_attr "calls_eh_return" "true")
6258 (if_then_else (eq_attr "delayed_branch" "true")
6259 (if_then_else (eq_attr "isa" "v9")
6260 (const_int 2)
6261 (const_int 3))
6262 (if_then_else (eq_attr "isa" "v9")
6263 (const_int 3)
6264 (const_int 4)))
6265 (eq_attr "empty_delay_slot" "true")
6266 (if_then_else (eq_attr "delayed_branch" "true")
6267 (const_int 2)
6268 (const_int 3))
6269 ] (const_int 1)))])
6270
6271 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6272 ;; all of memory. This blocks insns from being moved across this point.
6273
6274 (define_insn "blockage"
6275 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6276 ""
6277 ""
6278 [(set_attr "length" "0")])
6279
6280 (define_expand "probe_stack"
6281 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6282 ""
6283 {
6284 operands[0]
6285 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6286 })
6287
6288 ;; Prepare to return any type including a structure value.
6289
6290 (define_expand "untyped_return"
6291 [(match_operand:BLK 0 "memory_operand" "")
6292 (match_operand 1 "" "")]
6293 ""
6294 {
6295 rtx valreg1 = gen_rtx_REG (DImode, 24);
6296 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6297 rtx result = operands[0];
6298
6299 if (! TARGET_ARCH64)
6300 {
6301 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6302 ? 15 : 31));
6303 rtx value = gen_reg_rtx (SImode);
6304
6305 /* Fetch the instruction where we will return to and see if it's an unimp
6306 instruction (the most significant 10 bits will be zero). If so,
6307 update the return address to skip the unimp instruction. */
6308 emit_move_insn (value,
6309 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6310 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6311 emit_insn (gen_update_return (rtnreg, value));
6312 }
6313
6314 /* Reload the function value registers. */
6315 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6316 emit_move_insn (valreg2,
6317 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6318
6319 /* Put USE insns before the return. */
6320 emit_use (valreg1);
6321 emit_use (valreg2);
6322
6323 /* Construct the return. */
6324 expand_naked_return ();
6325
6326 DONE;
6327 })
6328
6329 ;; Adjust the return address conditionally. If the value of op1 is equal
6330 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6331 ;; This is technically *half* the check required by the 32-bit SPARC
6332 ;; psABI. This check only ensures that an "unimp" insn was written by
6333 ;; the caller, but doesn't check to see if the expected size matches
6334 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6335 ;; only used by the above code "untyped_return".
6336
6337 (define_insn "update_return"
6338 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6339 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6340 "! TARGET_ARCH64"
6341 {
6342 if (flag_delayed_branch)
6343 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6344 else
6345 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6346 }
6347 [(set (attr "type") (const_string "multi"))
6348 (set (attr "length")
6349 (if_then_else (eq_attr "delayed_branch" "true")
6350 (const_int 3)
6351 (const_int 4)))])
6352 \f
6353 (define_insn "nop"
6354 [(const_int 0)]
6355 ""
6356 "nop")
6357
6358 (define_expand "indirect_jump"
6359 [(set (pc) (match_operand 0 "address_operand" "p"))]
6360 ""
6361 "")
6362
6363 (define_insn "*branch_sp32"
6364 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6365 "! TARGET_ARCH64"
6366 "jmp\t%a0%#"
6367 [(set_attr "type" "uncond_branch")])
6368
6369 (define_insn "*branch_sp64"
6370 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6371 "TARGET_ARCH64"
6372 "jmp\t%a0%#"
6373 [(set_attr "type" "uncond_branch")])
6374
6375 (define_expand "nonlocal_goto"
6376 [(match_operand:SI 0 "general_operand" "")
6377 (match_operand:SI 1 "general_operand" "")
6378 (match_operand:SI 2 "general_operand" "")
6379 (match_operand:SI 3 "" "")]
6380 ""
6381 {
6382 rtx lab = operands[1];
6383 rtx stack = operands[2];
6384 rtx fp = operands[3];
6385 rtx labreg;
6386
6387 /* Trap instruction to flush all the register windows. */
6388 emit_insn (gen_flush_register_windows ());
6389
6390 /* Load the fp value for the containing fn into %fp. This is needed
6391 because STACK refers to %fp. Note that virtual register instantiation
6392 fails if the virtual %fp isn't set from a register. */
6393 if (GET_CODE (fp) != REG)
6394 fp = force_reg (Pmode, fp);
6395 emit_move_insn (virtual_stack_vars_rtx, fp);
6396
6397 /* Find the containing function's current nonlocal goto handler,
6398 which will do any cleanups and then jump to the label. */
6399 labreg = gen_rtx_REG (Pmode, 8);
6400 emit_move_insn (labreg, lab);
6401
6402 /* Restore %fp from stack pointer value for containing function.
6403 The restore insn that follows will move this to %sp,
6404 and reload the appropriate value into %fp. */
6405 emit_move_insn (hard_frame_pointer_rtx, stack);
6406
6407 emit_use (stack_pointer_rtx);
6408
6409 /* ??? The V9-specific version was disabled in rev 1.65. */
6410 emit_jump_insn (gen_goto_handler_and_restore (labreg));
6411 emit_barrier ();
6412 DONE;
6413 })
6414
6415 ;; Special trap insn to flush register windows.
6416 (define_insn "flush_register_windows"
6417 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6418 ""
6419 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6420 [(set_attr "type" "flushw")])
6421
6422 (define_insn "goto_handler_and_restore"
6423 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
6424 "GET_MODE (operands[0]) == Pmode"
6425 {
6426 if (flag_delayed_branch)
6427 return "jmp\t%0\n\t restore";
6428 else
6429 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
6430 }
6431 [(set (attr "type") (const_string "multi"))
6432 (set (attr "length")
6433 (if_then_else (eq_attr "delayed_branch" "true")
6434 (const_int 2)
6435 (const_int 4)))])
6436
6437 ;; For __builtin_setjmp we need to flush register windows iff the function
6438 ;; calls alloca as well, because otherwise the register window might be
6439 ;; saved after %sp adjustment and thus setjmp would crash
6440 (define_expand "builtin_setjmp_setup"
6441 [(match_operand 0 "register_operand" "r")]
6442 ""
6443 {
6444 emit_insn (gen_do_builtin_setjmp_setup ());
6445 DONE;
6446 })
6447
6448 (define_insn "do_builtin_setjmp_setup"
6449 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
6450 ""
6451 {
6452 if (!cfun->calls_alloca)
6453 return "";
6454 if (!TARGET_V9)
6455 return "ta\t3";
6456 fputs ("\tflushw\n", asm_out_file);
6457 if (flag_pic)
6458 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
6459 TARGET_ARCH64 ? 'x' : 'w',
6460 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
6461 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
6462 TARGET_ARCH64 ? 'x' : 'w',
6463 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
6464 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
6465 TARGET_ARCH64 ? 'x' : 'w',
6466 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
6467 return "";
6468 }
6469 [(set_attr "type" "multi")
6470 (set (attr "length")
6471 (cond [(eq_attr "calls_alloca" "false")
6472 (const_int 0)
6473 (eq_attr "isa" "!v9")
6474 (const_int 1)
6475 (eq_attr "pic" "true")
6476 (const_int 4)] (const_int 3)))])
6477
6478 ;; Pattern for use after a setjmp to store FP and the return register
6479 ;; into the stack area.
6480
6481 (define_expand "setjmp"
6482 [(const_int 0)]
6483 ""
6484 {
6485 rtx mem;
6486
6487 mem = gen_rtx_MEM (Pmode,
6488 plus_constant (stack_pointer_rtx,
6489 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
6490 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
6491
6492 mem = gen_rtx_MEM (Pmode,
6493 plus_constant (stack_pointer_rtx,
6494 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
6495 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
6496 DONE;
6497 })
6498
6499 ;; Special pattern for the FLUSH instruction.
6500
6501 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6502 ; of the define_insn otherwise missing a mode. We make "flush", aka
6503 ; gen_flush, the default one since sparc_initialize_trampoline uses
6504 ; it on SImode mem values.
6505
6506 (define_insn "flush"
6507 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6508 ""
6509 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6510 [(set_attr "type" "iflush")])
6511
6512 (define_insn "flushdi"
6513 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6514 ""
6515 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6516 [(set_attr "type" "iflush")])
6517
6518
6519 ;; Find first set instructions.
6520
6521 ;; The scan instruction searches from the most significant bit while ffs
6522 ;; searches from the least significant bit. The bit index and treatment of
6523 ;; zero also differ. It takes at least 7 instructions to get the proper
6524 ;; result. Here is an obvious 8 instruction sequence.
6525
6526 ;; XXX
6527 (define_insn "ffssi2"
6528 [(set (match_operand:SI 0 "register_operand" "=&r")
6529 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6530 (clobber (match_scratch:SI 2 "=&r"))]
6531 "TARGET_SPARCLITE || TARGET_SPARCLET"
6532 {
6533 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";
6534 }
6535 [(set_attr "type" "multi")
6536 (set_attr "length" "8")])
6537
6538 ;; ??? This should be a define expand, so that the extra instruction have
6539 ;; a chance of being optimized away.
6540
6541 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6542 ;; does, but no one uses that and we don't have a switch for it.
6543 ;
6544 ;(define_insn "ffsdi2"
6545 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6546 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6547 ; (clobber (match_scratch:DI 2 "=&r"))]
6548 ; "TARGET_ARCH64"
6549 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6550 ; [(set_attr "type" "multi")
6551 ; (set_attr "length" "4")])
6552
6553
6554 \f
6555 ;; Peepholes go at the end.
6556
6557 ;; Optimize consecutive loads or stores into ldd and std when possible.
6558 ;; The conditions in which we do this are very restricted and are
6559 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6560
6561 (define_peephole2
6562 [(set (match_operand:SI 0 "memory_operand" "")
6563 (const_int 0))
6564 (set (match_operand:SI 1 "memory_operand" "")
6565 (const_int 0))]
6566 "TARGET_V9
6567 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6568 [(set (match_dup 0)
6569 (const_int 0))]
6570 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6571
6572 (define_peephole2
6573 [(set (match_operand:SI 0 "memory_operand" "")
6574 (const_int 0))
6575 (set (match_operand:SI 1 "memory_operand" "")
6576 (const_int 0))]
6577 "TARGET_V9
6578 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6579 [(set (match_dup 1)
6580 (const_int 0))]
6581 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6582
6583 (define_peephole2
6584 [(set (match_operand:SI 0 "register_operand" "")
6585 (match_operand:SI 1 "memory_operand" ""))
6586 (set (match_operand:SI 2 "register_operand" "")
6587 (match_operand:SI 3 "memory_operand" ""))]
6588 "registers_ok_for_ldd_peep (operands[0], operands[2])
6589 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6590 [(set (match_dup 0)
6591 (match_dup 1))]
6592 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6593 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6594
6595 (define_peephole2
6596 [(set (match_operand:SI 0 "memory_operand" "")
6597 (match_operand:SI 1 "register_operand" ""))
6598 (set (match_operand:SI 2 "memory_operand" "")
6599 (match_operand:SI 3 "register_operand" ""))]
6600 "registers_ok_for_ldd_peep (operands[1], operands[3])
6601 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6602 [(set (match_dup 0)
6603 (match_dup 1))]
6604 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6605 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6606
6607 (define_peephole2
6608 [(set (match_operand:SF 0 "register_operand" "")
6609 (match_operand:SF 1 "memory_operand" ""))
6610 (set (match_operand:SF 2 "register_operand" "")
6611 (match_operand:SF 3 "memory_operand" ""))]
6612 "registers_ok_for_ldd_peep (operands[0], operands[2])
6613 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6614 [(set (match_dup 0)
6615 (match_dup 1))]
6616 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6617 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6618
6619 (define_peephole2
6620 [(set (match_operand:SF 0 "memory_operand" "")
6621 (match_operand:SF 1 "register_operand" ""))
6622 (set (match_operand:SF 2 "memory_operand" "")
6623 (match_operand:SF 3 "register_operand" ""))]
6624 "registers_ok_for_ldd_peep (operands[1], operands[3])
6625 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6626 [(set (match_dup 0)
6627 (match_dup 1))]
6628 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6629 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6630
6631 (define_peephole2
6632 [(set (match_operand:SI 0 "register_operand" "")
6633 (match_operand:SI 1 "memory_operand" ""))
6634 (set (match_operand:SI 2 "register_operand" "")
6635 (match_operand:SI 3 "memory_operand" ""))]
6636 "registers_ok_for_ldd_peep (operands[2], operands[0])
6637 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6638 [(set (match_dup 2)
6639 (match_dup 3))]
6640 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6641 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6642
6643 (define_peephole2
6644 [(set (match_operand:SI 0 "memory_operand" "")
6645 (match_operand:SI 1 "register_operand" ""))
6646 (set (match_operand:SI 2 "memory_operand" "")
6647 (match_operand:SI 3 "register_operand" ""))]
6648 "registers_ok_for_ldd_peep (operands[3], operands[1])
6649 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6650 [(set (match_dup 2)
6651 (match_dup 3))]
6652 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6653 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6654 ")
6655
6656 (define_peephole2
6657 [(set (match_operand:SF 0 "register_operand" "")
6658 (match_operand:SF 1 "memory_operand" ""))
6659 (set (match_operand:SF 2 "register_operand" "")
6660 (match_operand:SF 3 "memory_operand" ""))]
6661 "registers_ok_for_ldd_peep (operands[2], operands[0])
6662 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6663 [(set (match_dup 2)
6664 (match_dup 3))]
6665 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6666 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6667
6668 (define_peephole2
6669 [(set (match_operand:SF 0 "memory_operand" "")
6670 (match_operand:SF 1 "register_operand" ""))
6671 (set (match_operand:SF 2 "memory_operand" "")
6672 (match_operand:SF 3 "register_operand" ""))]
6673 "registers_ok_for_ldd_peep (operands[3], operands[1])
6674 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6675 [(set (match_dup 2)
6676 (match_dup 3))]
6677 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6678 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6679
6680 ;; Optimize the case of following a reg-reg move with a test
6681 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6682 ;; This can result from a float to fix conversion.
6683
6684 (define_peephole2
6685 [(set (match_operand:SI 0 "register_operand" "")
6686 (match_operand:SI 1 "register_operand" ""))
6687 (set (reg:CC 100)
6688 (compare:CC (match_operand:SI 2 "register_operand" "")
6689 (const_int 0)))]
6690 "(rtx_equal_p (operands[2], operands[0])
6691 || rtx_equal_p (operands[2], operands[1]))
6692 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6693 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6694 [(parallel [(set (match_dup 0) (match_dup 1))
6695 (set (reg:CC 100)
6696 (compare:CC (match_dup 1) (const_int 0)))])]
6697 "")
6698
6699 (define_peephole2
6700 [(set (match_operand:DI 0 "register_operand" "")
6701 (match_operand:DI 1 "register_operand" ""))
6702 (set (reg:CCX 100)
6703 (compare:CCX (match_operand:DI 2 "register_operand" "")
6704 (const_int 0)))]
6705 "TARGET_ARCH64
6706 && (rtx_equal_p (operands[2], operands[0])
6707 || rtx_equal_p (operands[2], operands[1]))
6708 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6709 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6710 [(parallel [(set (match_dup 0) (match_dup 1))
6711 (set (reg:CCX 100)
6712 (compare:CCX (match_dup 1) (const_int 0)))])]
6713 "")
6714
6715
6716 ;; Prefetch instructions.
6717
6718 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6719 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6720 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6721 ;; ??? state.
6722 (define_expand "prefetch"
6723 [(match_operand 0 "address_operand" "")
6724 (match_operand 1 "const_int_operand" "")
6725 (match_operand 2 "const_int_operand" "")]
6726 "TARGET_V9"
6727 {
6728 if (TARGET_ARCH64)
6729 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6730 else
6731 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6732 DONE;
6733 })
6734
6735 (define_insn "prefetch_64"
6736 [(prefetch (match_operand:DI 0 "address_operand" "p")
6737 (match_operand:DI 1 "const_int_operand" "n")
6738 (match_operand:DI 2 "const_int_operand" "n"))]
6739 ""
6740 {
6741 static const char * const prefetch_instr[2][2] = {
6742 {
6743 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6744 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6745 },
6746 {
6747 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6748 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6749 }
6750 };
6751 int read_or_write = INTVAL (operands[1]);
6752 int locality = INTVAL (operands[2]);
6753
6754 gcc_assert (read_or_write == 0 || read_or_write == 1);
6755 gcc_assert (locality >= 0 && locality < 4);
6756 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6757 }
6758 [(set_attr "type" "load")])
6759
6760 (define_insn "prefetch_32"
6761 [(prefetch (match_operand:SI 0 "address_operand" "p")
6762 (match_operand:SI 1 "const_int_operand" "n")
6763 (match_operand:SI 2 "const_int_operand" "n"))]
6764 ""
6765 {
6766 static const char * const prefetch_instr[2][2] = {
6767 {
6768 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6769 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6770 },
6771 {
6772 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6773 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6774 }
6775 };
6776 int read_or_write = INTVAL (operands[1]);
6777 int locality = INTVAL (operands[2]);
6778
6779 gcc_assert (read_or_write == 0 || read_or_write == 1);
6780 gcc_assert (locality >= 0 && locality < 4);
6781 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6782 }
6783 [(set_attr "type" "load")])
6784
6785
6786 ;; Trap instructions.
6787
6788 (define_insn "trap"
6789 [(trap_if (const_int 1) (const_int 5))]
6790 ""
6791 "ta\t5"
6792 [(set_attr "type" "trap")])
6793
6794 (define_expand "ctrapsi4"
6795 [(trap_if (match_operator 0 "noov_compare_operator"
6796 [(match_operand:SI 1 "compare_operand" "")
6797 (match_operand:SI 2 "arith_operand" "")])
6798 (match_operand 3 ""))]
6799 ""
6800 "operands[1] = gen_compare_reg (operands[0]);
6801 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6802 FAIL;
6803 operands[2] = const0_rtx;")
6804
6805 (define_expand "ctrapdi4"
6806 [(trap_if (match_operator 0 "noov_compare_operator"
6807 [(match_operand:DI 1 "compare_operand" "")
6808 (match_operand:DI 2 "arith_operand" "")])
6809 (match_operand 3 ""))]
6810 "TARGET_ARCH64"
6811 "operands[1] = gen_compare_reg (operands[0]);
6812 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6813 FAIL;
6814 operands[2] = const0_rtx;")
6815
6816
6817 (define_insn ""
6818 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
6819 (match_operand:SI 1 "arith_operand" "rM"))]
6820 ""
6821 {
6822 if (TARGET_V9)
6823 return "t%C0\t%%icc, %1";
6824 else
6825 return "t%C0\t%1";
6826 }
6827 [(set_attr "type" "trap")])
6828
6829 (define_insn ""
6830 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
6831 (match_operand:SI 1 "arith_operand" "rM"))]
6832 "TARGET_V9"
6833 "t%C0\t%%xcc, %1"
6834 [(set_attr "type" "trap")])
6835
6836
6837 ;; TLS support instructions.
6838
6839 (define_insn "tgd_hi22"
6840 [(set (match_operand:SI 0 "register_operand" "=r")
6841 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
6842 UNSPEC_TLSGD)))]
6843 "TARGET_TLS"
6844 "sethi\\t%%tgd_hi22(%a1), %0")
6845
6846 (define_insn "tgd_lo10"
6847 [(set (match_operand:SI 0 "register_operand" "=r")
6848 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6849 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
6850 UNSPEC_TLSGD)))]
6851 "TARGET_TLS"
6852 "add\\t%1, %%tgd_lo10(%a2), %0")
6853
6854 (define_insn "tgd_add32"
6855 [(set (match_operand:SI 0 "register_operand" "=r")
6856 (plus:SI (match_operand:SI 1 "register_operand" "r")
6857 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6858 (match_operand 3 "tgd_symbolic_operand" "")]
6859 UNSPEC_TLSGD)))]
6860 "TARGET_TLS && TARGET_ARCH32"
6861 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6862
6863 (define_insn "tgd_add64"
6864 [(set (match_operand:DI 0 "register_operand" "=r")
6865 (plus:DI (match_operand:DI 1 "register_operand" "r")
6866 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6867 (match_operand 3 "tgd_symbolic_operand" "")]
6868 UNSPEC_TLSGD)))]
6869 "TARGET_TLS && TARGET_ARCH64"
6870 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6871
6872 (define_insn "tgd_call32"
6873 [(set (match_operand 0 "register_operand" "=r")
6874 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
6875 (match_operand 2 "tgd_symbolic_operand" "")]
6876 UNSPEC_TLSGD))
6877 (match_operand 3 "" "")))
6878 (clobber (reg:SI 15))]
6879 "TARGET_TLS && TARGET_ARCH32"
6880 "call\t%a1, %%tgd_call(%a2)%#"
6881 [(set_attr "type" "call")])
6882
6883 (define_insn "tgd_call64"
6884 [(set (match_operand 0 "register_operand" "=r")
6885 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
6886 (match_operand 2 "tgd_symbolic_operand" "")]
6887 UNSPEC_TLSGD))
6888 (match_operand 3 "" "")))
6889 (clobber (reg:DI 15))]
6890 "TARGET_TLS && TARGET_ARCH64"
6891 "call\t%a1, %%tgd_call(%a2)%#"
6892 [(set_attr "type" "call")])
6893
6894 (define_insn "tldm_hi22"
6895 [(set (match_operand:SI 0 "register_operand" "=r")
6896 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6897 "TARGET_TLS"
6898 "sethi\\t%%tldm_hi22(%&), %0")
6899
6900 (define_insn "tldm_lo10"
6901 [(set (match_operand:SI 0 "register_operand" "=r")
6902 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6903 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6904 "TARGET_TLS"
6905 "add\\t%1, %%tldm_lo10(%&), %0")
6906
6907 (define_insn "tldm_add32"
6908 [(set (match_operand:SI 0 "register_operand" "=r")
6909 (plus:SI (match_operand:SI 1 "register_operand" "r")
6910 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
6911 UNSPEC_TLSLDM)))]
6912 "TARGET_TLS && TARGET_ARCH32"
6913 "add\\t%1, %2, %0, %%tldm_add(%&)")
6914
6915 (define_insn "tldm_add64"
6916 [(set (match_operand:DI 0 "register_operand" "=r")
6917 (plus:DI (match_operand:DI 1 "register_operand" "r")
6918 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
6919 UNSPEC_TLSLDM)))]
6920 "TARGET_TLS && TARGET_ARCH64"
6921 "add\\t%1, %2, %0, %%tldm_add(%&)")
6922
6923 (define_insn "tldm_call32"
6924 [(set (match_operand 0 "register_operand" "=r")
6925 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
6926 UNSPEC_TLSLDM))
6927 (match_operand 2 "" "")))
6928 (clobber (reg:SI 15))]
6929 "TARGET_TLS && TARGET_ARCH32"
6930 "call\t%a1, %%tldm_call(%&)%#"
6931 [(set_attr "type" "call")])
6932
6933 (define_insn "tldm_call64"
6934 [(set (match_operand 0 "register_operand" "=r")
6935 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
6936 UNSPEC_TLSLDM))
6937 (match_operand 2 "" "")))
6938 (clobber (reg:DI 15))]
6939 "TARGET_TLS && TARGET_ARCH64"
6940 "call\t%a1, %%tldm_call(%&)%#"
6941 [(set_attr "type" "call")])
6942
6943 (define_insn "tldo_hix22"
6944 [(set (match_operand:SI 0 "register_operand" "=r")
6945 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
6946 UNSPEC_TLSLDO)))]
6947 "TARGET_TLS"
6948 "sethi\\t%%tldo_hix22(%a1), %0")
6949
6950 (define_insn "tldo_lox10"
6951 [(set (match_operand:SI 0 "register_operand" "=r")
6952 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6953 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
6954 UNSPEC_TLSLDO)))]
6955 "TARGET_TLS"
6956 "xor\\t%1, %%tldo_lox10(%a2), %0")
6957
6958 (define_insn "tldo_add32"
6959 [(set (match_operand:SI 0 "register_operand" "=r")
6960 (plus:SI (match_operand:SI 1 "register_operand" "r")
6961 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6962 (match_operand 3 "tld_symbolic_operand" "")]
6963 UNSPEC_TLSLDO)))]
6964 "TARGET_TLS && TARGET_ARCH32"
6965 "add\\t%1, %2, %0, %%tldo_add(%a3)")
6966
6967 (define_insn "tldo_add64"
6968 [(set (match_operand:DI 0 "register_operand" "=r")
6969 (plus:DI (match_operand:DI 1 "register_operand" "r")
6970 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6971 (match_operand 3 "tld_symbolic_operand" "")]
6972 UNSPEC_TLSLDO)))]
6973 "TARGET_TLS && TARGET_ARCH64"
6974 "add\\t%1, %2, %0, %%tldo_add(%a3)")
6975
6976 (define_insn "tie_hi22"
6977 [(set (match_operand:SI 0 "register_operand" "=r")
6978 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
6979 UNSPEC_TLSIE)))]
6980 "TARGET_TLS"
6981 "sethi\\t%%tie_hi22(%a1), %0")
6982
6983 (define_insn "tie_lo10"
6984 [(set (match_operand:SI 0 "register_operand" "=r")
6985 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6986 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
6987 UNSPEC_TLSIE)))]
6988 "TARGET_TLS"
6989 "add\\t%1, %%tie_lo10(%a2), %0")
6990
6991 (define_insn "tie_ld32"
6992 [(set (match_operand:SI 0 "register_operand" "=r")
6993 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6994 (match_operand:SI 2 "register_operand" "r")
6995 (match_operand 3 "tie_symbolic_operand" "")]
6996 UNSPEC_TLSIE))]
6997 "TARGET_TLS && TARGET_ARCH32"
6998 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
6999 [(set_attr "type" "load")])
7000
7001 (define_insn "tie_ld64"
7002 [(set (match_operand:DI 0 "register_operand" "=r")
7003 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7004 (match_operand:SI 2 "register_operand" "r")
7005 (match_operand 3 "tie_symbolic_operand" "")]
7006 UNSPEC_TLSIE))]
7007 "TARGET_TLS && TARGET_ARCH64"
7008 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7009 [(set_attr "type" "load")])
7010
7011 (define_insn "tie_add32"
7012 [(set (match_operand:SI 0 "register_operand" "=r")
7013 (plus:SI (match_operand:SI 1 "register_operand" "r")
7014 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7015 (match_operand 3 "tie_symbolic_operand" "")]
7016 UNSPEC_TLSIE)))]
7017 "TARGET_SUN_TLS && TARGET_ARCH32"
7018 "add\\t%1, %2, %0, %%tie_add(%a3)")
7019
7020 (define_insn "tie_add64"
7021 [(set (match_operand:DI 0 "register_operand" "=r")
7022 (plus:DI (match_operand:DI 1 "register_operand" "r")
7023 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7024 (match_operand 3 "tie_symbolic_operand" "")]
7025 UNSPEC_TLSIE)))]
7026 "TARGET_SUN_TLS && TARGET_ARCH64"
7027 "add\\t%1, %2, %0, %%tie_add(%a3)")
7028
7029 (define_insn "tle_hix22_sp32"
7030 [(set (match_operand:SI 0 "register_operand" "=r")
7031 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7032 UNSPEC_TLSLE)))]
7033 "TARGET_TLS && TARGET_ARCH32"
7034 "sethi\\t%%tle_hix22(%a1), %0")
7035
7036 (define_insn "tle_lox10_sp32"
7037 [(set (match_operand:SI 0 "register_operand" "=r")
7038 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7039 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7040 UNSPEC_TLSLE)))]
7041 "TARGET_TLS && TARGET_ARCH32"
7042 "xor\\t%1, %%tle_lox10(%a2), %0")
7043
7044 (define_insn "tle_hix22_sp64"
7045 [(set (match_operand:DI 0 "register_operand" "=r")
7046 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7047 UNSPEC_TLSLE)))]
7048 "TARGET_TLS && TARGET_ARCH64"
7049 "sethi\\t%%tle_hix22(%a1), %0")
7050
7051 (define_insn "tle_lox10_sp64"
7052 [(set (match_operand:DI 0 "register_operand" "=r")
7053 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7054 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7055 UNSPEC_TLSLE)))]
7056 "TARGET_TLS && TARGET_ARCH64"
7057 "xor\\t%1, %%tle_lox10(%a2), %0")
7058
7059 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7060 (define_insn "*tldo_ldub_sp32"
7061 [(set (match_operand:QI 0 "register_operand" "=r")
7062 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7063 (match_operand 3 "tld_symbolic_operand" "")]
7064 UNSPEC_TLSLDO)
7065 (match_operand:SI 1 "register_operand" "r"))))]
7066 "TARGET_TLS && TARGET_ARCH32"
7067 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7068 [(set_attr "type" "load")
7069 (set_attr "us3load_type" "3cycle")])
7070
7071 (define_insn "*tldo_ldub1_sp32"
7072 [(set (match_operand:HI 0 "register_operand" "=r")
7073 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7074 (match_operand 3 "tld_symbolic_operand" "")]
7075 UNSPEC_TLSLDO)
7076 (match_operand:SI 1 "register_operand" "r")))))]
7077 "TARGET_TLS && TARGET_ARCH32"
7078 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7079 [(set_attr "type" "load")
7080 (set_attr "us3load_type" "3cycle")])
7081
7082 (define_insn "*tldo_ldub2_sp32"
7083 [(set (match_operand:SI 0 "register_operand" "=r")
7084 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7085 (match_operand 3 "tld_symbolic_operand" "")]
7086 UNSPEC_TLSLDO)
7087 (match_operand:SI 1 "register_operand" "r")))))]
7088 "TARGET_TLS && TARGET_ARCH32"
7089 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7090 [(set_attr "type" "load")
7091 (set_attr "us3load_type" "3cycle")])
7092
7093 (define_insn "*tldo_ldsb1_sp32"
7094 [(set (match_operand:HI 0 "register_operand" "=r")
7095 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7096 (match_operand 3 "tld_symbolic_operand" "")]
7097 UNSPEC_TLSLDO)
7098 (match_operand:SI 1 "register_operand" "r")))))]
7099 "TARGET_TLS && TARGET_ARCH32"
7100 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7101 [(set_attr "type" "sload")
7102 (set_attr "us3load_type" "3cycle")])
7103
7104 (define_insn "*tldo_ldsb2_sp32"
7105 [(set (match_operand:SI 0 "register_operand" "=r")
7106 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7107 (match_operand 3 "tld_symbolic_operand" "")]
7108 UNSPEC_TLSLDO)
7109 (match_operand:SI 1 "register_operand" "r")))))]
7110 "TARGET_TLS && TARGET_ARCH32"
7111 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7112 [(set_attr "type" "sload")
7113 (set_attr "us3load_type" "3cycle")])
7114
7115 (define_insn "*tldo_ldub_sp64"
7116 [(set (match_operand:QI 0 "register_operand" "=r")
7117 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7118 (match_operand 3 "tld_symbolic_operand" "")]
7119 UNSPEC_TLSLDO)
7120 (match_operand:DI 1 "register_operand" "r"))))]
7121 "TARGET_TLS && TARGET_ARCH64"
7122 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7123 [(set_attr "type" "load")
7124 (set_attr "us3load_type" "3cycle")])
7125
7126 (define_insn "*tldo_ldub1_sp64"
7127 [(set (match_operand:HI 0 "register_operand" "=r")
7128 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7129 (match_operand 3 "tld_symbolic_operand" "")]
7130 UNSPEC_TLSLDO)
7131 (match_operand:DI 1 "register_operand" "r")))))]
7132 "TARGET_TLS && TARGET_ARCH64"
7133 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7134 [(set_attr "type" "load")
7135 (set_attr "us3load_type" "3cycle")])
7136
7137 (define_insn "*tldo_ldub2_sp64"
7138 [(set (match_operand:SI 0 "register_operand" "=r")
7139 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7140 (match_operand 3 "tld_symbolic_operand" "")]
7141 UNSPEC_TLSLDO)
7142 (match_operand:DI 1 "register_operand" "r")))))]
7143 "TARGET_TLS && TARGET_ARCH64"
7144 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7145 [(set_attr "type" "load")
7146 (set_attr "us3load_type" "3cycle")])
7147
7148 (define_insn "*tldo_ldub3_sp64"
7149 [(set (match_operand:DI 0 "register_operand" "=r")
7150 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7151 (match_operand 3 "tld_symbolic_operand" "")]
7152 UNSPEC_TLSLDO)
7153 (match_operand:DI 1 "register_operand" "r")))))]
7154 "TARGET_TLS && TARGET_ARCH64"
7155 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7156 [(set_attr "type" "load")
7157 (set_attr "us3load_type" "3cycle")])
7158
7159 (define_insn "*tldo_ldsb1_sp64"
7160 [(set (match_operand:HI 0 "register_operand" "=r")
7161 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7162 (match_operand 3 "tld_symbolic_operand" "")]
7163 UNSPEC_TLSLDO)
7164 (match_operand:DI 1 "register_operand" "r")))))]
7165 "TARGET_TLS && TARGET_ARCH64"
7166 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7167 [(set_attr "type" "sload")
7168 (set_attr "us3load_type" "3cycle")])
7169
7170 (define_insn "*tldo_ldsb2_sp64"
7171 [(set (match_operand:SI 0 "register_operand" "=r")
7172 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7173 (match_operand 3 "tld_symbolic_operand" "")]
7174 UNSPEC_TLSLDO)
7175 (match_operand:DI 1 "register_operand" "r")))))]
7176 "TARGET_TLS && TARGET_ARCH64"
7177 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7178 [(set_attr "type" "sload")
7179 (set_attr "us3load_type" "3cycle")])
7180
7181 (define_insn "*tldo_ldsb3_sp64"
7182 [(set (match_operand:DI 0 "register_operand" "=r")
7183 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7184 (match_operand 3 "tld_symbolic_operand" "")]
7185 UNSPEC_TLSLDO)
7186 (match_operand:DI 1 "register_operand" "r")))))]
7187 "TARGET_TLS && TARGET_ARCH64"
7188 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7189 [(set_attr "type" "sload")
7190 (set_attr "us3load_type" "3cycle")])
7191
7192 (define_insn "*tldo_lduh_sp32"
7193 [(set (match_operand:HI 0 "register_operand" "=r")
7194 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7195 (match_operand 3 "tld_symbolic_operand" "")]
7196 UNSPEC_TLSLDO)
7197 (match_operand:SI 1 "register_operand" "r"))))]
7198 "TARGET_TLS && TARGET_ARCH32"
7199 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7200 [(set_attr "type" "load")
7201 (set_attr "us3load_type" "3cycle")])
7202
7203 (define_insn "*tldo_lduh1_sp32"
7204 [(set (match_operand:SI 0 "register_operand" "=r")
7205 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7206 (match_operand 3 "tld_symbolic_operand" "")]
7207 UNSPEC_TLSLDO)
7208 (match_operand:SI 1 "register_operand" "r")))))]
7209 "TARGET_TLS && TARGET_ARCH32"
7210 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7211 [(set_attr "type" "load")
7212 (set_attr "us3load_type" "3cycle")])
7213
7214 (define_insn "*tldo_ldsh1_sp32"
7215 [(set (match_operand:SI 0 "register_operand" "=r")
7216 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7217 (match_operand 3 "tld_symbolic_operand" "")]
7218 UNSPEC_TLSLDO)
7219 (match_operand:SI 1 "register_operand" "r")))))]
7220 "TARGET_TLS && TARGET_ARCH32"
7221 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7222 [(set_attr "type" "sload")
7223 (set_attr "us3load_type" "3cycle")])
7224
7225 (define_insn "*tldo_lduh_sp64"
7226 [(set (match_operand:HI 0 "register_operand" "=r")
7227 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7228 (match_operand 3 "tld_symbolic_operand" "")]
7229 UNSPEC_TLSLDO)
7230 (match_operand:DI 1 "register_operand" "r"))))]
7231 "TARGET_TLS && TARGET_ARCH64"
7232 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7233 [(set_attr "type" "load")
7234 (set_attr "us3load_type" "3cycle")])
7235
7236 (define_insn "*tldo_lduh1_sp64"
7237 [(set (match_operand:SI 0 "register_operand" "=r")
7238 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7239 (match_operand 3 "tld_symbolic_operand" "")]
7240 UNSPEC_TLSLDO)
7241 (match_operand:DI 1 "register_operand" "r")))))]
7242 "TARGET_TLS && TARGET_ARCH64"
7243 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7244 [(set_attr "type" "load")
7245 (set_attr "us3load_type" "3cycle")])
7246
7247 (define_insn "*tldo_lduh2_sp64"
7248 [(set (match_operand:DI 0 "register_operand" "=r")
7249 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7250 (match_operand 3 "tld_symbolic_operand" "")]
7251 UNSPEC_TLSLDO)
7252 (match_operand:DI 1 "register_operand" "r")))))]
7253 "TARGET_TLS && TARGET_ARCH64"
7254 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7255 [(set_attr "type" "load")
7256 (set_attr "us3load_type" "3cycle")])
7257
7258 (define_insn "*tldo_ldsh1_sp64"
7259 [(set (match_operand:SI 0 "register_operand" "=r")
7260 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7261 (match_operand 3 "tld_symbolic_operand" "")]
7262 UNSPEC_TLSLDO)
7263 (match_operand:DI 1 "register_operand" "r")))))]
7264 "TARGET_TLS && TARGET_ARCH64"
7265 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7266 [(set_attr "type" "sload")
7267 (set_attr "us3load_type" "3cycle")])
7268
7269 (define_insn "*tldo_ldsh2_sp64"
7270 [(set (match_operand:DI 0 "register_operand" "=r")
7271 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7272 (match_operand 3 "tld_symbolic_operand" "")]
7273 UNSPEC_TLSLDO)
7274 (match_operand:DI 1 "register_operand" "r")))))]
7275 "TARGET_TLS && TARGET_ARCH64"
7276 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7277 [(set_attr "type" "sload")
7278 (set_attr "us3load_type" "3cycle")])
7279
7280 (define_insn "*tldo_lduw_sp32"
7281 [(set (match_operand:SI 0 "register_operand" "=r")
7282 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7283 (match_operand 3 "tld_symbolic_operand" "")]
7284 UNSPEC_TLSLDO)
7285 (match_operand:SI 1 "register_operand" "r"))))]
7286 "TARGET_TLS && TARGET_ARCH32"
7287 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7288 [(set_attr "type" "load")])
7289
7290 (define_insn "*tldo_lduw_sp64"
7291 [(set (match_operand:SI 0 "register_operand" "=r")
7292 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7293 (match_operand 3 "tld_symbolic_operand" "")]
7294 UNSPEC_TLSLDO)
7295 (match_operand:DI 1 "register_operand" "r"))))]
7296 "TARGET_TLS && TARGET_ARCH64"
7297 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7298 [(set_attr "type" "load")])
7299
7300 (define_insn "*tldo_lduw1_sp64"
7301 [(set (match_operand:DI 0 "register_operand" "=r")
7302 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7303 (match_operand 3 "tld_symbolic_operand" "")]
7304 UNSPEC_TLSLDO)
7305 (match_operand:DI 1 "register_operand" "r")))))]
7306 "TARGET_TLS && TARGET_ARCH64"
7307 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7308 [(set_attr "type" "load")])
7309
7310 (define_insn "*tldo_ldsw1_sp64"
7311 [(set (match_operand:DI 0 "register_operand" "=r")
7312 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7313 (match_operand 3 "tld_symbolic_operand" "")]
7314 UNSPEC_TLSLDO)
7315 (match_operand:DI 1 "register_operand" "r")))))]
7316 "TARGET_TLS && TARGET_ARCH64"
7317 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7318 [(set_attr "type" "sload")
7319 (set_attr "us3load_type" "3cycle")])
7320
7321 (define_insn "*tldo_ldx_sp64"
7322 [(set (match_operand:DI 0 "register_operand" "=r")
7323 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7324 (match_operand 3 "tld_symbolic_operand" "")]
7325 UNSPEC_TLSLDO)
7326 (match_operand:DI 1 "register_operand" "r"))))]
7327 "TARGET_TLS && TARGET_ARCH64"
7328 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7329 [(set_attr "type" "load")])
7330
7331 (define_insn "*tldo_stb_sp32"
7332 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7333 (match_operand 3 "tld_symbolic_operand" "")]
7334 UNSPEC_TLSLDO)
7335 (match_operand:SI 1 "register_operand" "r")))
7336 (match_operand:QI 0 "register_operand" "=r"))]
7337 "TARGET_TLS && TARGET_ARCH32"
7338 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7339 [(set_attr "type" "store")])
7340
7341 (define_insn "*tldo_stb_sp64"
7342 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7343 (match_operand 3 "tld_symbolic_operand" "")]
7344 UNSPEC_TLSLDO)
7345 (match_operand:DI 1 "register_operand" "r")))
7346 (match_operand:QI 0 "register_operand" "=r"))]
7347 "TARGET_TLS && TARGET_ARCH64"
7348 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7349 [(set_attr "type" "store")])
7350
7351 (define_insn "*tldo_sth_sp32"
7352 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7353 (match_operand 3 "tld_symbolic_operand" "")]
7354 UNSPEC_TLSLDO)
7355 (match_operand:SI 1 "register_operand" "r")))
7356 (match_operand:HI 0 "register_operand" "=r"))]
7357 "TARGET_TLS && TARGET_ARCH32"
7358 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7359 [(set_attr "type" "store")])
7360
7361 (define_insn "*tldo_sth_sp64"
7362 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7363 (match_operand 3 "tld_symbolic_operand" "")]
7364 UNSPEC_TLSLDO)
7365 (match_operand:DI 1 "register_operand" "r")))
7366 (match_operand:HI 0 "register_operand" "=r"))]
7367 "TARGET_TLS && TARGET_ARCH64"
7368 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7369 [(set_attr "type" "store")])
7370
7371 (define_insn "*tldo_stw_sp32"
7372 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7373 (match_operand 3 "tld_symbolic_operand" "")]
7374 UNSPEC_TLSLDO)
7375 (match_operand:SI 1 "register_operand" "r")))
7376 (match_operand:SI 0 "register_operand" "=r"))]
7377 "TARGET_TLS && TARGET_ARCH32"
7378 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7379 [(set_attr "type" "store")])
7380
7381 (define_insn "*tldo_stw_sp64"
7382 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7383 (match_operand 3 "tld_symbolic_operand" "")]
7384 UNSPEC_TLSLDO)
7385 (match_operand:DI 1 "register_operand" "r")))
7386 (match_operand:SI 0 "register_operand" "=r"))]
7387 "TARGET_TLS && TARGET_ARCH64"
7388 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7389 [(set_attr "type" "store")])
7390
7391 (define_insn "*tldo_stx_sp64"
7392 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7393 (match_operand 3 "tld_symbolic_operand" "")]
7394 UNSPEC_TLSLDO)
7395 (match_operand:DI 1 "register_operand" "r")))
7396 (match_operand:DI 0 "register_operand" "=r"))]
7397 "TARGET_TLS && TARGET_ARCH64"
7398 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7399 [(set_attr "type" "store")])
7400
7401
7402 ;; Stack protector instructions.
7403
7404 (define_expand "stack_protect_set"
7405 [(match_operand 0 "memory_operand" "")
7406 (match_operand 1 "memory_operand" "")]
7407 ""
7408 {
7409 #ifdef TARGET_THREAD_SSP_OFFSET
7410 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7411 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7412 operands[1] = gen_rtx_MEM (Pmode, addr);
7413 #endif
7414 if (TARGET_ARCH64)
7415 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7416 else
7417 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7418 DONE;
7419 })
7420
7421 (define_insn "stack_protect_setsi"
7422 [(set (match_operand:SI 0 "memory_operand" "=m")
7423 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7424 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7425 "TARGET_ARCH32"
7426 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7427 [(set_attr "type" "multi")
7428 (set_attr "length" "3")])
7429
7430 (define_insn "stack_protect_setdi"
7431 [(set (match_operand:DI 0 "memory_operand" "=m")
7432 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7433 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7434 "TARGET_ARCH64"
7435 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7436 [(set_attr "type" "multi")
7437 (set_attr "length" "3")])
7438
7439 (define_expand "stack_protect_test"
7440 [(match_operand 0 "memory_operand" "")
7441 (match_operand 1 "memory_operand" "")
7442 (match_operand 2 "" "")]
7443 ""
7444 {
7445 rtx result, test;
7446 #ifdef TARGET_THREAD_SSP_OFFSET
7447 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7448 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7449 operands[1] = gen_rtx_MEM (Pmode, addr);
7450 #endif
7451 if (TARGET_ARCH64)
7452 {
7453 result = gen_reg_rtx (Pmode);
7454 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7455 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7456 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7457 }
7458 else
7459 {
7460 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7461 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7462 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7463 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7464 }
7465 DONE;
7466 })
7467
7468 (define_insn "stack_protect_testsi"
7469 [(set (reg:CC 100)
7470 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7471 (match_operand:SI 1 "memory_operand" "m")]
7472 UNSPEC_SP_TEST))
7473 (set (match_scratch:SI 3 "=r") (const_int 0))
7474 (clobber (match_scratch:SI 2 "=&r"))]
7475 "TARGET_ARCH32"
7476 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7477 [(set_attr "type" "multi")
7478 (set_attr "length" "4")])
7479
7480 (define_insn "stack_protect_testdi"
7481 [(set (match_operand:DI 0 "register_operand" "=&r")
7482 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7483 (match_operand:DI 2 "memory_operand" "m")]
7484 UNSPEC_SP_TEST))
7485 (set (match_scratch:DI 3 "=r") (const_int 0))]
7486 "TARGET_ARCH64"
7487 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7488 [(set_attr "type" "multi")
7489 (set_attr "length" "4")])
7490
7491
7492 ;; Vector instructions.
7493
7494 (define_insn "addv2si3"
7495 [(set (match_operand:V2SI 0 "register_operand" "=e")
7496 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7497 (match_operand:V2SI 2 "register_operand" "e")))]
7498 "TARGET_VIS"
7499 "fpadd32\t%1, %2, %0"
7500 [(set_attr "type" "fga")
7501 (set_attr "fptype" "double")])
7502
7503 (define_insn "addv4hi3"
7504 [(set (match_operand:V4HI 0 "register_operand" "=e")
7505 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7506 (match_operand:V4HI 2 "register_operand" "e")))]
7507 "TARGET_VIS"
7508 "fpadd16\t%1, %2, %0"
7509 [(set_attr "type" "fga")
7510 (set_attr "fptype" "double")])
7511
7512 ;; fpadd32s is emitted by the addsi3 pattern.
7513
7514 (define_insn "addv2hi3"
7515 [(set (match_operand:V2HI 0 "register_operand" "=f")
7516 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7517 (match_operand:V2HI 2 "register_operand" "f")))]
7518 "TARGET_VIS"
7519 "fpadd16s\t%1, %2, %0"
7520 [(set_attr "type" "fga")
7521 (set_attr "fptype" "single")])
7522
7523 (define_insn "subv2si3"
7524 [(set (match_operand:V2SI 0 "register_operand" "=e")
7525 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7526 (match_operand:V2SI 2 "register_operand" "e")))]
7527 "TARGET_VIS"
7528 "fpsub32\t%1, %2, %0"
7529 [(set_attr "type" "fga")
7530 (set_attr "fptype" "double")])
7531
7532 (define_insn "subv4hi3"
7533 [(set (match_operand:V4HI 0 "register_operand" "=e")
7534 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7535 (match_operand:V4HI 2 "register_operand" "e")))]
7536 "TARGET_VIS"
7537 "fpsub16\t%1, %2, %0"
7538 [(set_attr "type" "fga")
7539 (set_attr "fptype" "double")])
7540
7541 ;; fpsub32s is emitted by the subsi3 pattern.
7542
7543 (define_insn "subv2hi3"
7544 [(set (match_operand:V2HI 0 "register_operand" "=f")
7545 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7546 (match_operand:V2HI 2 "register_operand" "f")))]
7547 "TARGET_VIS"
7548 "fpsub16s\t%1, %2, %0"
7549 [(set_attr "type" "fga")
7550 (set_attr "fptype" "single")])
7551
7552 ;; All other logical instructions have integer equivalents so they
7553 ;; are defined together.
7554
7555 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7556
7557 (define_insn "*nand<V64:mode>_vis"
7558 [(set (match_operand:V64 0 "register_operand" "=e")
7559 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7560 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7561 "TARGET_VIS"
7562 "fnand\t%1, %2, %0"
7563 [(set_attr "type" "fga")
7564 (set_attr "fptype" "double")])
7565
7566 (define_insn "*nand<V32:mode>_vis"
7567 [(set (match_operand:V32 0 "register_operand" "=f")
7568 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7569 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7570 "TARGET_VIS"
7571 "fnands\t%1, %2, %0"
7572 [(set_attr "type" "fga")
7573 (set_attr "fptype" "single")])
7574
7575 ;; Hard to generate VIS instructions. We have builtins for these.
7576
7577 (define_insn "fpack16_vis"
7578 [(set (match_operand:V4QI 0 "register_operand" "=f")
7579 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7580 UNSPEC_FPACK16))]
7581 "TARGET_VIS"
7582 "fpack16\t%1, %0"
7583 [(set_attr "type" "fga")
7584 (set_attr "fptype" "double")])
7585
7586 (define_insn "fpackfix_vis"
7587 [(set (match_operand:V2HI 0 "register_operand" "=f")
7588 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7589 UNSPEC_FPACKFIX))]
7590 "TARGET_VIS"
7591 "fpackfix\t%1, %0"
7592 [(set_attr "type" "fga")
7593 (set_attr "fptype" "double")])
7594
7595 (define_insn "fpack32_vis"
7596 [(set (match_operand:V8QI 0 "register_operand" "=e")
7597 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7598 (match_operand:V8QI 2 "register_operand" "e")]
7599 UNSPEC_FPACK32))]
7600 "TARGET_VIS"
7601 "fpack32\t%1, %2, %0"
7602 [(set_attr "type" "fga")
7603 (set_attr "fptype" "double")])
7604
7605 (define_insn "fexpand_vis"
7606 [(set (match_operand:V4HI 0 "register_operand" "=e")
7607 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7608 UNSPEC_FEXPAND))]
7609 "TARGET_VIS"
7610 "fexpand\t%1, %0"
7611 [(set_attr "type" "fga")
7612 (set_attr "fptype" "double")])
7613
7614 ;; It may be possible to describe this operation as (1 indexed):
7615 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7616 ;; 1,5,10,14,19,23,28,32)
7617 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7618 ;; because vec_merge expects all the operands to be of the same type.
7619 (define_insn "fpmerge_vis"
7620 [(set (match_operand:V8QI 0 "register_operand" "=e")
7621 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7622 (match_operand:V4QI 2 "register_operand" "f")]
7623 UNSPEC_FPMERGE))]
7624 "TARGET_VIS"
7625 "fpmerge\t%1, %2, %0"
7626 [(set_attr "type" "fga")
7627 (set_attr "fptype" "double")])
7628
7629 ;; Partitioned multiply instructions
7630 (define_insn "fmul8x16_vis"
7631 [(set (match_operand:V4HI 0 "register_operand" "=e")
7632 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7633 (match_operand:V4HI 2 "register_operand" "e")))]
7634 "TARGET_VIS"
7635 "fmul8x16\t%1, %2, %0"
7636 [(set_attr "type" "fpmul")
7637 (set_attr "fptype" "double")])
7638
7639 ;; Only one of the following two insns can be a multiply.
7640 (define_insn "fmul8x16au_vis"
7641 [(set (match_operand:V4HI 0 "register_operand" "=e")
7642 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7643 (match_operand:V2HI 2 "register_operand" "f")))]
7644 "TARGET_VIS"
7645 "fmul8x16au\t%1, %2, %0"
7646 [(set_attr "type" "fpmul")
7647 (set_attr "fptype" "double")])
7648
7649 (define_insn "fmul8x16al_vis"
7650 [(set (match_operand:V4HI 0 "register_operand" "=e")
7651 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7652 (match_operand:V2HI 2 "register_operand" "f")]
7653 UNSPEC_MUL16AL))]
7654 "TARGET_VIS"
7655 "fmul8x16al\t%1, %2, %0"
7656 [(set_attr "type" "fpmul")
7657 (set_attr "fptype" "double")])
7658
7659 ;; Only one of the following two insns can be a multiply.
7660 (define_insn "fmul8sux16_vis"
7661 [(set (match_operand:V4HI 0 "register_operand" "=e")
7662 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7663 (match_operand:V4HI 2 "register_operand" "e")))]
7664 "TARGET_VIS"
7665 "fmul8sux16\t%1, %2, %0"
7666 [(set_attr "type" "fpmul")
7667 (set_attr "fptype" "double")])
7668
7669 (define_insn "fmul8ulx16_vis"
7670 [(set (match_operand:V4HI 0 "register_operand" "=e")
7671 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7672 (match_operand:V4HI 2 "register_operand" "e")]
7673 UNSPEC_MUL8UL))]
7674 "TARGET_VIS"
7675 "fmul8ulx16\t%1, %2, %0"
7676 [(set_attr "type" "fpmul")
7677 (set_attr "fptype" "double")])
7678
7679 ;; Only one of the following two insns can be a multiply.
7680 (define_insn "fmuld8sux16_vis"
7681 [(set (match_operand:V2SI 0 "register_operand" "=e")
7682 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7683 (match_operand:V2HI 2 "register_operand" "f")))]
7684 "TARGET_VIS"
7685 "fmuld8sux16\t%1, %2, %0"
7686 [(set_attr "type" "fpmul")
7687 (set_attr "fptype" "double")])
7688
7689 (define_insn "fmuld8ulx16_vis"
7690 [(set (match_operand:V2SI 0 "register_operand" "=e")
7691 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7692 (match_operand:V2HI 2 "register_operand" "f")]
7693 UNSPEC_MULDUL))]
7694 "TARGET_VIS"
7695 "fmuld8ulx16\t%1, %2, %0"
7696 [(set_attr "type" "fpmul")
7697 (set_attr "fptype" "double")])
7698
7699 ;; Using faligndata only makes sense after an alignaddr since the choice of
7700 ;; bytes to take out of each operand is dependent on the results of the last
7701 ;; alignaddr.
7702 (define_insn "faligndata<V64I:mode>_vis"
7703 [(set (match_operand:V64I 0 "register_operand" "=e")
7704 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
7705 (match_operand:V64I 2 "register_operand" "e")]
7706 UNSPEC_ALIGNDATA))]
7707 "TARGET_VIS"
7708 "faligndata\t%1, %2, %0"
7709 [(set_attr "type" "fga")
7710 (set_attr "fptype" "double")])
7711
7712 (define_insn "alignaddr<P:mode>_vis"
7713 [(set (match_operand:P 0 "register_operand" "=r")
7714 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7715 (match_operand:P 2 "register_or_zero_operand" "rJ")]
7716 UNSPEC_ALIGNADDR))]
7717 "TARGET_VIS"
7718 "alignaddr\t%r1, %r2, %0")
7719
7720 (define_insn "pdist_vis"
7721 [(set (match_operand:DI 0 "register_operand" "=e")
7722 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
7723 (match_operand:V8QI 2 "register_operand" "e")
7724 (match_operand:DI 3 "register_operand" "0")]
7725 UNSPEC_PDIST))]
7726 "TARGET_VIS"
7727 "pdist\t%1, %2, %0"
7728 [(set_attr "type" "fga")
7729 (set_attr "fptype" "double")])
7730
7731 (include "sync.md")