1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 ;; 2011 Free Software Foundation, Inc.
5 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
6 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3. If not see
23 ;; <http://www.gnu.org/licenses/>.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (UNSPEC_UPDATE_RETURN 1)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
41 (UNSPEC_MOVE_GOTDATA 19)
50 (UNSPEC_TLSLD_BASE 35)
106 (UNSPECV_PROBE_STACK_RANGE 11)
199 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
200 (define_mode_iterator I [QI HI SI DI])
201 (define_mode_iterator F [SF DF TF])
203 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
204 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
205 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
206 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
207 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
209 ;; Attribute for cpu type.
210 ;; These must match the values for enum processor_type in sparc.h.
231 (const (symbol_ref "sparc_cpu_attr")))
233 ;; Attribute for the instruction set.
234 ;; At present we only need to distinguish v9/!v9, but for clarity we
235 ;; test TARGET_V8 too.
236 (define_attr "isa" "v7,v8,v9,sparclet"
238 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
239 (symbol_ref "TARGET_V8") (const_string "v8")
240 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
241 (const_string "v7"))))
247 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
255 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,edgen,gsr,array,
258 multi,savew,flushw,iflush,trap"
259 (const_string "ialu"))
261 ;; True if branch/call has empty delay slot and will emit a nop in it
262 (define_attr "empty_delay_slot" "false,true"
263 (symbol_ref "(empty_delay_slot (insn)
264 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
266 (define_attr "branch_type" "none,icc,fcc,reg"
267 (const_string "none"))
269 (define_attr "pic" "false,true"
270 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
272 (define_attr "calls_alloca" "false,true"
273 (symbol_ref "(cfun->calls_alloca != 0
274 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
276 (define_attr "calls_eh_return" "false,true"
277 (symbol_ref "(crtl->calls_eh_return != 0
278 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
280 (define_attr "leaf_function" "false,true"
281 (symbol_ref "(current_function_uses_only_leaf_regs != 0
282 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
284 (define_attr "delayed_branch" "false,true"
285 (symbol_ref "(flag_delayed_branch != 0
286 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
288 (define_attr "flat" "false,true"
289 (symbol_ref "(TARGET_FLAT != 0
290 ? FLAT_TRUE : FLAT_FALSE)"))
292 ;; Length (in # of insns).
293 ;; Beware that setting a length greater or equal to 3 for conditional branches
294 ;; has a side-effect (see output_cbranch and output_v9branch).
295 (define_attr "length" ""
296 (cond [(eq_attr "type" "uncond_branch,call")
297 (if_then_else (eq_attr "empty_delay_slot" "true")
300 (eq_attr "type" "sibcall")
301 (if_then_else (eq_attr "leaf_function" "true")
302 (if_then_else (eq_attr "empty_delay_slot" "true")
305 (if_then_else (eq_attr "empty_delay_slot" "true")
308 (eq_attr "branch_type" "icc")
309 (if_then_else (match_operand 0 "noov_compare64_operator" "")
310 (if_then_else (lt (pc) (match_dup 1))
311 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
312 (if_then_else (eq_attr "empty_delay_slot" "true")
315 (if_then_else (eq_attr "empty_delay_slot" "true")
318 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
319 (if_then_else (eq_attr "empty_delay_slot" "true")
322 (if_then_else (eq_attr "empty_delay_slot" "true")
325 (if_then_else (eq_attr "empty_delay_slot" "true")
328 (eq_attr "branch_type" "fcc")
329 (if_then_else (match_operand 0 "fcc0_register_operand" "")
330 (if_then_else (eq_attr "empty_delay_slot" "true")
331 (if_then_else (not (match_test "TARGET_V9"))
334 (if_then_else (not (match_test "TARGET_V9"))
337 (if_then_else (lt (pc) (match_dup 2))
338 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
339 (if_then_else (eq_attr "empty_delay_slot" "true")
342 (if_then_else (eq_attr "empty_delay_slot" "true")
345 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
346 (if_then_else (eq_attr "empty_delay_slot" "true")
349 (if_then_else (eq_attr "empty_delay_slot" "true")
352 (eq_attr "branch_type" "reg")
353 (if_then_else (lt (pc) (match_dup 2))
354 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
355 (if_then_else (eq_attr "empty_delay_slot" "true")
358 (if_then_else (eq_attr "empty_delay_slot" "true")
361 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
362 (if_then_else (eq_attr "empty_delay_slot" "true")
365 (if_then_else (eq_attr "empty_delay_slot" "true")
371 (define_attr "fptype" "single,double"
372 (const_string "single"))
374 ;; UltraSPARC-III integer load type.
375 (define_attr "us3load_type" "2cycle,3cycle"
376 (const_string "2cycle"))
378 (define_asm_attributes
379 [(set_attr "length" "2")
380 (set_attr "type" "multi")])
382 ;; Attributes for instruction and branch scheduling
383 (define_attr "tls_call_delay" "false,true"
384 (symbol_ref "(tls_call_delay (insn)
385 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
387 (define_attr "in_call_delay" "false,true"
388 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
389 (const_string "false")
390 (eq_attr "type" "load,fpload,store,fpstore")
391 (if_then_else (eq_attr "length" "1")
392 (const_string "true")
393 (const_string "false"))]
394 (if_then_else (and (eq_attr "length" "1")
395 (eq_attr "tls_call_delay" "true"))
396 (const_string "true")
397 (const_string "false"))))
399 (define_attr "eligible_for_sibcall_delay" "false,true"
400 (symbol_ref "(eligible_for_sibcall_delay (insn)
401 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
402 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
404 (define_attr "eligible_for_return_delay" "false,true"
405 (symbol_ref "(eligible_for_return_delay (insn)
406 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
407 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
409 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
410 ;; branches. This would allow us to remove the nop always inserted before
411 ;; a floating point branch.
413 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
414 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
415 ;; This is because doing so will add several pipeline stalls to the path
416 ;; that the load/store did not come from. Unfortunately, there is no way
417 ;; to prevent fill_eager_delay_slots from using load/store without completely
418 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
419 ;; because it prevents us from moving back the final store of inner loops.
421 (define_attr "in_branch_delay" "false,true"
422 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
423 (eq_attr "length" "1"))
424 (const_string "true")
425 (const_string "false")))
427 (define_attr "in_uncond_branch_delay" "false,true"
428 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
429 (eq_attr "length" "1"))
430 (const_string "true")
431 (const_string "false")))
433 (define_attr "in_annul_branch_delay" "false,true"
434 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
435 (eq_attr "length" "1"))
436 (const_string "true")
437 (const_string "false")))
439 (define_delay (eq_attr "type" "call")
440 [(eq_attr "in_call_delay" "true") (nil) (nil)])
442 (define_delay (eq_attr "type" "sibcall")
443 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
445 (define_delay (eq_attr "type" "branch")
446 [(eq_attr "in_branch_delay" "true")
447 (nil) (eq_attr "in_annul_branch_delay" "true")])
449 (define_delay (eq_attr "type" "uncond_branch")
450 [(eq_attr "in_uncond_branch_delay" "true")
453 (define_delay (eq_attr "type" "return")
454 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
457 ;; Include SPARC DFA schedulers
459 (include "cypress.md")
460 (include "supersparc.md")
461 (include "hypersparc.md")
463 (include "sparclet.md")
464 (include "ultra1_2.md")
465 (include "ultra3.md")
466 (include "niagara.md")
467 (include "niagara2.md")
470 ;; Operand and operator predicates and constraints
472 (include "predicates.md")
473 (include "constraints.md")
476 ;; Compare instructions.
478 ;; These are just the DEFINE_INSNs to match the patterns and the
479 ;; DEFINE_SPLITs for some of the scc insns that actually require
480 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
482 ;; The compare DEFINE_INSNs.
484 (define_insn "*cmpsi_insn"
485 [(set (reg:CC CC_REG)
486 (compare:CC (match_operand:SI 0 "register_operand" "r")
487 (match_operand:SI 1 "arith_operand" "rI")))]
490 [(set_attr "type" "compare")])
492 (define_insn "*cmpdi_sp64"
493 [(set (reg:CCX CC_REG)
494 (compare:CCX (match_operand:DI 0 "register_operand" "r")
495 (match_operand:DI 1 "arith_operand" "rI")))]
498 [(set_attr "type" "compare")])
500 (define_insn "*cmpsf_fpe"
501 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
502 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
503 (match_operand:SF 2 "register_operand" "f")))]
507 return "fcmpes\t%0, %1, %2";
508 return "fcmpes\t%1, %2";
510 [(set_attr "type" "fpcmp")])
512 (define_insn "*cmpdf_fpe"
513 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
514 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
515 (match_operand:DF 2 "register_operand" "e")))]
519 return "fcmped\t%0, %1, %2";
520 return "fcmped\t%1, %2";
522 [(set_attr "type" "fpcmp")
523 (set_attr "fptype" "double")])
525 (define_insn "*cmptf_fpe"
526 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
527 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
528 (match_operand:TF 2 "register_operand" "e")))]
529 "TARGET_FPU && TARGET_HARD_QUAD"
532 return "fcmpeq\t%0, %1, %2";
533 return "fcmpeq\t%1, %2";
535 [(set_attr "type" "fpcmp")])
537 (define_insn "*cmpsf_fp"
538 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
539 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
540 (match_operand:SF 2 "register_operand" "f")))]
544 return "fcmps\t%0, %1, %2";
545 return "fcmps\t%1, %2";
547 [(set_attr "type" "fpcmp")])
549 (define_insn "*cmpdf_fp"
550 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
551 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
552 (match_operand:DF 2 "register_operand" "e")))]
556 return "fcmpd\t%0, %1, %2";
557 return "fcmpd\t%1, %2";
559 [(set_attr "type" "fpcmp")
560 (set_attr "fptype" "double")])
562 (define_insn "*cmptf_fp"
563 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
564 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
565 (match_operand:TF 2 "register_operand" "e")))]
566 "TARGET_FPU && TARGET_HARD_QUAD"
569 return "fcmpq\t%0, %1, %2";
570 return "fcmpq\t%1, %2";
572 [(set_attr "type" "fpcmp")])
574 ;; Next come the scc insns.
576 (define_expand "cstoresi4"
577 [(use (match_operator 1 "comparison_operator"
578 [(match_operand:SI 2 "compare_operand" "")
579 (match_operand:SI 3 "arith_operand" "")]))
580 (clobber (match_operand:SI 0 "register_operand"))]
583 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
584 operands[2] = force_reg (SImode, operands[2]);
585 if (emit_scc_insn (operands)) DONE; else FAIL;
588 (define_expand "cstoredi4"
589 [(use (match_operator 1 "comparison_operator"
590 [(match_operand:DI 2 "compare_operand" "")
591 (match_operand:DI 3 "arith_operand" "")]))
592 (clobber (match_operand:SI 0 "register_operand"))]
595 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
596 operands[2] = force_reg (DImode, operands[2]);
597 if (emit_scc_insn (operands)) DONE; else FAIL;
600 (define_expand "cstore<F:mode>4"
601 [(use (match_operator 1 "comparison_operator"
602 [(match_operand:F 2 "register_operand" "")
603 (match_operand:F 3 "register_operand" "")]))
604 (clobber (match_operand:SI 0 "register_operand"))]
606 { if (emit_scc_insn (operands)) DONE; else FAIL; })
610 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
611 ;; generate addcc/subcc instructions.
613 (define_expand "seqsi_special"
615 (xor:SI (match_operand:SI 1 "register_operand" "")
616 (match_operand:SI 2 "register_operand" "")))
617 (parallel [(set (match_operand:SI 0 "register_operand" "")
618 (eq:SI (match_dup 3) (const_int 0)))
619 (clobber (reg:CC CC_REG))])]
621 { operands[3] = gen_reg_rtx (SImode); })
623 (define_expand "seqdi_special"
625 (xor:DI (match_operand:DI 1 "register_operand" "")
626 (match_operand:DI 2 "register_operand" "")))
627 (set (match_operand:SI 0 "register_operand" "")
628 (eq:SI (match_dup 3) (const_int 0)))]
630 { operands[3] = gen_reg_rtx (DImode); })
632 (define_expand "snesi_special"
634 (xor:SI (match_operand:SI 1 "register_operand" "")
635 (match_operand:SI 2 "register_operand" "")))
636 (parallel [(set (match_operand:SI 0 "register_operand" "")
637 (ne:SI (match_dup 3) (const_int 0)))
638 (clobber (reg:CC CC_REG))])]
640 { operands[3] = gen_reg_rtx (SImode); })
642 (define_expand "snedi_special"
644 (xor:DI (match_operand:DI 1 "register_operand" "")
645 (match_operand:DI 2 "register_operand" "")))
646 (set (match_operand:SI 0 "register_operand" "")
647 (ne:SI (match_dup 3) (const_int 0)))]
649 { operands[3] = gen_reg_rtx (DImode); })
652 ;; Now the DEFINE_INSNs for the scc cases.
654 ;; The SEQ and SNE patterns are special because they can be done
655 ;; without any branching and do not involve a COMPARE. We want
656 ;; them to always use the splits below so the results can be
659 (define_insn_and_split "*snesi_zero"
660 [(set (match_operand:SI 0 "register_operand" "=r")
661 (ne:SI (match_operand:SI 1 "register_operand" "r")
663 (clobber (reg:CC CC_REG))]
667 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
669 (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
671 [(set_attr "length" "2")])
673 (define_insn_and_split "*neg_snesi_zero"
674 [(set (match_operand:SI 0 "register_operand" "=r")
675 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
677 (clobber (reg:CC CC_REG))]
681 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
683 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
685 [(set_attr "length" "2")])
687 (define_insn_and_split "*snesi_zero_extend"
688 [(set (match_operand:DI 0 "register_operand" "=r")
689 (ne:DI (match_operand:SI 1 "register_operand" "r")
691 (clobber (reg:CC CC_REG))]
695 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
698 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
700 (ltu:SI (reg:CC_NOOV CC_REG)
703 [(set_attr "length" "2")])
705 (define_insn_and_split "*snedi_zero"
706 [(set (match_operand:DI 0 "register_operand" "=&r")
707 (ne:DI (match_operand:DI 1 "register_operand" "r")
711 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
712 [(set (match_dup 0) (const_int 0))
713 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
718 [(set_attr "length" "2")])
720 (define_insn_and_split "*neg_snedi_zero"
721 [(set (match_operand:DI 0 "register_operand" "=&r")
722 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
726 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
727 [(set (match_dup 0) (const_int 0))
728 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
733 [(set_attr "length" "2")])
735 (define_insn_and_split "*snedi_zero_trunc"
736 [(set (match_operand:SI 0 "register_operand" "=&r")
737 (ne:SI (match_operand:DI 1 "register_operand" "r")
741 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
742 [(set (match_dup 0) (const_int 0))
743 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
748 [(set_attr "length" "2")])
750 (define_insn_and_split "*seqsi_zero"
751 [(set (match_operand:SI 0 "register_operand" "=r")
752 (eq:SI (match_operand:SI 1 "register_operand" "r")
754 (clobber (reg:CC CC_REG))]
758 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
760 (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
762 [(set_attr "length" "2")])
764 (define_insn_and_split "*neg_seqsi_zero"
765 [(set (match_operand:SI 0 "register_operand" "=r")
766 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
768 (clobber (reg:CC CC_REG))]
772 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
774 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
776 [(set_attr "length" "2")])
778 (define_insn_and_split "*seqsi_zero_extend"
779 [(set (match_operand:DI 0 "register_operand" "=r")
780 (eq:DI (match_operand:SI 1 "register_operand" "r")
782 (clobber (reg:CC CC_REG))]
786 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
789 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
791 (ltu:SI (reg:CC_NOOV CC_REG)
794 [(set_attr "length" "2")])
796 (define_insn_and_split "*seqdi_zero"
797 [(set (match_operand:DI 0 "register_operand" "=&r")
798 (eq:DI (match_operand:DI 1 "register_operand" "r")
802 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
803 [(set (match_dup 0) (const_int 0))
804 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
809 [(set_attr "length" "2")])
811 (define_insn_and_split "*neg_seqdi_zero"
812 [(set (match_operand:DI 0 "register_operand" "=&r")
813 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
817 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
818 [(set (match_dup 0) (const_int 0))
819 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
824 [(set_attr "length" "2")])
826 (define_insn_and_split "*seqdi_zero_trunc"
827 [(set (match_operand:SI 0 "register_operand" "=&r")
828 (eq:SI (match_operand:DI 1 "register_operand" "r")
832 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
833 [(set (match_dup 0) (const_int 0))
834 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
839 [(set_attr "length" "2")])
841 ;; We can also do (x + (i == 0)) and related, so put them in.
842 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
845 (define_insn_and_split "*x_plus_i_ne_0"
846 [(set (match_operand:SI 0 "register_operand" "=r")
847 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
849 (match_operand:SI 2 "register_operand" "r")))
850 (clobber (reg:CC CC_REG))]
854 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
856 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
859 [(set_attr "length" "2")])
861 (define_insn_and_split "*x_minus_i_ne_0"
862 [(set (match_operand:SI 0 "register_operand" "=r")
863 (minus:SI (match_operand:SI 2 "register_operand" "r")
864 (ne:SI (match_operand:SI 1 "register_operand" "r")
866 (clobber (reg:CC CC_REG))]
870 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
872 (set (match_dup 0) (minus:SI (match_dup 2)
873 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
875 [(set_attr "length" "2")])
877 (define_insn_and_split "*x_plus_i_eq_0"
878 [(set (match_operand:SI 0 "register_operand" "=r")
879 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
881 (match_operand:SI 2 "register_operand" "r")))
882 (clobber (reg:CC CC_REG))]
886 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
888 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
891 [(set_attr "length" "2")])
893 (define_insn_and_split "*x_minus_i_eq_0"
894 [(set (match_operand:SI 0 "register_operand" "=r")
895 (minus:SI (match_operand:SI 2 "register_operand" "r")
896 (eq:SI (match_operand:SI 1 "register_operand" "r")
898 (clobber (reg:CC CC_REG))]
902 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
904 (set (match_dup 0) (minus:SI (match_dup 2)
905 (geu:SI (reg:CC CC_REG) (const_int 0))))]
907 [(set_attr "length" "2")])
909 ;; We can also do GEU and LTU directly, but these operate after a compare.
910 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
913 (define_insn "*sltu_insn"
914 [(set (match_operand:SI 0 "register_operand" "=r")
915 (ltu:SI (reg:CC CC_REG) (const_int 0)))]
918 [(set_attr "type" "ialuX")])
920 (define_insn "*neg_sltu_insn"
921 [(set (match_operand:SI 0 "register_operand" "=r")
922 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
925 [(set_attr "type" "ialuX")])
927 ;; ??? Combine should canonicalize these next two to the same pattern.
928 (define_insn "*neg_sltu_minus_x"
929 [(set (match_operand:SI 0 "register_operand" "=r")
930 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
931 (match_operand:SI 1 "arith_operand" "rI")))]
934 [(set_attr "type" "ialuX")])
936 (define_insn "*neg_sltu_plus_x"
937 [(set (match_operand:SI 0 "register_operand" "=r")
938 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
939 (match_operand:SI 1 "arith_operand" "rI"))))]
942 [(set_attr "type" "ialuX")])
944 (define_insn "*sgeu_insn"
945 [(set (match_operand:SI 0 "register_operand" "=r")
946 (geu:SI (reg:CC CC_REG) (const_int 0)))]
949 [(set_attr "type" "ialuX")])
951 (define_insn "*neg_sgeu_insn"
952 [(set (match_operand:SI 0 "register_operand" "=r")
953 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
956 [(set_attr "type" "ialuX")])
958 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
959 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
962 (define_insn "*sltu_plus_x"
963 [(set (match_operand:SI 0 "register_operand" "=r")
964 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
965 (match_operand:SI 1 "arith_operand" "rI")))]
968 [(set_attr "type" "ialuX")])
970 (define_insn "*sltu_plus_x_plus_y"
971 [(set (match_operand:SI 0 "register_operand" "=r")
972 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
973 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
974 (match_operand:SI 2 "arith_operand" "rI"))))]
977 [(set_attr "type" "ialuX")])
979 (define_insn "*x_minus_sltu"
980 [(set (match_operand:SI 0 "register_operand" "=r")
981 (minus:SI (match_operand:SI 1 "register_operand" "r")
982 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
985 [(set_attr "type" "ialuX")])
987 ;; ??? Combine should canonicalize these next two to the same pattern.
988 (define_insn "*x_minus_y_minus_sltu"
989 [(set (match_operand:SI 0 "register_operand" "=r")
990 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
991 (match_operand:SI 2 "arith_operand" "rI"))
992 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
995 [(set_attr "type" "ialuX")])
997 (define_insn "*x_minus_sltu_plus_y"
998 [(set (match_operand:SI 0 "register_operand" "=r")
999 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1000 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1001 (match_operand:SI 2 "arith_operand" "rI"))))]
1004 [(set_attr "type" "ialuX")])
1006 (define_insn "*sgeu_plus_x"
1007 [(set (match_operand:SI 0 "register_operand" "=r")
1008 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1009 (match_operand:SI 1 "register_operand" "r")))]
1012 [(set_attr "type" "ialuX")])
1014 (define_insn "*x_minus_sgeu"
1015 [(set (match_operand:SI 0 "register_operand" "=r")
1016 (minus:SI (match_operand:SI 1 "register_operand" "r")
1017 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1020 [(set_attr "type" "ialuX")])
1023 [(set (match_operand:SI 0 "register_operand" "")
1024 (match_operator:SI 2 "noov_compare_operator"
1025 [(match_operand 1 "icc_or_fcc_register_operand" "")
1028 && REGNO (operands[1]) == SPARC_ICC_REG
1029 && (GET_MODE (operands[1]) == CCXmode
1030 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1031 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1032 [(set (match_dup 0) (const_int 0))
1034 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1040 ;; These control RTL generation for conditional jump insns
1042 (define_expand "cbranchcc4"
1044 (if_then_else (match_operator 0 "comparison_operator"
1045 [(match_operand 1 "compare_operand" "")
1046 (match_operand 2 "const_zero_operand" "")])
1047 (label_ref (match_operand 3 "" ""))
1052 (define_expand "cbranchsi4"
1053 [(use (match_operator 0 "comparison_operator"
1054 [(match_operand:SI 1 "compare_operand" "")
1055 (match_operand:SI 2 "arith_operand" "")]))
1056 (use (match_operand 3 ""))]
1059 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1060 operands[1] = force_reg (SImode, operands[1]);
1061 emit_conditional_branch_insn (operands);
1065 (define_expand "cbranchdi4"
1066 [(use (match_operator 0 "comparison_operator"
1067 [(match_operand:DI 1 "compare_operand" "")
1068 (match_operand:DI 2 "arith_operand" "")]))
1069 (use (match_operand 3 ""))]
1072 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1073 operands[1] = force_reg (DImode, operands[1]);
1074 emit_conditional_branch_insn (operands);
1078 (define_expand "cbranch<F:mode>4"
1079 [(use (match_operator 0 "comparison_operator"
1080 [(match_operand:F 1 "register_operand" "")
1081 (match_operand:F 2 "register_operand" "")]))
1082 (use (match_operand 3 ""))]
1084 { emit_conditional_branch_insn (operands); DONE; })
1087 ;; Now match both normal and inverted jump.
1089 ;; XXX fpcmp nop braindamage
1090 (define_insn "*normal_branch"
1092 (if_then_else (match_operator 0 "noov_compare_operator"
1093 [(reg CC_REG) (const_int 0)])
1094 (label_ref (match_operand 1 "" ""))
1098 return output_cbranch (operands[0], operands[1], 1, 0,
1099 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1102 [(set_attr "type" "branch")
1103 (set_attr "branch_type" "icc")])
1105 ;; XXX fpcmp nop braindamage
1106 (define_insn "*inverted_branch"
1108 (if_then_else (match_operator 0 "noov_compare_operator"
1109 [(reg CC_REG) (const_int 0)])
1111 (label_ref (match_operand 1 "" ""))))]
1114 return output_cbranch (operands[0], operands[1], 1, 1,
1115 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1118 [(set_attr "type" "branch")
1119 (set_attr "branch_type" "icc")])
1121 ;; XXX fpcmp nop braindamage
1122 (define_insn "*normal_fp_branch"
1124 (if_then_else (match_operator 1 "comparison_operator"
1125 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1127 (label_ref (match_operand 2 "" ""))
1131 return output_cbranch (operands[1], operands[2], 2, 0,
1132 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1135 [(set_attr "type" "branch")
1136 (set_attr "branch_type" "fcc")])
1138 ;; XXX fpcmp nop braindamage
1139 (define_insn "*inverted_fp_branch"
1141 (if_then_else (match_operator 1 "comparison_operator"
1142 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1145 (label_ref (match_operand 2 "" ""))))]
1148 return output_cbranch (operands[1], operands[2], 2, 1,
1149 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1152 [(set_attr "type" "branch")
1153 (set_attr "branch_type" "fcc")])
1155 ;; XXX fpcmp nop braindamage
1156 (define_insn "*normal_fpe_branch"
1158 (if_then_else (match_operator 1 "comparison_operator"
1159 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1161 (label_ref (match_operand 2 "" ""))
1165 return output_cbranch (operands[1], operands[2], 2, 0,
1166 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1169 [(set_attr "type" "branch")
1170 (set_attr "branch_type" "fcc")])
1172 ;; XXX fpcmp nop braindamage
1173 (define_insn "*inverted_fpe_branch"
1175 (if_then_else (match_operator 1 "comparison_operator"
1176 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1179 (label_ref (match_operand 2 "" ""))))]
1182 return output_cbranch (operands[1], operands[2], 2, 1,
1183 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1186 [(set_attr "type" "branch")
1187 (set_attr "branch_type" "fcc")])
1189 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1190 ;; in the architecture.
1192 ;; There are no 32 bit brreg insns.
1195 (define_insn "*normal_int_branch_sp64"
1197 (if_then_else (match_operator 0 "v9_register_compare_operator"
1198 [(match_operand:DI 1 "register_operand" "r")
1200 (label_ref (match_operand 2 "" ""))
1204 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1205 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1208 [(set_attr "type" "branch")
1209 (set_attr "branch_type" "reg")])
1212 (define_insn "*inverted_int_branch_sp64"
1214 (if_then_else (match_operator 0 "v9_register_compare_operator"
1215 [(match_operand:DI 1 "register_operand" "r")
1218 (label_ref (match_operand 2 "" ""))))]
1221 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1222 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1225 [(set_attr "type" "branch")
1226 (set_attr "branch_type" "reg")])
1229 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1230 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1231 ;; that adds the PC value at the call point to register #(operand 3).
1233 (define_insn "load_pcrel_sym<P:mode>"
1234 [(set (match_operand:P 0 "register_operand" "=r")
1235 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1236 (match_operand:P 2 "call_address_operand" "")
1237 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1238 (clobber (reg:P O7_REG))]
1239 "REGNO (operands[0]) == INTVAL (operands[3])"
1241 if (flag_delayed_branch)
1242 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1244 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1246 [(set (attr "type") (const_string "multi"))
1247 (set (attr "length")
1248 (if_then_else (eq_attr "delayed_branch" "true")
1253 ;; Integer move instructions
1255 (define_expand "movqi"
1256 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1257 (match_operand:QI 1 "general_operand" ""))]
1260 if (sparc_expand_move (QImode, operands))
1264 (define_insn "*movqi_insn"
1265 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1266 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1267 "(register_operand (operands[0], QImode)
1268 || register_or_zero_operand (operands[1], QImode))"
1273 [(set_attr "type" "*,load,store")
1274 (set_attr "us3load_type" "*,3cycle,*")])
1276 (define_expand "movhi"
1277 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1278 (match_operand:HI 1 "general_operand" ""))]
1281 if (sparc_expand_move (HImode, operands))
1285 (define_insn "*movhi_insn"
1286 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1287 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1288 "(register_operand (operands[0], HImode)
1289 || register_or_zero_operand (operands[1], HImode))"
1292 sethi\t%%hi(%a1), %0
1295 [(set_attr "type" "*,*,load,store")
1296 (set_attr "us3load_type" "*,*,3cycle,*")])
1298 ;; We always work with constants here.
1299 (define_insn "*movhi_lo_sum"
1300 [(set (match_operand:HI 0 "register_operand" "=r")
1301 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1302 (match_operand:HI 2 "small_int_operand" "I")))]
1306 (define_expand "movsi"
1307 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1308 (match_operand:SI 1 "general_operand" ""))]
1311 if (sparc_expand_move (SImode, operands))
1315 (define_insn "*movsi_insn"
1316 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d,d")
1317 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J,P"))]
1318 "(register_operand (operands[0], SImode)
1319 || register_or_zero_or_all_ones_operand (operands[1], SImode))"
1322 sethi\t%%hi(%a1), %0
1330 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")])
1332 (define_insn "*movsi_lo_sum"
1333 [(set (match_operand:SI 0 "register_operand" "=r")
1334 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1335 (match_operand:SI 2 "immediate_operand" "in")))]
1337 "or\t%1, %%lo(%a2), %0")
1339 (define_insn "*movsi_high"
1340 [(set (match_operand:SI 0 "register_operand" "=r")
1341 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1343 "sethi\t%%hi(%a1), %0")
1345 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1346 ;; so that CSE won't optimize the address computation away.
1347 (define_insn "movsi_lo_sum_pic"
1348 [(set (match_operand:SI 0 "register_operand" "=r")
1349 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1350 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1353 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1354 return "xor\t%1, %%gdop_lox10(%a2), %0";
1356 return "or\t%1, %%lo(%a2), %0";
1360 (define_insn "movsi_high_pic"
1361 [(set (match_operand:SI 0 "register_operand" "=r")
1362 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1363 "flag_pic && check_pic (1)"
1365 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1366 return "sethi\t%%gdop_hix22(%a1), %0";
1368 return "sethi\t%%hi(%a1), %0";
1372 (define_insn "movsi_pic_gotdata_op"
1373 [(set (match_operand:SI 0 "register_operand" "=r")
1374 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1375 (match_operand:SI 2 "register_operand" "r")
1376 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1377 "flag_pic && check_pic (1)"
1379 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1380 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1382 return "ld\t[%1 + %2], %0";
1385 [(set_attr "type" "load")])
1387 (define_expand "movsi_pic_label_ref"
1388 [(set (match_dup 3) (high:SI
1389 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1390 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1391 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1392 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1393 (set (match_operand:SI 0 "register_operand" "=r")
1394 (minus:SI (match_dup 5) (match_dup 4)))]
1397 crtl->uses_pic_offset_table = 1;
1398 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1399 if (!can_create_pseudo_p ())
1401 operands[3] = operands[0];
1402 operands[4] = operands[0];
1406 operands[3] = gen_reg_rtx (SImode);
1407 operands[4] = gen_reg_rtx (SImode);
1409 operands[5] = pic_offset_table_rtx;
1412 (define_insn "*movsi_high_pic_label_ref"
1413 [(set (match_operand:SI 0 "register_operand" "=r")
1415 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1416 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1418 "sethi\t%%hi(%a2-(%a1-.)), %0")
1420 (define_insn "*movsi_lo_sum_pic_label_ref"
1421 [(set (match_operand:SI 0 "register_operand" "=r")
1422 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1423 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1424 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1426 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1428 ;; Set up the PIC register for VxWorks.
1430 (define_expand "vxworks_load_got"
1432 (high:SI (match_dup 1)))
1434 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1436 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1437 "TARGET_VXWORKS_RTP"
1439 operands[0] = pic_offset_table_rtx;
1440 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1441 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1444 (define_expand "movdi"
1445 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1446 (match_operand:DI 1 "general_operand" ""))]
1449 if (sparc_expand_move (DImode, operands))
1453 ;; Be careful, fmovd does not exist when !v9.
1454 ;; We match MEM moves directly when we have correct even
1455 ;; numbered registers, but fall into splits otherwise.
1456 ;; The constraint ordering here is really important to
1457 ;; avoid insane problems in reload, especially for patterns
1460 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1461 ;; (const_int -5016)))
1465 (define_insn "*movdi_insn_sp32"
1466 [(set (match_operand:DI 0 "nonimmediate_operand"
1467 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1468 (match_operand:DI 1 "input_operand"
1469 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1471 && (register_operand (operands[0], DImode)
1472 || register_or_zero_operand (operands[1], DImode))"
1486 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1487 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1489 (define_insn "*movdi_insn_sp32_v9"
1490 [(set (match_operand:DI 0 "nonimmediate_operand"
1491 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1492 (match_operand:DI 1 "input_operand"
1493 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1496 && (register_operand (operands[0], DImode)
1497 || register_or_zero_operand (operands[1], DImode))"
1514 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1515 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1516 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1518 (define_insn "*movdi_insn_sp64"
1519 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b,b")
1520 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J,P"))]
1522 && (register_operand (operands[0], DImode)
1523 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1526 sethi\t%%hi(%a1), %0
1534 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")
1535 (set_attr "fptype" "*,*,*,*,double,*,*,double,double")])
1537 (define_expand "movdi_pic_label_ref"
1538 [(set (match_dup 3) (high:DI
1539 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1540 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1541 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1542 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1543 (set (match_operand:DI 0 "register_operand" "=r")
1544 (minus:DI (match_dup 5) (match_dup 4)))]
1545 "TARGET_ARCH64 && flag_pic"
1547 crtl->uses_pic_offset_table = 1;
1548 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1549 if (!can_create_pseudo_p ())
1551 operands[3] = operands[0];
1552 operands[4] = operands[0];
1556 operands[3] = gen_reg_rtx (DImode);
1557 operands[4] = gen_reg_rtx (DImode);
1559 operands[5] = pic_offset_table_rtx;
1562 (define_insn "*movdi_high_pic_label_ref"
1563 [(set (match_operand:DI 0 "register_operand" "=r")
1565 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1566 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1567 "TARGET_ARCH64 && flag_pic"
1568 "sethi\t%%hi(%a2-(%a1-.)), %0")
1570 (define_insn "*movdi_lo_sum_pic_label_ref"
1571 [(set (match_operand:DI 0 "register_operand" "=r")
1572 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1573 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1574 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1575 "TARGET_ARCH64 && flag_pic"
1576 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1578 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1579 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1581 (define_insn "movdi_lo_sum_pic"
1582 [(set (match_operand:DI 0 "register_operand" "=r")
1583 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1584 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1585 "TARGET_ARCH64 && flag_pic"
1587 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1588 return "xor\t%1, %%gdop_lox10(%a2), %0";
1590 return "or\t%1, %%lo(%a2), %0";
1594 (define_insn "movdi_high_pic"
1595 [(set (match_operand:DI 0 "register_operand" "=r")
1596 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1597 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1599 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1600 return "sethi\t%%gdop_hix22(%a1), %0";
1602 return "sethi\t%%hi(%a1), %0";
1606 (define_insn "movdi_pic_gotdata_op"
1607 [(set (match_operand:DI 0 "register_operand" "=r")
1608 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1609 (match_operand:DI 2 "register_operand" "r")
1610 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1611 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1613 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1614 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1616 return "ldx\t[%1 + %2], %0";
1619 [(set_attr "type" "load")])
1621 (define_insn "*sethi_di_medlow_embmedany_pic"
1622 [(set (match_operand:DI 0 "register_operand" "=r")
1623 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1624 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1625 "sethi\t%%hi(%a1), %0")
1627 (define_insn "*sethi_di_medlow"
1628 [(set (match_operand:DI 0 "register_operand" "=r")
1629 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1630 "TARGET_CM_MEDLOW && check_pic (1)"
1631 "sethi\t%%hi(%a1), %0")
1633 (define_insn "*losum_di_medlow"
1634 [(set (match_operand:DI 0 "register_operand" "=r")
1635 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1636 (match_operand:DI 2 "symbolic_operand" "")))]
1638 "or\t%1, %%lo(%a2), %0")
1640 (define_insn "seth44"
1641 [(set (match_operand:DI 0 "register_operand" "=r")
1642 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1644 "sethi\t%%h44(%a1), %0")
1646 (define_insn "setm44"
1647 [(set (match_operand:DI 0 "register_operand" "=r")
1648 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1649 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1651 "or\t%1, %%m44(%a2), %0")
1653 (define_insn "setl44"
1654 [(set (match_operand:DI 0 "register_operand" "=r")
1655 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1656 (match_operand:DI 2 "symbolic_operand" "")))]
1658 "or\t%1, %%l44(%a2), %0")
1660 (define_insn "sethh"
1661 [(set (match_operand:DI 0 "register_operand" "=r")
1662 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1664 "sethi\t%%hh(%a1), %0")
1666 (define_insn "setlm"
1667 [(set (match_operand:DI 0 "register_operand" "=r")
1668 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1670 "sethi\t%%lm(%a1), %0")
1672 (define_insn "sethm"
1673 [(set (match_operand:DI 0 "register_operand" "=r")
1674 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1675 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1677 "or\t%1, %%hm(%a2), %0")
1679 (define_insn "setlo"
1680 [(set (match_operand:DI 0 "register_operand" "=r")
1681 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1682 (match_operand:DI 2 "symbolic_operand" "")))]
1684 "or\t%1, %%lo(%a2), %0")
1686 (define_insn "embmedany_sethi"
1687 [(set (match_operand:DI 0 "register_operand" "=r")
1688 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1689 "TARGET_CM_EMBMEDANY && check_pic (1)"
1690 "sethi\t%%hi(%a1), %0")
1692 (define_insn "embmedany_losum"
1693 [(set (match_operand:DI 0 "register_operand" "=r")
1694 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1695 (match_operand:DI 2 "data_segment_operand" "")))]
1696 "TARGET_CM_EMBMEDANY"
1697 "add\t%1, %%lo(%a2), %0")
1699 (define_insn "embmedany_brsum"
1700 [(set (match_operand:DI 0 "register_operand" "=r")
1701 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1702 "TARGET_CM_EMBMEDANY"
1705 (define_insn "embmedany_textuhi"
1706 [(set (match_operand:DI 0 "register_operand" "=r")
1707 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1708 "TARGET_CM_EMBMEDANY && check_pic (1)"
1709 "sethi\t%%uhi(%a1), %0")
1711 (define_insn "embmedany_texthi"
1712 [(set (match_operand:DI 0 "register_operand" "=r")
1713 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1714 "TARGET_CM_EMBMEDANY && check_pic (1)"
1715 "sethi\t%%hi(%a1), %0")
1717 (define_insn "embmedany_textulo"
1718 [(set (match_operand:DI 0 "register_operand" "=r")
1719 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1720 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1721 "TARGET_CM_EMBMEDANY"
1722 "or\t%1, %%ulo(%a2), %0")
1724 (define_insn "embmedany_textlo"
1725 [(set (match_operand:DI 0 "register_operand" "=r")
1726 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1727 (match_operand:DI 2 "text_segment_operand" "")))]
1728 "TARGET_CM_EMBMEDANY"
1729 "or\t%1, %%lo(%a2), %0")
1731 ;; Now some patterns to help reload out a bit.
1732 (define_expand "reload_indi"
1733 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1734 (match_operand:DI 1 "immediate_operand" "")
1735 (match_operand:TI 2 "register_operand" "=&r")])]
1737 || TARGET_CM_EMBMEDANY)
1740 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1744 (define_expand "reload_outdi"
1745 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1746 (match_operand:DI 1 "immediate_operand" "")
1747 (match_operand:TI 2 "register_operand" "=&r")])]
1749 || TARGET_CM_EMBMEDANY)
1752 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1756 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1758 [(set (match_operand:DI 0 "register_operand" "")
1759 (match_operand:DI 1 "const_int_operand" ""))]
1760 "! TARGET_ARCH64 && reload_completed"
1761 [(clobber (const_int 0))]
1763 #if HOST_BITS_PER_WIDE_INT == 32
1764 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1765 (INTVAL (operands[1]) < 0) ?
1768 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1771 unsigned int low, high;
1773 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1774 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1775 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1777 /* Slick... but this trick loses if this subreg constant part
1778 can be done in one insn. */
1780 && ! SPARC_SETHI32_P (high)
1781 && ! SPARC_SIMM13_P (high))
1782 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1783 gen_highpart (SImode, operands[0])));
1785 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1791 [(set (match_operand:DI 0 "register_operand" "")
1792 (match_operand:DI 1 "const_double_operand" ""))]
1796 && ((GET_CODE (operands[0]) == REG
1797 && REGNO (operands[0]) < 32)
1798 || (GET_CODE (operands[0]) == SUBREG
1799 && GET_CODE (SUBREG_REG (operands[0])) == REG
1800 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1801 [(clobber (const_int 0))]
1803 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1804 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1806 /* Slick... but this trick loses if this subreg constant part
1807 can be done in one insn. */
1808 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1809 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1810 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1812 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1813 gen_highpart (SImode, operands[0])));
1817 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1818 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1824 [(set (match_operand:DI 0 "register_operand" "")
1825 (match_operand:DI 1 "register_operand" ""))]
1829 && ((GET_CODE (operands[0]) == REG
1830 && REGNO (operands[0]) < 32)
1831 || (GET_CODE (operands[0]) == SUBREG
1832 && GET_CODE (SUBREG_REG (operands[0])) == REG
1833 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1834 [(clobber (const_int 0))]
1836 rtx set_dest = operands[0];
1837 rtx set_src = operands[1];
1841 dest1 = gen_highpart (SImode, set_dest);
1842 dest2 = gen_lowpart (SImode, set_dest);
1843 src1 = gen_highpart (SImode, set_src);
1844 src2 = gen_lowpart (SImode, set_src);
1846 /* Now emit using the real source and destination we found, swapping
1847 the order if we detect overlap. */
1848 if (reg_overlap_mentioned_p (dest1, src2))
1850 emit_insn (gen_movsi (dest2, src2));
1851 emit_insn (gen_movsi (dest1, src1));
1855 emit_insn (gen_movsi (dest1, src1));
1856 emit_insn (gen_movsi (dest2, src2));
1861 ;; Now handle the cases of memory moves from/to non-even
1862 ;; DI mode register pairs.
1864 [(set (match_operand:DI 0 "register_operand" "")
1865 (match_operand:DI 1 "memory_operand" ""))]
1868 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1869 [(clobber (const_int 0))]
1871 rtx word0 = adjust_address (operands[1], SImode, 0);
1872 rtx word1 = adjust_address (operands[1], SImode, 4);
1873 rtx high_part = gen_highpart (SImode, operands[0]);
1874 rtx low_part = gen_lowpart (SImode, operands[0]);
1876 if (reg_overlap_mentioned_p (high_part, word1))
1878 emit_insn (gen_movsi (low_part, word1));
1879 emit_insn (gen_movsi (high_part, word0));
1883 emit_insn (gen_movsi (high_part, word0));
1884 emit_insn (gen_movsi (low_part, word1));
1890 [(set (match_operand:DI 0 "memory_operand" "")
1891 (match_operand:DI 1 "register_operand" ""))]
1894 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1895 [(clobber (const_int 0))]
1897 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1898 gen_highpart (SImode, operands[1])));
1899 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1900 gen_lowpart (SImode, operands[1])));
1905 [(set (match_operand:DI 0 "memory_operand" "")
1906 (match_operand:DI 1 "const_zero_operand" ""))]
1910 && ! mem_min_alignment (operands[0], 8)))
1911 && offsettable_memref_p (operands[0])"
1912 [(clobber (const_int 0))]
1914 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1915 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1920 ;; Floating point move instructions
1922 (define_expand "movsf"
1923 [(set (match_operand:SF 0 "nonimmediate_operand" "")
1924 (match_operand:SF 1 "general_operand" ""))]
1927 if (sparc_expand_move (SFmode, operands))
1931 (define_insn "*movsf_insn"
1932 [(set (match_operand:SF 0 "nonimmediate_operand" "=d, d,f, *r,*r,*r,f,*r,m, m")
1933 (match_operand:SF 1 "input_operand" "GY,ZC,f,*rRY, Q, S,m, m,f,*rGY"))]
1935 && (register_operand (operands[0], SFmode)
1936 || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
1938 if (GET_CODE (operands[1]) == CONST_DOUBLE
1939 && (which_alternative == 3
1940 || which_alternative == 4
1941 || which_alternative == 5))
1946 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1947 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1948 operands[1] = GEN_INT (i);
1951 switch (which_alternative)
1954 return "fzeros\t%0";
1958 return "fmovs\t%1, %0";
1960 return "mov\t%1, %0";
1962 return "sethi\t%%hi(%a1), %0";
1967 return "ld\t%1, %0";
1970 return "st\t%r1, %0";
1975 [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1977 ;; Exactly the same as above, except that all `f' cases are deleted.
1978 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1981 (define_insn "*movsf_insn_no_fpu"
1982 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1983 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1985 && (register_operand (operands[0], SFmode)
1986 || register_or_zero_operand (operands[1], SFmode))"
1988 if (GET_CODE (operands[1]) == CONST_DOUBLE
1989 && (which_alternative == 0
1990 || which_alternative == 1
1991 || which_alternative == 2))
1996 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1997 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1998 operands[1] = GEN_INT (i);
2001 switch (which_alternative)
2004 return "mov\t%1, %0";
2006 return "sethi\t%%hi(%a1), %0";
2010 return "ld\t%1, %0";
2012 return "st\t%r1, %0";
2017 [(set_attr "type" "*,*,*,load,store")])
2019 ;; The following 3 patterns build SFmode constants in integer registers.
2021 (define_insn "*movsf_lo_sum"
2022 [(set (match_operand:SF 0 "register_operand" "=r")
2023 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2024 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2030 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2031 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2032 operands[2] = GEN_INT (i);
2033 return "or\t%1, %%lo(%a2), %0";
2036 (define_insn "*movsf_high"
2037 [(set (match_operand:SF 0 "register_operand" "=r")
2038 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2044 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2045 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2046 operands[1] = GEN_INT (i);
2047 return "sethi\t%%hi(%1), %0";
2051 [(set (match_operand:SF 0 "register_operand" "")
2052 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2053 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2054 [(set (match_dup 0) (high:SF (match_dup 1)))
2055 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2057 (define_expand "movdf"
2058 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2059 (match_operand:DF 1 "general_operand" ""))]
2062 if (sparc_expand_move (DFmode, operands))
2066 ;; Be careful, fmovd does not exist when !v9.
2067 (define_insn "*movdf_insn_sp32"
2068 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e, *r, o, e,o")
2069 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2072 && (register_operand (operands[0], DFmode)
2073 || register_or_zero_operand (operands[1], DFmode))"
2085 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2086 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2088 (define_insn "*movdf_insn_sp32_no_fpu"
2089 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2090 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2093 && (register_operand (operands[0], DFmode)
2094 || register_or_zero_operand (operands[1], DFmode))"
2101 [(set_attr "type" "load,store,*,*,*")
2102 (set_attr "length" "*,*,2,2,2")])
2104 ;; We have available v9 double floats but not 64-bit integer registers.
2105 (define_insn "*movdf_insn_sp32_v9"
2106 [(set (match_operand:DF 0 "nonimmediate_operand" "=b, b,e, e, T,W,U,T, f, *r, o")
2107 (match_operand:DF 1 "input_operand" "GY,ZC,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2111 && (register_operand (operands[0], DFmode)
2112 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2125 [(set_attr "type" "fga,fga,fpmove,load,store,store,load,store,*,*,*")
2126 (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")
2127 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*")])
2129 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2130 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2131 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2135 && (register_operand (operands[0], DFmode)
2136 || register_or_zero_operand (operands[1], DFmode))"
2143 [(set_attr "type" "load,store,store,*,*")
2144 (set_attr "length" "*,*,*,2,2")])
2146 ;; We have available both v9 double floats and 64-bit integer registers.
2147 (define_insn "*movdf_insn_sp64"
2148 [(set (match_operand:DF 0 "nonimmediate_operand" "=b, b,e, e,W, *r,*r, m,*r")
2149 (match_operand:DF 1 "input_operand" "GY,ZC,e,W#F,e,*rGY, m,*rGY,DF"))]
2152 && (register_operand (operands[0], DFmode)
2153 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2164 [(set_attr "type" "fga,fga,fpmove,load,store,*,load,store,*")
2165 (set_attr "length" "*,*,*,*,*,*,*,*,2")
2166 (set_attr "fptype" "double,double,double,*,*,*,*,*,*")])
2168 (define_insn "*movdf_insn_sp64_no_fpu"
2169 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2170 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2173 && (register_operand (operands[0], DFmode)
2174 || register_or_zero_operand (operands[1], DFmode))"
2179 [(set_attr "type" "*,load,store")])
2181 ;; This pattern builds DFmode constants in integer registers.
2183 [(set (match_operand:DF 0 "register_operand" "")
2184 (match_operand:DF 1 "const_double_operand" ""))]
2186 && (GET_CODE (operands[0]) == REG
2187 && REGNO (operands[0]) < 32)
2188 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2189 && reload_completed"
2190 [(clobber (const_int 0))]
2192 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2196 #if HOST_BITS_PER_WIDE_INT == 32
2199 enum machine_mode mode = GET_MODE (operands[1]);
2200 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2201 emit_insn (gen_movdi (operands[0], tem));
2206 enum machine_mode mode = GET_MODE (operands[1]);
2207 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2208 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2210 gcc_assert (GET_CODE (hi) == CONST_INT);
2211 gcc_assert (GET_CODE (lo) == CONST_INT);
2213 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2215 /* Slick... but this trick loses if this subreg constant part
2216 can be done in one insn. */
2218 && ! SPARC_SETHI32_P (INTVAL (hi))
2219 && ! SPARC_SIMM13_P (INTVAL (hi)))
2221 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2222 gen_highpart (SImode, operands[0])));
2226 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2232 ;; Ok, now the splits to handle all the multi insn and
2233 ;; mis-aligned memory address cases.
2234 ;; In these splits please take note that we must be
2235 ;; careful when V9 but not ARCH64 because the integer
2236 ;; register DFmode cases must be handled.
2238 [(set (match_operand:DF 0 "register_operand" "")
2239 (match_operand:DF 1 "register_operand" ""))]
2242 && ((GET_CODE (operands[0]) == REG
2243 && REGNO (operands[0]) < 32)
2244 || (GET_CODE (operands[0]) == SUBREG
2245 && GET_CODE (SUBREG_REG (operands[0])) == REG
2246 && REGNO (SUBREG_REG (operands[0])) < 32))))
2247 && reload_completed"
2248 [(clobber (const_int 0))]
2250 rtx set_dest = operands[0];
2251 rtx set_src = operands[1];
2255 dest1 = gen_highpart (SFmode, set_dest);
2256 dest2 = gen_lowpart (SFmode, set_dest);
2257 src1 = gen_highpart (SFmode, set_src);
2258 src2 = gen_lowpart (SFmode, set_src);
2260 /* Now emit using the real source and destination we found, swapping
2261 the order if we detect overlap. */
2262 if (reg_overlap_mentioned_p (dest1, src2))
2264 emit_move_insn_1 (dest2, src2);
2265 emit_move_insn_1 (dest1, src1);
2269 emit_move_insn_1 (dest1, src1);
2270 emit_move_insn_1 (dest2, src2);
2276 [(set (match_operand:DF 0 "register_operand" "")
2277 (match_operand:DF 1 "memory_operand" ""))]
2280 && (((REGNO (operands[0]) % 2) != 0)
2281 || ! mem_min_alignment (operands[1], 8))
2282 && offsettable_memref_p (operands[1])"
2283 [(clobber (const_int 0))]
2287 word0 = adjust_address (operands[1], SFmode, 0);
2288 word1 = adjust_address (operands[1], SFmode, 4);
2290 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2292 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2293 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2297 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2298 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2304 [(set (match_operand:DF 0 "memory_operand" "")
2305 (match_operand:DF 1 "register_operand" ""))]
2308 && (((REGNO (operands[1]) % 2) != 0)
2309 || ! mem_min_alignment (operands[0], 8))
2310 && offsettable_memref_p (operands[0])"
2311 [(clobber (const_int 0))]
2315 word0 = adjust_address (operands[0], SFmode, 0);
2316 word1 = adjust_address (operands[0], SFmode, 4);
2318 emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2319 emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2324 [(set (match_operand:DF 0 "memory_operand" "")
2325 (match_operand:DF 1 "const_zero_operand" ""))]
2329 && ! mem_min_alignment (operands[0], 8)))
2330 && offsettable_memref_p (operands[0])"
2331 [(clobber (const_int 0))]
2335 dest1 = adjust_address (operands[0], SFmode, 0);
2336 dest2 = adjust_address (operands[0], SFmode, 4);
2338 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2339 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2344 [(set (match_operand:DF 0 "register_operand" "")
2345 (match_operand:DF 1 "const_zero_operand" ""))]
2348 && ((GET_CODE (operands[0]) == REG
2349 && REGNO (operands[0]) < 32)
2350 || (GET_CODE (operands[0]) == SUBREG
2351 && GET_CODE (SUBREG_REG (operands[0])) == REG
2352 && REGNO (SUBREG_REG (operands[0])) < 32))"
2353 [(clobber (const_int 0))]
2355 rtx set_dest = operands[0];
2358 dest1 = gen_highpart (SFmode, set_dest);
2359 dest2 = gen_lowpart (SFmode, set_dest);
2360 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2361 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2365 (define_expand "movtf"
2366 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2367 (match_operand:TF 1 "general_operand" ""))]
2370 if (sparc_expand_move (TFmode, operands))
2374 (define_insn "*movtf_insn_sp32"
2375 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2376 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2379 && (register_operand (operands[0], TFmode)
2380 || register_or_zero_operand (operands[1], TFmode))"
2382 [(set_attr "length" "4")])
2384 ;; Exactly the same as above, except that all `e' cases are deleted.
2385 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2388 (define_insn "*movtf_insn_sp32_no_fpu"
2389 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2390 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2393 && (register_operand (operands[0], TFmode)
2394 || register_or_zero_operand (operands[1], TFmode))"
2396 [(set_attr "length" "4")])
2398 (define_insn "*movtf_insn_sp64"
2399 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2400 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2403 && ! TARGET_HARD_QUAD
2404 && (register_operand (operands[0], TFmode)
2405 || register_or_zero_operand (operands[1], TFmode))"
2407 [(set_attr "length" "2")])
2409 (define_insn "*movtf_insn_sp64_hq"
2410 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2411 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2415 && (register_operand (operands[0], TFmode)
2416 || register_or_zero_operand (operands[1], TFmode))"
2424 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2425 (set_attr "length" "2,*,*,*,2,2")])
2427 (define_insn "*movtf_insn_sp64_no_fpu"
2428 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2429 (match_operand:TF 1 "input_operand" "orG,rG"))]
2432 && (register_operand (operands[0], TFmode)
2433 || register_or_zero_operand (operands[1], TFmode))"
2435 [(set_attr "length" "2")])
2437 ;; Now all the splits to handle multi-insn TF mode moves.
2439 [(set (match_operand:TF 0 "register_operand" "")
2440 (match_operand:TF 1 "register_operand" ""))]
2444 && ! TARGET_HARD_QUAD)
2445 || ! fp_register_operand (operands[0], TFmode))"
2446 [(clobber (const_int 0))]
2448 rtx set_dest = operands[0];
2449 rtx set_src = operands[1];
2453 dest1 = gen_df_reg (set_dest, 0);
2454 dest2 = gen_df_reg (set_dest, 1);
2455 src1 = gen_df_reg (set_src, 0);
2456 src2 = gen_df_reg (set_src, 1);
2458 /* Now emit using the real source and destination we found, swapping
2459 the order if we detect overlap. */
2460 if (reg_overlap_mentioned_p (dest1, src2))
2462 emit_insn (gen_movdf (dest2, src2));
2463 emit_insn (gen_movdf (dest1, src1));
2467 emit_insn (gen_movdf (dest1, src1));
2468 emit_insn (gen_movdf (dest2, src2));
2474 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2475 (match_operand:TF 1 "const_zero_operand" ""))]
2477 [(clobber (const_int 0))]
2479 rtx set_dest = operands[0];
2482 switch (GET_CODE (set_dest))
2485 dest1 = gen_df_reg (set_dest, 0);
2486 dest2 = gen_df_reg (set_dest, 1);
2489 dest1 = adjust_address (set_dest, DFmode, 0);
2490 dest2 = adjust_address (set_dest, DFmode, 8);
2496 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2497 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2502 [(set (match_operand:TF 0 "register_operand" "")
2503 (match_operand:TF 1 "memory_operand" ""))]
2505 && offsettable_memref_p (operands[1])
2507 || ! TARGET_HARD_QUAD
2508 || ! fp_register_operand (operands[0], TFmode)))"
2509 [(clobber (const_int 0))]
2511 rtx word0 = adjust_address (operands[1], DFmode, 0);
2512 rtx word1 = adjust_address (operands[1], DFmode, 8);
2513 rtx set_dest, dest1, dest2;
2515 set_dest = operands[0];
2517 dest1 = gen_df_reg (set_dest, 0);
2518 dest2 = gen_df_reg (set_dest, 1);
2520 /* Now output, ordering such that we don't clobber any registers
2521 mentioned in the address. */
2522 if (reg_overlap_mentioned_p (dest1, word1))
2525 emit_insn (gen_movdf (dest2, word1));
2526 emit_insn (gen_movdf (dest1, word0));
2530 emit_insn (gen_movdf (dest1, word0));
2531 emit_insn (gen_movdf (dest2, word1));
2537 [(set (match_operand:TF 0 "memory_operand" "")
2538 (match_operand:TF 1 "register_operand" ""))]
2540 && offsettable_memref_p (operands[0])
2542 || ! TARGET_HARD_QUAD
2543 || ! fp_register_operand (operands[1], TFmode)))"
2544 [(clobber (const_int 0))]
2546 rtx set_src = operands[1];
2548 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2549 gen_df_reg (set_src, 0)));
2550 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2551 gen_df_reg (set_src, 1)));
2556 ;; SPARC-V9 conditional move instructions
2558 ;; We can handle larger constants here for some flavors, but for now we keep
2559 ;; it simple and only allow those constants supported by all flavors.
2560 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2561 ;; 3 contains the constant if one is present, but we handle either for
2562 ;; generality (sparc.c puts a constant in operand 2).
2564 (define_expand "mov<I:mode>cc"
2565 [(set (match_operand:I 0 "register_operand" "")
2566 (if_then_else:I (match_operand 1 "comparison_operator" "")
2567 (match_operand:I 2 "arith10_operand" "")
2568 (match_operand:I 3 "arith10_operand" "")))]
2569 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2573 if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64)
2576 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2578 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2579 GET_CODE (operands[1]));
2581 if (XEXP (operands[1], 1) == const0_rtx
2582 && GET_CODE (XEXP (operands[1], 0)) == REG
2583 && GET_MODE (XEXP (operands[1], 0)) == DImode
2584 && v9_regcmp_p (GET_CODE (operands[1])))
2585 cc_reg = XEXP (operands[1], 0);
2587 cc_reg = gen_compare_reg (operands[1]);
2590 = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg,
2594 (define_expand "mov<F:mode>cc"
2595 [(set (match_operand:F 0 "register_operand" "")
2596 (if_then_else:F (match_operand 1 "comparison_operator" "")
2597 (match_operand:F 2 "register_operand" "")
2598 (match_operand:F 3 "register_operand" "")))]
2599 "TARGET_V9 && TARGET_FPU"
2603 if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64)
2606 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2608 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2609 GET_CODE (operands[1]));
2611 if (XEXP (operands[1], 1) == const0_rtx
2612 && GET_CODE (XEXP (operands[1], 0)) == REG
2613 && GET_MODE (XEXP (operands[1], 0)) == DImode
2614 && v9_regcmp_p (GET_CODE (operands[1])))
2615 cc_reg = XEXP (operands[1], 0);
2617 cc_reg = gen_compare_reg (operands[1]);
2620 = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg,
2624 ;; Conditional move define_insns
2626 (define_insn "*mov<I:mode>_cc_v9"
2627 [(set (match_operand:I 0 "register_operand" "=r,r")
2628 (if_then_else:I (match_operator 1 "comparison_operator"
2629 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2631 (match_operand:I 3 "arith11_operand" "rL,0")
2632 (match_operand:I 4 "arith11_operand" "0,rL")))]
2633 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2636 mov%c1\t%x2, %4, %0"
2637 [(set_attr "type" "cmove")])
2639 (define_insn "*mov<I:mode>_cc_reg_sp64"
2640 [(set (match_operand:I 0 "register_operand" "=r,r")
2641 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2642 [(match_operand:DI 2 "register_operand" "r,r")
2644 (match_operand:I 3 "arith10_operand" "rM,0")
2645 (match_operand:I 4 "arith10_operand" "0,rM")))]
2648 movr%D1\t%2, %r3, %0
2649 movr%d1\t%2, %r4, %0"
2650 [(set_attr "type" "cmove")])
2652 (define_insn "*movsf_cc_v9"
2653 [(set (match_operand:SF 0 "register_operand" "=f,f")
2654 (if_then_else:SF (match_operator 1 "comparison_operator"
2655 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2657 (match_operand:SF 3 "register_operand" "f,0")
2658 (match_operand:SF 4 "register_operand" "0,f")))]
2659 "TARGET_V9 && TARGET_FPU"
2661 fmovs%C1\t%x2, %3, %0
2662 fmovs%c1\t%x2, %4, %0"
2663 [(set_attr "type" "fpcmove")])
2665 (define_insn "*movsf_cc_reg_sp64"
2666 [(set (match_operand:SF 0 "register_operand" "=f,f")
2667 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2668 [(match_operand:DI 2 "register_operand" "r,r")
2670 (match_operand:SF 3 "register_operand" "f,0")
2671 (match_operand:SF 4 "register_operand" "0,f")))]
2672 "TARGET_ARCH64 && TARGET_FPU"
2674 fmovrs%D1\t%2, %3, %0
2675 fmovrs%d1\t%2, %4, %0"
2676 [(set_attr "type" "fpcrmove")])
2678 ;; Named because invoked by movtf_cc_v9
2679 (define_insn "movdf_cc_v9"
2680 [(set (match_operand:DF 0 "register_operand" "=e,e")
2681 (if_then_else:DF (match_operator 1 "comparison_operator"
2682 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2684 (match_operand:DF 3 "register_operand" "e,0")
2685 (match_operand:DF 4 "register_operand" "0,e")))]
2686 "TARGET_V9 && TARGET_FPU"
2688 fmovd%C1\t%x2, %3, %0
2689 fmovd%c1\t%x2, %4, %0"
2690 [(set_attr "type" "fpcmove")
2691 (set_attr "fptype" "double")])
2693 ;; Named because invoked by movtf_cc_reg_sp64
2694 (define_insn "movdf_cc_reg_sp64"
2695 [(set (match_operand:DF 0 "register_operand" "=e,e")
2696 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2697 [(match_operand:DI 2 "register_operand" "r,r")
2699 (match_operand:DF 3 "register_operand" "e,0")
2700 (match_operand:DF 4 "register_operand" "0,e")))]
2701 "TARGET_ARCH64 && TARGET_FPU"
2703 fmovrd%D1\t%2, %3, %0
2704 fmovrd%d1\t%2, %4, %0"
2705 [(set_attr "type" "fpcrmove")
2706 (set_attr "fptype" "double")])
2708 (define_insn "*movtf_cc_hq_v9"
2709 [(set (match_operand:TF 0 "register_operand" "=e,e")
2710 (if_then_else:TF (match_operator 1 "comparison_operator"
2711 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2713 (match_operand:TF 3 "register_operand" "e,0")
2714 (match_operand:TF 4 "register_operand" "0,e")))]
2715 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2717 fmovq%C1\t%x2, %3, %0
2718 fmovq%c1\t%x2, %4, %0"
2719 [(set_attr "type" "fpcmove")])
2721 (define_insn "*movtf_cc_reg_hq_sp64"
2722 [(set (match_operand:TF 0 "register_operand" "=e,e")
2723 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2724 [(match_operand:DI 2 "register_operand" "r,r")
2726 (match_operand:TF 3 "register_operand" "e,0")
2727 (match_operand:TF 4 "register_operand" "0,e")))]
2728 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2730 fmovrq%D1\t%2, %3, %0
2731 fmovrq%d1\t%2, %4, %0"
2732 [(set_attr "type" "fpcrmove")])
2734 (define_insn_and_split "*movtf_cc_v9"
2735 [(set (match_operand:TF 0 "register_operand" "=e,e")
2736 (if_then_else:TF (match_operator 1 "comparison_operator"
2737 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2739 (match_operand:TF 3 "register_operand" "e,0")
2740 (match_operand:TF 4 "register_operand" "0,e")))]
2741 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2743 "&& reload_completed"
2744 [(clobber (const_int 0))]
2746 rtx set_dest = operands[0];
2747 rtx set_srca = operands[3];
2748 rtx set_srcb = operands[4];
2749 int third = rtx_equal_p (set_dest, set_srca);
2751 rtx srca1, srca2, srcb1, srcb2;
2753 dest1 = gen_df_reg (set_dest, 0);
2754 dest2 = gen_df_reg (set_dest, 1);
2755 srca1 = gen_df_reg (set_srca, 0);
2756 srca2 = gen_df_reg (set_srca, 1);
2757 srcb1 = gen_df_reg (set_srcb, 0);
2758 srcb2 = gen_df_reg (set_srcb, 1);
2760 /* Now emit using the real source and destination we found, swapping
2761 the order if we detect overlap. */
2762 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2763 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2765 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2766 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2770 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2771 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2775 [(set_attr "length" "2")])
2777 (define_insn_and_split "*movtf_cc_reg_sp64"
2778 [(set (match_operand:TF 0 "register_operand" "=e,e")
2779 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2780 [(match_operand:DI 2 "register_operand" "r,r")
2782 (match_operand:TF 3 "register_operand" "e,0")
2783 (match_operand:TF 4 "register_operand" "0,e")))]
2784 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2786 "&& reload_completed"
2787 [(clobber (const_int 0))]
2789 rtx set_dest = operands[0];
2790 rtx set_srca = operands[3];
2791 rtx set_srcb = operands[4];
2792 int third = rtx_equal_p (set_dest, set_srca);
2794 rtx srca1, srca2, srcb1, srcb2;
2796 dest1 = gen_df_reg (set_dest, 0);
2797 dest2 = gen_df_reg (set_dest, 1);
2798 srca1 = gen_df_reg (set_srca, 0);
2799 srca2 = gen_df_reg (set_srca, 1);
2800 srcb1 = gen_df_reg (set_srcb, 0);
2801 srcb2 = gen_df_reg (set_srcb, 1);
2803 /* Now emit using the real source and destination we found, swapping
2804 the order if we detect overlap. */
2805 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2806 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2808 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2809 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2813 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2814 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2818 [(set_attr "length" "2")])
2821 ;; Zero-extension instructions
2823 ;; These patterns originally accepted general_operands, however, slightly
2824 ;; better code is generated by only accepting register_operands, and then
2825 ;; letting combine generate the ldu[hb] insns.
2827 (define_expand "zero_extendhisi2"
2828 [(set (match_operand:SI 0 "register_operand" "")
2829 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2832 rtx temp = gen_reg_rtx (SImode);
2833 rtx shift_16 = GEN_INT (16);
2834 int op1_subbyte = 0;
2836 if (GET_CODE (operand1) == SUBREG)
2838 op1_subbyte = SUBREG_BYTE (operand1);
2839 op1_subbyte /= GET_MODE_SIZE (SImode);
2840 op1_subbyte *= GET_MODE_SIZE (SImode);
2841 operand1 = XEXP (operand1, 0);
2844 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2846 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2850 (define_insn "*zero_extendhisi2_insn"
2851 [(set (match_operand:SI 0 "register_operand" "=r")
2852 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2855 [(set_attr "type" "load")
2856 (set_attr "us3load_type" "3cycle")])
2858 (define_expand "zero_extendqihi2"
2859 [(set (match_operand:HI 0 "register_operand" "")
2860 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2864 (define_insn "*zero_extendqihi2_insn"
2865 [(set (match_operand:HI 0 "register_operand" "=r,r")
2866 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2867 "GET_CODE (operands[1]) != CONST_INT"
2871 [(set_attr "type" "*,load")
2872 (set_attr "us3load_type" "*,3cycle")])
2874 (define_expand "zero_extendqisi2"
2875 [(set (match_operand:SI 0 "register_operand" "")
2876 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2880 (define_insn "*zero_extendqisi2_insn"
2881 [(set (match_operand:SI 0 "register_operand" "=r,r")
2882 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2883 "GET_CODE (operands[1]) != CONST_INT"
2887 [(set_attr "type" "*,load")
2888 (set_attr "us3load_type" "*,3cycle")])
2890 (define_expand "zero_extendqidi2"
2891 [(set (match_operand:DI 0 "register_operand" "")
2892 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2896 (define_insn "*zero_extendqidi2_insn"
2897 [(set (match_operand:DI 0 "register_operand" "=r,r")
2898 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2899 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2903 [(set_attr "type" "*,load")
2904 (set_attr "us3load_type" "*,3cycle")])
2906 (define_expand "zero_extendhidi2"
2907 [(set (match_operand:DI 0 "register_operand" "")
2908 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2911 rtx temp = gen_reg_rtx (DImode);
2912 rtx shift_48 = GEN_INT (48);
2913 int op1_subbyte = 0;
2915 if (GET_CODE (operand1) == SUBREG)
2917 op1_subbyte = SUBREG_BYTE (operand1);
2918 op1_subbyte /= GET_MODE_SIZE (DImode);
2919 op1_subbyte *= GET_MODE_SIZE (DImode);
2920 operand1 = XEXP (operand1, 0);
2923 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2925 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2929 (define_insn "*zero_extendhidi2_insn"
2930 [(set (match_operand:DI 0 "register_operand" "=r")
2931 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2934 [(set_attr "type" "load")
2935 (set_attr "us3load_type" "3cycle")])
2937 ;; ??? Write truncdisi pattern using sra?
2939 (define_expand "zero_extendsidi2"
2940 [(set (match_operand:DI 0 "register_operand" "")
2941 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2945 (define_insn "*zero_extendsidi2_insn_sp64"
2946 [(set (match_operand:DI 0 "register_operand" "=r,r")
2947 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2948 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2952 [(set_attr "type" "shift,load")])
2954 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2955 [(set (match_operand:DI 0 "register_operand" "=r")
2956 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2959 "&& reload_completed"
2960 [(set (match_dup 2) (match_dup 3))
2961 (set (match_dup 4) (match_dup 5))]
2965 dest1 = gen_highpart (SImode, operands[0]);
2966 dest2 = gen_lowpart (SImode, operands[0]);
2968 /* Swap the order in case of overlap. */
2969 if (REGNO (dest1) == REGNO (operands[1]))
2971 operands[2] = dest2;
2972 operands[3] = operands[1];
2973 operands[4] = dest1;
2974 operands[5] = const0_rtx;
2978 operands[2] = dest1;
2979 operands[3] = const0_rtx;
2980 operands[4] = dest2;
2981 operands[5] = operands[1];
2984 [(set_attr "length" "2")])
2986 ;; Simplify comparisons of extended values.
2988 (define_insn "*cmp_zero_extendqisi2"
2989 [(set (reg:CC CC_REG)
2990 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2993 "andcc\t%0, 0xff, %%g0"
2994 [(set_attr "type" "compare")])
2996 (define_insn "*cmp_zero_qi"
2997 [(set (reg:CC CC_REG)
2998 (compare:CC (match_operand:QI 0 "register_operand" "r")
3001 "andcc\t%0, 0xff, %%g0"
3002 [(set_attr "type" "compare")])
3004 (define_insn "*cmp_zero_extendqisi2_set"
3005 [(set (reg:CC CC_REG)
3006 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3008 (set (match_operand:SI 0 "register_operand" "=r")
3009 (zero_extend:SI (match_dup 1)))]
3011 "andcc\t%1, 0xff, %0"
3012 [(set_attr "type" "compare")])
3014 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3015 [(set (reg:CC CC_REG)
3016 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3019 (set (match_operand:SI 0 "register_operand" "=r")
3020 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3022 "andcc\t%1, 0xff, %0"
3023 [(set_attr "type" "compare")])
3025 (define_insn "*cmp_zero_extendqidi2"
3026 [(set (reg:CCX CC_REG)
3027 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3030 "andcc\t%0, 0xff, %%g0"
3031 [(set_attr "type" "compare")])
3033 (define_insn "*cmp_zero_qi_sp64"
3034 [(set (reg:CCX CC_REG)
3035 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3038 "andcc\t%0, 0xff, %%g0"
3039 [(set_attr "type" "compare")])
3041 (define_insn "*cmp_zero_extendqidi2_set"
3042 [(set (reg:CCX CC_REG)
3043 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3045 (set (match_operand:DI 0 "register_operand" "=r")
3046 (zero_extend:DI (match_dup 1)))]
3048 "andcc\t%1, 0xff, %0"
3049 [(set_attr "type" "compare")])
3051 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3052 [(set (reg:CCX CC_REG)
3053 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3056 (set (match_operand:DI 0 "register_operand" "=r")
3057 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3059 "andcc\t%1, 0xff, %0"
3060 [(set_attr "type" "compare")])
3062 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3064 (define_insn "*cmp_siqi_trunc"
3065 [(set (reg:CC CC_REG)
3066 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3069 "andcc\t%0, 0xff, %%g0"
3070 [(set_attr "type" "compare")])
3072 (define_insn "*cmp_siqi_trunc_set"
3073 [(set (reg:CC CC_REG)
3074 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3076 (set (match_operand:QI 0 "register_operand" "=r")
3077 (subreg:QI (match_dup 1) 3))]
3079 "andcc\t%1, 0xff, %0"
3080 [(set_attr "type" "compare")])
3082 (define_insn "*cmp_diqi_trunc"
3083 [(set (reg:CC CC_REG)
3084 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3087 "andcc\t%0, 0xff, %%g0"
3088 [(set_attr "type" "compare")])
3090 (define_insn "*cmp_diqi_trunc_set"
3091 [(set (reg:CC CC_REG)
3092 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3094 (set (match_operand:QI 0 "register_operand" "=r")
3095 (subreg:QI (match_dup 1) 7))]
3097 "andcc\t%1, 0xff, %0"
3098 [(set_attr "type" "compare")])
3101 ;; Sign-extension instructions
3103 ;; These patterns originally accepted general_operands, however, slightly
3104 ;; better code is generated by only accepting register_operands, and then
3105 ;; letting combine generate the lds[hb] insns.
3107 (define_expand "extendhisi2"
3108 [(set (match_operand:SI 0 "register_operand" "")
3109 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3112 rtx temp = gen_reg_rtx (SImode);
3113 rtx shift_16 = GEN_INT (16);
3114 int op1_subbyte = 0;
3116 if (GET_CODE (operand1) == SUBREG)
3118 op1_subbyte = SUBREG_BYTE (operand1);
3119 op1_subbyte /= GET_MODE_SIZE (SImode);
3120 op1_subbyte *= GET_MODE_SIZE (SImode);
3121 operand1 = XEXP (operand1, 0);
3124 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3126 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3130 (define_insn "*sign_extendhisi2_insn"
3131 [(set (match_operand:SI 0 "register_operand" "=r")
3132 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3135 [(set_attr "type" "sload")
3136 (set_attr "us3load_type" "3cycle")])
3138 (define_expand "extendqihi2"
3139 [(set (match_operand:HI 0 "register_operand" "")
3140 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3143 rtx temp = gen_reg_rtx (SImode);
3144 rtx shift_24 = GEN_INT (24);
3145 int op1_subbyte = 0;
3146 int op0_subbyte = 0;
3148 if (GET_CODE (operand1) == SUBREG)
3150 op1_subbyte = SUBREG_BYTE (operand1);
3151 op1_subbyte /= GET_MODE_SIZE (SImode);
3152 op1_subbyte *= GET_MODE_SIZE (SImode);
3153 operand1 = XEXP (operand1, 0);
3155 if (GET_CODE (operand0) == SUBREG)
3157 op0_subbyte = SUBREG_BYTE (operand0);
3158 op0_subbyte /= GET_MODE_SIZE (SImode);
3159 op0_subbyte *= GET_MODE_SIZE (SImode);
3160 operand0 = XEXP (operand0, 0);
3162 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3164 if (GET_MODE (operand0) != SImode)
3165 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3166 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3170 (define_insn "*sign_extendqihi2_insn"
3171 [(set (match_operand:HI 0 "register_operand" "=r")
3172 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3175 [(set_attr "type" "sload")
3176 (set_attr "us3load_type" "3cycle")])
3178 (define_expand "extendqisi2"
3179 [(set (match_operand:SI 0 "register_operand" "")
3180 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3183 rtx temp = gen_reg_rtx (SImode);
3184 rtx shift_24 = GEN_INT (24);
3185 int op1_subbyte = 0;
3187 if (GET_CODE (operand1) == SUBREG)
3189 op1_subbyte = SUBREG_BYTE (operand1);
3190 op1_subbyte /= GET_MODE_SIZE (SImode);
3191 op1_subbyte *= GET_MODE_SIZE (SImode);
3192 operand1 = XEXP (operand1, 0);
3195 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3197 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3201 (define_insn "*sign_extendqisi2_insn"
3202 [(set (match_operand:SI 0 "register_operand" "=r")
3203 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3206 [(set_attr "type" "sload")
3207 (set_attr "us3load_type" "3cycle")])
3209 (define_expand "extendqidi2"
3210 [(set (match_operand:DI 0 "register_operand" "")
3211 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3214 rtx temp = gen_reg_rtx (DImode);
3215 rtx shift_56 = GEN_INT (56);
3216 int op1_subbyte = 0;
3218 if (GET_CODE (operand1) == SUBREG)
3220 op1_subbyte = SUBREG_BYTE (operand1);
3221 op1_subbyte /= GET_MODE_SIZE (DImode);
3222 op1_subbyte *= GET_MODE_SIZE (DImode);
3223 operand1 = XEXP (operand1, 0);
3226 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3228 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3232 (define_insn "*sign_extendqidi2_insn"
3233 [(set (match_operand:DI 0 "register_operand" "=r")
3234 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3237 [(set_attr "type" "sload")
3238 (set_attr "us3load_type" "3cycle")])
3240 (define_expand "extendhidi2"
3241 [(set (match_operand:DI 0 "register_operand" "")
3242 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3245 rtx temp = gen_reg_rtx (DImode);
3246 rtx shift_48 = GEN_INT (48);
3247 int op1_subbyte = 0;
3249 if (GET_CODE (operand1) == SUBREG)
3251 op1_subbyte = SUBREG_BYTE (operand1);
3252 op1_subbyte /= GET_MODE_SIZE (DImode);
3253 op1_subbyte *= GET_MODE_SIZE (DImode);
3254 operand1 = XEXP (operand1, 0);
3257 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3259 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3263 (define_insn "*sign_extendhidi2_insn"
3264 [(set (match_operand:DI 0 "register_operand" "=r")
3265 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3268 [(set_attr "type" "sload")
3269 (set_attr "us3load_type" "3cycle")])
3271 (define_expand "extendsidi2"
3272 [(set (match_operand:DI 0 "register_operand" "")
3273 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3277 (define_insn "*sign_extendsidi2_insn"
3278 [(set (match_operand:DI 0 "register_operand" "=r,r")
3279 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3284 [(set_attr "type" "shift,sload")
3285 (set_attr "us3load_type" "*,3cycle")])
3288 ;; Special pattern for optimizing bit-field compares. This is needed
3289 ;; because combine uses this as a canonical form.
3291 (define_insn "*cmp_zero_extract"
3292 [(set (reg:CC CC_REG)
3294 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3295 (match_operand:SI 1 "small_int_operand" "I")
3296 (match_operand:SI 2 "small_int_operand" "I"))
3298 "INTVAL (operands[2]) > 19"
3300 int len = INTVAL (operands[1]);
3301 int pos = 32 - INTVAL (operands[2]) - len;
3302 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3303 operands[1] = GEN_INT (mask);
3304 return "andcc\t%0, %1, %%g0";
3306 [(set_attr "type" "compare")])
3308 (define_insn "*cmp_zero_extract_sp64"
3309 [(set (reg:CCX CC_REG)
3311 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3312 (match_operand:SI 1 "small_int_operand" "I")
3313 (match_operand:SI 2 "small_int_operand" "I"))
3315 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3317 int len = INTVAL (operands[1]);
3318 int pos = 64 - INTVAL (operands[2]) - len;
3319 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3320 operands[1] = GEN_INT (mask);
3321 return "andcc\t%0, %1, %%g0";
3323 [(set_attr "type" "compare")])
3326 ;; Conversions between float, double and long double.
3328 (define_insn "extendsfdf2"
3329 [(set (match_operand:DF 0 "register_operand" "=e")
3331 (match_operand:SF 1 "register_operand" "f")))]
3334 [(set_attr "type" "fp")
3335 (set_attr "fptype" "double")])
3337 (define_expand "extendsftf2"
3338 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3340 (match_operand:SF 1 "register_operand" "")))]
3341 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3342 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3344 (define_insn "*extendsftf2_hq"
3345 [(set (match_operand:TF 0 "register_operand" "=e")
3347 (match_operand:SF 1 "register_operand" "f")))]
3348 "TARGET_FPU && TARGET_HARD_QUAD"
3350 [(set_attr "type" "fp")])
3352 (define_expand "extenddftf2"
3353 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3355 (match_operand:DF 1 "register_operand" "")))]
3356 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3357 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3359 (define_insn "*extenddftf2_hq"
3360 [(set (match_operand:TF 0 "register_operand" "=e")
3362 (match_operand:DF 1 "register_operand" "e")))]
3363 "TARGET_FPU && TARGET_HARD_QUAD"
3365 [(set_attr "type" "fp")])
3367 (define_insn "truncdfsf2"
3368 [(set (match_operand:SF 0 "register_operand" "=f")
3370 (match_operand:DF 1 "register_operand" "e")))]
3373 [(set_attr "type" "fp")
3374 (set_attr "fptype" "double")])
3376 (define_expand "trunctfsf2"
3377 [(set (match_operand:SF 0 "register_operand" "")
3379 (match_operand:TF 1 "general_operand" "")))]
3380 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3381 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3383 (define_insn "*trunctfsf2_hq"
3384 [(set (match_operand:SF 0 "register_operand" "=f")
3386 (match_operand:TF 1 "register_operand" "e")))]
3387 "TARGET_FPU && TARGET_HARD_QUAD"
3389 [(set_attr "type" "fp")])
3391 (define_expand "trunctfdf2"
3392 [(set (match_operand:DF 0 "register_operand" "")
3394 (match_operand:TF 1 "general_operand" "")))]
3395 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3396 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3398 (define_insn "*trunctfdf2_hq"
3399 [(set (match_operand:DF 0 "register_operand" "=e")
3401 (match_operand:TF 1 "register_operand" "e")))]
3402 "TARGET_FPU && TARGET_HARD_QUAD"
3404 [(set_attr "type" "fp")])
3407 ;; Conversion between fixed point and floating point.
3409 (define_insn "floatsisf2"
3410 [(set (match_operand:SF 0 "register_operand" "=f")
3411 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3414 [(set_attr "type" "fp")
3415 (set_attr "fptype" "double")])
3417 (define_insn "floatsidf2"
3418 [(set (match_operand:DF 0 "register_operand" "=e")
3419 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3422 [(set_attr "type" "fp")
3423 (set_attr "fptype" "double")])
3425 (define_expand "floatsitf2"
3426 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3427 (float:TF (match_operand:SI 1 "register_operand" "")))]
3428 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3429 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3431 (define_insn "*floatsitf2_hq"
3432 [(set (match_operand:TF 0 "register_operand" "=e")
3433 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3434 "TARGET_FPU && TARGET_HARD_QUAD"
3436 [(set_attr "type" "fp")])
3438 (define_expand "floatunssitf2"
3439 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3440 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3441 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3442 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3444 ;; Now the same for 64 bit sources.
3446 (define_insn "floatdisf2"
3447 [(set (match_operand:SF 0 "register_operand" "=f")
3448 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3449 "TARGET_V9 && TARGET_FPU"
3451 [(set_attr "type" "fp")
3452 (set_attr "fptype" "double")])
3454 (define_expand "floatunsdisf2"
3455 [(use (match_operand:SF 0 "register_operand" ""))
3456 (use (match_operand:DI 1 "general_operand" ""))]
3457 "TARGET_ARCH64 && TARGET_FPU"
3458 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3460 (define_insn "floatdidf2"
3461 [(set (match_operand:DF 0 "register_operand" "=e")
3462 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3463 "TARGET_V9 && TARGET_FPU"
3465 [(set_attr "type" "fp")
3466 (set_attr "fptype" "double")])
3468 (define_expand "floatunsdidf2"
3469 [(use (match_operand:DF 0 "register_operand" ""))
3470 (use (match_operand:DI 1 "general_operand" ""))]
3471 "TARGET_ARCH64 && TARGET_FPU"
3472 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3474 (define_expand "floatditf2"
3475 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3476 (float:TF (match_operand:DI 1 "register_operand" "")))]
3477 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3478 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3480 (define_insn "*floatditf2_hq"
3481 [(set (match_operand:TF 0 "register_operand" "=e")
3482 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3483 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3485 [(set_attr "type" "fp")])
3487 (define_expand "floatunsditf2"
3488 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3489 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3490 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3491 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3493 ;; Convert a float to an actual integer.
3494 ;; Truncation is performed as part of the conversion.
3496 (define_insn "fix_truncsfsi2"
3497 [(set (match_operand:SI 0 "register_operand" "=f")
3498 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3501 [(set_attr "type" "fp")
3502 (set_attr "fptype" "double")])
3504 (define_insn "fix_truncdfsi2"
3505 [(set (match_operand:SI 0 "register_operand" "=f")
3506 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3509 [(set_attr "type" "fp")
3510 (set_attr "fptype" "double")])
3512 (define_expand "fix_trunctfsi2"
3513 [(set (match_operand:SI 0 "register_operand" "")
3514 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3515 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3516 "emit_tfmode_cvt (FIX, operands); DONE;")
3518 (define_insn "*fix_trunctfsi2_hq"
3519 [(set (match_operand:SI 0 "register_operand" "=f")
3520 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3521 "TARGET_FPU && TARGET_HARD_QUAD"
3523 [(set_attr "type" "fp")])
3525 (define_expand "fixuns_trunctfsi2"
3526 [(set (match_operand:SI 0 "register_operand" "")
3527 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3528 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3529 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3531 ;; Now the same, for V9 targets
3533 (define_insn "fix_truncsfdi2"
3534 [(set (match_operand:DI 0 "register_operand" "=e")
3535 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3536 "TARGET_V9 && TARGET_FPU"
3538 [(set_attr "type" "fp")
3539 (set_attr "fptype" "double")])
3541 (define_expand "fixuns_truncsfdi2"
3542 [(use (match_operand:DI 0 "register_operand" ""))
3543 (use (match_operand:SF 1 "general_operand" ""))]
3544 "TARGET_ARCH64 && TARGET_FPU"
3545 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3547 (define_insn "fix_truncdfdi2"
3548 [(set (match_operand:DI 0 "register_operand" "=e")
3549 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3550 "TARGET_V9 && TARGET_FPU"
3552 [(set_attr "type" "fp")
3553 (set_attr "fptype" "double")])
3555 (define_expand "fixuns_truncdfdi2"
3556 [(use (match_operand:DI 0 "register_operand" ""))
3557 (use (match_operand:DF 1 "general_operand" ""))]
3558 "TARGET_ARCH64 && TARGET_FPU"
3559 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3561 (define_expand "fix_trunctfdi2"
3562 [(set (match_operand:DI 0 "register_operand" "")
3563 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3564 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3565 "emit_tfmode_cvt (FIX, operands); DONE;")
3567 (define_insn "*fix_trunctfdi2_hq"
3568 [(set (match_operand:DI 0 "register_operand" "=e")
3569 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3570 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3572 [(set_attr "type" "fp")])
3574 (define_expand "fixuns_trunctfdi2"
3575 [(set (match_operand:DI 0 "register_operand" "")
3576 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3577 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3578 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3581 ;; Integer addition/subtraction instructions.
3583 (define_expand "adddi3"
3584 [(set (match_operand:DI 0 "register_operand" "")
3585 (plus:DI (match_operand:DI 1 "register_operand" "")
3586 (match_operand:DI 2 "arith_double_add_operand" "")))]
3589 if (! TARGET_ARCH64)
3591 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3592 gen_rtx_SET (VOIDmode, operands[0],
3593 gen_rtx_PLUS (DImode, operands[1],
3595 gen_rtx_CLOBBER (VOIDmode,
3596 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3601 (define_insn_and_split "*adddi3_insn_sp32"
3602 [(set (match_operand:DI 0 "register_operand" "=r")
3603 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3604 (match_operand:DI 2 "arith_double_operand" "rHI")))
3605 (clobber (reg:CC CC_REG))]
3608 "&& reload_completed"
3609 [(parallel [(set (reg:CC_NOOV CC_REG)
3610 (compare:CC_NOOV (plus:SI (match_dup 4)
3614 (plus:SI (match_dup 4) (match_dup 5)))])
3616 (plus:SI (plus:SI (match_dup 7)
3618 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3620 operands[3] = gen_lowpart (SImode, operands[0]);
3621 operands[4] = gen_lowpart (SImode, operands[1]);
3622 operands[5] = gen_lowpart (SImode, operands[2]);
3623 operands[6] = gen_highpart (SImode, operands[0]);
3624 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3625 #if HOST_BITS_PER_WIDE_INT == 32
3626 if (GET_CODE (operands[2]) == CONST_INT)
3628 if (INTVAL (operands[2]) < 0)
3629 operands[8] = constm1_rtx;
3631 operands[8] = const0_rtx;
3635 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3637 [(set_attr "length" "2")])
3639 ;; LTU here means "carry set"
3641 [(set (match_operand:SI 0 "register_operand" "=r")
3642 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3643 (match_operand:SI 2 "arith_operand" "rI"))
3644 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3647 [(set_attr "type" "ialuX")])
3649 (define_insn_and_split "*addx_extend_sp32"
3650 [(set (match_operand:DI 0 "register_operand" "=r")
3651 (zero_extend:DI (plus:SI (plus:SI
3652 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3653 (match_operand:SI 2 "arith_operand" "rI"))
3654 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3657 "&& reload_completed"
3658 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3659 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3660 (set (match_dup 4) (const_int 0))]
3661 "operands[3] = gen_lowpart (SImode, operands[0]);
3662 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3663 [(set_attr "length" "2")])
3665 (define_insn "*addx_extend_sp64"
3666 [(set (match_operand:DI 0 "register_operand" "=r")
3667 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3668 (match_operand:SI 2 "arith_operand" "rI"))
3669 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3672 [(set_attr "type" "ialuX")])
3674 (define_insn_and_split "*adddi3_extend_sp32"
3675 [(set (match_operand:DI 0 "register_operand" "=r")
3676 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3677 (match_operand:DI 2 "register_operand" "r")))
3678 (clobber (reg:CC CC_REG))]
3681 "&& reload_completed"
3682 [(parallel [(set (reg:CC_NOOV CC_REG)
3683 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3685 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3687 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3688 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3689 "operands[3] = gen_lowpart (SImode, operands[2]);
3690 operands[4] = gen_highpart (SImode, operands[2]);
3691 operands[5] = gen_lowpart (SImode, operands[0]);
3692 operands[6] = gen_highpart (SImode, operands[0]);"
3693 [(set_attr "length" "2")])
3695 (define_insn "*adddi3_sp64"
3696 [(set (match_operand:DI 0 "register_operand" "=r,r")
3697 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3698 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3704 (define_insn "addsi3"
3705 [(set (match_operand:SI 0 "register_operand" "=r,r")
3706 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3707 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3712 [(set_attr "type" "*,*")
3713 (set_attr "fptype" "*,*")])
3715 (define_insn "*cmp_cc_plus"
3716 [(set (reg:CC_NOOV CC_REG)
3717 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3718 (match_operand:SI 1 "arith_operand" "rI"))
3721 "addcc\t%0, %1, %%g0"
3722 [(set_attr "type" "compare")])
3724 (define_insn "*cmp_ccx_plus"
3725 [(set (reg:CCX_NOOV CC_REG)
3726 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3727 (match_operand:DI 1 "arith_operand" "rI"))
3730 "addcc\t%0, %1, %%g0"
3731 [(set_attr "type" "compare")])
3733 (define_insn "*cmp_cc_plus_set"
3734 [(set (reg:CC_NOOV CC_REG)
3735 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3736 (match_operand:SI 2 "arith_operand" "rI"))
3738 (set (match_operand:SI 0 "register_operand" "=r")
3739 (plus:SI (match_dup 1) (match_dup 2)))]
3742 [(set_attr "type" "compare")])
3744 (define_insn "*cmp_ccx_plus_set"
3745 [(set (reg:CCX_NOOV CC_REG)
3746 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3747 (match_operand:DI 2 "arith_operand" "rI"))
3749 (set (match_operand:DI 0 "register_operand" "=r")
3750 (plus:DI (match_dup 1) (match_dup 2)))]
3753 [(set_attr "type" "compare")])
3755 (define_expand "subdi3"
3756 [(set (match_operand:DI 0 "register_operand" "")
3757 (minus:DI (match_operand:DI 1 "register_operand" "")
3758 (match_operand:DI 2 "arith_double_add_operand" "")))]
3761 if (! TARGET_ARCH64)
3763 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3764 gen_rtx_SET (VOIDmode, operands[0],
3765 gen_rtx_MINUS (DImode, operands[1],
3767 gen_rtx_CLOBBER (VOIDmode,
3768 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3773 (define_insn_and_split "*subdi3_insn_sp32"
3774 [(set (match_operand:DI 0 "register_operand" "=r")
3775 (minus:DI (match_operand:DI 1 "register_operand" "r")
3776 (match_operand:DI 2 "arith_double_operand" "rHI")))
3777 (clobber (reg:CC CC_REG))]
3780 "&& reload_completed"
3781 [(parallel [(set (reg:CC_NOOV CC_REG)
3782 (compare:CC_NOOV (minus:SI (match_dup 4)
3786 (minus:SI (match_dup 4) (match_dup 5)))])
3788 (minus:SI (minus:SI (match_dup 7)
3790 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3792 operands[3] = gen_lowpart (SImode, operands[0]);
3793 operands[4] = gen_lowpart (SImode, operands[1]);
3794 operands[5] = gen_lowpart (SImode, operands[2]);
3795 operands[6] = gen_highpart (SImode, operands[0]);
3796 operands[7] = gen_highpart (SImode, operands[1]);
3797 #if HOST_BITS_PER_WIDE_INT == 32
3798 if (GET_CODE (operands[2]) == CONST_INT)
3800 if (INTVAL (operands[2]) < 0)
3801 operands[8] = constm1_rtx;
3803 operands[8] = const0_rtx;
3807 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3809 [(set_attr "length" "2")])
3811 ;; LTU here means "carry set"
3813 [(set (match_operand:SI 0 "register_operand" "=r")
3814 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3815 (match_operand:SI 2 "arith_operand" "rI"))
3816 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3819 [(set_attr "type" "ialuX")])
3821 (define_insn "*subx_extend_sp64"
3822 [(set (match_operand:DI 0 "register_operand" "=r")
3823 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3824 (match_operand:SI 2 "arith_operand" "rI"))
3825 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3828 [(set_attr "type" "ialuX")])
3830 (define_insn_and_split "*subx_extend"
3831 [(set (match_operand:DI 0 "register_operand" "=r")
3832 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3833 (match_operand:SI 2 "arith_operand" "rI"))
3834 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3837 "&& reload_completed"
3838 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3839 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3840 (set (match_dup 4) (const_int 0))]
3841 "operands[3] = gen_lowpart (SImode, operands[0]);
3842 operands[4] = gen_highpart (SImode, operands[0]);"
3843 [(set_attr "length" "2")])
3845 (define_insn_and_split "*subdi3_extend_sp32"
3846 [(set (match_operand:DI 0 "register_operand" "=r")
3847 (minus:DI (match_operand:DI 1 "register_operand" "r")
3848 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3849 (clobber (reg:CC CC_REG))]
3852 "&& reload_completed"
3853 [(parallel [(set (reg:CC_NOOV CC_REG)
3854 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3856 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3858 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3859 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3860 "operands[3] = gen_lowpart (SImode, operands[1]);
3861 operands[4] = gen_highpart (SImode, operands[1]);
3862 operands[5] = gen_lowpart (SImode, operands[0]);
3863 operands[6] = gen_highpart (SImode, operands[0]);"
3864 [(set_attr "length" "2")])
3866 (define_insn "*subdi3_sp64"
3867 [(set (match_operand:DI 0 "register_operand" "=r,r")
3868 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3869 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3875 (define_insn "subsi3"
3876 [(set (match_operand:SI 0 "register_operand" "=r,r")
3877 (minus:SI (match_operand:SI 1 "register_operand" "r,r")
3878 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3883 [(set_attr "type" "*,*")
3884 (set_attr "fptype" "*,*")])
3886 (define_insn "*cmp_minus_cc"
3887 [(set (reg:CC_NOOV CC_REG)
3888 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3889 (match_operand:SI 1 "arith_operand" "rI"))
3892 "subcc\t%r0, %1, %%g0"
3893 [(set_attr "type" "compare")])
3895 (define_insn "*cmp_minus_ccx"
3896 [(set (reg:CCX_NOOV CC_REG)
3897 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3898 (match_operand:DI 1 "arith_operand" "rI"))
3901 "subcc\t%0, %1, %%g0"
3902 [(set_attr "type" "compare")])
3904 (define_insn "cmp_minus_cc_set"
3905 [(set (reg:CC_NOOV CC_REG)
3906 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3907 (match_operand:SI 2 "arith_operand" "rI"))
3909 (set (match_operand:SI 0 "register_operand" "=r")
3910 (minus:SI (match_dup 1) (match_dup 2)))]
3912 "subcc\t%r1, %2, %0"
3913 [(set_attr "type" "compare")])
3915 (define_insn "*cmp_minus_ccx_set"
3916 [(set (reg:CCX_NOOV CC_REG)
3917 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3918 (match_operand:DI 2 "arith_operand" "rI"))
3920 (set (match_operand:DI 0 "register_operand" "=r")
3921 (minus:DI (match_dup 1) (match_dup 2)))]
3924 [(set_attr "type" "compare")])
3927 ;; Integer multiply/divide instructions.
3929 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3930 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3932 (define_insn "mulsi3"
3933 [(set (match_operand:SI 0 "register_operand" "=r")
3934 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3935 (match_operand:SI 2 "arith_operand" "rI")))]
3938 [(set_attr "type" "imul")])
3940 (define_expand "muldi3"
3941 [(set (match_operand:DI 0 "register_operand" "")
3942 (mult:DI (match_operand:DI 1 "arith_operand" "")
3943 (match_operand:DI 2 "arith_operand" "")))]
3944 "TARGET_ARCH64 || TARGET_V8PLUS"
3948 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3953 (define_insn "*muldi3_sp64"
3954 [(set (match_operand:DI 0 "register_operand" "=r")
3955 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3956 (match_operand:DI 2 "arith_operand" "rI")))]
3959 [(set_attr "type" "imul")])
3961 ;; V8plus wide multiply.
3963 (define_insn "muldi3_v8plus"
3964 [(set (match_operand:DI 0 "register_operand" "=r,h")
3965 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3966 (match_operand:DI 2 "arith_operand" "rI,rI")))
3967 (clobber (match_scratch:SI 3 "=&h,X"))
3968 (clobber (match_scratch:SI 4 "=&h,X"))]
3970 "* return output_v8plus_mult (insn, operands, \"mulx\");"
3971 [(set_attr "type" "multi")
3972 (set_attr "length" "9,8")])
3974 (define_insn "*cmp_mul_set"
3975 [(set (reg:CC CC_REG)
3976 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3977 (match_operand:SI 2 "arith_operand" "rI"))
3979 (set (match_operand:SI 0 "register_operand" "=r")
3980 (mult:SI (match_dup 1) (match_dup 2)))]
3981 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3982 "smulcc\t%1, %2, %0"
3983 [(set_attr "type" "imul")])
3985 (define_expand "mulsidi3"
3986 [(set (match_operand:DI 0 "register_operand" "")
3987 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3988 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3991 if (CONSTANT_P (operands[2]))
3994 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3996 else if (TARGET_ARCH32)
3997 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4000 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4006 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4011 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4012 ;; registers can hold 64-bit values in the V8plus environment.
4014 (define_insn "mulsidi3_v8plus"
4015 [(set (match_operand:DI 0 "register_operand" "=h,r")
4016 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4017 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4018 (clobber (match_scratch:SI 3 "=X,&h"))]
4021 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4022 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4023 [(set_attr "type" "multi")
4024 (set_attr "length" "2,3")])
4027 (define_insn "const_mulsidi3_v8plus"
4028 [(set (match_operand:DI 0 "register_operand" "=h,r")
4029 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4030 (match_operand:DI 2 "small_int_operand" "I,I")))
4031 (clobber (match_scratch:SI 3 "=X,&h"))]
4034 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4035 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4036 [(set_attr "type" "multi")
4037 (set_attr "length" "2,3")])
4040 (define_insn "*mulsidi3_sp32"
4041 [(set (match_operand:DI 0 "register_operand" "=r")
4042 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4043 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4046 return TARGET_SPARCLET
4047 ? "smuld\t%1, %2, %L0"
4048 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4051 (if_then_else (eq_attr "isa" "sparclet")
4052 (const_string "imul") (const_string "multi")))
4053 (set (attr "length")
4054 (if_then_else (eq_attr "isa" "sparclet")
4055 (const_int 1) (const_int 2)))])
4057 (define_insn "*mulsidi3_sp64"
4058 [(set (match_operand:DI 0 "register_operand" "=r")
4059 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4060 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4061 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4063 [(set_attr "type" "imul")])
4065 ;; Extra pattern, because sign_extend of a constant isn't valid.
4068 (define_insn "const_mulsidi3_sp32"
4069 [(set (match_operand:DI 0 "register_operand" "=r")
4070 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4071 (match_operand:DI 2 "small_int_operand" "I")))]
4074 return TARGET_SPARCLET
4075 ? "smuld\t%1, %2, %L0"
4076 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4079 (if_then_else (eq_attr "isa" "sparclet")
4080 (const_string "imul") (const_string "multi")))
4081 (set (attr "length")
4082 (if_then_else (eq_attr "isa" "sparclet")
4083 (const_int 1) (const_int 2)))])
4085 (define_insn "const_mulsidi3_sp64"
4086 [(set (match_operand:DI 0 "register_operand" "=r")
4087 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4088 (match_operand:DI 2 "small_int_operand" "I")))]
4089 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4091 [(set_attr "type" "imul")])
4093 (define_expand "smulsi3_highpart"
4094 [(set (match_operand:SI 0 "register_operand" "")
4096 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4097 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4099 "TARGET_HARD_MUL && TARGET_ARCH32"
4101 if (CONSTANT_P (operands[2]))
4105 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4111 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4116 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4117 operands[2], GEN_INT (32)));
4123 (define_insn "smulsi3_highpart_v8plus"
4124 [(set (match_operand:SI 0 "register_operand" "=h,r")
4126 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4127 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4128 (match_operand:SI 3 "small_int_operand" "I,I"))))
4129 (clobber (match_scratch:SI 4 "=X,&h"))]
4132 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4133 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4134 [(set_attr "type" "multi")
4135 (set_attr "length" "2")])
4137 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4140 [(set (match_operand:SI 0 "register_operand" "=h,r")
4143 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4144 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4145 (match_operand:SI 3 "small_int_operand" "I,I"))
4147 (clobber (match_scratch:SI 4 "=X,&h"))]
4150 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4151 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4152 [(set_attr "type" "multi")
4153 (set_attr "length" "2")])
4156 (define_insn "const_smulsi3_highpart_v8plus"
4157 [(set (match_operand:SI 0 "register_operand" "=h,r")
4159 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4160 (match_operand:DI 2 "small_int_operand" "I,I"))
4161 (match_operand:SI 3 "small_int_operand" "I,I"))))
4162 (clobber (match_scratch:SI 4 "=X,&h"))]
4165 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4166 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4167 [(set_attr "type" "multi")
4168 (set_attr "length" "2")])
4171 (define_insn "*smulsi3_highpart_sp32"
4172 [(set (match_operand:SI 0 "register_operand" "=r")
4174 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4175 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4178 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4179 [(set_attr "type" "multi")
4180 (set_attr "length" "2")])
4183 (define_insn "const_smulsi3_highpart"
4184 [(set (match_operand:SI 0 "register_operand" "=r")
4186 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4187 (match_operand:DI 2 "small_int_operand" "i"))
4190 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4191 [(set_attr "type" "multi")
4192 (set_attr "length" "2")])
4194 (define_expand "umulsidi3"
4195 [(set (match_operand:DI 0 "register_operand" "")
4196 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4197 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4200 if (CONSTANT_P (operands[2]))
4203 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4205 else if (TARGET_ARCH32)
4206 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4209 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4215 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4221 (define_insn "umulsidi3_v8plus"
4222 [(set (match_operand:DI 0 "register_operand" "=h,r")
4223 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4224 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4225 (clobber (match_scratch:SI 3 "=X,&h"))]
4228 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4229 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4230 [(set_attr "type" "multi")
4231 (set_attr "length" "2,3")])
4234 (define_insn "*umulsidi3_sp32"
4235 [(set (match_operand:DI 0 "register_operand" "=r")
4236 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4237 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4240 return TARGET_SPARCLET
4241 ? "umuld\t%1, %2, %L0"
4242 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4245 (if_then_else (eq_attr "isa" "sparclet")
4246 (const_string "imul") (const_string "multi")))
4247 (set (attr "length")
4248 (if_then_else (eq_attr "isa" "sparclet")
4249 (const_int 1) (const_int 2)))])
4251 (define_insn "*umulsidi3_sp64"
4252 [(set (match_operand:DI 0 "register_operand" "=r")
4253 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4254 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4255 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4257 [(set_attr "type" "imul")])
4259 ;; Extra pattern, because sign_extend of a constant isn't valid.
4262 (define_insn "const_umulsidi3_sp32"
4263 [(set (match_operand:DI 0 "register_operand" "=r")
4264 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4265 (match_operand:DI 2 "uns_small_int_operand" "")))]
4268 return TARGET_SPARCLET
4269 ? "umuld\t%1, %s2, %L0"
4270 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4273 (if_then_else (eq_attr "isa" "sparclet")
4274 (const_string "imul") (const_string "multi")))
4275 (set (attr "length")
4276 (if_then_else (eq_attr "isa" "sparclet")
4277 (const_int 1) (const_int 2)))])
4279 (define_insn "const_umulsidi3_sp64"
4280 [(set (match_operand:DI 0 "register_operand" "=r")
4281 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4282 (match_operand:DI 2 "uns_small_int_operand" "")))]
4283 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4285 [(set_attr "type" "imul")])
4288 (define_insn "const_umulsidi3_v8plus"
4289 [(set (match_operand:DI 0 "register_operand" "=h,r")
4290 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4291 (match_operand:DI 2 "uns_small_int_operand" "")))
4292 (clobber (match_scratch:SI 3 "=X,h"))]
4295 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4296 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4297 [(set_attr "type" "multi")
4298 (set_attr "length" "2,3")])
4300 (define_expand "umulsi3_highpart"
4301 [(set (match_operand:SI 0 "register_operand" "")
4303 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4304 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4306 "TARGET_HARD_MUL && TARGET_ARCH32"
4308 if (CONSTANT_P (operands[2]))
4312 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4318 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4323 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4324 operands[2], GEN_INT (32)));
4330 (define_insn "umulsi3_highpart_v8plus"
4331 [(set (match_operand:SI 0 "register_operand" "=h,r")
4333 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4334 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4335 (match_operand:SI 3 "small_int_operand" "I,I"))))
4336 (clobber (match_scratch:SI 4 "=X,h"))]
4339 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4340 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4341 [(set_attr "type" "multi")
4342 (set_attr "length" "2")])
4345 (define_insn "const_umulsi3_highpart_v8plus"
4346 [(set (match_operand:SI 0 "register_operand" "=h,r")
4348 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4349 (match_operand:DI 2 "uns_small_int_operand" ""))
4350 (match_operand:SI 3 "small_int_operand" "I,I"))))
4351 (clobber (match_scratch:SI 4 "=X,h"))]
4354 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4355 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4356 [(set_attr "type" "multi")
4357 (set_attr "length" "2")])
4360 (define_insn "*umulsi3_highpart_sp32"
4361 [(set (match_operand:SI 0 "register_operand" "=r")
4363 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4364 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4367 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4368 [(set_attr "type" "multi")
4369 (set_attr "length" "2")])
4372 (define_insn "const_umulsi3_highpart"
4373 [(set (match_operand:SI 0 "register_operand" "=r")
4375 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4376 (match_operand:DI 2 "uns_small_int_operand" ""))
4379 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4380 [(set_attr "type" "multi")
4381 (set_attr "length" "2")])
4383 (define_expand "divsi3"
4384 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4385 (div:SI (match_operand:SI 1 "register_operand" "")
4386 (match_operand:SI 2 "input_operand" "")))
4387 (clobber (match_scratch:SI 3 ""))])]
4388 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4392 operands[3] = gen_reg_rtx(SImode);
4393 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4394 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4400 ;; The V8 architecture specifies that there must be at least 3 instructions
4401 ;; between a write to the Y register and a use of it for correct results.
4402 ;; We try to fill one of them with a simple constant or a memory load.
4404 (define_insn "divsi3_sp32"
4405 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4406 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4407 (match_operand:SI 2 "input_operand" "rI,K,m")))
4408 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4409 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4411 output_asm_insn ("sra\t%1, 31, %3", operands);
4412 output_asm_insn ("wr\t%3, 0, %%y", operands);
4414 switch (which_alternative)
4418 return "sdiv\t%1, %2, %0";
4420 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4423 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4425 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4428 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4430 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4435 [(set_attr "type" "multi")
4436 (set (attr "length")
4437 (if_then_else (eq_attr "isa" "v9")
4438 (const_int 4) (const_int 6)))])
4440 (define_insn "divsi3_sp64"
4441 [(set (match_operand:SI 0 "register_operand" "=r")
4442 (div:SI (match_operand:SI 1 "register_operand" "r")
4443 (match_operand:SI 2 "input_operand" "rI")))
4444 (use (match_operand:SI 3 "register_operand" "r"))]
4445 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4446 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4447 [(set_attr "type" "multi")
4448 (set_attr "length" "2")])
4450 (define_insn "divdi3"
4451 [(set (match_operand:DI 0 "register_operand" "=r")
4452 (div:DI (match_operand:DI 1 "register_operand" "r")
4453 (match_operand:DI 2 "arith_operand" "rI")))]
4456 [(set_attr "type" "idiv")])
4458 (define_insn "*cmp_sdiv_cc_set"
4459 [(set (reg:CC CC_REG)
4460 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4461 (match_operand:SI 2 "arith_operand" "rI"))
4463 (set (match_operand:SI 0 "register_operand" "=r")
4464 (div:SI (match_dup 1) (match_dup 2)))
4465 (clobber (match_scratch:SI 3 "=&r"))]
4466 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4468 output_asm_insn ("sra\t%1, 31, %3", operands);
4469 output_asm_insn ("wr\t%3, 0, %%y", operands);
4472 return "sdivcc\t%1, %2, %0";
4474 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4476 [(set_attr "type" "multi")
4477 (set (attr "length")
4478 (if_then_else (eq_attr "isa" "v9")
4479 (const_int 3) (const_int 6)))])
4482 (define_expand "udivsi3"
4483 [(set (match_operand:SI 0 "register_operand" "")
4484 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4485 (match_operand:SI 2 "input_operand" "")))]
4486 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4489 ;; The V8 architecture specifies that there must be at least 3 instructions
4490 ;; between a write to the Y register and a use of it for correct results.
4491 ;; We try to fill one of them with a simple constant or a memory load.
4493 (define_insn "udivsi3_sp32"
4494 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4495 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4496 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4497 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4499 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4501 switch (which_alternative)
4505 return "udiv\t%1, %2, %0";
4507 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4510 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4512 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4515 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4517 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4520 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4522 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4527 [(set_attr "type" "multi")
4528 (set (attr "length")
4529 (if_then_else (eq_attr "isa" "v9")
4530 (const_int 3) (const_int 5)))])
4532 (define_insn "udivsi3_sp64"
4533 [(set (match_operand:SI 0 "register_operand" "=r")
4534 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4535 (match_operand:SI 2 "input_operand" "rI")))]
4536 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4537 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4538 [(set_attr "type" "multi")
4539 (set_attr "length" "2")])
4541 (define_insn "udivdi3"
4542 [(set (match_operand:DI 0 "register_operand" "=r")
4543 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4544 (match_operand:DI 2 "arith_operand" "rI")))]
4547 [(set_attr "type" "idiv")])
4549 (define_insn "*cmp_udiv_cc_set"
4550 [(set (reg:CC CC_REG)
4551 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4552 (match_operand:SI 2 "arith_operand" "rI"))
4554 (set (match_operand:SI 0 "register_operand" "=r")
4555 (udiv:SI (match_dup 1) (match_dup 2)))]
4556 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4558 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4561 return "udivcc\t%1, %2, %0";
4563 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4565 [(set_attr "type" "multi")
4566 (set (attr "length")
4567 (if_then_else (eq_attr "isa" "v9")
4568 (const_int 2) (const_int 5)))])
4570 ; sparclet multiply/accumulate insns
4572 (define_insn "*smacsi"
4573 [(set (match_operand:SI 0 "register_operand" "=r")
4574 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4575 (match_operand:SI 2 "arith_operand" "rI"))
4576 (match_operand:SI 3 "register_operand" "0")))]
4579 [(set_attr "type" "imul")])
4581 (define_insn "*smacdi"
4582 [(set (match_operand:DI 0 "register_operand" "=r")
4583 (plus:DI (mult:DI (sign_extend:DI
4584 (match_operand:SI 1 "register_operand" "%r"))
4586 (match_operand:SI 2 "register_operand" "r")))
4587 (match_operand:DI 3 "register_operand" "0")))]
4589 "smacd\t%1, %2, %L0"
4590 [(set_attr "type" "imul")])
4592 (define_insn "*umacdi"
4593 [(set (match_operand:DI 0 "register_operand" "=r")
4594 (plus:DI (mult:DI (zero_extend:DI
4595 (match_operand:SI 1 "register_operand" "%r"))
4597 (match_operand:SI 2 "register_operand" "r")))
4598 (match_operand:DI 3 "register_operand" "0")))]
4600 "umacd\t%1, %2, %L0"
4601 [(set_attr "type" "imul")])
4604 ;; Boolean instructions.
4606 ;; We define DImode `and' so with DImode `not' we can get
4607 ;; DImode `andn'. Other combinations are possible.
4609 (define_expand "anddi3"
4610 [(set (match_operand:DI 0 "register_operand" "")
4611 (and:DI (match_operand:DI 1 "arith_double_operand" "")
4612 (match_operand:DI 2 "arith_double_operand" "")))]
4616 (define_insn "*anddi3_sp32"
4617 [(set (match_operand:DI 0 "register_operand" "=r")
4618 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4619 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4623 (define_insn "*anddi3_sp64"
4624 [(set (match_operand:DI 0 "register_operand" "=r")
4625 (and:DI (match_operand:DI 1 "arith_operand" "%r")
4626 (match_operand:DI 2 "arith_operand" "rI")))]
4630 (define_insn "andsi3"
4631 [(set (match_operand:SI 0 "register_operand" "=r")
4632 (and:SI (match_operand:SI 1 "arith_operand" "%r")
4633 (match_operand:SI 2 "arith_operand" "rI")))]
4638 [(set (match_operand:SI 0 "register_operand" "")
4639 (and:SI (match_operand:SI 1 "register_operand" "")
4640 (match_operand:SI 2 "const_compl_high_operand" "")))
4641 (clobber (match_operand:SI 3 "register_operand" ""))]
4643 [(set (match_dup 3) (match_dup 4))
4644 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4646 operands[4] = GEN_INT (~INTVAL (operands[2]));
4649 (define_insn_and_split "*and_not_di_sp32"
4650 [(set (match_operand:DI 0 "register_operand" "=r")
4651 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4652 (match_operand:DI 2 "register_operand" "r")))]
4655 "&& reload_completed
4656 && ((GET_CODE (operands[0]) == REG
4657 && REGNO (operands[0]) < 32)
4658 || (GET_CODE (operands[0]) == SUBREG
4659 && GET_CODE (SUBREG_REG (operands[0])) == REG
4660 && REGNO (SUBREG_REG (operands[0])) < 32))"
4661 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4662 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4663 "operands[3] = gen_highpart (SImode, operands[0]);
4664 operands[4] = gen_highpart (SImode, operands[1]);
4665 operands[5] = gen_highpart (SImode, operands[2]);
4666 operands[6] = gen_lowpart (SImode, operands[0]);
4667 operands[7] = gen_lowpart (SImode, operands[1]);
4668 operands[8] = gen_lowpart (SImode, operands[2]);"
4669 [(set_attr "length" "2")])
4671 (define_insn "*and_not_di_sp64"
4672 [(set (match_operand:DI 0 "register_operand" "=r")
4673 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4674 (match_operand:DI 2 "register_operand" "r")))]
4678 (define_insn "*and_not_si"
4679 [(set (match_operand:SI 0 "register_operand" "=r")
4680 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4681 (match_operand:SI 2 "register_operand" "r")))]
4685 (define_expand "iordi3"
4686 [(set (match_operand:DI 0 "register_operand" "")
4687 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4688 (match_operand:DI 2 "arith_double_operand" "")))]
4692 (define_insn "*iordi3_sp32"
4693 [(set (match_operand:DI 0 "register_operand" "=r")
4694 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4695 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4698 [(set_attr "length" "2")])
4700 (define_insn "*iordi3_sp64"
4701 [(set (match_operand:DI 0 "register_operand" "=r")
4702 (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4703 (match_operand:DI 2 "arith_operand" "rI")))]
4707 (define_insn "iorsi3"
4708 [(set (match_operand:SI 0 "register_operand" "=r")
4709 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4710 (match_operand:SI 2 "arith_operand" "rI")))]
4715 [(set (match_operand:SI 0 "register_operand" "")
4716 (ior:SI (match_operand:SI 1 "register_operand" "")
4717 (match_operand:SI 2 "const_compl_high_operand" "")))
4718 (clobber (match_operand:SI 3 "register_operand" ""))]
4720 [(set (match_dup 3) (match_dup 4))
4721 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4723 operands[4] = GEN_INT (~INTVAL (operands[2]));
4726 (define_insn_and_split "*or_not_di_sp32"
4727 [(set (match_operand:DI 0 "register_operand" "=r")
4728 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4729 (match_operand:DI 2 "register_operand" "r")))]
4732 "&& reload_completed
4733 && ((GET_CODE (operands[0]) == REG
4734 && REGNO (operands[0]) < 32)
4735 || (GET_CODE (operands[0]) == SUBREG
4736 && GET_CODE (SUBREG_REG (operands[0])) == REG
4737 && REGNO (SUBREG_REG (operands[0])) < 32))"
4738 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4739 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4740 "operands[3] = gen_highpart (SImode, operands[0]);
4741 operands[4] = gen_highpart (SImode, operands[1]);
4742 operands[5] = gen_highpart (SImode, operands[2]);
4743 operands[6] = gen_lowpart (SImode, operands[0]);
4744 operands[7] = gen_lowpart (SImode, operands[1]);
4745 operands[8] = gen_lowpart (SImode, operands[2]);"
4746 [(set_attr "length" "2")])
4748 (define_insn "*or_not_di_sp64"
4749 [(set (match_operand:DI 0 "register_operand" "=r")
4750 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4751 (match_operand:DI 2 "register_operand" "r")))]
4755 (define_insn "*or_not_si"
4756 [(set (match_operand:SI 0 "register_operand" "=r")
4757 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4758 (match_operand:SI 2 "register_operand" "r")))]
4762 (define_expand "xordi3"
4763 [(set (match_operand:DI 0 "register_operand" "")
4764 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4765 (match_operand:DI 2 "arith_double_operand" "")))]
4769 (define_insn "*xordi3_sp32"
4770 [(set (match_operand:DI 0 "register_operand" "=r")
4771 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4772 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4775 [(set_attr "length" "2")])
4777 (define_insn "*xordi3_sp64"
4778 [(set (match_operand:DI 0 "register_operand" "=r")
4779 (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4780 (match_operand:DI 2 "arith_operand" "rI")))]
4784 (define_insn "xorsi3"
4785 [(set (match_operand:SI 0 "register_operand" "=r")
4786 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4787 (match_operand:SI 2 "arith_operand" "rI")))]
4792 [(set (match_operand:SI 0 "register_operand" "")
4793 (xor:SI (match_operand:SI 1 "register_operand" "")
4794 (match_operand:SI 2 "const_compl_high_operand" "")))
4795 (clobber (match_operand:SI 3 "register_operand" ""))]
4797 [(set (match_dup 3) (match_dup 4))
4798 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4800 operands[4] = GEN_INT (~INTVAL (operands[2]));
4804 [(set (match_operand:SI 0 "register_operand" "")
4805 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4806 (match_operand:SI 2 "const_compl_high_operand" ""))))
4807 (clobber (match_operand:SI 3 "register_operand" ""))]
4809 [(set (match_dup 3) (match_dup 4))
4810 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4812 operands[4] = GEN_INT (~INTVAL (operands[2]));
4815 ;; Split DImode logical operations requiring two instructions.
4817 [(set (match_operand:DI 0 "register_operand" "")
4818 (match_operator:DI 1 "cc_arith_operator" ; AND, IOR, XOR
4819 [(match_operand:DI 2 "register_operand" "")
4820 (match_operand:DI 3 "arith_double_operand" "")]))]
4823 && ((GET_CODE (operands[0]) == REG
4824 && REGNO (operands[0]) < 32)
4825 || (GET_CODE (operands[0]) == SUBREG
4826 && GET_CODE (SUBREG_REG (operands[0])) == REG
4827 && REGNO (SUBREG_REG (operands[0])) < 32))"
4828 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4829 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4831 operands[4] = gen_highpart (SImode, operands[0]);
4832 operands[5] = gen_lowpart (SImode, operands[0]);
4833 operands[6] = gen_highpart (SImode, operands[2]);
4834 operands[7] = gen_lowpart (SImode, operands[2]);
4835 #if HOST_BITS_PER_WIDE_INT == 32
4836 if (GET_CODE (operands[3]) == CONST_INT)
4838 if (INTVAL (operands[3]) < 0)
4839 operands[8] = constm1_rtx;
4841 operands[8] = const0_rtx;
4845 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
4846 operands[9] = gen_lowpart (SImode, operands[3]);
4849 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4850 ;; Combine now canonicalizes to the rightmost expression.
4851 (define_insn_and_split "*xor_not_di_sp32"
4852 [(set (match_operand:DI 0 "register_operand" "=r")
4853 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
4854 (match_operand:DI 2 "register_operand" "r"))))]
4857 "&& reload_completed
4858 && ((GET_CODE (operands[0]) == REG
4859 && REGNO (operands[0]) < 32)
4860 || (GET_CODE (operands[0]) == SUBREG
4861 && GET_CODE (SUBREG_REG (operands[0])) == REG
4862 && REGNO (SUBREG_REG (operands[0])) < 32))"
4863 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4864 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4865 "operands[3] = gen_highpart (SImode, operands[0]);
4866 operands[4] = gen_highpart (SImode, operands[1]);
4867 operands[5] = gen_highpart (SImode, operands[2]);
4868 operands[6] = gen_lowpart (SImode, operands[0]);
4869 operands[7] = gen_lowpart (SImode, operands[1]);
4870 operands[8] = gen_lowpart (SImode, operands[2]);"
4871 [(set_attr "length" "2")])
4873 (define_insn "*xor_not_di_sp64"
4874 [(set (match_operand:DI 0 "register_operand" "=r")
4875 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4876 (match_operand:DI 2 "arith_operand" "rI"))))]
4878 "xnor\t%r1, %2, %0")
4880 (define_insn "*xor_not_si"
4881 [(set (match_operand:SI 0 "register_operand" "=r")
4882 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4883 (match_operand:SI 2 "arith_operand" "rI"))))]
4885 "xnor\t%r1, %2, %0")
4887 ;; These correspond to the above in the case where we also (or only)
4888 ;; want to set the condition code.
4890 (define_insn "*cmp_cc_arith_op"
4891 [(set (reg:CC CC_REG)
4893 (match_operator:SI 2 "cc_arith_operator"
4894 [(match_operand:SI 0 "arith_operand" "%r")
4895 (match_operand:SI 1 "arith_operand" "rI")])
4898 "%A2cc\t%0, %1, %%g0"
4899 [(set_attr "type" "compare")])
4901 (define_insn "*cmp_ccx_arith_op"
4902 [(set (reg:CCX CC_REG)
4904 (match_operator:DI 2 "cc_arith_operator"
4905 [(match_operand:DI 0 "arith_operand" "%r")
4906 (match_operand:DI 1 "arith_operand" "rI")])
4909 "%A2cc\t%0, %1, %%g0"
4910 [(set_attr "type" "compare")])
4912 (define_insn "*cmp_cc_arith_op_set"
4913 [(set (reg:CC CC_REG)
4915 (match_operator:SI 3 "cc_arith_operator"
4916 [(match_operand:SI 1 "arith_operand" "%r")
4917 (match_operand:SI 2 "arith_operand" "rI")])
4919 (set (match_operand:SI 0 "register_operand" "=r")
4920 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4921 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4923 [(set_attr "type" "compare")])
4925 (define_insn "*cmp_ccx_arith_op_set"
4926 [(set (reg:CCX CC_REG)
4928 (match_operator:DI 3 "cc_arith_operator"
4929 [(match_operand:DI 1 "arith_operand" "%r")
4930 (match_operand:DI 2 "arith_operand" "rI")])
4932 (set (match_operand:DI 0 "register_operand" "=r")
4933 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4934 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4936 [(set_attr "type" "compare")])
4938 (define_insn "*cmp_cc_xor_not"
4939 [(set (reg:CC CC_REG)
4941 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4942 (match_operand:SI 1 "arith_operand" "rI")))
4945 "xnorcc\t%r0, %1, %%g0"
4946 [(set_attr "type" "compare")])
4948 (define_insn "*cmp_ccx_xor_not"
4949 [(set (reg:CCX CC_REG)
4951 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4952 (match_operand:DI 1 "arith_operand" "rI")))
4955 "xnorcc\t%r0, %1, %%g0"
4956 [(set_attr "type" "compare")])
4958 (define_insn "*cmp_cc_xor_not_set"
4959 [(set (reg:CC CC_REG)
4961 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4962 (match_operand:SI 2 "arith_operand" "rI")))
4964 (set (match_operand:SI 0 "register_operand" "=r")
4965 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4967 "xnorcc\t%r1, %2, %0"
4968 [(set_attr "type" "compare")])
4970 (define_insn "*cmp_ccx_xor_not_set"
4971 [(set (reg:CCX CC_REG)
4973 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4974 (match_operand:DI 2 "arith_operand" "rI")))
4976 (set (match_operand:DI 0 "register_operand" "=r")
4977 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4979 "xnorcc\t%r1, %2, %0"
4980 [(set_attr "type" "compare")])
4982 (define_insn "*cmp_cc_arith_op_not"
4983 [(set (reg:CC CC_REG)
4985 (match_operator:SI 2 "cc_arith_not_operator"
4986 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4987 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
4990 "%B2cc\t%r1, %0, %%g0"
4991 [(set_attr "type" "compare")])
4993 (define_insn "*cmp_ccx_arith_op_not"
4994 [(set (reg:CCX CC_REG)
4996 (match_operator:DI 2 "cc_arith_not_operator"
4997 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
4998 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5001 "%B2cc\t%r1, %0, %%g0"
5002 [(set_attr "type" "compare")])
5004 (define_insn "*cmp_cc_arith_op_not_set"
5005 [(set (reg:CC CC_REG)
5007 (match_operator:SI 3 "cc_arith_not_operator"
5008 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5009 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5011 (set (match_operand:SI 0 "register_operand" "=r")
5012 (match_operator:SI 4 "cc_arith_not_operator"
5013 [(not:SI (match_dup 1)) (match_dup 2)]))]
5014 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5015 "%B3cc\t%r2, %1, %0"
5016 [(set_attr "type" "compare")])
5018 (define_insn "*cmp_ccx_arith_op_not_set"
5019 [(set (reg:CCX CC_REG)
5021 (match_operator:DI 3 "cc_arith_not_operator"
5022 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5023 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5025 (set (match_operand:DI 0 "register_operand" "=r")
5026 (match_operator:DI 4 "cc_arith_not_operator"
5027 [(not:DI (match_dup 1)) (match_dup 2)]))]
5028 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5029 "%B3cc\t%r2, %1, %0"
5030 [(set_attr "type" "compare")])
5032 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5033 ;; does not know how to make it work for constants.
5035 (define_expand "negdi2"
5036 [(set (match_operand:DI 0 "register_operand" "=r")
5037 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5040 if (! TARGET_ARCH64)
5042 emit_insn (gen_rtx_PARALLEL
5045 gen_rtx_SET (VOIDmode, operand0,
5046 gen_rtx_NEG (DImode, operand1)),
5047 gen_rtx_CLOBBER (VOIDmode,
5048 gen_rtx_REG (CCmode,
5054 (define_insn_and_split "*negdi2_sp32"
5055 [(set (match_operand:DI 0 "register_operand" "=r")
5056 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5057 (clobber (reg:CC CC_REG))]
5060 "&& reload_completed"
5061 [(parallel [(set (reg:CC_NOOV CC_REG)
5062 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5064 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5065 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5066 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5067 "operands[2] = gen_highpart (SImode, operands[0]);
5068 operands[3] = gen_highpart (SImode, operands[1]);
5069 operands[4] = gen_lowpart (SImode, operands[0]);
5070 operands[5] = gen_lowpart (SImode, operands[1]);"
5071 [(set_attr "length" "2")])
5073 (define_insn "*negdi2_sp64"
5074 [(set (match_operand:DI 0 "register_operand" "=r")
5075 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5077 "sub\t%%g0, %1, %0")
5079 (define_insn "negsi2"
5080 [(set (match_operand:SI 0 "register_operand" "=r")
5081 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5083 "sub\t%%g0, %1, %0")
5085 (define_insn "*cmp_cc_neg"
5086 [(set (reg:CC_NOOV CC_REG)
5087 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5090 "subcc\t%%g0, %0, %%g0"
5091 [(set_attr "type" "compare")])
5093 (define_insn "*cmp_ccx_neg"
5094 [(set (reg:CCX_NOOV CC_REG)
5095 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5098 "subcc\t%%g0, %0, %%g0"
5099 [(set_attr "type" "compare")])
5101 (define_insn "*cmp_cc_set_neg"
5102 [(set (reg:CC_NOOV CC_REG)
5103 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5105 (set (match_operand:SI 0 "register_operand" "=r")
5106 (neg:SI (match_dup 1)))]
5108 "subcc\t%%g0, %1, %0"
5109 [(set_attr "type" "compare")])
5111 (define_insn "*cmp_ccx_set_neg"
5112 [(set (reg:CCX_NOOV CC_REG)
5113 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5115 (set (match_operand:DI 0 "register_operand" "=r")
5116 (neg:DI (match_dup 1)))]
5118 "subcc\t%%g0, %1, %0"
5119 [(set_attr "type" "compare")])
5121 ;; We cannot use the "not" pseudo insn because the Sun assembler
5122 ;; does not know how to make it work for constants.
5123 (define_expand "one_cmpldi2"
5124 [(set (match_operand:DI 0 "register_operand" "")
5125 (not:DI (match_operand:DI 1 "register_operand" "")))]
5129 (define_insn_and_split "*one_cmpldi2_sp32"
5130 [(set (match_operand:DI 0 "register_operand" "=r")
5131 (not:DI (match_operand:DI 1 "register_operand" "r")))]
5134 "&& reload_completed
5135 && ((GET_CODE (operands[0]) == REG
5136 && REGNO (operands[0]) < 32)
5137 || (GET_CODE (operands[0]) == SUBREG
5138 && GET_CODE (SUBREG_REG (operands[0])) == REG
5139 && REGNO (SUBREG_REG (operands[0])) < 32))"
5140 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5141 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5142 "operands[2] = gen_highpart (SImode, operands[0]);
5143 operands[3] = gen_highpart (SImode, operands[1]);
5144 operands[4] = gen_lowpart (SImode, operands[0]);
5145 operands[5] = gen_lowpart (SImode, operands[1]);"
5146 [(set_attr "length" "2")])
5148 (define_insn "*one_cmpldi2_sp64"
5149 [(set (match_operand:DI 0 "register_operand" "=r")
5150 (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5152 "xnor\t%%g0, %1, %0")
5154 (define_insn "one_cmplsi2"
5155 [(set (match_operand:SI 0 "register_operand" "=r")
5156 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5158 "xnor\t%%g0, %1, %0")
5160 (define_insn "*cmp_cc_not"
5161 [(set (reg:CC CC_REG)
5162 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5165 "xnorcc\t%%g0, %0, %%g0"
5166 [(set_attr "type" "compare")])
5168 (define_insn "*cmp_ccx_not"
5169 [(set (reg:CCX CC_REG)
5170 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5173 "xnorcc\t%%g0, %0, %%g0"
5174 [(set_attr "type" "compare")])
5176 (define_insn "*cmp_cc_set_not"
5177 [(set (reg:CC CC_REG)
5178 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5180 (set (match_operand:SI 0 "register_operand" "=r")
5181 (not:SI (match_dup 1)))]
5183 "xnorcc\t%%g0, %1, %0"
5184 [(set_attr "type" "compare")])
5186 (define_insn "*cmp_ccx_set_not"
5187 [(set (reg:CCX CC_REG)
5188 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5190 (set (match_operand:DI 0 "register_operand" "=r")
5191 (not:DI (match_dup 1)))]
5193 "xnorcc\t%%g0, %1, %0"
5194 [(set_attr "type" "compare")])
5196 (define_insn "*cmp_cc_set"
5197 [(set (match_operand:SI 0 "register_operand" "=r")
5198 (match_operand:SI 1 "register_operand" "r"))
5199 (set (reg:CC CC_REG)
5200 (compare:CC (match_dup 1)
5204 [(set_attr "type" "compare")])
5206 (define_insn "*cmp_ccx_set64"
5207 [(set (match_operand:DI 0 "register_operand" "=r")
5208 (match_operand:DI 1 "register_operand" "r"))
5209 (set (reg:CCX CC_REG)
5210 (compare:CCX (match_dup 1)
5214 [(set_attr "type" "compare")])
5217 ;; Floating point arithmetic instructions.
5219 (define_expand "addtf3"
5220 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5221 (plus:TF (match_operand:TF 1 "general_operand" "")
5222 (match_operand:TF 2 "general_operand" "")))]
5223 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5224 "emit_tfmode_binop (PLUS, operands); DONE;")
5226 (define_insn "*addtf3_hq"
5227 [(set (match_operand:TF 0 "register_operand" "=e")
5228 (plus:TF (match_operand:TF 1 "register_operand" "e")
5229 (match_operand:TF 2 "register_operand" "e")))]
5230 "TARGET_FPU && TARGET_HARD_QUAD"
5232 [(set_attr "type" "fp")])
5234 (define_insn "adddf3"
5235 [(set (match_operand:DF 0 "register_operand" "=e")
5236 (plus:DF (match_operand:DF 1 "register_operand" "e")
5237 (match_operand:DF 2 "register_operand" "e")))]
5240 [(set_attr "type" "fp")
5241 (set_attr "fptype" "double")])
5243 (define_insn "addsf3"
5244 [(set (match_operand:SF 0 "register_operand" "=f")
5245 (plus:SF (match_operand:SF 1 "register_operand" "f")
5246 (match_operand:SF 2 "register_operand" "f")))]
5249 [(set_attr "type" "fp")])
5251 (define_expand "subtf3"
5252 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5253 (minus:TF (match_operand:TF 1 "general_operand" "")
5254 (match_operand:TF 2 "general_operand" "")))]
5255 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5256 "emit_tfmode_binop (MINUS, operands); DONE;")
5258 (define_insn "*subtf3_hq"
5259 [(set (match_operand:TF 0 "register_operand" "=e")
5260 (minus:TF (match_operand:TF 1 "register_operand" "e")
5261 (match_operand:TF 2 "register_operand" "e")))]
5262 "TARGET_FPU && TARGET_HARD_QUAD"
5264 [(set_attr "type" "fp")])
5266 (define_insn "subdf3"
5267 [(set (match_operand:DF 0 "register_operand" "=e")
5268 (minus:DF (match_operand:DF 1 "register_operand" "e")
5269 (match_operand:DF 2 "register_operand" "e")))]
5272 [(set_attr "type" "fp")
5273 (set_attr "fptype" "double")])
5275 (define_insn "subsf3"
5276 [(set (match_operand:SF 0 "register_operand" "=f")
5277 (minus:SF (match_operand:SF 1 "register_operand" "f")
5278 (match_operand:SF 2 "register_operand" "f")))]
5281 [(set_attr "type" "fp")])
5283 (define_expand "multf3"
5284 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5285 (mult:TF (match_operand:TF 1 "general_operand" "")
5286 (match_operand:TF 2 "general_operand" "")))]
5287 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5288 "emit_tfmode_binop (MULT, operands); DONE;")
5290 (define_insn "*multf3_hq"
5291 [(set (match_operand:TF 0 "register_operand" "=e")
5292 (mult:TF (match_operand:TF 1 "register_operand" "e")
5293 (match_operand:TF 2 "register_operand" "e")))]
5294 "TARGET_FPU && TARGET_HARD_QUAD"
5296 [(set_attr "type" "fpmul")])
5298 (define_insn "muldf3"
5299 [(set (match_operand:DF 0 "register_operand" "=e")
5300 (mult:DF (match_operand:DF 1 "register_operand" "e")
5301 (match_operand:DF 2 "register_operand" "e")))]
5304 [(set_attr "type" "fpmul")
5305 (set_attr "fptype" "double")])
5307 (define_insn "mulsf3"
5308 [(set (match_operand:SF 0 "register_operand" "=f")
5309 (mult:SF (match_operand:SF 1 "register_operand" "f")
5310 (match_operand:SF 2 "register_operand" "f")))]
5313 [(set_attr "type" "fpmul")])
5315 (define_insn "fmadf4"
5316 [(set (match_operand:DF 0 "register_operand" "=e")
5317 (fma:DF (match_operand:DF 1 "register_operand" "e")
5318 (match_operand:DF 2 "register_operand" "e")
5319 (match_operand:DF 3 "register_operand" "e")))]
5321 "fmaddd\t%1, %2, %3, %0"
5322 [(set_attr "type" "fpmul")])
5324 (define_insn "fmsdf4"
5325 [(set (match_operand:DF 0 "register_operand" "=e")
5326 (fma:DF (match_operand:DF 1 "register_operand" "e")
5327 (match_operand:DF 2 "register_operand" "e")
5328 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5330 "fmsubd\t%1, %2, %3, %0"
5331 [(set_attr "type" "fpmul")])
5333 (define_insn "*nfmadf4"
5334 [(set (match_operand:DF 0 "register_operand" "=e")
5335 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5336 (match_operand:DF 2 "register_operand" "e")
5337 (match_operand:DF 3 "register_operand" "e"))))]
5339 "fnmaddd\t%1, %2, %3, %0"
5340 [(set_attr "type" "fpmul")])
5342 (define_insn "*nfmsdf4"
5343 [(set (match_operand:DF 0 "register_operand" "=e")
5344 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5345 (match_operand:DF 2 "register_operand" "e")
5346 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5348 "fnmsubd\t%1, %2, %3, %0"
5349 [(set_attr "type" "fpmul")])
5351 (define_insn "fmasf4"
5352 [(set (match_operand:SF 0 "register_operand" "=f")
5353 (fma:SF (match_operand:SF 1 "register_operand" "f")
5354 (match_operand:SF 2 "register_operand" "f")
5355 (match_operand:SF 3 "register_operand" "f")))]
5357 "fmadds\t%1, %2, %3, %0"
5358 [(set_attr "type" "fpmul")])
5360 (define_insn "fmssf4"
5361 [(set (match_operand:SF 0 "register_operand" "=f")
5362 (fma:SF (match_operand:SF 1 "register_operand" "f")
5363 (match_operand:SF 2 "register_operand" "f")
5364 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5366 "fmsubs\t%1, %2, %3, %0"
5367 [(set_attr "type" "fpmul")])
5369 (define_insn "*nfmasf4"
5370 [(set (match_operand:SF 0 "register_operand" "=f")
5371 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5372 (match_operand:SF 2 "register_operand" "f")
5373 (match_operand:SF 3 "register_operand" "f"))))]
5375 "fnmadds\t%1, %2, %3, %0"
5376 [(set_attr "type" "fpmul")])
5378 (define_insn "*nfmssf4"
5379 [(set (match_operand:SF 0 "register_operand" "=f")
5380 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5381 (match_operand:SF 2 "register_operand" "f")
5382 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5384 "fnmsubs\t%1, %2, %3, %0"
5385 [(set_attr "type" "fpmul")])
5387 (define_insn "*muldf3_extend"
5388 [(set (match_operand:DF 0 "register_operand" "=e")
5389 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5390 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5391 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5392 "fsmuld\t%1, %2, %0"
5393 [(set_attr "type" "fpmul")
5394 (set_attr "fptype" "double")])
5396 (define_insn "*multf3_extend"
5397 [(set (match_operand:TF 0 "register_operand" "=e")
5398 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5399 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5400 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5401 "fdmulq\t%1, %2, %0"
5402 [(set_attr "type" "fpmul")])
5404 (define_expand "divtf3"
5405 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5406 (div:TF (match_operand:TF 1 "general_operand" "")
5407 (match_operand:TF 2 "general_operand" "")))]
5408 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5409 "emit_tfmode_binop (DIV, operands); DONE;")
5411 ;; don't have timing for quad-prec. divide.
5412 (define_insn "*divtf3_hq"
5413 [(set (match_operand:TF 0 "register_operand" "=e")
5414 (div:TF (match_operand:TF 1 "register_operand" "e")
5415 (match_operand:TF 2 "register_operand" "e")))]
5416 "TARGET_FPU && TARGET_HARD_QUAD"
5418 [(set_attr "type" "fpdivd")])
5420 (define_insn "divdf3"
5421 [(set (match_operand:DF 0 "register_operand" "=e")
5422 (div:DF (match_operand:DF 1 "register_operand" "e")
5423 (match_operand:DF 2 "register_operand" "e")))]
5426 [(set_attr "type" "fpdivd")
5427 (set_attr "fptype" "double")])
5429 (define_insn "divsf3"
5430 [(set (match_operand:SF 0 "register_operand" "=f")
5431 (div:SF (match_operand:SF 1 "register_operand" "f")
5432 (match_operand:SF 2 "register_operand" "f")))]
5435 [(set_attr "type" "fpdivs")])
5437 (define_expand "negtf2"
5438 [(set (match_operand:TF 0 "register_operand" "=e,e")
5439 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5443 (define_insn_and_split "*negtf2_notv9"
5444 [(set (match_operand:TF 0 "register_operand" "=e,e")
5445 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5446 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5452 "&& reload_completed
5453 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5454 [(set (match_dup 2) (neg:SF (match_dup 3)))
5455 (set (match_dup 4) (match_dup 5))
5456 (set (match_dup 6) (match_dup 7))]
5457 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5458 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5459 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5460 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5461 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5462 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5463 [(set_attr "type" "fpmove,*")
5464 (set_attr "length" "*,2")])
5466 (define_insn_and_split "*negtf2_v9"
5467 [(set (match_operand:TF 0 "register_operand" "=e,e")
5468 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5469 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5470 "TARGET_FPU && TARGET_V9"
5474 "&& reload_completed
5475 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5476 [(set (match_dup 2) (neg:DF (match_dup 3)))
5477 (set (match_dup 4) (match_dup 5))]
5478 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5479 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5480 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5481 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5482 [(set_attr "type" "fpmove,*")
5483 (set_attr "length" "*,2")
5484 (set_attr "fptype" "double")])
5486 (define_expand "negdf2"
5487 [(set (match_operand:DF 0 "register_operand" "")
5488 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5492 (define_insn_and_split "*negdf2_notv9"
5493 [(set (match_operand:DF 0 "register_operand" "=e,e")
5494 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5495 "TARGET_FPU && ! TARGET_V9"
5499 "&& reload_completed
5500 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5501 [(set (match_dup 2) (neg:SF (match_dup 3)))
5502 (set (match_dup 4) (match_dup 5))]
5503 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5504 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5505 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5506 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5507 [(set_attr "type" "fpmove,*")
5508 (set_attr "length" "*,2")])
5510 (define_insn "*negdf2_v9"
5511 [(set (match_operand:DF 0 "register_operand" "=e")
5512 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5513 "TARGET_FPU && TARGET_V9"
5515 [(set_attr "type" "fpmove")
5516 (set_attr "fptype" "double")])
5518 (define_insn "negsf2"
5519 [(set (match_operand:SF 0 "register_operand" "=f")
5520 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5523 [(set_attr "type" "fpmove")])
5525 (define_expand "abstf2"
5526 [(set (match_operand:TF 0 "register_operand" "")
5527 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5531 (define_insn_and_split "*abstf2_notv9"
5532 [(set (match_operand:TF 0 "register_operand" "=e,e")
5533 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5534 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5535 "TARGET_FPU && ! TARGET_V9"
5539 "&& reload_completed
5540 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5541 [(set (match_dup 2) (abs:SF (match_dup 3)))
5542 (set (match_dup 4) (match_dup 5))
5543 (set (match_dup 6) (match_dup 7))]
5544 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5545 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5546 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5547 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5548 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5549 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5550 [(set_attr "type" "fpmove,*")
5551 (set_attr "length" "*,2")])
5553 (define_insn "*abstf2_hq_v9"
5554 [(set (match_operand:TF 0 "register_operand" "=e,e")
5555 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5556 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5560 [(set_attr "type" "fpmove")
5561 (set_attr "fptype" "double,*")])
5563 (define_insn_and_split "*abstf2_v9"
5564 [(set (match_operand:TF 0 "register_operand" "=e,e")
5565 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5566 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5570 "&& reload_completed
5571 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5572 [(set (match_dup 2) (abs:DF (match_dup 3)))
5573 (set (match_dup 4) (match_dup 5))]
5574 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5575 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5576 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5577 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5578 [(set_attr "type" "fpmove,*")
5579 (set_attr "length" "*,2")
5580 (set_attr "fptype" "double,*")])
5582 (define_expand "absdf2"
5583 [(set (match_operand:DF 0 "register_operand" "")
5584 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5588 (define_insn_and_split "*absdf2_notv9"
5589 [(set (match_operand:DF 0 "register_operand" "=e,e")
5590 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5591 "TARGET_FPU && ! TARGET_V9"
5595 "&& reload_completed
5596 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5597 [(set (match_dup 2) (abs:SF (match_dup 3)))
5598 (set (match_dup 4) (match_dup 5))]
5599 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5600 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5601 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5602 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5603 [(set_attr "type" "fpmove,*")
5604 (set_attr "length" "*,2")])
5606 (define_insn "*absdf2_v9"
5607 [(set (match_operand:DF 0 "register_operand" "=e")
5608 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5609 "TARGET_FPU && TARGET_V9"
5611 [(set_attr "type" "fpmove")
5612 (set_attr "fptype" "double")])
5614 (define_insn "abssf2"
5615 [(set (match_operand:SF 0 "register_operand" "=f")
5616 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5619 [(set_attr "type" "fpmove")])
5621 (define_expand "sqrttf2"
5622 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5623 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5624 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5625 "emit_tfmode_unop (SQRT, operands); DONE;")
5627 (define_insn "*sqrttf2_hq"
5628 [(set (match_operand:TF 0 "register_operand" "=e")
5629 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5630 "TARGET_FPU && TARGET_HARD_QUAD"
5632 [(set_attr "type" "fpsqrtd")])
5634 (define_insn "sqrtdf2"
5635 [(set (match_operand:DF 0 "register_operand" "=e")
5636 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5639 [(set_attr "type" "fpsqrtd")
5640 (set_attr "fptype" "double")])
5642 (define_insn "sqrtsf2"
5643 [(set (match_operand:SF 0 "register_operand" "=f")
5644 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5647 [(set_attr "type" "fpsqrts")])
5650 ;; Arithmetic shift instructions.
5652 (define_insn "ashlsi3"
5653 [(set (match_operand:SI 0 "register_operand" "=r")
5654 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5655 (match_operand:SI 2 "arith_operand" "rI")))]
5658 if (GET_CODE (operands[2]) == CONST_INT)
5659 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5660 return "sll\t%1, %2, %0";
5662 [(set_attr "type" "shift")])
5664 (define_insn "*ashlsi3_extend"
5665 [(set (match_operand:DI 0 "register_operand" "=r")
5667 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5668 (match_operand:SI 2 "arith_operand" "rI"))))]
5671 if (GET_CODE (operands[2]) == CONST_INT)
5672 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5673 return "sll\t%1, %2, %0";
5675 [(set_attr "type" "shift")])
5677 (define_expand "ashldi3"
5678 [(set (match_operand:DI 0 "register_operand" "=r")
5679 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5680 (match_operand:SI 2 "arith_operand" "rI")))]
5681 "TARGET_ARCH64 || TARGET_V8PLUS"
5683 if (! TARGET_ARCH64)
5685 if (GET_CODE (operands[2]) == CONST_INT)
5687 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5692 (define_insn "*ashldi3_sp64"
5693 [(set (match_operand:DI 0 "register_operand" "=r")
5694 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5695 (match_operand:SI 2 "arith_operand" "rI")))]
5698 if (GET_CODE (operands[2]) == CONST_INT)
5699 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5700 return "sllx\t%1, %2, %0";
5702 [(set_attr "type" "shift")])
5705 (define_insn "ashldi3_v8plus"
5706 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5707 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5708 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5709 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5711 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5712 [(set_attr "type" "multi")
5713 (set_attr "length" "5,5,6")])
5715 ;; Optimize (1LL<<x)-1
5716 ;; XXX this also needs to be fixed to handle equal subregs
5717 ;; XXX first before we could re-enable it.
5719 ; [(set (match_operand:DI 0 "register_operand" "=h")
5720 ; (plus:DI (ashift:DI (const_int 1)
5721 ; (match_operand:SI 1 "arith_operand" "rI"))
5723 ; "0 && TARGET_V8PLUS"
5725 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5726 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5727 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5729 ; [(set_attr "type" "multi")
5730 ; (set_attr "length" "4")])
5732 (define_insn "*cmp_cc_ashift_1"
5733 [(set (reg:CC_NOOV CC_REG)
5734 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5738 "addcc\t%0, %0, %%g0"
5739 [(set_attr "type" "compare")])
5741 (define_insn "*cmp_cc_set_ashift_1"
5742 [(set (reg:CC_NOOV CC_REG)
5743 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5746 (set (match_operand:SI 0 "register_operand" "=r")
5747 (ashift:SI (match_dup 1) (const_int 1)))]
5750 [(set_attr "type" "compare")])
5752 (define_insn "ashrsi3"
5753 [(set (match_operand:SI 0 "register_operand" "=r")
5754 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5755 (match_operand:SI 2 "arith_operand" "rI")))]
5758 if (GET_CODE (operands[2]) == CONST_INT)
5759 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5760 return "sra\t%1, %2, %0";
5762 [(set_attr "type" "shift")])
5764 (define_insn "*ashrsi3_extend"
5765 [(set (match_operand:DI 0 "register_operand" "=r")
5766 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5767 (match_operand:SI 2 "arith_operand" "r"))))]
5770 [(set_attr "type" "shift")])
5772 ;; This handles the case as above, but with constant shift instead of
5773 ;; register. Combiner "simplifies" it for us a little bit though.
5774 (define_insn "*ashrsi3_extend2"
5775 [(set (match_operand:DI 0 "register_operand" "=r")
5776 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5778 (match_operand:SI 2 "small_int_operand" "I")))]
5779 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5781 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5782 return "sra\t%1, %2, %0";
5784 [(set_attr "type" "shift")])
5786 (define_expand "ashrdi3"
5787 [(set (match_operand:DI 0 "register_operand" "=r")
5788 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5789 (match_operand:SI 2 "arith_operand" "rI")))]
5790 "TARGET_ARCH64 || TARGET_V8PLUS"
5792 if (! TARGET_ARCH64)
5794 if (GET_CODE (operands[2]) == CONST_INT)
5795 FAIL; /* prefer generic code in this case */
5796 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5801 (define_insn "*ashrdi3_sp64"
5802 [(set (match_operand:DI 0 "register_operand" "=r")
5803 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5804 (match_operand:SI 2 "arith_operand" "rI")))]
5808 if (GET_CODE (operands[2]) == CONST_INT)
5809 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5810 return "srax\t%1, %2, %0";
5812 [(set_attr "type" "shift")])
5815 (define_insn "ashrdi3_v8plus"
5816 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5817 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5818 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5819 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5821 "* return output_v8plus_shift (operands, insn, \"srax\");"
5822 [(set_attr "type" "multi")
5823 (set_attr "length" "5,5,6")])
5825 (define_insn "lshrsi3"
5826 [(set (match_operand:SI 0 "register_operand" "=r")
5827 (lshiftrt:SI (match_operand:SI 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]) & 0x1f);
5833 return "srl\t%1, %2, %0";
5835 [(set_attr "type" "shift")])
5837 (define_insn "*lshrsi3_extend0"
5838 [(set (match_operand:DI 0 "register_operand" "=r")
5840 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5841 (match_operand:SI 2 "arith_operand" "rI"))))]
5844 if (GET_CODE (operands[2]) == CONST_INT)
5845 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5846 return "srl\t%1, %2, %0";
5848 [(set_attr "type" "shift")])
5850 ;; This handles the case where
5851 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5852 ;; but combiner "simplifies" it for us.
5853 (define_insn "*lshrsi3_extend1"
5854 [(set (match_operand:DI 0 "register_operand" "=r")
5855 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5856 (match_operand:SI 2 "arith_operand" "r")) 0)
5857 (match_operand 3 "const_int_operand" "")))]
5858 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5860 [(set_attr "type" "shift")])
5862 ;; This handles the case where
5863 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5864 ;; but combiner "simplifies" it for us.
5865 (define_insn "*lshrsi3_extend2"
5866 [(set (match_operand:DI 0 "register_operand" "=r")
5867 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5868 (match_operand 2 "small_int_operand" "I")
5870 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5872 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5873 return "srl\t%1, %2, %0";
5875 [(set_attr "type" "shift")])
5877 (define_expand "lshrdi3"
5878 [(set (match_operand:DI 0 "register_operand" "=r")
5879 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5880 (match_operand:SI 2 "arith_operand" "rI")))]
5881 "TARGET_ARCH64 || TARGET_V8PLUS"
5883 if (! TARGET_ARCH64)
5885 if (GET_CODE (operands[2]) == CONST_INT)
5887 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5892 (define_insn "*lshrdi3_sp64"
5893 [(set (match_operand:DI 0 "register_operand" "=r")
5894 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5895 (match_operand:SI 2 "arith_operand" "rI")))]
5898 if (GET_CODE (operands[2]) == CONST_INT)
5899 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5900 return "srlx\t%1, %2, %0";
5902 [(set_attr "type" "shift")])
5905 (define_insn "lshrdi3_v8plus"
5906 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5907 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5908 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5909 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5911 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5912 [(set_attr "type" "multi")
5913 (set_attr "length" "5,5,6")])
5916 [(set (match_operand:SI 0 "register_operand" "=r")
5917 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5919 (match_operand:SI 2 "small_int_operand" "I")))]
5920 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5922 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5923 return "srax\t%1, %2, %0";
5925 [(set_attr "type" "shift")])
5928 [(set (match_operand:SI 0 "register_operand" "=r")
5929 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5931 (match_operand:SI 2 "small_int_operand" "I")))]
5932 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5934 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5935 return "srlx\t%1, %2, %0";
5937 [(set_attr "type" "shift")])
5940 [(set (match_operand:SI 0 "register_operand" "=r")
5941 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5942 (match_operand:SI 2 "small_int_operand" "I")) 4)
5943 (match_operand:SI 3 "small_int_operand" "I")))]
5945 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5946 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5947 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5949 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5951 return "srax\t%1, %2, %0";
5953 [(set_attr "type" "shift")])
5956 [(set (match_operand:SI 0 "register_operand" "=r")
5957 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5958 (match_operand:SI 2 "small_int_operand" "I")) 4)
5959 (match_operand:SI 3 "small_int_operand" "I")))]
5961 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5962 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5963 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5965 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5967 return "srlx\t%1, %2, %0";
5969 [(set_attr "type" "shift")])
5972 ;; Unconditional and other jump instructions.
5975 [(set (pc) (label_ref (match_operand 0 "" "")))]
5977 "* return output_ubranch (operands[0], 0, insn);"
5978 [(set_attr "type" "uncond_branch")])
5980 (define_expand "tablejump"
5981 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5982 (use (label_ref (match_operand 1 "" "")))])]
5985 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5987 /* In pic mode, our address differences are against the base of the
5988 table. Add that base value back in; CSE ought to be able to combine
5989 the two address loads. */
5993 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5995 if (CASE_VECTOR_MODE != Pmode)
5996 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5997 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5998 operands[0] = memory_address (Pmode, tmp);
6002 (define_insn "*tablejump_sp32"
6003 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6004 (use (label_ref (match_operand 1 "" "")))]
6007 [(set_attr "type" "uncond_branch")])
6009 (define_insn "*tablejump_sp64"
6010 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6011 (use (label_ref (match_operand 1 "" "")))]
6014 [(set_attr "type" "uncond_branch")])
6017 ;; Jump to subroutine instructions.
6019 (define_expand "call"
6020 ;; Note that this expression is not used for generating RTL.
6021 ;; All the RTL is generated explicitly below.
6022 [(call (match_operand 0 "call_operand" "")
6023 (match_operand 3 "" "i"))]
6024 ;; operands[2] is next_arg_register
6025 ;; operands[3] is struct_value_size_rtx.
6030 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6032 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6034 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6036 /* This is really a PIC sequence. We want to represent
6037 it as a funny jump so its delay slots can be filled.
6039 ??? But if this really *is* a CALL, will not it clobber the
6040 call-clobbered registers? We lose this if it is a JUMP_INSN.
6041 Why cannot we have delay slots filled if it were a CALL? */
6043 /* We accept negative sizes for untyped calls. */
6044 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6049 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6051 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6057 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6058 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6062 fn_rtx = operands[0];
6064 /* We accept negative sizes for untyped calls. */
6065 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6066 sparc_emit_call_insn
6069 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6071 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6074 sparc_emit_call_insn
6077 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6078 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6086 ;; We can't use the same pattern for these two insns, because then registers
6087 ;; in the address may not be properly reloaded.
6089 (define_insn "*call_address_sp32"
6090 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6091 (match_operand 1 "" ""))
6092 (clobber (reg:SI O7_REG))]
6093 ;;- Do not use operand 1 for most machines.
6096 [(set_attr "type" "call")])
6098 (define_insn "*call_symbolic_sp32"
6099 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6100 (match_operand 1 "" ""))
6101 (clobber (reg:SI O7_REG))]
6102 ;;- Do not use operand 1 for most machines.
6105 [(set_attr "type" "call")])
6107 (define_insn "*call_address_sp64"
6108 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6109 (match_operand 1 "" ""))
6110 (clobber (reg:DI O7_REG))]
6111 ;;- Do not use operand 1 for most machines.
6114 [(set_attr "type" "call")])
6116 (define_insn "*call_symbolic_sp64"
6117 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6118 (match_operand 1 "" ""))
6119 (clobber (reg:DI O7_REG))]
6120 ;;- Do not use operand 1 for most machines.
6123 [(set_attr "type" "call")])
6125 ;; This is a call that wants a structure value.
6126 ;; There is no such critter for v9 (??? we may need one anyway).
6127 (define_insn "*call_address_struct_value_sp32"
6128 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6129 (match_operand 1 "" ""))
6130 (match_operand 2 "immediate_operand" "")
6131 (clobber (reg:SI O7_REG))]
6132 ;;- Do not use operand 1 for most machines.
6133 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6135 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6136 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6138 [(set_attr "type" "call_no_delay_slot")
6139 (set_attr "length" "3")])
6141 ;; This is a call that wants a structure value.
6142 ;; There is no such critter for v9 (??? we may need one anyway).
6143 (define_insn "*call_symbolic_struct_value_sp32"
6144 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6145 (match_operand 1 "" ""))
6146 (match_operand 2 "immediate_operand" "")
6147 (clobber (reg:SI O7_REG))]
6148 ;;- Do not use operand 1 for most machines.
6149 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6151 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6152 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6154 [(set_attr "type" "call_no_delay_slot")
6155 (set_attr "length" "3")])
6157 ;; This is a call that may want a structure value. This is used for
6159 (define_insn "*call_address_untyped_struct_value_sp32"
6160 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6161 (match_operand 1 "" ""))
6162 (match_operand 2 "immediate_operand" "")
6163 (clobber (reg:SI O7_REG))]
6164 ;;- Do not use operand 1 for most machines.
6165 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6166 "call\t%a0, %1\n\t nop\n\tnop"
6167 [(set_attr "type" "call_no_delay_slot")
6168 (set_attr "length" "3")])
6170 ;; This is a call that may want a structure value. This is used for
6172 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6173 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6174 (match_operand 1 "" ""))
6175 (match_operand 2 "immediate_operand" "")
6176 (clobber (reg:SI O7_REG))]
6177 ;;- Do not use operand 1 for most machines.
6178 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6179 "call\t%a0, %1\n\t nop\n\tnop"
6180 [(set_attr "type" "call_no_delay_slot")
6181 (set_attr "length" "3")])
6183 (define_expand "call_value"
6184 ;; Note that this expression is not used for generating RTL.
6185 ;; All the RTL is generated explicitly below.
6186 [(set (match_operand 0 "register_operand" "=rf")
6187 (call (match_operand 1 "" "")
6188 (match_operand 4 "" "")))]
6189 ;; operand 2 is stack_size_rtx
6190 ;; operand 3 is next_arg_register
6196 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6198 fn_rtx = operands[1];
6201 gen_rtx_SET (VOIDmode, operands[0],
6202 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6203 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6205 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6210 (define_insn "*call_value_address_sp32"
6211 [(set (match_operand 0 "" "=rf")
6212 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6213 (match_operand 2 "" "")))
6214 (clobber (reg:SI O7_REG))]
6215 ;;- Do not use operand 2 for most machines.
6218 [(set_attr "type" "call")])
6220 (define_insn "*call_value_symbolic_sp32"
6221 [(set (match_operand 0 "" "=rf")
6222 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6223 (match_operand 2 "" "")))
6224 (clobber (reg:SI O7_REG))]
6225 ;;- Do not use operand 2 for most machines.
6228 [(set_attr "type" "call")])
6230 (define_insn "*call_value_address_sp64"
6231 [(set (match_operand 0 "" "")
6232 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6233 (match_operand 2 "" "")))
6234 (clobber (reg:DI O7_REG))]
6235 ;;- Do not use operand 2 for most machines.
6238 [(set_attr "type" "call")])
6240 (define_insn "*call_value_symbolic_sp64"
6241 [(set (match_operand 0 "" "")
6242 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6243 (match_operand 2 "" "")))
6244 (clobber (reg:DI O7_REG))]
6245 ;;- Do not use operand 2 for most machines.
6248 [(set_attr "type" "call")])
6250 (define_expand "untyped_call"
6251 [(parallel [(call (match_operand 0 "" "")
6253 (match_operand:BLK 1 "memory_operand" "")
6254 (match_operand 2 "" "")])]
6257 rtx valreg1 = gen_rtx_REG (DImode, 8);
6258 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6259 rtx result = operands[1];
6261 /* Pass constm1 to indicate that it may expect a structure value, but
6262 we don't know what size it is. */
6263 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6265 /* Save the function value registers. */
6266 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6267 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6270 /* The optimizer does not know that the call sets the function value
6271 registers we stored in the result block. We avoid problems by
6272 claiming that all hard registers are used and clobbered at this
6274 emit_insn (gen_blockage ());
6279 ;; Tail call instructions.
6281 (define_expand "sibcall"
6282 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6287 (define_insn "*sibcall_symbolic_sp32"
6288 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6289 (match_operand 1 "" ""))
6292 "* return output_sibcall(insn, operands[0]);"
6293 [(set_attr "type" "sibcall")])
6295 (define_insn "*sibcall_symbolic_sp64"
6296 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6297 (match_operand 1 "" ""))
6300 "* return output_sibcall(insn, operands[0]);"
6301 [(set_attr "type" "sibcall")])
6303 (define_expand "sibcall_value"
6304 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6305 (call (match_operand 1 "" "") (const_int 0)))
6310 (define_insn "*sibcall_value_symbolic_sp32"
6311 [(set (match_operand 0 "" "=rf")
6312 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6313 (match_operand 2 "" "")))
6316 "* return output_sibcall(insn, operands[1]);"
6317 [(set_attr "type" "sibcall")])
6319 (define_insn "*sibcall_value_symbolic_sp64"
6320 [(set (match_operand 0 "" "")
6321 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6322 (match_operand 2 "" "")))
6325 "* return output_sibcall(insn, operands[1]);"
6326 [(set_attr "type" "sibcall")])
6329 ;; Special instructions.
6331 (define_expand "prologue"
6336 sparc_flat_expand_prologue ();
6338 sparc_expand_prologue ();
6342 ;; The "register window save" insn is modelled as follows. The dwarf2
6343 ;; information is manually added in emit_window_save.
6345 (define_insn "window_save"
6347 [(match_operand 0 "arith_operand" "rI")]
6350 "save\t%%sp, %0, %%sp"
6351 [(set_attr "type" "savew")])
6353 (define_expand "epilogue"
6358 sparc_flat_expand_epilogue (false);
6360 sparc_expand_epilogue (false);
6363 (define_expand "sibcall_epilogue"
6368 sparc_flat_expand_epilogue (false);
6370 sparc_expand_epilogue (false);
6374 (define_expand "eh_return"
6375 [(use (match_operand 0 "general_operand" ""))]
6378 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6379 emit_jump_insn (gen_eh_return_internal ());
6384 (define_insn_and_split "eh_return_internal"
6388 "epilogue_completed"
6392 sparc_flat_expand_epilogue (true);
6394 sparc_expand_epilogue (true);
6397 (define_expand "return"
6399 "sparc_can_use_return_insn_p ()"
6402 (define_insn "*return_internal"
6405 "* return output_return (insn);"
6406 [(set_attr "type" "return")
6407 (set (attr "length")
6408 (cond [(eq_attr "calls_eh_return" "true")
6409 (if_then_else (eq_attr "delayed_branch" "true")
6410 (if_then_else (ior (eq_attr "isa" "v9")
6411 (eq_attr "flat" "true"))
6414 (if_then_else (eq_attr "flat" "true")
6417 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6418 (if_then_else (eq_attr "empty_delay_slot" "true")
6421 (eq_attr "empty_delay_slot" "true")
6422 (if_then_else (eq_attr "delayed_branch" "true")
6427 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6428 ;; all of memory. This blocks insns from being moved across this point.
6430 (define_insn "blockage"
6431 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6434 [(set_attr "length" "0")])
6436 (define_expand "probe_stack"
6437 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6441 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6444 (define_insn "probe_stack_range<P:mode>"
6445 [(set (match_operand:P 0 "register_operand" "=r")
6446 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6447 (match_operand:P 2 "register_operand" "r")]
6448 UNSPECV_PROBE_STACK_RANGE))]
6450 "* return output_probe_stack_range (operands[0], operands[2]);"
6451 [(set_attr "type" "multi")])
6453 ;; Prepare to return any type including a structure value.
6455 (define_expand "untyped_return"
6456 [(match_operand:BLK 0 "memory_operand" "")
6457 (match_operand 1 "" "")]
6460 rtx valreg1 = gen_rtx_REG (DImode, 24);
6461 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6462 rtx result = operands[0];
6464 if (! TARGET_ARCH64)
6466 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6467 rtx value = gen_reg_rtx (SImode);
6469 /* Fetch the instruction where we will return to and see if it's an unimp
6470 instruction (the most significant 10 bits will be zero). If so,
6471 update the return address to skip the unimp instruction. */
6472 emit_move_insn (value,
6473 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6474 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6475 emit_insn (gen_update_return (rtnreg, value));
6478 /* Reload the function value registers. */
6479 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6480 emit_move_insn (valreg2,
6481 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6483 /* Put USE insns before the return. */
6487 /* Construct the return. */
6488 expand_naked_return ();
6493 ;; Adjust the return address conditionally. If the value of op1 is equal
6494 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6495 ;; This is technically *half* the check required by the 32-bit SPARC
6496 ;; psABI. This check only ensures that an "unimp" insn was written by
6497 ;; the caller, but doesn't check to see if the expected size matches
6498 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6499 ;; only used by the above code "untyped_return".
6501 (define_insn "update_return"
6502 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6503 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6506 if (flag_delayed_branch)
6507 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6509 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6511 [(set (attr "type") (const_string "multi"))
6512 (set (attr "length")
6513 (if_then_else (eq_attr "delayed_branch" "true")
6522 (define_expand "indirect_jump"
6523 [(set (pc) (match_operand 0 "address_operand" "p"))]
6527 (define_insn "*branch_sp32"
6528 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6531 [(set_attr "type" "uncond_branch")])
6533 (define_insn "*branch_sp64"
6534 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6537 [(set_attr "type" "uncond_branch")])
6539 (define_expand "save_stack_nonlocal"
6540 [(set (match_operand 0 "memory_operand" "")
6541 (match_operand 1 "register_operand" ""))
6542 (set (match_dup 2) (match_dup 3))]
6545 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6546 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6547 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6550 (define_expand "restore_stack_nonlocal"
6551 [(set (match_operand 0 "register_operand" "")
6552 (match_operand 1 "memory_operand" ""))]
6555 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6558 (define_expand "nonlocal_goto"
6559 [(match_operand 0 "general_operand" "")
6560 (match_operand 1 "general_operand" "")
6561 (match_operand 2 "memory_operand" "")
6562 (match_operand 3 "memory_operand" "")]
6565 rtx r_label = copy_to_reg (operands[1]);
6566 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6567 rtx r_fp = operands[3];
6568 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6570 /* We need to flush all the register windows so that their contents will
6571 be re-synchronized by the restore insn of the target function. */
6573 emit_insn (gen_flush_register_windows ());
6575 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6576 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6578 /* Restore frame pointer for containing function. */
6579 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6580 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6582 /* USE of hard_frame_pointer_rtx added for consistency;
6583 not clear if really needed. */
6584 emit_use (hard_frame_pointer_rtx);
6585 emit_use (stack_pointer_rtx);
6587 /* We need to smuggle the load of %i7 as it is a fixed register. */
6588 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6593 (define_insn "nonlocal_goto_internal"
6594 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6595 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6596 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6598 if (flag_delayed_branch)
6601 return "jmp\t%0\n\t ldx\t%1, %%i7";
6603 return "jmp\t%0\n\t ld\t%1, %%i7";
6608 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6610 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6613 [(set (attr "type") (const_string "multi"))
6614 (set (attr "length")
6615 (if_then_else (eq_attr "delayed_branch" "true")
6619 (define_expand "builtin_setjmp_receiver"
6620 [(label_ref (match_operand 0 "" ""))]
6623 load_got_register ();
6627 ;; Special insn to flush register windows.
6629 (define_insn "flush_register_windows"
6630 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6632 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6633 [(set_attr "type" "flushw")])
6635 ;; Special pattern for the FLUSH instruction.
6637 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6638 ; of the define_insn otherwise missing a mode. We make "flush", aka
6639 ; gen_flush, the default one since sparc_initialize_trampoline uses
6640 ; it on SImode mem values.
6642 (define_insn "flush"
6643 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6645 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6646 [(set_attr "type" "iflush")])
6648 (define_insn "flushdi"
6649 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6651 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6652 [(set_attr "type" "iflush")])
6655 ;; Find first set instructions.
6657 ;; The scan instruction searches from the most significant bit while ffs
6658 ;; searches from the least significant bit. The bit index and treatment of
6659 ;; zero also differ. It takes at least 7 instructions to get the proper
6660 ;; result. Here is an obvious 8 instruction sequence.
6663 (define_insn "ffssi2"
6664 [(set (match_operand:SI 0 "register_operand" "=&r")
6665 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6666 (clobber (match_scratch:SI 2 "=&r"))]
6667 "TARGET_SPARCLITE || TARGET_SPARCLET"
6669 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";
6671 [(set_attr "type" "multi")
6672 (set_attr "length" "8")])
6674 (define_expand "popcountdi2"
6675 [(set (match_operand:DI 0 "register_operand" "")
6676 (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6679 if (! TARGET_ARCH64)
6681 emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6686 (define_insn "*popcountdi_sp64"
6687 [(set (match_operand:DI 0 "register_operand" "=r")
6688 (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6689 "TARGET_POPC && TARGET_ARCH64"
6692 (define_insn "popcountdi_v8plus"
6693 [(set (match_operand:DI 0 "register_operand" "=r")
6694 (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6695 (clobber (match_scratch:SI 2 "=&h"))]
6696 "TARGET_POPC && ! TARGET_ARCH64"
6698 if (sparc_check_64 (operands[1], insn) <= 0)
6699 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6700 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6702 [(set_attr "type" "multi")
6703 (set_attr "length" "5")])
6705 (define_expand "popcountsi2"
6707 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6708 (set (match_operand:SI 0 "register_operand" "")
6709 (truncate:SI (popcount:DI (match_dup 2))))]
6712 if (! TARGET_ARCH64)
6714 emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6718 operands[2] = gen_reg_rtx (DImode);
6721 (define_insn "*popcountsi_sp64"
6722 [(set (match_operand:SI 0 "register_operand" "=r")
6724 (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6725 "TARGET_POPC && TARGET_ARCH64"
6728 (define_insn "popcountsi_v8plus"
6729 [(set (match_operand:SI 0 "register_operand" "=r")
6730 (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6731 "TARGET_POPC && ! TARGET_ARCH64"
6733 if (sparc_check_64 (operands[1], insn) <= 0)
6734 output_asm_insn ("srl\t%1, 0, %1", operands);
6735 return "popc\t%1, %0";
6737 [(set_attr "type" "multi")
6738 (set_attr "length" "2")])
6740 (define_expand "clzdi2"
6741 [(set (match_operand:DI 0 "register_operand" "")
6742 (clz:DI (match_operand:DI 1 "register_operand" "")))]
6745 if (! TARGET_ARCH64)
6747 emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6752 (define_insn "*clzdi_sp64"
6753 [(set (match_operand:DI 0 "register_operand" "=r")
6754 (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6755 "TARGET_VIS3 && TARGET_ARCH64"
6758 (define_insn "clzdi_v8plus"
6759 [(set (match_operand:DI 0 "register_operand" "=r")
6760 (clz:DI (match_operand:DI 1 "register_operand" "r")))
6761 (clobber (match_scratch:SI 2 "=&h"))]
6762 "TARGET_VIS3 && ! TARGET_ARCH64"
6764 if (sparc_check_64 (operands[1], insn) <= 0)
6765 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6766 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6768 [(set_attr "type" "multi")
6769 (set_attr "length" "5")])
6771 (define_expand "clzsi2"
6773 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6775 (truncate:SI (clz:DI (match_dup 2))))
6776 (set (match_operand:SI 0 "register_operand" "")
6777 (minus:SI (match_dup 3) (const_int 32)))]
6780 if (! TARGET_ARCH64)
6782 emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6787 operands[2] = gen_reg_rtx (DImode);
6788 operands[3] = gen_reg_rtx (SImode);
6792 (define_insn "*clzsi_sp64"
6793 [(set (match_operand:SI 0 "register_operand" "=r")
6795 (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6796 "TARGET_VIS3 && TARGET_ARCH64"
6799 (define_insn "clzsi_v8plus"
6800 [(set (match_operand:SI 0 "register_operand" "=r")
6801 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6802 "TARGET_VIS3 && ! TARGET_ARCH64"
6804 if (sparc_check_64 (operands[1], insn) <= 0)
6805 output_asm_insn ("srl\t%1, 0, %1", operands);
6806 return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6808 [(set_attr "type" "multi")
6809 (set_attr "length" "3")])
6812 ;; Peepholes go at the end.
6814 ;; Optimize consecutive loads or stores into ldd and std when possible.
6815 ;; The conditions in which we do this are very restricted and are
6816 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6819 [(set (match_operand:SI 0 "memory_operand" "")
6821 (set (match_operand:SI 1 "memory_operand" "")
6824 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6827 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6830 [(set (match_operand:SI 0 "memory_operand" "")
6832 (set (match_operand:SI 1 "memory_operand" "")
6835 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6838 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6841 [(set (match_operand:SI 0 "register_operand" "")
6842 (match_operand:SI 1 "memory_operand" ""))
6843 (set (match_operand:SI 2 "register_operand" "")
6844 (match_operand:SI 3 "memory_operand" ""))]
6845 "registers_ok_for_ldd_peep (operands[0], operands[2])
6846 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6849 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6850 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6853 [(set (match_operand:SI 0 "memory_operand" "")
6854 (match_operand:SI 1 "register_operand" ""))
6855 (set (match_operand:SI 2 "memory_operand" "")
6856 (match_operand:SI 3 "register_operand" ""))]
6857 "registers_ok_for_ldd_peep (operands[1], operands[3])
6858 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6861 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6862 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6865 [(set (match_operand:SF 0 "register_operand" "")
6866 (match_operand:SF 1 "memory_operand" ""))
6867 (set (match_operand:SF 2 "register_operand" "")
6868 (match_operand:SF 3 "memory_operand" ""))]
6869 "registers_ok_for_ldd_peep (operands[0], operands[2])
6870 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6873 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6874 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6877 [(set (match_operand:SF 0 "memory_operand" "")
6878 (match_operand:SF 1 "register_operand" ""))
6879 (set (match_operand:SF 2 "memory_operand" "")
6880 (match_operand:SF 3 "register_operand" ""))]
6881 "registers_ok_for_ldd_peep (operands[1], operands[3])
6882 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6885 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6886 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6889 [(set (match_operand:SI 0 "register_operand" "")
6890 (match_operand:SI 1 "memory_operand" ""))
6891 (set (match_operand:SI 2 "register_operand" "")
6892 (match_operand:SI 3 "memory_operand" ""))]
6893 "registers_ok_for_ldd_peep (operands[2], operands[0])
6894 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6897 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6898 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6901 [(set (match_operand:SI 0 "memory_operand" "")
6902 (match_operand:SI 1 "register_operand" ""))
6903 (set (match_operand:SI 2 "memory_operand" "")
6904 (match_operand:SI 3 "register_operand" ""))]
6905 "registers_ok_for_ldd_peep (operands[3], operands[1])
6906 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6909 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6910 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6914 [(set (match_operand:SF 0 "register_operand" "")
6915 (match_operand:SF 1 "memory_operand" ""))
6916 (set (match_operand:SF 2 "register_operand" "")
6917 (match_operand:SF 3 "memory_operand" ""))]
6918 "registers_ok_for_ldd_peep (operands[2], operands[0])
6919 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6922 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6923 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6926 [(set (match_operand:SF 0 "memory_operand" "")
6927 (match_operand:SF 1 "register_operand" ""))
6928 (set (match_operand:SF 2 "memory_operand" "")
6929 (match_operand:SF 3 "register_operand" ""))]
6930 "registers_ok_for_ldd_peep (operands[3], operands[1])
6931 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6934 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6935 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6937 ;; Optimize the case of following a reg-reg move with a test
6938 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6939 ;; This can result from a float to fix conversion.
6942 [(set (match_operand:SI 0 "register_operand" "")
6943 (match_operand:SI 1 "register_operand" ""))
6944 (set (reg:CC CC_REG)
6945 (compare:CC (match_operand:SI 2 "register_operand" "")
6947 "(rtx_equal_p (operands[2], operands[0])
6948 || rtx_equal_p (operands[2], operands[1]))
6949 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6950 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6951 [(parallel [(set (match_dup 0) (match_dup 1))
6952 (set (reg:CC CC_REG)
6953 (compare:CC (match_dup 1) (const_int 0)))])]
6957 [(set (match_operand:DI 0 "register_operand" "")
6958 (match_operand:DI 1 "register_operand" ""))
6959 (set (reg:CCX CC_REG)
6960 (compare:CCX (match_operand:DI 2 "register_operand" "")
6963 && (rtx_equal_p (operands[2], operands[0])
6964 || rtx_equal_p (operands[2], operands[1]))
6965 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6966 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6967 [(parallel [(set (match_dup 0) (match_dup 1))
6968 (set (reg:CCX CC_REG)
6969 (compare:CCX (match_dup 1) (const_int 0)))])]
6973 ;; Prefetch instructions.
6975 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6976 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6977 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6979 (define_expand "prefetch"
6980 [(match_operand 0 "address_operand" "")
6981 (match_operand 1 "const_int_operand" "")
6982 (match_operand 2 "const_int_operand" "")]
6986 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6988 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6992 (define_insn "prefetch_64"
6993 [(prefetch (match_operand:DI 0 "address_operand" "p")
6994 (match_operand:DI 1 "const_int_operand" "n")
6995 (match_operand:DI 2 "const_int_operand" "n"))]
6998 static const char * const prefetch_instr[2][2] = {
7000 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7001 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7004 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7005 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7008 int read_or_write = INTVAL (operands[1]);
7009 int locality = INTVAL (operands[2]);
7011 gcc_assert (read_or_write == 0 || read_or_write == 1);
7012 gcc_assert (locality >= 0 && locality < 4);
7013 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7015 [(set_attr "type" "load")])
7017 (define_insn "prefetch_32"
7018 [(prefetch (match_operand:SI 0 "address_operand" "p")
7019 (match_operand:SI 1 "const_int_operand" "n")
7020 (match_operand:SI 2 "const_int_operand" "n"))]
7023 static const char * const prefetch_instr[2][2] = {
7025 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7026 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7029 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7030 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7033 int read_or_write = INTVAL (operands[1]);
7034 int locality = INTVAL (operands[2]);
7036 gcc_assert (read_or_write == 0 || read_or_write == 1);
7037 gcc_assert (locality >= 0 && locality < 4);
7038 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7040 [(set_attr "type" "load")])
7043 ;; Trap instructions.
7046 [(trap_if (const_int 1) (const_int 5))]
7049 [(set_attr "type" "trap")])
7051 (define_expand "ctrapsi4"
7052 [(trap_if (match_operator 0 "noov_compare_operator"
7053 [(match_operand:SI 1 "compare_operand" "")
7054 (match_operand:SI 2 "arith_operand" "")])
7055 (match_operand 3 ""))]
7057 "operands[1] = gen_compare_reg (operands[0]);
7058 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7060 operands[2] = const0_rtx;")
7062 (define_expand "ctrapdi4"
7063 [(trap_if (match_operator 0 "noov_compare_operator"
7064 [(match_operand:DI 1 "compare_operand" "")
7065 (match_operand:DI 2 "arith_operand" "")])
7066 (match_operand 3 ""))]
7068 "operands[1] = gen_compare_reg (operands[0]);
7069 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7071 operands[2] = const0_rtx;")
7075 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7076 (match_operand:SI 1 "arith_operand" "rM"))]
7080 return "t%C0\t%%icc, %1";
7084 [(set_attr "type" "trap")])
7087 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7088 (match_operand:SI 1 "arith_operand" "rM"))]
7091 [(set_attr "type" "trap")])
7094 ;; TLS support instructions.
7096 (define_insn "tgd_hi22"
7097 [(set (match_operand:SI 0 "register_operand" "=r")
7098 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7101 "sethi\\t%%tgd_hi22(%a1), %0")
7103 (define_insn "tgd_lo10"
7104 [(set (match_operand:SI 0 "register_operand" "=r")
7105 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7106 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7109 "add\\t%1, %%tgd_lo10(%a2), %0")
7111 (define_insn "tgd_add32"
7112 [(set (match_operand:SI 0 "register_operand" "=r")
7113 (plus:SI (match_operand:SI 1 "register_operand" "r")
7114 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7115 (match_operand 3 "tgd_symbolic_operand" "")]
7117 "TARGET_TLS && TARGET_ARCH32"
7118 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7120 (define_insn "tgd_add64"
7121 [(set (match_operand:DI 0 "register_operand" "=r")
7122 (plus:DI (match_operand:DI 1 "register_operand" "r")
7123 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7124 (match_operand 3 "tgd_symbolic_operand" "")]
7126 "TARGET_TLS && TARGET_ARCH64"
7127 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7129 (define_insn "tgd_call32"
7130 [(set (match_operand 0 "register_operand" "=r")
7131 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7132 (match_operand 2 "tgd_symbolic_operand" "")]
7134 (match_operand 3 "" "")))
7135 (clobber (reg:SI O7_REG))]
7136 "TARGET_TLS && TARGET_ARCH32"
7137 "call\t%a1, %%tgd_call(%a2)%#"
7138 [(set_attr "type" "call")])
7140 (define_insn "tgd_call64"
7141 [(set (match_operand 0 "register_operand" "=r")
7142 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7143 (match_operand 2 "tgd_symbolic_operand" "")]
7145 (match_operand 3 "" "")))
7146 (clobber (reg:DI O7_REG))]
7147 "TARGET_TLS && TARGET_ARCH64"
7148 "call\t%a1, %%tgd_call(%a2)%#"
7149 [(set_attr "type" "call")])
7151 (define_insn "tldm_hi22"
7152 [(set (match_operand:SI 0 "register_operand" "=r")
7153 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7155 "sethi\\t%%tldm_hi22(%&), %0")
7157 (define_insn "tldm_lo10"
7158 [(set (match_operand:SI 0 "register_operand" "=r")
7159 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7160 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7162 "add\\t%1, %%tldm_lo10(%&), %0")
7164 (define_insn "tldm_add32"
7165 [(set (match_operand:SI 0 "register_operand" "=r")
7166 (plus:SI (match_operand:SI 1 "register_operand" "r")
7167 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7169 "TARGET_TLS && TARGET_ARCH32"
7170 "add\\t%1, %2, %0, %%tldm_add(%&)")
7172 (define_insn "tldm_add64"
7173 [(set (match_operand:DI 0 "register_operand" "=r")
7174 (plus:DI (match_operand:DI 1 "register_operand" "r")
7175 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7177 "TARGET_TLS && TARGET_ARCH64"
7178 "add\\t%1, %2, %0, %%tldm_add(%&)")
7180 (define_insn "tldm_call32"
7181 [(set (match_operand 0 "register_operand" "=r")
7182 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7184 (match_operand 2 "" "")))
7185 (clobber (reg:SI O7_REG))]
7186 "TARGET_TLS && TARGET_ARCH32"
7187 "call\t%a1, %%tldm_call(%&)%#"
7188 [(set_attr "type" "call")])
7190 (define_insn "tldm_call64"
7191 [(set (match_operand 0 "register_operand" "=r")
7192 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7194 (match_operand 2 "" "")))
7195 (clobber (reg:DI O7_REG))]
7196 "TARGET_TLS && TARGET_ARCH64"
7197 "call\t%a1, %%tldm_call(%&)%#"
7198 [(set_attr "type" "call")])
7200 (define_insn "tldo_hix22"
7201 [(set (match_operand:SI 0 "register_operand" "=r")
7202 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7205 "sethi\\t%%tldo_hix22(%a1), %0")
7207 (define_insn "tldo_lox10"
7208 [(set (match_operand:SI 0 "register_operand" "=r")
7209 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7210 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7213 "xor\\t%1, %%tldo_lox10(%a2), %0")
7215 (define_insn "tldo_add32"
7216 [(set (match_operand:SI 0 "register_operand" "=r")
7217 (plus:SI (match_operand:SI 1 "register_operand" "r")
7218 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7219 (match_operand 3 "tld_symbolic_operand" "")]
7221 "TARGET_TLS && TARGET_ARCH32"
7222 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7224 (define_insn "tldo_add64"
7225 [(set (match_operand:DI 0 "register_operand" "=r")
7226 (plus:DI (match_operand:DI 1 "register_operand" "r")
7227 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7228 (match_operand 3 "tld_symbolic_operand" "")]
7230 "TARGET_TLS && TARGET_ARCH64"
7231 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7233 (define_insn "tie_hi22"
7234 [(set (match_operand:SI 0 "register_operand" "=r")
7235 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7238 "sethi\\t%%tie_hi22(%a1), %0")
7240 (define_insn "tie_lo10"
7241 [(set (match_operand:SI 0 "register_operand" "=r")
7242 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7243 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7246 "add\\t%1, %%tie_lo10(%a2), %0")
7248 (define_insn "tie_ld32"
7249 [(set (match_operand:SI 0 "register_operand" "=r")
7250 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7251 (match_operand:SI 2 "register_operand" "r")
7252 (match_operand 3 "tie_symbolic_operand" "")]
7254 "TARGET_TLS && TARGET_ARCH32"
7255 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7256 [(set_attr "type" "load")])
7258 (define_insn "tie_ld64"
7259 [(set (match_operand:DI 0 "register_operand" "=r")
7260 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7261 (match_operand:SI 2 "register_operand" "r")
7262 (match_operand 3 "tie_symbolic_operand" "")]
7264 "TARGET_TLS && TARGET_ARCH64"
7265 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7266 [(set_attr "type" "load")])
7268 (define_insn "tie_add32"
7269 [(set (match_operand:SI 0 "register_operand" "=r")
7270 (plus:SI (match_operand:SI 1 "register_operand" "r")
7271 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7272 (match_operand 3 "tie_symbolic_operand" "")]
7274 "TARGET_SUN_TLS && TARGET_ARCH32"
7275 "add\\t%1, %2, %0, %%tie_add(%a3)")
7277 (define_insn "tie_add64"
7278 [(set (match_operand:DI 0 "register_operand" "=r")
7279 (plus:DI (match_operand:DI 1 "register_operand" "r")
7280 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7281 (match_operand 3 "tie_symbolic_operand" "")]
7283 "TARGET_SUN_TLS && TARGET_ARCH64"
7284 "add\\t%1, %2, %0, %%tie_add(%a3)")
7286 (define_insn "tle_hix22_sp32"
7287 [(set (match_operand:SI 0 "register_operand" "=r")
7288 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7290 "TARGET_TLS && TARGET_ARCH32"
7291 "sethi\\t%%tle_hix22(%a1), %0")
7293 (define_insn "tle_lox10_sp32"
7294 [(set (match_operand:SI 0 "register_operand" "=r")
7295 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7296 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7298 "TARGET_TLS && TARGET_ARCH32"
7299 "xor\\t%1, %%tle_lox10(%a2), %0")
7301 (define_insn "tle_hix22_sp64"
7302 [(set (match_operand:DI 0 "register_operand" "=r")
7303 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7305 "TARGET_TLS && TARGET_ARCH64"
7306 "sethi\\t%%tle_hix22(%a1), %0")
7308 (define_insn "tle_lox10_sp64"
7309 [(set (match_operand:DI 0 "register_operand" "=r")
7310 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7311 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7313 "TARGET_TLS && TARGET_ARCH64"
7314 "xor\\t%1, %%tle_lox10(%a2), %0")
7316 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7317 (define_insn "*tldo_ldub_sp32"
7318 [(set (match_operand:QI 0 "register_operand" "=r")
7319 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7320 (match_operand 3 "tld_symbolic_operand" "")]
7322 (match_operand:SI 1 "register_operand" "r"))))]
7323 "TARGET_TLS && TARGET_ARCH32"
7324 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7325 [(set_attr "type" "load")
7326 (set_attr "us3load_type" "3cycle")])
7328 (define_insn "*tldo_ldub1_sp32"
7329 [(set (match_operand:HI 0 "register_operand" "=r")
7330 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7331 (match_operand 3 "tld_symbolic_operand" "")]
7333 (match_operand:SI 1 "register_operand" "r")))))]
7334 "TARGET_TLS && TARGET_ARCH32"
7335 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7336 [(set_attr "type" "load")
7337 (set_attr "us3load_type" "3cycle")])
7339 (define_insn "*tldo_ldub2_sp32"
7340 [(set (match_operand:SI 0 "register_operand" "=r")
7341 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7342 (match_operand 3 "tld_symbolic_operand" "")]
7344 (match_operand:SI 1 "register_operand" "r")))))]
7345 "TARGET_TLS && TARGET_ARCH32"
7346 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7347 [(set_attr "type" "load")
7348 (set_attr "us3load_type" "3cycle")])
7350 (define_insn "*tldo_ldsb1_sp32"
7351 [(set (match_operand:HI 0 "register_operand" "=r")
7352 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7353 (match_operand 3 "tld_symbolic_operand" "")]
7355 (match_operand:SI 1 "register_operand" "r")))))]
7356 "TARGET_TLS && TARGET_ARCH32"
7357 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7358 [(set_attr "type" "sload")
7359 (set_attr "us3load_type" "3cycle")])
7361 (define_insn "*tldo_ldsb2_sp32"
7362 [(set (match_operand:SI 0 "register_operand" "=r")
7363 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7364 (match_operand 3 "tld_symbolic_operand" "")]
7366 (match_operand:SI 1 "register_operand" "r")))))]
7367 "TARGET_TLS && TARGET_ARCH32"
7368 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7369 [(set_attr "type" "sload")
7370 (set_attr "us3load_type" "3cycle")])
7372 (define_insn "*tldo_ldub_sp64"
7373 [(set (match_operand:QI 0 "register_operand" "=r")
7374 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7375 (match_operand 3 "tld_symbolic_operand" "")]
7377 (match_operand:DI 1 "register_operand" "r"))))]
7378 "TARGET_TLS && TARGET_ARCH64"
7379 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7380 [(set_attr "type" "load")
7381 (set_attr "us3load_type" "3cycle")])
7383 (define_insn "*tldo_ldub1_sp64"
7384 [(set (match_operand:HI 0 "register_operand" "=r")
7385 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7386 (match_operand 3 "tld_symbolic_operand" "")]
7388 (match_operand:DI 1 "register_operand" "r")))))]
7389 "TARGET_TLS && TARGET_ARCH64"
7390 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7391 [(set_attr "type" "load")
7392 (set_attr "us3load_type" "3cycle")])
7394 (define_insn "*tldo_ldub2_sp64"
7395 [(set (match_operand:SI 0 "register_operand" "=r")
7396 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7397 (match_operand 3 "tld_symbolic_operand" "")]
7399 (match_operand:DI 1 "register_operand" "r")))))]
7400 "TARGET_TLS && TARGET_ARCH64"
7401 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7402 [(set_attr "type" "load")
7403 (set_attr "us3load_type" "3cycle")])
7405 (define_insn "*tldo_ldub3_sp64"
7406 [(set (match_operand:DI 0 "register_operand" "=r")
7407 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7408 (match_operand 3 "tld_symbolic_operand" "")]
7410 (match_operand:DI 1 "register_operand" "r")))))]
7411 "TARGET_TLS && TARGET_ARCH64"
7412 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7413 [(set_attr "type" "load")
7414 (set_attr "us3load_type" "3cycle")])
7416 (define_insn "*tldo_ldsb1_sp64"
7417 [(set (match_operand:HI 0 "register_operand" "=r")
7418 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7419 (match_operand 3 "tld_symbolic_operand" "")]
7421 (match_operand:DI 1 "register_operand" "r")))))]
7422 "TARGET_TLS && TARGET_ARCH64"
7423 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7424 [(set_attr "type" "sload")
7425 (set_attr "us3load_type" "3cycle")])
7427 (define_insn "*tldo_ldsb2_sp64"
7428 [(set (match_operand:SI 0 "register_operand" "=r")
7429 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7430 (match_operand 3 "tld_symbolic_operand" "")]
7432 (match_operand:DI 1 "register_operand" "r")))))]
7433 "TARGET_TLS && TARGET_ARCH64"
7434 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7435 [(set_attr "type" "sload")
7436 (set_attr "us3load_type" "3cycle")])
7438 (define_insn "*tldo_ldsb3_sp64"
7439 [(set (match_operand:DI 0 "register_operand" "=r")
7440 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7441 (match_operand 3 "tld_symbolic_operand" "")]
7443 (match_operand:DI 1 "register_operand" "r")))))]
7444 "TARGET_TLS && TARGET_ARCH64"
7445 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7446 [(set_attr "type" "sload")
7447 (set_attr "us3load_type" "3cycle")])
7449 (define_insn "*tldo_lduh_sp32"
7450 [(set (match_operand:HI 0 "register_operand" "=r")
7451 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7452 (match_operand 3 "tld_symbolic_operand" "")]
7454 (match_operand:SI 1 "register_operand" "r"))))]
7455 "TARGET_TLS && TARGET_ARCH32"
7456 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7457 [(set_attr "type" "load")
7458 (set_attr "us3load_type" "3cycle")])
7460 (define_insn "*tldo_lduh1_sp32"
7461 [(set (match_operand:SI 0 "register_operand" "=r")
7462 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7463 (match_operand 3 "tld_symbolic_operand" "")]
7465 (match_operand:SI 1 "register_operand" "r")))))]
7466 "TARGET_TLS && TARGET_ARCH32"
7467 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7468 [(set_attr "type" "load")
7469 (set_attr "us3load_type" "3cycle")])
7471 (define_insn "*tldo_ldsh1_sp32"
7472 [(set (match_operand:SI 0 "register_operand" "=r")
7473 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7474 (match_operand 3 "tld_symbolic_operand" "")]
7476 (match_operand:SI 1 "register_operand" "r")))))]
7477 "TARGET_TLS && TARGET_ARCH32"
7478 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7479 [(set_attr "type" "sload")
7480 (set_attr "us3load_type" "3cycle")])
7482 (define_insn "*tldo_lduh_sp64"
7483 [(set (match_operand:HI 0 "register_operand" "=r")
7484 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7485 (match_operand 3 "tld_symbolic_operand" "")]
7487 (match_operand:DI 1 "register_operand" "r"))))]
7488 "TARGET_TLS && TARGET_ARCH64"
7489 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7490 [(set_attr "type" "load")
7491 (set_attr "us3load_type" "3cycle")])
7493 (define_insn "*tldo_lduh1_sp64"
7494 [(set (match_operand:SI 0 "register_operand" "=r")
7495 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7496 (match_operand 3 "tld_symbolic_operand" "")]
7498 (match_operand:DI 1 "register_operand" "r")))))]
7499 "TARGET_TLS && TARGET_ARCH64"
7500 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7501 [(set_attr "type" "load")
7502 (set_attr "us3load_type" "3cycle")])
7504 (define_insn "*tldo_lduh2_sp64"
7505 [(set (match_operand:DI 0 "register_operand" "=r")
7506 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7507 (match_operand 3 "tld_symbolic_operand" "")]
7509 (match_operand:DI 1 "register_operand" "r")))))]
7510 "TARGET_TLS && TARGET_ARCH64"
7511 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7512 [(set_attr "type" "load")
7513 (set_attr "us3load_type" "3cycle")])
7515 (define_insn "*tldo_ldsh1_sp64"
7516 [(set (match_operand:SI 0 "register_operand" "=r")
7517 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7518 (match_operand 3 "tld_symbolic_operand" "")]
7520 (match_operand:DI 1 "register_operand" "r")))))]
7521 "TARGET_TLS && TARGET_ARCH64"
7522 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7523 [(set_attr "type" "sload")
7524 (set_attr "us3load_type" "3cycle")])
7526 (define_insn "*tldo_ldsh2_sp64"
7527 [(set (match_operand:DI 0 "register_operand" "=r")
7528 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7529 (match_operand 3 "tld_symbolic_operand" "")]
7531 (match_operand:DI 1 "register_operand" "r")))))]
7532 "TARGET_TLS && TARGET_ARCH64"
7533 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7534 [(set_attr "type" "sload")
7535 (set_attr "us3load_type" "3cycle")])
7537 (define_insn "*tldo_lduw_sp32"
7538 [(set (match_operand:SI 0 "register_operand" "=r")
7539 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7540 (match_operand 3 "tld_symbolic_operand" "")]
7542 (match_operand:SI 1 "register_operand" "r"))))]
7543 "TARGET_TLS && TARGET_ARCH32"
7544 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7545 [(set_attr "type" "load")])
7547 (define_insn "*tldo_lduw_sp64"
7548 [(set (match_operand:SI 0 "register_operand" "=r")
7549 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7550 (match_operand 3 "tld_symbolic_operand" "")]
7552 (match_operand:DI 1 "register_operand" "r"))))]
7553 "TARGET_TLS && TARGET_ARCH64"
7554 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7555 [(set_attr "type" "load")])
7557 (define_insn "*tldo_lduw1_sp64"
7558 [(set (match_operand:DI 0 "register_operand" "=r")
7559 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7560 (match_operand 3 "tld_symbolic_operand" "")]
7562 (match_operand:DI 1 "register_operand" "r")))))]
7563 "TARGET_TLS && TARGET_ARCH64"
7564 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7565 [(set_attr "type" "load")])
7567 (define_insn "*tldo_ldsw1_sp64"
7568 [(set (match_operand:DI 0 "register_operand" "=r")
7569 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7570 (match_operand 3 "tld_symbolic_operand" "")]
7572 (match_operand:DI 1 "register_operand" "r")))))]
7573 "TARGET_TLS && TARGET_ARCH64"
7574 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7575 [(set_attr "type" "sload")
7576 (set_attr "us3load_type" "3cycle")])
7578 (define_insn "*tldo_ldx_sp64"
7579 [(set (match_operand:DI 0 "register_operand" "=r")
7580 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7581 (match_operand 3 "tld_symbolic_operand" "")]
7583 (match_operand:DI 1 "register_operand" "r"))))]
7584 "TARGET_TLS && TARGET_ARCH64"
7585 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7586 [(set_attr "type" "load")])
7588 (define_insn "*tldo_stb_sp32"
7589 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7590 (match_operand 3 "tld_symbolic_operand" "")]
7592 (match_operand:SI 1 "register_operand" "r")))
7593 (match_operand:QI 0 "register_operand" "=r"))]
7594 "TARGET_TLS && TARGET_ARCH32"
7595 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7596 [(set_attr "type" "store")])
7598 (define_insn "*tldo_stb_sp64"
7599 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7600 (match_operand 3 "tld_symbolic_operand" "")]
7602 (match_operand:DI 1 "register_operand" "r")))
7603 (match_operand:QI 0 "register_operand" "=r"))]
7604 "TARGET_TLS && TARGET_ARCH64"
7605 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7606 [(set_attr "type" "store")])
7608 (define_insn "*tldo_sth_sp32"
7609 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7610 (match_operand 3 "tld_symbolic_operand" "")]
7612 (match_operand:SI 1 "register_operand" "r")))
7613 (match_operand:HI 0 "register_operand" "=r"))]
7614 "TARGET_TLS && TARGET_ARCH32"
7615 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7616 [(set_attr "type" "store")])
7618 (define_insn "*tldo_sth_sp64"
7619 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7620 (match_operand 3 "tld_symbolic_operand" "")]
7622 (match_operand:DI 1 "register_operand" "r")))
7623 (match_operand:HI 0 "register_operand" "=r"))]
7624 "TARGET_TLS && TARGET_ARCH64"
7625 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7626 [(set_attr "type" "store")])
7628 (define_insn "*tldo_stw_sp32"
7629 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7630 (match_operand 3 "tld_symbolic_operand" "")]
7632 (match_operand:SI 1 "register_operand" "r")))
7633 (match_operand:SI 0 "register_operand" "=r"))]
7634 "TARGET_TLS && TARGET_ARCH32"
7635 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7636 [(set_attr "type" "store")])
7638 (define_insn "*tldo_stw_sp64"
7639 [(set (mem:SI (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 (match_operand:SI 0 "register_operand" "=r"))]
7644 "TARGET_TLS && TARGET_ARCH64"
7645 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7646 [(set_attr "type" "store")])
7648 (define_insn "*tldo_stx_sp64"
7649 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7650 (match_operand 3 "tld_symbolic_operand" "")]
7652 (match_operand:DI 1 "register_operand" "r")))
7653 (match_operand:DI 0 "register_operand" "=r"))]
7654 "TARGET_TLS && TARGET_ARCH64"
7655 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7656 [(set_attr "type" "store")])
7659 ;; Stack protector instructions.
7661 (define_expand "stack_protect_set"
7662 [(match_operand 0 "memory_operand" "")
7663 (match_operand 1 "memory_operand" "")]
7666 #ifdef TARGET_THREAD_SSP_OFFSET
7667 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7668 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7669 operands[1] = gen_rtx_MEM (Pmode, addr);
7672 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7674 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7678 (define_insn "stack_protect_setsi"
7679 [(set (match_operand:SI 0 "memory_operand" "=m")
7680 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7681 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7683 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7684 [(set_attr "type" "multi")
7685 (set_attr "length" "3")])
7687 (define_insn "stack_protect_setdi"
7688 [(set (match_operand:DI 0 "memory_operand" "=m")
7689 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7690 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7692 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7693 [(set_attr "type" "multi")
7694 (set_attr "length" "3")])
7696 (define_expand "stack_protect_test"
7697 [(match_operand 0 "memory_operand" "")
7698 (match_operand 1 "memory_operand" "")
7699 (match_operand 2 "" "")]
7703 #ifdef TARGET_THREAD_SSP_OFFSET
7704 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7705 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7706 operands[1] = gen_rtx_MEM (Pmode, addr);
7710 result = gen_reg_rtx (Pmode);
7711 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7712 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7713 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7717 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7718 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7719 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7720 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7725 (define_insn "stack_protect_testsi"
7726 [(set (reg:CC CC_REG)
7727 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7728 (match_operand:SI 1 "memory_operand" "m")]
7730 (set (match_scratch:SI 3 "=r") (const_int 0))
7731 (clobber (match_scratch:SI 2 "=&r"))]
7733 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7734 [(set_attr "type" "multi")
7735 (set_attr "length" "4")])
7737 (define_insn "stack_protect_testdi"
7738 [(set (match_operand:DI 0 "register_operand" "=&r")
7739 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7740 (match_operand:DI 2 "memory_operand" "m")]
7742 (set (match_scratch:DI 3 "=r") (const_int 0))]
7744 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7745 [(set_attr "type" "multi")
7746 (set_attr "length" "4")])
7748 ;; Vector instructions.
7750 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7751 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7752 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7754 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
7755 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7756 (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7757 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7758 (V1DI "double") (V2SI "double") (V4HI "double")
7761 (define_expand "mov<VMALL:mode>"
7762 [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7763 (match_operand:VMALL 1 "general_operand" ""))]
7766 if (sparc_expand_move (<VMALL:MODE>mode, operands))
7770 (define_insn "*mov<VM32:mode>_insn"
7771 [(set (match_operand:VM32 0 "nonimmediate_operand" "=f, f,f,f,m, m,r,m, r, r")
7772 (match_operand:VM32 1 "input_operand" "GY,ZC,f,m,f,GY,m,r,GY,ZC"))]
7774 && (register_operand (operands[0], <VM32:MODE>mode)
7775 || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7787 [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*")])
7789 (define_insn "*mov<VM64:mode>_insn_sp64"
7790 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e, e,e,e,m, m,r,m, r, r")
7791 (match_operand:VM64 1 "input_operand" "GY,ZC,e,m,e,GY,m,r,GY,ZC"))]
7794 && (register_operand (operands[0], <VM64:MODE>mode)
7795 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7807 [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*")])
7809 (define_insn "*mov<VM64:mode>_insn_sp32"
7810 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e, e,e,e,m, m,U,T,o, r, r")
7811 (match_operand:VM64 1 "input_operand" "GY,ZC,e,m,e,GY,T,U,r,GY,ZC"))]
7814 && (register_operand (operands[0], <VM64:MODE>mode)
7815 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7826 mov 0, %L0; mov 0, %H0
7827 mov -1, %L0; mov -1, %H0"
7828 [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*,*")
7829 (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")])
7832 [(set (match_operand:VM64 0 "memory_operand" "")
7833 (match_operand:VM64 1 "register_operand" ""))]
7837 && (((REGNO (operands[1]) % 2) != 0)
7838 || ! mem_min_alignment (operands[0], 8))
7839 && offsettable_memref_p (operands[0])"
7840 [(clobber (const_int 0))]
7844 word0 = adjust_address (operands[0], SImode, 0);
7845 word1 = adjust_address (operands[0], SImode, 4);
7847 emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
7848 emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
7852 (define_expand "vec_init<mode>"
7853 [(match_operand:VMALL 0 "register_operand" "")
7854 (match_operand:VMALL 1 "" "")]
7857 sparc_expand_vector_init (operands[0], operands[1]);
7861 (define_code_iterator plusminus [plus minus])
7862 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
7864 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
7866 (define_insn "<plusminus_insn><mode>3"
7867 [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
7868 (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
7869 (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
7871 "fp<plusminus_insn><vbits>\t%1, %2, %0"
7872 [(set_attr "type" "fga")
7873 (set_attr "fptype" "<vfptype>")])
7875 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7876 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
7877 (V1DI "") (V2SI "") (V4HI "") (V8QI "")])
7878 (define_code_iterator vlop [ior and xor])
7879 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
7880 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
7882 (define_insn "<code><mode>3"
7883 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7884 (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7885 (match_operand:VL 2 "register_operand" "<vconstr>")))]
7887 "f<vlinsn><vlsuf>\t%1, %2, %0"
7888 [(set_attr "type" "fga")
7889 (set_attr "fptype" "<vfptype>")])
7891 (define_insn "*not_<code><mode>3"
7892 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7893 (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7894 (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7896 "f<vlninsn><vlsuf>\t%1, %2, %0"
7897 [(set_attr "type" "fga")
7898 (set_attr "fptype" "<vfptype>")])
7900 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7901 (define_insn "*nand<mode>_vis"
7902 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7903 (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
7904 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7906 "fnand<vlsuf>\t%1, %2, %0"
7907 [(set_attr "type" "fga")
7908 (set_attr "fptype" "<vfptype>")])
7910 (define_code_iterator vlnotop [ior and])
7912 (define_insn "*<code>_not1<mode>_vis"
7913 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7914 (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
7915 (match_operand:VL 2 "register_operand" "<vconstr>")))]
7917 "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
7918 [(set_attr "type" "fga")
7919 (set_attr "fptype" "<vfptype>")])
7921 (define_insn "*<code>_not2<mode>_vis"
7922 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7923 (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7924 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7926 "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
7927 [(set_attr "type" "fga")
7928 (set_attr "fptype" "<vfptype>")])
7930 (define_insn "one_cmpl<mode>2"
7931 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7932 (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
7934 "fnot1<vlsuf>\t%1, %0"
7935 [(set_attr "type" "fga")
7936 (set_attr "fptype" "<vfptype>")])
7938 ;; Hard to generate VIS instructions. We have builtins for these.
7940 (define_insn "fpack16_vis"
7941 [(set (match_operand:V4QI 0 "register_operand" "=f")
7942 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
7947 [(set_attr "type" "fga")
7948 (set_attr "fptype" "double")])
7950 (define_insn "fpackfix_vis"
7951 [(set (match_operand:V2HI 0 "register_operand" "=f")
7952 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
7957 [(set_attr "type" "fga")
7958 (set_attr "fptype" "double")])
7960 (define_insn "fpack32_vis"
7961 [(set (match_operand:V8QI 0 "register_operand" "=e")
7962 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7963 (match_operand:V8QI 2 "register_operand" "e")
7967 "fpack32\t%1, %2, %0"
7968 [(set_attr "type" "fga")
7969 (set_attr "fptype" "double")])
7971 (define_insn "fexpand_vis"
7972 [(set (match_operand:V4HI 0 "register_operand" "=e")
7973 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7977 [(set_attr "type" "fga")
7978 (set_attr "fptype" "double")])
7980 (define_insn "fpmerge_vis"
7981 [(set (match_operand:V8QI 0 "register_operand" "=e")
7983 (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
7984 (match_operand:V4QI 2 "register_operand" "f"))
7985 (parallel [(const_int 0) (const_int 4)
7986 (const_int 1) (const_int 5)
7987 (const_int 2) (const_int 6)
7988 (const_int 3) (const_int 7)])))]
7990 "fpmerge\t%1, %2, %0"
7991 [(set_attr "type" "fga")
7992 (set_attr "fptype" "double")])
7994 (define_insn "vec_interleave_lowv8qi"
7995 [(set (match_operand:V8QI 0 "register_operand" "=e")
7997 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
7998 (match_operand:V8QI 2 "register_operand" "f"))
7999 (parallel [(const_int 0) (const_int 8)
8000 (const_int 1) (const_int 9)
8001 (const_int 2) (const_int 10)
8002 (const_int 3) (const_int 11)])))]
8004 "fpmerge\t%L1, %L2, %0"
8005 [(set_attr "type" "fga")
8006 (set_attr "fptype" "double")])
8008 (define_insn "vec_interleave_highv8qi"
8009 [(set (match_operand:V8QI 0 "register_operand" "=e")
8011 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8012 (match_operand:V8QI 2 "register_operand" "f"))
8013 (parallel [(const_int 4) (const_int 12)
8014 (const_int 5) (const_int 13)
8015 (const_int 6) (const_int 14)
8016 (const_int 7) (const_int 15)])))]
8018 "fpmerge\t%H1, %H2, %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 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8026 (match_operand:V4HI 2 "register_operand" "e")]
8029 "fmul8x16\t%1, %2, %0"
8030 [(set_attr "type" "fpmul")
8031 (set_attr "fptype" "double")])
8033 (define_insn "fmul8x16au_vis"
8034 [(set (match_operand:V4HI 0 "register_operand" "=e")
8035 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8036 (match_operand:V2HI 2 "register_operand" "f")]
8039 "fmul8x16au\t%1, %2, %0"
8040 [(set_attr "type" "fpmul")
8041 (set_attr "fptype" "double")])
8043 (define_insn "fmul8x16al_vis"
8044 [(set (match_operand:V4HI 0 "register_operand" "=e")
8045 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8046 (match_operand:V2HI 2 "register_operand" "f")]
8049 "fmul8x16al\t%1, %2, %0"
8050 [(set_attr "type" "fpmul")
8051 (set_attr "fptype" "double")])
8053 (define_insn "fmul8sux16_vis"
8054 [(set (match_operand:V4HI 0 "register_operand" "=e")
8055 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8056 (match_operand:V4HI 2 "register_operand" "e")]
8059 "fmul8sux16\t%1, %2, %0"
8060 [(set_attr "type" "fpmul")
8061 (set_attr "fptype" "double")])
8063 (define_insn "fmul8ulx16_vis"
8064 [(set (match_operand:V4HI 0 "register_operand" "=e")
8065 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8066 (match_operand:V4HI 2 "register_operand" "e")]
8069 "fmul8ulx16\t%1, %2, %0"
8070 [(set_attr "type" "fpmul")
8071 (set_attr "fptype" "double")])
8073 (define_insn "fmuld8sux16_vis"
8074 [(set (match_operand:V2SI 0 "register_operand" "=e")
8075 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8076 (match_operand:V2HI 2 "register_operand" "f")]
8079 "fmuld8sux16\t%1, %2, %0"
8080 [(set_attr "type" "fpmul")
8081 (set_attr "fptype" "double")])
8083 (define_insn "fmuld8ulx16_vis"
8084 [(set (match_operand:V2SI 0 "register_operand" "=e")
8085 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8086 (match_operand:V2HI 2 "register_operand" "f")]
8089 "fmuld8ulx16\t%1, %2, %0"
8090 [(set_attr "type" "fpmul")
8091 (set_attr "fptype" "double")])
8093 (define_expand "wrgsr_vis"
8094 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8097 if (! TARGET_ARCH64)
8099 emit_insn (gen_wrgsr_v8plus (operands[0]));
8104 (define_insn "*wrgsr_sp64"
8105 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8106 "TARGET_VIS && TARGET_ARCH64"
8107 "wr\t%%g0, %0, %%gsr"
8108 [(set_attr "type" "gsr")])
8110 (define_insn "wrgsr_v8plus"
8111 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8112 (clobber (match_scratch:SI 1 "=X,&h"))]
8113 "TARGET_VIS && ! TARGET_ARCH64"
8115 if (GET_CODE (operands[0]) == CONST_INT
8116 || sparc_check_64 (operands[0], insn))
8117 return "wr\t%%g0, %0, %%gsr";
8119 output_asm_insn("srl\t%L0, 0, %L0", operands);
8120 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8122 [(set_attr "type" "multi")])
8124 (define_expand "rdgsr_vis"
8125 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8128 if (! TARGET_ARCH64)
8130 emit_insn (gen_rdgsr_v8plus (operands[0]));
8135 (define_insn "*rdgsr_sp64"
8136 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8137 "TARGET_VIS && TARGET_ARCH64"
8139 [(set_attr "type" "gsr")])
8141 (define_insn "rdgsr_v8plus"
8142 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8143 (clobber (match_scratch:SI 1 "=&h"))]
8144 "TARGET_VIS && ! TARGET_ARCH64"
8146 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8148 [(set_attr "type" "multi")])
8150 ;; Using faligndata only makes sense after an alignaddr since the choice of
8151 ;; bytes to take out of each operand is dependent on the results of the last
8153 (define_insn "faligndata<VM64:mode>_vis"
8154 [(set (match_operand:VM64 0 "register_operand" "=e")
8155 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8156 (match_operand:VM64 2 "register_operand" "e")
8160 "faligndata\t%1, %2, %0"
8161 [(set_attr "type" "fga")
8162 (set_attr "fptype" "double")])
8164 (define_insn "alignaddrsi_vis"
8165 [(set (match_operand:SI 0 "register_operand" "=r")
8166 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8167 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8168 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8169 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8171 "alignaddr\t%r1, %r2, %0")
8173 (define_insn "alignaddrdi_vis"
8174 [(set (match_operand:DI 0 "register_operand" "=r")
8175 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8176 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8177 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8178 (plus:DI (match_dup 1) (match_dup 2)))]
8180 "alignaddr\t%r1, %r2, %0")
8182 (define_insn "alignaddrlsi_vis"
8183 [(set (match_operand:SI 0 "register_operand" "=r")
8184 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8185 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8186 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8187 (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8190 "alignaddrl\t%r1, %r2, %0")
8192 (define_insn "alignaddrldi_vis"
8193 [(set (match_operand:DI 0 "register_operand" "=r")
8194 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8195 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8196 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8197 (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8200 "alignaddrl\t%r1, %r2, %0")
8202 (define_insn "pdist_vis"
8203 [(set (match_operand:DI 0 "register_operand" "=e")
8204 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8205 (match_operand:V8QI 2 "register_operand" "e")
8206 (match_operand:DI 3 "register_operand" "0")]
8210 [(set_attr "type" "fga")
8211 (set_attr "fptype" "double")])
8213 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8214 ;; with the same operands.
8215 (define_insn "edge8<P:mode>_vis"
8216 [(set (reg:CC_NOOV CC_REG)
8217 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8218 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8220 (set (match_operand:P 0 "register_operand" "=r")
8221 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8223 "edge8\t%r1, %r2, %0"
8224 [(set_attr "type" "edge")])
8226 (define_insn "edge8l<P:mode>_vis"
8227 [(set (reg:CC_NOOV CC_REG)
8228 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8229 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8231 (set (match_operand:P 0 "register_operand" "=r")
8232 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8234 "edge8l\t%r1, %r2, %0"
8235 [(set_attr "type" "edge")])
8237 (define_insn "edge16<P:mode>_vis"
8238 [(set (reg:CC_NOOV CC_REG)
8239 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8240 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8242 (set (match_operand:P 0 "register_operand" "=r")
8243 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8245 "edge16\t%r1, %r2, %0"
8246 [(set_attr "type" "edge")])
8248 (define_insn "edge16l<P:mode>_vis"
8249 [(set (reg:CC_NOOV CC_REG)
8250 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8251 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8253 (set (match_operand:P 0 "register_operand" "=r")
8254 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8256 "edge16l\t%r1, %r2, %0"
8257 [(set_attr "type" "edge")])
8259 (define_insn "edge32<P:mode>_vis"
8260 [(set (reg:CC_NOOV CC_REG)
8261 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8262 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8264 (set (match_operand:P 0 "register_operand" "=r")
8265 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8267 "edge32\t%r1, %r2, %0"
8268 [(set_attr "type" "edge")])
8270 (define_insn "edge32l<P:mode>_vis"
8271 [(set (reg:CC_NOOV CC_REG)
8272 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8273 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8275 (set (match_operand:P 0 "register_operand" "=r")
8276 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8278 "edge32l\t%r1, %r2, %0"
8279 [(set_attr "type" "edge")])
8281 (define_code_iterator gcond [le ne gt eq])
8282 (define_mode_iterator GCM [V4HI V2SI])
8283 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8285 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8286 [(set (match_operand:P 0 "register_operand" "=r")
8287 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8288 (match_operand:GCM 2 "register_operand" "e"))]
8291 "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8292 [(set_attr "type" "fpmul")
8293 (set_attr "fptype" "double")])
8295 (define_insn "array8<P:mode>_vis"
8296 [(set (match_operand:P 0 "register_operand" "=r")
8297 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8298 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8301 "array8\t%r1, %r2, %0"
8302 [(set_attr "type" "array")])
8304 (define_insn "array16<P:mode>_vis"
8305 [(set (match_operand:P 0 "register_operand" "=r")
8306 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8307 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8310 "array16\t%r1, %r2, %0"
8311 [(set_attr "type" "array")])
8313 (define_insn "array32<P:mode>_vis"
8314 [(set (match_operand:P 0 "register_operand" "=r")
8315 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8316 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8319 "array32\t%r1, %r2, %0"
8320 [(set_attr "type" "array")])
8322 (define_insn "bmaskdi_vis"
8323 [(set (match_operand:DI 0 "register_operand" "=r")
8324 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8325 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8326 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8327 (plus:DI (match_dup 1) (match_dup 2)))]
8329 "bmask\t%r1, %r2, %0"
8330 [(set_attr "type" "array")])
8332 (define_insn "bmasksi_vis"
8333 [(set (match_operand:SI 0 "register_operand" "=r")
8334 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8335 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8336 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8337 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8339 "bmask\t%r1, %r2, %0"
8340 [(set_attr "type" "array")])
8342 (define_insn "bshuffle<VM64:mode>_vis"
8343 [(set (match_operand:VM64 0 "register_operand" "=e")
8344 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8345 (match_operand:VM64 2 "register_operand" "e")
8349 "bshuffle\t%1, %2, %0"
8350 [(set_attr "type" "fga")
8351 (set_attr "fptype" "double")])
8353 ;; The rtl expanders will happily convert constant permutations on other
8354 ;; modes down to V8QI. Rely on this to avoid the complexity of the byte
8355 ;; order of the permutation.
8356 (define_expand "vec_perm_constv8qi"
8357 [(match_operand:V8QI 0 "register_operand" "")
8358 (match_operand:V8QI 1 "register_operand" "")
8359 (match_operand:V8QI 2 "register_operand" "")
8360 (match_operand:V8QI 3 "" "")]
8363 unsigned int i, mask;
8364 rtx sel = operands[3];
8366 for (i = mask = 0; i < 8; ++i)
8367 mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8368 sel = force_reg (SImode, gen_int_mode (mask, SImode));
8370 emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, const0_rtx));
8371 emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8375 ;; Unlike constant permutation, we can vastly simplify the compression of
8376 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8377 ;; width of the input is.
8378 (define_expand "vec_perm<mode>"
8379 [(match_operand:VM64 0 "register_operand" "")
8380 (match_operand:VM64 1 "register_operand" "")
8381 (match_operand:VM64 2 "register_operand" "")
8382 (match_operand:VM64 3 "register_operand" "")]
8385 sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8386 emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8390 ;; VIS 2.0 adds edge variants which do not set the condition codes
8391 (define_insn "edge8n<P:mode>_vis"
8392 [(set (match_operand:P 0 "register_operand" "=r")
8393 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8394 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8397 "edge8n\t%r1, %r2, %0"
8398 [(set_attr "type" "edgen")])
8400 (define_insn "edge8ln<P:mode>_vis"
8401 [(set (match_operand:P 0 "register_operand" "=r")
8402 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8403 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8406 "edge8ln\t%r1, %r2, %0"
8407 [(set_attr "type" "edgen")])
8409 (define_insn "edge16n<P:mode>_vis"
8410 [(set (match_operand:P 0 "register_operand" "=r")
8411 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8412 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8415 "edge16n\t%r1, %r2, %0"
8416 [(set_attr "type" "edgen")])
8418 (define_insn "edge16ln<P:mode>_vis"
8419 [(set (match_operand:P 0 "register_operand" "=r")
8420 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8421 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8424 "edge16ln\t%r1, %r2, %0"
8425 [(set_attr "type" "edgen")])
8427 (define_insn "edge32n<P:mode>_vis"
8428 [(set (match_operand:P 0 "register_operand" "=r")
8429 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8430 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8433 "edge32n\t%r1, %r2, %0"
8434 [(set_attr "type" "edgen")])
8436 (define_insn "edge32ln<P:mode>_vis"
8437 [(set (match_operand:P 0 "register_operand" "=r")
8438 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8439 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8442 "edge32ln\t%r1, %r2, %0"
8443 [(set_attr "type" "edge")])
8445 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8446 (define_insn "cmask8<P:mode>_vis"
8447 [(set (reg:DI GSR_REG)
8448 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8454 (define_insn "cmask16<P:mode>_vis"
8455 [(set (reg:DI GSR_REG)
8456 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8462 (define_insn "cmask32<P:mode>_vis"
8463 [(set (reg:DI GSR_REG)
8464 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8470 (define_insn "fchksm16_vis"
8471 [(set (match_operand:V4HI 0 "register_operand" "=e")
8472 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8473 (match_operand:V4HI 2 "register_operand" "e")]
8476 "fchksm16\t%1, %2, %0")
8478 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8479 (define_code_attr vis3_shift_insn
8480 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8481 (define_code_attr vis3_shift_patname
8482 [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8484 (define_insn "v<vis3_shift_patname><mode>3"
8485 [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8486 (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8487 (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8489 "<vis3_shift_insn><vbits>\t%1, %2, %0")
8491 (define_insn "pdistn<mode>_vis"
8492 [(set (match_operand:P 0 "register_operand" "=r")
8493 (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8494 (match_operand:V8QI 2 "register_operand" "e")]
8497 "pdistn\t%1, %2, %0")
8499 (define_insn "fmean16_vis"
8500 [(set (match_operand:V4HI 0 "register_operand" "=e")
8506 (match_operand:V4HI 1 "register_operand" "e"))
8508 (match_operand:V4HI 2 "register_operand" "e")))
8509 (const_vector:V4SI [(const_int 1) (const_int 1)
8510 (const_int 1) (const_int 1)]))
8513 "fmean16\t%1, %2, %0")
8515 (define_insn "fp<plusminus_insn>64_vis"
8516 [(set (match_operand:V1DI 0 "register_operand" "=e")
8517 (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8518 (match_operand:V1DI 2 "register_operand" "e")))]
8520 "fp<plusminus_insn>64\t%1, %2, %0")
8522 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8523 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8524 (define_code_attr vis3_addsub_ss_insn
8525 [(ss_plus "fpadds") (ss_minus "fpsubs")])
8526 (define_code_attr vis3_addsub_ss_patname
8527 [(ss_plus "ssadd") (ss_minus "sssub")])
8529 (define_insn "<vis3_addsub_ss_patname><mode>3"
8530 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8531 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8532 (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8534 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0")
8536 (define_insn "fucmp<code>8<P:mode>_vis"
8537 [(set (match_operand:P 0 "register_operand" "=r")
8538 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8539 (match_operand:V8QI 2 "register_operand" "e"))]
8542 "fucmp<code>8\t%1, %2, %0")
8544 (define_insn "*naddsf3"
8545 [(set (match_operand:SF 0 "register_operand" "=f")
8546 (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8547 (match_operand:SF 2 "register_operand" "f"))))]
8549 "fnadds\t%1, %2, %0"
8550 [(set_attr "type" "fp")])
8552 (define_insn "*nadddf3"
8553 [(set (match_operand:DF 0 "register_operand" "=e")
8554 (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8555 (match_operand:DF 2 "register_operand" "e"))))]
8557 "fnaddd\t%1, %2, %0"
8558 [(set_attr "type" "fp")
8559 (set_attr "fptype" "double")])
8561 (define_insn "*nmulsf3"
8562 [(set (match_operand:SF 0 "register_operand" "=f")
8563 (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8564 (match_operand:SF 2 "register_operand" "f")))]
8566 "fnmuls\t%1, %2, %0"
8567 [(set_attr "type" "fpmul")])
8569 (define_insn "*nmuldf3"
8570 [(set (match_operand:DF 0 "register_operand" "=e")
8571 (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8572 (match_operand:DF 2 "register_operand" "e")))]
8574 "fnmuld\t%1, %2, %0"
8575 [(set_attr "type" "fpmul")
8576 (set_attr "fptype" "double")])
8578 (define_insn "*nmuldf3_extend"
8579 [(set (match_operand:DF 0 "register_operand" "=e")
8580 (mult:DF (neg:DF (float_extend:DF
8581 (match_operand:SF 1 "register_operand" "f")))
8583 (match_operand:SF 2 "register_operand" "f"))))]
8585 "fnsmuld\t%1, %2, %0"
8586 [(set_attr "type" "fpmul")
8587 (set_attr "fptype" "double")])
8589 (define_insn "fhaddsf_vis"
8590 [(set (match_operand:SF 0 "register_operand" "=f")
8591 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8592 (match_operand:SF 2 "register_operand" "f")]
8595 "fhadds\t%1, %2, %0"
8596 [(set_attr "type" "fp")])
8598 (define_insn "fhadddf_vis"
8599 [(set (match_operand:DF 0 "register_operand" "=f")
8600 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8601 (match_operand:DF 2 "register_operand" "f")]
8604 "fhaddd\t%1, %2, %0"
8605 [(set_attr "type" "fp")
8606 (set_attr "fptype" "double")])
8608 (define_insn "fhsubsf_vis"
8609 [(set (match_operand:SF 0 "register_operand" "=f")
8610 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8611 (match_operand:SF 2 "register_operand" "f")]
8614 "fhsubs\t%1, %2, %0"
8615 [(set_attr "type" "fp")])
8617 (define_insn "fhsubdf_vis"
8618 [(set (match_operand:DF 0 "register_operand" "=f")
8619 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8620 (match_operand:DF 2 "register_operand" "f")]
8623 "fhsubd\t%1, %2, %0"
8624 [(set_attr "type" "fp")
8625 (set_attr "fptype" "double")])
8627 (define_insn "fnhaddsf_vis"
8628 [(set (match_operand:SF 0 "register_operand" "=f")
8629 (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8630 (match_operand:SF 2 "register_operand" "f")]
8633 "fnhadds\t%1, %2, %0"
8634 [(set_attr "type" "fp")])
8636 (define_insn "fnhadddf_vis"
8637 [(set (match_operand:DF 0 "register_operand" "=f")
8638 (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8639 (match_operand:DF 2 "register_operand" "f")]
8642 "fnhaddd\t%1, %2, %0"
8643 [(set_attr "type" "fp")
8644 (set_attr "fptype" "double")])
8646 (define_expand "umulxhi_vis"
8647 [(set (match_operand:DI 0 "register_operand" "")
8650 (mult:TI (zero_extend:TI
8651 (match_operand:DI 1 "arith_operand" ""))
8653 (match_operand:DI 2 "arith_operand" "")))
8657 if (! TARGET_ARCH64)
8659 emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8664 (define_insn "*umulxhi_sp64"
8665 [(set (match_operand:DI 0 "register_operand" "=r")
8668 (mult:TI (zero_extend:TI
8669 (match_operand:DI 1 "arith_operand" "%r"))
8671 (match_operand:DI 2 "arith_operand" "rI")))
8673 "TARGET_VIS3 && TARGET_ARCH64"
8674 "umulxhi\t%1, %2, %0"
8675 [(set_attr "type" "imul")])
8677 (define_insn "umulxhi_v8plus"
8678 [(set (match_operand:DI 0 "register_operand" "=r,h")
8681 (mult:TI (zero_extend:TI
8682 (match_operand:DI 1 "arith_operand" "%r,0"))
8684 (match_operand:DI 2 "arith_operand" "rI,rI")))
8686 (clobber (match_scratch:SI 3 "=&h,X"))
8687 (clobber (match_scratch:SI 4 "=&h,X"))]
8688 "TARGET_VIS3 && ! TARGET_ARCH64"
8689 "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8690 [(set_attr "type" "imul")
8691 (set_attr "length" "9,8")])
8693 (define_expand "xmulx_vis"
8694 [(set (match_operand:DI 0 "register_operand" "")
8696 (unspec:TI [(zero_extend:TI
8697 (match_operand:DI 1 "arith_operand" ""))
8699 (match_operand:DI 2 "arith_operand" ""))]
8703 if (! TARGET_ARCH64)
8705 emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8710 (define_insn "*xmulx_sp64"
8711 [(set (match_operand:DI 0 "register_operand" "=r")
8713 (unspec:TI [(zero_extend:TI
8714 (match_operand:DI 1 "arith_operand" "%r"))
8716 (match_operand:DI 2 "arith_operand" "rI"))]
8718 "TARGET_VIS3 && TARGET_ARCH64"
8720 [(set_attr "type" "imul")])
8722 (define_insn "xmulx_v8plus"
8723 [(set (match_operand:DI 0 "register_operand" "=r,h")
8725 (unspec:TI [(zero_extend:TI
8726 (match_operand:DI 1 "arith_operand" "%r,0"))
8728 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8730 (clobber (match_scratch:SI 3 "=&h,X"))
8731 (clobber (match_scratch:SI 4 "=&h,X"))]
8732 "TARGET_VIS3 && ! TARGET_ARCH64"
8733 "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8734 [(set_attr "type" "imul")
8735 (set_attr "length" "9,8")])
8737 (define_expand "xmulxhi_vis"
8738 [(set (match_operand:DI 0 "register_operand" "")
8741 (unspec:TI [(zero_extend:TI
8742 (match_operand:DI 1 "arith_operand" ""))
8744 (match_operand:DI 2 "arith_operand" ""))]
8749 if (! TARGET_ARCH64)
8751 emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
8756 (define_insn "*xmulxhi_sp64"
8757 [(set (match_operand:DI 0 "register_operand" "=r")
8760 (unspec:TI [(zero_extend:TI
8761 (match_operand:DI 1 "arith_operand" "%r"))
8763 (match_operand:DI 2 "arith_operand" "rI"))]
8766 "TARGET_VIS3 && TARGET_ARCH64"
8767 "xmulxhi\t%1, %2, %0"
8768 [(set_attr "type" "imul")])
8770 (define_insn "xmulxhi_v8plus"
8771 [(set (match_operand:DI 0 "register_operand" "=r,h")
8774 (unspec:TI [(zero_extend:TI
8775 (match_operand:DI 1 "arith_operand" "%r,0"))
8777 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8780 (clobber (match_scratch:SI 3 "=&h,X"))
8781 (clobber (match_scratch:SI 4 "=&h,X"))]
8782 "TARGET_VIS3 && !TARGET_ARCH64"
8783 "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
8784 [(set_attr "type" "imul")
8785 (set_attr "length" "9,8")])