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 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
204 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
205 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
206 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
207 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
209 ;; Attribute for cpu type.
210 ;; These must match the values for enum processor_type in sparc.h.
231 (const (symbol_ref "sparc_cpu_attr")))
233 ;; Attribute for the instruction set.
234 ;; At present we only need to distinguish v9/!v9, but for clarity we
235 ;; test TARGET_V8 too.
236 (define_attr "isa" "v7,v8,v9,sparclet"
238 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
239 (symbol_ref "TARGET_V8") (const_string "v8")
240 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
241 (const_string "v7"))))
243 (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3" (const_string "none"))
245 (define_attr "enabled" ""
246 (cond [(eq_attr "cpu_feature" "none") (const_int 1)
247 (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU")
248 (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && ! TARGET_V9")
249 (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9")
250 (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS")
251 (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")]
258 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
266 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,edgen,gsr,array,
269 multi,savew,flushw,iflush,trap"
270 (const_string "ialu"))
272 ;; True if branch/call has empty delay slot and will emit a nop in it
273 (define_attr "empty_delay_slot" "false,true"
274 (symbol_ref "(empty_delay_slot (insn)
275 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
277 (define_attr "branch_type" "none,icc,fcc,reg"
278 (const_string "none"))
280 (define_attr "pic" "false,true"
281 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
283 (define_attr "calls_alloca" "false,true"
284 (symbol_ref "(cfun->calls_alloca != 0
285 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
287 (define_attr "calls_eh_return" "false,true"
288 (symbol_ref "(crtl->calls_eh_return != 0
289 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
291 (define_attr "leaf_function" "false,true"
292 (symbol_ref "(current_function_uses_only_leaf_regs != 0
293 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
295 (define_attr "delayed_branch" "false,true"
296 (symbol_ref "(flag_delayed_branch != 0
297 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
299 (define_attr "flat" "false,true"
300 (symbol_ref "(TARGET_FLAT != 0
301 ? FLAT_TRUE : FLAT_FALSE)"))
303 ;; Length (in # of insns).
304 ;; Beware that setting a length greater or equal to 3 for conditional branches
305 ;; has a side-effect (see output_cbranch and output_v9branch).
306 (define_attr "length" ""
307 (cond [(eq_attr "type" "uncond_branch,call")
308 (if_then_else (eq_attr "empty_delay_slot" "true")
311 (eq_attr "type" "sibcall")
312 (if_then_else (eq_attr "leaf_function" "true")
313 (if_then_else (eq_attr "empty_delay_slot" "true")
316 (if_then_else (eq_attr "empty_delay_slot" "true")
319 (eq_attr "branch_type" "icc")
320 (if_then_else (match_operand 0 "noov_compare64_operator" "")
321 (if_then_else (lt (pc) (match_dup 1))
322 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
323 (if_then_else (eq_attr "empty_delay_slot" "true")
326 (if_then_else (eq_attr "empty_delay_slot" "true")
329 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
330 (if_then_else (eq_attr "empty_delay_slot" "true")
333 (if_then_else (eq_attr "empty_delay_slot" "true")
336 (if_then_else (eq_attr "empty_delay_slot" "true")
339 (eq_attr "branch_type" "fcc")
340 (if_then_else (match_operand 0 "fcc0_register_operand" "")
341 (if_then_else (eq_attr "empty_delay_slot" "true")
342 (if_then_else (not (match_test "TARGET_V9"))
345 (if_then_else (not (match_test "TARGET_V9"))
348 (if_then_else (lt (pc) (match_dup 2))
349 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
350 (if_then_else (eq_attr "empty_delay_slot" "true")
353 (if_then_else (eq_attr "empty_delay_slot" "true")
356 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
357 (if_then_else (eq_attr "empty_delay_slot" "true")
360 (if_then_else (eq_attr "empty_delay_slot" "true")
363 (eq_attr "branch_type" "reg")
364 (if_then_else (lt (pc) (match_dup 2))
365 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
366 (if_then_else (eq_attr "empty_delay_slot" "true")
369 (if_then_else (eq_attr "empty_delay_slot" "true")
372 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
373 (if_then_else (eq_attr "empty_delay_slot" "true")
376 (if_then_else (eq_attr "empty_delay_slot" "true")
382 (define_attr "fptype" "single,double"
383 (const_string "single"))
385 ;; UltraSPARC-III integer load type.
386 (define_attr "us3load_type" "2cycle,3cycle"
387 (const_string "2cycle"))
389 (define_asm_attributes
390 [(set_attr "length" "2")
391 (set_attr "type" "multi")])
393 ;; Attributes for instruction and branch scheduling
394 (define_attr "tls_call_delay" "false,true"
395 (symbol_ref "(tls_call_delay (insn)
396 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
398 (define_attr "in_call_delay" "false,true"
399 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
400 (const_string "false")
401 (eq_attr "type" "load,fpload,store,fpstore")
402 (if_then_else (eq_attr "length" "1")
403 (const_string "true")
404 (const_string "false"))]
405 (if_then_else (and (eq_attr "length" "1")
406 (eq_attr "tls_call_delay" "true"))
407 (const_string "true")
408 (const_string "false"))))
410 (define_attr "eligible_for_sibcall_delay" "false,true"
411 (symbol_ref "(eligible_for_sibcall_delay (insn)
412 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
413 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
415 (define_attr "eligible_for_return_delay" "false,true"
416 (symbol_ref "(eligible_for_return_delay (insn)
417 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
418 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
420 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
421 ;; branches. This would allow us to remove the nop always inserted before
422 ;; a floating point branch.
424 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
425 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
426 ;; This is because doing so will add several pipeline stalls to the path
427 ;; that the load/store did not come from. Unfortunately, there is no way
428 ;; to prevent fill_eager_delay_slots from using load/store without completely
429 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
430 ;; because it prevents us from moving back the final store of inner loops.
432 (define_attr "in_branch_delay" "false,true"
433 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
434 (eq_attr "length" "1"))
435 (const_string "true")
436 (const_string "false")))
438 (define_attr "in_uncond_branch_delay" "false,true"
439 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
440 (eq_attr "length" "1"))
441 (const_string "true")
442 (const_string "false")))
444 (define_attr "in_annul_branch_delay" "false,true"
445 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
446 (eq_attr "length" "1"))
447 (const_string "true")
448 (const_string "false")))
450 (define_delay (eq_attr "type" "call")
451 [(eq_attr "in_call_delay" "true") (nil) (nil)])
453 (define_delay (eq_attr "type" "sibcall")
454 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
456 (define_delay (eq_attr "type" "branch")
457 [(eq_attr "in_branch_delay" "true")
458 (nil) (eq_attr "in_annul_branch_delay" "true")])
460 (define_delay (eq_attr "type" "uncond_branch")
461 [(eq_attr "in_uncond_branch_delay" "true")
464 (define_delay (eq_attr "type" "return")
465 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
468 ;; Include SPARC DFA schedulers
470 (include "cypress.md")
471 (include "supersparc.md")
472 (include "hypersparc.md")
474 (include "sparclet.md")
475 (include "ultra1_2.md")
476 (include "ultra3.md")
477 (include "niagara.md")
478 (include "niagara2.md")
481 ;; Operand and operator predicates and constraints
483 (include "predicates.md")
484 (include "constraints.md")
487 ;; Compare instructions.
489 ;; These are just the DEFINE_INSNs to match the patterns and the
490 ;; DEFINE_SPLITs for some of the scc insns that actually require
491 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
493 ;; The compare DEFINE_INSNs.
495 (define_insn "*cmpsi_insn"
496 [(set (reg:CC CC_REG)
497 (compare:CC (match_operand:SI 0 "register_operand" "r")
498 (match_operand:SI 1 "arith_operand" "rI")))]
501 [(set_attr "type" "compare")])
503 (define_insn "*cmpdi_sp64"
504 [(set (reg:CCX CC_REG)
505 (compare:CCX (match_operand:DI 0 "register_operand" "r")
506 (match_operand:DI 1 "arith_operand" "rI")))]
509 [(set_attr "type" "compare")])
511 (define_insn "*cmpsf_fpe"
512 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
513 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
514 (match_operand:SF 2 "register_operand" "f")))]
518 return "fcmpes\t%0, %1, %2";
519 return "fcmpes\t%1, %2";
521 [(set_attr "type" "fpcmp")])
523 (define_insn "*cmpdf_fpe"
524 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
525 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
526 (match_operand:DF 2 "register_operand" "e")))]
530 return "fcmped\t%0, %1, %2";
531 return "fcmped\t%1, %2";
533 [(set_attr "type" "fpcmp")
534 (set_attr "fptype" "double")])
536 (define_insn "*cmptf_fpe"
537 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
538 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
539 (match_operand:TF 2 "register_operand" "e")))]
540 "TARGET_FPU && TARGET_HARD_QUAD"
543 return "fcmpeq\t%0, %1, %2";
544 return "fcmpeq\t%1, %2";
546 [(set_attr "type" "fpcmp")])
548 (define_insn "*cmpsf_fp"
549 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
550 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
551 (match_operand:SF 2 "register_operand" "f")))]
555 return "fcmps\t%0, %1, %2";
556 return "fcmps\t%1, %2";
558 [(set_attr "type" "fpcmp")])
560 (define_insn "*cmpdf_fp"
561 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
562 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
563 (match_operand:DF 2 "register_operand" "e")))]
567 return "fcmpd\t%0, %1, %2";
568 return "fcmpd\t%1, %2";
570 [(set_attr "type" "fpcmp")
571 (set_attr "fptype" "double")])
573 (define_insn "*cmptf_fp"
574 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
575 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
576 (match_operand:TF 2 "register_operand" "e")))]
577 "TARGET_FPU && TARGET_HARD_QUAD"
580 return "fcmpq\t%0, %1, %2";
581 return "fcmpq\t%1, %2";
583 [(set_attr "type" "fpcmp")])
585 ;; Next come the scc insns.
587 (define_expand "cstoresi4"
588 [(use (match_operator 1 "comparison_operator"
589 [(match_operand:SI 2 "compare_operand" "")
590 (match_operand:SI 3 "arith_operand" "")]))
591 (clobber (match_operand:SI 0 "register_operand"))]
594 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
595 operands[2] = force_reg (SImode, operands[2]);
596 if (emit_scc_insn (operands)) DONE; else FAIL;
599 (define_expand "cstoredi4"
600 [(use (match_operator 1 "comparison_operator"
601 [(match_operand:DI 2 "compare_operand" "")
602 (match_operand:DI 3 "arith_operand" "")]))
603 (clobber (match_operand:SI 0 "register_operand"))]
606 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
607 operands[2] = force_reg (DImode, operands[2]);
608 if (emit_scc_insn (operands)) DONE; else FAIL;
611 (define_expand "cstore<F:mode>4"
612 [(use (match_operator 1 "comparison_operator"
613 [(match_operand:F 2 "register_operand" "")
614 (match_operand:F 3 "register_operand" "")]))
615 (clobber (match_operand:SI 0 "register_operand"))]
617 { if (emit_scc_insn (operands)) DONE; else FAIL; })
621 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
622 ;; generate addcc/subcc instructions.
624 (define_expand "seqsi_special"
626 (xor:SI (match_operand:SI 1 "register_operand" "")
627 (match_operand:SI 2 "register_operand" "")))
628 (parallel [(set (match_operand:SI 0 "register_operand" "")
629 (eq:SI (match_dup 3) (const_int 0)))
630 (clobber (reg:CC CC_REG))])]
632 { operands[3] = gen_reg_rtx (SImode); })
634 (define_expand "seqdi_special"
636 (xor:DI (match_operand:DI 1 "register_operand" "")
637 (match_operand:DI 2 "register_operand" "")))
638 (set (match_operand:SI 0 "register_operand" "")
639 (eq:SI (match_dup 3) (const_int 0)))]
641 { operands[3] = gen_reg_rtx (DImode); })
643 (define_expand "snesi_special"
645 (xor:SI (match_operand:SI 1 "register_operand" "")
646 (match_operand:SI 2 "register_operand" "")))
647 (parallel [(set (match_operand:SI 0 "register_operand" "")
648 (ne:SI (match_dup 3) (const_int 0)))
649 (clobber (reg:CC CC_REG))])]
651 { operands[3] = gen_reg_rtx (SImode); })
653 (define_expand "snedi_special"
655 (xor:DI (match_operand:DI 1 "register_operand" "")
656 (match_operand:DI 2 "register_operand" "")))
657 (set (match_operand:SI 0 "register_operand" "")
658 (ne:SI (match_dup 3) (const_int 0)))]
659 "TARGET_ARCH64 && ! TARGET_VIS3"
660 { operands[3] = gen_reg_rtx (DImode); })
662 (define_expand "snedi_special_vis3"
664 (xor:DI (match_operand:DI 1 "register_operand" "")
665 (match_operand:DI 2 "register_operand" "")))
666 (parallel [(set (match_operand:SI 0 "register_operand" "")
667 (ne:SI (match_dup 3) (const_int 0)))
668 (clobber (reg:CCX CC_REG))])]
669 "TARGET_ARCH64 && TARGET_VIS3"
670 { operands[3] = gen_reg_rtx (DImode); })
673 ;; Now the DEFINE_INSNs for the scc cases.
675 ;; The SEQ and SNE patterns are special because they can be done
676 ;; without any branching and do not involve a COMPARE. We want
677 ;; them to always use the splits below so the results can be
680 (define_insn_and_split "*snesi_zero"
681 [(set (match_operand:SI 0 "register_operand" "=r")
682 (ne:SI (match_operand:SI 1 "register_operand" "r")
684 (clobber (reg:CC CC_REG))]
688 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
690 (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
692 [(set_attr "length" "2")])
694 (define_insn_and_split "*neg_snesi_zero"
695 [(set (match_operand:SI 0 "register_operand" "=r")
696 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
698 (clobber (reg:CC CC_REG))]
702 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
704 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
706 [(set_attr "length" "2")])
708 (define_insn_and_split "*snesi_zero_extend"
709 [(set (match_operand:DI 0 "register_operand" "=r")
710 (ne:DI (match_operand:SI 1 "register_operand" "r")
712 (clobber (reg:CC CC_REG))]
716 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
719 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
721 (ltu:SI (reg:CC_NOOV CC_REG)
724 [(set_attr "length" "2")])
726 (define_insn_and_split "*neg_snesi_sign_extend"
727 [(set (match_operand:DI 0 "register_operand" "=r")
728 (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r")
730 (clobber (reg:CC CC_REG))]
734 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
737 (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG)
740 [(set_attr "length" "2")])
742 (define_insn_and_split "*snedi_zero"
743 [(set (match_operand:DI 0 "register_operand" "=&r")
744 (ne:DI (match_operand:DI 1 "register_operand" "r")
746 "TARGET_ARCH64 && ! TARGET_VIS3"
748 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
749 [(set (match_dup 0) (const_int 0))
750 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
755 [(set_attr "length" "2")])
757 (define_insn_and_split "*snedi_zero_vis3"
758 [(set (match_operand:DI 0 "register_operand" "=r")
759 (ne:DI (match_operand:DI 1 "register_operand" "r")
761 (clobber (reg:CCX CC_REG))]
762 "TARGET_ARCH64 && TARGET_VIS3"
765 [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
767 (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
769 [(set_attr "length" "2")])
771 (define_insn_and_split "*neg_snedi_zero"
772 [(set (match_operand:DI 0 "register_operand" "=&r")
773 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
777 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
778 [(set (match_dup 0) (const_int 0))
779 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
784 [(set_attr "length" "2")])
786 (define_insn_and_split "*snedi_zero_trunc"
787 [(set (match_operand:SI 0 "register_operand" "=&r")
788 (ne:SI (match_operand:DI 1 "register_operand" "r")
790 "TARGET_ARCH64 && ! TARGET_VIS3"
792 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
793 [(set (match_dup 0) (const_int 0))
794 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
799 [(set_attr "length" "2")])
801 (define_insn_and_split "*snedi_zero_trunc_vis3"
802 [(set (match_operand:SI 0 "register_operand" "=r")
803 (ne:SI (match_operand:DI 1 "register_operand" "r")
805 (clobber (reg:CCX CC_REG))]
806 "TARGET_ARCH64 && TARGET_VIS3"
809 [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
811 (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
813 [(set_attr "length" "2")])
815 (define_insn_and_split "*seqsi_zero"
816 [(set (match_operand:SI 0 "register_operand" "=r")
817 (eq:SI (match_operand:SI 1 "register_operand" "r")
819 (clobber (reg:CC CC_REG))]
823 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
825 (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
827 [(set_attr "length" "2")])
829 (define_insn_and_split "*neg_seqsi_zero"
830 [(set (match_operand:SI 0 "register_operand" "=r")
831 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
833 (clobber (reg:CC CC_REG))]
837 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
839 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
841 [(set_attr "length" "2")])
843 (define_insn_and_split "*seqsi_zero_extend"
844 [(set (match_operand:DI 0 "register_operand" "=r")
845 (eq:DI (match_operand:SI 1 "register_operand" "r")
847 (clobber (reg:CC CC_REG))]
851 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
854 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
856 (ltu:SI (reg:CC_NOOV CC_REG)
859 [(set_attr "length" "2")])
861 (define_insn_and_split "*neg_seqsi_sign_extend"
862 [(set (match_operand:DI 0 "register_operand" "=r")
863 (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r")
865 (clobber (reg:CC CC_REG))]
869 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
871 (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG)
874 [(set_attr "length" "2")])
876 (define_insn_and_split "*seqdi_zero"
877 [(set (match_operand:DI 0 "register_operand" "=&r")
878 (eq:DI (match_operand:DI 1 "register_operand" "r")
882 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
883 [(set (match_dup 0) (const_int 0))
884 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
889 [(set_attr "length" "2")])
891 (define_insn_and_split "*neg_seqdi_zero"
892 [(set (match_operand:DI 0 "register_operand" "=&r")
893 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
897 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
898 [(set (match_dup 0) (const_int 0))
899 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
904 [(set_attr "length" "2")])
906 (define_insn_and_split "*seqdi_zero_trunc"
907 [(set (match_operand:SI 0 "register_operand" "=&r")
908 (eq:SI (match_operand:DI 1 "register_operand" "r")
912 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
913 [(set (match_dup 0) (const_int 0))
914 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
919 [(set_attr "length" "2")])
921 ;; We can also do (x + (i == 0)) and related, so put them in.
922 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
925 (define_insn_and_split "*x_plus_i_ne_0"
926 [(set (match_operand:SI 0 "register_operand" "=r")
927 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
929 (match_operand:SI 2 "register_operand" "r")))
930 (clobber (reg:CC CC_REG))]
934 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
936 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
939 [(set_attr "length" "2")])
941 (define_insn_and_split "*x_minus_i_ne_0"
942 [(set (match_operand:SI 0 "register_operand" "=r")
943 (minus:SI (match_operand:SI 2 "register_operand" "r")
944 (ne:SI (match_operand:SI 1 "register_operand" "r")
946 (clobber (reg:CC CC_REG))]
950 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
952 (set (match_dup 0) (minus:SI (match_dup 2)
953 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
955 [(set_attr "length" "2")])
957 (define_insn_and_split "*x_plus_i_eq_0"
958 [(set (match_operand:SI 0 "register_operand" "=r")
959 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
961 (match_operand:SI 2 "register_operand" "r")))
962 (clobber (reg:CC CC_REG))]
966 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
968 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
971 [(set_attr "length" "2")])
973 (define_insn_and_split "*x_minus_i_eq_0"
974 [(set (match_operand:SI 0 "register_operand" "=r")
975 (minus:SI (match_operand:SI 2 "register_operand" "r")
976 (eq:SI (match_operand:SI 1 "register_operand" "r")
978 (clobber (reg:CC CC_REG))]
982 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
984 (set (match_dup 0) (minus:SI (match_dup 2)
985 (geu:SI (reg:CC CC_REG) (const_int 0))))]
987 [(set_attr "length" "2")])
989 ;; We can also do GEU and LTU directly, but these operate after a compare.
990 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
993 (define_insn "*sltu_insn"
994 [(set (match_operand:SI 0 "register_operand" "=r")
995 (ltu:SI (reg:CC CC_REG) (const_int 0)))]
998 [(set_attr "type" "ialuX")])
1000 (define_insn "*sltu_insn_vis3"
1001 [(set (match_operand:DI 0 "register_operand" "=r")
1002 (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
1003 "TARGET_ARCH64 && TARGET_VIS3"
1004 "addxc\t%%g0, %%g0, %0"
1005 [(set_attr "type" "ialuX")])
1007 (define_insn "*sltu_insn_vis3_trunc"
1008 [(set (match_operand:SI 0 "register_operand" "=r")
1009 (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
1010 "TARGET_ARCH64 && TARGET_VIS3"
1011 "addxc\t%%g0, %%g0, %0"
1012 [(set_attr "type" "ialuX")])
1014 (define_insn "*sltu_extend_sp64"
1015 [(set (match_operand:DI 0 "register_operand" "=r")
1016 (ltu:DI (reg:CC CC_REG) (const_int 0)))]
1019 [(set_attr "type" "ialuX")])
1021 (define_insn "*neg_sltu_insn"
1022 [(set (match_operand:SI 0 "register_operand" "=r")
1023 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1026 [(set_attr "type" "ialuX")])
1028 (define_insn "*neg_sltu_extend_sp64"
1029 [(set (match_operand:DI 0 "register_operand" "=r")
1030 (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))]
1033 [(set_attr "type" "ialuX")])
1035 ;; ??? Combine should canonicalize these next two to the same pattern.
1036 (define_insn "*neg_sltu_minus_x"
1037 [(set (match_operand:SI 0 "register_operand" "=r")
1038 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
1039 (match_operand:SI 1 "arith_operand" "rI")))]
1041 "subx\t%%g0, %1, %0"
1042 [(set_attr "type" "ialuX")])
1044 (define_insn "*neg_sltu_plus_x"
1045 [(set (match_operand:SI 0 "register_operand" "=r")
1046 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1047 (match_operand:SI 1 "arith_operand" "rI"))))]
1049 "subx\t%%g0, %1, %0"
1050 [(set_attr "type" "ialuX")])
1052 (define_insn "*sgeu_insn"
1053 [(set (match_operand:SI 0 "register_operand" "=r")
1054 (geu:SI (reg:CC CC_REG) (const_int 0)))]
1056 "subx\t%%g0, -1, %0"
1057 [(set_attr "type" "ialuX")])
1059 (define_insn "*sgeu_extend_sp64"
1060 [(set (match_operand:DI 0 "register_operand" "=r")
1061 (geu:DI (reg:CC CC_REG) (const_int 0)))]
1063 "subx\t%%g0, -1, %0"
1064 [(set_attr "type" "ialuX")])
1066 (define_insn "*neg_sgeu_insn"
1067 [(set (match_operand:SI 0 "register_operand" "=r")
1068 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
1070 "addx\t%%g0, -1, %0"
1071 [(set_attr "type" "ialuX")])
1073 (define_insn "*neg_sgeu_extend_sp64"
1074 [(set (match_operand:DI 0 "register_operand" "=r")
1075 (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))]
1077 "addx\t%%g0, -1, %0"
1078 [(set_attr "type" "ialuX")])
1080 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1081 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1084 (define_insn "*sltu_plus_x"
1085 [(set (match_operand:SI 0 "register_operand" "=r")
1086 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1087 (match_operand:SI 1 "arith_operand" "rI")))]
1089 "addx\t%%g0, %1, %0"
1090 [(set_attr "type" "ialuX")])
1092 (define_insn "*sltu_plus_x_plus_y"
1093 [(set (match_operand:SI 0 "register_operand" "=r")
1094 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1095 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1096 (match_operand:SI 2 "arith_operand" "rI"))))]
1099 [(set_attr "type" "ialuX")])
1101 (define_insn "*x_minus_sltu"
1102 [(set (match_operand:SI 0 "register_operand" "=r")
1103 (minus:SI (match_operand:SI 1 "register_operand" "r")
1104 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1107 [(set_attr "type" "ialuX")])
1109 ;; ??? Combine should canonicalize these next two to the same pattern.
1110 (define_insn "*x_minus_y_minus_sltu"
1111 [(set (match_operand:SI 0 "register_operand" "=r")
1112 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1113 (match_operand:SI 2 "arith_operand" "rI"))
1114 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1117 [(set_attr "type" "ialuX")])
1119 (define_insn "*x_minus_sltu_plus_y"
1120 [(set (match_operand:SI 0 "register_operand" "=r")
1121 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1122 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1123 (match_operand:SI 2 "arith_operand" "rI"))))]
1126 [(set_attr "type" "ialuX")])
1128 (define_insn "*sgeu_plus_x"
1129 [(set (match_operand:SI 0 "register_operand" "=r")
1130 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1131 (match_operand:SI 1 "register_operand" "r")))]
1134 [(set_attr "type" "ialuX")])
1136 (define_insn "*x_minus_sgeu"
1137 [(set (match_operand:SI 0 "register_operand" "=r")
1138 (minus:SI (match_operand:SI 1 "register_operand" "r")
1139 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1142 [(set_attr "type" "ialuX")])
1145 [(set (match_operand:SI 0 "register_operand" "")
1146 (match_operator:SI 2 "noov_compare_operator"
1147 [(match_operand 1 "icc_or_fcc_register_operand" "")
1150 && REGNO (operands[1]) == SPARC_ICC_REG
1151 && (GET_MODE (operands[1]) == CCXmode
1152 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1153 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1154 [(set (match_dup 0) (const_int 0))
1156 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1162 ;; These control RTL generation for conditional jump insns
1164 (define_expand "cbranchcc4"
1166 (if_then_else (match_operator 0 "comparison_operator"
1167 [(match_operand 1 "compare_operand" "")
1168 (match_operand 2 "const_zero_operand" "")])
1169 (label_ref (match_operand 3 "" ""))
1174 (define_expand "cbranchsi4"
1175 [(use (match_operator 0 "comparison_operator"
1176 [(match_operand:SI 1 "compare_operand" "")
1177 (match_operand:SI 2 "arith_operand" "")]))
1178 (use (match_operand 3 ""))]
1181 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1182 operands[1] = force_reg (SImode, operands[1]);
1183 emit_conditional_branch_insn (operands);
1187 (define_expand "cbranchdi4"
1188 [(use (match_operator 0 "comparison_operator"
1189 [(match_operand:DI 1 "compare_operand" "")
1190 (match_operand:DI 2 "arith_operand" "")]))
1191 (use (match_operand 3 ""))]
1194 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1195 operands[1] = force_reg (DImode, operands[1]);
1196 emit_conditional_branch_insn (operands);
1200 (define_expand "cbranch<F:mode>4"
1201 [(use (match_operator 0 "comparison_operator"
1202 [(match_operand:F 1 "register_operand" "")
1203 (match_operand:F 2 "register_operand" "")]))
1204 (use (match_operand 3 ""))]
1206 { emit_conditional_branch_insn (operands); DONE; })
1209 ;; Now match both normal and inverted jump.
1211 ;; XXX fpcmp nop braindamage
1212 (define_insn "*normal_branch"
1214 (if_then_else (match_operator 0 "noov_compare_operator"
1215 [(reg CC_REG) (const_int 0)])
1216 (label_ref (match_operand 1 "" ""))
1220 return output_cbranch (operands[0], operands[1], 1, 0,
1221 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1224 [(set_attr "type" "branch")
1225 (set_attr "branch_type" "icc")])
1227 ;; XXX fpcmp nop braindamage
1228 (define_insn "*inverted_branch"
1230 (if_then_else (match_operator 0 "noov_compare_operator"
1231 [(reg CC_REG) (const_int 0)])
1233 (label_ref (match_operand 1 "" ""))))]
1236 return output_cbranch (operands[0], operands[1], 1, 1,
1237 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1240 [(set_attr "type" "branch")
1241 (set_attr "branch_type" "icc")])
1243 ;; XXX fpcmp nop braindamage
1244 (define_insn "*normal_fp_branch"
1246 (if_then_else (match_operator 1 "comparison_operator"
1247 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1249 (label_ref (match_operand 2 "" ""))
1253 return output_cbranch (operands[1], operands[2], 2, 0,
1254 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1257 [(set_attr "type" "branch")
1258 (set_attr "branch_type" "fcc")])
1260 ;; XXX fpcmp nop braindamage
1261 (define_insn "*inverted_fp_branch"
1263 (if_then_else (match_operator 1 "comparison_operator"
1264 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1267 (label_ref (match_operand 2 "" ""))))]
1270 return output_cbranch (operands[1], operands[2], 2, 1,
1271 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1274 [(set_attr "type" "branch")
1275 (set_attr "branch_type" "fcc")])
1277 ;; XXX fpcmp nop braindamage
1278 (define_insn "*normal_fpe_branch"
1280 (if_then_else (match_operator 1 "comparison_operator"
1281 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1283 (label_ref (match_operand 2 "" ""))
1287 return output_cbranch (operands[1], operands[2], 2, 0,
1288 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1291 [(set_attr "type" "branch")
1292 (set_attr "branch_type" "fcc")])
1294 ;; XXX fpcmp nop braindamage
1295 (define_insn "*inverted_fpe_branch"
1297 (if_then_else (match_operator 1 "comparison_operator"
1298 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1301 (label_ref (match_operand 2 "" ""))))]
1304 return output_cbranch (operands[1], operands[2], 2, 1,
1305 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1308 [(set_attr "type" "branch")
1309 (set_attr "branch_type" "fcc")])
1311 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1312 ;; in the architecture.
1314 ;; There are no 32 bit brreg insns.
1317 (define_insn "*normal_int_branch_sp64"
1319 (if_then_else (match_operator 0 "v9_register_compare_operator"
1320 [(match_operand:DI 1 "register_operand" "r")
1322 (label_ref (match_operand 2 "" ""))
1326 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1327 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1330 [(set_attr "type" "branch")
1331 (set_attr "branch_type" "reg")])
1334 (define_insn "*inverted_int_branch_sp64"
1336 (if_then_else (match_operator 0 "v9_register_compare_operator"
1337 [(match_operand:DI 1 "register_operand" "r")
1340 (label_ref (match_operand 2 "" ""))))]
1343 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1344 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1347 [(set_attr "type" "branch")
1348 (set_attr "branch_type" "reg")])
1351 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1352 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1353 ;; that adds the PC value at the call point to register #(operand 3).
1355 (define_insn "load_pcrel_sym<P:mode>"
1356 [(set (match_operand:P 0 "register_operand" "=r")
1357 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1358 (match_operand:P 2 "call_address_operand" "")
1359 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1360 (clobber (reg:P O7_REG))]
1361 "REGNO (operands[0]) == INTVAL (operands[3])"
1363 if (flag_delayed_branch)
1364 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1366 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1368 [(set (attr "type") (const_string "multi"))
1369 (set (attr "length")
1370 (if_then_else (eq_attr "delayed_branch" "true")
1375 ;; Integer move instructions
1377 (define_expand "movqi"
1378 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1379 (match_operand:QI 1 "general_operand" ""))]
1382 if (sparc_expand_move (QImode, operands))
1386 (define_insn "*movqi_insn"
1387 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1388 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1389 "(register_operand (operands[0], QImode)
1390 || register_or_zero_operand (operands[1], QImode))"
1395 [(set_attr "type" "*,load,store")
1396 (set_attr "us3load_type" "*,3cycle,*")])
1398 (define_expand "movhi"
1399 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1400 (match_operand:HI 1 "general_operand" ""))]
1403 if (sparc_expand_move (HImode, operands))
1407 (define_insn "*movhi_insn"
1408 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1409 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1410 "(register_operand (operands[0], HImode)
1411 || register_or_zero_operand (operands[1], HImode))"
1414 sethi\t%%hi(%a1), %0
1417 [(set_attr "type" "*,*,load,store")
1418 (set_attr "us3load_type" "*,*,3cycle,*")])
1420 ;; We always work with constants here.
1421 (define_insn "*movhi_lo_sum"
1422 [(set (match_operand:HI 0 "register_operand" "=r")
1423 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1424 (match_operand:HI 2 "small_int_operand" "I")))]
1428 (define_expand "movsi"
1429 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1430 (match_operand:SI 1 "general_operand" ""))]
1433 if (sparc_expand_move (SImode, operands))
1437 (define_insn "*movsi_insn"
1438 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1439 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1440 "register_operand (operands[0], SImode)
1441 || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1444 sethi\t%%hi(%a1), %0
1454 [(set_attr "type" "*,*,load,store,*,*,fpmove,fpload,fpstore,fga,fga")
1455 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1457 (define_insn "*movsi_lo_sum"
1458 [(set (match_operand:SI 0 "register_operand" "=r")
1459 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1460 (match_operand:SI 2 "immediate_operand" "in")))]
1462 "or\t%1, %%lo(%a2), %0")
1464 (define_insn "*movsi_high"
1465 [(set (match_operand:SI 0 "register_operand" "=r")
1466 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1468 "sethi\t%%hi(%a1), %0")
1470 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1471 ;; so that CSE won't optimize the address computation away.
1472 (define_insn "movsi_lo_sum_pic"
1473 [(set (match_operand:SI 0 "register_operand" "=r")
1474 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1475 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1478 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1479 return "xor\t%1, %%gdop_lox10(%a2), %0";
1481 return "or\t%1, %%lo(%a2), %0";
1485 (define_insn "movsi_high_pic"
1486 [(set (match_operand:SI 0 "register_operand" "=r")
1487 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1488 "flag_pic && check_pic (1)"
1490 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1491 return "sethi\t%%gdop_hix22(%a1), %0";
1493 return "sethi\t%%hi(%a1), %0";
1497 (define_insn "movsi_pic_gotdata_op"
1498 [(set (match_operand:SI 0 "register_operand" "=r")
1499 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1500 (match_operand:SI 2 "register_operand" "r")
1501 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1502 "flag_pic && check_pic (1)"
1504 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1505 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1507 return "ld\t[%1 + %2], %0";
1510 [(set_attr "type" "load")])
1512 (define_expand "movsi_pic_label_ref"
1513 [(set (match_dup 3) (high:SI
1514 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1515 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1516 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1517 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1518 (set (match_operand:SI 0 "register_operand" "=r")
1519 (minus:SI (match_dup 5) (match_dup 4)))]
1522 crtl->uses_pic_offset_table = 1;
1523 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1524 if (!can_create_pseudo_p ())
1526 operands[3] = operands[0];
1527 operands[4] = operands[0];
1531 operands[3] = gen_reg_rtx (SImode);
1532 operands[4] = gen_reg_rtx (SImode);
1534 operands[5] = pic_offset_table_rtx;
1537 (define_insn "*movsi_high_pic_label_ref"
1538 [(set (match_operand:SI 0 "register_operand" "=r")
1540 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1541 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1543 "sethi\t%%hi(%a2-(%a1-.)), %0")
1545 (define_insn "*movsi_lo_sum_pic_label_ref"
1546 [(set (match_operand:SI 0 "register_operand" "=r")
1547 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1548 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1549 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1551 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1553 ;; Set up the PIC register for VxWorks.
1555 (define_expand "vxworks_load_got"
1557 (high:SI (match_dup 1)))
1559 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1561 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1562 "TARGET_VXWORKS_RTP"
1564 operands[0] = pic_offset_table_rtx;
1565 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1566 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1569 (define_expand "movdi"
1570 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1571 (match_operand:DI 1 "general_operand" ""))]
1574 if (sparc_expand_move (DImode, operands))
1578 ;; Be careful, fmovd does not exist when !v9.
1579 ;; We match MEM moves directly when we have correct even
1580 ;; numbered registers, but fall into splits otherwise.
1581 ;; The constraint ordering here is really important to
1582 ;; avoid insane problems in reload, especially for patterns
1585 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1586 ;; (const_int -5016)))
1590 (define_insn "*movdi_insn_sp32"
1591 [(set (match_operand:DI 0 "nonimmediate_operand"
1592 "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e, r,?*f,?*e,?W,b,b")
1593 (match_operand:DI 1 "input_operand"
1594 " J,J,U,T,r,o,i,r,*f, T, o,*f, *e, *e,?*f, r, W,*e,J,P"))]
1596 && (register_operand (operands[0], DImode)
1597 || register_or_zero_operand (operands[1], DImode))"
1619 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,fga,fga")
1620 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1621 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1622 (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
1624 (define_insn "*movdi_insn_sp64"
1625 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1626 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,*e, r, *e, W,*e,J,P"))]
1628 && (register_operand (operands[0], DImode)
1629 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1632 sethi\t%%hi(%a1), %0
1642 [(set_attr "type" "*,*,load,store,*,*,fpmove,fpload,fpstore,fga,fga")
1643 (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1644 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1646 (define_expand "movdi_pic_label_ref"
1647 [(set (match_dup 3) (high:DI
1648 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1649 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1650 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1651 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1652 (set (match_operand:DI 0 "register_operand" "=r")
1653 (minus:DI (match_dup 5) (match_dup 4)))]
1654 "TARGET_ARCH64 && flag_pic"
1656 crtl->uses_pic_offset_table = 1;
1657 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1658 if (!can_create_pseudo_p ())
1660 operands[3] = operands[0];
1661 operands[4] = operands[0];
1665 operands[3] = gen_reg_rtx (DImode);
1666 operands[4] = gen_reg_rtx (DImode);
1668 operands[5] = pic_offset_table_rtx;
1671 (define_insn "*movdi_high_pic_label_ref"
1672 [(set (match_operand:DI 0 "register_operand" "=r")
1674 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1675 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1676 "TARGET_ARCH64 && flag_pic"
1677 "sethi\t%%hi(%a2-(%a1-.)), %0")
1679 (define_insn "*movdi_lo_sum_pic_label_ref"
1680 [(set (match_operand:DI 0 "register_operand" "=r")
1681 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1682 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1683 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1684 "TARGET_ARCH64 && flag_pic"
1685 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1687 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1688 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1690 (define_insn "movdi_lo_sum_pic"
1691 [(set (match_operand:DI 0 "register_operand" "=r")
1692 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1693 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1694 "TARGET_ARCH64 && flag_pic"
1696 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1697 return "xor\t%1, %%gdop_lox10(%a2), %0";
1699 return "or\t%1, %%lo(%a2), %0";
1703 (define_insn "movdi_high_pic"
1704 [(set (match_operand:DI 0 "register_operand" "=r")
1705 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1706 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1708 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1709 return "sethi\t%%gdop_hix22(%a1), %0";
1711 return "sethi\t%%hi(%a1), %0";
1715 (define_insn "movdi_pic_gotdata_op"
1716 [(set (match_operand:DI 0 "register_operand" "=r")
1717 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1718 (match_operand:DI 2 "register_operand" "r")
1719 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1720 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1722 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1723 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1725 return "ldx\t[%1 + %2], %0";
1728 [(set_attr "type" "load")])
1730 (define_insn "*sethi_di_medlow_embmedany_pic"
1731 [(set (match_operand:DI 0 "register_operand" "=r")
1732 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1733 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1734 "sethi\t%%hi(%a1), %0")
1736 (define_insn "*sethi_di_medlow"
1737 [(set (match_operand:DI 0 "register_operand" "=r")
1738 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1739 "TARGET_CM_MEDLOW && check_pic (1)"
1740 "sethi\t%%hi(%a1), %0")
1742 (define_insn "*losum_di_medlow"
1743 [(set (match_operand:DI 0 "register_operand" "=r")
1744 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1745 (match_operand:DI 2 "symbolic_operand" "")))]
1747 "or\t%1, %%lo(%a2), %0")
1749 (define_insn "seth44"
1750 [(set (match_operand:DI 0 "register_operand" "=r")
1751 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1753 "sethi\t%%h44(%a1), %0")
1755 (define_insn "setm44"
1756 [(set (match_operand:DI 0 "register_operand" "=r")
1757 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1758 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1760 "or\t%1, %%m44(%a2), %0")
1762 (define_insn "setl44"
1763 [(set (match_operand:DI 0 "register_operand" "=r")
1764 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1765 (match_operand:DI 2 "symbolic_operand" "")))]
1767 "or\t%1, %%l44(%a2), %0")
1769 (define_insn "sethh"
1770 [(set (match_operand:DI 0 "register_operand" "=r")
1771 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1773 "sethi\t%%hh(%a1), %0")
1775 (define_insn "setlm"
1776 [(set (match_operand:DI 0 "register_operand" "=r")
1777 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1779 "sethi\t%%lm(%a1), %0")
1781 (define_insn "sethm"
1782 [(set (match_operand:DI 0 "register_operand" "=r")
1783 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1784 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1786 "or\t%1, %%hm(%a2), %0")
1788 (define_insn "setlo"
1789 [(set (match_operand:DI 0 "register_operand" "=r")
1790 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1791 (match_operand:DI 2 "symbolic_operand" "")))]
1793 "or\t%1, %%lo(%a2), %0")
1795 (define_insn "embmedany_sethi"
1796 [(set (match_operand:DI 0 "register_operand" "=r")
1797 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1798 "TARGET_CM_EMBMEDANY && check_pic (1)"
1799 "sethi\t%%hi(%a1), %0")
1801 (define_insn "embmedany_losum"
1802 [(set (match_operand:DI 0 "register_operand" "=r")
1803 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1804 (match_operand:DI 2 "data_segment_operand" "")))]
1805 "TARGET_CM_EMBMEDANY"
1806 "add\t%1, %%lo(%a2), %0")
1808 (define_insn "embmedany_brsum"
1809 [(set (match_operand:DI 0 "register_operand" "=r")
1810 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1811 "TARGET_CM_EMBMEDANY"
1814 (define_insn "embmedany_textuhi"
1815 [(set (match_operand:DI 0 "register_operand" "=r")
1816 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1817 "TARGET_CM_EMBMEDANY && check_pic (1)"
1818 "sethi\t%%uhi(%a1), %0")
1820 (define_insn "embmedany_texthi"
1821 [(set (match_operand:DI 0 "register_operand" "=r")
1822 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1823 "TARGET_CM_EMBMEDANY && check_pic (1)"
1824 "sethi\t%%hi(%a1), %0")
1826 (define_insn "embmedany_textulo"
1827 [(set (match_operand:DI 0 "register_operand" "=r")
1828 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1829 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1830 "TARGET_CM_EMBMEDANY"
1831 "or\t%1, %%ulo(%a2), %0")
1833 (define_insn "embmedany_textlo"
1834 [(set (match_operand:DI 0 "register_operand" "=r")
1835 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1836 (match_operand:DI 2 "text_segment_operand" "")))]
1837 "TARGET_CM_EMBMEDANY"
1838 "or\t%1, %%lo(%a2), %0")
1840 ;; Now some patterns to help reload out a bit.
1841 (define_expand "reload_indi"
1842 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1843 (match_operand:DI 1 "immediate_operand" "")
1844 (match_operand:TI 2 "register_operand" "=&r")])]
1846 || TARGET_CM_EMBMEDANY)
1849 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1853 (define_expand "reload_outdi"
1854 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1855 (match_operand:DI 1 "immediate_operand" "")
1856 (match_operand:TI 2 "register_operand" "=&r")])]
1858 || TARGET_CM_EMBMEDANY)
1861 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1865 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1867 [(set (match_operand:DI 0 "register_operand" "")
1868 (match_operand:DI 1 "const_int_operand" ""))]
1870 && ((GET_CODE (operands[0]) == REG
1871 && SPARC_INT_REG_P (REGNO (operands[0])))
1872 || (GET_CODE (operands[0]) == SUBREG
1873 && GET_CODE (SUBREG_REG (operands[0])) == REG
1874 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))
1875 && reload_completed"
1876 [(clobber (const_int 0))]
1878 #if HOST_BITS_PER_WIDE_INT == 32
1879 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1880 (INTVAL (operands[1]) < 0) ?
1883 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1886 unsigned int low, high;
1888 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1889 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1890 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1892 /* Slick... but this trick loses if this subreg constant part
1893 can be done in one insn. */
1895 && ! SPARC_SETHI32_P (high)
1896 && ! SPARC_SIMM13_P (high))
1897 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1898 gen_highpart (SImode, operands[0])));
1900 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1906 [(set (match_operand:DI 0 "register_operand" "")
1907 (match_operand:DI 1 "const_double_operand" ""))]
1911 && ((GET_CODE (operands[0]) == REG
1912 && SPARC_INT_REG_P (REGNO (operands[0])))
1913 || (GET_CODE (operands[0]) == SUBREG
1914 && GET_CODE (SUBREG_REG (operands[0])) == REG
1915 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
1916 [(clobber (const_int 0))]
1918 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1919 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1921 /* Slick... but this trick loses if this subreg constant part
1922 can be done in one insn. */
1923 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1924 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1925 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1927 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1928 gen_highpart (SImode, operands[0])));
1932 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1933 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1939 [(set (match_operand:DI 0 "register_operand" "")
1940 (match_operand:DI 1 "register_operand" ""))]
1944 && sparc_split_regreg_legitimate (operands[0],
1946 [(clobber (const_int 0))]
1948 rtx set_dest = operands[0];
1949 rtx set_src = operands[1];
1953 dest1 = gen_highpart (SImode, set_dest);
1954 dest2 = gen_lowpart (SImode, set_dest);
1955 src1 = gen_highpart (SImode, set_src);
1956 src2 = gen_lowpart (SImode, set_src);
1958 /* Now emit using the real source and destination we found, swapping
1959 the order if we detect overlap. */
1960 if (reg_overlap_mentioned_p (dest1, src2))
1962 emit_insn (gen_movsi (dest2, src2));
1963 emit_insn (gen_movsi (dest1, src1));
1967 emit_insn (gen_movsi (dest1, src1));
1968 emit_insn (gen_movsi (dest2, src2));
1973 ;; Now handle the cases of memory moves from/to non-even
1974 ;; DI mode register pairs.
1976 [(set (match_operand:DI 0 "register_operand" "")
1977 (match_operand:DI 1 "memory_operand" ""))]
1980 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1981 [(clobber (const_int 0))]
1983 rtx word0 = adjust_address (operands[1], SImode, 0);
1984 rtx word1 = adjust_address (operands[1], SImode, 4);
1985 rtx high_part = gen_highpart (SImode, operands[0]);
1986 rtx low_part = gen_lowpart (SImode, operands[0]);
1988 if (reg_overlap_mentioned_p (high_part, word1))
1990 emit_insn (gen_movsi (low_part, word1));
1991 emit_insn (gen_movsi (high_part, word0));
1995 emit_insn (gen_movsi (high_part, word0));
1996 emit_insn (gen_movsi (low_part, word1));
2002 [(set (match_operand:DI 0 "memory_operand" "")
2003 (match_operand:DI 1 "register_operand" ""))]
2006 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2007 [(clobber (const_int 0))]
2009 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2010 gen_highpart (SImode, operands[1])));
2011 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2012 gen_lowpart (SImode, operands[1])));
2017 [(set (match_operand:DI 0 "memory_operand" "")
2018 (match_operand:DI 1 "const_zero_operand" ""))]
2022 && ! mem_min_alignment (operands[0], 8)))
2023 && offsettable_memref_p (operands[0])"
2024 [(clobber (const_int 0))]
2026 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2027 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2032 ;; Floating point move instructions
2034 (define_expand "movsf"
2035 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2036 (match_operand:SF 1 "general_operand" ""))]
2039 if (sparc_expand_move (SFmode, operands))
2043 (define_insn "*movsf_insn"
2044 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m, m")
2045 (match_operand:SF 1 "input_operand" "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2046 "(register_operand (operands[0], SFmode)
2047 || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2049 if (GET_CODE (operands[1]) == CONST_DOUBLE
2050 && (which_alternative == 3
2051 || which_alternative == 4
2052 || which_alternative == 5))
2057 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2058 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2059 operands[1] = GEN_INT (i);
2062 switch (which_alternative)
2065 return "fzeros\t%0";
2069 return "fmovs\t%1, %0";
2071 return "mov\t%1, %0";
2073 return "sethi\t%%hi(%a1), %0";
2077 return "movstouw\t%1, %0";
2079 return "movwtos\t%1, %0";
2082 return "ld\t%1, %0";
2085 return "st\t%r1, %0";
2090 [(set_attr "type" "fga,fga,fpmove,*,*,*,*,*,fpload,load,fpstore,store")
2091 (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2093 ;; The following 3 patterns build SFmode constants in integer registers.
2095 (define_insn "*movsf_lo_sum"
2096 [(set (match_operand:SF 0 "register_operand" "=r")
2097 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2098 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2104 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2105 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2106 operands[2] = GEN_INT (i);
2107 return "or\t%1, %%lo(%a2), %0";
2110 (define_insn "*movsf_high"
2111 [(set (match_operand:SF 0 "register_operand" "=r")
2112 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2118 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2119 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2120 operands[1] = GEN_INT (i);
2121 return "sethi\t%%hi(%1), %0";
2125 [(set (match_operand:SF 0 "register_operand" "")
2126 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2127 "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2128 [(set (match_dup 0) (high:SF (match_dup 1)))
2129 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2131 (define_expand "movdf"
2132 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2133 (match_operand:DF 1 "general_operand" ""))]
2136 if (sparc_expand_move (DFmode, operands))
2140 (define_insn "*movdf_insn_sp32"
2141 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f, e,T,W,U,T, f, *r, o,o")
2142 (match_operand:DF 1 "input_operand" "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))]
2144 && (register_operand (operands[0], DFmode)
2145 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2162 [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*")
2163 (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2")
2164 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2165 (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")])
2167 (define_insn "*movdf_insn_sp64"
2168 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r")
2169 (match_operand:DF 1 "input_operand" "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2171 && (register_operand (operands[0], DFmode)
2172 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2185 [(set_attr "type" "fga,fga,fpmove,*,*,load,store,*,load,store,*")
2186 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2187 (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2188 (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2190 ;; This pattern builds DFmode constants in integer registers.
2192 [(set (match_operand:DF 0 "register_operand" "")
2193 (match_operand:DF 1 "const_double_operand" ""))]
2194 "REG_P (operands[0])
2195 && SPARC_INT_REG_P (REGNO (operands[0]))
2196 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2197 && reload_completed"
2198 [(clobber (const_int 0))]
2200 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2204 #if HOST_BITS_PER_WIDE_INT == 32
2207 enum machine_mode mode = GET_MODE (operands[1]);
2208 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2209 emit_insn (gen_movdi (operands[0], tem));
2214 enum machine_mode mode = GET_MODE (operands[1]);
2215 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2216 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2218 gcc_assert (GET_CODE (hi) == CONST_INT);
2219 gcc_assert (GET_CODE (lo) == CONST_INT);
2221 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2223 /* Slick... but this trick loses if this subreg constant part
2224 can be done in one insn. */
2226 && ! SPARC_SETHI32_P (INTVAL (hi))
2227 && ! SPARC_SIMM13_P (INTVAL (hi)))
2229 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2230 gen_highpart (SImode, operands[0])));
2234 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2240 ;; Ok, now the splits to handle all the multi insn and
2241 ;; mis-aligned memory address cases.
2242 ;; In these splits please take note that we must be
2243 ;; careful when V9 but not ARCH64 because the integer
2244 ;; register DFmode cases must be handled.
2246 [(set (match_operand:DF 0 "register_operand" "")
2247 (match_operand:DF 1 "register_operand" ""))]
2250 && sparc_split_regreg_legitimate (operands[0],
2252 && reload_completed"
2253 [(clobber (const_int 0))]
2255 rtx set_dest = operands[0];
2256 rtx set_src = operands[1];
2260 dest1 = gen_highpart (SFmode, set_dest);
2261 dest2 = gen_lowpart (SFmode, set_dest);
2262 src1 = gen_highpart (SFmode, set_src);
2263 src2 = gen_lowpart (SFmode, set_src);
2265 /* Now emit using the real source and destination we found, swapping
2266 the order if we detect overlap. */
2267 if (reg_overlap_mentioned_p (dest1, src2))
2269 emit_move_insn_1 (dest2, src2);
2270 emit_move_insn_1 (dest1, src1);
2274 emit_move_insn_1 (dest1, src1);
2275 emit_move_insn_1 (dest2, src2);
2281 [(set (match_operand:DF 0 "register_operand" "")
2282 (match_operand:DF 1 "memory_operand" ""))]
2285 && (((REGNO (operands[0]) % 2) != 0)
2286 || ! mem_min_alignment (operands[1], 8))
2287 && offsettable_memref_p (operands[1])"
2288 [(clobber (const_int 0))]
2292 word0 = adjust_address (operands[1], SFmode, 0);
2293 word1 = adjust_address (operands[1], SFmode, 4);
2295 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2297 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2298 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2302 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2303 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2309 [(set (match_operand:DF 0 "memory_operand" "")
2310 (match_operand:DF 1 "register_operand" ""))]
2313 && (((REGNO (operands[1]) % 2) != 0)
2314 || ! mem_min_alignment (operands[0], 8))
2315 && offsettable_memref_p (operands[0])"
2316 [(clobber (const_int 0))]
2320 word0 = adjust_address (operands[0], SFmode, 0);
2321 word1 = adjust_address (operands[0], SFmode, 4);
2323 emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2324 emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2329 [(set (match_operand:DF 0 "memory_operand" "")
2330 (match_operand:DF 1 "const_zero_operand" ""))]
2334 && ! mem_min_alignment (operands[0], 8)))
2335 && offsettable_memref_p (operands[0])"
2336 [(clobber (const_int 0))]
2340 dest1 = adjust_address (operands[0], SFmode, 0);
2341 dest2 = adjust_address (operands[0], SFmode, 4);
2343 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2344 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2349 [(set (match_operand:DF 0 "register_operand" "")
2350 (match_operand:DF 1 "const_zero_operand" ""))]
2353 && ((GET_CODE (operands[0]) == REG
2354 && SPARC_INT_REG_P (REGNO (operands[0])))
2355 || (GET_CODE (operands[0]) == SUBREG
2356 && GET_CODE (SUBREG_REG (operands[0])) == REG
2357 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2358 [(clobber (const_int 0))]
2360 rtx set_dest = operands[0];
2363 dest1 = gen_highpart (SFmode, set_dest);
2364 dest2 = gen_lowpart (SFmode, set_dest);
2365 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2366 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2370 (define_expand "movtf"
2371 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2372 (match_operand:TF 1 "general_operand" ""))]
2375 if (sparc_expand_move (TFmode, operands))
2379 (define_insn "*movtf_insn_sp32"
2380 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,U, r")
2381 (match_operand:TF 1 "input_operand" " G,oe,e,rGU,o,roG"))]
2383 && (register_operand (operands[0], TFmode)
2384 || register_or_zero_operand (operands[1], TFmode))"
2386 [(set_attr "length" "4,4,4,4,4,4")
2387 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")])
2389 (define_insn "*movtf_insn_sp64"
2390 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o, r")
2391 (match_operand:TF 1 "input_operand" "G,oe,e,rG,roG"))]
2393 && ! TARGET_HARD_QUAD
2394 && (register_operand (operands[0], TFmode)
2395 || register_or_zero_operand (operands[1], TFmode))"
2397 [(set_attr "length" "2,2,2,2,2")
2398 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2400 (define_insn "*movtf_insn_sp64_hq"
2401 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o, r")
2402 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2405 && (register_operand (operands[0], TFmode)
2406 || register_or_zero_operand (operands[1], TFmode))"
2414 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2415 (set_attr "length" "2,*,*,*,2,2")])
2417 ;; Now all the splits to handle multi-insn TF mode moves.
2419 [(set (match_operand:TF 0 "register_operand" "")
2420 (match_operand:TF 1 "register_operand" ""))]
2424 && ! TARGET_HARD_QUAD)
2425 || (! fp_register_operand (operands[0], TFmode)
2426 && ! fp_register_operand (operands[1], TFmode)))"
2427 [(clobber (const_int 0))]
2429 rtx set_dest = operands[0];
2430 rtx set_src = operands[1];
2434 dest1 = gen_df_reg (set_dest, 0);
2435 dest2 = gen_df_reg (set_dest, 1);
2436 src1 = gen_df_reg (set_src, 0);
2437 src2 = gen_df_reg (set_src, 1);
2439 /* Now emit using the real source and destination we found, swapping
2440 the order if we detect overlap. */
2441 if (reg_overlap_mentioned_p (dest1, src2))
2443 emit_insn (gen_movdf (dest2, src2));
2444 emit_insn (gen_movdf (dest1, src1));
2448 emit_insn (gen_movdf (dest1, src1));
2449 emit_insn (gen_movdf (dest2, src2));
2455 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2456 (match_operand:TF 1 "const_zero_operand" ""))]
2458 [(clobber (const_int 0))]
2460 rtx set_dest = operands[0];
2463 switch (GET_CODE (set_dest))
2466 dest1 = gen_df_reg (set_dest, 0);
2467 dest2 = gen_df_reg (set_dest, 1);
2470 dest1 = adjust_address (set_dest, DFmode, 0);
2471 dest2 = adjust_address (set_dest, DFmode, 8);
2477 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2478 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2483 [(set (match_operand:TF 0 "register_operand" "")
2484 (match_operand:TF 1 "memory_operand" ""))]
2486 && offsettable_memref_p (operands[1])
2488 || ! TARGET_HARD_QUAD
2489 || ! fp_register_operand (operands[0], TFmode)))"
2490 [(clobber (const_int 0))]
2492 rtx word0 = adjust_address (operands[1], DFmode, 0);
2493 rtx word1 = adjust_address (operands[1], DFmode, 8);
2494 rtx set_dest, dest1, dest2;
2496 set_dest = operands[0];
2498 dest1 = gen_df_reg (set_dest, 0);
2499 dest2 = gen_df_reg (set_dest, 1);
2501 /* Now output, ordering such that we don't clobber any registers
2502 mentioned in the address. */
2503 if (reg_overlap_mentioned_p (dest1, word1))
2506 emit_insn (gen_movdf (dest2, word1));
2507 emit_insn (gen_movdf (dest1, word0));
2511 emit_insn (gen_movdf (dest1, word0));
2512 emit_insn (gen_movdf (dest2, word1));
2518 [(set (match_operand:TF 0 "memory_operand" "")
2519 (match_operand:TF 1 "register_operand" ""))]
2521 && offsettable_memref_p (operands[0])
2523 || ! TARGET_HARD_QUAD
2524 || ! fp_register_operand (operands[1], TFmode)))"
2525 [(clobber (const_int 0))]
2527 rtx set_src = operands[1];
2529 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2530 gen_df_reg (set_src, 0)));
2531 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2532 gen_df_reg (set_src, 1)));
2537 ;; SPARC-V9 conditional move instructions
2539 ;; We can handle larger constants here for some flavors, but for now we keep
2540 ;; it simple and only allow those constants supported by all flavors.
2541 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2542 ;; 3 contains the constant if one is present, but we handle either for
2543 ;; generality (sparc.c puts a constant in operand 2).
2545 ;; Our instruction patterns, on the other hand, canonicalize such that
2546 ;; operand 3 must be the set destination.
2548 (define_expand "mov<I:mode>cc"
2549 [(set (match_operand:I 0 "register_operand" "")
2550 (if_then_else:I (match_operand 1 "comparison_operator" "")
2551 (match_operand:I 2 "arith10_operand" "")
2552 (match_operand:I 3 "arith10_operand" "")))]
2553 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2555 if (! sparc_expand_conditional_move (<I:MODE>mode, operands))
2560 (define_expand "mov<F:mode>cc"
2561 [(set (match_operand:F 0 "register_operand" "")
2562 (if_then_else:F (match_operand 1 "comparison_operator" "")
2563 (match_operand:F 2 "register_operand" "")
2564 (match_operand:F 3 "register_operand" "")))]
2565 "TARGET_V9 && TARGET_FPU"
2567 if (! sparc_expand_conditional_move (<F:MODE>mode, operands))
2572 ;; Conditional move define_insns
2574 (define_insn "*mov<I:mode>_cc_v9"
2575 [(set (match_operand:I 0 "register_operand" "=r")
2576 (if_then_else:I (match_operator 1 "comparison_operator"
2577 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2579 (match_operand:I 3 "arith11_operand" "rL")
2580 (match_operand:I 4 "register_operand" "0")))]
2581 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2582 "mov%C1\t%x2, %3, %0"
2583 [(set_attr "type" "cmove")])
2585 (define_insn "*mov<I:mode>_cc_reg_sp64"
2586 [(set (match_operand:I 0 "register_operand" "=r")
2587 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2588 [(match_operand:DI 2 "register_operand" "r")
2590 (match_operand:I 3 "arith10_operand" "rM")
2591 (match_operand:I 4 "register_operand" "0")))]
2593 "movr%D1\t%2, %r3, %0"
2594 [(set_attr "type" "cmove")])
2596 (define_insn "*movsf_cc_v9"
2597 [(set (match_operand:SF 0 "register_operand" "=f")
2598 (if_then_else:SF (match_operator 1 "comparison_operator"
2599 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2601 (match_operand:SF 3 "register_operand" "f")
2602 (match_operand:SF 4 "register_operand" "0")))]
2603 "TARGET_V9 && TARGET_FPU"
2604 "fmovs%C1\t%x2, %3, %0"
2605 [(set_attr "type" "fpcmove")])
2607 (define_insn "*movsf_cc_reg_sp64"
2608 [(set (match_operand:SF 0 "register_operand" "=f")
2609 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2610 [(match_operand:DI 2 "register_operand" "r")
2612 (match_operand:SF 3 "register_operand" "f")
2613 (match_operand:SF 4 "register_operand" "0")))]
2614 "TARGET_ARCH64 && TARGET_FPU"
2615 "fmovrs%D1\t%2, %3, %0"
2616 [(set_attr "type" "fpcrmove")])
2618 ;; Named because invoked by movtf_cc_v9
2619 (define_insn "movdf_cc_v9"
2620 [(set (match_operand:DF 0 "register_operand" "=e")
2621 (if_then_else:DF (match_operator 1 "comparison_operator"
2622 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2624 (match_operand:DF 3 "register_operand" "e")
2625 (match_operand:DF 4 "register_operand" "0")))]
2626 "TARGET_V9 && TARGET_FPU"
2627 "fmovd%C1\t%x2, %3, %0"
2628 [(set_attr "type" "fpcmove")
2629 (set_attr "fptype" "double")])
2631 ;; Named because invoked by movtf_cc_reg_sp64
2632 (define_insn "movdf_cc_reg_sp64"
2633 [(set (match_operand:DF 0 "register_operand" "=e")
2634 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2635 [(match_operand:DI 2 "register_operand" "r")
2637 (match_operand:DF 3 "register_operand" "e")
2638 (match_operand:DF 4 "register_operand" "0")))]
2639 "TARGET_ARCH64 && TARGET_FPU"
2640 "fmovrd%D1\t%2, %3, %0"
2641 [(set_attr "type" "fpcrmove")
2642 (set_attr "fptype" "double")])
2644 (define_insn "*movtf_cc_hq_v9"
2645 [(set (match_operand:TF 0 "register_operand" "=e")
2646 (if_then_else:TF (match_operator 1 "comparison_operator"
2647 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2649 (match_operand:TF 3 "register_operand" "e")
2650 (match_operand:TF 4 "register_operand" "0")))]
2651 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2652 "fmovq%C1\t%x2, %3, %0"
2653 [(set_attr "type" "fpcmove")])
2655 (define_insn "*movtf_cc_reg_hq_sp64"
2656 [(set (match_operand:TF 0 "register_operand" "=e")
2657 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2658 [(match_operand:DI 2 "register_operand" "r")
2660 (match_operand:TF 3 "register_operand" "e")
2661 (match_operand:TF 4 "register_operand" "0")))]
2662 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2663 "fmovrq%D1\t%2, %3, %0"
2664 [(set_attr "type" "fpcrmove")])
2666 (define_insn_and_split "*movtf_cc_v9"
2667 [(set (match_operand:TF 0 "register_operand" "=e")
2668 (if_then_else:TF (match_operator 1 "comparison_operator"
2669 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2671 (match_operand:TF 3 "register_operand" "e")
2672 (match_operand:TF 4 "register_operand" "0")))]
2673 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2675 "&& reload_completed"
2676 [(clobber (const_int 0))]
2678 rtx set_dest = operands[0];
2679 rtx set_srca = operands[3];
2683 dest1 = gen_df_reg (set_dest, 0);
2684 dest2 = gen_df_reg (set_dest, 1);
2685 srca1 = gen_df_reg (set_srca, 0);
2686 srca2 = gen_df_reg (set_srca, 1);
2688 if (reg_overlap_mentioned_p (dest1, srca2))
2690 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2691 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2695 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2696 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2700 [(set_attr "length" "2")])
2702 (define_insn_and_split "*movtf_cc_reg_sp64"
2703 [(set (match_operand:TF 0 "register_operand" "=e")
2704 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2705 [(match_operand:DI 2 "register_operand" "r")
2707 (match_operand:TF 3 "register_operand" "e")
2708 (match_operand:TF 4 "register_operand" "0")))]
2709 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2711 "&& reload_completed"
2712 [(clobber (const_int 0))]
2714 rtx set_dest = operands[0];
2715 rtx set_srca = operands[3];
2719 dest1 = gen_df_reg (set_dest, 0);
2720 dest2 = gen_df_reg (set_dest, 1);
2721 srca1 = gen_df_reg (set_srca, 0);
2722 srca2 = gen_df_reg (set_srca, 1);
2724 if (reg_overlap_mentioned_p (dest1, srca2))
2726 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2727 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2731 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2732 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2736 [(set_attr "length" "2")])
2739 ;; Zero-extension instructions
2741 ;; These patterns originally accepted general_operands, however, slightly
2742 ;; better code is generated by only accepting register_operands, and then
2743 ;; letting combine generate the ldu[hb] insns.
2745 (define_expand "zero_extendhisi2"
2746 [(set (match_operand:SI 0 "register_operand" "")
2747 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2750 rtx temp = gen_reg_rtx (SImode);
2751 rtx shift_16 = GEN_INT (16);
2752 int op1_subbyte = 0;
2754 if (GET_CODE (operand1) == SUBREG)
2756 op1_subbyte = SUBREG_BYTE (operand1);
2757 op1_subbyte /= GET_MODE_SIZE (SImode);
2758 op1_subbyte *= GET_MODE_SIZE (SImode);
2759 operand1 = XEXP (operand1, 0);
2762 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2764 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2768 (define_insn "*zero_extendhisi2_insn"
2769 [(set (match_operand:SI 0 "register_operand" "=r")
2770 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2773 [(set_attr "type" "load")
2774 (set_attr "us3load_type" "3cycle")])
2776 (define_expand "zero_extendqihi2"
2777 [(set (match_operand:HI 0 "register_operand" "")
2778 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2782 (define_insn "*zero_extendqihi2_insn"
2783 [(set (match_operand:HI 0 "register_operand" "=r,r")
2784 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2785 "GET_CODE (operands[1]) != CONST_INT"
2789 [(set_attr "type" "*,load")
2790 (set_attr "us3load_type" "*,3cycle")])
2792 (define_expand "zero_extendqisi2"
2793 [(set (match_operand:SI 0 "register_operand" "")
2794 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2798 (define_insn "*zero_extendqisi2_insn"
2799 [(set (match_operand:SI 0 "register_operand" "=r,r")
2800 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2801 "GET_CODE (operands[1]) != CONST_INT"
2805 [(set_attr "type" "*,load")
2806 (set_attr "us3load_type" "*,3cycle")])
2808 (define_expand "zero_extendqidi2"
2809 [(set (match_operand:DI 0 "register_operand" "")
2810 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2814 (define_insn "*zero_extendqidi2_insn"
2815 [(set (match_operand:DI 0 "register_operand" "=r,r")
2816 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2817 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2821 [(set_attr "type" "*,load")
2822 (set_attr "us3load_type" "*,3cycle")])
2824 (define_expand "zero_extendhidi2"
2825 [(set (match_operand:DI 0 "register_operand" "")
2826 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2829 rtx temp = gen_reg_rtx (DImode);
2830 rtx shift_48 = GEN_INT (48);
2831 int op1_subbyte = 0;
2833 if (GET_CODE (operand1) == SUBREG)
2835 op1_subbyte = SUBREG_BYTE (operand1);
2836 op1_subbyte /= GET_MODE_SIZE (DImode);
2837 op1_subbyte *= GET_MODE_SIZE (DImode);
2838 operand1 = XEXP (operand1, 0);
2841 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2843 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2847 (define_insn "*zero_extendhidi2_insn"
2848 [(set (match_operand:DI 0 "register_operand" "=r")
2849 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2852 [(set_attr "type" "load")
2853 (set_attr "us3load_type" "3cycle")])
2855 ;; ??? Write truncdisi pattern using sra?
2857 (define_expand "zero_extendsidi2"
2858 [(set (match_operand:DI 0 "register_operand" "")
2859 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2863 (define_insn "*zero_extendsidi2_insn_sp64"
2864 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
2865 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
2867 && GET_CODE (operands[1]) != CONST_INT"
2872 [(set_attr "type" "shift,load,*")
2873 (set_attr "cpu_feature" "*,*,vis3")])
2875 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2876 [(set (match_operand:DI 0 "register_operand" "=r")
2877 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2880 "&& reload_completed"
2881 [(set (match_dup 2) (match_dup 3))
2882 (set (match_dup 4) (match_dup 5))]
2886 dest1 = gen_highpart (SImode, operands[0]);
2887 dest2 = gen_lowpart (SImode, operands[0]);
2889 /* Swap the order in case of overlap. */
2890 if (REGNO (dest1) == REGNO (operands[1]))
2892 operands[2] = dest2;
2893 operands[3] = operands[1];
2894 operands[4] = dest1;
2895 operands[5] = const0_rtx;
2899 operands[2] = dest1;
2900 operands[3] = const0_rtx;
2901 operands[4] = dest2;
2902 operands[5] = operands[1];
2905 [(set_attr "length" "2")])
2907 ;; Simplify comparisons of extended values.
2909 (define_insn "*cmp_zero_extendqisi2"
2910 [(set (reg:CC CC_REG)
2911 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2914 "andcc\t%0, 0xff, %%g0"
2915 [(set_attr "type" "compare")])
2917 (define_insn "*cmp_zero_qi"
2918 [(set (reg:CC CC_REG)
2919 (compare:CC (match_operand:QI 0 "register_operand" "r")
2922 "andcc\t%0, 0xff, %%g0"
2923 [(set_attr "type" "compare")])
2925 (define_insn "*cmp_zero_extendqisi2_set"
2926 [(set (reg:CC CC_REG)
2927 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2929 (set (match_operand:SI 0 "register_operand" "=r")
2930 (zero_extend:SI (match_dup 1)))]
2932 "andcc\t%1, 0xff, %0"
2933 [(set_attr "type" "compare")])
2935 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2936 [(set (reg:CC CC_REG)
2937 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2940 (set (match_operand:SI 0 "register_operand" "=r")
2941 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2943 "andcc\t%1, 0xff, %0"
2944 [(set_attr "type" "compare")])
2946 (define_insn "*cmp_zero_extendqidi2"
2947 [(set (reg:CCX CC_REG)
2948 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2951 "andcc\t%0, 0xff, %%g0"
2952 [(set_attr "type" "compare")])
2954 (define_insn "*cmp_zero_qi_sp64"
2955 [(set (reg:CCX CC_REG)
2956 (compare:CCX (match_operand:QI 0 "register_operand" "r")
2959 "andcc\t%0, 0xff, %%g0"
2960 [(set_attr "type" "compare")])
2962 (define_insn "*cmp_zero_extendqidi2_set"
2963 [(set (reg:CCX CC_REG)
2964 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2966 (set (match_operand:DI 0 "register_operand" "=r")
2967 (zero_extend:DI (match_dup 1)))]
2969 "andcc\t%1, 0xff, %0"
2970 [(set_attr "type" "compare")])
2972 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2973 [(set (reg:CCX CC_REG)
2974 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2977 (set (match_operand:DI 0 "register_operand" "=r")
2978 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2980 "andcc\t%1, 0xff, %0"
2981 [(set_attr "type" "compare")])
2983 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2985 (define_insn "*cmp_siqi_trunc"
2986 [(set (reg:CC CC_REG)
2987 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2990 "andcc\t%0, 0xff, %%g0"
2991 [(set_attr "type" "compare")])
2993 (define_insn "*cmp_siqi_trunc_set"
2994 [(set (reg:CC CC_REG)
2995 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
2997 (set (match_operand:QI 0 "register_operand" "=r")
2998 (subreg:QI (match_dup 1) 3))]
3000 "andcc\t%1, 0xff, %0"
3001 [(set_attr "type" "compare")])
3003 (define_insn "*cmp_diqi_trunc"
3004 [(set (reg:CC CC_REG)
3005 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3008 "andcc\t%0, 0xff, %%g0"
3009 [(set_attr "type" "compare")])
3011 (define_insn "*cmp_diqi_trunc_set"
3012 [(set (reg:CC CC_REG)
3013 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3015 (set (match_operand:QI 0 "register_operand" "=r")
3016 (subreg:QI (match_dup 1) 7))]
3018 "andcc\t%1, 0xff, %0"
3019 [(set_attr "type" "compare")])
3022 ;; Sign-extension instructions
3024 ;; These patterns originally accepted general_operands, however, slightly
3025 ;; better code is generated by only accepting register_operands, and then
3026 ;; letting combine generate the lds[hb] insns.
3028 (define_expand "extendhisi2"
3029 [(set (match_operand:SI 0 "register_operand" "")
3030 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3033 rtx temp = gen_reg_rtx (SImode);
3034 rtx shift_16 = GEN_INT (16);
3035 int op1_subbyte = 0;
3037 if (GET_CODE (operand1) == SUBREG)
3039 op1_subbyte = SUBREG_BYTE (operand1);
3040 op1_subbyte /= GET_MODE_SIZE (SImode);
3041 op1_subbyte *= GET_MODE_SIZE (SImode);
3042 operand1 = XEXP (operand1, 0);
3045 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3047 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3051 (define_insn "*sign_extendhisi2_insn"
3052 [(set (match_operand:SI 0 "register_operand" "=r")
3053 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3056 [(set_attr "type" "sload")
3057 (set_attr "us3load_type" "3cycle")])
3059 (define_expand "extendqihi2"
3060 [(set (match_operand:HI 0 "register_operand" "")
3061 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3064 rtx temp = gen_reg_rtx (SImode);
3065 rtx shift_24 = GEN_INT (24);
3066 int op1_subbyte = 0;
3067 int op0_subbyte = 0;
3069 if (GET_CODE (operand1) == SUBREG)
3071 op1_subbyte = SUBREG_BYTE (operand1);
3072 op1_subbyte /= GET_MODE_SIZE (SImode);
3073 op1_subbyte *= GET_MODE_SIZE (SImode);
3074 operand1 = XEXP (operand1, 0);
3076 if (GET_CODE (operand0) == SUBREG)
3078 op0_subbyte = SUBREG_BYTE (operand0);
3079 op0_subbyte /= GET_MODE_SIZE (SImode);
3080 op0_subbyte *= GET_MODE_SIZE (SImode);
3081 operand0 = XEXP (operand0, 0);
3083 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3085 if (GET_MODE (operand0) != SImode)
3086 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3087 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3091 (define_insn "*sign_extendqihi2_insn"
3092 [(set (match_operand:HI 0 "register_operand" "=r")
3093 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3096 [(set_attr "type" "sload")
3097 (set_attr "us3load_type" "3cycle")])
3099 (define_expand "extendqisi2"
3100 [(set (match_operand:SI 0 "register_operand" "")
3101 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3104 rtx temp = gen_reg_rtx (SImode);
3105 rtx shift_24 = GEN_INT (24);
3106 int op1_subbyte = 0;
3108 if (GET_CODE (operand1) == SUBREG)
3110 op1_subbyte = SUBREG_BYTE (operand1);
3111 op1_subbyte /= GET_MODE_SIZE (SImode);
3112 op1_subbyte *= GET_MODE_SIZE (SImode);
3113 operand1 = XEXP (operand1, 0);
3116 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3118 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3122 (define_insn "*sign_extendqisi2_insn"
3123 [(set (match_operand:SI 0 "register_operand" "=r")
3124 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3127 [(set_attr "type" "sload")
3128 (set_attr "us3load_type" "3cycle")])
3130 (define_expand "extendqidi2"
3131 [(set (match_operand:DI 0 "register_operand" "")
3132 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3135 rtx temp = gen_reg_rtx (DImode);
3136 rtx shift_56 = GEN_INT (56);
3137 int op1_subbyte = 0;
3139 if (GET_CODE (operand1) == SUBREG)
3141 op1_subbyte = SUBREG_BYTE (operand1);
3142 op1_subbyte /= GET_MODE_SIZE (DImode);
3143 op1_subbyte *= GET_MODE_SIZE (DImode);
3144 operand1 = XEXP (operand1, 0);
3147 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3149 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3153 (define_insn "*sign_extendqidi2_insn"
3154 [(set (match_operand:DI 0 "register_operand" "=r")
3155 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3158 [(set_attr "type" "sload")
3159 (set_attr "us3load_type" "3cycle")])
3161 (define_expand "extendhidi2"
3162 [(set (match_operand:DI 0 "register_operand" "")
3163 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3166 rtx temp = gen_reg_rtx (DImode);
3167 rtx shift_48 = GEN_INT (48);
3168 int op1_subbyte = 0;
3170 if (GET_CODE (operand1) == SUBREG)
3172 op1_subbyte = SUBREG_BYTE (operand1);
3173 op1_subbyte /= GET_MODE_SIZE (DImode);
3174 op1_subbyte *= GET_MODE_SIZE (DImode);
3175 operand1 = XEXP (operand1, 0);
3178 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3180 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3184 (define_insn "*sign_extendhidi2_insn"
3185 [(set (match_operand:DI 0 "register_operand" "=r")
3186 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3189 [(set_attr "type" "sload")
3190 (set_attr "us3load_type" "3cycle")])
3192 (define_expand "extendsidi2"
3193 [(set (match_operand:DI 0 "register_operand" "")
3194 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3198 (define_insn "*sign_extendsidi2_insn"
3199 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3200 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3206 [(set_attr "type" "shift,sload,*")
3207 (set_attr "us3load_type" "*,3cycle,*")
3208 (set_attr "cpu_feature" "*,*,vis3")])
3211 ;; Special pattern for optimizing bit-field compares. This is needed
3212 ;; because combine uses this as a canonical form.
3214 (define_insn "*cmp_zero_extract"
3215 [(set (reg:CC CC_REG)
3217 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3218 (match_operand:SI 1 "small_int_operand" "I")
3219 (match_operand:SI 2 "small_int_operand" "I"))
3221 "INTVAL (operands[2]) > 19"
3223 int len = INTVAL (operands[1]);
3224 int pos = 32 - INTVAL (operands[2]) - len;
3225 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3226 operands[1] = GEN_INT (mask);
3227 return "andcc\t%0, %1, %%g0";
3229 [(set_attr "type" "compare")])
3231 (define_insn "*cmp_zero_extract_sp64"
3232 [(set (reg:CCX CC_REG)
3234 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3235 (match_operand:SI 1 "small_int_operand" "I")
3236 (match_operand:SI 2 "small_int_operand" "I"))
3238 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3240 int len = INTVAL (operands[1]);
3241 int pos = 64 - INTVAL (operands[2]) - len;
3242 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3243 operands[1] = GEN_INT (mask);
3244 return "andcc\t%0, %1, %%g0";
3246 [(set_attr "type" "compare")])
3249 ;; Conversions between float, double and long double.
3251 (define_insn "extendsfdf2"
3252 [(set (match_operand:DF 0 "register_operand" "=e")
3254 (match_operand:SF 1 "register_operand" "f")))]
3257 [(set_attr "type" "fp")
3258 (set_attr "fptype" "double")])
3260 (define_expand "extendsftf2"
3261 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3263 (match_operand:SF 1 "register_operand" "")))]
3264 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3265 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3267 (define_insn "*extendsftf2_hq"
3268 [(set (match_operand:TF 0 "register_operand" "=e")
3270 (match_operand:SF 1 "register_operand" "f")))]
3271 "TARGET_FPU && TARGET_HARD_QUAD"
3273 [(set_attr "type" "fp")])
3275 (define_expand "extenddftf2"
3276 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3278 (match_operand:DF 1 "register_operand" "")))]
3279 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3280 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3282 (define_insn "*extenddftf2_hq"
3283 [(set (match_operand:TF 0 "register_operand" "=e")
3285 (match_operand:DF 1 "register_operand" "e")))]
3286 "TARGET_FPU && TARGET_HARD_QUAD"
3288 [(set_attr "type" "fp")])
3290 (define_insn "truncdfsf2"
3291 [(set (match_operand:SF 0 "register_operand" "=f")
3293 (match_operand:DF 1 "register_operand" "e")))]
3296 [(set_attr "type" "fp")
3297 (set_attr "fptype" "double")])
3299 (define_expand "trunctfsf2"
3300 [(set (match_operand:SF 0 "register_operand" "")
3302 (match_operand:TF 1 "general_operand" "")))]
3303 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3304 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3306 (define_insn "*trunctfsf2_hq"
3307 [(set (match_operand:SF 0 "register_operand" "=f")
3309 (match_operand:TF 1 "register_operand" "e")))]
3310 "TARGET_FPU && TARGET_HARD_QUAD"
3312 [(set_attr "type" "fp")])
3314 (define_expand "trunctfdf2"
3315 [(set (match_operand:DF 0 "register_operand" "")
3317 (match_operand:TF 1 "general_operand" "")))]
3318 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3319 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3321 (define_insn "*trunctfdf2_hq"
3322 [(set (match_operand:DF 0 "register_operand" "=e")
3324 (match_operand:TF 1 "register_operand" "e")))]
3325 "TARGET_FPU && TARGET_HARD_QUAD"
3327 [(set_attr "type" "fp")])
3330 ;; Conversion between fixed point and floating point.
3332 (define_insn "floatsisf2"
3333 [(set (match_operand:SF 0 "register_operand" "=f")
3334 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3337 [(set_attr "type" "fp")
3338 (set_attr "fptype" "double")])
3340 (define_insn "floatsidf2"
3341 [(set (match_operand:DF 0 "register_operand" "=e")
3342 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3345 [(set_attr "type" "fp")
3346 (set_attr "fptype" "double")])
3348 (define_expand "floatsitf2"
3349 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3350 (float:TF (match_operand:SI 1 "register_operand" "")))]
3351 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3352 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3354 (define_insn "*floatsitf2_hq"
3355 [(set (match_operand:TF 0 "register_operand" "=e")
3356 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3357 "TARGET_FPU && TARGET_HARD_QUAD"
3359 [(set_attr "type" "fp")])
3361 (define_expand "floatunssitf2"
3362 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3363 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3364 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3365 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3367 ;; Now the same for 64 bit sources.
3369 (define_insn "floatdisf2"
3370 [(set (match_operand:SF 0 "register_operand" "=f")
3371 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3372 "TARGET_V9 && TARGET_FPU"
3374 [(set_attr "type" "fp")
3375 (set_attr "fptype" "double")])
3377 (define_expand "floatunsdisf2"
3378 [(use (match_operand:SF 0 "register_operand" ""))
3379 (use (match_operand:DI 1 "general_operand" ""))]
3380 "TARGET_ARCH64 && TARGET_FPU"
3381 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3383 (define_insn "floatdidf2"
3384 [(set (match_operand:DF 0 "register_operand" "=e")
3385 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3386 "TARGET_V9 && TARGET_FPU"
3388 [(set_attr "type" "fp")
3389 (set_attr "fptype" "double")])
3391 (define_expand "floatunsdidf2"
3392 [(use (match_operand:DF 0 "register_operand" ""))
3393 (use (match_operand:DI 1 "general_operand" ""))]
3394 "TARGET_ARCH64 && TARGET_FPU"
3395 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3397 (define_expand "floatditf2"
3398 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3399 (float:TF (match_operand:DI 1 "register_operand" "")))]
3400 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3401 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3403 (define_insn "*floatditf2_hq"
3404 [(set (match_operand:TF 0 "register_operand" "=e")
3405 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3406 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3408 [(set_attr "type" "fp")])
3410 (define_expand "floatunsditf2"
3411 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3412 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3413 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3414 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3416 ;; Convert a float to an actual integer.
3417 ;; Truncation is performed as part of the conversion.
3419 (define_insn "fix_truncsfsi2"
3420 [(set (match_operand:SI 0 "register_operand" "=f")
3421 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3424 [(set_attr "type" "fp")
3425 (set_attr "fptype" "double")])
3427 (define_insn "fix_truncdfsi2"
3428 [(set (match_operand:SI 0 "register_operand" "=f")
3429 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3432 [(set_attr "type" "fp")
3433 (set_attr "fptype" "double")])
3435 (define_expand "fix_trunctfsi2"
3436 [(set (match_operand:SI 0 "register_operand" "")
3437 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3438 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3439 "emit_tfmode_cvt (FIX, operands); DONE;")
3441 (define_insn "*fix_trunctfsi2_hq"
3442 [(set (match_operand:SI 0 "register_operand" "=f")
3443 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3444 "TARGET_FPU && TARGET_HARD_QUAD"
3446 [(set_attr "type" "fp")])
3448 (define_expand "fixuns_trunctfsi2"
3449 [(set (match_operand:SI 0 "register_operand" "")
3450 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3451 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3452 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3454 ;; Now the same, for V9 targets
3456 (define_insn "fix_truncsfdi2"
3457 [(set (match_operand:DI 0 "register_operand" "=e")
3458 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3459 "TARGET_V9 && TARGET_FPU"
3461 [(set_attr "type" "fp")
3462 (set_attr "fptype" "double")])
3464 (define_expand "fixuns_truncsfdi2"
3465 [(use (match_operand:DI 0 "register_operand" ""))
3466 (use (match_operand:SF 1 "general_operand" ""))]
3467 "TARGET_ARCH64 && TARGET_FPU"
3468 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3470 (define_insn "fix_truncdfdi2"
3471 [(set (match_operand:DI 0 "register_operand" "=e")
3472 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3473 "TARGET_V9 && TARGET_FPU"
3475 [(set_attr "type" "fp")
3476 (set_attr "fptype" "double")])
3478 (define_expand "fixuns_truncdfdi2"
3479 [(use (match_operand:DI 0 "register_operand" ""))
3480 (use (match_operand:DF 1 "general_operand" ""))]
3481 "TARGET_ARCH64 && TARGET_FPU"
3482 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3484 (define_expand "fix_trunctfdi2"
3485 [(set (match_operand:DI 0 "register_operand" "")
3486 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3487 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3488 "emit_tfmode_cvt (FIX, operands); DONE;")
3490 (define_insn "*fix_trunctfdi2_hq"
3491 [(set (match_operand:DI 0 "register_operand" "=e")
3492 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3493 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3495 [(set_attr "type" "fp")])
3497 (define_expand "fixuns_trunctfdi2"
3498 [(set (match_operand:DI 0 "register_operand" "")
3499 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3500 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3501 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3504 ;; Integer addition/subtraction instructions.
3506 (define_expand "adddi3"
3507 [(set (match_operand:DI 0 "register_operand" "")
3508 (plus:DI (match_operand:DI 1 "register_operand" "")
3509 (match_operand:DI 2 "arith_double_add_operand" "")))]
3512 if (! TARGET_ARCH64)
3514 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3515 gen_rtx_SET (VOIDmode, operands[0],
3516 gen_rtx_PLUS (DImode, operands[1],
3518 gen_rtx_CLOBBER (VOIDmode,
3519 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3524 (define_insn_and_split "*adddi3_insn_sp32"
3525 [(set (match_operand:DI 0 "register_operand" "=r")
3526 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3527 (match_operand:DI 2 "arith_double_operand" "rHI")))
3528 (clobber (reg:CC CC_REG))]
3531 "&& reload_completed"
3532 [(parallel [(set (reg:CC_NOOV CC_REG)
3533 (compare:CC_NOOV (plus:SI (match_dup 4)
3537 (plus:SI (match_dup 4) (match_dup 5)))])
3539 (plus:SI (plus:SI (match_dup 7)
3541 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3543 operands[3] = gen_lowpart (SImode, operands[0]);
3544 operands[4] = gen_lowpart (SImode, operands[1]);
3545 operands[5] = gen_lowpart (SImode, operands[2]);
3546 operands[6] = gen_highpart (SImode, operands[0]);
3547 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3548 #if HOST_BITS_PER_WIDE_INT == 32
3549 if (GET_CODE (operands[2]) == CONST_INT)
3551 if (INTVAL (operands[2]) < 0)
3552 operands[8] = constm1_rtx;
3554 operands[8] = const0_rtx;
3558 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3560 [(set_attr "length" "2")])
3562 ;; LTU here means "carry set"
3564 [(set (match_operand:SI 0 "register_operand" "=r")
3565 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3566 (match_operand:SI 2 "arith_operand" "rI"))
3567 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3570 [(set_attr "type" "ialuX")])
3572 (define_insn "addxc"
3573 [(set (match_operand:DI 0 "register_operand" "=r")
3574 (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
3575 (match_operand:DI 2 "register_or_zero_operand" "rJ"))
3576 (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3577 "TARGET_ARCH64 && TARGET_VIS3"
3578 "addxc\t%r1, %r2, %0"
3579 [(set_attr "type" "ialuX")])
3581 (define_insn_and_split "*addx_extend_sp32"
3582 [(set (match_operand:DI 0 "register_operand" "=r")
3583 (zero_extend:DI (plus:SI (plus:SI
3584 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3585 (match_operand:SI 2 "arith_operand" "rI"))
3586 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3589 "&& reload_completed"
3590 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3591 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3592 (set (match_dup 4) (const_int 0))]
3593 "operands[3] = gen_lowpart (SImode, operands[0]);
3594 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3595 [(set_attr "length" "2")])
3597 (define_insn "*addx_extend_sp64"
3598 [(set (match_operand:DI 0 "register_operand" "=r")
3599 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3600 (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3601 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3603 "addx\t%r1, %r2, %0"
3604 [(set_attr "type" "ialuX")])
3606 (define_insn "*addxc_trunc_sp64_vis3"
3607 [(set (match_operand:SI 0 "register_operand" "=r")
3608 (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3609 (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3610 (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3611 "TARGET_ARCH64 && TARGET_VIS3"
3612 "addxc\t%r1, %r2, %0"
3613 [(set_attr "type" "ialuX")])
3615 (define_insn_and_split "*adddi3_extend_sp32"
3616 [(set (match_operand:DI 0 "register_operand" "=r")
3617 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3618 (match_operand:DI 2 "register_operand" "r")))
3619 (clobber (reg:CC CC_REG))]
3622 "&& reload_completed"
3623 [(parallel [(set (reg:CC_NOOV CC_REG)
3624 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3626 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3628 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3629 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3630 "operands[3] = gen_lowpart (SImode, operands[2]);
3631 operands[4] = gen_highpart (SImode, operands[2]);
3632 operands[5] = gen_lowpart (SImode, operands[0]);
3633 operands[6] = gen_highpart (SImode, operands[0]);"
3634 [(set_attr "length" "2")])
3636 (define_insn "*adddi3_sp64"
3637 [(set (match_operand:DI 0 "register_operand" "=r,r")
3638 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3639 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3645 (define_insn "addsi3"
3646 [(set (match_operand:SI 0 "register_operand" "=r,r")
3647 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3648 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3653 [(set_attr "type" "*,*")
3654 (set_attr "fptype" "*,*")])
3656 (define_insn "*cmp_cc_plus"
3657 [(set (reg:CC_NOOV CC_REG)
3658 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3659 (match_operand:SI 1 "arith_operand" "rI"))
3662 "addcc\t%0, %1, %%g0"
3663 [(set_attr "type" "compare")])
3665 (define_insn "*cmp_ccx_plus"
3666 [(set (reg:CCX_NOOV CC_REG)
3667 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3668 (match_operand:DI 1 "arith_operand" "rI"))
3671 "addcc\t%0, %1, %%g0"
3672 [(set_attr "type" "compare")])
3674 (define_insn "*cmp_cc_plus_set"
3675 [(set (reg:CC_NOOV CC_REG)
3676 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3677 (match_operand:SI 2 "arith_operand" "rI"))
3679 (set (match_operand:SI 0 "register_operand" "=r")
3680 (plus:SI (match_dup 1) (match_dup 2)))]
3683 [(set_attr "type" "compare")])
3685 (define_insn "*cmp_ccx_plus_set"
3686 [(set (reg:CCX_NOOV CC_REG)
3687 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3688 (match_operand:DI 2 "arith_operand" "rI"))
3690 (set (match_operand:DI 0 "register_operand" "=r")
3691 (plus:DI (match_dup 1) (match_dup 2)))]
3694 [(set_attr "type" "compare")])
3696 (define_expand "subdi3"
3697 [(set (match_operand:DI 0 "register_operand" "")
3698 (minus:DI (match_operand:DI 1 "register_operand" "")
3699 (match_operand:DI 2 "arith_double_add_operand" "")))]
3702 if (! TARGET_ARCH64)
3704 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3705 gen_rtx_SET (VOIDmode, operands[0],
3706 gen_rtx_MINUS (DImode, operands[1],
3708 gen_rtx_CLOBBER (VOIDmode,
3709 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3714 (define_insn_and_split "*subdi3_insn_sp32"
3715 [(set (match_operand:DI 0 "register_operand" "=r")
3716 (minus:DI (match_operand:DI 1 "register_operand" "r")
3717 (match_operand:DI 2 "arith_double_operand" "rHI")))
3718 (clobber (reg:CC CC_REG))]
3721 "&& reload_completed"
3722 [(parallel [(set (reg:CC_NOOV CC_REG)
3723 (compare:CC_NOOV (minus:SI (match_dup 4)
3727 (minus:SI (match_dup 4) (match_dup 5)))])
3729 (minus:SI (minus:SI (match_dup 7)
3731 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3733 operands[3] = gen_lowpart (SImode, operands[0]);
3734 operands[4] = gen_lowpart (SImode, operands[1]);
3735 operands[5] = gen_lowpart (SImode, operands[2]);
3736 operands[6] = gen_highpart (SImode, operands[0]);
3737 operands[7] = gen_highpart (SImode, operands[1]);
3738 #if HOST_BITS_PER_WIDE_INT == 32
3739 if (GET_CODE (operands[2]) == CONST_INT)
3741 if (INTVAL (operands[2]) < 0)
3742 operands[8] = constm1_rtx;
3744 operands[8] = const0_rtx;
3748 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3750 [(set_attr "length" "2")])
3752 ;; LTU here means "carry set"
3754 [(set (match_operand:SI 0 "register_operand" "=r")
3755 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3756 (match_operand:SI 2 "arith_operand" "rI"))
3757 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3760 [(set_attr "type" "ialuX")])
3762 (define_insn "*subx_extend_sp64"
3763 [(set (match_operand:DI 0 "register_operand" "=r")
3764 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3765 (match_operand:SI 2 "arith_operand" "rI"))
3766 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3769 [(set_attr "type" "ialuX")])
3771 (define_insn_and_split "*subx_extend"
3772 [(set (match_operand:DI 0 "register_operand" "=r")
3773 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3774 (match_operand:SI 2 "arith_operand" "rI"))
3775 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3778 "&& reload_completed"
3779 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3780 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3781 (set (match_dup 4) (const_int 0))]
3782 "operands[3] = gen_lowpart (SImode, operands[0]);
3783 operands[4] = gen_highpart (SImode, operands[0]);"
3784 [(set_attr "length" "2")])
3786 (define_insn_and_split "*subdi3_extend_sp32"
3787 [(set (match_operand:DI 0 "register_operand" "=r")
3788 (minus:DI (match_operand:DI 1 "register_operand" "r")
3789 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3790 (clobber (reg:CC CC_REG))]
3793 "&& reload_completed"
3794 [(parallel [(set (reg:CC_NOOV CC_REG)
3795 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3797 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3799 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3800 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3801 "operands[3] = gen_lowpart (SImode, operands[1]);
3802 operands[4] = gen_highpart (SImode, operands[1]);
3803 operands[5] = gen_lowpart (SImode, operands[0]);
3804 operands[6] = gen_highpart (SImode, operands[0]);"
3805 [(set_attr "length" "2")])
3807 (define_insn "*subdi3_sp64"
3808 [(set (match_operand:DI 0 "register_operand" "=r,r")
3809 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3810 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3816 (define_insn "subsi3"
3817 [(set (match_operand:SI 0 "register_operand" "=r,r")
3818 (minus:SI (match_operand:SI 1 "register_operand" "r,r")
3819 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3824 [(set_attr "type" "*,*")
3825 (set_attr "fptype" "*,*")])
3827 (define_insn "*cmp_minus_cc"
3828 [(set (reg:CC_NOOV CC_REG)
3829 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3830 (match_operand:SI 1 "arith_operand" "rI"))
3833 "subcc\t%r0, %1, %%g0"
3834 [(set_attr "type" "compare")])
3836 (define_insn "*cmp_minus_ccx"
3837 [(set (reg:CCX_NOOV CC_REG)
3838 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3839 (match_operand:DI 1 "arith_operand" "rI"))
3842 "subcc\t%0, %1, %%g0"
3843 [(set_attr "type" "compare")])
3845 (define_insn "cmp_minus_cc_set"
3846 [(set (reg:CC_NOOV CC_REG)
3847 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3848 (match_operand:SI 2 "arith_operand" "rI"))
3850 (set (match_operand:SI 0 "register_operand" "=r")
3851 (minus:SI (match_dup 1) (match_dup 2)))]
3853 "subcc\t%r1, %2, %0"
3854 [(set_attr "type" "compare")])
3856 (define_insn "*cmp_minus_ccx_set"
3857 [(set (reg:CCX_NOOV CC_REG)
3858 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3859 (match_operand:DI 2 "arith_operand" "rI"))
3861 (set (match_operand:DI 0 "register_operand" "=r")
3862 (minus:DI (match_dup 1) (match_dup 2)))]
3865 [(set_attr "type" "compare")])
3868 ;; Integer multiply/divide instructions.
3870 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3871 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3873 (define_insn "mulsi3"
3874 [(set (match_operand:SI 0 "register_operand" "=r")
3875 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3876 (match_operand:SI 2 "arith_operand" "rI")))]
3879 [(set_attr "type" "imul")])
3881 (define_expand "muldi3"
3882 [(set (match_operand:DI 0 "register_operand" "")
3883 (mult:DI (match_operand:DI 1 "arith_operand" "")
3884 (match_operand:DI 2 "arith_operand" "")))]
3885 "TARGET_ARCH64 || TARGET_V8PLUS"
3889 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3894 (define_insn "*muldi3_sp64"
3895 [(set (match_operand:DI 0 "register_operand" "=r")
3896 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3897 (match_operand:DI 2 "arith_operand" "rI")))]
3900 [(set_attr "type" "imul")])
3902 ;; V8plus wide multiply.
3904 (define_insn "muldi3_v8plus"
3905 [(set (match_operand:DI 0 "register_operand" "=r,h")
3906 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3907 (match_operand:DI 2 "arith_operand" "rI,rI")))
3908 (clobber (match_scratch:SI 3 "=&h,X"))
3909 (clobber (match_scratch:SI 4 "=&h,X"))]
3911 "* return output_v8plus_mult (insn, operands, \"mulx\");"
3912 [(set_attr "type" "multi")
3913 (set_attr "length" "9,8")])
3915 (define_insn "*cmp_mul_set"
3916 [(set (reg:CC CC_REG)
3917 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3918 (match_operand:SI 2 "arith_operand" "rI"))
3920 (set (match_operand:SI 0 "register_operand" "=r")
3921 (mult:SI (match_dup 1) (match_dup 2)))]
3922 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3923 "smulcc\t%1, %2, %0"
3924 [(set_attr "type" "imul")])
3926 (define_expand "mulsidi3"
3927 [(set (match_operand:DI 0 "register_operand" "")
3928 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3929 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3932 if (CONSTANT_P (operands[2]))
3935 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3937 else if (TARGET_ARCH32)
3938 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3941 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3947 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3952 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
3953 ;; registers can hold 64-bit values in the V8plus environment.
3955 (define_insn "mulsidi3_v8plus"
3956 [(set (match_operand:DI 0 "register_operand" "=h,r")
3957 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3958 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3959 (clobber (match_scratch:SI 3 "=X,&h"))]
3962 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3963 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3964 [(set_attr "type" "multi")
3965 (set_attr "length" "2,3")])
3968 (define_insn "const_mulsidi3_v8plus"
3969 [(set (match_operand:DI 0 "register_operand" "=h,r")
3970 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3971 (match_operand:DI 2 "small_int_operand" "I,I")))
3972 (clobber (match_scratch:SI 3 "=X,&h"))]
3975 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3976 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3977 [(set_attr "type" "multi")
3978 (set_attr "length" "2,3")])
3981 (define_insn "*mulsidi3_sp32"
3982 [(set (match_operand:DI 0 "register_operand" "=r")
3983 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3984 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3987 return TARGET_SPARCLET
3988 ? "smuld\t%1, %2, %L0"
3989 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3992 (if_then_else (eq_attr "isa" "sparclet")
3993 (const_string "imul") (const_string "multi")))
3994 (set (attr "length")
3995 (if_then_else (eq_attr "isa" "sparclet")
3996 (const_int 1) (const_int 2)))])
3998 (define_insn "*mulsidi3_sp64"
3999 [(set (match_operand:DI 0 "register_operand" "=r")
4000 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4001 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4002 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4004 [(set_attr "type" "imul")])
4006 ;; Extra pattern, because sign_extend of a constant isn't valid.
4009 (define_insn "const_mulsidi3_sp32"
4010 [(set (match_operand:DI 0 "register_operand" "=r")
4011 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4012 (match_operand:DI 2 "small_int_operand" "I")))]
4015 return TARGET_SPARCLET
4016 ? "smuld\t%1, %2, %L0"
4017 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4020 (if_then_else (eq_attr "isa" "sparclet")
4021 (const_string "imul") (const_string "multi")))
4022 (set (attr "length")
4023 (if_then_else (eq_attr "isa" "sparclet")
4024 (const_int 1) (const_int 2)))])
4026 (define_insn "const_mulsidi3_sp64"
4027 [(set (match_operand:DI 0 "register_operand" "=r")
4028 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4029 (match_operand:DI 2 "small_int_operand" "I")))]
4030 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4032 [(set_attr "type" "imul")])
4034 (define_expand "smulsi3_highpart"
4035 [(set (match_operand:SI 0 "register_operand" "")
4037 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4038 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4040 "TARGET_HARD_MUL && TARGET_ARCH32"
4042 if (CONSTANT_P (operands[2]))
4046 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4052 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4057 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4058 operands[2], GEN_INT (32)));
4064 (define_insn "smulsi3_highpart_v8plus"
4065 [(set (match_operand:SI 0 "register_operand" "=h,r")
4067 (lshiftrt:DI (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 (match_operand:SI 3 "small_int_operand" "I,I"))))
4070 (clobber (match_scratch:SI 4 "=X,&h"))]
4073 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4074 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4075 [(set_attr "type" "multi")
4076 (set_attr "length" "2")])
4078 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4081 [(set (match_operand:SI 0 "register_operand" "=h,r")
4084 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4085 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4086 (match_operand:SI 3 "small_int_operand" "I,I"))
4088 (clobber (match_scratch:SI 4 "=X,&h"))]
4091 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4092 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4093 [(set_attr "type" "multi")
4094 (set_attr "length" "2")])
4097 (define_insn "const_smulsi3_highpart_v8plus"
4098 [(set (match_operand:SI 0 "register_operand" "=h,r")
4100 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4101 (match_operand:DI 2 "small_int_operand" "I,I"))
4102 (match_operand:SI 3 "small_int_operand" "I,I"))))
4103 (clobber (match_scratch:SI 4 "=X,&h"))]
4106 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4107 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4108 [(set_attr "type" "multi")
4109 (set_attr "length" "2")])
4112 (define_insn "*smulsi3_highpart_sp32"
4113 [(set (match_operand:SI 0 "register_operand" "=r")
4115 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4116 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4119 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4120 [(set_attr "type" "multi")
4121 (set_attr "length" "2")])
4124 (define_insn "const_smulsi3_highpart"
4125 [(set (match_operand:SI 0 "register_operand" "=r")
4127 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4128 (match_operand:DI 2 "small_int_operand" "i"))
4131 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4132 [(set_attr "type" "multi")
4133 (set_attr "length" "2")])
4135 (define_expand "umulsidi3"
4136 [(set (match_operand:DI 0 "register_operand" "")
4137 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4138 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4141 if (CONSTANT_P (operands[2]))
4144 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4146 else if (TARGET_ARCH32)
4147 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4150 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4156 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4162 (define_insn "umulsidi3_v8plus"
4163 [(set (match_operand:DI 0 "register_operand" "=h,r")
4164 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4165 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4166 (clobber (match_scratch:SI 3 "=X,&h"))]
4169 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4170 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4171 [(set_attr "type" "multi")
4172 (set_attr "length" "2,3")])
4175 (define_insn "*umulsidi3_sp32"
4176 [(set (match_operand:DI 0 "register_operand" "=r")
4177 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4178 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4181 return TARGET_SPARCLET
4182 ? "umuld\t%1, %2, %L0"
4183 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4186 (if_then_else (eq_attr "isa" "sparclet")
4187 (const_string "imul") (const_string "multi")))
4188 (set (attr "length")
4189 (if_then_else (eq_attr "isa" "sparclet")
4190 (const_int 1) (const_int 2)))])
4192 (define_insn "*umulsidi3_sp64"
4193 [(set (match_operand:DI 0 "register_operand" "=r")
4194 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4195 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4196 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4198 [(set_attr "type" "imul")])
4200 ;; Extra pattern, because sign_extend of a constant isn't valid.
4203 (define_insn "const_umulsidi3_sp32"
4204 [(set (match_operand:DI 0 "register_operand" "=r")
4205 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4206 (match_operand:DI 2 "uns_small_int_operand" "")))]
4209 return TARGET_SPARCLET
4210 ? "umuld\t%1, %s2, %L0"
4211 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4214 (if_then_else (eq_attr "isa" "sparclet")
4215 (const_string "imul") (const_string "multi")))
4216 (set (attr "length")
4217 (if_then_else (eq_attr "isa" "sparclet")
4218 (const_int 1) (const_int 2)))])
4220 (define_insn "const_umulsidi3_sp64"
4221 [(set (match_operand:DI 0 "register_operand" "=r")
4222 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4223 (match_operand:DI 2 "uns_small_int_operand" "")))]
4224 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4226 [(set_attr "type" "imul")])
4229 (define_insn "const_umulsidi3_v8plus"
4230 [(set (match_operand:DI 0 "register_operand" "=h,r")
4231 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4232 (match_operand:DI 2 "uns_small_int_operand" "")))
4233 (clobber (match_scratch:SI 3 "=X,h"))]
4236 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4237 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4238 [(set_attr "type" "multi")
4239 (set_attr "length" "2,3")])
4241 (define_expand "umulsi3_highpart"
4242 [(set (match_operand:SI 0 "register_operand" "")
4244 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4245 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4247 "TARGET_HARD_MUL && TARGET_ARCH32"
4249 if (CONSTANT_P (operands[2]))
4253 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4259 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4264 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4265 operands[2], GEN_INT (32)));
4271 (define_insn "umulsi3_highpart_v8plus"
4272 [(set (match_operand:SI 0 "register_operand" "=h,r")
4274 (lshiftrt:DI (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 (match_operand:SI 3 "small_int_operand" "I,I"))))
4277 (clobber (match_scratch:SI 4 "=X,h"))]
4280 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4281 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4282 [(set_attr "type" "multi")
4283 (set_attr "length" "2")])
4286 (define_insn "const_umulsi3_highpart_v8plus"
4287 [(set (match_operand:SI 0 "register_operand" "=h,r")
4289 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4290 (match_operand:DI 2 "uns_small_int_operand" ""))
4291 (match_operand:SI 3 "small_int_operand" "I,I"))))
4292 (clobber (match_scratch:SI 4 "=X,h"))]
4295 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4296 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4297 [(set_attr "type" "multi")
4298 (set_attr "length" "2")])
4301 (define_insn "*umulsi3_highpart_sp32"
4302 [(set (match_operand:SI 0 "register_operand" "=r")
4304 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4305 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4308 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4309 [(set_attr "type" "multi")
4310 (set_attr "length" "2")])
4313 (define_insn "const_umulsi3_highpart"
4314 [(set (match_operand:SI 0 "register_operand" "=r")
4316 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4317 (match_operand:DI 2 "uns_small_int_operand" ""))
4320 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4321 [(set_attr "type" "multi")
4322 (set_attr "length" "2")])
4324 (define_expand "divsi3"
4325 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4326 (div:SI (match_operand:SI 1 "register_operand" "")
4327 (match_operand:SI 2 "input_operand" "")))
4328 (clobber (match_scratch:SI 3 ""))])]
4329 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4333 operands[3] = gen_reg_rtx(SImode);
4334 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4335 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4341 ;; The V8 architecture specifies that there must be at least 3 instructions
4342 ;; between a write to the Y register and a use of it for correct results.
4343 ;; We try to fill one of them with a simple constant or a memory load.
4345 (define_insn "divsi3_sp32"
4346 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4347 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4348 (match_operand:SI 2 "input_operand" "rI,K,m")))
4349 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4350 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4352 output_asm_insn ("sra\t%1, 31, %3", operands);
4353 output_asm_insn ("wr\t%3, 0, %%y", operands);
4355 switch (which_alternative)
4359 return "sdiv\t%1, %2, %0";
4361 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4364 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4366 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4369 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4371 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4376 [(set_attr "type" "multi")
4377 (set (attr "length")
4378 (if_then_else (eq_attr "isa" "v9")
4379 (const_int 4) (const_int 6)))])
4381 (define_insn "divsi3_sp64"
4382 [(set (match_operand:SI 0 "register_operand" "=r")
4383 (div:SI (match_operand:SI 1 "register_operand" "r")
4384 (match_operand:SI 2 "input_operand" "rI")))
4385 (use (match_operand:SI 3 "register_operand" "r"))]
4386 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4387 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4388 [(set_attr "type" "multi")
4389 (set_attr "length" "2")])
4391 (define_insn "divdi3"
4392 [(set (match_operand:DI 0 "register_operand" "=r")
4393 (div:DI (match_operand:DI 1 "register_operand" "r")
4394 (match_operand:DI 2 "arith_operand" "rI")))]
4397 [(set_attr "type" "idiv")])
4399 (define_insn "*cmp_sdiv_cc_set"
4400 [(set (reg:CC CC_REG)
4401 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4402 (match_operand:SI 2 "arith_operand" "rI"))
4404 (set (match_operand:SI 0 "register_operand" "=r")
4405 (div:SI (match_dup 1) (match_dup 2)))
4406 (clobber (match_scratch:SI 3 "=&r"))]
4407 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4409 output_asm_insn ("sra\t%1, 31, %3", operands);
4410 output_asm_insn ("wr\t%3, 0, %%y", operands);
4413 return "sdivcc\t%1, %2, %0";
4415 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4417 [(set_attr "type" "multi")
4418 (set (attr "length")
4419 (if_then_else (eq_attr "isa" "v9")
4420 (const_int 3) (const_int 6)))])
4423 (define_expand "udivsi3"
4424 [(set (match_operand:SI 0 "register_operand" "")
4425 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4426 (match_operand:SI 2 "input_operand" "")))]
4427 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4430 ;; The V8 architecture specifies that there must be at least 3 instructions
4431 ;; between a write to the Y register and a use of it for correct results.
4432 ;; We try to fill one of them with a simple constant or a memory load.
4434 (define_insn "udivsi3_sp32"
4435 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4436 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4437 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4438 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4440 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4442 switch (which_alternative)
4446 return "udiv\t%1, %2, %0";
4448 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4451 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4453 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4456 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4458 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4461 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4463 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4468 [(set_attr "type" "multi")
4469 (set (attr "length")
4470 (if_then_else (eq_attr "isa" "v9")
4471 (const_int 3) (const_int 5)))])
4473 (define_insn "udivsi3_sp64"
4474 [(set (match_operand:SI 0 "register_operand" "=r")
4475 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4476 (match_operand:SI 2 "input_operand" "rI")))]
4477 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4478 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4479 [(set_attr "type" "multi")
4480 (set_attr "length" "2")])
4482 (define_insn "udivdi3"
4483 [(set (match_operand:DI 0 "register_operand" "=r")
4484 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4485 (match_operand:DI 2 "arith_operand" "rI")))]
4488 [(set_attr "type" "idiv")])
4490 (define_insn "*cmp_udiv_cc_set"
4491 [(set (reg:CC CC_REG)
4492 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4493 (match_operand:SI 2 "arith_operand" "rI"))
4495 (set (match_operand:SI 0 "register_operand" "=r")
4496 (udiv:SI (match_dup 1) (match_dup 2)))]
4497 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4499 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4502 return "udivcc\t%1, %2, %0";
4504 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4506 [(set_attr "type" "multi")
4507 (set (attr "length")
4508 (if_then_else (eq_attr "isa" "v9")
4509 (const_int 2) (const_int 5)))])
4511 ; sparclet multiply/accumulate insns
4513 (define_insn "*smacsi"
4514 [(set (match_operand:SI 0 "register_operand" "=r")
4515 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4516 (match_operand:SI 2 "arith_operand" "rI"))
4517 (match_operand:SI 3 "register_operand" "0")))]
4520 [(set_attr "type" "imul")])
4522 (define_insn "*smacdi"
4523 [(set (match_operand:DI 0 "register_operand" "=r")
4524 (plus:DI (mult:DI (sign_extend:DI
4525 (match_operand:SI 1 "register_operand" "%r"))
4527 (match_operand:SI 2 "register_operand" "r")))
4528 (match_operand:DI 3 "register_operand" "0")))]
4530 "smacd\t%1, %2, %L0"
4531 [(set_attr "type" "imul")])
4533 (define_insn "*umacdi"
4534 [(set (match_operand:DI 0 "register_operand" "=r")
4535 (plus:DI (mult:DI (zero_extend:DI
4536 (match_operand:SI 1 "register_operand" "%r"))
4538 (match_operand:SI 2 "register_operand" "r")))
4539 (match_operand:DI 3 "register_operand" "0")))]
4541 "umacd\t%1, %2, %L0"
4542 [(set_attr "type" "imul")])
4545 ;; Boolean instructions.
4547 ;; We define DImode `and' so with DImode `not' we can get
4548 ;; DImode `andn'. Other combinations are possible.
4550 (define_expand "anddi3"
4551 [(set (match_operand:DI 0 "register_operand" "")
4552 (and:DI (match_operand:DI 1 "arith_double_operand" "")
4553 (match_operand:DI 2 "arith_double_operand" "")))]
4557 (define_insn "*anddi3_sp32"
4558 [(set (match_operand:DI 0 "register_operand" "=r")
4559 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4560 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4564 (define_insn "*anddi3_sp64"
4565 [(set (match_operand:DI 0 "register_operand" "=r")
4566 (and:DI (match_operand:DI 1 "arith_operand" "%r")
4567 (match_operand:DI 2 "arith_operand" "rI")))]
4571 (define_insn "andsi3"
4572 [(set (match_operand:SI 0 "register_operand" "=r")
4573 (and:SI (match_operand:SI 1 "arith_operand" "%r")
4574 (match_operand:SI 2 "arith_operand" "rI")))]
4579 [(set (match_operand:SI 0 "register_operand" "")
4580 (and:SI (match_operand:SI 1 "register_operand" "")
4581 (match_operand:SI 2 "const_compl_high_operand" "")))
4582 (clobber (match_operand:SI 3 "register_operand" ""))]
4584 [(set (match_dup 3) (match_dup 4))
4585 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4587 operands[4] = GEN_INT (~INTVAL (operands[2]));
4590 (define_insn_and_split "*and_not_di_sp32"
4591 [(set (match_operand:DI 0 "register_operand" "=r")
4592 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4593 (match_operand:DI 2 "register_operand" "r")))]
4596 "&& reload_completed
4597 && ((GET_CODE (operands[0]) == REG
4598 && SPARC_INT_REG_P (REGNO (operands[0])))
4599 || (GET_CODE (operands[0]) == SUBREG
4600 && GET_CODE (SUBREG_REG (operands[0])) == REG
4601 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4602 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4603 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4604 "operands[3] = gen_highpart (SImode, operands[0]);
4605 operands[4] = gen_highpart (SImode, operands[1]);
4606 operands[5] = gen_highpart (SImode, operands[2]);
4607 operands[6] = gen_lowpart (SImode, operands[0]);
4608 operands[7] = gen_lowpart (SImode, operands[1]);
4609 operands[8] = gen_lowpart (SImode, operands[2]);"
4610 [(set_attr "length" "2")])
4612 (define_insn "*and_not_di_sp64"
4613 [(set (match_operand:DI 0 "register_operand" "=r")
4614 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4615 (match_operand:DI 2 "register_operand" "r")))]
4619 (define_insn "*and_not_si"
4620 [(set (match_operand:SI 0 "register_operand" "=r")
4621 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4622 (match_operand:SI 2 "register_operand" "r")))]
4626 (define_expand "iordi3"
4627 [(set (match_operand:DI 0 "register_operand" "")
4628 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4629 (match_operand:DI 2 "arith_double_operand" "")))]
4633 (define_insn "*iordi3_sp32"
4634 [(set (match_operand:DI 0 "register_operand" "=r")
4635 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4636 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4639 [(set_attr "length" "2")])
4641 (define_insn "*iordi3_sp64"
4642 [(set (match_operand:DI 0 "register_operand" "=r")
4643 (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4644 (match_operand:DI 2 "arith_operand" "rI")))]
4648 (define_insn "iorsi3"
4649 [(set (match_operand:SI 0 "register_operand" "=r")
4650 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4651 (match_operand:SI 2 "arith_operand" "rI")))]
4656 [(set (match_operand:SI 0 "register_operand" "")
4657 (ior:SI (match_operand:SI 1 "register_operand" "")
4658 (match_operand:SI 2 "const_compl_high_operand" "")))
4659 (clobber (match_operand:SI 3 "register_operand" ""))]
4661 [(set (match_dup 3) (match_dup 4))
4662 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4664 operands[4] = GEN_INT (~INTVAL (operands[2]));
4667 (define_insn_and_split "*or_not_di_sp32"
4668 [(set (match_operand:DI 0 "register_operand" "=r")
4669 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4670 (match_operand:DI 2 "register_operand" "r")))]
4673 "&& reload_completed
4674 && ((GET_CODE (operands[0]) == REG
4675 && SPARC_INT_REG_P (REGNO (operands[0])))
4676 || (GET_CODE (operands[0]) == SUBREG
4677 && GET_CODE (SUBREG_REG (operands[0])) == REG
4678 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4679 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4680 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4681 "operands[3] = gen_highpart (SImode, operands[0]);
4682 operands[4] = gen_highpart (SImode, operands[1]);
4683 operands[5] = gen_highpart (SImode, operands[2]);
4684 operands[6] = gen_lowpart (SImode, operands[0]);
4685 operands[7] = gen_lowpart (SImode, operands[1]);
4686 operands[8] = gen_lowpart (SImode, operands[2]);"
4687 [(set_attr "length" "2")])
4689 (define_insn "*or_not_di_sp64"
4690 [(set (match_operand:DI 0 "register_operand" "=r")
4691 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4692 (match_operand:DI 2 "register_operand" "r")))]
4696 (define_insn "*or_not_si"
4697 [(set (match_operand:SI 0 "register_operand" "=r")
4698 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4699 (match_operand:SI 2 "register_operand" "r")))]
4703 (define_expand "xordi3"
4704 [(set (match_operand:DI 0 "register_operand" "")
4705 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4706 (match_operand:DI 2 "arith_double_operand" "")))]
4710 (define_insn "*xordi3_sp32"
4711 [(set (match_operand:DI 0 "register_operand" "=r")
4712 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4713 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4716 [(set_attr "length" "2")])
4718 (define_insn "*xordi3_sp64"
4719 [(set (match_operand:DI 0 "register_operand" "=r")
4720 (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4721 (match_operand:DI 2 "arith_operand" "rI")))]
4725 (define_insn "xorsi3"
4726 [(set (match_operand:SI 0 "register_operand" "=r")
4727 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4728 (match_operand:SI 2 "arith_operand" "rI")))]
4733 [(set (match_operand:SI 0 "register_operand" "")
4734 (xor:SI (match_operand:SI 1 "register_operand" "")
4735 (match_operand:SI 2 "const_compl_high_operand" "")))
4736 (clobber (match_operand:SI 3 "register_operand" ""))]
4738 [(set (match_dup 3) (match_dup 4))
4739 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4741 operands[4] = GEN_INT (~INTVAL (operands[2]));
4745 [(set (match_operand:SI 0 "register_operand" "")
4746 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4747 (match_operand:SI 2 "const_compl_high_operand" ""))))
4748 (clobber (match_operand:SI 3 "register_operand" ""))]
4750 [(set (match_dup 3) (match_dup 4))
4751 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4753 operands[4] = GEN_INT (~INTVAL (operands[2]));
4756 ;; Split DImode logical operations requiring two instructions.
4758 [(set (match_operand:DI 0 "register_operand" "")
4759 (match_operator:DI 1 "cc_arith_operator" ; AND, IOR, XOR
4760 [(match_operand:DI 2 "register_operand" "")
4761 (match_operand:DI 3 "arith_double_operand" "")]))]
4764 && ((GET_CODE (operands[0]) == REG
4765 && SPARC_INT_REG_P (REGNO (operands[0])))
4766 || (GET_CODE (operands[0]) == SUBREG
4767 && GET_CODE (SUBREG_REG (operands[0])) == REG
4768 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4769 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4770 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4772 operands[4] = gen_highpart (SImode, operands[0]);
4773 operands[5] = gen_lowpart (SImode, operands[0]);
4774 operands[6] = gen_highpart (SImode, operands[2]);
4775 operands[7] = gen_lowpart (SImode, operands[2]);
4776 #if HOST_BITS_PER_WIDE_INT == 32
4777 if (GET_CODE (operands[3]) == CONST_INT)
4779 if (INTVAL (operands[3]) < 0)
4780 operands[8] = constm1_rtx;
4782 operands[8] = const0_rtx;
4786 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
4787 operands[9] = gen_lowpart (SImode, operands[3]);
4790 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4791 ;; Combine now canonicalizes to the rightmost expression.
4792 (define_insn_and_split "*xor_not_di_sp32"
4793 [(set (match_operand:DI 0 "register_operand" "=r")
4794 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
4795 (match_operand:DI 2 "register_operand" "r"))))]
4798 "&& reload_completed
4799 && ((GET_CODE (operands[0]) == REG
4800 && SPARC_INT_REG_P (REGNO (operands[0])))
4801 || (GET_CODE (operands[0]) == SUBREG
4802 && GET_CODE (SUBREG_REG (operands[0])) == REG
4803 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4804 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4805 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4806 "operands[3] = gen_highpart (SImode, operands[0]);
4807 operands[4] = gen_highpart (SImode, operands[1]);
4808 operands[5] = gen_highpart (SImode, operands[2]);
4809 operands[6] = gen_lowpart (SImode, operands[0]);
4810 operands[7] = gen_lowpart (SImode, operands[1]);
4811 operands[8] = gen_lowpart (SImode, operands[2]);"
4812 [(set_attr "length" "2")])
4814 (define_insn "*xor_not_di_sp64"
4815 [(set (match_operand:DI 0 "register_operand" "=r")
4816 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4817 (match_operand:DI 2 "arith_operand" "rI"))))]
4819 "xnor\t%r1, %2, %0")
4821 (define_insn "*xor_not_si"
4822 [(set (match_operand:SI 0 "register_operand" "=r")
4823 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4824 (match_operand:SI 2 "arith_operand" "rI"))))]
4826 "xnor\t%r1, %2, %0")
4828 ;; These correspond to the above in the case where we also (or only)
4829 ;; want to set the condition code.
4831 (define_insn "*cmp_cc_arith_op"
4832 [(set (reg:CC CC_REG)
4834 (match_operator:SI 2 "cc_arith_operator"
4835 [(match_operand:SI 0 "arith_operand" "%r")
4836 (match_operand:SI 1 "arith_operand" "rI")])
4839 "%A2cc\t%0, %1, %%g0"
4840 [(set_attr "type" "compare")])
4842 (define_insn "*cmp_ccx_arith_op"
4843 [(set (reg:CCX CC_REG)
4845 (match_operator:DI 2 "cc_arith_operator"
4846 [(match_operand:DI 0 "arith_operand" "%r")
4847 (match_operand:DI 1 "arith_operand" "rI")])
4850 "%A2cc\t%0, %1, %%g0"
4851 [(set_attr "type" "compare")])
4853 (define_insn "*cmp_cc_arith_op_set"
4854 [(set (reg:CC CC_REG)
4856 (match_operator:SI 3 "cc_arith_operator"
4857 [(match_operand:SI 1 "arith_operand" "%r")
4858 (match_operand:SI 2 "arith_operand" "rI")])
4860 (set (match_operand:SI 0 "register_operand" "=r")
4861 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4862 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4864 [(set_attr "type" "compare")])
4866 (define_insn "*cmp_ccx_arith_op_set"
4867 [(set (reg:CCX CC_REG)
4869 (match_operator:DI 3 "cc_arith_operator"
4870 [(match_operand:DI 1 "arith_operand" "%r")
4871 (match_operand:DI 2 "arith_operand" "rI")])
4873 (set (match_operand:DI 0 "register_operand" "=r")
4874 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4875 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4877 [(set_attr "type" "compare")])
4879 (define_insn "*cmp_cc_xor_not"
4880 [(set (reg:CC CC_REG)
4882 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4883 (match_operand:SI 1 "arith_operand" "rI")))
4886 "xnorcc\t%r0, %1, %%g0"
4887 [(set_attr "type" "compare")])
4889 (define_insn "*cmp_ccx_xor_not"
4890 [(set (reg:CCX CC_REG)
4892 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4893 (match_operand:DI 1 "arith_operand" "rI")))
4896 "xnorcc\t%r0, %1, %%g0"
4897 [(set_attr "type" "compare")])
4899 (define_insn "*cmp_cc_xor_not_set"
4900 [(set (reg:CC CC_REG)
4902 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4903 (match_operand:SI 2 "arith_operand" "rI")))
4905 (set (match_operand:SI 0 "register_operand" "=r")
4906 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4908 "xnorcc\t%r1, %2, %0"
4909 [(set_attr "type" "compare")])
4911 (define_insn "*cmp_ccx_xor_not_set"
4912 [(set (reg:CCX CC_REG)
4914 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4915 (match_operand:DI 2 "arith_operand" "rI")))
4917 (set (match_operand:DI 0 "register_operand" "=r")
4918 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4920 "xnorcc\t%r1, %2, %0"
4921 [(set_attr "type" "compare")])
4923 (define_insn "*cmp_cc_arith_op_not"
4924 [(set (reg:CC CC_REG)
4926 (match_operator:SI 2 "cc_arith_not_operator"
4927 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4928 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
4931 "%B2cc\t%r1, %0, %%g0"
4932 [(set_attr "type" "compare")])
4934 (define_insn "*cmp_ccx_arith_op_not"
4935 [(set (reg:CCX CC_REG)
4937 (match_operator:DI 2 "cc_arith_not_operator"
4938 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
4939 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
4942 "%B2cc\t%r1, %0, %%g0"
4943 [(set_attr "type" "compare")])
4945 (define_insn "*cmp_cc_arith_op_not_set"
4946 [(set (reg:CC CC_REG)
4948 (match_operator:SI 3 "cc_arith_not_operator"
4949 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
4950 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
4952 (set (match_operand:SI 0 "register_operand" "=r")
4953 (match_operator:SI 4 "cc_arith_not_operator"
4954 [(not:SI (match_dup 1)) (match_dup 2)]))]
4955 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4956 "%B3cc\t%r2, %1, %0"
4957 [(set_attr "type" "compare")])
4959 (define_insn "*cmp_ccx_arith_op_not_set"
4960 [(set (reg:CCX CC_REG)
4962 (match_operator:DI 3 "cc_arith_not_operator"
4963 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
4964 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
4966 (set (match_operand:DI 0 "register_operand" "=r")
4967 (match_operator:DI 4 "cc_arith_not_operator"
4968 [(not:DI (match_dup 1)) (match_dup 2)]))]
4969 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4970 "%B3cc\t%r2, %1, %0"
4971 [(set_attr "type" "compare")])
4973 ;; We cannot use the "neg" pseudo insn because the Sun assembler
4974 ;; does not know how to make it work for constants.
4976 (define_expand "negdi2"
4977 [(set (match_operand:DI 0 "register_operand" "=r")
4978 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4981 if (! TARGET_ARCH64)
4983 emit_insn (gen_rtx_PARALLEL
4986 gen_rtx_SET (VOIDmode, operand0,
4987 gen_rtx_NEG (DImode, operand1)),
4988 gen_rtx_CLOBBER (VOIDmode,
4989 gen_rtx_REG (CCmode,
4995 (define_insn_and_split "*negdi2_sp32"
4996 [(set (match_operand:DI 0 "register_operand" "=r")
4997 (neg:DI (match_operand:DI 1 "register_operand" "r")))
4998 (clobber (reg:CC CC_REG))]
5001 "&& reload_completed"
5002 [(parallel [(set (reg:CC_NOOV CC_REG)
5003 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5005 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5006 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5007 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5008 "operands[2] = gen_highpart (SImode, operands[0]);
5009 operands[3] = gen_highpart (SImode, operands[1]);
5010 operands[4] = gen_lowpart (SImode, operands[0]);
5011 operands[5] = gen_lowpart (SImode, operands[1]);"
5012 [(set_attr "length" "2")])
5014 (define_insn "*negdi2_sp64"
5015 [(set (match_operand:DI 0 "register_operand" "=r")
5016 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5018 "sub\t%%g0, %1, %0")
5020 (define_insn "negsi2"
5021 [(set (match_operand:SI 0 "register_operand" "=r")
5022 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5024 "sub\t%%g0, %1, %0")
5026 (define_insn "*cmp_cc_neg"
5027 [(set (reg:CC_NOOV CC_REG)
5028 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5031 "subcc\t%%g0, %0, %%g0"
5032 [(set_attr "type" "compare")])
5034 (define_insn "*cmp_ccx_neg"
5035 [(set (reg:CCX_NOOV CC_REG)
5036 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5039 "subcc\t%%g0, %0, %%g0"
5040 [(set_attr "type" "compare")])
5042 (define_insn "*cmp_cc_set_neg"
5043 [(set (reg:CC_NOOV CC_REG)
5044 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5046 (set (match_operand:SI 0 "register_operand" "=r")
5047 (neg:SI (match_dup 1)))]
5049 "subcc\t%%g0, %1, %0"
5050 [(set_attr "type" "compare")])
5052 (define_insn "*cmp_ccx_set_neg"
5053 [(set (reg:CCX_NOOV CC_REG)
5054 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5056 (set (match_operand:DI 0 "register_operand" "=r")
5057 (neg:DI (match_dup 1)))]
5059 "subcc\t%%g0, %1, %0"
5060 [(set_attr "type" "compare")])
5062 ;; We cannot use the "not" pseudo insn because the Sun assembler
5063 ;; does not know how to make it work for constants.
5064 (define_expand "one_cmpldi2"
5065 [(set (match_operand:DI 0 "register_operand" "")
5066 (not:DI (match_operand:DI 1 "register_operand" "")))]
5070 (define_insn_and_split "*one_cmpldi2_sp32"
5071 [(set (match_operand:DI 0 "register_operand" "=r")
5072 (not:DI (match_operand:DI 1 "register_operand" "r")))]
5075 "&& reload_completed
5076 && ((GET_CODE (operands[0]) == REG
5077 && SPARC_INT_REG_P (REGNO (operands[0])))
5078 || (GET_CODE (operands[0]) == SUBREG
5079 && GET_CODE (SUBREG_REG (operands[0])) == REG
5080 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
5081 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5082 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5083 "operands[2] = gen_highpart (SImode, operands[0]);
5084 operands[3] = gen_highpart (SImode, operands[1]);
5085 operands[4] = gen_lowpart (SImode, operands[0]);
5086 operands[5] = gen_lowpart (SImode, operands[1]);"
5087 [(set_attr "length" "2")])
5089 (define_insn "*one_cmpldi2_sp64"
5090 [(set (match_operand:DI 0 "register_operand" "=r")
5091 (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5093 "xnor\t%%g0, %1, %0")
5095 (define_insn "one_cmplsi2"
5096 [(set (match_operand:SI 0 "register_operand" "=r")
5097 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5099 "xnor\t%%g0, %1, %0")
5101 (define_insn "*cmp_cc_not"
5102 [(set (reg:CC CC_REG)
5103 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5106 "xnorcc\t%%g0, %0, %%g0"
5107 [(set_attr "type" "compare")])
5109 (define_insn "*cmp_ccx_not"
5110 [(set (reg:CCX CC_REG)
5111 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5114 "xnorcc\t%%g0, %0, %%g0"
5115 [(set_attr "type" "compare")])
5117 (define_insn "*cmp_cc_set_not"
5118 [(set (reg:CC CC_REG)
5119 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5121 (set (match_operand:SI 0 "register_operand" "=r")
5122 (not:SI (match_dup 1)))]
5124 "xnorcc\t%%g0, %1, %0"
5125 [(set_attr "type" "compare")])
5127 (define_insn "*cmp_ccx_set_not"
5128 [(set (reg:CCX CC_REG)
5129 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5131 (set (match_operand:DI 0 "register_operand" "=r")
5132 (not:DI (match_dup 1)))]
5134 "xnorcc\t%%g0, %1, %0"
5135 [(set_attr "type" "compare")])
5137 (define_insn "*cmp_cc_set"
5138 [(set (match_operand:SI 0 "register_operand" "=r")
5139 (match_operand:SI 1 "register_operand" "r"))
5140 (set (reg:CC CC_REG)
5141 (compare:CC (match_dup 1)
5145 [(set_attr "type" "compare")])
5147 (define_insn "*cmp_ccx_set64"
5148 [(set (match_operand:DI 0 "register_operand" "=r")
5149 (match_operand:DI 1 "register_operand" "r"))
5150 (set (reg:CCX CC_REG)
5151 (compare:CCX (match_dup 1)
5155 [(set_attr "type" "compare")])
5158 ;; Floating point arithmetic instructions.
5160 (define_expand "addtf3"
5161 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5162 (plus:TF (match_operand:TF 1 "general_operand" "")
5163 (match_operand:TF 2 "general_operand" "")))]
5164 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5165 "emit_tfmode_binop (PLUS, operands); DONE;")
5167 (define_insn "*addtf3_hq"
5168 [(set (match_operand:TF 0 "register_operand" "=e")
5169 (plus:TF (match_operand:TF 1 "register_operand" "e")
5170 (match_operand:TF 2 "register_operand" "e")))]
5171 "TARGET_FPU && TARGET_HARD_QUAD"
5173 [(set_attr "type" "fp")])
5175 (define_insn "adddf3"
5176 [(set (match_operand:DF 0 "register_operand" "=e")
5177 (plus:DF (match_operand:DF 1 "register_operand" "e")
5178 (match_operand:DF 2 "register_operand" "e")))]
5181 [(set_attr "type" "fp")
5182 (set_attr "fptype" "double")])
5184 (define_insn "addsf3"
5185 [(set (match_operand:SF 0 "register_operand" "=f")
5186 (plus:SF (match_operand:SF 1 "register_operand" "f")
5187 (match_operand:SF 2 "register_operand" "f")))]
5190 [(set_attr "type" "fp")])
5192 (define_expand "subtf3"
5193 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5194 (minus:TF (match_operand:TF 1 "general_operand" "")
5195 (match_operand:TF 2 "general_operand" "")))]
5196 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5197 "emit_tfmode_binop (MINUS, operands); DONE;")
5199 (define_insn "*subtf3_hq"
5200 [(set (match_operand:TF 0 "register_operand" "=e")
5201 (minus:TF (match_operand:TF 1 "register_operand" "e")
5202 (match_operand:TF 2 "register_operand" "e")))]
5203 "TARGET_FPU && TARGET_HARD_QUAD"
5205 [(set_attr "type" "fp")])
5207 (define_insn "subdf3"
5208 [(set (match_operand:DF 0 "register_operand" "=e")
5209 (minus:DF (match_operand:DF 1 "register_operand" "e")
5210 (match_operand:DF 2 "register_operand" "e")))]
5213 [(set_attr "type" "fp")
5214 (set_attr "fptype" "double")])
5216 (define_insn "subsf3"
5217 [(set (match_operand:SF 0 "register_operand" "=f")
5218 (minus:SF (match_operand:SF 1 "register_operand" "f")
5219 (match_operand:SF 2 "register_operand" "f")))]
5222 [(set_attr "type" "fp")])
5224 (define_expand "multf3"
5225 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5226 (mult:TF (match_operand:TF 1 "general_operand" "")
5227 (match_operand:TF 2 "general_operand" "")))]
5228 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5229 "emit_tfmode_binop (MULT, operands); DONE;")
5231 (define_insn "*multf3_hq"
5232 [(set (match_operand:TF 0 "register_operand" "=e")
5233 (mult:TF (match_operand:TF 1 "register_operand" "e")
5234 (match_operand:TF 2 "register_operand" "e")))]
5235 "TARGET_FPU && TARGET_HARD_QUAD"
5237 [(set_attr "type" "fpmul")])
5239 (define_insn "muldf3"
5240 [(set (match_operand:DF 0 "register_operand" "=e")
5241 (mult:DF (match_operand:DF 1 "register_operand" "e")
5242 (match_operand:DF 2 "register_operand" "e")))]
5245 [(set_attr "type" "fpmul")
5246 (set_attr "fptype" "double")])
5248 (define_insn "mulsf3"
5249 [(set (match_operand:SF 0 "register_operand" "=f")
5250 (mult:SF (match_operand:SF 1 "register_operand" "f")
5251 (match_operand:SF 2 "register_operand" "f")))]
5254 [(set_attr "type" "fpmul")])
5256 (define_insn "fmadf4"
5257 [(set (match_operand:DF 0 "register_operand" "=e")
5258 (fma:DF (match_operand:DF 1 "register_operand" "e")
5259 (match_operand:DF 2 "register_operand" "e")
5260 (match_operand:DF 3 "register_operand" "e")))]
5262 "fmaddd\t%1, %2, %3, %0"
5263 [(set_attr "type" "fpmul")])
5265 (define_insn "fmsdf4"
5266 [(set (match_operand:DF 0 "register_operand" "=e")
5267 (fma:DF (match_operand:DF 1 "register_operand" "e")
5268 (match_operand:DF 2 "register_operand" "e")
5269 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5271 "fmsubd\t%1, %2, %3, %0"
5272 [(set_attr "type" "fpmul")])
5274 (define_insn "*nfmadf4"
5275 [(set (match_operand:DF 0 "register_operand" "=e")
5276 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5277 (match_operand:DF 2 "register_operand" "e")
5278 (match_operand:DF 3 "register_operand" "e"))))]
5280 "fnmaddd\t%1, %2, %3, %0"
5281 [(set_attr "type" "fpmul")])
5283 (define_insn "*nfmsdf4"
5284 [(set (match_operand:DF 0 "register_operand" "=e")
5285 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5286 (match_operand:DF 2 "register_operand" "e")
5287 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5289 "fnmsubd\t%1, %2, %3, %0"
5290 [(set_attr "type" "fpmul")])
5292 (define_insn "fmasf4"
5293 [(set (match_operand:SF 0 "register_operand" "=f")
5294 (fma:SF (match_operand:SF 1 "register_operand" "f")
5295 (match_operand:SF 2 "register_operand" "f")
5296 (match_operand:SF 3 "register_operand" "f")))]
5298 "fmadds\t%1, %2, %3, %0"
5299 [(set_attr "type" "fpmul")])
5301 (define_insn "fmssf4"
5302 [(set (match_operand:SF 0 "register_operand" "=f")
5303 (fma:SF (match_operand:SF 1 "register_operand" "f")
5304 (match_operand:SF 2 "register_operand" "f")
5305 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5307 "fmsubs\t%1, %2, %3, %0"
5308 [(set_attr "type" "fpmul")])
5310 (define_insn "*nfmasf4"
5311 [(set (match_operand:SF 0 "register_operand" "=f")
5312 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5313 (match_operand:SF 2 "register_operand" "f")
5314 (match_operand:SF 3 "register_operand" "f"))))]
5316 "fnmadds\t%1, %2, %3, %0"
5317 [(set_attr "type" "fpmul")])
5319 (define_insn "*nfmssf4"
5320 [(set (match_operand:SF 0 "register_operand" "=f")
5321 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5322 (match_operand:SF 2 "register_operand" "f")
5323 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5325 "fnmsubs\t%1, %2, %3, %0"
5326 [(set_attr "type" "fpmul")])
5328 (define_insn "*muldf3_extend"
5329 [(set (match_operand:DF 0 "register_operand" "=e")
5330 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5331 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5332 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5333 "fsmuld\t%1, %2, %0"
5334 [(set_attr "type" "fpmul")
5335 (set_attr "fptype" "double")])
5337 (define_insn "*multf3_extend"
5338 [(set (match_operand:TF 0 "register_operand" "=e")
5339 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5340 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5341 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5342 "fdmulq\t%1, %2, %0"
5343 [(set_attr "type" "fpmul")])
5345 (define_expand "divtf3"
5346 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5347 (div:TF (match_operand:TF 1 "general_operand" "")
5348 (match_operand:TF 2 "general_operand" "")))]
5349 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5350 "emit_tfmode_binop (DIV, operands); DONE;")
5352 ;; don't have timing for quad-prec. divide.
5353 (define_insn "*divtf3_hq"
5354 [(set (match_operand:TF 0 "register_operand" "=e")
5355 (div:TF (match_operand:TF 1 "register_operand" "e")
5356 (match_operand:TF 2 "register_operand" "e")))]
5357 "TARGET_FPU && TARGET_HARD_QUAD"
5359 [(set_attr "type" "fpdivd")])
5361 (define_insn "divdf3"
5362 [(set (match_operand:DF 0 "register_operand" "=e")
5363 (div:DF (match_operand:DF 1 "register_operand" "e")
5364 (match_operand:DF 2 "register_operand" "e")))]
5367 [(set_attr "type" "fpdivd")
5368 (set_attr "fptype" "double")])
5370 (define_insn "divsf3"
5371 [(set (match_operand:SF 0 "register_operand" "=f")
5372 (div:SF (match_operand:SF 1 "register_operand" "f")
5373 (match_operand:SF 2 "register_operand" "f")))]
5376 [(set_attr "type" "fpdivs")])
5378 (define_expand "negtf2"
5379 [(set (match_operand:TF 0 "register_operand" "=e,e")
5380 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5384 (define_insn_and_split "*negtf2_notv9"
5385 [(set (match_operand:TF 0 "register_operand" "=e,e")
5386 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5387 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5393 "&& reload_completed
5394 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5395 [(set (match_dup 2) (neg:SF (match_dup 3)))
5396 (set (match_dup 4) (match_dup 5))
5397 (set (match_dup 6) (match_dup 7))]
5398 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5399 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5400 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5401 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5402 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5403 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5404 [(set_attr "type" "fpmove,*")
5405 (set_attr "length" "*,2")])
5407 (define_insn_and_split "*negtf2_v9"
5408 [(set (match_operand:TF 0 "register_operand" "=e,e")
5409 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5410 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5411 "TARGET_FPU && TARGET_V9"
5415 "&& reload_completed
5416 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5417 [(set (match_dup 2) (neg:DF (match_dup 3)))
5418 (set (match_dup 4) (match_dup 5))]
5419 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5420 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5421 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5422 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5423 [(set_attr "type" "fpmove,*")
5424 (set_attr "length" "*,2")
5425 (set_attr "fptype" "double")])
5427 (define_expand "negdf2"
5428 [(set (match_operand:DF 0 "register_operand" "")
5429 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5433 (define_insn_and_split "*negdf2_notv9"
5434 [(set (match_operand:DF 0 "register_operand" "=e,e")
5435 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5436 "TARGET_FPU && ! TARGET_V9"
5440 "&& reload_completed
5441 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5442 [(set (match_dup 2) (neg:SF (match_dup 3)))
5443 (set (match_dup 4) (match_dup 5))]
5444 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5445 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5446 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5447 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5448 [(set_attr "type" "fpmove,*")
5449 (set_attr "length" "*,2")])
5451 (define_insn "*negdf2_v9"
5452 [(set (match_operand:DF 0 "register_operand" "=e")
5453 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5454 "TARGET_FPU && TARGET_V9"
5456 [(set_attr "type" "fpmove")
5457 (set_attr "fptype" "double")])
5459 (define_insn "negsf2"
5460 [(set (match_operand:SF 0 "register_operand" "=f")
5461 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5464 [(set_attr "type" "fpmove")])
5466 (define_expand "abstf2"
5467 [(set (match_operand:TF 0 "register_operand" "")
5468 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5472 (define_insn_and_split "*abstf2_notv9"
5473 [(set (match_operand:TF 0 "register_operand" "=e,e")
5474 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5475 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5476 "TARGET_FPU && ! TARGET_V9"
5480 "&& reload_completed
5481 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5482 [(set (match_dup 2) (abs:SF (match_dup 3)))
5483 (set (match_dup 4) (match_dup 5))
5484 (set (match_dup 6) (match_dup 7))]
5485 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5486 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5487 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5488 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5489 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5490 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5491 [(set_attr "type" "fpmove,*")
5492 (set_attr "length" "*,2")])
5494 (define_insn "*abstf2_hq_v9"
5495 [(set (match_operand:TF 0 "register_operand" "=e,e")
5496 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5497 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5501 [(set_attr "type" "fpmove")
5502 (set_attr "fptype" "double,*")])
5504 (define_insn_and_split "*abstf2_v9"
5505 [(set (match_operand:TF 0 "register_operand" "=e,e")
5506 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5507 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5511 "&& reload_completed
5512 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5513 [(set (match_dup 2) (abs:DF (match_dup 3)))
5514 (set (match_dup 4) (match_dup 5))]
5515 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5516 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5517 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5518 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5519 [(set_attr "type" "fpmove,*")
5520 (set_attr "length" "*,2")
5521 (set_attr "fptype" "double,*")])
5523 (define_expand "absdf2"
5524 [(set (match_operand:DF 0 "register_operand" "")
5525 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5529 (define_insn_and_split "*absdf2_notv9"
5530 [(set (match_operand:DF 0 "register_operand" "=e,e")
5531 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5532 "TARGET_FPU && ! TARGET_V9"
5536 "&& reload_completed
5537 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5538 [(set (match_dup 2) (abs:SF (match_dup 3)))
5539 (set (match_dup 4) (match_dup 5))]
5540 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5541 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5542 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5543 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5544 [(set_attr "type" "fpmove,*")
5545 (set_attr "length" "*,2")])
5547 (define_insn "*absdf2_v9"
5548 [(set (match_operand:DF 0 "register_operand" "=e")
5549 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5550 "TARGET_FPU && TARGET_V9"
5552 [(set_attr "type" "fpmove")
5553 (set_attr "fptype" "double")])
5555 (define_insn "abssf2"
5556 [(set (match_operand:SF 0 "register_operand" "=f")
5557 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5560 [(set_attr "type" "fpmove")])
5562 (define_expand "sqrttf2"
5563 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5564 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5565 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5566 "emit_tfmode_unop (SQRT, operands); DONE;")
5568 (define_insn "*sqrttf2_hq"
5569 [(set (match_operand:TF 0 "register_operand" "=e")
5570 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5571 "TARGET_FPU && TARGET_HARD_QUAD"
5573 [(set_attr "type" "fpsqrtd")])
5575 (define_insn "sqrtdf2"
5576 [(set (match_operand:DF 0 "register_operand" "=e")
5577 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5580 [(set_attr "type" "fpsqrtd")
5581 (set_attr "fptype" "double")])
5583 (define_insn "sqrtsf2"
5584 [(set (match_operand:SF 0 "register_operand" "=f")
5585 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5588 [(set_attr "type" "fpsqrts")])
5591 ;; Arithmetic shift instructions.
5593 (define_insn "ashlsi3"
5594 [(set (match_operand:SI 0 "register_operand" "=r")
5595 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5596 (match_operand:SI 2 "arith_operand" "rI")))]
5599 if (GET_CODE (operands[2]) == CONST_INT)
5600 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5601 return "sll\t%1, %2, %0";
5603 [(set_attr "type" "shift")])
5605 (define_insn "*ashlsi3_extend"
5606 [(set (match_operand:DI 0 "register_operand" "=r")
5608 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5609 (match_operand:SI 2 "arith_operand" "rI"))))]
5612 if (GET_CODE (operands[2]) == CONST_INT)
5613 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5614 return "sll\t%1, %2, %0";
5616 [(set_attr "type" "shift")])
5618 (define_expand "ashldi3"
5619 [(set (match_operand:DI 0 "register_operand" "=r")
5620 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5621 (match_operand:SI 2 "arith_operand" "rI")))]
5622 "TARGET_ARCH64 || TARGET_V8PLUS"
5624 if (! TARGET_ARCH64)
5626 if (GET_CODE (operands[2]) == CONST_INT)
5628 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5633 (define_insn "*ashldi3_sp64"
5634 [(set (match_operand:DI 0 "register_operand" "=r")
5635 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5636 (match_operand:SI 2 "arith_operand" "rI")))]
5639 if (GET_CODE (operands[2]) == CONST_INT)
5640 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5641 return "sllx\t%1, %2, %0";
5643 [(set_attr "type" "shift")])
5646 (define_insn "ashldi3_v8plus"
5647 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5648 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5649 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5650 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5652 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5653 [(set_attr "type" "multi")
5654 (set_attr "length" "5,5,6")])
5656 ;; Optimize (1LL<<x)-1
5657 ;; XXX this also needs to be fixed to handle equal subregs
5658 ;; XXX first before we could re-enable it.
5660 ; [(set (match_operand:DI 0 "register_operand" "=h")
5661 ; (plus:DI (ashift:DI (const_int 1)
5662 ; (match_operand:SI 1 "arith_operand" "rI"))
5664 ; "0 && TARGET_V8PLUS"
5666 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5667 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5668 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5670 ; [(set_attr "type" "multi")
5671 ; (set_attr "length" "4")])
5673 (define_insn "*cmp_cc_ashift_1"
5674 [(set (reg:CC_NOOV CC_REG)
5675 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5679 "addcc\t%0, %0, %%g0"
5680 [(set_attr "type" "compare")])
5682 (define_insn "*cmp_cc_set_ashift_1"
5683 [(set (reg:CC_NOOV CC_REG)
5684 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5687 (set (match_operand:SI 0 "register_operand" "=r")
5688 (ashift:SI (match_dup 1) (const_int 1)))]
5691 [(set_attr "type" "compare")])
5693 (define_insn "ashrsi3"
5694 [(set (match_operand:SI 0 "register_operand" "=r")
5695 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5696 (match_operand:SI 2 "arith_operand" "rI")))]
5699 if (GET_CODE (operands[2]) == CONST_INT)
5700 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5701 return "sra\t%1, %2, %0";
5703 [(set_attr "type" "shift")])
5705 (define_insn "*ashrsi3_extend"
5706 [(set (match_operand:DI 0 "register_operand" "=r")
5707 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5708 (match_operand:SI 2 "arith_operand" "r"))))]
5711 [(set_attr "type" "shift")])
5713 ;; This handles the case as above, but with constant shift instead of
5714 ;; register. Combiner "simplifies" it for us a little bit though.
5715 (define_insn "*ashrsi3_extend2"
5716 [(set (match_operand:DI 0 "register_operand" "=r")
5717 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5719 (match_operand:SI 2 "small_int_operand" "I")))]
5720 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5722 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5723 return "sra\t%1, %2, %0";
5725 [(set_attr "type" "shift")])
5727 (define_expand "ashrdi3"
5728 [(set (match_operand:DI 0 "register_operand" "=r")
5729 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5730 (match_operand:SI 2 "arith_operand" "rI")))]
5731 "TARGET_ARCH64 || TARGET_V8PLUS"
5733 if (! TARGET_ARCH64)
5735 if (GET_CODE (operands[2]) == CONST_INT)
5736 FAIL; /* prefer generic code in this case */
5737 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5742 (define_insn "*ashrdi3_sp64"
5743 [(set (match_operand:DI 0 "register_operand" "=r")
5744 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5745 (match_operand:SI 2 "arith_operand" "rI")))]
5749 if (GET_CODE (operands[2]) == CONST_INT)
5750 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5751 return "srax\t%1, %2, %0";
5753 [(set_attr "type" "shift")])
5756 (define_insn "ashrdi3_v8plus"
5757 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5758 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5759 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5760 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5762 "* return output_v8plus_shift (operands, insn, \"srax\");"
5763 [(set_attr "type" "multi")
5764 (set_attr "length" "5,5,6")])
5766 (define_insn "lshrsi3"
5767 [(set (match_operand:SI 0 "register_operand" "=r")
5768 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5769 (match_operand:SI 2 "arith_operand" "rI")))]
5772 if (GET_CODE (operands[2]) == CONST_INT)
5773 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5774 return "srl\t%1, %2, %0";
5776 [(set_attr "type" "shift")])
5778 (define_insn "*lshrsi3_extend0"
5779 [(set (match_operand:DI 0 "register_operand" "=r")
5781 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5782 (match_operand:SI 2 "arith_operand" "rI"))))]
5785 if (GET_CODE (operands[2]) == CONST_INT)
5786 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5787 return "srl\t%1, %2, %0";
5789 [(set_attr "type" "shift")])
5791 ;; This handles the case where
5792 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5793 ;; but combiner "simplifies" it for us.
5794 (define_insn "*lshrsi3_extend1"
5795 [(set (match_operand:DI 0 "register_operand" "=r")
5796 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5797 (match_operand:SI 2 "arith_operand" "r")) 0)
5798 (match_operand 3 "const_int_operand" "")))]
5799 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5801 [(set_attr "type" "shift")])
5803 ;; This handles the case where
5804 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5805 ;; but combiner "simplifies" it for us.
5806 (define_insn "*lshrsi3_extend2"
5807 [(set (match_operand:DI 0 "register_operand" "=r")
5808 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5809 (match_operand 2 "small_int_operand" "I")
5811 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5813 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5814 return "srl\t%1, %2, %0";
5816 [(set_attr "type" "shift")])
5818 (define_expand "lshrdi3"
5819 [(set (match_operand:DI 0 "register_operand" "=r")
5820 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5821 (match_operand:SI 2 "arith_operand" "rI")))]
5822 "TARGET_ARCH64 || TARGET_V8PLUS"
5824 if (! TARGET_ARCH64)
5826 if (GET_CODE (operands[2]) == CONST_INT)
5828 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5833 (define_insn "*lshrdi3_sp64"
5834 [(set (match_operand:DI 0 "register_operand" "=r")
5835 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5836 (match_operand:SI 2 "arith_operand" "rI")))]
5839 if (GET_CODE (operands[2]) == CONST_INT)
5840 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5841 return "srlx\t%1, %2, %0";
5843 [(set_attr "type" "shift")])
5846 (define_insn "lshrdi3_v8plus"
5847 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5848 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5849 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5850 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5852 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5853 [(set_attr "type" "multi")
5854 (set_attr "length" "5,5,6")])
5857 [(set (match_operand:SI 0 "register_operand" "=r")
5858 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5860 (match_operand:SI 2 "small_int_operand" "I")))]
5861 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5863 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5864 return "srax\t%1, %2, %0";
5866 [(set_attr "type" "shift")])
5869 [(set (match_operand:SI 0 "register_operand" "=r")
5870 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5872 (match_operand:SI 2 "small_int_operand" "I")))]
5873 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5875 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5876 return "srlx\t%1, %2, %0";
5878 [(set_attr "type" "shift")])
5881 [(set (match_operand:SI 0 "register_operand" "=r")
5882 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5883 (match_operand:SI 2 "small_int_operand" "I")) 4)
5884 (match_operand:SI 3 "small_int_operand" "I")))]
5886 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5887 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5888 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5890 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5892 return "srax\t%1, %2, %0";
5894 [(set_attr "type" "shift")])
5897 [(set (match_operand:SI 0 "register_operand" "=r")
5898 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5899 (match_operand:SI 2 "small_int_operand" "I")) 4)
5900 (match_operand:SI 3 "small_int_operand" "I")))]
5902 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5903 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5904 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5906 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5908 return "srlx\t%1, %2, %0";
5910 [(set_attr "type" "shift")])
5913 ;; Unconditional and other jump instructions.
5916 [(set (pc) (label_ref (match_operand 0 "" "")))]
5918 "* return output_ubranch (operands[0], 0, insn);"
5919 [(set_attr "type" "uncond_branch")])
5921 (define_expand "tablejump"
5922 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5923 (use (label_ref (match_operand 1 "" "")))])]
5926 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5928 /* In pic mode, our address differences are against the base of the
5929 table. Add that base value back in; CSE ought to be able to combine
5930 the two address loads. */
5934 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5936 if (CASE_VECTOR_MODE != Pmode)
5937 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5938 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5939 operands[0] = memory_address (Pmode, tmp);
5943 (define_insn "*tablejump_sp32"
5944 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5945 (use (label_ref (match_operand 1 "" "")))]
5948 [(set_attr "type" "uncond_branch")])
5950 (define_insn "*tablejump_sp64"
5951 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5952 (use (label_ref (match_operand 1 "" "")))]
5955 [(set_attr "type" "uncond_branch")])
5958 ;; Jump to subroutine instructions.
5960 (define_expand "call"
5961 ;; Note that this expression is not used for generating RTL.
5962 ;; All the RTL is generated explicitly below.
5963 [(call (match_operand 0 "call_operand" "")
5964 (match_operand 3 "" "i"))]
5965 ;; operands[2] is next_arg_register
5966 ;; operands[3] is struct_value_size_rtx.
5971 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5973 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5975 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5977 /* This is really a PIC sequence. We want to represent
5978 it as a funny jump so its delay slots can be filled.
5980 ??? But if this really *is* a CALL, will not it clobber the
5981 call-clobbered registers? We lose this if it is a JUMP_INSN.
5982 Why cannot we have delay slots filled if it were a CALL? */
5984 /* We accept negative sizes for untyped calls. */
5985 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5990 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5992 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5998 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5999 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6003 fn_rtx = operands[0];
6005 /* We accept negative sizes for untyped calls. */
6006 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6007 sparc_emit_call_insn
6010 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6012 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6015 sparc_emit_call_insn
6018 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6019 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6027 ;; We can't use the same pattern for these two insns, because then registers
6028 ;; in the address may not be properly reloaded.
6030 (define_insn "*call_address_sp32"
6031 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6032 (match_operand 1 "" ""))
6033 (clobber (reg:SI O7_REG))]
6034 ;;- Do not use operand 1 for most machines.
6037 [(set_attr "type" "call")])
6039 (define_insn "*call_symbolic_sp32"
6040 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6041 (match_operand 1 "" ""))
6042 (clobber (reg:SI O7_REG))]
6043 ;;- Do not use operand 1 for most machines.
6046 [(set_attr "type" "call")])
6048 (define_insn "*call_address_sp64"
6049 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6050 (match_operand 1 "" ""))
6051 (clobber (reg:DI O7_REG))]
6052 ;;- Do not use operand 1 for most machines.
6055 [(set_attr "type" "call")])
6057 (define_insn "*call_symbolic_sp64"
6058 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6059 (match_operand 1 "" ""))
6060 (clobber (reg:DI O7_REG))]
6061 ;;- Do not use operand 1 for most machines.
6064 [(set_attr "type" "call")])
6066 ;; This is a call that wants a structure value.
6067 ;; There is no such critter for v9 (??? we may need one anyway).
6068 (define_insn "*call_address_struct_value_sp32"
6069 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6070 (match_operand 1 "" ""))
6071 (match_operand 2 "immediate_operand" "")
6072 (clobber (reg:SI O7_REG))]
6073 ;;- Do not use operand 1 for most machines.
6074 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6076 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6077 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6079 [(set_attr "type" "call_no_delay_slot")
6080 (set_attr "length" "3")])
6082 ;; This is a call that wants a structure value.
6083 ;; There is no such critter for v9 (??? we may need one anyway).
6084 (define_insn "*call_symbolic_struct_value_sp32"
6085 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6086 (match_operand 1 "" ""))
6087 (match_operand 2 "immediate_operand" "")
6088 (clobber (reg:SI O7_REG))]
6089 ;;- Do not use operand 1 for most machines.
6090 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6092 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6093 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6095 [(set_attr "type" "call_no_delay_slot")
6096 (set_attr "length" "3")])
6098 ;; This is a call that may want a structure value. This is used for
6100 (define_insn "*call_address_untyped_struct_value_sp32"
6101 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6102 (match_operand 1 "" ""))
6103 (match_operand 2 "immediate_operand" "")
6104 (clobber (reg:SI O7_REG))]
6105 ;;- Do not use operand 1 for most machines.
6106 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6107 "call\t%a0, %1\n\t nop\n\tnop"
6108 [(set_attr "type" "call_no_delay_slot")
6109 (set_attr "length" "3")])
6111 ;; This is a call that may want a structure value. This is used for
6113 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6114 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6115 (match_operand 1 "" ""))
6116 (match_operand 2 "immediate_operand" "")
6117 (clobber (reg:SI O7_REG))]
6118 ;;- Do not use operand 1 for most machines.
6119 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6120 "call\t%a0, %1\n\t nop\n\tnop"
6121 [(set_attr "type" "call_no_delay_slot")
6122 (set_attr "length" "3")])
6124 (define_expand "call_value"
6125 ;; Note that this expression is not used for generating RTL.
6126 ;; All the RTL is generated explicitly below.
6127 [(set (match_operand 0 "register_operand" "=rf")
6128 (call (match_operand 1 "" "")
6129 (match_operand 4 "" "")))]
6130 ;; operand 2 is stack_size_rtx
6131 ;; operand 3 is next_arg_register
6137 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6139 fn_rtx = operands[1];
6142 gen_rtx_SET (VOIDmode, operands[0],
6143 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6144 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6146 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6151 (define_insn "*call_value_address_sp32"
6152 [(set (match_operand 0 "" "=rf")
6153 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6154 (match_operand 2 "" "")))
6155 (clobber (reg:SI O7_REG))]
6156 ;;- Do not use operand 2 for most machines.
6159 [(set_attr "type" "call")])
6161 (define_insn "*call_value_symbolic_sp32"
6162 [(set (match_operand 0 "" "=rf")
6163 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6164 (match_operand 2 "" "")))
6165 (clobber (reg:SI O7_REG))]
6166 ;;- Do not use operand 2 for most machines.
6169 [(set_attr "type" "call")])
6171 (define_insn "*call_value_address_sp64"
6172 [(set (match_operand 0 "" "")
6173 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6174 (match_operand 2 "" "")))
6175 (clobber (reg:DI O7_REG))]
6176 ;;- Do not use operand 2 for most machines.
6179 [(set_attr "type" "call")])
6181 (define_insn "*call_value_symbolic_sp64"
6182 [(set (match_operand 0 "" "")
6183 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6184 (match_operand 2 "" "")))
6185 (clobber (reg:DI O7_REG))]
6186 ;;- Do not use operand 2 for most machines.
6189 [(set_attr "type" "call")])
6191 (define_expand "untyped_call"
6192 [(parallel [(call (match_operand 0 "" "")
6194 (match_operand:BLK 1 "memory_operand" "")
6195 (match_operand 2 "" "")])]
6198 rtx valreg1 = gen_rtx_REG (DImode, 8);
6199 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6200 rtx result = operands[1];
6202 /* Pass constm1 to indicate that it may expect a structure value, but
6203 we don't know what size it is. */
6204 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6206 /* Save the function value registers. */
6207 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6208 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6211 /* The optimizer does not know that the call sets the function value
6212 registers we stored in the result block. We avoid problems by
6213 claiming that all hard registers are used and clobbered at this
6215 emit_insn (gen_blockage ());
6220 ;; Tail call instructions.
6222 (define_expand "sibcall"
6223 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6228 (define_insn "*sibcall_symbolic_sp32"
6229 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6230 (match_operand 1 "" ""))
6233 "* return output_sibcall(insn, operands[0]);"
6234 [(set_attr "type" "sibcall")])
6236 (define_insn "*sibcall_symbolic_sp64"
6237 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6238 (match_operand 1 "" ""))
6241 "* return output_sibcall(insn, operands[0]);"
6242 [(set_attr "type" "sibcall")])
6244 (define_expand "sibcall_value"
6245 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6246 (call (match_operand 1 "" "") (const_int 0)))
6251 (define_insn "*sibcall_value_symbolic_sp32"
6252 [(set (match_operand 0 "" "=rf")
6253 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6254 (match_operand 2 "" "")))
6257 "* return output_sibcall(insn, operands[1]);"
6258 [(set_attr "type" "sibcall")])
6260 (define_insn "*sibcall_value_symbolic_sp64"
6261 [(set (match_operand 0 "" "")
6262 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6263 (match_operand 2 "" "")))
6266 "* return output_sibcall(insn, operands[1]);"
6267 [(set_attr "type" "sibcall")])
6270 ;; Special instructions.
6272 (define_expand "prologue"
6277 sparc_flat_expand_prologue ();
6279 sparc_expand_prologue ();
6283 ;; The "register window save" insn is modelled as follows. The dwarf2
6284 ;; information is manually added in emit_window_save.
6286 (define_insn "window_save"
6288 [(match_operand 0 "arith_operand" "rI")]
6291 "save\t%%sp, %0, %%sp"
6292 [(set_attr "type" "savew")])
6294 (define_expand "epilogue"
6299 sparc_flat_expand_epilogue (false);
6301 sparc_expand_epilogue (false);
6304 (define_expand "sibcall_epilogue"
6309 sparc_flat_expand_epilogue (false);
6311 sparc_expand_epilogue (false);
6315 (define_expand "eh_return"
6316 [(use (match_operand 0 "general_operand" ""))]
6319 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6320 emit_jump_insn (gen_eh_return_internal ());
6325 (define_insn_and_split "eh_return_internal"
6329 "epilogue_completed"
6333 sparc_flat_expand_epilogue (true);
6335 sparc_expand_epilogue (true);
6338 (define_expand "return"
6340 "sparc_can_use_return_insn_p ()"
6343 (define_insn "*return_internal"
6346 "* return output_return (insn);"
6347 [(set_attr "type" "return")
6348 (set (attr "length")
6349 (cond [(eq_attr "calls_eh_return" "true")
6350 (if_then_else (eq_attr "delayed_branch" "true")
6351 (if_then_else (ior (eq_attr "isa" "v9")
6352 (eq_attr "flat" "true"))
6355 (if_then_else (eq_attr "flat" "true")
6358 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6359 (if_then_else (eq_attr "empty_delay_slot" "true")
6362 (eq_attr "empty_delay_slot" "true")
6363 (if_then_else (eq_attr "delayed_branch" "true")
6368 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6369 ;; all of memory. This blocks insns from being moved across this point.
6371 (define_insn "blockage"
6372 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6375 [(set_attr "length" "0")])
6377 (define_expand "probe_stack"
6378 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6382 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6385 (define_insn "probe_stack_range<P:mode>"
6386 [(set (match_operand:P 0 "register_operand" "=r")
6387 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6388 (match_operand:P 2 "register_operand" "r")]
6389 UNSPECV_PROBE_STACK_RANGE))]
6391 "* return output_probe_stack_range (operands[0], operands[2]);"
6392 [(set_attr "type" "multi")])
6394 ;; Prepare to return any type including a structure value.
6396 (define_expand "untyped_return"
6397 [(match_operand:BLK 0 "memory_operand" "")
6398 (match_operand 1 "" "")]
6401 rtx valreg1 = gen_rtx_REG (DImode, 24);
6402 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6403 rtx result = operands[0];
6405 if (! TARGET_ARCH64)
6407 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6408 rtx value = gen_reg_rtx (SImode);
6410 /* Fetch the instruction where we will return to and see if it's an unimp
6411 instruction (the most significant 10 bits will be zero). If so,
6412 update the return address to skip the unimp instruction. */
6413 emit_move_insn (value,
6414 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6415 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6416 emit_insn (gen_update_return (rtnreg, value));
6419 /* Reload the function value registers. */
6420 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6421 emit_move_insn (valreg2,
6422 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6424 /* Put USE insns before the return. */
6428 /* Construct the return. */
6429 expand_naked_return ();
6434 ;; Adjust the return address conditionally. If the value of op1 is equal
6435 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6436 ;; This is technically *half* the check required by the 32-bit SPARC
6437 ;; psABI. This check only ensures that an "unimp" insn was written by
6438 ;; the caller, but doesn't check to see if the expected size matches
6439 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6440 ;; only used by the above code "untyped_return".
6442 (define_insn "update_return"
6443 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6444 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6447 if (flag_delayed_branch)
6448 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6450 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6452 [(set (attr "type") (const_string "multi"))
6453 (set (attr "length")
6454 (if_then_else (eq_attr "delayed_branch" "true")
6463 (define_expand "indirect_jump"
6464 [(set (pc) (match_operand 0 "address_operand" "p"))]
6468 (define_insn "*branch_sp32"
6469 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6472 [(set_attr "type" "uncond_branch")])
6474 (define_insn "*branch_sp64"
6475 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6478 [(set_attr "type" "uncond_branch")])
6480 (define_expand "save_stack_nonlocal"
6481 [(set (match_operand 0 "memory_operand" "")
6482 (match_operand 1 "register_operand" ""))
6483 (set (match_dup 2) (match_dup 3))]
6486 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6487 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6488 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6491 (define_expand "restore_stack_nonlocal"
6492 [(set (match_operand 0 "register_operand" "")
6493 (match_operand 1 "memory_operand" ""))]
6496 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6499 (define_expand "nonlocal_goto"
6500 [(match_operand 0 "general_operand" "")
6501 (match_operand 1 "general_operand" "")
6502 (match_operand 2 "memory_operand" "")
6503 (match_operand 3 "memory_operand" "")]
6506 rtx r_label = copy_to_reg (operands[1]);
6507 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6508 rtx r_fp = operands[3];
6509 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6511 /* We need to flush all the register windows so that their contents will
6512 be re-synchronized by the restore insn of the target function. */
6514 emit_insn (gen_flush_register_windows ());
6516 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6517 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6519 /* Restore frame pointer for containing function. */
6520 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6521 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6523 /* USE of hard_frame_pointer_rtx added for consistency;
6524 not clear if really needed. */
6525 emit_use (hard_frame_pointer_rtx);
6526 emit_use (stack_pointer_rtx);
6528 /* We need to smuggle the load of %i7 as it is a fixed register. */
6529 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6534 (define_insn "nonlocal_goto_internal"
6535 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6536 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6537 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6539 if (flag_delayed_branch)
6542 return "jmp\t%0\n\t ldx\t%1, %%i7";
6544 return "jmp\t%0\n\t ld\t%1, %%i7";
6549 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6551 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6554 [(set (attr "type") (const_string "multi"))
6555 (set (attr "length")
6556 (if_then_else (eq_attr "delayed_branch" "true")
6560 (define_expand "builtin_setjmp_receiver"
6561 [(label_ref (match_operand 0 "" ""))]
6564 load_got_register ();
6568 ;; Special insn to flush register windows.
6570 (define_insn "flush_register_windows"
6571 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6573 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6574 [(set_attr "type" "flushw")])
6576 ;; Special pattern for the FLUSH instruction.
6578 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6579 ; of the define_insn otherwise missing a mode. We make "flush", aka
6580 ; gen_flush, the default one since sparc_initialize_trampoline uses
6581 ; it on SImode mem values.
6583 (define_insn "flush"
6584 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6586 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6587 [(set_attr "type" "iflush")])
6589 (define_insn "flushdi"
6590 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6592 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6593 [(set_attr "type" "iflush")])
6596 ;; Find first set instructions.
6598 ;; The scan instruction searches from the most significant bit while ffs
6599 ;; searches from the least significant bit. The bit index and treatment of
6600 ;; zero also differ. It takes at least 7 instructions to get the proper
6601 ;; result. Here is an obvious 8 instruction sequence.
6604 (define_insn "ffssi2"
6605 [(set (match_operand:SI 0 "register_operand" "=&r")
6606 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6607 (clobber (match_scratch:SI 2 "=&r"))]
6608 "TARGET_SPARCLITE || TARGET_SPARCLET"
6610 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";
6612 [(set_attr "type" "multi")
6613 (set_attr "length" "8")])
6615 (define_expand "popcountdi2"
6616 [(set (match_operand:DI 0 "register_operand" "")
6617 (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6620 if (! TARGET_ARCH64)
6622 emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6627 (define_insn "*popcountdi_sp64"
6628 [(set (match_operand:DI 0 "register_operand" "=r")
6629 (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6630 "TARGET_POPC && TARGET_ARCH64"
6633 (define_insn "popcountdi_v8plus"
6634 [(set (match_operand:DI 0 "register_operand" "=r")
6635 (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6636 (clobber (match_scratch:SI 2 "=&h"))]
6637 "TARGET_POPC && ! TARGET_ARCH64"
6639 if (sparc_check_64 (operands[1], insn) <= 0)
6640 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6641 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6643 [(set_attr "type" "multi")
6644 (set_attr "length" "5")])
6646 (define_expand "popcountsi2"
6648 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6649 (set (match_operand:SI 0 "register_operand" "")
6650 (truncate:SI (popcount:DI (match_dup 2))))]
6653 if (! TARGET_ARCH64)
6655 emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6659 operands[2] = gen_reg_rtx (DImode);
6662 (define_insn "*popcountsi_sp64"
6663 [(set (match_operand:SI 0 "register_operand" "=r")
6665 (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6666 "TARGET_POPC && TARGET_ARCH64"
6669 (define_insn "popcountsi_v8plus"
6670 [(set (match_operand:SI 0 "register_operand" "=r")
6671 (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6672 "TARGET_POPC && ! TARGET_ARCH64"
6674 if (sparc_check_64 (operands[1], insn) <= 0)
6675 output_asm_insn ("srl\t%1, 0, %1", operands);
6676 return "popc\t%1, %0";
6678 [(set_attr "type" "multi")
6679 (set_attr "length" "2")])
6681 (define_expand "clzdi2"
6682 [(set (match_operand:DI 0 "register_operand" "")
6683 (clz:DI (match_operand:DI 1 "register_operand" "")))]
6686 if (! TARGET_ARCH64)
6688 emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6693 (define_insn "*clzdi_sp64"
6694 [(set (match_operand:DI 0 "register_operand" "=r")
6695 (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6696 "TARGET_VIS3 && TARGET_ARCH64"
6699 (define_insn "clzdi_v8plus"
6700 [(set (match_operand:DI 0 "register_operand" "=r")
6701 (clz:DI (match_operand:DI 1 "register_operand" "r")))
6702 (clobber (match_scratch:SI 2 "=&h"))]
6703 "TARGET_VIS3 && ! TARGET_ARCH64"
6705 if (sparc_check_64 (operands[1], insn) <= 0)
6706 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6707 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6709 [(set_attr "type" "multi")
6710 (set_attr "length" "5")])
6712 (define_expand "clzsi2"
6714 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6716 (truncate:SI (clz:DI (match_dup 2))))
6717 (set (match_operand:SI 0 "register_operand" "")
6718 (minus:SI (match_dup 3) (const_int 32)))]
6721 if (! TARGET_ARCH64)
6723 emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6728 operands[2] = gen_reg_rtx (DImode);
6729 operands[3] = gen_reg_rtx (SImode);
6733 (define_insn "*clzsi_sp64"
6734 [(set (match_operand:SI 0 "register_operand" "=r")
6736 (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6737 "TARGET_VIS3 && TARGET_ARCH64"
6740 (define_insn "clzsi_v8plus"
6741 [(set (match_operand:SI 0 "register_operand" "=r")
6742 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6743 "TARGET_VIS3 && ! TARGET_ARCH64"
6745 if (sparc_check_64 (operands[1], insn) <= 0)
6746 output_asm_insn ("srl\t%1, 0, %1", operands);
6747 return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6749 [(set_attr "type" "multi")
6750 (set_attr "length" "3")])
6753 ;; Peepholes go at the end.
6755 ;; Optimize consecutive loads or stores into ldd and std when possible.
6756 ;; The conditions in which we do this are very restricted and are
6757 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6760 [(set (match_operand:SI 0 "memory_operand" "")
6762 (set (match_operand:SI 1 "memory_operand" "")
6765 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6768 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6771 [(set (match_operand:SI 0 "memory_operand" "")
6773 (set (match_operand:SI 1 "memory_operand" "")
6776 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6779 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6782 [(set (match_operand:SI 0 "register_operand" "")
6783 (match_operand:SI 1 "memory_operand" ""))
6784 (set (match_operand:SI 2 "register_operand" "")
6785 (match_operand:SI 3 "memory_operand" ""))]
6786 "registers_ok_for_ldd_peep (operands[0], operands[2])
6787 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6790 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6791 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6794 [(set (match_operand:SI 0 "memory_operand" "")
6795 (match_operand:SI 1 "register_operand" ""))
6796 (set (match_operand:SI 2 "memory_operand" "")
6797 (match_operand:SI 3 "register_operand" ""))]
6798 "registers_ok_for_ldd_peep (operands[1], operands[3])
6799 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6802 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6803 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6806 [(set (match_operand:SF 0 "register_operand" "")
6807 (match_operand:SF 1 "memory_operand" ""))
6808 (set (match_operand:SF 2 "register_operand" "")
6809 (match_operand:SF 3 "memory_operand" ""))]
6810 "registers_ok_for_ldd_peep (operands[0], operands[2])
6811 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6814 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6815 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6818 [(set (match_operand:SF 0 "memory_operand" "")
6819 (match_operand:SF 1 "register_operand" ""))
6820 (set (match_operand:SF 2 "memory_operand" "")
6821 (match_operand:SF 3 "register_operand" ""))]
6822 "registers_ok_for_ldd_peep (operands[1], operands[3])
6823 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6826 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6827 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6830 [(set (match_operand:SI 0 "register_operand" "")
6831 (match_operand:SI 1 "memory_operand" ""))
6832 (set (match_operand:SI 2 "register_operand" "")
6833 (match_operand:SI 3 "memory_operand" ""))]
6834 "registers_ok_for_ldd_peep (operands[2], operands[0])
6835 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6838 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6839 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6842 [(set (match_operand:SI 0 "memory_operand" "")
6843 (match_operand:SI 1 "register_operand" ""))
6844 (set (match_operand:SI 2 "memory_operand" "")
6845 (match_operand:SI 3 "register_operand" ""))]
6846 "registers_ok_for_ldd_peep (operands[3], operands[1])
6847 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6850 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6851 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6855 [(set (match_operand:SF 0 "register_operand" "")
6856 (match_operand:SF 1 "memory_operand" ""))
6857 (set (match_operand:SF 2 "register_operand" "")
6858 (match_operand:SF 3 "memory_operand" ""))]
6859 "registers_ok_for_ldd_peep (operands[2], operands[0])
6860 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6863 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6864 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6867 [(set (match_operand:SF 0 "memory_operand" "")
6868 (match_operand:SF 1 "register_operand" ""))
6869 (set (match_operand:SF 2 "memory_operand" "")
6870 (match_operand:SF 3 "register_operand" ""))]
6871 "registers_ok_for_ldd_peep (operands[3], operands[1])
6872 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6875 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6876 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6878 ;; Optimize the case of following a reg-reg move with a test
6879 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6880 ;; This can result from a float to fix conversion.
6883 [(set (match_operand:SI 0 "register_operand" "")
6884 (match_operand:SI 1 "register_operand" ""))
6885 (set (reg:CC CC_REG)
6886 (compare:CC (match_operand:SI 2 "register_operand" "")
6888 "(rtx_equal_p (operands[2], operands[0])
6889 || rtx_equal_p (operands[2], operands[1]))
6890 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6891 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6892 [(parallel [(set (match_dup 0) (match_dup 1))
6893 (set (reg:CC CC_REG)
6894 (compare:CC (match_dup 1) (const_int 0)))])]
6898 [(set (match_operand:DI 0 "register_operand" "")
6899 (match_operand:DI 1 "register_operand" ""))
6900 (set (reg:CCX CC_REG)
6901 (compare:CCX (match_operand:DI 2 "register_operand" "")
6904 && (rtx_equal_p (operands[2], operands[0])
6905 || rtx_equal_p (operands[2], operands[1]))
6906 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6907 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6908 [(parallel [(set (match_dup 0) (match_dup 1))
6909 (set (reg:CCX CC_REG)
6910 (compare:CCX (match_dup 1) (const_int 0)))])]
6914 ;; Prefetch instructions.
6916 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6917 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6918 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6920 (define_expand "prefetch"
6921 [(match_operand 0 "address_operand" "")
6922 (match_operand 1 "const_int_operand" "")
6923 (match_operand 2 "const_int_operand" "")]
6927 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6929 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6933 (define_insn "prefetch_64"
6934 [(prefetch (match_operand:DI 0 "address_operand" "p")
6935 (match_operand:DI 1 "const_int_operand" "n")
6936 (match_operand:DI 2 "const_int_operand" "n"))]
6939 static const char * const prefetch_instr[2][2] = {
6941 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6942 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6945 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6946 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6949 int read_or_write = INTVAL (operands[1]);
6950 int locality = INTVAL (operands[2]);
6952 gcc_assert (read_or_write == 0 || read_or_write == 1);
6953 gcc_assert (locality >= 0 && locality < 4);
6954 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6956 [(set_attr "type" "load")])
6958 (define_insn "prefetch_32"
6959 [(prefetch (match_operand:SI 0 "address_operand" "p")
6960 (match_operand:SI 1 "const_int_operand" "n")
6961 (match_operand:SI 2 "const_int_operand" "n"))]
6964 static const char * const prefetch_instr[2][2] = {
6966 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6967 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6970 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6971 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6974 int read_or_write = INTVAL (operands[1]);
6975 int locality = INTVAL (operands[2]);
6977 gcc_assert (read_or_write == 0 || read_or_write == 1);
6978 gcc_assert (locality >= 0 && locality < 4);
6979 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6981 [(set_attr "type" "load")])
6984 ;; Trap instructions.
6987 [(trap_if (const_int 1) (const_int 5))]
6990 [(set_attr "type" "trap")])
6992 (define_expand "ctrapsi4"
6993 [(trap_if (match_operator 0 "noov_compare_operator"
6994 [(match_operand:SI 1 "compare_operand" "")
6995 (match_operand:SI 2 "arith_operand" "")])
6996 (match_operand 3 ""))]
6998 "operands[1] = gen_compare_reg (operands[0]);
6999 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7001 operands[2] = const0_rtx;")
7003 (define_expand "ctrapdi4"
7004 [(trap_if (match_operator 0 "noov_compare_operator"
7005 [(match_operand:DI 1 "compare_operand" "")
7006 (match_operand:DI 2 "arith_operand" "")])
7007 (match_operand 3 ""))]
7009 "operands[1] = gen_compare_reg (operands[0]);
7010 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7012 operands[2] = const0_rtx;")
7016 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7017 (match_operand:SI 1 "arith_operand" "rM"))]
7021 return "t%C0\t%%icc, %1";
7025 [(set_attr "type" "trap")])
7028 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7029 (match_operand:SI 1 "arith_operand" "rM"))]
7032 [(set_attr "type" "trap")])
7035 ;; TLS support instructions.
7037 (define_insn "tgd_hi22"
7038 [(set (match_operand:SI 0 "register_operand" "=r")
7039 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7042 "sethi\\t%%tgd_hi22(%a1), %0")
7044 (define_insn "tgd_lo10"
7045 [(set (match_operand:SI 0 "register_operand" "=r")
7046 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7047 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7050 "add\\t%1, %%tgd_lo10(%a2), %0")
7052 (define_insn "tgd_add32"
7053 [(set (match_operand:SI 0 "register_operand" "=r")
7054 (plus:SI (match_operand:SI 1 "register_operand" "r")
7055 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7056 (match_operand 3 "tgd_symbolic_operand" "")]
7058 "TARGET_TLS && TARGET_ARCH32"
7059 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7061 (define_insn "tgd_add64"
7062 [(set (match_operand:DI 0 "register_operand" "=r")
7063 (plus:DI (match_operand:DI 1 "register_operand" "r")
7064 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7065 (match_operand 3 "tgd_symbolic_operand" "")]
7067 "TARGET_TLS && TARGET_ARCH64"
7068 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7070 (define_insn "tgd_call32"
7071 [(set (match_operand 0 "register_operand" "=r")
7072 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7073 (match_operand 2 "tgd_symbolic_operand" "")]
7075 (match_operand 3 "" "")))
7076 (clobber (reg:SI O7_REG))]
7077 "TARGET_TLS && TARGET_ARCH32"
7078 "call\t%a1, %%tgd_call(%a2)%#"
7079 [(set_attr "type" "call")])
7081 (define_insn "tgd_call64"
7082 [(set (match_operand 0 "register_operand" "=r")
7083 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7084 (match_operand 2 "tgd_symbolic_operand" "")]
7086 (match_operand 3 "" "")))
7087 (clobber (reg:DI O7_REG))]
7088 "TARGET_TLS && TARGET_ARCH64"
7089 "call\t%a1, %%tgd_call(%a2)%#"
7090 [(set_attr "type" "call")])
7092 (define_insn "tldm_hi22"
7093 [(set (match_operand:SI 0 "register_operand" "=r")
7094 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7096 "sethi\\t%%tldm_hi22(%&), %0")
7098 (define_insn "tldm_lo10"
7099 [(set (match_operand:SI 0 "register_operand" "=r")
7100 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7101 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7103 "add\\t%1, %%tldm_lo10(%&), %0")
7105 (define_insn "tldm_add32"
7106 [(set (match_operand:SI 0 "register_operand" "=r")
7107 (plus:SI (match_operand:SI 1 "register_operand" "r")
7108 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7110 "TARGET_TLS && TARGET_ARCH32"
7111 "add\\t%1, %2, %0, %%tldm_add(%&)")
7113 (define_insn "tldm_add64"
7114 [(set (match_operand:DI 0 "register_operand" "=r")
7115 (plus:DI (match_operand:DI 1 "register_operand" "r")
7116 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7118 "TARGET_TLS && TARGET_ARCH64"
7119 "add\\t%1, %2, %0, %%tldm_add(%&)")
7121 (define_insn "tldm_call32"
7122 [(set (match_operand 0 "register_operand" "=r")
7123 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7125 (match_operand 2 "" "")))
7126 (clobber (reg:SI O7_REG))]
7127 "TARGET_TLS && TARGET_ARCH32"
7128 "call\t%a1, %%tldm_call(%&)%#"
7129 [(set_attr "type" "call")])
7131 (define_insn "tldm_call64"
7132 [(set (match_operand 0 "register_operand" "=r")
7133 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7135 (match_operand 2 "" "")))
7136 (clobber (reg:DI O7_REG))]
7137 "TARGET_TLS && TARGET_ARCH64"
7138 "call\t%a1, %%tldm_call(%&)%#"
7139 [(set_attr "type" "call")])
7141 (define_insn "tldo_hix22"
7142 [(set (match_operand:SI 0 "register_operand" "=r")
7143 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7146 "sethi\\t%%tldo_hix22(%a1), %0")
7148 (define_insn "tldo_lox10"
7149 [(set (match_operand:SI 0 "register_operand" "=r")
7150 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7151 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7154 "xor\\t%1, %%tldo_lox10(%a2), %0")
7156 (define_insn "tldo_add32"
7157 [(set (match_operand:SI 0 "register_operand" "=r")
7158 (plus:SI (match_operand:SI 1 "register_operand" "r")
7159 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7160 (match_operand 3 "tld_symbolic_operand" "")]
7162 "TARGET_TLS && TARGET_ARCH32"
7163 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7165 (define_insn "tldo_add64"
7166 [(set (match_operand:DI 0 "register_operand" "=r")
7167 (plus:DI (match_operand:DI 1 "register_operand" "r")
7168 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7169 (match_operand 3 "tld_symbolic_operand" "")]
7171 "TARGET_TLS && TARGET_ARCH64"
7172 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7174 (define_insn "tie_hi22"
7175 [(set (match_operand:SI 0 "register_operand" "=r")
7176 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7179 "sethi\\t%%tie_hi22(%a1), %0")
7181 (define_insn "tie_lo10"
7182 [(set (match_operand:SI 0 "register_operand" "=r")
7183 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7184 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7187 "add\\t%1, %%tie_lo10(%a2), %0")
7189 (define_insn "tie_ld32"
7190 [(set (match_operand:SI 0 "register_operand" "=r")
7191 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7192 (match_operand:SI 2 "register_operand" "r")
7193 (match_operand 3 "tie_symbolic_operand" "")]
7195 "TARGET_TLS && TARGET_ARCH32"
7196 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7197 [(set_attr "type" "load")])
7199 (define_insn "tie_ld64"
7200 [(set (match_operand:DI 0 "register_operand" "=r")
7201 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7202 (match_operand:SI 2 "register_operand" "r")
7203 (match_operand 3 "tie_symbolic_operand" "")]
7205 "TARGET_TLS && TARGET_ARCH64"
7206 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7207 [(set_attr "type" "load")])
7209 (define_insn "tie_add32"
7210 [(set (match_operand:SI 0 "register_operand" "=r")
7211 (plus:SI (match_operand:SI 1 "register_operand" "r")
7212 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7213 (match_operand 3 "tie_symbolic_operand" "")]
7215 "TARGET_SUN_TLS && TARGET_ARCH32"
7216 "add\\t%1, %2, %0, %%tie_add(%a3)")
7218 (define_insn "tie_add64"
7219 [(set (match_operand:DI 0 "register_operand" "=r")
7220 (plus:DI (match_operand:DI 1 "register_operand" "r")
7221 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7222 (match_operand 3 "tie_symbolic_operand" "")]
7224 "TARGET_SUN_TLS && TARGET_ARCH64"
7225 "add\\t%1, %2, %0, %%tie_add(%a3)")
7227 (define_insn "tle_hix22_sp32"
7228 [(set (match_operand:SI 0 "register_operand" "=r")
7229 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7231 "TARGET_TLS && TARGET_ARCH32"
7232 "sethi\\t%%tle_hix22(%a1), %0")
7234 (define_insn "tle_lox10_sp32"
7235 [(set (match_operand:SI 0 "register_operand" "=r")
7236 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7237 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7239 "TARGET_TLS && TARGET_ARCH32"
7240 "xor\\t%1, %%tle_lox10(%a2), %0")
7242 (define_insn "tle_hix22_sp64"
7243 [(set (match_operand:DI 0 "register_operand" "=r")
7244 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7246 "TARGET_TLS && TARGET_ARCH64"
7247 "sethi\\t%%tle_hix22(%a1), %0")
7249 (define_insn "tle_lox10_sp64"
7250 [(set (match_operand:DI 0 "register_operand" "=r")
7251 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7252 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7254 "TARGET_TLS && TARGET_ARCH64"
7255 "xor\\t%1, %%tle_lox10(%a2), %0")
7257 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7258 (define_insn "*tldo_ldub_sp32"
7259 [(set (match_operand:QI 0 "register_operand" "=r")
7260 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7261 (match_operand 3 "tld_symbolic_operand" "")]
7263 (match_operand:SI 1 "register_operand" "r"))))]
7264 "TARGET_TLS && TARGET_ARCH32"
7265 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7266 [(set_attr "type" "load")
7267 (set_attr "us3load_type" "3cycle")])
7269 (define_insn "*tldo_ldub1_sp32"
7270 [(set (match_operand:HI 0 "register_operand" "=r")
7271 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7272 (match_operand 3 "tld_symbolic_operand" "")]
7274 (match_operand:SI 1 "register_operand" "r")))))]
7275 "TARGET_TLS && TARGET_ARCH32"
7276 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7277 [(set_attr "type" "load")
7278 (set_attr "us3load_type" "3cycle")])
7280 (define_insn "*tldo_ldub2_sp32"
7281 [(set (match_operand:SI 0 "register_operand" "=r")
7282 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7283 (match_operand 3 "tld_symbolic_operand" "")]
7285 (match_operand:SI 1 "register_operand" "r")))))]
7286 "TARGET_TLS && TARGET_ARCH32"
7287 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7288 [(set_attr "type" "load")
7289 (set_attr "us3load_type" "3cycle")])
7291 (define_insn "*tldo_ldsb1_sp32"
7292 [(set (match_operand:HI 0 "register_operand" "=r")
7293 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7294 (match_operand 3 "tld_symbolic_operand" "")]
7296 (match_operand:SI 1 "register_operand" "r")))))]
7297 "TARGET_TLS && TARGET_ARCH32"
7298 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7299 [(set_attr "type" "sload")
7300 (set_attr "us3load_type" "3cycle")])
7302 (define_insn "*tldo_ldsb2_sp32"
7303 [(set (match_operand:SI 0 "register_operand" "=r")
7304 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7305 (match_operand 3 "tld_symbolic_operand" "")]
7307 (match_operand:SI 1 "register_operand" "r")))))]
7308 "TARGET_TLS && TARGET_ARCH32"
7309 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7310 [(set_attr "type" "sload")
7311 (set_attr "us3load_type" "3cycle")])
7313 (define_insn "*tldo_ldub_sp64"
7314 [(set (match_operand:QI 0 "register_operand" "=r")
7315 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7316 (match_operand 3 "tld_symbolic_operand" "")]
7318 (match_operand:DI 1 "register_operand" "r"))))]
7319 "TARGET_TLS && TARGET_ARCH64"
7320 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7321 [(set_attr "type" "load")
7322 (set_attr "us3load_type" "3cycle")])
7324 (define_insn "*tldo_ldub1_sp64"
7325 [(set (match_operand:HI 0 "register_operand" "=r")
7326 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7327 (match_operand 3 "tld_symbolic_operand" "")]
7329 (match_operand:DI 1 "register_operand" "r")))))]
7330 "TARGET_TLS && TARGET_ARCH64"
7331 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7332 [(set_attr "type" "load")
7333 (set_attr "us3load_type" "3cycle")])
7335 (define_insn "*tldo_ldub2_sp64"
7336 [(set (match_operand:SI 0 "register_operand" "=r")
7337 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7338 (match_operand 3 "tld_symbolic_operand" "")]
7340 (match_operand:DI 1 "register_operand" "r")))))]
7341 "TARGET_TLS && TARGET_ARCH64"
7342 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7343 [(set_attr "type" "load")
7344 (set_attr "us3load_type" "3cycle")])
7346 (define_insn "*tldo_ldub3_sp64"
7347 [(set (match_operand:DI 0 "register_operand" "=r")
7348 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7349 (match_operand 3 "tld_symbolic_operand" "")]
7351 (match_operand:DI 1 "register_operand" "r")))))]
7352 "TARGET_TLS && TARGET_ARCH64"
7353 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7354 [(set_attr "type" "load")
7355 (set_attr "us3load_type" "3cycle")])
7357 (define_insn "*tldo_ldsb1_sp64"
7358 [(set (match_operand:HI 0 "register_operand" "=r")
7359 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7360 (match_operand 3 "tld_symbolic_operand" "")]
7362 (match_operand:DI 1 "register_operand" "r")))))]
7363 "TARGET_TLS && TARGET_ARCH64"
7364 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7365 [(set_attr "type" "sload")
7366 (set_attr "us3load_type" "3cycle")])
7368 (define_insn "*tldo_ldsb2_sp64"
7369 [(set (match_operand:SI 0 "register_operand" "=r")
7370 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7371 (match_operand 3 "tld_symbolic_operand" "")]
7373 (match_operand:DI 1 "register_operand" "r")))))]
7374 "TARGET_TLS && TARGET_ARCH64"
7375 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7376 [(set_attr "type" "sload")
7377 (set_attr "us3load_type" "3cycle")])
7379 (define_insn "*tldo_ldsb3_sp64"
7380 [(set (match_operand:DI 0 "register_operand" "=r")
7381 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7382 (match_operand 3 "tld_symbolic_operand" "")]
7384 (match_operand:DI 1 "register_operand" "r")))))]
7385 "TARGET_TLS && TARGET_ARCH64"
7386 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7387 [(set_attr "type" "sload")
7388 (set_attr "us3load_type" "3cycle")])
7390 (define_insn "*tldo_lduh_sp32"
7391 [(set (match_operand:HI 0 "register_operand" "=r")
7392 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7393 (match_operand 3 "tld_symbolic_operand" "")]
7395 (match_operand:SI 1 "register_operand" "r"))))]
7396 "TARGET_TLS && TARGET_ARCH32"
7397 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7398 [(set_attr "type" "load")
7399 (set_attr "us3load_type" "3cycle")])
7401 (define_insn "*tldo_lduh1_sp32"
7402 [(set (match_operand:SI 0 "register_operand" "=r")
7403 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7404 (match_operand 3 "tld_symbolic_operand" "")]
7406 (match_operand:SI 1 "register_operand" "r")))))]
7407 "TARGET_TLS && TARGET_ARCH32"
7408 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7409 [(set_attr "type" "load")
7410 (set_attr "us3load_type" "3cycle")])
7412 (define_insn "*tldo_ldsh1_sp32"
7413 [(set (match_operand:SI 0 "register_operand" "=r")
7414 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7415 (match_operand 3 "tld_symbolic_operand" "")]
7417 (match_operand:SI 1 "register_operand" "r")))))]
7418 "TARGET_TLS && TARGET_ARCH32"
7419 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7420 [(set_attr "type" "sload")
7421 (set_attr "us3load_type" "3cycle")])
7423 (define_insn "*tldo_lduh_sp64"
7424 [(set (match_operand:HI 0 "register_operand" "=r")
7425 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7426 (match_operand 3 "tld_symbolic_operand" "")]
7428 (match_operand:DI 1 "register_operand" "r"))))]
7429 "TARGET_TLS && TARGET_ARCH64"
7430 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7431 [(set_attr "type" "load")
7432 (set_attr "us3load_type" "3cycle")])
7434 (define_insn "*tldo_lduh1_sp64"
7435 [(set (match_operand:SI 0 "register_operand" "=r")
7436 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7437 (match_operand 3 "tld_symbolic_operand" "")]
7439 (match_operand:DI 1 "register_operand" "r")))))]
7440 "TARGET_TLS && TARGET_ARCH64"
7441 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7442 [(set_attr "type" "load")
7443 (set_attr "us3load_type" "3cycle")])
7445 (define_insn "*tldo_lduh2_sp64"
7446 [(set (match_operand:DI 0 "register_operand" "=r")
7447 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7448 (match_operand 3 "tld_symbolic_operand" "")]
7450 (match_operand:DI 1 "register_operand" "r")))))]
7451 "TARGET_TLS && TARGET_ARCH64"
7452 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7453 [(set_attr "type" "load")
7454 (set_attr "us3load_type" "3cycle")])
7456 (define_insn "*tldo_ldsh1_sp64"
7457 [(set (match_operand:SI 0 "register_operand" "=r")
7458 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7459 (match_operand 3 "tld_symbolic_operand" "")]
7461 (match_operand:DI 1 "register_operand" "r")))))]
7462 "TARGET_TLS && TARGET_ARCH64"
7463 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7464 [(set_attr "type" "sload")
7465 (set_attr "us3load_type" "3cycle")])
7467 (define_insn "*tldo_ldsh2_sp64"
7468 [(set (match_operand:DI 0 "register_operand" "=r")
7469 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7470 (match_operand 3 "tld_symbolic_operand" "")]
7472 (match_operand:DI 1 "register_operand" "r")))))]
7473 "TARGET_TLS && TARGET_ARCH64"
7474 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7475 [(set_attr "type" "sload")
7476 (set_attr "us3load_type" "3cycle")])
7478 (define_insn "*tldo_lduw_sp32"
7479 [(set (match_operand:SI 0 "register_operand" "=r")
7480 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7481 (match_operand 3 "tld_symbolic_operand" "")]
7483 (match_operand:SI 1 "register_operand" "r"))))]
7484 "TARGET_TLS && TARGET_ARCH32"
7485 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7486 [(set_attr "type" "load")])
7488 (define_insn "*tldo_lduw_sp64"
7489 [(set (match_operand:SI 0 "register_operand" "=r")
7490 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7491 (match_operand 3 "tld_symbolic_operand" "")]
7493 (match_operand:DI 1 "register_operand" "r"))))]
7494 "TARGET_TLS && TARGET_ARCH64"
7495 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7496 [(set_attr "type" "load")])
7498 (define_insn "*tldo_lduw1_sp64"
7499 [(set (match_operand:DI 0 "register_operand" "=r")
7500 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7501 (match_operand 3 "tld_symbolic_operand" "")]
7503 (match_operand:DI 1 "register_operand" "r")))))]
7504 "TARGET_TLS && TARGET_ARCH64"
7505 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7506 [(set_attr "type" "load")])
7508 (define_insn "*tldo_ldsw1_sp64"
7509 [(set (match_operand:DI 0 "register_operand" "=r")
7510 (sign_extend:DI (mem:SI (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 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7516 [(set_attr "type" "sload")
7517 (set_attr "us3load_type" "3cycle")])
7519 (define_insn "*tldo_ldx_sp64"
7520 [(set (match_operand:DI 0 "register_operand" "=r")
7521 (mem:DI (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 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7527 [(set_attr "type" "load")])
7529 (define_insn "*tldo_stb_sp32"
7530 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7531 (match_operand 3 "tld_symbolic_operand" "")]
7533 (match_operand:SI 1 "register_operand" "r")))
7534 (match_operand:QI 0 "register_operand" "=r"))]
7535 "TARGET_TLS && TARGET_ARCH32"
7536 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7537 [(set_attr "type" "store")])
7539 (define_insn "*tldo_stb_sp64"
7540 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7541 (match_operand 3 "tld_symbolic_operand" "")]
7543 (match_operand:DI 1 "register_operand" "r")))
7544 (match_operand:QI 0 "register_operand" "=r"))]
7545 "TARGET_TLS && TARGET_ARCH64"
7546 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7547 [(set_attr "type" "store")])
7549 (define_insn "*tldo_sth_sp32"
7550 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7551 (match_operand 3 "tld_symbolic_operand" "")]
7553 (match_operand:SI 1 "register_operand" "r")))
7554 (match_operand:HI 0 "register_operand" "=r"))]
7555 "TARGET_TLS && TARGET_ARCH32"
7556 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7557 [(set_attr "type" "store")])
7559 (define_insn "*tldo_sth_sp64"
7560 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7561 (match_operand 3 "tld_symbolic_operand" "")]
7563 (match_operand:DI 1 "register_operand" "r")))
7564 (match_operand:HI 0 "register_operand" "=r"))]
7565 "TARGET_TLS && TARGET_ARCH64"
7566 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7567 [(set_attr "type" "store")])
7569 (define_insn "*tldo_stw_sp32"
7570 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7571 (match_operand 3 "tld_symbolic_operand" "")]
7573 (match_operand:SI 1 "register_operand" "r")))
7574 (match_operand:SI 0 "register_operand" "=r"))]
7575 "TARGET_TLS && TARGET_ARCH32"
7576 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7577 [(set_attr "type" "store")])
7579 (define_insn "*tldo_stw_sp64"
7580 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7581 (match_operand 3 "tld_symbolic_operand" "")]
7583 (match_operand:DI 1 "register_operand" "r")))
7584 (match_operand:SI 0 "register_operand" "=r"))]
7585 "TARGET_TLS && TARGET_ARCH64"
7586 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7587 [(set_attr "type" "store")])
7589 (define_insn "*tldo_stx_sp64"
7590 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7591 (match_operand 3 "tld_symbolic_operand" "")]
7593 (match_operand:DI 1 "register_operand" "r")))
7594 (match_operand:DI 0 "register_operand" "=r"))]
7595 "TARGET_TLS && TARGET_ARCH64"
7596 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7597 [(set_attr "type" "store")])
7600 ;; Stack protector instructions.
7602 (define_expand "stack_protect_set"
7603 [(match_operand 0 "memory_operand" "")
7604 (match_operand 1 "memory_operand" "")]
7607 #ifdef TARGET_THREAD_SSP_OFFSET
7608 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7609 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7610 operands[1] = gen_rtx_MEM (Pmode, addr);
7613 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7615 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7619 (define_insn "stack_protect_setsi"
7620 [(set (match_operand:SI 0 "memory_operand" "=m")
7621 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7622 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7624 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7625 [(set_attr "type" "multi")
7626 (set_attr "length" "3")])
7628 (define_insn "stack_protect_setdi"
7629 [(set (match_operand:DI 0 "memory_operand" "=m")
7630 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7631 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7633 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7634 [(set_attr "type" "multi")
7635 (set_attr "length" "3")])
7637 (define_expand "stack_protect_test"
7638 [(match_operand 0 "memory_operand" "")
7639 (match_operand 1 "memory_operand" "")
7640 (match_operand 2 "" "")]
7644 #ifdef TARGET_THREAD_SSP_OFFSET
7645 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7646 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7647 operands[1] = gen_rtx_MEM (Pmode, addr);
7651 result = gen_reg_rtx (Pmode);
7652 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7653 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7654 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7658 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7659 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7660 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7661 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7666 (define_insn "stack_protect_testsi"
7667 [(set (reg:CC CC_REG)
7668 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7669 (match_operand:SI 1 "memory_operand" "m")]
7671 (set (match_scratch:SI 3 "=r") (const_int 0))
7672 (clobber (match_scratch:SI 2 "=&r"))]
7674 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7675 [(set_attr "type" "multi")
7676 (set_attr "length" "4")])
7678 (define_insn "stack_protect_testdi"
7679 [(set (match_operand:DI 0 "register_operand" "=&r")
7680 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7681 (match_operand:DI 2 "memory_operand" "m")]
7683 (set (match_scratch:DI 3 "=r") (const_int 0))]
7685 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7686 [(set_attr "type" "multi")
7687 (set_attr "length" "4")])
7689 ;; Vector instructions.
7691 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7692 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7693 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7695 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
7696 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7697 (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7698 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7699 (V1DI "double") (V2SI "double") (V4HI "double")
7702 (define_expand "mov<VMALL:mode>"
7703 [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7704 (match_operand:VMALL 1 "general_operand" ""))]
7707 if (sparc_expand_move (<VMALL:MODE>mode, operands))
7711 (define_insn "*mov<VM32:mode>_insn"
7712 [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
7713 (match_operand:VM32 1 "input_operand" "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
7715 && (register_operand (operands[0], <VM32:MODE>mode)
7716 || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7729 [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*,*")
7730 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
7732 (define_insn "*mov<VM64:mode>_insn_sp64"
7733 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
7734 (match_operand:VM64 1 "input_operand" "Y,C,e,m,e,Y, m,*r, e,*r,*r"))]
7737 && (register_operand (operands[0], <VM64:MODE>mode)
7738 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7751 [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*,*")
7752 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
7754 (define_insn "*mov<VM64:mode>_insn_sp32"
7755 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
7756 (match_operand:VM64 1 "input_operand" "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
7759 && (register_operand (operands[0], <VM64:MODE>mode)
7760 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7774 [(set_attr "type" "fga,fga,fga,*,*,fpload,fpstore,store,load,store,*,*")
7775 (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
7776 (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
7779 [(set (match_operand:VM64 0 "memory_operand" "")
7780 (match_operand:VM64 1 "register_operand" ""))]
7784 && (((REGNO (operands[1]) % 2) != 0)
7785 || ! mem_min_alignment (operands[0], 8))
7786 && offsettable_memref_p (operands[0])"
7787 [(clobber (const_int 0))]
7791 word0 = adjust_address (operands[0], SImode, 0);
7792 word1 = adjust_address (operands[0], SImode, 4);
7794 emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
7795 emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
7800 [(set (match_operand:VM64 0 "register_operand" "")
7801 (match_operand:VM64 1 "register_operand" ""))]
7805 && sparc_split_regreg_legitimate (operands[0], operands[1])"
7806 [(clobber (const_int 0))]
7808 rtx set_dest = operands[0];
7809 rtx set_src = operands[1];
7813 dest1 = gen_highpart (SImode, set_dest);
7814 dest2 = gen_lowpart (SImode, set_dest);
7815 src1 = gen_highpart (SImode, set_src);
7816 src2 = gen_lowpart (SImode, set_src);
7818 /* Now emit using the real source and destination we found, swapping
7819 the order if we detect overlap. */
7820 if (reg_overlap_mentioned_p (dest1, src2))
7822 emit_insn (gen_movsi (dest2, src2));
7823 emit_insn (gen_movsi (dest1, src1));
7827 emit_insn (gen_movsi (dest1, src1));
7828 emit_insn (gen_movsi (dest2, src2));
7833 (define_expand "zero_extend_v8qi_vis"
7834 [(set (match_operand:V8QI 0 "register_operand" "")
7837 (match_operand:QI 1 "memory_operand" ""))
7842 if (! REG_P (XEXP (operands[1], 0)))
7844 rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
7845 operands[1] = replace_equiv_address (operands[1], addr);
7847 operands[2] = CONST0_RTX (V8QImode);
7850 (define_expand "zero_extend_v4hi_vis"
7851 [(set (match_operand:V4HI 0 "register_operand" "")
7854 (match_operand:HI 1 "memory_operand" ""))
7859 if (! REG_P (XEXP (operands[1], 0)))
7861 rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
7862 operands[1] = replace_equiv_address (operands[1], addr);
7864 operands[2] = CONST0_RTX (V4HImode);
7867 (define_insn "*zero_extend_v8qi_<P:mode>_insn"
7868 [(set (match_operand:V8QI 0 "register_operand" "=e")
7871 (mem:QI (match_operand:P 1 "register_operand" "r")))
7872 (match_operand:V8QI 2 "const_zero_operand" "Y")
7875 "ldda\t[%1] 0xd0, %0")
7877 (define_insn "*zero_extend_v4hi_<P:mode>_insn"
7878 [(set (match_operand:V4HI 0 "register_operand" "=e")
7881 (mem:HI (match_operand:P 1 "register_operand" "r")))
7882 (match_operand:V4HI 2 "const_zero_operand" "Y")
7885 "ldda\t[%1] 0xd2, %0")
7887 (define_expand "vec_init<mode>"
7888 [(match_operand:VMALL 0 "register_operand" "")
7889 (match_operand:VMALL 1 "" "")]
7892 sparc_expand_vector_init (operands[0], operands[1]);
7896 (define_code_iterator plusminus [plus minus])
7897 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
7899 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
7901 (define_insn "<plusminus_insn><mode>3"
7902 [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
7903 (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
7904 (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
7906 "fp<plusminus_insn><vbits>\t%1, %2, %0"
7907 [(set_attr "type" "fga")
7908 (set_attr "fptype" "<vfptype>")])
7910 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7911 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
7912 (V1DI "") (V2SI "") (V4HI "") (V8QI "")])
7913 (define_code_iterator vlop [ior and xor])
7914 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
7915 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
7917 (define_insn "<code><mode>3"
7918 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7919 (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7920 (match_operand:VL 2 "register_operand" "<vconstr>")))]
7922 "f<vlinsn><vlsuf>\t%1, %2, %0"
7923 [(set_attr "type" "fga")
7924 (set_attr "fptype" "<vfptype>")])
7926 (define_insn "*not_<code><mode>3"
7927 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7928 (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7929 (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7931 "f<vlninsn><vlsuf>\t%1, %2, %0"
7932 [(set_attr "type" "fga")
7933 (set_attr "fptype" "<vfptype>")])
7935 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7936 (define_insn "*nand<mode>_vis"
7937 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7938 (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
7939 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7941 "fnand<vlsuf>\t%1, %2, %0"
7942 [(set_attr "type" "fga")
7943 (set_attr "fptype" "<vfptype>")])
7945 (define_code_iterator vlnotop [ior and])
7947 (define_insn "*<code>_not1<mode>_vis"
7948 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7949 (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
7950 (match_operand:VL 2 "register_operand" "<vconstr>")))]
7952 "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
7953 [(set_attr "type" "fga")
7954 (set_attr "fptype" "<vfptype>")])
7956 (define_insn "*<code>_not2<mode>_vis"
7957 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7958 (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7959 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7961 "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
7962 [(set_attr "type" "fga")
7963 (set_attr "fptype" "<vfptype>")])
7965 (define_insn "one_cmpl<mode>2"
7966 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7967 (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
7969 "fnot1<vlsuf>\t%1, %0"
7970 [(set_attr "type" "fga")
7971 (set_attr "fptype" "<vfptype>")])
7973 ;; Hard to generate VIS instructions. We have builtins for these.
7975 (define_insn "fpack16_vis"
7976 [(set (match_operand:V4QI 0 "register_operand" "=f")
7977 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
7982 [(set_attr "type" "fga")
7983 (set_attr "fptype" "double")])
7985 (define_insn "fpackfix_vis"
7986 [(set (match_operand:V2HI 0 "register_operand" "=f")
7987 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
7992 [(set_attr "type" "fga")
7993 (set_attr "fptype" "double")])
7995 (define_insn "fpack32_vis"
7996 [(set (match_operand:V8QI 0 "register_operand" "=e")
7997 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7998 (match_operand:V8QI 2 "register_operand" "e")
8002 "fpack32\t%1, %2, %0"
8003 [(set_attr "type" "fga")
8004 (set_attr "fptype" "double")])
8006 (define_insn "fexpand_vis"
8007 [(set (match_operand:V4HI 0 "register_operand" "=e")
8008 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8012 [(set_attr "type" "fga")
8013 (set_attr "fptype" "double")])
8015 (define_insn "fpmerge_vis"
8016 [(set (match_operand:V8QI 0 "register_operand" "=e")
8018 (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8019 (match_operand:V4QI 2 "register_operand" "f"))
8020 (parallel [(const_int 0) (const_int 4)
8021 (const_int 1) (const_int 5)
8022 (const_int 2) (const_int 6)
8023 (const_int 3) (const_int 7)])))]
8025 "fpmerge\t%1, %2, %0"
8026 [(set_attr "type" "fga")
8027 (set_attr "fptype" "double")])
8029 (define_insn "vec_interleave_lowv8qi"
8030 [(set (match_operand:V8QI 0 "register_operand" "=e")
8032 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8033 (match_operand:V8QI 2 "register_operand" "f"))
8034 (parallel [(const_int 0) (const_int 8)
8035 (const_int 1) (const_int 9)
8036 (const_int 2) (const_int 10)
8037 (const_int 3) (const_int 11)])))]
8039 "fpmerge\t%L1, %L2, %0"
8040 [(set_attr "type" "fga")
8041 (set_attr "fptype" "double")])
8043 (define_insn "vec_interleave_highv8qi"
8044 [(set (match_operand:V8QI 0 "register_operand" "=e")
8046 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8047 (match_operand:V8QI 2 "register_operand" "f"))
8048 (parallel [(const_int 4) (const_int 12)
8049 (const_int 5) (const_int 13)
8050 (const_int 6) (const_int 14)
8051 (const_int 7) (const_int 15)])))]
8053 "fpmerge\t%H1, %H2, %0"
8054 [(set_attr "type" "fga")
8055 (set_attr "fptype" "double")])
8057 ;; Partitioned multiply instructions
8058 (define_insn "fmul8x16_vis"
8059 [(set (match_operand:V4HI 0 "register_operand" "=e")
8060 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8061 (match_operand:V4HI 2 "register_operand" "e")]
8064 "fmul8x16\t%1, %2, %0"
8065 [(set_attr "type" "fpmul")
8066 (set_attr "fptype" "double")])
8068 (define_insn "fmul8x16au_vis"
8069 [(set (match_operand:V4HI 0 "register_operand" "=e")
8070 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8071 (match_operand:V2HI 2 "register_operand" "f")]
8074 "fmul8x16au\t%1, %2, %0"
8075 [(set_attr "type" "fpmul")
8076 (set_attr "fptype" "double")])
8078 (define_insn "fmul8x16al_vis"
8079 [(set (match_operand:V4HI 0 "register_operand" "=e")
8080 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8081 (match_operand:V2HI 2 "register_operand" "f")]
8084 "fmul8x16al\t%1, %2, %0"
8085 [(set_attr "type" "fpmul")
8086 (set_attr "fptype" "double")])
8088 (define_insn "fmul8sux16_vis"
8089 [(set (match_operand:V4HI 0 "register_operand" "=e")
8090 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8091 (match_operand:V4HI 2 "register_operand" "e")]
8094 "fmul8sux16\t%1, %2, %0"
8095 [(set_attr "type" "fpmul")
8096 (set_attr "fptype" "double")])
8098 (define_insn "fmul8ulx16_vis"
8099 [(set (match_operand:V4HI 0 "register_operand" "=e")
8100 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8101 (match_operand:V4HI 2 "register_operand" "e")]
8104 "fmul8ulx16\t%1, %2, %0"
8105 [(set_attr "type" "fpmul")
8106 (set_attr "fptype" "double")])
8108 (define_insn "fmuld8sux16_vis"
8109 [(set (match_operand:V2SI 0 "register_operand" "=e")
8110 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8111 (match_operand:V2HI 2 "register_operand" "f")]
8114 "fmuld8sux16\t%1, %2, %0"
8115 [(set_attr "type" "fpmul")
8116 (set_attr "fptype" "double")])
8118 (define_insn "fmuld8ulx16_vis"
8119 [(set (match_operand:V2SI 0 "register_operand" "=e")
8120 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8121 (match_operand:V2HI 2 "register_operand" "f")]
8124 "fmuld8ulx16\t%1, %2, %0"
8125 [(set_attr "type" "fpmul")
8126 (set_attr "fptype" "double")])
8128 (define_expand "wrgsr_vis"
8129 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8132 if (! TARGET_ARCH64)
8134 emit_insn (gen_wrgsr_v8plus (operands[0]));
8139 (define_insn "*wrgsr_sp64"
8140 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8141 "TARGET_VIS && TARGET_ARCH64"
8142 "wr\t%%g0, %0, %%gsr"
8143 [(set_attr "type" "gsr")])
8145 (define_insn "wrgsr_v8plus"
8146 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8147 (clobber (match_scratch:SI 1 "=X,&h"))]
8148 "TARGET_VIS && ! TARGET_ARCH64"
8150 if (GET_CODE (operands[0]) == CONST_INT
8151 || sparc_check_64 (operands[0], insn))
8152 return "wr\t%%g0, %0, %%gsr";
8154 output_asm_insn("srl\t%L0, 0, %L0", operands);
8155 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8157 [(set_attr "type" "multi")])
8159 (define_expand "rdgsr_vis"
8160 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8163 if (! TARGET_ARCH64)
8165 emit_insn (gen_rdgsr_v8plus (operands[0]));
8170 (define_insn "*rdgsr_sp64"
8171 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8172 "TARGET_VIS && TARGET_ARCH64"
8174 [(set_attr "type" "gsr")])
8176 (define_insn "rdgsr_v8plus"
8177 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8178 (clobber (match_scratch:SI 1 "=&h"))]
8179 "TARGET_VIS && ! TARGET_ARCH64"
8181 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8183 [(set_attr "type" "multi")])
8185 ;; Using faligndata only makes sense after an alignaddr since the choice of
8186 ;; bytes to take out of each operand is dependent on the results of the last
8188 (define_insn "faligndata<VM64:mode>_vis"
8189 [(set (match_operand:VM64 0 "register_operand" "=e")
8190 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8191 (match_operand:VM64 2 "register_operand" "e")
8195 "faligndata\t%1, %2, %0"
8196 [(set_attr "type" "fga")
8197 (set_attr "fptype" "double")])
8199 (define_insn "alignaddrsi_vis"
8200 [(set (match_operand:SI 0 "register_operand" "=r")
8201 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8202 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8203 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8204 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8206 "alignaddr\t%r1, %r2, %0")
8208 (define_insn "alignaddrdi_vis"
8209 [(set (match_operand:DI 0 "register_operand" "=r")
8210 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8211 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8212 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8213 (plus:DI (match_dup 1) (match_dup 2)))]
8215 "alignaddr\t%r1, %r2, %0")
8217 (define_insn "alignaddrlsi_vis"
8218 [(set (match_operand:SI 0 "register_operand" "=r")
8219 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8220 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8221 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8222 (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8225 "alignaddrl\t%r1, %r2, %0")
8227 (define_insn "alignaddrldi_vis"
8228 [(set (match_operand:DI 0 "register_operand" "=r")
8229 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8230 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8231 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8232 (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8235 "alignaddrl\t%r1, %r2, %0")
8237 (define_insn "pdist_vis"
8238 [(set (match_operand:DI 0 "register_operand" "=e")
8239 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8240 (match_operand:V8QI 2 "register_operand" "e")
8241 (match_operand:DI 3 "register_operand" "0")]
8245 [(set_attr "type" "fga")
8246 (set_attr "fptype" "double")])
8248 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8249 ;; with the same operands.
8250 (define_insn "edge8<P:mode>_vis"
8251 [(set (reg:CC_NOOV CC_REG)
8252 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8253 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8255 (set (match_operand:P 0 "register_operand" "=r")
8256 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8258 "edge8\t%r1, %r2, %0"
8259 [(set_attr "type" "edge")])
8261 (define_insn "edge8l<P:mode>_vis"
8262 [(set (reg:CC_NOOV CC_REG)
8263 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8264 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8266 (set (match_operand:P 0 "register_operand" "=r")
8267 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8269 "edge8l\t%r1, %r2, %0"
8270 [(set_attr "type" "edge")])
8272 (define_insn "edge16<P:mode>_vis"
8273 [(set (reg:CC_NOOV CC_REG)
8274 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8275 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8277 (set (match_operand:P 0 "register_operand" "=r")
8278 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8280 "edge16\t%r1, %r2, %0"
8281 [(set_attr "type" "edge")])
8283 (define_insn "edge16l<P:mode>_vis"
8284 [(set (reg:CC_NOOV CC_REG)
8285 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8286 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8288 (set (match_operand:P 0 "register_operand" "=r")
8289 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8291 "edge16l\t%r1, %r2, %0"
8292 [(set_attr "type" "edge")])
8294 (define_insn "edge32<P:mode>_vis"
8295 [(set (reg:CC_NOOV CC_REG)
8296 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8297 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8299 (set (match_operand:P 0 "register_operand" "=r")
8300 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8302 "edge32\t%r1, %r2, %0"
8303 [(set_attr "type" "edge")])
8305 (define_insn "edge32l<P:mode>_vis"
8306 [(set (reg:CC_NOOV CC_REG)
8307 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8308 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8310 (set (match_operand:P 0 "register_operand" "=r")
8311 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8313 "edge32l\t%r1, %r2, %0"
8314 [(set_attr "type" "edge")])
8316 (define_code_iterator gcond [le ne gt eq])
8317 (define_mode_iterator GCM [V4HI V2SI])
8318 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8320 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8321 [(set (match_operand:P 0 "register_operand" "=r")
8322 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8323 (match_operand:GCM 2 "register_operand" "e"))]
8326 "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8327 [(set_attr "type" "fpmul")
8328 (set_attr "fptype" "double")])
8330 (define_expand "vcond<mode><mode>"
8331 [(match_operand:GCM 0 "register_operand" "")
8332 (match_operand:GCM 1 "register_operand" "")
8333 (match_operand:GCM 2 "register_operand" "")
8334 (match_operator 3 ""
8335 [(match_operand:GCM 4 "register_operand" "")
8336 (match_operand:GCM 5 "register_operand" "")])]
8339 sparc_expand_vcond (<MODE>mode, operands,
8340 UNSPEC_CMASK<gcm_name>,
8345 (define_expand "vconduv8qiv8qi"
8346 [(match_operand:V8QI 0 "register_operand" "")
8347 (match_operand:V8QI 1 "register_operand" "")
8348 (match_operand:V8QI 2 "register_operand" "")
8349 (match_operator 3 ""
8350 [(match_operand:V8QI 4 "register_operand" "")
8351 (match_operand:V8QI 5 "register_operand" "")])]
8354 sparc_expand_vcond (V8QImode, operands,
8360 (define_insn "array8<P:mode>_vis"
8361 [(set (match_operand:P 0 "register_operand" "=r")
8362 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8363 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8366 "array8\t%r1, %r2, %0"
8367 [(set_attr "type" "array")])
8369 (define_insn "array16<P:mode>_vis"
8370 [(set (match_operand:P 0 "register_operand" "=r")
8371 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8372 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8375 "array16\t%r1, %r2, %0"
8376 [(set_attr "type" "array")])
8378 (define_insn "array32<P:mode>_vis"
8379 [(set (match_operand:P 0 "register_operand" "=r")
8380 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8381 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8384 "array32\t%r1, %r2, %0"
8385 [(set_attr "type" "array")])
8387 (define_insn "bmaskdi_vis"
8388 [(set (match_operand:DI 0 "register_operand" "=r")
8389 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8390 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8391 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8392 (plus:DI (match_dup 1) (match_dup 2)))]
8394 "bmask\t%r1, %r2, %0"
8395 [(set_attr "type" "array")])
8397 (define_insn "bmasksi_vis"
8398 [(set (match_operand:SI 0 "register_operand" "=r")
8399 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8400 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8401 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8402 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8404 "bmask\t%r1, %r2, %0"
8405 [(set_attr "type" "array")])
8407 (define_insn "bshuffle<VM64:mode>_vis"
8408 [(set (match_operand:VM64 0 "register_operand" "=e")
8409 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8410 (match_operand:VM64 2 "register_operand" "e")
8414 "bshuffle\t%1, %2, %0"
8415 [(set_attr "type" "fga")
8416 (set_attr "fptype" "double")])
8418 ;; The rtl expanders will happily convert constant permutations on other
8419 ;; modes down to V8QI. Rely on this to avoid the complexity of the byte
8420 ;; order of the permutation.
8421 (define_expand "vec_perm_constv8qi"
8422 [(match_operand:V8QI 0 "register_operand" "")
8423 (match_operand:V8QI 1 "register_operand" "")
8424 (match_operand:V8QI 2 "register_operand" "")
8425 (match_operand:V8QI 3 "" "")]
8428 unsigned int i, mask;
8429 rtx sel = operands[3];
8431 for (i = mask = 0; i < 8; ++i)
8432 mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8433 sel = force_reg (SImode, gen_int_mode (mask, SImode));
8435 emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, const0_rtx));
8436 emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8440 ;; Unlike constant permutation, we can vastly simplify the compression of
8441 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8442 ;; width of the input is.
8443 (define_expand "vec_perm<mode>"
8444 [(match_operand:VM64 0 "register_operand" "")
8445 (match_operand:VM64 1 "register_operand" "")
8446 (match_operand:VM64 2 "register_operand" "")
8447 (match_operand:VM64 3 "register_operand" "")]
8450 sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8451 emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8455 ;; VIS 2.0 adds edge variants which do not set the condition codes
8456 (define_insn "edge8n<P:mode>_vis"
8457 [(set (match_operand:P 0 "register_operand" "=r")
8458 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8459 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8462 "edge8n\t%r1, %r2, %0"
8463 [(set_attr "type" "edgen")])
8465 (define_insn "edge8ln<P:mode>_vis"
8466 [(set (match_operand:P 0 "register_operand" "=r")
8467 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8468 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8471 "edge8ln\t%r1, %r2, %0"
8472 [(set_attr "type" "edgen")])
8474 (define_insn "edge16n<P:mode>_vis"
8475 [(set (match_operand:P 0 "register_operand" "=r")
8476 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8477 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8480 "edge16n\t%r1, %r2, %0"
8481 [(set_attr "type" "edgen")])
8483 (define_insn "edge16ln<P:mode>_vis"
8484 [(set (match_operand:P 0 "register_operand" "=r")
8485 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8486 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8489 "edge16ln\t%r1, %r2, %0"
8490 [(set_attr "type" "edgen")])
8492 (define_insn "edge32n<P:mode>_vis"
8493 [(set (match_operand:P 0 "register_operand" "=r")
8494 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8495 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8498 "edge32n\t%r1, %r2, %0"
8499 [(set_attr "type" "edgen")])
8501 (define_insn "edge32ln<P:mode>_vis"
8502 [(set (match_operand:P 0 "register_operand" "=r")
8503 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8504 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8507 "edge32ln\t%r1, %r2, %0"
8508 [(set_attr "type" "edge")])
8510 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8511 (define_insn "cmask8<P:mode>_vis"
8512 [(set (reg:DI GSR_REG)
8513 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8519 (define_insn "cmask16<P:mode>_vis"
8520 [(set (reg:DI GSR_REG)
8521 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8527 (define_insn "cmask32<P:mode>_vis"
8528 [(set (reg:DI GSR_REG)
8529 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8535 (define_insn "fchksm16_vis"
8536 [(set (match_operand:V4HI 0 "register_operand" "=e")
8537 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8538 (match_operand:V4HI 2 "register_operand" "e")]
8541 "fchksm16\t%1, %2, %0")
8543 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8544 (define_code_attr vis3_shift_insn
8545 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8546 (define_code_attr vis3_shift_patname
8547 [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8549 (define_insn "v<vis3_shift_patname><mode>3"
8550 [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8551 (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8552 (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8554 "<vis3_shift_insn><vbits>\t%1, %2, %0")
8556 (define_insn "pdistn<mode>_vis"
8557 [(set (match_operand:P 0 "register_operand" "=r")
8558 (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8559 (match_operand:V8QI 2 "register_operand" "e")]
8562 "pdistn\t%1, %2, %0")
8564 (define_insn "fmean16_vis"
8565 [(set (match_operand:V4HI 0 "register_operand" "=e")
8571 (match_operand:V4HI 1 "register_operand" "e"))
8573 (match_operand:V4HI 2 "register_operand" "e")))
8574 (const_vector:V4SI [(const_int 1) (const_int 1)
8575 (const_int 1) (const_int 1)]))
8578 "fmean16\t%1, %2, %0")
8580 (define_insn "fp<plusminus_insn>64_vis"
8581 [(set (match_operand:V1DI 0 "register_operand" "=e")
8582 (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8583 (match_operand:V1DI 2 "register_operand" "e")))]
8585 "fp<plusminus_insn>64\t%1, %2, %0")
8587 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8588 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8589 (define_code_attr vis3_addsub_ss_insn
8590 [(ss_plus "fpadds") (ss_minus "fpsubs")])
8591 (define_code_attr vis3_addsub_ss_patname
8592 [(ss_plus "ssadd") (ss_minus "sssub")])
8594 (define_insn "<vis3_addsub_ss_patname><mode>3"
8595 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8596 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8597 (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8599 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0")
8601 (define_insn "fucmp<code>8<P:mode>_vis"
8602 [(set (match_operand:P 0 "register_operand" "=r")
8603 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8604 (match_operand:V8QI 2 "register_operand" "e"))]
8607 "fucmp<code>8\t%1, %2, %0")
8609 (define_insn "*naddsf3"
8610 [(set (match_operand:SF 0 "register_operand" "=f")
8611 (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8612 (match_operand:SF 2 "register_operand" "f"))))]
8614 "fnadds\t%1, %2, %0"
8615 [(set_attr "type" "fp")])
8617 (define_insn "*nadddf3"
8618 [(set (match_operand:DF 0 "register_operand" "=e")
8619 (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8620 (match_operand:DF 2 "register_operand" "e"))))]
8622 "fnaddd\t%1, %2, %0"
8623 [(set_attr "type" "fp")
8624 (set_attr "fptype" "double")])
8626 (define_insn "*nmulsf3"
8627 [(set (match_operand:SF 0 "register_operand" "=f")
8628 (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8629 (match_operand:SF 2 "register_operand" "f")))]
8631 "fnmuls\t%1, %2, %0"
8632 [(set_attr "type" "fpmul")])
8634 (define_insn "*nmuldf3"
8635 [(set (match_operand:DF 0 "register_operand" "=e")
8636 (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8637 (match_operand:DF 2 "register_operand" "e")))]
8639 "fnmuld\t%1, %2, %0"
8640 [(set_attr "type" "fpmul")
8641 (set_attr "fptype" "double")])
8643 (define_insn "*nmuldf3_extend"
8644 [(set (match_operand:DF 0 "register_operand" "=e")
8645 (mult:DF (neg:DF (float_extend:DF
8646 (match_operand:SF 1 "register_operand" "f")))
8648 (match_operand:SF 2 "register_operand" "f"))))]
8650 "fnsmuld\t%1, %2, %0"
8651 [(set_attr "type" "fpmul")
8652 (set_attr "fptype" "double")])
8654 (define_insn "fhaddsf_vis"
8655 [(set (match_operand:SF 0 "register_operand" "=f")
8656 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8657 (match_operand:SF 2 "register_operand" "f")]
8660 "fhadds\t%1, %2, %0"
8661 [(set_attr "type" "fp")])
8663 (define_insn "fhadddf_vis"
8664 [(set (match_operand:DF 0 "register_operand" "=f")
8665 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8666 (match_operand:DF 2 "register_operand" "f")]
8669 "fhaddd\t%1, %2, %0"
8670 [(set_attr "type" "fp")
8671 (set_attr "fptype" "double")])
8673 (define_insn "fhsubsf_vis"
8674 [(set (match_operand:SF 0 "register_operand" "=f")
8675 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8676 (match_operand:SF 2 "register_operand" "f")]
8679 "fhsubs\t%1, %2, %0"
8680 [(set_attr "type" "fp")])
8682 (define_insn "fhsubdf_vis"
8683 [(set (match_operand:DF 0 "register_operand" "=f")
8684 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8685 (match_operand:DF 2 "register_operand" "f")]
8688 "fhsubd\t%1, %2, %0"
8689 [(set_attr "type" "fp")
8690 (set_attr "fptype" "double")])
8692 (define_insn "fnhaddsf_vis"
8693 [(set (match_operand:SF 0 "register_operand" "=f")
8694 (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8695 (match_operand:SF 2 "register_operand" "f")]
8698 "fnhadds\t%1, %2, %0"
8699 [(set_attr "type" "fp")])
8701 (define_insn "fnhadddf_vis"
8702 [(set (match_operand:DF 0 "register_operand" "=f")
8703 (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8704 (match_operand:DF 2 "register_operand" "f")]
8707 "fnhaddd\t%1, %2, %0"
8708 [(set_attr "type" "fp")
8709 (set_attr "fptype" "double")])
8711 (define_expand "umulxhi_vis"
8712 [(set (match_operand:DI 0 "register_operand" "")
8715 (mult:TI (zero_extend:TI
8716 (match_operand:DI 1 "arith_operand" ""))
8718 (match_operand:DI 2 "arith_operand" "")))
8722 if (! TARGET_ARCH64)
8724 emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8729 (define_insn "*umulxhi_sp64"
8730 [(set (match_operand:DI 0 "register_operand" "=r")
8733 (mult:TI (zero_extend:TI
8734 (match_operand:DI 1 "arith_operand" "%r"))
8736 (match_operand:DI 2 "arith_operand" "rI")))
8738 "TARGET_VIS3 && TARGET_ARCH64"
8739 "umulxhi\t%1, %2, %0"
8740 [(set_attr "type" "imul")])
8742 (define_insn "umulxhi_v8plus"
8743 [(set (match_operand:DI 0 "register_operand" "=r,h")
8746 (mult:TI (zero_extend:TI
8747 (match_operand:DI 1 "arith_operand" "%r,0"))
8749 (match_operand:DI 2 "arith_operand" "rI,rI")))
8751 (clobber (match_scratch:SI 3 "=&h,X"))
8752 (clobber (match_scratch:SI 4 "=&h,X"))]
8753 "TARGET_VIS3 && ! TARGET_ARCH64"
8754 "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8755 [(set_attr "type" "imul")
8756 (set_attr "length" "9,8")])
8758 (define_expand "xmulx_vis"
8759 [(set (match_operand:DI 0 "register_operand" "")
8761 (unspec:TI [(zero_extend:TI
8762 (match_operand:DI 1 "arith_operand" ""))
8764 (match_operand:DI 2 "arith_operand" ""))]
8768 if (! TARGET_ARCH64)
8770 emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8775 (define_insn "*xmulx_sp64"
8776 [(set (match_operand:DI 0 "register_operand" "=r")
8778 (unspec:TI [(zero_extend:TI
8779 (match_operand:DI 1 "arith_operand" "%r"))
8781 (match_operand:DI 2 "arith_operand" "rI"))]
8783 "TARGET_VIS3 && TARGET_ARCH64"
8785 [(set_attr "type" "imul")])
8787 (define_insn "xmulx_v8plus"
8788 [(set (match_operand:DI 0 "register_operand" "=r,h")
8790 (unspec:TI [(zero_extend:TI
8791 (match_operand:DI 1 "arith_operand" "%r,0"))
8793 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8795 (clobber (match_scratch:SI 3 "=&h,X"))
8796 (clobber (match_scratch:SI 4 "=&h,X"))]
8797 "TARGET_VIS3 && ! TARGET_ARCH64"
8798 "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8799 [(set_attr "type" "imul")
8800 (set_attr "length" "9,8")])
8802 (define_expand "xmulxhi_vis"
8803 [(set (match_operand:DI 0 "register_operand" "")
8806 (unspec:TI [(zero_extend:TI
8807 (match_operand:DI 1 "arith_operand" ""))
8809 (match_operand:DI 2 "arith_operand" ""))]
8814 if (! TARGET_ARCH64)
8816 emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
8821 (define_insn "*xmulxhi_sp64"
8822 [(set (match_operand:DI 0 "register_operand" "=r")
8825 (unspec:TI [(zero_extend:TI
8826 (match_operand:DI 1 "arith_operand" "%r"))
8828 (match_operand:DI 2 "arith_operand" "rI"))]
8831 "TARGET_VIS3 && TARGET_ARCH64"
8832 "xmulxhi\t%1, %2, %0"
8833 [(set_attr "type" "imul")])
8835 (define_insn "xmulxhi_v8plus"
8836 [(set (match_operand:DI 0 "register_operand" "=r,h")
8839 (unspec:TI [(zero_extend:TI
8840 (match_operand:DI 1 "arith_operand" "%r,0"))
8842 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8845 (clobber (match_scratch:SI 3 "=&h,X"))
8846 (clobber (match_scratch:SI 4 "=&h,X"))]
8847 "TARGET_VIS3 && !TARGET_ARCH64"
8848 "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
8849 [(set_attr "type" "imul")
8850 (set_attr "length" "9,8")])