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)
94 (UNSPECV_PROBE_STACK_RANGE 11)
187 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
188 (define_mode_iterator I [QI HI SI DI])
189 (define_mode_iterator F [SF DF TF])
191 ;; We don't define V1SI because SI should work just fine.
192 (define_mode_iterator V32 [SF V2HI V4QI])
193 (define_mode_iterator V32I [SI V2HI V4QI])
195 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
196 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
198 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
199 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
200 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
201 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
202 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
205 ;; Attribute for cpu type.
206 ;; These must match the values for enum processor_type in sparc.h.
227 (const (symbol_ref "sparc_cpu_attr")))
229 ;; Attribute for the instruction set.
230 ;; At present we only need to distinguish v9/!v9, but for clarity we
231 ;; test TARGET_V8 too.
232 (define_attr "isa" "v7,v8,v9,sparclet"
234 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
235 (symbol_ref "TARGET_V8") (const_string "v8")
236 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
237 (const_string "v7"))))
243 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
251 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,edgen,gsr,array,
254 multi,savew,flushw,iflush,trap"
255 (const_string "ialu"))
257 ;; True if branch/call has empty delay slot and will emit a nop in it
258 (define_attr "empty_delay_slot" "false,true"
259 (symbol_ref "(empty_delay_slot (insn)
260 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
262 (define_attr "branch_type" "none,icc,fcc,reg"
263 (const_string "none"))
265 (define_attr "pic" "false,true"
266 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
268 (define_attr "calls_alloca" "false,true"
269 (symbol_ref "(cfun->calls_alloca != 0
270 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
272 (define_attr "calls_eh_return" "false,true"
273 (symbol_ref "(crtl->calls_eh_return != 0
274 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
276 (define_attr "leaf_function" "false,true"
277 (symbol_ref "(current_function_uses_only_leaf_regs != 0
278 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
280 (define_attr "delayed_branch" "false,true"
281 (symbol_ref "(flag_delayed_branch != 0
282 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
284 (define_attr "flat" "false,true"
285 (symbol_ref "(TARGET_FLAT != 0
286 ? FLAT_TRUE : FLAT_FALSE)"))
288 ;; Length (in # of insns).
289 ;; Beware that setting a length greater or equal to 3 for conditional branches
290 ;; has a side-effect (see output_cbranch and output_v9branch).
291 (define_attr "length" ""
292 (cond [(eq_attr "type" "uncond_branch,call")
293 (if_then_else (eq_attr "empty_delay_slot" "true")
296 (eq_attr "type" "sibcall")
297 (if_then_else (eq_attr "leaf_function" "true")
298 (if_then_else (eq_attr "empty_delay_slot" "true")
301 (if_then_else (eq_attr "empty_delay_slot" "true")
304 (eq_attr "branch_type" "icc")
305 (if_then_else (match_operand 0 "noov_compare64_operator" "")
306 (if_then_else (lt (pc) (match_dup 1))
307 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
308 (if_then_else (eq_attr "empty_delay_slot" "true")
311 (if_then_else (eq_attr "empty_delay_slot" "true")
314 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
315 (if_then_else (eq_attr "empty_delay_slot" "true")
318 (if_then_else (eq_attr "empty_delay_slot" "true")
321 (if_then_else (eq_attr "empty_delay_slot" "true")
324 (eq_attr "branch_type" "fcc")
325 (if_then_else (match_operand 0 "fcc0_register_operand" "")
326 (if_then_else (eq_attr "empty_delay_slot" "true")
327 (if_then_else (not (match_test "TARGET_V9"))
330 (if_then_else (not (match_test "TARGET_V9"))
333 (if_then_else (lt (pc) (match_dup 2))
334 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
335 (if_then_else (eq_attr "empty_delay_slot" "true")
338 (if_then_else (eq_attr "empty_delay_slot" "true")
341 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
342 (if_then_else (eq_attr "empty_delay_slot" "true")
345 (if_then_else (eq_attr "empty_delay_slot" "true")
348 (eq_attr "branch_type" "reg")
349 (if_then_else (lt (pc) (match_dup 2))
350 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
351 (if_then_else (eq_attr "empty_delay_slot" "true")
354 (if_then_else (eq_attr "empty_delay_slot" "true")
357 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
358 (if_then_else (eq_attr "empty_delay_slot" "true")
361 (if_then_else (eq_attr "empty_delay_slot" "true")
367 (define_attr "fptype" "single,double"
368 (const_string "single"))
370 ;; UltraSPARC-III integer load type.
371 (define_attr "us3load_type" "2cycle,3cycle"
372 (const_string "2cycle"))
374 (define_asm_attributes
375 [(set_attr "length" "2")
376 (set_attr "type" "multi")])
378 ;; Attributes for instruction and branch scheduling
379 (define_attr "tls_call_delay" "false,true"
380 (symbol_ref "(tls_call_delay (insn)
381 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
383 (define_attr "in_call_delay" "false,true"
384 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
385 (const_string "false")
386 (eq_attr "type" "load,fpload,store,fpstore")
387 (if_then_else (eq_attr "length" "1")
388 (const_string "true")
389 (const_string "false"))]
390 (if_then_else (and (eq_attr "length" "1")
391 (eq_attr "tls_call_delay" "true"))
392 (const_string "true")
393 (const_string "false"))))
395 (define_attr "eligible_for_sibcall_delay" "false,true"
396 (symbol_ref "(eligible_for_sibcall_delay (insn)
397 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
398 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
400 (define_attr "eligible_for_return_delay" "false,true"
401 (symbol_ref "(eligible_for_return_delay (insn)
402 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
403 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
405 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
406 ;; branches. This would allow us to remove the nop always inserted before
407 ;; a floating point branch.
409 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
410 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
411 ;; This is because doing so will add several pipeline stalls to the path
412 ;; that the load/store did not come from. Unfortunately, there is no way
413 ;; to prevent fill_eager_delay_slots from using load/store without completely
414 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
415 ;; because it prevents us from moving back the final store of inner loops.
417 (define_attr "in_branch_delay" "false,true"
418 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
419 (eq_attr "length" "1"))
420 (const_string "true")
421 (const_string "false")))
423 (define_attr "in_uncond_branch_delay" "false,true"
424 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
425 (eq_attr "length" "1"))
426 (const_string "true")
427 (const_string "false")))
429 (define_attr "in_annul_branch_delay" "false,true"
430 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
431 (eq_attr "length" "1"))
432 (const_string "true")
433 (const_string "false")))
435 (define_delay (eq_attr "type" "call")
436 [(eq_attr "in_call_delay" "true") (nil) (nil)])
438 (define_delay (eq_attr "type" "sibcall")
439 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
441 (define_delay (eq_attr "type" "branch")
442 [(eq_attr "in_branch_delay" "true")
443 (nil) (eq_attr "in_annul_branch_delay" "true")])
445 (define_delay (eq_attr "type" "uncond_branch")
446 [(eq_attr "in_uncond_branch_delay" "true")
449 (define_delay (eq_attr "type" "return")
450 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
453 ;; Include SPARC DFA schedulers
455 (include "cypress.md")
456 (include "supersparc.md")
457 (include "hypersparc.md")
459 (include "sparclet.md")
460 (include "ultra1_2.md")
461 (include "ultra3.md")
462 (include "niagara.md")
463 (include "niagara2.md")
466 ;; Operand and operator predicates and constraints
468 (include "predicates.md")
469 (include "constraints.md")
472 ;; Compare instructions.
474 ;; These are just the DEFINE_INSNs to match the patterns and the
475 ;; DEFINE_SPLITs for some of the scc insns that actually require
476 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
478 ;; The compare DEFINE_INSNs.
480 (define_insn "*cmpsi_insn"
481 [(set (reg:CC CC_REG)
482 (compare:CC (match_operand:SI 0 "register_operand" "r")
483 (match_operand:SI 1 "arith_operand" "rI")))]
486 [(set_attr "type" "compare")])
488 (define_insn "*cmpdi_sp64"
489 [(set (reg:CCX CC_REG)
490 (compare:CCX (match_operand:DI 0 "register_operand" "r")
491 (match_operand:DI 1 "arith_operand" "rI")))]
494 [(set_attr "type" "compare")])
496 (define_insn "*cmpsf_fpe"
497 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
498 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
499 (match_operand:SF 2 "register_operand" "f")))]
503 return "fcmpes\t%0, %1, %2";
504 return "fcmpes\t%1, %2";
506 [(set_attr "type" "fpcmp")])
508 (define_insn "*cmpdf_fpe"
509 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
510 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
511 (match_operand:DF 2 "register_operand" "e")))]
515 return "fcmped\t%0, %1, %2";
516 return "fcmped\t%1, %2";
518 [(set_attr "type" "fpcmp")
519 (set_attr "fptype" "double")])
521 (define_insn "*cmptf_fpe"
522 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
523 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
524 (match_operand:TF 2 "register_operand" "e")))]
525 "TARGET_FPU && TARGET_HARD_QUAD"
528 return "fcmpeq\t%0, %1, %2";
529 return "fcmpeq\t%1, %2";
531 [(set_attr "type" "fpcmp")])
533 (define_insn "*cmpsf_fp"
534 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
535 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
536 (match_operand:SF 2 "register_operand" "f")))]
540 return "fcmps\t%0, %1, %2";
541 return "fcmps\t%1, %2";
543 [(set_attr "type" "fpcmp")])
545 (define_insn "*cmpdf_fp"
546 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
547 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
548 (match_operand:DF 2 "register_operand" "e")))]
552 return "fcmpd\t%0, %1, %2";
553 return "fcmpd\t%1, %2";
555 [(set_attr "type" "fpcmp")
556 (set_attr "fptype" "double")])
558 (define_insn "*cmptf_fp"
559 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
560 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
561 (match_operand:TF 2 "register_operand" "e")))]
562 "TARGET_FPU && TARGET_HARD_QUAD"
565 return "fcmpq\t%0, %1, %2";
566 return "fcmpq\t%1, %2";
568 [(set_attr "type" "fpcmp")])
570 ;; Next come the scc insns.
572 (define_expand "cstoresi4"
573 [(use (match_operator 1 "comparison_operator"
574 [(match_operand:SI 2 "compare_operand" "")
575 (match_operand:SI 3 "arith_operand" "")]))
576 (clobber (match_operand:SI 0 "register_operand"))]
579 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
580 operands[2] = force_reg (SImode, operands[2]);
581 if (emit_scc_insn (operands)) DONE; else FAIL;
584 (define_expand "cstoredi4"
585 [(use (match_operator 1 "comparison_operator"
586 [(match_operand:DI 2 "compare_operand" "")
587 (match_operand:DI 3 "arith_operand" "")]))
588 (clobber (match_operand:SI 0 "register_operand"))]
591 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
592 operands[2] = force_reg (DImode, operands[2]);
593 if (emit_scc_insn (operands)) DONE; else FAIL;
596 (define_expand "cstore<F:mode>4"
597 [(use (match_operator 1 "comparison_operator"
598 [(match_operand:F 2 "register_operand" "")
599 (match_operand:F 3 "register_operand" "")]))
600 (clobber (match_operand:SI 0 "register_operand"))]
602 { if (emit_scc_insn (operands)) DONE; else FAIL; })
606 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
607 ;; generate addcc/subcc instructions.
609 (define_expand "seqsi_special"
611 (xor:SI (match_operand:SI 1 "register_operand" "")
612 (match_operand:SI 2 "register_operand" "")))
613 (parallel [(set (match_operand:SI 0 "register_operand" "")
614 (eq:SI (match_dup 3) (const_int 0)))
615 (clobber (reg:CC CC_REG))])]
617 { operands[3] = gen_reg_rtx (SImode); })
619 (define_expand "seqdi_special"
621 (xor:DI (match_operand:DI 1 "register_operand" "")
622 (match_operand:DI 2 "register_operand" "")))
623 (set (match_operand:SI 0 "register_operand" "")
624 (eq:SI (match_dup 3) (const_int 0)))]
626 { operands[3] = gen_reg_rtx (DImode); })
628 (define_expand "snesi_special"
630 (xor:SI (match_operand:SI 1 "register_operand" "")
631 (match_operand:SI 2 "register_operand" "")))
632 (parallel [(set (match_operand:SI 0 "register_operand" "")
633 (ne:SI (match_dup 3) (const_int 0)))
634 (clobber (reg:CC CC_REG))])]
636 { operands[3] = gen_reg_rtx (SImode); })
638 (define_expand "snedi_special"
640 (xor:DI (match_operand:DI 1 "register_operand" "")
641 (match_operand:DI 2 "register_operand" "")))
642 (set (match_operand:SI 0 "register_operand" "")
643 (ne:SI (match_dup 3) (const_int 0)))]
645 { operands[3] = gen_reg_rtx (DImode); })
648 ;; Now the DEFINE_INSNs for the scc cases.
650 ;; The SEQ and SNE patterns are special because they can be done
651 ;; without any branching and do not involve a COMPARE. We want
652 ;; them to always use the splits below so the results can be
655 (define_insn_and_split "*snesi_zero"
656 [(set (match_operand:SI 0 "register_operand" "=r")
657 (ne:SI (match_operand:SI 1 "register_operand" "r")
659 (clobber (reg:CC CC_REG))]
663 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
665 (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
667 [(set_attr "length" "2")])
669 (define_insn_and_split "*neg_snesi_zero"
670 [(set (match_operand:SI 0 "register_operand" "=r")
671 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
673 (clobber (reg:CC CC_REG))]
677 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
679 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
681 [(set_attr "length" "2")])
683 (define_insn_and_split "*snesi_zero_extend"
684 [(set (match_operand:DI 0 "register_operand" "=r")
685 (ne:DI (match_operand:SI 1 "register_operand" "r")
687 (clobber (reg:CC CC_REG))]
691 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
694 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
696 (ltu:SI (reg:CC_NOOV CC_REG)
699 [(set_attr "length" "2")])
701 (define_insn_and_split "*snedi_zero"
702 [(set (match_operand:DI 0 "register_operand" "=&r")
703 (ne:DI (match_operand:DI 1 "register_operand" "r")
707 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
708 [(set (match_dup 0) (const_int 0))
709 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
714 [(set_attr "length" "2")])
716 (define_insn_and_split "*neg_snedi_zero"
717 [(set (match_operand:DI 0 "register_operand" "=&r")
718 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
722 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
723 [(set (match_dup 0) (const_int 0))
724 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
729 [(set_attr "length" "2")])
731 (define_insn_and_split "*snedi_zero_trunc"
732 [(set (match_operand:SI 0 "register_operand" "=&r")
733 (ne:SI (match_operand:DI 1 "register_operand" "r")
737 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
738 [(set (match_dup 0) (const_int 0))
739 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
744 [(set_attr "length" "2")])
746 (define_insn_and_split "*seqsi_zero"
747 [(set (match_operand:SI 0 "register_operand" "=r")
748 (eq:SI (match_operand:SI 1 "register_operand" "r")
750 (clobber (reg:CC CC_REG))]
754 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
756 (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
758 [(set_attr "length" "2")])
760 (define_insn_and_split "*neg_seqsi_zero"
761 [(set (match_operand:SI 0 "register_operand" "=r")
762 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
764 (clobber (reg:CC CC_REG))]
768 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
770 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
772 [(set_attr "length" "2")])
774 (define_insn_and_split "*seqsi_zero_extend"
775 [(set (match_operand:DI 0 "register_operand" "=r")
776 (eq:DI (match_operand:SI 1 "register_operand" "r")
778 (clobber (reg:CC CC_REG))]
782 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
785 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
787 (ltu:SI (reg:CC_NOOV CC_REG)
790 [(set_attr "length" "2")])
792 (define_insn_and_split "*seqdi_zero"
793 [(set (match_operand:DI 0 "register_operand" "=&r")
794 (eq:DI (match_operand:DI 1 "register_operand" "r")
798 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
799 [(set (match_dup 0) (const_int 0))
800 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
805 [(set_attr "length" "2")])
807 (define_insn_and_split "*neg_seqdi_zero"
808 [(set (match_operand:DI 0 "register_operand" "=&r")
809 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
813 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
814 [(set (match_dup 0) (const_int 0))
815 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
820 [(set_attr "length" "2")])
822 (define_insn_and_split "*seqdi_zero_trunc"
823 [(set (match_operand:SI 0 "register_operand" "=&r")
824 (eq:SI (match_operand:DI 1 "register_operand" "r")
828 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
829 [(set (match_dup 0) (const_int 0))
830 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
835 [(set_attr "length" "2")])
837 ;; We can also do (x + (i == 0)) and related, so put them in.
838 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
841 (define_insn_and_split "*x_plus_i_ne_0"
842 [(set (match_operand:SI 0 "register_operand" "=r")
843 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
845 (match_operand:SI 2 "register_operand" "r")))
846 (clobber (reg:CC CC_REG))]
850 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
852 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
855 [(set_attr "length" "2")])
857 (define_insn_and_split "*x_minus_i_ne_0"
858 [(set (match_operand:SI 0 "register_operand" "=r")
859 (minus:SI (match_operand:SI 2 "register_operand" "r")
860 (ne:SI (match_operand:SI 1 "register_operand" "r")
862 (clobber (reg:CC CC_REG))]
866 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
868 (set (match_dup 0) (minus:SI (match_dup 2)
869 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
871 [(set_attr "length" "2")])
873 (define_insn_and_split "*x_plus_i_eq_0"
874 [(set (match_operand:SI 0 "register_operand" "=r")
875 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
877 (match_operand:SI 2 "register_operand" "r")))
878 (clobber (reg:CC CC_REG))]
882 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
884 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
887 [(set_attr "length" "2")])
889 (define_insn_and_split "*x_minus_i_eq_0"
890 [(set (match_operand:SI 0 "register_operand" "=r")
891 (minus:SI (match_operand:SI 2 "register_operand" "r")
892 (eq:SI (match_operand:SI 1 "register_operand" "r")
894 (clobber (reg:CC CC_REG))]
898 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
900 (set (match_dup 0) (minus:SI (match_dup 2)
901 (geu:SI (reg:CC CC_REG) (const_int 0))))]
903 [(set_attr "length" "2")])
905 ;; We can also do GEU and LTU directly, but these operate after a compare.
906 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
909 (define_insn "*sltu_insn"
910 [(set (match_operand:SI 0 "register_operand" "=r")
911 (ltu:SI (reg:CC CC_REG) (const_int 0)))]
914 [(set_attr "type" "ialuX")])
916 (define_insn "*neg_sltu_insn"
917 [(set (match_operand:SI 0 "register_operand" "=r")
918 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
921 [(set_attr "type" "ialuX")])
923 ;; ??? Combine should canonicalize these next two to the same pattern.
924 (define_insn "*neg_sltu_minus_x"
925 [(set (match_operand:SI 0 "register_operand" "=r")
926 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
927 (match_operand:SI 1 "arith_operand" "rI")))]
930 [(set_attr "type" "ialuX")])
932 (define_insn "*neg_sltu_plus_x"
933 [(set (match_operand:SI 0 "register_operand" "=r")
934 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
935 (match_operand:SI 1 "arith_operand" "rI"))))]
938 [(set_attr "type" "ialuX")])
940 (define_insn "*sgeu_insn"
941 [(set (match_operand:SI 0 "register_operand" "=r")
942 (geu:SI (reg:CC CC_REG) (const_int 0)))]
945 [(set_attr "type" "ialuX")])
947 (define_insn "*neg_sgeu_insn"
948 [(set (match_operand:SI 0 "register_operand" "=r")
949 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
952 [(set_attr "type" "ialuX")])
954 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
955 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
958 (define_insn "*sltu_plus_x"
959 [(set (match_operand:SI 0 "register_operand" "=r")
960 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
961 (match_operand:SI 1 "arith_operand" "rI")))]
964 [(set_attr "type" "ialuX")])
966 (define_insn "*sltu_plus_x_plus_y"
967 [(set (match_operand:SI 0 "register_operand" "=r")
968 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
969 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
970 (match_operand:SI 2 "arith_operand" "rI"))))]
973 [(set_attr "type" "ialuX")])
975 (define_insn "*x_minus_sltu"
976 [(set (match_operand:SI 0 "register_operand" "=r")
977 (minus:SI (match_operand:SI 1 "register_operand" "r")
978 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
981 [(set_attr "type" "ialuX")])
983 ;; ??? Combine should canonicalize these next two to the same pattern.
984 (define_insn "*x_minus_y_minus_sltu"
985 [(set (match_operand:SI 0 "register_operand" "=r")
986 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
987 (match_operand:SI 2 "arith_operand" "rI"))
988 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
991 [(set_attr "type" "ialuX")])
993 (define_insn "*x_minus_sltu_plus_y"
994 [(set (match_operand:SI 0 "register_operand" "=r")
995 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
996 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
997 (match_operand:SI 2 "arith_operand" "rI"))))]
1000 [(set_attr "type" "ialuX")])
1002 (define_insn "*sgeu_plus_x"
1003 [(set (match_operand:SI 0 "register_operand" "=r")
1004 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1005 (match_operand:SI 1 "register_operand" "r")))]
1008 [(set_attr "type" "ialuX")])
1010 (define_insn "*x_minus_sgeu"
1011 [(set (match_operand:SI 0 "register_operand" "=r")
1012 (minus:SI (match_operand:SI 1 "register_operand" "r")
1013 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1016 [(set_attr "type" "ialuX")])
1019 [(set (match_operand:SI 0 "register_operand" "")
1020 (match_operator:SI 2 "noov_compare_operator"
1021 [(match_operand 1 "icc_or_fcc_register_operand" "")
1024 && REGNO (operands[1]) == SPARC_ICC_REG
1025 && (GET_MODE (operands[1]) == CCXmode
1026 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1027 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1028 [(set (match_dup 0) (const_int 0))
1030 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1036 ;; These control RTL generation for conditional jump insns
1038 (define_expand "cbranchcc4"
1040 (if_then_else (match_operator 0 "comparison_operator"
1041 [(match_operand 1 "compare_operand" "")
1042 (match_operand 2 "const_zero_operand" "")])
1043 (label_ref (match_operand 3 "" ""))
1048 (define_expand "cbranchsi4"
1049 [(use (match_operator 0 "comparison_operator"
1050 [(match_operand:SI 1 "compare_operand" "")
1051 (match_operand:SI 2 "arith_operand" "")]))
1052 (use (match_operand 3 ""))]
1055 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1056 operands[1] = force_reg (SImode, operands[1]);
1057 emit_conditional_branch_insn (operands);
1061 (define_expand "cbranchdi4"
1062 [(use (match_operator 0 "comparison_operator"
1063 [(match_operand:DI 1 "compare_operand" "")
1064 (match_operand:DI 2 "arith_operand" "")]))
1065 (use (match_operand 3 ""))]
1068 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1069 operands[1] = force_reg (DImode, operands[1]);
1070 emit_conditional_branch_insn (operands);
1074 (define_expand "cbranch<F:mode>4"
1075 [(use (match_operator 0 "comparison_operator"
1076 [(match_operand:F 1 "register_operand" "")
1077 (match_operand:F 2 "register_operand" "")]))
1078 (use (match_operand 3 ""))]
1080 { emit_conditional_branch_insn (operands); DONE; })
1083 ;; Now match both normal and inverted jump.
1085 ;; XXX fpcmp nop braindamage
1086 (define_insn "*normal_branch"
1088 (if_then_else (match_operator 0 "noov_compare_operator"
1089 [(reg CC_REG) (const_int 0)])
1090 (label_ref (match_operand 1 "" ""))
1094 return output_cbranch (operands[0], operands[1], 1, 0,
1095 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1098 [(set_attr "type" "branch")
1099 (set_attr "branch_type" "icc")])
1101 ;; XXX fpcmp nop braindamage
1102 (define_insn "*inverted_branch"
1104 (if_then_else (match_operator 0 "noov_compare_operator"
1105 [(reg CC_REG) (const_int 0)])
1107 (label_ref (match_operand 1 "" ""))))]
1110 return output_cbranch (operands[0], operands[1], 1, 1,
1111 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1114 [(set_attr "type" "branch")
1115 (set_attr "branch_type" "icc")])
1117 ;; XXX fpcmp nop braindamage
1118 (define_insn "*normal_fp_branch"
1120 (if_then_else (match_operator 1 "comparison_operator"
1121 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1123 (label_ref (match_operand 2 "" ""))
1127 return output_cbranch (operands[1], operands[2], 2, 0,
1128 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1131 [(set_attr "type" "branch")
1132 (set_attr "branch_type" "fcc")])
1134 ;; XXX fpcmp nop braindamage
1135 (define_insn "*inverted_fp_branch"
1137 (if_then_else (match_operator 1 "comparison_operator"
1138 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1141 (label_ref (match_operand 2 "" ""))))]
1144 return output_cbranch (operands[1], operands[2], 2, 1,
1145 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1148 [(set_attr "type" "branch")
1149 (set_attr "branch_type" "fcc")])
1151 ;; XXX fpcmp nop braindamage
1152 (define_insn "*normal_fpe_branch"
1154 (if_then_else (match_operator 1 "comparison_operator"
1155 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1157 (label_ref (match_operand 2 "" ""))
1161 return output_cbranch (operands[1], operands[2], 2, 0,
1162 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1165 [(set_attr "type" "branch")
1166 (set_attr "branch_type" "fcc")])
1168 ;; XXX fpcmp nop braindamage
1169 (define_insn "*inverted_fpe_branch"
1171 (if_then_else (match_operator 1 "comparison_operator"
1172 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1175 (label_ref (match_operand 2 "" ""))))]
1178 return output_cbranch (operands[1], operands[2], 2, 1,
1179 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1182 [(set_attr "type" "branch")
1183 (set_attr "branch_type" "fcc")])
1185 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1186 ;; in the architecture.
1188 ;; There are no 32 bit brreg insns.
1191 (define_insn "*normal_int_branch_sp64"
1193 (if_then_else (match_operator 0 "v9_register_compare_operator"
1194 [(match_operand:DI 1 "register_operand" "r")
1196 (label_ref (match_operand 2 "" ""))
1200 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1201 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1204 [(set_attr "type" "branch")
1205 (set_attr "branch_type" "reg")])
1208 (define_insn "*inverted_int_branch_sp64"
1210 (if_then_else (match_operator 0 "v9_register_compare_operator"
1211 [(match_operand:DI 1 "register_operand" "r")
1214 (label_ref (match_operand 2 "" ""))))]
1217 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1218 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1221 [(set_attr "type" "branch")
1222 (set_attr "branch_type" "reg")])
1225 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1226 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1227 ;; that adds the PC value at the call point to register #(operand 3).
1229 (define_insn "load_pcrel_sym<P:mode>"
1230 [(set (match_operand:P 0 "register_operand" "=r")
1231 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1232 (match_operand:P 2 "call_address_operand" "")
1233 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1234 (clobber (reg:P O7_REG))]
1235 "REGNO (operands[0]) == INTVAL (operands[3])"
1237 if (flag_delayed_branch)
1238 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1240 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1242 [(set (attr "type") (const_string "multi"))
1243 (set (attr "length")
1244 (if_then_else (eq_attr "delayed_branch" "true")
1249 ;; Integer move instructions
1251 (define_expand "movqi"
1252 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1253 (match_operand:QI 1 "general_operand" ""))]
1256 if (sparc_expand_move (QImode, operands))
1260 (define_insn "*movqi_insn"
1261 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1262 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1263 "(register_operand (operands[0], QImode)
1264 || register_or_zero_operand (operands[1], QImode))"
1269 [(set_attr "type" "*,load,store")
1270 (set_attr "us3load_type" "*,3cycle,*")])
1272 (define_expand "movhi"
1273 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1274 (match_operand:HI 1 "general_operand" ""))]
1277 if (sparc_expand_move (HImode, operands))
1281 (define_insn "*movhi_insn"
1282 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1283 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1284 "(register_operand (operands[0], HImode)
1285 || register_or_zero_operand (operands[1], HImode))"
1288 sethi\t%%hi(%a1), %0
1291 [(set_attr "type" "*,*,load,store")
1292 (set_attr "us3load_type" "*,*,3cycle,*")])
1294 ;; We always work with constants here.
1295 (define_insn "*movhi_lo_sum"
1296 [(set (match_operand:HI 0 "register_operand" "=r")
1297 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1298 (match_operand:HI 2 "small_int_operand" "I")))]
1302 (define_expand "movsi"
1303 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1304 (match_operand:SI 1 "general_operand" ""))]
1307 if (sparc_expand_move (SImode, operands))
1311 (define_insn "*movsi_insn"
1312 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d,d")
1313 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J,P"))]
1314 "(register_operand (operands[0], SImode)
1315 || register_or_zero_or_all_ones_operand (operands[1], SImode))"
1318 sethi\t%%hi(%a1), %0
1326 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")])
1328 (define_insn "*movsi_lo_sum"
1329 [(set (match_operand:SI 0 "register_operand" "=r")
1330 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1331 (match_operand:SI 2 "immediate_operand" "in")))]
1333 "or\t%1, %%lo(%a2), %0")
1335 (define_insn "*movsi_high"
1336 [(set (match_operand:SI 0 "register_operand" "=r")
1337 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1339 "sethi\t%%hi(%a1), %0")
1341 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1342 ;; so that CSE won't optimize the address computation away.
1343 (define_insn "movsi_lo_sum_pic"
1344 [(set (match_operand:SI 0 "register_operand" "=r")
1345 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1346 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1349 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1350 return "xor\t%1, %%gdop_lox10(%a2), %0";
1352 return "or\t%1, %%lo(%a2), %0";
1356 (define_insn "movsi_high_pic"
1357 [(set (match_operand:SI 0 "register_operand" "=r")
1358 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1359 "flag_pic && check_pic (1)"
1361 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1362 return "sethi\t%%gdop_hix22(%a1), %0";
1364 return "sethi\t%%hi(%a1), %0";
1368 (define_insn "movsi_pic_gotdata_op"
1369 [(set (match_operand:SI 0 "register_operand" "=r")
1370 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1371 (match_operand:SI 2 "register_operand" "r")
1372 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1373 "flag_pic && check_pic (1)"
1375 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1376 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1378 return "ld\t[%1 + %2], %0";
1381 [(set_attr "type" "load")])
1383 (define_expand "movsi_pic_label_ref"
1384 [(set (match_dup 3) (high:SI
1385 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1386 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1387 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1388 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1389 (set (match_operand:SI 0 "register_operand" "=r")
1390 (minus:SI (match_dup 5) (match_dup 4)))]
1393 crtl->uses_pic_offset_table = 1;
1394 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1395 if (!can_create_pseudo_p ())
1397 operands[3] = operands[0];
1398 operands[4] = operands[0];
1402 operands[3] = gen_reg_rtx (SImode);
1403 operands[4] = gen_reg_rtx (SImode);
1405 operands[5] = pic_offset_table_rtx;
1408 (define_insn "*movsi_high_pic_label_ref"
1409 [(set (match_operand:SI 0 "register_operand" "=r")
1411 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1412 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1414 "sethi\t%%hi(%a2-(%a1-.)), %0")
1416 (define_insn "*movsi_lo_sum_pic_label_ref"
1417 [(set (match_operand:SI 0 "register_operand" "=r")
1418 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1419 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1420 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1422 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1424 ;; Set up the PIC register for VxWorks.
1426 (define_expand "vxworks_load_got"
1428 (high:SI (match_dup 1)))
1430 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1432 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1433 "TARGET_VXWORKS_RTP"
1435 operands[0] = pic_offset_table_rtx;
1436 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1437 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1440 (define_expand "movdi"
1441 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1442 (match_operand:DI 1 "general_operand" ""))]
1445 if (sparc_expand_move (DImode, operands))
1449 ;; Be careful, fmovd does not exist when !v9.
1450 ;; We match MEM moves directly when we have correct even
1451 ;; numbered registers, but fall into splits otherwise.
1452 ;; The constraint ordering here is really important to
1453 ;; avoid insane problems in reload, especially for patterns
1456 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1457 ;; (const_int -5016)))
1461 (define_insn "*movdi_insn_sp32"
1462 [(set (match_operand:DI 0 "nonimmediate_operand"
1463 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1464 (match_operand:DI 1 "input_operand"
1465 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1467 && (register_operand (operands[0], DImode)
1468 || register_or_zero_operand (operands[1], DImode))"
1482 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1483 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1485 (define_insn "*movdi_insn_sp32_v9"
1486 [(set (match_operand:DI 0 "nonimmediate_operand"
1487 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1488 (match_operand:DI 1 "input_operand"
1489 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1492 && (register_operand (operands[0], DImode)
1493 || register_or_zero_operand (operands[1], DImode))"
1510 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1511 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1512 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1514 (define_insn "*movdi_insn_sp64"
1515 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b,b")
1516 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J,P"))]
1518 && (register_operand (operands[0], DImode)
1519 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1522 sethi\t%%hi(%a1), %0
1530 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")
1531 (set_attr "fptype" "*,*,*,*,double,*,*,double,double")])
1533 (define_expand "movdi_pic_label_ref"
1534 [(set (match_dup 3) (high:DI
1535 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1536 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1537 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1538 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1539 (set (match_operand:DI 0 "register_operand" "=r")
1540 (minus:DI (match_dup 5) (match_dup 4)))]
1541 "TARGET_ARCH64 && flag_pic"
1543 crtl->uses_pic_offset_table = 1;
1544 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1545 if (!can_create_pseudo_p ())
1547 operands[3] = operands[0];
1548 operands[4] = operands[0];
1552 operands[3] = gen_reg_rtx (DImode);
1553 operands[4] = gen_reg_rtx (DImode);
1555 operands[5] = pic_offset_table_rtx;
1558 (define_insn "*movdi_high_pic_label_ref"
1559 [(set (match_operand:DI 0 "register_operand" "=r")
1561 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1562 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1563 "TARGET_ARCH64 && flag_pic"
1564 "sethi\t%%hi(%a2-(%a1-.)), %0")
1566 (define_insn "*movdi_lo_sum_pic_label_ref"
1567 [(set (match_operand:DI 0 "register_operand" "=r")
1568 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1569 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1570 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1571 "TARGET_ARCH64 && flag_pic"
1572 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1574 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1575 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1577 (define_insn "movdi_lo_sum_pic"
1578 [(set (match_operand:DI 0 "register_operand" "=r")
1579 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1580 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1581 "TARGET_ARCH64 && flag_pic"
1583 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1584 return "xor\t%1, %%gdop_lox10(%a2), %0";
1586 return "or\t%1, %%lo(%a2), %0";
1590 (define_insn "movdi_high_pic"
1591 [(set (match_operand:DI 0 "register_operand" "=r")
1592 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1593 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1595 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1596 return "sethi\t%%gdop_hix22(%a1), %0";
1598 return "sethi\t%%hi(%a1), %0";
1602 (define_insn "movdi_pic_gotdata_op"
1603 [(set (match_operand:DI 0 "register_operand" "=r")
1604 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1605 (match_operand:DI 2 "register_operand" "r")
1606 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1607 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1609 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1610 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1612 return "ldx\t[%1 + %2], %0";
1615 [(set_attr "type" "load")])
1617 (define_insn "*sethi_di_medlow_embmedany_pic"
1618 [(set (match_operand:DI 0 "register_operand" "=r")
1619 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1620 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1621 "sethi\t%%hi(%a1), %0")
1623 (define_insn "*sethi_di_medlow"
1624 [(set (match_operand:DI 0 "register_operand" "=r")
1625 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1626 "TARGET_CM_MEDLOW && check_pic (1)"
1627 "sethi\t%%hi(%a1), %0")
1629 (define_insn "*losum_di_medlow"
1630 [(set (match_operand:DI 0 "register_operand" "=r")
1631 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1632 (match_operand:DI 2 "symbolic_operand" "")))]
1634 "or\t%1, %%lo(%a2), %0")
1636 (define_insn "seth44"
1637 [(set (match_operand:DI 0 "register_operand" "=r")
1638 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1640 "sethi\t%%h44(%a1), %0")
1642 (define_insn "setm44"
1643 [(set (match_operand:DI 0 "register_operand" "=r")
1644 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1645 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1647 "or\t%1, %%m44(%a2), %0")
1649 (define_insn "setl44"
1650 [(set (match_operand:DI 0 "register_operand" "=r")
1651 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1652 (match_operand:DI 2 "symbolic_operand" "")))]
1654 "or\t%1, %%l44(%a2), %0")
1656 (define_insn "sethh"
1657 [(set (match_operand:DI 0 "register_operand" "=r")
1658 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1660 "sethi\t%%hh(%a1), %0")
1662 (define_insn "setlm"
1663 [(set (match_operand:DI 0 "register_operand" "=r")
1664 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1666 "sethi\t%%lm(%a1), %0")
1668 (define_insn "sethm"
1669 [(set (match_operand:DI 0 "register_operand" "=r")
1670 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1671 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1673 "or\t%1, %%hm(%a2), %0")
1675 (define_insn "setlo"
1676 [(set (match_operand:DI 0 "register_operand" "=r")
1677 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1678 (match_operand:DI 2 "symbolic_operand" "")))]
1680 "or\t%1, %%lo(%a2), %0")
1682 (define_insn "embmedany_sethi"
1683 [(set (match_operand:DI 0 "register_operand" "=r")
1684 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1685 "TARGET_CM_EMBMEDANY && check_pic (1)"
1686 "sethi\t%%hi(%a1), %0")
1688 (define_insn "embmedany_losum"
1689 [(set (match_operand:DI 0 "register_operand" "=r")
1690 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1691 (match_operand:DI 2 "data_segment_operand" "")))]
1692 "TARGET_CM_EMBMEDANY"
1693 "add\t%1, %%lo(%a2), %0")
1695 (define_insn "embmedany_brsum"
1696 [(set (match_operand:DI 0 "register_operand" "=r")
1697 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1698 "TARGET_CM_EMBMEDANY"
1701 (define_insn "embmedany_textuhi"
1702 [(set (match_operand:DI 0 "register_operand" "=r")
1703 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1704 "TARGET_CM_EMBMEDANY && check_pic (1)"
1705 "sethi\t%%uhi(%a1), %0")
1707 (define_insn "embmedany_texthi"
1708 [(set (match_operand:DI 0 "register_operand" "=r")
1709 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1710 "TARGET_CM_EMBMEDANY && check_pic (1)"
1711 "sethi\t%%hi(%a1), %0")
1713 (define_insn "embmedany_textulo"
1714 [(set (match_operand:DI 0 "register_operand" "=r")
1715 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1716 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1717 "TARGET_CM_EMBMEDANY"
1718 "or\t%1, %%ulo(%a2), %0")
1720 (define_insn "embmedany_textlo"
1721 [(set (match_operand:DI 0 "register_operand" "=r")
1722 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1723 (match_operand:DI 2 "text_segment_operand" "")))]
1724 "TARGET_CM_EMBMEDANY"
1725 "or\t%1, %%lo(%a2), %0")
1727 ;; Now some patterns to help reload out a bit.
1728 (define_expand "reload_indi"
1729 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1730 (match_operand:DI 1 "immediate_operand" "")
1731 (match_operand:TI 2 "register_operand" "=&r")])]
1733 || TARGET_CM_EMBMEDANY)
1736 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1740 (define_expand "reload_outdi"
1741 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1742 (match_operand:DI 1 "immediate_operand" "")
1743 (match_operand:TI 2 "register_operand" "=&r")])]
1745 || TARGET_CM_EMBMEDANY)
1748 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1752 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1754 [(set (match_operand:DI 0 "register_operand" "")
1755 (match_operand:DI 1 "const_int_operand" ""))]
1756 "! TARGET_ARCH64 && reload_completed"
1757 [(clobber (const_int 0))]
1759 #if HOST_BITS_PER_WIDE_INT == 32
1760 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1761 (INTVAL (operands[1]) < 0) ?
1764 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1767 unsigned int low, high;
1769 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1770 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1771 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1773 /* Slick... but this trick loses if this subreg constant part
1774 can be done in one insn. */
1776 && ! SPARC_SETHI32_P (high)
1777 && ! SPARC_SIMM13_P (high))
1778 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1779 gen_highpart (SImode, operands[0])));
1781 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1787 [(set (match_operand:DI 0 "register_operand" "")
1788 (match_operand:DI 1 "const_double_operand" ""))]
1792 && ((GET_CODE (operands[0]) == REG
1793 && REGNO (operands[0]) < 32)
1794 || (GET_CODE (operands[0]) == SUBREG
1795 && GET_CODE (SUBREG_REG (operands[0])) == REG
1796 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1797 [(clobber (const_int 0))]
1799 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1800 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1802 /* Slick... but this trick loses if this subreg constant part
1803 can be done in one insn. */
1804 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1805 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1806 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1808 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1809 gen_highpart (SImode, operands[0])));
1813 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1814 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1820 [(set (match_operand:DI 0 "register_operand" "")
1821 (match_operand:DI 1 "register_operand" ""))]
1825 && ((GET_CODE (operands[0]) == REG
1826 && REGNO (operands[0]) < 32)
1827 || (GET_CODE (operands[0]) == SUBREG
1828 && GET_CODE (SUBREG_REG (operands[0])) == REG
1829 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1830 [(clobber (const_int 0))]
1832 rtx set_dest = operands[0];
1833 rtx set_src = operands[1];
1837 dest1 = gen_highpart (SImode, set_dest);
1838 dest2 = gen_lowpart (SImode, set_dest);
1839 src1 = gen_highpart (SImode, set_src);
1840 src2 = gen_lowpart (SImode, set_src);
1842 /* Now emit using the real source and destination we found, swapping
1843 the order if we detect overlap. */
1844 if (reg_overlap_mentioned_p (dest1, src2))
1846 emit_insn (gen_movsi (dest2, src2));
1847 emit_insn (gen_movsi (dest1, src1));
1851 emit_insn (gen_movsi (dest1, src1));
1852 emit_insn (gen_movsi (dest2, src2));
1857 ;; Now handle the cases of memory moves from/to non-even
1858 ;; DI mode register pairs.
1860 [(set (match_operand:DI 0 "register_operand" "")
1861 (match_operand:DI 1 "memory_operand" ""))]
1864 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1865 [(clobber (const_int 0))]
1867 rtx word0 = adjust_address (operands[1], SImode, 0);
1868 rtx word1 = adjust_address (operands[1], SImode, 4);
1869 rtx high_part = gen_highpart (SImode, operands[0]);
1870 rtx low_part = gen_lowpart (SImode, operands[0]);
1872 if (reg_overlap_mentioned_p (high_part, word1))
1874 emit_insn (gen_movsi (low_part, word1));
1875 emit_insn (gen_movsi (high_part, word0));
1879 emit_insn (gen_movsi (high_part, word0));
1880 emit_insn (gen_movsi (low_part, word1));
1886 [(set (match_operand:DI 0 "memory_operand" "")
1887 (match_operand:DI 1 "register_operand" ""))]
1890 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1891 [(clobber (const_int 0))]
1893 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1894 gen_highpart (SImode, operands[1])));
1895 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1896 gen_lowpart (SImode, operands[1])));
1901 [(set (match_operand:DI 0 "memory_operand" "")
1902 (match_operand:DI 1 "const_zero_operand" ""))]
1906 && ! mem_min_alignment (operands[0], 8)))
1907 && offsettable_memref_p (operands[0])"
1908 [(clobber (const_int 0))]
1910 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1911 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1916 ;; Floating point and vector move instructions
1918 ;; Yes, you guessed it right, the former movsf expander.
1919 (define_expand "mov<V32:mode>"
1920 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1921 (match_operand:V32 1 "general_operand" ""))]
1922 "<V32:MODE>mode == SFmode || TARGET_VIS"
1924 if (sparc_expand_move (<V32:MODE>mode, operands))
1928 (define_insn "*movsf_insn"
1929 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,d,f,*r,*r,*r,f,*r,m,m")
1930 (match_operand:V32 1 "input_operand" "GY,ZC,f,*rRY,Q,S,m,m,f,*rGY"))]
1932 && (register_operand (operands[0], <V32:MODE>mode)
1933 || register_or_zero_or_all_ones_operand (operands[1], <V32:MODE>mode))"
1935 if (GET_CODE (operands[1]) == CONST_DOUBLE
1936 && (which_alternative == 3
1937 || which_alternative == 4
1938 || which_alternative == 5))
1943 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1944 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1945 operands[1] = GEN_INT (i);
1948 switch (which_alternative)
1951 return "fzeros\t%0";
1955 return "fmovs\t%1, %0";
1957 return "mov\t%1, %0";
1959 return "sethi\t%%hi(%a1), %0";
1964 return "ld\t%1, %0";
1967 return "st\t%r1, %0";
1972 [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1974 ;; Exactly the same as above, except that all `f' cases are deleted.
1975 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1978 (define_insn "*movsf_insn_no_fpu"
1979 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1980 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1982 && (register_operand (operands[0], SFmode)
1983 || register_or_zero_operand (operands[1], SFmode))"
1985 if (GET_CODE (operands[1]) == CONST_DOUBLE
1986 && (which_alternative == 0
1987 || which_alternative == 1
1988 || which_alternative == 2))
1993 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1994 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1995 operands[1] = GEN_INT (i);
1998 switch (which_alternative)
2001 return "mov\t%1, %0";
2003 return "sethi\t%%hi(%a1), %0";
2007 return "ld\t%1, %0";
2009 return "st\t%r1, %0";
2014 [(set_attr "type" "*,*,*,load,store")])
2016 ;; The following 3 patterns build SFmode constants in integer registers.
2018 (define_insn "*movsf_lo_sum"
2019 [(set (match_operand:SF 0 "register_operand" "=r")
2020 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2021 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2027 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2028 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2029 operands[2] = GEN_INT (i);
2030 return "or\t%1, %%lo(%a2), %0";
2033 (define_insn "*movsf_high"
2034 [(set (match_operand:SF 0 "register_operand" "=r")
2035 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2041 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2042 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2043 operands[1] = GEN_INT (i);
2044 return "sethi\t%%hi(%1), %0";
2048 [(set (match_operand:SF 0 "register_operand" "")
2049 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2050 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2051 [(set (match_dup 0) (high:SF (match_dup 1)))
2052 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2054 ;; Yes, you again guessed it right, the former movdf expander.
2055 (define_expand "mov<V64:mode>"
2056 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2057 (match_operand:V64 1 "general_operand" ""))]
2058 "<V64:MODE>mode == DFmode || TARGET_VIS"
2060 if (sparc_expand_move (<V64:MODE>mode, operands))
2064 ;; Be careful, fmovd does not exist when !v9.
2065 (define_insn "*movdf_insn_sp32"
2066 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2067 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2070 && (register_operand (operands[0], DFmode)
2071 || register_or_zero_operand (operands[1], DFmode))"
2083 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2084 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2086 (define_insn "*movdf_insn_sp32_no_fpu"
2087 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2088 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2091 && (register_operand (operands[0], DFmode)
2092 || register_or_zero_operand (operands[1], DFmode))"
2099 [(set_attr "type" "load,store,*,*,*")
2100 (set_attr "length" "*,*,2,2,2")])
2102 ;; We have available v9 double floats but not 64-bit integer registers.
2103 (define_insn "*movdf_insn_sp32_v9"
2104 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,T,W,U,T,f,*r,o")
2105 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2109 && (register_operand (operands[0], <V64:MODE>mode)
2110 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2123 [(set_attr "type" "fga,fga,fpmove,load,store,store,load,store,*,*,*")
2124 (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")
2125 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*")])
2127 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2128 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2129 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2133 && (register_operand (operands[0], DFmode)
2134 || register_or_zero_operand (operands[1], DFmode))"
2141 [(set_attr "type" "load,store,store,*,*")
2142 (set_attr "length" "*,*,*,2,2")])
2144 ;; We have available both v9 double floats and 64-bit integer registers.
2145 (define_insn "*movdf_insn_sp64"
2146 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,W,*r,*r,m,*r")
2147 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,e,*rGY,m,*rGY,DF"))]
2150 && (register_operand (operands[0], <V64:MODE>mode)
2151 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2162 [(set_attr "type" "fga,fga,fpmove,load,store,*,load,store,*")
2163 (set_attr "length" "*,*,*,*,*,*,*,*,2")
2164 (set_attr "fptype" "double,double,double,*,*,*,*,*,*")])
2166 (define_insn "*movdf_insn_sp64_no_fpu"
2167 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2168 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2171 && (register_operand (operands[0], DFmode)
2172 || register_or_zero_operand (operands[1], DFmode))"
2177 [(set_attr "type" "*,load,store")])
2179 ;; This pattern builds V64mode constants in integer registers.
2181 [(set (match_operand:V64 0 "register_operand" "")
2182 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2184 && (GET_CODE (operands[0]) == REG
2185 && REGNO (operands[0]) < 32)
2186 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2187 && reload_completed"
2188 [(clobber (const_int 0))]
2190 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2194 #if HOST_BITS_PER_WIDE_INT == 32
2197 enum machine_mode mode = GET_MODE (operands[1]);
2198 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2199 emit_insn (gen_movdi (operands[0], tem));
2204 enum machine_mode mode = GET_MODE (operands[1]);
2205 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2206 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2208 gcc_assert (GET_CODE (hi) == CONST_INT);
2209 gcc_assert (GET_CODE (lo) == CONST_INT);
2211 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2213 /* Slick... but this trick loses if this subreg constant part
2214 can be done in one insn. */
2216 && ! SPARC_SETHI32_P (INTVAL (hi))
2217 && ! SPARC_SIMM13_P (INTVAL (hi)))
2219 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2220 gen_highpart (SImode, operands[0])));
2224 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2230 ;; Ok, now the splits to handle all the multi insn and
2231 ;; mis-aligned memory address cases.
2232 ;; In these splits please take note that we must be
2233 ;; careful when V9 but not ARCH64 because the integer
2234 ;; register DFmode cases must be handled.
2236 [(set (match_operand:V64 0 "register_operand" "")
2237 (match_operand:V64 1 "register_operand" ""))]
2240 && ((GET_CODE (operands[0]) == REG
2241 && REGNO (operands[0]) < 32)
2242 || (GET_CODE (operands[0]) == SUBREG
2243 && GET_CODE (SUBREG_REG (operands[0])) == REG
2244 && REGNO (SUBREG_REG (operands[0])) < 32))))
2245 && reload_completed"
2246 [(clobber (const_int 0))]
2248 rtx set_dest = operands[0];
2249 rtx set_src = operands[1];
2252 enum machine_mode half_mode;
2254 /* We can be expanded for DFmode or integral vector modes. */
2255 if (<V64:MODE>mode == DFmode)
2260 dest1 = gen_highpart (half_mode, set_dest);
2261 dest2 = gen_lowpart (half_mode, set_dest);
2262 src1 = gen_highpart (half_mode, set_src);
2263 src2 = gen_lowpart (half_mode, set_src);
2265 /* Now emit using the real source and destination we found, swapping
2266 the order if we detect overlap. */
2267 if (reg_overlap_mentioned_p (dest1, src2))
2269 emit_move_insn_1 (dest2, src2);
2270 emit_move_insn_1 (dest1, src1);
2274 emit_move_insn_1 (dest1, src1);
2275 emit_move_insn_1 (dest2, src2);
2281 [(set (match_operand:V64 0 "register_operand" "")
2282 (match_operand:V64 1 "memory_operand" ""))]
2285 && (((REGNO (operands[0]) % 2) != 0)
2286 || ! mem_min_alignment (operands[1], 8))
2287 && offsettable_memref_p (operands[1])"
2288 [(clobber (const_int 0))]
2290 enum machine_mode half_mode;
2293 /* We can be expanded for DFmode or integral vector modes. */
2294 if (<V64:MODE>mode == DFmode)
2299 word0 = adjust_address (operands[1], half_mode, 0);
2300 word1 = adjust_address (operands[1], half_mode, 4);
2302 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2304 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2305 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2309 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2310 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2316 [(set (match_operand:V64 0 "memory_operand" "")
2317 (match_operand:V64 1 "register_operand" ""))]
2320 && (((REGNO (operands[1]) % 2) != 0)
2321 || ! mem_min_alignment (operands[0], 8))
2322 && offsettable_memref_p (operands[0])"
2323 [(clobber (const_int 0))]
2325 enum machine_mode half_mode;
2328 /* We can be expanded for DFmode or integral vector modes. */
2329 if (<V64:MODE>mode == DFmode)
2334 word0 = adjust_address (operands[0], half_mode, 0);
2335 word1 = adjust_address (operands[0], half_mode, 4);
2337 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2338 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2343 [(set (match_operand:V64 0 "memory_operand" "")
2344 (match_operand:V64 1 "const_zero_operand" ""))]
2348 && ! mem_min_alignment (operands[0], 8)))
2349 && offsettable_memref_p (operands[0])"
2350 [(clobber (const_int 0))]
2352 enum machine_mode half_mode;
2355 /* We can be expanded for DFmode or integral vector modes. */
2356 if (<V64:MODE>mode == DFmode)
2361 dest1 = adjust_address (operands[0], half_mode, 0);
2362 dest2 = adjust_address (operands[0], half_mode, 4);
2364 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2365 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2370 [(set (match_operand:V64 0 "register_operand" "")
2371 (match_operand:V64 1 "const_zero_operand" ""))]
2374 && ((GET_CODE (operands[0]) == REG
2375 && REGNO (operands[0]) < 32)
2376 || (GET_CODE (operands[0]) == SUBREG
2377 && GET_CODE (SUBREG_REG (operands[0])) == REG
2378 && REGNO (SUBREG_REG (operands[0])) < 32))"
2379 [(clobber (const_int 0))]
2381 enum machine_mode half_mode;
2382 rtx set_dest = operands[0];
2385 /* We can be expanded for DFmode or integral vector modes. */
2386 if (<V64:MODE>mode == DFmode)
2391 dest1 = gen_highpart (half_mode, set_dest);
2392 dest2 = gen_lowpart (half_mode, set_dest);
2393 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2394 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2398 (define_expand "movtf"
2399 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2400 (match_operand:TF 1 "general_operand" ""))]
2403 if (sparc_expand_move (TFmode, operands))
2407 (define_insn "*movtf_insn_sp32"
2408 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2409 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2412 && (register_operand (operands[0], TFmode)
2413 || register_or_zero_operand (operands[1], TFmode))"
2415 [(set_attr "length" "4")])
2417 ;; Exactly the same as above, except that all `e' cases are deleted.
2418 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2421 (define_insn "*movtf_insn_sp32_no_fpu"
2422 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2423 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2426 && (register_operand (operands[0], TFmode)
2427 || register_or_zero_operand (operands[1], TFmode))"
2429 [(set_attr "length" "4")])
2431 (define_insn "*movtf_insn_sp64"
2432 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2433 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2436 && ! TARGET_HARD_QUAD
2437 && (register_operand (operands[0], TFmode)
2438 || register_or_zero_operand (operands[1], TFmode))"
2440 [(set_attr "length" "2")])
2442 (define_insn "*movtf_insn_sp64_hq"
2443 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2444 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2448 && (register_operand (operands[0], TFmode)
2449 || register_or_zero_operand (operands[1], TFmode))"
2457 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2458 (set_attr "length" "2,*,*,*,2,2")])
2460 (define_insn "*movtf_insn_sp64_no_fpu"
2461 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2462 (match_operand:TF 1 "input_operand" "orG,rG"))]
2465 && (register_operand (operands[0], TFmode)
2466 || register_or_zero_operand (operands[1], TFmode))"
2468 [(set_attr "length" "2")])
2470 ;; Now all the splits to handle multi-insn TF mode moves.
2472 [(set (match_operand:TF 0 "register_operand" "")
2473 (match_operand:TF 1 "register_operand" ""))]
2477 && ! TARGET_HARD_QUAD)
2478 || ! fp_register_operand (operands[0], TFmode))"
2479 [(clobber (const_int 0))]
2481 rtx set_dest = operands[0];
2482 rtx set_src = operands[1];
2486 dest1 = gen_df_reg (set_dest, 0);
2487 dest2 = gen_df_reg (set_dest, 1);
2488 src1 = gen_df_reg (set_src, 0);
2489 src2 = gen_df_reg (set_src, 1);
2491 /* Now emit using the real source and destination we found, swapping
2492 the order if we detect overlap. */
2493 if (reg_overlap_mentioned_p (dest1, src2))
2495 emit_insn (gen_movdf (dest2, src2));
2496 emit_insn (gen_movdf (dest1, src1));
2500 emit_insn (gen_movdf (dest1, src1));
2501 emit_insn (gen_movdf (dest2, src2));
2507 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2508 (match_operand:TF 1 "const_zero_operand" ""))]
2510 [(clobber (const_int 0))]
2512 rtx set_dest = operands[0];
2515 switch (GET_CODE (set_dest))
2518 dest1 = gen_df_reg (set_dest, 0);
2519 dest2 = gen_df_reg (set_dest, 1);
2522 dest1 = adjust_address (set_dest, DFmode, 0);
2523 dest2 = adjust_address (set_dest, DFmode, 8);
2529 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2530 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2535 [(set (match_operand:TF 0 "register_operand" "")
2536 (match_operand:TF 1 "memory_operand" ""))]
2538 && offsettable_memref_p (operands[1])
2540 || ! TARGET_HARD_QUAD
2541 || ! fp_register_operand (operands[0], TFmode)))"
2542 [(clobber (const_int 0))]
2544 rtx word0 = adjust_address (operands[1], DFmode, 0);
2545 rtx word1 = adjust_address (operands[1], DFmode, 8);
2546 rtx set_dest, dest1, dest2;
2548 set_dest = operands[0];
2550 dest1 = gen_df_reg (set_dest, 0);
2551 dest2 = gen_df_reg (set_dest, 1);
2553 /* Now output, ordering such that we don't clobber any registers
2554 mentioned in the address. */
2555 if (reg_overlap_mentioned_p (dest1, word1))
2558 emit_insn (gen_movdf (dest2, word1));
2559 emit_insn (gen_movdf (dest1, word0));
2563 emit_insn (gen_movdf (dest1, word0));
2564 emit_insn (gen_movdf (dest2, word1));
2570 [(set (match_operand:TF 0 "memory_operand" "")
2571 (match_operand:TF 1 "register_operand" ""))]
2573 && offsettable_memref_p (operands[0])
2575 || ! TARGET_HARD_QUAD
2576 || ! fp_register_operand (operands[1], TFmode)))"
2577 [(clobber (const_int 0))]
2579 rtx set_src = operands[1];
2581 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2582 gen_df_reg (set_src, 0)));
2583 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2584 gen_df_reg (set_src, 1)));
2589 ;; SPARC-V9 conditional move instructions
2591 ;; We can handle larger constants here for some flavors, but for now we keep
2592 ;; it simple and only allow those constants supported by all flavors.
2593 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2594 ;; 3 contains the constant if one is present, but we handle either for
2595 ;; generality (sparc.c puts a constant in operand 2).
2597 (define_expand "mov<I:mode>cc"
2598 [(set (match_operand:I 0 "register_operand" "")
2599 (if_then_else:I (match_operand 1 "comparison_operator" "")
2600 (match_operand:I 2 "arith10_operand" "")
2601 (match_operand:I 3 "arith10_operand" "")))]
2602 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2604 enum rtx_code code = GET_CODE (operands[1]);
2607 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2611 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2613 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2614 GET_CODE (operands[1]));
2616 if (XEXP (operands[1], 1) == const0_rtx
2617 && GET_CODE (XEXP (operands[1], 0)) == REG
2618 && GET_MODE (XEXP (operands[1], 0)) == DImode
2619 && v9_regcmp_p (code))
2620 cc_reg = XEXP (operands[1], 0);
2622 cc_reg = gen_compare_reg (operands[1]);
2624 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2627 (define_expand "mov<F:mode>cc"
2628 [(set (match_operand:F 0 "register_operand" "")
2629 (if_then_else:F (match_operand 1 "comparison_operator" "")
2630 (match_operand:F 2 "register_operand" "")
2631 (match_operand:F 3 "register_operand" "")))]
2632 "TARGET_V9 && TARGET_FPU"
2634 enum rtx_code code = GET_CODE (operands[1]);
2637 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2641 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2643 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2644 GET_CODE (operands[1]));
2646 if (XEXP (operands[1], 1) == const0_rtx
2647 && GET_CODE (XEXP (operands[1], 0)) == REG
2648 && GET_MODE (XEXP (operands[1], 0)) == DImode
2649 && v9_regcmp_p (code))
2650 cc_reg = XEXP (operands[1], 0);
2652 cc_reg = gen_compare_reg (operands[1]);
2654 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2657 ;; Conditional move define_insns
2659 (define_insn "*mov<I:mode>_cc_v9"
2660 [(set (match_operand:I 0 "register_operand" "=r,r")
2661 (if_then_else:I (match_operator 1 "comparison_operator"
2662 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2664 (match_operand:I 3 "arith11_operand" "rL,0")
2665 (match_operand:I 4 "arith11_operand" "0,rL")))]
2666 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2669 mov%c1\t%x2, %4, %0"
2670 [(set_attr "type" "cmove")])
2672 (define_insn "*mov<I:mode>_cc_reg_sp64"
2673 [(set (match_operand:I 0 "register_operand" "=r,r")
2674 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2675 [(match_operand:DI 2 "register_operand" "r,r")
2677 (match_operand:I 3 "arith10_operand" "rM,0")
2678 (match_operand:I 4 "arith10_operand" "0,rM")))]
2681 movr%D1\t%2, %r3, %0
2682 movr%d1\t%2, %r4, %0"
2683 [(set_attr "type" "cmove")])
2685 (define_insn "*movsf_cc_v9"
2686 [(set (match_operand:SF 0 "register_operand" "=f,f")
2687 (if_then_else:SF (match_operator 1 "comparison_operator"
2688 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2690 (match_operand:SF 3 "register_operand" "f,0")
2691 (match_operand:SF 4 "register_operand" "0,f")))]
2692 "TARGET_V9 && TARGET_FPU"
2694 fmovs%C1\t%x2, %3, %0
2695 fmovs%c1\t%x2, %4, %0"
2696 [(set_attr "type" "fpcmove")])
2698 (define_insn "*movsf_cc_reg_sp64"
2699 [(set (match_operand:SF 0 "register_operand" "=f,f")
2700 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2701 [(match_operand:DI 2 "register_operand" "r,r")
2703 (match_operand:SF 3 "register_operand" "f,0")
2704 (match_operand:SF 4 "register_operand" "0,f")))]
2705 "TARGET_ARCH64 && TARGET_FPU"
2707 fmovrs%D1\t%2, %3, %0
2708 fmovrs%d1\t%2, %4, %0"
2709 [(set_attr "type" "fpcrmove")])
2711 ;; Named because invoked by movtf_cc_v9
2712 (define_insn "movdf_cc_v9"
2713 [(set (match_operand:DF 0 "register_operand" "=e,e")
2714 (if_then_else:DF (match_operator 1 "comparison_operator"
2715 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2717 (match_operand:DF 3 "register_operand" "e,0")
2718 (match_operand:DF 4 "register_operand" "0,e")))]
2719 "TARGET_V9 && TARGET_FPU"
2721 fmovd%C1\t%x2, %3, %0
2722 fmovd%c1\t%x2, %4, %0"
2723 [(set_attr "type" "fpcmove")
2724 (set_attr "fptype" "double")])
2726 ;; Named because invoked by movtf_cc_reg_sp64
2727 (define_insn "movdf_cc_reg_sp64"
2728 [(set (match_operand:DF 0 "register_operand" "=e,e")
2729 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2730 [(match_operand:DI 2 "register_operand" "r,r")
2732 (match_operand:DF 3 "register_operand" "e,0")
2733 (match_operand:DF 4 "register_operand" "0,e")))]
2734 "TARGET_ARCH64 && TARGET_FPU"
2736 fmovrd%D1\t%2, %3, %0
2737 fmovrd%d1\t%2, %4, %0"
2738 [(set_attr "type" "fpcrmove")
2739 (set_attr "fptype" "double")])
2741 (define_insn "*movtf_cc_hq_v9"
2742 [(set (match_operand:TF 0 "register_operand" "=e,e")
2743 (if_then_else:TF (match_operator 1 "comparison_operator"
2744 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2746 (match_operand:TF 3 "register_operand" "e,0")
2747 (match_operand:TF 4 "register_operand" "0,e")))]
2748 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2750 fmovq%C1\t%x2, %3, %0
2751 fmovq%c1\t%x2, %4, %0"
2752 [(set_attr "type" "fpcmove")])
2754 (define_insn "*movtf_cc_reg_hq_sp64"
2755 [(set (match_operand:TF 0 "register_operand" "=e,e")
2756 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2757 [(match_operand:DI 2 "register_operand" "r,r")
2759 (match_operand:TF 3 "register_operand" "e,0")
2760 (match_operand:TF 4 "register_operand" "0,e")))]
2761 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2763 fmovrq%D1\t%2, %3, %0
2764 fmovrq%d1\t%2, %4, %0"
2765 [(set_attr "type" "fpcrmove")])
2767 (define_insn_and_split "*movtf_cc_v9"
2768 [(set (match_operand:TF 0 "register_operand" "=e,e")
2769 (if_then_else:TF (match_operator 1 "comparison_operator"
2770 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2772 (match_operand:TF 3 "register_operand" "e,0")
2773 (match_operand:TF 4 "register_operand" "0,e")))]
2774 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2776 "&& reload_completed"
2777 [(clobber (const_int 0))]
2779 rtx set_dest = operands[0];
2780 rtx set_srca = operands[3];
2781 rtx set_srcb = operands[4];
2782 int third = rtx_equal_p (set_dest, set_srca);
2784 rtx srca1, srca2, srcb1, srcb2;
2786 dest1 = gen_df_reg (set_dest, 0);
2787 dest2 = gen_df_reg (set_dest, 1);
2788 srca1 = gen_df_reg (set_srca, 0);
2789 srca2 = gen_df_reg (set_srca, 1);
2790 srcb1 = gen_df_reg (set_srcb, 0);
2791 srcb2 = gen_df_reg (set_srcb, 1);
2793 /* Now emit using the real source and destination we found, swapping
2794 the order if we detect overlap. */
2795 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2796 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2798 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2799 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2803 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2804 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2808 [(set_attr "length" "2")])
2810 (define_insn_and_split "*movtf_cc_reg_sp64"
2811 [(set (match_operand:TF 0 "register_operand" "=e,e")
2812 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2813 [(match_operand:DI 2 "register_operand" "r,r")
2815 (match_operand:TF 3 "register_operand" "e,0")
2816 (match_operand:TF 4 "register_operand" "0,e")))]
2817 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2819 "&& reload_completed"
2820 [(clobber (const_int 0))]
2822 rtx set_dest = operands[0];
2823 rtx set_srca = operands[3];
2824 rtx set_srcb = operands[4];
2825 int third = rtx_equal_p (set_dest, set_srca);
2827 rtx srca1, srca2, srcb1, srcb2;
2829 dest1 = gen_df_reg (set_dest, 0);
2830 dest2 = gen_df_reg (set_dest, 1);
2831 srca1 = gen_df_reg (set_srca, 0);
2832 srca2 = gen_df_reg (set_srca, 1);
2833 srcb1 = gen_df_reg (set_srcb, 0);
2834 srcb2 = gen_df_reg (set_srcb, 1);
2836 /* Now emit using the real source and destination we found, swapping
2837 the order if we detect overlap. */
2838 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2839 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2841 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2842 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2846 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2847 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2851 [(set_attr "length" "2")])
2854 ;; Zero-extension instructions
2856 ;; These patterns originally accepted general_operands, however, slightly
2857 ;; better code is generated by only accepting register_operands, and then
2858 ;; letting combine generate the ldu[hb] insns.
2860 (define_expand "zero_extendhisi2"
2861 [(set (match_operand:SI 0 "register_operand" "")
2862 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2865 rtx temp = gen_reg_rtx (SImode);
2866 rtx shift_16 = GEN_INT (16);
2867 int op1_subbyte = 0;
2869 if (GET_CODE (operand1) == SUBREG)
2871 op1_subbyte = SUBREG_BYTE (operand1);
2872 op1_subbyte /= GET_MODE_SIZE (SImode);
2873 op1_subbyte *= GET_MODE_SIZE (SImode);
2874 operand1 = XEXP (operand1, 0);
2877 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2879 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2883 (define_insn "*zero_extendhisi2_insn"
2884 [(set (match_operand:SI 0 "register_operand" "=r")
2885 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2888 [(set_attr "type" "load")
2889 (set_attr "us3load_type" "3cycle")])
2891 (define_expand "zero_extendqihi2"
2892 [(set (match_operand:HI 0 "register_operand" "")
2893 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2897 (define_insn "*zero_extendqihi2_insn"
2898 [(set (match_operand:HI 0 "register_operand" "=r,r")
2899 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2900 "GET_CODE (operands[1]) != CONST_INT"
2904 [(set_attr "type" "*,load")
2905 (set_attr "us3load_type" "*,3cycle")])
2907 (define_expand "zero_extendqisi2"
2908 [(set (match_operand:SI 0 "register_operand" "")
2909 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2913 (define_insn "*zero_extendqisi2_insn"
2914 [(set (match_operand:SI 0 "register_operand" "=r,r")
2915 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2916 "GET_CODE (operands[1]) != CONST_INT"
2920 [(set_attr "type" "*,load")
2921 (set_attr "us3load_type" "*,3cycle")])
2923 (define_expand "zero_extendqidi2"
2924 [(set (match_operand:DI 0 "register_operand" "")
2925 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2929 (define_insn "*zero_extendqidi2_insn"
2930 [(set (match_operand:DI 0 "register_operand" "=r,r")
2931 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2932 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2936 [(set_attr "type" "*,load")
2937 (set_attr "us3load_type" "*,3cycle")])
2939 (define_expand "zero_extendhidi2"
2940 [(set (match_operand:DI 0 "register_operand" "")
2941 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2944 rtx temp = gen_reg_rtx (DImode);
2945 rtx shift_48 = GEN_INT (48);
2946 int op1_subbyte = 0;
2948 if (GET_CODE (operand1) == SUBREG)
2950 op1_subbyte = SUBREG_BYTE (operand1);
2951 op1_subbyte /= GET_MODE_SIZE (DImode);
2952 op1_subbyte *= GET_MODE_SIZE (DImode);
2953 operand1 = XEXP (operand1, 0);
2956 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2958 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2962 (define_insn "*zero_extendhidi2_insn"
2963 [(set (match_operand:DI 0 "register_operand" "=r")
2964 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2967 [(set_attr "type" "load")
2968 (set_attr "us3load_type" "3cycle")])
2970 ;; ??? Write truncdisi pattern using sra?
2972 (define_expand "zero_extendsidi2"
2973 [(set (match_operand:DI 0 "register_operand" "")
2974 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2978 (define_insn "*zero_extendsidi2_insn_sp64"
2979 [(set (match_operand:DI 0 "register_operand" "=r,r")
2980 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2981 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2985 [(set_attr "type" "shift,load")])
2987 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2988 [(set (match_operand:DI 0 "register_operand" "=r")
2989 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2992 "&& reload_completed"
2993 [(set (match_dup 2) (match_dup 3))
2994 (set (match_dup 4) (match_dup 5))]
2998 dest1 = gen_highpart (SImode, operands[0]);
2999 dest2 = gen_lowpart (SImode, operands[0]);
3001 /* Swap the order in case of overlap. */
3002 if (REGNO (dest1) == REGNO (operands[1]))
3004 operands[2] = dest2;
3005 operands[3] = operands[1];
3006 operands[4] = dest1;
3007 operands[5] = const0_rtx;
3011 operands[2] = dest1;
3012 operands[3] = const0_rtx;
3013 operands[4] = dest2;
3014 operands[5] = operands[1];
3017 [(set_attr "length" "2")])
3019 ;; Simplify comparisons of extended values.
3021 (define_insn "*cmp_zero_extendqisi2"
3022 [(set (reg:CC CC_REG)
3023 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3026 "andcc\t%0, 0xff, %%g0"
3027 [(set_attr "type" "compare")])
3029 (define_insn "*cmp_zero_qi"
3030 [(set (reg:CC CC_REG)
3031 (compare:CC (match_operand:QI 0 "register_operand" "r")
3034 "andcc\t%0, 0xff, %%g0"
3035 [(set_attr "type" "compare")])
3037 (define_insn "*cmp_zero_extendqisi2_set"
3038 [(set (reg:CC CC_REG)
3039 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3041 (set (match_operand:SI 0 "register_operand" "=r")
3042 (zero_extend:SI (match_dup 1)))]
3044 "andcc\t%1, 0xff, %0"
3045 [(set_attr "type" "compare")])
3047 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3048 [(set (reg:CC CC_REG)
3049 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3052 (set (match_operand:SI 0 "register_operand" "=r")
3053 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3055 "andcc\t%1, 0xff, %0"
3056 [(set_attr "type" "compare")])
3058 (define_insn "*cmp_zero_extendqidi2"
3059 [(set (reg:CCX CC_REG)
3060 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3063 "andcc\t%0, 0xff, %%g0"
3064 [(set_attr "type" "compare")])
3066 (define_insn "*cmp_zero_qi_sp64"
3067 [(set (reg:CCX CC_REG)
3068 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3071 "andcc\t%0, 0xff, %%g0"
3072 [(set_attr "type" "compare")])
3074 (define_insn "*cmp_zero_extendqidi2_set"
3075 [(set (reg:CCX CC_REG)
3076 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3078 (set (match_operand:DI 0 "register_operand" "=r")
3079 (zero_extend:DI (match_dup 1)))]
3081 "andcc\t%1, 0xff, %0"
3082 [(set_attr "type" "compare")])
3084 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3085 [(set (reg:CCX CC_REG)
3086 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3089 (set (match_operand:DI 0 "register_operand" "=r")
3090 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3092 "andcc\t%1, 0xff, %0"
3093 [(set_attr "type" "compare")])
3095 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3097 (define_insn "*cmp_siqi_trunc"
3098 [(set (reg:CC CC_REG)
3099 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3102 "andcc\t%0, 0xff, %%g0"
3103 [(set_attr "type" "compare")])
3105 (define_insn "*cmp_siqi_trunc_set"
3106 [(set (reg:CC CC_REG)
3107 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3109 (set (match_operand:QI 0 "register_operand" "=r")
3110 (subreg:QI (match_dup 1) 3))]
3112 "andcc\t%1, 0xff, %0"
3113 [(set_attr "type" "compare")])
3115 (define_insn "*cmp_diqi_trunc"
3116 [(set (reg:CC CC_REG)
3117 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3120 "andcc\t%0, 0xff, %%g0"
3121 [(set_attr "type" "compare")])
3123 (define_insn "*cmp_diqi_trunc_set"
3124 [(set (reg:CC CC_REG)
3125 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3127 (set (match_operand:QI 0 "register_operand" "=r")
3128 (subreg:QI (match_dup 1) 7))]
3130 "andcc\t%1, 0xff, %0"
3131 [(set_attr "type" "compare")])
3134 ;; Sign-extension instructions
3136 ;; These patterns originally accepted general_operands, however, slightly
3137 ;; better code is generated by only accepting register_operands, and then
3138 ;; letting combine generate the lds[hb] insns.
3140 (define_expand "extendhisi2"
3141 [(set (match_operand:SI 0 "register_operand" "")
3142 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3145 rtx temp = gen_reg_rtx (SImode);
3146 rtx shift_16 = GEN_INT (16);
3147 int op1_subbyte = 0;
3149 if (GET_CODE (operand1) == SUBREG)
3151 op1_subbyte = SUBREG_BYTE (operand1);
3152 op1_subbyte /= GET_MODE_SIZE (SImode);
3153 op1_subbyte *= GET_MODE_SIZE (SImode);
3154 operand1 = XEXP (operand1, 0);
3157 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3159 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3163 (define_insn "*sign_extendhisi2_insn"
3164 [(set (match_operand:SI 0 "register_operand" "=r")
3165 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3168 [(set_attr "type" "sload")
3169 (set_attr "us3load_type" "3cycle")])
3171 (define_expand "extendqihi2"
3172 [(set (match_operand:HI 0 "register_operand" "")
3173 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3176 rtx temp = gen_reg_rtx (SImode);
3177 rtx shift_24 = GEN_INT (24);
3178 int op1_subbyte = 0;
3179 int op0_subbyte = 0;
3181 if (GET_CODE (operand1) == SUBREG)
3183 op1_subbyte = SUBREG_BYTE (operand1);
3184 op1_subbyte /= GET_MODE_SIZE (SImode);
3185 op1_subbyte *= GET_MODE_SIZE (SImode);
3186 operand1 = XEXP (operand1, 0);
3188 if (GET_CODE (operand0) == SUBREG)
3190 op0_subbyte = SUBREG_BYTE (operand0);
3191 op0_subbyte /= GET_MODE_SIZE (SImode);
3192 op0_subbyte *= GET_MODE_SIZE (SImode);
3193 operand0 = XEXP (operand0, 0);
3195 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3197 if (GET_MODE (operand0) != SImode)
3198 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3199 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3203 (define_insn "*sign_extendqihi2_insn"
3204 [(set (match_operand:HI 0 "register_operand" "=r")
3205 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3208 [(set_attr "type" "sload")
3209 (set_attr "us3load_type" "3cycle")])
3211 (define_expand "extendqisi2"
3212 [(set (match_operand:SI 0 "register_operand" "")
3213 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3216 rtx temp = gen_reg_rtx (SImode);
3217 rtx shift_24 = GEN_INT (24);
3218 int op1_subbyte = 0;
3220 if (GET_CODE (operand1) == SUBREG)
3222 op1_subbyte = SUBREG_BYTE (operand1);
3223 op1_subbyte /= GET_MODE_SIZE (SImode);
3224 op1_subbyte *= GET_MODE_SIZE (SImode);
3225 operand1 = XEXP (operand1, 0);
3228 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3230 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3234 (define_insn "*sign_extendqisi2_insn"
3235 [(set (match_operand:SI 0 "register_operand" "=r")
3236 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3239 [(set_attr "type" "sload")
3240 (set_attr "us3load_type" "3cycle")])
3242 (define_expand "extendqidi2"
3243 [(set (match_operand:DI 0 "register_operand" "")
3244 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3247 rtx temp = gen_reg_rtx (DImode);
3248 rtx shift_56 = GEN_INT (56);
3249 int op1_subbyte = 0;
3251 if (GET_CODE (operand1) == SUBREG)
3253 op1_subbyte = SUBREG_BYTE (operand1);
3254 op1_subbyte /= GET_MODE_SIZE (DImode);
3255 op1_subbyte *= GET_MODE_SIZE (DImode);
3256 operand1 = XEXP (operand1, 0);
3259 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3261 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3265 (define_insn "*sign_extendqidi2_insn"
3266 [(set (match_operand:DI 0 "register_operand" "=r")
3267 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3270 [(set_attr "type" "sload")
3271 (set_attr "us3load_type" "3cycle")])
3273 (define_expand "extendhidi2"
3274 [(set (match_operand:DI 0 "register_operand" "")
3275 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3278 rtx temp = gen_reg_rtx (DImode);
3279 rtx shift_48 = GEN_INT (48);
3280 int op1_subbyte = 0;
3282 if (GET_CODE (operand1) == SUBREG)
3284 op1_subbyte = SUBREG_BYTE (operand1);
3285 op1_subbyte /= GET_MODE_SIZE (DImode);
3286 op1_subbyte *= GET_MODE_SIZE (DImode);
3287 operand1 = XEXP (operand1, 0);
3290 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3292 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3296 (define_insn "*sign_extendhidi2_insn"
3297 [(set (match_operand:DI 0 "register_operand" "=r")
3298 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3301 [(set_attr "type" "sload")
3302 (set_attr "us3load_type" "3cycle")])
3304 (define_expand "extendsidi2"
3305 [(set (match_operand:DI 0 "register_operand" "")
3306 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3310 (define_insn "*sign_extendsidi2_insn"
3311 [(set (match_operand:DI 0 "register_operand" "=r,r")
3312 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3317 [(set_attr "type" "shift,sload")
3318 (set_attr "us3load_type" "*,3cycle")])
3321 ;; Special pattern for optimizing bit-field compares. This is needed
3322 ;; because combine uses this as a canonical form.
3324 (define_insn "*cmp_zero_extract"
3325 [(set (reg:CC CC_REG)
3327 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3328 (match_operand:SI 1 "small_int_operand" "I")
3329 (match_operand:SI 2 "small_int_operand" "I"))
3331 "INTVAL (operands[2]) > 19"
3333 int len = INTVAL (operands[1]);
3334 int pos = 32 - INTVAL (operands[2]) - len;
3335 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3336 operands[1] = GEN_INT (mask);
3337 return "andcc\t%0, %1, %%g0";
3339 [(set_attr "type" "compare")])
3341 (define_insn "*cmp_zero_extract_sp64"
3342 [(set (reg:CCX CC_REG)
3344 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3345 (match_operand:SI 1 "small_int_operand" "I")
3346 (match_operand:SI 2 "small_int_operand" "I"))
3348 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3350 int len = INTVAL (operands[1]);
3351 int pos = 64 - INTVAL (operands[2]) - len;
3352 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3353 operands[1] = GEN_INT (mask);
3354 return "andcc\t%0, %1, %%g0";
3356 [(set_attr "type" "compare")])
3359 ;; Conversions between float, double and long double.
3361 (define_insn "extendsfdf2"
3362 [(set (match_operand:DF 0 "register_operand" "=e")
3364 (match_operand:SF 1 "register_operand" "f")))]
3367 [(set_attr "type" "fp")
3368 (set_attr "fptype" "double")])
3370 (define_expand "extendsftf2"
3371 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3373 (match_operand:SF 1 "register_operand" "")))]
3374 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3375 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3377 (define_insn "*extendsftf2_hq"
3378 [(set (match_operand:TF 0 "register_operand" "=e")
3380 (match_operand:SF 1 "register_operand" "f")))]
3381 "TARGET_FPU && TARGET_HARD_QUAD"
3383 [(set_attr "type" "fp")])
3385 (define_expand "extenddftf2"
3386 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3388 (match_operand:DF 1 "register_operand" "")))]
3389 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3390 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3392 (define_insn "*extenddftf2_hq"
3393 [(set (match_operand:TF 0 "register_operand" "=e")
3395 (match_operand:DF 1 "register_operand" "e")))]
3396 "TARGET_FPU && TARGET_HARD_QUAD"
3398 [(set_attr "type" "fp")])
3400 (define_insn "truncdfsf2"
3401 [(set (match_operand:SF 0 "register_operand" "=f")
3403 (match_operand:DF 1 "register_operand" "e")))]
3406 [(set_attr "type" "fp")
3407 (set_attr "fptype" "double")])
3409 (define_expand "trunctfsf2"
3410 [(set (match_operand:SF 0 "register_operand" "")
3412 (match_operand:TF 1 "general_operand" "")))]
3413 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3414 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3416 (define_insn "*trunctfsf2_hq"
3417 [(set (match_operand:SF 0 "register_operand" "=f")
3419 (match_operand:TF 1 "register_operand" "e")))]
3420 "TARGET_FPU && TARGET_HARD_QUAD"
3422 [(set_attr "type" "fp")])
3424 (define_expand "trunctfdf2"
3425 [(set (match_operand:DF 0 "register_operand" "")
3427 (match_operand:TF 1 "general_operand" "")))]
3428 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3429 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3431 (define_insn "*trunctfdf2_hq"
3432 [(set (match_operand:DF 0 "register_operand" "=e")
3434 (match_operand:TF 1 "register_operand" "e")))]
3435 "TARGET_FPU && TARGET_HARD_QUAD"
3437 [(set_attr "type" "fp")])
3440 ;; Conversion between fixed point and floating point.
3442 (define_insn "floatsisf2"
3443 [(set (match_operand:SF 0 "register_operand" "=f")
3444 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3447 [(set_attr "type" "fp")
3448 (set_attr "fptype" "double")])
3450 (define_insn "floatsidf2"
3451 [(set (match_operand:DF 0 "register_operand" "=e")
3452 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3455 [(set_attr "type" "fp")
3456 (set_attr "fptype" "double")])
3458 (define_expand "floatsitf2"
3459 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3460 (float:TF (match_operand:SI 1 "register_operand" "")))]
3461 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3462 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3464 (define_insn "*floatsitf2_hq"
3465 [(set (match_operand:TF 0 "register_operand" "=e")
3466 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3467 "TARGET_FPU && TARGET_HARD_QUAD"
3469 [(set_attr "type" "fp")])
3471 (define_expand "floatunssitf2"
3472 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3473 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3474 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3475 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3477 ;; Now the same for 64 bit sources.
3479 (define_insn "floatdisf2"
3480 [(set (match_operand:SF 0 "register_operand" "=f")
3481 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3482 "TARGET_V9 && TARGET_FPU"
3484 [(set_attr "type" "fp")
3485 (set_attr "fptype" "double")])
3487 (define_expand "floatunsdisf2"
3488 [(use (match_operand:SF 0 "register_operand" ""))
3489 (use (match_operand:DI 1 "general_operand" ""))]
3490 "TARGET_ARCH64 && TARGET_FPU"
3491 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3493 (define_insn "floatdidf2"
3494 [(set (match_operand:DF 0 "register_operand" "=e")
3495 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3496 "TARGET_V9 && TARGET_FPU"
3498 [(set_attr "type" "fp")
3499 (set_attr "fptype" "double")])
3501 (define_expand "floatunsdidf2"
3502 [(use (match_operand:DF 0 "register_operand" ""))
3503 (use (match_operand:DI 1 "general_operand" ""))]
3504 "TARGET_ARCH64 && TARGET_FPU"
3505 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3507 (define_expand "floatditf2"
3508 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3509 (float:TF (match_operand:DI 1 "register_operand" "")))]
3510 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3511 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3513 (define_insn "*floatditf2_hq"
3514 [(set (match_operand:TF 0 "register_operand" "=e")
3515 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3516 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3518 [(set_attr "type" "fp")])
3520 (define_expand "floatunsditf2"
3521 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3522 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3523 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3524 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3526 ;; Convert a float to an actual integer.
3527 ;; Truncation is performed as part of the conversion.
3529 (define_insn "fix_truncsfsi2"
3530 [(set (match_operand:SI 0 "register_operand" "=f")
3531 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3534 [(set_attr "type" "fp")
3535 (set_attr "fptype" "double")])
3537 (define_insn "fix_truncdfsi2"
3538 [(set (match_operand:SI 0 "register_operand" "=f")
3539 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3542 [(set_attr "type" "fp")
3543 (set_attr "fptype" "double")])
3545 (define_expand "fix_trunctfsi2"
3546 [(set (match_operand:SI 0 "register_operand" "")
3547 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3548 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3549 "emit_tfmode_cvt (FIX, operands); DONE;")
3551 (define_insn "*fix_trunctfsi2_hq"
3552 [(set (match_operand:SI 0 "register_operand" "=f")
3553 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3554 "TARGET_FPU && TARGET_HARD_QUAD"
3556 [(set_attr "type" "fp")])
3558 (define_expand "fixuns_trunctfsi2"
3559 [(set (match_operand:SI 0 "register_operand" "")
3560 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3561 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3562 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3564 ;; Now the same, for V9 targets
3566 (define_insn "fix_truncsfdi2"
3567 [(set (match_operand:DI 0 "register_operand" "=e")
3568 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3569 "TARGET_V9 && TARGET_FPU"
3571 [(set_attr "type" "fp")
3572 (set_attr "fptype" "double")])
3574 (define_expand "fixuns_truncsfdi2"
3575 [(use (match_operand:DI 0 "register_operand" ""))
3576 (use (match_operand:SF 1 "general_operand" ""))]
3577 "TARGET_ARCH64 && TARGET_FPU"
3578 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3580 (define_insn "fix_truncdfdi2"
3581 [(set (match_operand:DI 0 "register_operand" "=e")
3582 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3583 "TARGET_V9 && TARGET_FPU"
3585 [(set_attr "type" "fp")
3586 (set_attr "fptype" "double")])
3588 (define_expand "fixuns_truncdfdi2"
3589 [(use (match_operand:DI 0 "register_operand" ""))
3590 (use (match_operand:DF 1 "general_operand" ""))]
3591 "TARGET_ARCH64 && TARGET_FPU"
3592 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3594 (define_expand "fix_trunctfdi2"
3595 [(set (match_operand:DI 0 "register_operand" "")
3596 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3597 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3598 "emit_tfmode_cvt (FIX, operands); DONE;")
3600 (define_insn "*fix_trunctfdi2_hq"
3601 [(set (match_operand:DI 0 "register_operand" "=e")
3602 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3603 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3605 [(set_attr "type" "fp")])
3607 (define_expand "fixuns_trunctfdi2"
3608 [(set (match_operand:DI 0 "register_operand" "")
3609 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3610 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3611 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3614 ;; Integer addition/subtraction instructions.
3616 (define_expand "adddi3"
3617 [(set (match_operand:DI 0 "register_operand" "")
3618 (plus:DI (match_operand:DI 1 "register_operand" "")
3619 (match_operand:DI 2 "arith_double_add_operand" "")))]
3622 if (! TARGET_ARCH64)
3624 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3625 gen_rtx_SET (VOIDmode, operands[0],
3626 gen_rtx_PLUS (DImode, operands[1],
3628 gen_rtx_CLOBBER (VOIDmode,
3629 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3634 (define_insn_and_split "*adddi3_insn_sp32"
3635 [(set (match_operand:DI 0 "register_operand" "=r")
3636 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3637 (match_operand:DI 2 "arith_double_operand" "rHI")))
3638 (clobber (reg:CC CC_REG))]
3641 "&& reload_completed"
3642 [(parallel [(set (reg:CC_NOOV CC_REG)
3643 (compare:CC_NOOV (plus:SI (match_dup 4)
3647 (plus:SI (match_dup 4) (match_dup 5)))])
3649 (plus:SI (plus:SI (match_dup 7)
3651 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3653 operands[3] = gen_lowpart (SImode, operands[0]);
3654 operands[4] = gen_lowpart (SImode, operands[1]);
3655 operands[5] = gen_lowpart (SImode, operands[2]);
3656 operands[6] = gen_highpart (SImode, operands[0]);
3657 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3658 #if HOST_BITS_PER_WIDE_INT == 32
3659 if (GET_CODE (operands[2]) == CONST_INT)
3661 if (INTVAL (operands[2]) < 0)
3662 operands[8] = constm1_rtx;
3664 operands[8] = const0_rtx;
3668 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3670 [(set_attr "length" "2")])
3672 ;; LTU here means "carry set"
3674 [(set (match_operand:SI 0 "register_operand" "=r")
3675 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3676 (match_operand:SI 2 "arith_operand" "rI"))
3677 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3680 [(set_attr "type" "ialuX")])
3682 (define_insn_and_split "*addx_extend_sp32"
3683 [(set (match_operand:DI 0 "register_operand" "=r")
3684 (zero_extend:DI (plus:SI (plus:SI
3685 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3686 (match_operand:SI 2 "arith_operand" "rI"))
3687 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3690 "&& reload_completed"
3691 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3692 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3693 (set (match_dup 4) (const_int 0))]
3694 "operands[3] = gen_lowpart (SImode, operands[0]);
3695 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3696 [(set_attr "length" "2")])
3698 (define_insn "*addx_extend_sp64"
3699 [(set (match_operand:DI 0 "register_operand" "=r")
3700 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3701 (match_operand:SI 2 "arith_operand" "rI"))
3702 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3705 [(set_attr "type" "ialuX")])
3707 (define_insn_and_split "*adddi3_extend_sp32"
3708 [(set (match_operand:DI 0 "register_operand" "=r")
3709 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3710 (match_operand:DI 2 "register_operand" "r")))
3711 (clobber (reg:CC CC_REG))]
3714 "&& reload_completed"
3715 [(parallel [(set (reg:CC_NOOV CC_REG)
3716 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3718 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3720 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3721 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3722 "operands[3] = gen_lowpart (SImode, operands[2]);
3723 operands[4] = gen_highpart (SImode, operands[2]);
3724 operands[5] = gen_lowpart (SImode, operands[0]);
3725 operands[6] = gen_highpart (SImode, operands[0]);"
3726 [(set_attr "length" "2")])
3728 (define_insn "*adddi3_sp64"
3729 [(set (match_operand:DI 0 "register_operand" "=r,r")
3730 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3731 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3737 (define_insn "addsi3"
3738 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3739 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3740 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3745 fpadd32s\t%1, %2, %0"
3746 [(set_attr "type" "*,*,fga")
3747 (set_attr "fptype" "*,*,single")])
3749 (define_insn "*cmp_cc_plus"
3750 [(set (reg:CC_NOOV CC_REG)
3751 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3752 (match_operand:SI 1 "arith_operand" "rI"))
3755 "addcc\t%0, %1, %%g0"
3756 [(set_attr "type" "compare")])
3758 (define_insn "*cmp_ccx_plus"
3759 [(set (reg:CCX_NOOV CC_REG)
3760 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3761 (match_operand:DI 1 "arith_operand" "rI"))
3764 "addcc\t%0, %1, %%g0"
3765 [(set_attr "type" "compare")])
3767 (define_insn "*cmp_cc_plus_set"
3768 [(set (reg:CC_NOOV CC_REG)
3769 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3770 (match_operand:SI 2 "arith_operand" "rI"))
3772 (set (match_operand:SI 0 "register_operand" "=r")
3773 (plus:SI (match_dup 1) (match_dup 2)))]
3776 [(set_attr "type" "compare")])
3778 (define_insn "*cmp_ccx_plus_set"
3779 [(set (reg:CCX_NOOV CC_REG)
3780 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3781 (match_operand:DI 2 "arith_operand" "rI"))
3783 (set (match_operand:DI 0 "register_operand" "=r")
3784 (plus:DI (match_dup 1) (match_dup 2)))]
3787 [(set_attr "type" "compare")])
3789 (define_expand "subdi3"
3790 [(set (match_operand:DI 0 "register_operand" "")
3791 (minus:DI (match_operand:DI 1 "register_operand" "")
3792 (match_operand:DI 2 "arith_double_add_operand" "")))]
3795 if (! TARGET_ARCH64)
3797 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3798 gen_rtx_SET (VOIDmode, operands[0],
3799 gen_rtx_MINUS (DImode, operands[1],
3801 gen_rtx_CLOBBER (VOIDmode,
3802 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3807 (define_insn_and_split "*subdi3_insn_sp32"
3808 [(set (match_operand:DI 0 "register_operand" "=r")
3809 (minus:DI (match_operand:DI 1 "register_operand" "r")
3810 (match_operand:DI 2 "arith_double_operand" "rHI")))
3811 (clobber (reg:CC CC_REG))]
3814 "&& reload_completed"
3815 [(parallel [(set (reg:CC_NOOV CC_REG)
3816 (compare:CC_NOOV (minus:SI (match_dup 4)
3820 (minus:SI (match_dup 4) (match_dup 5)))])
3822 (minus:SI (minus:SI (match_dup 7)
3824 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3826 operands[3] = gen_lowpart (SImode, operands[0]);
3827 operands[4] = gen_lowpart (SImode, operands[1]);
3828 operands[5] = gen_lowpart (SImode, operands[2]);
3829 operands[6] = gen_highpart (SImode, operands[0]);
3830 operands[7] = gen_highpart (SImode, operands[1]);
3831 #if HOST_BITS_PER_WIDE_INT == 32
3832 if (GET_CODE (operands[2]) == CONST_INT)
3834 if (INTVAL (operands[2]) < 0)
3835 operands[8] = constm1_rtx;
3837 operands[8] = const0_rtx;
3841 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3843 [(set_attr "length" "2")])
3845 ;; LTU here means "carry set"
3847 [(set (match_operand:SI 0 "register_operand" "=r")
3848 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3849 (match_operand:SI 2 "arith_operand" "rI"))
3850 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3853 [(set_attr "type" "ialuX")])
3855 (define_insn "*subx_extend_sp64"
3856 [(set (match_operand:DI 0 "register_operand" "=r")
3857 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3858 (match_operand:SI 2 "arith_operand" "rI"))
3859 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3862 [(set_attr "type" "ialuX")])
3864 (define_insn_and_split "*subx_extend"
3865 [(set (match_operand:DI 0 "register_operand" "=r")
3866 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3867 (match_operand:SI 2 "arith_operand" "rI"))
3868 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3871 "&& reload_completed"
3872 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3873 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3874 (set (match_dup 4) (const_int 0))]
3875 "operands[3] = gen_lowpart (SImode, operands[0]);
3876 operands[4] = gen_highpart (SImode, operands[0]);"
3877 [(set_attr "length" "2")])
3879 (define_insn_and_split "*subdi3_extend_sp32"
3880 [(set (match_operand:DI 0 "register_operand" "=r")
3881 (minus:DI (match_operand:DI 1 "register_operand" "r")
3882 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3883 (clobber (reg:CC CC_REG))]
3886 "&& reload_completed"
3887 [(parallel [(set (reg:CC_NOOV CC_REG)
3888 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3890 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3892 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3893 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3894 "operands[3] = gen_lowpart (SImode, operands[1]);
3895 operands[4] = gen_highpart (SImode, operands[1]);
3896 operands[5] = gen_lowpart (SImode, operands[0]);
3897 operands[6] = gen_highpart (SImode, operands[0]);"
3898 [(set_attr "length" "2")])
3900 (define_insn "*subdi3_sp64"
3901 [(set (match_operand:DI 0 "register_operand" "=r,r")
3902 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3903 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3909 (define_insn "subsi3"
3910 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3911 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3912 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3917 fpsub32s\t%1, %2, %0"
3918 [(set_attr "type" "*,*,fga")
3919 (set_attr "fptype" "*,*,single")])
3921 (define_insn "*cmp_minus_cc"
3922 [(set (reg:CC_NOOV CC_REG)
3923 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3924 (match_operand:SI 1 "arith_operand" "rI"))
3927 "subcc\t%r0, %1, %%g0"
3928 [(set_attr "type" "compare")])
3930 (define_insn "*cmp_minus_ccx"
3931 [(set (reg:CCX_NOOV CC_REG)
3932 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3933 (match_operand:DI 1 "arith_operand" "rI"))
3936 "subcc\t%0, %1, %%g0"
3937 [(set_attr "type" "compare")])
3939 (define_insn "cmp_minus_cc_set"
3940 [(set (reg:CC_NOOV CC_REG)
3941 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3942 (match_operand:SI 2 "arith_operand" "rI"))
3944 (set (match_operand:SI 0 "register_operand" "=r")
3945 (minus:SI (match_dup 1) (match_dup 2)))]
3947 "subcc\t%r1, %2, %0"
3948 [(set_attr "type" "compare")])
3950 (define_insn "*cmp_minus_ccx_set"
3951 [(set (reg:CCX_NOOV CC_REG)
3952 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3953 (match_operand:DI 2 "arith_operand" "rI"))
3955 (set (match_operand:DI 0 "register_operand" "=r")
3956 (minus:DI (match_dup 1) (match_dup 2)))]
3959 [(set_attr "type" "compare")])
3962 ;; Integer multiply/divide instructions.
3964 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3965 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3967 (define_insn "mulsi3"
3968 [(set (match_operand:SI 0 "register_operand" "=r")
3969 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3970 (match_operand:SI 2 "arith_operand" "rI")))]
3973 [(set_attr "type" "imul")])
3975 (define_expand "muldi3"
3976 [(set (match_operand:DI 0 "register_operand" "")
3977 (mult:DI (match_operand:DI 1 "arith_operand" "")
3978 (match_operand:DI 2 "arith_operand" "")))]
3979 "TARGET_ARCH64 || TARGET_V8PLUS"
3983 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3988 (define_insn "*muldi3_sp64"
3989 [(set (match_operand:DI 0 "register_operand" "=r")
3990 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3991 (match_operand:DI 2 "arith_operand" "rI")))]
3994 [(set_attr "type" "imul")])
3996 ;; V8plus wide multiply.
3998 (define_insn "muldi3_v8plus"
3999 [(set (match_operand:DI 0 "register_operand" "=r,h")
4000 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4001 (match_operand:DI 2 "arith_operand" "rI,rI")))
4002 (clobber (match_scratch:SI 3 "=&h,X"))
4003 (clobber (match_scratch:SI 4 "=&h,X"))]
4006 if (sparc_check_64 (operands[1], insn) <= 0)
4007 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4008 if (which_alternative == 1)
4009 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4010 if (GET_CODE (operands[2]) == CONST_INT)
4012 if (which_alternative == 1)
4013 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4015 return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4017 else if (rtx_equal_p (operands[1], operands[2]))
4019 if (which_alternative == 1)
4020 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4022 return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %3, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4024 if (sparc_check_64 (operands[2], insn) <= 0)
4025 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4026 if (which_alternative == 1)
4027 return "or\t%L1, %H1, %H1\n\tsllx\t%H2, 32, %L1\n\tor\t%L2, %L1, %L1\n\tmulx\t%H1, %L1, %L0\;srlx\t%L0, 32, %H0";
4029 return "sllx\t%H1, 32, %3\n\tsllx\t%H2, 32, %4\n\tor\t%L1, %3, %3\n\tor\t%L2, %4, %4\n\tmulx\t%3, %4, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4031 [(set_attr "type" "multi")
4032 (set_attr "length" "9,8")])
4034 (define_insn "*cmp_mul_set"
4035 [(set (reg:CC CC_REG)
4036 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4037 (match_operand:SI 2 "arith_operand" "rI"))
4039 (set (match_operand:SI 0 "register_operand" "=r")
4040 (mult:SI (match_dup 1) (match_dup 2)))]
4041 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4042 "smulcc\t%1, %2, %0"
4043 [(set_attr "type" "imul")])
4045 (define_expand "mulsidi3"
4046 [(set (match_operand:DI 0 "register_operand" "")
4047 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4048 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4051 if (CONSTANT_P (operands[2]))
4054 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4056 else if (TARGET_ARCH32)
4057 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4060 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4066 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4071 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4072 ;; registers can hold 64-bit values in the V8plus environment.
4074 (define_insn "mulsidi3_v8plus"
4075 [(set (match_operand:DI 0 "register_operand" "=h,r")
4076 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4077 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4078 (clobber (match_scratch:SI 3 "=X,&h"))]
4081 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4082 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4083 [(set_attr "type" "multi")
4084 (set_attr "length" "2,3")])
4087 (define_insn "const_mulsidi3_v8plus"
4088 [(set (match_operand:DI 0 "register_operand" "=h,r")
4089 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4090 (match_operand:DI 2 "small_int_operand" "I,I")))
4091 (clobber (match_scratch:SI 3 "=X,&h"))]
4094 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4095 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4096 [(set_attr "type" "multi")
4097 (set_attr "length" "2,3")])
4100 (define_insn "*mulsidi3_sp32"
4101 [(set (match_operand:DI 0 "register_operand" "=r")
4102 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4103 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4106 return TARGET_SPARCLET
4107 ? "smuld\t%1, %2, %L0"
4108 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4111 (if_then_else (eq_attr "isa" "sparclet")
4112 (const_string "imul") (const_string "multi")))
4113 (set (attr "length")
4114 (if_then_else (eq_attr "isa" "sparclet")
4115 (const_int 1) (const_int 2)))])
4117 (define_insn "*mulsidi3_sp64"
4118 [(set (match_operand:DI 0 "register_operand" "=r")
4119 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4120 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4121 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4123 [(set_attr "type" "imul")])
4125 ;; Extra pattern, because sign_extend of a constant isn't valid.
4128 (define_insn "const_mulsidi3_sp32"
4129 [(set (match_operand:DI 0 "register_operand" "=r")
4130 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4131 (match_operand:DI 2 "small_int_operand" "I")))]
4134 return TARGET_SPARCLET
4135 ? "smuld\t%1, %2, %L0"
4136 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4139 (if_then_else (eq_attr "isa" "sparclet")
4140 (const_string "imul") (const_string "multi")))
4141 (set (attr "length")
4142 (if_then_else (eq_attr "isa" "sparclet")
4143 (const_int 1) (const_int 2)))])
4145 (define_insn "const_mulsidi3_sp64"
4146 [(set (match_operand:DI 0 "register_operand" "=r")
4147 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4148 (match_operand:DI 2 "small_int_operand" "I")))]
4149 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4151 [(set_attr "type" "imul")])
4153 (define_expand "smulsi3_highpart"
4154 [(set (match_operand:SI 0 "register_operand" "")
4156 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4157 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4159 "TARGET_HARD_MUL && TARGET_ARCH32"
4161 if (CONSTANT_P (operands[2]))
4165 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4171 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4176 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4177 operands[2], GEN_INT (32)));
4183 (define_insn "smulsi3_highpart_v8plus"
4184 [(set (match_operand:SI 0 "register_operand" "=h,r")
4186 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4187 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4188 (match_operand:SI 3 "small_int_operand" "I,I"))))
4189 (clobber (match_scratch:SI 4 "=X,&h"))]
4192 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4193 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4194 [(set_attr "type" "multi")
4195 (set_attr "length" "2")])
4197 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4200 [(set (match_operand:SI 0 "register_operand" "=h,r")
4203 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4204 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4205 (match_operand:SI 3 "small_int_operand" "I,I"))
4207 (clobber (match_scratch:SI 4 "=X,&h"))]
4210 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4211 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4212 [(set_attr "type" "multi")
4213 (set_attr "length" "2")])
4216 (define_insn "const_smulsi3_highpart_v8plus"
4217 [(set (match_operand:SI 0 "register_operand" "=h,r")
4219 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4220 (match_operand:DI 2 "small_int_operand" "I,I"))
4221 (match_operand:SI 3 "small_int_operand" "I,I"))))
4222 (clobber (match_scratch:SI 4 "=X,&h"))]
4225 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4226 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4227 [(set_attr "type" "multi")
4228 (set_attr "length" "2")])
4231 (define_insn "*smulsi3_highpart_sp32"
4232 [(set (match_operand:SI 0 "register_operand" "=r")
4234 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4235 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4238 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4239 [(set_attr "type" "multi")
4240 (set_attr "length" "2")])
4243 (define_insn "const_smulsi3_highpart"
4244 [(set (match_operand:SI 0 "register_operand" "=r")
4246 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4247 (match_operand:DI 2 "small_int_operand" "i"))
4250 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4251 [(set_attr "type" "multi")
4252 (set_attr "length" "2")])
4254 (define_expand "umulsidi3"
4255 [(set (match_operand:DI 0 "register_operand" "")
4256 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4257 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4260 if (CONSTANT_P (operands[2]))
4263 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4265 else if (TARGET_ARCH32)
4266 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4269 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4275 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4281 (define_insn "umulsidi3_v8plus"
4282 [(set (match_operand:DI 0 "register_operand" "=h,r")
4283 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4284 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4285 (clobber (match_scratch:SI 3 "=X,&h"))]
4288 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4289 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4290 [(set_attr "type" "multi")
4291 (set_attr "length" "2,3")])
4294 (define_insn "*umulsidi3_sp32"
4295 [(set (match_operand:DI 0 "register_operand" "=r")
4296 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4297 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4300 return TARGET_SPARCLET
4301 ? "umuld\t%1, %2, %L0"
4302 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4305 (if_then_else (eq_attr "isa" "sparclet")
4306 (const_string "imul") (const_string "multi")))
4307 (set (attr "length")
4308 (if_then_else (eq_attr "isa" "sparclet")
4309 (const_int 1) (const_int 2)))])
4311 (define_insn "*umulsidi3_sp64"
4312 [(set (match_operand:DI 0 "register_operand" "=r")
4313 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4314 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4315 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4317 [(set_attr "type" "imul")])
4319 ;; Extra pattern, because sign_extend of a constant isn't valid.
4322 (define_insn "const_umulsidi3_sp32"
4323 [(set (match_operand:DI 0 "register_operand" "=r")
4324 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4325 (match_operand:DI 2 "uns_small_int_operand" "")))]
4328 return TARGET_SPARCLET
4329 ? "umuld\t%1, %s2, %L0"
4330 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4333 (if_then_else (eq_attr "isa" "sparclet")
4334 (const_string "imul") (const_string "multi")))
4335 (set (attr "length")
4336 (if_then_else (eq_attr "isa" "sparclet")
4337 (const_int 1) (const_int 2)))])
4339 (define_insn "const_umulsidi3_sp64"
4340 [(set (match_operand:DI 0 "register_operand" "=r")
4341 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4342 (match_operand:DI 2 "uns_small_int_operand" "")))]
4343 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4345 [(set_attr "type" "imul")])
4348 (define_insn "const_umulsidi3_v8plus"
4349 [(set (match_operand:DI 0 "register_operand" "=h,r")
4350 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4351 (match_operand:DI 2 "uns_small_int_operand" "")))
4352 (clobber (match_scratch:SI 3 "=X,h"))]
4355 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4356 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4357 [(set_attr "type" "multi")
4358 (set_attr "length" "2,3")])
4360 (define_expand "umulsi3_highpart"
4361 [(set (match_operand:SI 0 "register_operand" "")
4363 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4364 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4366 "TARGET_HARD_MUL && TARGET_ARCH32"
4368 if (CONSTANT_P (operands[2]))
4372 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4378 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4383 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4384 operands[2], GEN_INT (32)));
4390 (define_insn "umulsi3_highpart_v8plus"
4391 [(set (match_operand:SI 0 "register_operand" "=h,r")
4393 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4394 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4395 (match_operand:SI 3 "small_int_operand" "I,I"))))
4396 (clobber (match_scratch:SI 4 "=X,h"))]
4399 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4400 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4401 [(set_attr "type" "multi")
4402 (set_attr "length" "2")])
4405 (define_insn "const_umulsi3_highpart_v8plus"
4406 [(set (match_operand:SI 0 "register_operand" "=h,r")
4408 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4409 (match_operand:DI 2 "uns_small_int_operand" ""))
4410 (match_operand:SI 3 "small_int_operand" "I,I"))))
4411 (clobber (match_scratch:SI 4 "=X,h"))]
4414 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4415 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4416 [(set_attr "type" "multi")
4417 (set_attr "length" "2")])
4420 (define_insn "*umulsi3_highpart_sp32"
4421 [(set (match_operand:SI 0 "register_operand" "=r")
4423 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4424 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4427 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4428 [(set_attr "type" "multi")
4429 (set_attr "length" "2")])
4432 (define_insn "const_umulsi3_highpart"
4433 [(set (match_operand:SI 0 "register_operand" "=r")
4435 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4436 (match_operand:DI 2 "uns_small_int_operand" ""))
4439 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4440 [(set_attr "type" "multi")
4441 (set_attr "length" "2")])
4443 (define_expand "divsi3"
4444 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4445 (div:SI (match_operand:SI 1 "register_operand" "")
4446 (match_operand:SI 2 "input_operand" "")))
4447 (clobber (match_scratch:SI 3 ""))])]
4448 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4452 operands[3] = gen_reg_rtx(SImode);
4453 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4454 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4460 ;; The V8 architecture specifies that there must be at least 3 instructions
4461 ;; between a write to the Y register and a use of it for correct results.
4462 ;; We try to fill one of them with a simple constant or a memory load.
4464 (define_insn "divsi3_sp32"
4465 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4466 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4467 (match_operand:SI 2 "input_operand" "rI,K,m")))
4468 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4469 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4471 output_asm_insn ("sra\t%1, 31, %3", operands);
4472 output_asm_insn ("wr\t%3, 0, %%y", operands);
4474 switch (which_alternative)
4478 return "sdiv\t%1, %2, %0";
4480 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4483 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4485 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4488 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4490 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4495 [(set_attr "type" "multi")
4496 (set (attr "length")
4497 (if_then_else (eq_attr "isa" "v9")
4498 (const_int 4) (const_int 6)))])
4500 (define_insn "divsi3_sp64"
4501 [(set (match_operand:SI 0 "register_operand" "=r")
4502 (div:SI (match_operand:SI 1 "register_operand" "r")
4503 (match_operand:SI 2 "input_operand" "rI")))
4504 (use (match_operand:SI 3 "register_operand" "r"))]
4505 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4506 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4507 [(set_attr "type" "multi")
4508 (set_attr "length" "2")])
4510 (define_insn "divdi3"
4511 [(set (match_operand:DI 0 "register_operand" "=r")
4512 (div:DI (match_operand:DI 1 "register_operand" "r")
4513 (match_operand:DI 2 "arith_operand" "rI")))]
4516 [(set_attr "type" "idiv")])
4518 (define_insn "*cmp_sdiv_cc_set"
4519 [(set (reg:CC CC_REG)
4520 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4521 (match_operand:SI 2 "arith_operand" "rI"))
4523 (set (match_operand:SI 0 "register_operand" "=r")
4524 (div:SI (match_dup 1) (match_dup 2)))
4525 (clobber (match_scratch:SI 3 "=&r"))]
4526 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4528 output_asm_insn ("sra\t%1, 31, %3", operands);
4529 output_asm_insn ("wr\t%3, 0, %%y", operands);
4532 return "sdivcc\t%1, %2, %0";
4534 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4536 [(set_attr "type" "multi")
4537 (set (attr "length")
4538 (if_then_else (eq_attr "isa" "v9")
4539 (const_int 3) (const_int 6)))])
4542 (define_expand "udivsi3"
4543 [(set (match_operand:SI 0 "register_operand" "")
4544 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4545 (match_operand:SI 2 "input_operand" "")))]
4546 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4549 ;; The V8 architecture specifies that there must be at least 3 instructions
4550 ;; between a write to the Y register and a use of it for correct results.
4551 ;; We try to fill one of them with a simple constant or a memory load.
4553 (define_insn "udivsi3_sp32"
4554 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4555 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4556 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4557 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4559 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4561 switch (which_alternative)
4565 return "udiv\t%1, %2, %0";
4567 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4570 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4572 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4575 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4577 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4580 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4582 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4587 [(set_attr "type" "multi")
4588 (set (attr "length")
4589 (if_then_else (eq_attr "isa" "v9")
4590 (const_int 3) (const_int 5)))])
4592 (define_insn "udivsi3_sp64"
4593 [(set (match_operand:SI 0 "register_operand" "=r")
4594 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4595 (match_operand:SI 2 "input_operand" "rI")))]
4596 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4597 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4598 [(set_attr "type" "multi")
4599 (set_attr "length" "2")])
4601 (define_insn "udivdi3"
4602 [(set (match_operand:DI 0 "register_operand" "=r")
4603 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4604 (match_operand:DI 2 "arith_operand" "rI")))]
4607 [(set_attr "type" "idiv")])
4609 (define_insn "*cmp_udiv_cc_set"
4610 [(set (reg:CC CC_REG)
4611 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4612 (match_operand:SI 2 "arith_operand" "rI"))
4614 (set (match_operand:SI 0 "register_operand" "=r")
4615 (udiv:SI (match_dup 1) (match_dup 2)))]
4616 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4618 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4621 return "udivcc\t%1, %2, %0";
4623 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4625 [(set_attr "type" "multi")
4626 (set (attr "length")
4627 (if_then_else (eq_attr "isa" "v9")
4628 (const_int 2) (const_int 5)))])
4630 ; sparclet multiply/accumulate insns
4632 (define_insn "*smacsi"
4633 [(set (match_operand:SI 0 "register_operand" "=r")
4634 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4635 (match_operand:SI 2 "arith_operand" "rI"))
4636 (match_operand:SI 3 "register_operand" "0")))]
4639 [(set_attr "type" "imul")])
4641 (define_insn "*smacdi"
4642 [(set (match_operand:DI 0 "register_operand" "=r")
4643 (plus:DI (mult:DI (sign_extend:DI
4644 (match_operand:SI 1 "register_operand" "%r"))
4646 (match_operand:SI 2 "register_operand" "r")))
4647 (match_operand:DI 3 "register_operand" "0")))]
4649 "smacd\t%1, %2, %L0"
4650 [(set_attr "type" "imul")])
4652 (define_insn "*umacdi"
4653 [(set (match_operand:DI 0 "register_operand" "=r")
4654 (plus:DI (mult:DI (zero_extend:DI
4655 (match_operand:SI 1 "register_operand" "%r"))
4657 (match_operand:SI 2 "register_operand" "r")))
4658 (match_operand:DI 3 "register_operand" "0")))]
4660 "umacd\t%1, %2, %L0"
4661 [(set_attr "type" "imul")])
4664 ;; Boolean instructions.
4666 ;; We define DImode `and' so with DImode `not' we can get
4667 ;; DImode `andn'. Other combinations are possible.
4669 (define_expand "and<V64I:mode>3"
4670 [(set (match_operand:V64I 0 "register_operand" "")
4671 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4672 (match_operand:V64I 2 "arith_double_operand" "")))]
4676 (define_insn "*and<V64I:mode>3_sp32"
4677 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4678 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4679 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4684 [(set_attr "type" "*,fga")
4685 (set_attr "length" "2,*")
4686 (set_attr "fptype" "*,double")])
4688 (define_insn "*and<V64I:mode>3_sp64"
4689 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4690 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4691 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4696 [(set_attr "type" "*,fga")
4697 (set_attr "fptype" "*,double")])
4699 (define_insn "and<V32I:mode>3"
4700 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4701 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4702 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4707 [(set_attr "type" "*,fga")
4708 (set_attr "fptype" "*,single")])
4711 [(set (match_operand:SI 0 "register_operand" "")
4712 (and:SI (match_operand:SI 1 "register_operand" "")
4713 (match_operand:SI 2 "const_compl_high_operand" "")))
4714 (clobber (match_operand:SI 3 "register_operand" ""))]
4716 [(set (match_dup 3) (match_dup 4))
4717 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4719 operands[4] = GEN_INT (~INTVAL (operands[2]));
4722 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4723 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4724 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4725 (match_operand:V64I 2 "register_operand" "r,b")))]
4729 fandnot1\t%1, %2, %0"
4730 "&& reload_completed
4731 && ((GET_CODE (operands[0]) == REG
4732 && REGNO (operands[0]) < 32)
4733 || (GET_CODE (operands[0]) == SUBREG
4734 && GET_CODE (SUBREG_REG (operands[0])) == REG
4735 && REGNO (SUBREG_REG (operands[0])) < 32))"
4736 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4737 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4738 "operands[3] = gen_highpart (SImode, operands[0]);
4739 operands[4] = gen_highpart (SImode, operands[1]);
4740 operands[5] = gen_highpart (SImode, operands[2]);
4741 operands[6] = gen_lowpart (SImode, operands[0]);
4742 operands[7] = gen_lowpart (SImode, operands[1]);
4743 operands[8] = gen_lowpart (SImode, operands[2]);"
4744 [(set_attr "type" "*,fga")
4745 (set_attr "length" "2,*")
4746 (set_attr "fptype" "*,double")])
4748 (define_insn "*and_not_<V64I:mode>_sp64"
4749 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4750 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4751 (match_operand:V64I 2 "register_operand" "r,b")))]
4755 fandnot1\t%1, %2, %0"
4756 [(set_attr "type" "*,fga")
4757 (set_attr "fptype" "*,double")])
4759 (define_insn "*and_not_<V32I:mode>"
4760 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4761 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4762 (match_operand:V32I 2 "register_operand" "r,d")))]
4766 fandnot1s\t%1, %2, %0"
4767 [(set_attr "type" "*,fga")
4768 (set_attr "fptype" "*,single")])
4770 (define_expand "ior<V64I:mode>3"
4771 [(set (match_operand:V64I 0 "register_operand" "")
4772 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4773 (match_operand:V64I 2 "arith_double_operand" "")))]
4777 (define_insn "*ior<V64I:mode>3_sp32"
4778 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4779 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4780 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4785 [(set_attr "type" "*,fga")
4786 (set_attr "length" "2,*")
4787 (set_attr "fptype" "*,double")])
4789 (define_insn "*ior<V64I:mode>3_sp64"
4790 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4791 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4792 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4797 [(set_attr "type" "*,fga")
4798 (set_attr "fptype" "*,double")])
4800 (define_insn "ior<V32I:mode>3"
4801 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4802 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4803 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4808 [(set_attr "type" "*,fga")
4809 (set_attr "fptype" "*,single")])
4812 [(set (match_operand:SI 0 "register_operand" "")
4813 (ior:SI (match_operand:SI 1 "register_operand" "")
4814 (match_operand:SI 2 "const_compl_high_operand" "")))
4815 (clobber (match_operand:SI 3 "register_operand" ""))]
4817 [(set (match_dup 3) (match_dup 4))
4818 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4820 operands[4] = GEN_INT (~INTVAL (operands[2]));
4823 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4824 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4825 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4826 (match_operand:V64I 2 "register_operand" "r,b")))]
4830 fornot1\t%1, %2, %0"
4831 "&& reload_completed
4832 && ((GET_CODE (operands[0]) == REG
4833 && REGNO (operands[0]) < 32)
4834 || (GET_CODE (operands[0]) == SUBREG
4835 && GET_CODE (SUBREG_REG (operands[0])) == REG
4836 && REGNO (SUBREG_REG (operands[0])) < 32))"
4837 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4838 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4839 "operands[3] = gen_highpart (SImode, operands[0]);
4840 operands[4] = gen_highpart (SImode, operands[1]);
4841 operands[5] = gen_highpart (SImode, operands[2]);
4842 operands[6] = gen_lowpart (SImode, operands[0]);
4843 operands[7] = gen_lowpart (SImode, operands[1]);
4844 operands[8] = gen_lowpart (SImode, operands[2]);"
4845 [(set_attr "type" "*,fga")
4846 (set_attr "length" "2,*")
4847 (set_attr "fptype" "*,double")])
4849 (define_insn "*or_not_<V64I:mode>_sp64"
4850 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4851 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4852 (match_operand:V64I 2 "register_operand" "r,b")))]
4856 fornot1\t%1, %2, %0"
4857 [(set_attr "type" "*,fga")
4858 (set_attr "fptype" "*,double")])
4860 (define_insn "*or_not_<V32I:mode>"
4861 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4862 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4863 (match_operand:V32I 2 "register_operand" "r,d")))]
4867 fornot1s\t%1, %2, %0"
4868 [(set_attr "type" "*,fga")
4869 (set_attr "fptype" "*,single")])
4871 (define_expand "xor<V64I:mode>3"
4872 [(set (match_operand:V64I 0 "register_operand" "")
4873 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4874 (match_operand:V64I 2 "arith_double_operand" "")))]
4878 (define_insn "*xor<V64I:mode>3_sp32"
4879 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4880 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4881 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4886 [(set_attr "type" "*,fga")
4887 (set_attr "length" "2,*")
4888 (set_attr "fptype" "*,double")])
4890 (define_insn "*xor<V64I:mode>3_sp64"
4891 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4892 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4893 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4898 [(set_attr "type" "*,fga")
4899 (set_attr "fptype" "*,double")])
4901 (define_insn "xor<V32I:mode>3"
4902 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4903 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4904 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4909 [(set_attr "type" "*,fga")
4910 (set_attr "fptype" "*,single")])
4913 [(set (match_operand:SI 0 "register_operand" "")
4914 (xor:SI (match_operand:SI 1 "register_operand" "")
4915 (match_operand:SI 2 "const_compl_high_operand" "")))
4916 (clobber (match_operand:SI 3 "register_operand" ""))]
4918 [(set (match_dup 3) (match_dup 4))
4919 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4921 operands[4] = GEN_INT (~INTVAL (operands[2]));
4925 [(set (match_operand:SI 0 "register_operand" "")
4926 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4927 (match_operand:SI 2 "const_compl_high_operand" ""))))
4928 (clobber (match_operand:SI 3 "register_operand" ""))]
4930 [(set (match_dup 3) (match_dup 4))
4931 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4933 operands[4] = GEN_INT (~INTVAL (operands[2]));
4936 ;; Split DImode logical operations requiring two instructions.
4938 [(set (match_operand:V64I 0 "register_operand" "")
4939 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4940 [(match_operand:V64I 2 "register_operand" "")
4941 (match_operand:V64I 3 "arith_double_operand" "")]))]
4944 && ((GET_CODE (operands[0]) == REG
4945 && REGNO (operands[0]) < 32)
4946 || (GET_CODE (operands[0]) == SUBREG
4947 && GET_CODE (SUBREG_REG (operands[0])) == REG
4948 && REGNO (SUBREG_REG (operands[0])) < 32))"
4949 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4950 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4952 operands[4] = gen_highpart (SImode, operands[0]);
4953 operands[5] = gen_lowpart (SImode, operands[0]);
4954 operands[6] = gen_highpart (SImode, operands[2]);
4955 operands[7] = gen_lowpart (SImode, operands[2]);
4956 #if HOST_BITS_PER_WIDE_INT == 32
4957 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4959 if (INTVAL (operands[3]) < 0)
4960 operands[8] = constm1_rtx;
4962 operands[8] = const0_rtx;
4966 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4967 operands[9] = gen_lowpart (SImode, operands[3]);
4970 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4971 ;; Combine now canonicalizes to the rightmost expression.
4972 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4973 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4974 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4975 (match_operand:V64I 2 "register_operand" "r,b"))))]
4980 "&& reload_completed
4981 && ((GET_CODE (operands[0]) == REG
4982 && REGNO (operands[0]) < 32)
4983 || (GET_CODE (operands[0]) == SUBREG
4984 && GET_CODE (SUBREG_REG (operands[0])) == REG
4985 && REGNO (SUBREG_REG (operands[0])) < 32))"
4986 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4987 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4988 "operands[3] = gen_highpart (SImode, operands[0]);
4989 operands[4] = gen_highpart (SImode, operands[1]);
4990 operands[5] = gen_highpart (SImode, operands[2]);
4991 operands[6] = gen_lowpart (SImode, operands[0]);
4992 operands[7] = gen_lowpart (SImode, operands[1]);
4993 operands[8] = gen_lowpart (SImode, operands[2]);"
4994 [(set_attr "type" "*,fga")
4995 (set_attr "length" "2,*")
4996 (set_attr "fptype" "*,double")])
4998 (define_insn "*xor_not_<V64I:mode>_sp64"
4999 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5000 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5001 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5006 [(set_attr "type" "*,fga")
5007 (set_attr "fptype" "*,double")])
5009 (define_insn "*xor_not_<V32I:mode>"
5010 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5011 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5012 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5017 [(set_attr "type" "*,fga")
5018 (set_attr "fptype" "*,single")])
5020 ;; These correspond to the above in the case where we also (or only)
5021 ;; want to set the condition code.
5023 (define_insn "*cmp_cc_arith_op"
5024 [(set (reg:CC CC_REG)
5026 (match_operator:SI 2 "cc_arith_operator"
5027 [(match_operand:SI 0 "arith_operand" "%r")
5028 (match_operand:SI 1 "arith_operand" "rI")])
5031 "%A2cc\t%0, %1, %%g0"
5032 [(set_attr "type" "compare")])
5034 (define_insn "*cmp_ccx_arith_op"
5035 [(set (reg:CCX CC_REG)
5037 (match_operator:DI 2 "cc_arith_operator"
5038 [(match_operand:DI 0 "arith_operand" "%r")
5039 (match_operand:DI 1 "arith_operand" "rI")])
5042 "%A2cc\t%0, %1, %%g0"
5043 [(set_attr "type" "compare")])
5045 (define_insn "*cmp_cc_arith_op_set"
5046 [(set (reg:CC CC_REG)
5048 (match_operator:SI 3 "cc_arith_operator"
5049 [(match_operand:SI 1 "arith_operand" "%r")
5050 (match_operand:SI 2 "arith_operand" "rI")])
5052 (set (match_operand:SI 0 "register_operand" "=r")
5053 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5054 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5056 [(set_attr "type" "compare")])
5058 (define_insn "*cmp_ccx_arith_op_set"
5059 [(set (reg:CCX CC_REG)
5061 (match_operator:DI 3 "cc_arith_operator"
5062 [(match_operand:DI 1 "arith_operand" "%r")
5063 (match_operand:DI 2 "arith_operand" "rI")])
5065 (set (match_operand:DI 0 "register_operand" "=r")
5066 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5067 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5069 [(set_attr "type" "compare")])
5071 (define_insn "*cmp_cc_xor_not"
5072 [(set (reg:CC CC_REG)
5074 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5075 (match_operand:SI 1 "arith_operand" "rI")))
5078 "xnorcc\t%r0, %1, %%g0"
5079 [(set_attr "type" "compare")])
5081 (define_insn "*cmp_ccx_xor_not"
5082 [(set (reg:CCX CC_REG)
5084 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5085 (match_operand:DI 1 "arith_operand" "rI")))
5088 "xnorcc\t%r0, %1, %%g0"
5089 [(set_attr "type" "compare")])
5091 (define_insn "*cmp_cc_xor_not_set"
5092 [(set (reg:CC CC_REG)
5094 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5095 (match_operand:SI 2 "arith_operand" "rI")))
5097 (set (match_operand:SI 0 "register_operand" "=r")
5098 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5100 "xnorcc\t%r1, %2, %0"
5101 [(set_attr "type" "compare")])
5103 (define_insn "*cmp_ccx_xor_not_set"
5104 [(set (reg:CCX CC_REG)
5106 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5107 (match_operand:DI 2 "arith_operand" "rI")))
5109 (set (match_operand:DI 0 "register_operand" "=r")
5110 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5112 "xnorcc\t%r1, %2, %0"
5113 [(set_attr "type" "compare")])
5115 (define_insn "*cmp_cc_arith_op_not"
5116 [(set (reg:CC CC_REG)
5118 (match_operator:SI 2 "cc_arith_not_operator"
5119 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5120 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5123 "%B2cc\t%r1, %0, %%g0"
5124 [(set_attr "type" "compare")])
5126 (define_insn "*cmp_ccx_arith_op_not"
5127 [(set (reg:CCX CC_REG)
5129 (match_operator:DI 2 "cc_arith_not_operator"
5130 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5131 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5134 "%B2cc\t%r1, %0, %%g0"
5135 [(set_attr "type" "compare")])
5137 (define_insn "*cmp_cc_arith_op_not_set"
5138 [(set (reg:CC CC_REG)
5140 (match_operator:SI 3 "cc_arith_not_operator"
5141 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5142 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5144 (set (match_operand:SI 0 "register_operand" "=r")
5145 (match_operator:SI 4 "cc_arith_not_operator"
5146 [(not:SI (match_dup 1)) (match_dup 2)]))]
5147 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5148 "%B3cc\t%r2, %1, %0"
5149 [(set_attr "type" "compare")])
5151 (define_insn "*cmp_ccx_arith_op_not_set"
5152 [(set (reg:CCX CC_REG)
5154 (match_operator:DI 3 "cc_arith_not_operator"
5155 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5156 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5158 (set (match_operand:DI 0 "register_operand" "=r")
5159 (match_operator:DI 4 "cc_arith_not_operator"
5160 [(not:DI (match_dup 1)) (match_dup 2)]))]
5161 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5162 "%B3cc\t%r2, %1, %0"
5163 [(set_attr "type" "compare")])
5165 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5166 ;; does not know how to make it work for constants.
5168 (define_expand "negdi2"
5169 [(set (match_operand:DI 0 "register_operand" "=r")
5170 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5173 if (! TARGET_ARCH64)
5175 emit_insn (gen_rtx_PARALLEL
5178 gen_rtx_SET (VOIDmode, operand0,
5179 gen_rtx_NEG (DImode, operand1)),
5180 gen_rtx_CLOBBER (VOIDmode,
5181 gen_rtx_REG (CCmode,
5187 (define_insn_and_split "*negdi2_sp32"
5188 [(set (match_operand:DI 0 "register_operand" "=r")
5189 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5190 (clobber (reg:CC CC_REG))]
5193 "&& reload_completed"
5194 [(parallel [(set (reg:CC_NOOV CC_REG)
5195 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5197 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5198 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5199 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5200 "operands[2] = gen_highpart (SImode, operands[0]);
5201 operands[3] = gen_highpart (SImode, operands[1]);
5202 operands[4] = gen_lowpart (SImode, operands[0]);
5203 operands[5] = gen_lowpart (SImode, operands[1]);"
5204 [(set_attr "length" "2")])
5206 (define_insn "*negdi2_sp64"
5207 [(set (match_operand:DI 0 "register_operand" "=r")
5208 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5210 "sub\t%%g0, %1, %0")
5212 (define_insn "negsi2"
5213 [(set (match_operand:SI 0 "register_operand" "=r")
5214 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5216 "sub\t%%g0, %1, %0")
5218 (define_insn "*cmp_cc_neg"
5219 [(set (reg:CC_NOOV CC_REG)
5220 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5223 "subcc\t%%g0, %0, %%g0"
5224 [(set_attr "type" "compare")])
5226 (define_insn "*cmp_ccx_neg"
5227 [(set (reg:CCX_NOOV CC_REG)
5228 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5231 "subcc\t%%g0, %0, %%g0"
5232 [(set_attr "type" "compare")])
5234 (define_insn "*cmp_cc_set_neg"
5235 [(set (reg:CC_NOOV CC_REG)
5236 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5238 (set (match_operand:SI 0 "register_operand" "=r")
5239 (neg:SI (match_dup 1)))]
5241 "subcc\t%%g0, %1, %0"
5242 [(set_attr "type" "compare")])
5244 (define_insn "*cmp_ccx_set_neg"
5245 [(set (reg:CCX_NOOV CC_REG)
5246 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5248 (set (match_operand:DI 0 "register_operand" "=r")
5249 (neg:DI (match_dup 1)))]
5251 "subcc\t%%g0, %1, %0"
5252 [(set_attr "type" "compare")])
5254 ;; We cannot use the "not" pseudo insn because the Sun assembler
5255 ;; does not know how to make it work for constants.
5256 (define_expand "one_cmpl<V64I:mode>2"
5257 [(set (match_operand:V64I 0 "register_operand" "")
5258 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5262 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5263 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5264 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5269 "&& reload_completed
5270 && ((GET_CODE (operands[0]) == REG
5271 && REGNO (operands[0]) < 32)
5272 || (GET_CODE (operands[0]) == SUBREG
5273 && GET_CODE (SUBREG_REG (operands[0])) == REG
5274 && REGNO (SUBREG_REG (operands[0])) < 32))"
5275 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5276 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5277 "operands[2] = gen_highpart (SImode, operands[0]);
5278 operands[3] = gen_highpart (SImode, operands[1]);
5279 operands[4] = gen_lowpart (SImode, operands[0]);
5280 operands[5] = gen_lowpart (SImode, operands[1]);"
5281 [(set_attr "type" "*,fga")
5282 (set_attr "length" "2,*")
5283 (set_attr "fptype" "*,double")])
5285 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5286 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5287 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5292 [(set_attr "type" "*,fga")
5293 (set_attr "fptype" "*,double")])
5295 (define_insn "one_cmpl<V32I:mode>2"
5296 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5297 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5302 [(set_attr "type" "*,fga")
5303 (set_attr "fptype" "*,single")])
5305 (define_insn "*cmp_cc_not"
5306 [(set (reg:CC CC_REG)
5307 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5310 "xnorcc\t%%g0, %0, %%g0"
5311 [(set_attr "type" "compare")])
5313 (define_insn "*cmp_ccx_not"
5314 [(set (reg:CCX CC_REG)
5315 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5318 "xnorcc\t%%g0, %0, %%g0"
5319 [(set_attr "type" "compare")])
5321 (define_insn "*cmp_cc_set_not"
5322 [(set (reg:CC CC_REG)
5323 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5325 (set (match_operand:SI 0 "register_operand" "=r")
5326 (not:SI (match_dup 1)))]
5328 "xnorcc\t%%g0, %1, %0"
5329 [(set_attr "type" "compare")])
5331 (define_insn "*cmp_ccx_set_not"
5332 [(set (reg:CCX CC_REG)
5333 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5335 (set (match_operand:DI 0 "register_operand" "=r")
5336 (not:DI (match_dup 1)))]
5338 "xnorcc\t%%g0, %1, %0"
5339 [(set_attr "type" "compare")])
5341 (define_insn "*cmp_cc_set"
5342 [(set (match_operand:SI 0 "register_operand" "=r")
5343 (match_operand:SI 1 "register_operand" "r"))
5344 (set (reg:CC CC_REG)
5345 (compare:CC (match_dup 1)
5349 [(set_attr "type" "compare")])
5351 (define_insn "*cmp_ccx_set64"
5352 [(set (match_operand:DI 0 "register_operand" "=r")
5353 (match_operand:DI 1 "register_operand" "r"))
5354 (set (reg:CCX CC_REG)
5355 (compare:CCX (match_dup 1)
5359 [(set_attr "type" "compare")])
5362 ;; Floating point arithmetic instructions.
5364 (define_expand "addtf3"
5365 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5366 (plus:TF (match_operand:TF 1 "general_operand" "")
5367 (match_operand:TF 2 "general_operand" "")))]
5368 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5369 "emit_tfmode_binop (PLUS, operands); DONE;")
5371 (define_insn "*addtf3_hq"
5372 [(set (match_operand:TF 0 "register_operand" "=e")
5373 (plus:TF (match_operand:TF 1 "register_operand" "e")
5374 (match_operand:TF 2 "register_operand" "e")))]
5375 "TARGET_FPU && TARGET_HARD_QUAD"
5377 [(set_attr "type" "fp")])
5379 (define_insn "adddf3"
5380 [(set (match_operand:DF 0 "register_operand" "=e")
5381 (plus:DF (match_operand:DF 1 "register_operand" "e")
5382 (match_operand:DF 2 "register_operand" "e")))]
5385 [(set_attr "type" "fp")
5386 (set_attr "fptype" "double")])
5388 (define_insn "addsf3"
5389 [(set (match_operand:SF 0 "register_operand" "=f")
5390 (plus:SF (match_operand:SF 1 "register_operand" "f")
5391 (match_operand:SF 2 "register_operand" "f")))]
5394 [(set_attr "type" "fp")])
5396 (define_expand "subtf3"
5397 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5398 (minus:TF (match_operand:TF 1 "general_operand" "")
5399 (match_operand:TF 2 "general_operand" "")))]
5400 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5401 "emit_tfmode_binop (MINUS, operands); DONE;")
5403 (define_insn "*subtf3_hq"
5404 [(set (match_operand:TF 0 "register_operand" "=e")
5405 (minus:TF (match_operand:TF 1 "register_operand" "e")
5406 (match_operand:TF 2 "register_operand" "e")))]
5407 "TARGET_FPU && TARGET_HARD_QUAD"
5409 [(set_attr "type" "fp")])
5411 (define_insn "subdf3"
5412 [(set (match_operand:DF 0 "register_operand" "=e")
5413 (minus:DF (match_operand:DF 1 "register_operand" "e")
5414 (match_operand:DF 2 "register_operand" "e")))]
5417 [(set_attr "type" "fp")
5418 (set_attr "fptype" "double")])
5420 (define_insn "subsf3"
5421 [(set (match_operand:SF 0 "register_operand" "=f")
5422 (minus:SF (match_operand:SF 1 "register_operand" "f")
5423 (match_operand:SF 2 "register_operand" "f")))]
5426 [(set_attr "type" "fp")])
5428 (define_expand "multf3"
5429 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5430 (mult:TF (match_operand:TF 1 "general_operand" "")
5431 (match_operand:TF 2 "general_operand" "")))]
5432 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5433 "emit_tfmode_binop (MULT, operands); DONE;")
5435 (define_insn "*multf3_hq"
5436 [(set (match_operand:TF 0 "register_operand" "=e")
5437 (mult:TF (match_operand:TF 1 "register_operand" "e")
5438 (match_operand:TF 2 "register_operand" "e")))]
5439 "TARGET_FPU && TARGET_HARD_QUAD"
5441 [(set_attr "type" "fpmul")])
5443 (define_insn "muldf3"
5444 [(set (match_operand:DF 0 "register_operand" "=e")
5445 (mult:DF (match_operand:DF 1 "register_operand" "e")
5446 (match_operand:DF 2 "register_operand" "e")))]
5449 [(set_attr "type" "fpmul")
5450 (set_attr "fptype" "double")])
5452 (define_insn "mulsf3"
5453 [(set (match_operand:SF 0 "register_operand" "=f")
5454 (mult:SF (match_operand:SF 1 "register_operand" "f")
5455 (match_operand:SF 2 "register_operand" "f")))]
5458 [(set_attr "type" "fpmul")])
5460 (define_insn "fmadf4"
5461 [(set (match_operand:DF 0 "register_operand" "=e")
5462 (fma:DF (match_operand:DF 1 "register_operand" "e")
5463 (match_operand:DF 2 "register_operand" "e")
5464 (match_operand:DF 3 "register_operand" "e")))]
5466 "fmaddd\t%1, %2, %3, %0"
5467 [(set_attr "type" "fpmul")])
5469 (define_insn "fmsdf4"
5470 [(set (match_operand:DF 0 "register_operand" "=e")
5471 (fma:DF (match_operand:DF 1 "register_operand" "e")
5472 (match_operand:DF 2 "register_operand" "e")
5473 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5475 "fmsubd\t%1, %2, %3, %0"
5476 [(set_attr "type" "fpmul")])
5478 (define_insn "*nfmadf4"
5479 [(set (match_operand:DF 0 "register_operand" "=e")
5480 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5481 (match_operand:DF 2 "register_operand" "e")
5482 (match_operand:DF 3 "register_operand" "e"))))]
5484 "fnmaddd\t%1, %2, %3, %0"
5485 [(set_attr "type" "fpmul")])
5487 (define_insn "*nfmsdf4"
5488 [(set (match_operand:DF 0 "register_operand" "=e")
5489 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5490 (match_operand:DF 2 "register_operand" "e")
5491 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5493 "fnmsubd\t%1, %2, %3, %0"
5494 [(set_attr "type" "fpmul")])
5496 (define_insn "fmasf4"
5497 [(set (match_operand:SF 0 "register_operand" "=f")
5498 (fma:SF (match_operand:SF 1 "register_operand" "f")
5499 (match_operand:SF 2 "register_operand" "f")
5500 (match_operand:SF 3 "register_operand" "f")))]
5502 "fmadds\t%1, %2, %3, %0"
5503 [(set_attr "type" "fpmul")])
5505 (define_insn "fmssf4"
5506 [(set (match_operand:SF 0 "register_operand" "=f")
5507 (fma:SF (match_operand:SF 1 "register_operand" "f")
5508 (match_operand:SF 2 "register_operand" "f")
5509 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5511 "fmsubs\t%1, %2, %3, %0"
5512 [(set_attr "type" "fpmul")])
5514 (define_insn "*nfmasf4"
5515 [(set (match_operand:SF 0 "register_operand" "=f")
5516 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5517 (match_operand:SF 2 "register_operand" "f")
5518 (match_operand:SF 3 "register_operand" "f"))))]
5520 "fnmadds\t%1, %2, %3, %0"
5521 [(set_attr "type" "fpmul")])
5523 (define_insn "*nfmssf4"
5524 [(set (match_operand:SF 0 "register_operand" "=f")
5525 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5526 (match_operand:SF 2 "register_operand" "f")
5527 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5529 "fnmsubs\t%1, %2, %3, %0"
5530 [(set_attr "type" "fpmul")])
5532 (define_insn "*muldf3_extend"
5533 [(set (match_operand:DF 0 "register_operand" "=e")
5534 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5535 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5536 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5537 "fsmuld\t%1, %2, %0"
5538 [(set_attr "type" "fpmul")
5539 (set_attr "fptype" "double")])
5541 (define_insn "*multf3_extend"
5542 [(set (match_operand:TF 0 "register_operand" "=e")
5543 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5544 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5545 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5546 "fdmulq\t%1, %2, %0"
5547 [(set_attr "type" "fpmul")])
5549 (define_expand "divtf3"
5550 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5551 (div:TF (match_operand:TF 1 "general_operand" "")
5552 (match_operand:TF 2 "general_operand" "")))]
5553 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5554 "emit_tfmode_binop (DIV, operands); DONE;")
5556 ;; don't have timing for quad-prec. divide.
5557 (define_insn "*divtf3_hq"
5558 [(set (match_operand:TF 0 "register_operand" "=e")
5559 (div:TF (match_operand:TF 1 "register_operand" "e")
5560 (match_operand:TF 2 "register_operand" "e")))]
5561 "TARGET_FPU && TARGET_HARD_QUAD"
5563 [(set_attr "type" "fpdivd")])
5565 (define_insn "divdf3"
5566 [(set (match_operand:DF 0 "register_operand" "=e")
5567 (div:DF (match_operand:DF 1 "register_operand" "e")
5568 (match_operand:DF 2 "register_operand" "e")))]
5571 [(set_attr "type" "fpdivd")
5572 (set_attr "fptype" "double")])
5574 (define_insn "divsf3"
5575 [(set (match_operand:SF 0 "register_operand" "=f")
5576 (div:SF (match_operand:SF 1 "register_operand" "f")
5577 (match_operand:SF 2 "register_operand" "f")))]
5580 [(set_attr "type" "fpdivs")])
5582 (define_expand "negtf2"
5583 [(set (match_operand:TF 0 "register_operand" "=e,e")
5584 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5588 (define_insn_and_split "*negtf2_notv9"
5589 [(set (match_operand:TF 0 "register_operand" "=e,e")
5590 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5591 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5597 "&& reload_completed
5598 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5599 [(set (match_dup 2) (neg:SF (match_dup 3)))
5600 (set (match_dup 4) (match_dup 5))
5601 (set (match_dup 6) (match_dup 7))]
5602 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5603 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5604 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5605 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5606 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5607 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5608 [(set_attr "type" "fpmove,*")
5609 (set_attr "length" "*,2")])
5611 (define_insn_and_split "*negtf2_v9"
5612 [(set (match_operand:TF 0 "register_operand" "=e,e")
5613 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5614 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5615 "TARGET_FPU && TARGET_V9"
5619 "&& reload_completed
5620 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5621 [(set (match_dup 2) (neg:DF (match_dup 3)))
5622 (set (match_dup 4) (match_dup 5))]
5623 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5624 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5625 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5626 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5627 [(set_attr "type" "fpmove,*")
5628 (set_attr "length" "*,2")
5629 (set_attr "fptype" "double")])
5631 (define_expand "negdf2"
5632 [(set (match_operand:DF 0 "register_operand" "")
5633 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5637 (define_insn_and_split "*negdf2_notv9"
5638 [(set (match_operand:DF 0 "register_operand" "=e,e")
5639 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5640 "TARGET_FPU && ! TARGET_V9"
5644 "&& reload_completed
5645 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5646 [(set (match_dup 2) (neg:SF (match_dup 3)))
5647 (set (match_dup 4) (match_dup 5))]
5648 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5649 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5650 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5651 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5652 [(set_attr "type" "fpmove,*")
5653 (set_attr "length" "*,2")])
5655 (define_insn "*negdf2_v9"
5656 [(set (match_operand:DF 0 "register_operand" "=e")
5657 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5658 "TARGET_FPU && TARGET_V9"
5660 [(set_attr "type" "fpmove")
5661 (set_attr "fptype" "double")])
5663 (define_insn "negsf2"
5664 [(set (match_operand:SF 0 "register_operand" "=f")
5665 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5668 [(set_attr "type" "fpmove")])
5670 (define_expand "abstf2"
5671 [(set (match_operand:TF 0 "register_operand" "")
5672 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5676 (define_insn_and_split "*abstf2_notv9"
5677 [(set (match_operand:TF 0 "register_operand" "=e,e")
5678 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5679 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5680 "TARGET_FPU && ! TARGET_V9"
5684 "&& reload_completed
5685 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5686 [(set (match_dup 2) (abs:SF (match_dup 3)))
5687 (set (match_dup 4) (match_dup 5))
5688 (set (match_dup 6) (match_dup 7))]
5689 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5690 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5691 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5692 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5693 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5694 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5695 [(set_attr "type" "fpmove,*")
5696 (set_attr "length" "*,2")])
5698 (define_insn "*abstf2_hq_v9"
5699 [(set (match_operand:TF 0 "register_operand" "=e,e")
5700 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5701 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5705 [(set_attr "type" "fpmove")
5706 (set_attr "fptype" "double,*")])
5708 (define_insn_and_split "*abstf2_v9"
5709 [(set (match_operand:TF 0 "register_operand" "=e,e")
5710 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5711 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5715 "&& reload_completed
5716 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5717 [(set (match_dup 2) (abs:DF (match_dup 3)))
5718 (set (match_dup 4) (match_dup 5))]
5719 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5720 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5721 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5722 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5723 [(set_attr "type" "fpmove,*")
5724 (set_attr "length" "*,2")
5725 (set_attr "fptype" "double,*")])
5727 (define_expand "absdf2"
5728 [(set (match_operand:DF 0 "register_operand" "")
5729 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5733 (define_insn_and_split "*absdf2_notv9"
5734 [(set (match_operand:DF 0 "register_operand" "=e,e")
5735 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5736 "TARGET_FPU && ! TARGET_V9"
5740 "&& reload_completed
5741 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5742 [(set (match_dup 2) (abs:SF (match_dup 3)))
5743 (set (match_dup 4) (match_dup 5))]
5744 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5745 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5746 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5747 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5748 [(set_attr "type" "fpmove,*")
5749 (set_attr "length" "*,2")])
5751 (define_insn "*absdf2_v9"
5752 [(set (match_operand:DF 0 "register_operand" "=e")
5753 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5754 "TARGET_FPU && TARGET_V9"
5756 [(set_attr "type" "fpmove")
5757 (set_attr "fptype" "double")])
5759 (define_insn "abssf2"
5760 [(set (match_operand:SF 0 "register_operand" "=f")
5761 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5764 [(set_attr "type" "fpmove")])
5766 (define_expand "sqrttf2"
5767 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5768 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5769 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5770 "emit_tfmode_unop (SQRT, operands); DONE;")
5772 (define_insn "*sqrttf2_hq"
5773 [(set (match_operand:TF 0 "register_operand" "=e")
5774 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5775 "TARGET_FPU && TARGET_HARD_QUAD"
5777 [(set_attr "type" "fpsqrtd")])
5779 (define_insn "sqrtdf2"
5780 [(set (match_operand:DF 0 "register_operand" "=e")
5781 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5784 [(set_attr "type" "fpsqrtd")
5785 (set_attr "fptype" "double")])
5787 (define_insn "sqrtsf2"
5788 [(set (match_operand:SF 0 "register_operand" "=f")
5789 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5792 [(set_attr "type" "fpsqrts")])
5795 ;; Arithmetic shift instructions.
5797 (define_insn "ashlsi3"
5798 [(set (match_operand:SI 0 "register_operand" "=r")
5799 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5800 (match_operand:SI 2 "arith_operand" "rI")))]
5803 if (GET_CODE (operands[2]) == CONST_INT)
5804 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5805 return "sll\t%1, %2, %0";
5808 (if_then_else (match_operand 2 "const_one_operand" "")
5809 (const_string "ialu") (const_string "shift")))])
5811 (define_expand "ashldi3"
5812 [(set (match_operand:DI 0 "register_operand" "=r")
5813 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5814 (match_operand:SI 2 "arith_operand" "rI")))]
5815 "TARGET_ARCH64 || TARGET_V8PLUS"
5817 if (! TARGET_ARCH64)
5819 if (GET_CODE (operands[2]) == CONST_INT)
5821 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5826 (define_insn "*ashldi3_sp64"
5827 [(set (match_operand:DI 0 "register_operand" "=r")
5828 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5829 (match_operand:SI 2 "arith_operand" "rI")))]
5832 if (GET_CODE (operands[2]) == CONST_INT)
5833 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5834 return "sllx\t%1, %2, %0";
5837 (if_then_else (match_operand 2 "const_one_operand" "")
5838 (const_string "ialu") (const_string "shift")))])
5841 (define_insn "ashldi3_v8plus"
5842 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5843 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5844 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5845 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5847 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5848 [(set_attr "type" "multi")
5849 (set_attr "length" "5,5,6")])
5851 ;; Optimize (1LL<<x)-1
5852 ;; XXX this also needs to be fixed to handle equal subregs
5853 ;; XXX first before we could re-enable it.
5855 ; [(set (match_operand:DI 0 "register_operand" "=h")
5856 ; (plus:DI (ashift:DI (const_int 1)
5857 ; (match_operand:SI 1 "arith_operand" "rI"))
5859 ; "0 && TARGET_V8PLUS"
5861 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5862 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5863 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5865 ; [(set_attr "type" "multi")
5866 ; (set_attr "length" "4")])
5868 (define_insn "*cmp_cc_ashift_1"
5869 [(set (reg:CC_NOOV CC_REG)
5870 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5874 "addcc\t%0, %0, %%g0"
5875 [(set_attr "type" "compare")])
5877 (define_insn "*cmp_cc_set_ashift_1"
5878 [(set (reg:CC_NOOV CC_REG)
5879 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5882 (set (match_operand:SI 0 "register_operand" "=r")
5883 (ashift:SI (match_dup 1) (const_int 1)))]
5886 [(set_attr "type" "compare")])
5888 (define_insn "ashrsi3"
5889 [(set (match_operand:SI 0 "register_operand" "=r")
5890 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5891 (match_operand:SI 2 "arith_operand" "rI")))]
5894 if (GET_CODE (operands[2]) == CONST_INT)
5895 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5896 return "sra\t%1, %2, %0";
5898 [(set_attr "type" "shift")])
5900 (define_insn "*ashrsi3_extend"
5901 [(set (match_operand:DI 0 "register_operand" "=r")
5902 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5903 (match_operand:SI 2 "arith_operand" "r"))))]
5906 [(set_attr "type" "shift")])
5908 ;; This handles the case as above, but with constant shift instead of
5909 ;; register. Combiner "simplifies" it for us a little bit though.
5910 (define_insn "*ashrsi3_extend2"
5911 [(set (match_operand:DI 0 "register_operand" "=r")
5912 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5914 (match_operand:SI 2 "small_int_operand" "I")))]
5915 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5917 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5918 return "sra\t%1, %2, %0";
5920 [(set_attr "type" "shift")])
5922 (define_expand "ashrdi3"
5923 [(set (match_operand:DI 0 "register_operand" "=r")
5924 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5925 (match_operand:SI 2 "arith_operand" "rI")))]
5926 "TARGET_ARCH64 || TARGET_V8PLUS"
5928 if (! TARGET_ARCH64)
5930 if (GET_CODE (operands[2]) == CONST_INT)
5931 FAIL; /* prefer generic code in this case */
5932 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5937 (define_insn "*ashrdi3_sp64"
5938 [(set (match_operand:DI 0 "register_operand" "=r")
5939 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5940 (match_operand:SI 2 "arith_operand" "rI")))]
5944 if (GET_CODE (operands[2]) == CONST_INT)
5945 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5946 return "srax\t%1, %2, %0";
5948 [(set_attr "type" "shift")])
5951 (define_insn "ashrdi3_v8plus"
5952 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5953 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5954 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5955 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5957 "* return output_v8plus_shift (operands, insn, \"srax\");"
5958 [(set_attr "type" "multi")
5959 (set_attr "length" "5,5,6")])
5961 (define_insn "lshrsi3"
5962 [(set (match_operand:SI 0 "register_operand" "=r")
5963 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5964 (match_operand:SI 2 "arith_operand" "rI")))]
5967 if (GET_CODE (operands[2]) == CONST_INT)
5968 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5969 return "srl\t%1, %2, %0";
5971 [(set_attr "type" "shift")])
5973 ;; This handles the case where
5974 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5975 ;; but combiner "simplifies" it for us.
5976 (define_insn "*lshrsi3_extend"
5977 [(set (match_operand:DI 0 "register_operand" "=r")
5978 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5979 (match_operand:SI 2 "arith_operand" "r")) 0)
5980 (match_operand 3 "const_int_operand" "")))]
5981 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5983 [(set_attr "type" "shift")])
5985 ;; This handles the case where
5986 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5987 ;; but combiner "simplifies" it for us.
5988 (define_insn "*lshrsi3_extend2"
5989 [(set (match_operand:DI 0 "register_operand" "=r")
5990 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5991 (match_operand 2 "small_int_operand" "I")
5993 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5995 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5996 return "srl\t%1, %2, %0";
5998 [(set_attr "type" "shift")])
6000 (define_expand "lshrdi3"
6001 [(set (match_operand:DI 0 "register_operand" "=r")
6002 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6003 (match_operand:SI 2 "arith_operand" "rI")))]
6004 "TARGET_ARCH64 || TARGET_V8PLUS"
6006 if (! TARGET_ARCH64)
6008 if (GET_CODE (operands[2]) == CONST_INT)
6010 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6015 (define_insn "*lshrdi3_sp64"
6016 [(set (match_operand:DI 0 "register_operand" "=r")
6017 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6018 (match_operand:SI 2 "arith_operand" "rI")))]
6021 if (GET_CODE (operands[2]) == CONST_INT)
6022 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6023 return "srlx\t%1, %2, %0";
6025 [(set_attr "type" "shift")])
6028 (define_insn "lshrdi3_v8plus"
6029 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6030 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6031 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6032 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6034 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6035 [(set_attr "type" "multi")
6036 (set_attr "length" "5,5,6")])
6039 [(set (match_operand:SI 0 "register_operand" "=r")
6040 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6042 (match_operand:SI 2 "small_int_operand" "I")))]
6043 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6045 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6046 return "srax\t%1, %2, %0";
6048 [(set_attr "type" "shift")])
6051 [(set (match_operand:SI 0 "register_operand" "=r")
6052 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6054 (match_operand:SI 2 "small_int_operand" "I")))]
6055 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6057 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6058 return "srlx\t%1, %2, %0";
6060 [(set_attr "type" "shift")])
6063 [(set (match_operand:SI 0 "register_operand" "=r")
6064 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6065 (match_operand:SI 2 "small_int_operand" "I")) 4)
6066 (match_operand:SI 3 "small_int_operand" "I")))]
6068 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6069 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6070 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6072 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6074 return "srax\t%1, %2, %0";
6076 [(set_attr "type" "shift")])
6079 [(set (match_operand:SI 0 "register_operand" "=r")
6080 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6081 (match_operand:SI 2 "small_int_operand" "I")) 4)
6082 (match_operand:SI 3 "small_int_operand" "I")))]
6084 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6085 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6086 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6088 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6090 return "srlx\t%1, %2, %0";
6092 [(set_attr "type" "shift")])
6095 ;; Unconditional and other jump instructions.
6098 [(set (pc) (label_ref (match_operand 0 "" "")))]
6100 "* return output_ubranch (operands[0], 0, insn);"
6101 [(set_attr "type" "uncond_branch")])
6103 (define_expand "tablejump"
6104 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6105 (use (label_ref (match_operand 1 "" "")))])]
6108 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6110 /* In pic mode, our address differences are against the base of the
6111 table. Add that base value back in; CSE ought to be able to combine
6112 the two address loads. */
6116 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6118 if (CASE_VECTOR_MODE != Pmode)
6119 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6120 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6121 operands[0] = memory_address (Pmode, tmp);
6125 (define_insn "*tablejump_sp32"
6126 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6127 (use (label_ref (match_operand 1 "" "")))]
6130 [(set_attr "type" "uncond_branch")])
6132 (define_insn "*tablejump_sp64"
6133 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6134 (use (label_ref (match_operand 1 "" "")))]
6137 [(set_attr "type" "uncond_branch")])
6140 ;; Jump to subroutine instructions.
6142 (define_expand "call"
6143 ;; Note that this expression is not used for generating RTL.
6144 ;; All the RTL is generated explicitly below.
6145 [(call (match_operand 0 "call_operand" "")
6146 (match_operand 3 "" "i"))]
6147 ;; operands[2] is next_arg_register
6148 ;; operands[3] is struct_value_size_rtx.
6153 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6155 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6157 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6159 /* This is really a PIC sequence. We want to represent
6160 it as a funny jump so its delay slots can be filled.
6162 ??? But if this really *is* a CALL, will not it clobber the
6163 call-clobbered registers? We lose this if it is a JUMP_INSN.
6164 Why cannot we have delay slots filled if it were a CALL? */
6166 /* We accept negative sizes for untyped calls. */
6167 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6172 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6174 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6180 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6181 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6185 fn_rtx = operands[0];
6187 /* We accept negative sizes for untyped calls. */
6188 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6189 sparc_emit_call_insn
6192 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6194 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6197 sparc_emit_call_insn
6200 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6201 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6209 ;; We can't use the same pattern for these two insns, because then registers
6210 ;; in the address may not be properly reloaded.
6212 (define_insn "*call_address_sp32"
6213 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6214 (match_operand 1 "" ""))
6215 (clobber (reg:SI O7_REG))]
6216 ;;- Do not use operand 1 for most machines.
6219 [(set_attr "type" "call")])
6221 (define_insn "*call_symbolic_sp32"
6222 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6223 (match_operand 1 "" ""))
6224 (clobber (reg:SI O7_REG))]
6225 ;;- Do not use operand 1 for most machines.
6228 [(set_attr "type" "call")])
6230 (define_insn "*call_address_sp64"
6231 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6232 (match_operand 1 "" ""))
6233 (clobber (reg:DI O7_REG))]
6234 ;;- Do not use operand 1 for most machines.
6237 [(set_attr "type" "call")])
6239 (define_insn "*call_symbolic_sp64"
6240 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6241 (match_operand 1 "" ""))
6242 (clobber (reg:DI O7_REG))]
6243 ;;- Do not use operand 1 for most machines.
6246 [(set_attr "type" "call")])
6248 ;; This is a call that wants a structure value.
6249 ;; There is no such critter for v9 (??? we may need one anyway).
6250 (define_insn "*call_address_struct_value_sp32"
6251 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6252 (match_operand 1 "" ""))
6253 (match_operand 2 "immediate_operand" "")
6254 (clobber (reg:SI O7_REG))]
6255 ;;- Do not use operand 1 for most machines.
6256 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6258 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6259 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6261 [(set_attr "type" "call_no_delay_slot")
6262 (set_attr "length" "3")])
6264 ;; This is a call that wants a structure value.
6265 ;; There is no such critter for v9 (??? we may need one anyway).
6266 (define_insn "*call_symbolic_struct_value_sp32"
6267 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6268 (match_operand 1 "" ""))
6269 (match_operand 2 "immediate_operand" "")
6270 (clobber (reg:SI O7_REG))]
6271 ;;- Do not use operand 1 for most machines.
6272 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6274 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6275 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6277 [(set_attr "type" "call_no_delay_slot")
6278 (set_attr "length" "3")])
6280 ;; This is a call that may want a structure value. This is used for
6282 (define_insn "*call_address_untyped_struct_value_sp32"
6283 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6284 (match_operand 1 "" ""))
6285 (match_operand 2 "immediate_operand" "")
6286 (clobber (reg:SI O7_REG))]
6287 ;;- Do not use operand 1 for most machines.
6288 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6289 "call\t%a0, %1\n\t nop\n\tnop"
6290 [(set_attr "type" "call_no_delay_slot")
6291 (set_attr "length" "3")])
6293 ;; This is a call that may want a structure value. This is used for
6295 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6296 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6297 (match_operand 1 "" ""))
6298 (match_operand 2 "immediate_operand" "")
6299 (clobber (reg:SI O7_REG))]
6300 ;;- Do not use operand 1 for most machines.
6301 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6302 "call\t%a0, %1\n\t nop\n\tnop"
6303 [(set_attr "type" "call_no_delay_slot")
6304 (set_attr "length" "3")])
6306 (define_expand "call_value"
6307 ;; Note that this expression is not used for generating RTL.
6308 ;; All the RTL is generated explicitly below.
6309 [(set (match_operand 0 "register_operand" "=rf")
6310 (call (match_operand 1 "" "")
6311 (match_operand 4 "" "")))]
6312 ;; operand 2 is stack_size_rtx
6313 ;; operand 3 is next_arg_register
6319 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6321 fn_rtx = operands[1];
6324 gen_rtx_SET (VOIDmode, operands[0],
6325 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6326 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6328 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6333 (define_insn "*call_value_address_sp32"
6334 [(set (match_operand 0 "" "=rf")
6335 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6336 (match_operand 2 "" "")))
6337 (clobber (reg:SI O7_REG))]
6338 ;;- Do not use operand 2 for most machines.
6341 [(set_attr "type" "call")])
6343 (define_insn "*call_value_symbolic_sp32"
6344 [(set (match_operand 0 "" "=rf")
6345 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6346 (match_operand 2 "" "")))
6347 (clobber (reg:SI O7_REG))]
6348 ;;- Do not use operand 2 for most machines.
6351 [(set_attr "type" "call")])
6353 (define_insn "*call_value_address_sp64"
6354 [(set (match_operand 0 "" "")
6355 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6356 (match_operand 2 "" "")))
6357 (clobber (reg:DI O7_REG))]
6358 ;;- Do not use operand 2 for most machines.
6361 [(set_attr "type" "call")])
6363 (define_insn "*call_value_symbolic_sp64"
6364 [(set (match_operand 0 "" "")
6365 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6366 (match_operand 2 "" "")))
6367 (clobber (reg:DI O7_REG))]
6368 ;;- Do not use operand 2 for most machines.
6371 [(set_attr "type" "call")])
6373 (define_expand "untyped_call"
6374 [(parallel [(call (match_operand 0 "" "")
6376 (match_operand:BLK 1 "memory_operand" "")
6377 (match_operand 2 "" "")])]
6380 rtx valreg1 = gen_rtx_REG (DImode, 8);
6381 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6382 rtx result = operands[1];
6384 /* Pass constm1 to indicate that it may expect a structure value, but
6385 we don't know what size it is. */
6386 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6388 /* Save the function value registers. */
6389 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6390 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6393 /* The optimizer does not know that the call sets the function value
6394 registers we stored in the result block. We avoid problems by
6395 claiming that all hard registers are used and clobbered at this
6397 emit_insn (gen_blockage ());
6402 ;; Tail call instructions.
6404 (define_expand "sibcall"
6405 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6410 (define_insn "*sibcall_symbolic_sp32"
6411 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6412 (match_operand 1 "" ""))
6415 "* return output_sibcall(insn, operands[0]);"
6416 [(set_attr "type" "sibcall")])
6418 (define_insn "*sibcall_symbolic_sp64"
6419 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6420 (match_operand 1 "" ""))
6423 "* return output_sibcall(insn, operands[0]);"
6424 [(set_attr "type" "sibcall")])
6426 (define_expand "sibcall_value"
6427 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6428 (call (match_operand 1 "" "") (const_int 0)))
6433 (define_insn "*sibcall_value_symbolic_sp32"
6434 [(set (match_operand 0 "" "=rf")
6435 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6436 (match_operand 2 "" "")))
6439 "* return output_sibcall(insn, operands[1]);"
6440 [(set_attr "type" "sibcall")])
6442 (define_insn "*sibcall_value_symbolic_sp64"
6443 [(set (match_operand 0 "" "")
6444 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6445 (match_operand 2 "" "")))
6448 "* return output_sibcall(insn, operands[1]);"
6449 [(set_attr "type" "sibcall")])
6452 ;; Special instructions.
6454 (define_expand "prologue"
6459 sparc_flat_expand_prologue ();
6461 sparc_expand_prologue ();
6465 ;; The "register window save" insn is modelled as follows. The dwarf2
6466 ;; information is manually added in emit_window_save.
6468 (define_insn "window_save"
6470 [(match_operand 0 "arith_operand" "rI")]
6473 "save\t%%sp, %0, %%sp"
6474 [(set_attr "type" "savew")])
6476 (define_expand "epilogue"
6481 sparc_flat_expand_epilogue (false);
6483 sparc_expand_epilogue (false);
6486 (define_expand "sibcall_epilogue"
6491 sparc_flat_expand_epilogue (false);
6493 sparc_expand_epilogue (false);
6497 (define_expand "eh_return"
6498 [(use (match_operand 0 "general_operand" ""))]
6501 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6502 emit_jump_insn (gen_eh_return_internal ());
6507 (define_insn_and_split "eh_return_internal"
6511 "epilogue_completed"
6515 sparc_flat_expand_epilogue (true);
6517 sparc_expand_epilogue (true);
6520 (define_expand "return"
6522 "sparc_can_use_return_insn_p ()"
6525 (define_insn "*return_internal"
6528 "* return output_return (insn);"
6529 [(set_attr "type" "return")
6530 (set (attr "length")
6531 (cond [(eq_attr "calls_eh_return" "true")
6532 (if_then_else (eq_attr "delayed_branch" "true")
6533 (if_then_else (ior (eq_attr "isa" "v9")
6534 (eq_attr "flat" "true"))
6537 (if_then_else (eq_attr "flat" "true")
6540 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6541 (if_then_else (eq_attr "empty_delay_slot" "true")
6544 (eq_attr "empty_delay_slot" "true")
6545 (if_then_else (eq_attr "delayed_branch" "true")
6550 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6551 ;; all of memory. This blocks insns from being moved across this point.
6553 (define_insn "blockage"
6554 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6557 [(set_attr "length" "0")])
6559 (define_expand "probe_stack"
6560 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6564 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6567 (define_insn "probe_stack_range<P:mode>"
6568 [(set (match_operand:P 0 "register_operand" "=r")
6569 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6570 (match_operand:P 2 "register_operand" "r")]
6571 UNSPECV_PROBE_STACK_RANGE))]
6573 "* return output_probe_stack_range (operands[0], operands[2]);"
6574 [(set_attr "type" "multi")])
6576 ;; Prepare to return any type including a structure value.
6578 (define_expand "untyped_return"
6579 [(match_operand:BLK 0 "memory_operand" "")
6580 (match_operand 1 "" "")]
6583 rtx valreg1 = gen_rtx_REG (DImode, 24);
6584 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6585 rtx result = operands[0];
6587 if (! TARGET_ARCH64)
6589 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6590 rtx value = gen_reg_rtx (SImode);
6592 /* Fetch the instruction where we will return to and see if it's an unimp
6593 instruction (the most significant 10 bits will be zero). If so,
6594 update the return address to skip the unimp instruction. */
6595 emit_move_insn (value,
6596 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6597 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6598 emit_insn (gen_update_return (rtnreg, value));
6601 /* Reload the function value registers. */
6602 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6603 emit_move_insn (valreg2,
6604 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6606 /* Put USE insns before the return. */
6610 /* Construct the return. */
6611 expand_naked_return ();
6616 ;; Adjust the return address conditionally. If the value of op1 is equal
6617 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6618 ;; This is technically *half* the check required by the 32-bit SPARC
6619 ;; psABI. This check only ensures that an "unimp" insn was written by
6620 ;; the caller, but doesn't check to see if the expected size matches
6621 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6622 ;; only used by the above code "untyped_return".
6624 (define_insn "update_return"
6625 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6626 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6629 if (flag_delayed_branch)
6630 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6632 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6634 [(set (attr "type") (const_string "multi"))
6635 (set (attr "length")
6636 (if_then_else (eq_attr "delayed_branch" "true")
6645 (define_expand "indirect_jump"
6646 [(set (pc) (match_operand 0 "address_operand" "p"))]
6650 (define_insn "*branch_sp32"
6651 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6654 [(set_attr "type" "uncond_branch")])
6656 (define_insn "*branch_sp64"
6657 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6660 [(set_attr "type" "uncond_branch")])
6662 (define_expand "save_stack_nonlocal"
6663 [(set (match_operand 0 "memory_operand" "")
6664 (match_operand 1 "register_operand" ""))
6665 (set (match_dup 2) (match_dup 3))]
6668 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6669 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6670 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6673 (define_expand "restore_stack_nonlocal"
6674 [(set (match_operand 0 "register_operand" "")
6675 (match_operand 1 "memory_operand" ""))]
6678 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6681 (define_expand "nonlocal_goto"
6682 [(match_operand 0 "general_operand" "")
6683 (match_operand 1 "general_operand" "")
6684 (match_operand 2 "memory_operand" "")
6685 (match_operand 3 "memory_operand" "")]
6688 rtx r_label = copy_to_reg (operands[1]);
6689 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6690 rtx r_fp = operands[3];
6691 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6693 /* We need to flush all the register windows so that their contents will
6694 be re-synchronized by the restore insn of the target function. */
6696 emit_insn (gen_flush_register_windows ());
6698 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6699 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6701 /* Restore frame pointer for containing function. */
6702 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6703 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6705 /* USE of hard_frame_pointer_rtx added for consistency;
6706 not clear if really needed. */
6707 emit_use (hard_frame_pointer_rtx);
6708 emit_use (stack_pointer_rtx);
6710 /* We need to smuggle the load of %i7 as it is a fixed register. */
6711 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6716 (define_insn "nonlocal_goto_internal"
6717 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6718 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6719 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6721 if (flag_delayed_branch)
6724 return "jmp\t%0\n\t ldx\t%1, %%i7";
6726 return "jmp\t%0\n\t ld\t%1, %%i7";
6731 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6733 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6736 [(set (attr "type") (const_string "multi"))
6737 (set (attr "length")
6738 (if_then_else (eq_attr "delayed_branch" "true")
6742 (define_expand "builtin_setjmp_receiver"
6743 [(label_ref (match_operand 0 "" ""))]
6746 load_got_register ();
6750 ;; Special insn to flush register windows.
6752 (define_insn "flush_register_windows"
6753 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6755 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6756 [(set_attr "type" "flushw")])
6758 ;; Special pattern for the FLUSH instruction.
6760 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6761 ; of the define_insn otherwise missing a mode. We make "flush", aka
6762 ; gen_flush, the default one since sparc_initialize_trampoline uses
6763 ; it on SImode mem values.
6765 (define_insn "flush"
6766 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6768 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6769 [(set_attr "type" "iflush")])
6771 (define_insn "flushdi"
6772 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6774 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6775 [(set_attr "type" "iflush")])
6778 ;; Find first set instructions.
6780 ;; The scan instruction searches from the most significant bit while ffs
6781 ;; searches from the least significant bit. The bit index and treatment of
6782 ;; zero also differ. It takes at least 7 instructions to get the proper
6783 ;; result. Here is an obvious 8 instruction sequence.
6786 (define_insn "ffssi2"
6787 [(set (match_operand:SI 0 "register_operand" "=&r")
6788 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6789 (clobber (match_scratch:SI 2 "=&r"))]
6790 "TARGET_SPARCLITE || TARGET_SPARCLET"
6792 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";
6794 [(set_attr "type" "multi")
6795 (set_attr "length" "8")])
6797 ;; ??? This should be a define expand, so that the extra instruction have
6798 ;; a chance of being optimized away.
6800 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6801 ;; does, but no one uses that and we don't have a switch for it.
6803 ;(define_insn "ffsdi2"
6804 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6805 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6806 ; (clobber (match_scratch:DI 2 "=&r"))]
6808 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6809 ; [(set_attr "type" "multi")
6810 ; (set_attr "length" "4")])
6814 ;; Peepholes go at the end.
6816 ;; Optimize consecutive loads or stores into ldd and std when possible.
6817 ;; The conditions in which we do this are very restricted and are
6818 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6821 [(set (match_operand:SI 0 "memory_operand" "")
6823 (set (match_operand:SI 1 "memory_operand" "")
6826 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6829 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6832 [(set (match_operand:SI 0 "memory_operand" "")
6834 (set (match_operand:SI 1 "memory_operand" "")
6837 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6840 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6843 [(set (match_operand:SI 0 "register_operand" "")
6844 (match_operand:SI 1 "memory_operand" ""))
6845 (set (match_operand:SI 2 "register_operand" "")
6846 (match_operand:SI 3 "memory_operand" ""))]
6847 "registers_ok_for_ldd_peep (operands[0], operands[2])
6848 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6851 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6852 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6855 [(set (match_operand:SI 0 "memory_operand" "")
6856 (match_operand:SI 1 "register_operand" ""))
6857 (set (match_operand:SI 2 "memory_operand" "")
6858 (match_operand:SI 3 "register_operand" ""))]
6859 "registers_ok_for_ldd_peep (operands[1], operands[3])
6860 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6863 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6864 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6867 [(set (match_operand:SF 0 "register_operand" "")
6868 (match_operand:SF 1 "memory_operand" ""))
6869 (set (match_operand:SF 2 "register_operand" "")
6870 (match_operand:SF 3 "memory_operand" ""))]
6871 "registers_ok_for_ldd_peep (operands[0], operands[2])
6872 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6875 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6876 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6879 [(set (match_operand:SF 0 "memory_operand" "")
6880 (match_operand:SF 1 "register_operand" ""))
6881 (set (match_operand:SF 2 "memory_operand" "")
6882 (match_operand:SF 3 "register_operand" ""))]
6883 "registers_ok_for_ldd_peep (operands[1], operands[3])
6884 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6887 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6888 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6891 [(set (match_operand:SI 0 "register_operand" "")
6892 (match_operand:SI 1 "memory_operand" ""))
6893 (set (match_operand:SI 2 "register_operand" "")
6894 (match_operand:SI 3 "memory_operand" ""))]
6895 "registers_ok_for_ldd_peep (operands[2], operands[0])
6896 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6899 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6900 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6903 [(set (match_operand:SI 0 "memory_operand" "")
6904 (match_operand:SI 1 "register_operand" ""))
6905 (set (match_operand:SI 2 "memory_operand" "")
6906 (match_operand:SI 3 "register_operand" ""))]
6907 "registers_ok_for_ldd_peep (operands[3], operands[1])
6908 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6911 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6912 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6916 [(set (match_operand:SF 0 "register_operand" "")
6917 (match_operand:SF 1 "memory_operand" ""))
6918 (set (match_operand:SF 2 "register_operand" "")
6919 (match_operand:SF 3 "memory_operand" ""))]
6920 "registers_ok_for_ldd_peep (operands[2], operands[0])
6921 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6924 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6925 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6928 [(set (match_operand:SF 0 "memory_operand" "")
6929 (match_operand:SF 1 "register_operand" ""))
6930 (set (match_operand:SF 2 "memory_operand" "")
6931 (match_operand:SF 3 "register_operand" ""))]
6932 "registers_ok_for_ldd_peep (operands[3], operands[1])
6933 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6936 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6937 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6939 ;; Optimize the case of following a reg-reg move with a test
6940 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6941 ;; This can result from a float to fix conversion.
6944 [(set (match_operand:SI 0 "register_operand" "")
6945 (match_operand:SI 1 "register_operand" ""))
6946 (set (reg:CC CC_REG)
6947 (compare:CC (match_operand:SI 2 "register_operand" "")
6949 "(rtx_equal_p (operands[2], operands[0])
6950 || rtx_equal_p (operands[2], operands[1]))
6951 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6952 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6953 [(parallel [(set (match_dup 0) (match_dup 1))
6954 (set (reg:CC CC_REG)
6955 (compare:CC (match_dup 1) (const_int 0)))])]
6959 [(set (match_operand:DI 0 "register_operand" "")
6960 (match_operand:DI 1 "register_operand" ""))
6961 (set (reg:CCX CC_REG)
6962 (compare:CCX (match_operand:DI 2 "register_operand" "")
6965 && (rtx_equal_p (operands[2], operands[0])
6966 || rtx_equal_p (operands[2], operands[1]))
6967 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6968 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6969 [(parallel [(set (match_dup 0) (match_dup 1))
6970 (set (reg:CCX CC_REG)
6971 (compare:CCX (match_dup 1) (const_int 0)))])]
6975 ;; Prefetch instructions.
6977 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6978 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6979 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6981 (define_expand "prefetch"
6982 [(match_operand 0 "address_operand" "")
6983 (match_operand 1 "const_int_operand" "")
6984 (match_operand 2 "const_int_operand" "")]
6988 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6990 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6994 (define_insn "prefetch_64"
6995 [(prefetch (match_operand:DI 0 "address_operand" "p")
6996 (match_operand:DI 1 "const_int_operand" "n")
6997 (match_operand:DI 2 "const_int_operand" "n"))]
7000 static const char * const prefetch_instr[2][2] = {
7002 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7003 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7006 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7007 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7010 int read_or_write = INTVAL (operands[1]);
7011 int locality = INTVAL (operands[2]);
7013 gcc_assert (read_or_write == 0 || read_or_write == 1);
7014 gcc_assert (locality >= 0 && locality < 4);
7015 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7017 [(set_attr "type" "load")])
7019 (define_insn "prefetch_32"
7020 [(prefetch (match_operand:SI 0 "address_operand" "p")
7021 (match_operand:SI 1 "const_int_operand" "n")
7022 (match_operand:SI 2 "const_int_operand" "n"))]
7025 static const char * const prefetch_instr[2][2] = {
7027 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7028 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7031 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7032 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7035 int read_or_write = INTVAL (operands[1]);
7036 int locality = INTVAL (operands[2]);
7038 gcc_assert (read_or_write == 0 || read_or_write == 1);
7039 gcc_assert (locality >= 0 && locality < 4);
7040 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7042 [(set_attr "type" "load")])
7045 ;; Trap instructions.
7048 [(trap_if (const_int 1) (const_int 5))]
7051 [(set_attr "type" "trap")])
7053 (define_expand "ctrapsi4"
7054 [(trap_if (match_operator 0 "noov_compare_operator"
7055 [(match_operand:SI 1 "compare_operand" "")
7056 (match_operand:SI 2 "arith_operand" "")])
7057 (match_operand 3 ""))]
7059 "operands[1] = gen_compare_reg (operands[0]);
7060 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7062 operands[2] = const0_rtx;")
7064 (define_expand "ctrapdi4"
7065 [(trap_if (match_operator 0 "noov_compare_operator"
7066 [(match_operand:DI 1 "compare_operand" "")
7067 (match_operand:DI 2 "arith_operand" "")])
7068 (match_operand 3 ""))]
7070 "operands[1] = gen_compare_reg (operands[0]);
7071 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7073 operands[2] = const0_rtx;")
7077 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7078 (match_operand:SI 1 "arith_operand" "rM"))]
7082 return "t%C0\t%%icc, %1";
7086 [(set_attr "type" "trap")])
7089 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7090 (match_operand:SI 1 "arith_operand" "rM"))]
7093 [(set_attr "type" "trap")])
7096 ;; TLS support instructions.
7098 (define_insn "tgd_hi22"
7099 [(set (match_operand:SI 0 "register_operand" "=r")
7100 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7103 "sethi\\t%%tgd_hi22(%a1), %0")
7105 (define_insn "tgd_lo10"
7106 [(set (match_operand:SI 0 "register_operand" "=r")
7107 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7108 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7111 "add\\t%1, %%tgd_lo10(%a2), %0")
7113 (define_insn "tgd_add32"
7114 [(set (match_operand:SI 0 "register_operand" "=r")
7115 (plus:SI (match_operand:SI 1 "register_operand" "r")
7116 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7117 (match_operand 3 "tgd_symbolic_operand" "")]
7119 "TARGET_TLS && TARGET_ARCH32"
7120 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7122 (define_insn "tgd_add64"
7123 [(set (match_operand:DI 0 "register_operand" "=r")
7124 (plus:DI (match_operand:DI 1 "register_operand" "r")
7125 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7126 (match_operand 3 "tgd_symbolic_operand" "")]
7128 "TARGET_TLS && TARGET_ARCH64"
7129 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7131 (define_insn "tgd_call32"
7132 [(set (match_operand 0 "register_operand" "=r")
7133 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7134 (match_operand 2 "tgd_symbolic_operand" "")]
7136 (match_operand 3 "" "")))
7137 (clobber (reg:SI O7_REG))]
7138 "TARGET_TLS && TARGET_ARCH32"
7139 "call\t%a1, %%tgd_call(%a2)%#"
7140 [(set_attr "type" "call")])
7142 (define_insn "tgd_call64"
7143 [(set (match_operand 0 "register_operand" "=r")
7144 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7145 (match_operand 2 "tgd_symbolic_operand" "")]
7147 (match_operand 3 "" "")))
7148 (clobber (reg:DI O7_REG))]
7149 "TARGET_TLS && TARGET_ARCH64"
7150 "call\t%a1, %%tgd_call(%a2)%#"
7151 [(set_attr "type" "call")])
7153 (define_insn "tldm_hi22"
7154 [(set (match_operand:SI 0 "register_operand" "=r")
7155 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7157 "sethi\\t%%tldm_hi22(%&), %0")
7159 (define_insn "tldm_lo10"
7160 [(set (match_operand:SI 0 "register_operand" "=r")
7161 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7162 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7164 "add\\t%1, %%tldm_lo10(%&), %0")
7166 (define_insn "tldm_add32"
7167 [(set (match_operand:SI 0 "register_operand" "=r")
7168 (plus:SI (match_operand:SI 1 "register_operand" "r")
7169 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7171 "TARGET_TLS && TARGET_ARCH32"
7172 "add\\t%1, %2, %0, %%tldm_add(%&)")
7174 (define_insn "tldm_add64"
7175 [(set (match_operand:DI 0 "register_operand" "=r")
7176 (plus:DI (match_operand:DI 1 "register_operand" "r")
7177 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7179 "TARGET_TLS && TARGET_ARCH64"
7180 "add\\t%1, %2, %0, %%tldm_add(%&)")
7182 (define_insn "tldm_call32"
7183 [(set (match_operand 0 "register_operand" "=r")
7184 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7186 (match_operand 2 "" "")))
7187 (clobber (reg:SI O7_REG))]
7188 "TARGET_TLS && TARGET_ARCH32"
7189 "call\t%a1, %%tldm_call(%&)%#"
7190 [(set_attr "type" "call")])
7192 (define_insn "tldm_call64"
7193 [(set (match_operand 0 "register_operand" "=r")
7194 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7196 (match_operand 2 "" "")))
7197 (clobber (reg:DI O7_REG))]
7198 "TARGET_TLS && TARGET_ARCH64"
7199 "call\t%a1, %%tldm_call(%&)%#"
7200 [(set_attr "type" "call")])
7202 (define_insn "tldo_hix22"
7203 [(set (match_operand:SI 0 "register_operand" "=r")
7204 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7207 "sethi\\t%%tldo_hix22(%a1), %0")
7209 (define_insn "tldo_lox10"
7210 [(set (match_operand:SI 0 "register_operand" "=r")
7211 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7212 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7215 "xor\\t%1, %%tldo_lox10(%a2), %0")
7217 (define_insn "tldo_add32"
7218 [(set (match_operand:SI 0 "register_operand" "=r")
7219 (plus:SI (match_operand:SI 1 "register_operand" "r")
7220 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7221 (match_operand 3 "tld_symbolic_operand" "")]
7223 "TARGET_TLS && TARGET_ARCH32"
7224 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7226 (define_insn "tldo_add64"
7227 [(set (match_operand:DI 0 "register_operand" "=r")
7228 (plus:DI (match_operand:DI 1 "register_operand" "r")
7229 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7230 (match_operand 3 "tld_symbolic_operand" "")]
7232 "TARGET_TLS && TARGET_ARCH64"
7233 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7235 (define_insn "tie_hi22"
7236 [(set (match_operand:SI 0 "register_operand" "=r")
7237 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7240 "sethi\\t%%tie_hi22(%a1), %0")
7242 (define_insn "tie_lo10"
7243 [(set (match_operand:SI 0 "register_operand" "=r")
7244 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7245 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7248 "add\\t%1, %%tie_lo10(%a2), %0")
7250 (define_insn "tie_ld32"
7251 [(set (match_operand:SI 0 "register_operand" "=r")
7252 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7253 (match_operand:SI 2 "register_operand" "r")
7254 (match_operand 3 "tie_symbolic_operand" "")]
7256 "TARGET_TLS && TARGET_ARCH32"
7257 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7258 [(set_attr "type" "load")])
7260 (define_insn "tie_ld64"
7261 [(set (match_operand:DI 0 "register_operand" "=r")
7262 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7263 (match_operand:SI 2 "register_operand" "r")
7264 (match_operand 3 "tie_symbolic_operand" "")]
7266 "TARGET_TLS && TARGET_ARCH64"
7267 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7268 [(set_attr "type" "load")])
7270 (define_insn "tie_add32"
7271 [(set (match_operand:SI 0 "register_operand" "=r")
7272 (plus:SI (match_operand:SI 1 "register_operand" "r")
7273 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7274 (match_operand 3 "tie_symbolic_operand" "")]
7276 "TARGET_SUN_TLS && TARGET_ARCH32"
7277 "add\\t%1, %2, %0, %%tie_add(%a3)")
7279 (define_insn "tie_add64"
7280 [(set (match_operand:DI 0 "register_operand" "=r")
7281 (plus:DI (match_operand:DI 1 "register_operand" "r")
7282 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7283 (match_operand 3 "tie_symbolic_operand" "")]
7285 "TARGET_SUN_TLS && TARGET_ARCH64"
7286 "add\\t%1, %2, %0, %%tie_add(%a3)")
7288 (define_insn "tle_hix22_sp32"
7289 [(set (match_operand:SI 0 "register_operand" "=r")
7290 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7292 "TARGET_TLS && TARGET_ARCH32"
7293 "sethi\\t%%tle_hix22(%a1), %0")
7295 (define_insn "tle_lox10_sp32"
7296 [(set (match_operand:SI 0 "register_operand" "=r")
7297 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7298 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7300 "TARGET_TLS && TARGET_ARCH32"
7301 "xor\\t%1, %%tle_lox10(%a2), %0")
7303 (define_insn "tle_hix22_sp64"
7304 [(set (match_operand:DI 0 "register_operand" "=r")
7305 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7307 "TARGET_TLS && TARGET_ARCH64"
7308 "sethi\\t%%tle_hix22(%a1), %0")
7310 (define_insn "tle_lox10_sp64"
7311 [(set (match_operand:DI 0 "register_operand" "=r")
7312 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7313 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7315 "TARGET_TLS && TARGET_ARCH64"
7316 "xor\\t%1, %%tle_lox10(%a2), %0")
7318 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7319 (define_insn "*tldo_ldub_sp32"
7320 [(set (match_operand:QI 0 "register_operand" "=r")
7321 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7322 (match_operand 3 "tld_symbolic_operand" "")]
7324 (match_operand:SI 1 "register_operand" "r"))))]
7325 "TARGET_TLS && TARGET_ARCH32"
7326 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7327 [(set_attr "type" "load")
7328 (set_attr "us3load_type" "3cycle")])
7330 (define_insn "*tldo_ldub1_sp32"
7331 [(set (match_operand:HI 0 "register_operand" "=r")
7332 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7333 (match_operand 3 "tld_symbolic_operand" "")]
7335 (match_operand:SI 1 "register_operand" "r")))))]
7336 "TARGET_TLS && TARGET_ARCH32"
7337 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7338 [(set_attr "type" "load")
7339 (set_attr "us3load_type" "3cycle")])
7341 (define_insn "*tldo_ldub2_sp32"
7342 [(set (match_operand:SI 0 "register_operand" "=r")
7343 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7344 (match_operand 3 "tld_symbolic_operand" "")]
7346 (match_operand:SI 1 "register_operand" "r")))))]
7347 "TARGET_TLS && TARGET_ARCH32"
7348 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7349 [(set_attr "type" "load")
7350 (set_attr "us3load_type" "3cycle")])
7352 (define_insn "*tldo_ldsb1_sp32"
7353 [(set (match_operand:HI 0 "register_operand" "=r")
7354 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7355 (match_operand 3 "tld_symbolic_operand" "")]
7357 (match_operand:SI 1 "register_operand" "r")))))]
7358 "TARGET_TLS && TARGET_ARCH32"
7359 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7360 [(set_attr "type" "sload")
7361 (set_attr "us3load_type" "3cycle")])
7363 (define_insn "*tldo_ldsb2_sp32"
7364 [(set (match_operand:SI 0 "register_operand" "=r")
7365 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7366 (match_operand 3 "tld_symbolic_operand" "")]
7368 (match_operand:SI 1 "register_operand" "r")))))]
7369 "TARGET_TLS && TARGET_ARCH32"
7370 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7371 [(set_attr "type" "sload")
7372 (set_attr "us3load_type" "3cycle")])
7374 (define_insn "*tldo_ldub_sp64"
7375 [(set (match_operand:QI 0 "register_operand" "=r")
7376 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7377 (match_operand 3 "tld_symbolic_operand" "")]
7379 (match_operand:DI 1 "register_operand" "r"))))]
7380 "TARGET_TLS && TARGET_ARCH64"
7381 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7382 [(set_attr "type" "load")
7383 (set_attr "us3load_type" "3cycle")])
7385 (define_insn "*tldo_ldub1_sp64"
7386 [(set (match_operand:HI 0 "register_operand" "=r")
7387 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7388 (match_operand 3 "tld_symbolic_operand" "")]
7390 (match_operand:DI 1 "register_operand" "r")))))]
7391 "TARGET_TLS && TARGET_ARCH64"
7392 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7393 [(set_attr "type" "load")
7394 (set_attr "us3load_type" "3cycle")])
7396 (define_insn "*tldo_ldub2_sp64"
7397 [(set (match_operand:SI 0 "register_operand" "=r")
7398 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7399 (match_operand 3 "tld_symbolic_operand" "")]
7401 (match_operand:DI 1 "register_operand" "r")))))]
7402 "TARGET_TLS && TARGET_ARCH64"
7403 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7404 [(set_attr "type" "load")
7405 (set_attr "us3load_type" "3cycle")])
7407 (define_insn "*tldo_ldub3_sp64"
7408 [(set (match_operand:DI 0 "register_operand" "=r")
7409 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7410 (match_operand 3 "tld_symbolic_operand" "")]
7412 (match_operand:DI 1 "register_operand" "r")))))]
7413 "TARGET_TLS && TARGET_ARCH64"
7414 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7415 [(set_attr "type" "load")
7416 (set_attr "us3load_type" "3cycle")])
7418 (define_insn "*tldo_ldsb1_sp64"
7419 [(set (match_operand:HI 0 "register_operand" "=r")
7420 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7421 (match_operand 3 "tld_symbolic_operand" "")]
7423 (match_operand:DI 1 "register_operand" "r")))))]
7424 "TARGET_TLS && TARGET_ARCH64"
7425 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7426 [(set_attr "type" "sload")
7427 (set_attr "us3load_type" "3cycle")])
7429 (define_insn "*tldo_ldsb2_sp64"
7430 [(set (match_operand:SI 0 "register_operand" "=r")
7431 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7432 (match_operand 3 "tld_symbolic_operand" "")]
7434 (match_operand:DI 1 "register_operand" "r")))))]
7435 "TARGET_TLS && TARGET_ARCH64"
7436 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7437 [(set_attr "type" "sload")
7438 (set_attr "us3load_type" "3cycle")])
7440 (define_insn "*tldo_ldsb3_sp64"
7441 [(set (match_operand:DI 0 "register_operand" "=r")
7442 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7443 (match_operand 3 "tld_symbolic_operand" "")]
7445 (match_operand:DI 1 "register_operand" "r")))))]
7446 "TARGET_TLS && TARGET_ARCH64"
7447 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7448 [(set_attr "type" "sload")
7449 (set_attr "us3load_type" "3cycle")])
7451 (define_insn "*tldo_lduh_sp32"
7452 [(set (match_operand:HI 0 "register_operand" "=r")
7453 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7454 (match_operand 3 "tld_symbolic_operand" "")]
7456 (match_operand:SI 1 "register_operand" "r"))))]
7457 "TARGET_TLS && TARGET_ARCH32"
7458 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7459 [(set_attr "type" "load")
7460 (set_attr "us3load_type" "3cycle")])
7462 (define_insn "*tldo_lduh1_sp32"
7463 [(set (match_operand:SI 0 "register_operand" "=r")
7464 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7465 (match_operand 3 "tld_symbolic_operand" "")]
7467 (match_operand:SI 1 "register_operand" "r")))))]
7468 "TARGET_TLS && TARGET_ARCH32"
7469 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7470 [(set_attr "type" "load")
7471 (set_attr "us3load_type" "3cycle")])
7473 (define_insn "*tldo_ldsh1_sp32"
7474 [(set (match_operand:SI 0 "register_operand" "=r")
7475 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7476 (match_operand 3 "tld_symbolic_operand" "")]
7478 (match_operand:SI 1 "register_operand" "r")))))]
7479 "TARGET_TLS && TARGET_ARCH32"
7480 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7481 [(set_attr "type" "sload")
7482 (set_attr "us3load_type" "3cycle")])
7484 (define_insn "*tldo_lduh_sp64"
7485 [(set (match_operand:HI 0 "register_operand" "=r")
7486 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7487 (match_operand 3 "tld_symbolic_operand" "")]
7489 (match_operand:DI 1 "register_operand" "r"))))]
7490 "TARGET_TLS && TARGET_ARCH64"
7491 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7492 [(set_attr "type" "load")
7493 (set_attr "us3load_type" "3cycle")])
7495 (define_insn "*tldo_lduh1_sp64"
7496 [(set (match_operand:SI 0 "register_operand" "=r")
7497 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7498 (match_operand 3 "tld_symbolic_operand" "")]
7500 (match_operand:DI 1 "register_operand" "r")))))]
7501 "TARGET_TLS && TARGET_ARCH64"
7502 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7503 [(set_attr "type" "load")
7504 (set_attr "us3load_type" "3cycle")])
7506 (define_insn "*tldo_lduh2_sp64"
7507 [(set (match_operand:DI 0 "register_operand" "=r")
7508 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7509 (match_operand 3 "tld_symbolic_operand" "")]
7511 (match_operand:DI 1 "register_operand" "r")))))]
7512 "TARGET_TLS && TARGET_ARCH64"
7513 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7514 [(set_attr "type" "load")
7515 (set_attr "us3load_type" "3cycle")])
7517 (define_insn "*tldo_ldsh1_sp64"
7518 [(set (match_operand:SI 0 "register_operand" "=r")
7519 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7520 (match_operand 3 "tld_symbolic_operand" "")]
7522 (match_operand:DI 1 "register_operand" "r")))))]
7523 "TARGET_TLS && TARGET_ARCH64"
7524 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7525 [(set_attr "type" "sload")
7526 (set_attr "us3load_type" "3cycle")])
7528 (define_insn "*tldo_ldsh2_sp64"
7529 [(set (match_operand:DI 0 "register_operand" "=r")
7530 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7531 (match_operand 3 "tld_symbolic_operand" "")]
7533 (match_operand:DI 1 "register_operand" "r")))))]
7534 "TARGET_TLS && TARGET_ARCH64"
7535 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7536 [(set_attr "type" "sload")
7537 (set_attr "us3load_type" "3cycle")])
7539 (define_insn "*tldo_lduw_sp32"
7540 [(set (match_operand:SI 0 "register_operand" "=r")
7541 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7542 (match_operand 3 "tld_symbolic_operand" "")]
7544 (match_operand:SI 1 "register_operand" "r"))))]
7545 "TARGET_TLS && TARGET_ARCH32"
7546 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7547 [(set_attr "type" "load")])
7549 (define_insn "*tldo_lduw_sp64"
7550 [(set (match_operand:SI 0 "register_operand" "=r")
7551 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7552 (match_operand 3 "tld_symbolic_operand" "")]
7554 (match_operand:DI 1 "register_operand" "r"))))]
7555 "TARGET_TLS && TARGET_ARCH64"
7556 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7557 [(set_attr "type" "load")])
7559 (define_insn "*tldo_lduw1_sp64"
7560 [(set (match_operand:DI 0 "register_operand" "=r")
7561 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7562 (match_operand 3 "tld_symbolic_operand" "")]
7564 (match_operand:DI 1 "register_operand" "r")))))]
7565 "TARGET_TLS && TARGET_ARCH64"
7566 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7567 [(set_attr "type" "load")])
7569 (define_insn "*tldo_ldsw1_sp64"
7570 [(set (match_operand:DI 0 "register_operand" "=r")
7571 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7572 (match_operand 3 "tld_symbolic_operand" "")]
7574 (match_operand:DI 1 "register_operand" "r")))))]
7575 "TARGET_TLS && TARGET_ARCH64"
7576 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7577 [(set_attr "type" "sload")
7578 (set_attr "us3load_type" "3cycle")])
7580 (define_insn "*tldo_ldx_sp64"
7581 [(set (match_operand:DI 0 "register_operand" "=r")
7582 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7583 (match_operand 3 "tld_symbolic_operand" "")]
7585 (match_operand:DI 1 "register_operand" "r"))))]
7586 "TARGET_TLS && TARGET_ARCH64"
7587 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7588 [(set_attr "type" "load")])
7590 (define_insn "*tldo_stb_sp32"
7591 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7592 (match_operand 3 "tld_symbolic_operand" "")]
7594 (match_operand:SI 1 "register_operand" "r")))
7595 (match_operand:QI 0 "register_operand" "=r"))]
7596 "TARGET_TLS && TARGET_ARCH32"
7597 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7598 [(set_attr "type" "store")])
7600 (define_insn "*tldo_stb_sp64"
7601 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7602 (match_operand 3 "tld_symbolic_operand" "")]
7604 (match_operand:DI 1 "register_operand" "r")))
7605 (match_operand:QI 0 "register_operand" "=r"))]
7606 "TARGET_TLS && TARGET_ARCH64"
7607 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7608 [(set_attr "type" "store")])
7610 (define_insn "*tldo_sth_sp32"
7611 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7612 (match_operand 3 "tld_symbolic_operand" "")]
7614 (match_operand:SI 1 "register_operand" "r")))
7615 (match_operand:HI 0 "register_operand" "=r"))]
7616 "TARGET_TLS && TARGET_ARCH32"
7617 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7618 [(set_attr "type" "store")])
7620 (define_insn "*tldo_sth_sp64"
7621 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7622 (match_operand 3 "tld_symbolic_operand" "")]
7624 (match_operand:DI 1 "register_operand" "r")))
7625 (match_operand:HI 0 "register_operand" "=r"))]
7626 "TARGET_TLS && TARGET_ARCH64"
7627 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7628 [(set_attr "type" "store")])
7630 (define_insn "*tldo_stw_sp32"
7631 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7632 (match_operand 3 "tld_symbolic_operand" "")]
7634 (match_operand:SI 1 "register_operand" "r")))
7635 (match_operand:SI 0 "register_operand" "=r"))]
7636 "TARGET_TLS && TARGET_ARCH32"
7637 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7638 [(set_attr "type" "store")])
7640 (define_insn "*tldo_stw_sp64"
7641 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7642 (match_operand 3 "tld_symbolic_operand" "")]
7644 (match_operand:DI 1 "register_operand" "r")))
7645 (match_operand:SI 0 "register_operand" "=r"))]
7646 "TARGET_TLS && TARGET_ARCH64"
7647 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7648 [(set_attr "type" "store")])
7650 (define_insn "*tldo_stx_sp64"
7651 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7652 (match_operand 3 "tld_symbolic_operand" "")]
7654 (match_operand:DI 1 "register_operand" "r")))
7655 (match_operand:DI 0 "register_operand" "=r"))]
7656 "TARGET_TLS && TARGET_ARCH64"
7657 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7658 [(set_attr "type" "store")])
7661 ;; Stack protector instructions.
7663 (define_expand "stack_protect_set"
7664 [(match_operand 0 "memory_operand" "")
7665 (match_operand 1 "memory_operand" "")]
7668 #ifdef TARGET_THREAD_SSP_OFFSET
7669 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7670 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7671 operands[1] = gen_rtx_MEM (Pmode, addr);
7674 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7676 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7680 (define_insn "stack_protect_setsi"
7681 [(set (match_operand:SI 0 "memory_operand" "=m")
7682 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7683 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7685 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7686 [(set_attr "type" "multi")
7687 (set_attr "length" "3")])
7689 (define_insn "stack_protect_setdi"
7690 [(set (match_operand:DI 0 "memory_operand" "=m")
7691 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7692 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7694 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7695 [(set_attr "type" "multi")
7696 (set_attr "length" "3")])
7698 (define_expand "stack_protect_test"
7699 [(match_operand 0 "memory_operand" "")
7700 (match_operand 1 "memory_operand" "")
7701 (match_operand 2 "" "")]
7705 #ifdef TARGET_THREAD_SSP_OFFSET
7706 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7707 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7708 operands[1] = gen_rtx_MEM (Pmode, addr);
7712 result = gen_reg_rtx (Pmode);
7713 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7714 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7715 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7719 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7720 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7721 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7722 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7727 (define_insn "stack_protect_testsi"
7728 [(set (reg:CC CC_REG)
7729 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7730 (match_operand:SI 1 "memory_operand" "m")]
7732 (set (match_scratch:SI 3 "=r") (const_int 0))
7733 (clobber (match_scratch:SI 2 "=&r"))]
7735 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7736 [(set_attr "type" "multi")
7737 (set_attr "length" "4")])
7739 (define_insn "stack_protect_testdi"
7740 [(set (match_operand:DI 0 "register_operand" "=&r")
7741 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7742 (match_operand:DI 2 "memory_operand" "m")]
7744 (set (match_scratch:DI 3 "=r") (const_int 0))]
7746 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7747 [(set_attr "type" "multi")
7748 (set_attr "length" "4")])
7751 ;; Vector instructions.
7753 (define_insn "addv2si3"
7754 [(set (match_operand:V2SI 0 "register_operand" "=e")
7755 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7756 (match_operand:V2SI 2 "register_operand" "e")))]
7758 "fpadd32\t%1, %2, %0"
7759 [(set_attr "type" "fga")
7760 (set_attr "fptype" "double")])
7762 (define_insn "addv4hi3"
7763 [(set (match_operand:V4HI 0 "register_operand" "=e")
7764 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7765 (match_operand:V4HI 2 "register_operand" "e")))]
7767 "fpadd16\t%1, %2, %0"
7768 [(set_attr "type" "fga")
7769 (set_attr "fptype" "double")])
7771 ;; fpadd32s is emitted by the addsi3 pattern.
7773 (define_insn "addv2hi3"
7774 [(set (match_operand:V2HI 0 "register_operand" "=f")
7775 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7776 (match_operand:V2HI 2 "register_operand" "f")))]
7778 "fpadd16s\t%1, %2, %0"
7779 [(set_attr "type" "fga")
7780 (set_attr "fptype" "single")])
7782 (define_insn "subv2si3"
7783 [(set (match_operand:V2SI 0 "register_operand" "=e")
7784 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7785 (match_operand:V2SI 2 "register_operand" "e")))]
7787 "fpsub32\t%1, %2, %0"
7788 [(set_attr "type" "fga")
7789 (set_attr "fptype" "double")])
7791 (define_insn "subv4hi3"
7792 [(set (match_operand:V4HI 0 "register_operand" "=e")
7793 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7794 (match_operand:V4HI 2 "register_operand" "e")))]
7796 "fpsub16\t%1, %2, %0"
7797 [(set_attr "type" "fga")
7798 (set_attr "fptype" "double")])
7800 ;; fpsub32s is emitted by the subsi3 pattern.
7802 (define_insn "subv2hi3"
7803 [(set (match_operand:V2HI 0 "register_operand" "=f")
7804 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7805 (match_operand:V2HI 2 "register_operand" "f")))]
7807 "fpsub16s\t%1, %2, %0"
7808 [(set_attr "type" "fga")
7809 (set_attr "fptype" "single")])
7811 ;; All other logical instructions have integer equivalents so they
7812 ;; are defined together.
7814 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7816 (define_insn "*nand<V64:mode>_vis"
7817 [(set (match_operand:V64 0 "register_operand" "=e")
7818 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7819 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7822 [(set_attr "type" "fga")
7823 (set_attr "fptype" "double")])
7825 (define_insn "*nand<V32:mode>_vis"
7826 [(set (match_operand:V32 0 "register_operand" "=f")
7827 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7828 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7830 "fnands\t%1, %2, %0"
7831 [(set_attr "type" "fga")
7832 (set_attr "fptype" "single")])
7834 ;; Hard to generate VIS instructions. We have builtins for these.
7836 (define_insn "fpack16_vis"
7837 [(set (match_operand:V4QI 0 "register_operand" "=f")
7838 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7840 (use (reg:DI GSR_REG))]
7843 [(set_attr "type" "fga")
7844 (set_attr "fptype" "double")])
7846 (define_insn "fpackfix_vis"
7847 [(set (match_operand:V2HI 0 "register_operand" "=f")
7848 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7850 (use (reg:DI GSR_REG))]
7853 [(set_attr "type" "fga")
7854 (set_attr "fptype" "double")])
7856 (define_insn "fpack32_vis"
7857 [(set (match_operand:V8QI 0 "register_operand" "=e")
7858 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7859 (match_operand:V8QI 2 "register_operand" "e")]
7861 (use (reg:DI GSR_REG))]
7863 "fpack32\t%1, %2, %0"
7864 [(set_attr "type" "fga")
7865 (set_attr "fptype" "double")])
7867 (define_insn "fexpand_vis"
7868 [(set (match_operand:V4HI 0 "register_operand" "=e")
7869 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7873 [(set_attr "type" "fga")
7874 (set_attr "fptype" "double")])
7876 ;; It may be possible to describe this operation as (1 indexed):
7877 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7878 ;; 1,5,10,14,19,23,28,32)
7879 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7880 ;; because vec_merge expects all the operands to be of the same type.
7881 (define_insn "fpmerge_vis"
7882 [(set (match_operand:V8QI 0 "register_operand" "=e")
7883 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7884 (match_operand:V4QI 2 "register_operand" "f")]
7887 "fpmerge\t%1, %2, %0"
7888 [(set_attr "type" "fga")
7889 (set_attr "fptype" "double")])
7891 ;; Partitioned multiply instructions
7892 (define_insn "fmul8x16_vis"
7893 [(set (match_operand:V4HI 0 "register_operand" "=e")
7894 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7895 (match_operand:V4HI 2 "register_operand" "e")))]
7897 "fmul8x16\t%1, %2, %0"
7898 [(set_attr "type" "fpmul")
7899 (set_attr "fptype" "double")])
7901 ;; Only one of the following two insns can be a multiply.
7902 (define_insn "fmul8x16au_vis"
7903 [(set (match_operand:V4HI 0 "register_operand" "=e")
7904 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7905 (match_operand:V2HI 2 "register_operand" "f")))]
7907 "fmul8x16au\t%1, %2, %0"
7908 [(set_attr "type" "fpmul")
7909 (set_attr "fptype" "double")])
7911 (define_insn "fmul8x16al_vis"
7912 [(set (match_operand:V4HI 0 "register_operand" "=e")
7913 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7914 (match_operand:V2HI 2 "register_operand" "f")]
7917 "fmul8x16al\t%1, %2, %0"
7918 [(set_attr "type" "fpmul")
7919 (set_attr "fptype" "double")])
7921 ;; Only one of the following two insns can be a multiply.
7922 (define_insn "fmul8sux16_vis"
7923 [(set (match_operand:V4HI 0 "register_operand" "=e")
7924 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7925 (match_operand:V4HI 2 "register_operand" "e")))]
7927 "fmul8sux16\t%1, %2, %0"
7928 [(set_attr "type" "fpmul")
7929 (set_attr "fptype" "double")])
7931 (define_insn "fmul8ulx16_vis"
7932 [(set (match_operand:V4HI 0 "register_operand" "=e")
7933 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7934 (match_operand:V4HI 2 "register_operand" "e")]
7937 "fmul8ulx16\t%1, %2, %0"
7938 [(set_attr "type" "fpmul")
7939 (set_attr "fptype" "double")])
7941 ;; Only one of the following two insns can be a multiply.
7942 (define_insn "fmuld8sux16_vis"
7943 [(set (match_operand:V2SI 0 "register_operand" "=e")
7944 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7945 (match_operand:V2HI 2 "register_operand" "f")))]
7947 "fmuld8sux16\t%1, %2, %0"
7948 [(set_attr "type" "fpmul")
7949 (set_attr "fptype" "double")])
7951 (define_insn "fmuld8ulx16_vis"
7952 [(set (match_operand:V2SI 0 "register_operand" "=e")
7953 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7954 (match_operand:V2HI 2 "register_operand" "f")]
7957 "fmuld8ulx16\t%1, %2, %0"
7958 [(set_attr "type" "fpmul")
7959 (set_attr "fptype" "double")])
7961 (define_expand "wrgsr_vis"
7962 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
7965 if (! TARGET_ARCH64)
7967 emit_insn (gen_wrgsr_v8plus (operands[0]));
7972 (define_insn "*wrgsr_sp64"
7973 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
7974 "TARGET_VIS && TARGET_ARCH64"
7975 "wr\t%%g0, %0, %%gsr"
7976 [(set_attr "type" "gsr")])
7978 (define_insn "wrgsr_v8plus"
7979 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
7980 (clobber (match_scratch:SI 1 "=X,&h"))]
7981 "TARGET_VIS && ! TARGET_ARCH64"
7983 if (GET_CODE (operands[0]) == CONST_INT
7984 || sparc_check_64 (operands[0], insn))
7985 return "wr\t%%g0, %0, %%gsr";
7987 output_asm_insn("srl\t%L0, 0, %L0", operands);
7988 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
7990 [(set_attr "type" "multi")])
7992 (define_expand "rdgsr_vis"
7993 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
7996 if (! TARGET_ARCH64)
7998 emit_insn (gen_rdgsr_v8plus (operands[0]));
8003 (define_insn "*rdgsr_sp64"
8004 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8005 "TARGET_VIS && TARGET_ARCH64"
8007 [(set_attr "type" "gsr")])
8009 (define_insn "rdgsr_v8plus"
8010 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8011 (clobber (match_scratch:SI 1 "=&h"))]
8012 "TARGET_VIS && ! TARGET_ARCH64"
8014 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8016 [(set_attr "type" "multi")])
8018 ;; Using faligndata only makes sense after an alignaddr since the choice of
8019 ;; bytes to take out of each operand is dependent on the results of the last
8021 (define_insn "faligndata<V64I:mode>_vis"
8022 [(set (match_operand:V64I 0 "register_operand" "=e")
8023 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8024 (match_operand:V64I 2 "register_operand" "e")]
8026 (use (reg:SI GSR_REG))]
8028 "faligndata\t%1, %2, %0"
8029 [(set_attr "type" "fga")
8030 (set_attr "fptype" "double")])
8032 (define_insn "alignaddrsi_vis"
8033 [(set (match_operand:SI 0 "register_operand" "=r")
8034 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8035 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8036 (set (reg:SI GSR_REG)
8037 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8038 (and:SI (plus:SI (match_dup 1) (match_dup 2))
8041 "alignaddr\t%r1, %r2, %0")
8043 (define_insn "alignaddrdi_vis"
8044 [(set (match_operand:DI 0 "register_operand" "=r")
8045 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8046 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8047 (set (reg:SI GSR_REG)
8048 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8049 (and:SI (truncate:SI (plus:DI (match_dup 1) (match_dup 2)))
8052 "alignaddr\t%r1, %r2, %0")
8054 (define_insn "alignaddrlsi_vis"
8055 [(set (match_operand:SI 0 "register_operand" "=r")
8056 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8057 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8058 (set (reg:SI GSR_REG)
8059 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8060 (xor:SI (and:SI (plus:SI (match_dup 1) (match_dup 2))
8064 "alignaddrl\t%r1, %r2, %0")
8066 (define_insn "alignaddrldi_vis"
8067 [(set (match_operand:DI 0 "register_operand" "=r")
8068 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8069 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8070 (set (reg:SI GSR_REG)
8071 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8072 (xor:SI (and:SI (truncate:SI (plus:DI (match_dup 1)
8077 "alignaddrl\t%r1, %r2, %0")
8079 (define_insn "pdist_vis"
8080 [(set (match_operand:DI 0 "register_operand" "=e")
8081 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8082 (match_operand:V8QI 2 "register_operand" "e")
8083 (match_operand:DI 3 "register_operand" "0")]
8087 [(set_attr "type" "fga")
8088 (set_attr "fptype" "double")])
8090 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8091 ;; with the same operands.
8092 (define_insn "edge8<P:mode>_vis"
8093 [(set (reg:CC_NOOV CC_REG)
8094 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8095 (match_operand:P 2 "register_operand" "rJ"))
8097 (set (match_operand:P 0 "register_operand" "=r")
8098 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8100 "edge8\t%r1, %r2, %0"
8101 [(set_attr "type" "edge")])
8103 (define_insn "edge8l<P:mode>_vis"
8104 [(set (reg:CC_NOOV CC_REG)
8105 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8106 (match_operand:P 2 "register_operand" "rJ"))
8108 (set (match_operand:P 0 "register_operand" "=r")
8109 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8111 "edge8l\t%r1, %r2, %0"
8112 [(set_attr "type" "edge")])
8114 (define_insn "edge16<P:mode>_vis"
8115 [(set (reg:CC_NOOV CC_REG)
8116 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8117 (match_operand:P 2 "register_operand" "rJ"))
8119 (set (match_operand:P 0 "register_operand" "=r")
8120 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8122 "edge16\t%r1, %r2, %0"
8123 [(set_attr "type" "edge")])
8125 (define_insn "edge16l<P:mode>_vis"
8126 [(set (reg:CC_NOOV CC_REG)
8127 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8128 (match_operand:P 2 "register_operand" "rJ"))
8130 (set (match_operand:P 0 "register_operand" "=r")
8131 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8133 "edge16l\t%r1, %r2, %0"
8134 [(set_attr "type" "edge")])
8136 (define_insn "edge32<P:mode>_vis"
8137 [(set (reg:CC_NOOV CC_REG)
8138 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8139 (match_operand:P 2 "register_operand" "rJ"))
8141 (set (match_operand:P 0 "register_operand" "=r")
8142 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8144 "edge32\t%r1, %r2, %0"
8145 [(set_attr "type" "edge")])
8147 (define_insn "edge32l<P:mode>_vis"
8148 [(set (reg:CC_NOOV CC_REG)
8149 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8150 (match_operand:P 2 "register_operand" "rJ"))
8152 (set (match_operand:P 0 "register_operand" "=r")
8153 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8155 "edge32l\t%r1, %r2, %0"
8156 [(set_attr "type" "edge")])
8158 (define_code_iterator gcond [le ne gt eq])
8159 (define_mode_iterator GCM [V4HI V2SI])
8160 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8162 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8163 [(set (match_operand:P 0 "register_operand" "=r")
8164 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8165 (match_operand:GCM 2 "register_operand" "e"))]
8168 "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8169 [(set_attr "type" "fpmul")
8170 (set_attr "fptype" "double")])
8172 (define_insn "array8<P:mode>_vis"
8173 [(set (match_operand:P 0 "register_operand" "=r")
8174 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8175 (match_operand:P 2 "register_operand" "rJ")]
8178 "array8\t%r1, %r2, %0"
8179 [(set_attr "type" "array")])
8181 (define_insn "array16<P:mode>_vis"
8182 [(set (match_operand:P 0 "register_operand" "=r")
8183 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8184 (match_operand:P 2 "register_operand" "rJ")]
8187 "array16\t%r1, %r2, %0"
8188 [(set_attr "type" "array")])
8190 (define_insn "array32<P:mode>_vis"
8191 [(set (match_operand:P 0 "register_operand" "=r")
8192 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8193 (match_operand:P 2 "register_operand" "rJ")]
8196 "array32\t%r1, %r2, %0"
8197 [(set_attr "type" "array")])
8199 (define_insn "bmask<P:mode>_vis"
8200 [(set (match_operand:P 0 "register_operand" "=r")
8201 (plus:P (match_operand:P 1 "register_operand" "rJ")
8202 (match_operand:P 2 "register_operand" "rJ")))
8203 (clobber (reg:SI GSR_REG))]
8205 "bmask\t%r1, %r2, %0"
8206 [(set_attr "type" "array")])
8208 (define_insn "bshuffle<V64I:mode>_vis"
8209 [(set (match_operand:V64I 0 "register_operand" "=e")
8210 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8211 (match_operand:V64I 2 "register_operand" "e")]
8213 (use (reg:SI GSR_REG))]
8215 "bshuffle\t%1, %2, %0"
8216 [(set_attr "type" "fga")
8217 (set_attr "fptype" "double")])
8219 ;; VIS 2.0 adds edge variants which do not set the condition codes
8220 (define_insn "edge8n<P:mode>_vis"
8221 [(set (match_operand:P 0 "register_operand" "=r")
8222 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8223 (match_operand:P 2 "register_operand" "rJ")]
8226 "edge8n\t%r1, %r2, %0"
8227 [(set_attr "type" "edgen")])
8229 (define_insn "edge8ln<P:mode>_vis"
8230 [(set (match_operand:P 0 "register_operand" "=r")
8231 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8232 (match_operand:P 2 "register_operand" "rJ")]
8235 "edge8ln\t%r1, %r2, %0"
8236 [(set_attr "type" "edgen")])
8238 (define_insn "edge16n<P:mode>_vis"
8239 [(set (match_operand:P 0 "register_operand" "=r")
8240 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8241 (match_operand:P 2 "register_operand" "rJ")]
8244 "edge16n\t%r1, %r2, %0"
8245 [(set_attr "type" "edgen")])
8247 (define_insn "edge16ln<P:mode>_vis"
8248 [(set (match_operand:P 0 "register_operand" "=r")
8249 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8250 (match_operand:P 2 "register_operand" "rJ")]
8253 "edge16ln\t%r1, %r2, %0"
8254 [(set_attr "type" "edgen")])
8256 (define_insn "edge32n<P:mode>_vis"
8257 [(set (match_operand:P 0 "register_operand" "=r")
8258 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8259 (match_operand:P 2 "register_operand" "rJ")]
8262 "edge32n\t%r1, %r2, %0"
8263 [(set_attr "type" "edgen")])
8265 (define_insn "edge32ln<P:mode>_vis"
8266 [(set (match_operand:P 0 "register_operand" "=r")
8267 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8268 (match_operand:P 2 "register_operand" "rJ")]
8271 "edge32ln\t%r1, %r2, %0"
8272 [(set_attr "type" "edge")])