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)
88 (UNSPECV_PROBE_STACK_RANGE 11)
181 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
182 (define_mode_iterator I [QI HI SI DI])
183 (define_mode_iterator F [SF DF TF])
185 ;; We don't define V1SI because SI should work just fine.
186 (define_mode_iterator V32 [SF V2HI V4QI])
187 (define_mode_iterator V32I [SI V2HI V4QI])
189 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
190 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
192 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
193 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
194 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
195 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
196 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
199 ;; Attribute for cpu type.
200 ;; These must match the values for enum processor_type in sparc.h.
221 (const (symbol_ref "sparc_cpu_attr")))
223 ;; Attribute for the instruction set.
224 ;; At present we only need to distinguish v9/!v9, but for clarity we
225 ;; test TARGET_V8 too.
226 (define_attr "isa" "v7,v8,v9,sparclet"
228 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
229 (symbol_ref "TARGET_V8") (const_string "v8")
230 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
231 (const_string "v7"))))
237 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
245 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,gsr,
248 multi,savew,flushw,iflush,trap"
249 (const_string "ialu"))
251 ;; True if branch/call has empty delay slot and will emit a nop in it
252 (define_attr "empty_delay_slot" "false,true"
253 (symbol_ref "(empty_delay_slot (insn)
254 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
256 (define_attr "branch_type" "none,icc,fcc,reg"
257 (const_string "none"))
259 (define_attr "pic" "false,true"
260 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
262 (define_attr "calls_alloca" "false,true"
263 (symbol_ref "(cfun->calls_alloca != 0
264 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
266 (define_attr "calls_eh_return" "false,true"
267 (symbol_ref "(crtl->calls_eh_return != 0
268 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
270 (define_attr "leaf_function" "false,true"
271 (symbol_ref "(current_function_uses_only_leaf_regs != 0
272 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
274 (define_attr "delayed_branch" "false,true"
275 (symbol_ref "(flag_delayed_branch != 0
276 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
278 (define_attr "flat" "false,true"
279 (symbol_ref "(TARGET_FLAT != 0
280 ? FLAT_TRUE : FLAT_FALSE)"))
282 ;; Length (in # of insns).
283 ;; Beware that setting a length greater or equal to 3 for conditional branches
284 ;; has a side-effect (see output_cbranch and output_v9branch).
285 (define_attr "length" ""
286 (cond [(eq_attr "type" "uncond_branch,call")
287 (if_then_else (eq_attr "empty_delay_slot" "true")
290 (eq_attr "type" "sibcall")
291 (if_then_else (eq_attr "leaf_function" "true")
292 (if_then_else (eq_attr "empty_delay_slot" "true")
295 (if_then_else (eq_attr "empty_delay_slot" "true")
298 (eq_attr "branch_type" "icc")
299 (if_then_else (match_operand 0 "noov_compare64_operator" "")
300 (if_then_else (lt (pc) (match_dup 1))
301 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
302 (if_then_else (eq_attr "empty_delay_slot" "true")
305 (if_then_else (eq_attr "empty_delay_slot" "true")
308 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
309 (if_then_else (eq_attr "empty_delay_slot" "true")
312 (if_then_else (eq_attr "empty_delay_slot" "true")
315 (if_then_else (eq_attr "empty_delay_slot" "true")
318 (eq_attr "branch_type" "fcc")
319 (if_then_else (match_operand 0 "fcc0_register_operand" "")
320 (if_then_else (eq_attr "empty_delay_slot" "true")
321 (if_then_else (not (match_test "TARGET_V9"))
324 (if_then_else (not (match_test "TARGET_V9"))
327 (if_then_else (lt (pc) (match_dup 2))
328 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
329 (if_then_else (eq_attr "empty_delay_slot" "true")
332 (if_then_else (eq_attr "empty_delay_slot" "true")
335 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
336 (if_then_else (eq_attr "empty_delay_slot" "true")
339 (if_then_else (eq_attr "empty_delay_slot" "true")
342 (eq_attr "branch_type" "reg")
343 (if_then_else (lt (pc) (match_dup 2))
344 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
345 (if_then_else (eq_attr "empty_delay_slot" "true")
348 (if_then_else (eq_attr "empty_delay_slot" "true")
351 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
352 (if_then_else (eq_attr "empty_delay_slot" "true")
355 (if_then_else (eq_attr "empty_delay_slot" "true")
361 (define_attr "fptype" "single,double"
362 (const_string "single"))
364 ;; UltraSPARC-III integer load type.
365 (define_attr "us3load_type" "2cycle,3cycle"
366 (const_string "2cycle"))
368 (define_asm_attributes
369 [(set_attr "length" "2")
370 (set_attr "type" "multi")])
372 ;; Attributes for instruction and branch scheduling
373 (define_attr "tls_call_delay" "false,true"
374 (symbol_ref "(tls_call_delay (insn)
375 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
377 (define_attr "in_call_delay" "false,true"
378 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
379 (const_string "false")
380 (eq_attr "type" "load,fpload,store,fpstore")
381 (if_then_else (eq_attr "length" "1")
382 (const_string "true")
383 (const_string "false"))]
384 (if_then_else (and (eq_attr "length" "1")
385 (eq_attr "tls_call_delay" "true"))
386 (const_string "true")
387 (const_string "false"))))
389 (define_attr "eligible_for_sibcall_delay" "false,true"
390 (symbol_ref "(eligible_for_sibcall_delay (insn)
391 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
392 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
394 (define_attr "eligible_for_return_delay" "false,true"
395 (symbol_ref "(eligible_for_return_delay (insn)
396 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
397 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
399 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
400 ;; branches. This would allow us to remove the nop always inserted before
401 ;; a floating point branch.
403 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
404 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
405 ;; This is because doing so will add several pipeline stalls to the path
406 ;; that the load/store did not come from. Unfortunately, there is no way
407 ;; to prevent fill_eager_delay_slots from using load/store without completely
408 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
409 ;; because it prevents us from moving back the final store of inner loops.
411 (define_attr "in_branch_delay" "false,true"
412 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
413 (eq_attr "length" "1"))
414 (const_string "true")
415 (const_string "false")))
417 (define_attr "in_uncond_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_annul_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_delay (eq_attr "type" "call")
430 [(eq_attr "in_call_delay" "true") (nil) (nil)])
432 (define_delay (eq_attr "type" "sibcall")
433 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
435 (define_delay (eq_attr "type" "branch")
436 [(eq_attr "in_branch_delay" "true")
437 (nil) (eq_attr "in_annul_branch_delay" "true")])
439 (define_delay (eq_attr "type" "uncond_branch")
440 [(eq_attr "in_uncond_branch_delay" "true")
443 (define_delay (eq_attr "type" "return")
444 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
447 ;; Include SPARC DFA schedulers
449 (include "cypress.md")
450 (include "supersparc.md")
451 (include "hypersparc.md")
453 (include "sparclet.md")
454 (include "ultra1_2.md")
455 (include "ultra3.md")
456 (include "niagara.md")
457 (include "niagara2.md")
460 ;; Operand and operator predicates and constraints
462 (include "predicates.md")
463 (include "constraints.md")
466 ;; Compare instructions.
468 ;; These are just the DEFINE_INSNs to match the patterns and the
469 ;; DEFINE_SPLITs for some of the scc insns that actually require
470 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
472 ;; The compare DEFINE_INSNs.
474 (define_insn "*cmpsi_insn"
475 [(set (reg:CC CC_REG)
476 (compare:CC (match_operand:SI 0 "register_operand" "r")
477 (match_operand:SI 1 "arith_operand" "rI")))]
480 [(set_attr "type" "compare")])
482 (define_insn "*cmpdi_sp64"
483 [(set (reg:CCX CC_REG)
484 (compare:CCX (match_operand:DI 0 "register_operand" "r")
485 (match_operand:DI 1 "arith_operand" "rI")))]
488 [(set_attr "type" "compare")])
490 (define_insn "*cmpsf_fpe"
491 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
492 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
493 (match_operand:SF 2 "register_operand" "f")))]
497 return "fcmpes\t%0, %1, %2";
498 return "fcmpes\t%1, %2";
500 [(set_attr "type" "fpcmp")])
502 (define_insn "*cmpdf_fpe"
503 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
504 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
505 (match_operand:DF 2 "register_operand" "e")))]
509 return "fcmped\t%0, %1, %2";
510 return "fcmped\t%1, %2";
512 [(set_attr "type" "fpcmp")
513 (set_attr "fptype" "double")])
515 (define_insn "*cmptf_fpe"
516 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
517 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
518 (match_operand:TF 2 "register_operand" "e")))]
519 "TARGET_FPU && TARGET_HARD_QUAD"
522 return "fcmpeq\t%0, %1, %2";
523 return "fcmpeq\t%1, %2";
525 [(set_attr "type" "fpcmp")])
527 (define_insn "*cmpsf_fp"
528 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
529 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
530 (match_operand:SF 2 "register_operand" "f")))]
534 return "fcmps\t%0, %1, %2";
535 return "fcmps\t%1, %2";
537 [(set_attr "type" "fpcmp")])
539 (define_insn "*cmpdf_fp"
540 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
541 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
542 (match_operand:DF 2 "register_operand" "e")))]
546 return "fcmpd\t%0, %1, %2";
547 return "fcmpd\t%1, %2";
549 [(set_attr "type" "fpcmp")
550 (set_attr "fptype" "double")])
552 (define_insn "*cmptf_fp"
553 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
554 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
555 (match_operand:TF 2 "register_operand" "e")))]
556 "TARGET_FPU && TARGET_HARD_QUAD"
559 return "fcmpq\t%0, %1, %2";
560 return "fcmpq\t%1, %2";
562 [(set_attr "type" "fpcmp")])
564 ;; Next come the scc insns.
566 (define_expand "cstoresi4"
567 [(use (match_operator 1 "comparison_operator"
568 [(match_operand:SI 2 "compare_operand" "")
569 (match_operand:SI 3 "arith_operand" "")]))
570 (clobber (match_operand:SI 0 "register_operand"))]
573 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
574 operands[2] = force_reg (SImode, operands[2]);
575 if (emit_scc_insn (operands)) DONE; else FAIL;
578 (define_expand "cstoredi4"
579 [(use (match_operator 1 "comparison_operator"
580 [(match_operand:DI 2 "compare_operand" "")
581 (match_operand:DI 3 "arith_operand" "")]))
582 (clobber (match_operand:SI 0 "register_operand"))]
585 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
586 operands[2] = force_reg (DImode, operands[2]);
587 if (emit_scc_insn (operands)) DONE; else FAIL;
590 (define_expand "cstore<F:mode>4"
591 [(use (match_operator 1 "comparison_operator"
592 [(match_operand:F 2 "register_operand" "")
593 (match_operand:F 3 "register_operand" "")]))
594 (clobber (match_operand:SI 0 "register_operand"))]
596 { if (emit_scc_insn (operands)) DONE; else FAIL; })
600 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
601 ;; generate addcc/subcc instructions.
603 (define_expand "seqsi_special"
605 (xor:SI (match_operand:SI 1 "register_operand" "")
606 (match_operand:SI 2 "register_operand" "")))
607 (parallel [(set (match_operand:SI 0 "register_operand" "")
608 (eq:SI (match_dup 3) (const_int 0)))
609 (clobber (reg:CC CC_REG))])]
611 { operands[3] = gen_reg_rtx (SImode); })
613 (define_expand "seqdi_special"
615 (xor:DI (match_operand:DI 1 "register_operand" "")
616 (match_operand:DI 2 "register_operand" "")))
617 (set (match_operand:SI 0 "register_operand" "")
618 (eq:SI (match_dup 3) (const_int 0)))]
620 { operands[3] = gen_reg_rtx (DImode); })
622 (define_expand "snesi_special"
624 (xor:SI (match_operand:SI 1 "register_operand" "")
625 (match_operand:SI 2 "register_operand" "")))
626 (parallel [(set (match_operand:SI 0 "register_operand" "")
627 (ne:SI (match_dup 3) (const_int 0)))
628 (clobber (reg:CC CC_REG))])]
630 { operands[3] = gen_reg_rtx (SImode); })
632 (define_expand "snedi_special"
634 (xor:DI (match_operand:DI 1 "register_operand" "")
635 (match_operand:DI 2 "register_operand" "")))
636 (set (match_operand:SI 0 "register_operand" "")
637 (ne:SI (match_dup 3) (const_int 0)))]
639 { operands[3] = gen_reg_rtx (DImode); })
642 ;; Now the DEFINE_INSNs for the scc cases.
644 ;; The SEQ and SNE patterns are special because they can be done
645 ;; without any branching and do not involve a COMPARE. We want
646 ;; them to always use the splits below so the results can be
649 (define_insn_and_split "*snesi_zero"
650 [(set (match_operand:SI 0 "register_operand" "=r")
651 (ne:SI (match_operand:SI 1 "register_operand" "r")
653 (clobber (reg:CC CC_REG))]
657 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
659 (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
661 [(set_attr "length" "2")])
663 (define_insn_and_split "*neg_snesi_zero"
664 [(set (match_operand:SI 0 "register_operand" "=r")
665 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
667 (clobber (reg:CC CC_REG))]
671 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
673 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
675 [(set_attr "length" "2")])
677 (define_insn_and_split "*snesi_zero_extend"
678 [(set (match_operand:DI 0 "register_operand" "=r")
679 (ne:DI (match_operand:SI 1 "register_operand" "r")
681 (clobber (reg:CC CC_REG))]
685 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
688 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
690 (ltu:SI (reg:CC_NOOV CC_REG)
693 [(set_attr "length" "2")])
695 (define_insn_and_split "*snedi_zero"
696 [(set (match_operand:DI 0 "register_operand" "=&r")
697 (ne:DI (match_operand:DI 1 "register_operand" "r")
701 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
702 [(set (match_dup 0) (const_int 0))
703 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
708 [(set_attr "length" "2")])
710 (define_insn_and_split "*neg_snedi_zero"
711 [(set (match_operand:DI 0 "register_operand" "=&r")
712 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
716 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
717 [(set (match_dup 0) (const_int 0))
718 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
723 [(set_attr "length" "2")])
725 (define_insn_and_split "*snedi_zero_trunc"
726 [(set (match_operand:SI 0 "register_operand" "=&r")
727 (ne:SI (match_operand:DI 1 "register_operand" "r")
731 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
732 [(set (match_dup 0) (const_int 0))
733 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
738 [(set_attr "length" "2")])
740 (define_insn_and_split "*seqsi_zero"
741 [(set (match_operand:SI 0 "register_operand" "=r")
742 (eq:SI (match_operand:SI 1 "register_operand" "r")
744 (clobber (reg:CC CC_REG))]
748 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
750 (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
752 [(set_attr "length" "2")])
754 (define_insn_and_split "*neg_seqsi_zero"
755 [(set (match_operand:SI 0 "register_operand" "=r")
756 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
758 (clobber (reg:CC CC_REG))]
762 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
764 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
766 [(set_attr "length" "2")])
768 (define_insn_and_split "*seqsi_zero_extend"
769 [(set (match_operand:DI 0 "register_operand" "=r")
770 (eq:DI (match_operand:SI 1 "register_operand" "r")
772 (clobber (reg:CC CC_REG))]
776 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
779 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
781 (ltu:SI (reg:CC_NOOV CC_REG)
784 [(set_attr "length" "2")])
786 (define_insn_and_split "*seqdi_zero"
787 [(set (match_operand:DI 0 "register_operand" "=&r")
788 (eq:DI (match_operand:DI 1 "register_operand" "r")
792 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
793 [(set (match_dup 0) (const_int 0))
794 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
799 [(set_attr "length" "2")])
801 (define_insn_and_split "*neg_seqdi_zero"
802 [(set (match_operand:DI 0 "register_operand" "=&r")
803 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
807 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
808 [(set (match_dup 0) (const_int 0))
809 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
814 [(set_attr "length" "2")])
816 (define_insn_and_split "*seqdi_zero_trunc"
817 [(set (match_operand:SI 0 "register_operand" "=&r")
818 (eq:SI (match_operand:DI 1 "register_operand" "r")
822 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
823 [(set (match_dup 0) (const_int 0))
824 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
829 [(set_attr "length" "2")])
831 ;; We can also do (x + (i == 0)) and related, so put them in.
832 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
835 (define_insn_and_split "*x_plus_i_ne_0"
836 [(set (match_operand:SI 0 "register_operand" "=r")
837 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
839 (match_operand:SI 2 "register_operand" "r")))
840 (clobber (reg:CC CC_REG))]
844 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
846 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
849 [(set_attr "length" "2")])
851 (define_insn_and_split "*x_minus_i_ne_0"
852 [(set (match_operand:SI 0 "register_operand" "=r")
853 (minus:SI (match_operand:SI 2 "register_operand" "r")
854 (ne:SI (match_operand:SI 1 "register_operand" "r")
856 (clobber (reg:CC CC_REG))]
860 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
862 (set (match_dup 0) (minus:SI (match_dup 2)
863 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
865 [(set_attr "length" "2")])
867 (define_insn_and_split "*x_plus_i_eq_0"
868 [(set (match_operand:SI 0 "register_operand" "=r")
869 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
871 (match_operand:SI 2 "register_operand" "r")))
872 (clobber (reg:CC CC_REG))]
876 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
878 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
881 [(set_attr "length" "2")])
883 (define_insn_and_split "*x_minus_i_eq_0"
884 [(set (match_operand:SI 0 "register_operand" "=r")
885 (minus:SI (match_operand:SI 2 "register_operand" "r")
886 (eq:SI (match_operand:SI 1 "register_operand" "r")
888 (clobber (reg:CC CC_REG))]
892 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
894 (set (match_dup 0) (minus:SI (match_dup 2)
895 (geu:SI (reg:CC CC_REG) (const_int 0))))]
897 [(set_attr "length" "2")])
899 ;; We can also do GEU and LTU directly, but these operate after a compare.
900 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
903 (define_insn "*sltu_insn"
904 [(set (match_operand:SI 0 "register_operand" "=r")
905 (ltu:SI (reg:CC CC_REG) (const_int 0)))]
908 [(set_attr "type" "ialuX")])
910 (define_insn "*neg_sltu_insn"
911 [(set (match_operand:SI 0 "register_operand" "=r")
912 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
915 [(set_attr "type" "ialuX")])
917 ;; ??? Combine should canonicalize these next two to the same pattern.
918 (define_insn "*neg_sltu_minus_x"
919 [(set (match_operand:SI 0 "register_operand" "=r")
920 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
921 (match_operand:SI 1 "arith_operand" "rI")))]
924 [(set_attr "type" "ialuX")])
926 (define_insn "*neg_sltu_plus_x"
927 [(set (match_operand:SI 0 "register_operand" "=r")
928 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
929 (match_operand:SI 1 "arith_operand" "rI"))))]
932 [(set_attr "type" "ialuX")])
934 (define_insn "*sgeu_insn"
935 [(set (match_operand:SI 0 "register_operand" "=r")
936 (geu:SI (reg:CC CC_REG) (const_int 0)))]
939 [(set_attr "type" "ialuX")])
941 (define_insn "*neg_sgeu_insn"
942 [(set (match_operand:SI 0 "register_operand" "=r")
943 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
946 [(set_attr "type" "ialuX")])
948 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
949 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
952 (define_insn "*sltu_plus_x"
953 [(set (match_operand:SI 0 "register_operand" "=r")
954 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
955 (match_operand:SI 1 "arith_operand" "rI")))]
958 [(set_attr "type" "ialuX")])
960 (define_insn "*sltu_plus_x_plus_y"
961 [(set (match_operand:SI 0 "register_operand" "=r")
962 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
963 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
964 (match_operand:SI 2 "arith_operand" "rI"))))]
967 [(set_attr "type" "ialuX")])
969 (define_insn "*x_minus_sltu"
970 [(set (match_operand:SI 0 "register_operand" "=r")
971 (minus:SI (match_operand:SI 1 "register_operand" "r")
972 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
975 [(set_attr "type" "ialuX")])
977 ;; ??? Combine should canonicalize these next two to the same pattern.
978 (define_insn "*x_minus_y_minus_sltu"
979 [(set (match_operand:SI 0 "register_operand" "=r")
980 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
981 (match_operand:SI 2 "arith_operand" "rI"))
982 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
985 [(set_attr "type" "ialuX")])
987 (define_insn "*x_minus_sltu_plus_y"
988 [(set (match_operand:SI 0 "register_operand" "=r")
989 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
990 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
991 (match_operand:SI 2 "arith_operand" "rI"))))]
994 [(set_attr "type" "ialuX")])
996 (define_insn "*sgeu_plus_x"
997 [(set (match_operand:SI 0 "register_operand" "=r")
998 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
999 (match_operand:SI 1 "register_operand" "r")))]
1002 [(set_attr "type" "ialuX")])
1004 (define_insn "*x_minus_sgeu"
1005 [(set (match_operand:SI 0 "register_operand" "=r")
1006 (minus:SI (match_operand:SI 1 "register_operand" "r")
1007 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1010 [(set_attr "type" "ialuX")])
1013 [(set (match_operand:SI 0 "register_operand" "")
1014 (match_operator:SI 2 "noov_compare_operator"
1015 [(match_operand 1 "icc_or_fcc_register_operand" "")
1018 && REGNO (operands[1]) == SPARC_ICC_REG
1019 && (GET_MODE (operands[1]) == CCXmode
1020 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1021 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1022 [(set (match_dup 0) (const_int 0))
1024 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1030 ;; These control RTL generation for conditional jump insns
1032 (define_expand "cbranchcc4"
1034 (if_then_else (match_operator 0 "comparison_operator"
1035 [(match_operand 1 "compare_operand" "")
1036 (match_operand 2 "const_zero_operand" "")])
1037 (label_ref (match_operand 3 "" ""))
1042 (define_expand "cbranchsi4"
1043 [(use (match_operator 0 "comparison_operator"
1044 [(match_operand:SI 1 "compare_operand" "")
1045 (match_operand:SI 2 "arith_operand" "")]))
1046 (use (match_operand 3 ""))]
1049 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1050 operands[1] = force_reg (SImode, operands[1]);
1051 emit_conditional_branch_insn (operands);
1055 (define_expand "cbranchdi4"
1056 [(use (match_operator 0 "comparison_operator"
1057 [(match_operand:DI 1 "compare_operand" "")
1058 (match_operand:DI 2 "arith_operand" "")]))
1059 (use (match_operand 3 ""))]
1062 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1063 operands[1] = force_reg (DImode, operands[1]);
1064 emit_conditional_branch_insn (operands);
1068 (define_expand "cbranch<F:mode>4"
1069 [(use (match_operator 0 "comparison_operator"
1070 [(match_operand:F 1 "register_operand" "")
1071 (match_operand:F 2 "register_operand" "")]))
1072 (use (match_operand 3 ""))]
1074 { emit_conditional_branch_insn (operands); DONE; })
1077 ;; Now match both normal and inverted jump.
1079 ;; XXX fpcmp nop braindamage
1080 (define_insn "*normal_branch"
1082 (if_then_else (match_operator 0 "noov_compare_operator"
1083 [(reg CC_REG) (const_int 0)])
1084 (label_ref (match_operand 1 "" ""))
1088 return output_cbranch (operands[0], operands[1], 1, 0,
1089 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1092 [(set_attr "type" "branch")
1093 (set_attr "branch_type" "icc")])
1095 ;; XXX fpcmp nop braindamage
1096 (define_insn "*inverted_branch"
1098 (if_then_else (match_operator 0 "noov_compare_operator"
1099 [(reg CC_REG) (const_int 0)])
1101 (label_ref (match_operand 1 "" ""))))]
1104 return output_cbranch (operands[0], operands[1], 1, 1,
1105 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1108 [(set_attr "type" "branch")
1109 (set_attr "branch_type" "icc")])
1111 ;; XXX fpcmp nop braindamage
1112 (define_insn "*normal_fp_branch"
1114 (if_then_else (match_operator 1 "comparison_operator"
1115 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1117 (label_ref (match_operand 2 "" ""))
1121 return output_cbranch (operands[1], operands[2], 2, 0,
1122 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1125 [(set_attr "type" "branch")
1126 (set_attr "branch_type" "fcc")])
1128 ;; XXX fpcmp nop braindamage
1129 (define_insn "*inverted_fp_branch"
1131 (if_then_else (match_operator 1 "comparison_operator"
1132 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1135 (label_ref (match_operand 2 "" ""))))]
1138 return output_cbranch (operands[1], operands[2], 2, 1,
1139 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1142 [(set_attr "type" "branch")
1143 (set_attr "branch_type" "fcc")])
1145 ;; XXX fpcmp nop braindamage
1146 (define_insn "*normal_fpe_branch"
1148 (if_then_else (match_operator 1 "comparison_operator"
1149 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1151 (label_ref (match_operand 2 "" ""))
1155 return output_cbranch (operands[1], operands[2], 2, 0,
1156 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1159 [(set_attr "type" "branch")
1160 (set_attr "branch_type" "fcc")])
1162 ;; XXX fpcmp nop braindamage
1163 (define_insn "*inverted_fpe_branch"
1165 (if_then_else (match_operator 1 "comparison_operator"
1166 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1169 (label_ref (match_operand 2 "" ""))))]
1172 return output_cbranch (operands[1], operands[2], 2, 1,
1173 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1176 [(set_attr "type" "branch")
1177 (set_attr "branch_type" "fcc")])
1179 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1180 ;; in the architecture.
1182 ;; There are no 32 bit brreg insns.
1185 (define_insn "*normal_int_branch_sp64"
1187 (if_then_else (match_operator 0 "v9_register_compare_operator"
1188 [(match_operand:DI 1 "register_operand" "r")
1190 (label_ref (match_operand 2 "" ""))
1194 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1195 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1198 [(set_attr "type" "branch")
1199 (set_attr "branch_type" "reg")])
1202 (define_insn "*inverted_int_branch_sp64"
1204 (if_then_else (match_operator 0 "v9_register_compare_operator"
1205 [(match_operand:DI 1 "register_operand" "r")
1208 (label_ref (match_operand 2 "" ""))))]
1211 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1212 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1215 [(set_attr "type" "branch")
1216 (set_attr "branch_type" "reg")])
1219 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1220 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1221 ;; that adds the PC value at the call point to register #(operand 3).
1223 (define_insn "load_pcrel_sym<P:mode>"
1224 [(set (match_operand:P 0 "register_operand" "=r")
1225 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1226 (match_operand:P 2 "call_address_operand" "")
1227 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1228 (clobber (reg:P O7_REG))]
1229 "REGNO (operands[0]) == INTVAL (operands[3])"
1231 if (flag_delayed_branch)
1232 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1234 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1236 [(set (attr "type") (const_string "multi"))
1237 (set (attr "length")
1238 (if_then_else (eq_attr "delayed_branch" "true")
1243 ;; Integer move instructions
1245 (define_expand "movqi"
1246 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1247 (match_operand:QI 1 "general_operand" ""))]
1250 if (sparc_expand_move (QImode, operands))
1254 (define_insn "*movqi_insn"
1255 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1256 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1257 "(register_operand (operands[0], QImode)
1258 || register_or_zero_operand (operands[1], QImode))"
1263 [(set_attr "type" "*,load,store")
1264 (set_attr "us3load_type" "*,3cycle,*")])
1266 (define_expand "movhi"
1267 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1268 (match_operand:HI 1 "general_operand" ""))]
1271 if (sparc_expand_move (HImode, operands))
1275 (define_insn "*movhi_insn"
1276 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1277 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1278 "(register_operand (operands[0], HImode)
1279 || register_or_zero_operand (operands[1], HImode))"
1282 sethi\t%%hi(%a1), %0
1285 [(set_attr "type" "*,*,load,store")
1286 (set_attr "us3load_type" "*,*,3cycle,*")])
1288 ;; We always work with constants here.
1289 (define_insn "*movhi_lo_sum"
1290 [(set (match_operand:HI 0 "register_operand" "=r")
1291 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1292 (match_operand:HI 2 "small_int_operand" "I")))]
1296 (define_expand "movsi"
1297 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1298 (match_operand:SI 1 "general_operand" ""))]
1301 if (sparc_expand_move (SImode, operands))
1305 (define_insn "*movsi_insn"
1306 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d,d")
1307 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J,P"))]
1308 "(register_operand (operands[0], SImode)
1309 || register_or_zero_or_all_ones_operand (operands[1], SImode))"
1312 sethi\t%%hi(%a1), %0
1320 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")])
1322 (define_insn "*movsi_lo_sum"
1323 [(set (match_operand:SI 0 "register_operand" "=r")
1324 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1325 (match_operand:SI 2 "immediate_operand" "in")))]
1327 "or\t%1, %%lo(%a2), %0")
1329 (define_insn "*movsi_high"
1330 [(set (match_operand:SI 0 "register_operand" "=r")
1331 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1333 "sethi\t%%hi(%a1), %0")
1335 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1336 ;; so that CSE won't optimize the address computation away.
1337 (define_insn "movsi_lo_sum_pic"
1338 [(set (match_operand:SI 0 "register_operand" "=r")
1339 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1340 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1343 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1344 return "xor\t%1, %%gdop_lox10(%a2), %0";
1346 return "or\t%1, %%lo(%a2), %0";
1350 (define_insn "movsi_high_pic"
1351 [(set (match_operand:SI 0 "register_operand" "=r")
1352 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1353 "flag_pic && check_pic (1)"
1355 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1356 return "sethi\t%%gdop_hix22(%a1), %0";
1358 return "sethi\t%%hi(%a1), %0";
1362 (define_insn "movsi_pic_gotdata_op"
1363 [(set (match_operand:SI 0 "register_operand" "=r")
1364 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1365 (match_operand:SI 2 "register_operand" "r")
1366 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1367 "flag_pic && check_pic (1)"
1369 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1370 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1372 return "ld\t[%1 + %2], %0";
1375 [(set_attr "type" "load")])
1377 (define_expand "movsi_pic_label_ref"
1378 [(set (match_dup 3) (high:SI
1379 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1380 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1381 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1382 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1383 (set (match_operand:SI 0 "register_operand" "=r")
1384 (minus:SI (match_dup 5) (match_dup 4)))]
1387 crtl->uses_pic_offset_table = 1;
1388 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1389 if (!can_create_pseudo_p ())
1391 operands[3] = operands[0];
1392 operands[4] = operands[0];
1396 operands[3] = gen_reg_rtx (SImode);
1397 operands[4] = gen_reg_rtx (SImode);
1399 operands[5] = pic_offset_table_rtx;
1402 (define_insn "*movsi_high_pic_label_ref"
1403 [(set (match_operand:SI 0 "register_operand" "=r")
1405 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1406 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1408 "sethi\t%%hi(%a2-(%a1-.)), %0")
1410 (define_insn "*movsi_lo_sum_pic_label_ref"
1411 [(set (match_operand:SI 0 "register_operand" "=r")
1412 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1413 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1414 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1416 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1418 ;; Set up the PIC register for VxWorks.
1420 (define_expand "vxworks_load_got"
1422 (high:SI (match_dup 1)))
1424 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1426 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1427 "TARGET_VXWORKS_RTP"
1429 operands[0] = pic_offset_table_rtx;
1430 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1431 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1434 (define_expand "movdi"
1435 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1436 (match_operand:DI 1 "general_operand" ""))]
1439 if (sparc_expand_move (DImode, operands))
1443 ;; Be careful, fmovd does not exist when !v9.
1444 ;; We match MEM moves directly when we have correct even
1445 ;; numbered registers, but fall into splits otherwise.
1446 ;; The constraint ordering here is really important to
1447 ;; avoid insane problems in reload, especially for patterns
1450 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1451 ;; (const_int -5016)))
1455 (define_insn "*movdi_insn_sp32"
1456 [(set (match_operand:DI 0 "nonimmediate_operand"
1457 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1458 (match_operand:DI 1 "input_operand"
1459 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1461 && (register_operand (operands[0], DImode)
1462 || register_or_zero_operand (operands[1], DImode))"
1476 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1477 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1479 (define_insn "*movdi_insn_sp32_v9"
1480 [(set (match_operand:DI 0 "nonimmediate_operand"
1481 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1482 (match_operand:DI 1 "input_operand"
1483 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1486 && (register_operand (operands[0], DImode)
1487 || register_or_zero_operand (operands[1], DImode))"
1504 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1505 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1506 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1508 (define_insn "*movdi_insn_sp64"
1509 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b,b")
1510 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J,P"))]
1512 && (register_operand (operands[0], DImode)
1513 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1516 sethi\t%%hi(%a1), %0
1524 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")
1525 (set_attr "fptype" "*,*,*,*,double,*,*,double,double")])
1527 (define_expand "movdi_pic_label_ref"
1528 [(set (match_dup 3) (high:DI
1529 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1530 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1531 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1532 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1533 (set (match_operand:DI 0 "register_operand" "=r")
1534 (minus:DI (match_dup 5) (match_dup 4)))]
1535 "TARGET_ARCH64 && flag_pic"
1537 crtl->uses_pic_offset_table = 1;
1538 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1539 if (!can_create_pseudo_p ())
1541 operands[3] = operands[0];
1542 operands[4] = operands[0];
1546 operands[3] = gen_reg_rtx (DImode);
1547 operands[4] = gen_reg_rtx (DImode);
1549 operands[5] = pic_offset_table_rtx;
1552 (define_insn "*movdi_high_pic_label_ref"
1553 [(set (match_operand:DI 0 "register_operand" "=r")
1555 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1556 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1557 "TARGET_ARCH64 && flag_pic"
1558 "sethi\t%%hi(%a2-(%a1-.)), %0")
1560 (define_insn "*movdi_lo_sum_pic_label_ref"
1561 [(set (match_operand:DI 0 "register_operand" "=r")
1562 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1563 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1564 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1565 "TARGET_ARCH64 && flag_pic"
1566 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1568 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1569 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1571 (define_insn "movdi_lo_sum_pic"
1572 [(set (match_operand:DI 0 "register_operand" "=r")
1573 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1574 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1575 "TARGET_ARCH64 && flag_pic"
1577 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1578 return "xor\t%1, %%gdop_lox10(%a2), %0";
1580 return "or\t%1, %%lo(%a2), %0";
1584 (define_insn "movdi_high_pic"
1585 [(set (match_operand:DI 0 "register_operand" "=r")
1586 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1587 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1589 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1590 return "sethi\t%%gdop_hix22(%a1), %0";
1592 return "sethi\t%%hi(%a1), %0";
1596 (define_insn "movdi_pic_gotdata_op"
1597 [(set (match_operand:DI 0 "register_operand" "=r")
1598 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1599 (match_operand:DI 2 "register_operand" "r")
1600 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1601 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1603 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1604 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1606 return "ldx\t[%1 + %2], %0";
1609 [(set_attr "type" "load")])
1611 (define_insn "*sethi_di_medlow_embmedany_pic"
1612 [(set (match_operand:DI 0 "register_operand" "=r")
1613 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1614 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1615 "sethi\t%%hi(%a1), %0")
1617 (define_insn "*sethi_di_medlow"
1618 [(set (match_operand:DI 0 "register_operand" "=r")
1619 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1620 "TARGET_CM_MEDLOW && check_pic (1)"
1621 "sethi\t%%hi(%a1), %0")
1623 (define_insn "*losum_di_medlow"
1624 [(set (match_operand:DI 0 "register_operand" "=r")
1625 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1626 (match_operand:DI 2 "symbolic_operand" "")))]
1628 "or\t%1, %%lo(%a2), %0")
1630 (define_insn "seth44"
1631 [(set (match_operand:DI 0 "register_operand" "=r")
1632 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1634 "sethi\t%%h44(%a1), %0")
1636 (define_insn "setm44"
1637 [(set (match_operand:DI 0 "register_operand" "=r")
1638 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1639 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1641 "or\t%1, %%m44(%a2), %0")
1643 (define_insn "setl44"
1644 [(set (match_operand:DI 0 "register_operand" "=r")
1645 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1646 (match_operand:DI 2 "symbolic_operand" "")))]
1648 "or\t%1, %%l44(%a2), %0")
1650 (define_insn "sethh"
1651 [(set (match_operand:DI 0 "register_operand" "=r")
1652 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1654 "sethi\t%%hh(%a1), %0")
1656 (define_insn "setlm"
1657 [(set (match_operand:DI 0 "register_operand" "=r")
1658 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1660 "sethi\t%%lm(%a1), %0")
1662 (define_insn "sethm"
1663 [(set (match_operand:DI 0 "register_operand" "=r")
1664 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1665 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1667 "or\t%1, %%hm(%a2), %0")
1669 (define_insn "setlo"
1670 [(set (match_operand:DI 0 "register_operand" "=r")
1671 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1672 (match_operand:DI 2 "symbolic_operand" "")))]
1674 "or\t%1, %%lo(%a2), %0")
1676 (define_insn "embmedany_sethi"
1677 [(set (match_operand:DI 0 "register_operand" "=r")
1678 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1679 "TARGET_CM_EMBMEDANY && check_pic (1)"
1680 "sethi\t%%hi(%a1), %0")
1682 (define_insn "embmedany_losum"
1683 [(set (match_operand:DI 0 "register_operand" "=r")
1684 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1685 (match_operand:DI 2 "data_segment_operand" "")))]
1686 "TARGET_CM_EMBMEDANY"
1687 "add\t%1, %%lo(%a2), %0")
1689 (define_insn "embmedany_brsum"
1690 [(set (match_operand:DI 0 "register_operand" "=r")
1691 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1692 "TARGET_CM_EMBMEDANY"
1695 (define_insn "embmedany_textuhi"
1696 [(set (match_operand:DI 0 "register_operand" "=r")
1697 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1698 "TARGET_CM_EMBMEDANY && check_pic (1)"
1699 "sethi\t%%uhi(%a1), %0")
1701 (define_insn "embmedany_texthi"
1702 [(set (match_operand:DI 0 "register_operand" "=r")
1703 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1704 "TARGET_CM_EMBMEDANY && check_pic (1)"
1705 "sethi\t%%hi(%a1), %0")
1707 (define_insn "embmedany_textulo"
1708 [(set (match_operand:DI 0 "register_operand" "=r")
1709 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1710 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1711 "TARGET_CM_EMBMEDANY"
1712 "or\t%1, %%ulo(%a2), %0")
1714 (define_insn "embmedany_textlo"
1715 [(set (match_operand:DI 0 "register_operand" "=r")
1716 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1717 (match_operand:DI 2 "text_segment_operand" "")))]
1718 "TARGET_CM_EMBMEDANY"
1719 "or\t%1, %%lo(%a2), %0")
1721 ;; Now some patterns to help reload out a bit.
1722 (define_expand "reload_indi"
1723 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1724 (match_operand:DI 1 "immediate_operand" "")
1725 (match_operand:TI 2 "register_operand" "=&r")])]
1727 || TARGET_CM_EMBMEDANY)
1730 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1734 (define_expand "reload_outdi"
1735 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1736 (match_operand:DI 1 "immediate_operand" "")
1737 (match_operand:TI 2 "register_operand" "=&r")])]
1739 || TARGET_CM_EMBMEDANY)
1742 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1746 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1748 [(set (match_operand:DI 0 "register_operand" "")
1749 (match_operand:DI 1 "const_int_operand" ""))]
1750 "! TARGET_ARCH64 && reload_completed"
1751 [(clobber (const_int 0))]
1753 #if HOST_BITS_PER_WIDE_INT == 32
1754 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1755 (INTVAL (operands[1]) < 0) ?
1758 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1761 unsigned int low, high;
1763 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1764 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1765 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1767 /* Slick... but this trick loses if this subreg constant part
1768 can be done in one insn. */
1770 && ! SPARC_SETHI32_P (high)
1771 && ! SPARC_SIMM13_P (high))
1772 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1773 gen_highpart (SImode, operands[0])));
1775 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1781 [(set (match_operand:DI 0 "register_operand" "")
1782 (match_operand:DI 1 "const_double_operand" ""))]
1786 && ((GET_CODE (operands[0]) == REG
1787 && REGNO (operands[0]) < 32)
1788 || (GET_CODE (operands[0]) == SUBREG
1789 && GET_CODE (SUBREG_REG (operands[0])) == REG
1790 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1791 [(clobber (const_int 0))]
1793 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1794 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1796 /* Slick... but this trick loses if this subreg constant part
1797 can be done in one insn. */
1798 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1799 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1800 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1802 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1803 gen_highpart (SImode, operands[0])));
1807 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1808 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1814 [(set (match_operand:DI 0 "register_operand" "")
1815 (match_operand:DI 1 "register_operand" ""))]
1819 && ((GET_CODE (operands[0]) == REG
1820 && REGNO (operands[0]) < 32)
1821 || (GET_CODE (operands[0]) == SUBREG
1822 && GET_CODE (SUBREG_REG (operands[0])) == REG
1823 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1824 [(clobber (const_int 0))]
1826 rtx set_dest = operands[0];
1827 rtx set_src = operands[1];
1831 dest1 = gen_highpart (SImode, set_dest);
1832 dest2 = gen_lowpart (SImode, set_dest);
1833 src1 = gen_highpart (SImode, set_src);
1834 src2 = gen_lowpart (SImode, set_src);
1836 /* Now emit using the real source and destination we found, swapping
1837 the order if we detect overlap. */
1838 if (reg_overlap_mentioned_p (dest1, src2))
1840 emit_insn (gen_movsi (dest2, src2));
1841 emit_insn (gen_movsi (dest1, src1));
1845 emit_insn (gen_movsi (dest1, src1));
1846 emit_insn (gen_movsi (dest2, src2));
1851 ;; Now handle the cases of memory moves from/to non-even
1852 ;; DI mode register pairs.
1854 [(set (match_operand:DI 0 "register_operand" "")
1855 (match_operand:DI 1 "memory_operand" ""))]
1858 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1859 [(clobber (const_int 0))]
1861 rtx word0 = adjust_address (operands[1], SImode, 0);
1862 rtx word1 = adjust_address (operands[1], SImode, 4);
1863 rtx high_part = gen_highpart (SImode, operands[0]);
1864 rtx low_part = gen_lowpart (SImode, operands[0]);
1866 if (reg_overlap_mentioned_p (high_part, word1))
1868 emit_insn (gen_movsi (low_part, word1));
1869 emit_insn (gen_movsi (high_part, word0));
1873 emit_insn (gen_movsi (high_part, word0));
1874 emit_insn (gen_movsi (low_part, word1));
1880 [(set (match_operand:DI 0 "memory_operand" "")
1881 (match_operand:DI 1 "register_operand" ""))]
1884 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1885 [(clobber (const_int 0))]
1887 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1888 gen_highpart (SImode, operands[1])));
1889 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1890 gen_lowpart (SImode, operands[1])));
1895 [(set (match_operand:DI 0 "memory_operand" "")
1896 (match_operand:DI 1 "const_zero_operand" ""))]
1900 && ! mem_min_alignment (operands[0], 8)))
1901 && offsettable_memref_p (operands[0])"
1902 [(clobber (const_int 0))]
1904 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1905 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1910 ;; Floating point and vector move instructions
1912 ;; Yes, you guessed it right, the former movsf expander.
1913 (define_expand "mov<V32:mode>"
1914 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1915 (match_operand:V32 1 "general_operand" ""))]
1916 "<V32:MODE>mode == SFmode || TARGET_VIS"
1918 if (sparc_expand_move (<V32:MODE>mode, operands))
1922 (define_insn "*movsf_insn"
1923 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,d,f,*r,*r,*r,f,*r,m,m")
1924 (match_operand:V32 1 "input_operand" "GY,ZC,f,*rRY,Q,S,m,m,f,*rGY"))]
1926 && (register_operand (operands[0], <V32:MODE>mode)
1927 || register_or_zero_or_all_ones_operand (operands[1], <V32:MODE>mode))"
1929 if (GET_CODE (operands[1]) == CONST_DOUBLE
1930 && (which_alternative == 3
1931 || which_alternative == 4
1932 || which_alternative == 5))
1937 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1938 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1939 operands[1] = GEN_INT (i);
1942 switch (which_alternative)
1945 return "fzeros\t%0";
1949 return "fmovs\t%1, %0";
1951 return "mov\t%1, %0";
1953 return "sethi\t%%hi(%a1), %0";
1958 return "ld\t%1, %0";
1961 return "st\t%r1, %0";
1966 [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1968 ;; Exactly the same as above, except that all `f' cases are deleted.
1969 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1972 (define_insn "*movsf_insn_no_fpu"
1973 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1974 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1976 && (register_operand (operands[0], SFmode)
1977 || register_or_zero_operand (operands[1], SFmode))"
1979 if (GET_CODE (operands[1]) == CONST_DOUBLE
1980 && (which_alternative == 0
1981 || which_alternative == 1
1982 || which_alternative == 2))
1987 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1988 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1989 operands[1] = GEN_INT (i);
1992 switch (which_alternative)
1995 return "mov\t%1, %0";
1997 return "sethi\t%%hi(%a1), %0";
2001 return "ld\t%1, %0";
2003 return "st\t%r1, %0";
2008 [(set_attr "type" "*,*,*,load,store")])
2010 ;; The following 3 patterns build SFmode constants in integer registers.
2012 (define_insn "*movsf_lo_sum"
2013 [(set (match_operand:SF 0 "register_operand" "=r")
2014 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2015 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2021 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2022 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2023 operands[2] = GEN_INT (i);
2024 return "or\t%1, %%lo(%a2), %0";
2027 (define_insn "*movsf_high"
2028 [(set (match_operand:SF 0 "register_operand" "=r")
2029 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2035 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2036 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2037 operands[1] = GEN_INT (i);
2038 return "sethi\t%%hi(%1), %0";
2042 [(set (match_operand:SF 0 "register_operand" "")
2043 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2044 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2045 [(set (match_dup 0) (high:SF (match_dup 1)))
2046 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2048 ;; Yes, you again guessed it right, the former movdf expander.
2049 (define_expand "mov<V64:mode>"
2050 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2051 (match_operand:V64 1 "general_operand" ""))]
2052 "<V64:MODE>mode == DFmode || TARGET_VIS"
2054 if (sparc_expand_move (<V64:MODE>mode, operands))
2058 ;; Be careful, fmovd does not exist when !v9.
2059 (define_insn "*movdf_insn_sp32"
2060 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2061 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2064 && (register_operand (operands[0], DFmode)
2065 || register_or_zero_operand (operands[1], DFmode))"
2077 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2078 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2080 (define_insn "*movdf_insn_sp32_no_fpu"
2081 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2082 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2085 && (register_operand (operands[0], DFmode)
2086 || register_or_zero_operand (operands[1], DFmode))"
2093 [(set_attr "type" "load,store,*,*,*")
2094 (set_attr "length" "*,*,2,2,2")])
2096 ;; We have available v9 double floats but not 64-bit integer registers.
2097 (define_insn "*movdf_insn_sp32_v9"
2098 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,T,W,U,T,f,*r,o")
2099 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2103 && (register_operand (operands[0], <V64:MODE>mode)
2104 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2117 [(set_attr "type" "fga,fga,fpmove,load,store,store,load,store,*,*,*")
2118 (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")
2119 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*")])
2121 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2122 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2123 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2127 && (register_operand (operands[0], DFmode)
2128 || register_or_zero_operand (operands[1], DFmode))"
2135 [(set_attr "type" "load,store,store,*,*")
2136 (set_attr "length" "*,*,*,2,2")])
2138 ;; We have available both v9 double floats and 64-bit integer registers.
2139 (define_insn "*movdf_insn_sp64"
2140 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,W,*r,*r,m,*r")
2141 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,e,*rGY,m,*rGY,DF"))]
2144 && (register_operand (operands[0], <V64:MODE>mode)
2145 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2156 [(set_attr "type" "fga,fga,fpmove,load,store,*,load,store,*")
2157 (set_attr "length" "*,*,*,*,*,*,*,*,2")
2158 (set_attr "fptype" "double,double,double,*,*,*,*,*,*")])
2160 (define_insn "*movdf_insn_sp64_no_fpu"
2161 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2162 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2165 && (register_operand (operands[0], DFmode)
2166 || register_or_zero_operand (operands[1], DFmode))"
2171 [(set_attr "type" "*,load,store")])
2173 ;; This pattern builds V64mode constants in integer registers.
2175 [(set (match_operand:V64 0 "register_operand" "")
2176 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2178 && (GET_CODE (operands[0]) == REG
2179 && REGNO (operands[0]) < 32)
2180 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2181 && reload_completed"
2182 [(clobber (const_int 0))]
2184 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2188 #if HOST_BITS_PER_WIDE_INT == 32
2191 enum machine_mode mode = GET_MODE (operands[1]);
2192 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2193 emit_insn (gen_movdi (operands[0], tem));
2198 enum machine_mode mode = GET_MODE (operands[1]);
2199 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2200 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2202 gcc_assert (GET_CODE (hi) == CONST_INT);
2203 gcc_assert (GET_CODE (lo) == CONST_INT);
2205 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2207 /* Slick... but this trick loses if this subreg constant part
2208 can be done in one insn. */
2210 && ! SPARC_SETHI32_P (INTVAL (hi))
2211 && ! SPARC_SIMM13_P (INTVAL (hi)))
2213 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2214 gen_highpart (SImode, operands[0])));
2218 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2224 ;; Ok, now the splits to handle all the multi insn and
2225 ;; mis-aligned memory address cases.
2226 ;; In these splits please take note that we must be
2227 ;; careful when V9 but not ARCH64 because the integer
2228 ;; register DFmode cases must be handled.
2230 [(set (match_operand:V64 0 "register_operand" "")
2231 (match_operand:V64 1 "register_operand" ""))]
2234 && ((GET_CODE (operands[0]) == REG
2235 && REGNO (operands[0]) < 32)
2236 || (GET_CODE (operands[0]) == SUBREG
2237 && GET_CODE (SUBREG_REG (operands[0])) == REG
2238 && REGNO (SUBREG_REG (operands[0])) < 32))))
2239 && reload_completed"
2240 [(clobber (const_int 0))]
2242 rtx set_dest = operands[0];
2243 rtx set_src = operands[1];
2246 enum machine_mode half_mode;
2248 /* We can be expanded for DFmode or integral vector modes. */
2249 if (<V64:MODE>mode == DFmode)
2254 dest1 = gen_highpart (half_mode, set_dest);
2255 dest2 = gen_lowpart (half_mode, set_dest);
2256 src1 = gen_highpart (half_mode, set_src);
2257 src2 = gen_lowpart (half_mode, set_src);
2259 /* Now emit using the real source and destination we found, swapping
2260 the order if we detect overlap. */
2261 if (reg_overlap_mentioned_p (dest1, src2))
2263 emit_move_insn_1 (dest2, src2);
2264 emit_move_insn_1 (dest1, src1);
2268 emit_move_insn_1 (dest1, src1);
2269 emit_move_insn_1 (dest2, src2);
2275 [(set (match_operand:V64 0 "register_operand" "")
2276 (match_operand:V64 1 "memory_operand" ""))]
2279 && (((REGNO (operands[0]) % 2) != 0)
2280 || ! mem_min_alignment (operands[1], 8))
2281 && offsettable_memref_p (operands[1])"
2282 [(clobber (const_int 0))]
2284 enum machine_mode half_mode;
2287 /* We can be expanded for DFmode or integral vector modes. */
2288 if (<V64:MODE>mode == DFmode)
2293 word0 = adjust_address (operands[1], half_mode, 0);
2294 word1 = adjust_address (operands[1], half_mode, 4);
2296 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2298 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2299 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2303 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2304 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2310 [(set (match_operand:V64 0 "memory_operand" "")
2311 (match_operand:V64 1 "register_operand" ""))]
2314 && (((REGNO (operands[1]) % 2) != 0)
2315 || ! mem_min_alignment (operands[0], 8))
2316 && offsettable_memref_p (operands[0])"
2317 [(clobber (const_int 0))]
2319 enum machine_mode half_mode;
2322 /* We can be expanded for DFmode or integral vector modes. */
2323 if (<V64:MODE>mode == DFmode)
2328 word0 = adjust_address (operands[0], half_mode, 0);
2329 word1 = adjust_address (operands[0], half_mode, 4);
2331 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2332 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2337 [(set (match_operand:V64 0 "memory_operand" "")
2338 (match_operand:V64 1 "const_zero_operand" ""))]
2342 && ! mem_min_alignment (operands[0], 8)))
2343 && offsettable_memref_p (operands[0])"
2344 [(clobber (const_int 0))]
2346 enum machine_mode half_mode;
2349 /* We can be expanded for DFmode or integral vector modes. */
2350 if (<V64:MODE>mode == DFmode)
2355 dest1 = adjust_address (operands[0], half_mode, 0);
2356 dest2 = adjust_address (operands[0], half_mode, 4);
2358 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2359 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2364 [(set (match_operand:V64 0 "register_operand" "")
2365 (match_operand:V64 1 "const_zero_operand" ""))]
2368 && ((GET_CODE (operands[0]) == REG
2369 && REGNO (operands[0]) < 32)
2370 || (GET_CODE (operands[0]) == SUBREG
2371 && GET_CODE (SUBREG_REG (operands[0])) == REG
2372 && REGNO (SUBREG_REG (operands[0])) < 32))"
2373 [(clobber (const_int 0))]
2375 enum machine_mode half_mode;
2376 rtx set_dest = operands[0];
2379 /* We can be expanded for DFmode or integral vector modes. */
2380 if (<V64:MODE>mode == DFmode)
2385 dest1 = gen_highpart (half_mode, set_dest);
2386 dest2 = gen_lowpart (half_mode, set_dest);
2387 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2388 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2392 (define_expand "movtf"
2393 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2394 (match_operand:TF 1 "general_operand" ""))]
2397 if (sparc_expand_move (TFmode, operands))
2401 (define_insn "*movtf_insn_sp32"
2402 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2403 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2406 && (register_operand (operands[0], TFmode)
2407 || register_or_zero_operand (operands[1], TFmode))"
2409 [(set_attr "length" "4")])
2411 ;; Exactly the same as above, except that all `e' cases are deleted.
2412 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2415 (define_insn "*movtf_insn_sp32_no_fpu"
2416 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2417 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2420 && (register_operand (operands[0], TFmode)
2421 || register_or_zero_operand (operands[1], TFmode))"
2423 [(set_attr "length" "4")])
2425 (define_insn "*movtf_insn_sp64"
2426 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2427 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2430 && ! TARGET_HARD_QUAD
2431 && (register_operand (operands[0], TFmode)
2432 || register_or_zero_operand (operands[1], TFmode))"
2434 [(set_attr "length" "2")])
2436 (define_insn "*movtf_insn_sp64_hq"
2437 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2438 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2442 && (register_operand (operands[0], TFmode)
2443 || register_or_zero_operand (operands[1], TFmode))"
2451 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2452 (set_attr "length" "2,*,*,*,2,2")])
2454 (define_insn "*movtf_insn_sp64_no_fpu"
2455 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2456 (match_operand:TF 1 "input_operand" "orG,rG"))]
2459 && (register_operand (operands[0], TFmode)
2460 || register_or_zero_operand (operands[1], TFmode))"
2462 [(set_attr "length" "2")])
2464 ;; Now all the splits to handle multi-insn TF mode moves.
2466 [(set (match_operand:TF 0 "register_operand" "")
2467 (match_operand:TF 1 "register_operand" ""))]
2471 && ! TARGET_HARD_QUAD)
2472 || ! fp_register_operand (operands[0], TFmode))"
2473 [(clobber (const_int 0))]
2475 rtx set_dest = operands[0];
2476 rtx set_src = operands[1];
2480 dest1 = gen_df_reg (set_dest, 0);
2481 dest2 = gen_df_reg (set_dest, 1);
2482 src1 = gen_df_reg (set_src, 0);
2483 src2 = gen_df_reg (set_src, 1);
2485 /* Now emit using the real source and destination we found, swapping
2486 the order if we detect overlap. */
2487 if (reg_overlap_mentioned_p (dest1, src2))
2489 emit_insn (gen_movdf (dest2, src2));
2490 emit_insn (gen_movdf (dest1, src1));
2494 emit_insn (gen_movdf (dest1, src1));
2495 emit_insn (gen_movdf (dest2, src2));
2501 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2502 (match_operand:TF 1 "const_zero_operand" ""))]
2504 [(clobber (const_int 0))]
2506 rtx set_dest = operands[0];
2509 switch (GET_CODE (set_dest))
2512 dest1 = gen_df_reg (set_dest, 0);
2513 dest2 = gen_df_reg (set_dest, 1);
2516 dest1 = adjust_address (set_dest, DFmode, 0);
2517 dest2 = adjust_address (set_dest, DFmode, 8);
2523 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2524 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2529 [(set (match_operand:TF 0 "register_operand" "")
2530 (match_operand:TF 1 "memory_operand" ""))]
2532 && offsettable_memref_p (operands[1])
2534 || ! TARGET_HARD_QUAD
2535 || ! fp_register_operand (operands[0], TFmode)))"
2536 [(clobber (const_int 0))]
2538 rtx word0 = adjust_address (operands[1], DFmode, 0);
2539 rtx word1 = adjust_address (operands[1], DFmode, 8);
2540 rtx set_dest, dest1, dest2;
2542 set_dest = operands[0];
2544 dest1 = gen_df_reg (set_dest, 0);
2545 dest2 = gen_df_reg (set_dest, 1);
2547 /* Now output, ordering such that we don't clobber any registers
2548 mentioned in the address. */
2549 if (reg_overlap_mentioned_p (dest1, word1))
2552 emit_insn (gen_movdf (dest2, word1));
2553 emit_insn (gen_movdf (dest1, word0));
2557 emit_insn (gen_movdf (dest1, word0));
2558 emit_insn (gen_movdf (dest2, word1));
2564 [(set (match_operand:TF 0 "memory_operand" "")
2565 (match_operand:TF 1 "register_operand" ""))]
2567 && offsettable_memref_p (operands[0])
2569 || ! TARGET_HARD_QUAD
2570 || ! fp_register_operand (operands[1], TFmode)))"
2571 [(clobber (const_int 0))]
2573 rtx set_src = operands[1];
2575 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2576 gen_df_reg (set_src, 0)));
2577 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2578 gen_df_reg (set_src, 1)));
2583 ;; SPARC-V9 conditional move instructions
2585 ;; We can handle larger constants here for some flavors, but for now we keep
2586 ;; it simple and only allow those constants supported by all flavors.
2587 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2588 ;; 3 contains the constant if one is present, but we handle either for
2589 ;; generality (sparc.c puts a constant in operand 2).
2591 (define_expand "mov<I:mode>cc"
2592 [(set (match_operand:I 0 "register_operand" "")
2593 (if_then_else:I (match_operand 1 "comparison_operator" "")
2594 (match_operand:I 2 "arith10_operand" "")
2595 (match_operand:I 3 "arith10_operand" "")))]
2596 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2598 enum rtx_code code = GET_CODE (operands[1]);
2601 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2605 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2607 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2608 GET_CODE (operands[1]));
2610 if (XEXP (operands[1], 1) == const0_rtx
2611 && GET_CODE (XEXP (operands[1], 0)) == REG
2612 && GET_MODE (XEXP (operands[1], 0)) == DImode
2613 && v9_regcmp_p (code))
2614 cc_reg = XEXP (operands[1], 0);
2616 cc_reg = gen_compare_reg (operands[1]);
2618 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2621 (define_expand "mov<F:mode>cc"
2622 [(set (match_operand:F 0 "register_operand" "")
2623 (if_then_else:F (match_operand 1 "comparison_operator" "")
2624 (match_operand:F 2 "register_operand" "")
2625 (match_operand:F 3 "register_operand" "")))]
2626 "TARGET_V9 && TARGET_FPU"
2628 enum rtx_code code = GET_CODE (operands[1]);
2631 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2635 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2637 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2638 GET_CODE (operands[1]));
2640 if (XEXP (operands[1], 1) == const0_rtx
2641 && GET_CODE (XEXP (operands[1], 0)) == REG
2642 && GET_MODE (XEXP (operands[1], 0)) == DImode
2643 && v9_regcmp_p (code))
2644 cc_reg = XEXP (operands[1], 0);
2646 cc_reg = gen_compare_reg (operands[1]);
2648 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2651 ;; Conditional move define_insns
2653 (define_insn "*mov<I:mode>_cc_v9"
2654 [(set (match_operand:I 0 "register_operand" "=r,r")
2655 (if_then_else:I (match_operator 1 "comparison_operator"
2656 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2658 (match_operand:I 3 "arith11_operand" "rL,0")
2659 (match_operand:I 4 "arith11_operand" "0,rL")))]
2660 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2663 mov%c1\t%x2, %4, %0"
2664 [(set_attr "type" "cmove")])
2666 (define_insn "*mov<I:mode>_cc_reg_sp64"
2667 [(set (match_operand:I 0 "register_operand" "=r,r")
2668 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2669 [(match_operand:DI 2 "register_operand" "r,r")
2671 (match_operand:I 3 "arith10_operand" "rM,0")
2672 (match_operand:I 4 "arith10_operand" "0,rM")))]
2675 movr%D1\t%2, %r3, %0
2676 movr%d1\t%2, %r4, %0"
2677 [(set_attr "type" "cmove")])
2679 (define_insn "*movsf_cc_v9"
2680 [(set (match_operand:SF 0 "register_operand" "=f,f")
2681 (if_then_else:SF (match_operator 1 "comparison_operator"
2682 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2684 (match_operand:SF 3 "register_operand" "f,0")
2685 (match_operand:SF 4 "register_operand" "0,f")))]
2686 "TARGET_V9 && TARGET_FPU"
2688 fmovs%C1\t%x2, %3, %0
2689 fmovs%c1\t%x2, %4, %0"
2690 [(set_attr "type" "fpcmove")])
2692 (define_insn "*movsf_cc_reg_sp64"
2693 [(set (match_operand:SF 0 "register_operand" "=f,f")
2694 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2695 [(match_operand:DI 2 "register_operand" "r,r")
2697 (match_operand:SF 3 "register_operand" "f,0")
2698 (match_operand:SF 4 "register_operand" "0,f")))]
2699 "TARGET_ARCH64 && TARGET_FPU"
2701 fmovrs%D1\t%2, %3, %0
2702 fmovrs%d1\t%2, %4, %0"
2703 [(set_attr "type" "fpcrmove")])
2705 ;; Named because invoked by movtf_cc_v9
2706 (define_insn "movdf_cc_v9"
2707 [(set (match_operand:DF 0 "register_operand" "=e,e")
2708 (if_then_else:DF (match_operator 1 "comparison_operator"
2709 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2711 (match_operand:DF 3 "register_operand" "e,0")
2712 (match_operand:DF 4 "register_operand" "0,e")))]
2713 "TARGET_V9 && TARGET_FPU"
2715 fmovd%C1\t%x2, %3, %0
2716 fmovd%c1\t%x2, %4, %0"
2717 [(set_attr "type" "fpcmove")
2718 (set_attr "fptype" "double")])
2720 ;; Named because invoked by movtf_cc_reg_sp64
2721 (define_insn "movdf_cc_reg_sp64"
2722 [(set (match_operand:DF 0 "register_operand" "=e,e")
2723 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2724 [(match_operand:DI 2 "register_operand" "r,r")
2726 (match_operand:DF 3 "register_operand" "e,0")
2727 (match_operand:DF 4 "register_operand" "0,e")))]
2728 "TARGET_ARCH64 && TARGET_FPU"
2730 fmovrd%D1\t%2, %3, %0
2731 fmovrd%d1\t%2, %4, %0"
2732 [(set_attr "type" "fpcrmove")
2733 (set_attr "fptype" "double")])
2735 (define_insn "*movtf_cc_hq_v9"
2736 [(set (match_operand:TF 0 "register_operand" "=e,e")
2737 (if_then_else:TF (match_operator 1 "comparison_operator"
2738 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2740 (match_operand:TF 3 "register_operand" "e,0")
2741 (match_operand:TF 4 "register_operand" "0,e")))]
2742 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2744 fmovq%C1\t%x2, %3, %0
2745 fmovq%c1\t%x2, %4, %0"
2746 [(set_attr "type" "fpcmove")])
2748 (define_insn "*movtf_cc_reg_hq_sp64"
2749 [(set (match_operand:TF 0 "register_operand" "=e,e")
2750 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2751 [(match_operand:DI 2 "register_operand" "r,r")
2753 (match_operand:TF 3 "register_operand" "e,0")
2754 (match_operand:TF 4 "register_operand" "0,e")))]
2755 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2757 fmovrq%D1\t%2, %3, %0
2758 fmovrq%d1\t%2, %4, %0"
2759 [(set_attr "type" "fpcrmove")])
2761 (define_insn_and_split "*movtf_cc_v9"
2762 [(set (match_operand:TF 0 "register_operand" "=e,e")
2763 (if_then_else:TF (match_operator 1 "comparison_operator"
2764 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2766 (match_operand:TF 3 "register_operand" "e,0")
2767 (match_operand:TF 4 "register_operand" "0,e")))]
2768 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2770 "&& reload_completed"
2771 [(clobber (const_int 0))]
2773 rtx set_dest = operands[0];
2774 rtx set_srca = operands[3];
2775 rtx set_srcb = operands[4];
2776 int third = rtx_equal_p (set_dest, set_srca);
2778 rtx srca1, srca2, srcb1, srcb2;
2780 dest1 = gen_df_reg (set_dest, 0);
2781 dest2 = gen_df_reg (set_dest, 1);
2782 srca1 = gen_df_reg (set_srca, 0);
2783 srca2 = gen_df_reg (set_srca, 1);
2784 srcb1 = gen_df_reg (set_srcb, 0);
2785 srcb2 = gen_df_reg (set_srcb, 1);
2787 /* Now emit using the real source and destination we found, swapping
2788 the order if we detect overlap. */
2789 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2790 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2792 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2793 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2797 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2798 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2802 [(set_attr "length" "2")])
2804 (define_insn_and_split "*movtf_cc_reg_sp64"
2805 [(set (match_operand:TF 0 "register_operand" "=e,e")
2806 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2807 [(match_operand:DI 2 "register_operand" "r,r")
2809 (match_operand:TF 3 "register_operand" "e,0")
2810 (match_operand:TF 4 "register_operand" "0,e")))]
2811 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2813 "&& reload_completed"
2814 [(clobber (const_int 0))]
2816 rtx set_dest = operands[0];
2817 rtx set_srca = operands[3];
2818 rtx set_srcb = operands[4];
2819 int third = rtx_equal_p (set_dest, set_srca);
2821 rtx srca1, srca2, srcb1, srcb2;
2823 dest1 = gen_df_reg (set_dest, 0);
2824 dest2 = gen_df_reg (set_dest, 1);
2825 srca1 = gen_df_reg (set_srca, 0);
2826 srca2 = gen_df_reg (set_srca, 1);
2827 srcb1 = gen_df_reg (set_srcb, 0);
2828 srcb2 = gen_df_reg (set_srcb, 1);
2830 /* Now emit using the real source and destination we found, swapping
2831 the order if we detect overlap. */
2832 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2833 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2835 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2836 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2840 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2841 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2845 [(set_attr "length" "2")])
2848 ;; Zero-extension instructions
2850 ;; These patterns originally accepted general_operands, however, slightly
2851 ;; better code is generated by only accepting register_operands, and then
2852 ;; letting combine generate the ldu[hb] insns.
2854 (define_expand "zero_extendhisi2"
2855 [(set (match_operand:SI 0 "register_operand" "")
2856 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2859 rtx temp = gen_reg_rtx (SImode);
2860 rtx shift_16 = GEN_INT (16);
2861 int op1_subbyte = 0;
2863 if (GET_CODE (operand1) == SUBREG)
2865 op1_subbyte = SUBREG_BYTE (operand1);
2866 op1_subbyte /= GET_MODE_SIZE (SImode);
2867 op1_subbyte *= GET_MODE_SIZE (SImode);
2868 operand1 = XEXP (operand1, 0);
2871 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2873 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2877 (define_insn "*zero_extendhisi2_insn"
2878 [(set (match_operand:SI 0 "register_operand" "=r")
2879 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2882 [(set_attr "type" "load")
2883 (set_attr "us3load_type" "3cycle")])
2885 (define_expand "zero_extendqihi2"
2886 [(set (match_operand:HI 0 "register_operand" "")
2887 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2891 (define_insn "*zero_extendqihi2_insn"
2892 [(set (match_operand:HI 0 "register_operand" "=r,r")
2893 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2894 "GET_CODE (operands[1]) != CONST_INT"
2898 [(set_attr "type" "*,load")
2899 (set_attr "us3load_type" "*,3cycle")])
2901 (define_expand "zero_extendqisi2"
2902 [(set (match_operand:SI 0 "register_operand" "")
2903 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2907 (define_insn "*zero_extendqisi2_insn"
2908 [(set (match_operand:SI 0 "register_operand" "=r,r")
2909 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2910 "GET_CODE (operands[1]) != CONST_INT"
2914 [(set_attr "type" "*,load")
2915 (set_attr "us3load_type" "*,3cycle")])
2917 (define_expand "zero_extendqidi2"
2918 [(set (match_operand:DI 0 "register_operand" "")
2919 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2923 (define_insn "*zero_extendqidi2_insn"
2924 [(set (match_operand:DI 0 "register_operand" "=r,r")
2925 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2926 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2930 [(set_attr "type" "*,load")
2931 (set_attr "us3load_type" "*,3cycle")])
2933 (define_expand "zero_extendhidi2"
2934 [(set (match_operand:DI 0 "register_operand" "")
2935 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2938 rtx temp = gen_reg_rtx (DImode);
2939 rtx shift_48 = GEN_INT (48);
2940 int op1_subbyte = 0;
2942 if (GET_CODE (operand1) == SUBREG)
2944 op1_subbyte = SUBREG_BYTE (operand1);
2945 op1_subbyte /= GET_MODE_SIZE (DImode);
2946 op1_subbyte *= GET_MODE_SIZE (DImode);
2947 operand1 = XEXP (operand1, 0);
2950 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2952 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2956 (define_insn "*zero_extendhidi2_insn"
2957 [(set (match_operand:DI 0 "register_operand" "=r")
2958 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2961 [(set_attr "type" "load")
2962 (set_attr "us3load_type" "3cycle")])
2964 ;; ??? Write truncdisi pattern using sra?
2966 (define_expand "zero_extendsidi2"
2967 [(set (match_operand:DI 0 "register_operand" "")
2968 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2972 (define_insn "*zero_extendsidi2_insn_sp64"
2973 [(set (match_operand:DI 0 "register_operand" "=r,r")
2974 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2975 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2979 [(set_attr "type" "shift,load")])
2981 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2982 [(set (match_operand:DI 0 "register_operand" "=r")
2983 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2986 "&& reload_completed"
2987 [(set (match_dup 2) (match_dup 3))
2988 (set (match_dup 4) (match_dup 5))]
2992 dest1 = gen_highpart (SImode, operands[0]);
2993 dest2 = gen_lowpart (SImode, operands[0]);
2995 /* Swap the order in case of overlap. */
2996 if (REGNO (dest1) == REGNO (operands[1]))
2998 operands[2] = dest2;
2999 operands[3] = operands[1];
3000 operands[4] = dest1;
3001 operands[5] = const0_rtx;
3005 operands[2] = dest1;
3006 operands[3] = const0_rtx;
3007 operands[4] = dest2;
3008 operands[5] = operands[1];
3011 [(set_attr "length" "2")])
3013 ;; Simplify comparisons of extended values.
3015 (define_insn "*cmp_zero_extendqisi2"
3016 [(set (reg:CC CC_REG)
3017 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3020 "andcc\t%0, 0xff, %%g0"
3021 [(set_attr "type" "compare")])
3023 (define_insn "*cmp_zero_qi"
3024 [(set (reg:CC CC_REG)
3025 (compare:CC (match_operand:QI 0 "register_operand" "r")
3028 "andcc\t%0, 0xff, %%g0"
3029 [(set_attr "type" "compare")])
3031 (define_insn "*cmp_zero_extendqisi2_set"
3032 [(set (reg:CC CC_REG)
3033 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3035 (set (match_operand:SI 0 "register_operand" "=r")
3036 (zero_extend:SI (match_dup 1)))]
3038 "andcc\t%1, 0xff, %0"
3039 [(set_attr "type" "compare")])
3041 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3042 [(set (reg:CC CC_REG)
3043 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3046 (set (match_operand:SI 0 "register_operand" "=r")
3047 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3049 "andcc\t%1, 0xff, %0"
3050 [(set_attr "type" "compare")])
3052 (define_insn "*cmp_zero_extendqidi2"
3053 [(set (reg:CCX CC_REG)
3054 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3057 "andcc\t%0, 0xff, %%g0"
3058 [(set_attr "type" "compare")])
3060 (define_insn "*cmp_zero_qi_sp64"
3061 [(set (reg:CCX CC_REG)
3062 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3065 "andcc\t%0, 0xff, %%g0"
3066 [(set_attr "type" "compare")])
3068 (define_insn "*cmp_zero_extendqidi2_set"
3069 [(set (reg:CCX CC_REG)
3070 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3072 (set (match_operand:DI 0 "register_operand" "=r")
3073 (zero_extend:DI (match_dup 1)))]
3075 "andcc\t%1, 0xff, %0"
3076 [(set_attr "type" "compare")])
3078 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3079 [(set (reg:CCX CC_REG)
3080 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3083 (set (match_operand:DI 0 "register_operand" "=r")
3084 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3086 "andcc\t%1, 0xff, %0"
3087 [(set_attr "type" "compare")])
3089 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3091 (define_insn "*cmp_siqi_trunc"
3092 [(set (reg:CC CC_REG)
3093 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3096 "andcc\t%0, 0xff, %%g0"
3097 [(set_attr "type" "compare")])
3099 (define_insn "*cmp_siqi_trunc_set"
3100 [(set (reg:CC CC_REG)
3101 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3103 (set (match_operand:QI 0 "register_operand" "=r")
3104 (subreg:QI (match_dup 1) 3))]
3106 "andcc\t%1, 0xff, %0"
3107 [(set_attr "type" "compare")])
3109 (define_insn "*cmp_diqi_trunc"
3110 [(set (reg:CC CC_REG)
3111 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3114 "andcc\t%0, 0xff, %%g0"
3115 [(set_attr "type" "compare")])
3117 (define_insn "*cmp_diqi_trunc_set"
3118 [(set (reg:CC CC_REG)
3119 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3121 (set (match_operand:QI 0 "register_operand" "=r")
3122 (subreg:QI (match_dup 1) 7))]
3124 "andcc\t%1, 0xff, %0"
3125 [(set_attr "type" "compare")])
3128 ;; Sign-extension instructions
3130 ;; These patterns originally accepted general_operands, however, slightly
3131 ;; better code is generated by only accepting register_operands, and then
3132 ;; letting combine generate the lds[hb] insns.
3134 (define_expand "extendhisi2"
3135 [(set (match_operand:SI 0 "register_operand" "")
3136 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3139 rtx temp = gen_reg_rtx (SImode);
3140 rtx shift_16 = GEN_INT (16);
3141 int op1_subbyte = 0;
3143 if (GET_CODE (operand1) == SUBREG)
3145 op1_subbyte = SUBREG_BYTE (operand1);
3146 op1_subbyte /= GET_MODE_SIZE (SImode);
3147 op1_subbyte *= GET_MODE_SIZE (SImode);
3148 operand1 = XEXP (operand1, 0);
3151 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3153 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3157 (define_insn "*sign_extendhisi2_insn"
3158 [(set (match_operand:SI 0 "register_operand" "=r")
3159 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3162 [(set_attr "type" "sload")
3163 (set_attr "us3load_type" "3cycle")])
3165 (define_expand "extendqihi2"
3166 [(set (match_operand:HI 0 "register_operand" "")
3167 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3170 rtx temp = gen_reg_rtx (SImode);
3171 rtx shift_24 = GEN_INT (24);
3172 int op1_subbyte = 0;
3173 int op0_subbyte = 0;
3175 if (GET_CODE (operand1) == SUBREG)
3177 op1_subbyte = SUBREG_BYTE (operand1);
3178 op1_subbyte /= GET_MODE_SIZE (SImode);
3179 op1_subbyte *= GET_MODE_SIZE (SImode);
3180 operand1 = XEXP (operand1, 0);
3182 if (GET_CODE (operand0) == SUBREG)
3184 op0_subbyte = SUBREG_BYTE (operand0);
3185 op0_subbyte /= GET_MODE_SIZE (SImode);
3186 op0_subbyte *= GET_MODE_SIZE (SImode);
3187 operand0 = XEXP (operand0, 0);
3189 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3191 if (GET_MODE (operand0) != SImode)
3192 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3193 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3197 (define_insn "*sign_extendqihi2_insn"
3198 [(set (match_operand:HI 0 "register_operand" "=r")
3199 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3202 [(set_attr "type" "sload")
3203 (set_attr "us3load_type" "3cycle")])
3205 (define_expand "extendqisi2"
3206 [(set (match_operand:SI 0 "register_operand" "")
3207 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3210 rtx temp = gen_reg_rtx (SImode);
3211 rtx shift_24 = GEN_INT (24);
3212 int op1_subbyte = 0;
3214 if (GET_CODE (operand1) == SUBREG)
3216 op1_subbyte = SUBREG_BYTE (operand1);
3217 op1_subbyte /= GET_MODE_SIZE (SImode);
3218 op1_subbyte *= GET_MODE_SIZE (SImode);
3219 operand1 = XEXP (operand1, 0);
3222 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3224 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3228 (define_insn "*sign_extendqisi2_insn"
3229 [(set (match_operand:SI 0 "register_operand" "=r")
3230 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3233 [(set_attr "type" "sload")
3234 (set_attr "us3load_type" "3cycle")])
3236 (define_expand "extendqidi2"
3237 [(set (match_operand:DI 0 "register_operand" "")
3238 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3241 rtx temp = gen_reg_rtx (DImode);
3242 rtx shift_56 = GEN_INT (56);
3243 int op1_subbyte = 0;
3245 if (GET_CODE (operand1) == SUBREG)
3247 op1_subbyte = SUBREG_BYTE (operand1);
3248 op1_subbyte /= GET_MODE_SIZE (DImode);
3249 op1_subbyte *= GET_MODE_SIZE (DImode);
3250 operand1 = XEXP (operand1, 0);
3253 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3255 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3259 (define_insn "*sign_extendqidi2_insn"
3260 [(set (match_operand:DI 0 "register_operand" "=r")
3261 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3264 [(set_attr "type" "sload")
3265 (set_attr "us3load_type" "3cycle")])
3267 (define_expand "extendhidi2"
3268 [(set (match_operand:DI 0 "register_operand" "")
3269 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3272 rtx temp = gen_reg_rtx (DImode);
3273 rtx shift_48 = GEN_INT (48);
3274 int op1_subbyte = 0;
3276 if (GET_CODE (operand1) == SUBREG)
3278 op1_subbyte = SUBREG_BYTE (operand1);
3279 op1_subbyte /= GET_MODE_SIZE (DImode);
3280 op1_subbyte *= GET_MODE_SIZE (DImode);
3281 operand1 = XEXP (operand1, 0);
3284 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3286 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3290 (define_insn "*sign_extendhidi2_insn"
3291 [(set (match_operand:DI 0 "register_operand" "=r")
3292 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3295 [(set_attr "type" "sload")
3296 (set_attr "us3load_type" "3cycle")])
3298 (define_expand "extendsidi2"
3299 [(set (match_operand:DI 0 "register_operand" "")
3300 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3304 (define_insn "*sign_extendsidi2_insn"
3305 [(set (match_operand:DI 0 "register_operand" "=r,r")
3306 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3311 [(set_attr "type" "shift,sload")
3312 (set_attr "us3load_type" "*,3cycle")])
3315 ;; Special pattern for optimizing bit-field compares. This is needed
3316 ;; because combine uses this as a canonical form.
3318 (define_insn "*cmp_zero_extract"
3319 [(set (reg:CC CC_REG)
3321 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3322 (match_operand:SI 1 "small_int_operand" "I")
3323 (match_operand:SI 2 "small_int_operand" "I"))
3325 "INTVAL (operands[2]) > 19"
3327 int len = INTVAL (operands[1]);
3328 int pos = 32 - INTVAL (operands[2]) - len;
3329 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3330 operands[1] = GEN_INT (mask);
3331 return "andcc\t%0, %1, %%g0";
3333 [(set_attr "type" "compare")])
3335 (define_insn "*cmp_zero_extract_sp64"
3336 [(set (reg:CCX CC_REG)
3338 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3339 (match_operand:SI 1 "small_int_operand" "I")
3340 (match_operand:SI 2 "small_int_operand" "I"))
3342 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3344 int len = INTVAL (operands[1]);
3345 int pos = 64 - INTVAL (operands[2]) - len;
3346 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3347 operands[1] = GEN_INT (mask);
3348 return "andcc\t%0, %1, %%g0";
3350 [(set_attr "type" "compare")])
3353 ;; Conversions between float, double and long double.
3355 (define_insn "extendsfdf2"
3356 [(set (match_operand:DF 0 "register_operand" "=e")
3358 (match_operand:SF 1 "register_operand" "f")))]
3361 [(set_attr "type" "fp")
3362 (set_attr "fptype" "double")])
3364 (define_expand "extendsftf2"
3365 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3367 (match_operand:SF 1 "register_operand" "")))]
3368 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3369 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3371 (define_insn "*extendsftf2_hq"
3372 [(set (match_operand:TF 0 "register_operand" "=e")
3374 (match_operand:SF 1 "register_operand" "f")))]
3375 "TARGET_FPU && TARGET_HARD_QUAD"
3377 [(set_attr "type" "fp")])
3379 (define_expand "extenddftf2"
3380 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3382 (match_operand:DF 1 "register_operand" "")))]
3383 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3384 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3386 (define_insn "*extenddftf2_hq"
3387 [(set (match_operand:TF 0 "register_operand" "=e")
3389 (match_operand:DF 1 "register_operand" "e")))]
3390 "TARGET_FPU && TARGET_HARD_QUAD"
3392 [(set_attr "type" "fp")])
3394 (define_insn "truncdfsf2"
3395 [(set (match_operand:SF 0 "register_operand" "=f")
3397 (match_operand:DF 1 "register_operand" "e")))]
3400 [(set_attr "type" "fp")
3401 (set_attr "fptype" "double")])
3403 (define_expand "trunctfsf2"
3404 [(set (match_operand:SF 0 "register_operand" "")
3406 (match_operand:TF 1 "general_operand" "")))]
3407 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3408 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3410 (define_insn "*trunctfsf2_hq"
3411 [(set (match_operand:SF 0 "register_operand" "=f")
3413 (match_operand:TF 1 "register_operand" "e")))]
3414 "TARGET_FPU && TARGET_HARD_QUAD"
3416 [(set_attr "type" "fp")])
3418 (define_expand "trunctfdf2"
3419 [(set (match_operand:DF 0 "register_operand" "")
3421 (match_operand:TF 1 "general_operand" "")))]
3422 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3423 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3425 (define_insn "*trunctfdf2_hq"
3426 [(set (match_operand:DF 0 "register_operand" "=e")
3428 (match_operand:TF 1 "register_operand" "e")))]
3429 "TARGET_FPU && TARGET_HARD_QUAD"
3431 [(set_attr "type" "fp")])
3434 ;; Conversion between fixed point and floating point.
3436 (define_insn "floatsisf2"
3437 [(set (match_operand:SF 0 "register_operand" "=f")
3438 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3441 [(set_attr "type" "fp")
3442 (set_attr "fptype" "double")])
3444 (define_insn "floatsidf2"
3445 [(set (match_operand:DF 0 "register_operand" "=e")
3446 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3449 [(set_attr "type" "fp")
3450 (set_attr "fptype" "double")])
3452 (define_expand "floatsitf2"
3453 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3454 (float:TF (match_operand:SI 1 "register_operand" "")))]
3455 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3456 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3458 (define_insn "*floatsitf2_hq"
3459 [(set (match_operand:TF 0 "register_operand" "=e")
3460 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3461 "TARGET_FPU && TARGET_HARD_QUAD"
3463 [(set_attr "type" "fp")])
3465 (define_expand "floatunssitf2"
3466 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3467 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3468 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3469 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3471 ;; Now the same for 64 bit sources.
3473 (define_insn "floatdisf2"
3474 [(set (match_operand:SF 0 "register_operand" "=f")
3475 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3476 "TARGET_V9 && TARGET_FPU"
3478 [(set_attr "type" "fp")
3479 (set_attr "fptype" "double")])
3481 (define_expand "floatunsdisf2"
3482 [(use (match_operand:SF 0 "register_operand" ""))
3483 (use (match_operand:DI 1 "general_operand" ""))]
3484 "TARGET_ARCH64 && TARGET_FPU"
3485 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3487 (define_insn "floatdidf2"
3488 [(set (match_operand:DF 0 "register_operand" "=e")
3489 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3490 "TARGET_V9 && TARGET_FPU"
3492 [(set_attr "type" "fp")
3493 (set_attr "fptype" "double")])
3495 (define_expand "floatunsdidf2"
3496 [(use (match_operand:DF 0 "register_operand" ""))
3497 (use (match_operand:DI 1 "general_operand" ""))]
3498 "TARGET_ARCH64 && TARGET_FPU"
3499 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3501 (define_expand "floatditf2"
3502 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3503 (float:TF (match_operand:DI 1 "register_operand" "")))]
3504 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3505 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3507 (define_insn "*floatditf2_hq"
3508 [(set (match_operand:TF 0 "register_operand" "=e")
3509 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3510 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3512 [(set_attr "type" "fp")])
3514 (define_expand "floatunsditf2"
3515 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3516 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3517 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3518 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3520 ;; Convert a float to an actual integer.
3521 ;; Truncation is performed as part of the conversion.
3523 (define_insn "fix_truncsfsi2"
3524 [(set (match_operand:SI 0 "register_operand" "=f")
3525 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3528 [(set_attr "type" "fp")
3529 (set_attr "fptype" "double")])
3531 (define_insn "fix_truncdfsi2"
3532 [(set (match_operand:SI 0 "register_operand" "=f")
3533 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3536 [(set_attr "type" "fp")
3537 (set_attr "fptype" "double")])
3539 (define_expand "fix_trunctfsi2"
3540 [(set (match_operand:SI 0 "register_operand" "")
3541 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3542 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3543 "emit_tfmode_cvt (FIX, operands); DONE;")
3545 (define_insn "*fix_trunctfsi2_hq"
3546 [(set (match_operand:SI 0 "register_operand" "=f")
3547 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3548 "TARGET_FPU && TARGET_HARD_QUAD"
3550 [(set_attr "type" "fp")])
3552 (define_expand "fixuns_trunctfsi2"
3553 [(set (match_operand:SI 0 "register_operand" "")
3554 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3555 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3556 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3558 ;; Now the same, for V9 targets
3560 (define_insn "fix_truncsfdi2"
3561 [(set (match_operand:DI 0 "register_operand" "=e")
3562 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3563 "TARGET_V9 && TARGET_FPU"
3565 [(set_attr "type" "fp")
3566 (set_attr "fptype" "double")])
3568 (define_expand "fixuns_truncsfdi2"
3569 [(use (match_operand:DI 0 "register_operand" ""))
3570 (use (match_operand:SF 1 "general_operand" ""))]
3571 "TARGET_ARCH64 && TARGET_FPU"
3572 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3574 (define_insn "fix_truncdfdi2"
3575 [(set (match_operand:DI 0 "register_operand" "=e")
3576 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3577 "TARGET_V9 && TARGET_FPU"
3579 [(set_attr "type" "fp")
3580 (set_attr "fptype" "double")])
3582 (define_expand "fixuns_truncdfdi2"
3583 [(use (match_operand:DI 0 "register_operand" ""))
3584 (use (match_operand:DF 1 "general_operand" ""))]
3585 "TARGET_ARCH64 && TARGET_FPU"
3586 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3588 (define_expand "fix_trunctfdi2"
3589 [(set (match_operand:DI 0 "register_operand" "")
3590 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3591 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3592 "emit_tfmode_cvt (FIX, operands); DONE;")
3594 (define_insn "*fix_trunctfdi2_hq"
3595 [(set (match_operand:DI 0 "register_operand" "=e")
3596 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3597 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3599 [(set_attr "type" "fp")])
3601 (define_expand "fixuns_trunctfdi2"
3602 [(set (match_operand:DI 0 "register_operand" "")
3603 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3604 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3605 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3608 ;; Integer addition/subtraction instructions.
3610 (define_expand "adddi3"
3611 [(set (match_operand:DI 0 "register_operand" "")
3612 (plus:DI (match_operand:DI 1 "register_operand" "")
3613 (match_operand:DI 2 "arith_double_add_operand" "")))]
3616 if (! TARGET_ARCH64)
3618 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3619 gen_rtx_SET (VOIDmode, operands[0],
3620 gen_rtx_PLUS (DImode, operands[1],
3622 gen_rtx_CLOBBER (VOIDmode,
3623 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3628 (define_insn_and_split "*adddi3_insn_sp32"
3629 [(set (match_operand:DI 0 "register_operand" "=r")
3630 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3631 (match_operand:DI 2 "arith_double_operand" "rHI")))
3632 (clobber (reg:CC CC_REG))]
3635 "&& reload_completed"
3636 [(parallel [(set (reg:CC_NOOV CC_REG)
3637 (compare:CC_NOOV (plus:SI (match_dup 4)
3641 (plus:SI (match_dup 4) (match_dup 5)))])
3643 (plus:SI (plus:SI (match_dup 7)
3645 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3647 operands[3] = gen_lowpart (SImode, operands[0]);
3648 operands[4] = gen_lowpart (SImode, operands[1]);
3649 operands[5] = gen_lowpart (SImode, operands[2]);
3650 operands[6] = gen_highpart (SImode, operands[0]);
3651 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3652 #if HOST_BITS_PER_WIDE_INT == 32
3653 if (GET_CODE (operands[2]) == CONST_INT)
3655 if (INTVAL (operands[2]) < 0)
3656 operands[8] = constm1_rtx;
3658 operands[8] = const0_rtx;
3662 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3664 [(set_attr "length" "2")])
3666 ;; LTU here means "carry set"
3668 [(set (match_operand:SI 0 "register_operand" "=r")
3669 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3670 (match_operand:SI 2 "arith_operand" "rI"))
3671 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3674 [(set_attr "type" "ialuX")])
3676 (define_insn_and_split "*addx_extend_sp32"
3677 [(set (match_operand:DI 0 "register_operand" "=r")
3678 (zero_extend:DI (plus:SI (plus:SI
3679 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3680 (match_operand:SI 2 "arith_operand" "rI"))
3681 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3684 "&& reload_completed"
3685 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3686 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3687 (set (match_dup 4) (const_int 0))]
3688 "operands[3] = gen_lowpart (SImode, operands[0]);
3689 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3690 [(set_attr "length" "2")])
3692 (define_insn "*addx_extend_sp64"
3693 [(set (match_operand:DI 0 "register_operand" "=r")
3694 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3695 (match_operand:SI 2 "arith_operand" "rI"))
3696 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3699 [(set_attr "type" "ialuX")])
3701 (define_insn_and_split "*adddi3_extend_sp32"
3702 [(set (match_operand:DI 0 "register_operand" "=r")
3703 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3704 (match_operand:DI 2 "register_operand" "r")))
3705 (clobber (reg:CC CC_REG))]
3708 "&& reload_completed"
3709 [(parallel [(set (reg:CC_NOOV CC_REG)
3710 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3712 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3714 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3715 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3716 "operands[3] = gen_lowpart (SImode, operands[2]);
3717 operands[4] = gen_highpart (SImode, operands[2]);
3718 operands[5] = gen_lowpart (SImode, operands[0]);
3719 operands[6] = gen_highpart (SImode, operands[0]);"
3720 [(set_attr "length" "2")])
3722 (define_insn "*adddi3_sp64"
3723 [(set (match_operand:DI 0 "register_operand" "=r,r")
3724 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3725 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3731 (define_insn "addsi3"
3732 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3733 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3734 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3739 fpadd32s\t%1, %2, %0"
3740 [(set_attr "type" "*,*,fga")
3741 (set_attr "fptype" "*,*,single")])
3743 (define_insn "*cmp_cc_plus"
3744 [(set (reg:CC_NOOV CC_REG)
3745 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3746 (match_operand:SI 1 "arith_operand" "rI"))
3749 "addcc\t%0, %1, %%g0"
3750 [(set_attr "type" "compare")])
3752 (define_insn "*cmp_ccx_plus"
3753 [(set (reg:CCX_NOOV CC_REG)
3754 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3755 (match_operand:DI 1 "arith_operand" "rI"))
3758 "addcc\t%0, %1, %%g0"
3759 [(set_attr "type" "compare")])
3761 (define_insn "*cmp_cc_plus_set"
3762 [(set (reg:CC_NOOV CC_REG)
3763 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3764 (match_operand:SI 2 "arith_operand" "rI"))
3766 (set (match_operand:SI 0 "register_operand" "=r")
3767 (plus:SI (match_dup 1) (match_dup 2)))]
3770 [(set_attr "type" "compare")])
3772 (define_insn "*cmp_ccx_plus_set"
3773 [(set (reg:CCX_NOOV CC_REG)
3774 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3775 (match_operand:DI 2 "arith_operand" "rI"))
3777 (set (match_operand:DI 0 "register_operand" "=r")
3778 (plus:DI (match_dup 1) (match_dup 2)))]
3781 [(set_attr "type" "compare")])
3783 (define_expand "subdi3"
3784 [(set (match_operand:DI 0 "register_operand" "")
3785 (minus:DI (match_operand:DI 1 "register_operand" "")
3786 (match_operand:DI 2 "arith_double_add_operand" "")))]
3789 if (! TARGET_ARCH64)
3791 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3792 gen_rtx_SET (VOIDmode, operands[0],
3793 gen_rtx_MINUS (DImode, operands[1],
3795 gen_rtx_CLOBBER (VOIDmode,
3796 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3801 (define_insn_and_split "*subdi3_insn_sp32"
3802 [(set (match_operand:DI 0 "register_operand" "=r")
3803 (minus:DI (match_operand:DI 1 "register_operand" "r")
3804 (match_operand:DI 2 "arith_double_operand" "rHI")))
3805 (clobber (reg:CC CC_REG))]
3808 "&& reload_completed"
3809 [(parallel [(set (reg:CC_NOOV CC_REG)
3810 (compare:CC_NOOV (minus:SI (match_dup 4)
3814 (minus:SI (match_dup 4) (match_dup 5)))])
3816 (minus:SI (minus:SI (match_dup 7)
3818 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3820 operands[3] = gen_lowpart (SImode, operands[0]);
3821 operands[4] = gen_lowpart (SImode, operands[1]);
3822 operands[5] = gen_lowpart (SImode, operands[2]);
3823 operands[6] = gen_highpart (SImode, operands[0]);
3824 operands[7] = gen_highpart (SImode, operands[1]);
3825 #if HOST_BITS_PER_WIDE_INT == 32
3826 if (GET_CODE (operands[2]) == CONST_INT)
3828 if (INTVAL (operands[2]) < 0)
3829 operands[8] = constm1_rtx;
3831 operands[8] = const0_rtx;
3835 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3837 [(set_attr "length" "2")])
3839 ;; LTU here means "carry set"
3841 [(set (match_operand:SI 0 "register_operand" "=r")
3842 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3843 (match_operand:SI 2 "arith_operand" "rI"))
3844 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3847 [(set_attr "type" "ialuX")])
3849 (define_insn "*subx_extend_sp64"
3850 [(set (match_operand:DI 0 "register_operand" "=r")
3851 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3852 (match_operand:SI 2 "arith_operand" "rI"))
3853 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3856 [(set_attr "type" "ialuX")])
3858 (define_insn_and_split "*subx_extend"
3859 [(set (match_operand:DI 0 "register_operand" "=r")
3860 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3861 (match_operand:SI 2 "arith_operand" "rI"))
3862 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3865 "&& reload_completed"
3866 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3867 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3868 (set (match_dup 4) (const_int 0))]
3869 "operands[3] = gen_lowpart (SImode, operands[0]);
3870 operands[4] = gen_highpart (SImode, operands[0]);"
3871 [(set_attr "length" "2")])
3873 (define_insn_and_split "*subdi3_extend_sp32"
3874 [(set (match_operand:DI 0 "register_operand" "=r")
3875 (minus:DI (match_operand:DI 1 "register_operand" "r")
3876 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3877 (clobber (reg:CC CC_REG))]
3880 "&& reload_completed"
3881 [(parallel [(set (reg:CC_NOOV CC_REG)
3882 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3884 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3886 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3887 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3888 "operands[3] = gen_lowpart (SImode, operands[1]);
3889 operands[4] = gen_highpart (SImode, operands[1]);
3890 operands[5] = gen_lowpart (SImode, operands[0]);
3891 operands[6] = gen_highpart (SImode, operands[0]);"
3892 [(set_attr "length" "2")])
3894 (define_insn "*subdi3_sp64"
3895 [(set (match_operand:DI 0 "register_operand" "=r,r")
3896 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3897 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3903 (define_insn "subsi3"
3904 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3905 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3906 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3911 fpsub32s\t%1, %2, %0"
3912 [(set_attr "type" "*,*,fga")
3913 (set_attr "fptype" "*,*,single")])
3915 (define_insn "*cmp_minus_cc"
3916 [(set (reg:CC_NOOV CC_REG)
3917 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3918 (match_operand:SI 1 "arith_operand" "rI"))
3921 "subcc\t%r0, %1, %%g0"
3922 [(set_attr "type" "compare")])
3924 (define_insn "*cmp_minus_ccx"
3925 [(set (reg:CCX_NOOV CC_REG)
3926 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3927 (match_operand:DI 1 "arith_operand" "rI"))
3930 "subcc\t%0, %1, %%g0"
3931 [(set_attr "type" "compare")])
3933 (define_insn "cmp_minus_cc_set"
3934 [(set (reg:CC_NOOV CC_REG)
3935 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3936 (match_operand:SI 2 "arith_operand" "rI"))
3938 (set (match_operand:SI 0 "register_operand" "=r")
3939 (minus:SI (match_dup 1) (match_dup 2)))]
3941 "subcc\t%r1, %2, %0"
3942 [(set_attr "type" "compare")])
3944 (define_insn "*cmp_minus_ccx_set"
3945 [(set (reg:CCX_NOOV CC_REG)
3946 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3947 (match_operand:DI 2 "arith_operand" "rI"))
3949 (set (match_operand:DI 0 "register_operand" "=r")
3950 (minus:DI (match_dup 1) (match_dup 2)))]
3953 [(set_attr "type" "compare")])
3956 ;; Integer multiply/divide instructions.
3958 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3959 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3961 (define_insn "mulsi3"
3962 [(set (match_operand:SI 0 "register_operand" "=r")
3963 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3964 (match_operand:SI 2 "arith_operand" "rI")))]
3967 [(set_attr "type" "imul")])
3969 (define_expand "muldi3"
3970 [(set (match_operand:DI 0 "register_operand" "")
3971 (mult:DI (match_operand:DI 1 "arith_operand" "")
3972 (match_operand:DI 2 "arith_operand" "")))]
3973 "TARGET_ARCH64 || TARGET_V8PLUS"
3977 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3982 (define_insn "*muldi3_sp64"
3983 [(set (match_operand:DI 0 "register_operand" "=r")
3984 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3985 (match_operand:DI 2 "arith_operand" "rI")))]
3988 [(set_attr "type" "imul")])
3990 ;; V8plus wide multiply.
3992 (define_insn "muldi3_v8plus"
3993 [(set (match_operand:DI 0 "register_operand" "=r,h")
3994 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3995 (match_operand:DI 2 "arith_operand" "rI,rI")))
3996 (clobber (match_scratch:SI 3 "=&h,X"))
3997 (clobber (match_scratch:SI 4 "=&h,X"))]
4000 if (sparc_check_64 (operands[1], insn) <= 0)
4001 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4002 if (which_alternative == 1)
4003 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4004 if (GET_CODE (operands[2]) == CONST_INT)
4006 if (which_alternative == 1)
4007 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4009 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";
4011 else if (rtx_equal_p (operands[1], operands[2]))
4013 if (which_alternative == 1)
4014 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4016 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";
4018 if (sparc_check_64 (operands[2], insn) <= 0)
4019 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4020 if (which_alternative == 1)
4021 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";
4023 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";
4025 [(set_attr "type" "multi")
4026 (set_attr "length" "9,8")])
4028 (define_insn "*cmp_mul_set"
4029 [(set (reg:CC CC_REG)
4030 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4031 (match_operand:SI 2 "arith_operand" "rI"))
4033 (set (match_operand:SI 0 "register_operand" "=r")
4034 (mult:SI (match_dup 1) (match_dup 2)))]
4035 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4036 "smulcc\t%1, %2, %0"
4037 [(set_attr "type" "imul")])
4039 (define_expand "mulsidi3"
4040 [(set (match_operand:DI 0 "register_operand" "")
4041 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4042 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4045 if (CONSTANT_P (operands[2]))
4048 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4050 else if (TARGET_ARCH32)
4051 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4054 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4060 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4065 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4066 ;; registers can hold 64-bit values in the V8plus environment.
4068 (define_insn "mulsidi3_v8plus"
4069 [(set (match_operand:DI 0 "register_operand" "=h,r")
4070 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4071 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4072 (clobber (match_scratch:SI 3 "=X,&h"))]
4075 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4076 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4077 [(set_attr "type" "multi")
4078 (set_attr "length" "2,3")])
4081 (define_insn "const_mulsidi3_v8plus"
4082 [(set (match_operand:DI 0 "register_operand" "=h,r")
4083 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4084 (match_operand:DI 2 "small_int_operand" "I,I")))
4085 (clobber (match_scratch:SI 3 "=X,&h"))]
4088 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4089 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4090 [(set_attr "type" "multi")
4091 (set_attr "length" "2,3")])
4094 (define_insn "*mulsidi3_sp32"
4095 [(set (match_operand:DI 0 "register_operand" "=r")
4096 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4097 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4100 return TARGET_SPARCLET
4101 ? "smuld\t%1, %2, %L0"
4102 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4105 (if_then_else (eq_attr "isa" "sparclet")
4106 (const_string "imul") (const_string "multi")))
4107 (set (attr "length")
4108 (if_then_else (eq_attr "isa" "sparclet")
4109 (const_int 1) (const_int 2)))])
4111 (define_insn "*mulsidi3_sp64"
4112 [(set (match_operand:DI 0 "register_operand" "=r")
4113 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4114 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4115 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4117 [(set_attr "type" "imul")])
4119 ;; Extra pattern, because sign_extend of a constant isn't valid.
4122 (define_insn "const_mulsidi3_sp32"
4123 [(set (match_operand:DI 0 "register_operand" "=r")
4124 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4125 (match_operand:DI 2 "small_int_operand" "I")))]
4128 return TARGET_SPARCLET
4129 ? "smuld\t%1, %2, %L0"
4130 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4133 (if_then_else (eq_attr "isa" "sparclet")
4134 (const_string "imul") (const_string "multi")))
4135 (set (attr "length")
4136 (if_then_else (eq_attr "isa" "sparclet")
4137 (const_int 1) (const_int 2)))])
4139 (define_insn "const_mulsidi3_sp64"
4140 [(set (match_operand:DI 0 "register_operand" "=r")
4141 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4142 (match_operand:DI 2 "small_int_operand" "I")))]
4143 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4145 [(set_attr "type" "imul")])
4147 (define_expand "smulsi3_highpart"
4148 [(set (match_operand:SI 0 "register_operand" "")
4150 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4151 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4153 "TARGET_HARD_MUL && TARGET_ARCH32"
4155 if (CONSTANT_P (operands[2]))
4159 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4165 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4170 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4171 operands[2], GEN_INT (32)));
4177 (define_insn "smulsi3_highpart_v8plus"
4178 [(set (match_operand:SI 0 "register_operand" "=h,r")
4180 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4181 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4182 (match_operand:SI 3 "small_int_operand" "I,I"))))
4183 (clobber (match_scratch:SI 4 "=X,&h"))]
4186 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4187 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4188 [(set_attr "type" "multi")
4189 (set_attr "length" "2")])
4191 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4194 [(set (match_operand:SI 0 "register_operand" "=h,r")
4197 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4198 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4199 (match_operand:SI 3 "small_int_operand" "I,I"))
4201 (clobber (match_scratch:SI 4 "=X,&h"))]
4204 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4205 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4206 [(set_attr "type" "multi")
4207 (set_attr "length" "2")])
4210 (define_insn "const_smulsi3_highpart_v8plus"
4211 [(set (match_operand:SI 0 "register_operand" "=h,r")
4213 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4214 (match_operand:DI 2 "small_int_operand" "I,I"))
4215 (match_operand:SI 3 "small_int_operand" "I,I"))))
4216 (clobber (match_scratch:SI 4 "=X,&h"))]
4219 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4220 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4221 [(set_attr "type" "multi")
4222 (set_attr "length" "2")])
4225 (define_insn "*smulsi3_highpart_sp32"
4226 [(set (match_operand:SI 0 "register_operand" "=r")
4228 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4229 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4232 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4233 [(set_attr "type" "multi")
4234 (set_attr "length" "2")])
4237 (define_insn "const_smulsi3_highpart"
4238 [(set (match_operand:SI 0 "register_operand" "=r")
4240 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4241 (match_operand:DI 2 "small_int_operand" "i"))
4244 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4245 [(set_attr "type" "multi")
4246 (set_attr "length" "2")])
4248 (define_expand "umulsidi3"
4249 [(set (match_operand:DI 0 "register_operand" "")
4250 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4251 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4254 if (CONSTANT_P (operands[2]))
4257 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4259 else if (TARGET_ARCH32)
4260 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4263 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4269 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4275 (define_insn "umulsidi3_v8plus"
4276 [(set (match_operand:DI 0 "register_operand" "=h,r")
4277 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4278 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4279 (clobber (match_scratch:SI 3 "=X,&h"))]
4282 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4283 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4284 [(set_attr "type" "multi")
4285 (set_attr "length" "2,3")])
4288 (define_insn "*umulsidi3_sp32"
4289 [(set (match_operand:DI 0 "register_operand" "=r")
4290 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4291 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4294 return TARGET_SPARCLET
4295 ? "umuld\t%1, %2, %L0"
4296 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4299 (if_then_else (eq_attr "isa" "sparclet")
4300 (const_string "imul") (const_string "multi")))
4301 (set (attr "length")
4302 (if_then_else (eq_attr "isa" "sparclet")
4303 (const_int 1) (const_int 2)))])
4305 (define_insn "*umulsidi3_sp64"
4306 [(set (match_operand:DI 0 "register_operand" "=r")
4307 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4308 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4309 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4311 [(set_attr "type" "imul")])
4313 ;; Extra pattern, because sign_extend of a constant isn't valid.
4316 (define_insn "const_umulsidi3_sp32"
4317 [(set (match_operand:DI 0 "register_operand" "=r")
4318 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4319 (match_operand:DI 2 "uns_small_int_operand" "")))]
4322 return TARGET_SPARCLET
4323 ? "umuld\t%1, %s2, %L0"
4324 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4327 (if_then_else (eq_attr "isa" "sparclet")
4328 (const_string "imul") (const_string "multi")))
4329 (set (attr "length")
4330 (if_then_else (eq_attr "isa" "sparclet")
4331 (const_int 1) (const_int 2)))])
4333 (define_insn "const_umulsidi3_sp64"
4334 [(set (match_operand:DI 0 "register_operand" "=r")
4335 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4336 (match_operand:DI 2 "uns_small_int_operand" "")))]
4337 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4339 [(set_attr "type" "imul")])
4342 (define_insn "const_umulsidi3_v8plus"
4343 [(set (match_operand:DI 0 "register_operand" "=h,r")
4344 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4345 (match_operand:DI 2 "uns_small_int_operand" "")))
4346 (clobber (match_scratch:SI 3 "=X,h"))]
4349 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4350 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4351 [(set_attr "type" "multi")
4352 (set_attr "length" "2,3")])
4354 (define_expand "umulsi3_highpart"
4355 [(set (match_operand:SI 0 "register_operand" "")
4357 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4358 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4360 "TARGET_HARD_MUL && TARGET_ARCH32"
4362 if (CONSTANT_P (operands[2]))
4366 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4372 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4377 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4378 operands[2], GEN_INT (32)));
4384 (define_insn "umulsi3_highpart_v8plus"
4385 [(set (match_operand:SI 0 "register_operand" "=h,r")
4387 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4388 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4389 (match_operand:SI 3 "small_int_operand" "I,I"))))
4390 (clobber (match_scratch:SI 4 "=X,h"))]
4393 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4394 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4395 [(set_attr "type" "multi")
4396 (set_attr "length" "2")])
4399 (define_insn "const_umulsi3_highpart_v8plus"
4400 [(set (match_operand:SI 0 "register_operand" "=h,r")
4402 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4403 (match_operand:DI 2 "uns_small_int_operand" ""))
4404 (match_operand:SI 3 "small_int_operand" "I,I"))))
4405 (clobber (match_scratch:SI 4 "=X,h"))]
4408 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4409 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4410 [(set_attr "type" "multi")
4411 (set_attr "length" "2")])
4414 (define_insn "*umulsi3_highpart_sp32"
4415 [(set (match_operand:SI 0 "register_operand" "=r")
4417 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4418 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4421 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4422 [(set_attr "type" "multi")
4423 (set_attr "length" "2")])
4426 (define_insn "const_umulsi3_highpart"
4427 [(set (match_operand:SI 0 "register_operand" "=r")
4429 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4430 (match_operand:DI 2 "uns_small_int_operand" ""))
4433 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4434 [(set_attr "type" "multi")
4435 (set_attr "length" "2")])
4437 (define_expand "divsi3"
4438 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4439 (div:SI (match_operand:SI 1 "register_operand" "")
4440 (match_operand:SI 2 "input_operand" "")))
4441 (clobber (match_scratch:SI 3 ""))])]
4442 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4446 operands[3] = gen_reg_rtx(SImode);
4447 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4448 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4454 ;; The V8 architecture specifies that there must be at least 3 instructions
4455 ;; between a write to the Y register and a use of it for correct results.
4456 ;; We try to fill one of them with a simple constant or a memory load.
4458 (define_insn "divsi3_sp32"
4459 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4460 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4461 (match_operand:SI 2 "input_operand" "rI,K,m")))
4462 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4463 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4465 output_asm_insn ("sra\t%1, 31, %3", operands);
4466 output_asm_insn ("wr\t%3, 0, %%y", operands);
4468 switch (which_alternative)
4472 return "sdiv\t%1, %2, %0";
4474 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4477 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4479 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4482 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4484 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4489 [(set_attr "type" "multi")
4490 (set (attr "length")
4491 (if_then_else (eq_attr "isa" "v9")
4492 (const_int 4) (const_int 6)))])
4494 (define_insn "divsi3_sp64"
4495 [(set (match_operand:SI 0 "register_operand" "=r")
4496 (div:SI (match_operand:SI 1 "register_operand" "r")
4497 (match_operand:SI 2 "input_operand" "rI")))
4498 (use (match_operand:SI 3 "register_operand" "r"))]
4499 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4500 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4501 [(set_attr "type" "multi")
4502 (set_attr "length" "2")])
4504 (define_insn "divdi3"
4505 [(set (match_operand:DI 0 "register_operand" "=r")
4506 (div:DI (match_operand:DI 1 "register_operand" "r")
4507 (match_operand:DI 2 "arith_operand" "rI")))]
4510 [(set_attr "type" "idiv")])
4512 (define_insn "*cmp_sdiv_cc_set"
4513 [(set (reg:CC CC_REG)
4514 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4515 (match_operand:SI 2 "arith_operand" "rI"))
4517 (set (match_operand:SI 0 "register_operand" "=r")
4518 (div:SI (match_dup 1) (match_dup 2)))
4519 (clobber (match_scratch:SI 3 "=&r"))]
4520 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4522 output_asm_insn ("sra\t%1, 31, %3", operands);
4523 output_asm_insn ("wr\t%3, 0, %%y", operands);
4526 return "sdivcc\t%1, %2, %0";
4528 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4530 [(set_attr "type" "multi")
4531 (set (attr "length")
4532 (if_then_else (eq_attr "isa" "v9")
4533 (const_int 3) (const_int 6)))])
4536 (define_expand "udivsi3"
4537 [(set (match_operand:SI 0 "register_operand" "")
4538 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4539 (match_operand:SI 2 "input_operand" "")))]
4540 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4543 ;; The V8 architecture specifies that there must be at least 3 instructions
4544 ;; between a write to the Y register and a use of it for correct results.
4545 ;; We try to fill one of them with a simple constant or a memory load.
4547 (define_insn "udivsi3_sp32"
4548 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4549 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4550 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4551 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4553 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4555 switch (which_alternative)
4559 return "udiv\t%1, %2, %0";
4561 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4564 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4566 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4569 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4571 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4574 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4576 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4581 [(set_attr "type" "multi")
4582 (set (attr "length")
4583 (if_then_else (eq_attr "isa" "v9")
4584 (const_int 3) (const_int 5)))])
4586 (define_insn "udivsi3_sp64"
4587 [(set (match_operand:SI 0 "register_operand" "=r")
4588 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4589 (match_operand:SI 2 "input_operand" "rI")))]
4590 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4591 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4592 [(set_attr "type" "multi")
4593 (set_attr "length" "2")])
4595 (define_insn "udivdi3"
4596 [(set (match_operand:DI 0 "register_operand" "=r")
4597 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4598 (match_operand:DI 2 "arith_operand" "rI")))]
4601 [(set_attr "type" "idiv")])
4603 (define_insn "*cmp_udiv_cc_set"
4604 [(set (reg:CC CC_REG)
4605 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4606 (match_operand:SI 2 "arith_operand" "rI"))
4608 (set (match_operand:SI 0 "register_operand" "=r")
4609 (udiv:SI (match_dup 1) (match_dup 2)))]
4610 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4612 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4615 return "udivcc\t%1, %2, %0";
4617 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4619 [(set_attr "type" "multi")
4620 (set (attr "length")
4621 (if_then_else (eq_attr "isa" "v9")
4622 (const_int 2) (const_int 5)))])
4624 ; sparclet multiply/accumulate insns
4626 (define_insn "*smacsi"
4627 [(set (match_operand:SI 0 "register_operand" "=r")
4628 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4629 (match_operand:SI 2 "arith_operand" "rI"))
4630 (match_operand:SI 3 "register_operand" "0")))]
4633 [(set_attr "type" "imul")])
4635 (define_insn "*smacdi"
4636 [(set (match_operand:DI 0 "register_operand" "=r")
4637 (plus:DI (mult:DI (sign_extend:DI
4638 (match_operand:SI 1 "register_operand" "%r"))
4640 (match_operand:SI 2 "register_operand" "r")))
4641 (match_operand:DI 3 "register_operand" "0")))]
4643 "smacd\t%1, %2, %L0"
4644 [(set_attr "type" "imul")])
4646 (define_insn "*umacdi"
4647 [(set (match_operand:DI 0 "register_operand" "=r")
4648 (plus:DI (mult:DI (zero_extend:DI
4649 (match_operand:SI 1 "register_operand" "%r"))
4651 (match_operand:SI 2 "register_operand" "r")))
4652 (match_operand:DI 3 "register_operand" "0")))]
4654 "umacd\t%1, %2, %L0"
4655 [(set_attr "type" "imul")])
4658 ;; Boolean instructions.
4660 ;; We define DImode `and' so with DImode `not' we can get
4661 ;; DImode `andn'. Other combinations are possible.
4663 (define_expand "and<V64I:mode>3"
4664 [(set (match_operand:V64I 0 "register_operand" "")
4665 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4666 (match_operand:V64I 2 "arith_double_operand" "")))]
4670 (define_insn "*and<V64I:mode>3_sp32"
4671 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4672 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4673 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4678 [(set_attr "type" "*,fga")
4679 (set_attr "length" "2,*")
4680 (set_attr "fptype" "*,double")])
4682 (define_insn "*and<V64I:mode>3_sp64"
4683 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4684 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4685 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4690 [(set_attr "type" "*,fga")
4691 (set_attr "fptype" "*,double")])
4693 (define_insn "and<V32I:mode>3"
4694 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4695 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4696 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4701 [(set_attr "type" "*,fga")
4702 (set_attr "fptype" "*,single")])
4705 [(set (match_operand:SI 0 "register_operand" "")
4706 (and:SI (match_operand:SI 1 "register_operand" "")
4707 (match_operand:SI 2 "const_compl_high_operand" "")))
4708 (clobber (match_operand:SI 3 "register_operand" ""))]
4710 [(set (match_dup 3) (match_dup 4))
4711 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4713 operands[4] = GEN_INT (~INTVAL (operands[2]));
4716 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4717 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4718 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4719 (match_operand:V64I 2 "register_operand" "r,b")))]
4723 fandnot1\t%1, %2, %0"
4724 "&& reload_completed
4725 && ((GET_CODE (operands[0]) == REG
4726 && REGNO (operands[0]) < 32)
4727 || (GET_CODE (operands[0]) == SUBREG
4728 && GET_CODE (SUBREG_REG (operands[0])) == REG
4729 && REGNO (SUBREG_REG (operands[0])) < 32))"
4730 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4731 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4732 "operands[3] = gen_highpart (SImode, operands[0]);
4733 operands[4] = gen_highpart (SImode, operands[1]);
4734 operands[5] = gen_highpart (SImode, operands[2]);
4735 operands[6] = gen_lowpart (SImode, operands[0]);
4736 operands[7] = gen_lowpart (SImode, operands[1]);
4737 operands[8] = gen_lowpart (SImode, operands[2]);"
4738 [(set_attr "type" "*,fga")
4739 (set_attr "length" "2,*")
4740 (set_attr "fptype" "*,double")])
4742 (define_insn "*and_not_<V64I:mode>_sp64"
4743 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4744 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4745 (match_operand:V64I 2 "register_operand" "r,b")))]
4749 fandnot1\t%1, %2, %0"
4750 [(set_attr "type" "*,fga")
4751 (set_attr "fptype" "*,double")])
4753 (define_insn "*and_not_<V32I:mode>"
4754 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4755 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4756 (match_operand:V32I 2 "register_operand" "r,d")))]
4760 fandnot1s\t%1, %2, %0"
4761 [(set_attr "type" "*,fga")
4762 (set_attr "fptype" "*,single")])
4764 (define_expand "ior<V64I:mode>3"
4765 [(set (match_operand:V64I 0 "register_operand" "")
4766 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4767 (match_operand:V64I 2 "arith_double_operand" "")))]
4771 (define_insn "*ior<V64I:mode>3_sp32"
4772 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4773 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4774 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4779 [(set_attr "type" "*,fga")
4780 (set_attr "length" "2,*")
4781 (set_attr "fptype" "*,double")])
4783 (define_insn "*ior<V64I:mode>3_sp64"
4784 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4785 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4786 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4791 [(set_attr "type" "*,fga")
4792 (set_attr "fptype" "*,double")])
4794 (define_insn "ior<V32I:mode>3"
4795 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4796 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4797 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4802 [(set_attr "type" "*,fga")
4803 (set_attr "fptype" "*,single")])
4806 [(set (match_operand:SI 0 "register_operand" "")
4807 (ior:SI (match_operand:SI 1 "register_operand" "")
4808 (match_operand:SI 2 "const_compl_high_operand" "")))
4809 (clobber (match_operand:SI 3 "register_operand" ""))]
4811 [(set (match_dup 3) (match_dup 4))
4812 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4814 operands[4] = GEN_INT (~INTVAL (operands[2]));
4817 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4818 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4819 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4820 (match_operand:V64I 2 "register_operand" "r,b")))]
4824 fornot1\t%1, %2, %0"
4825 "&& reload_completed
4826 && ((GET_CODE (operands[0]) == REG
4827 && REGNO (operands[0]) < 32)
4828 || (GET_CODE (operands[0]) == SUBREG
4829 && GET_CODE (SUBREG_REG (operands[0])) == REG
4830 && REGNO (SUBREG_REG (operands[0])) < 32))"
4831 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4832 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4833 "operands[3] = gen_highpart (SImode, operands[0]);
4834 operands[4] = gen_highpart (SImode, operands[1]);
4835 operands[5] = gen_highpart (SImode, operands[2]);
4836 operands[6] = gen_lowpart (SImode, operands[0]);
4837 operands[7] = gen_lowpart (SImode, operands[1]);
4838 operands[8] = gen_lowpart (SImode, operands[2]);"
4839 [(set_attr "type" "*,fga")
4840 (set_attr "length" "2,*")
4841 (set_attr "fptype" "*,double")])
4843 (define_insn "*or_not_<V64I:mode>_sp64"
4844 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4845 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4846 (match_operand:V64I 2 "register_operand" "r,b")))]
4850 fornot1\t%1, %2, %0"
4851 [(set_attr "type" "*,fga")
4852 (set_attr "fptype" "*,double")])
4854 (define_insn "*or_not_<V32I:mode>"
4855 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4856 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4857 (match_operand:V32I 2 "register_operand" "r,d")))]
4861 fornot1s\t%1, %2, %0"
4862 [(set_attr "type" "*,fga")
4863 (set_attr "fptype" "*,single")])
4865 (define_expand "xor<V64I:mode>3"
4866 [(set (match_operand:V64I 0 "register_operand" "")
4867 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4868 (match_operand:V64I 2 "arith_double_operand" "")))]
4872 (define_insn "*xor<V64I:mode>3_sp32"
4873 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4874 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4875 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4880 [(set_attr "type" "*,fga")
4881 (set_attr "length" "2,*")
4882 (set_attr "fptype" "*,double")])
4884 (define_insn "*xor<V64I:mode>3_sp64"
4885 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4886 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4887 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4892 [(set_attr "type" "*,fga")
4893 (set_attr "fptype" "*,double")])
4895 (define_insn "xor<V32I:mode>3"
4896 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4897 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4898 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4903 [(set_attr "type" "*,fga")
4904 (set_attr "fptype" "*,single")])
4907 [(set (match_operand:SI 0 "register_operand" "")
4908 (xor:SI (match_operand:SI 1 "register_operand" "")
4909 (match_operand:SI 2 "const_compl_high_operand" "")))
4910 (clobber (match_operand:SI 3 "register_operand" ""))]
4912 [(set (match_dup 3) (match_dup 4))
4913 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4915 operands[4] = GEN_INT (~INTVAL (operands[2]));
4919 [(set (match_operand:SI 0 "register_operand" "")
4920 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4921 (match_operand:SI 2 "const_compl_high_operand" ""))))
4922 (clobber (match_operand:SI 3 "register_operand" ""))]
4924 [(set (match_dup 3) (match_dup 4))
4925 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4927 operands[4] = GEN_INT (~INTVAL (operands[2]));
4930 ;; Split DImode logical operations requiring two instructions.
4932 [(set (match_operand:V64I 0 "register_operand" "")
4933 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4934 [(match_operand:V64I 2 "register_operand" "")
4935 (match_operand:V64I 3 "arith_double_operand" "")]))]
4938 && ((GET_CODE (operands[0]) == REG
4939 && REGNO (operands[0]) < 32)
4940 || (GET_CODE (operands[0]) == SUBREG
4941 && GET_CODE (SUBREG_REG (operands[0])) == REG
4942 && REGNO (SUBREG_REG (operands[0])) < 32))"
4943 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4944 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4946 operands[4] = gen_highpart (SImode, operands[0]);
4947 operands[5] = gen_lowpart (SImode, operands[0]);
4948 operands[6] = gen_highpart (SImode, operands[2]);
4949 operands[7] = gen_lowpart (SImode, operands[2]);
4950 #if HOST_BITS_PER_WIDE_INT == 32
4951 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4953 if (INTVAL (operands[3]) < 0)
4954 operands[8] = constm1_rtx;
4956 operands[8] = const0_rtx;
4960 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4961 operands[9] = gen_lowpart (SImode, operands[3]);
4964 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4965 ;; Combine now canonicalizes to the rightmost expression.
4966 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4967 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4968 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4969 (match_operand:V64I 2 "register_operand" "r,b"))))]
4974 "&& reload_completed
4975 && ((GET_CODE (operands[0]) == REG
4976 && REGNO (operands[0]) < 32)
4977 || (GET_CODE (operands[0]) == SUBREG
4978 && GET_CODE (SUBREG_REG (operands[0])) == REG
4979 && REGNO (SUBREG_REG (operands[0])) < 32))"
4980 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4981 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4982 "operands[3] = gen_highpart (SImode, operands[0]);
4983 operands[4] = gen_highpart (SImode, operands[1]);
4984 operands[5] = gen_highpart (SImode, operands[2]);
4985 operands[6] = gen_lowpart (SImode, operands[0]);
4986 operands[7] = gen_lowpart (SImode, operands[1]);
4987 operands[8] = gen_lowpart (SImode, operands[2]);"
4988 [(set_attr "type" "*,fga")
4989 (set_attr "length" "2,*")
4990 (set_attr "fptype" "*,double")])
4992 (define_insn "*xor_not_<V64I:mode>_sp64"
4993 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4994 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4995 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5000 [(set_attr "type" "*,fga")
5001 (set_attr "fptype" "*,double")])
5003 (define_insn "*xor_not_<V32I:mode>"
5004 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5005 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5006 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5011 [(set_attr "type" "*,fga")
5012 (set_attr "fptype" "*,single")])
5014 ;; These correspond to the above in the case where we also (or only)
5015 ;; want to set the condition code.
5017 (define_insn "*cmp_cc_arith_op"
5018 [(set (reg:CC CC_REG)
5020 (match_operator:SI 2 "cc_arith_operator"
5021 [(match_operand:SI 0 "arith_operand" "%r")
5022 (match_operand:SI 1 "arith_operand" "rI")])
5025 "%A2cc\t%0, %1, %%g0"
5026 [(set_attr "type" "compare")])
5028 (define_insn "*cmp_ccx_arith_op"
5029 [(set (reg:CCX CC_REG)
5031 (match_operator:DI 2 "cc_arith_operator"
5032 [(match_operand:DI 0 "arith_operand" "%r")
5033 (match_operand:DI 1 "arith_operand" "rI")])
5036 "%A2cc\t%0, %1, %%g0"
5037 [(set_attr "type" "compare")])
5039 (define_insn "*cmp_cc_arith_op_set"
5040 [(set (reg:CC CC_REG)
5042 (match_operator:SI 3 "cc_arith_operator"
5043 [(match_operand:SI 1 "arith_operand" "%r")
5044 (match_operand:SI 2 "arith_operand" "rI")])
5046 (set (match_operand:SI 0 "register_operand" "=r")
5047 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5048 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5050 [(set_attr "type" "compare")])
5052 (define_insn "*cmp_ccx_arith_op_set"
5053 [(set (reg:CCX CC_REG)
5055 (match_operator:DI 3 "cc_arith_operator"
5056 [(match_operand:DI 1 "arith_operand" "%r")
5057 (match_operand:DI 2 "arith_operand" "rI")])
5059 (set (match_operand:DI 0 "register_operand" "=r")
5060 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5061 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5063 [(set_attr "type" "compare")])
5065 (define_insn "*cmp_cc_xor_not"
5066 [(set (reg:CC CC_REG)
5068 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5069 (match_operand:SI 1 "arith_operand" "rI")))
5072 "xnorcc\t%r0, %1, %%g0"
5073 [(set_attr "type" "compare")])
5075 (define_insn "*cmp_ccx_xor_not"
5076 [(set (reg:CCX CC_REG)
5078 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5079 (match_operand:DI 1 "arith_operand" "rI")))
5082 "xnorcc\t%r0, %1, %%g0"
5083 [(set_attr "type" "compare")])
5085 (define_insn "*cmp_cc_xor_not_set"
5086 [(set (reg:CC CC_REG)
5088 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5089 (match_operand:SI 2 "arith_operand" "rI")))
5091 (set (match_operand:SI 0 "register_operand" "=r")
5092 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5094 "xnorcc\t%r1, %2, %0"
5095 [(set_attr "type" "compare")])
5097 (define_insn "*cmp_ccx_xor_not_set"
5098 [(set (reg:CCX CC_REG)
5100 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5101 (match_operand:DI 2 "arith_operand" "rI")))
5103 (set (match_operand:DI 0 "register_operand" "=r")
5104 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5106 "xnorcc\t%r1, %2, %0"
5107 [(set_attr "type" "compare")])
5109 (define_insn "*cmp_cc_arith_op_not"
5110 [(set (reg:CC CC_REG)
5112 (match_operator:SI 2 "cc_arith_not_operator"
5113 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5114 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5117 "%B2cc\t%r1, %0, %%g0"
5118 [(set_attr "type" "compare")])
5120 (define_insn "*cmp_ccx_arith_op_not"
5121 [(set (reg:CCX CC_REG)
5123 (match_operator:DI 2 "cc_arith_not_operator"
5124 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5125 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5128 "%B2cc\t%r1, %0, %%g0"
5129 [(set_attr "type" "compare")])
5131 (define_insn "*cmp_cc_arith_op_not_set"
5132 [(set (reg:CC CC_REG)
5134 (match_operator:SI 3 "cc_arith_not_operator"
5135 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5136 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5138 (set (match_operand:SI 0 "register_operand" "=r")
5139 (match_operator:SI 4 "cc_arith_not_operator"
5140 [(not:SI (match_dup 1)) (match_dup 2)]))]
5141 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5142 "%B3cc\t%r2, %1, %0"
5143 [(set_attr "type" "compare")])
5145 (define_insn "*cmp_ccx_arith_op_not_set"
5146 [(set (reg:CCX CC_REG)
5148 (match_operator:DI 3 "cc_arith_not_operator"
5149 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5150 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5152 (set (match_operand:DI 0 "register_operand" "=r")
5153 (match_operator:DI 4 "cc_arith_not_operator"
5154 [(not:DI (match_dup 1)) (match_dup 2)]))]
5155 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5156 "%B3cc\t%r2, %1, %0"
5157 [(set_attr "type" "compare")])
5159 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5160 ;; does not know how to make it work for constants.
5162 (define_expand "negdi2"
5163 [(set (match_operand:DI 0 "register_operand" "=r")
5164 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5167 if (! TARGET_ARCH64)
5169 emit_insn (gen_rtx_PARALLEL
5172 gen_rtx_SET (VOIDmode, operand0,
5173 gen_rtx_NEG (DImode, operand1)),
5174 gen_rtx_CLOBBER (VOIDmode,
5175 gen_rtx_REG (CCmode,
5181 (define_insn_and_split "*negdi2_sp32"
5182 [(set (match_operand:DI 0 "register_operand" "=r")
5183 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5184 (clobber (reg:CC CC_REG))]
5187 "&& reload_completed"
5188 [(parallel [(set (reg:CC_NOOV CC_REG)
5189 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5191 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5192 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5193 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5194 "operands[2] = gen_highpart (SImode, operands[0]);
5195 operands[3] = gen_highpart (SImode, operands[1]);
5196 operands[4] = gen_lowpart (SImode, operands[0]);
5197 operands[5] = gen_lowpart (SImode, operands[1]);"
5198 [(set_attr "length" "2")])
5200 (define_insn "*negdi2_sp64"
5201 [(set (match_operand:DI 0 "register_operand" "=r")
5202 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5204 "sub\t%%g0, %1, %0")
5206 (define_insn "negsi2"
5207 [(set (match_operand:SI 0 "register_operand" "=r")
5208 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5210 "sub\t%%g0, %1, %0")
5212 (define_insn "*cmp_cc_neg"
5213 [(set (reg:CC_NOOV CC_REG)
5214 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5217 "subcc\t%%g0, %0, %%g0"
5218 [(set_attr "type" "compare")])
5220 (define_insn "*cmp_ccx_neg"
5221 [(set (reg:CCX_NOOV CC_REG)
5222 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5225 "subcc\t%%g0, %0, %%g0"
5226 [(set_attr "type" "compare")])
5228 (define_insn "*cmp_cc_set_neg"
5229 [(set (reg:CC_NOOV CC_REG)
5230 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5232 (set (match_operand:SI 0 "register_operand" "=r")
5233 (neg:SI (match_dup 1)))]
5235 "subcc\t%%g0, %1, %0"
5236 [(set_attr "type" "compare")])
5238 (define_insn "*cmp_ccx_set_neg"
5239 [(set (reg:CCX_NOOV CC_REG)
5240 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5242 (set (match_operand:DI 0 "register_operand" "=r")
5243 (neg:DI (match_dup 1)))]
5245 "subcc\t%%g0, %1, %0"
5246 [(set_attr "type" "compare")])
5248 ;; We cannot use the "not" pseudo insn because the Sun assembler
5249 ;; does not know how to make it work for constants.
5250 (define_expand "one_cmpl<V64I:mode>2"
5251 [(set (match_operand:V64I 0 "register_operand" "")
5252 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5256 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5257 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5258 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5263 "&& reload_completed
5264 && ((GET_CODE (operands[0]) == REG
5265 && REGNO (operands[0]) < 32)
5266 || (GET_CODE (operands[0]) == SUBREG
5267 && GET_CODE (SUBREG_REG (operands[0])) == REG
5268 && REGNO (SUBREG_REG (operands[0])) < 32))"
5269 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5270 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5271 "operands[2] = gen_highpart (SImode, operands[0]);
5272 operands[3] = gen_highpart (SImode, operands[1]);
5273 operands[4] = gen_lowpart (SImode, operands[0]);
5274 operands[5] = gen_lowpart (SImode, operands[1]);"
5275 [(set_attr "type" "*,fga")
5276 (set_attr "length" "2,*")
5277 (set_attr "fptype" "*,double")])
5279 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5280 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5281 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5286 [(set_attr "type" "*,fga")
5287 (set_attr "fptype" "*,double")])
5289 (define_insn "one_cmpl<V32I:mode>2"
5290 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5291 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5296 [(set_attr "type" "*,fga")
5297 (set_attr "fptype" "*,single")])
5299 (define_insn "*cmp_cc_not"
5300 [(set (reg:CC CC_REG)
5301 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5304 "xnorcc\t%%g0, %0, %%g0"
5305 [(set_attr "type" "compare")])
5307 (define_insn "*cmp_ccx_not"
5308 [(set (reg:CCX CC_REG)
5309 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5312 "xnorcc\t%%g0, %0, %%g0"
5313 [(set_attr "type" "compare")])
5315 (define_insn "*cmp_cc_set_not"
5316 [(set (reg:CC CC_REG)
5317 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5319 (set (match_operand:SI 0 "register_operand" "=r")
5320 (not:SI (match_dup 1)))]
5322 "xnorcc\t%%g0, %1, %0"
5323 [(set_attr "type" "compare")])
5325 (define_insn "*cmp_ccx_set_not"
5326 [(set (reg:CCX CC_REG)
5327 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5329 (set (match_operand:DI 0 "register_operand" "=r")
5330 (not:DI (match_dup 1)))]
5332 "xnorcc\t%%g0, %1, %0"
5333 [(set_attr "type" "compare")])
5335 (define_insn "*cmp_cc_set"
5336 [(set (match_operand:SI 0 "register_operand" "=r")
5337 (match_operand:SI 1 "register_operand" "r"))
5338 (set (reg:CC CC_REG)
5339 (compare:CC (match_dup 1)
5343 [(set_attr "type" "compare")])
5345 (define_insn "*cmp_ccx_set64"
5346 [(set (match_operand:DI 0 "register_operand" "=r")
5347 (match_operand:DI 1 "register_operand" "r"))
5348 (set (reg:CCX CC_REG)
5349 (compare:CCX (match_dup 1)
5353 [(set_attr "type" "compare")])
5356 ;; Floating point arithmetic instructions.
5358 (define_expand "addtf3"
5359 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5360 (plus:TF (match_operand:TF 1 "general_operand" "")
5361 (match_operand:TF 2 "general_operand" "")))]
5362 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5363 "emit_tfmode_binop (PLUS, operands); DONE;")
5365 (define_insn "*addtf3_hq"
5366 [(set (match_operand:TF 0 "register_operand" "=e")
5367 (plus:TF (match_operand:TF 1 "register_operand" "e")
5368 (match_operand:TF 2 "register_operand" "e")))]
5369 "TARGET_FPU && TARGET_HARD_QUAD"
5371 [(set_attr "type" "fp")])
5373 (define_insn "adddf3"
5374 [(set (match_operand:DF 0 "register_operand" "=e")
5375 (plus:DF (match_operand:DF 1 "register_operand" "e")
5376 (match_operand:DF 2 "register_operand" "e")))]
5379 [(set_attr "type" "fp")
5380 (set_attr "fptype" "double")])
5382 (define_insn "addsf3"
5383 [(set (match_operand:SF 0 "register_operand" "=f")
5384 (plus:SF (match_operand:SF 1 "register_operand" "f")
5385 (match_operand:SF 2 "register_operand" "f")))]
5388 [(set_attr "type" "fp")])
5390 (define_expand "subtf3"
5391 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5392 (minus:TF (match_operand:TF 1 "general_operand" "")
5393 (match_operand:TF 2 "general_operand" "")))]
5394 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5395 "emit_tfmode_binop (MINUS, operands); DONE;")
5397 (define_insn "*subtf3_hq"
5398 [(set (match_operand:TF 0 "register_operand" "=e")
5399 (minus:TF (match_operand:TF 1 "register_operand" "e")
5400 (match_operand:TF 2 "register_operand" "e")))]
5401 "TARGET_FPU && TARGET_HARD_QUAD"
5403 [(set_attr "type" "fp")])
5405 (define_insn "subdf3"
5406 [(set (match_operand:DF 0 "register_operand" "=e")
5407 (minus:DF (match_operand:DF 1 "register_operand" "e")
5408 (match_operand:DF 2 "register_operand" "e")))]
5411 [(set_attr "type" "fp")
5412 (set_attr "fptype" "double")])
5414 (define_insn "subsf3"
5415 [(set (match_operand:SF 0 "register_operand" "=f")
5416 (minus:SF (match_operand:SF 1 "register_operand" "f")
5417 (match_operand:SF 2 "register_operand" "f")))]
5420 [(set_attr "type" "fp")])
5422 (define_expand "multf3"
5423 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5424 (mult:TF (match_operand:TF 1 "general_operand" "")
5425 (match_operand:TF 2 "general_operand" "")))]
5426 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5427 "emit_tfmode_binop (MULT, operands); DONE;")
5429 (define_insn "*multf3_hq"
5430 [(set (match_operand:TF 0 "register_operand" "=e")
5431 (mult:TF (match_operand:TF 1 "register_operand" "e")
5432 (match_operand:TF 2 "register_operand" "e")))]
5433 "TARGET_FPU && TARGET_HARD_QUAD"
5435 [(set_attr "type" "fpmul")])
5437 (define_insn "muldf3"
5438 [(set (match_operand:DF 0 "register_operand" "=e")
5439 (mult:DF (match_operand:DF 1 "register_operand" "e")
5440 (match_operand:DF 2 "register_operand" "e")))]
5443 [(set_attr "type" "fpmul")
5444 (set_attr "fptype" "double")])
5446 (define_insn "mulsf3"
5447 [(set (match_operand:SF 0 "register_operand" "=f")
5448 (mult:SF (match_operand:SF 1 "register_operand" "f")
5449 (match_operand:SF 2 "register_operand" "f")))]
5452 [(set_attr "type" "fpmul")])
5454 (define_insn "fmadf4"
5455 [(set (match_operand:DF 0 "register_operand" "=e")
5456 (fma:DF (match_operand:DF 1 "register_operand" "e")
5457 (match_operand:DF 2 "register_operand" "e")
5458 (match_operand:DF 3 "register_operand" "e")))]
5460 "fmaddd\t%1, %2, %3, %0"
5461 [(set_attr "type" "fpmul")])
5463 (define_insn "fmsdf4"
5464 [(set (match_operand:DF 0 "register_operand" "=e")
5465 (fma:DF (match_operand:DF 1 "register_operand" "e")
5466 (match_operand:DF 2 "register_operand" "e")
5467 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5469 "fmsubd\t%1, %2, %3, %0"
5470 [(set_attr "type" "fpmul")])
5472 (define_insn "*nfmadf4"
5473 [(set (match_operand:DF 0 "register_operand" "=e")
5474 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5475 (match_operand:DF 2 "register_operand" "e")
5476 (match_operand:DF 3 "register_operand" "e"))))]
5478 "fnmaddd\t%1, %2, %3, %0"
5479 [(set_attr "type" "fpmul")])
5481 (define_insn "*nfmsdf4"
5482 [(set (match_operand:DF 0 "register_operand" "=e")
5483 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5484 (match_operand:DF 2 "register_operand" "e")
5485 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5487 "fnmsubd\t%1, %2, %3, %0"
5488 [(set_attr "type" "fpmul")])
5490 (define_insn "fmasf4"
5491 [(set (match_operand:SF 0 "register_operand" "=f")
5492 (fma:SF (match_operand:SF 1 "register_operand" "f")
5493 (match_operand:SF 2 "register_operand" "f")
5494 (match_operand:SF 3 "register_operand" "f")))]
5496 "fmadds\t%1, %2, %3, %0"
5497 [(set_attr "type" "fpmul")])
5499 (define_insn "fmssf4"
5500 [(set (match_operand:SF 0 "register_operand" "=f")
5501 (fma:SF (match_operand:SF 1 "register_operand" "f")
5502 (match_operand:SF 2 "register_operand" "f")
5503 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5505 "fmsubs\t%1, %2, %3, %0"
5506 [(set_attr "type" "fpmul")])
5508 (define_insn "*nfmasf4"
5509 [(set (match_operand:SF 0 "register_operand" "=f")
5510 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5511 (match_operand:SF 2 "register_operand" "f")
5512 (match_operand:SF 3 "register_operand" "f"))))]
5514 "fnmadds\t%1, %2, %3, %0"
5515 [(set_attr "type" "fpmul")])
5517 (define_insn "*nfmssf4"
5518 [(set (match_operand:SF 0 "register_operand" "=f")
5519 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5520 (match_operand:SF 2 "register_operand" "f")
5521 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5523 "fnmsubs\t%1, %2, %3, %0"
5524 [(set_attr "type" "fpmul")])
5526 (define_insn "*muldf3_extend"
5527 [(set (match_operand:DF 0 "register_operand" "=e")
5528 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5529 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5530 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5531 "fsmuld\t%1, %2, %0"
5532 [(set_attr "type" "fpmul")
5533 (set_attr "fptype" "double")])
5535 (define_insn "*multf3_extend"
5536 [(set (match_operand:TF 0 "register_operand" "=e")
5537 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5538 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5539 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5540 "fdmulq\t%1, %2, %0"
5541 [(set_attr "type" "fpmul")])
5543 (define_expand "divtf3"
5544 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5545 (div:TF (match_operand:TF 1 "general_operand" "")
5546 (match_operand:TF 2 "general_operand" "")))]
5547 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5548 "emit_tfmode_binop (DIV, operands); DONE;")
5550 ;; don't have timing for quad-prec. divide.
5551 (define_insn "*divtf3_hq"
5552 [(set (match_operand:TF 0 "register_operand" "=e")
5553 (div:TF (match_operand:TF 1 "register_operand" "e")
5554 (match_operand:TF 2 "register_operand" "e")))]
5555 "TARGET_FPU && TARGET_HARD_QUAD"
5557 [(set_attr "type" "fpdivd")])
5559 (define_insn "divdf3"
5560 [(set (match_operand:DF 0 "register_operand" "=e")
5561 (div:DF (match_operand:DF 1 "register_operand" "e")
5562 (match_operand:DF 2 "register_operand" "e")))]
5565 [(set_attr "type" "fpdivd")
5566 (set_attr "fptype" "double")])
5568 (define_insn "divsf3"
5569 [(set (match_operand:SF 0 "register_operand" "=f")
5570 (div:SF (match_operand:SF 1 "register_operand" "f")
5571 (match_operand:SF 2 "register_operand" "f")))]
5574 [(set_attr "type" "fpdivs")])
5576 (define_expand "negtf2"
5577 [(set (match_operand:TF 0 "register_operand" "=e,e")
5578 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5582 (define_insn_and_split "*negtf2_notv9"
5583 [(set (match_operand:TF 0 "register_operand" "=e,e")
5584 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5585 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5591 "&& reload_completed
5592 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5593 [(set (match_dup 2) (neg:SF (match_dup 3)))
5594 (set (match_dup 4) (match_dup 5))
5595 (set (match_dup 6) (match_dup 7))]
5596 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5597 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5598 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5599 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5600 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5601 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5602 [(set_attr "type" "fpmove,*")
5603 (set_attr "length" "*,2")])
5605 (define_insn_and_split "*negtf2_v9"
5606 [(set (match_operand:TF 0 "register_operand" "=e,e")
5607 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5608 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5609 "TARGET_FPU && TARGET_V9"
5613 "&& reload_completed
5614 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5615 [(set (match_dup 2) (neg:DF (match_dup 3)))
5616 (set (match_dup 4) (match_dup 5))]
5617 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5618 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5619 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5620 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5621 [(set_attr "type" "fpmove,*")
5622 (set_attr "length" "*,2")
5623 (set_attr "fptype" "double")])
5625 (define_expand "negdf2"
5626 [(set (match_operand:DF 0 "register_operand" "")
5627 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5631 (define_insn_and_split "*negdf2_notv9"
5632 [(set (match_operand:DF 0 "register_operand" "=e,e")
5633 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5634 "TARGET_FPU && ! TARGET_V9"
5638 "&& reload_completed
5639 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5640 [(set (match_dup 2) (neg:SF (match_dup 3)))
5641 (set (match_dup 4) (match_dup 5))]
5642 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5643 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5644 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5645 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5646 [(set_attr "type" "fpmove,*")
5647 (set_attr "length" "*,2")])
5649 (define_insn "*negdf2_v9"
5650 [(set (match_operand:DF 0 "register_operand" "=e")
5651 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5652 "TARGET_FPU && TARGET_V9"
5654 [(set_attr "type" "fpmove")
5655 (set_attr "fptype" "double")])
5657 (define_insn "negsf2"
5658 [(set (match_operand:SF 0 "register_operand" "=f")
5659 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5662 [(set_attr "type" "fpmove")])
5664 (define_expand "abstf2"
5665 [(set (match_operand:TF 0 "register_operand" "")
5666 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5670 (define_insn_and_split "*abstf2_notv9"
5671 [(set (match_operand:TF 0 "register_operand" "=e,e")
5672 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5673 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5674 "TARGET_FPU && ! TARGET_V9"
5678 "&& reload_completed
5679 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5680 [(set (match_dup 2) (abs:SF (match_dup 3)))
5681 (set (match_dup 4) (match_dup 5))
5682 (set (match_dup 6) (match_dup 7))]
5683 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5684 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5685 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5686 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5687 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5688 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5689 [(set_attr "type" "fpmove,*")
5690 (set_attr "length" "*,2")])
5692 (define_insn "*abstf2_hq_v9"
5693 [(set (match_operand:TF 0 "register_operand" "=e,e")
5694 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5695 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5699 [(set_attr "type" "fpmove")
5700 (set_attr "fptype" "double,*")])
5702 (define_insn_and_split "*abstf2_v9"
5703 [(set (match_operand:TF 0 "register_operand" "=e,e")
5704 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5705 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5709 "&& reload_completed
5710 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5711 [(set (match_dup 2) (abs:DF (match_dup 3)))
5712 (set (match_dup 4) (match_dup 5))]
5713 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5714 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5715 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5716 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5717 [(set_attr "type" "fpmove,*")
5718 (set_attr "length" "*,2")
5719 (set_attr "fptype" "double,*")])
5721 (define_expand "absdf2"
5722 [(set (match_operand:DF 0 "register_operand" "")
5723 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5727 (define_insn_and_split "*absdf2_notv9"
5728 [(set (match_operand:DF 0 "register_operand" "=e,e")
5729 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5730 "TARGET_FPU && ! TARGET_V9"
5734 "&& reload_completed
5735 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5736 [(set (match_dup 2) (abs:SF (match_dup 3)))
5737 (set (match_dup 4) (match_dup 5))]
5738 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5739 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5740 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5741 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5742 [(set_attr "type" "fpmove,*")
5743 (set_attr "length" "*,2")])
5745 (define_insn "*absdf2_v9"
5746 [(set (match_operand:DF 0 "register_operand" "=e")
5747 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5748 "TARGET_FPU && TARGET_V9"
5750 [(set_attr "type" "fpmove")
5751 (set_attr "fptype" "double")])
5753 (define_insn "abssf2"
5754 [(set (match_operand:SF 0 "register_operand" "=f")
5755 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5758 [(set_attr "type" "fpmove")])
5760 (define_expand "sqrttf2"
5761 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5762 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5763 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5764 "emit_tfmode_unop (SQRT, operands); DONE;")
5766 (define_insn "*sqrttf2_hq"
5767 [(set (match_operand:TF 0 "register_operand" "=e")
5768 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5769 "TARGET_FPU && TARGET_HARD_QUAD"
5771 [(set_attr "type" "fpsqrtd")])
5773 (define_insn "sqrtdf2"
5774 [(set (match_operand:DF 0 "register_operand" "=e")
5775 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5778 [(set_attr "type" "fpsqrtd")
5779 (set_attr "fptype" "double")])
5781 (define_insn "sqrtsf2"
5782 [(set (match_operand:SF 0 "register_operand" "=f")
5783 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5786 [(set_attr "type" "fpsqrts")])
5789 ;; Arithmetic shift instructions.
5791 (define_insn "ashlsi3"
5792 [(set (match_operand:SI 0 "register_operand" "=r")
5793 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5794 (match_operand:SI 2 "arith_operand" "rI")))]
5797 if (GET_CODE (operands[2]) == CONST_INT)
5798 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5799 return "sll\t%1, %2, %0";
5802 (if_then_else (match_operand 2 "const_one_operand" "")
5803 (const_string "ialu") (const_string "shift")))])
5805 (define_expand "ashldi3"
5806 [(set (match_operand:DI 0 "register_operand" "=r")
5807 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5808 (match_operand:SI 2 "arith_operand" "rI")))]
5809 "TARGET_ARCH64 || TARGET_V8PLUS"
5811 if (! TARGET_ARCH64)
5813 if (GET_CODE (operands[2]) == CONST_INT)
5815 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5820 (define_insn "*ashldi3_sp64"
5821 [(set (match_operand:DI 0 "register_operand" "=r")
5822 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5823 (match_operand:SI 2 "arith_operand" "rI")))]
5826 if (GET_CODE (operands[2]) == CONST_INT)
5827 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5828 return "sllx\t%1, %2, %0";
5831 (if_then_else (match_operand 2 "const_one_operand" "")
5832 (const_string "ialu") (const_string "shift")))])
5835 (define_insn "ashldi3_v8plus"
5836 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5837 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5838 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5839 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5841 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5842 [(set_attr "type" "multi")
5843 (set_attr "length" "5,5,6")])
5845 ;; Optimize (1LL<<x)-1
5846 ;; XXX this also needs to be fixed to handle equal subregs
5847 ;; XXX first before we could re-enable it.
5849 ; [(set (match_operand:DI 0 "register_operand" "=h")
5850 ; (plus:DI (ashift:DI (const_int 1)
5851 ; (match_operand:SI 1 "arith_operand" "rI"))
5853 ; "0 && TARGET_V8PLUS"
5855 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5856 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5857 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5859 ; [(set_attr "type" "multi")
5860 ; (set_attr "length" "4")])
5862 (define_insn "*cmp_cc_ashift_1"
5863 [(set (reg:CC_NOOV CC_REG)
5864 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5868 "addcc\t%0, %0, %%g0"
5869 [(set_attr "type" "compare")])
5871 (define_insn "*cmp_cc_set_ashift_1"
5872 [(set (reg:CC_NOOV CC_REG)
5873 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5876 (set (match_operand:SI 0 "register_operand" "=r")
5877 (ashift:SI (match_dup 1) (const_int 1)))]
5880 [(set_attr "type" "compare")])
5882 (define_insn "ashrsi3"
5883 [(set (match_operand:SI 0 "register_operand" "=r")
5884 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5885 (match_operand:SI 2 "arith_operand" "rI")))]
5888 if (GET_CODE (operands[2]) == CONST_INT)
5889 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5890 return "sra\t%1, %2, %0";
5892 [(set_attr "type" "shift")])
5894 (define_insn "*ashrsi3_extend"
5895 [(set (match_operand:DI 0 "register_operand" "=r")
5896 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5897 (match_operand:SI 2 "arith_operand" "r"))))]
5900 [(set_attr "type" "shift")])
5902 ;; This handles the case as above, but with constant shift instead of
5903 ;; register. Combiner "simplifies" it for us a little bit though.
5904 (define_insn "*ashrsi3_extend2"
5905 [(set (match_operand:DI 0 "register_operand" "=r")
5906 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5908 (match_operand:SI 2 "small_int_operand" "I")))]
5909 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5911 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5912 return "sra\t%1, %2, %0";
5914 [(set_attr "type" "shift")])
5916 (define_expand "ashrdi3"
5917 [(set (match_operand:DI 0 "register_operand" "=r")
5918 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5919 (match_operand:SI 2 "arith_operand" "rI")))]
5920 "TARGET_ARCH64 || TARGET_V8PLUS"
5922 if (! TARGET_ARCH64)
5924 if (GET_CODE (operands[2]) == CONST_INT)
5925 FAIL; /* prefer generic code in this case */
5926 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5931 (define_insn "*ashrdi3_sp64"
5932 [(set (match_operand:DI 0 "register_operand" "=r")
5933 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5934 (match_operand:SI 2 "arith_operand" "rI")))]
5938 if (GET_CODE (operands[2]) == CONST_INT)
5939 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5940 return "srax\t%1, %2, %0";
5942 [(set_attr "type" "shift")])
5945 (define_insn "ashrdi3_v8plus"
5946 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5947 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5948 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5949 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5951 "* return output_v8plus_shift (operands, insn, \"srax\");"
5952 [(set_attr "type" "multi")
5953 (set_attr "length" "5,5,6")])
5955 (define_insn "lshrsi3"
5956 [(set (match_operand:SI 0 "register_operand" "=r")
5957 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5958 (match_operand:SI 2 "arith_operand" "rI")))]
5961 if (GET_CODE (operands[2]) == CONST_INT)
5962 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5963 return "srl\t%1, %2, %0";
5965 [(set_attr "type" "shift")])
5967 ;; This handles the case where
5968 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5969 ;; but combiner "simplifies" it for us.
5970 (define_insn "*lshrsi3_extend"
5971 [(set (match_operand:DI 0 "register_operand" "=r")
5972 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5973 (match_operand:SI 2 "arith_operand" "r")) 0)
5974 (match_operand 3 "const_int_operand" "")))]
5975 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5977 [(set_attr "type" "shift")])
5979 ;; This handles the case where
5980 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5981 ;; but combiner "simplifies" it for us.
5982 (define_insn "*lshrsi3_extend2"
5983 [(set (match_operand:DI 0 "register_operand" "=r")
5984 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5985 (match_operand 2 "small_int_operand" "I")
5987 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5989 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5990 return "srl\t%1, %2, %0";
5992 [(set_attr "type" "shift")])
5994 (define_expand "lshrdi3"
5995 [(set (match_operand:DI 0 "register_operand" "=r")
5996 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5997 (match_operand:SI 2 "arith_operand" "rI")))]
5998 "TARGET_ARCH64 || TARGET_V8PLUS"
6000 if (! TARGET_ARCH64)
6002 if (GET_CODE (operands[2]) == CONST_INT)
6004 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6009 (define_insn "*lshrdi3_sp64"
6010 [(set (match_operand:DI 0 "register_operand" "=r")
6011 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6012 (match_operand:SI 2 "arith_operand" "rI")))]
6015 if (GET_CODE (operands[2]) == CONST_INT)
6016 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6017 return "srlx\t%1, %2, %0";
6019 [(set_attr "type" "shift")])
6022 (define_insn "lshrdi3_v8plus"
6023 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6024 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6025 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6026 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6028 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6029 [(set_attr "type" "multi")
6030 (set_attr "length" "5,5,6")])
6033 [(set (match_operand:SI 0 "register_operand" "=r")
6034 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6036 (match_operand:SI 2 "small_int_operand" "I")))]
6037 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6039 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6040 return "srax\t%1, %2, %0";
6042 [(set_attr "type" "shift")])
6045 [(set (match_operand:SI 0 "register_operand" "=r")
6046 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6048 (match_operand:SI 2 "small_int_operand" "I")))]
6049 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6051 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6052 return "srlx\t%1, %2, %0";
6054 [(set_attr "type" "shift")])
6057 [(set (match_operand:SI 0 "register_operand" "=r")
6058 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6059 (match_operand:SI 2 "small_int_operand" "I")) 4)
6060 (match_operand:SI 3 "small_int_operand" "I")))]
6062 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6063 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6064 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6066 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6068 return "srax\t%1, %2, %0";
6070 [(set_attr "type" "shift")])
6073 [(set (match_operand:SI 0 "register_operand" "=r")
6074 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6075 (match_operand:SI 2 "small_int_operand" "I")) 4)
6076 (match_operand:SI 3 "small_int_operand" "I")))]
6078 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6079 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6080 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6082 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6084 return "srlx\t%1, %2, %0";
6086 [(set_attr "type" "shift")])
6089 ;; Unconditional and other jump instructions.
6092 [(set (pc) (label_ref (match_operand 0 "" "")))]
6094 "* return output_ubranch (operands[0], 0, insn);"
6095 [(set_attr "type" "uncond_branch")])
6097 (define_expand "tablejump"
6098 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6099 (use (label_ref (match_operand 1 "" "")))])]
6102 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6104 /* In pic mode, our address differences are against the base of the
6105 table. Add that base value back in; CSE ought to be able to combine
6106 the two address loads. */
6110 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6112 if (CASE_VECTOR_MODE != Pmode)
6113 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6114 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6115 operands[0] = memory_address (Pmode, tmp);
6119 (define_insn "*tablejump_sp32"
6120 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6121 (use (label_ref (match_operand 1 "" "")))]
6124 [(set_attr "type" "uncond_branch")])
6126 (define_insn "*tablejump_sp64"
6127 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6128 (use (label_ref (match_operand 1 "" "")))]
6131 [(set_attr "type" "uncond_branch")])
6134 ;; Jump to subroutine instructions.
6136 (define_expand "call"
6137 ;; Note that this expression is not used for generating RTL.
6138 ;; All the RTL is generated explicitly below.
6139 [(call (match_operand 0 "call_operand" "")
6140 (match_operand 3 "" "i"))]
6141 ;; operands[2] is next_arg_register
6142 ;; operands[3] is struct_value_size_rtx.
6147 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6149 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6151 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6153 /* This is really a PIC sequence. We want to represent
6154 it as a funny jump so its delay slots can be filled.
6156 ??? But if this really *is* a CALL, will not it clobber the
6157 call-clobbered registers? We lose this if it is a JUMP_INSN.
6158 Why cannot we have delay slots filled if it were a CALL? */
6160 /* We accept negative sizes for untyped calls. */
6161 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6166 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6168 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6174 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6175 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6179 fn_rtx = operands[0];
6181 /* We accept negative sizes for untyped calls. */
6182 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6183 sparc_emit_call_insn
6186 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6188 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6191 sparc_emit_call_insn
6194 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6195 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6203 ;; We can't use the same pattern for these two insns, because then registers
6204 ;; in the address may not be properly reloaded.
6206 (define_insn "*call_address_sp32"
6207 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6208 (match_operand 1 "" ""))
6209 (clobber (reg:SI O7_REG))]
6210 ;;- Do not use operand 1 for most machines.
6213 [(set_attr "type" "call")])
6215 (define_insn "*call_symbolic_sp32"
6216 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6217 (match_operand 1 "" ""))
6218 (clobber (reg:SI O7_REG))]
6219 ;;- Do not use operand 1 for most machines.
6222 [(set_attr "type" "call")])
6224 (define_insn "*call_address_sp64"
6225 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6226 (match_operand 1 "" ""))
6227 (clobber (reg:DI O7_REG))]
6228 ;;- Do not use operand 1 for most machines.
6231 [(set_attr "type" "call")])
6233 (define_insn "*call_symbolic_sp64"
6234 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6235 (match_operand 1 "" ""))
6236 (clobber (reg:DI O7_REG))]
6237 ;;- Do not use operand 1 for most machines.
6240 [(set_attr "type" "call")])
6242 ;; This is a call that wants a structure value.
6243 ;; There is no such critter for v9 (??? we may need one anyway).
6244 (define_insn "*call_address_struct_value_sp32"
6245 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6246 (match_operand 1 "" ""))
6247 (match_operand 2 "immediate_operand" "")
6248 (clobber (reg:SI O7_REG))]
6249 ;;- Do not use operand 1 for most machines.
6250 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6252 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6253 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6255 [(set_attr "type" "call_no_delay_slot")
6256 (set_attr "length" "3")])
6258 ;; This is a call that wants a structure value.
6259 ;; There is no such critter for v9 (??? we may need one anyway).
6260 (define_insn "*call_symbolic_struct_value_sp32"
6261 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6262 (match_operand 1 "" ""))
6263 (match_operand 2 "immediate_operand" "")
6264 (clobber (reg:SI O7_REG))]
6265 ;;- Do not use operand 1 for most machines.
6266 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6268 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6269 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6271 [(set_attr "type" "call_no_delay_slot")
6272 (set_attr "length" "3")])
6274 ;; This is a call that may want a structure value. This is used for
6276 (define_insn "*call_address_untyped_struct_value_sp32"
6277 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6278 (match_operand 1 "" ""))
6279 (match_operand 2 "immediate_operand" "")
6280 (clobber (reg:SI O7_REG))]
6281 ;;- Do not use operand 1 for most machines.
6282 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6283 "call\t%a0, %1\n\t nop\n\tnop"
6284 [(set_attr "type" "call_no_delay_slot")
6285 (set_attr "length" "3")])
6287 ;; This is a call that may want a structure value. This is used for
6289 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6290 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6291 (match_operand 1 "" ""))
6292 (match_operand 2 "immediate_operand" "")
6293 (clobber (reg:SI O7_REG))]
6294 ;;- Do not use operand 1 for most machines.
6295 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6296 "call\t%a0, %1\n\t nop\n\tnop"
6297 [(set_attr "type" "call_no_delay_slot")
6298 (set_attr "length" "3")])
6300 (define_expand "call_value"
6301 ;; Note that this expression is not used for generating RTL.
6302 ;; All the RTL is generated explicitly below.
6303 [(set (match_operand 0 "register_operand" "=rf")
6304 (call (match_operand 1 "" "")
6305 (match_operand 4 "" "")))]
6306 ;; operand 2 is stack_size_rtx
6307 ;; operand 3 is next_arg_register
6313 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6315 fn_rtx = operands[1];
6318 gen_rtx_SET (VOIDmode, operands[0],
6319 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6320 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6322 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6327 (define_insn "*call_value_address_sp32"
6328 [(set (match_operand 0 "" "=rf")
6329 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6330 (match_operand 2 "" "")))
6331 (clobber (reg:SI O7_REG))]
6332 ;;- Do not use operand 2 for most machines.
6335 [(set_attr "type" "call")])
6337 (define_insn "*call_value_symbolic_sp32"
6338 [(set (match_operand 0 "" "=rf")
6339 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6340 (match_operand 2 "" "")))
6341 (clobber (reg:SI O7_REG))]
6342 ;;- Do not use operand 2 for most machines.
6345 [(set_attr "type" "call")])
6347 (define_insn "*call_value_address_sp64"
6348 [(set (match_operand 0 "" "")
6349 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6350 (match_operand 2 "" "")))
6351 (clobber (reg:DI O7_REG))]
6352 ;;- Do not use operand 2 for most machines.
6355 [(set_attr "type" "call")])
6357 (define_insn "*call_value_symbolic_sp64"
6358 [(set (match_operand 0 "" "")
6359 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6360 (match_operand 2 "" "")))
6361 (clobber (reg:DI O7_REG))]
6362 ;;- Do not use operand 2 for most machines.
6365 [(set_attr "type" "call")])
6367 (define_expand "untyped_call"
6368 [(parallel [(call (match_operand 0 "" "")
6370 (match_operand:BLK 1 "memory_operand" "")
6371 (match_operand 2 "" "")])]
6374 rtx valreg1 = gen_rtx_REG (DImode, 8);
6375 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6376 rtx result = operands[1];
6378 /* Pass constm1 to indicate that it may expect a structure value, but
6379 we don't know what size it is. */
6380 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6382 /* Save the function value registers. */
6383 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6384 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6387 /* The optimizer does not know that the call sets the function value
6388 registers we stored in the result block. We avoid problems by
6389 claiming that all hard registers are used and clobbered at this
6391 emit_insn (gen_blockage ());
6396 ;; Tail call instructions.
6398 (define_expand "sibcall"
6399 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6404 (define_insn "*sibcall_symbolic_sp32"
6405 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6406 (match_operand 1 "" ""))
6409 "* return output_sibcall(insn, operands[0]);"
6410 [(set_attr "type" "sibcall")])
6412 (define_insn "*sibcall_symbolic_sp64"
6413 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6414 (match_operand 1 "" ""))
6417 "* return output_sibcall(insn, operands[0]);"
6418 [(set_attr "type" "sibcall")])
6420 (define_expand "sibcall_value"
6421 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6422 (call (match_operand 1 "" "") (const_int 0)))
6427 (define_insn "*sibcall_value_symbolic_sp32"
6428 [(set (match_operand 0 "" "=rf")
6429 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6430 (match_operand 2 "" "")))
6433 "* return output_sibcall(insn, operands[1]);"
6434 [(set_attr "type" "sibcall")])
6436 (define_insn "*sibcall_value_symbolic_sp64"
6437 [(set (match_operand 0 "" "")
6438 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6439 (match_operand 2 "" "")))
6442 "* return output_sibcall(insn, operands[1]);"
6443 [(set_attr "type" "sibcall")])
6446 ;; Special instructions.
6448 (define_expand "prologue"
6453 sparc_flat_expand_prologue ();
6455 sparc_expand_prologue ();
6459 ;; The "register window save" insn is modelled as follows. The dwarf2
6460 ;; information is manually added in emit_window_save.
6462 (define_insn "window_save"
6464 [(match_operand 0 "arith_operand" "rI")]
6467 "save\t%%sp, %0, %%sp"
6468 [(set_attr "type" "savew")])
6470 (define_expand "epilogue"
6475 sparc_flat_expand_epilogue (false);
6477 sparc_expand_epilogue (false);
6480 (define_expand "sibcall_epilogue"
6485 sparc_flat_expand_epilogue (false);
6487 sparc_expand_epilogue (false);
6491 (define_expand "eh_return"
6492 [(use (match_operand 0 "general_operand" ""))]
6495 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6496 emit_jump_insn (gen_eh_return_internal ());
6501 (define_insn_and_split "eh_return_internal"
6505 "epilogue_completed"
6509 sparc_flat_expand_epilogue (true);
6511 sparc_expand_epilogue (true);
6514 (define_expand "return"
6516 "sparc_can_use_return_insn_p ()"
6519 (define_insn "*return_internal"
6522 "* return output_return (insn);"
6523 [(set_attr "type" "return")
6524 (set (attr "length")
6525 (cond [(eq_attr "calls_eh_return" "true")
6526 (if_then_else (eq_attr "delayed_branch" "true")
6527 (if_then_else (ior (eq_attr "isa" "v9")
6528 (eq_attr "flat" "true"))
6531 (if_then_else (eq_attr "flat" "true")
6534 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6535 (if_then_else (eq_attr "empty_delay_slot" "true")
6538 (eq_attr "empty_delay_slot" "true")
6539 (if_then_else (eq_attr "delayed_branch" "true")
6544 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6545 ;; all of memory. This blocks insns from being moved across this point.
6547 (define_insn "blockage"
6548 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6551 [(set_attr "length" "0")])
6553 (define_expand "probe_stack"
6554 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6558 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6561 (define_insn "probe_stack_range<P:mode>"
6562 [(set (match_operand:P 0 "register_operand" "=r")
6563 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6564 (match_operand:P 2 "register_operand" "r")]
6565 UNSPECV_PROBE_STACK_RANGE))]
6567 "* return output_probe_stack_range (operands[0], operands[2]);"
6568 [(set_attr "type" "multi")])
6570 ;; Prepare to return any type including a structure value.
6572 (define_expand "untyped_return"
6573 [(match_operand:BLK 0 "memory_operand" "")
6574 (match_operand 1 "" "")]
6577 rtx valreg1 = gen_rtx_REG (DImode, 24);
6578 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6579 rtx result = operands[0];
6581 if (! TARGET_ARCH64)
6583 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6584 rtx value = gen_reg_rtx (SImode);
6586 /* Fetch the instruction where we will return to and see if it's an unimp
6587 instruction (the most significant 10 bits will be zero). If so,
6588 update the return address to skip the unimp instruction. */
6589 emit_move_insn (value,
6590 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6591 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6592 emit_insn (gen_update_return (rtnreg, value));
6595 /* Reload the function value registers. */
6596 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6597 emit_move_insn (valreg2,
6598 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6600 /* Put USE insns before the return. */
6604 /* Construct the return. */
6605 expand_naked_return ();
6610 ;; Adjust the return address conditionally. If the value of op1 is equal
6611 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6612 ;; This is technically *half* the check required by the 32-bit SPARC
6613 ;; psABI. This check only ensures that an "unimp" insn was written by
6614 ;; the caller, but doesn't check to see if the expected size matches
6615 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6616 ;; only used by the above code "untyped_return".
6618 (define_insn "update_return"
6619 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6620 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6623 if (flag_delayed_branch)
6624 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6626 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6628 [(set (attr "type") (const_string "multi"))
6629 (set (attr "length")
6630 (if_then_else (eq_attr "delayed_branch" "true")
6639 (define_expand "indirect_jump"
6640 [(set (pc) (match_operand 0 "address_operand" "p"))]
6644 (define_insn "*branch_sp32"
6645 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6648 [(set_attr "type" "uncond_branch")])
6650 (define_insn "*branch_sp64"
6651 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6654 [(set_attr "type" "uncond_branch")])
6656 (define_expand "save_stack_nonlocal"
6657 [(set (match_operand 0 "memory_operand" "")
6658 (match_operand 1 "register_operand" ""))
6659 (set (match_dup 2) (match_dup 3))]
6662 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6663 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6664 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6667 (define_expand "restore_stack_nonlocal"
6668 [(set (match_operand 0 "register_operand" "")
6669 (match_operand 1 "memory_operand" ""))]
6672 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6675 (define_expand "nonlocal_goto"
6676 [(match_operand 0 "general_operand" "")
6677 (match_operand 1 "general_operand" "")
6678 (match_operand 2 "memory_operand" "")
6679 (match_operand 3 "memory_operand" "")]
6682 rtx r_label = copy_to_reg (operands[1]);
6683 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6684 rtx r_fp = operands[3];
6685 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6687 /* We need to flush all the register windows so that their contents will
6688 be re-synchronized by the restore insn of the target function. */
6690 emit_insn (gen_flush_register_windows ());
6692 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6693 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6695 /* Restore frame pointer for containing function. */
6696 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6697 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6699 /* USE of hard_frame_pointer_rtx added for consistency;
6700 not clear if really needed. */
6701 emit_use (hard_frame_pointer_rtx);
6702 emit_use (stack_pointer_rtx);
6704 /* We need to smuggle the load of %i7 as it is a fixed register. */
6705 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6710 (define_insn "nonlocal_goto_internal"
6711 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6712 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6713 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6715 if (flag_delayed_branch)
6718 return "jmp\t%0\n\t ldx\t%1, %%i7";
6720 return "jmp\t%0\n\t ld\t%1, %%i7";
6725 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6727 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6730 [(set (attr "type") (const_string "multi"))
6731 (set (attr "length")
6732 (if_then_else (eq_attr "delayed_branch" "true")
6736 (define_expand "builtin_setjmp_receiver"
6737 [(label_ref (match_operand 0 "" ""))]
6740 load_got_register ();
6744 ;; Special insn to flush register windows.
6746 (define_insn "flush_register_windows"
6747 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6749 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6750 [(set_attr "type" "flushw")])
6752 ;; Special pattern for the FLUSH instruction.
6754 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6755 ; of the define_insn otherwise missing a mode. We make "flush", aka
6756 ; gen_flush, the default one since sparc_initialize_trampoline uses
6757 ; it on SImode mem values.
6759 (define_insn "flush"
6760 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6762 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6763 [(set_attr "type" "iflush")])
6765 (define_insn "flushdi"
6766 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6768 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6769 [(set_attr "type" "iflush")])
6772 ;; Find first set instructions.
6774 ;; The scan instruction searches from the most significant bit while ffs
6775 ;; searches from the least significant bit. The bit index and treatment of
6776 ;; zero also differ. It takes at least 7 instructions to get the proper
6777 ;; result. Here is an obvious 8 instruction sequence.
6780 (define_insn "ffssi2"
6781 [(set (match_operand:SI 0 "register_operand" "=&r")
6782 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6783 (clobber (match_scratch:SI 2 "=&r"))]
6784 "TARGET_SPARCLITE || TARGET_SPARCLET"
6786 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";
6788 [(set_attr "type" "multi")
6789 (set_attr "length" "8")])
6791 ;; ??? This should be a define expand, so that the extra instruction have
6792 ;; a chance of being optimized away.
6794 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6795 ;; does, but no one uses that and we don't have a switch for it.
6797 ;(define_insn "ffsdi2"
6798 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6799 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6800 ; (clobber (match_scratch:DI 2 "=&r"))]
6802 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6803 ; [(set_attr "type" "multi")
6804 ; (set_attr "length" "4")])
6808 ;; Peepholes go at the end.
6810 ;; Optimize consecutive loads or stores into ldd and std when possible.
6811 ;; The conditions in which we do this are very restricted and are
6812 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6815 [(set (match_operand:SI 0 "memory_operand" "")
6817 (set (match_operand:SI 1 "memory_operand" "")
6820 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6823 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6826 [(set (match_operand:SI 0 "memory_operand" "")
6828 (set (match_operand:SI 1 "memory_operand" "")
6831 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6834 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6837 [(set (match_operand:SI 0 "register_operand" "")
6838 (match_operand:SI 1 "memory_operand" ""))
6839 (set (match_operand:SI 2 "register_operand" "")
6840 (match_operand:SI 3 "memory_operand" ""))]
6841 "registers_ok_for_ldd_peep (operands[0], operands[2])
6842 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6845 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6846 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6849 [(set (match_operand:SI 0 "memory_operand" "")
6850 (match_operand:SI 1 "register_operand" ""))
6851 (set (match_operand:SI 2 "memory_operand" "")
6852 (match_operand:SI 3 "register_operand" ""))]
6853 "registers_ok_for_ldd_peep (operands[1], operands[3])
6854 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6857 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6858 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6861 [(set (match_operand:SF 0 "register_operand" "")
6862 (match_operand:SF 1 "memory_operand" ""))
6863 (set (match_operand:SF 2 "register_operand" "")
6864 (match_operand:SF 3 "memory_operand" ""))]
6865 "registers_ok_for_ldd_peep (operands[0], operands[2])
6866 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6869 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6870 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6873 [(set (match_operand:SF 0 "memory_operand" "")
6874 (match_operand:SF 1 "register_operand" ""))
6875 (set (match_operand:SF 2 "memory_operand" "")
6876 (match_operand:SF 3 "register_operand" ""))]
6877 "registers_ok_for_ldd_peep (operands[1], operands[3])
6878 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6881 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6882 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6885 [(set (match_operand:SI 0 "register_operand" "")
6886 (match_operand:SI 1 "memory_operand" ""))
6887 (set (match_operand:SI 2 "register_operand" "")
6888 (match_operand:SI 3 "memory_operand" ""))]
6889 "registers_ok_for_ldd_peep (operands[2], operands[0])
6890 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6893 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6894 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6897 [(set (match_operand:SI 0 "memory_operand" "")
6898 (match_operand:SI 1 "register_operand" ""))
6899 (set (match_operand:SI 2 "memory_operand" "")
6900 (match_operand:SI 3 "register_operand" ""))]
6901 "registers_ok_for_ldd_peep (operands[3], operands[1])
6902 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6905 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6906 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6910 [(set (match_operand:SF 0 "register_operand" "")
6911 (match_operand:SF 1 "memory_operand" ""))
6912 (set (match_operand:SF 2 "register_operand" "")
6913 (match_operand:SF 3 "memory_operand" ""))]
6914 "registers_ok_for_ldd_peep (operands[2], operands[0])
6915 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6918 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6919 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6922 [(set (match_operand:SF 0 "memory_operand" "")
6923 (match_operand:SF 1 "register_operand" ""))
6924 (set (match_operand:SF 2 "memory_operand" "")
6925 (match_operand:SF 3 "register_operand" ""))]
6926 "registers_ok_for_ldd_peep (operands[3], operands[1])
6927 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6930 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6931 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6933 ;; Optimize the case of following a reg-reg move with a test
6934 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6935 ;; This can result from a float to fix conversion.
6938 [(set (match_operand:SI 0 "register_operand" "")
6939 (match_operand:SI 1 "register_operand" ""))
6940 (set (reg:CC CC_REG)
6941 (compare:CC (match_operand:SI 2 "register_operand" "")
6943 "(rtx_equal_p (operands[2], operands[0])
6944 || rtx_equal_p (operands[2], operands[1]))
6945 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6946 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6947 [(parallel [(set (match_dup 0) (match_dup 1))
6948 (set (reg:CC CC_REG)
6949 (compare:CC (match_dup 1) (const_int 0)))])]
6953 [(set (match_operand:DI 0 "register_operand" "")
6954 (match_operand:DI 1 "register_operand" ""))
6955 (set (reg:CCX CC_REG)
6956 (compare:CCX (match_operand:DI 2 "register_operand" "")
6959 && (rtx_equal_p (operands[2], operands[0])
6960 || rtx_equal_p (operands[2], operands[1]))
6961 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6962 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6963 [(parallel [(set (match_dup 0) (match_dup 1))
6964 (set (reg:CCX CC_REG)
6965 (compare:CCX (match_dup 1) (const_int 0)))])]
6969 ;; Prefetch instructions.
6971 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6972 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6973 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6975 (define_expand "prefetch"
6976 [(match_operand 0 "address_operand" "")
6977 (match_operand 1 "const_int_operand" "")
6978 (match_operand 2 "const_int_operand" "")]
6982 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6984 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6988 (define_insn "prefetch_64"
6989 [(prefetch (match_operand:DI 0 "address_operand" "p")
6990 (match_operand:DI 1 "const_int_operand" "n")
6991 (match_operand:DI 2 "const_int_operand" "n"))]
6994 static const char * const prefetch_instr[2][2] = {
6996 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6997 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7000 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7001 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7004 int read_or_write = INTVAL (operands[1]);
7005 int locality = INTVAL (operands[2]);
7007 gcc_assert (read_or_write == 0 || read_or_write == 1);
7008 gcc_assert (locality >= 0 && locality < 4);
7009 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7011 [(set_attr "type" "load")])
7013 (define_insn "prefetch_32"
7014 [(prefetch (match_operand:SI 0 "address_operand" "p")
7015 (match_operand:SI 1 "const_int_operand" "n")
7016 (match_operand:SI 2 "const_int_operand" "n"))]
7019 static const char * const prefetch_instr[2][2] = {
7021 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7022 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7025 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7026 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7029 int read_or_write = INTVAL (operands[1]);
7030 int locality = INTVAL (operands[2]);
7032 gcc_assert (read_or_write == 0 || read_or_write == 1);
7033 gcc_assert (locality >= 0 && locality < 4);
7034 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7036 [(set_attr "type" "load")])
7039 ;; Trap instructions.
7042 [(trap_if (const_int 1) (const_int 5))]
7045 [(set_attr "type" "trap")])
7047 (define_expand "ctrapsi4"
7048 [(trap_if (match_operator 0 "noov_compare_operator"
7049 [(match_operand:SI 1 "compare_operand" "")
7050 (match_operand:SI 2 "arith_operand" "")])
7051 (match_operand 3 ""))]
7053 "operands[1] = gen_compare_reg (operands[0]);
7054 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7056 operands[2] = const0_rtx;")
7058 (define_expand "ctrapdi4"
7059 [(trap_if (match_operator 0 "noov_compare_operator"
7060 [(match_operand:DI 1 "compare_operand" "")
7061 (match_operand:DI 2 "arith_operand" "")])
7062 (match_operand 3 ""))]
7064 "operands[1] = gen_compare_reg (operands[0]);
7065 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7067 operands[2] = const0_rtx;")
7071 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7072 (match_operand:SI 1 "arith_operand" "rM"))]
7076 return "t%C0\t%%icc, %1";
7080 [(set_attr "type" "trap")])
7083 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7084 (match_operand:SI 1 "arith_operand" "rM"))]
7087 [(set_attr "type" "trap")])
7090 ;; TLS support instructions.
7092 (define_insn "tgd_hi22"
7093 [(set (match_operand:SI 0 "register_operand" "=r")
7094 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7097 "sethi\\t%%tgd_hi22(%a1), %0")
7099 (define_insn "tgd_lo10"
7100 [(set (match_operand:SI 0 "register_operand" "=r")
7101 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7102 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7105 "add\\t%1, %%tgd_lo10(%a2), %0")
7107 (define_insn "tgd_add32"
7108 [(set (match_operand:SI 0 "register_operand" "=r")
7109 (plus:SI (match_operand:SI 1 "register_operand" "r")
7110 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7111 (match_operand 3 "tgd_symbolic_operand" "")]
7113 "TARGET_TLS && TARGET_ARCH32"
7114 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7116 (define_insn "tgd_add64"
7117 [(set (match_operand:DI 0 "register_operand" "=r")
7118 (plus:DI (match_operand:DI 1 "register_operand" "r")
7119 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7120 (match_operand 3 "tgd_symbolic_operand" "")]
7122 "TARGET_TLS && TARGET_ARCH64"
7123 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7125 (define_insn "tgd_call32"
7126 [(set (match_operand 0 "register_operand" "=r")
7127 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7128 (match_operand 2 "tgd_symbolic_operand" "")]
7130 (match_operand 3 "" "")))
7131 (clobber (reg:SI O7_REG))]
7132 "TARGET_TLS && TARGET_ARCH32"
7133 "call\t%a1, %%tgd_call(%a2)%#"
7134 [(set_attr "type" "call")])
7136 (define_insn "tgd_call64"
7137 [(set (match_operand 0 "register_operand" "=r")
7138 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7139 (match_operand 2 "tgd_symbolic_operand" "")]
7141 (match_operand 3 "" "")))
7142 (clobber (reg:DI O7_REG))]
7143 "TARGET_TLS && TARGET_ARCH64"
7144 "call\t%a1, %%tgd_call(%a2)%#"
7145 [(set_attr "type" "call")])
7147 (define_insn "tldm_hi22"
7148 [(set (match_operand:SI 0 "register_operand" "=r")
7149 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7151 "sethi\\t%%tldm_hi22(%&), %0")
7153 (define_insn "tldm_lo10"
7154 [(set (match_operand:SI 0 "register_operand" "=r")
7155 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7156 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7158 "add\\t%1, %%tldm_lo10(%&), %0")
7160 (define_insn "tldm_add32"
7161 [(set (match_operand:SI 0 "register_operand" "=r")
7162 (plus:SI (match_operand:SI 1 "register_operand" "r")
7163 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7165 "TARGET_TLS && TARGET_ARCH32"
7166 "add\\t%1, %2, %0, %%tldm_add(%&)")
7168 (define_insn "tldm_add64"
7169 [(set (match_operand:DI 0 "register_operand" "=r")
7170 (plus:DI (match_operand:DI 1 "register_operand" "r")
7171 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7173 "TARGET_TLS && TARGET_ARCH64"
7174 "add\\t%1, %2, %0, %%tldm_add(%&)")
7176 (define_insn "tldm_call32"
7177 [(set (match_operand 0 "register_operand" "=r")
7178 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7180 (match_operand 2 "" "")))
7181 (clobber (reg:SI O7_REG))]
7182 "TARGET_TLS && TARGET_ARCH32"
7183 "call\t%a1, %%tldm_call(%&)%#"
7184 [(set_attr "type" "call")])
7186 (define_insn "tldm_call64"
7187 [(set (match_operand 0 "register_operand" "=r")
7188 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7190 (match_operand 2 "" "")))
7191 (clobber (reg:DI O7_REG))]
7192 "TARGET_TLS && TARGET_ARCH64"
7193 "call\t%a1, %%tldm_call(%&)%#"
7194 [(set_attr "type" "call")])
7196 (define_insn "tldo_hix22"
7197 [(set (match_operand:SI 0 "register_operand" "=r")
7198 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7201 "sethi\\t%%tldo_hix22(%a1), %0")
7203 (define_insn "tldo_lox10"
7204 [(set (match_operand:SI 0 "register_operand" "=r")
7205 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7206 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7209 "xor\\t%1, %%tldo_lox10(%a2), %0")
7211 (define_insn "tldo_add32"
7212 [(set (match_operand:SI 0 "register_operand" "=r")
7213 (plus:SI (match_operand:SI 1 "register_operand" "r")
7214 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7215 (match_operand 3 "tld_symbolic_operand" "")]
7217 "TARGET_TLS && TARGET_ARCH32"
7218 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7220 (define_insn "tldo_add64"
7221 [(set (match_operand:DI 0 "register_operand" "=r")
7222 (plus:DI (match_operand:DI 1 "register_operand" "r")
7223 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7224 (match_operand 3 "tld_symbolic_operand" "")]
7226 "TARGET_TLS && TARGET_ARCH64"
7227 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7229 (define_insn "tie_hi22"
7230 [(set (match_operand:SI 0 "register_operand" "=r")
7231 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7234 "sethi\\t%%tie_hi22(%a1), %0")
7236 (define_insn "tie_lo10"
7237 [(set (match_operand:SI 0 "register_operand" "=r")
7238 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7239 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7242 "add\\t%1, %%tie_lo10(%a2), %0")
7244 (define_insn "tie_ld32"
7245 [(set (match_operand:SI 0 "register_operand" "=r")
7246 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7247 (match_operand:SI 2 "register_operand" "r")
7248 (match_operand 3 "tie_symbolic_operand" "")]
7250 "TARGET_TLS && TARGET_ARCH32"
7251 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7252 [(set_attr "type" "load")])
7254 (define_insn "tie_ld64"
7255 [(set (match_operand:DI 0 "register_operand" "=r")
7256 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7257 (match_operand:SI 2 "register_operand" "r")
7258 (match_operand 3 "tie_symbolic_operand" "")]
7260 "TARGET_TLS && TARGET_ARCH64"
7261 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7262 [(set_attr "type" "load")])
7264 (define_insn "tie_add32"
7265 [(set (match_operand:SI 0 "register_operand" "=r")
7266 (plus:SI (match_operand:SI 1 "register_operand" "r")
7267 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7268 (match_operand 3 "tie_symbolic_operand" "")]
7270 "TARGET_SUN_TLS && TARGET_ARCH32"
7271 "add\\t%1, %2, %0, %%tie_add(%a3)")
7273 (define_insn "tie_add64"
7274 [(set (match_operand:DI 0 "register_operand" "=r")
7275 (plus:DI (match_operand:DI 1 "register_operand" "r")
7276 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7277 (match_operand 3 "tie_symbolic_operand" "")]
7279 "TARGET_SUN_TLS && TARGET_ARCH64"
7280 "add\\t%1, %2, %0, %%tie_add(%a3)")
7282 (define_insn "tle_hix22_sp32"
7283 [(set (match_operand:SI 0 "register_operand" "=r")
7284 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7286 "TARGET_TLS && TARGET_ARCH32"
7287 "sethi\\t%%tle_hix22(%a1), %0")
7289 (define_insn "tle_lox10_sp32"
7290 [(set (match_operand:SI 0 "register_operand" "=r")
7291 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7292 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7294 "TARGET_TLS && TARGET_ARCH32"
7295 "xor\\t%1, %%tle_lox10(%a2), %0")
7297 (define_insn "tle_hix22_sp64"
7298 [(set (match_operand:DI 0 "register_operand" "=r")
7299 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7301 "TARGET_TLS && TARGET_ARCH64"
7302 "sethi\\t%%tle_hix22(%a1), %0")
7304 (define_insn "tle_lox10_sp64"
7305 [(set (match_operand:DI 0 "register_operand" "=r")
7306 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7307 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7309 "TARGET_TLS && TARGET_ARCH64"
7310 "xor\\t%1, %%tle_lox10(%a2), %0")
7312 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7313 (define_insn "*tldo_ldub_sp32"
7314 [(set (match_operand:QI 0 "register_operand" "=r")
7315 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7316 (match_operand 3 "tld_symbolic_operand" "")]
7318 (match_operand:SI 1 "register_operand" "r"))))]
7319 "TARGET_TLS && TARGET_ARCH32"
7320 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7321 [(set_attr "type" "load")
7322 (set_attr "us3load_type" "3cycle")])
7324 (define_insn "*tldo_ldub1_sp32"
7325 [(set (match_operand:HI 0 "register_operand" "=r")
7326 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7327 (match_operand 3 "tld_symbolic_operand" "")]
7329 (match_operand:SI 1 "register_operand" "r")))))]
7330 "TARGET_TLS && TARGET_ARCH32"
7331 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7332 [(set_attr "type" "load")
7333 (set_attr "us3load_type" "3cycle")])
7335 (define_insn "*tldo_ldub2_sp32"
7336 [(set (match_operand:SI 0 "register_operand" "=r")
7337 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7338 (match_operand 3 "tld_symbolic_operand" "")]
7340 (match_operand:SI 1 "register_operand" "r")))))]
7341 "TARGET_TLS && TARGET_ARCH32"
7342 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7343 [(set_attr "type" "load")
7344 (set_attr "us3load_type" "3cycle")])
7346 (define_insn "*tldo_ldsb1_sp32"
7347 [(set (match_operand:HI 0 "register_operand" "=r")
7348 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7349 (match_operand 3 "tld_symbolic_operand" "")]
7351 (match_operand:SI 1 "register_operand" "r")))))]
7352 "TARGET_TLS && TARGET_ARCH32"
7353 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7354 [(set_attr "type" "sload")
7355 (set_attr "us3load_type" "3cycle")])
7357 (define_insn "*tldo_ldsb2_sp32"
7358 [(set (match_operand:SI 0 "register_operand" "=r")
7359 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7360 (match_operand 3 "tld_symbolic_operand" "")]
7362 (match_operand:SI 1 "register_operand" "r")))))]
7363 "TARGET_TLS && TARGET_ARCH32"
7364 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7365 [(set_attr "type" "sload")
7366 (set_attr "us3load_type" "3cycle")])
7368 (define_insn "*tldo_ldub_sp64"
7369 [(set (match_operand:QI 0 "register_operand" "=r")
7370 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7371 (match_operand 3 "tld_symbolic_operand" "")]
7373 (match_operand:DI 1 "register_operand" "r"))))]
7374 "TARGET_TLS && TARGET_ARCH64"
7375 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7376 [(set_attr "type" "load")
7377 (set_attr "us3load_type" "3cycle")])
7379 (define_insn "*tldo_ldub1_sp64"
7380 [(set (match_operand:HI 0 "register_operand" "=r")
7381 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7382 (match_operand 3 "tld_symbolic_operand" "")]
7384 (match_operand:DI 1 "register_operand" "r")))))]
7385 "TARGET_TLS && TARGET_ARCH64"
7386 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7387 [(set_attr "type" "load")
7388 (set_attr "us3load_type" "3cycle")])
7390 (define_insn "*tldo_ldub2_sp64"
7391 [(set (match_operand:SI 0 "register_operand" "=r")
7392 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7393 (match_operand 3 "tld_symbolic_operand" "")]
7395 (match_operand:DI 1 "register_operand" "r")))))]
7396 "TARGET_TLS && TARGET_ARCH64"
7397 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7398 [(set_attr "type" "load")
7399 (set_attr "us3load_type" "3cycle")])
7401 (define_insn "*tldo_ldub3_sp64"
7402 [(set (match_operand:DI 0 "register_operand" "=r")
7403 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7404 (match_operand 3 "tld_symbolic_operand" "")]
7406 (match_operand:DI 1 "register_operand" "r")))))]
7407 "TARGET_TLS && TARGET_ARCH64"
7408 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7409 [(set_attr "type" "load")
7410 (set_attr "us3load_type" "3cycle")])
7412 (define_insn "*tldo_ldsb1_sp64"
7413 [(set (match_operand:HI 0 "register_operand" "=r")
7414 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7415 (match_operand 3 "tld_symbolic_operand" "")]
7417 (match_operand:DI 1 "register_operand" "r")))))]
7418 "TARGET_TLS && TARGET_ARCH64"
7419 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7420 [(set_attr "type" "sload")
7421 (set_attr "us3load_type" "3cycle")])
7423 (define_insn "*tldo_ldsb2_sp64"
7424 [(set (match_operand:SI 0 "register_operand" "=r")
7425 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7426 (match_operand 3 "tld_symbolic_operand" "")]
7428 (match_operand:DI 1 "register_operand" "r")))))]
7429 "TARGET_TLS && TARGET_ARCH64"
7430 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7431 [(set_attr "type" "sload")
7432 (set_attr "us3load_type" "3cycle")])
7434 (define_insn "*tldo_ldsb3_sp64"
7435 [(set (match_operand:DI 0 "register_operand" "=r")
7436 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7437 (match_operand 3 "tld_symbolic_operand" "")]
7439 (match_operand:DI 1 "register_operand" "r")))))]
7440 "TARGET_TLS && TARGET_ARCH64"
7441 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7442 [(set_attr "type" "sload")
7443 (set_attr "us3load_type" "3cycle")])
7445 (define_insn "*tldo_lduh_sp32"
7446 [(set (match_operand:HI 0 "register_operand" "=r")
7447 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7448 (match_operand 3 "tld_symbolic_operand" "")]
7450 (match_operand:SI 1 "register_operand" "r"))))]
7451 "TARGET_TLS && TARGET_ARCH32"
7452 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7453 [(set_attr "type" "load")
7454 (set_attr "us3load_type" "3cycle")])
7456 (define_insn "*tldo_lduh1_sp32"
7457 [(set (match_operand:SI 0 "register_operand" "=r")
7458 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7459 (match_operand 3 "tld_symbolic_operand" "")]
7461 (match_operand:SI 1 "register_operand" "r")))))]
7462 "TARGET_TLS && TARGET_ARCH32"
7463 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7464 [(set_attr "type" "load")
7465 (set_attr "us3load_type" "3cycle")])
7467 (define_insn "*tldo_ldsh1_sp32"
7468 [(set (match_operand:SI 0 "register_operand" "=r")
7469 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7470 (match_operand 3 "tld_symbolic_operand" "")]
7472 (match_operand:SI 1 "register_operand" "r")))))]
7473 "TARGET_TLS && TARGET_ARCH32"
7474 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7475 [(set_attr "type" "sload")
7476 (set_attr "us3load_type" "3cycle")])
7478 (define_insn "*tldo_lduh_sp64"
7479 [(set (match_operand:HI 0 "register_operand" "=r")
7480 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7481 (match_operand 3 "tld_symbolic_operand" "")]
7483 (match_operand:DI 1 "register_operand" "r"))))]
7484 "TARGET_TLS && TARGET_ARCH64"
7485 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7486 [(set_attr "type" "load")
7487 (set_attr "us3load_type" "3cycle")])
7489 (define_insn "*tldo_lduh1_sp64"
7490 [(set (match_operand:SI 0 "register_operand" "=r")
7491 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7492 (match_operand 3 "tld_symbolic_operand" "")]
7494 (match_operand:DI 1 "register_operand" "r")))))]
7495 "TARGET_TLS && TARGET_ARCH64"
7496 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7497 [(set_attr "type" "load")
7498 (set_attr "us3load_type" "3cycle")])
7500 (define_insn "*tldo_lduh2_sp64"
7501 [(set (match_operand:DI 0 "register_operand" "=r")
7502 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7503 (match_operand 3 "tld_symbolic_operand" "")]
7505 (match_operand:DI 1 "register_operand" "r")))))]
7506 "TARGET_TLS && TARGET_ARCH64"
7507 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7508 [(set_attr "type" "load")
7509 (set_attr "us3load_type" "3cycle")])
7511 (define_insn "*tldo_ldsh1_sp64"
7512 [(set (match_operand:SI 0 "register_operand" "=r")
7513 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7514 (match_operand 3 "tld_symbolic_operand" "")]
7516 (match_operand:DI 1 "register_operand" "r")))))]
7517 "TARGET_TLS && TARGET_ARCH64"
7518 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7519 [(set_attr "type" "sload")
7520 (set_attr "us3load_type" "3cycle")])
7522 (define_insn "*tldo_ldsh2_sp64"
7523 [(set (match_operand:DI 0 "register_operand" "=r")
7524 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7525 (match_operand 3 "tld_symbolic_operand" "")]
7527 (match_operand:DI 1 "register_operand" "r")))))]
7528 "TARGET_TLS && TARGET_ARCH64"
7529 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7530 [(set_attr "type" "sload")
7531 (set_attr "us3load_type" "3cycle")])
7533 (define_insn "*tldo_lduw_sp32"
7534 [(set (match_operand:SI 0 "register_operand" "=r")
7535 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7536 (match_operand 3 "tld_symbolic_operand" "")]
7538 (match_operand:SI 1 "register_operand" "r"))))]
7539 "TARGET_TLS && TARGET_ARCH32"
7540 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7541 [(set_attr "type" "load")])
7543 (define_insn "*tldo_lduw_sp64"
7544 [(set (match_operand:SI 0 "register_operand" "=r")
7545 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7546 (match_operand 3 "tld_symbolic_operand" "")]
7548 (match_operand:DI 1 "register_operand" "r"))))]
7549 "TARGET_TLS && TARGET_ARCH64"
7550 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7551 [(set_attr "type" "load")])
7553 (define_insn "*tldo_lduw1_sp64"
7554 [(set (match_operand:DI 0 "register_operand" "=r")
7555 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7556 (match_operand 3 "tld_symbolic_operand" "")]
7558 (match_operand:DI 1 "register_operand" "r")))))]
7559 "TARGET_TLS && TARGET_ARCH64"
7560 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7561 [(set_attr "type" "load")])
7563 (define_insn "*tldo_ldsw1_sp64"
7564 [(set (match_operand:DI 0 "register_operand" "=r")
7565 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7566 (match_operand 3 "tld_symbolic_operand" "")]
7568 (match_operand:DI 1 "register_operand" "r")))))]
7569 "TARGET_TLS && TARGET_ARCH64"
7570 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7571 [(set_attr "type" "sload")
7572 (set_attr "us3load_type" "3cycle")])
7574 (define_insn "*tldo_ldx_sp64"
7575 [(set (match_operand:DI 0 "register_operand" "=r")
7576 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7577 (match_operand 3 "tld_symbolic_operand" "")]
7579 (match_operand:DI 1 "register_operand" "r"))))]
7580 "TARGET_TLS && TARGET_ARCH64"
7581 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7582 [(set_attr "type" "load")])
7584 (define_insn "*tldo_stb_sp32"
7585 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7586 (match_operand 3 "tld_symbolic_operand" "")]
7588 (match_operand:SI 1 "register_operand" "r")))
7589 (match_operand:QI 0 "register_operand" "=r"))]
7590 "TARGET_TLS && TARGET_ARCH32"
7591 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7592 [(set_attr "type" "store")])
7594 (define_insn "*tldo_stb_sp64"
7595 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7596 (match_operand 3 "tld_symbolic_operand" "")]
7598 (match_operand:DI 1 "register_operand" "r")))
7599 (match_operand:QI 0 "register_operand" "=r"))]
7600 "TARGET_TLS && TARGET_ARCH64"
7601 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7602 [(set_attr "type" "store")])
7604 (define_insn "*tldo_sth_sp32"
7605 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7606 (match_operand 3 "tld_symbolic_operand" "")]
7608 (match_operand:SI 1 "register_operand" "r")))
7609 (match_operand:HI 0 "register_operand" "=r"))]
7610 "TARGET_TLS && TARGET_ARCH32"
7611 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7612 [(set_attr "type" "store")])
7614 (define_insn "*tldo_sth_sp64"
7615 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7616 (match_operand 3 "tld_symbolic_operand" "")]
7618 (match_operand:DI 1 "register_operand" "r")))
7619 (match_operand:HI 0 "register_operand" "=r"))]
7620 "TARGET_TLS && TARGET_ARCH64"
7621 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7622 [(set_attr "type" "store")])
7624 (define_insn "*tldo_stw_sp32"
7625 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7626 (match_operand 3 "tld_symbolic_operand" "")]
7628 (match_operand:SI 1 "register_operand" "r")))
7629 (match_operand:SI 0 "register_operand" "=r"))]
7630 "TARGET_TLS && TARGET_ARCH32"
7631 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7632 [(set_attr "type" "store")])
7634 (define_insn "*tldo_stw_sp64"
7635 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7636 (match_operand 3 "tld_symbolic_operand" "")]
7638 (match_operand:DI 1 "register_operand" "r")))
7639 (match_operand:SI 0 "register_operand" "=r"))]
7640 "TARGET_TLS && TARGET_ARCH64"
7641 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7642 [(set_attr "type" "store")])
7644 (define_insn "*tldo_stx_sp64"
7645 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7646 (match_operand 3 "tld_symbolic_operand" "")]
7648 (match_operand:DI 1 "register_operand" "r")))
7649 (match_operand:DI 0 "register_operand" "=r"))]
7650 "TARGET_TLS && TARGET_ARCH64"
7651 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7652 [(set_attr "type" "store")])
7655 ;; Stack protector instructions.
7657 (define_expand "stack_protect_set"
7658 [(match_operand 0 "memory_operand" "")
7659 (match_operand 1 "memory_operand" "")]
7662 #ifdef TARGET_THREAD_SSP_OFFSET
7663 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7664 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7665 operands[1] = gen_rtx_MEM (Pmode, addr);
7668 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7670 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7674 (define_insn "stack_protect_setsi"
7675 [(set (match_operand:SI 0 "memory_operand" "=m")
7676 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7677 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7679 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7680 [(set_attr "type" "multi")
7681 (set_attr "length" "3")])
7683 (define_insn "stack_protect_setdi"
7684 [(set (match_operand:DI 0 "memory_operand" "=m")
7685 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7686 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7688 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7689 [(set_attr "type" "multi")
7690 (set_attr "length" "3")])
7692 (define_expand "stack_protect_test"
7693 [(match_operand 0 "memory_operand" "")
7694 (match_operand 1 "memory_operand" "")
7695 (match_operand 2 "" "")]
7699 #ifdef TARGET_THREAD_SSP_OFFSET
7700 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7701 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7702 operands[1] = gen_rtx_MEM (Pmode, addr);
7706 result = gen_reg_rtx (Pmode);
7707 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7708 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7709 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7713 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7714 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7715 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7716 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7721 (define_insn "stack_protect_testsi"
7722 [(set (reg:CC CC_REG)
7723 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7724 (match_operand:SI 1 "memory_operand" "m")]
7726 (set (match_scratch:SI 3 "=r") (const_int 0))
7727 (clobber (match_scratch:SI 2 "=&r"))]
7729 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7730 [(set_attr "type" "multi")
7731 (set_attr "length" "4")])
7733 (define_insn "stack_protect_testdi"
7734 [(set (match_operand:DI 0 "register_operand" "=&r")
7735 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7736 (match_operand:DI 2 "memory_operand" "m")]
7738 (set (match_scratch:DI 3 "=r") (const_int 0))]
7740 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7741 [(set_attr "type" "multi")
7742 (set_attr "length" "4")])
7745 ;; Vector instructions.
7747 (define_insn "addv2si3"
7748 [(set (match_operand:V2SI 0 "register_operand" "=e")
7749 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7750 (match_operand:V2SI 2 "register_operand" "e")))]
7752 "fpadd32\t%1, %2, %0"
7753 [(set_attr "type" "fga")
7754 (set_attr "fptype" "double")])
7756 (define_insn "addv4hi3"
7757 [(set (match_operand:V4HI 0 "register_operand" "=e")
7758 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7759 (match_operand:V4HI 2 "register_operand" "e")))]
7761 "fpadd16\t%1, %2, %0"
7762 [(set_attr "type" "fga")
7763 (set_attr "fptype" "double")])
7765 ;; fpadd32s is emitted by the addsi3 pattern.
7767 (define_insn "addv2hi3"
7768 [(set (match_operand:V2HI 0 "register_operand" "=f")
7769 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7770 (match_operand:V2HI 2 "register_operand" "f")))]
7772 "fpadd16s\t%1, %2, %0"
7773 [(set_attr "type" "fga")
7774 (set_attr "fptype" "single")])
7776 (define_insn "subv2si3"
7777 [(set (match_operand:V2SI 0 "register_operand" "=e")
7778 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7779 (match_operand:V2SI 2 "register_operand" "e")))]
7781 "fpsub32\t%1, %2, %0"
7782 [(set_attr "type" "fga")
7783 (set_attr "fptype" "double")])
7785 (define_insn "subv4hi3"
7786 [(set (match_operand:V4HI 0 "register_operand" "=e")
7787 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7788 (match_operand:V4HI 2 "register_operand" "e")))]
7790 "fpsub16\t%1, %2, %0"
7791 [(set_attr "type" "fga")
7792 (set_attr "fptype" "double")])
7794 ;; fpsub32s is emitted by the subsi3 pattern.
7796 (define_insn "subv2hi3"
7797 [(set (match_operand:V2HI 0 "register_operand" "=f")
7798 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7799 (match_operand:V2HI 2 "register_operand" "f")))]
7801 "fpsub16s\t%1, %2, %0"
7802 [(set_attr "type" "fga")
7803 (set_attr "fptype" "single")])
7805 ;; All other logical instructions have integer equivalents so they
7806 ;; are defined together.
7808 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7810 (define_insn "*nand<V64:mode>_vis"
7811 [(set (match_operand:V64 0 "register_operand" "=e")
7812 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7813 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7816 [(set_attr "type" "fga")
7817 (set_attr "fptype" "double")])
7819 (define_insn "*nand<V32:mode>_vis"
7820 [(set (match_operand:V32 0 "register_operand" "=f")
7821 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7822 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7824 "fnands\t%1, %2, %0"
7825 [(set_attr "type" "fga")
7826 (set_attr "fptype" "single")])
7828 ;; Hard to generate VIS instructions. We have builtins for these.
7830 (define_insn "fpack16_vis"
7831 [(set (match_operand:V4QI 0 "register_operand" "=f")
7832 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7834 (use (reg:DI GSR_REG))]
7837 [(set_attr "type" "fga")
7838 (set_attr "fptype" "double")])
7840 (define_insn "fpackfix_vis"
7841 [(set (match_operand:V2HI 0 "register_operand" "=f")
7842 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7844 (use (reg:DI GSR_REG))]
7847 [(set_attr "type" "fga")
7848 (set_attr "fptype" "double")])
7850 (define_insn "fpack32_vis"
7851 [(set (match_operand:V8QI 0 "register_operand" "=e")
7852 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7853 (match_operand:V8QI 2 "register_operand" "e")]
7855 (use (reg:DI GSR_REG))]
7857 "fpack32\t%1, %2, %0"
7858 [(set_attr "type" "fga")
7859 (set_attr "fptype" "double")])
7861 (define_insn "fexpand_vis"
7862 [(set (match_operand:V4HI 0 "register_operand" "=e")
7863 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7867 [(set_attr "type" "fga")
7868 (set_attr "fptype" "double")])
7870 ;; It may be possible to describe this operation as (1 indexed):
7871 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7872 ;; 1,5,10,14,19,23,28,32)
7873 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7874 ;; because vec_merge expects all the operands to be of the same type.
7875 (define_insn "fpmerge_vis"
7876 [(set (match_operand:V8QI 0 "register_operand" "=e")
7877 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7878 (match_operand:V4QI 2 "register_operand" "f")]
7881 "fpmerge\t%1, %2, %0"
7882 [(set_attr "type" "fga")
7883 (set_attr "fptype" "double")])
7885 ;; Partitioned multiply instructions
7886 (define_insn "fmul8x16_vis"
7887 [(set (match_operand:V4HI 0 "register_operand" "=e")
7888 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7889 (match_operand:V4HI 2 "register_operand" "e")))]
7891 "fmul8x16\t%1, %2, %0"
7892 [(set_attr "type" "fpmul")
7893 (set_attr "fptype" "double")])
7895 ;; Only one of the following two insns can be a multiply.
7896 (define_insn "fmul8x16au_vis"
7897 [(set (match_operand:V4HI 0 "register_operand" "=e")
7898 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7899 (match_operand:V2HI 2 "register_operand" "f")))]
7901 "fmul8x16au\t%1, %2, %0"
7902 [(set_attr "type" "fpmul")
7903 (set_attr "fptype" "double")])
7905 (define_insn "fmul8x16al_vis"
7906 [(set (match_operand:V4HI 0 "register_operand" "=e")
7907 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7908 (match_operand:V2HI 2 "register_operand" "f")]
7911 "fmul8x16al\t%1, %2, %0"
7912 [(set_attr "type" "fpmul")
7913 (set_attr "fptype" "double")])
7915 ;; Only one of the following two insns can be a multiply.
7916 (define_insn "fmul8sux16_vis"
7917 [(set (match_operand:V4HI 0 "register_operand" "=e")
7918 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7919 (match_operand:V4HI 2 "register_operand" "e")))]
7921 "fmul8sux16\t%1, %2, %0"
7922 [(set_attr "type" "fpmul")
7923 (set_attr "fptype" "double")])
7925 (define_insn "fmul8ulx16_vis"
7926 [(set (match_operand:V4HI 0 "register_operand" "=e")
7927 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7928 (match_operand:V4HI 2 "register_operand" "e")]
7931 "fmul8ulx16\t%1, %2, %0"
7932 [(set_attr "type" "fpmul")
7933 (set_attr "fptype" "double")])
7935 ;; Only one of the following two insns can be a multiply.
7936 (define_insn "fmuld8sux16_vis"
7937 [(set (match_operand:V2SI 0 "register_operand" "=e")
7938 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7939 (match_operand:V2HI 2 "register_operand" "f")))]
7941 "fmuld8sux16\t%1, %2, %0"
7942 [(set_attr "type" "fpmul")
7943 (set_attr "fptype" "double")])
7945 (define_insn "fmuld8ulx16_vis"
7946 [(set (match_operand:V2SI 0 "register_operand" "=e")
7947 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7948 (match_operand:V2HI 2 "register_operand" "f")]
7951 "fmuld8ulx16\t%1, %2, %0"
7952 [(set_attr "type" "fpmul")
7953 (set_attr "fptype" "double")])
7955 (define_expand "wrgsr_vis"
7956 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
7959 if (! TARGET_ARCH64)
7961 emit_insn (gen_wrgsr_v8plus (operands[0]));
7966 (define_insn "*wrgsr_sp64"
7967 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
7968 "TARGET_VIS && TARGET_ARCH64"
7969 "wr\t%%g0, %0, %%gsr"
7970 [(set_attr "type" "gsr")])
7972 (define_insn "wrgsr_v8plus"
7973 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
7974 (clobber (match_scratch:SI 1 "=X,&h"))]
7975 "TARGET_VIS && ! TARGET_ARCH64"
7977 if (GET_CODE (operands[0]) == CONST_INT
7978 || sparc_check_64 (operands[0], insn))
7979 return "wr\t%%g0, %0, %%gsr";
7981 output_asm_insn("srl\t%L0, 0, %L0", operands);
7982 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
7984 [(set_attr "type" "multi")])
7986 (define_expand "rdgsr_vis"
7987 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
7990 if (! TARGET_ARCH64)
7992 emit_insn (gen_rdgsr_v8plus (operands[0]));
7997 (define_insn "*rdgsr_sp64"
7998 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
7999 "TARGET_VIS && TARGET_ARCH64"
8001 [(set_attr "type" "gsr")])
8003 (define_insn "rdgsr_v8plus"
8004 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8005 (clobber (match_scratch:SI 1 "=&h"))]
8006 "TARGET_VIS && ! TARGET_ARCH64"
8008 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8010 [(set_attr "type" "multi")])
8012 ;; Using faligndata only makes sense after an alignaddr since the choice of
8013 ;; bytes to take out of each operand is dependent on the results of the last
8015 (define_insn "faligndata<V64I:mode>_vis"
8016 [(set (match_operand:V64I 0 "register_operand" "=e")
8017 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8018 (match_operand:V64I 2 "register_operand" "e")]
8020 (use (reg:SI GSR_REG))]
8022 "faligndata\t%1, %2, %0"
8023 [(set_attr "type" "fga")
8024 (set_attr "fptype" "double")])
8026 (define_insn "alignaddrsi_vis"
8027 [(set (match_operand:SI 0 "register_operand" "=r")
8028 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8029 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8030 (set (reg:SI GSR_REG)
8031 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8032 (and:SI (plus:SI (match_dup 1) (match_dup 2))
8035 "alignaddr\t%r1, %r2, %0")
8037 (define_insn "alignaddrdi_vis"
8038 [(set (match_operand:DI 0 "register_operand" "=r")
8039 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8040 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8041 (set (reg:SI GSR_REG)
8042 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8043 (and:SI (truncate:SI (plus:DI (match_dup 1) (match_dup 2)))
8046 "alignaddr\t%r1, %r2, %0")
8048 (define_insn "alignaddrlsi_vis"
8049 [(set (match_operand:SI 0 "register_operand" "=r")
8050 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8051 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8052 (set (reg:SI GSR_REG)
8053 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8054 (xor:SI (and:SI (plus:SI (match_dup 1) (match_dup 2))
8058 "alignaddrl\t%r1, %r2, %0")
8060 (define_insn "alignaddrldi_vis"
8061 [(set (match_operand:DI 0 "register_operand" "=r")
8062 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8063 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8064 (set (reg:SI GSR_REG)
8065 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8066 (xor:SI (and:SI (truncate:SI (plus:DI (match_dup 1)
8071 "alignaddrl\t%r1, %r2, %0")
8073 (define_insn "pdist_vis"
8074 [(set (match_operand:DI 0 "register_operand" "=e")
8075 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8076 (match_operand:V8QI 2 "register_operand" "e")
8077 (match_operand:DI 3 "register_operand" "0")]
8081 [(set_attr "type" "fga")
8082 (set_attr "fptype" "double")])
8084 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8085 ;; with the same operands.
8086 (define_insn "edge8<P:mode>_vis"
8087 [(set (reg:CC_NOOV CC_REG)
8088 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8089 (match_operand:P 2 "register_operand" "rJ"))
8091 (set (match_operand:P 0 "register_operand" "=r")
8092 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8094 "edge8\t%r1, %r2, %0"
8095 [(set_attr "type" "edge")])
8097 (define_insn "edge8l<P:mode>_vis"
8098 [(set (reg:CC_NOOV CC_REG)
8099 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8100 (match_operand:P 2 "register_operand" "rJ"))
8102 (set (match_operand:P 0 "register_operand" "=r")
8103 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8105 "edge8l\t%r1, %r2, %0"
8106 [(set_attr "type" "edge")])
8108 (define_insn "edge16<P:mode>_vis"
8109 [(set (reg:CC_NOOV CC_REG)
8110 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8111 (match_operand:P 2 "register_operand" "rJ"))
8113 (set (match_operand:P 0 "register_operand" "=r")
8114 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8116 "edge16\t%r1, %r2, %0"
8117 [(set_attr "type" "edge")])
8119 (define_insn "edge16l<P:mode>_vis"
8120 [(set (reg:CC_NOOV CC_REG)
8121 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8122 (match_operand:P 2 "register_operand" "rJ"))
8124 (set (match_operand:P 0 "register_operand" "=r")
8125 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8127 "edge16l\t%r1, %r2, %0"
8128 [(set_attr "type" "edge")])
8130 (define_insn "edge32<P:mode>_vis"
8131 [(set (reg:CC_NOOV CC_REG)
8132 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8133 (match_operand:P 2 "register_operand" "rJ"))
8135 (set (match_operand:P 0 "register_operand" "=r")
8136 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8138 "edge32\t%r1, %r2, %0"
8139 [(set_attr "type" "edge")])
8141 (define_insn "edge32l<P:mode>_vis"
8142 [(set (reg:CC_NOOV CC_REG)
8143 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8144 (match_operand:P 2 "register_operand" "rJ"))
8146 (set (match_operand:P 0 "register_operand" "=r")
8147 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8149 "edge32l\t%r1, %r2, %0"
8150 [(set_attr "type" "edge")])
8152 (define_insn "fcmple16<P:mode>_vis"
8153 [(set (match_operand:P 0 "register_operand" "=r")
8154 (unspec:P [(match_operand:V4HI 1 "register_operand" "e")
8155 (match_operand:V4HI 2 "register_operand" "e")]
8158 "fcmple16\t%1, %2, %0"
8159 [(set_attr "type" "fpmul")
8160 (set_attr "fptype" "double")])
8162 (define_insn "fcmple32<P:mode>_vis"
8163 [(set (match_operand:P 0 "register_operand" "=r")
8164 (unspec:P [(match_operand:V2SI 1 "register_operand" "e")
8165 (match_operand:V2SI 2 "register_operand" "e")]
8168 "fcmple32\t%1, %2, %0"
8169 [(set_attr "type" "fpmul")
8170 (set_attr "fptype" "double")])
8172 (define_insn "fcmpne16<P:mode>_vis"
8173 [(set (match_operand:P 0 "register_operand" "=r")
8174 (unspec:P [(match_operand:V4HI 1 "register_operand" "e")
8175 (match_operand:V4HI 2 "register_operand" "e")]
8178 "fcmpne16\t%1, %2, %0"
8179 [(set_attr "type" "fpmul")
8180 (set_attr "fptype" "double")])
8182 (define_insn "fcmpne32<P:mode>_vis"
8183 [(set (match_operand:P 0 "register_operand" "=r")
8184 (unspec:P [(match_operand:V2SI 1 "register_operand" "e")
8185 (match_operand:V2SI 2 "register_operand" "e")]
8188 "fcmpne32\t%1, %2, %0"
8189 [(set_attr "type" "fpmul")
8190 (set_attr "fptype" "double")])
8192 (define_insn "fcmpgt16<P:mode>_vis"
8193 [(set (match_operand:P 0 "register_operand" "=r")
8194 (unspec:P [(match_operand:V4HI 1 "register_operand" "e")
8195 (match_operand:V4HI 2 "register_operand" "e")]
8198 "fcmpgt16\t%1, %2, %0"
8199 [(set_attr "type" "fpmul")
8200 (set_attr "fptype" "double")])
8202 (define_insn "fcmpgt32<P:mode>_vis"
8203 [(set (match_operand:P 0 "register_operand" "=r")
8204 (unspec:P [(match_operand:V2SI 1 "register_operand" "e")
8205 (match_operand:V2SI 2 "register_operand" "e")]
8208 "fcmpgt32\t%1, %2, %0"
8209 [(set_attr "type" "fpmul")
8210 (set_attr "fptype" "double")])
8212 (define_insn "fcmpeq16<P:mode>_vis"
8213 [(set (match_operand:P 0 "register_operand" "=r")
8214 (unspec:P [(match_operand:V4HI 1 "register_operand" "e")
8215 (match_operand:V4HI 2 "register_operand" "e")]
8218 "fcmpeq16\t%1, %2, %0"
8219 [(set_attr "type" "fpmul")
8220 (set_attr "fptype" "double")])
8222 (define_insn "fcmpeq32<P:mode>_vis"
8223 [(set (match_operand:P 0 "register_operand" "=r")
8224 (unspec:P [(match_operand:V2SI 1 "register_operand" "e")
8225 (match_operand:V2SI 2 "register_operand" "e")]
8228 "fcmpeq32\t%1, %2, %0"
8229 [(set_attr "type" "fpmul")
8230 (set_attr "fptype" "double")])