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)
86 (UNSPECV_PROBE_STACK_RANGE 11)
179 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
180 (define_mode_iterator I [QI HI SI DI])
181 (define_mode_iterator F [SF DF TF])
183 ;; We don't define V1SI because SI should work just fine.
184 (define_mode_iterator V32 [SF V2HI V4QI])
185 (define_mode_iterator V32I [SI V2HI V4QI])
187 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
188 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
190 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
191 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
192 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
193 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
194 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
197 ;; Attribute for cpu type.
198 ;; These must match the values for enum processor_type in sparc.h.
219 (const (symbol_ref "sparc_cpu_attr")))
221 ;; Attribute for the instruction set.
222 ;; At present we only need to distinguish v9/!v9, but for clarity we
223 ;; test TARGET_V8 too.
224 (define_attr "isa" "v7,v8,v9,sparclet"
226 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
227 (symbol_ref "TARGET_V8") (const_string "v8")
228 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
229 (const_string "v7"))))
235 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
243 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,gsr,array,
246 multi,savew,flushw,iflush,trap"
247 (const_string "ialu"))
249 ;; True if branch/call has empty delay slot and will emit a nop in it
250 (define_attr "empty_delay_slot" "false,true"
251 (symbol_ref "(empty_delay_slot (insn)
252 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
254 (define_attr "branch_type" "none,icc,fcc,reg"
255 (const_string "none"))
257 (define_attr "pic" "false,true"
258 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
260 (define_attr "calls_alloca" "false,true"
261 (symbol_ref "(cfun->calls_alloca != 0
262 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
264 (define_attr "calls_eh_return" "false,true"
265 (symbol_ref "(crtl->calls_eh_return != 0
266 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
268 (define_attr "leaf_function" "false,true"
269 (symbol_ref "(current_function_uses_only_leaf_regs != 0
270 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
272 (define_attr "delayed_branch" "false,true"
273 (symbol_ref "(flag_delayed_branch != 0
274 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
276 (define_attr "flat" "false,true"
277 (symbol_ref "(TARGET_FLAT != 0
278 ? FLAT_TRUE : FLAT_FALSE)"))
280 ;; Length (in # of insns).
281 ;; Beware that setting a length greater or equal to 3 for conditional branches
282 ;; has a side-effect (see output_cbranch and output_v9branch).
283 (define_attr "length" ""
284 (cond [(eq_attr "type" "uncond_branch,call")
285 (if_then_else (eq_attr "empty_delay_slot" "true")
288 (eq_attr "type" "sibcall")
289 (if_then_else (eq_attr "leaf_function" "true")
290 (if_then_else (eq_attr "empty_delay_slot" "true")
293 (if_then_else (eq_attr "empty_delay_slot" "true")
296 (eq_attr "branch_type" "icc")
297 (if_then_else (match_operand 0 "noov_compare64_operator" "")
298 (if_then_else (lt (pc) (match_dup 1))
299 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
300 (if_then_else (eq_attr "empty_delay_slot" "true")
303 (if_then_else (eq_attr "empty_delay_slot" "true")
306 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
307 (if_then_else (eq_attr "empty_delay_slot" "true")
310 (if_then_else (eq_attr "empty_delay_slot" "true")
313 (if_then_else (eq_attr "empty_delay_slot" "true")
316 (eq_attr "branch_type" "fcc")
317 (if_then_else (match_operand 0 "fcc0_register_operand" "")
318 (if_then_else (eq_attr "empty_delay_slot" "true")
319 (if_then_else (not (match_test "TARGET_V9"))
322 (if_then_else (not (match_test "TARGET_V9"))
325 (if_then_else (lt (pc) (match_dup 2))
326 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
327 (if_then_else (eq_attr "empty_delay_slot" "true")
330 (if_then_else (eq_attr "empty_delay_slot" "true")
333 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
334 (if_then_else (eq_attr "empty_delay_slot" "true")
337 (if_then_else (eq_attr "empty_delay_slot" "true")
340 (eq_attr "branch_type" "reg")
341 (if_then_else (lt (pc) (match_dup 2))
342 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
343 (if_then_else (eq_attr "empty_delay_slot" "true")
346 (if_then_else (eq_attr "empty_delay_slot" "true")
349 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
350 (if_then_else (eq_attr "empty_delay_slot" "true")
353 (if_then_else (eq_attr "empty_delay_slot" "true")
359 (define_attr "fptype" "single,double"
360 (const_string "single"))
362 ;; UltraSPARC-III integer load type.
363 (define_attr "us3load_type" "2cycle,3cycle"
364 (const_string "2cycle"))
366 (define_asm_attributes
367 [(set_attr "length" "2")
368 (set_attr "type" "multi")])
370 ;; Attributes for instruction and branch scheduling
371 (define_attr "tls_call_delay" "false,true"
372 (symbol_ref "(tls_call_delay (insn)
373 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
375 (define_attr "in_call_delay" "false,true"
376 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
377 (const_string "false")
378 (eq_attr "type" "load,fpload,store,fpstore")
379 (if_then_else (eq_attr "length" "1")
380 (const_string "true")
381 (const_string "false"))]
382 (if_then_else (and (eq_attr "length" "1")
383 (eq_attr "tls_call_delay" "true"))
384 (const_string "true")
385 (const_string "false"))))
387 (define_attr "eligible_for_sibcall_delay" "false,true"
388 (symbol_ref "(eligible_for_sibcall_delay (insn)
389 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
390 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
392 (define_attr "eligible_for_return_delay" "false,true"
393 (symbol_ref "(eligible_for_return_delay (insn)
394 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
395 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
397 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
398 ;; branches. This would allow us to remove the nop always inserted before
399 ;; a floating point branch.
401 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
402 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
403 ;; This is because doing so will add several pipeline stalls to the path
404 ;; that the load/store did not come from. Unfortunately, there is no way
405 ;; to prevent fill_eager_delay_slots from using load/store without completely
406 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
407 ;; because it prevents us from moving back the final store of inner loops.
409 (define_attr "in_branch_delay" "false,true"
410 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
411 (eq_attr "length" "1"))
412 (const_string "true")
413 (const_string "false")))
415 (define_attr "in_uncond_branch_delay" "false,true"
416 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
417 (eq_attr "length" "1"))
418 (const_string "true")
419 (const_string "false")))
421 (define_attr "in_annul_branch_delay" "false,true"
422 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
423 (eq_attr "length" "1"))
424 (const_string "true")
425 (const_string "false")))
427 (define_delay (eq_attr "type" "call")
428 [(eq_attr "in_call_delay" "true") (nil) (nil)])
430 (define_delay (eq_attr "type" "sibcall")
431 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
433 (define_delay (eq_attr "type" "branch")
434 [(eq_attr "in_branch_delay" "true")
435 (nil) (eq_attr "in_annul_branch_delay" "true")])
437 (define_delay (eq_attr "type" "uncond_branch")
438 [(eq_attr "in_uncond_branch_delay" "true")
441 (define_delay (eq_attr "type" "return")
442 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
445 ;; Include SPARC DFA schedulers
447 (include "cypress.md")
448 (include "supersparc.md")
449 (include "hypersparc.md")
451 (include "sparclet.md")
452 (include "ultra1_2.md")
453 (include "ultra3.md")
454 (include "niagara.md")
455 (include "niagara2.md")
458 ;; Operand and operator predicates and constraints
460 (include "predicates.md")
461 (include "constraints.md")
464 ;; Compare instructions.
466 ;; These are just the DEFINE_INSNs to match the patterns and the
467 ;; DEFINE_SPLITs for some of the scc insns that actually require
468 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
470 ;; The compare DEFINE_INSNs.
472 (define_insn "*cmpsi_insn"
473 [(set (reg:CC CC_REG)
474 (compare:CC (match_operand:SI 0 "register_operand" "r")
475 (match_operand:SI 1 "arith_operand" "rI")))]
478 [(set_attr "type" "compare")])
480 (define_insn "*cmpdi_sp64"
481 [(set (reg:CCX CC_REG)
482 (compare:CCX (match_operand:DI 0 "register_operand" "r")
483 (match_operand:DI 1 "arith_operand" "rI")))]
486 [(set_attr "type" "compare")])
488 (define_insn "*cmpsf_fpe"
489 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
490 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
491 (match_operand:SF 2 "register_operand" "f")))]
495 return "fcmpes\t%0, %1, %2";
496 return "fcmpes\t%1, %2";
498 [(set_attr "type" "fpcmp")])
500 (define_insn "*cmpdf_fpe"
501 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
502 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
503 (match_operand:DF 2 "register_operand" "e")))]
507 return "fcmped\t%0, %1, %2";
508 return "fcmped\t%1, %2";
510 [(set_attr "type" "fpcmp")
511 (set_attr "fptype" "double")])
513 (define_insn "*cmptf_fpe"
514 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
515 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
516 (match_operand:TF 2 "register_operand" "e")))]
517 "TARGET_FPU && TARGET_HARD_QUAD"
520 return "fcmpeq\t%0, %1, %2";
521 return "fcmpeq\t%1, %2";
523 [(set_attr "type" "fpcmp")])
525 (define_insn "*cmpsf_fp"
526 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
527 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
528 (match_operand:SF 2 "register_operand" "f")))]
532 return "fcmps\t%0, %1, %2";
533 return "fcmps\t%1, %2";
535 [(set_attr "type" "fpcmp")])
537 (define_insn "*cmpdf_fp"
538 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
539 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
540 (match_operand:DF 2 "register_operand" "e")))]
544 return "fcmpd\t%0, %1, %2";
545 return "fcmpd\t%1, %2";
547 [(set_attr "type" "fpcmp")
548 (set_attr "fptype" "double")])
550 (define_insn "*cmptf_fp"
551 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
552 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
553 (match_operand:TF 2 "register_operand" "e")))]
554 "TARGET_FPU && TARGET_HARD_QUAD"
557 return "fcmpq\t%0, %1, %2";
558 return "fcmpq\t%1, %2";
560 [(set_attr "type" "fpcmp")])
562 ;; Next come the scc insns.
564 (define_expand "cstoresi4"
565 [(use (match_operator 1 "comparison_operator"
566 [(match_operand:SI 2 "compare_operand" "")
567 (match_operand:SI 3 "arith_operand" "")]))
568 (clobber (match_operand:SI 0 "register_operand"))]
571 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
572 operands[2] = force_reg (SImode, operands[2]);
573 if (emit_scc_insn (operands)) DONE; else FAIL;
576 (define_expand "cstoredi4"
577 [(use (match_operator 1 "comparison_operator"
578 [(match_operand:DI 2 "compare_operand" "")
579 (match_operand:DI 3 "arith_operand" "")]))
580 (clobber (match_operand:SI 0 "register_operand"))]
583 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
584 operands[2] = force_reg (DImode, operands[2]);
585 if (emit_scc_insn (operands)) DONE; else FAIL;
588 (define_expand "cstore<F:mode>4"
589 [(use (match_operator 1 "comparison_operator"
590 [(match_operand:F 2 "register_operand" "")
591 (match_operand:F 3 "register_operand" "")]))
592 (clobber (match_operand:SI 0 "register_operand"))]
594 { if (emit_scc_insn (operands)) DONE; else FAIL; })
598 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
599 ;; generate addcc/subcc instructions.
601 (define_expand "seqsi_special"
603 (xor:SI (match_operand:SI 1 "register_operand" "")
604 (match_operand:SI 2 "register_operand" "")))
605 (parallel [(set (match_operand:SI 0 "register_operand" "")
606 (eq:SI (match_dup 3) (const_int 0)))
607 (clobber (reg:CC CC_REG))])]
609 { operands[3] = gen_reg_rtx (SImode); })
611 (define_expand "seqdi_special"
613 (xor:DI (match_operand:DI 1 "register_operand" "")
614 (match_operand:DI 2 "register_operand" "")))
615 (set (match_operand:SI 0 "register_operand" "")
616 (eq:SI (match_dup 3) (const_int 0)))]
618 { operands[3] = gen_reg_rtx (DImode); })
620 (define_expand "snesi_special"
622 (xor:SI (match_operand:SI 1 "register_operand" "")
623 (match_operand:SI 2 "register_operand" "")))
624 (parallel [(set (match_operand:SI 0 "register_operand" "")
625 (ne:SI (match_dup 3) (const_int 0)))
626 (clobber (reg:CC CC_REG))])]
628 { operands[3] = gen_reg_rtx (SImode); })
630 (define_expand "snedi_special"
632 (xor:DI (match_operand:DI 1 "register_operand" "")
633 (match_operand:DI 2 "register_operand" "")))
634 (set (match_operand:SI 0 "register_operand" "")
635 (ne:SI (match_dup 3) (const_int 0)))]
637 { operands[3] = gen_reg_rtx (DImode); })
640 ;; Now the DEFINE_INSNs for the scc cases.
642 ;; The SEQ and SNE patterns are special because they can be done
643 ;; without any branching and do not involve a COMPARE. We want
644 ;; them to always use the splits below so the results can be
647 (define_insn_and_split "*snesi_zero"
648 [(set (match_operand:SI 0 "register_operand" "=r")
649 (ne:SI (match_operand:SI 1 "register_operand" "r")
651 (clobber (reg:CC CC_REG))]
655 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
657 (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
659 [(set_attr "length" "2")])
661 (define_insn_and_split "*neg_snesi_zero"
662 [(set (match_operand:SI 0 "register_operand" "=r")
663 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
665 (clobber (reg:CC CC_REG))]
669 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
671 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
673 [(set_attr "length" "2")])
675 (define_insn_and_split "*snesi_zero_extend"
676 [(set (match_operand:DI 0 "register_operand" "=r")
677 (ne:DI (match_operand:SI 1 "register_operand" "r")
679 (clobber (reg:CC CC_REG))]
683 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
686 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
688 (ltu:SI (reg:CC_NOOV CC_REG)
691 [(set_attr "length" "2")])
693 (define_insn_and_split "*snedi_zero"
694 [(set (match_operand:DI 0 "register_operand" "=&r")
695 (ne:DI (match_operand:DI 1 "register_operand" "r")
699 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
700 [(set (match_dup 0) (const_int 0))
701 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
706 [(set_attr "length" "2")])
708 (define_insn_and_split "*neg_snedi_zero"
709 [(set (match_operand:DI 0 "register_operand" "=&r")
710 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
714 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
715 [(set (match_dup 0) (const_int 0))
716 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
721 [(set_attr "length" "2")])
723 (define_insn_and_split "*snedi_zero_trunc"
724 [(set (match_operand:SI 0 "register_operand" "=&r")
725 (ne:SI (match_operand:DI 1 "register_operand" "r")
729 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
730 [(set (match_dup 0) (const_int 0))
731 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
736 [(set_attr "length" "2")])
738 (define_insn_and_split "*seqsi_zero"
739 [(set (match_operand:SI 0 "register_operand" "=r")
740 (eq:SI (match_operand:SI 1 "register_operand" "r")
742 (clobber (reg:CC CC_REG))]
746 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
748 (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
750 [(set_attr "length" "2")])
752 (define_insn_and_split "*neg_seqsi_zero"
753 [(set (match_operand:SI 0 "register_operand" "=r")
754 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
756 (clobber (reg:CC CC_REG))]
760 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
762 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
764 [(set_attr "length" "2")])
766 (define_insn_and_split "*seqsi_zero_extend"
767 [(set (match_operand:DI 0 "register_operand" "=r")
768 (eq:DI (match_operand:SI 1 "register_operand" "r")
770 (clobber (reg:CC CC_REG))]
774 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
777 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
779 (ltu:SI (reg:CC_NOOV CC_REG)
782 [(set_attr "length" "2")])
784 (define_insn_and_split "*seqdi_zero"
785 [(set (match_operand:DI 0 "register_operand" "=&r")
786 (eq:DI (match_operand:DI 1 "register_operand" "r")
790 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
791 [(set (match_dup 0) (const_int 0))
792 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
797 [(set_attr "length" "2")])
799 (define_insn_and_split "*neg_seqdi_zero"
800 [(set (match_operand:DI 0 "register_operand" "=&r")
801 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
805 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
806 [(set (match_dup 0) (const_int 0))
807 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
812 [(set_attr "length" "2")])
814 (define_insn_and_split "*seqdi_zero_trunc"
815 [(set (match_operand:SI 0 "register_operand" "=&r")
816 (eq:SI (match_operand:DI 1 "register_operand" "r")
820 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
821 [(set (match_dup 0) (const_int 0))
822 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
827 [(set_attr "length" "2")])
829 ;; We can also do (x + (i == 0)) and related, so put them in.
830 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
833 (define_insn_and_split "*x_plus_i_ne_0"
834 [(set (match_operand:SI 0 "register_operand" "=r")
835 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
837 (match_operand:SI 2 "register_operand" "r")))
838 (clobber (reg:CC CC_REG))]
842 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
844 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
847 [(set_attr "length" "2")])
849 (define_insn_and_split "*x_minus_i_ne_0"
850 [(set (match_operand:SI 0 "register_operand" "=r")
851 (minus:SI (match_operand:SI 2 "register_operand" "r")
852 (ne:SI (match_operand:SI 1 "register_operand" "r")
854 (clobber (reg:CC CC_REG))]
858 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
860 (set (match_dup 0) (minus:SI (match_dup 2)
861 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
863 [(set_attr "length" "2")])
865 (define_insn_and_split "*x_plus_i_eq_0"
866 [(set (match_operand:SI 0 "register_operand" "=r")
867 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
869 (match_operand:SI 2 "register_operand" "r")))
870 (clobber (reg:CC CC_REG))]
874 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
876 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
879 [(set_attr "length" "2")])
881 (define_insn_and_split "*x_minus_i_eq_0"
882 [(set (match_operand:SI 0 "register_operand" "=r")
883 (minus:SI (match_operand:SI 2 "register_operand" "r")
884 (eq:SI (match_operand:SI 1 "register_operand" "r")
886 (clobber (reg:CC CC_REG))]
890 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
892 (set (match_dup 0) (minus:SI (match_dup 2)
893 (geu:SI (reg:CC CC_REG) (const_int 0))))]
895 [(set_attr "length" "2")])
897 ;; We can also do GEU and LTU directly, but these operate after a compare.
898 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
901 (define_insn "*sltu_insn"
902 [(set (match_operand:SI 0 "register_operand" "=r")
903 (ltu:SI (reg:CC CC_REG) (const_int 0)))]
906 [(set_attr "type" "ialuX")])
908 (define_insn "*neg_sltu_insn"
909 [(set (match_operand:SI 0 "register_operand" "=r")
910 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
913 [(set_attr "type" "ialuX")])
915 ;; ??? Combine should canonicalize these next two to the same pattern.
916 (define_insn "*neg_sltu_minus_x"
917 [(set (match_operand:SI 0 "register_operand" "=r")
918 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
919 (match_operand:SI 1 "arith_operand" "rI")))]
922 [(set_attr "type" "ialuX")])
924 (define_insn "*neg_sltu_plus_x"
925 [(set (match_operand:SI 0 "register_operand" "=r")
926 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
927 (match_operand:SI 1 "arith_operand" "rI"))))]
930 [(set_attr "type" "ialuX")])
932 (define_insn "*sgeu_insn"
933 [(set (match_operand:SI 0 "register_operand" "=r")
934 (geu:SI (reg:CC CC_REG) (const_int 0)))]
937 [(set_attr "type" "ialuX")])
939 (define_insn "*neg_sgeu_insn"
940 [(set (match_operand:SI 0 "register_operand" "=r")
941 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
944 [(set_attr "type" "ialuX")])
946 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
947 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
950 (define_insn "*sltu_plus_x"
951 [(set (match_operand:SI 0 "register_operand" "=r")
952 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
953 (match_operand:SI 1 "arith_operand" "rI")))]
956 [(set_attr "type" "ialuX")])
958 (define_insn "*sltu_plus_x_plus_y"
959 [(set (match_operand:SI 0 "register_operand" "=r")
960 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
961 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
962 (match_operand:SI 2 "arith_operand" "rI"))))]
965 [(set_attr "type" "ialuX")])
967 (define_insn "*x_minus_sltu"
968 [(set (match_operand:SI 0 "register_operand" "=r")
969 (minus:SI (match_operand:SI 1 "register_operand" "r")
970 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
973 [(set_attr "type" "ialuX")])
975 ;; ??? Combine should canonicalize these next two to the same pattern.
976 (define_insn "*x_minus_y_minus_sltu"
977 [(set (match_operand:SI 0 "register_operand" "=r")
978 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
979 (match_operand:SI 2 "arith_operand" "rI"))
980 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
983 [(set_attr "type" "ialuX")])
985 (define_insn "*x_minus_sltu_plus_y"
986 [(set (match_operand:SI 0 "register_operand" "=r")
987 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
988 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
989 (match_operand:SI 2 "arith_operand" "rI"))))]
992 [(set_attr "type" "ialuX")])
994 (define_insn "*sgeu_plus_x"
995 [(set (match_operand:SI 0 "register_operand" "=r")
996 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
997 (match_operand:SI 1 "register_operand" "r")))]
1000 [(set_attr "type" "ialuX")])
1002 (define_insn "*x_minus_sgeu"
1003 [(set (match_operand:SI 0 "register_operand" "=r")
1004 (minus:SI (match_operand:SI 1 "register_operand" "r")
1005 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1008 [(set_attr "type" "ialuX")])
1011 [(set (match_operand:SI 0 "register_operand" "")
1012 (match_operator:SI 2 "noov_compare_operator"
1013 [(match_operand 1 "icc_or_fcc_register_operand" "")
1016 && REGNO (operands[1]) == SPARC_ICC_REG
1017 && (GET_MODE (operands[1]) == CCXmode
1018 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1019 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1020 [(set (match_dup 0) (const_int 0))
1022 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1028 ;; These control RTL generation for conditional jump insns
1030 (define_expand "cbranchcc4"
1032 (if_then_else (match_operator 0 "comparison_operator"
1033 [(match_operand 1 "compare_operand" "")
1034 (match_operand 2 "const_zero_operand" "")])
1035 (label_ref (match_operand 3 "" ""))
1040 (define_expand "cbranchsi4"
1041 [(use (match_operator 0 "comparison_operator"
1042 [(match_operand:SI 1 "compare_operand" "")
1043 (match_operand:SI 2 "arith_operand" "")]))
1044 (use (match_operand 3 ""))]
1047 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1048 operands[1] = force_reg (SImode, operands[1]);
1049 emit_conditional_branch_insn (operands);
1053 (define_expand "cbranchdi4"
1054 [(use (match_operator 0 "comparison_operator"
1055 [(match_operand:DI 1 "compare_operand" "")
1056 (match_operand:DI 2 "arith_operand" "")]))
1057 (use (match_operand 3 ""))]
1060 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1061 operands[1] = force_reg (DImode, operands[1]);
1062 emit_conditional_branch_insn (operands);
1066 (define_expand "cbranch<F:mode>4"
1067 [(use (match_operator 0 "comparison_operator"
1068 [(match_operand:F 1 "register_operand" "")
1069 (match_operand:F 2 "register_operand" "")]))
1070 (use (match_operand 3 ""))]
1072 { emit_conditional_branch_insn (operands); DONE; })
1075 ;; Now match both normal and inverted jump.
1077 ;; XXX fpcmp nop braindamage
1078 (define_insn "*normal_branch"
1080 (if_then_else (match_operator 0 "noov_compare_operator"
1081 [(reg CC_REG) (const_int 0)])
1082 (label_ref (match_operand 1 "" ""))
1086 return output_cbranch (operands[0], operands[1], 1, 0,
1087 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1090 [(set_attr "type" "branch")
1091 (set_attr "branch_type" "icc")])
1093 ;; XXX fpcmp nop braindamage
1094 (define_insn "*inverted_branch"
1096 (if_then_else (match_operator 0 "noov_compare_operator"
1097 [(reg CC_REG) (const_int 0)])
1099 (label_ref (match_operand 1 "" ""))))]
1102 return output_cbranch (operands[0], operands[1], 1, 1,
1103 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1106 [(set_attr "type" "branch")
1107 (set_attr "branch_type" "icc")])
1109 ;; XXX fpcmp nop braindamage
1110 (define_insn "*normal_fp_branch"
1112 (if_then_else (match_operator 1 "comparison_operator"
1113 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1115 (label_ref (match_operand 2 "" ""))
1119 return output_cbranch (operands[1], operands[2], 2, 0,
1120 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1123 [(set_attr "type" "branch")
1124 (set_attr "branch_type" "fcc")])
1126 ;; XXX fpcmp nop braindamage
1127 (define_insn "*inverted_fp_branch"
1129 (if_then_else (match_operator 1 "comparison_operator"
1130 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1133 (label_ref (match_operand 2 "" ""))))]
1136 return output_cbranch (operands[1], operands[2], 2, 1,
1137 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1140 [(set_attr "type" "branch")
1141 (set_attr "branch_type" "fcc")])
1143 ;; XXX fpcmp nop braindamage
1144 (define_insn "*normal_fpe_branch"
1146 (if_then_else (match_operator 1 "comparison_operator"
1147 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1149 (label_ref (match_operand 2 "" ""))
1153 return output_cbranch (operands[1], operands[2], 2, 0,
1154 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1157 [(set_attr "type" "branch")
1158 (set_attr "branch_type" "fcc")])
1160 ;; XXX fpcmp nop braindamage
1161 (define_insn "*inverted_fpe_branch"
1163 (if_then_else (match_operator 1 "comparison_operator"
1164 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1167 (label_ref (match_operand 2 "" ""))))]
1170 return output_cbranch (operands[1], operands[2], 2, 1,
1171 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1174 [(set_attr "type" "branch")
1175 (set_attr "branch_type" "fcc")])
1177 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1178 ;; in the architecture.
1180 ;; There are no 32 bit brreg insns.
1183 (define_insn "*normal_int_branch_sp64"
1185 (if_then_else (match_operator 0 "v9_register_compare_operator"
1186 [(match_operand:DI 1 "register_operand" "r")
1188 (label_ref (match_operand 2 "" ""))
1192 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1193 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1196 [(set_attr "type" "branch")
1197 (set_attr "branch_type" "reg")])
1200 (define_insn "*inverted_int_branch_sp64"
1202 (if_then_else (match_operator 0 "v9_register_compare_operator"
1203 [(match_operand:DI 1 "register_operand" "r")
1206 (label_ref (match_operand 2 "" ""))))]
1209 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1210 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1213 [(set_attr "type" "branch")
1214 (set_attr "branch_type" "reg")])
1217 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1218 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1219 ;; that adds the PC value at the call point to register #(operand 3).
1221 (define_insn "load_pcrel_sym<P:mode>"
1222 [(set (match_operand:P 0 "register_operand" "=r")
1223 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1224 (match_operand:P 2 "call_address_operand" "")
1225 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1226 (clobber (reg:P O7_REG))]
1227 "REGNO (operands[0]) == INTVAL (operands[3])"
1229 if (flag_delayed_branch)
1230 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1232 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1234 [(set (attr "type") (const_string "multi"))
1235 (set (attr "length")
1236 (if_then_else (eq_attr "delayed_branch" "true")
1241 ;; Integer move instructions
1243 (define_expand "movqi"
1244 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1245 (match_operand:QI 1 "general_operand" ""))]
1248 if (sparc_expand_move (QImode, operands))
1252 (define_insn "*movqi_insn"
1253 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1254 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1255 "(register_operand (operands[0], QImode)
1256 || register_or_zero_operand (operands[1], QImode))"
1261 [(set_attr "type" "*,load,store")
1262 (set_attr "us3load_type" "*,3cycle,*")])
1264 (define_expand "movhi"
1265 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1266 (match_operand:HI 1 "general_operand" ""))]
1269 if (sparc_expand_move (HImode, operands))
1273 (define_insn "*movhi_insn"
1274 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1275 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1276 "(register_operand (operands[0], HImode)
1277 || register_or_zero_operand (operands[1], HImode))"
1280 sethi\t%%hi(%a1), %0
1283 [(set_attr "type" "*,*,load,store")
1284 (set_attr "us3load_type" "*,*,3cycle,*")])
1286 ;; We always work with constants here.
1287 (define_insn "*movhi_lo_sum"
1288 [(set (match_operand:HI 0 "register_operand" "=r")
1289 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1290 (match_operand:HI 2 "small_int_operand" "I")))]
1294 (define_expand "movsi"
1295 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1296 (match_operand:SI 1 "general_operand" ""))]
1299 if (sparc_expand_move (SImode, operands))
1303 (define_insn "*movsi_insn"
1304 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d,d")
1305 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J,P"))]
1306 "(register_operand (operands[0], SImode)
1307 || register_or_zero_or_all_ones_operand (operands[1], SImode))"
1310 sethi\t%%hi(%a1), %0
1318 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")])
1320 (define_insn "*movsi_lo_sum"
1321 [(set (match_operand:SI 0 "register_operand" "=r")
1322 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1323 (match_operand:SI 2 "immediate_operand" "in")))]
1325 "or\t%1, %%lo(%a2), %0")
1327 (define_insn "*movsi_high"
1328 [(set (match_operand:SI 0 "register_operand" "=r")
1329 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1331 "sethi\t%%hi(%a1), %0")
1333 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1334 ;; so that CSE won't optimize the address computation away.
1335 (define_insn "movsi_lo_sum_pic"
1336 [(set (match_operand:SI 0 "register_operand" "=r")
1337 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1338 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1341 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1342 return "xor\t%1, %%gdop_lox10(%a2), %0";
1344 return "or\t%1, %%lo(%a2), %0";
1348 (define_insn "movsi_high_pic"
1349 [(set (match_operand:SI 0 "register_operand" "=r")
1350 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1351 "flag_pic && check_pic (1)"
1353 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1354 return "sethi\t%%gdop_hix22(%a1), %0";
1356 return "sethi\t%%hi(%a1), %0";
1360 (define_insn "movsi_pic_gotdata_op"
1361 [(set (match_operand:SI 0 "register_operand" "=r")
1362 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1363 (match_operand:SI 2 "register_operand" "r")
1364 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1365 "flag_pic && check_pic (1)"
1367 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1368 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1370 return "ld\t[%1 + %2], %0";
1373 [(set_attr "type" "load")])
1375 (define_expand "movsi_pic_label_ref"
1376 [(set (match_dup 3) (high:SI
1377 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1378 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1379 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1380 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1381 (set (match_operand:SI 0 "register_operand" "=r")
1382 (minus:SI (match_dup 5) (match_dup 4)))]
1385 crtl->uses_pic_offset_table = 1;
1386 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1387 if (!can_create_pseudo_p ())
1389 operands[3] = operands[0];
1390 operands[4] = operands[0];
1394 operands[3] = gen_reg_rtx (SImode);
1395 operands[4] = gen_reg_rtx (SImode);
1397 operands[5] = pic_offset_table_rtx;
1400 (define_insn "*movsi_high_pic_label_ref"
1401 [(set (match_operand:SI 0 "register_operand" "=r")
1403 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1404 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1406 "sethi\t%%hi(%a2-(%a1-.)), %0")
1408 (define_insn "*movsi_lo_sum_pic_label_ref"
1409 [(set (match_operand:SI 0 "register_operand" "=r")
1410 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1411 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1412 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1414 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1416 ;; Set up the PIC register for VxWorks.
1418 (define_expand "vxworks_load_got"
1420 (high:SI (match_dup 1)))
1422 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1424 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1425 "TARGET_VXWORKS_RTP"
1427 operands[0] = pic_offset_table_rtx;
1428 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1429 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1432 (define_expand "movdi"
1433 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1434 (match_operand:DI 1 "general_operand" ""))]
1437 if (sparc_expand_move (DImode, operands))
1441 ;; Be careful, fmovd does not exist when !v9.
1442 ;; We match MEM moves directly when we have correct even
1443 ;; numbered registers, but fall into splits otherwise.
1444 ;; The constraint ordering here is really important to
1445 ;; avoid insane problems in reload, especially for patterns
1448 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1449 ;; (const_int -5016)))
1453 (define_insn "*movdi_insn_sp32"
1454 [(set (match_operand:DI 0 "nonimmediate_operand"
1455 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1456 (match_operand:DI 1 "input_operand"
1457 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1459 && (register_operand (operands[0], DImode)
1460 || register_or_zero_operand (operands[1], DImode))"
1474 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1475 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1477 (define_insn "*movdi_insn_sp32_v9"
1478 [(set (match_operand:DI 0 "nonimmediate_operand"
1479 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1480 (match_operand:DI 1 "input_operand"
1481 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1484 && (register_operand (operands[0], DImode)
1485 || register_or_zero_operand (operands[1], DImode))"
1502 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1503 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1504 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1506 (define_insn "*movdi_insn_sp64"
1507 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b,b")
1508 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J,P"))]
1510 && (register_operand (operands[0], DImode)
1511 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1514 sethi\t%%hi(%a1), %0
1522 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")
1523 (set_attr "fptype" "*,*,*,*,double,*,*,double,double")])
1525 (define_expand "movdi_pic_label_ref"
1526 [(set (match_dup 3) (high:DI
1527 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1528 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1529 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1530 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1531 (set (match_operand:DI 0 "register_operand" "=r")
1532 (minus:DI (match_dup 5) (match_dup 4)))]
1533 "TARGET_ARCH64 && flag_pic"
1535 crtl->uses_pic_offset_table = 1;
1536 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1537 if (!can_create_pseudo_p ())
1539 operands[3] = operands[0];
1540 operands[4] = operands[0];
1544 operands[3] = gen_reg_rtx (DImode);
1545 operands[4] = gen_reg_rtx (DImode);
1547 operands[5] = pic_offset_table_rtx;
1550 (define_insn "*movdi_high_pic_label_ref"
1551 [(set (match_operand:DI 0 "register_operand" "=r")
1553 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1554 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1555 "TARGET_ARCH64 && flag_pic"
1556 "sethi\t%%hi(%a2-(%a1-.)), %0")
1558 (define_insn "*movdi_lo_sum_pic_label_ref"
1559 [(set (match_operand:DI 0 "register_operand" "=r")
1560 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1561 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1562 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1563 "TARGET_ARCH64 && flag_pic"
1564 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1566 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1567 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1569 (define_insn "movdi_lo_sum_pic"
1570 [(set (match_operand:DI 0 "register_operand" "=r")
1571 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1572 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1573 "TARGET_ARCH64 && flag_pic"
1575 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1576 return "xor\t%1, %%gdop_lox10(%a2), %0";
1578 return "or\t%1, %%lo(%a2), %0";
1582 (define_insn "movdi_high_pic"
1583 [(set (match_operand:DI 0 "register_operand" "=r")
1584 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1585 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1587 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1588 return "sethi\t%%gdop_hix22(%a1), %0";
1590 return "sethi\t%%hi(%a1), %0";
1594 (define_insn "movdi_pic_gotdata_op"
1595 [(set (match_operand:DI 0 "register_operand" "=r")
1596 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1597 (match_operand:DI 2 "register_operand" "r")
1598 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1599 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1601 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1602 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1604 return "ldx\t[%1 + %2], %0";
1607 [(set_attr "type" "load")])
1609 (define_insn "*sethi_di_medlow_embmedany_pic"
1610 [(set (match_operand:DI 0 "register_operand" "=r")
1611 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1612 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1613 "sethi\t%%hi(%a1), %0")
1615 (define_insn "*sethi_di_medlow"
1616 [(set (match_operand:DI 0 "register_operand" "=r")
1617 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1618 "TARGET_CM_MEDLOW && check_pic (1)"
1619 "sethi\t%%hi(%a1), %0")
1621 (define_insn "*losum_di_medlow"
1622 [(set (match_operand:DI 0 "register_operand" "=r")
1623 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1624 (match_operand:DI 2 "symbolic_operand" "")))]
1626 "or\t%1, %%lo(%a2), %0")
1628 (define_insn "seth44"
1629 [(set (match_operand:DI 0 "register_operand" "=r")
1630 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1632 "sethi\t%%h44(%a1), %0")
1634 (define_insn "setm44"
1635 [(set (match_operand:DI 0 "register_operand" "=r")
1636 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1637 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1639 "or\t%1, %%m44(%a2), %0")
1641 (define_insn "setl44"
1642 [(set (match_operand:DI 0 "register_operand" "=r")
1643 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1644 (match_operand:DI 2 "symbolic_operand" "")))]
1646 "or\t%1, %%l44(%a2), %0")
1648 (define_insn "sethh"
1649 [(set (match_operand:DI 0 "register_operand" "=r")
1650 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1652 "sethi\t%%hh(%a1), %0")
1654 (define_insn "setlm"
1655 [(set (match_operand:DI 0 "register_operand" "=r")
1656 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1658 "sethi\t%%lm(%a1), %0")
1660 (define_insn "sethm"
1661 [(set (match_operand:DI 0 "register_operand" "=r")
1662 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1663 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1665 "or\t%1, %%hm(%a2), %0")
1667 (define_insn "setlo"
1668 [(set (match_operand:DI 0 "register_operand" "=r")
1669 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1670 (match_operand:DI 2 "symbolic_operand" "")))]
1672 "or\t%1, %%lo(%a2), %0")
1674 (define_insn "embmedany_sethi"
1675 [(set (match_operand:DI 0 "register_operand" "=r")
1676 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1677 "TARGET_CM_EMBMEDANY && check_pic (1)"
1678 "sethi\t%%hi(%a1), %0")
1680 (define_insn "embmedany_losum"
1681 [(set (match_operand:DI 0 "register_operand" "=r")
1682 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1683 (match_operand:DI 2 "data_segment_operand" "")))]
1684 "TARGET_CM_EMBMEDANY"
1685 "add\t%1, %%lo(%a2), %0")
1687 (define_insn "embmedany_brsum"
1688 [(set (match_operand:DI 0 "register_operand" "=r")
1689 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1690 "TARGET_CM_EMBMEDANY"
1693 (define_insn "embmedany_textuhi"
1694 [(set (match_operand:DI 0 "register_operand" "=r")
1695 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1696 "TARGET_CM_EMBMEDANY && check_pic (1)"
1697 "sethi\t%%uhi(%a1), %0")
1699 (define_insn "embmedany_texthi"
1700 [(set (match_operand:DI 0 "register_operand" "=r")
1701 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1702 "TARGET_CM_EMBMEDANY && check_pic (1)"
1703 "sethi\t%%hi(%a1), %0")
1705 (define_insn "embmedany_textulo"
1706 [(set (match_operand:DI 0 "register_operand" "=r")
1707 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1708 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1709 "TARGET_CM_EMBMEDANY"
1710 "or\t%1, %%ulo(%a2), %0")
1712 (define_insn "embmedany_textlo"
1713 [(set (match_operand:DI 0 "register_operand" "=r")
1714 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1715 (match_operand:DI 2 "text_segment_operand" "")))]
1716 "TARGET_CM_EMBMEDANY"
1717 "or\t%1, %%lo(%a2), %0")
1719 ;; Now some patterns to help reload out a bit.
1720 (define_expand "reload_indi"
1721 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1722 (match_operand:DI 1 "immediate_operand" "")
1723 (match_operand:TI 2 "register_operand" "=&r")])]
1725 || TARGET_CM_EMBMEDANY)
1728 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1732 (define_expand "reload_outdi"
1733 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1734 (match_operand:DI 1 "immediate_operand" "")
1735 (match_operand:TI 2 "register_operand" "=&r")])]
1737 || TARGET_CM_EMBMEDANY)
1740 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1744 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1746 [(set (match_operand:DI 0 "register_operand" "")
1747 (match_operand:DI 1 "const_int_operand" ""))]
1748 "! TARGET_ARCH64 && reload_completed"
1749 [(clobber (const_int 0))]
1751 #if HOST_BITS_PER_WIDE_INT == 32
1752 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1753 (INTVAL (operands[1]) < 0) ?
1756 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1759 unsigned int low, high;
1761 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1762 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1763 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1765 /* Slick... but this trick loses if this subreg constant part
1766 can be done in one insn. */
1768 && ! SPARC_SETHI32_P (high)
1769 && ! SPARC_SIMM13_P (high))
1770 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1771 gen_highpart (SImode, operands[0])));
1773 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1779 [(set (match_operand:DI 0 "register_operand" "")
1780 (match_operand:DI 1 "const_double_operand" ""))]
1784 && ((GET_CODE (operands[0]) == REG
1785 && REGNO (operands[0]) < 32)
1786 || (GET_CODE (operands[0]) == SUBREG
1787 && GET_CODE (SUBREG_REG (operands[0])) == REG
1788 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1789 [(clobber (const_int 0))]
1791 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1792 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1794 /* Slick... but this trick loses if this subreg constant part
1795 can be done in one insn. */
1796 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1797 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1798 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1800 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1801 gen_highpart (SImode, operands[0])));
1805 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1806 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1812 [(set (match_operand:DI 0 "register_operand" "")
1813 (match_operand:DI 1 "register_operand" ""))]
1817 && ((GET_CODE (operands[0]) == REG
1818 && REGNO (operands[0]) < 32)
1819 || (GET_CODE (operands[0]) == SUBREG
1820 && GET_CODE (SUBREG_REG (operands[0])) == REG
1821 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1822 [(clobber (const_int 0))]
1824 rtx set_dest = operands[0];
1825 rtx set_src = operands[1];
1829 dest1 = gen_highpart (SImode, set_dest);
1830 dest2 = gen_lowpart (SImode, set_dest);
1831 src1 = gen_highpart (SImode, set_src);
1832 src2 = gen_lowpart (SImode, set_src);
1834 /* Now emit using the real source and destination we found, swapping
1835 the order if we detect overlap. */
1836 if (reg_overlap_mentioned_p (dest1, src2))
1838 emit_insn (gen_movsi (dest2, src2));
1839 emit_insn (gen_movsi (dest1, src1));
1843 emit_insn (gen_movsi (dest1, src1));
1844 emit_insn (gen_movsi (dest2, src2));
1849 ;; Now handle the cases of memory moves from/to non-even
1850 ;; DI mode register pairs.
1852 [(set (match_operand:DI 0 "register_operand" "")
1853 (match_operand:DI 1 "memory_operand" ""))]
1856 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1857 [(clobber (const_int 0))]
1859 rtx word0 = adjust_address (operands[1], SImode, 0);
1860 rtx word1 = adjust_address (operands[1], SImode, 4);
1861 rtx high_part = gen_highpart (SImode, operands[0]);
1862 rtx low_part = gen_lowpart (SImode, operands[0]);
1864 if (reg_overlap_mentioned_p (high_part, word1))
1866 emit_insn (gen_movsi (low_part, word1));
1867 emit_insn (gen_movsi (high_part, word0));
1871 emit_insn (gen_movsi (high_part, word0));
1872 emit_insn (gen_movsi (low_part, word1));
1878 [(set (match_operand:DI 0 "memory_operand" "")
1879 (match_operand:DI 1 "register_operand" ""))]
1882 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1883 [(clobber (const_int 0))]
1885 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1886 gen_highpart (SImode, operands[1])));
1887 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1888 gen_lowpart (SImode, operands[1])));
1893 [(set (match_operand:DI 0 "memory_operand" "")
1894 (match_operand:DI 1 "const_zero_operand" ""))]
1898 && ! mem_min_alignment (operands[0], 8)))
1899 && offsettable_memref_p (operands[0])"
1900 [(clobber (const_int 0))]
1902 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1903 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1908 ;; Floating point and vector move instructions
1910 ;; Yes, you guessed it right, the former movsf expander.
1911 (define_expand "mov<V32:mode>"
1912 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1913 (match_operand:V32 1 "general_operand" ""))]
1914 "<V32:MODE>mode == SFmode || TARGET_VIS"
1916 if (sparc_expand_move (<V32:MODE>mode, operands))
1920 (define_insn "*movsf_insn"
1921 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,d,f,*r,*r,*r,f,*r,m,m")
1922 (match_operand:V32 1 "input_operand" "GY,ZC,f,*rRY,Q,S,m,m,f,*rGY"))]
1924 && (register_operand (operands[0], <V32:MODE>mode)
1925 || register_or_zero_or_all_ones_operand (operands[1], <V32:MODE>mode))"
1927 if (GET_CODE (operands[1]) == CONST_DOUBLE
1928 && (which_alternative == 3
1929 || which_alternative == 4
1930 || which_alternative == 5))
1935 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1936 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1937 operands[1] = GEN_INT (i);
1940 switch (which_alternative)
1943 return "fzeros\t%0";
1947 return "fmovs\t%1, %0";
1949 return "mov\t%1, %0";
1951 return "sethi\t%%hi(%a1), %0";
1956 return "ld\t%1, %0";
1959 return "st\t%r1, %0";
1964 [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1966 ;; Exactly the same as above, except that all `f' cases are deleted.
1967 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1970 (define_insn "*movsf_insn_no_fpu"
1971 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1972 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1974 && (register_operand (operands[0], SFmode)
1975 || register_or_zero_operand (operands[1], SFmode))"
1977 if (GET_CODE (operands[1]) == CONST_DOUBLE
1978 && (which_alternative == 0
1979 || which_alternative == 1
1980 || which_alternative == 2))
1985 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1986 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1987 operands[1] = GEN_INT (i);
1990 switch (which_alternative)
1993 return "mov\t%1, %0";
1995 return "sethi\t%%hi(%a1), %0";
1999 return "ld\t%1, %0";
2001 return "st\t%r1, %0";
2006 [(set_attr "type" "*,*,*,load,store")])
2008 ;; The following 3 patterns build SFmode constants in integer registers.
2010 (define_insn "*movsf_lo_sum"
2011 [(set (match_operand:SF 0 "register_operand" "=r")
2012 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2013 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2019 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2020 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2021 operands[2] = GEN_INT (i);
2022 return "or\t%1, %%lo(%a2), %0";
2025 (define_insn "*movsf_high"
2026 [(set (match_operand:SF 0 "register_operand" "=r")
2027 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2033 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2034 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2035 operands[1] = GEN_INT (i);
2036 return "sethi\t%%hi(%1), %0";
2040 [(set (match_operand:SF 0 "register_operand" "")
2041 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2042 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2043 [(set (match_dup 0) (high:SF (match_dup 1)))
2044 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2046 ;; Yes, you again guessed it right, the former movdf expander.
2047 (define_expand "mov<V64:mode>"
2048 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2049 (match_operand:V64 1 "general_operand" ""))]
2050 "<V64:MODE>mode == DFmode || TARGET_VIS"
2052 if (sparc_expand_move (<V64:MODE>mode, operands))
2056 ;; Be careful, fmovd does not exist when !v9.
2057 (define_insn "*movdf_insn_sp32"
2058 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2059 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2062 && (register_operand (operands[0], DFmode)
2063 || register_or_zero_operand (operands[1], DFmode))"
2075 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2076 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2078 (define_insn "*movdf_insn_sp32_no_fpu"
2079 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2080 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2083 && (register_operand (operands[0], DFmode)
2084 || register_or_zero_operand (operands[1], DFmode))"
2091 [(set_attr "type" "load,store,*,*,*")
2092 (set_attr "length" "*,*,2,2,2")])
2094 ;; We have available v9 double floats but not 64-bit integer registers.
2095 (define_insn "*movdf_insn_sp32_v9"
2096 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,T,W,U,T,f,*r,o")
2097 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2101 && (register_operand (operands[0], <V64:MODE>mode)
2102 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2115 [(set_attr "type" "fga,fga,fpmove,load,store,store,load,store,*,*,*")
2116 (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")
2117 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*")])
2119 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2120 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2121 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2125 && (register_operand (operands[0], DFmode)
2126 || register_or_zero_operand (operands[1], DFmode))"
2133 [(set_attr "type" "load,store,store,*,*")
2134 (set_attr "length" "*,*,*,2,2")])
2136 ;; We have available both v9 double floats and 64-bit integer registers.
2137 (define_insn "*movdf_insn_sp64"
2138 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,W,*r,*r,m,*r")
2139 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,e,*rGY,m,*rGY,DF"))]
2142 && (register_operand (operands[0], <V64:MODE>mode)
2143 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2154 [(set_attr "type" "fga,fga,fpmove,load,store,*,load,store,*")
2155 (set_attr "length" "*,*,*,*,*,*,*,*,2")
2156 (set_attr "fptype" "double,double,double,*,*,*,*,*,*")])
2158 (define_insn "*movdf_insn_sp64_no_fpu"
2159 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2160 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2163 && (register_operand (operands[0], DFmode)
2164 || register_or_zero_operand (operands[1], DFmode))"
2169 [(set_attr "type" "*,load,store")])
2171 ;; This pattern builds V64mode constants in integer registers.
2173 [(set (match_operand:V64 0 "register_operand" "")
2174 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2176 && (GET_CODE (operands[0]) == REG
2177 && REGNO (operands[0]) < 32)
2178 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2179 && reload_completed"
2180 [(clobber (const_int 0))]
2182 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2186 #if HOST_BITS_PER_WIDE_INT == 32
2189 enum machine_mode mode = GET_MODE (operands[1]);
2190 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2191 emit_insn (gen_movdi (operands[0], tem));
2196 enum machine_mode mode = GET_MODE (operands[1]);
2197 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2198 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2200 gcc_assert (GET_CODE (hi) == CONST_INT);
2201 gcc_assert (GET_CODE (lo) == CONST_INT);
2203 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2205 /* Slick... but this trick loses if this subreg constant part
2206 can be done in one insn. */
2208 && ! SPARC_SETHI32_P (INTVAL (hi))
2209 && ! SPARC_SIMM13_P (INTVAL (hi)))
2211 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2212 gen_highpart (SImode, operands[0])));
2216 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2222 ;; Ok, now the splits to handle all the multi insn and
2223 ;; mis-aligned memory address cases.
2224 ;; In these splits please take note that we must be
2225 ;; careful when V9 but not ARCH64 because the integer
2226 ;; register DFmode cases must be handled.
2228 [(set (match_operand:V64 0 "register_operand" "")
2229 (match_operand:V64 1 "register_operand" ""))]
2232 && ((GET_CODE (operands[0]) == REG
2233 && REGNO (operands[0]) < 32)
2234 || (GET_CODE (operands[0]) == SUBREG
2235 && GET_CODE (SUBREG_REG (operands[0])) == REG
2236 && REGNO (SUBREG_REG (operands[0])) < 32))))
2237 && reload_completed"
2238 [(clobber (const_int 0))]
2240 rtx set_dest = operands[0];
2241 rtx set_src = operands[1];
2244 enum machine_mode half_mode;
2246 /* We can be expanded for DFmode or integral vector modes. */
2247 if (<V64:MODE>mode == DFmode)
2252 dest1 = gen_highpart (half_mode, set_dest);
2253 dest2 = gen_lowpart (half_mode, set_dest);
2254 src1 = gen_highpart (half_mode, set_src);
2255 src2 = gen_lowpart (half_mode, set_src);
2257 /* Now emit using the real source and destination we found, swapping
2258 the order if we detect overlap. */
2259 if (reg_overlap_mentioned_p (dest1, src2))
2261 emit_move_insn_1 (dest2, src2);
2262 emit_move_insn_1 (dest1, src1);
2266 emit_move_insn_1 (dest1, src1);
2267 emit_move_insn_1 (dest2, src2);
2273 [(set (match_operand:V64 0 "register_operand" "")
2274 (match_operand:V64 1 "memory_operand" ""))]
2277 && (((REGNO (operands[0]) % 2) != 0)
2278 || ! mem_min_alignment (operands[1], 8))
2279 && offsettable_memref_p (operands[1])"
2280 [(clobber (const_int 0))]
2282 enum machine_mode half_mode;
2285 /* We can be expanded for DFmode or integral vector modes. */
2286 if (<V64:MODE>mode == DFmode)
2291 word0 = adjust_address (operands[1], half_mode, 0);
2292 word1 = adjust_address (operands[1], half_mode, 4);
2294 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2296 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2297 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2301 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2302 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2308 [(set (match_operand:V64 0 "memory_operand" "")
2309 (match_operand:V64 1 "register_operand" ""))]
2312 && (((REGNO (operands[1]) % 2) != 0)
2313 || ! mem_min_alignment (operands[0], 8))
2314 && offsettable_memref_p (operands[0])"
2315 [(clobber (const_int 0))]
2317 enum machine_mode half_mode;
2320 /* We can be expanded for DFmode or integral vector modes. */
2321 if (<V64:MODE>mode == DFmode)
2326 word0 = adjust_address (operands[0], half_mode, 0);
2327 word1 = adjust_address (operands[0], half_mode, 4);
2329 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2330 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2335 [(set (match_operand:V64 0 "memory_operand" "")
2336 (match_operand:V64 1 "const_zero_operand" ""))]
2340 && ! mem_min_alignment (operands[0], 8)))
2341 && offsettable_memref_p (operands[0])"
2342 [(clobber (const_int 0))]
2344 enum machine_mode half_mode;
2347 /* We can be expanded for DFmode or integral vector modes. */
2348 if (<V64:MODE>mode == DFmode)
2353 dest1 = adjust_address (operands[0], half_mode, 0);
2354 dest2 = adjust_address (operands[0], half_mode, 4);
2356 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2357 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2362 [(set (match_operand:V64 0 "register_operand" "")
2363 (match_operand:V64 1 "const_zero_operand" ""))]
2366 && ((GET_CODE (operands[0]) == REG
2367 && REGNO (operands[0]) < 32)
2368 || (GET_CODE (operands[0]) == SUBREG
2369 && GET_CODE (SUBREG_REG (operands[0])) == REG
2370 && REGNO (SUBREG_REG (operands[0])) < 32))"
2371 [(clobber (const_int 0))]
2373 enum machine_mode half_mode;
2374 rtx set_dest = operands[0];
2377 /* We can be expanded for DFmode or integral vector modes. */
2378 if (<V64:MODE>mode == DFmode)
2383 dest1 = gen_highpart (half_mode, set_dest);
2384 dest2 = gen_lowpart (half_mode, set_dest);
2385 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2386 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2390 (define_expand "movtf"
2391 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2392 (match_operand:TF 1 "general_operand" ""))]
2395 if (sparc_expand_move (TFmode, operands))
2399 (define_insn "*movtf_insn_sp32"
2400 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2401 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2404 && (register_operand (operands[0], TFmode)
2405 || register_or_zero_operand (operands[1], TFmode))"
2407 [(set_attr "length" "4")])
2409 ;; Exactly the same as above, except that all `e' cases are deleted.
2410 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2413 (define_insn "*movtf_insn_sp32_no_fpu"
2414 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2415 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2418 && (register_operand (operands[0], TFmode)
2419 || register_or_zero_operand (operands[1], TFmode))"
2421 [(set_attr "length" "4")])
2423 (define_insn "*movtf_insn_sp64"
2424 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2425 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2428 && ! TARGET_HARD_QUAD
2429 && (register_operand (operands[0], TFmode)
2430 || register_or_zero_operand (operands[1], TFmode))"
2432 [(set_attr "length" "2")])
2434 (define_insn "*movtf_insn_sp64_hq"
2435 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2436 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2440 && (register_operand (operands[0], TFmode)
2441 || register_or_zero_operand (operands[1], TFmode))"
2449 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2450 (set_attr "length" "2,*,*,*,2,2")])
2452 (define_insn "*movtf_insn_sp64_no_fpu"
2453 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2454 (match_operand:TF 1 "input_operand" "orG,rG"))]
2457 && (register_operand (operands[0], TFmode)
2458 || register_or_zero_operand (operands[1], TFmode))"
2460 [(set_attr "length" "2")])
2462 ;; Now all the splits to handle multi-insn TF mode moves.
2464 [(set (match_operand:TF 0 "register_operand" "")
2465 (match_operand:TF 1 "register_operand" ""))]
2469 && ! TARGET_HARD_QUAD)
2470 || ! fp_register_operand (operands[0], TFmode))"
2471 [(clobber (const_int 0))]
2473 rtx set_dest = operands[0];
2474 rtx set_src = operands[1];
2478 dest1 = gen_df_reg (set_dest, 0);
2479 dest2 = gen_df_reg (set_dest, 1);
2480 src1 = gen_df_reg (set_src, 0);
2481 src2 = gen_df_reg (set_src, 1);
2483 /* Now emit using the real source and destination we found, swapping
2484 the order if we detect overlap. */
2485 if (reg_overlap_mentioned_p (dest1, src2))
2487 emit_insn (gen_movdf (dest2, src2));
2488 emit_insn (gen_movdf (dest1, src1));
2492 emit_insn (gen_movdf (dest1, src1));
2493 emit_insn (gen_movdf (dest2, src2));
2499 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2500 (match_operand:TF 1 "const_zero_operand" ""))]
2502 [(clobber (const_int 0))]
2504 rtx set_dest = operands[0];
2507 switch (GET_CODE (set_dest))
2510 dest1 = gen_df_reg (set_dest, 0);
2511 dest2 = gen_df_reg (set_dest, 1);
2514 dest1 = adjust_address (set_dest, DFmode, 0);
2515 dest2 = adjust_address (set_dest, DFmode, 8);
2521 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2522 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2527 [(set (match_operand:TF 0 "register_operand" "")
2528 (match_operand:TF 1 "memory_operand" ""))]
2530 && offsettable_memref_p (operands[1])
2532 || ! TARGET_HARD_QUAD
2533 || ! fp_register_operand (operands[0], TFmode)))"
2534 [(clobber (const_int 0))]
2536 rtx word0 = adjust_address (operands[1], DFmode, 0);
2537 rtx word1 = adjust_address (operands[1], DFmode, 8);
2538 rtx set_dest, dest1, dest2;
2540 set_dest = operands[0];
2542 dest1 = gen_df_reg (set_dest, 0);
2543 dest2 = gen_df_reg (set_dest, 1);
2545 /* Now output, ordering such that we don't clobber any registers
2546 mentioned in the address. */
2547 if (reg_overlap_mentioned_p (dest1, word1))
2550 emit_insn (gen_movdf (dest2, word1));
2551 emit_insn (gen_movdf (dest1, word0));
2555 emit_insn (gen_movdf (dest1, word0));
2556 emit_insn (gen_movdf (dest2, word1));
2562 [(set (match_operand:TF 0 "memory_operand" "")
2563 (match_operand:TF 1 "register_operand" ""))]
2565 && offsettable_memref_p (operands[0])
2567 || ! TARGET_HARD_QUAD
2568 || ! fp_register_operand (operands[1], TFmode)))"
2569 [(clobber (const_int 0))]
2571 rtx set_src = operands[1];
2573 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2574 gen_df_reg (set_src, 0)));
2575 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2576 gen_df_reg (set_src, 1)));
2581 ;; SPARC-V9 conditional move instructions
2583 ;; We can handle larger constants here for some flavors, but for now we keep
2584 ;; it simple and only allow those constants supported by all flavors.
2585 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2586 ;; 3 contains the constant if one is present, but we handle either for
2587 ;; generality (sparc.c puts a constant in operand 2).
2589 (define_expand "mov<I:mode>cc"
2590 [(set (match_operand:I 0 "register_operand" "")
2591 (if_then_else:I (match_operand 1 "comparison_operator" "")
2592 (match_operand:I 2 "arith10_operand" "")
2593 (match_operand:I 3 "arith10_operand" "")))]
2594 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2596 enum rtx_code code = GET_CODE (operands[1]);
2599 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2603 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2605 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2606 GET_CODE (operands[1]));
2608 if (XEXP (operands[1], 1) == const0_rtx
2609 && GET_CODE (XEXP (operands[1], 0)) == REG
2610 && GET_MODE (XEXP (operands[1], 0)) == DImode
2611 && v9_regcmp_p (code))
2612 cc_reg = XEXP (operands[1], 0);
2614 cc_reg = gen_compare_reg (operands[1]);
2616 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2619 (define_expand "mov<F:mode>cc"
2620 [(set (match_operand:F 0 "register_operand" "")
2621 (if_then_else:F (match_operand 1 "comparison_operator" "")
2622 (match_operand:F 2 "register_operand" "")
2623 (match_operand:F 3 "register_operand" "")))]
2624 "TARGET_V9 && TARGET_FPU"
2626 enum rtx_code code = GET_CODE (operands[1]);
2629 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2633 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2635 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2636 GET_CODE (operands[1]));
2638 if (XEXP (operands[1], 1) == const0_rtx
2639 && GET_CODE (XEXP (operands[1], 0)) == REG
2640 && GET_MODE (XEXP (operands[1], 0)) == DImode
2641 && v9_regcmp_p (code))
2642 cc_reg = XEXP (operands[1], 0);
2644 cc_reg = gen_compare_reg (operands[1]);
2646 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2649 ;; Conditional move define_insns
2651 (define_insn "*mov<I:mode>_cc_v9"
2652 [(set (match_operand:I 0 "register_operand" "=r,r")
2653 (if_then_else:I (match_operator 1 "comparison_operator"
2654 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2656 (match_operand:I 3 "arith11_operand" "rL,0")
2657 (match_operand:I 4 "arith11_operand" "0,rL")))]
2658 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2661 mov%c1\t%x2, %4, %0"
2662 [(set_attr "type" "cmove")])
2664 (define_insn "*mov<I:mode>_cc_reg_sp64"
2665 [(set (match_operand:I 0 "register_operand" "=r,r")
2666 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2667 [(match_operand:DI 2 "register_operand" "r,r")
2669 (match_operand:I 3 "arith10_operand" "rM,0")
2670 (match_operand:I 4 "arith10_operand" "0,rM")))]
2673 movr%D1\t%2, %r3, %0
2674 movr%d1\t%2, %r4, %0"
2675 [(set_attr "type" "cmove")])
2677 (define_insn "*movsf_cc_v9"
2678 [(set (match_operand:SF 0 "register_operand" "=f,f")
2679 (if_then_else:SF (match_operator 1 "comparison_operator"
2680 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2682 (match_operand:SF 3 "register_operand" "f,0")
2683 (match_operand:SF 4 "register_operand" "0,f")))]
2684 "TARGET_V9 && TARGET_FPU"
2686 fmovs%C1\t%x2, %3, %0
2687 fmovs%c1\t%x2, %4, %0"
2688 [(set_attr "type" "fpcmove")])
2690 (define_insn "*movsf_cc_reg_sp64"
2691 [(set (match_operand:SF 0 "register_operand" "=f,f")
2692 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2693 [(match_operand:DI 2 "register_operand" "r,r")
2695 (match_operand:SF 3 "register_operand" "f,0")
2696 (match_operand:SF 4 "register_operand" "0,f")))]
2697 "TARGET_ARCH64 && TARGET_FPU"
2699 fmovrs%D1\t%2, %3, %0
2700 fmovrs%d1\t%2, %4, %0"
2701 [(set_attr "type" "fpcrmove")])
2703 ;; Named because invoked by movtf_cc_v9
2704 (define_insn "movdf_cc_v9"
2705 [(set (match_operand:DF 0 "register_operand" "=e,e")
2706 (if_then_else:DF (match_operator 1 "comparison_operator"
2707 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2709 (match_operand:DF 3 "register_operand" "e,0")
2710 (match_operand:DF 4 "register_operand" "0,e")))]
2711 "TARGET_V9 && TARGET_FPU"
2713 fmovd%C1\t%x2, %3, %0
2714 fmovd%c1\t%x2, %4, %0"
2715 [(set_attr "type" "fpcmove")
2716 (set_attr "fptype" "double")])
2718 ;; Named because invoked by movtf_cc_reg_sp64
2719 (define_insn "movdf_cc_reg_sp64"
2720 [(set (match_operand:DF 0 "register_operand" "=e,e")
2721 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2722 [(match_operand:DI 2 "register_operand" "r,r")
2724 (match_operand:DF 3 "register_operand" "e,0")
2725 (match_operand:DF 4 "register_operand" "0,e")))]
2726 "TARGET_ARCH64 && TARGET_FPU"
2728 fmovrd%D1\t%2, %3, %0
2729 fmovrd%d1\t%2, %4, %0"
2730 [(set_attr "type" "fpcrmove")
2731 (set_attr "fptype" "double")])
2733 (define_insn "*movtf_cc_hq_v9"
2734 [(set (match_operand:TF 0 "register_operand" "=e,e")
2735 (if_then_else:TF (match_operator 1 "comparison_operator"
2736 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2738 (match_operand:TF 3 "register_operand" "e,0")
2739 (match_operand:TF 4 "register_operand" "0,e")))]
2740 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2742 fmovq%C1\t%x2, %3, %0
2743 fmovq%c1\t%x2, %4, %0"
2744 [(set_attr "type" "fpcmove")])
2746 (define_insn "*movtf_cc_reg_hq_sp64"
2747 [(set (match_operand:TF 0 "register_operand" "=e,e")
2748 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2749 [(match_operand:DI 2 "register_operand" "r,r")
2751 (match_operand:TF 3 "register_operand" "e,0")
2752 (match_operand:TF 4 "register_operand" "0,e")))]
2753 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2755 fmovrq%D1\t%2, %3, %0
2756 fmovrq%d1\t%2, %4, %0"
2757 [(set_attr "type" "fpcrmove")])
2759 (define_insn_and_split "*movtf_cc_v9"
2760 [(set (match_operand:TF 0 "register_operand" "=e,e")
2761 (if_then_else:TF (match_operator 1 "comparison_operator"
2762 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2764 (match_operand:TF 3 "register_operand" "e,0")
2765 (match_operand:TF 4 "register_operand" "0,e")))]
2766 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2768 "&& reload_completed"
2769 [(clobber (const_int 0))]
2771 rtx set_dest = operands[0];
2772 rtx set_srca = operands[3];
2773 rtx set_srcb = operands[4];
2774 int third = rtx_equal_p (set_dest, set_srca);
2776 rtx srca1, srca2, srcb1, srcb2;
2778 dest1 = gen_df_reg (set_dest, 0);
2779 dest2 = gen_df_reg (set_dest, 1);
2780 srca1 = gen_df_reg (set_srca, 0);
2781 srca2 = gen_df_reg (set_srca, 1);
2782 srcb1 = gen_df_reg (set_srcb, 0);
2783 srcb2 = gen_df_reg (set_srcb, 1);
2785 /* Now emit using the real source and destination we found, swapping
2786 the order if we detect overlap. */
2787 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2788 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2790 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2791 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2795 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2796 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2800 [(set_attr "length" "2")])
2802 (define_insn_and_split "*movtf_cc_reg_sp64"
2803 [(set (match_operand:TF 0 "register_operand" "=e,e")
2804 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2805 [(match_operand:DI 2 "register_operand" "r,r")
2807 (match_operand:TF 3 "register_operand" "e,0")
2808 (match_operand:TF 4 "register_operand" "0,e")))]
2809 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2811 "&& reload_completed"
2812 [(clobber (const_int 0))]
2814 rtx set_dest = operands[0];
2815 rtx set_srca = operands[3];
2816 rtx set_srcb = operands[4];
2817 int third = rtx_equal_p (set_dest, set_srca);
2819 rtx srca1, srca2, srcb1, srcb2;
2821 dest1 = gen_df_reg (set_dest, 0);
2822 dest2 = gen_df_reg (set_dest, 1);
2823 srca1 = gen_df_reg (set_srca, 0);
2824 srca2 = gen_df_reg (set_srca, 1);
2825 srcb1 = gen_df_reg (set_srcb, 0);
2826 srcb2 = gen_df_reg (set_srcb, 1);
2828 /* Now emit using the real source and destination we found, swapping
2829 the order if we detect overlap. */
2830 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2831 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2833 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2834 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2838 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2839 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2843 [(set_attr "length" "2")])
2846 ;; Zero-extension instructions
2848 ;; These patterns originally accepted general_operands, however, slightly
2849 ;; better code is generated by only accepting register_operands, and then
2850 ;; letting combine generate the ldu[hb] insns.
2852 (define_expand "zero_extendhisi2"
2853 [(set (match_operand:SI 0 "register_operand" "")
2854 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2857 rtx temp = gen_reg_rtx (SImode);
2858 rtx shift_16 = GEN_INT (16);
2859 int op1_subbyte = 0;
2861 if (GET_CODE (operand1) == SUBREG)
2863 op1_subbyte = SUBREG_BYTE (operand1);
2864 op1_subbyte /= GET_MODE_SIZE (SImode);
2865 op1_subbyte *= GET_MODE_SIZE (SImode);
2866 operand1 = XEXP (operand1, 0);
2869 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2871 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2875 (define_insn "*zero_extendhisi2_insn"
2876 [(set (match_operand:SI 0 "register_operand" "=r")
2877 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2880 [(set_attr "type" "load")
2881 (set_attr "us3load_type" "3cycle")])
2883 (define_expand "zero_extendqihi2"
2884 [(set (match_operand:HI 0 "register_operand" "")
2885 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2889 (define_insn "*zero_extendqihi2_insn"
2890 [(set (match_operand:HI 0 "register_operand" "=r,r")
2891 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2892 "GET_CODE (operands[1]) != CONST_INT"
2896 [(set_attr "type" "*,load")
2897 (set_attr "us3load_type" "*,3cycle")])
2899 (define_expand "zero_extendqisi2"
2900 [(set (match_operand:SI 0 "register_operand" "")
2901 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2905 (define_insn "*zero_extendqisi2_insn"
2906 [(set (match_operand:SI 0 "register_operand" "=r,r")
2907 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2908 "GET_CODE (operands[1]) != CONST_INT"
2912 [(set_attr "type" "*,load")
2913 (set_attr "us3load_type" "*,3cycle")])
2915 (define_expand "zero_extendqidi2"
2916 [(set (match_operand:DI 0 "register_operand" "")
2917 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2921 (define_insn "*zero_extendqidi2_insn"
2922 [(set (match_operand:DI 0 "register_operand" "=r,r")
2923 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2924 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2928 [(set_attr "type" "*,load")
2929 (set_attr "us3load_type" "*,3cycle")])
2931 (define_expand "zero_extendhidi2"
2932 [(set (match_operand:DI 0 "register_operand" "")
2933 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2936 rtx temp = gen_reg_rtx (DImode);
2937 rtx shift_48 = GEN_INT (48);
2938 int op1_subbyte = 0;
2940 if (GET_CODE (operand1) == SUBREG)
2942 op1_subbyte = SUBREG_BYTE (operand1);
2943 op1_subbyte /= GET_MODE_SIZE (DImode);
2944 op1_subbyte *= GET_MODE_SIZE (DImode);
2945 operand1 = XEXP (operand1, 0);
2948 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2950 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2954 (define_insn "*zero_extendhidi2_insn"
2955 [(set (match_operand:DI 0 "register_operand" "=r")
2956 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2959 [(set_attr "type" "load")
2960 (set_attr "us3load_type" "3cycle")])
2962 ;; ??? Write truncdisi pattern using sra?
2964 (define_expand "zero_extendsidi2"
2965 [(set (match_operand:DI 0 "register_operand" "")
2966 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2970 (define_insn "*zero_extendsidi2_insn_sp64"
2971 [(set (match_operand:DI 0 "register_operand" "=r,r")
2972 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2973 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2977 [(set_attr "type" "shift,load")])
2979 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2980 [(set (match_operand:DI 0 "register_operand" "=r")
2981 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2984 "&& reload_completed"
2985 [(set (match_dup 2) (match_dup 3))
2986 (set (match_dup 4) (match_dup 5))]
2990 dest1 = gen_highpart (SImode, operands[0]);
2991 dest2 = gen_lowpart (SImode, operands[0]);
2993 /* Swap the order in case of overlap. */
2994 if (REGNO (dest1) == REGNO (operands[1]))
2996 operands[2] = dest2;
2997 operands[3] = operands[1];
2998 operands[4] = dest1;
2999 operands[5] = const0_rtx;
3003 operands[2] = dest1;
3004 operands[3] = const0_rtx;
3005 operands[4] = dest2;
3006 operands[5] = operands[1];
3009 [(set_attr "length" "2")])
3011 ;; Simplify comparisons of extended values.
3013 (define_insn "*cmp_zero_extendqisi2"
3014 [(set (reg:CC CC_REG)
3015 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3018 "andcc\t%0, 0xff, %%g0"
3019 [(set_attr "type" "compare")])
3021 (define_insn "*cmp_zero_qi"
3022 [(set (reg:CC CC_REG)
3023 (compare:CC (match_operand:QI 0 "register_operand" "r")
3026 "andcc\t%0, 0xff, %%g0"
3027 [(set_attr "type" "compare")])
3029 (define_insn "*cmp_zero_extendqisi2_set"
3030 [(set (reg:CC CC_REG)
3031 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3033 (set (match_operand:SI 0 "register_operand" "=r")
3034 (zero_extend:SI (match_dup 1)))]
3036 "andcc\t%1, 0xff, %0"
3037 [(set_attr "type" "compare")])
3039 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3040 [(set (reg:CC CC_REG)
3041 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3044 (set (match_operand:SI 0 "register_operand" "=r")
3045 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3047 "andcc\t%1, 0xff, %0"
3048 [(set_attr "type" "compare")])
3050 (define_insn "*cmp_zero_extendqidi2"
3051 [(set (reg:CCX CC_REG)
3052 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3055 "andcc\t%0, 0xff, %%g0"
3056 [(set_attr "type" "compare")])
3058 (define_insn "*cmp_zero_qi_sp64"
3059 [(set (reg:CCX CC_REG)
3060 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3063 "andcc\t%0, 0xff, %%g0"
3064 [(set_attr "type" "compare")])
3066 (define_insn "*cmp_zero_extendqidi2_set"
3067 [(set (reg:CCX CC_REG)
3068 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3070 (set (match_operand:DI 0 "register_operand" "=r")
3071 (zero_extend:DI (match_dup 1)))]
3073 "andcc\t%1, 0xff, %0"
3074 [(set_attr "type" "compare")])
3076 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3077 [(set (reg:CCX CC_REG)
3078 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3081 (set (match_operand:DI 0 "register_operand" "=r")
3082 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3084 "andcc\t%1, 0xff, %0"
3085 [(set_attr "type" "compare")])
3087 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3089 (define_insn "*cmp_siqi_trunc"
3090 [(set (reg:CC CC_REG)
3091 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3094 "andcc\t%0, 0xff, %%g0"
3095 [(set_attr "type" "compare")])
3097 (define_insn "*cmp_siqi_trunc_set"
3098 [(set (reg:CC CC_REG)
3099 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3101 (set (match_operand:QI 0 "register_operand" "=r")
3102 (subreg:QI (match_dup 1) 3))]
3104 "andcc\t%1, 0xff, %0"
3105 [(set_attr "type" "compare")])
3107 (define_insn "*cmp_diqi_trunc"
3108 [(set (reg:CC CC_REG)
3109 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3112 "andcc\t%0, 0xff, %%g0"
3113 [(set_attr "type" "compare")])
3115 (define_insn "*cmp_diqi_trunc_set"
3116 [(set (reg:CC CC_REG)
3117 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3119 (set (match_operand:QI 0 "register_operand" "=r")
3120 (subreg:QI (match_dup 1) 7))]
3122 "andcc\t%1, 0xff, %0"
3123 [(set_attr "type" "compare")])
3126 ;; Sign-extension instructions
3128 ;; These patterns originally accepted general_operands, however, slightly
3129 ;; better code is generated by only accepting register_operands, and then
3130 ;; letting combine generate the lds[hb] insns.
3132 (define_expand "extendhisi2"
3133 [(set (match_operand:SI 0 "register_operand" "")
3134 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3137 rtx temp = gen_reg_rtx (SImode);
3138 rtx shift_16 = GEN_INT (16);
3139 int op1_subbyte = 0;
3141 if (GET_CODE (operand1) == SUBREG)
3143 op1_subbyte = SUBREG_BYTE (operand1);
3144 op1_subbyte /= GET_MODE_SIZE (SImode);
3145 op1_subbyte *= GET_MODE_SIZE (SImode);
3146 operand1 = XEXP (operand1, 0);
3149 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3151 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3155 (define_insn "*sign_extendhisi2_insn"
3156 [(set (match_operand:SI 0 "register_operand" "=r")
3157 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3160 [(set_attr "type" "sload")
3161 (set_attr "us3load_type" "3cycle")])
3163 (define_expand "extendqihi2"
3164 [(set (match_operand:HI 0 "register_operand" "")
3165 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3168 rtx temp = gen_reg_rtx (SImode);
3169 rtx shift_24 = GEN_INT (24);
3170 int op1_subbyte = 0;
3171 int op0_subbyte = 0;
3173 if (GET_CODE (operand1) == SUBREG)
3175 op1_subbyte = SUBREG_BYTE (operand1);
3176 op1_subbyte /= GET_MODE_SIZE (SImode);
3177 op1_subbyte *= GET_MODE_SIZE (SImode);
3178 operand1 = XEXP (operand1, 0);
3180 if (GET_CODE (operand0) == SUBREG)
3182 op0_subbyte = SUBREG_BYTE (operand0);
3183 op0_subbyte /= GET_MODE_SIZE (SImode);
3184 op0_subbyte *= GET_MODE_SIZE (SImode);
3185 operand0 = XEXP (operand0, 0);
3187 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3189 if (GET_MODE (operand0) != SImode)
3190 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3191 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3195 (define_insn "*sign_extendqihi2_insn"
3196 [(set (match_operand:HI 0 "register_operand" "=r")
3197 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3200 [(set_attr "type" "sload")
3201 (set_attr "us3load_type" "3cycle")])
3203 (define_expand "extendqisi2"
3204 [(set (match_operand:SI 0 "register_operand" "")
3205 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3208 rtx temp = gen_reg_rtx (SImode);
3209 rtx shift_24 = GEN_INT (24);
3210 int op1_subbyte = 0;
3212 if (GET_CODE (operand1) == SUBREG)
3214 op1_subbyte = SUBREG_BYTE (operand1);
3215 op1_subbyte /= GET_MODE_SIZE (SImode);
3216 op1_subbyte *= GET_MODE_SIZE (SImode);
3217 operand1 = XEXP (operand1, 0);
3220 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3222 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3226 (define_insn "*sign_extendqisi2_insn"
3227 [(set (match_operand:SI 0 "register_operand" "=r")
3228 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3231 [(set_attr "type" "sload")
3232 (set_attr "us3load_type" "3cycle")])
3234 (define_expand "extendqidi2"
3235 [(set (match_operand:DI 0 "register_operand" "")
3236 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3239 rtx temp = gen_reg_rtx (DImode);
3240 rtx shift_56 = GEN_INT (56);
3241 int op1_subbyte = 0;
3243 if (GET_CODE (operand1) == SUBREG)
3245 op1_subbyte = SUBREG_BYTE (operand1);
3246 op1_subbyte /= GET_MODE_SIZE (DImode);
3247 op1_subbyte *= GET_MODE_SIZE (DImode);
3248 operand1 = XEXP (operand1, 0);
3251 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3253 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3257 (define_insn "*sign_extendqidi2_insn"
3258 [(set (match_operand:DI 0 "register_operand" "=r")
3259 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3262 [(set_attr "type" "sload")
3263 (set_attr "us3load_type" "3cycle")])
3265 (define_expand "extendhidi2"
3266 [(set (match_operand:DI 0 "register_operand" "")
3267 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3270 rtx temp = gen_reg_rtx (DImode);
3271 rtx shift_48 = GEN_INT (48);
3272 int op1_subbyte = 0;
3274 if (GET_CODE (operand1) == SUBREG)
3276 op1_subbyte = SUBREG_BYTE (operand1);
3277 op1_subbyte /= GET_MODE_SIZE (DImode);
3278 op1_subbyte *= GET_MODE_SIZE (DImode);
3279 operand1 = XEXP (operand1, 0);
3282 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3284 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3288 (define_insn "*sign_extendhidi2_insn"
3289 [(set (match_operand:DI 0 "register_operand" "=r")
3290 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3293 [(set_attr "type" "sload")
3294 (set_attr "us3load_type" "3cycle")])
3296 (define_expand "extendsidi2"
3297 [(set (match_operand:DI 0 "register_operand" "")
3298 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3302 (define_insn "*sign_extendsidi2_insn"
3303 [(set (match_operand:DI 0 "register_operand" "=r,r")
3304 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3309 [(set_attr "type" "shift,sload")
3310 (set_attr "us3load_type" "*,3cycle")])
3313 ;; Special pattern for optimizing bit-field compares. This is needed
3314 ;; because combine uses this as a canonical form.
3316 (define_insn "*cmp_zero_extract"
3317 [(set (reg:CC CC_REG)
3319 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3320 (match_operand:SI 1 "small_int_operand" "I")
3321 (match_operand:SI 2 "small_int_operand" "I"))
3323 "INTVAL (operands[2]) > 19"
3325 int len = INTVAL (operands[1]);
3326 int pos = 32 - INTVAL (operands[2]) - len;
3327 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3328 operands[1] = GEN_INT (mask);
3329 return "andcc\t%0, %1, %%g0";
3331 [(set_attr "type" "compare")])
3333 (define_insn "*cmp_zero_extract_sp64"
3334 [(set (reg:CCX CC_REG)
3336 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3337 (match_operand:SI 1 "small_int_operand" "I")
3338 (match_operand:SI 2 "small_int_operand" "I"))
3340 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3342 int len = INTVAL (operands[1]);
3343 int pos = 64 - INTVAL (operands[2]) - len;
3344 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3345 operands[1] = GEN_INT (mask);
3346 return "andcc\t%0, %1, %%g0";
3348 [(set_attr "type" "compare")])
3351 ;; Conversions between float, double and long double.
3353 (define_insn "extendsfdf2"
3354 [(set (match_operand:DF 0 "register_operand" "=e")
3356 (match_operand:SF 1 "register_operand" "f")))]
3359 [(set_attr "type" "fp")
3360 (set_attr "fptype" "double")])
3362 (define_expand "extendsftf2"
3363 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3365 (match_operand:SF 1 "register_operand" "")))]
3366 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3367 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3369 (define_insn "*extendsftf2_hq"
3370 [(set (match_operand:TF 0 "register_operand" "=e")
3372 (match_operand:SF 1 "register_operand" "f")))]
3373 "TARGET_FPU && TARGET_HARD_QUAD"
3375 [(set_attr "type" "fp")])
3377 (define_expand "extenddftf2"
3378 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3380 (match_operand:DF 1 "register_operand" "")))]
3381 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3382 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3384 (define_insn "*extenddftf2_hq"
3385 [(set (match_operand:TF 0 "register_operand" "=e")
3387 (match_operand:DF 1 "register_operand" "e")))]
3388 "TARGET_FPU && TARGET_HARD_QUAD"
3390 [(set_attr "type" "fp")])
3392 (define_insn "truncdfsf2"
3393 [(set (match_operand:SF 0 "register_operand" "=f")
3395 (match_operand:DF 1 "register_operand" "e")))]
3398 [(set_attr "type" "fp")
3399 (set_attr "fptype" "double")])
3401 (define_expand "trunctfsf2"
3402 [(set (match_operand:SF 0 "register_operand" "")
3404 (match_operand:TF 1 "general_operand" "")))]
3405 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3406 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3408 (define_insn "*trunctfsf2_hq"
3409 [(set (match_operand:SF 0 "register_operand" "=f")
3411 (match_operand:TF 1 "register_operand" "e")))]
3412 "TARGET_FPU && TARGET_HARD_QUAD"
3414 [(set_attr "type" "fp")])
3416 (define_expand "trunctfdf2"
3417 [(set (match_operand:DF 0 "register_operand" "")
3419 (match_operand:TF 1 "general_operand" "")))]
3420 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3421 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3423 (define_insn "*trunctfdf2_hq"
3424 [(set (match_operand:DF 0 "register_operand" "=e")
3426 (match_operand:TF 1 "register_operand" "e")))]
3427 "TARGET_FPU && TARGET_HARD_QUAD"
3429 [(set_attr "type" "fp")])
3432 ;; Conversion between fixed point and floating point.
3434 (define_insn "floatsisf2"
3435 [(set (match_operand:SF 0 "register_operand" "=f")
3436 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3439 [(set_attr "type" "fp")
3440 (set_attr "fptype" "double")])
3442 (define_insn "floatsidf2"
3443 [(set (match_operand:DF 0 "register_operand" "=e")
3444 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3447 [(set_attr "type" "fp")
3448 (set_attr "fptype" "double")])
3450 (define_expand "floatsitf2"
3451 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3452 (float:TF (match_operand:SI 1 "register_operand" "")))]
3453 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3454 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3456 (define_insn "*floatsitf2_hq"
3457 [(set (match_operand:TF 0 "register_operand" "=e")
3458 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3459 "TARGET_FPU && TARGET_HARD_QUAD"
3461 [(set_attr "type" "fp")])
3463 (define_expand "floatunssitf2"
3464 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3465 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3466 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3467 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3469 ;; Now the same for 64 bit sources.
3471 (define_insn "floatdisf2"
3472 [(set (match_operand:SF 0 "register_operand" "=f")
3473 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3474 "TARGET_V9 && TARGET_FPU"
3476 [(set_attr "type" "fp")
3477 (set_attr "fptype" "double")])
3479 (define_expand "floatunsdisf2"
3480 [(use (match_operand:SF 0 "register_operand" ""))
3481 (use (match_operand:DI 1 "general_operand" ""))]
3482 "TARGET_ARCH64 && TARGET_FPU"
3483 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3485 (define_insn "floatdidf2"
3486 [(set (match_operand:DF 0 "register_operand" "=e")
3487 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3488 "TARGET_V9 && TARGET_FPU"
3490 [(set_attr "type" "fp")
3491 (set_attr "fptype" "double")])
3493 (define_expand "floatunsdidf2"
3494 [(use (match_operand:DF 0 "register_operand" ""))
3495 (use (match_operand:DI 1 "general_operand" ""))]
3496 "TARGET_ARCH64 && TARGET_FPU"
3497 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3499 (define_expand "floatditf2"
3500 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3501 (float:TF (match_operand:DI 1 "register_operand" "")))]
3502 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3503 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3505 (define_insn "*floatditf2_hq"
3506 [(set (match_operand:TF 0 "register_operand" "=e")
3507 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3508 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3510 [(set_attr "type" "fp")])
3512 (define_expand "floatunsditf2"
3513 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3514 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3515 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3516 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3518 ;; Convert a float to an actual integer.
3519 ;; Truncation is performed as part of the conversion.
3521 (define_insn "fix_truncsfsi2"
3522 [(set (match_operand:SI 0 "register_operand" "=f")
3523 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3526 [(set_attr "type" "fp")
3527 (set_attr "fptype" "double")])
3529 (define_insn "fix_truncdfsi2"
3530 [(set (match_operand:SI 0 "register_operand" "=f")
3531 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3534 [(set_attr "type" "fp")
3535 (set_attr "fptype" "double")])
3537 (define_expand "fix_trunctfsi2"
3538 [(set (match_operand:SI 0 "register_operand" "")
3539 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3540 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3541 "emit_tfmode_cvt (FIX, operands); DONE;")
3543 (define_insn "*fix_trunctfsi2_hq"
3544 [(set (match_operand:SI 0 "register_operand" "=f")
3545 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3546 "TARGET_FPU && TARGET_HARD_QUAD"
3548 [(set_attr "type" "fp")])
3550 (define_expand "fixuns_trunctfsi2"
3551 [(set (match_operand:SI 0 "register_operand" "")
3552 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3553 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3554 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3556 ;; Now the same, for V9 targets
3558 (define_insn "fix_truncsfdi2"
3559 [(set (match_operand:DI 0 "register_operand" "=e")
3560 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3561 "TARGET_V9 && TARGET_FPU"
3563 [(set_attr "type" "fp")
3564 (set_attr "fptype" "double")])
3566 (define_expand "fixuns_truncsfdi2"
3567 [(use (match_operand:DI 0 "register_operand" ""))
3568 (use (match_operand:SF 1 "general_operand" ""))]
3569 "TARGET_ARCH64 && TARGET_FPU"
3570 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3572 (define_insn "fix_truncdfdi2"
3573 [(set (match_operand:DI 0 "register_operand" "=e")
3574 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3575 "TARGET_V9 && TARGET_FPU"
3577 [(set_attr "type" "fp")
3578 (set_attr "fptype" "double")])
3580 (define_expand "fixuns_truncdfdi2"
3581 [(use (match_operand:DI 0 "register_operand" ""))
3582 (use (match_operand:DF 1 "general_operand" ""))]
3583 "TARGET_ARCH64 && TARGET_FPU"
3584 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3586 (define_expand "fix_trunctfdi2"
3587 [(set (match_operand:DI 0 "register_operand" "")
3588 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3589 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3590 "emit_tfmode_cvt (FIX, operands); DONE;")
3592 (define_insn "*fix_trunctfdi2_hq"
3593 [(set (match_operand:DI 0 "register_operand" "=e")
3594 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3595 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3597 [(set_attr "type" "fp")])
3599 (define_expand "fixuns_trunctfdi2"
3600 [(set (match_operand:DI 0 "register_operand" "")
3601 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3602 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3603 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3606 ;; Integer addition/subtraction instructions.
3608 (define_expand "adddi3"
3609 [(set (match_operand:DI 0 "register_operand" "")
3610 (plus:DI (match_operand:DI 1 "register_operand" "")
3611 (match_operand:DI 2 "arith_double_add_operand" "")))]
3614 if (! TARGET_ARCH64)
3616 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3617 gen_rtx_SET (VOIDmode, operands[0],
3618 gen_rtx_PLUS (DImode, operands[1],
3620 gen_rtx_CLOBBER (VOIDmode,
3621 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3626 (define_insn_and_split "*adddi3_insn_sp32"
3627 [(set (match_operand:DI 0 "register_operand" "=r")
3628 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3629 (match_operand:DI 2 "arith_double_operand" "rHI")))
3630 (clobber (reg:CC CC_REG))]
3633 "&& reload_completed"
3634 [(parallel [(set (reg:CC_NOOV CC_REG)
3635 (compare:CC_NOOV (plus:SI (match_dup 4)
3639 (plus:SI (match_dup 4) (match_dup 5)))])
3641 (plus:SI (plus:SI (match_dup 7)
3643 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3645 operands[3] = gen_lowpart (SImode, operands[0]);
3646 operands[4] = gen_lowpart (SImode, operands[1]);
3647 operands[5] = gen_lowpart (SImode, operands[2]);
3648 operands[6] = gen_highpart (SImode, operands[0]);
3649 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3650 #if HOST_BITS_PER_WIDE_INT == 32
3651 if (GET_CODE (operands[2]) == CONST_INT)
3653 if (INTVAL (operands[2]) < 0)
3654 operands[8] = constm1_rtx;
3656 operands[8] = const0_rtx;
3660 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3662 [(set_attr "length" "2")])
3664 ;; LTU here means "carry set"
3666 [(set (match_operand:SI 0 "register_operand" "=r")
3667 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3668 (match_operand:SI 2 "arith_operand" "rI"))
3669 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3672 [(set_attr "type" "ialuX")])
3674 (define_insn_and_split "*addx_extend_sp32"
3675 [(set (match_operand:DI 0 "register_operand" "=r")
3676 (zero_extend:DI (plus:SI (plus:SI
3677 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3678 (match_operand:SI 2 "arith_operand" "rI"))
3679 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3682 "&& reload_completed"
3683 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3684 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3685 (set (match_dup 4) (const_int 0))]
3686 "operands[3] = gen_lowpart (SImode, operands[0]);
3687 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3688 [(set_attr "length" "2")])
3690 (define_insn "*addx_extend_sp64"
3691 [(set (match_operand:DI 0 "register_operand" "=r")
3692 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3693 (match_operand:SI 2 "arith_operand" "rI"))
3694 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3697 [(set_attr "type" "ialuX")])
3699 (define_insn_and_split "*adddi3_extend_sp32"
3700 [(set (match_operand:DI 0 "register_operand" "=r")
3701 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3702 (match_operand:DI 2 "register_operand" "r")))
3703 (clobber (reg:CC CC_REG))]
3706 "&& reload_completed"
3707 [(parallel [(set (reg:CC_NOOV CC_REG)
3708 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3710 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3712 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3713 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3714 "operands[3] = gen_lowpart (SImode, operands[2]);
3715 operands[4] = gen_highpart (SImode, operands[2]);
3716 operands[5] = gen_lowpart (SImode, operands[0]);
3717 operands[6] = gen_highpart (SImode, operands[0]);"
3718 [(set_attr "length" "2")])
3720 (define_insn "*adddi3_sp64"
3721 [(set (match_operand:DI 0 "register_operand" "=r,r")
3722 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3723 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3729 (define_insn "addsi3"
3730 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3731 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3732 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3737 fpadd32s\t%1, %2, %0"
3738 [(set_attr "type" "*,*,fga")
3739 (set_attr "fptype" "*,*,single")])
3741 (define_insn "*cmp_cc_plus"
3742 [(set (reg:CC_NOOV CC_REG)
3743 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3744 (match_operand:SI 1 "arith_operand" "rI"))
3747 "addcc\t%0, %1, %%g0"
3748 [(set_attr "type" "compare")])
3750 (define_insn "*cmp_ccx_plus"
3751 [(set (reg:CCX_NOOV CC_REG)
3752 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3753 (match_operand:DI 1 "arith_operand" "rI"))
3756 "addcc\t%0, %1, %%g0"
3757 [(set_attr "type" "compare")])
3759 (define_insn "*cmp_cc_plus_set"
3760 [(set (reg:CC_NOOV CC_REG)
3761 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3762 (match_operand:SI 2 "arith_operand" "rI"))
3764 (set (match_operand:SI 0 "register_operand" "=r")
3765 (plus:SI (match_dup 1) (match_dup 2)))]
3768 [(set_attr "type" "compare")])
3770 (define_insn "*cmp_ccx_plus_set"
3771 [(set (reg:CCX_NOOV CC_REG)
3772 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3773 (match_operand:DI 2 "arith_operand" "rI"))
3775 (set (match_operand:DI 0 "register_operand" "=r")
3776 (plus:DI (match_dup 1) (match_dup 2)))]
3779 [(set_attr "type" "compare")])
3781 (define_expand "subdi3"
3782 [(set (match_operand:DI 0 "register_operand" "")
3783 (minus:DI (match_operand:DI 1 "register_operand" "")
3784 (match_operand:DI 2 "arith_double_add_operand" "")))]
3787 if (! TARGET_ARCH64)
3789 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3790 gen_rtx_SET (VOIDmode, operands[0],
3791 gen_rtx_MINUS (DImode, operands[1],
3793 gen_rtx_CLOBBER (VOIDmode,
3794 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3799 (define_insn_and_split "*subdi3_insn_sp32"
3800 [(set (match_operand:DI 0 "register_operand" "=r")
3801 (minus:DI (match_operand:DI 1 "register_operand" "r")
3802 (match_operand:DI 2 "arith_double_operand" "rHI")))
3803 (clobber (reg:CC CC_REG))]
3806 "&& reload_completed"
3807 [(parallel [(set (reg:CC_NOOV CC_REG)
3808 (compare:CC_NOOV (minus:SI (match_dup 4)
3812 (minus:SI (match_dup 4) (match_dup 5)))])
3814 (minus:SI (minus:SI (match_dup 7)
3816 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3818 operands[3] = gen_lowpart (SImode, operands[0]);
3819 operands[4] = gen_lowpart (SImode, operands[1]);
3820 operands[5] = gen_lowpart (SImode, operands[2]);
3821 operands[6] = gen_highpart (SImode, operands[0]);
3822 operands[7] = gen_highpart (SImode, operands[1]);
3823 #if HOST_BITS_PER_WIDE_INT == 32
3824 if (GET_CODE (operands[2]) == CONST_INT)
3826 if (INTVAL (operands[2]) < 0)
3827 operands[8] = constm1_rtx;
3829 operands[8] = const0_rtx;
3833 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3835 [(set_attr "length" "2")])
3837 ;; LTU here means "carry set"
3839 [(set (match_operand:SI 0 "register_operand" "=r")
3840 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3841 (match_operand:SI 2 "arith_operand" "rI"))
3842 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3845 [(set_attr "type" "ialuX")])
3847 (define_insn "*subx_extend_sp64"
3848 [(set (match_operand:DI 0 "register_operand" "=r")
3849 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3850 (match_operand:SI 2 "arith_operand" "rI"))
3851 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3854 [(set_attr "type" "ialuX")])
3856 (define_insn_and_split "*subx_extend"
3857 [(set (match_operand:DI 0 "register_operand" "=r")
3858 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3859 (match_operand:SI 2 "arith_operand" "rI"))
3860 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3863 "&& reload_completed"
3864 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3865 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3866 (set (match_dup 4) (const_int 0))]
3867 "operands[3] = gen_lowpart (SImode, operands[0]);
3868 operands[4] = gen_highpart (SImode, operands[0]);"
3869 [(set_attr "length" "2")])
3871 (define_insn_and_split "*subdi3_extend_sp32"
3872 [(set (match_operand:DI 0 "register_operand" "=r")
3873 (minus:DI (match_operand:DI 1 "register_operand" "r")
3874 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3875 (clobber (reg:CC CC_REG))]
3878 "&& reload_completed"
3879 [(parallel [(set (reg:CC_NOOV CC_REG)
3880 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3882 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3884 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3885 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3886 "operands[3] = gen_lowpart (SImode, operands[1]);
3887 operands[4] = gen_highpart (SImode, operands[1]);
3888 operands[5] = gen_lowpart (SImode, operands[0]);
3889 operands[6] = gen_highpart (SImode, operands[0]);"
3890 [(set_attr "length" "2")])
3892 (define_insn "*subdi3_sp64"
3893 [(set (match_operand:DI 0 "register_operand" "=r,r")
3894 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3895 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3901 (define_insn "subsi3"
3902 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3903 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3904 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3909 fpsub32s\t%1, %2, %0"
3910 [(set_attr "type" "*,*,fga")
3911 (set_attr "fptype" "*,*,single")])
3913 (define_insn "*cmp_minus_cc"
3914 [(set (reg:CC_NOOV CC_REG)
3915 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3916 (match_operand:SI 1 "arith_operand" "rI"))
3919 "subcc\t%r0, %1, %%g0"
3920 [(set_attr "type" "compare")])
3922 (define_insn "*cmp_minus_ccx"
3923 [(set (reg:CCX_NOOV CC_REG)
3924 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3925 (match_operand:DI 1 "arith_operand" "rI"))
3928 "subcc\t%0, %1, %%g0"
3929 [(set_attr "type" "compare")])
3931 (define_insn "cmp_minus_cc_set"
3932 [(set (reg:CC_NOOV CC_REG)
3933 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3934 (match_operand:SI 2 "arith_operand" "rI"))
3936 (set (match_operand:SI 0 "register_operand" "=r")
3937 (minus:SI (match_dup 1) (match_dup 2)))]
3939 "subcc\t%r1, %2, %0"
3940 [(set_attr "type" "compare")])
3942 (define_insn "*cmp_minus_ccx_set"
3943 [(set (reg:CCX_NOOV CC_REG)
3944 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3945 (match_operand:DI 2 "arith_operand" "rI"))
3947 (set (match_operand:DI 0 "register_operand" "=r")
3948 (minus:DI (match_dup 1) (match_dup 2)))]
3951 [(set_attr "type" "compare")])
3954 ;; Integer multiply/divide instructions.
3956 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3957 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3959 (define_insn "mulsi3"
3960 [(set (match_operand:SI 0 "register_operand" "=r")
3961 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3962 (match_operand:SI 2 "arith_operand" "rI")))]
3965 [(set_attr "type" "imul")])
3967 (define_expand "muldi3"
3968 [(set (match_operand:DI 0 "register_operand" "")
3969 (mult:DI (match_operand:DI 1 "arith_operand" "")
3970 (match_operand:DI 2 "arith_operand" "")))]
3971 "TARGET_ARCH64 || TARGET_V8PLUS"
3975 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3980 (define_insn "*muldi3_sp64"
3981 [(set (match_operand:DI 0 "register_operand" "=r")
3982 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3983 (match_operand:DI 2 "arith_operand" "rI")))]
3986 [(set_attr "type" "imul")])
3988 ;; V8plus wide multiply.
3990 (define_insn "muldi3_v8plus"
3991 [(set (match_operand:DI 0 "register_operand" "=r,h")
3992 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3993 (match_operand:DI 2 "arith_operand" "rI,rI")))
3994 (clobber (match_scratch:SI 3 "=&h,X"))
3995 (clobber (match_scratch:SI 4 "=&h,X"))]
3998 if (sparc_check_64 (operands[1], insn) <= 0)
3999 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4000 if (which_alternative == 1)
4001 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4002 if (GET_CODE (operands[2]) == CONST_INT)
4004 if (which_alternative == 1)
4005 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4007 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";
4009 else if (rtx_equal_p (operands[1], operands[2]))
4011 if (which_alternative == 1)
4012 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4014 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";
4016 if (sparc_check_64 (operands[2], insn) <= 0)
4017 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4018 if (which_alternative == 1)
4019 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";
4021 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";
4023 [(set_attr "type" "multi")
4024 (set_attr "length" "9,8")])
4026 (define_insn "*cmp_mul_set"
4027 [(set (reg:CC CC_REG)
4028 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4029 (match_operand:SI 2 "arith_operand" "rI"))
4031 (set (match_operand:SI 0 "register_operand" "=r")
4032 (mult:SI (match_dup 1) (match_dup 2)))]
4033 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4034 "smulcc\t%1, %2, %0"
4035 [(set_attr "type" "imul")])
4037 (define_expand "mulsidi3"
4038 [(set (match_operand:DI 0 "register_operand" "")
4039 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4040 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4043 if (CONSTANT_P (operands[2]))
4046 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4048 else if (TARGET_ARCH32)
4049 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4052 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4058 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4063 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4064 ;; registers can hold 64-bit values in the V8plus environment.
4066 (define_insn "mulsidi3_v8plus"
4067 [(set (match_operand:DI 0 "register_operand" "=h,r")
4068 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4069 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4070 (clobber (match_scratch:SI 3 "=X,&h"))]
4073 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4074 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4075 [(set_attr "type" "multi")
4076 (set_attr "length" "2,3")])
4079 (define_insn "const_mulsidi3_v8plus"
4080 [(set (match_operand:DI 0 "register_operand" "=h,r")
4081 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4082 (match_operand:DI 2 "small_int_operand" "I,I")))
4083 (clobber (match_scratch:SI 3 "=X,&h"))]
4086 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4087 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4088 [(set_attr "type" "multi")
4089 (set_attr "length" "2,3")])
4092 (define_insn "*mulsidi3_sp32"
4093 [(set (match_operand:DI 0 "register_operand" "=r")
4094 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4095 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4098 return TARGET_SPARCLET
4099 ? "smuld\t%1, %2, %L0"
4100 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4103 (if_then_else (eq_attr "isa" "sparclet")
4104 (const_string "imul") (const_string "multi")))
4105 (set (attr "length")
4106 (if_then_else (eq_attr "isa" "sparclet")
4107 (const_int 1) (const_int 2)))])
4109 (define_insn "*mulsidi3_sp64"
4110 [(set (match_operand:DI 0 "register_operand" "=r")
4111 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4112 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4113 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4115 [(set_attr "type" "imul")])
4117 ;; Extra pattern, because sign_extend of a constant isn't valid.
4120 (define_insn "const_mulsidi3_sp32"
4121 [(set (match_operand:DI 0 "register_operand" "=r")
4122 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4123 (match_operand:DI 2 "small_int_operand" "I")))]
4126 return TARGET_SPARCLET
4127 ? "smuld\t%1, %2, %L0"
4128 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4131 (if_then_else (eq_attr "isa" "sparclet")
4132 (const_string "imul") (const_string "multi")))
4133 (set (attr "length")
4134 (if_then_else (eq_attr "isa" "sparclet")
4135 (const_int 1) (const_int 2)))])
4137 (define_insn "const_mulsidi3_sp64"
4138 [(set (match_operand:DI 0 "register_operand" "=r")
4139 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4140 (match_operand:DI 2 "small_int_operand" "I")))]
4141 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4143 [(set_attr "type" "imul")])
4145 (define_expand "smulsi3_highpart"
4146 [(set (match_operand:SI 0 "register_operand" "")
4148 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4149 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4151 "TARGET_HARD_MUL && TARGET_ARCH32"
4153 if (CONSTANT_P (operands[2]))
4157 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4163 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4168 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4169 operands[2], GEN_INT (32)));
4175 (define_insn "smulsi3_highpart_v8plus"
4176 [(set (match_operand:SI 0 "register_operand" "=h,r")
4178 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4179 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4180 (match_operand:SI 3 "small_int_operand" "I,I"))))
4181 (clobber (match_scratch:SI 4 "=X,&h"))]
4184 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4185 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4186 [(set_attr "type" "multi")
4187 (set_attr "length" "2")])
4189 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4192 [(set (match_operand:SI 0 "register_operand" "=h,r")
4195 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4196 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4197 (match_operand:SI 3 "small_int_operand" "I,I"))
4199 (clobber (match_scratch:SI 4 "=X,&h"))]
4202 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4203 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4204 [(set_attr "type" "multi")
4205 (set_attr "length" "2")])
4208 (define_insn "const_smulsi3_highpart_v8plus"
4209 [(set (match_operand:SI 0 "register_operand" "=h,r")
4211 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4212 (match_operand:DI 2 "small_int_operand" "I,I"))
4213 (match_operand:SI 3 "small_int_operand" "I,I"))))
4214 (clobber (match_scratch:SI 4 "=X,&h"))]
4217 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4218 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4219 [(set_attr "type" "multi")
4220 (set_attr "length" "2")])
4223 (define_insn "*smulsi3_highpart_sp32"
4224 [(set (match_operand:SI 0 "register_operand" "=r")
4226 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4227 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4230 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4231 [(set_attr "type" "multi")
4232 (set_attr "length" "2")])
4235 (define_insn "const_smulsi3_highpart"
4236 [(set (match_operand:SI 0 "register_operand" "=r")
4238 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4239 (match_operand:DI 2 "small_int_operand" "i"))
4242 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4243 [(set_attr "type" "multi")
4244 (set_attr "length" "2")])
4246 (define_expand "umulsidi3"
4247 [(set (match_operand:DI 0 "register_operand" "")
4248 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4249 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4252 if (CONSTANT_P (operands[2]))
4255 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4257 else if (TARGET_ARCH32)
4258 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4261 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4267 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4273 (define_insn "umulsidi3_v8plus"
4274 [(set (match_operand:DI 0 "register_operand" "=h,r")
4275 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4276 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4277 (clobber (match_scratch:SI 3 "=X,&h"))]
4280 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4281 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4282 [(set_attr "type" "multi")
4283 (set_attr "length" "2,3")])
4286 (define_insn "*umulsidi3_sp32"
4287 [(set (match_operand:DI 0 "register_operand" "=r")
4288 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4289 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4292 return TARGET_SPARCLET
4293 ? "umuld\t%1, %2, %L0"
4294 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4297 (if_then_else (eq_attr "isa" "sparclet")
4298 (const_string "imul") (const_string "multi")))
4299 (set (attr "length")
4300 (if_then_else (eq_attr "isa" "sparclet")
4301 (const_int 1) (const_int 2)))])
4303 (define_insn "*umulsidi3_sp64"
4304 [(set (match_operand:DI 0 "register_operand" "=r")
4305 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4306 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4307 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4309 [(set_attr "type" "imul")])
4311 ;; Extra pattern, because sign_extend of a constant isn't valid.
4314 (define_insn "const_umulsidi3_sp32"
4315 [(set (match_operand:DI 0 "register_operand" "=r")
4316 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4317 (match_operand:DI 2 "uns_small_int_operand" "")))]
4320 return TARGET_SPARCLET
4321 ? "umuld\t%1, %s2, %L0"
4322 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4325 (if_then_else (eq_attr "isa" "sparclet")
4326 (const_string "imul") (const_string "multi")))
4327 (set (attr "length")
4328 (if_then_else (eq_attr "isa" "sparclet")
4329 (const_int 1) (const_int 2)))])
4331 (define_insn "const_umulsidi3_sp64"
4332 [(set (match_operand:DI 0 "register_operand" "=r")
4333 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4334 (match_operand:DI 2 "uns_small_int_operand" "")))]
4335 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4337 [(set_attr "type" "imul")])
4340 (define_insn "const_umulsidi3_v8plus"
4341 [(set (match_operand:DI 0 "register_operand" "=h,r")
4342 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4343 (match_operand:DI 2 "uns_small_int_operand" "")))
4344 (clobber (match_scratch:SI 3 "=X,h"))]
4347 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4348 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4349 [(set_attr "type" "multi")
4350 (set_attr "length" "2,3")])
4352 (define_expand "umulsi3_highpart"
4353 [(set (match_operand:SI 0 "register_operand" "")
4355 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4356 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4358 "TARGET_HARD_MUL && TARGET_ARCH32"
4360 if (CONSTANT_P (operands[2]))
4364 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4370 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4375 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4376 operands[2], GEN_INT (32)));
4382 (define_insn "umulsi3_highpart_v8plus"
4383 [(set (match_operand:SI 0 "register_operand" "=h,r")
4385 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4386 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4387 (match_operand:SI 3 "small_int_operand" "I,I"))))
4388 (clobber (match_scratch:SI 4 "=X,h"))]
4391 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4392 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4393 [(set_attr "type" "multi")
4394 (set_attr "length" "2")])
4397 (define_insn "const_umulsi3_highpart_v8plus"
4398 [(set (match_operand:SI 0 "register_operand" "=h,r")
4400 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4401 (match_operand:DI 2 "uns_small_int_operand" ""))
4402 (match_operand:SI 3 "small_int_operand" "I,I"))))
4403 (clobber (match_scratch:SI 4 "=X,h"))]
4406 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4407 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4408 [(set_attr "type" "multi")
4409 (set_attr "length" "2")])
4412 (define_insn "*umulsi3_highpart_sp32"
4413 [(set (match_operand:SI 0 "register_operand" "=r")
4415 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4416 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4419 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4420 [(set_attr "type" "multi")
4421 (set_attr "length" "2")])
4424 (define_insn "const_umulsi3_highpart"
4425 [(set (match_operand:SI 0 "register_operand" "=r")
4427 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4428 (match_operand:DI 2 "uns_small_int_operand" ""))
4431 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4432 [(set_attr "type" "multi")
4433 (set_attr "length" "2")])
4435 (define_expand "divsi3"
4436 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4437 (div:SI (match_operand:SI 1 "register_operand" "")
4438 (match_operand:SI 2 "input_operand" "")))
4439 (clobber (match_scratch:SI 3 ""))])]
4440 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4444 operands[3] = gen_reg_rtx(SImode);
4445 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4446 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4452 ;; The V8 architecture specifies that there must be at least 3 instructions
4453 ;; between a write to the Y register and a use of it for correct results.
4454 ;; We try to fill one of them with a simple constant or a memory load.
4456 (define_insn "divsi3_sp32"
4457 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4458 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4459 (match_operand:SI 2 "input_operand" "rI,K,m")))
4460 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4461 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4463 output_asm_insn ("sra\t%1, 31, %3", operands);
4464 output_asm_insn ("wr\t%3, 0, %%y", operands);
4466 switch (which_alternative)
4470 return "sdiv\t%1, %2, %0";
4472 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4475 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4477 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4480 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4482 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4487 [(set_attr "type" "multi")
4488 (set (attr "length")
4489 (if_then_else (eq_attr "isa" "v9")
4490 (const_int 4) (const_int 6)))])
4492 (define_insn "divsi3_sp64"
4493 [(set (match_operand:SI 0 "register_operand" "=r")
4494 (div:SI (match_operand:SI 1 "register_operand" "r")
4495 (match_operand:SI 2 "input_operand" "rI")))
4496 (use (match_operand:SI 3 "register_operand" "r"))]
4497 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4498 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4499 [(set_attr "type" "multi")
4500 (set_attr "length" "2")])
4502 (define_insn "divdi3"
4503 [(set (match_operand:DI 0 "register_operand" "=r")
4504 (div:DI (match_operand:DI 1 "register_operand" "r")
4505 (match_operand:DI 2 "arith_operand" "rI")))]
4508 [(set_attr "type" "idiv")])
4510 (define_insn "*cmp_sdiv_cc_set"
4511 [(set (reg:CC CC_REG)
4512 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4513 (match_operand:SI 2 "arith_operand" "rI"))
4515 (set (match_operand:SI 0 "register_operand" "=r")
4516 (div:SI (match_dup 1) (match_dup 2)))
4517 (clobber (match_scratch:SI 3 "=&r"))]
4518 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4520 output_asm_insn ("sra\t%1, 31, %3", operands);
4521 output_asm_insn ("wr\t%3, 0, %%y", operands);
4524 return "sdivcc\t%1, %2, %0";
4526 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4528 [(set_attr "type" "multi")
4529 (set (attr "length")
4530 (if_then_else (eq_attr "isa" "v9")
4531 (const_int 3) (const_int 6)))])
4534 (define_expand "udivsi3"
4535 [(set (match_operand:SI 0 "register_operand" "")
4536 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4537 (match_operand:SI 2 "input_operand" "")))]
4538 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4541 ;; The V8 architecture specifies that there must be at least 3 instructions
4542 ;; between a write to the Y register and a use of it for correct results.
4543 ;; We try to fill one of them with a simple constant or a memory load.
4545 (define_insn "udivsi3_sp32"
4546 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4547 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4548 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4549 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4551 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4553 switch (which_alternative)
4557 return "udiv\t%1, %2, %0";
4559 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4562 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4564 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4567 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4569 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4572 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4574 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4579 [(set_attr "type" "multi")
4580 (set (attr "length")
4581 (if_then_else (eq_attr "isa" "v9")
4582 (const_int 3) (const_int 5)))])
4584 (define_insn "udivsi3_sp64"
4585 [(set (match_operand:SI 0 "register_operand" "=r")
4586 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4587 (match_operand:SI 2 "input_operand" "rI")))]
4588 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4589 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4590 [(set_attr "type" "multi")
4591 (set_attr "length" "2")])
4593 (define_insn "udivdi3"
4594 [(set (match_operand:DI 0 "register_operand" "=r")
4595 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4596 (match_operand:DI 2 "arith_operand" "rI")))]
4599 [(set_attr "type" "idiv")])
4601 (define_insn "*cmp_udiv_cc_set"
4602 [(set (reg:CC CC_REG)
4603 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4604 (match_operand:SI 2 "arith_operand" "rI"))
4606 (set (match_operand:SI 0 "register_operand" "=r")
4607 (udiv:SI (match_dup 1) (match_dup 2)))]
4608 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4610 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4613 return "udivcc\t%1, %2, %0";
4615 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4617 [(set_attr "type" "multi")
4618 (set (attr "length")
4619 (if_then_else (eq_attr "isa" "v9")
4620 (const_int 2) (const_int 5)))])
4622 ; sparclet multiply/accumulate insns
4624 (define_insn "*smacsi"
4625 [(set (match_operand:SI 0 "register_operand" "=r")
4626 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4627 (match_operand:SI 2 "arith_operand" "rI"))
4628 (match_operand:SI 3 "register_operand" "0")))]
4631 [(set_attr "type" "imul")])
4633 (define_insn "*smacdi"
4634 [(set (match_operand:DI 0 "register_operand" "=r")
4635 (plus:DI (mult:DI (sign_extend:DI
4636 (match_operand:SI 1 "register_operand" "%r"))
4638 (match_operand:SI 2 "register_operand" "r")))
4639 (match_operand:DI 3 "register_operand" "0")))]
4641 "smacd\t%1, %2, %L0"
4642 [(set_attr "type" "imul")])
4644 (define_insn "*umacdi"
4645 [(set (match_operand:DI 0 "register_operand" "=r")
4646 (plus:DI (mult:DI (zero_extend:DI
4647 (match_operand:SI 1 "register_operand" "%r"))
4649 (match_operand:SI 2 "register_operand" "r")))
4650 (match_operand:DI 3 "register_operand" "0")))]
4652 "umacd\t%1, %2, %L0"
4653 [(set_attr "type" "imul")])
4656 ;; Boolean instructions.
4658 ;; We define DImode `and' so with DImode `not' we can get
4659 ;; DImode `andn'. Other combinations are possible.
4661 (define_expand "and<V64I:mode>3"
4662 [(set (match_operand:V64I 0 "register_operand" "")
4663 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4664 (match_operand:V64I 2 "arith_double_operand" "")))]
4668 (define_insn "*and<V64I:mode>3_sp32"
4669 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4670 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4671 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4676 [(set_attr "type" "*,fga")
4677 (set_attr "length" "2,*")
4678 (set_attr "fptype" "*,double")])
4680 (define_insn "*and<V64I:mode>3_sp64"
4681 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4682 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4683 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4688 [(set_attr "type" "*,fga")
4689 (set_attr "fptype" "*,double")])
4691 (define_insn "and<V32I:mode>3"
4692 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4693 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4694 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4699 [(set_attr "type" "*,fga")
4700 (set_attr "fptype" "*,single")])
4703 [(set (match_operand:SI 0 "register_operand" "")
4704 (and:SI (match_operand:SI 1 "register_operand" "")
4705 (match_operand:SI 2 "const_compl_high_operand" "")))
4706 (clobber (match_operand:SI 3 "register_operand" ""))]
4708 [(set (match_dup 3) (match_dup 4))
4709 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4711 operands[4] = GEN_INT (~INTVAL (operands[2]));
4714 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4715 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4716 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4717 (match_operand:V64I 2 "register_operand" "r,b")))]
4721 fandnot1\t%1, %2, %0"
4722 "&& reload_completed
4723 && ((GET_CODE (operands[0]) == REG
4724 && REGNO (operands[0]) < 32)
4725 || (GET_CODE (operands[0]) == SUBREG
4726 && GET_CODE (SUBREG_REG (operands[0])) == REG
4727 && REGNO (SUBREG_REG (operands[0])) < 32))"
4728 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4729 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4730 "operands[3] = gen_highpart (SImode, operands[0]);
4731 operands[4] = gen_highpart (SImode, operands[1]);
4732 operands[5] = gen_highpart (SImode, operands[2]);
4733 operands[6] = gen_lowpart (SImode, operands[0]);
4734 operands[7] = gen_lowpart (SImode, operands[1]);
4735 operands[8] = gen_lowpart (SImode, operands[2]);"
4736 [(set_attr "type" "*,fga")
4737 (set_attr "length" "2,*")
4738 (set_attr "fptype" "*,double")])
4740 (define_insn "*and_not_<V64I:mode>_sp64"
4741 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4742 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4743 (match_operand:V64I 2 "register_operand" "r,b")))]
4747 fandnot1\t%1, %2, %0"
4748 [(set_attr "type" "*,fga")
4749 (set_attr "fptype" "*,double")])
4751 (define_insn "*and_not_<V32I:mode>"
4752 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4753 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4754 (match_operand:V32I 2 "register_operand" "r,d")))]
4758 fandnot1s\t%1, %2, %0"
4759 [(set_attr "type" "*,fga")
4760 (set_attr "fptype" "*,single")])
4762 (define_expand "ior<V64I:mode>3"
4763 [(set (match_operand:V64I 0 "register_operand" "")
4764 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4765 (match_operand:V64I 2 "arith_double_operand" "")))]
4769 (define_insn "*ior<V64I:mode>3_sp32"
4770 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4771 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4772 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4777 [(set_attr "type" "*,fga")
4778 (set_attr "length" "2,*")
4779 (set_attr "fptype" "*,double")])
4781 (define_insn "*ior<V64I:mode>3_sp64"
4782 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4783 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4784 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4789 [(set_attr "type" "*,fga")
4790 (set_attr "fptype" "*,double")])
4792 (define_insn "ior<V32I:mode>3"
4793 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4794 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4795 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4800 [(set_attr "type" "*,fga")
4801 (set_attr "fptype" "*,single")])
4804 [(set (match_operand:SI 0 "register_operand" "")
4805 (ior:SI (match_operand:SI 1 "register_operand" "")
4806 (match_operand:SI 2 "const_compl_high_operand" "")))
4807 (clobber (match_operand:SI 3 "register_operand" ""))]
4809 [(set (match_dup 3) (match_dup 4))
4810 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4812 operands[4] = GEN_INT (~INTVAL (operands[2]));
4815 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4816 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4817 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4818 (match_operand:V64I 2 "register_operand" "r,b")))]
4822 fornot1\t%1, %2, %0"
4823 "&& reload_completed
4824 && ((GET_CODE (operands[0]) == REG
4825 && REGNO (operands[0]) < 32)
4826 || (GET_CODE (operands[0]) == SUBREG
4827 && GET_CODE (SUBREG_REG (operands[0])) == REG
4828 && REGNO (SUBREG_REG (operands[0])) < 32))"
4829 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4830 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4831 "operands[3] = gen_highpart (SImode, operands[0]);
4832 operands[4] = gen_highpart (SImode, operands[1]);
4833 operands[5] = gen_highpart (SImode, operands[2]);
4834 operands[6] = gen_lowpart (SImode, operands[0]);
4835 operands[7] = gen_lowpart (SImode, operands[1]);
4836 operands[8] = gen_lowpart (SImode, operands[2]);"
4837 [(set_attr "type" "*,fga")
4838 (set_attr "length" "2,*")
4839 (set_attr "fptype" "*,double")])
4841 (define_insn "*or_not_<V64I:mode>_sp64"
4842 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4843 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4844 (match_operand:V64I 2 "register_operand" "r,b")))]
4848 fornot1\t%1, %2, %0"
4849 [(set_attr "type" "*,fga")
4850 (set_attr "fptype" "*,double")])
4852 (define_insn "*or_not_<V32I:mode>"
4853 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4854 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4855 (match_operand:V32I 2 "register_operand" "r,d")))]
4859 fornot1s\t%1, %2, %0"
4860 [(set_attr "type" "*,fga")
4861 (set_attr "fptype" "*,single")])
4863 (define_expand "xor<V64I:mode>3"
4864 [(set (match_operand:V64I 0 "register_operand" "")
4865 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4866 (match_operand:V64I 2 "arith_double_operand" "")))]
4870 (define_insn "*xor<V64I:mode>3_sp32"
4871 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4872 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4873 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4878 [(set_attr "type" "*,fga")
4879 (set_attr "length" "2,*")
4880 (set_attr "fptype" "*,double")])
4882 (define_insn "*xor<V64I:mode>3_sp64"
4883 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4884 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4885 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4890 [(set_attr "type" "*,fga")
4891 (set_attr "fptype" "*,double")])
4893 (define_insn "xor<V32I:mode>3"
4894 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4895 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4896 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4901 [(set_attr "type" "*,fga")
4902 (set_attr "fptype" "*,single")])
4905 [(set (match_operand:SI 0 "register_operand" "")
4906 (xor:SI (match_operand:SI 1 "register_operand" "")
4907 (match_operand:SI 2 "const_compl_high_operand" "")))
4908 (clobber (match_operand:SI 3 "register_operand" ""))]
4910 [(set (match_dup 3) (match_dup 4))
4911 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4913 operands[4] = GEN_INT (~INTVAL (operands[2]));
4917 [(set (match_operand:SI 0 "register_operand" "")
4918 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4919 (match_operand:SI 2 "const_compl_high_operand" ""))))
4920 (clobber (match_operand:SI 3 "register_operand" ""))]
4922 [(set (match_dup 3) (match_dup 4))
4923 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4925 operands[4] = GEN_INT (~INTVAL (operands[2]));
4928 ;; Split DImode logical operations requiring two instructions.
4930 [(set (match_operand:V64I 0 "register_operand" "")
4931 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4932 [(match_operand:V64I 2 "register_operand" "")
4933 (match_operand:V64I 3 "arith_double_operand" "")]))]
4936 && ((GET_CODE (operands[0]) == REG
4937 && REGNO (operands[0]) < 32)
4938 || (GET_CODE (operands[0]) == SUBREG
4939 && GET_CODE (SUBREG_REG (operands[0])) == REG
4940 && REGNO (SUBREG_REG (operands[0])) < 32))"
4941 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4942 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4944 operands[4] = gen_highpart (SImode, operands[0]);
4945 operands[5] = gen_lowpart (SImode, operands[0]);
4946 operands[6] = gen_highpart (SImode, operands[2]);
4947 operands[7] = gen_lowpart (SImode, operands[2]);
4948 #if HOST_BITS_PER_WIDE_INT == 32
4949 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4951 if (INTVAL (operands[3]) < 0)
4952 operands[8] = constm1_rtx;
4954 operands[8] = const0_rtx;
4958 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4959 operands[9] = gen_lowpart (SImode, operands[3]);
4962 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4963 ;; Combine now canonicalizes to the rightmost expression.
4964 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4965 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4966 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4967 (match_operand:V64I 2 "register_operand" "r,b"))))]
4972 "&& reload_completed
4973 && ((GET_CODE (operands[0]) == REG
4974 && REGNO (operands[0]) < 32)
4975 || (GET_CODE (operands[0]) == SUBREG
4976 && GET_CODE (SUBREG_REG (operands[0])) == REG
4977 && REGNO (SUBREG_REG (operands[0])) < 32))"
4978 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4979 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4980 "operands[3] = gen_highpart (SImode, operands[0]);
4981 operands[4] = gen_highpart (SImode, operands[1]);
4982 operands[5] = gen_highpart (SImode, operands[2]);
4983 operands[6] = gen_lowpart (SImode, operands[0]);
4984 operands[7] = gen_lowpart (SImode, operands[1]);
4985 operands[8] = gen_lowpart (SImode, operands[2]);"
4986 [(set_attr "type" "*,fga")
4987 (set_attr "length" "2,*")
4988 (set_attr "fptype" "*,double")])
4990 (define_insn "*xor_not_<V64I:mode>_sp64"
4991 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4992 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4993 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4998 [(set_attr "type" "*,fga")
4999 (set_attr "fptype" "*,double")])
5001 (define_insn "*xor_not_<V32I:mode>"
5002 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5003 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5004 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5009 [(set_attr "type" "*,fga")
5010 (set_attr "fptype" "*,single")])
5012 ;; These correspond to the above in the case where we also (or only)
5013 ;; want to set the condition code.
5015 (define_insn "*cmp_cc_arith_op"
5016 [(set (reg:CC CC_REG)
5018 (match_operator:SI 2 "cc_arith_operator"
5019 [(match_operand:SI 0 "arith_operand" "%r")
5020 (match_operand:SI 1 "arith_operand" "rI")])
5023 "%A2cc\t%0, %1, %%g0"
5024 [(set_attr "type" "compare")])
5026 (define_insn "*cmp_ccx_arith_op"
5027 [(set (reg:CCX CC_REG)
5029 (match_operator:DI 2 "cc_arith_operator"
5030 [(match_operand:DI 0 "arith_operand" "%r")
5031 (match_operand:DI 1 "arith_operand" "rI")])
5034 "%A2cc\t%0, %1, %%g0"
5035 [(set_attr "type" "compare")])
5037 (define_insn "*cmp_cc_arith_op_set"
5038 [(set (reg:CC CC_REG)
5040 (match_operator:SI 3 "cc_arith_operator"
5041 [(match_operand:SI 1 "arith_operand" "%r")
5042 (match_operand:SI 2 "arith_operand" "rI")])
5044 (set (match_operand:SI 0 "register_operand" "=r")
5045 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5046 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5048 [(set_attr "type" "compare")])
5050 (define_insn "*cmp_ccx_arith_op_set"
5051 [(set (reg:CCX CC_REG)
5053 (match_operator:DI 3 "cc_arith_operator"
5054 [(match_operand:DI 1 "arith_operand" "%r")
5055 (match_operand:DI 2 "arith_operand" "rI")])
5057 (set (match_operand:DI 0 "register_operand" "=r")
5058 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5059 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5061 [(set_attr "type" "compare")])
5063 (define_insn "*cmp_cc_xor_not"
5064 [(set (reg:CC CC_REG)
5066 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5067 (match_operand:SI 1 "arith_operand" "rI")))
5070 "xnorcc\t%r0, %1, %%g0"
5071 [(set_attr "type" "compare")])
5073 (define_insn "*cmp_ccx_xor_not"
5074 [(set (reg:CCX CC_REG)
5076 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5077 (match_operand:DI 1 "arith_operand" "rI")))
5080 "xnorcc\t%r0, %1, %%g0"
5081 [(set_attr "type" "compare")])
5083 (define_insn "*cmp_cc_xor_not_set"
5084 [(set (reg:CC CC_REG)
5086 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5087 (match_operand:SI 2 "arith_operand" "rI")))
5089 (set (match_operand:SI 0 "register_operand" "=r")
5090 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5092 "xnorcc\t%r1, %2, %0"
5093 [(set_attr "type" "compare")])
5095 (define_insn "*cmp_ccx_xor_not_set"
5096 [(set (reg:CCX CC_REG)
5098 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5099 (match_operand:DI 2 "arith_operand" "rI")))
5101 (set (match_operand:DI 0 "register_operand" "=r")
5102 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5104 "xnorcc\t%r1, %2, %0"
5105 [(set_attr "type" "compare")])
5107 (define_insn "*cmp_cc_arith_op_not"
5108 [(set (reg:CC CC_REG)
5110 (match_operator:SI 2 "cc_arith_not_operator"
5111 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5112 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5115 "%B2cc\t%r1, %0, %%g0"
5116 [(set_attr "type" "compare")])
5118 (define_insn "*cmp_ccx_arith_op_not"
5119 [(set (reg:CCX CC_REG)
5121 (match_operator:DI 2 "cc_arith_not_operator"
5122 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5123 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5126 "%B2cc\t%r1, %0, %%g0"
5127 [(set_attr "type" "compare")])
5129 (define_insn "*cmp_cc_arith_op_not_set"
5130 [(set (reg:CC CC_REG)
5132 (match_operator:SI 3 "cc_arith_not_operator"
5133 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5134 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5136 (set (match_operand:SI 0 "register_operand" "=r")
5137 (match_operator:SI 4 "cc_arith_not_operator"
5138 [(not:SI (match_dup 1)) (match_dup 2)]))]
5139 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5140 "%B3cc\t%r2, %1, %0"
5141 [(set_attr "type" "compare")])
5143 (define_insn "*cmp_ccx_arith_op_not_set"
5144 [(set (reg:CCX CC_REG)
5146 (match_operator:DI 3 "cc_arith_not_operator"
5147 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5148 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5150 (set (match_operand:DI 0 "register_operand" "=r")
5151 (match_operator:DI 4 "cc_arith_not_operator"
5152 [(not:DI (match_dup 1)) (match_dup 2)]))]
5153 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5154 "%B3cc\t%r2, %1, %0"
5155 [(set_attr "type" "compare")])
5157 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5158 ;; does not know how to make it work for constants.
5160 (define_expand "negdi2"
5161 [(set (match_operand:DI 0 "register_operand" "=r")
5162 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5165 if (! TARGET_ARCH64)
5167 emit_insn (gen_rtx_PARALLEL
5170 gen_rtx_SET (VOIDmode, operand0,
5171 gen_rtx_NEG (DImode, operand1)),
5172 gen_rtx_CLOBBER (VOIDmode,
5173 gen_rtx_REG (CCmode,
5179 (define_insn_and_split "*negdi2_sp32"
5180 [(set (match_operand:DI 0 "register_operand" "=r")
5181 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5182 (clobber (reg:CC CC_REG))]
5185 "&& reload_completed"
5186 [(parallel [(set (reg:CC_NOOV CC_REG)
5187 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5189 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5190 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5191 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5192 "operands[2] = gen_highpart (SImode, operands[0]);
5193 operands[3] = gen_highpart (SImode, operands[1]);
5194 operands[4] = gen_lowpart (SImode, operands[0]);
5195 operands[5] = gen_lowpart (SImode, operands[1]);"
5196 [(set_attr "length" "2")])
5198 (define_insn "*negdi2_sp64"
5199 [(set (match_operand:DI 0 "register_operand" "=r")
5200 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5202 "sub\t%%g0, %1, %0")
5204 (define_insn "negsi2"
5205 [(set (match_operand:SI 0 "register_operand" "=r")
5206 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5208 "sub\t%%g0, %1, %0")
5210 (define_insn "*cmp_cc_neg"
5211 [(set (reg:CC_NOOV CC_REG)
5212 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5215 "subcc\t%%g0, %0, %%g0"
5216 [(set_attr "type" "compare")])
5218 (define_insn "*cmp_ccx_neg"
5219 [(set (reg:CCX_NOOV CC_REG)
5220 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5223 "subcc\t%%g0, %0, %%g0"
5224 [(set_attr "type" "compare")])
5226 (define_insn "*cmp_cc_set_neg"
5227 [(set (reg:CC_NOOV CC_REG)
5228 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5230 (set (match_operand:SI 0 "register_operand" "=r")
5231 (neg:SI (match_dup 1)))]
5233 "subcc\t%%g0, %1, %0"
5234 [(set_attr "type" "compare")])
5236 (define_insn "*cmp_ccx_set_neg"
5237 [(set (reg:CCX_NOOV CC_REG)
5238 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5240 (set (match_operand:DI 0 "register_operand" "=r")
5241 (neg:DI (match_dup 1)))]
5243 "subcc\t%%g0, %1, %0"
5244 [(set_attr "type" "compare")])
5246 ;; We cannot use the "not" pseudo insn because the Sun assembler
5247 ;; does not know how to make it work for constants.
5248 (define_expand "one_cmpl<V64I:mode>2"
5249 [(set (match_operand:V64I 0 "register_operand" "")
5250 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5254 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5255 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5256 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5261 "&& reload_completed
5262 && ((GET_CODE (operands[0]) == REG
5263 && REGNO (operands[0]) < 32)
5264 || (GET_CODE (operands[0]) == SUBREG
5265 && GET_CODE (SUBREG_REG (operands[0])) == REG
5266 && REGNO (SUBREG_REG (operands[0])) < 32))"
5267 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5268 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5269 "operands[2] = gen_highpart (SImode, operands[0]);
5270 operands[3] = gen_highpart (SImode, operands[1]);
5271 operands[4] = gen_lowpart (SImode, operands[0]);
5272 operands[5] = gen_lowpart (SImode, operands[1]);"
5273 [(set_attr "type" "*,fga")
5274 (set_attr "length" "2,*")
5275 (set_attr "fptype" "*,double")])
5277 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5278 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5279 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5284 [(set_attr "type" "*,fga")
5285 (set_attr "fptype" "*,double")])
5287 (define_insn "one_cmpl<V32I:mode>2"
5288 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5289 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5294 [(set_attr "type" "*,fga")
5295 (set_attr "fptype" "*,single")])
5297 (define_insn "*cmp_cc_not"
5298 [(set (reg:CC CC_REG)
5299 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5302 "xnorcc\t%%g0, %0, %%g0"
5303 [(set_attr "type" "compare")])
5305 (define_insn "*cmp_ccx_not"
5306 [(set (reg:CCX CC_REG)
5307 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5310 "xnorcc\t%%g0, %0, %%g0"
5311 [(set_attr "type" "compare")])
5313 (define_insn "*cmp_cc_set_not"
5314 [(set (reg:CC CC_REG)
5315 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5317 (set (match_operand:SI 0 "register_operand" "=r")
5318 (not:SI (match_dup 1)))]
5320 "xnorcc\t%%g0, %1, %0"
5321 [(set_attr "type" "compare")])
5323 (define_insn "*cmp_ccx_set_not"
5324 [(set (reg:CCX CC_REG)
5325 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5327 (set (match_operand:DI 0 "register_operand" "=r")
5328 (not:DI (match_dup 1)))]
5330 "xnorcc\t%%g0, %1, %0"
5331 [(set_attr "type" "compare")])
5333 (define_insn "*cmp_cc_set"
5334 [(set (match_operand:SI 0 "register_operand" "=r")
5335 (match_operand:SI 1 "register_operand" "r"))
5336 (set (reg:CC CC_REG)
5337 (compare:CC (match_dup 1)
5341 [(set_attr "type" "compare")])
5343 (define_insn "*cmp_ccx_set64"
5344 [(set (match_operand:DI 0 "register_operand" "=r")
5345 (match_operand:DI 1 "register_operand" "r"))
5346 (set (reg:CCX CC_REG)
5347 (compare:CCX (match_dup 1)
5351 [(set_attr "type" "compare")])
5354 ;; Floating point arithmetic instructions.
5356 (define_expand "addtf3"
5357 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5358 (plus:TF (match_operand:TF 1 "general_operand" "")
5359 (match_operand:TF 2 "general_operand" "")))]
5360 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5361 "emit_tfmode_binop (PLUS, operands); DONE;")
5363 (define_insn "*addtf3_hq"
5364 [(set (match_operand:TF 0 "register_operand" "=e")
5365 (plus:TF (match_operand:TF 1 "register_operand" "e")
5366 (match_operand:TF 2 "register_operand" "e")))]
5367 "TARGET_FPU && TARGET_HARD_QUAD"
5369 [(set_attr "type" "fp")])
5371 (define_insn "adddf3"
5372 [(set (match_operand:DF 0 "register_operand" "=e")
5373 (plus:DF (match_operand:DF 1 "register_operand" "e")
5374 (match_operand:DF 2 "register_operand" "e")))]
5377 [(set_attr "type" "fp")
5378 (set_attr "fptype" "double")])
5380 (define_insn "addsf3"
5381 [(set (match_operand:SF 0 "register_operand" "=f")
5382 (plus:SF (match_operand:SF 1 "register_operand" "f")
5383 (match_operand:SF 2 "register_operand" "f")))]
5386 [(set_attr "type" "fp")])
5388 (define_expand "subtf3"
5389 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5390 (minus:TF (match_operand:TF 1 "general_operand" "")
5391 (match_operand:TF 2 "general_operand" "")))]
5392 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5393 "emit_tfmode_binop (MINUS, operands); DONE;")
5395 (define_insn "*subtf3_hq"
5396 [(set (match_operand:TF 0 "register_operand" "=e")
5397 (minus:TF (match_operand:TF 1 "register_operand" "e")
5398 (match_operand:TF 2 "register_operand" "e")))]
5399 "TARGET_FPU && TARGET_HARD_QUAD"
5401 [(set_attr "type" "fp")])
5403 (define_insn "subdf3"
5404 [(set (match_operand:DF 0 "register_operand" "=e")
5405 (minus:DF (match_operand:DF 1 "register_operand" "e")
5406 (match_operand:DF 2 "register_operand" "e")))]
5409 [(set_attr "type" "fp")
5410 (set_attr "fptype" "double")])
5412 (define_insn "subsf3"
5413 [(set (match_operand:SF 0 "register_operand" "=f")
5414 (minus:SF (match_operand:SF 1 "register_operand" "f")
5415 (match_operand:SF 2 "register_operand" "f")))]
5418 [(set_attr "type" "fp")])
5420 (define_expand "multf3"
5421 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5422 (mult:TF (match_operand:TF 1 "general_operand" "")
5423 (match_operand:TF 2 "general_operand" "")))]
5424 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5425 "emit_tfmode_binop (MULT, operands); DONE;")
5427 (define_insn "*multf3_hq"
5428 [(set (match_operand:TF 0 "register_operand" "=e")
5429 (mult:TF (match_operand:TF 1 "register_operand" "e")
5430 (match_operand:TF 2 "register_operand" "e")))]
5431 "TARGET_FPU && TARGET_HARD_QUAD"
5433 [(set_attr "type" "fpmul")])
5435 (define_insn "muldf3"
5436 [(set (match_operand:DF 0 "register_operand" "=e")
5437 (mult:DF (match_operand:DF 1 "register_operand" "e")
5438 (match_operand:DF 2 "register_operand" "e")))]
5441 [(set_attr "type" "fpmul")
5442 (set_attr "fptype" "double")])
5444 (define_insn "mulsf3"
5445 [(set (match_operand:SF 0 "register_operand" "=f")
5446 (mult:SF (match_operand:SF 1 "register_operand" "f")
5447 (match_operand:SF 2 "register_operand" "f")))]
5450 [(set_attr "type" "fpmul")])
5452 (define_insn "fmadf4"
5453 [(set (match_operand:DF 0 "register_operand" "=e")
5454 (fma:DF (match_operand:DF 1 "register_operand" "e")
5455 (match_operand:DF 2 "register_operand" "e")
5456 (match_operand:DF 3 "register_operand" "e")))]
5458 "fmaddd\t%1, %2, %3, %0"
5459 [(set_attr "type" "fpmul")])
5461 (define_insn "fmsdf4"
5462 [(set (match_operand:DF 0 "register_operand" "=e")
5463 (fma:DF (match_operand:DF 1 "register_operand" "e")
5464 (match_operand:DF 2 "register_operand" "e")
5465 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5467 "fmsubd\t%1, %2, %3, %0"
5468 [(set_attr "type" "fpmul")])
5470 (define_insn "*nfmadf4"
5471 [(set (match_operand:DF 0 "register_operand" "=e")
5472 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5473 (match_operand:DF 2 "register_operand" "e")
5474 (match_operand:DF 3 "register_operand" "e"))))]
5476 "fnmaddd\t%1, %2, %3, %0"
5477 [(set_attr "type" "fpmul")])
5479 (define_insn "*nfmsdf4"
5480 [(set (match_operand:DF 0 "register_operand" "=e")
5481 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5482 (match_operand:DF 2 "register_operand" "e")
5483 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5485 "fnmsubd\t%1, %2, %3, %0"
5486 [(set_attr "type" "fpmul")])
5488 (define_insn "fmasf4"
5489 [(set (match_operand:SF 0 "register_operand" "=f")
5490 (fma:SF (match_operand:SF 1 "register_operand" "f")
5491 (match_operand:SF 2 "register_operand" "f")
5492 (match_operand:SF 3 "register_operand" "f")))]
5494 "fmadds\t%1, %2, %3, %0"
5495 [(set_attr "type" "fpmul")])
5497 (define_insn "fmssf4"
5498 [(set (match_operand:SF 0 "register_operand" "=f")
5499 (fma:SF (match_operand:SF 1 "register_operand" "f")
5500 (match_operand:SF 2 "register_operand" "f")
5501 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5503 "fmsubs\t%1, %2, %3, %0"
5504 [(set_attr "type" "fpmul")])
5506 (define_insn "*nfmasf4"
5507 [(set (match_operand:SF 0 "register_operand" "=f")
5508 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5509 (match_operand:SF 2 "register_operand" "f")
5510 (match_operand:SF 3 "register_operand" "f"))))]
5512 "fnmadds\t%1, %2, %3, %0"
5513 [(set_attr "type" "fpmul")])
5515 (define_insn "*nfmssf4"
5516 [(set (match_operand:SF 0 "register_operand" "=f")
5517 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5518 (match_operand:SF 2 "register_operand" "f")
5519 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5521 "fnmsubs\t%1, %2, %3, %0"
5522 [(set_attr "type" "fpmul")])
5524 (define_insn "*muldf3_extend"
5525 [(set (match_operand:DF 0 "register_operand" "=e")
5526 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5527 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5528 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5529 "fsmuld\t%1, %2, %0"
5530 [(set_attr "type" "fpmul")
5531 (set_attr "fptype" "double")])
5533 (define_insn "*multf3_extend"
5534 [(set (match_operand:TF 0 "register_operand" "=e")
5535 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5536 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5537 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5538 "fdmulq\t%1, %2, %0"
5539 [(set_attr "type" "fpmul")])
5541 (define_expand "divtf3"
5542 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5543 (div:TF (match_operand:TF 1 "general_operand" "")
5544 (match_operand:TF 2 "general_operand" "")))]
5545 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5546 "emit_tfmode_binop (DIV, operands); DONE;")
5548 ;; don't have timing for quad-prec. divide.
5549 (define_insn "*divtf3_hq"
5550 [(set (match_operand:TF 0 "register_operand" "=e")
5551 (div:TF (match_operand:TF 1 "register_operand" "e")
5552 (match_operand:TF 2 "register_operand" "e")))]
5553 "TARGET_FPU && TARGET_HARD_QUAD"
5555 [(set_attr "type" "fpdivd")])
5557 (define_insn "divdf3"
5558 [(set (match_operand:DF 0 "register_operand" "=e")
5559 (div:DF (match_operand:DF 1 "register_operand" "e")
5560 (match_operand:DF 2 "register_operand" "e")))]
5563 [(set_attr "type" "fpdivd")
5564 (set_attr "fptype" "double")])
5566 (define_insn "divsf3"
5567 [(set (match_operand:SF 0 "register_operand" "=f")
5568 (div:SF (match_operand:SF 1 "register_operand" "f")
5569 (match_operand:SF 2 "register_operand" "f")))]
5572 [(set_attr "type" "fpdivs")])
5574 (define_expand "negtf2"
5575 [(set (match_operand:TF 0 "register_operand" "=e,e")
5576 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5580 (define_insn_and_split "*negtf2_notv9"
5581 [(set (match_operand:TF 0 "register_operand" "=e,e")
5582 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5583 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5589 "&& reload_completed
5590 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5591 [(set (match_dup 2) (neg:SF (match_dup 3)))
5592 (set (match_dup 4) (match_dup 5))
5593 (set (match_dup 6) (match_dup 7))]
5594 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5595 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5596 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5597 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5598 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5599 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5600 [(set_attr "type" "fpmove,*")
5601 (set_attr "length" "*,2")])
5603 (define_insn_and_split "*negtf2_v9"
5604 [(set (match_operand:TF 0 "register_operand" "=e,e")
5605 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5606 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5607 "TARGET_FPU && TARGET_V9"
5611 "&& reload_completed
5612 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5613 [(set (match_dup 2) (neg:DF (match_dup 3)))
5614 (set (match_dup 4) (match_dup 5))]
5615 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5616 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5617 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5618 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5619 [(set_attr "type" "fpmove,*")
5620 (set_attr "length" "*,2")
5621 (set_attr "fptype" "double")])
5623 (define_expand "negdf2"
5624 [(set (match_operand:DF 0 "register_operand" "")
5625 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5629 (define_insn_and_split "*negdf2_notv9"
5630 [(set (match_operand:DF 0 "register_operand" "=e,e")
5631 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5632 "TARGET_FPU && ! TARGET_V9"
5636 "&& reload_completed
5637 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5638 [(set (match_dup 2) (neg:SF (match_dup 3)))
5639 (set (match_dup 4) (match_dup 5))]
5640 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5641 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5642 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5643 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5644 [(set_attr "type" "fpmove,*")
5645 (set_attr "length" "*,2")])
5647 (define_insn "*negdf2_v9"
5648 [(set (match_operand:DF 0 "register_operand" "=e")
5649 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5650 "TARGET_FPU && TARGET_V9"
5652 [(set_attr "type" "fpmove")
5653 (set_attr "fptype" "double")])
5655 (define_insn "negsf2"
5656 [(set (match_operand:SF 0 "register_operand" "=f")
5657 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5660 [(set_attr "type" "fpmove")])
5662 (define_expand "abstf2"
5663 [(set (match_operand:TF 0 "register_operand" "")
5664 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5668 (define_insn_and_split "*abstf2_notv9"
5669 [(set (match_operand:TF 0 "register_operand" "=e,e")
5670 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5671 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5672 "TARGET_FPU && ! TARGET_V9"
5676 "&& reload_completed
5677 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5678 [(set (match_dup 2) (abs:SF (match_dup 3)))
5679 (set (match_dup 4) (match_dup 5))
5680 (set (match_dup 6) (match_dup 7))]
5681 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5682 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5683 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5684 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5685 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5686 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5687 [(set_attr "type" "fpmove,*")
5688 (set_attr "length" "*,2")])
5690 (define_insn "*abstf2_hq_v9"
5691 [(set (match_operand:TF 0 "register_operand" "=e,e")
5692 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5693 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5697 [(set_attr "type" "fpmove")
5698 (set_attr "fptype" "double,*")])
5700 (define_insn_and_split "*abstf2_v9"
5701 [(set (match_operand:TF 0 "register_operand" "=e,e")
5702 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5703 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5707 "&& reload_completed
5708 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5709 [(set (match_dup 2) (abs:DF (match_dup 3)))
5710 (set (match_dup 4) (match_dup 5))]
5711 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5712 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5713 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5714 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5715 [(set_attr "type" "fpmove,*")
5716 (set_attr "length" "*,2")
5717 (set_attr "fptype" "double,*")])
5719 (define_expand "absdf2"
5720 [(set (match_operand:DF 0 "register_operand" "")
5721 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5725 (define_insn_and_split "*absdf2_notv9"
5726 [(set (match_operand:DF 0 "register_operand" "=e,e")
5727 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5728 "TARGET_FPU && ! TARGET_V9"
5732 "&& reload_completed
5733 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5734 [(set (match_dup 2) (abs:SF (match_dup 3)))
5735 (set (match_dup 4) (match_dup 5))]
5736 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5737 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5738 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5739 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5740 [(set_attr "type" "fpmove,*")
5741 (set_attr "length" "*,2")])
5743 (define_insn "*absdf2_v9"
5744 [(set (match_operand:DF 0 "register_operand" "=e")
5745 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5746 "TARGET_FPU && TARGET_V9"
5748 [(set_attr "type" "fpmove")
5749 (set_attr "fptype" "double")])
5751 (define_insn "abssf2"
5752 [(set (match_operand:SF 0 "register_operand" "=f")
5753 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5756 [(set_attr "type" "fpmove")])
5758 (define_expand "sqrttf2"
5759 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5760 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5761 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5762 "emit_tfmode_unop (SQRT, operands); DONE;")
5764 (define_insn "*sqrttf2_hq"
5765 [(set (match_operand:TF 0 "register_operand" "=e")
5766 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5767 "TARGET_FPU && TARGET_HARD_QUAD"
5769 [(set_attr "type" "fpsqrtd")])
5771 (define_insn "sqrtdf2"
5772 [(set (match_operand:DF 0 "register_operand" "=e")
5773 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5776 [(set_attr "type" "fpsqrtd")
5777 (set_attr "fptype" "double")])
5779 (define_insn "sqrtsf2"
5780 [(set (match_operand:SF 0 "register_operand" "=f")
5781 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5784 [(set_attr "type" "fpsqrts")])
5787 ;; Arithmetic shift instructions.
5789 (define_insn "ashlsi3"
5790 [(set (match_operand:SI 0 "register_operand" "=r")
5791 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5792 (match_operand:SI 2 "arith_operand" "rI")))]
5795 if (GET_CODE (operands[2]) == CONST_INT)
5796 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5797 return "sll\t%1, %2, %0";
5800 (if_then_else (match_operand 2 "const_one_operand" "")
5801 (const_string "ialu") (const_string "shift")))])
5803 (define_expand "ashldi3"
5804 [(set (match_operand:DI 0 "register_operand" "=r")
5805 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5806 (match_operand:SI 2 "arith_operand" "rI")))]
5807 "TARGET_ARCH64 || TARGET_V8PLUS"
5809 if (! TARGET_ARCH64)
5811 if (GET_CODE (operands[2]) == CONST_INT)
5813 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5818 (define_insn "*ashldi3_sp64"
5819 [(set (match_operand:DI 0 "register_operand" "=r")
5820 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5821 (match_operand:SI 2 "arith_operand" "rI")))]
5824 if (GET_CODE (operands[2]) == CONST_INT)
5825 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5826 return "sllx\t%1, %2, %0";
5829 (if_then_else (match_operand 2 "const_one_operand" "")
5830 (const_string "ialu") (const_string "shift")))])
5833 (define_insn "ashldi3_v8plus"
5834 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5835 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5836 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5837 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5839 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5840 [(set_attr "type" "multi")
5841 (set_attr "length" "5,5,6")])
5843 ;; Optimize (1LL<<x)-1
5844 ;; XXX this also needs to be fixed to handle equal subregs
5845 ;; XXX first before we could re-enable it.
5847 ; [(set (match_operand:DI 0 "register_operand" "=h")
5848 ; (plus:DI (ashift:DI (const_int 1)
5849 ; (match_operand:SI 1 "arith_operand" "rI"))
5851 ; "0 && TARGET_V8PLUS"
5853 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5854 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5855 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5857 ; [(set_attr "type" "multi")
5858 ; (set_attr "length" "4")])
5860 (define_insn "*cmp_cc_ashift_1"
5861 [(set (reg:CC_NOOV CC_REG)
5862 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5866 "addcc\t%0, %0, %%g0"
5867 [(set_attr "type" "compare")])
5869 (define_insn "*cmp_cc_set_ashift_1"
5870 [(set (reg:CC_NOOV CC_REG)
5871 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5874 (set (match_operand:SI 0 "register_operand" "=r")
5875 (ashift:SI (match_dup 1) (const_int 1)))]
5878 [(set_attr "type" "compare")])
5880 (define_insn "ashrsi3"
5881 [(set (match_operand:SI 0 "register_operand" "=r")
5882 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5883 (match_operand:SI 2 "arith_operand" "rI")))]
5886 if (GET_CODE (operands[2]) == CONST_INT)
5887 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5888 return "sra\t%1, %2, %0";
5890 [(set_attr "type" "shift")])
5892 (define_insn "*ashrsi3_extend"
5893 [(set (match_operand:DI 0 "register_operand" "=r")
5894 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5895 (match_operand:SI 2 "arith_operand" "r"))))]
5898 [(set_attr "type" "shift")])
5900 ;; This handles the case as above, but with constant shift instead of
5901 ;; register. Combiner "simplifies" it for us a little bit though.
5902 (define_insn "*ashrsi3_extend2"
5903 [(set (match_operand:DI 0 "register_operand" "=r")
5904 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5906 (match_operand:SI 2 "small_int_operand" "I")))]
5907 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5909 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5910 return "sra\t%1, %2, %0";
5912 [(set_attr "type" "shift")])
5914 (define_expand "ashrdi3"
5915 [(set (match_operand:DI 0 "register_operand" "=r")
5916 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5917 (match_operand:SI 2 "arith_operand" "rI")))]
5918 "TARGET_ARCH64 || TARGET_V8PLUS"
5920 if (! TARGET_ARCH64)
5922 if (GET_CODE (operands[2]) == CONST_INT)
5923 FAIL; /* prefer generic code in this case */
5924 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5929 (define_insn "*ashrdi3_sp64"
5930 [(set (match_operand:DI 0 "register_operand" "=r")
5931 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5932 (match_operand:SI 2 "arith_operand" "rI")))]
5936 if (GET_CODE (operands[2]) == CONST_INT)
5937 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5938 return "srax\t%1, %2, %0";
5940 [(set_attr "type" "shift")])
5943 (define_insn "ashrdi3_v8plus"
5944 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5945 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5946 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5947 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5949 "* return output_v8plus_shift (operands, insn, \"srax\");"
5950 [(set_attr "type" "multi")
5951 (set_attr "length" "5,5,6")])
5953 (define_insn "lshrsi3"
5954 [(set (match_operand:SI 0 "register_operand" "=r")
5955 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5956 (match_operand:SI 2 "arith_operand" "rI")))]
5959 if (GET_CODE (operands[2]) == CONST_INT)
5960 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5961 return "srl\t%1, %2, %0";
5963 [(set_attr "type" "shift")])
5965 ;; This handles the case where
5966 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5967 ;; but combiner "simplifies" it for us.
5968 (define_insn "*lshrsi3_extend"
5969 [(set (match_operand:DI 0 "register_operand" "=r")
5970 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5971 (match_operand:SI 2 "arith_operand" "r")) 0)
5972 (match_operand 3 "const_int_operand" "")))]
5973 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5975 [(set_attr "type" "shift")])
5977 ;; This handles the case where
5978 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5979 ;; but combiner "simplifies" it for us.
5980 (define_insn "*lshrsi3_extend2"
5981 [(set (match_operand:DI 0 "register_operand" "=r")
5982 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5983 (match_operand 2 "small_int_operand" "I")
5985 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5987 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5988 return "srl\t%1, %2, %0";
5990 [(set_attr "type" "shift")])
5992 (define_expand "lshrdi3"
5993 [(set (match_operand:DI 0 "register_operand" "=r")
5994 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5995 (match_operand:SI 2 "arith_operand" "rI")))]
5996 "TARGET_ARCH64 || TARGET_V8PLUS"
5998 if (! TARGET_ARCH64)
6000 if (GET_CODE (operands[2]) == CONST_INT)
6002 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6007 (define_insn "*lshrdi3_sp64"
6008 [(set (match_operand:DI 0 "register_operand" "=r")
6009 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6010 (match_operand:SI 2 "arith_operand" "rI")))]
6013 if (GET_CODE (operands[2]) == CONST_INT)
6014 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6015 return "srlx\t%1, %2, %0";
6017 [(set_attr "type" "shift")])
6020 (define_insn "lshrdi3_v8plus"
6021 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6022 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6023 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6024 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6026 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6027 [(set_attr "type" "multi")
6028 (set_attr "length" "5,5,6")])
6031 [(set (match_operand:SI 0 "register_operand" "=r")
6032 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6034 (match_operand:SI 2 "small_int_operand" "I")))]
6035 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6037 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6038 return "srax\t%1, %2, %0";
6040 [(set_attr "type" "shift")])
6043 [(set (match_operand:SI 0 "register_operand" "=r")
6044 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6046 (match_operand:SI 2 "small_int_operand" "I")))]
6047 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6049 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6050 return "srlx\t%1, %2, %0";
6052 [(set_attr "type" "shift")])
6055 [(set (match_operand:SI 0 "register_operand" "=r")
6056 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6057 (match_operand:SI 2 "small_int_operand" "I")) 4)
6058 (match_operand:SI 3 "small_int_operand" "I")))]
6060 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6061 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6062 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6064 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6066 return "srax\t%1, %2, %0";
6068 [(set_attr "type" "shift")])
6071 [(set (match_operand:SI 0 "register_operand" "=r")
6072 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6073 (match_operand:SI 2 "small_int_operand" "I")) 4)
6074 (match_operand:SI 3 "small_int_operand" "I")))]
6076 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6077 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6078 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6080 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6082 return "srlx\t%1, %2, %0";
6084 [(set_attr "type" "shift")])
6087 ;; Unconditional and other jump instructions.
6090 [(set (pc) (label_ref (match_operand 0 "" "")))]
6092 "* return output_ubranch (operands[0], 0, insn);"
6093 [(set_attr "type" "uncond_branch")])
6095 (define_expand "tablejump"
6096 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6097 (use (label_ref (match_operand 1 "" "")))])]
6100 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6102 /* In pic mode, our address differences are against the base of the
6103 table. Add that base value back in; CSE ought to be able to combine
6104 the two address loads. */
6108 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6110 if (CASE_VECTOR_MODE != Pmode)
6111 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6112 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6113 operands[0] = memory_address (Pmode, tmp);
6117 (define_insn "*tablejump_sp32"
6118 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6119 (use (label_ref (match_operand 1 "" "")))]
6122 [(set_attr "type" "uncond_branch")])
6124 (define_insn "*tablejump_sp64"
6125 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6126 (use (label_ref (match_operand 1 "" "")))]
6129 [(set_attr "type" "uncond_branch")])
6132 ;; Jump to subroutine instructions.
6134 (define_expand "call"
6135 ;; Note that this expression is not used for generating RTL.
6136 ;; All the RTL is generated explicitly below.
6137 [(call (match_operand 0 "call_operand" "")
6138 (match_operand 3 "" "i"))]
6139 ;; operands[2] is next_arg_register
6140 ;; operands[3] is struct_value_size_rtx.
6145 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6147 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6149 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6151 /* This is really a PIC sequence. We want to represent
6152 it as a funny jump so its delay slots can be filled.
6154 ??? But if this really *is* a CALL, will not it clobber the
6155 call-clobbered registers? We lose this if it is a JUMP_INSN.
6156 Why cannot we have delay slots filled if it were a CALL? */
6158 /* We accept negative sizes for untyped calls. */
6159 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6164 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6166 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6172 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6173 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6177 fn_rtx = operands[0];
6179 /* We accept negative sizes for untyped calls. */
6180 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6181 sparc_emit_call_insn
6184 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6186 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6189 sparc_emit_call_insn
6192 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6193 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6201 ;; We can't use the same pattern for these two insns, because then registers
6202 ;; in the address may not be properly reloaded.
6204 (define_insn "*call_address_sp32"
6205 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6206 (match_operand 1 "" ""))
6207 (clobber (reg:SI O7_REG))]
6208 ;;- Do not use operand 1 for most machines.
6211 [(set_attr "type" "call")])
6213 (define_insn "*call_symbolic_sp32"
6214 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6215 (match_operand 1 "" ""))
6216 (clobber (reg:SI O7_REG))]
6217 ;;- Do not use operand 1 for most machines.
6220 [(set_attr "type" "call")])
6222 (define_insn "*call_address_sp64"
6223 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6224 (match_operand 1 "" ""))
6225 (clobber (reg:DI O7_REG))]
6226 ;;- Do not use operand 1 for most machines.
6229 [(set_attr "type" "call")])
6231 (define_insn "*call_symbolic_sp64"
6232 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6233 (match_operand 1 "" ""))
6234 (clobber (reg:DI O7_REG))]
6235 ;;- Do not use operand 1 for most machines.
6238 [(set_attr "type" "call")])
6240 ;; This is a call that wants a structure value.
6241 ;; There is no such critter for v9 (??? we may need one anyway).
6242 (define_insn "*call_address_struct_value_sp32"
6243 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6244 (match_operand 1 "" ""))
6245 (match_operand 2 "immediate_operand" "")
6246 (clobber (reg:SI O7_REG))]
6247 ;;- Do not use operand 1 for most machines.
6248 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6250 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6251 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6253 [(set_attr "type" "call_no_delay_slot")
6254 (set_attr "length" "3")])
6256 ;; This is a call that wants a structure value.
6257 ;; There is no such critter for v9 (??? we may need one anyway).
6258 (define_insn "*call_symbolic_struct_value_sp32"
6259 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6260 (match_operand 1 "" ""))
6261 (match_operand 2 "immediate_operand" "")
6262 (clobber (reg:SI O7_REG))]
6263 ;;- Do not use operand 1 for most machines.
6264 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6266 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6267 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6269 [(set_attr "type" "call_no_delay_slot")
6270 (set_attr "length" "3")])
6272 ;; This is a call that may want a structure value. This is used for
6274 (define_insn "*call_address_untyped_struct_value_sp32"
6275 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6276 (match_operand 1 "" ""))
6277 (match_operand 2 "immediate_operand" "")
6278 (clobber (reg:SI O7_REG))]
6279 ;;- Do not use operand 1 for most machines.
6280 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6281 "call\t%a0, %1\n\t nop\n\tnop"
6282 [(set_attr "type" "call_no_delay_slot")
6283 (set_attr "length" "3")])
6285 ;; This is a call that may want a structure value. This is used for
6287 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6288 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6289 (match_operand 1 "" ""))
6290 (match_operand 2 "immediate_operand" "")
6291 (clobber (reg:SI O7_REG))]
6292 ;;- Do not use operand 1 for most machines.
6293 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6294 "call\t%a0, %1\n\t nop\n\tnop"
6295 [(set_attr "type" "call_no_delay_slot")
6296 (set_attr "length" "3")])
6298 (define_expand "call_value"
6299 ;; Note that this expression is not used for generating RTL.
6300 ;; All the RTL is generated explicitly below.
6301 [(set (match_operand 0 "register_operand" "=rf")
6302 (call (match_operand 1 "" "")
6303 (match_operand 4 "" "")))]
6304 ;; operand 2 is stack_size_rtx
6305 ;; operand 3 is next_arg_register
6311 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6313 fn_rtx = operands[1];
6316 gen_rtx_SET (VOIDmode, operands[0],
6317 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6318 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6320 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6325 (define_insn "*call_value_address_sp32"
6326 [(set (match_operand 0 "" "=rf")
6327 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6328 (match_operand 2 "" "")))
6329 (clobber (reg:SI O7_REG))]
6330 ;;- Do not use operand 2 for most machines.
6333 [(set_attr "type" "call")])
6335 (define_insn "*call_value_symbolic_sp32"
6336 [(set (match_operand 0 "" "=rf")
6337 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6338 (match_operand 2 "" "")))
6339 (clobber (reg:SI O7_REG))]
6340 ;;- Do not use operand 2 for most machines.
6343 [(set_attr "type" "call")])
6345 (define_insn "*call_value_address_sp64"
6346 [(set (match_operand 0 "" "")
6347 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6348 (match_operand 2 "" "")))
6349 (clobber (reg:DI O7_REG))]
6350 ;;- Do not use operand 2 for most machines.
6353 [(set_attr "type" "call")])
6355 (define_insn "*call_value_symbolic_sp64"
6356 [(set (match_operand 0 "" "")
6357 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6358 (match_operand 2 "" "")))
6359 (clobber (reg:DI O7_REG))]
6360 ;;- Do not use operand 2 for most machines.
6363 [(set_attr "type" "call")])
6365 (define_expand "untyped_call"
6366 [(parallel [(call (match_operand 0 "" "")
6368 (match_operand:BLK 1 "memory_operand" "")
6369 (match_operand 2 "" "")])]
6372 rtx valreg1 = gen_rtx_REG (DImode, 8);
6373 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6374 rtx result = operands[1];
6376 /* Pass constm1 to indicate that it may expect a structure value, but
6377 we don't know what size it is. */
6378 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6380 /* Save the function value registers. */
6381 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6382 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6385 /* The optimizer does not know that the call sets the function value
6386 registers we stored in the result block. We avoid problems by
6387 claiming that all hard registers are used and clobbered at this
6389 emit_insn (gen_blockage ());
6394 ;; Tail call instructions.
6396 (define_expand "sibcall"
6397 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6402 (define_insn "*sibcall_symbolic_sp32"
6403 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6404 (match_operand 1 "" ""))
6407 "* return output_sibcall(insn, operands[0]);"
6408 [(set_attr "type" "sibcall")])
6410 (define_insn "*sibcall_symbolic_sp64"
6411 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6412 (match_operand 1 "" ""))
6415 "* return output_sibcall(insn, operands[0]);"
6416 [(set_attr "type" "sibcall")])
6418 (define_expand "sibcall_value"
6419 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6420 (call (match_operand 1 "" "") (const_int 0)))
6425 (define_insn "*sibcall_value_symbolic_sp32"
6426 [(set (match_operand 0 "" "=rf")
6427 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6428 (match_operand 2 "" "")))
6431 "* return output_sibcall(insn, operands[1]);"
6432 [(set_attr "type" "sibcall")])
6434 (define_insn "*sibcall_value_symbolic_sp64"
6435 [(set (match_operand 0 "" "")
6436 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6437 (match_operand 2 "" "")))
6440 "* return output_sibcall(insn, operands[1]);"
6441 [(set_attr "type" "sibcall")])
6444 ;; Special instructions.
6446 (define_expand "prologue"
6451 sparc_flat_expand_prologue ();
6453 sparc_expand_prologue ();
6457 ;; The "register window save" insn is modelled as follows. The dwarf2
6458 ;; information is manually added in emit_window_save.
6460 (define_insn "window_save"
6462 [(match_operand 0 "arith_operand" "rI")]
6465 "save\t%%sp, %0, %%sp"
6466 [(set_attr "type" "savew")])
6468 (define_expand "epilogue"
6473 sparc_flat_expand_epilogue (false);
6475 sparc_expand_epilogue (false);
6478 (define_expand "sibcall_epilogue"
6483 sparc_flat_expand_epilogue (false);
6485 sparc_expand_epilogue (false);
6489 (define_expand "eh_return"
6490 [(use (match_operand 0 "general_operand" ""))]
6493 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6494 emit_jump_insn (gen_eh_return_internal ());
6499 (define_insn_and_split "eh_return_internal"
6503 "epilogue_completed"
6507 sparc_flat_expand_epilogue (true);
6509 sparc_expand_epilogue (true);
6512 (define_expand "return"
6514 "sparc_can_use_return_insn_p ()"
6517 (define_insn "*return_internal"
6520 "* return output_return (insn);"
6521 [(set_attr "type" "return")
6522 (set (attr "length")
6523 (cond [(eq_attr "calls_eh_return" "true")
6524 (if_then_else (eq_attr "delayed_branch" "true")
6525 (if_then_else (ior (eq_attr "isa" "v9")
6526 (eq_attr "flat" "true"))
6529 (if_then_else (eq_attr "flat" "true")
6532 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6533 (if_then_else (eq_attr "empty_delay_slot" "true")
6536 (eq_attr "empty_delay_slot" "true")
6537 (if_then_else (eq_attr "delayed_branch" "true")
6542 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6543 ;; all of memory. This blocks insns from being moved across this point.
6545 (define_insn "blockage"
6546 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6549 [(set_attr "length" "0")])
6551 (define_expand "probe_stack"
6552 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6556 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6559 (define_insn "probe_stack_range<P:mode>"
6560 [(set (match_operand:P 0 "register_operand" "=r")
6561 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6562 (match_operand:P 2 "register_operand" "r")]
6563 UNSPECV_PROBE_STACK_RANGE))]
6565 "* return output_probe_stack_range (operands[0], operands[2]);"
6566 [(set_attr "type" "multi")])
6568 ;; Prepare to return any type including a structure value.
6570 (define_expand "untyped_return"
6571 [(match_operand:BLK 0 "memory_operand" "")
6572 (match_operand 1 "" "")]
6575 rtx valreg1 = gen_rtx_REG (DImode, 24);
6576 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6577 rtx result = operands[0];
6579 if (! TARGET_ARCH64)
6581 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6582 rtx value = gen_reg_rtx (SImode);
6584 /* Fetch the instruction where we will return to and see if it's an unimp
6585 instruction (the most significant 10 bits will be zero). If so,
6586 update the return address to skip the unimp instruction. */
6587 emit_move_insn (value,
6588 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6589 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6590 emit_insn (gen_update_return (rtnreg, value));
6593 /* Reload the function value registers. */
6594 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6595 emit_move_insn (valreg2,
6596 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6598 /* Put USE insns before the return. */
6602 /* Construct the return. */
6603 expand_naked_return ();
6608 ;; Adjust the return address conditionally. If the value of op1 is equal
6609 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6610 ;; This is technically *half* the check required by the 32-bit SPARC
6611 ;; psABI. This check only ensures that an "unimp" insn was written by
6612 ;; the caller, but doesn't check to see if the expected size matches
6613 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6614 ;; only used by the above code "untyped_return".
6616 (define_insn "update_return"
6617 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6618 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6621 if (flag_delayed_branch)
6622 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6624 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6626 [(set (attr "type") (const_string "multi"))
6627 (set (attr "length")
6628 (if_then_else (eq_attr "delayed_branch" "true")
6637 (define_expand "indirect_jump"
6638 [(set (pc) (match_operand 0 "address_operand" "p"))]
6642 (define_insn "*branch_sp32"
6643 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6646 [(set_attr "type" "uncond_branch")])
6648 (define_insn "*branch_sp64"
6649 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6652 [(set_attr "type" "uncond_branch")])
6654 (define_expand "save_stack_nonlocal"
6655 [(set (match_operand 0 "memory_operand" "")
6656 (match_operand 1 "register_operand" ""))
6657 (set (match_dup 2) (match_dup 3))]
6660 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6661 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6662 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6665 (define_expand "restore_stack_nonlocal"
6666 [(set (match_operand 0 "register_operand" "")
6667 (match_operand 1 "memory_operand" ""))]
6670 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6673 (define_expand "nonlocal_goto"
6674 [(match_operand 0 "general_operand" "")
6675 (match_operand 1 "general_operand" "")
6676 (match_operand 2 "memory_operand" "")
6677 (match_operand 3 "memory_operand" "")]
6680 rtx r_label = copy_to_reg (operands[1]);
6681 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6682 rtx r_fp = operands[3];
6683 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6685 /* We need to flush all the register windows so that their contents will
6686 be re-synchronized by the restore insn of the target function. */
6688 emit_insn (gen_flush_register_windows ());
6690 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6691 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6693 /* Restore frame pointer for containing function. */
6694 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6695 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6697 /* USE of hard_frame_pointer_rtx added for consistency;
6698 not clear if really needed. */
6699 emit_use (hard_frame_pointer_rtx);
6700 emit_use (stack_pointer_rtx);
6702 /* We need to smuggle the load of %i7 as it is a fixed register. */
6703 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6708 (define_insn "nonlocal_goto_internal"
6709 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6710 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6711 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6713 if (flag_delayed_branch)
6716 return "jmp\t%0\n\t ldx\t%1, %%i7";
6718 return "jmp\t%0\n\t ld\t%1, %%i7";
6723 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6725 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6728 [(set (attr "type") (const_string "multi"))
6729 (set (attr "length")
6730 (if_then_else (eq_attr "delayed_branch" "true")
6734 (define_expand "builtin_setjmp_receiver"
6735 [(label_ref (match_operand 0 "" ""))]
6738 load_got_register ();
6742 ;; Special insn to flush register windows.
6744 (define_insn "flush_register_windows"
6745 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6747 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6748 [(set_attr "type" "flushw")])
6750 ;; Special pattern for the FLUSH instruction.
6752 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6753 ; of the define_insn otherwise missing a mode. We make "flush", aka
6754 ; gen_flush, the default one since sparc_initialize_trampoline uses
6755 ; it on SImode mem values.
6757 (define_insn "flush"
6758 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6760 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6761 [(set_attr "type" "iflush")])
6763 (define_insn "flushdi"
6764 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6766 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6767 [(set_attr "type" "iflush")])
6770 ;; Find first set instructions.
6772 ;; The scan instruction searches from the most significant bit while ffs
6773 ;; searches from the least significant bit. The bit index and treatment of
6774 ;; zero also differ. It takes at least 7 instructions to get the proper
6775 ;; result. Here is an obvious 8 instruction sequence.
6778 (define_insn "ffssi2"
6779 [(set (match_operand:SI 0 "register_operand" "=&r")
6780 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6781 (clobber (match_scratch:SI 2 "=&r"))]
6782 "TARGET_SPARCLITE || TARGET_SPARCLET"
6784 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";
6786 [(set_attr "type" "multi")
6787 (set_attr "length" "8")])
6789 ;; ??? This should be a define expand, so that the extra instruction have
6790 ;; a chance of being optimized away.
6792 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6793 ;; does, but no one uses that and we don't have a switch for it.
6795 ;(define_insn "ffsdi2"
6796 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6797 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6798 ; (clobber (match_scratch:DI 2 "=&r"))]
6800 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6801 ; [(set_attr "type" "multi")
6802 ; (set_attr "length" "4")])
6806 ;; Peepholes go at the end.
6808 ;; Optimize consecutive loads or stores into ldd and std when possible.
6809 ;; The conditions in which we do this are very restricted and are
6810 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6813 [(set (match_operand:SI 0 "memory_operand" "")
6815 (set (match_operand:SI 1 "memory_operand" "")
6818 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6821 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6824 [(set (match_operand:SI 0 "memory_operand" "")
6826 (set (match_operand:SI 1 "memory_operand" "")
6829 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6832 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6835 [(set (match_operand:SI 0 "register_operand" "")
6836 (match_operand:SI 1 "memory_operand" ""))
6837 (set (match_operand:SI 2 "register_operand" "")
6838 (match_operand:SI 3 "memory_operand" ""))]
6839 "registers_ok_for_ldd_peep (operands[0], operands[2])
6840 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6843 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6844 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6847 [(set (match_operand:SI 0 "memory_operand" "")
6848 (match_operand:SI 1 "register_operand" ""))
6849 (set (match_operand:SI 2 "memory_operand" "")
6850 (match_operand:SI 3 "register_operand" ""))]
6851 "registers_ok_for_ldd_peep (operands[1], operands[3])
6852 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6855 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6856 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6859 [(set (match_operand:SF 0 "register_operand" "")
6860 (match_operand:SF 1 "memory_operand" ""))
6861 (set (match_operand:SF 2 "register_operand" "")
6862 (match_operand:SF 3 "memory_operand" ""))]
6863 "registers_ok_for_ldd_peep (operands[0], operands[2])
6864 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6867 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6868 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6871 [(set (match_operand:SF 0 "memory_operand" "")
6872 (match_operand:SF 1 "register_operand" ""))
6873 (set (match_operand:SF 2 "memory_operand" "")
6874 (match_operand:SF 3 "register_operand" ""))]
6875 "registers_ok_for_ldd_peep (operands[1], operands[3])
6876 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6879 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6880 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6883 [(set (match_operand:SI 0 "register_operand" "")
6884 (match_operand:SI 1 "memory_operand" ""))
6885 (set (match_operand:SI 2 "register_operand" "")
6886 (match_operand:SI 3 "memory_operand" ""))]
6887 "registers_ok_for_ldd_peep (operands[2], operands[0])
6888 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6891 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6892 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6895 [(set (match_operand:SI 0 "memory_operand" "")
6896 (match_operand:SI 1 "register_operand" ""))
6897 (set (match_operand:SI 2 "memory_operand" "")
6898 (match_operand:SI 3 "register_operand" ""))]
6899 "registers_ok_for_ldd_peep (operands[3], operands[1])
6900 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6903 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6904 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6908 [(set (match_operand:SF 0 "register_operand" "")
6909 (match_operand:SF 1 "memory_operand" ""))
6910 (set (match_operand:SF 2 "register_operand" "")
6911 (match_operand:SF 3 "memory_operand" ""))]
6912 "registers_ok_for_ldd_peep (operands[2], operands[0])
6913 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6916 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6917 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6920 [(set (match_operand:SF 0 "memory_operand" "")
6921 (match_operand:SF 1 "register_operand" ""))
6922 (set (match_operand:SF 2 "memory_operand" "")
6923 (match_operand:SF 3 "register_operand" ""))]
6924 "registers_ok_for_ldd_peep (operands[3], operands[1])
6925 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6928 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6929 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6931 ;; Optimize the case of following a reg-reg move with a test
6932 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6933 ;; This can result from a float to fix conversion.
6936 [(set (match_operand:SI 0 "register_operand" "")
6937 (match_operand:SI 1 "register_operand" ""))
6938 (set (reg:CC CC_REG)
6939 (compare:CC (match_operand:SI 2 "register_operand" "")
6941 "(rtx_equal_p (operands[2], operands[0])
6942 || rtx_equal_p (operands[2], operands[1]))
6943 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6944 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6945 [(parallel [(set (match_dup 0) (match_dup 1))
6946 (set (reg:CC CC_REG)
6947 (compare:CC (match_dup 1) (const_int 0)))])]
6951 [(set (match_operand:DI 0 "register_operand" "")
6952 (match_operand:DI 1 "register_operand" ""))
6953 (set (reg:CCX CC_REG)
6954 (compare:CCX (match_operand:DI 2 "register_operand" "")
6957 && (rtx_equal_p (operands[2], operands[0])
6958 || rtx_equal_p (operands[2], operands[1]))
6959 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6960 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6961 [(parallel [(set (match_dup 0) (match_dup 1))
6962 (set (reg:CCX CC_REG)
6963 (compare:CCX (match_dup 1) (const_int 0)))])]
6967 ;; Prefetch instructions.
6969 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6970 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6971 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6973 (define_expand "prefetch"
6974 [(match_operand 0 "address_operand" "")
6975 (match_operand 1 "const_int_operand" "")
6976 (match_operand 2 "const_int_operand" "")]
6980 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6982 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6986 (define_insn "prefetch_64"
6987 [(prefetch (match_operand:DI 0 "address_operand" "p")
6988 (match_operand:DI 1 "const_int_operand" "n")
6989 (match_operand:DI 2 "const_int_operand" "n"))]
6992 static const char * const prefetch_instr[2][2] = {
6994 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6995 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6998 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6999 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7002 int read_or_write = INTVAL (operands[1]);
7003 int locality = INTVAL (operands[2]);
7005 gcc_assert (read_or_write == 0 || read_or_write == 1);
7006 gcc_assert (locality >= 0 && locality < 4);
7007 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7009 [(set_attr "type" "load")])
7011 (define_insn "prefetch_32"
7012 [(prefetch (match_operand:SI 0 "address_operand" "p")
7013 (match_operand:SI 1 "const_int_operand" "n")
7014 (match_operand:SI 2 "const_int_operand" "n"))]
7017 static const char * const prefetch_instr[2][2] = {
7019 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7020 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7023 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7024 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7027 int read_or_write = INTVAL (operands[1]);
7028 int locality = INTVAL (operands[2]);
7030 gcc_assert (read_or_write == 0 || read_or_write == 1);
7031 gcc_assert (locality >= 0 && locality < 4);
7032 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7034 [(set_attr "type" "load")])
7037 ;; Trap instructions.
7040 [(trap_if (const_int 1) (const_int 5))]
7043 [(set_attr "type" "trap")])
7045 (define_expand "ctrapsi4"
7046 [(trap_if (match_operator 0 "noov_compare_operator"
7047 [(match_operand:SI 1 "compare_operand" "")
7048 (match_operand:SI 2 "arith_operand" "")])
7049 (match_operand 3 ""))]
7051 "operands[1] = gen_compare_reg (operands[0]);
7052 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7054 operands[2] = const0_rtx;")
7056 (define_expand "ctrapdi4"
7057 [(trap_if (match_operator 0 "noov_compare_operator"
7058 [(match_operand:DI 1 "compare_operand" "")
7059 (match_operand:DI 2 "arith_operand" "")])
7060 (match_operand 3 ""))]
7062 "operands[1] = gen_compare_reg (operands[0]);
7063 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7065 operands[2] = const0_rtx;")
7069 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7070 (match_operand:SI 1 "arith_operand" "rM"))]
7074 return "t%C0\t%%icc, %1";
7078 [(set_attr "type" "trap")])
7081 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7082 (match_operand:SI 1 "arith_operand" "rM"))]
7085 [(set_attr "type" "trap")])
7088 ;; TLS support instructions.
7090 (define_insn "tgd_hi22"
7091 [(set (match_operand:SI 0 "register_operand" "=r")
7092 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7095 "sethi\\t%%tgd_hi22(%a1), %0")
7097 (define_insn "tgd_lo10"
7098 [(set (match_operand:SI 0 "register_operand" "=r")
7099 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7100 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7103 "add\\t%1, %%tgd_lo10(%a2), %0")
7105 (define_insn "tgd_add32"
7106 [(set (match_operand:SI 0 "register_operand" "=r")
7107 (plus:SI (match_operand:SI 1 "register_operand" "r")
7108 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7109 (match_operand 3 "tgd_symbolic_operand" "")]
7111 "TARGET_TLS && TARGET_ARCH32"
7112 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7114 (define_insn "tgd_add64"
7115 [(set (match_operand:DI 0 "register_operand" "=r")
7116 (plus:DI (match_operand:DI 1 "register_operand" "r")
7117 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7118 (match_operand 3 "tgd_symbolic_operand" "")]
7120 "TARGET_TLS && TARGET_ARCH64"
7121 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7123 (define_insn "tgd_call32"
7124 [(set (match_operand 0 "register_operand" "=r")
7125 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7126 (match_operand 2 "tgd_symbolic_operand" "")]
7128 (match_operand 3 "" "")))
7129 (clobber (reg:SI O7_REG))]
7130 "TARGET_TLS && TARGET_ARCH32"
7131 "call\t%a1, %%tgd_call(%a2)%#"
7132 [(set_attr "type" "call")])
7134 (define_insn "tgd_call64"
7135 [(set (match_operand 0 "register_operand" "=r")
7136 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7137 (match_operand 2 "tgd_symbolic_operand" "")]
7139 (match_operand 3 "" "")))
7140 (clobber (reg:DI O7_REG))]
7141 "TARGET_TLS && TARGET_ARCH64"
7142 "call\t%a1, %%tgd_call(%a2)%#"
7143 [(set_attr "type" "call")])
7145 (define_insn "tldm_hi22"
7146 [(set (match_operand:SI 0 "register_operand" "=r")
7147 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7149 "sethi\\t%%tldm_hi22(%&), %0")
7151 (define_insn "tldm_lo10"
7152 [(set (match_operand:SI 0 "register_operand" "=r")
7153 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7154 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7156 "add\\t%1, %%tldm_lo10(%&), %0")
7158 (define_insn "tldm_add32"
7159 [(set (match_operand:SI 0 "register_operand" "=r")
7160 (plus:SI (match_operand:SI 1 "register_operand" "r")
7161 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7163 "TARGET_TLS && TARGET_ARCH32"
7164 "add\\t%1, %2, %0, %%tldm_add(%&)")
7166 (define_insn "tldm_add64"
7167 [(set (match_operand:DI 0 "register_operand" "=r")
7168 (plus:DI (match_operand:DI 1 "register_operand" "r")
7169 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7171 "TARGET_TLS && TARGET_ARCH64"
7172 "add\\t%1, %2, %0, %%tldm_add(%&)")
7174 (define_insn "tldm_call32"
7175 [(set (match_operand 0 "register_operand" "=r")
7176 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7178 (match_operand 2 "" "")))
7179 (clobber (reg:SI O7_REG))]
7180 "TARGET_TLS && TARGET_ARCH32"
7181 "call\t%a1, %%tldm_call(%&)%#"
7182 [(set_attr "type" "call")])
7184 (define_insn "tldm_call64"
7185 [(set (match_operand 0 "register_operand" "=r")
7186 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7188 (match_operand 2 "" "")))
7189 (clobber (reg:DI O7_REG))]
7190 "TARGET_TLS && TARGET_ARCH64"
7191 "call\t%a1, %%tldm_call(%&)%#"
7192 [(set_attr "type" "call")])
7194 (define_insn "tldo_hix22"
7195 [(set (match_operand:SI 0 "register_operand" "=r")
7196 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7199 "sethi\\t%%tldo_hix22(%a1), %0")
7201 (define_insn "tldo_lox10"
7202 [(set (match_operand:SI 0 "register_operand" "=r")
7203 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7204 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7207 "xor\\t%1, %%tldo_lox10(%a2), %0")
7209 (define_insn "tldo_add32"
7210 [(set (match_operand:SI 0 "register_operand" "=r")
7211 (plus:SI (match_operand:SI 1 "register_operand" "r")
7212 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7213 (match_operand 3 "tld_symbolic_operand" "")]
7215 "TARGET_TLS && TARGET_ARCH32"
7216 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7218 (define_insn "tldo_add64"
7219 [(set (match_operand:DI 0 "register_operand" "=r")
7220 (plus:DI (match_operand:DI 1 "register_operand" "r")
7221 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7222 (match_operand 3 "tld_symbolic_operand" "")]
7224 "TARGET_TLS && TARGET_ARCH64"
7225 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7227 (define_insn "tie_hi22"
7228 [(set (match_operand:SI 0 "register_operand" "=r")
7229 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7232 "sethi\\t%%tie_hi22(%a1), %0")
7234 (define_insn "tie_lo10"
7235 [(set (match_operand:SI 0 "register_operand" "=r")
7236 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7237 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7240 "add\\t%1, %%tie_lo10(%a2), %0")
7242 (define_insn "tie_ld32"
7243 [(set (match_operand:SI 0 "register_operand" "=r")
7244 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7245 (match_operand:SI 2 "register_operand" "r")
7246 (match_operand 3 "tie_symbolic_operand" "")]
7248 "TARGET_TLS && TARGET_ARCH32"
7249 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7250 [(set_attr "type" "load")])
7252 (define_insn "tie_ld64"
7253 [(set (match_operand:DI 0 "register_operand" "=r")
7254 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7255 (match_operand:SI 2 "register_operand" "r")
7256 (match_operand 3 "tie_symbolic_operand" "")]
7258 "TARGET_TLS && TARGET_ARCH64"
7259 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7260 [(set_attr "type" "load")])
7262 (define_insn "tie_add32"
7263 [(set (match_operand:SI 0 "register_operand" "=r")
7264 (plus:SI (match_operand:SI 1 "register_operand" "r")
7265 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7266 (match_operand 3 "tie_symbolic_operand" "")]
7268 "TARGET_SUN_TLS && TARGET_ARCH32"
7269 "add\\t%1, %2, %0, %%tie_add(%a3)")
7271 (define_insn "tie_add64"
7272 [(set (match_operand:DI 0 "register_operand" "=r")
7273 (plus:DI (match_operand:DI 1 "register_operand" "r")
7274 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7275 (match_operand 3 "tie_symbolic_operand" "")]
7277 "TARGET_SUN_TLS && TARGET_ARCH64"
7278 "add\\t%1, %2, %0, %%tie_add(%a3)")
7280 (define_insn "tle_hix22_sp32"
7281 [(set (match_operand:SI 0 "register_operand" "=r")
7282 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7284 "TARGET_TLS && TARGET_ARCH32"
7285 "sethi\\t%%tle_hix22(%a1), %0")
7287 (define_insn "tle_lox10_sp32"
7288 [(set (match_operand:SI 0 "register_operand" "=r")
7289 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7290 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7292 "TARGET_TLS && TARGET_ARCH32"
7293 "xor\\t%1, %%tle_lox10(%a2), %0")
7295 (define_insn "tle_hix22_sp64"
7296 [(set (match_operand:DI 0 "register_operand" "=r")
7297 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7299 "TARGET_TLS && TARGET_ARCH64"
7300 "sethi\\t%%tle_hix22(%a1), %0")
7302 (define_insn "tle_lox10_sp64"
7303 [(set (match_operand:DI 0 "register_operand" "=r")
7304 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7305 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7307 "TARGET_TLS && TARGET_ARCH64"
7308 "xor\\t%1, %%tle_lox10(%a2), %0")
7310 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7311 (define_insn "*tldo_ldub_sp32"
7312 [(set (match_operand:QI 0 "register_operand" "=r")
7313 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7314 (match_operand 3 "tld_symbolic_operand" "")]
7316 (match_operand:SI 1 "register_operand" "r"))))]
7317 "TARGET_TLS && TARGET_ARCH32"
7318 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7319 [(set_attr "type" "load")
7320 (set_attr "us3load_type" "3cycle")])
7322 (define_insn "*tldo_ldub1_sp32"
7323 [(set (match_operand:HI 0 "register_operand" "=r")
7324 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7325 (match_operand 3 "tld_symbolic_operand" "")]
7327 (match_operand:SI 1 "register_operand" "r")))))]
7328 "TARGET_TLS && TARGET_ARCH32"
7329 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7330 [(set_attr "type" "load")
7331 (set_attr "us3load_type" "3cycle")])
7333 (define_insn "*tldo_ldub2_sp32"
7334 [(set (match_operand:SI 0 "register_operand" "=r")
7335 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7336 (match_operand 3 "tld_symbolic_operand" "")]
7338 (match_operand:SI 1 "register_operand" "r")))))]
7339 "TARGET_TLS && TARGET_ARCH32"
7340 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7341 [(set_attr "type" "load")
7342 (set_attr "us3load_type" "3cycle")])
7344 (define_insn "*tldo_ldsb1_sp32"
7345 [(set (match_operand:HI 0 "register_operand" "=r")
7346 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7347 (match_operand 3 "tld_symbolic_operand" "")]
7349 (match_operand:SI 1 "register_operand" "r")))))]
7350 "TARGET_TLS && TARGET_ARCH32"
7351 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7352 [(set_attr "type" "sload")
7353 (set_attr "us3load_type" "3cycle")])
7355 (define_insn "*tldo_ldsb2_sp32"
7356 [(set (match_operand:SI 0 "register_operand" "=r")
7357 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7358 (match_operand 3 "tld_symbolic_operand" "")]
7360 (match_operand:SI 1 "register_operand" "r")))))]
7361 "TARGET_TLS && TARGET_ARCH32"
7362 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7363 [(set_attr "type" "sload")
7364 (set_attr "us3load_type" "3cycle")])
7366 (define_insn "*tldo_ldub_sp64"
7367 [(set (match_operand:QI 0 "register_operand" "=r")
7368 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7369 (match_operand 3 "tld_symbolic_operand" "")]
7371 (match_operand:DI 1 "register_operand" "r"))))]
7372 "TARGET_TLS && TARGET_ARCH64"
7373 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7374 [(set_attr "type" "load")
7375 (set_attr "us3load_type" "3cycle")])
7377 (define_insn "*tldo_ldub1_sp64"
7378 [(set (match_operand:HI 0 "register_operand" "=r")
7379 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7380 (match_operand 3 "tld_symbolic_operand" "")]
7382 (match_operand:DI 1 "register_operand" "r")))))]
7383 "TARGET_TLS && TARGET_ARCH64"
7384 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7385 [(set_attr "type" "load")
7386 (set_attr "us3load_type" "3cycle")])
7388 (define_insn "*tldo_ldub2_sp64"
7389 [(set (match_operand:SI 0 "register_operand" "=r")
7390 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7391 (match_operand 3 "tld_symbolic_operand" "")]
7393 (match_operand:DI 1 "register_operand" "r")))))]
7394 "TARGET_TLS && TARGET_ARCH64"
7395 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7396 [(set_attr "type" "load")
7397 (set_attr "us3load_type" "3cycle")])
7399 (define_insn "*tldo_ldub3_sp64"
7400 [(set (match_operand:DI 0 "register_operand" "=r")
7401 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7402 (match_operand 3 "tld_symbolic_operand" "")]
7404 (match_operand:DI 1 "register_operand" "r")))))]
7405 "TARGET_TLS && TARGET_ARCH64"
7406 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7407 [(set_attr "type" "load")
7408 (set_attr "us3load_type" "3cycle")])
7410 (define_insn "*tldo_ldsb1_sp64"
7411 [(set (match_operand:HI 0 "register_operand" "=r")
7412 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7413 (match_operand 3 "tld_symbolic_operand" "")]
7415 (match_operand:DI 1 "register_operand" "r")))))]
7416 "TARGET_TLS && TARGET_ARCH64"
7417 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7418 [(set_attr "type" "sload")
7419 (set_attr "us3load_type" "3cycle")])
7421 (define_insn "*tldo_ldsb2_sp64"
7422 [(set (match_operand:SI 0 "register_operand" "=r")
7423 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7424 (match_operand 3 "tld_symbolic_operand" "")]
7426 (match_operand:DI 1 "register_operand" "r")))))]
7427 "TARGET_TLS && TARGET_ARCH64"
7428 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7429 [(set_attr "type" "sload")
7430 (set_attr "us3load_type" "3cycle")])
7432 (define_insn "*tldo_ldsb3_sp64"
7433 [(set (match_operand:DI 0 "register_operand" "=r")
7434 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7435 (match_operand 3 "tld_symbolic_operand" "")]
7437 (match_operand:DI 1 "register_operand" "r")))))]
7438 "TARGET_TLS && TARGET_ARCH64"
7439 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7440 [(set_attr "type" "sload")
7441 (set_attr "us3load_type" "3cycle")])
7443 (define_insn "*tldo_lduh_sp32"
7444 [(set (match_operand:HI 0 "register_operand" "=r")
7445 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7446 (match_operand 3 "tld_symbolic_operand" "")]
7448 (match_operand:SI 1 "register_operand" "r"))))]
7449 "TARGET_TLS && TARGET_ARCH32"
7450 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7451 [(set_attr "type" "load")
7452 (set_attr "us3load_type" "3cycle")])
7454 (define_insn "*tldo_lduh1_sp32"
7455 [(set (match_operand:SI 0 "register_operand" "=r")
7456 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7457 (match_operand 3 "tld_symbolic_operand" "")]
7459 (match_operand:SI 1 "register_operand" "r")))))]
7460 "TARGET_TLS && TARGET_ARCH32"
7461 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7462 [(set_attr "type" "load")
7463 (set_attr "us3load_type" "3cycle")])
7465 (define_insn "*tldo_ldsh1_sp32"
7466 [(set (match_operand:SI 0 "register_operand" "=r")
7467 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7468 (match_operand 3 "tld_symbolic_operand" "")]
7470 (match_operand:SI 1 "register_operand" "r")))))]
7471 "TARGET_TLS && TARGET_ARCH32"
7472 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7473 [(set_attr "type" "sload")
7474 (set_attr "us3load_type" "3cycle")])
7476 (define_insn "*tldo_lduh_sp64"
7477 [(set (match_operand:HI 0 "register_operand" "=r")
7478 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7479 (match_operand 3 "tld_symbolic_operand" "")]
7481 (match_operand:DI 1 "register_operand" "r"))))]
7482 "TARGET_TLS && TARGET_ARCH64"
7483 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7484 [(set_attr "type" "load")
7485 (set_attr "us3load_type" "3cycle")])
7487 (define_insn "*tldo_lduh1_sp64"
7488 [(set (match_operand:SI 0 "register_operand" "=r")
7489 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7490 (match_operand 3 "tld_symbolic_operand" "")]
7492 (match_operand:DI 1 "register_operand" "r")))))]
7493 "TARGET_TLS && TARGET_ARCH64"
7494 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7495 [(set_attr "type" "load")
7496 (set_attr "us3load_type" "3cycle")])
7498 (define_insn "*tldo_lduh2_sp64"
7499 [(set (match_operand:DI 0 "register_operand" "=r")
7500 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7501 (match_operand 3 "tld_symbolic_operand" "")]
7503 (match_operand:DI 1 "register_operand" "r")))))]
7504 "TARGET_TLS && TARGET_ARCH64"
7505 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7506 [(set_attr "type" "load")
7507 (set_attr "us3load_type" "3cycle")])
7509 (define_insn "*tldo_ldsh1_sp64"
7510 [(set (match_operand:SI 0 "register_operand" "=r")
7511 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7512 (match_operand 3 "tld_symbolic_operand" "")]
7514 (match_operand:DI 1 "register_operand" "r")))))]
7515 "TARGET_TLS && TARGET_ARCH64"
7516 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7517 [(set_attr "type" "sload")
7518 (set_attr "us3load_type" "3cycle")])
7520 (define_insn "*tldo_ldsh2_sp64"
7521 [(set (match_operand:DI 0 "register_operand" "=r")
7522 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7523 (match_operand 3 "tld_symbolic_operand" "")]
7525 (match_operand:DI 1 "register_operand" "r")))))]
7526 "TARGET_TLS && TARGET_ARCH64"
7527 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7528 [(set_attr "type" "sload")
7529 (set_attr "us3load_type" "3cycle")])
7531 (define_insn "*tldo_lduw_sp32"
7532 [(set (match_operand:SI 0 "register_operand" "=r")
7533 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7534 (match_operand 3 "tld_symbolic_operand" "")]
7536 (match_operand:SI 1 "register_operand" "r"))))]
7537 "TARGET_TLS && TARGET_ARCH32"
7538 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7539 [(set_attr "type" "load")])
7541 (define_insn "*tldo_lduw_sp64"
7542 [(set (match_operand:SI 0 "register_operand" "=r")
7543 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7544 (match_operand 3 "tld_symbolic_operand" "")]
7546 (match_operand:DI 1 "register_operand" "r"))))]
7547 "TARGET_TLS && TARGET_ARCH64"
7548 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7549 [(set_attr "type" "load")])
7551 (define_insn "*tldo_lduw1_sp64"
7552 [(set (match_operand:DI 0 "register_operand" "=r")
7553 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7554 (match_operand 3 "tld_symbolic_operand" "")]
7556 (match_operand:DI 1 "register_operand" "r")))))]
7557 "TARGET_TLS && TARGET_ARCH64"
7558 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7559 [(set_attr "type" "load")])
7561 (define_insn "*tldo_ldsw1_sp64"
7562 [(set (match_operand:DI 0 "register_operand" "=r")
7563 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7564 (match_operand 3 "tld_symbolic_operand" "")]
7566 (match_operand:DI 1 "register_operand" "r")))))]
7567 "TARGET_TLS && TARGET_ARCH64"
7568 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7569 [(set_attr "type" "sload")
7570 (set_attr "us3load_type" "3cycle")])
7572 (define_insn "*tldo_ldx_sp64"
7573 [(set (match_operand:DI 0 "register_operand" "=r")
7574 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7575 (match_operand 3 "tld_symbolic_operand" "")]
7577 (match_operand:DI 1 "register_operand" "r"))))]
7578 "TARGET_TLS && TARGET_ARCH64"
7579 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7580 [(set_attr "type" "load")])
7582 (define_insn "*tldo_stb_sp32"
7583 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7584 (match_operand 3 "tld_symbolic_operand" "")]
7586 (match_operand:SI 1 "register_operand" "r")))
7587 (match_operand:QI 0 "register_operand" "=r"))]
7588 "TARGET_TLS && TARGET_ARCH32"
7589 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7590 [(set_attr "type" "store")])
7592 (define_insn "*tldo_stb_sp64"
7593 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7594 (match_operand 3 "tld_symbolic_operand" "")]
7596 (match_operand:DI 1 "register_operand" "r")))
7597 (match_operand:QI 0 "register_operand" "=r"))]
7598 "TARGET_TLS && TARGET_ARCH64"
7599 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7600 [(set_attr "type" "store")])
7602 (define_insn "*tldo_sth_sp32"
7603 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7604 (match_operand 3 "tld_symbolic_operand" "")]
7606 (match_operand:SI 1 "register_operand" "r")))
7607 (match_operand:HI 0 "register_operand" "=r"))]
7608 "TARGET_TLS && TARGET_ARCH32"
7609 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7610 [(set_attr "type" "store")])
7612 (define_insn "*tldo_sth_sp64"
7613 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7614 (match_operand 3 "tld_symbolic_operand" "")]
7616 (match_operand:DI 1 "register_operand" "r")))
7617 (match_operand:HI 0 "register_operand" "=r"))]
7618 "TARGET_TLS && TARGET_ARCH64"
7619 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7620 [(set_attr "type" "store")])
7622 (define_insn "*tldo_stw_sp32"
7623 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7624 (match_operand 3 "tld_symbolic_operand" "")]
7626 (match_operand:SI 1 "register_operand" "r")))
7627 (match_operand:SI 0 "register_operand" "=r"))]
7628 "TARGET_TLS && TARGET_ARCH32"
7629 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7630 [(set_attr "type" "store")])
7632 (define_insn "*tldo_stw_sp64"
7633 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7634 (match_operand 3 "tld_symbolic_operand" "")]
7636 (match_operand:DI 1 "register_operand" "r")))
7637 (match_operand:SI 0 "register_operand" "=r"))]
7638 "TARGET_TLS && TARGET_ARCH64"
7639 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7640 [(set_attr "type" "store")])
7642 (define_insn "*tldo_stx_sp64"
7643 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7644 (match_operand 3 "tld_symbolic_operand" "")]
7646 (match_operand:DI 1 "register_operand" "r")))
7647 (match_operand:DI 0 "register_operand" "=r"))]
7648 "TARGET_TLS && TARGET_ARCH64"
7649 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7650 [(set_attr "type" "store")])
7653 ;; Stack protector instructions.
7655 (define_expand "stack_protect_set"
7656 [(match_operand 0 "memory_operand" "")
7657 (match_operand 1 "memory_operand" "")]
7660 #ifdef TARGET_THREAD_SSP_OFFSET
7661 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7662 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7663 operands[1] = gen_rtx_MEM (Pmode, addr);
7666 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7668 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7672 (define_insn "stack_protect_setsi"
7673 [(set (match_operand:SI 0 "memory_operand" "=m")
7674 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7675 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7677 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7678 [(set_attr "type" "multi")
7679 (set_attr "length" "3")])
7681 (define_insn "stack_protect_setdi"
7682 [(set (match_operand:DI 0 "memory_operand" "=m")
7683 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7684 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7686 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7687 [(set_attr "type" "multi")
7688 (set_attr "length" "3")])
7690 (define_expand "stack_protect_test"
7691 [(match_operand 0 "memory_operand" "")
7692 (match_operand 1 "memory_operand" "")
7693 (match_operand 2 "" "")]
7697 #ifdef TARGET_THREAD_SSP_OFFSET
7698 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7699 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7700 operands[1] = gen_rtx_MEM (Pmode, addr);
7704 result = gen_reg_rtx (Pmode);
7705 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7706 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7707 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7711 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7712 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7713 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7714 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7719 (define_insn "stack_protect_testsi"
7720 [(set (reg:CC CC_REG)
7721 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7722 (match_operand:SI 1 "memory_operand" "m")]
7724 (set (match_scratch:SI 3 "=r") (const_int 0))
7725 (clobber (match_scratch:SI 2 "=&r"))]
7727 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7728 [(set_attr "type" "multi")
7729 (set_attr "length" "4")])
7731 (define_insn "stack_protect_testdi"
7732 [(set (match_operand:DI 0 "register_operand" "=&r")
7733 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7734 (match_operand:DI 2 "memory_operand" "m")]
7736 (set (match_scratch:DI 3 "=r") (const_int 0))]
7738 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7739 [(set_attr "type" "multi")
7740 (set_attr "length" "4")])
7743 ;; Vector instructions.
7745 (define_insn "addv2si3"
7746 [(set (match_operand:V2SI 0 "register_operand" "=e")
7747 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7748 (match_operand:V2SI 2 "register_operand" "e")))]
7750 "fpadd32\t%1, %2, %0"
7751 [(set_attr "type" "fga")
7752 (set_attr "fptype" "double")])
7754 (define_insn "addv4hi3"
7755 [(set (match_operand:V4HI 0 "register_operand" "=e")
7756 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7757 (match_operand:V4HI 2 "register_operand" "e")))]
7759 "fpadd16\t%1, %2, %0"
7760 [(set_attr "type" "fga")
7761 (set_attr "fptype" "double")])
7763 ;; fpadd32s is emitted by the addsi3 pattern.
7765 (define_insn "addv2hi3"
7766 [(set (match_operand:V2HI 0 "register_operand" "=f")
7767 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7768 (match_operand:V2HI 2 "register_operand" "f")))]
7770 "fpadd16s\t%1, %2, %0"
7771 [(set_attr "type" "fga")
7772 (set_attr "fptype" "single")])
7774 (define_insn "subv2si3"
7775 [(set (match_operand:V2SI 0 "register_operand" "=e")
7776 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7777 (match_operand:V2SI 2 "register_operand" "e")))]
7779 "fpsub32\t%1, %2, %0"
7780 [(set_attr "type" "fga")
7781 (set_attr "fptype" "double")])
7783 (define_insn "subv4hi3"
7784 [(set (match_operand:V4HI 0 "register_operand" "=e")
7785 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7786 (match_operand:V4HI 2 "register_operand" "e")))]
7788 "fpsub16\t%1, %2, %0"
7789 [(set_attr "type" "fga")
7790 (set_attr "fptype" "double")])
7792 ;; fpsub32s is emitted by the subsi3 pattern.
7794 (define_insn "subv2hi3"
7795 [(set (match_operand:V2HI 0 "register_operand" "=f")
7796 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7797 (match_operand:V2HI 2 "register_operand" "f")))]
7799 "fpsub16s\t%1, %2, %0"
7800 [(set_attr "type" "fga")
7801 (set_attr "fptype" "single")])
7803 ;; All other logical instructions have integer equivalents so they
7804 ;; are defined together.
7806 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7808 (define_insn "*nand<V64:mode>_vis"
7809 [(set (match_operand:V64 0 "register_operand" "=e")
7810 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7811 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7814 [(set_attr "type" "fga")
7815 (set_attr "fptype" "double")])
7817 (define_insn "*nand<V32:mode>_vis"
7818 [(set (match_operand:V32 0 "register_operand" "=f")
7819 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7820 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7822 "fnands\t%1, %2, %0"
7823 [(set_attr "type" "fga")
7824 (set_attr "fptype" "single")])
7826 ;; Hard to generate VIS instructions. We have builtins for these.
7828 (define_insn "fpack16_vis"
7829 [(set (match_operand:V4QI 0 "register_operand" "=f")
7830 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7832 (use (reg:DI GSR_REG))]
7835 [(set_attr "type" "fga")
7836 (set_attr "fptype" "double")])
7838 (define_insn "fpackfix_vis"
7839 [(set (match_operand:V2HI 0 "register_operand" "=f")
7840 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7842 (use (reg:DI GSR_REG))]
7845 [(set_attr "type" "fga")
7846 (set_attr "fptype" "double")])
7848 (define_insn "fpack32_vis"
7849 [(set (match_operand:V8QI 0 "register_operand" "=e")
7850 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7851 (match_operand:V8QI 2 "register_operand" "e")]
7853 (use (reg:DI GSR_REG))]
7855 "fpack32\t%1, %2, %0"
7856 [(set_attr "type" "fga")
7857 (set_attr "fptype" "double")])
7859 (define_insn "fexpand_vis"
7860 [(set (match_operand:V4HI 0 "register_operand" "=e")
7861 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7865 [(set_attr "type" "fga")
7866 (set_attr "fptype" "double")])
7868 ;; It may be possible to describe this operation as (1 indexed):
7869 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7870 ;; 1,5,10,14,19,23,28,32)
7871 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7872 ;; because vec_merge expects all the operands to be of the same type.
7873 (define_insn "fpmerge_vis"
7874 [(set (match_operand:V8QI 0 "register_operand" "=e")
7875 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7876 (match_operand:V4QI 2 "register_operand" "f")]
7879 "fpmerge\t%1, %2, %0"
7880 [(set_attr "type" "fga")
7881 (set_attr "fptype" "double")])
7883 ;; Partitioned multiply instructions
7884 (define_insn "fmul8x16_vis"
7885 [(set (match_operand:V4HI 0 "register_operand" "=e")
7886 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7887 (match_operand:V4HI 2 "register_operand" "e")))]
7889 "fmul8x16\t%1, %2, %0"
7890 [(set_attr "type" "fpmul")
7891 (set_attr "fptype" "double")])
7893 ;; Only one of the following two insns can be a multiply.
7894 (define_insn "fmul8x16au_vis"
7895 [(set (match_operand:V4HI 0 "register_operand" "=e")
7896 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7897 (match_operand:V2HI 2 "register_operand" "f")))]
7899 "fmul8x16au\t%1, %2, %0"
7900 [(set_attr "type" "fpmul")
7901 (set_attr "fptype" "double")])
7903 (define_insn "fmul8x16al_vis"
7904 [(set (match_operand:V4HI 0 "register_operand" "=e")
7905 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7906 (match_operand:V2HI 2 "register_operand" "f")]
7909 "fmul8x16al\t%1, %2, %0"
7910 [(set_attr "type" "fpmul")
7911 (set_attr "fptype" "double")])
7913 ;; Only one of the following two insns can be a multiply.
7914 (define_insn "fmul8sux16_vis"
7915 [(set (match_operand:V4HI 0 "register_operand" "=e")
7916 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7917 (match_operand:V4HI 2 "register_operand" "e")))]
7919 "fmul8sux16\t%1, %2, %0"
7920 [(set_attr "type" "fpmul")
7921 (set_attr "fptype" "double")])
7923 (define_insn "fmul8ulx16_vis"
7924 [(set (match_operand:V4HI 0 "register_operand" "=e")
7925 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7926 (match_operand:V4HI 2 "register_operand" "e")]
7929 "fmul8ulx16\t%1, %2, %0"
7930 [(set_attr "type" "fpmul")
7931 (set_attr "fptype" "double")])
7933 ;; Only one of the following two insns can be a multiply.
7934 (define_insn "fmuld8sux16_vis"
7935 [(set (match_operand:V2SI 0 "register_operand" "=e")
7936 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7937 (match_operand:V2HI 2 "register_operand" "f")))]
7939 "fmuld8sux16\t%1, %2, %0"
7940 [(set_attr "type" "fpmul")
7941 (set_attr "fptype" "double")])
7943 (define_insn "fmuld8ulx16_vis"
7944 [(set (match_operand:V2SI 0 "register_operand" "=e")
7945 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7946 (match_operand:V2HI 2 "register_operand" "f")]
7949 "fmuld8ulx16\t%1, %2, %0"
7950 [(set_attr "type" "fpmul")
7951 (set_attr "fptype" "double")])
7953 (define_expand "wrgsr_vis"
7954 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
7957 if (! TARGET_ARCH64)
7959 emit_insn (gen_wrgsr_v8plus (operands[0]));
7964 (define_insn "*wrgsr_sp64"
7965 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
7966 "TARGET_VIS && TARGET_ARCH64"
7967 "wr\t%%g0, %0, %%gsr"
7968 [(set_attr "type" "gsr")])
7970 (define_insn "wrgsr_v8plus"
7971 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
7972 (clobber (match_scratch:SI 1 "=X,&h"))]
7973 "TARGET_VIS && ! TARGET_ARCH64"
7975 if (GET_CODE (operands[0]) == CONST_INT
7976 || sparc_check_64 (operands[0], insn))
7977 return "wr\t%%g0, %0, %%gsr";
7979 output_asm_insn("srl\t%L0, 0, %L0", operands);
7980 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
7982 [(set_attr "type" "multi")])
7984 (define_expand "rdgsr_vis"
7985 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
7988 if (! TARGET_ARCH64)
7990 emit_insn (gen_rdgsr_v8plus (operands[0]));
7995 (define_insn "*rdgsr_sp64"
7996 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
7997 "TARGET_VIS && TARGET_ARCH64"
7999 [(set_attr "type" "gsr")])
8001 (define_insn "rdgsr_v8plus"
8002 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8003 (clobber (match_scratch:SI 1 "=&h"))]
8004 "TARGET_VIS && ! TARGET_ARCH64"
8006 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8008 [(set_attr "type" "multi")])
8010 ;; Using faligndata only makes sense after an alignaddr since the choice of
8011 ;; bytes to take out of each operand is dependent on the results of the last
8013 (define_insn "faligndata<V64I:mode>_vis"
8014 [(set (match_operand:V64I 0 "register_operand" "=e")
8015 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8016 (match_operand:V64I 2 "register_operand" "e")]
8018 (use (reg:SI GSR_REG))]
8020 "faligndata\t%1, %2, %0"
8021 [(set_attr "type" "fga")
8022 (set_attr "fptype" "double")])
8024 (define_insn "alignaddrsi_vis"
8025 [(set (match_operand:SI 0 "register_operand" "=r")
8026 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8027 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8028 (set (reg:SI GSR_REG)
8029 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8030 (and:SI (plus:SI (match_dup 1) (match_dup 2))
8033 "alignaddr\t%r1, %r2, %0")
8035 (define_insn "alignaddrdi_vis"
8036 [(set (match_operand:DI 0 "register_operand" "=r")
8037 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8038 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8039 (set (reg:SI GSR_REG)
8040 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8041 (and:SI (truncate:SI (plus:DI (match_dup 1) (match_dup 2)))
8044 "alignaddr\t%r1, %r2, %0")
8046 (define_insn "alignaddrlsi_vis"
8047 [(set (match_operand:SI 0 "register_operand" "=r")
8048 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8049 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8050 (set (reg:SI GSR_REG)
8051 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8052 (xor:SI (and:SI (plus:SI (match_dup 1) (match_dup 2))
8056 "alignaddrl\t%r1, %r2, %0")
8058 (define_insn "alignaddrldi_vis"
8059 [(set (match_operand:DI 0 "register_operand" "=r")
8060 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8061 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8062 (set (reg:SI GSR_REG)
8063 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8064 (xor:SI (and:SI (truncate:SI (plus:DI (match_dup 1)
8069 "alignaddrl\t%r1, %r2, %0")
8071 (define_insn "pdist_vis"
8072 [(set (match_operand:DI 0 "register_operand" "=e")
8073 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8074 (match_operand:V8QI 2 "register_operand" "e")
8075 (match_operand:DI 3 "register_operand" "0")]
8079 [(set_attr "type" "fga")
8080 (set_attr "fptype" "double")])
8082 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8083 ;; with the same operands.
8084 (define_insn "edge8<P:mode>_vis"
8085 [(set (reg:CC_NOOV CC_REG)
8086 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8087 (match_operand:P 2 "register_operand" "rJ"))
8089 (set (match_operand:P 0 "register_operand" "=r")
8090 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8092 "edge8\t%r1, %r2, %0"
8093 [(set_attr "type" "edge")])
8095 (define_insn "edge8l<P:mode>_vis"
8096 [(set (reg:CC_NOOV CC_REG)
8097 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8098 (match_operand:P 2 "register_operand" "rJ"))
8100 (set (match_operand:P 0 "register_operand" "=r")
8101 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8103 "edge8l\t%r1, %r2, %0"
8104 [(set_attr "type" "edge")])
8106 (define_insn "edge16<P:mode>_vis"
8107 [(set (reg:CC_NOOV CC_REG)
8108 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8109 (match_operand:P 2 "register_operand" "rJ"))
8111 (set (match_operand:P 0 "register_operand" "=r")
8112 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8114 "edge16\t%r1, %r2, %0"
8115 [(set_attr "type" "edge")])
8117 (define_insn "edge16l<P:mode>_vis"
8118 [(set (reg:CC_NOOV CC_REG)
8119 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8120 (match_operand:P 2 "register_operand" "rJ"))
8122 (set (match_operand:P 0 "register_operand" "=r")
8123 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8125 "edge16l\t%r1, %r2, %0"
8126 [(set_attr "type" "edge")])
8128 (define_insn "edge32<P:mode>_vis"
8129 [(set (reg:CC_NOOV CC_REG)
8130 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8131 (match_operand:P 2 "register_operand" "rJ"))
8133 (set (match_operand:P 0 "register_operand" "=r")
8134 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8136 "edge32\t%r1, %r2, %0"
8137 [(set_attr "type" "edge")])
8139 (define_insn "edge32l<P:mode>_vis"
8140 [(set (reg:CC_NOOV CC_REG)
8141 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8142 (match_operand:P 2 "register_operand" "rJ"))
8144 (set (match_operand:P 0 "register_operand" "=r")
8145 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8147 "edge32l\t%r1, %r2, %0"
8148 [(set_attr "type" "edge")])
8150 (define_code_iterator gcond [le ne gt eq])
8151 (define_code_attr gcond_name [(le "le") (ne "ne") (gt "gt") (eq "eq")])
8152 (define_mode_iterator GCM [V4HI V2SI])
8153 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8155 (define_insn "fcmp<gcond_name><gcm_name><P:mode>_vis"
8156 [(set (match_operand:P 0 "register_operand" "=r")
8157 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8158 (match_operand:GCM 2 "register_operand" "e"))]
8161 "fcmp<gcond_name><gcm_name>\t%1, %2, %0"
8162 [(set_attr "type" "fpmul")
8163 (set_attr "fptype" "double")])
8165 (define_insn "array8<P:mode>_vis"
8166 [(set (match_operand:P 0 "register_operand" "=r")
8167 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8168 (match_operand:P 2 "register_operand" "rJ")]
8171 "array8\t%r1, %r2, %0"
8172 [(set_attr "type" "array")])
8174 (define_insn "array16<P:mode>_vis"
8175 [(set (match_operand:P 0 "register_operand" "=r")
8176 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8177 (match_operand:P 2 "register_operand" "rJ")]
8180 "array16\t%r1, %r2, %0"
8181 [(set_attr "type" "array")])
8183 (define_insn "array32<P:mode>_vis"
8184 [(set (match_operand:P 0 "register_operand" "=r")
8185 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8186 (match_operand:P 2 "register_operand" "rJ")]
8189 "array32\t%r1, %r2, %0"
8190 [(set_attr "type" "array")])