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_FRAME_BLOCKAGE 3)
32 (UNSPEC_MOVE_PIC_LABEL 5)
38 (UNSPEC_EMB_TEXTUHI 13)
39 (UNSPEC_EMB_TEXTHI 14)
40 (UNSPEC_EMB_TEXTULO 15)
42 (UNSPEC_MOVE_GOTDATA 19)
52 (UNSPEC_TLSLD_BASE 35)
100 [(UNSPECV_BLOCKAGE 0)
107 (UNSPECV_PROBE_STACK_RANGE 11)
200 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
201 (define_mode_iterator I [QI HI SI DI])
202 (define_mode_iterator F [SF DF TF])
204 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
205 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
206 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
207 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
208 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
210 ;; Attribute for cpu type.
211 ;; These must match the values for enum processor_type in sparc.h.
232 (const (symbol_ref "sparc_cpu_attr")))
234 ;; Attribute for the instruction set.
235 ;; At present we only need to distinguish v9/!v9, but for clarity we
236 ;; test TARGET_V8 too.
237 (define_attr "isa" "v7,v8,v9,sparclet"
239 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
240 (symbol_ref "TARGET_V8") (const_string "v8")
241 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
242 (const_string "v7"))))
244 (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3" (const_string "none"))
246 (define_attr "enabled" ""
247 (cond [(eq_attr "cpu_feature" "none") (const_int 1)
248 (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU")
249 (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && ! TARGET_V9")
250 (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9")
251 (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS")
252 (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")]
259 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
260 cbcond,uncond_cbcond,
268 fga,visl,vismv,fgm_pack,fgm_mul,pdist,pdistn,edge,edgen,gsr,array,
271 multi,savew,flushw,iflush,trap"
272 (const_string "ialu"))
274 ;; True if branch/call has empty delay slot and will emit a nop in it
275 (define_attr "empty_delay_slot" "false,true"
276 (symbol_ref "(empty_delay_slot (insn)
277 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
279 ;; True if we are making use of compare-and-branch instructions.
280 ;; True if we should emit a nop after a cbcond instruction
281 (define_attr "emit_cbcond_nop" "false,true"
282 (symbol_ref "(emit_cbcond_nop (insn)
283 ? EMIT_CBCOND_NOP_TRUE : EMIT_CBCOND_NOP_FALSE)"))
285 (define_attr "branch_type" "none,icc,fcc,reg"
286 (const_string "none"))
288 (define_attr "pic" "false,true"
289 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
291 (define_attr "calls_alloca" "false,true"
292 (symbol_ref "(cfun->calls_alloca != 0
293 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
295 (define_attr "calls_eh_return" "false,true"
296 (symbol_ref "(crtl->calls_eh_return != 0
297 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
299 (define_attr "leaf_function" "false,true"
300 (symbol_ref "(crtl->uses_only_leaf_regs != 0
301 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
303 (define_attr "delayed_branch" "false,true"
304 (symbol_ref "(flag_delayed_branch != 0
305 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
307 (define_attr "flat" "false,true"
308 (symbol_ref "(TARGET_FLAT != 0
309 ? FLAT_TRUE : FLAT_FALSE)"))
311 ;; Length (in # of insns).
312 ;; Beware that setting a length greater or equal to 3 for conditional branches
313 ;; has a side-effect (see output_cbranch and output_v9branch).
314 (define_attr "length" ""
315 (cond [(eq_attr "type" "uncond_branch,call")
316 (if_then_else (eq_attr "empty_delay_slot" "true")
319 (eq_attr "type" "sibcall")
320 (if_then_else (eq_attr "leaf_function" "true")
321 (if_then_else (eq_attr "empty_delay_slot" "true")
324 (if_then_else (eq_attr "empty_delay_slot" "true")
327 (eq_attr "branch_type" "icc")
328 (if_then_else (match_operand 0 "noov_compare64_operator" "")
329 (if_then_else (lt (pc) (match_dup 1))
330 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
331 (if_then_else (eq_attr "empty_delay_slot" "true")
334 (if_then_else (eq_attr "empty_delay_slot" "true")
337 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
338 (if_then_else (eq_attr "empty_delay_slot" "true")
341 (if_then_else (eq_attr "empty_delay_slot" "true")
344 (if_then_else (eq_attr "empty_delay_slot" "true")
347 (eq_attr "branch_type" "fcc")
348 (if_then_else (match_operand 0 "fcc0_register_operand" "")
349 (if_then_else (eq_attr "empty_delay_slot" "true")
350 (if_then_else (not (match_test "TARGET_V9"))
353 (if_then_else (not (match_test "TARGET_V9"))
356 (if_then_else (lt (pc) (match_dup 2))
357 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
358 (if_then_else (eq_attr "empty_delay_slot" "true")
361 (if_then_else (eq_attr "empty_delay_slot" "true")
364 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
365 (if_then_else (eq_attr "empty_delay_slot" "true")
368 (if_then_else (eq_attr "empty_delay_slot" "true")
371 (eq_attr "branch_type" "reg")
372 (if_then_else (lt (pc) (match_dup 2))
373 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
374 (if_then_else (eq_attr "empty_delay_slot" "true")
377 (if_then_else (eq_attr "empty_delay_slot" "true")
380 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
381 (if_then_else (eq_attr "empty_delay_slot" "true")
384 (if_then_else (eq_attr "empty_delay_slot" "true")
387 (eq_attr "type" "cbcond")
388 (if_then_else (lt (pc) (match_dup 3))
389 (if_then_else (lt (minus (match_dup 3) (pc)) (const_int 500))
390 (if_then_else (eq_attr "emit_cbcond_nop" "true")
394 (if_then_else (lt (minus (pc) (match_dup 3)) (const_int 500))
395 (if_then_else (eq_attr "emit_cbcond_nop" "true")
399 (eq_attr "type" "uncond_cbcond")
400 (if_then_else (lt (pc) (match_dup 0))
401 (if_then_else (lt (minus (match_dup 0) (pc)) (const_int 500))
402 (if_then_else (eq_attr "emit_cbcond_nop" "true")
406 (if_then_else (lt (minus (pc) (match_dup 0)) (const_int 500))
407 (if_then_else (eq_attr "emit_cbcond_nop" "true")
414 (define_attr "fptype" "single,double"
415 (const_string "single"))
417 ;; UltraSPARC-III integer load type.
418 (define_attr "us3load_type" "2cycle,3cycle"
419 (const_string "2cycle"))
421 (define_asm_attributes
422 [(set_attr "length" "2")
423 (set_attr "type" "multi")])
425 ;; Attributes for instruction and branch scheduling
426 (define_attr "tls_call_delay" "false,true"
427 (symbol_ref "(tls_call_delay (insn)
428 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
430 (define_attr "in_call_delay" "false,true"
431 (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
432 (const_string "false")
433 (eq_attr "type" "load,fpload,store,fpstore")
434 (if_then_else (eq_attr "length" "1")
435 (const_string "true")
436 (const_string "false"))]
437 (if_then_else (and (eq_attr "length" "1")
438 (eq_attr "tls_call_delay" "true"))
439 (const_string "true")
440 (const_string "false"))))
442 (define_attr "eligible_for_sibcall_delay" "false,true"
443 (symbol_ref "(eligible_for_sibcall_delay (insn)
444 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
445 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
447 (define_attr "eligible_for_return_delay" "false,true"
448 (symbol_ref "(eligible_for_return_delay (insn)
449 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
450 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
452 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
453 ;; branches. This would allow us to remove the nop always inserted before
454 ;; a floating point branch.
456 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
457 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
458 ;; This is because doing so will add several pipeline stalls to the path
459 ;; that the load/store did not come from. Unfortunately, there is no way
460 ;; to prevent fill_eager_delay_slots from using load/store without completely
461 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
462 ;; because it prevents us from moving back the final store of inner loops.
464 (define_attr "in_branch_delay" "false,true"
465 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
466 (eq_attr "length" "1"))
467 (const_string "true")
468 (const_string "false")))
470 (define_attr "in_uncond_branch_delay" "false,true"
471 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
472 (eq_attr "length" "1"))
473 (const_string "true")
474 (const_string "false")))
476 (define_attr "in_annul_branch_delay" "false,true"
477 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
478 (eq_attr "length" "1"))
479 (const_string "true")
480 (const_string "false")))
482 (define_delay (eq_attr "type" "call")
483 [(eq_attr "in_call_delay" "true") (nil) (nil)])
485 (define_delay (eq_attr "type" "sibcall")
486 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
488 (define_delay (eq_attr "type" "branch")
489 [(eq_attr "in_branch_delay" "true")
490 (nil) (eq_attr "in_annul_branch_delay" "true")])
492 (define_delay (eq_attr "type" "uncond_branch")
493 [(eq_attr "in_uncond_branch_delay" "true")
496 (define_delay (eq_attr "type" "return")
497 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
500 ;; Include SPARC DFA schedulers
502 (include "cypress.md")
503 (include "supersparc.md")
504 (include "hypersparc.md")
506 (include "sparclet.md")
507 (include "ultra1_2.md")
508 (include "ultra3.md")
509 (include "niagara.md")
510 (include "niagara2.md")
511 (include "niagara4.md")
514 ;; Operand and operator predicates and constraints
516 (include "predicates.md")
517 (include "constraints.md")
520 ;; Compare instructions.
522 ;; These are just the DEFINE_INSNs to match the patterns and the
523 ;; DEFINE_SPLITs for some of the scc insns that actually require
524 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
526 ;; The compare DEFINE_INSNs.
528 (define_insn "*cmpsi_insn"
529 [(set (reg:CC CC_REG)
530 (compare:CC (match_operand:SI 0 "register_operand" "r")
531 (match_operand:SI 1 "arith_operand" "rI")))]
534 [(set_attr "type" "compare")])
536 (define_insn "*cmpdi_sp64"
537 [(set (reg:CCX CC_REG)
538 (compare:CCX (match_operand:DI 0 "register_operand" "r")
539 (match_operand:DI 1 "arith_operand" "rI")))]
542 [(set_attr "type" "compare")])
544 (define_insn "*cmpsf_fpe"
545 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
546 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
547 (match_operand:SF 2 "register_operand" "f")))]
551 return "fcmpes\t%0, %1, %2";
552 return "fcmpes\t%1, %2";
554 [(set_attr "type" "fpcmp")])
556 (define_insn "*cmpdf_fpe"
557 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
558 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
559 (match_operand:DF 2 "register_operand" "e")))]
563 return "fcmped\t%0, %1, %2";
564 return "fcmped\t%1, %2";
566 [(set_attr "type" "fpcmp")
567 (set_attr "fptype" "double")])
569 (define_insn "*cmptf_fpe"
570 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
571 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
572 (match_operand:TF 2 "register_operand" "e")))]
573 "TARGET_FPU && TARGET_HARD_QUAD"
576 return "fcmpeq\t%0, %1, %2";
577 return "fcmpeq\t%1, %2";
579 [(set_attr "type" "fpcmp")])
581 (define_insn "*cmpsf_fp"
582 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
583 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
584 (match_operand:SF 2 "register_operand" "f")))]
588 return "fcmps\t%0, %1, %2";
589 return "fcmps\t%1, %2";
591 [(set_attr "type" "fpcmp")])
593 (define_insn "*cmpdf_fp"
594 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
595 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
596 (match_operand:DF 2 "register_operand" "e")))]
600 return "fcmpd\t%0, %1, %2";
601 return "fcmpd\t%1, %2";
603 [(set_attr "type" "fpcmp")
604 (set_attr "fptype" "double")])
606 (define_insn "*cmptf_fp"
607 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
608 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
609 (match_operand:TF 2 "register_operand" "e")))]
610 "TARGET_FPU && TARGET_HARD_QUAD"
613 return "fcmpq\t%0, %1, %2";
614 return "fcmpq\t%1, %2";
616 [(set_attr "type" "fpcmp")])
618 ;; Next come the scc insns.
620 (define_expand "cstoresi4"
621 [(use (match_operator 1 "comparison_operator"
622 [(match_operand:SI 2 "compare_operand" "")
623 (match_operand:SI 3 "arith_operand" "")]))
624 (clobber (match_operand:SI 0 "register_operand"))]
627 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
628 operands[2] = force_reg (SImode, operands[2]);
629 if (emit_scc_insn (operands)) DONE; else FAIL;
632 (define_expand "cstoredi4"
633 [(use (match_operator 1 "comparison_operator"
634 [(match_operand:DI 2 "compare_operand" "")
635 (match_operand:DI 3 "arith_operand" "")]))
636 (clobber (match_operand:SI 0 "register_operand"))]
639 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
640 operands[2] = force_reg (DImode, operands[2]);
641 if (emit_scc_insn (operands)) DONE; else FAIL;
644 (define_expand "cstore<F:mode>4"
645 [(use (match_operator 1 "comparison_operator"
646 [(match_operand:F 2 "register_operand" "")
647 (match_operand:F 3 "register_operand" "")]))
648 (clobber (match_operand:SI 0 "register_operand"))]
650 { if (emit_scc_insn (operands)) DONE; else FAIL; })
654 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
655 ;; generate addcc/subcc instructions.
657 (define_expand "seqsi_special"
659 (xor:SI (match_operand:SI 1 "register_operand" "")
660 (match_operand:SI 2 "register_operand" "")))
661 (parallel [(set (match_operand:SI 0 "register_operand" "")
662 (eq:SI (match_dup 3) (const_int 0)))
663 (clobber (reg:CC CC_REG))])]
665 { operands[3] = gen_reg_rtx (SImode); })
667 (define_expand "seqdi_special"
669 (xor:DI (match_operand:DI 1 "register_operand" "")
670 (match_operand:DI 2 "register_operand" "")))
671 (set (match_operand:SI 0 "register_operand" "")
672 (eq:SI (match_dup 3) (const_int 0)))]
674 { operands[3] = gen_reg_rtx (DImode); })
676 (define_expand "snesi_special"
678 (xor:SI (match_operand:SI 1 "register_operand" "")
679 (match_operand:SI 2 "register_operand" "")))
680 (parallel [(set (match_operand:SI 0 "register_operand" "")
681 (ne:SI (match_dup 3) (const_int 0)))
682 (clobber (reg:CC CC_REG))])]
684 { operands[3] = gen_reg_rtx (SImode); })
686 (define_expand "snedi_special"
688 (xor:DI (match_operand:DI 1 "register_operand" "")
689 (match_operand:DI 2 "register_operand" "")))
690 (set (match_operand:SI 0 "register_operand" "")
691 (ne:SI (match_dup 3) (const_int 0)))]
692 "TARGET_ARCH64 && ! TARGET_VIS3"
693 { operands[3] = gen_reg_rtx (DImode); })
695 (define_expand "snedi_special_vis3"
697 (xor:DI (match_operand:DI 1 "register_operand" "")
698 (match_operand:DI 2 "register_operand" "")))
699 (parallel [(set (match_operand:SI 0 "register_operand" "")
700 (ne:SI (match_dup 3) (const_int 0)))
701 (clobber (reg:CCX CC_REG))])]
702 "TARGET_ARCH64 && TARGET_VIS3"
703 { operands[3] = gen_reg_rtx (DImode); })
706 ;; Now the DEFINE_INSNs for the scc cases.
708 ;; The SEQ and SNE patterns are special because they can be done
709 ;; without any branching and do not involve a COMPARE. We want
710 ;; them to always use the splits below so the results can be
713 (define_insn_and_split "*snesi_zero"
714 [(set (match_operand:SI 0 "register_operand" "=r")
715 (ne:SI (match_operand:SI 1 "register_operand" "r")
717 (clobber (reg:CC CC_REG))]
721 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
723 (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
725 [(set_attr "length" "2")])
727 (define_insn_and_split "*neg_snesi_zero"
728 [(set (match_operand:SI 0 "register_operand" "=r")
729 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
731 (clobber (reg:CC CC_REG))]
735 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
737 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
739 [(set_attr "length" "2")])
741 (define_insn_and_split "*snesi_zero_extend"
742 [(set (match_operand:DI 0 "register_operand" "=r")
743 (ne:DI (match_operand:SI 1 "register_operand" "r")
745 (clobber (reg:CC CC_REG))]
749 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
752 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
754 (ltu:SI (reg:CC_NOOV CC_REG)
757 [(set_attr "length" "2")])
759 (define_insn_and_split "*neg_snesi_sign_extend"
760 [(set (match_operand:DI 0 "register_operand" "=r")
761 (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r")
763 (clobber (reg:CC CC_REG))]
767 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
770 (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG)
773 [(set_attr "length" "2")])
775 (define_insn_and_split "*snedi_zero"
776 [(set (match_operand:DI 0 "register_operand" "=&r")
777 (ne:DI (match_operand:DI 1 "register_operand" "r")
779 "TARGET_ARCH64 && ! TARGET_VIS3"
781 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
782 [(set (match_dup 0) (const_int 0))
783 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
788 [(set_attr "length" "2")])
790 (define_insn_and_split "*snedi_zero_vis3"
791 [(set (match_operand:DI 0 "register_operand" "=r")
792 (ne:DI (match_operand:DI 1 "register_operand" "r")
794 (clobber (reg:CCX CC_REG))]
795 "TARGET_ARCH64 && TARGET_VIS3"
798 [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
800 (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
802 [(set_attr "length" "2")])
804 (define_insn_and_split "*neg_snedi_zero"
805 [(set (match_operand:DI 0 "register_operand" "=&r")
806 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
810 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
811 [(set (match_dup 0) (const_int 0))
812 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
817 [(set_attr "length" "2")])
819 (define_insn_and_split "*snedi_zero_trunc"
820 [(set (match_operand:SI 0 "register_operand" "=&r")
821 (ne:SI (match_operand:DI 1 "register_operand" "r")
823 "TARGET_ARCH64 && ! TARGET_VIS3"
825 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
826 [(set (match_dup 0) (const_int 0))
827 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
832 [(set_attr "length" "2")])
834 (define_insn_and_split "*snedi_zero_trunc_vis3"
835 [(set (match_operand:SI 0 "register_operand" "=r")
836 (ne:SI (match_operand:DI 1 "register_operand" "r")
838 (clobber (reg:CCX CC_REG))]
839 "TARGET_ARCH64 && TARGET_VIS3"
842 [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
844 (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
846 [(set_attr "length" "2")])
848 (define_insn_and_split "*seqsi_zero"
849 [(set (match_operand:SI 0 "register_operand" "=r")
850 (eq:SI (match_operand:SI 1 "register_operand" "r")
852 (clobber (reg:CC CC_REG))]
856 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
858 (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
860 [(set_attr "length" "2")])
862 (define_insn_and_split "*neg_seqsi_zero"
863 [(set (match_operand:SI 0 "register_operand" "=r")
864 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
866 (clobber (reg:CC CC_REG))]
870 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
872 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
874 [(set_attr "length" "2")])
876 (define_insn_and_split "*seqsi_zero_extend"
877 [(set (match_operand:DI 0 "register_operand" "=r")
878 (eq:DI (match_operand:SI 1 "register_operand" "r")
880 (clobber (reg:CC CC_REG))]
884 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
887 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
889 (ltu:SI (reg:CC_NOOV CC_REG)
892 [(set_attr "length" "2")])
894 (define_insn_and_split "*neg_seqsi_sign_extend"
895 [(set (match_operand:DI 0 "register_operand" "=r")
896 (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r")
898 (clobber (reg:CC CC_REG))]
902 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
904 (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG)
907 [(set_attr "length" "2")])
909 (define_insn_and_split "*seqdi_zero"
910 [(set (match_operand:DI 0 "register_operand" "=&r")
911 (eq:DI (match_operand:DI 1 "register_operand" "r")
915 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
916 [(set (match_dup 0) (const_int 0))
917 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
922 [(set_attr "length" "2")])
924 (define_insn_and_split "*neg_seqdi_zero"
925 [(set (match_operand:DI 0 "register_operand" "=&r")
926 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
930 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
931 [(set (match_dup 0) (const_int 0))
932 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
937 [(set_attr "length" "2")])
939 (define_insn_and_split "*seqdi_zero_trunc"
940 [(set (match_operand:SI 0 "register_operand" "=&r")
941 (eq:SI (match_operand:DI 1 "register_operand" "r")
945 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
946 [(set (match_dup 0) (const_int 0))
947 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
952 [(set_attr "length" "2")])
954 ;; We can also do (x + (i == 0)) and related, so put them in.
955 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
958 (define_insn_and_split "*x_plus_i_ne_0"
959 [(set (match_operand:SI 0 "register_operand" "=r")
960 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
962 (match_operand:SI 2 "register_operand" "r")))
963 (clobber (reg:CC CC_REG))]
967 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
969 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
972 [(set_attr "length" "2")])
974 (define_insn_and_split "*x_minus_i_ne_0"
975 [(set (match_operand:SI 0 "register_operand" "=r")
976 (minus:SI (match_operand:SI 2 "register_operand" "r")
977 (ne:SI (match_operand:SI 1 "register_operand" "r")
979 (clobber (reg:CC CC_REG))]
983 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
985 (set (match_dup 0) (minus:SI (match_dup 2)
986 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
988 [(set_attr "length" "2")])
990 (define_insn_and_split "*x_plus_i_eq_0"
991 [(set (match_operand:SI 0 "register_operand" "=r")
992 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
994 (match_operand:SI 2 "register_operand" "r")))
995 (clobber (reg:CC CC_REG))]
999 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
1001 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1004 [(set_attr "length" "2")])
1006 (define_insn_and_split "*x_minus_i_eq_0"
1007 [(set (match_operand:SI 0 "register_operand" "=r")
1008 (minus:SI (match_operand:SI 2 "register_operand" "r")
1009 (eq:SI (match_operand:SI 1 "register_operand" "r")
1011 (clobber (reg:CC CC_REG))]
1015 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
1017 (set (match_dup 0) (minus:SI (match_dup 2)
1018 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1020 [(set_attr "length" "2")])
1022 ;; We can also do GEU and LTU directly, but these operate after a compare.
1023 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1026 (define_insn "*sltu_insn"
1027 [(set (match_operand:SI 0 "register_operand" "=r")
1028 (ltu:SI (reg:CC CC_REG) (const_int 0)))]
1031 [(set_attr "type" "ialuX")])
1033 (define_insn "*sltu_insn_vis3"
1034 [(set (match_operand:DI 0 "register_operand" "=r")
1035 (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
1036 "TARGET_ARCH64 && TARGET_VIS3"
1037 "addxc\t%%g0, %%g0, %0"
1038 [(set_attr "type" "ialuX")])
1040 (define_insn "*sltu_insn_vis3_trunc"
1041 [(set (match_operand:SI 0 "register_operand" "=r")
1042 (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
1043 "TARGET_ARCH64 && TARGET_VIS3"
1044 "addxc\t%%g0, %%g0, %0"
1045 [(set_attr "type" "ialuX")])
1047 (define_insn "*sltu_extend_sp64"
1048 [(set (match_operand:DI 0 "register_operand" "=r")
1049 (ltu:DI (reg:CC CC_REG) (const_int 0)))]
1052 [(set_attr "type" "ialuX")])
1054 (define_insn "*neg_sltu_insn"
1055 [(set (match_operand:SI 0 "register_operand" "=r")
1056 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1059 [(set_attr "type" "ialuX")])
1061 (define_insn "*neg_sltu_extend_sp64"
1062 [(set (match_operand:DI 0 "register_operand" "=r")
1063 (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))]
1066 [(set_attr "type" "ialuX")])
1068 ;; ??? Combine should canonicalize these next two to the same pattern.
1069 (define_insn "*neg_sltu_minus_x"
1070 [(set (match_operand:SI 0 "register_operand" "=r")
1071 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
1072 (match_operand:SI 1 "arith_operand" "rI")))]
1074 "subx\t%%g0, %1, %0"
1075 [(set_attr "type" "ialuX")])
1077 (define_insn "*neg_sltu_plus_x"
1078 [(set (match_operand:SI 0 "register_operand" "=r")
1079 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1080 (match_operand:SI 1 "arith_operand" "rI"))))]
1082 "subx\t%%g0, %1, %0"
1083 [(set_attr "type" "ialuX")])
1085 (define_insn "*sgeu_insn"
1086 [(set (match_operand:SI 0 "register_operand" "=r")
1087 (geu:SI (reg:CC CC_REG) (const_int 0)))]
1089 "subx\t%%g0, -1, %0"
1090 [(set_attr "type" "ialuX")])
1092 (define_insn "*sgeu_extend_sp64"
1093 [(set (match_operand:DI 0 "register_operand" "=r")
1094 (geu:DI (reg:CC CC_REG) (const_int 0)))]
1096 "subx\t%%g0, -1, %0"
1097 [(set_attr "type" "ialuX")])
1099 (define_insn "*neg_sgeu_insn"
1100 [(set (match_operand:SI 0 "register_operand" "=r")
1101 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
1103 "addx\t%%g0, -1, %0"
1104 [(set_attr "type" "ialuX")])
1106 (define_insn "*neg_sgeu_extend_sp64"
1107 [(set (match_operand:DI 0 "register_operand" "=r")
1108 (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))]
1110 "addx\t%%g0, -1, %0"
1111 [(set_attr "type" "ialuX")])
1113 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1114 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1117 (define_insn "*sltu_plus_x"
1118 [(set (match_operand:SI 0 "register_operand" "=r")
1119 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1120 (match_operand:SI 1 "arith_operand" "rI")))]
1122 "addx\t%%g0, %1, %0"
1123 [(set_attr "type" "ialuX")])
1125 (define_insn "*sltu_plus_x_plus_y"
1126 [(set (match_operand:SI 0 "register_operand" "=r")
1127 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1128 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1129 (match_operand:SI 2 "arith_operand" "rI"))))]
1132 [(set_attr "type" "ialuX")])
1134 (define_insn "*x_minus_sltu"
1135 [(set (match_operand:SI 0 "register_operand" "=r")
1136 (minus:SI (match_operand:SI 1 "register_operand" "r")
1137 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1140 [(set_attr "type" "ialuX")])
1142 ;; ??? Combine should canonicalize these next two to the same pattern.
1143 (define_insn "*x_minus_y_minus_sltu"
1144 [(set (match_operand:SI 0 "register_operand" "=r")
1145 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1146 (match_operand:SI 2 "arith_operand" "rI"))
1147 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1150 [(set_attr "type" "ialuX")])
1152 (define_insn "*x_minus_sltu_plus_y"
1153 [(set (match_operand:SI 0 "register_operand" "=r")
1154 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1155 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1156 (match_operand:SI 2 "arith_operand" "rI"))))]
1159 [(set_attr "type" "ialuX")])
1161 (define_insn "*sgeu_plus_x"
1162 [(set (match_operand:SI 0 "register_operand" "=r")
1163 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1164 (match_operand:SI 1 "register_operand" "r")))]
1167 [(set_attr "type" "ialuX")])
1169 (define_insn "*x_minus_sgeu"
1170 [(set (match_operand:SI 0 "register_operand" "=r")
1171 (minus:SI (match_operand:SI 1 "register_operand" "r")
1172 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1175 [(set_attr "type" "ialuX")])
1178 [(set (match_operand:SI 0 "register_operand" "")
1179 (match_operator:SI 2 "noov_compare_operator"
1180 [(match_operand 1 "icc_or_fcc_register_operand" "")
1183 && REGNO (operands[1]) == SPARC_ICC_REG
1184 && (GET_MODE (operands[1]) == CCXmode
1185 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1186 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1187 [(set (match_dup 0) (const_int 0))
1189 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1195 ;; These control RTL generation for conditional jump insns
1197 (define_expand "cbranchcc4"
1199 (if_then_else (match_operator 0 "comparison_operator"
1200 [(match_operand 1 "compare_operand" "")
1201 (match_operand 2 "const_zero_operand" "")])
1202 (label_ref (match_operand 3 "" ""))
1207 (define_expand "cbranchsi4"
1208 [(use (match_operator 0 "comparison_operator"
1209 [(match_operand:SI 1 "compare_operand" "")
1210 (match_operand:SI 2 "arith_operand" "")]))
1211 (use (match_operand 3 ""))]
1214 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1215 operands[1] = force_reg (SImode, operands[1]);
1216 emit_conditional_branch_insn (operands);
1220 (define_expand "cbranchdi4"
1221 [(use (match_operator 0 "comparison_operator"
1222 [(match_operand:DI 1 "compare_operand" "")
1223 (match_operand:DI 2 "arith_operand" "")]))
1224 (use (match_operand 3 ""))]
1227 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1228 operands[1] = force_reg (DImode, operands[1]);
1229 emit_conditional_branch_insn (operands);
1233 (define_expand "cbranch<F:mode>4"
1234 [(use (match_operator 0 "comparison_operator"
1235 [(match_operand:F 1 "register_operand" "")
1236 (match_operand:F 2 "register_operand" "")]))
1237 (use (match_operand 3 ""))]
1239 { emit_conditional_branch_insn (operands); DONE; })
1242 ;; Now match both normal and inverted jump.
1244 ;; XXX fpcmp nop braindamage
1245 (define_insn "*normal_branch"
1247 (if_then_else (match_operator 0 "noov_compare_operator"
1248 [(reg CC_REG) (const_int 0)])
1249 (label_ref (match_operand 1 "" ""))
1253 return output_cbranch (operands[0], operands[1], 1, 0,
1254 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1257 [(set_attr "type" "branch")
1258 (set_attr "branch_type" "icc")])
1260 ;; XXX fpcmp nop braindamage
1261 (define_insn "*inverted_branch"
1263 (if_then_else (match_operator 0 "noov_compare_operator"
1264 [(reg CC_REG) (const_int 0)])
1266 (label_ref (match_operand 1 "" ""))))]
1269 return output_cbranch (operands[0], operands[1], 1, 1,
1270 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1273 [(set_attr "type" "branch")
1274 (set_attr "branch_type" "icc")])
1276 ;; XXX fpcmp nop braindamage
1277 (define_insn "*normal_fp_branch"
1279 (if_then_else (match_operator 1 "comparison_operator"
1280 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1282 (label_ref (match_operand 2 "" ""))
1286 return output_cbranch (operands[1], operands[2], 2, 0,
1287 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1290 [(set_attr "type" "branch")
1291 (set_attr "branch_type" "fcc")])
1293 ;; XXX fpcmp nop braindamage
1294 (define_insn "*inverted_fp_branch"
1296 (if_then_else (match_operator 1 "comparison_operator"
1297 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1300 (label_ref (match_operand 2 "" ""))))]
1303 return output_cbranch (operands[1], operands[2], 2, 1,
1304 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1307 [(set_attr "type" "branch")
1308 (set_attr "branch_type" "fcc")])
1310 ;; XXX fpcmp nop braindamage
1311 (define_insn "*normal_fpe_branch"
1313 (if_then_else (match_operator 1 "comparison_operator"
1314 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1316 (label_ref (match_operand 2 "" ""))
1320 return output_cbranch (operands[1], operands[2], 2, 0,
1321 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1324 [(set_attr "type" "branch")
1325 (set_attr "branch_type" "fcc")])
1327 ;; XXX fpcmp nop braindamage
1328 (define_insn "*inverted_fpe_branch"
1330 (if_then_else (match_operator 1 "comparison_operator"
1331 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1334 (label_ref (match_operand 2 "" ""))))]
1337 return output_cbranch (operands[1], operands[2], 2, 1,
1338 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1341 [(set_attr "type" "branch")
1342 (set_attr "branch_type" "fcc")])
1344 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1345 ;; in the architecture.
1347 (define_insn "*cbcond_sp32"
1349 (if_then_else (match_operator 0 "noov_compare_operator"
1350 [(match_operand:SI 1 "register_operand" "r")
1351 (match_operand:SI 2 "arith5_operand" "rA")])
1352 (label_ref (match_operand 3 "" ""))
1356 return output_cbcond (operands[0], operands[3], insn);
1358 [(set_attr "type" "cbcond")])
1360 (define_insn "*cbcond_sp64"
1362 (if_then_else (match_operator 0 "noov_compare_operator"
1363 [(match_operand:DI 1 "register_operand" "r")
1364 (match_operand:DI 2 "arith5_operand" "rA")])
1365 (label_ref (match_operand 3 "" ""))
1367 "TARGET_ARCH64 && TARGET_CBCOND"
1369 return output_cbcond (operands[0], operands[3], insn);
1371 [(set_attr "type" "cbcond")])
1373 ;; There are no 32 bit brreg insns.
1376 (define_insn "*normal_int_branch_sp64"
1378 (if_then_else (match_operator 0 "v9_register_compare_operator"
1379 [(match_operand:DI 1 "register_operand" "r")
1381 (label_ref (match_operand 2 "" ""))
1385 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1386 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1389 [(set_attr "type" "branch")
1390 (set_attr "branch_type" "reg")])
1393 (define_insn "*inverted_int_branch_sp64"
1395 (if_then_else (match_operator 0 "v9_register_compare_operator"
1396 [(match_operand:DI 1 "register_operand" "r")
1399 (label_ref (match_operand 2 "" ""))))]
1402 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1403 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1406 [(set_attr "type" "branch")
1407 (set_attr "branch_type" "reg")])
1410 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1411 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1412 ;; that adds the PC value at the call point to register #(operand 3).
1414 ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..."
1415 ;; because the RDPC instruction is extremely expensive and incurs a complete
1416 ;; instruction pipeline flush.
1418 (define_insn "load_pcrel_sym<P:mode>"
1419 [(set (match_operand:P 0 "register_operand" "=r")
1420 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1421 (match_operand:P 2 "call_address_operand" "")
1422 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1423 (clobber (reg:P O7_REG))]
1424 "REGNO (operands[0]) == INTVAL (operands[3])"
1426 if (flag_delayed_branch)
1427 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1429 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1431 [(set (attr "type") (const_string "multi"))
1432 (set (attr "length")
1433 (if_then_else (eq_attr "delayed_branch" "true")
1438 ;; Integer move instructions
1440 (define_expand "movqi"
1441 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1442 (match_operand:QI 1 "general_operand" ""))]
1445 if (sparc_expand_move (QImode, operands))
1449 (define_insn "*movqi_insn"
1450 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1451 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1452 "(register_operand (operands[0], QImode)
1453 || register_or_zero_operand (operands[1], QImode))"
1458 [(set_attr "type" "*,load,store")
1459 (set_attr "us3load_type" "*,3cycle,*")])
1461 (define_expand "movhi"
1462 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1463 (match_operand:HI 1 "general_operand" ""))]
1466 if (sparc_expand_move (HImode, operands))
1470 (define_insn "*movhi_insn"
1471 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1472 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1473 "(register_operand (operands[0], HImode)
1474 || register_or_zero_operand (operands[1], HImode))"
1477 sethi\t%%hi(%a1), %0
1480 [(set_attr "type" "*,*,load,store")
1481 (set_attr "us3load_type" "*,*,3cycle,*")])
1483 ;; We always work with constants here.
1484 (define_insn "*movhi_lo_sum"
1485 [(set (match_operand:HI 0 "register_operand" "=r")
1486 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1487 (match_operand:HI 2 "small_int_operand" "I")))]
1491 (define_expand "movsi"
1492 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1493 (match_operand:SI 1 "general_operand" ""))]
1496 if (sparc_expand_move (SImode, operands))
1500 (define_insn "*movsi_insn"
1501 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1502 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1503 "register_operand (operands[0], SImode)
1504 || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1507 sethi\t%%hi(%a1), %0
1517 [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1518 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1520 (define_insn "*movsi_lo_sum"
1521 [(set (match_operand:SI 0 "register_operand" "=r")
1522 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1523 (match_operand:SI 2 "immediate_operand" "in")))]
1525 "or\t%1, %%lo(%a2), %0")
1527 (define_insn "*movsi_high"
1528 [(set (match_operand:SI 0 "register_operand" "=r")
1529 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1531 "sethi\t%%hi(%a1), %0")
1533 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1534 ;; so that CSE won't optimize the address computation away.
1535 (define_insn "movsi_lo_sum_pic"
1536 [(set (match_operand:SI 0 "register_operand" "=r")
1537 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1538 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1541 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1542 return "xor\t%1, %%gdop_lox10(%a2), %0";
1544 return "or\t%1, %%lo(%a2), %0";
1548 (define_insn "movsi_high_pic"
1549 [(set (match_operand:SI 0 "register_operand" "=r")
1550 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1551 "flag_pic && check_pic (1)"
1553 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1554 return "sethi\t%%gdop_hix22(%a1), %0";
1556 return "sethi\t%%hi(%a1), %0";
1560 (define_insn "movsi_pic_gotdata_op"
1561 [(set (match_operand:SI 0 "register_operand" "=r")
1562 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1563 (match_operand:SI 2 "register_operand" "r")
1564 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1565 "flag_pic && check_pic (1)"
1567 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1568 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1570 return "ld\t[%1 + %2], %0";
1573 [(set_attr "type" "load")])
1575 (define_expand "movsi_pic_label_ref"
1576 [(set (match_dup 3) (high:SI
1577 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1578 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1579 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1580 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1581 (set (match_operand:SI 0 "register_operand" "=r")
1582 (minus:SI (match_dup 5) (match_dup 4)))]
1585 crtl->uses_pic_offset_table = 1;
1586 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1587 if (!can_create_pseudo_p ())
1589 operands[3] = operands[0];
1590 operands[4] = operands[0];
1594 operands[3] = gen_reg_rtx (SImode);
1595 operands[4] = gen_reg_rtx (SImode);
1597 operands[5] = pic_offset_table_rtx;
1600 (define_insn "*movsi_high_pic_label_ref"
1601 [(set (match_operand:SI 0 "register_operand" "=r")
1603 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1604 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1606 "sethi\t%%hi(%a2-(%a1-.)), %0")
1608 (define_insn "*movsi_lo_sum_pic_label_ref"
1609 [(set (match_operand:SI 0 "register_operand" "=r")
1610 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1611 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1612 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1614 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1616 ;; Set up the PIC register for VxWorks.
1618 (define_expand "vxworks_load_got"
1620 (high:SI (match_dup 1)))
1622 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1624 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1625 "TARGET_VXWORKS_RTP"
1627 operands[0] = pic_offset_table_rtx;
1628 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1629 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1632 (define_expand "movdi"
1633 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1634 (match_operand:DI 1 "general_operand" ""))]
1637 if (sparc_expand_move (DImode, operands))
1641 ;; Be careful, fmovd does not exist when !v9.
1642 ;; We match MEM moves directly when we have correct even
1643 ;; numbered registers, but fall into splits otherwise.
1644 ;; The constraint ordering here is really important to
1645 ;; avoid insane problems in reload, especially for patterns
1648 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1649 ;; (const_int -5016)))
1653 (define_insn "*movdi_insn_sp32"
1654 [(set (match_operand:DI 0 "nonimmediate_operand"
1655 "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e, r,?*f,?*e,?W,b,b")
1656 (match_operand:DI 1 "input_operand"
1657 " J,J,U,T,r,o,i,r,*f, T, o,*f, *e, *e,?*f, r, W,*e,J,P"))]
1659 && (register_operand (operands[0], DImode)
1660 || register_or_zero_operand (operands[1], DImode))"
1682 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl")
1683 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1684 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1685 (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
1687 (define_insn "*movdi_insn_sp64"
1688 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1689 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,*e, r, *e, W,*e,J,P"))]
1691 && (register_operand (operands[0], DImode)
1692 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1695 sethi\t%%hi(%a1), %0
1705 [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1706 (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1707 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1709 (define_expand "movdi_pic_label_ref"
1710 [(set (match_dup 3) (high:DI
1711 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1712 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1713 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1714 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1715 (set (match_operand:DI 0 "register_operand" "=r")
1716 (minus:DI (match_dup 5) (match_dup 4)))]
1717 "TARGET_ARCH64 && flag_pic"
1719 crtl->uses_pic_offset_table = 1;
1720 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1721 if (!can_create_pseudo_p ())
1723 operands[3] = operands[0];
1724 operands[4] = operands[0];
1728 operands[3] = gen_reg_rtx (DImode);
1729 operands[4] = gen_reg_rtx (DImode);
1731 operands[5] = pic_offset_table_rtx;
1734 (define_insn "*movdi_high_pic_label_ref"
1735 [(set (match_operand:DI 0 "register_operand" "=r")
1737 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1738 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1739 "TARGET_ARCH64 && flag_pic"
1740 "sethi\t%%hi(%a2-(%a1-.)), %0")
1742 (define_insn "*movdi_lo_sum_pic_label_ref"
1743 [(set (match_operand:DI 0 "register_operand" "=r")
1744 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1745 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1746 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1747 "TARGET_ARCH64 && flag_pic"
1748 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1750 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1751 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1753 (define_insn "movdi_lo_sum_pic"
1754 [(set (match_operand:DI 0 "register_operand" "=r")
1755 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1756 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1757 "TARGET_ARCH64 && flag_pic"
1759 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1760 return "xor\t%1, %%gdop_lox10(%a2), %0";
1762 return "or\t%1, %%lo(%a2), %0";
1766 (define_insn "movdi_high_pic"
1767 [(set (match_operand:DI 0 "register_operand" "=r")
1768 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1769 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1771 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1772 return "sethi\t%%gdop_hix22(%a1), %0";
1774 return "sethi\t%%hi(%a1), %0";
1778 (define_insn "movdi_pic_gotdata_op"
1779 [(set (match_operand:DI 0 "register_operand" "=r")
1780 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1781 (match_operand:DI 2 "register_operand" "r")
1782 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1783 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1785 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1786 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1788 return "ldx\t[%1 + %2], %0";
1791 [(set_attr "type" "load")])
1793 (define_insn "*sethi_di_medlow_embmedany_pic"
1794 [(set (match_operand:DI 0 "register_operand" "=r")
1795 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1796 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1797 "sethi\t%%hi(%a1), %0")
1799 (define_insn "*sethi_di_medlow"
1800 [(set (match_operand:DI 0 "register_operand" "=r")
1801 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1802 "TARGET_CM_MEDLOW && check_pic (1)"
1803 "sethi\t%%hi(%a1), %0")
1805 (define_insn "*losum_di_medlow"
1806 [(set (match_operand:DI 0 "register_operand" "=r")
1807 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1808 (match_operand:DI 2 "symbolic_operand" "")))]
1810 "or\t%1, %%lo(%a2), %0")
1812 (define_insn "seth44"
1813 [(set (match_operand:DI 0 "register_operand" "=r")
1814 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1816 "sethi\t%%h44(%a1), %0")
1818 (define_insn "setm44"
1819 [(set (match_operand:DI 0 "register_operand" "=r")
1820 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1821 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1823 "or\t%1, %%m44(%a2), %0")
1825 (define_insn "setl44"
1826 [(set (match_operand:DI 0 "register_operand" "=r")
1827 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1828 (match_operand:DI 2 "symbolic_operand" "")))]
1830 "or\t%1, %%l44(%a2), %0")
1832 (define_insn "sethh"
1833 [(set (match_operand:DI 0 "register_operand" "=r")
1834 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1836 "sethi\t%%hh(%a1), %0")
1838 (define_insn "setlm"
1839 [(set (match_operand:DI 0 "register_operand" "=r")
1840 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1842 "sethi\t%%lm(%a1), %0")
1844 (define_insn "sethm"
1845 [(set (match_operand:DI 0 "register_operand" "=r")
1846 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1847 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1849 "or\t%1, %%hm(%a2), %0")
1851 (define_insn "setlo"
1852 [(set (match_operand:DI 0 "register_operand" "=r")
1853 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1854 (match_operand:DI 2 "symbolic_operand" "")))]
1856 "or\t%1, %%lo(%a2), %0")
1858 (define_insn "embmedany_sethi"
1859 [(set (match_operand:DI 0 "register_operand" "=r")
1860 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1861 "TARGET_CM_EMBMEDANY && check_pic (1)"
1862 "sethi\t%%hi(%a1), %0")
1864 (define_insn "embmedany_losum"
1865 [(set (match_operand:DI 0 "register_operand" "=r")
1866 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1867 (match_operand:DI 2 "data_segment_operand" "")))]
1868 "TARGET_CM_EMBMEDANY"
1869 "add\t%1, %%lo(%a2), %0")
1871 (define_insn "embmedany_brsum"
1872 [(set (match_operand:DI 0 "register_operand" "=r")
1873 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1874 "TARGET_CM_EMBMEDANY"
1877 (define_insn "embmedany_textuhi"
1878 [(set (match_operand:DI 0 "register_operand" "=r")
1879 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1880 "TARGET_CM_EMBMEDANY && check_pic (1)"
1881 "sethi\t%%uhi(%a1), %0")
1883 (define_insn "embmedany_texthi"
1884 [(set (match_operand:DI 0 "register_operand" "=r")
1885 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1886 "TARGET_CM_EMBMEDANY && check_pic (1)"
1887 "sethi\t%%hi(%a1), %0")
1889 (define_insn "embmedany_textulo"
1890 [(set (match_operand:DI 0 "register_operand" "=r")
1891 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1892 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1893 "TARGET_CM_EMBMEDANY"
1894 "or\t%1, %%ulo(%a2), %0")
1896 (define_insn "embmedany_textlo"
1897 [(set (match_operand:DI 0 "register_operand" "=r")
1898 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1899 (match_operand:DI 2 "text_segment_operand" "")))]
1900 "TARGET_CM_EMBMEDANY"
1901 "or\t%1, %%lo(%a2), %0")
1903 ;; Now some patterns to help reload out a bit.
1904 (define_expand "reload_indi"
1905 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1906 (match_operand:DI 1 "immediate_operand" "")
1907 (match_operand:TI 2 "register_operand" "=&r")])]
1909 || TARGET_CM_EMBMEDANY)
1912 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1916 (define_expand "reload_outdi"
1917 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1918 (match_operand:DI 1 "immediate_operand" "")
1919 (match_operand:TI 2 "register_operand" "=&r")])]
1921 || TARGET_CM_EMBMEDANY)
1924 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1928 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1930 [(set (match_operand:DI 0 "register_operand" "")
1931 (match_operand:DI 1 "const_int_operand" ""))]
1933 && ((GET_CODE (operands[0]) == REG
1934 && SPARC_INT_REG_P (REGNO (operands[0])))
1935 || (GET_CODE (operands[0]) == SUBREG
1936 && GET_CODE (SUBREG_REG (operands[0])) == REG
1937 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))
1938 && reload_completed"
1939 [(clobber (const_int 0))]
1941 #if HOST_BITS_PER_WIDE_INT == 32
1942 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1943 (INTVAL (operands[1]) < 0) ?
1946 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1949 unsigned int low, high;
1951 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1952 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1953 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1955 /* Slick... but this trick loses if this subreg constant part
1956 can be done in one insn. */
1958 && ! SPARC_SETHI32_P (high)
1959 && ! SPARC_SIMM13_P (high))
1960 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1961 gen_highpart (SImode, operands[0])));
1963 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1969 [(set (match_operand:DI 0 "register_operand" "")
1970 (match_operand:DI 1 "const_double_operand" ""))]
1974 && ((GET_CODE (operands[0]) == REG
1975 && SPARC_INT_REG_P (REGNO (operands[0])))
1976 || (GET_CODE (operands[0]) == SUBREG
1977 && GET_CODE (SUBREG_REG (operands[0])) == REG
1978 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
1979 [(clobber (const_int 0))]
1981 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1982 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1984 /* Slick... but this trick loses if this subreg constant part
1985 can be done in one insn. */
1986 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1987 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1988 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1990 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1991 gen_highpart (SImode, operands[0])));
1995 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1996 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2002 [(set (match_operand:DI 0 "register_operand" "")
2003 (match_operand:DI 1 "register_operand" ""))]
2007 && sparc_split_regreg_legitimate (operands[0],
2009 [(clobber (const_int 0))]
2011 rtx set_dest = operands[0];
2012 rtx set_src = operands[1];
2016 dest1 = gen_highpart (SImode, set_dest);
2017 dest2 = gen_lowpart (SImode, set_dest);
2018 src1 = gen_highpart (SImode, set_src);
2019 src2 = gen_lowpart (SImode, set_src);
2021 /* Now emit using the real source and destination we found, swapping
2022 the order if we detect overlap. */
2023 if (reg_overlap_mentioned_p (dest1, src2))
2025 emit_insn (gen_movsi (dest2, src2));
2026 emit_insn (gen_movsi (dest1, src1));
2030 emit_insn (gen_movsi (dest1, src1));
2031 emit_insn (gen_movsi (dest2, src2));
2036 ;; Now handle the cases of memory moves from/to non-even
2037 ;; DI mode register pairs.
2039 [(set (match_operand:DI 0 "register_operand" "")
2040 (match_operand:DI 1 "memory_operand" ""))]
2043 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2044 [(clobber (const_int 0))]
2046 rtx word0 = adjust_address (operands[1], SImode, 0);
2047 rtx word1 = adjust_address (operands[1], SImode, 4);
2048 rtx high_part = gen_highpart (SImode, operands[0]);
2049 rtx low_part = gen_lowpart (SImode, operands[0]);
2051 if (reg_overlap_mentioned_p (high_part, word1))
2053 emit_insn (gen_movsi (low_part, word1));
2054 emit_insn (gen_movsi (high_part, word0));
2058 emit_insn (gen_movsi (high_part, word0));
2059 emit_insn (gen_movsi (low_part, word1));
2065 [(set (match_operand:DI 0 "memory_operand" "")
2066 (match_operand:DI 1 "register_operand" ""))]
2069 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2070 [(clobber (const_int 0))]
2072 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2073 gen_highpart (SImode, operands[1])));
2074 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2075 gen_lowpart (SImode, operands[1])));
2080 [(set (match_operand:DI 0 "memory_operand" "")
2081 (match_operand:DI 1 "const_zero_operand" ""))]
2085 && ! mem_min_alignment (operands[0], 8)))
2086 && offsettable_memref_p (operands[0])"
2087 [(clobber (const_int 0))]
2089 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2090 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2094 (define_expand "movti"
2095 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2096 (match_operand:TI 1 "general_operand" ""))]
2099 if (sparc_expand_move (TImode, operands))
2103 ;; We need to prevent reload from splitting TImode moves, because it
2104 ;; might decide to overwrite a pointer with the value it points to.
2105 ;; In that case we have to do the loads in the appropriate order so
2106 ;; that the pointer is not destroyed too early.
2108 (define_insn "*movti_insn_sp64"
2109 [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b")
2110 (match_operand:TI 1 "input_operand" "roJ,rJ, eo, e,J"))]
2112 && ! TARGET_HARD_QUAD
2113 && (register_operand (operands[0], TImode)
2114 || register_or_zero_operand (operands[1], TImode))"
2116 [(set_attr "length" "2,2,2,2,2")
2117 (set_attr "cpu_feature" "*,*,fpu,fpu,vis")])
2119 (define_insn "*movti_insn_sp64_hq"
2120 [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b")
2121 (match_operand:TI 1 "input_operand" "roJ,rJ, e, m, e,J"))]
2124 && (register_operand (operands[0], TImode)
2125 || register_or_zero_operand (operands[1], TImode))"
2133 [(set_attr "type" "*,*,fpmove,fpload,fpstore,*")
2134 (set_attr "length" "2,2,*,*,*,2")])
2136 ;; Now all the splits to handle multi-insn TI mode moves.
2138 [(set (match_operand:TI 0 "register_operand" "")
2139 (match_operand:TI 1 "register_operand" ""))]
2142 && ! TARGET_HARD_QUAD)
2143 || (! fp_register_operand (operands[0], TImode)
2144 && ! fp_register_operand (operands[1], TImode)))"
2145 [(clobber (const_int 0))]
2147 rtx set_dest = operands[0];
2148 rtx set_src = operands[1];
2152 dest1 = gen_highpart (DImode, set_dest);
2153 dest2 = gen_lowpart (DImode, set_dest);
2154 src1 = gen_highpart (DImode, set_src);
2155 src2 = gen_lowpart (DImode, set_src);
2157 /* Now emit using the real source and destination we found, swapping
2158 the order if we detect overlap. */
2159 if (reg_overlap_mentioned_p (dest1, src2))
2161 emit_insn (gen_movdi (dest2, src2));
2162 emit_insn (gen_movdi (dest1, src1));
2166 emit_insn (gen_movdi (dest1, src1));
2167 emit_insn (gen_movdi (dest2, src2));
2173 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2174 (match_operand:TI 1 "const_zero_operand" ""))]
2176 [(clobber (const_int 0))]
2178 rtx set_dest = operands[0];
2181 switch (GET_CODE (set_dest))
2184 dest1 = gen_highpart (DImode, set_dest);
2185 dest2 = gen_lowpart (DImode, set_dest);
2188 dest1 = adjust_address (set_dest, DImode, 0);
2189 dest2 = adjust_address (set_dest, DImode, 8);
2195 emit_insn (gen_movdi (dest1, const0_rtx));
2196 emit_insn (gen_movdi (dest2, const0_rtx));
2201 [(set (match_operand:TI 0 "register_operand" "")
2202 (match_operand:TI 1 "memory_operand" ""))]
2204 && offsettable_memref_p (operands[1])
2205 && (! TARGET_HARD_QUAD
2206 || ! fp_register_operand (operands[0], TImode))"
2207 [(clobber (const_int 0))]
2209 rtx word0 = adjust_address (operands[1], DImode, 0);
2210 rtx word1 = adjust_address (operands[1], DImode, 8);
2211 rtx set_dest, dest1, dest2;
2213 set_dest = operands[0];
2215 dest1 = gen_highpart (DImode, set_dest);
2216 dest2 = gen_lowpart (DImode, set_dest);
2218 /* Now output, ordering such that we don't clobber any registers
2219 mentioned in the address. */
2220 if (reg_overlap_mentioned_p (dest1, word1))
2223 emit_insn (gen_movdi (dest2, word1));
2224 emit_insn (gen_movdi (dest1, word0));
2228 emit_insn (gen_movdi (dest1, word0));
2229 emit_insn (gen_movdi (dest2, word1));
2235 [(set (match_operand:TI 0 "memory_operand" "")
2236 (match_operand:TI 1 "register_operand" ""))]
2238 && offsettable_memref_p (operands[0])
2239 && (! TARGET_HARD_QUAD
2240 || ! fp_register_operand (operands[1], TImode))"
2241 [(clobber (const_int 0))]
2243 rtx set_src = operands[1];
2245 emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0),
2246 gen_highpart (DImode, set_src)));
2247 emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8),
2248 gen_lowpart (DImode, set_src)));
2253 ;; Floating point move instructions
2255 (define_expand "movsf"
2256 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2257 (match_operand:SF 1 "general_operand" ""))]
2260 if (sparc_expand_move (SFmode, operands))
2264 (define_insn "*movsf_insn"
2265 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m, m")
2266 (match_operand:SF 1 "input_operand" "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2267 "(register_operand (operands[0], SFmode)
2268 || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2270 if (GET_CODE (operands[1]) == CONST_DOUBLE
2271 && (which_alternative == 3
2272 || which_alternative == 4
2273 || which_alternative == 5))
2278 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2279 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2280 operands[1] = GEN_INT (i);
2283 switch (which_alternative)
2286 return "fzeros\t%0";
2290 return "fmovs\t%1, %0";
2292 return "mov\t%1, %0";
2294 return "sethi\t%%hi(%a1), %0";
2298 return "movstouw\t%1, %0";
2300 return "movwtos\t%1, %0";
2303 return "ld\t%1, %0";
2306 return "st\t%r1, %0";
2311 [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store")
2312 (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2314 ;; The following 3 patterns build SFmode constants in integer registers.
2316 (define_insn "*movsf_lo_sum"
2317 [(set (match_operand:SF 0 "register_operand" "=r")
2318 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2319 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2325 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2326 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2327 operands[2] = GEN_INT (i);
2328 return "or\t%1, %%lo(%a2), %0";
2331 (define_insn "*movsf_high"
2332 [(set (match_operand:SF 0 "register_operand" "=r")
2333 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2339 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2340 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2341 operands[1] = GEN_INT (i);
2342 return "sethi\t%%hi(%1), %0";
2346 [(set (match_operand:SF 0 "register_operand" "")
2347 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2348 "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2349 [(set (match_dup 0) (high:SF (match_dup 1)))
2350 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2352 (define_expand "movdf"
2353 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2354 (match_operand:DF 1 "general_operand" ""))]
2357 if (sparc_expand_move (DFmode, operands))
2361 (define_insn "*movdf_insn_sp32"
2362 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f, e,T,W,U,T, f, *r, o,o")
2363 (match_operand:DF 1 "input_operand" "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))]
2365 && (register_operand (operands[0], DFmode)
2366 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2383 [(set_attr "type" "visl,visl,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*")
2384 (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2")
2385 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2386 (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")])
2388 (define_insn "*movdf_insn_sp64"
2389 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r")
2390 (match_operand:DF 1 "input_operand" "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2392 && (register_operand (operands[0], DFmode)
2393 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2406 [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*")
2407 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2408 (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2409 (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2411 ;; This pattern builds DFmode constants in integer registers.
2413 [(set (match_operand:DF 0 "register_operand" "")
2414 (match_operand:DF 1 "const_double_operand" ""))]
2415 "REG_P (operands[0])
2416 && SPARC_INT_REG_P (REGNO (operands[0]))
2417 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2418 && reload_completed"
2419 [(clobber (const_int 0))]
2421 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2425 #if HOST_BITS_PER_WIDE_INT == 32
2428 enum machine_mode mode = GET_MODE (operands[1]);
2429 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2430 emit_insn (gen_movdi (operands[0], tem));
2435 enum machine_mode mode = GET_MODE (operands[1]);
2436 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2437 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2439 gcc_assert (GET_CODE (hi) == CONST_INT);
2440 gcc_assert (GET_CODE (lo) == CONST_INT);
2442 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2444 /* Slick... but this trick loses if this subreg constant part
2445 can be done in one insn. */
2447 && ! SPARC_SETHI32_P (INTVAL (hi))
2448 && ! SPARC_SIMM13_P (INTVAL (hi)))
2450 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2451 gen_highpart (SImode, operands[0])));
2455 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2461 ;; Ok, now the splits to handle all the multi insn and
2462 ;; mis-aligned memory address cases.
2463 ;; In these splits please take note that we must be
2464 ;; careful when V9 but not ARCH64 because the integer
2465 ;; register DFmode cases must be handled.
2467 [(set (match_operand:DF 0 "register_operand" "")
2468 (match_operand:DF 1 "register_operand" ""))]
2471 && sparc_split_regreg_legitimate (operands[0],
2473 && reload_completed"
2474 [(clobber (const_int 0))]
2476 rtx set_dest = operands[0];
2477 rtx set_src = operands[1];
2481 dest1 = gen_highpart (SFmode, set_dest);
2482 dest2 = gen_lowpart (SFmode, set_dest);
2483 src1 = gen_highpart (SFmode, set_src);
2484 src2 = gen_lowpart (SFmode, set_src);
2486 /* Now emit using the real source and destination we found, swapping
2487 the order if we detect overlap. */
2488 if (reg_overlap_mentioned_p (dest1, src2))
2490 emit_move_insn_1 (dest2, src2);
2491 emit_move_insn_1 (dest1, src1);
2495 emit_move_insn_1 (dest1, src1);
2496 emit_move_insn_1 (dest2, src2);
2502 [(set (match_operand:DF 0 "register_operand" "")
2503 (match_operand:DF 1 "memory_operand" ""))]
2506 && (((REGNO (operands[0]) % 2) != 0)
2507 || ! mem_min_alignment (operands[1], 8))
2508 && offsettable_memref_p (operands[1])"
2509 [(clobber (const_int 0))]
2513 word0 = adjust_address (operands[1], SFmode, 0);
2514 word1 = adjust_address (operands[1], SFmode, 4);
2516 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2518 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2519 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2523 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2524 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2530 [(set (match_operand:DF 0 "memory_operand" "")
2531 (match_operand:DF 1 "register_operand" ""))]
2534 && (((REGNO (operands[1]) % 2) != 0)
2535 || ! mem_min_alignment (operands[0], 8))
2536 && offsettable_memref_p (operands[0])"
2537 [(clobber (const_int 0))]
2541 word0 = adjust_address (operands[0], SFmode, 0);
2542 word1 = adjust_address (operands[0], SFmode, 4);
2544 emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2545 emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2550 [(set (match_operand:DF 0 "memory_operand" "")
2551 (match_operand:DF 1 "const_zero_operand" ""))]
2555 && ! mem_min_alignment (operands[0], 8)))
2556 && offsettable_memref_p (operands[0])"
2557 [(clobber (const_int 0))]
2561 dest1 = adjust_address (operands[0], SFmode, 0);
2562 dest2 = adjust_address (operands[0], SFmode, 4);
2564 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2565 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2570 [(set (match_operand:DF 0 "register_operand" "")
2571 (match_operand:DF 1 "const_zero_operand" ""))]
2574 && ((GET_CODE (operands[0]) == REG
2575 && SPARC_INT_REG_P (REGNO (operands[0])))
2576 || (GET_CODE (operands[0]) == SUBREG
2577 && GET_CODE (SUBREG_REG (operands[0])) == REG
2578 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2579 [(clobber (const_int 0))]
2581 rtx set_dest = operands[0];
2584 dest1 = gen_highpart (SFmode, set_dest);
2585 dest2 = gen_lowpart (SFmode, set_dest);
2586 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2587 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2591 (define_expand "movtf"
2592 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2593 (match_operand:TF 1 "general_operand" ""))]
2596 if (sparc_expand_move (TFmode, operands))
2600 (define_insn "*movtf_insn_sp32"
2601 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,U, r")
2602 (match_operand:TF 1 "input_operand" " G,oe,e,rGU,o,roG"))]
2604 && (register_operand (operands[0], TFmode)
2605 || register_or_zero_operand (operands[1], TFmode))"
2607 [(set_attr "length" "4,4,4,4,4,4")
2608 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")])
2610 (define_insn "*movtf_insn_sp64"
2611 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o, r")
2612 (match_operand:TF 1 "input_operand" "G,oe,e,rG,roG"))]
2614 && ! TARGET_HARD_QUAD
2615 && (register_operand (operands[0], TFmode)
2616 || register_or_zero_operand (operands[1], TFmode))"
2618 [(set_attr "length" "2,2,2,2,2")
2619 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2621 (define_insn "*movtf_insn_sp64_hq"
2622 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o, r")
2623 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2626 && (register_operand (operands[0], TFmode)
2627 || register_or_zero_operand (operands[1], TFmode))"
2635 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2636 (set_attr "length" "2,*,*,*,2,2")])
2638 ;; Now all the splits to handle multi-insn TF mode moves.
2640 [(set (match_operand:TF 0 "register_operand" "")
2641 (match_operand:TF 1 "register_operand" ""))]
2645 && ! TARGET_HARD_QUAD)
2646 || (! fp_register_operand (operands[0], TFmode)
2647 && ! fp_register_operand (operands[1], TFmode)))"
2648 [(clobber (const_int 0))]
2650 rtx set_dest = operands[0];
2651 rtx set_src = operands[1];
2655 dest1 = gen_df_reg (set_dest, 0);
2656 dest2 = gen_df_reg (set_dest, 1);
2657 src1 = gen_df_reg (set_src, 0);
2658 src2 = gen_df_reg (set_src, 1);
2660 /* Now emit using the real source and destination we found, swapping
2661 the order if we detect overlap. */
2662 if (reg_overlap_mentioned_p (dest1, src2))
2664 emit_insn (gen_movdf (dest2, src2));
2665 emit_insn (gen_movdf (dest1, src1));
2669 emit_insn (gen_movdf (dest1, src1));
2670 emit_insn (gen_movdf (dest2, src2));
2676 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2677 (match_operand:TF 1 "const_zero_operand" ""))]
2679 [(clobber (const_int 0))]
2681 rtx set_dest = operands[0];
2684 switch (GET_CODE (set_dest))
2687 dest1 = gen_df_reg (set_dest, 0);
2688 dest2 = gen_df_reg (set_dest, 1);
2691 dest1 = adjust_address (set_dest, DFmode, 0);
2692 dest2 = adjust_address (set_dest, DFmode, 8);
2698 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2699 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2704 [(set (match_operand:TF 0 "register_operand" "")
2705 (match_operand:TF 1 "memory_operand" ""))]
2707 && offsettable_memref_p (operands[1])
2709 || ! TARGET_HARD_QUAD
2710 || ! fp_register_operand (operands[0], TFmode)))"
2711 [(clobber (const_int 0))]
2713 rtx word0 = adjust_address (operands[1], DFmode, 0);
2714 rtx word1 = adjust_address (operands[1], DFmode, 8);
2715 rtx set_dest, dest1, dest2;
2717 set_dest = operands[0];
2719 dest1 = gen_df_reg (set_dest, 0);
2720 dest2 = gen_df_reg (set_dest, 1);
2722 /* Now output, ordering such that we don't clobber any registers
2723 mentioned in the address. */
2724 if (reg_overlap_mentioned_p (dest1, word1))
2727 emit_insn (gen_movdf (dest2, word1));
2728 emit_insn (gen_movdf (dest1, word0));
2732 emit_insn (gen_movdf (dest1, word0));
2733 emit_insn (gen_movdf (dest2, word1));
2739 [(set (match_operand:TF 0 "memory_operand" "")
2740 (match_operand:TF 1 "register_operand" ""))]
2742 && offsettable_memref_p (operands[0])
2744 || ! TARGET_HARD_QUAD
2745 || ! fp_register_operand (operands[1], TFmode)))"
2746 [(clobber (const_int 0))]
2748 rtx set_src = operands[1];
2750 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2751 gen_df_reg (set_src, 0)));
2752 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2753 gen_df_reg (set_src, 1)));
2758 ;; SPARC-V9 conditional move instructions
2760 ;; We can handle larger constants here for some flavors, but for now we keep
2761 ;; it simple and only allow those constants supported by all flavors.
2762 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2763 ;; 3 contains the constant if one is present, but we handle either for
2764 ;; generality (sparc.c puts a constant in operand 2).
2766 ;; Our instruction patterns, on the other hand, canonicalize such that
2767 ;; operand 3 must be the set destination.
2769 (define_expand "mov<I:mode>cc"
2770 [(set (match_operand:I 0 "register_operand" "")
2771 (if_then_else:I (match_operand 1 "comparison_operator" "")
2772 (match_operand:I 2 "arith10_operand" "")
2773 (match_operand:I 3 "arith10_operand" "")))]
2774 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2776 if (! sparc_expand_conditional_move (<I:MODE>mode, operands))
2781 (define_expand "mov<F:mode>cc"
2782 [(set (match_operand:F 0 "register_operand" "")
2783 (if_then_else:F (match_operand 1 "comparison_operator" "")
2784 (match_operand:F 2 "register_operand" "")
2785 (match_operand:F 3 "register_operand" "")))]
2786 "TARGET_V9 && TARGET_FPU"
2788 if (! sparc_expand_conditional_move (<F:MODE>mode, operands))
2793 ;; Conditional move define_insns
2795 (define_insn "*mov<I:mode>_cc_v9"
2796 [(set (match_operand:I 0 "register_operand" "=r")
2797 (if_then_else:I (match_operator 1 "comparison_operator"
2798 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2800 (match_operand:I 3 "arith11_operand" "rL")
2801 (match_operand:I 4 "register_operand" "0")))]
2802 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2803 "mov%C1\t%x2, %3, %0"
2804 [(set_attr "type" "cmove")])
2806 (define_insn "*mov<I:mode>_cc_reg_sp64"
2807 [(set (match_operand:I 0 "register_operand" "=r")
2808 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2809 [(match_operand:DI 2 "register_operand" "r")
2811 (match_operand:I 3 "arith10_operand" "rM")
2812 (match_operand:I 4 "register_operand" "0")))]
2814 "movr%D1\t%2, %r3, %0"
2815 [(set_attr "type" "cmove")])
2817 (define_insn "*movsf_cc_v9"
2818 [(set (match_operand:SF 0 "register_operand" "=f")
2819 (if_then_else:SF (match_operator 1 "comparison_operator"
2820 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2822 (match_operand:SF 3 "register_operand" "f")
2823 (match_operand:SF 4 "register_operand" "0")))]
2824 "TARGET_V9 && TARGET_FPU"
2825 "fmovs%C1\t%x2, %3, %0"
2826 [(set_attr "type" "fpcmove")])
2828 (define_insn "*movsf_cc_reg_sp64"
2829 [(set (match_operand:SF 0 "register_operand" "=f")
2830 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2831 [(match_operand:DI 2 "register_operand" "r")
2833 (match_operand:SF 3 "register_operand" "f")
2834 (match_operand:SF 4 "register_operand" "0")))]
2835 "TARGET_ARCH64 && TARGET_FPU"
2836 "fmovrs%D1\t%2, %3, %0"
2837 [(set_attr "type" "fpcrmove")])
2839 ;; Named because invoked by movtf_cc_v9
2840 (define_insn "movdf_cc_v9"
2841 [(set (match_operand:DF 0 "register_operand" "=e")
2842 (if_then_else:DF (match_operator 1 "comparison_operator"
2843 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2845 (match_operand:DF 3 "register_operand" "e")
2846 (match_operand:DF 4 "register_operand" "0")))]
2847 "TARGET_V9 && TARGET_FPU"
2848 "fmovd%C1\t%x2, %3, %0"
2849 [(set_attr "type" "fpcmove")
2850 (set_attr "fptype" "double")])
2852 ;; Named because invoked by movtf_cc_reg_sp64
2853 (define_insn "movdf_cc_reg_sp64"
2854 [(set (match_operand:DF 0 "register_operand" "=e")
2855 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2856 [(match_operand:DI 2 "register_operand" "r")
2858 (match_operand:DF 3 "register_operand" "e")
2859 (match_operand:DF 4 "register_operand" "0")))]
2860 "TARGET_ARCH64 && TARGET_FPU"
2861 "fmovrd%D1\t%2, %3, %0"
2862 [(set_attr "type" "fpcrmove")
2863 (set_attr "fptype" "double")])
2865 (define_insn "*movtf_cc_hq_v9"
2866 [(set (match_operand:TF 0 "register_operand" "=e")
2867 (if_then_else:TF (match_operator 1 "comparison_operator"
2868 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2870 (match_operand:TF 3 "register_operand" "e")
2871 (match_operand:TF 4 "register_operand" "0")))]
2872 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2873 "fmovq%C1\t%x2, %3, %0"
2874 [(set_attr "type" "fpcmove")])
2876 (define_insn "*movtf_cc_reg_hq_sp64"
2877 [(set (match_operand:TF 0 "register_operand" "=e")
2878 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2879 [(match_operand:DI 2 "register_operand" "r")
2881 (match_operand:TF 3 "register_operand" "e")
2882 (match_operand:TF 4 "register_operand" "0")))]
2883 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2884 "fmovrq%D1\t%2, %3, %0"
2885 [(set_attr "type" "fpcrmove")])
2887 (define_insn_and_split "*movtf_cc_v9"
2888 [(set (match_operand:TF 0 "register_operand" "=e")
2889 (if_then_else:TF (match_operator 1 "comparison_operator"
2890 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2892 (match_operand:TF 3 "register_operand" "e")
2893 (match_operand:TF 4 "register_operand" "0")))]
2894 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2896 "&& reload_completed"
2897 [(clobber (const_int 0))]
2899 rtx set_dest = operands[0];
2900 rtx set_srca = operands[3];
2904 dest1 = gen_df_reg (set_dest, 0);
2905 dest2 = gen_df_reg (set_dest, 1);
2906 srca1 = gen_df_reg (set_srca, 0);
2907 srca2 = gen_df_reg (set_srca, 1);
2909 if (reg_overlap_mentioned_p (dest1, srca2))
2911 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2912 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2916 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2917 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2921 [(set_attr "length" "2")])
2923 (define_insn_and_split "*movtf_cc_reg_sp64"
2924 [(set (match_operand:TF 0 "register_operand" "=e")
2925 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2926 [(match_operand:DI 2 "register_operand" "r")
2928 (match_operand:TF 3 "register_operand" "e")
2929 (match_operand:TF 4 "register_operand" "0")))]
2930 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2932 "&& reload_completed"
2933 [(clobber (const_int 0))]
2935 rtx set_dest = operands[0];
2936 rtx set_srca = operands[3];
2940 dest1 = gen_df_reg (set_dest, 0);
2941 dest2 = gen_df_reg (set_dest, 1);
2942 srca1 = gen_df_reg (set_srca, 0);
2943 srca2 = gen_df_reg (set_srca, 1);
2945 if (reg_overlap_mentioned_p (dest1, srca2))
2947 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2948 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2952 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2953 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2957 [(set_attr "length" "2")])
2960 ;; Zero-extension instructions
2962 ;; These patterns originally accepted general_operands, however, slightly
2963 ;; better code is generated by only accepting register_operands, and then
2964 ;; letting combine generate the ldu[hb] insns.
2966 (define_expand "zero_extendhisi2"
2967 [(set (match_operand:SI 0 "register_operand" "")
2968 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2971 rtx temp = gen_reg_rtx (SImode);
2972 rtx shift_16 = GEN_INT (16);
2973 int op1_subbyte = 0;
2975 if (GET_CODE (operand1) == SUBREG)
2977 op1_subbyte = SUBREG_BYTE (operand1);
2978 op1_subbyte /= GET_MODE_SIZE (SImode);
2979 op1_subbyte *= GET_MODE_SIZE (SImode);
2980 operand1 = XEXP (operand1, 0);
2983 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2985 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2989 (define_insn "*zero_extendhisi2_insn"
2990 [(set (match_operand:SI 0 "register_operand" "=r")
2991 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2994 [(set_attr "type" "load")
2995 (set_attr "us3load_type" "3cycle")])
2997 (define_expand "zero_extendqihi2"
2998 [(set (match_operand:HI 0 "register_operand" "")
2999 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3003 (define_insn "*zero_extendqihi2_insn"
3004 [(set (match_operand:HI 0 "register_operand" "=r,r")
3005 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3006 "GET_CODE (operands[1]) != CONST_INT"
3010 [(set_attr "type" "*,load")
3011 (set_attr "us3load_type" "*,3cycle")])
3013 (define_expand "zero_extendqisi2"
3014 [(set (match_operand:SI 0 "register_operand" "")
3015 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3019 (define_insn "*zero_extendqisi2_insn"
3020 [(set (match_operand:SI 0 "register_operand" "=r,r")
3021 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3022 "GET_CODE (operands[1]) != CONST_INT"
3026 [(set_attr "type" "*,load")
3027 (set_attr "us3load_type" "*,3cycle")])
3029 (define_expand "zero_extendqidi2"
3030 [(set (match_operand:DI 0 "register_operand" "")
3031 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3035 (define_insn "*zero_extendqidi2_insn"
3036 [(set (match_operand:DI 0 "register_operand" "=r,r")
3037 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3038 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3042 [(set_attr "type" "*,load")
3043 (set_attr "us3load_type" "*,3cycle")])
3045 (define_expand "zero_extendhidi2"
3046 [(set (match_operand:DI 0 "register_operand" "")
3047 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3050 rtx temp = gen_reg_rtx (DImode);
3051 rtx shift_48 = GEN_INT (48);
3052 int op1_subbyte = 0;
3054 if (GET_CODE (operand1) == SUBREG)
3056 op1_subbyte = SUBREG_BYTE (operand1);
3057 op1_subbyte /= GET_MODE_SIZE (DImode);
3058 op1_subbyte *= GET_MODE_SIZE (DImode);
3059 operand1 = XEXP (operand1, 0);
3062 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3064 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3068 (define_insn "*zero_extendhidi2_insn"
3069 [(set (match_operand:DI 0 "register_operand" "=r")
3070 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3073 [(set_attr "type" "load")
3074 (set_attr "us3load_type" "3cycle")])
3076 ;; ??? Write truncdisi pattern using sra?
3078 (define_expand "zero_extendsidi2"
3079 [(set (match_operand:DI 0 "register_operand" "")
3080 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3084 (define_insn "*zero_extendsidi2_insn_sp64"
3085 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3086 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3088 && GET_CODE (operands[1]) != CONST_INT"
3093 [(set_attr "type" "shift,load,*")
3094 (set_attr "cpu_feature" "*,*,vis3")])
3096 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3097 [(set (match_operand:DI 0 "register_operand" "=r")
3098 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3101 "&& reload_completed"
3102 [(set (match_dup 2) (match_dup 3))
3103 (set (match_dup 4) (match_dup 5))]
3107 dest1 = gen_highpart (SImode, operands[0]);
3108 dest2 = gen_lowpart (SImode, operands[0]);
3110 /* Swap the order in case of overlap. */
3111 if (REGNO (dest1) == REGNO (operands[1]))
3113 operands[2] = dest2;
3114 operands[3] = operands[1];
3115 operands[4] = dest1;
3116 operands[5] = const0_rtx;
3120 operands[2] = dest1;
3121 operands[3] = const0_rtx;
3122 operands[4] = dest2;
3123 operands[5] = operands[1];
3126 [(set_attr "length" "2")])
3128 ;; Simplify comparisons of extended values.
3130 (define_insn "*cmp_zero_extendqisi2"
3131 [(set (reg:CC CC_REG)
3132 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3135 "andcc\t%0, 0xff, %%g0"
3136 [(set_attr "type" "compare")])
3138 (define_insn "*cmp_zero_qi"
3139 [(set (reg:CC CC_REG)
3140 (compare:CC (match_operand:QI 0 "register_operand" "r")
3143 "andcc\t%0, 0xff, %%g0"
3144 [(set_attr "type" "compare")])
3146 (define_insn "*cmp_zero_extendqisi2_set"
3147 [(set (reg:CC CC_REG)
3148 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3150 (set (match_operand:SI 0 "register_operand" "=r")
3151 (zero_extend:SI (match_dup 1)))]
3153 "andcc\t%1, 0xff, %0"
3154 [(set_attr "type" "compare")])
3156 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3157 [(set (reg:CC CC_REG)
3158 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3161 (set (match_operand:SI 0 "register_operand" "=r")
3162 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3164 "andcc\t%1, 0xff, %0"
3165 [(set_attr "type" "compare")])
3167 (define_insn "*cmp_zero_extendqidi2"
3168 [(set (reg:CCX CC_REG)
3169 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3172 "andcc\t%0, 0xff, %%g0"
3173 [(set_attr "type" "compare")])
3175 (define_insn "*cmp_zero_qi_sp64"
3176 [(set (reg:CCX CC_REG)
3177 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3180 "andcc\t%0, 0xff, %%g0"
3181 [(set_attr "type" "compare")])
3183 (define_insn "*cmp_zero_extendqidi2_set"
3184 [(set (reg:CCX CC_REG)
3185 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3187 (set (match_operand:DI 0 "register_operand" "=r")
3188 (zero_extend:DI (match_dup 1)))]
3190 "andcc\t%1, 0xff, %0"
3191 [(set_attr "type" "compare")])
3193 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3194 [(set (reg:CCX CC_REG)
3195 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3198 (set (match_operand:DI 0 "register_operand" "=r")
3199 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3201 "andcc\t%1, 0xff, %0"
3202 [(set_attr "type" "compare")])
3204 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3206 (define_insn "*cmp_siqi_trunc"
3207 [(set (reg:CC CC_REG)
3208 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3211 "andcc\t%0, 0xff, %%g0"
3212 [(set_attr "type" "compare")])
3214 (define_insn "*cmp_siqi_trunc_set"
3215 [(set (reg:CC CC_REG)
3216 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3218 (set (match_operand:QI 0 "register_operand" "=r")
3219 (subreg:QI (match_dup 1) 3))]
3221 "andcc\t%1, 0xff, %0"
3222 [(set_attr "type" "compare")])
3224 (define_insn "*cmp_diqi_trunc"
3225 [(set (reg:CC CC_REG)
3226 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3229 "andcc\t%0, 0xff, %%g0"
3230 [(set_attr "type" "compare")])
3232 (define_insn "*cmp_diqi_trunc_set"
3233 [(set (reg:CC CC_REG)
3234 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3236 (set (match_operand:QI 0 "register_operand" "=r")
3237 (subreg:QI (match_dup 1) 7))]
3239 "andcc\t%1, 0xff, %0"
3240 [(set_attr "type" "compare")])
3243 ;; Sign-extension instructions
3245 ;; These patterns originally accepted general_operands, however, slightly
3246 ;; better code is generated by only accepting register_operands, and then
3247 ;; letting combine generate the lds[hb] insns.
3249 (define_expand "extendhisi2"
3250 [(set (match_operand:SI 0 "register_operand" "")
3251 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3254 rtx temp = gen_reg_rtx (SImode);
3255 rtx shift_16 = GEN_INT (16);
3256 int op1_subbyte = 0;
3258 if (GET_CODE (operand1) == SUBREG)
3260 op1_subbyte = SUBREG_BYTE (operand1);
3261 op1_subbyte /= GET_MODE_SIZE (SImode);
3262 op1_subbyte *= GET_MODE_SIZE (SImode);
3263 operand1 = XEXP (operand1, 0);
3266 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3268 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3272 (define_insn "*sign_extendhisi2_insn"
3273 [(set (match_operand:SI 0 "register_operand" "=r")
3274 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3277 [(set_attr "type" "sload")
3278 (set_attr "us3load_type" "3cycle")])
3280 (define_expand "extendqihi2"
3281 [(set (match_operand:HI 0 "register_operand" "")
3282 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3285 rtx temp = gen_reg_rtx (SImode);
3286 rtx shift_24 = GEN_INT (24);
3287 int op1_subbyte = 0;
3288 int op0_subbyte = 0;
3290 if (GET_CODE (operand1) == SUBREG)
3292 op1_subbyte = SUBREG_BYTE (operand1);
3293 op1_subbyte /= GET_MODE_SIZE (SImode);
3294 op1_subbyte *= GET_MODE_SIZE (SImode);
3295 operand1 = XEXP (operand1, 0);
3297 if (GET_CODE (operand0) == SUBREG)
3299 op0_subbyte = SUBREG_BYTE (operand0);
3300 op0_subbyte /= GET_MODE_SIZE (SImode);
3301 op0_subbyte *= GET_MODE_SIZE (SImode);
3302 operand0 = XEXP (operand0, 0);
3304 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3306 if (GET_MODE (operand0) != SImode)
3307 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3308 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3312 (define_insn "*sign_extendqihi2_insn"
3313 [(set (match_operand:HI 0 "register_operand" "=r")
3314 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3317 [(set_attr "type" "sload")
3318 (set_attr "us3load_type" "3cycle")])
3320 (define_expand "extendqisi2"
3321 [(set (match_operand:SI 0 "register_operand" "")
3322 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3325 rtx temp = gen_reg_rtx (SImode);
3326 rtx shift_24 = GEN_INT (24);
3327 int op1_subbyte = 0;
3329 if (GET_CODE (operand1) == SUBREG)
3331 op1_subbyte = SUBREG_BYTE (operand1);
3332 op1_subbyte /= GET_MODE_SIZE (SImode);
3333 op1_subbyte *= GET_MODE_SIZE (SImode);
3334 operand1 = XEXP (operand1, 0);
3337 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3339 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3343 (define_insn "*sign_extendqisi2_insn"
3344 [(set (match_operand:SI 0 "register_operand" "=r")
3345 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3348 [(set_attr "type" "sload")
3349 (set_attr "us3load_type" "3cycle")])
3351 (define_expand "extendqidi2"
3352 [(set (match_operand:DI 0 "register_operand" "")
3353 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3356 rtx temp = gen_reg_rtx (DImode);
3357 rtx shift_56 = GEN_INT (56);
3358 int op1_subbyte = 0;
3360 if (GET_CODE (operand1) == SUBREG)
3362 op1_subbyte = SUBREG_BYTE (operand1);
3363 op1_subbyte /= GET_MODE_SIZE (DImode);
3364 op1_subbyte *= GET_MODE_SIZE (DImode);
3365 operand1 = XEXP (operand1, 0);
3368 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3370 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3374 (define_insn "*sign_extendqidi2_insn"
3375 [(set (match_operand:DI 0 "register_operand" "=r")
3376 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3379 [(set_attr "type" "sload")
3380 (set_attr "us3load_type" "3cycle")])
3382 (define_expand "extendhidi2"
3383 [(set (match_operand:DI 0 "register_operand" "")
3384 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3387 rtx temp = gen_reg_rtx (DImode);
3388 rtx shift_48 = GEN_INT (48);
3389 int op1_subbyte = 0;
3391 if (GET_CODE (operand1) == SUBREG)
3393 op1_subbyte = SUBREG_BYTE (operand1);
3394 op1_subbyte /= GET_MODE_SIZE (DImode);
3395 op1_subbyte *= GET_MODE_SIZE (DImode);
3396 operand1 = XEXP (operand1, 0);
3399 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3401 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3405 (define_insn "*sign_extendhidi2_insn"
3406 [(set (match_operand:DI 0 "register_operand" "=r")
3407 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3410 [(set_attr "type" "sload")
3411 (set_attr "us3load_type" "3cycle")])
3413 (define_expand "extendsidi2"
3414 [(set (match_operand:DI 0 "register_operand" "")
3415 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3419 (define_insn "*sign_extendsidi2_insn"
3420 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3421 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3427 [(set_attr "type" "shift,sload,*")
3428 (set_attr "us3load_type" "*,3cycle,*")
3429 (set_attr "cpu_feature" "*,*,vis3")])
3432 ;; Special pattern for optimizing bit-field compares. This is needed
3433 ;; because combine uses this as a canonical form.
3435 (define_insn "*cmp_zero_extract"
3436 [(set (reg:CC CC_REG)
3438 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3439 (match_operand:SI 1 "small_int_operand" "I")
3440 (match_operand:SI 2 "small_int_operand" "I"))
3442 "INTVAL (operands[2]) > 19"
3444 int len = INTVAL (operands[1]);
3445 int pos = 32 - INTVAL (operands[2]) - len;
3446 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3447 operands[1] = GEN_INT (mask);
3448 return "andcc\t%0, %1, %%g0";
3450 [(set_attr "type" "compare")])
3452 (define_insn "*cmp_zero_extract_sp64"
3453 [(set (reg:CCX CC_REG)
3455 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3456 (match_operand:SI 1 "small_int_operand" "I")
3457 (match_operand:SI 2 "small_int_operand" "I"))
3459 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3461 int len = INTVAL (operands[1]);
3462 int pos = 64 - INTVAL (operands[2]) - len;
3463 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3464 operands[1] = GEN_INT (mask);
3465 return "andcc\t%0, %1, %%g0";
3467 [(set_attr "type" "compare")])
3470 ;; Conversions between float, double and long double.
3472 (define_insn "extendsfdf2"
3473 [(set (match_operand:DF 0 "register_operand" "=e")
3475 (match_operand:SF 1 "register_operand" "f")))]
3478 [(set_attr "type" "fp")
3479 (set_attr "fptype" "double")])
3481 (define_expand "extendsftf2"
3482 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3484 (match_operand:SF 1 "register_operand" "")))]
3485 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3486 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3488 (define_insn "*extendsftf2_hq"
3489 [(set (match_operand:TF 0 "register_operand" "=e")
3491 (match_operand:SF 1 "register_operand" "f")))]
3492 "TARGET_FPU && TARGET_HARD_QUAD"
3494 [(set_attr "type" "fp")])
3496 (define_expand "extenddftf2"
3497 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3499 (match_operand:DF 1 "register_operand" "")))]
3500 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3501 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3503 (define_insn "*extenddftf2_hq"
3504 [(set (match_operand:TF 0 "register_operand" "=e")
3506 (match_operand:DF 1 "register_operand" "e")))]
3507 "TARGET_FPU && TARGET_HARD_QUAD"
3509 [(set_attr "type" "fp")])
3511 (define_insn "truncdfsf2"
3512 [(set (match_operand:SF 0 "register_operand" "=f")
3514 (match_operand:DF 1 "register_operand" "e")))]
3517 [(set_attr "type" "fp")
3518 (set_attr "fptype" "double")])
3520 (define_expand "trunctfsf2"
3521 [(set (match_operand:SF 0 "register_operand" "")
3523 (match_operand:TF 1 "general_operand" "")))]
3524 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3525 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3527 (define_insn "*trunctfsf2_hq"
3528 [(set (match_operand:SF 0 "register_operand" "=f")
3530 (match_operand:TF 1 "register_operand" "e")))]
3531 "TARGET_FPU && TARGET_HARD_QUAD"
3533 [(set_attr "type" "fp")])
3535 (define_expand "trunctfdf2"
3536 [(set (match_operand:DF 0 "register_operand" "")
3538 (match_operand:TF 1 "general_operand" "")))]
3539 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3540 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3542 (define_insn "*trunctfdf2_hq"
3543 [(set (match_operand:DF 0 "register_operand" "=e")
3545 (match_operand:TF 1 "register_operand" "e")))]
3546 "TARGET_FPU && TARGET_HARD_QUAD"
3548 [(set_attr "type" "fp")])
3551 ;; Conversion between fixed point and floating point.
3553 (define_insn "floatsisf2"
3554 [(set (match_operand:SF 0 "register_operand" "=f")
3555 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3558 [(set_attr "type" "fp")
3559 (set_attr "fptype" "double")])
3561 (define_insn "floatsidf2"
3562 [(set (match_operand:DF 0 "register_operand" "=e")
3563 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3566 [(set_attr "type" "fp")
3567 (set_attr "fptype" "double")])
3569 (define_expand "floatsitf2"
3570 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3571 (float:TF (match_operand:SI 1 "register_operand" "")))]
3572 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3573 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3575 (define_insn "*floatsitf2_hq"
3576 [(set (match_operand:TF 0 "register_operand" "=e")
3577 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3578 "TARGET_FPU && TARGET_HARD_QUAD"
3580 [(set_attr "type" "fp")])
3582 (define_expand "floatunssitf2"
3583 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3584 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3585 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3586 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3588 ;; Now the same for 64 bit sources.
3590 (define_insn "floatdisf2"
3591 [(set (match_operand:SF 0 "register_operand" "=f")
3592 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3593 "TARGET_V9 && TARGET_FPU"
3595 [(set_attr "type" "fp")
3596 (set_attr "fptype" "double")])
3598 (define_expand "floatunsdisf2"
3599 [(use (match_operand:SF 0 "register_operand" ""))
3600 (use (match_operand:DI 1 "general_operand" ""))]
3601 "TARGET_ARCH64 && TARGET_FPU"
3602 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3604 (define_insn "floatdidf2"
3605 [(set (match_operand:DF 0 "register_operand" "=e")
3606 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3607 "TARGET_V9 && TARGET_FPU"
3609 [(set_attr "type" "fp")
3610 (set_attr "fptype" "double")])
3612 (define_expand "floatunsdidf2"
3613 [(use (match_operand:DF 0 "register_operand" ""))
3614 (use (match_operand:DI 1 "general_operand" ""))]
3615 "TARGET_ARCH64 && TARGET_FPU"
3616 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3618 (define_expand "floatditf2"
3619 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3620 (float:TF (match_operand:DI 1 "register_operand" "")))]
3621 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3622 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3624 (define_insn "*floatditf2_hq"
3625 [(set (match_operand:TF 0 "register_operand" "=e")
3626 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3627 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3629 [(set_attr "type" "fp")])
3631 (define_expand "floatunsditf2"
3632 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3633 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3634 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3635 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3637 ;; Convert a float to an actual integer.
3638 ;; Truncation is performed as part of the conversion.
3640 (define_insn "fix_truncsfsi2"
3641 [(set (match_operand:SI 0 "register_operand" "=f")
3642 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3645 [(set_attr "type" "fp")
3646 (set_attr "fptype" "double")])
3648 (define_insn "fix_truncdfsi2"
3649 [(set (match_operand:SI 0 "register_operand" "=f")
3650 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3653 [(set_attr "type" "fp")
3654 (set_attr "fptype" "double")])
3656 (define_expand "fix_trunctfsi2"
3657 [(set (match_operand:SI 0 "register_operand" "")
3658 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3659 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3660 "emit_tfmode_cvt (FIX, operands); DONE;")
3662 (define_insn "*fix_trunctfsi2_hq"
3663 [(set (match_operand:SI 0 "register_operand" "=f")
3664 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3665 "TARGET_FPU && TARGET_HARD_QUAD"
3667 [(set_attr "type" "fp")])
3669 (define_expand "fixuns_trunctfsi2"
3670 [(set (match_operand:SI 0 "register_operand" "")
3671 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3672 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3673 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3675 ;; Now the same, for V9 targets
3677 (define_insn "fix_truncsfdi2"
3678 [(set (match_operand:DI 0 "register_operand" "=e")
3679 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3680 "TARGET_V9 && TARGET_FPU"
3682 [(set_attr "type" "fp")
3683 (set_attr "fptype" "double")])
3685 (define_expand "fixuns_truncsfdi2"
3686 [(use (match_operand:DI 0 "register_operand" ""))
3687 (use (match_operand:SF 1 "general_operand" ""))]
3688 "TARGET_ARCH64 && TARGET_FPU"
3689 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3691 (define_insn "fix_truncdfdi2"
3692 [(set (match_operand:DI 0 "register_operand" "=e")
3693 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3694 "TARGET_V9 && TARGET_FPU"
3696 [(set_attr "type" "fp")
3697 (set_attr "fptype" "double")])
3699 (define_expand "fixuns_truncdfdi2"
3700 [(use (match_operand:DI 0 "register_operand" ""))
3701 (use (match_operand:DF 1 "general_operand" ""))]
3702 "TARGET_ARCH64 && TARGET_FPU"
3703 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3705 (define_expand "fix_trunctfdi2"
3706 [(set (match_operand:DI 0 "register_operand" "")
3707 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3708 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3709 "emit_tfmode_cvt (FIX, operands); DONE;")
3711 (define_insn "*fix_trunctfdi2_hq"
3712 [(set (match_operand:DI 0 "register_operand" "=e")
3713 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3714 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3716 [(set_attr "type" "fp")])
3718 (define_expand "fixuns_trunctfdi2"
3719 [(set (match_operand:DI 0 "register_operand" "")
3720 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3721 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3722 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3725 ;; Integer addition/subtraction instructions.
3727 (define_expand "adddi3"
3728 [(set (match_operand:DI 0 "register_operand" "")
3729 (plus:DI (match_operand:DI 1 "register_operand" "")
3730 (match_operand:DI 2 "arith_double_add_operand" "")))]
3733 if (! TARGET_ARCH64)
3735 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3736 gen_rtx_SET (VOIDmode, operands[0],
3737 gen_rtx_PLUS (DImode, operands[1],
3739 gen_rtx_CLOBBER (VOIDmode,
3740 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3745 (define_insn_and_split "*adddi3_insn_sp32"
3746 [(set (match_operand:DI 0 "register_operand" "=&r")
3747 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3748 (match_operand:DI 2 "arith_double_operand" "rHI")))
3749 (clobber (reg:CC CC_REG))]
3752 "&& reload_completed"
3753 [(parallel [(set (reg:CC_NOOV CC_REG)
3754 (compare:CC_NOOV (plus:SI (match_dup 4)
3758 (plus:SI (match_dup 4) (match_dup 5)))])
3760 (plus:SI (plus:SI (match_dup 7)
3762 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3764 operands[3] = gen_lowpart (SImode, operands[0]);
3765 operands[4] = gen_lowpart (SImode, operands[1]);
3766 operands[5] = gen_lowpart (SImode, operands[2]);
3767 operands[6] = gen_highpart (SImode, operands[0]);
3768 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3769 #if HOST_BITS_PER_WIDE_INT == 32
3770 if (GET_CODE (operands[2]) == CONST_INT)
3772 if (INTVAL (operands[2]) < 0)
3773 operands[8] = constm1_rtx;
3775 operands[8] = const0_rtx;
3779 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3781 [(set_attr "length" "2")])
3783 ;; LTU here means "carry set"
3785 [(set (match_operand:SI 0 "register_operand" "=r")
3786 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3787 (match_operand:SI 2 "arith_operand" "rI"))
3788 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3791 [(set_attr "type" "ialuX")])
3793 (define_insn "addxc"
3794 [(set (match_operand:DI 0 "register_operand" "=r")
3795 (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
3796 (match_operand:DI 2 "register_or_zero_operand" "rJ"))
3797 (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3798 "TARGET_ARCH64 && TARGET_VIS3"
3799 "addxc\t%r1, %r2, %0"
3800 [(set_attr "type" "ialuX")])
3802 (define_insn_and_split "*addx_extend_sp32"
3803 [(set (match_operand:DI 0 "register_operand" "=r")
3804 (zero_extend:DI (plus:SI (plus:SI
3805 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3806 (match_operand:SI 2 "arith_operand" "rI"))
3807 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3810 "&& reload_completed"
3811 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3812 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3813 (set (match_dup 4) (const_int 0))]
3814 "operands[3] = gen_lowpart (SImode, operands[0]);
3815 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3816 [(set_attr "length" "2")])
3818 (define_insn "*addx_extend_sp64"
3819 [(set (match_operand:DI 0 "register_operand" "=r")
3820 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3821 (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3822 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3824 "addx\t%r1, %r2, %0"
3825 [(set_attr "type" "ialuX")])
3827 (define_insn "*addxc_trunc_sp64_vis3"
3828 [(set (match_operand:SI 0 "register_operand" "=r")
3829 (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3830 (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3831 (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3832 "TARGET_ARCH64 && TARGET_VIS3"
3833 "addxc\t%r1, %r2, %0"
3834 [(set_attr "type" "ialuX")])
3836 (define_insn_and_split "*adddi3_extend_sp32"
3837 [(set (match_operand:DI 0 "register_operand" "=r")
3838 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3839 (match_operand:DI 2 "register_operand" "r")))
3840 (clobber (reg:CC CC_REG))]
3843 "&& reload_completed"
3844 [(parallel [(set (reg:CC_NOOV CC_REG)
3845 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3847 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3849 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3850 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3851 "operands[3] = gen_lowpart (SImode, operands[2]);
3852 operands[4] = gen_highpart (SImode, operands[2]);
3853 operands[5] = gen_lowpart (SImode, operands[0]);
3854 operands[6] = gen_highpart (SImode, operands[0]);"
3855 [(set_attr "length" "2")])
3857 (define_insn "*adddi3_sp64"
3858 [(set (match_operand:DI 0 "register_operand" "=r,r")
3859 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3860 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3866 (define_insn "addsi3"
3867 [(set (match_operand:SI 0 "register_operand" "=r,r")
3868 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3869 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3874 [(set_attr "type" "*,*")
3875 (set_attr "fptype" "*,*")])
3877 (define_insn "*cmp_cc_plus"
3878 [(set (reg:CC_NOOV CC_REG)
3879 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3880 (match_operand:SI 1 "arith_operand" "rI"))
3883 "addcc\t%0, %1, %%g0"
3884 [(set_attr "type" "compare")])
3886 (define_insn "*cmp_ccx_plus"
3887 [(set (reg:CCX_NOOV CC_REG)
3888 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3889 (match_operand:DI 1 "arith_operand" "rI"))
3892 "addcc\t%0, %1, %%g0"
3893 [(set_attr "type" "compare")])
3895 (define_insn "*cmp_cc_plus_set"
3896 [(set (reg:CC_NOOV CC_REG)
3897 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3898 (match_operand:SI 2 "arith_operand" "rI"))
3900 (set (match_operand:SI 0 "register_operand" "=r")
3901 (plus:SI (match_dup 1) (match_dup 2)))]
3904 [(set_attr "type" "compare")])
3906 (define_insn "*cmp_ccx_plus_set"
3907 [(set (reg:CCX_NOOV CC_REG)
3908 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3909 (match_operand:DI 2 "arith_operand" "rI"))
3911 (set (match_operand:DI 0 "register_operand" "=r")
3912 (plus:DI (match_dup 1) (match_dup 2)))]
3915 [(set_attr "type" "compare")])
3917 (define_expand "subdi3"
3918 [(set (match_operand:DI 0 "register_operand" "")
3919 (minus:DI (match_operand:DI 1 "register_operand" "")
3920 (match_operand:DI 2 "arith_double_add_operand" "")))]
3923 if (! TARGET_ARCH64)
3925 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3926 gen_rtx_SET (VOIDmode, operands[0],
3927 gen_rtx_MINUS (DImode, operands[1],
3929 gen_rtx_CLOBBER (VOIDmode,
3930 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3935 (define_insn_and_split "*subdi3_insn_sp32"
3936 [(set (match_operand:DI 0 "register_operand" "=r")
3937 (minus:DI (match_operand:DI 1 "register_operand" "r")
3938 (match_operand:DI 2 "arith_double_operand" "rHI")))
3939 (clobber (reg:CC CC_REG))]
3942 "&& reload_completed"
3943 [(parallel [(set (reg:CC_NOOV CC_REG)
3944 (compare:CC_NOOV (minus:SI (match_dup 4)
3948 (minus:SI (match_dup 4) (match_dup 5)))])
3950 (minus:SI (minus:SI (match_dup 7)
3952 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3954 operands[3] = gen_lowpart (SImode, operands[0]);
3955 operands[4] = gen_lowpart (SImode, operands[1]);
3956 operands[5] = gen_lowpart (SImode, operands[2]);
3957 operands[6] = gen_highpart (SImode, operands[0]);
3958 operands[7] = gen_highpart (SImode, operands[1]);
3959 #if HOST_BITS_PER_WIDE_INT == 32
3960 if (GET_CODE (operands[2]) == CONST_INT)
3962 if (INTVAL (operands[2]) < 0)
3963 operands[8] = constm1_rtx;
3965 operands[8] = const0_rtx;
3969 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3971 [(set_attr "length" "2")])
3973 ;; LTU here means "carry set"
3975 [(set (match_operand:SI 0 "register_operand" "=r")
3976 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3977 (match_operand:SI 2 "arith_operand" "rI"))
3978 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3981 [(set_attr "type" "ialuX")])
3983 (define_insn "*subx_extend_sp64"
3984 [(set (match_operand:DI 0 "register_operand" "=r")
3985 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3986 (match_operand:SI 2 "arith_operand" "rI"))
3987 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3990 [(set_attr "type" "ialuX")])
3992 (define_insn_and_split "*subx_extend"
3993 [(set (match_operand:DI 0 "register_operand" "=r")
3994 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3995 (match_operand:SI 2 "arith_operand" "rI"))
3996 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3999 "&& reload_completed"
4000 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4001 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
4002 (set (match_dup 4) (const_int 0))]
4003 "operands[3] = gen_lowpart (SImode, operands[0]);
4004 operands[4] = gen_highpart (SImode, operands[0]);"
4005 [(set_attr "length" "2")])
4007 (define_insn_and_split "*subdi3_extend_sp32"
4008 [(set (match_operand:DI 0 "register_operand" "=r")
4009 (minus:DI (match_operand:DI 1 "register_operand" "r")
4010 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4011 (clobber (reg:CC CC_REG))]
4014 "&& reload_completed"
4015 [(parallel [(set (reg:CC_NOOV CC_REG)
4016 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4018 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4020 (minus:SI (minus:SI (match_dup 4) (const_int 0))
4021 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
4022 "operands[3] = gen_lowpart (SImode, operands[1]);
4023 operands[4] = gen_highpart (SImode, operands[1]);
4024 operands[5] = gen_lowpart (SImode, operands[0]);
4025 operands[6] = gen_highpart (SImode, operands[0]);"
4026 [(set_attr "length" "2")])
4028 (define_insn "*subdi3_sp64"
4029 [(set (match_operand:DI 0 "register_operand" "=r,r")
4030 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4031 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4037 (define_insn "subsi3"
4038 [(set (match_operand:SI 0 "register_operand" "=r,r")
4039 (minus:SI (match_operand:SI 1 "register_operand" "r,r")
4040 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
4045 [(set_attr "type" "*,*")
4046 (set_attr "fptype" "*,*")])
4048 (define_insn "*cmp_minus_cc"
4049 [(set (reg:CC_NOOV CC_REG)
4050 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4051 (match_operand:SI 1 "arith_operand" "rI"))
4054 "subcc\t%r0, %1, %%g0"
4055 [(set_attr "type" "compare")])
4057 (define_insn "*cmp_minus_ccx"
4058 [(set (reg:CCX_NOOV CC_REG)
4059 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4060 (match_operand:DI 1 "arith_operand" "rI"))
4063 "subcc\t%0, %1, %%g0"
4064 [(set_attr "type" "compare")])
4066 (define_insn "cmp_minus_cc_set"
4067 [(set (reg:CC_NOOV CC_REG)
4068 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4069 (match_operand:SI 2 "arith_operand" "rI"))
4071 (set (match_operand:SI 0 "register_operand" "=r")
4072 (minus:SI (match_dup 1) (match_dup 2)))]
4074 "subcc\t%r1, %2, %0"
4075 [(set_attr "type" "compare")])
4077 (define_insn "*cmp_minus_ccx_set"
4078 [(set (reg:CCX_NOOV CC_REG)
4079 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4080 (match_operand:DI 2 "arith_operand" "rI"))
4082 (set (match_operand:DI 0 "register_operand" "=r")
4083 (minus:DI (match_dup 1) (match_dup 2)))]
4086 [(set_attr "type" "compare")])
4089 ;; Integer multiply/divide instructions.
4091 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4092 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4094 (define_insn "mulsi3"
4095 [(set (match_operand:SI 0 "register_operand" "=r")
4096 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4097 (match_operand:SI 2 "arith_operand" "rI")))]
4100 [(set_attr "type" "imul")])
4102 (define_expand "muldi3"
4103 [(set (match_operand:DI 0 "register_operand" "")
4104 (mult:DI (match_operand:DI 1 "arith_operand" "")
4105 (match_operand:DI 2 "arith_operand" "")))]
4106 "TARGET_ARCH64 || TARGET_V8PLUS"
4110 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4115 (define_insn "*muldi3_sp64"
4116 [(set (match_operand:DI 0 "register_operand" "=r")
4117 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4118 (match_operand:DI 2 "arith_operand" "rI")))]
4121 [(set_attr "type" "imul")])
4123 ;; V8plus wide multiply.
4125 (define_insn "muldi3_v8plus"
4126 [(set (match_operand:DI 0 "register_operand" "=r,h")
4127 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4128 (match_operand:DI 2 "arith_operand" "rI,rI")))
4129 (clobber (match_scratch:SI 3 "=&h,X"))
4130 (clobber (match_scratch:SI 4 "=&h,X"))]
4132 "* return output_v8plus_mult (insn, operands, \"mulx\");"
4133 [(set_attr "type" "multi")
4134 (set_attr "length" "9,8")])
4136 (define_insn "*cmp_mul_set"
4137 [(set (reg:CC CC_REG)
4138 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4139 (match_operand:SI 2 "arith_operand" "rI"))
4141 (set (match_operand:SI 0 "register_operand" "=r")
4142 (mult:SI (match_dup 1) (match_dup 2)))]
4143 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4144 "smulcc\t%1, %2, %0"
4145 [(set_attr "type" "imul")])
4147 (define_expand "mulsidi3"
4148 [(set (match_operand:DI 0 "register_operand" "")
4149 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4150 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4153 if (CONSTANT_P (operands[2]))
4156 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4158 else if (TARGET_ARCH32)
4159 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4162 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4168 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4173 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4174 ;; registers can hold 64-bit values in the V8plus environment.
4176 (define_insn "mulsidi3_v8plus"
4177 [(set (match_operand:DI 0 "register_operand" "=h,r")
4178 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4179 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4180 (clobber (match_scratch:SI 3 "=X,&h"))]
4183 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4184 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4185 [(set_attr "type" "multi")
4186 (set_attr "length" "2,3")])
4189 (define_insn "const_mulsidi3_v8plus"
4190 [(set (match_operand:DI 0 "register_operand" "=h,r")
4191 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4192 (match_operand:DI 2 "small_int_operand" "I,I")))
4193 (clobber (match_scratch:SI 3 "=X,&h"))]
4196 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4197 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4198 [(set_attr "type" "multi")
4199 (set_attr "length" "2,3")])
4202 (define_insn "*mulsidi3_sp32"
4203 [(set (match_operand:DI 0 "register_operand" "=r")
4204 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4205 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4208 return TARGET_SPARCLET
4209 ? "smuld\t%1, %2, %L0"
4210 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4213 (if_then_else (eq_attr "isa" "sparclet")
4214 (const_string "imul") (const_string "multi")))
4215 (set (attr "length")
4216 (if_then_else (eq_attr "isa" "sparclet")
4217 (const_int 1) (const_int 2)))])
4219 (define_insn "*mulsidi3_sp64"
4220 [(set (match_operand:DI 0 "register_operand" "=r")
4221 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4222 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4223 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4225 [(set_attr "type" "imul")])
4227 ;; Extra pattern, because sign_extend of a constant isn't valid.
4230 (define_insn "const_mulsidi3_sp32"
4231 [(set (match_operand:DI 0 "register_operand" "=r")
4232 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4233 (match_operand:DI 2 "small_int_operand" "I")))]
4236 return TARGET_SPARCLET
4237 ? "smuld\t%1, %2, %L0"
4238 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4241 (if_then_else (eq_attr "isa" "sparclet")
4242 (const_string "imul") (const_string "multi")))
4243 (set (attr "length")
4244 (if_then_else (eq_attr "isa" "sparclet")
4245 (const_int 1) (const_int 2)))])
4247 (define_insn "const_mulsidi3_sp64"
4248 [(set (match_operand:DI 0 "register_operand" "=r")
4249 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4250 (match_operand:DI 2 "small_int_operand" "I")))]
4251 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4253 [(set_attr "type" "imul")])
4255 (define_expand "smulsi3_highpart"
4256 [(set (match_operand:SI 0 "register_operand" "")
4258 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4259 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4261 "TARGET_HARD_MUL && TARGET_ARCH32"
4263 if (CONSTANT_P (operands[2]))
4267 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4273 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4278 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4279 operands[2], GEN_INT (32)));
4285 (define_insn "smulsi3_highpart_v8plus"
4286 [(set (match_operand:SI 0 "register_operand" "=h,r")
4288 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4289 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4290 (match_operand:SI 3 "small_int_operand" "I,I"))))
4291 (clobber (match_scratch:SI 4 "=X,&h"))]
4294 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4295 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4296 [(set_attr "type" "multi")
4297 (set_attr "length" "2")])
4299 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4302 [(set (match_operand:SI 0 "register_operand" "=h,r")
4305 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4306 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4307 (match_operand:SI 3 "small_int_operand" "I,I"))
4309 (clobber (match_scratch:SI 4 "=X,&h"))]
4312 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4313 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4314 [(set_attr "type" "multi")
4315 (set_attr "length" "2")])
4318 (define_insn "const_smulsi3_highpart_v8plus"
4319 [(set (match_operand:SI 0 "register_operand" "=h,r")
4321 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4322 (match_operand:DI 2 "small_int_operand" "I,I"))
4323 (match_operand:SI 3 "small_int_operand" "I,I"))))
4324 (clobber (match_scratch:SI 4 "=X,&h"))]
4327 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4328 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4329 [(set_attr "type" "multi")
4330 (set_attr "length" "2")])
4333 (define_insn "*smulsi3_highpart_sp32"
4334 [(set (match_operand:SI 0 "register_operand" "=r")
4336 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4337 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4340 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4341 [(set_attr "type" "multi")
4342 (set_attr "length" "2")])
4345 (define_insn "const_smulsi3_highpart"
4346 [(set (match_operand:SI 0 "register_operand" "=r")
4348 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4349 (match_operand:DI 2 "small_int_operand" "i"))
4352 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4353 [(set_attr "type" "multi")
4354 (set_attr "length" "2")])
4356 (define_expand "umulsidi3"
4357 [(set (match_operand:DI 0 "register_operand" "")
4358 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4359 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4362 if (CONSTANT_P (operands[2]))
4365 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4367 else if (TARGET_ARCH32)
4368 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4371 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4377 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4383 (define_insn "umulsidi3_v8plus"
4384 [(set (match_operand:DI 0 "register_operand" "=h,r")
4385 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4386 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4387 (clobber (match_scratch:SI 3 "=X,&h"))]
4390 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4391 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4392 [(set_attr "type" "multi")
4393 (set_attr "length" "2,3")])
4396 (define_insn "*umulsidi3_sp32"
4397 [(set (match_operand:DI 0 "register_operand" "=r")
4398 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4399 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4402 return TARGET_SPARCLET
4403 ? "umuld\t%1, %2, %L0"
4404 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4407 (if_then_else (eq_attr "isa" "sparclet")
4408 (const_string "imul") (const_string "multi")))
4409 (set (attr "length")
4410 (if_then_else (eq_attr "isa" "sparclet")
4411 (const_int 1) (const_int 2)))])
4413 (define_insn "*umulsidi3_sp64"
4414 [(set (match_operand:DI 0 "register_operand" "=r")
4415 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4416 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4417 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4419 [(set_attr "type" "imul")])
4421 ;; Extra pattern, because sign_extend of a constant isn't valid.
4424 (define_insn "const_umulsidi3_sp32"
4425 [(set (match_operand:DI 0 "register_operand" "=r")
4426 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4427 (match_operand:DI 2 "uns_small_int_operand" "")))]
4430 return TARGET_SPARCLET
4431 ? "umuld\t%1, %s2, %L0"
4432 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4435 (if_then_else (eq_attr "isa" "sparclet")
4436 (const_string "imul") (const_string "multi")))
4437 (set (attr "length")
4438 (if_then_else (eq_attr "isa" "sparclet")
4439 (const_int 1) (const_int 2)))])
4441 (define_insn "const_umulsidi3_sp64"
4442 [(set (match_operand:DI 0 "register_operand" "=r")
4443 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4444 (match_operand:DI 2 "uns_small_int_operand" "")))]
4445 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4447 [(set_attr "type" "imul")])
4450 (define_insn "const_umulsidi3_v8plus"
4451 [(set (match_operand:DI 0 "register_operand" "=h,r")
4452 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4453 (match_operand:DI 2 "uns_small_int_operand" "")))
4454 (clobber (match_scratch:SI 3 "=X,h"))]
4457 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4458 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4459 [(set_attr "type" "multi")
4460 (set_attr "length" "2,3")])
4462 (define_expand "umulsi3_highpart"
4463 [(set (match_operand:SI 0 "register_operand" "")
4465 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4466 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4468 "TARGET_HARD_MUL && TARGET_ARCH32"
4470 if (CONSTANT_P (operands[2]))
4474 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4480 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4485 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4486 operands[2], GEN_INT (32)));
4492 (define_insn "umulsi3_highpart_v8plus"
4493 [(set (match_operand:SI 0 "register_operand" "=h,r")
4495 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4496 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4497 (match_operand:SI 3 "small_int_operand" "I,I"))))
4498 (clobber (match_scratch:SI 4 "=X,h"))]
4501 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4502 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4503 [(set_attr "type" "multi")
4504 (set_attr "length" "2")])
4507 (define_insn "const_umulsi3_highpart_v8plus"
4508 [(set (match_operand:SI 0 "register_operand" "=h,r")
4510 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4511 (match_operand:DI 2 "uns_small_int_operand" ""))
4512 (match_operand:SI 3 "small_int_operand" "I,I"))))
4513 (clobber (match_scratch:SI 4 "=X,h"))]
4516 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4517 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4518 [(set_attr "type" "multi")
4519 (set_attr "length" "2")])
4522 (define_insn "*umulsi3_highpart_sp32"
4523 [(set (match_operand:SI 0 "register_operand" "=r")
4525 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4526 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4529 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4530 [(set_attr "type" "multi")
4531 (set_attr "length" "2")])
4534 (define_insn "const_umulsi3_highpart"
4535 [(set (match_operand:SI 0 "register_operand" "=r")
4537 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4538 (match_operand:DI 2 "uns_small_int_operand" ""))
4541 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4542 [(set_attr "type" "multi")
4543 (set_attr "length" "2")])
4545 (define_expand "divsi3"
4546 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4547 (div:SI (match_operand:SI 1 "register_operand" "")
4548 (match_operand:SI 2 "input_operand" "")))
4549 (clobber (match_scratch:SI 3 ""))])]
4550 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4554 operands[3] = gen_reg_rtx(SImode);
4555 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4556 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4562 ;; The V8 architecture specifies that there must be at least 3 instructions
4563 ;; between a write to the Y register and a use of it for correct results.
4564 ;; We try to fill one of them with a simple constant or a memory load.
4566 (define_insn "divsi3_sp32"
4567 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4568 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4569 (match_operand:SI 2 "input_operand" "rI,K,m")))
4570 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4571 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4573 output_asm_insn ("sra\t%1, 31, %3", operands);
4574 output_asm_insn ("wr\t%3, 0, %%y", operands);
4576 switch (which_alternative)
4580 return "sdiv\t%1, %2, %0";
4582 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4585 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4587 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4590 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4592 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4597 [(set_attr "type" "multi")
4598 (set (attr "length")
4599 (if_then_else (eq_attr "isa" "v9")
4600 (const_int 4) (const_int 6)))])
4602 (define_insn "divsi3_sp64"
4603 [(set (match_operand:SI 0 "register_operand" "=r")
4604 (div:SI (match_operand:SI 1 "register_operand" "r")
4605 (match_operand:SI 2 "input_operand" "rI")))
4606 (use (match_operand:SI 3 "register_operand" "r"))]
4607 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4608 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4609 [(set_attr "type" "multi")
4610 (set_attr "length" "2")])
4612 (define_insn "divdi3"
4613 [(set (match_operand:DI 0 "register_operand" "=r")
4614 (div:DI (match_operand:DI 1 "register_operand" "r")
4615 (match_operand:DI 2 "arith_operand" "rI")))]
4618 [(set_attr "type" "idiv")])
4620 (define_insn "*cmp_sdiv_cc_set"
4621 [(set (reg:CC CC_REG)
4622 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4623 (match_operand:SI 2 "arith_operand" "rI"))
4625 (set (match_operand:SI 0 "register_operand" "=r")
4626 (div:SI (match_dup 1) (match_dup 2)))
4627 (clobber (match_scratch:SI 3 "=&r"))]
4628 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4630 output_asm_insn ("sra\t%1, 31, %3", operands);
4631 output_asm_insn ("wr\t%3, 0, %%y", operands);
4634 return "sdivcc\t%1, %2, %0";
4636 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4638 [(set_attr "type" "multi")
4639 (set (attr "length")
4640 (if_then_else (eq_attr "isa" "v9")
4641 (const_int 3) (const_int 6)))])
4644 (define_expand "udivsi3"
4645 [(set (match_operand:SI 0 "register_operand" "")
4646 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4647 (match_operand:SI 2 "input_operand" "")))]
4648 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4651 ;; The V8 architecture specifies that there must be at least 3 instructions
4652 ;; between a write to the Y register and a use of it for correct results.
4653 ;; We try to fill one of them with a simple constant or a memory load.
4655 (define_insn "udivsi3_sp32"
4656 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4657 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4658 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4659 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4661 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4663 switch (which_alternative)
4667 return "udiv\t%1, %2, %0";
4669 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4672 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4674 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4677 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4679 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4682 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4684 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4689 [(set_attr "type" "multi")
4690 (set (attr "length")
4691 (if_then_else (eq_attr "isa" "v9")
4692 (const_int 3) (const_int 5)))])
4694 (define_insn "udivsi3_sp64"
4695 [(set (match_operand:SI 0 "register_operand" "=r")
4696 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4697 (match_operand:SI 2 "input_operand" "rI")))]
4698 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4699 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4700 [(set_attr "type" "multi")
4701 (set_attr "length" "2")])
4703 (define_insn "udivdi3"
4704 [(set (match_operand:DI 0 "register_operand" "=r")
4705 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4706 (match_operand:DI 2 "arith_operand" "rI")))]
4709 [(set_attr "type" "idiv")])
4711 (define_insn "*cmp_udiv_cc_set"
4712 [(set (reg:CC CC_REG)
4713 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4714 (match_operand:SI 2 "arith_operand" "rI"))
4716 (set (match_operand:SI 0 "register_operand" "=r")
4717 (udiv:SI (match_dup 1) (match_dup 2)))]
4718 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4720 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4723 return "udivcc\t%1, %2, %0";
4725 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4727 [(set_attr "type" "multi")
4728 (set (attr "length")
4729 (if_then_else (eq_attr "isa" "v9")
4730 (const_int 2) (const_int 5)))])
4732 ; sparclet multiply/accumulate insns
4734 (define_insn "*smacsi"
4735 [(set (match_operand:SI 0 "register_operand" "=r")
4736 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4737 (match_operand:SI 2 "arith_operand" "rI"))
4738 (match_operand:SI 3 "register_operand" "0")))]
4741 [(set_attr "type" "imul")])
4743 (define_insn "*smacdi"
4744 [(set (match_operand:DI 0 "register_operand" "=r")
4745 (plus:DI (mult:DI (sign_extend:DI
4746 (match_operand:SI 1 "register_operand" "%r"))
4748 (match_operand:SI 2 "register_operand" "r")))
4749 (match_operand:DI 3 "register_operand" "0")))]
4751 "smacd\t%1, %2, %L0"
4752 [(set_attr "type" "imul")])
4754 (define_insn "*umacdi"
4755 [(set (match_operand:DI 0 "register_operand" "=r")
4756 (plus:DI (mult:DI (zero_extend:DI
4757 (match_operand:SI 1 "register_operand" "%r"))
4759 (match_operand:SI 2 "register_operand" "r")))
4760 (match_operand:DI 3 "register_operand" "0")))]
4762 "umacd\t%1, %2, %L0"
4763 [(set_attr "type" "imul")])
4766 ;; Boolean instructions.
4768 ;; We define DImode `and' so with DImode `not' we can get
4769 ;; DImode `andn'. Other combinations are possible.
4771 (define_expand "anddi3"
4772 [(set (match_operand:DI 0 "register_operand" "")
4773 (and:DI (match_operand:DI 1 "arith_double_operand" "")
4774 (match_operand:DI 2 "arith_double_operand" "")))]
4778 (define_insn "*anddi3_sp32"
4779 [(set (match_operand:DI 0 "register_operand" "=r")
4780 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4781 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4785 (define_insn "*anddi3_sp64"
4786 [(set (match_operand:DI 0 "register_operand" "=r")
4787 (and:DI (match_operand:DI 1 "arith_operand" "%r")
4788 (match_operand:DI 2 "arith_operand" "rI")))]
4792 (define_insn "andsi3"
4793 [(set (match_operand:SI 0 "register_operand" "=r")
4794 (and:SI (match_operand:SI 1 "arith_operand" "%r")
4795 (match_operand:SI 2 "arith_operand" "rI")))]
4800 [(set (match_operand:SI 0 "register_operand" "")
4801 (and:SI (match_operand:SI 1 "register_operand" "")
4802 (match_operand:SI 2 "const_compl_high_operand" "")))
4803 (clobber (match_operand:SI 3 "register_operand" ""))]
4805 [(set (match_dup 3) (match_dup 4))
4806 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4808 operands[4] = GEN_INT (~INTVAL (operands[2]));
4811 (define_insn_and_split "*and_not_di_sp32"
4812 [(set (match_operand:DI 0 "register_operand" "=r")
4813 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4814 (match_operand:DI 2 "register_operand" "r")))]
4817 "&& reload_completed
4818 && ((GET_CODE (operands[0]) == REG
4819 && SPARC_INT_REG_P (REGNO (operands[0])))
4820 || (GET_CODE (operands[0]) == SUBREG
4821 && GET_CODE (SUBREG_REG (operands[0])) == REG
4822 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4823 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4824 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4825 "operands[3] = gen_highpart (SImode, operands[0]);
4826 operands[4] = gen_highpart (SImode, operands[1]);
4827 operands[5] = gen_highpart (SImode, operands[2]);
4828 operands[6] = gen_lowpart (SImode, operands[0]);
4829 operands[7] = gen_lowpart (SImode, operands[1]);
4830 operands[8] = gen_lowpart (SImode, operands[2]);"
4831 [(set_attr "length" "2")])
4833 (define_insn "*and_not_di_sp64"
4834 [(set (match_operand:DI 0 "register_operand" "=r")
4835 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4836 (match_operand:DI 2 "register_operand" "r")))]
4840 (define_insn "*and_not_si"
4841 [(set (match_operand:SI 0 "register_operand" "=r")
4842 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4843 (match_operand:SI 2 "register_operand" "r")))]
4847 (define_expand "iordi3"
4848 [(set (match_operand:DI 0 "register_operand" "")
4849 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4850 (match_operand:DI 2 "arith_double_operand" "")))]
4854 (define_insn "*iordi3_sp32"
4855 [(set (match_operand:DI 0 "register_operand" "=r")
4856 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4857 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4860 [(set_attr "length" "2")])
4862 (define_insn "*iordi3_sp64"
4863 [(set (match_operand:DI 0 "register_operand" "=r")
4864 (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4865 (match_operand:DI 2 "arith_operand" "rI")))]
4869 (define_insn "iorsi3"
4870 [(set (match_operand:SI 0 "register_operand" "=r")
4871 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4872 (match_operand:SI 2 "arith_operand" "rI")))]
4877 [(set (match_operand:SI 0 "register_operand" "")
4878 (ior:SI (match_operand:SI 1 "register_operand" "")
4879 (match_operand:SI 2 "const_compl_high_operand" "")))
4880 (clobber (match_operand:SI 3 "register_operand" ""))]
4882 [(set (match_dup 3) (match_dup 4))
4883 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4885 operands[4] = GEN_INT (~INTVAL (operands[2]));
4888 (define_insn_and_split "*or_not_di_sp32"
4889 [(set (match_operand:DI 0 "register_operand" "=r")
4890 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4891 (match_operand:DI 2 "register_operand" "r")))]
4894 "&& reload_completed
4895 && ((GET_CODE (operands[0]) == REG
4896 && SPARC_INT_REG_P (REGNO (operands[0])))
4897 || (GET_CODE (operands[0]) == SUBREG
4898 && GET_CODE (SUBREG_REG (operands[0])) == REG
4899 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4900 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4901 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4902 "operands[3] = gen_highpart (SImode, operands[0]);
4903 operands[4] = gen_highpart (SImode, operands[1]);
4904 operands[5] = gen_highpart (SImode, operands[2]);
4905 operands[6] = gen_lowpart (SImode, operands[0]);
4906 operands[7] = gen_lowpart (SImode, operands[1]);
4907 operands[8] = gen_lowpart (SImode, operands[2]);"
4908 [(set_attr "length" "2")])
4910 (define_insn "*or_not_di_sp64"
4911 [(set (match_operand:DI 0 "register_operand" "=r")
4912 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4913 (match_operand:DI 2 "register_operand" "r")))]
4917 (define_insn "*or_not_si"
4918 [(set (match_operand:SI 0 "register_operand" "=r")
4919 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4920 (match_operand:SI 2 "register_operand" "r")))]
4924 (define_expand "xordi3"
4925 [(set (match_operand:DI 0 "register_operand" "")
4926 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4927 (match_operand:DI 2 "arith_double_operand" "")))]
4931 (define_insn "*xordi3_sp32"
4932 [(set (match_operand:DI 0 "register_operand" "=r")
4933 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4934 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4937 [(set_attr "length" "2")])
4939 (define_insn "*xordi3_sp64"
4940 [(set (match_operand:DI 0 "register_operand" "=r")
4941 (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4942 (match_operand:DI 2 "arith_operand" "rI")))]
4946 (define_insn "xorsi3"
4947 [(set (match_operand:SI 0 "register_operand" "=r")
4948 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4949 (match_operand:SI 2 "arith_operand" "rI")))]
4954 [(set (match_operand:SI 0 "register_operand" "")
4955 (xor:SI (match_operand:SI 1 "register_operand" "")
4956 (match_operand:SI 2 "const_compl_high_operand" "")))
4957 (clobber (match_operand:SI 3 "register_operand" ""))]
4959 [(set (match_dup 3) (match_dup 4))
4960 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4962 operands[4] = GEN_INT (~INTVAL (operands[2]));
4966 [(set (match_operand:SI 0 "register_operand" "")
4967 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4968 (match_operand:SI 2 "const_compl_high_operand" ""))))
4969 (clobber (match_operand:SI 3 "register_operand" ""))]
4971 [(set (match_dup 3) (match_dup 4))
4972 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4974 operands[4] = GEN_INT (~INTVAL (operands[2]));
4977 ;; Split DImode logical operations requiring two instructions.
4979 [(set (match_operand:DI 0 "register_operand" "")
4980 (match_operator:DI 1 "cc_arith_operator" ; AND, IOR, XOR
4981 [(match_operand:DI 2 "register_operand" "")
4982 (match_operand:DI 3 "arith_double_operand" "")]))]
4985 && ((GET_CODE (operands[0]) == REG
4986 && SPARC_INT_REG_P (REGNO (operands[0])))
4987 || (GET_CODE (operands[0]) == SUBREG
4988 && GET_CODE (SUBREG_REG (operands[0])) == REG
4989 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4990 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4991 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4993 operands[4] = gen_highpart (SImode, operands[0]);
4994 operands[5] = gen_lowpart (SImode, operands[0]);
4995 operands[6] = gen_highpart (SImode, operands[2]);
4996 operands[7] = gen_lowpart (SImode, operands[2]);
4997 #if HOST_BITS_PER_WIDE_INT == 32
4998 if (GET_CODE (operands[3]) == CONST_INT)
5000 if (INTVAL (operands[3]) < 0)
5001 operands[8] = constm1_rtx;
5003 operands[8] = const0_rtx;
5007 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5008 operands[9] = gen_lowpart (SImode, operands[3]);
5011 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5012 ;; Combine now canonicalizes to the rightmost expression.
5013 (define_insn_and_split "*xor_not_di_sp32"
5014 [(set (match_operand:DI 0 "register_operand" "=r")
5015 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
5016 (match_operand:DI 2 "register_operand" "r"))))]
5019 "&& reload_completed
5020 && ((GET_CODE (operands[0]) == REG
5021 && SPARC_INT_REG_P (REGNO (operands[0])))
5022 || (GET_CODE (operands[0]) == SUBREG
5023 && GET_CODE (SUBREG_REG (operands[0])) == REG
5024 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
5025 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5026 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5027 "operands[3] = gen_highpart (SImode, operands[0]);
5028 operands[4] = gen_highpart (SImode, operands[1]);
5029 operands[5] = gen_highpart (SImode, operands[2]);
5030 operands[6] = gen_lowpart (SImode, operands[0]);
5031 operands[7] = gen_lowpart (SImode, operands[1]);
5032 operands[8] = gen_lowpart (SImode, operands[2]);"
5033 [(set_attr "length" "2")])
5035 (define_insn "*xor_not_di_sp64"
5036 [(set (match_operand:DI 0 "register_operand" "=r")
5037 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
5038 (match_operand:DI 2 "arith_operand" "rI"))))]
5040 "xnor\t%r1, %2, %0")
5042 (define_insn "*xor_not_si"
5043 [(set (match_operand:SI 0 "register_operand" "=r")
5044 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
5045 (match_operand:SI 2 "arith_operand" "rI"))))]
5047 "xnor\t%r1, %2, %0")
5049 ;; These correspond to the above in the case where we also (or only)
5050 ;; want to set the condition code.
5052 (define_insn "*cmp_cc_arith_op"
5053 [(set (reg:CC CC_REG)
5055 (match_operator:SI 2 "cc_arith_operator"
5056 [(match_operand:SI 0 "arith_operand" "%r")
5057 (match_operand:SI 1 "arith_operand" "rI")])
5060 "%A2cc\t%0, %1, %%g0"
5061 [(set_attr "type" "compare")])
5063 (define_insn "*cmp_ccx_arith_op"
5064 [(set (reg:CCX CC_REG)
5066 (match_operator:DI 2 "cc_arith_operator"
5067 [(match_operand:DI 0 "arith_operand" "%r")
5068 (match_operand:DI 1 "arith_operand" "rI")])
5071 "%A2cc\t%0, %1, %%g0"
5072 [(set_attr "type" "compare")])
5074 (define_insn "*cmp_cc_arith_op_set"
5075 [(set (reg:CC CC_REG)
5077 (match_operator:SI 3 "cc_arith_operator"
5078 [(match_operand:SI 1 "arith_operand" "%r")
5079 (match_operand:SI 2 "arith_operand" "rI")])
5081 (set (match_operand:SI 0 "register_operand" "=r")
5082 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5083 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5085 [(set_attr "type" "compare")])
5087 (define_insn "*cmp_ccx_arith_op_set"
5088 [(set (reg:CCX CC_REG)
5090 (match_operator:DI 3 "cc_arith_operator"
5091 [(match_operand:DI 1 "arith_operand" "%r")
5092 (match_operand:DI 2 "arith_operand" "rI")])
5094 (set (match_operand:DI 0 "register_operand" "=r")
5095 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5096 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5098 [(set_attr "type" "compare")])
5100 (define_insn "*cmp_cc_xor_not"
5101 [(set (reg:CC CC_REG)
5103 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5104 (match_operand:SI 1 "arith_operand" "rI")))
5107 "xnorcc\t%r0, %1, %%g0"
5108 [(set_attr "type" "compare")])
5110 (define_insn "*cmp_ccx_xor_not"
5111 [(set (reg:CCX CC_REG)
5113 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5114 (match_operand:DI 1 "arith_operand" "rI")))
5117 "xnorcc\t%r0, %1, %%g0"
5118 [(set_attr "type" "compare")])
5120 (define_insn "*cmp_cc_xor_not_set"
5121 [(set (reg:CC CC_REG)
5123 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5124 (match_operand:SI 2 "arith_operand" "rI")))
5126 (set (match_operand:SI 0 "register_operand" "=r")
5127 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5129 "xnorcc\t%r1, %2, %0"
5130 [(set_attr "type" "compare")])
5132 (define_insn "*cmp_ccx_xor_not_set"
5133 [(set (reg:CCX CC_REG)
5135 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5136 (match_operand:DI 2 "arith_operand" "rI")))
5138 (set (match_operand:DI 0 "register_operand" "=r")
5139 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5141 "xnorcc\t%r1, %2, %0"
5142 [(set_attr "type" "compare")])
5144 (define_insn "*cmp_cc_arith_op_not"
5145 [(set (reg:CC CC_REG)
5147 (match_operator:SI 2 "cc_arith_not_operator"
5148 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5149 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5152 "%B2cc\t%r1, %0, %%g0"
5153 [(set_attr "type" "compare")])
5155 (define_insn "*cmp_ccx_arith_op_not"
5156 [(set (reg:CCX CC_REG)
5158 (match_operator:DI 2 "cc_arith_not_operator"
5159 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5160 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5163 "%B2cc\t%r1, %0, %%g0"
5164 [(set_attr "type" "compare")])
5166 (define_insn "*cmp_cc_arith_op_not_set"
5167 [(set (reg:CC CC_REG)
5169 (match_operator:SI 3 "cc_arith_not_operator"
5170 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5171 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5173 (set (match_operand:SI 0 "register_operand" "=r")
5174 (match_operator:SI 4 "cc_arith_not_operator"
5175 [(not:SI (match_dup 1)) (match_dup 2)]))]
5176 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5177 "%B3cc\t%r2, %1, %0"
5178 [(set_attr "type" "compare")])
5180 (define_insn "*cmp_ccx_arith_op_not_set"
5181 [(set (reg:CCX CC_REG)
5183 (match_operator:DI 3 "cc_arith_not_operator"
5184 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5185 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5187 (set (match_operand:DI 0 "register_operand" "=r")
5188 (match_operator:DI 4 "cc_arith_not_operator"
5189 [(not:DI (match_dup 1)) (match_dup 2)]))]
5190 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5191 "%B3cc\t%r2, %1, %0"
5192 [(set_attr "type" "compare")])
5194 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5195 ;; does not know how to make it work for constants.
5197 (define_expand "negdi2"
5198 [(set (match_operand:DI 0 "register_operand" "=r")
5199 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5202 if (! TARGET_ARCH64)
5204 emit_insn (gen_rtx_PARALLEL
5207 gen_rtx_SET (VOIDmode, operand0,
5208 gen_rtx_NEG (DImode, operand1)),
5209 gen_rtx_CLOBBER (VOIDmode,
5210 gen_rtx_REG (CCmode,
5216 (define_insn_and_split "*negdi2_sp32"
5217 [(set (match_operand:DI 0 "register_operand" "=r")
5218 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5219 (clobber (reg:CC CC_REG))]
5222 "&& reload_completed"
5223 [(parallel [(set (reg:CC_NOOV CC_REG)
5224 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5226 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5227 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5228 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5229 "operands[2] = gen_highpart (SImode, operands[0]);
5230 operands[3] = gen_highpart (SImode, operands[1]);
5231 operands[4] = gen_lowpart (SImode, operands[0]);
5232 operands[5] = gen_lowpart (SImode, operands[1]);"
5233 [(set_attr "length" "2")])
5235 (define_insn "*negdi2_sp64"
5236 [(set (match_operand:DI 0 "register_operand" "=r")
5237 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5239 "sub\t%%g0, %1, %0")
5241 (define_insn "negsi2"
5242 [(set (match_operand:SI 0 "register_operand" "=r")
5243 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5245 "sub\t%%g0, %1, %0")
5247 (define_insn "*cmp_cc_neg"
5248 [(set (reg:CC_NOOV CC_REG)
5249 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5252 "subcc\t%%g0, %0, %%g0"
5253 [(set_attr "type" "compare")])
5255 (define_insn "*cmp_ccx_neg"
5256 [(set (reg:CCX_NOOV CC_REG)
5257 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5260 "subcc\t%%g0, %0, %%g0"
5261 [(set_attr "type" "compare")])
5263 (define_insn "*cmp_cc_set_neg"
5264 [(set (reg:CC_NOOV CC_REG)
5265 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5267 (set (match_operand:SI 0 "register_operand" "=r")
5268 (neg:SI (match_dup 1)))]
5270 "subcc\t%%g0, %1, %0"
5271 [(set_attr "type" "compare")])
5273 (define_insn "*cmp_ccx_set_neg"
5274 [(set (reg:CCX_NOOV CC_REG)
5275 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5277 (set (match_operand:DI 0 "register_operand" "=r")
5278 (neg:DI (match_dup 1)))]
5280 "subcc\t%%g0, %1, %0"
5281 [(set_attr "type" "compare")])
5283 ;; We cannot use the "not" pseudo insn because the Sun assembler
5284 ;; does not know how to make it work for constants.
5285 (define_expand "one_cmpldi2"
5286 [(set (match_operand:DI 0 "register_operand" "")
5287 (not:DI (match_operand:DI 1 "register_operand" "")))]
5291 (define_insn_and_split "*one_cmpldi2_sp32"
5292 [(set (match_operand:DI 0 "register_operand" "=r")
5293 (not:DI (match_operand:DI 1 "register_operand" "r")))]
5296 "&& reload_completed
5297 && ((GET_CODE (operands[0]) == REG
5298 && SPARC_INT_REG_P (REGNO (operands[0])))
5299 || (GET_CODE (operands[0]) == SUBREG
5300 && GET_CODE (SUBREG_REG (operands[0])) == REG
5301 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
5302 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5303 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5304 "operands[2] = gen_highpart (SImode, operands[0]);
5305 operands[3] = gen_highpart (SImode, operands[1]);
5306 operands[4] = gen_lowpart (SImode, operands[0]);
5307 operands[5] = gen_lowpart (SImode, operands[1]);"
5308 [(set_attr "length" "2")])
5310 (define_insn "*one_cmpldi2_sp64"
5311 [(set (match_operand:DI 0 "register_operand" "=r")
5312 (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5314 "xnor\t%%g0, %1, %0")
5316 (define_insn "one_cmplsi2"
5317 [(set (match_operand:SI 0 "register_operand" "=r")
5318 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5320 "xnor\t%%g0, %1, %0")
5322 (define_insn "*cmp_cc_not"
5323 [(set (reg:CC CC_REG)
5324 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5327 "xnorcc\t%%g0, %0, %%g0"
5328 [(set_attr "type" "compare")])
5330 (define_insn "*cmp_ccx_not"
5331 [(set (reg:CCX CC_REG)
5332 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5335 "xnorcc\t%%g0, %0, %%g0"
5336 [(set_attr "type" "compare")])
5338 (define_insn "*cmp_cc_set_not"
5339 [(set (reg:CC CC_REG)
5340 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5342 (set (match_operand:SI 0 "register_operand" "=r")
5343 (not:SI (match_dup 1)))]
5345 "xnorcc\t%%g0, %1, %0"
5346 [(set_attr "type" "compare")])
5348 (define_insn "*cmp_ccx_set_not"
5349 [(set (reg:CCX CC_REG)
5350 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5352 (set (match_operand:DI 0 "register_operand" "=r")
5353 (not:DI (match_dup 1)))]
5355 "xnorcc\t%%g0, %1, %0"
5356 [(set_attr "type" "compare")])
5358 (define_insn "*cmp_cc_set"
5359 [(set (match_operand:SI 0 "register_operand" "=r")
5360 (match_operand:SI 1 "register_operand" "r"))
5361 (set (reg:CC CC_REG)
5362 (compare:CC (match_dup 1)
5366 [(set_attr "type" "compare")])
5368 (define_insn "*cmp_ccx_set64"
5369 [(set (match_operand:DI 0 "register_operand" "=r")
5370 (match_operand:DI 1 "register_operand" "r"))
5371 (set (reg:CCX CC_REG)
5372 (compare:CCX (match_dup 1)
5376 [(set_attr "type" "compare")])
5379 ;; Floating point arithmetic instructions.
5381 (define_expand "addtf3"
5382 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5383 (plus:TF (match_operand:TF 1 "general_operand" "")
5384 (match_operand:TF 2 "general_operand" "")))]
5385 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5386 "emit_tfmode_binop (PLUS, operands); DONE;")
5388 (define_insn "*addtf3_hq"
5389 [(set (match_operand:TF 0 "register_operand" "=e")
5390 (plus:TF (match_operand:TF 1 "register_operand" "e")
5391 (match_operand:TF 2 "register_operand" "e")))]
5392 "TARGET_FPU && TARGET_HARD_QUAD"
5394 [(set_attr "type" "fp")])
5396 (define_insn "adddf3"
5397 [(set (match_operand:DF 0 "register_operand" "=e")
5398 (plus:DF (match_operand:DF 1 "register_operand" "e")
5399 (match_operand:DF 2 "register_operand" "e")))]
5402 [(set_attr "type" "fp")
5403 (set_attr "fptype" "double")])
5405 (define_insn "addsf3"
5406 [(set (match_operand:SF 0 "register_operand" "=f")
5407 (plus:SF (match_operand:SF 1 "register_operand" "f")
5408 (match_operand:SF 2 "register_operand" "f")))]
5411 [(set_attr "type" "fp")])
5413 (define_expand "subtf3"
5414 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5415 (minus:TF (match_operand:TF 1 "general_operand" "")
5416 (match_operand:TF 2 "general_operand" "")))]
5417 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5418 "emit_tfmode_binop (MINUS, operands); DONE;")
5420 (define_insn "*subtf3_hq"
5421 [(set (match_operand:TF 0 "register_operand" "=e")
5422 (minus:TF (match_operand:TF 1 "register_operand" "e")
5423 (match_operand:TF 2 "register_operand" "e")))]
5424 "TARGET_FPU && TARGET_HARD_QUAD"
5426 [(set_attr "type" "fp")])
5428 (define_insn "subdf3"
5429 [(set (match_operand:DF 0 "register_operand" "=e")
5430 (minus:DF (match_operand:DF 1 "register_operand" "e")
5431 (match_operand:DF 2 "register_operand" "e")))]
5434 [(set_attr "type" "fp")
5435 (set_attr "fptype" "double")])
5437 (define_insn "subsf3"
5438 [(set (match_operand:SF 0 "register_operand" "=f")
5439 (minus:SF (match_operand:SF 1 "register_operand" "f")
5440 (match_operand:SF 2 "register_operand" "f")))]
5443 [(set_attr "type" "fp")])
5445 (define_expand "multf3"
5446 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5447 (mult:TF (match_operand:TF 1 "general_operand" "")
5448 (match_operand:TF 2 "general_operand" "")))]
5449 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5450 "emit_tfmode_binop (MULT, operands); DONE;")
5452 (define_insn "*multf3_hq"
5453 [(set (match_operand:TF 0 "register_operand" "=e")
5454 (mult:TF (match_operand:TF 1 "register_operand" "e")
5455 (match_operand:TF 2 "register_operand" "e")))]
5456 "TARGET_FPU && TARGET_HARD_QUAD"
5458 [(set_attr "type" "fpmul")])
5460 (define_insn "muldf3"
5461 [(set (match_operand:DF 0 "register_operand" "=e")
5462 (mult:DF (match_operand:DF 1 "register_operand" "e")
5463 (match_operand:DF 2 "register_operand" "e")))]
5466 [(set_attr "type" "fpmul")
5467 (set_attr "fptype" "double")])
5469 (define_insn "mulsf3"
5470 [(set (match_operand:SF 0 "register_operand" "=f")
5471 (mult:SF (match_operand:SF 1 "register_operand" "f")
5472 (match_operand:SF 2 "register_operand" "f")))]
5475 [(set_attr "type" "fpmul")])
5477 (define_insn "fmadf4"
5478 [(set (match_operand:DF 0 "register_operand" "=e")
5479 (fma:DF (match_operand:DF 1 "register_operand" "e")
5480 (match_operand:DF 2 "register_operand" "e")
5481 (match_operand:DF 3 "register_operand" "e")))]
5483 "fmaddd\t%1, %2, %3, %0"
5484 [(set_attr "type" "fpmul")])
5486 (define_insn "fmsdf4"
5487 [(set (match_operand:DF 0 "register_operand" "=e")
5488 (fma:DF (match_operand:DF 1 "register_operand" "e")
5489 (match_operand:DF 2 "register_operand" "e")
5490 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5492 "fmsubd\t%1, %2, %3, %0"
5493 [(set_attr "type" "fpmul")])
5495 (define_insn "*nfmadf4"
5496 [(set (match_operand:DF 0 "register_operand" "=e")
5497 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5498 (match_operand:DF 2 "register_operand" "e")
5499 (match_operand:DF 3 "register_operand" "e"))))]
5501 "fnmaddd\t%1, %2, %3, %0"
5502 [(set_attr "type" "fpmul")])
5504 (define_insn "*nfmsdf4"
5505 [(set (match_operand:DF 0 "register_operand" "=e")
5506 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5507 (match_operand:DF 2 "register_operand" "e")
5508 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5510 "fnmsubd\t%1, %2, %3, %0"
5511 [(set_attr "type" "fpmul")])
5513 (define_insn "fmasf4"
5514 [(set (match_operand:SF 0 "register_operand" "=f")
5515 (fma:SF (match_operand:SF 1 "register_operand" "f")
5516 (match_operand:SF 2 "register_operand" "f")
5517 (match_operand:SF 3 "register_operand" "f")))]
5519 "fmadds\t%1, %2, %3, %0"
5520 [(set_attr "type" "fpmul")])
5522 (define_insn "fmssf4"
5523 [(set (match_operand:SF 0 "register_operand" "=f")
5524 (fma:SF (match_operand:SF 1 "register_operand" "f")
5525 (match_operand:SF 2 "register_operand" "f")
5526 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5528 "fmsubs\t%1, %2, %3, %0"
5529 [(set_attr "type" "fpmul")])
5531 (define_insn "*nfmasf4"
5532 [(set (match_operand:SF 0 "register_operand" "=f")
5533 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5534 (match_operand:SF 2 "register_operand" "f")
5535 (match_operand:SF 3 "register_operand" "f"))))]
5537 "fnmadds\t%1, %2, %3, %0"
5538 [(set_attr "type" "fpmul")])
5540 (define_insn "*nfmssf4"
5541 [(set (match_operand:SF 0 "register_operand" "=f")
5542 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5543 (match_operand:SF 2 "register_operand" "f")
5544 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5546 "fnmsubs\t%1, %2, %3, %0"
5547 [(set_attr "type" "fpmul")])
5549 (define_insn "*muldf3_extend"
5550 [(set (match_operand:DF 0 "register_operand" "=e")
5551 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5552 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5553 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5554 "fsmuld\t%1, %2, %0"
5555 [(set_attr "type" "fpmul")
5556 (set_attr "fptype" "double")])
5558 (define_insn "*multf3_extend"
5559 [(set (match_operand:TF 0 "register_operand" "=e")
5560 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5561 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5562 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5563 "fdmulq\t%1, %2, %0"
5564 [(set_attr "type" "fpmul")])
5566 (define_expand "divtf3"
5567 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5568 (div:TF (match_operand:TF 1 "general_operand" "")
5569 (match_operand:TF 2 "general_operand" "")))]
5570 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5571 "emit_tfmode_binop (DIV, operands); DONE;")
5573 ;; don't have timing for quad-prec. divide.
5574 (define_insn "*divtf3_hq"
5575 [(set (match_operand:TF 0 "register_operand" "=e")
5576 (div:TF (match_operand:TF 1 "register_operand" "e")
5577 (match_operand:TF 2 "register_operand" "e")))]
5578 "TARGET_FPU && TARGET_HARD_QUAD"
5580 [(set_attr "type" "fpdivd")])
5582 (define_insn "divdf3"
5583 [(set (match_operand:DF 0 "register_operand" "=e")
5584 (div:DF (match_operand:DF 1 "register_operand" "e")
5585 (match_operand:DF 2 "register_operand" "e")))]
5588 [(set_attr "type" "fpdivd")
5589 (set_attr "fptype" "double")])
5591 (define_insn "divsf3"
5592 [(set (match_operand:SF 0 "register_operand" "=f")
5593 (div:SF (match_operand:SF 1 "register_operand" "f")
5594 (match_operand:SF 2 "register_operand" "f")))]
5597 [(set_attr "type" "fpdivs")])
5599 (define_expand "negtf2"
5600 [(set (match_operand:TF 0 "register_operand" "=e,e")
5601 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5605 (define_insn_and_split "*negtf2_notv9"
5606 [(set (match_operand:TF 0 "register_operand" "=e,e")
5607 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5608 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5614 "&& reload_completed
5615 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5616 [(set (match_dup 2) (neg:SF (match_dup 3)))
5617 (set (match_dup 4) (match_dup 5))
5618 (set (match_dup 6) (match_dup 7))]
5619 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5620 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5621 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5622 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5623 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5624 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5625 [(set_attr "type" "fpmove,*")
5626 (set_attr "length" "*,2")])
5628 (define_insn_and_split "*negtf2_v9"
5629 [(set (match_operand:TF 0 "register_operand" "=e,e")
5630 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5631 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5632 "TARGET_FPU && TARGET_V9"
5636 "&& reload_completed
5637 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5638 [(set (match_dup 2) (neg:DF (match_dup 3)))
5639 (set (match_dup 4) (match_dup 5))]
5640 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5641 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5642 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5643 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5644 [(set_attr "type" "fpmove,*")
5645 (set_attr "length" "*,2")
5646 (set_attr "fptype" "double")])
5648 (define_expand "negdf2"
5649 [(set (match_operand:DF 0 "register_operand" "")
5650 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5654 (define_insn_and_split "*negdf2_notv9"
5655 [(set (match_operand:DF 0 "register_operand" "=e,e")
5656 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5657 "TARGET_FPU && ! TARGET_V9"
5661 "&& reload_completed
5662 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5663 [(set (match_dup 2) (neg:SF (match_dup 3)))
5664 (set (match_dup 4) (match_dup 5))]
5665 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5666 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5667 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5668 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5669 [(set_attr "type" "fpmove,*")
5670 (set_attr "length" "*,2")])
5672 (define_insn "*negdf2_v9"
5673 [(set (match_operand:DF 0 "register_operand" "=e")
5674 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5675 "TARGET_FPU && TARGET_V9"
5677 [(set_attr "type" "fpmove")
5678 (set_attr "fptype" "double")])
5680 (define_insn "negsf2"
5681 [(set (match_operand:SF 0 "register_operand" "=f")
5682 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5685 [(set_attr "type" "fpmove")])
5687 (define_expand "abstf2"
5688 [(set (match_operand:TF 0 "register_operand" "")
5689 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5693 (define_insn_and_split "*abstf2_notv9"
5694 [(set (match_operand:TF 0 "register_operand" "=e,e")
5695 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5696 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5697 "TARGET_FPU && ! TARGET_V9"
5701 "&& reload_completed
5702 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5703 [(set (match_dup 2) (abs:SF (match_dup 3)))
5704 (set (match_dup 4) (match_dup 5))
5705 (set (match_dup 6) (match_dup 7))]
5706 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5707 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5708 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5709 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5710 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5711 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5712 [(set_attr "type" "fpmove,*")
5713 (set_attr "length" "*,2")])
5715 (define_insn "*abstf2_hq_v9"
5716 [(set (match_operand:TF 0 "register_operand" "=e,e")
5717 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5718 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5722 [(set_attr "type" "fpmove")
5723 (set_attr "fptype" "double,*")])
5725 (define_insn_and_split "*abstf2_v9"
5726 [(set (match_operand:TF 0 "register_operand" "=e,e")
5727 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5728 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5732 "&& reload_completed
5733 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5734 [(set (match_dup 2) (abs:DF (match_dup 3)))
5735 (set (match_dup 4) (match_dup 5))]
5736 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5737 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5738 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5739 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5740 [(set_attr "type" "fpmove,*")
5741 (set_attr "length" "*,2")
5742 (set_attr "fptype" "double,*")])
5744 (define_expand "absdf2"
5745 [(set (match_operand:DF 0 "register_operand" "")
5746 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5750 (define_insn_and_split "*absdf2_notv9"
5751 [(set (match_operand:DF 0 "register_operand" "=e,e")
5752 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5753 "TARGET_FPU && ! TARGET_V9"
5757 "&& reload_completed
5758 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5759 [(set (match_dup 2) (abs:SF (match_dup 3)))
5760 (set (match_dup 4) (match_dup 5))]
5761 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5762 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5763 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5764 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5765 [(set_attr "type" "fpmove,*")
5766 (set_attr "length" "*,2")])
5768 (define_insn "*absdf2_v9"
5769 [(set (match_operand:DF 0 "register_operand" "=e")
5770 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5771 "TARGET_FPU && TARGET_V9"
5773 [(set_attr "type" "fpmove")
5774 (set_attr "fptype" "double")])
5776 (define_insn "abssf2"
5777 [(set (match_operand:SF 0 "register_operand" "=f")
5778 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5781 [(set_attr "type" "fpmove")])
5783 (define_expand "sqrttf2"
5784 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5785 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5786 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5787 "emit_tfmode_unop (SQRT, operands); DONE;")
5789 (define_insn "*sqrttf2_hq"
5790 [(set (match_operand:TF 0 "register_operand" "=e")
5791 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5792 "TARGET_FPU && TARGET_HARD_QUAD"
5794 [(set_attr "type" "fpsqrtd")])
5796 (define_insn "sqrtdf2"
5797 [(set (match_operand:DF 0 "register_operand" "=e")
5798 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5801 [(set_attr "type" "fpsqrtd")
5802 (set_attr "fptype" "double")])
5804 (define_insn "sqrtsf2"
5805 [(set (match_operand:SF 0 "register_operand" "=f")
5806 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5809 [(set_attr "type" "fpsqrts")])
5812 ;; Arithmetic shift instructions.
5814 (define_insn "ashlsi3"
5815 [(set (match_operand:SI 0 "register_operand" "=r")
5816 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5817 (match_operand:SI 2 "arith_operand" "rI")))]
5820 if (GET_CODE (operands[2]) == CONST_INT)
5821 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5822 return "sll\t%1, %2, %0";
5824 [(set_attr "type" "shift")])
5826 (define_insn "*ashlsi3_extend"
5827 [(set (match_operand:DI 0 "register_operand" "=r")
5829 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5830 (match_operand:SI 2 "arith_operand" "rI"))))]
5833 if (GET_CODE (operands[2]) == CONST_INT)
5834 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5835 return "sll\t%1, %2, %0";
5837 [(set_attr "type" "shift")])
5839 (define_expand "ashldi3"
5840 [(set (match_operand:DI 0 "register_operand" "=r")
5841 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5842 (match_operand:SI 2 "arith_operand" "rI")))]
5843 "TARGET_ARCH64 || TARGET_V8PLUS"
5845 if (! TARGET_ARCH64)
5847 if (GET_CODE (operands[2]) == CONST_INT)
5849 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5854 (define_insn "*ashldi3_sp64"
5855 [(set (match_operand:DI 0 "register_operand" "=r")
5856 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5857 (match_operand:SI 2 "arith_operand" "rI")))]
5860 if (GET_CODE (operands[2]) == CONST_INT)
5861 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5862 return "sllx\t%1, %2, %0";
5864 [(set_attr "type" "shift")])
5867 (define_insn "ashldi3_v8plus"
5868 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5869 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5870 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5871 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5873 "* return output_v8plus_shift (insn ,operands, \"sllx\");"
5874 [(set_attr "type" "multi")
5875 (set_attr "length" "5,5,6")])
5877 ;; Optimize (1LL<<x)-1
5878 ;; XXX this also needs to be fixed to handle equal subregs
5879 ;; XXX first before we could re-enable it.
5881 ; [(set (match_operand:DI 0 "register_operand" "=h")
5882 ; (plus:DI (ashift:DI (const_int 1)
5883 ; (match_operand:SI 1 "arith_operand" "rI"))
5885 ; "0 && TARGET_V8PLUS"
5887 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5888 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5889 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5891 ; [(set_attr "type" "multi")
5892 ; (set_attr "length" "4")])
5894 (define_insn "*cmp_cc_ashift_1"
5895 [(set (reg:CC_NOOV CC_REG)
5896 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5900 "addcc\t%0, %0, %%g0"
5901 [(set_attr "type" "compare")])
5903 (define_insn "*cmp_cc_set_ashift_1"
5904 [(set (reg:CC_NOOV CC_REG)
5905 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5908 (set (match_operand:SI 0 "register_operand" "=r")
5909 (ashift:SI (match_dup 1) (const_int 1)))]
5912 [(set_attr "type" "compare")])
5914 (define_insn "ashrsi3"
5915 [(set (match_operand:SI 0 "register_operand" "=r")
5916 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5917 (match_operand:SI 2 "arith_operand" "rI")))]
5920 if (GET_CODE (operands[2]) == CONST_INT)
5921 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5922 return "sra\t%1, %2, %0";
5924 [(set_attr "type" "shift")])
5926 (define_insn "*ashrsi3_extend"
5927 [(set (match_operand:DI 0 "register_operand" "=r")
5928 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5929 (match_operand:SI 2 "arith_operand" "r"))))]
5932 [(set_attr "type" "shift")])
5934 ;; This handles the case as above, but with constant shift instead of
5935 ;; register. Combiner "simplifies" it for us a little bit though.
5936 (define_insn "*ashrsi3_extend2"
5937 [(set (match_operand:DI 0 "register_operand" "=r")
5938 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5940 (match_operand:SI 2 "small_int_operand" "I")))]
5941 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5943 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5944 return "sra\t%1, %2, %0";
5946 [(set_attr "type" "shift")])
5948 (define_expand "ashrdi3"
5949 [(set (match_operand:DI 0 "register_operand" "=r")
5950 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5951 (match_operand:SI 2 "arith_operand" "rI")))]
5952 "TARGET_ARCH64 || TARGET_V8PLUS"
5954 if (! TARGET_ARCH64)
5956 if (GET_CODE (operands[2]) == CONST_INT)
5957 FAIL; /* prefer generic code in this case */
5958 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5963 (define_insn "*ashrdi3_sp64"
5964 [(set (match_operand:DI 0 "register_operand" "=r")
5965 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5966 (match_operand:SI 2 "arith_operand" "rI")))]
5970 if (GET_CODE (operands[2]) == CONST_INT)
5971 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5972 return "srax\t%1, %2, %0";
5974 [(set_attr "type" "shift")])
5977 (define_insn "ashrdi3_v8plus"
5978 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5979 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5980 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5981 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5983 "* return output_v8plus_shift (insn, operands, \"srax\");"
5984 [(set_attr "type" "multi")
5985 (set_attr "length" "5,5,6")])
5987 (define_insn "lshrsi3"
5988 [(set (match_operand:SI 0 "register_operand" "=r")
5989 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5990 (match_operand:SI 2 "arith_operand" "rI")))]
5993 if (GET_CODE (operands[2]) == CONST_INT)
5994 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5995 return "srl\t%1, %2, %0";
5997 [(set_attr "type" "shift")])
5999 (define_insn "*lshrsi3_extend0"
6000 [(set (match_operand:DI 0 "register_operand" "=r")
6002 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6003 (match_operand:SI 2 "arith_operand" "rI"))))]
6006 if (GET_CODE (operands[2]) == CONST_INT)
6007 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6008 return "srl\t%1, %2, %0";
6010 [(set_attr "type" "shift")])
6012 ;; This handles the case where
6013 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6014 ;; but combiner "simplifies" it for us.
6015 (define_insn "*lshrsi3_extend1"
6016 [(set (match_operand:DI 0 "register_operand" "=r")
6017 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6018 (match_operand:SI 2 "arith_operand" "r")) 0)
6019 (match_operand 3 "const_int_operand" "")))]
6020 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6022 [(set_attr "type" "shift")])
6024 ;; This handles the case where
6025 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6026 ;; but combiner "simplifies" it for us.
6027 (define_insn "*lshrsi3_extend2"
6028 [(set (match_operand:DI 0 "register_operand" "=r")
6029 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6030 (match_operand 2 "small_int_operand" "I")
6032 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6034 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6035 return "srl\t%1, %2, %0";
6037 [(set_attr "type" "shift")])
6039 (define_expand "lshrdi3"
6040 [(set (match_operand:DI 0 "register_operand" "=r")
6041 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6042 (match_operand:SI 2 "arith_operand" "rI")))]
6043 "TARGET_ARCH64 || TARGET_V8PLUS"
6045 if (! TARGET_ARCH64)
6047 if (GET_CODE (operands[2]) == CONST_INT)
6049 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6054 (define_insn "*lshrdi3_sp64"
6055 [(set (match_operand:DI 0 "register_operand" "=r")
6056 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6057 (match_operand:SI 2 "arith_operand" "rI")))]
6060 if (GET_CODE (operands[2]) == CONST_INT)
6061 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6062 return "srlx\t%1, %2, %0";
6064 [(set_attr "type" "shift")])
6067 (define_insn "lshrdi3_v8plus"
6068 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6069 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6070 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6071 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6073 "* return output_v8plus_shift (insn, operands, \"srlx\");"
6074 [(set_attr "type" "multi")
6075 (set_attr "length" "5,5,6")])
6078 [(set (match_operand:SI 0 "register_operand" "=r")
6079 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6081 (match_operand:SI 2 "small_int_operand" "I")))]
6082 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6084 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6085 return "srax\t%1, %2, %0";
6087 [(set_attr "type" "shift")])
6090 [(set (match_operand:SI 0 "register_operand" "=r")
6091 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6093 (match_operand:SI 2 "small_int_operand" "I")))]
6094 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6096 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6097 return "srlx\t%1, %2, %0";
6099 [(set_attr "type" "shift")])
6102 [(set (match_operand:SI 0 "register_operand" "=r")
6103 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6104 (match_operand:SI 2 "small_int_operand" "I")) 4)
6105 (match_operand:SI 3 "small_int_operand" "I")))]
6107 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6108 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6109 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6111 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6113 return "srax\t%1, %2, %0";
6115 [(set_attr "type" "shift")])
6118 [(set (match_operand:SI 0 "register_operand" "=r")
6119 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6120 (match_operand:SI 2 "small_int_operand" "I")) 4)
6121 (match_operand:SI 3 "small_int_operand" "I")))]
6123 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6124 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6125 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6127 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6129 return "srlx\t%1, %2, %0";
6131 [(set_attr "type" "shift")])
6134 ;; Unconditional and other jump instructions.
6136 (define_expand "jump"
6137 [(set (pc) (label_ref (match_operand 0 "" "")))]
6140 (define_insn "*jump_ubranch"
6141 [(set (pc) (label_ref (match_operand 0 "" "")))]
6143 "* return output_ubranch (operands[0], insn);"
6144 [(set_attr "type" "uncond_branch")])
6146 (define_insn "*jump_cbcond"
6147 [(set (pc) (label_ref (match_operand 0 "" "")))]
6149 "* return output_ubranch (operands[0], insn);"
6150 [(set_attr "type" "uncond_cbcond")])
6152 (define_expand "tablejump"
6153 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6154 (use (label_ref (match_operand 1 "" "")))])]
6157 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6159 /* In pic mode, our address differences are against the base of the
6160 table. Add that base value back in; CSE ought to be able to combine
6161 the two address loads. */
6165 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6167 if (CASE_VECTOR_MODE != Pmode)
6168 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6169 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6170 operands[0] = memory_address (Pmode, tmp);
6174 (define_insn "*tablejump_sp32"
6175 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6176 (use (label_ref (match_operand 1 "" "")))]
6179 [(set_attr "type" "uncond_branch")])
6181 (define_insn "*tablejump_sp64"
6182 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6183 (use (label_ref (match_operand 1 "" "")))]
6186 [(set_attr "type" "uncond_branch")])
6189 ;; Jump to subroutine instructions.
6191 (define_expand "call"
6192 ;; Note that this expression is not used for generating RTL.
6193 ;; All the RTL is generated explicitly below.
6194 [(call (match_operand 0 "call_operand" "")
6195 (match_operand 3 "" "i"))]
6196 ;; operands[2] is next_arg_register
6197 ;; operands[3] is struct_value_size_rtx.
6202 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6204 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6206 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6208 /* This is really a PIC sequence. We want to represent
6209 it as a funny jump so its delay slots can be filled.
6211 ??? But if this really *is* a CALL, will not it clobber the
6212 call-clobbered registers? We lose this if it is a JUMP_INSN.
6213 Why cannot we have delay slots filled if it were a CALL? */
6215 /* We accept negative sizes for untyped calls. */
6216 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6221 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6223 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6229 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6230 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6234 fn_rtx = operands[0];
6236 /* We accept negative sizes for untyped calls. */
6237 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6238 sparc_emit_call_insn
6241 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6243 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6246 sparc_emit_call_insn
6249 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6250 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6258 ;; We can't use the same pattern for these two insns, because then registers
6259 ;; in the address may not be properly reloaded.
6261 (define_insn "*call_address_sp32"
6262 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6263 (match_operand 1 "" ""))
6264 (clobber (reg:SI O7_REG))]
6265 ;;- Do not use operand 1 for most machines.
6268 [(set_attr "type" "call")])
6270 (define_insn "*call_symbolic_sp32"
6271 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6272 (match_operand 1 "" ""))
6273 (clobber (reg:SI O7_REG))]
6274 ;;- Do not use operand 1 for most machines.
6277 [(set_attr "type" "call")])
6279 (define_insn "*call_address_sp64"
6280 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6281 (match_operand 1 "" ""))
6282 (clobber (reg:DI O7_REG))]
6283 ;;- Do not use operand 1 for most machines.
6286 [(set_attr "type" "call")])
6288 (define_insn "*call_symbolic_sp64"
6289 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6290 (match_operand 1 "" ""))
6291 (clobber (reg:DI O7_REG))]
6292 ;;- Do not use operand 1 for most machines.
6295 [(set_attr "type" "call")])
6297 ;; This is a call that wants a structure value.
6298 ;; There is no such critter for v9 (??? we may need one anyway).
6299 (define_insn "*call_address_struct_value_sp32"
6300 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6301 (match_operand 1 "" ""))
6302 (match_operand 2 "immediate_operand" "")
6303 (clobber (reg:SI O7_REG))]
6304 ;;- Do not use operand 1 for most machines.
6305 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6307 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6308 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6310 [(set_attr "type" "call_no_delay_slot")
6311 (set_attr "length" "3")])
6313 ;; This is a call that wants a structure value.
6314 ;; There is no such critter for v9 (??? we may need one anyway).
6315 (define_insn "*call_symbolic_struct_value_sp32"
6316 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6317 (match_operand 1 "" ""))
6318 (match_operand 2 "immediate_operand" "")
6319 (clobber (reg:SI O7_REG))]
6320 ;;- Do not use operand 1 for most machines.
6321 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6323 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6324 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6326 [(set_attr "type" "call_no_delay_slot")
6327 (set_attr "length" "3")])
6329 ;; This is a call that may want a structure value. This is used for
6331 (define_insn "*call_address_untyped_struct_value_sp32"
6332 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6333 (match_operand 1 "" ""))
6334 (match_operand 2 "immediate_operand" "")
6335 (clobber (reg:SI O7_REG))]
6336 ;;- Do not use operand 1 for most machines.
6337 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6338 "call\t%a0, %1\n\t nop\n\tnop"
6339 [(set_attr "type" "call_no_delay_slot")
6340 (set_attr "length" "3")])
6342 ;; This is a call that may want a structure value. This is used for
6344 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6345 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6346 (match_operand 1 "" ""))
6347 (match_operand 2 "immediate_operand" "")
6348 (clobber (reg:SI O7_REG))]
6349 ;;- Do not use operand 1 for most machines.
6350 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6351 "call\t%a0, %1\n\t nop\n\tnop"
6352 [(set_attr "type" "call_no_delay_slot")
6353 (set_attr "length" "3")])
6355 (define_expand "call_value"
6356 ;; Note that this expression is not used for generating RTL.
6357 ;; All the RTL is generated explicitly below.
6358 [(set (match_operand 0 "register_operand" "=rf")
6359 (call (match_operand 1 "" "")
6360 (match_operand 4 "" "")))]
6361 ;; operand 2 is stack_size_rtx
6362 ;; operand 3 is next_arg_register
6368 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6370 fn_rtx = operands[1];
6373 gen_rtx_SET (VOIDmode, operands[0],
6374 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6375 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6377 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6382 (define_insn "*call_value_address_sp32"
6383 [(set (match_operand 0 "" "=rf")
6384 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6385 (match_operand 2 "" "")))
6386 (clobber (reg:SI O7_REG))]
6387 ;;- Do not use operand 2 for most machines.
6390 [(set_attr "type" "call")])
6392 (define_insn "*call_value_symbolic_sp32"
6393 [(set (match_operand 0 "" "=rf")
6394 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6395 (match_operand 2 "" "")))
6396 (clobber (reg:SI O7_REG))]
6397 ;;- Do not use operand 2 for most machines.
6400 [(set_attr "type" "call")])
6402 (define_insn "*call_value_address_sp64"
6403 [(set (match_operand 0 "" "")
6404 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6405 (match_operand 2 "" "")))
6406 (clobber (reg:DI O7_REG))]
6407 ;;- Do not use operand 2 for most machines.
6410 [(set_attr "type" "call")])
6412 (define_insn "*call_value_symbolic_sp64"
6413 [(set (match_operand 0 "" "")
6414 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6415 (match_operand 2 "" "")))
6416 (clobber (reg:DI O7_REG))]
6417 ;;- Do not use operand 2 for most machines.
6420 [(set_attr "type" "call")])
6422 (define_expand "untyped_call"
6423 [(parallel [(call (match_operand 0 "" "")
6425 (match_operand:BLK 1 "memory_operand" "")
6426 (match_operand 2 "" "")])]
6429 rtx valreg1 = gen_rtx_REG (DImode, 8);
6430 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6431 rtx result = operands[1];
6433 /* Pass constm1 to indicate that it may expect a structure value, but
6434 we don't know what size it is. */
6435 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6437 /* Save the function value registers. */
6438 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6439 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6442 /* The optimizer does not know that the call sets the function value
6443 registers we stored in the result block. We avoid problems by
6444 claiming that all hard registers are used and clobbered at this
6446 emit_insn (gen_blockage ());
6451 ;; Tail call instructions.
6453 (define_expand "sibcall"
6454 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6459 (define_insn "*sibcall_symbolic_sp32"
6460 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6461 (match_operand 1 "" ""))
6464 "* return output_sibcall(insn, operands[0]);"
6465 [(set_attr "type" "sibcall")])
6467 (define_insn "*sibcall_symbolic_sp64"
6468 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6469 (match_operand 1 "" ""))
6472 "* return output_sibcall(insn, operands[0]);"
6473 [(set_attr "type" "sibcall")])
6475 (define_expand "sibcall_value"
6476 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6477 (call (match_operand 1 "" "") (const_int 0)))
6482 (define_insn "*sibcall_value_symbolic_sp32"
6483 [(set (match_operand 0 "" "=rf")
6484 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6485 (match_operand 2 "" "")))
6488 "* return output_sibcall(insn, operands[1]);"
6489 [(set_attr "type" "sibcall")])
6491 (define_insn "*sibcall_value_symbolic_sp64"
6492 [(set (match_operand 0 "" "")
6493 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6494 (match_operand 2 "" "")))
6497 "* return output_sibcall(insn, operands[1]);"
6498 [(set_attr "type" "sibcall")])
6501 ;; Special instructions.
6503 (define_expand "prologue"
6508 sparc_flat_expand_prologue ();
6510 sparc_expand_prologue ();
6514 ;; The "register window save" insn is modelled as follows. The dwarf2
6515 ;; information is manually added in emit_window_save.
6517 (define_insn "window_save"
6519 [(match_operand 0 "arith_operand" "rI")]
6522 "save\t%%sp, %0, %%sp"
6523 [(set_attr "type" "savew")])
6525 (define_expand "epilogue"
6530 sparc_flat_expand_epilogue (false);
6532 sparc_expand_epilogue (false);
6535 (define_expand "sibcall_epilogue"
6540 sparc_flat_expand_epilogue (false);
6542 sparc_expand_epilogue (false);
6546 (define_expand "eh_return"
6547 [(use (match_operand 0 "general_operand" ""))]
6550 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6551 emit_jump_insn (gen_eh_return_internal ());
6556 (define_insn_and_split "eh_return_internal"
6560 "epilogue_completed"
6564 sparc_flat_expand_epilogue (true);
6566 sparc_expand_epilogue (true);
6569 (define_expand "return"
6571 "sparc_can_use_return_insn_p ()"
6574 (define_insn "*return_internal"
6577 "* return output_return (insn);"
6578 [(set_attr "type" "return")
6579 (set (attr "length")
6580 (cond [(eq_attr "calls_eh_return" "true")
6581 (if_then_else (eq_attr "delayed_branch" "true")
6582 (if_then_else (ior (eq_attr "isa" "v9")
6583 (eq_attr "flat" "true"))
6586 (if_then_else (eq_attr "flat" "true")
6589 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6590 (if_then_else (eq_attr "empty_delay_slot" "true")
6593 (eq_attr "empty_delay_slot" "true")
6594 (if_then_else (eq_attr "delayed_branch" "true")
6599 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6600 ;; all of memory. This blocks insns from being moved across this point.
6602 (define_insn "blockage"
6603 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6606 [(set_attr "length" "0")])
6608 ;; Do not schedule instructions accessing memory before this point.
6610 (define_expand "frame_blockage"
6612 (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
6615 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6616 MEM_VOLATILE_P (operands[0]) = 1;
6617 operands[1] = stack_pointer_rtx;
6620 (define_insn "*frame_blockage<P:mode>"
6621 [(set (match_operand:BLK 0 "" "")
6622 (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
6625 [(set_attr "length" "0")])
6627 (define_expand "probe_stack"
6628 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6632 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6635 (define_insn "probe_stack_range<P:mode>"
6636 [(set (match_operand:P 0 "register_operand" "=r")
6637 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6638 (match_operand:P 2 "register_operand" "r")]
6639 UNSPECV_PROBE_STACK_RANGE))]
6641 "* return output_probe_stack_range (operands[0], operands[2]);"
6642 [(set_attr "type" "multi")])
6644 ;; Prepare to return any type including a structure value.
6646 (define_expand "untyped_return"
6647 [(match_operand:BLK 0 "memory_operand" "")
6648 (match_operand 1 "" "")]
6651 rtx valreg1 = gen_rtx_REG (DImode, 24);
6652 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6653 rtx result = operands[0];
6655 if (! TARGET_ARCH64)
6657 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6658 rtx value = gen_reg_rtx (SImode);
6660 /* Fetch the instruction where we will return to and see if it's an unimp
6661 instruction (the most significant 10 bits will be zero). If so,
6662 update the return address to skip the unimp instruction. */
6663 emit_move_insn (value,
6664 gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8)));
6665 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6666 emit_insn (gen_update_return (rtnreg, value));
6669 /* Reload the function value registers. */
6670 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6671 emit_move_insn (valreg2,
6672 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6674 /* Put USE insns before the return. */
6678 /* Construct the return. */
6679 expand_naked_return ();
6684 ;; Adjust the return address conditionally. If the value of op1 is equal
6685 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6686 ;; This is technically *half* the check required by the 32-bit SPARC
6687 ;; psABI. This check only ensures that an "unimp" insn was written by
6688 ;; the caller, but doesn't check to see if the expected size matches
6689 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6690 ;; only used by the above code "untyped_return".
6692 (define_insn "update_return"
6693 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6694 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6697 if (flag_delayed_branch)
6698 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6700 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6702 [(set (attr "type") (const_string "multi"))
6703 (set (attr "length")
6704 (if_then_else (eq_attr "delayed_branch" "true")
6713 (define_expand "indirect_jump"
6714 [(set (pc) (match_operand 0 "address_operand" "p"))]
6718 (define_insn "*branch_sp32"
6719 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6722 [(set_attr "type" "uncond_branch")])
6724 (define_insn "*branch_sp64"
6725 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6728 [(set_attr "type" "uncond_branch")])
6730 (define_expand "save_stack_nonlocal"
6731 [(set (match_operand 0 "memory_operand" "")
6732 (match_operand 1 "register_operand" ""))
6733 (set (match_dup 2) (match_dup 3))]
6736 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6737 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6738 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6741 (define_expand "restore_stack_nonlocal"
6742 [(set (match_operand 0 "register_operand" "")
6743 (match_operand 1 "memory_operand" ""))]
6746 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6749 (define_expand "nonlocal_goto"
6750 [(match_operand 0 "general_operand" "")
6751 (match_operand 1 "general_operand" "")
6752 (match_operand 2 "memory_operand" "")
6753 (match_operand 3 "memory_operand" "")]
6756 rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6757 rtx r_label = copy_to_reg (operands[1]);
6758 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6759 rtx r_fp = operands[3];
6760 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6762 /* We need to flush all the register windows so that their contents will
6763 be re-synchronized by the restore insn of the target function. */
6765 emit_insn (gen_flush_register_windows ());
6767 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6768 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6770 /* Restore frame pointer for containing function. */
6771 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6772 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6773 emit_move_insn (i7, r_i7);
6775 /* USE of hard_frame_pointer_rtx added for consistency;
6776 not clear if really needed. */
6777 emit_use (hard_frame_pointer_rtx);
6778 emit_use (stack_pointer_rtx);
6781 emit_jump_insn (gen_indirect_jump (r_label));
6786 (define_expand "builtin_setjmp_receiver"
6787 [(label_ref (match_operand 0 "" ""))]
6790 load_got_register ();
6794 ;; Special insn to flush register windows.
6796 (define_insn "flush_register_windows"
6797 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6799 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6800 [(set_attr "type" "flushw")])
6802 ;; Special pattern for the FLUSH instruction.
6804 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6805 ; of the define_insn otherwise missing a mode. We make "flush", aka
6806 ; gen_flush, the default one since sparc_initialize_trampoline uses
6807 ; it on SImode mem values.
6809 (define_insn "flush"
6810 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6812 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6813 [(set_attr "type" "iflush")])
6815 (define_insn "flushdi"
6816 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6818 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6819 [(set_attr "type" "iflush")])
6822 ;; Find first set instructions.
6824 ;; The scan instruction searches from the most significant bit while ffs
6825 ;; searches from the least significant bit. The bit index and treatment of
6826 ;; zero also differ. It takes at least 7 instructions to get the proper
6827 ;; result. Here is an obvious 8 instruction sequence.
6830 (define_insn "ffssi2"
6831 [(set (match_operand:SI 0 "register_operand" "=&r")
6832 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6833 (clobber (match_scratch:SI 2 "=&r"))]
6834 "TARGET_SPARCLITE || TARGET_SPARCLET"
6836 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";
6838 [(set_attr "type" "multi")
6839 (set_attr "length" "8")])
6841 (define_expand "popcountdi2"
6842 [(set (match_operand:DI 0 "register_operand" "")
6843 (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6846 if (! TARGET_ARCH64)
6848 emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6853 (define_insn "*popcountdi_sp64"
6854 [(set (match_operand:DI 0 "register_operand" "=r")
6855 (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6856 "TARGET_POPC && TARGET_ARCH64"
6859 (define_insn "popcountdi_v8plus"
6860 [(set (match_operand:DI 0 "register_operand" "=r")
6861 (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6862 (clobber (match_scratch:SI 2 "=&h"))]
6863 "TARGET_POPC && ! TARGET_ARCH64"
6865 if (sparc_check_64 (operands[1], insn) <= 0)
6866 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6867 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6869 [(set_attr "type" "multi")
6870 (set_attr "length" "5")])
6872 (define_expand "popcountsi2"
6874 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6875 (set (match_operand:SI 0 "register_operand" "")
6876 (truncate:SI (popcount:DI (match_dup 2))))]
6879 if (! TARGET_ARCH64)
6881 emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6885 operands[2] = gen_reg_rtx (DImode);
6888 (define_insn "*popcountsi_sp64"
6889 [(set (match_operand:SI 0 "register_operand" "=r")
6891 (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6892 "TARGET_POPC && TARGET_ARCH64"
6895 (define_insn "popcountsi_v8plus"
6896 [(set (match_operand:SI 0 "register_operand" "=r")
6897 (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6898 "TARGET_POPC && ! TARGET_ARCH64"
6900 if (sparc_check_64 (operands[1], insn) <= 0)
6901 output_asm_insn ("srl\t%1, 0, %1", operands);
6902 return "popc\t%1, %0";
6904 [(set_attr "type" "multi")
6905 (set_attr "length" "2")])
6907 (define_expand "clzdi2"
6908 [(set (match_operand:DI 0 "register_operand" "")
6909 (clz:DI (match_operand:DI 1 "register_operand" "")))]
6912 if (! TARGET_ARCH64)
6914 emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6919 (define_insn "*clzdi_sp64"
6920 [(set (match_operand:DI 0 "register_operand" "=r")
6921 (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6922 "TARGET_VIS3 && TARGET_ARCH64"
6925 (define_insn "clzdi_v8plus"
6926 [(set (match_operand:DI 0 "register_operand" "=r")
6927 (clz:DI (match_operand:DI 1 "register_operand" "r")))
6928 (clobber (match_scratch:SI 2 "=&h"))]
6929 "TARGET_VIS3 && ! TARGET_ARCH64"
6931 if (sparc_check_64 (operands[1], insn) <= 0)
6932 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6933 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6935 [(set_attr "type" "multi")
6936 (set_attr "length" "5")])
6938 (define_expand "clzsi2"
6940 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6942 (truncate:SI (clz:DI (match_dup 2))))
6943 (set (match_operand:SI 0 "register_operand" "")
6944 (minus:SI (match_dup 3) (const_int 32)))]
6947 if (! TARGET_ARCH64)
6949 emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6954 operands[2] = gen_reg_rtx (DImode);
6955 operands[3] = gen_reg_rtx (SImode);
6959 (define_insn "*clzsi_sp64"
6960 [(set (match_operand:SI 0 "register_operand" "=r")
6962 (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6963 "TARGET_VIS3 && TARGET_ARCH64"
6966 (define_insn "clzsi_v8plus"
6967 [(set (match_operand:SI 0 "register_operand" "=r")
6968 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6969 "TARGET_VIS3 && ! TARGET_ARCH64"
6971 if (sparc_check_64 (operands[1], insn) <= 0)
6972 output_asm_insn ("srl\t%1, 0, %1", operands);
6973 return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6975 [(set_attr "type" "multi")
6976 (set_attr "length" "3")])
6979 ;; Peepholes go at the end.
6981 ;; Optimize consecutive loads or stores into ldd and std when possible.
6982 ;; The conditions in which we do this are very restricted and are
6983 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6986 [(set (match_operand:SI 0 "memory_operand" "")
6988 (set (match_operand:SI 1 "memory_operand" "")
6991 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6994 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6997 [(set (match_operand:SI 0 "memory_operand" "")
6999 (set (match_operand:SI 1 "memory_operand" "")
7002 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7005 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7008 [(set (match_operand:SI 0 "register_operand" "")
7009 (match_operand:SI 1 "memory_operand" ""))
7010 (set (match_operand:SI 2 "register_operand" "")
7011 (match_operand:SI 3 "memory_operand" ""))]
7012 "registers_ok_for_ldd_peep (operands[0], operands[2])
7013 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7016 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7017 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7020 [(set (match_operand:SI 0 "memory_operand" "")
7021 (match_operand:SI 1 "register_operand" ""))
7022 (set (match_operand:SI 2 "memory_operand" "")
7023 (match_operand:SI 3 "register_operand" ""))]
7024 "registers_ok_for_ldd_peep (operands[1], operands[3])
7025 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7028 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7029 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7032 [(set (match_operand:SF 0 "register_operand" "")
7033 (match_operand:SF 1 "memory_operand" ""))
7034 (set (match_operand:SF 2 "register_operand" "")
7035 (match_operand:SF 3 "memory_operand" ""))]
7036 "registers_ok_for_ldd_peep (operands[0], operands[2])
7037 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7040 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7041 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7044 [(set (match_operand:SF 0 "memory_operand" "")
7045 (match_operand:SF 1 "register_operand" ""))
7046 (set (match_operand:SF 2 "memory_operand" "")
7047 (match_operand:SF 3 "register_operand" ""))]
7048 "registers_ok_for_ldd_peep (operands[1], operands[3])
7049 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7052 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7053 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7056 [(set (match_operand:SI 0 "register_operand" "")
7057 (match_operand:SI 1 "memory_operand" ""))
7058 (set (match_operand:SI 2 "register_operand" "")
7059 (match_operand:SI 3 "memory_operand" ""))]
7060 "registers_ok_for_ldd_peep (operands[2], operands[0])
7061 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7064 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7065 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7068 [(set (match_operand:SI 0 "memory_operand" "")
7069 (match_operand:SI 1 "register_operand" ""))
7070 (set (match_operand:SI 2 "memory_operand" "")
7071 (match_operand:SI 3 "register_operand" ""))]
7072 "registers_ok_for_ldd_peep (operands[3], operands[1])
7073 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7076 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7077 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7081 [(set (match_operand:SF 0 "register_operand" "")
7082 (match_operand:SF 1 "memory_operand" ""))
7083 (set (match_operand:SF 2 "register_operand" "")
7084 (match_operand:SF 3 "memory_operand" ""))]
7085 "registers_ok_for_ldd_peep (operands[2], operands[0])
7086 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7089 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7090 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7093 [(set (match_operand:SF 0 "memory_operand" "")
7094 (match_operand:SF 1 "register_operand" ""))
7095 (set (match_operand:SF 2 "memory_operand" "")
7096 (match_operand:SF 3 "register_operand" ""))]
7097 "registers_ok_for_ldd_peep (operands[3], operands[1])
7098 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7101 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7102 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7104 ;; Optimize the case of following a reg-reg move with a test
7105 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7106 ;; This can result from a float to fix conversion.
7109 [(set (match_operand:SI 0 "register_operand" "")
7110 (match_operand:SI 1 "register_operand" ""))
7111 (set (reg:CC CC_REG)
7112 (compare:CC (match_operand:SI 2 "register_operand" "")
7114 "(rtx_equal_p (operands[2], operands[0])
7115 || rtx_equal_p (operands[2], operands[1]))
7116 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7117 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7118 [(parallel [(set (match_dup 0) (match_dup 1))
7119 (set (reg:CC CC_REG)
7120 (compare:CC (match_dup 1) (const_int 0)))])]
7124 [(set (match_operand:DI 0 "register_operand" "")
7125 (match_operand:DI 1 "register_operand" ""))
7126 (set (reg:CCX CC_REG)
7127 (compare:CCX (match_operand:DI 2 "register_operand" "")
7130 && (rtx_equal_p (operands[2], operands[0])
7131 || rtx_equal_p (operands[2], operands[1]))
7132 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7133 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7134 [(parallel [(set (match_dup 0) (match_dup 1))
7135 (set (reg:CCX CC_REG)
7136 (compare:CCX (match_dup 1) (const_int 0)))])]
7140 ;; Prefetch instructions.
7142 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7143 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7144 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7146 (define_expand "prefetch"
7147 [(match_operand 0 "address_operand" "")
7148 (match_operand 1 "const_int_operand" "")
7149 (match_operand 2 "const_int_operand" "")]
7153 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7155 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7159 (define_insn "prefetch_64"
7160 [(prefetch (match_operand:DI 0 "address_operand" "p")
7161 (match_operand:DI 1 "const_int_operand" "n")
7162 (match_operand:DI 2 "const_int_operand" "n"))]
7165 static const char * const prefetch_instr[2][2] = {
7167 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7168 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7171 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7172 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7175 int read_or_write = INTVAL (operands[1]);
7176 int locality = INTVAL (operands[2]);
7178 gcc_assert (read_or_write == 0 || read_or_write == 1);
7179 gcc_assert (locality >= 0 && locality < 4);
7180 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7182 [(set_attr "type" "load")])
7184 (define_insn "prefetch_32"
7185 [(prefetch (match_operand:SI 0 "address_operand" "p")
7186 (match_operand:SI 1 "const_int_operand" "n")
7187 (match_operand:SI 2 "const_int_operand" "n"))]
7190 static const char * const prefetch_instr[2][2] = {
7192 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7193 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7196 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7197 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7200 int read_or_write = INTVAL (operands[1]);
7201 int locality = INTVAL (operands[2]);
7203 gcc_assert (read_or_write == 0 || read_or_write == 1);
7204 gcc_assert (locality >= 0 && locality < 4);
7205 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7207 [(set_attr "type" "load")])
7210 ;; Trap instructions.
7213 [(trap_if (const_int 1) (const_int 5))]
7216 [(set_attr "type" "trap")])
7218 (define_expand "ctrapsi4"
7219 [(trap_if (match_operator 0 "noov_compare_operator"
7220 [(match_operand:SI 1 "compare_operand" "")
7221 (match_operand:SI 2 "arith_operand" "")])
7222 (match_operand 3 ""))]
7224 "operands[1] = gen_compare_reg (operands[0]);
7225 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7227 operands[2] = const0_rtx;")
7229 (define_expand "ctrapdi4"
7230 [(trap_if (match_operator 0 "noov_compare_operator"
7231 [(match_operand:DI 1 "compare_operand" "")
7232 (match_operand:DI 2 "arith_operand" "")])
7233 (match_operand 3 ""))]
7235 "operands[1] = gen_compare_reg (operands[0]);
7236 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7238 operands[2] = const0_rtx;")
7242 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7243 (match_operand:SI 1 "arith_operand" "rM"))]
7247 return "t%C0\t%%icc, %1";
7251 [(set_attr "type" "trap")])
7254 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7255 (match_operand:SI 1 "arith_operand" "rM"))]
7258 [(set_attr "type" "trap")])
7261 ;; TLS support instructions.
7263 (define_insn "tgd_hi22"
7264 [(set (match_operand:SI 0 "register_operand" "=r")
7265 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7268 "sethi\\t%%tgd_hi22(%a1), %0")
7270 (define_insn "tgd_lo10"
7271 [(set (match_operand:SI 0 "register_operand" "=r")
7272 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7273 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7276 "add\\t%1, %%tgd_lo10(%a2), %0")
7278 (define_insn "tgd_add32"
7279 [(set (match_operand:SI 0 "register_operand" "=r")
7280 (plus:SI (match_operand:SI 1 "register_operand" "r")
7281 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7282 (match_operand 3 "tgd_symbolic_operand" "")]
7284 "TARGET_TLS && TARGET_ARCH32"
7285 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7287 (define_insn "tgd_add64"
7288 [(set (match_operand:DI 0 "register_operand" "=r")
7289 (plus:DI (match_operand:DI 1 "register_operand" "r")
7290 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7291 (match_operand 3 "tgd_symbolic_operand" "")]
7293 "TARGET_TLS && TARGET_ARCH64"
7294 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7296 (define_insn "tgd_call32"
7297 [(set (match_operand 0 "register_operand" "=r")
7298 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7299 (match_operand 2 "tgd_symbolic_operand" "")]
7301 (match_operand 3 "" "")))
7302 (clobber (reg:SI O7_REG))]
7303 "TARGET_TLS && TARGET_ARCH32"
7304 "call\t%a1, %%tgd_call(%a2)%#"
7305 [(set_attr "type" "call")])
7307 (define_insn "tgd_call64"
7308 [(set (match_operand 0 "register_operand" "=r")
7309 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7310 (match_operand 2 "tgd_symbolic_operand" "")]
7312 (match_operand 3 "" "")))
7313 (clobber (reg:DI O7_REG))]
7314 "TARGET_TLS && TARGET_ARCH64"
7315 "call\t%a1, %%tgd_call(%a2)%#"
7316 [(set_attr "type" "call")])
7318 (define_insn "tldm_hi22"
7319 [(set (match_operand:SI 0 "register_operand" "=r")
7320 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7322 "sethi\\t%%tldm_hi22(%&), %0")
7324 (define_insn "tldm_lo10"
7325 [(set (match_operand:SI 0 "register_operand" "=r")
7326 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7327 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7329 "add\\t%1, %%tldm_lo10(%&), %0")
7331 (define_insn "tldm_add32"
7332 [(set (match_operand:SI 0 "register_operand" "=r")
7333 (plus:SI (match_operand:SI 1 "register_operand" "r")
7334 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7336 "TARGET_TLS && TARGET_ARCH32"
7337 "add\\t%1, %2, %0, %%tldm_add(%&)")
7339 (define_insn "tldm_add64"
7340 [(set (match_operand:DI 0 "register_operand" "=r")
7341 (plus:DI (match_operand:DI 1 "register_operand" "r")
7342 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7344 "TARGET_TLS && TARGET_ARCH64"
7345 "add\\t%1, %2, %0, %%tldm_add(%&)")
7347 (define_insn "tldm_call32"
7348 [(set (match_operand 0 "register_operand" "=r")
7349 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7351 (match_operand 2 "" "")))
7352 (clobber (reg:SI O7_REG))]
7353 "TARGET_TLS && TARGET_ARCH32"
7354 "call\t%a1, %%tldm_call(%&)%#"
7355 [(set_attr "type" "call")])
7357 (define_insn "tldm_call64"
7358 [(set (match_operand 0 "register_operand" "=r")
7359 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7361 (match_operand 2 "" "")))
7362 (clobber (reg:DI O7_REG))]
7363 "TARGET_TLS && TARGET_ARCH64"
7364 "call\t%a1, %%tldm_call(%&)%#"
7365 [(set_attr "type" "call")])
7367 (define_insn "tldo_hix22"
7368 [(set (match_operand:SI 0 "register_operand" "=r")
7369 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7372 "sethi\\t%%tldo_hix22(%a1), %0")
7374 (define_insn "tldo_lox10"
7375 [(set (match_operand:SI 0 "register_operand" "=r")
7376 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7377 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7380 "xor\\t%1, %%tldo_lox10(%a2), %0")
7382 (define_insn "tldo_add32"
7383 [(set (match_operand:SI 0 "register_operand" "=r")
7384 (plus:SI (match_operand:SI 1 "register_operand" "r")
7385 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7386 (match_operand 3 "tld_symbolic_operand" "")]
7388 "TARGET_TLS && TARGET_ARCH32"
7389 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7391 (define_insn "tldo_add64"
7392 [(set (match_operand:DI 0 "register_operand" "=r")
7393 (plus:DI (match_operand:DI 1 "register_operand" "r")
7394 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7395 (match_operand 3 "tld_symbolic_operand" "")]
7397 "TARGET_TLS && TARGET_ARCH64"
7398 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7400 (define_insn "tie_hi22"
7401 [(set (match_operand:SI 0 "register_operand" "=r")
7402 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7405 "sethi\\t%%tie_hi22(%a1), %0")
7407 (define_insn "tie_lo10"
7408 [(set (match_operand:SI 0 "register_operand" "=r")
7409 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7410 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7413 "add\\t%1, %%tie_lo10(%a2), %0")
7415 (define_insn "tie_ld32"
7416 [(set (match_operand:SI 0 "register_operand" "=r")
7417 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7418 (match_operand:SI 2 "register_operand" "r")
7419 (match_operand 3 "tie_symbolic_operand" "")]
7421 "TARGET_TLS && TARGET_ARCH32"
7422 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7423 [(set_attr "type" "load")])
7425 (define_insn "tie_ld64"
7426 [(set (match_operand:DI 0 "register_operand" "=r")
7427 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7428 (match_operand:SI 2 "register_operand" "r")
7429 (match_operand 3 "tie_symbolic_operand" "")]
7431 "TARGET_TLS && TARGET_ARCH64"
7432 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7433 [(set_attr "type" "load")])
7435 (define_insn "tie_add32"
7436 [(set (match_operand:SI 0 "register_operand" "=r")
7437 (plus:SI (match_operand:SI 1 "register_operand" "r")
7438 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7439 (match_operand 3 "tie_symbolic_operand" "")]
7441 "TARGET_SUN_TLS && TARGET_ARCH32"
7442 "add\\t%1, %2, %0, %%tie_add(%a3)")
7444 (define_insn "tie_add64"
7445 [(set (match_operand:DI 0 "register_operand" "=r")
7446 (plus:DI (match_operand:DI 1 "register_operand" "r")
7447 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7448 (match_operand 3 "tie_symbolic_operand" "")]
7450 "TARGET_SUN_TLS && TARGET_ARCH64"
7451 "add\\t%1, %2, %0, %%tie_add(%a3)")
7453 (define_insn "tle_hix22_sp32"
7454 [(set (match_operand:SI 0 "register_operand" "=r")
7455 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7457 "TARGET_TLS && TARGET_ARCH32"
7458 "sethi\\t%%tle_hix22(%a1), %0")
7460 (define_insn "tle_lox10_sp32"
7461 [(set (match_operand:SI 0 "register_operand" "=r")
7462 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7463 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7465 "TARGET_TLS && TARGET_ARCH32"
7466 "xor\\t%1, %%tle_lox10(%a2), %0")
7468 (define_insn "tle_hix22_sp64"
7469 [(set (match_operand:DI 0 "register_operand" "=r")
7470 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7472 "TARGET_TLS && TARGET_ARCH64"
7473 "sethi\\t%%tle_hix22(%a1), %0")
7475 (define_insn "tle_lox10_sp64"
7476 [(set (match_operand:DI 0 "register_operand" "=r")
7477 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7478 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7480 "TARGET_TLS && TARGET_ARCH64"
7481 "xor\\t%1, %%tle_lox10(%a2), %0")
7483 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7484 (define_insn "*tldo_ldub_sp32"
7485 [(set (match_operand:QI 0 "register_operand" "=r")
7486 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7487 (match_operand 3 "tld_symbolic_operand" "")]
7489 (match_operand:SI 1 "register_operand" "r"))))]
7490 "TARGET_TLS && TARGET_ARCH32"
7491 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7492 [(set_attr "type" "load")
7493 (set_attr "us3load_type" "3cycle")])
7495 (define_insn "*tldo_ldub1_sp32"
7496 [(set (match_operand:HI 0 "register_operand" "=r")
7497 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7498 (match_operand 3 "tld_symbolic_operand" "")]
7500 (match_operand:SI 1 "register_operand" "r")))))]
7501 "TARGET_TLS && TARGET_ARCH32"
7502 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7503 [(set_attr "type" "load")
7504 (set_attr "us3load_type" "3cycle")])
7506 (define_insn "*tldo_ldub2_sp32"
7507 [(set (match_operand:SI 0 "register_operand" "=r")
7508 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7509 (match_operand 3 "tld_symbolic_operand" "")]
7511 (match_operand:SI 1 "register_operand" "r")))))]
7512 "TARGET_TLS && TARGET_ARCH32"
7513 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7514 [(set_attr "type" "load")
7515 (set_attr "us3load_type" "3cycle")])
7517 (define_insn "*tldo_ldsb1_sp32"
7518 [(set (match_operand:HI 0 "register_operand" "=r")
7519 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7520 (match_operand 3 "tld_symbolic_operand" "")]
7522 (match_operand:SI 1 "register_operand" "r")))))]
7523 "TARGET_TLS && TARGET_ARCH32"
7524 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7525 [(set_attr "type" "sload")
7526 (set_attr "us3load_type" "3cycle")])
7528 (define_insn "*tldo_ldsb2_sp32"
7529 [(set (match_operand:SI 0 "register_operand" "=r")
7530 (sign_extend:SI (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 "TARGET_TLS && TARGET_ARCH32"
7535 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7536 [(set_attr "type" "sload")
7537 (set_attr "us3load_type" "3cycle")])
7539 (define_insn "*tldo_ldub_sp64"
7540 [(set (match_operand:QI 0 "register_operand" "=r")
7541 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7542 (match_operand 3 "tld_symbolic_operand" "")]
7544 (match_operand:DI 1 "register_operand" "r"))))]
7545 "TARGET_TLS && TARGET_ARCH64"
7546 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7547 [(set_attr "type" "load")
7548 (set_attr "us3load_type" "3cycle")])
7550 (define_insn "*tldo_ldub1_sp64"
7551 [(set (match_operand:HI 0 "register_operand" "=r")
7552 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7553 (match_operand 3 "tld_symbolic_operand" "")]
7555 (match_operand:DI 1 "register_operand" "r")))))]
7556 "TARGET_TLS && TARGET_ARCH64"
7557 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7558 [(set_attr "type" "load")
7559 (set_attr "us3load_type" "3cycle")])
7561 (define_insn "*tldo_ldub2_sp64"
7562 [(set (match_operand:SI 0 "register_operand" "=r")
7563 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7564 (match_operand 3 "tld_symbolic_operand" "")]
7566 (match_operand:DI 1 "register_operand" "r")))))]
7567 "TARGET_TLS && TARGET_ARCH64"
7568 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7569 [(set_attr "type" "load")
7570 (set_attr "us3load_type" "3cycle")])
7572 (define_insn "*tldo_ldub3_sp64"
7573 [(set (match_operand:DI 0 "register_operand" "=r")
7574 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7575 (match_operand 3 "tld_symbolic_operand" "")]
7577 (match_operand:DI 1 "register_operand" "r")))))]
7578 "TARGET_TLS && TARGET_ARCH64"
7579 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7580 [(set_attr "type" "load")
7581 (set_attr "us3load_type" "3cycle")])
7583 (define_insn "*tldo_ldsb1_sp64"
7584 [(set (match_operand:HI 0 "register_operand" "=r")
7585 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7586 (match_operand 3 "tld_symbolic_operand" "")]
7588 (match_operand:DI 1 "register_operand" "r")))))]
7589 "TARGET_TLS && TARGET_ARCH64"
7590 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7591 [(set_attr "type" "sload")
7592 (set_attr "us3load_type" "3cycle")])
7594 (define_insn "*tldo_ldsb2_sp64"
7595 [(set (match_operand:SI 0 "register_operand" "=r")
7596 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7597 (match_operand 3 "tld_symbolic_operand" "")]
7599 (match_operand:DI 1 "register_operand" "r")))))]
7600 "TARGET_TLS && TARGET_ARCH64"
7601 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7602 [(set_attr "type" "sload")
7603 (set_attr "us3load_type" "3cycle")])
7605 (define_insn "*tldo_ldsb3_sp64"
7606 [(set (match_operand:DI 0 "register_operand" "=r")
7607 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7608 (match_operand 3 "tld_symbolic_operand" "")]
7610 (match_operand:DI 1 "register_operand" "r")))))]
7611 "TARGET_TLS && TARGET_ARCH64"
7612 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7613 [(set_attr "type" "sload")
7614 (set_attr "us3load_type" "3cycle")])
7616 (define_insn "*tldo_lduh_sp32"
7617 [(set (match_operand:HI 0 "register_operand" "=r")
7618 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7619 (match_operand 3 "tld_symbolic_operand" "")]
7621 (match_operand:SI 1 "register_operand" "r"))))]
7622 "TARGET_TLS && TARGET_ARCH32"
7623 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7624 [(set_attr "type" "load")
7625 (set_attr "us3load_type" "3cycle")])
7627 (define_insn "*tldo_lduh1_sp32"
7628 [(set (match_operand:SI 0 "register_operand" "=r")
7629 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7630 (match_operand 3 "tld_symbolic_operand" "")]
7632 (match_operand:SI 1 "register_operand" "r")))))]
7633 "TARGET_TLS && TARGET_ARCH32"
7634 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7635 [(set_attr "type" "load")
7636 (set_attr "us3load_type" "3cycle")])
7638 (define_insn "*tldo_ldsh1_sp32"
7639 [(set (match_operand:SI 0 "register_operand" "=r")
7640 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7641 (match_operand 3 "tld_symbolic_operand" "")]
7643 (match_operand:SI 1 "register_operand" "r")))))]
7644 "TARGET_TLS && TARGET_ARCH32"
7645 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7646 [(set_attr "type" "sload")
7647 (set_attr "us3load_type" "3cycle")])
7649 (define_insn "*tldo_lduh_sp64"
7650 [(set (match_operand:HI 0 "register_operand" "=r")
7651 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7652 (match_operand 3 "tld_symbolic_operand" "")]
7654 (match_operand:DI 1 "register_operand" "r"))))]
7655 "TARGET_TLS && TARGET_ARCH64"
7656 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7657 [(set_attr "type" "load")
7658 (set_attr "us3load_type" "3cycle")])
7660 (define_insn "*tldo_lduh1_sp64"
7661 [(set (match_operand:SI 0 "register_operand" "=r")
7662 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7663 (match_operand 3 "tld_symbolic_operand" "")]
7665 (match_operand:DI 1 "register_operand" "r")))))]
7666 "TARGET_TLS && TARGET_ARCH64"
7667 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7668 [(set_attr "type" "load")
7669 (set_attr "us3load_type" "3cycle")])
7671 (define_insn "*tldo_lduh2_sp64"
7672 [(set (match_operand:DI 0 "register_operand" "=r")
7673 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7674 (match_operand 3 "tld_symbolic_operand" "")]
7676 (match_operand:DI 1 "register_operand" "r")))))]
7677 "TARGET_TLS && TARGET_ARCH64"
7678 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7679 [(set_attr "type" "load")
7680 (set_attr "us3load_type" "3cycle")])
7682 (define_insn "*tldo_ldsh1_sp64"
7683 [(set (match_operand:SI 0 "register_operand" "=r")
7684 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7685 (match_operand 3 "tld_symbolic_operand" "")]
7687 (match_operand:DI 1 "register_operand" "r")))))]
7688 "TARGET_TLS && TARGET_ARCH64"
7689 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7690 [(set_attr "type" "sload")
7691 (set_attr "us3load_type" "3cycle")])
7693 (define_insn "*tldo_ldsh2_sp64"
7694 [(set (match_operand:DI 0 "register_operand" "=r")
7695 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7696 (match_operand 3 "tld_symbolic_operand" "")]
7698 (match_operand:DI 1 "register_operand" "r")))))]
7699 "TARGET_TLS && TARGET_ARCH64"
7700 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7701 [(set_attr "type" "sload")
7702 (set_attr "us3load_type" "3cycle")])
7704 (define_insn "*tldo_lduw_sp32"
7705 [(set (match_operand:SI 0 "register_operand" "=r")
7706 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7707 (match_operand 3 "tld_symbolic_operand" "")]
7709 (match_operand:SI 1 "register_operand" "r"))))]
7710 "TARGET_TLS && TARGET_ARCH32"
7711 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7712 [(set_attr "type" "load")])
7714 (define_insn "*tldo_lduw_sp64"
7715 [(set (match_operand:SI 0 "register_operand" "=r")
7716 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7717 (match_operand 3 "tld_symbolic_operand" "")]
7719 (match_operand:DI 1 "register_operand" "r"))))]
7720 "TARGET_TLS && TARGET_ARCH64"
7721 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7722 [(set_attr "type" "load")])
7724 (define_insn "*tldo_lduw1_sp64"
7725 [(set (match_operand:DI 0 "register_operand" "=r")
7726 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7727 (match_operand 3 "tld_symbolic_operand" "")]
7729 (match_operand:DI 1 "register_operand" "r")))))]
7730 "TARGET_TLS && TARGET_ARCH64"
7731 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7732 [(set_attr "type" "load")])
7734 (define_insn "*tldo_ldsw1_sp64"
7735 [(set (match_operand:DI 0 "register_operand" "=r")
7736 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7737 (match_operand 3 "tld_symbolic_operand" "")]
7739 (match_operand:DI 1 "register_operand" "r")))))]
7740 "TARGET_TLS && TARGET_ARCH64"
7741 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7742 [(set_attr "type" "sload")
7743 (set_attr "us3load_type" "3cycle")])
7745 (define_insn "*tldo_ldx_sp64"
7746 [(set (match_operand:DI 0 "register_operand" "=r")
7747 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7748 (match_operand 3 "tld_symbolic_operand" "")]
7750 (match_operand:DI 1 "register_operand" "r"))))]
7751 "TARGET_TLS && TARGET_ARCH64"
7752 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7753 [(set_attr "type" "load")])
7755 (define_insn "*tldo_stb_sp32"
7756 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7757 (match_operand 3 "tld_symbolic_operand" "")]
7759 (match_operand:SI 1 "register_operand" "r")))
7760 (match_operand:QI 0 "register_operand" "r"))]
7761 "TARGET_TLS && TARGET_ARCH32"
7762 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7763 [(set_attr "type" "store")])
7765 (define_insn "*tldo_stb_sp64"
7766 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7767 (match_operand 3 "tld_symbolic_operand" "")]
7769 (match_operand:DI 1 "register_operand" "r")))
7770 (match_operand:QI 0 "register_operand" "r"))]
7771 "TARGET_TLS && TARGET_ARCH64"
7772 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7773 [(set_attr "type" "store")])
7775 (define_insn "*tldo_sth_sp32"
7776 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7777 (match_operand 3 "tld_symbolic_operand" "")]
7779 (match_operand:SI 1 "register_operand" "r")))
7780 (match_operand:HI 0 "register_operand" "r"))]
7781 "TARGET_TLS && TARGET_ARCH32"
7782 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7783 [(set_attr "type" "store")])
7785 (define_insn "*tldo_sth_sp64"
7786 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7787 (match_operand 3 "tld_symbolic_operand" "")]
7789 (match_operand:DI 1 "register_operand" "r")))
7790 (match_operand:HI 0 "register_operand" "r"))]
7791 "TARGET_TLS && TARGET_ARCH64"
7792 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7793 [(set_attr "type" "store")])
7795 (define_insn "*tldo_stw_sp32"
7796 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7797 (match_operand 3 "tld_symbolic_operand" "")]
7799 (match_operand:SI 1 "register_operand" "r")))
7800 (match_operand:SI 0 "register_operand" "r"))]
7801 "TARGET_TLS && TARGET_ARCH32"
7802 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7803 [(set_attr "type" "store")])
7805 (define_insn "*tldo_stw_sp64"
7806 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7807 (match_operand 3 "tld_symbolic_operand" "")]
7809 (match_operand:DI 1 "register_operand" "r")))
7810 (match_operand:SI 0 "register_operand" "r"))]
7811 "TARGET_TLS && TARGET_ARCH64"
7812 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7813 [(set_attr "type" "store")])
7815 (define_insn "*tldo_stx_sp64"
7816 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7817 (match_operand 3 "tld_symbolic_operand" "")]
7819 (match_operand:DI 1 "register_operand" "r")))
7820 (match_operand:DI 0 "register_operand" "r"))]
7821 "TARGET_TLS && TARGET_ARCH64"
7822 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7823 [(set_attr "type" "store")])
7826 ;; Stack protector instructions.
7828 (define_expand "stack_protect_set"
7829 [(match_operand 0 "memory_operand" "")
7830 (match_operand 1 "memory_operand" "")]
7833 #ifdef TARGET_THREAD_SSP_OFFSET
7834 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7835 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7836 operands[1] = gen_rtx_MEM (Pmode, addr);
7839 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7841 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7845 (define_insn "stack_protect_setsi"
7846 [(set (match_operand:SI 0 "memory_operand" "=m")
7847 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7848 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7850 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7851 [(set_attr "type" "multi")
7852 (set_attr "length" "3")])
7854 (define_insn "stack_protect_setdi"
7855 [(set (match_operand:DI 0 "memory_operand" "=m")
7856 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7857 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7859 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7860 [(set_attr "type" "multi")
7861 (set_attr "length" "3")])
7863 (define_expand "stack_protect_test"
7864 [(match_operand 0 "memory_operand" "")
7865 (match_operand 1 "memory_operand" "")
7866 (match_operand 2 "" "")]
7870 #ifdef TARGET_THREAD_SSP_OFFSET
7871 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7872 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7873 operands[1] = gen_rtx_MEM (Pmode, addr);
7877 result = gen_reg_rtx (Pmode);
7878 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7879 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7880 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7884 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7885 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7886 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7887 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7892 (define_insn "stack_protect_testsi"
7893 [(set (reg:CC CC_REG)
7894 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7895 (match_operand:SI 1 "memory_operand" "m")]
7897 (set (match_scratch:SI 3 "=r") (const_int 0))
7898 (clobber (match_scratch:SI 2 "=&r"))]
7900 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7901 [(set_attr "type" "multi")
7902 (set_attr "length" "4")])
7904 (define_insn "stack_protect_testdi"
7905 [(set (match_operand:DI 0 "register_operand" "=&r")
7906 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7907 (match_operand:DI 2 "memory_operand" "m")]
7909 (set (match_scratch:DI 3 "=r") (const_int 0))]
7911 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7912 [(set_attr "type" "multi")
7913 (set_attr "length" "4")])
7915 ;; Vector instructions.
7917 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7918 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7919 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7921 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
7922 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7923 (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7924 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7925 (V1DI "double") (V2SI "double") (V4HI "double")
7928 (define_expand "mov<VMALL:mode>"
7929 [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7930 (match_operand:VMALL 1 "general_operand" ""))]
7933 if (sparc_expand_move (<VMALL:MODE>mode, operands))
7937 (define_insn "*mov<VM32:mode>_insn"
7938 [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
7939 (match_operand:VM32 1 "input_operand" "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
7941 && (register_operand (operands[0], <VM32:MODE>mode)
7942 || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7955 [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv")
7956 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
7958 (define_insn "*mov<VM64:mode>_insn_sp64"
7959 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
7960 (match_operand:VM64 1 "input_operand" "Y,C,e,m,e,Y, m,*r, e,*r,*r"))]
7963 && (register_operand (operands[0], <VM64:MODE>mode)
7964 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7977 [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*")
7978 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
7980 (define_insn "*mov<VM64:mode>_insn_sp32"
7981 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
7982 (match_operand:VM64 1 "input_operand" "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
7985 && (register_operand (operands[0], <VM64:MODE>mode)
7986 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
8000 [(set_attr "type" "visl,visl,vismv,*,*,fpload,fpstore,store,load,store,*,*")
8001 (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
8002 (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
8005 [(set (match_operand:VM64 0 "memory_operand" "")
8006 (match_operand:VM64 1 "register_operand" ""))]
8010 && (((REGNO (operands[1]) % 2) != 0)
8011 || ! mem_min_alignment (operands[0], 8))
8012 && offsettable_memref_p (operands[0])"
8013 [(clobber (const_int 0))]
8017 word0 = adjust_address (operands[0], SImode, 0);
8018 word1 = adjust_address (operands[0], SImode, 4);
8020 emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
8021 emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
8026 [(set (match_operand:VM64 0 "register_operand" "")
8027 (match_operand:VM64 1 "register_operand" ""))]
8031 && sparc_split_regreg_legitimate (operands[0], operands[1])"
8032 [(clobber (const_int 0))]
8034 rtx set_dest = operands[0];
8035 rtx set_src = operands[1];
8039 dest1 = gen_highpart (SImode, set_dest);
8040 dest2 = gen_lowpart (SImode, set_dest);
8041 src1 = gen_highpart (SImode, set_src);
8042 src2 = gen_lowpart (SImode, set_src);
8044 /* Now emit using the real source and destination we found, swapping
8045 the order if we detect overlap. */
8046 if (reg_overlap_mentioned_p (dest1, src2))
8048 emit_insn (gen_movsi (dest2, src2));
8049 emit_insn (gen_movsi (dest1, src1));
8053 emit_insn (gen_movsi (dest1, src1));
8054 emit_insn (gen_movsi (dest2, src2));
8059 (define_expand "vec_init<mode>"
8060 [(match_operand:VMALL 0 "register_operand" "")
8061 (match_operand:VMALL 1 "" "")]
8064 sparc_expand_vector_init (operands[0], operands[1]);
8068 (define_code_iterator plusminus [plus minus])
8069 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
8071 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
8073 (define_insn "<plusminus_insn><mode>3"
8074 [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
8075 (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
8076 (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
8078 "fp<plusminus_insn><vbits>\t%1, %2, %0"
8079 [(set_attr "type" "fga")
8080 (set_attr "fptype" "<vfptype>")])
8082 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8083 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
8084 (V1DI "") (V2SI "") (V4HI "") (V8QI "")])
8085 (define_code_iterator vlop [ior and xor])
8086 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
8087 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
8089 (define_insn "<code><mode>3"
8090 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8091 (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8092 (match_operand:VL 2 "register_operand" "<vconstr>")))]
8094 "f<vlinsn><vlsuf>\t%1, %2, %0"
8095 [(set_attr "type" "visl")
8096 (set_attr "fptype" "<vfptype>")])
8098 (define_insn "*not_<code><mode>3"
8099 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8100 (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8101 (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8103 "f<vlninsn><vlsuf>\t%1, %2, %0"
8104 [(set_attr "type" "visl")
8105 (set_attr "fptype" "<vfptype>")])
8107 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8108 (define_insn "*nand<mode>_vis"
8109 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8110 (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8111 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8113 "fnand<vlsuf>\t%1, %2, %0"
8114 [(set_attr "type" "visl")
8115 (set_attr "fptype" "<vfptype>")])
8117 (define_code_iterator vlnotop [ior and])
8119 (define_insn "*<code>_not1<mode>_vis"
8120 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8121 (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8122 (match_operand:VL 2 "register_operand" "<vconstr>")))]
8124 "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
8125 [(set_attr "type" "visl")
8126 (set_attr "fptype" "<vfptype>")])
8128 (define_insn "*<code>_not2<mode>_vis"
8129 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8130 (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8131 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8133 "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
8134 [(set_attr "type" "visl")
8135 (set_attr "fptype" "<vfptype>")])
8137 (define_insn "one_cmpl<mode>2"
8138 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8139 (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
8141 "fnot1<vlsuf>\t%1, %0"
8142 [(set_attr "type" "visl")
8143 (set_attr "fptype" "<vfptype>")])
8145 ;; Hard to generate VIS instructions. We have builtins for these.
8147 (define_insn "fpack16_vis"
8148 [(set (match_operand:V4QI 0 "register_operand" "=f")
8149 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
8154 [(set_attr "type" "fgm_pack")
8155 (set_attr "fptype" "double")])
8157 (define_insn "fpackfix_vis"
8158 [(set (match_operand:V2HI 0 "register_operand" "=f")
8159 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
8164 [(set_attr "type" "fgm_pack")
8165 (set_attr "fptype" "double")])
8167 (define_insn "fpack32_vis"
8168 [(set (match_operand:V8QI 0 "register_operand" "=e")
8169 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8170 (match_operand:V8QI 2 "register_operand" "e")
8174 "fpack32\t%1, %2, %0"
8175 [(set_attr "type" "fgm_pack")
8176 (set_attr "fptype" "double")])
8178 (define_insn "fexpand_vis"
8179 [(set (match_operand:V4HI 0 "register_operand" "=e")
8180 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8184 [(set_attr "type" "fga")
8185 (set_attr "fptype" "double")])
8187 (define_insn "fpmerge_vis"
8188 [(set (match_operand:V8QI 0 "register_operand" "=e")
8190 (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8191 (match_operand:V4QI 2 "register_operand" "f"))
8192 (parallel [(const_int 0) (const_int 4)
8193 (const_int 1) (const_int 5)
8194 (const_int 2) (const_int 6)
8195 (const_int 3) (const_int 7)])))]
8197 "fpmerge\t%1, %2, %0"
8198 [(set_attr "type" "fga")
8199 (set_attr "fptype" "double")])
8201 (define_insn "vec_interleave_lowv8qi"
8202 [(set (match_operand:V8QI 0 "register_operand" "=e")
8204 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8205 (match_operand:V8QI 2 "register_operand" "f"))
8206 (parallel [(const_int 0) (const_int 8)
8207 (const_int 1) (const_int 9)
8208 (const_int 2) (const_int 10)
8209 (const_int 3) (const_int 11)])))]
8211 "fpmerge\t%L1, %L2, %0"
8212 [(set_attr "type" "fga")
8213 (set_attr "fptype" "double")])
8215 (define_insn "vec_interleave_highv8qi"
8216 [(set (match_operand:V8QI 0 "register_operand" "=e")
8218 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8219 (match_operand:V8QI 2 "register_operand" "f"))
8220 (parallel [(const_int 4) (const_int 12)
8221 (const_int 5) (const_int 13)
8222 (const_int 6) (const_int 14)
8223 (const_int 7) (const_int 15)])))]
8225 "fpmerge\t%H1, %H2, %0"
8226 [(set_attr "type" "fga")
8227 (set_attr "fptype" "double")])
8229 ;; Partitioned multiply instructions
8230 (define_insn "fmul8x16_vis"
8231 [(set (match_operand:V4HI 0 "register_operand" "=e")
8232 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8233 (match_operand:V4HI 2 "register_operand" "e")]
8236 "fmul8x16\t%1, %2, %0"
8237 [(set_attr "type" "fgm_mul")
8238 (set_attr "fptype" "double")])
8240 (define_insn "fmul8x16au_vis"
8241 [(set (match_operand:V4HI 0 "register_operand" "=e")
8242 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8243 (match_operand:V2HI 2 "register_operand" "f")]
8246 "fmul8x16au\t%1, %2, %0"
8247 [(set_attr "type" "fgm_mul")
8248 (set_attr "fptype" "double")])
8250 (define_insn "fmul8x16al_vis"
8251 [(set (match_operand:V4HI 0 "register_operand" "=e")
8252 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8253 (match_operand:V2HI 2 "register_operand" "f")]
8256 "fmul8x16al\t%1, %2, %0"
8257 [(set_attr "type" "fgm_mul")
8258 (set_attr "fptype" "double")])
8260 (define_insn "fmul8sux16_vis"
8261 [(set (match_operand:V4HI 0 "register_operand" "=e")
8262 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8263 (match_operand:V4HI 2 "register_operand" "e")]
8266 "fmul8sux16\t%1, %2, %0"
8267 [(set_attr "type" "fgm_mul")
8268 (set_attr "fptype" "double")])
8270 (define_insn "fmul8ulx16_vis"
8271 [(set (match_operand:V4HI 0 "register_operand" "=e")
8272 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8273 (match_operand:V4HI 2 "register_operand" "e")]
8276 "fmul8ulx16\t%1, %2, %0"
8277 [(set_attr "type" "fgm_mul")
8278 (set_attr "fptype" "double")])
8280 (define_insn "fmuld8sux16_vis"
8281 [(set (match_operand:V2SI 0 "register_operand" "=e")
8282 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8283 (match_operand:V2HI 2 "register_operand" "f")]
8286 "fmuld8sux16\t%1, %2, %0"
8287 [(set_attr "type" "fgm_mul")
8288 (set_attr "fptype" "double")])
8290 (define_insn "fmuld8ulx16_vis"
8291 [(set (match_operand:V2SI 0 "register_operand" "=e")
8292 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8293 (match_operand:V2HI 2 "register_operand" "f")]
8296 "fmuld8ulx16\t%1, %2, %0"
8297 [(set_attr "type" "fgm_mul")
8298 (set_attr "fptype" "double")])
8300 (define_expand "wrgsr_vis"
8301 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8304 if (! TARGET_ARCH64)
8306 emit_insn (gen_wrgsr_v8plus (operands[0]));
8311 (define_insn "*wrgsr_sp64"
8312 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8313 "TARGET_VIS && TARGET_ARCH64"
8314 "wr\t%%g0, %0, %%gsr"
8315 [(set_attr "type" "gsr")])
8317 (define_insn "wrgsr_v8plus"
8318 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8319 (clobber (match_scratch:SI 1 "=X,&h"))]
8320 "TARGET_VIS && ! TARGET_ARCH64"
8322 if (GET_CODE (operands[0]) == CONST_INT
8323 || sparc_check_64 (operands[0], insn))
8324 return "wr\t%%g0, %0, %%gsr";
8326 output_asm_insn("srl\t%L0, 0, %L0", operands);
8327 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8329 [(set_attr "type" "multi")])
8331 (define_expand "rdgsr_vis"
8332 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8335 if (! TARGET_ARCH64)
8337 emit_insn (gen_rdgsr_v8plus (operands[0]));
8342 (define_insn "*rdgsr_sp64"
8343 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8344 "TARGET_VIS && TARGET_ARCH64"
8346 [(set_attr "type" "gsr")])
8348 (define_insn "rdgsr_v8plus"
8349 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8350 (clobber (match_scratch:SI 1 "=&h"))]
8351 "TARGET_VIS && ! TARGET_ARCH64"
8353 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8355 [(set_attr "type" "multi")])
8357 ;; Using faligndata only makes sense after an alignaddr since the choice of
8358 ;; bytes to take out of each operand is dependent on the results of the last
8360 (define_insn "faligndata<VM64:mode>_vis"
8361 [(set (match_operand:VM64 0 "register_operand" "=e")
8362 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8363 (match_operand:VM64 2 "register_operand" "e")
8367 "faligndata\t%1, %2, %0"
8368 [(set_attr "type" "fga")
8369 (set_attr "fptype" "double")])
8371 (define_insn "alignaddrsi_vis"
8372 [(set (match_operand:SI 0 "register_operand" "=r")
8373 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8374 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8375 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8376 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8378 "alignaddr\t%r1, %r2, %0"
8379 [(set_attr "type" "gsr")])
8381 (define_insn "alignaddrdi_vis"
8382 [(set (match_operand:DI 0 "register_operand" "=r")
8383 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8384 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8385 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8386 (plus:DI (match_dup 1) (match_dup 2)))]
8388 "alignaddr\t%r1, %r2, %0"
8389 [(set_attr "type" "gsr")])
8391 (define_insn "alignaddrlsi_vis"
8392 [(set (match_operand:SI 0 "register_operand" "=r")
8393 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8394 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8395 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8396 (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8399 "alignaddrl\t%r1, %r2, %0"
8400 [(set_attr "type" "gsr")])
8402 (define_insn "alignaddrldi_vis"
8403 [(set (match_operand:DI 0 "register_operand" "=r")
8404 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8405 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8406 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8407 (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8410 "alignaddrl\t%r1, %r2, %0"
8411 [(set_attr "type" "gsr")])
8413 (define_insn "pdist_vis"
8414 [(set (match_operand:DI 0 "register_operand" "=e")
8415 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8416 (match_operand:V8QI 2 "register_operand" "e")
8417 (match_operand:DI 3 "register_operand" "0")]
8421 [(set_attr "type" "pdist")
8422 (set_attr "fptype" "double")])
8424 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8425 ;; with the same operands.
8426 (define_insn "edge8<P:mode>_vis"
8427 [(set (reg:CC_NOOV CC_REG)
8428 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8429 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8431 (set (match_operand:P 0 "register_operand" "=r")
8432 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8434 "edge8\t%r1, %r2, %0"
8435 [(set_attr "type" "edge")])
8437 (define_insn "edge8l<P:mode>_vis"
8438 [(set (reg:CC_NOOV CC_REG)
8439 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8440 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8442 (set (match_operand:P 0 "register_operand" "=r")
8443 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8445 "edge8l\t%r1, %r2, %0"
8446 [(set_attr "type" "edge")])
8448 (define_insn "edge16<P:mode>_vis"
8449 [(set (reg:CC_NOOV CC_REG)
8450 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8451 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8453 (set (match_operand:P 0 "register_operand" "=r")
8454 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8456 "edge16\t%r1, %r2, %0"
8457 [(set_attr "type" "edge")])
8459 (define_insn "edge16l<P:mode>_vis"
8460 [(set (reg:CC_NOOV CC_REG)
8461 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8462 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8464 (set (match_operand:P 0 "register_operand" "=r")
8465 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8467 "edge16l\t%r1, %r2, %0"
8468 [(set_attr "type" "edge")])
8470 (define_insn "edge32<P:mode>_vis"
8471 [(set (reg:CC_NOOV CC_REG)
8472 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8473 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8475 (set (match_operand:P 0 "register_operand" "=r")
8476 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8478 "edge32\t%r1, %r2, %0"
8479 [(set_attr "type" "edge")])
8481 (define_insn "edge32l<P:mode>_vis"
8482 [(set (reg:CC_NOOV CC_REG)
8483 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8484 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8486 (set (match_operand:P 0 "register_operand" "=r")
8487 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8489 "edge32l\t%r1, %r2, %0"
8490 [(set_attr "type" "edge")])
8492 (define_code_iterator gcond [le ne gt eq])
8493 (define_mode_iterator GCM [V4HI V2SI])
8494 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8496 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8497 [(set (match_operand:P 0 "register_operand" "=r")
8498 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8499 (match_operand:GCM 2 "register_operand" "e"))]
8502 "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8503 [(set_attr "type" "visl")
8504 (set_attr "fptype" "double")])
8506 (define_expand "vcond<mode><mode>"
8507 [(match_operand:GCM 0 "register_operand" "")
8508 (match_operand:GCM 1 "register_operand" "")
8509 (match_operand:GCM 2 "register_operand" "")
8510 (match_operator 3 ""
8511 [(match_operand:GCM 4 "register_operand" "")
8512 (match_operand:GCM 5 "register_operand" "")])]
8515 sparc_expand_vcond (<MODE>mode, operands,
8516 UNSPEC_CMASK<gcm_name>,
8521 (define_expand "vconduv8qiv8qi"
8522 [(match_operand:V8QI 0 "register_operand" "")
8523 (match_operand:V8QI 1 "register_operand" "")
8524 (match_operand:V8QI 2 "register_operand" "")
8525 (match_operator 3 ""
8526 [(match_operand:V8QI 4 "register_operand" "")
8527 (match_operand:V8QI 5 "register_operand" "")])]
8530 sparc_expand_vcond (V8QImode, operands,
8536 (define_insn "array8<P:mode>_vis"
8537 [(set (match_operand:P 0 "register_operand" "=r")
8538 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8539 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8542 "array8\t%r1, %r2, %0"
8543 [(set_attr "type" "array")])
8545 (define_insn "array16<P:mode>_vis"
8546 [(set (match_operand:P 0 "register_operand" "=r")
8547 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8548 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8551 "array16\t%r1, %r2, %0"
8552 [(set_attr "type" "array")])
8554 (define_insn "array32<P:mode>_vis"
8555 [(set (match_operand:P 0 "register_operand" "=r")
8556 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8557 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8560 "array32\t%r1, %r2, %0"
8561 [(set_attr "type" "array")])
8563 (define_insn "bmaskdi_vis"
8564 [(set (match_operand:DI 0 "register_operand" "=r")
8565 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8566 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8567 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8568 (plus:DI (match_dup 1) (match_dup 2)))]
8570 "bmask\t%r1, %r2, %0"
8571 [(set_attr "type" "array")])
8573 (define_insn "bmasksi_vis"
8574 [(set (match_operand:SI 0 "register_operand" "=r")
8575 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8576 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8577 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8578 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8580 "bmask\t%r1, %r2, %0"
8581 [(set_attr "type" "array")])
8583 (define_insn "bshuffle<VM64:mode>_vis"
8584 [(set (match_operand:VM64 0 "register_operand" "=e")
8585 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8586 (match_operand:VM64 2 "register_operand" "e")
8590 "bshuffle\t%1, %2, %0"
8591 [(set_attr "type" "fga")
8592 (set_attr "fptype" "double")])
8594 ;; The rtl expanders will happily convert constant permutations on other
8595 ;; modes down to V8QI. Rely on this to avoid the complexity of the byte
8596 ;; order of the permutation.
8597 (define_expand "vec_perm_constv8qi"
8598 [(match_operand:V8QI 0 "register_operand" "")
8599 (match_operand:V8QI 1 "register_operand" "")
8600 (match_operand:V8QI 2 "register_operand" "")
8601 (match_operand:V8QI 3 "" "")]
8604 unsigned int i, mask;
8605 rtx sel = operands[3];
8607 for (i = mask = 0; i < 8; ++i)
8608 mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8609 sel = force_reg (SImode, gen_int_mode (mask, SImode));
8611 emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, const0_rtx));
8612 emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8616 ;; Unlike constant permutation, we can vastly simplify the compression of
8617 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8618 ;; width of the input is.
8619 (define_expand "vec_perm<mode>"
8620 [(match_operand:VM64 0 "register_operand" "")
8621 (match_operand:VM64 1 "register_operand" "")
8622 (match_operand:VM64 2 "register_operand" "")
8623 (match_operand:VM64 3 "register_operand" "")]
8626 sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8627 emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8631 ;; VIS 2.0 adds edge variants which do not set the condition codes
8632 (define_insn "edge8n<P:mode>_vis"
8633 [(set (match_operand:P 0 "register_operand" "=r")
8634 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8635 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8638 "edge8n\t%r1, %r2, %0"
8639 [(set_attr "type" "edgen")])
8641 (define_insn "edge8ln<P:mode>_vis"
8642 [(set (match_operand:P 0 "register_operand" "=r")
8643 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8644 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8647 "edge8ln\t%r1, %r2, %0"
8648 [(set_attr "type" "edgen")])
8650 (define_insn "edge16n<P:mode>_vis"
8651 [(set (match_operand:P 0 "register_operand" "=r")
8652 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8653 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8656 "edge16n\t%r1, %r2, %0"
8657 [(set_attr "type" "edgen")])
8659 (define_insn "edge16ln<P:mode>_vis"
8660 [(set (match_operand:P 0 "register_operand" "=r")
8661 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8662 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8665 "edge16ln\t%r1, %r2, %0"
8666 [(set_attr "type" "edgen")])
8668 (define_insn "edge32n<P:mode>_vis"
8669 [(set (match_operand:P 0 "register_operand" "=r")
8670 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8671 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8674 "edge32n\t%r1, %r2, %0"
8675 [(set_attr "type" "edgen")])
8677 (define_insn "edge32ln<P:mode>_vis"
8678 [(set (match_operand:P 0 "register_operand" "=r")
8679 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8680 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8683 "edge32ln\t%r1, %r2, %0"
8684 [(set_attr "type" "edge")])
8686 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8687 (define_insn "cmask8<P:mode>_vis"
8688 [(set (reg:DI GSR_REG)
8689 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8694 [(set_attr "type" "fga")])
8696 (define_insn "cmask16<P:mode>_vis"
8697 [(set (reg:DI GSR_REG)
8698 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8703 [(set_attr "type" "fga")])
8705 (define_insn "cmask32<P:mode>_vis"
8706 [(set (reg:DI GSR_REG)
8707 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8712 [(set_attr "type" "fga")])
8714 (define_insn "fchksm16_vis"
8715 [(set (match_operand:V4HI 0 "register_operand" "=e")
8716 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8717 (match_operand:V4HI 2 "register_operand" "e")]
8720 "fchksm16\t%1, %2, %0"
8721 [(set_attr "type" "fga")])
8723 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8724 (define_code_attr vis3_shift_insn
8725 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8726 (define_code_attr vis3_shift_patname
8727 [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8729 (define_insn "v<vis3_shift_patname><mode>3"
8730 [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8731 (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8732 (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8734 "<vis3_shift_insn><vbits>\t%1, %2, %0"
8735 [(set_attr "type" "fga")])
8737 (define_insn "pdistn<mode>_vis"
8738 [(set (match_operand:P 0 "register_operand" "=r")
8739 (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8740 (match_operand:V8QI 2 "register_operand" "e")]
8743 "pdistn\t%1, %2, %0"
8744 [(set_attr "type" "pdistn")
8745 (set_attr "fptype" "double")])
8747 (define_insn "fmean16_vis"
8748 [(set (match_operand:V4HI 0 "register_operand" "=e")
8754 (match_operand:V4HI 1 "register_operand" "e"))
8756 (match_operand:V4HI 2 "register_operand" "e")))
8757 (const_vector:V4SI [(const_int 1) (const_int 1)
8758 (const_int 1) (const_int 1)]))
8761 "fmean16\t%1, %2, %0"
8762 [(set_attr "type" "fga")])
8764 (define_insn "fp<plusminus_insn>64_vis"
8765 [(set (match_operand:V1DI 0 "register_operand" "=e")
8766 (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8767 (match_operand:V1DI 2 "register_operand" "e")))]
8769 "fp<plusminus_insn>64\t%1, %2, %0"
8770 [(set_attr "type" "fga")])
8772 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8773 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8774 (define_code_attr vis3_addsub_ss_insn
8775 [(ss_plus "fpadds") (ss_minus "fpsubs")])
8776 (define_code_attr vis3_addsub_ss_patname
8777 [(ss_plus "ssadd") (ss_minus "sssub")])
8779 (define_insn "<vis3_addsub_ss_patname><mode>3"
8780 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8781 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8782 (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8784 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
8785 [(set_attr "type" "fga")])
8787 (define_insn "fucmp<code>8<P:mode>_vis"
8788 [(set (match_operand:P 0 "register_operand" "=r")
8789 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8790 (match_operand:V8QI 2 "register_operand" "e"))]
8793 "fucmp<code>8\t%1, %2, %0"
8794 [(set_attr "type" "visl")])
8796 (define_insn "*naddsf3"
8797 [(set (match_operand:SF 0 "register_operand" "=f")
8798 (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8799 (match_operand:SF 2 "register_operand" "f"))))]
8801 "fnadds\t%1, %2, %0"
8802 [(set_attr "type" "fp")])
8804 (define_insn "*nadddf3"
8805 [(set (match_operand:DF 0 "register_operand" "=e")
8806 (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8807 (match_operand:DF 2 "register_operand" "e"))))]
8809 "fnaddd\t%1, %2, %0"
8810 [(set_attr "type" "fp")
8811 (set_attr "fptype" "double")])
8813 (define_insn "*nmulsf3"
8814 [(set (match_operand:SF 0 "register_operand" "=f")
8815 (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8816 (match_operand:SF 2 "register_operand" "f")))]
8818 "fnmuls\t%1, %2, %0"
8819 [(set_attr "type" "fpmul")])
8821 (define_insn "*nmuldf3"
8822 [(set (match_operand:DF 0 "register_operand" "=e")
8823 (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8824 (match_operand:DF 2 "register_operand" "e")))]
8826 "fnmuld\t%1, %2, %0"
8827 [(set_attr "type" "fpmul")
8828 (set_attr "fptype" "double")])
8830 (define_insn "*nmuldf3_extend"
8831 [(set (match_operand:DF 0 "register_operand" "=e")
8832 (mult:DF (neg:DF (float_extend:DF
8833 (match_operand:SF 1 "register_operand" "f")))
8835 (match_operand:SF 2 "register_operand" "f"))))]
8837 "fnsmuld\t%1, %2, %0"
8838 [(set_attr "type" "fpmul")
8839 (set_attr "fptype" "double")])
8841 (define_insn "fhaddsf_vis"
8842 [(set (match_operand:SF 0 "register_operand" "=f")
8843 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8844 (match_operand:SF 2 "register_operand" "f")]
8847 "fhadds\t%1, %2, %0"
8848 [(set_attr "type" "fp")])
8850 (define_insn "fhadddf_vis"
8851 [(set (match_operand:DF 0 "register_operand" "=f")
8852 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8853 (match_operand:DF 2 "register_operand" "f")]
8856 "fhaddd\t%1, %2, %0"
8857 [(set_attr "type" "fp")
8858 (set_attr "fptype" "double")])
8860 (define_insn "fhsubsf_vis"
8861 [(set (match_operand:SF 0 "register_operand" "=f")
8862 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8863 (match_operand:SF 2 "register_operand" "f")]
8866 "fhsubs\t%1, %2, %0"
8867 [(set_attr "type" "fp")])
8869 (define_insn "fhsubdf_vis"
8870 [(set (match_operand:DF 0 "register_operand" "=f")
8871 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8872 (match_operand:DF 2 "register_operand" "f")]
8875 "fhsubd\t%1, %2, %0"
8876 [(set_attr "type" "fp")
8877 (set_attr "fptype" "double")])
8879 (define_insn "fnhaddsf_vis"
8880 [(set (match_operand:SF 0 "register_operand" "=f")
8881 (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8882 (match_operand:SF 2 "register_operand" "f")]
8885 "fnhadds\t%1, %2, %0"
8886 [(set_attr "type" "fp")])
8888 (define_insn "fnhadddf_vis"
8889 [(set (match_operand:DF 0 "register_operand" "=f")
8890 (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8891 (match_operand:DF 2 "register_operand" "f")]
8894 "fnhaddd\t%1, %2, %0"
8895 [(set_attr "type" "fp")
8896 (set_attr "fptype" "double")])
8898 (define_expand "umulxhi_vis"
8899 [(set (match_operand:DI 0 "register_operand" "")
8902 (mult:TI (zero_extend:TI
8903 (match_operand:DI 1 "arith_operand" ""))
8905 (match_operand:DI 2 "arith_operand" "")))
8909 if (! TARGET_ARCH64)
8911 emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8916 (define_insn "*umulxhi_sp64"
8917 [(set (match_operand:DI 0 "register_operand" "=r")
8920 (mult:TI (zero_extend:TI
8921 (match_operand:DI 1 "arith_operand" "%r"))
8923 (match_operand:DI 2 "arith_operand" "rI")))
8925 "TARGET_VIS3 && TARGET_ARCH64"
8926 "umulxhi\t%1, %2, %0"
8927 [(set_attr "type" "imul")])
8929 (define_insn "umulxhi_v8plus"
8930 [(set (match_operand:DI 0 "register_operand" "=r,h")
8933 (mult:TI (zero_extend:TI
8934 (match_operand:DI 1 "arith_operand" "%r,0"))
8936 (match_operand:DI 2 "arith_operand" "rI,rI")))
8938 (clobber (match_scratch:SI 3 "=&h,X"))
8939 (clobber (match_scratch:SI 4 "=&h,X"))]
8940 "TARGET_VIS3 && ! TARGET_ARCH64"
8941 "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8942 [(set_attr "type" "imul")
8943 (set_attr "length" "9,8")])
8945 (define_expand "xmulx_vis"
8946 [(set (match_operand:DI 0 "register_operand" "")
8948 (unspec:TI [(zero_extend:TI
8949 (match_operand:DI 1 "arith_operand" ""))
8951 (match_operand:DI 2 "arith_operand" ""))]
8955 if (! TARGET_ARCH64)
8957 emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8962 (define_insn "*xmulx_sp64"
8963 [(set (match_operand:DI 0 "register_operand" "=r")
8965 (unspec:TI [(zero_extend:TI
8966 (match_operand:DI 1 "arith_operand" "%r"))
8968 (match_operand:DI 2 "arith_operand" "rI"))]
8970 "TARGET_VIS3 && TARGET_ARCH64"
8972 [(set_attr "type" "imul")])
8974 (define_insn "xmulx_v8plus"
8975 [(set (match_operand:DI 0 "register_operand" "=r,h")
8977 (unspec:TI [(zero_extend:TI
8978 (match_operand:DI 1 "arith_operand" "%r,0"))
8980 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8982 (clobber (match_scratch:SI 3 "=&h,X"))
8983 (clobber (match_scratch:SI 4 "=&h,X"))]
8984 "TARGET_VIS3 && ! TARGET_ARCH64"
8985 "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8986 [(set_attr "type" "imul")
8987 (set_attr "length" "9,8")])
8989 (define_expand "xmulxhi_vis"
8990 [(set (match_operand:DI 0 "register_operand" "")
8993 (unspec:TI [(zero_extend:TI
8994 (match_operand:DI 1 "arith_operand" ""))
8996 (match_operand:DI 2 "arith_operand" ""))]
9001 if (! TARGET_ARCH64)
9003 emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
9008 (define_insn "*xmulxhi_sp64"
9009 [(set (match_operand:DI 0 "register_operand" "=r")
9012 (unspec:TI [(zero_extend:TI
9013 (match_operand:DI 1 "arith_operand" "%r"))
9015 (match_operand:DI 2 "arith_operand" "rI"))]
9018 "TARGET_VIS3 && TARGET_ARCH64"
9019 "xmulxhi\t%1, %2, %0"
9020 [(set_attr "type" "imul")])
9022 (define_insn "xmulxhi_v8plus"
9023 [(set (match_operand:DI 0 "register_operand" "=r,h")
9026 (unspec:TI [(zero_extend:TI
9027 (match_operand:DI 1 "arith_operand" "%r,0"))
9029 (match_operand:DI 2 "arith_operand" "rI,rI"))]
9032 (clobber (match_scratch:SI 3 "=&h,X"))
9033 (clobber (match_scratch:SI 4 "=&h,X"))]
9034 "TARGET_VIS3 && !TARGET_ARCH64"
9035 "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
9036 [(set_attr "type" "imul")
9037 (set_attr "length" "9,8")])