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, 2010
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,
9 ;; This file is part of GCC.
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)
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.
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/>.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (UNSPEC_UPDATE_RETURN 1)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
41 (UNSPEC_MOVE_GOTDATA 19)
50 (UNSPEC_TLSLD_BASE 35)
81 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
82 (define_mode_iterator I [QI HI SI DI])
83 (define_mode_iterator F [SF DF TF])
85 ;; We don't define V1SI because SI should work just fine.
86 (define_mode_iterator V32 [SF V2HI V4QI])
87 (define_mode_iterator V32I [SI V2HI V4QI])
89 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
90 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
92 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
93 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
94 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
95 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
96 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
99 ;; Attribute for cpu type.
100 ;; These must match the values for enum processor_type in sparc.h.
107 hypersparc,sparclite86x,
114 (const (symbol_ref "sparc_cpu_attr")))
116 ;; Attribute for the instruction set.
117 ;; At present we only need to distinguish v9/!v9, but for clarity we
118 ;; test TARGET_V8 too.
119 (define_attr "isa" "v7,v8,v9,sparclet"
121 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
122 (symbol_ref "TARGET_V8") (const_string "v8")
123 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
124 (const_string "v7"))))
130 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
138 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
141 multi,savew,flushw,iflush,trap"
142 (const_string "ialu"))
144 ;; True if branch/call has empty delay slot and will emit a nop in it
145 (define_attr "empty_delay_slot" "false,true"
146 (symbol_ref "(empty_delay_slot (insn)
147 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
149 (define_attr "branch_type" "none,icc,fcc,reg"
150 (const_string "none"))
152 (define_attr "pic" "false,true"
153 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
155 (define_attr "calls_alloca" "false,true"
156 (symbol_ref "(cfun->calls_alloca != 0
157 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
159 (define_attr "calls_eh_return" "false,true"
160 (symbol_ref "(crtl->calls_eh_return != 0
161 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
163 (define_attr "leaf_function" "false,true"
164 (symbol_ref "(current_function_uses_only_leaf_regs != 0
165 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
167 (define_attr "delayed_branch" "false,true"
168 (symbol_ref "(flag_delayed_branch != 0
169 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
171 ;; Length (in # of insns).
172 ;; Beware that setting a length greater or equal to 3 for conditional branches
173 ;; has a side-effect (see output_cbranch and output_v9branch).
174 (define_attr "length" ""
175 (cond [(eq_attr "type" "uncond_branch,call")
176 (if_then_else (eq_attr "empty_delay_slot" "true")
179 (eq_attr "type" "sibcall")
180 (if_then_else (eq_attr "leaf_function" "true")
181 (if_then_else (eq_attr "empty_delay_slot" "true")
184 (if_then_else (eq_attr "empty_delay_slot" "true")
187 (eq_attr "branch_type" "icc")
188 (if_then_else (match_operand 0 "noov_compare64_operator" "")
189 (if_then_else (lt (pc) (match_dup 1))
190 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
191 (if_then_else (eq_attr "empty_delay_slot" "true")
194 (if_then_else (eq_attr "empty_delay_slot" "true")
197 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
198 (if_then_else (eq_attr "empty_delay_slot" "true")
201 (if_then_else (eq_attr "empty_delay_slot" "true")
204 (if_then_else (eq_attr "empty_delay_slot" "true")
207 (eq_attr "branch_type" "fcc")
208 (if_then_else (match_operand 0 "fcc0_register_operand" "")
209 (if_then_else (eq_attr "empty_delay_slot" "true")
210 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
213 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
216 (if_then_else (lt (pc) (match_dup 2))
217 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
218 (if_then_else (eq_attr "empty_delay_slot" "true")
221 (if_then_else (eq_attr "empty_delay_slot" "true")
224 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
225 (if_then_else (eq_attr "empty_delay_slot" "true")
228 (if_then_else (eq_attr "empty_delay_slot" "true")
231 (eq_attr "branch_type" "reg")
232 (if_then_else (lt (pc) (match_dup 2))
233 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
234 (if_then_else (eq_attr "empty_delay_slot" "true")
237 (if_then_else (eq_attr "empty_delay_slot" "true")
240 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
241 (if_then_else (eq_attr "empty_delay_slot" "true")
244 (if_then_else (eq_attr "empty_delay_slot" "true")
250 (define_attr "fptype" "single,double"
251 (const_string "single"))
253 ;; UltraSPARC-III integer load type.
254 (define_attr "us3load_type" "2cycle,3cycle"
255 (const_string "2cycle"))
257 (define_asm_attributes
258 [(set_attr "length" "2")
259 (set_attr "type" "multi")])
261 ;; Attributes for instruction and branch scheduling
262 (define_attr "tls_call_delay" "false,true"
263 (symbol_ref "(tls_call_delay (insn)
264 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
266 (define_attr "in_call_delay" "false,true"
267 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
268 (const_string "false")
269 (eq_attr "type" "load,fpload,store,fpstore")
270 (if_then_else (eq_attr "length" "1")
271 (const_string "true")
272 (const_string "false"))]
273 (if_then_else (and (eq_attr "length" "1")
274 (eq_attr "tls_call_delay" "true"))
275 (const_string "true")
276 (const_string "false"))))
278 (define_attr "eligible_for_sibcall_delay" "false,true"
279 (symbol_ref "(eligible_for_sibcall_delay (insn)
280 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
281 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
283 (define_attr "eligible_for_return_delay" "false,true"
284 (symbol_ref "(eligible_for_return_delay (insn)
285 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
286 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
288 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
289 ;; branches. This would allow us to remove the nop always inserted before
290 ;; a floating point branch.
292 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
293 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
294 ;; This is because doing so will add several pipeline stalls to the path
295 ;; that the load/store did not come from. Unfortunately, there is no way
296 ;; to prevent fill_eager_delay_slots from using load/store without completely
297 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
298 ;; because it prevents us from moving back the final store of inner loops.
300 (define_attr "in_branch_delay" "false,true"
301 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
302 (eq_attr "length" "1"))
303 (const_string "true")
304 (const_string "false")))
306 (define_attr "in_uncond_branch_delay" "false,true"
307 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
308 (eq_attr "length" "1"))
309 (const_string "true")
310 (const_string "false")))
312 (define_attr "in_annul_branch_delay" "false,true"
313 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
314 (eq_attr "length" "1"))
315 (const_string "true")
316 (const_string "false")))
318 (define_delay (eq_attr "type" "call")
319 [(eq_attr "in_call_delay" "true") (nil) (nil)])
321 (define_delay (eq_attr "type" "sibcall")
322 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
324 (define_delay (eq_attr "type" "branch")
325 [(eq_attr "in_branch_delay" "true")
326 (nil) (eq_attr "in_annul_branch_delay" "true")])
328 (define_delay (eq_attr "type" "uncond_branch")
329 [(eq_attr "in_uncond_branch_delay" "true")
332 (define_delay (eq_attr "type" "return")
333 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
336 ;; Include SPARC DFA schedulers
338 (include "cypress.md")
339 (include "supersparc.md")
340 (include "hypersparc.md")
341 (include "sparclet.md")
342 (include "ultra1_2.md")
343 (include "ultra3.md")
344 (include "niagara.md")
345 (include "niagara2.md")
348 ;; Operand and operator predicates and constraints
350 (include "predicates.md")
351 (include "constraints.md")
354 ;; Compare instructions.
356 ;; These are just the DEFINE_INSNs to match the patterns and the
357 ;; DEFINE_SPLITs for some of the scc insns that actually require
358 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
360 ;; The compare DEFINE_INSNs.
362 (define_insn "*cmpsi_insn"
364 (compare:CC (match_operand:SI 0 "register_operand" "r")
365 (match_operand:SI 1 "arith_operand" "rI")))]
368 [(set_attr "type" "compare")])
370 (define_insn "*cmpdi_sp64"
372 (compare:CCX (match_operand:DI 0 "register_operand" "r")
373 (match_operand:DI 1 "arith_operand" "rI")))]
376 [(set_attr "type" "compare")])
378 (define_insn "*cmpsf_fpe"
379 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
380 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
381 (match_operand:SF 2 "register_operand" "f")))]
385 return "fcmpes\t%0, %1, %2";
386 return "fcmpes\t%1, %2";
388 [(set_attr "type" "fpcmp")])
390 (define_insn "*cmpdf_fpe"
391 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
392 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
393 (match_operand:DF 2 "register_operand" "e")))]
397 return "fcmped\t%0, %1, %2";
398 return "fcmped\t%1, %2";
400 [(set_attr "type" "fpcmp")
401 (set_attr "fptype" "double")])
403 (define_insn "*cmptf_fpe"
404 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
405 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
406 (match_operand:TF 2 "register_operand" "e")))]
407 "TARGET_FPU && TARGET_HARD_QUAD"
410 return "fcmpeq\t%0, %1, %2";
411 return "fcmpeq\t%1, %2";
413 [(set_attr "type" "fpcmp")])
415 (define_insn "*cmpsf_fp"
416 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
417 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
418 (match_operand:SF 2 "register_operand" "f")))]
422 return "fcmps\t%0, %1, %2";
423 return "fcmps\t%1, %2";
425 [(set_attr "type" "fpcmp")])
427 (define_insn "*cmpdf_fp"
428 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
429 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
430 (match_operand:DF 2 "register_operand" "e")))]
434 return "fcmpd\t%0, %1, %2";
435 return "fcmpd\t%1, %2";
437 [(set_attr "type" "fpcmp")
438 (set_attr "fptype" "double")])
440 (define_insn "*cmptf_fp"
441 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
442 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
443 (match_operand:TF 2 "register_operand" "e")))]
444 "TARGET_FPU && TARGET_HARD_QUAD"
447 return "fcmpq\t%0, %1, %2";
448 return "fcmpq\t%1, %2";
450 [(set_attr "type" "fpcmp")])
452 ;; Next come the scc insns.
454 (define_expand "cstoresi4"
455 [(use (match_operator 1 "comparison_operator"
456 [(match_operand:SI 2 "compare_operand" "")
457 (match_operand:SI 3 "arith_operand" "")]))
458 (clobber (match_operand:SI 0 "register_operand"))]
461 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
462 operands[2] = force_reg (SImode, operands[2]);
463 if (emit_scc_insn (operands)) DONE; else FAIL;
466 (define_expand "cstoredi4"
467 [(use (match_operator 1 "comparison_operator"
468 [(match_operand:DI 2 "compare_operand" "")
469 (match_operand:DI 3 "arith_operand" "")]))
470 (clobber (match_operand:SI 0 "register_operand"))]
473 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
474 operands[2] = force_reg (DImode, operands[2]);
475 if (emit_scc_insn (operands)) DONE; else FAIL;
478 (define_expand "cstore<F:mode>4"
479 [(use (match_operator 1 "comparison_operator"
480 [(match_operand:F 2 "register_operand" "")
481 (match_operand:F 3 "register_operand" "")]))
482 (clobber (match_operand:SI 0 "register_operand"))]
484 { if (emit_scc_insn (operands)) DONE; else FAIL; })
488 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
489 ;; generate addcc/subcc instructions.
491 (define_expand "seqsi_special"
493 (xor:SI (match_operand:SI 1 "register_operand" "")
494 (match_operand:SI 2 "register_operand" "")))
495 (parallel [(set (match_operand:SI 0 "register_operand" "")
496 (eq:SI (match_dup 3) (const_int 0)))
497 (clobber (reg:CC 100))])]
499 { operands[3] = gen_reg_rtx (SImode); })
501 (define_expand "seqdi_special"
503 (xor:DI (match_operand:DI 1 "register_operand" "")
504 (match_operand:DI 2 "register_operand" "")))
505 (set (match_operand:SI 0 "register_operand" "")
506 (eq:SI (match_dup 3) (const_int 0)))]
508 { operands[3] = gen_reg_rtx (DImode); })
510 (define_expand "snesi_special"
512 (xor:SI (match_operand:SI 1 "register_operand" "")
513 (match_operand:SI 2 "register_operand" "")))
514 (parallel [(set (match_operand:SI 0 "register_operand" "")
515 (ne:SI (match_dup 3) (const_int 0)))
516 (clobber (reg:CC 100))])]
518 { operands[3] = gen_reg_rtx (SImode); })
520 (define_expand "snedi_special"
522 (xor:DI (match_operand:DI 1 "register_operand" "")
523 (match_operand:DI 2 "register_operand" "")))
524 (set (match_operand:SI 0 "register_operand" "")
525 (ne:SI (match_dup 3) (const_int 0)))]
527 { operands[3] = gen_reg_rtx (DImode); })
530 ;; Now the DEFINE_INSNs for the scc cases.
532 ;; The SEQ and SNE patterns are special because they can be done
533 ;; without any branching and do not involve a COMPARE. We want
534 ;; them to always use the splits below so the results can be
537 (define_insn_and_split "*snesi_zero"
538 [(set (match_operand:SI 0 "register_operand" "=r")
539 (ne:SI (match_operand:SI 1 "register_operand" "r")
541 (clobber (reg:CC 100))]
545 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
547 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
549 [(set_attr "length" "2")])
551 (define_insn_and_split "*neg_snesi_zero"
552 [(set (match_operand:SI 0 "register_operand" "=r")
553 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
555 (clobber (reg:CC 100))]
559 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
561 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
563 [(set_attr "length" "2")])
565 (define_insn_and_split "*snesi_zero_extend"
566 [(set (match_operand:DI 0 "register_operand" "=r")
567 (ne:DI (match_operand:SI 1 "register_operand" "r")
569 (clobber (reg:CC 100))]
573 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
576 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
578 (ltu:SI (reg:CC_NOOV 100)
581 [(set_attr "length" "2")])
583 (define_insn_and_split "*snedi_zero"
584 [(set (match_operand:DI 0 "register_operand" "=&r")
585 (ne:DI (match_operand:DI 1 "register_operand" "r")
589 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
590 [(set (match_dup 0) (const_int 0))
591 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
596 [(set_attr "length" "2")])
598 (define_insn_and_split "*neg_snedi_zero"
599 [(set (match_operand:DI 0 "register_operand" "=&r")
600 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
604 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
605 [(set (match_dup 0) (const_int 0))
606 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
611 [(set_attr "length" "2")])
613 (define_insn_and_split "*snedi_zero_trunc"
614 [(set (match_operand:SI 0 "register_operand" "=&r")
615 (ne:SI (match_operand:DI 1 "register_operand" "r")
619 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
620 [(set (match_dup 0) (const_int 0))
621 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
626 [(set_attr "length" "2")])
628 (define_insn_and_split "*seqsi_zero"
629 [(set (match_operand:SI 0 "register_operand" "=r")
630 (eq:SI (match_operand:SI 1 "register_operand" "r")
632 (clobber (reg:CC 100))]
636 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
638 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
640 [(set_attr "length" "2")])
642 (define_insn_and_split "*neg_seqsi_zero"
643 [(set (match_operand:SI 0 "register_operand" "=r")
644 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
646 (clobber (reg:CC 100))]
650 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
652 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
654 [(set_attr "length" "2")])
656 (define_insn_and_split "*seqsi_zero_extend"
657 [(set (match_operand:DI 0 "register_operand" "=r")
658 (eq:DI (match_operand:SI 1 "register_operand" "r")
660 (clobber (reg:CC 100))]
664 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
667 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
669 (ltu:SI (reg:CC_NOOV 100)
672 [(set_attr "length" "2")])
674 (define_insn_and_split "*seqdi_zero"
675 [(set (match_operand:DI 0 "register_operand" "=&r")
676 (eq:DI (match_operand:DI 1 "register_operand" "r")
680 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
681 [(set (match_dup 0) (const_int 0))
682 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
687 [(set_attr "length" "2")])
689 (define_insn_and_split "*neg_seqdi_zero"
690 [(set (match_operand:DI 0 "register_operand" "=&r")
691 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
695 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
696 [(set (match_dup 0) (const_int 0))
697 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
702 [(set_attr "length" "2")])
704 (define_insn_and_split "*seqdi_zero_trunc"
705 [(set (match_operand:SI 0 "register_operand" "=&r")
706 (eq:SI (match_operand:DI 1 "register_operand" "r")
710 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
711 [(set (match_dup 0) (const_int 0))
712 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
717 [(set_attr "length" "2")])
719 ;; We can also do (x + (i == 0)) and related, so put them in.
720 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
723 (define_insn_and_split "*x_plus_i_ne_0"
724 [(set (match_operand:SI 0 "register_operand" "=r")
725 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
727 (match_operand:SI 2 "register_operand" "r")))
728 (clobber (reg:CC 100))]
732 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
734 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
737 [(set_attr "length" "2")])
739 (define_insn_and_split "*x_minus_i_ne_0"
740 [(set (match_operand:SI 0 "register_operand" "=r")
741 (minus:SI (match_operand:SI 2 "register_operand" "r")
742 (ne:SI (match_operand:SI 1 "register_operand" "r")
744 (clobber (reg:CC 100))]
748 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
750 (set (match_dup 0) (minus:SI (match_dup 2)
751 (ltu:SI (reg:CC 100) (const_int 0))))]
753 [(set_attr "length" "2")])
755 (define_insn_and_split "*x_plus_i_eq_0"
756 [(set (match_operand:SI 0 "register_operand" "=r")
757 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
759 (match_operand:SI 2 "register_operand" "r")))
760 (clobber (reg:CC 100))]
764 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
766 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
769 [(set_attr "length" "2")])
771 (define_insn_and_split "*x_minus_i_eq_0"
772 [(set (match_operand:SI 0 "register_operand" "=r")
773 (minus:SI (match_operand:SI 2 "register_operand" "r")
774 (eq:SI (match_operand:SI 1 "register_operand" "r")
776 (clobber (reg:CC 100))]
780 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
782 (set (match_dup 0) (minus:SI (match_dup 2)
783 (geu:SI (reg:CC 100) (const_int 0))))]
785 [(set_attr "length" "2")])
787 ;; We can also do GEU and LTU directly, but these operate after a compare.
788 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
791 (define_insn "*sltu_insn"
792 [(set (match_operand:SI 0 "register_operand" "=r")
793 (ltu:SI (reg:CC 100) (const_int 0)))]
796 [(set_attr "type" "ialuX")])
798 (define_insn "*neg_sltu_insn"
799 [(set (match_operand:SI 0 "register_operand" "=r")
800 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
803 [(set_attr "type" "ialuX")])
805 ;; ??? Combine should canonicalize these next two to the same pattern.
806 (define_insn "*neg_sltu_minus_x"
807 [(set (match_operand:SI 0 "register_operand" "=r")
808 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
809 (match_operand:SI 1 "arith_operand" "rI")))]
812 [(set_attr "type" "ialuX")])
814 (define_insn "*neg_sltu_plus_x"
815 [(set (match_operand:SI 0 "register_operand" "=r")
816 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
817 (match_operand:SI 1 "arith_operand" "rI"))))]
820 [(set_attr "type" "ialuX")])
822 (define_insn "*sgeu_insn"
823 [(set (match_operand:SI 0 "register_operand" "=r")
824 (geu:SI (reg:CC 100) (const_int 0)))]
827 [(set_attr "type" "ialuX")])
829 (define_insn "*neg_sgeu_insn"
830 [(set (match_operand:SI 0 "register_operand" "=r")
831 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
834 [(set_attr "type" "ialuX")])
836 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
837 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
840 (define_insn "*sltu_plus_x"
841 [(set (match_operand:SI 0 "register_operand" "=r")
842 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
843 (match_operand:SI 1 "arith_operand" "rI")))]
846 [(set_attr "type" "ialuX")])
848 (define_insn "*sltu_plus_x_plus_y"
849 [(set (match_operand:SI 0 "register_operand" "=r")
850 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
851 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
852 (match_operand:SI 2 "arith_operand" "rI"))))]
855 [(set_attr "type" "ialuX")])
857 (define_insn "*x_minus_sltu"
858 [(set (match_operand:SI 0 "register_operand" "=r")
859 (minus:SI (match_operand:SI 1 "register_operand" "r")
860 (ltu:SI (reg:CC 100) (const_int 0))))]
863 [(set_attr "type" "ialuX")])
865 ;; ??? Combine should canonicalize these next two to the same pattern.
866 (define_insn "*x_minus_y_minus_sltu"
867 [(set (match_operand:SI 0 "register_operand" "=r")
868 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
869 (match_operand:SI 2 "arith_operand" "rI"))
870 (ltu:SI (reg:CC 100) (const_int 0))))]
873 [(set_attr "type" "ialuX")])
875 (define_insn "*x_minus_sltu_plus_y"
876 [(set (match_operand:SI 0 "register_operand" "=r")
877 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
878 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
879 (match_operand:SI 2 "arith_operand" "rI"))))]
882 [(set_attr "type" "ialuX")])
884 (define_insn "*sgeu_plus_x"
885 [(set (match_operand:SI 0 "register_operand" "=r")
886 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
887 (match_operand:SI 1 "register_operand" "r")))]
890 [(set_attr "type" "ialuX")])
892 (define_insn "*x_minus_sgeu"
893 [(set (match_operand:SI 0 "register_operand" "=r")
894 (minus:SI (match_operand:SI 1 "register_operand" "r")
895 (geu:SI (reg:CC 100) (const_int 0))))]
898 [(set_attr "type" "ialuX")])
901 [(set (match_operand:SI 0 "register_operand" "")
902 (match_operator:SI 2 "noov_compare_operator"
903 [(match_operand 1 "icc_or_fcc_register_operand" "")
906 && REGNO (operands[1]) == SPARC_ICC_REG
907 && (GET_MODE (operands[1]) == CCXmode
908 /* 32-bit LTU/GEU are better implemented using addx/subx. */
909 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
910 [(set (match_dup 0) (const_int 0))
912 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
918 ;; These control RTL generation for conditional jump insns
920 (define_expand "cbranchcc4"
922 (if_then_else (match_operator 0 "comparison_operator"
923 [(match_operand 1 "compare_operand" "")
924 (match_operand 2 "const_zero_operand" "")])
925 (label_ref (match_operand 3 "" ""))
930 (define_expand "cbranchsi4"
931 [(use (match_operator 0 "comparison_operator"
932 [(match_operand:SI 1 "compare_operand" "")
933 (match_operand:SI 2 "arith_operand" "")]))
934 (use (match_operand 3 ""))]
937 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
938 operands[1] = force_reg (SImode, operands[1]);
939 emit_conditional_branch_insn (operands);
943 (define_expand "cbranchdi4"
944 [(use (match_operator 0 "comparison_operator"
945 [(match_operand:DI 1 "compare_operand" "")
946 (match_operand:DI 2 "arith_operand" "")]))
947 (use (match_operand 3 ""))]
950 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
951 operands[1] = force_reg (DImode, operands[1]);
952 emit_conditional_branch_insn (operands);
956 (define_expand "cbranch<F:mode>4"
957 [(use (match_operator 0 "comparison_operator"
958 [(match_operand:F 1 "register_operand" "")
959 (match_operand:F 2 "register_operand" "")]))
960 (use (match_operand 3 ""))]
962 { emit_conditional_branch_insn (operands); DONE; })
965 ;; Now match both normal and inverted jump.
967 ;; XXX fpcmp nop braindamage
968 (define_insn "*normal_branch"
970 (if_then_else (match_operator 0 "noov_compare_operator"
971 [(reg 100) (const_int 0)])
972 (label_ref (match_operand 1 "" ""))
976 return output_cbranch (operands[0], operands[1], 1, 0,
977 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
980 [(set_attr "type" "branch")
981 (set_attr "branch_type" "icc")])
983 ;; XXX fpcmp nop braindamage
984 (define_insn "*inverted_branch"
986 (if_then_else (match_operator 0 "noov_compare_operator"
987 [(reg 100) (const_int 0)])
989 (label_ref (match_operand 1 "" ""))))]
992 return output_cbranch (operands[0], operands[1], 1, 1,
993 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
996 [(set_attr "type" "branch")
997 (set_attr "branch_type" "icc")])
999 ;; XXX fpcmp nop braindamage
1000 (define_insn "*normal_fp_branch"
1002 (if_then_else (match_operator 1 "comparison_operator"
1003 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1005 (label_ref (match_operand 2 "" ""))
1009 return output_cbranch (operands[1], operands[2], 2, 0,
1010 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1013 [(set_attr "type" "branch")
1014 (set_attr "branch_type" "fcc")])
1016 ;; XXX fpcmp nop braindamage
1017 (define_insn "*inverted_fp_branch"
1019 (if_then_else (match_operator 1 "comparison_operator"
1020 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1023 (label_ref (match_operand 2 "" ""))))]
1026 return output_cbranch (operands[1], operands[2], 2, 1,
1027 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1030 [(set_attr "type" "branch")
1031 (set_attr "branch_type" "fcc")])
1033 ;; XXX fpcmp nop braindamage
1034 (define_insn "*normal_fpe_branch"
1036 (if_then_else (match_operator 1 "comparison_operator"
1037 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1039 (label_ref (match_operand 2 "" ""))
1043 return output_cbranch (operands[1], operands[2], 2, 0,
1044 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1047 [(set_attr "type" "branch")
1048 (set_attr "branch_type" "fcc")])
1050 ;; XXX fpcmp nop braindamage
1051 (define_insn "*inverted_fpe_branch"
1053 (if_then_else (match_operator 1 "comparison_operator"
1054 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1057 (label_ref (match_operand 2 "" ""))))]
1060 return output_cbranch (operands[1], operands[2], 2, 1,
1061 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1064 [(set_attr "type" "branch")
1065 (set_attr "branch_type" "fcc")])
1067 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1068 ;; in the architecture.
1070 ;; There are no 32 bit brreg insns.
1073 (define_insn "*normal_int_branch_sp64"
1075 (if_then_else (match_operator 0 "v9_register_compare_operator"
1076 [(match_operand:DI 1 "register_operand" "r")
1078 (label_ref (match_operand 2 "" ""))
1082 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1083 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1086 [(set_attr "type" "branch")
1087 (set_attr "branch_type" "reg")])
1090 (define_insn "*inverted_int_branch_sp64"
1092 (if_then_else (match_operator 0 "v9_register_compare_operator"
1093 [(match_operand:DI 1 "register_operand" "r")
1096 (label_ref (match_operand 2 "" ""))))]
1099 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1100 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1103 [(set_attr "type" "branch")
1104 (set_attr "branch_type" "reg")])
1107 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1108 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1109 ;; that adds the PC value at the call point to operand 0.
1111 (define_insn "load_pcrel_sym<P:mode>"
1112 [(set (match_operand:P 0 "register_operand" "=r")
1113 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1114 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1115 (clobber (reg:P 15))]
1118 if (flag_delayed_branch)
1119 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1121 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1123 [(set (attr "type") (const_string "multi"))
1124 (set (attr "length")
1125 (if_then_else (eq_attr "delayed_branch" "true")
1130 ;; Integer move instructions
1132 (define_expand "movqi"
1133 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1134 (match_operand:QI 1 "general_operand" ""))]
1137 if (sparc_expand_move (QImode, operands))
1141 (define_insn "*movqi_insn"
1142 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1143 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1144 "(register_operand (operands[0], QImode)
1145 || register_or_zero_operand (operands[1], QImode))"
1150 [(set_attr "type" "*,load,store")
1151 (set_attr "us3load_type" "*,3cycle,*")])
1153 (define_expand "movhi"
1154 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1155 (match_operand:HI 1 "general_operand" ""))]
1158 if (sparc_expand_move (HImode, operands))
1162 (define_insn "*movhi_insn"
1163 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1164 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1165 "(register_operand (operands[0], HImode)
1166 || register_or_zero_operand (operands[1], HImode))"
1169 sethi\t%%hi(%a1), %0
1172 [(set_attr "type" "*,*,load,store")
1173 (set_attr "us3load_type" "*,*,3cycle,*")])
1175 ;; We always work with constants here.
1176 (define_insn "*movhi_lo_sum"
1177 [(set (match_operand:HI 0 "register_operand" "=r")
1178 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1179 (match_operand:HI 2 "small_int_operand" "I")))]
1183 (define_expand "movsi"
1184 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1185 (match_operand:SI 1 "general_operand" ""))]
1188 if (sparc_expand_move (SImode, operands))
1192 (define_insn "*movsi_insn"
1193 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1194 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1195 "(register_operand (operands[0], SImode)
1196 || register_or_zero_operand (operands[1], SImode))"
1199 sethi\t%%hi(%a1), %0
1206 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1208 (define_insn "*movsi_lo_sum"
1209 [(set (match_operand:SI 0 "register_operand" "=r")
1210 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1211 (match_operand:SI 2 "immediate_operand" "in")))]
1213 "or\t%1, %%lo(%a2), %0")
1215 (define_insn "*movsi_high"
1216 [(set (match_operand:SI 0 "register_operand" "=r")
1217 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1219 "sethi\t%%hi(%a1), %0")
1221 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1222 ;; so that CSE won't optimize the address computation away.
1223 (define_insn "movsi_lo_sum_pic"
1224 [(set (match_operand:SI 0 "register_operand" "=r")
1225 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1226 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1229 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1230 return "xor\t%1, %%gdop_lox10(%a2), %0";
1232 return "or\t%1, %%lo(%a2), %0";
1236 (define_insn "movsi_high_pic"
1237 [(set (match_operand:SI 0 "register_operand" "=r")
1238 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1239 "flag_pic && check_pic (1)"
1241 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1242 return "sethi\t%%gdop_hix22(%a1), %0";
1244 return "sethi\t%%hi(%a1), %0";
1248 (define_insn "movsi_pic_gotdata_op"
1249 [(set (match_operand:SI 0 "register_operand" "=r")
1250 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1251 (match_operand:SI 2 "register_operand" "r")
1252 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1253 "flag_pic && check_pic (1)"
1255 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1256 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1258 return "ld\t[%1 + %2], %0";
1261 [(set_attr "type" "load")])
1263 (define_expand "movsi_pic_label_ref"
1264 [(set (match_dup 3) (high:SI
1265 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1266 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1267 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1268 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1269 (set (match_operand:SI 0 "register_operand" "=r")
1270 (minus:SI (match_dup 5) (match_dup 4)))]
1273 crtl->uses_pic_offset_table = 1;
1274 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1275 if (!can_create_pseudo_p ())
1277 operands[3] = operands[0];
1278 operands[4] = operands[0];
1282 operands[3] = gen_reg_rtx (SImode);
1283 operands[4] = gen_reg_rtx (SImode);
1285 operands[5] = pic_offset_table_rtx;
1288 (define_insn "*movsi_high_pic_label_ref"
1289 [(set (match_operand:SI 0 "register_operand" "=r")
1291 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1292 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1294 "sethi\t%%hi(%a2-(%a1-.)), %0")
1296 (define_insn "*movsi_lo_sum_pic_label_ref"
1297 [(set (match_operand:SI 0 "register_operand" "=r")
1298 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1299 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1300 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1302 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1304 ;; Set up the PIC register for VxWorks.
1306 (define_expand "vxworks_load_got"
1308 (high:SI (match_dup 1)))
1310 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1312 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1313 "TARGET_VXWORKS_RTP"
1315 operands[0] = pic_offset_table_rtx;
1316 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1317 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1320 (define_expand "movdi"
1321 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1322 (match_operand:DI 1 "general_operand" ""))]
1325 if (sparc_expand_move (DImode, operands))
1329 ;; Be careful, fmovd does not exist when !v9.
1330 ;; We match MEM moves directly when we have correct even
1331 ;; numbered registers, but fall into splits otherwise.
1332 ;; The constraint ordering here is really important to
1333 ;; avoid insane problems in reload, especially for patterns
1336 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1337 ;; (const_int -5016)))
1341 (define_insn "*movdi_insn_sp32"
1342 [(set (match_operand:DI 0 "nonimmediate_operand"
1343 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1344 (match_operand:DI 1 "input_operand"
1345 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1347 && (register_operand (operands[0], DImode)
1348 || register_or_zero_operand (operands[1], DImode))"
1362 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1363 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1365 (define_insn "*movdi_insn_sp32_v9"
1366 [(set (match_operand:DI 0 "nonimmediate_operand"
1367 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1368 (match_operand:DI 1 "input_operand"
1369 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1372 && (register_operand (operands[0], DImode)
1373 || register_or_zero_operand (operands[1], DImode))"
1390 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1391 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1392 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1394 (define_insn "*movdi_insn_sp64"
1395 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1396 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1398 && (register_operand (operands[0], DImode)
1399 || register_or_zero_operand (operands[1], DImode))"
1402 sethi\t%%hi(%a1), %0
1409 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1410 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1412 (define_expand "movdi_pic_label_ref"
1413 [(set (match_dup 3) (high:DI
1414 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1415 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1416 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1417 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1418 (set (match_operand:DI 0 "register_operand" "=r")
1419 (minus:DI (match_dup 5) (match_dup 4)))]
1420 "TARGET_ARCH64 && flag_pic"
1422 crtl->uses_pic_offset_table = 1;
1423 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1424 if (!can_create_pseudo_p ())
1426 operands[3] = operands[0];
1427 operands[4] = operands[0];
1431 operands[3] = gen_reg_rtx (DImode);
1432 operands[4] = gen_reg_rtx (DImode);
1434 operands[5] = pic_offset_table_rtx;
1437 (define_insn "*movdi_high_pic_label_ref"
1438 [(set (match_operand:DI 0 "register_operand" "=r")
1440 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1441 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1442 "TARGET_ARCH64 && flag_pic"
1443 "sethi\t%%hi(%a2-(%a1-.)), %0")
1445 (define_insn "*movdi_lo_sum_pic_label_ref"
1446 [(set (match_operand:DI 0 "register_operand" "=r")
1447 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1448 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1449 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1450 "TARGET_ARCH64 && flag_pic"
1451 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1453 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1454 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1456 (define_insn "movdi_lo_sum_pic"
1457 [(set (match_operand:DI 0 "register_operand" "=r")
1458 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1459 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1460 "TARGET_ARCH64 && flag_pic"
1462 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1463 return "xor\t%1, %%gdop_lox10(%a2), %0";
1465 return "or\t%1, %%lo(%a2), %0";
1469 (define_insn "movdi_high_pic"
1470 [(set (match_operand:DI 0 "register_operand" "=r")
1471 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1472 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1474 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1475 return "sethi\t%%gdop_hix22(%a1), %0";
1477 return "sethi\t%%hi(%a1), %0";
1481 (define_insn "movdi_pic_gotdata_op"
1482 [(set (match_operand:DI 0 "register_operand" "=r")
1483 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1484 (match_operand:DI 2 "register_operand" "r")
1485 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1486 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1488 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1489 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1491 return "ldx\t[%1 + %2], %0";
1494 [(set_attr "type" "load")])
1496 (define_insn "*sethi_di_medlow_embmedany_pic"
1497 [(set (match_operand:DI 0 "register_operand" "=r")
1498 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1499 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1500 "sethi\t%%hi(%a1), %0")
1502 (define_insn "*sethi_di_medlow"
1503 [(set (match_operand:DI 0 "register_operand" "=r")
1504 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1505 "TARGET_CM_MEDLOW && check_pic (1)"
1506 "sethi\t%%hi(%a1), %0")
1508 (define_insn "*losum_di_medlow"
1509 [(set (match_operand:DI 0 "register_operand" "=r")
1510 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1511 (match_operand:DI 2 "symbolic_operand" "")))]
1513 "or\t%1, %%lo(%a2), %0")
1515 (define_insn "seth44"
1516 [(set (match_operand:DI 0 "register_operand" "=r")
1517 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1519 "sethi\t%%h44(%a1), %0")
1521 (define_insn "setm44"
1522 [(set (match_operand:DI 0 "register_operand" "=r")
1523 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1524 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1526 "or\t%1, %%m44(%a2), %0")
1528 (define_insn "setl44"
1529 [(set (match_operand:DI 0 "register_operand" "=r")
1530 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1531 (match_operand:DI 2 "symbolic_operand" "")))]
1533 "or\t%1, %%l44(%a2), %0")
1535 (define_insn "sethh"
1536 [(set (match_operand:DI 0 "register_operand" "=r")
1537 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1539 "sethi\t%%hh(%a1), %0")
1541 (define_insn "setlm"
1542 [(set (match_operand:DI 0 "register_operand" "=r")
1543 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1545 "sethi\t%%lm(%a1), %0")
1547 (define_insn "sethm"
1548 [(set (match_operand:DI 0 "register_operand" "=r")
1549 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1550 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1552 "or\t%1, %%hm(%a2), %0")
1554 (define_insn "setlo"
1555 [(set (match_operand:DI 0 "register_operand" "=r")
1556 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1557 (match_operand:DI 2 "symbolic_operand" "")))]
1559 "or\t%1, %%lo(%a2), %0")
1561 (define_insn "embmedany_sethi"
1562 [(set (match_operand:DI 0 "register_operand" "=r")
1563 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1564 "TARGET_CM_EMBMEDANY && check_pic (1)"
1565 "sethi\t%%hi(%a1), %0")
1567 (define_insn "embmedany_losum"
1568 [(set (match_operand:DI 0 "register_operand" "=r")
1569 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1570 (match_operand:DI 2 "data_segment_operand" "")))]
1571 "TARGET_CM_EMBMEDANY"
1572 "add\t%1, %%lo(%a2), %0")
1574 (define_insn "embmedany_brsum"
1575 [(set (match_operand:DI 0 "register_operand" "=r")
1576 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1577 "TARGET_CM_EMBMEDANY"
1580 (define_insn "embmedany_textuhi"
1581 [(set (match_operand:DI 0 "register_operand" "=r")
1582 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1583 "TARGET_CM_EMBMEDANY && check_pic (1)"
1584 "sethi\t%%uhi(%a1), %0")
1586 (define_insn "embmedany_texthi"
1587 [(set (match_operand:DI 0 "register_operand" "=r")
1588 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1589 "TARGET_CM_EMBMEDANY && check_pic (1)"
1590 "sethi\t%%hi(%a1), %0")
1592 (define_insn "embmedany_textulo"
1593 [(set (match_operand:DI 0 "register_operand" "=r")
1594 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1595 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1596 "TARGET_CM_EMBMEDANY"
1597 "or\t%1, %%ulo(%a2), %0")
1599 (define_insn "embmedany_textlo"
1600 [(set (match_operand:DI 0 "register_operand" "=r")
1601 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1602 (match_operand:DI 2 "text_segment_operand" "")))]
1603 "TARGET_CM_EMBMEDANY"
1604 "or\t%1, %%lo(%a2), %0")
1606 ;; Now some patterns to help reload out a bit.
1607 (define_expand "reload_indi"
1608 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1609 (match_operand:DI 1 "immediate_operand" "")
1610 (match_operand:TI 2 "register_operand" "=&r")])]
1612 || TARGET_CM_EMBMEDANY)
1615 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1619 (define_expand "reload_outdi"
1620 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1621 (match_operand:DI 1 "immediate_operand" "")
1622 (match_operand:TI 2 "register_operand" "=&r")])]
1624 || TARGET_CM_EMBMEDANY)
1627 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1631 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1633 [(set (match_operand:DI 0 "register_operand" "")
1634 (match_operand:DI 1 "const_int_operand" ""))]
1635 "! TARGET_ARCH64 && reload_completed"
1636 [(clobber (const_int 0))]
1638 #if HOST_BITS_PER_WIDE_INT == 32
1639 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1640 (INTVAL (operands[1]) < 0) ?
1643 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1646 unsigned int low, high;
1648 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1649 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1650 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1652 /* Slick... but this trick loses if this subreg constant part
1653 can be done in one insn. */
1655 && ! SPARC_SETHI32_P (high)
1656 && ! SPARC_SIMM13_P (high))
1657 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1658 gen_highpart (SImode, operands[0])));
1660 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1666 [(set (match_operand:DI 0 "register_operand" "")
1667 (match_operand:DI 1 "const_double_operand" ""))]
1671 && ((GET_CODE (operands[0]) == REG
1672 && REGNO (operands[0]) < 32)
1673 || (GET_CODE (operands[0]) == SUBREG
1674 && GET_CODE (SUBREG_REG (operands[0])) == REG
1675 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1676 [(clobber (const_int 0))]
1678 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1679 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1681 /* Slick... but this trick loses if this subreg constant part
1682 can be done in one insn. */
1683 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1684 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1685 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1687 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1688 gen_highpart (SImode, operands[0])));
1692 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1693 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1699 [(set (match_operand:DI 0 "register_operand" "")
1700 (match_operand:DI 1 "register_operand" ""))]
1704 && ((GET_CODE (operands[0]) == REG
1705 && REGNO (operands[0]) < 32)
1706 || (GET_CODE (operands[0]) == SUBREG
1707 && GET_CODE (SUBREG_REG (operands[0])) == REG
1708 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1709 [(clobber (const_int 0))]
1711 rtx set_dest = operands[0];
1712 rtx set_src = operands[1];
1716 dest1 = gen_highpart (SImode, set_dest);
1717 dest2 = gen_lowpart (SImode, set_dest);
1718 src1 = gen_highpart (SImode, set_src);
1719 src2 = gen_lowpart (SImode, set_src);
1721 /* Now emit using the real source and destination we found, swapping
1722 the order if we detect overlap. */
1723 if (reg_overlap_mentioned_p (dest1, src2))
1725 emit_insn (gen_movsi (dest2, src2));
1726 emit_insn (gen_movsi (dest1, src1));
1730 emit_insn (gen_movsi (dest1, src1));
1731 emit_insn (gen_movsi (dest2, src2));
1736 ;; Now handle the cases of memory moves from/to non-even
1737 ;; DI mode register pairs.
1739 [(set (match_operand:DI 0 "register_operand" "")
1740 (match_operand:DI 1 "memory_operand" ""))]
1743 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1744 [(clobber (const_int 0))]
1746 rtx word0 = adjust_address (operands[1], SImode, 0);
1747 rtx word1 = adjust_address (operands[1], SImode, 4);
1748 rtx high_part = gen_highpart (SImode, operands[0]);
1749 rtx low_part = gen_lowpart (SImode, operands[0]);
1751 if (reg_overlap_mentioned_p (high_part, word1))
1753 emit_insn (gen_movsi (low_part, word1));
1754 emit_insn (gen_movsi (high_part, word0));
1758 emit_insn (gen_movsi (high_part, word0));
1759 emit_insn (gen_movsi (low_part, word1));
1765 [(set (match_operand:DI 0 "memory_operand" "")
1766 (match_operand:DI 1 "register_operand" ""))]
1769 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1770 [(clobber (const_int 0))]
1772 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1773 gen_highpart (SImode, operands[1])));
1774 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1775 gen_lowpart (SImode, operands[1])));
1780 [(set (match_operand:DI 0 "memory_operand" "")
1781 (match_operand:DI 1 "const_zero_operand" ""))]
1785 && ! mem_min_alignment (operands[0], 8)))
1786 && offsettable_memref_p (operands[0])"
1787 [(clobber (const_int 0))]
1789 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1790 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1795 ;; Floating point and vector move instructions
1797 ;; Yes, you guessed it right, the former movsf expander.
1798 (define_expand "mov<V32:mode>"
1799 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1800 (match_operand:V32 1 "general_operand" ""))]
1801 "<V32:MODE>mode == SFmode || TARGET_VIS"
1803 if (sparc_expand_move (<V32:MODE>mode, operands))
1807 (define_insn "*movsf_insn"
1808 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
1809 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
1811 && (register_operand (operands[0], <V32:MODE>mode)
1812 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
1814 if (GET_CODE (operands[1]) == CONST_DOUBLE
1815 && (which_alternative == 2
1816 || which_alternative == 3
1817 || which_alternative == 4))
1822 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1823 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1824 operands[1] = GEN_INT (i);
1827 switch (which_alternative)
1830 return "fzeros\t%0";
1832 return "fmovs\t%1, %0";
1834 return "mov\t%1, %0";
1836 return "sethi\t%%hi(%a1), %0";
1841 return "ld\t%1, %0";
1844 return "st\t%r1, %0";
1849 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1851 ;; Exactly the same as above, except that all `f' cases are deleted.
1852 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1855 (define_insn "*movsf_insn_no_fpu"
1856 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1857 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1859 && (register_operand (operands[0], SFmode)
1860 || register_or_zero_operand (operands[1], SFmode))"
1862 if (GET_CODE (operands[1]) == CONST_DOUBLE
1863 && (which_alternative == 0
1864 || which_alternative == 1
1865 || which_alternative == 2))
1870 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1871 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1872 operands[1] = GEN_INT (i);
1875 switch (which_alternative)
1878 return "mov\t%1, %0";
1880 return "sethi\t%%hi(%a1), %0";
1884 return "ld\t%1, %0";
1886 return "st\t%r1, %0";
1891 [(set_attr "type" "*,*,*,load,store")])
1893 ;; The following 3 patterns build SFmode constants in integer registers.
1895 (define_insn "*movsf_lo_sum"
1896 [(set (match_operand:SF 0 "register_operand" "=r")
1897 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
1898 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
1904 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
1905 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1906 operands[2] = GEN_INT (i);
1907 return "or\t%1, %%lo(%a2), %0";
1910 (define_insn "*movsf_high"
1911 [(set (match_operand:SF 0 "register_operand" "=r")
1912 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
1918 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1919 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1920 operands[1] = GEN_INT (i);
1921 return "sethi\t%%hi(%1), %0";
1925 [(set (match_operand:SF 0 "register_operand" "")
1926 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
1927 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
1928 [(set (match_dup 0) (high:SF (match_dup 1)))
1929 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
1931 ;; Yes, you again guessed it right, the former movdf expander.
1932 (define_expand "mov<V64:mode>"
1933 [(set (match_operand:V64 0 "nonimmediate_operand" "")
1934 (match_operand:V64 1 "general_operand" ""))]
1935 "<V64:MODE>mode == DFmode || TARGET_VIS"
1937 if (sparc_expand_move (<V64:MODE>mode, operands))
1941 ;; Be careful, fmovd does not exist when !v9.
1942 (define_insn "*movdf_insn_sp32"
1943 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
1944 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
1947 && (register_operand (operands[0], DFmode)
1948 || register_or_zero_operand (operands[1], DFmode))"
1960 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
1961 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
1963 (define_insn "*movdf_insn_sp32_no_fpu"
1964 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
1965 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
1968 && (register_operand (operands[0], DFmode)
1969 || register_or_zero_operand (operands[1], DFmode))"
1976 [(set_attr "type" "load,store,*,*,*")
1977 (set_attr "length" "*,*,2,2,2")])
1979 ;; We have available v9 double floats but not 64-bit integer registers.
1980 (define_insn "*movdf_insn_sp32_v9"
1981 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
1982 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
1986 && (register_operand (operands[0], <V64:MODE>mode)
1987 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
1999 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2000 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2001 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2003 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2004 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2005 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2009 && (register_operand (operands[0], DFmode)
2010 || register_or_zero_operand (operands[1], DFmode))"
2017 [(set_attr "type" "load,store,store,*,*")
2018 (set_attr "length" "*,*,*,2,2")])
2020 ;; We have available both v9 double floats and 64-bit integer registers.
2021 (define_insn "*movdf_insn_sp64"
2022 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2023 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
2026 && (register_operand (operands[0], <V64:MODE>mode)
2027 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2037 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2038 (set_attr "length" "*,*,*,*,*,*,*,2")
2039 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2041 (define_insn "*movdf_insn_sp64_no_fpu"
2042 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2043 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2046 && (register_operand (operands[0], DFmode)
2047 || register_or_zero_operand (operands[1], DFmode))"
2052 [(set_attr "type" "*,load,store")])
2054 ;; This pattern builds V64mode constants in integer registers.
2056 [(set (match_operand:V64 0 "register_operand" "")
2057 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2059 && (GET_CODE (operands[0]) == REG
2060 && REGNO (operands[0]) < 32)
2061 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2062 && reload_completed"
2063 [(clobber (const_int 0))]
2065 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2069 #if HOST_BITS_PER_WIDE_INT == 32
2072 enum machine_mode mode = GET_MODE (operands[1]);
2073 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2074 emit_insn (gen_movdi (operands[0], tem));
2079 enum machine_mode mode = GET_MODE (operands[1]);
2080 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2081 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2083 gcc_assert (GET_CODE (hi) == CONST_INT);
2084 gcc_assert (GET_CODE (lo) == CONST_INT);
2086 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2088 /* Slick... but this trick loses if this subreg constant part
2089 can be done in one insn. */
2091 && ! SPARC_SETHI32_P (INTVAL (hi))
2092 && ! SPARC_SIMM13_P (INTVAL (hi)))
2094 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2095 gen_highpart (SImode, operands[0])));
2099 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2105 ;; Ok, now the splits to handle all the multi insn and
2106 ;; mis-aligned memory address cases.
2107 ;; In these splits please take note that we must be
2108 ;; careful when V9 but not ARCH64 because the integer
2109 ;; register DFmode cases must be handled.
2111 [(set (match_operand:V64 0 "register_operand" "")
2112 (match_operand:V64 1 "register_operand" ""))]
2115 && ((GET_CODE (operands[0]) == REG
2116 && REGNO (operands[0]) < 32)
2117 || (GET_CODE (operands[0]) == SUBREG
2118 && GET_CODE (SUBREG_REG (operands[0])) == REG
2119 && REGNO (SUBREG_REG (operands[0])) < 32))))
2120 && reload_completed"
2121 [(clobber (const_int 0))]
2123 rtx set_dest = operands[0];
2124 rtx set_src = operands[1];
2127 enum machine_mode half_mode;
2129 /* We can be expanded for DFmode or integral vector modes. */
2130 if (<V64:MODE>mode == DFmode)
2135 dest1 = gen_highpart (half_mode, set_dest);
2136 dest2 = gen_lowpart (half_mode, set_dest);
2137 src1 = gen_highpart (half_mode, set_src);
2138 src2 = gen_lowpart (half_mode, set_src);
2140 /* Now emit using the real source and destination we found, swapping
2141 the order if we detect overlap. */
2142 if (reg_overlap_mentioned_p (dest1, src2))
2144 emit_move_insn_1 (dest2, src2);
2145 emit_move_insn_1 (dest1, src1);
2149 emit_move_insn_1 (dest1, src1);
2150 emit_move_insn_1 (dest2, src2);
2156 [(set (match_operand:V64 0 "register_operand" "")
2157 (match_operand:V64 1 "memory_operand" ""))]
2160 && (((REGNO (operands[0]) % 2) != 0)
2161 || ! mem_min_alignment (operands[1], 8))
2162 && offsettable_memref_p (operands[1])"
2163 [(clobber (const_int 0))]
2165 enum machine_mode half_mode;
2168 /* We can be expanded for DFmode or integral vector modes. */
2169 if (<V64:MODE>mode == DFmode)
2174 word0 = adjust_address (operands[1], half_mode, 0);
2175 word1 = adjust_address (operands[1], half_mode, 4);
2177 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2179 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2180 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2184 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2185 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2191 [(set (match_operand:V64 0 "memory_operand" "")
2192 (match_operand:V64 1 "register_operand" ""))]
2195 && (((REGNO (operands[1]) % 2) != 0)
2196 || ! mem_min_alignment (operands[0], 8))
2197 && offsettable_memref_p (operands[0])"
2198 [(clobber (const_int 0))]
2200 enum machine_mode half_mode;
2203 /* We can be expanded for DFmode or integral vector modes. */
2204 if (<V64:MODE>mode == DFmode)
2209 word0 = adjust_address (operands[0], half_mode, 0);
2210 word1 = adjust_address (operands[0], half_mode, 4);
2212 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2213 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2218 [(set (match_operand:V64 0 "memory_operand" "")
2219 (match_operand:V64 1 "const_zero_operand" ""))]
2223 && ! mem_min_alignment (operands[0], 8)))
2224 && offsettable_memref_p (operands[0])"
2225 [(clobber (const_int 0))]
2227 enum machine_mode half_mode;
2230 /* We can be expanded for DFmode or integral vector modes. */
2231 if (<V64:MODE>mode == DFmode)
2236 dest1 = adjust_address (operands[0], half_mode, 0);
2237 dest2 = adjust_address (operands[0], half_mode, 4);
2239 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2240 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2245 [(set (match_operand:V64 0 "register_operand" "")
2246 (match_operand:V64 1 "const_zero_operand" ""))]
2249 && ((GET_CODE (operands[0]) == REG
2250 && REGNO (operands[0]) < 32)
2251 || (GET_CODE (operands[0]) == SUBREG
2252 && GET_CODE (SUBREG_REG (operands[0])) == REG
2253 && REGNO (SUBREG_REG (operands[0])) < 32))"
2254 [(clobber (const_int 0))]
2256 enum machine_mode half_mode;
2257 rtx set_dest = operands[0];
2260 /* We can be expanded for DFmode or integral vector modes. */
2261 if (<V64:MODE>mode == DFmode)
2266 dest1 = gen_highpart (half_mode, set_dest);
2267 dest2 = gen_lowpart (half_mode, set_dest);
2268 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2269 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2273 (define_expand "movtf"
2274 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2275 (match_operand:TF 1 "general_operand" ""))]
2278 if (sparc_expand_move (TFmode, operands))
2282 (define_insn "*movtf_insn_sp32"
2283 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2284 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2287 && (register_operand (operands[0], TFmode)
2288 || register_or_zero_operand (operands[1], TFmode))"
2290 [(set_attr "length" "4")])
2292 ;; Exactly the same as above, except that all `e' cases are deleted.
2293 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2296 (define_insn "*movtf_insn_sp32_no_fpu"
2297 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2298 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2301 && (register_operand (operands[0], TFmode)
2302 || register_or_zero_operand (operands[1], TFmode))"
2304 [(set_attr "length" "4")])
2306 (define_insn "*movtf_insn_sp64"
2307 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2308 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2311 && ! TARGET_HARD_QUAD
2312 && (register_operand (operands[0], TFmode)
2313 || register_or_zero_operand (operands[1], TFmode))"
2315 [(set_attr "length" "2")])
2317 (define_insn "*movtf_insn_sp64_hq"
2318 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2319 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2323 && (register_operand (operands[0], TFmode)
2324 || register_or_zero_operand (operands[1], TFmode))"
2332 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2333 (set_attr "length" "2,*,*,*,2,2")])
2335 (define_insn "*movtf_insn_sp64_no_fpu"
2336 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2337 (match_operand:TF 1 "input_operand" "orG,rG"))]
2340 && (register_operand (operands[0], TFmode)
2341 || register_or_zero_operand (operands[1], TFmode))"
2343 [(set_attr "length" "2")])
2345 ;; Now all the splits to handle multi-insn TF mode moves.
2347 [(set (match_operand:TF 0 "register_operand" "")
2348 (match_operand:TF 1 "register_operand" ""))]
2352 && ! TARGET_HARD_QUAD)
2353 || ! fp_register_operand (operands[0], TFmode))"
2354 [(clobber (const_int 0))]
2356 rtx set_dest = operands[0];
2357 rtx set_src = operands[1];
2361 dest1 = gen_df_reg (set_dest, 0);
2362 dest2 = gen_df_reg (set_dest, 1);
2363 src1 = gen_df_reg (set_src, 0);
2364 src2 = gen_df_reg (set_src, 1);
2366 /* Now emit using the real source and destination we found, swapping
2367 the order if we detect overlap. */
2368 if (reg_overlap_mentioned_p (dest1, src2))
2370 emit_insn (gen_movdf (dest2, src2));
2371 emit_insn (gen_movdf (dest1, src1));
2375 emit_insn (gen_movdf (dest1, src1));
2376 emit_insn (gen_movdf (dest2, src2));
2382 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2383 (match_operand:TF 1 "const_zero_operand" ""))]
2385 [(clobber (const_int 0))]
2387 rtx set_dest = operands[0];
2390 switch (GET_CODE (set_dest))
2393 dest1 = gen_df_reg (set_dest, 0);
2394 dest2 = gen_df_reg (set_dest, 1);
2397 dest1 = adjust_address (set_dest, DFmode, 0);
2398 dest2 = adjust_address (set_dest, DFmode, 8);
2404 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2405 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2410 [(set (match_operand:TF 0 "register_operand" "")
2411 (match_operand:TF 1 "memory_operand" ""))]
2413 && offsettable_memref_p (operands[1])
2415 || ! TARGET_HARD_QUAD
2416 || ! fp_register_operand (operands[0], TFmode)))"
2417 [(clobber (const_int 0))]
2419 rtx word0 = adjust_address (operands[1], DFmode, 0);
2420 rtx word1 = adjust_address (operands[1], DFmode, 8);
2421 rtx set_dest, dest1, dest2;
2423 set_dest = operands[0];
2425 dest1 = gen_df_reg (set_dest, 0);
2426 dest2 = gen_df_reg (set_dest, 1);
2428 /* Now output, ordering such that we don't clobber any registers
2429 mentioned in the address. */
2430 if (reg_overlap_mentioned_p (dest1, word1))
2433 emit_insn (gen_movdf (dest2, word1));
2434 emit_insn (gen_movdf (dest1, word0));
2438 emit_insn (gen_movdf (dest1, word0));
2439 emit_insn (gen_movdf (dest2, word1));
2445 [(set (match_operand:TF 0 "memory_operand" "")
2446 (match_operand:TF 1 "register_operand" ""))]
2448 && offsettable_memref_p (operands[0])
2450 || ! TARGET_HARD_QUAD
2451 || ! fp_register_operand (operands[1], TFmode)))"
2452 [(clobber (const_int 0))]
2454 rtx set_src = operands[1];
2456 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2457 gen_df_reg (set_src, 0)));
2458 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2459 gen_df_reg (set_src, 1)));
2464 ;; SPARC-V9 conditional move instructions
2466 ;; We can handle larger constants here for some flavors, but for now we keep
2467 ;; it simple and only allow those constants supported by all flavors.
2468 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2469 ;; 3 contains the constant if one is present, but we handle either for
2470 ;; generality (sparc.c puts a constant in operand 2).
2472 (define_expand "mov<I:mode>cc"
2473 [(set (match_operand:I 0 "register_operand" "")
2474 (if_then_else:I (match_operand 1 "comparison_operator" "")
2475 (match_operand:I 2 "arith10_operand" "")
2476 (match_operand:I 3 "arith10_operand" "")))]
2477 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2479 enum rtx_code code = GET_CODE (operands[1]);
2482 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2486 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2488 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2489 GET_CODE (operands[1]));
2491 if (XEXP (operands[1], 1) == const0_rtx
2492 && GET_CODE (XEXP (operands[1], 0)) == REG
2493 && GET_MODE (XEXP (operands[1], 0)) == DImode
2494 && v9_regcmp_p (code))
2495 cc_reg = XEXP (operands[1], 0);
2497 cc_reg = gen_compare_reg (operands[1]);
2499 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2502 (define_expand "mov<F:mode>cc"
2503 [(set (match_operand:F 0 "register_operand" "")
2504 (if_then_else:F (match_operand 1 "comparison_operator" "")
2505 (match_operand:F 2 "register_operand" "")
2506 (match_operand:F 3 "register_operand" "")))]
2507 "TARGET_V9 && TARGET_FPU"
2509 enum rtx_code code = GET_CODE (operands[1]);
2512 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2516 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2518 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2519 GET_CODE (operands[1]));
2521 if (XEXP (operands[1], 1) == const0_rtx
2522 && GET_CODE (XEXP (operands[1], 0)) == REG
2523 && GET_MODE (XEXP (operands[1], 0)) == DImode
2524 && v9_regcmp_p (code))
2525 cc_reg = XEXP (operands[1], 0);
2527 cc_reg = gen_compare_reg (operands[1]);
2529 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2532 ;; Conditional move define_insns
2534 (define_insn "*mov<I:mode>_cc_v9"
2535 [(set (match_operand:I 0 "register_operand" "=r,r")
2536 (if_then_else:I (match_operator 1 "comparison_operator"
2537 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2539 (match_operand:I 3 "arith11_operand" "rL,0")
2540 (match_operand:I 4 "arith11_operand" "0,rL")))]
2541 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2544 mov%c1\t%x2, %4, %0"
2545 [(set_attr "type" "cmove")])
2547 (define_insn "*mov<I:mode>_cc_reg_sp64"
2548 [(set (match_operand:I 0 "register_operand" "=r,r")
2549 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2550 [(match_operand:DI 2 "register_operand" "r,r")
2552 (match_operand:I 3 "arith10_operand" "rM,0")
2553 (match_operand:I 4 "arith10_operand" "0,rM")))]
2556 movr%D1\t%2, %r3, %0
2557 movr%d1\t%2, %r4, %0"
2558 [(set_attr "type" "cmove")])
2560 (define_insn "*movsf_cc_v9"
2561 [(set (match_operand:SF 0 "register_operand" "=f,f")
2562 (if_then_else:SF (match_operator 1 "comparison_operator"
2563 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2565 (match_operand:SF 3 "register_operand" "f,0")
2566 (match_operand:SF 4 "register_operand" "0,f")))]
2567 "TARGET_V9 && TARGET_FPU"
2569 fmovs%C1\t%x2, %3, %0
2570 fmovs%c1\t%x2, %4, %0"
2571 [(set_attr "type" "fpcmove")])
2573 (define_insn "*movsf_cc_reg_sp64"
2574 [(set (match_operand:SF 0 "register_operand" "=f,f")
2575 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2576 [(match_operand:DI 2 "register_operand" "r,r")
2578 (match_operand:SF 3 "register_operand" "f,0")
2579 (match_operand:SF 4 "register_operand" "0,f")))]
2580 "TARGET_ARCH64 && TARGET_FPU"
2582 fmovrs%D1\t%2, %3, %0
2583 fmovrs%d1\t%2, %4, %0"
2584 [(set_attr "type" "fpcrmove")])
2586 ;; Named because invoked by movtf_cc_v9
2587 (define_insn "movdf_cc_v9"
2588 [(set (match_operand:DF 0 "register_operand" "=e,e")
2589 (if_then_else:DF (match_operator 1 "comparison_operator"
2590 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2592 (match_operand:DF 3 "register_operand" "e,0")
2593 (match_operand:DF 4 "register_operand" "0,e")))]
2594 "TARGET_V9 && TARGET_FPU"
2596 fmovd%C1\t%x2, %3, %0
2597 fmovd%c1\t%x2, %4, %0"
2598 [(set_attr "type" "fpcmove")
2599 (set_attr "fptype" "double")])
2601 ;; Named because invoked by movtf_cc_reg_sp64
2602 (define_insn "movdf_cc_reg_sp64"
2603 [(set (match_operand:DF 0 "register_operand" "=e,e")
2604 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2605 [(match_operand:DI 2 "register_operand" "r,r")
2607 (match_operand:DF 3 "register_operand" "e,0")
2608 (match_operand:DF 4 "register_operand" "0,e")))]
2609 "TARGET_ARCH64 && TARGET_FPU"
2611 fmovrd%D1\t%2, %3, %0
2612 fmovrd%d1\t%2, %4, %0"
2613 [(set_attr "type" "fpcrmove")
2614 (set_attr "fptype" "double")])
2616 (define_insn "*movtf_cc_hq_v9"
2617 [(set (match_operand:TF 0 "register_operand" "=e,e")
2618 (if_then_else:TF (match_operator 1 "comparison_operator"
2619 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2621 (match_operand:TF 3 "register_operand" "e,0")
2622 (match_operand:TF 4 "register_operand" "0,e")))]
2623 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2625 fmovq%C1\t%x2, %3, %0
2626 fmovq%c1\t%x2, %4, %0"
2627 [(set_attr "type" "fpcmove")])
2629 (define_insn "*movtf_cc_reg_hq_sp64"
2630 [(set (match_operand:TF 0 "register_operand" "=e,e")
2631 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2632 [(match_operand:DI 2 "register_operand" "r,r")
2634 (match_operand:TF 3 "register_operand" "e,0")
2635 (match_operand:TF 4 "register_operand" "0,e")))]
2636 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2638 fmovrq%D1\t%2, %3, %0
2639 fmovrq%d1\t%2, %4, %0"
2640 [(set_attr "type" "fpcrmove")])
2642 (define_insn_and_split "*movtf_cc_v9"
2643 [(set (match_operand:TF 0 "register_operand" "=e,e")
2644 (if_then_else:TF (match_operator 1 "comparison_operator"
2645 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2647 (match_operand:TF 3 "register_operand" "e,0")
2648 (match_operand:TF 4 "register_operand" "0,e")))]
2649 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2651 "&& reload_completed"
2652 [(clobber (const_int 0))]
2654 rtx set_dest = operands[0];
2655 rtx set_srca = operands[3];
2656 rtx set_srcb = operands[4];
2657 int third = rtx_equal_p (set_dest, set_srca);
2659 rtx srca1, srca2, srcb1, srcb2;
2661 dest1 = gen_df_reg (set_dest, 0);
2662 dest2 = gen_df_reg (set_dest, 1);
2663 srca1 = gen_df_reg (set_srca, 0);
2664 srca2 = gen_df_reg (set_srca, 1);
2665 srcb1 = gen_df_reg (set_srcb, 0);
2666 srcb2 = gen_df_reg (set_srcb, 1);
2668 /* Now emit using the real source and destination we found, swapping
2669 the order if we detect overlap. */
2670 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2671 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2673 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2674 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2678 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2679 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2683 [(set_attr "length" "2")])
2685 (define_insn_and_split "*movtf_cc_reg_sp64"
2686 [(set (match_operand:TF 0 "register_operand" "=e,e")
2687 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2688 [(match_operand:DI 2 "register_operand" "r,r")
2690 (match_operand:TF 3 "register_operand" "e,0")
2691 (match_operand:TF 4 "register_operand" "0,e")))]
2692 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2694 "&& reload_completed"
2695 [(clobber (const_int 0))]
2697 rtx set_dest = operands[0];
2698 rtx set_srca = operands[3];
2699 rtx set_srcb = operands[4];
2700 int third = rtx_equal_p (set_dest, set_srca);
2702 rtx srca1, srca2, srcb1, srcb2;
2704 dest1 = gen_df_reg (set_dest, 0);
2705 dest2 = gen_df_reg (set_dest, 1);
2706 srca1 = gen_df_reg (set_srca, 0);
2707 srca2 = gen_df_reg (set_srca, 1);
2708 srcb1 = gen_df_reg (set_srcb, 0);
2709 srcb2 = gen_df_reg (set_srcb, 1);
2711 /* Now emit using the real source and destination we found, swapping
2712 the order if we detect overlap. */
2713 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2714 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2716 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2717 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2721 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2722 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2726 [(set_attr "length" "2")])
2729 ;; Zero-extension instructions
2731 ;; These patterns originally accepted general_operands, however, slightly
2732 ;; better code is generated by only accepting register_operands, and then
2733 ;; letting combine generate the ldu[hb] insns.
2735 (define_expand "zero_extendhisi2"
2736 [(set (match_operand:SI 0 "register_operand" "")
2737 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2740 rtx temp = gen_reg_rtx (SImode);
2741 rtx shift_16 = GEN_INT (16);
2742 int op1_subbyte = 0;
2744 if (GET_CODE (operand1) == SUBREG)
2746 op1_subbyte = SUBREG_BYTE (operand1);
2747 op1_subbyte /= GET_MODE_SIZE (SImode);
2748 op1_subbyte *= GET_MODE_SIZE (SImode);
2749 operand1 = XEXP (operand1, 0);
2752 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2754 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2758 (define_insn "*zero_extendhisi2_insn"
2759 [(set (match_operand:SI 0 "register_operand" "=r")
2760 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2763 [(set_attr "type" "load")
2764 (set_attr "us3load_type" "3cycle")])
2766 (define_expand "zero_extendqihi2"
2767 [(set (match_operand:HI 0 "register_operand" "")
2768 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2772 (define_insn "*zero_extendqihi2_insn"
2773 [(set (match_operand:HI 0 "register_operand" "=r,r")
2774 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2775 "GET_CODE (operands[1]) != CONST_INT"
2779 [(set_attr "type" "*,load")
2780 (set_attr "us3load_type" "*,3cycle")])
2782 (define_expand "zero_extendqisi2"
2783 [(set (match_operand:SI 0 "register_operand" "")
2784 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2788 (define_insn "*zero_extendqisi2_insn"
2789 [(set (match_operand:SI 0 "register_operand" "=r,r")
2790 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2791 "GET_CODE (operands[1]) != CONST_INT"
2795 [(set_attr "type" "*,load")
2796 (set_attr "us3load_type" "*,3cycle")])
2798 (define_expand "zero_extendqidi2"
2799 [(set (match_operand:DI 0 "register_operand" "")
2800 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2804 (define_insn "*zero_extendqidi2_insn"
2805 [(set (match_operand:DI 0 "register_operand" "=r,r")
2806 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2807 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2811 [(set_attr "type" "*,load")
2812 (set_attr "us3load_type" "*,3cycle")])
2814 (define_expand "zero_extendhidi2"
2815 [(set (match_operand:DI 0 "register_operand" "")
2816 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2819 rtx temp = gen_reg_rtx (DImode);
2820 rtx shift_48 = GEN_INT (48);
2821 int op1_subbyte = 0;
2823 if (GET_CODE (operand1) == SUBREG)
2825 op1_subbyte = SUBREG_BYTE (operand1);
2826 op1_subbyte /= GET_MODE_SIZE (DImode);
2827 op1_subbyte *= GET_MODE_SIZE (DImode);
2828 operand1 = XEXP (operand1, 0);
2831 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2833 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2837 (define_insn "*zero_extendhidi2_insn"
2838 [(set (match_operand:DI 0 "register_operand" "=r")
2839 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2842 [(set_attr "type" "load")
2843 (set_attr "us3load_type" "3cycle")])
2845 ;; ??? Write truncdisi pattern using sra?
2847 (define_expand "zero_extendsidi2"
2848 [(set (match_operand:DI 0 "register_operand" "")
2849 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2853 (define_insn "*zero_extendsidi2_insn_sp64"
2854 [(set (match_operand:DI 0 "register_operand" "=r,r")
2855 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2856 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2860 [(set_attr "type" "shift,load")])
2862 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2863 [(set (match_operand:DI 0 "register_operand" "=r")
2864 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2867 "&& reload_completed"
2868 [(set (match_dup 2) (match_dup 3))
2869 (set (match_dup 4) (match_dup 5))]
2873 dest1 = gen_highpart (SImode, operands[0]);
2874 dest2 = gen_lowpart (SImode, operands[0]);
2876 /* Swap the order in case of overlap. */
2877 if (REGNO (dest1) == REGNO (operands[1]))
2879 operands[2] = dest2;
2880 operands[3] = operands[1];
2881 operands[4] = dest1;
2882 operands[5] = const0_rtx;
2886 operands[2] = dest1;
2887 operands[3] = const0_rtx;
2888 operands[4] = dest2;
2889 operands[5] = operands[1];
2892 [(set_attr "length" "2")])
2894 ;; Simplify comparisons of extended values.
2896 (define_insn "*cmp_zero_extendqisi2"
2898 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2901 "andcc\t%0, 0xff, %%g0"
2902 [(set_attr "type" "compare")])
2904 (define_insn "*cmp_zero_qi"
2906 (compare:CC (match_operand:QI 0 "register_operand" "r")
2909 "andcc\t%0, 0xff, %%g0"
2910 [(set_attr "type" "compare")])
2912 (define_insn "*cmp_zero_extendqisi2_set"
2914 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2916 (set (match_operand:SI 0 "register_operand" "=r")
2917 (zero_extend:SI (match_dup 1)))]
2919 "andcc\t%1, 0xff, %0"
2920 [(set_attr "type" "compare")])
2922 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2924 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2927 (set (match_operand:SI 0 "register_operand" "=r")
2928 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2930 "andcc\t%1, 0xff, %0"
2931 [(set_attr "type" "compare")])
2933 (define_insn "*cmp_zero_extendqidi2"
2935 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2938 "andcc\t%0, 0xff, %%g0"
2939 [(set_attr "type" "compare")])
2941 (define_insn "*cmp_zero_qi_sp64"
2943 (compare:CCX (match_operand:QI 0 "register_operand" "r")
2946 "andcc\t%0, 0xff, %%g0"
2947 [(set_attr "type" "compare")])
2949 (define_insn "*cmp_zero_extendqidi2_set"
2951 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2953 (set (match_operand:DI 0 "register_operand" "=r")
2954 (zero_extend:DI (match_dup 1)))]
2956 "andcc\t%1, 0xff, %0"
2957 [(set_attr "type" "compare")])
2959 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2961 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2964 (set (match_operand:DI 0 "register_operand" "=r")
2965 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2967 "andcc\t%1, 0xff, %0"
2968 [(set_attr "type" "compare")])
2970 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2972 (define_insn "*cmp_siqi_trunc"
2974 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2977 "andcc\t%0, 0xff, %%g0"
2978 [(set_attr "type" "compare")])
2980 (define_insn "*cmp_siqi_trunc_set"
2982 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
2984 (set (match_operand:QI 0 "register_operand" "=r")
2985 (subreg:QI (match_dup 1) 3))]
2987 "andcc\t%1, 0xff, %0"
2988 [(set_attr "type" "compare")])
2990 (define_insn "*cmp_diqi_trunc"
2992 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
2995 "andcc\t%0, 0xff, %%g0"
2996 [(set_attr "type" "compare")])
2998 (define_insn "*cmp_diqi_trunc_set"
3000 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3002 (set (match_operand:QI 0 "register_operand" "=r")
3003 (subreg:QI (match_dup 1) 7))]
3005 "andcc\t%1, 0xff, %0"
3006 [(set_attr "type" "compare")])
3009 ;; Sign-extension instructions
3011 ;; These patterns originally accepted general_operands, however, slightly
3012 ;; better code is generated by only accepting register_operands, and then
3013 ;; letting combine generate the lds[hb] insns.
3015 (define_expand "extendhisi2"
3016 [(set (match_operand:SI 0 "register_operand" "")
3017 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3020 rtx temp = gen_reg_rtx (SImode);
3021 rtx shift_16 = GEN_INT (16);
3022 int op1_subbyte = 0;
3024 if (GET_CODE (operand1) == SUBREG)
3026 op1_subbyte = SUBREG_BYTE (operand1);
3027 op1_subbyte /= GET_MODE_SIZE (SImode);
3028 op1_subbyte *= GET_MODE_SIZE (SImode);
3029 operand1 = XEXP (operand1, 0);
3032 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3034 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3038 (define_insn "*sign_extendhisi2_insn"
3039 [(set (match_operand:SI 0 "register_operand" "=r")
3040 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3043 [(set_attr "type" "sload")
3044 (set_attr "us3load_type" "3cycle")])
3046 (define_expand "extendqihi2"
3047 [(set (match_operand:HI 0 "register_operand" "")
3048 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3051 rtx temp = gen_reg_rtx (SImode);
3052 rtx shift_24 = GEN_INT (24);
3053 int op1_subbyte = 0;
3054 int op0_subbyte = 0;
3056 if (GET_CODE (operand1) == SUBREG)
3058 op1_subbyte = SUBREG_BYTE (operand1);
3059 op1_subbyte /= GET_MODE_SIZE (SImode);
3060 op1_subbyte *= GET_MODE_SIZE (SImode);
3061 operand1 = XEXP (operand1, 0);
3063 if (GET_CODE (operand0) == SUBREG)
3065 op0_subbyte = SUBREG_BYTE (operand0);
3066 op0_subbyte /= GET_MODE_SIZE (SImode);
3067 op0_subbyte *= GET_MODE_SIZE (SImode);
3068 operand0 = XEXP (operand0, 0);
3070 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3072 if (GET_MODE (operand0) != SImode)
3073 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3074 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3078 (define_insn "*sign_extendqihi2_insn"
3079 [(set (match_operand:HI 0 "register_operand" "=r")
3080 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3083 [(set_attr "type" "sload")
3084 (set_attr "us3load_type" "3cycle")])
3086 (define_expand "extendqisi2"
3087 [(set (match_operand:SI 0 "register_operand" "")
3088 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3091 rtx temp = gen_reg_rtx (SImode);
3092 rtx shift_24 = GEN_INT (24);
3093 int op1_subbyte = 0;
3095 if (GET_CODE (operand1) == SUBREG)
3097 op1_subbyte = SUBREG_BYTE (operand1);
3098 op1_subbyte /= GET_MODE_SIZE (SImode);
3099 op1_subbyte *= GET_MODE_SIZE (SImode);
3100 operand1 = XEXP (operand1, 0);
3103 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3105 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3109 (define_insn "*sign_extendqisi2_insn"
3110 [(set (match_operand:SI 0 "register_operand" "=r")
3111 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3114 [(set_attr "type" "sload")
3115 (set_attr "us3load_type" "3cycle")])
3117 (define_expand "extendqidi2"
3118 [(set (match_operand:DI 0 "register_operand" "")
3119 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3122 rtx temp = gen_reg_rtx (DImode);
3123 rtx shift_56 = GEN_INT (56);
3124 int op1_subbyte = 0;
3126 if (GET_CODE (operand1) == SUBREG)
3128 op1_subbyte = SUBREG_BYTE (operand1);
3129 op1_subbyte /= GET_MODE_SIZE (DImode);
3130 op1_subbyte *= GET_MODE_SIZE (DImode);
3131 operand1 = XEXP (operand1, 0);
3134 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3136 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3140 (define_insn "*sign_extendqidi2_insn"
3141 [(set (match_operand:DI 0 "register_operand" "=r")
3142 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3145 [(set_attr "type" "sload")
3146 (set_attr "us3load_type" "3cycle")])
3148 (define_expand "extendhidi2"
3149 [(set (match_operand:DI 0 "register_operand" "")
3150 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3153 rtx temp = gen_reg_rtx (DImode);
3154 rtx shift_48 = GEN_INT (48);
3155 int op1_subbyte = 0;
3157 if (GET_CODE (operand1) == SUBREG)
3159 op1_subbyte = SUBREG_BYTE (operand1);
3160 op1_subbyte /= GET_MODE_SIZE (DImode);
3161 op1_subbyte *= GET_MODE_SIZE (DImode);
3162 operand1 = XEXP (operand1, 0);
3165 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3167 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3171 (define_insn "*sign_extendhidi2_insn"
3172 [(set (match_operand:DI 0 "register_operand" "=r")
3173 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3176 [(set_attr "type" "sload")
3177 (set_attr "us3load_type" "3cycle")])
3179 (define_expand "extendsidi2"
3180 [(set (match_operand:DI 0 "register_operand" "")
3181 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3185 (define_insn "*sign_extendsidi2_insn"
3186 [(set (match_operand:DI 0 "register_operand" "=r,r")
3187 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3192 [(set_attr "type" "shift,sload")
3193 (set_attr "us3load_type" "*,3cycle")])
3196 ;; Special pattern for optimizing bit-field compares. This is needed
3197 ;; because combine uses this as a canonical form.
3199 (define_insn "*cmp_zero_extract"
3202 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3203 (match_operand:SI 1 "small_int_operand" "I")
3204 (match_operand:SI 2 "small_int_operand" "I"))
3206 "INTVAL (operands[2]) > 19"
3208 int len = INTVAL (operands[1]);
3209 int pos = 32 - INTVAL (operands[2]) - len;
3210 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3211 operands[1] = GEN_INT (mask);
3212 return "andcc\t%0, %1, %%g0";
3214 [(set_attr "type" "compare")])
3216 (define_insn "*cmp_zero_extract_sp64"
3219 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3220 (match_operand:SI 1 "small_int_operand" "I")
3221 (match_operand:SI 2 "small_int_operand" "I"))
3223 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3225 int len = INTVAL (operands[1]);
3226 int pos = 64 - INTVAL (operands[2]) - len;
3227 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3228 operands[1] = GEN_INT (mask);
3229 return "andcc\t%0, %1, %%g0";
3231 [(set_attr "type" "compare")])
3234 ;; Conversions between float, double and long double.
3236 (define_insn "extendsfdf2"
3237 [(set (match_operand:DF 0 "register_operand" "=e")
3239 (match_operand:SF 1 "register_operand" "f")))]
3242 [(set_attr "type" "fp")
3243 (set_attr "fptype" "double")])
3245 (define_expand "extendsftf2"
3246 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3248 (match_operand:SF 1 "register_operand" "")))]
3249 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3250 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3252 (define_insn "*extendsftf2_hq"
3253 [(set (match_operand:TF 0 "register_operand" "=e")
3255 (match_operand:SF 1 "register_operand" "f")))]
3256 "TARGET_FPU && TARGET_HARD_QUAD"
3258 [(set_attr "type" "fp")])
3260 (define_expand "extenddftf2"
3261 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3263 (match_operand:DF 1 "register_operand" "")))]
3264 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3265 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3267 (define_insn "*extenddftf2_hq"
3268 [(set (match_operand:TF 0 "register_operand" "=e")
3270 (match_operand:DF 1 "register_operand" "e")))]
3271 "TARGET_FPU && TARGET_HARD_QUAD"
3273 [(set_attr "type" "fp")])
3275 (define_insn "truncdfsf2"
3276 [(set (match_operand:SF 0 "register_operand" "=f")
3278 (match_operand:DF 1 "register_operand" "e")))]
3281 [(set_attr "type" "fp")
3282 (set_attr "fptype" "double")])
3284 (define_expand "trunctfsf2"
3285 [(set (match_operand:SF 0 "register_operand" "")
3287 (match_operand:TF 1 "general_operand" "")))]
3288 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3289 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3291 (define_insn "*trunctfsf2_hq"
3292 [(set (match_operand:SF 0 "register_operand" "=f")
3294 (match_operand:TF 1 "register_operand" "e")))]
3295 "TARGET_FPU && TARGET_HARD_QUAD"
3297 [(set_attr "type" "fp")])
3299 (define_expand "trunctfdf2"
3300 [(set (match_operand:DF 0 "register_operand" "")
3302 (match_operand:TF 1 "general_operand" "")))]
3303 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3304 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3306 (define_insn "*trunctfdf2_hq"
3307 [(set (match_operand:DF 0 "register_operand" "=e")
3309 (match_operand:TF 1 "register_operand" "e")))]
3310 "TARGET_FPU && TARGET_HARD_QUAD"
3312 [(set_attr "type" "fp")])
3315 ;; Conversion between fixed point and floating point.
3317 (define_insn "floatsisf2"
3318 [(set (match_operand:SF 0 "register_operand" "=f")
3319 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3322 [(set_attr "type" "fp")
3323 (set_attr "fptype" "double")])
3325 (define_insn "floatsidf2"
3326 [(set (match_operand:DF 0 "register_operand" "=e")
3327 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3330 [(set_attr "type" "fp")
3331 (set_attr "fptype" "double")])
3333 (define_expand "floatsitf2"
3334 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3335 (float:TF (match_operand:SI 1 "register_operand" "")))]
3336 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3337 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3339 (define_insn "*floatsitf2_hq"
3340 [(set (match_operand:TF 0 "register_operand" "=e")
3341 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3342 "TARGET_FPU && TARGET_HARD_QUAD"
3344 [(set_attr "type" "fp")])
3346 (define_expand "floatunssitf2"
3347 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3348 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3349 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3350 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3352 ;; Now the same for 64 bit sources.
3354 (define_insn "floatdisf2"
3355 [(set (match_operand:SF 0 "register_operand" "=f")
3356 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3357 "TARGET_V9 && TARGET_FPU"
3359 [(set_attr "type" "fp")
3360 (set_attr "fptype" "double")])
3362 (define_expand "floatunsdisf2"
3363 [(use (match_operand:SF 0 "register_operand" ""))
3364 (use (match_operand:DI 1 "general_operand" ""))]
3365 "TARGET_ARCH64 && TARGET_FPU"
3366 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3368 (define_insn "floatdidf2"
3369 [(set (match_operand:DF 0 "register_operand" "=e")
3370 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3371 "TARGET_V9 && TARGET_FPU"
3373 [(set_attr "type" "fp")
3374 (set_attr "fptype" "double")])
3376 (define_expand "floatunsdidf2"
3377 [(use (match_operand:DF 0 "register_operand" ""))
3378 (use (match_operand:DI 1 "general_operand" ""))]
3379 "TARGET_ARCH64 && TARGET_FPU"
3380 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3382 (define_expand "floatditf2"
3383 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3384 (float:TF (match_operand:DI 1 "register_operand" "")))]
3385 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3386 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3388 (define_insn "*floatditf2_hq"
3389 [(set (match_operand:TF 0 "register_operand" "=e")
3390 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3391 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3393 [(set_attr "type" "fp")])
3395 (define_expand "floatunsditf2"
3396 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3397 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3398 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3399 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3401 ;; Convert a float to an actual integer.
3402 ;; Truncation is performed as part of the conversion.
3404 (define_insn "fix_truncsfsi2"
3405 [(set (match_operand:SI 0 "register_operand" "=f")
3406 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3409 [(set_attr "type" "fp")
3410 (set_attr "fptype" "double")])
3412 (define_insn "fix_truncdfsi2"
3413 [(set (match_operand:SI 0 "register_operand" "=f")
3414 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3417 [(set_attr "type" "fp")
3418 (set_attr "fptype" "double")])
3420 (define_expand "fix_trunctfsi2"
3421 [(set (match_operand:SI 0 "register_operand" "")
3422 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3423 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3424 "emit_tfmode_cvt (FIX, operands); DONE;")
3426 (define_insn "*fix_trunctfsi2_hq"
3427 [(set (match_operand:SI 0 "register_operand" "=f")
3428 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3429 "TARGET_FPU && TARGET_HARD_QUAD"
3431 [(set_attr "type" "fp")])
3433 (define_expand "fixuns_trunctfsi2"
3434 [(set (match_operand:SI 0 "register_operand" "")
3435 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3436 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3437 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3439 ;; Now the same, for V9 targets
3441 (define_insn "fix_truncsfdi2"
3442 [(set (match_operand:DI 0 "register_operand" "=e")
3443 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3444 "TARGET_V9 && TARGET_FPU"
3446 [(set_attr "type" "fp")
3447 (set_attr "fptype" "double")])
3449 (define_expand "fixuns_truncsfdi2"
3450 [(use (match_operand:DI 0 "register_operand" ""))
3451 (use (match_operand:SF 1 "general_operand" ""))]
3452 "TARGET_ARCH64 && TARGET_FPU"
3453 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3455 (define_insn "fix_truncdfdi2"
3456 [(set (match_operand:DI 0 "register_operand" "=e")
3457 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3458 "TARGET_V9 && TARGET_FPU"
3460 [(set_attr "type" "fp")
3461 (set_attr "fptype" "double")])
3463 (define_expand "fixuns_truncdfdi2"
3464 [(use (match_operand:DI 0 "register_operand" ""))
3465 (use (match_operand:DF 1 "general_operand" ""))]
3466 "TARGET_ARCH64 && TARGET_FPU"
3467 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3469 (define_expand "fix_trunctfdi2"
3470 [(set (match_operand:DI 0 "register_operand" "")
3471 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3472 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3473 "emit_tfmode_cvt (FIX, operands); DONE;")
3475 (define_insn "*fix_trunctfdi2_hq"
3476 [(set (match_operand:DI 0 "register_operand" "=e")
3477 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3478 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3480 [(set_attr "type" "fp")])
3482 (define_expand "fixuns_trunctfdi2"
3483 [(set (match_operand:DI 0 "register_operand" "")
3484 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3485 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3486 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3489 ;; Integer addition/subtraction instructions.
3491 (define_expand "adddi3"
3492 [(set (match_operand:DI 0 "register_operand" "")
3493 (plus:DI (match_operand:DI 1 "register_operand" "")
3494 (match_operand:DI 2 "arith_double_add_operand" "")))]
3497 if (! TARGET_ARCH64)
3499 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3500 gen_rtx_SET (VOIDmode, operands[0],
3501 gen_rtx_PLUS (DImode, operands[1],
3503 gen_rtx_CLOBBER (VOIDmode,
3504 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3509 (define_insn_and_split "adddi3_insn_sp32"
3510 [(set (match_operand:DI 0 "register_operand" "=r")
3511 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3512 (match_operand:DI 2 "arith_double_operand" "rHI")))
3513 (clobber (reg:CC 100))]
3516 "&& reload_completed"
3517 [(parallel [(set (reg:CC_NOOV 100)
3518 (compare:CC_NOOV (plus:SI (match_dup 4)
3522 (plus:SI (match_dup 4) (match_dup 5)))])
3524 (plus:SI (plus:SI (match_dup 7)
3526 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3528 operands[3] = gen_lowpart (SImode, operands[0]);
3529 operands[4] = gen_lowpart (SImode, operands[1]);
3530 operands[5] = gen_lowpart (SImode, operands[2]);
3531 operands[6] = gen_highpart (SImode, operands[0]);
3532 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3533 #if HOST_BITS_PER_WIDE_INT == 32
3534 if (GET_CODE (operands[2]) == CONST_INT)
3536 if (INTVAL (operands[2]) < 0)
3537 operands[8] = constm1_rtx;
3539 operands[8] = const0_rtx;
3543 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3545 [(set_attr "length" "2")])
3547 ;; LTU here means "carry set"
3549 [(set (match_operand:SI 0 "register_operand" "=r")
3550 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3551 (match_operand:SI 2 "arith_operand" "rI"))
3552 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3555 [(set_attr "type" "ialuX")])
3557 (define_insn_and_split "*addx_extend_sp32"
3558 [(set (match_operand:DI 0 "register_operand" "=r")
3559 (zero_extend:DI (plus:SI (plus:SI
3560 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3561 (match_operand:SI 2 "arith_operand" "rI"))
3562 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3565 "&& reload_completed"
3566 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3567 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3568 (set (match_dup 4) (const_int 0))]
3569 "operands[3] = gen_lowpart (SImode, operands[0]);
3570 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3571 [(set_attr "length" "2")])
3573 (define_insn "*addx_extend_sp64"
3574 [(set (match_operand:DI 0 "register_operand" "=r")
3575 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3576 (match_operand:SI 2 "arith_operand" "rI"))
3577 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3580 [(set_attr "type" "ialuX")])
3582 (define_insn_and_split ""
3583 [(set (match_operand:DI 0 "register_operand" "=r")
3584 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3585 (match_operand:DI 2 "register_operand" "r")))
3586 (clobber (reg:CC 100))]
3589 "&& reload_completed"
3590 [(parallel [(set (reg:CC_NOOV 100)
3591 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3593 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3595 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3596 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3597 "operands[3] = gen_lowpart (SImode, operands[2]);
3598 operands[4] = gen_highpart (SImode, operands[2]);
3599 operands[5] = gen_lowpart (SImode, operands[0]);
3600 operands[6] = gen_highpart (SImode, operands[0]);"
3601 [(set_attr "length" "2")])
3603 (define_insn "*adddi3_sp64"
3604 [(set (match_operand:DI 0 "register_operand" "=r,r")
3605 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3606 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3612 (define_insn "addsi3"
3613 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3614 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3615 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3620 fpadd32s\t%1, %2, %0"
3621 [(set_attr "type" "*,*,fga")
3622 (set_attr "fptype" "*,*,single")])
3624 (define_insn "*cmp_cc_plus"
3625 [(set (reg:CC_NOOV 100)
3626 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3627 (match_operand:SI 1 "arith_operand" "rI"))
3630 "addcc\t%0, %1, %%g0"
3631 [(set_attr "type" "compare")])
3633 (define_insn "*cmp_ccx_plus"
3634 [(set (reg:CCX_NOOV 100)
3635 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3636 (match_operand:DI 1 "arith_operand" "rI"))
3639 "addcc\t%0, %1, %%g0"
3640 [(set_attr "type" "compare")])
3642 (define_insn "*cmp_cc_plus_set"
3643 [(set (reg:CC_NOOV 100)
3644 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3645 (match_operand:SI 2 "arith_operand" "rI"))
3647 (set (match_operand:SI 0 "register_operand" "=r")
3648 (plus:SI (match_dup 1) (match_dup 2)))]
3651 [(set_attr "type" "compare")])
3653 (define_insn "*cmp_ccx_plus_set"
3654 [(set (reg:CCX_NOOV 100)
3655 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3656 (match_operand:DI 2 "arith_operand" "rI"))
3658 (set (match_operand:DI 0 "register_operand" "=r")
3659 (plus:DI (match_dup 1) (match_dup 2)))]
3662 [(set_attr "type" "compare")])
3664 (define_expand "subdi3"
3665 [(set (match_operand:DI 0 "register_operand" "")
3666 (minus:DI (match_operand:DI 1 "register_operand" "")
3667 (match_operand:DI 2 "arith_double_add_operand" "")))]
3670 if (! TARGET_ARCH64)
3672 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3673 gen_rtx_SET (VOIDmode, operands[0],
3674 gen_rtx_MINUS (DImode, operands[1],
3676 gen_rtx_CLOBBER (VOIDmode,
3677 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3682 (define_insn_and_split "subdi3_insn_sp32"
3683 [(set (match_operand:DI 0 "register_operand" "=r")
3684 (minus:DI (match_operand:DI 1 "register_operand" "r")
3685 (match_operand:DI 2 "arith_double_operand" "rHI")))
3686 (clobber (reg:CC 100))]
3689 "&& reload_completed"
3690 [(parallel [(set (reg:CC_NOOV 100)
3691 (compare:CC_NOOV (minus:SI (match_dup 4)
3695 (minus:SI (match_dup 4) (match_dup 5)))])
3697 (minus:SI (minus:SI (match_dup 7)
3699 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3701 operands[3] = gen_lowpart (SImode, operands[0]);
3702 operands[4] = gen_lowpart (SImode, operands[1]);
3703 operands[5] = gen_lowpart (SImode, operands[2]);
3704 operands[6] = gen_highpart (SImode, operands[0]);
3705 operands[7] = gen_highpart (SImode, operands[1]);
3706 #if HOST_BITS_PER_WIDE_INT == 32
3707 if (GET_CODE (operands[2]) == CONST_INT)
3709 if (INTVAL (operands[2]) < 0)
3710 operands[8] = constm1_rtx;
3712 operands[8] = const0_rtx;
3716 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3718 [(set_attr "length" "2")])
3720 ;; LTU here means "carry set"
3722 [(set (match_operand:SI 0 "register_operand" "=r")
3723 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3724 (match_operand:SI 2 "arith_operand" "rI"))
3725 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3728 [(set_attr "type" "ialuX")])
3730 (define_insn "*subx_extend_sp64"
3731 [(set (match_operand:DI 0 "register_operand" "=r")
3732 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3733 (match_operand:SI 2 "arith_operand" "rI"))
3734 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3737 [(set_attr "type" "ialuX")])
3739 (define_insn_and_split "*subx_extend"
3740 [(set (match_operand:DI 0 "register_operand" "=r")
3741 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3742 (match_operand:SI 2 "arith_operand" "rI"))
3743 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3746 "&& reload_completed"
3747 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3748 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3749 (set (match_dup 4) (const_int 0))]
3750 "operands[3] = gen_lowpart (SImode, operands[0]);
3751 operands[4] = gen_highpart (SImode, operands[0]);"
3752 [(set_attr "length" "2")])
3754 (define_insn_and_split ""
3755 [(set (match_operand:DI 0 "register_operand" "=r")
3756 (minus:DI (match_operand:DI 1 "register_operand" "r")
3757 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3758 (clobber (reg:CC 100))]
3761 "&& reload_completed"
3762 [(parallel [(set (reg:CC_NOOV 100)
3763 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3765 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3767 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3768 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3769 "operands[3] = gen_lowpart (SImode, operands[1]);
3770 operands[4] = gen_highpart (SImode, operands[1]);
3771 operands[5] = gen_lowpart (SImode, operands[0]);
3772 operands[6] = gen_highpart (SImode, operands[0]);"
3773 [(set_attr "length" "2")])
3775 (define_insn "*subdi3_sp64"
3776 [(set (match_operand:DI 0 "register_operand" "=r,r")
3777 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3778 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3784 (define_insn "subsi3"
3785 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3786 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3787 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3792 fpsub32s\t%1, %2, %0"
3793 [(set_attr "type" "*,*,fga")
3794 (set_attr "fptype" "*,*,single")])
3796 (define_insn "*cmp_minus_cc"
3797 [(set (reg:CC_NOOV 100)
3798 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3799 (match_operand:SI 1 "arith_operand" "rI"))
3802 "subcc\t%r0, %1, %%g0"
3803 [(set_attr "type" "compare")])
3805 (define_insn "*cmp_minus_ccx"
3806 [(set (reg:CCX_NOOV 100)
3807 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3808 (match_operand:DI 1 "arith_operand" "rI"))
3811 "subcc\t%0, %1, %%g0"
3812 [(set_attr "type" "compare")])
3814 (define_insn "cmp_minus_cc_set"
3815 [(set (reg:CC_NOOV 100)
3816 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3817 (match_operand:SI 2 "arith_operand" "rI"))
3819 (set (match_operand:SI 0 "register_operand" "=r")
3820 (minus:SI (match_dup 1) (match_dup 2)))]
3822 "subcc\t%r1, %2, %0"
3823 [(set_attr "type" "compare")])
3825 (define_insn "*cmp_minus_ccx_set"
3826 [(set (reg:CCX_NOOV 100)
3827 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3828 (match_operand:DI 2 "arith_operand" "rI"))
3830 (set (match_operand:DI 0 "register_operand" "=r")
3831 (minus:DI (match_dup 1) (match_dup 2)))]
3834 [(set_attr "type" "compare")])
3837 ;; Integer multiply/divide instructions.
3839 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3840 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3842 (define_insn "mulsi3"
3843 [(set (match_operand:SI 0 "register_operand" "=r")
3844 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3845 (match_operand:SI 2 "arith_operand" "rI")))]
3848 [(set_attr "type" "imul")])
3850 (define_expand "muldi3"
3851 [(set (match_operand:DI 0 "register_operand" "")
3852 (mult:DI (match_operand:DI 1 "arith_operand" "")
3853 (match_operand:DI 2 "arith_operand" "")))]
3854 "TARGET_ARCH64 || TARGET_V8PLUS"
3858 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3863 (define_insn "*muldi3_sp64"
3864 [(set (match_operand:DI 0 "register_operand" "=r")
3865 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3866 (match_operand:DI 2 "arith_operand" "rI")))]
3869 [(set_attr "type" "imul")])
3871 ;; V8plus wide multiply.
3873 (define_insn "muldi3_v8plus"
3874 [(set (match_operand:DI 0 "register_operand" "=r,h")
3875 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3876 (match_operand:DI 2 "arith_operand" "rI,rI")))
3877 (clobber (match_scratch:SI 3 "=&h,X"))
3878 (clobber (match_scratch:SI 4 "=&h,X"))]
3881 if (sparc_check_64 (operands[1], insn) <= 0)
3882 output_asm_insn ("srl\t%L1, 0, %L1", operands);
3883 if (which_alternative == 1)
3884 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3885 if (GET_CODE (operands[2]) == CONST_INT)
3887 if (which_alternative == 1)
3888 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
3890 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";
3892 else if (rtx_equal_p (operands[1], operands[2]))
3894 if (which_alternative == 1)
3895 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
3897 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";
3899 if (sparc_check_64 (operands[2], insn) <= 0)
3900 output_asm_insn ("srl\t%L2, 0, %L2", operands);
3901 if (which_alternative == 1)
3902 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";
3904 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";
3906 [(set_attr "type" "multi")
3907 (set_attr "length" "9,8")])
3909 (define_insn "*cmp_mul_set"
3911 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3912 (match_operand:SI 2 "arith_operand" "rI"))
3914 (set (match_operand:SI 0 "register_operand" "=r")
3915 (mult:SI (match_dup 1) (match_dup 2)))]
3916 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3917 "smulcc\t%1, %2, %0"
3918 [(set_attr "type" "imul")])
3920 (define_expand "mulsidi3"
3921 [(set (match_operand:DI 0 "register_operand" "")
3922 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3923 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3926 if (CONSTANT_P (operands[2]))
3929 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3931 else if (TARGET_ARCH32)
3932 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3935 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3941 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3946 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
3947 ;; registers can hold 64-bit values in the V8plus environment.
3949 (define_insn "mulsidi3_v8plus"
3950 [(set (match_operand:DI 0 "register_operand" "=h,r")
3951 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3952 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3953 (clobber (match_scratch:SI 3 "=X,&h"))]
3956 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3957 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3958 [(set_attr "type" "multi")
3959 (set_attr "length" "2,3")])
3962 (define_insn "const_mulsidi3_v8plus"
3963 [(set (match_operand:DI 0 "register_operand" "=h,r")
3964 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3965 (match_operand:DI 2 "small_int_operand" "I,I")))
3966 (clobber (match_scratch:SI 3 "=X,&h"))]
3969 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3970 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3971 [(set_attr "type" "multi")
3972 (set_attr "length" "2,3")])
3975 (define_insn "*mulsidi3_sp32"
3976 [(set (match_operand:DI 0 "register_operand" "=r")
3977 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3978 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3981 return TARGET_SPARCLET
3982 ? "smuld\t%1, %2, %L0"
3983 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3986 (if_then_else (eq_attr "isa" "sparclet")
3987 (const_string "imul") (const_string "multi")))
3988 (set (attr "length")
3989 (if_then_else (eq_attr "isa" "sparclet")
3990 (const_int 1) (const_int 2)))])
3992 (define_insn "*mulsidi3_sp64"
3993 [(set (match_operand:DI 0 "register_operand" "=r")
3994 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3995 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3996 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
3998 [(set_attr "type" "imul")])
4000 ;; Extra pattern, because sign_extend of a constant isn't valid.
4003 (define_insn "const_mulsidi3_sp32"
4004 [(set (match_operand:DI 0 "register_operand" "=r")
4005 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4006 (match_operand:DI 2 "small_int_operand" "I")))]
4009 return TARGET_SPARCLET
4010 ? "smuld\t%1, %2, %L0"
4011 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4014 (if_then_else (eq_attr "isa" "sparclet")
4015 (const_string "imul") (const_string "multi")))
4016 (set (attr "length")
4017 (if_then_else (eq_attr "isa" "sparclet")
4018 (const_int 1) (const_int 2)))])
4020 (define_insn "const_mulsidi3_sp64"
4021 [(set (match_operand:DI 0 "register_operand" "=r")
4022 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4023 (match_operand:DI 2 "small_int_operand" "I")))]
4024 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4026 [(set_attr "type" "imul")])
4028 (define_expand "smulsi3_highpart"
4029 [(set (match_operand:SI 0 "register_operand" "")
4031 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4032 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4034 "TARGET_HARD_MUL && TARGET_ARCH32"
4036 if (CONSTANT_P (operands[2]))
4040 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4046 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4051 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4052 operands[2], GEN_INT (32)));
4058 (define_insn "smulsi3_highpart_v8plus"
4059 [(set (match_operand:SI 0 "register_operand" "=h,r")
4061 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4062 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4063 (match_operand:SI 3 "small_int_operand" "I,I"))))
4064 (clobber (match_scratch:SI 4 "=X,&h"))]
4067 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4068 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4069 [(set_attr "type" "multi")
4070 (set_attr "length" "2")])
4072 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4075 [(set (match_operand:SI 0 "register_operand" "=h,r")
4078 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4079 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4080 (match_operand:SI 3 "small_int_operand" "I,I"))
4082 (clobber (match_scratch:SI 4 "=X,&h"))]
4085 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4086 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4087 [(set_attr "type" "multi")
4088 (set_attr "length" "2")])
4091 (define_insn "const_smulsi3_highpart_v8plus"
4092 [(set (match_operand:SI 0 "register_operand" "=h,r")
4094 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4095 (match_operand:DI 2 "small_int_operand" "I,I"))
4096 (match_operand:SI 3 "small_int_operand" "I,I"))))
4097 (clobber (match_scratch:SI 4 "=X,&h"))]
4100 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4101 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4102 [(set_attr "type" "multi")
4103 (set_attr "length" "2")])
4106 (define_insn "*smulsi3_highpart_sp32"
4107 [(set (match_operand:SI 0 "register_operand" "=r")
4109 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4110 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4113 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4114 [(set_attr "type" "multi")
4115 (set_attr "length" "2")])
4118 (define_insn "const_smulsi3_highpart"
4119 [(set (match_operand:SI 0 "register_operand" "=r")
4121 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4122 (match_operand:DI 2 "small_int_operand" "i"))
4125 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4126 [(set_attr "type" "multi")
4127 (set_attr "length" "2")])
4129 (define_expand "umulsidi3"
4130 [(set (match_operand:DI 0 "register_operand" "")
4131 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4132 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4135 if (CONSTANT_P (operands[2]))
4138 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4140 else if (TARGET_ARCH32)
4141 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4144 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4150 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4156 (define_insn "umulsidi3_v8plus"
4157 [(set (match_operand:DI 0 "register_operand" "=h,r")
4158 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4159 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4160 (clobber (match_scratch:SI 3 "=X,&h"))]
4163 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4164 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4165 [(set_attr "type" "multi")
4166 (set_attr "length" "2,3")])
4169 (define_insn "*umulsidi3_sp32"
4170 [(set (match_operand:DI 0 "register_operand" "=r")
4171 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4172 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4175 return TARGET_SPARCLET
4176 ? "umuld\t%1, %2, %L0"
4177 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4180 (if_then_else (eq_attr "isa" "sparclet")
4181 (const_string "imul") (const_string "multi")))
4182 (set (attr "length")
4183 (if_then_else (eq_attr "isa" "sparclet")
4184 (const_int 1) (const_int 2)))])
4186 (define_insn "*umulsidi3_sp64"
4187 [(set (match_operand:DI 0 "register_operand" "=r")
4188 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4189 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4190 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4192 [(set_attr "type" "imul")])
4194 ;; Extra pattern, because sign_extend of a constant isn't valid.
4197 (define_insn "const_umulsidi3_sp32"
4198 [(set (match_operand:DI 0 "register_operand" "=r")
4199 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4200 (match_operand:DI 2 "uns_small_int_operand" "")))]
4203 return TARGET_SPARCLET
4204 ? "umuld\t%1, %s2, %L0"
4205 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4208 (if_then_else (eq_attr "isa" "sparclet")
4209 (const_string "imul") (const_string "multi")))
4210 (set (attr "length")
4211 (if_then_else (eq_attr "isa" "sparclet")
4212 (const_int 1) (const_int 2)))])
4214 (define_insn "const_umulsidi3_sp64"
4215 [(set (match_operand:DI 0 "register_operand" "=r")
4216 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4217 (match_operand:DI 2 "uns_small_int_operand" "")))]
4218 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4220 [(set_attr "type" "imul")])
4223 (define_insn "const_umulsidi3_v8plus"
4224 [(set (match_operand:DI 0 "register_operand" "=h,r")
4225 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4226 (match_operand:DI 2 "uns_small_int_operand" "")))
4227 (clobber (match_scratch:SI 3 "=X,h"))]
4230 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4231 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4232 [(set_attr "type" "multi")
4233 (set_attr "length" "2,3")])
4235 (define_expand "umulsi3_highpart"
4236 [(set (match_operand:SI 0 "register_operand" "")
4238 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4239 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4241 "TARGET_HARD_MUL && TARGET_ARCH32"
4243 if (CONSTANT_P (operands[2]))
4247 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4253 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4258 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4259 operands[2], GEN_INT (32)));
4265 (define_insn "umulsi3_highpart_v8plus"
4266 [(set (match_operand:SI 0 "register_operand" "=h,r")
4268 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4269 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4270 (match_operand:SI 3 "small_int_operand" "I,I"))))
4271 (clobber (match_scratch:SI 4 "=X,h"))]
4274 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4275 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4276 [(set_attr "type" "multi")
4277 (set_attr "length" "2")])
4280 (define_insn "const_umulsi3_highpart_v8plus"
4281 [(set (match_operand:SI 0 "register_operand" "=h,r")
4283 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4284 (match_operand:DI 2 "uns_small_int_operand" ""))
4285 (match_operand:SI 3 "small_int_operand" "I,I"))))
4286 (clobber (match_scratch:SI 4 "=X,h"))]
4289 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4290 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4291 [(set_attr "type" "multi")
4292 (set_attr "length" "2")])
4295 (define_insn "*umulsi3_highpart_sp32"
4296 [(set (match_operand:SI 0 "register_operand" "=r")
4298 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4299 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4302 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4303 [(set_attr "type" "multi")
4304 (set_attr "length" "2")])
4307 (define_insn "const_umulsi3_highpart"
4308 [(set (match_operand:SI 0 "register_operand" "=r")
4310 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4311 (match_operand:DI 2 "uns_small_int_operand" ""))
4314 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4315 [(set_attr "type" "multi")
4316 (set_attr "length" "2")])
4318 (define_expand "divsi3"
4319 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4320 (div:SI (match_operand:SI 1 "register_operand" "")
4321 (match_operand:SI 2 "input_operand" "")))
4322 (clobber (match_scratch:SI 3 ""))])]
4323 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4327 operands[3] = gen_reg_rtx(SImode);
4328 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4329 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4335 ;; The V8 architecture specifies that there must be at least 3 instructions
4336 ;; between a write to the Y register and a use of it for correct results.
4337 ;; We try to fill one of them with a simple constant or a memory load.
4339 (define_insn "divsi3_sp32"
4340 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4341 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4342 (match_operand:SI 2 "input_operand" "rI,K,m")))
4343 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4344 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4346 output_asm_insn ("sra\t%1, 31, %3", operands);
4347 output_asm_insn ("wr\t%3, 0, %%y", operands);
4349 switch (which_alternative)
4353 return "sdiv\t%1, %2, %0";
4355 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4358 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4360 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4363 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4365 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4370 [(set_attr "type" "multi")
4371 (set (attr "length")
4372 (if_then_else (eq_attr "isa" "v9")
4373 (const_int 4) (const_int 6)))])
4375 (define_insn "divsi3_sp64"
4376 [(set (match_operand:SI 0 "register_operand" "=r")
4377 (div:SI (match_operand:SI 1 "register_operand" "r")
4378 (match_operand:SI 2 "input_operand" "rI")))
4379 (use (match_operand:SI 3 "register_operand" "r"))]
4380 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4381 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4382 [(set_attr "type" "multi")
4383 (set_attr "length" "2")])
4385 (define_insn "divdi3"
4386 [(set (match_operand:DI 0 "register_operand" "=r")
4387 (div:DI (match_operand:DI 1 "register_operand" "r")
4388 (match_operand:DI 2 "arith_operand" "rI")))]
4391 [(set_attr "type" "idiv")])
4393 (define_insn "*cmp_sdiv_cc_set"
4395 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4396 (match_operand:SI 2 "arith_operand" "rI"))
4398 (set (match_operand:SI 0 "register_operand" "=r")
4399 (div:SI (match_dup 1) (match_dup 2)))
4400 (clobber (match_scratch:SI 3 "=&r"))]
4401 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4403 output_asm_insn ("sra\t%1, 31, %3", operands);
4404 output_asm_insn ("wr\t%3, 0, %%y", operands);
4407 return "sdivcc\t%1, %2, %0";
4409 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4411 [(set_attr "type" "multi")
4412 (set (attr "length")
4413 (if_then_else (eq_attr "isa" "v9")
4414 (const_int 3) (const_int 6)))])
4417 (define_expand "udivsi3"
4418 [(set (match_operand:SI 0 "register_operand" "")
4419 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4420 (match_operand:SI 2 "input_operand" "")))]
4421 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4424 ;; The V8 architecture specifies that there must be at least 3 instructions
4425 ;; between a write to the Y register and a use of it for correct results.
4426 ;; We try to fill one of them with a simple constant or a memory load.
4428 (define_insn "udivsi3_sp32"
4429 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4430 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4431 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4432 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4434 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4436 switch (which_alternative)
4440 return "udiv\t%1, %2, %0";
4442 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4445 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4447 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4450 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4452 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4455 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4457 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4462 [(set_attr "type" "multi")
4463 (set (attr "length")
4464 (if_then_else (eq_attr "isa" "v9")
4465 (const_int 3) (const_int 5)))])
4467 (define_insn "udivsi3_sp64"
4468 [(set (match_operand:SI 0 "register_operand" "=r")
4469 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4470 (match_operand:SI 2 "input_operand" "rI")))]
4471 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4472 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4473 [(set_attr "type" "multi")
4474 (set_attr "length" "2")])
4476 (define_insn "udivdi3"
4477 [(set (match_operand:DI 0 "register_operand" "=r")
4478 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4479 (match_operand:DI 2 "arith_operand" "rI")))]
4482 [(set_attr "type" "idiv")])
4484 (define_insn "*cmp_udiv_cc_set"
4486 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4487 (match_operand:SI 2 "arith_operand" "rI"))
4489 (set (match_operand:SI 0 "register_operand" "=r")
4490 (udiv:SI (match_dup 1) (match_dup 2)))]
4491 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4493 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4496 return "udivcc\t%1, %2, %0";
4498 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4500 [(set_attr "type" "multi")
4501 (set (attr "length")
4502 (if_then_else (eq_attr "isa" "v9")
4503 (const_int 2) (const_int 5)))])
4505 ; sparclet multiply/accumulate insns
4507 (define_insn "*smacsi"
4508 [(set (match_operand:SI 0 "register_operand" "=r")
4509 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4510 (match_operand:SI 2 "arith_operand" "rI"))
4511 (match_operand:SI 3 "register_operand" "0")))]
4514 [(set_attr "type" "imul")])
4516 (define_insn "*smacdi"
4517 [(set (match_operand:DI 0 "register_operand" "=r")
4518 (plus:DI (mult:DI (sign_extend:DI
4519 (match_operand:SI 1 "register_operand" "%r"))
4521 (match_operand:SI 2 "register_operand" "r")))
4522 (match_operand:DI 3 "register_operand" "0")))]
4524 "smacd\t%1, %2, %L0"
4525 [(set_attr "type" "imul")])
4527 (define_insn "*umacdi"
4528 [(set (match_operand:DI 0 "register_operand" "=r")
4529 (plus:DI (mult:DI (zero_extend:DI
4530 (match_operand:SI 1 "register_operand" "%r"))
4532 (match_operand:SI 2 "register_operand" "r")))
4533 (match_operand:DI 3 "register_operand" "0")))]
4535 "umacd\t%1, %2, %L0"
4536 [(set_attr "type" "imul")])
4539 ;; Boolean instructions.
4541 ;; We define DImode `and' so with DImode `not' we can get
4542 ;; DImode `andn'. Other combinations are possible.
4544 (define_expand "and<V64I:mode>3"
4545 [(set (match_operand:V64I 0 "register_operand" "")
4546 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4547 (match_operand:V64I 2 "arith_double_operand" "")))]
4551 (define_insn "*and<V64I:mode>3_sp32"
4552 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4553 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4554 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4559 [(set_attr "type" "*,fga")
4560 (set_attr "length" "2,*")
4561 (set_attr "fptype" "*,double")])
4563 (define_insn "*and<V64I:mode>3_sp64"
4564 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4565 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4566 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4571 [(set_attr "type" "*,fga")
4572 (set_attr "fptype" "*,double")])
4574 (define_insn "and<V32I:mode>3"
4575 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4576 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4577 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4582 [(set_attr "type" "*,fga")
4583 (set_attr "fptype" "*,single")])
4586 [(set (match_operand:SI 0 "register_operand" "")
4587 (and:SI (match_operand:SI 1 "register_operand" "")
4588 (match_operand:SI 2 "const_compl_high_operand" "")))
4589 (clobber (match_operand:SI 3 "register_operand" ""))]
4591 [(set (match_dup 3) (match_dup 4))
4592 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4594 operands[4] = GEN_INT (~INTVAL (operands[2]));
4597 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4598 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4599 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4600 (match_operand:V64I 2 "register_operand" "r,b")))]
4604 fandnot1\t%1, %2, %0"
4605 "&& reload_completed
4606 && ((GET_CODE (operands[0]) == REG
4607 && REGNO (operands[0]) < 32)
4608 || (GET_CODE (operands[0]) == SUBREG
4609 && GET_CODE (SUBREG_REG (operands[0])) == REG
4610 && REGNO (SUBREG_REG (operands[0])) < 32))"
4611 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4612 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4613 "operands[3] = gen_highpart (SImode, operands[0]);
4614 operands[4] = gen_highpart (SImode, operands[1]);
4615 operands[5] = gen_highpart (SImode, operands[2]);
4616 operands[6] = gen_lowpart (SImode, operands[0]);
4617 operands[7] = gen_lowpart (SImode, operands[1]);
4618 operands[8] = gen_lowpart (SImode, operands[2]);"
4619 [(set_attr "type" "*,fga")
4620 (set_attr "length" "2,*")
4621 (set_attr "fptype" "*,double")])
4623 (define_insn "*and_not_<V64I:mode>_sp64"
4624 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4625 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4626 (match_operand:V64I 2 "register_operand" "r,b")))]
4630 fandnot1\t%1, %2, %0"
4631 [(set_attr "type" "*,fga")
4632 (set_attr "fptype" "*,double")])
4634 (define_insn "*and_not_<V32I:mode>"
4635 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4636 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4637 (match_operand:V32I 2 "register_operand" "r,d")))]
4641 fandnot1s\t%1, %2, %0"
4642 [(set_attr "type" "*,fga")
4643 (set_attr "fptype" "*,single")])
4645 (define_expand "ior<V64I:mode>3"
4646 [(set (match_operand:V64I 0 "register_operand" "")
4647 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4648 (match_operand:V64I 2 "arith_double_operand" "")))]
4652 (define_insn "*ior<V64I:mode>3_sp32"
4653 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4654 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4655 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4660 [(set_attr "type" "*,fga")
4661 (set_attr "length" "2,*")
4662 (set_attr "fptype" "*,double")])
4664 (define_insn "*ior<V64I:mode>3_sp64"
4665 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4666 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4667 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4672 [(set_attr "type" "*,fga")
4673 (set_attr "fptype" "*,double")])
4675 (define_insn "ior<V32I:mode>3"
4676 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4677 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4678 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4683 [(set_attr "type" "*,fga")
4684 (set_attr "fptype" "*,single")])
4687 [(set (match_operand:SI 0 "register_operand" "")
4688 (ior:SI (match_operand:SI 1 "register_operand" "")
4689 (match_operand:SI 2 "const_compl_high_operand" "")))
4690 (clobber (match_operand:SI 3 "register_operand" ""))]
4692 [(set (match_dup 3) (match_dup 4))
4693 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4695 operands[4] = GEN_INT (~INTVAL (operands[2]));
4698 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4699 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4700 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4701 (match_operand:V64I 2 "register_operand" "r,b")))]
4705 fornot1\t%1, %2, %0"
4706 "&& reload_completed
4707 && ((GET_CODE (operands[0]) == REG
4708 && REGNO (operands[0]) < 32)
4709 || (GET_CODE (operands[0]) == SUBREG
4710 && GET_CODE (SUBREG_REG (operands[0])) == REG
4711 && REGNO (SUBREG_REG (operands[0])) < 32))"
4712 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4713 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4714 "operands[3] = gen_highpart (SImode, operands[0]);
4715 operands[4] = gen_highpart (SImode, operands[1]);
4716 operands[5] = gen_highpart (SImode, operands[2]);
4717 operands[6] = gen_lowpart (SImode, operands[0]);
4718 operands[7] = gen_lowpart (SImode, operands[1]);
4719 operands[8] = gen_lowpart (SImode, operands[2]);"
4720 [(set_attr "type" "*,fga")
4721 (set_attr "length" "2,*")
4722 (set_attr "fptype" "*,double")])
4724 (define_insn "*or_not_<V64I:mode>_sp64"
4725 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4726 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4727 (match_operand:V64I 2 "register_operand" "r,b")))]
4731 fornot1\t%1, %2, %0"
4732 [(set_attr "type" "*,fga")
4733 (set_attr "fptype" "*,double")])
4735 (define_insn "*or_not_<V32I:mode>"
4736 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4737 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4738 (match_operand:V32I 2 "register_operand" "r,d")))]
4742 fornot1s\t%1, %2, %0"
4743 [(set_attr "type" "*,fga")
4744 (set_attr "fptype" "*,single")])
4746 (define_expand "xor<V64I:mode>3"
4747 [(set (match_operand:V64I 0 "register_operand" "")
4748 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4749 (match_operand:V64I 2 "arith_double_operand" "")))]
4753 (define_insn "*xor<V64I:mode>3_sp32"
4754 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4755 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4756 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4761 [(set_attr "type" "*,fga")
4762 (set_attr "length" "2,*")
4763 (set_attr "fptype" "*,double")])
4765 (define_insn "*xor<V64I:mode>3_sp64"
4766 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4767 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4768 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4773 [(set_attr "type" "*,fga")
4774 (set_attr "fptype" "*,double")])
4776 (define_insn "xor<V32I:mode>3"
4777 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4778 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4779 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4784 [(set_attr "type" "*,fga")
4785 (set_attr "fptype" "*,single")])
4788 [(set (match_operand:SI 0 "register_operand" "")
4789 (xor:SI (match_operand:SI 1 "register_operand" "")
4790 (match_operand:SI 2 "const_compl_high_operand" "")))
4791 (clobber (match_operand:SI 3 "register_operand" ""))]
4793 [(set (match_dup 3) (match_dup 4))
4794 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4796 operands[4] = GEN_INT (~INTVAL (operands[2]));
4800 [(set (match_operand:SI 0 "register_operand" "")
4801 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4802 (match_operand:SI 2 "const_compl_high_operand" ""))))
4803 (clobber (match_operand:SI 3 "register_operand" ""))]
4805 [(set (match_dup 3) (match_dup 4))
4806 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4808 operands[4] = GEN_INT (~INTVAL (operands[2]));
4811 ;; Split DImode logical operations requiring two instructions.
4813 [(set (match_operand:V64I 0 "register_operand" "")
4814 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4815 [(match_operand:V64I 2 "register_operand" "")
4816 (match_operand:V64I 3 "arith_double_operand" "")]))]
4819 && ((GET_CODE (operands[0]) == REG
4820 && REGNO (operands[0]) < 32)
4821 || (GET_CODE (operands[0]) == SUBREG
4822 && GET_CODE (SUBREG_REG (operands[0])) == REG
4823 && REGNO (SUBREG_REG (operands[0])) < 32))"
4824 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4825 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4827 operands[4] = gen_highpart (SImode, operands[0]);
4828 operands[5] = gen_lowpart (SImode, operands[0]);
4829 operands[6] = gen_highpart (SImode, operands[2]);
4830 operands[7] = gen_lowpart (SImode, operands[2]);
4831 #if HOST_BITS_PER_WIDE_INT == 32
4832 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4834 if (INTVAL (operands[3]) < 0)
4835 operands[8] = constm1_rtx;
4837 operands[8] = const0_rtx;
4841 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4842 operands[9] = gen_lowpart (SImode, operands[3]);
4845 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4846 ;; Combine now canonicalizes to the rightmost expression.
4847 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4848 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4849 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4850 (match_operand:V64I 2 "register_operand" "r,b"))))]
4855 "&& reload_completed
4856 && ((GET_CODE (operands[0]) == REG
4857 && REGNO (operands[0]) < 32)
4858 || (GET_CODE (operands[0]) == SUBREG
4859 && GET_CODE (SUBREG_REG (operands[0])) == REG
4860 && REGNO (SUBREG_REG (operands[0])) < 32))"
4861 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4862 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4863 "operands[3] = gen_highpart (SImode, operands[0]);
4864 operands[4] = gen_highpart (SImode, operands[1]);
4865 operands[5] = gen_highpart (SImode, operands[2]);
4866 operands[6] = gen_lowpart (SImode, operands[0]);
4867 operands[7] = gen_lowpart (SImode, operands[1]);
4868 operands[8] = gen_lowpart (SImode, operands[2]);"
4869 [(set_attr "type" "*,fga")
4870 (set_attr "length" "2,*")
4871 (set_attr "fptype" "*,double")])
4873 (define_insn "*xor_not_<V64I:mode>_sp64"
4874 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4875 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4876 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4881 [(set_attr "type" "*,fga")
4882 (set_attr "fptype" "*,double")])
4884 (define_insn "*xor_not_<V32I:mode>"
4885 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4886 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
4887 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
4892 [(set_attr "type" "*,fga")
4893 (set_attr "fptype" "*,single")])
4895 ;; These correspond to the above in the case where we also (or only)
4896 ;; want to set the condition code.
4898 (define_insn "*cmp_cc_arith_op"
4901 (match_operator:SI 2 "cc_arith_operator"
4902 [(match_operand:SI 0 "arith_operand" "%r")
4903 (match_operand:SI 1 "arith_operand" "rI")])
4906 "%A2cc\t%0, %1, %%g0"
4907 [(set_attr "type" "compare")])
4909 (define_insn "*cmp_ccx_arith_op"
4912 (match_operator:DI 2 "cc_arith_operator"
4913 [(match_operand:DI 0 "arith_operand" "%r")
4914 (match_operand:DI 1 "arith_operand" "rI")])
4917 "%A2cc\t%0, %1, %%g0"
4918 [(set_attr "type" "compare")])
4920 (define_insn "*cmp_cc_arith_op_set"
4923 (match_operator:SI 3 "cc_arith_operator"
4924 [(match_operand:SI 1 "arith_operand" "%r")
4925 (match_operand:SI 2 "arith_operand" "rI")])
4927 (set (match_operand:SI 0 "register_operand" "=r")
4928 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4929 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4931 [(set_attr "type" "compare")])
4933 (define_insn "*cmp_ccx_arith_op_set"
4936 (match_operator:DI 3 "cc_arith_operator"
4937 [(match_operand:DI 1 "arith_operand" "%r")
4938 (match_operand:DI 2 "arith_operand" "rI")])
4940 (set (match_operand:DI 0 "register_operand" "=r")
4941 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4942 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4944 [(set_attr "type" "compare")])
4946 (define_insn "*cmp_cc_xor_not"
4949 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4950 (match_operand:SI 1 "arith_operand" "rI")))
4953 "xnorcc\t%r0, %1, %%g0"
4954 [(set_attr "type" "compare")])
4956 (define_insn "*cmp_ccx_xor_not"
4959 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4960 (match_operand:DI 1 "arith_operand" "rI")))
4963 "xnorcc\t%r0, %1, %%g0"
4964 [(set_attr "type" "compare")])
4966 (define_insn "*cmp_cc_xor_not_set"
4969 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4970 (match_operand:SI 2 "arith_operand" "rI")))
4972 (set (match_operand:SI 0 "register_operand" "=r")
4973 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4975 "xnorcc\t%r1, %2, %0"
4976 [(set_attr "type" "compare")])
4978 (define_insn "*cmp_ccx_xor_not_set"
4981 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4982 (match_operand:DI 2 "arith_operand" "rI")))
4984 (set (match_operand:DI 0 "register_operand" "=r")
4985 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4987 "xnorcc\t%r1, %2, %0"
4988 [(set_attr "type" "compare")])
4990 (define_insn "*cmp_cc_arith_op_not"
4993 (match_operator:SI 2 "cc_arith_not_operator"
4994 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4995 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
4998 "%B2cc\t%r1, %0, %%g0"
4999 [(set_attr "type" "compare")])
5001 (define_insn "*cmp_ccx_arith_op_not"
5004 (match_operator:DI 2 "cc_arith_not_operator"
5005 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5006 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5009 "%B2cc\t%r1, %0, %%g0"
5010 [(set_attr "type" "compare")])
5012 (define_insn "*cmp_cc_arith_op_not_set"
5015 (match_operator:SI 3 "cc_arith_not_operator"
5016 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5017 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5019 (set (match_operand:SI 0 "register_operand" "=r")
5020 (match_operator:SI 4 "cc_arith_not_operator"
5021 [(not:SI (match_dup 1)) (match_dup 2)]))]
5022 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5023 "%B3cc\t%r2, %1, %0"
5024 [(set_attr "type" "compare")])
5026 (define_insn "*cmp_ccx_arith_op_not_set"
5029 (match_operator:DI 3 "cc_arith_not_operator"
5030 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5031 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5033 (set (match_operand:DI 0 "register_operand" "=r")
5034 (match_operator:DI 4 "cc_arith_not_operator"
5035 [(not:DI (match_dup 1)) (match_dup 2)]))]
5036 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5037 "%B3cc\t%r2, %1, %0"
5038 [(set_attr "type" "compare")])
5040 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5041 ;; does not know how to make it work for constants.
5043 (define_expand "negdi2"
5044 [(set (match_operand:DI 0 "register_operand" "=r")
5045 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5048 if (! TARGET_ARCH64)
5050 emit_insn (gen_rtx_PARALLEL
5053 gen_rtx_SET (VOIDmode, operand0,
5054 gen_rtx_NEG (DImode, operand1)),
5055 gen_rtx_CLOBBER (VOIDmode,
5056 gen_rtx_REG (CCmode,
5062 (define_insn_and_split "*negdi2_sp32"
5063 [(set (match_operand:DI 0 "register_operand" "=r")
5064 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5065 (clobber (reg:CC 100))]
5068 "&& reload_completed"
5069 [(parallel [(set (reg:CC_NOOV 100)
5070 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5072 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5073 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5074 (ltu:SI (reg:CC 100) (const_int 0))))]
5075 "operands[2] = gen_highpart (SImode, operands[0]);
5076 operands[3] = gen_highpart (SImode, operands[1]);
5077 operands[4] = gen_lowpart (SImode, operands[0]);
5078 operands[5] = gen_lowpart (SImode, operands[1]);"
5079 [(set_attr "length" "2")])
5081 (define_insn "*negdi2_sp64"
5082 [(set (match_operand:DI 0 "register_operand" "=r")
5083 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5085 "sub\t%%g0, %1, %0")
5087 (define_insn "negsi2"
5088 [(set (match_operand:SI 0 "register_operand" "=r")
5089 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5091 "sub\t%%g0, %1, %0")
5093 (define_insn "*cmp_cc_neg"
5094 [(set (reg:CC_NOOV 100)
5095 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5098 "subcc\t%%g0, %0, %%g0"
5099 [(set_attr "type" "compare")])
5101 (define_insn "*cmp_ccx_neg"
5102 [(set (reg:CCX_NOOV 100)
5103 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5106 "subcc\t%%g0, %0, %%g0"
5107 [(set_attr "type" "compare")])
5109 (define_insn "*cmp_cc_set_neg"
5110 [(set (reg:CC_NOOV 100)
5111 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5113 (set (match_operand:SI 0 "register_operand" "=r")
5114 (neg:SI (match_dup 1)))]
5116 "subcc\t%%g0, %1, %0"
5117 [(set_attr "type" "compare")])
5119 (define_insn "*cmp_ccx_set_neg"
5120 [(set (reg:CCX_NOOV 100)
5121 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5123 (set (match_operand:DI 0 "register_operand" "=r")
5124 (neg:DI (match_dup 1)))]
5126 "subcc\t%%g0, %1, %0"
5127 [(set_attr "type" "compare")])
5129 ;; We cannot use the "not" pseudo insn because the Sun assembler
5130 ;; does not know how to make it work for constants.
5131 (define_expand "one_cmpl<V64I:mode>2"
5132 [(set (match_operand:V64I 0 "register_operand" "")
5133 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5137 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5138 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5139 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5144 "&& reload_completed
5145 && ((GET_CODE (operands[0]) == REG
5146 && REGNO (operands[0]) < 32)
5147 || (GET_CODE (operands[0]) == SUBREG
5148 && GET_CODE (SUBREG_REG (operands[0])) == REG
5149 && REGNO (SUBREG_REG (operands[0])) < 32))"
5150 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5151 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5152 "operands[2] = gen_highpart (SImode, operands[0]);
5153 operands[3] = gen_highpart (SImode, operands[1]);
5154 operands[4] = gen_lowpart (SImode, operands[0]);
5155 operands[5] = gen_lowpart (SImode, operands[1]);"
5156 [(set_attr "type" "*,fga")
5157 (set_attr "length" "2,*")
5158 (set_attr "fptype" "*,double")])
5160 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5161 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5162 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5167 [(set_attr "type" "*,fga")
5168 (set_attr "fptype" "*,double")])
5170 (define_insn "one_cmpl<V32I:mode>2"
5171 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5172 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5177 [(set_attr "type" "*,fga")
5178 (set_attr "fptype" "*,single")])
5180 (define_insn "*cmp_cc_not"
5182 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5185 "xnorcc\t%%g0, %0, %%g0"
5186 [(set_attr "type" "compare")])
5188 (define_insn "*cmp_ccx_not"
5190 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5193 "xnorcc\t%%g0, %0, %%g0"
5194 [(set_attr "type" "compare")])
5196 (define_insn "*cmp_cc_set_not"
5198 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5200 (set (match_operand:SI 0 "register_operand" "=r")
5201 (not:SI (match_dup 1)))]
5203 "xnorcc\t%%g0, %1, %0"
5204 [(set_attr "type" "compare")])
5206 (define_insn "*cmp_ccx_set_not"
5208 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5210 (set (match_operand:DI 0 "register_operand" "=r")
5211 (not:DI (match_dup 1)))]
5213 "xnorcc\t%%g0, %1, %0"
5214 [(set_attr "type" "compare")])
5216 (define_insn "*cmp_cc_set"
5217 [(set (match_operand:SI 0 "register_operand" "=r")
5218 (match_operand:SI 1 "register_operand" "r"))
5220 (compare:CC (match_dup 1)
5224 [(set_attr "type" "compare")])
5226 (define_insn "*cmp_ccx_set64"
5227 [(set (match_operand:DI 0 "register_operand" "=r")
5228 (match_operand:DI 1 "register_operand" "r"))
5230 (compare:CCX (match_dup 1)
5234 [(set_attr "type" "compare")])
5237 ;; Floating point arithmetic instructions.
5239 (define_expand "addtf3"
5240 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5241 (plus:TF (match_operand:TF 1 "general_operand" "")
5242 (match_operand:TF 2 "general_operand" "")))]
5243 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5244 "emit_tfmode_binop (PLUS, operands); DONE;")
5246 (define_insn "*addtf3_hq"
5247 [(set (match_operand:TF 0 "register_operand" "=e")
5248 (plus:TF (match_operand:TF 1 "register_operand" "e")
5249 (match_operand:TF 2 "register_operand" "e")))]
5250 "TARGET_FPU && TARGET_HARD_QUAD"
5252 [(set_attr "type" "fp")])
5254 (define_insn "adddf3"
5255 [(set (match_operand:DF 0 "register_operand" "=e")
5256 (plus:DF (match_operand:DF 1 "register_operand" "e")
5257 (match_operand:DF 2 "register_operand" "e")))]
5260 [(set_attr "type" "fp")
5261 (set_attr "fptype" "double")])
5263 (define_insn "addsf3"
5264 [(set (match_operand:SF 0 "register_operand" "=f")
5265 (plus:SF (match_operand:SF 1 "register_operand" "f")
5266 (match_operand:SF 2 "register_operand" "f")))]
5269 [(set_attr "type" "fp")])
5271 (define_expand "subtf3"
5272 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5273 (minus:TF (match_operand:TF 1 "general_operand" "")
5274 (match_operand:TF 2 "general_operand" "")))]
5275 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5276 "emit_tfmode_binop (MINUS, operands); DONE;")
5278 (define_insn "*subtf3_hq"
5279 [(set (match_operand:TF 0 "register_operand" "=e")
5280 (minus:TF (match_operand:TF 1 "register_operand" "e")
5281 (match_operand:TF 2 "register_operand" "e")))]
5282 "TARGET_FPU && TARGET_HARD_QUAD"
5284 [(set_attr "type" "fp")])
5286 (define_insn "subdf3"
5287 [(set (match_operand:DF 0 "register_operand" "=e")
5288 (minus:DF (match_operand:DF 1 "register_operand" "e")
5289 (match_operand:DF 2 "register_operand" "e")))]
5292 [(set_attr "type" "fp")
5293 (set_attr "fptype" "double")])
5295 (define_insn "subsf3"
5296 [(set (match_operand:SF 0 "register_operand" "=f")
5297 (minus:SF (match_operand:SF 1 "register_operand" "f")
5298 (match_operand:SF 2 "register_operand" "f")))]
5301 [(set_attr "type" "fp")])
5303 (define_expand "multf3"
5304 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5305 (mult:TF (match_operand:TF 1 "general_operand" "")
5306 (match_operand:TF 2 "general_operand" "")))]
5307 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5308 "emit_tfmode_binop (MULT, operands); DONE;")
5310 (define_insn "*multf3_hq"
5311 [(set (match_operand:TF 0 "register_operand" "=e")
5312 (mult:TF (match_operand:TF 1 "register_operand" "e")
5313 (match_operand:TF 2 "register_operand" "e")))]
5314 "TARGET_FPU && TARGET_HARD_QUAD"
5316 [(set_attr "type" "fpmul")])
5318 (define_insn "muldf3"
5319 [(set (match_operand:DF 0 "register_operand" "=e")
5320 (mult:DF (match_operand:DF 1 "register_operand" "e")
5321 (match_operand:DF 2 "register_operand" "e")))]
5324 [(set_attr "type" "fpmul")
5325 (set_attr "fptype" "double")])
5327 (define_insn "mulsf3"
5328 [(set (match_operand:SF 0 "register_operand" "=f")
5329 (mult:SF (match_operand:SF 1 "register_operand" "f")
5330 (match_operand:SF 2 "register_operand" "f")))]
5333 [(set_attr "type" "fpmul")])
5335 (define_insn "*muldf3_extend"
5336 [(set (match_operand:DF 0 "register_operand" "=e")
5337 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5338 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5339 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5340 "fsmuld\t%1, %2, %0"
5341 [(set_attr "type" "fpmul")
5342 (set_attr "fptype" "double")])
5344 (define_insn "*multf3_extend"
5345 [(set (match_operand:TF 0 "register_operand" "=e")
5346 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5347 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5348 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5349 "fdmulq\t%1, %2, %0"
5350 [(set_attr "type" "fpmul")])
5352 (define_expand "divtf3"
5353 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5354 (div:TF (match_operand:TF 1 "general_operand" "")
5355 (match_operand:TF 2 "general_operand" "")))]
5356 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5357 "emit_tfmode_binop (DIV, operands); DONE;")
5359 ;; don't have timing for quad-prec. divide.
5360 (define_insn "*divtf3_hq"
5361 [(set (match_operand:TF 0 "register_operand" "=e")
5362 (div:TF (match_operand:TF 1 "register_operand" "e")
5363 (match_operand:TF 2 "register_operand" "e")))]
5364 "TARGET_FPU && TARGET_HARD_QUAD"
5366 [(set_attr "type" "fpdivd")])
5368 (define_insn "divdf3"
5369 [(set (match_operand:DF 0 "register_operand" "=e")
5370 (div:DF (match_operand:DF 1 "register_operand" "e")
5371 (match_operand:DF 2 "register_operand" "e")))]
5374 [(set_attr "type" "fpdivd")
5375 (set_attr "fptype" "double")])
5377 (define_insn "divsf3"
5378 [(set (match_operand:SF 0 "register_operand" "=f")
5379 (div:SF (match_operand:SF 1 "register_operand" "f")
5380 (match_operand:SF 2 "register_operand" "f")))]
5383 [(set_attr "type" "fpdivs")])
5385 (define_expand "negtf2"
5386 [(set (match_operand:TF 0 "register_operand" "=e,e")
5387 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5391 (define_insn_and_split "*negtf2_notv9"
5392 [(set (match_operand:TF 0 "register_operand" "=e,e")
5393 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5394 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5400 "&& reload_completed
5401 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5402 [(set (match_dup 2) (neg:SF (match_dup 3)))
5403 (set (match_dup 4) (match_dup 5))
5404 (set (match_dup 6) (match_dup 7))]
5405 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5406 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5407 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5408 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5409 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5410 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5411 [(set_attr "type" "fpmove,*")
5412 (set_attr "length" "*,2")])
5414 (define_insn_and_split "*negtf2_v9"
5415 [(set (match_operand:TF 0 "register_operand" "=e,e")
5416 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5417 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5418 "TARGET_FPU && TARGET_V9"
5422 "&& reload_completed
5423 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5424 [(set (match_dup 2) (neg:DF (match_dup 3)))
5425 (set (match_dup 4) (match_dup 5))]
5426 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5427 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5428 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5429 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5430 [(set_attr "type" "fpmove,*")
5431 (set_attr "length" "*,2")
5432 (set_attr "fptype" "double")])
5434 (define_expand "negdf2"
5435 [(set (match_operand:DF 0 "register_operand" "")
5436 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5440 (define_insn_and_split "*negdf2_notv9"
5441 [(set (match_operand:DF 0 "register_operand" "=e,e")
5442 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5443 "TARGET_FPU && ! TARGET_V9"
5447 "&& reload_completed
5448 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5449 [(set (match_dup 2) (neg:SF (match_dup 3)))
5450 (set (match_dup 4) (match_dup 5))]
5451 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5452 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5453 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5454 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5455 [(set_attr "type" "fpmove,*")
5456 (set_attr "length" "*,2")])
5458 (define_insn "*negdf2_v9"
5459 [(set (match_operand:DF 0 "register_operand" "=e")
5460 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5461 "TARGET_FPU && TARGET_V9"
5463 [(set_attr "type" "fpmove")
5464 (set_attr "fptype" "double")])
5466 (define_insn "negsf2"
5467 [(set (match_operand:SF 0 "register_operand" "=f")
5468 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5471 [(set_attr "type" "fpmove")])
5473 (define_expand "abstf2"
5474 [(set (match_operand:TF 0 "register_operand" "")
5475 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5479 (define_insn_and_split "*abstf2_notv9"
5480 [(set (match_operand:TF 0 "register_operand" "=e,e")
5481 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5482 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5483 "TARGET_FPU && ! TARGET_V9"
5487 "&& reload_completed
5488 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5489 [(set (match_dup 2) (abs:SF (match_dup 3)))
5490 (set (match_dup 4) (match_dup 5))
5491 (set (match_dup 6) (match_dup 7))]
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 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5497 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5498 [(set_attr "type" "fpmove,*")
5499 (set_attr "length" "*,2")])
5501 (define_insn "*abstf2_hq_v9"
5502 [(set (match_operand:TF 0 "register_operand" "=e,e")
5503 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5504 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5508 [(set_attr "type" "fpmove")
5509 (set_attr "fptype" "double,*")])
5511 (define_insn_and_split "*abstf2_v9"
5512 [(set (match_operand:TF 0 "register_operand" "=e,e")
5513 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5514 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5518 "&& reload_completed
5519 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5520 [(set (match_dup 2) (abs:DF (match_dup 3)))
5521 (set (match_dup 4) (match_dup 5))]
5522 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5523 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5524 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5525 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5526 [(set_attr "type" "fpmove,*")
5527 (set_attr "length" "*,2")
5528 (set_attr "fptype" "double,*")])
5530 (define_expand "absdf2"
5531 [(set (match_operand:DF 0 "register_operand" "")
5532 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5536 (define_insn_and_split "*absdf2_notv9"
5537 [(set (match_operand:DF 0 "register_operand" "=e,e")
5538 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5539 "TARGET_FPU && ! TARGET_V9"
5543 "&& reload_completed
5544 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5545 [(set (match_dup 2) (abs:SF (match_dup 3)))
5546 (set (match_dup 4) (match_dup 5))]
5547 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5548 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5549 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5550 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5551 [(set_attr "type" "fpmove,*")
5552 (set_attr "length" "*,2")])
5554 (define_insn "*absdf2_v9"
5555 [(set (match_operand:DF 0 "register_operand" "=e")
5556 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5557 "TARGET_FPU && TARGET_V9"
5559 [(set_attr "type" "fpmove")
5560 (set_attr "fptype" "double")])
5562 (define_insn "abssf2"
5563 [(set (match_operand:SF 0 "register_operand" "=f")
5564 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5567 [(set_attr "type" "fpmove")])
5569 (define_expand "sqrttf2"
5570 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5571 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5572 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5573 "emit_tfmode_unop (SQRT, operands); DONE;")
5575 (define_insn "*sqrttf2_hq"
5576 [(set (match_operand:TF 0 "register_operand" "=e")
5577 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5578 "TARGET_FPU && TARGET_HARD_QUAD"
5580 [(set_attr "type" "fpsqrtd")])
5582 (define_insn "sqrtdf2"
5583 [(set (match_operand:DF 0 "register_operand" "=e")
5584 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5587 [(set_attr "type" "fpsqrtd")
5588 (set_attr "fptype" "double")])
5590 (define_insn "sqrtsf2"
5591 [(set (match_operand:SF 0 "register_operand" "=f")
5592 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5595 [(set_attr "type" "fpsqrts")])
5598 ;; Arithmetic shift instructions.
5600 (define_insn "ashlsi3"
5601 [(set (match_operand:SI 0 "register_operand" "=r")
5602 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5603 (match_operand:SI 2 "arith_operand" "rI")))]
5606 if (GET_CODE (operands[2]) == CONST_INT)
5607 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5608 return "sll\t%1, %2, %0";
5611 (if_then_else (match_operand 2 "const_one_operand" "")
5612 (const_string "ialu") (const_string "shift")))])
5614 (define_expand "ashldi3"
5615 [(set (match_operand:DI 0 "register_operand" "=r")
5616 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5617 (match_operand:SI 2 "arith_operand" "rI")))]
5618 "TARGET_ARCH64 || TARGET_V8PLUS"
5620 if (! TARGET_ARCH64)
5622 if (GET_CODE (operands[2]) == CONST_INT)
5624 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5629 (define_insn "*ashldi3_sp64"
5630 [(set (match_operand:DI 0 "register_operand" "=r")
5631 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5632 (match_operand:SI 2 "arith_operand" "rI")))]
5635 if (GET_CODE (operands[2]) == CONST_INT)
5636 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5637 return "sllx\t%1, %2, %0";
5640 (if_then_else (match_operand 2 "const_one_operand" "")
5641 (const_string "ialu") (const_string "shift")))])
5644 (define_insn "ashldi3_v8plus"
5645 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5646 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5647 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5648 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5650 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5651 [(set_attr "type" "multi")
5652 (set_attr "length" "5,5,6")])
5654 ;; Optimize (1LL<<x)-1
5655 ;; XXX this also needs to be fixed to handle equal subregs
5656 ;; XXX first before we could re-enable it.
5658 ; [(set (match_operand:DI 0 "register_operand" "=h")
5659 ; (plus:DI (ashift:DI (const_int 1)
5660 ; (match_operand:SI 1 "arith_operand" "rI"))
5662 ; "0 && TARGET_V8PLUS"
5664 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5665 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5666 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5668 ; [(set_attr "type" "multi")
5669 ; (set_attr "length" "4")])
5671 (define_insn "*cmp_cc_ashift_1"
5672 [(set (reg:CC_NOOV 100)
5673 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5677 "addcc\t%0, %0, %%g0"
5678 [(set_attr "type" "compare")])
5680 (define_insn "*cmp_cc_set_ashift_1"
5681 [(set (reg:CC_NOOV 100)
5682 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5685 (set (match_operand:SI 0 "register_operand" "=r")
5686 (ashift:SI (match_dup 1) (const_int 1)))]
5689 [(set_attr "type" "compare")])
5691 (define_insn "ashrsi3"
5692 [(set (match_operand:SI 0 "register_operand" "=r")
5693 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5694 (match_operand:SI 2 "arith_operand" "rI")))]
5697 if (GET_CODE (operands[2]) == CONST_INT)
5698 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5699 return "sra\t%1, %2, %0";
5701 [(set_attr "type" "shift")])
5703 (define_insn "*ashrsi3_extend"
5704 [(set (match_operand:DI 0 "register_operand" "=r")
5705 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5706 (match_operand:SI 2 "arith_operand" "r"))))]
5709 [(set_attr "type" "shift")])
5711 ;; This handles the case as above, but with constant shift instead of
5712 ;; register. Combiner "simplifies" it for us a little bit though.
5713 (define_insn "*ashrsi3_extend2"
5714 [(set (match_operand:DI 0 "register_operand" "=r")
5715 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5717 (match_operand:SI 2 "small_int_operand" "I")))]
5718 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5720 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5721 return "sra\t%1, %2, %0";
5723 [(set_attr "type" "shift")])
5725 (define_expand "ashrdi3"
5726 [(set (match_operand:DI 0 "register_operand" "=r")
5727 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5728 (match_operand:SI 2 "arith_operand" "rI")))]
5729 "TARGET_ARCH64 || TARGET_V8PLUS"
5731 if (! TARGET_ARCH64)
5733 if (GET_CODE (operands[2]) == CONST_INT)
5734 FAIL; /* prefer generic code in this case */
5735 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5740 (define_insn "*ashrdi3_sp64"
5741 [(set (match_operand:DI 0 "register_operand" "=r")
5742 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5743 (match_operand:SI 2 "arith_operand" "rI")))]
5747 if (GET_CODE (operands[2]) == CONST_INT)
5748 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5749 return "srax\t%1, %2, %0";
5751 [(set_attr "type" "shift")])
5754 (define_insn "ashrdi3_v8plus"
5755 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5756 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5757 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5758 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5760 "* return output_v8plus_shift (operands, insn, \"srax\");"
5761 [(set_attr "type" "multi")
5762 (set_attr "length" "5,5,6")])
5764 (define_insn "lshrsi3"
5765 [(set (match_operand:SI 0 "register_operand" "=r")
5766 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5767 (match_operand:SI 2 "arith_operand" "rI")))]
5770 if (GET_CODE (operands[2]) == CONST_INT)
5771 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5772 return "srl\t%1, %2, %0";
5774 [(set_attr "type" "shift")])
5776 ;; This handles the case where
5777 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5778 ;; but combiner "simplifies" it for us.
5779 (define_insn "*lshrsi3_extend"
5780 [(set (match_operand:DI 0 "register_operand" "=r")
5781 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5782 (match_operand:SI 2 "arith_operand" "r")) 0)
5783 (match_operand 3 "const_int_operand" "")))]
5784 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5786 [(set_attr "type" "shift")])
5788 ;; This handles the case where
5789 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5790 ;; but combiner "simplifies" it for us.
5791 (define_insn "*lshrsi3_extend2"
5792 [(set (match_operand:DI 0 "register_operand" "=r")
5793 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5794 (match_operand 2 "small_int_operand" "I")
5796 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5798 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5799 return "srl\t%1, %2, %0";
5801 [(set_attr "type" "shift")])
5803 (define_expand "lshrdi3"
5804 [(set (match_operand:DI 0 "register_operand" "=r")
5805 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5806 (match_operand:SI 2 "arith_operand" "rI")))]
5807 "TARGET_ARCH64 || TARGET_V8PLUS"
5809 if (! TARGET_ARCH64)
5811 if (GET_CODE (operands[2]) == CONST_INT)
5813 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5818 (define_insn "*lshrdi3_sp64"
5819 [(set (match_operand:DI 0 "register_operand" "=r")
5820 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5821 (match_operand:SI 2 "arith_operand" "rI")))]
5824 if (GET_CODE (operands[2]) == CONST_INT)
5825 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5826 return "srlx\t%1, %2, %0";
5828 [(set_attr "type" "shift")])
5831 (define_insn "lshrdi3_v8plus"
5832 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5833 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5834 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5835 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5837 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5838 [(set_attr "type" "multi")
5839 (set_attr "length" "5,5,6")])
5842 [(set (match_operand:SI 0 "register_operand" "=r")
5843 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5845 (match_operand:SI 2 "small_int_operand" "I")))]
5846 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5848 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5849 return "srax\t%1, %2, %0";
5851 [(set_attr "type" "shift")])
5854 [(set (match_operand:SI 0 "register_operand" "=r")
5855 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5857 (match_operand:SI 2 "small_int_operand" "I")))]
5858 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5860 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5861 return "srlx\t%1, %2, %0";
5863 [(set_attr "type" "shift")])
5866 [(set (match_operand:SI 0 "register_operand" "=r")
5867 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5868 (match_operand:SI 2 "small_int_operand" "I")) 4)
5869 (match_operand:SI 3 "small_int_operand" "I")))]
5871 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5872 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5873 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5875 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5877 return "srax\t%1, %2, %0";
5879 [(set_attr "type" "shift")])
5882 [(set (match_operand:SI 0 "register_operand" "=r")
5883 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5884 (match_operand:SI 2 "small_int_operand" "I")) 4)
5885 (match_operand:SI 3 "small_int_operand" "I")))]
5887 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5888 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5889 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5891 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5893 return "srlx\t%1, %2, %0";
5895 [(set_attr "type" "shift")])
5898 ;; Unconditional and other jump instructions.
5901 [(set (pc) (label_ref (match_operand 0 "" "")))]
5903 "* return output_ubranch (operands[0], 0, insn);"
5904 [(set_attr "type" "uncond_branch")])
5906 (define_expand "tablejump"
5907 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5908 (use (label_ref (match_operand 1 "" "")))])]
5911 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5913 /* In pic mode, our address differences are against the base of the
5914 table. Add that base value back in; CSE ought to be able to combine
5915 the two address loads. */
5919 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5921 if (CASE_VECTOR_MODE != Pmode)
5922 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5923 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5924 operands[0] = memory_address (Pmode, tmp);
5928 (define_insn "*tablejump_sp32"
5929 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5930 (use (label_ref (match_operand 1 "" "")))]
5933 [(set_attr "type" "uncond_branch")])
5935 (define_insn "*tablejump_sp64"
5936 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5937 (use (label_ref (match_operand 1 "" "")))]
5940 [(set_attr "type" "uncond_branch")])
5943 ;; Jump to subroutine instructions.
5945 (define_expand "call"
5946 ;; Note that this expression is not used for generating RTL.
5947 ;; All the RTL is generated explicitly below.
5948 [(call (match_operand 0 "call_operand" "")
5949 (match_operand 3 "" "i"))]
5950 ;; operands[2] is next_arg_register
5951 ;; operands[3] is struct_value_size_rtx.
5956 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5958 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5960 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5962 /* This is really a PIC sequence. We want to represent
5963 it as a funny jump so its delay slots can be filled.
5965 ??? But if this really *is* a CALL, will not it clobber the
5966 call-clobbered registers? We lose this if it is a JUMP_INSN.
5967 Why cannot we have delay slots filled if it were a CALL? */
5969 /* We accept negative sizes for untyped calls. */
5970 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5975 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5977 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5983 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5984 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5988 fn_rtx = operands[0];
5990 /* We accept negative sizes for untyped calls. */
5991 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5992 sparc_emit_call_insn
5995 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
5997 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6000 sparc_emit_call_insn
6003 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6004 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6012 ;; We can't use the same pattern for these two insns, because then registers
6013 ;; in the address may not be properly reloaded.
6015 (define_insn "*call_address_sp32"
6016 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6017 (match_operand 1 "" ""))
6018 (clobber (reg:SI 15))]
6019 ;;- Do not use operand 1 for most machines.
6022 [(set_attr "type" "call")])
6024 (define_insn "*call_symbolic_sp32"
6025 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6026 (match_operand 1 "" ""))
6027 (clobber (reg:SI 15))]
6028 ;;- Do not use operand 1 for most machines.
6031 [(set_attr "type" "call")])
6033 (define_insn "*call_address_sp64"
6034 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6035 (match_operand 1 "" ""))
6036 (clobber (reg:DI 15))]
6037 ;;- Do not use operand 1 for most machines.
6040 [(set_attr "type" "call")])
6042 (define_insn "*call_symbolic_sp64"
6043 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6044 (match_operand 1 "" ""))
6045 (clobber (reg:DI 15))]
6046 ;;- Do not use operand 1 for most machines.
6049 [(set_attr "type" "call")])
6051 ;; This is a call that wants a structure value.
6052 ;; There is no such critter for v9 (??? we may need one anyway).
6053 (define_insn "*call_address_struct_value_sp32"
6054 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6055 (match_operand 1 "" ""))
6056 (match_operand 2 "immediate_operand" "")
6057 (clobber (reg:SI 15))]
6058 ;;- Do not use operand 1 for most machines.
6059 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6061 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6062 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6064 [(set_attr "type" "call_no_delay_slot")
6065 (set_attr "length" "3")])
6067 ;; This is a call that wants a structure value.
6068 ;; There is no such critter for v9 (??? we may need one anyway).
6069 (define_insn "*call_symbolic_struct_value_sp32"
6070 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6071 (match_operand 1 "" ""))
6072 (match_operand 2 "immediate_operand" "")
6073 (clobber (reg:SI 15))]
6074 ;;- Do not use operand 1 for most machines.
6075 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6077 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6078 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6080 [(set_attr "type" "call_no_delay_slot")
6081 (set_attr "length" "3")])
6083 ;; This is a call that may want a structure value. This is used for
6085 (define_insn "*call_address_untyped_struct_value_sp32"
6086 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6087 (match_operand 1 "" ""))
6088 (match_operand 2 "immediate_operand" "")
6089 (clobber (reg:SI 15))]
6090 ;;- Do not use operand 1 for most machines.
6091 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6092 "call\t%a0, %1\n\t nop\n\tnop"
6093 [(set_attr "type" "call_no_delay_slot")
6094 (set_attr "length" "3")])
6096 ;; This is a call that may want a structure value. This is used for
6098 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6099 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6100 (match_operand 1 "" ""))
6101 (match_operand 2 "immediate_operand" "")
6102 (clobber (reg:SI 15))]
6103 ;;- Do not use operand 1 for most machines.
6104 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6105 "call\t%a0, %1\n\t nop\n\tnop"
6106 [(set_attr "type" "call_no_delay_slot")
6107 (set_attr "length" "3")])
6109 (define_expand "call_value"
6110 ;; Note that this expression is not used for generating RTL.
6111 ;; All the RTL is generated explicitly below.
6112 [(set (match_operand 0 "register_operand" "=rf")
6113 (call (match_operand 1 "" "")
6114 (match_operand 4 "" "")))]
6115 ;; operand 2 is stack_size_rtx
6116 ;; operand 3 is next_arg_register
6122 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6124 fn_rtx = operands[1];
6127 gen_rtx_SET (VOIDmode, operands[0],
6128 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6129 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6131 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6136 (define_insn "*call_value_address_sp32"
6137 [(set (match_operand 0 "" "=rf")
6138 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6139 (match_operand 2 "" "")))
6140 (clobber (reg:SI 15))]
6141 ;;- Do not use operand 2 for most machines.
6144 [(set_attr "type" "call")])
6146 (define_insn "*call_value_symbolic_sp32"
6147 [(set (match_operand 0 "" "=rf")
6148 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6149 (match_operand 2 "" "")))
6150 (clobber (reg:SI 15))]
6151 ;;- Do not use operand 2 for most machines.
6154 [(set_attr "type" "call")])
6156 (define_insn "*call_value_address_sp64"
6157 [(set (match_operand 0 "" "")
6158 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6159 (match_operand 2 "" "")))
6160 (clobber (reg:DI 15))]
6161 ;;- Do not use operand 2 for most machines.
6164 [(set_attr "type" "call")])
6166 (define_insn "*call_value_symbolic_sp64"
6167 [(set (match_operand 0 "" "")
6168 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6169 (match_operand 2 "" "")))
6170 (clobber (reg:DI 15))]
6171 ;;- Do not use operand 2 for most machines.
6174 [(set_attr "type" "call")])
6176 (define_expand "untyped_call"
6177 [(parallel [(call (match_operand 0 "" "")
6179 (match_operand:BLK 1 "memory_operand" "")
6180 (match_operand 2 "" "")])]
6183 rtx valreg1 = gen_rtx_REG (DImode, 8);
6184 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6185 rtx result = operands[1];
6187 /* Pass constm1 to indicate that it may expect a structure value, but
6188 we don't know what size it is. */
6189 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6191 /* Save the function value registers. */
6192 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6193 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6196 /* The optimizer does not know that the call sets the function value
6197 registers we stored in the result block. We avoid problems by
6198 claiming that all hard registers are used and clobbered at this
6200 emit_insn (gen_blockage ());
6205 ;; Tail call instructions.
6207 (define_expand "sibcall"
6208 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6213 (define_insn "*sibcall_symbolic_sp32"
6214 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6215 (match_operand 1 "" ""))
6218 "* return output_sibcall(insn, operands[0]);"
6219 [(set_attr "type" "sibcall")])
6221 (define_insn "*sibcall_symbolic_sp64"
6222 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6223 (match_operand 1 "" ""))
6226 "* return output_sibcall(insn, operands[0]);"
6227 [(set_attr "type" "sibcall")])
6229 (define_expand "sibcall_value"
6230 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6231 (call (match_operand 1 "" "") (const_int 0)))
6236 (define_insn "*sibcall_value_symbolic_sp32"
6237 [(set (match_operand 0 "" "=rf")
6238 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6239 (match_operand 2 "" "")))
6242 "* return output_sibcall(insn, operands[1]);"
6243 [(set_attr "type" "sibcall")])
6245 (define_insn "*sibcall_value_symbolic_sp64"
6246 [(set (match_operand 0 "" "")
6247 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6248 (match_operand 2 "" "")))
6251 "* return output_sibcall(insn, operands[1]);"
6252 [(set_attr "type" "sibcall")])
6255 ;; Special instructions.
6257 (define_expand "prologue"
6261 sparc_expand_prologue ();
6265 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6266 ;; backend automatically emits the required call frame debugging information
6267 ;; while it is parsing it. Therefore, the pattern should not be modified
6268 ;; without first studying the impact of the changes on the debug info.
6269 ;; [(set (%fp) (%sp))
6270 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6271 ;; (set (%i7) (%o7))]
6273 (define_insn "save_register_window<P:mode>"
6274 [(set (reg:P 30) (reg:P 14))
6275 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6276 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6277 (set (reg:P 31) (reg:P 15))]
6279 "save\t%%sp, %0, %%sp"
6280 [(set_attr "type" "savew")])
6282 (define_expand "epilogue"
6286 sparc_expand_epilogue ();
6289 (define_expand "sibcall_epilogue"
6293 sparc_expand_epilogue ();
6297 (define_expand "return"
6299 "sparc_can_use_return_insn_p ()"
6302 (define_insn "*return_internal"
6305 "* return output_return (insn);"
6306 [(set_attr "type" "return")
6307 (set (attr "length")
6308 (cond [(eq_attr "leaf_function" "true")
6309 (if_then_else (eq_attr "empty_delay_slot" "true")
6312 (eq_attr "calls_eh_return" "true")
6313 (if_then_else (eq_attr "delayed_branch" "true")
6314 (if_then_else (eq_attr "isa" "v9")
6317 (if_then_else (eq_attr "isa" "v9")
6320 (eq_attr "empty_delay_slot" "true")
6321 (if_then_else (eq_attr "delayed_branch" "true")
6326 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6327 ;; all of memory. This blocks insns from being moved across this point.
6329 (define_insn "blockage"
6330 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6333 [(set_attr "length" "0")])
6335 (define_expand "probe_stack"
6336 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6340 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6343 ;; Prepare to return any type including a structure value.
6345 (define_expand "untyped_return"
6346 [(match_operand:BLK 0 "memory_operand" "")
6347 (match_operand 1 "" "")]
6350 rtx valreg1 = gen_rtx_REG (DImode, 24);
6351 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6352 rtx result = operands[0];
6354 if (! TARGET_ARCH64)
6356 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6358 rtx value = gen_reg_rtx (SImode);
6360 /* Fetch the instruction where we will return to and see if it's an unimp
6361 instruction (the most significant 10 bits will be zero). If so,
6362 update the return address to skip the unimp instruction. */
6363 emit_move_insn (value,
6364 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6365 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6366 emit_insn (gen_update_return (rtnreg, value));
6369 /* Reload the function value registers. */
6370 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6371 emit_move_insn (valreg2,
6372 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6374 /* Put USE insns before the return. */
6378 /* Construct the return. */
6379 expand_naked_return ();
6384 ;; Adjust the return address conditionally. If the value of op1 is equal
6385 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6386 ;; This is technically *half* the check required by the 32-bit SPARC
6387 ;; psABI. This check only ensures that an "unimp" insn was written by
6388 ;; the caller, but doesn't check to see if the expected size matches
6389 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6390 ;; only used by the above code "untyped_return".
6392 (define_insn "update_return"
6393 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6394 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6397 if (flag_delayed_branch)
6398 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6400 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6402 [(set (attr "type") (const_string "multi"))
6403 (set (attr "length")
6404 (if_then_else (eq_attr "delayed_branch" "true")
6413 (define_expand "indirect_jump"
6414 [(set (pc) (match_operand 0 "address_operand" "p"))]
6418 (define_insn "*branch_sp32"
6419 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6422 [(set_attr "type" "uncond_branch")])
6424 (define_insn "*branch_sp64"
6425 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6428 [(set_attr "type" "uncond_branch")])
6430 (define_expand "nonlocal_goto"
6431 [(match_operand:SI 0 "general_operand" "")
6432 (match_operand:SI 1 "general_operand" "")
6433 (match_operand:SI 2 "general_operand" "")
6434 (match_operand:SI 3 "" "")]
6437 rtx lab = operands[1];
6438 rtx stack = operands[2];
6439 rtx fp = operands[3];
6442 /* Trap instruction to flush all the register windows. */
6443 emit_insn (gen_flush_register_windows ());
6445 /* Load the fp value for the containing fn into %fp. This is needed
6446 because STACK refers to %fp. Note that virtual register instantiation
6447 fails if the virtual %fp isn't set from a register. */
6448 if (GET_CODE (fp) != REG)
6449 fp = force_reg (Pmode, fp);
6450 emit_move_insn (virtual_stack_vars_rtx, fp);
6452 /* Find the containing function's current nonlocal goto handler,
6453 which will do any cleanups and then jump to the label. */
6454 labreg = gen_rtx_REG (Pmode, 8);
6455 emit_move_insn (labreg, lab);
6457 /* Restore %fp from stack pointer value for containing function.
6458 The restore insn that follows will move this to %sp,
6459 and reload the appropriate value into %fp. */
6460 emit_move_insn (hard_frame_pointer_rtx, stack);
6462 emit_use (stack_pointer_rtx);
6464 /* ??? The V9-specific version was disabled in rev 1.65. */
6465 emit_jump_insn (gen_goto_handler_and_restore (labreg));
6470 ;; Special trap insn to flush register windows.
6471 (define_insn "flush_register_windows"
6472 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6474 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6475 [(set_attr "type" "flushw")])
6477 (define_insn "goto_handler_and_restore"
6478 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
6479 "GET_MODE (operands[0]) == Pmode"
6481 if (flag_delayed_branch)
6482 return "jmp\t%0\n\t restore";
6484 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
6486 [(set (attr "type") (const_string "multi"))
6487 (set (attr "length")
6488 (if_then_else (eq_attr "delayed_branch" "true")
6492 ;; For __builtin_setjmp we need to flush register windows iff the function
6493 ;; calls alloca as well, because otherwise the register window might be
6494 ;; saved after %sp adjustment and thus setjmp would crash
6495 (define_expand "builtin_setjmp_setup"
6496 [(match_operand 0 "register_operand" "r")]
6499 emit_insn (gen_do_builtin_setjmp_setup ());
6503 (define_insn "do_builtin_setjmp_setup"
6504 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
6507 if (!cfun->calls_alloca)
6511 fputs ("\tflushw\n", asm_out_file);
6513 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
6514 TARGET_ARCH64 ? 'x' : 'w',
6515 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
6516 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
6517 TARGET_ARCH64 ? 'x' : 'w',
6518 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
6519 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
6520 TARGET_ARCH64 ? 'x' : 'w',
6521 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
6524 [(set_attr "type" "multi")
6525 (set (attr "length")
6526 (cond [(eq_attr "calls_alloca" "false")
6528 (eq_attr "isa" "!v9")
6530 (eq_attr "pic" "true")
6531 (const_int 4)] (const_int 3)))])
6533 ;; Pattern for use after a setjmp to store FP and the return register
6534 ;; into the stack area.
6536 (define_expand "setjmp"
6542 mem = gen_rtx_MEM (Pmode,
6543 plus_constant (stack_pointer_rtx,
6544 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
6545 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
6547 mem = gen_rtx_MEM (Pmode,
6548 plus_constant (stack_pointer_rtx,
6549 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
6550 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
6554 ;; Special pattern for the FLUSH instruction.
6556 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6557 ; of the define_insn otherwise missing a mode. We make "flush", aka
6558 ; gen_flush, the default one since sparc_initialize_trampoline uses
6559 ; it on SImode mem values.
6561 (define_insn "flush"
6562 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6564 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6565 [(set_attr "type" "iflush")])
6567 (define_insn "flushdi"
6568 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6570 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6571 [(set_attr "type" "iflush")])
6574 ;; Find first set instructions.
6576 ;; The scan instruction searches from the most significant bit while ffs
6577 ;; searches from the least significant bit. The bit index and treatment of
6578 ;; zero also differ. It takes at least 7 instructions to get the proper
6579 ;; result. Here is an obvious 8 instruction sequence.
6582 (define_insn "ffssi2"
6583 [(set (match_operand:SI 0 "register_operand" "=&r")
6584 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6585 (clobber (match_scratch:SI 2 "=&r"))]
6586 "TARGET_SPARCLITE || TARGET_SPARCLET"
6588 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";
6590 [(set_attr "type" "multi")
6591 (set_attr "length" "8")])
6593 ;; ??? This should be a define expand, so that the extra instruction have
6594 ;; a chance of being optimized away.
6596 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6597 ;; does, but no one uses that and we don't have a switch for it.
6599 ;(define_insn "ffsdi2"
6600 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6601 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6602 ; (clobber (match_scratch:DI 2 "=&r"))]
6604 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6605 ; [(set_attr "type" "multi")
6606 ; (set_attr "length" "4")])
6610 ;; Peepholes go at the end.
6612 ;; Optimize consecutive loads or stores into ldd and std when possible.
6613 ;; The conditions in which we do this are very restricted and are
6614 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6617 [(set (match_operand:SI 0 "memory_operand" "")
6619 (set (match_operand:SI 1 "memory_operand" "")
6622 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6625 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6628 [(set (match_operand:SI 0 "memory_operand" "")
6630 (set (match_operand:SI 1 "memory_operand" "")
6633 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6636 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6639 [(set (match_operand:SI 0 "register_operand" "")
6640 (match_operand:SI 1 "memory_operand" ""))
6641 (set (match_operand:SI 2 "register_operand" "")
6642 (match_operand:SI 3 "memory_operand" ""))]
6643 "registers_ok_for_ldd_peep (operands[0], operands[2])
6644 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6647 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6648 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6651 [(set (match_operand:SI 0 "memory_operand" "")
6652 (match_operand:SI 1 "register_operand" ""))
6653 (set (match_operand:SI 2 "memory_operand" "")
6654 (match_operand:SI 3 "register_operand" ""))]
6655 "registers_ok_for_ldd_peep (operands[1], operands[3])
6656 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6659 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6660 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6663 [(set (match_operand:SF 0 "register_operand" "")
6664 (match_operand:SF 1 "memory_operand" ""))
6665 (set (match_operand:SF 2 "register_operand" "")
6666 (match_operand:SF 3 "memory_operand" ""))]
6667 "registers_ok_for_ldd_peep (operands[0], operands[2])
6668 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6671 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6672 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6675 [(set (match_operand:SF 0 "memory_operand" "")
6676 (match_operand:SF 1 "register_operand" ""))
6677 (set (match_operand:SF 2 "memory_operand" "")
6678 (match_operand:SF 3 "register_operand" ""))]
6679 "registers_ok_for_ldd_peep (operands[1], operands[3])
6680 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6683 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6684 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6687 [(set (match_operand:SI 0 "register_operand" "")
6688 (match_operand:SI 1 "memory_operand" ""))
6689 (set (match_operand:SI 2 "register_operand" "")
6690 (match_operand:SI 3 "memory_operand" ""))]
6691 "registers_ok_for_ldd_peep (operands[2], operands[0])
6692 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6695 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6696 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6699 [(set (match_operand:SI 0 "memory_operand" "")
6700 (match_operand:SI 1 "register_operand" ""))
6701 (set (match_operand:SI 2 "memory_operand" "")
6702 (match_operand:SI 3 "register_operand" ""))]
6703 "registers_ok_for_ldd_peep (operands[3], operands[1])
6704 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6707 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6708 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6712 [(set (match_operand:SF 0 "register_operand" "")
6713 (match_operand:SF 1 "memory_operand" ""))
6714 (set (match_operand:SF 2 "register_operand" "")
6715 (match_operand:SF 3 "memory_operand" ""))]
6716 "registers_ok_for_ldd_peep (operands[2], operands[0])
6717 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6720 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6721 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6724 [(set (match_operand:SF 0 "memory_operand" "")
6725 (match_operand:SF 1 "register_operand" ""))
6726 (set (match_operand:SF 2 "memory_operand" "")
6727 (match_operand:SF 3 "register_operand" ""))]
6728 "registers_ok_for_ldd_peep (operands[3], operands[1])
6729 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6732 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6733 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6735 ;; Optimize the case of following a reg-reg move with a test
6736 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6737 ;; This can result from a float to fix conversion.
6740 [(set (match_operand:SI 0 "register_operand" "")
6741 (match_operand:SI 1 "register_operand" ""))
6743 (compare:CC (match_operand:SI 2 "register_operand" "")
6745 "(rtx_equal_p (operands[2], operands[0])
6746 || rtx_equal_p (operands[2], operands[1]))
6747 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6748 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6749 [(parallel [(set (match_dup 0) (match_dup 1))
6751 (compare:CC (match_dup 1) (const_int 0)))])]
6755 [(set (match_operand:DI 0 "register_operand" "")
6756 (match_operand:DI 1 "register_operand" ""))
6758 (compare:CCX (match_operand:DI 2 "register_operand" "")
6761 && (rtx_equal_p (operands[2], operands[0])
6762 || rtx_equal_p (operands[2], operands[1]))
6763 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6764 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6765 [(parallel [(set (match_dup 0) (match_dup 1))
6767 (compare:CCX (match_dup 1) (const_int 0)))])]
6771 ;; Prefetch instructions.
6773 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6774 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6775 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6777 (define_expand "prefetch"
6778 [(match_operand 0 "address_operand" "")
6779 (match_operand 1 "const_int_operand" "")
6780 (match_operand 2 "const_int_operand" "")]
6784 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6786 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6790 (define_insn "prefetch_64"
6791 [(prefetch (match_operand:DI 0 "address_operand" "p")
6792 (match_operand:DI 1 "const_int_operand" "n")
6793 (match_operand:DI 2 "const_int_operand" "n"))]
6796 static const char * const prefetch_instr[2][2] = {
6798 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6799 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6802 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6803 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6806 int read_or_write = INTVAL (operands[1]);
6807 int locality = INTVAL (operands[2]);
6809 gcc_assert (read_or_write == 0 || read_or_write == 1);
6810 gcc_assert (locality >= 0 && locality < 4);
6811 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6813 [(set_attr "type" "load")])
6815 (define_insn "prefetch_32"
6816 [(prefetch (match_operand:SI 0 "address_operand" "p")
6817 (match_operand:SI 1 "const_int_operand" "n")
6818 (match_operand:SI 2 "const_int_operand" "n"))]
6821 static const char * const prefetch_instr[2][2] = {
6823 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6824 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6827 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6828 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6831 int read_or_write = INTVAL (operands[1]);
6832 int locality = INTVAL (operands[2]);
6834 gcc_assert (read_or_write == 0 || read_or_write == 1);
6835 gcc_assert (locality >= 0 && locality < 4);
6836 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6838 [(set_attr "type" "load")])
6841 ;; Trap instructions.
6844 [(trap_if (const_int 1) (const_int 5))]
6847 [(set_attr "type" "trap")])
6849 (define_expand "ctrapsi4"
6850 [(trap_if (match_operator 0 "noov_compare_operator"
6851 [(match_operand:SI 1 "compare_operand" "")
6852 (match_operand:SI 2 "arith_operand" "")])
6853 (match_operand 3 ""))]
6855 "operands[1] = gen_compare_reg (operands[0]);
6856 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6858 operands[2] = const0_rtx;")
6860 (define_expand "ctrapdi4"
6861 [(trap_if (match_operator 0 "noov_compare_operator"
6862 [(match_operand:DI 1 "compare_operand" "")
6863 (match_operand:DI 2 "arith_operand" "")])
6864 (match_operand 3 ""))]
6866 "operands[1] = gen_compare_reg (operands[0]);
6867 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6869 operands[2] = const0_rtx;")
6873 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
6874 (match_operand:SI 1 "arith_operand" "rM"))]
6878 return "t%C0\t%%icc, %1";
6882 [(set_attr "type" "trap")])
6885 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
6886 (match_operand:SI 1 "arith_operand" "rM"))]
6889 [(set_attr "type" "trap")])
6892 ;; TLS support instructions.
6894 (define_insn "tgd_hi22"
6895 [(set (match_operand:SI 0 "register_operand" "=r")
6896 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
6899 "sethi\\t%%tgd_hi22(%a1), %0")
6901 (define_insn "tgd_lo10"
6902 [(set (match_operand:SI 0 "register_operand" "=r")
6903 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6904 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
6907 "add\\t%1, %%tgd_lo10(%a2), %0")
6909 (define_insn "tgd_add32"
6910 [(set (match_operand:SI 0 "register_operand" "=r")
6911 (plus:SI (match_operand:SI 1 "register_operand" "r")
6912 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6913 (match_operand 3 "tgd_symbolic_operand" "")]
6915 "TARGET_TLS && TARGET_ARCH32"
6916 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6918 (define_insn "tgd_add64"
6919 [(set (match_operand:DI 0 "register_operand" "=r")
6920 (plus:DI (match_operand:DI 1 "register_operand" "r")
6921 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6922 (match_operand 3 "tgd_symbolic_operand" "")]
6924 "TARGET_TLS && TARGET_ARCH64"
6925 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6927 (define_insn "tgd_call32"
6928 [(set (match_operand 0 "register_operand" "=r")
6929 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
6930 (match_operand 2 "tgd_symbolic_operand" "")]
6932 (match_operand 3 "" "")))
6933 (clobber (reg:SI 15))]
6934 "TARGET_TLS && TARGET_ARCH32"
6935 "call\t%a1, %%tgd_call(%a2)%#"
6936 [(set_attr "type" "call")])
6938 (define_insn "tgd_call64"
6939 [(set (match_operand 0 "register_operand" "=r")
6940 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
6941 (match_operand 2 "tgd_symbolic_operand" "")]
6943 (match_operand 3 "" "")))
6944 (clobber (reg:DI 15))]
6945 "TARGET_TLS && TARGET_ARCH64"
6946 "call\t%a1, %%tgd_call(%a2)%#"
6947 [(set_attr "type" "call")])
6949 (define_insn "tldm_hi22"
6950 [(set (match_operand:SI 0 "register_operand" "=r")
6951 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6953 "sethi\\t%%tldm_hi22(%&), %0")
6955 (define_insn "tldm_lo10"
6956 [(set (match_operand:SI 0 "register_operand" "=r")
6957 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6958 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6960 "add\\t%1, %%tldm_lo10(%&), %0")
6962 (define_insn "tldm_add32"
6963 [(set (match_operand:SI 0 "register_operand" "=r")
6964 (plus:SI (match_operand:SI 1 "register_operand" "r")
6965 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
6967 "TARGET_TLS && TARGET_ARCH32"
6968 "add\\t%1, %2, %0, %%tldm_add(%&)")
6970 (define_insn "tldm_add64"
6971 [(set (match_operand:DI 0 "register_operand" "=r")
6972 (plus:DI (match_operand:DI 1 "register_operand" "r")
6973 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
6975 "TARGET_TLS && TARGET_ARCH64"
6976 "add\\t%1, %2, %0, %%tldm_add(%&)")
6978 (define_insn "tldm_call32"
6979 [(set (match_operand 0 "register_operand" "=r")
6980 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
6982 (match_operand 2 "" "")))
6983 (clobber (reg:SI 15))]
6984 "TARGET_TLS && TARGET_ARCH32"
6985 "call\t%a1, %%tldm_call(%&)%#"
6986 [(set_attr "type" "call")])
6988 (define_insn "tldm_call64"
6989 [(set (match_operand 0 "register_operand" "=r")
6990 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
6992 (match_operand 2 "" "")))
6993 (clobber (reg:DI 15))]
6994 "TARGET_TLS && TARGET_ARCH64"
6995 "call\t%a1, %%tldm_call(%&)%#"
6996 [(set_attr "type" "call")])
6998 (define_insn "tldo_hix22"
6999 [(set (match_operand:SI 0 "register_operand" "=r")
7000 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7003 "sethi\\t%%tldo_hix22(%a1), %0")
7005 (define_insn "tldo_lox10"
7006 [(set (match_operand:SI 0 "register_operand" "=r")
7007 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7008 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7011 "xor\\t%1, %%tldo_lox10(%a2), %0")
7013 (define_insn "tldo_add32"
7014 [(set (match_operand:SI 0 "register_operand" "=r")
7015 (plus:SI (match_operand:SI 1 "register_operand" "r")
7016 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7017 (match_operand 3 "tld_symbolic_operand" "")]
7019 "TARGET_TLS && TARGET_ARCH32"
7020 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7022 (define_insn "tldo_add64"
7023 [(set (match_operand:DI 0 "register_operand" "=r")
7024 (plus:DI (match_operand:DI 1 "register_operand" "r")
7025 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7026 (match_operand 3 "tld_symbolic_operand" "")]
7028 "TARGET_TLS && TARGET_ARCH64"
7029 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7031 (define_insn "tie_hi22"
7032 [(set (match_operand:SI 0 "register_operand" "=r")
7033 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7036 "sethi\\t%%tie_hi22(%a1), %0")
7038 (define_insn "tie_lo10"
7039 [(set (match_operand:SI 0 "register_operand" "=r")
7040 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7041 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7044 "add\\t%1, %%tie_lo10(%a2), %0")
7046 (define_insn "tie_ld32"
7047 [(set (match_operand:SI 0 "register_operand" "=r")
7048 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7049 (match_operand:SI 2 "register_operand" "r")
7050 (match_operand 3 "tie_symbolic_operand" "")]
7052 "TARGET_TLS && TARGET_ARCH32"
7053 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7054 [(set_attr "type" "load")])
7056 (define_insn "tie_ld64"
7057 [(set (match_operand:DI 0 "register_operand" "=r")
7058 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7059 (match_operand:SI 2 "register_operand" "r")
7060 (match_operand 3 "tie_symbolic_operand" "")]
7062 "TARGET_TLS && TARGET_ARCH64"
7063 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7064 [(set_attr "type" "load")])
7066 (define_insn "tie_add32"
7067 [(set (match_operand:SI 0 "register_operand" "=r")
7068 (plus:SI (match_operand:SI 1 "register_operand" "r")
7069 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7070 (match_operand 3 "tie_symbolic_operand" "")]
7072 "TARGET_SUN_TLS && TARGET_ARCH32"
7073 "add\\t%1, %2, %0, %%tie_add(%a3)")
7075 (define_insn "tie_add64"
7076 [(set (match_operand:DI 0 "register_operand" "=r")
7077 (plus:DI (match_operand:DI 1 "register_operand" "r")
7078 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7079 (match_operand 3 "tie_symbolic_operand" "")]
7081 "TARGET_SUN_TLS && TARGET_ARCH64"
7082 "add\\t%1, %2, %0, %%tie_add(%a3)")
7084 (define_insn "tle_hix22_sp32"
7085 [(set (match_operand:SI 0 "register_operand" "=r")
7086 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7088 "TARGET_TLS && TARGET_ARCH32"
7089 "sethi\\t%%tle_hix22(%a1), %0")
7091 (define_insn "tle_lox10_sp32"
7092 [(set (match_operand:SI 0 "register_operand" "=r")
7093 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7094 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7096 "TARGET_TLS && TARGET_ARCH32"
7097 "xor\\t%1, %%tle_lox10(%a2), %0")
7099 (define_insn "tle_hix22_sp64"
7100 [(set (match_operand:DI 0 "register_operand" "=r")
7101 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7103 "TARGET_TLS && TARGET_ARCH64"
7104 "sethi\\t%%tle_hix22(%a1), %0")
7106 (define_insn "tle_lox10_sp64"
7107 [(set (match_operand:DI 0 "register_operand" "=r")
7108 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7109 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7111 "TARGET_TLS && TARGET_ARCH64"
7112 "xor\\t%1, %%tle_lox10(%a2), %0")
7114 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7115 (define_insn "*tldo_ldub_sp32"
7116 [(set (match_operand:QI 0 "register_operand" "=r")
7117 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7118 (match_operand 3 "tld_symbolic_operand" "")]
7120 (match_operand:SI 1 "register_operand" "r"))))]
7121 "TARGET_TLS && TARGET_ARCH32"
7122 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7123 [(set_attr "type" "load")
7124 (set_attr "us3load_type" "3cycle")])
7126 (define_insn "*tldo_ldub1_sp32"
7127 [(set (match_operand:HI 0 "register_operand" "=r")
7128 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7129 (match_operand 3 "tld_symbolic_operand" "")]
7131 (match_operand:SI 1 "register_operand" "r")))))]
7132 "TARGET_TLS && TARGET_ARCH32"
7133 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7134 [(set_attr "type" "load")
7135 (set_attr "us3load_type" "3cycle")])
7137 (define_insn "*tldo_ldub2_sp32"
7138 [(set (match_operand:SI 0 "register_operand" "=r")
7139 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7140 (match_operand 3 "tld_symbolic_operand" "")]
7142 (match_operand:SI 1 "register_operand" "r")))))]
7143 "TARGET_TLS && TARGET_ARCH32"
7144 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7145 [(set_attr "type" "load")
7146 (set_attr "us3load_type" "3cycle")])
7148 (define_insn "*tldo_ldsb1_sp32"
7149 [(set (match_operand:HI 0 "register_operand" "=r")
7150 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7151 (match_operand 3 "tld_symbolic_operand" "")]
7153 (match_operand:SI 1 "register_operand" "r")))))]
7154 "TARGET_TLS && TARGET_ARCH32"
7155 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7156 [(set_attr "type" "sload")
7157 (set_attr "us3load_type" "3cycle")])
7159 (define_insn "*tldo_ldsb2_sp32"
7160 [(set (match_operand:SI 0 "register_operand" "=r")
7161 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7162 (match_operand 3 "tld_symbolic_operand" "")]
7164 (match_operand:SI 1 "register_operand" "r")))))]
7165 "TARGET_TLS && TARGET_ARCH32"
7166 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7167 [(set_attr "type" "sload")
7168 (set_attr "us3load_type" "3cycle")])
7170 (define_insn "*tldo_ldub_sp64"
7171 [(set (match_operand:QI 0 "register_operand" "=r")
7172 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7173 (match_operand 3 "tld_symbolic_operand" "")]
7175 (match_operand:DI 1 "register_operand" "r"))))]
7176 "TARGET_TLS && TARGET_ARCH64"
7177 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7178 [(set_attr "type" "load")
7179 (set_attr "us3load_type" "3cycle")])
7181 (define_insn "*tldo_ldub1_sp64"
7182 [(set (match_operand:HI 0 "register_operand" "=r")
7183 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7184 (match_operand 3 "tld_symbolic_operand" "")]
7186 (match_operand:DI 1 "register_operand" "r")))))]
7187 "TARGET_TLS && TARGET_ARCH64"
7188 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7189 [(set_attr "type" "load")
7190 (set_attr "us3load_type" "3cycle")])
7192 (define_insn "*tldo_ldub2_sp64"
7193 [(set (match_operand:SI 0 "register_operand" "=r")
7194 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7195 (match_operand 3 "tld_symbolic_operand" "")]
7197 (match_operand:DI 1 "register_operand" "r")))))]
7198 "TARGET_TLS && TARGET_ARCH64"
7199 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7200 [(set_attr "type" "load")
7201 (set_attr "us3load_type" "3cycle")])
7203 (define_insn "*tldo_ldub3_sp64"
7204 [(set (match_operand:DI 0 "register_operand" "=r")
7205 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7206 (match_operand 3 "tld_symbolic_operand" "")]
7208 (match_operand:DI 1 "register_operand" "r")))))]
7209 "TARGET_TLS && TARGET_ARCH64"
7210 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7211 [(set_attr "type" "load")
7212 (set_attr "us3load_type" "3cycle")])
7214 (define_insn "*tldo_ldsb1_sp64"
7215 [(set (match_operand:HI 0 "register_operand" "=r")
7216 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7217 (match_operand 3 "tld_symbolic_operand" "")]
7219 (match_operand:DI 1 "register_operand" "r")))))]
7220 "TARGET_TLS && TARGET_ARCH64"
7221 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7222 [(set_attr "type" "sload")
7223 (set_attr "us3load_type" "3cycle")])
7225 (define_insn "*tldo_ldsb2_sp64"
7226 [(set (match_operand:SI 0 "register_operand" "=r")
7227 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7228 (match_operand 3 "tld_symbolic_operand" "")]
7230 (match_operand:DI 1 "register_operand" "r")))))]
7231 "TARGET_TLS && TARGET_ARCH64"
7232 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7233 [(set_attr "type" "sload")
7234 (set_attr "us3load_type" "3cycle")])
7236 (define_insn "*tldo_ldsb3_sp64"
7237 [(set (match_operand:DI 0 "register_operand" "=r")
7238 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7239 (match_operand 3 "tld_symbolic_operand" "")]
7241 (match_operand:DI 1 "register_operand" "r")))))]
7242 "TARGET_TLS && TARGET_ARCH64"
7243 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7244 [(set_attr "type" "sload")
7245 (set_attr "us3load_type" "3cycle")])
7247 (define_insn "*tldo_lduh_sp32"
7248 [(set (match_operand:HI 0 "register_operand" "=r")
7249 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7250 (match_operand 3 "tld_symbolic_operand" "")]
7252 (match_operand:SI 1 "register_operand" "r"))))]
7253 "TARGET_TLS && TARGET_ARCH32"
7254 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7255 [(set_attr "type" "load")
7256 (set_attr "us3load_type" "3cycle")])
7258 (define_insn "*tldo_lduh1_sp32"
7259 [(set (match_operand:SI 0 "register_operand" "=r")
7260 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7261 (match_operand 3 "tld_symbolic_operand" "")]
7263 (match_operand:SI 1 "register_operand" "r")))))]
7264 "TARGET_TLS && TARGET_ARCH32"
7265 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7266 [(set_attr "type" "load")
7267 (set_attr "us3load_type" "3cycle")])
7269 (define_insn "*tldo_ldsh1_sp32"
7270 [(set (match_operand:SI 0 "register_operand" "=r")
7271 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7272 (match_operand 3 "tld_symbolic_operand" "")]
7274 (match_operand:SI 1 "register_operand" "r")))))]
7275 "TARGET_TLS && TARGET_ARCH32"
7276 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7277 [(set_attr "type" "sload")
7278 (set_attr "us3load_type" "3cycle")])
7280 (define_insn "*tldo_lduh_sp64"
7281 [(set (match_operand:HI 0 "register_operand" "=r")
7282 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7283 (match_operand 3 "tld_symbolic_operand" "")]
7285 (match_operand:DI 1 "register_operand" "r"))))]
7286 "TARGET_TLS && TARGET_ARCH64"
7287 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7288 [(set_attr "type" "load")
7289 (set_attr "us3load_type" "3cycle")])
7291 (define_insn "*tldo_lduh1_sp64"
7292 [(set (match_operand:SI 0 "register_operand" "=r")
7293 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7294 (match_operand 3 "tld_symbolic_operand" "")]
7296 (match_operand:DI 1 "register_operand" "r")))))]
7297 "TARGET_TLS && TARGET_ARCH64"
7298 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7299 [(set_attr "type" "load")
7300 (set_attr "us3load_type" "3cycle")])
7302 (define_insn "*tldo_lduh2_sp64"
7303 [(set (match_operand:DI 0 "register_operand" "=r")
7304 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7305 (match_operand 3 "tld_symbolic_operand" "")]
7307 (match_operand:DI 1 "register_operand" "r")))))]
7308 "TARGET_TLS && TARGET_ARCH64"
7309 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7310 [(set_attr "type" "load")
7311 (set_attr "us3load_type" "3cycle")])
7313 (define_insn "*tldo_ldsh1_sp64"
7314 [(set (match_operand:SI 0 "register_operand" "=r")
7315 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7316 (match_operand 3 "tld_symbolic_operand" "")]
7318 (match_operand:DI 1 "register_operand" "r")))))]
7319 "TARGET_TLS && TARGET_ARCH64"
7320 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7321 [(set_attr "type" "sload")
7322 (set_attr "us3load_type" "3cycle")])
7324 (define_insn "*tldo_ldsh2_sp64"
7325 [(set (match_operand:DI 0 "register_operand" "=r")
7326 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7327 (match_operand 3 "tld_symbolic_operand" "")]
7329 (match_operand:DI 1 "register_operand" "r")))))]
7330 "TARGET_TLS && TARGET_ARCH64"
7331 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7332 [(set_attr "type" "sload")
7333 (set_attr "us3load_type" "3cycle")])
7335 (define_insn "*tldo_lduw_sp32"
7336 [(set (match_operand:SI 0 "register_operand" "=r")
7337 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7338 (match_operand 3 "tld_symbolic_operand" "")]
7340 (match_operand:SI 1 "register_operand" "r"))))]
7341 "TARGET_TLS && TARGET_ARCH32"
7342 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7343 [(set_attr "type" "load")])
7345 (define_insn "*tldo_lduw_sp64"
7346 [(set (match_operand:SI 0 "register_operand" "=r")
7347 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7348 (match_operand 3 "tld_symbolic_operand" "")]
7350 (match_operand:DI 1 "register_operand" "r"))))]
7351 "TARGET_TLS && TARGET_ARCH64"
7352 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7353 [(set_attr "type" "load")])
7355 (define_insn "*tldo_lduw1_sp64"
7356 [(set (match_operand:DI 0 "register_operand" "=r")
7357 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7358 (match_operand 3 "tld_symbolic_operand" "")]
7360 (match_operand:DI 1 "register_operand" "r")))))]
7361 "TARGET_TLS && TARGET_ARCH64"
7362 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7363 [(set_attr "type" "load")])
7365 (define_insn "*tldo_ldsw1_sp64"
7366 [(set (match_operand:DI 0 "register_operand" "=r")
7367 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7368 (match_operand 3 "tld_symbolic_operand" "")]
7370 (match_operand:DI 1 "register_operand" "r")))))]
7371 "TARGET_TLS && TARGET_ARCH64"
7372 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7373 [(set_attr "type" "sload")
7374 (set_attr "us3load_type" "3cycle")])
7376 (define_insn "*tldo_ldx_sp64"
7377 [(set (match_operand:DI 0 "register_operand" "=r")
7378 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7379 (match_operand 3 "tld_symbolic_operand" "")]
7381 (match_operand:DI 1 "register_operand" "r"))))]
7382 "TARGET_TLS && TARGET_ARCH64"
7383 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7384 [(set_attr "type" "load")])
7386 (define_insn "*tldo_stb_sp32"
7387 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7388 (match_operand 3 "tld_symbolic_operand" "")]
7390 (match_operand:SI 1 "register_operand" "r")))
7391 (match_operand:QI 0 "register_operand" "=r"))]
7392 "TARGET_TLS && TARGET_ARCH32"
7393 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7394 [(set_attr "type" "store")])
7396 (define_insn "*tldo_stb_sp64"
7397 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7398 (match_operand 3 "tld_symbolic_operand" "")]
7400 (match_operand:DI 1 "register_operand" "r")))
7401 (match_operand:QI 0 "register_operand" "=r"))]
7402 "TARGET_TLS && TARGET_ARCH64"
7403 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7404 [(set_attr "type" "store")])
7406 (define_insn "*tldo_sth_sp32"
7407 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7408 (match_operand 3 "tld_symbolic_operand" "")]
7410 (match_operand:SI 1 "register_operand" "r")))
7411 (match_operand:HI 0 "register_operand" "=r"))]
7412 "TARGET_TLS && TARGET_ARCH32"
7413 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7414 [(set_attr "type" "store")])
7416 (define_insn "*tldo_sth_sp64"
7417 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7418 (match_operand 3 "tld_symbolic_operand" "")]
7420 (match_operand:DI 1 "register_operand" "r")))
7421 (match_operand:HI 0 "register_operand" "=r"))]
7422 "TARGET_TLS && TARGET_ARCH64"
7423 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7424 [(set_attr "type" "store")])
7426 (define_insn "*tldo_stw_sp32"
7427 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7428 (match_operand 3 "tld_symbolic_operand" "")]
7430 (match_operand:SI 1 "register_operand" "r")))
7431 (match_operand:SI 0 "register_operand" "=r"))]
7432 "TARGET_TLS && TARGET_ARCH32"
7433 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7434 [(set_attr "type" "store")])
7436 (define_insn "*tldo_stw_sp64"
7437 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7438 (match_operand 3 "tld_symbolic_operand" "")]
7440 (match_operand:DI 1 "register_operand" "r")))
7441 (match_operand:SI 0 "register_operand" "=r"))]
7442 "TARGET_TLS && TARGET_ARCH64"
7443 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7444 [(set_attr "type" "store")])
7446 (define_insn "*tldo_stx_sp64"
7447 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7448 (match_operand 3 "tld_symbolic_operand" "")]
7450 (match_operand:DI 1 "register_operand" "r")))
7451 (match_operand:DI 0 "register_operand" "=r"))]
7452 "TARGET_TLS && TARGET_ARCH64"
7453 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7454 [(set_attr "type" "store")])
7457 ;; Stack protector instructions.
7459 (define_expand "stack_protect_set"
7460 [(match_operand 0 "memory_operand" "")
7461 (match_operand 1 "memory_operand" "")]
7464 #ifdef TARGET_THREAD_SSP_OFFSET
7465 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7466 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7467 operands[1] = gen_rtx_MEM (Pmode, addr);
7470 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7472 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7476 (define_insn "stack_protect_setsi"
7477 [(set (match_operand:SI 0 "memory_operand" "=m")
7478 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7479 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7481 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7482 [(set_attr "type" "multi")
7483 (set_attr "length" "3")])
7485 (define_insn "stack_protect_setdi"
7486 [(set (match_operand:DI 0 "memory_operand" "=m")
7487 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7488 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7490 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7491 [(set_attr "type" "multi")
7492 (set_attr "length" "3")])
7494 (define_expand "stack_protect_test"
7495 [(match_operand 0 "memory_operand" "")
7496 (match_operand 1 "memory_operand" "")
7497 (match_operand 2 "" "")]
7501 #ifdef TARGET_THREAD_SSP_OFFSET
7502 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7503 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7504 operands[1] = gen_rtx_MEM (Pmode, addr);
7508 result = gen_reg_rtx (Pmode);
7509 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7510 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7511 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7515 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7516 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7517 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7518 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7523 (define_insn "stack_protect_testsi"
7525 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7526 (match_operand:SI 1 "memory_operand" "m")]
7528 (set (match_scratch:SI 3 "=r") (const_int 0))
7529 (clobber (match_scratch:SI 2 "=&r"))]
7531 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7532 [(set_attr "type" "multi")
7533 (set_attr "length" "4")])
7535 (define_insn "stack_protect_testdi"
7536 [(set (match_operand:DI 0 "register_operand" "=&r")
7537 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7538 (match_operand:DI 2 "memory_operand" "m")]
7540 (set (match_scratch:DI 3 "=r") (const_int 0))]
7542 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7543 [(set_attr "type" "multi")
7544 (set_attr "length" "4")])
7547 ;; Vector instructions.
7549 (define_insn "addv2si3"
7550 [(set (match_operand:V2SI 0 "register_operand" "=e")
7551 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7552 (match_operand:V2SI 2 "register_operand" "e")))]
7554 "fpadd32\t%1, %2, %0"
7555 [(set_attr "type" "fga")
7556 (set_attr "fptype" "double")])
7558 (define_insn "addv4hi3"
7559 [(set (match_operand:V4HI 0 "register_operand" "=e")
7560 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7561 (match_operand:V4HI 2 "register_operand" "e")))]
7563 "fpadd16\t%1, %2, %0"
7564 [(set_attr "type" "fga")
7565 (set_attr "fptype" "double")])
7567 ;; fpadd32s is emitted by the addsi3 pattern.
7569 (define_insn "addv2hi3"
7570 [(set (match_operand:V2HI 0 "register_operand" "=f")
7571 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7572 (match_operand:V2HI 2 "register_operand" "f")))]
7574 "fpadd16s\t%1, %2, %0"
7575 [(set_attr "type" "fga")
7576 (set_attr "fptype" "single")])
7578 (define_insn "subv2si3"
7579 [(set (match_operand:V2SI 0 "register_operand" "=e")
7580 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7581 (match_operand:V2SI 2 "register_operand" "e")))]
7583 "fpsub32\t%1, %2, %0"
7584 [(set_attr "type" "fga")
7585 (set_attr "fptype" "double")])
7587 (define_insn "subv4hi3"
7588 [(set (match_operand:V4HI 0 "register_operand" "=e")
7589 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7590 (match_operand:V4HI 2 "register_operand" "e")))]
7592 "fpsub16\t%1, %2, %0"
7593 [(set_attr "type" "fga")
7594 (set_attr "fptype" "double")])
7596 ;; fpsub32s is emitted by the subsi3 pattern.
7598 (define_insn "subv2hi3"
7599 [(set (match_operand:V2HI 0 "register_operand" "=f")
7600 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7601 (match_operand:V2HI 2 "register_operand" "f")))]
7603 "fpsub16s\t%1, %2, %0"
7604 [(set_attr "type" "fga")
7605 (set_attr "fptype" "single")])
7607 ;; All other logical instructions have integer equivalents so they
7608 ;; are defined together.
7610 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7612 (define_insn "*nand<V64:mode>_vis"
7613 [(set (match_operand:V64 0 "register_operand" "=e")
7614 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7615 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7618 [(set_attr "type" "fga")
7619 (set_attr "fptype" "double")])
7621 (define_insn "*nand<V32:mode>_vis"
7622 [(set (match_operand:V32 0 "register_operand" "=f")
7623 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7624 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7626 "fnands\t%1, %2, %0"
7627 [(set_attr "type" "fga")
7628 (set_attr "fptype" "single")])
7630 ;; Hard to generate VIS instructions. We have builtins for these.
7632 (define_insn "fpack16_vis"
7633 [(set (match_operand:V4QI 0 "register_operand" "=f")
7634 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7638 [(set_attr "type" "fga")
7639 (set_attr "fptype" "double")])
7641 (define_insn "fpackfix_vis"
7642 [(set (match_operand:V2HI 0 "register_operand" "=f")
7643 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7647 [(set_attr "type" "fga")
7648 (set_attr "fptype" "double")])
7650 (define_insn "fpack32_vis"
7651 [(set (match_operand:V8QI 0 "register_operand" "=e")
7652 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7653 (match_operand:V8QI 2 "register_operand" "e")]
7656 "fpack32\t%1, %2, %0"
7657 [(set_attr "type" "fga")
7658 (set_attr "fptype" "double")])
7660 (define_insn "fexpand_vis"
7661 [(set (match_operand:V4HI 0 "register_operand" "=e")
7662 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7666 [(set_attr "type" "fga")
7667 (set_attr "fptype" "double")])
7669 ;; It may be possible to describe this operation as (1 indexed):
7670 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7671 ;; 1,5,10,14,19,23,28,32)
7672 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7673 ;; because vec_merge expects all the operands to be of the same type.
7674 (define_insn "fpmerge_vis"
7675 [(set (match_operand:V8QI 0 "register_operand" "=e")
7676 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7677 (match_operand:V4QI 2 "register_operand" "f")]
7680 "fpmerge\t%1, %2, %0"
7681 [(set_attr "type" "fga")
7682 (set_attr "fptype" "double")])
7684 ;; Partitioned multiply instructions
7685 (define_insn "fmul8x16_vis"
7686 [(set (match_operand:V4HI 0 "register_operand" "=e")
7687 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7688 (match_operand:V4HI 2 "register_operand" "e")))]
7690 "fmul8x16\t%1, %2, %0"
7691 [(set_attr "type" "fpmul")
7692 (set_attr "fptype" "double")])
7694 ;; Only one of the following two insns can be a multiply.
7695 (define_insn "fmul8x16au_vis"
7696 [(set (match_operand:V4HI 0 "register_operand" "=e")
7697 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7698 (match_operand:V2HI 2 "register_operand" "f")))]
7700 "fmul8x16au\t%1, %2, %0"
7701 [(set_attr "type" "fpmul")
7702 (set_attr "fptype" "double")])
7704 (define_insn "fmul8x16al_vis"
7705 [(set (match_operand:V4HI 0 "register_operand" "=e")
7706 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7707 (match_operand:V2HI 2 "register_operand" "f")]
7710 "fmul8x16al\t%1, %2, %0"
7711 [(set_attr "type" "fpmul")
7712 (set_attr "fptype" "double")])
7714 ;; Only one of the following two insns can be a multiply.
7715 (define_insn "fmul8sux16_vis"
7716 [(set (match_operand:V4HI 0 "register_operand" "=e")
7717 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7718 (match_operand:V4HI 2 "register_operand" "e")))]
7720 "fmul8sux16\t%1, %2, %0"
7721 [(set_attr "type" "fpmul")
7722 (set_attr "fptype" "double")])
7724 (define_insn "fmul8ulx16_vis"
7725 [(set (match_operand:V4HI 0 "register_operand" "=e")
7726 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7727 (match_operand:V4HI 2 "register_operand" "e")]
7730 "fmul8ulx16\t%1, %2, %0"
7731 [(set_attr "type" "fpmul")
7732 (set_attr "fptype" "double")])
7734 ;; Only one of the following two insns can be a multiply.
7735 (define_insn "fmuld8sux16_vis"
7736 [(set (match_operand:V2SI 0 "register_operand" "=e")
7737 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7738 (match_operand:V2HI 2 "register_operand" "f")))]
7740 "fmuld8sux16\t%1, %2, %0"
7741 [(set_attr "type" "fpmul")
7742 (set_attr "fptype" "double")])
7744 (define_insn "fmuld8ulx16_vis"
7745 [(set (match_operand:V2SI 0 "register_operand" "=e")
7746 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7747 (match_operand:V2HI 2 "register_operand" "f")]
7750 "fmuld8ulx16\t%1, %2, %0"
7751 [(set_attr "type" "fpmul")
7752 (set_attr "fptype" "double")])
7754 ;; Using faligndata only makes sense after an alignaddr since the choice of
7755 ;; bytes to take out of each operand is dependent on the results of the last
7757 (define_insn "faligndata<V64I:mode>_vis"
7758 [(set (match_operand:V64I 0 "register_operand" "=e")
7759 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
7760 (match_operand:V64I 2 "register_operand" "e")]
7763 "faligndata\t%1, %2, %0"
7764 [(set_attr "type" "fga")
7765 (set_attr "fptype" "double")])
7767 (define_insn "alignaddr<P:mode>_vis"
7768 [(set (match_operand:P 0 "register_operand" "=r")
7769 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7770 (match_operand:P 2 "register_or_zero_operand" "rJ")]
7773 "alignaddr\t%r1, %r2, %0")
7775 (define_insn "pdist_vis"
7776 [(set (match_operand:DI 0 "register_operand" "=e")
7777 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
7778 (match_operand:V8QI 2 "register_operand" "e")
7779 (match_operand:DI 3 "register_operand" "0")]
7783 [(set_attr "type" "fga")
7784 (set_attr "fptype" "double")])