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 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
210 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
211 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
212 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
213 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
215 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (SI "32s") (V2HI "16s")])
216 (define_mode_attr vconstr [(V2SI "e") (V4HI "e") (SI "f") (V2HI "f")])
218 ;; Attribute for cpu type.
219 ;; These must match the values for enum processor_type in sparc.h.
240 (const (symbol_ref "sparc_cpu_attr")))
242 ;; Attribute for the instruction set.
243 ;; At present we only need to distinguish v9/!v9, but for clarity we
244 ;; test TARGET_V8 too.
245 (define_attr "isa" "v7,v8,v9,sparclet"
247 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
248 (symbol_ref "TARGET_V8") (const_string "v8")
249 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
250 (const_string "v7"))))
256 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
264 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,edgen,gsr,array,
267 multi,savew,flushw,iflush,trap"
268 (const_string "ialu"))
270 ;; True if branch/call has empty delay slot and will emit a nop in it
271 (define_attr "empty_delay_slot" "false,true"
272 (symbol_ref "(empty_delay_slot (insn)
273 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
275 (define_attr "branch_type" "none,icc,fcc,reg"
276 (const_string "none"))
278 (define_attr "pic" "false,true"
279 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
281 (define_attr "calls_alloca" "false,true"
282 (symbol_ref "(cfun->calls_alloca != 0
283 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
285 (define_attr "calls_eh_return" "false,true"
286 (symbol_ref "(crtl->calls_eh_return != 0
287 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
289 (define_attr "leaf_function" "false,true"
290 (symbol_ref "(current_function_uses_only_leaf_regs != 0
291 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
293 (define_attr "delayed_branch" "false,true"
294 (symbol_ref "(flag_delayed_branch != 0
295 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
297 (define_attr "flat" "false,true"
298 (symbol_ref "(TARGET_FLAT != 0
299 ? FLAT_TRUE : FLAT_FALSE)"))
301 ;; Length (in # of insns).
302 ;; Beware that setting a length greater or equal to 3 for conditional branches
303 ;; has a side-effect (see output_cbranch and output_v9branch).
304 (define_attr "length" ""
305 (cond [(eq_attr "type" "uncond_branch,call")
306 (if_then_else (eq_attr "empty_delay_slot" "true")
309 (eq_attr "type" "sibcall")
310 (if_then_else (eq_attr "leaf_function" "true")
311 (if_then_else (eq_attr "empty_delay_slot" "true")
314 (if_then_else (eq_attr "empty_delay_slot" "true")
317 (eq_attr "branch_type" "icc")
318 (if_then_else (match_operand 0 "noov_compare64_operator" "")
319 (if_then_else (lt (pc) (match_dup 1))
320 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
321 (if_then_else (eq_attr "empty_delay_slot" "true")
324 (if_then_else (eq_attr "empty_delay_slot" "true")
327 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
328 (if_then_else (eq_attr "empty_delay_slot" "true")
331 (if_then_else (eq_attr "empty_delay_slot" "true")
334 (if_then_else (eq_attr "empty_delay_slot" "true")
337 (eq_attr "branch_type" "fcc")
338 (if_then_else (match_operand 0 "fcc0_register_operand" "")
339 (if_then_else (eq_attr "empty_delay_slot" "true")
340 (if_then_else (not (match_test "TARGET_V9"))
343 (if_then_else (not (match_test "TARGET_V9"))
346 (if_then_else (lt (pc) (match_dup 2))
347 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
348 (if_then_else (eq_attr "empty_delay_slot" "true")
351 (if_then_else (eq_attr "empty_delay_slot" "true")
354 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
355 (if_then_else (eq_attr "empty_delay_slot" "true")
358 (if_then_else (eq_attr "empty_delay_slot" "true")
361 (eq_attr "branch_type" "reg")
362 (if_then_else (lt (pc) (match_dup 2))
363 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
364 (if_then_else (eq_attr "empty_delay_slot" "true")
367 (if_then_else (eq_attr "empty_delay_slot" "true")
370 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
371 (if_then_else (eq_attr "empty_delay_slot" "true")
374 (if_then_else (eq_attr "empty_delay_slot" "true")
380 (define_attr "fptype" "single,double"
381 (const_string "single"))
383 ;; UltraSPARC-III integer load type.
384 (define_attr "us3load_type" "2cycle,3cycle"
385 (const_string "2cycle"))
387 (define_asm_attributes
388 [(set_attr "length" "2")
389 (set_attr "type" "multi")])
391 ;; Attributes for instruction and branch scheduling
392 (define_attr "tls_call_delay" "false,true"
393 (symbol_ref "(tls_call_delay (insn)
394 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
396 (define_attr "in_call_delay" "false,true"
397 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
398 (const_string "false")
399 (eq_attr "type" "load,fpload,store,fpstore")
400 (if_then_else (eq_attr "length" "1")
401 (const_string "true")
402 (const_string "false"))]
403 (if_then_else (and (eq_attr "length" "1")
404 (eq_attr "tls_call_delay" "true"))
405 (const_string "true")
406 (const_string "false"))))
408 (define_attr "eligible_for_sibcall_delay" "false,true"
409 (symbol_ref "(eligible_for_sibcall_delay (insn)
410 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
411 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
413 (define_attr "eligible_for_return_delay" "false,true"
414 (symbol_ref "(eligible_for_return_delay (insn)
415 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
416 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
418 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
419 ;; branches. This would allow us to remove the nop always inserted before
420 ;; a floating point branch.
422 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
423 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
424 ;; This is because doing so will add several pipeline stalls to the path
425 ;; that the load/store did not come from. Unfortunately, there is no way
426 ;; to prevent fill_eager_delay_slots from using load/store without completely
427 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
428 ;; because it prevents us from moving back the final store of inner loops.
430 (define_attr "in_branch_delay" "false,true"
431 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
432 (eq_attr "length" "1"))
433 (const_string "true")
434 (const_string "false")))
436 (define_attr "in_uncond_branch_delay" "false,true"
437 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
438 (eq_attr "length" "1"))
439 (const_string "true")
440 (const_string "false")))
442 (define_attr "in_annul_branch_delay" "false,true"
443 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
444 (eq_attr "length" "1"))
445 (const_string "true")
446 (const_string "false")))
448 (define_delay (eq_attr "type" "call")
449 [(eq_attr "in_call_delay" "true") (nil) (nil)])
451 (define_delay (eq_attr "type" "sibcall")
452 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
454 (define_delay (eq_attr "type" "branch")
455 [(eq_attr "in_branch_delay" "true")
456 (nil) (eq_attr "in_annul_branch_delay" "true")])
458 (define_delay (eq_attr "type" "uncond_branch")
459 [(eq_attr "in_uncond_branch_delay" "true")
462 (define_delay (eq_attr "type" "return")
463 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
466 ;; Include SPARC DFA schedulers
468 (include "cypress.md")
469 (include "supersparc.md")
470 (include "hypersparc.md")
472 (include "sparclet.md")
473 (include "ultra1_2.md")
474 (include "ultra3.md")
475 (include "niagara.md")
476 (include "niagara2.md")
479 ;; Operand and operator predicates and constraints
481 (include "predicates.md")
482 (include "constraints.md")
485 ;; Compare instructions.
487 ;; These are just the DEFINE_INSNs to match the patterns and the
488 ;; DEFINE_SPLITs for some of the scc insns that actually require
489 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
491 ;; The compare DEFINE_INSNs.
493 (define_insn "*cmpsi_insn"
494 [(set (reg:CC CC_REG)
495 (compare:CC (match_operand:SI 0 "register_operand" "r")
496 (match_operand:SI 1 "arith_operand" "rI")))]
499 [(set_attr "type" "compare")])
501 (define_insn "*cmpdi_sp64"
502 [(set (reg:CCX CC_REG)
503 (compare:CCX (match_operand:DI 0 "register_operand" "r")
504 (match_operand:DI 1 "arith_operand" "rI")))]
507 [(set_attr "type" "compare")])
509 (define_insn "*cmpsf_fpe"
510 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
511 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
512 (match_operand:SF 2 "register_operand" "f")))]
516 return "fcmpes\t%0, %1, %2";
517 return "fcmpes\t%1, %2";
519 [(set_attr "type" "fpcmp")])
521 (define_insn "*cmpdf_fpe"
522 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
523 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
524 (match_operand:DF 2 "register_operand" "e")))]
528 return "fcmped\t%0, %1, %2";
529 return "fcmped\t%1, %2";
531 [(set_attr "type" "fpcmp")
532 (set_attr "fptype" "double")])
534 (define_insn "*cmptf_fpe"
535 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
536 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
537 (match_operand:TF 2 "register_operand" "e")))]
538 "TARGET_FPU && TARGET_HARD_QUAD"
541 return "fcmpeq\t%0, %1, %2";
542 return "fcmpeq\t%1, %2";
544 [(set_attr "type" "fpcmp")])
546 (define_insn "*cmpsf_fp"
547 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
548 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
549 (match_operand:SF 2 "register_operand" "f")))]
553 return "fcmps\t%0, %1, %2";
554 return "fcmps\t%1, %2";
556 [(set_attr "type" "fpcmp")])
558 (define_insn "*cmpdf_fp"
559 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
560 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
561 (match_operand:DF 2 "register_operand" "e")))]
565 return "fcmpd\t%0, %1, %2";
566 return "fcmpd\t%1, %2";
568 [(set_attr "type" "fpcmp")
569 (set_attr "fptype" "double")])
571 (define_insn "*cmptf_fp"
572 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
573 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
574 (match_operand:TF 2 "register_operand" "e")))]
575 "TARGET_FPU && TARGET_HARD_QUAD"
578 return "fcmpq\t%0, %1, %2";
579 return "fcmpq\t%1, %2";
581 [(set_attr "type" "fpcmp")])
583 ;; Next come the scc insns.
585 (define_expand "cstoresi4"
586 [(use (match_operator 1 "comparison_operator"
587 [(match_operand:SI 2 "compare_operand" "")
588 (match_operand:SI 3 "arith_operand" "")]))
589 (clobber (match_operand:SI 0 "register_operand"))]
592 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
593 operands[2] = force_reg (SImode, operands[2]);
594 if (emit_scc_insn (operands)) DONE; else FAIL;
597 (define_expand "cstoredi4"
598 [(use (match_operator 1 "comparison_operator"
599 [(match_operand:DI 2 "compare_operand" "")
600 (match_operand:DI 3 "arith_operand" "")]))
601 (clobber (match_operand:SI 0 "register_operand"))]
604 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
605 operands[2] = force_reg (DImode, operands[2]);
606 if (emit_scc_insn (operands)) DONE; else FAIL;
609 (define_expand "cstore<F:mode>4"
610 [(use (match_operator 1 "comparison_operator"
611 [(match_operand:F 2 "register_operand" "")
612 (match_operand:F 3 "register_operand" "")]))
613 (clobber (match_operand:SI 0 "register_operand"))]
615 { if (emit_scc_insn (operands)) DONE; else FAIL; })
619 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
620 ;; generate addcc/subcc instructions.
622 (define_expand "seqsi_special"
624 (xor:SI (match_operand:SI 1 "register_operand" "")
625 (match_operand:SI 2 "register_operand" "")))
626 (parallel [(set (match_operand:SI 0 "register_operand" "")
627 (eq:SI (match_dup 3) (const_int 0)))
628 (clobber (reg:CC CC_REG))])]
630 { operands[3] = gen_reg_rtx (SImode); })
632 (define_expand "seqdi_special"
634 (xor:DI (match_operand:DI 1 "register_operand" "")
635 (match_operand:DI 2 "register_operand" "")))
636 (set (match_operand:SI 0 "register_operand" "")
637 (eq:SI (match_dup 3) (const_int 0)))]
639 { operands[3] = gen_reg_rtx (DImode); })
641 (define_expand "snesi_special"
643 (xor:SI (match_operand:SI 1 "register_operand" "")
644 (match_operand:SI 2 "register_operand" "")))
645 (parallel [(set (match_operand:SI 0 "register_operand" "")
646 (ne:SI (match_dup 3) (const_int 0)))
647 (clobber (reg:CC CC_REG))])]
649 { operands[3] = gen_reg_rtx (SImode); })
651 (define_expand "snedi_special"
653 (xor:DI (match_operand:DI 1 "register_operand" "")
654 (match_operand:DI 2 "register_operand" "")))
655 (set (match_operand:SI 0 "register_operand" "")
656 (ne:SI (match_dup 3) (const_int 0)))]
658 { operands[3] = gen_reg_rtx (DImode); })
661 ;; Now the DEFINE_INSNs for the scc cases.
663 ;; The SEQ and SNE patterns are special because they can be done
664 ;; without any branching and do not involve a COMPARE. We want
665 ;; them to always use the splits below so the results can be
668 (define_insn_and_split "*snesi_zero"
669 [(set (match_operand:SI 0 "register_operand" "=r")
670 (ne:SI (match_operand:SI 1 "register_operand" "r")
672 (clobber (reg:CC CC_REG))]
676 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
678 (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
680 [(set_attr "length" "2")])
682 (define_insn_and_split "*neg_snesi_zero"
683 [(set (match_operand:SI 0 "register_operand" "=r")
684 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
686 (clobber (reg:CC CC_REG))]
690 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
692 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
694 [(set_attr "length" "2")])
696 (define_insn_and_split "*snesi_zero_extend"
697 [(set (match_operand:DI 0 "register_operand" "=r")
698 (ne:DI (match_operand:SI 1 "register_operand" "r")
700 (clobber (reg:CC CC_REG))]
704 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
707 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
709 (ltu:SI (reg:CC_NOOV CC_REG)
712 [(set_attr "length" "2")])
714 (define_insn_and_split "*snedi_zero"
715 [(set (match_operand:DI 0 "register_operand" "=&r")
716 (ne:DI (match_operand:DI 1 "register_operand" "r")
720 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
721 [(set (match_dup 0) (const_int 0))
722 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
727 [(set_attr "length" "2")])
729 (define_insn_and_split "*neg_snedi_zero"
730 [(set (match_operand:DI 0 "register_operand" "=&r")
731 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
735 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
736 [(set (match_dup 0) (const_int 0))
737 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
742 [(set_attr "length" "2")])
744 (define_insn_and_split "*snedi_zero_trunc"
745 [(set (match_operand:SI 0 "register_operand" "=&r")
746 (ne:SI (match_operand:DI 1 "register_operand" "r")
750 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
751 [(set (match_dup 0) (const_int 0))
752 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
757 [(set_attr "length" "2")])
759 (define_insn_and_split "*seqsi_zero"
760 [(set (match_operand:SI 0 "register_operand" "=r")
761 (eq:SI (match_operand:SI 1 "register_operand" "r")
763 (clobber (reg:CC CC_REG))]
767 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
769 (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
771 [(set_attr "length" "2")])
773 (define_insn_and_split "*neg_seqsi_zero"
774 [(set (match_operand:SI 0 "register_operand" "=r")
775 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
777 (clobber (reg:CC CC_REG))]
781 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
783 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
785 [(set_attr "length" "2")])
787 (define_insn_and_split "*seqsi_zero_extend"
788 [(set (match_operand:DI 0 "register_operand" "=r")
789 (eq:DI (match_operand:SI 1 "register_operand" "r")
791 (clobber (reg:CC CC_REG))]
795 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
798 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
800 (ltu:SI (reg:CC_NOOV CC_REG)
803 [(set_attr "length" "2")])
805 (define_insn_and_split "*seqdi_zero"
806 [(set (match_operand:DI 0 "register_operand" "=&r")
807 (eq:DI (match_operand:DI 1 "register_operand" "r")
811 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
812 [(set (match_dup 0) (const_int 0))
813 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
818 [(set_attr "length" "2")])
820 (define_insn_and_split "*neg_seqdi_zero"
821 [(set (match_operand:DI 0 "register_operand" "=&r")
822 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
826 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
827 [(set (match_dup 0) (const_int 0))
828 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
833 [(set_attr "length" "2")])
835 (define_insn_and_split "*seqdi_zero_trunc"
836 [(set (match_operand:SI 0 "register_operand" "=&r")
837 (eq:SI (match_operand:DI 1 "register_operand" "r")
841 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
842 [(set (match_dup 0) (const_int 0))
843 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
848 [(set_attr "length" "2")])
850 ;; We can also do (x + (i == 0)) and related, so put them in.
851 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
854 (define_insn_and_split "*x_plus_i_ne_0"
855 [(set (match_operand:SI 0 "register_operand" "=r")
856 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
858 (match_operand:SI 2 "register_operand" "r")))
859 (clobber (reg:CC CC_REG))]
863 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
865 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
868 [(set_attr "length" "2")])
870 (define_insn_and_split "*x_minus_i_ne_0"
871 [(set (match_operand:SI 0 "register_operand" "=r")
872 (minus:SI (match_operand:SI 2 "register_operand" "r")
873 (ne:SI (match_operand:SI 1 "register_operand" "r")
875 (clobber (reg:CC CC_REG))]
879 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
881 (set (match_dup 0) (minus:SI (match_dup 2)
882 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
884 [(set_attr "length" "2")])
886 (define_insn_and_split "*x_plus_i_eq_0"
887 [(set (match_operand:SI 0 "register_operand" "=r")
888 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
890 (match_operand:SI 2 "register_operand" "r")))
891 (clobber (reg:CC CC_REG))]
895 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
897 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
900 [(set_attr "length" "2")])
902 (define_insn_and_split "*x_minus_i_eq_0"
903 [(set (match_operand:SI 0 "register_operand" "=r")
904 (minus:SI (match_operand:SI 2 "register_operand" "r")
905 (eq:SI (match_operand:SI 1 "register_operand" "r")
907 (clobber (reg:CC CC_REG))]
911 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
913 (set (match_dup 0) (minus:SI (match_dup 2)
914 (geu:SI (reg:CC CC_REG) (const_int 0))))]
916 [(set_attr "length" "2")])
918 ;; We can also do GEU and LTU directly, but these operate after a compare.
919 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
922 (define_insn "*sltu_insn"
923 [(set (match_operand:SI 0 "register_operand" "=r")
924 (ltu:SI (reg:CC CC_REG) (const_int 0)))]
927 [(set_attr "type" "ialuX")])
929 (define_insn "*neg_sltu_insn"
930 [(set (match_operand:SI 0 "register_operand" "=r")
931 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
934 [(set_attr "type" "ialuX")])
936 ;; ??? Combine should canonicalize these next two to the same pattern.
937 (define_insn "*neg_sltu_minus_x"
938 [(set (match_operand:SI 0 "register_operand" "=r")
939 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
940 (match_operand:SI 1 "arith_operand" "rI")))]
943 [(set_attr "type" "ialuX")])
945 (define_insn "*neg_sltu_plus_x"
946 [(set (match_operand:SI 0 "register_operand" "=r")
947 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
948 (match_operand:SI 1 "arith_operand" "rI"))))]
951 [(set_attr "type" "ialuX")])
953 (define_insn "*sgeu_insn"
954 [(set (match_operand:SI 0 "register_operand" "=r")
955 (geu:SI (reg:CC CC_REG) (const_int 0)))]
958 [(set_attr "type" "ialuX")])
960 (define_insn "*neg_sgeu_insn"
961 [(set (match_operand:SI 0 "register_operand" "=r")
962 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
965 [(set_attr "type" "ialuX")])
967 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
968 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
971 (define_insn "*sltu_plus_x"
972 [(set (match_operand:SI 0 "register_operand" "=r")
973 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
974 (match_operand:SI 1 "arith_operand" "rI")))]
977 [(set_attr "type" "ialuX")])
979 (define_insn "*sltu_plus_x_plus_y"
980 [(set (match_operand:SI 0 "register_operand" "=r")
981 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
982 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
983 (match_operand:SI 2 "arith_operand" "rI"))))]
986 [(set_attr "type" "ialuX")])
988 (define_insn "*x_minus_sltu"
989 [(set (match_operand:SI 0 "register_operand" "=r")
990 (minus:SI (match_operand:SI 1 "register_operand" "r")
991 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
994 [(set_attr "type" "ialuX")])
996 ;; ??? Combine should canonicalize these next two to the same pattern.
997 (define_insn "*x_minus_y_minus_sltu"
998 [(set (match_operand:SI 0 "register_operand" "=r")
999 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1000 (match_operand:SI 2 "arith_operand" "rI"))
1001 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1004 [(set_attr "type" "ialuX")])
1006 (define_insn "*x_minus_sltu_plus_y"
1007 [(set (match_operand:SI 0 "register_operand" "=r")
1008 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1009 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1010 (match_operand:SI 2 "arith_operand" "rI"))))]
1013 [(set_attr "type" "ialuX")])
1015 (define_insn "*sgeu_plus_x"
1016 [(set (match_operand:SI 0 "register_operand" "=r")
1017 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1018 (match_operand:SI 1 "register_operand" "r")))]
1021 [(set_attr "type" "ialuX")])
1023 (define_insn "*x_minus_sgeu"
1024 [(set (match_operand:SI 0 "register_operand" "=r")
1025 (minus:SI (match_operand:SI 1 "register_operand" "r")
1026 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1029 [(set_attr "type" "ialuX")])
1032 [(set (match_operand:SI 0 "register_operand" "")
1033 (match_operator:SI 2 "noov_compare_operator"
1034 [(match_operand 1 "icc_or_fcc_register_operand" "")
1037 && REGNO (operands[1]) == SPARC_ICC_REG
1038 && (GET_MODE (operands[1]) == CCXmode
1039 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1040 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1041 [(set (match_dup 0) (const_int 0))
1043 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1049 ;; These control RTL generation for conditional jump insns
1051 (define_expand "cbranchcc4"
1053 (if_then_else (match_operator 0 "comparison_operator"
1054 [(match_operand 1 "compare_operand" "")
1055 (match_operand 2 "const_zero_operand" "")])
1056 (label_ref (match_operand 3 "" ""))
1061 (define_expand "cbranchsi4"
1062 [(use (match_operator 0 "comparison_operator"
1063 [(match_operand:SI 1 "compare_operand" "")
1064 (match_operand:SI 2 "arith_operand" "")]))
1065 (use (match_operand 3 ""))]
1068 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1069 operands[1] = force_reg (SImode, operands[1]);
1070 emit_conditional_branch_insn (operands);
1074 (define_expand "cbranchdi4"
1075 [(use (match_operator 0 "comparison_operator"
1076 [(match_operand:DI 1 "compare_operand" "")
1077 (match_operand:DI 2 "arith_operand" "")]))
1078 (use (match_operand 3 ""))]
1081 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1082 operands[1] = force_reg (DImode, operands[1]);
1083 emit_conditional_branch_insn (operands);
1087 (define_expand "cbranch<F:mode>4"
1088 [(use (match_operator 0 "comparison_operator"
1089 [(match_operand:F 1 "register_operand" "")
1090 (match_operand:F 2 "register_operand" "")]))
1091 (use (match_operand 3 ""))]
1093 { emit_conditional_branch_insn (operands); DONE; })
1096 ;; Now match both normal and inverted jump.
1098 ;; XXX fpcmp nop braindamage
1099 (define_insn "*normal_branch"
1101 (if_then_else (match_operator 0 "noov_compare_operator"
1102 [(reg CC_REG) (const_int 0)])
1103 (label_ref (match_operand 1 "" ""))
1107 return output_cbranch (operands[0], operands[1], 1, 0,
1108 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1111 [(set_attr "type" "branch")
1112 (set_attr "branch_type" "icc")])
1114 ;; XXX fpcmp nop braindamage
1115 (define_insn "*inverted_branch"
1117 (if_then_else (match_operator 0 "noov_compare_operator"
1118 [(reg CC_REG) (const_int 0)])
1120 (label_ref (match_operand 1 "" ""))))]
1123 return output_cbranch (operands[0], operands[1], 1, 1,
1124 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1127 [(set_attr "type" "branch")
1128 (set_attr "branch_type" "icc")])
1130 ;; XXX fpcmp nop braindamage
1131 (define_insn "*normal_fp_branch"
1133 (if_then_else (match_operator 1 "comparison_operator"
1134 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1136 (label_ref (match_operand 2 "" ""))
1140 return output_cbranch (operands[1], operands[2], 2, 0,
1141 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1144 [(set_attr "type" "branch")
1145 (set_attr "branch_type" "fcc")])
1147 ;; XXX fpcmp nop braindamage
1148 (define_insn "*inverted_fp_branch"
1150 (if_then_else (match_operator 1 "comparison_operator"
1151 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1154 (label_ref (match_operand 2 "" ""))))]
1157 return output_cbranch (operands[1], operands[2], 2, 1,
1158 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1161 [(set_attr "type" "branch")
1162 (set_attr "branch_type" "fcc")])
1164 ;; XXX fpcmp nop braindamage
1165 (define_insn "*normal_fpe_branch"
1167 (if_then_else (match_operator 1 "comparison_operator"
1168 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1170 (label_ref (match_operand 2 "" ""))
1174 return output_cbranch (operands[1], operands[2], 2, 0,
1175 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1178 [(set_attr "type" "branch")
1179 (set_attr "branch_type" "fcc")])
1181 ;; XXX fpcmp nop braindamage
1182 (define_insn "*inverted_fpe_branch"
1184 (if_then_else (match_operator 1 "comparison_operator"
1185 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1188 (label_ref (match_operand 2 "" ""))))]
1191 return output_cbranch (operands[1], operands[2], 2, 1,
1192 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1195 [(set_attr "type" "branch")
1196 (set_attr "branch_type" "fcc")])
1198 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1199 ;; in the architecture.
1201 ;; There are no 32 bit brreg insns.
1204 (define_insn "*normal_int_branch_sp64"
1206 (if_then_else (match_operator 0 "v9_register_compare_operator"
1207 [(match_operand:DI 1 "register_operand" "r")
1209 (label_ref (match_operand 2 "" ""))
1213 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1214 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1217 [(set_attr "type" "branch")
1218 (set_attr "branch_type" "reg")])
1221 (define_insn "*inverted_int_branch_sp64"
1223 (if_then_else (match_operator 0 "v9_register_compare_operator"
1224 [(match_operand:DI 1 "register_operand" "r")
1227 (label_ref (match_operand 2 "" ""))))]
1230 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1231 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1234 [(set_attr "type" "branch")
1235 (set_attr "branch_type" "reg")])
1238 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1239 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1240 ;; that adds the PC value at the call point to register #(operand 3).
1242 (define_insn "load_pcrel_sym<P:mode>"
1243 [(set (match_operand:P 0 "register_operand" "=r")
1244 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1245 (match_operand:P 2 "call_address_operand" "")
1246 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1247 (clobber (reg:P O7_REG))]
1248 "REGNO (operands[0]) == INTVAL (operands[3])"
1250 if (flag_delayed_branch)
1251 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1253 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1255 [(set (attr "type") (const_string "multi"))
1256 (set (attr "length")
1257 (if_then_else (eq_attr "delayed_branch" "true")
1262 ;; Integer move instructions
1264 (define_expand "movqi"
1265 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1266 (match_operand:QI 1 "general_operand" ""))]
1269 if (sparc_expand_move (QImode, operands))
1273 (define_insn "*movqi_insn"
1274 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1275 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1276 "(register_operand (operands[0], QImode)
1277 || register_or_zero_operand (operands[1], QImode))"
1282 [(set_attr "type" "*,load,store")
1283 (set_attr "us3load_type" "*,3cycle,*")])
1285 (define_expand "movhi"
1286 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1287 (match_operand:HI 1 "general_operand" ""))]
1290 if (sparc_expand_move (HImode, operands))
1294 (define_insn "*movhi_insn"
1295 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1296 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1297 "(register_operand (operands[0], HImode)
1298 || register_or_zero_operand (operands[1], HImode))"
1301 sethi\t%%hi(%a1), %0
1304 [(set_attr "type" "*,*,load,store")
1305 (set_attr "us3load_type" "*,*,3cycle,*")])
1307 ;; We always work with constants here.
1308 (define_insn "*movhi_lo_sum"
1309 [(set (match_operand:HI 0 "register_operand" "=r")
1310 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1311 (match_operand:HI 2 "small_int_operand" "I")))]
1315 (define_expand "movsi"
1316 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1317 (match_operand:SI 1 "general_operand" ""))]
1320 if (sparc_expand_move (SImode, operands))
1324 (define_insn "*movsi_insn"
1325 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d,d")
1326 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J,P"))]
1327 "(register_operand (operands[0], SImode)
1328 || register_or_zero_or_all_ones_operand (operands[1], SImode))"
1331 sethi\t%%hi(%a1), %0
1339 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")])
1341 (define_insn "*movsi_lo_sum"
1342 [(set (match_operand:SI 0 "register_operand" "=r")
1343 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1344 (match_operand:SI 2 "immediate_operand" "in")))]
1346 "or\t%1, %%lo(%a2), %0")
1348 (define_insn "*movsi_high"
1349 [(set (match_operand:SI 0 "register_operand" "=r")
1350 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1352 "sethi\t%%hi(%a1), %0")
1354 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1355 ;; so that CSE won't optimize the address computation away.
1356 (define_insn "movsi_lo_sum_pic"
1357 [(set (match_operand:SI 0 "register_operand" "=r")
1358 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1359 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1362 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1363 return "xor\t%1, %%gdop_lox10(%a2), %0";
1365 return "or\t%1, %%lo(%a2), %0";
1369 (define_insn "movsi_high_pic"
1370 [(set (match_operand:SI 0 "register_operand" "=r")
1371 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1372 "flag_pic && check_pic (1)"
1374 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1375 return "sethi\t%%gdop_hix22(%a1), %0";
1377 return "sethi\t%%hi(%a1), %0";
1381 (define_insn "movsi_pic_gotdata_op"
1382 [(set (match_operand:SI 0 "register_operand" "=r")
1383 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1384 (match_operand:SI 2 "register_operand" "r")
1385 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1386 "flag_pic && check_pic (1)"
1388 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1389 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1391 return "ld\t[%1 + %2], %0";
1394 [(set_attr "type" "load")])
1396 (define_expand "movsi_pic_label_ref"
1397 [(set (match_dup 3) (high:SI
1398 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1399 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1400 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1401 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1402 (set (match_operand:SI 0 "register_operand" "=r")
1403 (minus:SI (match_dup 5) (match_dup 4)))]
1406 crtl->uses_pic_offset_table = 1;
1407 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1408 if (!can_create_pseudo_p ())
1410 operands[3] = operands[0];
1411 operands[4] = operands[0];
1415 operands[3] = gen_reg_rtx (SImode);
1416 operands[4] = gen_reg_rtx (SImode);
1418 operands[5] = pic_offset_table_rtx;
1421 (define_insn "*movsi_high_pic_label_ref"
1422 [(set (match_operand:SI 0 "register_operand" "=r")
1424 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1425 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1427 "sethi\t%%hi(%a2-(%a1-.)), %0")
1429 (define_insn "*movsi_lo_sum_pic_label_ref"
1430 [(set (match_operand:SI 0 "register_operand" "=r")
1431 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1432 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1433 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1435 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1437 ;; Set up the PIC register for VxWorks.
1439 (define_expand "vxworks_load_got"
1441 (high:SI (match_dup 1)))
1443 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1445 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1446 "TARGET_VXWORKS_RTP"
1448 operands[0] = pic_offset_table_rtx;
1449 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1450 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1453 (define_expand "movdi"
1454 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1455 (match_operand:DI 1 "general_operand" ""))]
1458 if (sparc_expand_move (DImode, operands))
1462 ;; Be careful, fmovd does not exist when !v9.
1463 ;; We match MEM moves directly when we have correct even
1464 ;; numbered registers, but fall into splits otherwise.
1465 ;; The constraint ordering here is really important to
1466 ;; avoid insane problems in reload, especially for patterns
1469 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1470 ;; (const_int -5016)))
1474 (define_insn "*movdi_insn_sp32"
1475 [(set (match_operand:DI 0 "nonimmediate_operand"
1476 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1477 (match_operand:DI 1 "input_operand"
1478 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1480 && (register_operand (operands[0], DImode)
1481 || register_or_zero_operand (operands[1], DImode))"
1495 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1496 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1498 (define_insn "*movdi_insn_sp32_v9"
1499 [(set (match_operand:DI 0 "nonimmediate_operand"
1500 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1501 (match_operand:DI 1 "input_operand"
1502 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1505 && (register_operand (operands[0], DImode)
1506 || register_or_zero_operand (operands[1], DImode))"
1523 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1524 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1525 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1527 (define_insn "*movdi_insn_sp64"
1528 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b,b")
1529 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J,P"))]
1531 && (register_operand (operands[0], DImode)
1532 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1535 sethi\t%%hi(%a1), %0
1543 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")
1544 (set_attr "fptype" "*,*,*,*,double,*,*,double,double")])
1546 (define_expand "movdi_pic_label_ref"
1547 [(set (match_dup 3) (high:DI
1548 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1549 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1550 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1551 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1552 (set (match_operand:DI 0 "register_operand" "=r")
1553 (minus:DI (match_dup 5) (match_dup 4)))]
1554 "TARGET_ARCH64 && flag_pic"
1556 crtl->uses_pic_offset_table = 1;
1557 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1558 if (!can_create_pseudo_p ())
1560 operands[3] = operands[0];
1561 operands[4] = operands[0];
1565 operands[3] = gen_reg_rtx (DImode);
1566 operands[4] = gen_reg_rtx (DImode);
1568 operands[5] = pic_offset_table_rtx;
1571 (define_insn "*movdi_high_pic_label_ref"
1572 [(set (match_operand:DI 0 "register_operand" "=r")
1574 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1575 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1576 "TARGET_ARCH64 && flag_pic"
1577 "sethi\t%%hi(%a2-(%a1-.)), %0")
1579 (define_insn "*movdi_lo_sum_pic_label_ref"
1580 [(set (match_operand:DI 0 "register_operand" "=r")
1581 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1582 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1583 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1584 "TARGET_ARCH64 && flag_pic"
1585 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1587 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1588 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1590 (define_insn "movdi_lo_sum_pic"
1591 [(set (match_operand:DI 0 "register_operand" "=r")
1592 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1593 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1594 "TARGET_ARCH64 && flag_pic"
1596 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1597 return "xor\t%1, %%gdop_lox10(%a2), %0";
1599 return "or\t%1, %%lo(%a2), %0";
1603 (define_insn "movdi_high_pic"
1604 [(set (match_operand:DI 0 "register_operand" "=r")
1605 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1606 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1608 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1609 return "sethi\t%%gdop_hix22(%a1), %0";
1611 return "sethi\t%%hi(%a1), %0";
1615 (define_insn "movdi_pic_gotdata_op"
1616 [(set (match_operand:DI 0 "register_operand" "=r")
1617 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1618 (match_operand:DI 2 "register_operand" "r")
1619 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1620 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1622 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1623 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1625 return "ldx\t[%1 + %2], %0";
1628 [(set_attr "type" "load")])
1630 (define_insn "*sethi_di_medlow_embmedany_pic"
1631 [(set (match_operand:DI 0 "register_operand" "=r")
1632 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1633 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1634 "sethi\t%%hi(%a1), %0")
1636 (define_insn "*sethi_di_medlow"
1637 [(set (match_operand:DI 0 "register_operand" "=r")
1638 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1639 "TARGET_CM_MEDLOW && check_pic (1)"
1640 "sethi\t%%hi(%a1), %0")
1642 (define_insn "*losum_di_medlow"
1643 [(set (match_operand:DI 0 "register_operand" "=r")
1644 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1645 (match_operand:DI 2 "symbolic_operand" "")))]
1647 "or\t%1, %%lo(%a2), %0")
1649 (define_insn "seth44"
1650 [(set (match_operand:DI 0 "register_operand" "=r")
1651 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1653 "sethi\t%%h44(%a1), %0")
1655 (define_insn "setm44"
1656 [(set (match_operand:DI 0 "register_operand" "=r")
1657 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1658 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1660 "or\t%1, %%m44(%a2), %0")
1662 (define_insn "setl44"
1663 [(set (match_operand:DI 0 "register_operand" "=r")
1664 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1665 (match_operand:DI 2 "symbolic_operand" "")))]
1667 "or\t%1, %%l44(%a2), %0")
1669 (define_insn "sethh"
1670 [(set (match_operand:DI 0 "register_operand" "=r")
1671 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1673 "sethi\t%%hh(%a1), %0")
1675 (define_insn "setlm"
1676 [(set (match_operand:DI 0 "register_operand" "=r")
1677 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1679 "sethi\t%%lm(%a1), %0")
1681 (define_insn "sethm"
1682 [(set (match_operand:DI 0 "register_operand" "=r")
1683 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1684 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1686 "or\t%1, %%hm(%a2), %0")
1688 (define_insn "setlo"
1689 [(set (match_operand:DI 0 "register_operand" "=r")
1690 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1691 (match_operand:DI 2 "symbolic_operand" "")))]
1693 "or\t%1, %%lo(%a2), %0")
1695 (define_insn "embmedany_sethi"
1696 [(set (match_operand:DI 0 "register_operand" "=r")
1697 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1698 "TARGET_CM_EMBMEDANY && check_pic (1)"
1699 "sethi\t%%hi(%a1), %0")
1701 (define_insn "embmedany_losum"
1702 [(set (match_operand:DI 0 "register_operand" "=r")
1703 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1704 (match_operand:DI 2 "data_segment_operand" "")))]
1705 "TARGET_CM_EMBMEDANY"
1706 "add\t%1, %%lo(%a2), %0")
1708 (define_insn "embmedany_brsum"
1709 [(set (match_operand:DI 0 "register_operand" "=r")
1710 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1711 "TARGET_CM_EMBMEDANY"
1714 (define_insn "embmedany_textuhi"
1715 [(set (match_operand:DI 0 "register_operand" "=r")
1716 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1717 "TARGET_CM_EMBMEDANY && check_pic (1)"
1718 "sethi\t%%uhi(%a1), %0")
1720 (define_insn "embmedany_texthi"
1721 [(set (match_operand:DI 0 "register_operand" "=r")
1722 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1723 "TARGET_CM_EMBMEDANY && check_pic (1)"
1724 "sethi\t%%hi(%a1), %0")
1726 (define_insn "embmedany_textulo"
1727 [(set (match_operand:DI 0 "register_operand" "=r")
1728 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1729 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1730 "TARGET_CM_EMBMEDANY"
1731 "or\t%1, %%ulo(%a2), %0")
1733 (define_insn "embmedany_textlo"
1734 [(set (match_operand:DI 0 "register_operand" "=r")
1735 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1736 (match_operand:DI 2 "text_segment_operand" "")))]
1737 "TARGET_CM_EMBMEDANY"
1738 "or\t%1, %%lo(%a2), %0")
1740 ;; Now some patterns to help reload out a bit.
1741 (define_expand "reload_indi"
1742 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1743 (match_operand:DI 1 "immediate_operand" "")
1744 (match_operand:TI 2 "register_operand" "=&r")])]
1746 || TARGET_CM_EMBMEDANY)
1749 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1753 (define_expand "reload_outdi"
1754 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1755 (match_operand:DI 1 "immediate_operand" "")
1756 (match_operand:TI 2 "register_operand" "=&r")])]
1758 || TARGET_CM_EMBMEDANY)
1761 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1765 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1767 [(set (match_operand:DI 0 "register_operand" "")
1768 (match_operand:DI 1 "const_int_operand" ""))]
1769 "! TARGET_ARCH64 && reload_completed"
1770 [(clobber (const_int 0))]
1772 #if HOST_BITS_PER_WIDE_INT == 32
1773 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1774 (INTVAL (operands[1]) < 0) ?
1777 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1780 unsigned int low, high;
1782 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1783 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1784 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1786 /* Slick... but this trick loses if this subreg constant part
1787 can be done in one insn. */
1789 && ! SPARC_SETHI32_P (high)
1790 && ! SPARC_SIMM13_P (high))
1791 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1792 gen_highpart (SImode, operands[0])));
1794 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1800 [(set (match_operand:DI 0 "register_operand" "")
1801 (match_operand:DI 1 "const_double_operand" ""))]
1805 && ((GET_CODE (operands[0]) == REG
1806 && REGNO (operands[0]) < 32)
1807 || (GET_CODE (operands[0]) == SUBREG
1808 && GET_CODE (SUBREG_REG (operands[0])) == REG
1809 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1810 [(clobber (const_int 0))]
1812 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1813 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1815 /* Slick... but this trick loses if this subreg constant part
1816 can be done in one insn. */
1817 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1818 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1819 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1821 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1822 gen_highpart (SImode, operands[0])));
1826 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1827 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1833 [(set (match_operand:DI 0 "register_operand" "")
1834 (match_operand:DI 1 "register_operand" ""))]
1838 && ((GET_CODE (operands[0]) == REG
1839 && REGNO (operands[0]) < 32)
1840 || (GET_CODE (operands[0]) == SUBREG
1841 && GET_CODE (SUBREG_REG (operands[0])) == REG
1842 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1843 [(clobber (const_int 0))]
1845 rtx set_dest = operands[0];
1846 rtx set_src = operands[1];
1850 dest1 = gen_highpart (SImode, set_dest);
1851 dest2 = gen_lowpart (SImode, set_dest);
1852 src1 = gen_highpart (SImode, set_src);
1853 src2 = gen_lowpart (SImode, set_src);
1855 /* Now emit using the real source and destination we found, swapping
1856 the order if we detect overlap. */
1857 if (reg_overlap_mentioned_p (dest1, src2))
1859 emit_insn (gen_movsi (dest2, src2));
1860 emit_insn (gen_movsi (dest1, src1));
1864 emit_insn (gen_movsi (dest1, src1));
1865 emit_insn (gen_movsi (dest2, src2));
1870 ;; Now handle the cases of memory moves from/to non-even
1871 ;; DI mode register pairs.
1873 [(set (match_operand:DI 0 "register_operand" "")
1874 (match_operand:DI 1 "memory_operand" ""))]
1877 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1878 [(clobber (const_int 0))]
1880 rtx word0 = adjust_address (operands[1], SImode, 0);
1881 rtx word1 = adjust_address (operands[1], SImode, 4);
1882 rtx high_part = gen_highpart (SImode, operands[0]);
1883 rtx low_part = gen_lowpart (SImode, operands[0]);
1885 if (reg_overlap_mentioned_p (high_part, word1))
1887 emit_insn (gen_movsi (low_part, word1));
1888 emit_insn (gen_movsi (high_part, word0));
1892 emit_insn (gen_movsi (high_part, word0));
1893 emit_insn (gen_movsi (low_part, word1));
1899 [(set (match_operand:DI 0 "memory_operand" "")
1900 (match_operand:DI 1 "register_operand" ""))]
1903 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1904 [(clobber (const_int 0))]
1906 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1907 gen_highpart (SImode, operands[1])));
1908 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1909 gen_lowpart (SImode, operands[1])));
1914 [(set (match_operand:DI 0 "memory_operand" "")
1915 (match_operand:DI 1 "const_zero_operand" ""))]
1919 && ! mem_min_alignment (operands[0], 8)))
1920 && offsettable_memref_p (operands[0])"
1921 [(clobber (const_int 0))]
1923 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1924 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1929 ;; Floating point and vector move instructions
1931 ;; Yes, you guessed it right, the former movsf expander.
1932 (define_expand "mov<V32:mode>"
1933 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1934 (match_operand:V32 1 "general_operand" ""))]
1935 "<V32:MODE>mode == SFmode || TARGET_VIS"
1937 if (sparc_expand_move (<V32:MODE>mode, operands))
1941 (define_insn "*movsf_insn"
1942 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,d,f,*r,*r,*r,f,*r,m,m")
1943 (match_operand:V32 1 "input_operand" "GY,ZC,f,*rRY,Q,S,m,m,f,*rGY"))]
1945 && (register_operand (operands[0], <V32:MODE>mode)
1946 || register_or_zero_or_all_ones_operand (operands[1], <V32:MODE>mode))"
1948 if (GET_CODE (operands[1]) == CONST_DOUBLE
1949 && (which_alternative == 3
1950 || which_alternative == 4
1951 || which_alternative == 5))
1956 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1957 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1958 operands[1] = GEN_INT (i);
1961 switch (which_alternative)
1964 return "fzeros\t%0";
1968 return "fmovs\t%1, %0";
1970 return "mov\t%1, %0";
1972 return "sethi\t%%hi(%a1), %0";
1977 return "ld\t%1, %0";
1980 return "st\t%r1, %0";
1985 [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1987 ;; Exactly the same as above, except that all `f' cases are deleted.
1988 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1991 (define_insn "*movsf_insn_no_fpu"
1992 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1993 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1995 && (register_operand (operands[0], SFmode)
1996 || register_or_zero_operand (operands[1], SFmode))"
1998 if (GET_CODE (operands[1]) == CONST_DOUBLE
1999 && (which_alternative == 0
2000 || which_alternative == 1
2001 || which_alternative == 2))
2006 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2007 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2008 operands[1] = GEN_INT (i);
2011 switch (which_alternative)
2014 return "mov\t%1, %0";
2016 return "sethi\t%%hi(%a1), %0";
2020 return "ld\t%1, %0";
2022 return "st\t%r1, %0";
2027 [(set_attr "type" "*,*,*,load,store")])
2029 ;; The following 3 patterns build SFmode constants in integer registers.
2031 (define_insn "*movsf_lo_sum"
2032 [(set (match_operand:SF 0 "register_operand" "=r")
2033 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2034 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2040 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2041 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2042 operands[2] = GEN_INT (i);
2043 return "or\t%1, %%lo(%a2), %0";
2046 (define_insn "*movsf_high"
2047 [(set (match_operand:SF 0 "register_operand" "=r")
2048 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2054 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2055 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2056 operands[1] = GEN_INT (i);
2057 return "sethi\t%%hi(%1), %0";
2061 [(set (match_operand:SF 0 "register_operand" "")
2062 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2063 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2064 [(set (match_dup 0) (high:SF (match_dup 1)))
2065 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2067 ;; Yes, you again guessed it right, the former movdf expander.
2068 (define_expand "mov<V64:mode>"
2069 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2070 (match_operand:V64 1 "general_operand" ""))]
2071 "<V64:MODE>mode == DFmode || TARGET_VIS"
2073 if (sparc_expand_move (<V64:MODE>mode, operands))
2077 ;; Be careful, fmovd does not exist when !v9.
2078 (define_insn "*movdf_insn_sp32"
2079 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2080 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2083 && (register_operand (operands[0], DFmode)
2084 || register_or_zero_operand (operands[1], DFmode))"
2096 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2097 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2099 (define_insn "*movdf_insn_sp32_no_fpu"
2100 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2101 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2104 && (register_operand (operands[0], DFmode)
2105 || register_or_zero_operand (operands[1], DFmode))"
2112 [(set_attr "type" "load,store,*,*,*")
2113 (set_attr "length" "*,*,2,2,2")])
2115 ;; We have available v9 double floats but not 64-bit integer registers.
2116 (define_insn "*movdf_insn_sp32_v9"
2117 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,T,W,U,T,f,*r,o")
2118 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2122 && (register_operand (operands[0], <V64:MODE>mode)
2123 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2136 [(set_attr "type" "fga,fga,fpmove,load,store,store,load,store,*,*,*")
2137 (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")
2138 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*")])
2140 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2141 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2142 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2146 && (register_operand (operands[0], DFmode)
2147 || register_or_zero_operand (operands[1], DFmode))"
2154 [(set_attr "type" "load,store,store,*,*")
2155 (set_attr "length" "*,*,*,2,2")])
2157 ;; We have available both v9 double floats and 64-bit integer registers.
2158 (define_insn "*movdf_insn_sp64"
2159 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,W,*r,*r,m,*r")
2160 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,e,*rGY,m,*rGY,DF"))]
2163 && (register_operand (operands[0], <V64:MODE>mode)
2164 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2175 [(set_attr "type" "fga,fga,fpmove,load,store,*,load,store,*")
2176 (set_attr "length" "*,*,*,*,*,*,*,*,2")
2177 (set_attr "fptype" "double,double,double,*,*,*,*,*,*")])
2179 (define_insn "*movdf_insn_sp64_no_fpu"
2180 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2181 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2184 && (register_operand (operands[0], DFmode)
2185 || register_or_zero_operand (operands[1], DFmode))"
2190 [(set_attr "type" "*,load,store")])
2192 ;; This pattern builds V64mode constants in integer registers.
2194 [(set (match_operand:V64 0 "register_operand" "")
2195 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2197 && (GET_CODE (operands[0]) == REG
2198 && REGNO (operands[0]) < 32)
2199 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2200 && reload_completed"
2201 [(clobber (const_int 0))]
2203 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2207 #if HOST_BITS_PER_WIDE_INT == 32
2210 enum machine_mode mode = GET_MODE (operands[1]);
2211 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2212 emit_insn (gen_movdi (operands[0], tem));
2217 enum machine_mode mode = GET_MODE (operands[1]);
2218 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2219 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2221 gcc_assert (GET_CODE (hi) == CONST_INT);
2222 gcc_assert (GET_CODE (lo) == CONST_INT);
2224 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2226 /* Slick... but this trick loses if this subreg constant part
2227 can be done in one insn. */
2229 && ! SPARC_SETHI32_P (INTVAL (hi))
2230 && ! SPARC_SIMM13_P (INTVAL (hi)))
2232 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2233 gen_highpart (SImode, operands[0])));
2237 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2243 ;; Ok, now the splits to handle all the multi insn and
2244 ;; mis-aligned memory address cases.
2245 ;; In these splits please take note that we must be
2246 ;; careful when V9 but not ARCH64 because the integer
2247 ;; register DFmode cases must be handled.
2249 [(set (match_operand:V64 0 "register_operand" "")
2250 (match_operand:V64 1 "register_operand" ""))]
2253 && ((GET_CODE (operands[0]) == REG
2254 && REGNO (operands[0]) < 32)
2255 || (GET_CODE (operands[0]) == SUBREG
2256 && GET_CODE (SUBREG_REG (operands[0])) == REG
2257 && REGNO (SUBREG_REG (operands[0])) < 32))))
2258 && reload_completed"
2259 [(clobber (const_int 0))]
2261 rtx set_dest = operands[0];
2262 rtx set_src = operands[1];
2265 enum machine_mode half_mode;
2267 /* We can be expanded for DFmode or integral vector modes. */
2268 if (<V64:MODE>mode == DFmode)
2273 dest1 = gen_highpart (half_mode, set_dest);
2274 dest2 = gen_lowpart (half_mode, set_dest);
2275 src1 = gen_highpart (half_mode, set_src);
2276 src2 = gen_lowpart (half_mode, set_src);
2278 /* Now emit using the real source and destination we found, swapping
2279 the order if we detect overlap. */
2280 if (reg_overlap_mentioned_p (dest1, src2))
2282 emit_move_insn_1 (dest2, src2);
2283 emit_move_insn_1 (dest1, src1);
2287 emit_move_insn_1 (dest1, src1);
2288 emit_move_insn_1 (dest2, src2);
2294 [(set (match_operand:V64 0 "register_operand" "")
2295 (match_operand:V64 1 "memory_operand" ""))]
2298 && (((REGNO (operands[0]) % 2) != 0)
2299 || ! mem_min_alignment (operands[1], 8))
2300 && offsettable_memref_p (operands[1])"
2301 [(clobber (const_int 0))]
2303 enum machine_mode half_mode;
2306 /* We can be expanded for DFmode or integral vector modes. */
2307 if (<V64:MODE>mode == DFmode)
2312 word0 = adjust_address (operands[1], half_mode, 0);
2313 word1 = adjust_address (operands[1], half_mode, 4);
2315 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2317 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2318 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2322 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2323 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2329 [(set (match_operand:V64 0 "memory_operand" "")
2330 (match_operand:V64 1 "register_operand" ""))]
2333 && (((REGNO (operands[1]) % 2) != 0)
2334 || ! mem_min_alignment (operands[0], 8))
2335 && offsettable_memref_p (operands[0])"
2336 [(clobber (const_int 0))]
2338 enum machine_mode half_mode;
2341 /* We can be expanded for DFmode or integral vector modes. */
2342 if (<V64:MODE>mode == DFmode)
2347 word0 = adjust_address (operands[0], half_mode, 0);
2348 word1 = adjust_address (operands[0], half_mode, 4);
2350 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2351 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2356 [(set (match_operand:V64 0 "memory_operand" "")
2357 (match_operand:V64 1 "const_zero_operand" ""))]
2361 && ! mem_min_alignment (operands[0], 8)))
2362 && offsettable_memref_p (operands[0])"
2363 [(clobber (const_int 0))]
2365 enum machine_mode half_mode;
2368 /* We can be expanded for DFmode or integral vector modes. */
2369 if (<V64:MODE>mode == DFmode)
2374 dest1 = adjust_address (operands[0], half_mode, 0);
2375 dest2 = adjust_address (operands[0], half_mode, 4);
2377 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2378 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2383 [(set (match_operand:V64 0 "register_operand" "")
2384 (match_operand:V64 1 "const_zero_operand" ""))]
2387 && ((GET_CODE (operands[0]) == REG
2388 && REGNO (operands[0]) < 32)
2389 || (GET_CODE (operands[0]) == SUBREG
2390 && GET_CODE (SUBREG_REG (operands[0])) == REG
2391 && REGNO (SUBREG_REG (operands[0])) < 32))"
2392 [(clobber (const_int 0))]
2394 enum machine_mode half_mode;
2395 rtx set_dest = operands[0];
2398 /* We can be expanded for DFmode or integral vector modes. */
2399 if (<V64:MODE>mode == DFmode)
2404 dest1 = gen_highpart (half_mode, set_dest);
2405 dest2 = gen_lowpart (half_mode, set_dest);
2406 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2407 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2411 (define_expand "movtf"
2412 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2413 (match_operand:TF 1 "general_operand" ""))]
2416 if (sparc_expand_move (TFmode, operands))
2420 (define_insn "*movtf_insn_sp32"
2421 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2422 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2425 && (register_operand (operands[0], TFmode)
2426 || register_or_zero_operand (operands[1], TFmode))"
2428 [(set_attr "length" "4")])
2430 ;; Exactly the same as above, except that all `e' cases are deleted.
2431 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2434 (define_insn "*movtf_insn_sp32_no_fpu"
2435 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2436 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2439 && (register_operand (operands[0], TFmode)
2440 || register_or_zero_operand (operands[1], TFmode))"
2442 [(set_attr "length" "4")])
2444 (define_insn "*movtf_insn_sp64"
2445 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2446 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2449 && ! TARGET_HARD_QUAD
2450 && (register_operand (operands[0], TFmode)
2451 || register_or_zero_operand (operands[1], TFmode))"
2453 [(set_attr "length" "2")])
2455 (define_insn "*movtf_insn_sp64_hq"
2456 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2457 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2461 && (register_operand (operands[0], TFmode)
2462 || register_or_zero_operand (operands[1], TFmode))"
2470 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2471 (set_attr "length" "2,*,*,*,2,2")])
2473 (define_insn "*movtf_insn_sp64_no_fpu"
2474 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2475 (match_operand:TF 1 "input_operand" "orG,rG"))]
2478 && (register_operand (operands[0], TFmode)
2479 || register_or_zero_operand (operands[1], TFmode))"
2481 [(set_attr "length" "2")])
2483 ;; Now all the splits to handle multi-insn TF mode moves.
2485 [(set (match_operand:TF 0 "register_operand" "")
2486 (match_operand:TF 1 "register_operand" ""))]
2490 && ! TARGET_HARD_QUAD)
2491 || ! fp_register_operand (operands[0], TFmode))"
2492 [(clobber (const_int 0))]
2494 rtx set_dest = operands[0];
2495 rtx set_src = operands[1];
2499 dest1 = gen_df_reg (set_dest, 0);
2500 dest2 = gen_df_reg (set_dest, 1);
2501 src1 = gen_df_reg (set_src, 0);
2502 src2 = gen_df_reg (set_src, 1);
2504 /* Now emit using the real source and destination we found, swapping
2505 the order if we detect overlap. */
2506 if (reg_overlap_mentioned_p (dest1, src2))
2508 emit_insn (gen_movdf (dest2, src2));
2509 emit_insn (gen_movdf (dest1, src1));
2513 emit_insn (gen_movdf (dest1, src1));
2514 emit_insn (gen_movdf (dest2, src2));
2520 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2521 (match_operand:TF 1 "const_zero_operand" ""))]
2523 [(clobber (const_int 0))]
2525 rtx set_dest = operands[0];
2528 switch (GET_CODE (set_dest))
2531 dest1 = gen_df_reg (set_dest, 0);
2532 dest2 = gen_df_reg (set_dest, 1);
2535 dest1 = adjust_address (set_dest, DFmode, 0);
2536 dest2 = adjust_address (set_dest, DFmode, 8);
2542 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2543 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2548 [(set (match_operand:TF 0 "register_operand" "")
2549 (match_operand:TF 1 "memory_operand" ""))]
2551 && offsettable_memref_p (operands[1])
2553 || ! TARGET_HARD_QUAD
2554 || ! fp_register_operand (operands[0], TFmode)))"
2555 [(clobber (const_int 0))]
2557 rtx word0 = adjust_address (operands[1], DFmode, 0);
2558 rtx word1 = adjust_address (operands[1], DFmode, 8);
2559 rtx set_dest, dest1, dest2;
2561 set_dest = operands[0];
2563 dest1 = gen_df_reg (set_dest, 0);
2564 dest2 = gen_df_reg (set_dest, 1);
2566 /* Now output, ordering such that we don't clobber any registers
2567 mentioned in the address. */
2568 if (reg_overlap_mentioned_p (dest1, word1))
2571 emit_insn (gen_movdf (dest2, word1));
2572 emit_insn (gen_movdf (dest1, word0));
2576 emit_insn (gen_movdf (dest1, word0));
2577 emit_insn (gen_movdf (dest2, word1));
2583 [(set (match_operand:TF 0 "memory_operand" "")
2584 (match_operand:TF 1 "register_operand" ""))]
2586 && offsettable_memref_p (operands[0])
2588 || ! TARGET_HARD_QUAD
2589 || ! fp_register_operand (operands[1], TFmode)))"
2590 [(clobber (const_int 0))]
2592 rtx set_src = operands[1];
2594 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2595 gen_df_reg (set_src, 0)));
2596 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2597 gen_df_reg (set_src, 1)));
2602 ;; SPARC-V9 conditional move instructions
2604 ;; We can handle larger constants here for some flavors, but for now we keep
2605 ;; it simple and only allow those constants supported by all flavors.
2606 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2607 ;; 3 contains the constant if one is present, but we handle either for
2608 ;; generality (sparc.c puts a constant in operand 2).
2610 (define_expand "mov<I:mode>cc"
2611 [(set (match_operand:I 0 "register_operand" "")
2612 (if_then_else:I (match_operand 1 "comparison_operator" "")
2613 (match_operand:I 2 "arith10_operand" "")
2614 (match_operand:I 3 "arith10_operand" "")))]
2615 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2619 if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64)
2622 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2624 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2625 GET_CODE (operands[1]));
2627 if (XEXP (operands[1], 1) == const0_rtx
2628 && GET_CODE (XEXP (operands[1], 0)) == REG
2629 && GET_MODE (XEXP (operands[1], 0)) == DImode
2630 && v9_regcmp_p (GET_CODE (operands[1])))
2631 cc_reg = XEXP (operands[1], 0);
2633 cc_reg = gen_compare_reg (operands[1]);
2636 = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg,
2640 (define_expand "mov<F:mode>cc"
2641 [(set (match_operand:F 0 "register_operand" "")
2642 (if_then_else:F (match_operand 1 "comparison_operator" "")
2643 (match_operand:F 2 "register_operand" "")
2644 (match_operand:F 3 "register_operand" "")))]
2645 "TARGET_V9 && TARGET_FPU"
2649 if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64)
2652 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2654 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2655 GET_CODE (operands[1]));
2657 if (XEXP (operands[1], 1) == const0_rtx
2658 && GET_CODE (XEXP (operands[1], 0)) == REG
2659 && GET_MODE (XEXP (operands[1], 0)) == DImode
2660 && v9_regcmp_p (GET_CODE (operands[1])))
2661 cc_reg = XEXP (operands[1], 0);
2663 cc_reg = gen_compare_reg (operands[1]);
2666 = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg,
2670 ;; Conditional move define_insns
2672 (define_insn "*mov<I:mode>_cc_v9"
2673 [(set (match_operand:I 0 "register_operand" "=r,r")
2674 (if_then_else:I (match_operator 1 "comparison_operator"
2675 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2677 (match_operand:I 3 "arith11_operand" "rL,0")
2678 (match_operand:I 4 "arith11_operand" "0,rL")))]
2679 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2682 mov%c1\t%x2, %4, %0"
2683 [(set_attr "type" "cmove")])
2685 (define_insn "*mov<I:mode>_cc_reg_sp64"
2686 [(set (match_operand:I 0 "register_operand" "=r,r")
2687 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2688 [(match_operand:DI 2 "register_operand" "r,r")
2690 (match_operand:I 3 "arith10_operand" "rM,0")
2691 (match_operand:I 4 "arith10_operand" "0,rM")))]
2694 movr%D1\t%2, %r3, %0
2695 movr%d1\t%2, %r4, %0"
2696 [(set_attr "type" "cmove")])
2698 (define_insn "*movsf_cc_v9"
2699 [(set (match_operand:SF 0 "register_operand" "=f,f")
2700 (if_then_else:SF (match_operator 1 "comparison_operator"
2701 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2703 (match_operand:SF 3 "register_operand" "f,0")
2704 (match_operand:SF 4 "register_operand" "0,f")))]
2705 "TARGET_V9 && TARGET_FPU"
2707 fmovs%C1\t%x2, %3, %0
2708 fmovs%c1\t%x2, %4, %0"
2709 [(set_attr "type" "fpcmove")])
2711 (define_insn "*movsf_cc_reg_sp64"
2712 [(set (match_operand:SF 0 "register_operand" "=f,f")
2713 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2714 [(match_operand:DI 2 "register_operand" "r,r")
2716 (match_operand:SF 3 "register_operand" "f,0")
2717 (match_operand:SF 4 "register_operand" "0,f")))]
2718 "TARGET_ARCH64 && TARGET_FPU"
2720 fmovrs%D1\t%2, %3, %0
2721 fmovrs%d1\t%2, %4, %0"
2722 [(set_attr "type" "fpcrmove")])
2724 ;; Named because invoked by movtf_cc_v9
2725 (define_insn "movdf_cc_v9"
2726 [(set (match_operand:DF 0 "register_operand" "=e,e")
2727 (if_then_else:DF (match_operator 1 "comparison_operator"
2728 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2730 (match_operand:DF 3 "register_operand" "e,0")
2731 (match_operand:DF 4 "register_operand" "0,e")))]
2732 "TARGET_V9 && TARGET_FPU"
2734 fmovd%C1\t%x2, %3, %0
2735 fmovd%c1\t%x2, %4, %0"
2736 [(set_attr "type" "fpcmove")
2737 (set_attr "fptype" "double")])
2739 ;; Named because invoked by movtf_cc_reg_sp64
2740 (define_insn "movdf_cc_reg_sp64"
2741 [(set (match_operand:DF 0 "register_operand" "=e,e")
2742 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2743 [(match_operand:DI 2 "register_operand" "r,r")
2745 (match_operand:DF 3 "register_operand" "e,0")
2746 (match_operand:DF 4 "register_operand" "0,e")))]
2747 "TARGET_ARCH64 && TARGET_FPU"
2749 fmovrd%D1\t%2, %3, %0
2750 fmovrd%d1\t%2, %4, %0"
2751 [(set_attr "type" "fpcrmove")
2752 (set_attr "fptype" "double")])
2754 (define_insn "*movtf_cc_hq_v9"
2755 [(set (match_operand:TF 0 "register_operand" "=e,e")
2756 (if_then_else:TF (match_operator 1 "comparison_operator"
2757 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2759 (match_operand:TF 3 "register_operand" "e,0")
2760 (match_operand:TF 4 "register_operand" "0,e")))]
2761 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2763 fmovq%C1\t%x2, %3, %0
2764 fmovq%c1\t%x2, %4, %0"
2765 [(set_attr "type" "fpcmove")])
2767 (define_insn "*movtf_cc_reg_hq_sp64"
2768 [(set (match_operand:TF 0 "register_operand" "=e,e")
2769 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2770 [(match_operand:DI 2 "register_operand" "r,r")
2772 (match_operand:TF 3 "register_operand" "e,0")
2773 (match_operand:TF 4 "register_operand" "0,e")))]
2774 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2776 fmovrq%D1\t%2, %3, %0
2777 fmovrq%d1\t%2, %4, %0"
2778 [(set_attr "type" "fpcrmove")])
2780 (define_insn_and_split "*movtf_cc_v9"
2781 [(set (match_operand:TF 0 "register_operand" "=e,e")
2782 (if_then_else:TF (match_operator 1 "comparison_operator"
2783 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2785 (match_operand:TF 3 "register_operand" "e,0")
2786 (match_operand:TF 4 "register_operand" "0,e")))]
2787 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2789 "&& reload_completed"
2790 [(clobber (const_int 0))]
2792 rtx set_dest = operands[0];
2793 rtx set_srca = operands[3];
2794 rtx set_srcb = operands[4];
2795 int third = rtx_equal_p (set_dest, set_srca);
2797 rtx srca1, srca2, srcb1, srcb2;
2799 dest1 = gen_df_reg (set_dest, 0);
2800 dest2 = gen_df_reg (set_dest, 1);
2801 srca1 = gen_df_reg (set_srca, 0);
2802 srca2 = gen_df_reg (set_srca, 1);
2803 srcb1 = gen_df_reg (set_srcb, 0);
2804 srcb2 = gen_df_reg (set_srcb, 1);
2806 /* Now emit using the real source and destination we found, swapping
2807 the order if we detect overlap. */
2808 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2809 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2811 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2812 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2816 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2817 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2821 [(set_attr "length" "2")])
2823 (define_insn_and_split "*movtf_cc_reg_sp64"
2824 [(set (match_operand:TF 0 "register_operand" "=e,e")
2825 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2826 [(match_operand:DI 2 "register_operand" "r,r")
2828 (match_operand:TF 3 "register_operand" "e,0")
2829 (match_operand:TF 4 "register_operand" "0,e")))]
2830 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2832 "&& reload_completed"
2833 [(clobber (const_int 0))]
2835 rtx set_dest = operands[0];
2836 rtx set_srca = operands[3];
2837 rtx set_srcb = operands[4];
2838 int third = rtx_equal_p (set_dest, set_srca);
2840 rtx srca1, srca2, srcb1, srcb2;
2842 dest1 = gen_df_reg (set_dest, 0);
2843 dest2 = gen_df_reg (set_dest, 1);
2844 srca1 = gen_df_reg (set_srca, 0);
2845 srca2 = gen_df_reg (set_srca, 1);
2846 srcb1 = gen_df_reg (set_srcb, 0);
2847 srcb2 = gen_df_reg (set_srcb, 1);
2849 /* Now emit using the real source and destination we found, swapping
2850 the order if we detect overlap. */
2851 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2852 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2854 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2855 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2859 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2860 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2864 [(set_attr "length" "2")])
2867 ;; Zero-extension instructions
2869 ;; These patterns originally accepted general_operands, however, slightly
2870 ;; better code is generated by only accepting register_operands, and then
2871 ;; letting combine generate the ldu[hb] insns.
2873 (define_expand "zero_extendhisi2"
2874 [(set (match_operand:SI 0 "register_operand" "")
2875 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2878 rtx temp = gen_reg_rtx (SImode);
2879 rtx shift_16 = GEN_INT (16);
2880 int op1_subbyte = 0;
2882 if (GET_CODE (operand1) == SUBREG)
2884 op1_subbyte = SUBREG_BYTE (operand1);
2885 op1_subbyte /= GET_MODE_SIZE (SImode);
2886 op1_subbyte *= GET_MODE_SIZE (SImode);
2887 operand1 = XEXP (operand1, 0);
2890 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2892 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2896 (define_insn "*zero_extendhisi2_insn"
2897 [(set (match_operand:SI 0 "register_operand" "=r")
2898 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2901 [(set_attr "type" "load")
2902 (set_attr "us3load_type" "3cycle")])
2904 (define_expand "zero_extendqihi2"
2905 [(set (match_operand:HI 0 "register_operand" "")
2906 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2910 (define_insn "*zero_extendqihi2_insn"
2911 [(set (match_operand:HI 0 "register_operand" "=r,r")
2912 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2913 "GET_CODE (operands[1]) != CONST_INT"
2917 [(set_attr "type" "*,load")
2918 (set_attr "us3load_type" "*,3cycle")])
2920 (define_expand "zero_extendqisi2"
2921 [(set (match_operand:SI 0 "register_operand" "")
2922 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2926 (define_insn "*zero_extendqisi2_insn"
2927 [(set (match_operand:SI 0 "register_operand" "=r,r")
2928 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2929 "GET_CODE (operands[1]) != CONST_INT"
2933 [(set_attr "type" "*,load")
2934 (set_attr "us3load_type" "*,3cycle")])
2936 (define_expand "zero_extendqidi2"
2937 [(set (match_operand:DI 0 "register_operand" "")
2938 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2942 (define_insn "*zero_extendqidi2_insn"
2943 [(set (match_operand:DI 0 "register_operand" "=r,r")
2944 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2945 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2949 [(set_attr "type" "*,load")
2950 (set_attr "us3load_type" "*,3cycle")])
2952 (define_expand "zero_extendhidi2"
2953 [(set (match_operand:DI 0 "register_operand" "")
2954 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2957 rtx temp = gen_reg_rtx (DImode);
2958 rtx shift_48 = GEN_INT (48);
2959 int op1_subbyte = 0;
2961 if (GET_CODE (operand1) == SUBREG)
2963 op1_subbyte = SUBREG_BYTE (operand1);
2964 op1_subbyte /= GET_MODE_SIZE (DImode);
2965 op1_subbyte *= GET_MODE_SIZE (DImode);
2966 operand1 = XEXP (operand1, 0);
2969 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2971 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2975 (define_insn "*zero_extendhidi2_insn"
2976 [(set (match_operand:DI 0 "register_operand" "=r")
2977 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2980 [(set_attr "type" "load")
2981 (set_attr "us3load_type" "3cycle")])
2983 ;; ??? Write truncdisi pattern using sra?
2985 (define_expand "zero_extendsidi2"
2986 [(set (match_operand:DI 0 "register_operand" "")
2987 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2991 (define_insn "*zero_extendsidi2_insn_sp64"
2992 [(set (match_operand:DI 0 "register_operand" "=r,r")
2993 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2994 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2998 [(set_attr "type" "shift,load")])
3000 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3001 [(set (match_operand:DI 0 "register_operand" "=r")
3002 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3005 "&& reload_completed"
3006 [(set (match_dup 2) (match_dup 3))
3007 (set (match_dup 4) (match_dup 5))]
3011 dest1 = gen_highpart (SImode, operands[0]);
3012 dest2 = gen_lowpart (SImode, operands[0]);
3014 /* Swap the order in case of overlap. */
3015 if (REGNO (dest1) == REGNO (operands[1]))
3017 operands[2] = dest2;
3018 operands[3] = operands[1];
3019 operands[4] = dest1;
3020 operands[5] = const0_rtx;
3024 operands[2] = dest1;
3025 operands[3] = const0_rtx;
3026 operands[4] = dest2;
3027 operands[5] = operands[1];
3030 [(set_attr "length" "2")])
3032 ;; Simplify comparisons of extended values.
3034 (define_insn "*cmp_zero_extendqisi2"
3035 [(set (reg:CC CC_REG)
3036 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3039 "andcc\t%0, 0xff, %%g0"
3040 [(set_attr "type" "compare")])
3042 (define_insn "*cmp_zero_qi"
3043 [(set (reg:CC CC_REG)
3044 (compare:CC (match_operand:QI 0 "register_operand" "r")
3047 "andcc\t%0, 0xff, %%g0"
3048 [(set_attr "type" "compare")])
3050 (define_insn "*cmp_zero_extendqisi2_set"
3051 [(set (reg:CC CC_REG)
3052 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3054 (set (match_operand:SI 0 "register_operand" "=r")
3055 (zero_extend:SI (match_dup 1)))]
3057 "andcc\t%1, 0xff, %0"
3058 [(set_attr "type" "compare")])
3060 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3061 [(set (reg:CC CC_REG)
3062 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3065 (set (match_operand:SI 0 "register_operand" "=r")
3066 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3068 "andcc\t%1, 0xff, %0"
3069 [(set_attr "type" "compare")])
3071 (define_insn "*cmp_zero_extendqidi2"
3072 [(set (reg:CCX CC_REG)
3073 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3076 "andcc\t%0, 0xff, %%g0"
3077 [(set_attr "type" "compare")])
3079 (define_insn "*cmp_zero_qi_sp64"
3080 [(set (reg:CCX CC_REG)
3081 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3084 "andcc\t%0, 0xff, %%g0"
3085 [(set_attr "type" "compare")])
3087 (define_insn "*cmp_zero_extendqidi2_set"
3088 [(set (reg:CCX CC_REG)
3089 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3091 (set (match_operand:DI 0 "register_operand" "=r")
3092 (zero_extend:DI (match_dup 1)))]
3094 "andcc\t%1, 0xff, %0"
3095 [(set_attr "type" "compare")])
3097 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3098 [(set (reg:CCX CC_REG)
3099 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3102 (set (match_operand:DI 0 "register_operand" "=r")
3103 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3105 "andcc\t%1, 0xff, %0"
3106 [(set_attr "type" "compare")])
3108 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3110 (define_insn "*cmp_siqi_trunc"
3111 [(set (reg:CC CC_REG)
3112 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3115 "andcc\t%0, 0xff, %%g0"
3116 [(set_attr "type" "compare")])
3118 (define_insn "*cmp_siqi_trunc_set"
3119 [(set (reg:CC CC_REG)
3120 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3122 (set (match_operand:QI 0 "register_operand" "=r")
3123 (subreg:QI (match_dup 1) 3))]
3125 "andcc\t%1, 0xff, %0"
3126 [(set_attr "type" "compare")])
3128 (define_insn "*cmp_diqi_trunc"
3129 [(set (reg:CC CC_REG)
3130 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3133 "andcc\t%0, 0xff, %%g0"
3134 [(set_attr "type" "compare")])
3136 (define_insn "*cmp_diqi_trunc_set"
3137 [(set (reg:CC CC_REG)
3138 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3140 (set (match_operand:QI 0 "register_operand" "=r")
3141 (subreg:QI (match_dup 1) 7))]
3143 "andcc\t%1, 0xff, %0"
3144 [(set_attr "type" "compare")])
3147 ;; Sign-extension instructions
3149 ;; These patterns originally accepted general_operands, however, slightly
3150 ;; better code is generated by only accepting register_operands, and then
3151 ;; letting combine generate the lds[hb] insns.
3153 (define_expand "extendhisi2"
3154 [(set (match_operand:SI 0 "register_operand" "")
3155 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3158 rtx temp = gen_reg_rtx (SImode);
3159 rtx shift_16 = GEN_INT (16);
3160 int op1_subbyte = 0;
3162 if (GET_CODE (operand1) == SUBREG)
3164 op1_subbyte = SUBREG_BYTE (operand1);
3165 op1_subbyte /= GET_MODE_SIZE (SImode);
3166 op1_subbyte *= GET_MODE_SIZE (SImode);
3167 operand1 = XEXP (operand1, 0);
3170 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3172 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3176 (define_insn "*sign_extendhisi2_insn"
3177 [(set (match_operand:SI 0 "register_operand" "=r")
3178 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3181 [(set_attr "type" "sload")
3182 (set_attr "us3load_type" "3cycle")])
3184 (define_expand "extendqihi2"
3185 [(set (match_operand:HI 0 "register_operand" "")
3186 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3189 rtx temp = gen_reg_rtx (SImode);
3190 rtx shift_24 = GEN_INT (24);
3191 int op1_subbyte = 0;
3192 int op0_subbyte = 0;
3194 if (GET_CODE (operand1) == SUBREG)
3196 op1_subbyte = SUBREG_BYTE (operand1);
3197 op1_subbyte /= GET_MODE_SIZE (SImode);
3198 op1_subbyte *= GET_MODE_SIZE (SImode);
3199 operand1 = XEXP (operand1, 0);
3201 if (GET_CODE (operand0) == SUBREG)
3203 op0_subbyte = SUBREG_BYTE (operand0);
3204 op0_subbyte /= GET_MODE_SIZE (SImode);
3205 op0_subbyte *= GET_MODE_SIZE (SImode);
3206 operand0 = XEXP (operand0, 0);
3208 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3210 if (GET_MODE (operand0) != SImode)
3211 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3212 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3216 (define_insn "*sign_extendqihi2_insn"
3217 [(set (match_operand:HI 0 "register_operand" "=r")
3218 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3221 [(set_attr "type" "sload")
3222 (set_attr "us3load_type" "3cycle")])
3224 (define_expand "extendqisi2"
3225 [(set (match_operand:SI 0 "register_operand" "")
3226 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3229 rtx temp = gen_reg_rtx (SImode);
3230 rtx shift_24 = GEN_INT (24);
3231 int op1_subbyte = 0;
3233 if (GET_CODE (operand1) == SUBREG)
3235 op1_subbyte = SUBREG_BYTE (operand1);
3236 op1_subbyte /= GET_MODE_SIZE (SImode);
3237 op1_subbyte *= GET_MODE_SIZE (SImode);
3238 operand1 = XEXP (operand1, 0);
3241 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3243 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3247 (define_insn "*sign_extendqisi2_insn"
3248 [(set (match_operand:SI 0 "register_operand" "=r")
3249 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3252 [(set_attr "type" "sload")
3253 (set_attr "us3load_type" "3cycle")])
3255 (define_expand "extendqidi2"
3256 [(set (match_operand:DI 0 "register_operand" "")
3257 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3260 rtx temp = gen_reg_rtx (DImode);
3261 rtx shift_56 = GEN_INT (56);
3262 int op1_subbyte = 0;
3264 if (GET_CODE (operand1) == SUBREG)
3266 op1_subbyte = SUBREG_BYTE (operand1);
3267 op1_subbyte /= GET_MODE_SIZE (DImode);
3268 op1_subbyte *= GET_MODE_SIZE (DImode);
3269 operand1 = XEXP (operand1, 0);
3272 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3274 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3278 (define_insn "*sign_extendqidi2_insn"
3279 [(set (match_operand:DI 0 "register_operand" "=r")
3280 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3283 [(set_attr "type" "sload")
3284 (set_attr "us3load_type" "3cycle")])
3286 (define_expand "extendhidi2"
3287 [(set (match_operand:DI 0 "register_operand" "")
3288 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3291 rtx temp = gen_reg_rtx (DImode);
3292 rtx shift_48 = GEN_INT (48);
3293 int op1_subbyte = 0;
3295 if (GET_CODE (operand1) == SUBREG)
3297 op1_subbyte = SUBREG_BYTE (operand1);
3298 op1_subbyte /= GET_MODE_SIZE (DImode);
3299 op1_subbyte *= GET_MODE_SIZE (DImode);
3300 operand1 = XEXP (operand1, 0);
3303 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3305 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3309 (define_insn "*sign_extendhidi2_insn"
3310 [(set (match_operand:DI 0 "register_operand" "=r")
3311 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3314 [(set_attr "type" "sload")
3315 (set_attr "us3load_type" "3cycle")])
3317 (define_expand "extendsidi2"
3318 [(set (match_operand:DI 0 "register_operand" "")
3319 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3323 (define_insn "*sign_extendsidi2_insn"
3324 [(set (match_operand:DI 0 "register_operand" "=r,r")
3325 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3330 [(set_attr "type" "shift,sload")
3331 (set_attr "us3load_type" "*,3cycle")])
3334 ;; Special pattern for optimizing bit-field compares. This is needed
3335 ;; because combine uses this as a canonical form.
3337 (define_insn "*cmp_zero_extract"
3338 [(set (reg:CC CC_REG)
3340 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3341 (match_operand:SI 1 "small_int_operand" "I")
3342 (match_operand:SI 2 "small_int_operand" "I"))
3344 "INTVAL (operands[2]) > 19"
3346 int len = INTVAL (operands[1]);
3347 int pos = 32 - INTVAL (operands[2]) - len;
3348 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3349 operands[1] = GEN_INT (mask);
3350 return "andcc\t%0, %1, %%g0";
3352 [(set_attr "type" "compare")])
3354 (define_insn "*cmp_zero_extract_sp64"
3355 [(set (reg:CCX CC_REG)
3357 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3358 (match_operand:SI 1 "small_int_operand" "I")
3359 (match_operand:SI 2 "small_int_operand" "I"))
3361 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3363 int len = INTVAL (operands[1]);
3364 int pos = 64 - INTVAL (operands[2]) - len;
3365 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3366 operands[1] = GEN_INT (mask);
3367 return "andcc\t%0, %1, %%g0";
3369 [(set_attr "type" "compare")])
3372 ;; Conversions between float, double and long double.
3374 (define_insn "extendsfdf2"
3375 [(set (match_operand:DF 0 "register_operand" "=e")
3377 (match_operand:SF 1 "register_operand" "f")))]
3380 [(set_attr "type" "fp")
3381 (set_attr "fptype" "double")])
3383 (define_expand "extendsftf2"
3384 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3386 (match_operand:SF 1 "register_operand" "")))]
3387 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3388 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3390 (define_insn "*extendsftf2_hq"
3391 [(set (match_operand:TF 0 "register_operand" "=e")
3393 (match_operand:SF 1 "register_operand" "f")))]
3394 "TARGET_FPU && TARGET_HARD_QUAD"
3396 [(set_attr "type" "fp")])
3398 (define_expand "extenddftf2"
3399 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3401 (match_operand:DF 1 "register_operand" "")))]
3402 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3403 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3405 (define_insn "*extenddftf2_hq"
3406 [(set (match_operand:TF 0 "register_operand" "=e")
3408 (match_operand:DF 1 "register_operand" "e")))]
3409 "TARGET_FPU && TARGET_HARD_QUAD"
3411 [(set_attr "type" "fp")])
3413 (define_insn "truncdfsf2"
3414 [(set (match_operand:SF 0 "register_operand" "=f")
3416 (match_operand:DF 1 "register_operand" "e")))]
3419 [(set_attr "type" "fp")
3420 (set_attr "fptype" "double")])
3422 (define_expand "trunctfsf2"
3423 [(set (match_operand:SF 0 "register_operand" "")
3425 (match_operand:TF 1 "general_operand" "")))]
3426 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3427 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3429 (define_insn "*trunctfsf2_hq"
3430 [(set (match_operand:SF 0 "register_operand" "=f")
3432 (match_operand:TF 1 "register_operand" "e")))]
3433 "TARGET_FPU && TARGET_HARD_QUAD"
3435 [(set_attr "type" "fp")])
3437 (define_expand "trunctfdf2"
3438 [(set (match_operand:DF 0 "register_operand" "")
3440 (match_operand:TF 1 "general_operand" "")))]
3441 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3442 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3444 (define_insn "*trunctfdf2_hq"
3445 [(set (match_operand:DF 0 "register_operand" "=e")
3447 (match_operand:TF 1 "register_operand" "e")))]
3448 "TARGET_FPU && TARGET_HARD_QUAD"
3450 [(set_attr "type" "fp")])
3453 ;; Conversion between fixed point and floating point.
3455 (define_insn "floatsisf2"
3456 [(set (match_operand:SF 0 "register_operand" "=f")
3457 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3460 [(set_attr "type" "fp")
3461 (set_attr "fptype" "double")])
3463 (define_insn "floatsidf2"
3464 [(set (match_operand:DF 0 "register_operand" "=e")
3465 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3468 [(set_attr "type" "fp")
3469 (set_attr "fptype" "double")])
3471 (define_expand "floatsitf2"
3472 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3473 (float:TF (match_operand:SI 1 "register_operand" "")))]
3474 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3475 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3477 (define_insn "*floatsitf2_hq"
3478 [(set (match_operand:TF 0 "register_operand" "=e")
3479 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3480 "TARGET_FPU && TARGET_HARD_QUAD"
3482 [(set_attr "type" "fp")])
3484 (define_expand "floatunssitf2"
3485 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3486 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3487 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3488 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3490 ;; Now the same for 64 bit sources.
3492 (define_insn "floatdisf2"
3493 [(set (match_operand:SF 0 "register_operand" "=f")
3494 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3495 "TARGET_V9 && TARGET_FPU"
3497 [(set_attr "type" "fp")
3498 (set_attr "fptype" "double")])
3500 (define_expand "floatunsdisf2"
3501 [(use (match_operand:SF 0 "register_operand" ""))
3502 (use (match_operand:DI 1 "general_operand" ""))]
3503 "TARGET_ARCH64 && TARGET_FPU"
3504 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3506 (define_insn "floatdidf2"
3507 [(set (match_operand:DF 0 "register_operand" "=e")
3508 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3509 "TARGET_V9 && TARGET_FPU"
3511 [(set_attr "type" "fp")
3512 (set_attr "fptype" "double")])
3514 (define_expand "floatunsdidf2"
3515 [(use (match_operand:DF 0 "register_operand" ""))
3516 (use (match_operand:DI 1 "general_operand" ""))]
3517 "TARGET_ARCH64 && TARGET_FPU"
3518 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3520 (define_expand "floatditf2"
3521 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3522 (float:TF (match_operand:DI 1 "register_operand" "")))]
3523 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3524 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3526 (define_insn "*floatditf2_hq"
3527 [(set (match_operand:TF 0 "register_operand" "=e")
3528 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3529 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3531 [(set_attr "type" "fp")])
3533 (define_expand "floatunsditf2"
3534 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3535 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3536 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3537 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3539 ;; Convert a float to an actual integer.
3540 ;; Truncation is performed as part of the conversion.
3542 (define_insn "fix_truncsfsi2"
3543 [(set (match_operand:SI 0 "register_operand" "=f")
3544 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3547 [(set_attr "type" "fp")
3548 (set_attr "fptype" "double")])
3550 (define_insn "fix_truncdfsi2"
3551 [(set (match_operand:SI 0 "register_operand" "=f")
3552 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3555 [(set_attr "type" "fp")
3556 (set_attr "fptype" "double")])
3558 (define_expand "fix_trunctfsi2"
3559 [(set (match_operand:SI 0 "register_operand" "")
3560 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3561 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3562 "emit_tfmode_cvt (FIX, operands); DONE;")
3564 (define_insn "*fix_trunctfsi2_hq"
3565 [(set (match_operand:SI 0 "register_operand" "=f")
3566 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3567 "TARGET_FPU && TARGET_HARD_QUAD"
3569 [(set_attr "type" "fp")])
3571 (define_expand "fixuns_trunctfsi2"
3572 [(set (match_operand:SI 0 "register_operand" "")
3573 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3574 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3575 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3577 ;; Now the same, for V9 targets
3579 (define_insn "fix_truncsfdi2"
3580 [(set (match_operand:DI 0 "register_operand" "=e")
3581 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3582 "TARGET_V9 && TARGET_FPU"
3584 [(set_attr "type" "fp")
3585 (set_attr "fptype" "double")])
3587 (define_expand "fixuns_truncsfdi2"
3588 [(use (match_operand:DI 0 "register_operand" ""))
3589 (use (match_operand:SF 1 "general_operand" ""))]
3590 "TARGET_ARCH64 && TARGET_FPU"
3591 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3593 (define_insn "fix_truncdfdi2"
3594 [(set (match_operand:DI 0 "register_operand" "=e")
3595 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3596 "TARGET_V9 && TARGET_FPU"
3598 [(set_attr "type" "fp")
3599 (set_attr "fptype" "double")])
3601 (define_expand "fixuns_truncdfdi2"
3602 [(use (match_operand:DI 0 "register_operand" ""))
3603 (use (match_operand:DF 1 "general_operand" ""))]
3604 "TARGET_ARCH64 && TARGET_FPU"
3605 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3607 (define_expand "fix_trunctfdi2"
3608 [(set (match_operand:DI 0 "register_operand" "")
3609 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3610 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3611 "emit_tfmode_cvt (FIX, operands); DONE;")
3613 (define_insn "*fix_trunctfdi2_hq"
3614 [(set (match_operand:DI 0 "register_operand" "=e")
3615 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3616 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3618 [(set_attr "type" "fp")])
3620 (define_expand "fixuns_trunctfdi2"
3621 [(set (match_operand:DI 0 "register_operand" "")
3622 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3623 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3624 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3627 ;; Integer addition/subtraction instructions.
3629 (define_expand "adddi3"
3630 [(set (match_operand:DI 0 "register_operand" "")
3631 (plus:DI (match_operand:DI 1 "register_operand" "")
3632 (match_operand:DI 2 "arith_double_add_operand" "")))]
3635 if (! TARGET_ARCH64)
3637 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3638 gen_rtx_SET (VOIDmode, operands[0],
3639 gen_rtx_PLUS (DImode, operands[1],
3641 gen_rtx_CLOBBER (VOIDmode,
3642 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3647 (define_insn_and_split "*adddi3_insn_sp32"
3648 [(set (match_operand:DI 0 "register_operand" "=r")
3649 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3650 (match_operand:DI 2 "arith_double_operand" "rHI")))
3651 (clobber (reg:CC CC_REG))]
3654 "&& reload_completed"
3655 [(parallel [(set (reg:CC_NOOV CC_REG)
3656 (compare:CC_NOOV (plus:SI (match_dup 4)
3660 (plus:SI (match_dup 4) (match_dup 5)))])
3662 (plus:SI (plus:SI (match_dup 7)
3664 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3666 operands[3] = gen_lowpart (SImode, operands[0]);
3667 operands[4] = gen_lowpart (SImode, operands[1]);
3668 operands[5] = gen_lowpart (SImode, operands[2]);
3669 operands[6] = gen_highpart (SImode, operands[0]);
3670 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3671 #if HOST_BITS_PER_WIDE_INT == 32
3672 if (GET_CODE (operands[2]) == CONST_INT)
3674 if (INTVAL (operands[2]) < 0)
3675 operands[8] = constm1_rtx;
3677 operands[8] = const0_rtx;
3681 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3683 [(set_attr "length" "2")])
3685 ;; LTU here means "carry set"
3687 [(set (match_operand:SI 0 "register_operand" "=r")
3688 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3689 (match_operand:SI 2 "arith_operand" "rI"))
3690 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3693 [(set_attr "type" "ialuX")])
3695 (define_insn_and_split "*addx_extend_sp32"
3696 [(set (match_operand:DI 0 "register_operand" "=r")
3697 (zero_extend:DI (plus:SI (plus:SI
3698 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3699 (match_operand:SI 2 "arith_operand" "rI"))
3700 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3703 "&& reload_completed"
3704 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3705 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3706 (set (match_dup 4) (const_int 0))]
3707 "operands[3] = gen_lowpart (SImode, operands[0]);
3708 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3709 [(set_attr "length" "2")])
3711 (define_insn "*addx_extend_sp64"
3712 [(set (match_operand:DI 0 "register_operand" "=r")
3713 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3714 (match_operand:SI 2 "arith_operand" "rI"))
3715 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3718 [(set_attr "type" "ialuX")])
3720 (define_insn_and_split "*adddi3_extend_sp32"
3721 [(set (match_operand:DI 0 "register_operand" "=r")
3722 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3723 (match_operand:DI 2 "register_operand" "r")))
3724 (clobber (reg:CC CC_REG))]
3727 "&& reload_completed"
3728 [(parallel [(set (reg:CC_NOOV CC_REG)
3729 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3731 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3733 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3734 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3735 "operands[3] = gen_lowpart (SImode, operands[2]);
3736 operands[4] = gen_highpart (SImode, operands[2]);
3737 operands[5] = gen_lowpart (SImode, operands[0]);
3738 operands[6] = gen_highpart (SImode, operands[0]);"
3739 [(set_attr "length" "2")])
3741 (define_insn "*adddi3_sp64"
3742 [(set (match_operand:DI 0 "register_operand" "=r,r")
3743 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3744 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3750 (define_insn "addsi3"
3751 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3752 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3753 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3758 fpadd32s\t%1, %2, %0"
3759 [(set_attr "type" "*,*,fga")
3760 (set_attr "fptype" "*,*,single")])
3762 (define_insn "*cmp_cc_plus"
3763 [(set (reg:CC_NOOV CC_REG)
3764 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3765 (match_operand:SI 1 "arith_operand" "rI"))
3768 "addcc\t%0, %1, %%g0"
3769 [(set_attr "type" "compare")])
3771 (define_insn "*cmp_ccx_plus"
3772 [(set (reg:CCX_NOOV CC_REG)
3773 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3774 (match_operand:DI 1 "arith_operand" "rI"))
3777 "addcc\t%0, %1, %%g0"
3778 [(set_attr "type" "compare")])
3780 (define_insn "*cmp_cc_plus_set"
3781 [(set (reg:CC_NOOV CC_REG)
3782 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3783 (match_operand:SI 2 "arith_operand" "rI"))
3785 (set (match_operand:SI 0 "register_operand" "=r")
3786 (plus:SI (match_dup 1) (match_dup 2)))]
3789 [(set_attr "type" "compare")])
3791 (define_insn "*cmp_ccx_plus_set"
3792 [(set (reg:CCX_NOOV CC_REG)
3793 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3794 (match_operand:DI 2 "arith_operand" "rI"))
3796 (set (match_operand:DI 0 "register_operand" "=r")
3797 (plus:DI (match_dup 1) (match_dup 2)))]
3800 [(set_attr "type" "compare")])
3802 (define_expand "subdi3"
3803 [(set (match_operand:DI 0 "register_operand" "")
3804 (minus:DI (match_operand:DI 1 "register_operand" "")
3805 (match_operand:DI 2 "arith_double_add_operand" "")))]
3808 if (! TARGET_ARCH64)
3810 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3811 gen_rtx_SET (VOIDmode, operands[0],
3812 gen_rtx_MINUS (DImode, operands[1],
3814 gen_rtx_CLOBBER (VOIDmode,
3815 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3820 (define_insn_and_split "*subdi3_insn_sp32"
3821 [(set (match_operand:DI 0 "register_operand" "=r")
3822 (minus:DI (match_operand:DI 1 "register_operand" "r")
3823 (match_operand:DI 2 "arith_double_operand" "rHI")))
3824 (clobber (reg:CC CC_REG))]
3827 "&& reload_completed"
3828 [(parallel [(set (reg:CC_NOOV CC_REG)
3829 (compare:CC_NOOV (minus:SI (match_dup 4)
3833 (minus:SI (match_dup 4) (match_dup 5)))])
3835 (minus:SI (minus:SI (match_dup 7)
3837 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3839 operands[3] = gen_lowpart (SImode, operands[0]);
3840 operands[4] = gen_lowpart (SImode, operands[1]);
3841 operands[5] = gen_lowpart (SImode, operands[2]);
3842 operands[6] = gen_highpart (SImode, operands[0]);
3843 operands[7] = gen_highpart (SImode, operands[1]);
3844 #if HOST_BITS_PER_WIDE_INT == 32
3845 if (GET_CODE (operands[2]) == CONST_INT)
3847 if (INTVAL (operands[2]) < 0)
3848 operands[8] = constm1_rtx;
3850 operands[8] = const0_rtx;
3854 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3856 [(set_attr "length" "2")])
3858 ;; LTU here means "carry set"
3860 [(set (match_operand:SI 0 "register_operand" "=r")
3861 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3862 (match_operand:SI 2 "arith_operand" "rI"))
3863 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3866 [(set_attr "type" "ialuX")])
3868 (define_insn "*subx_extend_sp64"
3869 [(set (match_operand:DI 0 "register_operand" "=r")
3870 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3871 (match_operand:SI 2 "arith_operand" "rI"))
3872 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3875 [(set_attr "type" "ialuX")])
3877 (define_insn_and_split "*subx_extend"
3878 [(set (match_operand:DI 0 "register_operand" "=r")
3879 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3880 (match_operand:SI 2 "arith_operand" "rI"))
3881 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3884 "&& reload_completed"
3885 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3886 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3887 (set (match_dup 4) (const_int 0))]
3888 "operands[3] = gen_lowpart (SImode, operands[0]);
3889 operands[4] = gen_highpart (SImode, operands[0]);"
3890 [(set_attr "length" "2")])
3892 (define_insn_and_split "*subdi3_extend_sp32"
3893 [(set (match_operand:DI 0 "register_operand" "=r")
3894 (minus:DI (match_operand:DI 1 "register_operand" "r")
3895 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3896 (clobber (reg:CC CC_REG))]
3899 "&& reload_completed"
3900 [(parallel [(set (reg:CC_NOOV CC_REG)
3901 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3903 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3905 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3906 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3907 "operands[3] = gen_lowpart (SImode, operands[1]);
3908 operands[4] = gen_highpart (SImode, operands[1]);
3909 operands[5] = gen_lowpart (SImode, operands[0]);
3910 operands[6] = gen_highpart (SImode, operands[0]);"
3911 [(set_attr "length" "2")])
3913 (define_insn "*subdi3_sp64"
3914 [(set (match_operand:DI 0 "register_operand" "=r,r")
3915 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3916 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3922 (define_insn "subsi3"
3923 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3924 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3925 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3930 fpsub32s\t%1, %2, %0"
3931 [(set_attr "type" "*,*,fga")
3932 (set_attr "fptype" "*,*,single")])
3934 (define_insn "*cmp_minus_cc"
3935 [(set (reg:CC_NOOV CC_REG)
3936 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3937 (match_operand:SI 1 "arith_operand" "rI"))
3940 "subcc\t%r0, %1, %%g0"
3941 [(set_attr "type" "compare")])
3943 (define_insn "*cmp_minus_ccx"
3944 [(set (reg:CCX_NOOV CC_REG)
3945 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3946 (match_operand:DI 1 "arith_operand" "rI"))
3949 "subcc\t%0, %1, %%g0"
3950 [(set_attr "type" "compare")])
3952 (define_insn "cmp_minus_cc_set"
3953 [(set (reg:CC_NOOV CC_REG)
3954 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3955 (match_operand:SI 2 "arith_operand" "rI"))
3957 (set (match_operand:SI 0 "register_operand" "=r")
3958 (minus:SI (match_dup 1) (match_dup 2)))]
3960 "subcc\t%r1, %2, %0"
3961 [(set_attr "type" "compare")])
3963 (define_insn "*cmp_minus_ccx_set"
3964 [(set (reg:CCX_NOOV CC_REG)
3965 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3966 (match_operand:DI 2 "arith_operand" "rI"))
3968 (set (match_operand:DI 0 "register_operand" "=r")
3969 (minus:DI (match_dup 1) (match_dup 2)))]
3972 [(set_attr "type" "compare")])
3975 ;; Integer multiply/divide instructions.
3977 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3978 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3980 (define_insn "mulsi3"
3981 [(set (match_operand:SI 0 "register_operand" "=r")
3982 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3983 (match_operand:SI 2 "arith_operand" "rI")))]
3986 [(set_attr "type" "imul")])
3988 (define_expand "muldi3"
3989 [(set (match_operand:DI 0 "register_operand" "")
3990 (mult:DI (match_operand:DI 1 "arith_operand" "")
3991 (match_operand:DI 2 "arith_operand" "")))]
3992 "TARGET_ARCH64 || TARGET_V8PLUS"
3996 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4001 (define_insn "*muldi3_sp64"
4002 [(set (match_operand:DI 0 "register_operand" "=r")
4003 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4004 (match_operand:DI 2 "arith_operand" "rI")))]
4007 [(set_attr "type" "imul")])
4009 ;; V8plus wide multiply.
4011 (define_insn "muldi3_v8plus"
4012 [(set (match_operand:DI 0 "register_operand" "=r,h")
4013 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4014 (match_operand:DI 2 "arith_operand" "rI,rI")))
4015 (clobber (match_scratch:SI 3 "=&h,X"))
4016 (clobber (match_scratch:SI 4 "=&h,X"))]
4018 "* return output_v8plus_mult (insn, operands, \"mulx\");"
4019 [(set_attr "type" "multi")
4020 (set_attr "length" "9,8")])
4022 (define_insn "*cmp_mul_set"
4023 [(set (reg:CC CC_REG)
4024 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4025 (match_operand:SI 2 "arith_operand" "rI"))
4027 (set (match_operand:SI 0 "register_operand" "=r")
4028 (mult:SI (match_dup 1) (match_dup 2)))]
4029 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4030 "smulcc\t%1, %2, %0"
4031 [(set_attr "type" "imul")])
4033 (define_expand "mulsidi3"
4034 [(set (match_operand:DI 0 "register_operand" "")
4035 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4036 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4039 if (CONSTANT_P (operands[2]))
4042 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4044 else if (TARGET_ARCH32)
4045 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4048 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4054 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4059 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4060 ;; registers can hold 64-bit values in the V8plus environment.
4062 (define_insn "mulsidi3_v8plus"
4063 [(set (match_operand:DI 0 "register_operand" "=h,r")
4064 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4065 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4066 (clobber (match_scratch:SI 3 "=X,&h"))]
4069 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4070 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4071 [(set_attr "type" "multi")
4072 (set_attr "length" "2,3")])
4075 (define_insn "const_mulsidi3_v8plus"
4076 [(set (match_operand:DI 0 "register_operand" "=h,r")
4077 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4078 (match_operand:DI 2 "small_int_operand" "I,I")))
4079 (clobber (match_scratch:SI 3 "=X,&h"))]
4082 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4083 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4084 [(set_attr "type" "multi")
4085 (set_attr "length" "2,3")])
4088 (define_insn "*mulsidi3_sp32"
4089 [(set (match_operand:DI 0 "register_operand" "=r")
4090 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4091 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4094 return TARGET_SPARCLET
4095 ? "smuld\t%1, %2, %L0"
4096 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4099 (if_then_else (eq_attr "isa" "sparclet")
4100 (const_string "imul") (const_string "multi")))
4101 (set (attr "length")
4102 (if_then_else (eq_attr "isa" "sparclet")
4103 (const_int 1) (const_int 2)))])
4105 (define_insn "*mulsidi3_sp64"
4106 [(set (match_operand:DI 0 "register_operand" "=r")
4107 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4108 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4109 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4111 [(set_attr "type" "imul")])
4113 ;; Extra pattern, because sign_extend of a constant isn't valid.
4116 (define_insn "const_mulsidi3_sp32"
4117 [(set (match_operand:DI 0 "register_operand" "=r")
4118 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4119 (match_operand:DI 2 "small_int_operand" "I")))]
4122 return TARGET_SPARCLET
4123 ? "smuld\t%1, %2, %L0"
4124 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4127 (if_then_else (eq_attr "isa" "sparclet")
4128 (const_string "imul") (const_string "multi")))
4129 (set (attr "length")
4130 (if_then_else (eq_attr "isa" "sparclet")
4131 (const_int 1) (const_int 2)))])
4133 (define_insn "const_mulsidi3_sp64"
4134 [(set (match_operand:DI 0 "register_operand" "=r")
4135 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4136 (match_operand:DI 2 "small_int_operand" "I")))]
4137 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4139 [(set_attr "type" "imul")])
4141 (define_expand "smulsi3_highpart"
4142 [(set (match_operand:SI 0 "register_operand" "")
4144 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4145 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4147 "TARGET_HARD_MUL && TARGET_ARCH32"
4149 if (CONSTANT_P (operands[2]))
4153 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4159 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4164 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4165 operands[2], GEN_INT (32)));
4171 (define_insn "smulsi3_highpart_v8plus"
4172 [(set (match_operand:SI 0 "register_operand" "=h,r")
4174 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4175 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4176 (match_operand:SI 3 "small_int_operand" "I,I"))))
4177 (clobber (match_scratch:SI 4 "=X,&h"))]
4180 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4181 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4182 [(set_attr "type" "multi")
4183 (set_attr "length" "2")])
4185 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4188 [(set (match_operand:SI 0 "register_operand" "=h,r")
4191 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4192 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4193 (match_operand:SI 3 "small_int_operand" "I,I"))
4195 (clobber (match_scratch:SI 4 "=X,&h"))]
4198 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4199 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4200 [(set_attr "type" "multi")
4201 (set_attr "length" "2")])
4204 (define_insn "const_smulsi3_highpart_v8plus"
4205 [(set (match_operand:SI 0 "register_operand" "=h,r")
4207 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4208 (match_operand:DI 2 "small_int_operand" "I,I"))
4209 (match_operand:SI 3 "small_int_operand" "I,I"))))
4210 (clobber (match_scratch:SI 4 "=X,&h"))]
4213 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4214 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4215 [(set_attr "type" "multi")
4216 (set_attr "length" "2")])
4219 (define_insn "*smulsi3_highpart_sp32"
4220 [(set (match_operand:SI 0 "register_operand" "=r")
4222 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4223 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4226 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4227 [(set_attr "type" "multi")
4228 (set_attr "length" "2")])
4231 (define_insn "const_smulsi3_highpart"
4232 [(set (match_operand:SI 0 "register_operand" "=r")
4234 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4235 (match_operand:DI 2 "small_int_operand" "i"))
4238 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4239 [(set_attr "type" "multi")
4240 (set_attr "length" "2")])
4242 (define_expand "umulsidi3"
4243 [(set (match_operand:DI 0 "register_operand" "")
4244 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4245 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4248 if (CONSTANT_P (operands[2]))
4251 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4253 else if (TARGET_ARCH32)
4254 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4257 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4263 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4269 (define_insn "umulsidi3_v8plus"
4270 [(set (match_operand:DI 0 "register_operand" "=h,r")
4271 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4272 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4273 (clobber (match_scratch:SI 3 "=X,&h"))]
4276 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4277 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4278 [(set_attr "type" "multi")
4279 (set_attr "length" "2,3")])
4282 (define_insn "*umulsidi3_sp32"
4283 [(set (match_operand:DI 0 "register_operand" "=r")
4284 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4285 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4288 return TARGET_SPARCLET
4289 ? "umuld\t%1, %2, %L0"
4290 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4293 (if_then_else (eq_attr "isa" "sparclet")
4294 (const_string "imul") (const_string "multi")))
4295 (set (attr "length")
4296 (if_then_else (eq_attr "isa" "sparclet")
4297 (const_int 1) (const_int 2)))])
4299 (define_insn "*umulsidi3_sp64"
4300 [(set (match_operand:DI 0 "register_operand" "=r")
4301 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4302 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4303 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4305 [(set_attr "type" "imul")])
4307 ;; Extra pattern, because sign_extend of a constant isn't valid.
4310 (define_insn "const_umulsidi3_sp32"
4311 [(set (match_operand:DI 0 "register_operand" "=r")
4312 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4313 (match_operand:DI 2 "uns_small_int_operand" "")))]
4316 return TARGET_SPARCLET
4317 ? "umuld\t%1, %s2, %L0"
4318 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4321 (if_then_else (eq_attr "isa" "sparclet")
4322 (const_string "imul") (const_string "multi")))
4323 (set (attr "length")
4324 (if_then_else (eq_attr "isa" "sparclet")
4325 (const_int 1) (const_int 2)))])
4327 (define_insn "const_umulsidi3_sp64"
4328 [(set (match_operand:DI 0 "register_operand" "=r")
4329 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4330 (match_operand:DI 2 "uns_small_int_operand" "")))]
4331 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4333 [(set_attr "type" "imul")])
4336 (define_insn "const_umulsidi3_v8plus"
4337 [(set (match_operand:DI 0 "register_operand" "=h,r")
4338 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4339 (match_operand:DI 2 "uns_small_int_operand" "")))
4340 (clobber (match_scratch:SI 3 "=X,h"))]
4343 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4344 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4345 [(set_attr "type" "multi")
4346 (set_attr "length" "2,3")])
4348 (define_expand "umulsi3_highpart"
4349 [(set (match_operand:SI 0 "register_operand" "")
4351 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4352 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4354 "TARGET_HARD_MUL && TARGET_ARCH32"
4356 if (CONSTANT_P (operands[2]))
4360 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4366 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4371 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4372 operands[2], GEN_INT (32)));
4378 (define_insn "umulsi3_highpart_v8plus"
4379 [(set (match_operand:SI 0 "register_operand" "=h,r")
4381 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4382 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4383 (match_operand:SI 3 "small_int_operand" "I,I"))))
4384 (clobber (match_scratch:SI 4 "=X,h"))]
4387 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4388 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4389 [(set_attr "type" "multi")
4390 (set_attr "length" "2")])
4393 (define_insn "const_umulsi3_highpart_v8plus"
4394 [(set (match_operand:SI 0 "register_operand" "=h,r")
4396 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4397 (match_operand:DI 2 "uns_small_int_operand" ""))
4398 (match_operand:SI 3 "small_int_operand" "I,I"))))
4399 (clobber (match_scratch:SI 4 "=X,h"))]
4402 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4403 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4404 [(set_attr "type" "multi")
4405 (set_attr "length" "2")])
4408 (define_insn "*umulsi3_highpart_sp32"
4409 [(set (match_operand:SI 0 "register_operand" "=r")
4411 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4412 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4415 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4416 [(set_attr "type" "multi")
4417 (set_attr "length" "2")])
4420 (define_insn "const_umulsi3_highpart"
4421 [(set (match_operand:SI 0 "register_operand" "=r")
4423 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4424 (match_operand:DI 2 "uns_small_int_operand" ""))
4427 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4428 [(set_attr "type" "multi")
4429 (set_attr "length" "2")])
4431 (define_expand "divsi3"
4432 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4433 (div:SI (match_operand:SI 1 "register_operand" "")
4434 (match_operand:SI 2 "input_operand" "")))
4435 (clobber (match_scratch:SI 3 ""))])]
4436 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4440 operands[3] = gen_reg_rtx(SImode);
4441 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4442 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4448 ;; The V8 architecture specifies that there must be at least 3 instructions
4449 ;; between a write to the Y register and a use of it for correct results.
4450 ;; We try to fill one of them with a simple constant or a memory load.
4452 (define_insn "divsi3_sp32"
4453 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4454 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4455 (match_operand:SI 2 "input_operand" "rI,K,m")))
4456 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4457 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4459 output_asm_insn ("sra\t%1, 31, %3", operands);
4460 output_asm_insn ("wr\t%3, 0, %%y", operands);
4462 switch (which_alternative)
4466 return "sdiv\t%1, %2, %0";
4468 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4471 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4473 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4476 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4478 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4483 [(set_attr "type" "multi")
4484 (set (attr "length")
4485 (if_then_else (eq_attr "isa" "v9")
4486 (const_int 4) (const_int 6)))])
4488 (define_insn "divsi3_sp64"
4489 [(set (match_operand:SI 0 "register_operand" "=r")
4490 (div:SI (match_operand:SI 1 "register_operand" "r")
4491 (match_operand:SI 2 "input_operand" "rI")))
4492 (use (match_operand:SI 3 "register_operand" "r"))]
4493 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4494 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4495 [(set_attr "type" "multi")
4496 (set_attr "length" "2")])
4498 (define_insn "divdi3"
4499 [(set (match_operand:DI 0 "register_operand" "=r")
4500 (div:DI (match_operand:DI 1 "register_operand" "r")
4501 (match_operand:DI 2 "arith_operand" "rI")))]
4504 [(set_attr "type" "idiv")])
4506 (define_insn "*cmp_sdiv_cc_set"
4507 [(set (reg:CC CC_REG)
4508 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4509 (match_operand:SI 2 "arith_operand" "rI"))
4511 (set (match_operand:SI 0 "register_operand" "=r")
4512 (div:SI (match_dup 1) (match_dup 2)))
4513 (clobber (match_scratch:SI 3 "=&r"))]
4514 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4516 output_asm_insn ("sra\t%1, 31, %3", operands);
4517 output_asm_insn ("wr\t%3, 0, %%y", operands);
4520 return "sdivcc\t%1, %2, %0";
4522 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4524 [(set_attr "type" "multi")
4525 (set (attr "length")
4526 (if_then_else (eq_attr "isa" "v9")
4527 (const_int 3) (const_int 6)))])
4530 (define_expand "udivsi3"
4531 [(set (match_operand:SI 0 "register_operand" "")
4532 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4533 (match_operand:SI 2 "input_operand" "")))]
4534 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4537 ;; The V8 architecture specifies that there must be at least 3 instructions
4538 ;; between a write to the Y register and a use of it for correct results.
4539 ;; We try to fill one of them with a simple constant or a memory load.
4541 (define_insn "udivsi3_sp32"
4542 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4543 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4544 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4545 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4547 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4549 switch (which_alternative)
4553 return "udiv\t%1, %2, %0";
4555 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4558 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4560 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4563 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4565 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4568 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4570 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4575 [(set_attr "type" "multi")
4576 (set (attr "length")
4577 (if_then_else (eq_attr "isa" "v9")
4578 (const_int 3) (const_int 5)))])
4580 (define_insn "udivsi3_sp64"
4581 [(set (match_operand:SI 0 "register_operand" "=r")
4582 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4583 (match_operand:SI 2 "input_operand" "rI")))]
4584 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4585 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4586 [(set_attr "type" "multi")
4587 (set_attr "length" "2")])
4589 (define_insn "udivdi3"
4590 [(set (match_operand:DI 0 "register_operand" "=r")
4591 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4592 (match_operand:DI 2 "arith_operand" "rI")))]
4595 [(set_attr "type" "idiv")])
4597 (define_insn "*cmp_udiv_cc_set"
4598 [(set (reg:CC CC_REG)
4599 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4600 (match_operand:SI 2 "arith_operand" "rI"))
4602 (set (match_operand:SI 0 "register_operand" "=r")
4603 (udiv:SI (match_dup 1) (match_dup 2)))]
4604 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4606 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4609 return "udivcc\t%1, %2, %0";
4611 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4613 [(set_attr "type" "multi")
4614 (set (attr "length")
4615 (if_then_else (eq_attr "isa" "v9")
4616 (const_int 2) (const_int 5)))])
4618 ; sparclet multiply/accumulate insns
4620 (define_insn "*smacsi"
4621 [(set (match_operand:SI 0 "register_operand" "=r")
4622 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4623 (match_operand:SI 2 "arith_operand" "rI"))
4624 (match_operand:SI 3 "register_operand" "0")))]
4627 [(set_attr "type" "imul")])
4629 (define_insn "*smacdi"
4630 [(set (match_operand:DI 0 "register_operand" "=r")
4631 (plus:DI (mult:DI (sign_extend:DI
4632 (match_operand:SI 1 "register_operand" "%r"))
4634 (match_operand:SI 2 "register_operand" "r")))
4635 (match_operand:DI 3 "register_operand" "0")))]
4637 "smacd\t%1, %2, %L0"
4638 [(set_attr "type" "imul")])
4640 (define_insn "*umacdi"
4641 [(set (match_operand:DI 0 "register_operand" "=r")
4642 (plus:DI (mult:DI (zero_extend:DI
4643 (match_operand:SI 1 "register_operand" "%r"))
4645 (match_operand:SI 2 "register_operand" "r")))
4646 (match_operand:DI 3 "register_operand" "0")))]
4648 "umacd\t%1, %2, %L0"
4649 [(set_attr "type" "imul")])
4652 ;; Boolean instructions.
4654 ;; We define DImode `and' so with DImode `not' we can get
4655 ;; DImode `andn'. Other combinations are possible.
4657 (define_expand "and<V64I:mode>3"
4658 [(set (match_operand:V64I 0 "register_operand" "")
4659 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4660 (match_operand:V64I 2 "arith_double_operand" "")))]
4664 (define_insn "*and<V64I:mode>3_sp32"
4665 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4666 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4667 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4672 [(set_attr "type" "*,fga")
4673 (set_attr "length" "2,*")
4674 (set_attr "fptype" "*,double")])
4676 (define_insn "*and<V64I:mode>3_sp64"
4677 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4678 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4679 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4684 [(set_attr "type" "*,fga")
4685 (set_attr "fptype" "*,double")])
4687 (define_insn "and<V32I:mode>3"
4688 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4689 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4690 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4695 [(set_attr "type" "*,fga")
4696 (set_attr "fptype" "*,single")])
4699 [(set (match_operand:SI 0 "register_operand" "")
4700 (and:SI (match_operand:SI 1 "register_operand" "")
4701 (match_operand:SI 2 "const_compl_high_operand" "")))
4702 (clobber (match_operand:SI 3 "register_operand" ""))]
4704 [(set (match_dup 3) (match_dup 4))
4705 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4707 operands[4] = GEN_INT (~INTVAL (operands[2]));
4710 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4711 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4712 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4713 (match_operand:V64I 2 "register_operand" "r,b")))]
4717 fandnot1\t%1, %2, %0"
4718 "&& reload_completed
4719 && ((GET_CODE (operands[0]) == REG
4720 && REGNO (operands[0]) < 32)
4721 || (GET_CODE (operands[0]) == SUBREG
4722 && GET_CODE (SUBREG_REG (operands[0])) == REG
4723 && REGNO (SUBREG_REG (operands[0])) < 32))"
4724 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4725 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4726 "operands[3] = gen_highpart (SImode, operands[0]);
4727 operands[4] = gen_highpart (SImode, operands[1]);
4728 operands[5] = gen_highpart (SImode, operands[2]);
4729 operands[6] = gen_lowpart (SImode, operands[0]);
4730 operands[7] = gen_lowpart (SImode, operands[1]);
4731 operands[8] = gen_lowpart (SImode, operands[2]);"
4732 [(set_attr "type" "*,fga")
4733 (set_attr "length" "2,*")
4734 (set_attr "fptype" "*,double")])
4736 (define_insn "*and_not_<V64I:mode>_sp64"
4737 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4738 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4739 (match_operand:V64I 2 "register_operand" "r,b")))]
4743 fandnot1\t%1, %2, %0"
4744 [(set_attr "type" "*,fga")
4745 (set_attr "fptype" "*,double")])
4747 (define_insn "*and_not_<V32I:mode>"
4748 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4749 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4750 (match_operand:V32I 2 "register_operand" "r,d")))]
4754 fandnot1s\t%1, %2, %0"
4755 [(set_attr "type" "*,fga")
4756 (set_attr "fptype" "*,single")])
4758 (define_expand "ior<V64I:mode>3"
4759 [(set (match_operand:V64I 0 "register_operand" "")
4760 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4761 (match_operand:V64I 2 "arith_double_operand" "")))]
4765 (define_insn "*ior<V64I:mode>3_sp32"
4766 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4767 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4768 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4773 [(set_attr "type" "*,fga")
4774 (set_attr "length" "2,*")
4775 (set_attr "fptype" "*,double")])
4777 (define_insn "*ior<V64I:mode>3_sp64"
4778 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4779 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4780 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4785 [(set_attr "type" "*,fga")
4786 (set_attr "fptype" "*,double")])
4788 (define_insn "ior<V32I:mode>3"
4789 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4790 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4791 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4796 [(set_attr "type" "*,fga")
4797 (set_attr "fptype" "*,single")])
4800 [(set (match_operand:SI 0 "register_operand" "")
4801 (ior:SI (match_operand:SI 1 "register_operand" "")
4802 (match_operand:SI 2 "const_compl_high_operand" "")))
4803 (clobber (match_operand:SI 3 "register_operand" ""))]
4805 [(set (match_dup 3) (match_dup 4))
4806 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4808 operands[4] = GEN_INT (~INTVAL (operands[2]));
4811 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4812 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4813 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4814 (match_operand:V64I 2 "register_operand" "r,b")))]
4818 fornot1\t%1, %2, %0"
4819 "&& reload_completed
4820 && ((GET_CODE (operands[0]) == REG
4821 && REGNO (operands[0]) < 32)
4822 || (GET_CODE (operands[0]) == SUBREG
4823 && GET_CODE (SUBREG_REG (operands[0])) == REG
4824 && REGNO (SUBREG_REG (operands[0])) < 32))"
4825 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4826 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4827 "operands[3] = gen_highpart (SImode, operands[0]);
4828 operands[4] = gen_highpart (SImode, operands[1]);
4829 operands[5] = gen_highpart (SImode, operands[2]);
4830 operands[6] = gen_lowpart (SImode, operands[0]);
4831 operands[7] = gen_lowpart (SImode, operands[1]);
4832 operands[8] = gen_lowpart (SImode, operands[2]);"
4833 [(set_attr "type" "*,fga")
4834 (set_attr "length" "2,*")
4835 (set_attr "fptype" "*,double")])
4837 (define_insn "*or_not_<V64I:mode>_sp64"
4838 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4839 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4840 (match_operand:V64I 2 "register_operand" "r,b")))]
4844 fornot1\t%1, %2, %0"
4845 [(set_attr "type" "*,fga")
4846 (set_attr "fptype" "*,double")])
4848 (define_insn "*or_not_<V32I:mode>"
4849 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4850 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4851 (match_operand:V32I 2 "register_operand" "r,d")))]
4855 fornot1s\t%1, %2, %0"
4856 [(set_attr "type" "*,fga")
4857 (set_attr "fptype" "*,single")])
4859 (define_expand "xor<V64I:mode>3"
4860 [(set (match_operand:V64I 0 "register_operand" "")
4861 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4862 (match_operand:V64I 2 "arith_double_operand" "")))]
4866 (define_insn "*xor<V64I:mode>3_sp32"
4867 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4868 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4869 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4874 [(set_attr "type" "*,fga")
4875 (set_attr "length" "2,*")
4876 (set_attr "fptype" "*,double")])
4878 (define_insn "*xor<V64I:mode>3_sp64"
4879 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4880 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4881 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4886 [(set_attr "type" "*,fga")
4887 (set_attr "fptype" "*,double")])
4889 (define_insn "xor<V32I:mode>3"
4890 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4891 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4892 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4897 [(set_attr "type" "*,fga")
4898 (set_attr "fptype" "*,single")])
4901 [(set (match_operand:SI 0 "register_operand" "")
4902 (xor:SI (match_operand:SI 1 "register_operand" "")
4903 (match_operand:SI 2 "const_compl_high_operand" "")))
4904 (clobber (match_operand:SI 3 "register_operand" ""))]
4906 [(set (match_dup 3) (match_dup 4))
4907 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4909 operands[4] = GEN_INT (~INTVAL (operands[2]));
4913 [(set (match_operand:SI 0 "register_operand" "")
4914 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4915 (match_operand:SI 2 "const_compl_high_operand" ""))))
4916 (clobber (match_operand:SI 3 "register_operand" ""))]
4918 [(set (match_dup 3) (match_dup 4))
4919 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4921 operands[4] = GEN_INT (~INTVAL (operands[2]));
4924 ;; Split DImode logical operations requiring two instructions.
4926 [(set (match_operand:V64I 0 "register_operand" "")
4927 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4928 [(match_operand:V64I 2 "register_operand" "")
4929 (match_operand:V64I 3 "arith_double_operand" "")]))]
4932 && ((GET_CODE (operands[0]) == REG
4933 && REGNO (operands[0]) < 32)
4934 || (GET_CODE (operands[0]) == SUBREG
4935 && GET_CODE (SUBREG_REG (operands[0])) == REG
4936 && REGNO (SUBREG_REG (operands[0])) < 32))"
4937 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4938 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4940 operands[4] = gen_highpart (SImode, operands[0]);
4941 operands[5] = gen_lowpart (SImode, operands[0]);
4942 operands[6] = gen_highpart (SImode, operands[2]);
4943 operands[7] = gen_lowpart (SImode, operands[2]);
4944 #if HOST_BITS_PER_WIDE_INT == 32
4945 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4947 if (INTVAL (operands[3]) < 0)
4948 operands[8] = constm1_rtx;
4950 operands[8] = const0_rtx;
4954 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4955 operands[9] = gen_lowpart (SImode, operands[3]);
4958 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4959 ;; Combine now canonicalizes to the rightmost expression.
4960 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4961 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4962 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4963 (match_operand:V64I 2 "register_operand" "r,b"))))]
4968 "&& reload_completed
4969 && ((GET_CODE (operands[0]) == REG
4970 && REGNO (operands[0]) < 32)
4971 || (GET_CODE (operands[0]) == SUBREG
4972 && GET_CODE (SUBREG_REG (operands[0])) == REG
4973 && REGNO (SUBREG_REG (operands[0])) < 32))"
4974 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4975 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4976 "operands[3] = gen_highpart (SImode, operands[0]);
4977 operands[4] = gen_highpart (SImode, operands[1]);
4978 operands[5] = gen_highpart (SImode, operands[2]);
4979 operands[6] = gen_lowpart (SImode, operands[0]);
4980 operands[7] = gen_lowpart (SImode, operands[1]);
4981 operands[8] = gen_lowpart (SImode, operands[2]);"
4982 [(set_attr "type" "*,fga")
4983 (set_attr "length" "2,*")
4984 (set_attr "fptype" "*,double")])
4986 (define_insn "*xor_not_<V64I:mode>_sp64"
4987 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4988 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4989 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4994 [(set_attr "type" "*,fga")
4995 (set_attr "fptype" "*,double")])
4997 (define_insn "*xor_not_<V32I:mode>"
4998 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4999 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5000 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5005 [(set_attr "type" "*,fga")
5006 (set_attr "fptype" "*,single")])
5008 ;; These correspond to the above in the case where we also (or only)
5009 ;; want to set the condition code.
5011 (define_insn "*cmp_cc_arith_op"
5012 [(set (reg:CC CC_REG)
5014 (match_operator:SI 2 "cc_arith_operator"
5015 [(match_operand:SI 0 "arith_operand" "%r")
5016 (match_operand:SI 1 "arith_operand" "rI")])
5019 "%A2cc\t%0, %1, %%g0"
5020 [(set_attr "type" "compare")])
5022 (define_insn "*cmp_ccx_arith_op"
5023 [(set (reg:CCX CC_REG)
5025 (match_operator:DI 2 "cc_arith_operator"
5026 [(match_operand:DI 0 "arith_operand" "%r")
5027 (match_operand:DI 1 "arith_operand" "rI")])
5030 "%A2cc\t%0, %1, %%g0"
5031 [(set_attr "type" "compare")])
5033 (define_insn "*cmp_cc_arith_op_set"
5034 [(set (reg:CC CC_REG)
5036 (match_operator:SI 3 "cc_arith_operator"
5037 [(match_operand:SI 1 "arith_operand" "%r")
5038 (match_operand:SI 2 "arith_operand" "rI")])
5040 (set (match_operand:SI 0 "register_operand" "=r")
5041 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5042 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5044 [(set_attr "type" "compare")])
5046 (define_insn "*cmp_ccx_arith_op_set"
5047 [(set (reg:CCX CC_REG)
5049 (match_operator:DI 3 "cc_arith_operator"
5050 [(match_operand:DI 1 "arith_operand" "%r")
5051 (match_operand:DI 2 "arith_operand" "rI")])
5053 (set (match_operand:DI 0 "register_operand" "=r")
5054 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5055 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5057 [(set_attr "type" "compare")])
5059 (define_insn "*cmp_cc_xor_not"
5060 [(set (reg:CC CC_REG)
5062 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5063 (match_operand:SI 1 "arith_operand" "rI")))
5066 "xnorcc\t%r0, %1, %%g0"
5067 [(set_attr "type" "compare")])
5069 (define_insn "*cmp_ccx_xor_not"
5070 [(set (reg:CCX CC_REG)
5072 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5073 (match_operand:DI 1 "arith_operand" "rI")))
5076 "xnorcc\t%r0, %1, %%g0"
5077 [(set_attr "type" "compare")])
5079 (define_insn "*cmp_cc_xor_not_set"
5080 [(set (reg:CC CC_REG)
5082 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5083 (match_operand:SI 2 "arith_operand" "rI")))
5085 (set (match_operand:SI 0 "register_operand" "=r")
5086 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5088 "xnorcc\t%r1, %2, %0"
5089 [(set_attr "type" "compare")])
5091 (define_insn "*cmp_ccx_xor_not_set"
5092 [(set (reg:CCX CC_REG)
5094 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5095 (match_operand:DI 2 "arith_operand" "rI")))
5097 (set (match_operand:DI 0 "register_operand" "=r")
5098 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5100 "xnorcc\t%r1, %2, %0"
5101 [(set_attr "type" "compare")])
5103 (define_insn "*cmp_cc_arith_op_not"
5104 [(set (reg:CC CC_REG)
5106 (match_operator:SI 2 "cc_arith_not_operator"
5107 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5108 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5111 "%B2cc\t%r1, %0, %%g0"
5112 [(set_attr "type" "compare")])
5114 (define_insn "*cmp_ccx_arith_op_not"
5115 [(set (reg:CCX CC_REG)
5117 (match_operator:DI 2 "cc_arith_not_operator"
5118 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5119 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5122 "%B2cc\t%r1, %0, %%g0"
5123 [(set_attr "type" "compare")])
5125 (define_insn "*cmp_cc_arith_op_not_set"
5126 [(set (reg:CC CC_REG)
5128 (match_operator:SI 3 "cc_arith_not_operator"
5129 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5130 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5132 (set (match_operand:SI 0 "register_operand" "=r")
5133 (match_operator:SI 4 "cc_arith_not_operator"
5134 [(not:SI (match_dup 1)) (match_dup 2)]))]
5135 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5136 "%B3cc\t%r2, %1, %0"
5137 [(set_attr "type" "compare")])
5139 (define_insn "*cmp_ccx_arith_op_not_set"
5140 [(set (reg:CCX CC_REG)
5142 (match_operator:DI 3 "cc_arith_not_operator"
5143 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5144 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5146 (set (match_operand:DI 0 "register_operand" "=r")
5147 (match_operator:DI 4 "cc_arith_not_operator"
5148 [(not:DI (match_dup 1)) (match_dup 2)]))]
5149 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5150 "%B3cc\t%r2, %1, %0"
5151 [(set_attr "type" "compare")])
5153 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5154 ;; does not know how to make it work for constants.
5156 (define_expand "negdi2"
5157 [(set (match_operand:DI 0 "register_operand" "=r")
5158 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5161 if (! TARGET_ARCH64)
5163 emit_insn (gen_rtx_PARALLEL
5166 gen_rtx_SET (VOIDmode, operand0,
5167 gen_rtx_NEG (DImode, operand1)),
5168 gen_rtx_CLOBBER (VOIDmode,
5169 gen_rtx_REG (CCmode,
5175 (define_insn_and_split "*negdi2_sp32"
5176 [(set (match_operand:DI 0 "register_operand" "=r")
5177 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5178 (clobber (reg:CC CC_REG))]
5181 "&& reload_completed"
5182 [(parallel [(set (reg:CC_NOOV CC_REG)
5183 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5185 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5186 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5187 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5188 "operands[2] = gen_highpart (SImode, operands[0]);
5189 operands[3] = gen_highpart (SImode, operands[1]);
5190 operands[4] = gen_lowpart (SImode, operands[0]);
5191 operands[5] = gen_lowpart (SImode, operands[1]);"
5192 [(set_attr "length" "2")])
5194 (define_insn "*negdi2_sp64"
5195 [(set (match_operand:DI 0 "register_operand" "=r")
5196 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5198 "sub\t%%g0, %1, %0")
5200 (define_insn "negsi2"
5201 [(set (match_operand:SI 0 "register_operand" "=r")
5202 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5204 "sub\t%%g0, %1, %0")
5206 (define_insn "*cmp_cc_neg"
5207 [(set (reg:CC_NOOV CC_REG)
5208 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5211 "subcc\t%%g0, %0, %%g0"
5212 [(set_attr "type" "compare")])
5214 (define_insn "*cmp_ccx_neg"
5215 [(set (reg:CCX_NOOV CC_REG)
5216 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5219 "subcc\t%%g0, %0, %%g0"
5220 [(set_attr "type" "compare")])
5222 (define_insn "*cmp_cc_set_neg"
5223 [(set (reg:CC_NOOV CC_REG)
5224 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5226 (set (match_operand:SI 0 "register_operand" "=r")
5227 (neg:SI (match_dup 1)))]
5229 "subcc\t%%g0, %1, %0"
5230 [(set_attr "type" "compare")])
5232 (define_insn "*cmp_ccx_set_neg"
5233 [(set (reg:CCX_NOOV CC_REG)
5234 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5236 (set (match_operand:DI 0 "register_operand" "=r")
5237 (neg:DI (match_dup 1)))]
5239 "subcc\t%%g0, %1, %0"
5240 [(set_attr "type" "compare")])
5242 ;; We cannot use the "not" pseudo insn because the Sun assembler
5243 ;; does not know how to make it work for constants.
5244 (define_expand "one_cmpl<V64I:mode>2"
5245 [(set (match_operand:V64I 0 "register_operand" "")
5246 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5250 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5251 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5252 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5257 "&& reload_completed
5258 && ((GET_CODE (operands[0]) == REG
5259 && REGNO (operands[0]) < 32)
5260 || (GET_CODE (operands[0]) == SUBREG
5261 && GET_CODE (SUBREG_REG (operands[0])) == REG
5262 && REGNO (SUBREG_REG (operands[0])) < 32))"
5263 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5264 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5265 "operands[2] = gen_highpart (SImode, operands[0]);
5266 operands[3] = gen_highpart (SImode, operands[1]);
5267 operands[4] = gen_lowpart (SImode, operands[0]);
5268 operands[5] = gen_lowpart (SImode, operands[1]);"
5269 [(set_attr "type" "*,fga")
5270 (set_attr "length" "2,*")
5271 (set_attr "fptype" "*,double")])
5273 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5274 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5275 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5280 [(set_attr "type" "*,fga")
5281 (set_attr "fptype" "*,double")])
5283 (define_insn "one_cmpl<V32I:mode>2"
5284 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5285 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5290 [(set_attr "type" "*,fga")
5291 (set_attr "fptype" "*,single")])
5293 (define_insn "*cmp_cc_not"
5294 [(set (reg:CC CC_REG)
5295 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5298 "xnorcc\t%%g0, %0, %%g0"
5299 [(set_attr "type" "compare")])
5301 (define_insn "*cmp_ccx_not"
5302 [(set (reg:CCX CC_REG)
5303 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5306 "xnorcc\t%%g0, %0, %%g0"
5307 [(set_attr "type" "compare")])
5309 (define_insn "*cmp_cc_set_not"
5310 [(set (reg:CC CC_REG)
5311 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5313 (set (match_operand:SI 0 "register_operand" "=r")
5314 (not:SI (match_dup 1)))]
5316 "xnorcc\t%%g0, %1, %0"
5317 [(set_attr "type" "compare")])
5319 (define_insn "*cmp_ccx_set_not"
5320 [(set (reg:CCX CC_REG)
5321 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5323 (set (match_operand:DI 0 "register_operand" "=r")
5324 (not:DI (match_dup 1)))]
5326 "xnorcc\t%%g0, %1, %0"
5327 [(set_attr "type" "compare")])
5329 (define_insn "*cmp_cc_set"
5330 [(set (match_operand:SI 0 "register_operand" "=r")
5331 (match_operand:SI 1 "register_operand" "r"))
5332 (set (reg:CC CC_REG)
5333 (compare:CC (match_dup 1)
5337 [(set_attr "type" "compare")])
5339 (define_insn "*cmp_ccx_set64"
5340 [(set (match_operand:DI 0 "register_operand" "=r")
5341 (match_operand:DI 1 "register_operand" "r"))
5342 (set (reg:CCX CC_REG)
5343 (compare:CCX (match_dup 1)
5347 [(set_attr "type" "compare")])
5350 ;; Floating point arithmetic instructions.
5352 (define_expand "addtf3"
5353 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5354 (plus:TF (match_operand:TF 1 "general_operand" "")
5355 (match_operand:TF 2 "general_operand" "")))]
5356 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5357 "emit_tfmode_binop (PLUS, operands); DONE;")
5359 (define_insn "*addtf3_hq"
5360 [(set (match_operand:TF 0 "register_operand" "=e")
5361 (plus:TF (match_operand:TF 1 "register_operand" "e")
5362 (match_operand:TF 2 "register_operand" "e")))]
5363 "TARGET_FPU && TARGET_HARD_QUAD"
5365 [(set_attr "type" "fp")])
5367 (define_insn "adddf3"
5368 [(set (match_operand:DF 0 "register_operand" "=e")
5369 (plus:DF (match_operand:DF 1 "register_operand" "e")
5370 (match_operand:DF 2 "register_operand" "e")))]
5373 [(set_attr "type" "fp")
5374 (set_attr "fptype" "double")])
5376 (define_insn "addsf3"
5377 [(set (match_operand:SF 0 "register_operand" "=f")
5378 (plus:SF (match_operand:SF 1 "register_operand" "f")
5379 (match_operand:SF 2 "register_operand" "f")))]
5382 [(set_attr "type" "fp")])
5384 (define_expand "subtf3"
5385 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5386 (minus:TF (match_operand:TF 1 "general_operand" "")
5387 (match_operand:TF 2 "general_operand" "")))]
5388 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5389 "emit_tfmode_binop (MINUS, operands); DONE;")
5391 (define_insn "*subtf3_hq"
5392 [(set (match_operand:TF 0 "register_operand" "=e")
5393 (minus:TF (match_operand:TF 1 "register_operand" "e")
5394 (match_operand:TF 2 "register_operand" "e")))]
5395 "TARGET_FPU && TARGET_HARD_QUAD"
5397 [(set_attr "type" "fp")])
5399 (define_insn "subdf3"
5400 [(set (match_operand:DF 0 "register_operand" "=e")
5401 (minus:DF (match_operand:DF 1 "register_operand" "e")
5402 (match_operand:DF 2 "register_operand" "e")))]
5405 [(set_attr "type" "fp")
5406 (set_attr "fptype" "double")])
5408 (define_insn "subsf3"
5409 [(set (match_operand:SF 0 "register_operand" "=f")
5410 (minus:SF (match_operand:SF 1 "register_operand" "f")
5411 (match_operand:SF 2 "register_operand" "f")))]
5414 [(set_attr "type" "fp")])
5416 (define_expand "multf3"
5417 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5418 (mult:TF (match_operand:TF 1 "general_operand" "")
5419 (match_operand:TF 2 "general_operand" "")))]
5420 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5421 "emit_tfmode_binop (MULT, operands); DONE;")
5423 (define_insn "*multf3_hq"
5424 [(set (match_operand:TF 0 "register_operand" "=e")
5425 (mult:TF (match_operand:TF 1 "register_operand" "e")
5426 (match_operand:TF 2 "register_operand" "e")))]
5427 "TARGET_FPU && TARGET_HARD_QUAD"
5429 [(set_attr "type" "fpmul")])
5431 (define_insn "muldf3"
5432 [(set (match_operand:DF 0 "register_operand" "=e")
5433 (mult:DF (match_operand:DF 1 "register_operand" "e")
5434 (match_operand:DF 2 "register_operand" "e")))]
5437 [(set_attr "type" "fpmul")
5438 (set_attr "fptype" "double")])
5440 (define_insn "mulsf3"
5441 [(set (match_operand:SF 0 "register_operand" "=f")
5442 (mult:SF (match_operand:SF 1 "register_operand" "f")
5443 (match_operand:SF 2 "register_operand" "f")))]
5446 [(set_attr "type" "fpmul")])
5448 (define_insn "fmadf4"
5449 [(set (match_operand:DF 0 "register_operand" "=e")
5450 (fma:DF (match_operand:DF 1 "register_operand" "e")
5451 (match_operand:DF 2 "register_operand" "e")
5452 (match_operand:DF 3 "register_operand" "e")))]
5454 "fmaddd\t%1, %2, %3, %0"
5455 [(set_attr "type" "fpmul")])
5457 (define_insn "fmsdf4"
5458 [(set (match_operand:DF 0 "register_operand" "=e")
5459 (fma:DF (match_operand:DF 1 "register_operand" "e")
5460 (match_operand:DF 2 "register_operand" "e")
5461 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5463 "fmsubd\t%1, %2, %3, %0"
5464 [(set_attr "type" "fpmul")])
5466 (define_insn "*nfmadf4"
5467 [(set (match_operand:DF 0 "register_operand" "=e")
5468 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5469 (match_operand:DF 2 "register_operand" "e")
5470 (match_operand:DF 3 "register_operand" "e"))))]
5472 "fnmaddd\t%1, %2, %3, %0"
5473 [(set_attr "type" "fpmul")])
5475 (define_insn "*nfmsdf4"
5476 [(set (match_operand:DF 0 "register_operand" "=e")
5477 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5478 (match_operand:DF 2 "register_operand" "e")
5479 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5481 "fnmsubd\t%1, %2, %3, %0"
5482 [(set_attr "type" "fpmul")])
5484 (define_insn "fmasf4"
5485 [(set (match_operand:SF 0 "register_operand" "=f")
5486 (fma:SF (match_operand:SF 1 "register_operand" "f")
5487 (match_operand:SF 2 "register_operand" "f")
5488 (match_operand:SF 3 "register_operand" "f")))]
5490 "fmadds\t%1, %2, %3, %0"
5491 [(set_attr "type" "fpmul")])
5493 (define_insn "fmssf4"
5494 [(set (match_operand:SF 0 "register_operand" "=f")
5495 (fma:SF (match_operand:SF 1 "register_operand" "f")
5496 (match_operand:SF 2 "register_operand" "f")
5497 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5499 "fmsubs\t%1, %2, %3, %0"
5500 [(set_attr "type" "fpmul")])
5502 (define_insn "*nfmasf4"
5503 [(set (match_operand:SF 0 "register_operand" "=f")
5504 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5505 (match_operand:SF 2 "register_operand" "f")
5506 (match_operand:SF 3 "register_operand" "f"))))]
5508 "fnmadds\t%1, %2, %3, %0"
5509 [(set_attr "type" "fpmul")])
5511 (define_insn "*nfmssf4"
5512 [(set (match_operand:SF 0 "register_operand" "=f")
5513 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5514 (match_operand:SF 2 "register_operand" "f")
5515 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5517 "fnmsubs\t%1, %2, %3, %0"
5518 [(set_attr "type" "fpmul")])
5520 (define_insn "*muldf3_extend"
5521 [(set (match_operand:DF 0 "register_operand" "=e")
5522 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5523 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5524 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5525 "fsmuld\t%1, %2, %0"
5526 [(set_attr "type" "fpmul")
5527 (set_attr "fptype" "double")])
5529 (define_insn "*multf3_extend"
5530 [(set (match_operand:TF 0 "register_operand" "=e")
5531 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5532 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5533 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5534 "fdmulq\t%1, %2, %0"
5535 [(set_attr "type" "fpmul")])
5537 (define_expand "divtf3"
5538 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5539 (div:TF (match_operand:TF 1 "general_operand" "")
5540 (match_operand:TF 2 "general_operand" "")))]
5541 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5542 "emit_tfmode_binop (DIV, operands); DONE;")
5544 ;; don't have timing for quad-prec. divide.
5545 (define_insn "*divtf3_hq"
5546 [(set (match_operand:TF 0 "register_operand" "=e")
5547 (div:TF (match_operand:TF 1 "register_operand" "e")
5548 (match_operand:TF 2 "register_operand" "e")))]
5549 "TARGET_FPU && TARGET_HARD_QUAD"
5551 [(set_attr "type" "fpdivd")])
5553 (define_insn "divdf3"
5554 [(set (match_operand:DF 0 "register_operand" "=e")
5555 (div:DF (match_operand:DF 1 "register_operand" "e")
5556 (match_operand:DF 2 "register_operand" "e")))]
5559 [(set_attr "type" "fpdivd")
5560 (set_attr "fptype" "double")])
5562 (define_insn "divsf3"
5563 [(set (match_operand:SF 0 "register_operand" "=f")
5564 (div:SF (match_operand:SF 1 "register_operand" "f")
5565 (match_operand:SF 2 "register_operand" "f")))]
5568 [(set_attr "type" "fpdivs")])
5570 (define_expand "negtf2"
5571 [(set (match_operand:TF 0 "register_operand" "=e,e")
5572 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5576 (define_insn_and_split "*negtf2_notv9"
5577 [(set (match_operand:TF 0 "register_operand" "=e,e")
5578 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5579 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5585 "&& reload_completed
5586 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5587 [(set (match_dup 2) (neg:SF (match_dup 3)))
5588 (set (match_dup 4) (match_dup 5))
5589 (set (match_dup 6) (match_dup 7))]
5590 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5591 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5592 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5593 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5594 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5595 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5596 [(set_attr "type" "fpmove,*")
5597 (set_attr "length" "*,2")])
5599 (define_insn_and_split "*negtf2_v9"
5600 [(set (match_operand:TF 0 "register_operand" "=e,e")
5601 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5602 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5603 "TARGET_FPU && TARGET_V9"
5607 "&& reload_completed
5608 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5609 [(set (match_dup 2) (neg:DF (match_dup 3)))
5610 (set (match_dup 4) (match_dup 5))]
5611 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5612 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5613 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5614 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5615 [(set_attr "type" "fpmove,*")
5616 (set_attr "length" "*,2")
5617 (set_attr "fptype" "double")])
5619 (define_expand "negdf2"
5620 [(set (match_operand:DF 0 "register_operand" "")
5621 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5625 (define_insn_and_split "*negdf2_notv9"
5626 [(set (match_operand:DF 0 "register_operand" "=e,e")
5627 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5628 "TARGET_FPU && ! TARGET_V9"
5632 "&& reload_completed
5633 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5634 [(set (match_dup 2) (neg:SF (match_dup 3)))
5635 (set (match_dup 4) (match_dup 5))]
5636 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5637 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5638 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5639 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5640 [(set_attr "type" "fpmove,*")
5641 (set_attr "length" "*,2")])
5643 (define_insn "*negdf2_v9"
5644 [(set (match_operand:DF 0 "register_operand" "=e")
5645 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5646 "TARGET_FPU && TARGET_V9"
5648 [(set_attr "type" "fpmove")
5649 (set_attr "fptype" "double")])
5651 (define_insn "negsf2"
5652 [(set (match_operand:SF 0 "register_operand" "=f")
5653 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5656 [(set_attr "type" "fpmove")])
5658 (define_expand "abstf2"
5659 [(set (match_operand:TF 0 "register_operand" "")
5660 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5664 (define_insn_and_split "*abstf2_notv9"
5665 [(set (match_operand:TF 0 "register_operand" "=e,e")
5666 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5667 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5668 "TARGET_FPU && ! TARGET_V9"
5672 "&& reload_completed
5673 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5674 [(set (match_dup 2) (abs:SF (match_dup 3)))
5675 (set (match_dup 4) (match_dup 5))
5676 (set (match_dup 6) (match_dup 7))]
5677 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5678 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5679 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5680 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5681 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5682 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5683 [(set_attr "type" "fpmove,*")
5684 (set_attr "length" "*,2")])
5686 (define_insn "*abstf2_hq_v9"
5687 [(set (match_operand:TF 0 "register_operand" "=e,e")
5688 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5689 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5693 [(set_attr "type" "fpmove")
5694 (set_attr "fptype" "double,*")])
5696 (define_insn_and_split "*abstf2_v9"
5697 [(set (match_operand:TF 0 "register_operand" "=e,e")
5698 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5699 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5703 "&& reload_completed
5704 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5705 [(set (match_dup 2) (abs:DF (match_dup 3)))
5706 (set (match_dup 4) (match_dup 5))]
5707 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5708 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5709 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5710 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5711 [(set_attr "type" "fpmove,*")
5712 (set_attr "length" "*,2")
5713 (set_attr "fptype" "double,*")])
5715 (define_expand "absdf2"
5716 [(set (match_operand:DF 0 "register_operand" "")
5717 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5721 (define_insn_and_split "*absdf2_notv9"
5722 [(set (match_operand:DF 0 "register_operand" "=e,e")
5723 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5724 "TARGET_FPU && ! TARGET_V9"
5728 "&& reload_completed
5729 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5730 [(set (match_dup 2) (abs:SF (match_dup 3)))
5731 (set (match_dup 4) (match_dup 5))]
5732 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5733 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5734 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5735 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5736 [(set_attr "type" "fpmove,*")
5737 (set_attr "length" "*,2")])
5739 (define_insn "*absdf2_v9"
5740 [(set (match_operand:DF 0 "register_operand" "=e")
5741 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5742 "TARGET_FPU && TARGET_V9"
5744 [(set_attr "type" "fpmove")
5745 (set_attr "fptype" "double")])
5747 (define_insn "abssf2"
5748 [(set (match_operand:SF 0 "register_operand" "=f")
5749 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5752 [(set_attr "type" "fpmove")])
5754 (define_expand "sqrttf2"
5755 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5756 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5757 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5758 "emit_tfmode_unop (SQRT, operands); DONE;")
5760 (define_insn "*sqrttf2_hq"
5761 [(set (match_operand:TF 0 "register_operand" "=e")
5762 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5763 "TARGET_FPU && TARGET_HARD_QUAD"
5765 [(set_attr "type" "fpsqrtd")])
5767 (define_insn "sqrtdf2"
5768 [(set (match_operand:DF 0 "register_operand" "=e")
5769 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5772 [(set_attr "type" "fpsqrtd")
5773 (set_attr "fptype" "double")])
5775 (define_insn "sqrtsf2"
5776 [(set (match_operand:SF 0 "register_operand" "=f")
5777 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5780 [(set_attr "type" "fpsqrts")])
5783 ;; Arithmetic shift instructions.
5785 (define_insn "ashlsi3"
5786 [(set (match_operand:SI 0 "register_operand" "=r")
5787 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5788 (match_operand:SI 2 "arith_operand" "rI")))]
5791 if (GET_CODE (operands[2]) == CONST_INT)
5792 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5793 return "sll\t%1, %2, %0";
5795 [(set_attr "type" "shift")])
5797 (define_insn "*ashlsi3_extend"
5798 [(set (match_operand:DI 0 "register_operand" "=r")
5800 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5801 (match_operand:SI 2 "arith_operand" "rI"))))]
5804 if (GET_CODE (operands[2]) == CONST_INT)
5805 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5806 return "sll\t%1, %2, %0";
5808 [(set_attr "type" "shift")])
5810 (define_expand "ashldi3"
5811 [(set (match_operand:DI 0 "register_operand" "=r")
5812 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5813 (match_operand:SI 2 "arith_operand" "rI")))]
5814 "TARGET_ARCH64 || TARGET_V8PLUS"
5816 if (! TARGET_ARCH64)
5818 if (GET_CODE (operands[2]) == CONST_INT)
5820 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5825 (define_insn "*ashldi3_sp64"
5826 [(set (match_operand:DI 0 "register_operand" "=r")
5827 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5828 (match_operand:SI 2 "arith_operand" "rI")))]
5831 if (GET_CODE (operands[2]) == CONST_INT)
5832 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5833 return "sllx\t%1, %2, %0";
5835 [(set_attr "type" "shift")])
5838 (define_insn "ashldi3_v8plus"
5839 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5840 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5841 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5842 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5844 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5845 [(set_attr "type" "multi")
5846 (set_attr "length" "5,5,6")])
5848 ;; Optimize (1LL<<x)-1
5849 ;; XXX this also needs to be fixed to handle equal subregs
5850 ;; XXX first before we could re-enable it.
5852 ; [(set (match_operand:DI 0 "register_operand" "=h")
5853 ; (plus:DI (ashift:DI (const_int 1)
5854 ; (match_operand:SI 1 "arith_operand" "rI"))
5856 ; "0 && TARGET_V8PLUS"
5858 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5859 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5860 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5862 ; [(set_attr "type" "multi")
5863 ; (set_attr "length" "4")])
5865 (define_insn "*cmp_cc_ashift_1"
5866 [(set (reg:CC_NOOV CC_REG)
5867 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5871 "addcc\t%0, %0, %%g0"
5872 [(set_attr "type" "compare")])
5874 (define_insn "*cmp_cc_set_ashift_1"
5875 [(set (reg:CC_NOOV CC_REG)
5876 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5879 (set (match_operand:SI 0 "register_operand" "=r")
5880 (ashift:SI (match_dup 1) (const_int 1)))]
5883 [(set_attr "type" "compare")])
5885 (define_insn "ashrsi3"
5886 [(set (match_operand:SI 0 "register_operand" "=r")
5887 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5888 (match_operand:SI 2 "arith_operand" "rI")))]
5891 if (GET_CODE (operands[2]) == CONST_INT)
5892 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5893 return "sra\t%1, %2, %0";
5895 [(set_attr "type" "shift")])
5897 (define_insn "*ashrsi3_extend"
5898 [(set (match_operand:DI 0 "register_operand" "=r")
5899 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5900 (match_operand:SI 2 "arith_operand" "r"))))]
5903 [(set_attr "type" "shift")])
5905 ;; This handles the case as above, but with constant shift instead of
5906 ;; register. Combiner "simplifies" it for us a little bit though.
5907 (define_insn "*ashrsi3_extend2"
5908 [(set (match_operand:DI 0 "register_operand" "=r")
5909 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5911 (match_operand:SI 2 "small_int_operand" "I")))]
5912 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5914 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5915 return "sra\t%1, %2, %0";
5917 [(set_attr "type" "shift")])
5919 (define_expand "ashrdi3"
5920 [(set (match_operand:DI 0 "register_operand" "=r")
5921 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5922 (match_operand:SI 2 "arith_operand" "rI")))]
5923 "TARGET_ARCH64 || TARGET_V8PLUS"
5925 if (! TARGET_ARCH64)
5927 if (GET_CODE (operands[2]) == CONST_INT)
5928 FAIL; /* prefer generic code in this case */
5929 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5934 (define_insn "*ashrdi3_sp64"
5935 [(set (match_operand:DI 0 "register_operand" "=r")
5936 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5937 (match_operand:SI 2 "arith_operand" "rI")))]
5941 if (GET_CODE (operands[2]) == CONST_INT)
5942 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5943 return "srax\t%1, %2, %0";
5945 [(set_attr "type" "shift")])
5948 (define_insn "ashrdi3_v8plus"
5949 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5950 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5951 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5952 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5954 "* return output_v8plus_shift (operands, insn, \"srax\");"
5955 [(set_attr "type" "multi")
5956 (set_attr "length" "5,5,6")])
5958 (define_insn "lshrsi3"
5959 [(set (match_operand:SI 0 "register_operand" "=r")
5960 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5961 (match_operand:SI 2 "arith_operand" "rI")))]
5964 if (GET_CODE (operands[2]) == CONST_INT)
5965 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5966 return "srl\t%1, %2, %0";
5968 [(set_attr "type" "shift")])
5970 (define_insn "*lshrsi3_extend0"
5971 [(set (match_operand:DI 0 "register_operand" "=r")
5973 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5974 (match_operand:SI 2 "arith_operand" "rI"))))]
5977 if (GET_CODE (operands[2]) == CONST_INT)
5978 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5979 return "srl\t%1, %2, %0";
5981 [(set_attr "type" "shift")])
5983 ;; This handles the case where
5984 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5985 ;; but combiner "simplifies" it for us.
5986 (define_insn "*lshrsi3_extend1"
5987 [(set (match_operand:DI 0 "register_operand" "=r")
5988 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5989 (match_operand:SI 2 "arith_operand" "r")) 0)
5990 (match_operand 3 "const_int_operand" "")))]
5991 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5993 [(set_attr "type" "shift")])
5995 ;; This handles the case where
5996 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5997 ;; but combiner "simplifies" it for us.
5998 (define_insn "*lshrsi3_extend2"
5999 [(set (match_operand:DI 0 "register_operand" "=r")
6000 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6001 (match_operand 2 "small_int_operand" "I")
6003 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6005 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6006 return "srl\t%1, %2, %0";
6008 [(set_attr "type" "shift")])
6010 (define_expand "lshrdi3"
6011 [(set (match_operand:DI 0 "register_operand" "=r")
6012 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6013 (match_operand:SI 2 "arith_operand" "rI")))]
6014 "TARGET_ARCH64 || TARGET_V8PLUS"
6016 if (! TARGET_ARCH64)
6018 if (GET_CODE (operands[2]) == CONST_INT)
6020 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6025 (define_insn "*lshrdi3_sp64"
6026 [(set (match_operand:DI 0 "register_operand" "=r")
6027 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6028 (match_operand:SI 2 "arith_operand" "rI")))]
6031 if (GET_CODE (operands[2]) == CONST_INT)
6032 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6033 return "srlx\t%1, %2, %0";
6035 [(set_attr "type" "shift")])
6038 (define_insn "lshrdi3_v8plus"
6039 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6040 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6041 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6042 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6044 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6045 [(set_attr "type" "multi")
6046 (set_attr "length" "5,5,6")])
6049 [(set (match_operand:SI 0 "register_operand" "=r")
6050 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6052 (match_operand:SI 2 "small_int_operand" "I")))]
6053 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6055 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6056 return "srax\t%1, %2, %0";
6058 [(set_attr "type" "shift")])
6061 [(set (match_operand:SI 0 "register_operand" "=r")
6062 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6064 (match_operand:SI 2 "small_int_operand" "I")))]
6065 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6067 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6068 return "srlx\t%1, %2, %0";
6070 [(set_attr "type" "shift")])
6073 [(set (match_operand:SI 0 "register_operand" "=r")
6074 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6075 (match_operand:SI 2 "small_int_operand" "I")) 4)
6076 (match_operand:SI 3 "small_int_operand" "I")))]
6078 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6079 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6080 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6082 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6084 return "srax\t%1, %2, %0";
6086 [(set_attr "type" "shift")])
6089 [(set (match_operand:SI 0 "register_operand" "=r")
6090 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6091 (match_operand:SI 2 "small_int_operand" "I")) 4)
6092 (match_operand:SI 3 "small_int_operand" "I")))]
6094 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6095 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6096 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6098 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6100 return "srlx\t%1, %2, %0";
6102 [(set_attr "type" "shift")])
6105 ;; Unconditional and other jump instructions.
6108 [(set (pc) (label_ref (match_operand 0 "" "")))]
6110 "* return output_ubranch (operands[0], 0, insn);"
6111 [(set_attr "type" "uncond_branch")])
6113 (define_expand "tablejump"
6114 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6115 (use (label_ref (match_operand 1 "" "")))])]
6118 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6120 /* In pic mode, our address differences are against the base of the
6121 table. Add that base value back in; CSE ought to be able to combine
6122 the two address loads. */
6126 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6128 if (CASE_VECTOR_MODE != Pmode)
6129 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6130 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6131 operands[0] = memory_address (Pmode, tmp);
6135 (define_insn "*tablejump_sp32"
6136 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6137 (use (label_ref (match_operand 1 "" "")))]
6140 [(set_attr "type" "uncond_branch")])
6142 (define_insn "*tablejump_sp64"
6143 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6144 (use (label_ref (match_operand 1 "" "")))]
6147 [(set_attr "type" "uncond_branch")])
6150 ;; Jump to subroutine instructions.
6152 (define_expand "call"
6153 ;; Note that this expression is not used for generating RTL.
6154 ;; All the RTL is generated explicitly below.
6155 [(call (match_operand 0 "call_operand" "")
6156 (match_operand 3 "" "i"))]
6157 ;; operands[2] is next_arg_register
6158 ;; operands[3] is struct_value_size_rtx.
6163 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6165 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6167 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6169 /* This is really a PIC sequence. We want to represent
6170 it as a funny jump so its delay slots can be filled.
6172 ??? But if this really *is* a CALL, will not it clobber the
6173 call-clobbered registers? We lose this if it is a JUMP_INSN.
6174 Why cannot we have delay slots filled if it were a CALL? */
6176 /* We accept negative sizes for untyped calls. */
6177 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6182 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6184 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6190 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6191 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6195 fn_rtx = operands[0];
6197 /* We accept negative sizes for untyped calls. */
6198 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6199 sparc_emit_call_insn
6202 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6204 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6207 sparc_emit_call_insn
6210 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6211 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6219 ;; We can't use the same pattern for these two insns, because then registers
6220 ;; in the address may not be properly reloaded.
6222 (define_insn "*call_address_sp32"
6223 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6224 (match_operand 1 "" ""))
6225 (clobber (reg:SI O7_REG))]
6226 ;;- Do not use operand 1 for most machines.
6229 [(set_attr "type" "call")])
6231 (define_insn "*call_symbolic_sp32"
6232 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6233 (match_operand 1 "" ""))
6234 (clobber (reg:SI O7_REG))]
6235 ;;- Do not use operand 1 for most machines.
6238 [(set_attr "type" "call")])
6240 (define_insn "*call_address_sp64"
6241 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6242 (match_operand 1 "" ""))
6243 (clobber (reg:DI O7_REG))]
6244 ;;- Do not use operand 1 for most machines.
6247 [(set_attr "type" "call")])
6249 (define_insn "*call_symbolic_sp64"
6250 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6251 (match_operand 1 "" ""))
6252 (clobber (reg:DI O7_REG))]
6253 ;;- Do not use operand 1 for most machines.
6256 [(set_attr "type" "call")])
6258 ;; This is a call that wants a structure value.
6259 ;; There is no such critter for v9 (??? we may need one anyway).
6260 (define_insn "*call_address_struct_value_sp32"
6261 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6262 (match_operand 1 "" ""))
6263 (match_operand 2 "immediate_operand" "")
6264 (clobber (reg:SI O7_REG))]
6265 ;;- Do not use operand 1 for most machines.
6266 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6268 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6269 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6271 [(set_attr "type" "call_no_delay_slot")
6272 (set_attr "length" "3")])
6274 ;; This is a call that wants a structure value.
6275 ;; There is no such critter for v9 (??? we may need one anyway).
6276 (define_insn "*call_symbolic_struct_value_sp32"
6277 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6278 (match_operand 1 "" ""))
6279 (match_operand 2 "immediate_operand" "")
6280 (clobber (reg:SI O7_REG))]
6281 ;;- Do not use operand 1 for most machines.
6282 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6284 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6285 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6287 [(set_attr "type" "call_no_delay_slot")
6288 (set_attr "length" "3")])
6290 ;; This is a call that may want a structure value. This is used for
6292 (define_insn "*call_address_untyped_struct_value_sp32"
6293 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6294 (match_operand 1 "" ""))
6295 (match_operand 2 "immediate_operand" "")
6296 (clobber (reg:SI O7_REG))]
6297 ;;- Do not use operand 1 for most machines.
6298 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6299 "call\t%a0, %1\n\t nop\n\tnop"
6300 [(set_attr "type" "call_no_delay_slot")
6301 (set_attr "length" "3")])
6303 ;; This is a call that may want a structure value. This is used for
6305 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6306 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6307 (match_operand 1 "" ""))
6308 (match_operand 2 "immediate_operand" "")
6309 (clobber (reg:SI O7_REG))]
6310 ;;- Do not use operand 1 for most machines.
6311 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6312 "call\t%a0, %1\n\t nop\n\tnop"
6313 [(set_attr "type" "call_no_delay_slot")
6314 (set_attr "length" "3")])
6316 (define_expand "call_value"
6317 ;; Note that this expression is not used for generating RTL.
6318 ;; All the RTL is generated explicitly below.
6319 [(set (match_operand 0 "register_operand" "=rf")
6320 (call (match_operand 1 "" "")
6321 (match_operand 4 "" "")))]
6322 ;; operand 2 is stack_size_rtx
6323 ;; operand 3 is next_arg_register
6329 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6331 fn_rtx = operands[1];
6334 gen_rtx_SET (VOIDmode, operands[0],
6335 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6336 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6338 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6343 (define_insn "*call_value_address_sp32"
6344 [(set (match_operand 0 "" "=rf")
6345 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6346 (match_operand 2 "" "")))
6347 (clobber (reg:SI O7_REG))]
6348 ;;- Do not use operand 2 for most machines.
6351 [(set_attr "type" "call")])
6353 (define_insn "*call_value_symbolic_sp32"
6354 [(set (match_operand 0 "" "=rf")
6355 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6356 (match_operand 2 "" "")))
6357 (clobber (reg:SI O7_REG))]
6358 ;;- Do not use operand 2 for most machines.
6361 [(set_attr "type" "call")])
6363 (define_insn "*call_value_address_sp64"
6364 [(set (match_operand 0 "" "")
6365 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6366 (match_operand 2 "" "")))
6367 (clobber (reg:DI O7_REG))]
6368 ;;- Do not use operand 2 for most machines.
6371 [(set_attr "type" "call")])
6373 (define_insn "*call_value_symbolic_sp64"
6374 [(set (match_operand 0 "" "")
6375 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6376 (match_operand 2 "" "")))
6377 (clobber (reg:DI O7_REG))]
6378 ;;- Do not use operand 2 for most machines.
6381 [(set_attr "type" "call")])
6383 (define_expand "untyped_call"
6384 [(parallel [(call (match_operand 0 "" "")
6386 (match_operand:BLK 1 "memory_operand" "")
6387 (match_operand 2 "" "")])]
6390 rtx valreg1 = gen_rtx_REG (DImode, 8);
6391 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6392 rtx result = operands[1];
6394 /* Pass constm1 to indicate that it may expect a structure value, but
6395 we don't know what size it is. */
6396 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6398 /* Save the function value registers. */
6399 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6400 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6403 /* The optimizer does not know that the call sets the function value
6404 registers we stored in the result block. We avoid problems by
6405 claiming that all hard registers are used and clobbered at this
6407 emit_insn (gen_blockage ());
6412 ;; Tail call instructions.
6414 (define_expand "sibcall"
6415 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6420 (define_insn "*sibcall_symbolic_sp32"
6421 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6422 (match_operand 1 "" ""))
6425 "* return output_sibcall(insn, operands[0]);"
6426 [(set_attr "type" "sibcall")])
6428 (define_insn "*sibcall_symbolic_sp64"
6429 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6430 (match_operand 1 "" ""))
6433 "* return output_sibcall(insn, operands[0]);"
6434 [(set_attr "type" "sibcall")])
6436 (define_expand "sibcall_value"
6437 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6438 (call (match_operand 1 "" "") (const_int 0)))
6443 (define_insn "*sibcall_value_symbolic_sp32"
6444 [(set (match_operand 0 "" "=rf")
6445 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6446 (match_operand 2 "" "")))
6449 "* return output_sibcall(insn, operands[1]);"
6450 [(set_attr "type" "sibcall")])
6452 (define_insn "*sibcall_value_symbolic_sp64"
6453 [(set (match_operand 0 "" "")
6454 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6455 (match_operand 2 "" "")))
6458 "* return output_sibcall(insn, operands[1]);"
6459 [(set_attr "type" "sibcall")])
6462 ;; Special instructions.
6464 (define_expand "prologue"
6469 sparc_flat_expand_prologue ();
6471 sparc_expand_prologue ();
6475 ;; The "register window save" insn is modelled as follows. The dwarf2
6476 ;; information is manually added in emit_window_save.
6478 (define_insn "window_save"
6480 [(match_operand 0 "arith_operand" "rI")]
6483 "save\t%%sp, %0, %%sp"
6484 [(set_attr "type" "savew")])
6486 (define_expand "epilogue"
6491 sparc_flat_expand_epilogue (false);
6493 sparc_expand_epilogue (false);
6496 (define_expand "sibcall_epilogue"
6501 sparc_flat_expand_epilogue (false);
6503 sparc_expand_epilogue (false);
6507 (define_expand "eh_return"
6508 [(use (match_operand 0 "general_operand" ""))]
6511 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6512 emit_jump_insn (gen_eh_return_internal ());
6517 (define_insn_and_split "eh_return_internal"
6521 "epilogue_completed"
6525 sparc_flat_expand_epilogue (true);
6527 sparc_expand_epilogue (true);
6530 (define_expand "return"
6532 "sparc_can_use_return_insn_p ()"
6535 (define_insn "*return_internal"
6538 "* return output_return (insn);"
6539 [(set_attr "type" "return")
6540 (set (attr "length")
6541 (cond [(eq_attr "calls_eh_return" "true")
6542 (if_then_else (eq_attr "delayed_branch" "true")
6543 (if_then_else (ior (eq_attr "isa" "v9")
6544 (eq_attr "flat" "true"))
6547 (if_then_else (eq_attr "flat" "true")
6550 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6551 (if_then_else (eq_attr "empty_delay_slot" "true")
6554 (eq_attr "empty_delay_slot" "true")
6555 (if_then_else (eq_attr "delayed_branch" "true")
6560 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6561 ;; all of memory. This blocks insns from being moved across this point.
6563 (define_insn "blockage"
6564 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6567 [(set_attr "length" "0")])
6569 (define_expand "probe_stack"
6570 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6574 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6577 (define_insn "probe_stack_range<P:mode>"
6578 [(set (match_operand:P 0 "register_operand" "=r")
6579 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6580 (match_operand:P 2 "register_operand" "r")]
6581 UNSPECV_PROBE_STACK_RANGE))]
6583 "* return output_probe_stack_range (operands[0], operands[2]);"
6584 [(set_attr "type" "multi")])
6586 ;; Prepare to return any type including a structure value.
6588 (define_expand "untyped_return"
6589 [(match_operand:BLK 0 "memory_operand" "")
6590 (match_operand 1 "" "")]
6593 rtx valreg1 = gen_rtx_REG (DImode, 24);
6594 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6595 rtx result = operands[0];
6597 if (! TARGET_ARCH64)
6599 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6600 rtx value = gen_reg_rtx (SImode);
6602 /* Fetch the instruction where we will return to and see if it's an unimp
6603 instruction (the most significant 10 bits will be zero). If so,
6604 update the return address to skip the unimp instruction. */
6605 emit_move_insn (value,
6606 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6607 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6608 emit_insn (gen_update_return (rtnreg, value));
6611 /* Reload the function value registers. */
6612 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6613 emit_move_insn (valreg2,
6614 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6616 /* Put USE insns before the return. */
6620 /* Construct the return. */
6621 expand_naked_return ();
6626 ;; Adjust the return address conditionally. If the value of op1 is equal
6627 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6628 ;; This is technically *half* the check required by the 32-bit SPARC
6629 ;; psABI. This check only ensures that an "unimp" insn was written by
6630 ;; the caller, but doesn't check to see if the expected size matches
6631 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6632 ;; only used by the above code "untyped_return".
6634 (define_insn "update_return"
6635 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6636 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6639 if (flag_delayed_branch)
6640 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6642 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6644 [(set (attr "type") (const_string "multi"))
6645 (set (attr "length")
6646 (if_then_else (eq_attr "delayed_branch" "true")
6655 (define_expand "indirect_jump"
6656 [(set (pc) (match_operand 0 "address_operand" "p"))]
6660 (define_insn "*branch_sp32"
6661 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6664 [(set_attr "type" "uncond_branch")])
6666 (define_insn "*branch_sp64"
6667 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6670 [(set_attr "type" "uncond_branch")])
6672 (define_expand "save_stack_nonlocal"
6673 [(set (match_operand 0 "memory_operand" "")
6674 (match_operand 1 "register_operand" ""))
6675 (set (match_dup 2) (match_dup 3))]
6678 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6679 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6680 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6683 (define_expand "restore_stack_nonlocal"
6684 [(set (match_operand 0 "register_operand" "")
6685 (match_operand 1 "memory_operand" ""))]
6688 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6691 (define_expand "nonlocal_goto"
6692 [(match_operand 0 "general_operand" "")
6693 (match_operand 1 "general_operand" "")
6694 (match_operand 2 "memory_operand" "")
6695 (match_operand 3 "memory_operand" "")]
6698 rtx r_label = copy_to_reg (operands[1]);
6699 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6700 rtx r_fp = operands[3];
6701 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6703 /* We need to flush all the register windows so that their contents will
6704 be re-synchronized by the restore insn of the target function. */
6706 emit_insn (gen_flush_register_windows ());
6708 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6709 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6711 /* Restore frame pointer for containing function. */
6712 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6713 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6715 /* USE of hard_frame_pointer_rtx added for consistency;
6716 not clear if really needed. */
6717 emit_use (hard_frame_pointer_rtx);
6718 emit_use (stack_pointer_rtx);
6720 /* We need to smuggle the load of %i7 as it is a fixed register. */
6721 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6726 (define_insn "nonlocal_goto_internal"
6727 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6728 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6729 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6731 if (flag_delayed_branch)
6734 return "jmp\t%0\n\t ldx\t%1, %%i7";
6736 return "jmp\t%0\n\t ld\t%1, %%i7";
6741 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6743 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6746 [(set (attr "type") (const_string "multi"))
6747 (set (attr "length")
6748 (if_then_else (eq_attr "delayed_branch" "true")
6752 (define_expand "builtin_setjmp_receiver"
6753 [(label_ref (match_operand 0 "" ""))]
6756 load_got_register ();
6760 ;; Special insn to flush register windows.
6762 (define_insn "flush_register_windows"
6763 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6765 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6766 [(set_attr "type" "flushw")])
6768 ;; Special pattern for the FLUSH instruction.
6770 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6771 ; of the define_insn otherwise missing a mode. We make "flush", aka
6772 ; gen_flush, the default one since sparc_initialize_trampoline uses
6773 ; it on SImode mem values.
6775 (define_insn "flush"
6776 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6778 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6779 [(set_attr "type" "iflush")])
6781 (define_insn "flushdi"
6782 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6784 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6785 [(set_attr "type" "iflush")])
6788 ;; Find first set instructions.
6790 ;; The scan instruction searches from the most significant bit while ffs
6791 ;; searches from the least significant bit. The bit index and treatment of
6792 ;; zero also differ. It takes at least 7 instructions to get the proper
6793 ;; result. Here is an obvious 8 instruction sequence.
6796 (define_insn "ffssi2"
6797 [(set (match_operand:SI 0 "register_operand" "=&r")
6798 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6799 (clobber (match_scratch:SI 2 "=&r"))]
6800 "TARGET_SPARCLITE || TARGET_SPARCLET"
6802 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";
6804 [(set_attr "type" "multi")
6805 (set_attr "length" "8")])
6807 (define_expand "popcountdi2"
6808 [(set (match_operand:DI 0 "register_operand" "")
6809 (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6812 if (! TARGET_ARCH64)
6814 emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6819 (define_insn "*popcountdi_sp64"
6820 [(set (match_operand:DI 0 "register_operand" "=r")
6821 (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6822 "TARGET_POPC && TARGET_ARCH64"
6825 (define_insn "popcountdi_v8plus"
6826 [(set (match_operand:DI 0 "register_operand" "=r")
6827 (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6828 (clobber (match_scratch:SI 2 "=&h"))]
6829 "TARGET_POPC && ! TARGET_ARCH64"
6831 if (sparc_check_64 (operands[1], insn) <= 0)
6832 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6833 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6835 [(set_attr "type" "multi")
6836 (set_attr "length" "5")])
6838 (define_expand "popcountsi2"
6840 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6841 (set (match_operand:SI 0 "register_operand" "")
6842 (truncate:SI (popcount:DI (match_dup 2))))]
6845 if (! TARGET_ARCH64)
6847 emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6851 operands[2] = gen_reg_rtx (DImode);
6854 (define_insn "*popcountsi_sp64"
6855 [(set (match_operand:SI 0 "register_operand" "=r")
6857 (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6858 "TARGET_POPC && TARGET_ARCH64"
6861 (define_insn "popcountsi_v8plus"
6862 [(set (match_operand:SI 0 "register_operand" "=r")
6863 (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6864 "TARGET_POPC && ! TARGET_ARCH64"
6866 if (sparc_check_64 (operands[1], insn) <= 0)
6867 output_asm_insn ("srl\t%1, 0, %1", operands);
6868 return "popc\t%1, %0";
6870 [(set_attr "type" "multi")
6871 (set_attr "length" "2")])
6873 (define_expand "clzdi2"
6874 [(set (match_operand:DI 0 "register_operand" "")
6875 (clz:DI (match_operand:DI 1 "register_operand" "")))]
6878 if (! TARGET_ARCH64)
6880 emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6885 (define_insn "*clzdi_sp64"
6886 [(set (match_operand:DI 0 "register_operand" "=r")
6887 (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6888 "TARGET_VIS3 && TARGET_ARCH64"
6891 (define_insn "clzdi_v8plus"
6892 [(set (match_operand:DI 0 "register_operand" "=r")
6893 (clz:DI (match_operand:DI 1 "register_operand" "r")))
6894 (clobber (match_scratch:SI 2 "=&h"))]
6895 "TARGET_VIS3 && ! TARGET_ARCH64"
6897 if (sparc_check_64 (operands[1], insn) <= 0)
6898 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6899 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6901 [(set_attr "type" "multi")
6902 (set_attr "length" "5")])
6904 (define_expand "clzsi2"
6906 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6908 (truncate:SI (clz:DI (match_dup 2))))
6909 (set (match_operand:SI 0 "register_operand" "")
6910 (minus:SI (match_dup 3) (const_int 32)))]
6913 if (! TARGET_ARCH64)
6915 emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6920 operands[2] = gen_reg_rtx (DImode);
6921 operands[3] = gen_reg_rtx (SImode);
6925 (define_insn "*clzsi_sp64"
6926 [(set (match_operand:SI 0 "register_operand" "=r")
6928 (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6929 "TARGET_VIS3 && TARGET_ARCH64"
6932 (define_insn "clzsi_v8plus"
6933 [(set (match_operand:SI 0 "register_operand" "=r")
6934 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6935 "TARGET_VIS3 && ! TARGET_ARCH64"
6937 if (sparc_check_64 (operands[1], insn) <= 0)
6938 output_asm_insn ("srl\t%1, 0, %1", operands);
6939 return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6941 [(set_attr "type" "multi")
6942 (set_attr "length" "3")])
6945 ;; Peepholes go at the end.
6947 ;; Optimize consecutive loads or stores into ldd and std when possible.
6948 ;; The conditions in which we do this are very restricted and are
6949 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6952 [(set (match_operand:SI 0 "memory_operand" "")
6954 (set (match_operand:SI 1 "memory_operand" "")
6957 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6960 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6963 [(set (match_operand:SI 0 "memory_operand" "")
6965 (set (match_operand:SI 1 "memory_operand" "")
6968 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6971 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6974 [(set (match_operand:SI 0 "register_operand" "")
6975 (match_operand:SI 1 "memory_operand" ""))
6976 (set (match_operand:SI 2 "register_operand" "")
6977 (match_operand:SI 3 "memory_operand" ""))]
6978 "registers_ok_for_ldd_peep (operands[0], operands[2])
6979 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6982 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6983 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6986 [(set (match_operand:SI 0 "memory_operand" "")
6987 (match_operand:SI 1 "register_operand" ""))
6988 (set (match_operand:SI 2 "memory_operand" "")
6989 (match_operand:SI 3 "register_operand" ""))]
6990 "registers_ok_for_ldd_peep (operands[1], operands[3])
6991 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6994 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6995 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6998 [(set (match_operand:SF 0 "register_operand" "")
6999 (match_operand:SF 1 "memory_operand" ""))
7000 (set (match_operand:SF 2 "register_operand" "")
7001 (match_operand:SF 3 "memory_operand" ""))]
7002 "registers_ok_for_ldd_peep (operands[0], operands[2])
7003 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7006 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7007 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7010 [(set (match_operand:SF 0 "memory_operand" "")
7011 (match_operand:SF 1 "register_operand" ""))
7012 (set (match_operand:SF 2 "memory_operand" "")
7013 (match_operand:SF 3 "register_operand" ""))]
7014 "registers_ok_for_ldd_peep (operands[1], operands[3])
7015 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7018 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7019 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7022 [(set (match_operand:SI 0 "register_operand" "")
7023 (match_operand:SI 1 "memory_operand" ""))
7024 (set (match_operand:SI 2 "register_operand" "")
7025 (match_operand:SI 3 "memory_operand" ""))]
7026 "registers_ok_for_ldd_peep (operands[2], operands[0])
7027 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7030 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7031 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7034 [(set (match_operand:SI 0 "memory_operand" "")
7035 (match_operand:SI 1 "register_operand" ""))
7036 (set (match_operand:SI 2 "memory_operand" "")
7037 (match_operand:SI 3 "register_operand" ""))]
7038 "registers_ok_for_ldd_peep (operands[3], operands[1])
7039 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7042 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7043 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7047 [(set (match_operand:SF 0 "register_operand" "")
7048 (match_operand:SF 1 "memory_operand" ""))
7049 (set (match_operand:SF 2 "register_operand" "")
7050 (match_operand:SF 3 "memory_operand" ""))]
7051 "registers_ok_for_ldd_peep (operands[2], operands[0])
7052 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7055 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7056 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7059 [(set (match_operand:SF 0 "memory_operand" "")
7060 (match_operand:SF 1 "register_operand" ""))
7061 (set (match_operand:SF 2 "memory_operand" "")
7062 (match_operand:SF 3 "register_operand" ""))]
7063 "registers_ok_for_ldd_peep (operands[3], operands[1])
7064 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7067 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7068 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7070 ;; Optimize the case of following a reg-reg move with a test
7071 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7072 ;; This can result from a float to fix conversion.
7075 [(set (match_operand:SI 0 "register_operand" "")
7076 (match_operand:SI 1 "register_operand" ""))
7077 (set (reg:CC CC_REG)
7078 (compare:CC (match_operand:SI 2 "register_operand" "")
7080 "(rtx_equal_p (operands[2], operands[0])
7081 || rtx_equal_p (operands[2], operands[1]))
7082 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7083 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7084 [(parallel [(set (match_dup 0) (match_dup 1))
7085 (set (reg:CC CC_REG)
7086 (compare:CC (match_dup 1) (const_int 0)))])]
7090 [(set (match_operand:DI 0 "register_operand" "")
7091 (match_operand:DI 1 "register_operand" ""))
7092 (set (reg:CCX CC_REG)
7093 (compare:CCX (match_operand:DI 2 "register_operand" "")
7096 && (rtx_equal_p (operands[2], operands[0])
7097 || rtx_equal_p (operands[2], operands[1]))
7098 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7099 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7100 [(parallel [(set (match_dup 0) (match_dup 1))
7101 (set (reg:CCX CC_REG)
7102 (compare:CCX (match_dup 1) (const_int 0)))])]
7106 ;; Prefetch instructions.
7108 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7109 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7110 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7112 (define_expand "prefetch"
7113 [(match_operand 0 "address_operand" "")
7114 (match_operand 1 "const_int_operand" "")
7115 (match_operand 2 "const_int_operand" "")]
7119 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7121 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7125 (define_insn "prefetch_64"
7126 [(prefetch (match_operand:DI 0 "address_operand" "p")
7127 (match_operand:DI 1 "const_int_operand" "n")
7128 (match_operand:DI 2 "const_int_operand" "n"))]
7131 static const char * const prefetch_instr[2][2] = {
7133 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7134 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7137 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7138 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7141 int read_or_write = INTVAL (operands[1]);
7142 int locality = INTVAL (operands[2]);
7144 gcc_assert (read_or_write == 0 || read_or_write == 1);
7145 gcc_assert (locality >= 0 && locality < 4);
7146 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7148 [(set_attr "type" "load")])
7150 (define_insn "prefetch_32"
7151 [(prefetch (match_operand:SI 0 "address_operand" "p")
7152 (match_operand:SI 1 "const_int_operand" "n")
7153 (match_operand:SI 2 "const_int_operand" "n"))]
7156 static const char * const prefetch_instr[2][2] = {
7158 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7159 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7162 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7163 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7166 int read_or_write = INTVAL (operands[1]);
7167 int locality = INTVAL (operands[2]);
7169 gcc_assert (read_or_write == 0 || read_or_write == 1);
7170 gcc_assert (locality >= 0 && locality < 4);
7171 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7173 [(set_attr "type" "load")])
7176 ;; Trap instructions.
7179 [(trap_if (const_int 1) (const_int 5))]
7182 [(set_attr "type" "trap")])
7184 (define_expand "ctrapsi4"
7185 [(trap_if (match_operator 0 "noov_compare_operator"
7186 [(match_operand:SI 1 "compare_operand" "")
7187 (match_operand:SI 2 "arith_operand" "")])
7188 (match_operand 3 ""))]
7190 "operands[1] = gen_compare_reg (operands[0]);
7191 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7193 operands[2] = const0_rtx;")
7195 (define_expand "ctrapdi4"
7196 [(trap_if (match_operator 0 "noov_compare_operator"
7197 [(match_operand:DI 1 "compare_operand" "")
7198 (match_operand:DI 2 "arith_operand" "")])
7199 (match_operand 3 ""))]
7201 "operands[1] = gen_compare_reg (operands[0]);
7202 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7204 operands[2] = const0_rtx;")
7208 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7209 (match_operand:SI 1 "arith_operand" "rM"))]
7213 return "t%C0\t%%icc, %1";
7217 [(set_attr "type" "trap")])
7220 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7221 (match_operand:SI 1 "arith_operand" "rM"))]
7224 [(set_attr "type" "trap")])
7227 ;; TLS support instructions.
7229 (define_insn "tgd_hi22"
7230 [(set (match_operand:SI 0 "register_operand" "=r")
7231 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7234 "sethi\\t%%tgd_hi22(%a1), %0")
7236 (define_insn "tgd_lo10"
7237 [(set (match_operand:SI 0 "register_operand" "=r")
7238 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7239 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7242 "add\\t%1, %%tgd_lo10(%a2), %0")
7244 (define_insn "tgd_add32"
7245 [(set (match_operand:SI 0 "register_operand" "=r")
7246 (plus:SI (match_operand:SI 1 "register_operand" "r")
7247 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7248 (match_operand 3 "tgd_symbolic_operand" "")]
7250 "TARGET_TLS && TARGET_ARCH32"
7251 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7253 (define_insn "tgd_add64"
7254 [(set (match_operand:DI 0 "register_operand" "=r")
7255 (plus:DI (match_operand:DI 1 "register_operand" "r")
7256 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7257 (match_operand 3 "tgd_symbolic_operand" "")]
7259 "TARGET_TLS && TARGET_ARCH64"
7260 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7262 (define_insn "tgd_call32"
7263 [(set (match_operand 0 "register_operand" "=r")
7264 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7265 (match_operand 2 "tgd_symbolic_operand" "")]
7267 (match_operand 3 "" "")))
7268 (clobber (reg:SI O7_REG))]
7269 "TARGET_TLS && TARGET_ARCH32"
7270 "call\t%a1, %%tgd_call(%a2)%#"
7271 [(set_attr "type" "call")])
7273 (define_insn "tgd_call64"
7274 [(set (match_operand 0 "register_operand" "=r")
7275 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7276 (match_operand 2 "tgd_symbolic_operand" "")]
7278 (match_operand 3 "" "")))
7279 (clobber (reg:DI O7_REG))]
7280 "TARGET_TLS && TARGET_ARCH64"
7281 "call\t%a1, %%tgd_call(%a2)%#"
7282 [(set_attr "type" "call")])
7284 (define_insn "tldm_hi22"
7285 [(set (match_operand:SI 0 "register_operand" "=r")
7286 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7288 "sethi\\t%%tldm_hi22(%&), %0")
7290 (define_insn "tldm_lo10"
7291 [(set (match_operand:SI 0 "register_operand" "=r")
7292 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7293 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7295 "add\\t%1, %%tldm_lo10(%&), %0")
7297 (define_insn "tldm_add32"
7298 [(set (match_operand:SI 0 "register_operand" "=r")
7299 (plus:SI (match_operand:SI 1 "register_operand" "r")
7300 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7302 "TARGET_TLS && TARGET_ARCH32"
7303 "add\\t%1, %2, %0, %%tldm_add(%&)")
7305 (define_insn "tldm_add64"
7306 [(set (match_operand:DI 0 "register_operand" "=r")
7307 (plus:DI (match_operand:DI 1 "register_operand" "r")
7308 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7310 "TARGET_TLS && TARGET_ARCH64"
7311 "add\\t%1, %2, %0, %%tldm_add(%&)")
7313 (define_insn "tldm_call32"
7314 [(set (match_operand 0 "register_operand" "=r")
7315 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7317 (match_operand 2 "" "")))
7318 (clobber (reg:SI O7_REG))]
7319 "TARGET_TLS && TARGET_ARCH32"
7320 "call\t%a1, %%tldm_call(%&)%#"
7321 [(set_attr "type" "call")])
7323 (define_insn "tldm_call64"
7324 [(set (match_operand 0 "register_operand" "=r")
7325 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7327 (match_operand 2 "" "")))
7328 (clobber (reg:DI O7_REG))]
7329 "TARGET_TLS && TARGET_ARCH64"
7330 "call\t%a1, %%tldm_call(%&)%#"
7331 [(set_attr "type" "call")])
7333 (define_insn "tldo_hix22"
7334 [(set (match_operand:SI 0 "register_operand" "=r")
7335 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7338 "sethi\\t%%tldo_hix22(%a1), %0")
7340 (define_insn "tldo_lox10"
7341 [(set (match_operand:SI 0 "register_operand" "=r")
7342 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7343 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7346 "xor\\t%1, %%tldo_lox10(%a2), %0")
7348 (define_insn "tldo_add32"
7349 [(set (match_operand:SI 0 "register_operand" "=r")
7350 (plus:SI (match_operand:SI 1 "register_operand" "r")
7351 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7352 (match_operand 3 "tld_symbolic_operand" "")]
7354 "TARGET_TLS && TARGET_ARCH32"
7355 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7357 (define_insn "tldo_add64"
7358 [(set (match_operand:DI 0 "register_operand" "=r")
7359 (plus:DI (match_operand:DI 1 "register_operand" "r")
7360 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7361 (match_operand 3 "tld_symbolic_operand" "")]
7363 "TARGET_TLS && TARGET_ARCH64"
7364 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7366 (define_insn "tie_hi22"
7367 [(set (match_operand:SI 0 "register_operand" "=r")
7368 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7371 "sethi\\t%%tie_hi22(%a1), %0")
7373 (define_insn "tie_lo10"
7374 [(set (match_operand:SI 0 "register_operand" "=r")
7375 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7376 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7379 "add\\t%1, %%tie_lo10(%a2), %0")
7381 (define_insn "tie_ld32"
7382 [(set (match_operand:SI 0 "register_operand" "=r")
7383 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7384 (match_operand:SI 2 "register_operand" "r")
7385 (match_operand 3 "tie_symbolic_operand" "")]
7387 "TARGET_TLS && TARGET_ARCH32"
7388 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7389 [(set_attr "type" "load")])
7391 (define_insn "tie_ld64"
7392 [(set (match_operand:DI 0 "register_operand" "=r")
7393 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7394 (match_operand:SI 2 "register_operand" "r")
7395 (match_operand 3 "tie_symbolic_operand" "")]
7397 "TARGET_TLS && TARGET_ARCH64"
7398 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7399 [(set_attr "type" "load")])
7401 (define_insn "tie_add32"
7402 [(set (match_operand:SI 0 "register_operand" "=r")
7403 (plus:SI (match_operand:SI 1 "register_operand" "r")
7404 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7405 (match_operand 3 "tie_symbolic_operand" "")]
7407 "TARGET_SUN_TLS && TARGET_ARCH32"
7408 "add\\t%1, %2, %0, %%tie_add(%a3)")
7410 (define_insn "tie_add64"
7411 [(set (match_operand:DI 0 "register_operand" "=r")
7412 (plus:DI (match_operand:DI 1 "register_operand" "r")
7413 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7414 (match_operand 3 "tie_symbolic_operand" "")]
7416 "TARGET_SUN_TLS && TARGET_ARCH64"
7417 "add\\t%1, %2, %0, %%tie_add(%a3)")
7419 (define_insn "tle_hix22_sp32"
7420 [(set (match_operand:SI 0 "register_operand" "=r")
7421 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7423 "TARGET_TLS && TARGET_ARCH32"
7424 "sethi\\t%%tle_hix22(%a1), %0")
7426 (define_insn "tle_lox10_sp32"
7427 [(set (match_operand:SI 0 "register_operand" "=r")
7428 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7429 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7431 "TARGET_TLS && TARGET_ARCH32"
7432 "xor\\t%1, %%tle_lox10(%a2), %0")
7434 (define_insn "tle_hix22_sp64"
7435 [(set (match_operand:DI 0 "register_operand" "=r")
7436 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7438 "TARGET_TLS && TARGET_ARCH64"
7439 "sethi\\t%%tle_hix22(%a1), %0")
7441 (define_insn "tle_lox10_sp64"
7442 [(set (match_operand:DI 0 "register_operand" "=r")
7443 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7444 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7446 "TARGET_TLS && TARGET_ARCH64"
7447 "xor\\t%1, %%tle_lox10(%a2), %0")
7449 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7450 (define_insn "*tldo_ldub_sp32"
7451 [(set (match_operand:QI 0 "register_operand" "=r")
7452 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7453 (match_operand 3 "tld_symbolic_operand" "")]
7455 (match_operand:SI 1 "register_operand" "r"))))]
7456 "TARGET_TLS && TARGET_ARCH32"
7457 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7458 [(set_attr "type" "load")
7459 (set_attr "us3load_type" "3cycle")])
7461 (define_insn "*tldo_ldub1_sp32"
7462 [(set (match_operand:HI 0 "register_operand" "=r")
7463 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7464 (match_operand 3 "tld_symbolic_operand" "")]
7466 (match_operand:SI 1 "register_operand" "r")))))]
7467 "TARGET_TLS && TARGET_ARCH32"
7468 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7469 [(set_attr "type" "load")
7470 (set_attr "us3load_type" "3cycle")])
7472 (define_insn "*tldo_ldub2_sp32"
7473 [(set (match_operand:SI 0 "register_operand" "=r")
7474 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7475 (match_operand 3 "tld_symbolic_operand" "")]
7477 (match_operand:SI 1 "register_operand" "r")))))]
7478 "TARGET_TLS && TARGET_ARCH32"
7479 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7480 [(set_attr "type" "load")
7481 (set_attr "us3load_type" "3cycle")])
7483 (define_insn "*tldo_ldsb1_sp32"
7484 [(set (match_operand:HI 0 "register_operand" "=r")
7485 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7486 (match_operand 3 "tld_symbolic_operand" "")]
7488 (match_operand:SI 1 "register_operand" "r")))))]
7489 "TARGET_TLS && TARGET_ARCH32"
7490 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7491 [(set_attr "type" "sload")
7492 (set_attr "us3load_type" "3cycle")])
7494 (define_insn "*tldo_ldsb2_sp32"
7495 [(set (match_operand:SI 0 "register_operand" "=r")
7496 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7497 (match_operand 3 "tld_symbolic_operand" "")]
7499 (match_operand:SI 1 "register_operand" "r")))))]
7500 "TARGET_TLS && TARGET_ARCH32"
7501 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7502 [(set_attr "type" "sload")
7503 (set_attr "us3load_type" "3cycle")])
7505 (define_insn "*tldo_ldub_sp64"
7506 [(set (match_operand:QI 0 "register_operand" "=r")
7507 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7508 (match_operand 3 "tld_symbolic_operand" "")]
7510 (match_operand:DI 1 "register_operand" "r"))))]
7511 "TARGET_TLS && TARGET_ARCH64"
7512 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7513 [(set_attr "type" "load")
7514 (set_attr "us3load_type" "3cycle")])
7516 (define_insn "*tldo_ldub1_sp64"
7517 [(set (match_operand:HI 0 "register_operand" "=r")
7518 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7519 (match_operand 3 "tld_symbolic_operand" "")]
7521 (match_operand:DI 1 "register_operand" "r")))))]
7522 "TARGET_TLS && TARGET_ARCH64"
7523 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7524 [(set_attr "type" "load")
7525 (set_attr "us3load_type" "3cycle")])
7527 (define_insn "*tldo_ldub2_sp64"
7528 [(set (match_operand:SI 0 "register_operand" "=r")
7529 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7530 (match_operand 3 "tld_symbolic_operand" "")]
7532 (match_operand:DI 1 "register_operand" "r")))))]
7533 "TARGET_TLS && TARGET_ARCH64"
7534 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7535 [(set_attr "type" "load")
7536 (set_attr "us3load_type" "3cycle")])
7538 (define_insn "*tldo_ldub3_sp64"
7539 [(set (match_operand:DI 0 "register_operand" "=r")
7540 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7541 (match_operand 3 "tld_symbolic_operand" "")]
7543 (match_operand:DI 1 "register_operand" "r")))))]
7544 "TARGET_TLS && TARGET_ARCH64"
7545 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7546 [(set_attr "type" "load")
7547 (set_attr "us3load_type" "3cycle")])
7549 (define_insn "*tldo_ldsb1_sp64"
7550 [(set (match_operand:HI 0 "register_operand" "=r")
7551 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7552 (match_operand 3 "tld_symbolic_operand" "")]
7554 (match_operand:DI 1 "register_operand" "r")))))]
7555 "TARGET_TLS && TARGET_ARCH64"
7556 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7557 [(set_attr "type" "sload")
7558 (set_attr "us3load_type" "3cycle")])
7560 (define_insn "*tldo_ldsb2_sp64"
7561 [(set (match_operand:SI 0 "register_operand" "=r")
7562 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7563 (match_operand 3 "tld_symbolic_operand" "")]
7565 (match_operand:DI 1 "register_operand" "r")))))]
7566 "TARGET_TLS && TARGET_ARCH64"
7567 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7568 [(set_attr "type" "sload")
7569 (set_attr "us3load_type" "3cycle")])
7571 (define_insn "*tldo_ldsb3_sp64"
7572 [(set (match_operand:DI 0 "register_operand" "=r")
7573 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7574 (match_operand 3 "tld_symbolic_operand" "")]
7576 (match_operand:DI 1 "register_operand" "r")))))]
7577 "TARGET_TLS && TARGET_ARCH64"
7578 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7579 [(set_attr "type" "sload")
7580 (set_attr "us3load_type" "3cycle")])
7582 (define_insn "*tldo_lduh_sp32"
7583 [(set (match_operand:HI 0 "register_operand" "=r")
7584 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7585 (match_operand 3 "tld_symbolic_operand" "")]
7587 (match_operand:SI 1 "register_operand" "r"))))]
7588 "TARGET_TLS && TARGET_ARCH32"
7589 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7590 [(set_attr "type" "load")
7591 (set_attr "us3load_type" "3cycle")])
7593 (define_insn "*tldo_lduh1_sp32"
7594 [(set (match_operand:SI 0 "register_operand" "=r")
7595 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7596 (match_operand 3 "tld_symbolic_operand" "")]
7598 (match_operand:SI 1 "register_operand" "r")))))]
7599 "TARGET_TLS && TARGET_ARCH32"
7600 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7601 [(set_attr "type" "load")
7602 (set_attr "us3load_type" "3cycle")])
7604 (define_insn "*tldo_ldsh1_sp32"
7605 [(set (match_operand:SI 0 "register_operand" "=r")
7606 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7607 (match_operand 3 "tld_symbolic_operand" "")]
7609 (match_operand:SI 1 "register_operand" "r")))))]
7610 "TARGET_TLS && TARGET_ARCH32"
7611 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7612 [(set_attr "type" "sload")
7613 (set_attr "us3load_type" "3cycle")])
7615 (define_insn "*tldo_lduh_sp64"
7616 [(set (match_operand:HI 0 "register_operand" "=r")
7617 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7618 (match_operand 3 "tld_symbolic_operand" "")]
7620 (match_operand:DI 1 "register_operand" "r"))))]
7621 "TARGET_TLS && TARGET_ARCH64"
7622 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7623 [(set_attr "type" "load")
7624 (set_attr "us3load_type" "3cycle")])
7626 (define_insn "*tldo_lduh1_sp64"
7627 [(set (match_operand:SI 0 "register_operand" "=r")
7628 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7629 (match_operand 3 "tld_symbolic_operand" "")]
7631 (match_operand:DI 1 "register_operand" "r")))))]
7632 "TARGET_TLS && TARGET_ARCH64"
7633 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7634 [(set_attr "type" "load")
7635 (set_attr "us3load_type" "3cycle")])
7637 (define_insn "*tldo_lduh2_sp64"
7638 [(set (match_operand:DI 0 "register_operand" "=r")
7639 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7640 (match_operand 3 "tld_symbolic_operand" "")]
7642 (match_operand:DI 1 "register_operand" "r")))))]
7643 "TARGET_TLS && TARGET_ARCH64"
7644 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7645 [(set_attr "type" "load")
7646 (set_attr "us3load_type" "3cycle")])
7648 (define_insn "*tldo_ldsh1_sp64"
7649 [(set (match_operand:SI 0 "register_operand" "=r")
7650 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7651 (match_operand 3 "tld_symbolic_operand" "")]
7653 (match_operand:DI 1 "register_operand" "r")))))]
7654 "TARGET_TLS && TARGET_ARCH64"
7655 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7656 [(set_attr "type" "sload")
7657 (set_attr "us3load_type" "3cycle")])
7659 (define_insn "*tldo_ldsh2_sp64"
7660 [(set (match_operand:DI 0 "register_operand" "=r")
7661 (sign_extend:DI (mem:HI (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 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7667 [(set_attr "type" "sload")
7668 (set_attr "us3load_type" "3cycle")])
7670 (define_insn "*tldo_lduw_sp32"
7671 [(set (match_operand:SI 0 "register_operand" "=r")
7672 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7673 (match_operand 3 "tld_symbolic_operand" "")]
7675 (match_operand:SI 1 "register_operand" "r"))))]
7676 "TARGET_TLS && TARGET_ARCH32"
7677 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7678 [(set_attr "type" "load")])
7680 (define_insn "*tldo_lduw_sp64"
7681 [(set (match_operand:SI 0 "register_operand" "=r")
7682 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7683 (match_operand 3 "tld_symbolic_operand" "")]
7685 (match_operand:DI 1 "register_operand" "r"))))]
7686 "TARGET_TLS && TARGET_ARCH64"
7687 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7688 [(set_attr "type" "load")])
7690 (define_insn "*tldo_lduw1_sp64"
7691 [(set (match_operand:DI 0 "register_operand" "=r")
7692 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7693 (match_operand 3 "tld_symbolic_operand" "")]
7695 (match_operand:DI 1 "register_operand" "r")))))]
7696 "TARGET_TLS && TARGET_ARCH64"
7697 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7698 [(set_attr "type" "load")])
7700 (define_insn "*tldo_ldsw1_sp64"
7701 [(set (match_operand:DI 0 "register_operand" "=r")
7702 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7703 (match_operand 3 "tld_symbolic_operand" "")]
7705 (match_operand:DI 1 "register_operand" "r")))))]
7706 "TARGET_TLS && TARGET_ARCH64"
7707 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7708 [(set_attr "type" "sload")
7709 (set_attr "us3load_type" "3cycle")])
7711 (define_insn "*tldo_ldx_sp64"
7712 [(set (match_operand:DI 0 "register_operand" "=r")
7713 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7714 (match_operand 3 "tld_symbolic_operand" "")]
7716 (match_operand:DI 1 "register_operand" "r"))))]
7717 "TARGET_TLS && TARGET_ARCH64"
7718 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7719 [(set_attr "type" "load")])
7721 (define_insn "*tldo_stb_sp32"
7722 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7723 (match_operand 3 "tld_symbolic_operand" "")]
7725 (match_operand:SI 1 "register_operand" "r")))
7726 (match_operand:QI 0 "register_operand" "=r"))]
7727 "TARGET_TLS && TARGET_ARCH32"
7728 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7729 [(set_attr "type" "store")])
7731 (define_insn "*tldo_stb_sp64"
7732 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7733 (match_operand 3 "tld_symbolic_operand" "")]
7735 (match_operand:DI 1 "register_operand" "r")))
7736 (match_operand:QI 0 "register_operand" "=r"))]
7737 "TARGET_TLS && TARGET_ARCH64"
7738 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7739 [(set_attr "type" "store")])
7741 (define_insn "*tldo_sth_sp32"
7742 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7743 (match_operand 3 "tld_symbolic_operand" "")]
7745 (match_operand:SI 1 "register_operand" "r")))
7746 (match_operand:HI 0 "register_operand" "=r"))]
7747 "TARGET_TLS && TARGET_ARCH32"
7748 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7749 [(set_attr "type" "store")])
7751 (define_insn "*tldo_sth_sp64"
7752 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7753 (match_operand 3 "tld_symbolic_operand" "")]
7755 (match_operand:DI 1 "register_operand" "r")))
7756 (match_operand:HI 0 "register_operand" "=r"))]
7757 "TARGET_TLS && TARGET_ARCH64"
7758 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7759 [(set_attr "type" "store")])
7761 (define_insn "*tldo_stw_sp32"
7762 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7763 (match_operand 3 "tld_symbolic_operand" "")]
7765 (match_operand:SI 1 "register_operand" "r")))
7766 (match_operand:SI 0 "register_operand" "=r"))]
7767 "TARGET_TLS && TARGET_ARCH32"
7768 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7769 [(set_attr "type" "store")])
7771 (define_insn "*tldo_stw_sp64"
7772 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7773 (match_operand 3 "tld_symbolic_operand" "")]
7775 (match_operand:DI 1 "register_operand" "r")))
7776 (match_operand:SI 0 "register_operand" "=r"))]
7777 "TARGET_TLS && TARGET_ARCH64"
7778 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7779 [(set_attr "type" "store")])
7781 (define_insn "*tldo_stx_sp64"
7782 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7783 (match_operand 3 "tld_symbolic_operand" "")]
7785 (match_operand:DI 1 "register_operand" "r")))
7786 (match_operand:DI 0 "register_operand" "=r"))]
7787 "TARGET_TLS && TARGET_ARCH64"
7788 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7789 [(set_attr "type" "store")])
7792 ;; Stack protector instructions.
7794 (define_expand "stack_protect_set"
7795 [(match_operand 0 "memory_operand" "")
7796 (match_operand 1 "memory_operand" "")]
7799 #ifdef TARGET_THREAD_SSP_OFFSET
7800 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7801 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7802 operands[1] = gen_rtx_MEM (Pmode, addr);
7805 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7807 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7811 (define_insn "stack_protect_setsi"
7812 [(set (match_operand:SI 0 "memory_operand" "=m")
7813 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7814 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7816 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7817 [(set_attr "type" "multi")
7818 (set_attr "length" "3")])
7820 (define_insn "stack_protect_setdi"
7821 [(set (match_operand:DI 0 "memory_operand" "=m")
7822 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7823 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7825 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7826 [(set_attr "type" "multi")
7827 (set_attr "length" "3")])
7829 (define_expand "stack_protect_test"
7830 [(match_operand 0 "memory_operand" "")
7831 (match_operand 1 "memory_operand" "")
7832 (match_operand 2 "" "")]
7836 #ifdef TARGET_THREAD_SSP_OFFSET
7837 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7838 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7839 operands[1] = gen_rtx_MEM (Pmode, addr);
7843 result = gen_reg_rtx (Pmode);
7844 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7845 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7846 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7850 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7851 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7852 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7853 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7858 (define_insn "stack_protect_testsi"
7859 [(set (reg:CC CC_REG)
7860 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7861 (match_operand:SI 1 "memory_operand" "m")]
7863 (set (match_scratch:SI 3 "=r") (const_int 0))
7864 (clobber (match_scratch:SI 2 "=&r"))]
7866 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7867 [(set_attr "type" "multi")
7868 (set_attr "length" "4")])
7870 (define_insn "stack_protect_testdi"
7871 [(set (match_operand:DI 0 "register_operand" "=&r")
7872 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7873 (match_operand:DI 2 "memory_operand" "m")]
7875 (set (match_scratch:DI 3 "=r") (const_int 0))]
7877 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7878 [(set_attr "type" "multi")
7879 (set_attr "length" "4")])
7882 ;; Vector instructions.
7884 (define_insn "addv2si3"
7885 [(set (match_operand:V2SI 0 "register_operand" "=e")
7886 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7887 (match_operand:V2SI 2 "register_operand" "e")))]
7889 "fpadd32\t%1, %2, %0"
7890 [(set_attr "type" "fga")
7891 (set_attr "fptype" "double")])
7893 (define_insn "addv4hi3"
7894 [(set (match_operand:V4HI 0 "register_operand" "=e")
7895 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7896 (match_operand:V4HI 2 "register_operand" "e")))]
7898 "fpadd16\t%1, %2, %0"
7899 [(set_attr "type" "fga")
7900 (set_attr "fptype" "double")])
7902 ;; fpadd32s is emitted by the addsi3 pattern.
7904 (define_insn "addv2hi3"
7905 [(set (match_operand:V2HI 0 "register_operand" "=f")
7906 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7907 (match_operand:V2HI 2 "register_operand" "f")))]
7909 "fpadd16s\t%1, %2, %0"
7910 [(set_attr "type" "fga")
7911 (set_attr "fptype" "single")])
7913 (define_insn "subv2si3"
7914 [(set (match_operand:V2SI 0 "register_operand" "=e")
7915 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7916 (match_operand:V2SI 2 "register_operand" "e")))]
7918 "fpsub32\t%1, %2, %0"
7919 [(set_attr "type" "fga")
7920 (set_attr "fptype" "double")])
7922 (define_insn "subv4hi3"
7923 [(set (match_operand:V4HI 0 "register_operand" "=e")
7924 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7925 (match_operand:V4HI 2 "register_operand" "e")))]
7927 "fpsub16\t%1, %2, %0"
7928 [(set_attr "type" "fga")
7929 (set_attr "fptype" "double")])
7931 ;; fpsub32s is emitted by the subsi3 pattern.
7933 (define_insn "subv2hi3"
7934 [(set (match_operand:V2HI 0 "register_operand" "=f")
7935 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7936 (match_operand:V2HI 2 "register_operand" "f")))]
7938 "fpsub16s\t%1, %2, %0"
7939 [(set_attr "type" "fga")
7940 (set_attr "fptype" "single")])
7942 ;; All other logical instructions have integer equivalents so they
7943 ;; are defined together.
7945 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7947 (define_insn "*nand<V64:mode>_vis"
7948 [(set (match_operand:V64 0 "register_operand" "=e")
7949 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7950 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7953 [(set_attr "type" "fga")
7954 (set_attr "fptype" "double")])
7956 (define_insn "*nand<V32:mode>_vis"
7957 [(set (match_operand:V32 0 "register_operand" "=f")
7958 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7959 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7961 "fnands\t%1, %2, %0"
7962 [(set_attr "type" "fga")
7963 (set_attr "fptype" "single")])
7965 ;; Hard to generate VIS instructions. We have builtins for these.
7967 (define_insn "fpack16_vis"
7968 [(set (match_operand:V4QI 0 "register_operand" "=f")
7969 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
7974 [(set_attr "type" "fga")
7975 (set_attr "fptype" "double")])
7977 (define_insn "fpackfix_vis"
7978 [(set (match_operand:V2HI 0 "register_operand" "=f")
7979 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
7984 [(set_attr "type" "fga")
7985 (set_attr "fptype" "double")])
7987 (define_insn "fpack32_vis"
7988 [(set (match_operand:V8QI 0 "register_operand" "=e")
7989 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7990 (match_operand:V8QI 2 "register_operand" "e")
7994 "fpack32\t%1, %2, %0"
7995 [(set_attr "type" "fga")
7996 (set_attr "fptype" "double")])
7998 (define_insn "fexpand_vis"
7999 [(set (match_operand:V4HI 0 "register_operand" "=e")
8000 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8004 [(set_attr "type" "fga")
8005 (set_attr "fptype" "double")])
8007 ;; It may be possible to describe this operation as (1 indexed):
8008 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8009 ;; 1,5,10,14,19,23,28,32)
8010 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8011 ;; because vec_merge expects all the operands to be of the same type.
8012 (define_insn "fpmerge_vis"
8013 [(set (match_operand:V8QI 0 "register_operand" "=e")
8014 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8015 (match_operand:V4QI 2 "register_operand" "f")]
8018 "fpmerge\t%1, %2, %0"
8019 [(set_attr "type" "fga")
8020 (set_attr "fptype" "double")])
8022 ;; Partitioned multiply instructions
8023 (define_insn "fmul8x16_vis"
8024 [(set (match_operand:V4HI 0 "register_operand" "=e")
8025 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8026 (match_operand:V4HI 2 "register_operand" "e")))]
8028 "fmul8x16\t%1, %2, %0"
8029 [(set_attr "type" "fpmul")
8030 (set_attr "fptype" "double")])
8032 ;; Only one of the following two insns can be a multiply.
8033 (define_insn "fmul8x16au_vis"
8034 [(set (match_operand:V4HI 0 "register_operand" "=e")
8035 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8036 (match_operand:V2HI 2 "register_operand" "f")))]
8038 "fmul8x16au\t%1, %2, %0"
8039 [(set_attr "type" "fpmul")
8040 (set_attr "fptype" "double")])
8042 (define_insn "fmul8x16al_vis"
8043 [(set (match_operand:V4HI 0 "register_operand" "=e")
8044 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8045 (match_operand:V2HI 2 "register_operand" "f")]
8048 "fmul8x16al\t%1, %2, %0"
8049 [(set_attr "type" "fpmul")
8050 (set_attr "fptype" "double")])
8052 ;; Only one of the following two insns can be a multiply.
8053 (define_insn "fmul8sux16_vis"
8054 [(set (match_operand:V4HI 0 "register_operand" "=e")
8055 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8056 (match_operand:V4HI 2 "register_operand" "e")))]
8058 "fmul8sux16\t%1, %2, %0"
8059 [(set_attr "type" "fpmul")
8060 (set_attr "fptype" "double")])
8062 (define_insn "fmul8ulx16_vis"
8063 [(set (match_operand:V4HI 0 "register_operand" "=e")
8064 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8065 (match_operand:V4HI 2 "register_operand" "e")]
8068 "fmul8ulx16\t%1, %2, %0"
8069 [(set_attr "type" "fpmul")
8070 (set_attr "fptype" "double")])
8072 ;; Only one of the following two insns can be a multiply.
8073 (define_insn "fmuld8sux16_vis"
8074 [(set (match_operand:V2SI 0 "register_operand" "=e")
8075 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8076 (match_operand:V2HI 2 "register_operand" "f")))]
8078 "fmuld8sux16\t%1, %2, %0"
8079 [(set_attr "type" "fpmul")
8080 (set_attr "fptype" "double")])
8082 (define_insn "fmuld8ulx16_vis"
8083 [(set (match_operand:V2SI 0 "register_operand" "=e")
8084 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8085 (match_operand:V2HI 2 "register_operand" "f")]
8088 "fmuld8ulx16\t%1, %2, %0"
8089 [(set_attr "type" "fpmul")
8090 (set_attr "fptype" "double")])
8092 (define_expand "wrgsr_vis"
8093 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8096 if (! TARGET_ARCH64)
8098 emit_insn (gen_wrgsr_v8plus (operands[0]));
8103 (define_insn "*wrgsr_sp64"
8104 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8105 "TARGET_VIS && TARGET_ARCH64"
8106 "wr\t%%g0, %0, %%gsr"
8107 [(set_attr "type" "gsr")])
8109 (define_insn "wrgsr_v8plus"
8110 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8111 (clobber (match_scratch:SI 1 "=X,&h"))]
8112 "TARGET_VIS && ! TARGET_ARCH64"
8114 if (GET_CODE (operands[0]) == CONST_INT
8115 || sparc_check_64 (operands[0], insn))
8116 return "wr\t%%g0, %0, %%gsr";
8118 output_asm_insn("srl\t%L0, 0, %L0", operands);
8119 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8121 [(set_attr "type" "multi")])
8123 (define_expand "rdgsr_vis"
8124 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8127 if (! TARGET_ARCH64)
8129 emit_insn (gen_rdgsr_v8plus (operands[0]));
8134 (define_insn "*rdgsr_sp64"
8135 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8136 "TARGET_VIS && TARGET_ARCH64"
8138 [(set_attr "type" "gsr")])
8140 (define_insn "rdgsr_v8plus"
8141 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8142 (clobber (match_scratch:SI 1 "=&h"))]
8143 "TARGET_VIS && ! TARGET_ARCH64"
8145 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8147 [(set_attr "type" "multi")])
8149 ;; Using faligndata only makes sense after an alignaddr since the choice of
8150 ;; bytes to take out of each operand is dependent on the results of the last
8152 (define_insn "faligndata<V64I:mode>_vis"
8153 [(set (match_operand:V64I 0 "register_operand" "=e")
8154 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8155 (match_operand:V64I 2 "register_operand" "e")
8159 "faligndata\t%1, %2, %0"
8160 [(set_attr "type" "fga")
8161 (set_attr "fptype" "double")])
8163 (define_insn "alignaddrsi_vis"
8164 [(set (match_operand:SI 0 "register_operand" "=r")
8165 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8166 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8167 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8168 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8170 "alignaddr\t%r1, %r2, %0")
8172 (define_insn "alignaddrdi_vis"
8173 [(set (match_operand:DI 0 "register_operand" "=r")
8174 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8175 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8176 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8177 (plus:DI (match_dup 1) (match_dup 2)))]
8179 "alignaddr\t%r1, %r2, %0")
8181 (define_insn "alignaddrlsi_vis"
8182 [(set (match_operand:SI 0 "register_operand" "=r")
8183 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8184 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8185 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8186 (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8189 "alignaddrl\t%r1, %r2, %0")
8191 (define_insn "alignaddrldi_vis"
8192 [(set (match_operand:DI 0 "register_operand" "=r")
8193 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8194 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8195 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8196 (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8199 "alignaddrl\t%r1, %r2, %0")
8201 (define_insn "pdist_vis"
8202 [(set (match_operand:DI 0 "register_operand" "=e")
8203 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8204 (match_operand:V8QI 2 "register_operand" "e")
8205 (match_operand:DI 3 "register_operand" "0")]
8209 [(set_attr "type" "fga")
8210 (set_attr "fptype" "double")])
8212 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8213 ;; with the same operands.
8214 (define_insn "edge8<P:mode>_vis"
8215 [(set (reg:CC_NOOV CC_REG)
8216 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8217 (match_operand:P 2 "register_operand" "rJ"))
8219 (set (match_operand:P 0 "register_operand" "=r")
8220 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8222 "edge8\t%r1, %r2, %0"
8223 [(set_attr "type" "edge")])
8225 (define_insn "edge8l<P:mode>_vis"
8226 [(set (reg:CC_NOOV CC_REG)
8227 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8228 (match_operand:P 2 "register_operand" "rJ"))
8230 (set (match_operand:P 0 "register_operand" "=r")
8231 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8233 "edge8l\t%r1, %r2, %0"
8234 [(set_attr "type" "edge")])
8236 (define_insn "edge16<P:mode>_vis"
8237 [(set (reg:CC_NOOV CC_REG)
8238 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8239 (match_operand:P 2 "register_operand" "rJ"))
8241 (set (match_operand:P 0 "register_operand" "=r")
8242 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8244 "edge16\t%r1, %r2, %0"
8245 [(set_attr "type" "edge")])
8247 (define_insn "edge16l<P:mode>_vis"
8248 [(set (reg:CC_NOOV CC_REG)
8249 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8250 (match_operand:P 2 "register_operand" "rJ"))
8252 (set (match_operand:P 0 "register_operand" "=r")
8253 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8255 "edge16l\t%r1, %r2, %0"
8256 [(set_attr "type" "edge")])
8258 (define_insn "edge32<P:mode>_vis"
8259 [(set (reg:CC_NOOV CC_REG)
8260 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8261 (match_operand:P 2 "register_operand" "rJ"))
8263 (set (match_operand:P 0 "register_operand" "=r")
8264 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8266 "edge32\t%r1, %r2, %0"
8267 [(set_attr "type" "edge")])
8269 (define_insn "edge32l<P:mode>_vis"
8270 [(set (reg:CC_NOOV CC_REG)
8271 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8272 (match_operand:P 2 "register_operand" "rJ"))
8274 (set (match_operand:P 0 "register_operand" "=r")
8275 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8277 "edge32l\t%r1, %r2, %0"
8278 [(set_attr "type" "edge")])
8280 (define_code_iterator gcond [le ne gt eq])
8281 (define_mode_iterator GCM [V4HI V2SI])
8282 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8284 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8285 [(set (match_operand:P 0 "register_operand" "=r")
8286 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8287 (match_operand:GCM 2 "register_operand" "e"))]
8290 "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8291 [(set_attr "type" "fpmul")
8292 (set_attr "fptype" "double")])
8294 (define_insn "array8<P:mode>_vis"
8295 [(set (match_operand:P 0 "register_operand" "=r")
8296 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8297 (match_operand:P 2 "register_operand" "rJ")]
8300 "array8\t%r1, %r2, %0"
8301 [(set_attr "type" "array")])
8303 (define_insn "array16<P:mode>_vis"
8304 [(set (match_operand:P 0 "register_operand" "=r")
8305 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8306 (match_operand:P 2 "register_operand" "rJ")]
8309 "array16\t%r1, %r2, %0"
8310 [(set_attr "type" "array")])
8312 (define_insn "array32<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 "array32\t%r1, %r2, %0"
8319 [(set_attr "type" "array")])
8321 (define_insn "bmaskdi_vis"
8322 [(set (match_operand:DI 0 "register_operand" "=r")
8323 (plus:DI (match_operand:DI 1 "register_operand" "rJ")
8324 (match_operand:DI 2 "register_operand" "rJ")))
8325 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8326 (plus:DI (match_dup 1) (match_dup 2)))]
8328 "bmask\t%r1, %r2, %0"
8329 [(set_attr "type" "array")])
8331 (define_insn "bmasksi_vis"
8332 [(set (match_operand:SI 0 "register_operand" "=r")
8333 (plus:SI (match_operand:SI 1 "register_operand" "rJ")
8334 (match_operand:SI 2 "register_operand" "rJ")))
8335 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8336 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8338 "bmask\t%r1, %r2, %0"
8339 [(set_attr "type" "array")])
8341 (define_insn "bshuffle<V64I:mode>_vis"
8342 [(set (match_operand:V64I 0 "register_operand" "=e")
8343 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8344 (match_operand:V64I 2 "register_operand" "e")
8348 "bshuffle\t%1, %2, %0"
8349 [(set_attr "type" "fga")
8350 (set_attr "fptype" "double")])
8352 ;; VIS 2.0 adds edge variants which do not set the condition codes
8353 (define_insn "edge8n<P:mode>_vis"
8354 [(set (match_operand:P 0 "register_operand" "=r")
8355 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8356 (match_operand:P 2 "register_operand" "rJ")]
8359 "edge8n\t%r1, %r2, %0"
8360 [(set_attr "type" "edgen")])
8362 (define_insn "edge8ln<P:mode>_vis"
8363 [(set (match_operand:P 0 "register_operand" "=r")
8364 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8365 (match_operand:P 2 "register_operand" "rJ")]
8368 "edge8ln\t%r1, %r2, %0"
8369 [(set_attr "type" "edgen")])
8371 (define_insn "edge16n<P:mode>_vis"
8372 [(set (match_operand:P 0 "register_operand" "=r")
8373 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8374 (match_operand:P 2 "register_operand" "rJ")]
8377 "edge16n\t%r1, %r2, %0"
8378 [(set_attr "type" "edgen")])
8380 (define_insn "edge16ln<P:mode>_vis"
8381 [(set (match_operand:P 0 "register_operand" "=r")
8382 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8383 (match_operand:P 2 "register_operand" "rJ")]
8386 "edge16ln\t%r1, %r2, %0"
8387 [(set_attr "type" "edgen")])
8389 (define_insn "edge32n<P:mode>_vis"
8390 [(set (match_operand:P 0 "register_operand" "=r")
8391 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8392 (match_operand:P 2 "register_operand" "rJ")]
8395 "edge32n\t%r1, %r2, %0"
8396 [(set_attr "type" "edgen")])
8398 (define_insn "edge32ln<P:mode>_vis"
8399 [(set (match_operand:P 0 "register_operand" "=r")
8400 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8401 (match_operand:P 2 "register_operand" "rJ")]
8404 "edge32ln\t%r1, %r2, %0"
8405 [(set_attr "type" "edge")])
8407 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8408 (define_insn "cmask8<P:mode>_vis"
8409 [(set (reg:DI GSR_REG)
8410 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8416 (define_insn "cmask16<P:mode>_vis"
8417 [(set (reg:DI GSR_REG)
8418 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8424 (define_insn "cmask32<P:mode>_vis"
8425 [(set (reg:DI GSR_REG)
8426 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8432 (define_insn "fchksm16_vis"
8433 [(set (match_operand:V4HI 0 "register_operand" "=e")
8434 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8435 (match_operand:V4HI 2 "register_operand" "e")]
8438 "fchksm16\t%1, %2, %0")
8440 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8441 (define_code_attr vis3_shift_insn
8442 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8444 (define_insn "<vis3_shift_insn><vbits>_vis"
8445 [(set (match_operand:V64N8 0 "register_operand" "=<vconstr>")
8446 (vis3_shift:V64N8 (match_operand:V64N8 1 "register_operand" "<vconstr>")
8447 (match_operand:V64N8 2 "register_operand" "<vconstr>")))]
8449 "<vis3_shift_insn><vbits>\t%1, %2, %0")
8451 (define_insn "pdistn<mode>_vis"
8452 [(set (match_operand:P 0 "register_operand" "=r")
8453 (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8454 (match_operand:V8QI 2 "register_operand" "e")]
8457 "pdistn\t%1, %2, %0")
8459 (define_insn "fmean16_vis"
8460 [(set (match_operand:V4HI 0 "register_operand" "=e")
8466 (match_operand:V4HI 1 "register_operand" "e"))
8468 (match_operand:V4HI 2 "register_operand" "e")))
8469 (const_vector:V4SI [(const_int 1) (const_int 1)
8470 (const_int 1) (const_int 1)]))
8473 "fmean16\t%1, %2, %0")
8475 (define_insn "fpadd64_vis"
8476 [(set (match_operand:DI 0 "register_operand" "=e")
8477 (plus:DI (match_operand:DI 1 "register_operand" "e")
8478 (match_operand:DI 2 "register_operand" "e")))]
8480 "fpadd64\t%1, %2, %0")
8482 (define_insn "fpsub64_vis"
8483 [(set (match_operand:DI 0 "register_operand" "=e")
8484 (minus:DI (match_operand:DI 1 "register_operand" "e")
8485 (match_operand:DI 2 "register_operand" "e")))]
8487 "fpsub64\t%1, %2, %0")
8489 (define_mode_iterator VASS [V4HI V2SI V2HI SI])
8490 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8491 (define_code_attr vis3_addsub_ss_insn
8492 [(ss_plus "fpadds") (ss_minus "fpsubs")])
8494 (define_insn "<vis3_addsub_ss_insn><vbits>_vis"
8495 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8496 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8497 (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8499 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0")
8501 (define_insn "fucmp<code>8<P:mode>_vis"
8502 [(set (match_operand:P 0 "register_operand" "=r")
8503 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8504 (match_operand:V8QI 2 "register_operand" "e"))]
8507 "fucmp<code>8\t%1, %2, %0")
8509 (define_insn "*naddsf3"
8510 [(set (match_operand:SF 0 "register_operand" "=f")
8511 (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8512 (match_operand:SF 2 "register_operand" "f"))))]
8514 "fnadds\t%1, %2, %0"
8515 [(set_attr "type" "fp")])
8517 (define_insn "*nadddf3"
8518 [(set (match_operand:DF 0 "register_operand" "=e")
8519 (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8520 (match_operand:DF 2 "register_operand" "e"))))]
8522 "fnaddd\t%1, %2, %0"
8523 [(set_attr "type" "fp")
8524 (set_attr "fptype" "double")])
8526 (define_insn "*nmulsf3"
8527 [(set (match_operand:SF 0 "register_operand" "=f")
8528 (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8529 (match_operand:SF 2 "register_operand" "f")))]
8531 "fnmuls\t%1, %2, %0"
8532 [(set_attr "type" "fpmul")])
8534 (define_insn "*nmuldf3"
8535 [(set (match_operand:DF 0 "register_operand" "=e")
8536 (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8537 (match_operand:DF 2 "register_operand" "e")))]
8539 "fnmuld\t%1, %2, %0"
8540 [(set_attr "type" "fpmul")
8541 (set_attr "fptype" "double")])
8543 (define_insn "*nmuldf3_extend"
8544 [(set (match_operand:DF 0 "register_operand" "=e")
8545 (mult:DF (neg:DF (float_extend:DF
8546 (match_operand:SF 1 "register_operand" "f")))
8548 (match_operand:SF 2 "register_operand" "f"))))]
8550 "fnsmuld\t%1, %2, %0"
8551 [(set_attr "type" "fpmul")
8552 (set_attr "fptype" "double")])
8554 (define_insn "fhaddsf_vis"
8555 [(set (match_operand:SF 0 "register_operand" "=f")
8556 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8557 (match_operand:SF 2 "register_operand" "f")]
8560 "fhadds\t%1, %2, %0"
8561 [(set_attr "type" "fp")])
8563 (define_insn "fhadddf_vis"
8564 [(set (match_operand:DF 0 "register_operand" "=f")
8565 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8566 (match_operand:DF 2 "register_operand" "f")]
8569 "fhaddd\t%1, %2, %0"
8570 [(set_attr "type" "fp")
8571 (set_attr "fptype" "double")])
8573 (define_insn "fhsubsf_vis"
8574 [(set (match_operand:SF 0 "register_operand" "=f")
8575 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8576 (match_operand:SF 2 "register_operand" "f")]
8579 "fhsubs\t%1, %2, %0"
8580 [(set_attr "type" "fp")])
8582 (define_insn "fhsubdf_vis"
8583 [(set (match_operand:DF 0 "register_operand" "=f")
8584 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8585 (match_operand:DF 2 "register_operand" "f")]
8588 "fhsubd\t%1, %2, %0"
8589 [(set_attr "type" "fp")
8590 (set_attr "fptype" "double")])
8592 (define_insn "fnhaddsf_vis"
8593 [(set (match_operand:SF 0 "register_operand" "=f")
8594 (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8595 (match_operand:SF 2 "register_operand" "f")]
8598 "fnhadds\t%1, %2, %0"
8599 [(set_attr "type" "fp")])
8601 (define_insn "fnhadddf_vis"
8602 [(set (match_operand:DF 0 "register_operand" "=f")
8603 (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8604 (match_operand:DF 2 "register_operand" "f")]
8607 "fnhaddd\t%1, %2, %0"
8608 [(set_attr "type" "fp")
8609 (set_attr "fptype" "double")])
8611 (define_expand "umulxhi_vis"
8612 [(set (match_operand:DI 0 "register_operand" "")
8615 (mult:TI (zero_extend:TI
8616 (match_operand:DI 1 "arith_operand" ""))
8618 (match_operand:DI 2 "arith_operand" "")))
8622 if (! TARGET_ARCH64)
8624 emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8629 (define_insn "*umulxhi_sp64"
8630 [(set (match_operand:DI 0 "register_operand" "=r")
8633 (mult:TI (zero_extend:TI
8634 (match_operand:DI 1 "arith_operand" "%r"))
8636 (match_operand:DI 2 "arith_operand" "rI")))
8638 "TARGET_VIS3 && TARGET_ARCH64"
8639 "umulxhi\t%1, %2, %0"
8640 [(set_attr "type" "imul")])
8642 (define_insn "umulxhi_v8plus"
8643 [(set (match_operand:DI 0 "register_operand" "=r,h")
8646 (mult:TI (zero_extend:TI
8647 (match_operand:DI 1 "arith_operand" "%r,0"))
8649 (match_operand:DI 2 "arith_operand" "rI,rI")))
8651 (clobber (match_scratch:SI 3 "=&h,X"))
8652 (clobber (match_scratch:SI 4 "=&h,X"))]
8653 "TARGET_VIS3 && ! TARGET_ARCH64"
8654 "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8655 [(set_attr "type" "imul")
8656 (set_attr "length" "9,8")])
8658 (define_expand "xmulx_vis"
8659 [(set (match_operand:DI 0 "register_operand" "")
8661 (unspec:TI [(zero_extend:TI
8662 (match_operand:DI 1 "arith_operand" ""))
8664 (match_operand:DI 2 "arith_operand" ""))]
8668 if (! TARGET_ARCH64)
8670 emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8675 (define_insn "*xmulx_sp64"
8676 [(set (match_operand:DI 0 "register_operand" "=r")
8678 (unspec:TI [(zero_extend:TI
8679 (match_operand:DI 1 "arith_operand" "%r"))
8681 (match_operand:DI 2 "arith_operand" "rI"))]
8683 "TARGET_VIS3 && TARGET_ARCH64"
8685 [(set_attr "type" "imul")])
8687 (define_insn "xmulx_v8plus"
8688 [(set (match_operand:DI 0 "register_operand" "=r,h")
8690 (unspec:TI [(zero_extend:TI
8691 (match_operand:DI 1 "arith_operand" "%r,0"))
8693 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8695 (clobber (match_scratch:SI 3 "=&h,X"))
8696 (clobber (match_scratch:SI 4 "=&h,X"))]
8697 "TARGET_VIS3 && ! TARGET_ARCH64"
8698 "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8699 [(set_attr "type" "imul")
8700 (set_attr "length" "9,8")])
8702 (define_expand "xmulxhi_vis"
8703 [(set (match_operand:DI 0 "register_operand" "")
8706 (unspec:TI [(zero_extend:TI
8707 (match_operand:DI 1 "arith_operand" ""))
8709 (match_operand:DI 2 "arith_operand" ""))]
8714 if (! TARGET_ARCH64)
8716 emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
8721 (define_insn "*xmulxhi_sp64"
8722 [(set (match_operand:DI 0 "register_operand" "=r")
8725 (unspec:TI [(zero_extend:TI
8726 (match_operand:DI 1 "arith_operand" "%r"))
8728 (match_operand:DI 2 "arith_operand" "rI"))]
8731 "TARGET_VIS3 && TARGET_ARCH64"
8732 "xmulxhi\t%1, %2, %0"
8733 [(set_attr "type" "imul")])
8735 (define_insn "xmulxhi_v8plus"
8736 [(set (match_operand:DI 0 "register_operand" "=r,h")
8739 (unspec:TI [(zero_extend:TI
8740 (match_operand:DI 1 "arith_operand" "%r,0"))
8742 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8745 (clobber (match_scratch:SI 3 "=&h,X"))
8746 (clobber (match_scratch:SI 4 "=&h,X"))]
8747 "TARGET_VIS3 && !TARGET_ARCH64"
8748 "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
8749 [(set_attr "type" "imul")
8750 (set_attr "length" "9,8")])