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)
106 (UNSPECV_PROBE_STACK_RANGE 11)
199 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
200 (define_mode_iterator I [QI HI SI DI])
201 (define_mode_iterator F [SF DF TF])
203 ;; We don't define V1SI because SI should work just fine.
204 (define_mode_iterator V32 [SF V2HI V4QI])
205 (define_mode_iterator V32I [SI V2HI V4QI])
207 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
208 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
210 (define_mode_iterator V64N8 [V2SI V4HI])
212 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
213 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
214 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
215 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
216 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
218 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (SI "32s") (V2HI "16s")])
219 (define_mode_attr vconstr [(V2SI "e") (V4HI "e") (SI "f") (V2HI "f")])
221 ;; Attribute for cpu type.
222 ;; These must match the values for enum processor_type in sparc.h.
243 (const (symbol_ref "sparc_cpu_attr")))
245 ;; Attribute for the instruction set.
246 ;; At present we only need to distinguish v9/!v9, but for clarity we
247 ;; test TARGET_V8 too.
248 (define_attr "isa" "v7,v8,v9,sparclet"
250 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
251 (symbol_ref "TARGET_V8") (const_string "v8")
252 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
253 (const_string "v7"))))
259 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
267 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,edgen,gsr,array,
270 multi,savew,flushw,iflush,trap"
271 (const_string "ialu"))
273 ;; True if branch/call has empty delay slot and will emit a nop in it
274 (define_attr "empty_delay_slot" "false,true"
275 (symbol_ref "(empty_delay_slot (insn)
276 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
278 (define_attr "branch_type" "none,icc,fcc,reg"
279 (const_string "none"))
281 (define_attr "pic" "false,true"
282 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
284 (define_attr "calls_alloca" "false,true"
285 (symbol_ref "(cfun->calls_alloca != 0
286 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
288 (define_attr "calls_eh_return" "false,true"
289 (symbol_ref "(crtl->calls_eh_return != 0
290 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
292 (define_attr "leaf_function" "false,true"
293 (symbol_ref "(current_function_uses_only_leaf_regs != 0
294 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
296 (define_attr "delayed_branch" "false,true"
297 (symbol_ref "(flag_delayed_branch != 0
298 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
300 (define_attr "flat" "false,true"
301 (symbol_ref "(TARGET_FLAT != 0
302 ? FLAT_TRUE : FLAT_FALSE)"))
304 ;; Length (in # of insns).
305 ;; Beware that setting a length greater or equal to 3 for conditional branches
306 ;; has a side-effect (see output_cbranch and output_v9branch).
307 (define_attr "length" ""
308 (cond [(eq_attr "type" "uncond_branch,call")
309 (if_then_else (eq_attr "empty_delay_slot" "true")
312 (eq_attr "type" "sibcall")
313 (if_then_else (eq_attr "leaf_function" "true")
314 (if_then_else (eq_attr "empty_delay_slot" "true")
317 (if_then_else (eq_attr "empty_delay_slot" "true")
320 (eq_attr "branch_type" "icc")
321 (if_then_else (match_operand 0 "noov_compare64_operator" "")
322 (if_then_else (lt (pc) (match_dup 1))
323 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
324 (if_then_else (eq_attr "empty_delay_slot" "true")
327 (if_then_else (eq_attr "empty_delay_slot" "true")
330 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
331 (if_then_else (eq_attr "empty_delay_slot" "true")
334 (if_then_else (eq_attr "empty_delay_slot" "true")
337 (if_then_else (eq_attr "empty_delay_slot" "true")
340 (eq_attr "branch_type" "fcc")
341 (if_then_else (match_operand 0 "fcc0_register_operand" "")
342 (if_then_else (eq_attr "empty_delay_slot" "true")
343 (if_then_else (not (match_test "TARGET_V9"))
346 (if_then_else (not (match_test "TARGET_V9"))
349 (if_then_else (lt (pc) (match_dup 2))
350 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
351 (if_then_else (eq_attr "empty_delay_slot" "true")
354 (if_then_else (eq_attr "empty_delay_slot" "true")
357 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
358 (if_then_else (eq_attr "empty_delay_slot" "true")
361 (if_then_else (eq_attr "empty_delay_slot" "true")
364 (eq_attr "branch_type" "reg")
365 (if_then_else (lt (pc) (match_dup 2))
366 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
367 (if_then_else (eq_attr "empty_delay_slot" "true")
370 (if_then_else (eq_attr "empty_delay_slot" "true")
373 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
374 (if_then_else (eq_attr "empty_delay_slot" "true")
377 (if_then_else (eq_attr "empty_delay_slot" "true")
383 (define_attr "fptype" "single,double"
384 (const_string "single"))
386 ;; UltraSPARC-III integer load type.
387 (define_attr "us3load_type" "2cycle,3cycle"
388 (const_string "2cycle"))
390 (define_asm_attributes
391 [(set_attr "length" "2")
392 (set_attr "type" "multi")])
394 ;; Attributes for instruction and branch scheduling
395 (define_attr "tls_call_delay" "false,true"
396 (symbol_ref "(tls_call_delay (insn)
397 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
399 (define_attr "in_call_delay" "false,true"
400 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
401 (const_string "false")
402 (eq_attr "type" "load,fpload,store,fpstore")
403 (if_then_else (eq_attr "length" "1")
404 (const_string "true")
405 (const_string "false"))]
406 (if_then_else (and (eq_attr "length" "1")
407 (eq_attr "tls_call_delay" "true"))
408 (const_string "true")
409 (const_string "false"))))
411 (define_attr "eligible_for_sibcall_delay" "false,true"
412 (symbol_ref "(eligible_for_sibcall_delay (insn)
413 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
414 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
416 (define_attr "eligible_for_return_delay" "false,true"
417 (symbol_ref "(eligible_for_return_delay (insn)
418 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
419 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
421 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
422 ;; branches. This would allow us to remove the nop always inserted before
423 ;; a floating point branch.
425 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
426 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
427 ;; This is because doing so will add several pipeline stalls to the path
428 ;; that the load/store did not come from. Unfortunately, there is no way
429 ;; to prevent fill_eager_delay_slots from using load/store without completely
430 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
431 ;; because it prevents us from moving back the final store of inner loops.
433 (define_attr "in_branch_delay" "false,true"
434 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
435 (eq_attr "length" "1"))
436 (const_string "true")
437 (const_string "false")))
439 (define_attr "in_uncond_branch_delay" "false,true"
440 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
441 (eq_attr "length" "1"))
442 (const_string "true")
443 (const_string "false")))
445 (define_attr "in_annul_branch_delay" "false,true"
446 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
447 (eq_attr "length" "1"))
448 (const_string "true")
449 (const_string "false")))
451 (define_delay (eq_attr "type" "call")
452 [(eq_attr "in_call_delay" "true") (nil) (nil)])
454 (define_delay (eq_attr "type" "sibcall")
455 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
457 (define_delay (eq_attr "type" "branch")
458 [(eq_attr "in_branch_delay" "true")
459 (nil) (eq_attr "in_annul_branch_delay" "true")])
461 (define_delay (eq_attr "type" "uncond_branch")
462 [(eq_attr "in_uncond_branch_delay" "true")
465 (define_delay (eq_attr "type" "return")
466 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
469 ;; Include SPARC DFA schedulers
471 (include "cypress.md")
472 (include "supersparc.md")
473 (include "hypersparc.md")
475 (include "sparclet.md")
476 (include "ultra1_2.md")
477 (include "ultra3.md")
478 (include "niagara.md")
479 (include "niagara2.md")
482 ;; Operand and operator predicates and constraints
484 (include "predicates.md")
485 (include "constraints.md")
488 ;; Compare instructions.
490 ;; These are just the DEFINE_INSNs to match the patterns and the
491 ;; DEFINE_SPLITs for some of the scc insns that actually require
492 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
494 ;; The compare DEFINE_INSNs.
496 (define_insn "*cmpsi_insn"
497 [(set (reg:CC CC_REG)
498 (compare:CC (match_operand:SI 0 "register_operand" "r")
499 (match_operand:SI 1 "arith_operand" "rI")))]
502 [(set_attr "type" "compare")])
504 (define_insn "*cmpdi_sp64"
505 [(set (reg:CCX CC_REG)
506 (compare:CCX (match_operand:DI 0 "register_operand" "r")
507 (match_operand:DI 1 "arith_operand" "rI")))]
510 [(set_attr "type" "compare")])
512 (define_insn "*cmpsf_fpe"
513 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
514 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
515 (match_operand:SF 2 "register_operand" "f")))]
519 return "fcmpes\t%0, %1, %2";
520 return "fcmpes\t%1, %2";
522 [(set_attr "type" "fpcmp")])
524 (define_insn "*cmpdf_fpe"
525 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
526 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
527 (match_operand:DF 2 "register_operand" "e")))]
531 return "fcmped\t%0, %1, %2";
532 return "fcmped\t%1, %2";
534 [(set_attr "type" "fpcmp")
535 (set_attr "fptype" "double")])
537 (define_insn "*cmptf_fpe"
538 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
539 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
540 (match_operand:TF 2 "register_operand" "e")))]
541 "TARGET_FPU && TARGET_HARD_QUAD"
544 return "fcmpeq\t%0, %1, %2";
545 return "fcmpeq\t%1, %2";
547 [(set_attr "type" "fpcmp")])
549 (define_insn "*cmpsf_fp"
550 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
551 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
552 (match_operand:SF 2 "register_operand" "f")))]
556 return "fcmps\t%0, %1, %2";
557 return "fcmps\t%1, %2";
559 [(set_attr "type" "fpcmp")])
561 (define_insn "*cmpdf_fp"
562 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
563 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
564 (match_operand:DF 2 "register_operand" "e")))]
568 return "fcmpd\t%0, %1, %2";
569 return "fcmpd\t%1, %2";
571 [(set_attr "type" "fpcmp")
572 (set_attr "fptype" "double")])
574 (define_insn "*cmptf_fp"
575 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
576 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
577 (match_operand:TF 2 "register_operand" "e")))]
578 "TARGET_FPU && TARGET_HARD_QUAD"
581 return "fcmpq\t%0, %1, %2";
582 return "fcmpq\t%1, %2";
584 [(set_attr "type" "fpcmp")])
586 ;; Next come the scc insns.
588 (define_expand "cstoresi4"
589 [(use (match_operator 1 "comparison_operator"
590 [(match_operand:SI 2 "compare_operand" "")
591 (match_operand:SI 3 "arith_operand" "")]))
592 (clobber (match_operand:SI 0 "register_operand"))]
595 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
596 operands[2] = force_reg (SImode, operands[2]);
597 if (emit_scc_insn (operands)) DONE; else FAIL;
600 (define_expand "cstoredi4"
601 [(use (match_operator 1 "comparison_operator"
602 [(match_operand:DI 2 "compare_operand" "")
603 (match_operand:DI 3 "arith_operand" "")]))
604 (clobber (match_operand:SI 0 "register_operand"))]
607 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
608 operands[2] = force_reg (DImode, operands[2]);
609 if (emit_scc_insn (operands)) DONE; else FAIL;
612 (define_expand "cstore<F:mode>4"
613 [(use (match_operator 1 "comparison_operator"
614 [(match_operand:F 2 "register_operand" "")
615 (match_operand:F 3 "register_operand" "")]))
616 (clobber (match_operand:SI 0 "register_operand"))]
618 { if (emit_scc_insn (operands)) DONE; else FAIL; })
622 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
623 ;; generate addcc/subcc instructions.
625 (define_expand "seqsi_special"
627 (xor:SI (match_operand:SI 1 "register_operand" "")
628 (match_operand:SI 2 "register_operand" "")))
629 (parallel [(set (match_operand:SI 0 "register_operand" "")
630 (eq:SI (match_dup 3) (const_int 0)))
631 (clobber (reg:CC CC_REG))])]
633 { operands[3] = gen_reg_rtx (SImode); })
635 (define_expand "seqdi_special"
637 (xor:DI (match_operand:DI 1 "register_operand" "")
638 (match_operand:DI 2 "register_operand" "")))
639 (set (match_operand:SI 0 "register_operand" "")
640 (eq:SI (match_dup 3) (const_int 0)))]
642 { operands[3] = gen_reg_rtx (DImode); })
644 (define_expand "snesi_special"
646 (xor:SI (match_operand:SI 1 "register_operand" "")
647 (match_operand:SI 2 "register_operand" "")))
648 (parallel [(set (match_operand:SI 0 "register_operand" "")
649 (ne:SI (match_dup 3) (const_int 0)))
650 (clobber (reg:CC CC_REG))])]
652 { operands[3] = gen_reg_rtx (SImode); })
654 (define_expand "snedi_special"
656 (xor:DI (match_operand:DI 1 "register_operand" "")
657 (match_operand:DI 2 "register_operand" "")))
658 (set (match_operand:SI 0 "register_operand" "")
659 (ne:SI (match_dup 3) (const_int 0)))]
661 { operands[3] = gen_reg_rtx (DImode); })
664 ;; Now the DEFINE_INSNs for the scc cases.
666 ;; The SEQ and SNE patterns are special because they can be done
667 ;; without any branching and do not involve a COMPARE. We want
668 ;; them to always use the splits below so the results can be
671 (define_insn_and_split "*snesi_zero"
672 [(set (match_operand:SI 0 "register_operand" "=r")
673 (ne:SI (match_operand:SI 1 "register_operand" "r")
675 (clobber (reg:CC CC_REG))]
679 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
681 (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
683 [(set_attr "length" "2")])
685 (define_insn_and_split "*neg_snesi_zero"
686 [(set (match_operand:SI 0 "register_operand" "=r")
687 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
689 (clobber (reg:CC CC_REG))]
693 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
695 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
697 [(set_attr "length" "2")])
699 (define_insn_and_split "*snesi_zero_extend"
700 [(set (match_operand:DI 0 "register_operand" "=r")
701 (ne:DI (match_operand:SI 1 "register_operand" "r")
703 (clobber (reg:CC CC_REG))]
707 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
710 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
712 (ltu:SI (reg:CC_NOOV CC_REG)
715 [(set_attr "length" "2")])
717 (define_insn_and_split "*snedi_zero"
718 [(set (match_operand:DI 0 "register_operand" "=&r")
719 (ne:DI (match_operand:DI 1 "register_operand" "r")
723 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
724 [(set (match_dup 0) (const_int 0))
725 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
730 [(set_attr "length" "2")])
732 (define_insn_and_split "*neg_snedi_zero"
733 [(set (match_operand:DI 0 "register_operand" "=&r")
734 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
738 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
739 [(set (match_dup 0) (const_int 0))
740 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
745 [(set_attr "length" "2")])
747 (define_insn_and_split "*snedi_zero_trunc"
748 [(set (match_operand:SI 0 "register_operand" "=&r")
749 (ne:SI (match_operand:DI 1 "register_operand" "r")
753 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
754 [(set (match_dup 0) (const_int 0))
755 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
760 [(set_attr "length" "2")])
762 (define_insn_and_split "*seqsi_zero"
763 [(set (match_operand:SI 0 "register_operand" "=r")
764 (eq:SI (match_operand:SI 1 "register_operand" "r")
766 (clobber (reg:CC CC_REG))]
770 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
772 (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
774 [(set_attr "length" "2")])
776 (define_insn_and_split "*neg_seqsi_zero"
777 [(set (match_operand:SI 0 "register_operand" "=r")
778 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
780 (clobber (reg:CC CC_REG))]
784 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
786 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
788 [(set_attr "length" "2")])
790 (define_insn_and_split "*seqsi_zero_extend"
791 [(set (match_operand:DI 0 "register_operand" "=r")
792 (eq:DI (match_operand:SI 1 "register_operand" "r")
794 (clobber (reg:CC CC_REG))]
798 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
801 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
803 (ltu:SI (reg:CC_NOOV CC_REG)
806 [(set_attr "length" "2")])
808 (define_insn_and_split "*seqdi_zero"
809 [(set (match_operand:DI 0 "register_operand" "=&r")
810 (eq:DI (match_operand:DI 1 "register_operand" "r")
814 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
815 [(set (match_dup 0) (const_int 0))
816 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
821 [(set_attr "length" "2")])
823 (define_insn_and_split "*neg_seqdi_zero"
824 [(set (match_operand:DI 0 "register_operand" "=&r")
825 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
829 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
830 [(set (match_dup 0) (const_int 0))
831 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
836 [(set_attr "length" "2")])
838 (define_insn_and_split "*seqdi_zero_trunc"
839 [(set (match_operand:SI 0 "register_operand" "=&r")
840 (eq:SI (match_operand:DI 1 "register_operand" "r")
844 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
845 [(set (match_dup 0) (const_int 0))
846 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
851 [(set_attr "length" "2")])
853 ;; We can also do (x + (i == 0)) and related, so put them in.
854 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
857 (define_insn_and_split "*x_plus_i_ne_0"
858 [(set (match_operand:SI 0 "register_operand" "=r")
859 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
861 (match_operand:SI 2 "register_operand" "r")))
862 (clobber (reg:CC CC_REG))]
866 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
868 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
871 [(set_attr "length" "2")])
873 (define_insn_and_split "*x_minus_i_ne_0"
874 [(set (match_operand:SI 0 "register_operand" "=r")
875 (minus:SI (match_operand:SI 2 "register_operand" "r")
876 (ne:SI (match_operand:SI 1 "register_operand" "r")
878 (clobber (reg:CC CC_REG))]
882 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
884 (set (match_dup 0) (minus:SI (match_dup 2)
885 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
887 [(set_attr "length" "2")])
889 (define_insn_and_split "*x_plus_i_eq_0"
890 [(set (match_operand:SI 0 "register_operand" "=r")
891 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
893 (match_operand:SI 2 "register_operand" "r")))
894 (clobber (reg:CC CC_REG))]
898 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
900 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
903 [(set_attr "length" "2")])
905 (define_insn_and_split "*x_minus_i_eq_0"
906 [(set (match_operand:SI 0 "register_operand" "=r")
907 (minus:SI (match_operand:SI 2 "register_operand" "r")
908 (eq:SI (match_operand:SI 1 "register_operand" "r")
910 (clobber (reg:CC CC_REG))]
914 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
916 (set (match_dup 0) (minus:SI (match_dup 2)
917 (geu:SI (reg:CC CC_REG) (const_int 0))))]
919 [(set_attr "length" "2")])
921 ;; We can also do GEU and LTU directly, but these operate after a compare.
922 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
925 (define_insn "*sltu_insn"
926 [(set (match_operand:SI 0 "register_operand" "=r")
927 (ltu:SI (reg:CC CC_REG) (const_int 0)))]
930 [(set_attr "type" "ialuX")])
932 (define_insn "*neg_sltu_insn"
933 [(set (match_operand:SI 0 "register_operand" "=r")
934 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
937 [(set_attr "type" "ialuX")])
939 ;; ??? Combine should canonicalize these next two to the same pattern.
940 (define_insn "*neg_sltu_minus_x"
941 [(set (match_operand:SI 0 "register_operand" "=r")
942 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
943 (match_operand:SI 1 "arith_operand" "rI")))]
946 [(set_attr "type" "ialuX")])
948 (define_insn "*neg_sltu_plus_x"
949 [(set (match_operand:SI 0 "register_operand" "=r")
950 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
951 (match_operand:SI 1 "arith_operand" "rI"))))]
954 [(set_attr "type" "ialuX")])
956 (define_insn "*sgeu_insn"
957 [(set (match_operand:SI 0 "register_operand" "=r")
958 (geu:SI (reg:CC CC_REG) (const_int 0)))]
961 [(set_attr "type" "ialuX")])
963 (define_insn "*neg_sgeu_insn"
964 [(set (match_operand:SI 0 "register_operand" "=r")
965 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
968 [(set_attr "type" "ialuX")])
970 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
971 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
974 (define_insn "*sltu_plus_x"
975 [(set (match_operand:SI 0 "register_operand" "=r")
976 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
977 (match_operand:SI 1 "arith_operand" "rI")))]
980 [(set_attr "type" "ialuX")])
982 (define_insn "*sltu_plus_x_plus_y"
983 [(set (match_operand:SI 0 "register_operand" "=r")
984 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
985 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
986 (match_operand:SI 2 "arith_operand" "rI"))))]
989 [(set_attr "type" "ialuX")])
991 (define_insn "*x_minus_sltu"
992 [(set (match_operand:SI 0 "register_operand" "=r")
993 (minus:SI (match_operand:SI 1 "register_operand" "r")
994 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
997 [(set_attr "type" "ialuX")])
999 ;; ??? Combine should canonicalize these next two to the same pattern.
1000 (define_insn "*x_minus_y_minus_sltu"
1001 [(set (match_operand:SI 0 "register_operand" "=r")
1002 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1003 (match_operand:SI 2 "arith_operand" "rI"))
1004 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1007 [(set_attr "type" "ialuX")])
1009 (define_insn "*x_minus_sltu_plus_y"
1010 [(set (match_operand:SI 0 "register_operand" "=r")
1011 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1012 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1013 (match_operand:SI 2 "arith_operand" "rI"))))]
1016 [(set_attr "type" "ialuX")])
1018 (define_insn "*sgeu_plus_x"
1019 [(set (match_operand:SI 0 "register_operand" "=r")
1020 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1021 (match_operand:SI 1 "register_operand" "r")))]
1024 [(set_attr "type" "ialuX")])
1026 (define_insn "*x_minus_sgeu"
1027 [(set (match_operand:SI 0 "register_operand" "=r")
1028 (minus:SI (match_operand:SI 1 "register_operand" "r")
1029 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1032 [(set_attr "type" "ialuX")])
1035 [(set (match_operand:SI 0 "register_operand" "")
1036 (match_operator:SI 2 "noov_compare_operator"
1037 [(match_operand 1 "icc_or_fcc_register_operand" "")
1040 && REGNO (operands[1]) == SPARC_ICC_REG
1041 && (GET_MODE (operands[1]) == CCXmode
1042 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1043 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1044 [(set (match_dup 0) (const_int 0))
1046 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1052 ;; These control RTL generation for conditional jump insns
1054 (define_expand "cbranchcc4"
1056 (if_then_else (match_operator 0 "comparison_operator"
1057 [(match_operand 1 "compare_operand" "")
1058 (match_operand 2 "const_zero_operand" "")])
1059 (label_ref (match_operand 3 "" ""))
1064 (define_expand "cbranchsi4"
1065 [(use (match_operator 0 "comparison_operator"
1066 [(match_operand:SI 1 "compare_operand" "")
1067 (match_operand:SI 2 "arith_operand" "")]))
1068 (use (match_operand 3 ""))]
1071 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1072 operands[1] = force_reg (SImode, operands[1]);
1073 emit_conditional_branch_insn (operands);
1077 (define_expand "cbranchdi4"
1078 [(use (match_operator 0 "comparison_operator"
1079 [(match_operand:DI 1 "compare_operand" "")
1080 (match_operand:DI 2 "arith_operand" "")]))
1081 (use (match_operand 3 ""))]
1084 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1085 operands[1] = force_reg (DImode, operands[1]);
1086 emit_conditional_branch_insn (operands);
1090 (define_expand "cbranch<F:mode>4"
1091 [(use (match_operator 0 "comparison_operator"
1092 [(match_operand:F 1 "register_operand" "")
1093 (match_operand:F 2 "register_operand" "")]))
1094 (use (match_operand 3 ""))]
1096 { emit_conditional_branch_insn (operands); DONE; })
1099 ;; Now match both normal and inverted jump.
1101 ;; XXX fpcmp nop braindamage
1102 (define_insn "*normal_branch"
1104 (if_then_else (match_operator 0 "noov_compare_operator"
1105 [(reg CC_REG) (const_int 0)])
1106 (label_ref (match_operand 1 "" ""))
1110 return output_cbranch (operands[0], operands[1], 1, 0,
1111 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1114 [(set_attr "type" "branch")
1115 (set_attr "branch_type" "icc")])
1117 ;; XXX fpcmp nop braindamage
1118 (define_insn "*inverted_branch"
1120 (if_then_else (match_operator 0 "noov_compare_operator"
1121 [(reg CC_REG) (const_int 0)])
1123 (label_ref (match_operand 1 "" ""))))]
1126 return output_cbranch (operands[0], operands[1], 1, 1,
1127 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1130 [(set_attr "type" "branch")
1131 (set_attr "branch_type" "icc")])
1133 ;; XXX fpcmp nop braindamage
1134 (define_insn "*normal_fp_branch"
1136 (if_then_else (match_operator 1 "comparison_operator"
1137 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1139 (label_ref (match_operand 2 "" ""))
1143 return output_cbranch (operands[1], operands[2], 2, 0,
1144 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1147 [(set_attr "type" "branch")
1148 (set_attr "branch_type" "fcc")])
1150 ;; XXX fpcmp nop braindamage
1151 (define_insn "*inverted_fp_branch"
1153 (if_then_else (match_operator 1 "comparison_operator"
1154 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1157 (label_ref (match_operand 2 "" ""))))]
1160 return output_cbranch (operands[1], operands[2], 2, 1,
1161 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1164 [(set_attr "type" "branch")
1165 (set_attr "branch_type" "fcc")])
1167 ;; XXX fpcmp nop braindamage
1168 (define_insn "*normal_fpe_branch"
1170 (if_then_else (match_operator 1 "comparison_operator"
1171 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1173 (label_ref (match_operand 2 "" ""))
1177 return output_cbranch (operands[1], operands[2], 2, 0,
1178 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1181 [(set_attr "type" "branch")
1182 (set_attr "branch_type" "fcc")])
1184 ;; XXX fpcmp nop braindamage
1185 (define_insn "*inverted_fpe_branch"
1187 (if_then_else (match_operator 1 "comparison_operator"
1188 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1191 (label_ref (match_operand 2 "" ""))))]
1194 return output_cbranch (operands[1], operands[2], 2, 1,
1195 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1198 [(set_attr "type" "branch")
1199 (set_attr "branch_type" "fcc")])
1201 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1202 ;; in the architecture.
1204 ;; There are no 32 bit brreg insns.
1207 (define_insn "*normal_int_branch_sp64"
1209 (if_then_else (match_operator 0 "v9_register_compare_operator"
1210 [(match_operand:DI 1 "register_operand" "r")
1212 (label_ref (match_operand 2 "" ""))
1216 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1217 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1220 [(set_attr "type" "branch")
1221 (set_attr "branch_type" "reg")])
1224 (define_insn "*inverted_int_branch_sp64"
1226 (if_then_else (match_operator 0 "v9_register_compare_operator"
1227 [(match_operand:DI 1 "register_operand" "r")
1230 (label_ref (match_operand 2 "" ""))))]
1233 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1234 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1237 [(set_attr "type" "branch")
1238 (set_attr "branch_type" "reg")])
1241 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1242 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1243 ;; that adds the PC value at the call point to register #(operand 3).
1245 (define_insn "load_pcrel_sym<P:mode>"
1246 [(set (match_operand:P 0 "register_operand" "=r")
1247 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1248 (match_operand:P 2 "call_address_operand" "")
1249 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1250 (clobber (reg:P O7_REG))]
1251 "REGNO (operands[0]) == INTVAL (operands[3])"
1253 if (flag_delayed_branch)
1254 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1256 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1258 [(set (attr "type") (const_string "multi"))
1259 (set (attr "length")
1260 (if_then_else (eq_attr "delayed_branch" "true")
1265 ;; Integer move instructions
1267 (define_expand "movqi"
1268 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1269 (match_operand:QI 1 "general_operand" ""))]
1272 if (sparc_expand_move (QImode, operands))
1276 (define_insn "*movqi_insn"
1277 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1278 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1279 "(register_operand (operands[0], QImode)
1280 || register_or_zero_operand (operands[1], QImode))"
1285 [(set_attr "type" "*,load,store")
1286 (set_attr "us3load_type" "*,3cycle,*")])
1288 (define_expand "movhi"
1289 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1290 (match_operand:HI 1 "general_operand" ""))]
1293 if (sparc_expand_move (HImode, operands))
1297 (define_insn "*movhi_insn"
1298 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1299 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1300 "(register_operand (operands[0], HImode)
1301 || register_or_zero_operand (operands[1], HImode))"
1304 sethi\t%%hi(%a1), %0
1307 [(set_attr "type" "*,*,load,store")
1308 (set_attr "us3load_type" "*,*,3cycle,*")])
1310 ;; We always work with constants here.
1311 (define_insn "*movhi_lo_sum"
1312 [(set (match_operand:HI 0 "register_operand" "=r")
1313 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1314 (match_operand:HI 2 "small_int_operand" "I")))]
1318 (define_expand "movsi"
1319 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1320 (match_operand:SI 1 "general_operand" ""))]
1323 if (sparc_expand_move (SImode, operands))
1327 (define_insn "*movsi_insn"
1328 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d,d")
1329 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J,P"))]
1330 "(register_operand (operands[0], SImode)
1331 || register_or_zero_or_all_ones_operand (operands[1], SImode))"
1334 sethi\t%%hi(%a1), %0
1342 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")])
1344 (define_insn "*movsi_lo_sum"
1345 [(set (match_operand:SI 0 "register_operand" "=r")
1346 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1347 (match_operand:SI 2 "immediate_operand" "in")))]
1349 "or\t%1, %%lo(%a2), %0")
1351 (define_insn "*movsi_high"
1352 [(set (match_operand:SI 0 "register_operand" "=r")
1353 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1355 "sethi\t%%hi(%a1), %0")
1357 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1358 ;; so that CSE won't optimize the address computation away.
1359 (define_insn "movsi_lo_sum_pic"
1360 [(set (match_operand:SI 0 "register_operand" "=r")
1361 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1362 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1365 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1366 return "xor\t%1, %%gdop_lox10(%a2), %0";
1368 return "or\t%1, %%lo(%a2), %0";
1372 (define_insn "movsi_high_pic"
1373 [(set (match_operand:SI 0 "register_operand" "=r")
1374 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1375 "flag_pic && check_pic (1)"
1377 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1378 return "sethi\t%%gdop_hix22(%a1), %0";
1380 return "sethi\t%%hi(%a1), %0";
1384 (define_insn "movsi_pic_gotdata_op"
1385 [(set (match_operand:SI 0 "register_operand" "=r")
1386 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1387 (match_operand:SI 2 "register_operand" "r")
1388 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1389 "flag_pic && check_pic (1)"
1391 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1392 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1394 return "ld\t[%1 + %2], %0";
1397 [(set_attr "type" "load")])
1399 (define_expand "movsi_pic_label_ref"
1400 [(set (match_dup 3) (high:SI
1401 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1402 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1403 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1404 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1405 (set (match_operand:SI 0 "register_operand" "=r")
1406 (minus:SI (match_dup 5) (match_dup 4)))]
1409 crtl->uses_pic_offset_table = 1;
1410 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1411 if (!can_create_pseudo_p ())
1413 operands[3] = operands[0];
1414 operands[4] = operands[0];
1418 operands[3] = gen_reg_rtx (SImode);
1419 operands[4] = gen_reg_rtx (SImode);
1421 operands[5] = pic_offset_table_rtx;
1424 (define_insn "*movsi_high_pic_label_ref"
1425 [(set (match_operand:SI 0 "register_operand" "=r")
1427 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1428 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1430 "sethi\t%%hi(%a2-(%a1-.)), %0")
1432 (define_insn "*movsi_lo_sum_pic_label_ref"
1433 [(set (match_operand:SI 0 "register_operand" "=r")
1434 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1435 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1436 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1438 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1440 ;; Set up the PIC register for VxWorks.
1442 (define_expand "vxworks_load_got"
1444 (high:SI (match_dup 1)))
1446 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1448 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1449 "TARGET_VXWORKS_RTP"
1451 operands[0] = pic_offset_table_rtx;
1452 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1453 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1456 (define_expand "movdi"
1457 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1458 (match_operand:DI 1 "general_operand" ""))]
1461 if (sparc_expand_move (DImode, operands))
1465 ;; Be careful, fmovd does not exist when !v9.
1466 ;; We match MEM moves directly when we have correct even
1467 ;; numbered registers, but fall into splits otherwise.
1468 ;; The constraint ordering here is really important to
1469 ;; avoid insane problems in reload, especially for patterns
1472 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1473 ;; (const_int -5016)))
1477 (define_insn "*movdi_insn_sp32"
1478 [(set (match_operand:DI 0 "nonimmediate_operand"
1479 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1480 (match_operand:DI 1 "input_operand"
1481 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1483 && (register_operand (operands[0], DImode)
1484 || register_or_zero_operand (operands[1], DImode))"
1498 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1499 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1501 (define_insn "*movdi_insn_sp32_v9"
1502 [(set (match_operand:DI 0 "nonimmediate_operand"
1503 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1504 (match_operand:DI 1 "input_operand"
1505 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1508 && (register_operand (operands[0], DImode)
1509 || register_or_zero_operand (operands[1], DImode))"
1526 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1527 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1528 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1530 (define_insn "*movdi_insn_sp64"
1531 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b,b")
1532 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J,P"))]
1534 && (register_operand (operands[0], DImode)
1535 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1538 sethi\t%%hi(%a1), %0
1546 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")
1547 (set_attr "fptype" "*,*,*,*,double,*,*,double,double")])
1549 (define_expand "movdi_pic_label_ref"
1550 [(set (match_dup 3) (high:DI
1551 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1552 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1553 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1554 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1555 (set (match_operand:DI 0 "register_operand" "=r")
1556 (minus:DI (match_dup 5) (match_dup 4)))]
1557 "TARGET_ARCH64 && flag_pic"
1559 crtl->uses_pic_offset_table = 1;
1560 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1561 if (!can_create_pseudo_p ())
1563 operands[3] = operands[0];
1564 operands[4] = operands[0];
1568 operands[3] = gen_reg_rtx (DImode);
1569 operands[4] = gen_reg_rtx (DImode);
1571 operands[5] = pic_offset_table_rtx;
1574 (define_insn "*movdi_high_pic_label_ref"
1575 [(set (match_operand:DI 0 "register_operand" "=r")
1577 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1578 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1579 "TARGET_ARCH64 && flag_pic"
1580 "sethi\t%%hi(%a2-(%a1-.)), %0")
1582 (define_insn "*movdi_lo_sum_pic_label_ref"
1583 [(set (match_operand:DI 0 "register_operand" "=r")
1584 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1585 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1586 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1587 "TARGET_ARCH64 && flag_pic"
1588 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1590 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1591 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1593 (define_insn "movdi_lo_sum_pic"
1594 [(set (match_operand:DI 0 "register_operand" "=r")
1595 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1596 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1597 "TARGET_ARCH64 && flag_pic"
1599 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1600 return "xor\t%1, %%gdop_lox10(%a2), %0";
1602 return "or\t%1, %%lo(%a2), %0";
1606 (define_insn "movdi_high_pic"
1607 [(set (match_operand:DI 0 "register_operand" "=r")
1608 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1609 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1611 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1612 return "sethi\t%%gdop_hix22(%a1), %0";
1614 return "sethi\t%%hi(%a1), %0";
1618 (define_insn "movdi_pic_gotdata_op"
1619 [(set (match_operand:DI 0 "register_operand" "=r")
1620 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1621 (match_operand:DI 2 "register_operand" "r")
1622 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1623 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1625 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1626 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1628 return "ldx\t[%1 + %2], %0";
1631 [(set_attr "type" "load")])
1633 (define_insn "*sethi_di_medlow_embmedany_pic"
1634 [(set (match_operand:DI 0 "register_operand" "=r")
1635 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1636 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1637 "sethi\t%%hi(%a1), %0")
1639 (define_insn "*sethi_di_medlow"
1640 [(set (match_operand:DI 0 "register_operand" "=r")
1641 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1642 "TARGET_CM_MEDLOW && check_pic (1)"
1643 "sethi\t%%hi(%a1), %0")
1645 (define_insn "*losum_di_medlow"
1646 [(set (match_operand:DI 0 "register_operand" "=r")
1647 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1648 (match_operand:DI 2 "symbolic_operand" "")))]
1650 "or\t%1, %%lo(%a2), %0")
1652 (define_insn "seth44"
1653 [(set (match_operand:DI 0 "register_operand" "=r")
1654 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1656 "sethi\t%%h44(%a1), %0")
1658 (define_insn "setm44"
1659 [(set (match_operand:DI 0 "register_operand" "=r")
1660 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1661 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1663 "or\t%1, %%m44(%a2), %0")
1665 (define_insn "setl44"
1666 [(set (match_operand:DI 0 "register_operand" "=r")
1667 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1668 (match_operand:DI 2 "symbolic_operand" "")))]
1670 "or\t%1, %%l44(%a2), %0")
1672 (define_insn "sethh"
1673 [(set (match_operand:DI 0 "register_operand" "=r")
1674 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1676 "sethi\t%%hh(%a1), %0")
1678 (define_insn "setlm"
1679 [(set (match_operand:DI 0 "register_operand" "=r")
1680 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1682 "sethi\t%%lm(%a1), %0")
1684 (define_insn "sethm"
1685 [(set (match_operand:DI 0 "register_operand" "=r")
1686 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1687 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1689 "or\t%1, %%hm(%a2), %0")
1691 (define_insn "setlo"
1692 [(set (match_operand:DI 0 "register_operand" "=r")
1693 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1694 (match_operand:DI 2 "symbolic_operand" "")))]
1696 "or\t%1, %%lo(%a2), %0")
1698 (define_insn "embmedany_sethi"
1699 [(set (match_operand:DI 0 "register_operand" "=r")
1700 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1701 "TARGET_CM_EMBMEDANY && check_pic (1)"
1702 "sethi\t%%hi(%a1), %0")
1704 (define_insn "embmedany_losum"
1705 [(set (match_operand:DI 0 "register_operand" "=r")
1706 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1707 (match_operand:DI 2 "data_segment_operand" "")))]
1708 "TARGET_CM_EMBMEDANY"
1709 "add\t%1, %%lo(%a2), %0")
1711 (define_insn "embmedany_brsum"
1712 [(set (match_operand:DI 0 "register_operand" "=r")
1713 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1714 "TARGET_CM_EMBMEDANY"
1717 (define_insn "embmedany_textuhi"
1718 [(set (match_operand:DI 0 "register_operand" "=r")
1719 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1720 "TARGET_CM_EMBMEDANY && check_pic (1)"
1721 "sethi\t%%uhi(%a1), %0")
1723 (define_insn "embmedany_texthi"
1724 [(set (match_operand:DI 0 "register_operand" "=r")
1725 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1726 "TARGET_CM_EMBMEDANY && check_pic (1)"
1727 "sethi\t%%hi(%a1), %0")
1729 (define_insn "embmedany_textulo"
1730 [(set (match_operand:DI 0 "register_operand" "=r")
1731 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1732 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1733 "TARGET_CM_EMBMEDANY"
1734 "or\t%1, %%ulo(%a2), %0")
1736 (define_insn "embmedany_textlo"
1737 [(set (match_operand:DI 0 "register_operand" "=r")
1738 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1739 (match_operand:DI 2 "text_segment_operand" "")))]
1740 "TARGET_CM_EMBMEDANY"
1741 "or\t%1, %%lo(%a2), %0")
1743 ;; Now some patterns to help reload out a bit.
1744 (define_expand "reload_indi"
1745 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1746 (match_operand:DI 1 "immediate_operand" "")
1747 (match_operand:TI 2 "register_operand" "=&r")])]
1749 || TARGET_CM_EMBMEDANY)
1752 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1756 (define_expand "reload_outdi"
1757 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1758 (match_operand:DI 1 "immediate_operand" "")
1759 (match_operand:TI 2 "register_operand" "=&r")])]
1761 || TARGET_CM_EMBMEDANY)
1764 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1768 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1770 [(set (match_operand:DI 0 "register_operand" "")
1771 (match_operand:DI 1 "const_int_operand" ""))]
1772 "! TARGET_ARCH64 && reload_completed"
1773 [(clobber (const_int 0))]
1775 #if HOST_BITS_PER_WIDE_INT == 32
1776 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1777 (INTVAL (operands[1]) < 0) ?
1780 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1783 unsigned int low, high;
1785 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1786 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1787 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1789 /* Slick... but this trick loses if this subreg constant part
1790 can be done in one insn. */
1792 && ! SPARC_SETHI32_P (high)
1793 && ! SPARC_SIMM13_P (high))
1794 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1795 gen_highpart (SImode, operands[0])));
1797 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1803 [(set (match_operand:DI 0 "register_operand" "")
1804 (match_operand:DI 1 "const_double_operand" ""))]
1808 && ((GET_CODE (operands[0]) == REG
1809 && REGNO (operands[0]) < 32)
1810 || (GET_CODE (operands[0]) == SUBREG
1811 && GET_CODE (SUBREG_REG (operands[0])) == REG
1812 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1813 [(clobber (const_int 0))]
1815 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1816 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1818 /* Slick... but this trick loses if this subreg constant part
1819 can be done in one insn. */
1820 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1821 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1822 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1824 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1825 gen_highpart (SImode, operands[0])));
1829 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1830 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1836 [(set (match_operand:DI 0 "register_operand" "")
1837 (match_operand:DI 1 "register_operand" ""))]
1841 && ((GET_CODE (operands[0]) == REG
1842 && REGNO (operands[0]) < 32)
1843 || (GET_CODE (operands[0]) == SUBREG
1844 && GET_CODE (SUBREG_REG (operands[0])) == REG
1845 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1846 [(clobber (const_int 0))]
1848 rtx set_dest = operands[0];
1849 rtx set_src = operands[1];
1853 dest1 = gen_highpart (SImode, set_dest);
1854 dest2 = gen_lowpart (SImode, set_dest);
1855 src1 = gen_highpart (SImode, set_src);
1856 src2 = gen_lowpart (SImode, set_src);
1858 /* Now emit using the real source and destination we found, swapping
1859 the order if we detect overlap. */
1860 if (reg_overlap_mentioned_p (dest1, src2))
1862 emit_insn (gen_movsi (dest2, src2));
1863 emit_insn (gen_movsi (dest1, src1));
1867 emit_insn (gen_movsi (dest1, src1));
1868 emit_insn (gen_movsi (dest2, src2));
1873 ;; Now handle the cases of memory moves from/to non-even
1874 ;; DI mode register pairs.
1876 [(set (match_operand:DI 0 "register_operand" "")
1877 (match_operand:DI 1 "memory_operand" ""))]
1880 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1881 [(clobber (const_int 0))]
1883 rtx word0 = adjust_address (operands[1], SImode, 0);
1884 rtx word1 = adjust_address (operands[1], SImode, 4);
1885 rtx high_part = gen_highpart (SImode, operands[0]);
1886 rtx low_part = gen_lowpart (SImode, operands[0]);
1888 if (reg_overlap_mentioned_p (high_part, word1))
1890 emit_insn (gen_movsi (low_part, word1));
1891 emit_insn (gen_movsi (high_part, word0));
1895 emit_insn (gen_movsi (high_part, word0));
1896 emit_insn (gen_movsi (low_part, word1));
1902 [(set (match_operand:DI 0 "memory_operand" "")
1903 (match_operand:DI 1 "register_operand" ""))]
1906 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1907 [(clobber (const_int 0))]
1909 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1910 gen_highpart (SImode, operands[1])));
1911 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1912 gen_lowpart (SImode, operands[1])));
1917 [(set (match_operand:DI 0 "memory_operand" "")
1918 (match_operand:DI 1 "const_zero_operand" ""))]
1922 && ! mem_min_alignment (operands[0], 8)))
1923 && offsettable_memref_p (operands[0])"
1924 [(clobber (const_int 0))]
1926 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1927 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1932 ;; Floating point and vector move instructions
1934 ;; Yes, you guessed it right, the former movsf expander.
1935 (define_expand "mov<V32:mode>"
1936 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1937 (match_operand:V32 1 "general_operand" ""))]
1938 "<V32:MODE>mode == SFmode || TARGET_VIS"
1940 if (sparc_expand_move (<V32:MODE>mode, operands))
1944 (define_insn "*movsf_insn"
1945 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,d,f,*r,*r,*r,f,*r,m,m")
1946 (match_operand:V32 1 "input_operand" "GY,ZC,f,*rRY,Q,S,m,m,f,*rGY"))]
1948 && (register_operand (operands[0], <V32:MODE>mode)
1949 || register_or_zero_or_all_ones_operand (operands[1], <V32:MODE>mode))"
1951 if (GET_CODE (operands[1]) == CONST_DOUBLE
1952 && (which_alternative == 3
1953 || which_alternative == 4
1954 || which_alternative == 5))
1959 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1960 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1961 operands[1] = GEN_INT (i);
1964 switch (which_alternative)
1967 return "fzeros\t%0";
1971 return "fmovs\t%1, %0";
1973 return "mov\t%1, %0";
1975 return "sethi\t%%hi(%a1), %0";
1980 return "ld\t%1, %0";
1983 return "st\t%r1, %0";
1988 [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1990 ;; Exactly the same as above, except that all `f' cases are deleted.
1991 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1994 (define_insn "*movsf_insn_no_fpu"
1995 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1996 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1998 && (register_operand (operands[0], SFmode)
1999 || register_or_zero_operand (operands[1], SFmode))"
2001 if (GET_CODE (operands[1]) == CONST_DOUBLE
2002 && (which_alternative == 0
2003 || which_alternative == 1
2004 || which_alternative == 2))
2009 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2010 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2011 operands[1] = GEN_INT (i);
2014 switch (which_alternative)
2017 return "mov\t%1, %0";
2019 return "sethi\t%%hi(%a1), %0";
2023 return "ld\t%1, %0";
2025 return "st\t%r1, %0";
2030 [(set_attr "type" "*,*,*,load,store")])
2032 ;; The following 3 patterns build SFmode constants in integer registers.
2034 (define_insn "*movsf_lo_sum"
2035 [(set (match_operand:SF 0 "register_operand" "=r")
2036 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2037 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2043 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2044 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2045 operands[2] = GEN_INT (i);
2046 return "or\t%1, %%lo(%a2), %0";
2049 (define_insn "*movsf_high"
2050 [(set (match_operand:SF 0 "register_operand" "=r")
2051 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2057 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2058 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2059 operands[1] = GEN_INT (i);
2060 return "sethi\t%%hi(%1), %0";
2064 [(set (match_operand:SF 0 "register_operand" "")
2065 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2066 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2067 [(set (match_dup 0) (high:SF (match_dup 1)))
2068 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2070 ;; Yes, you again guessed it right, the former movdf expander.
2071 (define_expand "mov<V64:mode>"
2072 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2073 (match_operand:V64 1 "general_operand" ""))]
2074 "<V64:MODE>mode == DFmode || TARGET_VIS"
2076 if (sparc_expand_move (<V64:MODE>mode, operands))
2080 ;; Be careful, fmovd does not exist when !v9.
2081 (define_insn "*movdf_insn_sp32"
2082 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2083 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2086 && (register_operand (operands[0], DFmode)
2087 || register_or_zero_operand (operands[1], DFmode))"
2099 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2100 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2102 (define_insn "*movdf_insn_sp32_no_fpu"
2103 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2104 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2107 && (register_operand (operands[0], DFmode)
2108 || register_or_zero_operand (operands[1], DFmode))"
2115 [(set_attr "type" "load,store,*,*,*")
2116 (set_attr "length" "*,*,2,2,2")])
2118 ;; We have available v9 double floats but not 64-bit integer registers.
2119 (define_insn "*movdf_insn_sp32_v9"
2120 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,T,W,U,T,f,*r,o")
2121 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2125 && (register_operand (operands[0], <V64:MODE>mode)
2126 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2139 [(set_attr "type" "fga,fga,fpmove,load,store,store,load,store,*,*,*")
2140 (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")
2141 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*")])
2143 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2144 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2145 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2149 && (register_operand (operands[0], DFmode)
2150 || register_or_zero_operand (operands[1], DFmode))"
2157 [(set_attr "type" "load,store,store,*,*")
2158 (set_attr "length" "*,*,*,2,2")])
2160 ;; We have available both v9 double floats and 64-bit integer registers.
2161 (define_insn "*movdf_insn_sp64"
2162 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,W,*r,*r,m,*r")
2163 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,e,*rGY,m,*rGY,DF"))]
2166 && (register_operand (operands[0], <V64:MODE>mode)
2167 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2178 [(set_attr "type" "fga,fga,fpmove,load,store,*,load,store,*")
2179 (set_attr "length" "*,*,*,*,*,*,*,*,2")
2180 (set_attr "fptype" "double,double,double,*,*,*,*,*,*")])
2182 (define_insn "*movdf_insn_sp64_no_fpu"
2183 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2184 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2187 && (register_operand (operands[0], DFmode)
2188 || register_or_zero_operand (operands[1], DFmode))"
2193 [(set_attr "type" "*,load,store")])
2195 ;; This pattern builds V64mode constants in integer registers.
2197 [(set (match_operand:V64 0 "register_operand" "")
2198 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2200 && (GET_CODE (operands[0]) == REG
2201 && REGNO (operands[0]) < 32)
2202 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2203 && reload_completed"
2204 [(clobber (const_int 0))]
2206 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2210 #if HOST_BITS_PER_WIDE_INT == 32
2213 enum machine_mode mode = GET_MODE (operands[1]);
2214 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2215 emit_insn (gen_movdi (operands[0], tem));
2220 enum machine_mode mode = GET_MODE (operands[1]);
2221 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2222 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2224 gcc_assert (GET_CODE (hi) == CONST_INT);
2225 gcc_assert (GET_CODE (lo) == CONST_INT);
2227 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2229 /* Slick... but this trick loses if this subreg constant part
2230 can be done in one insn. */
2232 && ! SPARC_SETHI32_P (INTVAL (hi))
2233 && ! SPARC_SIMM13_P (INTVAL (hi)))
2235 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2236 gen_highpart (SImode, operands[0])));
2240 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2246 ;; Ok, now the splits to handle all the multi insn and
2247 ;; mis-aligned memory address cases.
2248 ;; In these splits please take note that we must be
2249 ;; careful when V9 but not ARCH64 because the integer
2250 ;; register DFmode cases must be handled.
2252 [(set (match_operand:V64 0 "register_operand" "")
2253 (match_operand:V64 1 "register_operand" ""))]
2256 && ((GET_CODE (operands[0]) == REG
2257 && REGNO (operands[0]) < 32)
2258 || (GET_CODE (operands[0]) == SUBREG
2259 && GET_CODE (SUBREG_REG (operands[0])) == REG
2260 && REGNO (SUBREG_REG (operands[0])) < 32))))
2261 && reload_completed"
2262 [(clobber (const_int 0))]
2264 rtx set_dest = operands[0];
2265 rtx set_src = operands[1];
2268 enum machine_mode half_mode;
2270 /* We can be expanded for DFmode or integral vector modes. */
2271 if (<V64:MODE>mode == DFmode)
2276 dest1 = gen_highpart (half_mode, set_dest);
2277 dest2 = gen_lowpart (half_mode, set_dest);
2278 src1 = gen_highpart (half_mode, set_src);
2279 src2 = gen_lowpart (half_mode, set_src);
2281 /* Now emit using the real source and destination we found, swapping
2282 the order if we detect overlap. */
2283 if (reg_overlap_mentioned_p (dest1, src2))
2285 emit_move_insn_1 (dest2, src2);
2286 emit_move_insn_1 (dest1, src1);
2290 emit_move_insn_1 (dest1, src1);
2291 emit_move_insn_1 (dest2, src2);
2297 [(set (match_operand:V64 0 "register_operand" "")
2298 (match_operand:V64 1 "memory_operand" ""))]
2301 && (((REGNO (operands[0]) % 2) != 0)
2302 || ! mem_min_alignment (operands[1], 8))
2303 && offsettable_memref_p (operands[1])"
2304 [(clobber (const_int 0))]
2306 enum machine_mode half_mode;
2309 /* We can be expanded for DFmode or integral vector modes. */
2310 if (<V64:MODE>mode == DFmode)
2315 word0 = adjust_address (operands[1], half_mode, 0);
2316 word1 = adjust_address (operands[1], half_mode, 4);
2318 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2320 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2321 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2325 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2326 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2332 [(set (match_operand:V64 0 "memory_operand" "")
2333 (match_operand:V64 1 "register_operand" ""))]
2336 && (((REGNO (operands[1]) % 2) != 0)
2337 || ! mem_min_alignment (operands[0], 8))
2338 && offsettable_memref_p (operands[0])"
2339 [(clobber (const_int 0))]
2341 enum machine_mode half_mode;
2344 /* We can be expanded for DFmode or integral vector modes. */
2345 if (<V64:MODE>mode == DFmode)
2350 word0 = adjust_address (operands[0], half_mode, 0);
2351 word1 = adjust_address (operands[0], half_mode, 4);
2353 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2354 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2359 [(set (match_operand:V64 0 "memory_operand" "")
2360 (match_operand:V64 1 "const_zero_operand" ""))]
2364 && ! mem_min_alignment (operands[0], 8)))
2365 && offsettable_memref_p (operands[0])"
2366 [(clobber (const_int 0))]
2368 enum machine_mode half_mode;
2371 /* We can be expanded for DFmode or integral vector modes. */
2372 if (<V64:MODE>mode == DFmode)
2377 dest1 = adjust_address (operands[0], half_mode, 0);
2378 dest2 = adjust_address (operands[0], half_mode, 4);
2380 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2381 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2386 [(set (match_operand:V64 0 "register_operand" "")
2387 (match_operand:V64 1 "const_zero_operand" ""))]
2390 && ((GET_CODE (operands[0]) == REG
2391 && REGNO (operands[0]) < 32)
2392 || (GET_CODE (operands[0]) == SUBREG
2393 && GET_CODE (SUBREG_REG (operands[0])) == REG
2394 && REGNO (SUBREG_REG (operands[0])) < 32))"
2395 [(clobber (const_int 0))]
2397 enum machine_mode half_mode;
2398 rtx set_dest = operands[0];
2401 /* We can be expanded for DFmode or integral vector modes. */
2402 if (<V64:MODE>mode == DFmode)
2407 dest1 = gen_highpart (half_mode, set_dest);
2408 dest2 = gen_lowpart (half_mode, set_dest);
2409 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2410 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2414 (define_expand "movtf"
2415 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2416 (match_operand:TF 1 "general_operand" ""))]
2419 if (sparc_expand_move (TFmode, operands))
2423 (define_insn "*movtf_insn_sp32"
2424 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2425 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2428 && (register_operand (operands[0], TFmode)
2429 || register_or_zero_operand (operands[1], TFmode))"
2431 [(set_attr "length" "4")])
2433 ;; Exactly the same as above, except that all `e' cases are deleted.
2434 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2437 (define_insn "*movtf_insn_sp32_no_fpu"
2438 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2439 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2442 && (register_operand (operands[0], TFmode)
2443 || register_or_zero_operand (operands[1], TFmode))"
2445 [(set_attr "length" "4")])
2447 (define_insn "*movtf_insn_sp64"
2448 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2449 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2452 && ! TARGET_HARD_QUAD
2453 && (register_operand (operands[0], TFmode)
2454 || register_or_zero_operand (operands[1], TFmode))"
2456 [(set_attr "length" "2")])
2458 (define_insn "*movtf_insn_sp64_hq"
2459 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2460 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2464 && (register_operand (operands[0], TFmode)
2465 || register_or_zero_operand (operands[1], TFmode))"
2473 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2474 (set_attr "length" "2,*,*,*,2,2")])
2476 (define_insn "*movtf_insn_sp64_no_fpu"
2477 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2478 (match_operand:TF 1 "input_operand" "orG,rG"))]
2481 && (register_operand (operands[0], TFmode)
2482 || register_or_zero_operand (operands[1], TFmode))"
2484 [(set_attr "length" "2")])
2486 ;; Now all the splits to handle multi-insn TF mode moves.
2488 [(set (match_operand:TF 0 "register_operand" "")
2489 (match_operand:TF 1 "register_operand" ""))]
2493 && ! TARGET_HARD_QUAD)
2494 || ! fp_register_operand (operands[0], TFmode))"
2495 [(clobber (const_int 0))]
2497 rtx set_dest = operands[0];
2498 rtx set_src = operands[1];
2502 dest1 = gen_df_reg (set_dest, 0);
2503 dest2 = gen_df_reg (set_dest, 1);
2504 src1 = gen_df_reg (set_src, 0);
2505 src2 = gen_df_reg (set_src, 1);
2507 /* Now emit using the real source and destination we found, swapping
2508 the order if we detect overlap. */
2509 if (reg_overlap_mentioned_p (dest1, src2))
2511 emit_insn (gen_movdf (dest2, src2));
2512 emit_insn (gen_movdf (dest1, src1));
2516 emit_insn (gen_movdf (dest1, src1));
2517 emit_insn (gen_movdf (dest2, src2));
2523 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2524 (match_operand:TF 1 "const_zero_operand" ""))]
2526 [(clobber (const_int 0))]
2528 rtx set_dest = operands[0];
2531 switch (GET_CODE (set_dest))
2534 dest1 = gen_df_reg (set_dest, 0);
2535 dest2 = gen_df_reg (set_dest, 1);
2538 dest1 = adjust_address (set_dest, DFmode, 0);
2539 dest2 = adjust_address (set_dest, DFmode, 8);
2545 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2546 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2551 [(set (match_operand:TF 0 "register_operand" "")
2552 (match_operand:TF 1 "memory_operand" ""))]
2554 && offsettable_memref_p (operands[1])
2556 || ! TARGET_HARD_QUAD
2557 || ! fp_register_operand (operands[0], TFmode)))"
2558 [(clobber (const_int 0))]
2560 rtx word0 = adjust_address (operands[1], DFmode, 0);
2561 rtx word1 = adjust_address (operands[1], DFmode, 8);
2562 rtx set_dest, dest1, dest2;
2564 set_dest = operands[0];
2566 dest1 = gen_df_reg (set_dest, 0);
2567 dest2 = gen_df_reg (set_dest, 1);
2569 /* Now output, ordering such that we don't clobber any registers
2570 mentioned in the address. */
2571 if (reg_overlap_mentioned_p (dest1, word1))
2574 emit_insn (gen_movdf (dest2, word1));
2575 emit_insn (gen_movdf (dest1, word0));
2579 emit_insn (gen_movdf (dest1, word0));
2580 emit_insn (gen_movdf (dest2, word1));
2586 [(set (match_operand:TF 0 "memory_operand" "")
2587 (match_operand:TF 1 "register_operand" ""))]
2589 && offsettable_memref_p (operands[0])
2591 || ! TARGET_HARD_QUAD
2592 || ! fp_register_operand (operands[1], TFmode)))"
2593 [(clobber (const_int 0))]
2595 rtx set_src = operands[1];
2597 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2598 gen_df_reg (set_src, 0)));
2599 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2600 gen_df_reg (set_src, 1)));
2605 ;; SPARC-V9 conditional move instructions
2607 ;; We can handle larger constants here for some flavors, but for now we keep
2608 ;; it simple and only allow those constants supported by all flavors.
2609 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2610 ;; 3 contains the constant if one is present, but we handle either for
2611 ;; generality (sparc.c puts a constant in operand 2).
2613 (define_expand "mov<I:mode>cc"
2614 [(set (match_operand:I 0 "register_operand" "")
2615 (if_then_else:I (match_operand 1 "comparison_operator" "")
2616 (match_operand:I 2 "arith10_operand" "")
2617 (match_operand:I 3 "arith10_operand" "")))]
2618 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2622 if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64)
2625 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2627 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2628 GET_CODE (operands[1]));
2630 if (XEXP (operands[1], 1) == const0_rtx
2631 && GET_CODE (XEXP (operands[1], 0)) == REG
2632 && GET_MODE (XEXP (operands[1], 0)) == DImode
2633 && v9_regcmp_p (GET_CODE (operands[1])))
2634 cc_reg = XEXP (operands[1], 0);
2636 cc_reg = gen_compare_reg (operands[1]);
2639 = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg,
2643 (define_expand "mov<F:mode>cc"
2644 [(set (match_operand:F 0 "register_operand" "")
2645 (if_then_else:F (match_operand 1 "comparison_operator" "")
2646 (match_operand:F 2 "register_operand" "")
2647 (match_operand:F 3 "register_operand" "")))]
2648 "TARGET_V9 && TARGET_FPU"
2652 if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64)
2655 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2657 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2658 GET_CODE (operands[1]));
2660 if (XEXP (operands[1], 1) == const0_rtx
2661 && GET_CODE (XEXP (operands[1], 0)) == REG
2662 && GET_MODE (XEXP (operands[1], 0)) == DImode
2663 && v9_regcmp_p (GET_CODE (operands[1])))
2664 cc_reg = XEXP (operands[1], 0);
2666 cc_reg = gen_compare_reg (operands[1]);
2669 = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg,
2673 ;; Conditional move define_insns
2675 (define_insn "*mov<I:mode>_cc_v9"
2676 [(set (match_operand:I 0 "register_operand" "=r,r")
2677 (if_then_else:I (match_operator 1 "comparison_operator"
2678 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2680 (match_operand:I 3 "arith11_operand" "rL,0")
2681 (match_operand:I 4 "arith11_operand" "0,rL")))]
2682 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2685 mov%c1\t%x2, %4, %0"
2686 [(set_attr "type" "cmove")])
2688 (define_insn "*mov<I:mode>_cc_reg_sp64"
2689 [(set (match_operand:I 0 "register_operand" "=r,r")
2690 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2691 [(match_operand:DI 2 "register_operand" "r,r")
2693 (match_operand:I 3 "arith10_operand" "rM,0")
2694 (match_operand:I 4 "arith10_operand" "0,rM")))]
2697 movr%D1\t%2, %r3, %0
2698 movr%d1\t%2, %r4, %0"
2699 [(set_attr "type" "cmove")])
2701 (define_insn "*movsf_cc_v9"
2702 [(set (match_operand:SF 0 "register_operand" "=f,f")
2703 (if_then_else:SF (match_operator 1 "comparison_operator"
2704 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2706 (match_operand:SF 3 "register_operand" "f,0")
2707 (match_operand:SF 4 "register_operand" "0,f")))]
2708 "TARGET_V9 && TARGET_FPU"
2710 fmovs%C1\t%x2, %3, %0
2711 fmovs%c1\t%x2, %4, %0"
2712 [(set_attr "type" "fpcmove")])
2714 (define_insn "*movsf_cc_reg_sp64"
2715 [(set (match_operand:SF 0 "register_operand" "=f,f")
2716 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2717 [(match_operand:DI 2 "register_operand" "r,r")
2719 (match_operand:SF 3 "register_operand" "f,0")
2720 (match_operand:SF 4 "register_operand" "0,f")))]
2721 "TARGET_ARCH64 && TARGET_FPU"
2723 fmovrs%D1\t%2, %3, %0
2724 fmovrs%d1\t%2, %4, %0"
2725 [(set_attr "type" "fpcrmove")])
2727 ;; Named because invoked by movtf_cc_v9
2728 (define_insn "movdf_cc_v9"
2729 [(set (match_operand:DF 0 "register_operand" "=e,e")
2730 (if_then_else:DF (match_operator 1 "comparison_operator"
2731 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2733 (match_operand:DF 3 "register_operand" "e,0")
2734 (match_operand:DF 4 "register_operand" "0,e")))]
2735 "TARGET_V9 && TARGET_FPU"
2737 fmovd%C1\t%x2, %3, %0
2738 fmovd%c1\t%x2, %4, %0"
2739 [(set_attr "type" "fpcmove")
2740 (set_attr "fptype" "double")])
2742 ;; Named because invoked by movtf_cc_reg_sp64
2743 (define_insn "movdf_cc_reg_sp64"
2744 [(set (match_operand:DF 0 "register_operand" "=e,e")
2745 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2746 [(match_operand:DI 2 "register_operand" "r,r")
2748 (match_operand:DF 3 "register_operand" "e,0")
2749 (match_operand:DF 4 "register_operand" "0,e")))]
2750 "TARGET_ARCH64 && TARGET_FPU"
2752 fmovrd%D1\t%2, %3, %0
2753 fmovrd%d1\t%2, %4, %0"
2754 [(set_attr "type" "fpcrmove")
2755 (set_attr "fptype" "double")])
2757 (define_insn "*movtf_cc_hq_v9"
2758 [(set (match_operand:TF 0 "register_operand" "=e,e")
2759 (if_then_else:TF (match_operator 1 "comparison_operator"
2760 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2762 (match_operand:TF 3 "register_operand" "e,0")
2763 (match_operand:TF 4 "register_operand" "0,e")))]
2764 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2766 fmovq%C1\t%x2, %3, %0
2767 fmovq%c1\t%x2, %4, %0"
2768 [(set_attr "type" "fpcmove")])
2770 (define_insn "*movtf_cc_reg_hq_sp64"
2771 [(set (match_operand:TF 0 "register_operand" "=e,e")
2772 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2773 [(match_operand:DI 2 "register_operand" "r,r")
2775 (match_operand:TF 3 "register_operand" "e,0")
2776 (match_operand:TF 4 "register_operand" "0,e")))]
2777 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2779 fmovrq%D1\t%2, %3, %0
2780 fmovrq%d1\t%2, %4, %0"
2781 [(set_attr "type" "fpcrmove")])
2783 (define_insn_and_split "*movtf_cc_v9"
2784 [(set (match_operand:TF 0 "register_operand" "=e,e")
2785 (if_then_else:TF (match_operator 1 "comparison_operator"
2786 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2788 (match_operand:TF 3 "register_operand" "e,0")
2789 (match_operand:TF 4 "register_operand" "0,e")))]
2790 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2792 "&& reload_completed"
2793 [(clobber (const_int 0))]
2795 rtx set_dest = operands[0];
2796 rtx set_srca = operands[3];
2797 rtx set_srcb = operands[4];
2798 int third = rtx_equal_p (set_dest, set_srca);
2800 rtx srca1, srca2, srcb1, srcb2;
2802 dest1 = gen_df_reg (set_dest, 0);
2803 dest2 = gen_df_reg (set_dest, 1);
2804 srca1 = gen_df_reg (set_srca, 0);
2805 srca2 = gen_df_reg (set_srca, 1);
2806 srcb1 = gen_df_reg (set_srcb, 0);
2807 srcb2 = gen_df_reg (set_srcb, 1);
2809 /* Now emit using the real source and destination we found, swapping
2810 the order if we detect overlap. */
2811 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2812 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2814 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2815 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2819 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2820 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2824 [(set_attr "length" "2")])
2826 (define_insn_and_split "*movtf_cc_reg_sp64"
2827 [(set (match_operand:TF 0 "register_operand" "=e,e")
2828 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2829 [(match_operand:DI 2 "register_operand" "r,r")
2831 (match_operand:TF 3 "register_operand" "e,0")
2832 (match_operand:TF 4 "register_operand" "0,e")))]
2833 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2835 "&& reload_completed"
2836 [(clobber (const_int 0))]
2838 rtx set_dest = operands[0];
2839 rtx set_srca = operands[3];
2840 rtx set_srcb = operands[4];
2841 int third = rtx_equal_p (set_dest, set_srca);
2843 rtx srca1, srca2, srcb1, srcb2;
2845 dest1 = gen_df_reg (set_dest, 0);
2846 dest2 = gen_df_reg (set_dest, 1);
2847 srca1 = gen_df_reg (set_srca, 0);
2848 srca2 = gen_df_reg (set_srca, 1);
2849 srcb1 = gen_df_reg (set_srcb, 0);
2850 srcb2 = gen_df_reg (set_srcb, 1);
2852 /* Now emit using the real source and destination we found, swapping
2853 the order if we detect overlap. */
2854 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2855 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2857 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2858 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2862 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2863 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2867 [(set_attr "length" "2")])
2870 ;; Zero-extension instructions
2872 ;; These patterns originally accepted general_operands, however, slightly
2873 ;; better code is generated by only accepting register_operands, and then
2874 ;; letting combine generate the ldu[hb] insns.
2876 (define_expand "zero_extendhisi2"
2877 [(set (match_operand:SI 0 "register_operand" "")
2878 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2881 rtx temp = gen_reg_rtx (SImode);
2882 rtx shift_16 = GEN_INT (16);
2883 int op1_subbyte = 0;
2885 if (GET_CODE (operand1) == SUBREG)
2887 op1_subbyte = SUBREG_BYTE (operand1);
2888 op1_subbyte /= GET_MODE_SIZE (SImode);
2889 op1_subbyte *= GET_MODE_SIZE (SImode);
2890 operand1 = XEXP (operand1, 0);
2893 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2895 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2899 (define_insn "*zero_extendhisi2_insn"
2900 [(set (match_operand:SI 0 "register_operand" "=r")
2901 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2904 [(set_attr "type" "load")
2905 (set_attr "us3load_type" "3cycle")])
2907 (define_expand "zero_extendqihi2"
2908 [(set (match_operand:HI 0 "register_operand" "")
2909 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2913 (define_insn "*zero_extendqihi2_insn"
2914 [(set (match_operand:HI 0 "register_operand" "=r,r")
2915 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2916 "GET_CODE (operands[1]) != CONST_INT"
2920 [(set_attr "type" "*,load")
2921 (set_attr "us3load_type" "*,3cycle")])
2923 (define_expand "zero_extendqisi2"
2924 [(set (match_operand:SI 0 "register_operand" "")
2925 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2929 (define_insn "*zero_extendqisi2_insn"
2930 [(set (match_operand:SI 0 "register_operand" "=r,r")
2931 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2932 "GET_CODE (operands[1]) != CONST_INT"
2936 [(set_attr "type" "*,load")
2937 (set_attr "us3load_type" "*,3cycle")])
2939 (define_expand "zero_extendqidi2"
2940 [(set (match_operand:DI 0 "register_operand" "")
2941 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2945 (define_insn "*zero_extendqidi2_insn"
2946 [(set (match_operand:DI 0 "register_operand" "=r,r")
2947 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2948 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2952 [(set_attr "type" "*,load")
2953 (set_attr "us3load_type" "*,3cycle")])
2955 (define_expand "zero_extendhidi2"
2956 [(set (match_operand:DI 0 "register_operand" "")
2957 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2960 rtx temp = gen_reg_rtx (DImode);
2961 rtx shift_48 = GEN_INT (48);
2962 int op1_subbyte = 0;
2964 if (GET_CODE (operand1) == SUBREG)
2966 op1_subbyte = SUBREG_BYTE (operand1);
2967 op1_subbyte /= GET_MODE_SIZE (DImode);
2968 op1_subbyte *= GET_MODE_SIZE (DImode);
2969 operand1 = XEXP (operand1, 0);
2972 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2974 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2978 (define_insn "*zero_extendhidi2_insn"
2979 [(set (match_operand:DI 0 "register_operand" "=r")
2980 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2983 [(set_attr "type" "load")
2984 (set_attr "us3load_type" "3cycle")])
2986 ;; ??? Write truncdisi pattern using sra?
2988 (define_expand "zero_extendsidi2"
2989 [(set (match_operand:DI 0 "register_operand" "")
2990 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2994 (define_insn "*zero_extendsidi2_insn_sp64"
2995 [(set (match_operand:DI 0 "register_operand" "=r,r")
2996 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2997 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3001 [(set_attr "type" "shift,load")])
3003 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3004 [(set (match_operand:DI 0 "register_operand" "=r")
3005 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3008 "&& reload_completed"
3009 [(set (match_dup 2) (match_dup 3))
3010 (set (match_dup 4) (match_dup 5))]
3014 dest1 = gen_highpart (SImode, operands[0]);
3015 dest2 = gen_lowpart (SImode, operands[0]);
3017 /* Swap the order in case of overlap. */
3018 if (REGNO (dest1) == REGNO (operands[1]))
3020 operands[2] = dest2;
3021 operands[3] = operands[1];
3022 operands[4] = dest1;
3023 operands[5] = const0_rtx;
3027 operands[2] = dest1;
3028 operands[3] = const0_rtx;
3029 operands[4] = dest2;
3030 operands[5] = operands[1];
3033 [(set_attr "length" "2")])
3035 ;; Simplify comparisons of extended values.
3037 (define_insn "*cmp_zero_extendqisi2"
3038 [(set (reg:CC CC_REG)
3039 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3042 "andcc\t%0, 0xff, %%g0"
3043 [(set_attr "type" "compare")])
3045 (define_insn "*cmp_zero_qi"
3046 [(set (reg:CC CC_REG)
3047 (compare:CC (match_operand:QI 0 "register_operand" "r")
3050 "andcc\t%0, 0xff, %%g0"
3051 [(set_attr "type" "compare")])
3053 (define_insn "*cmp_zero_extendqisi2_set"
3054 [(set (reg:CC CC_REG)
3055 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3057 (set (match_operand:SI 0 "register_operand" "=r")
3058 (zero_extend:SI (match_dup 1)))]
3060 "andcc\t%1, 0xff, %0"
3061 [(set_attr "type" "compare")])
3063 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3064 [(set (reg:CC CC_REG)
3065 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3068 (set (match_operand:SI 0 "register_operand" "=r")
3069 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3071 "andcc\t%1, 0xff, %0"
3072 [(set_attr "type" "compare")])
3074 (define_insn "*cmp_zero_extendqidi2"
3075 [(set (reg:CCX CC_REG)
3076 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3079 "andcc\t%0, 0xff, %%g0"
3080 [(set_attr "type" "compare")])
3082 (define_insn "*cmp_zero_qi_sp64"
3083 [(set (reg:CCX CC_REG)
3084 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3087 "andcc\t%0, 0xff, %%g0"
3088 [(set_attr "type" "compare")])
3090 (define_insn "*cmp_zero_extendqidi2_set"
3091 [(set (reg:CCX CC_REG)
3092 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3094 (set (match_operand:DI 0 "register_operand" "=r")
3095 (zero_extend:DI (match_dup 1)))]
3097 "andcc\t%1, 0xff, %0"
3098 [(set_attr "type" "compare")])
3100 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3101 [(set (reg:CCX CC_REG)
3102 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3105 (set (match_operand:DI 0 "register_operand" "=r")
3106 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3108 "andcc\t%1, 0xff, %0"
3109 [(set_attr "type" "compare")])
3111 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3113 (define_insn "*cmp_siqi_trunc"
3114 [(set (reg:CC CC_REG)
3115 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3118 "andcc\t%0, 0xff, %%g0"
3119 [(set_attr "type" "compare")])
3121 (define_insn "*cmp_siqi_trunc_set"
3122 [(set (reg:CC CC_REG)
3123 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3125 (set (match_operand:QI 0 "register_operand" "=r")
3126 (subreg:QI (match_dup 1) 3))]
3128 "andcc\t%1, 0xff, %0"
3129 [(set_attr "type" "compare")])
3131 (define_insn "*cmp_diqi_trunc"
3132 [(set (reg:CC CC_REG)
3133 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3136 "andcc\t%0, 0xff, %%g0"
3137 [(set_attr "type" "compare")])
3139 (define_insn "*cmp_diqi_trunc_set"
3140 [(set (reg:CC CC_REG)
3141 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3143 (set (match_operand:QI 0 "register_operand" "=r")
3144 (subreg:QI (match_dup 1) 7))]
3146 "andcc\t%1, 0xff, %0"
3147 [(set_attr "type" "compare")])
3150 ;; Sign-extension instructions
3152 ;; These patterns originally accepted general_operands, however, slightly
3153 ;; better code is generated by only accepting register_operands, and then
3154 ;; letting combine generate the lds[hb] insns.
3156 (define_expand "extendhisi2"
3157 [(set (match_operand:SI 0 "register_operand" "")
3158 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3161 rtx temp = gen_reg_rtx (SImode);
3162 rtx shift_16 = GEN_INT (16);
3163 int op1_subbyte = 0;
3165 if (GET_CODE (operand1) == SUBREG)
3167 op1_subbyte = SUBREG_BYTE (operand1);
3168 op1_subbyte /= GET_MODE_SIZE (SImode);
3169 op1_subbyte *= GET_MODE_SIZE (SImode);
3170 operand1 = XEXP (operand1, 0);
3173 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3175 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3179 (define_insn "*sign_extendhisi2_insn"
3180 [(set (match_operand:SI 0 "register_operand" "=r")
3181 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3184 [(set_attr "type" "sload")
3185 (set_attr "us3load_type" "3cycle")])
3187 (define_expand "extendqihi2"
3188 [(set (match_operand:HI 0 "register_operand" "")
3189 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3192 rtx temp = gen_reg_rtx (SImode);
3193 rtx shift_24 = GEN_INT (24);
3194 int op1_subbyte = 0;
3195 int op0_subbyte = 0;
3197 if (GET_CODE (operand1) == SUBREG)
3199 op1_subbyte = SUBREG_BYTE (operand1);
3200 op1_subbyte /= GET_MODE_SIZE (SImode);
3201 op1_subbyte *= GET_MODE_SIZE (SImode);
3202 operand1 = XEXP (operand1, 0);
3204 if (GET_CODE (operand0) == SUBREG)
3206 op0_subbyte = SUBREG_BYTE (operand0);
3207 op0_subbyte /= GET_MODE_SIZE (SImode);
3208 op0_subbyte *= GET_MODE_SIZE (SImode);
3209 operand0 = XEXP (operand0, 0);
3211 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3213 if (GET_MODE (operand0) != SImode)
3214 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3215 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3219 (define_insn "*sign_extendqihi2_insn"
3220 [(set (match_operand:HI 0 "register_operand" "=r")
3221 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3224 [(set_attr "type" "sload")
3225 (set_attr "us3load_type" "3cycle")])
3227 (define_expand "extendqisi2"
3228 [(set (match_operand:SI 0 "register_operand" "")
3229 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3232 rtx temp = gen_reg_rtx (SImode);
3233 rtx shift_24 = GEN_INT (24);
3234 int op1_subbyte = 0;
3236 if (GET_CODE (operand1) == SUBREG)
3238 op1_subbyte = SUBREG_BYTE (operand1);
3239 op1_subbyte /= GET_MODE_SIZE (SImode);
3240 op1_subbyte *= GET_MODE_SIZE (SImode);
3241 operand1 = XEXP (operand1, 0);
3244 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3246 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3250 (define_insn "*sign_extendqisi2_insn"
3251 [(set (match_operand:SI 0 "register_operand" "=r")
3252 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3255 [(set_attr "type" "sload")
3256 (set_attr "us3load_type" "3cycle")])
3258 (define_expand "extendqidi2"
3259 [(set (match_operand:DI 0 "register_operand" "")
3260 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3263 rtx temp = gen_reg_rtx (DImode);
3264 rtx shift_56 = GEN_INT (56);
3265 int op1_subbyte = 0;
3267 if (GET_CODE (operand1) == SUBREG)
3269 op1_subbyte = SUBREG_BYTE (operand1);
3270 op1_subbyte /= GET_MODE_SIZE (DImode);
3271 op1_subbyte *= GET_MODE_SIZE (DImode);
3272 operand1 = XEXP (operand1, 0);
3275 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3277 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3281 (define_insn "*sign_extendqidi2_insn"
3282 [(set (match_operand:DI 0 "register_operand" "=r")
3283 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3286 [(set_attr "type" "sload")
3287 (set_attr "us3load_type" "3cycle")])
3289 (define_expand "extendhidi2"
3290 [(set (match_operand:DI 0 "register_operand" "")
3291 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3294 rtx temp = gen_reg_rtx (DImode);
3295 rtx shift_48 = GEN_INT (48);
3296 int op1_subbyte = 0;
3298 if (GET_CODE (operand1) == SUBREG)
3300 op1_subbyte = SUBREG_BYTE (operand1);
3301 op1_subbyte /= GET_MODE_SIZE (DImode);
3302 op1_subbyte *= GET_MODE_SIZE (DImode);
3303 operand1 = XEXP (operand1, 0);
3306 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3308 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3312 (define_insn "*sign_extendhidi2_insn"
3313 [(set (match_operand:DI 0 "register_operand" "=r")
3314 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3317 [(set_attr "type" "sload")
3318 (set_attr "us3load_type" "3cycle")])
3320 (define_expand "extendsidi2"
3321 [(set (match_operand:DI 0 "register_operand" "")
3322 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3326 (define_insn "*sign_extendsidi2_insn"
3327 [(set (match_operand:DI 0 "register_operand" "=r,r")
3328 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3333 [(set_attr "type" "shift,sload")
3334 (set_attr "us3load_type" "*,3cycle")])
3337 ;; Special pattern for optimizing bit-field compares. This is needed
3338 ;; because combine uses this as a canonical form.
3340 (define_insn "*cmp_zero_extract"
3341 [(set (reg:CC CC_REG)
3343 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3344 (match_operand:SI 1 "small_int_operand" "I")
3345 (match_operand:SI 2 "small_int_operand" "I"))
3347 "INTVAL (operands[2]) > 19"
3349 int len = INTVAL (operands[1]);
3350 int pos = 32 - INTVAL (operands[2]) - len;
3351 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3352 operands[1] = GEN_INT (mask);
3353 return "andcc\t%0, %1, %%g0";
3355 [(set_attr "type" "compare")])
3357 (define_insn "*cmp_zero_extract_sp64"
3358 [(set (reg:CCX CC_REG)
3360 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3361 (match_operand:SI 1 "small_int_operand" "I")
3362 (match_operand:SI 2 "small_int_operand" "I"))
3364 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3366 int len = INTVAL (operands[1]);
3367 int pos = 64 - INTVAL (operands[2]) - len;
3368 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3369 operands[1] = GEN_INT (mask);
3370 return "andcc\t%0, %1, %%g0";
3372 [(set_attr "type" "compare")])
3375 ;; Conversions between float, double and long double.
3377 (define_insn "extendsfdf2"
3378 [(set (match_operand:DF 0 "register_operand" "=e")
3380 (match_operand:SF 1 "register_operand" "f")))]
3383 [(set_attr "type" "fp")
3384 (set_attr "fptype" "double")])
3386 (define_expand "extendsftf2"
3387 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3389 (match_operand:SF 1 "register_operand" "")))]
3390 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3391 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3393 (define_insn "*extendsftf2_hq"
3394 [(set (match_operand:TF 0 "register_operand" "=e")
3396 (match_operand:SF 1 "register_operand" "f")))]
3397 "TARGET_FPU && TARGET_HARD_QUAD"
3399 [(set_attr "type" "fp")])
3401 (define_expand "extenddftf2"
3402 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3404 (match_operand:DF 1 "register_operand" "")))]
3405 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3406 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3408 (define_insn "*extenddftf2_hq"
3409 [(set (match_operand:TF 0 "register_operand" "=e")
3411 (match_operand:DF 1 "register_operand" "e")))]
3412 "TARGET_FPU && TARGET_HARD_QUAD"
3414 [(set_attr "type" "fp")])
3416 (define_insn "truncdfsf2"
3417 [(set (match_operand:SF 0 "register_operand" "=f")
3419 (match_operand:DF 1 "register_operand" "e")))]
3422 [(set_attr "type" "fp")
3423 (set_attr "fptype" "double")])
3425 (define_expand "trunctfsf2"
3426 [(set (match_operand:SF 0 "register_operand" "")
3428 (match_operand:TF 1 "general_operand" "")))]
3429 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3430 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3432 (define_insn "*trunctfsf2_hq"
3433 [(set (match_operand:SF 0 "register_operand" "=f")
3435 (match_operand:TF 1 "register_operand" "e")))]
3436 "TARGET_FPU && TARGET_HARD_QUAD"
3438 [(set_attr "type" "fp")])
3440 (define_expand "trunctfdf2"
3441 [(set (match_operand:DF 0 "register_operand" "")
3443 (match_operand:TF 1 "general_operand" "")))]
3444 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3445 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3447 (define_insn "*trunctfdf2_hq"
3448 [(set (match_operand:DF 0 "register_operand" "=e")
3450 (match_operand:TF 1 "register_operand" "e")))]
3451 "TARGET_FPU && TARGET_HARD_QUAD"
3453 [(set_attr "type" "fp")])
3456 ;; Conversion between fixed point and floating point.
3458 (define_insn "floatsisf2"
3459 [(set (match_operand:SF 0 "register_operand" "=f")
3460 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3463 [(set_attr "type" "fp")
3464 (set_attr "fptype" "double")])
3466 (define_insn "floatsidf2"
3467 [(set (match_operand:DF 0 "register_operand" "=e")
3468 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3471 [(set_attr "type" "fp")
3472 (set_attr "fptype" "double")])
3474 (define_expand "floatsitf2"
3475 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3476 (float:TF (match_operand:SI 1 "register_operand" "")))]
3477 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3478 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3480 (define_insn "*floatsitf2_hq"
3481 [(set (match_operand:TF 0 "register_operand" "=e")
3482 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3483 "TARGET_FPU && TARGET_HARD_QUAD"
3485 [(set_attr "type" "fp")])
3487 (define_expand "floatunssitf2"
3488 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3489 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3490 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3491 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3493 ;; Now the same for 64 bit sources.
3495 (define_insn "floatdisf2"
3496 [(set (match_operand:SF 0 "register_operand" "=f")
3497 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3498 "TARGET_V9 && TARGET_FPU"
3500 [(set_attr "type" "fp")
3501 (set_attr "fptype" "double")])
3503 (define_expand "floatunsdisf2"
3504 [(use (match_operand:SF 0 "register_operand" ""))
3505 (use (match_operand:DI 1 "general_operand" ""))]
3506 "TARGET_ARCH64 && TARGET_FPU"
3507 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3509 (define_insn "floatdidf2"
3510 [(set (match_operand:DF 0 "register_operand" "=e")
3511 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3512 "TARGET_V9 && TARGET_FPU"
3514 [(set_attr "type" "fp")
3515 (set_attr "fptype" "double")])
3517 (define_expand "floatunsdidf2"
3518 [(use (match_operand:DF 0 "register_operand" ""))
3519 (use (match_operand:DI 1 "general_operand" ""))]
3520 "TARGET_ARCH64 && TARGET_FPU"
3521 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3523 (define_expand "floatditf2"
3524 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3525 (float:TF (match_operand:DI 1 "register_operand" "")))]
3526 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3527 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3529 (define_insn "*floatditf2_hq"
3530 [(set (match_operand:TF 0 "register_operand" "=e")
3531 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3532 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3534 [(set_attr "type" "fp")])
3536 (define_expand "floatunsditf2"
3537 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3538 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3539 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3540 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3542 ;; Convert a float to an actual integer.
3543 ;; Truncation is performed as part of the conversion.
3545 (define_insn "fix_truncsfsi2"
3546 [(set (match_operand:SI 0 "register_operand" "=f")
3547 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3550 [(set_attr "type" "fp")
3551 (set_attr "fptype" "double")])
3553 (define_insn "fix_truncdfsi2"
3554 [(set (match_operand:SI 0 "register_operand" "=f")
3555 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3558 [(set_attr "type" "fp")
3559 (set_attr "fptype" "double")])
3561 (define_expand "fix_trunctfsi2"
3562 [(set (match_operand:SI 0 "register_operand" "")
3563 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3564 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3565 "emit_tfmode_cvt (FIX, operands); DONE;")
3567 (define_insn "*fix_trunctfsi2_hq"
3568 [(set (match_operand:SI 0 "register_operand" "=f")
3569 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3570 "TARGET_FPU && TARGET_HARD_QUAD"
3572 [(set_attr "type" "fp")])
3574 (define_expand "fixuns_trunctfsi2"
3575 [(set (match_operand:SI 0 "register_operand" "")
3576 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3577 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3578 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3580 ;; Now the same, for V9 targets
3582 (define_insn "fix_truncsfdi2"
3583 [(set (match_operand:DI 0 "register_operand" "=e")
3584 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3585 "TARGET_V9 && TARGET_FPU"
3587 [(set_attr "type" "fp")
3588 (set_attr "fptype" "double")])
3590 (define_expand "fixuns_truncsfdi2"
3591 [(use (match_operand:DI 0 "register_operand" ""))
3592 (use (match_operand:SF 1 "general_operand" ""))]
3593 "TARGET_ARCH64 && TARGET_FPU"
3594 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3596 (define_insn "fix_truncdfdi2"
3597 [(set (match_operand:DI 0 "register_operand" "=e")
3598 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3599 "TARGET_V9 && TARGET_FPU"
3601 [(set_attr "type" "fp")
3602 (set_attr "fptype" "double")])
3604 (define_expand "fixuns_truncdfdi2"
3605 [(use (match_operand:DI 0 "register_operand" ""))
3606 (use (match_operand:DF 1 "general_operand" ""))]
3607 "TARGET_ARCH64 && TARGET_FPU"
3608 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3610 (define_expand "fix_trunctfdi2"
3611 [(set (match_operand:DI 0 "register_operand" "")
3612 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3613 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3614 "emit_tfmode_cvt (FIX, operands); DONE;")
3616 (define_insn "*fix_trunctfdi2_hq"
3617 [(set (match_operand:DI 0 "register_operand" "=e")
3618 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3619 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3621 [(set_attr "type" "fp")])
3623 (define_expand "fixuns_trunctfdi2"
3624 [(set (match_operand:DI 0 "register_operand" "")
3625 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3626 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3627 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3630 ;; Integer addition/subtraction instructions.
3632 (define_expand "adddi3"
3633 [(set (match_operand:DI 0 "register_operand" "")
3634 (plus:DI (match_operand:DI 1 "register_operand" "")
3635 (match_operand:DI 2 "arith_double_add_operand" "")))]
3638 if (! TARGET_ARCH64)
3640 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3641 gen_rtx_SET (VOIDmode, operands[0],
3642 gen_rtx_PLUS (DImode, operands[1],
3644 gen_rtx_CLOBBER (VOIDmode,
3645 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3650 (define_insn_and_split "*adddi3_insn_sp32"
3651 [(set (match_operand:DI 0 "register_operand" "=r")
3652 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3653 (match_operand:DI 2 "arith_double_operand" "rHI")))
3654 (clobber (reg:CC CC_REG))]
3657 "&& reload_completed"
3658 [(parallel [(set (reg:CC_NOOV CC_REG)
3659 (compare:CC_NOOV (plus:SI (match_dup 4)
3663 (plus:SI (match_dup 4) (match_dup 5)))])
3665 (plus:SI (plus:SI (match_dup 7)
3667 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3669 operands[3] = gen_lowpart (SImode, operands[0]);
3670 operands[4] = gen_lowpart (SImode, operands[1]);
3671 operands[5] = gen_lowpart (SImode, operands[2]);
3672 operands[6] = gen_highpart (SImode, operands[0]);
3673 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3674 #if HOST_BITS_PER_WIDE_INT == 32
3675 if (GET_CODE (operands[2]) == CONST_INT)
3677 if (INTVAL (operands[2]) < 0)
3678 operands[8] = constm1_rtx;
3680 operands[8] = const0_rtx;
3684 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3686 [(set_attr "length" "2")])
3688 ;; LTU here means "carry set"
3690 [(set (match_operand:SI 0 "register_operand" "=r")
3691 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3692 (match_operand:SI 2 "arith_operand" "rI"))
3693 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3696 [(set_attr "type" "ialuX")])
3698 (define_insn_and_split "*addx_extend_sp32"
3699 [(set (match_operand:DI 0 "register_operand" "=r")
3700 (zero_extend:DI (plus:SI (plus:SI
3701 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3702 (match_operand:SI 2 "arith_operand" "rI"))
3703 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3706 "&& reload_completed"
3707 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3708 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3709 (set (match_dup 4) (const_int 0))]
3710 "operands[3] = gen_lowpart (SImode, operands[0]);
3711 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3712 [(set_attr "length" "2")])
3714 (define_insn "*addx_extend_sp64"
3715 [(set (match_operand:DI 0 "register_operand" "=r")
3716 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3717 (match_operand:SI 2 "arith_operand" "rI"))
3718 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3721 [(set_attr "type" "ialuX")])
3723 (define_insn_and_split "*adddi3_extend_sp32"
3724 [(set (match_operand:DI 0 "register_operand" "=r")
3725 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3726 (match_operand:DI 2 "register_operand" "r")))
3727 (clobber (reg:CC CC_REG))]
3730 "&& reload_completed"
3731 [(parallel [(set (reg:CC_NOOV CC_REG)
3732 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3734 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3736 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3737 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3738 "operands[3] = gen_lowpart (SImode, operands[2]);
3739 operands[4] = gen_highpart (SImode, operands[2]);
3740 operands[5] = gen_lowpart (SImode, operands[0]);
3741 operands[6] = gen_highpart (SImode, operands[0]);"
3742 [(set_attr "length" "2")])
3744 (define_insn "*adddi3_sp64"
3745 [(set (match_operand:DI 0 "register_operand" "=r,r")
3746 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3747 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3753 (define_insn "addsi3"
3754 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3755 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3756 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3761 fpadd32s\t%1, %2, %0"
3762 [(set_attr "type" "*,*,fga")
3763 (set_attr "fptype" "*,*,single")])
3765 (define_insn "*cmp_cc_plus"
3766 [(set (reg:CC_NOOV CC_REG)
3767 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3768 (match_operand:SI 1 "arith_operand" "rI"))
3771 "addcc\t%0, %1, %%g0"
3772 [(set_attr "type" "compare")])
3774 (define_insn "*cmp_ccx_plus"
3775 [(set (reg:CCX_NOOV CC_REG)
3776 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3777 (match_operand:DI 1 "arith_operand" "rI"))
3780 "addcc\t%0, %1, %%g0"
3781 [(set_attr "type" "compare")])
3783 (define_insn "*cmp_cc_plus_set"
3784 [(set (reg:CC_NOOV CC_REG)
3785 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3786 (match_operand:SI 2 "arith_operand" "rI"))
3788 (set (match_operand:SI 0 "register_operand" "=r")
3789 (plus:SI (match_dup 1) (match_dup 2)))]
3792 [(set_attr "type" "compare")])
3794 (define_insn "*cmp_ccx_plus_set"
3795 [(set (reg:CCX_NOOV CC_REG)
3796 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3797 (match_operand:DI 2 "arith_operand" "rI"))
3799 (set (match_operand:DI 0 "register_operand" "=r")
3800 (plus:DI (match_dup 1) (match_dup 2)))]
3803 [(set_attr "type" "compare")])
3805 (define_expand "subdi3"
3806 [(set (match_operand:DI 0 "register_operand" "")
3807 (minus:DI (match_operand:DI 1 "register_operand" "")
3808 (match_operand:DI 2 "arith_double_add_operand" "")))]
3811 if (! TARGET_ARCH64)
3813 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3814 gen_rtx_SET (VOIDmode, operands[0],
3815 gen_rtx_MINUS (DImode, operands[1],
3817 gen_rtx_CLOBBER (VOIDmode,
3818 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3823 (define_insn_and_split "*subdi3_insn_sp32"
3824 [(set (match_operand:DI 0 "register_operand" "=r")
3825 (minus:DI (match_operand:DI 1 "register_operand" "r")
3826 (match_operand:DI 2 "arith_double_operand" "rHI")))
3827 (clobber (reg:CC CC_REG))]
3830 "&& reload_completed"
3831 [(parallel [(set (reg:CC_NOOV CC_REG)
3832 (compare:CC_NOOV (minus:SI (match_dup 4)
3836 (minus:SI (match_dup 4) (match_dup 5)))])
3838 (minus:SI (minus:SI (match_dup 7)
3840 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3842 operands[3] = gen_lowpart (SImode, operands[0]);
3843 operands[4] = gen_lowpart (SImode, operands[1]);
3844 operands[5] = gen_lowpart (SImode, operands[2]);
3845 operands[6] = gen_highpart (SImode, operands[0]);
3846 operands[7] = gen_highpart (SImode, operands[1]);
3847 #if HOST_BITS_PER_WIDE_INT == 32
3848 if (GET_CODE (operands[2]) == CONST_INT)
3850 if (INTVAL (operands[2]) < 0)
3851 operands[8] = constm1_rtx;
3853 operands[8] = const0_rtx;
3857 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3859 [(set_attr "length" "2")])
3861 ;; LTU here means "carry set"
3863 [(set (match_operand:SI 0 "register_operand" "=r")
3864 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3865 (match_operand:SI 2 "arith_operand" "rI"))
3866 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3869 [(set_attr "type" "ialuX")])
3871 (define_insn "*subx_extend_sp64"
3872 [(set (match_operand:DI 0 "register_operand" "=r")
3873 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3874 (match_operand:SI 2 "arith_operand" "rI"))
3875 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3878 [(set_attr "type" "ialuX")])
3880 (define_insn_and_split "*subx_extend"
3881 [(set (match_operand:DI 0 "register_operand" "=r")
3882 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3883 (match_operand:SI 2 "arith_operand" "rI"))
3884 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3887 "&& reload_completed"
3888 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3889 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3890 (set (match_dup 4) (const_int 0))]
3891 "operands[3] = gen_lowpart (SImode, operands[0]);
3892 operands[4] = gen_highpart (SImode, operands[0]);"
3893 [(set_attr "length" "2")])
3895 (define_insn_and_split "*subdi3_extend_sp32"
3896 [(set (match_operand:DI 0 "register_operand" "=r")
3897 (minus:DI (match_operand:DI 1 "register_operand" "r")
3898 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3899 (clobber (reg:CC CC_REG))]
3902 "&& reload_completed"
3903 [(parallel [(set (reg:CC_NOOV CC_REG)
3904 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3906 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3908 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3909 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3910 "operands[3] = gen_lowpart (SImode, operands[1]);
3911 operands[4] = gen_highpart (SImode, operands[1]);
3912 operands[5] = gen_lowpart (SImode, operands[0]);
3913 operands[6] = gen_highpart (SImode, operands[0]);"
3914 [(set_attr "length" "2")])
3916 (define_insn "*subdi3_sp64"
3917 [(set (match_operand:DI 0 "register_operand" "=r,r")
3918 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3919 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3925 (define_insn "subsi3"
3926 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3927 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3928 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3933 fpsub32s\t%1, %2, %0"
3934 [(set_attr "type" "*,*,fga")
3935 (set_attr "fptype" "*,*,single")])
3937 (define_insn "*cmp_minus_cc"
3938 [(set (reg:CC_NOOV CC_REG)
3939 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3940 (match_operand:SI 1 "arith_operand" "rI"))
3943 "subcc\t%r0, %1, %%g0"
3944 [(set_attr "type" "compare")])
3946 (define_insn "*cmp_minus_ccx"
3947 [(set (reg:CCX_NOOV CC_REG)
3948 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3949 (match_operand:DI 1 "arith_operand" "rI"))
3952 "subcc\t%0, %1, %%g0"
3953 [(set_attr "type" "compare")])
3955 (define_insn "cmp_minus_cc_set"
3956 [(set (reg:CC_NOOV CC_REG)
3957 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3958 (match_operand:SI 2 "arith_operand" "rI"))
3960 (set (match_operand:SI 0 "register_operand" "=r")
3961 (minus:SI (match_dup 1) (match_dup 2)))]
3963 "subcc\t%r1, %2, %0"
3964 [(set_attr "type" "compare")])
3966 (define_insn "*cmp_minus_ccx_set"
3967 [(set (reg:CCX_NOOV CC_REG)
3968 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3969 (match_operand:DI 2 "arith_operand" "rI"))
3971 (set (match_operand:DI 0 "register_operand" "=r")
3972 (minus:DI (match_dup 1) (match_dup 2)))]
3975 [(set_attr "type" "compare")])
3978 ;; Integer multiply/divide instructions.
3980 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3981 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3983 (define_insn "mulsi3"
3984 [(set (match_operand:SI 0 "register_operand" "=r")
3985 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3986 (match_operand:SI 2 "arith_operand" "rI")))]
3989 [(set_attr "type" "imul")])
3991 (define_expand "muldi3"
3992 [(set (match_operand:DI 0 "register_operand" "")
3993 (mult:DI (match_operand:DI 1 "arith_operand" "")
3994 (match_operand:DI 2 "arith_operand" "")))]
3995 "TARGET_ARCH64 || TARGET_V8PLUS"
3999 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4004 (define_insn "*muldi3_sp64"
4005 [(set (match_operand:DI 0 "register_operand" "=r")
4006 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4007 (match_operand:DI 2 "arith_operand" "rI")))]
4010 [(set_attr "type" "imul")])
4012 ;; V8plus wide multiply.
4014 (define_insn "muldi3_v8plus"
4015 [(set (match_operand:DI 0 "register_operand" "=r,h")
4016 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4017 (match_operand:DI 2 "arith_operand" "rI,rI")))
4018 (clobber (match_scratch:SI 3 "=&h,X"))
4019 (clobber (match_scratch:SI 4 "=&h,X"))]
4021 "* return output_v8plus_mult (insn, operands, \"mulx\");"
4022 [(set_attr "type" "multi")
4023 (set_attr "length" "9,8")])
4025 (define_insn "*cmp_mul_set"
4026 [(set (reg:CC CC_REG)
4027 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4028 (match_operand:SI 2 "arith_operand" "rI"))
4030 (set (match_operand:SI 0 "register_operand" "=r")
4031 (mult:SI (match_dup 1) (match_dup 2)))]
4032 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4033 "smulcc\t%1, %2, %0"
4034 [(set_attr "type" "imul")])
4036 (define_expand "mulsidi3"
4037 [(set (match_operand:DI 0 "register_operand" "")
4038 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4039 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4042 if (CONSTANT_P (operands[2]))
4045 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4047 else if (TARGET_ARCH32)
4048 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4051 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4057 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4062 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4063 ;; registers can hold 64-bit values in the V8plus environment.
4065 (define_insn "mulsidi3_v8plus"
4066 [(set (match_operand:DI 0 "register_operand" "=h,r")
4067 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4068 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4069 (clobber (match_scratch:SI 3 "=X,&h"))]
4072 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4073 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4074 [(set_attr "type" "multi")
4075 (set_attr "length" "2,3")])
4078 (define_insn "const_mulsidi3_v8plus"
4079 [(set (match_operand:DI 0 "register_operand" "=h,r")
4080 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4081 (match_operand:DI 2 "small_int_operand" "I,I")))
4082 (clobber (match_scratch:SI 3 "=X,&h"))]
4085 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4086 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4087 [(set_attr "type" "multi")
4088 (set_attr "length" "2,3")])
4091 (define_insn "*mulsidi3_sp32"
4092 [(set (match_operand:DI 0 "register_operand" "=r")
4093 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4094 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4097 return TARGET_SPARCLET
4098 ? "smuld\t%1, %2, %L0"
4099 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4102 (if_then_else (eq_attr "isa" "sparclet")
4103 (const_string "imul") (const_string "multi")))
4104 (set (attr "length")
4105 (if_then_else (eq_attr "isa" "sparclet")
4106 (const_int 1) (const_int 2)))])
4108 (define_insn "*mulsidi3_sp64"
4109 [(set (match_operand:DI 0 "register_operand" "=r")
4110 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4111 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4112 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4114 [(set_attr "type" "imul")])
4116 ;; Extra pattern, because sign_extend of a constant isn't valid.
4119 (define_insn "const_mulsidi3_sp32"
4120 [(set (match_operand:DI 0 "register_operand" "=r")
4121 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4122 (match_operand:DI 2 "small_int_operand" "I")))]
4125 return TARGET_SPARCLET
4126 ? "smuld\t%1, %2, %L0"
4127 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4130 (if_then_else (eq_attr "isa" "sparclet")
4131 (const_string "imul") (const_string "multi")))
4132 (set (attr "length")
4133 (if_then_else (eq_attr "isa" "sparclet")
4134 (const_int 1) (const_int 2)))])
4136 (define_insn "const_mulsidi3_sp64"
4137 [(set (match_operand:DI 0 "register_operand" "=r")
4138 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4139 (match_operand:DI 2 "small_int_operand" "I")))]
4140 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4142 [(set_attr "type" "imul")])
4144 (define_expand "smulsi3_highpart"
4145 [(set (match_operand:SI 0 "register_operand" "")
4147 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4148 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4150 "TARGET_HARD_MUL && TARGET_ARCH32"
4152 if (CONSTANT_P (operands[2]))
4156 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4162 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4167 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4168 operands[2], GEN_INT (32)));
4174 (define_insn "smulsi3_highpart_v8plus"
4175 [(set (match_operand:SI 0 "register_operand" "=h,r")
4177 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4178 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4179 (match_operand:SI 3 "small_int_operand" "I,I"))))
4180 (clobber (match_scratch:SI 4 "=X,&h"))]
4183 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4184 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4185 [(set_attr "type" "multi")
4186 (set_attr "length" "2")])
4188 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4191 [(set (match_operand:SI 0 "register_operand" "=h,r")
4194 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4195 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4196 (match_operand:SI 3 "small_int_operand" "I,I"))
4198 (clobber (match_scratch:SI 4 "=X,&h"))]
4201 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4202 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4203 [(set_attr "type" "multi")
4204 (set_attr "length" "2")])
4207 (define_insn "const_smulsi3_highpart_v8plus"
4208 [(set (match_operand:SI 0 "register_operand" "=h,r")
4210 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4211 (match_operand:DI 2 "small_int_operand" "I,I"))
4212 (match_operand:SI 3 "small_int_operand" "I,I"))))
4213 (clobber (match_scratch:SI 4 "=X,&h"))]
4216 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4217 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4218 [(set_attr "type" "multi")
4219 (set_attr "length" "2")])
4222 (define_insn "*smulsi3_highpart_sp32"
4223 [(set (match_operand:SI 0 "register_operand" "=r")
4225 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4226 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4229 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4230 [(set_attr "type" "multi")
4231 (set_attr "length" "2")])
4234 (define_insn "const_smulsi3_highpart"
4235 [(set (match_operand:SI 0 "register_operand" "=r")
4237 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4238 (match_operand:DI 2 "small_int_operand" "i"))
4241 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4242 [(set_attr "type" "multi")
4243 (set_attr "length" "2")])
4245 (define_expand "umulsidi3"
4246 [(set (match_operand:DI 0 "register_operand" "")
4247 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4248 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4251 if (CONSTANT_P (operands[2]))
4254 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4256 else if (TARGET_ARCH32)
4257 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4260 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4266 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4272 (define_insn "umulsidi3_v8plus"
4273 [(set (match_operand:DI 0 "register_operand" "=h,r")
4274 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4275 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4276 (clobber (match_scratch:SI 3 "=X,&h"))]
4279 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4280 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4281 [(set_attr "type" "multi")
4282 (set_attr "length" "2,3")])
4285 (define_insn "*umulsidi3_sp32"
4286 [(set (match_operand:DI 0 "register_operand" "=r")
4287 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4288 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4291 return TARGET_SPARCLET
4292 ? "umuld\t%1, %2, %L0"
4293 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4296 (if_then_else (eq_attr "isa" "sparclet")
4297 (const_string "imul") (const_string "multi")))
4298 (set (attr "length")
4299 (if_then_else (eq_attr "isa" "sparclet")
4300 (const_int 1) (const_int 2)))])
4302 (define_insn "*umulsidi3_sp64"
4303 [(set (match_operand:DI 0 "register_operand" "=r")
4304 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4305 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4306 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4308 [(set_attr "type" "imul")])
4310 ;; Extra pattern, because sign_extend of a constant isn't valid.
4313 (define_insn "const_umulsidi3_sp32"
4314 [(set (match_operand:DI 0 "register_operand" "=r")
4315 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4316 (match_operand:DI 2 "uns_small_int_operand" "")))]
4319 return TARGET_SPARCLET
4320 ? "umuld\t%1, %s2, %L0"
4321 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4324 (if_then_else (eq_attr "isa" "sparclet")
4325 (const_string "imul") (const_string "multi")))
4326 (set (attr "length")
4327 (if_then_else (eq_attr "isa" "sparclet")
4328 (const_int 1) (const_int 2)))])
4330 (define_insn "const_umulsidi3_sp64"
4331 [(set (match_operand:DI 0 "register_operand" "=r")
4332 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4333 (match_operand:DI 2 "uns_small_int_operand" "")))]
4334 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4336 [(set_attr "type" "imul")])
4339 (define_insn "const_umulsidi3_v8plus"
4340 [(set (match_operand:DI 0 "register_operand" "=h,r")
4341 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4342 (match_operand:DI 2 "uns_small_int_operand" "")))
4343 (clobber (match_scratch:SI 3 "=X,h"))]
4346 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4347 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4348 [(set_attr "type" "multi")
4349 (set_attr "length" "2,3")])
4351 (define_expand "umulsi3_highpart"
4352 [(set (match_operand:SI 0 "register_operand" "")
4354 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4355 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4357 "TARGET_HARD_MUL && TARGET_ARCH32"
4359 if (CONSTANT_P (operands[2]))
4363 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4369 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4374 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4375 operands[2], GEN_INT (32)));
4381 (define_insn "umulsi3_highpart_v8plus"
4382 [(set (match_operand:SI 0 "register_operand" "=h,r")
4384 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4385 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4386 (match_operand:SI 3 "small_int_operand" "I,I"))))
4387 (clobber (match_scratch:SI 4 "=X,h"))]
4390 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4391 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4392 [(set_attr "type" "multi")
4393 (set_attr "length" "2")])
4396 (define_insn "const_umulsi3_highpart_v8plus"
4397 [(set (match_operand:SI 0 "register_operand" "=h,r")
4399 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4400 (match_operand:DI 2 "uns_small_int_operand" ""))
4401 (match_operand:SI 3 "small_int_operand" "I,I"))))
4402 (clobber (match_scratch:SI 4 "=X,h"))]
4405 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4406 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4407 [(set_attr "type" "multi")
4408 (set_attr "length" "2")])
4411 (define_insn "*umulsi3_highpart_sp32"
4412 [(set (match_operand:SI 0 "register_operand" "=r")
4414 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4415 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4418 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4419 [(set_attr "type" "multi")
4420 (set_attr "length" "2")])
4423 (define_insn "const_umulsi3_highpart"
4424 [(set (match_operand:SI 0 "register_operand" "=r")
4426 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4427 (match_operand:DI 2 "uns_small_int_operand" ""))
4430 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4431 [(set_attr "type" "multi")
4432 (set_attr "length" "2")])
4434 (define_expand "divsi3"
4435 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4436 (div:SI (match_operand:SI 1 "register_operand" "")
4437 (match_operand:SI 2 "input_operand" "")))
4438 (clobber (match_scratch:SI 3 ""))])]
4439 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4443 operands[3] = gen_reg_rtx(SImode);
4444 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4445 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4451 ;; The V8 architecture specifies that there must be at least 3 instructions
4452 ;; between a write to the Y register and a use of it for correct results.
4453 ;; We try to fill one of them with a simple constant or a memory load.
4455 (define_insn "divsi3_sp32"
4456 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4457 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4458 (match_operand:SI 2 "input_operand" "rI,K,m")))
4459 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4460 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4462 output_asm_insn ("sra\t%1, 31, %3", operands);
4463 output_asm_insn ("wr\t%3, 0, %%y", operands);
4465 switch (which_alternative)
4469 return "sdiv\t%1, %2, %0";
4471 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4474 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4476 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4479 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4481 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4486 [(set_attr "type" "multi")
4487 (set (attr "length")
4488 (if_then_else (eq_attr "isa" "v9")
4489 (const_int 4) (const_int 6)))])
4491 (define_insn "divsi3_sp64"
4492 [(set (match_operand:SI 0 "register_operand" "=r")
4493 (div:SI (match_operand:SI 1 "register_operand" "r")
4494 (match_operand:SI 2 "input_operand" "rI")))
4495 (use (match_operand:SI 3 "register_operand" "r"))]
4496 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4497 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4498 [(set_attr "type" "multi")
4499 (set_attr "length" "2")])
4501 (define_insn "divdi3"
4502 [(set (match_operand:DI 0 "register_operand" "=r")
4503 (div:DI (match_operand:DI 1 "register_operand" "r")
4504 (match_operand:DI 2 "arith_operand" "rI")))]
4507 [(set_attr "type" "idiv")])
4509 (define_insn "*cmp_sdiv_cc_set"
4510 [(set (reg:CC CC_REG)
4511 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4512 (match_operand:SI 2 "arith_operand" "rI"))
4514 (set (match_operand:SI 0 "register_operand" "=r")
4515 (div:SI (match_dup 1) (match_dup 2)))
4516 (clobber (match_scratch:SI 3 "=&r"))]
4517 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4519 output_asm_insn ("sra\t%1, 31, %3", operands);
4520 output_asm_insn ("wr\t%3, 0, %%y", operands);
4523 return "sdivcc\t%1, %2, %0";
4525 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4527 [(set_attr "type" "multi")
4528 (set (attr "length")
4529 (if_then_else (eq_attr "isa" "v9")
4530 (const_int 3) (const_int 6)))])
4533 (define_expand "udivsi3"
4534 [(set (match_operand:SI 0 "register_operand" "")
4535 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4536 (match_operand:SI 2 "input_operand" "")))]
4537 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4540 ;; The V8 architecture specifies that there must be at least 3 instructions
4541 ;; between a write to the Y register and a use of it for correct results.
4542 ;; We try to fill one of them with a simple constant or a memory load.
4544 (define_insn "udivsi3_sp32"
4545 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4546 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4547 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4548 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4550 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4552 switch (which_alternative)
4556 return "udiv\t%1, %2, %0";
4558 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4561 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4563 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4566 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4568 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4571 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4573 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4578 [(set_attr "type" "multi")
4579 (set (attr "length")
4580 (if_then_else (eq_attr "isa" "v9")
4581 (const_int 3) (const_int 5)))])
4583 (define_insn "udivsi3_sp64"
4584 [(set (match_operand:SI 0 "register_operand" "=r")
4585 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4586 (match_operand:SI 2 "input_operand" "rI")))]
4587 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4588 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4589 [(set_attr "type" "multi")
4590 (set_attr "length" "2")])
4592 (define_insn "udivdi3"
4593 [(set (match_operand:DI 0 "register_operand" "=r")
4594 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4595 (match_operand:DI 2 "arith_operand" "rI")))]
4598 [(set_attr "type" "idiv")])
4600 (define_insn "*cmp_udiv_cc_set"
4601 [(set (reg:CC CC_REG)
4602 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4603 (match_operand:SI 2 "arith_operand" "rI"))
4605 (set (match_operand:SI 0 "register_operand" "=r")
4606 (udiv:SI (match_dup 1) (match_dup 2)))]
4607 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4609 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4612 return "udivcc\t%1, %2, %0";
4614 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4616 [(set_attr "type" "multi")
4617 (set (attr "length")
4618 (if_then_else (eq_attr "isa" "v9")
4619 (const_int 2) (const_int 5)))])
4621 ; sparclet multiply/accumulate insns
4623 (define_insn "*smacsi"
4624 [(set (match_operand:SI 0 "register_operand" "=r")
4625 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4626 (match_operand:SI 2 "arith_operand" "rI"))
4627 (match_operand:SI 3 "register_operand" "0")))]
4630 [(set_attr "type" "imul")])
4632 (define_insn "*smacdi"
4633 [(set (match_operand:DI 0 "register_operand" "=r")
4634 (plus:DI (mult:DI (sign_extend:DI
4635 (match_operand:SI 1 "register_operand" "%r"))
4637 (match_operand:SI 2 "register_operand" "r")))
4638 (match_operand:DI 3 "register_operand" "0")))]
4640 "smacd\t%1, %2, %L0"
4641 [(set_attr "type" "imul")])
4643 (define_insn "*umacdi"
4644 [(set (match_operand:DI 0 "register_operand" "=r")
4645 (plus:DI (mult:DI (zero_extend:DI
4646 (match_operand:SI 1 "register_operand" "%r"))
4648 (match_operand:SI 2 "register_operand" "r")))
4649 (match_operand:DI 3 "register_operand" "0")))]
4651 "umacd\t%1, %2, %L0"
4652 [(set_attr "type" "imul")])
4655 ;; Boolean instructions.
4657 ;; We define DImode `and' so with DImode `not' we can get
4658 ;; DImode `andn'. Other combinations are possible.
4660 (define_expand "and<V64I:mode>3"
4661 [(set (match_operand:V64I 0 "register_operand" "")
4662 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4663 (match_operand:V64I 2 "arith_double_operand" "")))]
4667 (define_insn "*and<V64I:mode>3_sp32"
4668 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4669 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4670 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4675 [(set_attr "type" "*,fga")
4676 (set_attr "length" "2,*")
4677 (set_attr "fptype" "*,double")])
4679 (define_insn "*and<V64I:mode>3_sp64"
4680 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4681 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4682 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4687 [(set_attr "type" "*,fga")
4688 (set_attr "fptype" "*,double")])
4690 (define_insn "and<V32I:mode>3"
4691 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4692 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4693 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4698 [(set_attr "type" "*,fga")
4699 (set_attr "fptype" "*,single")])
4702 [(set (match_operand:SI 0 "register_operand" "")
4703 (and:SI (match_operand:SI 1 "register_operand" "")
4704 (match_operand:SI 2 "const_compl_high_operand" "")))
4705 (clobber (match_operand:SI 3 "register_operand" ""))]
4707 [(set (match_dup 3) (match_dup 4))
4708 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4710 operands[4] = GEN_INT (~INTVAL (operands[2]));
4713 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4714 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4715 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4716 (match_operand:V64I 2 "register_operand" "r,b")))]
4720 fandnot1\t%1, %2, %0"
4721 "&& reload_completed
4722 && ((GET_CODE (operands[0]) == REG
4723 && REGNO (operands[0]) < 32)
4724 || (GET_CODE (operands[0]) == SUBREG
4725 && GET_CODE (SUBREG_REG (operands[0])) == REG
4726 && REGNO (SUBREG_REG (operands[0])) < 32))"
4727 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4728 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4729 "operands[3] = gen_highpart (SImode, operands[0]);
4730 operands[4] = gen_highpart (SImode, operands[1]);
4731 operands[5] = gen_highpart (SImode, operands[2]);
4732 operands[6] = gen_lowpart (SImode, operands[0]);
4733 operands[7] = gen_lowpart (SImode, operands[1]);
4734 operands[8] = gen_lowpart (SImode, operands[2]);"
4735 [(set_attr "type" "*,fga")
4736 (set_attr "length" "2,*")
4737 (set_attr "fptype" "*,double")])
4739 (define_insn "*and_not_<V64I:mode>_sp64"
4740 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4741 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4742 (match_operand:V64I 2 "register_operand" "r,b")))]
4746 fandnot1\t%1, %2, %0"
4747 [(set_attr "type" "*,fga")
4748 (set_attr "fptype" "*,double")])
4750 (define_insn "*and_not_<V32I:mode>"
4751 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4752 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4753 (match_operand:V32I 2 "register_operand" "r,d")))]
4757 fandnot1s\t%1, %2, %0"
4758 [(set_attr "type" "*,fga")
4759 (set_attr "fptype" "*,single")])
4761 (define_expand "ior<V64I:mode>3"
4762 [(set (match_operand:V64I 0 "register_operand" "")
4763 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4764 (match_operand:V64I 2 "arith_double_operand" "")))]
4768 (define_insn "*ior<V64I:mode>3_sp32"
4769 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4770 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4771 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4776 [(set_attr "type" "*,fga")
4777 (set_attr "length" "2,*")
4778 (set_attr "fptype" "*,double")])
4780 (define_insn "*ior<V64I:mode>3_sp64"
4781 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4782 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4783 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4788 [(set_attr "type" "*,fga")
4789 (set_attr "fptype" "*,double")])
4791 (define_insn "ior<V32I:mode>3"
4792 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4793 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4794 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4799 [(set_attr "type" "*,fga")
4800 (set_attr "fptype" "*,single")])
4803 [(set (match_operand:SI 0 "register_operand" "")
4804 (ior:SI (match_operand:SI 1 "register_operand" "")
4805 (match_operand:SI 2 "const_compl_high_operand" "")))
4806 (clobber (match_operand:SI 3 "register_operand" ""))]
4808 [(set (match_dup 3) (match_dup 4))
4809 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4811 operands[4] = GEN_INT (~INTVAL (operands[2]));
4814 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4815 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4816 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4817 (match_operand:V64I 2 "register_operand" "r,b")))]
4821 fornot1\t%1, %2, %0"
4822 "&& reload_completed
4823 && ((GET_CODE (operands[0]) == REG
4824 && REGNO (operands[0]) < 32)
4825 || (GET_CODE (operands[0]) == SUBREG
4826 && GET_CODE (SUBREG_REG (operands[0])) == REG
4827 && REGNO (SUBREG_REG (operands[0])) < 32))"
4828 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4829 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4830 "operands[3] = gen_highpart (SImode, operands[0]);
4831 operands[4] = gen_highpart (SImode, operands[1]);
4832 operands[5] = gen_highpart (SImode, operands[2]);
4833 operands[6] = gen_lowpart (SImode, operands[0]);
4834 operands[7] = gen_lowpart (SImode, operands[1]);
4835 operands[8] = gen_lowpart (SImode, operands[2]);"
4836 [(set_attr "type" "*,fga")
4837 (set_attr "length" "2,*")
4838 (set_attr "fptype" "*,double")])
4840 (define_insn "*or_not_<V64I:mode>_sp64"
4841 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4842 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4843 (match_operand:V64I 2 "register_operand" "r,b")))]
4847 fornot1\t%1, %2, %0"
4848 [(set_attr "type" "*,fga")
4849 (set_attr "fptype" "*,double")])
4851 (define_insn "*or_not_<V32I:mode>"
4852 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4853 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4854 (match_operand:V32I 2 "register_operand" "r,d")))]
4858 fornot1s\t%1, %2, %0"
4859 [(set_attr "type" "*,fga")
4860 (set_attr "fptype" "*,single")])
4862 (define_expand "xor<V64I:mode>3"
4863 [(set (match_operand:V64I 0 "register_operand" "")
4864 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4865 (match_operand:V64I 2 "arith_double_operand" "")))]
4869 (define_insn "*xor<V64I:mode>3_sp32"
4870 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4871 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4872 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4877 [(set_attr "type" "*,fga")
4878 (set_attr "length" "2,*")
4879 (set_attr "fptype" "*,double")])
4881 (define_insn "*xor<V64I:mode>3_sp64"
4882 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4883 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4884 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4889 [(set_attr "type" "*,fga")
4890 (set_attr "fptype" "*,double")])
4892 (define_insn "xor<V32I:mode>3"
4893 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4894 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4895 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4900 [(set_attr "type" "*,fga")
4901 (set_attr "fptype" "*,single")])
4904 [(set (match_operand:SI 0 "register_operand" "")
4905 (xor:SI (match_operand:SI 1 "register_operand" "")
4906 (match_operand:SI 2 "const_compl_high_operand" "")))
4907 (clobber (match_operand:SI 3 "register_operand" ""))]
4909 [(set (match_dup 3) (match_dup 4))
4910 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4912 operands[4] = GEN_INT (~INTVAL (operands[2]));
4916 [(set (match_operand:SI 0 "register_operand" "")
4917 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4918 (match_operand:SI 2 "const_compl_high_operand" ""))))
4919 (clobber (match_operand:SI 3 "register_operand" ""))]
4921 [(set (match_dup 3) (match_dup 4))
4922 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4924 operands[4] = GEN_INT (~INTVAL (operands[2]));
4927 ;; Split DImode logical operations requiring two instructions.
4929 [(set (match_operand:V64I 0 "register_operand" "")
4930 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4931 [(match_operand:V64I 2 "register_operand" "")
4932 (match_operand:V64I 3 "arith_double_operand" "")]))]
4935 && ((GET_CODE (operands[0]) == REG
4936 && REGNO (operands[0]) < 32)
4937 || (GET_CODE (operands[0]) == SUBREG
4938 && GET_CODE (SUBREG_REG (operands[0])) == REG
4939 && REGNO (SUBREG_REG (operands[0])) < 32))"
4940 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4941 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4943 operands[4] = gen_highpart (SImode, operands[0]);
4944 operands[5] = gen_lowpart (SImode, operands[0]);
4945 operands[6] = gen_highpart (SImode, operands[2]);
4946 operands[7] = gen_lowpart (SImode, operands[2]);
4947 #if HOST_BITS_PER_WIDE_INT == 32
4948 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4950 if (INTVAL (operands[3]) < 0)
4951 operands[8] = constm1_rtx;
4953 operands[8] = const0_rtx;
4957 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4958 operands[9] = gen_lowpart (SImode, operands[3]);
4961 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4962 ;; Combine now canonicalizes to the rightmost expression.
4963 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4964 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4965 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4966 (match_operand:V64I 2 "register_operand" "r,b"))))]
4971 "&& reload_completed
4972 && ((GET_CODE (operands[0]) == REG
4973 && REGNO (operands[0]) < 32)
4974 || (GET_CODE (operands[0]) == SUBREG
4975 && GET_CODE (SUBREG_REG (operands[0])) == REG
4976 && REGNO (SUBREG_REG (operands[0])) < 32))"
4977 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4978 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4979 "operands[3] = gen_highpart (SImode, operands[0]);
4980 operands[4] = gen_highpart (SImode, operands[1]);
4981 operands[5] = gen_highpart (SImode, operands[2]);
4982 operands[6] = gen_lowpart (SImode, operands[0]);
4983 operands[7] = gen_lowpart (SImode, operands[1]);
4984 operands[8] = gen_lowpart (SImode, operands[2]);"
4985 [(set_attr "type" "*,fga")
4986 (set_attr "length" "2,*")
4987 (set_attr "fptype" "*,double")])
4989 (define_insn "*xor_not_<V64I:mode>_sp64"
4990 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4991 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4992 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4997 [(set_attr "type" "*,fga")
4998 (set_attr "fptype" "*,double")])
5000 (define_insn "*xor_not_<V32I:mode>"
5001 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5002 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5003 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5008 [(set_attr "type" "*,fga")
5009 (set_attr "fptype" "*,single")])
5011 ;; These correspond to the above in the case where we also (or only)
5012 ;; want to set the condition code.
5014 (define_insn "*cmp_cc_arith_op"
5015 [(set (reg:CC CC_REG)
5017 (match_operator:SI 2 "cc_arith_operator"
5018 [(match_operand:SI 0 "arith_operand" "%r")
5019 (match_operand:SI 1 "arith_operand" "rI")])
5022 "%A2cc\t%0, %1, %%g0"
5023 [(set_attr "type" "compare")])
5025 (define_insn "*cmp_ccx_arith_op"
5026 [(set (reg:CCX CC_REG)
5028 (match_operator:DI 2 "cc_arith_operator"
5029 [(match_operand:DI 0 "arith_operand" "%r")
5030 (match_operand:DI 1 "arith_operand" "rI")])
5033 "%A2cc\t%0, %1, %%g0"
5034 [(set_attr "type" "compare")])
5036 (define_insn "*cmp_cc_arith_op_set"
5037 [(set (reg:CC CC_REG)
5039 (match_operator:SI 3 "cc_arith_operator"
5040 [(match_operand:SI 1 "arith_operand" "%r")
5041 (match_operand:SI 2 "arith_operand" "rI")])
5043 (set (match_operand:SI 0 "register_operand" "=r")
5044 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5045 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5047 [(set_attr "type" "compare")])
5049 (define_insn "*cmp_ccx_arith_op_set"
5050 [(set (reg:CCX CC_REG)
5052 (match_operator:DI 3 "cc_arith_operator"
5053 [(match_operand:DI 1 "arith_operand" "%r")
5054 (match_operand:DI 2 "arith_operand" "rI")])
5056 (set (match_operand:DI 0 "register_operand" "=r")
5057 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5058 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5060 [(set_attr "type" "compare")])
5062 (define_insn "*cmp_cc_xor_not"
5063 [(set (reg:CC CC_REG)
5065 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5066 (match_operand:SI 1 "arith_operand" "rI")))
5069 "xnorcc\t%r0, %1, %%g0"
5070 [(set_attr "type" "compare")])
5072 (define_insn "*cmp_ccx_xor_not"
5073 [(set (reg:CCX CC_REG)
5075 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5076 (match_operand:DI 1 "arith_operand" "rI")))
5079 "xnorcc\t%r0, %1, %%g0"
5080 [(set_attr "type" "compare")])
5082 (define_insn "*cmp_cc_xor_not_set"
5083 [(set (reg:CC CC_REG)
5085 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5086 (match_operand:SI 2 "arith_operand" "rI")))
5088 (set (match_operand:SI 0 "register_operand" "=r")
5089 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5091 "xnorcc\t%r1, %2, %0"
5092 [(set_attr "type" "compare")])
5094 (define_insn "*cmp_ccx_xor_not_set"
5095 [(set (reg:CCX CC_REG)
5097 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5098 (match_operand:DI 2 "arith_operand" "rI")))
5100 (set (match_operand:DI 0 "register_operand" "=r")
5101 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5103 "xnorcc\t%r1, %2, %0"
5104 [(set_attr "type" "compare")])
5106 (define_insn "*cmp_cc_arith_op_not"
5107 [(set (reg:CC CC_REG)
5109 (match_operator:SI 2 "cc_arith_not_operator"
5110 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5111 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5114 "%B2cc\t%r1, %0, %%g0"
5115 [(set_attr "type" "compare")])
5117 (define_insn "*cmp_ccx_arith_op_not"
5118 [(set (reg:CCX CC_REG)
5120 (match_operator:DI 2 "cc_arith_not_operator"
5121 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5122 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5125 "%B2cc\t%r1, %0, %%g0"
5126 [(set_attr "type" "compare")])
5128 (define_insn "*cmp_cc_arith_op_not_set"
5129 [(set (reg:CC CC_REG)
5131 (match_operator:SI 3 "cc_arith_not_operator"
5132 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5133 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5135 (set (match_operand:SI 0 "register_operand" "=r")
5136 (match_operator:SI 4 "cc_arith_not_operator"
5137 [(not:SI (match_dup 1)) (match_dup 2)]))]
5138 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5139 "%B3cc\t%r2, %1, %0"
5140 [(set_attr "type" "compare")])
5142 (define_insn "*cmp_ccx_arith_op_not_set"
5143 [(set (reg:CCX CC_REG)
5145 (match_operator:DI 3 "cc_arith_not_operator"
5146 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5147 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5149 (set (match_operand:DI 0 "register_operand" "=r")
5150 (match_operator:DI 4 "cc_arith_not_operator"
5151 [(not:DI (match_dup 1)) (match_dup 2)]))]
5152 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5153 "%B3cc\t%r2, %1, %0"
5154 [(set_attr "type" "compare")])
5156 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5157 ;; does not know how to make it work for constants.
5159 (define_expand "negdi2"
5160 [(set (match_operand:DI 0 "register_operand" "=r")
5161 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5164 if (! TARGET_ARCH64)
5166 emit_insn (gen_rtx_PARALLEL
5169 gen_rtx_SET (VOIDmode, operand0,
5170 gen_rtx_NEG (DImode, operand1)),
5171 gen_rtx_CLOBBER (VOIDmode,
5172 gen_rtx_REG (CCmode,
5178 (define_insn_and_split "*negdi2_sp32"
5179 [(set (match_operand:DI 0 "register_operand" "=r")
5180 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5181 (clobber (reg:CC CC_REG))]
5184 "&& reload_completed"
5185 [(parallel [(set (reg:CC_NOOV CC_REG)
5186 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5188 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5189 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5190 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5191 "operands[2] = gen_highpart (SImode, operands[0]);
5192 operands[3] = gen_highpart (SImode, operands[1]);
5193 operands[4] = gen_lowpart (SImode, operands[0]);
5194 operands[5] = gen_lowpart (SImode, operands[1]);"
5195 [(set_attr "length" "2")])
5197 (define_insn "*negdi2_sp64"
5198 [(set (match_operand:DI 0 "register_operand" "=r")
5199 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5201 "sub\t%%g0, %1, %0")
5203 (define_insn "negsi2"
5204 [(set (match_operand:SI 0 "register_operand" "=r")
5205 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5207 "sub\t%%g0, %1, %0")
5209 (define_insn "*cmp_cc_neg"
5210 [(set (reg:CC_NOOV CC_REG)
5211 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5214 "subcc\t%%g0, %0, %%g0"
5215 [(set_attr "type" "compare")])
5217 (define_insn "*cmp_ccx_neg"
5218 [(set (reg:CCX_NOOV CC_REG)
5219 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5222 "subcc\t%%g0, %0, %%g0"
5223 [(set_attr "type" "compare")])
5225 (define_insn "*cmp_cc_set_neg"
5226 [(set (reg:CC_NOOV CC_REG)
5227 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5229 (set (match_operand:SI 0 "register_operand" "=r")
5230 (neg:SI (match_dup 1)))]
5232 "subcc\t%%g0, %1, %0"
5233 [(set_attr "type" "compare")])
5235 (define_insn "*cmp_ccx_set_neg"
5236 [(set (reg:CCX_NOOV CC_REG)
5237 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5239 (set (match_operand:DI 0 "register_operand" "=r")
5240 (neg:DI (match_dup 1)))]
5242 "subcc\t%%g0, %1, %0"
5243 [(set_attr "type" "compare")])
5245 ;; We cannot use the "not" pseudo insn because the Sun assembler
5246 ;; does not know how to make it work for constants.
5247 (define_expand "one_cmpl<V64I:mode>2"
5248 [(set (match_operand:V64I 0 "register_operand" "")
5249 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5253 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5254 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5255 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5260 "&& reload_completed
5261 && ((GET_CODE (operands[0]) == REG
5262 && REGNO (operands[0]) < 32)
5263 || (GET_CODE (operands[0]) == SUBREG
5264 && GET_CODE (SUBREG_REG (operands[0])) == REG
5265 && REGNO (SUBREG_REG (operands[0])) < 32))"
5266 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5267 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5268 "operands[2] = gen_highpart (SImode, operands[0]);
5269 operands[3] = gen_highpart (SImode, operands[1]);
5270 operands[4] = gen_lowpart (SImode, operands[0]);
5271 operands[5] = gen_lowpart (SImode, operands[1]);"
5272 [(set_attr "type" "*,fga")
5273 (set_attr "length" "2,*")
5274 (set_attr "fptype" "*,double")])
5276 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5277 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5278 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5283 [(set_attr "type" "*,fga")
5284 (set_attr "fptype" "*,double")])
5286 (define_insn "one_cmpl<V32I:mode>2"
5287 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5288 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5293 [(set_attr "type" "*,fga")
5294 (set_attr "fptype" "*,single")])
5296 (define_insn "*cmp_cc_not"
5297 [(set (reg:CC CC_REG)
5298 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5301 "xnorcc\t%%g0, %0, %%g0"
5302 [(set_attr "type" "compare")])
5304 (define_insn "*cmp_ccx_not"
5305 [(set (reg:CCX CC_REG)
5306 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5309 "xnorcc\t%%g0, %0, %%g0"
5310 [(set_attr "type" "compare")])
5312 (define_insn "*cmp_cc_set_not"
5313 [(set (reg:CC CC_REG)
5314 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5316 (set (match_operand:SI 0 "register_operand" "=r")
5317 (not:SI (match_dup 1)))]
5319 "xnorcc\t%%g0, %1, %0"
5320 [(set_attr "type" "compare")])
5322 (define_insn "*cmp_ccx_set_not"
5323 [(set (reg:CCX CC_REG)
5324 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5326 (set (match_operand:DI 0 "register_operand" "=r")
5327 (not:DI (match_dup 1)))]
5329 "xnorcc\t%%g0, %1, %0"
5330 [(set_attr "type" "compare")])
5332 (define_insn "*cmp_cc_set"
5333 [(set (match_operand:SI 0 "register_operand" "=r")
5334 (match_operand:SI 1 "register_operand" "r"))
5335 (set (reg:CC CC_REG)
5336 (compare:CC (match_dup 1)
5340 [(set_attr "type" "compare")])
5342 (define_insn "*cmp_ccx_set64"
5343 [(set (match_operand:DI 0 "register_operand" "=r")
5344 (match_operand:DI 1 "register_operand" "r"))
5345 (set (reg:CCX CC_REG)
5346 (compare:CCX (match_dup 1)
5350 [(set_attr "type" "compare")])
5353 ;; Floating point arithmetic instructions.
5355 (define_expand "addtf3"
5356 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5357 (plus:TF (match_operand:TF 1 "general_operand" "")
5358 (match_operand:TF 2 "general_operand" "")))]
5359 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5360 "emit_tfmode_binop (PLUS, operands); DONE;")
5362 (define_insn "*addtf3_hq"
5363 [(set (match_operand:TF 0 "register_operand" "=e")
5364 (plus:TF (match_operand:TF 1 "register_operand" "e")
5365 (match_operand:TF 2 "register_operand" "e")))]
5366 "TARGET_FPU && TARGET_HARD_QUAD"
5368 [(set_attr "type" "fp")])
5370 (define_insn "adddf3"
5371 [(set (match_operand:DF 0 "register_operand" "=e")
5372 (plus:DF (match_operand:DF 1 "register_operand" "e")
5373 (match_operand:DF 2 "register_operand" "e")))]
5376 [(set_attr "type" "fp")
5377 (set_attr "fptype" "double")])
5379 (define_insn "addsf3"
5380 [(set (match_operand:SF 0 "register_operand" "=f")
5381 (plus:SF (match_operand:SF 1 "register_operand" "f")
5382 (match_operand:SF 2 "register_operand" "f")))]
5385 [(set_attr "type" "fp")])
5387 (define_expand "subtf3"
5388 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5389 (minus:TF (match_operand:TF 1 "general_operand" "")
5390 (match_operand:TF 2 "general_operand" "")))]
5391 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5392 "emit_tfmode_binop (MINUS, operands); DONE;")
5394 (define_insn "*subtf3_hq"
5395 [(set (match_operand:TF 0 "register_operand" "=e")
5396 (minus:TF (match_operand:TF 1 "register_operand" "e")
5397 (match_operand:TF 2 "register_operand" "e")))]
5398 "TARGET_FPU && TARGET_HARD_QUAD"
5400 [(set_attr "type" "fp")])
5402 (define_insn "subdf3"
5403 [(set (match_operand:DF 0 "register_operand" "=e")
5404 (minus:DF (match_operand:DF 1 "register_operand" "e")
5405 (match_operand:DF 2 "register_operand" "e")))]
5408 [(set_attr "type" "fp")
5409 (set_attr "fptype" "double")])
5411 (define_insn "subsf3"
5412 [(set (match_operand:SF 0 "register_operand" "=f")
5413 (minus:SF (match_operand:SF 1 "register_operand" "f")
5414 (match_operand:SF 2 "register_operand" "f")))]
5417 [(set_attr "type" "fp")])
5419 (define_expand "multf3"
5420 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5421 (mult:TF (match_operand:TF 1 "general_operand" "")
5422 (match_operand:TF 2 "general_operand" "")))]
5423 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5424 "emit_tfmode_binop (MULT, operands); DONE;")
5426 (define_insn "*multf3_hq"
5427 [(set (match_operand:TF 0 "register_operand" "=e")
5428 (mult:TF (match_operand:TF 1 "register_operand" "e")
5429 (match_operand:TF 2 "register_operand" "e")))]
5430 "TARGET_FPU && TARGET_HARD_QUAD"
5432 [(set_attr "type" "fpmul")])
5434 (define_insn "muldf3"
5435 [(set (match_operand:DF 0 "register_operand" "=e")
5436 (mult:DF (match_operand:DF 1 "register_operand" "e")
5437 (match_operand:DF 2 "register_operand" "e")))]
5440 [(set_attr "type" "fpmul")
5441 (set_attr "fptype" "double")])
5443 (define_insn "mulsf3"
5444 [(set (match_operand:SF 0 "register_operand" "=f")
5445 (mult:SF (match_operand:SF 1 "register_operand" "f")
5446 (match_operand:SF 2 "register_operand" "f")))]
5449 [(set_attr "type" "fpmul")])
5451 (define_insn "fmadf4"
5452 [(set (match_operand:DF 0 "register_operand" "=e")
5453 (fma:DF (match_operand:DF 1 "register_operand" "e")
5454 (match_operand:DF 2 "register_operand" "e")
5455 (match_operand:DF 3 "register_operand" "e")))]
5457 "fmaddd\t%1, %2, %3, %0"
5458 [(set_attr "type" "fpmul")])
5460 (define_insn "fmsdf4"
5461 [(set (match_operand:DF 0 "register_operand" "=e")
5462 (fma:DF (match_operand:DF 1 "register_operand" "e")
5463 (match_operand:DF 2 "register_operand" "e")
5464 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5466 "fmsubd\t%1, %2, %3, %0"
5467 [(set_attr "type" "fpmul")])
5469 (define_insn "*nfmadf4"
5470 [(set (match_operand:DF 0 "register_operand" "=e")
5471 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5472 (match_operand:DF 2 "register_operand" "e")
5473 (match_operand:DF 3 "register_operand" "e"))))]
5475 "fnmaddd\t%1, %2, %3, %0"
5476 [(set_attr "type" "fpmul")])
5478 (define_insn "*nfmsdf4"
5479 [(set (match_operand:DF 0 "register_operand" "=e")
5480 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5481 (match_operand:DF 2 "register_operand" "e")
5482 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5484 "fnmsubd\t%1, %2, %3, %0"
5485 [(set_attr "type" "fpmul")])
5487 (define_insn "fmasf4"
5488 [(set (match_operand:SF 0 "register_operand" "=f")
5489 (fma:SF (match_operand:SF 1 "register_operand" "f")
5490 (match_operand:SF 2 "register_operand" "f")
5491 (match_operand:SF 3 "register_operand" "f")))]
5493 "fmadds\t%1, %2, %3, %0"
5494 [(set_attr "type" "fpmul")])
5496 (define_insn "fmssf4"
5497 [(set (match_operand:SF 0 "register_operand" "=f")
5498 (fma:SF (match_operand:SF 1 "register_operand" "f")
5499 (match_operand:SF 2 "register_operand" "f")
5500 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5502 "fmsubs\t%1, %2, %3, %0"
5503 [(set_attr "type" "fpmul")])
5505 (define_insn "*nfmasf4"
5506 [(set (match_operand:SF 0 "register_operand" "=f")
5507 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5508 (match_operand:SF 2 "register_operand" "f")
5509 (match_operand:SF 3 "register_operand" "f"))))]
5511 "fnmadds\t%1, %2, %3, %0"
5512 [(set_attr "type" "fpmul")])
5514 (define_insn "*nfmssf4"
5515 [(set (match_operand:SF 0 "register_operand" "=f")
5516 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5517 (match_operand:SF 2 "register_operand" "f")
5518 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5520 "fnmsubs\t%1, %2, %3, %0"
5521 [(set_attr "type" "fpmul")])
5523 (define_insn "*muldf3_extend"
5524 [(set (match_operand:DF 0 "register_operand" "=e")
5525 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5526 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5527 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5528 "fsmuld\t%1, %2, %0"
5529 [(set_attr "type" "fpmul")
5530 (set_attr "fptype" "double")])
5532 (define_insn "*multf3_extend"
5533 [(set (match_operand:TF 0 "register_operand" "=e")
5534 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5535 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5536 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5537 "fdmulq\t%1, %2, %0"
5538 [(set_attr "type" "fpmul")])
5540 (define_expand "divtf3"
5541 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5542 (div:TF (match_operand:TF 1 "general_operand" "")
5543 (match_operand:TF 2 "general_operand" "")))]
5544 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5545 "emit_tfmode_binop (DIV, operands); DONE;")
5547 ;; don't have timing for quad-prec. divide.
5548 (define_insn "*divtf3_hq"
5549 [(set (match_operand:TF 0 "register_operand" "=e")
5550 (div:TF (match_operand:TF 1 "register_operand" "e")
5551 (match_operand:TF 2 "register_operand" "e")))]
5552 "TARGET_FPU && TARGET_HARD_QUAD"
5554 [(set_attr "type" "fpdivd")])
5556 (define_insn "divdf3"
5557 [(set (match_operand:DF 0 "register_operand" "=e")
5558 (div:DF (match_operand:DF 1 "register_operand" "e")
5559 (match_operand:DF 2 "register_operand" "e")))]
5562 [(set_attr "type" "fpdivd")
5563 (set_attr "fptype" "double")])
5565 (define_insn "divsf3"
5566 [(set (match_operand:SF 0 "register_operand" "=f")
5567 (div:SF (match_operand:SF 1 "register_operand" "f")
5568 (match_operand:SF 2 "register_operand" "f")))]
5571 [(set_attr "type" "fpdivs")])
5573 (define_expand "negtf2"
5574 [(set (match_operand:TF 0 "register_operand" "=e,e")
5575 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5579 (define_insn_and_split "*negtf2_notv9"
5580 [(set (match_operand:TF 0 "register_operand" "=e,e")
5581 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5582 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5588 "&& reload_completed
5589 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5590 [(set (match_dup 2) (neg:SF (match_dup 3)))
5591 (set (match_dup 4) (match_dup 5))
5592 (set (match_dup 6) (match_dup 7))]
5593 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5594 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5595 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5596 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5597 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5598 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5599 [(set_attr "type" "fpmove,*")
5600 (set_attr "length" "*,2")])
5602 (define_insn_and_split "*negtf2_v9"
5603 [(set (match_operand:TF 0 "register_operand" "=e,e")
5604 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5605 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5606 "TARGET_FPU && TARGET_V9"
5610 "&& reload_completed
5611 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5612 [(set (match_dup 2) (neg:DF (match_dup 3)))
5613 (set (match_dup 4) (match_dup 5))]
5614 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5615 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5616 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5617 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5618 [(set_attr "type" "fpmove,*")
5619 (set_attr "length" "*,2")
5620 (set_attr "fptype" "double")])
5622 (define_expand "negdf2"
5623 [(set (match_operand:DF 0 "register_operand" "")
5624 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5628 (define_insn_and_split "*negdf2_notv9"
5629 [(set (match_operand:DF 0 "register_operand" "=e,e")
5630 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5631 "TARGET_FPU && ! TARGET_V9"
5635 "&& reload_completed
5636 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5637 [(set (match_dup 2) (neg:SF (match_dup 3)))
5638 (set (match_dup 4) (match_dup 5))]
5639 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5640 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5641 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5642 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5643 [(set_attr "type" "fpmove,*")
5644 (set_attr "length" "*,2")])
5646 (define_insn "*negdf2_v9"
5647 [(set (match_operand:DF 0 "register_operand" "=e")
5648 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5649 "TARGET_FPU && TARGET_V9"
5651 [(set_attr "type" "fpmove")
5652 (set_attr "fptype" "double")])
5654 (define_insn "negsf2"
5655 [(set (match_operand:SF 0 "register_operand" "=f")
5656 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5659 [(set_attr "type" "fpmove")])
5661 (define_expand "abstf2"
5662 [(set (match_operand:TF 0 "register_operand" "")
5663 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5667 (define_insn_and_split "*abstf2_notv9"
5668 [(set (match_operand:TF 0 "register_operand" "=e,e")
5669 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5670 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5671 "TARGET_FPU && ! TARGET_V9"
5675 "&& reload_completed
5676 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5677 [(set (match_dup 2) (abs:SF (match_dup 3)))
5678 (set (match_dup 4) (match_dup 5))
5679 (set (match_dup 6) (match_dup 7))]
5680 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5681 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5682 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5683 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5684 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5685 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5686 [(set_attr "type" "fpmove,*")
5687 (set_attr "length" "*,2")])
5689 (define_insn "*abstf2_hq_v9"
5690 [(set (match_operand:TF 0 "register_operand" "=e,e")
5691 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5692 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5696 [(set_attr "type" "fpmove")
5697 (set_attr "fptype" "double,*")])
5699 (define_insn_and_split "*abstf2_v9"
5700 [(set (match_operand:TF 0 "register_operand" "=e,e")
5701 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5702 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5706 "&& reload_completed
5707 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5708 [(set (match_dup 2) (abs:DF (match_dup 3)))
5709 (set (match_dup 4) (match_dup 5))]
5710 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5711 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5712 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5713 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5714 [(set_attr "type" "fpmove,*")
5715 (set_attr "length" "*,2")
5716 (set_attr "fptype" "double,*")])
5718 (define_expand "absdf2"
5719 [(set (match_operand:DF 0 "register_operand" "")
5720 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5724 (define_insn_and_split "*absdf2_notv9"
5725 [(set (match_operand:DF 0 "register_operand" "=e,e")
5726 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5727 "TARGET_FPU && ! TARGET_V9"
5731 "&& reload_completed
5732 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5733 [(set (match_dup 2) (abs:SF (match_dup 3)))
5734 (set (match_dup 4) (match_dup 5))]
5735 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5736 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5737 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5738 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5739 [(set_attr "type" "fpmove,*")
5740 (set_attr "length" "*,2")])
5742 (define_insn "*absdf2_v9"
5743 [(set (match_operand:DF 0 "register_operand" "=e")
5744 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5745 "TARGET_FPU && TARGET_V9"
5747 [(set_attr "type" "fpmove")
5748 (set_attr "fptype" "double")])
5750 (define_insn "abssf2"
5751 [(set (match_operand:SF 0 "register_operand" "=f")
5752 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5755 [(set_attr "type" "fpmove")])
5757 (define_expand "sqrttf2"
5758 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5759 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5760 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5761 "emit_tfmode_unop (SQRT, operands); DONE;")
5763 (define_insn "*sqrttf2_hq"
5764 [(set (match_operand:TF 0 "register_operand" "=e")
5765 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5766 "TARGET_FPU && TARGET_HARD_QUAD"
5768 [(set_attr "type" "fpsqrtd")])
5770 (define_insn "sqrtdf2"
5771 [(set (match_operand:DF 0 "register_operand" "=e")
5772 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5775 [(set_attr "type" "fpsqrtd")
5776 (set_attr "fptype" "double")])
5778 (define_insn "sqrtsf2"
5779 [(set (match_operand:SF 0 "register_operand" "=f")
5780 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5783 [(set_attr "type" "fpsqrts")])
5786 ;; Arithmetic shift instructions.
5788 (define_insn "ashlsi3"
5789 [(set (match_operand:SI 0 "register_operand" "=r")
5790 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5791 (match_operand:SI 2 "arith_operand" "rI")))]
5794 if (GET_CODE (operands[2]) == CONST_INT)
5795 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5796 return "sll\t%1, %2, %0";
5798 [(set_attr "type" "shift")])
5800 (define_insn "*ashlsi3_extend"
5801 [(set (match_operand:DI 0 "register_operand" "=r")
5803 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5804 (match_operand:SI 2 "arith_operand" "rI"))))]
5807 if (GET_CODE (operands[2]) == CONST_INT)
5808 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5809 return "sll\t%1, %2, %0";
5811 [(set_attr "type" "shift")])
5813 (define_expand "ashldi3"
5814 [(set (match_operand:DI 0 "register_operand" "=r")
5815 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5816 (match_operand:SI 2 "arith_operand" "rI")))]
5817 "TARGET_ARCH64 || TARGET_V8PLUS"
5819 if (! TARGET_ARCH64)
5821 if (GET_CODE (operands[2]) == CONST_INT)
5823 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5828 (define_insn "*ashldi3_sp64"
5829 [(set (match_operand:DI 0 "register_operand" "=r")
5830 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5831 (match_operand:SI 2 "arith_operand" "rI")))]
5834 if (GET_CODE (operands[2]) == CONST_INT)
5835 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5836 return "sllx\t%1, %2, %0";
5838 [(set_attr "type" "shift")])
5841 (define_insn "ashldi3_v8plus"
5842 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5843 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5844 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5845 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5847 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5848 [(set_attr "type" "multi")
5849 (set_attr "length" "5,5,6")])
5851 ;; Optimize (1LL<<x)-1
5852 ;; XXX this also needs to be fixed to handle equal subregs
5853 ;; XXX first before we could re-enable it.
5855 ; [(set (match_operand:DI 0 "register_operand" "=h")
5856 ; (plus:DI (ashift:DI (const_int 1)
5857 ; (match_operand:SI 1 "arith_operand" "rI"))
5859 ; "0 && TARGET_V8PLUS"
5861 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5862 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5863 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5865 ; [(set_attr "type" "multi")
5866 ; (set_attr "length" "4")])
5868 (define_insn "*cmp_cc_ashift_1"
5869 [(set (reg:CC_NOOV CC_REG)
5870 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5874 "addcc\t%0, %0, %%g0"
5875 [(set_attr "type" "compare")])
5877 (define_insn "*cmp_cc_set_ashift_1"
5878 [(set (reg:CC_NOOV CC_REG)
5879 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5882 (set (match_operand:SI 0 "register_operand" "=r")
5883 (ashift:SI (match_dup 1) (const_int 1)))]
5886 [(set_attr "type" "compare")])
5888 (define_insn "ashrsi3"
5889 [(set (match_operand:SI 0 "register_operand" "=r")
5890 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5891 (match_operand:SI 2 "arith_operand" "rI")))]
5894 if (GET_CODE (operands[2]) == CONST_INT)
5895 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5896 return "sra\t%1, %2, %0";
5898 [(set_attr "type" "shift")])
5900 (define_insn "*ashrsi3_extend"
5901 [(set (match_operand:DI 0 "register_operand" "=r")
5902 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5903 (match_operand:SI 2 "arith_operand" "r"))))]
5906 [(set_attr "type" "shift")])
5908 ;; This handles the case as above, but with constant shift instead of
5909 ;; register. Combiner "simplifies" it for us a little bit though.
5910 (define_insn "*ashrsi3_extend2"
5911 [(set (match_operand:DI 0 "register_operand" "=r")
5912 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5914 (match_operand:SI 2 "small_int_operand" "I")))]
5915 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5917 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5918 return "sra\t%1, %2, %0";
5920 [(set_attr "type" "shift")])
5922 (define_expand "ashrdi3"
5923 [(set (match_operand:DI 0 "register_operand" "=r")
5924 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5925 (match_operand:SI 2 "arith_operand" "rI")))]
5926 "TARGET_ARCH64 || TARGET_V8PLUS"
5928 if (! TARGET_ARCH64)
5930 if (GET_CODE (operands[2]) == CONST_INT)
5931 FAIL; /* prefer generic code in this case */
5932 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5937 (define_insn "*ashrdi3_sp64"
5938 [(set (match_operand:DI 0 "register_operand" "=r")
5939 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5940 (match_operand:SI 2 "arith_operand" "rI")))]
5944 if (GET_CODE (operands[2]) == CONST_INT)
5945 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5946 return "srax\t%1, %2, %0";
5948 [(set_attr "type" "shift")])
5951 (define_insn "ashrdi3_v8plus"
5952 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5953 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5954 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5955 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5957 "* return output_v8plus_shift (operands, insn, \"srax\");"
5958 [(set_attr "type" "multi")
5959 (set_attr "length" "5,5,6")])
5961 (define_insn "lshrsi3"
5962 [(set (match_operand:SI 0 "register_operand" "=r")
5963 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5964 (match_operand:SI 2 "arith_operand" "rI")))]
5967 if (GET_CODE (operands[2]) == CONST_INT)
5968 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5969 return "srl\t%1, %2, %0";
5971 [(set_attr "type" "shift")])
5973 (define_insn "*lshrsi3_extend0"
5974 [(set (match_operand:DI 0 "register_operand" "=r")
5976 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5977 (match_operand:SI 2 "arith_operand" "rI"))))]
5980 if (GET_CODE (operands[2]) == CONST_INT)
5981 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5982 return "srl\t%1, %2, %0";
5984 [(set_attr "type" "shift")])
5986 ;; This handles the case where
5987 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5988 ;; but combiner "simplifies" it for us.
5989 (define_insn "*lshrsi3_extend1"
5990 [(set (match_operand:DI 0 "register_operand" "=r")
5991 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5992 (match_operand:SI 2 "arith_operand" "r")) 0)
5993 (match_operand 3 "const_int_operand" "")))]
5994 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5996 [(set_attr "type" "shift")])
5998 ;; This handles the case where
5999 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6000 ;; but combiner "simplifies" it for us.
6001 (define_insn "*lshrsi3_extend2"
6002 [(set (match_operand:DI 0 "register_operand" "=r")
6003 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6004 (match_operand 2 "small_int_operand" "I")
6006 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6008 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6009 return "srl\t%1, %2, %0";
6011 [(set_attr "type" "shift")])
6013 (define_expand "lshrdi3"
6014 [(set (match_operand:DI 0 "register_operand" "=r")
6015 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6016 (match_operand:SI 2 "arith_operand" "rI")))]
6017 "TARGET_ARCH64 || TARGET_V8PLUS"
6019 if (! TARGET_ARCH64)
6021 if (GET_CODE (operands[2]) == CONST_INT)
6023 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6028 (define_insn "*lshrdi3_sp64"
6029 [(set (match_operand:DI 0 "register_operand" "=r")
6030 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6031 (match_operand:SI 2 "arith_operand" "rI")))]
6034 if (GET_CODE (operands[2]) == CONST_INT)
6035 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6036 return "srlx\t%1, %2, %0";
6038 [(set_attr "type" "shift")])
6041 (define_insn "lshrdi3_v8plus"
6042 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6043 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6044 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6045 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6047 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6048 [(set_attr "type" "multi")
6049 (set_attr "length" "5,5,6")])
6052 [(set (match_operand:SI 0 "register_operand" "=r")
6053 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6055 (match_operand:SI 2 "small_int_operand" "I")))]
6056 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6058 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6059 return "srax\t%1, %2, %0";
6061 [(set_attr "type" "shift")])
6064 [(set (match_operand:SI 0 "register_operand" "=r")
6065 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6067 (match_operand:SI 2 "small_int_operand" "I")))]
6068 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6070 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6071 return "srlx\t%1, %2, %0";
6073 [(set_attr "type" "shift")])
6076 [(set (match_operand:SI 0 "register_operand" "=r")
6077 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6078 (match_operand:SI 2 "small_int_operand" "I")) 4)
6079 (match_operand:SI 3 "small_int_operand" "I")))]
6081 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6082 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6083 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6085 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6087 return "srax\t%1, %2, %0";
6089 [(set_attr "type" "shift")])
6092 [(set (match_operand:SI 0 "register_operand" "=r")
6093 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6094 (match_operand:SI 2 "small_int_operand" "I")) 4)
6095 (match_operand:SI 3 "small_int_operand" "I")))]
6097 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6098 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6099 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6101 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6103 return "srlx\t%1, %2, %0";
6105 [(set_attr "type" "shift")])
6108 ;; Unconditional and other jump instructions.
6111 [(set (pc) (label_ref (match_operand 0 "" "")))]
6113 "* return output_ubranch (operands[0], 0, insn);"
6114 [(set_attr "type" "uncond_branch")])
6116 (define_expand "tablejump"
6117 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6118 (use (label_ref (match_operand 1 "" "")))])]
6121 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6123 /* In pic mode, our address differences are against the base of the
6124 table. Add that base value back in; CSE ought to be able to combine
6125 the two address loads. */
6129 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6131 if (CASE_VECTOR_MODE != Pmode)
6132 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6133 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6134 operands[0] = memory_address (Pmode, tmp);
6138 (define_insn "*tablejump_sp32"
6139 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6140 (use (label_ref (match_operand 1 "" "")))]
6143 [(set_attr "type" "uncond_branch")])
6145 (define_insn "*tablejump_sp64"
6146 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6147 (use (label_ref (match_operand 1 "" "")))]
6150 [(set_attr "type" "uncond_branch")])
6153 ;; Jump to subroutine instructions.
6155 (define_expand "call"
6156 ;; Note that this expression is not used for generating RTL.
6157 ;; All the RTL is generated explicitly below.
6158 [(call (match_operand 0 "call_operand" "")
6159 (match_operand 3 "" "i"))]
6160 ;; operands[2] is next_arg_register
6161 ;; operands[3] is struct_value_size_rtx.
6166 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6168 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6170 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6172 /* This is really a PIC sequence. We want to represent
6173 it as a funny jump so its delay slots can be filled.
6175 ??? But if this really *is* a CALL, will not it clobber the
6176 call-clobbered registers? We lose this if it is a JUMP_INSN.
6177 Why cannot we have delay slots filled if it were a CALL? */
6179 /* We accept negative sizes for untyped calls. */
6180 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6185 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6187 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6193 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6194 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6198 fn_rtx = operands[0];
6200 /* We accept negative sizes for untyped calls. */
6201 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6202 sparc_emit_call_insn
6205 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6207 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6210 sparc_emit_call_insn
6213 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6214 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6222 ;; We can't use the same pattern for these two insns, because then registers
6223 ;; in the address may not be properly reloaded.
6225 (define_insn "*call_address_sp32"
6226 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6227 (match_operand 1 "" ""))
6228 (clobber (reg:SI O7_REG))]
6229 ;;- Do not use operand 1 for most machines.
6232 [(set_attr "type" "call")])
6234 (define_insn "*call_symbolic_sp32"
6235 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6236 (match_operand 1 "" ""))
6237 (clobber (reg:SI O7_REG))]
6238 ;;- Do not use operand 1 for most machines.
6241 [(set_attr "type" "call")])
6243 (define_insn "*call_address_sp64"
6244 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6245 (match_operand 1 "" ""))
6246 (clobber (reg:DI O7_REG))]
6247 ;;- Do not use operand 1 for most machines.
6250 [(set_attr "type" "call")])
6252 (define_insn "*call_symbolic_sp64"
6253 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6254 (match_operand 1 "" ""))
6255 (clobber (reg:DI O7_REG))]
6256 ;;- Do not use operand 1 for most machines.
6259 [(set_attr "type" "call")])
6261 ;; This is a call that wants a structure value.
6262 ;; There is no such critter for v9 (??? we may need one anyway).
6263 (define_insn "*call_address_struct_value_sp32"
6264 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6265 (match_operand 1 "" ""))
6266 (match_operand 2 "immediate_operand" "")
6267 (clobber (reg:SI O7_REG))]
6268 ;;- Do not use operand 1 for most machines.
6269 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6271 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6272 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6274 [(set_attr "type" "call_no_delay_slot")
6275 (set_attr "length" "3")])
6277 ;; This is a call that wants a structure value.
6278 ;; There is no such critter for v9 (??? we may need one anyway).
6279 (define_insn "*call_symbolic_struct_value_sp32"
6280 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6281 (match_operand 1 "" ""))
6282 (match_operand 2 "immediate_operand" "")
6283 (clobber (reg:SI O7_REG))]
6284 ;;- Do not use operand 1 for most machines.
6285 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6287 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6288 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6290 [(set_attr "type" "call_no_delay_slot")
6291 (set_attr "length" "3")])
6293 ;; This is a call that may want a structure value. This is used for
6295 (define_insn "*call_address_untyped_struct_value_sp32"
6296 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6297 (match_operand 1 "" ""))
6298 (match_operand 2 "immediate_operand" "")
6299 (clobber (reg:SI O7_REG))]
6300 ;;- Do not use operand 1 for most machines.
6301 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6302 "call\t%a0, %1\n\t nop\n\tnop"
6303 [(set_attr "type" "call_no_delay_slot")
6304 (set_attr "length" "3")])
6306 ;; This is a call that may want a structure value. This is used for
6308 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6309 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6310 (match_operand 1 "" ""))
6311 (match_operand 2 "immediate_operand" "")
6312 (clobber (reg:SI O7_REG))]
6313 ;;- Do not use operand 1 for most machines.
6314 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6315 "call\t%a0, %1\n\t nop\n\tnop"
6316 [(set_attr "type" "call_no_delay_slot")
6317 (set_attr "length" "3")])
6319 (define_expand "call_value"
6320 ;; Note that this expression is not used for generating RTL.
6321 ;; All the RTL is generated explicitly below.
6322 [(set (match_operand 0 "register_operand" "=rf")
6323 (call (match_operand 1 "" "")
6324 (match_operand 4 "" "")))]
6325 ;; operand 2 is stack_size_rtx
6326 ;; operand 3 is next_arg_register
6332 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6334 fn_rtx = operands[1];
6337 gen_rtx_SET (VOIDmode, operands[0],
6338 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6339 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6341 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6346 (define_insn "*call_value_address_sp32"
6347 [(set (match_operand 0 "" "=rf")
6348 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6349 (match_operand 2 "" "")))
6350 (clobber (reg:SI O7_REG))]
6351 ;;- Do not use operand 2 for most machines.
6354 [(set_attr "type" "call")])
6356 (define_insn "*call_value_symbolic_sp32"
6357 [(set (match_operand 0 "" "=rf")
6358 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6359 (match_operand 2 "" "")))
6360 (clobber (reg:SI O7_REG))]
6361 ;;- Do not use operand 2 for most machines.
6364 [(set_attr "type" "call")])
6366 (define_insn "*call_value_address_sp64"
6367 [(set (match_operand 0 "" "")
6368 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6369 (match_operand 2 "" "")))
6370 (clobber (reg:DI O7_REG))]
6371 ;;- Do not use operand 2 for most machines.
6374 [(set_attr "type" "call")])
6376 (define_insn "*call_value_symbolic_sp64"
6377 [(set (match_operand 0 "" "")
6378 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6379 (match_operand 2 "" "")))
6380 (clobber (reg:DI O7_REG))]
6381 ;;- Do not use operand 2 for most machines.
6384 [(set_attr "type" "call")])
6386 (define_expand "untyped_call"
6387 [(parallel [(call (match_operand 0 "" "")
6389 (match_operand:BLK 1 "memory_operand" "")
6390 (match_operand 2 "" "")])]
6393 rtx valreg1 = gen_rtx_REG (DImode, 8);
6394 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6395 rtx result = operands[1];
6397 /* Pass constm1 to indicate that it may expect a structure value, but
6398 we don't know what size it is. */
6399 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6401 /* Save the function value registers. */
6402 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6403 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6406 /* The optimizer does not know that the call sets the function value
6407 registers we stored in the result block. We avoid problems by
6408 claiming that all hard registers are used and clobbered at this
6410 emit_insn (gen_blockage ());
6415 ;; Tail call instructions.
6417 (define_expand "sibcall"
6418 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6423 (define_insn "*sibcall_symbolic_sp32"
6424 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6425 (match_operand 1 "" ""))
6428 "* return output_sibcall(insn, operands[0]);"
6429 [(set_attr "type" "sibcall")])
6431 (define_insn "*sibcall_symbolic_sp64"
6432 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6433 (match_operand 1 "" ""))
6436 "* return output_sibcall(insn, operands[0]);"
6437 [(set_attr "type" "sibcall")])
6439 (define_expand "sibcall_value"
6440 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6441 (call (match_operand 1 "" "") (const_int 0)))
6446 (define_insn "*sibcall_value_symbolic_sp32"
6447 [(set (match_operand 0 "" "=rf")
6448 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6449 (match_operand 2 "" "")))
6452 "* return output_sibcall(insn, operands[1]);"
6453 [(set_attr "type" "sibcall")])
6455 (define_insn "*sibcall_value_symbolic_sp64"
6456 [(set (match_operand 0 "" "")
6457 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6458 (match_operand 2 "" "")))
6461 "* return output_sibcall(insn, operands[1]);"
6462 [(set_attr "type" "sibcall")])
6465 ;; Special instructions.
6467 (define_expand "prologue"
6472 sparc_flat_expand_prologue ();
6474 sparc_expand_prologue ();
6478 ;; The "register window save" insn is modelled as follows. The dwarf2
6479 ;; information is manually added in emit_window_save.
6481 (define_insn "window_save"
6483 [(match_operand 0 "arith_operand" "rI")]
6486 "save\t%%sp, %0, %%sp"
6487 [(set_attr "type" "savew")])
6489 (define_expand "epilogue"
6494 sparc_flat_expand_epilogue (false);
6496 sparc_expand_epilogue (false);
6499 (define_expand "sibcall_epilogue"
6504 sparc_flat_expand_epilogue (false);
6506 sparc_expand_epilogue (false);
6510 (define_expand "eh_return"
6511 [(use (match_operand 0 "general_operand" ""))]
6514 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6515 emit_jump_insn (gen_eh_return_internal ());
6520 (define_insn_and_split "eh_return_internal"
6524 "epilogue_completed"
6528 sparc_flat_expand_epilogue (true);
6530 sparc_expand_epilogue (true);
6533 (define_expand "return"
6535 "sparc_can_use_return_insn_p ()"
6538 (define_insn "*return_internal"
6541 "* return output_return (insn);"
6542 [(set_attr "type" "return")
6543 (set (attr "length")
6544 (cond [(eq_attr "calls_eh_return" "true")
6545 (if_then_else (eq_attr "delayed_branch" "true")
6546 (if_then_else (ior (eq_attr "isa" "v9")
6547 (eq_attr "flat" "true"))
6550 (if_then_else (eq_attr "flat" "true")
6553 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6554 (if_then_else (eq_attr "empty_delay_slot" "true")
6557 (eq_attr "empty_delay_slot" "true")
6558 (if_then_else (eq_attr "delayed_branch" "true")
6563 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6564 ;; all of memory. This blocks insns from being moved across this point.
6566 (define_insn "blockage"
6567 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6570 [(set_attr "length" "0")])
6572 (define_expand "probe_stack"
6573 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6577 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6580 (define_insn "probe_stack_range<P:mode>"
6581 [(set (match_operand:P 0 "register_operand" "=r")
6582 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6583 (match_operand:P 2 "register_operand" "r")]
6584 UNSPECV_PROBE_STACK_RANGE))]
6586 "* return output_probe_stack_range (operands[0], operands[2]);"
6587 [(set_attr "type" "multi")])
6589 ;; Prepare to return any type including a structure value.
6591 (define_expand "untyped_return"
6592 [(match_operand:BLK 0 "memory_operand" "")
6593 (match_operand 1 "" "")]
6596 rtx valreg1 = gen_rtx_REG (DImode, 24);
6597 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6598 rtx result = operands[0];
6600 if (! TARGET_ARCH64)
6602 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6603 rtx value = gen_reg_rtx (SImode);
6605 /* Fetch the instruction where we will return to and see if it's an unimp
6606 instruction (the most significant 10 bits will be zero). If so,
6607 update the return address to skip the unimp instruction. */
6608 emit_move_insn (value,
6609 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6610 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6611 emit_insn (gen_update_return (rtnreg, value));
6614 /* Reload the function value registers. */
6615 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6616 emit_move_insn (valreg2,
6617 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6619 /* Put USE insns before the return. */
6623 /* Construct the return. */
6624 expand_naked_return ();
6629 ;; Adjust the return address conditionally. If the value of op1 is equal
6630 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6631 ;; This is technically *half* the check required by the 32-bit SPARC
6632 ;; psABI. This check only ensures that an "unimp" insn was written by
6633 ;; the caller, but doesn't check to see if the expected size matches
6634 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6635 ;; only used by the above code "untyped_return".
6637 (define_insn "update_return"
6638 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6639 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6642 if (flag_delayed_branch)
6643 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6645 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6647 [(set (attr "type") (const_string "multi"))
6648 (set (attr "length")
6649 (if_then_else (eq_attr "delayed_branch" "true")
6658 (define_expand "indirect_jump"
6659 [(set (pc) (match_operand 0 "address_operand" "p"))]
6663 (define_insn "*branch_sp32"
6664 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6667 [(set_attr "type" "uncond_branch")])
6669 (define_insn "*branch_sp64"
6670 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6673 [(set_attr "type" "uncond_branch")])
6675 (define_expand "save_stack_nonlocal"
6676 [(set (match_operand 0 "memory_operand" "")
6677 (match_operand 1 "register_operand" ""))
6678 (set (match_dup 2) (match_dup 3))]
6681 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6682 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6683 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6686 (define_expand "restore_stack_nonlocal"
6687 [(set (match_operand 0 "register_operand" "")
6688 (match_operand 1 "memory_operand" ""))]
6691 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6694 (define_expand "nonlocal_goto"
6695 [(match_operand 0 "general_operand" "")
6696 (match_operand 1 "general_operand" "")
6697 (match_operand 2 "memory_operand" "")
6698 (match_operand 3 "memory_operand" "")]
6701 rtx r_label = copy_to_reg (operands[1]);
6702 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6703 rtx r_fp = operands[3];
6704 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6706 /* We need to flush all the register windows so that their contents will
6707 be re-synchronized by the restore insn of the target function. */
6709 emit_insn (gen_flush_register_windows ());
6711 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6712 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6714 /* Restore frame pointer for containing function. */
6715 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6716 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6718 /* USE of hard_frame_pointer_rtx added for consistency;
6719 not clear if really needed. */
6720 emit_use (hard_frame_pointer_rtx);
6721 emit_use (stack_pointer_rtx);
6723 /* We need to smuggle the load of %i7 as it is a fixed register. */
6724 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6729 (define_insn "nonlocal_goto_internal"
6730 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6731 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6732 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6734 if (flag_delayed_branch)
6737 return "jmp\t%0\n\t ldx\t%1, %%i7";
6739 return "jmp\t%0\n\t ld\t%1, %%i7";
6744 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6746 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6749 [(set (attr "type") (const_string "multi"))
6750 (set (attr "length")
6751 (if_then_else (eq_attr "delayed_branch" "true")
6755 (define_expand "builtin_setjmp_receiver"
6756 [(label_ref (match_operand 0 "" ""))]
6759 load_got_register ();
6763 ;; Special insn to flush register windows.
6765 (define_insn "flush_register_windows"
6766 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6768 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6769 [(set_attr "type" "flushw")])
6771 ;; Special pattern for the FLUSH instruction.
6773 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6774 ; of the define_insn otherwise missing a mode. We make "flush", aka
6775 ; gen_flush, the default one since sparc_initialize_trampoline uses
6776 ; it on SImode mem values.
6778 (define_insn "flush"
6779 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6781 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6782 [(set_attr "type" "iflush")])
6784 (define_insn "flushdi"
6785 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6787 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6788 [(set_attr "type" "iflush")])
6791 ;; Find first set instructions.
6793 ;; The scan instruction searches from the most significant bit while ffs
6794 ;; searches from the least significant bit. The bit index and treatment of
6795 ;; zero also differ. It takes at least 7 instructions to get the proper
6796 ;; result. Here is an obvious 8 instruction sequence.
6799 (define_insn "ffssi2"
6800 [(set (match_operand:SI 0 "register_operand" "=&r")
6801 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6802 (clobber (match_scratch:SI 2 "=&r"))]
6803 "TARGET_SPARCLITE || TARGET_SPARCLET"
6805 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";
6807 [(set_attr "type" "multi")
6808 (set_attr "length" "8")])
6810 (define_expand "popcountdi2"
6811 [(set (match_operand:DI 0 "register_operand" "")
6812 (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6815 if (! TARGET_ARCH64)
6817 emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6822 (define_insn "*popcountdi_sp64"
6823 [(set (match_operand:DI 0 "register_operand" "=r")
6824 (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6825 "TARGET_POPC && TARGET_ARCH64"
6828 (define_insn "popcountdi_v8plus"
6829 [(set (match_operand:DI 0 "register_operand" "=r")
6830 (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6831 (clobber (match_scratch:SI 2 "=&h"))]
6832 "TARGET_POPC && ! TARGET_ARCH64"
6834 if (sparc_check_64 (operands[1], insn) <= 0)
6835 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6836 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6838 [(set_attr "type" "multi")
6839 (set_attr "length" "5")])
6841 (define_expand "popcountsi2"
6843 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6844 (set (match_operand:SI 0 "register_operand" "")
6845 (truncate:SI (popcount:DI (match_dup 2))))]
6848 if (! TARGET_ARCH64)
6850 emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6854 operands[2] = gen_reg_rtx (DImode);
6857 (define_insn "*popcountsi_sp64"
6858 [(set (match_operand:SI 0 "register_operand" "=r")
6860 (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6861 "TARGET_POPC && TARGET_ARCH64"
6864 (define_insn "popcountsi_v8plus"
6865 [(set (match_operand:SI 0 "register_operand" "=r")
6866 (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6867 "TARGET_POPC && ! TARGET_ARCH64"
6869 if (sparc_check_64 (operands[1], insn) <= 0)
6870 output_asm_insn ("srl\t%1, 0, %1", operands);
6871 return "popc\t%1, %0";
6873 [(set_attr "type" "multi")
6874 (set_attr "length" "2")])
6876 (define_expand "clzdi2"
6877 [(set (match_operand:DI 0 "register_operand" "")
6878 (clz:DI (match_operand:DI 1 "register_operand" "")))]
6881 if (! TARGET_ARCH64)
6883 emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6888 (define_insn "*clzdi_sp64"
6889 [(set (match_operand:DI 0 "register_operand" "=r")
6890 (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6891 "TARGET_VIS3 && TARGET_ARCH64"
6894 (define_insn "clzdi_v8plus"
6895 [(set (match_operand:DI 0 "register_operand" "=r")
6896 (clz:DI (match_operand:DI 1 "register_operand" "r")))
6897 (clobber (match_scratch:SI 2 "=&h"))]
6898 "TARGET_VIS3 && ! TARGET_ARCH64"
6900 if (sparc_check_64 (operands[1], insn) <= 0)
6901 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6902 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6904 [(set_attr "type" "multi")
6905 (set_attr "length" "5")])
6907 (define_expand "clzsi2"
6909 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6911 (truncate:SI (clz:DI (match_dup 2))))
6912 (set (match_operand:SI 0 "register_operand" "")
6913 (minus:SI (match_dup 3) (const_int 32)))]
6916 if (! TARGET_ARCH64)
6918 emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6923 operands[2] = gen_reg_rtx (DImode);
6924 operands[3] = gen_reg_rtx (SImode);
6928 (define_insn "*clzsi_sp64"
6929 [(set (match_operand:SI 0 "register_operand" "=r")
6931 (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6932 "TARGET_VIS3 && TARGET_ARCH64"
6935 (define_insn "clzsi_v8plus"
6936 [(set (match_operand:SI 0 "register_operand" "=r")
6937 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6938 "TARGET_VIS3 && ! TARGET_ARCH64"
6940 if (sparc_check_64 (operands[1], insn) <= 0)
6941 output_asm_insn ("srl\t%1, 0, %1", operands);
6942 return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6944 [(set_attr "type" "multi")
6945 (set_attr "length" "3")])
6948 ;; Peepholes go at the end.
6950 ;; Optimize consecutive loads or stores into ldd and std when possible.
6951 ;; The conditions in which we do this are very restricted and are
6952 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6955 [(set (match_operand:SI 0 "memory_operand" "")
6957 (set (match_operand:SI 1 "memory_operand" "")
6960 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6963 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6966 [(set (match_operand:SI 0 "memory_operand" "")
6968 (set (match_operand:SI 1 "memory_operand" "")
6971 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6974 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6977 [(set (match_operand:SI 0 "register_operand" "")
6978 (match_operand:SI 1 "memory_operand" ""))
6979 (set (match_operand:SI 2 "register_operand" "")
6980 (match_operand:SI 3 "memory_operand" ""))]
6981 "registers_ok_for_ldd_peep (operands[0], operands[2])
6982 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6985 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6986 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6989 [(set (match_operand:SI 0 "memory_operand" "")
6990 (match_operand:SI 1 "register_operand" ""))
6991 (set (match_operand:SI 2 "memory_operand" "")
6992 (match_operand:SI 3 "register_operand" ""))]
6993 "registers_ok_for_ldd_peep (operands[1], operands[3])
6994 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6997 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6998 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7001 [(set (match_operand:SF 0 "register_operand" "")
7002 (match_operand:SF 1 "memory_operand" ""))
7003 (set (match_operand:SF 2 "register_operand" "")
7004 (match_operand:SF 3 "memory_operand" ""))]
7005 "registers_ok_for_ldd_peep (operands[0], operands[2])
7006 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7009 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7010 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7013 [(set (match_operand:SF 0 "memory_operand" "")
7014 (match_operand:SF 1 "register_operand" ""))
7015 (set (match_operand:SF 2 "memory_operand" "")
7016 (match_operand:SF 3 "register_operand" ""))]
7017 "registers_ok_for_ldd_peep (operands[1], operands[3])
7018 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7021 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7022 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7025 [(set (match_operand:SI 0 "register_operand" "")
7026 (match_operand:SI 1 "memory_operand" ""))
7027 (set (match_operand:SI 2 "register_operand" "")
7028 (match_operand:SI 3 "memory_operand" ""))]
7029 "registers_ok_for_ldd_peep (operands[2], operands[0])
7030 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7033 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7034 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7037 [(set (match_operand:SI 0 "memory_operand" "")
7038 (match_operand:SI 1 "register_operand" ""))
7039 (set (match_operand:SI 2 "memory_operand" "")
7040 (match_operand:SI 3 "register_operand" ""))]
7041 "registers_ok_for_ldd_peep (operands[3], operands[1])
7042 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7045 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7046 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7050 [(set (match_operand:SF 0 "register_operand" "")
7051 (match_operand:SF 1 "memory_operand" ""))
7052 (set (match_operand:SF 2 "register_operand" "")
7053 (match_operand:SF 3 "memory_operand" ""))]
7054 "registers_ok_for_ldd_peep (operands[2], operands[0])
7055 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7058 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7059 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7062 [(set (match_operand:SF 0 "memory_operand" "")
7063 (match_operand:SF 1 "register_operand" ""))
7064 (set (match_operand:SF 2 "memory_operand" "")
7065 (match_operand:SF 3 "register_operand" ""))]
7066 "registers_ok_for_ldd_peep (operands[3], operands[1])
7067 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7070 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7071 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7073 ;; Optimize the case of following a reg-reg move with a test
7074 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7075 ;; This can result from a float to fix conversion.
7078 [(set (match_operand:SI 0 "register_operand" "")
7079 (match_operand:SI 1 "register_operand" ""))
7080 (set (reg:CC CC_REG)
7081 (compare:CC (match_operand:SI 2 "register_operand" "")
7083 "(rtx_equal_p (operands[2], operands[0])
7084 || rtx_equal_p (operands[2], operands[1]))
7085 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7086 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7087 [(parallel [(set (match_dup 0) (match_dup 1))
7088 (set (reg:CC CC_REG)
7089 (compare:CC (match_dup 1) (const_int 0)))])]
7093 [(set (match_operand:DI 0 "register_operand" "")
7094 (match_operand:DI 1 "register_operand" ""))
7095 (set (reg:CCX CC_REG)
7096 (compare:CCX (match_operand:DI 2 "register_operand" "")
7099 && (rtx_equal_p (operands[2], operands[0])
7100 || rtx_equal_p (operands[2], operands[1]))
7101 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7102 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7103 [(parallel [(set (match_dup 0) (match_dup 1))
7104 (set (reg:CCX CC_REG)
7105 (compare:CCX (match_dup 1) (const_int 0)))])]
7109 ;; Prefetch instructions.
7111 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7112 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7113 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7115 (define_expand "prefetch"
7116 [(match_operand 0 "address_operand" "")
7117 (match_operand 1 "const_int_operand" "")
7118 (match_operand 2 "const_int_operand" "")]
7122 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7124 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7128 (define_insn "prefetch_64"
7129 [(prefetch (match_operand:DI 0 "address_operand" "p")
7130 (match_operand:DI 1 "const_int_operand" "n")
7131 (match_operand:DI 2 "const_int_operand" "n"))]
7134 static const char * const prefetch_instr[2][2] = {
7136 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7137 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7140 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7141 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7144 int read_or_write = INTVAL (operands[1]);
7145 int locality = INTVAL (operands[2]);
7147 gcc_assert (read_or_write == 0 || read_or_write == 1);
7148 gcc_assert (locality >= 0 && locality < 4);
7149 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7151 [(set_attr "type" "load")])
7153 (define_insn "prefetch_32"
7154 [(prefetch (match_operand:SI 0 "address_operand" "p")
7155 (match_operand:SI 1 "const_int_operand" "n")
7156 (match_operand:SI 2 "const_int_operand" "n"))]
7159 static const char * const prefetch_instr[2][2] = {
7161 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7162 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7165 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7166 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7169 int read_or_write = INTVAL (operands[1]);
7170 int locality = INTVAL (operands[2]);
7172 gcc_assert (read_or_write == 0 || read_or_write == 1);
7173 gcc_assert (locality >= 0 && locality < 4);
7174 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7176 [(set_attr "type" "load")])
7179 ;; Trap instructions.
7182 [(trap_if (const_int 1) (const_int 5))]
7185 [(set_attr "type" "trap")])
7187 (define_expand "ctrapsi4"
7188 [(trap_if (match_operator 0 "noov_compare_operator"
7189 [(match_operand:SI 1 "compare_operand" "")
7190 (match_operand:SI 2 "arith_operand" "")])
7191 (match_operand 3 ""))]
7193 "operands[1] = gen_compare_reg (operands[0]);
7194 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7196 operands[2] = const0_rtx;")
7198 (define_expand "ctrapdi4"
7199 [(trap_if (match_operator 0 "noov_compare_operator"
7200 [(match_operand:DI 1 "compare_operand" "")
7201 (match_operand:DI 2 "arith_operand" "")])
7202 (match_operand 3 ""))]
7204 "operands[1] = gen_compare_reg (operands[0]);
7205 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7207 operands[2] = const0_rtx;")
7211 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7212 (match_operand:SI 1 "arith_operand" "rM"))]
7216 return "t%C0\t%%icc, %1";
7220 [(set_attr "type" "trap")])
7223 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7224 (match_operand:SI 1 "arith_operand" "rM"))]
7227 [(set_attr "type" "trap")])
7230 ;; TLS support instructions.
7232 (define_insn "tgd_hi22"
7233 [(set (match_operand:SI 0 "register_operand" "=r")
7234 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7237 "sethi\\t%%tgd_hi22(%a1), %0")
7239 (define_insn "tgd_lo10"
7240 [(set (match_operand:SI 0 "register_operand" "=r")
7241 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7242 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7245 "add\\t%1, %%tgd_lo10(%a2), %0")
7247 (define_insn "tgd_add32"
7248 [(set (match_operand:SI 0 "register_operand" "=r")
7249 (plus:SI (match_operand:SI 1 "register_operand" "r")
7250 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7251 (match_operand 3 "tgd_symbolic_operand" "")]
7253 "TARGET_TLS && TARGET_ARCH32"
7254 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7256 (define_insn "tgd_add64"
7257 [(set (match_operand:DI 0 "register_operand" "=r")
7258 (plus:DI (match_operand:DI 1 "register_operand" "r")
7259 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7260 (match_operand 3 "tgd_symbolic_operand" "")]
7262 "TARGET_TLS && TARGET_ARCH64"
7263 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7265 (define_insn "tgd_call32"
7266 [(set (match_operand 0 "register_operand" "=r")
7267 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7268 (match_operand 2 "tgd_symbolic_operand" "")]
7270 (match_operand 3 "" "")))
7271 (clobber (reg:SI O7_REG))]
7272 "TARGET_TLS && TARGET_ARCH32"
7273 "call\t%a1, %%tgd_call(%a2)%#"
7274 [(set_attr "type" "call")])
7276 (define_insn "tgd_call64"
7277 [(set (match_operand 0 "register_operand" "=r")
7278 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7279 (match_operand 2 "tgd_symbolic_operand" "")]
7281 (match_operand 3 "" "")))
7282 (clobber (reg:DI O7_REG))]
7283 "TARGET_TLS && TARGET_ARCH64"
7284 "call\t%a1, %%tgd_call(%a2)%#"
7285 [(set_attr "type" "call")])
7287 (define_insn "tldm_hi22"
7288 [(set (match_operand:SI 0 "register_operand" "=r")
7289 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7291 "sethi\\t%%tldm_hi22(%&), %0")
7293 (define_insn "tldm_lo10"
7294 [(set (match_operand:SI 0 "register_operand" "=r")
7295 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7296 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7298 "add\\t%1, %%tldm_lo10(%&), %0")
7300 (define_insn "tldm_add32"
7301 [(set (match_operand:SI 0 "register_operand" "=r")
7302 (plus:SI (match_operand:SI 1 "register_operand" "r")
7303 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7305 "TARGET_TLS && TARGET_ARCH32"
7306 "add\\t%1, %2, %0, %%tldm_add(%&)")
7308 (define_insn "tldm_add64"
7309 [(set (match_operand:DI 0 "register_operand" "=r")
7310 (plus:DI (match_operand:DI 1 "register_operand" "r")
7311 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7313 "TARGET_TLS && TARGET_ARCH64"
7314 "add\\t%1, %2, %0, %%tldm_add(%&)")
7316 (define_insn "tldm_call32"
7317 [(set (match_operand 0 "register_operand" "=r")
7318 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7320 (match_operand 2 "" "")))
7321 (clobber (reg:SI O7_REG))]
7322 "TARGET_TLS && TARGET_ARCH32"
7323 "call\t%a1, %%tldm_call(%&)%#"
7324 [(set_attr "type" "call")])
7326 (define_insn "tldm_call64"
7327 [(set (match_operand 0 "register_operand" "=r")
7328 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7330 (match_operand 2 "" "")))
7331 (clobber (reg:DI O7_REG))]
7332 "TARGET_TLS && TARGET_ARCH64"
7333 "call\t%a1, %%tldm_call(%&)%#"
7334 [(set_attr "type" "call")])
7336 (define_insn "tldo_hix22"
7337 [(set (match_operand:SI 0 "register_operand" "=r")
7338 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7341 "sethi\\t%%tldo_hix22(%a1), %0")
7343 (define_insn "tldo_lox10"
7344 [(set (match_operand:SI 0 "register_operand" "=r")
7345 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7346 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7349 "xor\\t%1, %%tldo_lox10(%a2), %0")
7351 (define_insn "tldo_add32"
7352 [(set (match_operand:SI 0 "register_operand" "=r")
7353 (plus:SI (match_operand:SI 1 "register_operand" "r")
7354 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7355 (match_operand 3 "tld_symbolic_operand" "")]
7357 "TARGET_TLS && TARGET_ARCH32"
7358 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7360 (define_insn "tldo_add64"
7361 [(set (match_operand:DI 0 "register_operand" "=r")
7362 (plus:DI (match_operand:DI 1 "register_operand" "r")
7363 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7364 (match_operand 3 "tld_symbolic_operand" "")]
7366 "TARGET_TLS && TARGET_ARCH64"
7367 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7369 (define_insn "tie_hi22"
7370 [(set (match_operand:SI 0 "register_operand" "=r")
7371 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7374 "sethi\\t%%tie_hi22(%a1), %0")
7376 (define_insn "tie_lo10"
7377 [(set (match_operand:SI 0 "register_operand" "=r")
7378 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7379 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7382 "add\\t%1, %%tie_lo10(%a2), %0")
7384 (define_insn "tie_ld32"
7385 [(set (match_operand:SI 0 "register_operand" "=r")
7386 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7387 (match_operand:SI 2 "register_operand" "r")
7388 (match_operand 3 "tie_symbolic_operand" "")]
7390 "TARGET_TLS && TARGET_ARCH32"
7391 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7392 [(set_attr "type" "load")])
7394 (define_insn "tie_ld64"
7395 [(set (match_operand:DI 0 "register_operand" "=r")
7396 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7397 (match_operand:SI 2 "register_operand" "r")
7398 (match_operand 3 "tie_symbolic_operand" "")]
7400 "TARGET_TLS && TARGET_ARCH64"
7401 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7402 [(set_attr "type" "load")])
7404 (define_insn "tie_add32"
7405 [(set (match_operand:SI 0 "register_operand" "=r")
7406 (plus:SI (match_operand:SI 1 "register_operand" "r")
7407 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7408 (match_operand 3 "tie_symbolic_operand" "")]
7410 "TARGET_SUN_TLS && TARGET_ARCH32"
7411 "add\\t%1, %2, %0, %%tie_add(%a3)")
7413 (define_insn "tie_add64"
7414 [(set (match_operand:DI 0 "register_operand" "=r")
7415 (plus:DI (match_operand:DI 1 "register_operand" "r")
7416 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7417 (match_operand 3 "tie_symbolic_operand" "")]
7419 "TARGET_SUN_TLS && TARGET_ARCH64"
7420 "add\\t%1, %2, %0, %%tie_add(%a3)")
7422 (define_insn "tle_hix22_sp32"
7423 [(set (match_operand:SI 0 "register_operand" "=r")
7424 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7426 "TARGET_TLS && TARGET_ARCH32"
7427 "sethi\\t%%tle_hix22(%a1), %0")
7429 (define_insn "tle_lox10_sp32"
7430 [(set (match_operand:SI 0 "register_operand" "=r")
7431 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7432 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7434 "TARGET_TLS && TARGET_ARCH32"
7435 "xor\\t%1, %%tle_lox10(%a2), %0")
7437 (define_insn "tle_hix22_sp64"
7438 [(set (match_operand:DI 0 "register_operand" "=r")
7439 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7441 "TARGET_TLS && TARGET_ARCH64"
7442 "sethi\\t%%tle_hix22(%a1), %0")
7444 (define_insn "tle_lox10_sp64"
7445 [(set (match_operand:DI 0 "register_operand" "=r")
7446 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7447 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7449 "TARGET_TLS && TARGET_ARCH64"
7450 "xor\\t%1, %%tle_lox10(%a2), %0")
7452 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7453 (define_insn "*tldo_ldub_sp32"
7454 [(set (match_operand:QI 0 "register_operand" "=r")
7455 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7456 (match_operand 3 "tld_symbolic_operand" "")]
7458 (match_operand:SI 1 "register_operand" "r"))))]
7459 "TARGET_TLS && TARGET_ARCH32"
7460 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7461 [(set_attr "type" "load")
7462 (set_attr "us3load_type" "3cycle")])
7464 (define_insn "*tldo_ldub1_sp32"
7465 [(set (match_operand:HI 0 "register_operand" "=r")
7466 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7467 (match_operand 3 "tld_symbolic_operand" "")]
7469 (match_operand:SI 1 "register_operand" "r")))))]
7470 "TARGET_TLS && TARGET_ARCH32"
7471 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7472 [(set_attr "type" "load")
7473 (set_attr "us3load_type" "3cycle")])
7475 (define_insn "*tldo_ldub2_sp32"
7476 [(set (match_operand:SI 0 "register_operand" "=r")
7477 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7478 (match_operand 3 "tld_symbolic_operand" "")]
7480 (match_operand:SI 1 "register_operand" "r")))))]
7481 "TARGET_TLS && TARGET_ARCH32"
7482 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7483 [(set_attr "type" "load")
7484 (set_attr "us3load_type" "3cycle")])
7486 (define_insn "*tldo_ldsb1_sp32"
7487 [(set (match_operand:HI 0 "register_operand" "=r")
7488 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7489 (match_operand 3 "tld_symbolic_operand" "")]
7491 (match_operand:SI 1 "register_operand" "r")))))]
7492 "TARGET_TLS && TARGET_ARCH32"
7493 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7494 [(set_attr "type" "sload")
7495 (set_attr "us3load_type" "3cycle")])
7497 (define_insn "*tldo_ldsb2_sp32"
7498 [(set (match_operand:SI 0 "register_operand" "=r")
7499 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7500 (match_operand 3 "tld_symbolic_operand" "")]
7502 (match_operand:SI 1 "register_operand" "r")))))]
7503 "TARGET_TLS && TARGET_ARCH32"
7504 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7505 [(set_attr "type" "sload")
7506 (set_attr "us3load_type" "3cycle")])
7508 (define_insn "*tldo_ldub_sp64"
7509 [(set (match_operand:QI 0 "register_operand" "=r")
7510 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7511 (match_operand 3 "tld_symbolic_operand" "")]
7513 (match_operand:DI 1 "register_operand" "r"))))]
7514 "TARGET_TLS && TARGET_ARCH64"
7515 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7516 [(set_attr "type" "load")
7517 (set_attr "us3load_type" "3cycle")])
7519 (define_insn "*tldo_ldub1_sp64"
7520 [(set (match_operand:HI 0 "register_operand" "=r")
7521 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7522 (match_operand 3 "tld_symbolic_operand" "")]
7524 (match_operand:DI 1 "register_operand" "r")))))]
7525 "TARGET_TLS && TARGET_ARCH64"
7526 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7527 [(set_attr "type" "load")
7528 (set_attr "us3load_type" "3cycle")])
7530 (define_insn "*tldo_ldub2_sp64"
7531 [(set (match_operand:SI 0 "register_operand" "=r")
7532 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7533 (match_operand 3 "tld_symbolic_operand" "")]
7535 (match_operand:DI 1 "register_operand" "r")))))]
7536 "TARGET_TLS && TARGET_ARCH64"
7537 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7538 [(set_attr "type" "load")
7539 (set_attr "us3load_type" "3cycle")])
7541 (define_insn "*tldo_ldub3_sp64"
7542 [(set (match_operand:DI 0 "register_operand" "=r")
7543 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7544 (match_operand 3 "tld_symbolic_operand" "")]
7546 (match_operand:DI 1 "register_operand" "r")))))]
7547 "TARGET_TLS && TARGET_ARCH64"
7548 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7549 [(set_attr "type" "load")
7550 (set_attr "us3load_type" "3cycle")])
7552 (define_insn "*tldo_ldsb1_sp64"
7553 [(set (match_operand:HI 0 "register_operand" "=r")
7554 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7555 (match_operand 3 "tld_symbolic_operand" "")]
7557 (match_operand:DI 1 "register_operand" "r")))))]
7558 "TARGET_TLS && TARGET_ARCH64"
7559 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7560 [(set_attr "type" "sload")
7561 (set_attr "us3load_type" "3cycle")])
7563 (define_insn "*tldo_ldsb2_sp64"
7564 [(set (match_operand:SI 0 "register_operand" "=r")
7565 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7566 (match_operand 3 "tld_symbolic_operand" "")]
7568 (match_operand:DI 1 "register_operand" "r")))))]
7569 "TARGET_TLS && TARGET_ARCH64"
7570 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7571 [(set_attr "type" "sload")
7572 (set_attr "us3load_type" "3cycle")])
7574 (define_insn "*tldo_ldsb3_sp64"
7575 [(set (match_operand:DI 0 "register_operand" "=r")
7576 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7577 (match_operand 3 "tld_symbolic_operand" "")]
7579 (match_operand:DI 1 "register_operand" "r")))))]
7580 "TARGET_TLS && TARGET_ARCH64"
7581 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7582 [(set_attr "type" "sload")
7583 (set_attr "us3load_type" "3cycle")])
7585 (define_insn "*tldo_lduh_sp32"
7586 [(set (match_operand:HI 0 "register_operand" "=r")
7587 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7588 (match_operand 3 "tld_symbolic_operand" "")]
7590 (match_operand:SI 1 "register_operand" "r"))))]
7591 "TARGET_TLS && TARGET_ARCH32"
7592 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7593 [(set_attr "type" "load")
7594 (set_attr "us3load_type" "3cycle")])
7596 (define_insn "*tldo_lduh1_sp32"
7597 [(set (match_operand:SI 0 "register_operand" "=r")
7598 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7599 (match_operand 3 "tld_symbolic_operand" "")]
7601 (match_operand:SI 1 "register_operand" "r")))))]
7602 "TARGET_TLS && TARGET_ARCH32"
7603 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7604 [(set_attr "type" "load")
7605 (set_attr "us3load_type" "3cycle")])
7607 (define_insn "*tldo_ldsh1_sp32"
7608 [(set (match_operand:SI 0 "register_operand" "=r")
7609 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7610 (match_operand 3 "tld_symbolic_operand" "")]
7612 (match_operand:SI 1 "register_operand" "r")))))]
7613 "TARGET_TLS && TARGET_ARCH32"
7614 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7615 [(set_attr "type" "sload")
7616 (set_attr "us3load_type" "3cycle")])
7618 (define_insn "*tldo_lduh_sp64"
7619 [(set (match_operand:HI 0 "register_operand" "=r")
7620 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7621 (match_operand 3 "tld_symbolic_operand" "")]
7623 (match_operand:DI 1 "register_operand" "r"))))]
7624 "TARGET_TLS && TARGET_ARCH64"
7625 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7626 [(set_attr "type" "load")
7627 (set_attr "us3load_type" "3cycle")])
7629 (define_insn "*tldo_lduh1_sp64"
7630 [(set (match_operand:SI 0 "register_operand" "=r")
7631 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7632 (match_operand 3 "tld_symbolic_operand" "")]
7634 (match_operand:DI 1 "register_operand" "r")))))]
7635 "TARGET_TLS && TARGET_ARCH64"
7636 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7637 [(set_attr "type" "load")
7638 (set_attr "us3load_type" "3cycle")])
7640 (define_insn "*tldo_lduh2_sp64"
7641 [(set (match_operand:DI 0 "register_operand" "=r")
7642 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7643 (match_operand 3 "tld_symbolic_operand" "")]
7645 (match_operand:DI 1 "register_operand" "r")))))]
7646 "TARGET_TLS && TARGET_ARCH64"
7647 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7648 [(set_attr "type" "load")
7649 (set_attr "us3load_type" "3cycle")])
7651 (define_insn "*tldo_ldsh1_sp64"
7652 [(set (match_operand:SI 0 "register_operand" "=r")
7653 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7654 (match_operand 3 "tld_symbolic_operand" "")]
7656 (match_operand:DI 1 "register_operand" "r")))))]
7657 "TARGET_TLS && TARGET_ARCH64"
7658 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7659 [(set_attr "type" "sload")
7660 (set_attr "us3load_type" "3cycle")])
7662 (define_insn "*tldo_ldsh2_sp64"
7663 [(set (match_operand:DI 0 "register_operand" "=r")
7664 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7665 (match_operand 3 "tld_symbolic_operand" "")]
7667 (match_operand:DI 1 "register_operand" "r")))))]
7668 "TARGET_TLS && TARGET_ARCH64"
7669 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7670 [(set_attr "type" "sload")
7671 (set_attr "us3load_type" "3cycle")])
7673 (define_insn "*tldo_lduw_sp32"
7674 [(set (match_operand:SI 0 "register_operand" "=r")
7675 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7676 (match_operand 3 "tld_symbolic_operand" "")]
7678 (match_operand:SI 1 "register_operand" "r"))))]
7679 "TARGET_TLS && TARGET_ARCH32"
7680 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7681 [(set_attr "type" "load")])
7683 (define_insn "*tldo_lduw_sp64"
7684 [(set (match_operand:SI 0 "register_operand" "=r")
7685 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7686 (match_operand 3 "tld_symbolic_operand" "")]
7688 (match_operand:DI 1 "register_operand" "r"))))]
7689 "TARGET_TLS && TARGET_ARCH64"
7690 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7691 [(set_attr "type" "load")])
7693 (define_insn "*tldo_lduw1_sp64"
7694 [(set (match_operand:DI 0 "register_operand" "=r")
7695 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7696 (match_operand 3 "tld_symbolic_operand" "")]
7698 (match_operand:DI 1 "register_operand" "r")))))]
7699 "TARGET_TLS && TARGET_ARCH64"
7700 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7701 [(set_attr "type" "load")])
7703 (define_insn "*tldo_ldsw1_sp64"
7704 [(set (match_operand:DI 0 "register_operand" "=r")
7705 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7706 (match_operand 3 "tld_symbolic_operand" "")]
7708 (match_operand:DI 1 "register_operand" "r")))))]
7709 "TARGET_TLS && TARGET_ARCH64"
7710 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7711 [(set_attr "type" "sload")
7712 (set_attr "us3load_type" "3cycle")])
7714 (define_insn "*tldo_ldx_sp64"
7715 [(set (match_operand:DI 0 "register_operand" "=r")
7716 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7717 (match_operand 3 "tld_symbolic_operand" "")]
7719 (match_operand:DI 1 "register_operand" "r"))))]
7720 "TARGET_TLS && TARGET_ARCH64"
7721 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7722 [(set_attr "type" "load")])
7724 (define_insn "*tldo_stb_sp32"
7725 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7726 (match_operand 3 "tld_symbolic_operand" "")]
7728 (match_operand:SI 1 "register_operand" "r")))
7729 (match_operand:QI 0 "register_operand" "=r"))]
7730 "TARGET_TLS && TARGET_ARCH32"
7731 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7732 [(set_attr "type" "store")])
7734 (define_insn "*tldo_stb_sp64"
7735 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7736 (match_operand 3 "tld_symbolic_operand" "")]
7738 (match_operand:DI 1 "register_operand" "r")))
7739 (match_operand:QI 0 "register_operand" "=r"))]
7740 "TARGET_TLS && TARGET_ARCH64"
7741 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7742 [(set_attr "type" "store")])
7744 (define_insn "*tldo_sth_sp32"
7745 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7746 (match_operand 3 "tld_symbolic_operand" "")]
7748 (match_operand:SI 1 "register_operand" "r")))
7749 (match_operand:HI 0 "register_operand" "=r"))]
7750 "TARGET_TLS && TARGET_ARCH32"
7751 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7752 [(set_attr "type" "store")])
7754 (define_insn "*tldo_sth_sp64"
7755 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7756 (match_operand 3 "tld_symbolic_operand" "")]
7758 (match_operand:DI 1 "register_operand" "r")))
7759 (match_operand:HI 0 "register_operand" "=r"))]
7760 "TARGET_TLS && TARGET_ARCH64"
7761 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7762 [(set_attr "type" "store")])
7764 (define_insn "*tldo_stw_sp32"
7765 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7766 (match_operand 3 "tld_symbolic_operand" "")]
7768 (match_operand:SI 1 "register_operand" "r")))
7769 (match_operand:SI 0 "register_operand" "=r"))]
7770 "TARGET_TLS && TARGET_ARCH32"
7771 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7772 [(set_attr "type" "store")])
7774 (define_insn "*tldo_stw_sp64"
7775 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7776 (match_operand 3 "tld_symbolic_operand" "")]
7778 (match_operand:DI 1 "register_operand" "r")))
7779 (match_operand:SI 0 "register_operand" "=r"))]
7780 "TARGET_TLS && TARGET_ARCH64"
7781 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7782 [(set_attr "type" "store")])
7784 (define_insn "*tldo_stx_sp64"
7785 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7786 (match_operand 3 "tld_symbolic_operand" "")]
7788 (match_operand:DI 1 "register_operand" "r")))
7789 (match_operand:DI 0 "register_operand" "=r"))]
7790 "TARGET_TLS && TARGET_ARCH64"
7791 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7792 [(set_attr "type" "store")])
7795 ;; Stack protector instructions.
7797 (define_expand "stack_protect_set"
7798 [(match_operand 0 "memory_operand" "")
7799 (match_operand 1 "memory_operand" "")]
7802 #ifdef TARGET_THREAD_SSP_OFFSET
7803 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7804 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7805 operands[1] = gen_rtx_MEM (Pmode, addr);
7808 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7810 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7814 (define_insn "stack_protect_setsi"
7815 [(set (match_operand:SI 0 "memory_operand" "=m")
7816 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7817 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7819 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7820 [(set_attr "type" "multi")
7821 (set_attr "length" "3")])
7823 (define_insn "stack_protect_setdi"
7824 [(set (match_operand:DI 0 "memory_operand" "=m")
7825 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7826 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7828 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7829 [(set_attr "type" "multi")
7830 (set_attr "length" "3")])
7832 (define_expand "stack_protect_test"
7833 [(match_operand 0 "memory_operand" "")
7834 (match_operand 1 "memory_operand" "")
7835 (match_operand 2 "" "")]
7839 #ifdef TARGET_THREAD_SSP_OFFSET
7840 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7841 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7842 operands[1] = gen_rtx_MEM (Pmode, addr);
7846 result = gen_reg_rtx (Pmode);
7847 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7848 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7849 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7853 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7854 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7855 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7856 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7861 (define_insn "stack_protect_testsi"
7862 [(set (reg:CC CC_REG)
7863 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7864 (match_operand:SI 1 "memory_operand" "m")]
7866 (set (match_scratch:SI 3 "=r") (const_int 0))
7867 (clobber (match_scratch:SI 2 "=&r"))]
7869 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7870 [(set_attr "type" "multi")
7871 (set_attr "length" "4")])
7873 (define_insn "stack_protect_testdi"
7874 [(set (match_operand:DI 0 "register_operand" "=&r")
7875 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7876 (match_operand:DI 2 "memory_operand" "m")]
7878 (set (match_scratch:DI 3 "=r") (const_int 0))]
7880 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7881 [(set_attr "type" "multi")
7882 (set_attr "length" "4")])
7885 ;; Vector instructions.
7887 (define_insn "addv2si3"
7888 [(set (match_operand:V2SI 0 "register_operand" "=e")
7889 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7890 (match_operand:V2SI 2 "register_operand" "e")))]
7892 "fpadd32\t%1, %2, %0"
7893 [(set_attr "type" "fga")
7894 (set_attr "fptype" "double")])
7896 (define_insn "addv4hi3"
7897 [(set (match_operand:V4HI 0 "register_operand" "=e")
7898 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7899 (match_operand:V4HI 2 "register_operand" "e")))]
7901 "fpadd16\t%1, %2, %0"
7902 [(set_attr "type" "fga")
7903 (set_attr "fptype" "double")])
7905 ;; fpadd32s is emitted by the addsi3 pattern.
7907 (define_insn "addv2hi3"
7908 [(set (match_operand:V2HI 0 "register_operand" "=f")
7909 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7910 (match_operand:V2HI 2 "register_operand" "f")))]
7912 "fpadd16s\t%1, %2, %0"
7913 [(set_attr "type" "fga")
7914 (set_attr "fptype" "single")])
7916 (define_insn "subv2si3"
7917 [(set (match_operand:V2SI 0 "register_operand" "=e")
7918 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7919 (match_operand:V2SI 2 "register_operand" "e")))]
7921 "fpsub32\t%1, %2, %0"
7922 [(set_attr "type" "fga")
7923 (set_attr "fptype" "double")])
7925 (define_insn "subv4hi3"
7926 [(set (match_operand:V4HI 0 "register_operand" "=e")
7927 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7928 (match_operand:V4HI 2 "register_operand" "e")))]
7930 "fpsub16\t%1, %2, %0"
7931 [(set_attr "type" "fga")
7932 (set_attr "fptype" "double")])
7934 ;; fpsub32s is emitted by the subsi3 pattern.
7936 (define_insn "subv2hi3"
7937 [(set (match_operand:V2HI 0 "register_operand" "=f")
7938 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7939 (match_operand:V2HI 2 "register_operand" "f")))]
7941 "fpsub16s\t%1, %2, %0"
7942 [(set_attr "type" "fga")
7943 (set_attr "fptype" "single")])
7945 ;; All other logical instructions have integer equivalents so they
7946 ;; are defined together.
7948 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7950 (define_insn "*nand<V64:mode>_vis"
7951 [(set (match_operand:V64 0 "register_operand" "=e")
7952 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7953 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7956 [(set_attr "type" "fga")
7957 (set_attr "fptype" "double")])
7959 (define_insn "*nand<V32:mode>_vis"
7960 [(set (match_operand:V32 0 "register_operand" "=f")
7961 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7962 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7964 "fnands\t%1, %2, %0"
7965 [(set_attr "type" "fga")
7966 (set_attr "fptype" "single")])
7968 ;; Hard to generate VIS instructions. We have builtins for these.
7970 (define_insn "fpack16_vis"
7971 [(set (match_operand:V4QI 0 "register_operand" "=f")
7972 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
7977 [(set_attr "type" "fga")
7978 (set_attr "fptype" "double")])
7980 (define_insn "fpackfix_vis"
7981 [(set (match_operand:V2HI 0 "register_operand" "=f")
7982 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
7987 [(set_attr "type" "fga")
7988 (set_attr "fptype" "double")])
7990 (define_insn "fpack32_vis"
7991 [(set (match_operand:V8QI 0 "register_operand" "=e")
7992 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7993 (match_operand:V8QI 2 "register_operand" "e")
7997 "fpack32\t%1, %2, %0"
7998 [(set_attr "type" "fga")
7999 (set_attr "fptype" "double")])
8001 (define_insn "fexpand_vis"
8002 [(set (match_operand:V4HI 0 "register_operand" "=e")
8003 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8007 [(set_attr "type" "fga")
8008 (set_attr "fptype" "double")])
8010 (define_insn "fpmerge_vis"
8011 [(set (match_operand:V8QI 0 "register_operand" "=e")
8013 (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8014 (match_operand:V4QI 2 "register_operand" "f"))
8015 (parallel [(const_int 0) (const_int 4)
8016 (const_int 1) (const_int 5)
8017 (const_int 2) (const_int 6)
8018 (const_int 3) (const_int 7)])))]
8020 "fpmerge\t%1, %2, %0"
8021 [(set_attr "type" "fga")
8022 (set_attr "fptype" "double")])
8024 (define_insn "vec_interleave_lowv8qi"
8025 [(set (match_operand:V8QI 0 "register_operand" "=e")
8027 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8028 (match_operand:V8QI 2 "register_operand" "f"))
8029 (parallel [(const_int 0) (const_int 8)
8030 (const_int 1) (const_int 9)
8031 (const_int 2) (const_int 10)
8032 (const_int 3) (const_int 11)])))]
8034 "fpmerge\t%L1, %L2, %0"
8035 [(set_attr "type" "fga")
8036 (set_attr "fptype" "double")])
8038 (define_insn "vec_interleave_highv8qi"
8039 [(set (match_operand:V8QI 0 "register_operand" "=e")
8041 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8042 (match_operand:V8QI 2 "register_operand" "f"))
8043 (parallel [(const_int 4) (const_int 12)
8044 (const_int 5) (const_int 13)
8045 (const_int 6) (const_int 14)
8046 (const_int 7) (const_int 15)])))]
8048 "fpmerge\t%H1, %H2, %0"
8049 [(set_attr "type" "fga")
8050 (set_attr "fptype" "double")])
8052 ;; Partitioned multiply instructions
8053 (define_insn "fmul8x16_vis"
8054 [(set (match_operand:V4HI 0 "register_operand" "=e")
8055 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8056 (match_operand:V4HI 2 "register_operand" "e")]
8059 "fmul8x16\t%1, %2, %0"
8060 [(set_attr "type" "fpmul")
8061 (set_attr "fptype" "double")])
8063 (define_insn "fmul8x16au_vis"
8064 [(set (match_operand:V4HI 0 "register_operand" "=e")
8065 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8066 (match_operand:V2HI 2 "register_operand" "f")]
8069 "fmul8x16au\t%1, %2, %0"
8070 [(set_attr "type" "fpmul")
8071 (set_attr "fptype" "double")])
8073 (define_insn "fmul8x16al_vis"
8074 [(set (match_operand:V4HI 0 "register_operand" "=e")
8075 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8076 (match_operand:V2HI 2 "register_operand" "f")]
8079 "fmul8x16al\t%1, %2, %0"
8080 [(set_attr "type" "fpmul")
8081 (set_attr "fptype" "double")])
8083 (define_insn "fmul8sux16_vis"
8084 [(set (match_operand:V4HI 0 "register_operand" "=e")
8085 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8086 (match_operand:V4HI 2 "register_operand" "e")]
8089 "fmul8sux16\t%1, %2, %0"
8090 [(set_attr "type" "fpmul")
8091 (set_attr "fptype" "double")])
8093 (define_insn "fmul8ulx16_vis"
8094 [(set (match_operand:V4HI 0 "register_operand" "=e")
8095 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8096 (match_operand:V4HI 2 "register_operand" "e")]
8099 "fmul8ulx16\t%1, %2, %0"
8100 [(set_attr "type" "fpmul")
8101 (set_attr "fptype" "double")])
8103 (define_insn "fmuld8sux16_vis"
8104 [(set (match_operand:V2SI 0 "register_operand" "=e")
8105 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8106 (match_operand:V2HI 2 "register_operand" "f")]
8109 "fmuld8sux16\t%1, %2, %0"
8110 [(set_attr "type" "fpmul")
8111 (set_attr "fptype" "double")])
8113 (define_insn "fmuld8ulx16_vis"
8114 [(set (match_operand:V2SI 0 "register_operand" "=e")
8115 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8116 (match_operand:V2HI 2 "register_operand" "f")]
8119 "fmuld8ulx16\t%1, %2, %0"
8120 [(set_attr "type" "fpmul")
8121 (set_attr "fptype" "double")])
8123 (define_expand "wrgsr_vis"
8124 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8127 if (! TARGET_ARCH64)
8129 emit_insn (gen_wrgsr_v8plus (operands[0]));
8134 (define_insn "*wrgsr_sp64"
8135 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8136 "TARGET_VIS && TARGET_ARCH64"
8137 "wr\t%%g0, %0, %%gsr"
8138 [(set_attr "type" "gsr")])
8140 (define_insn "wrgsr_v8plus"
8141 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8142 (clobber (match_scratch:SI 1 "=X,&h"))]
8143 "TARGET_VIS && ! TARGET_ARCH64"
8145 if (GET_CODE (operands[0]) == CONST_INT
8146 || sparc_check_64 (operands[0], insn))
8147 return "wr\t%%g0, %0, %%gsr";
8149 output_asm_insn("srl\t%L0, 0, %L0", operands);
8150 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8152 [(set_attr "type" "multi")])
8154 (define_expand "rdgsr_vis"
8155 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8158 if (! TARGET_ARCH64)
8160 emit_insn (gen_rdgsr_v8plus (operands[0]));
8165 (define_insn "*rdgsr_sp64"
8166 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8167 "TARGET_VIS && TARGET_ARCH64"
8169 [(set_attr "type" "gsr")])
8171 (define_insn "rdgsr_v8plus"
8172 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8173 (clobber (match_scratch:SI 1 "=&h"))]
8174 "TARGET_VIS && ! TARGET_ARCH64"
8176 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8178 [(set_attr "type" "multi")])
8180 ;; Using faligndata only makes sense after an alignaddr since the choice of
8181 ;; bytes to take out of each operand is dependent on the results of the last
8183 (define_insn "faligndata<V64I:mode>_vis"
8184 [(set (match_operand:V64I 0 "register_operand" "=e")
8185 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8186 (match_operand:V64I 2 "register_operand" "e")
8190 "faligndata\t%1, %2, %0"
8191 [(set_attr "type" "fga")
8192 (set_attr "fptype" "double")])
8194 (define_insn "alignaddrsi_vis"
8195 [(set (match_operand:SI 0 "register_operand" "=r")
8196 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8197 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8198 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8199 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8201 "alignaddr\t%r1, %r2, %0")
8203 (define_insn "alignaddrdi_vis"
8204 [(set (match_operand:DI 0 "register_operand" "=r")
8205 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8206 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8207 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8208 (plus:DI (match_dup 1) (match_dup 2)))]
8210 "alignaddr\t%r1, %r2, %0")
8212 (define_insn "alignaddrlsi_vis"
8213 [(set (match_operand:SI 0 "register_operand" "=r")
8214 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8215 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8216 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8217 (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8220 "alignaddrl\t%r1, %r2, %0")
8222 (define_insn "alignaddrldi_vis"
8223 [(set (match_operand:DI 0 "register_operand" "=r")
8224 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8225 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8226 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8227 (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8230 "alignaddrl\t%r1, %r2, %0")
8232 (define_insn "pdist_vis"
8233 [(set (match_operand:DI 0 "register_operand" "=e")
8234 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8235 (match_operand:V8QI 2 "register_operand" "e")
8236 (match_operand:DI 3 "register_operand" "0")]
8240 [(set_attr "type" "fga")
8241 (set_attr "fptype" "double")])
8243 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8244 ;; with the same operands.
8245 (define_insn "edge8<P:mode>_vis"
8246 [(set (reg:CC_NOOV CC_REG)
8247 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8248 (match_operand:P 2 "register_operand" "rJ"))
8250 (set (match_operand:P 0 "register_operand" "=r")
8251 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8253 "edge8\t%r1, %r2, %0"
8254 [(set_attr "type" "edge")])
8256 (define_insn "edge8l<P:mode>_vis"
8257 [(set (reg:CC_NOOV CC_REG)
8258 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8259 (match_operand:P 2 "register_operand" "rJ"))
8261 (set (match_operand:P 0 "register_operand" "=r")
8262 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8264 "edge8l\t%r1, %r2, %0"
8265 [(set_attr "type" "edge")])
8267 (define_insn "edge16<P:mode>_vis"
8268 [(set (reg:CC_NOOV CC_REG)
8269 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8270 (match_operand:P 2 "register_operand" "rJ"))
8272 (set (match_operand:P 0 "register_operand" "=r")
8273 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8275 "edge16\t%r1, %r2, %0"
8276 [(set_attr "type" "edge")])
8278 (define_insn "edge16l<P:mode>_vis"
8279 [(set (reg:CC_NOOV CC_REG)
8280 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8281 (match_operand:P 2 "register_operand" "rJ"))
8283 (set (match_operand:P 0 "register_operand" "=r")
8284 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8286 "edge16l\t%r1, %r2, %0"
8287 [(set_attr "type" "edge")])
8289 (define_insn "edge32<P:mode>_vis"
8290 [(set (reg:CC_NOOV CC_REG)
8291 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8292 (match_operand:P 2 "register_operand" "rJ"))
8294 (set (match_operand:P 0 "register_operand" "=r")
8295 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8297 "edge32\t%r1, %r2, %0"
8298 [(set_attr "type" "edge")])
8300 (define_insn "edge32l<P:mode>_vis"
8301 [(set (reg:CC_NOOV CC_REG)
8302 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8303 (match_operand:P 2 "register_operand" "rJ"))
8305 (set (match_operand:P 0 "register_operand" "=r")
8306 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8308 "edge32l\t%r1, %r2, %0"
8309 [(set_attr "type" "edge")])
8311 (define_code_iterator gcond [le ne gt eq])
8312 (define_mode_iterator GCM [V4HI V2SI])
8313 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8315 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8316 [(set (match_operand:P 0 "register_operand" "=r")
8317 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8318 (match_operand:GCM 2 "register_operand" "e"))]
8321 "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8322 [(set_attr "type" "fpmul")
8323 (set_attr "fptype" "double")])
8325 (define_insn "array8<P:mode>_vis"
8326 [(set (match_operand:P 0 "register_operand" "=r")
8327 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8328 (match_operand:P 2 "register_operand" "rJ")]
8331 "array8\t%r1, %r2, %0"
8332 [(set_attr "type" "array")])
8334 (define_insn "array16<P:mode>_vis"
8335 [(set (match_operand:P 0 "register_operand" "=r")
8336 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8337 (match_operand:P 2 "register_operand" "rJ")]
8340 "array16\t%r1, %r2, %0"
8341 [(set_attr "type" "array")])
8343 (define_insn "array32<P:mode>_vis"
8344 [(set (match_operand:P 0 "register_operand" "=r")
8345 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8346 (match_operand:P 2 "register_operand" "rJ")]
8349 "array32\t%r1, %r2, %0"
8350 [(set_attr "type" "array")])
8352 (define_insn "bmaskdi_vis"
8353 [(set (match_operand:DI 0 "register_operand" "=r")
8354 (plus:DI (match_operand:DI 1 "register_operand" "rJ")
8355 (match_operand:DI 2 "register_operand" "rJ")))
8356 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8357 (plus:DI (match_dup 1) (match_dup 2)))]
8359 "bmask\t%r1, %r2, %0"
8360 [(set_attr "type" "array")])
8362 (define_insn "bmasksi_vis"
8363 [(set (match_operand:SI 0 "register_operand" "=r")
8364 (plus:SI (match_operand:SI 1 "register_operand" "rJ")
8365 (match_operand:SI 2 "register_operand" "rJ")))
8366 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8367 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8369 "bmask\t%r1, %r2, %0"
8370 [(set_attr "type" "array")])
8372 (define_insn "bshuffle<V64I:mode>_vis"
8373 [(set (match_operand:V64I 0 "register_operand" "=e")
8374 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8375 (match_operand:V64I 2 "register_operand" "e")
8379 "bshuffle\t%1, %2, %0"
8380 [(set_attr "type" "fga")
8381 (set_attr "fptype" "double")])
8383 ;; VIS 2.0 adds edge variants which do not set the condition codes
8384 (define_insn "edge8n<P:mode>_vis"
8385 [(set (match_operand:P 0 "register_operand" "=r")
8386 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8387 (match_operand:P 2 "register_operand" "rJ")]
8390 "edge8n\t%r1, %r2, %0"
8391 [(set_attr "type" "edgen")])
8393 (define_insn "edge8ln<P:mode>_vis"
8394 [(set (match_operand:P 0 "register_operand" "=r")
8395 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8396 (match_operand:P 2 "register_operand" "rJ")]
8399 "edge8ln\t%r1, %r2, %0"
8400 [(set_attr "type" "edgen")])
8402 (define_insn "edge16n<P:mode>_vis"
8403 [(set (match_operand:P 0 "register_operand" "=r")
8404 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8405 (match_operand:P 2 "register_operand" "rJ")]
8408 "edge16n\t%r1, %r2, %0"
8409 [(set_attr "type" "edgen")])
8411 (define_insn "edge16ln<P:mode>_vis"
8412 [(set (match_operand:P 0 "register_operand" "=r")
8413 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8414 (match_operand:P 2 "register_operand" "rJ")]
8417 "edge16ln\t%r1, %r2, %0"
8418 [(set_attr "type" "edgen")])
8420 (define_insn "edge32n<P:mode>_vis"
8421 [(set (match_operand:P 0 "register_operand" "=r")
8422 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8423 (match_operand:P 2 "register_operand" "rJ")]
8426 "edge32n\t%r1, %r2, %0"
8427 [(set_attr "type" "edgen")])
8429 (define_insn "edge32ln<P:mode>_vis"
8430 [(set (match_operand:P 0 "register_operand" "=r")
8431 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8432 (match_operand:P 2 "register_operand" "rJ")]
8435 "edge32ln\t%r1, %r2, %0"
8436 [(set_attr "type" "edge")])
8438 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8439 (define_insn "cmask8<P:mode>_vis"
8440 [(set (reg:DI GSR_REG)
8441 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8447 (define_insn "cmask16<P:mode>_vis"
8448 [(set (reg:DI GSR_REG)
8449 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8455 (define_insn "cmask32<P:mode>_vis"
8456 [(set (reg:DI GSR_REG)
8457 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8463 (define_insn "fchksm16_vis"
8464 [(set (match_operand:V4HI 0 "register_operand" "=e")
8465 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8466 (match_operand:V4HI 2 "register_operand" "e")]
8469 "fchksm16\t%1, %2, %0")
8471 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8472 (define_code_attr vis3_shift_insn
8473 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8474 (define_code_attr vis3_shift_patname
8475 [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8477 (define_insn "v<vis3_shift_patname><mode>3"
8478 [(set (match_operand:V64N8 0 "register_operand" "=<vconstr>")
8479 (vis3_shift:V64N8 (match_operand:V64N8 1 "register_operand" "<vconstr>")
8480 (match_operand:V64N8 2 "register_operand" "<vconstr>")))]
8482 "<vis3_shift_insn><vbits>\t%1, %2, %0")
8484 (define_insn "pdistn<mode>_vis"
8485 [(set (match_operand:P 0 "register_operand" "=r")
8486 (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8487 (match_operand:V8QI 2 "register_operand" "e")]
8490 "pdistn\t%1, %2, %0")
8492 (define_insn "fmean16_vis"
8493 [(set (match_operand:V4HI 0 "register_operand" "=e")
8499 (match_operand:V4HI 1 "register_operand" "e"))
8501 (match_operand:V4HI 2 "register_operand" "e")))
8502 (const_vector:V4SI [(const_int 1) (const_int 1)
8503 (const_int 1) (const_int 1)]))
8506 "fmean16\t%1, %2, %0")
8508 (define_insn "fpadd64_vis"
8509 [(set (match_operand:DI 0 "register_operand" "=e")
8510 (plus:DI (match_operand:DI 1 "register_operand" "e")
8511 (match_operand:DI 2 "register_operand" "e")))]
8513 "fpadd64\t%1, %2, %0")
8515 (define_insn "fpsub64_vis"
8516 [(set (match_operand:DI 0 "register_operand" "=e")
8517 (minus:DI (match_operand:DI 1 "register_operand" "e")
8518 (match_operand:DI 2 "register_operand" "e")))]
8520 "fpsub64\t%1, %2, %0")
8522 (define_mode_iterator VASS [V4HI V2SI V2HI SI])
8523 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8524 (define_code_attr vis3_addsub_ss_insn
8525 [(ss_plus "fpadds") (ss_minus "fpsubs")])
8526 (define_code_attr vis3_addsub_ss_patname
8527 [(ss_plus "ssadd") (ss_minus "sssub")])
8529 (define_insn "<vis3_addsub_ss_patname><mode>3"
8530 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8531 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8532 (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8534 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0")
8536 (define_insn "fucmp<code>8<P:mode>_vis"
8537 [(set (match_operand:P 0 "register_operand" "=r")
8538 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8539 (match_operand:V8QI 2 "register_operand" "e"))]
8542 "fucmp<code>8\t%1, %2, %0")
8544 (define_insn "*naddsf3"
8545 [(set (match_operand:SF 0 "register_operand" "=f")
8546 (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8547 (match_operand:SF 2 "register_operand" "f"))))]
8549 "fnadds\t%1, %2, %0"
8550 [(set_attr "type" "fp")])
8552 (define_insn "*nadddf3"
8553 [(set (match_operand:DF 0 "register_operand" "=e")
8554 (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8555 (match_operand:DF 2 "register_operand" "e"))))]
8557 "fnaddd\t%1, %2, %0"
8558 [(set_attr "type" "fp")
8559 (set_attr "fptype" "double")])
8561 (define_insn "*nmulsf3"
8562 [(set (match_operand:SF 0 "register_operand" "=f")
8563 (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8564 (match_operand:SF 2 "register_operand" "f")))]
8566 "fnmuls\t%1, %2, %0"
8567 [(set_attr "type" "fpmul")])
8569 (define_insn "*nmuldf3"
8570 [(set (match_operand:DF 0 "register_operand" "=e")
8571 (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8572 (match_operand:DF 2 "register_operand" "e")))]
8574 "fnmuld\t%1, %2, %0"
8575 [(set_attr "type" "fpmul")
8576 (set_attr "fptype" "double")])
8578 (define_insn "*nmuldf3_extend"
8579 [(set (match_operand:DF 0 "register_operand" "=e")
8580 (mult:DF (neg:DF (float_extend:DF
8581 (match_operand:SF 1 "register_operand" "f")))
8583 (match_operand:SF 2 "register_operand" "f"))))]
8585 "fnsmuld\t%1, %2, %0"
8586 [(set_attr "type" "fpmul")
8587 (set_attr "fptype" "double")])
8589 (define_insn "fhaddsf_vis"
8590 [(set (match_operand:SF 0 "register_operand" "=f")
8591 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8592 (match_operand:SF 2 "register_operand" "f")]
8595 "fhadds\t%1, %2, %0"
8596 [(set_attr "type" "fp")])
8598 (define_insn "fhadddf_vis"
8599 [(set (match_operand:DF 0 "register_operand" "=f")
8600 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8601 (match_operand:DF 2 "register_operand" "f")]
8604 "fhaddd\t%1, %2, %0"
8605 [(set_attr "type" "fp")
8606 (set_attr "fptype" "double")])
8608 (define_insn "fhsubsf_vis"
8609 [(set (match_operand:SF 0 "register_operand" "=f")
8610 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8611 (match_operand:SF 2 "register_operand" "f")]
8614 "fhsubs\t%1, %2, %0"
8615 [(set_attr "type" "fp")])
8617 (define_insn "fhsubdf_vis"
8618 [(set (match_operand:DF 0 "register_operand" "=f")
8619 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8620 (match_operand:DF 2 "register_operand" "f")]
8623 "fhsubd\t%1, %2, %0"
8624 [(set_attr "type" "fp")
8625 (set_attr "fptype" "double")])
8627 (define_insn "fnhaddsf_vis"
8628 [(set (match_operand:SF 0 "register_operand" "=f")
8629 (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8630 (match_operand:SF 2 "register_operand" "f")]
8633 "fnhadds\t%1, %2, %0"
8634 [(set_attr "type" "fp")])
8636 (define_insn "fnhadddf_vis"
8637 [(set (match_operand:DF 0 "register_operand" "=f")
8638 (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8639 (match_operand:DF 2 "register_operand" "f")]
8642 "fnhaddd\t%1, %2, %0"
8643 [(set_attr "type" "fp")
8644 (set_attr "fptype" "double")])
8646 (define_expand "umulxhi_vis"
8647 [(set (match_operand:DI 0 "register_operand" "")
8650 (mult:TI (zero_extend:TI
8651 (match_operand:DI 1 "arith_operand" ""))
8653 (match_operand:DI 2 "arith_operand" "")))
8657 if (! TARGET_ARCH64)
8659 emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8664 (define_insn "*umulxhi_sp64"
8665 [(set (match_operand:DI 0 "register_operand" "=r")
8668 (mult:TI (zero_extend:TI
8669 (match_operand:DI 1 "arith_operand" "%r"))
8671 (match_operand:DI 2 "arith_operand" "rI")))
8673 "TARGET_VIS3 && TARGET_ARCH64"
8674 "umulxhi\t%1, %2, %0"
8675 [(set_attr "type" "imul")])
8677 (define_insn "umulxhi_v8plus"
8678 [(set (match_operand:DI 0 "register_operand" "=r,h")
8681 (mult:TI (zero_extend:TI
8682 (match_operand:DI 1 "arith_operand" "%r,0"))
8684 (match_operand:DI 2 "arith_operand" "rI,rI")))
8686 (clobber (match_scratch:SI 3 "=&h,X"))
8687 (clobber (match_scratch:SI 4 "=&h,X"))]
8688 "TARGET_VIS3 && ! TARGET_ARCH64"
8689 "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8690 [(set_attr "type" "imul")
8691 (set_attr "length" "9,8")])
8693 (define_expand "xmulx_vis"
8694 [(set (match_operand:DI 0 "register_operand" "")
8696 (unspec:TI [(zero_extend:TI
8697 (match_operand:DI 1 "arith_operand" ""))
8699 (match_operand:DI 2 "arith_operand" ""))]
8703 if (! TARGET_ARCH64)
8705 emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8710 (define_insn "*xmulx_sp64"
8711 [(set (match_operand:DI 0 "register_operand" "=r")
8713 (unspec:TI [(zero_extend:TI
8714 (match_operand:DI 1 "arith_operand" "%r"))
8716 (match_operand:DI 2 "arith_operand" "rI"))]
8718 "TARGET_VIS3 && TARGET_ARCH64"
8720 [(set_attr "type" "imul")])
8722 (define_insn "xmulx_v8plus"
8723 [(set (match_operand:DI 0 "register_operand" "=r,h")
8725 (unspec:TI [(zero_extend:TI
8726 (match_operand:DI 1 "arith_operand" "%r,0"))
8728 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8730 (clobber (match_scratch:SI 3 "=&h,X"))
8731 (clobber (match_scratch:SI 4 "=&h,X"))]
8732 "TARGET_VIS3 && ! TARGET_ARCH64"
8733 "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8734 [(set_attr "type" "imul")
8735 (set_attr "length" "9,8")])
8737 (define_expand "xmulxhi_vis"
8738 [(set (match_operand:DI 0 "register_operand" "")
8741 (unspec:TI [(zero_extend:TI
8742 (match_operand:DI 1 "arith_operand" ""))
8744 (match_operand:DI 2 "arith_operand" ""))]
8749 if (! TARGET_ARCH64)
8751 emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
8756 (define_insn "*xmulxhi_sp64"
8757 [(set (match_operand:DI 0 "register_operand" "=r")
8760 (unspec:TI [(zero_extend:TI
8761 (match_operand:DI 1 "arith_operand" "%r"))
8763 (match_operand:DI 2 "arith_operand" "rI"))]
8766 "TARGET_VIS3 && TARGET_ARCH64"
8767 "xmulxhi\t%1, %2, %0"
8768 [(set_attr "type" "imul")])
8770 (define_insn "xmulxhi_v8plus"
8771 [(set (match_operand:DI 0 "register_operand" "=r,h")
8774 (unspec:TI [(zero_extend:TI
8775 (match_operand:DI 1 "arith_operand" "%r,0"))
8777 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8780 (clobber (match_scratch:SI 3 "=&h,X"))
8781 (clobber (match_scratch:SI 4 "=&h,X"))]
8782 "TARGET_VIS3 && !TARGET_ARCH64"
8783 "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
8784 [(set_attr "type" "imul")
8785 (set_attr "length" "9,8")])