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 ;; 2011 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)
69 (UNSPEC_ALIGNADDRL 57)
89 (UNSPECV_PROBE_STACK_RANGE 11)
181 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
182 (define_mode_iterator I [QI HI SI DI])
183 (define_mode_iterator F [SF DF TF])
185 ;; We don't define V1SI because SI should work just fine.
186 (define_mode_iterator V32 [SF V2HI V4QI])
187 (define_mode_iterator V32I [SI V2HI V4QI])
189 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
190 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
192 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
193 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
194 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
195 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
196 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
199 ;; Attribute for cpu type.
200 ;; These must match the values for enum processor_type in sparc.h.
221 (const (symbol_ref "sparc_cpu_attr")))
223 ;; Attribute for the instruction set.
224 ;; At present we only need to distinguish v9/!v9, but for clarity we
225 ;; test TARGET_V8 too.
226 (define_attr "isa" "v7,v8,v9,sparclet"
228 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
229 (symbol_ref "TARGET_V8") (const_string "v8")
230 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
231 (const_string "v7"))))
237 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
245 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,
248 multi,savew,flushw,iflush,trap"
249 (const_string "ialu"))
251 ;; True if branch/call has empty delay slot and will emit a nop in it
252 (define_attr "empty_delay_slot" "false,true"
253 (symbol_ref "(empty_delay_slot (insn)
254 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
256 (define_attr "branch_type" "none,icc,fcc,reg"
257 (const_string "none"))
259 (define_attr "pic" "false,true"
260 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
262 (define_attr "calls_alloca" "false,true"
263 (symbol_ref "(cfun->calls_alloca != 0
264 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
266 (define_attr "calls_eh_return" "false,true"
267 (symbol_ref "(crtl->calls_eh_return != 0
268 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
270 (define_attr "leaf_function" "false,true"
271 (symbol_ref "(current_function_uses_only_leaf_regs != 0
272 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
274 (define_attr "delayed_branch" "false,true"
275 (symbol_ref "(flag_delayed_branch != 0
276 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
278 (define_attr "flat" "false,true"
279 (symbol_ref "(TARGET_FLAT != 0
280 ? FLAT_TRUE : FLAT_FALSE)"))
282 ;; Length (in # of insns).
283 ;; Beware that setting a length greater or equal to 3 for conditional branches
284 ;; has a side-effect (see output_cbranch and output_v9branch).
285 (define_attr "length" ""
286 (cond [(eq_attr "type" "uncond_branch,call")
287 (if_then_else (eq_attr "empty_delay_slot" "true")
290 (eq_attr "type" "sibcall")
291 (if_then_else (eq_attr "leaf_function" "true")
292 (if_then_else (eq_attr "empty_delay_slot" "true")
295 (if_then_else (eq_attr "empty_delay_slot" "true")
298 (eq_attr "branch_type" "icc")
299 (if_then_else (match_operand 0 "noov_compare64_operator" "")
300 (if_then_else (lt (pc) (match_dup 1))
301 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
302 (if_then_else (eq_attr "empty_delay_slot" "true")
305 (if_then_else (eq_attr "empty_delay_slot" "true")
308 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
309 (if_then_else (eq_attr "empty_delay_slot" "true")
312 (if_then_else (eq_attr "empty_delay_slot" "true")
315 (if_then_else (eq_attr "empty_delay_slot" "true")
318 (eq_attr "branch_type" "fcc")
319 (if_then_else (match_operand 0 "fcc0_register_operand" "")
320 (if_then_else (eq_attr "empty_delay_slot" "true")
321 (if_then_else (not (match_test "TARGET_V9"))
324 (if_then_else (not (match_test "TARGET_V9"))
327 (if_then_else (lt (pc) (match_dup 2))
328 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
329 (if_then_else (eq_attr "empty_delay_slot" "true")
332 (if_then_else (eq_attr "empty_delay_slot" "true")
335 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
336 (if_then_else (eq_attr "empty_delay_slot" "true")
339 (if_then_else (eq_attr "empty_delay_slot" "true")
342 (eq_attr "branch_type" "reg")
343 (if_then_else (lt (pc) (match_dup 2))
344 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
345 (if_then_else (eq_attr "empty_delay_slot" "true")
348 (if_then_else (eq_attr "empty_delay_slot" "true")
351 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
352 (if_then_else (eq_attr "empty_delay_slot" "true")
355 (if_then_else (eq_attr "empty_delay_slot" "true")
361 (define_attr "fptype" "single,double"
362 (const_string "single"))
364 ;; UltraSPARC-III integer load type.
365 (define_attr "us3load_type" "2cycle,3cycle"
366 (const_string "2cycle"))
368 (define_asm_attributes
369 [(set_attr "length" "2")
370 (set_attr "type" "multi")])
372 ;; Attributes for instruction and branch scheduling
373 (define_attr "tls_call_delay" "false,true"
374 (symbol_ref "(tls_call_delay (insn)
375 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
377 (define_attr "in_call_delay" "false,true"
378 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
379 (const_string "false")
380 (eq_attr "type" "load,fpload,store,fpstore")
381 (if_then_else (eq_attr "length" "1")
382 (const_string "true")
383 (const_string "false"))]
384 (if_then_else (and (eq_attr "length" "1")
385 (eq_attr "tls_call_delay" "true"))
386 (const_string "true")
387 (const_string "false"))))
389 (define_attr "eligible_for_sibcall_delay" "false,true"
390 (symbol_ref "(eligible_for_sibcall_delay (insn)
391 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
392 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
394 (define_attr "eligible_for_return_delay" "false,true"
395 (symbol_ref "(eligible_for_return_delay (insn)
396 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
397 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
399 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
400 ;; branches. This would allow us to remove the nop always inserted before
401 ;; a floating point branch.
403 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
404 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
405 ;; This is because doing so will add several pipeline stalls to the path
406 ;; that the load/store did not come from. Unfortunately, there is no way
407 ;; to prevent fill_eager_delay_slots from using load/store without completely
408 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
409 ;; because it prevents us from moving back the final store of inner loops.
411 (define_attr "in_branch_delay" "false,true"
412 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
413 (eq_attr "length" "1"))
414 (const_string "true")
415 (const_string "false")))
417 (define_attr "in_uncond_branch_delay" "false,true"
418 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
419 (eq_attr "length" "1"))
420 (const_string "true")
421 (const_string "false")))
423 (define_attr "in_annul_branch_delay" "false,true"
424 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
425 (eq_attr "length" "1"))
426 (const_string "true")
427 (const_string "false")))
429 (define_delay (eq_attr "type" "call")
430 [(eq_attr "in_call_delay" "true") (nil) (nil)])
432 (define_delay (eq_attr "type" "sibcall")
433 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
435 (define_delay (eq_attr "type" "branch")
436 [(eq_attr "in_branch_delay" "true")
437 (nil) (eq_attr "in_annul_branch_delay" "true")])
439 (define_delay (eq_attr "type" "uncond_branch")
440 [(eq_attr "in_uncond_branch_delay" "true")
443 (define_delay (eq_attr "type" "return")
444 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
447 ;; Include SPARC DFA schedulers
449 (include "cypress.md")
450 (include "supersparc.md")
451 (include "hypersparc.md")
453 (include "sparclet.md")
454 (include "ultra1_2.md")
455 (include "ultra3.md")
456 (include "niagara.md")
457 (include "niagara2.md")
460 ;; Operand and operator predicates and constraints
462 (include "predicates.md")
463 (include "constraints.md")
466 ;; Compare instructions.
468 ;; These are just the DEFINE_INSNs to match the patterns and the
469 ;; DEFINE_SPLITs for some of the scc insns that actually require
470 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
472 ;; The compare DEFINE_INSNs.
474 (define_insn "*cmpsi_insn"
475 [(set (reg:CC CC_REG)
476 (compare:CC (match_operand:SI 0 "register_operand" "r")
477 (match_operand:SI 1 "arith_operand" "rI")))]
480 [(set_attr "type" "compare")])
482 (define_insn "*cmpdi_sp64"
483 [(set (reg:CCX CC_REG)
484 (compare:CCX (match_operand:DI 0 "register_operand" "r")
485 (match_operand:DI 1 "arith_operand" "rI")))]
488 [(set_attr "type" "compare")])
490 (define_insn "*cmpsf_fpe"
491 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
492 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
493 (match_operand:SF 2 "register_operand" "f")))]
497 return "fcmpes\t%0, %1, %2";
498 return "fcmpes\t%1, %2";
500 [(set_attr "type" "fpcmp")])
502 (define_insn "*cmpdf_fpe"
503 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
504 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
505 (match_operand:DF 2 "register_operand" "e")))]
509 return "fcmped\t%0, %1, %2";
510 return "fcmped\t%1, %2";
512 [(set_attr "type" "fpcmp")
513 (set_attr "fptype" "double")])
515 (define_insn "*cmptf_fpe"
516 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
517 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
518 (match_operand:TF 2 "register_operand" "e")))]
519 "TARGET_FPU && TARGET_HARD_QUAD"
522 return "fcmpeq\t%0, %1, %2";
523 return "fcmpeq\t%1, %2";
525 [(set_attr "type" "fpcmp")])
527 (define_insn "*cmpsf_fp"
528 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
529 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
530 (match_operand:SF 2 "register_operand" "f")))]
534 return "fcmps\t%0, %1, %2";
535 return "fcmps\t%1, %2";
537 [(set_attr "type" "fpcmp")])
539 (define_insn "*cmpdf_fp"
540 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
541 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
542 (match_operand:DF 2 "register_operand" "e")))]
546 return "fcmpd\t%0, %1, %2";
547 return "fcmpd\t%1, %2";
549 [(set_attr "type" "fpcmp")
550 (set_attr "fptype" "double")])
552 (define_insn "*cmptf_fp"
553 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
554 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
555 (match_operand:TF 2 "register_operand" "e")))]
556 "TARGET_FPU && TARGET_HARD_QUAD"
559 return "fcmpq\t%0, %1, %2";
560 return "fcmpq\t%1, %2";
562 [(set_attr "type" "fpcmp")])
564 ;; Next come the scc insns.
566 (define_expand "cstoresi4"
567 [(use (match_operator 1 "comparison_operator"
568 [(match_operand:SI 2 "compare_operand" "")
569 (match_operand:SI 3 "arith_operand" "")]))
570 (clobber (match_operand:SI 0 "register_operand"))]
573 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
574 operands[2] = force_reg (SImode, operands[2]);
575 if (emit_scc_insn (operands)) DONE; else FAIL;
578 (define_expand "cstoredi4"
579 [(use (match_operator 1 "comparison_operator"
580 [(match_operand:DI 2 "compare_operand" "")
581 (match_operand:DI 3 "arith_operand" "")]))
582 (clobber (match_operand:SI 0 "register_operand"))]
585 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
586 operands[2] = force_reg (DImode, operands[2]);
587 if (emit_scc_insn (operands)) DONE; else FAIL;
590 (define_expand "cstore<F:mode>4"
591 [(use (match_operator 1 "comparison_operator"
592 [(match_operand:F 2 "register_operand" "")
593 (match_operand:F 3 "register_operand" "")]))
594 (clobber (match_operand:SI 0 "register_operand"))]
596 { if (emit_scc_insn (operands)) DONE; else FAIL; })
600 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
601 ;; generate addcc/subcc instructions.
603 (define_expand "seqsi_special"
605 (xor:SI (match_operand:SI 1 "register_operand" "")
606 (match_operand:SI 2 "register_operand" "")))
607 (parallel [(set (match_operand:SI 0 "register_operand" "")
608 (eq:SI (match_dup 3) (const_int 0)))
609 (clobber (reg:CC CC_REG))])]
611 { operands[3] = gen_reg_rtx (SImode); })
613 (define_expand "seqdi_special"
615 (xor:DI (match_operand:DI 1 "register_operand" "")
616 (match_operand:DI 2 "register_operand" "")))
617 (set (match_operand:SI 0 "register_operand" "")
618 (eq:SI (match_dup 3) (const_int 0)))]
620 { operands[3] = gen_reg_rtx (DImode); })
622 (define_expand "snesi_special"
624 (xor:SI (match_operand:SI 1 "register_operand" "")
625 (match_operand:SI 2 "register_operand" "")))
626 (parallel [(set (match_operand:SI 0 "register_operand" "")
627 (ne:SI (match_dup 3) (const_int 0)))
628 (clobber (reg:CC CC_REG))])]
630 { operands[3] = gen_reg_rtx (SImode); })
632 (define_expand "snedi_special"
634 (xor:DI (match_operand:DI 1 "register_operand" "")
635 (match_operand:DI 2 "register_operand" "")))
636 (set (match_operand:SI 0 "register_operand" "")
637 (ne:SI (match_dup 3) (const_int 0)))]
639 { operands[3] = gen_reg_rtx (DImode); })
642 ;; Now the DEFINE_INSNs for the scc cases.
644 ;; The SEQ and SNE patterns are special because they can be done
645 ;; without any branching and do not involve a COMPARE. We want
646 ;; them to always use the splits below so the results can be
649 (define_insn_and_split "*snesi_zero"
650 [(set (match_operand:SI 0 "register_operand" "=r")
651 (ne:SI (match_operand:SI 1 "register_operand" "r")
653 (clobber (reg:CC CC_REG))]
657 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
659 (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
661 [(set_attr "length" "2")])
663 (define_insn_and_split "*neg_snesi_zero"
664 [(set (match_operand:SI 0 "register_operand" "=r")
665 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
667 (clobber (reg:CC CC_REG))]
671 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
673 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
675 [(set_attr "length" "2")])
677 (define_insn_and_split "*snesi_zero_extend"
678 [(set (match_operand:DI 0 "register_operand" "=r")
679 (ne:DI (match_operand:SI 1 "register_operand" "r")
681 (clobber (reg:CC CC_REG))]
685 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
688 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
690 (ltu:SI (reg:CC_NOOV CC_REG)
693 [(set_attr "length" "2")])
695 (define_insn_and_split "*snedi_zero"
696 [(set (match_operand:DI 0 "register_operand" "=&r")
697 (ne:DI (match_operand:DI 1 "register_operand" "r")
701 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
702 [(set (match_dup 0) (const_int 0))
703 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
708 [(set_attr "length" "2")])
710 (define_insn_and_split "*neg_snedi_zero"
711 [(set (match_operand:DI 0 "register_operand" "=&r")
712 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
716 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
717 [(set (match_dup 0) (const_int 0))
718 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
723 [(set_attr "length" "2")])
725 (define_insn_and_split "*snedi_zero_trunc"
726 [(set (match_operand:SI 0 "register_operand" "=&r")
727 (ne:SI (match_operand:DI 1 "register_operand" "r")
731 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
732 [(set (match_dup 0) (const_int 0))
733 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
738 [(set_attr "length" "2")])
740 (define_insn_and_split "*seqsi_zero"
741 [(set (match_operand:SI 0 "register_operand" "=r")
742 (eq:SI (match_operand:SI 1 "register_operand" "r")
744 (clobber (reg:CC CC_REG))]
748 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
750 (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
752 [(set_attr "length" "2")])
754 (define_insn_and_split "*neg_seqsi_zero"
755 [(set (match_operand:SI 0 "register_operand" "=r")
756 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
758 (clobber (reg:CC CC_REG))]
762 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
764 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
766 [(set_attr "length" "2")])
768 (define_insn_and_split "*seqsi_zero_extend"
769 [(set (match_operand:DI 0 "register_operand" "=r")
770 (eq:DI (match_operand:SI 1 "register_operand" "r")
772 (clobber (reg:CC CC_REG))]
776 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
779 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
781 (ltu:SI (reg:CC_NOOV CC_REG)
784 [(set_attr "length" "2")])
786 (define_insn_and_split "*seqdi_zero"
787 [(set (match_operand:DI 0 "register_operand" "=&r")
788 (eq:DI (match_operand:DI 1 "register_operand" "r")
792 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
793 [(set (match_dup 0) (const_int 0))
794 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
799 [(set_attr "length" "2")])
801 (define_insn_and_split "*neg_seqdi_zero"
802 [(set (match_operand:DI 0 "register_operand" "=&r")
803 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
807 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
808 [(set (match_dup 0) (const_int 0))
809 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
814 [(set_attr "length" "2")])
816 (define_insn_and_split "*seqdi_zero_trunc"
817 [(set (match_operand:SI 0 "register_operand" "=&r")
818 (eq:SI (match_operand:DI 1 "register_operand" "r")
822 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
823 [(set (match_dup 0) (const_int 0))
824 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
829 [(set_attr "length" "2")])
831 ;; We can also do (x + (i == 0)) and related, so put them in.
832 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
835 (define_insn_and_split "*x_plus_i_ne_0"
836 [(set (match_operand:SI 0 "register_operand" "=r")
837 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
839 (match_operand:SI 2 "register_operand" "r")))
840 (clobber (reg:CC CC_REG))]
844 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
846 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
849 [(set_attr "length" "2")])
851 (define_insn_and_split "*x_minus_i_ne_0"
852 [(set (match_operand:SI 0 "register_operand" "=r")
853 (minus:SI (match_operand:SI 2 "register_operand" "r")
854 (ne:SI (match_operand:SI 1 "register_operand" "r")
856 (clobber (reg:CC CC_REG))]
860 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
862 (set (match_dup 0) (minus:SI (match_dup 2)
863 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
865 [(set_attr "length" "2")])
867 (define_insn_and_split "*x_plus_i_eq_0"
868 [(set (match_operand:SI 0 "register_operand" "=r")
869 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
871 (match_operand:SI 2 "register_operand" "r")))
872 (clobber (reg:CC CC_REG))]
876 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
878 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
881 [(set_attr "length" "2")])
883 (define_insn_and_split "*x_minus_i_eq_0"
884 [(set (match_operand:SI 0 "register_operand" "=r")
885 (minus:SI (match_operand:SI 2 "register_operand" "r")
886 (eq:SI (match_operand:SI 1 "register_operand" "r")
888 (clobber (reg:CC CC_REG))]
892 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
894 (set (match_dup 0) (minus:SI (match_dup 2)
895 (geu:SI (reg:CC CC_REG) (const_int 0))))]
897 [(set_attr "length" "2")])
899 ;; We can also do GEU and LTU directly, but these operate after a compare.
900 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
903 (define_insn "*sltu_insn"
904 [(set (match_operand:SI 0 "register_operand" "=r")
905 (ltu:SI (reg:CC CC_REG) (const_int 0)))]
908 [(set_attr "type" "ialuX")])
910 (define_insn "*neg_sltu_insn"
911 [(set (match_operand:SI 0 "register_operand" "=r")
912 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
915 [(set_attr "type" "ialuX")])
917 ;; ??? Combine should canonicalize these next two to the same pattern.
918 (define_insn "*neg_sltu_minus_x"
919 [(set (match_operand:SI 0 "register_operand" "=r")
920 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
921 (match_operand:SI 1 "arith_operand" "rI")))]
924 [(set_attr "type" "ialuX")])
926 (define_insn "*neg_sltu_plus_x"
927 [(set (match_operand:SI 0 "register_operand" "=r")
928 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
929 (match_operand:SI 1 "arith_operand" "rI"))))]
932 [(set_attr "type" "ialuX")])
934 (define_insn "*sgeu_insn"
935 [(set (match_operand:SI 0 "register_operand" "=r")
936 (geu:SI (reg:CC CC_REG) (const_int 0)))]
939 [(set_attr "type" "ialuX")])
941 (define_insn "*neg_sgeu_insn"
942 [(set (match_operand:SI 0 "register_operand" "=r")
943 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
946 [(set_attr "type" "ialuX")])
948 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
949 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
952 (define_insn "*sltu_plus_x"
953 [(set (match_operand:SI 0 "register_operand" "=r")
954 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
955 (match_operand:SI 1 "arith_operand" "rI")))]
958 [(set_attr "type" "ialuX")])
960 (define_insn "*sltu_plus_x_plus_y"
961 [(set (match_operand:SI 0 "register_operand" "=r")
962 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
963 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
964 (match_operand:SI 2 "arith_operand" "rI"))))]
967 [(set_attr "type" "ialuX")])
969 (define_insn "*x_minus_sltu"
970 [(set (match_operand:SI 0 "register_operand" "=r")
971 (minus:SI (match_operand:SI 1 "register_operand" "r")
972 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
975 [(set_attr "type" "ialuX")])
977 ;; ??? Combine should canonicalize these next two to the same pattern.
978 (define_insn "*x_minus_y_minus_sltu"
979 [(set (match_operand:SI 0 "register_operand" "=r")
980 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
981 (match_operand:SI 2 "arith_operand" "rI"))
982 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
985 [(set_attr "type" "ialuX")])
987 (define_insn "*x_minus_sltu_plus_y"
988 [(set (match_operand:SI 0 "register_operand" "=r")
989 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
990 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
991 (match_operand:SI 2 "arith_operand" "rI"))))]
994 [(set_attr "type" "ialuX")])
996 (define_insn "*sgeu_plus_x"
997 [(set (match_operand:SI 0 "register_operand" "=r")
998 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
999 (match_operand:SI 1 "register_operand" "r")))]
1002 [(set_attr "type" "ialuX")])
1004 (define_insn "*x_minus_sgeu"
1005 [(set (match_operand:SI 0 "register_operand" "=r")
1006 (minus:SI (match_operand:SI 1 "register_operand" "r")
1007 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1010 [(set_attr "type" "ialuX")])
1013 [(set (match_operand:SI 0 "register_operand" "")
1014 (match_operator:SI 2 "noov_compare_operator"
1015 [(match_operand 1 "icc_or_fcc_register_operand" "")
1018 && REGNO (operands[1]) == SPARC_ICC_REG
1019 && (GET_MODE (operands[1]) == CCXmode
1020 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1021 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1022 [(set (match_dup 0) (const_int 0))
1024 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1030 ;; These control RTL generation for conditional jump insns
1032 (define_expand "cbranchcc4"
1034 (if_then_else (match_operator 0 "comparison_operator"
1035 [(match_operand 1 "compare_operand" "")
1036 (match_operand 2 "const_zero_operand" "")])
1037 (label_ref (match_operand 3 "" ""))
1042 (define_expand "cbranchsi4"
1043 [(use (match_operator 0 "comparison_operator"
1044 [(match_operand:SI 1 "compare_operand" "")
1045 (match_operand:SI 2 "arith_operand" "")]))
1046 (use (match_operand 3 ""))]
1049 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1050 operands[1] = force_reg (SImode, operands[1]);
1051 emit_conditional_branch_insn (operands);
1055 (define_expand "cbranchdi4"
1056 [(use (match_operator 0 "comparison_operator"
1057 [(match_operand:DI 1 "compare_operand" "")
1058 (match_operand:DI 2 "arith_operand" "")]))
1059 (use (match_operand 3 ""))]
1062 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1063 operands[1] = force_reg (DImode, operands[1]);
1064 emit_conditional_branch_insn (operands);
1068 (define_expand "cbranch<F:mode>4"
1069 [(use (match_operator 0 "comparison_operator"
1070 [(match_operand:F 1 "register_operand" "")
1071 (match_operand:F 2 "register_operand" "")]))
1072 (use (match_operand 3 ""))]
1074 { emit_conditional_branch_insn (operands); DONE; })
1077 ;; Now match both normal and inverted jump.
1079 ;; XXX fpcmp nop braindamage
1080 (define_insn "*normal_branch"
1082 (if_then_else (match_operator 0 "noov_compare_operator"
1083 [(reg CC_REG) (const_int 0)])
1084 (label_ref (match_operand 1 "" ""))
1088 return output_cbranch (operands[0], operands[1], 1, 0,
1089 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1092 [(set_attr "type" "branch")
1093 (set_attr "branch_type" "icc")])
1095 ;; XXX fpcmp nop braindamage
1096 (define_insn "*inverted_branch"
1098 (if_then_else (match_operator 0 "noov_compare_operator"
1099 [(reg CC_REG) (const_int 0)])
1101 (label_ref (match_operand 1 "" ""))))]
1104 return output_cbranch (operands[0], operands[1], 1, 1,
1105 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1108 [(set_attr "type" "branch")
1109 (set_attr "branch_type" "icc")])
1111 ;; XXX fpcmp nop braindamage
1112 (define_insn "*normal_fp_branch"
1114 (if_then_else (match_operator 1 "comparison_operator"
1115 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1117 (label_ref (match_operand 2 "" ""))
1121 return output_cbranch (operands[1], operands[2], 2, 0,
1122 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1125 [(set_attr "type" "branch")
1126 (set_attr "branch_type" "fcc")])
1128 ;; XXX fpcmp nop braindamage
1129 (define_insn "*inverted_fp_branch"
1131 (if_then_else (match_operator 1 "comparison_operator"
1132 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1135 (label_ref (match_operand 2 "" ""))))]
1138 return output_cbranch (operands[1], operands[2], 2, 1,
1139 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1142 [(set_attr "type" "branch")
1143 (set_attr "branch_type" "fcc")])
1145 ;; XXX fpcmp nop braindamage
1146 (define_insn "*normal_fpe_branch"
1148 (if_then_else (match_operator 1 "comparison_operator"
1149 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1151 (label_ref (match_operand 2 "" ""))
1155 return output_cbranch (operands[1], operands[2], 2, 0,
1156 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1159 [(set_attr "type" "branch")
1160 (set_attr "branch_type" "fcc")])
1162 ;; XXX fpcmp nop braindamage
1163 (define_insn "*inverted_fpe_branch"
1165 (if_then_else (match_operator 1 "comparison_operator"
1166 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1169 (label_ref (match_operand 2 "" ""))))]
1172 return output_cbranch (operands[1], operands[2], 2, 1,
1173 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1176 [(set_attr "type" "branch")
1177 (set_attr "branch_type" "fcc")])
1179 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1180 ;; in the architecture.
1182 ;; There are no 32 bit brreg insns.
1185 (define_insn "*normal_int_branch_sp64"
1187 (if_then_else (match_operator 0 "v9_register_compare_operator"
1188 [(match_operand:DI 1 "register_operand" "r")
1190 (label_ref (match_operand 2 "" ""))
1194 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1195 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1198 [(set_attr "type" "branch")
1199 (set_attr "branch_type" "reg")])
1202 (define_insn "*inverted_int_branch_sp64"
1204 (if_then_else (match_operator 0 "v9_register_compare_operator"
1205 [(match_operand:DI 1 "register_operand" "r")
1208 (label_ref (match_operand 2 "" ""))))]
1211 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1212 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1215 [(set_attr "type" "branch")
1216 (set_attr "branch_type" "reg")])
1219 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1220 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1221 ;; that adds the PC value at the call point to register #(operand 3).
1223 (define_insn "load_pcrel_sym<P:mode>"
1224 [(set (match_operand:P 0 "register_operand" "=r")
1225 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1226 (match_operand:P 2 "call_address_operand" "")
1227 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1228 (clobber (reg:P O7_REG))]
1229 "REGNO (operands[0]) == INTVAL (operands[3])"
1231 if (flag_delayed_branch)
1232 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1234 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1236 [(set (attr "type") (const_string "multi"))
1237 (set (attr "length")
1238 (if_then_else (eq_attr "delayed_branch" "true")
1243 ;; Integer move instructions
1245 (define_expand "movqi"
1246 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1247 (match_operand:QI 1 "general_operand" ""))]
1250 if (sparc_expand_move (QImode, operands))
1254 (define_insn "*movqi_insn"
1255 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1256 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1257 "(register_operand (operands[0], QImode)
1258 || register_or_zero_operand (operands[1], QImode))"
1263 [(set_attr "type" "*,load,store")
1264 (set_attr "us3load_type" "*,3cycle,*")])
1266 (define_expand "movhi"
1267 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1268 (match_operand:HI 1 "general_operand" ""))]
1271 if (sparc_expand_move (HImode, operands))
1275 (define_insn "*movhi_insn"
1276 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1277 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1278 "(register_operand (operands[0], HImode)
1279 || register_or_zero_operand (operands[1], HImode))"
1282 sethi\t%%hi(%a1), %0
1285 [(set_attr "type" "*,*,load,store")
1286 (set_attr "us3load_type" "*,*,3cycle,*")])
1288 ;; We always work with constants here.
1289 (define_insn "*movhi_lo_sum"
1290 [(set (match_operand:HI 0 "register_operand" "=r")
1291 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1292 (match_operand:HI 2 "small_int_operand" "I")))]
1296 (define_expand "movsi"
1297 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1298 (match_operand:SI 1 "general_operand" ""))]
1301 if (sparc_expand_move (SImode, operands))
1305 (define_insn "*movsi_insn"
1306 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1307 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1308 "(register_operand (operands[0], SImode)
1309 || register_or_zero_operand (operands[1], SImode))"
1312 sethi\t%%hi(%a1), %0
1319 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1321 (define_insn "*movsi_lo_sum"
1322 [(set (match_operand:SI 0 "register_operand" "=r")
1323 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1324 (match_operand:SI 2 "immediate_operand" "in")))]
1326 "or\t%1, %%lo(%a2), %0")
1328 (define_insn "*movsi_high"
1329 [(set (match_operand:SI 0 "register_operand" "=r")
1330 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1332 "sethi\t%%hi(%a1), %0")
1334 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1335 ;; so that CSE won't optimize the address computation away.
1336 (define_insn "movsi_lo_sum_pic"
1337 [(set (match_operand:SI 0 "register_operand" "=r")
1338 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1339 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1342 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1343 return "xor\t%1, %%gdop_lox10(%a2), %0";
1345 return "or\t%1, %%lo(%a2), %0";
1349 (define_insn "movsi_high_pic"
1350 [(set (match_operand:SI 0 "register_operand" "=r")
1351 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1352 "flag_pic && check_pic (1)"
1354 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1355 return "sethi\t%%gdop_hix22(%a1), %0";
1357 return "sethi\t%%hi(%a1), %0";
1361 (define_insn "movsi_pic_gotdata_op"
1362 [(set (match_operand:SI 0 "register_operand" "=r")
1363 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1364 (match_operand:SI 2 "register_operand" "r")
1365 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1366 "flag_pic && check_pic (1)"
1368 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1369 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1371 return "ld\t[%1 + %2], %0";
1374 [(set_attr "type" "load")])
1376 (define_expand "movsi_pic_label_ref"
1377 [(set (match_dup 3) (high:SI
1378 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1379 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1380 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1381 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1382 (set (match_operand:SI 0 "register_operand" "=r")
1383 (minus:SI (match_dup 5) (match_dup 4)))]
1386 crtl->uses_pic_offset_table = 1;
1387 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1388 if (!can_create_pseudo_p ())
1390 operands[3] = operands[0];
1391 operands[4] = operands[0];
1395 operands[3] = gen_reg_rtx (SImode);
1396 operands[4] = gen_reg_rtx (SImode);
1398 operands[5] = pic_offset_table_rtx;
1401 (define_insn "*movsi_high_pic_label_ref"
1402 [(set (match_operand:SI 0 "register_operand" "=r")
1404 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1405 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1407 "sethi\t%%hi(%a2-(%a1-.)), %0")
1409 (define_insn "*movsi_lo_sum_pic_label_ref"
1410 [(set (match_operand:SI 0 "register_operand" "=r")
1411 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1412 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1413 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1415 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1417 ;; Set up the PIC register for VxWorks.
1419 (define_expand "vxworks_load_got"
1421 (high:SI (match_dup 1)))
1423 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1425 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1426 "TARGET_VXWORKS_RTP"
1428 operands[0] = pic_offset_table_rtx;
1429 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1430 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1433 (define_expand "movdi"
1434 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1435 (match_operand:DI 1 "general_operand" ""))]
1438 if (sparc_expand_move (DImode, operands))
1442 ;; Be careful, fmovd does not exist when !v9.
1443 ;; We match MEM moves directly when we have correct even
1444 ;; numbered registers, but fall into splits otherwise.
1445 ;; The constraint ordering here is really important to
1446 ;; avoid insane problems in reload, especially for patterns
1449 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1450 ;; (const_int -5016)))
1454 (define_insn "*movdi_insn_sp32"
1455 [(set (match_operand:DI 0 "nonimmediate_operand"
1456 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1457 (match_operand:DI 1 "input_operand"
1458 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1460 && (register_operand (operands[0], DImode)
1461 || register_or_zero_operand (operands[1], DImode))"
1475 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1476 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1478 (define_insn "*movdi_insn_sp32_v9"
1479 [(set (match_operand:DI 0 "nonimmediate_operand"
1480 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1481 (match_operand:DI 1 "input_operand"
1482 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1485 && (register_operand (operands[0], DImode)
1486 || register_or_zero_operand (operands[1], DImode))"
1503 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1504 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1505 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1507 (define_insn "*movdi_insn_sp64"
1508 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1509 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1511 && (register_operand (operands[0], DImode)
1512 || register_or_zero_operand (operands[1], DImode))"
1515 sethi\t%%hi(%a1), %0
1522 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1523 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1525 (define_expand "movdi_pic_label_ref"
1526 [(set (match_dup 3) (high:DI
1527 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1528 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1529 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1530 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1531 (set (match_operand:DI 0 "register_operand" "=r")
1532 (minus:DI (match_dup 5) (match_dup 4)))]
1533 "TARGET_ARCH64 && flag_pic"
1535 crtl->uses_pic_offset_table = 1;
1536 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1537 if (!can_create_pseudo_p ())
1539 operands[3] = operands[0];
1540 operands[4] = operands[0];
1544 operands[3] = gen_reg_rtx (DImode);
1545 operands[4] = gen_reg_rtx (DImode);
1547 operands[5] = pic_offset_table_rtx;
1550 (define_insn "*movdi_high_pic_label_ref"
1551 [(set (match_operand:DI 0 "register_operand" "=r")
1553 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1554 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1555 "TARGET_ARCH64 && flag_pic"
1556 "sethi\t%%hi(%a2-(%a1-.)), %0")
1558 (define_insn "*movdi_lo_sum_pic_label_ref"
1559 [(set (match_operand:DI 0 "register_operand" "=r")
1560 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1561 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1562 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1563 "TARGET_ARCH64 && flag_pic"
1564 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1566 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1567 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1569 (define_insn "movdi_lo_sum_pic"
1570 [(set (match_operand:DI 0 "register_operand" "=r")
1571 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1572 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1573 "TARGET_ARCH64 && flag_pic"
1575 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1576 return "xor\t%1, %%gdop_lox10(%a2), %0";
1578 return "or\t%1, %%lo(%a2), %0";
1582 (define_insn "movdi_high_pic"
1583 [(set (match_operand:DI 0 "register_operand" "=r")
1584 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1585 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1587 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1588 return "sethi\t%%gdop_hix22(%a1), %0";
1590 return "sethi\t%%hi(%a1), %0";
1594 (define_insn "movdi_pic_gotdata_op"
1595 [(set (match_operand:DI 0 "register_operand" "=r")
1596 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1597 (match_operand:DI 2 "register_operand" "r")
1598 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1599 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1601 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1602 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1604 return "ldx\t[%1 + %2], %0";
1607 [(set_attr "type" "load")])
1609 (define_insn "*sethi_di_medlow_embmedany_pic"
1610 [(set (match_operand:DI 0 "register_operand" "=r")
1611 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1612 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1613 "sethi\t%%hi(%a1), %0")
1615 (define_insn "*sethi_di_medlow"
1616 [(set (match_operand:DI 0 "register_operand" "=r")
1617 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1618 "TARGET_CM_MEDLOW && check_pic (1)"
1619 "sethi\t%%hi(%a1), %0")
1621 (define_insn "*losum_di_medlow"
1622 [(set (match_operand:DI 0 "register_operand" "=r")
1623 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1624 (match_operand:DI 2 "symbolic_operand" "")))]
1626 "or\t%1, %%lo(%a2), %0")
1628 (define_insn "seth44"
1629 [(set (match_operand:DI 0 "register_operand" "=r")
1630 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1632 "sethi\t%%h44(%a1), %0")
1634 (define_insn "setm44"
1635 [(set (match_operand:DI 0 "register_operand" "=r")
1636 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1637 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1639 "or\t%1, %%m44(%a2), %0")
1641 (define_insn "setl44"
1642 [(set (match_operand:DI 0 "register_operand" "=r")
1643 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1644 (match_operand:DI 2 "symbolic_operand" "")))]
1646 "or\t%1, %%l44(%a2), %0")
1648 (define_insn "sethh"
1649 [(set (match_operand:DI 0 "register_operand" "=r")
1650 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1652 "sethi\t%%hh(%a1), %0")
1654 (define_insn "setlm"
1655 [(set (match_operand:DI 0 "register_operand" "=r")
1656 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1658 "sethi\t%%lm(%a1), %0")
1660 (define_insn "sethm"
1661 [(set (match_operand:DI 0 "register_operand" "=r")
1662 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1663 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1665 "or\t%1, %%hm(%a2), %0")
1667 (define_insn "setlo"
1668 [(set (match_operand:DI 0 "register_operand" "=r")
1669 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1670 (match_operand:DI 2 "symbolic_operand" "")))]
1672 "or\t%1, %%lo(%a2), %0")
1674 (define_insn "embmedany_sethi"
1675 [(set (match_operand:DI 0 "register_operand" "=r")
1676 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1677 "TARGET_CM_EMBMEDANY && check_pic (1)"
1678 "sethi\t%%hi(%a1), %0")
1680 (define_insn "embmedany_losum"
1681 [(set (match_operand:DI 0 "register_operand" "=r")
1682 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1683 (match_operand:DI 2 "data_segment_operand" "")))]
1684 "TARGET_CM_EMBMEDANY"
1685 "add\t%1, %%lo(%a2), %0")
1687 (define_insn "embmedany_brsum"
1688 [(set (match_operand:DI 0 "register_operand" "=r")
1689 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1690 "TARGET_CM_EMBMEDANY"
1693 (define_insn "embmedany_textuhi"
1694 [(set (match_operand:DI 0 "register_operand" "=r")
1695 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1696 "TARGET_CM_EMBMEDANY && check_pic (1)"
1697 "sethi\t%%uhi(%a1), %0")
1699 (define_insn "embmedany_texthi"
1700 [(set (match_operand:DI 0 "register_operand" "=r")
1701 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1702 "TARGET_CM_EMBMEDANY && check_pic (1)"
1703 "sethi\t%%hi(%a1), %0")
1705 (define_insn "embmedany_textulo"
1706 [(set (match_operand:DI 0 "register_operand" "=r")
1707 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1708 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1709 "TARGET_CM_EMBMEDANY"
1710 "or\t%1, %%ulo(%a2), %0")
1712 (define_insn "embmedany_textlo"
1713 [(set (match_operand:DI 0 "register_operand" "=r")
1714 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1715 (match_operand:DI 2 "text_segment_operand" "")))]
1716 "TARGET_CM_EMBMEDANY"
1717 "or\t%1, %%lo(%a2), %0")
1719 ;; Now some patterns to help reload out a bit.
1720 (define_expand "reload_indi"
1721 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1722 (match_operand:DI 1 "immediate_operand" "")
1723 (match_operand:TI 2 "register_operand" "=&r")])]
1725 || TARGET_CM_EMBMEDANY)
1728 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1732 (define_expand "reload_outdi"
1733 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1734 (match_operand:DI 1 "immediate_operand" "")
1735 (match_operand:TI 2 "register_operand" "=&r")])]
1737 || TARGET_CM_EMBMEDANY)
1740 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1744 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1746 [(set (match_operand:DI 0 "register_operand" "")
1747 (match_operand:DI 1 "const_int_operand" ""))]
1748 "! TARGET_ARCH64 && reload_completed"
1749 [(clobber (const_int 0))]
1751 #if HOST_BITS_PER_WIDE_INT == 32
1752 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1753 (INTVAL (operands[1]) < 0) ?
1756 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1759 unsigned int low, high;
1761 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1762 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1763 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1765 /* Slick... but this trick loses if this subreg constant part
1766 can be done in one insn. */
1768 && ! SPARC_SETHI32_P (high)
1769 && ! SPARC_SIMM13_P (high))
1770 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1771 gen_highpart (SImode, operands[0])));
1773 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1779 [(set (match_operand:DI 0 "register_operand" "")
1780 (match_operand:DI 1 "const_double_operand" ""))]
1784 && ((GET_CODE (operands[0]) == REG
1785 && REGNO (operands[0]) < 32)
1786 || (GET_CODE (operands[0]) == SUBREG
1787 && GET_CODE (SUBREG_REG (operands[0])) == REG
1788 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1789 [(clobber (const_int 0))]
1791 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1792 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1794 /* Slick... but this trick loses if this subreg constant part
1795 can be done in one insn. */
1796 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1797 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1798 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1800 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1801 gen_highpart (SImode, operands[0])));
1805 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1806 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1812 [(set (match_operand:DI 0 "register_operand" "")
1813 (match_operand:DI 1 "register_operand" ""))]
1817 && ((GET_CODE (operands[0]) == REG
1818 && REGNO (operands[0]) < 32)
1819 || (GET_CODE (operands[0]) == SUBREG
1820 && GET_CODE (SUBREG_REG (operands[0])) == REG
1821 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1822 [(clobber (const_int 0))]
1824 rtx set_dest = operands[0];
1825 rtx set_src = operands[1];
1829 dest1 = gen_highpart (SImode, set_dest);
1830 dest2 = gen_lowpart (SImode, set_dest);
1831 src1 = gen_highpart (SImode, set_src);
1832 src2 = gen_lowpart (SImode, set_src);
1834 /* Now emit using the real source and destination we found, swapping
1835 the order if we detect overlap. */
1836 if (reg_overlap_mentioned_p (dest1, src2))
1838 emit_insn (gen_movsi (dest2, src2));
1839 emit_insn (gen_movsi (dest1, src1));
1843 emit_insn (gen_movsi (dest1, src1));
1844 emit_insn (gen_movsi (dest2, src2));
1849 ;; Now handle the cases of memory moves from/to non-even
1850 ;; DI mode register pairs.
1852 [(set (match_operand:DI 0 "register_operand" "")
1853 (match_operand:DI 1 "memory_operand" ""))]
1856 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1857 [(clobber (const_int 0))]
1859 rtx word0 = adjust_address (operands[1], SImode, 0);
1860 rtx word1 = adjust_address (operands[1], SImode, 4);
1861 rtx high_part = gen_highpart (SImode, operands[0]);
1862 rtx low_part = gen_lowpart (SImode, operands[0]);
1864 if (reg_overlap_mentioned_p (high_part, word1))
1866 emit_insn (gen_movsi (low_part, word1));
1867 emit_insn (gen_movsi (high_part, word0));
1871 emit_insn (gen_movsi (high_part, word0));
1872 emit_insn (gen_movsi (low_part, word1));
1878 [(set (match_operand:DI 0 "memory_operand" "")
1879 (match_operand:DI 1 "register_operand" ""))]
1882 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1883 [(clobber (const_int 0))]
1885 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1886 gen_highpart (SImode, operands[1])));
1887 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1888 gen_lowpart (SImode, operands[1])));
1893 [(set (match_operand:DI 0 "memory_operand" "")
1894 (match_operand:DI 1 "const_zero_operand" ""))]
1898 && ! mem_min_alignment (operands[0], 8)))
1899 && offsettable_memref_p (operands[0])"
1900 [(clobber (const_int 0))]
1902 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1903 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1908 ;; Floating point and vector move instructions
1910 ;; Yes, you guessed it right, the former movsf expander.
1911 (define_expand "mov<V32:mode>"
1912 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1913 (match_operand:V32 1 "general_operand" ""))]
1914 "<V32:MODE>mode == SFmode || TARGET_VIS"
1916 if (sparc_expand_move (<V32:MODE>mode, operands))
1920 (define_insn "*movsf_insn"
1921 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
1922 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
1924 && (register_operand (operands[0], <V32:MODE>mode)
1925 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
1927 if (GET_CODE (operands[1]) == CONST_DOUBLE
1928 && (which_alternative == 2
1929 || which_alternative == 3
1930 || which_alternative == 4))
1935 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1936 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1937 operands[1] = GEN_INT (i);
1940 switch (which_alternative)
1943 return "fzeros\t%0";
1945 return "fmovs\t%1, %0";
1947 return "mov\t%1, %0";
1949 return "sethi\t%%hi(%a1), %0";
1954 return "ld\t%1, %0";
1957 return "st\t%r1, %0";
1962 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1964 ;; Exactly the same as above, except that all `f' cases are deleted.
1965 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1968 (define_insn "*movsf_insn_no_fpu"
1969 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1970 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1972 && (register_operand (operands[0], SFmode)
1973 || register_or_zero_operand (operands[1], SFmode))"
1975 if (GET_CODE (operands[1]) == CONST_DOUBLE
1976 && (which_alternative == 0
1977 || which_alternative == 1
1978 || which_alternative == 2))
1983 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1984 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1985 operands[1] = GEN_INT (i);
1988 switch (which_alternative)
1991 return "mov\t%1, %0";
1993 return "sethi\t%%hi(%a1), %0";
1997 return "ld\t%1, %0";
1999 return "st\t%r1, %0";
2004 [(set_attr "type" "*,*,*,load,store")])
2006 ;; The following 3 patterns build SFmode constants in integer registers.
2008 (define_insn "*movsf_lo_sum"
2009 [(set (match_operand:SF 0 "register_operand" "=r")
2010 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2011 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2017 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2018 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2019 operands[2] = GEN_INT (i);
2020 return "or\t%1, %%lo(%a2), %0";
2023 (define_insn "*movsf_high"
2024 [(set (match_operand:SF 0 "register_operand" "=r")
2025 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2031 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2032 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2033 operands[1] = GEN_INT (i);
2034 return "sethi\t%%hi(%1), %0";
2038 [(set (match_operand:SF 0 "register_operand" "")
2039 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2040 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2041 [(set (match_dup 0) (high:SF (match_dup 1)))
2042 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2044 ;; Yes, you again guessed it right, the former movdf expander.
2045 (define_expand "mov<V64:mode>"
2046 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2047 (match_operand:V64 1 "general_operand" ""))]
2048 "<V64:MODE>mode == DFmode || TARGET_VIS"
2050 if (sparc_expand_move (<V64:MODE>mode, operands))
2054 ;; Be careful, fmovd does not exist when !v9.
2055 (define_insn "*movdf_insn_sp32"
2056 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2057 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2060 && (register_operand (operands[0], DFmode)
2061 || register_or_zero_operand (operands[1], DFmode))"
2073 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2074 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2076 (define_insn "*movdf_insn_sp32_no_fpu"
2077 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2078 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2081 && (register_operand (operands[0], DFmode)
2082 || register_or_zero_operand (operands[1], DFmode))"
2089 [(set_attr "type" "load,store,*,*,*")
2090 (set_attr "length" "*,*,2,2,2")])
2092 ;; We have available v9 double floats but not 64-bit integer registers.
2093 (define_insn "*movdf_insn_sp32_v9"
2094 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2095 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2099 && (register_operand (operands[0], <V64:MODE>mode)
2100 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2112 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2113 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2114 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2116 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2117 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2118 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2122 && (register_operand (operands[0], DFmode)
2123 || register_or_zero_operand (operands[1], DFmode))"
2130 [(set_attr "type" "load,store,store,*,*")
2131 (set_attr "length" "*,*,*,2,2")])
2133 ;; We have available both v9 double floats and 64-bit integer registers.
2134 (define_insn "*movdf_insn_sp64"
2135 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2136 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
2139 && (register_operand (operands[0], <V64:MODE>mode)
2140 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2150 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2151 (set_attr "length" "*,*,*,*,*,*,*,2")
2152 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2154 (define_insn "*movdf_insn_sp64_no_fpu"
2155 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2156 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2159 && (register_operand (operands[0], DFmode)
2160 || register_or_zero_operand (operands[1], DFmode))"
2165 [(set_attr "type" "*,load,store")])
2167 ;; This pattern builds V64mode constants in integer registers.
2169 [(set (match_operand:V64 0 "register_operand" "")
2170 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2172 && (GET_CODE (operands[0]) == REG
2173 && REGNO (operands[0]) < 32)
2174 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2175 && reload_completed"
2176 [(clobber (const_int 0))]
2178 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2182 #if HOST_BITS_PER_WIDE_INT == 32
2185 enum machine_mode mode = GET_MODE (operands[1]);
2186 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2187 emit_insn (gen_movdi (operands[0], tem));
2192 enum machine_mode mode = GET_MODE (operands[1]);
2193 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2194 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2196 gcc_assert (GET_CODE (hi) == CONST_INT);
2197 gcc_assert (GET_CODE (lo) == CONST_INT);
2199 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2201 /* Slick... but this trick loses if this subreg constant part
2202 can be done in one insn. */
2204 && ! SPARC_SETHI32_P (INTVAL (hi))
2205 && ! SPARC_SIMM13_P (INTVAL (hi)))
2207 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2208 gen_highpart (SImode, operands[0])));
2212 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2218 ;; Ok, now the splits to handle all the multi insn and
2219 ;; mis-aligned memory address cases.
2220 ;; In these splits please take note that we must be
2221 ;; careful when V9 but not ARCH64 because the integer
2222 ;; register DFmode cases must be handled.
2224 [(set (match_operand:V64 0 "register_operand" "")
2225 (match_operand:V64 1 "register_operand" ""))]
2228 && ((GET_CODE (operands[0]) == REG
2229 && REGNO (operands[0]) < 32)
2230 || (GET_CODE (operands[0]) == SUBREG
2231 && GET_CODE (SUBREG_REG (operands[0])) == REG
2232 && REGNO (SUBREG_REG (operands[0])) < 32))))
2233 && reload_completed"
2234 [(clobber (const_int 0))]
2236 rtx set_dest = operands[0];
2237 rtx set_src = operands[1];
2240 enum machine_mode half_mode;
2242 /* We can be expanded for DFmode or integral vector modes. */
2243 if (<V64:MODE>mode == DFmode)
2248 dest1 = gen_highpart (half_mode, set_dest);
2249 dest2 = gen_lowpart (half_mode, set_dest);
2250 src1 = gen_highpart (half_mode, set_src);
2251 src2 = gen_lowpart (half_mode, set_src);
2253 /* Now emit using the real source and destination we found, swapping
2254 the order if we detect overlap. */
2255 if (reg_overlap_mentioned_p (dest1, src2))
2257 emit_move_insn_1 (dest2, src2);
2258 emit_move_insn_1 (dest1, src1);
2262 emit_move_insn_1 (dest1, src1);
2263 emit_move_insn_1 (dest2, src2);
2269 [(set (match_operand:V64 0 "register_operand" "")
2270 (match_operand:V64 1 "memory_operand" ""))]
2273 && (((REGNO (operands[0]) % 2) != 0)
2274 || ! mem_min_alignment (operands[1], 8))
2275 && offsettable_memref_p (operands[1])"
2276 [(clobber (const_int 0))]
2278 enum machine_mode half_mode;
2281 /* We can be expanded for DFmode or integral vector modes. */
2282 if (<V64:MODE>mode == DFmode)
2287 word0 = adjust_address (operands[1], half_mode, 0);
2288 word1 = adjust_address (operands[1], half_mode, 4);
2290 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2292 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2293 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2297 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2298 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2304 [(set (match_operand:V64 0 "memory_operand" "")
2305 (match_operand:V64 1 "register_operand" ""))]
2308 && (((REGNO (operands[1]) % 2) != 0)
2309 || ! mem_min_alignment (operands[0], 8))
2310 && offsettable_memref_p (operands[0])"
2311 [(clobber (const_int 0))]
2313 enum machine_mode half_mode;
2316 /* We can be expanded for DFmode or integral vector modes. */
2317 if (<V64:MODE>mode == DFmode)
2322 word0 = adjust_address (operands[0], half_mode, 0);
2323 word1 = adjust_address (operands[0], half_mode, 4);
2325 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2326 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2331 [(set (match_operand:V64 0 "memory_operand" "")
2332 (match_operand:V64 1 "const_zero_operand" ""))]
2336 && ! mem_min_alignment (operands[0], 8)))
2337 && offsettable_memref_p (operands[0])"
2338 [(clobber (const_int 0))]
2340 enum machine_mode half_mode;
2343 /* We can be expanded for DFmode or integral vector modes. */
2344 if (<V64:MODE>mode == DFmode)
2349 dest1 = adjust_address (operands[0], half_mode, 0);
2350 dest2 = adjust_address (operands[0], half_mode, 4);
2352 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2353 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2358 [(set (match_operand:V64 0 "register_operand" "")
2359 (match_operand:V64 1 "const_zero_operand" ""))]
2362 && ((GET_CODE (operands[0]) == REG
2363 && REGNO (operands[0]) < 32)
2364 || (GET_CODE (operands[0]) == SUBREG
2365 && GET_CODE (SUBREG_REG (operands[0])) == REG
2366 && REGNO (SUBREG_REG (operands[0])) < 32))"
2367 [(clobber (const_int 0))]
2369 enum machine_mode half_mode;
2370 rtx set_dest = operands[0];
2373 /* We can be expanded for DFmode or integral vector modes. */
2374 if (<V64:MODE>mode == DFmode)
2379 dest1 = gen_highpart (half_mode, set_dest);
2380 dest2 = gen_lowpart (half_mode, set_dest);
2381 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2382 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2386 (define_expand "movtf"
2387 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2388 (match_operand:TF 1 "general_operand" ""))]
2391 if (sparc_expand_move (TFmode, operands))
2395 (define_insn "*movtf_insn_sp32"
2396 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2397 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2400 && (register_operand (operands[0], TFmode)
2401 || register_or_zero_operand (operands[1], TFmode))"
2403 [(set_attr "length" "4")])
2405 ;; Exactly the same as above, except that all `e' cases are deleted.
2406 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2409 (define_insn "*movtf_insn_sp32_no_fpu"
2410 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2411 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2414 && (register_operand (operands[0], TFmode)
2415 || register_or_zero_operand (operands[1], TFmode))"
2417 [(set_attr "length" "4")])
2419 (define_insn "*movtf_insn_sp64"
2420 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2421 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2424 && ! TARGET_HARD_QUAD
2425 && (register_operand (operands[0], TFmode)
2426 || register_or_zero_operand (operands[1], TFmode))"
2428 [(set_attr "length" "2")])
2430 (define_insn "*movtf_insn_sp64_hq"
2431 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2432 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2436 && (register_operand (operands[0], TFmode)
2437 || register_or_zero_operand (operands[1], TFmode))"
2445 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2446 (set_attr "length" "2,*,*,*,2,2")])
2448 (define_insn "*movtf_insn_sp64_no_fpu"
2449 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2450 (match_operand:TF 1 "input_operand" "orG,rG"))]
2453 && (register_operand (operands[0], TFmode)
2454 || register_or_zero_operand (operands[1], TFmode))"
2456 [(set_attr "length" "2")])
2458 ;; Now all the splits to handle multi-insn TF mode moves.
2460 [(set (match_operand:TF 0 "register_operand" "")
2461 (match_operand:TF 1 "register_operand" ""))]
2465 && ! TARGET_HARD_QUAD)
2466 || ! fp_register_operand (operands[0], TFmode))"
2467 [(clobber (const_int 0))]
2469 rtx set_dest = operands[0];
2470 rtx set_src = operands[1];
2474 dest1 = gen_df_reg (set_dest, 0);
2475 dest2 = gen_df_reg (set_dest, 1);
2476 src1 = gen_df_reg (set_src, 0);
2477 src2 = gen_df_reg (set_src, 1);
2479 /* Now emit using the real source and destination we found, swapping
2480 the order if we detect overlap. */
2481 if (reg_overlap_mentioned_p (dest1, src2))
2483 emit_insn (gen_movdf (dest2, src2));
2484 emit_insn (gen_movdf (dest1, src1));
2488 emit_insn (gen_movdf (dest1, src1));
2489 emit_insn (gen_movdf (dest2, src2));
2495 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2496 (match_operand:TF 1 "const_zero_operand" ""))]
2498 [(clobber (const_int 0))]
2500 rtx set_dest = operands[0];
2503 switch (GET_CODE (set_dest))
2506 dest1 = gen_df_reg (set_dest, 0);
2507 dest2 = gen_df_reg (set_dest, 1);
2510 dest1 = adjust_address (set_dest, DFmode, 0);
2511 dest2 = adjust_address (set_dest, DFmode, 8);
2517 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2518 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2523 [(set (match_operand:TF 0 "register_operand" "")
2524 (match_operand:TF 1 "memory_operand" ""))]
2526 && offsettable_memref_p (operands[1])
2528 || ! TARGET_HARD_QUAD
2529 || ! fp_register_operand (operands[0], TFmode)))"
2530 [(clobber (const_int 0))]
2532 rtx word0 = adjust_address (operands[1], DFmode, 0);
2533 rtx word1 = adjust_address (operands[1], DFmode, 8);
2534 rtx set_dest, dest1, dest2;
2536 set_dest = operands[0];
2538 dest1 = gen_df_reg (set_dest, 0);
2539 dest2 = gen_df_reg (set_dest, 1);
2541 /* Now output, ordering such that we don't clobber any registers
2542 mentioned in the address. */
2543 if (reg_overlap_mentioned_p (dest1, word1))
2546 emit_insn (gen_movdf (dest2, word1));
2547 emit_insn (gen_movdf (dest1, word0));
2551 emit_insn (gen_movdf (dest1, word0));
2552 emit_insn (gen_movdf (dest2, word1));
2558 [(set (match_operand:TF 0 "memory_operand" "")
2559 (match_operand:TF 1 "register_operand" ""))]
2561 && offsettable_memref_p (operands[0])
2563 || ! TARGET_HARD_QUAD
2564 || ! fp_register_operand (operands[1], TFmode)))"
2565 [(clobber (const_int 0))]
2567 rtx set_src = operands[1];
2569 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2570 gen_df_reg (set_src, 0)));
2571 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2572 gen_df_reg (set_src, 1)));
2577 ;; SPARC-V9 conditional move instructions
2579 ;; We can handle larger constants here for some flavors, but for now we keep
2580 ;; it simple and only allow those constants supported by all flavors.
2581 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2582 ;; 3 contains the constant if one is present, but we handle either for
2583 ;; generality (sparc.c puts a constant in operand 2).
2585 (define_expand "mov<I:mode>cc"
2586 [(set (match_operand:I 0 "register_operand" "")
2587 (if_then_else:I (match_operand 1 "comparison_operator" "")
2588 (match_operand:I 2 "arith10_operand" "")
2589 (match_operand:I 3 "arith10_operand" "")))]
2590 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2592 enum rtx_code code = GET_CODE (operands[1]);
2595 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2599 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2601 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2602 GET_CODE (operands[1]));
2604 if (XEXP (operands[1], 1) == const0_rtx
2605 && GET_CODE (XEXP (operands[1], 0)) == REG
2606 && GET_MODE (XEXP (operands[1], 0)) == DImode
2607 && v9_regcmp_p (code))
2608 cc_reg = XEXP (operands[1], 0);
2610 cc_reg = gen_compare_reg (operands[1]);
2612 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2615 (define_expand "mov<F:mode>cc"
2616 [(set (match_operand:F 0 "register_operand" "")
2617 (if_then_else:F (match_operand 1 "comparison_operator" "")
2618 (match_operand:F 2 "register_operand" "")
2619 (match_operand:F 3 "register_operand" "")))]
2620 "TARGET_V9 && TARGET_FPU"
2622 enum rtx_code code = GET_CODE (operands[1]);
2625 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2629 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2631 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2632 GET_CODE (operands[1]));
2634 if (XEXP (operands[1], 1) == const0_rtx
2635 && GET_CODE (XEXP (operands[1], 0)) == REG
2636 && GET_MODE (XEXP (operands[1], 0)) == DImode
2637 && v9_regcmp_p (code))
2638 cc_reg = XEXP (operands[1], 0);
2640 cc_reg = gen_compare_reg (operands[1]);
2642 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2645 ;; Conditional move define_insns
2647 (define_insn "*mov<I:mode>_cc_v9"
2648 [(set (match_operand:I 0 "register_operand" "=r,r")
2649 (if_then_else:I (match_operator 1 "comparison_operator"
2650 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2652 (match_operand:I 3 "arith11_operand" "rL,0")
2653 (match_operand:I 4 "arith11_operand" "0,rL")))]
2654 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2657 mov%c1\t%x2, %4, %0"
2658 [(set_attr "type" "cmove")])
2660 (define_insn "*mov<I:mode>_cc_reg_sp64"
2661 [(set (match_operand:I 0 "register_operand" "=r,r")
2662 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2663 [(match_operand:DI 2 "register_operand" "r,r")
2665 (match_operand:I 3 "arith10_operand" "rM,0")
2666 (match_operand:I 4 "arith10_operand" "0,rM")))]
2669 movr%D1\t%2, %r3, %0
2670 movr%d1\t%2, %r4, %0"
2671 [(set_attr "type" "cmove")])
2673 (define_insn "*movsf_cc_v9"
2674 [(set (match_operand:SF 0 "register_operand" "=f,f")
2675 (if_then_else:SF (match_operator 1 "comparison_operator"
2676 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2678 (match_operand:SF 3 "register_operand" "f,0")
2679 (match_operand:SF 4 "register_operand" "0,f")))]
2680 "TARGET_V9 && TARGET_FPU"
2682 fmovs%C1\t%x2, %3, %0
2683 fmovs%c1\t%x2, %4, %0"
2684 [(set_attr "type" "fpcmove")])
2686 (define_insn "*movsf_cc_reg_sp64"
2687 [(set (match_operand:SF 0 "register_operand" "=f,f")
2688 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2689 [(match_operand:DI 2 "register_operand" "r,r")
2691 (match_operand:SF 3 "register_operand" "f,0")
2692 (match_operand:SF 4 "register_operand" "0,f")))]
2693 "TARGET_ARCH64 && TARGET_FPU"
2695 fmovrs%D1\t%2, %3, %0
2696 fmovrs%d1\t%2, %4, %0"
2697 [(set_attr "type" "fpcrmove")])
2699 ;; Named because invoked by movtf_cc_v9
2700 (define_insn "movdf_cc_v9"
2701 [(set (match_operand:DF 0 "register_operand" "=e,e")
2702 (if_then_else:DF (match_operator 1 "comparison_operator"
2703 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2705 (match_operand:DF 3 "register_operand" "e,0")
2706 (match_operand:DF 4 "register_operand" "0,e")))]
2707 "TARGET_V9 && TARGET_FPU"
2709 fmovd%C1\t%x2, %3, %0
2710 fmovd%c1\t%x2, %4, %0"
2711 [(set_attr "type" "fpcmove")
2712 (set_attr "fptype" "double")])
2714 ;; Named because invoked by movtf_cc_reg_sp64
2715 (define_insn "movdf_cc_reg_sp64"
2716 [(set (match_operand:DF 0 "register_operand" "=e,e")
2717 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2718 [(match_operand:DI 2 "register_operand" "r,r")
2720 (match_operand:DF 3 "register_operand" "e,0")
2721 (match_operand:DF 4 "register_operand" "0,e")))]
2722 "TARGET_ARCH64 && TARGET_FPU"
2724 fmovrd%D1\t%2, %3, %0
2725 fmovrd%d1\t%2, %4, %0"
2726 [(set_attr "type" "fpcrmove")
2727 (set_attr "fptype" "double")])
2729 (define_insn "*movtf_cc_hq_v9"
2730 [(set (match_operand:TF 0 "register_operand" "=e,e")
2731 (if_then_else:TF (match_operator 1 "comparison_operator"
2732 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2734 (match_operand:TF 3 "register_operand" "e,0")
2735 (match_operand:TF 4 "register_operand" "0,e")))]
2736 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2738 fmovq%C1\t%x2, %3, %0
2739 fmovq%c1\t%x2, %4, %0"
2740 [(set_attr "type" "fpcmove")])
2742 (define_insn "*movtf_cc_reg_hq_sp64"
2743 [(set (match_operand:TF 0 "register_operand" "=e,e")
2744 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2745 [(match_operand:DI 2 "register_operand" "r,r")
2747 (match_operand:TF 3 "register_operand" "e,0")
2748 (match_operand:TF 4 "register_operand" "0,e")))]
2749 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2751 fmovrq%D1\t%2, %3, %0
2752 fmovrq%d1\t%2, %4, %0"
2753 [(set_attr "type" "fpcrmove")])
2755 (define_insn_and_split "*movtf_cc_v9"
2756 [(set (match_operand:TF 0 "register_operand" "=e,e")
2757 (if_then_else:TF (match_operator 1 "comparison_operator"
2758 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2760 (match_operand:TF 3 "register_operand" "e,0")
2761 (match_operand:TF 4 "register_operand" "0,e")))]
2762 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2764 "&& reload_completed"
2765 [(clobber (const_int 0))]
2767 rtx set_dest = operands[0];
2768 rtx set_srca = operands[3];
2769 rtx set_srcb = operands[4];
2770 int third = rtx_equal_p (set_dest, set_srca);
2772 rtx srca1, srca2, srcb1, srcb2;
2774 dest1 = gen_df_reg (set_dest, 0);
2775 dest2 = gen_df_reg (set_dest, 1);
2776 srca1 = gen_df_reg (set_srca, 0);
2777 srca2 = gen_df_reg (set_srca, 1);
2778 srcb1 = gen_df_reg (set_srcb, 0);
2779 srcb2 = gen_df_reg (set_srcb, 1);
2781 /* Now emit using the real source and destination we found, swapping
2782 the order if we detect overlap. */
2783 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2784 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2786 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2787 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2791 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2792 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2796 [(set_attr "length" "2")])
2798 (define_insn_and_split "*movtf_cc_reg_sp64"
2799 [(set (match_operand:TF 0 "register_operand" "=e,e")
2800 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2801 [(match_operand:DI 2 "register_operand" "r,r")
2803 (match_operand:TF 3 "register_operand" "e,0")
2804 (match_operand:TF 4 "register_operand" "0,e")))]
2805 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2807 "&& reload_completed"
2808 [(clobber (const_int 0))]
2810 rtx set_dest = operands[0];
2811 rtx set_srca = operands[3];
2812 rtx set_srcb = operands[4];
2813 int third = rtx_equal_p (set_dest, set_srca);
2815 rtx srca1, srca2, srcb1, srcb2;
2817 dest1 = gen_df_reg (set_dest, 0);
2818 dest2 = gen_df_reg (set_dest, 1);
2819 srca1 = gen_df_reg (set_srca, 0);
2820 srca2 = gen_df_reg (set_srca, 1);
2821 srcb1 = gen_df_reg (set_srcb, 0);
2822 srcb2 = gen_df_reg (set_srcb, 1);
2824 /* Now emit using the real source and destination we found, swapping
2825 the order if we detect overlap. */
2826 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2827 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2829 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2830 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2834 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2835 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2839 [(set_attr "length" "2")])
2842 ;; Zero-extension instructions
2844 ;; These patterns originally accepted general_operands, however, slightly
2845 ;; better code is generated by only accepting register_operands, and then
2846 ;; letting combine generate the ldu[hb] insns.
2848 (define_expand "zero_extendhisi2"
2849 [(set (match_operand:SI 0 "register_operand" "")
2850 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2853 rtx temp = gen_reg_rtx (SImode);
2854 rtx shift_16 = GEN_INT (16);
2855 int op1_subbyte = 0;
2857 if (GET_CODE (operand1) == SUBREG)
2859 op1_subbyte = SUBREG_BYTE (operand1);
2860 op1_subbyte /= GET_MODE_SIZE (SImode);
2861 op1_subbyte *= GET_MODE_SIZE (SImode);
2862 operand1 = XEXP (operand1, 0);
2865 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2867 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2871 (define_insn "*zero_extendhisi2_insn"
2872 [(set (match_operand:SI 0 "register_operand" "=r")
2873 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2876 [(set_attr "type" "load")
2877 (set_attr "us3load_type" "3cycle")])
2879 (define_expand "zero_extendqihi2"
2880 [(set (match_operand:HI 0 "register_operand" "")
2881 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2885 (define_insn "*zero_extendqihi2_insn"
2886 [(set (match_operand:HI 0 "register_operand" "=r,r")
2887 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2888 "GET_CODE (operands[1]) != CONST_INT"
2892 [(set_attr "type" "*,load")
2893 (set_attr "us3load_type" "*,3cycle")])
2895 (define_expand "zero_extendqisi2"
2896 [(set (match_operand:SI 0 "register_operand" "")
2897 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2901 (define_insn "*zero_extendqisi2_insn"
2902 [(set (match_operand:SI 0 "register_operand" "=r,r")
2903 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2904 "GET_CODE (operands[1]) != CONST_INT"
2908 [(set_attr "type" "*,load")
2909 (set_attr "us3load_type" "*,3cycle")])
2911 (define_expand "zero_extendqidi2"
2912 [(set (match_operand:DI 0 "register_operand" "")
2913 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2917 (define_insn "*zero_extendqidi2_insn"
2918 [(set (match_operand:DI 0 "register_operand" "=r,r")
2919 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2920 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2924 [(set_attr "type" "*,load")
2925 (set_attr "us3load_type" "*,3cycle")])
2927 (define_expand "zero_extendhidi2"
2928 [(set (match_operand:DI 0 "register_operand" "")
2929 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2932 rtx temp = gen_reg_rtx (DImode);
2933 rtx shift_48 = GEN_INT (48);
2934 int op1_subbyte = 0;
2936 if (GET_CODE (operand1) == SUBREG)
2938 op1_subbyte = SUBREG_BYTE (operand1);
2939 op1_subbyte /= GET_MODE_SIZE (DImode);
2940 op1_subbyte *= GET_MODE_SIZE (DImode);
2941 operand1 = XEXP (operand1, 0);
2944 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2946 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2950 (define_insn "*zero_extendhidi2_insn"
2951 [(set (match_operand:DI 0 "register_operand" "=r")
2952 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2955 [(set_attr "type" "load")
2956 (set_attr "us3load_type" "3cycle")])
2958 ;; ??? Write truncdisi pattern using sra?
2960 (define_expand "zero_extendsidi2"
2961 [(set (match_operand:DI 0 "register_operand" "")
2962 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2966 (define_insn "*zero_extendsidi2_insn_sp64"
2967 [(set (match_operand:DI 0 "register_operand" "=r,r")
2968 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2969 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2973 [(set_attr "type" "shift,load")])
2975 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2976 [(set (match_operand:DI 0 "register_operand" "=r")
2977 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2980 "&& reload_completed"
2981 [(set (match_dup 2) (match_dup 3))
2982 (set (match_dup 4) (match_dup 5))]
2986 dest1 = gen_highpart (SImode, operands[0]);
2987 dest2 = gen_lowpart (SImode, operands[0]);
2989 /* Swap the order in case of overlap. */
2990 if (REGNO (dest1) == REGNO (operands[1]))
2992 operands[2] = dest2;
2993 operands[3] = operands[1];
2994 operands[4] = dest1;
2995 operands[5] = const0_rtx;
2999 operands[2] = dest1;
3000 operands[3] = const0_rtx;
3001 operands[4] = dest2;
3002 operands[5] = operands[1];
3005 [(set_attr "length" "2")])
3007 ;; Simplify comparisons of extended values.
3009 (define_insn "*cmp_zero_extendqisi2"
3010 [(set (reg:CC CC_REG)
3011 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3014 "andcc\t%0, 0xff, %%g0"
3015 [(set_attr "type" "compare")])
3017 (define_insn "*cmp_zero_qi"
3018 [(set (reg:CC CC_REG)
3019 (compare:CC (match_operand:QI 0 "register_operand" "r")
3022 "andcc\t%0, 0xff, %%g0"
3023 [(set_attr "type" "compare")])
3025 (define_insn "*cmp_zero_extendqisi2_set"
3026 [(set (reg:CC CC_REG)
3027 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3029 (set (match_operand:SI 0 "register_operand" "=r")
3030 (zero_extend:SI (match_dup 1)))]
3032 "andcc\t%1, 0xff, %0"
3033 [(set_attr "type" "compare")])
3035 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3036 [(set (reg:CC CC_REG)
3037 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3040 (set (match_operand:SI 0 "register_operand" "=r")
3041 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3043 "andcc\t%1, 0xff, %0"
3044 [(set_attr "type" "compare")])
3046 (define_insn "*cmp_zero_extendqidi2"
3047 [(set (reg:CCX CC_REG)
3048 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3051 "andcc\t%0, 0xff, %%g0"
3052 [(set_attr "type" "compare")])
3054 (define_insn "*cmp_zero_qi_sp64"
3055 [(set (reg:CCX CC_REG)
3056 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3059 "andcc\t%0, 0xff, %%g0"
3060 [(set_attr "type" "compare")])
3062 (define_insn "*cmp_zero_extendqidi2_set"
3063 [(set (reg:CCX CC_REG)
3064 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3066 (set (match_operand:DI 0 "register_operand" "=r")
3067 (zero_extend:DI (match_dup 1)))]
3069 "andcc\t%1, 0xff, %0"
3070 [(set_attr "type" "compare")])
3072 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3073 [(set (reg:CCX CC_REG)
3074 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3077 (set (match_operand:DI 0 "register_operand" "=r")
3078 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3080 "andcc\t%1, 0xff, %0"
3081 [(set_attr "type" "compare")])
3083 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3085 (define_insn "*cmp_siqi_trunc"
3086 [(set (reg:CC CC_REG)
3087 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3090 "andcc\t%0, 0xff, %%g0"
3091 [(set_attr "type" "compare")])
3093 (define_insn "*cmp_siqi_trunc_set"
3094 [(set (reg:CC CC_REG)
3095 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3097 (set (match_operand:QI 0 "register_operand" "=r")
3098 (subreg:QI (match_dup 1) 3))]
3100 "andcc\t%1, 0xff, %0"
3101 [(set_attr "type" "compare")])
3103 (define_insn "*cmp_diqi_trunc"
3104 [(set (reg:CC CC_REG)
3105 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3108 "andcc\t%0, 0xff, %%g0"
3109 [(set_attr "type" "compare")])
3111 (define_insn "*cmp_diqi_trunc_set"
3112 [(set (reg:CC CC_REG)
3113 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3115 (set (match_operand:QI 0 "register_operand" "=r")
3116 (subreg:QI (match_dup 1) 7))]
3118 "andcc\t%1, 0xff, %0"
3119 [(set_attr "type" "compare")])
3122 ;; Sign-extension instructions
3124 ;; These patterns originally accepted general_operands, however, slightly
3125 ;; better code is generated by only accepting register_operands, and then
3126 ;; letting combine generate the lds[hb] insns.
3128 (define_expand "extendhisi2"
3129 [(set (match_operand:SI 0 "register_operand" "")
3130 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3133 rtx temp = gen_reg_rtx (SImode);
3134 rtx shift_16 = GEN_INT (16);
3135 int op1_subbyte = 0;
3137 if (GET_CODE (operand1) == SUBREG)
3139 op1_subbyte = SUBREG_BYTE (operand1);
3140 op1_subbyte /= GET_MODE_SIZE (SImode);
3141 op1_subbyte *= GET_MODE_SIZE (SImode);
3142 operand1 = XEXP (operand1, 0);
3145 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3147 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3151 (define_insn "*sign_extendhisi2_insn"
3152 [(set (match_operand:SI 0 "register_operand" "=r")
3153 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3156 [(set_attr "type" "sload")
3157 (set_attr "us3load_type" "3cycle")])
3159 (define_expand "extendqihi2"
3160 [(set (match_operand:HI 0 "register_operand" "")
3161 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3164 rtx temp = gen_reg_rtx (SImode);
3165 rtx shift_24 = GEN_INT (24);
3166 int op1_subbyte = 0;
3167 int op0_subbyte = 0;
3169 if (GET_CODE (operand1) == SUBREG)
3171 op1_subbyte = SUBREG_BYTE (operand1);
3172 op1_subbyte /= GET_MODE_SIZE (SImode);
3173 op1_subbyte *= GET_MODE_SIZE (SImode);
3174 operand1 = XEXP (operand1, 0);
3176 if (GET_CODE (operand0) == SUBREG)
3178 op0_subbyte = SUBREG_BYTE (operand0);
3179 op0_subbyte /= GET_MODE_SIZE (SImode);
3180 op0_subbyte *= GET_MODE_SIZE (SImode);
3181 operand0 = XEXP (operand0, 0);
3183 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3185 if (GET_MODE (operand0) != SImode)
3186 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3187 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3191 (define_insn "*sign_extendqihi2_insn"
3192 [(set (match_operand:HI 0 "register_operand" "=r")
3193 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3196 [(set_attr "type" "sload")
3197 (set_attr "us3load_type" "3cycle")])
3199 (define_expand "extendqisi2"
3200 [(set (match_operand:SI 0 "register_operand" "")
3201 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3204 rtx temp = gen_reg_rtx (SImode);
3205 rtx shift_24 = GEN_INT (24);
3206 int op1_subbyte = 0;
3208 if (GET_CODE (operand1) == SUBREG)
3210 op1_subbyte = SUBREG_BYTE (operand1);
3211 op1_subbyte /= GET_MODE_SIZE (SImode);
3212 op1_subbyte *= GET_MODE_SIZE (SImode);
3213 operand1 = XEXP (operand1, 0);
3216 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3218 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3222 (define_insn "*sign_extendqisi2_insn"
3223 [(set (match_operand:SI 0 "register_operand" "=r")
3224 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3227 [(set_attr "type" "sload")
3228 (set_attr "us3load_type" "3cycle")])
3230 (define_expand "extendqidi2"
3231 [(set (match_operand:DI 0 "register_operand" "")
3232 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3235 rtx temp = gen_reg_rtx (DImode);
3236 rtx shift_56 = GEN_INT (56);
3237 int op1_subbyte = 0;
3239 if (GET_CODE (operand1) == SUBREG)
3241 op1_subbyte = SUBREG_BYTE (operand1);
3242 op1_subbyte /= GET_MODE_SIZE (DImode);
3243 op1_subbyte *= GET_MODE_SIZE (DImode);
3244 operand1 = XEXP (operand1, 0);
3247 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3249 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3253 (define_insn "*sign_extendqidi2_insn"
3254 [(set (match_operand:DI 0 "register_operand" "=r")
3255 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3258 [(set_attr "type" "sload")
3259 (set_attr "us3load_type" "3cycle")])
3261 (define_expand "extendhidi2"
3262 [(set (match_operand:DI 0 "register_operand" "")
3263 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3266 rtx temp = gen_reg_rtx (DImode);
3267 rtx shift_48 = GEN_INT (48);
3268 int op1_subbyte = 0;
3270 if (GET_CODE (operand1) == SUBREG)
3272 op1_subbyte = SUBREG_BYTE (operand1);
3273 op1_subbyte /= GET_MODE_SIZE (DImode);
3274 op1_subbyte *= GET_MODE_SIZE (DImode);
3275 operand1 = XEXP (operand1, 0);
3278 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3280 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3284 (define_insn "*sign_extendhidi2_insn"
3285 [(set (match_operand:DI 0 "register_operand" "=r")
3286 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3289 [(set_attr "type" "sload")
3290 (set_attr "us3load_type" "3cycle")])
3292 (define_expand "extendsidi2"
3293 [(set (match_operand:DI 0 "register_operand" "")
3294 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3298 (define_insn "*sign_extendsidi2_insn"
3299 [(set (match_operand:DI 0 "register_operand" "=r,r")
3300 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3305 [(set_attr "type" "shift,sload")
3306 (set_attr "us3load_type" "*,3cycle")])
3309 ;; Special pattern for optimizing bit-field compares. This is needed
3310 ;; because combine uses this as a canonical form.
3312 (define_insn "*cmp_zero_extract"
3313 [(set (reg:CC CC_REG)
3315 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3316 (match_operand:SI 1 "small_int_operand" "I")
3317 (match_operand:SI 2 "small_int_operand" "I"))
3319 "INTVAL (operands[2]) > 19"
3321 int len = INTVAL (operands[1]);
3322 int pos = 32 - INTVAL (operands[2]) - len;
3323 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3324 operands[1] = GEN_INT (mask);
3325 return "andcc\t%0, %1, %%g0";
3327 [(set_attr "type" "compare")])
3329 (define_insn "*cmp_zero_extract_sp64"
3330 [(set (reg:CCX CC_REG)
3332 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3333 (match_operand:SI 1 "small_int_operand" "I")
3334 (match_operand:SI 2 "small_int_operand" "I"))
3336 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3338 int len = INTVAL (operands[1]);
3339 int pos = 64 - INTVAL (operands[2]) - len;
3340 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3341 operands[1] = GEN_INT (mask);
3342 return "andcc\t%0, %1, %%g0";
3344 [(set_attr "type" "compare")])
3347 ;; Conversions between float, double and long double.
3349 (define_insn "extendsfdf2"
3350 [(set (match_operand:DF 0 "register_operand" "=e")
3352 (match_operand:SF 1 "register_operand" "f")))]
3355 [(set_attr "type" "fp")
3356 (set_attr "fptype" "double")])
3358 (define_expand "extendsftf2"
3359 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3361 (match_operand:SF 1 "register_operand" "")))]
3362 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3363 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3365 (define_insn "*extendsftf2_hq"
3366 [(set (match_operand:TF 0 "register_operand" "=e")
3368 (match_operand:SF 1 "register_operand" "f")))]
3369 "TARGET_FPU && TARGET_HARD_QUAD"
3371 [(set_attr "type" "fp")])
3373 (define_expand "extenddftf2"
3374 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3376 (match_operand:DF 1 "register_operand" "")))]
3377 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3378 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3380 (define_insn "*extenddftf2_hq"
3381 [(set (match_operand:TF 0 "register_operand" "=e")
3383 (match_operand:DF 1 "register_operand" "e")))]
3384 "TARGET_FPU && TARGET_HARD_QUAD"
3386 [(set_attr "type" "fp")])
3388 (define_insn "truncdfsf2"
3389 [(set (match_operand:SF 0 "register_operand" "=f")
3391 (match_operand:DF 1 "register_operand" "e")))]
3394 [(set_attr "type" "fp")
3395 (set_attr "fptype" "double")])
3397 (define_expand "trunctfsf2"
3398 [(set (match_operand:SF 0 "register_operand" "")
3400 (match_operand:TF 1 "general_operand" "")))]
3401 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3402 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3404 (define_insn "*trunctfsf2_hq"
3405 [(set (match_operand:SF 0 "register_operand" "=f")
3407 (match_operand:TF 1 "register_operand" "e")))]
3408 "TARGET_FPU && TARGET_HARD_QUAD"
3410 [(set_attr "type" "fp")])
3412 (define_expand "trunctfdf2"
3413 [(set (match_operand:DF 0 "register_operand" "")
3415 (match_operand:TF 1 "general_operand" "")))]
3416 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3417 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3419 (define_insn "*trunctfdf2_hq"
3420 [(set (match_operand:DF 0 "register_operand" "=e")
3422 (match_operand:TF 1 "register_operand" "e")))]
3423 "TARGET_FPU && TARGET_HARD_QUAD"
3425 [(set_attr "type" "fp")])
3428 ;; Conversion between fixed point and floating point.
3430 (define_insn "floatsisf2"
3431 [(set (match_operand:SF 0 "register_operand" "=f")
3432 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3435 [(set_attr "type" "fp")
3436 (set_attr "fptype" "double")])
3438 (define_insn "floatsidf2"
3439 [(set (match_operand:DF 0 "register_operand" "=e")
3440 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3443 [(set_attr "type" "fp")
3444 (set_attr "fptype" "double")])
3446 (define_expand "floatsitf2"
3447 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3448 (float:TF (match_operand:SI 1 "register_operand" "")))]
3449 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3450 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3452 (define_insn "*floatsitf2_hq"
3453 [(set (match_operand:TF 0 "register_operand" "=e")
3454 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3455 "TARGET_FPU && TARGET_HARD_QUAD"
3457 [(set_attr "type" "fp")])
3459 (define_expand "floatunssitf2"
3460 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3461 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3462 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3463 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3465 ;; Now the same for 64 bit sources.
3467 (define_insn "floatdisf2"
3468 [(set (match_operand:SF 0 "register_operand" "=f")
3469 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3470 "TARGET_V9 && TARGET_FPU"
3472 [(set_attr "type" "fp")
3473 (set_attr "fptype" "double")])
3475 (define_expand "floatunsdisf2"
3476 [(use (match_operand:SF 0 "register_operand" ""))
3477 (use (match_operand:DI 1 "general_operand" ""))]
3478 "TARGET_ARCH64 && TARGET_FPU"
3479 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3481 (define_insn "floatdidf2"
3482 [(set (match_operand:DF 0 "register_operand" "=e")
3483 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3484 "TARGET_V9 && TARGET_FPU"
3486 [(set_attr "type" "fp")
3487 (set_attr "fptype" "double")])
3489 (define_expand "floatunsdidf2"
3490 [(use (match_operand:DF 0 "register_operand" ""))
3491 (use (match_operand:DI 1 "general_operand" ""))]
3492 "TARGET_ARCH64 && TARGET_FPU"
3493 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3495 (define_expand "floatditf2"
3496 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3497 (float:TF (match_operand:DI 1 "register_operand" "")))]
3498 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3499 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3501 (define_insn "*floatditf2_hq"
3502 [(set (match_operand:TF 0 "register_operand" "=e")
3503 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3504 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3506 [(set_attr "type" "fp")])
3508 (define_expand "floatunsditf2"
3509 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3510 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3511 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3512 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3514 ;; Convert a float to an actual integer.
3515 ;; Truncation is performed as part of the conversion.
3517 (define_insn "fix_truncsfsi2"
3518 [(set (match_operand:SI 0 "register_operand" "=f")
3519 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3522 [(set_attr "type" "fp")
3523 (set_attr "fptype" "double")])
3525 (define_insn "fix_truncdfsi2"
3526 [(set (match_operand:SI 0 "register_operand" "=f")
3527 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3530 [(set_attr "type" "fp")
3531 (set_attr "fptype" "double")])
3533 (define_expand "fix_trunctfsi2"
3534 [(set (match_operand:SI 0 "register_operand" "")
3535 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3536 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3537 "emit_tfmode_cvt (FIX, operands); DONE;")
3539 (define_insn "*fix_trunctfsi2_hq"
3540 [(set (match_operand:SI 0 "register_operand" "=f")
3541 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3542 "TARGET_FPU && TARGET_HARD_QUAD"
3544 [(set_attr "type" "fp")])
3546 (define_expand "fixuns_trunctfsi2"
3547 [(set (match_operand:SI 0 "register_operand" "")
3548 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3549 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3550 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3552 ;; Now the same, for V9 targets
3554 (define_insn "fix_truncsfdi2"
3555 [(set (match_operand:DI 0 "register_operand" "=e")
3556 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3557 "TARGET_V9 && TARGET_FPU"
3559 [(set_attr "type" "fp")
3560 (set_attr "fptype" "double")])
3562 (define_expand "fixuns_truncsfdi2"
3563 [(use (match_operand:DI 0 "register_operand" ""))
3564 (use (match_operand:SF 1 "general_operand" ""))]
3565 "TARGET_ARCH64 && TARGET_FPU"
3566 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3568 (define_insn "fix_truncdfdi2"
3569 [(set (match_operand:DI 0 "register_operand" "=e")
3570 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3571 "TARGET_V9 && TARGET_FPU"
3573 [(set_attr "type" "fp")
3574 (set_attr "fptype" "double")])
3576 (define_expand "fixuns_truncdfdi2"
3577 [(use (match_operand:DI 0 "register_operand" ""))
3578 (use (match_operand:DF 1 "general_operand" ""))]
3579 "TARGET_ARCH64 && TARGET_FPU"
3580 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3582 (define_expand "fix_trunctfdi2"
3583 [(set (match_operand:DI 0 "register_operand" "")
3584 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3585 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3586 "emit_tfmode_cvt (FIX, operands); DONE;")
3588 (define_insn "*fix_trunctfdi2_hq"
3589 [(set (match_operand:DI 0 "register_operand" "=e")
3590 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3591 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3593 [(set_attr "type" "fp")])
3595 (define_expand "fixuns_trunctfdi2"
3596 [(set (match_operand:DI 0 "register_operand" "")
3597 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3598 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3599 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3602 ;; Integer addition/subtraction instructions.
3604 (define_expand "adddi3"
3605 [(set (match_operand:DI 0 "register_operand" "")
3606 (plus:DI (match_operand:DI 1 "register_operand" "")
3607 (match_operand:DI 2 "arith_double_add_operand" "")))]
3610 if (! TARGET_ARCH64)
3612 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3613 gen_rtx_SET (VOIDmode, operands[0],
3614 gen_rtx_PLUS (DImode, operands[1],
3616 gen_rtx_CLOBBER (VOIDmode,
3617 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3622 (define_insn_and_split "*adddi3_insn_sp32"
3623 [(set (match_operand:DI 0 "register_operand" "=r")
3624 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3625 (match_operand:DI 2 "arith_double_operand" "rHI")))
3626 (clobber (reg:CC CC_REG))]
3629 "&& reload_completed"
3630 [(parallel [(set (reg:CC_NOOV CC_REG)
3631 (compare:CC_NOOV (plus:SI (match_dup 4)
3635 (plus:SI (match_dup 4) (match_dup 5)))])
3637 (plus:SI (plus:SI (match_dup 7)
3639 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3641 operands[3] = gen_lowpart (SImode, operands[0]);
3642 operands[4] = gen_lowpart (SImode, operands[1]);
3643 operands[5] = gen_lowpart (SImode, operands[2]);
3644 operands[6] = gen_highpart (SImode, operands[0]);
3645 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3646 #if HOST_BITS_PER_WIDE_INT == 32
3647 if (GET_CODE (operands[2]) == CONST_INT)
3649 if (INTVAL (operands[2]) < 0)
3650 operands[8] = constm1_rtx;
3652 operands[8] = const0_rtx;
3656 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3658 [(set_attr "length" "2")])
3660 ;; LTU here means "carry set"
3662 [(set (match_operand:SI 0 "register_operand" "=r")
3663 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3664 (match_operand:SI 2 "arith_operand" "rI"))
3665 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3668 [(set_attr "type" "ialuX")])
3670 (define_insn_and_split "*addx_extend_sp32"
3671 [(set (match_operand:DI 0 "register_operand" "=r")
3672 (zero_extend:DI (plus:SI (plus:SI
3673 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3674 (match_operand:SI 2 "arith_operand" "rI"))
3675 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3678 "&& reload_completed"
3679 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3680 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3681 (set (match_dup 4) (const_int 0))]
3682 "operands[3] = gen_lowpart (SImode, operands[0]);
3683 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3684 [(set_attr "length" "2")])
3686 (define_insn "*addx_extend_sp64"
3687 [(set (match_operand:DI 0 "register_operand" "=r")
3688 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3689 (match_operand:SI 2 "arith_operand" "rI"))
3690 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3693 [(set_attr "type" "ialuX")])
3695 (define_insn_and_split "*adddi3_extend_sp32"
3696 [(set (match_operand:DI 0 "register_operand" "=r")
3697 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3698 (match_operand:DI 2 "register_operand" "r")))
3699 (clobber (reg:CC CC_REG))]
3702 "&& reload_completed"
3703 [(parallel [(set (reg:CC_NOOV CC_REG)
3704 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3706 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3708 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3709 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3710 "operands[3] = gen_lowpart (SImode, operands[2]);
3711 operands[4] = gen_highpart (SImode, operands[2]);
3712 operands[5] = gen_lowpart (SImode, operands[0]);
3713 operands[6] = gen_highpart (SImode, operands[0]);"
3714 [(set_attr "length" "2")])
3716 (define_insn "*adddi3_sp64"
3717 [(set (match_operand:DI 0 "register_operand" "=r,r")
3718 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3719 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3725 (define_insn "addsi3"
3726 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3727 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3728 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3733 fpadd32s\t%1, %2, %0"
3734 [(set_attr "type" "*,*,fga")
3735 (set_attr "fptype" "*,*,single")])
3737 (define_insn "*cmp_cc_plus"
3738 [(set (reg:CC_NOOV CC_REG)
3739 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3740 (match_operand:SI 1 "arith_operand" "rI"))
3743 "addcc\t%0, %1, %%g0"
3744 [(set_attr "type" "compare")])
3746 (define_insn "*cmp_ccx_plus"
3747 [(set (reg:CCX_NOOV CC_REG)
3748 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3749 (match_operand:DI 1 "arith_operand" "rI"))
3752 "addcc\t%0, %1, %%g0"
3753 [(set_attr "type" "compare")])
3755 (define_insn "*cmp_cc_plus_set"
3756 [(set (reg:CC_NOOV CC_REG)
3757 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3758 (match_operand:SI 2 "arith_operand" "rI"))
3760 (set (match_operand:SI 0 "register_operand" "=r")
3761 (plus:SI (match_dup 1) (match_dup 2)))]
3764 [(set_attr "type" "compare")])
3766 (define_insn "*cmp_ccx_plus_set"
3767 [(set (reg:CCX_NOOV CC_REG)
3768 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3769 (match_operand:DI 2 "arith_operand" "rI"))
3771 (set (match_operand:DI 0 "register_operand" "=r")
3772 (plus:DI (match_dup 1) (match_dup 2)))]
3775 [(set_attr "type" "compare")])
3777 (define_expand "subdi3"
3778 [(set (match_operand:DI 0 "register_operand" "")
3779 (minus:DI (match_operand:DI 1 "register_operand" "")
3780 (match_operand:DI 2 "arith_double_add_operand" "")))]
3783 if (! TARGET_ARCH64)
3785 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3786 gen_rtx_SET (VOIDmode, operands[0],
3787 gen_rtx_MINUS (DImode, operands[1],
3789 gen_rtx_CLOBBER (VOIDmode,
3790 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3795 (define_insn_and_split "*subdi3_insn_sp32"
3796 [(set (match_operand:DI 0 "register_operand" "=r")
3797 (minus:DI (match_operand:DI 1 "register_operand" "r")
3798 (match_operand:DI 2 "arith_double_operand" "rHI")))
3799 (clobber (reg:CC CC_REG))]
3802 "&& reload_completed"
3803 [(parallel [(set (reg:CC_NOOV CC_REG)
3804 (compare:CC_NOOV (minus:SI (match_dup 4)
3808 (minus:SI (match_dup 4) (match_dup 5)))])
3810 (minus:SI (minus:SI (match_dup 7)
3812 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3814 operands[3] = gen_lowpart (SImode, operands[0]);
3815 operands[4] = gen_lowpart (SImode, operands[1]);
3816 operands[5] = gen_lowpart (SImode, operands[2]);
3817 operands[6] = gen_highpart (SImode, operands[0]);
3818 operands[7] = gen_highpart (SImode, operands[1]);
3819 #if HOST_BITS_PER_WIDE_INT == 32
3820 if (GET_CODE (operands[2]) == CONST_INT)
3822 if (INTVAL (operands[2]) < 0)
3823 operands[8] = constm1_rtx;
3825 operands[8] = const0_rtx;
3829 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3831 [(set_attr "length" "2")])
3833 ;; LTU here means "carry set"
3835 [(set (match_operand:SI 0 "register_operand" "=r")
3836 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3837 (match_operand:SI 2 "arith_operand" "rI"))
3838 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3841 [(set_attr "type" "ialuX")])
3843 (define_insn "*subx_extend_sp64"
3844 [(set (match_operand:DI 0 "register_operand" "=r")
3845 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3846 (match_operand:SI 2 "arith_operand" "rI"))
3847 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3850 [(set_attr "type" "ialuX")])
3852 (define_insn_and_split "*subx_extend"
3853 [(set (match_operand:DI 0 "register_operand" "=r")
3854 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3855 (match_operand:SI 2 "arith_operand" "rI"))
3856 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3859 "&& reload_completed"
3860 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3861 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3862 (set (match_dup 4) (const_int 0))]
3863 "operands[3] = gen_lowpart (SImode, operands[0]);
3864 operands[4] = gen_highpart (SImode, operands[0]);"
3865 [(set_attr "length" "2")])
3867 (define_insn_and_split "*subdi3_extend_sp32"
3868 [(set (match_operand:DI 0 "register_operand" "=r")
3869 (minus:DI (match_operand:DI 1 "register_operand" "r")
3870 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3871 (clobber (reg:CC CC_REG))]
3874 "&& reload_completed"
3875 [(parallel [(set (reg:CC_NOOV CC_REG)
3876 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3878 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3880 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3881 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3882 "operands[3] = gen_lowpart (SImode, operands[1]);
3883 operands[4] = gen_highpart (SImode, operands[1]);
3884 operands[5] = gen_lowpart (SImode, operands[0]);
3885 operands[6] = gen_highpart (SImode, operands[0]);"
3886 [(set_attr "length" "2")])
3888 (define_insn "*subdi3_sp64"
3889 [(set (match_operand:DI 0 "register_operand" "=r,r")
3890 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3891 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3897 (define_insn "subsi3"
3898 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3899 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3900 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3905 fpsub32s\t%1, %2, %0"
3906 [(set_attr "type" "*,*,fga")
3907 (set_attr "fptype" "*,*,single")])
3909 (define_insn "*cmp_minus_cc"
3910 [(set (reg:CC_NOOV CC_REG)
3911 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3912 (match_operand:SI 1 "arith_operand" "rI"))
3915 "subcc\t%r0, %1, %%g0"
3916 [(set_attr "type" "compare")])
3918 (define_insn "*cmp_minus_ccx"
3919 [(set (reg:CCX_NOOV CC_REG)
3920 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3921 (match_operand:DI 1 "arith_operand" "rI"))
3924 "subcc\t%0, %1, %%g0"
3925 [(set_attr "type" "compare")])
3927 (define_insn "cmp_minus_cc_set"
3928 [(set (reg:CC_NOOV CC_REG)
3929 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3930 (match_operand:SI 2 "arith_operand" "rI"))
3932 (set (match_operand:SI 0 "register_operand" "=r")
3933 (minus:SI (match_dup 1) (match_dup 2)))]
3935 "subcc\t%r1, %2, %0"
3936 [(set_attr "type" "compare")])
3938 (define_insn "*cmp_minus_ccx_set"
3939 [(set (reg:CCX_NOOV CC_REG)
3940 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3941 (match_operand:DI 2 "arith_operand" "rI"))
3943 (set (match_operand:DI 0 "register_operand" "=r")
3944 (minus:DI (match_dup 1) (match_dup 2)))]
3947 [(set_attr "type" "compare")])
3950 ;; Integer multiply/divide instructions.
3952 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3953 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3955 (define_insn "mulsi3"
3956 [(set (match_operand:SI 0 "register_operand" "=r")
3957 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3958 (match_operand:SI 2 "arith_operand" "rI")))]
3961 [(set_attr "type" "imul")])
3963 (define_expand "muldi3"
3964 [(set (match_operand:DI 0 "register_operand" "")
3965 (mult:DI (match_operand:DI 1 "arith_operand" "")
3966 (match_operand:DI 2 "arith_operand" "")))]
3967 "TARGET_ARCH64 || TARGET_V8PLUS"
3971 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3976 (define_insn "*muldi3_sp64"
3977 [(set (match_operand:DI 0 "register_operand" "=r")
3978 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3979 (match_operand:DI 2 "arith_operand" "rI")))]
3982 [(set_attr "type" "imul")])
3984 ;; V8plus wide multiply.
3986 (define_insn "muldi3_v8plus"
3987 [(set (match_operand:DI 0 "register_operand" "=r,h")
3988 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3989 (match_operand:DI 2 "arith_operand" "rI,rI")))
3990 (clobber (match_scratch:SI 3 "=&h,X"))
3991 (clobber (match_scratch:SI 4 "=&h,X"))]
3994 if (sparc_check_64 (operands[1], insn) <= 0)
3995 output_asm_insn ("srl\t%L1, 0, %L1", operands);
3996 if (which_alternative == 1)
3997 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3998 if (GET_CODE (operands[2]) == CONST_INT)
4000 if (which_alternative == 1)
4001 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4003 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";
4005 else if (rtx_equal_p (operands[1], operands[2]))
4007 if (which_alternative == 1)
4008 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4010 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";
4012 if (sparc_check_64 (operands[2], insn) <= 0)
4013 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4014 if (which_alternative == 1)
4015 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";
4017 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";
4019 [(set_attr "type" "multi")
4020 (set_attr "length" "9,8")])
4022 (define_insn "*cmp_mul_set"
4023 [(set (reg:CC CC_REG)
4024 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4025 (match_operand:SI 2 "arith_operand" "rI"))
4027 (set (match_operand:SI 0 "register_operand" "=r")
4028 (mult:SI (match_dup 1) (match_dup 2)))]
4029 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4030 "smulcc\t%1, %2, %0"
4031 [(set_attr "type" "imul")])
4033 (define_expand "mulsidi3"
4034 [(set (match_operand:DI 0 "register_operand" "")
4035 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4036 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4039 if (CONSTANT_P (operands[2]))
4042 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4044 else if (TARGET_ARCH32)
4045 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4048 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4054 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4059 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4060 ;; registers can hold 64-bit values in the V8plus environment.
4062 (define_insn "mulsidi3_v8plus"
4063 [(set (match_operand:DI 0 "register_operand" "=h,r")
4064 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4065 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4066 (clobber (match_scratch:SI 3 "=X,&h"))]
4069 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4070 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4071 [(set_attr "type" "multi")
4072 (set_attr "length" "2,3")])
4075 (define_insn "const_mulsidi3_v8plus"
4076 [(set (match_operand:DI 0 "register_operand" "=h,r")
4077 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4078 (match_operand:DI 2 "small_int_operand" "I,I")))
4079 (clobber (match_scratch:SI 3 "=X,&h"))]
4082 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4083 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4084 [(set_attr "type" "multi")
4085 (set_attr "length" "2,3")])
4088 (define_insn "*mulsidi3_sp32"
4089 [(set (match_operand:DI 0 "register_operand" "=r")
4090 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4091 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4094 return TARGET_SPARCLET
4095 ? "smuld\t%1, %2, %L0"
4096 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4099 (if_then_else (eq_attr "isa" "sparclet")
4100 (const_string "imul") (const_string "multi")))
4101 (set (attr "length")
4102 (if_then_else (eq_attr "isa" "sparclet")
4103 (const_int 1) (const_int 2)))])
4105 (define_insn "*mulsidi3_sp64"
4106 [(set (match_operand:DI 0 "register_operand" "=r")
4107 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4108 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4109 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4111 [(set_attr "type" "imul")])
4113 ;; Extra pattern, because sign_extend of a constant isn't valid.
4116 (define_insn "const_mulsidi3_sp32"
4117 [(set (match_operand:DI 0 "register_operand" "=r")
4118 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4119 (match_operand:DI 2 "small_int_operand" "I")))]
4122 return TARGET_SPARCLET
4123 ? "smuld\t%1, %2, %L0"
4124 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4127 (if_then_else (eq_attr "isa" "sparclet")
4128 (const_string "imul") (const_string "multi")))
4129 (set (attr "length")
4130 (if_then_else (eq_attr "isa" "sparclet")
4131 (const_int 1) (const_int 2)))])
4133 (define_insn "const_mulsidi3_sp64"
4134 [(set (match_operand:DI 0 "register_operand" "=r")
4135 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4136 (match_operand:DI 2 "small_int_operand" "I")))]
4137 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4139 [(set_attr "type" "imul")])
4141 (define_expand "smulsi3_highpart"
4142 [(set (match_operand:SI 0 "register_operand" "")
4144 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4145 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4147 "TARGET_HARD_MUL && TARGET_ARCH32"
4149 if (CONSTANT_P (operands[2]))
4153 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4159 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4164 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4165 operands[2], GEN_INT (32)));
4171 (define_insn "smulsi3_highpart_v8plus"
4172 [(set (match_operand:SI 0 "register_operand" "=h,r")
4174 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4175 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4176 (match_operand:SI 3 "small_int_operand" "I,I"))))
4177 (clobber (match_scratch:SI 4 "=X,&h"))]
4180 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4181 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4182 [(set_attr "type" "multi")
4183 (set_attr "length" "2")])
4185 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4188 [(set (match_operand:SI 0 "register_operand" "=h,r")
4191 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4192 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4193 (match_operand:SI 3 "small_int_operand" "I,I"))
4195 (clobber (match_scratch:SI 4 "=X,&h"))]
4198 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4199 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4200 [(set_attr "type" "multi")
4201 (set_attr "length" "2")])
4204 (define_insn "const_smulsi3_highpart_v8plus"
4205 [(set (match_operand:SI 0 "register_operand" "=h,r")
4207 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4208 (match_operand:DI 2 "small_int_operand" "I,I"))
4209 (match_operand:SI 3 "small_int_operand" "I,I"))))
4210 (clobber (match_scratch:SI 4 "=X,&h"))]
4213 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4214 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4215 [(set_attr "type" "multi")
4216 (set_attr "length" "2")])
4219 (define_insn "*smulsi3_highpart_sp32"
4220 [(set (match_operand:SI 0 "register_operand" "=r")
4222 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4223 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4226 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4227 [(set_attr "type" "multi")
4228 (set_attr "length" "2")])
4231 (define_insn "const_smulsi3_highpart"
4232 [(set (match_operand:SI 0 "register_operand" "=r")
4234 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4235 (match_operand:DI 2 "small_int_operand" "i"))
4238 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4239 [(set_attr "type" "multi")
4240 (set_attr "length" "2")])
4242 (define_expand "umulsidi3"
4243 [(set (match_operand:DI 0 "register_operand" "")
4244 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4245 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4248 if (CONSTANT_P (operands[2]))
4251 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4253 else if (TARGET_ARCH32)
4254 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4257 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4263 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4269 (define_insn "umulsidi3_v8plus"
4270 [(set (match_operand:DI 0 "register_operand" "=h,r")
4271 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4272 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4273 (clobber (match_scratch:SI 3 "=X,&h"))]
4276 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4277 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4278 [(set_attr "type" "multi")
4279 (set_attr "length" "2,3")])
4282 (define_insn "*umulsidi3_sp32"
4283 [(set (match_operand:DI 0 "register_operand" "=r")
4284 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4285 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4288 return TARGET_SPARCLET
4289 ? "umuld\t%1, %2, %L0"
4290 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4293 (if_then_else (eq_attr "isa" "sparclet")
4294 (const_string "imul") (const_string "multi")))
4295 (set (attr "length")
4296 (if_then_else (eq_attr "isa" "sparclet")
4297 (const_int 1) (const_int 2)))])
4299 (define_insn "*umulsidi3_sp64"
4300 [(set (match_operand:DI 0 "register_operand" "=r")
4301 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4302 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4303 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4305 [(set_attr "type" "imul")])
4307 ;; Extra pattern, because sign_extend of a constant isn't valid.
4310 (define_insn "const_umulsidi3_sp32"
4311 [(set (match_operand:DI 0 "register_operand" "=r")
4312 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4313 (match_operand:DI 2 "uns_small_int_operand" "")))]
4316 return TARGET_SPARCLET
4317 ? "umuld\t%1, %s2, %L0"
4318 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4321 (if_then_else (eq_attr "isa" "sparclet")
4322 (const_string "imul") (const_string "multi")))
4323 (set (attr "length")
4324 (if_then_else (eq_attr "isa" "sparclet")
4325 (const_int 1) (const_int 2)))])
4327 (define_insn "const_umulsidi3_sp64"
4328 [(set (match_operand:DI 0 "register_operand" "=r")
4329 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4330 (match_operand:DI 2 "uns_small_int_operand" "")))]
4331 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4333 [(set_attr "type" "imul")])
4336 (define_insn "const_umulsidi3_v8plus"
4337 [(set (match_operand:DI 0 "register_operand" "=h,r")
4338 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4339 (match_operand:DI 2 "uns_small_int_operand" "")))
4340 (clobber (match_scratch:SI 3 "=X,h"))]
4343 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4344 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4345 [(set_attr "type" "multi")
4346 (set_attr "length" "2,3")])
4348 (define_expand "umulsi3_highpart"
4349 [(set (match_operand:SI 0 "register_operand" "")
4351 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4352 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4354 "TARGET_HARD_MUL && TARGET_ARCH32"
4356 if (CONSTANT_P (operands[2]))
4360 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4366 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4371 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4372 operands[2], GEN_INT (32)));
4378 (define_insn "umulsi3_highpart_v8plus"
4379 [(set (match_operand:SI 0 "register_operand" "=h,r")
4381 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4382 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4383 (match_operand:SI 3 "small_int_operand" "I,I"))))
4384 (clobber (match_scratch:SI 4 "=X,h"))]
4387 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4388 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4389 [(set_attr "type" "multi")
4390 (set_attr "length" "2")])
4393 (define_insn "const_umulsi3_highpart_v8plus"
4394 [(set (match_operand:SI 0 "register_operand" "=h,r")
4396 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4397 (match_operand:DI 2 "uns_small_int_operand" ""))
4398 (match_operand:SI 3 "small_int_operand" "I,I"))))
4399 (clobber (match_scratch:SI 4 "=X,h"))]
4402 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4403 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4404 [(set_attr "type" "multi")
4405 (set_attr "length" "2")])
4408 (define_insn "*umulsi3_highpart_sp32"
4409 [(set (match_operand:SI 0 "register_operand" "=r")
4411 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4412 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4415 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4416 [(set_attr "type" "multi")
4417 (set_attr "length" "2")])
4420 (define_insn "const_umulsi3_highpart"
4421 [(set (match_operand:SI 0 "register_operand" "=r")
4423 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4424 (match_operand:DI 2 "uns_small_int_operand" ""))
4427 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4428 [(set_attr "type" "multi")
4429 (set_attr "length" "2")])
4431 (define_expand "divsi3"
4432 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4433 (div:SI (match_operand:SI 1 "register_operand" "")
4434 (match_operand:SI 2 "input_operand" "")))
4435 (clobber (match_scratch:SI 3 ""))])]
4436 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4440 operands[3] = gen_reg_rtx(SImode);
4441 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4442 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4448 ;; The V8 architecture specifies that there must be at least 3 instructions
4449 ;; between a write to the Y register and a use of it for correct results.
4450 ;; We try to fill one of them with a simple constant or a memory load.
4452 (define_insn "divsi3_sp32"
4453 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4454 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4455 (match_operand:SI 2 "input_operand" "rI,K,m")))
4456 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4457 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4459 output_asm_insn ("sra\t%1, 31, %3", operands);
4460 output_asm_insn ("wr\t%3, 0, %%y", operands);
4462 switch (which_alternative)
4466 return "sdiv\t%1, %2, %0";
4468 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4471 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4473 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4476 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4478 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4483 [(set_attr "type" "multi")
4484 (set (attr "length")
4485 (if_then_else (eq_attr "isa" "v9")
4486 (const_int 4) (const_int 6)))])
4488 (define_insn "divsi3_sp64"
4489 [(set (match_operand:SI 0 "register_operand" "=r")
4490 (div:SI (match_operand:SI 1 "register_operand" "r")
4491 (match_operand:SI 2 "input_operand" "rI")))
4492 (use (match_operand:SI 3 "register_operand" "r"))]
4493 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4494 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4495 [(set_attr "type" "multi")
4496 (set_attr "length" "2")])
4498 (define_insn "divdi3"
4499 [(set (match_operand:DI 0 "register_operand" "=r")
4500 (div:DI (match_operand:DI 1 "register_operand" "r")
4501 (match_operand:DI 2 "arith_operand" "rI")))]
4504 [(set_attr "type" "idiv")])
4506 (define_insn "*cmp_sdiv_cc_set"
4507 [(set (reg:CC CC_REG)
4508 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4509 (match_operand:SI 2 "arith_operand" "rI"))
4511 (set (match_operand:SI 0 "register_operand" "=r")
4512 (div:SI (match_dup 1) (match_dup 2)))
4513 (clobber (match_scratch:SI 3 "=&r"))]
4514 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4516 output_asm_insn ("sra\t%1, 31, %3", operands);
4517 output_asm_insn ("wr\t%3, 0, %%y", operands);
4520 return "sdivcc\t%1, %2, %0";
4522 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4524 [(set_attr "type" "multi")
4525 (set (attr "length")
4526 (if_then_else (eq_attr "isa" "v9")
4527 (const_int 3) (const_int 6)))])
4530 (define_expand "udivsi3"
4531 [(set (match_operand:SI 0 "register_operand" "")
4532 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4533 (match_operand:SI 2 "input_operand" "")))]
4534 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4537 ;; The V8 architecture specifies that there must be at least 3 instructions
4538 ;; between a write to the Y register and a use of it for correct results.
4539 ;; We try to fill one of them with a simple constant or a memory load.
4541 (define_insn "udivsi3_sp32"
4542 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4543 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4544 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4545 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4547 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4549 switch (which_alternative)
4553 return "udiv\t%1, %2, %0";
4555 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4558 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4560 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4563 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4565 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4568 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4570 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4575 [(set_attr "type" "multi")
4576 (set (attr "length")
4577 (if_then_else (eq_attr "isa" "v9")
4578 (const_int 3) (const_int 5)))])
4580 (define_insn "udivsi3_sp64"
4581 [(set (match_operand:SI 0 "register_operand" "=r")
4582 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4583 (match_operand:SI 2 "input_operand" "rI")))]
4584 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4585 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4586 [(set_attr "type" "multi")
4587 (set_attr "length" "2")])
4589 (define_insn "udivdi3"
4590 [(set (match_operand:DI 0 "register_operand" "=r")
4591 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4592 (match_operand:DI 2 "arith_operand" "rI")))]
4595 [(set_attr "type" "idiv")])
4597 (define_insn "*cmp_udiv_cc_set"
4598 [(set (reg:CC CC_REG)
4599 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4600 (match_operand:SI 2 "arith_operand" "rI"))
4602 (set (match_operand:SI 0 "register_operand" "=r")
4603 (udiv:SI (match_dup 1) (match_dup 2)))]
4604 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4606 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4609 return "udivcc\t%1, %2, %0";
4611 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4613 [(set_attr "type" "multi")
4614 (set (attr "length")
4615 (if_then_else (eq_attr "isa" "v9")
4616 (const_int 2) (const_int 5)))])
4618 ; sparclet multiply/accumulate insns
4620 (define_insn "*smacsi"
4621 [(set (match_operand:SI 0 "register_operand" "=r")
4622 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4623 (match_operand:SI 2 "arith_operand" "rI"))
4624 (match_operand:SI 3 "register_operand" "0")))]
4627 [(set_attr "type" "imul")])
4629 (define_insn "*smacdi"
4630 [(set (match_operand:DI 0 "register_operand" "=r")
4631 (plus:DI (mult:DI (sign_extend:DI
4632 (match_operand:SI 1 "register_operand" "%r"))
4634 (match_operand:SI 2 "register_operand" "r")))
4635 (match_operand:DI 3 "register_operand" "0")))]
4637 "smacd\t%1, %2, %L0"
4638 [(set_attr "type" "imul")])
4640 (define_insn "*umacdi"
4641 [(set (match_operand:DI 0 "register_operand" "=r")
4642 (plus:DI (mult:DI (zero_extend:DI
4643 (match_operand:SI 1 "register_operand" "%r"))
4645 (match_operand:SI 2 "register_operand" "r")))
4646 (match_operand:DI 3 "register_operand" "0")))]
4648 "umacd\t%1, %2, %L0"
4649 [(set_attr "type" "imul")])
4652 ;; Boolean instructions.
4654 ;; We define DImode `and' so with DImode `not' we can get
4655 ;; DImode `andn'. Other combinations are possible.
4657 (define_expand "and<V64I:mode>3"
4658 [(set (match_operand:V64I 0 "register_operand" "")
4659 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4660 (match_operand:V64I 2 "arith_double_operand" "")))]
4664 (define_insn "*and<V64I:mode>3_sp32"
4665 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4666 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4667 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4672 [(set_attr "type" "*,fga")
4673 (set_attr "length" "2,*")
4674 (set_attr "fptype" "*,double")])
4676 (define_insn "*and<V64I:mode>3_sp64"
4677 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4678 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4679 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4684 [(set_attr "type" "*,fga")
4685 (set_attr "fptype" "*,double")])
4687 (define_insn "and<V32I:mode>3"
4688 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4689 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4690 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4695 [(set_attr "type" "*,fga")
4696 (set_attr "fptype" "*,single")])
4699 [(set (match_operand:SI 0 "register_operand" "")
4700 (and:SI (match_operand:SI 1 "register_operand" "")
4701 (match_operand:SI 2 "const_compl_high_operand" "")))
4702 (clobber (match_operand:SI 3 "register_operand" ""))]
4704 [(set (match_dup 3) (match_dup 4))
4705 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4707 operands[4] = GEN_INT (~INTVAL (operands[2]));
4710 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4711 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4712 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4713 (match_operand:V64I 2 "register_operand" "r,b")))]
4717 fandnot1\t%1, %2, %0"
4718 "&& reload_completed
4719 && ((GET_CODE (operands[0]) == REG
4720 && REGNO (operands[0]) < 32)
4721 || (GET_CODE (operands[0]) == SUBREG
4722 && GET_CODE (SUBREG_REG (operands[0])) == REG
4723 && REGNO (SUBREG_REG (operands[0])) < 32))"
4724 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4725 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4726 "operands[3] = gen_highpart (SImode, operands[0]);
4727 operands[4] = gen_highpart (SImode, operands[1]);
4728 operands[5] = gen_highpart (SImode, operands[2]);
4729 operands[6] = gen_lowpart (SImode, operands[0]);
4730 operands[7] = gen_lowpart (SImode, operands[1]);
4731 operands[8] = gen_lowpart (SImode, operands[2]);"
4732 [(set_attr "type" "*,fga")
4733 (set_attr "length" "2,*")
4734 (set_attr "fptype" "*,double")])
4736 (define_insn "*and_not_<V64I:mode>_sp64"
4737 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4738 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4739 (match_operand:V64I 2 "register_operand" "r,b")))]
4743 fandnot1\t%1, %2, %0"
4744 [(set_attr "type" "*,fga")
4745 (set_attr "fptype" "*,double")])
4747 (define_insn "*and_not_<V32I:mode>"
4748 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4749 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4750 (match_operand:V32I 2 "register_operand" "r,d")))]
4754 fandnot1s\t%1, %2, %0"
4755 [(set_attr "type" "*,fga")
4756 (set_attr "fptype" "*,single")])
4758 (define_expand "ior<V64I:mode>3"
4759 [(set (match_operand:V64I 0 "register_operand" "")
4760 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4761 (match_operand:V64I 2 "arith_double_operand" "")))]
4765 (define_insn "*ior<V64I:mode>3_sp32"
4766 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4767 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4768 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4773 [(set_attr "type" "*,fga")
4774 (set_attr "length" "2,*")
4775 (set_attr "fptype" "*,double")])
4777 (define_insn "*ior<V64I:mode>3_sp64"
4778 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4779 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4780 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4785 [(set_attr "type" "*,fga")
4786 (set_attr "fptype" "*,double")])
4788 (define_insn "ior<V32I:mode>3"
4789 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4790 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4791 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4796 [(set_attr "type" "*,fga")
4797 (set_attr "fptype" "*,single")])
4800 [(set (match_operand:SI 0 "register_operand" "")
4801 (ior: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) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4808 operands[4] = GEN_INT (~INTVAL (operands[2]));
4811 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4812 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4813 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4814 (match_operand:V64I 2 "register_operand" "r,b")))]
4818 fornot1\t%1, %2, %0"
4819 "&& reload_completed
4820 && ((GET_CODE (operands[0]) == REG
4821 && REGNO (operands[0]) < 32)
4822 || (GET_CODE (operands[0]) == SUBREG
4823 && GET_CODE (SUBREG_REG (operands[0])) == REG
4824 && REGNO (SUBREG_REG (operands[0])) < 32))"
4825 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4826 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4827 "operands[3] = gen_highpart (SImode, operands[0]);
4828 operands[4] = gen_highpart (SImode, operands[1]);
4829 operands[5] = gen_highpart (SImode, operands[2]);
4830 operands[6] = gen_lowpart (SImode, operands[0]);
4831 operands[7] = gen_lowpart (SImode, operands[1]);
4832 operands[8] = gen_lowpart (SImode, operands[2]);"
4833 [(set_attr "type" "*,fga")
4834 (set_attr "length" "2,*")
4835 (set_attr "fptype" "*,double")])
4837 (define_insn "*or_not_<V64I:mode>_sp64"
4838 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4839 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4840 (match_operand:V64I 2 "register_operand" "r,b")))]
4844 fornot1\t%1, %2, %0"
4845 [(set_attr "type" "*,fga")
4846 (set_attr "fptype" "*,double")])
4848 (define_insn "*or_not_<V32I:mode>"
4849 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4850 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4851 (match_operand:V32I 2 "register_operand" "r,d")))]
4855 fornot1s\t%1, %2, %0"
4856 [(set_attr "type" "*,fga")
4857 (set_attr "fptype" "*,single")])
4859 (define_expand "xor<V64I:mode>3"
4860 [(set (match_operand:V64I 0 "register_operand" "")
4861 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4862 (match_operand:V64I 2 "arith_double_operand" "")))]
4866 (define_insn "*xor<V64I:mode>3_sp32"
4867 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4868 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4869 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4874 [(set_attr "type" "*,fga")
4875 (set_attr "length" "2,*")
4876 (set_attr "fptype" "*,double")])
4878 (define_insn "*xor<V64I:mode>3_sp64"
4879 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4880 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4881 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4886 [(set_attr "type" "*,fga")
4887 (set_attr "fptype" "*,double")])
4889 (define_insn "xor<V32I:mode>3"
4890 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4891 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4892 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4897 [(set_attr "type" "*,fga")
4898 (set_attr "fptype" "*,single")])
4901 [(set (match_operand:SI 0 "register_operand" "")
4902 (xor:SI (match_operand:SI 1 "register_operand" "")
4903 (match_operand:SI 2 "const_compl_high_operand" "")))
4904 (clobber (match_operand:SI 3 "register_operand" ""))]
4906 [(set (match_dup 3) (match_dup 4))
4907 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4909 operands[4] = GEN_INT (~INTVAL (operands[2]));
4913 [(set (match_operand:SI 0 "register_operand" "")
4914 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4915 (match_operand:SI 2 "const_compl_high_operand" ""))))
4916 (clobber (match_operand:SI 3 "register_operand" ""))]
4918 [(set (match_dup 3) (match_dup 4))
4919 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4921 operands[4] = GEN_INT (~INTVAL (operands[2]));
4924 ;; Split DImode logical operations requiring two instructions.
4926 [(set (match_operand:V64I 0 "register_operand" "")
4927 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4928 [(match_operand:V64I 2 "register_operand" "")
4929 (match_operand:V64I 3 "arith_double_operand" "")]))]
4932 && ((GET_CODE (operands[0]) == REG
4933 && REGNO (operands[0]) < 32)
4934 || (GET_CODE (operands[0]) == SUBREG
4935 && GET_CODE (SUBREG_REG (operands[0])) == REG
4936 && REGNO (SUBREG_REG (operands[0])) < 32))"
4937 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4938 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4940 operands[4] = gen_highpart (SImode, operands[0]);
4941 operands[5] = gen_lowpart (SImode, operands[0]);
4942 operands[6] = gen_highpart (SImode, operands[2]);
4943 operands[7] = gen_lowpart (SImode, operands[2]);
4944 #if HOST_BITS_PER_WIDE_INT == 32
4945 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4947 if (INTVAL (operands[3]) < 0)
4948 operands[8] = constm1_rtx;
4950 operands[8] = const0_rtx;
4954 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4955 operands[9] = gen_lowpart (SImode, operands[3]);
4958 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4959 ;; Combine now canonicalizes to the rightmost expression.
4960 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4961 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4962 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4963 (match_operand:V64I 2 "register_operand" "r,b"))))]
4968 "&& reload_completed
4969 && ((GET_CODE (operands[0]) == REG
4970 && REGNO (operands[0]) < 32)
4971 || (GET_CODE (operands[0]) == SUBREG
4972 && GET_CODE (SUBREG_REG (operands[0])) == REG
4973 && REGNO (SUBREG_REG (operands[0])) < 32))"
4974 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4975 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4976 "operands[3] = gen_highpart (SImode, operands[0]);
4977 operands[4] = gen_highpart (SImode, operands[1]);
4978 operands[5] = gen_highpart (SImode, operands[2]);
4979 operands[6] = gen_lowpart (SImode, operands[0]);
4980 operands[7] = gen_lowpart (SImode, operands[1]);
4981 operands[8] = gen_lowpart (SImode, operands[2]);"
4982 [(set_attr "type" "*,fga")
4983 (set_attr "length" "2,*")
4984 (set_attr "fptype" "*,double")])
4986 (define_insn "*xor_not_<V64I:mode>_sp64"
4987 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4988 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4989 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4994 [(set_attr "type" "*,fga")
4995 (set_attr "fptype" "*,double")])
4997 (define_insn "*xor_not_<V32I:mode>"
4998 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4999 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5000 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5005 [(set_attr "type" "*,fga")
5006 (set_attr "fptype" "*,single")])
5008 ;; These correspond to the above in the case where we also (or only)
5009 ;; want to set the condition code.
5011 (define_insn "*cmp_cc_arith_op"
5012 [(set (reg:CC CC_REG)
5014 (match_operator:SI 2 "cc_arith_operator"
5015 [(match_operand:SI 0 "arith_operand" "%r")
5016 (match_operand:SI 1 "arith_operand" "rI")])
5019 "%A2cc\t%0, %1, %%g0"
5020 [(set_attr "type" "compare")])
5022 (define_insn "*cmp_ccx_arith_op"
5023 [(set (reg:CCX CC_REG)
5025 (match_operator:DI 2 "cc_arith_operator"
5026 [(match_operand:DI 0 "arith_operand" "%r")
5027 (match_operand:DI 1 "arith_operand" "rI")])
5030 "%A2cc\t%0, %1, %%g0"
5031 [(set_attr "type" "compare")])
5033 (define_insn "*cmp_cc_arith_op_set"
5034 [(set (reg:CC CC_REG)
5036 (match_operator:SI 3 "cc_arith_operator"
5037 [(match_operand:SI 1 "arith_operand" "%r")
5038 (match_operand:SI 2 "arith_operand" "rI")])
5040 (set (match_operand:SI 0 "register_operand" "=r")
5041 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5042 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5044 [(set_attr "type" "compare")])
5046 (define_insn "*cmp_ccx_arith_op_set"
5047 [(set (reg:CCX CC_REG)
5049 (match_operator:DI 3 "cc_arith_operator"
5050 [(match_operand:DI 1 "arith_operand" "%r")
5051 (match_operand:DI 2 "arith_operand" "rI")])
5053 (set (match_operand:DI 0 "register_operand" "=r")
5054 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5055 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5057 [(set_attr "type" "compare")])
5059 (define_insn "*cmp_cc_xor_not"
5060 [(set (reg:CC CC_REG)
5062 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5063 (match_operand:SI 1 "arith_operand" "rI")))
5066 "xnorcc\t%r0, %1, %%g0"
5067 [(set_attr "type" "compare")])
5069 (define_insn "*cmp_ccx_xor_not"
5070 [(set (reg:CCX CC_REG)
5072 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5073 (match_operand:DI 1 "arith_operand" "rI")))
5076 "xnorcc\t%r0, %1, %%g0"
5077 [(set_attr "type" "compare")])
5079 (define_insn "*cmp_cc_xor_not_set"
5080 [(set (reg:CC CC_REG)
5082 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5083 (match_operand:SI 2 "arith_operand" "rI")))
5085 (set (match_operand:SI 0 "register_operand" "=r")
5086 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5088 "xnorcc\t%r1, %2, %0"
5089 [(set_attr "type" "compare")])
5091 (define_insn "*cmp_ccx_xor_not_set"
5092 [(set (reg:CCX CC_REG)
5094 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5095 (match_operand:DI 2 "arith_operand" "rI")))
5097 (set (match_operand:DI 0 "register_operand" "=r")
5098 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5100 "xnorcc\t%r1, %2, %0"
5101 [(set_attr "type" "compare")])
5103 (define_insn "*cmp_cc_arith_op_not"
5104 [(set (reg:CC CC_REG)
5106 (match_operator:SI 2 "cc_arith_not_operator"
5107 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5108 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5111 "%B2cc\t%r1, %0, %%g0"
5112 [(set_attr "type" "compare")])
5114 (define_insn "*cmp_ccx_arith_op_not"
5115 [(set (reg:CCX CC_REG)
5117 (match_operator:DI 2 "cc_arith_not_operator"
5118 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5119 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5122 "%B2cc\t%r1, %0, %%g0"
5123 [(set_attr "type" "compare")])
5125 (define_insn "*cmp_cc_arith_op_not_set"
5126 [(set (reg:CC CC_REG)
5128 (match_operator:SI 3 "cc_arith_not_operator"
5129 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5130 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5132 (set (match_operand:SI 0 "register_operand" "=r")
5133 (match_operator:SI 4 "cc_arith_not_operator"
5134 [(not:SI (match_dup 1)) (match_dup 2)]))]
5135 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5136 "%B3cc\t%r2, %1, %0"
5137 [(set_attr "type" "compare")])
5139 (define_insn "*cmp_ccx_arith_op_not_set"
5140 [(set (reg:CCX CC_REG)
5142 (match_operator:DI 3 "cc_arith_not_operator"
5143 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5144 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5146 (set (match_operand:DI 0 "register_operand" "=r")
5147 (match_operator:DI 4 "cc_arith_not_operator"
5148 [(not:DI (match_dup 1)) (match_dup 2)]))]
5149 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5150 "%B3cc\t%r2, %1, %0"
5151 [(set_attr "type" "compare")])
5153 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5154 ;; does not know how to make it work for constants.
5156 (define_expand "negdi2"
5157 [(set (match_operand:DI 0 "register_operand" "=r")
5158 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5161 if (! TARGET_ARCH64)
5163 emit_insn (gen_rtx_PARALLEL
5166 gen_rtx_SET (VOIDmode, operand0,
5167 gen_rtx_NEG (DImode, operand1)),
5168 gen_rtx_CLOBBER (VOIDmode,
5169 gen_rtx_REG (CCmode,
5175 (define_insn_and_split "*negdi2_sp32"
5176 [(set (match_operand:DI 0 "register_operand" "=r")
5177 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5178 (clobber (reg:CC CC_REG))]
5181 "&& reload_completed"
5182 [(parallel [(set (reg:CC_NOOV CC_REG)
5183 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5185 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5186 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5187 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5188 "operands[2] = gen_highpart (SImode, operands[0]);
5189 operands[3] = gen_highpart (SImode, operands[1]);
5190 operands[4] = gen_lowpart (SImode, operands[0]);
5191 operands[5] = gen_lowpart (SImode, operands[1]);"
5192 [(set_attr "length" "2")])
5194 (define_insn "*negdi2_sp64"
5195 [(set (match_operand:DI 0 "register_operand" "=r")
5196 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5198 "sub\t%%g0, %1, %0")
5200 (define_insn "negsi2"
5201 [(set (match_operand:SI 0 "register_operand" "=r")
5202 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5204 "sub\t%%g0, %1, %0")
5206 (define_insn "*cmp_cc_neg"
5207 [(set (reg:CC_NOOV CC_REG)
5208 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5211 "subcc\t%%g0, %0, %%g0"
5212 [(set_attr "type" "compare")])
5214 (define_insn "*cmp_ccx_neg"
5215 [(set (reg:CCX_NOOV CC_REG)
5216 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5219 "subcc\t%%g0, %0, %%g0"
5220 [(set_attr "type" "compare")])
5222 (define_insn "*cmp_cc_set_neg"
5223 [(set (reg:CC_NOOV CC_REG)
5224 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5226 (set (match_operand:SI 0 "register_operand" "=r")
5227 (neg:SI (match_dup 1)))]
5229 "subcc\t%%g0, %1, %0"
5230 [(set_attr "type" "compare")])
5232 (define_insn "*cmp_ccx_set_neg"
5233 [(set (reg:CCX_NOOV CC_REG)
5234 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5236 (set (match_operand:DI 0 "register_operand" "=r")
5237 (neg:DI (match_dup 1)))]
5239 "subcc\t%%g0, %1, %0"
5240 [(set_attr "type" "compare")])
5242 ;; We cannot use the "not" pseudo insn because the Sun assembler
5243 ;; does not know how to make it work for constants.
5244 (define_expand "one_cmpl<V64I:mode>2"
5245 [(set (match_operand:V64I 0 "register_operand" "")
5246 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5250 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5251 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5252 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5257 "&& reload_completed
5258 && ((GET_CODE (operands[0]) == REG
5259 && REGNO (operands[0]) < 32)
5260 || (GET_CODE (operands[0]) == SUBREG
5261 && GET_CODE (SUBREG_REG (operands[0])) == REG
5262 && REGNO (SUBREG_REG (operands[0])) < 32))"
5263 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5264 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5265 "operands[2] = gen_highpart (SImode, operands[0]);
5266 operands[3] = gen_highpart (SImode, operands[1]);
5267 operands[4] = gen_lowpart (SImode, operands[0]);
5268 operands[5] = gen_lowpart (SImode, operands[1]);"
5269 [(set_attr "type" "*,fga")
5270 (set_attr "length" "2,*")
5271 (set_attr "fptype" "*,double")])
5273 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5274 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5275 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5280 [(set_attr "type" "*,fga")
5281 (set_attr "fptype" "*,double")])
5283 (define_insn "one_cmpl<V32I:mode>2"
5284 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5285 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5290 [(set_attr "type" "*,fga")
5291 (set_attr "fptype" "*,single")])
5293 (define_insn "*cmp_cc_not"
5294 [(set (reg:CC CC_REG)
5295 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5298 "xnorcc\t%%g0, %0, %%g0"
5299 [(set_attr "type" "compare")])
5301 (define_insn "*cmp_ccx_not"
5302 [(set (reg:CCX CC_REG)
5303 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5306 "xnorcc\t%%g0, %0, %%g0"
5307 [(set_attr "type" "compare")])
5309 (define_insn "*cmp_cc_set_not"
5310 [(set (reg:CC CC_REG)
5311 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5313 (set (match_operand:SI 0 "register_operand" "=r")
5314 (not:SI (match_dup 1)))]
5316 "xnorcc\t%%g0, %1, %0"
5317 [(set_attr "type" "compare")])
5319 (define_insn "*cmp_ccx_set_not"
5320 [(set (reg:CCX CC_REG)
5321 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5323 (set (match_operand:DI 0 "register_operand" "=r")
5324 (not:DI (match_dup 1)))]
5326 "xnorcc\t%%g0, %1, %0"
5327 [(set_attr "type" "compare")])
5329 (define_insn "*cmp_cc_set"
5330 [(set (match_operand:SI 0 "register_operand" "=r")
5331 (match_operand:SI 1 "register_operand" "r"))
5332 (set (reg:CC CC_REG)
5333 (compare:CC (match_dup 1)
5337 [(set_attr "type" "compare")])
5339 (define_insn "*cmp_ccx_set64"
5340 [(set (match_operand:DI 0 "register_operand" "=r")
5341 (match_operand:DI 1 "register_operand" "r"))
5342 (set (reg:CCX CC_REG)
5343 (compare:CCX (match_dup 1)
5347 [(set_attr "type" "compare")])
5350 ;; Floating point arithmetic instructions.
5352 (define_expand "addtf3"
5353 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5354 (plus: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 (PLUS, operands); DONE;")
5359 (define_insn "*addtf3_hq"
5360 [(set (match_operand:TF 0 "register_operand" "=e")
5361 (plus:TF (match_operand:TF 1 "register_operand" "e")
5362 (match_operand:TF 2 "register_operand" "e")))]
5363 "TARGET_FPU && TARGET_HARD_QUAD"
5365 [(set_attr "type" "fp")])
5367 (define_insn "adddf3"
5368 [(set (match_operand:DF 0 "register_operand" "=e")
5369 (plus:DF (match_operand:DF 1 "register_operand" "e")
5370 (match_operand:DF 2 "register_operand" "e")))]
5373 [(set_attr "type" "fp")
5374 (set_attr "fptype" "double")])
5376 (define_insn "addsf3"
5377 [(set (match_operand:SF 0 "register_operand" "=f")
5378 (plus:SF (match_operand:SF 1 "register_operand" "f")
5379 (match_operand:SF 2 "register_operand" "f")))]
5382 [(set_attr "type" "fp")])
5384 (define_expand "subtf3"
5385 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5386 (minus:TF (match_operand:TF 1 "general_operand" "")
5387 (match_operand:TF 2 "general_operand" "")))]
5388 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5389 "emit_tfmode_binop (MINUS, operands); DONE;")
5391 (define_insn "*subtf3_hq"
5392 [(set (match_operand:TF 0 "register_operand" "=e")
5393 (minus:TF (match_operand:TF 1 "register_operand" "e")
5394 (match_operand:TF 2 "register_operand" "e")))]
5395 "TARGET_FPU && TARGET_HARD_QUAD"
5397 [(set_attr "type" "fp")])
5399 (define_insn "subdf3"
5400 [(set (match_operand:DF 0 "register_operand" "=e")
5401 (minus:DF (match_operand:DF 1 "register_operand" "e")
5402 (match_operand:DF 2 "register_operand" "e")))]
5405 [(set_attr "type" "fp")
5406 (set_attr "fptype" "double")])
5408 (define_insn "subsf3"
5409 [(set (match_operand:SF 0 "register_operand" "=f")
5410 (minus:SF (match_operand:SF 1 "register_operand" "f")
5411 (match_operand:SF 2 "register_operand" "f")))]
5414 [(set_attr "type" "fp")])
5416 (define_expand "multf3"
5417 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5418 (mult:TF (match_operand:TF 1 "general_operand" "")
5419 (match_operand:TF 2 "general_operand" "")))]
5420 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5421 "emit_tfmode_binop (MULT, operands); DONE;")
5423 (define_insn "*multf3_hq"
5424 [(set (match_operand:TF 0 "register_operand" "=e")
5425 (mult:TF (match_operand:TF 1 "register_operand" "e")
5426 (match_operand:TF 2 "register_operand" "e")))]
5427 "TARGET_FPU && TARGET_HARD_QUAD"
5429 [(set_attr "type" "fpmul")])
5431 (define_insn "muldf3"
5432 [(set (match_operand:DF 0 "register_operand" "=e")
5433 (mult:DF (match_operand:DF 1 "register_operand" "e")
5434 (match_operand:DF 2 "register_operand" "e")))]
5437 [(set_attr "type" "fpmul")
5438 (set_attr "fptype" "double")])
5440 (define_insn "mulsf3"
5441 [(set (match_operand:SF 0 "register_operand" "=f")
5442 (mult:SF (match_operand:SF 1 "register_operand" "f")
5443 (match_operand:SF 2 "register_operand" "f")))]
5446 [(set_attr "type" "fpmul")])
5448 (define_insn "*muldf3_extend"
5449 [(set (match_operand:DF 0 "register_operand" "=e")
5450 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5451 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5452 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5453 "fsmuld\t%1, %2, %0"
5454 [(set_attr "type" "fpmul")
5455 (set_attr "fptype" "double")])
5457 (define_insn "*multf3_extend"
5458 [(set (match_operand:TF 0 "register_operand" "=e")
5459 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5460 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5461 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5462 "fdmulq\t%1, %2, %0"
5463 [(set_attr "type" "fpmul")])
5465 (define_expand "divtf3"
5466 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5467 (div:TF (match_operand:TF 1 "general_operand" "")
5468 (match_operand:TF 2 "general_operand" "")))]
5469 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5470 "emit_tfmode_binop (DIV, operands); DONE;")
5472 ;; don't have timing for quad-prec. divide.
5473 (define_insn "*divtf3_hq"
5474 [(set (match_operand:TF 0 "register_operand" "=e")
5475 (div:TF (match_operand:TF 1 "register_operand" "e")
5476 (match_operand:TF 2 "register_operand" "e")))]
5477 "TARGET_FPU && TARGET_HARD_QUAD"
5479 [(set_attr "type" "fpdivd")])
5481 (define_insn "divdf3"
5482 [(set (match_operand:DF 0 "register_operand" "=e")
5483 (div:DF (match_operand:DF 1 "register_operand" "e")
5484 (match_operand:DF 2 "register_operand" "e")))]
5487 [(set_attr "type" "fpdivd")
5488 (set_attr "fptype" "double")])
5490 (define_insn "divsf3"
5491 [(set (match_operand:SF 0 "register_operand" "=f")
5492 (div:SF (match_operand:SF 1 "register_operand" "f")
5493 (match_operand:SF 2 "register_operand" "f")))]
5496 [(set_attr "type" "fpdivs")])
5498 (define_expand "negtf2"
5499 [(set (match_operand:TF 0 "register_operand" "=e,e")
5500 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5504 (define_insn_and_split "*negtf2_notv9"
5505 [(set (match_operand:TF 0 "register_operand" "=e,e")
5506 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5507 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5513 "&& reload_completed
5514 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5515 [(set (match_dup 2) (neg:SF (match_dup 3)))
5516 (set (match_dup 4) (match_dup 5))
5517 (set (match_dup 6) (match_dup 7))]
5518 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5519 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5520 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5521 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5522 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5523 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5524 [(set_attr "type" "fpmove,*")
5525 (set_attr "length" "*,2")])
5527 (define_insn_and_split "*negtf2_v9"
5528 [(set (match_operand:TF 0 "register_operand" "=e,e")
5529 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5530 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5531 "TARGET_FPU && TARGET_V9"
5535 "&& reload_completed
5536 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5537 [(set (match_dup 2) (neg:DF (match_dup 3)))
5538 (set (match_dup 4) (match_dup 5))]
5539 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5540 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5541 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5542 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5543 [(set_attr "type" "fpmove,*")
5544 (set_attr "length" "*,2")
5545 (set_attr "fptype" "double")])
5547 (define_expand "negdf2"
5548 [(set (match_operand:DF 0 "register_operand" "")
5549 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5553 (define_insn_and_split "*negdf2_notv9"
5554 [(set (match_operand:DF 0 "register_operand" "=e,e")
5555 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5556 "TARGET_FPU && ! TARGET_V9"
5560 "&& reload_completed
5561 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5562 [(set (match_dup 2) (neg:SF (match_dup 3)))
5563 (set (match_dup 4) (match_dup 5))]
5564 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5565 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5566 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5567 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5568 [(set_attr "type" "fpmove,*")
5569 (set_attr "length" "*,2")])
5571 (define_insn "*negdf2_v9"
5572 [(set (match_operand:DF 0 "register_operand" "=e")
5573 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5574 "TARGET_FPU && TARGET_V9"
5576 [(set_attr "type" "fpmove")
5577 (set_attr "fptype" "double")])
5579 (define_insn "negsf2"
5580 [(set (match_operand:SF 0 "register_operand" "=f")
5581 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5584 [(set_attr "type" "fpmove")])
5586 (define_expand "abstf2"
5587 [(set (match_operand:TF 0 "register_operand" "")
5588 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5592 (define_insn_and_split "*abstf2_notv9"
5593 [(set (match_operand:TF 0 "register_operand" "=e,e")
5594 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5595 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5596 "TARGET_FPU && ! TARGET_V9"
5600 "&& reload_completed
5601 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5602 [(set (match_dup 2) (abs:SF (match_dup 3)))
5603 (set (match_dup 4) (match_dup 5))
5604 (set (match_dup 6) (match_dup 7))]
5605 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5606 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5607 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5608 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5609 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5610 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5611 [(set_attr "type" "fpmove,*")
5612 (set_attr "length" "*,2")])
5614 (define_insn "*abstf2_hq_v9"
5615 [(set (match_operand:TF 0 "register_operand" "=e,e")
5616 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5617 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5621 [(set_attr "type" "fpmove")
5622 (set_attr "fptype" "double,*")])
5624 (define_insn_and_split "*abstf2_v9"
5625 [(set (match_operand:TF 0 "register_operand" "=e,e")
5626 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5627 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5631 "&& reload_completed
5632 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5633 [(set (match_dup 2) (abs:DF (match_dup 3)))
5634 (set (match_dup 4) (match_dup 5))]
5635 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5636 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5637 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5638 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5639 [(set_attr "type" "fpmove,*")
5640 (set_attr "length" "*,2")
5641 (set_attr "fptype" "double,*")])
5643 (define_expand "absdf2"
5644 [(set (match_operand:DF 0 "register_operand" "")
5645 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5649 (define_insn_and_split "*absdf2_notv9"
5650 [(set (match_operand:DF 0 "register_operand" "=e,e")
5651 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5652 "TARGET_FPU && ! TARGET_V9"
5656 "&& reload_completed
5657 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5658 [(set (match_dup 2) (abs:SF (match_dup 3)))
5659 (set (match_dup 4) (match_dup 5))]
5660 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5661 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5662 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5663 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5664 [(set_attr "type" "fpmove,*")
5665 (set_attr "length" "*,2")])
5667 (define_insn "*absdf2_v9"
5668 [(set (match_operand:DF 0 "register_operand" "=e")
5669 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5670 "TARGET_FPU && TARGET_V9"
5672 [(set_attr "type" "fpmove")
5673 (set_attr "fptype" "double")])
5675 (define_insn "abssf2"
5676 [(set (match_operand:SF 0 "register_operand" "=f")
5677 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5680 [(set_attr "type" "fpmove")])
5682 (define_expand "sqrttf2"
5683 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5684 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5685 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5686 "emit_tfmode_unop (SQRT, operands); DONE;")
5688 (define_insn "*sqrttf2_hq"
5689 [(set (match_operand:TF 0 "register_operand" "=e")
5690 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5691 "TARGET_FPU && TARGET_HARD_QUAD"
5693 [(set_attr "type" "fpsqrtd")])
5695 (define_insn "sqrtdf2"
5696 [(set (match_operand:DF 0 "register_operand" "=e")
5697 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5700 [(set_attr "type" "fpsqrtd")
5701 (set_attr "fptype" "double")])
5703 (define_insn "sqrtsf2"
5704 [(set (match_operand:SF 0 "register_operand" "=f")
5705 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5708 [(set_attr "type" "fpsqrts")])
5711 ;; Arithmetic shift instructions.
5713 (define_insn "ashlsi3"
5714 [(set (match_operand:SI 0 "register_operand" "=r")
5715 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5716 (match_operand:SI 2 "arith_operand" "rI")))]
5719 if (GET_CODE (operands[2]) == CONST_INT)
5720 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5721 return "sll\t%1, %2, %0";
5724 (if_then_else (match_operand 2 "const_one_operand" "")
5725 (const_string "ialu") (const_string "shift")))])
5727 (define_expand "ashldi3"
5728 [(set (match_operand:DI 0 "register_operand" "=r")
5729 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5730 (match_operand:SI 2 "arith_operand" "rI")))]
5731 "TARGET_ARCH64 || TARGET_V8PLUS"
5733 if (! TARGET_ARCH64)
5735 if (GET_CODE (operands[2]) == CONST_INT)
5737 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5742 (define_insn "*ashldi3_sp64"
5743 [(set (match_operand:DI 0 "register_operand" "=r")
5744 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5745 (match_operand:SI 2 "arith_operand" "rI")))]
5748 if (GET_CODE (operands[2]) == CONST_INT)
5749 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5750 return "sllx\t%1, %2, %0";
5753 (if_then_else (match_operand 2 "const_one_operand" "")
5754 (const_string "ialu") (const_string "shift")))])
5757 (define_insn "ashldi3_v8plus"
5758 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5759 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5760 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5761 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5763 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5764 [(set_attr "type" "multi")
5765 (set_attr "length" "5,5,6")])
5767 ;; Optimize (1LL<<x)-1
5768 ;; XXX this also needs to be fixed to handle equal subregs
5769 ;; XXX first before we could re-enable it.
5771 ; [(set (match_operand:DI 0 "register_operand" "=h")
5772 ; (plus:DI (ashift:DI (const_int 1)
5773 ; (match_operand:SI 1 "arith_operand" "rI"))
5775 ; "0 && TARGET_V8PLUS"
5777 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5778 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5779 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5781 ; [(set_attr "type" "multi")
5782 ; (set_attr "length" "4")])
5784 (define_insn "*cmp_cc_ashift_1"
5785 [(set (reg:CC_NOOV CC_REG)
5786 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5790 "addcc\t%0, %0, %%g0"
5791 [(set_attr "type" "compare")])
5793 (define_insn "*cmp_cc_set_ashift_1"
5794 [(set (reg:CC_NOOV CC_REG)
5795 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5798 (set (match_operand:SI 0 "register_operand" "=r")
5799 (ashift:SI (match_dup 1) (const_int 1)))]
5802 [(set_attr "type" "compare")])
5804 (define_insn "ashrsi3"
5805 [(set (match_operand:SI 0 "register_operand" "=r")
5806 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5807 (match_operand:SI 2 "arith_operand" "rI")))]
5810 if (GET_CODE (operands[2]) == CONST_INT)
5811 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5812 return "sra\t%1, %2, %0";
5814 [(set_attr "type" "shift")])
5816 (define_insn "*ashrsi3_extend"
5817 [(set (match_operand:DI 0 "register_operand" "=r")
5818 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5819 (match_operand:SI 2 "arith_operand" "r"))))]
5822 [(set_attr "type" "shift")])
5824 ;; This handles the case as above, but with constant shift instead of
5825 ;; register. Combiner "simplifies" it for us a little bit though.
5826 (define_insn "*ashrsi3_extend2"
5827 [(set (match_operand:DI 0 "register_operand" "=r")
5828 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5830 (match_operand:SI 2 "small_int_operand" "I")))]
5831 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5833 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5834 return "sra\t%1, %2, %0";
5836 [(set_attr "type" "shift")])
5838 (define_expand "ashrdi3"
5839 [(set (match_operand:DI 0 "register_operand" "=r")
5840 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5841 (match_operand:SI 2 "arith_operand" "rI")))]
5842 "TARGET_ARCH64 || TARGET_V8PLUS"
5844 if (! TARGET_ARCH64)
5846 if (GET_CODE (operands[2]) == CONST_INT)
5847 FAIL; /* prefer generic code in this case */
5848 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5853 (define_insn "*ashrdi3_sp64"
5854 [(set (match_operand:DI 0 "register_operand" "=r")
5855 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5856 (match_operand:SI 2 "arith_operand" "rI")))]
5860 if (GET_CODE (operands[2]) == CONST_INT)
5861 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5862 return "srax\t%1, %2, %0";
5864 [(set_attr "type" "shift")])
5867 (define_insn "ashrdi3_v8plus"
5868 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5869 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5870 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5871 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5873 "* return output_v8plus_shift (operands, insn, \"srax\");"
5874 [(set_attr "type" "multi")
5875 (set_attr "length" "5,5,6")])
5877 (define_insn "lshrsi3"
5878 [(set (match_operand:SI 0 "register_operand" "=r")
5879 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5880 (match_operand:SI 2 "arith_operand" "rI")))]
5883 if (GET_CODE (operands[2]) == CONST_INT)
5884 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5885 return "srl\t%1, %2, %0";
5887 [(set_attr "type" "shift")])
5889 ;; This handles the case where
5890 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5891 ;; but combiner "simplifies" it for us.
5892 (define_insn "*lshrsi3_extend"
5893 [(set (match_operand:DI 0 "register_operand" "=r")
5894 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5895 (match_operand:SI 2 "arith_operand" "r")) 0)
5896 (match_operand 3 "const_int_operand" "")))]
5897 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5899 [(set_attr "type" "shift")])
5901 ;; This handles the case where
5902 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5903 ;; but combiner "simplifies" it for us.
5904 (define_insn "*lshrsi3_extend2"
5905 [(set (match_operand:DI 0 "register_operand" "=r")
5906 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5907 (match_operand 2 "small_int_operand" "I")
5909 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5911 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5912 return "srl\t%1, %2, %0";
5914 [(set_attr "type" "shift")])
5916 (define_expand "lshrdi3"
5917 [(set (match_operand:DI 0 "register_operand" "=r")
5918 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5919 (match_operand:SI 2 "arith_operand" "rI")))]
5920 "TARGET_ARCH64 || TARGET_V8PLUS"
5922 if (! TARGET_ARCH64)
5924 if (GET_CODE (operands[2]) == CONST_INT)
5926 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5931 (define_insn "*lshrdi3_sp64"
5932 [(set (match_operand:DI 0 "register_operand" "=r")
5933 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5934 (match_operand:SI 2 "arith_operand" "rI")))]
5937 if (GET_CODE (operands[2]) == CONST_INT)
5938 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5939 return "srlx\t%1, %2, %0";
5941 [(set_attr "type" "shift")])
5944 (define_insn "lshrdi3_v8plus"
5945 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5946 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5947 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5948 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5950 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5951 [(set_attr "type" "multi")
5952 (set_attr "length" "5,5,6")])
5955 [(set (match_operand:SI 0 "register_operand" "=r")
5956 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5958 (match_operand:SI 2 "small_int_operand" "I")))]
5959 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5961 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5962 return "srax\t%1, %2, %0";
5964 [(set_attr "type" "shift")])
5967 [(set (match_operand:SI 0 "register_operand" "=r")
5968 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5970 (match_operand:SI 2 "small_int_operand" "I")))]
5971 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5973 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5974 return "srlx\t%1, %2, %0";
5976 [(set_attr "type" "shift")])
5979 [(set (match_operand:SI 0 "register_operand" "=r")
5980 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5981 (match_operand:SI 2 "small_int_operand" "I")) 4)
5982 (match_operand:SI 3 "small_int_operand" "I")))]
5984 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5985 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5986 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5988 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5990 return "srax\t%1, %2, %0";
5992 [(set_attr "type" "shift")])
5995 [(set (match_operand:SI 0 "register_operand" "=r")
5996 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5997 (match_operand:SI 2 "small_int_operand" "I")) 4)
5998 (match_operand:SI 3 "small_int_operand" "I")))]
6000 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6001 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6002 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6004 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6006 return "srlx\t%1, %2, %0";
6008 [(set_attr "type" "shift")])
6011 ;; Unconditional and other jump instructions.
6014 [(set (pc) (label_ref (match_operand 0 "" "")))]
6016 "* return output_ubranch (operands[0], 0, insn);"
6017 [(set_attr "type" "uncond_branch")])
6019 (define_expand "tablejump"
6020 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6021 (use (label_ref (match_operand 1 "" "")))])]
6024 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6026 /* In pic mode, our address differences are against the base of the
6027 table. Add that base value back in; CSE ought to be able to combine
6028 the two address loads. */
6032 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6034 if (CASE_VECTOR_MODE != Pmode)
6035 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6036 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6037 operands[0] = memory_address (Pmode, tmp);
6041 (define_insn "*tablejump_sp32"
6042 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6043 (use (label_ref (match_operand 1 "" "")))]
6046 [(set_attr "type" "uncond_branch")])
6048 (define_insn "*tablejump_sp64"
6049 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6050 (use (label_ref (match_operand 1 "" "")))]
6053 [(set_attr "type" "uncond_branch")])
6056 ;; Jump to subroutine instructions.
6058 (define_expand "call"
6059 ;; Note that this expression is not used for generating RTL.
6060 ;; All the RTL is generated explicitly below.
6061 [(call (match_operand 0 "call_operand" "")
6062 (match_operand 3 "" "i"))]
6063 ;; operands[2] is next_arg_register
6064 ;; operands[3] is struct_value_size_rtx.
6069 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6071 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6073 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6075 /* This is really a PIC sequence. We want to represent
6076 it as a funny jump so its delay slots can be filled.
6078 ??? But if this really *is* a CALL, will not it clobber the
6079 call-clobbered registers? We lose this if it is a JUMP_INSN.
6080 Why cannot we have delay slots filled if it were a CALL? */
6082 /* We accept negative sizes for untyped calls. */
6083 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6088 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6090 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6096 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6097 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6101 fn_rtx = operands[0];
6103 /* We accept negative sizes for untyped calls. */
6104 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6105 sparc_emit_call_insn
6108 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6110 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6113 sparc_emit_call_insn
6116 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6117 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6125 ;; We can't use the same pattern for these two insns, because then registers
6126 ;; in the address may not be properly reloaded.
6128 (define_insn "*call_address_sp32"
6129 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6130 (match_operand 1 "" ""))
6131 (clobber (reg:SI O7_REG))]
6132 ;;- Do not use operand 1 for most machines.
6135 [(set_attr "type" "call")])
6137 (define_insn "*call_symbolic_sp32"
6138 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6139 (match_operand 1 "" ""))
6140 (clobber (reg:SI O7_REG))]
6141 ;;- Do not use operand 1 for most machines.
6144 [(set_attr "type" "call")])
6146 (define_insn "*call_address_sp64"
6147 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6148 (match_operand 1 "" ""))
6149 (clobber (reg:DI O7_REG))]
6150 ;;- Do not use operand 1 for most machines.
6153 [(set_attr "type" "call")])
6155 (define_insn "*call_symbolic_sp64"
6156 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6157 (match_operand 1 "" ""))
6158 (clobber (reg:DI O7_REG))]
6159 ;;- Do not use operand 1 for most machines.
6162 [(set_attr "type" "call")])
6164 ;; This is a call that wants a structure value.
6165 ;; There is no such critter for v9 (??? we may need one anyway).
6166 (define_insn "*call_address_struct_value_sp32"
6167 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6168 (match_operand 1 "" ""))
6169 (match_operand 2 "immediate_operand" "")
6170 (clobber (reg:SI O7_REG))]
6171 ;;- Do not use operand 1 for most machines.
6172 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6174 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6175 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6177 [(set_attr "type" "call_no_delay_slot")
6178 (set_attr "length" "3")])
6180 ;; This is a call that wants a structure value.
6181 ;; There is no such critter for v9 (??? we may need one anyway).
6182 (define_insn "*call_symbolic_struct_value_sp32"
6183 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6184 (match_operand 1 "" ""))
6185 (match_operand 2 "immediate_operand" "")
6186 (clobber (reg:SI O7_REG))]
6187 ;;- Do not use operand 1 for most machines.
6188 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6190 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6191 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6193 [(set_attr "type" "call_no_delay_slot")
6194 (set_attr "length" "3")])
6196 ;; This is a call that may want a structure value. This is used for
6198 (define_insn "*call_address_untyped_struct_value_sp32"
6199 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6200 (match_operand 1 "" ""))
6201 (match_operand 2 "immediate_operand" "")
6202 (clobber (reg:SI O7_REG))]
6203 ;;- Do not use operand 1 for most machines.
6204 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6205 "call\t%a0, %1\n\t nop\n\tnop"
6206 [(set_attr "type" "call_no_delay_slot")
6207 (set_attr "length" "3")])
6209 ;; This is a call that may want a structure value. This is used for
6211 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6212 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6213 (match_operand 1 "" ""))
6214 (match_operand 2 "immediate_operand" "")
6215 (clobber (reg:SI O7_REG))]
6216 ;;- Do not use operand 1 for most machines.
6217 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6218 "call\t%a0, %1\n\t nop\n\tnop"
6219 [(set_attr "type" "call_no_delay_slot")
6220 (set_attr "length" "3")])
6222 (define_expand "call_value"
6223 ;; Note that this expression is not used for generating RTL.
6224 ;; All the RTL is generated explicitly below.
6225 [(set (match_operand 0 "register_operand" "=rf")
6226 (call (match_operand 1 "" "")
6227 (match_operand 4 "" "")))]
6228 ;; operand 2 is stack_size_rtx
6229 ;; operand 3 is next_arg_register
6235 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6237 fn_rtx = operands[1];
6240 gen_rtx_SET (VOIDmode, operands[0],
6241 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6242 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6244 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6249 (define_insn "*call_value_address_sp32"
6250 [(set (match_operand 0 "" "=rf")
6251 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6252 (match_operand 2 "" "")))
6253 (clobber (reg:SI O7_REG))]
6254 ;;- Do not use operand 2 for most machines.
6257 [(set_attr "type" "call")])
6259 (define_insn "*call_value_symbolic_sp32"
6260 [(set (match_operand 0 "" "=rf")
6261 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6262 (match_operand 2 "" "")))
6263 (clobber (reg:SI O7_REG))]
6264 ;;- Do not use operand 2 for most machines.
6267 [(set_attr "type" "call")])
6269 (define_insn "*call_value_address_sp64"
6270 [(set (match_operand 0 "" "")
6271 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6272 (match_operand 2 "" "")))
6273 (clobber (reg:DI O7_REG))]
6274 ;;- Do not use operand 2 for most machines.
6277 [(set_attr "type" "call")])
6279 (define_insn "*call_value_symbolic_sp64"
6280 [(set (match_operand 0 "" "")
6281 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6282 (match_operand 2 "" "")))
6283 (clobber (reg:DI O7_REG))]
6284 ;;- Do not use operand 2 for most machines.
6287 [(set_attr "type" "call")])
6289 (define_expand "untyped_call"
6290 [(parallel [(call (match_operand 0 "" "")
6292 (match_operand:BLK 1 "memory_operand" "")
6293 (match_operand 2 "" "")])]
6296 rtx valreg1 = gen_rtx_REG (DImode, 8);
6297 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6298 rtx result = operands[1];
6300 /* Pass constm1 to indicate that it may expect a structure value, but
6301 we don't know what size it is. */
6302 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6304 /* Save the function value registers. */
6305 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6306 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6309 /* The optimizer does not know that the call sets the function value
6310 registers we stored in the result block. We avoid problems by
6311 claiming that all hard registers are used and clobbered at this
6313 emit_insn (gen_blockage ());
6318 ;; Tail call instructions.
6320 (define_expand "sibcall"
6321 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6326 (define_insn "*sibcall_symbolic_sp32"
6327 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6328 (match_operand 1 "" ""))
6331 "* return output_sibcall(insn, operands[0]);"
6332 [(set_attr "type" "sibcall")])
6334 (define_insn "*sibcall_symbolic_sp64"
6335 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6336 (match_operand 1 "" ""))
6339 "* return output_sibcall(insn, operands[0]);"
6340 [(set_attr "type" "sibcall")])
6342 (define_expand "sibcall_value"
6343 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6344 (call (match_operand 1 "" "") (const_int 0)))
6349 (define_insn "*sibcall_value_symbolic_sp32"
6350 [(set (match_operand 0 "" "=rf")
6351 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6352 (match_operand 2 "" "")))
6355 "* return output_sibcall(insn, operands[1]);"
6356 [(set_attr "type" "sibcall")])
6358 (define_insn "*sibcall_value_symbolic_sp64"
6359 [(set (match_operand 0 "" "")
6360 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6361 (match_operand 2 "" "")))
6364 "* return output_sibcall(insn, operands[1]);"
6365 [(set_attr "type" "sibcall")])
6368 ;; Special instructions.
6370 (define_expand "prologue"
6375 sparc_flat_expand_prologue ();
6377 sparc_expand_prologue ();
6381 ;; The "register window save" insn is modelled as follows. The dwarf2
6382 ;; information is manually added in emit_window_save.
6384 (define_insn "window_save"
6386 [(match_operand 0 "arith_operand" "rI")]
6389 "save\t%%sp, %0, %%sp"
6390 [(set_attr "type" "savew")])
6392 (define_expand "epilogue"
6397 sparc_flat_expand_epilogue (false);
6399 sparc_expand_epilogue (false);
6402 (define_expand "sibcall_epilogue"
6407 sparc_flat_expand_epilogue (false);
6409 sparc_expand_epilogue (false);
6413 (define_expand "eh_return"
6414 [(use (match_operand 0 "general_operand" ""))]
6417 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6418 emit_jump_insn (gen_eh_return_internal ());
6423 (define_insn_and_split "eh_return_internal"
6427 "epilogue_completed"
6431 sparc_flat_expand_epilogue (true);
6433 sparc_expand_epilogue (true);
6436 (define_expand "return"
6438 "sparc_can_use_return_insn_p ()"
6441 (define_insn "*return_internal"
6444 "* return output_return (insn);"
6445 [(set_attr "type" "return")
6446 (set (attr "length")
6447 (cond [(eq_attr "calls_eh_return" "true")
6448 (if_then_else (eq_attr "delayed_branch" "true")
6449 (if_then_else (ior (eq_attr "isa" "v9")
6450 (eq_attr "flat" "true"))
6453 (if_then_else (eq_attr "flat" "true")
6456 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6457 (if_then_else (eq_attr "empty_delay_slot" "true")
6460 (eq_attr "empty_delay_slot" "true")
6461 (if_then_else (eq_attr "delayed_branch" "true")
6466 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6467 ;; all of memory. This blocks insns from being moved across this point.
6469 (define_insn "blockage"
6470 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6473 [(set_attr "length" "0")])
6475 (define_expand "probe_stack"
6476 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6480 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6483 (define_insn "probe_stack_range<P:mode>"
6484 [(set (match_operand:P 0 "register_operand" "=r")
6485 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6486 (match_operand:P 2 "register_operand" "r")]
6487 UNSPECV_PROBE_STACK_RANGE))]
6489 "* return output_probe_stack_range (operands[0], operands[2]);"
6490 [(set_attr "type" "multi")])
6492 ;; Prepare to return any type including a structure value.
6494 (define_expand "untyped_return"
6495 [(match_operand:BLK 0 "memory_operand" "")
6496 (match_operand 1 "" "")]
6499 rtx valreg1 = gen_rtx_REG (DImode, 24);
6500 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6501 rtx result = operands[0];
6503 if (! TARGET_ARCH64)
6505 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6506 rtx value = gen_reg_rtx (SImode);
6508 /* Fetch the instruction where we will return to and see if it's an unimp
6509 instruction (the most significant 10 bits will be zero). If so,
6510 update the return address to skip the unimp instruction. */
6511 emit_move_insn (value,
6512 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6513 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6514 emit_insn (gen_update_return (rtnreg, value));
6517 /* Reload the function value registers. */
6518 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6519 emit_move_insn (valreg2,
6520 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6522 /* Put USE insns before the return. */
6526 /* Construct the return. */
6527 expand_naked_return ();
6532 ;; Adjust the return address conditionally. If the value of op1 is equal
6533 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6534 ;; This is technically *half* the check required by the 32-bit SPARC
6535 ;; psABI. This check only ensures that an "unimp" insn was written by
6536 ;; the caller, but doesn't check to see if the expected size matches
6537 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6538 ;; only used by the above code "untyped_return".
6540 (define_insn "update_return"
6541 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6542 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6545 if (flag_delayed_branch)
6546 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6548 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6550 [(set (attr "type") (const_string "multi"))
6551 (set (attr "length")
6552 (if_then_else (eq_attr "delayed_branch" "true")
6561 (define_expand "indirect_jump"
6562 [(set (pc) (match_operand 0 "address_operand" "p"))]
6566 (define_insn "*branch_sp32"
6567 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6570 [(set_attr "type" "uncond_branch")])
6572 (define_insn "*branch_sp64"
6573 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6576 [(set_attr "type" "uncond_branch")])
6578 (define_expand "save_stack_nonlocal"
6579 [(set (match_operand 0 "memory_operand" "")
6580 (match_operand 1 "register_operand" ""))
6581 (set (match_dup 2) (match_dup 3))]
6584 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6585 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6586 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6589 (define_expand "restore_stack_nonlocal"
6590 [(set (match_operand 0 "register_operand" "")
6591 (match_operand 1 "memory_operand" ""))]
6594 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6597 (define_expand "nonlocal_goto"
6598 [(match_operand 0 "general_operand" "")
6599 (match_operand 1 "general_operand" "")
6600 (match_operand 2 "memory_operand" "")
6601 (match_operand 3 "memory_operand" "")]
6604 rtx r_label = copy_to_reg (operands[1]);
6605 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6606 rtx r_fp = operands[3];
6607 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6609 /* We need to flush all the register windows so that their contents will
6610 be re-synchronized by the restore insn of the target function. */
6612 emit_insn (gen_flush_register_windows ());
6614 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6615 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6617 /* Restore frame pointer for containing function. */
6618 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6619 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6621 /* USE of hard_frame_pointer_rtx added for consistency;
6622 not clear if really needed. */
6623 emit_use (hard_frame_pointer_rtx);
6624 emit_use (stack_pointer_rtx);
6626 /* We need to smuggle the load of %i7 as it is a fixed register. */
6627 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6632 (define_insn "nonlocal_goto_internal"
6633 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6634 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6635 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6637 if (flag_delayed_branch)
6640 return "jmp\t%0\n\t ldx\t%1, %%i7";
6642 return "jmp\t%0\n\t ld\t%1, %%i7";
6647 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6649 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6652 [(set (attr "type") (const_string "multi"))
6653 (set (attr "length")
6654 (if_then_else (eq_attr "delayed_branch" "true")
6658 (define_expand "builtin_setjmp_receiver"
6659 [(label_ref (match_operand 0 "" ""))]
6662 load_got_register ();
6666 ;; Special insn to flush register windows.
6668 (define_insn "flush_register_windows"
6669 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6671 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6672 [(set_attr "type" "flushw")])
6674 ;; Special pattern for the FLUSH instruction.
6676 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6677 ; of the define_insn otherwise missing a mode. We make "flush", aka
6678 ; gen_flush, the default one since sparc_initialize_trampoline uses
6679 ; it on SImode mem values.
6681 (define_insn "flush"
6682 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6684 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6685 [(set_attr "type" "iflush")])
6687 (define_insn "flushdi"
6688 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6690 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6691 [(set_attr "type" "iflush")])
6694 ;; Find first set instructions.
6696 ;; The scan instruction searches from the most significant bit while ffs
6697 ;; searches from the least significant bit. The bit index and treatment of
6698 ;; zero also differ. It takes at least 7 instructions to get the proper
6699 ;; result. Here is an obvious 8 instruction sequence.
6702 (define_insn "ffssi2"
6703 [(set (match_operand:SI 0 "register_operand" "=&r")
6704 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6705 (clobber (match_scratch:SI 2 "=&r"))]
6706 "TARGET_SPARCLITE || TARGET_SPARCLET"
6708 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";
6710 [(set_attr "type" "multi")
6711 (set_attr "length" "8")])
6713 ;; ??? This should be a define expand, so that the extra instruction have
6714 ;; a chance of being optimized away.
6716 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6717 ;; does, but no one uses that and we don't have a switch for it.
6719 ;(define_insn "ffsdi2"
6720 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6721 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6722 ; (clobber (match_scratch:DI 2 "=&r"))]
6724 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6725 ; [(set_attr "type" "multi")
6726 ; (set_attr "length" "4")])
6730 ;; Peepholes go at the end.
6732 ;; Optimize consecutive loads or stores into ldd and std when possible.
6733 ;; The conditions in which we do this are very restricted and are
6734 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6737 [(set (match_operand:SI 0 "memory_operand" "")
6739 (set (match_operand:SI 1 "memory_operand" "")
6742 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6745 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6748 [(set (match_operand:SI 0 "memory_operand" "")
6750 (set (match_operand:SI 1 "memory_operand" "")
6753 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6756 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6759 [(set (match_operand:SI 0 "register_operand" "")
6760 (match_operand:SI 1 "memory_operand" ""))
6761 (set (match_operand:SI 2 "register_operand" "")
6762 (match_operand:SI 3 "memory_operand" ""))]
6763 "registers_ok_for_ldd_peep (operands[0], operands[2])
6764 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6767 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6768 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6771 [(set (match_operand:SI 0 "memory_operand" "")
6772 (match_operand:SI 1 "register_operand" ""))
6773 (set (match_operand:SI 2 "memory_operand" "")
6774 (match_operand:SI 3 "register_operand" ""))]
6775 "registers_ok_for_ldd_peep (operands[1], operands[3])
6776 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6779 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6780 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6783 [(set (match_operand:SF 0 "register_operand" "")
6784 (match_operand:SF 1 "memory_operand" ""))
6785 (set (match_operand:SF 2 "register_operand" "")
6786 (match_operand:SF 3 "memory_operand" ""))]
6787 "registers_ok_for_ldd_peep (operands[0], operands[2])
6788 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6791 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6792 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6795 [(set (match_operand:SF 0 "memory_operand" "")
6796 (match_operand:SF 1 "register_operand" ""))
6797 (set (match_operand:SF 2 "memory_operand" "")
6798 (match_operand:SF 3 "register_operand" ""))]
6799 "registers_ok_for_ldd_peep (operands[1], operands[3])
6800 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6803 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6804 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6807 [(set (match_operand:SI 0 "register_operand" "")
6808 (match_operand:SI 1 "memory_operand" ""))
6809 (set (match_operand:SI 2 "register_operand" "")
6810 (match_operand:SI 3 "memory_operand" ""))]
6811 "registers_ok_for_ldd_peep (operands[2], operands[0])
6812 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6815 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6816 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6819 [(set (match_operand:SI 0 "memory_operand" "")
6820 (match_operand:SI 1 "register_operand" ""))
6821 (set (match_operand:SI 2 "memory_operand" "")
6822 (match_operand:SI 3 "register_operand" ""))]
6823 "registers_ok_for_ldd_peep (operands[3], operands[1])
6824 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6827 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6828 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6832 [(set (match_operand:SF 0 "register_operand" "")
6833 (match_operand:SF 1 "memory_operand" ""))
6834 (set (match_operand:SF 2 "register_operand" "")
6835 (match_operand:SF 3 "memory_operand" ""))]
6836 "registers_ok_for_ldd_peep (operands[2], operands[0])
6837 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6840 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6841 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6844 [(set (match_operand:SF 0 "memory_operand" "")
6845 (match_operand:SF 1 "register_operand" ""))
6846 (set (match_operand:SF 2 "memory_operand" "")
6847 (match_operand:SF 3 "register_operand" ""))]
6848 "registers_ok_for_ldd_peep (operands[3], operands[1])
6849 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6852 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6853 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6855 ;; Optimize the case of following a reg-reg move with a test
6856 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6857 ;; This can result from a float to fix conversion.
6860 [(set (match_operand:SI 0 "register_operand" "")
6861 (match_operand:SI 1 "register_operand" ""))
6862 (set (reg:CC CC_REG)
6863 (compare:CC (match_operand:SI 2 "register_operand" "")
6865 "(rtx_equal_p (operands[2], operands[0])
6866 || rtx_equal_p (operands[2], operands[1]))
6867 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6868 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6869 [(parallel [(set (match_dup 0) (match_dup 1))
6870 (set (reg:CC CC_REG)
6871 (compare:CC (match_dup 1) (const_int 0)))])]
6875 [(set (match_operand:DI 0 "register_operand" "")
6876 (match_operand:DI 1 "register_operand" ""))
6877 (set (reg:CCX CC_REG)
6878 (compare:CCX (match_operand:DI 2 "register_operand" "")
6881 && (rtx_equal_p (operands[2], operands[0])
6882 || rtx_equal_p (operands[2], operands[1]))
6883 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6884 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6885 [(parallel [(set (match_dup 0) (match_dup 1))
6886 (set (reg:CCX CC_REG)
6887 (compare:CCX (match_dup 1) (const_int 0)))])]
6891 ;; Prefetch instructions.
6893 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6894 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6895 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6897 (define_expand "prefetch"
6898 [(match_operand 0 "address_operand" "")
6899 (match_operand 1 "const_int_operand" "")
6900 (match_operand 2 "const_int_operand" "")]
6904 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6906 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6910 (define_insn "prefetch_64"
6911 [(prefetch (match_operand:DI 0 "address_operand" "p")
6912 (match_operand:DI 1 "const_int_operand" "n")
6913 (match_operand:DI 2 "const_int_operand" "n"))]
6916 static const char * const prefetch_instr[2][2] = {
6918 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6919 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6922 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6923 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6926 int read_or_write = INTVAL (operands[1]);
6927 int locality = INTVAL (operands[2]);
6929 gcc_assert (read_or_write == 0 || read_or_write == 1);
6930 gcc_assert (locality >= 0 && locality < 4);
6931 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6933 [(set_attr "type" "load")])
6935 (define_insn "prefetch_32"
6936 [(prefetch (match_operand:SI 0 "address_operand" "p")
6937 (match_operand:SI 1 "const_int_operand" "n")
6938 (match_operand:SI 2 "const_int_operand" "n"))]
6941 static const char * const prefetch_instr[2][2] = {
6943 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6944 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6947 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6948 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6951 int read_or_write = INTVAL (operands[1]);
6952 int locality = INTVAL (operands[2]);
6954 gcc_assert (read_or_write == 0 || read_or_write == 1);
6955 gcc_assert (locality >= 0 && locality < 4);
6956 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6958 [(set_attr "type" "load")])
6961 ;; Trap instructions.
6964 [(trap_if (const_int 1) (const_int 5))]
6967 [(set_attr "type" "trap")])
6969 (define_expand "ctrapsi4"
6970 [(trap_if (match_operator 0 "noov_compare_operator"
6971 [(match_operand:SI 1 "compare_operand" "")
6972 (match_operand:SI 2 "arith_operand" "")])
6973 (match_operand 3 ""))]
6975 "operands[1] = gen_compare_reg (operands[0]);
6976 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6978 operands[2] = const0_rtx;")
6980 (define_expand "ctrapdi4"
6981 [(trap_if (match_operator 0 "noov_compare_operator"
6982 [(match_operand:DI 1 "compare_operand" "")
6983 (match_operand:DI 2 "arith_operand" "")])
6984 (match_operand 3 ""))]
6986 "operands[1] = gen_compare_reg (operands[0]);
6987 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6989 operands[2] = const0_rtx;")
6993 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
6994 (match_operand:SI 1 "arith_operand" "rM"))]
6998 return "t%C0\t%%icc, %1";
7002 [(set_attr "type" "trap")])
7005 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7006 (match_operand:SI 1 "arith_operand" "rM"))]
7009 [(set_attr "type" "trap")])
7012 ;; TLS support instructions.
7014 (define_insn "tgd_hi22"
7015 [(set (match_operand:SI 0 "register_operand" "=r")
7016 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7019 "sethi\\t%%tgd_hi22(%a1), %0")
7021 (define_insn "tgd_lo10"
7022 [(set (match_operand:SI 0 "register_operand" "=r")
7023 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7024 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7027 "add\\t%1, %%tgd_lo10(%a2), %0")
7029 (define_insn "tgd_add32"
7030 [(set (match_operand:SI 0 "register_operand" "=r")
7031 (plus:SI (match_operand:SI 1 "register_operand" "r")
7032 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7033 (match_operand 3 "tgd_symbolic_operand" "")]
7035 "TARGET_TLS && TARGET_ARCH32"
7036 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7038 (define_insn "tgd_add64"
7039 [(set (match_operand:DI 0 "register_operand" "=r")
7040 (plus:DI (match_operand:DI 1 "register_operand" "r")
7041 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7042 (match_operand 3 "tgd_symbolic_operand" "")]
7044 "TARGET_TLS && TARGET_ARCH64"
7045 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7047 (define_insn "tgd_call32"
7048 [(set (match_operand 0 "register_operand" "=r")
7049 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7050 (match_operand 2 "tgd_symbolic_operand" "")]
7052 (match_operand 3 "" "")))
7053 (clobber (reg:SI O7_REG))]
7054 "TARGET_TLS && TARGET_ARCH32"
7055 "call\t%a1, %%tgd_call(%a2)%#"
7056 [(set_attr "type" "call")])
7058 (define_insn "tgd_call64"
7059 [(set (match_operand 0 "register_operand" "=r")
7060 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7061 (match_operand 2 "tgd_symbolic_operand" "")]
7063 (match_operand 3 "" "")))
7064 (clobber (reg:DI O7_REG))]
7065 "TARGET_TLS && TARGET_ARCH64"
7066 "call\t%a1, %%tgd_call(%a2)%#"
7067 [(set_attr "type" "call")])
7069 (define_insn "tldm_hi22"
7070 [(set (match_operand:SI 0 "register_operand" "=r")
7071 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7073 "sethi\\t%%tldm_hi22(%&), %0")
7075 (define_insn "tldm_lo10"
7076 [(set (match_operand:SI 0 "register_operand" "=r")
7077 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7078 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7080 "add\\t%1, %%tldm_lo10(%&), %0")
7082 (define_insn "tldm_add32"
7083 [(set (match_operand:SI 0 "register_operand" "=r")
7084 (plus:SI (match_operand:SI 1 "register_operand" "r")
7085 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7087 "TARGET_TLS && TARGET_ARCH32"
7088 "add\\t%1, %2, %0, %%tldm_add(%&)")
7090 (define_insn "tldm_add64"
7091 [(set (match_operand:DI 0 "register_operand" "=r")
7092 (plus:DI (match_operand:DI 1 "register_operand" "r")
7093 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7095 "TARGET_TLS && TARGET_ARCH64"
7096 "add\\t%1, %2, %0, %%tldm_add(%&)")
7098 (define_insn "tldm_call32"
7099 [(set (match_operand 0 "register_operand" "=r")
7100 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7102 (match_operand 2 "" "")))
7103 (clobber (reg:SI O7_REG))]
7104 "TARGET_TLS && TARGET_ARCH32"
7105 "call\t%a1, %%tldm_call(%&)%#"
7106 [(set_attr "type" "call")])
7108 (define_insn "tldm_call64"
7109 [(set (match_operand 0 "register_operand" "=r")
7110 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7112 (match_operand 2 "" "")))
7113 (clobber (reg:DI O7_REG))]
7114 "TARGET_TLS && TARGET_ARCH64"
7115 "call\t%a1, %%tldm_call(%&)%#"
7116 [(set_attr "type" "call")])
7118 (define_insn "tldo_hix22"
7119 [(set (match_operand:SI 0 "register_operand" "=r")
7120 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7123 "sethi\\t%%tldo_hix22(%a1), %0")
7125 (define_insn "tldo_lox10"
7126 [(set (match_operand:SI 0 "register_operand" "=r")
7127 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7128 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7131 "xor\\t%1, %%tldo_lox10(%a2), %0")
7133 (define_insn "tldo_add32"
7134 [(set (match_operand:SI 0 "register_operand" "=r")
7135 (plus:SI (match_operand:SI 1 "register_operand" "r")
7136 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7137 (match_operand 3 "tld_symbolic_operand" "")]
7139 "TARGET_TLS && TARGET_ARCH32"
7140 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7142 (define_insn "tldo_add64"
7143 [(set (match_operand:DI 0 "register_operand" "=r")
7144 (plus:DI (match_operand:DI 1 "register_operand" "r")
7145 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7146 (match_operand 3 "tld_symbolic_operand" "")]
7148 "TARGET_TLS && TARGET_ARCH64"
7149 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7151 (define_insn "tie_hi22"
7152 [(set (match_operand:SI 0 "register_operand" "=r")
7153 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7156 "sethi\\t%%tie_hi22(%a1), %0")
7158 (define_insn "tie_lo10"
7159 [(set (match_operand:SI 0 "register_operand" "=r")
7160 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7161 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7164 "add\\t%1, %%tie_lo10(%a2), %0")
7166 (define_insn "tie_ld32"
7167 [(set (match_operand:SI 0 "register_operand" "=r")
7168 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7169 (match_operand:SI 2 "register_operand" "r")
7170 (match_operand 3 "tie_symbolic_operand" "")]
7172 "TARGET_TLS && TARGET_ARCH32"
7173 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7174 [(set_attr "type" "load")])
7176 (define_insn "tie_ld64"
7177 [(set (match_operand:DI 0 "register_operand" "=r")
7178 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7179 (match_operand:SI 2 "register_operand" "r")
7180 (match_operand 3 "tie_symbolic_operand" "")]
7182 "TARGET_TLS && TARGET_ARCH64"
7183 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7184 [(set_attr "type" "load")])
7186 (define_insn "tie_add32"
7187 [(set (match_operand:SI 0 "register_operand" "=r")
7188 (plus:SI (match_operand:SI 1 "register_operand" "r")
7189 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7190 (match_operand 3 "tie_symbolic_operand" "")]
7192 "TARGET_SUN_TLS && TARGET_ARCH32"
7193 "add\\t%1, %2, %0, %%tie_add(%a3)")
7195 (define_insn "tie_add64"
7196 [(set (match_operand:DI 0 "register_operand" "=r")
7197 (plus:DI (match_operand:DI 1 "register_operand" "r")
7198 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7199 (match_operand 3 "tie_symbolic_operand" "")]
7201 "TARGET_SUN_TLS && TARGET_ARCH64"
7202 "add\\t%1, %2, %0, %%tie_add(%a3)")
7204 (define_insn "tle_hix22_sp32"
7205 [(set (match_operand:SI 0 "register_operand" "=r")
7206 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7208 "TARGET_TLS && TARGET_ARCH32"
7209 "sethi\\t%%tle_hix22(%a1), %0")
7211 (define_insn "tle_lox10_sp32"
7212 [(set (match_operand:SI 0 "register_operand" "=r")
7213 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7214 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7216 "TARGET_TLS && TARGET_ARCH32"
7217 "xor\\t%1, %%tle_lox10(%a2), %0")
7219 (define_insn "tle_hix22_sp64"
7220 [(set (match_operand:DI 0 "register_operand" "=r")
7221 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7223 "TARGET_TLS && TARGET_ARCH64"
7224 "sethi\\t%%tle_hix22(%a1), %0")
7226 (define_insn "tle_lox10_sp64"
7227 [(set (match_operand:DI 0 "register_operand" "=r")
7228 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7229 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7231 "TARGET_TLS && TARGET_ARCH64"
7232 "xor\\t%1, %%tle_lox10(%a2), %0")
7234 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7235 (define_insn "*tldo_ldub_sp32"
7236 [(set (match_operand:QI 0 "register_operand" "=r")
7237 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7238 (match_operand 3 "tld_symbolic_operand" "")]
7240 (match_operand:SI 1 "register_operand" "r"))))]
7241 "TARGET_TLS && TARGET_ARCH32"
7242 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7243 [(set_attr "type" "load")
7244 (set_attr "us3load_type" "3cycle")])
7246 (define_insn "*tldo_ldub1_sp32"
7247 [(set (match_operand:HI 0 "register_operand" "=r")
7248 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7249 (match_operand 3 "tld_symbolic_operand" "")]
7251 (match_operand:SI 1 "register_operand" "r")))))]
7252 "TARGET_TLS && TARGET_ARCH32"
7253 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7254 [(set_attr "type" "load")
7255 (set_attr "us3load_type" "3cycle")])
7257 (define_insn "*tldo_ldub2_sp32"
7258 [(set (match_operand:SI 0 "register_operand" "=r")
7259 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7260 (match_operand 3 "tld_symbolic_operand" "")]
7262 (match_operand:SI 1 "register_operand" "r")))))]
7263 "TARGET_TLS && TARGET_ARCH32"
7264 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7265 [(set_attr "type" "load")
7266 (set_attr "us3load_type" "3cycle")])
7268 (define_insn "*tldo_ldsb1_sp32"
7269 [(set (match_operand:HI 0 "register_operand" "=r")
7270 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7271 (match_operand 3 "tld_symbolic_operand" "")]
7273 (match_operand:SI 1 "register_operand" "r")))))]
7274 "TARGET_TLS && TARGET_ARCH32"
7275 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7276 [(set_attr "type" "sload")
7277 (set_attr "us3load_type" "3cycle")])
7279 (define_insn "*tldo_ldsb2_sp32"
7280 [(set (match_operand:SI 0 "register_operand" "=r")
7281 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7282 (match_operand 3 "tld_symbolic_operand" "")]
7284 (match_operand:SI 1 "register_operand" "r")))))]
7285 "TARGET_TLS && TARGET_ARCH32"
7286 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7287 [(set_attr "type" "sload")
7288 (set_attr "us3load_type" "3cycle")])
7290 (define_insn "*tldo_ldub_sp64"
7291 [(set (match_operand:QI 0 "register_operand" "=r")
7292 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7293 (match_operand 3 "tld_symbolic_operand" "")]
7295 (match_operand:DI 1 "register_operand" "r"))))]
7296 "TARGET_TLS && TARGET_ARCH64"
7297 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7298 [(set_attr "type" "load")
7299 (set_attr "us3load_type" "3cycle")])
7301 (define_insn "*tldo_ldub1_sp64"
7302 [(set (match_operand:HI 0 "register_operand" "=r")
7303 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7304 (match_operand 3 "tld_symbolic_operand" "")]
7306 (match_operand:DI 1 "register_operand" "r")))))]
7307 "TARGET_TLS && TARGET_ARCH64"
7308 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7309 [(set_attr "type" "load")
7310 (set_attr "us3load_type" "3cycle")])
7312 (define_insn "*tldo_ldub2_sp64"
7313 [(set (match_operand:SI 0 "register_operand" "=r")
7314 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7315 (match_operand 3 "tld_symbolic_operand" "")]
7317 (match_operand:DI 1 "register_operand" "r")))))]
7318 "TARGET_TLS && TARGET_ARCH64"
7319 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7320 [(set_attr "type" "load")
7321 (set_attr "us3load_type" "3cycle")])
7323 (define_insn "*tldo_ldub3_sp64"
7324 [(set (match_operand:DI 0 "register_operand" "=r")
7325 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7326 (match_operand 3 "tld_symbolic_operand" "")]
7328 (match_operand:DI 1 "register_operand" "r")))))]
7329 "TARGET_TLS && TARGET_ARCH64"
7330 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7331 [(set_attr "type" "load")
7332 (set_attr "us3load_type" "3cycle")])
7334 (define_insn "*tldo_ldsb1_sp64"
7335 [(set (match_operand:HI 0 "register_operand" "=r")
7336 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7337 (match_operand 3 "tld_symbolic_operand" "")]
7339 (match_operand:DI 1 "register_operand" "r")))))]
7340 "TARGET_TLS && TARGET_ARCH64"
7341 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7342 [(set_attr "type" "sload")
7343 (set_attr "us3load_type" "3cycle")])
7345 (define_insn "*tldo_ldsb2_sp64"
7346 [(set (match_operand:SI 0 "register_operand" "=r")
7347 (sign_extend:SI (mem:QI (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 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7353 [(set_attr "type" "sload")
7354 (set_attr "us3load_type" "3cycle")])
7356 (define_insn "*tldo_ldsb3_sp64"
7357 [(set (match_operand:DI 0 "register_operand" "=r")
7358 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7359 (match_operand 3 "tld_symbolic_operand" "")]
7361 (match_operand:DI 1 "register_operand" "r")))))]
7362 "TARGET_TLS && TARGET_ARCH64"
7363 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7364 [(set_attr "type" "sload")
7365 (set_attr "us3load_type" "3cycle")])
7367 (define_insn "*tldo_lduh_sp32"
7368 [(set (match_operand:HI 0 "register_operand" "=r")
7369 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7370 (match_operand 3 "tld_symbolic_operand" "")]
7372 (match_operand:SI 1 "register_operand" "r"))))]
7373 "TARGET_TLS && TARGET_ARCH32"
7374 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7375 [(set_attr "type" "load")
7376 (set_attr "us3load_type" "3cycle")])
7378 (define_insn "*tldo_lduh1_sp32"
7379 [(set (match_operand:SI 0 "register_operand" "=r")
7380 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7381 (match_operand 3 "tld_symbolic_operand" "")]
7383 (match_operand:SI 1 "register_operand" "r")))))]
7384 "TARGET_TLS && TARGET_ARCH32"
7385 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7386 [(set_attr "type" "load")
7387 (set_attr "us3load_type" "3cycle")])
7389 (define_insn "*tldo_ldsh1_sp32"
7390 [(set (match_operand:SI 0 "register_operand" "=r")
7391 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7392 (match_operand 3 "tld_symbolic_operand" "")]
7394 (match_operand:SI 1 "register_operand" "r")))))]
7395 "TARGET_TLS && TARGET_ARCH32"
7396 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7397 [(set_attr "type" "sload")
7398 (set_attr "us3load_type" "3cycle")])
7400 (define_insn "*tldo_lduh_sp64"
7401 [(set (match_operand:HI 0 "register_operand" "=r")
7402 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7403 (match_operand 3 "tld_symbolic_operand" "")]
7405 (match_operand:DI 1 "register_operand" "r"))))]
7406 "TARGET_TLS && TARGET_ARCH64"
7407 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7408 [(set_attr "type" "load")
7409 (set_attr "us3load_type" "3cycle")])
7411 (define_insn "*tldo_lduh1_sp64"
7412 [(set (match_operand:SI 0 "register_operand" "=r")
7413 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7414 (match_operand 3 "tld_symbolic_operand" "")]
7416 (match_operand:DI 1 "register_operand" "r")))))]
7417 "TARGET_TLS && TARGET_ARCH64"
7418 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7419 [(set_attr "type" "load")
7420 (set_attr "us3load_type" "3cycle")])
7422 (define_insn "*tldo_lduh2_sp64"
7423 [(set (match_operand:DI 0 "register_operand" "=r")
7424 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7425 (match_operand 3 "tld_symbolic_operand" "")]
7427 (match_operand:DI 1 "register_operand" "r")))))]
7428 "TARGET_TLS && TARGET_ARCH64"
7429 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7430 [(set_attr "type" "load")
7431 (set_attr "us3load_type" "3cycle")])
7433 (define_insn "*tldo_ldsh1_sp64"
7434 [(set (match_operand:SI 0 "register_operand" "=r")
7435 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7436 (match_operand 3 "tld_symbolic_operand" "")]
7438 (match_operand:DI 1 "register_operand" "r")))))]
7439 "TARGET_TLS && TARGET_ARCH64"
7440 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7441 [(set_attr "type" "sload")
7442 (set_attr "us3load_type" "3cycle")])
7444 (define_insn "*tldo_ldsh2_sp64"
7445 [(set (match_operand:DI 0 "register_operand" "=r")
7446 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7447 (match_operand 3 "tld_symbolic_operand" "")]
7449 (match_operand:DI 1 "register_operand" "r")))))]
7450 "TARGET_TLS && TARGET_ARCH64"
7451 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7452 [(set_attr "type" "sload")
7453 (set_attr "us3load_type" "3cycle")])
7455 (define_insn "*tldo_lduw_sp32"
7456 [(set (match_operand:SI 0 "register_operand" "=r")
7457 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7458 (match_operand 3 "tld_symbolic_operand" "")]
7460 (match_operand:SI 1 "register_operand" "r"))))]
7461 "TARGET_TLS && TARGET_ARCH32"
7462 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7463 [(set_attr "type" "load")])
7465 (define_insn "*tldo_lduw_sp64"
7466 [(set (match_operand:SI 0 "register_operand" "=r")
7467 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7468 (match_operand 3 "tld_symbolic_operand" "")]
7470 (match_operand:DI 1 "register_operand" "r"))))]
7471 "TARGET_TLS && TARGET_ARCH64"
7472 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7473 [(set_attr "type" "load")])
7475 (define_insn "*tldo_lduw1_sp64"
7476 [(set (match_operand:DI 0 "register_operand" "=r")
7477 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7478 (match_operand 3 "tld_symbolic_operand" "")]
7480 (match_operand:DI 1 "register_operand" "r")))))]
7481 "TARGET_TLS && TARGET_ARCH64"
7482 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7483 [(set_attr "type" "load")])
7485 (define_insn "*tldo_ldsw1_sp64"
7486 [(set (match_operand:DI 0 "register_operand" "=r")
7487 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7488 (match_operand 3 "tld_symbolic_operand" "")]
7490 (match_operand:DI 1 "register_operand" "r")))))]
7491 "TARGET_TLS && TARGET_ARCH64"
7492 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7493 [(set_attr "type" "sload")
7494 (set_attr "us3load_type" "3cycle")])
7496 (define_insn "*tldo_ldx_sp64"
7497 [(set (match_operand:DI 0 "register_operand" "=r")
7498 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7499 (match_operand 3 "tld_symbolic_operand" "")]
7501 (match_operand:DI 1 "register_operand" "r"))))]
7502 "TARGET_TLS && TARGET_ARCH64"
7503 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7504 [(set_attr "type" "load")])
7506 (define_insn "*tldo_stb_sp32"
7507 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7508 (match_operand 3 "tld_symbolic_operand" "")]
7510 (match_operand:SI 1 "register_operand" "r")))
7511 (match_operand:QI 0 "register_operand" "=r"))]
7512 "TARGET_TLS && TARGET_ARCH32"
7513 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7514 [(set_attr "type" "store")])
7516 (define_insn "*tldo_stb_sp64"
7517 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7518 (match_operand 3 "tld_symbolic_operand" "")]
7520 (match_operand:DI 1 "register_operand" "r")))
7521 (match_operand:QI 0 "register_operand" "=r"))]
7522 "TARGET_TLS && TARGET_ARCH64"
7523 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7524 [(set_attr "type" "store")])
7526 (define_insn "*tldo_sth_sp32"
7527 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7528 (match_operand 3 "tld_symbolic_operand" "")]
7530 (match_operand:SI 1 "register_operand" "r")))
7531 (match_operand:HI 0 "register_operand" "=r"))]
7532 "TARGET_TLS && TARGET_ARCH32"
7533 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7534 [(set_attr "type" "store")])
7536 (define_insn "*tldo_sth_sp64"
7537 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7538 (match_operand 3 "tld_symbolic_operand" "")]
7540 (match_operand:DI 1 "register_operand" "r")))
7541 (match_operand:HI 0 "register_operand" "=r"))]
7542 "TARGET_TLS && TARGET_ARCH64"
7543 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7544 [(set_attr "type" "store")])
7546 (define_insn "*tldo_stw_sp32"
7547 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7548 (match_operand 3 "tld_symbolic_operand" "")]
7550 (match_operand:SI 1 "register_operand" "r")))
7551 (match_operand:SI 0 "register_operand" "=r"))]
7552 "TARGET_TLS && TARGET_ARCH32"
7553 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7554 [(set_attr "type" "store")])
7556 (define_insn "*tldo_stw_sp64"
7557 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7558 (match_operand 3 "tld_symbolic_operand" "")]
7560 (match_operand:DI 1 "register_operand" "r")))
7561 (match_operand:SI 0 "register_operand" "=r"))]
7562 "TARGET_TLS && TARGET_ARCH64"
7563 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7564 [(set_attr "type" "store")])
7566 (define_insn "*tldo_stx_sp64"
7567 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7568 (match_operand 3 "tld_symbolic_operand" "")]
7570 (match_operand:DI 1 "register_operand" "r")))
7571 (match_operand:DI 0 "register_operand" "=r"))]
7572 "TARGET_TLS && TARGET_ARCH64"
7573 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7574 [(set_attr "type" "store")])
7577 ;; Stack protector instructions.
7579 (define_expand "stack_protect_set"
7580 [(match_operand 0 "memory_operand" "")
7581 (match_operand 1 "memory_operand" "")]
7584 #ifdef TARGET_THREAD_SSP_OFFSET
7585 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7586 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7587 operands[1] = gen_rtx_MEM (Pmode, addr);
7590 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7592 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7596 (define_insn "stack_protect_setsi"
7597 [(set (match_operand:SI 0 "memory_operand" "=m")
7598 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7599 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7601 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7602 [(set_attr "type" "multi")
7603 (set_attr "length" "3")])
7605 (define_insn "stack_protect_setdi"
7606 [(set (match_operand:DI 0 "memory_operand" "=m")
7607 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7608 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7610 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7611 [(set_attr "type" "multi")
7612 (set_attr "length" "3")])
7614 (define_expand "stack_protect_test"
7615 [(match_operand 0 "memory_operand" "")
7616 (match_operand 1 "memory_operand" "")
7617 (match_operand 2 "" "")]
7621 #ifdef TARGET_THREAD_SSP_OFFSET
7622 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7623 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7624 operands[1] = gen_rtx_MEM (Pmode, addr);
7628 result = gen_reg_rtx (Pmode);
7629 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7630 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7631 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7635 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7636 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7637 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7638 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7643 (define_insn "stack_protect_testsi"
7644 [(set (reg:CC CC_REG)
7645 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7646 (match_operand:SI 1 "memory_operand" "m")]
7648 (set (match_scratch:SI 3 "=r") (const_int 0))
7649 (clobber (match_scratch:SI 2 "=&r"))]
7651 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7652 [(set_attr "type" "multi")
7653 (set_attr "length" "4")])
7655 (define_insn "stack_protect_testdi"
7656 [(set (match_operand:DI 0 "register_operand" "=&r")
7657 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7658 (match_operand:DI 2 "memory_operand" "m")]
7660 (set (match_scratch:DI 3 "=r") (const_int 0))]
7662 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7663 [(set_attr "type" "multi")
7664 (set_attr "length" "4")])
7667 ;; Vector instructions.
7669 (define_insn "addv2si3"
7670 [(set (match_operand:V2SI 0 "register_operand" "=e")
7671 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7672 (match_operand:V2SI 2 "register_operand" "e")))]
7674 "fpadd32\t%1, %2, %0"
7675 [(set_attr "type" "fga")
7676 (set_attr "fptype" "double")])
7678 (define_insn "addv4hi3"
7679 [(set (match_operand:V4HI 0 "register_operand" "=e")
7680 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7681 (match_operand:V4HI 2 "register_operand" "e")))]
7683 "fpadd16\t%1, %2, %0"
7684 [(set_attr "type" "fga")
7685 (set_attr "fptype" "double")])
7687 ;; fpadd32s is emitted by the addsi3 pattern.
7689 (define_insn "addv2hi3"
7690 [(set (match_operand:V2HI 0 "register_operand" "=f")
7691 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7692 (match_operand:V2HI 2 "register_operand" "f")))]
7694 "fpadd16s\t%1, %2, %0"
7695 [(set_attr "type" "fga")
7696 (set_attr "fptype" "single")])
7698 (define_insn "subv2si3"
7699 [(set (match_operand:V2SI 0 "register_operand" "=e")
7700 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7701 (match_operand:V2SI 2 "register_operand" "e")))]
7703 "fpsub32\t%1, %2, %0"
7704 [(set_attr "type" "fga")
7705 (set_attr "fptype" "double")])
7707 (define_insn "subv4hi3"
7708 [(set (match_operand:V4HI 0 "register_operand" "=e")
7709 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7710 (match_operand:V4HI 2 "register_operand" "e")))]
7712 "fpsub16\t%1, %2, %0"
7713 [(set_attr "type" "fga")
7714 (set_attr "fptype" "double")])
7716 ;; fpsub32s is emitted by the subsi3 pattern.
7718 (define_insn "subv2hi3"
7719 [(set (match_operand:V2HI 0 "register_operand" "=f")
7720 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7721 (match_operand:V2HI 2 "register_operand" "f")))]
7723 "fpsub16s\t%1, %2, %0"
7724 [(set_attr "type" "fga")
7725 (set_attr "fptype" "single")])
7727 ;; All other logical instructions have integer equivalents so they
7728 ;; are defined together.
7730 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7732 (define_insn "*nand<V64:mode>_vis"
7733 [(set (match_operand:V64 0 "register_operand" "=e")
7734 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7735 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7738 [(set_attr "type" "fga")
7739 (set_attr "fptype" "double")])
7741 (define_insn "*nand<V32:mode>_vis"
7742 [(set (match_operand:V32 0 "register_operand" "=f")
7743 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7744 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7746 "fnands\t%1, %2, %0"
7747 [(set_attr "type" "fga")
7748 (set_attr "fptype" "single")])
7750 ;; Hard to generate VIS instructions. We have builtins for these.
7752 (define_insn "fpack16_vis"
7753 [(set (match_operand:V4QI 0 "register_operand" "=f")
7754 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7758 [(set_attr "type" "fga")
7759 (set_attr "fptype" "double")])
7761 (define_insn "fpackfix_vis"
7762 [(set (match_operand:V2HI 0 "register_operand" "=f")
7763 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7767 [(set_attr "type" "fga")
7768 (set_attr "fptype" "double")])
7770 (define_insn "fpack32_vis"
7771 [(set (match_operand:V8QI 0 "register_operand" "=e")
7772 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7773 (match_operand:V8QI 2 "register_operand" "e")]
7776 "fpack32\t%1, %2, %0"
7777 [(set_attr "type" "fga")
7778 (set_attr "fptype" "double")])
7780 (define_insn "fexpand_vis"
7781 [(set (match_operand:V4HI 0 "register_operand" "=e")
7782 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7786 [(set_attr "type" "fga")
7787 (set_attr "fptype" "double")])
7789 ;; It may be possible to describe this operation as (1 indexed):
7790 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7791 ;; 1,5,10,14,19,23,28,32)
7792 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7793 ;; because vec_merge expects all the operands to be of the same type.
7794 (define_insn "fpmerge_vis"
7795 [(set (match_operand:V8QI 0 "register_operand" "=e")
7796 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7797 (match_operand:V4QI 2 "register_operand" "f")]
7800 "fpmerge\t%1, %2, %0"
7801 [(set_attr "type" "fga")
7802 (set_attr "fptype" "double")])
7804 ;; Partitioned multiply instructions
7805 (define_insn "fmul8x16_vis"
7806 [(set (match_operand:V4HI 0 "register_operand" "=e")
7807 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7808 (match_operand:V4HI 2 "register_operand" "e")))]
7810 "fmul8x16\t%1, %2, %0"
7811 [(set_attr "type" "fpmul")
7812 (set_attr "fptype" "double")])
7814 ;; Only one of the following two insns can be a multiply.
7815 (define_insn "fmul8x16au_vis"
7816 [(set (match_operand:V4HI 0 "register_operand" "=e")
7817 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7818 (match_operand:V2HI 2 "register_operand" "f")))]
7820 "fmul8x16au\t%1, %2, %0"
7821 [(set_attr "type" "fpmul")
7822 (set_attr "fptype" "double")])
7824 (define_insn "fmul8x16al_vis"
7825 [(set (match_operand:V4HI 0 "register_operand" "=e")
7826 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7827 (match_operand:V2HI 2 "register_operand" "f")]
7830 "fmul8x16al\t%1, %2, %0"
7831 [(set_attr "type" "fpmul")
7832 (set_attr "fptype" "double")])
7834 ;; Only one of the following two insns can be a multiply.
7835 (define_insn "fmul8sux16_vis"
7836 [(set (match_operand:V4HI 0 "register_operand" "=e")
7837 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7838 (match_operand:V4HI 2 "register_operand" "e")))]
7840 "fmul8sux16\t%1, %2, %0"
7841 [(set_attr "type" "fpmul")
7842 (set_attr "fptype" "double")])
7844 (define_insn "fmul8ulx16_vis"
7845 [(set (match_operand:V4HI 0 "register_operand" "=e")
7846 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7847 (match_operand:V4HI 2 "register_operand" "e")]
7850 "fmul8ulx16\t%1, %2, %0"
7851 [(set_attr "type" "fpmul")
7852 (set_attr "fptype" "double")])
7854 ;; Only one of the following two insns can be a multiply.
7855 (define_insn "fmuld8sux16_vis"
7856 [(set (match_operand:V2SI 0 "register_operand" "=e")
7857 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7858 (match_operand:V2HI 2 "register_operand" "f")))]
7860 "fmuld8sux16\t%1, %2, %0"
7861 [(set_attr "type" "fpmul")
7862 (set_attr "fptype" "double")])
7864 (define_insn "fmuld8ulx16_vis"
7865 [(set (match_operand:V2SI 0 "register_operand" "=e")
7866 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7867 (match_operand:V2HI 2 "register_operand" "f")]
7870 "fmuld8ulx16\t%1, %2, %0"
7871 [(set_attr "type" "fpmul")
7872 (set_attr "fptype" "double")])
7874 ;; Using faligndata only makes sense after an alignaddr since the choice of
7875 ;; bytes to take out of each operand is dependent on the results of the last
7877 (define_insn "faligndata<V64I:mode>_vis"
7878 [(set (match_operand:V64I 0 "register_operand" "=e")
7879 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
7880 (match_operand:V64I 2 "register_operand" "e")]
7883 "faligndata\t%1, %2, %0"
7884 [(set_attr "type" "fga")
7885 (set_attr "fptype" "double")])
7887 (define_insn "alignaddr<P:mode>_vis"
7888 [(set (match_operand:P 0 "register_operand" "=r")
7889 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7890 (match_operand:P 2 "register_or_zero_operand" "rJ")]
7893 "alignaddr\t%r1, %r2, %0")
7895 (define_insn "alignaddrl<P:mode>_vis"
7896 [(set (match_operand:P 0 "register_operand" "=r")
7897 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7898 (match_operand:P 2 "register_or_zero_operand" "rJ")]
7899 UNSPEC_ALIGNADDRL))]
7901 "alignaddrl\t%r1, %r2, %0")
7903 (define_insn "pdist_vis"
7904 [(set (match_operand:DI 0 "register_operand" "=e")
7905 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
7906 (match_operand:V8QI 2 "register_operand" "e")
7907 (match_operand:DI 3 "register_operand" "0")]
7911 [(set_attr "type" "fga")
7912 (set_attr "fptype" "double")])
7914 ;; Edge instructions produce condition codes equivalent to a 'subcc'
7915 ;; with the same operands.
7916 (define_insn "edge8<P:mode>_vis"
7917 [(set (reg:CC_NOOV CC_REG)
7918 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
7919 (match_operand:P 2 "register_operand" "rJ"))
7921 (set (match_operand:SI 0 "register_operand" "=r")
7922 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
7924 "edge8\t%r1, %r2, %0"
7925 [(set_attr "type" "edge")])
7927 (define_insn "edge8l<P:mode>_vis"
7928 [(set (reg:CC_NOOV CC_REG)
7929 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
7930 (match_operand:P 2 "register_operand" "rJ"))
7932 (set (match_operand:SI 0 "register_operand" "=r")
7933 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
7935 "edge8l\t%r1, %r2, %0"
7936 [(set_attr "type" "edge")])
7938 (define_insn "edge16<P:mode>_vis"
7939 [(set (reg:CC_NOOV CC_REG)
7940 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
7941 (match_operand:P 2 "register_operand" "rJ"))
7943 (set (match_operand:SI 0 "register_operand" "=r")
7944 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
7946 "edge16\t%r1, %r2, %0"
7947 [(set_attr "type" "edge")])
7949 (define_insn "edge16l<P:mode>_vis"
7950 [(set (reg:CC_NOOV CC_REG)
7951 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
7952 (match_operand:P 2 "register_operand" "rJ"))
7954 (set (match_operand:SI 0 "register_operand" "=r")
7955 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
7957 "edge16l\t%r1, %r2, %0"
7958 [(set_attr "type" "edge")])
7960 (define_insn "edge32<P:mode>_vis"
7961 [(set (reg:CC_NOOV CC_REG)
7962 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
7963 (match_operand:P 2 "register_operand" "rJ"))
7965 (set (match_operand:SI 0 "register_operand" "=r")
7966 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
7968 "edge32\t%r1, %r2, %0"
7969 [(set_attr "type" "edge")])
7971 (define_insn "edge32l<P:mode>_vis"
7972 [(set (reg:CC_NOOV CC_REG)
7973 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
7974 (match_operand:P 2 "register_operand" "rJ"))
7976 (set (match_operand:SI 0 "register_operand" "=r")
7977 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
7979 "edge32l\t%r1, %r2, %0"
7980 [(set_attr "type" "edge")])
7982 (define_insn "fcmple16_vis"
7983 [(set (match_operand:SI 0 "register_operand" "=r")
7984 (unspec:SI [(match_operand:V4HI 1 "register_operand" "e")
7985 (match_operand:V4HI 2 "register_operand" "e")]
7988 "fcmple16\t%1, %2, %0"
7989 [(set_attr "type" "fpmul")
7990 (set_attr "fptype" "double")])
7992 (define_insn "fcmple32_vis"
7993 [(set (match_operand:SI 0 "register_operand" "=r")
7994 (unspec:SI [(match_operand:V2SI 1 "register_operand" "e")
7995 (match_operand:V2SI 2 "register_operand" "e")]
7998 "fcmple32\t%1, %2, %0"
7999 [(set_attr "type" "fpmul")
8000 (set_attr "fptype" "double")])
8002 (define_insn "fcmpne16_vis"
8003 [(set (match_operand:SI 0 "register_operand" "=r")
8004 (unspec:SI [(match_operand:V4HI 1 "register_operand" "e")
8005 (match_operand:V4HI 2 "register_operand" "e")]
8008 "fcmpne16\t%1, %2, %0"
8009 [(set_attr "type" "fpmul")
8010 (set_attr "fptype" "double")])
8012 (define_insn "fcmpne32_vis"
8013 [(set (match_operand:SI 0 "register_operand" "=r")
8014 (unspec:SI [(match_operand:V2SI 1 "register_operand" "e")
8015 (match_operand:V2SI 2 "register_operand" "e")]
8018 "fcmpne32\t%1, %2, %0"
8019 [(set_attr "type" "fpmul")
8020 (set_attr "fptype" "double")])
8022 (define_insn "fcmpgt16_vis"
8023 [(set (match_operand:SI 0 "register_operand" "=r")
8024 (unspec:SI [(match_operand:V4HI 1 "register_operand" "e")
8025 (match_operand:V4HI 2 "register_operand" "e")]
8028 "fcmpgt16\t%1, %2, %0"
8029 [(set_attr "type" "fpmul")
8030 (set_attr "fptype" "double")])
8032 (define_insn "fcmpgt32_vis"
8033 [(set (match_operand:SI 0 "register_operand" "=r")
8034 (unspec:SI [(match_operand:V2SI 1 "register_operand" "e")
8035 (match_operand:V2SI 2 "register_operand" "e")]
8038 "fcmpgt32\t%1, %2, %0"
8039 [(set_attr "type" "fpmul")
8040 (set_attr "fptype" "double")])
8042 (define_insn "fcmpeq16_vis"
8043 [(set (match_operand:SI 0 "register_operand" "=r")
8044 (unspec:SI [(match_operand:V4HI 1 "register_operand" "e")
8045 (match_operand:V4HI 2 "register_operand" "e")]
8048 "fcmpeq16\t%1, %2, %0"
8049 [(set_attr "type" "fpmul")
8050 (set_attr "fptype" "double")])
8052 (define_insn "fcmpeq32_vis"
8053 [(set (match_operand:SI 0 "register_operand" "=r")
8054 (unspec:SI [(match_operand:V2SI 1 "register_operand" "e")
8055 (match_operand:V2SI 2 "register_operand" "e")]
8058 "fcmpeq32\t%1, %2, %0"
8059 [(set_attr "type" "fpmul")
8060 (set_attr "fptype" "double")])