1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 ;; 2011 Free Software Foundation, Inc.
5 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
6 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3. If not see
23 ;; <http://www.gnu.org/licenses/>.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (UNSPEC_UPDATE_RETURN 1)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
41 (UNSPEC_MOVE_GOTDATA 19)
50 (UNSPEC_TLSLD_BASE 35)
106 (UNSPECV_PROBE_STACK_RANGE 11)
199 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
200 (define_mode_iterator I [QI HI SI DI])
201 (define_mode_iterator F [SF DF TF])
203 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
204 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
205 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
206 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
207 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
209 ;; Attribute for cpu type.
210 ;; These must match the values for enum processor_type in sparc.h.
231 (const (symbol_ref "sparc_cpu_attr")))
233 ;; Attribute for the instruction set.
234 ;; At present we only need to distinguish v9/!v9, but for clarity we
235 ;; test TARGET_V8 too.
236 (define_attr "isa" "v7,v8,v9,sparclet"
238 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
239 (symbol_ref "TARGET_V8") (const_string "v8")
240 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
241 (const_string "v7"))))
243 (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3" (const_string "none"))
245 (define_attr "enabled" ""
246 (cond [(eq_attr "cpu_feature" "none") (const_int 1)
247 (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU")
248 (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && ! TARGET_V9")
249 (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9")
250 (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS")
251 (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")]
258 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
266 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,edgen,gsr,array,
269 multi,savew,flushw,iflush,trap"
270 (const_string "ialu"))
272 ;; True if branch/call has empty delay slot and will emit a nop in it
273 (define_attr "empty_delay_slot" "false,true"
274 (symbol_ref "(empty_delay_slot (insn)
275 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
277 (define_attr "branch_type" "none,icc,fcc,reg"
278 (const_string "none"))
280 (define_attr "pic" "false,true"
281 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
283 (define_attr "calls_alloca" "false,true"
284 (symbol_ref "(cfun->calls_alloca != 0
285 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
287 (define_attr "calls_eh_return" "false,true"
288 (symbol_ref "(crtl->calls_eh_return != 0
289 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
291 (define_attr "leaf_function" "false,true"
292 (symbol_ref "(current_function_uses_only_leaf_regs != 0
293 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
295 (define_attr "delayed_branch" "false,true"
296 (symbol_ref "(flag_delayed_branch != 0
297 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
299 (define_attr "flat" "false,true"
300 (symbol_ref "(TARGET_FLAT != 0
301 ? FLAT_TRUE : FLAT_FALSE)"))
303 ;; Length (in # of insns).
304 ;; Beware that setting a length greater or equal to 3 for conditional branches
305 ;; has a side-effect (see output_cbranch and output_v9branch).
306 (define_attr "length" ""
307 (cond [(eq_attr "type" "uncond_branch,call")
308 (if_then_else (eq_attr "empty_delay_slot" "true")
311 (eq_attr "type" "sibcall")
312 (if_then_else (eq_attr "leaf_function" "true")
313 (if_then_else (eq_attr "empty_delay_slot" "true")
316 (if_then_else (eq_attr "empty_delay_slot" "true")
319 (eq_attr "branch_type" "icc")
320 (if_then_else (match_operand 0 "noov_compare64_operator" "")
321 (if_then_else (lt (pc) (match_dup 1))
322 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
323 (if_then_else (eq_attr "empty_delay_slot" "true")
326 (if_then_else (eq_attr "empty_delay_slot" "true")
329 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
330 (if_then_else (eq_attr "empty_delay_slot" "true")
333 (if_then_else (eq_attr "empty_delay_slot" "true")
336 (if_then_else (eq_attr "empty_delay_slot" "true")
339 (eq_attr "branch_type" "fcc")
340 (if_then_else (match_operand 0 "fcc0_register_operand" "")
341 (if_then_else (eq_attr "empty_delay_slot" "true")
342 (if_then_else (not (match_test "TARGET_V9"))
345 (if_then_else (not (match_test "TARGET_V9"))
348 (if_then_else (lt (pc) (match_dup 2))
349 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
350 (if_then_else (eq_attr "empty_delay_slot" "true")
353 (if_then_else (eq_attr "empty_delay_slot" "true")
356 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
357 (if_then_else (eq_attr "empty_delay_slot" "true")
360 (if_then_else (eq_attr "empty_delay_slot" "true")
363 (eq_attr "branch_type" "reg")
364 (if_then_else (lt (pc) (match_dup 2))
365 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
366 (if_then_else (eq_attr "empty_delay_slot" "true")
369 (if_then_else (eq_attr "empty_delay_slot" "true")
372 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
373 (if_then_else (eq_attr "empty_delay_slot" "true")
376 (if_then_else (eq_attr "empty_delay_slot" "true")
382 (define_attr "fptype" "single,double"
383 (const_string "single"))
385 ;; UltraSPARC-III integer load type.
386 (define_attr "us3load_type" "2cycle,3cycle"
387 (const_string "2cycle"))
389 (define_asm_attributes
390 [(set_attr "length" "2")
391 (set_attr "type" "multi")])
393 ;; Attributes for instruction and branch scheduling
394 (define_attr "tls_call_delay" "false,true"
395 (symbol_ref "(tls_call_delay (insn)
396 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
398 (define_attr "in_call_delay" "false,true"
399 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
400 (const_string "false")
401 (eq_attr "type" "load,fpload,store,fpstore")
402 (if_then_else (eq_attr "length" "1")
403 (const_string "true")
404 (const_string "false"))]
405 (if_then_else (and (eq_attr "length" "1")
406 (eq_attr "tls_call_delay" "true"))
407 (const_string "true")
408 (const_string "false"))))
410 (define_attr "eligible_for_sibcall_delay" "false,true"
411 (symbol_ref "(eligible_for_sibcall_delay (insn)
412 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
413 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
415 (define_attr "eligible_for_return_delay" "false,true"
416 (symbol_ref "(eligible_for_return_delay (insn)
417 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
418 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
420 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
421 ;; branches. This would allow us to remove the nop always inserted before
422 ;; a floating point branch.
424 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
425 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
426 ;; This is because doing so will add several pipeline stalls to the path
427 ;; that the load/store did not come from. Unfortunately, there is no way
428 ;; to prevent fill_eager_delay_slots from using load/store without completely
429 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
430 ;; because it prevents us from moving back the final store of inner loops.
432 (define_attr "in_branch_delay" "false,true"
433 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
434 (eq_attr "length" "1"))
435 (const_string "true")
436 (const_string "false")))
438 (define_attr "in_uncond_branch_delay" "false,true"
439 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
440 (eq_attr "length" "1"))
441 (const_string "true")
442 (const_string "false")))
444 (define_attr "in_annul_branch_delay" "false,true"
445 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
446 (eq_attr "length" "1"))
447 (const_string "true")
448 (const_string "false")))
450 (define_delay (eq_attr "type" "call")
451 [(eq_attr "in_call_delay" "true") (nil) (nil)])
453 (define_delay (eq_attr "type" "sibcall")
454 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
456 (define_delay (eq_attr "type" "branch")
457 [(eq_attr "in_branch_delay" "true")
458 (nil) (eq_attr "in_annul_branch_delay" "true")])
460 (define_delay (eq_attr "type" "uncond_branch")
461 [(eq_attr "in_uncond_branch_delay" "true")
464 (define_delay (eq_attr "type" "return")
465 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
468 ;; Include SPARC DFA schedulers
470 (include "cypress.md")
471 (include "supersparc.md")
472 (include "hypersparc.md")
474 (include "sparclet.md")
475 (include "ultra1_2.md")
476 (include "ultra3.md")
477 (include "niagara.md")
478 (include "niagara2.md")
481 ;; Operand and operator predicates and constraints
483 (include "predicates.md")
484 (include "constraints.md")
487 ;; Compare instructions.
489 ;; These are just the DEFINE_INSNs to match the patterns and the
490 ;; DEFINE_SPLITs for some of the scc insns that actually require
491 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
493 ;; The compare DEFINE_INSNs.
495 (define_insn "*cmpsi_insn"
496 [(set (reg:CC CC_REG)
497 (compare:CC (match_operand:SI 0 "register_operand" "r")
498 (match_operand:SI 1 "arith_operand" "rI")))]
501 [(set_attr "type" "compare")])
503 (define_insn "*cmpdi_sp64"
504 [(set (reg:CCX CC_REG)
505 (compare:CCX (match_operand:DI 0 "register_operand" "r")
506 (match_operand:DI 1 "arith_operand" "rI")))]
509 [(set_attr "type" "compare")])
511 (define_insn "*cmpsf_fpe"
512 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
513 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
514 (match_operand:SF 2 "register_operand" "f")))]
518 return "fcmpes\t%0, %1, %2";
519 return "fcmpes\t%1, %2";
521 [(set_attr "type" "fpcmp")])
523 (define_insn "*cmpdf_fpe"
524 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
525 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
526 (match_operand:DF 2 "register_operand" "e")))]
530 return "fcmped\t%0, %1, %2";
531 return "fcmped\t%1, %2";
533 [(set_attr "type" "fpcmp")
534 (set_attr "fptype" "double")])
536 (define_insn "*cmptf_fpe"
537 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
538 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
539 (match_operand:TF 2 "register_operand" "e")))]
540 "TARGET_FPU && TARGET_HARD_QUAD"
543 return "fcmpeq\t%0, %1, %2";
544 return "fcmpeq\t%1, %2";
546 [(set_attr "type" "fpcmp")])
548 (define_insn "*cmpsf_fp"
549 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
550 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
551 (match_operand:SF 2 "register_operand" "f")))]
555 return "fcmps\t%0, %1, %2";
556 return "fcmps\t%1, %2";
558 [(set_attr "type" "fpcmp")])
560 (define_insn "*cmpdf_fp"
561 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
562 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
563 (match_operand:DF 2 "register_operand" "e")))]
567 return "fcmpd\t%0, %1, %2";
568 return "fcmpd\t%1, %2";
570 [(set_attr "type" "fpcmp")
571 (set_attr "fptype" "double")])
573 (define_insn "*cmptf_fp"
574 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
575 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
576 (match_operand:TF 2 "register_operand" "e")))]
577 "TARGET_FPU && TARGET_HARD_QUAD"
580 return "fcmpq\t%0, %1, %2";
581 return "fcmpq\t%1, %2";
583 [(set_attr "type" "fpcmp")])
585 ;; Next come the scc insns.
587 (define_expand "cstoresi4"
588 [(use (match_operator 1 "comparison_operator"
589 [(match_operand:SI 2 "compare_operand" "")
590 (match_operand:SI 3 "arith_operand" "")]))
591 (clobber (match_operand:SI 0 "register_operand"))]
594 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
595 operands[2] = force_reg (SImode, operands[2]);
596 if (emit_scc_insn (operands)) DONE; else FAIL;
599 (define_expand "cstoredi4"
600 [(use (match_operator 1 "comparison_operator"
601 [(match_operand:DI 2 "compare_operand" "")
602 (match_operand:DI 3 "arith_operand" "")]))
603 (clobber (match_operand:SI 0 "register_operand"))]
606 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
607 operands[2] = force_reg (DImode, operands[2]);
608 if (emit_scc_insn (operands)) DONE; else FAIL;
611 (define_expand "cstore<F:mode>4"
612 [(use (match_operator 1 "comparison_operator"
613 [(match_operand:F 2 "register_operand" "")
614 (match_operand:F 3 "register_operand" "")]))
615 (clobber (match_operand:SI 0 "register_operand"))]
617 { if (emit_scc_insn (operands)) DONE; else FAIL; })
621 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
622 ;; generate addcc/subcc instructions.
624 (define_expand "seqsi_special"
626 (xor:SI (match_operand:SI 1 "register_operand" "")
627 (match_operand:SI 2 "register_operand" "")))
628 (parallel [(set (match_operand:SI 0 "register_operand" "")
629 (eq:SI (match_dup 3) (const_int 0)))
630 (clobber (reg:CC CC_REG))])]
632 { operands[3] = gen_reg_rtx (SImode); })
634 (define_expand "seqdi_special"
636 (xor:DI (match_operand:DI 1 "register_operand" "")
637 (match_operand:DI 2 "register_operand" "")))
638 (set (match_operand:SI 0 "register_operand" "")
639 (eq:SI (match_dup 3) (const_int 0)))]
641 { operands[3] = gen_reg_rtx (DImode); })
643 (define_expand "snesi_special"
645 (xor:SI (match_operand:SI 1 "register_operand" "")
646 (match_operand:SI 2 "register_operand" "")))
647 (parallel [(set (match_operand:SI 0 "register_operand" "")
648 (ne:SI (match_dup 3) (const_int 0)))
649 (clobber (reg:CC CC_REG))])]
651 { operands[3] = gen_reg_rtx (SImode); })
653 (define_expand "snedi_special"
655 (xor:DI (match_operand:DI 1 "register_operand" "")
656 (match_operand:DI 2 "register_operand" "")))
657 (set (match_operand:SI 0 "register_operand" "")
658 (ne:SI (match_dup 3) (const_int 0)))]
660 { operands[3] = gen_reg_rtx (DImode); })
663 ;; Now the DEFINE_INSNs for the scc cases.
665 ;; The SEQ and SNE patterns are special because they can be done
666 ;; without any branching and do not involve a COMPARE. We want
667 ;; them to always use the splits below so the results can be
670 (define_insn_and_split "*snesi_zero"
671 [(set (match_operand:SI 0 "register_operand" "=r")
672 (ne:SI (match_operand:SI 1 "register_operand" "r")
674 (clobber (reg:CC CC_REG))]
678 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
680 (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
682 [(set_attr "length" "2")])
684 (define_insn_and_split "*neg_snesi_zero"
685 [(set (match_operand:SI 0 "register_operand" "=r")
686 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
688 (clobber (reg:CC CC_REG))]
692 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
694 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
696 [(set_attr "length" "2")])
698 (define_insn_and_split "*snesi_zero_extend"
699 [(set (match_operand:DI 0 "register_operand" "=r")
700 (ne:DI (match_operand:SI 1 "register_operand" "r")
702 (clobber (reg:CC CC_REG))]
706 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
709 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
711 (ltu:SI (reg:CC_NOOV CC_REG)
714 [(set_attr "length" "2")])
716 (define_insn_and_split "*snedi_zero"
717 [(set (match_operand:DI 0 "register_operand" "=&r")
718 (ne:DI (match_operand:DI 1 "register_operand" "r")
722 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
723 [(set (match_dup 0) (const_int 0))
724 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
729 [(set_attr "length" "2")])
731 (define_insn_and_split "*neg_snedi_zero"
732 [(set (match_operand:DI 0 "register_operand" "=&r")
733 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
737 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
738 [(set (match_dup 0) (const_int 0))
739 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
744 [(set_attr "length" "2")])
746 (define_insn_and_split "*snedi_zero_trunc"
747 [(set (match_operand:SI 0 "register_operand" "=&r")
748 (ne:SI (match_operand:DI 1 "register_operand" "r")
752 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
753 [(set (match_dup 0) (const_int 0))
754 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
759 [(set_attr "length" "2")])
761 (define_insn_and_split "*seqsi_zero"
762 [(set (match_operand:SI 0 "register_operand" "=r")
763 (eq:SI (match_operand:SI 1 "register_operand" "r")
765 (clobber (reg:CC CC_REG))]
769 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
771 (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
773 [(set_attr "length" "2")])
775 (define_insn_and_split "*neg_seqsi_zero"
776 [(set (match_operand:SI 0 "register_operand" "=r")
777 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
779 (clobber (reg:CC CC_REG))]
783 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
785 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
787 [(set_attr "length" "2")])
789 (define_insn_and_split "*seqsi_zero_extend"
790 [(set (match_operand:DI 0 "register_operand" "=r")
791 (eq:DI (match_operand:SI 1 "register_operand" "r")
793 (clobber (reg:CC CC_REG))]
797 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
800 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
802 (ltu:SI (reg:CC_NOOV CC_REG)
805 [(set_attr "length" "2")])
807 (define_insn_and_split "*seqdi_zero"
808 [(set (match_operand:DI 0 "register_operand" "=&r")
809 (eq:DI (match_operand:DI 1 "register_operand" "r")
813 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
814 [(set (match_dup 0) (const_int 0))
815 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
820 [(set_attr "length" "2")])
822 (define_insn_and_split "*neg_seqdi_zero"
823 [(set (match_operand:DI 0 "register_operand" "=&r")
824 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
828 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
829 [(set (match_dup 0) (const_int 0))
830 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
835 [(set_attr "length" "2")])
837 (define_insn_and_split "*seqdi_zero_trunc"
838 [(set (match_operand:SI 0 "register_operand" "=&r")
839 (eq:SI (match_operand:DI 1 "register_operand" "r")
843 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
844 [(set (match_dup 0) (const_int 0))
845 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
850 [(set_attr "length" "2")])
852 ;; We can also do (x + (i == 0)) and related, so put them in.
853 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
856 (define_insn_and_split "*x_plus_i_ne_0"
857 [(set (match_operand:SI 0 "register_operand" "=r")
858 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
860 (match_operand:SI 2 "register_operand" "r")))
861 (clobber (reg:CC CC_REG))]
865 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
867 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
870 [(set_attr "length" "2")])
872 (define_insn_and_split "*x_minus_i_ne_0"
873 [(set (match_operand:SI 0 "register_operand" "=r")
874 (minus:SI (match_operand:SI 2 "register_operand" "r")
875 (ne:SI (match_operand:SI 1 "register_operand" "r")
877 (clobber (reg:CC CC_REG))]
881 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
883 (set (match_dup 0) (minus:SI (match_dup 2)
884 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
886 [(set_attr "length" "2")])
888 (define_insn_and_split "*x_plus_i_eq_0"
889 [(set (match_operand:SI 0 "register_operand" "=r")
890 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
892 (match_operand:SI 2 "register_operand" "r")))
893 (clobber (reg:CC CC_REG))]
897 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
899 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
902 [(set_attr "length" "2")])
904 (define_insn_and_split "*x_minus_i_eq_0"
905 [(set (match_operand:SI 0 "register_operand" "=r")
906 (minus:SI (match_operand:SI 2 "register_operand" "r")
907 (eq:SI (match_operand:SI 1 "register_operand" "r")
909 (clobber (reg:CC CC_REG))]
913 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
915 (set (match_dup 0) (minus:SI (match_dup 2)
916 (geu:SI (reg:CC CC_REG) (const_int 0))))]
918 [(set_attr "length" "2")])
920 ;; We can also do GEU and LTU directly, but these operate after a compare.
921 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
924 (define_insn "*sltu_insn"
925 [(set (match_operand:SI 0 "register_operand" "=r")
926 (ltu:SI (reg:CC CC_REG) (const_int 0)))]
929 [(set_attr "type" "ialuX")])
931 (define_insn "*neg_sltu_insn"
932 [(set (match_operand:SI 0 "register_operand" "=r")
933 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
936 [(set_attr "type" "ialuX")])
938 ;; ??? Combine should canonicalize these next two to the same pattern.
939 (define_insn "*neg_sltu_minus_x"
940 [(set (match_operand:SI 0 "register_operand" "=r")
941 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
942 (match_operand:SI 1 "arith_operand" "rI")))]
945 [(set_attr "type" "ialuX")])
947 (define_insn "*neg_sltu_plus_x"
948 [(set (match_operand:SI 0 "register_operand" "=r")
949 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
950 (match_operand:SI 1 "arith_operand" "rI"))))]
953 [(set_attr "type" "ialuX")])
955 (define_insn "*sgeu_insn"
956 [(set (match_operand:SI 0 "register_operand" "=r")
957 (geu:SI (reg:CC CC_REG) (const_int 0)))]
960 [(set_attr "type" "ialuX")])
962 (define_insn "*neg_sgeu_insn"
963 [(set (match_operand:SI 0 "register_operand" "=r")
964 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
967 [(set_attr "type" "ialuX")])
969 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
970 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
973 (define_insn "*sltu_plus_x"
974 [(set (match_operand:SI 0 "register_operand" "=r")
975 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
976 (match_operand:SI 1 "arith_operand" "rI")))]
979 [(set_attr "type" "ialuX")])
981 (define_insn "*sltu_plus_x_plus_y"
982 [(set (match_operand:SI 0 "register_operand" "=r")
983 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
984 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
985 (match_operand:SI 2 "arith_operand" "rI"))))]
988 [(set_attr "type" "ialuX")])
990 (define_insn "*x_minus_sltu"
991 [(set (match_operand:SI 0 "register_operand" "=r")
992 (minus:SI (match_operand:SI 1 "register_operand" "r")
993 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
996 [(set_attr "type" "ialuX")])
998 ;; ??? Combine should canonicalize these next two to the same pattern.
999 (define_insn "*x_minus_y_minus_sltu"
1000 [(set (match_operand:SI 0 "register_operand" "=r")
1001 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1002 (match_operand:SI 2 "arith_operand" "rI"))
1003 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1006 [(set_attr "type" "ialuX")])
1008 (define_insn "*x_minus_sltu_plus_y"
1009 [(set (match_operand:SI 0 "register_operand" "=r")
1010 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1011 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1012 (match_operand:SI 2 "arith_operand" "rI"))))]
1015 [(set_attr "type" "ialuX")])
1017 (define_insn "*sgeu_plus_x"
1018 [(set (match_operand:SI 0 "register_operand" "=r")
1019 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1020 (match_operand:SI 1 "register_operand" "r")))]
1023 [(set_attr "type" "ialuX")])
1025 (define_insn "*x_minus_sgeu"
1026 [(set (match_operand:SI 0 "register_operand" "=r")
1027 (minus:SI (match_operand:SI 1 "register_operand" "r")
1028 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1031 [(set_attr "type" "ialuX")])
1034 [(set (match_operand:SI 0 "register_operand" "")
1035 (match_operator:SI 2 "noov_compare_operator"
1036 [(match_operand 1 "icc_or_fcc_register_operand" "")
1039 && REGNO (operands[1]) == SPARC_ICC_REG
1040 && (GET_MODE (operands[1]) == CCXmode
1041 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1042 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1043 [(set (match_dup 0) (const_int 0))
1045 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1051 ;; These control RTL generation for conditional jump insns
1053 (define_expand "cbranchcc4"
1055 (if_then_else (match_operator 0 "comparison_operator"
1056 [(match_operand 1 "compare_operand" "")
1057 (match_operand 2 "const_zero_operand" "")])
1058 (label_ref (match_operand 3 "" ""))
1063 (define_expand "cbranchsi4"
1064 [(use (match_operator 0 "comparison_operator"
1065 [(match_operand:SI 1 "compare_operand" "")
1066 (match_operand:SI 2 "arith_operand" "")]))
1067 (use (match_operand 3 ""))]
1070 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1071 operands[1] = force_reg (SImode, operands[1]);
1072 emit_conditional_branch_insn (operands);
1076 (define_expand "cbranchdi4"
1077 [(use (match_operator 0 "comparison_operator"
1078 [(match_operand:DI 1 "compare_operand" "")
1079 (match_operand:DI 2 "arith_operand" "")]))
1080 (use (match_operand 3 ""))]
1083 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1084 operands[1] = force_reg (DImode, operands[1]);
1085 emit_conditional_branch_insn (operands);
1089 (define_expand "cbranch<F:mode>4"
1090 [(use (match_operator 0 "comparison_operator"
1091 [(match_operand:F 1 "register_operand" "")
1092 (match_operand:F 2 "register_operand" "")]))
1093 (use (match_operand 3 ""))]
1095 { emit_conditional_branch_insn (operands); DONE; })
1098 ;; Now match both normal and inverted jump.
1100 ;; XXX fpcmp nop braindamage
1101 (define_insn "*normal_branch"
1103 (if_then_else (match_operator 0 "noov_compare_operator"
1104 [(reg CC_REG) (const_int 0)])
1105 (label_ref (match_operand 1 "" ""))
1109 return output_cbranch (operands[0], operands[1], 1, 0,
1110 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1113 [(set_attr "type" "branch")
1114 (set_attr "branch_type" "icc")])
1116 ;; XXX fpcmp nop braindamage
1117 (define_insn "*inverted_branch"
1119 (if_then_else (match_operator 0 "noov_compare_operator"
1120 [(reg CC_REG) (const_int 0)])
1122 (label_ref (match_operand 1 "" ""))))]
1125 return output_cbranch (operands[0], operands[1], 1, 1,
1126 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1129 [(set_attr "type" "branch")
1130 (set_attr "branch_type" "icc")])
1132 ;; XXX fpcmp nop braindamage
1133 (define_insn "*normal_fp_branch"
1135 (if_then_else (match_operator 1 "comparison_operator"
1136 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1138 (label_ref (match_operand 2 "" ""))
1142 return output_cbranch (operands[1], operands[2], 2, 0,
1143 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1146 [(set_attr "type" "branch")
1147 (set_attr "branch_type" "fcc")])
1149 ;; XXX fpcmp nop braindamage
1150 (define_insn "*inverted_fp_branch"
1152 (if_then_else (match_operator 1 "comparison_operator"
1153 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1156 (label_ref (match_operand 2 "" ""))))]
1159 return output_cbranch (operands[1], operands[2], 2, 1,
1160 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1163 [(set_attr "type" "branch")
1164 (set_attr "branch_type" "fcc")])
1166 ;; XXX fpcmp nop braindamage
1167 (define_insn "*normal_fpe_branch"
1169 (if_then_else (match_operator 1 "comparison_operator"
1170 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1172 (label_ref (match_operand 2 "" ""))
1176 return output_cbranch (operands[1], operands[2], 2, 0,
1177 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1180 [(set_attr "type" "branch")
1181 (set_attr "branch_type" "fcc")])
1183 ;; XXX fpcmp nop braindamage
1184 (define_insn "*inverted_fpe_branch"
1186 (if_then_else (match_operator 1 "comparison_operator"
1187 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1190 (label_ref (match_operand 2 "" ""))))]
1193 return output_cbranch (operands[1], operands[2], 2, 1,
1194 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1197 [(set_attr "type" "branch")
1198 (set_attr "branch_type" "fcc")])
1200 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1201 ;; in the architecture.
1203 ;; There are no 32 bit brreg insns.
1206 (define_insn "*normal_int_branch_sp64"
1208 (if_then_else (match_operator 0 "v9_register_compare_operator"
1209 [(match_operand:DI 1 "register_operand" "r")
1211 (label_ref (match_operand 2 "" ""))
1215 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1216 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1219 [(set_attr "type" "branch")
1220 (set_attr "branch_type" "reg")])
1223 (define_insn "*inverted_int_branch_sp64"
1225 (if_then_else (match_operator 0 "v9_register_compare_operator"
1226 [(match_operand:DI 1 "register_operand" "r")
1229 (label_ref (match_operand 2 "" ""))))]
1232 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1233 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1236 [(set_attr "type" "branch")
1237 (set_attr "branch_type" "reg")])
1240 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1241 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1242 ;; that adds the PC value at the call point to register #(operand 3).
1244 (define_insn "load_pcrel_sym<P:mode>"
1245 [(set (match_operand:P 0 "register_operand" "=r")
1246 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1247 (match_operand:P 2 "call_address_operand" "")
1248 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1249 (clobber (reg:P O7_REG))]
1250 "REGNO (operands[0]) == INTVAL (operands[3])"
1252 if (flag_delayed_branch)
1253 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1255 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1257 [(set (attr "type") (const_string "multi"))
1258 (set (attr "length")
1259 (if_then_else (eq_attr "delayed_branch" "true")
1264 ;; Integer move instructions
1266 (define_expand "movqi"
1267 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1268 (match_operand:QI 1 "general_operand" ""))]
1271 if (sparc_expand_move (QImode, operands))
1275 (define_insn "*movqi_insn"
1276 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1277 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1278 "(register_operand (operands[0], QImode)
1279 || register_or_zero_operand (operands[1], QImode))"
1284 [(set_attr "type" "*,load,store")
1285 (set_attr "us3load_type" "*,3cycle,*")])
1287 (define_expand "movhi"
1288 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1289 (match_operand:HI 1 "general_operand" ""))]
1292 if (sparc_expand_move (HImode, operands))
1296 (define_insn "*movhi_insn"
1297 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1298 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1299 "(register_operand (operands[0], HImode)
1300 || register_or_zero_operand (operands[1], HImode))"
1303 sethi\t%%hi(%a1), %0
1306 [(set_attr "type" "*,*,load,store")
1307 (set_attr "us3load_type" "*,*,3cycle,*")])
1309 ;; We always work with constants here.
1310 (define_insn "*movhi_lo_sum"
1311 [(set (match_operand:HI 0 "register_operand" "=r")
1312 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1313 (match_operand:HI 2 "small_int_operand" "I")))]
1317 (define_expand "movsi"
1318 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1319 (match_operand:SI 1 "general_operand" ""))]
1322 if (sparc_expand_move (SImode, operands))
1326 (define_insn "*movsi_insn"
1327 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1328 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1329 "register_operand (operands[0], SImode)
1330 || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1333 sethi\t%%hi(%a1), %0
1343 [(set_attr "type" "*,*,load,store,*,*,fpmove,fpload,fpstore,fga,fga")
1344 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1346 (define_insn "*movsi_lo_sum"
1347 [(set (match_operand:SI 0 "register_operand" "=r")
1348 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1349 (match_operand:SI 2 "immediate_operand" "in")))]
1351 "or\t%1, %%lo(%a2), %0")
1353 (define_insn "*movsi_high"
1354 [(set (match_operand:SI 0 "register_operand" "=r")
1355 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1357 "sethi\t%%hi(%a1), %0")
1359 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1360 ;; so that CSE won't optimize the address computation away.
1361 (define_insn "movsi_lo_sum_pic"
1362 [(set (match_operand:SI 0 "register_operand" "=r")
1363 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1364 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1367 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1368 return "xor\t%1, %%gdop_lox10(%a2), %0";
1370 return "or\t%1, %%lo(%a2), %0";
1374 (define_insn "movsi_high_pic"
1375 [(set (match_operand:SI 0 "register_operand" "=r")
1376 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1377 "flag_pic && check_pic (1)"
1379 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1380 return "sethi\t%%gdop_hix22(%a1), %0";
1382 return "sethi\t%%hi(%a1), %0";
1386 (define_insn "movsi_pic_gotdata_op"
1387 [(set (match_operand:SI 0 "register_operand" "=r")
1388 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1389 (match_operand:SI 2 "register_operand" "r")
1390 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1391 "flag_pic && check_pic (1)"
1393 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1394 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1396 return "ld\t[%1 + %2], %0";
1399 [(set_attr "type" "load")])
1401 (define_expand "movsi_pic_label_ref"
1402 [(set (match_dup 3) (high:SI
1403 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1404 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1405 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1406 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1407 (set (match_operand:SI 0 "register_operand" "=r")
1408 (minus:SI (match_dup 5) (match_dup 4)))]
1411 crtl->uses_pic_offset_table = 1;
1412 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1413 if (!can_create_pseudo_p ())
1415 operands[3] = operands[0];
1416 operands[4] = operands[0];
1420 operands[3] = gen_reg_rtx (SImode);
1421 operands[4] = gen_reg_rtx (SImode);
1423 operands[5] = pic_offset_table_rtx;
1426 (define_insn "*movsi_high_pic_label_ref"
1427 [(set (match_operand:SI 0 "register_operand" "=r")
1429 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1430 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1432 "sethi\t%%hi(%a2-(%a1-.)), %0")
1434 (define_insn "*movsi_lo_sum_pic_label_ref"
1435 [(set (match_operand:SI 0 "register_operand" "=r")
1436 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1437 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1438 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1440 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1442 ;; Set up the PIC register for VxWorks.
1444 (define_expand "vxworks_load_got"
1446 (high:SI (match_dup 1)))
1448 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1450 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1451 "TARGET_VXWORKS_RTP"
1453 operands[0] = pic_offset_table_rtx;
1454 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1455 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1458 (define_expand "movdi"
1459 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1460 (match_operand:DI 1 "general_operand" ""))]
1463 if (sparc_expand_move (DImode, operands))
1467 ;; Be careful, fmovd does not exist when !v9.
1468 ;; We match MEM moves directly when we have correct even
1469 ;; numbered registers, but fall into splits otherwise.
1470 ;; The constraint ordering here is really important to
1471 ;; avoid insane problems in reload, especially for patterns
1474 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1475 ;; (const_int -5016)))
1479 (define_insn "*movdi_insn_sp32"
1480 [(set (match_operand:DI 0 "nonimmediate_operand"
1481 "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e, r,?*f,?*e,?W,b,b")
1482 (match_operand:DI 1 "input_operand"
1483 " J,J,U,T,r,o,i,r,*f, T, o,*f, *e, *e,?*f, r, W,*e,J,P"))]
1485 && (register_operand (operands[0], DImode)
1486 || register_or_zero_operand (operands[1], DImode))"
1508 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,fga,fga")
1509 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1510 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1511 (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
1513 (define_insn "*movdi_insn_sp64"
1514 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1515 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,*e, r, *e, W,*e,J,P"))]
1517 && (register_operand (operands[0], DImode)
1518 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1521 sethi\t%%hi(%a1), %0
1531 [(set_attr "type" "*,*,load,store,*,*,fpmove,fpload,fpstore,fga,fga")
1532 (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1533 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1535 (define_expand "movdi_pic_label_ref"
1536 [(set (match_dup 3) (high:DI
1537 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1538 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1539 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1540 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1541 (set (match_operand:DI 0 "register_operand" "=r")
1542 (minus:DI (match_dup 5) (match_dup 4)))]
1543 "TARGET_ARCH64 && flag_pic"
1545 crtl->uses_pic_offset_table = 1;
1546 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1547 if (!can_create_pseudo_p ())
1549 operands[3] = operands[0];
1550 operands[4] = operands[0];
1554 operands[3] = gen_reg_rtx (DImode);
1555 operands[4] = gen_reg_rtx (DImode);
1557 operands[5] = pic_offset_table_rtx;
1560 (define_insn "*movdi_high_pic_label_ref"
1561 [(set (match_operand:DI 0 "register_operand" "=r")
1563 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1564 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1565 "TARGET_ARCH64 && flag_pic"
1566 "sethi\t%%hi(%a2-(%a1-.)), %0")
1568 (define_insn "*movdi_lo_sum_pic_label_ref"
1569 [(set (match_operand:DI 0 "register_operand" "=r")
1570 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1571 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1572 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1573 "TARGET_ARCH64 && flag_pic"
1574 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1576 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1577 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1579 (define_insn "movdi_lo_sum_pic"
1580 [(set (match_operand:DI 0 "register_operand" "=r")
1581 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1582 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1583 "TARGET_ARCH64 && flag_pic"
1585 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1586 return "xor\t%1, %%gdop_lox10(%a2), %0";
1588 return "or\t%1, %%lo(%a2), %0";
1592 (define_insn "movdi_high_pic"
1593 [(set (match_operand:DI 0 "register_operand" "=r")
1594 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1595 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1597 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1598 return "sethi\t%%gdop_hix22(%a1), %0";
1600 return "sethi\t%%hi(%a1), %0";
1604 (define_insn "movdi_pic_gotdata_op"
1605 [(set (match_operand:DI 0 "register_operand" "=r")
1606 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1607 (match_operand:DI 2 "register_operand" "r")
1608 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1609 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1611 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1612 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1614 return "ldx\t[%1 + %2], %0";
1617 [(set_attr "type" "load")])
1619 (define_insn "*sethi_di_medlow_embmedany_pic"
1620 [(set (match_operand:DI 0 "register_operand" "=r")
1621 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1622 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1623 "sethi\t%%hi(%a1), %0")
1625 (define_insn "*sethi_di_medlow"
1626 [(set (match_operand:DI 0 "register_operand" "=r")
1627 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1628 "TARGET_CM_MEDLOW && check_pic (1)"
1629 "sethi\t%%hi(%a1), %0")
1631 (define_insn "*losum_di_medlow"
1632 [(set (match_operand:DI 0 "register_operand" "=r")
1633 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1634 (match_operand:DI 2 "symbolic_operand" "")))]
1636 "or\t%1, %%lo(%a2), %0")
1638 (define_insn "seth44"
1639 [(set (match_operand:DI 0 "register_operand" "=r")
1640 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1642 "sethi\t%%h44(%a1), %0")
1644 (define_insn "setm44"
1645 [(set (match_operand:DI 0 "register_operand" "=r")
1646 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1647 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1649 "or\t%1, %%m44(%a2), %0")
1651 (define_insn "setl44"
1652 [(set (match_operand:DI 0 "register_operand" "=r")
1653 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1654 (match_operand:DI 2 "symbolic_operand" "")))]
1656 "or\t%1, %%l44(%a2), %0")
1658 (define_insn "sethh"
1659 [(set (match_operand:DI 0 "register_operand" "=r")
1660 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1662 "sethi\t%%hh(%a1), %0")
1664 (define_insn "setlm"
1665 [(set (match_operand:DI 0 "register_operand" "=r")
1666 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1668 "sethi\t%%lm(%a1), %0")
1670 (define_insn "sethm"
1671 [(set (match_operand:DI 0 "register_operand" "=r")
1672 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1673 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1675 "or\t%1, %%hm(%a2), %0")
1677 (define_insn "setlo"
1678 [(set (match_operand:DI 0 "register_operand" "=r")
1679 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1680 (match_operand:DI 2 "symbolic_operand" "")))]
1682 "or\t%1, %%lo(%a2), %0")
1684 (define_insn "embmedany_sethi"
1685 [(set (match_operand:DI 0 "register_operand" "=r")
1686 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1687 "TARGET_CM_EMBMEDANY && check_pic (1)"
1688 "sethi\t%%hi(%a1), %0")
1690 (define_insn "embmedany_losum"
1691 [(set (match_operand:DI 0 "register_operand" "=r")
1692 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1693 (match_operand:DI 2 "data_segment_operand" "")))]
1694 "TARGET_CM_EMBMEDANY"
1695 "add\t%1, %%lo(%a2), %0")
1697 (define_insn "embmedany_brsum"
1698 [(set (match_operand:DI 0 "register_operand" "=r")
1699 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1700 "TARGET_CM_EMBMEDANY"
1703 (define_insn "embmedany_textuhi"
1704 [(set (match_operand:DI 0 "register_operand" "=r")
1705 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1706 "TARGET_CM_EMBMEDANY && check_pic (1)"
1707 "sethi\t%%uhi(%a1), %0")
1709 (define_insn "embmedany_texthi"
1710 [(set (match_operand:DI 0 "register_operand" "=r")
1711 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1712 "TARGET_CM_EMBMEDANY && check_pic (1)"
1713 "sethi\t%%hi(%a1), %0")
1715 (define_insn "embmedany_textulo"
1716 [(set (match_operand:DI 0 "register_operand" "=r")
1717 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1718 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1719 "TARGET_CM_EMBMEDANY"
1720 "or\t%1, %%ulo(%a2), %0")
1722 (define_insn "embmedany_textlo"
1723 [(set (match_operand:DI 0 "register_operand" "=r")
1724 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1725 (match_operand:DI 2 "text_segment_operand" "")))]
1726 "TARGET_CM_EMBMEDANY"
1727 "or\t%1, %%lo(%a2), %0")
1729 ;; Now some patterns to help reload out a bit.
1730 (define_expand "reload_indi"
1731 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1732 (match_operand:DI 1 "immediate_operand" "")
1733 (match_operand:TI 2 "register_operand" "=&r")])]
1735 || TARGET_CM_EMBMEDANY)
1738 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1742 (define_expand "reload_outdi"
1743 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1744 (match_operand:DI 1 "immediate_operand" "")
1745 (match_operand:TI 2 "register_operand" "=&r")])]
1747 || TARGET_CM_EMBMEDANY)
1750 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1754 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1756 [(set (match_operand:DI 0 "register_operand" "")
1757 (match_operand:DI 1 "const_int_operand" ""))]
1759 && ((GET_CODE (operands[0]) == REG
1760 && SPARC_INT_REG_P (REGNO (operands[0])))
1761 || (GET_CODE (operands[0]) == SUBREG
1762 && GET_CODE (SUBREG_REG (operands[0])) == REG
1763 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))
1764 && reload_completed"
1765 [(clobber (const_int 0))]
1767 #if HOST_BITS_PER_WIDE_INT == 32
1768 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1769 (INTVAL (operands[1]) < 0) ?
1772 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1775 unsigned int low, high;
1777 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1778 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1779 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1781 /* Slick... but this trick loses if this subreg constant part
1782 can be done in one insn. */
1784 && ! SPARC_SETHI32_P (high)
1785 && ! SPARC_SIMM13_P (high))
1786 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1787 gen_highpart (SImode, operands[0])));
1789 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1795 [(set (match_operand:DI 0 "register_operand" "")
1796 (match_operand:DI 1 "const_double_operand" ""))]
1800 && ((GET_CODE (operands[0]) == REG
1801 && SPARC_INT_REG_P (REGNO (operands[0])))
1802 || (GET_CODE (operands[0]) == SUBREG
1803 && GET_CODE (SUBREG_REG (operands[0])) == REG
1804 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
1805 [(clobber (const_int 0))]
1807 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1808 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1810 /* Slick... but this trick loses if this subreg constant part
1811 can be done in one insn. */
1812 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1813 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1814 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1816 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1817 gen_highpart (SImode, operands[0])));
1821 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1822 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1828 [(set (match_operand:DI 0 "register_operand" "")
1829 (match_operand:DI 1 "register_operand" ""))]
1833 && sparc_split_regreg_legitimate (operands[0],
1835 [(clobber (const_int 0))]
1837 rtx set_dest = operands[0];
1838 rtx set_src = operands[1];
1842 dest1 = gen_highpart (SImode, set_dest);
1843 dest2 = gen_lowpart (SImode, set_dest);
1844 src1 = gen_highpart (SImode, set_src);
1845 src2 = gen_lowpart (SImode, set_src);
1847 /* Now emit using the real source and destination we found, swapping
1848 the order if we detect overlap. */
1849 if (reg_overlap_mentioned_p (dest1, src2))
1851 emit_insn (gen_movsi (dest2, src2));
1852 emit_insn (gen_movsi (dest1, src1));
1856 emit_insn (gen_movsi (dest1, src1));
1857 emit_insn (gen_movsi (dest2, src2));
1862 ;; Now handle the cases of memory moves from/to non-even
1863 ;; DI mode register pairs.
1865 [(set (match_operand:DI 0 "register_operand" "")
1866 (match_operand:DI 1 "memory_operand" ""))]
1869 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1870 [(clobber (const_int 0))]
1872 rtx word0 = adjust_address (operands[1], SImode, 0);
1873 rtx word1 = adjust_address (operands[1], SImode, 4);
1874 rtx high_part = gen_highpart (SImode, operands[0]);
1875 rtx low_part = gen_lowpart (SImode, operands[0]);
1877 if (reg_overlap_mentioned_p (high_part, word1))
1879 emit_insn (gen_movsi (low_part, word1));
1880 emit_insn (gen_movsi (high_part, word0));
1884 emit_insn (gen_movsi (high_part, word0));
1885 emit_insn (gen_movsi (low_part, word1));
1891 [(set (match_operand:DI 0 "memory_operand" "")
1892 (match_operand:DI 1 "register_operand" ""))]
1895 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1896 [(clobber (const_int 0))]
1898 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1899 gen_highpart (SImode, operands[1])));
1900 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1901 gen_lowpart (SImode, operands[1])));
1906 [(set (match_operand:DI 0 "memory_operand" "")
1907 (match_operand:DI 1 "const_zero_operand" ""))]
1911 && ! mem_min_alignment (operands[0], 8)))
1912 && offsettable_memref_p (operands[0])"
1913 [(clobber (const_int 0))]
1915 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1916 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1921 ;; Floating point move instructions
1923 (define_expand "movsf"
1924 [(set (match_operand:SF 0 "nonimmediate_operand" "")
1925 (match_operand:SF 1 "general_operand" ""))]
1928 if (sparc_expand_move (SFmode, operands))
1932 (define_insn "*movsf_insn"
1933 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f, f,*r, m, m")
1934 (match_operand:SF 1 "input_operand" "G,C,f,*rR, Q, S, f,*r, m, m, f,*rG"))]
1935 "(register_operand (operands[0], SFmode)
1936 || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
1938 if (GET_CODE (operands[1]) == CONST_DOUBLE
1939 && (which_alternative == 3
1940 || which_alternative == 4
1941 || which_alternative == 5))
1946 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1947 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1948 operands[1] = GEN_INT (i);
1951 switch (which_alternative)
1954 return "fzeros\t%0";
1958 return "fmovs\t%1, %0";
1960 return "mov\t%1, %0";
1962 return "sethi\t%%hi(%a1), %0";
1966 return "movstouw\t%1, %0";
1968 return "movwtos\t%1, %0";
1971 return "ld\t%1, %0";
1974 return "st\t%r1, %0";
1979 [(set_attr "type" "fga,fga,fpmove,*,*,*,*,*,fpload,load,fpstore,store")
1980 (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
1982 ;; The following 3 patterns build SFmode constants in integer registers.
1984 (define_insn "*movsf_lo_sum"
1985 [(set (match_operand:SF 0 "register_operand" "=r")
1986 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
1987 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
1993 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
1994 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1995 operands[2] = GEN_INT (i);
1996 return "or\t%1, %%lo(%a2), %0";
1999 (define_insn "*movsf_high"
2000 [(set (match_operand:SF 0 "register_operand" "=r")
2001 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2007 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2008 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2009 operands[1] = GEN_INT (i);
2010 return "sethi\t%%hi(%1), %0";
2014 [(set (match_operand:SF 0 "register_operand" "")
2015 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2016 "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2017 [(set (match_dup 0) (high:SF (match_dup 1)))
2018 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2020 (define_expand "movdf"
2021 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2022 (match_operand:DF 1 "general_operand" ""))]
2025 if (sparc_expand_move (DFmode, operands))
2029 (define_insn "*movdf_insn_sp32"
2030 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f, e,T,W,U,T, f, *r, o,o")
2031 (match_operand:DF 1 "input_operand" "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roGF,*rG,f"))]
2033 && (register_operand (operands[0], DFmode)
2034 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2051 [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*")
2052 (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2")
2053 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2054 (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")])
2056 (define_insn "*movdf_insn_sp64"
2057 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r")
2058 (match_operand:DF 1 "input_operand" "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2060 && (register_operand (operands[0], DFmode)
2061 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2074 [(set_attr "type" "fga,fga,fpmove,*,*,load,store,*,load,store,*")
2075 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2076 (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2077 (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2079 ;; This pattern builds DFmode constants in integer registers.
2081 [(set (match_operand:DF 0 "register_operand" "")
2082 (match_operand:DF 1 "const_double_operand" ""))]
2084 && (GET_CODE (operands[0]) == REG
2085 && SPARC_INT_REG_P (REGNO (operands[0])))
2086 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2087 && reload_completed"
2088 [(clobber (const_int 0))]
2090 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2094 #if HOST_BITS_PER_WIDE_INT == 32
2097 enum machine_mode mode = GET_MODE (operands[1]);
2098 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2099 emit_insn (gen_movdi (operands[0], tem));
2104 enum machine_mode mode = GET_MODE (operands[1]);
2105 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2106 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2108 gcc_assert (GET_CODE (hi) == CONST_INT);
2109 gcc_assert (GET_CODE (lo) == CONST_INT);
2111 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2113 /* Slick... but this trick loses if this subreg constant part
2114 can be done in one insn. */
2116 && ! SPARC_SETHI32_P (INTVAL (hi))
2117 && ! SPARC_SIMM13_P (INTVAL (hi)))
2119 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2120 gen_highpart (SImode, operands[0])));
2124 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2130 ;; Ok, now the splits to handle all the multi insn and
2131 ;; mis-aligned memory address cases.
2132 ;; In these splits please take note that we must be
2133 ;; careful when V9 but not ARCH64 because the integer
2134 ;; register DFmode cases must be handled.
2136 [(set (match_operand:DF 0 "register_operand" "")
2137 (match_operand:DF 1 "register_operand" ""))]
2140 && sparc_split_regreg_legitimate (operands[0],
2142 && reload_completed"
2143 [(clobber (const_int 0))]
2145 rtx set_dest = operands[0];
2146 rtx set_src = operands[1];
2150 dest1 = gen_highpart (SFmode, set_dest);
2151 dest2 = gen_lowpart (SFmode, set_dest);
2152 src1 = gen_highpart (SFmode, set_src);
2153 src2 = gen_lowpart (SFmode, set_src);
2155 /* Now emit using the real source and destination we found, swapping
2156 the order if we detect overlap. */
2157 if (reg_overlap_mentioned_p (dest1, src2))
2159 emit_move_insn_1 (dest2, src2);
2160 emit_move_insn_1 (dest1, src1);
2164 emit_move_insn_1 (dest1, src1);
2165 emit_move_insn_1 (dest2, src2);
2171 [(set (match_operand:DF 0 "register_operand" "")
2172 (match_operand:DF 1 "memory_operand" ""))]
2175 && (((REGNO (operands[0]) % 2) != 0)
2176 || ! mem_min_alignment (operands[1], 8))
2177 && offsettable_memref_p (operands[1])"
2178 [(clobber (const_int 0))]
2182 word0 = adjust_address (operands[1], SFmode, 0);
2183 word1 = adjust_address (operands[1], SFmode, 4);
2185 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2187 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2188 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2192 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2193 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2199 [(set (match_operand:DF 0 "memory_operand" "")
2200 (match_operand:DF 1 "register_operand" ""))]
2203 && (((REGNO (operands[1]) % 2) != 0)
2204 || ! mem_min_alignment (operands[0], 8))
2205 && offsettable_memref_p (operands[0])"
2206 [(clobber (const_int 0))]
2210 word0 = adjust_address (operands[0], SFmode, 0);
2211 word1 = adjust_address (operands[0], SFmode, 4);
2213 emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2214 emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2219 [(set (match_operand:DF 0 "memory_operand" "")
2220 (match_operand:DF 1 "const_zero_operand" ""))]
2224 && ! mem_min_alignment (operands[0], 8)))
2225 && offsettable_memref_p (operands[0])"
2226 [(clobber (const_int 0))]
2230 dest1 = adjust_address (operands[0], SFmode, 0);
2231 dest2 = adjust_address (operands[0], SFmode, 4);
2233 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2234 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2239 [(set (match_operand:DF 0 "register_operand" "")
2240 (match_operand:DF 1 "const_zero_operand" ""))]
2243 && ((GET_CODE (operands[0]) == REG
2244 && SPARC_INT_REG_P (REGNO (operands[0])))
2245 || (GET_CODE (operands[0]) == SUBREG
2246 && GET_CODE (SUBREG_REG (operands[0])) == REG
2247 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2248 [(clobber (const_int 0))]
2250 rtx set_dest = operands[0];
2253 dest1 = gen_highpart (SFmode, set_dest);
2254 dest2 = gen_lowpart (SFmode, set_dest);
2255 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2256 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2260 (define_expand "movtf"
2261 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2262 (match_operand:TF 1 "general_operand" ""))]
2265 if (sparc_expand_move (TFmode, operands))
2269 (define_insn "*movtf_insn_sp32"
2270 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2271 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2274 && (register_operand (operands[0], TFmode)
2275 || register_or_zero_operand (operands[1], TFmode))"
2277 [(set_attr "length" "4")])
2279 ;; Exactly the same as above, except that all `e' cases are deleted.
2280 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2283 (define_insn "*movtf_insn_sp32_no_fpu"
2284 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2285 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2288 && (register_operand (operands[0], TFmode)
2289 || register_or_zero_operand (operands[1], TFmode))"
2291 [(set_attr "length" "4")])
2293 (define_insn "*movtf_insn_sp64"
2294 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2295 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2298 && ! TARGET_HARD_QUAD
2299 && (register_operand (operands[0], TFmode)
2300 || register_or_zero_operand (operands[1], TFmode))"
2302 [(set_attr "length" "2")])
2304 (define_insn "*movtf_insn_sp64_hq"
2305 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2306 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2310 && (register_operand (operands[0], TFmode)
2311 || register_or_zero_operand (operands[1], TFmode))"
2319 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2320 (set_attr "length" "2,*,*,*,2,2")])
2322 (define_insn "*movtf_insn_sp64_no_fpu"
2323 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2324 (match_operand:TF 1 "input_operand" "orG,rG"))]
2327 && (register_operand (operands[0], TFmode)
2328 || register_or_zero_operand (operands[1], TFmode))"
2330 [(set_attr "length" "2")])
2332 ;; Now all the splits to handle multi-insn TF mode moves.
2334 [(set (match_operand:TF 0 "register_operand" "")
2335 (match_operand:TF 1 "register_operand" ""))]
2339 && ! TARGET_HARD_QUAD)
2340 || (! fp_register_operand (operands[0], TFmode)
2341 && ! fp_register_operand (operands[1], TFmode)))"
2342 [(clobber (const_int 0))]
2344 rtx set_dest = operands[0];
2345 rtx set_src = operands[1];
2349 dest1 = gen_df_reg (set_dest, 0);
2350 dest2 = gen_df_reg (set_dest, 1);
2351 src1 = gen_df_reg (set_src, 0);
2352 src2 = gen_df_reg (set_src, 1);
2354 /* Now emit using the real source and destination we found, swapping
2355 the order if we detect overlap. */
2356 if (reg_overlap_mentioned_p (dest1, src2))
2358 emit_insn (gen_movdf (dest2, src2));
2359 emit_insn (gen_movdf (dest1, src1));
2363 emit_insn (gen_movdf (dest1, src1));
2364 emit_insn (gen_movdf (dest2, src2));
2370 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2371 (match_operand:TF 1 "const_zero_operand" ""))]
2373 [(clobber (const_int 0))]
2375 rtx set_dest = operands[0];
2378 switch (GET_CODE (set_dest))
2381 dest1 = gen_df_reg (set_dest, 0);
2382 dest2 = gen_df_reg (set_dest, 1);
2385 dest1 = adjust_address (set_dest, DFmode, 0);
2386 dest2 = adjust_address (set_dest, DFmode, 8);
2392 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2393 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2398 [(set (match_operand:TF 0 "register_operand" "")
2399 (match_operand:TF 1 "memory_operand" ""))]
2401 && offsettable_memref_p (operands[1])
2403 || ! TARGET_HARD_QUAD
2404 || ! fp_register_operand (operands[0], TFmode)))"
2405 [(clobber (const_int 0))]
2407 rtx word0 = adjust_address (operands[1], DFmode, 0);
2408 rtx word1 = adjust_address (operands[1], DFmode, 8);
2409 rtx set_dest, dest1, dest2;
2411 set_dest = operands[0];
2413 dest1 = gen_df_reg (set_dest, 0);
2414 dest2 = gen_df_reg (set_dest, 1);
2416 /* Now output, ordering such that we don't clobber any registers
2417 mentioned in the address. */
2418 if (reg_overlap_mentioned_p (dest1, word1))
2421 emit_insn (gen_movdf (dest2, word1));
2422 emit_insn (gen_movdf (dest1, word0));
2426 emit_insn (gen_movdf (dest1, word0));
2427 emit_insn (gen_movdf (dest2, word1));
2433 [(set (match_operand:TF 0 "memory_operand" "")
2434 (match_operand:TF 1 "register_operand" ""))]
2436 && offsettable_memref_p (operands[0])
2438 || ! TARGET_HARD_QUAD
2439 || ! fp_register_operand (operands[1], TFmode)))"
2440 [(clobber (const_int 0))]
2442 rtx set_src = operands[1];
2444 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2445 gen_df_reg (set_src, 0)));
2446 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2447 gen_df_reg (set_src, 1)));
2452 ;; SPARC-V9 conditional move instructions
2454 ;; We can handle larger constants here for some flavors, but for now we keep
2455 ;; it simple and only allow those constants supported by all flavors.
2456 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2457 ;; 3 contains the constant if one is present, but we handle either for
2458 ;; generality (sparc.c puts a constant in operand 2).
2460 ;; Our instruction patterns, on the other hand, canonicalize such that
2461 ;; operand 3 must be the set destination.
2463 (define_expand "mov<I:mode>cc"
2464 [(set (match_operand:I 0 "register_operand" "")
2465 (if_then_else:I (match_operand 1 "comparison_operator" "")
2466 (match_operand:I 2 "arith10_operand" "")
2467 (match_operand:I 3 "arith10_operand" "")))]
2468 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2470 if (! sparc_expand_conditional_move (<I:MODE>mode, operands))
2475 (define_expand "mov<F:mode>cc"
2476 [(set (match_operand:F 0 "register_operand" "")
2477 (if_then_else:F (match_operand 1 "comparison_operator" "")
2478 (match_operand:F 2 "register_operand" "")
2479 (match_operand:F 3 "register_operand" "")))]
2480 "TARGET_V9 && TARGET_FPU"
2482 if (! sparc_expand_conditional_move (<F:MODE>mode, operands))
2487 ;; Conditional move define_insns
2489 (define_insn "*mov<I:mode>_cc_v9"
2490 [(set (match_operand:I 0 "register_operand" "=r")
2491 (if_then_else:I (match_operator 1 "comparison_operator"
2492 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2494 (match_operand:I 3 "arith11_operand" "rL")
2495 (match_operand:I 4 "register_operand" "0")))]
2496 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2497 "mov%C1\t%x2, %3, %0"
2498 [(set_attr "type" "cmove")])
2500 (define_insn "*mov<I:mode>_cc_reg_sp64"
2501 [(set (match_operand:I 0 "register_operand" "=r")
2502 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2503 [(match_operand:DI 2 "register_operand" "r")
2505 (match_operand:I 3 "arith10_operand" "rM")
2506 (match_operand:I 4 "register_operand" "0")))]
2508 "movr%D1\t%2, %r3, %0"
2509 [(set_attr "type" "cmove")])
2511 (define_insn "*movsf_cc_v9"
2512 [(set (match_operand:SF 0 "register_operand" "=f")
2513 (if_then_else:SF (match_operator 1 "comparison_operator"
2514 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2516 (match_operand:SF 3 "register_operand" "f")
2517 (match_operand:SF 4 "register_operand" "0")))]
2518 "TARGET_V9 && TARGET_FPU"
2519 "fmovs%C1\t%x2, %3, %0"
2520 [(set_attr "type" "fpcmove")])
2522 (define_insn "*movsf_cc_reg_sp64"
2523 [(set (match_operand:SF 0 "register_operand" "=f")
2524 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2525 [(match_operand:DI 2 "register_operand" "r")
2527 (match_operand:SF 3 "register_operand" "f")
2528 (match_operand:SF 4 "register_operand" "0")))]
2529 "TARGET_ARCH64 && TARGET_FPU"
2530 "fmovrs%D1\t%2, %3, %0"
2531 [(set_attr "type" "fpcrmove")])
2533 ;; Named because invoked by movtf_cc_v9
2534 (define_insn "movdf_cc_v9"
2535 [(set (match_operand:DF 0 "register_operand" "=e")
2536 (if_then_else:DF (match_operator 1 "comparison_operator"
2537 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2539 (match_operand:DF 3 "register_operand" "e")
2540 (match_operand:DF 4 "register_operand" "0")))]
2541 "TARGET_V9 && TARGET_FPU"
2542 "fmovd%C1\t%x2, %3, %0"
2543 [(set_attr "type" "fpcmove")
2544 (set_attr "fptype" "double")])
2546 ;; Named because invoked by movtf_cc_reg_sp64
2547 (define_insn "movdf_cc_reg_sp64"
2548 [(set (match_operand:DF 0 "register_operand" "=e")
2549 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2550 [(match_operand:DI 2 "register_operand" "r")
2552 (match_operand:DF 3 "register_operand" "e")
2553 (match_operand:DF 4 "register_operand" "0")))]
2554 "TARGET_ARCH64 && TARGET_FPU"
2555 "fmovrd%D1\t%2, %3, %0"
2556 [(set_attr "type" "fpcrmove")
2557 (set_attr "fptype" "double")])
2559 (define_insn "*movtf_cc_hq_v9"
2560 [(set (match_operand:TF 0 "register_operand" "=e")
2561 (if_then_else:TF (match_operator 1 "comparison_operator"
2562 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2564 (match_operand:TF 3 "register_operand" "e")
2565 (match_operand:TF 4 "register_operand" "0")))]
2566 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2567 "fmovq%C1\t%x2, %3, %0"
2568 [(set_attr "type" "fpcmove")])
2570 (define_insn "*movtf_cc_reg_hq_sp64"
2571 [(set (match_operand:TF 0 "register_operand" "=e")
2572 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2573 [(match_operand:DI 2 "register_operand" "r")
2575 (match_operand:TF 3 "register_operand" "e")
2576 (match_operand:TF 4 "register_operand" "0")))]
2577 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2578 "fmovrq%D1\t%2, %3, %0"
2579 [(set_attr "type" "fpcrmove")])
2581 (define_insn_and_split "*movtf_cc_v9"
2582 [(set (match_operand:TF 0 "register_operand" "=e")
2583 (if_then_else:TF (match_operator 1 "comparison_operator"
2584 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2586 (match_operand:TF 3 "register_operand" "e")
2587 (match_operand:TF 4 "register_operand" "0")))]
2588 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2590 "&& reload_completed"
2591 [(clobber (const_int 0))]
2593 rtx set_dest = operands[0];
2594 rtx set_srca = operands[3];
2598 dest1 = gen_df_reg (set_dest, 0);
2599 dest2 = gen_df_reg (set_dest, 1);
2600 srca1 = gen_df_reg (set_srca, 0);
2601 srca2 = gen_df_reg (set_srca, 1);
2603 if (reg_overlap_mentioned_p (dest1, srca2))
2605 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2606 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2610 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2611 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2615 [(set_attr "length" "2")])
2617 (define_insn_and_split "*movtf_cc_reg_sp64"
2618 [(set (match_operand:TF 0 "register_operand" "=e")
2619 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2620 [(match_operand:DI 2 "register_operand" "r")
2622 (match_operand:TF 3 "register_operand" "e")
2623 (match_operand:TF 4 "register_operand" "0")))]
2624 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2626 "&& reload_completed"
2627 [(clobber (const_int 0))]
2629 rtx set_dest = operands[0];
2630 rtx set_srca = operands[3];
2634 dest1 = gen_df_reg (set_dest, 0);
2635 dest2 = gen_df_reg (set_dest, 1);
2636 srca1 = gen_df_reg (set_srca, 0);
2637 srca2 = gen_df_reg (set_srca, 1);
2639 if (reg_overlap_mentioned_p (dest1, srca2))
2641 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2642 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2646 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2647 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2651 [(set_attr "length" "2")])
2654 ;; Zero-extension instructions
2656 ;; These patterns originally accepted general_operands, however, slightly
2657 ;; better code is generated by only accepting register_operands, and then
2658 ;; letting combine generate the ldu[hb] insns.
2660 (define_expand "zero_extendhisi2"
2661 [(set (match_operand:SI 0 "register_operand" "")
2662 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2665 rtx temp = gen_reg_rtx (SImode);
2666 rtx shift_16 = GEN_INT (16);
2667 int op1_subbyte = 0;
2669 if (GET_CODE (operand1) == SUBREG)
2671 op1_subbyte = SUBREG_BYTE (operand1);
2672 op1_subbyte /= GET_MODE_SIZE (SImode);
2673 op1_subbyte *= GET_MODE_SIZE (SImode);
2674 operand1 = XEXP (operand1, 0);
2677 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2679 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2683 (define_insn "*zero_extendhisi2_insn"
2684 [(set (match_operand:SI 0 "register_operand" "=r")
2685 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2688 [(set_attr "type" "load")
2689 (set_attr "us3load_type" "3cycle")])
2691 (define_expand "zero_extendqihi2"
2692 [(set (match_operand:HI 0 "register_operand" "")
2693 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2697 (define_insn "*zero_extendqihi2_insn"
2698 [(set (match_operand:HI 0 "register_operand" "=r,r")
2699 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2700 "GET_CODE (operands[1]) != CONST_INT"
2704 [(set_attr "type" "*,load")
2705 (set_attr "us3load_type" "*,3cycle")])
2707 (define_expand "zero_extendqisi2"
2708 [(set (match_operand:SI 0 "register_operand" "")
2709 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2713 (define_insn "*zero_extendqisi2_insn"
2714 [(set (match_operand:SI 0 "register_operand" "=r,r")
2715 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2716 "GET_CODE (operands[1]) != CONST_INT"
2720 [(set_attr "type" "*,load")
2721 (set_attr "us3load_type" "*,3cycle")])
2723 (define_expand "zero_extendqidi2"
2724 [(set (match_operand:DI 0 "register_operand" "")
2725 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2729 (define_insn "*zero_extendqidi2_insn"
2730 [(set (match_operand:DI 0 "register_operand" "=r,r")
2731 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2732 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2736 [(set_attr "type" "*,load")
2737 (set_attr "us3load_type" "*,3cycle")])
2739 (define_expand "zero_extendhidi2"
2740 [(set (match_operand:DI 0 "register_operand" "")
2741 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2744 rtx temp = gen_reg_rtx (DImode);
2745 rtx shift_48 = GEN_INT (48);
2746 int op1_subbyte = 0;
2748 if (GET_CODE (operand1) == SUBREG)
2750 op1_subbyte = SUBREG_BYTE (operand1);
2751 op1_subbyte /= GET_MODE_SIZE (DImode);
2752 op1_subbyte *= GET_MODE_SIZE (DImode);
2753 operand1 = XEXP (operand1, 0);
2756 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2758 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2762 (define_insn "*zero_extendhidi2_insn"
2763 [(set (match_operand:DI 0 "register_operand" "=r")
2764 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2767 [(set_attr "type" "load")
2768 (set_attr "us3load_type" "3cycle")])
2770 ;; ??? Write truncdisi pattern using sra?
2772 (define_expand "zero_extendsidi2"
2773 [(set (match_operand:DI 0 "register_operand" "")
2774 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2778 (define_insn "*zero_extendsidi2_insn_sp64"
2779 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
2780 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
2782 && GET_CODE (operands[1]) != CONST_INT"
2787 [(set_attr "type" "shift,load,*")
2788 (set_attr "cpu_feature" "*,*,vis3")])
2790 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2791 [(set (match_operand:DI 0 "register_operand" "=r")
2792 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2795 "&& reload_completed"
2796 [(set (match_dup 2) (match_dup 3))
2797 (set (match_dup 4) (match_dup 5))]
2801 dest1 = gen_highpart (SImode, operands[0]);
2802 dest2 = gen_lowpart (SImode, operands[0]);
2804 /* Swap the order in case of overlap. */
2805 if (REGNO (dest1) == REGNO (operands[1]))
2807 operands[2] = dest2;
2808 operands[3] = operands[1];
2809 operands[4] = dest1;
2810 operands[5] = const0_rtx;
2814 operands[2] = dest1;
2815 operands[3] = const0_rtx;
2816 operands[4] = dest2;
2817 operands[5] = operands[1];
2820 [(set_attr "length" "2")])
2822 ;; Simplify comparisons of extended values.
2824 (define_insn "*cmp_zero_extendqisi2"
2825 [(set (reg:CC CC_REG)
2826 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2829 "andcc\t%0, 0xff, %%g0"
2830 [(set_attr "type" "compare")])
2832 (define_insn "*cmp_zero_qi"
2833 [(set (reg:CC CC_REG)
2834 (compare:CC (match_operand:QI 0 "register_operand" "r")
2837 "andcc\t%0, 0xff, %%g0"
2838 [(set_attr "type" "compare")])
2840 (define_insn "*cmp_zero_extendqisi2_set"
2841 [(set (reg:CC CC_REG)
2842 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2844 (set (match_operand:SI 0 "register_operand" "=r")
2845 (zero_extend:SI (match_dup 1)))]
2847 "andcc\t%1, 0xff, %0"
2848 [(set_attr "type" "compare")])
2850 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2851 [(set (reg:CC CC_REG)
2852 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2855 (set (match_operand:SI 0 "register_operand" "=r")
2856 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2858 "andcc\t%1, 0xff, %0"
2859 [(set_attr "type" "compare")])
2861 (define_insn "*cmp_zero_extendqidi2"
2862 [(set (reg:CCX CC_REG)
2863 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2866 "andcc\t%0, 0xff, %%g0"
2867 [(set_attr "type" "compare")])
2869 (define_insn "*cmp_zero_qi_sp64"
2870 [(set (reg:CCX CC_REG)
2871 (compare:CCX (match_operand:QI 0 "register_operand" "r")
2874 "andcc\t%0, 0xff, %%g0"
2875 [(set_attr "type" "compare")])
2877 (define_insn "*cmp_zero_extendqidi2_set"
2878 [(set (reg:CCX CC_REG)
2879 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2881 (set (match_operand:DI 0 "register_operand" "=r")
2882 (zero_extend:DI (match_dup 1)))]
2884 "andcc\t%1, 0xff, %0"
2885 [(set_attr "type" "compare")])
2887 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2888 [(set (reg:CCX CC_REG)
2889 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2892 (set (match_operand:DI 0 "register_operand" "=r")
2893 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2895 "andcc\t%1, 0xff, %0"
2896 [(set_attr "type" "compare")])
2898 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2900 (define_insn "*cmp_siqi_trunc"
2901 [(set (reg:CC CC_REG)
2902 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2905 "andcc\t%0, 0xff, %%g0"
2906 [(set_attr "type" "compare")])
2908 (define_insn "*cmp_siqi_trunc_set"
2909 [(set (reg:CC CC_REG)
2910 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
2912 (set (match_operand:QI 0 "register_operand" "=r")
2913 (subreg:QI (match_dup 1) 3))]
2915 "andcc\t%1, 0xff, %0"
2916 [(set_attr "type" "compare")])
2918 (define_insn "*cmp_diqi_trunc"
2919 [(set (reg:CC CC_REG)
2920 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
2923 "andcc\t%0, 0xff, %%g0"
2924 [(set_attr "type" "compare")])
2926 (define_insn "*cmp_diqi_trunc_set"
2927 [(set (reg:CC CC_REG)
2928 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
2930 (set (match_operand:QI 0 "register_operand" "=r")
2931 (subreg:QI (match_dup 1) 7))]
2933 "andcc\t%1, 0xff, %0"
2934 [(set_attr "type" "compare")])
2937 ;; Sign-extension instructions
2939 ;; These patterns originally accepted general_operands, however, slightly
2940 ;; better code is generated by only accepting register_operands, and then
2941 ;; letting combine generate the lds[hb] insns.
2943 (define_expand "extendhisi2"
2944 [(set (match_operand:SI 0 "register_operand" "")
2945 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2948 rtx temp = gen_reg_rtx (SImode);
2949 rtx shift_16 = GEN_INT (16);
2950 int op1_subbyte = 0;
2952 if (GET_CODE (operand1) == SUBREG)
2954 op1_subbyte = SUBREG_BYTE (operand1);
2955 op1_subbyte /= GET_MODE_SIZE (SImode);
2956 op1_subbyte *= GET_MODE_SIZE (SImode);
2957 operand1 = XEXP (operand1, 0);
2960 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2962 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
2966 (define_insn "*sign_extendhisi2_insn"
2967 [(set (match_operand:SI 0 "register_operand" "=r")
2968 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2971 [(set_attr "type" "sload")
2972 (set_attr "us3load_type" "3cycle")])
2974 (define_expand "extendqihi2"
2975 [(set (match_operand:HI 0 "register_operand" "")
2976 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
2979 rtx temp = gen_reg_rtx (SImode);
2980 rtx shift_24 = GEN_INT (24);
2981 int op1_subbyte = 0;
2982 int op0_subbyte = 0;
2984 if (GET_CODE (operand1) == SUBREG)
2986 op1_subbyte = SUBREG_BYTE (operand1);
2987 op1_subbyte /= GET_MODE_SIZE (SImode);
2988 op1_subbyte *= GET_MODE_SIZE (SImode);
2989 operand1 = XEXP (operand1, 0);
2991 if (GET_CODE (operand0) == SUBREG)
2993 op0_subbyte = SUBREG_BYTE (operand0);
2994 op0_subbyte /= GET_MODE_SIZE (SImode);
2995 op0_subbyte *= GET_MODE_SIZE (SImode);
2996 operand0 = XEXP (operand0, 0);
2998 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3000 if (GET_MODE (operand0) != SImode)
3001 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3002 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3006 (define_insn "*sign_extendqihi2_insn"
3007 [(set (match_operand:HI 0 "register_operand" "=r")
3008 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3011 [(set_attr "type" "sload")
3012 (set_attr "us3load_type" "3cycle")])
3014 (define_expand "extendqisi2"
3015 [(set (match_operand:SI 0 "register_operand" "")
3016 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3019 rtx temp = gen_reg_rtx (SImode);
3020 rtx shift_24 = GEN_INT (24);
3021 int op1_subbyte = 0;
3023 if (GET_CODE (operand1) == SUBREG)
3025 op1_subbyte = SUBREG_BYTE (operand1);
3026 op1_subbyte /= GET_MODE_SIZE (SImode);
3027 op1_subbyte *= GET_MODE_SIZE (SImode);
3028 operand1 = XEXP (operand1, 0);
3031 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3033 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3037 (define_insn "*sign_extendqisi2_insn"
3038 [(set (match_operand:SI 0 "register_operand" "=r")
3039 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3042 [(set_attr "type" "sload")
3043 (set_attr "us3load_type" "3cycle")])
3045 (define_expand "extendqidi2"
3046 [(set (match_operand:DI 0 "register_operand" "")
3047 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3050 rtx temp = gen_reg_rtx (DImode);
3051 rtx shift_56 = GEN_INT (56);
3052 int op1_subbyte = 0;
3054 if (GET_CODE (operand1) == SUBREG)
3056 op1_subbyte = SUBREG_BYTE (operand1);
3057 op1_subbyte /= GET_MODE_SIZE (DImode);
3058 op1_subbyte *= GET_MODE_SIZE (DImode);
3059 operand1 = XEXP (operand1, 0);
3062 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3064 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3068 (define_insn "*sign_extendqidi2_insn"
3069 [(set (match_operand:DI 0 "register_operand" "=r")
3070 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3073 [(set_attr "type" "sload")
3074 (set_attr "us3load_type" "3cycle")])
3076 (define_expand "extendhidi2"
3077 [(set (match_operand:DI 0 "register_operand" "")
3078 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3081 rtx temp = gen_reg_rtx (DImode);
3082 rtx shift_48 = GEN_INT (48);
3083 int op1_subbyte = 0;
3085 if (GET_CODE (operand1) == SUBREG)
3087 op1_subbyte = SUBREG_BYTE (operand1);
3088 op1_subbyte /= GET_MODE_SIZE (DImode);
3089 op1_subbyte *= GET_MODE_SIZE (DImode);
3090 operand1 = XEXP (operand1, 0);
3093 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3095 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3099 (define_insn "*sign_extendhidi2_insn"
3100 [(set (match_operand:DI 0 "register_operand" "=r")
3101 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3104 [(set_attr "type" "sload")
3105 (set_attr "us3load_type" "3cycle")])
3107 (define_expand "extendsidi2"
3108 [(set (match_operand:DI 0 "register_operand" "")
3109 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3113 (define_insn "*sign_extendsidi2_insn"
3114 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3115 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3121 [(set_attr "type" "shift,sload,*")
3122 (set_attr "us3load_type" "*,3cycle,*")
3123 (set_attr "cpu_feature" "*,*,vis3")])
3126 ;; Special pattern for optimizing bit-field compares. This is needed
3127 ;; because combine uses this as a canonical form.
3129 (define_insn "*cmp_zero_extract"
3130 [(set (reg:CC CC_REG)
3132 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3133 (match_operand:SI 1 "small_int_operand" "I")
3134 (match_operand:SI 2 "small_int_operand" "I"))
3136 "INTVAL (operands[2]) > 19"
3138 int len = INTVAL (operands[1]);
3139 int pos = 32 - INTVAL (operands[2]) - len;
3140 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3141 operands[1] = GEN_INT (mask);
3142 return "andcc\t%0, %1, %%g0";
3144 [(set_attr "type" "compare")])
3146 (define_insn "*cmp_zero_extract_sp64"
3147 [(set (reg:CCX CC_REG)
3149 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3150 (match_operand:SI 1 "small_int_operand" "I")
3151 (match_operand:SI 2 "small_int_operand" "I"))
3153 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3155 int len = INTVAL (operands[1]);
3156 int pos = 64 - INTVAL (operands[2]) - len;
3157 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3158 operands[1] = GEN_INT (mask);
3159 return "andcc\t%0, %1, %%g0";
3161 [(set_attr "type" "compare")])
3164 ;; Conversions between float, double and long double.
3166 (define_insn "extendsfdf2"
3167 [(set (match_operand:DF 0 "register_operand" "=e")
3169 (match_operand:SF 1 "register_operand" "f")))]
3172 [(set_attr "type" "fp")
3173 (set_attr "fptype" "double")])
3175 (define_expand "extendsftf2"
3176 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3178 (match_operand:SF 1 "register_operand" "")))]
3179 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3180 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3182 (define_insn "*extendsftf2_hq"
3183 [(set (match_operand:TF 0 "register_operand" "=e")
3185 (match_operand:SF 1 "register_operand" "f")))]
3186 "TARGET_FPU && TARGET_HARD_QUAD"
3188 [(set_attr "type" "fp")])
3190 (define_expand "extenddftf2"
3191 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3193 (match_operand:DF 1 "register_operand" "")))]
3194 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3195 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3197 (define_insn "*extenddftf2_hq"
3198 [(set (match_operand:TF 0 "register_operand" "=e")
3200 (match_operand:DF 1 "register_operand" "e")))]
3201 "TARGET_FPU && TARGET_HARD_QUAD"
3203 [(set_attr "type" "fp")])
3205 (define_insn "truncdfsf2"
3206 [(set (match_operand:SF 0 "register_operand" "=f")
3208 (match_operand:DF 1 "register_operand" "e")))]
3211 [(set_attr "type" "fp")
3212 (set_attr "fptype" "double")])
3214 (define_expand "trunctfsf2"
3215 [(set (match_operand:SF 0 "register_operand" "")
3217 (match_operand:TF 1 "general_operand" "")))]
3218 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3219 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3221 (define_insn "*trunctfsf2_hq"
3222 [(set (match_operand:SF 0 "register_operand" "=f")
3224 (match_operand:TF 1 "register_operand" "e")))]
3225 "TARGET_FPU && TARGET_HARD_QUAD"
3227 [(set_attr "type" "fp")])
3229 (define_expand "trunctfdf2"
3230 [(set (match_operand:DF 0 "register_operand" "")
3232 (match_operand:TF 1 "general_operand" "")))]
3233 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3234 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3236 (define_insn "*trunctfdf2_hq"
3237 [(set (match_operand:DF 0 "register_operand" "=e")
3239 (match_operand:TF 1 "register_operand" "e")))]
3240 "TARGET_FPU && TARGET_HARD_QUAD"
3242 [(set_attr "type" "fp")])
3245 ;; Conversion between fixed point and floating point.
3247 (define_insn "floatsisf2"
3248 [(set (match_operand:SF 0 "register_operand" "=f")
3249 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3252 [(set_attr "type" "fp")
3253 (set_attr "fptype" "double")])
3255 (define_insn "floatsidf2"
3256 [(set (match_operand:DF 0 "register_operand" "=e")
3257 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3260 [(set_attr "type" "fp")
3261 (set_attr "fptype" "double")])
3263 (define_expand "floatsitf2"
3264 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3265 (float:TF (match_operand:SI 1 "register_operand" "")))]
3266 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3267 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3269 (define_insn "*floatsitf2_hq"
3270 [(set (match_operand:TF 0 "register_operand" "=e")
3271 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3272 "TARGET_FPU && TARGET_HARD_QUAD"
3274 [(set_attr "type" "fp")])
3276 (define_expand "floatunssitf2"
3277 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3278 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3279 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3280 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3282 ;; Now the same for 64 bit sources.
3284 (define_insn "floatdisf2"
3285 [(set (match_operand:SF 0 "register_operand" "=f")
3286 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3287 "TARGET_V9 && TARGET_FPU"
3289 [(set_attr "type" "fp")
3290 (set_attr "fptype" "double")])
3292 (define_expand "floatunsdisf2"
3293 [(use (match_operand:SF 0 "register_operand" ""))
3294 (use (match_operand:DI 1 "general_operand" ""))]
3295 "TARGET_ARCH64 && TARGET_FPU"
3296 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3298 (define_insn "floatdidf2"
3299 [(set (match_operand:DF 0 "register_operand" "=e")
3300 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3301 "TARGET_V9 && TARGET_FPU"
3303 [(set_attr "type" "fp")
3304 (set_attr "fptype" "double")])
3306 (define_expand "floatunsdidf2"
3307 [(use (match_operand:DF 0 "register_operand" ""))
3308 (use (match_operand:DI 1 "general_operand" ""))]
3309 "TARGET_ARCH64 && TARGET_FPU"
3310 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3312 (define_expand "floatditf2"
3313 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3314 (float:TF (match_operand:DI 1 "register_operand" "")))]
3315 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3316 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3318 (define_insn "*floatditf2_hq"
3319 [(set (match_operand:TF 0 "register_operand" "=e")
3320 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3321 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3323 [(set_attr "type" "fp")])
3325 (define_expand "floatunsditf2"
3326 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3327 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3328 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3329 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3331 ;; Convert a float to an actual integer.
3332 ;; Truncation is performed as part of the conversion.
3334 (define_insn "fix_truncsfsi2"
3335 [(set (match_operand:SI 0 "register_operand" "=f")
3336 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3339 [(set_attr "type" "fp")
3340 (set_attr "fptype" "double")])
3342 (define_insn "fix_truncdfsi2"
3343 [(set (match_operand:SI 0 "register_operand" "=f")
3344 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3347 [(set_attr "type" "fp")
3348 (set_attr "fptype" "double")])
3350 (define_expand "fix_trunctfsi2"
3351 [(set (match_operand:SI 0 "register_operand" "")
3352 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3353 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3354 "emit_tfmode_cvt (FIX, operands); DONE;")
3356 (define_insn "*fix_trunctfsi2_hq"
3357 [(set (match_operand:SI 0 "register_operand" "=f")
3358 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3359 "TARGET_FPU && TARGET_HARD_QUAD"
3361 [(set_attr "type" "fp")])
3363 (define_expand "fixuns_trunctfsi2"
3364 [(set (match_operand:SI 0 "register_operand" "")
3365 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3366 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3367 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3369 ;; Now the same, for V9 targets
3371 (define_insn "fix_truncsfdi2"
3372 [(set (match_operand:DI 0 "register_operand" "=e")
3373 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3374 "TARGET_V9 && TARGET_FPU"
3376 [(set_attr "type" "fp")
3377 (set_attr "fptype" "double")])
3379 (define_expand "fixuns_truncsfdi2"
3380 [(use (match_operand:DI 0 "register_operand" ""))
3381 (use (match_operand:SF 1 "general_operand" ""))]
3382 "TARGET_ARCH64 && TARGET_FPU"
3383 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3385 (define_insn "fix_truncdfdi2"
3386 [(set (match_operand:DI 0 "register_operand" "=e")
3387 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3388 "TARGET_V9 && TARGET_FPU"
3390 [(set_attr "type" "fp")
3391 (set_attr "fptype" "double")])
3393 (define_expand "fixuns_truncdfdi2"
3394 [(use (match_operand:DI 0 "register_operand" ""))
3395 (use (match_operand:DF 1 "general_operand" ""))]
3396 "TARGET_ARCH64 && TARGET_FPU"
3397 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3399 (define_expand "fix_trunctfdi2"
3400 [(set (match_operand:DI 0 "register_operand" "")
3401 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3402 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3403 "emit_tfmode_cvt (FIX, operands); DONE;")
3405 (define_insn "*fix_trunctfdi2_hq"
3406 [(set (match_operand:DI 0 "register_operand" "=e")
3407 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3408 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3410 [(set_attr "type" "fp")])
3412 (define_expand "fixuns_trunctfdi2"
3413 [(set (match_operand:DI 0 "register_operand" "")
3414 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3415 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3416 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3419 ;; Integer addition/subtraction instructions.
3421 (define_expand "adddi3"
3422 [(set (match_operand:DI 0 "register_operand" "")
3423 (plus:DI (match_operand:DI 1 "register_operand" "")
3424 (match_operand:DI 2 "arith_double_add_operand" "")))]
3427 if (! TARGET_ARCH64)
3429 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3430 gen_rtx_SET (VOIDmode, operands[0],
3431 gen_rtx_PLUS (DImode, operands[1],
3433 gen_rtx_CLOBBER (VOIDmode,
3434 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3439 (define_insn_and_split "*adddi3_insn_sp32"
3440 [(set (match_operand:DI 0 "register_operand" "=r")
3441 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3442 (match_operand:DI 2 "arith_double_operand" "rHI")))
3443 (clobber (reg:CC CC_REG))]
3446 "&& reload_completed"
3447 [(parallel [(set (reg:CC_NOOV CC_REG)
3448 (compare:CC_NOOV (plus:SI (match_dup 4)
3452 (plus:SI (match_dup 4) (match_dup 5)))])
3454 (plus:SI (plus:SI (match_dup 7)
3456 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3458 operands[3] = gen_lowpart (SImode, operands[0]);
3459 operands[4] = gen_lowpart (SImode, operands[1]);
3460 operands[5] = gen_lowpart (SImode, operands[2]);
3461 operands[6] = gen_highpart (SImode, operands[0]);
3462 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3463 #if HOST_BITS_PER_WIDE_INT == 32
3464 if (GET_CODE (operands[2]) == CONST_INT)
3466 if (INTVAL (operands[2]) < 0)
3467 operands[8] = constm1_rtx;
3469 operands[8] = const0_rtx;
3473 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3475 [(set_attr "length" "2")])
3477 ;; LTU here means "carry set"
3479 [(set (match_operand:SI 0 "register_operand" "=r")
3480 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3481 (match_operand:SI 2 "arith_operand" "rI"))
3482 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3485 [(set_attr "type" "ialuX")])
3487 (define_insn_and_split "*addx_extend_sp32"
3488 [(set (match_operand:DI 0 "register_operand" "=r")
3489 (zero_extend:DI (plus:SI (plus:SI
3490 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3491 (match_operand:SI 2 "arith_operand" "rI"))
3492 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3495 "&& reload_completed"
3496 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3497 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3498 (set (match_dup 4) (const_int 0))]
3499 "operands[3] = gen_lowpart (SImode, operands[0]);
3500 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3501 [(set_attr "length" "2")])
3503 (define_insn "*addx_extend_sp64"
3504 [(set (match_operand:DI 0 "register_operand" "=r")
3505 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3506 (match_operand:SI 2 "arith_operand" "rI"))
3507 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3510 [(set_attr "type" "ialuX")])
3512 (define_insn_and_split "*adddi3_extend_sp32"
3513 [(set (match_operand:DI 0 "register_operand" "=r")
3514 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3515 (match_operand:DI 2 "register_operand" "r")))
3516 (clobber (reg:CC CC_REG))]
3519 "&& reload_completed"
3520 [(parallel [(set (reg:CC_NOOV CC_REG)
3521 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3523 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3525 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3526 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3527 "operands[3] = gen_lowpart (SImode, operands[2]);
3528 operands[4] = gen_highpart (SImode, operands[2]);
3529 operands[5] = gen_lowpart (SImode, operands[0]);
3530 operands[6] = gen_highpart (SImode, operands[0]);"
3531 [(set_attr "length" "2")])
3533 (define_insn "*adddi3_sp64"
3534 [(set (match_operand:DI 0 "register_operand" "=r,r")
3535 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3536 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3542 (define_insn "addsi3"
3543 [(set (match_operand:SI 0 "register_operand" "=r,r")
3544 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3545 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3550 [(set_attr "type" "*,*")
3551 (set_attr "fptype" "*,*")])
3553 (define_insn "*cmp_cc_plus"
3554 [(set (reg:CC_NOOV CC_REG)
3555 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3556 (match_operand:SI 1 "arith_operand" "rI"))
3559 "addcc\t%0, %1, %%g0"
3560 [(set_attr "type" "compare")])
3562 (define_insn "*cmp_ccx_plus"
3563 [(set (reg:CCX_NOOV CC_REG)
3564 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3565 (match_operand:DI 1 "arith_operand" "rI"))
3568 "addcc\t%0, %1, %%g0"
3569 [(set_attr "type" "compare")])
3571 (define_insn "*cmp_cc_plus_set"
3572 [(set (reg:CC_NOOV CC_REG)
3573 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3574 (match_operand:SI 2 "arith_operand" "rI"))
3576 (set (match_operand:SI 0 "register_operand" "=r")
3577 (plus:SI (match_dup 1) (match_dup 2)))]
3580 [(set_attr "type" "compare")])
3582 (define_insn "*cmp_ccx_plus_set"
3583 [(set (reg:CCX_NOOV CC_REG)
3584 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3585 (match_operand:DI 2 "arith_operand" "rI"))
3587 (set (match_operand:DI 0 "register_operand" "=r")
3588 (plus:DI (match_dup 1) (match_dup 2)))]
3591 [(set_attr "type" "compare")])
3593 (define_expand "subdi3"
3594 [(set (match_operand:DI 0 "register_operand" "")
3595 (minus:DI (match_operand:DI 1 "register_operand" "")
3596 (match_operand:DI 2 "arith_double_add_operand" "")))]
3599 if (! TARGET_ARCH64)
3601 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3602 gen_rtx_SET (VOIDmode, operands[0],
3603 gen_rtx_MINUS (DImode, operands[1],
3605 gen_rtx_CLOBBER (VOIDmode,
3606 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3611 (define_insn_and_split "*subdi3_insn_sp32"
3612 [(set (match_operand:DI 0 "register_operand" "=r")
3613 (minus:DI (match_operand:DI 1 "register_operand" "r")
3614 (match_operand:DI 2 "arith_double_operand" "rHI")))
3615 (clobber (reg:CC CC_REG))]
3618 "&& reload_completed"
3619 [(parallel [(set (reg:CC_NOOV CC_REG)
3620 (compare:CC_NOOV (minus:SI (match_dup 4)
3624 (minus:SI (match_dup 4) (match_dup 5)))])
3626 (minus:SI (minus:SI (match_dup 7)
3628 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3630 operands[3] = gen_lowpart (SImode, operands[0]);
3631 operands[4] = gen_lowpart (SImode, operands[1]);
3632 operands[5] = gen_lowpart (SImode, operands[2]);
3633 operands[6] = gen_highpart (SImode, operands[0]);
3634 operands[7] = gen_highpart (SImode, operands[1]);
3635 #if HOST_BITS_PER_WIDE_INT == 32
3636 if (GET_CODE (operands[2]) == CONST_INT)
3638 if (INTVAL (operands[2]) < 0)
3639 operands[8] = constm1_rtx;
3641 operands[8] = const0_rtx;
3645 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3647 [(set_attr "length" "2")])
3649 ;; LTU here means "carry set"
3651 [(set (match_operand:SI 0 "register_operand" "=r")
3652 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3653 (match_operand:SI 2 "arith_operand" "rI"))
3654 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3657 [(set_attr "type" "ialuX")])
3659 (define_insn "*subx_extend_sp64"
3660 [(set (match_operand:DI 0 "register_operand" "=r")
3661 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3662 (match_operand:SI 2 "arith_operand" "rI"))
3663 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3666 [(set_attr "type" "ialuX")])
3668 (define_insn_and_split "*subx_extend"
3669 [(set (match_operand:DI 0 "register_operand" "=r")
3670 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3671 (match_operand:SI 2 "arith_operand" "rI"))
3672 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3675 "&& reload_completed"
3676 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3677 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3678 (set (match_dup 4) (const_int 0))]
3679 "operands[3] = gen_lowpart (SImode, operands[0]);
3680 operands[4] = gen_highpart (SImode, operands[0]);"
3681 [(set_attr "length" "2")])
3683 (define_insn_and_split "*subdi3_extend_sp32"
3684 [(set (match_operand:DI 0 "register_operand" "=r")
3685 (minus:DI (match_operand:DI 1 "register_operand" "r")
3686 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3687 (clobber (reg:CC CC_REG))]
3690 "&& reload_completed"
3691 [(parallel [(set (reg:CC_NOOV CC_REG)
3692 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3694 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3696 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3697 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3698 "operands[3] = gen_lowpart (SImode, operands[1]);
3699 operands[4] = gen_highpart (SImode, operands[1]);
3700 operands[5] = gen_lowpart (SImode, operands[0]);
3701 operands[6] = gen_highpart (SImode, operands[0]);"
3702 [(set_attr "length" "2")])
3704 (define_insn "*subdi3_sp64"
3705 [(set (match_operand:DI 0 "register_operand" "=r,r")
3706 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3707 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3713 (define_insn "subsi3"
3714 [(set (match_operand:SI 0 "register_operand" "=r,r")
3715 (minus:SI (match_operand:SI 1 "register_operand" "r,r")
3716 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3721 [(set_attr "type" "*,*")
3722 (set_attr "fptype" "*,*")])
3724 (define_insn "*cmp_minus_cc"
3725 [(set (reg:CC_NOOV CC_REG)
3726 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3727 (match_operand:SI 1 "arith_operand" "rI"))
3730 "subcc\t%r0, %1, %%g0"
3731 [(set_attr "type" "compare")])
3733 (define_insn "*cmp_minus_ccx"
3734 [(set (reg:CCX_NOOV CC_REG)
3735 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3736 (match_operand:DI 1 "arith_operand" "rI"))
3739 "subcc\t%0, %1, %%g0"
3740 [(set_attr "type" "compare")])
3742 (define_insn "cmp_minus_cc_set"
3743 [(set (reg:CC_NOOV CC_REG)
3744 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3745 (match_operand:SI 2 "arith_operand" "rI"))
3747 (set (match_operand:SI 0 "register_operand" "=r")
3748 (minus:SI (match_dup 1) (match_dup 2)))]
3750 "subcc\t%r1, %2, %0"
3751 [(set_attr "type" "compare")])
3753 (define_insn "*cmp_minus_ccx_set"
3754 [(set (reg:CCX_NOOV CC_REG)
3755 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3756 (match_operand:DI 2 "arith_operand" "rI"))
3758 (set (match_operand:DI 0 "register_operand" "=r")
3759 (minus:DI (match_dup 1) (match_dup 2)))]
3762 [(set_attr "type" "compare")])
3765 ;; Integer multiply/divide instructions.
3767 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3768 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3770 (define_insn "mulsi3"
3771 [(set (match_operand:SI 0 "register_operand" "=r")
3772 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3773 (match_operand:SI 2 "arith_operand" "rI")))]
3776 [(set_attr "type" "imul")])
3778 (define_expand "muldi3"
3779 [(set (match_operand:DI 0 "register_operand" "")
3780 (mult:DI (match_operand:DI 1 "arith_operand" "")
3781 (match_operand:DI 2 "arith_operand" "")))]
3782 "TARGET_ARCH64 || TARGET_V8PLUS"
3786 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3791 (define_insn "*muldi3_sp64"
3792 [(set (match_operand:DI 0 "register_operand" "=r")
3793 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3794 (match_operand:DI 2 "arith_operand" "rI")))]
3797 [(set_attr "type" "imul")])
3799 ;; V8plus wide multiply.
3801 (define_insn "muldi3_v8plus"
3802 [(set (match_operand:DI 0 "register_operand" "=r,h")
3803 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3804 (match_operand:DI 2 "arith_operand" "rI,rI")))
3805 (clobber (match_scratch:SI 3 "=&h,X"))
3806 (clobber (match_scratch:SI 4 "=&h,X"))]
3808 "* return output_v8plus_mult (insn, operands, \"mulx\");"
3809 [(set_attr "type" "multi")
3810 (set_attr "length" "9,8")])
3812 (define_insn "*cmp_mul_set"
3813 [(set (reg:CC CC_REG)
3814 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3815 (match_operand:SI 2 "arith_operand" "rI"))
3817 (set (match_operand:SI 0 "register_operand" "=r")
3818 (mult:SI (match_dup 1) (match_dup 2)))]
3819 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3820 "smulcc\t%1, %2, %0"
3821 [(set_attr "type" "imul")])
3823 (define_expand "mulsidi3"
3824 [(set (match_operand:DI 0 "register_operand" "")
3825 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3826 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3829 if (CONSTANT_P (operands[2]))
3832 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3834 else if (TARGET_ARCH32)
3835 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3838 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3844 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3849 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
3850 ;; registers can hold 64-bit values in the V8plus environment.
3852 (define_insn "mulsidi3_v8plus"
3853 [(set (match_operand:DI 0 "register_operand" "=h,r")
3854 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3855 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3856 (clobber (match_scratch:SI 3 "=X,&h"))]
3859 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3860 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3861 [(set_attr "type" "multi")
3862 (set_attr "length" "2,3")])
3865 (define_insn "const_mulsidi3_v8plus"
3866 [(set (match_operand:DI 0 "register_operand" "=h,r")
3867 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3868 (match_operand:DI 2 "small_int_operand" "I,I")))
3869 (clobber (match_scratch:SI 3 "=X,&h"))]
3872 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3873 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3874 [(set_attr "type" "multi")
3875 (set_attr "length" "2,3")])
3878 (define_insn "*mulsidi3_sp32"
3879 [(set (match_operand:DI 0 "register_operand" "=r")
3880 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3881 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3884 return TARGET_SPARCLET
3885 ? "smuld\t%1, %2, %L0"
3886 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3889 (if_then_else (eq_attr "isa" "sparclet")
3890 (const_string "imul") (const_string "multi")))
3891 (set (attr "length")
3892 (if_then_else (eq_attr "isa" "sparclet")
3893 (const_int 1) (const_int 2)))])
3895 (define_insn "*mulsidi3_sp64"
3896 [(set (match_operand:DI 0 "register_operand" "=r")
3897 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3898 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3899 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
3901 [(set_attr "type" "imul")])
3903 ;; Extra pattern, because sign_extend of a constant isn't valid.
3906 (define_insn "const_mulsidi3_sp32"
3907 [(set (match_operand:DI 0 "register_operand" "=r")
3908 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3909 (match_operand:DI 2 "small_int_operand" "I")))]
3912 return TARGET_SPARCLET
3913 ? "smuld\t%1, %2, %L0"
3914 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3917 (if_then_else (eq_attr "isa" "sparclet")
3918 (const_string "imul") (const_string "multi")))
3919 (set (attr "length")
3920 (if_then_else (eq_attr "isa" "sparclet")
3921 (const_int 1) (const_int 2)))])
3923 (define_insn "const_mulsidi3_sp64"
3924 [(set (match_operand:DI 0 "register_operand" "=r")
3925 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3926 (match_operand:DI 2 "small_int_operand" "I")))]
3927 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
3929 [(set_attr "type" "imul")])
3931 (define_expand "smulsi3_highpart"
3932 [(set (match_operand:SI 0 "register_operand" "")
3934 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3935 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
3937 "TARGET_HARD_MUL && TARGET_ARCH32"
3939 if (CONSTANT_P (operands[2]))
3943 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
3949 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
3954 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
3955 operands[2], GEN_INT (32)));
3961 (define_insn "smulsi3_highpart_v8plus"
3962 [(set (match_operand:SI 0 "register_operand" "=h,r")
3964 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3965 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
3966 (match_operand:SI 3 "small_int_operand" "I,I"))))
3967 (clobber (match_scratch:SI 4 "=X,&h"))]
3970 smul\t%1, %2, %0\;srlx\t%0, %3, %0
3971 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
3972 [(set_attr "type" "multi")
3973 (set_attr "length" "2")])
3975 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
3978 [(set (match_operand:SI 0 "register_operand" "=h,r")
3981 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3982 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
3983 (match_operand:SI 3 "small_int_operand" "I,I"))
3985 (clobber (match_scratch:SI 4 "=X,&h"))]
3988 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
3989 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
3990 [(set_attr "type" "multi")
3991 (set_attr "length" "2")])
3994 (define_insn "const_smulsi3_highpart_v8plus"
3995 [(set (match_operand:SI 0 "register_operand" "=h,r")
3997 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3998 (match_operand:DI 2 "small_int_operand" "I,I"))
3999 (match_operand:SI 3 "small_int_operand" "I,I"))))
4000 (clobber (match_scratch:SI 4 "=X,&h"))]
4003 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4004 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4005 [(set_attr "type" "multi")
4006 (set_attr "length" "2")])
4009 (define_insn "*smulsi3_highpart_sp32"
4010 [(set (match_operand:SI 0 "register_operand" "=r")
4012 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4013 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4016 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4017 [(set_attr "type" "multi")
4018 (set_attr "length" "2")])
4021 (define_insn "const_smulsi3_highpart"
4022 [(set (match_operand:SI 0 "register_operand" "=r")
4024 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4025 (match_operand:DI 2 "small_int_operand" "i"))
4028 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4029 [(set_attr "type" "multi")
4030 (set_attr "length" "2")])
4032 (define_expand "umulsidi3"
4033 [(set (match_operand:DI 0 "register_operand" "")
4034 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4035 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4038 if (CONSTANT_P (operands[2]))
4041 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4043 else if (TARGET_ARCH32)
4044 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4047 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4053 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4059 (define_insn "umulsidi3_v8plus"
4060 [(set (match_operand:DI 0 "register_operand" "=h,r")
4061 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4062 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4063 (clobber (match_scratch:SI 3 "=X,&h"))]
4066 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4067 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4068 [(set_attr "type" "multi")
4069 (set_attr "length" "2,3")])
4072 (define_insn "*umulsidi3_sp32"
4073 [(set (match_operand:DI 0 "register_operand" "=r")
4074 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4075 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4078 return TARGET_SPARCLET
4079 ? "umuld\t%1, %2, %L0"
4080 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4083 (if_then_else (eq_attr "isa" "sparclet")
4084 (const_string "imul") (const_string "multi")))
4085 (set (attr "length")
4086 (if_then_else (eq_attr "isa" "sparclet")
4087 (const_int 1) (const_int 2)))])
4089 (define_insn "*umulsidi3_sp64"
4090 [(set (match_operand:DI 0 "register_operand" "=r")
4091 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4092 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4093 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4095 [(set_attr "type" "imul")])
4097 ;; Extra pattern, because sign_extend of a constant isn't valid.
4100 (define_insn "const_umulsidi3_sp32"
4101 [(set (match_operand:DI 0 "register_operand" "=r")
4102 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4103 (match_operand:DI 2 "uns_small_int_operand" "")))]
4106 return TARGET_SPARCLET
4107 ? "umuld\t%1, %s2, %L0"
4108 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4111 (if_then_else (eq_attr "isa" "sparclet")
4112 (const_string "imul") (const_string "multi")))
4113 (set (attr "length")
4114 (if_then_else (eq_attr "isa" "sparclet")
4115 (const_int 1) (const_int 2)))])
4117 (define_insn "const_umulsidi3_sp64"
4118 [(set (match_operand:DI 0 "register_operand" "=r")
4119 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4120 (match_operand:DI 2 "uns_small_int_operand" "")))]
4121 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4123 [(set_attr "type" "imul")])
4126 (define_insn "const_umulsidi3_v8plus"
4127 [(set (match_operand:DI 0 "register_operand" "=h,r")
4128 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4129 (match_operand:DI 2 "uns_small_int_operand" "")))
4130 (clobber (match_scratch:SI 3 "=X,h"))]
4133 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4134 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4135 [(set_attr "type" "multi")
4136 (set_attr "length" "2,3")])
4138 (define_expand "umulsi3_highpart"
4139 [(set (match_operand:SI 0 "register_operand" "")
4141 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4142 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4144 "TARGET_HARD_MUL && TARGET_ARCH32"
4146 if (CONSTANT_P (operands[2]))
4150 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4156 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4161 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4162 operands[2], GEN_INT (32)));
4168 (define_insn "umulsi3_highpart_v8plus"
4169 [(set (match_operand:SI 0 "register_operand" "=h,r")
4171 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4172 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4173 (match_operand:SI 3 "small_int_operand" "I,I"))))
4174 (clobber (match_scratch:SI 4 "=X,h"))]
4177 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4178 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4179 [(set_attr "type" "multi")
4180 (set_attr "length" "2")])
4183 (define_insn "const_umulsi3_highpart_v8plus"
4184 [(set (match_operand:SI 0 "register_operand" "=h,r")
4186 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4187 (match_operand:DI 2 "uns_small_int_operand" ""))
4188 (match_operand:SI 3 "small_int_operand" "I,I"))))
4189 (clobber (match_scratch:SI 4 "=X,h"))]
4192 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4193 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4194 [(set_attr "type" "multi")
4195 (set_attr "length" "2")])
4198 (define_insn "*umulsi3_highpart_sp32"
4199 [(set (match_operand:SI 0 "register_operand" "=r")
4201 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4202 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4205 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4206 [(set_attr "type" "multi")
4207 (set_attr "length" "2")])
4210 (define_insn "const_umulsi3_highpart"
4211 [(set (match_operand:SI 0 "register_operand" "=r")
4213 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4214 (match_operand:DI 2 "uns_small_int_operand" ""))
4217 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4218 [(set_attr "type" "multi")
4219 (set_attr "length" "2")])
4221 (define_expand "divsi3"
4222 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4223 (div:SI (match_operand:SI 1 "register_operand" "")
4224 (match_operand:SI 2 "input_operand" "")))
4225 (clobber (match_scratch:SI 3 ""))])]
4226 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4230 operands[3] = gen_reg_rtx(SImode);
4231 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4232 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4238 ;; The V8 architecture specifies that there must be at least 3 instructions
4239 ;; between a write to the Y register and a use of it for correct results.
4240 ;; We try to fill one of them with a simple constant or a memory load.
4242 (define_insn "divsi3_sp32"
4243 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4244 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4245 (match_operand:SI 2 "input_operand" "rI,K,m")))
4246 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4247 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4249 output_asm_insn ("sra\t%1, 31, %3", operands);
4250 output_asm_insn ("wr\t%3, 0, %%y", operands);
4252 switch (which_alternative)
4256 return "sdiv\t%1, %2, %0";
4258 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4261 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4263 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4266 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4268 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4273 [(set_attr "type" "multi")
4274 (set (attr "length")
4275 (if_then_else (eq_attr "isa" "v9")
4276 (const_int 4) (const_int 6)))])
4278 (define_insn "divsi3_sp64"
4279 [(set (match_operand:SI 0 "register_operand" "=r")
4280 (div:SI (match_operand:SI 1 "register_operand" "r")
4281 (match_operand:SI 2 "input_operand" "rI")))
4282 (use (match_operand:SI 3 "register_operand" "r"))]
4283 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4284 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4285 [(set_attr "type" "multi")
4286 (set_attr "length" "2")])
4288 (define_insn "divdi3"
4289 [(set (match_operand:DI 0 "register_operand" "=r")
4290 (div:DI (match_operand:DI 1 "register_operand" "r")
4291 (match_operand:DI 2 "arith_operand" "rI")))]
4294 [(set_attr "type" "idiv")])
4296 (define_insn "*cmp_sdiv_cc_set"
4297 [(set (reg:CC CC_REG)
4298 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4299 (match_operand:SI 2 "arith_operand" "rI"))
4301 (set (match_operand:SI 0 "register_operand" "=r")
4302 (div:SI (match_dup 1) (match_dup 2)))
4303 (clobber (match_scratch:SI 3 "=&r"))]
4304 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4306 output_asm_insn ("sra\t%1, 31, %3", operands);
4307 output_asm_insn ("wr\t%3, 0, %%y", operands);
4310 return "sdivcc\t%1, %2, %0";
4312 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4314 [(set_attr "type" "multi")
4315 (set (attr "length")
4316 (if_then_else (eq_attr "isa" "v9")
4317 (const_int 3) (const_int 6)))])
4320 (define_expand "udivsi3"
4321 [(set (match_operand:SI 0 "register_operand" "")
4322 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4323 (match_operand:SI 2 "input_operand" "")))]
4324 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4327 ;; The V8 architecture specifies that there must be at least 3 instructions
4328 ;; between a write to the Y register and a use of it for correct results.
4329 ;; We try to fill one of them with a simple constant or a memory load.
4331 (define_insn "udivsi3_sp32"
4332 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4333 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4334 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4335 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4337 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4339 switch (which_alternative)
4343 return "udiv\t%1, %2, %0";
4345 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4348 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4350 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4353 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4355 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4358 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4360 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4365 [(set_attr "type" "multi")
4366 (set (attr "length")
4367 (if_then_else (eq_attr "isa" "v9")
4368 (const_int 3) (const_int 5)))])
4370 (define_insn "udivsi3_sp64"
4371 [(set (match_operand:SI 0 "register_operand" "=r")
4372 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4373 (match_operand:SI 2 "input_operand" "rI")))]
4374 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4375 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4376 [(set_attr "type" "multi")
4377 (set_attr "length" "2")])
4379 (define_insn "udivdi3"
4380 [(set (match_operand:DI 0 "register_operand" "=r")
4381 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4382 (match_operand:DI 2 "arith_operand" "rI")))]
4385 [(set_attr "type" "idiv")])
4387 (define_insn "*cmp_udiv_cc_set"
4388 [(set (reg:CC CC_REG)
4389 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4390 (match_operand:SI 2 "arith_operand" "rI"))
4392 (set (match_operand:SI 0 "register_operand" "=r")
4393 (udiv:SI (match_dup 1) (match_dup 2)))]
4394 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4396 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4399 return "udivcc\t%1, %2, %0";
4401 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4403 [(set_attr "type" "multi")
4404 (set (attr "length")
4405 (if_then_else (eq_attr "isa" "v9")
4406 (const_int 2) (const_int 5)))])
4408 ; sparclet multiply/accumulate insns
4410 (define_insn "*smacsi"
4411 [(set (match_operand:SI 0 "register_operand" "=r")
4412 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4413 (match_operand:SI 2 "arith_operand" "rI"))
4414 (match_operand:SI 3 "register_operand" "0")))]
4417 [(set_attr "type" "imul")])
4419 (define_insn "*smacdi"
4420 [(set (match_operand:DI 0 "register_operand" "=r")
4421 (plus:DI (mult:DI (sign_extend:DI
4422 (match_operand:SI 1 "register_operand" "%r"))
4424 (match_operand:SI 2 "register_operand" "r")))
4425 (match_operand:DI 3 "register_operand" "0")))]
4427 "smacd\t%1, %2, %L0"
4428 [(set_attr "type" "imul")])
4430 (define_insn "*umacdi"
4431 [(set (match_operand:DI 0 "register_operand" "=r")
4432 (plus:DI (mult:DI (zero_extend:DI
4433 (match_operand:SI 1 "register_operand" "%r"))
4435 (match_operand:SI 2 "register_operand" "r")))
4436 (match_operand:DI 3 "register_operand" "0")))]
4438 "umacd\t%1, %2, %L0"
4439 [(set_attr "type" "imul")])
4442 ;; Boolean instructions.
4444 ;; We define DImode `and' so with DImode `not' we can get
4445 ;; DImode `andn'. Other combinations are possible.
4447 (define_expand "anddi3"
4448 [(set (match_operand:DI 0 "register_operand" "")
4449 (and:DI (match_operand:DI 1 "arith_double_operand" "")
4450 (match_operand:DI 2 "arith_double_operand" "")))]
4454 (define_insn "*anddi3_sp32"
4455 [(set (match_operand:DI 0 "register_operand" "=r")
4456 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4457 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4461 (define_insn "*anddi3_sp64"
4462 [(set (match_operand:DI 0 "register_operand" "=r")
4463 (and:DI (match_operand:DI 1 "arith_operand" "%r")
4464 (match_operand:DI 2 "arith_operand" "rI")))]
4468 (define_insn "andsi3"
4469 [(set (match_operand:SI 0 "register_operand" "=r")
4470 (and:SI (match_operand:SI 1 "arith_operand" "%r")
4471 (match_operand:SI 2 "arith_operand" "rI")))]
4476 [(set (match_operand:SI 0 "register_operand" "")
4477 (and:SI (match_operand:SI 1 "register_operand" "")
4478 (match_operand:SI 2 "const_compl_high_operand" "")))
4479 (clobber (match_operand:SI 3 "register_operand" ""))]
4481 [(set (match_dup 3) (match_dup 4))
4482 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4484 operands[4] = GEN_INT (~INTVAL (operands[2]));
4487 (define_insn_and_split "*and_not_di_sp32"
4488 [(set (match_operand:DI 0 "register_operand" "=r")
4489 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4490 (match_operand:DI 2 "register_operand" "r")))]
4493 "&& reload_completed
4494 && ((GET_CODE (operands[0]) == REG
4495 && SPARC_INT_REG_P (REGNO (operands[0])))
4496 || (GET_CODE (operands[0]) == SUBREG
4497 && GET_CODE (SUBREG_REG (operands[0])) == REG
4498 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4499 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4500 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4501 "operands[3] = gen_highpart (SImode, operands[0]);
4502 operands[4] = gen_highpart (SImode, operands[1]);
4503 operands[5] = gen_highpart (SImode, operands[2]);
4504 operands[6] = gen_lowpart (SImode, operands[0]);
4505 operands[7] = gen_lowpart (SImode, operands[1]);
4506 operands[8] = gen_lowpart (SImode, operands[2]);"
4507 [(set_attr "length" "2")])
4509 (define_insn "*and_not_di_sp64"
4510 [(set (match_operand:DI 0 "register_operand" "=r")
4511 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4512 (match_operand:DI 2 "register_operand" "r")))]
4516 (define_insn "*and_not_si"
4517 [(set (match_operand:SI 0 "register_operand" "=r")
4518 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4519 (match_operand:SI 2 "register_operand" "r")))]
4523 (define_expand "iordi3"
4524 [(set (match_operand:DI 0 "register_operand" "")
4525 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4526 (match_operand:DI 2 "arith_double_operand" "")))]
4530 (define_insn "*iordi3_sp32"
4531 [(set (match_operand:DI 0 "register_operand" "=r")
4532 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4533 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4536 [(set_attr "length" "2")])
4538 (define_insn "*iordi3_sp64"
4539 [(set (match_operand:DI 0 "register_operand" "=r")
4540 (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4541 (match_operand:DI 2 "arith_operand" "rI")))]
4545 (define_insn "iorsi3"
4546 [(set (match_operand:SI 0 "register_operand" "=r")
4547 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4548 (match_operand:SI 2 "arith_operand" "rI")))]
4553 [(set (match_operand:SI 0 "register_operand" "")
4554 (ior:SI (match_operand:SI 1 "register_operand" "")
4555 (match_operand:SI 2 "const_compl_high_operand" "")))
4556 (clobber (match_operand:SI 3 "register_operand" ""))]
4558 [(set (match_dup 3) (match_dup 4))
4559 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4561 operands[4] = GEN_INT (~INTVAL (operands[2]));
4564 (define_insn_and_split "*or_not_di_sp32"
4565 [(set (match_operand:DI 0 "register_operand" "=r")
4566 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4567 (match_operand:DI 2 "register_operand" "r")))]
4570 "&& reload_completed
4571 && ((GET_CODE (operands[0]) == REG
4572 && SPARC_INT_REG_P (REGNO (operands[0])))
4573 || (GET_CODE (operands[0]) == SUBREG
4574 && GET_CODE (SUBREG_REG (operands[0])) == REG
4575 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4576 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4577 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4578 "operands[3] = gen_highpart (SImode, operands[0]);
4579 operands[4] = gen_highpart (SImode, operands[1]);
4580 operands[5] = gen_highpart (SImode, operands[2]);
4581 operands[6] = gen_lowpart (SImode, operands[0]);
4582 operands[7] = gen_lowpart (SImode, operands[1]);
4583 operands[8] = gen_lowpart (SImode, operands[2]);"
4584 [(set_attr "length" "2")])
4586 (define_insn "*or_not_di_sp64"
4587 [(set (match_operand:DI 0 "register_operand" "=r")
4588 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4589 (match_operand:DI 2 "register_operand" "r")))]
4593 (define_insn "*or_not_si"
4594 [(set (match_operand:SI 0 "register_operand" "=r")
4595 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4596 (match_operand:SI 2 "register_operand" "r")))]
4600 (define_expand "xordi3"
4601 [(set (match_operand:DI 0 "register_operand" "")
4602 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4603 (match_operand:DI 2 "arith_double_operand" "")))]
4607 (define_insn "*xordi3_sp32"
4608 [(set (match_operand:DI 0 "register_operand" "=r")
4609 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4610 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4613 [(set_attr "length" "2")])
4615 (define_insn "*xordi3_sp64"
4616 [(set (match_operand:DI 0 "register_operand" "=r")
4617 (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4618 (match_operand:DI 2 "arith_operand" "rI")))]
4622 (define_insn "xorsi3"
4623 [(set (match_operand:SI 0 "register_operand" "=r")
4624 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4625 (match_operand:SI 2 "arith_operand" "rI")))]
4630 [(set (match_operand:SI 0 "register_operand" "")
4631 (xor:SI (match_operand:SI 1 "register_operand" "")
4632 (match_operand:SI 2 "const_compl_high_operand" "")))
4633 (clobber (match_operand:SI 3 "register_operand" ""))]
4635 [(set (match_dup 3) (match_dup 4))
4636 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4638 operands[4] = GEN_INT (~INTVAL (operands[2]));
4642 [(set (match_operand:SI 0 "register_operand" "")
4643 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4644 (match_operand:SI 2 "const_compl_high_operand" ""))))
4645 (clobber (match_operand:SI 3 "register_operand" ""))]
4647 [(set (match_dup 3) (match_dup 4))
4648 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4650 operands[4] = GEN_INT (~INTVAL (operands[2]));
4653 ;; Split DImode logical operations requiring two instructions.
4655 [(set (match_operand:DI 0 "register_operand" "")
4656 (match_operator:DI 1 "cc_arith_operator" ; AND, IOR, XOR
4657 [(match_operand:DI 2 "register_operand" "")
4658 (match_operand:DI 3 "arith_double_operand" "")]))]
4661 && ((GET_CODE (operands[0]) == REG
4662 && SPARC_INT_REG_P (REGNO (operands[0])))
4663 || (GET_CODE (operands[0]) == SUBREG
4664 && GET_CODE (SUBREG_REG (operands[0])) == REG
4665 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4666 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4667 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4669 operands[4] = gen_highpart (SImode, operands[0]);
4670 operands[5] = gen_lowpart (SImode, operands[0]);
4671 operands[6] = gen_highpart (SImode, operands[2]);
4672 operands[7] = gen_lowpart (SImode, operands[2]);
4673 #if HOST_BITS_PER_WIDE_INT == 32
4674 if (GET_CODE (operands[3]) == CONST_INT)
4676 if (INTVAL (operands[3]) < 0)
4677 operands[8] = constm1_rtx;
4679 operands[8] = const0_rtx;
4683 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
4684 operands[9] = gen_lowpart (SImode, operands[3]);
4687 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4688 ;; Combine now canonicalizes to the rightmost expression.
4689 (define_insn_and_split "*xor_not_di_sp32"
4690 [(set (match_operand:DI 0 "register_operand" "=r")
4691 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
4692 (match_operand:DI 2 "register_operand" "r"))))]
4695 "&& reload_completed
4696 && ((GET_CODE (operands[0]) == REG
4697 && SPARC_INT_REG_P (REGNO (operands[0])))
4698 || (GET_CODE (operands[0]) == SUBREG
4699 && GET_CODE (SUBREG_REG (operands[0])) == REG
4700 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4701 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4702 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4703 "operands[3] = gen_highpart (SImode, operands[0]);
4704 operands[4] = gen_highpart (SImode, operands[1]);
4705 operands[5] = gen_highpart (SImode, operands[2]);
4706 operands[6] = gen_lowpart (SImode, operands[0]);
4707 operands[7] = gen_lowpart (SImode, operands[1]);
4708 operands[8] = gen_lowpart (SImode, operands[2]);"
4709 [(set_attr "length" "2")])
4711 (define_insn "*xor_not_di_sp64"
4712 [(set (match_operand:DI 0 "register_operand" "=r")
4713 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4714 (match_operand:DI 2 "arith_operand" "rI"))))]
4716 "xnor\t%r1, %2, %0")
4718 (define_insn "*xor_not_si"
4719 [(set (match_operand:SI 0 "register_operand" "=r")
4720 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4721 (match_operand:SI 2 "arith_operand" "rI"))))]
4723 "xnor\t%r1, %2, %0")
4725 ;; These correspond to the above in the case where we also (or only)
4726 ;; want to set the condition code.
4728 (define_insn "*cmp_cc_arith_op"
4729 [(set (reg:CC CC_REG)
4731 (match_operator:SI 2 "cc_arith_operator"
4732 [(match_operand:SI 0 "arith_operand" "%r")
4733 (match_operand:SI 1 "arith_operand" "rI")])
4736 "%A2cc\t%0, %1, %%g0"
4737 [(set_attr "type" "compare")])
4739 (define_insn "*cmp_ccx_arith_op"
4740 [(set (reg:CCX CC_REG)
4742 (match_operator:DI 2 "cc_arith_operator"
4743 [(match_operand:DI 0 "arith_operand" "%r")
4744 (match_operand:DI 1 "arith_operand" "rI")])
4747 "%A2cc\t%0, %1, %%g0"
4748 [(set_attr "type" "compare")])
4750 (define_insn "*cmp_cc_arith_op_set"
4751 [(set (reg:CC CC_REG)
4753 (match_operator:SI 3 "cc_arith_operator"
4754 [(match_operand:SI 1 "arith_operand" "%r")
4755 (match_operand:SI 2 "arith_operand" "rI")])
4757 (set (match_operand:SI 0 "register_operand" "=r")
4758 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4759 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4761 [(set_attr "type" "compare")])
4763 (define_insn "*cmp_ccx_arith_op_set"
4764 [(set (reg:CCX CC_REG)
4766 (match_operator:DI 3 "cc_arith_operator"
4767 [(match_operand:DI 1 "arith_operand" "%r")
4768 (match_operand:DI 2 "arith_operand" "rI")])
4770 (set (match_operand:DI 0 "register_operand" "=r")
4771 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4772 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4774 [(set_attr "type" "compare")])
4776 (define_insn "*cmp_cc_xor_not"
4777 [(set (reg:CC CC_REG)
4779 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4780 (match_operand:SI 1 "arith_operand" "rI")))
4783 "xnorcc\t%r0, %1, %%g0"
4784 [(set_attr "type" "compare")])
4786 (define_insn "*cmp_ccx_xor_not"
4787 [(set (reg:CCX CC_REG)
4789 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4790 (match_operand:DI 1 "arith_operand" "rI")))
4793 "xnorcc\t%r0, %1, %%g0"
4794 [(set_attr "type" "compare")])
4796 (define_insn "*cmp_cc_xor_not_set"
4797 [(set (reg:CC CC_REG)
4799 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4800 (match_operand:SI 2 "arith_operand" "rI")))
4802 (set (match_operand:SI 0 "register_operand" "=r")
4803 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4805 "xnorcc\t%r1, %2, %0"
4806 [(set_attr "type" "compare")])
4808 (define_insn "*cmp_ccx_xor_not_set"
4809 [(set (reg:CCX CC_REG)
4811 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4812 (match_operand:DI 2 "arith_operand" "rI")))
4814 (set (match_operand:DI 0 "register_operand" "=r")
4815 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4817 "xnorcc\t%r1, %2, %0"
4818 [(set_attr "type" "compare")])
4820 (define_insn "*cmp_cc_arith_op_not"
4821 [(set (reg:CC CC_REG)
4823 (match_operator:SI 2 "cc_arith_not_operator"
4824 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4825 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
4828 "%B2cc\t%r1, %0, %%g0"
4829 [(set_attr "type" "compare")])
4831 (define_insn "*cmp_ccx_arith_op_not"
4832 [(set (reg:CCX CC_REG)
4834 (match_operator:DI 2 "cc_arith_not_operator"
4835 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
4836 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
4839 "%B2cc\t%r1, %0, %%g0"
4840 [(set_attr "type" "compare")])
4842 (define_insn "*cmp_cc_arith_op_not_set"
4843 [(set (reg:CC CC_REG)
4845 (match_operator:SI 3 "cc_arith_not_operator"
4846 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
4847 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
4849 (set (match_operand:SI 0 "register_operand" "=r")
4850 (match_operator:SI 4 "cc_arith_not_operator"
4851 [(not:SI (match_dup 1)) (match_dup 2)]))]
4852 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4853 "%B3cc\t%r2, %1, %0"
4854 [(set_attr "type" "compare")])
4856 (define_insn "*cmp_ccx_arith_op_not_set"
4857 [(set (reg:CCX CC_REG)
4859 (match_operator:DI 3 "cc_arith_not_operator"
4860 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
4861 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
4863 (set (match_operand:DI 0 "register_operand" "=r")
4864 (match_operator:DI 4 "cc_arith_not_operator"
4865 [(not:DI (match_dup 1)) (match_dup 2)]))]
4866 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4867 "%B3cc\t%r2, %1, %0"
4868 [(set_attr "type" "compare")])
4870 ;; We cannot use the "neg" pseudo insn because the Sun assembler
4871 ;; does not know how to make it work for constants.
4873 (define_expand "negdi2"
4874 [(set (match_operand:DI 0 "register_operand" "=r")
4875 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4878 if (! TARGET_ARCH64)
4880 emit_insn (gen_rtx_PARALLEL
4883 gen_rtx_SET (VOIDmode, operand0,
4884 gen_rtx_NEG (DImode, operand1)),
4885 gen_rtx_CLOBBER (VOIDmode,
4886 gen_rtx_REG (CCmode,
4892 (define_insn_and_split "*negdi2_sp32"
4893 [(set (match_operand:DI 0 "register_operand" "=r")
4894 (neg:DI (match_operand:DI 1 "register_operand" "r")))
4895 (clobber (reg:CC CC_REG))]
4898 "&& reload_completed"
4899 [(parallel [(set (reg:CC_NOOV CC_REG)
4900 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
4902 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
4903 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4904 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
4905 "operands[2] = gen_highpart (SImode, operands[0]);
4906 operands[3] = gen_highpart (SImode, operands[1]);
4907 operands[4] = gen_lowpart (SImode, operands[0]);
4908 operands[5] = gen_lowpart (SImode, operands[1]);"
4909 [(set_attr "length" "2")])
4911 (define_insn "*negdi2_sp64"
4912 [(set (match_operand:DI 0 "register_operand" "=r")
4913 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4915 "sub\t%%g0, %1, %0")
4917 (define_insn "negsi2"
4918 [(set (match_operand:SI 0 "register_operand" "=r")
4919 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
4921 "sub\t%%g0, %1, %0")
4923 (define_insn "*cmp_cc_neg"
4924 [(set (reg:CC_NOOV CC_REG)
4925 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
4928 "subcc\t%%g0, %0, %%g0"
4929 [(set_attr "type" "compare")])
4931 (define_insn "*cmp_ccx_neg"
4932 [(set (reg:CCX_NOOV CC_REG)
4933 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
4936 "subcc\t%%g0, %0, %%g0"
4937 [(set_attr "type" "compare")])
4939 (define_insn "*cmp_cc_set_neg"
4940 [(set (reg:CC_NOOV CC_REG)
4941 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
4943 (set (match_operand:SI 0 "register_operand" "=r")
4944 (neg:SI (match_dup 1)))]
4946 "subcc\t%%g0, %1, %0"
4947 [(set_attr "type" "compare")])
4949 (define_insn "*cmp_ccx_set_neg"
4950 [(set (reg:CCX_NOOV CC_REG)
4951 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
4953 (set (match_operand:DI 0 "register_operand" "=r")
4954 (neg:DI (match_dup 1)))]
4956 "subcc\t%%g0, %1, %0"
4957 [(set_attr "type" "compare")])
4959 ;; We cannot use the "not" pseudo insn because the Sun assembler
4960 ;; does not know how to make it work for constants.
4961 (define_expand "one_cmpldi2"
4962 [(set (match_operand:DI 0 "register_operand" "")
4963 (not:DI (match_operand:DI 1 "register_operand" "")))]
4967 (define_insn_and_split "*one_cmpldi2_sp32"
4968 [(set (match_operand:DI 0 "register_operand" "=r")
4969 (not:DI (match_operand:DI 1 "register_operand" "r")))]
4972 "&& reload_completed
4973 && ((GET_CODE (operands[0]) == REG
4974 && SPARC_INT_REG_P (REGNO (operands[0])))
4975 || (GET_CODE (operands[0]) == SUBREG
4976 && GET_CODE (SUBREG_REG (operands[0])) == REG
4977 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4978 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
4979 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
4980 "operands[2] = gen_highpart (SImode, operands[0]);
4981 operands[3] = gen_highpart (SImode, operands[1]);
4982 operands[4] = gen_lowpart (SImode, operands[0]);
4983 operands[5] = gen_lowpart (SImode, operands[1]);"
4984 [(set_attr "length" "2")])
4986 (define_insn "*one_cmpldi2_sp64"
4987 [(set (match_operand:DI 0 "register_operand" "=r")
4988 (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
4990 "xnor\t%%g0, %1, %0")
4992 (define_insn "one_cmplsi2"
4993 [(set (match_operand:SI 0 "register_operand" "=r")
4994 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
4996 "xnor\t%%g0, %1, %0")
4998 (define_insn "*cmp_cc_not"
4999 [(set (reg:CC CC_REG)
5000 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5003 "xnorcc\t%%g0, %0, %%g0"
5004 [(set_attr "type" "compare")])
5006 (define_insn "*cmp_ccx_not"
5007 [(set (reg:CCX CC_REG)
5008 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5011 "xnorcc\t%%g0, %0, %%g0"
5012 [(set_attr "type" "compare")])
5014 (define_insn "*cmp_cc_set_not"
5015 [(set (reg:CC CC_REG)
5016 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5018 (set (match_operand:SI 0 "register_operand" "=r")
5019 (not:SI (match_dup 1)))]
5021 "xnorcc\t%%g0, %1, %0"
5022 [(set_attr "type" "compare")])
5024 (define_insn "*cmp_ccx_set_not"
5025 [(set (reg:CCX CC_REG)
5026 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5028 (set (match_operand:DI 0 "register_operand" "=r")
5029 (not:DI (match_dup 1)))]
5031 "xnorcc\t%%g0, %1, %0"
5032 [(set_attr "type" "compare")])
5034 (define_insn "*cmp_cc_set"
5035 [(set (match_operand:SI 0 "register_operand" "=r")
5036 (match_operand:SI 1 "register_operand" "r"))
5037 (set (reg:CC CC_REG)
5038 (compare:CC (match_dup 1)
5042 [(set_attr "type" "compare")])
5044 (define_insn "*cmp_ccx_set64"
5045 [(set (match_operand:DI 0 "register_operand" "=r")
5046 (match_operand:DI 1 "register_operand" "r"))
5047 (set (reg:CCX CC_REG)
5048 (compare:CCX (match_dup 1)
5052 [(set_attr "type" "compare")])
5055 ;; Floating point arithmetic instructions.
5057 (define_expand "addtf3"
5058 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5059 (plus:TF (match_operand:TF 1 "general_operand" "")
5060 (match_operand:TF 2 "general_operand" "")))]
5061 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5062 "emit_tfmode_binop (PLUS, operands); DONE;")
5064 (define_insn "*addtf3_hq"
5065 [(set (match_operand:TF 0 "register_operand" "=e")
5066 (plus:TF (match_operand:TF 1 "register_operand" "e")
5067 (match_operand:TF 2 "register_operand" "e")))]
5068 "TARGET_FPU && TARGET_HARD_QUAD"
5070 [(set_attr "type" "fp")])
5072 (define_insn "adddf3"
5073 [(set (match_operand:DF 0 "register_operand" "=e")
5074 (plus:DF (match_operand:DF 1 "register_operand" "e")
5075 (match_operand:DF 2 "register_operand" "e")))]
5078 [(set_attr "type" "fp")
5079 (set_attr "fptype" "double")])
5081 (define_insn "addsf3"
5082 [(set (match_operand:SF 0 "register_operand" "=f")
5083 (plus:SF (match_operand:SF 1 "register_operand" "f")
5084 (match_operand:SF 2 "register_operand" "f")))]
5087 [(set_attr "type" "fp")])
5089 (define_expand "subtf3"
5090 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5091 (minus:TF (match_operand:TF 1 "general_operand" "")
5092 (match_operand:TF 2 "general_operand" "")))]
5093 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5094 "emit_tfmode_binop (MINUS, operands); DONE;")
5096 (define_insn "*subtf3_hq"
5097 [(set (match_operand:TF 0 "register_operand" "=e")
5098 (minus:TF (match_operand:TF 1 "register_operand" "e")
5099 (match_operand:TF 2 "register_operand" "e")))]
5100 "TARGET_FPU && TARGET_HARD_QUAD"
5102 [(set_attr "type" "fp")])
5104 (define_insn "subdf3"
5105 [(set (match_operand:DF 0 "register_operand" "=e")
5106 (minus:DF (match_operand:DF 1 "register_operand" "e")
5107 (match_operand:DF 2 "register_operand" "e")))]
5110 [(set_attr "type" "fp")
5111 (set_attr "fptype" "double")])
5113 (define_insn "subsf3"
5114 [(set (match_operand:SF 0 "register_operand" "=f")
5115 (minus:SF (match_operand:SF 1 "register_operand" "f")
5116 (match_operand:SF 2 "register_operand" "f")))]
5119 [(set_attr "type" "fp")])
5121 (define_expand "multf3"
5122 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5123 (mult:TF (match_operand:TF 1 "general_operand" "")
5124 (match_operand:TF 2 "general_operand" "")))]
5125 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5126 "emit_tfmode_binop (MULT, operands); DONE;")
5128 (define_insn "*multf3_hq"
5129 [(set (match_operand:TF 0 "register_operand" "=e")
5130 (mult:TF (match_operand:TF 1 "register_operand" "e")
5131 (match_operand:TF 2 "register_operand" "e")))]
5132 "TARGET_FPU && TARGET_HARD_QUAD"
5134 [(set_attr "type" "fpmul")])
5136 (define_insn "muldf3"
5137 [(set (match_operand:DF 0 "register_operand" "=e")
5138 (mult:DF (match_operand:DF 1 "register_operand" "e")
5139 (match_operand:DF 2 "register_operand" "e")))]
5142 [(set_attr "type" "fpmul")
5143 (set_attr "fptype" "double")])
5145 (define_insn "mulsf3"
5146 [(set (match_operand:SF 0 "register_operand" "=f")
5147 (mult:SF (match_operand:SF 1 "register_operand" "f")
5148 (match_operand:SF 2 "register_operand" "f")))]
5151 [(set_attr "type" "fpmul")])
5153 (define_insn "fmadf4"
5154 [(set (match_operand:DF 0 "register_operand" "=e")
5155 (fma:DF (match_operand:DF 1 "register_operand" "e")
5156 (match_operand:DF 2 "register_operand" "e")
5157 (match_operand:DF 3 "register_operand" "e")))]
5159 "fmaddd\t%1, %2, %3, %0"
5160 [(set_attr "type" "fpmul")])
5162 (define_insn "fmsdf4"
5163 [(set (match_operand:DF 0 "register_operand" "=e")
5164 (fma:DF (match_operand:DF 1 "register_operand" "e")
5165 (match_operand:DF 2 "register_operand" "e")
5166 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5168 "fmsubd\t%1, %2, %3, %0"
5169 [(set_attr "type" "fpmul")])
5171 (define_insn "*nfmadf4"
5172 [(set (match_operand:DF 0 "register_operand" "=e")
5173 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5174 (match_operand:DF 2 "register_operand" "e")
5175 (match_operand:DF 3 "register_operand" "e"))))]
5177 "fnmaddd\t%1, %2, %3, %0"
5178 [(set_attr "type" "fpmul")])
5180 (define_insn "*nfmsdf4"
5181 [(set (match_operand:DF 0 "register_operand" "=e")
5182 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5183 (match_operand:DF 2 "register_operand" "e")
5184 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5186 "fnmsubd\t%1, %2, %3, %0"
5187 [(set_attr "type" "fpmul")])
5189 (define_insn "fmasf4"
5190 [(set (match_operand:SF 0 "register_operand" "=f")
5191 (fma:SF (match_operand:SF 1 "register_operand" "f")
5192 (match_operand:SF 2 "register_operand" "f")
5193 (match_operand:SF 3 "register_operand" "f")))]
5195 "fmadds\t%1, %2, %3, %0"
5196 [(set_attr "type" "fpmul")])
5198 (define_insn "fmssf4"
5199 [(set (match_operand:SF 0 "register_operand" "=f")
5200 (fma:SF (match_operand:SF 1 "register_operand" "f")
5201 (match_operand:SF 2 "register_operand" "f")
5202 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5204 "fmsubs\t%1, %2, %3, %0"
5205 [(set_attr "type" "fpmul")])
5207 (define_insn "*nfmasf4"
5208 [(set (match_operand:SF 0 "register_operand" "=f")
5209 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5210 (match_operand:SF 2 "register_operand" "f")
5211 (match_operand:SF 3 "register_operand" "f"))))]
5213 "fnmadds\t%1, %2, %3, %0"
5214 [(set_attr "type" "fpmul")])
5216 (define_insn "*nfmssf4"
5217 [(set (match_operand:SF 0 "register_operand" "=f")
5218 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5219 (match_operand:SF 2 "register_operand" "f")
5220 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5222 "fnmsubs\t%1, %2, %3, %0"
5223 [(set_attr "type" "fpmul")])
5225 (define_insn "*muldf3_extend"
5226 [(set (match_operand:DF 0 "register_operand" "=e")
5227 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5228 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5229 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5230 "fsmuld\t%1, %2, %0"
5231 [(set_attr "type" "fpmul")
5232 (set_attr "fptype" "double")])
5234 (define_insn "*multf3_extend"
5235 [(set (match_operand:TF 0 "register_operand" "=e")
5236 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5237 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5238 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5239 "fdmulq\t%1, %2, %0"
5240 [(set_attr "type" "fpmul")])
5242 (define_expand "divtf3"
5243 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5244 (div:TF (match_operand:TF 1 "general_operand" "")
5245 (match_operand:TF 2 "general_operand" "")))]
5246 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5247 "emit_tfmode_binop (DIV, operands); DONE;")
5249 ;; don't have timing for quad-prec. divide.
5250 (define_insn "*divtf3_hq"
5251 [(set (match_operand:TF 0 "register_operand" "=e")
5252 (div:TF (match_operand:TF 1 "register_operand" "e")
5253 (match_operand:TF 2 "register_operand" "e")))]
5254 "TARGET_FPU && TARGET_HARD_QUAD"
5256 [(set_attr "type" "fpdivd")])
5258 (define_insn "divdf3"
5259 [(set (match_operand:DF 0 "register_operand" "=e")
5260 (div:DF (match_operand:DF 1 "register_operand" "e")
5261 (match_operand:DF 2 "register_operand" "e")))]
5264 [(set_attr "type" "fpdivd")
5265 (set_attr "fptype" "double")])
5267 (define_insn "divsf3"
5268 [(set (match_operand:SF 0 "register_operand" "=f")
5269 (div:SF (match_operand:SF 1 "register_operand" "f")
5270 (match_operand:SF 2 "register_operand" "f")))]
5273 [(set_attr "type" "fpdivs")])
5275 (define_expand "negtf2"
5276 [(set (match_operand:TF 0 "register_operand" "=e,e")
5277 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5281 (define_insn_and_split "*negtf2_notv9"
5282 [(set (match_operand:TF 0 "register_operand" "=e,e")
5283 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5284 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5290 "&& reload_completed
5291 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5292 [(set (match_dup 2) (neg:SF (match_dup 3)))
5293 (set (match_dup 4) (match_dup 5))
5294 (set (match_dup 6) (match_dup 7))]
5295 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5296 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5297 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5298 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5299 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5300 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5301 [(set_attr "type" "fpmove,*")
5302 (set_attr "length" "*,2")])
5304 (define_insn_and_split "*negtf2_v9"
5305 [(set (match_operand:TF 0 "register_operand" "=e,e")
5306 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5307 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5308 "TARGET_FPU && TARGET_V9"
5312 "&& reload_completed
5313 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5314 [(set (match_dup 2) (neg:DF (match_dup 3)))
5315 (set (match_dup 4) (match_dup 5))]
5316 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5317 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5318 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5319 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5320 [(set_attr "type" "fpmove,*")
5321 (set_attr "length" "*,2")
5322 (set_attr "fptype" "double")])
5324 (define_expand "negdf2"
5325 [(set (match_operand:DF 0 "register_operand" "")
5326 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5330 (define_insn_and_split "*negdf2_notv9"
5331 [(set (match_operand:DF 0 "register_operand" "=e,e")
5332 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5333 "TARGET_FPU && ! TARGET_V9"
5337 "&& reload_completed
5338 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5339 [(set (match_dup 2) (neg:SF (match_dup 3)))
5340 (set (match_dup 4) (match_dup 5))]
5341 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5342 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5343 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5344 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5345 [(set_attr "type" "fpmove,*")
5346 (set_attr "length" "*,2")])
5348 (define_insn "*negdf2_v9"
5349 [(set (match_operand:DF 0 "register_operand" "=e")
5350 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5351 "TARGET_FPU && TARGET_V9"
5353 [(set_attr "type" "fpmove")
5354 (set_attr "fptype" "double")])
5356 (define_insn "negsf2"
5357 [(set (match_operand:SF 0 "register_operand" "=f")
5358 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5361 [(set_attr "type" "fpmove")])
5363 (define_expand "abstf2"
5364 [(set (match_operand:TF 0 "register_operand" "")
5365 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5369 (define_insn_and_split "*abstf2_notv9"
5370 [(set (match_operand:TF 0 "register_operand" "=e,e")
5371 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5372 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5373 "TARGET_FPU && ! TARGET_V9"
5377 "&& reload_completed
5378 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5379 [(set (match_dup 2) (abs:SF (match_dup 3)))
5380 (set (match_dup 4) (match_dup 5))
5381 (set (match_dup 6) (match_dup 7))]
5382 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5383 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5384 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5385 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5386 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5387 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5388 [(set_attr "type" "fpmove,*")
5389 (set_attr "length" "*,2")])
5391 (define_insn "*abstf2_hq_v9"
5392 [(set (match_operand:TF 0 "register_operand" "=e,e")
5393 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5394 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5398 [(set_attr "type" "fpmove")
5399 (set_attr "fptype" "double,*")])
5401 (define_insn_and_split "*abstf2_v9"
5402 [(set (match_operand:TF 0 "register_operand" "=e,e")
5403 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5404 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5408 "&& reload_completed
5409 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5410 [(set (match_dup 2) (abs:DF (match_dup 3)))
5411 (set (match_dup 4) (match_dup 5))]
5412 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5413 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5414 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5415 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5416 [(set_attr "type" "fpmove,*")
5417 (set_attr "length" "*,2")
5418 (set_attr "fptype" "double,*")])
5420 (define_expand "absdf2"
5421 [(set (match_operand:DF 0 "register_operand" "")
5422 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5426 (define_insn_and_split "*absdf2_notv9"
5427 [(set (match_operand:DF 0 "register_operand" "=e,e")
5428 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5429 "TARGET_FPU && ! TARGET_V9"
5433 "&& reload_completed
5434 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5435 [(set (match_dup 2) (abs:SF (match_dup 3)))
5436 (set (match_dup 4) (match_dup 5))]
5437 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5438 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5439 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5440 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5441 [(set_attr "type" "fpmove,*")
5442 (set_attr "length" "*,2")])
5444 (define_insn "*absdf2_v9"
5445 [(set (match_operand:DF 0 "register_operand" "=e")
5446 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5447 "TARGET_FPU && TARGET_V9"
5449 [(set_attr "type" "fpmove")
5450 (set_attr "fptype" "double")])
5452 (define_insn "abssf2"
5453 [(set (match_operand:SF 0 "register_operand" "=f")
5454 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5457 [(set_attr "type" "fpmove")])
5459 (define_expand "sqrttf2"
5460 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5461 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5462 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5463 "emit_tfmode_unop (SQRT, operands); DONE;")
5465 (define_insn "*sqrttf2_hq"
5466 [(set (match_operand:TF 0 "register_operand" "=e")
5467 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5468 "TARGET_FPU && TARGET_HARD_QUAD"
5470 [(set_attr "type" "fpsqrtd")])
5472 (define_insn "sqrtdf2"
5473 [(set (match_operand:DF 0 "register_operand" "=e")
5474 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5477 [(set_attr "type" "fpsqrtd")
5478 (set_attr "fptype" "double")])
5480 (define_insn "sqrtsf2"
5481 [(set (match_operand:SF 0 "register_operand" "=f")
5482 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5485 [(set_attr "type" "fpsqrts")])
5488 ;; Arithmetic shift instructions.
5490 (define_insn "ashlsi3"
5491 [(set (match_operand:SI 0 "register_operand" "=r")
5492 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5493 (match_operand:SI 2 "arith_operand" "rI")))]
5496 if (GET_CODE (operands[2]) == CONST_INT)
5497 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5498 return "sll\t%1, %2, %0";
5500 [(set_attr "type" "shift")])
5502 (define_insn "*ashlsi3_extend"
5503 [(set (match_operand:DI 0 "register_operand" "=r")
5505 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5506 (match_operand:SI 2 "arith_operand" "rI"))))]
5509 if (GET_CODE (operands[2]) == CONST_INT)
5510 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5511 return "sll\t%1, %2, %0";
5513 [(set_attr "type" "shift")])
5515 (define_expand "ashldi3"
5516 [(set (match_operand:DI 0 "register_operand" "=r")
5517 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5518 (match_operand:SI 2 "arith_operand" "rI")))]
5519 "TARGET_ARCH64 || TARGET_V8PLUS"
5521 if (! TARGET_ARCH64)
5523 if (GET_CODE (operands[2]) == CONST_INT)
5525 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5530 (define_insn "*ashldi3_sp64"
5531 [(set (match_operand:DI 0 "register_operand" "=r")
5532 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5533 (match_operand:SI 2 "arith_operand" "rI")))]
5536 if (GET_CODE (operands[2]) == CONST_INT)
5537 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5538 return "sllx\t%1, %2, %0";
5540 [(set_attr "type" "shift")])
5543 (define_insn "ashldi3_v8plus"
5544 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5545 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5546 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5547 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5549 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5550 [(set_attr "type" "multi")
5551 (set_attr "length" "5,5,6")])
5553 ;; Optimize (1LL<<x)-1
5554 ;; XXX this also needs to be fixed to handle equal subregs
5555 ;; XXX first before we could re-enable it.
5557 ; [(set (match_operand:DI 0 "register_operand" "=h")
5558 ; (plus:DI (ashift:DI (const_int 1)
5559 ; (match_operand:SI 1 "arith_operand" "rI"))
5561 ; "0 && TARGET_V8PLUS"
5563 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5564 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5565 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5567 ; [(set_attr "type" "multi")
5568 ; (set_attr "length" "4")])
5570 (define_insn "*cmp_cc_ashift_1"
5571 [(set (reg:CC_NOOV CC_REG)
5572 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5576 "addcc\t%0, %0, %%g0"
5577 [(set_attr "type" "compare")])
5579 (define_insn "*cmp_cc_set_ashift_1"
5580 [(set (reg:CC_NOOV CC_REG)
5581 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5584 (set (match_operand:SI 0 "register_operand" "=r")
5585 (ashift:SI (match_dup 1) (const_int 1)))]
5588 [(set_attr "type" "compare")])
5590 (define_insn "ashrsi3"
5591 [(set (match_operand:SI 0 "register_operand" "=r")
5592 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5593 (match_operand:SI 2 "arith_operand" "rI")))]
5596 if (GET_CODE (operands[2]) == CONST_INT)
5597 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5598 return "sra\t%1, %2, %0";
5600 [(set_attr "type" "shift")])
5602 (define_insn "*ashrsi3_extend"
5603 [(set (match_operand:DI 0 "register_operand" "=r")
5604 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5605 (match_operand:SI 2 "arith_operand" "r"))))]
5608 [(set_attr "type" "shift")])
5610 ;; This handles the case as above, but with constant shift instead of
5611 ;; register. Combiner "simplifies" it for us a little bit though.
5612 (define_insn "*ashrsi3_extend2"
5613 [(set (match_operand:DI 0 "register_operand" "=r")
5614 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5616 (match_operand:SI 2 "small_int_operand" "I")))]
5617 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5619 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5620 return "sra\t%1, %2, %0";
5622 [(set_attr "type" "shift")])
5624 (define_expand "ashrdi3"
5625 [(set (match_operand:DI 0 "register_operand" "=r")
5626 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5627 (match_operand:SI 2 "arith_operand" "rI")))]
5628 "TARGET_ARCH64 || TARGET_V8PLUS"
5630 if (! TARGET_ARCH64)
5632 if (GET_CODE (operands[2]) == CONST_INT)
5633 FAIL; /* prefer generic code in this case */
5634 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5639 (define_insn "*ashrdi3_sp64"
5640 [(set (match_operand:DI 0 "register_operand" "=r")
5641 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5642 (match_operand:SI 2 "arith_operand" "rI")))]
5646 if (GET_CODE (operands[2]) == CONST_INT)
5647 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5648 return "srax\t%1, %2, %0";
5650 [(set_attr "type" "shift")])
5653 (define_insn "ashrdi3_v8plus"
5654 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5655 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5656 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5657 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5659 "* return output_v8plus_shift (operands, insn, \"srax\");"
5660 [(set_attr "type" "multi")
5661 (set_attr "length" "5,5,6")])
5663 (define_insn "lshrsi3"
5664 [(set (match_operand:SI 0 "register_operand" "=r")
5665 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5666 (match_operand:SI 2 "arith_operand" "rI")))]
5669 if (GET_CODE (operands[2]) == CONST_INT)
5670 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5671 return "srl\t%1, %2, %0";
5673 [(set_attr "type" "shift")])
5675 (define_insn "*lshrsi3_extend0"
5676 [(set (match_operand:DI 0 "register_operand" "=r")
5678 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5679 (match_operand:SI 2 "arith_operand" "rI"))))]
5682 if (GET_CODE (operands[2]) == CONST_INT)
5683 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5684 return "srl\t%1, %2, %0";
5686 [(set_attr "type" "shift")])
5688 ;; This handles the case where
5689 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5690 ;; but combiner "simplifies" it for us.
5691 (define_insn "*lshrsi3_extend1"
5692 [(set (match_operand:DI 0 "register_operand" "=r")
5693 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5694 (match_operand:SI 2 "arith_operand" "r")) 0)
5695 (match_operand 3 "const_int_operand" "")))]
5696 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5698 [(set_attr "type" "shift")])
5700 ;; This handles the case where
5701 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5702 ;; but combiner "simplifies" it for us.
5703 (define_insn "*lshrsi3_extend2"
5704 [(set (match_operand:DI 0 "register_operand" "=r")
5705 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5706 (match_operand 2 "small_int_operand" "I")
5708 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5710 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5711 return "srl\t%1, %2, %0";
5713 [(set_attr "type" "shift")])
5715 (define_expand "lshrdi3"
5716 [(set (match_operand:DI 0 "register_operand" "=r")
5717 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5718 (match_operand:SI 2 "arith_operand" "rI")))]
5719 "TARGET_ARCH64 || TARGET_V8PLUS"
5721 if (! TARGET_ARCH64)
5723 if (GET_CODE (operands[2]) == CONST_INT)
5725 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5730 (define_insn "*lshrdi3_sp64"
5731 [(set (match_operand:DI 0 "register_operand" "=r")
5732 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5733 (match_operand:SI 2 "arith_operand" "rI")))]
5736 if (GET_CODE (operands[2]) == CONST_INT)
5737 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5738 return "srlx\t%1, %2, %0";
5740 [(set_attr "type" "shift")])
5743 (define_insn "lshrdi3_v8plus"
5744 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5745 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5746 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5747 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5749 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5750 [(set_attr "type" "multi")
5751 (set_attr "length" "5,5,6")])
5754 [(set (match_operand:SI 0 "register_operand" "=r")
5755 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5757 (match_operand:SI 2 "small_int_operand" "I")))]
5758 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5760 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5761 return "srax\t%1, %2, %0";
5763 [(set_attr "type" "shift")])
5766 [(set (match_operand:SI 0 "register_operand" "=r")
5767 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5769 (match_operand:SI 2 "small_int_operand" "I")))]
5770 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5772 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5773 return "srlx\t%1, %2, %0";
5775 [(set_attr "type" "shift")])
5778 [(set (match_operand:SI 0 "register_operand" "=r")
5779 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5780 (match_operand:SI 2 "small_int_operand" "I")) 4)
5781 (match_operand:SI 3 "small_int_operand" "I")))]
5783 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5784 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5785 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5787 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5789 return "srax\t%1, %2, %0";
5791 [(set_attr "type" "shift")])
5794 [(set (match_operand:SI 0 "register_operand" "=r")
5795 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5796 (match_operand:SI 2 "small_int_operand" "I")) 4)
5797 (match_operand:SI 3 "small_int_operand" "I")))]
5799 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5800 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5801 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5803 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5805 return "srlx\t%1, %2, %0";
5807 [(set_attr "type" "shift")])
5810 ;; Unconditional and other jump instructions.
5813 [(set (pc) (label_ref (match_operand 0 "" "")))]
5815 "* return output_ubranch (operands[0], 0, insn);"
5816 [(set_attr "type" "uncond_branch")])
5818 (define_expand "tablejump"
5819 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5820 (use (label_ref (match_operand 1 "" "")))])]
5823 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5825 /* In pic mode, our address differences are against the base of the
5826 table. Add that base value back in; CSE ought to be able to combine
5827 the two address loads. */
5831 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5833 if (CASE_VECTOR_MODE != Pmode)
5834 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5835 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5836 operands[0] = memory_address (Pmode, tmp);
5840 (define_insn "*tablejump_sp32"
5841 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5842 (use (label_ref (match_operand 1 "" "")))]
5845 [(set_attr "type" "uncond_branch")])
5847 (define_insn "*tablejump_sp64"
5848 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5849 (use (label_ref (match_operand 1 "" "")))]
5852 [(set_attr "type" "uncond_branch")])
5855 ;; Jump to subroutine instructions.
5857 (define_expand "call"
5858 ;; Note that this expression is not used for generating RTL.
5859 ;; All the RTL is generated explicitly below.
5860 [(call (match_operand 0 "call_operand" "")
5861 (match_operand 3 "" "i"))]
5862 ;; operands[2] is next_arg_register
5863 ;; operands[3] is struct_value_size_rtx.
5868 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5870 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5872 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5874 /* This is really a PIC sequence. We want to represent
5875 it as a funny jump so its delay slots can be filled.
5877 ??? But if this really *is* a CALL, will not it clobber the
5878 call-clobbered registers? We lose this if it is a JUMP_INSN.
5879 Why cannot we have delay slots filled if it were a CALL? */
5881 /* We accept negative sizes for untyped calls. */
5882 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5887 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5889 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5895 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5896 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5900 fn_rtx = operands[0];
5902 /* We accept negative sizes for untyped calls. */
5903 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5904 sparc_emit_call_insn
5907 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
5909 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
5912 sparc_emit_call_insn
5915 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
5916 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
5924 ;; We can't use the same pattern for these two insns, because then registers
5925 ;; in the address may not be properly reloaded.
5927 (define_insn "*call_address_sp32"
5928 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
5929 (match_operand 1 "" ""))
5930 (clobber (reg:SI O7_REG))]
5931 ;;- Do not use operand 1 for most machines.
5934 [(set_attr "type" "call")])
5936 (define_insn "*call_symbolic_sp32"
5937 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
5938 (match_operand 1 "" ""))
5939 (clobber (reg:SI O7_REG))]
5940 ;;- Do not use operand 1 for most machines.
5943 [(set_attr "type" "call")])
5945 (define_insn "*call_address_sp64"
5946 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
5947 (match_operand 1 "" ""))
5948 (clobber (reg:DI O7_REG))]
5949 ;;- Do not use operand 1 for most machines.
5952 [(set_attr "type" "call")])
5954 (define_insn "*call_symbolic_sp64"
5955 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
5956 (match_operand 1 "" ""))
5957 (clobber (reg:DI O7_REG))]
5958 ;;- Do not use operand 1 for most machines.
5961 [(set_attr "type" "call")])
5963 ;; This is a call that wants a structure value.
5964 ;; There is no such critter for v9 (??? we may need one anyway).
5965 (define_insn "*call_address_struct_value_sp32"
5966 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
5967 (match_operand 1 "" ""))
5968 (match_operand 2 "immediate_operand" "")
5969 (clobber (reg:SI O7_REG))]
5970 ;;- Do not use operand 1 for most machines.
5971 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
5973 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
5974 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
5976 [(set_attr "type" "call_no_delay_slot")
5977 (set_attr "length" "3")])
5979 ;; This is a call that wants a structure value.
5980 ;; There is no such critter for v9 (??? we may need one anyway).
5981 (define_insn "*call_symbolic_struct_value_sp32"
5982 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
5983 (match_operand 1 "" ""))
5984 (match_operand 2 "immediate_operand" "")
5985 (clobber (reg:SI O7_REG))]
5986 ;;- Do not use operand 1 for most machines.
5987 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
5989 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
5990 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
5992 [(set_attr "type" "call_no_delay_slot")
5993 (set_attr "length" "3")])
5995 ;; This is a call that may want a structure value. This is used for
5997 (define_insn "*call_address_untyped_struct_value_sp32"
5998 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
5999 (match_operand 1 "" ""))
6000 (match_operand 2 "immediate_operand" "")
6001 (clobber (reg:SI O7_REG))]
6002 ;;- Do not use operand 1 for most machines.
6003 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6004 "call\t%a0, %1\n\t nop\n\tnop"
6005 [(set_attr "type" "call_no_delay_slot")
6006 (set_attr "length" "3")])
6008 ;; This is a call that may want a structure value. This is used for
6010 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6011 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6012 (match_operand 1 "" ""))
6013 (match_operand 2 "immediate_operand" "")
6014 (clobber (reg:SI O7_REG))]
6015 ;;- Do not use operand 1 for most machines.
6016 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6017 "call\t%a0, %1\n\t nop\n\tnop"
6018 [(set_attr "type" "call_no_delay_slot")
6019 (set_attr "length" "3")])
6021 (define_expand "call_value"
6022 ;; Note that this expression is not used for generating RTL.
6023 ;; All the RTL is generated explicitly below.
6024 [(set (match_operand 0 "register_operand" "=rf")
6025 (call (match_operand 1 "" "")
6026 (match_operand 4 "" "")))]
6027 ;; operand 2 is stack_size_rtx
6028 ;; operand 3 is next_arg_register
6034 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6036 fn_rtx = operands[1];
6039 gen_rtx_SET (VOIDmode, operands[0],
6040 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6041 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6043 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6048 (define_insn "*call_value_address_sp32"
6049 [(set (match_operand 0 "" "=rf")
6050 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6051 (match_operand 2 "" "")))
6052 (clobber (reg:SI O7_REG))]
6053 ;;- Do not use operand 2 for most machines.
6056 [(set_attr "type" "call")])
6058 (define_insn "*call_value_symbolic_sp32"
6059 [(set (match_operand 0 "" "=rf")
6060 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6061 (match_operand 2 "" "")))
6062 (clobber (reg:SI O7_REG))]
6063 ;;- Do not use operand 2 for most machines.
6066 [(set_attr "type" "call")])
6068 (define_insn "*call_value_address_sp64"
6069 [(set (match_operand 0 "" "")
6070 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6071 (match_operand 2 "" "")))
6072 (clobber (reg:DI O7_REG))]
6073 ;;- Do not use operand 2 for most machines.
6076 [(set_attr "type" "call")])
6078 (define_insn "*call_value_symbolic_sp64"
6079 [(set (match_operand 0 "" "")
6080 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6081 (match_operand 2 "" "")))
6082 (clobber (reg:DI O7_REG))]
6083 ;;- Do not use operand 2 for most machines.
6086 [(set_attr "type" "call")])
6088 (define_expand "untyped_call"
6089 [(parallel [(call (match_operand 0 "" "")
6091 (match_operand:BLK 1 "memory_operand" "")
6092 (match_operand 2 "" "")])]
6095 rtx valreg1 = gen_rtx_REG (DImode, 8);
6096 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6097 rtx result = operands[1];
6099 /* Pass constm1 to indicate that it may expect a structure value, but
6100 we don't know what size it is. */
6101 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6103 /* Save the function value registers. */
6104 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6105 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6108 /* The optimizer does not know that the call sets the function value
6109 registers we stored in the result block. We avoid problems by
6110 claiming that all hard registers are used and clobbered at this
6112 emit_insn (gen_blockage ());
6117 ;; Tail call instructions.
6119 (define_expand "sibcall"
6120 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6125 (define_insn "*sibcall_symbolic_sp32"
6126 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6127 (match_operand 1 "" ""))
6130 "* return output_sibcall(insn, operands[0]);"
6131 [(set_attr "type" "sibcall")])
6133 (define_insn "*sibcall_symbolic_sp64"
6134 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6135 (match_operand 1 "" ""))
6138 "* return output_sibcall(insn, operands[0]);"
6139 [(set_attr "type" "sibcall")])
6141 (define_expand "sibcall_value"
6142 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6143 (call (match_operand 1 "" "") (const_int 0)))
6148 (define_insn "*sibcall_value_symbolic_sp32"
6149 [(set (match_operand 0 "" "=rf")
6150 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6151 (match_operand 2 "" "")))
6154 "* return output_sibcall(insn, operands[1]);"
6155 [(set_attr "type" "sibcall")])
6157 (define_insn "*sibcall_value_symbolic_sp64"
6158 [(set (match_operand 0 "" "")
6159 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6160 (match_operand 2 "" "")))
6163 "* return output_sibcall(insn, operands[1]);"
6164 [(set_attr "type" "sibcall")])
6167 ;; Special instructions.
6169 (define_expand "prologue"
6174 sparc_flat_expand_prologue ();
6176 sparc_expand_prologue ();
6180 ;; The "register window save" insn is modelled as follows. The dwarf2
6181 ;; information is manually added in emit_window_save.
6183 (define_insn "window_save"
6185 [(match_operand 0 "arith_operand" "rI")]
6188 "save\t%%sp, %0, %%sp"
6189 [(set_attr "type" "savew")])
6191 (define_expand "epilogue"
6196 sparc_flat_expand_epilogue (false);
6198 sparc_expand_epilogue (false);
6201 (define_expand "sibcall_epilogue"
6206 sparc_flat_expand_epilogue (false);
6208 sparc_expand_epilogue (false);
6212 (define_expand "eh_return"
6213 [(use (match_operand 0 "general_operand" ""))]
6216 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6217 emit_jump_insn (gen_eh_return_internal ());
6222 (define_insn_and_split "eh_return_internal"
6226 "epilogue_completed"
6230 sparc_flat_expand_epilogue (true);
6232 sparc_expand_epilogue (true);
6235 (define_expand "return"
6237 "sparc_can_use_return_insn_p ()"
6240 (define_insn "*return_internal"
6243 "* return output_return (insn);"
6244 [(set_attr "type" "return")
6245 (set (attr "length")
6246 (cond [(eq_attr "calls_eh_return" "true")
6247 (if_then_else (eq_attr "delayed_branch" "true")
6248 (if_then_else (ior (eq_attr "isa" "v9")
6249 (eq_attr "flat" "true"))
6252 (if_then_else (eq_attr "flat" "true")
6255 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6256 (if_then_else (eq_attr "empty_delay_slot" "true")
6259 (eq_attr "empty_delay_slot" "true")
6260 (if_then_else (eq_attr "delayed_branch" "true")
6265 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6266 ;; all of memory. This blocks insns from being moved across this point.
6268 (define_insn "blockage"
6269 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6272 [(set_attr "length" "0")])
6274 (define_expand "probe_stack"
6275 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6279 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6282 (define_insn "probe_stack_range<P:mode>"
6283 [(set (match_operand:P 0 "register_operand" "=r")
6284 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6285 (match_operand:P 2 "register_operand" "r")]
6286 UNSPECV_PROBE_STACK_RANGE))]
6288 "* return output_probe_stack_range (operands[0], operands[2]);"
6289 [(set_attr "type" "multi")])
6291 ;; Prepare to return any type including a structure value.
6293 (define_expand "untyped_return"
6294 [(match_operand:BLK 0 "memory_operand" "")
6295 (match_operand 1 "" "")]
6298 rtx valreg1 = gen_rtx_REG (DImode, 24);
6299 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6300 rtx result = operands[0];
6302 if (! TARGET_ARCH64)
6304 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6305 rtx value = gen_reg_rtx (SImode);
6307 /* Fetch the instruction where we will return to and see if it's an unimp
6308 instruction (the most significant 10 bits will be zero). If so,
6309 update the return address to skip the unimp instruction. */
6310 emit_move_insn (value,
6311 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6312 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6313 emit_insn (gen_update_return (rtnreg, value));
6316 /* Reload the function value registers. */
6317 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6318 emit_move_insn (valreg2,
6319 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6321 /* Put USE insns before the return. */
6325 /* Construct the return. */
6326 expand_naked_return ();
6331 ;; Adjust the return address conditionally. If the value of op1 is equal
6332 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6333 ;; This is technically *half* the check required by the 32-bit SPARC
6334 ;; psABI. This check only ensures that an "unimp" insn was written by
6335 ;; the caller, but doesn't check to see if the expected size matches
6336 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6337 ;; only used by the above code "untyped_return".
6339 (define_insn "update_return"
6340 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6341 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6344 if (flag_delayed_branch)
6345 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6347 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6349 [(set (attr "type") (const_string "multi"))
6350 (set (attr "length")
6351 (if_then_else (eq_attr "delayed_branch" "true")
6360 (define_expand "indirect_jump"
6361 [(set (pc) (match_operand 0 "address_operand" "p"))]
6365 (define_insn "*branch_sp32"
6366 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6369 [(set_attr "type" "uncond_branch")])
6371 (define_insn "*branch_sp64"
6372 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6375 [(set_attr "type" "uncond_branch")])
6377 (define_expand "save_stack_nonlocal"
6378 [(set (match_operand 0 "memory_operand" "")
6379 (match_operand 1 "register_operand" ""))
6380 (set (match_dup 2) (match_dup 3))]
6383 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6384 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6385 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6388 (define_expand "restore_stack_nonlocal"
6389 [(set (match_operand 0 "register_operand" "")
6390 (match_operand 1 "memory_operand" ""))]
6393 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6396 (define_expand "nonlocal_goto"
6397 [(match_operand 0 "general_operand" "")
6398 (match_operand 1 "general_operand" "")
6399 (match_operand 2 "memory_operand" "")
6400 (match_operand 3 "memory_operand" "")]
6403 rtx r_label = copy_to_reg (operands[1]);
6404 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6405 rtx r_fp = operands[3];
6406 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6408 /* We need to flush all the register windows so that their contents will
6409 be re-synchronized by the restore insn of the target function. */
6411 emit_insn (gen_flush_register_windows ());
6413 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6414 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6416 /* Restore frame pointer for containing function. */
6417 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6418 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6420 /* USE of hard_frame_pointer_rtx added for consistency;
6421 not clear if really needed. */
6422 emit_use (hard_frame_pointer_rtx);
6423 emit_use (stack_pointer_rtx);
6425 /* We need to smuggle the load of %i7 as it is a fixed register. */
6426 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6431 (define_insn "nonlocal_goto_internal"
6432 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6433 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6434 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6436 if (flag_delayed_branch)
6439 return "jmp\t%0\n\t ldx\t%1, %%i7";
6441 return "jmp\t%0\n\t ld\t%1, %%i7";
6446 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6448 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6451 [(set (attr "type") (const_string "multi"))
6452 (set (attr "length")
6453 (if_then_else (eq_attr "delayed_branch" "true")
6457 (define_expand "builtin_setjmp_receiver"
6458 [(label_ref (match_operand 0 "" ""))]
6461 load_got_register ();
6465 ;; Special insn to flush register windows.
6467 (define_insn "flush_register_windows"
6468 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6470 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6471 [(set_attr "type" "flushw")])
6473 ;; Special pattern for the FLUSH instruction.
6475 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6476 ; of the define_insn otherwise missing a mode. We make "flush", aka
6477 ; gen_flush, the default one since sparc_initialize_trampoline uses
6478 ; it on SImode mem values.
6480 (define_insn "flush"
6481 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6483 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6484 [(set_attr "type" "iflush")])
6486 (define_insn "flushdi"
6487 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6489 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6490 [(set_attr "type" "iflush")])
6493 ;; Find first set instructions.
6495 ;; The scan instruction searches from the most significant bit while ffs
6496 ;; searches from the least significant bit. The bit index and treatment of
6497 ;; zero also differ. It takes at least 7 instructions to get the proper
6498 ;; result. Here is an obvious 8 instruction sequence.
6501 (define_insn "ffssi2"
6502 [(set (match_operand:SI 0 "register_operand" "=&r")
6503 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6504 (clobber (match_scratch:SI 2 "=&r"))]
6505 "TARGET_SPARCLITE || TARGET_SPARCLET"
6507 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";
6509 [(set_attr "type" "multi")
6510 (set_attr "length" "8")])
6512 (define_expand "popcountdi2"
6513 [(set (match_operand:DI 0 "register_operand" "")
6514 (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6517 if (! TARGET_ARCH64)
6519 emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6524 (define_insn "*popcountdi_sp64"
6525 [(set (match_operand:DI 0 "register_operand" "=r")
6526 (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6527 "TARGET_POPC && TARGET_ARCH64"
6530 (define_insn "popcountdi_v8plus"
6531 [(set (match_operand:DI 0 "register_operand" "=r")
6532 (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6533 (clobber (match_scratch:SI 2 "=&h"))]
6534 "TARGET_POPC && ! TARGET_ARCH64"
6536 if (sparc_check_64 (operands[1], insn) <= 0)
6537 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6538 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6540 [(set_attr "type" "multi")
6541 (set_attr "length" "5")])
6543 (define_expand "popcountsi2"
6545 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6546 (set (match_operand:SI 0 "register_operand" "")
6547 (truncate:SI (popcount:DI (match_dup 2))))]
6550 if (! TARGET_ARCH64)
6552 emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6556 operands[2] = gen_reg_rtx (DImode);
6559 (define_insn "*popcountsi_sp64"
6560 [(set (match_operand:SI 0 "register_operand" "=r")
6562 (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6563 "TARGET_POPC && TARGET_ARCH64"
6566 (define_insn "popcountsi_v8plus"
6567 [(set (match_operand:SI 0 "register_operand" "=r")
6568 (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6569 "TARGET_POPC && ! TARGET_ARCH64"
6571 if (sparc_check_64 (operands[1], insn) <= 0)
6572 output_asm_insn ("srl\t%1, 0, %1", operands);
6573 return "popc\t%1, %0";
6575 [(set_attr "type" "multi")
6576 (set_attr "length" "2")])
6578 (define_expand "clzdi2"
6579 [(set (match_operand:DI 0 "register_operand" "")
6580 (clz:DI (match_operand:DI 1 "register_operand" "")))]
6583 if (! TARGET_ARCH64)
6585 emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6590 (define_insn "*clzdi_sp64"
6591 [(set (match_operand:DI 0 "register_operand" "=r")
6592 (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6593 "TARGET_VIS3 && TARGET_ARCH64"
6596 (define_insn "clzdi_v8plus"
6597 [(set (match_operand:DI 0 "register_operand" "=r")
6598 (clz:DI (match_operand:DI 1 "register_operand" "r")))
6599 (clobber (match_scratch:SI 2 "=&h"))]
6600 "TARGET_VIS3 && ! TARGET_ARCH64"
6602 if (sparc_check_64 (operands[1], insn) <= 0)
6603 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6604 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6606 [(set_attr "type" "multi")
6607 (set_attr "length" "5")])
6609 (define_expand "clzsi2"
6611 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6613 (truncate:SI (clz:DI (match_dup 2))))
6614 (set (match_operand:SI 0 "register_operand" "")
6615 (minus:SI (match_dup 3) (const_int 32)))]
6618 if (! TARGET_ARCH64)
6620 emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6625 operands[2] = gen_reg_rtx (DImode);
6626 operands[3] = gen_reg_rtx (SImode);
6630 (define_insn "*clzsi_sp64"
6631 [(set (match_operand:SI 0 "register_operand" "=r")
6633 (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6634 "TARGET_VIS3 && TARGET_ARCH64"
6637 (define_insn "clzsi_v8plus"
6638 [(set (match_operand:SI 0 "register_operand" "=r")
6639 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6640 "TARGET_VIS3 && ! TARGET_ARCH64"
6642 if (sparc_check_64 (operands[1], insn) <= 0)
6643 output_asm_insn ("srl\t%1, 0, %1", operands);
6644 return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6646 [(set_attr "type" "multi")
6647 (set_attr "length" "3")])
6650 ;; Peepholes go at the end.
6652 ;; Optimize consecutive loads or stores into ldd and std when possible.
6653 ;; The conditions in which we do this are very restricted and are
6654 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6657 [(set (match_operand:SI 0 "memory_operand" "")
6659 (set (match_operand:SI 1 "memory_operand" "")
6662 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6665 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6668 [(set (match_operand:SI 0 "memory_operand" "")
6670 (set (match_operand:SI 1 "memory_operand" "")
6673 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6676 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6679 [(set (match_operand:SI 0 "register_operand" "")
6680 (match_operand:SI 1 "memory_operand" ""))
6681 (set (match_operand:SI 2 "register_operand" "")
6682 (match_operand:SI 3 "memory_operand" ""))]
6683 "registers_ok_for_ldd_peep (operands[0], operands[2])
6684 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6687 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6688 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6691 [(set (match_operand:SI 0 "memory_operand" "")
6692 (match_operand:SI 1 "register_operand" ""))
6693 (set (match_operand:SI 2 "memory_operand" "")
6694 (match_operand:SI 3 "register_operand" ""))]
6695 "registers_ok_for_ldd_peep (operands[1], operands[3])
6696 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6699 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6700 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6703 [(set (match_operand:SF 0 "register_operand" "")
6704 (match_operand:SF 1 "memory_operand" ""))
6705 (set (match_operand:SF 2 "register_operand" "")
6706 (match_operand:SF 3 "memory_operand" ""))]
6707 "registers_ok_for_ldd_peep (operands[0], operands[2])
6708 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6711 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6712 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6715 [(set (match_operand:SF 0 "memory_operand" "")
6716 (match_operand:SF 1 "register_operand" ""))
6717 (set (match_operand:SF 2 "memory_operand" "")
6718 (match_operand:SF 3 "register_operand" ""))]
6719 "registers_ok_for_ldd_peep (operands[1], operands[3])
6720 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6723 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6724 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6727 [(set (match_operand:SI 0 "register_operand" "")
6728 (match_operand:SI 1 "memory_operand" ""))
6729 (set (match_operand:SI 2 "register_operand" "")
6730 (match_operand:SI 3 "memory_operand" ""))]
6731 "registers_ok_for_ldd_peep (operands[2], operands[0])
6732 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6735 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6736 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6739 [(set (match_operand:SI 0 "memory_operand" "")
6740 (match_operand:SI 1 "register_operand" ""))
6741 (set (match_operand:SI 2 "memory_operand" "")
6742 (match_operand:SI 3 "register_operand" ""))]
6743 "registers_ok_for_ldd_peep (operands[3], operands[1])
6744 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6747 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6748 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6752 [(set (match_operand:SF 0 "register_operand" "")
6753 (match_operand:SF 1 "memory_operand" ""))
6754 (set (match_operand:SF 2 "register_operand" "")
6755 (match_operand:SF 3 "memory_operand" ""))]
6756 "registers_ok_for_ldd_peep (operands[2], operands[0])
6757 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6760 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6761 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6764 [(set (match_operand:SF 0 "memory_operand" "")
6765 (match_operand:SF 1 "register_operand" ""))
6766 (set (match_operand:SF 2 "memory_operand" "")
6767 (match_operand:SF 3 "register_operand" ""))]
6768 "registers_ok_for_ldd_peep (operands[3], operands[1])
6769 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6772 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6773 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6775 ;; Optimize the case of following a reg-reg move with a test
6776 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6777 ;; This can result from a float to fix conversion.
6780 [(set (match_operand:SI 0 "register_operand" "")
6781 (match_operand:SI 1 "register_operand" ""))
6782 (set (reg:CC CC_REG)
6783 (compare:CC (match_operand:SI 2 "register_operand" "")
6785 "(rtx_equal_p (operands[2], operands[0])
6786 || rtx_equal_p (operands[2], operands[1]))
6787 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6788 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6789 [(parallel [(set (match_dup 0) (match_dup 1))
6790 (set (reg:CC CC_REG)
6791 (compare:CC (match_dup 1) (const_int 0)))])]
6795 [(set (match_operand:DI 0 "register_operand" "")
6796 (match_operand:DI 1 "register_operand" ""))
6797 (set (reg:CCX CC_REG)
6798 (compare:CCX (match_operand:DI 2 "register_operand" "")
6801 && (rtx_equal_p (operands[2], operands[0])
6802 || rtx_equal_p (operands[2], operands[1]))
6803 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6804 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6805 [(parallel [(set (match_dup 0) (match_dup 1))
6806 (set (reg:CCX CC_REG)
6807 (compare:CCX (match_dup 1) (const_int 0)))])]
6811 ;; Prefetch instructions.
6813 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6814 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6815 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6817 (define_expand "prefetch"
6818 [(match_operand 0 "address_operand" "")
6819 (match_operand 1 "const_int_operand" "")
6820 (match_operand 2 "const_int_operand" "")]
6824 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6826 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6830 (define_insn "prefetch_64"
6831 [(prefetch (match_operand:DI 0 "address_operand" "p")
6832 (match_operand:DI 1 "const_int_operand" "n")
6833 (match_operand:DI 2 "const_int_operand" "n"))]
6836 static const char * const prefetch_instr[2][2] = {
6838 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6839 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6842 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6843 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6846 int read_or_write = INTVAL (operands[1]);
6847 int locality = INTVAL (operands[2]);
6849 gcc_assert (read_or_write == 0 || read_or_write == 1);
6850 gcc_assert (locality >= 0 && locality < 4);
6851 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6853 [(set_attr "type" "load")])
6855 (define_insn "prefetch_32"
6856 [(prefetch (match_operand:SI 0 "address_operand" "p")
6857 (match_operand:SI 1 "const_int_operand" "n")
6858 (match_operand:SI 2 "const_int_operand" "n"))]
6861 static const char * const prefetch_instr[2][2] = {
6863 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6864 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6867 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6868 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6871 int read_or_write = INTVAL (operands[1]);
6872 int locality = INTVAL (operands[2]);
6874 gcc_assert (read_or_write == 0 || read_or_write == 1);
6875 gcc_assert (locality >= 0 && locality < 4);
6876 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6878 [(set_attr "type" "load")])
6881 ;; Trap instructions.
6884 [(trap_if (const_int 1) (const_int 5))]
6887 [(set_attr "type" "trap")])
6889 (define_expand "ctrapsi4"
6890 [(trap_if (match_operator 0 "noov_compare_operator"
6891 [(match_operand:SI 1 "compare_operand" "")
6892 (match_operand:SI 2 "arith_operand" "")])
6893 (match_operand 3 ""))]
6895 "operands[1] = gen_compare_reg (operands[0]);
6896 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6898 operands[2] = const0_rtx;")
6900 (define_expand "ctrapdi4"
6901 [(trap_if (match_operator 0 "noov_compare_operator"
6902 [(match_operand:DI 1 "compare_operand" "")
6903 (match_operand:DI 2 "arith_operand" "")])
6904 (match_operand 3 ""))]
6906 "operands[1] = gen_compare_reg (operands[0]);
6907 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6909 operands[2] = const0_rtx;")
6913 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
6914 (match_operand:SI 1 "arith_operand" "rM"))]
6918 return "t%C0\t%%icc, %1";
6922 [(set_attr "type" "trap")])
6925 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
6926 (match_operand:SI 1 "arith_operand" "rM"))]
6929 [(set_attr "type" "trap")])
6932 ;; TLS support instructions.
6934 (define_insn "tgd_hi22"
6935 [(set (match_operand:SI 0 "register_operand" "=r")
6936 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
6939 "sethi\\t%%tgd_hi22(%a1), %0")
6941 (define_insn "tgd_lo10"
6942 [(set (match_operand:SI 0 "register_operand" "=r")
6943 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6944 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
6947 "add\\t%1, %%tgd_lo10(%a2), %0")
6949 (define_insn "tgd_add32"
6950 [(set (match_operand:SI 0 "register_operand" "=r")
6951 (plus:SI (match_operand:SI 1 "register_operand" "r")
6952 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6953 (match_operand 3 "tgd_symbolic_operand" "")]
6955 "TARGET_TLS && TARGET_ARCH32"
6956 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6958 (define_insn "tgd_add64"
6959 [(set (match_operand:DI 0 "register_operand" "=r")
6960 (plus:DI (match_operand:DI 1 "register_operand" "r")
6961 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6962 (match_operand 3 "tgd_symbolic_operand" "")]
6964 "TARGET_TLS && TARGET_ARCH64"
6965 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6967 (define_insn "tgd_call32"
6968 [(set (match_operand 0 "register_operand" "=r")
6969 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
6970 (match_operand 2 "tgd_symbolic_operand" "")]
6972 (match_operand 3 "" "")))
6973 (clobber (reg:SI O7_REG))]
6974 "TARGET_TLS && TARGET_ARCH32"
6975 "call\t%a1, %%tgd_call(%a2)%#"
6976 [(set_attr "type" "call")])
6978 (define_insn "tgd_call64"
6979 [(set (match_operand 0 "register_operand" "=r")
6980 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
6981 (match_operand 2 "tgd_symbolic_operand" "")]
6983 (match_operand 3 "" "")))
6984 (clobber (reg:DI O7_REG))]
6985 "TARGET_TLS && TARGET_ARCH64"
6986 "call\t%a1, %%tgd_call(%a2)%#"
6987 [(set_attr "type" "call")])
6989 (define_insn "tldm_hi22"
6990 [(set (match_operand:SI 0 "register_operand" "=r")
6991 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6993 "sethi\\t%%tldm_hi22(%&), %0")
6995 (define_insn "tldm_lo10"
6996 [(set (match_operand:SI 0 "register_operand" "=r")
6997 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6998 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7000 "add\\t%1, %%tldm_lo10(%&), %0")
7002 (define_insn "tldm_add32"
7003 [(set (match_operand:SI 0 "register_operand" "=r")
7004 (plus:SI (match_operand:SI 1 "register_operand" "r")
7005 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7007 "TARGET_TLS && TARGET_ARCH32"
7008 "add\\t%1, %2, %0, %%tldm_add(%&)")
7010 (define_insn "tldm_add64"
7011 [(set (match_operand:DI 0 "register_operand" "=r")
7012 (plus:DI (match_operand:DI 1 "register_operand" "r")
7013 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7015 "TARGET_TLS && TARGET_ARCH64"
7016 "add\\t%1, %2, %0, %%tldm_add(%&)")
7018 (define_insn "tldm_call32"
7019 [(set (match_operand 0 "register_operand" "=r")
7020 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7022 (match_operand 2 "" "")))
7023 (clobber (reg:SI O7_REG))]
7024 "TARGET_TLS && TARGET_ARCH32"
7025 "call\t%a1, %%tldm_call(%&)%#"
7026 [(set_attr "type" "call")])
7028 (define_insn "tldm_call64"
7029 [(set (match_operand 0 "register_operand" "=r")
7030 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7032 (match_operand 2 "" "")))
7033 (clobber (reg:DI O7_REG))]
7034 "TARGET_TLS && TARGET_ARCH64"
7035 "call\t%a1, %%tldm_call(%&)%#"
7036 [(set_attr "type" "call")])
7038 (define_insn "tldo_hix22"
7039 [(set (match_operand:SI 0 "register_operand" "=r")
7040 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7043 "sethi\\t%%tldo_hix22(%a1), %0")
7045 (define_insn "tldo_lox10"
7046 [(set (match_operand:SI 0 "register_operand" "=r")
7047 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7048 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7051 "xor\\t%1, %%tldo_lox10(%a2), %0")
7053 (define_insn "tldo_add32"
7054 [(set (match_operand:SI 0 "register_operand" "=r")
7055 (plus:SI (match_operand:SI 1 "register_operand" "r")
7056 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7057 (match_operand 3 "tld_symbolic_operand" "")]
7059 "TARGET_TLS && TARGET_ARCH32"
7060 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7062 (define_insn "tldo_add64"
7063 [(set (match_operand:DI 0 "register_operand" "=r")
7064 (plus:DI (match_operand:DI 1 "register_operand" "r")
7065 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7066 (match_operand 3 "tld_symbolic_operand" "")]
7068 "TARGET_TLS && TARGET_ARCH64"
7069 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7071 (define_insn "tie_hi22"
7072 [(set (match_operand:SI 0 "register_operand" "=r")
7073 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7076 "sethi\\t%%tie_hi22(%a1), %0")
7078 (define_insn "tie_lo10"
7079 [(set (match_operand:SI 0 "register_operand" "=r")
7080 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7081 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7084 "add\\t%1, %%tie_lo10(%a2), %0")
7086 (define_insn "tie_ld32"
7087 [(set (match_operand:SI 0 "register_operand" "=r")
7088 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7089 (match_operand:SI 2 "register_operand" "r")
7090 (match_operand 3 "tie_symbolic_operand" "")]
7092 "TARGET_TLS && TARGET_ARCH32"
7093 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7094 [(set_attr "type" "load")])
7096 (define_insn "tie_ld64"
7097 [(set (match_operand:DI 0 "register_operand" "=r")
7098 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7099 (match_operand:SI 2 "register_operand" "r")
7100 (match_operand 3 "tie_symbolic_operand" "")]
7102 "TARGET_TLS && TARGET_ARCH64"
7103 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7104 [(set_attr "type" "load")])
7106 (define_insn "tie_add32"
7107 [(set (match_operand:SI 0 "register_operand" "=r")
7108 (plus:SI (match_operand:SI 1 "register_operand" "r")
7109 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7110 (match_operand 3 "tie_symbolic_operand" "")]
7112 "TARGET_SUN_TLS && TARGET_ARCH32"
7113 "add\\t%1, %2, %0, %%tie_add(%a3)")
7115 (define_insn "tie_add64"
7116 [(set (match_operand:DI 0 "register_operand" "=r")
7117 (plus:DI (match_operand:DI 1 "register_operand" "r")
7118 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7119 (match_operand 3 "tie_symbolic_operand" "")]
7121 "TARGET_SUN_TLS && TARGET_ARCH64"
7122 "add\\t%1, %2, %0, %%tie_add(%a3)")
7124 (define_insn "tle_hix22_sp32"
7125 [(set (match_operand:SI 0 "register_operand" "=r")
7126 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7128 "TARGET_TLS && TARGET_ARCH32"
7129 "sethi\\t%%tle_hix22(%a1), %0")
7131 (define_insn "tle_lox10_sp32"
7132 [(set (match_operand:SI 0 "register_operand" "=r")
7133 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7134 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7136 "TARGET_TLS && TARGET_ARCH32"
7137 "xor\\t%1, %%tle_lox10(%a2), %0")
7139 (define_insn "tle_hix22_sp64"
7140 [(set (match_operand:DI 0 "register_operand" "=r")
7141 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7143 "TARGET_TLS && TARGET_ARCH64"
7144 "sethi\\t%%tle_hix22(%a1), %0")
7146 (define_insn "tle_lox10_sp64"
7147 [(set (match_operand:DI 0 "register_operand" "=r")
7148 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7149 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7151 "TARGET_TLS && TARGET_ARCH64"
7152 "xor\\t%1, %%tle_lox10(%a2), %0")
7154 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7155 (define_insn "*tldo_ldub_sp32"
7156 [(set (match_operand:QI 0 "register_operand" "=r")
7157 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7158 (match_operand 3 "tld_symbolic_operand" "")]
7160 (match_operand:SI 1 "register_operand" "r"))))]
7161 "TARGET_TLS && TARGET_ARCH32"
7162 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7163 [(set_attr "type" "load")
7164 (set_attr "us3load_type" "3cycle")])
7166 (define_insn "*tldo_ldub1_sp32"
7167 [(set (match_operand:HI 0 "register_operand" "=r")
7168 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7169 (match_operand 3 "tld_symbolic_operand" "")]
7171 (match_operand:SI 1 "register_operand" "r")))))]
7172 "TARGET_TLS && TARGET_ARCH32"
7173 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7174 [(set_attr "type" "load")
7175 (set_attr "us3load_type" "3cycle")])
7177 (define_insn "*tldo_ldub2_sp32"
7178 [(set (match_operand:SI 0 "register_operand" "=r")
7179 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7180 (match_operand 3 "tld_symbolic_operand" "")]
7182 (match_operand:SI 1 "register_operand" "r")))))]
7183 "TARGET_TLS && TARGET_ARCH32"
7184 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7185 [(set_attr "type" "load")
7186 (set_attr "us3load_type" "3cycle")])
7188 (define_insn "*tldo_ldsb1_sp32"
7189 [(set (match_operand:HI 0 "register_operand" "=r")
7190 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7191 (match_operand 3 "tld_symbolic_operand" "")]
7193 (match_operand:SI 1 "register_operand" "r")))))]
7194 "TARGET_TLS && TARGET_ARCH32"
7195 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7196 [(set_attr "type" "sload")
7197 (set_attr "us3load_type" "3cycle")])
7199 (define_insn "*tldo_ldsb2_sp32"
7200 [(set (match_operand:SI 0 "register_operand" "=r")
7201 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7202 (match_operand 3 "tld_symbolic_operand" "")]
7204 (match_operand:SI 1 "register_operand" "r")))))]
7205 "TARGET_TLS && TARGET_ARCH32"
7206 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7207 [(set_attr "type" "sload")
7208 (set_attr "us3load_type" "3cycle")])
7210 (define_insn "*tldo_ldub_sp64"
7211 [(set (match_operand:QI 0 "register_operand" "=r")
7212 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7213 (match_operand 3 "tld_symbolic_operand" "")]
7215 (match_operand:DI 1 "register_operand" "r"))))]
7216 "TARGET_TLS && TARGET_ARCH64"
7217 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7218 [(set_attr "type" "load")
7219 (set_attr "us3load_type" "3cycle")])
7221 (define_insn "*tldo_ldub1_sp64"
7222 [(set (match_operand:HI 0 "register_operand" "=r")
7223 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7224 (match_operand 3 "tld_symbolic_operand" "")]
7226 (match_operand:DI 1 "register_operand" "r")))))]
7227 "TARGET_TLS && TARGET_ARCH64"
7228 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7229 [(set_attr "type" "load")
7230 (set_attr "us3load_type" "3cycle")])
7232 (define_insn "*tldo_ldub2_sp64"
7233 [(set (match_operand:SI 0 "register_operand" "=r")
7234 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7235 (match_operand 3 "tld_symbolic_operand" "")]
7237 (match_operand:DI 1 "register_operand" "r")))))]
7238 "TARGET_TLS && TARGET_ARCH64"
7239 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7240 [(set_attr "type" "load")
7241 (set_attr "us3load_type" "3cycle")])
7243 (define_insn "*tldo_ldub3_sp64"
7244 [(set (match_operand:DI 0 "register_operand" "=r")
7245 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7246 (match_operand 3 "tld_symbolic_operand" "")]
7248 (match_operand:DI 1 "register_operand" "r")))))]
7249 "TARGET_TLS && TARGET_ARCH64"
7250 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7251 [(set_attr "type" "load")
7252 (set_attr "us3load_type" "3cycle")])
7254 (define_insn "*tldo_ldsb1_sp64"
7255 [(set (match_operand:HI 0 "register_operand" "=r")
7256 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7257 (match_operand 3 "tld_symbolic_operand" "")]
7259 (match_operand:DI 1 "register_operand" "r")))))]
7260 "TARGET_TLS && TARGET_ARCH64"
7261 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7262 [(set_attr "type" "sload")
7263 (set_attr "us3load_type" "3cycle")])
7265 (define_insn "*tldo_ldsb2_sp64"
7266 [(set (match_operand:SI 0 "register_operand" "=r")
7267 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7268 (match_operand 3 "tld_symbolic_operand" "")]
7270 (match_operand:DI 1 "register_operand" "r")))))]
7271 "TARGET_TLS && TARGET_ARCH64"
7272 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7273 [(set_attr "type" "sload")
7274 (set_attr "us3load_type" "3cycle")])
7276 (define_insn "*tldo_ldsb3_sp64"
7277 [(set (match_operand:DI 0 "register_operand" "=r")
7278 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7279 (match_operand 3 "tld_symbolic_operand" "")]
7281 (match_operand:DI 1 "register_operand" "r")))))]
7282 "TARGET_TLS && TARGET_ARCH64"
7283 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7284 [(set_attr "type" "sload")
7285 (set_attr "us3load_type" "3cycle")])
7287 (define_insn "*tldo_lduh_sp32"
7288 [(set (match_operand:HI 0 "register_operand" "=r")
7289 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7290 (match_operand 3 "tld_symbolic_operand" "")]
7292 (match_operand:SI 1 "register_operand" "r"))))]
7293 "TARGET_TLS && TARGET_ARCH32"
7294 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7295 [(set_attr "type" "load")
7296 (set_attr "us3load_type" "3cycle")])
7298 (define_insn "*tldo_lduh1_sp32"
7299 [(set (match_operand:SI 0 "register_operand" "=r")
7300 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7301 (match_operand 3 "tld_symbolic_operand" "")]
7303 (match_operand:SI 1 "register_operand" "r")))))]
7304 "TARGET_TLS && TARGET_ARCH32"
7305 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7306 [(set_attr "type" "load")
7307 (set_attr "us3load_type" "3cycle")])
7309 (define_insn "*tldo_ldsh1_sp32"
7310 [(set (match_operand:SI 0 "register_operand" "=r")
7311 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7312 (match_operand 3 "tld_symbolic_operand" "")]
7314 (match_operand:SI 1 "register_operand" "r")))))]
7315 "TARGET_TLS && TARGET_ARCH32"
7316 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7317 [(set_attr "type" "sload")
7318 (set_attr "us3load_type" "3cycle")])
7320 (define_insn "*tldo_lduh_sp64"
7321 [(set (match_operand:HI 0 "register_operand" "=r")
7322 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7323 (match_operand 3 "tld_symbolic_operand" "")]
7325 (match_operand:DI 1 "register_operand" "r"))))]
7326 "TARGET_TLS && TARGET_ARCH64"
7327 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7328 [(set_attr "type" "load")
7329 (set_attr "us3load_type" "3cycle")])
7331 (define_insn "*tldo_lduh1_sp64"
7332 [(set (match_operand:SI 0 "register_operand" "=r")
7333 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7334 (match_operand 3 "tld_symbolic_operand" "")]
7336 (match_operand:DI 1 "register_operand" "r")))))]
7337 "TARGET_TLS && TARGET_ARCH64"
7338 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7339 [(set_attr "type" "load")
7340 (set_attr "us3load_type" "3cycle")])
7342 (define_insn "*tldo_lduh2_sp64"
7343 [(set (match_operand:DI 0 "register_operand" "=r")
7344 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7345 (match_operand 3 "tld_symbolic_operand" "")]
7347 (match_operand:DI 1 "register_operand" "r")))))]
7348 "TARGET_TLS && TARGET_ARCH64"
7349 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7350 [(set_attr "type" "load")
7351 (set_attr "us3load_type" "3cycle")])
7353 (define_insn "*tldo_ldsh1_sp64"
7354 [(set (match_operand:SI 0 "register_operand" "=r")
7355 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7356 (match_operand 3 "tld_symbolic_operand" "")]
7358 (match_operand:DI 1 "register_operand" "r")))))]
7359 "TARGET_TLS && TARGET_ARCH64"
7360 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7361 [(set_attr "type" "sload")
7362 (set_attr "us3load_type" "3cycle")])
7364 (define_insn "*tldo_ldsh2_sp64"
7365 [(set (match_operand:DI 0 "register_operand" "=r")
7366 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7367 (match_operand 3 "tld_symbolic_operand" "")]
7369 (match_operand:DI 1 "register_operand" "r")))))]
7370 "TARGET_TLS && TARGET_ARCH64"
7371 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7372 [(set_attr "type" "sload")
7373 (set_attr "us3load_type" "3cycle")])
7375 (define_insn "*tldo_lduw_sp32"
7376 [(set (match_operand:SI 0 "register_operand" "=r")
7377 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7378 (match_operand 3 "tld_symbolic_operand" "")]
7380 (match_operand:SI 1 "register_operand" "r"))))]
7381 "TARGET_TLS && TARGET_ARCH32"
7382 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7383 [(set_attr "type" "load")])
7385 (define_insn "*tldo_lduw_sp64"
7386 [(set (match_operand:SI 0 "register_operand" "=r")
7387 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7388 (match_operand 3 "tld_symbolic_operand" "")]
7390 (match_operand:DI 1 "register_operand" "r"))))]
7391 "TARGET_TLS && TARGET_ARCH64"
7392 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7393 [(set_attr "type" "load")])
7395 (define_insn "*tldo_lduw1_sp64"
7396 [(set (match_operand:DI 0 "register_operand" "=r")
7397 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7398 (match_operand 3 "tld_symbolic_operand" "")]
7400 (match_operand:DI 1 "register_operand" "r")))))]
7401 "TARGET_TLS && TARGET_ARCH64"
7402 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7403 [(set_attr "type" "load")])
7405 (define_insn "*tldo_ldsw1_sp64"
7406 [(set (match_operand:DI 0 "register_operand" "=r")
7407 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7408 (match_operand 3 "tld_symbolic_operand" "")]
7410 (match_operand:DI 1 "register_operand" "r")))))]
7411 "TARGET_TLS && TARGET_ARCH64"
7412 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7413 [(set_attr "type" "sload")
7414 (set_attr "us3load_type" "3cycle")])
7416 (define_insn "*tldo_ldx_sp64"
7417 [(set (match_operand:DI 0 "register_operand" "=r")
7418 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7419 (match_operand 3 "tld_symbolic_operand" "")]
7421 (match_operand:DI 1 "register_operand" "r"))))]
7422 "TARGET_TLS && TARGET_ARCH64"
7423 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7424 [(set_attr "type" "load")])
7426 (define_insn "*tldo_stb_sp32"
7427 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7428 (match_operand 3 "tld_symbolic_operand" "")]
7430 (match_operand:SI 1 "register_operand" "r")))
7431 (match_operand:QI 0 "register_operand" "=r"))]
7432 "TARGET_TLS && TARGET_ARCH32"
7433 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7434 [(set_attr "type" "store")])
7436 (define_insn "*tldo_stb_sp64"
7437 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7438 (match_operand 3 "tld_symbolic_operand" "")]
7440 (match_operand:DI 1 "register_operand" "r")))
7441 (match_operand:QI 0 "register_operand" "=r"))]
7442 "TARGET_TLS && TARGET_ARCH64"
7443 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7444 [(set_attr "type" "store")])
7446 (define_insn "*tldo_sth_sp32"
7447 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7448 (match_operand 3 "tld_symbolic_operand" "")]
7450 (match_operand:SI 1 "register_operand" "r")))
7451 (match_operand:HI 0 "register_operand" "=r"))]
7452 "TARGET_TLS && TARGET_ARCH32"
7453 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7454 [(set_attr "type" "store")])
7456 (define_insn "*tldo_sth_sp64"
7457 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7458 (match_operand 3 "tld_symbolic_operand" "")]
7460 (match_operand:DI 1 "register_operand" "r")))
7461 (match_operand:HI 0 "register_operand" "=r"))]
7462 "TARGET_TLS && TARGET_ARCH64"
7463 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7464 [(set_attr "type" "store")])
7466 (define_insn "*tldo_stw_sp32"
7467 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7468 (match_operand 3 "tld_symbolic_operand" "")]
7470 (match_operand:SI 1 "register_operand" "r")))
7471 (match_operand:SI 0 "register_operand" "=r"))]
7472 "TARGET_TLS && TARGET_ARCH32"
7473 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7474 [(set_attr "type" "store")])
7476 (define_insn "*tldo_stw_sp64"
7477 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7478 (match_operand 3 "tld_symbolic_operand" "")]
7480 (match_operand:DI 1 "register_operand" "r")))
7481 (match_operand:SI 0 "register_operand" "=r"))]
7482 "TARGET_TLS && TARGET_ARCH64"
7483 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7484 [(set_attr "type" "store")])
7486 (define_insn "*tldo_stx_sp64"
7487 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7488 (match_operand 3 "tld_symbolic_operand" "")]
7490 (match_operand:DI 1 "register_operand" "r")))
7491 (match_operand:DI 0 "register_operand" "=r"))]
7492 "TARGET_TLS && TARGET_ARCH64"
7493 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7494 [(set_attr "type" "store")])
7497 ;; Stack protector instructions.
7499 (define_expand "stack_protect_set"
7500 [(match_operand 0 "memory_operand" "")
7501 (match_operand 1 "memory_operand" "")]
7504 #ifdef TARGET_THREAD_SSP_OFFSET
7505 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7506 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7507 operands[1] = gen_rtx_MEM (Pmode, addr);
7510 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7512 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7516 (define_insn "stack_protect_setsi"
7517 [(set (match_operand:SI 0 "memory_operand" "=m")
7518 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7519 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7521 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7522 [(set_attr "type" "multi")
7523 (set_attr "length" "3")])
7525 (define_insn "stack_protect_setdi"
7526 [(set (match_operand:DI 0 "memory_operand" "=m")
7527 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7528 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7530 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7531 [(set_attr "type" "multi")
7532 (set_attr "length" "3")])
7534 (define_expand "stack_protect_test"
7535 [(match_operand 0 "memory_operand" "")
7536 (match_operand 1 "memory_operand" "")
7537 (match_operand 2 "" "")]
7541 #ifdef TARGET_THREAD_SSP_OFFSET
7542 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7543 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7544 operands[1] = gen_rtx_MEM (Pmode, addr);
7548 result = gen_reg_rtx (Pmode);
7549 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7550 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7551 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7555 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7556 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7557 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7558 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7563 (define_insn "stack_protect_testsi"
7564 [(set (reg:CC CC_REG)
7565 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7566 (match_operand:SI 1 "memory_operand" "m")]
7568 (set (match_scratch:SI 3 "=r") (const_int 0))
7569 (clobber (match_scratch:SI 2 "=&r"))]
7571 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7572 [(set_attr "type" "multi")
7573 (set_attr "length" "4")])
7575 (define_insn "stack_protect_testdi"
7576 [(set (match_operand:DI 0 "register_operand" "=&r")
7577 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7578 (match_operand:DI 2 "memory_operand" "m")]
7580 (set (match_scratch:DI 3 "=r") (const_int 0))]
7582 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7583 [(set_attr "type" "multi")
7584 (set_attr "length" "4")])
7586 ;; Vector instructions.
7588 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7589 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7590 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7592 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
7593 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7594 (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7595 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7596 (V1DI "double") (V2SI "double") (V4HI "double")
7599 (define_expand "mov<VMALL:mode>"
7600 [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7601 (match_operand:VMALL 1 "general_operand" ""))]
7604 if (sparc_expand_move (<VMALL:MODE>mode, operands))
7608 (define_insn "*mov<VM32:mode>_insn"
7609 [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
7610 (match_operand:VM32 1 "input_operand" "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
7612 && (register_operand (operands[0], <VM32:MODE>mode)
7613 || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7626 [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*,*")
7627 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
7629 (define_insn "*mov<VM64:mode>_insn_sp64"
7630 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, f,*r")
7631 (match_operand:VM64 1 "input_operand" "Y,C,e,m,e,Y, m,*r, f,*r,*r"))]
7634 && (register_operand (operands[0], <VM64:MODE>mode)
7635 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7648 [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*,*")
7649 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
7651 (define_insn "*mov<VM64:mode>_insn_sp32"
7652 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
7653 (match_operand:VM64 1 "input_operand" "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
7656 && (register_operand (operands[0], <VM64:MODE>mode)
7657 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7671 [(set_attr "type" "fga,fga,fga,*,*,fpload,fpstore,store,load,store,*,*")
7672 (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
7673 (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
7676 [(set (match_operand:VM64 0 "memory_operand" "")
7677 (match_operand:VM64 1 "register_operand" ""))]
7681 && (((REGNO (operands[1]) % 2) != 0)
7682 || ! mem_min_alignment (operands[0], 8))
7683 && offsettable_memref_p (operands[0])"
7684 [(clobber (const_int 0))]
7688 word0 = adjust_address (operands[0], SImode, 0);
7689 word1 = adjust_address (operands[0], SImode, 4);
7691 emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
7692 emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
7697 [(set (match_operand:VM64 0 "register_operand" "")
7698 (match_operand:VM64 1 "register_operand" ""))]
7702 && sparc_split_regreg_legitimate (operands[0], operands[1])"
7703 [(clobber (const_int 0))]
7705 rtx set_dest = operands[0];
7706 rtx set_src = operands[1];
7710 dest1 = gen_highpart (SImode, set_dest);
7711 dest2 = gen_lowpart (SImode, set_dest);
7712 src1 = gen_highpart (SImode, set_src);
7713 src2 = gen_lowpart (SImode, set_src);
7715 /* Now emit using the real source and destination we found, swapping
7716 the order if we detect overlap. */
7717 if (reg_overlap_mentioned_p (dest1, src2))
7719 emit_insn (gen_movsi (dest2, src2));
7720 emit_insn (gen_movsi (dest1, src1));
7724 emit_insn (gen_movsi (dest1, src1));
7725 emit_insn (gen_movsi (dest2, src2));
7730 (define_expand "vec_init<mode>"
7731 [(match_operand:VMALL 0 "register_operand" "")
7732 (match_operand:VMALL 1 "" "")]
7735 sparc_expand_vector_init (operands[0], operands[1]);
7739 (define_code_iterator plusminus [plus minus])
7740 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
7742 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
7744 (define_insn "<plusminus_insn><mode>3"
7745 [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
7746 (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
7747 (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
7749 "fp<plusminus_insn><vbits>\t%1, %2, %0"
7750 [(set_attr "type" "fga")
7751 (set_attr "fptype" "<vfptype>")])
7753 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7754 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
7755 (V1DI "") (V2SI "") (V4HI "") (V8QI "")])
7756 (define_code_iterator vlop [ior and xor])
7757 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
7758 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
7760 (define_insn "<code><mode>3"
7761 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7762 (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7763 (match_operand:VL 2 "register_operand" "<vconstr>")))]
7765 "f<vlinsn><vlsuf>\t%1, %2, %0"
7766 [(set_attr "type" "fga")
7767 (set_attr "fptype" "<vfptype>")])
7769 (define_insn "*not_<code><mode>3"
7770 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7771 (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7772 (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7774 "f<vlninsn><vlsuf>\t%1, %2, %0"
7775 [(set_attr "type" "fga")
7776 (set_attr "fptype" "<vfptype>")])
7778 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7779 (define_insn "*nand<mode>_vis"
7780 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7781 (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
7782 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7784 "fnand<vlsuf>\t%1, %2, %0"
7785 [(set_attr "type" "fga")
7786 (set_attr "fptype" "<vfptype>")])
7788 (define_code_iterator vlnotop [ior and])
7790 (define_insn "*<code>_not1<mode>_vis"
7791 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7792 (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
7793 (match_operand:VL 2 "register_operand" "<vconstr>")))]
7795 "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
7796 [(set_attr "type" "fga")
7797 (set_attr "fptype" "<vfptype>")])
7799 (define_insn "*<code>_not2<mode>_vis"
7800 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7801 (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7802 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7804 "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
7805 [(set_attr "type" "fga")
7806 (set_attr "fptype" "<vfptype>")])
7808 (define_insn "one_cmpl<mode>2"
7809 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7810 (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
7812 "fnot1<vlsuf>\t%1, %0"
7813 [(set_attr "type" "fga")
7814 (set_attr "fptype" "<vfptype>")])
7816 ;; Hard to generate VIS instructions. We have builtins for these.
7818 (define_insn "fpack16_vis"
7819 [(set (match_operand:V4QI 0 "register_operand" "=f")
7820 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
7825 [(set_attr "type" "fga")
7826 (set_attr "fptype" "double")])
7828 (define_insn "fpackfix_vis"
7829 [(set (match_operand:V2HI 0 "register_operand" "=f")
7830 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
7835 [(set_attr "type" "fga")
7836 (set_attr "fptype" "double")])
7838 (define_insn "fpack32_vis"
7839 [(set (match_operand:V8QI 0 "register_operand" "=e")
7840 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7841 (match_operand:V8QI 2 "register_operand" "e")
7845 "fpack32\t%1, %2, %0"
7846 [(set_attr "type" "fga")
7847 (set_attr "fptype" "double")])
7849 (define_insn "fexpand_vis"
7850 [(set (match_operand:V4HI 0 "register_operand" "=e")
7851 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7855 [(set_attr "type" "fga")
7856 (set_attr "fptype" "double")])
7858 (define_insn "fpmerge_vis"
7859 [(set (match_operand:V8QI 0 "register_operand" "=e")
7861 (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
7862 (match_operand:V4QI 2 "register_operand" "f"))
7863 (parallel [(const_int 0) (const_int 4)
7864 (const_int 1) (const_int 5)
7865 (const_int 2) (const_int 6)
7866 (const_int 3) (const_int 7)])))]
7868 "fpmerge\t%1, %2, %0"
7869 [(set_attr "type" "fga")
7870 (set_attr "fptype" "double")])
7872 (define_insn "vec_interleave_lowv8qi"
7873 [(set (match_operand:V8QI 0 "register_operand" "=e")
7875 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
7876 (match_operand:V8QI 2 "register_operand" "f"))
7877 (parallel [(const_int 0) (const_int 8)
7878 (const_int 1) (const_int 9)
7879 (const_int 2) (const_int 10)
7880 (const_int 3) (const_int 11)])))]
7882 "fpmerge\t%L1, %L2, %0"
7883 [(set_attr "type" "fga")
7884 (set_attr "fptype" "double")])
7886 (define_insn "vec_interleave_highv8qi"
7887 [(set (match_operand:V8QI 0 "register_operand" "=e")
7889 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
7890 (match_operand:V8QI 2 "register_operand" "f"))
7891 (parallel [(const_int 4) (const_int 12)
7892 (const_int 5) (const_int 13)
7893 (const_int 6) (const_int 14)
7894 (const_int 7) (const_int 15)])))]
7896 "fpmerge\t%H1, %H2, %0"
7897 [(set_attr "type" "fga")
7898 (set_attr "fptype" "double")])
7900 ;; Partitioned multiply instructions
7901 (define_insn "fmul8x16_vis"
7902 [(set (match_operand:V4HI 0 "register_operand" "=e")
7903 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7904 (match_operand:V4HI 2 "register_operand" "e")]
7907 "fmul8x16\t%1, %2, %0"
7908 [(set_attr "type" "fpmul")
7909 (set_attr "fptype" "double")])
7911 (define_insn "fmul8x16au_vis"
7912 [(set (match_operand:V4HI 0 "register_operand" "=e")
7913 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7914 (match_operand:V2HI 2 "register_operand" "f")]
7917 "fmul8x16au\t%1, %2, %0"
7918 [(set_attr "type" "fpmul")
7919 (set_attr "fptype" "double")])
7921 (define_insn "fmul8x16al_vis"
7922 [(set (match_operand:V4HI 0 "register_operand" "=e")
7923 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7924 (match_operand:V2HI 2 "register_operand" "f")]
7927 "fmul8x16al\t%1, %2, %0"
7928 [(set_attr "type" "fpmul")
7929 (set_attr "fptype" "double")])
7931 (define_insn "fmul8sux16_vis"
7932 [(set (match_operand:V4HI 0 "register_operand" "=e")
7933 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7934 (match_operand:V4HI 2 "register_operand" "e")]
7937 "fmul8sux16\t%1, %2, %0"
7938 [(set_attr "type" "fpmul")
7939 (set_attr "fptype" "double")])
7941 (define_insn "fmul8ulx16_vis"
7942 [(set (match_operand:V4HI 0 "register_operand" "=e")
7943 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7944 (match_operand:V4HI 2 "register_operand" "e")]
7947 "fmul8ulx16\t%1, %2, %0"
7948 [(set_attr "type" "fpmul")
7949 (set_attr "fptype" "double")])
7951 (define_insn "fmuld8sux16_vis"
7952 [(set (match_operand:V2SI 0 "register_operand" "=e")
7953 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7954 (match_operand:V2HI 2 "register_operand" "f")]
7957 "fmuld8sux16\t%1, %2, %0"
7958 [(set_attr "type" "fpmul")
7959 (set_attr "fptype" "double")])
7961 (define_insn "fmuld8ulx16_vis"
7962 [(set (match_operand:V2SI 0 "register_operand" "=e")
7963 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7964 (match_operand:V2HI 2 "register_operand" "f")]
7967 "fmuld8ulx16\t%1, %2, %0"
7968 [(set_attr "type" "fpmul")
7969 (set_attr "fptype" "double")])
7971 (define_expand "wrgsr_vis"
7972 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
7975 if (! TARGET_ARCH64)
7977 emit_insn (gen_wrgsr_v8plus (operands[0]));
7982 (define_insn "*wrgsr_sp64"
7983 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
7984 "TARGET_VIS && TARGET_ARCH64"
7985 "wr\t%%g0, %0, %%gsr"
7986 [(set_attr "type" "gsr")])
7988 (define_insn "wrgsr_v8plus"
7989 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
7990 (clobber (match_scratch:SI 1 "=X,&h"))]
7991 "TARGET_VIS && ! TARGET_ARCH64"
7993 if (GET_CODE (operands[0]) == CONST_INT
7994 || sparc_check_64 (operands[0], insn))
7995 return "wr\t%%g0, %0, %%gsr";
7997 output_asm_insn("srl\t%L0, 0, %L0", operands);
7998 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8000 [(set_attr "type" "multi")])
8002 (define_expand "rdgsr_vis"
8003 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8006 if (! TARGET_ARCH64)
8008 emit_insn (gen_rdgsr_v8plus (operands[0]));
8013 (define_insn "*rdgsr_sp64"
8014 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8015 "TARGET_VIS && TARGET_ARCH64"
8017 [(set_attr "type" "gsr")])
8019 (define_insn "rdgsr_v8plus"
8020 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8021 (clobber (match_scratch:SI 1 "=&h"))]
8022 "TARGET_VIS && ! TARGET_ARCH64"
8024 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8026 [(set_attr "type" "multi")])
8028 ;; Using faligndata only makes sense after an alignaddr since the choice of
8029 ;; bytes to take out of each operand is dependent on the results of the last
8031 (define_insn "faligndata<VM64:mode>_vis"
8032 [(set (match_operand:VM64 0 "register_operand" "=e")
8033 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8034 (match_operand:VM64 2 "register_operand" "e")
8038 "faligndata\t%1, %2, %0"
8039 [(set_attr "type" "fga")
8040 (set_attr "fptype" "double")])
8042 (define_insn "alignaddrsi_vis"
8043 [(set (match_operand:SI 0 "register_operand" "=r")
8044 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8045 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8046 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8047 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8049 "alignaddr\t%r1, %r2, %0")
8051 (define_insn "alignaddrdi_vis"
8052 [(set (match_operand:DI 0 "register_operand" "=r")
8053 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8054 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8055 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8056 (plus:DI (match_dup 1) (match_dup 2)))]
8058 "alignaddr\t%r1, %r2, %0")
8060 (define_insn "alignaddrlsi_vis"
8061 [(set (match_operand:SI 0 "register_operand" "=r")
8062 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8063 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8064 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8065 (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8068 "alignaddrl\t%r1, %r2, %0")
8070 (define_insn "alignaddrldi_vis"
8071 [(set (match_operand:DI 0 "register_operand" "=r")
8072 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8073 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8074 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8075 (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8078 "alignaddrl\t%r1, %r2, %0")
8080 (define_insn "pdist_vis"
8081 [(set (match_operand:DI 0 "register_operand" "=e")
8082 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8083 (match_operand:V8QI 2 "register_operand" "e")
8084 (match_operand:DI 3 "register_operand" "0")]
8088 [(set_attr "type" "fga")
8089 (set_attr "fptype" "double")])
8091 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8092 ;; with the same operands.
8093 (define_insn "edge8<P:mode>_vis"
8094 [(set (reg:CC_NOOV CC_REG)
8095 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8096 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8098 (set (match_operand:P 0 "register_operand" "=r")
8099 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8101 "edge8\t%r1, %r2, %0"
8102 [(set_attr "type" "edge")])
8104 (define_insn "edge8l<P:mode>_vis"
8105 [(set (reg:CC_NOOV CC_REG)
8106 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8107 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8109 (set (match_operand:P 0 "register_operand" "=r")
8110 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8112 "edge8l\t%r1, %r2, %0"
8113 [(set_attr "type" "edge")])
8115 (define_insn "edge16<P:mode>_vis"
8116 [(set (reg:CC_NOOV CC_REG)
8117 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8118 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8120 (set (match_operand:P 0 "register_operand" "=r")
8121 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8123 "edge16\t%r1, %r2, %0"
8124 [(set_attr "type" "edge")])
8126 (define_insn "edge16l<P:mode>_vis"
8127 [(set (reg:CC_NOOV CC_REG)
8128 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8129 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8131 (set (match_operand:P 0 "register_operand" "=r")
8132 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8134 "edge16l\t%r1, %r2, %0"
8135 [(set_attr "type" "edge")])
8137 (define_insn "edge32<P:mode>_vis"
8138 [(set (reg:CC_NOOV CC_REG)
8139 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8140 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8142 (set (match_operand:P 0 "register_operand" "=r")
8143 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8145 "edge32\t%r1, %r2, %0"
8146 [(set_attr "type" "edge")])
8148 (define_insn "edge32l<P:mode>_vis"
8149 [(set (reg:CC_NOOV CC_REG)
8150 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8151 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8153 (set (match_operand:P 0 "register_operand" "=r")
8154 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8156 "edge32l\t%r1, %r2, %0"
8157 [(set_attr "type" "edge")])
8159 (define_code_iterator gcond [le ne gt eq])
8160 (define_mode_iterator GCM [V4HI V2SI])
8161 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8163 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8164 [(set (match_operand:P 0 "register_operand" "=r")
8165 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8166 (match_operand:GCM 2 "register_operand" "e"))]
8169 "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8170 [(set_attr "type" "fpmul")
8171 (set_attr "fptype" "double")])
8173 (define_insn "array8<P:mode>_vis"
8174 [(set (match_operand:P 0 "register_operand" "=r")
8175 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8176 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8179 "array8\t%r1, %r2, %0"
8180 [(set_attr "type" "array")])
8182 (define_insn "array16<P:mode>_vis"
8183 [(set (match_operand:P 0 "register_operand" "=r")
8184 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8185 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8188 "array16\t%r1, %r2, %0"
8189 [(set_attr "type" "array")])
8191 (define_insn "array32<P:mode>_vis"
8192 [(set (match_operand:P 0 "register_operand" "=r")
8193 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8194 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8197 "array32\t%r1, %r2, %0"
8198 [(set_attr "type" "array")])
8200 (define_insn "bmaskdi_vis"
8201 [(set (match_operand:DI 0 "register_operand" "=r")
8202 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8203 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8204 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8205 (plus:DI (match_dup 1) (match_dup 2)))]
8207 "bmask\t%r1, %r2, %0"
8208 [(set_attr "type" "array")])
8210 (define_insn "bmasksi_vis"
8211 [(set (match_operand:SI 0 "register_operand" "=r")
8212 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8213 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8214 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8215 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8217 "bmask\t%r1, %r2, %0"
8218 [(set_attr "type" "array")])
8220 (define_insn "bshuffle<VM64:mode>_vis"
8221 [(set (match_operand:VM64 0 "register_operand" "=e")
8222 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8223 (match_operand:VM64 2 "register_operand" "e")
8227 "bshuffle\t%1, %2, %0"
8228 [(set_attr "type" "fga")
8229 (set_attr "fptype" "double")])
8231 ;; The rtl expanders will happily convert constant permutations on other
8232 ;; modes down to V8QI. Rely on this to avoid the complexity of the byte
8233 ;; order of the permutation.
8234 (define_expand "vec_perm_constv8qi"
8235 [(match_operand:V8QI 0 "register_operand" "")
8236 (match_operand:V8QI 1 "register_operand" "")
8237 (match_operand:V8QI 2 "register_operand" "")
8238 (match_operand:V8QI 3 "" "")]
8241 unsigned int i, mask;
8242 rtx sel = operands[3];
8244 for (i = mask = 0; i < 8; ++i)
8245 mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8246 sel = force_reg (SImode, gen_int_mode (mask, SImode));
8248 emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, const0_rtx));
8249 emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8253 ;; Unlike constant permutation, we can vastly simplify the compression of
8254 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8255 ;; width of the input is.
8256 (define_expand "vec_perm<mode>"
8257 [(match_operand:VM64 0 "register_operand" "")
8258 (match_operand:VM64 1 "register_operand" "")
8259 (match_operand:VM64 2 "register_operand" "")
8260 (match_operand:VM64 3 "register_operand" "")]
8263 sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8264 emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8268 ;; VIS 2.0 adds edge variants which do not set the condition codes
8269 (define_insn "edge8n<P:mode>_vis"
8270 [(set (match_operand:P 0 "register_operand" "=r")
8271 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8272 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8275 "edge8n\t%r1, %r2, %0"
8276 [(set_attr "type" "edgen")])
8278 (define_insn "edge8ln<P:mode>_vis"
8279 [(set (match_operand:P 0 "register_operand" "=r")
8280 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8281 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8284 "edge8ln\t%r1, %r2, %0"
8285 [(set_attr "type" "edgen")])
8287 (define_insn "edge16n<P:mode>_vis"
8288 [(set (match_operand:P 0 "register_operand" "=r")
8289 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8290 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8293 "edge16n\t%r1, %r2, %0"
8294 [(set_attr "type" "edgen")])
8296 (define_insn "edge16ln<P:mode>_vis"
8297 [(set (match_operand:P 0 "register_operand" "=r")
8298 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8299 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8302 "edge16ln\t%r1, %r2, %0"
8303 [(set_attr "type" "edgen")])
8305 (define_insn "edge32n<P:mode>_vis"
8306 [(set (match_operand:P 0 "register_operand" "=r")
8307 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8308 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8311 "edge32n\t%r1, %r2, %0"
8312 [(set_attr "type" "edgen")])
8314 (define_insn "edge32ln<P:mode>_vis"
8315 [(set (match_operand:P 0 "register_operand" "=r")
8316 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8317 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8320 "edge32ln\t%r1, %r2, %0"
8321 [(set_attr "type" "edge")])
8323 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8324 (define_insn "cmask8<P:mode>_vis"
8325 [(set (reg:DI GSR_REG)
8326 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8332 (define_insn "cmask16<P:mode>_vis"
8333 [(set (reg:DI GSR_REG)
8334 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8340 (define_insn "cmask32<P:mode>_vis"
8341 [(set (reg:DI GSR_REG)
8342 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8348 (define_insn "fchksm16_vis"
8349 [(set (match_operand:V4HI 0 "register_operand" "=e")
8350 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8351 (match_operand:V4HI 2 "register_operand" "e")]
8354 "fchksm16\t%1, %2, %0")
8356 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8357 (define_code_attr vis3_shift_insn
8358 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8359 (define_code_attr vis3_shift_patname
8360 [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8362 (define_insn "v<vis3_shift_patname><mode>3"
8363 [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8364 (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8365 (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8367 "<vis3_shift_insn><vbits>\t%1, %2, %0")
8369 (define_insn "pdistn<mode>_vis"
8370 [(set (match_operand:P 0 "register_operand" "=r")
8371 (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8372 (match_operand:V8QI 2 "register_operand" "e")]
8375 "pdistn\t%1, %2, %0")
8377 (define_insn "fmean16_vis"
8378 [(set (match_operand:V4HI 0 "register_operand" "=e")
8384 (match_operand:V4HI 1 "register_operand" "e"))
8386 (match_operand:V4HI 2 "register_operand" "e")))
8387 (const_vector:V4SI [(const_int 1) (const_int 1)
8388 (const_int 1) (const_int 1)]))
8391 "fmean16\t%1, %2, %0")
8393 (define_insn "fp<plusminus_insn>64_vis"
8394 [(set (match_operand:V1DI 0 "register_operand" "=e")
8395 (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8396 (match_operand:V1DI 2 "register_operand" "e")))]
8398 "fp<plusminus_insn>64\t%1, %2, %0")
8400 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8401 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8402 (define_code_attr vis3_addsub_ss_insn
8403 [(ss_plus "fpadds") (ss_minus "fpsubs")])
8404 (define_code_attr vis3_addsub_ss_patname
8405 [(ss_plus "ssadd") (ss_minus "sssub")])
8407 (define_insn "<vis3_addsub_ss_patname><mode>3"
8408 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8409 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8410 (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8412 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0")
8414 (define_insn "fucmp<code>8<P:mode>_vis"
8415 [(set (match_operand:P 0 "register_operand" "=r")
8416 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8417 (match_operand:V8QI 2 "register_operand" "e"))]
8420 "fucmp<code>8\t%1, %2, %0")
8422 (define_insn "*naddsf3"
8423 [(set (match_operand:SF 0 "register_operand" "=f")
8424 (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8425 (match_operand:SF 2 "register_operand" "f"))))]
8427 "fnadds\t%1, %2, %0"
8428 [(set_attr "type" "fp")])
8430 (define_insn "*nadddf3"
8431 [(set (match_operand:DF 0 "register_operand" "=e")
8432 (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8433 (match_operand:DF 2 "register_operand" "e"))))]
8435 "fnaddd\t%1, %2, %0"
8436 [(set_attr "type" "fp")
8437 (set_attr "fptype" "double")])
8439 (define_insn "*nmulsf3"
8440 [(set (match_operand:SF 0 "register_operand" "=f")
8441 (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8442 (match_operand:SF 2 "register_operand" "f")))]
8444 "fnmuls\t%1, %2, %0"
8445 [(set_attr "type" "fpmul")])
8447 (define_insn "*nmuldf3"
8448 [(set (match_operand:DF 0 "register_operand" "=e")
8449 (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8450 (match_operand:DF 2 "register_operand" "e")))]
8452 "fnmuld\t%1, %2, %0"
8453 [(set_attr "type" "fpmul")
8454 (set_attr "fptype" "double")])
8456 (define_insn "*nmuldf3_extend"
8457 [(set (match_operand:DF 0 "register_operand" "=e")
8458 (mult:DF (neg:DF (float_extend:DF
8459 (match_operand:SF 1 "register_operand" "f")))
8461 (match_operand:SF 2 "register_operand" "f"))))]
8463 "fnsmuld\t%1, %2, %0"
8464 [(set_attr "type" "fpmul")
8465 (set_attr "fptype" "double")])
8467 (define_insn "fhaddsf_vis"
8468 [(set (match_operand:SF 0 "register_operand" "=f")
8469 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8470 (match_operand:SF 2 "register_operand" "f")]
8473 "fhadds\t%1, %2, %0"
8474 [(set_attr "type" "fp")])
8476 (define_insn "fhadddf_vis"
8477 [(set (match_operand:DF 0 "register_operand" "=f")
8478 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8479 (match_operand:DF 2 "register_operand" "f")]
8482 "fhaddd\t%1, %2, %0"
8483 [(set_attr "type" "fp")
8484 (set_attr "fptype" "double")])
8486 (define_insn "fhsubsf_vis"
8487 [(set (match_operand:SF 0 "register_operand" "=f")
8488 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8489 (match_operand:SF 2 "register_operand" "f")]
8492 "fhsubs\t%1, %2, %0"
8493 [(set_attr "type" "fp")])
8495 (define_insn "fhsubdf_vis"
8496 [(set (match_operand:DF 0 "register_operand" "=f")
8497 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8498 (match_operand:DF 2 "register_operand" "f")]
8501 "fhsubd\t%1, %2, %0"
8502 [(set_attr "type" "fp")
8503 (set_attr "fptype" "double")])
8505 (define_insn "fnhaddsf_vis"
8506 [(set (match_operand:SF 0 "register_operand" "=f")
8507 (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8508 (match_operand:SF 2 "register_operand" "f")]
8511 "fnhadds\t%1, %2, %0"
8512 [(set_attr "type" "fp")])
8514 (define_insn "fnhadddf_vis"
8515 [(set (match_operand:DF 0 "register_operand" "=f")
8516 (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8517 (match_operand:DF 2 "register_operand" "f")]
8520 "fnhaddd\t%1, %2, %0"
8521 [(set_attr "type" "fp")
8522 (set_attr "fptype" "double")])
8524 (define_expand "umulxhi_vis"
8525 [(set (match_operand:DI 0 "register_operand" "")
8528 (mult:TI (zero_extend:TI
8529 (match_operand:DI 1 "arith_operand" ""))
8531 (match_operand:DI 2 "arith_operand" "")))
8535 if (! TARGET_ARCH64)
8537 emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8542 (define_insn "*umulxhi_sp64"
8543 [(set (match_operand:DI 0 "register_operand" "=r")
8546 (mult:TI (zero_extend:TI
8547 (match_operand:DI 1 "arith_operand" "%r"))
8549 (match_operand:DI 2 "arith_operand" "rI")))
8551 "TARGET_VIS3 && TARGET_ARCH64"
8552 "umulxhi\t%1, %2, %0"
8553 [(set_attr "type" "imul")])
8555 (define_insn "umulxhi_v8plus"
8556 [(set (match_operand:DI 0 "register_operand" "=r,h")
8559 (mult:TI (zero_extend:TI
8560 (match_operand:DI 1 "arith_operand" "%r,0"))
8562 (match_operand:DI 2 "arith_operand" "rI,rI")))
8564 (clobber (match_scratch:SI 3 "=&h,X"))
8565 (clobber (match_scratch:SI 4 "=&h,X"))]
8566 "TARGET_VIS3 && ! TARGET_ARCH64"
8567 "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8568 [(set_attr "type" "imul")
8569 (set_attr "length" "9,8")])
8571 (define_expand "xmulx_vis"
8572 [(set (match_operand:DI 0 "register_operand" "")
8574 (unspec:TI [(zero_extend:TI
8575 (match_operand:DI 1 "arith_operand" ""))
8577 (match_operand:DI 2 "arith_operand" ""))]
8581 if (! TARGET_ARCH64)
8583 emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8588 (define_insn "*xmulx_sp64"
8589 [(set (match_operand:DI 0 "register_operand" "=r")
8591 (unspec:TI [(zero_extend:TI
8592 (match_operand:DI 1 "arith_operand" "%r"))
8594 (match_operand:DI 2 "arith_operand" "rI"))]
8596 "TARGET_VIS3 && TARGET_ARCH64"
8598 [(set_attr "type" "imul")])
8600 (define_insn "xmulx_v8plus"
8601 [(set (match_operand:DI 0 "register_operand" "=r,h")
8603 (unspec:TI [(zero_extend:TI
8604 (match_operand:DI 1 "arith_operand" "%r,0"))
8606 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8608 (clobber (match_scratch:SI 3 "=&h,X"))
8609 (clobber (match_scratch:SI 4 "=&h,X"))]
8610 "TARGET_VIS3 && ! TARGET_ARCH64"
8611 "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8612 [(set_attr "type" "imul")
8613 (set_attr "length" "9,8")])
8615 (define_expand "xmulxhi_vis"
8616 [(set (match_operand:DI 0 "register_operand" "")
8619 (unspec:TI [(zero_extend:TI
8620 (match_operand:DI 1 "arith_operand" ""))
8622 (match_operand:DI 2 "arith_operand" ""))]
8627 if (! TARGET_ARCH64)
8629 emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
8634 (define_insn "*xmulxhi_sp64"
8635 [(set (match_operand:DI 0 "register_operand" "=r")
8638 (unspec:TI [(zero_extend:TI
8639 (match_operand:DI 1 "arith_operand" "%r"))
8641 (match_operand:DI 2 "arith_operand" "rI"))]
8644 "TARGET_VIS3 && TARGET_ARCH64"
8645 "xmulxhi\t%1, %2, %0"
8646 [(set_attr "type" "imul")])
8648 (define_insn "xmulxhi_v8plus"
8649 [(set (match_operand:DI 0 "register_operand" "=r,h")
8652 (unspec:TI [(zero_extend:TI
8653 (match_operand:DI 1 "arith_operand" "%r,0"))
8655 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8658 (clobber (match_scratch:SI 3 "=&h,X"))
8659 (clobber (match_scratch:SI 4 "=&h,X"))]
8660 "TARGET_VIS3 && !TARGET_ARCH64"
8661 "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
8662 [(set_attr "type" "imul")
8663 (set_attr "length" "9,8")])