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,
267 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,edgen,gsr,array,
270 multi,savew,flushw,iflush,trap"
271 (const_string "ialu"))
273 ;; True if branch/call has empty delay slot and will emit a nop in it
274 (define_attr "empty_delay_slot" "false,true"
275 (symbol_ref "(empty_delay_slot (insn)
276 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
278 (define_attr "branch_type" "none,icc,fcc,reg"
279 (const_string "none"))
281 (define_attr "pic" "false,true"
282 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
284 (define_attr "calls_alloca" "false,true"
285 (symbol_ref "(cfun->calls_alloca != 0
286 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
288 (define_attr "calls_eh_return" "false,true"
289 (symbol_ref "(crtl->calls_eh_return != 0
290 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
292 (define_attr "leaf_function" "false,true"
293 (symbol_ref "(current_function_uses_only_leaf_regs != 0
294 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
296 (define_attr "delayed_branch" "false,true"
297 (symbol_ref "(flag_delayed_branch != 0
298 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
300 (define_attr "flat" "false,true"
301 (symbol_ref "(TARGET_FLAT != 0
302 ? FLAT_TRUE : FLAT_FALSE)"))
304 ;; Length (in # of insns).
305 ;; Beware that setting a length greater or equal to 3 for conditional branches
306 ;; has a side-effect (see output_cbranch and output_v9branch).
307 (define_attr "length" ""
308 (cond [(eq_attr "type" "uncond_branch,call")
309 (if_then_else (eq_attr "empty_delay_slot" "true")
312 (eq_attr "type" "sibcall")
313 (if_then_else (eq_attr "leaf_function" "true")
314 (if_then_else (eq_attr "empty_delay_slot" "true")
317 (if_then_else (eq_attr "empty_delay_slot" "true")
320 (eq_attr "branch_type" "icc")
321 (if_then_else (match_operand 0 "noov_compare64_operator" "")
322 (if_then_else (lt (pc) (match_dup 1))
323 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
324 (if_then_else (eq_attr "empty_delay_slot" "true")
327 (if_then_else (eq_attr "empty_delay_slot" "true")
330 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
331 (if_then_else (eq_attr "empty_delay_slot" "true")
334 (if_then_else (eq_attr "empty_delay_slot" "true")
337 (if_then_else (eq_attr "empty_delay_slot" "true")
340 (eq_attr "branch_type" "fcc")
341 (if_then_else (match_operand 0 "fcc0_register_operand" "")
342 (if_then_else (eq_attr "empty_delay_slot" "true")
343 (if_then_else (not (match_test "TARGET_V9"))
346 (if_then_else (not (match_test "TARGET_V9"))
349 (if_then_else (lt (pc) (match_dup 2))
350 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
351 (if_then_else (eq_attr "empty_delay_slot" "true")
354 (if_then_else (eq_attr "empty_delay_slot" "true")
357 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
358 (if_then_else (eq_attr "empty_delay_slot" "true")
361 (if_then_else (eq_attr "empty_delay_slot" "true")
364 (eq_attr "branch_type" "reg")
365 (if_then_else (lt (pc) (match_dup 2))
366 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
367 (if_then_else (eq_attr "empty_delay_slot" "true")
370 (if_then_else (eq_attr "empty_delay_slot" "true")
373 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
374 (if_then_else (eq_attr "empty_delay_slot" "true")
377 (if_then_else (eq_attr "empty_delay_slot" "true")
383 (define_attr "fptype" "single,double"
384 (const_string "single"))
386 ;; UltraSPARC-III integer load type.
387 (define_attr "us3load_type" "2cycle,3cycle"
388 (const_string "2cycle"))
390 (define_asm_attributes
391 [(set_attr "length" "2")
392 (set_attr "type" "multi")])
394 ;; Attributes for instruction and branch scheduling
395 (define_attr "tls_call_delay" "false,true"
396 (symbol_ref "(tls_call_delay (insn)
397 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
399 (define_attr "in_call_delay" "false,true"
400 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
401 (const_string "false")
402 (eq_attr "type" "load,fpload,store,fpstore")
403 (if_then_else (eq_attr "length" "1")
404 (const_string "true")
405 (const_string "false"))]
406 (if_then_else (and (eq_attr "length" "1")
407 (eq_attr "tls_call_delay" "true"))
408 (const_string "true")
409 (const_string "false"))))
411 (define_attr "eligible_for_sibcall_delay" "false,true"
412 (symbol_ref "(eligible_for_sibcall_delay (insn)
413 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
414 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
416 (define_attr "eligible_for_return_delay" "false,true"
417 (symbol_ref "(eligible_for_return_delay (insn)
418 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
419 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
421 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
422 ;; branches. This would allow us to remove the nop always inserted before
423 ;; a floating point branch.
425 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
426 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
427 ;; This is because doing so will add several pipeline stalls to the path
428 ;; that the load/store did not come from. Unfortunately, there is no way
429 ;; to prevent fill_eager_delay_slots from using load/store without completely
430 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
431 ;; because it prevents us from moving back the final store of inner loops.
433 (define_attr "in_branch_delay" "false,true"
434 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
435 (eq_attr "length" "1"))
436 (const_string "true")
437 (const_string "false")))
439 (define_attr "in_uncond_branch_delay" "false,true"
440 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
441 (eq_attr "length" "1"))
442 (const_string "true")
443 (const_string "false")))
445 (define_attr "in_annul_branch_delay" "false,true"
446 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
447 (eq_attr "length" "1"))
448 (const_string "true")
449 (const_string "false")))
451 (define_delay (eq_attr "type" "call")
452 [(eq_attr "in_call_delay" "true") (nil) (nil)])
454 (define_delay (eq_attr "type" "sibcall")
455 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
457 (define_delay (eq_attr "type" "branch")
458 [(eq_attr "in_branch_delay" "true")
459 (nil) (eq_attr "in_annul_branch_delay" "true")])
461 (define_delay (eq_attr "type" "uncond_branch")
462 [(eq_attr "in_uncond_branch_delay" "true")
465 (define_delay (eq_attr "type" "return")
466 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
469 ;; Include SPARC DFA schedulers
471 (include "cypress.md")
472 (include "supersparc.md")
473 (include "hypersparc.md")
475 (include "sparclet.md")
476 (include "ultra1_2.md")
477 (include "ultra3.md")
478 (include "niagara.md")
479 (include "niagara2.md")
482 ;; Operand and operator predicates and constraints
484 (include "predicates.md")
485 (include "constraints.md")
488 ;; Compare instructions.
490 ;; These are just the DEFINE_INSNs to match the patterns and the
491 ;; DEFINE_SPLITs for some of the scc insns that actually require
492 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
494 ;; The compare DEFINE_INSNs.
496 (define_insn "*cmpsi_insn"
497 [(set (reg:CC CC_REG)
498 (compare:CC (match_operand:SI 0 "register_operand" "r")
499 (match_operand:SI 1 "arith_operand" "rI")))]
502 [(set_attr "type" "compare")])
504 (define_insn "*cmpdi_sp64"
505 [(set (reg:CCX CC_REG)
506 (compare:CCX (match_operand:DI 0 "register_operand" "r")
507 (match_operand:DI 1 "arith_operand" "rI")))]
510 [(set_attr "type" "compare")])
512 (define_insn "*cmpsf_fpe"
513 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
514 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
515 (match_operand:SF 2 "register_operand" "f")))]
519 return "fcmpes\t%0, %1, %2";
520 return "fcmpes\t%1, %2";
522 [(set_attr "type" "fpcmp")])
524 (define_insn "*cmpdf_fpe"
525 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
526 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
527 (match_operand:DF 2 "register_operand" "e")))]
531 return "fcmped\t%0, %1, %2";
532 return "fcmped\t%1, %2";
534 [(set_attr "type" "fpcmp")
535 (set_attr "fptype" "double")])
537 (define_insn "*cmptf_fpe"
538 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
539 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
540 (match_operand:TF 2 "register_operand" "e")))]
541 "TARGET_FPU && TARGET_HARD_QUAD"
544 return "fcmpeq\t%0, %1, %2";
545 return "fcmpeq\t%1, %2";
547 [(set_attr "type" "fpcmp")])
549 (define_insn "*cmpsf_fp"
550 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
551 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
552 (match_operand:SF 2 "register_operand" "f")))]
556 return "fcmps\t%0, %1, %2";
557 return "fcmps\t%1, %2";
559 [(set_attr "type" "fpcmp")])
561 (define_insn "*cmpdf_fp"
562 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
563 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
564 (match_operand:DF 2 "register_operand" "e")))]
568 return "fcmpd\t%0, %1, %2";
569 return "fcmpd\t%1, %2";
571 [(set_attr "type" "fpcmp")
572 (set_attr "fptype" "double")])
574 (define_insn "*cmptf_fp"
575 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
576 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
577 (match_operand:TF 2 "register_operand" "e")))]
578 "TARGET_FPU && TARGET_HARD_QUAD"
581 return "fcmpq\t%0, %1, %2";
582 return "fcmpq\t%1, %2";
584 [(set_attr "type" "fpcmp")])
586 ;; Next come the scc insns.
588 (define_expand "cstoresi4"
589 [(use (match_operator 1 "comparison_operator"
590 [(match_operand:SI 2 "compare_operand" "")
591 (match_operand:SI 3 "arith_operand" "")]))
592 (clobber (match_operand:SI 0 "register_operand"))]
595 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
596 operands[2] = force_reg (SImode, operands[2]);
597 if (emit_scc_insn (operands)) DONE; else FAIL;
600 (define_expand "cstoredi4"
601 [(use (match_operator 1 "comparison_operator"
602 [(match_operand:DI 2 "compare_operand" "")
603 (match_operand:DI 3 "arith_operand" "")]))
604 (clobber (match_operand:SI 0 "register_operand"))]
607 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
608 operands[2] = force_reg (DImode, operands[2]);
609 if (emit_scc_insn (operands)) DONE; else FAIL;
612 (define_expand "cstore<F:mode>4"
613 [(use (match_operator 1 "comparison_operator"
614 [(match_operand:F 2 "register_operand" "")
615 (match_operand:F 3 "register_operand" "")]))
616 (clobber (match_operand:SI 0 "register_operand"))]
618 { if (emit_scc_insn (operands)) DONE; else FAIL; })
622 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
623 ;; generate addcc/subcc instructions.
625 (define_expand "seqsi_special"
627 (xor:SI (match_operand:SI 1 "register_operand" "")
628 (match_operand:SI 2 "register_operand" "")))
629 (parallel [(set (match_operand:SI 0 "register_operand" "")
630 (eq:SI (match_dup 3) (const_int 0)))
631 (clobber (reg:CC CC_REG))])]
633 { operands[3] = gen_reg_rtx (SImode); })
635 (define_expand "seqdi_special"
637 (xor:DI (match_operand:DI 1 "register_operand" "")
638 (match_operand:DI 2 "register_operand" "")))
639 (set (match_operand:SI 0 "register_operand" "")
640 (eq:SI (match_dup 3) (const_int 0)))]
642 { operands[3] = gen_reg_rtx (DImode); })
644 (define_expand "snesi_special"
646 (xor:SI (match_operand:SI 1 "register_operand" "")
647 (match_operand:SI 2 "register_operand" "")))
648 (parallel [(set (match_operand:SI 0 "register_operand" "")
649 (ne:SI (match_dup 3) (const_int 0)))
650 (clobber (reg:CC CC_REG))])]
652 { operands[3] = gen_reg_rtx (SImode); })
654 (define_expand "snedi_special"
656 (xor:DI (match_operand:DI 1 "register_operand" "")
657 (match_operand:DI 2 "register_operand" "")))
658 (set (match_operand:SI 0 "register_operand" "")
659 (ne:SI (match_dup 3) (const_int 0)))]
660 "TARGET_ARCH64 && ! TARGET_VIS3"
661 { operands[3] = gen_reg_rtx (DImode); })
663 (define_expand "snedi_special_vis3"
665 (xor:DI (match_operand:DI 1 "register_operand" "")
666 (match_operand:DI 2 "register_operand" "")))
667 (parallel [(set (match_operand:SI 0 "register_operand" "")
668 (ne:SI (match_dup 3) (const_int 0)))
669 (clobber (reg:CCX CC_REG))])]
670 "TARGET_ARCH64 && TARGET_VIS3"
671 { operands[3] = gen_reg_rtx (DImode); })
674 ;; Now the DEFINE_INSNs for the scc cases.
676 ;; The SEQ and SNE patterns are special because they can be done
677 ;; without any branching and do not involve a COMPARE. We want
678 ;; them to always use the splits below so the results can be
681 (define_insn_and_split "*snesi_zero"
682 [(set (match_operand:SI 0 "register_operand" "=r")
683 (ne:SI (match_operand:SI 1 "register_operand" "r")
685 (clobber (reg:CC CC_REG))]
689 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
691 (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
693 [(set_attr "length" "2")])
695 (define_insn_and_split "*neg_snesi_zero"
696 [(set (match_operand:SI 0 "register_operand" "=r")
697 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
699 (clobber (reg:CC CC_REG))]
703 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
705 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
707 [(set_attr "length" "2")])
709 (define_insn_and_split "*snesi_zero_extend"
710 [(set (match_operand:DI 0 "register_operand" "=r")
711 (ne:DI (match_operand:SI 1 "register_operand" "r")
713 (clobber (reg:CC CC_REG))]
717 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
720 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
722 (ltu:SI (reg:CC_NOOV CC_REG)
725 [(set_attr "length" "2")])
727 (define_insn_and_split "*neg_snesi_sign_extend"
728 [(set (match_operand:DI 0 "register_operand" "=r")
729 (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r")
731 (clobber (reg:CC CC_REG))]
735 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
738 (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG)
741 [(set_attr "length" "2")])
743 (define_insn_and_split "*snedi_zero"
744 [(set (match_operand:DI 0 "register_operand" "=&r")
745 (ne:DI (match_operand:DI 1 "register_operand" "r")
747 "TARGET_ARCH64 && ! TARGET_VIS3"
749 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
750 [(set (match_dup 0) (const_int 0))
751 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
756 [(set_attr "length" "2")])
758 (define_insn_and_split "*snedi_zero_vis3"
759 [(set (match_operand:DI 0 "register_operand" "=r")
760 (ne:DI (match_operand:DI 1 "register_operand" "r")
762 (clobber (reg:CCX CC_REG))]
763 "TARGET_ARCH64 && TARGET_VIS3"
766 [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
768 (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
770 [(set_attr "length" "2")])
772 (define_insn_and_split "*neg_snedi_zero"
773 [(set (match_operand:DI 0 "register_operand" "=&r")
774 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
778 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
779 [(set (match_dup 0) (const_int 0))
780 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
785 [(set_attr "length" "2")])
787 (define_insn_and_split "*snedi_zero_trunc"
788 [(set (match_operand:SI 0 "register_operand" "=&r")
789 (ne:SI (match_operand:DI 1 "register_operand" "r")
791 "TARGET_ARCH64 && ! TARGET_VIS3"
793 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
794 [(set (match_dup 0) (const_int 0))
795 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
800 [(set_attr "length" "2")])
802 (define_insn_and_split "*snedi_zero_trunc_vis3"
803 [(set (match_operand:SI 0 "register_operand" "=r")
804 (ne:SI (match_operand:DI 1 "register_operand" "r")
806 (clobber (reg:CCX CC_REG))]
807 "TARGET_ARCH64 && TARGET_VIS3"
810 [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
812 (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
814 [(set_attr "length" "2")])
816 (define_insn_and_split "*seqsi_zero"
817 [(set (match_operand:SI 0 "register_operand" "=r")
818 (eq:SI (match_operand:SI 1 "register_operand" "r")
820 (clobber (reg:CC CC_REG))]
824 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
826 (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
828 [(set_attr "length" "2")])
830 (define_insn_and_split "*neg_seqsi_zero"
831 [(set (match_operand:SI 0 "register_operand" "=r")
832 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
834 (clobber (reg:CC CC_REG))]
838 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
840 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
842 [(set_attr "length" "2")])
844 (define_insn_and_split "*seqsi_zero_extend"
845 [(set (match_operand:DI 0 "register_operand" "=r")
846 (eq:DI (match_operand:SI 1 "register_operand" "r")
848 (clobber (reg:CC CC_REG))]
852 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
855 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
857 (ltu:SI (reg:CC_NOOV CC_REG)
860 [(set_attr "length" "2")])
862 (define_insn_and_split "*neg_seqsi_sign_extend"
863 [(set (match_operand:DI 0 "register_operand" "=r")
864 (neg:DI (eq:DI (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) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG)
875 [(set_attr "length" "2")])
877 (define_insn_and_split "*seqdi_zero"
878 [(set (match_operand:DI 0 "register_operand" "=&r")
879 (eq:DI (match_operand:DI 1 "register_operand" "r")
883 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
884 [(set (match_dup 0) (const_int 0))
885 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
890 [(set_attr "length" "2")])
892 (define_insn_and_split "*neg_seqdi_zero"
893 [(set (match_operand:DI 0 "register_operand" "=&r")
894 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
898 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
899 [(set (match_dup 0) (const_int 0))
900 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
905 [(set_attr "length" "2")])
907 (define_insn_and_split "*seqdi_zero_trunc"
908 [(set (match_operand:SI 0 "register_operand" "=&r")
909 (eq:SI (match_operand:DI 1 "register_operand" "r")
913 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
914 [(set (match_dup 0) (const_int 0))
915 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
920 [(set_attr "length" "2")])
922 ;; We can also do (x + (i == 0)) and related, so put them in.
923 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
926 (define_insn_and_split "*x_plus_i_ne_0"
927 [(set (match_operand:SI 0 "register_operand" "=r")
928 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
930 (match_operand:SI 2 "register_operand" "r")))
931 (clobber (reg:CC CC_REG))]
935 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
937 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
940 [(set_attr "length" "2")])
942 (define_insn_and_split "*x_minus_i_ne_0"
943 [(set (match_operand:SI 0 "register_operand" "=r")
944 (minus:SI (match_operand:SI 2 "register_operand" "r")
945 (ne:SI (match_operand:SI 1 "register_operand" "r")
947 (clobber (reg:CC CC_REG))]
951 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
953 (set (match_dup 0) (minus:SI (match_dup 2)
954 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
956 [(set_attr "length" "2")])
958 (define_insn_and_split "*x_plus_i_eq_0"
959 [(set (match_operand:SI 0 "register_operand" "=r")
960 (plus:SI (eq: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 (geu:SI (reg:CC CC_REG) (const_int 0))
972 [(set_attr "length" "2")])
974 (define_insn_and_split "*x_minus_i_eq_0"
975 [(set (match_operand:SI 0 "register_operand" "=r")
976 (minus:SI (match_operand:SI 2 "register_operand" "r")
977 (eq: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 (geu:SI (reg:CC CC_REG) (const_int 0))))]
988 [(set_attr "length" "2")])
990 ;; We can also do GEU and LTU directly, but these operate after a compare.
991 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
994 (define_insn "*sltu_insn"
995 [(set (match_operand:SI 0 "register_operand" "=r")
996 (ltu:SI (reg:CC CC_REG) (const_int 0)))]
999 [(set_attr "type" "ialuX")])
1001 (define_insn "*sltu_insn_vis3"
1002 [(set (match_operand:DI 0 "register_operand" "=r")
1003 (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
1004 "TARGET_ARCH64 && TARGET_VIS3"
1005 "addxc\t%%g0, %%g0, %0"
1006 [(set_attr "type" "ialuX")])
1008 (define_insn "*sltu_insn_vis3_trunc"
1009 [(set (match_operand:SI 0 "register_operand" "=r")
1010 (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
1011 "TARGET_ARCH64 && TARGET_VIS3"
1012 "addxc\t%%g0, %%g0, %0"
1013 [(set_attr "type" "ialuX")])
1015 (define_insn "*sltu_extend_sp64"
1016 [(set (match_operand:DI 0 "register_operand" "=r")
1017 (ltu:DI (reg:CC CC_REG) (const_int 0)))]
1020 [(set_attr "type" "ialuX")])
1022 (define_insn "*neg_sltu_insn"
1023 [(set (match_operand:SI 0 "register_operand" "=r")
1024 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1027 [(set_attr "type" "ialuX")])
1029 (define_insn "*neg_sltu_extend_sp64"
1030 [(set (match_operand:DI 0 "register_operand" "=r")
1031 (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))]
1034 [(set_attr "type" "ialuX")])
1036 ;; ??? Combine should canonicalize these next two to the same pattern.
1037 (define_insn "*neg_sltu_minus_x"
1038 [(set (match_operand:SI 0 "register_operand" "=r")
1039 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
1040 (match_operand:SI 1 "arith_operand" "rI")))]
1042 "subx\t%%g0, %1, %0"
1043 [(set_attr "type" "ialuX")])
1045 (define_insn "*neg_sltu_plus_x"
1046 [(set (match_operand:SI 0 "register_operand" "=r")
1047 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1048 (match_operand:SI 1 "arith_operand" "rI"))))]
1050 "subx\t%%g0, %1, %0"
1051 [(set_attr "type" "ialuX")])
1053 (define_insn "*sgeu_insn"
1054 [(set (match_operand:SI 0 "register_operand" "=r")
1055 (geu:SI (reg:CC CC_REG) (const_int 0)))]
1057 "subx\t%%g0, -1, %0"
1058 [(set_attr "type" "ialuX")])
1060 (define_insn "*sgeu_extend_sp64"
1061 [(set (match_operand:DI 0 "register_operand" "=r")
1062 (geu:DI (reg:CC CC_REG) (const_int 0)))]
1064 "subx\t%%g0, -1, %0"
1065 [(set_attr "type" "ialuX")])
1067 (define_insn "*neg_sgeu_insn"
1068 [(set (match_operand:SI 0 "register_operand" "=r")
1069 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
1071 "addx\t%%g0, -1, %0"
1072 [(set_attr "type" "ialuX")])
1074 (define_insn "*neg_sgeu_extend_sp64"
1075 [(set (match_operand:DI 0 "register_operand" "=r")
1076 (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))]
1078 "addx\t%%g0, -1, %0"
1079 [(set_attr "type" "ialuX")])
1081 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1082 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1085 (define_insn "*sltu_plus_x"
1086 [(set (match_operand:SI 0 "register_operand" "=r")
1087 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1088 (match_operand:SI 1 "arith_operand" "rI")))]
1090 "addx\t%%g0, %1, %0"
1091 [(set_attr "type" "ialuX")])
1093 (define_insn "*sltu_plus_x_plus_y"
1094 [(set (match_operand:SI 0 "register_operand" "=r")
1095 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1096 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1097 (match_operand:SI 2 "arith_operand" "rI"))))]
1100 [(set_attr "type" "ialuX")])
1102 (define_insn "*x_minus_sltu"
1103 [(set (match_operand:SI 0 "register_operand" "=r")
1104 (minus:SI (match_operand:SI 1 "register_operand" "r")
1105 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1108 [(set_attr "type" "ialuX")])
1110 ;; ??? Combine should canonicalize these next two to the same pattern.
1111 (define_insn "*x_minus_y_minus_sltu"
1112 [(set (match_operand:SI 0 "register_operand" "=r")
1113 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1114 (match_operand:SI 2 "arith_operand" "rI"))
1115 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1118 [(set_attr "type" "ialuX")])
1120 (define_insn "*x_minus_sltu_plus_y"
1121 [(set (match_operand:SI 0 "register_operand" "=r")
1122 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1123 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1124 (match_operand:SI 2 "arith_operand" "rI"))))]
1127 [(set_attr "type" "ialuX")])
1129 (define_insn "*sgeu_plus_x"
1130 [(set (match_operand:SI 0 "register_operand" "=r")
1131 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1132 (match_operand:SI 1 "register_operand" "r")))]
1135 [(set_attr "type" "ialuX")])
1137 (define_insn "*x_minus_sgeu"
1138 [(set (match_operand:SI 0 "register_operand" "=r")
1139 (minus:SI (match_operand:SI 1 "register_operand" "r")
1140 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1143 [(set_attr "type" "ialuX")])
1146 [(set (match_operand:SI 0 "register_operand" "")
1147 (match_operator:SI 2 "noov_compare_operator"
1148 [(match_operand 1 "icc_or_fcc_register_operand" "")
1151 && REGNO (operands[1]) == SPARC_ICC_REG
1152 && (GET_MODE (operands[1]) == CCXmode
1153 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1154 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1155 [(set (match_dup 0) (const_int 0))
1157 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1163 ;; These control RTL generation for conditional jump insns
1165 (define_expand "cbranchcc4"
1167 (if_then_else (match_operator 0 "comparison_operator"
1168 [(match_operand 1 "compare_operand" "")
1169 (match_operand 2 "const_zero_operand" "")])
1170 (label_ref (match_operand 3 "" ""))
1175 (define_expand "cbranchsi4"
1176 [(use (match_operator 0 "comparison_operator"
1177 [(match_operand:SI 1 "compare_operand" "")
1178 (match_operand:SI 2 "arith_operand" "")]))
1179 (use (match_operand 3 ""))]
1182 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1183 operands[1] = force_reg (SImode, operands[1]);
1184 emit_conditional_branch_insn (operands);
1188 (define_expand "cbranchdi4"
1189 [(use (match_operator 0 "comparison_operator"
1190 [(match_operand:DI 1 "compare_operand" "")
1191 (match_operand:DI 2 "arith_operand" "")]))
1192 (use (match_operand 3 ""))]
1195 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1196 operands[1] = force_reg (DImode, operands[1]);
1197 emit_conditional_branch_insn (operands);
1201 (define_expand "cbranch<F:mode>4"
1202 [(use (match_operator 0 "comparison_operator"
1203 [(match_operand:F 1 "register_operand" "")
1204 (match_operand:F 2 "register_operand" "")]))
1205 (use (match_operand 3 ""))]
1207 { emit_conditional_branch_insn (operands); DONE; })
1210 ;; Now match both normal and inverted jump.
1212 ;; XXX fpcmp nop braindamage
1213 (define_insn "*normal_branch"
1215 (if_then_else (match_operator 0 "noov_compare_operator"
1216 [(reg CC_REG) (const_int 0)])
1217 (label_ref (match_operand 1 "" ""))
1221 return output_cbranch (operands[0], operands[1], 1, 0,
1222 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1225 [(set_attr "type" "branch")
1226 (set_attr "branch_type" "icc")])
1228 ;; XXX fpcmp nop braindamage
1229 (define_insn "*inverted_branch"
1231 (if_then_else (match_operator 0 "noov_compare_operator"
1232 [(reg CC_REG) (const_int 0)])
1234 (label_ref (match_operand 1 "" ""))))]
1237 return output_cbranch (operands[0], operands[1], 1, 1,
1238 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1241 [(set_attr "type" "branch")
1242 (set_attr "branch_type" "icc")])
1244 ;; XXX fpcmp nop braindamage
1245 (define_insn "*normal_fp_branch"
1247 (if_then_else (match_operator 1 "comparison_operator"
1248 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1250 (label_ref (match_operand 2 "" ""))
1254 return output_cbranch (operands[1], operands[2], 2, 0,
1255 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1258 [(set_attr "type" "branch")
1259 (set_attr "branch_type" "fcc")])
1261 ;; XXX fpcmp nop braindamage
1262 (define_insn "*inverted_fp_branch"
1264 (if_then_else (match_operator 1 "comparison_operator"
1265 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1268 (label_ref (match_operand 2 "" ""))))]
1271 return output_cbranch (operands[1], operands[2], 2, 1,
1272 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1275 [(set_attr "type" "branch")
1276 (set_attr "branch_type" "fcc")])
1278 ;; XXX fpcmp nop braindamage
1279 (define_insn "*normal_fpe_branch"
1281 (if_then_else (match_operator 1 "comparison_operator"
1282 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1284 (label_ref (match_operand 2 "" ""))
1288 return output_cbranch (operands[1], operands[2], 2, 0,
1289 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1292 [(set_attr "type" "branch")
1293 (set_attr "branch_type" "fcc")])
1295 ;; XXX fpcmp nop braindamage
1296 (define_insn "*inverted_fpe_branch"
1298 (if_then_else (match_operator 1 "comparison_operator"
1299 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1302 (label_ref (match_operand 2 "" ""))))]
1305 return output_cbranch (operands[1], operands[2], 2, 1,
1306 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1309 [(set_attr "type" "branch")
1310 (set_attr "branch_type" "fcc")])
1312 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1313 ;; in the architecture.
1315 ;; There are no 32 bit brreg insns.
1318 (define_insn "*normal_int_branch_sp64"
1320 (if_then_else (match_operator 0 "v9_register_compare_operator"
1321 [(match_operand:DI 1 "register_operand" "r")
1323 (label_ref (match_operand 2 "" ""))
1327 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1328 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1331 [(set_attr "type" "branch")
1332 (set_attr "branch_type" "reg")])
1335 (define_insn "*inverted_int_branch_sp64"
1337 (if_then_else (match_operator 0 "v9_register_compare_operator"
1338 [(match_operand:DI 1 "register_operand" "r")
1341 (label_ref (match_operand 2 "" ""))))]
1344 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1345 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1348 [(set_attr "type" "branch")
1349 (set_attr "branch_type" "reg")])
1352 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1353 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1354 ;; that adds the PC value at the call point to register #(operand 3).
1356 ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..."
1357 ;; because the RDPC instruction is extremely expensive and incurs a complete
1358 ;; instruction pipeline flush.
1360 (define_insn "load_pcrel_sym<P:mode>"
1361 [(set (match_operand:P 0 "register_operand" "=r")
1362 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1363 (match_operand:P 2 "call_address_operand" "")
1364 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1365 (clobber (reg:P O7_REG))]
1366 "REGNO (operands[0]) == INTVAL (operands[3])"
1368 if (flag_delayed_branch)
1369 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1371 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1373 [(set (attr "type") (const_string "multi"))
1374 (set (attr "length")
1375 (if_then_else (eq_attr "delayed_branch" "true")
1380 ;; Integer move instructions
1382 (define_expand "movqi"
1383 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1384 (match_operand:QI 1 "general_operand" ""))]
1387 if (sparc_expand_move (QImode, operands))
1391 (define_insn "*movqi_insn"
1392 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1393 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1394 "(register_operand (operands[0], QImode)
1395 || register_or_zero_operand (operands[1], QImode))"
1400 [(set_attr "type" "*,load,store")
1401 (set_attr "us3load_type" "*,3cycle,*")])
1403 (define_expand "movhi"
1404 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1405 (match_operand:HI 1 "general_operand" ""))]
1408 if (sparc_expand_move (HImode, operands))
1412 (define_insn "*movhi_insn"
1413 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1414 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1415 "(register_operand (operands[0], HImode)
1416 || register_or_zero_operand (operands[1], HImode))"
1419 sethi\t%%hi(%a1), %0
1422 [(set_attr "type" "*,*,load,store")
1423 (set_attr "us3load_type" "*,*,3cycle,*")])
1425 ;; We always work with constants here.
1426 (define_insn "*movhi_lo_sum"
1427 [(set (match_operand:HI 0 "register_operand" "=r")
1428 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1429 (match_operand:HI 2 "small_int_operand" "I")))]
1433 (define_expand "movsi"
1434 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1435 (match_operand:SI 1 "general_operand" ""))]
1438 if (sparc_expand_move (SImode, operands))
1442 (define_insn "*movsi_insn"
1443 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1444 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1445 "register_operand (operands[0], SImode)
1446 || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1449 sethi\t%%hi(%a1), %0
1459 [(set_attr "type" "*,*,load,store,*,*,fpmove,fpload,fpstore,fga,fga")
1460 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1462 (define_insn "*movsi_lo_sum"
1463 [(set (match_operand:SI 0 "register_operand" "=r")
1464 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1465 (match_operand:SI 2 "immediate_operand" "in")))]
1467 "or\t%1, %%lo(%a2), %0")
1469 (define_insn "*movsi_high"
1470 [(set (match_operand:SI 0 "register_operand" "=r")
1471 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1473 "sethi\t%%hi(%a1), %0")
1475 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1476 ;; so that CSE won't optimize the address computation away.
1477 (define_insn "movsi_lo_sum_pic"
1478 [(set (match_operand:SI 0 "register_operand" "=r")
1479 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1480 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1483 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1484 return "xor\t%1, %%gdop_lox10(%a2), %0";
1486 return "or\t%1, %%lo(%a2), %0";
1490 (define_insn "movsi_high_pic"
1491 [(set (match_operand:SI 0 "register_operand" "=r")
1492 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1493 "flag_pic && check_pic (1)"
1495 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1496 return "sethi\t%%gdop_hix22(%a1), %0";
1498 return "sethi\t%%hi(%a1), %0";
1502 (define_insn "movsi_pic_gotdata_op"
1503 [(set (match_operand:SI 0 "register_operand" "=r")
1504 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1505 (match_operand:SI 2 "register_operand" "r")
1506 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1507 "flag_pic && check_pic (1)"
1509 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1510 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1512 return "ld\t[%1 + %2], %0";
1515 [(set_attr "type" "load")])
1517 (define_expand "movsi_pic_label_ref"
1518 [(set (match_dup 3) (high:SI
1519 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1520 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1521 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1522 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1523 (set (match_operand:SI 0 "register_operand" "=r")
1524 (minus:SI (match_dup 5) (match_dup 4)))]
1527 crtl->uses_pic_offset_table = 1;
1528 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1529 if (!can_create_pseudo_p ())
1531 operands[3] = operands[0];
1532 operands[4] = operands[0];
1536 operands[3] = gen_reg_rtx (SImode);
1537 operands[4] = gen_reg_rtx (SImode);
1539 operands[5] = pic_offset_table_rtx;
1542 (define_insn "*movsi_high_pic_label_ref"
1543 [(set (match_operand:SI 0 "register_operand" "=r")
1545 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1546 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1548 "sethi\t%%hi(%a2-(%a1-.)), %0")
1550 (define_insn "*movsi_lo_sum_pic_label_ref"
1551 [(set (match_operand:SI 0 "register_operand" "=r")
1552 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1553 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1554 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1556 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1558 ;; Set up the PIC register for VxWorks.
1560 (define_expand "vxworks_load_got"
1562 (high:SI (match_dup 1)))
1564 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1566 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1567 "TARGET_VXWORKS_RTP"
1569 operands[0] = pic_offset_table_rtx;
1570 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1571 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1574 (define_expand "movdi"
1575 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1576 (match_operand:DI 1 "general_operand" ""))]
1579 if (sparc_expand_move (DImode, operands))
1583 ;; Be careful, fmovd does not exist when !v9.
1584 ;; We match MEM moves directly when we have correct even
1585 ;; numbered registers, but fall into splits otherwise.
1586 ;; The constraint ordering here is really important to
1587 ;; avoid insane problems in reload, especially for patterns
1590 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1591 ;; (const_int -5016)))
1595 (define_insn "*movdi_insn_sp32"
1596 [(set (match_operand:DI 0 "nonimmediate_operand"
1597 "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e, r,?*f,?*e,?W,b,b")
1598 (match_operand:DI 1 "input_operand"
1599 " J,J,U,T,r,o,i,r,*f, T, o,*f, *e, *e,?*f, r, W,*e,J,P"))]
1601 && (register_operand (operands[0], DImode)
1602 || register_or_zero_operand (operands[1], DImode))"
1624 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,fga,fga")
1625 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1626 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1627 (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
1629 (define_insn "*movdi_insn_sp64"
1630 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1631 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,*e, r, *e, W,*e,J,P"))]
1633 && (register_operand (operands[0], DImode)
1634 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1637 sethi\t%%hi(%a1), %0
1647 [(set_attr "type" "*,*,load,store,*,*,fpmove,fpload,fpstore,fga,fga")
1648 (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1649 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1651 (define_expand "movdi_pic_label_ref"
1652 [(set (match_dup 3) (high:DI
1653 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1654 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1655 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1656 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1657 (set (match_operand:DI 0 "register_operand" "=r")
1658 (minus:DI (match_dup 5) (match_dup 4)))]
1659 "TARGET_ARCH64 && flag_pic"
1661 crtl->uses_pic_offset_table = 1;
1662 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1663 if (!can_create_pseudo_p ())
1665 operands[3] = operands[0];
1666 operands[4] = operands[0];
1670 operands[3] = gen_reg_rtx (DImode);
1671 operands[4] = gen_reg_rtx (DImode);
1673 operands[5] = pic_offset_table_rtx;
1676 (define_insn "*movdi_high_pic_label_ref"
1677 [(set (match_operand:DI 0 "register_operand" "=r")
1679 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1680 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1681 "TARGET_ARCH64 && flag_pic"
1682 "sethi\t%%hi(%a2-(%a1-.)), %0")
1684 (define_insn "*movdi_lo_sum_pic_label_ref"
1685 [(set (match_operand:DI 0 "register_operand" "=r")
1686 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1687 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1688 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1689 "TARGET_ARCH64 && flag_pic"
1690 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1692 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1693 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1695 (define_insn "movdi_lo_sum_pic"
1696 [(set (match_operand:DI 0 "register_operand" "=r")
1697 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1698 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1699 "TARGET_ARCH64 && flag_pic"
1701 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1702 return "xor\t%1, %%gdop_lox10(%a2), %0";
1704 return "or\t%1, %%lo(%a2), %0";
1708 (define_insn "movdi_high_pic"
1709 [(set (match_operand:DI 0 "register_operand" "=r")
1710 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1711 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1713 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1714 return "sethi\t%%gdop_hix22(%a1), %0";
1716 return "sethi\t%%hi(%a1), %0";
1720 (define_insn "movdi_pic_gotdata_op"
1721 [(set (match_operand:DI 0 "register_operand" "=r")
1722 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1723 (match_operand:DI 2 "register_operand" "r")
1724 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1725 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1727 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1728 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1730 return "ldx\t[%1 + %2], %0";
1733 [(set_attr "type" "load")])
1735 (define_insn "*sethi_di_medlow_embmedany_pic"
1736 [(set (match_operand:DI 0 "register_operand" "=r")
1737 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1738 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1739 "sethi\t%%hi(%a1), %0")
1741 (define_insn "*sethi_di_medlow"
1742 [(set (match_operand:DI 0 "register_operand" "=r")
1743 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1744 "TARGET_CM_MEDLOW && check_pic (1)"
1745 "sethi\t%%hi(%a1), %0")
1747 (define_insn "*losum_di_medlow"
1748 [(set (match_operand:DI 0 "register_operand" "=r")
1749 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1750 (match_operand:DI 2 "symbolic_operand" "")))]
1752 "or\t%1, %%lo(%a2), %0")
1754 (define_insn "seth44"
1755 [(set (match_operand:DI 0 "register_operand" "=r")
1756 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1758 "sethi\t%%h44(%a1), %0")
1760 (define_insn "setm44"
1761 [(set (match_operand:DI 0 "register_operand" "=r")
1762 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1763 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1765 "or\t%1, %%m44(%a2), %0")
1767 (define_insn "setl44"
1768 [(set (match_operand:DI 0 "register_operand" "=r")
1769 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1770 (match_operand:DI 2 "symbolic_operand" "")))]
1772 "or\t%1, %%l44(%a2), %0")
1774 (define_insn "sethh"
1775 [(set (match_operand:DI 0 "register_operand" "=r")
1776 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1778 "sethi\t%%hh(%a1), %0")
1780 (define_insn "setlm"
1781 [(set (match_operand:DI 0 "register_operand" "=r")
1782 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1784 "sethi\t%%lm(%a1), %0")
1786 (define_insn "sethm"
1787 [(set (match_operand:DI 0 "register_operand" "=r")
1788 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1789 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1791 "or\t%1, %%hm(%a2), %0")
1793 (define_insn "setlo"
1794 [(set (match_operand:DI 0 "register_operand" "=r")
1795 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1796 (match_operand:DI 2 "symbolic_operand" "")))]
1798 "or\t%1, %%lo(%a2), %0")
1800 (define_insn "embmedany_sethi"
1801 [(set (match_operand:DI 0 "register_operand" "=r")
1802 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1803 "TARGET_CM_EMBMEDANY && check_pic (1)"
1804 "sethi\t%%hi(%a1), %0")
1806 (define_insn "embmedany_losum"
1807 [(set (match_operand:DI 0 "register_operand" "=r")
1808 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1809 (match_operand:DI 2 "data_segment_operand" "")))]
1810 "TARGET_CM_EMBMEDANY"
1811 "add\t%1, %%lo(%a2), %0")
1813 (define_insn "embmedany_brsum"
1814 [(set (match_operand:DI 0 "register_operand" "=r")
1815 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1816 "TARGET_CM_EMBMEDANY"
1819 (define_insn "embmedany_textuhi"
1820 [(set (match_operand:DI 0 "register_operand" "=r")
1821 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1822 "TARGET_CM_EMBMEDANY && check_pic (1)"
1823 "sethi\t%%uhi(%a1), %0")
1825 (define_insn "embmedany_texthi"
1826 [(set (match_operand:DI 0 "register_operand" "=r")
1827 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1828 "TARGET_CM_EMBMEDANY && check_pic (1)"
1829 "sethi\t%%hi(%a1), %0")
1831 (define_insn "embmedany_textulo"
1832 [(set (match_operand:DI 0 "register_operand" "=r")
1833 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1834 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1835 "TARGET_CM_EMBMEDANY"
1836 "or\t%1, %%ulo(%a2), %0")
1838 (define_insn "embmedany_textlo"
1839 [(set (match_operand:DI 0 "register_operand" "=r")
1840 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1841 (match_operand:DI 2 "text_segment_operand" "")))]
1842 "TARGET_CM_EMBMEDANY"
1843 "or\t%1, %%lo(%a2), %0")
1845 ;; Now some patterns to help reload out a bit.
1846 (define_expand "reload_indi"
1847 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1848 (match_operand:DI 1 "immediate_operand" "")
1849 (match_operand:TI 2 "register_operand" "=&r")])]
1851 || TARGET_CM_EMBMEDANY)
1854 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1858 (define_expand "reload_outdi"
1859 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1860 (match_operand:DI 1 "immediate_operand" "")
1861 (match_operand:TI 2 "register_operand" "=&r")])]
1863 || TARGET_CM_EMBMEDANY)
1866 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1870 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1872 [(set (match_operand:DI 0 "register_operand" "")
1873 (match_operand:DI 1 "const_int_operand" ""))]
1875 && ((GET_CODE (operands[0]) == REG
1876 && SPARC_INT_REG_P (REGNO (operands[0])))
1877 || (GET_CODE (operands[0]) == SUBREG
1878 && GET_CODE (SUBREG_REG (operands[0])) == REG
1879 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))
1880 && reload_completed"
1881 [(clobber (const_int 0))]
1883 #if HOST_BITS_PER_WIDE_INT == 32
1884 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1885 (INTVAL (operands[1]) < 0) ?
1888 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1891 unsigned int low, high;
1893 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1894 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1895 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1897 /* Slick... but this trick loses if this subreg constant part
1898 can be done in one insn. */
1900 && ! SPARC_SETHI32_P (high)
1901 && ! SPARC_SIMM13_P (high))
1902 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1903 gen_highpart (SImode, operands[0])));
1905 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1911 [(set (match_operand:DI 0 "register_operand" "")
1912 (match_operand:DI 1 "const_double_operand" ""))]
1916 && ((GET_CODE (operands[0]) == REG
1917 && SPARC_INT_REG_P (REGNO (operands[0])))
1918 || (GET_CODE (operands[0]) == SUBREG
1919 && GET_CODE (SUBREG_REG (operands[0])) == REG
1920 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
1921 [(clobber (const_int 0))]
1923 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1924 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1926 /* Slick... but this trick loses if this subreg constant part
1927 can be done in one insn. */
1928 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1929 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1930 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1932 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1933 gen_highpart (SImode, operands[0])));
1937 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1938 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1944 [(set (match_operand:DI 0 "register_operand" "")
1945 (match_operand:DI 1 "register_operand" ""))]
1949 && sparc_split_regreg_legitimate (operands[0],
1951 [(clobber (const_int 0))]
1953 rtx set_dest = operands[0];
1954 rtx set_src = operands[1];
1958 dest1 = gen_highpart (SImode, set_dest);
1959 dest2 = gen_lowpart (SImode, set_dest);
1960 src1 = gen_highpart (SImode, set_src);
1961 src2 = gen_lowpart (SImode, set_src);
1963 /* Now emit using the real source and destination we found, swapping
1964 the order if we detect overlap. */
1965 if (reg_overlap_mentioned_p (dest1, src2))
1967 emit_insn (gen_movsi (dest2, src2));
1968 emit_insn (gen_movsi (dest1, src1));
1972 emit_insn (gen_movsi (dest1, src1));
1973 emit_insn (gen_movsi (dest2, src2));
1978 ;; Now handle the cases of memory moves from/to non-even
1979 ;; DI mode register pairs.
1981 [(set (match_operand:DI 0 "register_operand" "")
1982 (match_operand:DI 1 "memory_operand" ""))]
1985 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1986 [(clobber (const_int 0))]
1988 rtx word0 = adjust_address (operands[1], SImode, 0);
1989 rtx word1 = adjust_address (operands[1], SImode, 4);
1990 rtx high_part = gen_highpart (SImode, operands[0]);
1991 rtx low_part = gen_lowpart (SImode, operands[0]);
1993 if (reg_overlap_mentioned_p (high_part, word1))
1995 emit_insn (gen_movsi (low_part, word1));
1996 emit_insn (gen_movsi (high_part, word0));
2000 emit_insn (gen_movsi (high_part, word0));
2001 emit_insn (gen_movsi (low_part, word1));
2007 [(set (match_operand:DI 0 "memory_operand" "")
2008 (match_operand:DI 1 "register_operand" ""))]
2011 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2012 [(clobber (const_int 0))]
2014 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2015 gen_highpart (SImode, operands[1])));
2016 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2017 gen_lowpart (SImode, operands[1])));
2022 [(set (match_operand:DI 0 "memory_operand" "")
2023 (match_operand:DI 1 "const_zero_operand" ""))]
2027 && ! mem_min_alignment (operands[0], 8)))
2028 && offsettable_memref_p (operands[0])"
2029 [(clobber (const_int 0))]
2031 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2032 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2037 ;; Floating point move instructions
2039 (define_expand "movsf"
2040 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2041 (match_operand:SF 1 "general_operand" ""))]
2044 if (sparc_expand_move (SFmode, operands))
2048 (define_insn "*movsf_insn"
2049 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m, m")
2050 (match_operand:SF 1 "input_operand" "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2051 "(register_operand (operands[0], SFmode)
2052 || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2054 if (GET_CODE (operands[1]) == CONST_DOUBLE
2055 && (which_alternative == 3
2056 || which_alternative == 4
2057 || which_alternative == 5))
2062 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2063 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2064 operands[1] = GEN_INT (i);
2067 switch (which_alternative)
2070 return "fzeros\t%0";
2074 return "fmovs\t%1, %0";
2076 return "mov\t%1, %0";
2078 return "sethi\t%%hi(%a1), %0";
2082 return "movstouw\t%1, %0";
2084 return "movwtos\t%1, %0";
2087 return "ld\t%1, %0";
2090 return "st\t%r1, %0";
2095 [(set_attr "type" "fga,fga,fpmove,*,*,*,*,*,fpload,load,fpstore,store")
2096 (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2098 ;; The following 3 patterns build SFmode constants in integer registers.
2100 (define_insn "*movsf_lo_sum"
2101 [(set (match_operand:SF 0 "register_operand" "=r")
2102 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2103 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2109 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2110 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2111 operands[2] = GEN_INT (i);
2112 return "or\t%1, %%lo(%a2), %0";
2115 (define_insn "*movsf_high"
2116 [(set (match_operand:SF 0 "register_operand" "=r")
2117 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2123 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2124 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2125 operands[1] = GEN_INT (i);
2126 return "sethi\t%%hi(%1), %0";
2130 [(set (match_operand:SF 0 "register_operand" "")
2131 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2132 "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2133 [(set (match_dup 0) (high:SF (match_dup 1)))
2134 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2136 (define_expand "movdf"
2137 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2138 (match_operand:DF 1 "general_operand" ""))]
2141 if (sparc_expand_move (DFmode, operands))
2145 (define_insn "*movdf_insn_sp32"
2146 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f, e,T,W,U,T, f, *r, o,o")
2147 (match_operand:DF 1 "input_operand" "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))]
2149 && (register_operand (operands[0], DFmode)
2150 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2167 [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*")
2168 (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2")
2169 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2170 (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")])
2172 (define_insn "*movdf_insn_sp64"
2173 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r")
2174 (match_operand:DF 1 "input_operand" "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2176 && (register_operand (operands[0], DFmode)
2177 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2190 [(set_attr "type" "fga,fga,fpmove,*,*,load,store,*,load,store,*")
2191 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2192 (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2193 (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2195 ;; This pattern builds DFmode constants in integer registers.
2197 [(set (match_operand:DF 0 "register_operand" "")
2198 (match_operand:DF 1 "const_double_operand" ""))]
2199 "REG_P (operands[0])
2200 && SPARC_INT_REG_P (REGNO (operands[0]))
2201 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2202 && reload_completed"
2203 [(clobber (const_int 0))]
2205 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2209 #if HOST_BITS_PER_WIDE_INT == 32
2212 enum machine_mode mode = GET_MODE (operands[1]);
2213 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2214 emit_insn (gen_movdi (operands[0], tem));
2219 enum machine_mode mode = GET_MODE (operands[1]);
2220 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2221 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2223 gcc_assert (GET_CODE (hi) == CONST_INT);
2224 gcc_assert (GET_CODE (lo) == CONST_INT);
2226 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2228 /* Slick... but this trick loses if this subreg constant part
2229 can be done in one insn. */
2231 && ! SPARC_SETHI32_P (INTVAL (hi))
2232 && ! SPARC_SIMM13_P (INTVAL (hi)))
2234 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2235 gen_highpart (SImode, operands[0])));
2239 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2245 ;; Ok, now the splits to handle all the multi insn and
2246 ;; mis-aligned memory address cases.
2247 ;; In these splits please take note that we must be
2248 ;; careful when V9 but not ARCH64 because the integer
2249 ;; register DFmode cases must be handled.
2251 [(set (match_operand:DF 0 "register_operand" "")
2252 (match_operand:DF 1 "register_operand" ""))]
2255 && sparc_split_regreg_legitimate (operands[0],
2257 && reload_completed"
2258 [(clobber (const_int 0))]
2260 rtx set_dest = operands[0];
2261 rtx set_src = operands[1];
2265 dest1 = gen_highpart (SFmode, set_dest);
2266 dest2 = gen_lowpart (SFmode, set_dest);
2267 src1 = gen_highpart (SFmode, set_src);
2268 src2 = gen_lowpart (SFmode, set_src);
2270 /* Now emit using the real source and destination we found, swapping
2271 the order if we detect overlap. */
2272 if (reg_overlap_mentioned_p (dest1, src2))
2274 emit_move_insn_1 (dest2, src2);
2275 emit_move_insn_1 (dest1, src1);
2279 emit_move_insn_1 (dest1, src1);
2280 emit_move_insn_1 (dest2, src2);
2286 [(set (match_operand:DF 0 "register_operand" "")
2287 (match_operand:DF 1 "memory_operand" ""))]
2290 && (((REGNO (operands[0]) % 2) != 0)
2291 || ! mem_min_alignment (operands[1], 8))
2292 && offsettable_memref_p (operands[1])"
2293 [(clobber (const_int 0))]
2297 word0 = adjust_address (operands[1], SFmode, 0);
2298 word1 = adjust_address (operands[1], SFmode, 4);
2300 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2302 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2303 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2307 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2308 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2314 [(set (match_operand:DF 0 "memory_operand" "")
2315 (match_operand:DF 1 "register_operand" ""))]
2318 && (((REGNO (operands[1]) % 2) != 0)
2319 || ! mem_min_alignment (operands[0], 8))
2320 && offsettable_memref_p (operands[0])"
2321 [(clobber (const_int 0))]
2325 word0 = adjust_address (operands[0], SFmode, 0);
2326 word1 = adjust_address (operands[0], SFmode, 4);
2328 emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2329 emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2334 [(set (match_operand:DF 0 "memory_operand" "")
2335 (match_operand:DF 1 "const_zero_operand" ""))]
2339 && ! mem_min_alignment (operands[0], 8)))
2340 && offsettable_memref_p (operands[0])"
2341 [(clobber (const_int 0))]
2345 dest1 = adjust_address (operands[0], SFmode, 0);
2346 dest2 = adjust_address (operands[0], SFmode, 4);
2348 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2349 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2354 [(set (match_operand:DF 0 "register_operand" "")
2355 (match_operand:DF 1 "const_zero_operand" ""))]
2358 && ((GET_CODE (operands[0]) == REG
2359 && SPARC_INT_REG_P (REGNO (operands[0])))
2360 || (GET_CODE (operands[0]) == SUBREG
2361 && GET_CODE (SUBREG_REG (operands[0])) == REG
2362 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2363 [(clobber (const_int 0))]
2365 rtx set_dest = operands[0];
2368 dest1 = gen_highpart (SFmode, set_dest);
2369 dest2 = gen_lowpart (SFmode, set_dest);
2370 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2371 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2375 (define_expand "movtf"
2376 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2377 (match_operand:TF 1 "general_operand" ""))]
2380 if (sparc_expand_move (TFmode, operands))
2384 (define_insn "*movtf_insn_sp32"
2385 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,U, r")
2386 (match_operand:TF 1 "input_operand" " G,oe,e,rGU,o,roG"))]
2388 && (register_operand (operands[0], TFmode)
2389 || register_or_zero_operand (operands[1], TFmode))"
2391 [(set_attr "length" "4,4,4,4,4,4")
2392 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")])
2394 (define_insn "*movtf_insn_sp64"
2395 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o, r")
2396 (match_operand:TF 1 "input_operand" "G,oe,e,rG,roG"))]
2398 && ! TARGET_HARD_QUAD
2399 && (register_operand (operands[0], TFmode)
2400 || register_or_zero_operand (operands[1], TFmode))"
2402 [(set_attr "length" "2,2,2,2,2")
2403 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2405 (define_insn "*movtf_insn_sp64_hq"
2406 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o, r")
2407 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2410 && (register_operand (operands[0], TFmode)
2411 || register_or_zero_operand (operands[1], TFmode))"
2419 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2420 (set_attr "length" "2,*,*,*,2,2")])
2422 ;; Now all the splits to handle multi-insn TF mode moves.
2424 [(set (match_operand:TF 0 "register_operand" "")
2425 (match_operand:TF 1 "register_operand" ""))]
2429 && ! TARGET_HARD_QUAD)
2430 || (! fp_register_operand (operands[0], TFmode)
2431 && ! fp_register_operand (operands[1], TFmode)))"
2432 [(clobber (const_int 0))]
2434 rtx set_dest = operands[0];
2435 rtx set_src = operands[1];
2439 dest1 = gen_df_reg (set_dest, 0);
2440 dest2 = gen_df_reg (set_dest, 1);
2441 src1 = gen_df_reg (set_src, 0);
2442 src2 = gen_df_reg (set_src, 1);
2444 /* Now emit using the real source and destination we found, swapping
2445 the order if we detect overlap. */
2446 if (reg_overlap_mentioned_p (dest1, src2))
2448 emit_insn (gen_movdf (dest2, src2));
2449 emit_insn (gen_movdf (dest1, src1));
2453 emit_insn (gen_movdf (dest1, src1));
2454 emit_insn (gen_movdf (dest2, src2));
2460 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2461 (match_operand:TF 1 "const_zero_operand" ""))]
2463 [(clobber (const_int 0))]
2465 rtx set_dest = operands[0];
2468 switch (GET_CODE (set_dest))
2471 dest1 = gen_df_reg (set_dest, 0);
2472 dest2 = gen_df_reg (set_dest, 1);
2475 dest1 = adjust_address (set_dest, DFmode, 0);
2476 dest2 = adjust_address (set_dest, DFmode, 8);
2482 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2483 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2488 [(set (match_operand:TF 0 "register_operand" "")
2489 (match_operand:TF 1 "memory_operand" ""))]
2491 && offsettable_memref_p (operands[1])
2493 || ! TARGET_HARD_QUAD
2494 || ! fp_register_operand (operands[0], TFmode)))"
2495 [(clobber (const_int 0))]
2497 rtx word0 = adjust_address (operands[1], DFmode, 0);
2498 rtx word1 = adjust_address (operands[1], DFmode, 8);
2499 rtx set_dest, dest1, dest2;
2501 set_dest = operands[0];
2503 dest1 = gen_df_reg (set_dest, 0);
2504 dest2 = gen_df_reg (set_dest, 1);
2506 /* Now output, ordering such that we don't clobber any registers
2507 mentioned in the address. */
2508 if (reg_overlap_mentioned_p (dest1, word1))
2511 emit_insn (gen_movdf (dest2, word1));
2512 emit_insn (gen_movdf (dest1, word0));
2516 emit_insn (gen_movdf (dest1, word0));
2517 emit_insn (gen_movdf (dest2, word1));
2523 [(set (match_operand:TF 0 "memory_operand" "")
2524 (match_operand:TF 1 "register_operand" ""))]
2526 && offsettable_memref_p (operands[0])
2528 || ! TARGET_HARD_QUAD
2529 || ! fp_register_operand (operands[1], TFmode)))"
2530 [(clobber (const_int 0))]
2532 rtx set_src = operands[1];
2534 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2535 gen_df_reg (set_src, 0)));
2536 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2537 gen_df_reg (set_src, 1)));
2542 ;; SPARC-V9 conditional move instructions
2544 ;; We can handle larger constants here for some flavors, but for now we keep
2545 ;; it simple and only allow those constants supported by all flavors.
2546 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2547 ;; 3 contains the constant if one is present, but we handle either for
2548 ;; generality (sparc.c puts a constant in operand 2).
2550 ;; Our instruction patterns, on the other hand, canonicalize such that
2551 ;; operand 3 must be the set destination.
2553 (define_expand "mov<I:mode>cc"
2554 [(set (match_operand:I 0 "register_operand" "")
2555 (if_then_else:I (match_operand 1 "comparison_operator" "")
2556 (match_operand:I 2 "arith10_operand" "")
2557 (match_operand:I 3 "arith10_operand" "")))]
2558 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2560 if (! sparc_expand_conditional_move (<I:MODE>mode, operands))
2565 (define_expand "mov<F:mode>cc"
2566 [(set (match_operand:F 0 "register_operand" "")
2567 (if_then_else:F (match_operand 1 "comparison_operator" "")
2568 (match_operand:F 2 "register_operand" "")
2569 (match_operand:F 3 "register_operand" "")))]
2570 "TARGET_V9 && TARGET_FPU"
2572 if (! sparc_expand_conditional_move (<F:MODE>mode, operands))
2577 ;; Conditional move define_insns
2579 (define_insn "*mov<I:mode>_cc_v9"
2580 [(set (match_operand:I 0 "register_operand" "=r")
2581 (if_then_else:I (match_operator 1 "comparison_operator"
2582 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2584 (match_operand:I 3 "arith11_operand" "rL")
2585 (match_operand:I 4 "register_operand" "0")))]
2586 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2587 "mov%C1\t%x2, %3, %0"
2588 [(set_attr "type" "cmove")])
2590 (define_insn "*mov<I:mode>_cc_reg_sp64"
2591 [(set (match_operand:I 0 "register_operand" "=r")
2592 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2593 [(match_operand:DI 2 "register_operand" "r")
2595 (match_operand:I 3 "arith10_operand" "rM")
2596 (match_operand:I 4 "register_operand" "0")))]
2598 "movr%D1\t%2, %r3, %0"
2599 [(set_attr "type" "cmove")])
2601 (define_insn "*movsf_cc_v9"
2602 [(set (match_operand:SF 0 "register_operand" "=f")
2603 (if_then_else:SF (match_operator 1 "comparison_operator"
2604 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2606 (match_operand:SF 3 "register_operand" "f")
2607 (match_operand:SF 4 "register_operand" "0")))]
2608 "TARGET_V9 && TARGET_FPU"
2609 "fmovs%C1\t%x2, %3, %0"
2610 [(set_attr "type" "fpcmove")])
2612 (define_insn "*movsf_cc_reg_sp64"
2613 [(set (match_operand:SF 0 "register_operand" "=f")
2614 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2615 [(match_operand:DI 2 "register_operand" "r")
2617 (match_operand:SF 3 "register_operand" "f")
2618 (match_operand:SF 4 "register_operand" "0")))]
2619 "TARGET_ARCH64 && TARGET_FPU"
2620 "fmovrs%D1\t%2, %3, %0"
2621 [(set_attr "type" "fpcrmove")])
2623 ;; Named because invoked by movtf_cc_v9
2624 (define_insn "movdf_cc_v9"
2625 [(set (match_operand:DF 0 "register_operand" "=e")
2626 (if_then_else:DF (match_operator 1 "comparison_operator"
2627 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2629 (match_operand:DF 3 "register_operand" "e")
2630 (match_operand:DF 4 "register_operand" "0")))]
2631 "TARGET_V9 && TARGET_FPU"
2632 "fmovd%C1\t%x2, %3, %0"
2633 [(set_attr "type" "fpcmove")
2634 (set_attr "fptype" "double")])
2636 ;; Named because invoked by movtf_cc_reg_sp64
2637 (define_insn "movdf_cc_reg_sp64"
2638 [(set (match_operand:DF 0 "register_operand" "=e")
2639 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2640 [(match_operand:DI 2 "register_operand" "r")
2642 (match_operand:DF 3 "register_operand" "e")
2643 (match_operand:DF 4 "register_operand" "0")))]
2644 "TARGET_ARCH64 && TARGET_FPU"
2645 "fmovrd%D1\t%2, %3, %0"
2646 [(set_attr "type" "fpcrmove")
2647 (set_attr "fptype" "double")])
2649 (define_insn "*movtf_cc_hq_v9"
2650 [(set (match_operand:TF 0 "register_operand" "=e")
2651 (if_then_else:TF (match_operator 1 "comparison_operator"
2652 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2654 (match_operand:TF 3 "register_operand" "e")
2655 (match_operand:TF 4 "register_operand" "0")))]
2656 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2657 "fmovq%C1\t%x2, %3, %0"
2658 [(set_attr "type" "fpcmove")])
2660 (define_insn "*movtf_cc_reg_hq_sp64"
2661 [(set (match_operand:TF 0 "register_operand" "=e")
2662 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2663 [(match_operand:DI 2 "register_operand" "r")
2665 (match_operand:TF 3 "register_operand" "e")
2666 (match_operand:TF 4 "register_operand" "0")))]
2667 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2668 "fmovrq%D1\t%2, %3, %0"
2669 [(set_attr "type" "fpcrmove")])
2671 (define_insn_and_split "*movtf_cc_v9"
2672 [(set (match_operand:TF 0 "register_operand" "=e")
2673 (if_then_else:TF (match_operator 1 "comparison_operator"
2674 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2676 (match_operand:TF 3 "register_operand" "e")
2677 (match_operand:TF 4 "register_operand" "0")))]
2678 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2680 "&& reload_completed"
2681 [(clobber (const_int 0))]
2683 rtx set_dest = operands[0];
2684 rtx set_srca = operands[3];
2688 dest1 = gen_df_reg (set_dest, 0);
2689 dest2 = gen_df_reg (set_dest, 1);
2690 srca1 = gen_df_reg (set_srca, 0);
2691 srca2 = gen_df_reg (set_srca, 1);
2693 if (reg_overlap_mentioned_p (dest1, srca2))
2695 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2696 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2700 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2701 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2705 [(set_attr "length" "2")])
2707 (define_insn_and_split "*movtf_cc_reg_sp64"
2708 [(set (match_operand:TF 0 "register_operand" "=e")
2709 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2710 [(match_operand:DI 2 "register_operand" "r")
2712 (match_operand:TF 3 "register_operand" "e")
2713 (match_operand:TF 4 "register_operand" "0")))]
2714 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2716 "&& reload_completed"
2717 [(clobber (const_int 0))]
2719 rtx set_dest = operands[0];
2720 rtx set_srca = operands[3];
2724 dest1 = gen_df_reg (set_dest, 0);
2725 dest2 = gen_df_reg (set_dest, 1);
2726 srca1 = gen_df_reg (set_srca, 0);
2727 srca2 = gen_df_reg (set_srca, 1);
2729 if (reg_overlap_mentioned_p (dest1, srca2))
2731 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2732 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2736 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2737 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2741 [(set_attr "length" "2")])
2744 ;; Zero-extension instructions
2746 ;; These patterns originally accepted general_operands, however, slightly
2747 ;; better code is generated by only accepting register_operands, and then
2748 ;; letting combine generate the ldu[hb] insns.
2750 (define_expand "zero_extendhisi2"
2751 [(set (match_operand:SI 0 "register_operand" "")
2752 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2755 rtx temp = gen_reg_rtx (SImode);
2756 rtx shift_16 = GEN_INT (16);
2757 int op1_subbyte = 0;
2759 if (GET_CODE (operand1) == SUBREG)
2761 op1_subbyte = SUBREG_BYTE (operand1);
2762 op1_subbyte /= GET_MODE_SIZE (SImode);
2763 op1_subbyte *= GET_MODE_SIZE (SImode);
2764 operand1 = XEXP (operand1, 0);
2767 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2769 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2773 (define_insn "*zero_extendhisi2_insn"
2774 [(set (match_operand:SI 0 "register_operand" "=r")
2775 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2778 [(set_attr "type" "load")
2779 (set_attr "us3load_type" "3cycle")])
2781 (define_expand "zero_extendqihi2"
2782 [(set (match_operand:HI 0 "register_operand" "")
2783 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2787 (define_insn "*zero_extendqihi2_insn"
2788 [(set (match_operand:HI 0 "register_operand" "=r,r")
2789 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2790 "GET_CODE (operands[1]) != CONST_INT"
2794 [(set_attr "type" "*,load")
2795 (set_attr "us3load_type" "*,3cycle")])
2797 (define_expand "zero_extendqisi2"
2798 [(set (match_operand:SI 0 "register_operand" "")
2799 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2803 (define_insn "*zero_extendqisi2_insn"
2804 [(set (match_operand:SI 0 "register_operand" "=r,r")
2805 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2806 "GET_CODE (operands[1]) != CONST_INT"
2810 [(set_attr "type" "*,load")
2811 (set_attr "us3load_type" "*,3cycle")])
2813 (define_expand "zero_extendqidi2"
2814 [(set (match_operand:DI 0 "register_operand" "")
2815 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2819 (define_insn "*zero_extendqidi2_insn"
2820 [(set (match_operand:DI 0 "register_operand" "=r,r")
2821 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2822 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2826 [(set_attr "type" "*,load")
2827 (set_attr "us3load_type" "*,3cycle")])
2829 (define_expand "zero_extendhidi2"
2830 [(set (match_operand:DI 0 "register_operand" "")
2831 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2834 rtx temp = gen_reg_rtx (DImode);
2835 rtx shift_48 = GEN_INT (48);
2836 int op1_subbyte = 0;
2838 if (GET_CODE (operand1) == SUBREG)
2840 op1_subbyte = SUBREG_BYTE (operand1);
2841 op1_subbyte /= GET_MODE_SIZE (DImode);
2842 op1_subbyte *= GET_MODE_SIZE (DImode);
2843 operand1 = XEXP (operand1, 0);
2846 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2848 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2852 (define_insn "*zero_extendhidi2_insn"
2853 [(set (match_operand:DI 0 "register_operand" "=r")
2854 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2857 [(set_attr "type" "load")
2858 (set_attr "us3load_type" "3cycle")])
2860 ;; ??? Write truncdisi pattern using sra?
2862 (define_expand "zero_extendsidi2"
2863 [(set (match_operand:DI 0 "register_operand" "")
2864 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2868 (define_insn "*zero_extendsidi2_insn_sp64"
2869 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
2870 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
2872 && GET_CODE (operands[1]) != CONST_INT"
2877 [(set_attr "type" "shift,load,*")
2878 (set_attr "cpu_feature" "*,*,vis3")])
2880 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2881 [(set (match_operand:DI 0 "register_operand" "=r")
2882 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2885 "&& reload_completed"
2886 [(set (match_dup 2) (match_dup 3))
2887 (set (match_dup 4) (match_dup 5))]
2891 dest1 = gen_highpart (SImode, operands[0]);
2892 dest2 = gen_lowpart (SImode, operands[0]);
2894 /* Swap the order in case of overlap. */
2895 if (REGNO (dest1) == REGNO (operands[1]))
2897 operands[2] = dest2;
2898 operands[3] = operands[1];
2899 operands[4] = dest1;
2900 operands[5] = const0_rtx;
2904 operands[2] = dest1;
2905 operands[3] = const0_rtx;
2906 operands[4] = dest2;
2907 operands[5] = operands[1];
2910 [(set_attr "length" "2")])
2912 ;; Simplify comparisons of extended values.
2914 (define_insn "*cmp_zero_extendqisi2"
2915 [(set (reg:CC CC_REG)
2916 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2919 "andcc\t%0, 0xff, %%g0"
2920 [(set_attr "type" "compare")])
2922 (define_insn "*cmp_zero_qi"
2923 [(set (reg:CC CC_REG)
2924 (compare:CC (match_operand:QI 0 "register_operand" "r")
2927 "andcc\t%0, 0xff, %%g0"
2928 [(set_attr "type" "compare")])
2930 (define_insn "*cmp_zero_extendqisi2_set"
2931 [(set (reg:CC CC_REG)
2932 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2934 (set (match_operand:SI 0 "register_operand" "=r")
2935 (zero_extend:SI (match_dup 1)))]
2937 "andcc\t%1, 0xff, %0"
2938 [(set_attr "type" "compare")])
2940 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2941 [(set (reg:CC CC_REG)
2942 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2945 (set (match_operand:SI 0 "register_operand" "=r")
2946 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2948 "andcc\t%1, 0xff, %0"
2949 [(set_attr "type" "compare")])
2951 (define_insn "*cmp_zero_extendqidi2"
2952 [(set (reg:CCX CC_REG)
2953 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2956 "andcc\t%0, 0xff, %%g0"
2957 [(set_attr "type" "compare")])
2959 (define_insn "*cmp_zero_qi_sp64"
2960 [(set (reg:CCX CC_REG)
2961 (compare:CCX (match_operand:QI 0 "register_operand" "r")
2964 "andcc\t%0, 0xff, %%g0"
2965 [(set_attr "type" "compare")])
2967 (define_insn "*cmp_zero_extendqidi2_set"
2968 [(set (reg:CCX CC_REG)
2969 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2971 (set (match_operand:DI 0 "register_operand" "=r")
2972 (zero_extend:DI (match_dup 1)))]
2974 "andcc\t%1, 0xff, %0"
2975 [(set_attr "type" "compare")])
2977 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2978 [(set (reg:CCX CC_REG)
2979 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2982 (set (match_operand:DI 0 "register_operand" "=r")
2983 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2985 "andcc\t%1, 0xff, %0"
2986 [(set_attr "type" "compare")])
2988 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2990 (define_insn "*cmp_siqi_trunc"
2991 [(set (reg:CC CC_REG)
2992 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2995 "andcc\t%0, 0xff, %%g0"
2996 [(set_attr "type" "compare")])
2998 (define_insn "*cmp_siqi_trunc_set"
2999 [(set (reg:CC CC_REG)
3000 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3002 (set (match_operand:QI 0 "register_operand" "=r")
3003 (subreg:QI (match_dup 1) 3))]
3005 "andcc\t%1, 0xff, %0"
3006 [(set_attr "type" "compare")])
3008 (define_insn "*cmp_diqi_trunc"
3009 [(set (reg:CC CC_REG)
3010 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3013 "andcc\t%0, 0xff, %%g0"
3014 [(set_attr "type" "compare")])
3016 (define_insn "*cmp_diqi_trunc_set"
3017 [(set (reg:CC CC_REG)
3018 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3020 (set (match_operand:QI 0 "register_operand" "=r")
3021 (subreg:QI (match_dup 1) 7))]
3023 "andcc\t%1, 0xff, %0"
3024 [(set_attr "type" "compare")])
3027 ;; Sign-extension instructions
3029 ;; These patterns originally accepted general_operands, however, slightly
3030 ;; better code is generated by only accepting register_operands, and then
3031 ;; letting combine generate the lds[hb] insns.
3033 (define_expand "extendhisi2"
3034 [(set (match_operand:SI 0 "register_operand" "")
3035 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3038 rtx temp = gen_reg_rtx (SImode);
3039 rtx shift_16 = GEN_INT (16);
3040 int op1_subbyte = 0;
3042 if (GET_CODE (operand1) == SUBREG)
3044 op1_subbyte = SUBREG_BYTE (operand1);
3045 op1_subbyte /= GET_MODE_SIZE (SImode);
3046 op1_subbyte *= GET_MODE_SIZE (SImode);
3047 operand1 = XEXP (operand1, 0);
3050 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3052 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3056 (define_insn "*sign_extendhisi2_insn"
3057 [(set (match_operand:SI 0 "register_operand" "=r")
3058 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3061 [(set_attr "type" "sload")
3062 (set_attr "us3load_type" "3cycle")])
3064 (define_expand "extendqihi2"
3065 [(set (match_operand:HI 0 "register_operand" "")
3066 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3069 rtx temp = gen_reg_rtx (SImode);
3070 rtx shift_24 = GEN_INT (24);
3071 int op1_subbyte = 0;
3072 int op0_subbyte = 0;
3074 if (GET_CODE (operand1) == SUBREG)
3076 op1_subbyte = SUBREG_BYTE (operand1);
3077 op1_subbyte /= GET_MODE_SIZE (SImode);
3078 op1_subbyte *= GET_MODE_SIZE (SImode);
3079 operand1 = XEXP (operand1, 0);
3081 if (GET_CODE (operand0) == SUBREG)
3083 op0_subbyte = SUBREG_BYTE (operand0);
3084 op0_subbyte /= GET_MODE_SIZE (SImode);
3085 op0_subbyte *= GET_MODE_SIZE (SImode);
3086 operand0 = XEXP (operand0, 0);
3088 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3090 if (GET_MODE (operand0) != SImode)
3091 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3092 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3096 (define_insn "*sign_extendqihi2_insn"
3097 [(set (match_operand:HI 0 "register_operand" "=r")
3098 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3101 [(set_attr "type" "sload")
3102 (set_attr "us3load_type" "3cycle")])
3104 (define_expand "extendqisi2"
3105 [(set (match_operand:SI 0 "register_operand" "")
3106 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3109 rtx temp = gen_reg_rtx (SImode);
3110 rtx shift_24 = GEN_INT (24);
3111 int op1_subbyte = 0;
3113 if (GET_CODE (operand1) == SUBREG)
3115 op1_subbyte = SUBREG_BYTE (operand1);
3116 op1_subbyte /= GET_MODE_SIZE (SImode);
3117 op1_subbyte *= GET_MODE_SIZE (SImode);
3118 operand1 = XEXP (operand1, 0);
3121 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3123 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3127 (define_insn "*sign_extendqisi2_insn"
3128 [(set (match_operand:SI 0 "register_operand" "=r")
3129 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3132 [(set_attr "type" "sload")
3133 (set_attr "us3load_type" "3cycle")])
3135 (define_expand "extendqidi2"
3136 [(set (match_operand:DI 0 "register_operand" "")
3137 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3140 rtx temp = gen_reg_rtx (DImode);
3141 rtx shift_56 = GEN_INT (56);
3142 int op1_subbyte = 0;
3144 if (GET_CODE (operand1) == SUBREG)
3146 op1_subbyte = SUBREG_BYTE (operand1);
3147 op1_subbyte /= GET_MODE_SIZE (DImode);
3148 op1_subbyte *= GET_MODE_SIZE (DImode);
3149 operand1 = XEXP (operand1, 0);
3152 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3154 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3158 (define_insn "*sign_extendqidi2_insn"
3159 [(set (match_operand:DI 0 "register_operand" "=r")
3160 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3163 [(set_attr "type" "sload")
3164 (set_attr "us3load_type" "3cycle")])
3166 (define_expand "extendhidi2"
3167 [(set (match_operand:DI 0 "register_operand" "")
3168 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3171 rtx temp = gen_reg_rtx (DImode);
3172 rtx shift_48 = GEN_INT (48);
3173 int op1_subbyte = 0;
3175 if (GET_CODE (operand1) == SUBREG)
3177 op1_subbyte = SUBREG_BYTE (operand1);
3178 op1_subbyte /= GET_MODE_SIZE (DImode);
3179 op1_subbyte *= GET_MODE_SIZE (DImode);
3180 operand1 = XEXP (operand1, 0);
3183 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3185 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3189 (define_insn "*sign_extendhidi2_insn"
3190 [(set (match_operand:DI 0 "register_operand" "=r")
3191 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3194 [(set_attr "type" "sload")
3195 (set_attr "us3load_type" "3cycle")])
3197 (define_expand "extendsidi2"
3198 [(set (match_operand:DI 0 "register_operand" "")
3199 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3203 (define_insn "*sign_extendsidi2_insn"
3204 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3205 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3211 [(set_attr "type" "shift,sload,*")
3212 (set_attr "us3load_type" "*,3cycle,*")
3213 (set_attr "cpu_feature" "*,*,vis3")])
3216 ;; Special pattern for optimizing bit-field compares. This is needed
3217 ;; because combine uses this as a canonical form.
3219 (define_insn "*cmp_zero_extract"
3220 [(set (reg:CC CC_REG)
3222 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3223 (match_operand:SI 1 "small_int_operand" "I")
3224 (match_operand:SI 2 "small_int_operand" "I"))
3226 "INTVAL (operands[2]) > 19"
3228 int len = INTVAL (operands[1]);
3229 int pos = 32 - INTVAL (operands[2]) - len;
3230 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3231 operands[1] = GEN_INT (mask);
3232 return "andcc\t%0, %1, %%g0";
3234 [(set_attr "type" "compare")])
3236 (define_insn "*cmp_zero_extract_sp64"
3237 [(set (reg:CCX CC_REG)
3239 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3240 (match_operand:SI 1 "small_int_operand" "I")
3241 (match_operand:SI 2 "small_int_operand" "I"))
3243 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3245 int len = INTVAL (operands[1]);
3246 int pos = 64 - INTVAL (operands[2]) - len;
3247 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3248 operands[1] = GEN_INT (mask);
3249 return "andcc\t%0, %1, %%g0";
3251 [(set_attr "type" "compare")])
3254 ;; Conversions between float, double and long double.
3256 (define_insn "extendsfdf2"
3257 [(set (match_operand:DF 0 "register_operand" "=e")
3259 (match_operand:SF 1 "register_operand" "f")))]
3262 [(set_attr "type" "fp")
3263 (set_attr "fptype" "double")])
3265 (define_expand "extendsftf2"
3266 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3268 (match_operand:SF 1 "register_operand" "")))]
3269 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3270 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3272 (define_insn "*extendsftf2_hq"
3273 [(set (match_operand:TF 0 "register_operand" "=e")
3275 (match_operand:SF 1 "register_operand" "f")))]
3276 "TARGET_FPU && TARGET_HARD_QUAD"
3278 [(set_attr "type" "fp")])
3280 (define_expand "extenddftf2"
3281 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3283 (match_operand:DF 1 "register_operand" "")))]
3284 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3285 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3287 (define_insn "*extenddftf2_hq"
3288 [(set (match_operand:TF 0 "register_operand" "=e")
3290 (match_operand:DF 1 "register_operand" "e")))]
3291 "TARGET_FPU && TARGET_HARD_QUAD"
3293 [(set_attr "type" "fp")])
3295 (define_insn "truncdfsf2"
3296 [(set (match_operand:SF 0 "register_operand" "=f")
3298 (match_operand:DF 1 "register_operand" "e")))]
3301 [(set_attr "type" "fp")
3302 (set_attr "fptype" "double")])
3304 (define_expand "trunctfsf2"
3305 [(set (match_operand:SF 0 "register_operand" "")
3307 (match_operand:TF 1 "general_operand" "")))]
3308 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3309 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3311 (define_insn "*trunctfsf2_hq"
3312 [(set (match_operand:SF 0 "register_operand" "=f")
3314 (match_operand:TF 1 "register_operand" "e")))]
3315 "TARGET_FPU && TARGET_HARD_QUAD"
3317 [(set_attr "type" "fp")])
3319 (define_expand "trunctfdf2"
3320 [(set (match_operand:DF 0 "register_operand" "")
3322 (match_operand:TF 1 "general_operand" "")))]
3323 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3324 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3326 (define_insn "*trunctfdf2_hq"
3327 [(set (match_operand:DF 0 "register_operand" "=e")
3329 (match_operand:TF 1 "register_operand" "e")))]
3330 "TARGET_FPU && TARGET_HARD_QUAD"
3332 [(set_attr "type" "fp")])
3335 ;; Conversion between fixed point and floating point.
3337 (define_insn "floatsisf2"
3338 [(set (match_operand:SF 0 "register_operand" "=f")
3339 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3342 [(set_attr "type" "fp")
3343 (set_attr "fptype" "double")])
3345 (define_insn "floatsidf2"
3346 [(set (match_operand:DF 0 "register_operand" "=e")
3347 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3350 [(set_attr "type" "fp")
3351 (set_attr "fptype" "double")])
3353 (define_expand "floatsitf2"
3354 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3355 (float:TF (match_operand:SI 1 "register_operand" "")))]
3356 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3357 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3359 (define_insn "*floatsitf2_hq"
3360 [(set (match_operand:TF 0 "register_operand" "=e")
3361 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3362 "TARGET_FPU && TARGET_HARD_QUAD"
3364 [(set_attr "type" "fp")])
3366 (define_expand "floatunssitf2"
3367 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3368 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3369 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3370 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3372 ;; Now the same for 64 bit sources.
3374 (define_insn "floatdisf2"
3375 [(set (match_operand:SF 0 "register_operand" "=f")
3376 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3377 "TARGET_V9 && TARGET_FPU"
3379 [(set_attr "type" "fp")
3380 (set_attr "fptype" "double")])
3382 (define_expand "floatunsdisf2"
3383 [(use (match_operand:SF 0 "register_operand" ""))
3384 (use (match_operand:DI 1 "general_operand" ""))]
3385 "TARGET_ARCH64 && TARGET_FPU"
3386 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3388 (define_insn "floatdidf2"
3389 [(set (match_operand:DF 0 "register_operand" "=e")
3390 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3391 "TARGET_V9 && TARGET_FPU"
3393 [(set_attr "type" "fp")
3394 (set_attr "fptype" "double")])
3396 (define_expand "floatunsdidf2"
3397 [(use (match_operand:DF 0 "register_operand" ""))
3398 (use (match_operand:DI 1 "general_operand" ""))]
3399 "TARGET_ARCH64 && TARGET_FPU"
3400 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3402 (define_expand "floatditf2"
3403 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3404 (float:TF (match_operand:DI 1 "register_operand" "")))]
3405 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3406 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3408 (define_insn "*floatditf2_hq"
3409 [(set (match_operand:TF 0 "register_operand" "=e")
3410 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3411 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3413 [(set_attr "type" "fp")])
3415 (define_expand "floatunsditf2"
3416 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3417 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3418 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3419 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3421 ;; Convert a float to an actual integer.
3422 ;; Truncation is performed as part of the conversion.
3424 (define_insn "fix_truncsfsi2"
3425 [(set (match_operand:SI 0 "register_operand" "=f")
3426 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3429 [(set_attr "type" "fp")
3430 (set_attr "fptype" "double")])
3432 (define_insn "fix_truncdfsi2"
3433 [(set (match_operand:SI 0 "register_operand" "=f")
3434 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3437 [(set_attr "type" "fp")
3438 (set_attr "fptype" "double")])
3440 (define_expand "fix_trunctfsi2"
3441 [(set (match_operand:SI 0 "register_operand" "")
3442 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3443 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3444 "emit_tfmode_cvt (FIX, operands); DONE;")
3446 (define_insn "*fix_trunctfsi2_hq"
3447 [(set (match_operand:SI 0 "register_operand" "=f")
3448 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3449 "TARGET_FPU && TARGET_HARD_QUAD"
3451 [(set_attr "type" "fp")])
3453 (define_expand "fixuns_trunctfsi2"
3454 [(set (match_operand:SI 0 "register_operand" "")
3455 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3456 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3457 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3459 ;; Now the same, for V9 targets
3461 (define_insn "fix_truncsfdi2"
3462 [(set (match_operand:DI 0 "register_operand" "=e")
3463 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3464 "TARGET_V9 && TARGET_FPU"
3466 [(set_attr "type" "fp")
3467 (set_attr "fptype" "double")])
3469 (define_expand "fixuns_truncsfdi2"
3470 [(use (match_operand:DI 0 "register_operand" ""))
3471 (use (match_operand:SF 1 "general_operand" ""))]
3472 "TARGET_ARCH64 && TARGET_FPU"
3473 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3475 (define_insn "fix_truncdfdi2"
3476 [(set (match_operand:DI 0 "register_operand" "=e")
3477 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3478 "TARGET_V9 && TARGET_FPU"
3480 [(set_attr "type" "fp")
3481 (set_attr "fptype" "double")])
3483 (define_expand "fixuns_truncdfdi2"
3484 [(use (match_operand:DI 0 "register_operand" ""))
3485 (use (match_operand:DF 1 "general_operand" ""))]
3486 "TARGET_ARCH64 && TARGET_FPU"
3487 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3489 (define_expand "fix_trunctfdi2"
3490 [(set (match_operand:DI 0 "register_operand" "")
3491 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3492 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3493 "emit_tfmode_cvt (FIX, operands); DONE;")
3495 (define_insn "*fix_trunctfdi2_hq"
3496 [(set (match_operand:DI 0 "register_operand" "=e")
3497 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3498 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3500 [(set_attr "type" "fp")])
3502 (define_expand "fixuns_trunctfdi2"
3503 [(set (match_operand:DI 0 "register_operand" "")
3504 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3505 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3506 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3509 ;; Integer addition/subtraction instructions.
3511 (define_expand "adddi3"
3512 [(set (match_operand:DI 0 "register_operand" "")
3513 (plus:DI (match_operand:DI 1 "register_operand" "")
3514 (match_operand:DI 2 "arith_double_add_operand" "")))]
3517 if (! TARGET_ARCH64)
3519 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3520 gen_rtx_SET (VOIDmode, operands[0],
3521 gen_rtx_PLUS (DImode, operands[1],
3523 gen_rtx_CLOBBER (VOIDmode,
3524 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3529 (define_insn_and_split "*adddi3_insn_sp32"
3530 [(set (match_operand:DI 0 "register_operand" "=&r")
3531 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3532 (match_operand:DI 2 "arith_double_operand" "rHI")))
3533 (clobber (reg:CC CC_REG))]
3536 "&& reload_completed"
3537 [(parallel [(set (reg:CC_NOOV CC_REG)
3538 (compare:CC_NOOV (plus:SI (match_dup 4)
3542 (plus:SI (match_dup 4) (match_dup 5)))])
3544 (plus:SI (plus:SI (match_dup 7)
3546 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3548 operands[3] = gen_lowpart (SImode, operands[0]);
3549 operands[4] = gen_lowpart (SImode, operands[1]);
3550 operands[5] = gen_lowpart (SImode, operands[2]);
3551 operands[6] = gen_highpart (SImode, operands[0]);
3552 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3553 #if HOST_BITS_PER_WIDE_INT == 32
3554 if (GET_CODE (operands[2]) == CONST_INT)
3556 if (INTVAL (operands[2]) < 0)
3557 operands[8] = constm1_rtx;
3559 operands[8] = const0_rtx;
3563 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3565 [(set_attr "length" "2")])
3567 ;; LTU here means "carry set"
3569 [(set (match_operand:SI 0 "register_operand" "=r")
3570 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3571 (match_operand:SI 2 "arith_operand" "rI"))
3572 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3575 [(set_attr "type" "ialuX")])
3577 (define_insn "addxc"
3578 [(set (match_operand:DI 0 "register_operand" "=r")
3579 (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
3580 (match_operand:DI 2 "register_or_zero_operand" "rJ"))
3581 (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3582 "TARGET_ARCH64 && TARGET_VIS3"
3583 "addxc\t%r1, %r2, %0"
3584 [(set_attr "type" "ialuX")])
3586 (define_insn_and_split "*addx_extend_sp32"
3587 [(set (match_operand:DI 0 "register_operand" "=r")
3588 (zero_extend:DI (plus:SI (plus:SI
3589 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3590 (match_operand:SI 2 "arith_operand" "rI"))
3591 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3594 "&& reload_completed"
3595 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3596 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3597 (set (match_dup 4) (const_int 0))]
3598 "operands[3] = gen_lowpart (SImode, operands[0]);
3599 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3600 [(set_attr "length" "2")])
3602 (define_insn "*addx_extend_sp64"
3603 [(set (match_operand:DI 0 "register_operand" "=r")
3604 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3605 (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3606 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3608 "addx\t%r1, %r2, %0"
3609 [(set_attr "type" "ialuX")])
3611 (define_insn "*addxc_trunc_sp64_vis3"
3612 [(set (match_operand:SI 0 "register_operand" "=r")
3613 (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3614 (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3615 (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3616 "TARGET_ARCH64 && TARGET_VIS3"
3617 "addxc\t%r1, %r2, %0"
3618 [(set_attr "type" "ialuX")])
3620 (define_insn_and_split "*adddi3_extend_sp32"
3621 [(set (match_operand:DI 0 "register_operand" "=r")
3622 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3623 (match_operand:DI 2 "register_operand" "r")))
3624 (clobber (reg:CC CC_REG))]
3627 "&& reload_completed"
3628 [(parallel [(set (reg:CC_NOOV CC_REG)
3629 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3631 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3633 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3634 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3635 "operands[3] = gen_lowpart (SImode, operands[2]);
3636 operands[4] = gen_highpart (SImode, operands[2]);
3637 operands[5] = gen_lowpart (SImode, operands[0]);
3638 operands[6] = gen_highpart (SImode, operands[0]);"
3639 [(set_attr "length" "2")])
3641 (define_insn "*adddi3_sp64"
3642 [(set (match_operand:DI 0 "register_operand" "=r,r")
3643 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3644 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3650 (define_insn "addsi3"
3651 [(set (match_operand:SI 0 "register_operand" "=r,r")
3652 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3653 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3658 [(set_attr "type" "*,*")
3659 (set_attr "fptype" "*,*")])
3661 (define_insn "*cmp_cc_plus"
3662 [(set (reg:CC_NOOV CC_REG)
3663 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3664 (match_operand:SI 1 "arith_operand" "rI"))
3667 "addcc\t%0, %1, %%g0"
3668 [(set_attr "type" "compare")])
3670 (define_insn "*cmp_ccx_plus"
3671 [(set (reg:CCX_NOOV CC_REG)
3672 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3673 (match_operand:DI 1 "arith_operand" "rI"))
3676 "addcc\t%0, %1, %%g0"
3677 [(set_attr "type" "compare")])
3679 (define_insn "*cmp_cc_plus_set"
3680 [(set (reg:CC_NOOV CC_REG)
3681 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3682 (match_operand:SI 2 "arith_operand" "rI"))
3684 (set (match_operand:SI 0 "register_operand" "=r")
3685 (plus:SI (match_dup 1) (match_dup 2)))]
3688 [(set_attr "type" "compare")])
3690 (define_insn "*cmp_ccx_plus_set"
3691 [(set (reg:CCX_NOOV CC_REG)
3692 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3693 (match_operand:DI 2 "arith_operand" "rI"))
3695 (set (match_operand:DI 0 "register_operand" "=r")
3696 (plus:DI (match_dup 1) (match_dup 2)))]
3699 [(set_attr "type" "compare")])
3701 (define_expand "subdi3"
3702 [(set (match_operand:DI 0 "register_operand" "")
3703 (minus:DI (match_operand:DI 1 "register_operand" "")
3704 (match_operand:DI 2 "arith_double_add_operand" "")))]
3707 if (! TARGET_ARCH64)
3709 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3710 gen_rtx_SET (VOIDmode, operands[0],
3711 gen_rtx_MINUS (DImode, operands[1],
3713 gen_rtx_CLOBBER (VOIDmode,
3714 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3719 (define_insn_and_split "*subdi3_insn_sp32"
3720 [(set (match_operand:DI 0 "register_operand" "=r")
3721 (minus:DI (match_operand:DI 1 "register_operand" "r")
3722 (match_operand:DI 2 "arith_double_operand" "rHI")))
3723 (clobber (reg:CC CC_REG))]
3726 "&& reload_completed"
3727 [(parallel [(set (reg:CC_NOOV CC_REG)
3728 (compare:CC_NOOV (minus:SI (match_dup 4)
3732 (minus:SI (match_dup 4) (match_dup 5)))])
3734 (minus:SI (minus:SI (match_dup 7)
3736 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3738 operands[3] = gen_lowpart (SImode, operands[0]);
3739 operands[4] = gen_lowpart (SImode, operands[1]);
3740 operands[5] = gen_lowpart (SImode, operands[2]);
3741 operands[6] = gen_highpart (SImode, operands[0]);
3742 operands[7] = gen_highpart (SImode, operands[1]);
3743 #if HOST_BITS_PER_WIDE_INT == 32
3744 if (GET_CODE (operands[2]) == CONST_INT)
3746 if (INTVAL (operands[2]) < 0)
3747 operands[8] = constm1_rtx;
3749 operands[8] = const0_rtx;
3753 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3755 [(set_attr "length" "2")])
3757 ;; LTU here means "carry set"
3759 [(set (match_operand:SI 0 "register_operand" "=r")
3760 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3761 (match_operand:SI 2 "arith_operand" "rI"))
3762 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3765 [(set_attr "type" "ialuX")])
3767 (define_insn "*subx_extend_sp64"
3768 [(set (match_operand:DI 0 "register_operand" "=r")
3769 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3770 (match_operand:SI 2 "arith_operand" "rI"))
3771 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3774 [(set_attr "type" "ialuX")])
3776 (define_insn_and_split "*subx_extend"
3777 [(set (match_operand:DI 0 "register_operand" "=r")
3778 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3779 (match_operand:SI 2 "arith_operand" "rI"))
3780 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3783 "&& reload_completed"
3784 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3785 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3786 (set (match_dup 4) (const_int 0))]
3787 "operands[3] = gen_lowpart (SImode, operands[0]);
3788 operands[4] = gen_highpart (SImode, operands[0]);"
3789 [(set_attr "length" "2")])
3791 (define_insn_and_split "*subdi3_extend_sp32"
3792 [(set (match_operand:DI 0 "register_operand" "=r")
3793 (minus:DI (match_operand:DI 1 "register_operand" "r")
3794 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3795 (clobber (reg:CC CC_REG))]
3798 "&& reload_completed"
3799 [(parallel [(set (reg:CC_NOOV CC_REG)
3800 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3802 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3804 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3805 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3806 "operands[3] = gen_lowpart (SImode, operands[1]);
3807 operands[4] = gen_highpart (SImode, operands[1]);
3808 operands[5] = gen_lowpart (SImode, operands[0]);
3809 operands[6] = gen_highpart (SImode, operands[0]);"
3810 [(set_attr "length" "2")])
3812 (define_insn "*subdi3_sp64"
3813 [(set (match_operand:DI 0 "register_operand" "=r,r")
3814 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3815 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3821 (define_insn "subsi3"
3822 [(set (match_operand:SI 0 "register_operand" "=r,r")
3823 (minus:SI (match_operand:SI 1 "register_operand" "r,r")
3824 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3829 [(set_attr "type" "*,*")
3830 (set_attr "fptype" "*,*")])
3832 (define_insn "*cmp_minus_cc"
3833 [(set (reg:CC_NOOV CC_REG)
3834 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3835 (match_operand:SI 1 "arith_operand" "rI"))
3838 "subcc\t%r0, %1, %%g0"
3839 [(set_attr "type" "compare")])
3841 (define_insn "*cmp_minus_ccx"
3842 [(set (reg:CCX_NOOV CC_REG)
3843 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3844 (match_operand:DI 1 "arith_operand" "rI"))
3847 "subcc\t%0, %1, %%g0"
3848 [(set_attr "type" "compare")])
3850 (define_insn "cmp_minus_cc_set"
3851 [(set (reg:CC_NOOV CC_REG)
3852 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3853 (match_operand:SI 2 "arith_operand" "rI"))
3855 (set (match_operand:SI 0 "register_operand" "=r")
3856 (minus:SI (match_dup 1) (match_dup 2)))]
3858 "subcc\t%r1, %2, %0"
3859 [(set_attr "type" "compare")])
3861 (define_insn "*cmp_minus_ccx_set"
3862 [(set (reg:CCX_NOOV CC_REG)
3863 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3864 (match_operand:DI 2 "arith_operand" "rI"))
3866 (set (match_operand:DI 0 "register_operand" "=r")
3867 (minus:DI (match_dup 1) (match_dup 2)))]
3870 [(set_attr "type" "compare")])
3873 ;; Integer multiply/divide instructions.
3875 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3876 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3878 (define_insn "mulsi3"
3879 [(set (match_operand:SI 0 "register_operand" "=r")
3880 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3881 (match_operand:SI 2 "arith_operand" "rI")))]
3884 [(set_attr "type" "imul")])
3886 (define_expand "muldi3"
3887 [(set (match_operand:DI 0 "register_operand" "")
3888 (mult:DI (match_operand:DI 1 "arith_operand" "")
3889 (match_operand:DI 2 "arith_operand" "")))]
3890 "TARGET_ARCH64 || TARGET_V8PLUS"
3894 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3899 (define_insn "*muldi3_sp64"
3900 [(set (match_operand:DI 0 "register_operand" "=r")
3901 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3902 (match_operand:DI 2 "arith_operand" "rI")))]
3905 [(set_attr "type" "imul")])
3907 ;; V8plus wide multiply.
3909 (define_insn "muldi3_v8plus"
3910 [(set (match_operand:DI 0 "register_operand" "=r,h")
3911 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3912 (match_operand:DI 2 "arith_operand" "rI,rI")))
3913 (clobber (match_scratch:SI 3 "=&h,X"))
3914 (clobber (match_scratch:SI 4 "=&h,X"))]
3916 "* return output_v8plus_mult (insn, operands, \"mulx\");"
3917 [(set_attr "type" "multi")
3918 (set_attr "length" "9,8")])
3920 (define_insn "*cmp_mul_set"
3921 [(set (reg:CC CC_REG)
3922 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3923 (match_operand:SI 2 "arith_operand" "rI"))
3925 (set (match_operand:SI 0 "register_operand" "=r")
3926 (mult:SI (match_dup 1) (match_dup 2)))]
3927 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3928 "smulcc\t%1, %2, %0"
3929 [(set_attr "type" "imul")])
3931 (define_expand "mulsidi3"
3932 [(set (match_operand:DI 0 "register_operand" "")
3933 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3934 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3937 if (CONSTANT_P (operands[2]))
3940 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3942 else if (TARGET_ARCH32)
3943 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3946 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3952 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3957 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
3958 ;; registers can hold 64-bit values in the V8plus environment.
3960 (define_insn "mulsidi3_v8plus"
3961 [(set (match_operand:DI 0 "register_operand" "=h,r")
3962 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3963 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3964 (clobber (match_scratch:SI 3 "=X,&h"))]
3967 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3968 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3969 [(set_attr "type" "multi")
3970 (set_attr "length" "2,3")])
3973 (define_insn "const_mulsidi3_v8plus"
3974 [(set (match_operand:DI 0 "register_operand" "=h,r")
3975 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3976 (match_operand:DI 2 "small_int_operand" "I,I")))
3977 (clobber (match_scratch:SI 3 "=X,&h"))]
3980 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3981 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3982 [(set_attr "type" "multi")
3983 (set_attr "length" "2,3")])
3986 (define_insn "*mulsidi3_sp32"
3987 [(set (match_operand:DI 0 "register_operand" "=r")
3988 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3989 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3992 return TARGET_SPARCLET
3993 ? "smuld\t%1, %2, %L0"
3994 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3997 (if_then_else (eq_attr "isa" "sparclet")
3998 (const_string "imul") (const_string "multi")))
3999 (set (attr "length")
4000 (if_then_else (eq_attr "isa" "sparclet")
4001 (const_int 1) (const_int 2)))])
4003 (define_insn "*mulsidi3_sp64"
4004 [(set (match_operand:DI 0 "register_operand" "=r")
4005 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4006 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4007 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4009 [(set_attr "type" "imul")])
4011 ;; Extra pattern, because sign_extend of a constant isn't valid.
4014 (define_insn "const_mulsidi3_sp32"
4015 [(set (match_operand:DI 0 "register_operand" "=r")
4016 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4017 (match_operand:DI 2 "small_int_operand" "I")))]
4020 return TARGET_SPARCLET
4021 ? "smuld\t%1, %2, %L0"
4022 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4025 (if_then_else (eq_attr "isa" "sparclet")
4026 (const_string "imul") (const_string "multi")))
4027 (set (attr "length")
4028 (if_then_else (eq_attr "isa" "sparclet")
4029 (const_int 1) (const_int 2)))])
4031 (define_insn "const_mulsidi3_sp64"
4032 [(set (match_operand:DI 0 "register_operand" "=r")
4033 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4034 (match_operand:DI 2 "small_int_operand" "I")))]
4035 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4037 [(set_attr "type" "imul")])
4039 (define_expand "smulsi3_highpart"
4040 [(set (match_operand:SI 0 "register_operand" "")
4042 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4043 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4045 "TARGET_HARD_MUL && TARGET_ARCH32"
4047 if (CONSTANT_P (operands[2]))
4051 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4057 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4062 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4063 operands[2], GEN_INT (32)));
4069 (define_insn "smulsi3_highpart_v8plus"
4070 [(set (match_operand:SI 0 "register_operand" "=h,r")
4072 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4073 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4074 (match_operand:SI 3 "small_int_operand" "I,I"))))
4075 (clobber (match_scratch:SI 4 "=X,&h"))]
4078 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4079 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4080 [(set_attr "type" "multi")
4081 (set_attr "length" "2")])
4083 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4086 [(set (match_operand:SI 0 "register_operand" "=h,r")
4089 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4090 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4091 (match_operand:SI 3 "small_int_operand" "I,I"))
4093 (clobber (match_scratch:SI 4 "=X,&h"))]
4096 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4097 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4098 [(set_attr "type" "multi")
4099 (set_attr "length" "2")])
4102 (define_insn "const_smulsi3_highpart_v8plus"
4103 [(set (match_operand:SI 0 "register_operand" "=h,r")
4105 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4106 (match_operand:DI 2 "small_int_operand" "I,I"))
4107 (match_operand:SI 3 "small_int_operand" "I,I"))))
4108 (clobber (match_scratch:SI 4 "=X,&h"))]
4111 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4112 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4113 [(set_attr "type" "multi")
4114 (set_attr "length" "2")])
4117 (define_insn "*smulsi3_highpart_sp32"
4118 [(set (match_operand:SI 0 "register_operand" "=r")
4120 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4121 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4124 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4125 [(set_attr "type" "multi")
4126 (set_attr "length" "2")])
4129 (define_insn "const_smulsi3_highpart"
4130 [(set (match_operand:SI 0 "register_operand" "=r")
4132 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4133 (match_operand:DI 2 "small_int_operand" "i"))
4136 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4137 [(set_attr "type" "multi")
4138 (set_attr "length" "2")])
4140 (define_expand "umulsidi3"
4141 [(set (match_operand:DI 0 "register_operand" "")
4142 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4143 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4146 if (CONSTANT_P (operands[2]))
4149 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4151 else if (TARGET_ARCH32)
4152 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4155 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4161 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4167 (define_insn "umulsidi3_v8plus"
4168 [(set (match_operand:DI 0 "register_operand" "=h,r")
4169 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4170 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4171 (clobber (match_scratch:SI 3 "=X,&h"))]
4174 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4175 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4176 [(set_attr "type" "multi")
4177 (set_attr "length" "2,3")])
4180 (define_insn "*umulsidi3_sp32"
4181 [(set (match_operand:DI 0 "register_operand" "=r")
4182 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4183 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4186 return TARGET_SPARCLET
4187 ? "umuld\t%1, %2, %L0"
4188 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4191 (if_then_else (eq_attr "isa" "sparclet")
4192 (const_string "imul") (const_string "multi")))
4193 (set (attr "length")
4194 (if_then_else (eq_attr "isa" "sparclet")
4195 (const_int 1) (const_int 2)))])
4197 (define_insn "*umulsidi3_sp64"
4198 [(set (match_operand:DI 0 "register_operand" "=r")
4199 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4200 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4201 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4203 [(set_attr "type" "imul")])
4205 ;; Extra pattern, because sign_extend of a constant isn't valid.
4208 (define_insn "const_umulsidi3_sp32"
4209 [(set (match_operand:DI 0 "register_operand" "=r")
4210 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4211 (match_operand:DI 2 "uns_small_int_operand" "")))]
4214 return TARGET_SPARCLET
4215 ? "umuld\t%1, %s2, %L0"
4216 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4219 (if_then_else (eq_attr "isa" "sparclet")
4220 (const_string "imul") (const_string "multi")))
4221 (set (attr "length")
4222 (if_then_else (eq_attr "isa" "sparclet")
4223 (const_int 1) (const_int 2)))])
4225 (define_insn "const_umulsidi3_sp64"
4226 [(set (match_operand:DI 0 "register_operand" "=r")
4227 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4228 (match_operand:DI 2 "uns_small_int_operand" "")))]
4229 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4231 [(set_attr "type" "imul")])
4234 (define_insn "const_umulsidi3_v8plus"
4235 [(set (match_operand:DI 0 "register_operand" "=h,r")
4236 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4237 (match_operand:DI 2 "uns_small_int_operand" "")))
4238 (clobber (match_scratch:SI 3 "=X,h"))]
4241 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4242 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4243 [(set_attr "type" "multi")
4244 (set_attr "length" "2,3")])
4246 (define_expand "umulsi3_highpart"
4247 [(set (match_operand:SI 0 "register_operand" "")
4249 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4250 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4252 "TARGET_HARD_MUL && TARGET_ARCH32"
4254 if (CONSTANT_P (operands[2]))
4258 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4264 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4269 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4270 operands[2], GEN_INT (32)));
4276 (define_insn "umulsi3_highpart_v8plus"
4277 [(set (match_operand:SI 0 "register_operand" "=h,r")
4279 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4280 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4281 (match_operand:SI 3 "small_int_operand" "I,I"))))
4282 (clobber (match_scratch:SI 4 "=X,h"))]
4285 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4286 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4287 [(set_attr "type" "multi")
4288 (set_attr "length" "2")])
4291 (define_insn "const_umulsi3_highpart_v8plus"
4292 [(set (match_operand:SI 0 "register_operand" "=h,r")
4294 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4295 (match_operand:DI 2 "uns_small_int_operand" ""))
4296 (match_operand:SI 3 "small_int_operand" "I,I"))))
4297 (clobber (match_scratch:SI 4 "=X,h"))]
4300 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4301 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4302 [(set_attr "type" "multi")
4303 (set_attr "length" "2")])
4306 (define_insn "*umulsi3_highpart_sp32"
4307 [(set (match_operand:SI 0 "register_operand" "=r")
4309 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4310 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4313 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4314 [(set_attr "type" "multi")
4315 (set_attr "length" "2")])
4318 (define_insn "const_umulsi3_highpart"
4319 [(set (match_operand:SI 0 "register_operand" "=r")
4321 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4322 (match_operand:DI 2 "uns_small_int_operand" ""))
4325 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4326 [(set_attr "type" "multi")
4327 (set_attr "length" "2")])
4329 (define_expand "divsi3"
4330 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4331 (div:SI (match_operand:SI 1 "register_operand" "")
4332 (match_operand:SI 2 "input_operand" "")))
4333 (clobber (match_scratch:SI 3 ""))])]
4334 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4338 operands[3] = gen_reg_rtx(SImode);
4339 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4340 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4346 ;; The V8 architecture specifies that there must be at least 3 instructions
4347 ;; between a write to the Y register and a use of it for correct results.
4348 ;; We try to fill one of them with a simple constant or a memory load.
4350 (define_insn "divsi3_sp32"
4351 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4352 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4353 (match_operand:SI 2 "input_operand" "rI,K,m")))
4354 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4355 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4357 output_asm_insn ("sra\t%1, 31, %3", operands);
4358 output_asm_insn ("wr\t%3, 0, %%y", operands);
4360 switch (which_alternative)
4364 return "sdiv\t%1, %2, %0";
4366 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4369 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4371 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4374 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4376 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4381 [(set_attr "type" "multi")
4382 (set (attr "length")
4383 (if_then_else (eq_attr "isa" "v9")
4384 (const_int 4) (const_int 6)))])
4386 (define_insn "divsi3_sp64"
4387 [(set (match_operand:SI 0 "register_operand" "=r")
4388 (div:SI (match_operand:SI 1 "register_operand" "r")
4389 (match_operand:SI 2 "input_operand" "rI")))
4390 (use (match_operand:SI 3 "register_operand" "r"))]
4391 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4392 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4393 [(set_attr "type" "multi")
4394 (set_attr "length" "2")])
4396 (define_insn "divdi3"
4397 [(set (match_operand:DI 0 "register_operand" "=r")
4398 (div:DI (match_operand:DI 1 "register_operand" "r")
4399 (match_operand:DI 2 "arith_operand" "rI")))]
4402 [(set_attr "type" "idiv")])
4404 (define_insn "*cmp_sdiv_cc_set"
4405 [(set (reg:CC CC_REG)
4406 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4407 (match_operand:SI 2 "arith_operand" "rI"))
4409 (set (match_operand:SI 0 "register_operand" "=r")
4410 (div:SI (match_dup 1) (match_dup 2)))
4411 (clobber (match_scratch:SI 3 "=&r"))]
4412 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4414 output_asm_insn ("sra\t%1, 31, %3", operands);
4415 output_asm_insn ("wr\t%3, 0, %%y", operands);
4418 return "sdivcc\t%1, %2, %0";
4420 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4422 [(set_attr "type" "multi")
4423 (set (attr "length")
4424 (if_then_else (eq_attr "isa" "v9")
4425 (const_int 3) (const_int 6)))])
4428 (define_expand "udivsi3"
4429 [(set (match_operand:SI 0 "register_operand" "")
4430 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4431 (match_operand:SI 2 "input_operand" "")))]
4432 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4435 ;; The V8 architecture specifies that there must be at least 3 instructions
4436 ;; between a write to the Y register and a use of it for correct results.
4437 ;; We try to fill one of them with a simple constant or a memory load.
4439 (define_insn "udivsi3_sp32"
4440 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4441 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4442 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4443 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4445 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4447 switch (which_alternative)
4451 return "udiv\t%1, %2, %0";
4453 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4456 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4458 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4461 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4463 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4466 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4468 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4473 [(set_attr "type" "multi")
4474 (set (attr "length")
4475 (if_then_else (eq_attr "isa" "v9")
4476 (const_int 3) (const_int 5)))])
4478 (define_insn "udivsi3_sp64"
4479 [(set (match_operand:SI 0 "register_operand" "=r")
4480 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4481 (match_operand:SI 2 "input_operand" "rI")))]
4482 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4483 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4484 [(set_attr "type" "multi")
4485 (set_attr "length" "2")])
4487 (define_insn "udivdi3"
4488 [(set (match_operand:DI 0 "register_operand" "=r")
4489 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4490 (match_operand:DI 2 "arith_operand" "rI")))]
4493 [(set_attr "type" "idiv")])
4495 (define_insn "*cmp_udiv_cc_set"
4496 [(set (reg:CC CC_REG)
4497 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4498 (match_operand:SI 2 "arith_operand" "rI"))
4500 (set (match_operand:SI 0 "register_operand" "=r")
4501 (udiv:SI (match_dup 1) (match_dup 2)))]
4502 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4504 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4507 return "udivcc\t%1, %2, %0";
4509 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4511 [(set_attr "type" "multi")
4512 (set (attr "length")
4513 (if_then_else (eq_attr "isa" "v9")
4514 (const_int 2) (const_int 5)))])
4516 ; sparclet multiply/accumulate insns
4518 (define_insn "*smacsi"
4519 [(set (match_operand:SI 0 "register_operand" "=r")
4520 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4521 (match_operand:SI 2 "arith_operand" "rI"))
4522 (match_operand:SI 3 "register_operand" "0")))]
4525 [(set_attr "type" "imul")])
4527 (define_insn "*smacdi"
4528 [(set (match_operand:DI 0 "register_operand" "=r")
4529 (plus:DI (mult:DI (sign_extend:DI
4530 (match_operand:SI 1 "register_operand" "%r"))
4532 (match_operand:SI 2 "register_operand" "r")))
4533 (match_operand:DI 3 "register_operand" "0")))]
4535 "smacd\t%1, %2, %L0"
4536 [(set_attr "type" "imul")])
4538 (define_insn "*umacdi"
4539 [(set (match_operand:DI 0 "register_operand" "=r")
4540 (plus:DI (mult:DI (zero_extend:DI
4541 (match_operand:SI 1 "register_operand" "%r"))
4543 (match_operand:SI 2 "register_operand" "r")))
4544 (match_operand:DI 3 "register_operand" "0")))]
4546 "umacd\t%1, %2, %L0"
4547 [(set_attr "type" "imul")])
4550 ;; Boolean instructions.
4552 ;; We define DImode `and' so with DImode `not' we can get
4553 ;; DImode `andn'. Other combinations are possible.
4555 (define_expand "anddi3"
4556 [(set (match_operand:DI 0 "register_operand" "")
4557 (and:DI (match_operand:DI 1 "arith_double_operand" "")
4558 (match_operand:DI 2 "arith_double_operand" "")))]
4562 (define_insn "*anddi3_sp32"
4563 [(set (match_operand:DI 0 "register_operand" "=r")
4564 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4565 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4569 (define_insn "*anddi3_sp64"
4570 [(set (match_operand:DI 0 "register_operand" "=r")
4571 (and:DI (match_operand:DI 1 "arith_operand" "%r")
4572 (match_operand:DI 2 "arith_operand" "rI")))]
4576 (define_insn "andsi3"
4577 [(set (match_operand:SI 0 "register_operand" "=r")
4578 (and:SI (match_operand:SI 1 "arith_operand" "%r")
4579 (match_operand:SI 2 "arith_operand" "rI")))]
4584 [(set (match_operand:SI 0 "register_operand" "")
4585 (and:SI (match_operand:SI 1 "register_operand" "")
4586 (match_operand:SI 2 "const_compl_high_operand" "")))
4587 (clobber (match_operand:SI 3 "register_operand" ""))]
4589 [(set (match_dup 3) (match_dup 4))
4590 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4592 operands[4] = GEN_INT (~INTVAL (operands[2]));
4595 (define_insn_and_split "*and_not_di_sp32"
4596 [(set (match_operand:DI 0 "register_operand" "=r")
4597 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4598 (match_operand:DI 2 "register_operand" "r")))]
4601 "&& reload_completed
4602 && ((GET_CODE (operands[0]) == REG
4603 && SPARC_INT_REG_P (REGNO (operands[0])))
4604 || (GET_CODE (operands[0]) == SUBREG
4605 && GET_CODE (SUBREG_REG (operands[0])) == REG
4606 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4607 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4608 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4609 "operands[3] = gen_highpart (SImode, operands[0]);
4610 operands[4] = gen_highpart (SImode, operands[1]);
4611 operands[5] = gen_highpart (SImode, operands[2]);
4612 operands[6] = gen_lowpart (SImode, operands[0]);
4613 operands[7] = gen_lowpart (SImode, operands[1]);
4614 operands[8] = gen_lowpart (SImode, operands[2]);"
4615 [(set_attr "length" "2")])
4617 (define_insn "*and_not_di_sp64"
4618 [(set (match_operand:DI 0 "register_operand" "=r")
4619 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4620 (match_operand:DI 2 "register_operand" "r")))]
4624 (define_insn "*and_not_si"
4625 [(set (match_operand:SI 0 "register_operand" "=r")
4626 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4627 (match_operand:SI 2 "register_operand" "r")))]
4631 (define_expand "iordi3"
4632 [(set (match_operand:DI 0 "register_operand" "")
4633 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4634 (match_operand:DI 2 "arith_double_operand" "")))]
4638 (define_insn "*iordi3_sp32"
4639 [(set (match_operand:DI 0 "register_operand" "=r")
4640 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4641 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4644 [(set_attr "length" "2")])
4646 (define_insn "*iordi3_sp64"
4647 [(set (match_operand:DI 0 "register_operand" "=r")
4648 (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4649 (match_operand:DI 2 "arith_operand" "rI")))]
4653 (define_insn "iorsi3"
4654 [(set (match_operand:SI 0 "register_operand" "=r")
4655 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4656 (match_operand:SI 2 "arith_operand" "rI")))]
4661 [(set (match_operand:SI 0 "register_operand" "")
4662 (ior:SI (match_operand:SI 1 "register_operand" "")
4663 (match_operand:SI 2 "const_compl_high_operand" "")))
4664 (clobber (match_operand:SI 3 "register_operand" ""))]
4666 [(set (match_dup 3) (match_dup 4))
4667 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4669 operands[4] = GEN_INT (~INTVAL (operands[2]));
4672 (define_insn_and_split "*or_not_di_sp32"
4673 [(set (match_operand:DI 0 "register_operand" "=r")
4674 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4675 (match_operand:DI 2 "register_operand" "r")))]
4678 "&& reload_completed
4679 && ((GET_CODE (operands[0]) == REG
4680 && SPARC_INT_REG_P (REGNO (operands[0])))
4681 || (GET_CODE (operands[0]) == SUBREG
4682 && GET_CODE (SUBREG_REG (operands[0])) == REG
4683 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4684 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4685 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4686 "operands[3] = gen_highpart (SImode, operands[0]);
4687 operands[4] = gen_highpart (SImode, operands[1]);
4688 operands[5] = gen_highpart (SImode, operands[2]);
4689 operands[6] = gen_lowpart (SImode, operands[0]);
4690 operands[7] = gen_lowpart (SImode, operands[1]);
4691 operands[8] = gen_lowpart (SImode, operands[2]);"
4692 [(set_attr "length" "2")])
4694 (define_insn "*or_not_di_sp64"
4695 [(set (match_operand:DI 0 "register_operand" "=r")
4696 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4697 (match_operand:DI 2 "register_operand" "r")))]
4701 (define_insn "*or_not_si"
4702 [(set (match_operand:SI 0 "register_operand" "=r")
4703 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4704 (match_operand:SI 2 "register_operand" "r")))]
4708 (define_expand "xordi3"
4709 [(set (match_operand:DI 0 "register_operand" "")
4710 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4711 (match_operand:DI 2 "arith_double_operand" "")))]
4715 (define_insn "*xordi3_sp32"
4716 [(set (match_operand:DI 0 "register_operand" "=r")
4717 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4718 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4721 [(set_attr "length" "2")])
4723 (define_insn "*xordi3_sp64"
4724 [(set (match_operand:DI 0 "register_operand" "=r")
4725 (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4726 (match_operand:DI 2 "arith_operand" "rI")))]
4730 (define_insn "xorsi3"
4731 [(set (match_operand:SI 0 "register_operand" "=r")
4732 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4733 (match_operand:SI 2 "arith_operand" "rI")))]
4738 [(set (match_operand:SI 0 "register_operand" "")
4739 (xor:SI (match_operand:SI 1 "register_operand" "")
4740 (match_operand:SI 2 "const_compl_high_operand" "")))
4741 (clobber (match_operand:SI 3 "register_operand" ""))]
4743 [(set (match_dup 3) (match_dup 4))
4744 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4746 operands[4] = GEN_INT (~INTVAL (operands[2]));
4750 [(set (match_operand:SI 0 "register_operand" "")
4751 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4752 (match_operand:SI 2 "const_compl_high_operand" ""))))
4753 (clobber (match_operand:SI 3 "register_operand" ""))]
4755 [(set (match_dup 3) (match_dup 4))
4756 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4758 operands[4] = GEN_INT (~INTVAL (operands[2]));
4761 ;; Split DImode logical operations requiring two instructions.
4763 [(set (match_operand:DI 0 "register_operand" "")
4764 (match_operator:DI 1 "cc_arith_operator" ; AND, IOR, XOR
4765 [(match_operand:DI 2 "register_operand" "")
4766 (match_operand:DI 3 "arith_double_operand" "")]))]
4769 && ((GET_CODE (operands[0]) == REG
4770 && SPARC_INT_REG_P (REGNO (operands[0])))
4771 || (GET_CODE (operands[0]) == SUBREG
4772 && GET_CODE (SUBREG_REG (operands[0])) == REG
4773 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4774 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4775 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4777 operands[4] = gen_highpart (SImode, operands[0]);
4778 operands[5] = gen_lowpart (SImode, operands[0]);
4779 operands[6] = gen_highpart (SImode, operands[2]);
4780 operands[7] = gen_lowpart (SImode, operands[2]);
4781 #if HOST_BITS_PER_WIDE_INT == 32
4782 if (GET_CODE (operands[3]) == CONST_INT)
4784 if (INTVAL (operands[3]) < 0)
4785 operands[8] = constm1_rtx;
4787 operands[8] = const0_rtx;
4791 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
4792 operands[9] = gen_lowpart (SImode, operands[3]);
4795 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4796 ;; Combine now canonicalizes to the rightmost expression.
4797 (define_insn_and_split "*xor_not_di_sp32"
4798 [(set (match_operand:DI 0 "register_operand" "=r")
4799 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
4800 (match_operand:DI 2 "register_operand" "r"))))]
4803 "&& reload_completed
4804 && ((GET_CODE (operands[0]) == REG
4805 && SPARC_INT_REG_P (REGNO (operands[0])))
4806 || (GET_CODE (operands[0]) == SUBREG
4807 && GET_CODE (SUBREG_REG (operands[0])) == REG
4808 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4809 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4810 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4811 "operands[3] = gen_highpart (SImode, operands[0]);
4812 operands[4] = gen_highpart (SImode, operands[1]);
4813 operands[5] = gen_highpart (SImode, operands[2]);
4814 operands[6] = gen_lowpart (SImode, operands[0]);
4815 operands[7] = gen_lowpart (SImode, operands[1]);
4816 operands[8] = gen_lowpart (SImode, operands[2]);"
4817 [(set_attr "length" "2")])
4819 (define_insn "*xor_not_di_sp64"
4820 [(set (match_operand:DI 0 "register_operand" "=r")
4821 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4822 (match_operand:DI 2 "arith_operand" "rI"))))]
4824 "xnor\t%r1, %2, %0")
4826 (define_insn "*xor_not_si"
4827 [(set (match_operand:SI 0 "register_operand" "=r")
4828 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4829 (match_operand:SI 2 "arith_operand" "rI"))))]
4831 "xnor\t%r1, %2, %0")
4833 ;; These correspond to the above in the case where we also (or only)
4834 ;; want to set the condition code.
4836 (define_insn "*cmp_cc_arith_op"
4837 [(set (reg:CC CC_REG)
4839 (match_operator:SI 2 "cc_arith_operator"
4840 [(match_operand:SI 0 "arith_operand" "%r")
4841 (match_operand:SI 1 "arith_operand" "rI")])
4844 "%A2cc\t%0, %1, %%g0"
4845 [(set_attr "type" "compare")])
4847 (define_insn "*cmp_ccx_arith_op"
4848 [(set (reg:CCX CC_REG)
4850 (match_operator:DI 2 "cc_arith_operator"
4851 [(match_operand:DI 0 "arith_operand" "%r")
4852 (match_operand:DI 1 "arith_operand" "rI")])
4855 "%A2cc\t%0, %1, %%g0"
4856 [(set_attr "type" "compare")])
4858 (define_insn "*cmp_cc_arith_op_set"
4859 [(set (reg:CC CC_REG)
4861 (match_operator:SI 3 "cc_arith_operator"
4862 [(match_operand:SI 1 "arith_operand" "%r")
4863 (match_operand:SI 2 "arith_operand" "rI")])
4865 (set (match_operand:SI 0 "register_operand" "=r")
4866 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4867 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4869 [(set_attr "type" "compare")])
4871 (define_insn "*cmp_ccx_arith_op_set"
4872 [(set (reg:CCX CC_REG)
4874 (match_operator:DI 3 "cc_arith_operator"
4875 [(match_operand:DI 1 "arith_operand" "%r")
4876 (match_operand:DI 2 "arith_operand" "rI")])
4878 (set (match_operand:DI 0 "register_operand" "=r")
4879 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4880 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4882 [(set_attr "type" "compare")])
4884 (define_insn "*cmp_cc_xor_not"
4885 [(set (reg:CC CC_REG)
4887 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4888 (match_operand:SI 1 "arith_operand" "rI")))
4891 "xnorcc\t%r0, %1, %%g0"
4892 [(set_attr "type" "compare")])
4894 (define_insn "*cmp_ccx_xor_not"
4895 [(set (reg:CCX CC_REG)
4897 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4898 (match_operand:DI 1 "arith_operand" "rI")))
4901 "xnorcc\t%r0, %1, %%g0"
4902 [(set_attr "type" "compare")])
4904 (define_insn "*cmp_cc_xor_not_set"
4905 [(set (reg:CC CC_REG)
4907 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4908 (match_operand:SI 2 "arith_operand" "rI")))
4910 (set (match_operand:SI 0 "register_operand" "=r")
4911 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4913 "xnorcc\t%r1, %2, %0"
4914 [(set_attr "type" "compare")])
4916 (define_insn "*cmp_ccx_xor_not_set"
4917 [(set (reg:CCX CC_REG)
4919 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4920 (match_operand:DI 2 "arith_operand" "rI")))
4922 (set (match_operand:DI 0 "register_operand" "=r")
4923 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4925 "xnorcc\t%r1, %2, %0"
4926 [(set_attr "type" "compare")])
4928 (define_insn "*cmp_cc_arith_op_not"
4929 [(set (reg:CC CC_REG)
4931 (match_operator:SI 2 "cc_arith_not_operator"
4932 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4933 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
4936 "%B2cc\t%r1, %0, %%g0"
4937 [(set_attr "type" "compare")])
4939 (define_insn "*cmp_ccx_arith_op_not"
4940 [(set (reg:CCX CC_REG)
4942 (match_operator:DI 2 "cc_arith_not_operator"
4943 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
4944 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
4947 "%B2cc\t%r1, %0, %%g0"
4948 [(set_attr "type" "compare")])
4950 (define_insn "*cmp_cc_arith_op_not_set"
4951 [(set (reg:CC CC_REG)
4953 (match_operator:SI 3 "cc_arith_not_operator"
4954 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
4955 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
4957 (set (match_operand:SI 0 "register_operand" "=r")
4958 (match_operator:SI 4 "cc_arith_not_operator"
4959 [(not:SI (match_dup 1)) (match_dup 2)]))]
4960 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4961 "%B3cc\t%r2, %1, %0"
4962 [(set_attr "type" "compare")])
4964 (define_insn "*cmp_ccx_arith_op_not_set"
4965 [(set (reg:CCX CC_REG)
4967 (match_operator:DI 3 "cc_arith_not_operator"
4968 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
4969 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
4971 (set (match_operand:DI 0 "register_operand" "=r")
4972 (match_operator:DI 4 "cc_arith_not_operator"
4973 [(not:DI (match_dup 1)) (match_dup 2)]))]
4974 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4975 "%B3cc\t%r2, %1, %0"
4976 [(set_attr "type" "compare")])
4978 ;; We cannot use the "neg" pseudo insn because the Sun assembler
4979 ;; does not know how to make it work for constants.
4981 (define_expand "negdi2"
4982 [(set (match_operand:DI 0 "register_operand" "=r")
4983 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4986 if (! TARGET_ARCH64)
4988 emit_insn (gen_rtx_PARALLEL
4991 gen_rtx_SET (VOIDmode, operand0,
4992 gen_rtx_NEG (DImode, operand1)),
4993 gen_rtx_CLOBBER (VOIDmode,
4994 gen_rtx_REG (CCmode,
5000 (define_insn_and_split "*negdi2_sp32"
5001 [(set (match_operand:DI 0 "register_operand" "=r")
5002 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5003 (clobber (reg:CC CC_REG))]
5006 "&& reload_completed"
5007 [(parallel [(set (reg:CC_NOOV CC_REG)
5008 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5010 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5011 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5012 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5013 "operands[2] = gen_highpart (SImode, operands[0]);
5014 operands[3] = gen_highpart (SImode, operands[1]);
5015 operands[4] = gen_lowpart (SImode, operands[0]);
5016 operands[5] = gen_lowpart (SImode, operands[1]);"
5017 [(set_attr "length" "2")])
5019 (define_insn "*negdi2_sp64"
5020 [(set (match_operand:DI 0 "register_operand" "=r")
5021 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5023 "sub\t%%g0, %1, %0")
5025 (define_insn "negsi2"
5026 [(set (match_operand:SI 0 "register_operand" "=r")
5027 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5029 "sub\t%%g0, %1, %0")
5031 (define_insn "*cmp_cc_neg"
5032 [(set (reg:CC_NOOV CC_REG)
5033 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5036 "subcc\t%%g0, %0, %%g0"
5037 [(set_attr "type" "compare")])
5039 (define_insn "*cmp_ccx_neg"
5040 [(set (reg:CCX_NOOV CC_REG)
5041 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5044 "subcc\t%%g0, %0, %%g0"
5045 [(set_attr "type" "compare")])
5047 (define_insn "*cmp_cc_set_neg"
5048 [(set (reg:CC_NOOV CC_REG)
5049 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5051 (set (match_operand:SI 0 "register_operand" "=r")
5052 (neg:SI (match_dup 1)))]
5054 "subcc\t%%g0, %1, %0"
5055 [(set_attr "type" "compare")])
5057 (define_insn "*cmp_ccx_set_neg"
5058 [(set (reg:CCX_NOOV CC_REG)
5059 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5061 (set (match_operand:DI 0 "register_operand" "=r")
5062 (neg:DI (match_dup 1)))]
5064 "subcc\t%%g0, %1, %0"
5065 [(set_attr "type" "compare")])
5067 ;; We cannot use the "not" pseudo insn because the Sun assembler
5068 ;; does not know how to make it work for constants.
5069 (define_expand "one_cmpldi2"
5070 [(set (match_operand:DI 0 "register_operand" "")
5071 (not:DI (match_operand:DI 1 "register_operand" "")))]
5075 (define_insn_and_split "*one_cmpldi2_sp32"
5076 [(set (match_operand:DI 0 "register_operand" "=r")
5077 (not:DI (match_operand:DI 1 "register_operand" "r")))]
5080 "&& reload_completed
5081 && ((GET_CODE (operands[0]) == REG
5082 && SPARC_INT_REG_P (REGNO (operands[0])))
5083 || (GET_CODE (operands[0]) == SUBREG
5084 && GET_CODE (SUBREG_REG (operands[0])) == REG
5085 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
5086 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5087 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5088 "operands[2] = gen_highpart (SImode, operands[0]);
5089 operands[3] = gen_highpart (SImode, operands[1]);
5090 operands[4] = gen_lowpart (SImode, operands[0]);
5091 operands[5] = gen_lowpart (SImode, operands[1]);"
5092 [(set_attr "length" "2")])
5094 (define_insn "*one_cmpldi2_sp64"
5095 [(set (match_operand:DI 0 "register_operand" "=r")
5096 (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5098 "xnor\t%%g0, %1, %0")
5100 (define_insn "one_cmplsi2"
5101 [(set (match_operand:SI 0 "register_operand" "=r")
5102 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5104 "xnor\t%%g0, %1, %0")
5106 (define_insn "*cmp_cc_not"
5107 [(set (reg:CC CC_REG)
5108 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5111 "xnorcc\t%%g0, %0, %%g0"
5112 [(set_attr "type" "compare")])
5114 (define_insn "*cmp_ccx_not"
5115 [(set (reg:CCX CC_REG)
5116 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5119 "xnorcc\t%%g0, %0, %%g0"
5120 [(set_attr "type" "compare")])
5122 (define_insn "*cmp_cc_set_not"
5123 [(set (reg:CC CC_REG)
5124 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5126 (set (match_operand:SI 0 "register_operand" "=r")
5127 (not:SI (match_dup 1)))]
5129 "xnorcc\t%%g0, %1, %0"
5130 [(set_attr "type" "compare")])
5132 (define_insn "*cmp_ccx_set_not"
5133 [(set (reg:CCX CC_REG)
5134 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5136 (set (match_operand:DI 0 "register_operand" "=r")
5137 (not:DI (match_dup 1)))]
5139 "xnorcc\t%%g0, %1, %0"
5140 [(set_attr "type" "compare")])
5142 (define_insn "*cmp_cc_set"
5143 [(set (match_operand:SI 0 "register_operand" "=r")
5144 (match_operand:SI 1 "register_operand" "r"))
5145 (set (reg:CC CC_REG)
5146 (compare:CC (match_dup 1)
5150 [(set_attr "type" "compare")])
5152 (define_insn "*cmp_ccx_set64"
5153 [(set (match_operand:DI 0 "register_operand" "=r")
5154 (match_operand:DI 1 "register_operand" "r"))
5155 (set (reg:CCX CC_REG)
5156 (compare:CCX (match_dup 1)
5160 [(set_attr "type" "compare")])
5163 ;; Floating point arithmetic instructions.
5165 (define_expand "addtf3"
5166 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5167 (plus:TF (match_operand:TF 1 "general_operand" "")
5168 (match_operand:TF 2 "general_operand" "")))]
5169 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5170 "emit_tfmode_binop (PLUS, operands); DONE;")
5172 (define_insn "*addtf3_hq"
5173 [(set (match_operand:TF 0 "register_operand" "=e")
5174 (plus:TF (match_operand:TF 1 "register_operand" "e")
5175 (match_operand:TF 2 "register_operand" "e")))]
5176 "TARGET_FPU && TARGET_HARD_QUAD"
5178 [(set_attr "type" "fp")])
5180 (define_insn "adddf3"
5181 [(set (match_operand:DF 0 "register_operand" "=e")
5182 (plus:DF (match_operand:DF 1 "register_operand" "e")
5183 (match_operand:DF 2 "register_operand" "e")))]
5186 [(set_attr "type" "fp")
5187 (set_attr "fptype" "double")])
5189 (define_insn "addsf3"
5190 [(set (match_operand:SF 0 "register_operand" "=f")
5191 (plus:SF (match_operand:SF 1 "register_operand" "f")
5192 (match_operand:SF 2 "register_operand" "f")))]
5195 [(set_attr "type" "fp")])
5197 (define_expand "subtf3"
5198 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5199 (minus:TF (match_operand:TF 1 "general_operand" "")
5200 (match_operand:TF 2 "general_operand" "")))]
5201 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5202 "emit_tfmode_binop (MINUS, operands); DONE;")
5204 (define_insn "*subtf3_hq"
5205 [(set (match_operand:TF 0 "register_operand" "=e")
5206 (minus:TF (match_operand:TF 1 "register_operand" "e")
5207 (match_operand:TF 2 "register_operand" "e")))]
5208 "TARGET_FPU && TARGET_HARD_QUAD"
5210 [(set_attr "type" "fp")])
5212 (define_insn "subdf3"
5213 [(set (match_operand:DF 0 "register_operand" "=e")
5214 (minus:DF (match_operand:DF 1 "register_operand" "e")
5215 (match_operand:DF 2 "register_operand" "e")))]
5218 [(set_attr "type" "fp")
5219 (set_attr "fptype" "double")])
5221 (define_insn "subsf3"
5222 [(set (match_operand:SF 0 "register_operand" "=f")
5223 (minus:SF (match_operand:SF 1 "register_operand" "f")
5224 (match_operand:SF 2 "register_operand" "f")))]
5227 [(set_attr "type" "fp")])
5229 (define_expand "multf3"
5230 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5231 (mult:TF (match_operand:TF 1 "general_operand" "")
5232 (match_operand:TF 2 "general_operand" "")))]
5233 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5234 "emit_tfmode_binop (MULT, operands); DONE;")
5236 (define_insn "*multf3_hq"
5237 [(set (match_operand:TF 0 "register_operand" "=e")
5238 (mult:TF (match_operand:TF 1 "register_operand" "e")
5239 (match_operand:TF 2 "register_operand" "e")))]
5240 "TARGET_FPU && TARGET_HARD_QUAD"
5242 [(set_attr "type" "fpmul")])
5244 (define_insn "muldf3"
5245 [(set (match_operand:DF 0 "register_operand" "=e")
5246 (mult:DF (match_operand:DF 1 "register_operand" "e")
5247 (match_operand:DF 2 "register_operand" "e")))]
5250 [(set_attr "type" "fpmul")
5251 (set_attr "fptype" "double")])
5253 (define_insn "mulsf3"
5254 [(set (match_operand:SF 0 "register_operand" "=f")
5255 (mult:SF (match_operand:SF 1 "register_operand" "f")
5256 (match_operand:SF 2 "register_operand" "f")))]
5259 [(set_attr "type" "fpmul")])
5261 (define_insn "fmadf4"
5262 [(set (match_operand:DF 0 "register_operand" "=e")
5263 (fma:DF (match_operand:DF 1 "register_operand" "e")
5264 (match_operand:DF 2 "register_operand" "e")
5265 (match_operand:DF 3 "register_operand" "e")))]
5267 "fmaddd\t%1, %2, %3, %0"
5268 [(set_attr "type" "fpmul")])
5270 (define_insn "fmsdf4"
5271 [(set (match_operand:DF 0 "register_operand" "=e")
5272 (fma:DF (match_operand:DF 1 "register_operand" "e")
5273 (match_operand:DF 2 "register_operand" "e")
5274 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5276 "fmsubd\t%1, %2, %3, %0"
5277 [(set_attr "type" "fpmul")])
5279 (define_insn "*nfmadf4"
5280 [(set (match_operand:DF 0 "register_operand" "=e")
5281 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5282 (match_operand:DF 2 "register_operand" "e")
5283 (match_operand:DF 3 "register_operand" "e"))))]
5285 "fnmaddd\t%1, %2, %3, %0"
5286 [(set_attr "type" "fpmul")])
5288 (define_insn "*nfmsdf4"
5289 [(set (match_operand:DF 0 "register_operand" "=e")
5290 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5291 (match_operand:DF 2 "register_operand" "e")
5292 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5294 "fnmsubd\t%1, %2, %3, %0"
5295 [(set_attr "type" "fpmul")])
5297 (define_insn "fmasf4"
5298 [(set (match_operand:SF 0 "register_operand" "=f")
5299 (fma:SF (match_operand:SF 1 "register_operand" "f")
5300 (match_operand:SF 2 "register_operand" "f")
5301 (match_operand:SF 3 "register_operand" "f")))]
5303 "fmadds\t%1, %2, %3, %0"
5304 [(set_attr "type" "fpmul")])
5306 (define_insn "fmssf4"
5307 [(set (match_operand:SF 0 "register_operand" "=f")
5308 (fma:SF (match_operand:SF 1 "register_operand" "f")
5309 (match_operand:SF 2 "register_operand" "f")
5310 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5312 "fmsubs\t%1, %2, %3, %0"
5313 [(set_attr "type" "fpmul")])
5315 (define_insn "*nfmasf4"
5316 [(set (match_operand:SF 0 "register_operand" "=f")
5317 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5318 (match_operand:SF 2 "register_operand" "f")
5319 (match_operand:SF 3 "register_operand" "f"))))]
5321 "fnmadds\t%1, %2, %3, %0"
5322 [(set_attr "type" "fpmul")])
5324 (define_insn "*nfmssf4"
5325 [(set (match_operand:SF 0 "register_operand" "=f")
5326 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5327 (match_operand:SF 2 "register_operand" "f")
5328 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5330 "fnmsubs\t%1, %2, %3, %0"
5331 [(set_attr "type" "fpmul")])
5333 (define_insn "*muldf3_extend"
5334 [(set (match_operand:DF 0 "register_operand" "=e")
5335 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5336 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5337 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5338 "fsmuld\t%1, %2, %0"
5339 [(set_attr "type" "fpmul")
5340 (set_attr "fptype" "double")])
5342 (define_insn "*multf3_extend"
5343 [(set (match_operand:TF 0 "register_operand" "=e")
5344 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5345 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5346 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5347 "fdmulq\t%1, %2, %0"
5348 [(set_attr "type" "fpmul")])
5350 (define_expand "divtf3"
5351 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5352 (div:TF (match_operand:TF 1 "general_operand" "")
5353 (match_operand:TF 2 "general_operand" "")))]
5354 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5355 "emit_tfmode_binop (DIV, operands); DONE;")
5357 ;; don't have timing for quad-prec. divide.
5358 (define_insn "*divtf3_hq"
5359 [(set (match_operand:TF 0 "register_operand" "=e")
5360 (div:TF (match_operand:TF 1 "register_operand" "e")
5361 (match_operand:TF 2 "register_operand" "e")))]
5362 "TARGET_FPU && TARGET_HARD_QUAD"
5364 [(set_attr "type" "fpdivd")])
5366 (define_insn "divdf3"
5367 [(set (match_operand:DF 0 "register_operand" "=e")
5368 (div:DF (match_operand:DF 1 "register_operand" "e")
5369 (match_operand:DF 2 "register_operand" "e")))]
5372 [(set_attr "type" "fpdivd")
5373 (set_attr "fptype" "double")])
5375 (define_insn "divsf3"
5376 [(set (match_operand:SF 0 "register_operand" "=f")
5377 (div:SF (match_operand:SF 1 "register_operand" "f")
5378 (match_operand:SF 2 "register_operand" "f")))]
5381 [(set_attr "type" "fpdivs")])
5383 (define_expand "negtf2"
5384 [(set (match_operand:TF 0 "register_operand" "=e,e")
5385 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5389 (define_insn_and_split "*negtf2_notv9"
5390 [(set (match_operand:TF 0 "register_operand" "=e,e")
5391 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5392 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5398 "&& reload_completed
5399 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5400 [(set (match_dup 2) (neg:SF (match_dup 3)))
5401 (set (match_dup 4) (match_dup 5))
5402 (set (match_dup 6) (match_dup 7))]
5403 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5404 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5405 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5406 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5407 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5408 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5409 [(set_attr "type" "fpmove,*")
5410 (set_attr "length" "*,2")])
5412 (define_insn_and_split "*negtf2_v9"
5413 [(set (match_operand:TF 0 "register_operand" "=e,e")
5414 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5415 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5416 "TARGET_FPU && TARGET_V9"
5420 "&& reload_completed
5421 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5422 [(set (match_dup 2) (neg:DF (match_dup 3)))
5423 (set (match_dup 4) (match_dup 5))]
5424 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5425 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5426 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5427 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5428 [(set_attr "type" "fpmove,*")
5429 (set_attr "length" "*,2")
5430 (set_attr "fptype" "double")])
5432 (define_expand "negdf2"
5433 [(set (match_operand:DF 0 "register_operand" "")
5434 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5438 (define_insn_and_split "*negdf2_notv9"
5439 [(set (match_operand:DF 0 "register_operand" "=e,e")
5440 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5441 "TARGET_FPU && ! TARGET_V9"
5445 "&& reload_completed
5446 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5447 [(set (match_dup 2) (neg:SF (match_dup 3)))
5448 (set (match_dup 4) (match_dup 5))]
5449 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5450 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5451 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5452 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5453 [(set_attr "type" "fpmove,*")
5454 (set_attr "length" "*,2")])
5456 (define_insn "*negdf2_v9"
5457 [(set (match_operand:DF 0 "register_operand" "=e")
5458 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5459 "TARGET_FPU && TARGET_V9"
5461 [(set_attr "type" "fpmove")
5462 (set_attr "fptype" "double")])
5464 (define_insn "negsf2"
5465 [(set (match_operand:SF 0 "register_operand" "=f")
5466 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5469 [(set_attr "type" "fpmove")])
5471 (define_expand "abstf2"
5472 [(set (match_operand:TF 0 "register_operand" "")
5473 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5477 (define_insn_and_split "*abstf2_notv9"
5478 [(set (match_operand:TF 0 "register_operand" "=e,e")
5479 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5480 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5481 "TARGET_FPU && ! TARGET_V9"
5485 "&& reload_completed
5486 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5487 [(set (match_dup 2) (abs:SF (match_dup 3)))
5488 (set (match_dup 4) (match_dup 5))
5489 (set (match_dup 6) (match_dup 7))]
5490 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5491 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5492 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5493 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5494 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5495 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5496 [(set_attr "type" "fpmove,*")
5497 (set_attr "length" "*,2")])
5499 (define_insn "*abstf2_hq_v9"
5500 [(set (match_operand:TF 0 "register_operand" "=e,e")
5501 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5502 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5506 [(set_attr "type" "fpmove")
5507 (set_attr "fptype" "double,*")])
5509 (define_insn_and_split "*abstf2_v9"
5510 [(set (match_operand:TF 0 "register_operand" "=e,e")
5511 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5512 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5516 "&& reload_completed
5517 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5518 [(set (match_dup 2) (abs:DF (match_dup 3)))
5519 (set (match_dup 4) (match_dup 5))]
5520 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5521 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5522 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5523 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5524 [(set_attr "type" "fpmove,*")
5525 (set_attr "length" "*,2")
5526 (set_attr "fptype" "double,*")])
5528 (define_expand "absdf2"
5529 [(set (match_operand:DF 0 "register_operand" "")
5530 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5534 (define_insn_and_split "*absdf2_notv9"
5535 [(set (match_operand:DF 0 "register_operand" "=e,e")
5536 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5537 "TARGET_FPU && ! TARGET_V9"
5541 "&& reload_completed
5542 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5543 [(set (match_dup 2) (abs:SF (match_dup 3)))
5544 (set (match_dup 4) (match_dup 5))]
5545 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5546 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5547 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5548 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5549 [(set_attr "type" "fpmove,*")
5550 (set_attr "length" "*,2")])
5552 (define_insn "*absdf2_v9"
5553 [(set (match_operand:DF 0 "register_operand" "=e")
5554 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5555 "TARGET_FPU && TARGET_V9"
5557 [(set_attr "type" "fpmove")
5558 (set_attr "fptype" "double")])
5560 (define_insn "abssf2"
5561 [(set (match_operand:SF 0 "register_operand" "=f")
5562 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5565 [(set_attr "type" "fpmove")])
5567 (define_expand "sqrttf2"
5568 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5569 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5570 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5571 "emit_tfmode_unop (SQRT, operands); DONE;")
5573 (define_insn "*sqrttf2_hq"
5574 [(set (match_operand:TF 0 "register_operand" "=e")
5575 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5576 "TARGET_FPU && TARGET_HARD_QUAD"
5578 [(set_attr "type" "fpsqrtd")])
5580 (define_insn "sqrtdf2"
5581 [(set (match_operand:DF 0 "register_operand" "=e")
5582 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5585 [(set_attr "type" "fpsqrtd")
5586 (set_attr "fptype" "double")])
5588 (define_insn "sqrtsf2"
5589 [(set (match_operand:SF 0 "register_operand" "=f")
5590 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5593 [(set_attr "type" "fpsqrts")])
5596 ;; Arithmetic shift instructions.
5598 (define_insn "ashlsi3"
5599 [(set (match_operand:SI 0 "register_operand" "=r")
5600 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5601 (match_operand:SI 2 "arith_operand" "rI")))]
5604 if (GET_CODE (operands[2]) == CONST_INT)
5605 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5606 return "sll\t%1, %2, %0";
5608 [(set_attr "type" "shift")])
5610 (define_insn "*ashlsi3_extend"
5611 [(set (match_operand:DI 0 "register_operand" "=r")
5613 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5614 (match_operand:SI 2 "arith_operand" "rI"))))]
5617 if (GET_CODE (operands[2]) == CONST_INT)
5618 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5619 return "sll\t%1, %2, %0";
5621 [(set_attr "type" "shift")])
5623 (define_expand "ashldi3"
5624 [(set (match_operand:DI 0 "register_operand" "=r")
5625 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5626 (match_operand:SI 2 "arith_operand" "rI")))]
5627 "TARGET_ARCH64 || TARGET_V8PLUS"
5629 if (! TARGET_ARCH64)
5631 if (GET_CODE (operands[2]) == CONST_INT)
5633 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5638 (define_insn "*ashldi3_sp64"
5639 [(set (match_operand:DI 0 "register_operand" "=r")
5640 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5641 (match_operand:SI 2 "arith_operand" "rI")))]
5644 if (GET_CODE (operands[2]) == CONST_INT)
5645 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5646 return "sllx\t%1, %2, %0";
5648 [(set_attr "type" "shift")])
5651 (define_insn "ashldi3_v8plus"
5652 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5653 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5654 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5655 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5657 "* return output_v8plus_shift (insn ,operands, \"sllx\");"
5658 [(set_attr "type" "multi")
5659 (set_attr "length" "5,5,6")])
5661 ;; Optimize (1LL<<x)-1
5662 ;; XXX this also needs to be fixed to handle equal subregs
5663 ;; XXX first before we could re-enable it.
5665 ; [(set (match_operand:DI 0 "register_operand" "=h")
5666 ; (plus:DI (ashift:DI (const_int 1)
5667 ; (match_operand:SI 1 "arith_operand" "rI"))
5669 ; "0 && TARGET_V8PLUS"
5671 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5672 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5673 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5675 ; [(set_attr "type" "multi")
5676 ; (set_attr "length" "4")])
5678 (define_insn "*cmp_cc_ashift_1"
5679 [(set (reg:CC_NOOV CC_REG)
5680 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5684 "addcc\t%0, %0, %%g0"
5685 [(set_attr "type" "compare")])
5687 (define_insn "*cmp_cc_set_ashift_1"
5688 [(set (reg:CC_NOOV CC_REG)
5689 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5692 (set (match_operand:SI 0 "register_operand" "=r")
5693 (ashift:SI (match_dup 1) (const_int 1)))]
5696 [(set_attr "type" "compare")])
5698 (define_insn "ashrsi3"
5699 [(set (match_operand:SI 0 "register_operand" "=r")
5700 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5701 (match_operand:SI 2 "arith_operand" "rI")))]
5704 if (GET_CODE (operands[2]) == CONST_INT)
5705 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5706 return "sra\t%1, %2, %0";
5708 [(set_attr "type" "shift")])
5710 (define_insn "*ashrsi3_extend"
5711 [(set (match_operand:DI 0 "register_operand" "=r")
5712 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5713 (match_operand:SI 2 "arith_operand" "r"))))]
5716 [(set_attr "type" "shift")])
5718 ;; This handles the case as above, but with constant shift instead of
5719 ;; register. Combiner "simplifies" it for us a little bit though.
5720 (define_insn "*ashrsi3_extend2"
5721 [(set (match_operand:DI 0 "register_operand" "=r")
5722 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5724 (match_operand:SI 2 "small_int_operand" "I")))]
5725 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5727 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5728 return "sra\t%1, %2, %0";
5730 [(set_attr "type" "shift")])
5732 (define_expand "ashrdi3"
5733 [(set (match_operand:DI 0 "register_operand" "=r")
5734 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5735 (match_operand:SI 2 "arith_operand" "rI")))]
5736 "TARGET_ARCH64 || TARGET_V8PLUS"
5738 if (! TARGET_ARCH64)
5740 if (GET_CODE (operands[2]) == CONST_INT)
5741 FAIL; /* prefer generic code in this case */
5742 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5747 (define_insn "*ashrdi3_sp64"
5748 [(set (match_operand:DI 0 "register_operand" "=r")
5749 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5750 (match_operand:SI 2 "arith_operand" "rI")))]
5754 if (GET_CODE (operands[2]) == CONST_INT)
5755 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5756 return "srax\t%1, %2, %0";
5758 [(set_attr "type" "shift")])
5761 (define_insn "ashrdi3_v8plus"
5762 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5763 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5764 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5765 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5767 "* return output_v8plus_shift (insn, operands, \"srax\");"
5768 [(set_attr "type" "multi")
5769 (set_attr "length" "5,5,6")])
5771 (define_insn "lshrsi3"
5772 [(set (match_operand:SI 0 "register_operand" "=r")
5773 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5774 (match_operand:SI 2 "arith_operand" "rI")))]
5777 if (GET_CODE (operands[2]) == CONST_INT)
5778 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5779 return "srl\t%1, %2, %0";
5781 [(set_attr "type" "shift")])
5783 (define_insn "*lshrsi3_extend0"
5784 [(set (match_operand:DI 0 "register_operand" "=r")
5786 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5787 (match_operand:SI 2 "arith_operand" "rI"))))]
5790 if (GET_CODE (operands[2]) == CONST_INT)
5791 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5792 return "srl\t%1, %2, %0";
5794 [(set_attr "type" "shift")])
5796 ;; This handles the case where
5797 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5798 ;; but combiner "simplifies" it for us.
5799 (define_insn "*lshrsi3_extend1"
5800 [(set (match_operand:DI 0 "register_operand" "=r")
5801 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5802 (match_operand:SI 2 "arith_operand" "r")) 0)
5803 (match_operand 3 "const_int_operand" "")))]
5804 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5806 [(set_attr "type" "shift")])
5808 ;; This handles the case where
5809 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5810 ;; but combiner "simplifies" it for us.
5811 (define_insn "*lshrsi3_extend2"
5812 [(set (match_operand:DI 0 "register_operand" "=r")
5813 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5814 (match_operand 2 "small_int_operand" "I")
5816 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5818 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5819 return "srl\t%1, %2, %0";
5821 [(set_attr "type" "shift")])
5823 (define_expand "lshrdi3"
5824 [(set (match_operand:DI 0 "register_operand" "=r")
5825 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5826 (match_operand:SI 2 "arith_operand" "rI")))]
5827 "TARGET_ARCH64 || TARGET_V8PLUS"
5829 if (! TARGET_ARCH64)
5831 if (GET_CODE (operands[2]) == CONST_INT)
5833 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5838 (define_insn "*lshrdi3_sp64"
5839 [(set (match_operand:DI 0 "register_operand" "=r")
5840 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5841 (match_operand:SI 2 "arith_operand" "rI")))]
5844 if (GET_CODE (operands[2]) == CONST_INT)
5845 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5846 return "srlx\t%1, %2, %0";
5848 [(set_attr "type" "shift")])
5851 (define_insn "lshrdi3_v8plus"
5852 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5853 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5854 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5855 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5857 "* return output_v8plus_shift (insn, operands, \"srlx\");"
5858 [(set_attr "type" "multi")
5859 (set_attr "length" "5,5,6")])
5862 [(set (match_operand:SI 0 "register_operand" "=r")
5863 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5865 (match_operand:SI 2 "small_int_operand" "I")))]
5866 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5868 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5869 return "srax\t%1, %2, %0";
5871 [(set_attr "type" "shift")])
5874 [(set (match_operand:SI 0 "register_operand" "=r")
5875 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5877 (match_operand:SI 2 "small_int_operand" "I")))]
5878 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5880 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5881 return "srlx\t%1, %2, %0";
5883 [(set_attr "type" "shift")])
5886 [(set (match_operand:SI 0 "register_operand" "=r")
5887 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5888 (match_operand:SI 2 "small_int_operand" "I")) 4)
5889 (match_operand:SI 3 "small_int_operand" "I")))]
5891 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5892 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5893 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5895 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5897 return "srax\t%1, %2, %0";
5899 [(set_attr "type" "shift")])
5902 [(set (match_operand:SI 0 "register_operand" "=r")
5903 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5904 (match_operand:SI 2 "small_int_operand" "I")) 4)
5905 (match_operand:SI 3 "small_int_operand" "I")))]
5907 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5908 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5909 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5911 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5913 return "srlx\t%1, %2, %0";
5915 [(set_attr "type" "shift")])
5918 ;; Unconditional and other jump instructions.
5921 [(set (pc) (label_ref (match_operand 0 "" "")))]
5923 "* return output_ubranch (operands[0], 0, insn);"
5924 [(set_attr "type" "uncond_branch")])
5926 (define_expand "tablejump"
5927 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5928 (use (label_ref (match_operand 1 "" "")))])]
5931 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5933 /* In pic mode, our address differences are against the base of the
5934 table. Add that base value back in; CSE ought to be able to combine
5935 the two address loads. */
5939 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5941 if (CASE_VECTOR_MODE != Pmode)
5942 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5943 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5944 operands[0] = memory_address (Pmode, tmp);
5948 (define_insn "*tablejump_sp32"
5949 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5950 (use (label_ref (match_operand 1 "" "")))]
5953 [(set_attr "type" "uncond_branch")])
5955 (define_insn "*tablejump_sp64"
5956 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5957 (use (label_ref (match_operand 1 "" "")))]
5960 [(set_attr "type" "uncond_branch")])
5963 ;; Jump to subroutine instructions.
5965 (define_expand "call"
5966 ;; Note that this expression is not used for generating RTL.
5967 ;; All the RTL is generated explicitly below.
5968 [(call (match_operand 0 "call_operand" "")
5969 (match_operand 3 "" "i"))]
5970 ;; operands[2] is next_arg_register
5971 ;; operands[3] is struct_value_size_rtx.
5976 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5978 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5980 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5982 /* This is really a PIC sequence. We want to represent
5983 it as a funny jump so its delay slots can be filled.
5985 ??? But if this really *is* a CALL, will not it clobber the
5986 call-clobbered registers? We lose this if it is a JUMP_INSN.
5987 Why cannot we have delay slots filled if it were a CALL? */
5989 /* We accept negative sizes for untyped calls. */
5990 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5995 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5997 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6003 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6004 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6008 fn_rtx = operands[0];
6010 /* We accept negative sizes for untyped calls. */
6011 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6012 sparc_emit_call_insn
6015 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6017 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6020 sparc_emit_call_insn
6023 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6024 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6032 ;; We can't use the same pattern for these two insns, because then registers
6033 ;; in the address may not be properly reloaded.
6035 (define_insn "*call_address_sp32"
6036 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6037 (match_operand 1 "" ""))
6038 (clobber (reg:SI O7_REG))]
6039 ;;- Do not use operand 1 for most machines.
6042 [(set_attr "type" "call")])
6044 (define_insn "*call_symbolic_sp32"
6045 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6046 (match_operand 1 "" ""))
6047 (clobber (reg:SI O7_REG))]
6048 ;;- Do not use operand 1 for most machines.
6051 [(set_attr "type" "call")])
6053 (define_insn "*call_address_sp64"
6054 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6055 (match_operand 1 "" ""))
6056 (clobber (reg:DI O7_REG))]
6057 ;;- Do not use operand 1 for most machines.
6060 [(set_attr "type" "call")])
6062 (define_insn "*call_symbolic_sp64"
6063 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6064 (match_operand 1 "" ""))
6065 (clobber (reg:DI O7_REG))]
6066 ;;- Do not use operand 1 for most machines.
6069 [(set_attr "type" "call")])
6071 ;; This is a call that wants a structure value.
6072 ;; There is no such critter for v9 (??? we may need one anyway).
6073 (define_insn "*call_address_struct_value_sp32"
6074 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6075 (match_operand 1 "" ""))
6076 (match_operand 2 "immediate_operand" "")
6077 (clobber (reg:SI O7_REG))]
6078 ;;- Do not use operand 1 for most machines.
6079 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6081 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6082 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6084 [(set_attr "type" "call_no_delay_slot")
6085 (set_attr "length" "3")])
6087 ;; This is a call that wants a structure value.
6088 ;; There is no such critter for v9 (??? we may need one anyway).
6089 (define_insn "*call_symbolic_struct_value_sp32"
6090 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6091 (match_operand 1 "" ""))
6092 (match_operand 2 "immediate_operand" "")
6093 (clobber (reg:SI O7_REG))]
6094 ;;- Do not use operand 1 for most machines.
6095 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6097 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6098 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6100 [(set_attr "type" "call_no_delay_slot")
6101 (set_attr "length" "3")])
6103 ;; This is a call that may want a structure value. This is used for
6105 (define_insn "*call_address_untyped_struct_value_sp32"
6106 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6107 (match_operand 1 "" ""))
6108 (match_operand 2 "immediate_operand" "")
6109 (clobber (reg:SI O7_REG))]
6110 ;;- Do not use operand 1 for most machines.
6111 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6112 "call\t%a0, %1\n\t nop\n\tnop"
6113 [(set_attr "type" "call_no_delay_slot")
6114 (set_attr "length" "3")])
6116 ;; This is a call that may want a structure value. This is used for
6118 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6119 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6120 (match_operand 1 "" ""))
6121 (match_operand 2 "immediate_operand" "")
6122 (clobber (reg:SI O7_REG))]
6123 ;;- Do not use operand 1 for most machines.
6124 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6125 "call\t%a0, %1\n\t nop\n\tnop"
6126 [(set_attr "type" "call_no_delay_slot")
6127 (set_attr "length" "3")])
6129 (define_expand "call_value"
6130 ;; Note that this expression is not used for generating RTL.
6131 ;; All the RTL is generated explicitly below.
6132 [(set (match_operand 0 "register_operand" "=rf")
6133 (call (match_operand 1 "" "")
6134 (match_operand 4 "" "")))]
6135 ;; operand 2 is stack_size_rtx
6136 ;; operand 3 is next_arg_register
6142 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6144 fn_rtx = operands[1];
6147 gen_rtx_SET (VOIDmode, operands[0],
6148 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6149 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6151 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6156 (define_insn "*call_value_address_sp32"
6157 [(set (match_operand 0 "" "=rf")
6158 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6159 (match_operand 2 "" "")))
6160 (clobber (reg:SI O7_REG))]
6161 ;;- Do not use operand 2 for most machines.
6164 [(set_attr "type" "call")])
6166 (define_insn "*call_value_symbolic_sp32"
6167 [(set (match_operand 0 "" "=rf")
6168 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6169 (match_operand 2 "" "")))
6170 (clobber (reg:SI O7_REG))]
6171 ;;- Do not use operand 2 for most machines.
6174 [(set_attr "type" "call")])
6176 (define_insn "*call_value_address_sp64"
6177 [(set (match_operand 0 "" "")
6178 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6179 (match_operand 2 "" "")))
6180 (clobber (reg:DI O7_REG))]
6181 ;;- Do not use operand 2 for most machines.
6184 [(set_attr "type" "call")])
6186 (define_insn "*call_value_symbolic_sp64"
6187 [(set (match_operand 0 "" "")
6188 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6189 (match_operand 2 "" "")))
6190 (clobber (reg:DI O7_REG))]
6191 ;;- Do not use operand 2 for most machines.
6194 [(set_attr "type" "call")])
6196 (define_expand "untyped_call"
6197 [(parallel [(call (match_operand 0 "" "")
6199 (match_operand:BLK 1 "memory_operand" "")
6200 (match_operand 2 "" "")])]
6203 rtx valreg1 = gen_rtx_REG (DImode, 8);
6204 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6205 rtx result = operands[1];
6207 /* Pass constm1 to indicate that it may expect a structure value, but
6208 we don't know what size it is. */
6209 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6211 /* Save the function value registers. */
6212 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6213 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6216 /* The optimizer does not know that the call sets the function value
6217 registers we stored in the result block. We avoid problems by
6218 claiming that all hard registers are used and clobbered at this
6220 emit_insn (gen_blockage ());
6225 ;; Tail call instructions.
6227 (define_expand "sibcall"
6228 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6233 (define_insn "*sibcall_symbolic_sp32"
6234 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6235 (match_operand 1 "" ""))
6238 "* return output_sibcall(insn, operands[0]);"
6239 [(set_attr "type" "sibcall")])
6241 (define_insn "*sibcall_symbolic_sp64"
6242 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6243 (match_operand 1 "" ""))
6246 "* return output_sibcall(insn, operands[0]);"
6247 [(set_attr "type" "sibcall")])
6249 (define_expand "sibcall_value"
6250 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6251 (call (match_operand 1 "" "") (const_int 0)))
6256 (define_insn "*sibcall_value_symbolic_sp32"
6257 [(set (match_operand 0 "" "=rf")
6258 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6259 (match_operand 2 "" "")))
6262 "* return output_sibcall(insn, operands[1]);"
6263 [(set_attr "type" "sibcall")])
6265 (define_insn "*sibcall_value_symbolic_sp64"
6266 [(set (match_operand 0 "" "")
6267 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6268 (match_operand 2 "" "")))
6271 "* return output_sibcall(insn, operands[1]);"
6272 [(set_attr "type" "sibcall")])
6275 ;; Special instructions.
6277 (define_expand "prologue"
6282 sparc_flat_expand_prologue ();
6284 sparc_expand_prologue ();
6288 ;; The "register window save" insn is modelled as follows. The dwarf2
6289 ;; information is manually added in emit_window_save.
6291 (define_insn "window_save"
6293 [(match_operand 0 "arith_operand" "rI")]
6296 "save\t%%sp, %0, %%sp"
6297 [(set_attr "type" "savew")])
6299 (define_expand "epilogue"
6304 sparc_flat_expand_epilogue (false);
6306 sparc_expand_epilogue (false);
6309 (define_expand "sibcall_epilogue"
6314 sparc_flat_expand_epilogue (false);
6316 sparc_expand_epilogue (false);
6320 (define_expand "eh_return"
6321 [(use (match_operand 0 "general_operand" ""))]
6324 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6325 emit_jump_insn (gen_eh_return_internal ());
6330 (define_insn_and_split "eh_return_internal"
6334 "epilogue_completed"
6338 sparc_flat_expand_epilogue (true);
6340 sparc_expand_epilogue (true);
6343 (define_expand "return"
6345 "sparc_can_use_return_insn_p ()"
6348 (define_insn "*return_internal"
6351 "* return output_return (insn);"
6352 [(set_attr "type" "return")
6353 (set (attr "length")
6354 (cond [(eq_attr "calls_eh_return" "true")
6355 (if_then_else (eq_attr "delayed_branch" "true")
6356 (if_then_else (ior (eq_attr "isa" "v9")
6357 (eq_attr "flat" "true"))
6360 (if_then_else (eq_attr "flat" "true")
6363 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6364 (if_then_else (eq_attr "empty_delay_slot" "true")
6367 (eq_attr "empty_delay_slot" "true")
6368 (if_then_else (eq_attr "delayed_branch" "true")
6373 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6374 ;; all of memory. This blocks insns from being moved across this point.
6376 (define_insn "blockage"
6377 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6380 [(set_attr "length" "0")])
6382 ;; Do not schedule instructions accessing memory before this point.
6384 (define_expand "frame_blockage"
6386 (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
6389 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6390 MEM_VOLATILE_P (operands[0]) = 1;
6391 operands[1] = stack_pointer_rtx;
6394 (define_insn "*frame_blockage<P:mode>"
6395 [(set (match_operand:BLK 0 "" "")
6396 (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
6399 [(set_attr "length" "0")])
6401 (define_expand "probe_stack"
6402 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6406 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6409 (define_insn "probe_stack_range<P:mode>"
6410 [(set (match_operand:P 0 "register_operand" "=r")
6411 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6412 (match_operand:P 2 "register_operand" "r")]
6413 UNSPECV_PROBE_STACK_RANGE))]
6415 "* return output_probe_stack_range (operands[0], operands[2]);"
6416 [(set_attr "type" "multi")])
6418 ;; Prepare to return any type including a structure value.
6420 (define_expand "untyped_return"
6421 [(match_operand:BLK 0 "memory_operand" "")
6422 (match_operand 1 "" "")]
6425 rtx valreg1 = gen_rtx_REG (DImode, 24);
6426 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6427 rtx result = operands[0];
6429 if (! TARGET_ARCH64)
6431 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6432 rtx value = gen_reg_rtx (SImode);
6434 /* Fetch the instruction where we will return to and see if it's an unimp
6435 instruction (the most significant 10 bits will be zero). If so,
6436 update the return address to skip the unimp instruction. */
6437 emit_move_insn (value,
6438 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6439 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6440 emit_insn (gen_update_return (rtnreg, value));
6443 /* Reload the function value registers. */
6444 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6445 emit_move_insn (valreg2,
6446 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6448 /* Put USE insns before the return. */
6452 /* Construct the return. */
6453 expand_naked_return ();
6458 ;; Adjust the return address conditionally. If the value of op1 is equal
6459 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6460 ;; This is technically *half* the check required by the 32-bit SPARC
6461 ;; psABI. This check only ensures that an "unimp" insn was written by
6462 ;; the caller, but doesn't check to see if the expected size matches
6463 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6464 ;; only used by the above code "untyped_return".
6466 (define_insn "update_return"
6467 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6468 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6471 if (flag_delayed_branch)
6472 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6474 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6476 [(set (attr "type") (const_string "multi"))
6477 (set (attr "length")
6478 (if_then_else (eq_attr "delayed_branch" "true")
6487 (define_expand "indirect_jump"
6488 [(set (pc) (match_operand 0 "address_operand" "p"))]
6492 (define_insn "*branch_sp32"
6493 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6496 [(set_attr "type" "uncond_branch")])
6498 (define_insn "*branch_sp64"
6499 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6502 [(set_attr "type" "uncond_branch")])
6504 (define_expand "save_stack_nonlocal"
6505 [(set (match_operand 0 "memory_operand" "")
6506 (match_operand 1 "register_operand" ""))
6507 (set (match_dup 2) (match_dup 3))]
6510 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6511 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6512 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6515 (define_expand "restore_stack_nonlocal"
6516 [(set (match_operand 0 "register_operand" "")
6517 (match_operand 1 "memory_operand" ""))]
6520 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6523 (define_expand "nonlocal_goto"
6524 [(match_operand 0 "general_operand" "")
6525 (match_operand 1 "general_operand" "")
6526 (match_operand 2 "memory_operand" "")
6527 (match_operand 3 "memory_operand" "")]
6530 rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6531 rtx r_label = copy_to_reg (operands[1]);
6532 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6533 rtx r_fp = operands[3];
6534 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6536 /* We need to flush all the register windows so that their contents will
6537 be re-synchronized by the restore insn of the target function. */
6539 emit_insn (gen_flush_register_windows ());
6541 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6542 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6544 /* Restore frame pointer for containing function. */
6545 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6546 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6547 emit_move_insn (i7, r_i7);
6549 /* USE of hard_frame_pointer_rtx added for consistency;
6550 not clear if really needed. */
6551 emit_use (hard_frame_pointer_rtx);
6552 emit_use (stack_pointer_rtx);
6555 emit_jump_insn (gen_indirect_jump (r_label));
6560 (define_expand "builtin_setjmp_receiver"
6561 [(label_ref (match_operand 0 "" ""))]
6564 load_got_register ();
6568 ;; Special insn to flush register windows.
6570 (define_insn "flush_register_windows"
6571 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6573 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6574 [(set_attr "type" "flushw")])
6576 ;; Special pattern for the FLUSH instruction.
6578 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6579 ; of the define_insn otherwise missing a mode. We make "flush", aka
6580 ; gen_flush, the default one since sparc_initialize_trampoline uses
6581 ; it on SImode mem values.
6583 (define_insn "flush"
6584 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6586 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6587 [(set_attr "type" "iflush")])
6589 (define_insn "flushdi"
6590 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6592 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6593 [(set_attr "type" "iflush")])
6596 ;; Find first set instructions.
6598 ;; The scan instruction searches from the most significant bit while ffs
6599 ;; searches from the least significant bit. The bit index and treatment of
6600 ;; zero also differ. It takes at least 7 instructions to get the proper
6601 ;; result. Here is an obvious 8 instruction sequence.
6604 (define_insn "ffssi2"
6605 [(set (match_operand:SI 0 "register_operand" "=&r")
6606 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6607 (clobber (match_scratch:SI 2 "=&r"))]
6608 "TARGET_SPARCLITE || TARGET_SPARCLET"
6610 return "sub\t%%g0, %1, %0\;and\t%0, %1, %0\;scan\t%0, 0, %0\;mov\t32, %2\;sub\t%2, %0, %0\;sra\t%0, 31, %2\;and\t%2, 31, %2\;add\t%2, %0, %0";
6612 [(set_attr "type" "multi")
6613 (set_attr "length" "8")])
6615 (define_expand "popcountdi2"
6616 [(set (match_operand:DI 0 "register_operand" "")
6617 (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6620 if (! TARGET_ARCH64)
6622 emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6627 (define_insn "*popcountdi_sp64"
6628 [(set (match_operand:DI 0 "register_operand" "=r")
6629 (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6630 "TARGET_POPC && TARGET_ARCH64"
6633 (define_insn "popcountdi_v8plus"
6634 [(set (match_operand:DI 0 "register_operand" "=r")
6635 (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6636 (clobber (match_scratch:SI 2 "=&h"))]
6637 "TARGET_POPC && ! TARGET_ARCH64"
6639 if (sparc_check_64 (operands[1], insn) <= 0)
6640 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6641 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6643 [(set_attr "type" "multi")
6644 (set_attr "length" "5")])
6646 (define_expand "popcountsi2"
6648 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6649 (set (match_operand:SI 0 "register_operand" "")
6650 (truncate:SI (popcount:DI (match_dup 2))))]
6653 if (! TARGET_ARCH64)
6655 emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6659 operands[2] = gen_reg_rtx (DImode);
6662 (define_insn "*popcountsi_sp64"
6663 [(set (match_operand:SI 0 "register_operand" "=r")
6665 (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6666 "TARGET_POPC && TARGET_ARCH64"
6669 (define_insn "popcountsi_v8plus"
6670 [(set (match_operand:SI 0 "register_operand" "=r")
6671 (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6672 "TARGET_POPC && ! TARGET_ARCH64"
6674 if (sparc_check_64 (operands[1], insn) <= 0)
6675 output_asm_insn ("srl\t%1, 0, %1", operands);
6676 return "popc\t%1, %0";
6678 [(set_attr "type" "multi")
6679 (set_attr "length" "2")])
6681 (define_expand "clzdi2"
6682 [(set (match_operand:DI 0 "register_operand" "")
6683 (clz:DI (match_operand:DI 1 "register_operand" "")))]
6686 if (! TARGET_ARCH64)
6688 emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6693 (define_insn "*clzdi_sp64"
6694 [(set (match_operand:DI 0 "register_operand" "=r")
6695 (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6696 "TARGET_VIS3 && TARGET_ARCH64"
6699 (define_insn "clzdi_v8plus"
6700 [(set (match_operand:DI 0 "register_operand" "=r")
6701 (clz:DI (match_operand:DI 1 "register_operand" "r")))
6702 (clobber (match_scratch:SI 2 "=&h"))]
6703 "TARGET_VIS3 && ! TARGET_ARCH64"
6705 if (sparc_check_64 (operands[1], insn) <= 0)
6706 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6707 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6709 [(set_attr "type" "multi")
6710 (set_attr "length" "5")])
6712 (define_expand "clzsi2"
6714 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6716 (truncate:SI (clz:DI (match_dup 2))))
6717 (set (match_operand:SI 0 "register_operand" "")
6718 (minus:SI (match_dup 3) (const_int 32)))]
6721 if (! TARGET_ARCH64)
6723 emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6728 operands[2] = gen_reg_rtx (DImode);
6729 operands[3] = gen_reg_rtx (SImode);
6733 (define_insn "*clzsi_sp64"
6734 [(set (match_operand:SI 0 "register_operand" "=r")
6736 (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6737 "TARGET_VIS3 && TARGET_ARCH64"
6740 (define_insn "clzsi_v8plus"
6741 [(set (match_operand:SI 0 "register_operand" "=r")
6742 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6743 "TARGET_VIS3 && ! TARGET_ARCH64"
6745 if (sparc_check_64 (operands[1], insn) <= 0)
6746 output_asm_insn ("srl\t%1, 0, %1", operands);
6747 return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6749 [(set_attr "type" "multi")
6750 (set_attr "length" "3")])
6753 ;; Peepholes go at the end.
6755 ;; Optimize consecutive loads or stores into ldd and std when possible.
6756 ;; The conditions in which we do this are very restricted and are
6757 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6760 [(set (match_operand:SI 0 "memory_operand" "")
6762 (set (match_operand:SI 1 "memory_operand" "")
6765 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6768 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6771 [(set (match_operand:SI 0 "memory_operand" "")
6773 (set (match_operand:SI 1 "memory_operand" "")
6776 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6779 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6782 [(set (match_operand:SI 0 "register_operand" "")
6783 (match_operand:SI 1 "memory_operand" ""))
6784 (set (match_operand:SI 2 "register_operand" "")
6785 (match_operand:SI 3 "memory_operand" ""))]
6786 "registers_ok_for_ldd_peep (operands[0], operands[2])
6787 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6790 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6791 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6794 [(set (match_operand:SI 0 "memory_operand" "")
6795 (match_operand:SI 1 "register_operand" ""))
6796 (set (match_operand:SI 2 "memory_operand" "")
6797 (match_operand:SI 3 "register_operand" ""))]
6798 "registers_ok_for_ldd_peep (operands[1], operands[3])
6799 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6802 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6803 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6806 [(set (match_operand:SF 0 "register_operand" "")
6807 (match_operand:SF 1 "memory_operand" ""))
6808 (set (match_operand:SF 2 "register_operand" "")
6809 (match_operand:SF 3 "memory_operand" ""))]
6810 "registers_ok_for_ldd_peep (operands[0], operands[2])
6811 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6814 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6815 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6818 [(set (match_operand:SF 0 "memory_operand" "")
6819 (match_operand:SF 1 "register_operand" ""))
6820 (set (match_operand:SF 2 "memory_operand" "")
6821 (match_operand:SF 3 "register_operand" ""))]
6822 "registers_ok_for_ldd_peep (operands[1], operands[3])
6823 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6826 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6827 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6830 [(set (match_operand:SI 0 "register_operand" "")
6831 (match_operand:SI 1 "memory_operand" ""))
6832 (set (match_operand:SI 2 "register_operand" "")
6833 (match_operand:SI 3 "memory_operand" ""))]
6834 "registers_ok_for_ldd_peep (operands[2], operands[0])
6835 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6838 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6839 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6842 [(set (match_operand:SI 0 "memory_operand" "")
6843 (match_operand:SI 1 "register_operand" ""))
6844 (set (match_operand:SI 2 "memory_operand" "")
6845 (match_operand:SI 3 "register_operand" ""))]
6846 "registers_ok_for_ldd_peep (operands[3], operands[1])
6847 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6850 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6851 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6855 [(set (match_operand:SF 0 "register_operand" "")
6856 (match_operand:SF 1 "memory_operand" ""))
6857 (set (match_operand:SF 2 "register_operand" "")
6858 (match_operand:SF 3 "memory_operand" ""))]
6859 "registers_ok_for_ldd_peep (operands[2], operands[0])
6860 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6863 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6864 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6867 [(set (match_operand:SF 0 "memory_operand" "")
6868 (match_operand:SF 1 "register_operand" ""))
6869 (set (match_operand:SF 2 "memory_operand" "")
6870 (match_operand:SF 3 "register_operand" ""))]
6871 "registers_ok_for_ldd_peep (operands[3], operands[1])
6872 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6875 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6876 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6878 ;; Optimize the case of following a reg-reg move with a test
6879 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6880 ;; This can result from a float to fix conversion.
6883 [(set (match_operand:SI 0 "register_operand" "")
6884 (match_operand:SI 1 "register_operand" ""))
6885 (set (reg:CC CC_REG)
6886 (compare:CC (match_operand:SI 2 "register_operand" "")
6888 "(rtx_equal_p (operands[2], operands[0])
6889 || rtx_equal_p (operands[2], operands[1]))
6890 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6891 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6892 [(parallel [(set (match_dup 0) (match_dup 1))
6893 (set (reg:CC CC_REG)
6894 (compare:CC (match_dup 1) (const_int 0)))])]
6898 [(set (match_operand:DI 0 "register_operand" "")
6899 (match_operand:DI 1 "register_operand" ""))
6900 (set (reg:CCX CC_REG)
6901 (compare:CCX (match_operand:DI 2 "register_operand" "")
6904 && (rtx_equal_p (operands[2], operands[0])
6905 || rtx_equal_p (operands[2], operands[1]))
6906 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6907 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6908 [(parallel [(set (match_dup 0) (match_dup 1))
6909 (set (reg:CCX CC_REG)
6910 (compare:CCX (match_dup 1) (const_int 0)))])]
6914 ;; Prefetch instructions.
6916 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6917 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6918 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6920 (define_expand "prefetch"
6921 [(match_operand 0 "address_operand" "")
6922 (match_operand 1 "const_int_operand" "")
6923 (match_operand 2 "const_int_operand" "")]
6927 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6929 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6933 (define_insn "prefetch_64"
6934 [(prefetch (match_operand:DI 0 "address_operand" "p")
6935 (match_operand:DI 1 "const_int_operand" "n")
6936 (match_operand:DI 2 "const_int_operand" "n"))]
6939 static const char * const prefetch_instr[2][2] = {
6941 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6942 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6945 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6946 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6949 int read_or_write = INTVAL (operands[1]);
6950 int locality = INTVAL (operands[2]);
6952 gcc_assert (read_or_write == 0 || read_or_write == 1);
6953 gcc_assert (locality >= 0 && locality < 4);
6954 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6956 [(set_attr "type" "load")])
6958 (define_insn "prefetch_32"
6959 [(prefetch (match_operand:SI 0 "address_operand" "p")
6960 (match_operand:SI 1 "const_int_operand" "n")
6961 (match_operand:SI 2 "const_int_operand" "n"))]
6964 static const char * const prefetch_instr[2][2] = {
6966 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6967 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6970 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6971 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6974 int read_or_write = INTVAL (operands[1]);
6975 int locality = INTVAL (operands[2]);
6977 gcc_assert (read_or_write == 0 || read_or_write == 1);
6978 gcc_assert (locality >= 0 && locality < 4);
6979 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6981 [(set_attr "type" "load")])
6984 ;; Trap instructions.
6987 [(trap_if (const_int 1) (const_int 5))]
6990 [(set_attr "type" "trap")])
6992 (define_expand "ctrapsi4"
6993 [(trap_if (match_operator 0 "noov_compare_operator"
6994 [(match_operand:SI 1 "compare_operand" "")
6995 (match_operand:SI 2 "arith_operand" "")])
6996 (match_operand 3 ""))]
6998 "operands[1] = gen_compare_reg (operands[0]);
6999 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7001 operands[2] = const0_rtx;")
7003 (define_expand "ctrapdi4"
7004 [(trap_if (match_operator 0 "noov_compare_operator"
7005 [(match_operand:DI 1 "compare_operand" "")
7006 (match_operand:DI 2 "arith_operand" "")])
7007 (match_operand 3 ""))]
7009 "operands[1] = gen_compare_reg (operands[0]);
7010 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7012 operands[2] = const0_rtx;")
7016 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7017 (match_operand:SI 1 "arith_operand" "rM"))]
7021 return "t%C0\t%%icc, %1";
7025 [(set_attr "type" "trap")])
7028 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7029 (match_operand:SI 1 "arith_operand" "rM"))]
7032 [(set_attr "type" "trap")])
7035 ;; TLS support instructions.
7037 (define_insn "tgd_hi22"
7038 [(set (match_operand:SI 0 "register_operand" "=r")
7039 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7042 "sethi\\t%%tgd_hi22(%a1), %0")
7044 (define_insn "tgd_lo10"
7045 [(set (match_operand:SI 0 "register_operand" "=r")
7046 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7047 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7050 "add\\t%1, %%tgd_lo10(%a2), %0")
7052 (define_insn "tgd_add32"
7053 [(set (match_operand:SI 0 "register_operand" "=r")
7054 (plus:SI (match_operand:SI 1 "register_operand" "r")
7055 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7056 (match_operand 3 "tgd_symbolic_operand" "")]
7058 "TARGET_TLS && TARGET_ARCH32"
7059 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7061 (define_insn "tgd_add64"
7062 [(set (match_operand:DI 0 "register_operand" "=r")
7063 (plus:DI (match_operand:DI 1 "register_operand" "r")
7064 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7065 (match_operand 3 "tgd_symbolic_operand" "")]
7067 "TARGET_TLS && TARGET_ARCH64"
7068 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7070 (define_insn "tgd_call32"
7071 [(set (match_operand 0 "register_operand" "=r")
7072 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7073 (match_operand 2 "tgd_symbolic_operand" "")]
7075 (match_operand 3 "" "")))
7076 (clobber (reg:SI O7_REG))]
7077 "TARGET_TLS && TARGET_ARCH32"
7078 "call\t%a1, %%tgd_call(%a2)%#"
7079 [(set_attr "type" "call")])
7081 (define_insn "tgd_call64"
7082 [(set (match_operand 0 "register_operand" "=r")
7083 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7084 (match_operand 2 "tgd_symbolic_operand" "")]
7086 (match_operand 3 "" "")))
7087 (clobber (reg:DI O7_REG))]
7088 "TARGET_TLS && TARGET_ARCH64"
7089 "call\t%a1, %%tgd_call(%a2)%#"
7090 [(set_attr "type" "call")])
7092 (define_insn "tldm_hi22"
7093 [(set (match_operand:SI 0 "register_operand" "=r")
7094 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7096 "sethi\\t%%tldm_hi22(%&), %0")
7098 (define_insn "tldm_lo10"
7099 [(set (match_operand:SI 0 "register_operand" "=r")
7100 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7101 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7103 "add\\t%1, %%tldm_lo10(%&), %0")
7105 (define_insn "tldm_add32"
7106 [(set (match_operand:SI 0 "register_operand" "=r")
7107 (plus:SI (match_operand:SI 1 "register_operand" "r")
7108 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7110 "TARGET_TLS && TARGET_ARCH32"
7111 "add\\t%1, %2, %0, %%tldm_add(%&)")
7113 (define_insn "tldm_add64"
7114 [(set (match_operand:DI 0 "register_operand" "=r")
7115 (plus:DI (match_operand:DI 1 "register_operand" "r")
7116 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7118 "TARGET_TLS && TARGET_ARCH64"
7119 "add\\t%1, %2, %0, %%tldm_add(%&)")
7121 (define_insn "tldm_call32"
7122 [(set (match_operand 0 "register_operand" "=r")
7123 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7125 (match_operand 2 "" "")))
7126 (clobber (reg:SI O7_REG))]
7127 "TARGET_TLS && TARGET_ARCH32"
7128 "call\t%a1, %%tldm_call(%&)%#"
7129 [(set_attr "type" "call")])
7131 (define_insn "tldm_call64"
7132 [(set (match_operand 0 "register_operand" "=r")
7133 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7135 (match_operand 2 "" "")))
7136 (clobber (reg:DI O7_REG))]
7137 "TARGET_TLS && TARGET_ARCH64"
7138 "call\t%a1, %%tldm_call(%&)%#"
7139 [(set_attr "type" "call")])
7141 (define_insn "tldo_hix22"
7142 [(set (match_operand:SI 0 "register_operand" "=r")
7143 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7146 "sethi\\t%%tldo_hix22(%a1), %0")
7148 (define_insn "tldo_lox10"
7149 [(set (match_operand:SI 0 "register_operand" "=r")
7150 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7151 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7154 "xor\\t%1, %%tldo_lox10(%a2), %0")
7156 (define_insn "tldo_add32"
7157 [(set (match_operand:SI 0 "register_operand" "=r")
7158 (plus:SI (match_operand:SI 1 "register_operand" "r")
7159 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7160 (match_operand 3 "tld_symbolic_operand" "")]
7162 "TARGET_TLS && TARGET_ARCH32"
7163 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7165 (define_insn "tldo_add64"
7166 [(set (match_operand:DI 0 "register_operand" "=r")
7167 (plus:DI (match_operand:DI 1 "register_operand" "r")
7168 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7169 (match_operand 3 "tld_symbolic_operand" "")]
7171 "TARGET_TLS && TARGET_ARCH64"
7172 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7174 (define_insn "tie_hi22"
7175 [(set (match_operand:SI 0 "register_operand" "=r")
7176 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7179 "sethi\\t%%tie_hi22(%a1), %0")
7181 (define_insn "tie_lo10"
7182 [(set (match_operand:SI 0 "register_operand" "=r")
7183 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7184 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7187 "add\\t%1, %%tie_lo10(%a2), %0")
7189 (define_insn "tie_ld32"
7190 [(set (match_operand:SI 0 "register_operand" "=r")
7191 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7192 (match_operand:SI 2 "register_operand" "r")
7193 (match_operand 3 "tie_symbolic_operand" "")]
7195 "TARGET_TLS && TARGET_ARCH32"
7196 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7197 [(set_attr "type" "load")])
7199 (define_insn "tie_ld64"
7200 [(set (match_operand:DI 0 "register_operand" "=r")
7201 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7202 (match_operand:SI 2 "register_operand" "r")
7203 (match_operand 3 "tie_symbolic_operand" "")]
7205 "TARGET_TLS && TARGET_ARCH64"
7206 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7207 [(set_attr "type" "load")])
7209 (define_insn "tie_add32"
7210 [(set (match_operand:SI 0 "register_operand" "=r")
7211 (plus:SI (match_operand:SI 1 "register_operand" "r")
7212 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7213 (match_operand 3 "tie_symbolic_operand" "")]
7215 "TARGET_SUN_TLS && TARGET_ARCH32"
7216 "add\\t%1, %2, %0, %%tie_add(%a3)")
7218 (define_insn "tie_add64"
7219 [(set (match_operand:DI 0 "register_operand" "=r")
7220 (plus:DI (match_operand:DI 1 "register_operand" "r")
7221 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7222 (match_operand 3 "tie_symbolic_operand" "")]
7224 "TARGET_SUN_TLS && TARGET_ARCH64"
7225 "add\\t%1, %2, %0, %%tie_add(%a3)")
7227 (define_insn "tle_hix22_sp32"
7228 [(set (match_operand:SI 0 "register_operand" "=r")
7229 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7231 "TARGET_TLS && TARGET_ARCH32"
7232 "sethi\\t%%tle_hix22(%a1), %0")
7234 (define_insn "tle_lox10_sp32"
7235 [(set (match_operand:SI 0 "register_operand" "=r")
7236 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7237 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7239 "TARGET_TLS && TARGET_ARCH32"
7240 "xor\\t%1, %%tle_lox10(%a2), %0")
7242 (define_insn "tle_hix22_sp64"
7243 [(set (match_operand:DI 0 "register_operand" "=r")
7244 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7246 "TARGET_TLS && TARGET_ARCH64"
7247 "sethi\\t%%tle_hix22(%a1), %0")
7249 (define_insn "tle_lox10_sp64"
7250 [(set (match_operand:DI 0 "register_operand" "=r")
7251 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7252 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7254 "TARGET_TLS && TARGET_ARCH64"
7255 "xor\\t%1, %%tle_lox10(%a2), %0")
7257 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7258 (define_insn "*tldo_ldub_sp32"
7259 [(set (match_operand:QI 0 "register_operand" "=r")
7260 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7261 (match_operand 3 "tld_symbolic_operand" "")]
7263 (match_operand:SI 1 "register_operand" "r"))))]
7264 "TARGET_TLS && TARGET_ARCH32"
7265 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7266 [(set_attr "type" "load")
7267 (set_attr "us3load_type" "3cycle")])
7269 (define_insn "*tldo_ldub1_sp32"
7270 [(set (match_operand:HI 0 "register_operand" "=r")
7271 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7272 (match_operand 3 "tld_symbolic_operand" "")]
7274 (match_operand:SI 1 "register_operand" "r")))))]
7275 "TARGET_TLS && TARGET_ARCH32"
7276 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7277 [(set_attr "type" "load")
7278 (set_attr "us3load_type" "3cycle")])
7280 (define_insn "*tldo_ldub2_sp32"
7281 [(set (match_operand:SI 0 "register_operand" "=r")
7282 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7283 (match_operand 3 "tld_symbolic_operand" "")]
7285 (match_operand:SI 1 "register_operand" "r")))))]
7286 "TARGET_TLS && TARGET_ARCH32"
7287 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7288 [(set_attr "type" "load")
7289 (set_attr "us3load_type" "3cycle")])
7291 (define_insn "*tldo_ldsb1_sp32"
7292 [(set (match_operand:HI 0 "register_operand" "=r")
7293 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7294 (match_operand 3 "tld_symbolic_operand" "")]
7296 (match_operand:SI 1 "register_operand" "r")))))]
7297 "TARGET_TLS && TARGET_ARCH32"
7298 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7299 [(set_attr "type" "sload")
7300 (set_attr "us3load_type" "3cycle")])
7302 (define_insn "*tldo_ldsb2_sp32"
7303 [(set (match_operand:SI 0 "register_operand" "=r")
7304 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7305 (match_operand 3 "tld_symbolic_operand" "")]
7307 (match_operand:SI 1 "register_operand" "r")))))]
7308 "TARGET_TLS && TARGET_ARCH32"
7309 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7310 [(set_attr "type" "sload")
7311 (set_attr "us3load_type" "3cycle")])
7313 (define_insn "*tldo_ldub_sp64"
7314 [(set (match_operand:QI 0 "register_operand" "=r")
7315 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7316 (match_operand 3 "tld_symbolic_operand" "")]
7318 (match_operand:DI 1 "register_operand" "r"))))]
7319 "TARGET_TLS && TARGET_ARCH64"
7320 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7321 [(set_attr "type" "load")
7322 (set_attr "us3load_type" "3cycle")])
7324 (define_insn "*tldo_ldub1_sp64"
7325 [(set (match_operand:HI 0 "register_operand" "=r")
7326 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7327 (match_operand 3 "tld_symbolic_operand" "")]
7329 (match_operand:DI 1 "register_operand" "r")))))]
7330 "TARGET_TLS && TARGET_ARCH64"
7331 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7332 [(set_attr "type" "load")
7333 (set_attr "us3load_type" "3cycle")])
7335 (define_insn "*tldo_ldub2_sp64"
7336 [(set (match_operand:SI 0 "register_operand" "=r")
7337 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7338 (match_operand 3 "tld_symbolic_operand" "")]
7340 (match_operand:DI 1 "register_operand" "r")))))]
7341 "TARGET_TLS && TARGET_ARCH64"
7342 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7343 [(set_attr "type" "load")
7344 (set_attr "us3load_type" "3cycle")])
7346 (define_insn "*tldo_ldub3_sp64"
7347 [(set (match_operand:DI 0 "register_operand" "=r")
7348 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7349 (match_operand 3 "tld_symbolic_operand" "")]
7351 (match_operand:DI 1 "register_operand" "r")))))]
7352 "TARGET_TLS && TARGET_ARCH64"
7353 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7354 [(set_attr "type" "load")
7355 (set_attr "us3load_type" "3cycle")])
7357 (define_insn "*tldo_ldsb1_sp64"
7358 [(set (match_operand:HI 0 "register_operand" "=r")
7359 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7360 (match_operand 3 "tld_symbolic_operand" "")]
7362 (match_operand:DI 1 "register_operand" "r")))))]
7363 "TARGET_TLS && TARGET_ARCH64"
7364 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7365 [(set_attr "type" "sload")
7366 (set_attr "us3load_type" "3cycle")])
7368 (define_insn "*tldo_ldsb2_sp64"
7369 [(set (match_operand:SI 0 "register_operand" "=r")
7370 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7371 (match_operand 3 "tld_symbolic_operand" "")]
7373 (match_operand:DI 1 "register_operand" "r")))))]
7374 "TARGET_TLS && TARGET_ARCH64"
7375 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7376 [(set_attr "type" "sload")
7377 (set_attr "us3load_type" "3cycle")])
7379 (define_insn "*tldo_ldsb3_sp64"
7380 [(set (match_operand:DI 0 "register_operand" "=r")
7381 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7382 (match_operand 3 "tld_symbolic_operand" "")]
7384 (match_operand:DI 1 "register_operand" "r")))))]
7385 "TARGET_TLS && TARGET_ARCH64"
7386 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7387 [(set_attr "type" "sload")
7388 (set_attr "us3load_type" "3cycle")])
7390 (define_insn "*tldo_lduh_sp32"
7391 [(set (match_operand:HI 0 "register_operand" "=r")
7392 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7393 (match_operand 3 "tld_symbolic_operand" "")]
7395 (match_operand:SI 1 "register_operand" "r"))))]
7396 "TARGET_TLS && TARGET_ARCH32"
7397 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7398 [(set_attr "type" "load")
7399 (set_attr "us3load_type" "3cycle")])
7401 (define_insn "*tldo_lduh1_sp32"
7402 [(set (match_operand:SI 0 "register_operand" "=r")
7403 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7404 (match_operand 3 "tld_symbolic_operand" "")]
7406 (match_operand:SI 1 "register_operand" "r")))))]
7407 "TARGET_TLS && TARGET_ARCH32"
7408 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7409 [(set_attr "type" "load")
7410 (set_attr "us3load_type" "3cycle")])
7412 (define_insn "*tldo_ldsh1_sp32"
7413 [(set (match_operand:SI 0 "register_operand" "=r")
7414 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7415 (match_operand 3 "tld_symbolic_operand" "")]
7417 (match_operand:SI 1 "register_operand" "r")))))]
7418 "TARGET_TLS && TARGET_ARCH32"
7419 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7420 [(set_attr "type" "sload")
7421 (set_attr "us3load_type" "3cycle")])
7423 (define_insn "*tldo_lduh_sp64"
7424 [(set (match_operand:HI 0 "register_operand" "=r")
7425 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7426 (match_operand 3 "tld_symbolic_operand" "")]
7428 (match_operand:DI 1 "register_operand" "r"))))]
7429 "TARGET_TLS && TARGET_ARCH64"
7430 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7431 [(set_attr "type" "load")
7432 (set_attr "us3load_type" "3cycle")])
7434 (define_insn "*tldo_lduh1_sp64"
7435 [(set (match_operand:SI 0 "register_operand" "=r")
7436 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7437 (match_operand 3 "tld_symbolic_operand" "")]
7439 (match_operand:DI 1 "register_operand" "r")))))]
7440 "TARGET_TLS && TARGET_ARCH64"
7441 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7442 [(set_attr "type" "load")
7443 (set_attr "us3load_type" "3cycle")])
7445 (define_insn "*tldo_lduh2_sp64"
7446 [(set (match_operand:DI 0 "register_operand" "=r")
7447 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7448 (match_operand 3 "tld_symbolic_operand" "")]
7450 (match_operand:DI 1 "register_operand" "r")))))]
7451 "TARGET_TLS && TARGET_ARCH64"
7452 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7453 [(set_attr "type" "load")
7454 (set_attr "us3load_type" "3cycle")])
7456 (define_insn "*tldo_ldsh1_sp64"
7457 [(set (match_operand:SI 0 "register_operand" "=r")
7458 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7459 (match_operand 3 "tld_symbolic_operand" "")]
7461 (match_operand:DI 1 "register_operand" "r")))))]
7462 "TARGET_TLS && TARGET_ARCH64"
7463 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7464 [(set_attr "type" "sload")
7465 (set_attr "us3load_type" "3cycle")])
7467 (define_insn "*tldo_ldsh2_sp64"
7468 [(set (match_operand:DI 0 "register_operand" "=r")
7469 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7470 (match_operand 3 "tld_symbolic_operand" "")]
7472 (match_operand:DI 1 "register_operand" "r")))))]
7473 "TARGET_TLS && TARGET_ARCH64"
7474 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7475 [(set_attr "type" "sload")
7476 (set_attr "us3load_type" "3cycle")])
7478 (define_insn "*tldo_lduw_sp32"
7479 [(set (match_operand:SI 0 "register_operand" "=r")
7480 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7481 (match_operand 3 "tld_symbolic_operand" "")]
7483 (match_operand:SI 1 "register_operand" "r"))))]
7484 "TARGET_TLS && TARGET_ARCH32"
7485 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7486 [(set_attr "type" "load")])
7488 (define_insn "*tldo_lduw_sp64"
7489 [(set (match_operand:SI 0 "register_operand" "=r")
7490 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7491 (match_operand 3 "tld_symbolic_operand" "")]
7493 (match_operand:DI 1 "register_operand" "r"))))]
7494 "TARGET_TLS && TARGET_ARCH64"
7495 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7496 [(set_attr "type" "load")])
7498 (define_insn "*tldo_lduw1_sp64"
7499 [(set (match_operand:DI 0 "register_operand" "=r")
7500 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7501 (match_operand 3 "tld_symbolic_operand" "")]
7503 (match_operand:DI 1 "register_operand" "r")))))]
7504 "TARGET_TLS && TARGET_ARCH64"
7505 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7506 [(set_attr "type" "load")])
7508 (define_insn "*tldo_ldsw1_sp64"
7509 [(set (match_operand:DI 0 "register_operand" "=r")
7510 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7511 (match_operand 3 "tld_symbolic_operand" "")]
7513 (match_operand:DI 1 "register_operand" "r")))))]
7514 "TARGET_TLS && TARGET_ARCH64"
7515 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7516 [(set_attr "type" "sload")
7517 (set_attr "us3load_type" "3cycle")])
7519 (define_insn "*tldo_ldx_sp64"
7520 [(set (match_operand:DI 0 "register_operand" "=r")
7521 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7522 (match_operand 3 "tld_symbolic_operand" "")]
7524 (match_operand:DI 1 "register_operand" "r"))))]
7525 "TARGET_TLS && TARGET_ARCH64"
7526 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7527 [(set_attr "type" "load")])
7529 (define_insn "*tldo_stb_sp32"
7530 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7531 (match_operand 3 "tld_symbolic_operand" "")]
7533 (match_operand:SI 1 "register_operand" "r")))
7534 (match_operand:QI 0 "register_operand" "=r"))]
7535 "TARGET_TLS && TARGET_ARCH32"
7536 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7537 [(set_attr "type" "store")])
7539 (define_insn "*tldo_stb_sp64"
7540 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7541 (match_operand 3 "tld_symbolic_operand" "")]
7543 (match_operand:DI 1 "register_operand" "r")))
7544 (match_operand:QI 0 "register_operand" "=r"))]
7545 "TARGET_TLS && TARGET_ARCH64"
7546 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7547 [(set_attr "type" "store")])
7549 (define_insn "*tldo_sth_sp32"
7550 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7551 (match_operand 3 "tld_symbolic_operand" "")]
7553 (match_operand:SI 1 "register_operand" "r")))
7554 (match_operand:HI 0 "register_operand" "=r"))]
7555 "TARGET_TLS && TARGET_ARCH32"
7556 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7557 [(set_attr "type" "store")])
7559 (define_insn "*tldo_sth_sp64"
7560 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7561 (match_operand 3 "tld_symbolic_operand" "")]
7563 (match_operand:DI 1 "register_operand" "r")))
7564 (match_operand:HI 0 "register_operand" "=r"))]
7565 "TARGET_TLS && TARGET_ARCH64"
7566 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7567 [(set_attr "type" "store")])
7569 (define_insn "*tldo_stw_sp32"
7570 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7571 (match_operand 3 "tld_symbolic_operand" "")]
7573 (match_operand:SI 1 "register_operand" "r")))
7574 (match_operand:SI 0 "register_operand" "=r"))]
7575 "TARGET_TLS && TARGET_ARCH32"
7576 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7577 [(set_attr "type" "store")])
7579 (define_insn "*tldo_stw_sp64"
7580 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7581 (match_operand 3 "tld_symbolic_operand" "")]
7583 (match_operand:DI 1 "register_operand" "r")))
7584 (match_operand:SI 0 "register_operand" "=r"))]
7585 "TARGET_TLS && TARGET_ARCH64"
7586 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7587 [(set_attr "type" "store")])
7589 (define_insn "*tldo_stx_sp64"
7590 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7591 (match_operand 3 "tld_symbolic_operand" "")]
7593 (match_operand:DI 1 "register_operand" "r")))
7594 (match_operand:DI 0 "register_operand" "=r"))]
7595 "TARGET_TLS && TARGET_ARCH64"
7596 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7597 [(set_attr "type" "store")])
7600 ;; Stack protector instructions.
7602 (define_expand "stack_protect_set"
7603 [(match_operand 0 "memory_operand" "")
7604 (match_operand 1 "memory_operand" "")]
7607 #ifdef TARGET_THREAD_SSP_OFFSET
7608 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7609 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7610 operands[1] = gen_rtx_MEM (Pmode, addr);
7613 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7615 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7619 (define_insn "stack_protect_setsi"
7620 [(set (match_operand:SI 0 "memory_operand" "=m")
7621 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7622 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7624 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7625 [(set_attr "type" "multi")
7626 (set_attr "length" "3")])
7628 (define_insn "stack_protect_setdi"
7629 [(set (match_operand:DI 0 "memory_operand" "=m")
7630 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7631 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7633 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7634 [(set_attr "type" "multi")
7635 (set_attr "length" "3")])
7637 (define_expand "stack_protect_test"
7638 [(match_operand 0 "memory_operand" "")
7639 (match_operand 1 "memory_operand" "")
7640 (match_operand 2 "" "")]
7644 #ifdef TARGET_THREAD_SSP_OFFSET
7645 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7646 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7647 operands[1] = gen_rtx_MEM (Pmode, addr);
7651 result = gen_reg_rtx (Pmode);
7652 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7653 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7654 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7658 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7659 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7660 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7661 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7666 (define_insn "stack_protect_testsi"
7667 [(set (reg:CC CC_REG)
7668 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7669 (match_operand:SI 1 "memory_operand" "m")]
7671 (set (match_scratch:SI 3 "=r") (const_int 0))
7672 (clobber (match_scratch:SI 2 "=&r"))]
7674 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7675 [(set_attr "type" "multi")
7676 (set_attr "length" "4")])
7678 (define_insn "stack_protect_testdi"
7679 [(set (match_operand:DI 0 "register_operand" "=&r")
7680 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7681 (match_operand:DI 2 "memory_operand" "m")]
7683 (set (match_scratch:DI 3 "=r") (const_int 0))]
7685 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7686 [(set_attr "type" "multi")
7687 (set_attr "length" "4")])
7689 ;; Vector instructions.
7691 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7692 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7693 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7695 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
7696 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7697 (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7698 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7699 (V1DI "double") (V2SI "double") (V4HI "double")
7702 (define_expand "mov<VMALL:mode>"
7703 [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7704 (match_operand:VMALL 1 "general_operand" ""))]
7707 if (sparc_expand_move (<VMALL:MODE>mode, operands))
7711 (define_insn "*mov<VM32:mode>_insn"
7712 [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
7713 (match_operand:VM32 1 "input_operand" "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
7715 && (register_operand (operands[0], <VM32:MODE>mode)
7716 || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7729 [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*,*")
7730 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
7732 (define_insn "*mov<VM64:mode>_insn_sp64"
7733 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
7734 (match_operand:VM64 1 "input_operand" "Y,C,e,m,e,Y, m,*r, e,*r,*r"))]
7737 && (register_operand (operands[0], <VM64:MODE>mode)
7738 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7751 [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*,*")
7752 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
7754 (define_insn "*mov<VM64:mode>_insn_sp32"
7755 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
7756 (match_operand:VM64 1 "input_operand" "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
7759 && (register_operand (operands[0], <VM64:MODE>mode)
7760 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7774 [(set_attr "type" "fga,fga,fga,*,*,fpload,fpstore,store,load,store,*,*")
7775 (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
7776 (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
7779 [(set (match_operand:VM64 0 "memory_operand" "")
7780 (match_operand:VM64 1 "register_operand" ""))]
7784 && (((REGNO (operands[1]) % 2) != 0)
7785 || ! mem_min_alignment (operands[0], 8))
7786 && offsettable_memref_p (operands[0])"
7787 [(clobber (const_int 0))]
7791 word0 = adjust_address (operands[0], SImode, 0);
7792 word1 = adjust_address (operands[0], SImode, 4);
7794 emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
7795 emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
7800 [(set (match_operand:VM64 0 "register_operand" "")
7801 (match_operand:VM64 1 "register_operand" ""))]
7805 && sparc_split_regreg_legitimate (operands[0], operands[1])"
7806 [(clobber (const_int 0))]
7808 rtx set_dest = operands[0];
7809 rtx set_src = operands[1];
7813 dest1 = gen_highpart (SImode, set_dest);
7814 dest2 = gen_lowpart (SImode, set_dest);
7815 src1 = gen_highpart (SImode, set_src);
7816 src2 = gen_lowpart (SImode, set_src);
7818 /* Now emit using the real source and destination we found, swapping
7819 the order if we detect overlap. */
7820 if (reg_overlap_mentioned_p (dest1, src2))
7822 emit_insn (gen_movsi (dest2, src2));
7823 emit_insn (gen_movsi (dest1, src1));
7827 emit_insn (gen_movsi (dest1, src1));
7828 emit_insn (gen_movsi (dest2, src2));
7833 (define_expand "vec_init<mode>"
7834 [(match_operand:VMALL 0 "register_operand" "")
7835 (match_operand:VMALL 1 "" "")]
7838 sparc_expand_vector_init (operands[0], operands[1]);
7842 (define_code_iterator plusminus [plus minus])
7843 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
7845 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
7847 (define_insn "<plusminus_insn><mode>3"
7848 [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
7849 (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
7850 (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
7852 "fp<plusminus_insn><vbits>\t%1, %2, %0"
7853 [(set_attr "type" "fga")
7854 (set_attr "fptype" "<vfptype>")])
7856 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7857 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
7858 (V1DI "") (V2SI "") (V4HI "") (V8QI "")])
7859 (define_code_iterator vlop [ior and xor])
7860 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
7861 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
7863 (define_insn "<code><mode>3"
7864 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7865 (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7866 (match_operand:VL 2 "register_operand" "<vconstr>")))]
7868 "f<vlinsn><vlsuf>\t%1, %2, %0"
7869 [(set_attr "type" "fga")
7870 (set_attr "fptype" "<vfptype>")])
7872 (define_insn "*not_<code><mode>3"
7873 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7874 (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7875 (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7877 "f<vlninsn><vlsuf>\t%1, %2, %0"
7878 [(set_attr "type" "fga")
7879 (set_attr "fptype" "<vfptype>")])
7881 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7882 (define_insn "*nand<mode>_vis"
7883 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7884 (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
7885 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7887 "fnand<vlsuf>\t%1, %2, %0"
7888 [(set_attr "type" "fga")
7889 (set_attr "fptype" "<vfptype>")])
7891 (define_code_iterator vlnotop [ior and])
7893 (define_insn "*<code>_not1<mode>_vis"
7894 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7895 (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
7896 (match_operand:VL 2 "register_operand" "<vconstr>")))]
7898 "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
7899 [(set_attr "type" "fga")
7900 (set_attr "fptype" "<vfptype>")])
7902 (define_insn "*<code>_not2<mode>_vis"
7903 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7904 (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7905 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7907 "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
7908 [(set_attr "type" "fga")
7909 (set_attr "fptype" "<vfptype>")])
7911 (define_insn "one_cmpl<mode>2"
7912 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7913 (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
7915 "fnot1<vlsuf>\t%1, %0"
7916 [(set_attr "type" "fga")
7917 (set_attr "fptype" "<vfptype>")])
7919 ;; Hard to generate VIS instructions. We have builtins for these.
7921 (define_insn "fpack16_vis"
7922 [(set (match_operand:V4QI 0 "register_operand" "=f")
7923 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
7928 [(set_attr "type" "fga")
7929 (set_attr "fptype" "double")])
7931 (define_insn "fpackfix_vis"
7932 [(set (match_operand:V2HI 0 "register_operand" "=f")
7933 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
7938 [(set_attr "type" "fga")
7939 (set_attr "fptype" "double")])
7941 (define_insn "fpack32_vis"
7942 [(set (match_operand:V8QI 0 "register_operand" "=e")
7943 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7944 (match_operand:V8QI 2 "register_operand" "e")
7948 "fpack32\t%1, %2, %0"
7949 [(set_attr "type" "fga")
7950 (set_attr "fptype" "double")])
7952 (define_insn "fexpand_vis"
7953 [(set (match_operand:V4HI 0 "register_operand" "=e")
7954 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7958 [(set_attr "type" "fga")
7959 (set_attr "fptype" "double")])
7961 (define_insn "fpmerge_vis"
7962 [(set (match_operand:V8QI 0 "register_operand" "=e")
7964 (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
7965 (match_operand:V4QI 2 "register_operand" "f"))
7966 (parallel [(const_int 0) (const_int 4)
7967 (const_int 1) (const_int 5)
7968 (const_int 2) (const_int 6)
7969 (const_int 3) (const_int 7)])))]
7971 "fpmerge\t%1, %2, %0"
7972 [(set_attr "type" "fga")
7973 (set_attr "fptype" "double")])
7975 (define_insn "vec_interleave_lowv8qi"
7976 [(set (match_operand:V8QI 0 "register_operand" "=e")
7978 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
7979 (match_operand:V8QI 2 "register_operand" "f"))
7980 (parallel [(const_int 0) (const_int 8)
7981 (const_int 1) (const_int 9)
7982 (const_int 2) (const_int 10)
7983 (const_int 3) (const_int 11)])))]
7985 "fpmerge\t%L1, %L2, %0"
7986 [(set_attr "type" "fga")
7987 (set_attr "fptype" "double")])
7989 (define_insn "vec_interleave_highv8qi"
7990 [(set (match_operand:V8QI 0 "register_operand" "=e")
7992 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
7993 (match_operand:V8QI 2 "register_operand" "f"))
7994 (parallel [(const_int 4) (const_int 12)
7995 (const_int 5) (const_int 13)
7996 (const_int 6) (const_int 14)
7997 (const_int 7) (const_int 15)])))]
7999 "fpmerge\t%H1, %H2, %0"
8000 [(set_attr "type" "fga")
8001 (set_attr "fptype" "double")])
8003 ;; Partitioned multiply instructions
8004 (define_insn "fmul8x16_vis"
8005 [(set (match_operand:V4HI 0 "register_operand" "=e")
8006 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8007 (match_operand:V4HI 2 "register_operand" "e")]
8010 "fmul8x16\t%1, %2, %0"
8011 [(set_attr "type" "fpmul")
8012 (set_attr "fptype" "double")])
8014 (define_insn "fmul8x16au_vis"
8015 [(set (match_operand:V4HI 0 "register_operand" "=e")
8016 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8017 (match_operand:V2HI 2 "register_operand" "f")]
8020 "fmul8x16au\t%1, %2, %0"
8021 [(set_attr "type" "fpmul")
8022 (set_attr "fptype" "double")])
8024 (define_insn "fmul8x16al_vis"
8025 [(set (match_operand:V4HI 0 "register_operand" "=e")
8026 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8027 (match_operand:V2HI 2 "register_operand" "f")]
8030 "fmul8x16al\t%1, %2, %0"
8031 [(set_attr "type" "fpmul")
8032 (set_attr "fptype" "double")])
8034 (define_insn "fmul8sux16_vis"
8035 [(set (match_operand:V4HI 0 "register_operand" "=e")
8036 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8037 (match_operand:V4HI 2 "register_operand" "e")]
8040 "fmul8sux16\t%1, %2, %0"
8041 [(set_attr "type" "fpmul")
8042 (set_attr "fptype" "double")])
8044 (define_insn "fmul8ulx16_vis"
8045 [(set (match_operand:V4HI 0 "register_operand" "=e")
8046 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8047 (match_operand:V4HI 2 "register_operand" "e")]
8050 "fmul8ulx16\t%1, %2, %0"
8051 [(set_attr "type" "fpmul")
8052 (set_attr "fptype" "double")])
8054 (define_insn "fmuld8sux16_vis"
8055 [(set (match_operand:V2SI 0 "register_operand" "=e")
8056 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8057 (match_operand:V2HI 2 "register_operand" "f")]
8060 "fmuld8sux16\t%1, %2, %0"
8061 [(set_attr "type" "fpmul")
8062 (set_attr "fptype" "double")])
8064 (define_insn "fmuld8ulx16_vis"
8065 [(set (match_operand:V2SI 0 "register_operand" "=e")
8066 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8067 (match_operand:V2HI 2 "register_operand" "f")]
8070 "fmuld8ulx16\t%1, %2, %0"
8071 [(set_attr "type" "fpmul")
8072 (set_attr "fptype" "double")])
8074 (define_expand "wrgsr_vis"
8075 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8078 if (! TARGET_ARCH64)
8080 emit_insn (gen_wrgsr_v8plus (operands[0]));
8085 (define_insn "*wrgsr_sp64"
8086 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8087 "TARGET_VIS && TARGET_ARCH64"
8088 "wr\t%%g0, %0, %%gsr"
8089 [(set_attr "type" "gsr")])
8091 (define_insn "wrgsr_v8plus"
8092 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8093 (clobber (match_scratch:SI 1 "=X,&h"))]
8094 "TARGET_VIS && ! TARGET_ARCH64"
8096 if (GET_CODE (operands[0]) == CONST_INT
8097 || sparc_check_64 (operands[0], insn))
8098 return "wr\t%%g0, %0, %%gsr";
8100 output_asm_insn("srl\t%L0, 0, %L0", operands);
8101 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8103 [(set_attr "type" "multi")])
8105 (define_expand "rdgsr_vis"
8106 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8109 if (! TARGET_ARCH64)
8111 emit_insn (gen_rdgsr_v8plus (operands[0]));
8116 (define_insn "*rdgsr_sp64"
8117 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8118 "TARGET_VIS && TARGET_ARCH64"
8120 [(set_attr "type" "gsr")])
8122 (define_insn "rdgsr_v8plus"
8123 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8124 (clobber (match_scratch:SI 1 "=&h"))]
8125 "TARGET_VIS && ! TARGET_ARCH64"
8127 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8129 [(set_attr "type" "multi")])
8131 ;; Using faligndata only makes sense after an alignaddr since the choice of
8132 ;; bytes to take out of each operand is dependent on the results of the last
8134 (define_insn "faligndata<VM64:mode>_vis"
8135 [(set (match_operand:VM64 0 "register_operand" "=e")
8136 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8137 (match_operand:VM64 2 "register_operand" "e")
8141 "faligndata\t%1, %2, %0"
8142 [(set_attr "type" "fga")
8143 (set_attr "fptype" "double")])
8145 (define_insn "alignaddrsi_vis"
8146 [(set (match_operand:SI 0 "register_operand" "=r")
8147 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8148 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8149 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8150 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8152 "alignaddr\t%r1, %r2, %0")
8154 (define_insn "alignaddrdi_vis"
8155 [(set (match_operand:DI 0 "register_operand" "=r")
8156 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8157 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8158 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8159 (plus:DI (match_dup 1) (match_dup 2)))]
8161 "alignaddr\t%r1, %r2, %0")
8163 (define_insn "alignaddrlsi_vis"
8164 [(set (match_operand:SI 0 "register_operand" "=r")
8165 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8166 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8167 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8168 (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8171 "alignaddrl\t%r1, %r2, %0")
8173 (define_insn "alignaddrldi_vis"
8174 [(set (match_operand:DI 0 "register_operand" "=r")
8175 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8176 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8177 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8178 (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8181 "alignaddrl\t%r1, %r2, %0")
8183 (define_insn "pdist_vis"
8184 [(set (match_operand:DI 0 "register_operand" "=e")
8185 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8186 (match_operand:V8QI 2 "register_operand" "e")
8187 (match_operand:DI 3 "register_operand" "0")]
8191 [(set_attr "type" "fga")
8192 (set_attr "fptype" "double")])
8194 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8195 ;; with the same operands.
8196 (define_insn "edge8<P:mode>_vis"
8197 [(set (reg:CC_NOOV CC_REG)
8198 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8199 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8201 (set (match_operand:P 0 "register_operand" "=r")
8202 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8204 "edge8\t%r1, %r2, %0"
8205 [(set_attr "type" "edge")])
8207 (define_insn "edge8l<P:mode>_vis"
8208 [(set (reg:CC_NOOV CC_REG)
8209 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8210 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8212 (set (match_operand:P 0 "register_operand" "=r")
8213 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8215 "edge8l\t%r1, %r2, %0"
8216 [(set_attr "type" "edge")])
8218 (define_insn "edge16<P:mode>_vis"
8219 [(set (reg:CC_NOOV CC_REG)
8220 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8221 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8223 (set (match_operand:P 0 "register_operand" "=r")
8224 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8226 "edge16\t%r1, %r2, %0"
8227 [(set_attr "type" "edge")])
8229 (define_insn "edge16l<P:mode>_vis"
8230 [(set (reg:CC_NOOV CC_REG)
8231 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8232 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8234 (set (match_operand:P 0 "register_operand" "=r")
8235 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8237 "edge16l\t%r1, %r2, %0"
8238 [(set_attr "type" "edge")])
8240 (define_insn "edge32<P:mode>_vis"
8241 [(set (reg:CC_NOOV CC_REG)
8242 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8243 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8245 (set (match_operand:P 0 "register_operand" "=r")
8246 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8248 "edge32\t%r1, %r2, %0"
8249 [(set_attr "type" "edge")])
8251 (define_insn "edge32l<P:mode>_vis"
8252 [(set (reg:CC_NOOV CC_REG)
8253 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8254 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8256 (set (match_operand:P 0 "register_operand" "=r")
8257 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8259 "edge32l\t%r1, %r2, %0"
8260 [(set_attr "type" "edge")])
8262 (define_code_iterator gcond [le ne gt eq])
8263 (define_mode_iterator GCM [V4HI V2SI])
8264 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8266 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8267 [(set (match_operand:P 0 "register_operand" "=r")
8268 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8269 (match_operand:GCM 2 "register_operand" "e"))]
8272 "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8273 [(set_attr "type" "fpmul")
8274 (set_attr "fptype" "double")])
8276 (define_expand "vcond<mode><mode>"
8277 [(match_operand:GCM 0 "register_operand" "")
8278 (match_operand:GCM 1 "register_operand" "")
8279 (match_operand:GCM 2 "register_operand" "")
8280 (match_operator 3 ""
8281 [(match_operand:GCM 4 "register_operand" "")
8282 (match_operand:GCM 5 "register_operand" "")])]
8285 sparc_expand_vcond (<MODE>mode, operands,
8286 UNSPEC_CMASK<gcm_name>,
8291 (define_expand "vconduv8qiv8qi"
8292 [(match_operand:V8QI 0 "register_operand" "")
8293 (match_operand:V8QI 1 "register_operand" "")
8294 (match_operand:V8QI 2 "register_operand" "")
8295 (match_operator 3 ""
8296 [(match_operand:V8QI 4 "register_operand" "")
8297 (match_operand:V8QI 5 "register_operand" "")])]
8300 sparc_expand_vcond (V8QImode, operands,
8306 (define_insn "array8<P:mode>_vis"
8307 [(set (match_operand:P 0 "register_operand" "=r")
8308 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8309 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8312 "array8\t%r1, %r2, %0"
8313 [(set_attr "type" "array")])
8315 (define_insn "array16<P:mode>_vis"
8316 [(set (match_operand:P 0 "register_operand" "=r")
8317 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8318 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8321 "array16\t%r1, %r2, %0"
8322 [(set_attr "type" "array")])
8324 (define_insn "array32<P:mode>_vis"
8325 [(set (match_operand:P 0 "register_operand" "=r")
8326 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8327 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8330 "array32\t%r1, %r2, %0"
8331 [(set_attr "type" "array")])
8333 (define_insn "bmaskdi_vis"
8334 [(set (match_operand:DI 0 "register_operand" "=r")
8335 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8336 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8337 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8338 (plus:DI (match_dup 1) (match_dup 2)))]
8340 "bmask\t%r1, %r2, %0"
8341 [(set_attr "type" "array")])
8343 (define_insn "bmasksi_vis"
8344 [(set (match_operand:SI 0 "register_operand" "=r")
8345 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8346 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8347 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8348 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8350 "bmask\t%r1, %r2, %0"
8351 [(set_attr "type" "array")])
8353 (define_insn "bshuffle<VM64:mode>_vis"
8354 [(set (match_operand:VM64 0 "register_operand" "=e")
8355 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8356 (match_operand:VM64 2 "register_operand" "e")
8360 "bshuffle\t%1, %2, %0"
8361 [(set_attr "type" "fga")
8362 (set_attr "fptype" "double")])
8364 ;; The rtl expanders will happily convert constant permutations on other
8365 ;; modes down to V8QI. Rely on this to avoid the complexity of the byte
8366 ;; order of the permutation.
8367 (define_expand "vec_perm_constv8qi"
8368 [(match_operand:V8QI 0 "register_operand" "")
8369 (match_operand:V8QI 1 "register_operand" "")
8370 (match_operand:V8QI 2 "register_operand" "")
8371 (match_operand:V8QI 3 "" "")]
8374 unsigned int i, mask;
8375 rtx sel = operands[3];
8377 for (i = mask = 0; i < 8; ++i)
8378 mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8379 sel = force_reg (SImode, gen_int_mode (mask, SImode));
8381 emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, const0_rtx));
8382 emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8386 ;; Unlike constant permutation, we can vastly simplify the compression of
8387 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8388 ;; width of the input is.
8389 (define_expand "vec_perm<mode>"
8390 [(match_operand:VM64 0 "register_operand" "")
8391 (match_operand:VM64 1 "register_operand" "")
8392 (match_operand:VM64 2 "register_operand" "")
8393 (match_operand:VM64 3 "register_operand" "")]
8396 sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8397 emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8401 ;; VIS 2.0 adds edge variants which do not set the condition codes
8402 (define_insn "edge8n<P:mode>_vis"
8403 [(set (match_operand:P 0 "register_operand" "=r")
8404 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8405 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8408 "edge8n\t%r1, %r2, %0"
8409 [(set_attr "type" "edgen")])
8411 (define_insn "edge8ln<P:mode>_vis"
8412 [(set (match_operand:P 0 "register_operand" "=r")
8413 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8414 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8417 "edge8ln\t%r1, %r2, %0"
8418 [(set_attr "type" "edgen")])
8420 (define_insn "edge16n<P:mode>_vis"
8421 [(set (match_operand:P 0 "register_operand" "=r")
8422 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8423 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8426 "edge16n\t%r1, %r2, %0"
8427 [(set_attr "type" "edgen")])
8429 (define_insn "edge16ln<P:mode>_vis"
8430 [(set (match_operand:P 0 "register_operand" "=r")
8431 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8432 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8435 "edge16ln\t%r1, %r2, %0"
8436 [(set_attr "type" "edgen")])
8438 (define_insn "edge32n<P:mode>_vis"
8439 [(set (match_operand:P 0 "register_operand" "=r")
8440 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8441 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8444 "edge32n\t%r1, %r2, %0"
8445 [(set_attr "type" "edgen")])
8447 (define_insn "edge32ln<P:mode>_vis"
8448 [(set (match_operand:P 0 "register_operand" "=r")
8449 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8450 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8453 "edge32ln\t%r1, %r2, %0"
8454 [(set_attr "type" "edge")])
8456 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8457 (define_insn "cmask8<P:mode>_vis"
8458 [(set (reg:DI GSR_REG)
8459 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8465 (define_insn "cmask16<P:mode>_vis"
8466 [(set (reg:DI GSR_REG)
8467 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8473 (define_insn "cmask32<P:mode>_vis"
8474 [(set (reg:DI GSR_REG)
8475 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8481 (define_insn "fchksm16_vis"
8482 [(set (match_operand:V4HI 0 "register_operand" "=e")
8483 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8484 (match_operand:V4HI 2 "register_operand" "e")]
8487 "fchksm16\t%1, %2, %0")
8489 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8490 (define_code_attr vis3_shift_insn
8491 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8492 (define_code_attr vis3_shift_patname
8493 [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8495 (define_insn "v<vis3_shift_patname><mode>3"
8496 [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8497 (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8498 (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8500 "<vis3_shift_insn><vbits>\t%1, %2, %0")
8502 (define_insn "pdistn<mode>_vis"
8503 [(set (match_operand:P 0 "register_operand" "=r")
8504 (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8505 (match_operand:V8QI 2 "register_operand" "e")]
8508 "pdistn\t%1, %2, %0")
8510 (define_insn "fmean16_vis"
8511 [(set (match_operand:V4HI 0 "register_operand" "=e")
8517 (match_operand:V4HI 1 "register_operand" "e"))
8519 (match_operand:V4HI 2 "register_operand" "e")))
8520 (const_vector:V4SI [(const_int 1) (const_int 1)
8521 (const_int 1) (const_int 1)]))
8524 "fmean16\t%1, %2, %0")
8526 (define_insn "fp<plusminus_insn>64_vis"
8527 [(set (match_operand:V1DI 0 "register_operand" "=e")
8528 (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8529 (match_operand:V1DI 2 "register_operand" "e")))]
8531 "fp<plusminus_insn>64\t%1, %2, %0")
8533 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8534 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8535 (define_code_attr vis3_addsub_ss_insn
8536 [(ss_plus "fpadds") (ss_minus "fpsubs")])
8537 (define_code_attr vis3_addsub_ss_patname
8538 [(ss_plus "ssadd") (ss_minus "sssub")])
8540 (define_insn "<vis3_addsub_ss_patname><mode>3"
8541 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8542 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8543 (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8545 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0")
8547 (define_insn "fucmp<code>8<P:mode>_vis"
8548 [(set (match_operand:P 0 "register_operand" "=r")
8549 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8550 (match_operand:V8QI 2 "register_operand" "e"))]
8553 "fucmp<code>8\t%1, %2, %0")
8555 (define_insn "*naddsf3"
8556 [(set (match_operand:SF 0 "register_operand" "=f")
8557 (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8558 (match_operand:SF 2 "register_operand" "f"))))]
8560 "fnadds\t%1, %2, %0"
8561 [(set_attr "type" "fp")])
8563 (define_insn "*nadddf3"
8564 [(set (match_operand:DF 0 "register_operand" "=e")
8565 (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8566 (match_operand:DF 2 "register_operand" "e"))))]
8568 "fnaddd\t%1, %2, %0"
8569 [(set_attr "type" "fp")
8570 (set_attr "fptype" "double")])
8572 (define_insn "*nmulsf3"
8573 [(set (match_operand:SF 0 "register_operand" "=f")
8574 (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8575 (match_operand:SF 2 "register_operand" "f")))]
8577 "fnmuls\t%1, %2, %0"
8578 [(set_attr "type" "fpmul")])
8580 (define_insn "*nmuldf3"
8581 [(set (match_operand:DF 0 "register_operand" "=e")
8582 (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8583 (match_operand:DF 2 "register_operand" "e")))]
8585 "fnmuld\t%1, %2, %0"
8586 [(set_attr "type" "fpmul")
8587 (set_attr "fptype" "double")])
8589 (define_insn "*nmuldf3_extend"
8590 [(set (match_operand:DF 0 "register_operand" "=e")
8591 (mult:DF (neg:DF (float_extend:DF
8592 (match_operand:SF 1 "register_operand" "f")))
8594 (match_operand:SF 2 "register_operand" "f"))))]
8596 "fnsmuld\t%1, %2, %0"
8597 [(set_attr "type" "fpmul")
8598 (set_attr "fptype" "double")])
8600 (define_insn "fhaddsf_vis"
8601 [(set (match_operand:SF 0 "register_operand" "=f")
8602 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8603 (match_operand:SF 2 "register_operand" "f")]
8606 "fhadds\t%1, %2, %0"
8607 [(set_attr "type" "fp")])
8609 (define_insn "fhadddf_vis"
8610 [(set (match_operand:DF 0 "register_operand" "=f")
8611 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8612 (match_operand:DF 2 "register_operand" "f")]
8615 "fhaddd\t%1, %2, %0"
8616 [(set_attr "type" "fp")
8617 (set_attr "fptype" "double")])
8619 (define_insn "fhsubsf_vis"
8620 [(set (match_operand:SF 0 "register_operand" "=f")
8621 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8622 (match_operand:SF 2 "register_operand" "f")]
8625 "fhsubs\t%1, %2, %0"
8626 [(set_attr "type" "fp")])
8628 (define_insn "fhsubdf_vis"
8629 [(set (match_operand:DF 0 "register_operand" "=f")
8630 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8631 (match_operand:DF 2 "register_operand" "f")]
8634 "fhsubd\t%1, %2, %0"
8635 [(set_attr "type" "fp")
8636 (set_attr "fptype" "double")])
8638 (define_insn "fnhaddsf_vis"
8639 [(set (match_operand:SF 0 "register_operand" "=f")
8640 (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8641 (match_operand:SF 2 "register_operand" "f")]
8644 "fnhadds\t%1, %2, %0"
8645 [(set_attr "type" "fp")])
8647 (define_insn "fnhadddf_vis"
8648 [(set (match_operand:DF 0 "register_operand" "=f")
8649 (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8650 (match_operand:DF 2 "register_operand" "f")]
8653 "fnhaddd\t%1, %2, %0"
8654 [(set_attr "type" "fp")
8655 (set_attr "fptype" "double")])
8657 (define_expand "umulxhi_vis"
8658 [(set (match_operand:DI 0 "register_operand" "")
8661 (mult:TI (zero_extend:TI
8662 (match_operand:DI 1 "arith_operand" ""))
8664 (match_operand:DI 2 "arith_operand" "")))
8668 if (! TARGET_ARCH64)
8670 emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8675 (define_insn "*umulxhi_sp64"
8676 [(set (match_operand:DI 0 "register_operand" "=r")
8679 (mult:TI (zero_extend:TI
8680 (match_operand:DI 1 "arith_operand" "%r"))
8682 (match_operand:DI 2 "arith_operand" "rI")))
8684 "TARGET_VIS3 && TARGET_ARCH64"
8685 "umulxhi\t%1, %2, %0"
8686 [(set_attr "type" "imul")])
8688 (define_insn "umulxhi_v8plus"
8689 [(set (match_operand:DI 0 "register_operand" "=r,h")
8692 (mult:TI (zero_extend:TI
8693 (match_operand:DI 1 "arith_operand" "%r,0"))
8695 (match_operand:DI 2 "arith_operand" "rI,rI")))
8697 (clobber (match_scratch:SI 3 "=&h,X"))
8698 (clobber (match_scratch:SI 4 "=&h,X"))]
8699 "TARGET_VIS3 && ! TARGET_ARCH64"
8700 "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8701 [(set_attr "type" "imul")
8702 (set_attr "length" "9,8")])
8704 (define_expand "xmulx_vis"
8705 [(set (match_operand:DI 0 "register_operand" "")
8707 (unspec:TI [(zero_extend:TI
8708 (match_operand:DI 1 "arith_operand" ""))
8710 (match_operand:DI 2 "arith_operand" ""))]
8714 if (! TARGET_ARCH64)
8716 emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8721 (define_insn "*xmulx_sp64"
8722 [(set (match_operand:DI 0 "register_operand" "=r")
8724 (unspec:TI [(zero_extend:TI
8725 (match_operand:DI 1 "arith_operand" "%r"))
8727 (match_operand:DI 2 "arith_operand" "rI"))]
8729 "TARGET_VIS3 && TARGET_ARCH64"
8731 [(set_attr "type" "imul")])
8733 (define_insn "xmulx_v8plus"
8734 [(set (match_operand:DI 0 "register_operand" "=r,h")
8736 (unspec:TI [(zero_extend:TI
8737 (match_operand:DI 1 "arith_operand" "%r,0"))
8739 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8741 (clobber (match_scratch:SI 3 "=&h,X"))
8742 (clobber (match_scratch:SI 4 "=&h,X"))]
8743 "TARGET_VIS3 && ! TARGET_ARCH64"
8744 "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8745 [(set_attr "type" "imul")
8746 (set_attr "length" "9,8")])
8748 (define_expand "xmulxhi_vis"
8749 [(set (match_operand:DI 0 "register_operand" "")
8752 (unspec:TI [(zero_extend:TI
8753 (match_operand:DI 1 "arith_operand" ""))
8755 (match_operand:DI 2 "arith_operand" ""))]
8760 if (! TARGET_ARCH64)
8762 emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
8767 (define_insn "*xmulxhi_sp64"
8768 [(set (match_operand:DI 0 "register_operand" "=r")
8771 (unspec:TI [(zero_extend:TI
8772 (match_operand:DI 1 "arith_operand" "%r"))
8774 (match_operand:DI 2 "arith_operand" "rI"))]
8777 "TARGET_VIS3 && TARGET_ARCH64"
8778 "xmulxhi\t%1, %2, %0"
8779 [(set_attr "type" "imul")])
8781 (define_insn "xmulxhi_v8plus"
8782 [(set (match_operand:DI 0 "register_operand" "=r,h")
8785 (unspec:TI [(zero_extend:TI
8786 (match_operand:DI 1 "arith_operand" "%r,0"))
8788 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8791 (clobber (match_scratch:SI 3 "=&h,X"))
8792 (clobber (match_scratch:SI 4 "=&h,X"))]
8793 "TARGET_VIS3 && !TARGET_ARCH64"
8794 "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
8795 [(set_attr "type" "imul")
8796 (set_attr "length" "9,8")])