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)
103 (UNSPECV_PROBE_STACK_RANGE 11)
196 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
197 (define_mode_iterator I [QI HI SI DI])
198 (define_mode_iterator F [SF DF TF])
200 ;; We don't define V1SI because SI should work just fine.
201 (define_mode_iterator V32 [SF V2HI V4QI])
202 (define_mode_iterator V32I [SI V2HI V4QI])
204 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
205 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
207 (define_mode_iterator V64N8 [V2SI V4HI])
209 (define_mode_iterator SIDI [SI DI])
211 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
212 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
213 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
214 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
215 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
217 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (SI "32s") (V2HI "16s")])
218 (define_mode_attr vconstr [(V2SI "e") (V4HI "e") (SI "f") (V2HI "f")])
220 ;; Attribute for cpu type.
221 ;; These must match the values for enum processor_type in sparc.h.
242 (const (symbol_ref "sparc_cpu_attr")))
244 ;; Attribute for the instruction set.
245 ;; At present we only need to distinguish v9/!v9, but for clarity we
246 ;; test TARGET_V8 too.
247 (define_attr "isa" "v7,v8,v9,sparclet"
249 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
250 (symbol_ref "TARGET_V8") (const_string "v8")
251 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
252 (const_string "v7"))))
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,!f,!f,!m,d,d")
1328 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,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
1341 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")])
1343 (define_insn "*movsi_lo_sum"
1344 [(set (match_operand:SI 0 "register_operand" "=r")
1345 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1346 (match_operand:SI 2 "immediate_operand" "in")))]
1348 "or\t%1, %%lo(%a2), %0")
1350 (define_insn "*movsi_high"
1351 [(set (match_operand:SI 0 "register_operand" "=r")
1352 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1354 "sethi\t%%hi(%a1), %0")
1356 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1357 ;; so that CSE won't optimize the address computation away.
1358 (define_insn "movsi_lo_sum_pic"
1359 [(set (match_operand:SI 0 "register_operand" "=r")
1360 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1361 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1364 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1365 return "xor\t%1, %%gdop_lox10(%a2), %0";
1367 return "or\t%1, %%lo(%a2), %0";
1371 (define_insn "movsi_high_pic"
1372 [(set (match_operand:SI 0 "register_operand" "=r")
1373 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1374 "flag_pic && check_pic (1)"
1376 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1377 return "sethi\t%%gdop_hix22(%a1), %0";
1379 return "sethi\t%%hi(%a1), %0";
1383 (define_insn "movsi_pic_gotdata_op"
1384 [(set (match_operand:SI 0 "register_operand" "=r")
1385 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1386 (match_operand:SI 2 "register_operand" "r")
1387 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1388 "flag_pic && check_pic (1)"
1390 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1391 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1393 return "ld\t[%1 + %2], %0";
1396 [(set_attr "type" "load")])
1398 (define_expand "movsi_pic_label_ref"
1399 [(set (match_dup 3) (high:SI
1400 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1401 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1402 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1403 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1404 (set (match_operand:SI 0 "register_operand" "=r")
1405 (minus:SI (match_dup 5) (match_dup 4)))]
1408 crtl->uses_pic_offset_table = 1;
1409 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1410 if (!can_create_pseudo_p ())
1412 operands[3] = operands[0];
1413 operands[4] = operands[0];
1417 operands[3] = gen_reg_rtx (SImode);
1418 operands[4] = gen_reg_rtx (SImode);
1420 operands[5] = pic_offset_table_rtx;
1423 (define_insn "*movsi_high_pic_label_ref"
1424 [(set (match_operand:SI 0 "register_operand" "=r")
1426 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1427 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1429 "sethi\t%%hi(%a2-(%a1-.)), %0")
1431 (define_insn "*movsi_lo_sum_pic_label_ref"
1432 [(set (match_operand:SI 0 "register_operand" "=r")
1433 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1434 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1435 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1437 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1439 ;; Set up the PIC register for VxWorks.
1441 (define_expand "vxworks_load_got"
1443 (high:SI (match_dup 1)))
1445 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1447 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1448 "TARGET_VXWORKS_RTP"
1450 operands[0] = pic_offset_table_rtx;
1451 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1452 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1455 (define_expand "movdi"
1456 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1457 (match_operand:DI 1 "general_operand" ""))]
1460 if (sparc_expand_move (DImode, operands))
1464 ;; Be careful, fmovd does not exist when !v9.
1465 ;; We match MEM moves directly when we have correct even
1466 ;; numbered registers, but fall into splits otherwise.
1467 ;; The constraint ordering here is really important to
1468 ;; avoid insane problems in reload, especially for patterns
1471 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1472 ;; (const_int -5016)))
1476 (define_insn "*movdi_insn_sp32"
1477 [(set (match_operand:DI 0 "nonimmediate_operand"
1478 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1479 (match_operand:DI 1 "input_operand"
1480 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1482 && (register_operand (operands[0], DImode)
1483 || register_or_zero_operand (operands[1], DImode))"
1497 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1498 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1500 (define_insn "*movdi_insn_sp32_v9"
1501 [(set (match_operand:DI 0 "nonimmediate_operand"
1502 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1503 (match_operand:DI 1 "input_operand"
1504 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1507 && (register_operand (operands[0], DImode)
1508 || register_or_zero_operand (operands[1], DImode))"
1525 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1526 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1527 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1529 (define_insn "*movdi_insn_sp64"
1530 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b,b")
1531 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J,P"))]
1533 && (register_operand (operands[0], DImode)
1534 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1537 sethi\t%%hi(%a1), %0
1545 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")
1546 (set_attr "fptype" "*,*,*,*,double,*,*,double,double")])
1548 (define_expand "movdi_pic_label_ref"
1549 [(set (match_dup 3) (high:DI
1550 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1551 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1552 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1553 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1554 (set (match_operand:DI 0 "register_operand" "=r")
1555 (minus:DI (match_dup 5) (match_dup 4)))]
1556 "TARGET_ARCH64 && flag_pic"
1558 crtl->uses_pic_offset_table = 1;
1559 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1560 if (!can_create_pseudo_p ())
1562 operands[3] = operands[0];
1563 operands[4] = operands[0];
1567 operands[3] = gen_reg_rtx (DImode);
1568 operands[4] = gen_reg_rtx (DImode);
1570 operands[5] = pic_offset_table_rtx;
1573 (define_insn "*movdi_high_pic_label_ref"
1574 [(set (match_operand:DI 0 "register_operand" "=r")
1576 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1577 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1578 "TARGET_ARCH64 && flag_pic"
1579 "sethi\t%%hi(%a2-(%a1-.)), %0")
1581 (define_insn "*movdi_lo_sum_pic_label_ref"
1582 [(set (match_operand:DI 0 "register_operand" "=r")
1583 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1584 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1585 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1586 "TARGET_ARCH64 && flag_pic"
1587 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1589 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1590 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1592 (define_insn "movdi_lo_sum_pic"
1593 [(set (match_operand:DI 0 "register_operand" "=r")
1594 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1595 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1596 "TARGET_ARCH64 && flag_pic"
1598 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1599 return "xor\t%1, %%gdop_lox10(%a2), %0";
1601 return "or\t%1, %%lo(%a2), %0";
1605 (define_insn "movdi_high_pic"
1606 [(set (match_operand:DI 0 "register_operand" "=r")
1607 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1608 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1610 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1611 return "sethi\t%%gdop_hix22(%a1), %0";
1613 return "sethi\t%%hi(%a1), %0";
1617 (define_insn "movdi_pic_gotdata_op"
1618 [(set (match_operand:DI 0 "register_operand" "=r")
1619 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1620 (match_operand:DI 2 "register_operand" "r")
1621 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1622 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1624 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1625 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1627 return "ldx\t[%1 + %2], %0";
1630 [(set_attr "type" "load")])
1632 (define_insn "*sethi_di_medlow_embmedany_pic"
1633 [(set (match_operand:DI 0 "register_operand" "=r")
1634 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1635 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1636 "sethi\t%%hi(%a1), %0")
1638 (define_insn "*sethi_di_medlow"
1639 [(set (match_operand:DI 0 "register_operand" "=r")
1640 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1641 "TARGET_CM_MEDLOW && check_pic (1)"
1642 "sethi\t%%hi(%a1), %0")
1644 (define_insn "*losum_di_medlow"
1645 [(set (match_operand:DI 0 "register_operand" "=r")
1646 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1647 (match_operand:DI 2 "symbolic_operand" "")))]
1649 "or\t%1, %%lo(%a2), %0")
1651 (define_insn "seth44"
1652 [(set (match_operand:DI 0 "register_operand" "=r")
1653 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1655 "sethi\t%%h44(%a1), %0")
1657 (define_insn "setm44"
1658 [(set (match_operand:DI 0 "register_operand" "=r")
1659 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1660 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1662 "or\t%1, %%m44(%a2), %0")
1664 (define_insn "setl44"
1665 [(set (match_operand:DI 0 "register_operand" "=r")
1666 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1667 (match_operand:DI 2 "symbolic_operand" "")))]
1669 "or\t%1, %%l44(%a2), %0")
1671 (define_insn "sethh"
1672 [(set (match_operand:DI 0 "register_operand" "=r")
1673 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1675 "sethi\t%%hh(%a1), %0")
1677 (define_insn "setlm"
1678 [(set (match_operand:DI 0 "register_operand" "=r")
1679 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1681 "sethi\t%%lm(%a1), %0")
1683 (define_insn "sethm"
1684 [(set (match_operand:DI 0 "register_operand" "=r")
1685 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1686 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1688 "or\t%1, %%hm(%a2), %0")
1690 (define_insn "setlo"
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 "symbolic_operand" "")))]
1695 "or\t%1, %%lo(%a2), %0")
1697 (define_insn "embmedany_sethi"
1698 [(set (match_operand:DI 0 "register_operand" "=r")
1699 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1700 "TARGET_CM_EMBMEDANY && check_pic (1)"
1701 "sethi\t%%hi(%a1), %0")
1703 (define_insn "embmedany_losum"
1704 [(set (match_operand:DI 0 "register_operand" "=r")
1705 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1706 (match_operand:DI 2 "data_segment_operand" "")))]
1707 "TARGET_CM_EMBMEDANY"
1708 "add\t%1, %%lo(%a2), %0")
1710 (define_insn "embmedany_brsum"
1711 [(set (match_operand:DI 0 "register_operand" "=r")
1712 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1713 "TARGET_CM_EMBMEDANY"
1716 (define_insn "embmedany_textuhi"
1717 [(set (match_operand:DI 0 "register_operand" "=r")
1718 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1719 "TARGET_CM_EMBMEDANY && check_pic (1)"
1720 "sethi\t%%uhi(%a1), %0")
1722 (define_insn "embmedany_texthi"
1723 [(set (match_operand:DI 0 "register_operand" "=r")
1724 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1725 "TARGET_CM_EMBMEDANY && check_pic (1)"
1726 "sethi\t%%hi(%a1), %0")
1728 (define_insn "embmedany_textulo"
1729 [(set (match_operand:DI 0 "register_operand" "=r")
1730 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1731 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1732 "TARGET_CM_EMBMEDANY"
1733 "or\t%1, %%ulo(%a2), %0")
1735 (define_insn "embmedany_textlo"
1736 [(set (match_operand:DI 0 "register_operand" "=r")
1737 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1738 (match_operand:DI 2 "text_segment_operand" "")))]
1739 "TARGET_CM_EMBMEDANY"
1740 "or\t%1, %%lo(%a2), %0")
1742 ;; Now some patterns to help reload out a bit.
1743 (define_expand "reload_indi"
1744 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1745 (match_operand:DI 1 "immediate_operand" "")
1746 (match_operand:TI 2 "register_operand" "=&r")])]
1748 || TARGET_CM_EMBMEDANY)
1751 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1755 (define_expand "reload_outdi"
1756 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1757 (match_operand:DI 1 "immediate_operand" "")
1758 (match_operand:TI 2 "register_operand" "=&r")])]
1760 || TARGET_CM_EMBMEDANY)
1763 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1767 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1769 [(set (match_operand:DI 0 "register_operand" "")
1770 (match_operand:DI 1 "const_int_operand" ""))]
1771 "! TARGET_ARCH64 && reload_completed"
1772 [(clobber (const_int 0))]
1774 #if HOST_BITS_PER_WIDE_INT == 32
1775 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1776 (INTVAL (operands[1]) < 0) ?
1779 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1782 unsigned int low, high;
1784 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1785 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1786 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1788 /* Slick... but this trick loses if this subreg constant part
1789 can be done in one insn. */
1791 && ! SPARC_SETHI32_P (high)
1792 && ! SPARC_SIMM13_P (high))
1793 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1794 gen_highpart (SImode, operands[0])));
1796 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1802 [(set (match_operand:DI 0 "register_operand" "")
1803 (match_operand:DI 1 "const_double_operand" ""))]
1807 && ((GET_CODE (operands[0]) == REG
1808 && REGNO (operands[0]) < 32)
1809 || (GET_CODE (operands[0]) == SUBREG
1810 && GET_CODE (SUBREG_REG (operands[0])) == REG
1811 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1812 [(clobber (const_int 0))]
1814 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1815 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1817 /* Slick... but this trick loses if this subreg constant part
1818 can be done in one insn. */
1819 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1820 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1821 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1823 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1824 gen_highpart (SImode, operands[0])));
1828 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1829 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1835 [(set (match_operand:DI 0 "register_operand" "")
1836 (match_operand:DI 1 "register_operand" ""))]
1840 && ((GET_CODE (operands[0]) == REG
1841 && REGNO (operands[0]) < 32)
1842 || (GET_CODE (operands[0]) == SUBREG
1843 && GET_CODE (SUBREG_REG (operands[0])) == REG
1844 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1845 [(clobber (const_int 0))]
1847 rtx set_dest = operands[0];
1848 rtx set_src = operands[1];
1852 dest1 = gen_highpart (SImode, set_dest);
1853 dest2 = gen_lowpart (SImode, set_dest);
1854 src1 = gen_highpart (SImode, set_src);
1855 src2 = gen_lowpart (SImode, set_src);
1857 /* Now emit using the real source and destination we found, swapping
1858 the order if we detect overlap. */
1859 if (reg_overlap_mentioned_p (dest1, src2))
1861 emit_insn (gen_movsi (dest2, src2));
1862 emit_insn (gen_movsi (dest1, src1));
1866 emit_insn (gen_movsi (dest1, src1));
1867 emit_insn (gen_movsi (dest2, src2));
1872 ;; Now handle the cases of memory moves from/to non-even
1873 ;; DI mode register pairs.
1875 [(set (match_operand:DI 0 "register_operand" "")
1876 (match_operand:DI 1 "memory_operand" ""))]
1879 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1880 [(clobber (const_int 0))]
1882 rtx word0 = adjust_address (operands[1], SImode, 0);
1883 rtx word1 = adjust_address (operands[1], SImode, 4);
1884 rtx high_part = gen_highpart (SImode, operands[0]);
1885 rtx low_part = gen_lowpart (SImode, operands[0]);
1887 if (reg_overlap_mentioned_p (high_part, word1))
1889 emit_insn (gen_movsi (low_part, word1));
1890 emit_insn (gen_movsi (high_part, word0));
1894 emit_insn (gen_movsi (high_part, word0));
1895 emit_insn (gen_movsi (low_part, word1));
1901 [(set (match_operand:DI 0 "memory_operand" "")
1902 (match_operand:DI 1 "register_operand" ""))]
1905 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1906 [(clobber (const_int 0))]
1908 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1909 gen_highpart (SImode, operands[1])));
1910 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1911 gen_lowpart (SImode, operands[1])));
1916 [(set (match_operand:DI 0 "memory_operand" "")
1917 (match_operand:DI 1 "const_zero_operand" ""))]
1921 && ! mem_min_alignment (operands[0], 8)))
1922 && offsettable_memref_p (operands[0])"
1923 [(clobber (const_int 0))]
1925 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1926 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1931 ;; Floating point and vector move instructions
1933 ;; Yes, you guessed it right, the former movsf expander.
1934 (define_expand "mov<V32:mode>"
1935 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1936 (match_operand:V32 1 "general_operand" ""))]
1937 "<V32:MODE>mode == SFmode || TARGET_VIS"
1939 if (sparc_expand_move (<V32:MODE>mode, operands))
1943 (define_insn "*movsf_insn"
1944 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,d,f,*r,*r,*r,f,*r,m,m")
1945 (match_operand:V32 1 "input_operand" "GY,ZC,f,*rRY,Q,S,m,m,f,*rGY"))]
1947 && (register_operand (operands[0], <V32:MODE>mode)
1948 || register_or_zero_or_all_ones_operand (operands[1], <V32:MODE>mode))"
1950 if (GET_CODE (operands[1]) == CONST_DOUBLE
1951 && (which_alternative == 3
1952 || which_alternative == 4
1953 || which_alternative == 5))
1958 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1959 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1960 operands[1] = GEN_INT (i);
1963 switch (which_alternative)
1966 return "fzeros\t%0";
1970 return "fmovs\t%1, %0";
1972 return "mov\t%1, %0";
1974 return "sethi\t%%hi(%a1), %0";
1979 return "ld\t%1, %0";
1982 return "st\t%r1, %0";
1987 [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1989 ;; Exactly the same as above, except that all `f' cases are deleted.
1990 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1993 (define_insn "*movsf_insn_no_fpu"
1994 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1995 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1997 && (register_operand (operands[0], SFmode)
1998 || register_or_zero_operand (operands[1], SFmode))"
2000 if (GET_CODE (operands[1]) == CONST_DOUBLE
2001 && (which_alternative == 0
2002 || which_alternative == 1
2003 || which_alternative == 2))
2008 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2009 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2010 operands[1] = GEN_INT (i);
2013 switch (which_alternative)
2016 return "mov\t%1, %0";
2018 return "sethi\t%%hi(%a1), %0";
2022 return "ld\t%1, %0";
2024 return "st\t%r1, %0";
2029 [(set_attr "type" "*,*,*,load,store")])
2031 ;; The following 3 patterns build SFmode constants in integer registers.
2033 (define_insn "*movsf_lo_sum"
2034 [(set (match_operand:SF 0 "register_operand" "=r")
2035 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2036 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2042 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2043 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2044 operands[2] = GEN_INT (i);
2045 return "or\t%1, %%lo(%a2), %0";
2048 (define_insn "*movsf_high"
2049 [(set (match_operand:SF 0 "register_operand" "=r")
2050 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2056 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2057 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2058 operands[1] = GEN_INT (i);
2059 return "sethi\t%%hi(%1), %0";
2063 [(set (match_operand:SF 0 "register_operand" "")
2064 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2065 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2066 [(set (match_dup 0) (high:SF (match_dup 1)))
2067 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2069 ;; Yes, you again guessed it right, the former movdf expander.
2070 (define_expand "mov<V64:mode>"
2071 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2072 (match_operand:V64 1 "general_operand" ""))]
2073 "<V64:MODE>mode == DFmode || TARGET_VIS"
2075 if (sparc_expand_move (<V64:MODE>mode, operands))
2079 ;; Be careful, fmovd does not exist when !v9.
2080 (define_insn "*movdf_insn_sp32"
2081 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2082 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2085 && (register_operand (operands[0], DFmode)
2086 || register_or_zero_operand (operands[1], DFmode))"
2098 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2099 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2101 (define_insn "*movdf_insn_sp32_no_fpu"
2102 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2103 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2106 && (register_operand (operands[0], DFmode)
2107 || register_or_zero_operand (operands[1], DFmode))"
2114 [(set_attr "type" "load,store,*,*,*")
2115 (set_attr "length" "*,*,2,2,2")])
2117 ;; We have available v9 double floats but not 64-bit integer registers.
2118 (define_insn "*movdf_insn_sp32_v9"
2119 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,T,W,U,T,f,*r,o")
2120 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2124 && (register_operand (operands[0], <V64:MODE>mode)
2125 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2138 [(set_attr "type" "fga,fga,fpmove,load,store,store,load,store,*,*,*")
2139 (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")
2140 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*")])
2142 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2143 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2144 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2148 && (register_operand (operands[0], DFmode)
2149 || register_or_zero_operand (operands[1], DFmode))"
2156 [(set_attr "type" "load,store,store,*,*")
2157 (set_attr "length" "*,*,*,2,2")])
2159 ;; We have available both v9 double floats and 64-bit integer registers.
2160 (define_insn "*movdf_insn_sp64"
2161 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,W,*r,*r,m,*r")
2162 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,e,*rGY,m,*rGY,DF"))]
2165 && (register_operand (operands[0], <V64:MODE>mode)
2166 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2177 [(set_attr "type" "fga,fga,fpmove,load,store,*,load,store,*")
2178 (set_attr "length" "*,*,*,*,*,*,*,*,2")
2179 (set_attr "fptype" "double,double,double,*,*,*,*,*,*")])
2181 (define_insn "*movdf_insn_sp64_no_fpu"
2182 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2183 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2186 && (register_operand (operands[0], DFmode)
2187 || register_or_zero_operand (operands[1], DFmode))"
2192 [(set_attr "type" "*,load,store")])
2194 ;; This pattern builds V64mode constants in integer registers.
2196 [(set (match_operand:V64 0 "register_operand" "")
2197 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2199 && (GET_CODE (operands[0]) == REG
2200 && REGNO (operands[0]) < 32)
2201 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2202 && reload_completed"
2203 [(clobber (const_int 0))]
2205 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2209 #if HOST_BITS_PER_WIDE_INT == 32
2212 enum machine_mode mode = GET_MODE (operands[1]);
2213 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2214 emit_insn (gen_movdi (operands[0], tem));
2219 enum machine_mode mode = GET_MODE (operands[1]);
2220 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2221 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2223 gcc_assert (GET_CODE (hi) == CONST_INT);
2224 gcc_assert (GET_CODE (lo) == CONST_INT);
2226 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2228 /* Slick... but this trick loses if this subreg constant part
2229 can be done in one insn. */
2231 && ! SPARC_SETHI32_P (INTVAL (hi))
2232 && ! SPARC_SIMM13_P (INTVAL (hi)))
2234 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2235 gen_highpart (SImode, operands[0])));
2239 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2245 ;; Ok, now the splits to handle all the multi insn and
2246 ;; mis-aligned memory address cases.
2247 ;; In these splits please take note that we must be
2248 ;; careful when V9 but not ARCH64 because the integer
2249 ;; register DFmode cases must be handled.
2251 [(set (match_operand:V64 0 "register_operand" "")
2252 (match_operand:V64 1 "register_operand" ""))]
2255 && ((GET_CODE (operands[0]) == REG
2256 && REGNO (operands[0]) < 32)
2257 || (GET_CODE (operands[0]) == SUBREG
2258 && GET_CODE (SUBREG_REG (operands[0])) == REG
2259 && REGNO (SUBREG_REG (operands[0])) < 32))))
2260 && reload_completed"
2261 [(clobber (const_int 0))]
2263 rtx set_dest = operands[0];
2264 rtx set_src = operands[1];
2267 enum machine_mode half_mode;
2269 /* We can be expanded for DFmode or integral vector modes. */
2270 if (<V64:MODE>mode == DFmode)
2275 dest1 = gen_highpart (half_mode, set_dest);
2276 dest2 = gen_lowpart (half_mode, set_dest);
2277 src1 = gen_highpart (half_mode, set_src);
2278 src2 = gen_lowpart (half_mode, set_src);
2280 /* Now emit using the real source and destination we found, swapping
2281 the order if we detect overlap. */
2282 if (reg_overlap_mentioned_p (dest1, src2))
2284 emit_move_insn_1 (dest2, src2);
2285 emit_move_insn_1 (dest1, src1);
2289 emit_move_insn_1 (dest1, src1);
2290 emit_move_insn_1 (dest2, src2);
2296 [(set (match_operand:V64 0 "register_operand" "")
2297 (match_operand:V64 1 "memory_operand" ""))]
2300 && (((REGNO (operands[0]) % 2) != 0)
2301 || ! mem_min_alignment (operands[1], 8))
2302 && offsettable_memref_p (operands[1])"
2303 [(clobber (const_int 0))]
2305 enum machine_mode half_mode;
2308 /* We can be expanded for DFmode or integral vector modes. */
2309 if (<V64:MODE>mode == DFmode)
2314 word0 = adjust_address (operands[1], half_mode, 0);
2315 word1 = adjust_address (operands[1], half_mode, 4);
2317 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2319 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2320 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2324 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2325 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2331 [(set (match_operand:V64 0 "memory_operand" "")
2332 (match_operand:V64 1 "register_operand" ""))]
2335 && (((REGNO (operands[1]) % 2) != 0)
2336 || ! mem_min_alignment (operands[0], 8))
2337 && offsettable_memref_p (operands[0])"
2338 [(clobber (const_int 0))]
2340 enum machine_mode half_mode;
2343 /* We can be expanded for DFmode or integral vector modes. */
2344 if (<V64:MODE>mode == DFmode)
2349 word0 = adjust_address (operands[0], half_mode, 0);
2350 word1 = adjust_address (operands[0], half_mode, 4);
2352 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2353 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2358 [(set (match_operand:V64 0 "memory_operand" "")
2359 (match_operand:V64 1 "const_zero_operand" ""))]
2363 && ! mem_min_alignment (operands[0], 8)))
2364 && offsettable_memref_p (operands[0])"
2365 [(clobber (const_int 0))]
2367 enum machine_mode half_mode;
2370 /* We can be expanded for DFmode or integral vector modes. */
2371 if (<V64:MODE>mode == DFmode)
2376 dest1 = adjust_address (operands[0], half_mode, 0);
2377 dest2 = adjust_address (operands[0], half_mode, 4);
2379 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2380 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2385 [(set (match_operand:V64 0 "register_operand" "")
2386 (match_operand:V64 1 "const_zero_operand" ""))]
2389 && ((GET_CODE (operands[0]) == REG
2390 && REGNO (operands[0]) < 32)
2391 || (GET_CODE (operands[0]) == SUBREG
2392 && GET_CODE (SUBREG_REG (operands[0])) == REG
2393 && REGNO (SUBREG_REG (operands[0])) < 32))"
2394 [(clobber (const_int 0))]
2396 enum machine_mode half_mode;
2397 rtx set_dest = operands[0];
2400 /* We can be expanded for DFmode or integral vector modes. */
2401 if (<V64:MODE>mode == DFmode)
2406 dest1 = gen_highpart (half_mode, set_dest);
2407 dest2 = gen_lowpart (half_mode, set_dest);
2408 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2409 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2413 (define_expand "movtf"
2414 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2415 (match_operand:TF 1 "general_operand" ""))]
2418 if (sparc_expand_move (TFmode, operands))
2422 (define_insn "*movtf_insn_sp32"
2423 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2424 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2427 && (register_operand (operands[0], TFmode)
2428 || register_or_zero_operand (operands[1], TFmode))"
2430 [(set_attr "length" "4")])
2432 ;; Exactly the same as above, except that all `e' cases are deleted.
2433 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2436 (define_insn "*movtf_insn_sp32_no_fpu"
2437 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2438 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2441 && (register_operand (operands[0], TFmode)
2442 || register_or_zero_operand (operands[1], TFmode))"
2444 [(set_attr "length" "4")])
2446 (define_insn "*movtf_insn_sp64"
2447 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2448 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2451 && ! TARGET_HARD_QUAD
2452 && (register_operand (operands[0], TFmode)
2453 || register_or_zero_operand (operands[1], TFmode))"
2455 [(set_attr "length" "2")])
2457 (define_insn "*movtf_insn_sp64_hq"
2458 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2459 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2463 && (register_operand (operands[0], TFmode)
2464 || register_or_zero_operand (operands[1], TFmode))"
2472 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2473 (set_attr "length" "2,*,*,*,2,2")])
2475 (define_insn "*movtf_insn_sp64_no_fpu"
2476 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2477 (match_operand:TF 1 "input_operand" "orG,rG"))]
2480 && (register_operand (operands[0], TFmode)
2481 || register_or_zero_operand (operands[1], TFmode))"
2483 [(set_attr "length" "2")])
2485 ;; Now all the splits to handle multi-insn TF mode moves.
2487 [(set (match_operand:TF 0 "register_operand" "")
2488 (match_operand:TF 1 "register_operand" ""))]
2492 && ! TARGET_HARD_QUAD)
2493 || ! fp_register_operand (operands[0], TFmode))"
2494 [(clobber (const_int 0))]
2496 rtx set_dest = operands[0];
2497 rtx set_src = operands[1];
2501 dest1 = gen_df_reg (set_dest, 0);
2502 dest2 = gen_df_reg (set_dest, 1);
2503 src1 = gen_df_reg (set_src, 0);
2504 src2 = gen_df_reg (set_src, 1);
2506 /* Now emit using the real source and destination we found, swapping
2507 the order if we detect overlap. */
2508 if (reg_overlap_mentioned_p (dest1, src2))
2510 emit_insn (gen_movdf (dest2, src2));
2511 emit_insn (gen_movdf (dest1, src1));
2515 emit_insn (gen_movdf (dest1, src1));
2516 emit_insn (gen_movdf (dest2, src2));
2522 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2523 (match_operand:TF 1 "const_zero_operand" ""))]
2525 [(clobber (const_int 0))]
2527 rtx set_dest = operands[0];
2530 switch (GET_CODE (set_dest))
2533 dest1 = gen_df_reg (set_dest, 0);
2534 dest2 = gen_df_reg (set_dest, 1);
2537 dest1 = adjust_address (set_dest, DFmode, 0);
2538 dest2 = adjust_address (set_dest, DFmode, 8);
2544 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2545 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2550 [(set (match_operand:TF 0 "register_operand" "")
2551 (match_operand:TF 1 "memory_operand" ""))]
2553 && offsettable_memref_p (operands[1])
2555 || ! TARGET_HARD_QUAD
2556 || ! fp_register_operand (operands[0], TFmode)))"
2557 [(clobber (const_int 0))]
2559 rtx word0 = adjust_address (operands[1], DFmode, 0);
2560 rtx word1 = adjust_address (operands[1], DFmode, 8);
2561 rtx set_dest, dest1, dest2;
2563 set_dest = operands[0];
2565 dest1 = gen_df_reg (set_dest, 0);
2566 dest2 = gen_df_reg (set_dest, 1);
2568 /* Now output, ordering such that we don't clobber any registers
2569 mentioned in the address. */
2570 if (reg_overlap_mentioned_p (dest1, word1))
2573 emit_insn (gen_movdf (dest2, word1));
2574 emit_insn (gen_movdf (dest1, word0));
2578 emit_insn (gen_movdf (dest1, word0));
2579 emit_insn (gen_movdf (dest2, word1));
2585 [(set (match_operand:TF 0 "memory_operand" "")
2586 (match_operand:TF 1 "register_operand" ""))]
2588 && offsettable_memref_p (operands[0])
2590 || ! TARGET_HARD_QUAD
2591 || ! fp_register_operand (operands[1], TFmode)))"
2592 [(clobber (const_int 0))]
2594 rtx set_src = operands[1];
2596 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2597 gen_df_reg (set_src, 0)));
2598 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2599 gen_df_reg (set_src, 1)));
2604 ;; SPARC-V9 conditional move instructions
2606 ;; We can handle larger constants here for some flavors, but for now we keep
2607 ;; it simple and only allow those constants supported by all flavors.
2608 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2609 ;; 3 contains the constant if one is present, but we handle either for
2610 ;; generality (sparc.c puts a constant in operand 2).
2612 (define_expand "mov<I:mode>cc"
2613 [(set (match_operand:I 0 "register_operand" "")
2614 (if_then_else:I (match_operand 1 "comparison_operator" "")
2615 (match_operand:I 2 "arith10_operand" "")
2616 (match_operand:I 3 "arith10_operand" "")))]
2617 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2619 enum rtx_code code = GET_CODE (operands[1]);
2622 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2626 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2628 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2629 GET_CODE (operands[1]));
2631 if (XEXP (operands[1], 1) == const0_rtx
2632 && GET_CODE (XEXP (operands[1], 0)) == REG
2633 && GET_MODE (XEXP (operands[1], 0)) == DImode
2634 && v9_regcmp_p (code))
2635 cc_reg = XEXP (operands[1], 0);
2637 cc_reg = gen_compare_reg (operands[1]);
2639 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2642 (define_expand "mov<F:mode>cc"
2643 [(set (match_operand:F 0 "register_operand" "")
2644 (if_then_else:F (match_operand 1 "comparison_operator" "")
2645 (match_operand:F 2 "register_operand" "")
2646 (match_operand:F 3 "register_operand" "")))]
2647 "TARGET_V9 && TARGET_FPU"
2649 enum rtx_code code = GET_CODE (operands[1]);
2652 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2656 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2658 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2659 GET_CODE (operands[1]));
2661 if (XEXP (operands[1], 1) == const0_rtx
2662 && GET_CODE (XEXP (operands[1], 0)) == REG
2663 && GET_MODE (XEXP (operands[1], 0)) == DImode
2664 && v9_regcmp_p (code))
2665 cc_reg = XEXP (operands[1], 0);
2667 cc_reg = gen_compare_reg (operands[1]);
2669 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2672 ;; Conditional move define_insns
2674 (define_insn "*mov<I:mode>_cc_v9"
2675 [(set (match_operand:I 0 "register_operand" "=r,r")
2676 (if_then_else:I (match_operator 1 "comparison_operator"
2677 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2679 (match_operand:I 3 "arith11_operand" "rL,0")
2680 (match_operand:I 4 "arith11_operand" "0,rL")))]
2681 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2684 mov%c1\t%x2, %4, %0"
2685 [(set_attr "type" "cmove")])
2687 (define_insn "*mov<I:mode>_cc_reg_sp64"
2688 [(set (match_operand:I 0 "register_operand" "=r,r")
2689 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2690 [(match_operand:DI 2 "register_operand" "r,r")
2692 (match_operand:I 3 "arith10_operand" "rM,0")
2693 (match_operand:I 4 "arith10_operand" "0,rM")))]
2696 movr%D1\t%2, %r3, %0
2697 movr%d1\t%2, %r4, %0"
2698 [(set_attr "type" "cmove")])
2700 (define_insn "*movsf_cc_v9"
2701 [(set (match_operand:SF 0 "register_operand" "=f,f")
2702 (if_then_else:SF (match_operator 1 "comparison_operator"
2703 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2705 (match_operand:SF 3 "register_operand" "f,0")
2706 (match_operand:SF 4 "register_operand" "0,f")))]
2707 "TARGET_V9 && TARGET_FPU"
2709 fmovs%C1\t%x2, %3, %0
2710 fmovs%c1\t%x2, %4, %0"
2711 [(set_attr "type" "fpcmove")])
2713 (define_insn "*movsf_cc_reg_sp64"
2714 [(set (match_operand:SF 0 "register_operand" "=f,f")
2715 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2716 [(match_operand:DI 2 "register_operand" "r,r")
2718 (match_operand:SF 3 "register_operand" "f,0")
2719 (match_operand:SF 4 "register_operand" "0,f")))]
2720 "TARGET_ARCH64 && TARGET_FPU"
2722 fmovrs%D1\t%2, %3, %0
2723 fmovrs%d1\t%2, %4, %0"
2724 [(set_attr "type" "fpcrmove")])
2726 ;; Named because invoked by movtf_cc_v9
2727 (define_insn "movdf_cc_v9"
2728 [(set (match_operand:DF 0 "register_operand" "=e,e")
2729 (if_then_else:DF (match_operator 1 "comparison_operator"
2730 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2732 (match_operand:DF 3 "register_operand" "e,0")
2733 (match_operand:DF 4 "register_operand" "0,e")))]
2734 "TARGET_V9 && TARGET_FPU"
2736 fmovd%C1\t%x2, %3, %0
2737 fmovd%c1\t%x2, %4, %0"
2738 [(set_attr "type" "fpcmove")
2739 (set_attr "fptype" "double")])
2741 ;; Named because invoked by movtf_cc_reg_sp64
2742 (define_insn "movdf_cc_reg_sp64"
2743 [(set (match_operand:DF 0 "register_operand" "=e,e")
2744 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2745 [(match_operand:DI 2 "register_operand" "r,r")
2747 (match_operand:DF 3 "register_operand" "e,0")
2748 (match_operand:DF 4 "register_operand" "0,e")))]
2749 "TARGET_ARCH64 && TARGET_FPU"
2751 fmovrd%D1\t%2, %3, %0
2752 fmovrd%d1\t%2, %4, %0"
2753 [(set_attr "type" "fpcrmove")
2754 (set_attr "fptype" "double")])
2756 (define_insn "*movtf_cc_hq_v9"
2757 [(set (match_operand:TF 0 "register_operand" "=e,e")
2758 (if_then_else:TF (match_operator 1 "comparison_operator"
2759 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2761 (match_operand:TF 3 "register_operand" "e,0")
2762 (match_operand:TF 4 "register_operand" "0,e")))]
2763 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2765 fmovq%C1\t%x2, %3, %0
2766 fmovq%c1\t%x2, %4, %0"
2767 [(set_attr "type" "fpcmove")])
2769 (define_insn "*movtf_cc_reg_hq_sp64"
2770 [(set (match_operand:TF 0 "register_operand" "=e,e")
2771 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2772 [(match_operand:DI 2 "register_operand" "r,r")
2774 (match_operand:TF 3 "register_operand" "e,0")
2775 (match_operand:TF 4 "register_operand" "0,e")))]
2776 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2778 fmovrq%D1\t%2, %3, %0
2779 fmovrq%d1\t%2, %4, %0"
2780 [(set_attr "type" "fpcrmove")])
2782 (define_insn_and_split "*movtf_cc_v9"
2783 [(set (match_operand:TF 0 "register_operand" "=e,e")
2784 (if_then_else:TF (match_operator 1 "comparison_operator"
2785 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2787 (match_operand:TF 3 "register_operand" "e,0")
2788 (match_operand:TF 4 "register_operand" "0,e")))]
2789 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2791 "&& reload_completed"
2792 [(clobber (const_int 0))]
2794 rtx set_dest = operands[0];
2795 rtx set_srca = operands[3];
2796 rtx set_srcb = operands[4];
2797 int third = rtx_equal_p (set_dest, set_srca);
2799 rtx srca1, srca2, srcb1, srcb2;
2801 dest1 = gen_df_reg (set_dest, 0);
2802 dest2 = gen_df_reg (set_dest, 1);
2803 srca1 = gen_df_reg (set_srca, 0);
2804 srca2 = gen_df_reg (set_srca, 1);
2805 srcb1 = gen_df_reg (set_srcb, 0);
2806 srcb2 = gen_df_reg (set_srcb, 1);
2808 /* Now emit using the real source and destination we found, swapping
2809 the order if we detect overlap. */
2810 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2811 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2813 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2814 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2818 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2819 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2823 [(set_attr "length" "2")])
2825 (define_insn_and_split "*movtf_cc_reg_sp64"
2826 [(set (match_operand:TF 0 "register_operand" "=e,e")
2827 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2828 [(match_operand:DI 2 "register_operand" "r,r")
2830 (match_operand:TF 3 "register_operand" "e,0")
2831 (match_operand:TF 4 "register_operand" "0,e")))]
2832 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2834 "&& reload_completed"
2835 [(clobber (const_int 0))]
2837 rtx set_dest = operands[0];
2838 rtx set_srca = operands[3];
2839 rtx set_srcb = operands[4];
2840 int third = rtx_equal_p (set_dest, set_srca);
2842 rtx srca1, srca2, srcb1, srcb2;
2844 dest1 = gen_df_reg (set_dest, 0);
2845 dest2 = gen_df_reg (set_dest, 1);
2846 srca1 = gen_df_reg (set_srca, 0);
2847 srca2 = gen_df_reg (set_srca, 1);
2848 srcb1 = gen_df_reg (set_srcb, 0);
2849 srcb2 = gen_df_reg (set_srcb, 1);
2851 /* Now emit using the real source and destination we found, swapping
2852 the order if we detect overlap. */
2853 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2854 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2856 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2857 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2861 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2862 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2866 [(set_attr "length" "2")])
2869 ;; Zero-extension instructions
2871 ;; These patterns originally accepted general_operands, however, slightly
2872 ;; better code is generated by only accepting register_operands, and then
2873 ;; letting combine generate the ldu[hb] insns.
2875 (define_expand "zero_extendhisi2"
2876 [(set (match_operand:SI 0 "register_operand" "")
2877 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2880 rtx temp = gen_reg_rtx (SImode);
2881 rtx shift_16 = GEN_INT (16);
2882 int op1_subbyte = 0;
2884 if (GET_CODE (operand1) == SUBREG)
2886 op1_subbyte = SUBREG_BYTE (operand1);
2887 op1_subbyte /= GET_MODE_SIZE (SImode);
2888 op1_subbyte *= GET_MODE_SIZE (SImode);
2889 operand1 = XEXP (operand1, 0);
2892 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2894 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2898 (define_insn "*zero_extendhisi2_insn"
2899 [(set (match_operand:SI 0 "register_operand" "=r")
2900 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2903 [(set_attr "type" "load")
2904 (set_attr "us3load_type" "3cycle")])
2906 (define_expand "zero_extendqihi2"
2907 [(set (match_operand:HI 0 "register_operand" "")
2908 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2912 (define_insn "*zero_extendqihi2_insn"
2913 [(set (match_operand:HI 0 "register_operand" "=r,r")
2914 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2915 "GET_CODE (operands[1]) != CONST_INT"
2919 [(set_attr "type" "*,load")
2920 (set_attr "us3load_type" "*,3cycle")])
2922 (define_expand "zero_extendqisi2"
2923 [(set (match_operand:SI 0 "register_operand" "")
2924 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2928 (define_insn "*zero_extendqisi2_insn"
2929 [(set (match_operand:SI 0 "register_operand" "=r,r")
2930 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2931 "GET_CODE (operands[1]) != CONST_INT"
2935 [(set_attr "type" "*,load")
2936 (set_attr "us3load_type" "*,3cycle")])
2938 (define_expand "zero_extendqidi2"
2939 [(set (match_operand:DI 0 "register_operand" "")
2940 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2944 (define_insn "*zero_extendqidi2_insn"
2945 [(set (match_operand:DI 0 "register_operand" "=r,r")
2946 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2947 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2951 [(set_attr "type" "*,load")
2952 (set_attr "us3load_type" "*,3cycle")])
2954 (define_expand "zero_extendhidi2"
2955 [(set (match_operand:DI 0 "register_operand" "")
2956 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2959 rtx temp = gen_reg_rtx (DImode);
2960 rtx shift_48 = GEN_INT (48);
2961 int op1_subbyte = 0;
2963 if (GET_CODE (operand1) == SUBREG)
2965 op1_subbyte = SUBREG_BYTE (operand1);
2966 op1_subbyte /= GET_MODE_SIZE (DImode);
2967 op1_subbyte *= GET_MODE_SIZE (DImode);
2968 operand1 = XEXP (operand1, 0);
2971 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2973 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2977 (define_insn "*zero_extendhidi2_insn"
2978 [(set (match_operand:DI 0 "register_operand" "=r")
2979 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2982 [(set_attr "type" "load")
2983 (set_attr "us3load_type" "3cycle")])
2985 ;; ??? Write truncdisi pattern using sra?
2987 (define_expand "zero_extendsidi2"
2988 [(set (match_operand:DI 0 "register_operand" "")
2989 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2993 (define_insn "*zero_extendsidi2_insn_sp64"
2994 [(set (match_operand:DI 0 "register_operand" "=r,r")
2995 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2996 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3000 [(set_attr "type" "shift,load")])
3002 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3003 [(set (match_operand:DI 0 "register_operand" "=r")
3004 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3007 "&& reload_completed"
3008 [(set (match_dup 2) (match_dup 3))
3009 (set (match_dup 4) (match_dup 5))]
3013 dest1 = gen_highpart (SImode, operands[0]);
3014 dest2 = gen_lowpart (SImode, operands[0]);
3016 /* Swap the order in case of overlap. */
3017 if (REGNO (dest1) == REGNO (operands[1]))
3019 operands[2] = dest2;
3020 operands[3] = operands[1];
3021 operands[4] = dest1;
3022 operands[5] = const0_rtx;
3026 operands[2] = dest1;
3027 operands[3] = const0_rtx;
3028 operands[4] = dest2;
3029 operands[5] = operands[1];
3032 [(set_attr "length" "2")])
3034 ;; Simplify comparisons of extended values.
3036 (define_insn "*cmp_zero_extendqisi2"
3037 [(set (reg:CC CC_REG)
3038 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3041 "andcc\t%0, 0xff, %%g0"
3042 [(set_attr "type" "compare")])
3044 (define_insn "*cmp_zero_qi"
3045 [(set (reg:CC CC_REG)
3046 (compare:CC (match_operand:QI 0 "register_operand" "r")
3049 "andcc\t%0, 0xff, %%g0"
3050 [(set_attr "type" "compare")])
3052 (define_insn "*cmp_zero_extendqisi2_set"
3053 [(set (reg:CC CC_REG)
3054 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3056 (set (match_operand:SI 0 "register_operand" "=r")
3057 (zero_extend:SI (match_dup 1)))]
3059 "andcc\t%1, 0xff, %0"
3060 [(set_attr "type" "compare")])
3062 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3063 [(set (reg:CC CC_REG)
3064 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3067 (set (match_operand:SI 0 "register_operand" "=r")
3068 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3070 "andcc\t%1, 0xff, %0"
3071 [(set_attr "type" "compare")])
3073 (define_insn "*cmp_zero_extendqidi2"
3074 [(set (reg:CCX CC_REG)
3075 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3078 "andcc\t%0, 0xff, %%g0"
3079 [(set_attr "type" "compare")])
3081 (define_insn "*cmp_zero_qi_sp64"
3082 [(set (reg:CCX CC_REG)
3083 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3086 "andcc\t%0, 0xff, %%g0"
3087 [(set_attr "type" "compare")])
3089 (define_insn "*cmp_zero_extendqidi2_set"
3090 [(set (reg:CCX CC_REG)
3091 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3093 (set (match_operand:DI 0 "register_operand" "=r")
3094 (zero_extend:DI (match_dup 1)))]
3096 "andcc\t%1, 0xff, %0"
3097 [(set_attr "type" "compare")])
3099 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3100 [(set (reg:CCX CC_REG)
3101 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3104 (set (match_operand:DI 0 "register_operand" "=r")
3105 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3107 "andcc\t%1, 0xff, %0"
3108 [(set_attr "type" "compare")])
3110 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3112 (define_insn "*cmp_siqi_trunc"
3113 [(set (reg:CC CC_REG)
3114 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3117 "andcc\t%0, 0xff, %%g0"
3118 [(set_attr "type" "compare")])
3120 (define_insn "*cmp_siqi_trunc_set"
3121 [(set (reg:CC CC_REG)
3122 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3124 (set (match_operand:QI 0 "register_operand" "=r")
3125 (subreg:QI (match_dup 1) 3))]
3127 "andcc\t%1, 0xff, %0"
3128 [(set_attr "type" "compare")])
3130 (define_insn "*cmp_diqi_trunc"
3131 [(set (reg:CC CC_REG)
3132 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3135 "andcc\t%0, 0xff, %%g0"
3136 [(set_attr "type" "compare")])
3138 (define_insn "*cmp_diqi_trunc_set"
3139 [(set (reg:CC CC_REG)
3140 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3142 (set (match_operand:QI 0 "register_operand" "=r")
3143 (subreg:QI (match_dup 1) 7))]
3145 "andcc\t%1, 0xff, %0"
3146 [(set_attr "type" "compare")])
3149 ;; Sign-extension instructions
3151 ;; These patterns originally accepted general_operands, however, slightly
3152 ;; better code is generated by only accepting register_operands, and then
3153 ;; letting combine generate the lds[hb] insns.
3155 (define_expand "extendhisi2"
3156 [(set (match_operand:SI 0 "register_operand" "")
3157 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3160 rtx temp = gen_reg_rtx (SImode);
3161 rtx shift_16 = GEN_INT (16);
3162 int op1_subbyte = 0;
3164 if (GET_CODE (operand1) == SUBREG)
3166 op1_subbyte = SUBREG_BYTE (operand1);
3167 op1_subbyte /= GET_MODE_SIZE (SImode);
3168 op1_subbyte *= GET_MODE_SIZE (SImode);
3169 operand1 = XEXP (operand1, 0);
3172 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3174 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3178 (define_insn "*sign_extendhisi2_insn"
3179 [(set (match_operand:SI 0 "register_operand" "=r")
3180 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3183 [(set_attr "type" "sload")
3184 (set_attr "us3load_type" "3cycle")])
3186 (define_expand "extendqihi2"
3187 [(set (match_operand:HI 0 "register_operand" "")
3188 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3191 rtx temp = gen_reg_rtx (SImode);
3192 rtx shift_24 = GEN_INT (24);
3193 int op1_subbyte = 0;
3194 int op0_subbyte = 0;
3196 if (GET_CODE (operand1) == SUBREG)
3198 op1_subbyte = SUBREG_BYTE (operand1);
3199 op1_subbyte /= GET_MODE_SIZE (SImode);
3200 op1_subbyte *= GET_MODE_SIZE (SImode);
3201 operand1 = XEXP (operand1, 0);
3203 if (GET_CODE (operand0) == SUBREG)
3205 op0_subbyte = SUBREG_BYTE (operand0);
3206 op0_subbyte /= GET_MODE_SIZE (SImode);
3207 op0_subbyte *= GET_MODE_SIZE (SImode);
3208 operand0 = XEXP (operand0, 0);
3210 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3212 if (GET_MODE (operand0) != SImode)
3213 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3214 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3218 (define_insn "*sign_extendqihi2_insn"
3219 [(set (match_operand:HI 0 "register_operand" "=r")
3220 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3223 [(set_attr "type" "sload")
3224 (set_attr "us3load_type" "3cycle")])
3226 (define_expand "extendqisi2"
3227 [(set (match_operand:SI 0 "register_operand" "")
3228 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3231 rtx temp = gen_reg_rtx (SImode);
3232 rtx shift_24 = GEN_INT (24);
3233 int op1_subbyte = 0;
3235 if (GET_CODE (operand1) == SUBREG)
3237 op1_subbyte = SUBREG_BYTE (operand1);
3238 op1_subbyte /= GET_MODE_SIZE (SImode);
3239 op1_subbyte *= GET_MODE_SIZE (SImode);
3240 operand1 = XEXP (operand1, 0);
3243 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3245 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3249 (define_insn "*sign_extendqisi2_insn"
3250 [(set (match_operand:SI 0 "register_operand" "=r")
3251 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3254 [(set_attr "type" "sload")
3255 (set_attr "us3load_type" "3cycle")])
3257 (define_expand "extendqidi2"
3258 [(set (match_operand:DI 0 "register_operand" "")
3259 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3262 rtx temp = gen_reg_rtx (DImode);
3263 rtx shift_56 = GEN_INT (56);
3264 int op1_subbyte = 0;
3266 if (GET_CODE (operand1) == SUBREG)
3268 op1_subbyte = SUBREG_BYTE (operand1);
3269 op1_subbyte /= GET_MODE_SIZE (DImode);
3270 op1_subbyte *= GET_MODE_SIZE (DImode);
3271 operand1 = XEXP (operand1, 0);
3274 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3276 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3280 (define_insn "*sign_extendqidi2_insn"
3281 [(set (match_operand:DI 0 "register_operand" "=r")
3282 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3285 [(set_attr "type" "sload")
3286 (set_attr "us3load_type" "3cycle")])
3288 (define_expand "extendhidi2"
3289 [(set (match_operand:DI 0 "register_operand" "")
3290 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3293 rtx temp = gen_reg_rtx (DImode);
3294 rtx shift_48 = GEN_INT (48);
3295 int op1_subbyte = 0;
3297 if (GET_CODE (operand1) == SUBREG)
3299 op1_subbyte = SUBREG_BYTE (operand1);
3300 op1_subbyte /= GET_MODE_SIZE (DImode);
3301 op1_subbyte *= GET_MODE_SIZE (DImode);
3302 operand1 = XEXP (operand1, 0);
3305 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3307 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3311 (define_insn "*sign_extendhidi2_insn"
3312 [(set (match_operand:DI 0 "register_operand" "=r")
3313 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3316 [(set_attr "type" "sload")
3317 (set_attr "us3load_type" "3cycle")])
3319 (define_expand "extendsidi2"
3320 [(set (match_operand:DI 0 "register_operand" "")
3321 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3325 (define_insn "*sign_extendsidi2_insn"
3326 [(set (match_operand:DI 0 "register_operand" "=r,r")
3327 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3332 [(set_attr "type" "shift,sload")
3333 (set_attr "us3load_type" "*,3cycle")])
3336 ;; Special pattern for optimizing bit-field compares. This is needed
3337 ;; because combine uses this as a canonical form.
3339 (define_insn "*cmp_zero_extract"
3340 [(set (reg:CC CC_REG)
3342 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3343 (match_operand:SI 1 "small_int_operand" "I")
3344 (match_operand:SI 2 "small_int_operand" "I"))
3346 "INTVAL (operands[2]) > 19"
3348 int len = INTVAL (operands[1]);
3349 int pos = 32 - INTVAL (operands[2]) - len;
3350 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3351 operands[1] = GEN_INT (mask);
3352 return "andcc\t%0, %1, %%g0";
3354 [(set_attr "type" "compare")])
3356 (define_insn "*cmp_zero_extract_sp64"
3357 [(set (reg:CCX CC_REG)
3359 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3360 (match_operand:SI 1 "small_int_operand" "I")
3361 (match_operand:SI 2 "small_int_operand" "I"))
3363 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3365 int len = INTVAL (operands[1]);
3366 int pos = 64 - INTVAL (operands[2]) - len;
3367 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3368 operands[1] = GEN_INT (mask);
3369 return "andcc\t%0, %1, %%g0";
3371 [(set_attr "type" "compare")])
3374 ;; Conversions between float, double and long double.
3376 (define_insn "extendsfdf2"
3377 [(set (match_operand:DF 0 "register_operand" "=e")
3379 (match_operand:SF 1 "register_operand" "f")))]
3382 [(set_attr "type" "fp")
3383 (set_attr "fptype" "double")])
3385 (define_expand "extendsftf2"
3386 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3388 (match_operand:SF 1 "register_operand" "")))]
3389 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3390 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3392 (define_insn "*extendsftf2_hq"
3393 [(set (match_operand:TF 0 "register_operand" "=e")
3395 (match_operand:SF 1 "register_operand" "f")))]
3396 "TARGET_FPU && TARGET_HARD_QUAD"
3398 [(set_attr "type" "fp")])
3400 (define_expand "extenddftf2"
3401 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3403 (match_operand:DF 1 "register_operand" "")))]
3404 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3405 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3407 (define_insn "*extenddftf2_hq"
3408 [(set (match_operand:TF 0 "register_operand" "=e")
3410 (match_operand:DF 1 "register_operand" "e")))]
3411 "TARGET_FPU && TARGET_HARD_QUAD"
3413 [(set_attr "type" "fp")])
3415 (define_insn "truncdfsf2"
3416 [(set (match_operand:SF 0 "register_operand" "=f")
3418 (match_operand:DF 1 "register_operand" "e")))]
3421 [(set_attr "type" "fp")
3422 (set_attr "fptype" "double")])
3424 (define_expand "trunctfsf2"
3425 [(set (match_operand:SF 0 "register_operand" "")
3427 (match_operand:TF 1 "general_operand" "")))]
3428 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3429 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3431 (define_insn "*trunctfsf2_hq"
3432 [(set (match_operand:SF 0 "register_operand" "=f")
3434 (match_operand:TF 1 "register_operand" "e")))]
3435 "TARGET_FPU && TARGET_HARD_QUAD"
3437 [(set_attr "type" "fp")])
3439 (define_expand "trunctfdf2"
3440 [(set (match_operand:DF 0 "register_operand" "")
3442 (match_operand:TF 1 "general_operand" "")))]
3443 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3444 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3446 (define_insn "*trunctfdf2_hq"
3447 [(set (match_operand:DF 0 "register_operand" "=e")
3449 (match_operand:TF 1 "register_operand" "e")))]
3450 "TARGET_FPU && TARGET_HARD_QUAD"
3452 [(set_attr "type" "fp")])
3455 ;; Conversion between fixed point and floating point.
3457 (define_insn "floatsisf2"
3458 [(set (match_operand:SF 0 "register_operand" "=f")
3459 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3462 [(set_attr "type" "fp")
3463 (set_attr "fptype" "double")])
3465 (define_insn "floatsidf2"
3466 [(set (match_operand:DF 0 "register_operand" "=e")
3467 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3470 [(set_attr "type" "fp")
3471 (set_attr "fptype" "double")])
3473 (define_expand "floatsitf2"
3474 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3475 (float:TF (match_operand:SI 1 "register_operand" "")))]
3476 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3477 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3479 (define_insn "*floatsitf2_hq"
3480 [(set (match_operand:TF 0 "register_operand" "=e")
3481 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3482 "TARGET_FPU && TARGET_HARD_QUAD"
3484 [(set_attr "type" "fp")])
3486 (define_expand "floatunssitf2"
3487 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3488 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3489 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3490 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3492 ;; Now the same for 64 bit sources.
3494 (define_insn "floatdisf2"
3495 [(set (match_operand:SF 0 "register_operand" "=f")
3496 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3497 "TARGET_V9 && TARGET_FPU"
3499 [(set_attr "type" "fp")
3500 (set_attr "fptype" "double")])
3502 (define_expand "floatunsdisf2"
3503 [(use (match_operand:SF 0 "register_operand" ""))
3504 (use (match_operand:DI 1 "general_operand" ""))]
3505 "TARGET_ARCH64 && TARGET_FPU"
3506 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3508 (define_insn "floatdidf2"
3509 [(set (match_operand:DF 0 "register_operand" "=e")
3510 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3511 "TARGET_V9 && TARGET_FPU"
3513 [(set_attr "type" "fp")
3514 (set_attr "fptype" "double")])
3516 (define_expand "floatunsdidf2"
3517 [(use (match_operand:DF 0 "register_operand" ""))
3518 (use (match_operand:DI 1 "general_operand" ""))]
3519 "TARGET_ARCH64 && TARGET_FPU"
3520 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3522 (define_expand "floatditf2"
3523 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3524 (float:TF (match_operand:DI 1 "register_operand" "")))]
3525 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3526 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3528 (define_insn "*floatditf2_hq"
3529 [(set (match_operand:TF 0 "register_operand" "=e")
3530 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3531 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3533 [(set_attr "type" "fp")])
3535 (define_expand "floatunsditf2"
3536 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3537 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3538 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3539 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3541 ;; Convert a float to an actual integer.
3542 ;; Truncation is performed as part of the conversion.
3544 (define_insn "fix_truncsfsi2"
3545 [(set (match_operand:SI 0 "register_operand" "=f")
3546 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3549 [(set_attr "type" "fp")
3550 (set_attr "fptype" "double")])
3552 (define_insn "fix_truncdfsi2"
3553 [(set (match_operand:SI 0 "register_operand" "=f")
3554 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3557 [(set_attr "type" "fp")
3558 (set_attr "fptype" "double")])
3560 (define_expand "fix_trunctfsi2"
3561 [(set (match_operand:SI 0 "register_operand" "")
3562 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3563 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3564 "emit_tfmode_cvt (FIX, operands); DONE;")
3566 (define_insn "*fix_trunctfsi2_hq"
3567 [(set (match_operand:SI 0 "register_operand" "=f")
3568 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3569 "TARGET_FPU && TARGET_HARD_QUAD"
3571 [(set_attr "type" "fp")])
3573 (define_expand "fixuns_trunctfsi2"
3574 [(set (match_operand:SI 0 "register_operand" "")
3575 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3576 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3577 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3579 ;; Now the same, for V9 targets
3581 (define_insn "fix_truncsfdi2"
3582 [(set (match_operand:DI 0 "register_operand" "=e")
3583 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3584 "TARGET_V9 && TARGET_FPU"
3586 [(set_attr "type" "fp")
3587 (set_attr "fptype" "double")])
3589 (define_expand "fixuns_truncsfdi2"
3590 [(use (match_operand:DI 0 "register_operand" ""))
3591 (use (match_operand:SF 1 "general_operand" ""))]
3592 "TARGET_ARCH64 && TARGET_FPU"
3593 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3595 (define_insn "fix_truncdfdi2"
3596 [(set (match_operand:DI 0 "register_operand" "=e")
3597 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3598 "TARGET_V9 && TARGET_FPU"
3600 [(set_attr "type" "fp")
3601 (set_attr "fptype" "double")])
3603 (define_expand "fixuns_truncdfdi2"
3604 [(use (match_operand:DI 0 "register_operand" ""))
3605 (use (match_operand:DF 1 "general_operand" ""))]
3606 "TARGET_ARCH64 && TARGET_FPU"
3607 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3609 (define_expand "fix_trunctfdi2"
3610 [(set (match_operand:DI 0 "register_operand" "")
3611 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3612 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3613 "emit_tfmode_cvt (FIX, operands); DONE;")
3615 (define_insn "*fix_trunctfdi2_hq"
3616 [(set (match_operand:DI 0 "register_operand" "=e")
3617 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3618 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3620 [(set_attr "type" "fp")])
3622 (define_expand "fixuns_trunctfdi2"
3623 [(set (match_operand:DI 0 "register_operand" "")
3624 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3625 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3626 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3629 ;; Integer addition/subtraction instructions.
3631 (define_expand "adddi3"
3632 [(set (match_operand:DI 0 "register_operand" "")
3633 (plus:DI (match_operand:DI 1 "register_operand" "")
3634 (match_operand:DI 2 "arith_double_add_operand" "")))]
3637 if (! TARGET_ARCH64)
3639 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3640 gen_rtx_SET (VOIDmode, operands[0],
3641 gen_rtx_PLUS (DImode, operands[1],
3643 gen_rtx_CLOBBER (VOIDmode,
3644 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3649 (define_insn_and_split "*adddi3_insn_sp32"
3650 [(set (match_operand:DI 0 "register_operand" "=r")
3651 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3652 (match_operand:DI 2 "arith_double_operand" "rHI")))
3653 (clobber (reg:CC CC_REG))]
3656 "&& reload_completed"
3657 [(parallel [(set (reg:CC_NOOV CC_REG)
3658 (compare:CC_NOOV (plus:SI (match_dup 4)
3662 (plus:SI (match_dup 4) (match_dup 5)))])
3664 (plus:SI (plus:SI (match_dup 7)
3666 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3668 operands[3] = gen_lowpart (SImode, operands[0]);
3669 operands[4] = gen_lowpart (SImode, operands[1]);
3670 operands[5] = gen_lowpart (SImode, operands[2]);
3671 operands[6] = gen_highpart (SImode, operands[0]);
3672 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3673 #if HOST_BITS_PER_WIDE_INT == 32
3674 if (GET_CODE (operands[2]) == CONST_INT)
3676 if (INTVAL (operands[2]) < 0)
3677 operands[8] = constm1_rtx;
3679 operands[8] = const0_rtx;
3683 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3685 [(set_attr "length" "2")])
3687 ;; LTU here means "carry set"
3689 [(set (match_operand:SI 0 "register_operand" "=r")
3690 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3691 (match_operand:SI 2 "arith_operand" "rI"))
3692 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3695 [(set_attr "type" "ialuX")])
3697 (define_insn_and_split "*addx_extend_sp32"
3698 [(set (match_operand:DI 0 "register_operand" "=r")
3699 (zero_extend:DI (plus:SI (plus:SI
3700 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3701 (match_operand:SI 2 "arith_operand" "rI"))
3702 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3705 "&& reload_completed"
3706 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3707 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3708 (set (match_dup 4) (const_int 0))]
3709 "operands[3] = gen_lowpart (SImode, operands[0]);
3710 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3711 [(set_attr "length" "2")])
3713 (define_insn "*addx_extend_sp64"
3714 [(set (match_operand:DI 0 "register_operand" "=r")
3715 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3716 (match_operand:SI 2 "arith_operand" "rI"))
3717 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3720 [(set_attr "type" "ialuX")])
3722 (define_insn_and_split "*adddi3_extend_sp32"
3723 [(set (match_operand:DI 0 "register_operand" "=r")
3724 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3725 (match_operand:DI 2 "register_operand" "r")))
3726 (clobber (reg:CC CC_REG))]
3729 "&& reload_completed"
3730 [(parallel [(set (reg:CC_NOOV CC_REG)
3731 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3733 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3735 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3736 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3737 "operands[3] = gen_lowpart (SImode, operands[2]);
3738 operands[4] = gen_highpart (SImode, operands[2]);
3739 operands[5] = gen_lowpart (SImode, operands[0]);
3740 operands[6] = gen_highpart (SImode, operands[0]);"
3741 [(set_attr "length" "2")])
3743 (define_insn "*adddi3_sp64"
3744 [(set (match_operand:DI 0 "register_operand" "=r,r")
3745 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3746 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3752 (define_insn "addsi3"
3753 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3754 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3755 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3760 fpadd32s\t%1, %2, %0"
3761 [(set_attr "type" "*,*,fga")
3762 (set_attr "fptype" "*,*,single")])
3764 (define_insn "*cmp_cc_plus"
3765 [(set (reg:CC_NOOV CC_REG)
3766 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3767 (match_operand:SI 1 "arith_operand" "rI"))
3770 "addcc\t%0, %1, %%g0"
3771 [(set_attr "type" "compare")])
3773 (define_insn "*cmp_ccx_plus"
3774 [(set (reg:CCX_NOOV CC_REG)
3775 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3776 (match_operand:DI 1 "arith_operand" "rI"))
3779 "addcc\t%0, %1, %%g0"
3780 [(set_attr "type" "compare")])
3782 (define_insn "*cmp_cc_plus_set"
3783 [(set (reg:CC_NOOV CC_REG)
3784 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3785 (match_operand:SI 2 "arith_operand" "rI"))
3787 (set (match_operand:SI 0 "register_operand" "=r")
3788 (plus:SI (match_dup 1) (match_dup 2)))]
3791 [(set_attr "type" "compare")])
3793 (define_insn "*cmp_ccx_plus_set"
3794 [(set (reg:CCX_NOOV CC_REG)
3795 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3796 (match_operand:DI 2 "arith_operand" "rI"))
3798 (set (match_operand:DI 0 "register_operand" "=r")
3799 (plus:DI (match_dup 1) (match_dup 2)))]
3802 [(set_attr "type" "compare")])
3804 (define_expand "subdi3"
3805 [(set (match_operand:DI 0 "register_operand" "")
3806 (minus:DI (match_operand:DI 1 "register_operand" "")
3807 (match_operand:DI 2 "arith_double_add_operand" "")))]
3810 if (! TARGET_ARCH64)
3812 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3813 gen_rtx_SET (VOIDmode, operands[0],
3814 gen_rtx_MINUS (DImode, operands[1],
3816 gen_rtx_CLOBBER (VOIDmode,
3817 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3822 (define_insn_and_split "*subdi3_insn_sp32"
3823 [(set (match_operand:DI 0 "register_operand" "=r")
3824 (minus:DI (match_operand:DI 1 "register_operand" "r")
3825 (match_operand:DI 2 "arith_double_operand" "rHI")))
3826 (clobber (reg:CC CC_REG))]
3829 "&& reload_completed"
3830 [(parallel [(set (reg:CC_NOOV CC_REG)
3831 (compare:CC_NOOV (minus:SI (match_dup 4)
3835 (minus:SI (match_dup 4) (match_dup 5)))])
3837 (minus:SI (minus:SI (match_dup 7)
3839 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3841 operands[3] = gen_lowpart (SImode, operands[0]);
3842 operands[4] = gen_lowpart (SImode, operands[1]);
3843 operands[5] = gen_lowpart (SImode, operands[2]);
3844 operands[6] = gen_highpart (SImode, operands[0]);
3845 operands[7] = gen_highpart (SImode, operands[1]);
3846 #if HOST_BITS_PER_WIDE_INT == 32
3847 if (GET_CODE (operands[2]) == CONST_INT)
3849 if (INTVAL (operands[2]) < 0)
3850 operands[8] = constm1_rtx;
3852 operands[8] = const0_rtx;
3856 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3858 [(set_attr "length" "2")])
3860 ;; LTU here means "carry set"
3862 [(set (match_operand:SI 0 "register_operand" "=r")
3863 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3864 (match_operand:SI 2 "arith_operand" "rI"))
3865 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3868 [(set_attr "type" "ialuX")])
3870 (define_insn "*subx_extend_sp64"
3871 [(set (match_operand:DI 0 "register_operand" "=r")
3872 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3873 (match_operand:SI 2 "arith_operand" "rI"))
3874 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3877 [(set_attr "type" "ialuX")])
3879 (define_insn_and_split "*subx_extend"
3880 [(set (match_operand:DI 0 "register_operand" "=r")
3881 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3882 (match_operand:SI 2 "arith_operand" "rI"))
3883 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3886 "&& reload_completed"
3887 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3888 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3889 (set (match_dup 4) (const_int 0))]
3890 "operands[3] = gen_lowpart (SImode, operands[0]);
3891 operands[4] = gen_highpart (SImode, operands[0]);"
3892 [(set_attr "length" "2")])
3894 (define_insn_and_split "*subdi3_extend_sp32"
3895 [(set (match_operand:DI 0 "register_operand" "=r")
3896 (minus:DI (match_operand:DI 1 "register_operand" "r")
3897 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3898 (clobber (reg:CC CC_REG))]
3901 "&& reload_completed"
3902 [(parallel [(set (reg:CC_NOOV CC_REG)
3903 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3905 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3907 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3908 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3909 "operands[3] = gen_lowpart (SImode, operands[1]);
3910 operands[4] = gen_highpart (SImode, operands[1]);
3911 operands[5] = gen_lowpart (SImode, operands[0]);
3912 operands[6] = gen_highpart (SImode, operands[0]);"
3913 [(set_attr "length" "2")])
3915 (define_insn "*subdi3_sp64"
3916 [(set (match_operand:DI 0 "register_operand" "=r,r")
3917 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3918 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3924 (define_insn "subsi3"
3925 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3926 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3927 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3932 fpsub32s\t%1, %2, %0"
3933 [(set_attr "type" "*,*,fga")
3934 (set_attr "fptype" "*,*,single")])
3936 (define_insn "*cmp_minus_cc"
3937 [(set (reg:CC_NOOV CC_REG)
3938 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3939 (match_operand:SI 1 "arith_operand" "rI"))
3942 "subcc\t%r0, %1, %%g0"
3943 [(set_attr "type" "compare")])
3945 (define_insn "*cmp_minus_ccx"
3946 [(set (reg:CCX_NOOV CC_REG)
3947 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3948 (match_operand:DI 1 "arith_operand" "rI"))
3951 "subcc\t%0, %1, %%g0"
3952 [(set_attr "type" "compare")])
3954 (define_insn "cmp_minus_cc_set"
3955 [(set (reg:CC_NOOV CC_REG)
3956 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3957 (match_operand:SI 2 "arith_operand" "rI"))
3959 (set (match_operand:SI 0 "register_operand" "=r")
3960 (minus:SI (match_dup 1) (match_dup 2)))]
3962 "subcc\t%r1, %2, %0"
3963 [(set_attr "type" "compare")])
3965 (define_insn "*cmp_minus_ccx_set"
3966 [(set (reg:CCX_NOOV CC_REG)
3967 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3968 (match_operand:DI 2 "arith_operand" "rI"))
3970 (set (match_operand:DI 0 "register_operand" "=r")
3971 (minus:DI (match_dup 1) (match_dup 2)))]
3974 [(set_attr "type" "compare")])
3977 ;; Integer multiply/divide instructions.
3979 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3980 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3982 (define_insn "mulsi3"
3983 [(set (match_operand:SI 0 "register_operand" "=r")
3984 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3985 (match_operand:SI 2 "arith_operand" "rI")))]
3988 [(set_attr "type" "imul")])
3990 (define_expand "muldi3"
3991 [(set (match_operand:DI 0 "register_operand" "")
3992 (mult:DI (match_operand:DI 1 "arith_operand" "")
3993 (match_operand:DI 2 "arith_operand" "")))]
3994 "TARGET_ARCH64 || TARGET_V8PLUS"
3998 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4003 (define_insn "*muldi3_sp64"
4004 [(set (match_operand:DI 0 "register_operand" "=r")
4005 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4006 (match_operand:DI 2 "arith_operand" "rI")))]
4009 [(set_attr "type" "imul")])
4011 ;; V8plus wide multiply.
4013 (define_insn "muldi3_v8plus"
4014 [(set (match_operand:DI 0 "register_operand" "=r,h")
4015 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4016 (match_operand:DI 2 "arith_operand" "rI,rI")))
4017 (clobber (match_scratch:SI 3 "=&h,X"))
4018 (clobber (match_scratch:SI 4 "=&h,X"))]
4020 "* return output_v8plus_mult (insn, operands, \"mulx\");"
4021 [(set_attr "type" "multi")
4022 (set_attr "length" "9,8")])
4024 (define_insn "*cmp_mul_set"
4025 [(set (reg:CC CC_REG)
4026 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4027 (match_operand:SI 2 "arith_operand" "rI"))
4029 (set (match_operand:SI 0 "register_operand" "=r")
4030 (mult:SI (match_dup 1) (match_dup 2)))]
4031 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4032 "smulcc\t%1, %2, %0"
4033 [(set_attr "type" "imul")])
4035 (define_expand "mulsidi3"
4036 [(set (match_operand:DI 0 "register_operand" "")
4037 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4038 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4041 if (CONSTANT_P (operands[2]))
4044 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4046 else if (TARGET_ARCH32)
4047 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4050 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4056 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4061 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4062 ;; registers can hold 64-bit values in the V8plus environment.
4064 (define_insn "mulsidi3_v8plus"
4065 [(set (match_operand:DI 0 "register_operand" "=h,r")
4066 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4067 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4068 (clobber (match_scratch:SI 3 "=X,&h"))]
4071 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4072 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4073 [(set_attr "type" "multi")
4074 (set_attr "length" "2,3")])
4077 (define_insn "const_mulsidi3_v8plus"
4078 [(set (match_operand:DI 0 "register_operand" "=h,r")
4079 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4080 (match_operand:DI 2 "small_int_operand" "I,I")))
4081 (clobber (match_scratch:SI 3 "=X,&h"))]
4084 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4085 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4086 [(set_attr "type" "multi")
4087 (set_attr "length" "2,3")])
4090 (define_insn "*mulsidi3_sp32"
4091 [(set (match_operand:DI 0 "register_operand" "=r")
4092 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4093 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4096 return TARGET_SPARCLET
4097 ? "smuld\t%1, %2, %L0"
4098 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4101 (if_then_else (eq_attr "isa" "sparclet")
4102 (const_string "imul") (const_string "multi")))
4103 (set (attr "length")
4104 (if_then_else (eq_attr "isa" "sparclet")
4105 (const_int 1) (const_int 2)))])
4107 (define_insn "*mulsidi3_sp64"
4108 [(set (match_operand:DI 0 "register_operand" "=r")
4109 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4110 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4111 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4113 [(set_attr "type" "imul")])
4115 ;; Extra pattern, because sign_extend of a constant isn't valid.
4118 (define_insn "const_mulsidi3_sp32"
4119 [(set (match_operand:DI 0 "register_operand" "=r")
4120 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4121 (match_operand:DI 2 "small_int_operand" "I")))]
4124 return TARGET_SPARCLET
4125 ? "smuld\t%1, %2, %L0"
4126 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4129 (if_then_else (eq_attr "isa" "sparclet")
4130 (const_string "imul") (const_string "multi")))
4131 (set (attr "length")
4132 (if_then_else (eq_attr "isa" "sparclet")
4133 (const_int 1) (const_int 2)))])
4135 (define_insn "const_mulsidi3_sp64"
4136 [(set (match_operand:DI 0 "register_operand" "=r")
4137 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4138 (match_operand:DI 2 "small_int_operand" "I")))]
4139 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4141 [(set_attr "type" "imul")])
4143 (define_expand "smulsi3_highpart"
4144 [(set (match_operand:SI 0 "register_operand" "")
4146 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4147 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4149 "TARGET_HARD_MUL && TARGET_ARCH32"
4151 if (CONSTANT_P (operands[2]))
4155 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4161 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4166 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4167 operands[2], GEN_INT (32)));
4173 (define_insn "smulsi3_highpart_v8plus"
4174 [(set (match_operand:SI 0 "register_operand" "=h,r")
4176 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4177 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4178 (match_operand:SI 3 "small_int_operand" "I,I"))))
4179 (clobber (match_scratch:SI 4 "=X,&h"))]
4182 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4183 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4184 [(set_attr "type" "multi")
4185 (set_attr "length" "2")])
4187 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4190 [(set (match_operand:SI 0 "register_operand" "=h,r")
4193 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4194 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4195 (match_operand:SI 3 "small_int_operand" "I,I"))
4197 (clobber (match_scratch:SI 4 "=X,&h"))]
4200 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4201 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4202 [(set_attr "type" "multi")
4203 (set_attr "length" "2")])
4206 (define_insn "const_smulsi3_highpart_v8plus"
4207 [(set (match_operand:SI 0 "register_operand" "=h,r")
4209 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4210 (match_operand:DI 2 "small_int_operand" "I,I"))
4211 (match_operand:SI 3 "small_int_operand" "I,I"))))
4212 (clobber (match_scratch:SI 4 "=X,&h"))]
4215 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4216 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4217 [(set_attr "type" "multi")
4218 (set_attr "length" "2")])
4221 (define_insn "*smulsi3_highpart_sp32"
4222 [(set (match_operand:SI 0 "register_operand" "=r")
4224 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4225 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4228 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4229 [(set_attr "type" "multi")
4230 (set_attr "length" "2")])
4233 (define_insn "const_smulsi3_highpart"
4234 [(set (match_operand:SI 0 "register_operand" "=r")
4236 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4237 (match_operand:DI 2 "small_int_operand" "i"))
4240 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4241 [(set_attr "type" "multi")
4242 (set_attr "length" "2")])
4244 (define_expand "umulsidi3"
4245 [(set (match_operand:DI 0 "register_operand" "")
4246 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4247 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4250 if (CONSTANT_P (operands[2]))
4253 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4255 else if (TARGET_ARCH32)
4256 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4259 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4265 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4271 (define_insn "umulsidi3_v8plus"
4272 [(set (match_operand:DI 0 "register_operand" "=h,r")
4273 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4274 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4275 (clobber (match_scratch:SI 3 "=X,&h"))]
4278 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4279 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4280 [(set_attr "type" "multi")
4281 (set_attr "length" "2,3")])
4284 (define_insn "*umulsidi3_sp32"
4285 [(set (match_operand:DI 0 "register_operand" "=r")
4286 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4287 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4290 return TARGET_SPARCLET
4291 ? "umuld\t%1, %2, %L0"
4292 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4295 (if_then_else (eq_attr "isa" "sparclet")
4296 (const_string "imul") (const_string "multi")))
4297 (set (attr "length")
4298 (if_then_else (eq_attr "isa" "sparclet")
4299 (const_int 1) (const_int 2)))])
4301 (define_insn "*umulsidi3_sp64"
4302 [(set (match_operand:DI 0 "register_operand" "=r")
4303 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4304 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4305 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4307 [(set_attr "type" "imul")])
4309 ;; Extra pattern, because sign_extend of a constant isn't valid.
4312 (define_insn "const_umulsidi3_sp32"
4313 [(set (match_operand:DI 0 "register_operand" "=r")
4314 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4315 (match_operand:DI 2 "uns_small_int_operand" "")))]
4318 return TARGET_SPARCLET
4319 ? "umuld\t%1, %s2, %L0"
4320 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4323 (if_then_else (eq_attr "isa" "sparclet")
4324 (const_string "imul") (const_string "multi")))
4325 (set (attr "length")
4326 (if_then_else (eq_attr "isa" "sparclet")
4327 (const_int 1) (const_int 2)))])
4329 (define_insn "const_umulsidi3_sp64"
4330 [(set (match_operand:DI 0 "register_operand" "=r")
4331 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4332 (match_operand:DI 2 "uns_small_int_operand" "")))]
4333 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4335 [(set_attr "type" "imul")])
4338 (define_insn "const_umulsidi3_v8plus"
4339 [(set (match_operand:DI 0 "register_operand" "=h,r")
4340 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4341 (match_operand:DI 2 "uns_small_int_operand" "")))
4342 (clobber (match_scratch:SI 3 "=X,h"))]
4345 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4346 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4347 [(set_attr "type" "multi")
4348 (set_attr "length" "2,3")])
4350 (define_expand "umulsi3_highpart"
4351 [(set (match_operand:SI 0 "register_operand" "")
4353 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4354 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4356 "TARGET_HARD_MUL && TARGET_ARCH32"
4358 if (CONSTANT_P (operands[2]))
4362 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4368 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4373 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4374 operands[2], GEN_INT (32)));
4380 (define_insn "umulsi3_highpart_v8plus"
4381 [(set (match_operand:SI 0 "register_operand" "=h,r")
4383 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4384 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4385 (match_operand:SI 3 "small_int_operand" "I,I"))))
4386 (clobber (match_scratch:SI 4 "=X,h"))]
4389 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4390 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4391 [(set_attr "type" "multi")
4392 (set_attr "length" "2")])
4395 (define_insn "const_umulsi3_highpart_v8plus"
4396 [(set (match_operand:SI 0 "register_operand" "=h,r")
4398 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4399 (match_operand:DI 2 "uns_small_int_operand" ""))
4400 (match_operand:SI 3 "small_int_operand" "I,I"))))
4401 (clobber (match_scratch:SI 4 "=X,h"))]
4404 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4405 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4406 [(set_attr "type" "multi")
4407 (set_attr "length" "2")])
4410 (define_insn "*umulsi3_highpart_sp32"
4411 [(set (match_operand:SI 0 "register_operand" "=r")
4413 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4414 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4417 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4418 [(set_attr "type" "multi")
4419 (set_attr "length" "2")])
4422 (define_insn "const_umulsi3_highpart"
4423 [(set (match_operand:SI 0 "register_operand" "=r")
4425 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4426 (match_operand:DI 2 "uns_small_int_operand" ""))
4429 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4430 [(set_attr "type" "multi")
4431 (set_attr "length" "2")])
4433 (define_expand "divsi3"
4434 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4435 (div:SI (match_operand:SI 1 "register_operand" "")
4436 (match_operand:SI 2 "input_operand" "")))
4437 (clobber (match_scratch:SI 3 ""))])]
4438 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4442 operands[3] = gen_reg_rtx(SImode);
4443 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4444 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4450 ;; The V8 architecture specifies that there must be at least 3 instructions
4451 ;; between a write to the Y register and a use of it for correct results.
4452 ;; We try to fill one of them with a simple constant or a memory load.
4454 (define_insn "divsi3_sp32"
4455 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4456 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4457 (match_operand:SI 2 "input_operand" "rI,K,m")))
4458 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4459 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4461 output_asm_insn ("sra\t%1, 31, %3", operands);
4462 output_asm_insn ("wr\t%3, 0, %%y", operands);
4464 switch (which_alternative)
4468 return "sdiv\t%1, %2, %0";
4470 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4473 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4475 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4478 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4480 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4485 [(set_attr "type" "multi")
4486 (set (attr "length")
4487 (if_then_else (eq_attr "isa" "v9")
4488 (const_int 4) (const_int 6)))])
4490 (define_insn "divsi3_sp64"
4491 [(set (match_operand:SI 0 "register_operand" "=r")
4492 (div:SI (match_operand:SI 1 "register_operand" "r")
4493 (match_operand:SI 2 "input_operand" "rI")))
4494 (use (match_operand:SI 3 "register_operand" "r"))]
4495 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4496 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4497 [(set_attr "type" "multi")
4498 (set_attr "length" "2")])
4500 (define_insn "divdi3"
4501 [(set (match_operand:DI 0 "register_operand" "=r")
4502 (div:DI (match_operand:DI 1 "register_operand" "r")
4503 (match_operand:DI 2 "arith_operand" "rI")))]
4506 [(set_attr "type" "idiv")])
4508 (define_insn "*cmp_sdiv_cc_set"
4509 [(set (reg:CC CC_REG)
4510 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4511 (match_operand:SI 2 "arith_operand" "rI"))
4513 (set (match_operand:SI 0 "register_operand" "=r")
4514 (div:SI (match_dup 1) (match_dup 2)))
4515 (clobber (match_scratch:SI 3 "=&r"))]
4516 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4518 output_asm_insn ("sra\t%1, 31, %3", operands);
4519 output_asm_insn ("wr\t%3, 0, %%y", operands);
4522 return "sdivcc\t%1, %2, %0";
4524 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4526 [(set_attr "type" "multi")
4527 (set (attr "length")
4528 (if_then_else (eq_attr "isa" "v9")
4529 (const_int 3) (const_int 6)))])
4532 (define_expand "udivsi3"
4533 [(set (match_operand:SI 0 "register_operand" "")
4534 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4535 (match_operand:SI 2 "input_operand" "")))]
4536 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4539 ;; The V8 architecture specifies that there must be at least 3 instructions
4540 ;; between a write to the Y register and a use of it for correct results.
4541 ;; We try to fill one of them with a simple constant or a memory load.
4543 (define_insn "udivsi3_sp32"
4544 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4545 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4546 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4547 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4549 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4551 switch (which_alternative)
4555 return "udiv\t%1, %2, %0";
4557 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4560 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4562 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4565 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4567 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4570 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4572 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4577 [(set_attr "type" "multi")
4578 (set (attr "length")
4579 (if_then_else (eq_attr "isa" "v9")
4580 (const_int 3) (const_int 5)))])
4582 (define_insn "udivsi3_sp64"
4583 [(set (match_operand:SI 0 "register_operand" "=r")
4584 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4585 (match_operand:SI 2 "input_operand" "rI")))]
4586 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4587 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4588 [(set_attr "type" "multi")
4589 (set_attr "length" "2")])
4591 (define_insn "udivdi3"
4592 [(set (match_operand:DI 0 "register_operand" "=r")
4593 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4594 (match_operand:DI 2 "arith_operand" "rI")))]
4597 [(set_attr "type" "idiv")])
4599 (define_insn "*cmp_udiv_cc_set"
4600 [(set (reg:CC CC_REG)
4601 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4602 (match_operand:SI 2 "arith_operand" "rI"))
4604 (set (match_operand:SI 0 "register_operand" "=r")
4605 (udiv:SI (match_dup 1) (match_dup 2)))]
4606 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4608 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4611 return "udivcc\t%1, %2, %0";
4613 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4615 [(set_attr "type" "multi")
4616 (set (attr "length")
4617 (if_then_else (eq_attr "isa" "v9")
4618 (const_int 2) (const_int 5)))])
4620 ; sparclet multiply/accumulate insns
4622 (define_insn "*smacsi"
4623 [(set (match_operand:SI 0 "register_operand" "=r")
4624 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4625 (match_operand:SI 2 "arith_operand" "rI"))
4626 (match_operand:SI 3 "register_operand" "0")))]
4629 [(set_attr "type" "imul")])
4631 (define_insn "*smacdi"
4632 [(set (match_operand:DI 0 "register_operand" "=r")
4633 (plus:DI (mult:DI (sign_extend:DI
4634 (match_operand:SI 1 "register_operand" "%r"))
4636 (match_operand:SI 2 "register_operand" "r")))
4637 (match_operand:DI 3 "register_operand" "0")))]
4639 "smacd\t%1, %2, %L0"
4640 [(set_attr "type" "imul")])
4642 (define_insn "*umacdi"
4643 [(set (match_operand:DI 0 "register_operand" "=r")
4644 (plus:DI (mult:DI (zero_extend:DI
4645 (match_operand:SI 1 "register_operand" "%r"))
4647 (match_operand:SI 2 "register_operand" "r")))
4648 (match_operand:DI 3 "register_operand" "0")))]
4650 "umacd\t%1, %2, %L0"
4651 [(set_attr "type" "imul")])
4654 ;; Boolean instructions.
4656 ;; We define DImode `and' so with DImode `not' we can get
4657 ;; DImode `andn'. Other combinations are possible.
4659 (define_expand "and<V64I:mode>3"
4660 [(set (match_operand:V64I 0 "register_operand" "")
4661 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4662 (match_operand:V64I 2 "arith_double_operand" "")))]
4666 (define_insn "*and<V64I:mode>3_sp32"
4667 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4668 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4669 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4674 [(set_attr "type" "*,fga")
4675 (set_attr "length" "2,*")
4676 (set_attr "fptype" "*,double")])
4678 (define_insn "*and<V64I:mode>3_sp64"
4679 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4680 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4681 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4686 [(set_attr "type" "*,fga")
4687 (set_attr "fptype" "*,double")])
4689 (define_insn "and<V32I:mode>3"
4690 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4691 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4692 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4697 [(set_attr "type" "*,fga")
4698 (set_attr "fptype" "*,single")])
4701 [(set (match_operand:SI 0 "register_operand" "")
4702 (and:SI (match_operand:SI 1 "register_operand" "")
4703 (match_operand:SI 2 "const_compl_high_operand" "")))
4704 (clobber (match_operand:SI 3 "register_operand" ""))]
4706 [(set (match_dup 3) (match_dup 4))
4707 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4709 operands[4] = GEN_INT (~INTVAL (operands[2]));
4712 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4713 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4714 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4715 (match_operand:V64I 2 "register_operand" "r,b")))]
4719 fandnot1\t%1, %2, %0"
4720 "&& reload_completed
4721 && ((GET_CODE (operands[0]) == REG
4722 && REGNO (operands[0]) < 32)
4723 || (GET_CODE (operands[0]) == SUBREG
4724 && GET_CODE (SUBREG_REG (operands[0])) == REG
4725 && REGNO (SUBREG_REG (operands[0])) < 32))"
4726 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4727 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4728 "operands[3] = gen_highpart (SImode, operands[0]);
4729 operands[4] = gen_highpart (SImode, operands[1]);
4730 operands[5] = gen_highpart (SImode, operands[2]);
4731 operands[6] = gen_lowpart (SImode, operands[0]);
4732 operands[7] = gen_lowpart (SImode, operands[1]);
4733 operands[8] = gen_lowpart (SImode, operands[2]);"
4734 [(set_attr "type" "*,fga")
4735 (set_attr "length" "2,*")
4736 (set_attr "fptype" "*,double")])
4738 (define_insn "*and_not_<V64I:mode>_sp64"
4739 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4740 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4741 (match_operand:V64I 2 "register_operand" "r,b")))]
4745 fandnot1\t%1, %2, %0"
4746 [(set_attr "type" "*,fga")
4747 (set_attr "fptype" "*,double")])
4749 (define_insn "*and_not_<V32I:mode>"
4750 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4751 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4752 (match_operand:V32I 2 "register_operand" "r,d")))]
4756 fandnot1s\t%1, %2, %0"
4757 [(set_attr "type" "*,fga")
4758 (set_attr "fptype" "*,single")])
4760 (define_expand "ior<V64I:mode>3"
4761 [(set (match_operand:V64I 0 "register_operand" "")
4762 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4763 (match_operand:V64I 2 "arith_double_operand" "")))]
4767 (define_insn "*ior<V64I:mode>3_sp32"
4768 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4769 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4770 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4775 [(set_attr "type" "*,fga")
4776 (set_attr "length" "2,*")
4777 (set_attr "fptype" "*,double")])
4779 (define_insn "*ior<V64I:mode>3_sp64"
4780 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4781 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4782 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4787 [(set_attr "type" "*,fga")
4788 (set_attr "fptype" "*,double")])
4790 (define_insn "ior<V32I:mode>3"
4791 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4792 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4793 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4798 [(set_attr "type" "*,fga")
4799 (set_attr "fptype" "*,single")])
4802 [(set (match_operand:SI 0 "register_operand" "")
4803 (ior:SI (match_operand:SI 1 "register_operand" "")
4804 (match_operand:SI 2 "const_compl_high_operand" "")))
4805 (clobber (match_operand:SI 3 "register_operand" ""))]
4807 [(set (match_dup 3) (match_dup 4))
4808 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4810 operands[4] = GEN_INT (~INTVAL (operands[2]));
4813 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4814 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4815 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4816 (match_operand:V64I 2 "register_operand" "r,b")))]
4820 fornot1\t%1, %2, %0"
4821 "&& reload_completed
4822 && ((GET_CODE (operands[0]) == REG
4823 && REGNO (operands[0]) < 32)
4824 || (GET_CODE (operands[0]) == SUBREG
4825 && GET_CODE (SUBREG_REG (operands[0])) == REG
4826 && REGNO (SUBREG_REG (operands[0])) < 32))"
4827 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4828 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4829 "operands[3] = gen_highpart (SImode, operands[0]);
4830 operands[4] = gen_highpart (SImode, operands[1]);
4831 operands[5] = gen_highpart (SImode, operands[2]);
4832 operands[6] = gen_lowpart (SImode, operands[0]);
4833 operands[7] = gen_lowpart (SImode, operands[1]);
4834 operands[8] = gen_lowpart (SImode, operands[2]);"
4835 [(set_attr "type" "*,fga")
4836 (set_attr "length" "2,*")
4837 (set_attr "fptype" "*,double")])
4839 (define_insn "*or_not_<V64I:mode>_sp64"
4840 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4841 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4842 (match_operand:V64I 2 "register_operand" "r,b")))]
4846 fornot1\t%1, %2, %0"
4847 [(set_attr "type" "*,fga")
4848 (set_attr "fptype" "*,double")])
4850 (define_insn "*or_not_<V32I:mode>"
4851 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4852 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4853 (match_operand:V32I 2 "register_operand" "r,d")))]
4857 fornot1s\t%1, %2, %0"
4858 [(set_attr "type" "*,fga")
4859 (set_attr "fptype" "*,single")])
4861 (define_expand "xor<V64I:mode>3"
4862 [(set (match_operand:V64I 0 "register_operand" "")
4863 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4864 (match_operand:V64I 2 "arith_double_operand" "")))]
4868 (define_insn "*xor<V64I:mode>3_sp32"
4869 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4870 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4871 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4876 [(set_attr "type" "*,fga")
4877 (set_attr "length" "2,*")
4878 (set_attr "fptype" "*,double")])
4880 (define_insn "*xor<V64I:mode>3_sp64"
4881 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4882 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4883 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4888 [(set_attr "type" "*,fga")
4889 (set_attr "fptype" "*,double")])
4891 (define_insn "xor<V32I:mode>3"
4892 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4893 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4894 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4899 [(set_attr "type" "*,fga")
4900 (set_attr "fptype" "*,single")])
4903 [(set (match_operand:SI 0 "register_operand" "")
4904 (xor:SI (match_operand:SI 1 "register_operand" "")
4905 (match_operand:SI 2 "const_compl_high_operand" "")))
4906 (clobber (match_operand:SI 3 "register_operand" ""))]
4908 [(set (match_dup 3) (match_dup 4))
4909 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4911 operands[4] = GEN_INT (~INTVAL (operands[2]));
4915 [(set (match_operand:SI 0 "register_operand" "")
4916 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4917 (match_operand:SI 2 "const_compl_high_operand" ""))))
4918 (clobber (match_operand:SI 3 "register_operand" ""))]
4920 [(set (match_dup 3) (match_dup 4))
4921 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4923 operands[4] = GEN_INT (~INTVAL (operands[2]));
4926 ;; Split DImode logical operations requiring two instructions.
4928 [(set (match_operand:V64I 0 "register_operand" "")
4929 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4930 [(match_operand:V64I 2 "register_operand" "")
4931 (match_operand:V64I 3 "arith_double_operand" "")]))]
4934 && ((GET_CODE (operands[0]) == REG
4935 && REGNO (operands[0]) < 32)
4936 || (GET_CODE (operands[0]) == SUBREG
4937 && GET_CODE (SUBREG_REG (operands[0])) == REG
4938 && REGNO (SUBREG_REG (operands[0])) < 32))"
4939 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4940 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4942 operands[4] = gen_highpart (SImode, operands[0]);
4943 operands[5] = gen_lowpart (SImode, operands[0]);
4944 operands[6] = gen_highpart (SImode, operands[2]);
4945 operands[7] = gen_lowpart (SImode, operands[2]);
4946 #if HOST_BITS_PER_WIDE_INT == 32
4947 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4949 if (INTVAL (operands[3]) < 0)
4950 operands[8] = constm1_rtx;
4952 operands[8] = const0_rtx;
4956 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4957 operands[9] = gen_lowpart (SImode, operands[3]);
4960 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4961 ;; Combine now canonicalizes to the rightmost expression.
4962 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4963 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4964 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4965 (match_operand:V64I 2 "register_operand" "r,b"))))]
4970 "&& reload_completed
4971 && ((GET_CODE (operands[0]) == REG
4972 && REGNO (operands[0]) < 32)
4973 || (GET_CODE (operands[0]) == SUBREG
4974 && GET_CODE (SUBREG_REG (operands[0])) == REG
4975 && REGNO (SUBREG_REG (operands[0])) < 32))"
4976 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4977 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4978 "operands[3] = gen_highpart (SImode, operands[0]);
4979 operands[4] = gen_highpart (SImode, operands[1]);
4980 operands[5] = gen_highpart (SImode, operands[2]);
4981 operands[6] = gen_lowpart (SImode, operands[0]);
4982 operands[7] = gen_lowpart (SImode, operands[1]);
4983 operands[8] = gen_lowpart (SImode, operands[2]);"
4984 [(set_attr "type" "*,fga")
4985 (set_attr "length" "2,*")
4986 (set_attr "fptype" "*,double")])
4988 (define_insn "*xor_not_<V64I:mode>_sp64"
4989 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4990 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4991 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4996 [(set_attr "type" "*,fga")
4997 (set_attr "fptype" "*,double")])
4999 (define_insn "*xor_not_<V32I:mode>"
5000 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5001 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5002 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5007 [(set_attr "type" "*,fga")
5008 (set_attr "fptype" "*,single")])
5010 ;; These correspond to the above in the case where we also (or only)
5011 ;; want to set the condition code.
5013 (define_insn "*cmp_cc_arith_op"
5014 [(set (reg:CC CC_REG)
5016 (match_operator:SI 2 "cc_arith_operator"
5017 [(match_operand:SI 0 "arith_operand" "%r")
5018 (match_operand:SI 1 "arith_operand" "rI")])
5021 "%A2cc\t%0, %1, %%g0"
5022 [(set_attr "type" "compare")])
5024 (define_insn "*cmp_ccx_arith_op"
5025 [(set (reg:CCX CC_REG)
5027 (match_operator:DI 2 "cc_arith_operator"
5028 [(match_operand:DI 0 "arith_operand" "%r")
5029 (match_operand:DI 1 "arith_operand" "rI")])
5032 "%A2cc\t%0, %1, %%g0"
5033 [(set_attr "type" "compare")])
5035 (define_insn "*cmp_cc_arith_op_set"
5036 [(set (reg:CC CC_REG)
5038 (match_operator:SI 3 "cc_arith_operator"
5039 [(match_operand:SI 1 "arith_operand" "%r")
5040 (match_operand:SI 2 "arith_operand" "rI")])
5042 (set (match_operand:SI 0 "register_operand" "=r")
5043 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5044 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5046 [(set_attr "type" "compare")])
5048 (define_insn "*cmp_ccx_arith_op_set"
5049 [(set (reg:CCX CC_REG)
5051 (match_operator:DI 3 "cc_arith_operator"
5052 [(match_operand:DI 1 "arith_operand" "%r")
5053 (match_operand:DI 2 "arith_operand" "rI")])
5055 (set (match_operand:DI 0 "register_operand" "=r")
5056 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5057 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5059 [(set_attr "type" "compare")])
5061 (define_insn "*cmp_cc_xor_not"
5062 [(set (reg:CC CC_REG)
5064 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5065 (match_operand:SI 1 "arith_operand" "rI")))
5068 "xnorcc\t%r0, %1, %%g0"
5069 [(set_attr "type" "compare")])
5071 (define_insn "*cmp_ccx_xor_not"
5072 [(set (reg:CCX CC_REG)
5074 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5075 (match_operand:DI 1 "arith_operand" "rI")))
5078 "xnorcc\t%r0, %1, %%g0"
5079 [(set_attr "type" "compare")])
5081 (define_insn "*cmp_cc_xor_not_set"
5082 [(set (reg:CC CC_REG)
5084 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5085 (match_operand:SI 2 "arith_operand" "rI")))
5087 (set (match_operand:SI 0 "register_operand" "=r")
5088 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5090 "xnorcc\t%r1, %2, %0"
5091 [(set_attr "type" "compare")])
5093 (define_insn "*cmp_ccx_xor_not_set"
5094 [(set (reg:CCX CC_REG)
5096 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5097 (match_operand:DI 2 "arith_operand" "rI")))
5099 (set (match_operand:DI 0 "register_operand" "=r")
5100 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5102 "xnorcc\t%r1, %2, %0"
5103 [(set_attr "type" "compare")])
5105 (define_insn "*cmp_cc_arith_op_not"
5106 [(set (reg:CC CC_REG)
5108 (match_operator:SI 2 "cc_arith_not_operator"
5109 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5110 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5113 "%B2cc\t%r1, %0, %%g0"
5114 [(set_attr "type" "compare")])
5116 (define_insn "*cmp_ccx_arith_op_not"
5117 [(set (reg:CCX CC_REG)
5119 (match_operator:DI 2 "cc_arith_not_operator"
5120 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5121 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5124 "%B2cc\t%r1, %0, %%g0"
5125 [(set_attr "type" "compare")])
5127 (define_insn "*cmp_cc_arith_op_not_set"
5128 [(set (reg:CC CC_REG)
5130 (match_operator:SI 3 "cc_arith_not_operator"
5131 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5132 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5134 (set (match_operand:SI 0 "register_operand" "=r")
5135 (match_operator:SI 4 "cc_arith_not_operator"
5136 [(not:SI (match_dup 1)) (match_dup 2)]))]
5137 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5138 "%B3cc\t%r2, %1, %0"
5139 [(set_attr "type" "compare")])
5141 (define_insn "*cmp_ccx_arith_op_not_set"
5142 [(set (reg:CCX CC_REG)
5144 (match_operator:DI 3 "cc_arith_not_operator"
5145 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5146 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5148 (set (match_operand:DI 0 "register_operand" "=r")
5149 (match_operator:DI 4 "cc_arith_not_operator"
5150 [(not:DI (match_dup 1)) (match_dup 2)]))]
5151 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5152 "%B3cc\t%r2, %1, %0"
5153 [(set_attr "type" "compare")])
5155 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5156 ;; does not know how to make it work for constants.
5158 (define_expand "negdi2"
5159 [(set (match_operand:DI 0 "register_operand" "=r")
5160 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5163 if (! TARGET_ARCH64)
5165 emit_insn (gen_rtx_PARALLEL
5168 gen_rtx_SET (VOIDmode, operand0,
5169 gen_rtx_NEG (DImode, operand1)),
5170 gen_rtx_CLOBBER (VOIDmode,
5171 gen_rtx_REG (CCmode,
5177 (define_insn_and_split "*negdi2_sp32"
5178 [(set (match_operand:DI 0 "register_operand" "=r")
5179 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5180 (clobber (reg:CC CC_REG))]
5183 "&& reload_completed"
5184 [(parallel [(set (reg:CC_NOOV CC_REG)
5185 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5187 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5188 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5189 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5190 "operands[2] = gen_highpart (SImode, operands[0]);
5191 operands[3] = gen_highpart (SImode, operands[1]);
5192 operands[4] = gen_lowpart (SImode, operands[0]);
5193 operands[5] = gen_lowpart (SImode, operands[1]);"
5194 [(set_attr "length" "2")])
5196 (define_insn "*negdi2_sp64"
5197 [(set (match_operand:DI 0 "register_operand" "=r")
5198 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5200 "sub\t%%g0, %1, %0")
5202 (define_insn "negsi2"
5203 [(set (match_operand:SI 0 "register_operand" "=r")
5204 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5206 "sub\t%%g0, %1, %0")
5208 (define_insn "*cmp_cc_neg"
5209 [(set (reg:CC_NOOV CC_REG)
5210 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5213 "subcc\t%%g0, %0, %%g0"
5214 [(set_attr "type" "compare")])
5216 (define_insn "*cmp_ccx_neg"
5217 [(set (reg:CCX_NOOV CC_REG)
5218 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5221 "subcc\t%%g0, %0, %%g0"
5222 [(set_attr "type" "compare")])
5224 (define_insn "*cmp_cc_set_neg"
5225 [(set (reg:CC_NOOV CC_REG)
5226 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5228 (set (match_operand:SI 0 "register_operand" "=r")
5229 (neg:SI (match_dup 1)))]
5231 "subcc\t%%g0, %1, %0"
5232 [(set_attr "type" "compare")])
5234 (define_insn "*cmp_ccx_set_neg"
5235 [(set (reg:CCX_NOOV CC_REG)
5236 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5238 (set (match_operand:DI 0 "register_operand" "=r")
5239 (neg:DI (match_dup 1)))]
5241 "subcc\t%%g0, %1, %0"
5242 [(set_attr "type" "compare")])
5244 ;; We cannot use the "not" pseudo insn because the Sun assembler
5245 ;; does not know how to make it work for constants.
5246 (define_expand "one_cmpl<V64I:mode>2"
5247 [(set (match_operand:V64I 0 "register_operand" "")
5248 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5252 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5253 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5254 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5259 "&& reload_completed
5260 && ((GET_CODE (operands[0]) == REG
5261 && REGNO (operands[0]) < 32)
5262 || (GET_CODE (operands[0]) == SUBREG
5263 && GET_CODE (SUBREG_REG (operands[0])) == REG
5264 && REGNO (SUBREG_REG (operands[0])) < 32))"
5265 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5266 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5267 "operands[2] = gen_highpart (SImode, operands[0]);
5268 operands[3] = gen_highpart (SImode, operands[1]);
5269 operands[4] = gen_lowpart (SImode, operands[0]);
5270 operands[5] = gen_lowpart (SImode, operands[1]);"
5271 [(set_attr "type" "*,fga")
5272 (set_attr "length" "2,*")
5273 (set_attr "fptype" "*,double")])
5275 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5276 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5277 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5282 [(set_attr "type" "*,fga")
5283 (set_attr "fptype" "*,double")])
5285 (define_insn "one_cmpl<V32I:mode>2"
5286 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5287 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5292 [(set_attr "type" "*,fga")
5293 (set_attr "fptype" "*,single")])
5295 (define_insn "*cmp_cc_not"
5296 [(set (reg:CC CC_REG)
5297 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5300 "xnorcc\t%%g0, %0, %%g0"
5301 [(set_attr "type" "compare")])
5303 (define_insn "*cmp_ccx_not"
5304 [(set (reg:CCX CC_REG)
5305 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5308 "xnorcc\t%%g0, %0, %%g0"
5309 [(set_attr "type" "compare")])
5311 (define_insn "*cmp_cc_set_not"
5312 [(set (reg:CC CC_REG)
5313 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5315 (set (match_operand:SI 0 "register_operand" "=r")
5316 (not:SI (match_dup 1)))]
5318 "xnorcc\t%%g0, %1, %0"
5319 [(set_attr "type" "compare")])
5321 (define_insn "*cmp_ccx_set_not"
5322 [(set (reg:CCX CC_REG)
5323 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5325 (set (match_operand:DI 0 "register_operand" "=r")
5326 (not:DI (match_dup 1)))]
5328 "xnorcc\t%%g0, %1, %0"
5329 [(set_attr "type" "compare")])
5331 (define_insn "*cmp_cc_set"
5332 [(set (match_operand:SI 0 "register_operand" "=r")
5333 (match_operand:SI 1 "register_operand" "r"))
5334 (set (reg:CC CC_REG)
5335 (compare:CC (match_dup 1)
5339 [(set_attr "type" "compare")])
5341 (define_insn "*cmp_ccx_set64"
5342 [(set (match_operand:DI 0 "register_operand" "=r")
5343 (match_operand:DI 1 "register_operand" "r"))
5344 (set (reg:CCX CC_REG)
5345 (compare:CCX (match_dup 1)
5349 [(set_attr "type" "compare")])
5352 ;; Floating point arithmetic instructions.
5354 (define_expand "addtf3"
5355 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5356 (plus:TF (match_operand:TF 1 "general_operand" "")
5357 (match_operand:TF 2 "general_operand" "")))]
5358 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5359 "emit_tfmode_binop (PLUS, operands); DONE;")
5361 (define_insn "*addtf3_hq"
5362 [(set (match_operand:TF 0 "register_operand" "=e")
5363 (plus:TF (match_operand:TF 1 "register_operand" "e")
5364 (match_operand:TF 2 "register_operand" "e")))]
5365 "TARGET_FPU && TARGET_HARD_QUAD"
5367 [(set_attr "type" "fp")])
5369 (define_insn "adddf3"
5370 [(set (match_operand:DF 0 "register_operand" "=e")
5371 (plus:DF (match_operand:DF 1 "register_operand" "e")
5372 (match_operand:DF 2 "register_operand" "e")))]
5375 [(set_attr "type" "fp")
5376 (set_attr "fptype" "double")])
5378 (define_insn "addsf3"
5379 [(set (match_operand:SF 0 "register_operand" "=f")
5380 (plus:SF (match_operand:SF 1 "register_operand" "f")
5381 (match_operand:SF 2 "register_operand" "f")))]
5384 [(set_attr "type" "fp")])
5386 (define_expand "subtf3"
5387 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5388 (minus:TF (match_operand:TF 1 "general_operand" "")
5389 (match_operand:TF 2 "general_operand" "")))]
5390 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5391 "emit_tfmode_binop (MINUS, operands); DONE;")
5393 (define_insn "*subtf3_hq"
5394 [(set (match_operand:TF 0 "register_operand" "=e")
5395 (minus:TF (match_operand:TF 1 "register_operand" "e")
5396 (match_operand:TF 2 "register_operand" "e")))]
5397 "TARGET_FPU && TARGET_HARD_QUAD"
5399 [(set_attr "type" "fp")])
5401 (define_insn "subdf3"
5402 [(set (match_operand:DF 0 "register_operand" "=e")
5403 (minus:DF (match_operand:DF 1 "register_operand" "e")
5404 (match_operand:DF 2 "register_operand" "e")))]
5407 [(set_attr "type" "fp")
5408 (set_attr "fptype" "double")])
5410 (define_insn "subsf3"
5411 [(set (match_operand:SF 0 "register_operand" "=f")
5412 (minus:SF (match_operand:SF 1 "register_operand" "f")
5413 (match_operand:SF 2 "register_operand" "f")))]
5416 [(set_attr "type" "fp")])
5418 (define_expand "multf3"
5419 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5420 (mult:TF (match_operand:TF 1 "general_operand" "")
5421 (match_operand:TF 2 "general_operand" "")))]
5422 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5423 "emit_tfmode_binop (MULT, operands); DONE;")
5425 (define_insn "*multf3_hq"
5426 [(set (match_operand:TF 0 "register_operand" "=e")
5427 (mult:TF (match_operand:TF 1 "register_operand" "e")
5428 (match_operand:TF 2 "register_operand" "e")))]
5429 "TARGET_FPU && TARGET_HARD_QUAD"
5431 [(set_attr "type" "fpmul")])
5433 (define_insn "muldf3"
5434 [(set (match_operand:DF 0 "register_operand" "=e")
5435 (mult:DF (match_operand:DF 1 "register_operand" "e")
5436 (match_operand:DF 2 "register_operand" "e")))]
5439 [(set_attr "type" "fpmul")
5440 (set_attr "fptype" "double")])
5442 (define_insn "mulsf3"
5443 [(set (match_operand:SF 0 "register_operand" "=f")
5444 (mult:SF (match_operand:SF 1 "register_operand" "f")
5445 (match_operand:SF 2 "register_operand" "f")))]
5448 [(set_attr "type" "fpmul")])
5450 (define_insn "fmadf4"
5451 [(set (match_operand:DF 0 "register_operand" "=e")
5452 (fma:DF (match_operand:DF 1 "register_operand" "e")
5453 (match_operand:DF 2 "register_operand" "e")
5454 (match_operand:DF 3 "register_operand" "e")))]
5456 "fmaddd\t%1, %2, %3, %0"
5457 [(set_attr "type" "fpmul")])
5459 (define_insn "fmsdf4"
5460 [(set (match_operand:DF 0 "register_operand" "=e")
5461 (fma:DF (match_operand:DF 1 "register_operand" "e")
5462 (match_operand:DF 2 "register_operand" "e")
5463 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5465 "fmsubd\t%1, %2, %3, %0"
5466 [(set_attr "type" "fpmul")])
5468 (define_insn "*nfmadf4"
5469 [(set (match_operand:DF 0 "register_operand" "=e")
5470 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5471 (match_operand:DF 2 "register_operand" "e")
5472 (match_operand:DF 3 "register_operand" "e"))))]
5474 "fnmaddd\t%1, %2, %3, %0"
5475 [(set_attr "type" "fpmul")])
5477 (define_insn "*nfmsdf4"
5478 [(set (match_operand:DF 0 "register_operand" "=e")
5479 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5480 (match_operand:DF 2 "register_operand" "e")
5481 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5483 "fnmsubd\t%1, %2, %3, %0"
5484 [(set_attr "type" "fpmul")])
5486 (define_insn "fmasf4"
5487 [(set (match_operand:SF 0 "register_operand" "=f")
5488 (fma:SF (match_operand:SF 1 "register_operand" "f")
5489 (match_operand:SF 2 "register_operand" "f")
5490 (match_operand:SF 3 "register_operand" "f")))]
5492 "fmadds\t%1, %2, %3, %0"
5493 [(set_attr "type" "fpmul")])
5495 (define_insn "fmssf4"
5496 [(set (match_operand:SF 0 "register_operand" "=f")
5497 (fma:SF (match_operand:SF 1 "register_operand" "f")
5498 (match_operand:SF 2 "register_operand" "f")
5499 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5501 "fmsubs\t%1, %2, %3, %0"
5502 [(set_attr "type" "fpmul")])
5504 (define_insn "*nfmasf4"
5505 [(set (match_operand:SF 0 "register_operand" "=f")
5506 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5507 (match_operand:SF 2 "register_operand" "f")
5508 (match_operand:SF 3 "register_operand" "f"))))]
5510 "fnmadds\t%1, %2, %3, %0"
5511 [(set_attr "type" "fpmul")])
5513 (define_insn "*nfmssf4"
5514 [(set (match_operand:SF 0 "register_operand" "=f")
5515 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5516 (match_operand:SF 2 "register_operand" "f")
5517 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5519 "fnmsubs\t%1, %2, %3, %0"
5520 [(set_attr "type" "fpmul")])
5522 (define_insn "*muldf3_extend"
5523 [(set (match_operand:DF 0 "register_operand" "=e")
5524 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5525 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5526 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5527 "fsmuld\t%1, %2, %0"
5528 [(set_attr "type" "fpmul")
5529 (set_attr "fptype" "double")])
5531 (define_insn "*multf3_extend"
5532 [(set (match_operand:TF 0 "register_operand" "=e")
5533 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5534 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5535 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5536 "fdmulq\t%1, %2, %0"
5537 [(set_attr "type" "fpmul")])
5539 (define_expand "divtf3"
5540 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5541 (div:TF (match_operand:TF 1 "general_operand" "")
5542 (match_operand:TF 2 "general_operand" "")))]
5543 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5544 "emit_tfmode_binop (DIV, operands); DONE;")
5546 ;; don't have timing for quad-prec. divide.
5547 (define_insn "*divtf3_hq"
5548 [(set (match_operand:TF 0 "register_operand" "=e")
5549 (div:TF (match_operand:TF 1 "register_operand" "e")
5550 (match_operand:TF 2 "register_operand" "e")))]
5551 "TARGET_FPU && TARGET_HARD_QUAD"
5553 [(set_attr "type" "fpdivd")])
5555 (define_insn "divdf3"
5556 [(set (match_operand:DF 0 "register_operand" "=e")
5557 (div:DF (match_operand:DF 1 "register_operand" "e")
5558 (match_operand:DF 2 "register_operand" "e")))]
5561 [(set_attr "type" "fpdivd")
5562 (set_attr "fptype" "double")])
5564 (define_insn "divsf3"
5565 [(set (match_operand:SF 0 "register_operand" "=f")
5566 (div:SF (match_operand:SF 1 "register_operand" "f")
5567 (match_operand:SF 2 "register_operand" "f")))]
5570 [(set_attr "type" "fpdivs")])
5572 (define_expand "negtf2"
5573 [(set (match_operand:TF 0 "register_operand" "=e,e")
5574 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5578 (define_insn_and_split "*negtf2_notv9"
5579 [(set (match_operand:TF 0 "register_operand" "=e,e")
5580 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5581 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5587 "&& reload_completed
5588 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5589 [(set (match_dup 2) (neg:SF (match_dup 3)))
5590 (set (match_dup 4) (match_dup 5))
5591 (set (match_dup 6) (match_dup 7))]
5592 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5593 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5594 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5595 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5596 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5597 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5598 [(set_attr "type" "fpmove,*")
5599 (set_attr "length" "*,2")])
5601 (define_insn_and_split "*negtf2_v9"
5602 [(set (match_operand:TF 0 "register_operand" "=e,e")
5603 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5604 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5605 "TARGET_FPU && TARGET_V9"
5609 "&& reload_completed
5610 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5611 [(set (match_dup 2) (neg:DF (match_dup 3)))
5612 (set (match_dup 4) (match_dup 5))]
5613 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5614 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5615 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5616 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5617 [(set_attr "type" "fpmove,*")
5618 (set_attr "length" "*,2")
5619 (set_attr "fptype" "double")])
5621 (define_expand "negdf2"
5622 [(set (match_operand:DF 0 "register_operand" "")
5623 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5627 (define_insn_and_split "*negdf2_notv9"
5628 [(set (match_operand:DF 0 "register_operand" "=e,e")
5629 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5630 "TARGET_FPU && ! TARGET_V9"
5634 "&& reload_completed
5635 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5636 [(set (match_dup 2) (neg:SF (match_dup 3)))
5637 (set (match_dup 4) (match_dup 5))]
5638 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5639 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5640 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5641 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5642 [(set_attr "type" "fpmove,*")
5643 (set_attr "length" "*,2")])
5645 (define_insn "*negdf2_v9"
5646 [(set (match_operand:DF 0 "register_operand" "=e")
5647 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5648 "TARGET_FPU && TARGET_V9"
5650 [(set_attr "type" "fpmove")
5651 (set_attr "fptype" "double")])
5653 (define_insn "negsf2"
5654 [(set (match_operand:SF 0 "register_operand" "=f")
5655 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5658 [(set_attr "type" "fpmove")])
5660 (define_expand "abstf2"
5661 [(set (match_operand:TF 0 "register_operand" "")
5662 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5666 (define_insn_and_split "*abstf2_notv9"
5667 [(set (match_operand:TF 0 "register_operand" "=e,e")
5668 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5669 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5670 "TARGET_FPU && ! TARGET_V9"
5674 "&& reload_completed
5675 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5676 [(set (match_dup 2) (abs:SF (match_dup 3)))
5677 (set (match_dup 4) (match_dup 5))
5678 (set (match_dup 6) (match_dup 7))]
5679 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5680 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5681 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5682 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5683 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5684 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5685 [(set_attr "type" "fpmove,*")
5686 (set_attr "length" "*,2")])
5688 (define_insn "*abstf2_hq_v9"
5689 [(set (match_operand:TF 0 "register_operand" "=e,e")
5690 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5691 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5695 [(set_attr "type" "fpmove")
5696 (set_attr "fptype" "double,*")])
5698 (define_insn_and_split "*abstf2_v9"
5699 [(set (match_operand:TF 0 "register_operand" "=e,e")
5700 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5701 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5705 "&& reload_completed
5706 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5707 [(set (match_dup 2) (abs:DF (match_dup 3)))
5708 (set (match_dup 4) (match_dup 5))]
5709 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5710 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5711 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5712 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5713 [(set_attr "type" "fpmove,*")
5714 (set_attr "length" "*,2")
5715 (set_attr "fptype" "double,*")])
5717 (define_expand "absdf2"
5718 [(set (match_operand:DF 0 "register_operand" "")
5719 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5723 (define_insn_and_split "*absdf2_notv9"
5724 [(set (match_operand:DF 0 "register_operand" "=e,e")
5725 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5726 "TARGET_FPU && ! TARGET_V9"
5730 "&& reload_completed
5731 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5732 [(set (match_dup 2) (abs:SF (match_dup 3)))
5733 (set (match_dup 4) (match_dup 5))]
5734 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5735 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5736 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5737 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5738 [(set_attr "type" "fpmove,*")
5739 (set_attr "length" "*,2")])
5741 (define_insn "*absdf2_v9"
5742 [(set (match_operand:DF 0 "register_operand" "=e")
5743 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5744 "TARGET_FPU && TARGET_V9"
5746 [(set_attr "type" "fpmove")
5747 (set_attr "fptype" "double")])
5749 (define_insn "abssf2"
5750 [(set (match_operand:SF 0 "register_operand" "=f")
5751 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5754 [(set_attr "type" "fpmove")])
5756 (define_expand "sqrttf2"
5757 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5758 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5759 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5760 "emit_tfmode_unop (SQRT, operands); DONE;")
5762 (define_insn "*sqrttf2_hq"
5763 [(set (match_operand:TF 0 "register_operand" "=e")
5764 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5765 "TARGET_FPU && TARGET_HARD_QUAD"
5767 [(set_attr "type" "fpsqrtd")])
5769 (define_insn "sqrtdf2"
5770 [(set (match_operand:DF 0 "register_operand" "=e")
5771 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5774 [(set_attr "type" "fpsqrtd")
5775 (set_attr "fptype" "double")])
5777 (define_insn "sqrtsf2"
5778 [(set (match_operand:SF 0 "register_operand" "=f")
5779 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5782 [(set_attr "type" "fpsqrts")])
5785 ;; Arithmetic shift instructions.
5787 (define_insn "ashlsi3"
5788 [(set (match_operand:SI 0 "register_operand" "=r")
5789 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5790 (match_operand:SI 2 "arith_operand" "rI")))]
5793 if (GET_CODE (operands[2]) == CONST_INT)
5794 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5795 return "sll\t%1, %2, %0";
5797 [(set_attr "type" "shift")])
5799 (define_insn "*ashlsi3_extend"
5800 [(set (match_operand:DI 0 "register_operand" "=r")
5802 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5803 (match_operand:SI 2 "arith_operand" "rI"))))]
5806 if (GET_CODE (operands[2]) == CONST_INT)
5807 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5808 return "sll\t%1, %2, %0";
5810 [(set_attr "type" "shift")])
5812 (define_expand "ashldi3"
5813 [(set (match_operand:DI 0 "register_operand" "=r")
5814 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5815 (match_operand:SI 2 "arith_operand" "rI")))]
5816 "TARGET_ARCH64 || TARGET_V8PLUS"
5818 if (! TARGET_ARCH64)
5820 if (GET_CODE (operands[2]) == CONST_INT)
5822 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5827 (define_insn "*ashldi3_sp64"
5828 [(set (match_operand:DI 0 "register_operand" "=r")
5829 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5830 (match_operand:SI 2 "arith_operand" "rI")))]
5833 if (GET_CODE (operands[2]) == CONST_INT)
5834 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5835 return "sllx\t%1, %2, %0";
5837 [(set_attr "type" "shift")])
5840 (define_insn "ashldi3_v8plus"
5841 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5842 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5843 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5844 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5846 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5847 [(set_attr "type" "multi")
5848 (set_attr "length" "5,5,6")])
5850 ;; Optimize (1LL<<x)-1
5851 ;; XXX this also needs to be fixed to handle equal subregs
5852 ;; XXX first before we could re-enable it.
5854 ; [(set (match_operand:DI 0 "register_operand" "=h")
5855 ; (plus:DI (ashift:DI (const_int 1)
5856 ; (match_operand:SI 1 "arith_operand" "rI"))
5858 ; "0 && TARGET_V8PLUS"
5860 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5861 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5862 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5864 ; [(set_attr "type" "multi")
5865 ; (set_attr "length" "4")])
5867 (define_insn "*cmp_cc_ashift_1"
5868 [(set (reg:CC_NOOV CC_REG)
5869 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5873 "addcc\t%0, %0, %%g0"
5874 [(set_attr "type" "compare")])
5876 (define_insn "*cmp_cc_set_ashift_1"
5877 [(set (reg:CC_NOOV CC_REG)
5878 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5881 (set (match_operand:SI 0 "register_operand" "=r")
5882 (ashift:SI (match_dup 1) (const_int 1)))]
5885 [(set_attr "type" "compare")])
5887 (define_insn "ashrsi3"
5888 [(set (match_operand:SI 0 "register_operand" "=r")
5889 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5890 (match_operand:SI 2 "arith_operand" "rI")))]
5893 if (GET_CODE (operands[2]) == CONST_INT)
5894 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5895 return "sra\t%1, %2, %0";
5897 [(set_attr "type" "shift")])
5899 (define_insn "*ashrsi3_extend"
5900 [(set (match_operand:DI 0 "register_operand" "=r")
5901 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5902 (match_operand:SI 2 "arith_operand" "r"))))]
5905 [(set_attr "type" "shift")])
5907 ;; This handles the case as above, but with constant shift instead of
5908 ;; register. Combiner "simplifies" it for us a little bit though.
5909 (define_insn "*ashrsi3_extend2"
5910 [(set (match_operand:DI 0 "register_operand" "=r")
5911 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5913 (match_operand:SI 2 "small_int_operand" "I")))]
5914 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5916 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5917 return "sra\t%1, %2, %0";
5919 [(set_attr "type" "shift")])
5921 (define_expand "ashrdi3"
5922 [(set (match_operand:DI 0 "register_operand" "=r")
5923 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5924 (match_operand:SI 2 "arith_operand" "rI")))]
5925 "TARGET_ARCH64 || TARGET_V8PLUS"
5927 if (! TARGET_ARCH64)
5929 if (GET_CODE (operands[2]) == CONST_INT)
5930 FAIL; /* prefer generic code in this case */
5931 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5936 (define_insn "*ashrdi3_sp64"
5937 [(set (match_operand:DI 0 "register_operand" "=r")
5938 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5939 (match_operand:SI 2 "arith_operand" "rI")))]
5943 if (GET_CODE (operands[2]) == CONST_INT)
5944 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5945 return "srax\t%1, %2, %0";
5947 [(set_attr "type" "shift")])
5950 (define_insn "ashrdi3_v8plus"
5951 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5952 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5953 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5954 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5956 "* return output_v8plus_shift (operands, insn, \"srax\");"
5957 [(set_attr "type" "multi")
5958 (set_attr "length" "5,5,6")])
5960 (define_insn "lshrsi3"
5961 [(set (match_operand:SI 0 "register_operand" "=r")
5962 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5963 (match_operand:SI 2 "arith_operand" "rI")))]
5966 if (GET_CODE (operands[2]) == CONST_INT)
5967 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5968 return "srl\t%1, %2, %0";
5970 [(set_attr "type" "shift")])
5972 (define_insn "*lshrsi3_extend0"
5973 [(set (match_operand:DI 0 "register_operand" "=r")
5975 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5976 (match_operand:SI 2 "arith_operand" "rI"))))]
5979 if (GET_CODE (operands[2]) == CONST_INT)
5980 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5981 return "srl\t%1, %2, %0";
5983 [(set_attr "type" "shift")])
5985 ;; This handles the case where
5986 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5987 ;; but combiner "simplifies" it for us.
5988 (define_insn "*lshrsi3_extend1"
5989 [(set (match_operand:DI 0 "register_operand" "=r")
5990 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5991 (match_operand:SI 2 "arith_operand" "r")) 0)
5992 (match_operand 3 "const_int_operand" "")))]
5993 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5995 [(set_attr "type" "shift")])
5997 ;; This handles the case where
5998 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5999 ;; but combiner "simplifies" it for us.
6000 (define_insn "*lshrsi3_extend2"
6001 [(set (match_operand:DI 0 "register_operand" "=r")
6002 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6003 (match_operand 2 "small_int_operand" "I")
6005 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6007 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6008 return "srl\t%1, %2, %0";
6010 [(set_attr "type" "shift")])
6012 (define_expand "lshrdi3"
6013 [(set (match_operand:DI 0 "register_operand" "=r")
6014 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6015 (match_operand:SI 2 "arith_operand" "rI")))]
6016 "TARGET_ARCH64 || TARGET_V8PLUS"
6018 if (! TARGET_ARCH64)
6020 if (GET_CODE (operands[2]) == CONST_INT)
6022 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6027 (define_insn "*lshrdi3_sp64"
6028 [(set (match_operand:DI 0 "register_operand" "=r")
6029 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6030 (match_operand:SI 2 "arith_operand" "rI")))]
6033 if (GET_CODE (operands[2]) == CONST_INT)
6034 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6035 return "srlx\t%1, %2, %0";
6037 [(set_attr "type" "shift")])
6040 (define_insn "lshrdi3_v8plus"
6041 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6042 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6043 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6044 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6046 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6047 [(set_attr "type" "multi")
6048 (set_attr "length" "5,5,6")])
6051 [(set (match_operand:SI 0 "register_operand" "=r")
6052 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6054 (match_operand:SI 2 "small_int_operand" "I")))]
6055 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6057 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6058 return "srax\t%1, %2, %0";
6060 [(set_attr "type" "shift")])
6063 [(set (match_operand:SI 0 "register_operand" "=r")
6064 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6066 (match_operand:SI 2 "small_int_operand" "I")))]
6067 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6069 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6070 return "srlx\t%1, %2, %0";
6072 [(set_attr "type" "shift")])
6075 [(set (match_operand:SI 0 "register_operand" "=r")
6076 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6077 (match_operand:SI 2 "small_int_operand" "I")) 4)
6078 (match_operand:SI 3 "small_int_operand" "I")))]
6080 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6081 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6082 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6084 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6086 return "srax\t%1, %2, %0";
6088 [(set_attr "type" "shift")])
6091 [(set (match_operand:SI 0 "register_operand" "=r")
6092 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6093 (match_operand:SI 2 "small_int_operand" "I")) 4)
6094 (match_operand:SI 3 "small_int_operand" "I")))]
6096 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6097 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6098 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6100 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6102 return "srlx\t%1, %2, %0";
6104 [(set_attr "type" "shift")])
6107 ;; Unconditional and other jump instructions.
6110 [(set (pc) (label_ref (match_operand 0 "" "")))]
6112 "* return output_ubranch (operands[0], 0, insn);"
6113 [(set_attr "type" "uncond_branch")])
6115 (define_expand "tablejump"
6116 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6117 (use (label_ref (match_operand 1 "" "")))])]
6120 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6122 /* In pic mode, our address differences are against the base of the
6123 table. Add that base value back in; CSE ought to be able to combine
6124 the two address loads. */
6128 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6130 if (CASE_VECTOR_MODE != Pmode)
6131 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6132 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6133 operands[0] = memory_address (Pmode, tmp);
6137 (define_insn "*tablejump_sp32"
6138 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6139 (use (label_ref (match_operand 1 "" "")))]
6142 [(set_attr "type" "uncond_branch")])
6144 (define_insn "*tablejump_sp64"
6145 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6146 (use (label_ref (match_operand 1 "" "")))]
6149 [(set_attr "type" "uncond_branch")])
6152 ;; Jump to subroutine instructions.
6154 (define_expand "call"
6155 ;; Note that this expression is not used for generating RTL.
6156 ;; All the RTL is generated explicitly below.
6157 [(call (match_operand 0 "call_operand" "")
6158 (match_operand 3 "" "i"))]
6159 ;; operands[2] is next_arg_register
6160 ;; operands[3] is struct_value_size_rtx.
6165 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6167 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6169 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6171 /* This is really a PIC sequence. We want to represent
6172 it as a funny jump so its delay slots can be filled.
6174 ??? But if this really *is* a CALL, will not it clobber the
6175 call-clobbered registers? We lose this if it is a JUMP_INSN.
6176 Why cannot we have delay slots filled if it were a CALL? */
6178 /* We accept negative sizes for untyped calls. */
6179 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6184 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6186 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6192 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6193 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6197 fn_rtx = operands[0];
6199 /* We accept negative sizes for untyped calls. */
6200 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6201 sparc_emit_call_insn
6204 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6206 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6209 sparc_emit_call_insn
6212 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6213 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6221 ;; We can't use the same pattern for these two insns, because then registers
6222 ;; in the address may not be properly reloaded.
6224 (define_insn "*call_address_sp32"
6225 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6226 (match_operand 1 "" ""))
6227 (clobber (reg:SI O7_REG))]
6228 ;;- Do not use operand 1 for most machines.
6231 [(set_attr "type" "call")])
6233 (define_insn "*call_symbolic_sp32"
6234 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6235 (match_operand 1 "" ""))
6236 (clobber (reg:SI O7_REG))]
6237 ;;- Do not use operand 1 for most machines.
6240 [(set_attr "type" "call")])
6242 (define_insn "*call_address_sp64"
6243 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6244 (match_operand 1 "" ""))
6245 (clobber (reg:DI O7_REG))]
6246 ;;- Do not use operand 1 for most machines.
6249 [(set_attr "type" "call")])
6251 (define_insn "*call_symbolic_sp64"
6252 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6253 (match_operand 1 "" ""))
6254 (clobber (reg:DI O7_REG))]
6255 ;;- Do not use operand 1 for most machines.
6258 [(set_attr "type" "call")])
6260 ;; This is a call that wants a structure value.
6261 ;; There is no such critter for v9 (??? we may need one anyway).
6262 (define_insn "*call_address_struct_value_sp32"
6263 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6264 (match_operand 1 "" ""))
6265 (match_operand 2 "immediate_operand" "")
6266 (clobber (reg:SI O7_REG))]
6267 ;;- Do not use operand 1 for most machines.
6268 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6270 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6271 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6273 [(set_attr "type" "call_no_delay_slot")
6274 (set_attr "length" "3")])
6276 ;; This is a call that wants a structure value.
6277 ;; There is no such critter for v9 (??? we may need one anyway).
6278 (define_insn "*call_symbolic_struct_value_sp32"
6279 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6280 (match_operand 1 "" ""))
6281 (match_operand 2 "immediate_operand" "")
6282 (clobber (reg:SI O7_REG))]
6283 ;;- Do not use operand 1 for most machines.
6284 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6286 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6287 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6289 [(set_attr "type" "call_no_delay_slot")
6290 (set_attr "length" "3")])
6292 ;; This is a call that may want a structure value. This is used for
6294 (define_insn "*call_address_untyped_struct_value_sp32"
6295 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6296 (match_operand 1 "" ""))
6297 (match_operand 2 "immediate_operand" "")
6298 (clobber (reg:SI O7_REG))]
6299 ;;- Do not use operand 1 for most machines.
6300 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6301 "call\t%a0, %1\n\t nop\n\tnop"
6302 [(set_attr "type" "call_no_delay_slot")
6303 (set_attr "length" "3")])
6305 ;; This is a call that may want a structure value. This is used for
6307 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6308 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6309 (match_operand 1 "" ""))
6310 (match_operand 2 "immediate_operand" "")
6311 (clobber (reg:SI O7_REG))]
6312 ;;- Do not use operand 1 for most machines.
6313 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6314 "call\t%a0, %1\n\t nop\n\tnop"
6315 [(set_attr "type" "call_no_delay_slot")
6316 (set_attr "length" "3")])
6318 (define_expand "call_value"
6319 ;; Note that this expression is not used for generating RTL.
6320 ;; All the RTL is generated explicitly below.
6321 [(set (match_operand 0 "register_operand" "=rf")
6322 (call (match_operand 1 "" "")
6323 (match_operand 4 "" "")))]
6324 ;; operand 2 is stack_size_rtx
6325 ;; operand 3 is next_arg_register
6331 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6333 fn_rtx = operands[1];
6336 gen_rtx_SET (VOIDmode, operands[0],
6337 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6338 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6340 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6345 (define_insn "*call_value_address_sp32"
6346 [(set (match_operand 0 "" "=rf")
6347 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6348 (match_operand 2 "" "")))
6349 (clobber (reg:SI O7_REG))]
6350 ;;- Do not use operand 2 for most machines.
6353 [(set_attr "type" "call")])
6355 (define_insn "*call_value_symbolic_sp32"
6356 [(set (match_operand 0 "" "=rf")
6357 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6358 (match_operand 2 "" "")))
6359 (clobber (reg:SI O7_REG))]
6360 ;;- Do not use operand 2 for most machines.
6363 [(set_attr "type" "call")])
6365 (define_insn "*call_value_address_sp64"
6366 [(set (match_operand 0 "" "")
6367 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6368 (match_operand 2 "" "")))
6369 (clobber (reg:DI O7_REG))]
6370 ;;- Do not use operand 2 for most machines.
6373 [(set_attr "type" "call")])
6375 (define_insn "*call_value_symbolic_sp64"
6376 [(set (match_operand 0 "" "")
6377 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6378 (match_operand 2 "" "")))
6379 (clobber (reg:DI O7_REG))]
6380 ;;- Do not use operand 2 for most machines.
6383 [(set_attr "type" "call")])
6385 (define_expand "untyped_call"
6386 [(parallel [(call (match_operand 0 "" "")
6388 (match_operand:BLK 1 "memory_operand" "")
6389 (match_operand 2 "" "")])]
6392 rtx valreg1 = gen_rtx_REG (DImode, 8);
6393 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6394 rtx result = operands[1];
6396 /* Pass constm1 to indicate that it may expect a structure value, but
6397 we don't know what size it is. */
6398 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6400 /* Save the function value registers. */
6401 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6402 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6405 /* The optimizer does not know that the call sets the function value
6406 registers we stored in the result block. We avoid problems by
6407 claiming that all hard registers are used and clobbered at this
6409 emit_insn (gen_blockage ());
6414 ;; Tail call instructions.
6416 (define_expand "sibcall"
6417 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6422 (define_insn "*sibcall_symbolic_sp32"
6423 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6424 (match_operand 1 "" ""))
6427 "* return output_sibcall(insn, operands[0]);"
6428 [(set_attr "type" "sibcall")])
6430 (define_insn "*sibcall_symbolic_sp64"
6431 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6432 (match_operand 1 "" ""))
6435 "* return output_sibcall(insn, operands[0]);"
6436 [(set_attr "type" "sibcall")])
6438 (define_expand "sibcall_value"
6439 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6440 (call (match_operand 1 "" "") (const_int 0)))
6445 (define_insn "*sibcall_value_symbolic_sp32"
6446 [(set (match_operand 0 "" "=rf")
6447 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6448 (match_operand 2 "" "")))
6451 "* return output_sibcall(insn, operands[1]);"
6452 [(set_attr "type" "sibcall")])
6454 (define_insn "*sibcall_value_symbolic_sp64"
6455 [(set (match_operand 0 "" "")
6456 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6457 (match_operand 2 "" "")))
6460 "* return output_sibcall(insn, operands[1]);"
6461 [(set_attr "type" "sibcall")])
6464 ;; Special instructions.
6466 (define_expand "prologue"
6471 sparc_flat_expand_prologue ();
6473 sparc_expand_prologue ();
6477 ;; The "register window save" insn is modelled as follows. The dwarf2
6478 ;; information is manually added in emit_window_save.
6480 (define_insn "window_save"
6482 [(match_operand 0 "arith_operand" "rI")]
6485 "save\t%%sp, %0, %%sp"
6486 [(set_attr "type" "savew")])
6488 (define_expand "epilogue"
6493 sparc_flat_expand_epilogue (false);
6495 sparc_expand_epilogue (false);
6498 (define_expand "sibcall_epilogue"
6503 sparc_flat_expand_epilogue (false);
6505 sparc_expand_epilogue (false);
6509 (define_expand "eh_return"
6510 [(use (match_operand 0 "general_operand" ""))]
6513 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6514 emit_jump_insn (gen_eh_return_internal ());
6519 (define_insn_and_split "eh_return_internal"
6523 "epilogue_completed"
6527 sparc_flat_expand_epilogue (true);
6529 sparc_expand_epilogue (true);
6532 (define_expand "return"
6534 "sparc_can_use_return_insn_p ()"
6537 (define_insn "*return_internal"
6540 "* return output_return (insn);"
6541 [(set_attr "type" "return")
6542 (set (attr "length")
6543 (cond [(eq_attr "calls_eh_return" "true")
6544 (if_then_else (eq_attr "delayed_branch" "true")
6545 (if_then_else (ior (eq_attr "isa" "v9")
6546 (eq_attr "flat" "true"))
6549 (if_then_else (eq_attr "flat" "true")
6552 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6553 (if_then_else (eq_attr "empty_delay_slot" "true")
6556 (eq_attr "empty_delay_slot" "true")
6557 (if_then_else (eq_attr "delayed_branch" "true")
6562 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6563 ;; all of memory. This blocks insns from being moved across this point.
6565 (define_insn "blockage"
6566 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6569 [(set_attr "length" "0")])
6571 (define_expand "probe_stack"
6572 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6576 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6579 (define_insn "probe_stack_range<P:mode>"
6580 [(set (match_operand:P 0 "register_operand" "=r")
6581 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6582 (match_operand:P 2 "register_operand" "r")]
6583 UNSPECV_PROBE_STACK_RANGE))]
6585 "* return output_probe_stack_range (operands[0], operands[2]);"
6586 [(set_attr "type" "multi")])
6588 ;; Prepare to return any type including a structure value.
6590 (define_expand "untyped_return"
6591 [(match_operand:BLK 0 "memory_operand" "")
6592 (match_operand 1 "" "")]
6595 rtx valreg1 = gen_rtx_REG (DImode, 24);
6596 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6597 rtx result = operands[0];
6599 if (! TARGET_ARCH64)
6601 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6602 rtx value = gen_reg_rtx (SImode);
6604 /* Fetch the instruction where we will return to and see if it's an unimp
6605 instruction (the most significant 10 bits will be zero). If so,
6606 update the return address to skip the unimp instruction. */
6607 emit_move_insn (value,
6608 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6609 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6610 emit_insn (gen_update_return (rtnreg, value));
6613 /* Reload the function value registers. */
6614 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6615 emit_move_insn (valreg2,
6616 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6618 /* Put USE insns before the return. */
6622 /* Construct the return. */
6623 expand_naked_return ();
6628 ;; Adjust the return address conditionally. If the value of op1 is equal
6629 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6630 ;; This is technically *half* the check required by the 32-bit SPARC
6631 ;; psABI. This check only ensures that an "unimp" insn was written by
6632 ;; the caller, but doesn't check to see if the expected size matches
6633 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6634 ;; only used by the above code "untyped_return".
6636 (define_insn "update_return"
6637 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6638 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6641 if (flag_delayed_branch)
6642 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6644 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6646 [(set (attr "type") (const_string "multi"))
6647 (set (attr "length")
6648 (if_then_else (eq_attr "delayed_branch" "true")
6657 (define_expand "indirect_jump"
6658 [(set (pc) (match_operand 0 "address_operand" "p"))]
6662 (define_insn "*branch_sp32"
6663 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6666 [(set_attr "type" "uncond_branch")])
6668 (define_insn "*branch_sp64"
6669 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6672 [(set_attr "type" "uncond_branch")])
6674 (define_expand "save_stack_nonlocal"
6675 [(set (match_operand 0 "memory_operand" "")
6676 (match_operand 1 "register_operand" ""))
6677 (set (match_dup 2) (match_dup 3))]
6680 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6681 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6682 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6685 (define_expand "restore_stack_nonlocal"
6686 [(set (match_operand 0 "register_operand" "")
6687 (match_operand 1 "memory_operand" ""))]
6690 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6693 (define_expand "nonlocal_goto"
6694 [(match_operand 0 "general_operand" "")
6695 (match_operand 1 "general_operand" "")
6696 (match_operand 2 "memory_operand" "")
6697 (match_operand 3 "memory_operand" "")]
6700 rtx r_label = copy_to_reg (operands[1]);
6701 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6702 rtx r_fp = operands[3];
6703 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6705 /* We need to flush all the register windows so that their contents will
6706 be re-synchronized by the restore insn of the target function. */
6708 emit_insn (gen_flush_register_windows ());
6710 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6711 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6713 /* Restore frame pointer for containing function. */
6714 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6715 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6717 /* USE of hard_frame_pointer_rtx added for consistency;
6718 not clear if really needed. */
6719 emit_use (hard_frame_pointer_rtx);
6720 emit_use (stack_pointer_rtx);
6722 /* We need to smuggle the load of %i7 as it is a fixed register. */
6723 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6728 (define_insn "nonlocal_goto_internal"
6729 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6730 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6731 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6733 if (flag_delayed_branch)
6736 return "jmp\t%0\n\t ldx\t%1, %%i7";
6738 return "jmp\t%0\n\t ld\t%1, %%i7";
6743 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6745 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6748 [(set (attr "type") (const_string "multi"))
6749 (set (attr "length")
6750 (if_then_else (eq_attr "delayed_branch" "true")
6754 (define_expand "builtin_setjmp_receiver"
6755 [(label_ref (match_operand 0 "" ""))]
6758 load_got_register ();
6762 ;; Special insn to flush register windows.
6764 (define_insn "flush_register_windows"
6765 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6767 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6768 [(set_attr "type" "flushw")])
6770 ;; Special pattern for the FLUSH instruction.
6772 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6773 ; of the define_insn otherwise missing a mode. We make "flush", aka
6774 ; gen_flush, the default one since sparc_initialize_trampoline uses
6775 ; it on SImode mem values.
6777 (define_insn "flush"
6778 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6780 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6781 [(set_attr "type" "iflush")])
6783 (define_insn "flushdi"
6784 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6786 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6787 [(set_attr "type" "iflush")])
6790 ;; Find first set instructions.
6792 ;; The scan instruction searches from the most significant bit while ffs
6793 ;; searches from the least significant bit. The bit index and treatment of
6794 ;; zero also differ. It takes at least 7 instructions to get the proper
6795 ;; result. Here is an obvious 8 instruction sequence.
6798 (define_insn "ffssi2"
6799 [(set (match_operand:SI 0 "register_operand" "=&r")
6800 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6801 (clobber (match_scratch:SI 2 "=&r"))]
6802 "TARGET_SPARCLITE || TARGET_SPARCLET"
6804 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";
6806 [(set_attr "type" "multi")
6807 (set_attr "length" "8")])
6809 (define_expand "popcount<mode>2"
6810 [(set (match_operand:SIDI 0 "register_operand" "")
6811 (popcount:SIDI (match_operand:SIDI 1 "register_operand" "")))]
6814 if (! TARGET_ARCH64)
6816 emit_insn (gen_popcount<mode>_v8plus (operands[0], operands[1]));
6821 (define_insn "*popcount<mode>_sp64"
6822 [(set (match_operand:SIDI 0 "register_operand" "=r")
6823 (popcount:SIDI (match_operand:SIDI 1 "register_operand" "r")))]
6824 "TARGET_POPC && TARGET_ARCH64"
6827 (define_insn "popcountsi_v8plus"
6828 [(set (match_operand:SI 0 "register_operand" "=r")
6829 (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6830 "TARGET_POPC && ! TARGET_ARCH64"
6832 if (sparc_check_64 (operands[1], insn) <= 0)
6833 output_asm_insn ("srl\t%1, 0, %1", operands);
6834 return "popc\t%1, %0";
6836 [(set_attr "type" "multi")
6837 (set_attr "length" "2")])
6839 (define_insn "popcountdi_v8plus"
6840 [(set (match_operand:DI 0 "register_operand" "=r")
6841 (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6842 (clobber (match_scratch:SI 2 "=&h"))]
6843 "TARGET_POPC && ! TARGET_ARCH64"
6845 if (sparc_check_64 (operands[1], insn) <= 0)
6846 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6847 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6849 [(set_attr "type" "multi")
6850 (set_attr "length" "5")])
6852 (define_expand "clz<mode>2"
6853 [(set (match_operand:SIDI 0 "register_operand" "")
6854 (clz:SIDI (match_operand:SIDI 1 "register_operand" "")))]
6857 if (! TARGET_ARCH64)
6859 emit_insn (gen_clz<mode>_v8plus (operands[0], operands[1]));
6864 (define_insn "*clzdi_sp64"
6865 [(set (match_operand:DI 0 "register_operand" "=r")
6866 (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6867 "TARGET_VIS3 && TARGET_ARCH64"
6870 (define_insn "clzdi_v8plus"
6871 [(set (match_operand:DI 0 "register_operand" "=r")
6872 (clz:DI (match_operand:DI 1 "register_operand" "r")))
6873 (clobber (match_scratch:SI 2 "=&h"))]
6874 "TARGET_VIS3 && ! TARGET_ARCH64"
6876 if (sparc_check_64 (operands[1], insn) <= 0)
6877 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6878 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6880 [(set_attr "type" "multi")
6881 (set_attr "length" "5")])
6883 (define_insn "*clzsi_sp64"
6884 [(set (match_operand:SI 0 "register_operand" "=r")
6885 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6886 "TARGET_VIS3 && TARGET_ARCH64"
6887 "lzd\t%1, %0\n\tsub\t%0, 32, %0"
6888 [(set_attr "type" "multi")
6889 (set_attr "length" "2")])
6891 (define_insn "clzsi_v8plus"
6892 [(set (match_operand:SI 0 "register_operand" "=r")
6893 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6894 "TARGET_VIS3 && ! TARGET_ARCH64"
6896 if (sparc_check_64 (operands[1], insn) <= 0)
6897 output_asm_insn ("srl\t%1, 0, %1", operands);
6898 return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6900 [(set_attr "type" "multi")
6901 (set_attr "length" "3")])
6904 ;; Peepholes go at the end.
6906 ;; Optimize consecutive loads or stores into ldd and std when possible.
6907 ;; The conditions in which we do this are very restricted and are
6908 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6911 [(set (match_operand:SI 0 "memory_operand" "")
6913 (set (match_operand:SI 1 "memory_operand" "")
6916 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6919 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6922 [(set (match_operand:SI 0 "memory_operand" "")
6924 (set (match_operand:SI 1 "memory_operand" "")
6927 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6930 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6933 [(set (match_operand:SI 0 "register_operand" "")
6934 (match_operand:SI 1 "memory_operand" ""))
6935 (set (match_operand:SI 2 "register_operand" "")
6936 (match_operand:SI 3 "memory_operand" ""))]
6937 "registers_ok_for_ldd_peep (operands[0], operands[2])
6938 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6941 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6942 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6945 [(set (match_operand:SI 0 "memory_operand" "")
6946 (match_operand:SI 1 "register_operand" ""))
6947 (set (match_operand:SI 2 "memory_operand" "")
6948 (match_operand:SI 3 "register_operand" ""))]
6949 "registers_ok_for_ldd_peep (operands[1], operands[3])
6950 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6953 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6954 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6957 [(set (match_operand:SF 0 "register_operand" "")
6958 (match_operand:SF 1 "memory_operand" ""))
6959 (set (match_operand:SF 2 "register_operand" "")
6960 (match_operand:SF 3 "memory_operand" ""))]
6961 "registers_ok_for_ldd_peep (operands[0], operands[2])
6962 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6965 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6966 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6969 [(set (match_operand:SF 0 "memory_operand" "")
6970 (match_operand:SF 1 "register_operand" ""))
6971 (set (match_operand:SF 2 "memory_operand" "")
6972 (match_operand:SF 3 "register_operand" ""))]
6973 "registers_ok_for_ldd_peep (operands[1], operands[3])
6974 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6977 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6978 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6981 [(set (match_operand:SI 0 "register_operand" "")
6982 (match_operand:SI 1 "memory_operand" ""))
6983 (set (match_operand:SI 2 "register_operand" "")
6984 (match_operand:SI 3 "memory_operand" ""))]
6985 "registers_ok_for_ldd_peep (operands[2], operands[0])
6986 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6989 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6990 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6993 [(set (match_operand:SI 0 "memory_operand" "")
6994 (match_operand:SI 1 "register_operand" ""))
6995 (set (match_operand:SI 2 "memory_operand" "")
6996 (match_operand:SI 3 "register_operand" ""))]
6997 "registers_ok_for_ldd_peep (operands[3], operands[1])
6998 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7001 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7002 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7006 [(set (match_operand:SF 0 "register_operand" "")
7007 (match_operand:SF 1 "memory_operand" ""))
7008 (set (match_operand:SF 2 "register_operand" "")
7009 (match_operand:SF 3 "memory_operand" ""))]
7010 "registers_ok_for_ldd_peep (operands[2], operands[0])
7011 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7014 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7015 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7018 [(set (match_operand:SF 0 "memory_operand" "")
7019 (match_operand:SF 1 "register_operand" ""))
7020 (set (match_operand:SF 2 "memory_operand" "")
7021 (match_operand:SF 3 "register_operand" ""))]
7022 "registers_ok_for_ldd_peep (operands[3], operands[1])
7023 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7026 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7027 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7029 ;; Optimize the case of following a reg-reg move with a test
7030 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7031 ;; This can result from a float to fix conversion.
7034 [(set (match_operand:SI 0 "register_operand" "")
7035 (match_operand:SI 1 "register_operand" ""))
7036 (set (reg:CC CC_REG)
7037 (compare:CC (match_operand:SI 2 "register_operand" "")
7039 "(rtx_equal_p (operands[2], operands[0])
7040 || rtx_equal_p (operands[2], operands[1]))
7041 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7042 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7043 [(parallel [(set (match_dup 0) (match_dup 1))
7044 (set (reg:CC CC_REG)
7045 (compare:CC (match_dup 1) (const_int 0)))])]
7049 [(set (match_operand:DI 0 "register_operand" "")
7050 (match_operand:DI 1 "register_operand" ""))
7051 (set (reg:CCX CC_REG)
7052 (compare:CCX (match_operand:DI 2 "register_operand" "")
7055 && (rtx_equal_p (operands[2], operands[0])
7056 || rtx_equal_p (operands[2], operands[1]))
7057 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7058 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7059 [(parallel [(set (match_dup 0) (match_dup 1))
7060 (set (reg:CCX CC_REG)
7061 (compare:CCX (match_dup 1) (const_int 0)))])]
7065 ;; Prefetch instructions.
7067 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7068 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7069 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7071 (define_expand "prefetch"
7072 [(match_operand 0 "address_operand" "")
7073 (match_operand 1 "const_int_operand" "")
7074 (match_operand 2 "const_int_operand" "")]
7078 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7080 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7084 (define_insn "prefetch_64"
7085 [(prefetch (match_operand:DI 0 "address_operand" "p")
7086 (match_operand:DI 1 "const_int_operand" "n")
7087 (match_operand:DI 2 "const_int_operand" "n"))]
7090 static const char * const prefetch_instr[2][2] = {
7092 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7093 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7096 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7097 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7100 int read_or_write = INTVAL (operands[1]);
7101 int locality = INTVAL (operands[2]);
7103 gcc_assert (read_or_write == 0 || read_or_write == 1);
7104 gcc_assert (locality >= 0 && locality < 4);
7105 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7107 [(set_attr "type" "load")])
7109 (define_insn "prefetch_32"
7110 [(prefetch (match_operand:SI 0 "address_operand" "p")
7111 (match_operand:SI 1 "const_int_operand" "n")
7112 (match_operand:SI 2 "const_int_operand" "n"))]
7115 static const char * const prefetch_instr[2][2] = {
7117 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7118 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7121 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7122 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7125 int read_or_write = INTVAL (operands[1]);
7126 int locality = INTVAL (operands[2]);
7128 gcc_assert (read_or_write == 0 || read_or_write == 1);
7129 gcc_assert (locality >= 0 && locality < 4);
7130 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7132 [(set_attr "type" "load")])
7135 ;; Trap instructions.
7138 [(trap_if (const_int 1) (const_int 5))]
7141 [(set_attr "type" "trap")])
7143 (define_expand "ctrapsi4"
7144 [(trap_if (match_operator 0 "noov_compare_operator"
7145 [(match_operand:SI 1 "compare_operand" "")
7146 (match_operand:SI 2 "arith_operand" "")])
7147 (match_operand 3 ""))]
7149 "operands[1] = gen_compare_reg (operands[0]);
7150 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7152 operands[2] = const0_rtx;")
7154 (define_expand "ctrapdi4"
7155 [(trap_if (match_operator 0 "noov_compare_operator"
7156 [(match_operand:DI 1 "compare_operand" "")
7157 (match_operand:DI 2 "arith_operand" "")])
7158 (match_operand 3 ""))]
7160 "operands[1] = gen_compare_reg (operands[0]);
7161 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7163 operands[2] = const0_rtx;")
7167 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7168 (match_operand:SI 1 "arith_operand" "rM"))]
7172 return "t%C0\t%%icc, %1";
7176 [(set_attr "type" "trap")])
7179 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7180 (match_operand:SI 1 "arith_operand" "rM"))]
7183 [(set_attr "type" "trap")])
7186 ;; TLS support instructions.
7188 (define_insn "tgd_hi22"
7189 [(set (match_operand:SI 0 "register_operand" "=r")
7190 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7193 "sethi\\t%%tgd_hi22(%a1), %0")
7195 (define_insn "tgd_lo10"
7196 [(set (match_operand:SI 0 "register_operand" "=r")
7197 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7198 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7201 "add\\t%1, %%tgd_lo10(%a2), %0")
7203 (define_insn "tgd_add32"
7204 [(set (match_operand:SI 0 "register_operand" "=r")
7205 (plus:SI (match_operand:SI 1 "register_operand" "r")
7206 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7207 (match_operand 3 "tgd_symbolic_operand" "")]
7209 "TARGET_TLS && TARGET_ARCH32"
7210 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7212 (define_insn "tgd_add64"
7213 [(set (match_operand:DI 0 "register_operand" "=r")
7214 (plus:DI (match_operand:DI 1 "register_operand" "r")
7215 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7216 (match_operand 3 "tgd_symbolic_operand" "")]
7218 "TARGET_TLS && TARGET_ARCH64"
7219 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7221 (define_insn "tgd_call32"
7222 [(set (match_operand 0 "register_operand" "=r")
7223 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7224 (match_operand 2 "tgd_symbolic_operand" "")]
7226 (match_operand 3 "" "")))
7227 (clobber (reg:SI O7_REG))]
7228 "TARGET_TLS && TARGET_ARCH32"
7229 "call\t%a1, %%tgd_call(%a2)%#"
7230 [(set_attr "type" "call")])
7232 (define_insn "tgd_call64"
7233 [(set (match_operand 0 "register_operand" "=r")
7234 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7235 (match_operand 2 "tgd_symbolic_operand" "")]
7237 (match_operand 3 "" "")))
7238 (clobber (reg:DI O7_REG))]
7239 "TARGET_TLS && TARGET_ARCH64"
7240 "call\t%a1, %%tgd_call(%a2)%#"
7241 [(set_attr "type" "call")])
7243 (define_insn "tldm_hi22"
7244 [(set (match_operand:SI 0 "register_operand" "=r")
7245 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7247 "sethi\\t%%tldm_hi22(%&), %0")
7249 (define_insn "tldm_lo10"
7250 [(set (match_operand:SI 0 "register_operand" "=r")
7251 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7252 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7254 "add\\t%1, %%tldm_lo10(%&), %0")
7256 (define_insn "tldm_add32"
7257 [(set (match_operand:SI 0 "register_operand" "=r")
7258 (plus:SI (match_operand:SI 1 "register_operand" "r")
7259 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7261 "TARGET_TLS && TARGET_ARCH32"
7262 "add\\t%1, %2, %0, %%tldm_add(%&)")
7264 (define_insn "tldm_add64"
7265 [(set (match_operand:DI 0 "register_operand" "=r")
7266 (plus:DI (match_operand:DI 1 "register_operand" "r")
7267 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7269 "TARGET_TLS && TARGET_ARCH64"
7270 "add\\t%1, %2, %0, %%tldm_add(%&)")
7272 (define_insn "tldm_call32"
7273 [(set (match_operand 0 "register_operand" "=r")
7274 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7276 (match_operand 2 "" "")))
7277 (clobber (reg:SI O7_REG))]
7278 "TARGET_TLS && TARGET_ARCH32"
7279 "call\t%a1, %%tldm_call(%&)%#"
7280 [(set_attr "type" "call")])
7282 (define_insn "tldm_call64"
7283 [(set (match_operand 0 "register_operand" "=r")
7284 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7286 (match_operand 2 "" "")))
7287 (clobber (reg:DI O7_REG))]
7288 "TARGET_TLS && TARGET_ARCH64"
7289 "call\t%a1, %%tldm_call(%&)%#"
7290 [(set_attr "type" "call")])
7292 (define_insn "tldo_hix22"
7293 [(set (match_operand:SI 0 "register_operand" "=r")
7294 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7297 "sethi\\t%%tldo_hix22(%a1), %0")
7299 (define_insn "tldo_lox10"
7300 [(set (match_operand:SI 0 "register_operand" "=r")
7301 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7302 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7305 "xor\\t%1, %%tldo_lox10(%a2), %0")
7307 (define_insn "tldo_add32"
7308 [(set (match_operand:SI 0 "register_operand" "=r")
7309 (plus:SI (match_operand:SI 1 "register_operand" "r")
7310 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7311 (match_operand 3 "tld_symbolic_operand" "")]
7313 "TARGET_TLS && TARGET_ARCH32"
7314 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7316 (define_insn "tldo_add64"
7317 [(set (match_operand:DI 0 "register_operand" "=r")
7318 (plus:DI (match_operand:DI 1 "register_operand" "r")
7319 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7320 (match_operand 3 "tld_symbolic_operand" "")]
7322 "TARGET_TLS && TARGET_ARCH64"
7323 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7325 (define_insn "tie_hi22"
7326 [(set (match_operand:SI 0 "register_operand" "=r")
7327 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7330 "sethi\\t%%tie_hi22(%a1), %0")
7332 (define_insn "tie_lo10"
7333 [(set (match_operand:SI 0 "register_operand" "=r")
7334 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7335 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7338 "add\\t%1, %%tie_lo10(%a2), %0")
7340 (define_insn "tie_ld32"
7341 [(set (match_operand:SI 0 "register_operand" "=r")
7342 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7343 (match_operand:SI 2 "register_operand" "r")
7344 (match_operand 3 "tie_symbolic_operand" "")]
7346 "TARGET_TLS && TARGET_ARCH32"
7347 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7348 [(set_attr "type" "load")])
7350 (define_insn "tie_ld64"
7351 [(set (match_operand:DI 0 "register_operand" "=r")
7352 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7353 (match_operand:SI 2 "register_operand" "r")
7354 (match_operand 3 "tie_symbolic_operand" "")]
7356 "TARGET_TLS && TARGET_ARCH64"
7357 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7358 [(set_attr "type" "load")])
7360 (define_insn "tie_add32"
7361 [(set (match_operand:SI 0 "register_operand" "=r")
7362 (plus:SI (match_operand:SI 1 "register_operand" "r")
7363 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7364 (match_operand 3 "tie_symbolic_operand" "")]
7366 "TARGET_SUN_TLS && TARGET_ARCH32"
7367 "add\\t%1, %2, %0, %%tie_add(%a3)")
7369 (define_insn "tie_add64"
7370 [(set (match_operand:DI 0 "register_operand" "=r")
7371 (plus:DI (match_operand:DI 1 "register_operand" "r")
7372 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7373 (match_operand 3 "tie_symbolic_operand" "")]
7375 "TARGET_SUN_TLS && TARGET_ARCH64"
7376 "add\\t%1, %2, %0, %%tie_add(%a3)")
7378 (define_insn "tle_hix22_sp32"
7379 [(set (match_operand:SI 0 "register_operand" "=r")
7380 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7382 "TARGET_TLS && TARGET_ARCH32"
7383 "sethi\\t%%tle_hix22(%a1), %0")
7385 (define_insn "tle_lox10_sp32"
7386 [(set (match_operand:SI 0 "register_operand" "=r")
7387 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7388 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7390 "TARGET_TLS && TARGET_ARCH32"
7391 "xor\\t%1, %%tle_lox10(%a2), %0")
7393 (define_insn "tle_hix22_sp64"
7394 [(set (match_operand:DI 0 "register_operand" "=r")
7395 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7397 "TARGET_TLS && TARGET_ARCH64"
7398 "sethi\\t%%tle_hix22(%a1), %0")
7400 (define_insn "tle_lox10_sp64"
7401 [(set (match_operand:DI 0 "register_operand" "=r")
7402 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7403 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7405 "TARGET_TLS && TARGET_ARCH64"
7406 "xor\\t%1, %%tle_lox10(%a2), %0")
7408 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7409 (define_insn "*tldo_ldub_sp32"
7410 [(set (match_operand:QI 0 "register_operand" "=r")
7411 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7412 (match_operand 3 "tld_symbolic_operand" "")]
7414 (match_operand:SI 1 "register_operand" "r"))))]
7415 "TARGET_TLS && TARGET_ARCH32"
7416 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7417 [(set_attr "type" "load")
7418 (set_attr "us3load_type" "3cycle")])
7420 (define_insn "*tldo_ldub1_sp32"
7421 [(set (match_operand:HI 0 "register_operand" "=r")
7422 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7423 (match_operand 3 "tld_symbolic_operand" "")]
7425 (match_operand:SI 1 "register_operand" "r")))))]
7426 "TARGET_TLS && TARGET_ARCH32"
7427 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7428 [(set_attr "type" "load")
7429 (set_attr "us3load_type" "3cycle")])
7431 (define_insn "*tldo_ldub2_sp32"
7432 [(set (match_operand:SI 0 "register_operand" "=r")
7433 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7434 (match_operand 3 "tld_symbolic_operand" "")]
7436 (match_operand:SI 1 "register_operand" "r")))))]
7437 "TARGET_TLS && TARGET_ARCH32"
7438 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7439 [(set_attr "type" "load")
7440 (set_attr "us3load_type" "3cycle")])
7442 (define_insn "*tldo_ldsb1_sp32"
7443 [(set (match_operand:HI 0 "register_operand" "=r")
7444 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7445 (match_operand 3 "tld_symbolic_operand" "")]
7447 (match_operand:SI 1 "register_operand" "r")))))]
7448 "TARGET_TLS && TARGET_ARCH32"
7449 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7450 [(set_attr "type" "sload")
7451 (set_attr "us3load_type" "3cycle")])
7453 (define_insn "*tldo_ldsb2_sp32"
7454 [(set (match_operand:SI 0 "register_operand" "=r")
7455 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7456 (match_operand 3 "tld_symbolic_operand" "")]
7458 (match_operand:SI 1 "register_operand" "r")))))]
7459 "TARGET_TLS && TARGET_ARCH32"
7460 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7461 [(set_attr "type" "sload")
7462 (set_attr "us3load_type" "3cycle")])
7464 (define_insn "*tldo_ldub_sp64"
7465 [(set (match_operand:QI 0 "register_operand" "=r")
7466 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7467 (match_operand 3 "tld_symbolic_operand" "")]
7469 (match_operand:DI 1 "register_operand" "r"))))]
7470 "TARGET_TLS && TARGET_ARCH64"
7471 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7472 [(set_attr "type" "load")
7473 (set_attr "us3load_type" "3cycle")])
7475 (define_insn "*tldo_ldub1_sp64"
7476 [(set (match_operand:HI 0 "register_operand" "=r")
7477 (zero_extend:HI (mem:QI (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 "TARGET_TLS && TARGET_ARCH64"
7482 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7483 [(set_attr "type" "load")
7484 (set_attr "us3load_type" "3cycle")])
7486 (define_insn "*tldo_ldub2_sp64"
7487 [(set (match_operand:SI 0 "register_operand" "=r")
7488 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7489 (match_operand 3 "tld_symbolic_operand" "")]
7491 (match_operand:DI 1 "register_operand" "r")))))]
7492 "TARGET_TLS && TARGET_ARCH64"
7493 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7494 [(set_attr "type" "load")
7495 (set_attr "us3load_type" "3cycle")])
7497 (define_insn "*tldo_ldub3_sp64"
7498 [(set (match_operand:DI 0 "register_operand" "=r")
7499 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7500 (match_operand 3 "tld_symbolic_operand" "")]
7502 (match_operand:DI 1 "register_operand" "r")))))]
7503 "TARGET_TLS && TARGET_ARCH64"
7504 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7505 [(set_attr "type" "load")
7506 (set_attr "us3load_type" "3cycle")])
7508 (define_insn "*tldo_ldsb1_sp64"
7509 [(set (match_operand:HI 0 "register_operand" "=r")
7510 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7511 (match_operand 3 "tld_symbolic_operand" "")]
7513 (match_operand:DI 1 "register_operand" "r")))))]
7514 "TARGET_TLS && TARGET_ARCH64"
7515 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7516 [(set_attr "type" "sload")
7517 (set_attr "us3load_type" "3cycle")])
7519 (define_insn "*tldo_ldsb2_sp64"
7520 [(set (match_operand:SI 0 "register_operand" "=r")
7521 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7522 (match_operand 3 "tld_symbolic_operand" "")]
7524 (match_operand:DI 1 "register_operand" "r")))))]
7525 "TARGET_TLS && TARGET_ARCH64"
7526 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7527 [(set_attr "type" "sload")
7528 (set_attr "us3load_type" "3cycle")])
7530 (define_insn "*tldo_ldsb3_sp64"
7531 [(set (match_operand:DI 0 "register_operand" "=r")
7532 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7533 (match_operand 3 "tld_symbolic_operand" "")]
7535 (match_operand:DI 1 "register_operand" "r")))))]
7536 "TARGET_TLS && TARGET_ARCH64"
7537 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7538 [(set_attr "type" "sload")
7539 (set_attr "us3load_type" "3cycle")])
7541 (define_insn "*tldo_lduh_sp32"
7542 [(set (match_operand:HI 0 "register_operand" "=r")
7543 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7544 (match_operand 3 "tld_symbolic_operand" "")]
7546 (match_operand:SI 1 "register_operand" "r"))))]
7547 "TARGET_TLS && TARGET_ARCH32"
7548 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7549 [(set_attr "type" "load")
7550 (set_attr "us3load_type" "3cycle")])
7552 (define_insn "*tldo_lduh1_sp32"
7553 [(set (match_operand:SI 0 "register_operand" "=r")
7554 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7555 (match_operand 3 "tld_symbolic_operand" "")]
7557 (match_operand:SI 1 "register_operand" "r")))))]
7558 "TARGET_TLS && TARGET_ARCH32"
7559 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7560 [(set_attr "type" "load")
7561 (set_attr "us3load_type" "3cycle")])
7563 (define_insn "*tldo_ldsh1_sp32"
7564 [(set (match_operand:SI 0 "register_operand" "=r")
7565 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7566 (match_operand 3 "tld_symbolic_operand" "")]
7568 (match_operand:SI 1 "register_operand" "r")))))]
7569 "TARGET_TLS && TARGET_ARCH32"
7570 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7571 [(set_attr "type" "sload")
7572 (set_attr "us3load_type" "3cycle")])
7574 (define_insn "*tldo_lduh_sp64"
7575 [(set (match_operand:HI 0 "register_operand" "=r")
7576 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7577 (match_operand 3 "tld_symbolic_operand" "")]
7579 (match_operand:DI 1 "register_operand" "r"))))]
7580 "TARGET_TLS && TARGET_ARCH64"
7581 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7582 [(set_attr "type" "load")
7583 (set_attr "us3load_type" "3cycle")])
7585 (define_insn "*tldo_lduh1_sp64"
7586 [(set (match_operand:SI 0 "register_operand" "=r")
7587 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7588 (match_operand 3 "tld_symbolic_operand" "")]
7590 (match_operand:DI 1 "register_operand" "r")))))]
7591 "TARGET_TLS && TARGET_ARCH64"
7592 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7593 [(set_attr "type" "load")
7594 (set_attr "us3load_type" "3cycle")])
7596 (define_insn "*tldo_lduh2_sp64"
7597 [(set (match_operand:DI 0 "register_operand" "=r")
7598 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7599 (match_operand 3 "tld_symbolic_operand" "")]
7601 (match_operand:DI 1 "register_operand" "r")))))]
7602 "TARGET_TLS && TARGET_ARCH64"
7603 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7604 [(set_attr "type" "load")
7605 (set_attr "us3load_type" "3cycle")])
7607 (define_insn "*tldo_ldsh1_sp64"
7608 [(set (match_operand:SI 0 "register_operand" "=r")
7609 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7610 (match_operand 3 "tld_symbolic_operand" "")]
7612 (match_operand:DI 1 "register_operand" "r")))))]
7613 "TARGET_TLS && TARGET_ARCH64"
7614 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7615 [(set_attr "type" "sload")
7616 (set_attr "us3load_type" "3cycle")])
7618 (define_insn "*tldo_ldsh2_sp64"
7619 [(set (match_operand:DI 0 "register_operand" "=r")
7620 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7621 (match_operand 3 "tld_symbolic_operand" "")]
7623 (match_operand:DI 1 "register_operand" "r")))))]
7624 "TARGET_TLS && TARGET_ARCH64"
7625 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7626 [(set_attr "type" "sload")
7627 (set_attr "us3load_type" "3cycle")])
7629 (define_insn "*tldo_lduw_sp32"
7630 [(set (match_operand:SI 0 "register_operand" "=r")
7631 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7632 (match_operand 3 "tld_symbolic_operand" "")]
7634 (match_operand:SI 1 "register_operand" "r"))))]
7635 "TARGET_TLS && TARGET_ARCH32"
7636 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7637 [(set_attr "type" "load")])
7639 (define_insn "*tldo_lduw_sp64"
7640 [(set (match_operand:SI 0 "register_operand" "=r")
7641 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7642 (match_operand 3 "tld_symbolic_operand" "")]
7644 (match_operand:DI 1 "register_operand" "r"))))]
7645 "TARGET_TLS && TARGET_ARCH64"
7646 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7647 [(set_attr "type" "load")])
7649 (define_insn "*tldo_lduw1_sp64"
7650 [(set (match_operand:DI 0 "register_operand" "=r")
7651 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7652 (match_operand 3 "tld_symbolic_operand" "")]
7654 (match_operand:DI 1 "register_operand" "r")))))]
7655 "TARGET_TLS && TARGET_ARCH64"
7656 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7657 [(set_attr "type" "load")])
7659 (define_insn "*tldo_ldsw1_sp64"
7660 [(set (match_operand:DI 0 "register_operand" "=r")
7661 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7662 (match_operand 3 "tld_symbolic_operand" "")]
7664 (match_operand:DI 1 "register_operand" "r")))))]
7665 "TARGET_TLS && TARGET_ARCH64"
7666 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7667 [(set_attr "type" "sload")
7668 (set_attr "us3load_type" "3cycle")])
7670 (define_insn "*tldo_ldx_sp64"
7671 [(set (match_operand:DI 0 "register_operand" "=r")
7672 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7673 (match_operand 3 "tld_symbolic_operand" "")]
7675 (match_operand:DI 1 "register_operand" "r"))))]
7676 "TARGET_TLS && TARGET_ARCH64"
7677 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7678 [(set_attr "type" "load")])
7680 (define_insn "*tldo_stb_sp32"
7681 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7682 (match_operand 3 "tld_symbolic_operand" "")]
7684 (match_operand:SI 1 "register_operand" "r")))
7685 (match_operand:QI 0 "register_operand" "=r"))]
7686 "TARGET_TLS && TARGET_ARCH32"
7687 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7688 [(set_attr "type" "store")])
7690 (define_insn "*tldo_stb_sp64"
7691 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7692 (match_operand 3 "tld_symbolic_operand" "")]
7694 (match_operand:DI 1 "register_operand" "r")))
7695 (match_operand:QI 0 "register_operand" "=r"))]
7696 "TARGET_TLS && TARGET_ARCH64"
7697 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7698 [(set_attr "type" "store")])
7700 (define_insn "*tldo_sth_sp32"
7701 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7702 (match_operand 3 "tld_symbolic_operand" "")]
7704 (match_operand:SI 1 "register_operand" "r")))
7705 (match_operand:HI 0 "register_operand" "=r"))]
7706 "TARGET_TLS && TARGET_ARCH32"
7707 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7708 [(set_attr "type" "store")])
7710 (define_insn "*tldo_sth_sp64"
7711 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7712 (match_operand 3 "tld_symbolic_operand" "")]
7714 (match_operand:DI 1 "register_operand" "r")))
7715 (match_operand:HI 0 "register_operand" "=r"))]
7716 "TARGET_TLS && TARGET_ARCH64"
7717 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7718 [(set_attr "type" "store")])
7720 (define_insn "*tldo_stw_sp32"
7721 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7722 (match_operand 3 "tld_symbolic_operand" "")]
7724 (match_operand:SI 1 "register_operand" "r")))
7725 (match_operand:SI 0 "register_operand" "=r"))]
7726 "TARGET_TLS && TARGET_ARCH32"
7727 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7728 [(set_attr "type" "store")])
7730 (define_insn "*tldo_stw_sp64"
7731 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7732 (match_operand 3 "tld_symbolic_operand" "")]
7734 (match_operand:DI 1 "register_operand" "r")))
7735 (match_operand:SI 0 "register_operand" "=r"))]
7736 "TARGET_TLS && TARGET_ARCH64"
7737 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7738 [(set_attr "type" "store")])
7740 (define_insn "*tldo_stx_sp64"
7741 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7742 (match_operand 3 "tld_symbolic_operand" "")]
7744 (match_operand:DI 1 "register_operand" "r")))
7745 (match_operand:DI 0 "register_operand" "=r"))]
7746 "TARGET_TLS && TARGET_ARCH64"
7747 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7748 [(set_attr "type" "store")])
7751 ;; Stack protector instructions.
7753 (define_expand "stack_protect_set"
7754 [(match_operand 0 "memory_operand" "")
7755 (match_operand 1 "memory_operand" "")]
7758 #ifdef TARGET_THREAD_SSP_OFFSET
7759 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7760 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7761 operands[1] = gen_rtx_MEM (Pmode, addr);
7764 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7766 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7770 (define_insn "stack_protect_setsi"
7771 [(set (match_operand:SI 0 "memory_operand" "=m")
7772 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7773 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7775 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7776 [(set_attr "type" "multi")
7777 (set_attr "length" "3")])
7779 (define_insn "stack_protect_setdi"
7780 [(set (match_operand:DI 0 "memory_operand" "=m")
7781 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7782 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7784 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7785 [(set_attr "type" "multi")
7786 (set_attr "length" "3")])
7788 (define_expand "stack_protect_test"
7789 [(match_operand 0 "memory_operand" "")
7790 (match_operand 1 "memory_operand" "")
7791 (match_operand 2 "" "")]
7795 #ifdef TARGET_THREAD_SSP_OFFSET
7796 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7797 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7798 operands[1] = gen_rtx_MEM (Pmode, addr);
7802 result = gen_reg_rtx (Pmode);
7803 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7804 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7805 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7809 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7810 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7811 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7812 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7817 (define_insn "stack_protect_testsi"
7818 [(set (reg:CC CC_REG)
7819 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7820 (match_operand:SI 1 "memory_operand" "m")]
7822 (set (match_scratch:SI 3 "=r") (const_int 0))
7823 (clobber (match_scratch:SI 2 "=&r"))]
7825 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7826 [(set_attr "type" "multi")
7827 (set_attr "length" "4")])
7829 (define_insn "stack_protect_testdi"
7830 [(set (match_operand:DI 0 "register_operand" "=&r")
7831 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7832 (match_operand:DI 2 "memory_operand" "m")]
7834 (set (match_scratch:DI 3 "=r") (const_int 0))]
7836 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7837 [(set_attr "type" "multi")
7838 (set_attr "length" "4")])
7841 ;; Vector instructions.
7843 (define_insn "addv2si3"
7844 [(set (match_operand:V2SI 0 "register_operand" "=e")
7845 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7846 (match_operand:V2SI 2 "register_operand" "e")))]
7848 "fpadd32\t%1, %2, %0"
7849 [(set_attr "type" "fga")
7850 (set_attr "fptype" "double")])
7852 (define_insn "addv4hi3"
7853 [(set (match_operand:V4HI 0 "register_operand" "=e")
7854 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7855 (match_operand:V4HI 2 "register_operand" "e")))]
7857 "fpadd16\t%1, %2, %0"
7858 [(set_attr "type" "fga")
7859 (set_attr "fptype" "double")])
7861 ;; fpadd32s is emitted by the addsi3 pattern.
7863 (define_insn "addv2hi3"
7864 [(set (match_operand:V2HI 0 "register_operand" "=f")
7865 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7866 (match_operand:V2HI 2 "register_operand" "f")))]
7868 "fpadd16s\t%1, %2, %0"
7869 [(set_attr "type" "fga")
7870 (set_attr "fptype" "single")])
7872 (define_insn "subv2si3"
7873 [(set (match_operand:V2SI 0 "register_operand" "=e")
7874 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7875 (match_operand:V2SI 2 "register_operand" "e")))]
7877 "fpsub32\t%1, %2, %0"
7878 [(set_attr "type" "fga")
7879 (set_attr "fptype" "double")])
7881 (define_insn "subv4hi3"
7882 [(set (match_operand:V4HI 0 "register_operand" "=e")
7883 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7884 (match_operand:V4HI 2 "register_operand" "e")))]
7886 "fpsub16\t%1, %2, %0"
7887 [(set_attr "type" "fga")
7888 (set_attr "fptype" "double")])
7890 ;; fpsub32s is emitted by the subsi3 pattern.
7892 (define_insn "subv2hi3"
7893 [(set (match_operand:V2HI 0 "register_operand" "=f")
7894 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7895 (match_operand:V2HI 2 "register_operand" "f")))]
7897 "fpsub16s\t%1, %2, %0"
7898 [(set_attr "type" "fga")
7899 (set_attr "fptype" "single")])
7901 ;; All other logical instructions have integer equivalents so they
7902 ;; are defined together.
7904 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7906 (define_insn "*nand<V64:mode>_vis"
7907 [(set (match_operand:V64 0 "register_operand" "=e")
7908 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7909 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7912 [(set_attr "type" "fga")
7913 (set_attr "fptype" "double")])
7915 (define_insn "*nand<V32:mode>_vis"
7916 [(set (match_operand:V32 0 "register_operand" "=f")
7917 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7918 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7920 "fnands\t%1, %2, %0"
7921 [(set_attr "type" "fga")
7922 (set_attr "fptype" "single")])
7924 ;; Hard to generate VIS instructions. We have builtins for these.
7926 (define_insn "fpack16_vis"
7927 [(set (match_operand:V4QI 0 "register_operand" "=f")
7928 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
7933 [(set_attr "type" "fga")
7934 (set_attr "fptype" "double")])
7936 (define_insn "fpackfix_vis"
7937 [(set (match_operand:V2HI 0 "register_operand" "=f")
7938 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
7943 [(set_attr "type" "fga")
7944 (set_attr "fptype" "double")])
7946 (define_insn "fpack32_vis"
7947 [(set (match_operand:V8QI 0 "register_operand" "=e")
7948 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7949 (match_operand:V8QI 2 "register_operand" "e")
7953 "fpack32\t%1, %2, %0"
7954 [(set_attr "type" "fga")
7955 (set_attr "fptype" "double")])
7957 (define_insn "fexpand_vis"
7958 [(set (match_operand:V4HI 0 "register_operand" "=e")
7959 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7963 [(set_attr "type" "fga")
7964 (set_attr "fptype" "double")])
7966 ;; It may be possible to describe this operation as (1 indexed):
7967 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7968 ;; 1,5,10,14,19,23,28,32)
7969 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7970 ;; because vec_merge expects all the operands to be of the same type.
7971 (define_insn "fpmerge_vis"
7972 [(set (match_operand:V8QI 0 "register_operand" "=e")
7973 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7974 (match_operand:V4QI 2 "register_operand" "f")]
7977 "fpmerge\t%1, %2, %0"
7978 [(set_attr "type" "fga")
7979 (set_attr "fptype" "double")])
7981 ;; Partitioned multiply instructions
7982 (define_insn "fmul8x16_vis"
7983 [(set (match_operand:V4HI 0 "register_operand" "=e")
7984 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7985 (match_operand:V4HI 2 "register_operand" "e")))]
7987 "fmul8x16\t%1, %2, %0"
7988 [(set_attr "type" "fpmul")
7989 (set_attr "fptype" "double")])
7991 ;; Only one of the following two insns can be a multiply.
7992 (define_insn "fmul8x16au_vis"
7993 [(set (match_operand:V4HI 0 "register_operand" "=e")
7994 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7995 (match_operand:V2HI 2 "register_operand" "f")))]
7997 "fmul8x16au\t%1, %2, %0"
7998 [(set_attr "type" "fpmul")
7999 (set_attr "fptype" "double")])
8001 (define_insn "fmul8x16al_vis"
8002 [(set (match_operand:V4HI 0 "register_operand" "=e")
8003 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8004 (match_operand:V2HI 2 "register_operand" "f")]
8007 "fmul8x16al\t%1, %2, %0"
8008 [(set_attr "type" "fpmul")
8009 (set_attr "fptype" "double")])
8011 ;; Only one of the following two insns can be a multiply.
8012 (define_insn "fmul8sux16_vis"
8013 [(set (match_operand:V4HI 0 "register_operand" "=e")
8014 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8015 (match_operand:V4HI 2 "register_operand" "e")))]
8017 "fmul8sux16\t%1, %2, %0"
8018 [(set_attr "type" "fpmul")
8019 (set_attr "fptype" "double")])
8021 (define_insn "fmul8ulx16_vis"
8022 [(set (match_operand:V4HI 0 "register_operand" "=e")
8023 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8024 (match_operand:V4HI 2 "register_operand" "e")]
8027 "fmul8ulx16\t%1, %2, %0"
8028 [(set_attr "type" "fpmul")
8029 (set_attr "fptype" "double")])
8031 ;; Only one of the following two insns can be a multiply.
8032 (define_insn "fmuld8sux16_vis"
8033 [(set (match_operand:V2SI 0 "register_operand" "=e")
8034 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8035 (match_operand:V2HI 2 "register_operand" "f")))]
8037 "fmuld8sux16\t%1, %2, %0"
8038 [(set_attr "type" "fpmul")
8039 (set_attr "fptype" "double")])
8041 (define_insn "fmuld8ulx16_vis"
8042 [(set (match_operand:V2SI 0 "register_operand" "=e")
8043 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8044 (match_operand:V2HI 2 "register_operand" "f")]
8047 "fmuld8ulx16\t%1, %2, %0"
8048 [(set_attr "type" "fpmul")
8049 (set_attr "fptype" "double")])
8051 (define_expand "wrgsr_vis"
8052 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8055 if (! TARGET_ARCH64)
8057 emit_insn (gen_wrgsr_v8plus (operands[0]));
8062 (define_insn "*wrgsr_sp64"
8063 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8064 "TARGET_VIS && TARGET_ARCH64"
8065 "wr\t%%g0, %0, %%gsr"
8066 [(set_attr "type" "gsr")])
8068 (define_insn "wrgsr_v8plus"
8069 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8070 (clobber (match_scratch:SI 1 "=X,&h"))]
8071 "TARGET_VIS && ! TARGET_ARCH64"
8073 if (GET_CODE (operands[0]) == CONST_INT
8074 || sparc_check_64 (operands[0], insn))
8075 return "wr\t%%g0, %0, %%gsr";
8077 output_asm_insn("srl\t%L0, 0, %L0", operands);
8078 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8080 [(set_attr "type" "multi")])
8082 (define_expand "rdgsr_vis"
8083 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8086 if (! TARGET_ARCH64)
8088 emit_insn (gen_rdgsr_v8plus (operands[0]));
8093 (define_insn "*rdgsr_sp64"
8094 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8095 "TARGET_VIS && TARGET_ARCH64"
8097 [(set_attr "type" "gsr")])
8099 (define_insn "rdgsr_v8plus"
8100 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8101 (clobber (match_scratch:SI 1 "=&h"))]
8102 "TARGET_VIS && ! TARGET_ARCH64"
8104 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8106 [(set_attr "type" "multi")])
8108 ;; Using faligndata only makes sense after an alignaddr since the choice of
8109 ;; bytes to take out of each operand is dependent on the results of the last
8111 (define_insn "faligndata<V64I:mode>_vis"
8112 [(set (match_operand:V64I 0 "register_operand" "=e")
8113 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8114 (match_operand:V64I 2 "register_operand" "e")
8118 "faligndata\t%1, %2, %0"
8119 [(set_attr "type" "fga")
8120 (set_attr "fptype" "double")])
8122 (define_insn "alignaddrsi_vis"
8123 [(set (match_operand:SI 0 "register_operand" "=r")
8124 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8125 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8126 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8127 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8129 "alignaddr\t%r1, %r2, %0")
8131 (define_insn "alignaddrdi_vis"
8132 [(set (match_operand:DI 0 "register_operand" "=r")
8133 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8134 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8135 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8136 (plus:DI (match_dup 1) (match_dup 2)))]
8138 "alignaddr\t%r1, %r2, %0")
8140 (define_insn "alignaddrlsi_vis"
8141 [(set (match_operand:SI 0 "register_operand" "=r")
8142 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8143 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8144 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8145 (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8148 "alignaddrl\t%r1, %r2, %0")
8150 (define_insn "alignaddrldi_vis"
8151 [(set (match_operand:DI 0 "register_operand" "=r")
8152 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8153 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8154 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8155 (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8158 "alignaddrl\t%r1, %r2, %0")
8160 (define_insn "pdist_vis"
8161 [(set (match_operand:DI 0 "register_operand" "=e")
8162 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8163 (match_operand:V8QI 2 "register_operand" "e")
8164 (match_operand:DI 3 "register_operand" "0")]
8168 [(set_attr "type" "fga")
8169 (set_attr "fptype" "double")])
8171 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8172 ;; with the same operands.
8173 (define_insn "edge8<P:mode>_vis"
8174 [(set (reg:CC_NOOV CC_REG)
8175 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8176 (match_operand:P 2 "register_operand" "rJ"))
8178 (set (match_operand:P 0 "register_operand" "=r")
8179 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8181 "edge8\t%r1, %r2, %0"
8182 [(set_attr "type" "edge")])
8184 (define_insn "edge8l<P:mode>_vis"
8185 [(set (reg:CC_NOOV CC_REG)
8186 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8187 (match_operand:P 2 "register_operand" "rJ"))
8189 (set (match_operand:P 0 "register_operand" "=r")
8190 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8192 "edge8l\t%r1, %r2, %0"
8193 [(set_attr "type" "edge")])
8195 (define_insn "edge16<P:mode>_vis"
8196 [(set (reg:CC_NOOV CC_REG)
8197 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8198 (match_operand:P 2 "register_operand" "rJ"))
8200 (set (match_operand:P 0 "register_operand" "=r")
8201 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8203 "edge16\t%r1, %r2, %0"
8204 [(set_attr "type" "edge")])
8206 (define_insn "edge16l<P:mode>_vis"
8207 [(set (reg:CC_NOOV CC_REG)
8208 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8209 (match_operand:P 2 "register_operand" "rJ"))
8211 (set (match_operand:P 0 "register_operand" "=r")
8212 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8214 "edge16l\t%r1, %r2, %0"
8215 [(set_attr "type" "edge")])
8217 (define_insn "edge32<P:mode>_vis"
8218 [(set (reg:CC_NOOV CC_REG)
8219 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8220 (match_operand:P 2 "register_operand" "rJ"))
8222 (set (match_operand:P 0 "register_operand" "=r")
8223 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8225 "edge32\t%r1, %r2, %0"
8226 [(set_attr "type" "edge")])
8228 (define_insn "edge32l<P:mode>_vis"
8229 [(set (reg:CC_NOOV CC_REG)
8230 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8231 (match_operand:P 2 "register_operand" "rJ"))
8233 (set (match_operand:P 0 "register_operand" "=r")
8234 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8236 "edge32l\t%r1, %r2, %0"
8237 [(set_attr "type" "edge")])
8239 (define_code_iterator gcond [le ne gt eq])
8240 (define_mode_iterator GCM [V4HI V2SI])
8241 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8243 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8244 [(set (match_operand:P 0 "register_operand" "=r")
8245 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8246 (match_operand:GCM 2 "register_operand" "e"))]
8249 "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8250 [(set_attr "type" "fpmul")
8251 (set_attr "fptype" "double")])
8253 (define_insn "array8<P:mode>_vis"
8254 [(set (match_operand:P 0 "register_operand" "=r")
8255 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8256 (match_operand:P 2 "register_operand" "rJ")]
8259 "array8\t%r1, %r2, %0"
8260 [(set_attr "type" "array")])
8262 (define_insn "array16<P:mode>_vis"
8263 [(set (match_operand:P 0 "register_operand" "=r")
8264 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8265 (match_operand:P 2 "register_operand" "rJ")]
8268 "array16\t%r1, %r2, %0"
8269 [(set_attr "type" "array")])
8271 (define_insn "array32<P:mode>_vis"
8272 [(set (match_operand:P 0 "register_operand" "=r")
8273 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8274 (match_operand:P 2 "register_operand" "rJ")]
8277 "array32\t%r1, %r2, %0"
8278 [(set_attr "type" "array")])
8280 (define_insn "bmaskdi_vis"
8281 [(set (match_operand:DI 0 "register_operand" "=r")
8282 (plus:DI (match_operand:DI 1 "register_operand" "rJ")
8283 (match_operand:DI 2 "register_operand" "rJ")))
8284 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8285 (plus:DI (match_dup 1) (match_dup 2)))]
8287 "bmask\t%r1, %r2, %0"
8288 [(set_attr "type" "array")])
8290 (define_insn "bmasksi_vis"
8291 [(set (match_operand:SI 0 "register_operand" "=r")
8292 (plus:SI (match_operand:SI 1 "register_operand" "rJ")
8293 (match_operand:SI 2 "register_operand" "rJ")))
8294 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8295 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8297 "bmask\t%r1, %r2, %0"
8298 [(set_attr "type" "array")])
8300 (define_insn "bshuffle<V64I:mode>_vis"
8301 [(set (match_operand:V64I 0 "register_operand" "=e")
8302 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8303 (match_operand:V64I 2 "register_operand" "e")
8307 "bshuffle\t%1, %2, %0"
8308 [(set_attr "type" "fga")
8309 (set_attr "fptype" "double")])
8311 ;; VIS 2.0 adds edge variants which do not set the condition codes
8312 (define_insn "edge8n<P:mode>_vis"
8313 [(set (match_operand:P 0 "register_operand" "=r")
8314 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8315 (match_operand:P 2 "register_operand" "rJ")]
8318 "edge8n\t%r1, %r2, %0"
8319 [(set_attr "type" "edgen")])
8321 (define_insn "edge8ln<P:mode>_vis"
8322 [(set (match_operand:P 0 "register_operand" "=r")
8323 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8324 (match_operand:P 2 "register_operand" "rJ")]
8327 "edge8ln\t%r1, %r2, %0"
8328 [(set_attr "type" "edgen")])
8330 (define_insn "edge16n<P:mode>_vis"
8331 [(set (match_operand:P 0 "register_operand" "=r")
8332 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8333 (match_operand:P 2 "register_operand" "rJ")]
8336 "edge16n\t%r1, %r2, %0"
8337 [(set_attr "type" "edgen")])
8339 (define_insn "edge16ln<P:mode>_vis"
8340 [(set (match_operand:P 0 "register_operand" "=r")
8341 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8342 (match_operand:P 2 "register_operand" "rJ")]
8345 "edge16ln\t%r1, %r2, %0"
8346 [(set_attr "type" "edgen")])
8348 (define_insn "edge32n<P:mode>_vis"
8349 [(set (match_operand:P 0 "register_operand" "=r")
8350 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8351 (match_operand:P 2 "register_operand" "rJ")]
8354 "edge32n\t%r1, %r2, %0"
8355 [(set_attr "type" "edgen")])
8357 (define_insn "edge32ln<P:mode>_vis"
8358 [(set (match_operand:P 0 "register_operand" "=r")
8359 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8360 (match_operand:P 2 "register_operand" "rJ")]
8363 "edge32ln\t%r1, %r2, %0"
8364 [(set_attr "type" "edge")])
8366 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8367 (define_insn "cmask8<P:mode>_vis"
8368 [(set (reg:DI GSR_REG)
8369 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8375 (define_insn "cmask16<P:mode>_vis"
8376 [(set (reg:DI GSR_REG)
8377 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8383 (define_insn "cmask32<P:mode>_vis"
8384 [(set (reg:DI GSR_REG)
8385 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8391 (define_insn "fchksm16_vis"
8392 [(set (match_operand:V4HI 0 "register_operand" "=e")
8393 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8394 (match_operand:V4HI 2 "register_operand" "e")]
8397 "fchksm16\t%1, %2, %0")
8399 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8400 (define_code_attr vis3_shift_insn
8401 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8403 (define_insn "<vis3_shift_insn><vbits>_vis"
8404 [(set (match_operand:V64N8 0 "register_operand" "=<vconstr>")
8405 (vis3_shift:V64N8 (match_operand:V64N8 1 "register_operand" "<vconstr>")
8406 (match_operand:V64N8 2 "register_operand" "<vconstr>")))]
8408 "<vis3_shift_insn><vbits>\t%1, %2, %0")
8410 (define_insn "pdistn<mode>_vis"
8411 [(set (match_operand:P 0 "register_operand" "=r")
8412 (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8413 (match_operand:V8QI 2 "register_operand" "e")]
8416 "pdistn\t%1, %2, %0")
8418 (define_insn "fmean16_vis"
8419 [(set (match_operand:V4HI 0 "register_operand" "=e")
8425 (match_operand:V4HI 1 "register_operand" "e"))
8427 (match_operand:V4HI 2 "register_operand" "e")))
8428 (const_vector:V4SI [(const_int 1) (const_int 1)
8429 (const_int 1) (const_int 1)]))
8432 "fmean16\t%1, %2, %0")
8434 (define_insn "fpadd64_vis"
8435 [(set (match_operand:DI 0 "register_operand" "=e")
8436 (plus:DI (match_operand:DI 1 "register_operand" "e")
8437 (match_operand:DI 2 "register_operand" "e")))]
8439 "fpadd64\t%1, %2, %0")
8441 (define_insn "fpsub64_vis"
8442 [(set (match_operand:DI 0 "register_operand" "=e")
8443 (minus:DI (match_operand:DI 1 "register_operand" "e")
8444 (match_operand:DI 2 "register_operand" "e")))]
8446 "fpsub64\t%1, %2, %0")
8448 (define_mode_iterator VASS [V4HI V2SI V2HI SI])
8449 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8450 (define_code_attr vis3_addsub_ss_insn
8451 [(ss_plus "fpadds") (ss_minus "fpsubs")])
8453 (define_insn "<vis3_addsub_ss_insn><vbits>_vis"
8454 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8455 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8456 (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8458 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0")
8460 (define_insn "fucmp<code>8<P:mode>_vis"
8461 [(set (match_operand:P 0 "register_operand" "=r")
8462 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8463 (match_operand:V8QI 2 "register_operand" "e"))]
8466 "fucmp<code>8\t%1, %2, %0")
8468 (define_insn "*naddsf3"
8469 [(set (match_operand:SF 0 "register_operand" "=f")
8470 (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8471 (match_operand:SF 2 "register_operand" "f"))))]
8473 "fnadds\t%1, %2, %0"
8474 [(set_attr "type" "fp")])
8476 (define_insn "*nadddf3"
8477 [(set (match_operand:DF 0 "register_operand" "=e")
8478 (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8479 (match_operand:DF 2 "register_operand" "e"))))]
8481 "fnaddd\t%1, %2, %0"
8482 [(set_attr "type" "fp")
8483 (set_attr "fptype" "double")])
8485 (define_insn "*nmulsf3"
8486 [(set (match_operand:SF 0 "register_operand" "=f")
8487 (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8488 (match_operand:SF 2 "register_operand" "f")))]
8490 "fnmuls\t%1, %2, %0"
8491 [(set_attr "type" "fpmul")])
8493 (define_insn "*nmuldf3"
8494 [(set (match_operand:DF 0 "register_operand" "=e")
8495 (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8496 (match_operand:DF 2 "register_operand" "e")))]
8498 "fnmuld\t%1, %2, %0"
8499 [(set_attr "type" "fpmul")
8500 (set_attr "fptype" "double")])
8502 (define_insn "*nmuldf3_extend"
8503 [(set (match_operand:DF 0 "register_operand" "=e")
8504 (mult:DF (neg:DF (float_extend:DF
8505 (match_operand:SF 1 "register_operand" "f")))
8507 (match_operand:SF 2 "register_operand" "f"))))]
8509 "fnsmuld\t%1, %2, %0"
8510 [(set_attr "type" "fpmul")
8511 (set_attr "fptype" "double")])
8513 (define_insn "fhaddsf_vis"
8514 [(set (match_operand:SF 0 "register_operand" "=f")
8515 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8516 (match_operand:SF 2 "register_operand" "f")]
8519 "fhadds\t%1, %2, %0"
8520 [(set_attr "type" "fp")])
8522 (define_insn "fhadddf_vis"
8523 [(set (match_operand:DF 0 "register_operand" "=f")
8524 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8525 (match_operand:DF 2 "register_operand" "f")]
8528 "fhaddd\t%1, %2, %0"
8529 [(set_attr "type" "fp")
8530 (set_attr "fptype" "double")])
8532 (define_insn "fhsubsf_vis"
8533 [(set (match_operand:SF 0 "register_operand" "=f")
8534 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8535 (match_operand:SF 2 "register_operand" "f")]
8538 "fhsubs\t%1, %2, %0"
8539 [(set_attr "type" "fp")])
8541 (define_insn "fhsubdf_vis"
8542 [(set (match_operand:DF 0 "register_operand" "=f")
8543 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8544 (match_operand:DF 2 "register_operand" "f")]
8547 "fhsubd\t%1, %2, %0"
8548 [(set_attr "type" "fp")
8549 (set_attr "fptype" "double")])
8551 (define_insn "fnhaddsf_vis"
8552 [(set (match_operand:SF 0 "register_operand" "=f")
8553 (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8554 (match_operand:SF 2 "register_operand" "f")]
8557 "fnhadds\t%1, %2, %0"
8558 [(set_attr "type" "fp")])
8560 (define_insn "fnhadddf_vis"
8561 [(set (match_operand:DF 0 "register_operand" "=f")
8562 (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8563 (match_operand:DF 2 "register_operand" "f")]
8566 "fnhaddd\t%1, %2, %0"
8567 [(set_attr "type" "fp")
8568 (set_attr "fptype" "double")])
8570 (define_expand "umulxhi_vis"
8571 [(set (match_operand:DI 0 "register_operand" "")
8574 (mult: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_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8588 (define_insn "*umulxhi_sp64"
8589 [(set (match_operand:DI 0 "register_operand" "=r")
8592 (mult:TI (zero_extend:TI
8593 (match_operand:DI 1 "arith_operand" "%r"))
8595 (match_operand:DI 2 "arith_operand" "rI")))
8597 "TARGET_VIS3 && TARGET_ARCH64"
8598 "umulxhi\t%1, %2, %0"
8599 [(set_attr "type" "imul")])
8601 (define_insn "umulxhi_v8plus"
8602 [(set (match_operand:DI 0 "register_operand" "=r,h")
8605 (mult:TI (zero_extend:TI
8606 (match_operand:DI 1 "arith_operand" "%r,0"))
8608 (match_operand:DI 2 "arith_operand" "rI,rI")))
8610 (clobber (match_scratch:SI 3 "=&h,X"))
8611 (clobber (match_scratch:SI 4 "=&h,X"))]
8612 "TARGET_VIS3 && ! TARGET_ARCH64"
8613 "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8614 [(set_attr "type" "imul")
8615 (set_attr "length" "9,8")])
8617 (define_expand "xmulx_vis"
8618 [(set (match_operand:DI 0 "register_operand" "")
8620 (unspec:TI [(zero_extend:TI
8621 (match_operand:DI 1 "arith_operand" ""))
8623 (match_operand:DI 2 "arith_operand" ""))]
8627 if (! TARGET_ARCH64)
8629 emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8634 (define_insn "*xmulx_sp64"
8635 [(set (match_operand:DI 0 "register_operand" "=r")
8637 (unspec:TI [(zero_extend:TI
8638 (match_operand:DI 1 "arith_operand" "%r"))
8640 (match_operand:DI 2 "arith_operand" "rI"))]
8642 "TARGET_VIS3 && TARGET_ARCH64"
8644 [(set_attr "type" "imul")])
8646 (define_insn "xmulx_v8plus"
8647 [(set (match_operand:DI 0 "register_operand" "=r,h")
8649 (unspec:TI [(zero_extend:TI
8650 (match_operand:DI 1 "arith_operand" "%r,0"))
8652 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8654 (clobber (match_scratch:SI 3 "=&h,X"))
8655 (clobber (match_scratch:SI 4 "=&h,X"))]
8656 "TARGET_VIS3 && ! TARGET_ARCH64"
8657 "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8658 [(set_attr "type" "imul")
8659 (set_attr "length" "9,8")])
8661 (define_expand "xmulxhi_vis"
8662 [(set (match_operand:DI 0 "register_operand" "")
8665 (unspec:TI [(zero_extend:TI
8666 (match_operand:DI 1 "arith_operand" ""))
8668 (match_operand:DI 2 "arith_operand" ""))]
8673 if (! TARGET_ARCH64)
8675 emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
8680 (define_insn "*xmulxhi_sp64"
8681 [(set (match_operand:DI 0 "register_operand" "=r")
8684 (unspec:TI [(zero_extend:TI
8685 (match_operand:DI 1 "arith_operand" "%r"))
8687 (match_operand:DI 2 "arith_operand" "rI"))]
8690 "TARGET_VIS3 && TARGET_ARCH64"
8691 "xmulxhi\t%1, %2, %0"
8692 [(set_attr "type" "imul")])
8694 (define_insn "xmulxhi_v8plus"
8695 [(set (match_operand:DI 0 "register_operand" "=r,h")
8698 (unspec:TI [(zero_extend:TI
8699 (match_operand:DI 1 "arith_operand" "%r,0"))
8701 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8704 (clobber (match_scratch:SI 3 "=&h,X"))
8705 (clobber (match_scratch:SI 4 "=&h,X"))]
8706 "TARGET_VIS3 && !TARGET_ARCH64"
8707 "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
8708 [(set_attr "type" "imul")
8709 (set_attr "length" "9,8")])