comparison gcc/config/sparc/sparc.md @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children b7f97abdc517
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
73 (UNSPECV_SAVEW 6) 73 (UNSPECV_SAVEW 6)
74 (UNSPECV_CAS 8) 74 (UNSPECV_CAS 8)
75 (UNSPECV_SWAP 9) 75 (UNSPECV_SWAP 9)
76 (UNSPECV_LDSTUB 10) 76 (UNSPECV_LDSTUB 10)
77 ]) 77 ])
78
79
80 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
81 (define_mode_iterator I [QI HI SI DI])
82 (define_mode_iterator F [SF DF TF])
83
84 ;; We don't define V1SI because SI should work just fine.
85 (define_mode_iterator V32 [SF V2HI V4QI])
86 (define_mode_iterator V32I [SI V2HI V4QI])
87
88 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
89 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
78 90
79 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this 91 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
80 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name 92 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
81 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding 93 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
82 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of 94 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
128 multi,savew,flushw,iflush,trap" 140 multi,savew,flushw,iflush,trap"
129 (const_string "ialu")) 141 (const_string "ialu"))
130 142
131 ;; True if branch/call has empty delay slot and will emit a nop in it 143 ;; True if branch/call has empty delay slot and will emit a nop in it
132 (define_attr "empty_delay_slot" "false,true" 144 (define_attr "empty_delay_slot" "false,true"
133 (symbol_ref "empty_delay_slot (insn)")) 145 (symbol_ref "(empty_delay_slot (insn)
146 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
134 147
135 (define_attr "branch_type" "none,icc,fcc,reg" 148 (define_attr "branch_type" "none,icc,fcc,reg"
136 (const_string "none")) 149 (const_string "none"))
137 150
138 (define_attr "pic" "false,true" 151 (define_attr "pic" "false,true"
139 (symbol_ref "flag_pic != 0")) 152 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
140 153
141 (define_attr "calls_alloca" "false,true" 154 (define_attr "calls_alloca" "false,true"
142 (symbol_ref "cfun->calls_alloca != 0")) 155 (symbol_ref "(cfun->calls_alloca != 0
156 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
143 157
144 (define_attr "calls_eh_return" "false,true" 158 (define_attr "calls_eh_return" "false,true"
145 (symbol_ref "crtl->calls_eh_return !=0 ")) 159 (symbol_ref "(crtl->calls_eh_return != 0
160 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
146 161
147 (define_attr "leaf_function" "false,true" 162 (define_attr "leaf_function" "false,true"
148 (symbol_ref "current_function_uses_only_leaf_regs != 0")) 163 (symbol_ref "(current_function_uses_only_leaf_regs != 0
164 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
149 165
150 (define_attr "delayed_branch" "false,true" 166 (define_attr "delayed_branch" "false,true"
151 (symbol_ref "flag_delayed_branch != 0")) 167 (symbol_ref "(flag_delayed_branch != 0
168 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
152 169
153 ;; Length (in # of insns). 170 ;; Length (in # of insns).
154 ;; Beware that setting a length greater or equal to 3 for conditional branches 171 ;; Beware that setting a length greater or equal to 3 for conditional branches
155 ;; has a side-effect (see output_cbranch and output_v9branch). 172 ;; has a side-effect (see output_cbranch and output_v9branch).
156 (define_attr "length" "" 173 (define_attr "length" ""
240 [(set_attr "length" "2") 257 [(set_attr "length" "2")
241 (set_attr "type" "multi")]) 258 (set_attr "type" "multi")])
242 259
243 ;; Attributes for instruction and branch scheduling 260 ;; Attributes for instruction and branch scheduling
244 (define_attr "tls_call_delay" "false,true" 261 (define_attr "tls_call_delay" "false,true"
245 (symbol_ref "tls_call_delay (insn)")) 262 (symbol_ref "(tls_call_delay (insn)
263 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
246 264
247 (define_attr "in_call_delay" "false,true" 265 (define_attr "in_call_delay" "false,true"
248 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi") 266 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
249 (const_string "false") 267 (const_string "false")
250 (eq_attr "type" "load,fpload,store,fpstore") 268 (eq_attr "type" "load,fpload,store,fpstore")
255 (eq_attr "tls_call_delay" "true")) 273 (eq_attr "tls_call_delay" "true"))
256 (const_string "true") 274 (const_string "true")
257 (const_string "false")))) 275 (const_string "false"))))
258 276
259 (define_attr "eligible_for_sibcall_delay" "false,true" 277 (define_attr "eligible_for_sibcall_delay" "false,true"
260 (symbol_ref "eligible_for_sibcall_delay (insn)")) 278 (symbol_ref "(eligible_for_sibcall_delay (insn)
279 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
280 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
261 281
262 (define_attr "eligible_for_return_delay" "false,true" 282 (define_attr "eligible_for_return_delay" "false,true"
263 (symbol_ref "eligible_for_return_delay (insn)")) 283 (symbol_ref "(eligible_for_return_delay (insn)
284 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
285 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
264 286
265 ;; ??? !v9: Should implement the notion of predelay slots for floating-point 287 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
266 ;; branches. This would allow us to remove the nop always inserted before 288 ;; branches. This would allow us to remove the nop always inserted before
267 ;; a floating point branch. 289 ;; a floating point branch.
268 290
328 (include "constraints.md") 350 (include "constraints.md")
329 351
330 352
331 ;; Compare instructions. 353 ;; Compare instructions.
332 354
333 ;; We generate RTL for comparisons and branches by having the cmpxx 355 ;; These are just the DEFINE_INSNs to match the patterns and the
334 ;; patterns store away the operands. Then, the scc and bcc patterns 356 ;; DEFINE_SPLITs for some of the scc insns that actually require
335 ;; emit RTL for both the compare and the branch. 357 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
336 ;; 358
337 ;; We do this because we want to generate different code for an sne and 359 ;; The compare DEFINE_INSNs.
338 ;; seq insn. In those cases, if the second operand of the compare is not
339 ;; const0_rtx, we want to compute the xor of the two operands and test
340 ;; it against zero.
341 ;;
342 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
343 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
344 ;; insns that actually require more than one machine instruction.
345
346 (define_expand "cmpsi"
347 [(set (reg:CC 100)
348 (compare:CC (match_operand:SI 0 "compare_operand" "")
349 (match_operand:SI 1 "arith_operand" "")))]
350 ""
351 {
352 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
353 operands[0] = force_reg (SImode, operands[0]);
354
355 sparc_compare_op0 = operands[0];
356 sparc_compare_op1 = operands[1];
357 DONE;
358 })
359
360 (define_expand "cmpdi"
361 [(set (reg:CCX 100)
362 (compare:CCX (match_operand:DI 0 "compare_operand" "")
363 (match_operand:DI 1 "arith_operand" "")))]
364 "TARGET_ARCH64"
365 {
366 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
367 operands[0] = force_reg (DImode, operands[0]);
368
369 sparc_compare_op0 = operands[0];
370 sparc_compare_op1 = operands[1];
371 DONE;
372 })
373
374 (define_expand "cmpsf"
375 ;; The 96 here isn't ever used by anyone.
376 [(set (reg:CCFP 96)
377 (compare:CCFP (match_operand:SF 0 "register_operand" "")
378 (match_operand:SF 1 "register_operand" "")))]
379 "TARGET_FPU"
380 {
381 sparc_compare_op0 = operands[0];
382 sparc_compare_op1 = operands[1];
383 DONE;
384 })
385
386 (define_expand "cmpdf"
387 ;; The 96 here isn't ever used by anyone.
388 [(set (reg:CCFP 96)
389 (compare:CCFP (match_operand:DF 0 "register_operand" "")
390 (match_operand:DF 1 "register_operand" "")))]
391 "TARGET_FPU"
392 {
393 sparc_compare_op0 = operands[0];
394 sparc_compare_op1 = operands[1];
395 DONE;
396 })
397
398 (define_expand "cmptf"
399 ;; The 96 here isn't ever used by anyone.
400 [(set (reg:CCFP 96)
401 (compare:CCFP (match_operand:TF 0 "register_operand" "")
402 (match_operand:TF 1 "register_operand" "")))]
403 "TARGET_FPU"
404 {
405 sparc_compare_op0 = operands[0];
406 sparc_compare_op1 = operands[1];
407 DONE;
408 })
409
410 ;; Now the compare DEFINE_INSNs.
411 360
412 (define_insn "*cmpsi_insn" 361 (define_insn "*cmpsi_insn"
413 [(set (reg:CC 100) 362 [(set (reg:CC 100)
414 (compare:CC (match_operand:SI 0 "register_operand" "r") 363 (compare:CC (match_operand:SI 0 "register_operand" "r")
415 (match_operand:SI 1 "arith_operand" "rI")))] 364 (match_operand:SI 1 "arith_operand" "rI")))]
497 return "fcmpq\t%0, %1, %2"; 446 return "fcmpq\t%0, %1, %2";
498 return "fcmpq\t%1, %2"; 447 return "fcmpq\t%1, %2";
499 } 448 }
500 [(set_attr "type" "fpcmp")]) 449 [(set_attr "type" "fpcmp")])
501 450
502 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this 451 ;; Next come the scc insns.
503 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use 452
504 ;; the same code as v8 (the addx/subx method has more applications). The 453 (define_expand "cstoresi4"
505 ;; exception to this is "reg != 0" which can be done in one instruction on v9 454 [(use (match_operator 1 "comparison_operator"
506 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do 455 [(match_operand:SI 2 "compare_operand" "")
507 ;; branches. 456 (match_operand:SI 3 "arith_operand" "")]))
457 (clobber (match_operand:SI 0 "register_operand"))]
458 ""
459 {
460 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
461 operands[2] = force_reg (SImode, operands[2]);
462 if (emit_scc_insn (operands)) DONE; else FAIL;
463 })
464
465 (define_expand "cstoredi4"
466 [(use (match_operator 1 "comparison_operator"
467 [(match_operand:DI 2 "compare_operand" "")
468 (match_operand:DI 3 "arith_operand" "")]))
469 (clobber (match_operand:SI 0 "register_operand"))]
470 "TARGET_ARCH64"
471 {
472 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
473 operands[2] = force_reg (DImode, operands[2]);
474 if (emit_scc_insn (operands)) DONE; else FAIL;
475 })
476
477 (define_expand "cstore<F:mode>4"
478 [(use (match_operator 1 "comparison_operator"
479 [(match_operand:F 2 "register_operand" "")
480 (match_operand:F 3 "register_operand" "")]))
481 (clobber (match_operand:SI 0 "register_operand"))]
482 "TARGET_FPU"
483 { if (emit_scc_insn (operands)) DONE; else FAIL; })
484
485
508 486
509 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they 487 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
510 ;; generate addcc/subcc instructions. 488 ;; generate addcc/subcc instructions.
511 489
512 (define_expand "seqsi_special" 490 (define_expand "seqsi_special"
521 499
522 (define_expand "seqdi_special" 500 (define_expand "seqdi_special"
523 [(set (match_dup 3) 501 [(set (match_dup 3)
524 (xor:DI (match_operand:DI 1 "register_operand" "") 502 (xor:DI (match_operand:DI 1 "register_operand" "")
525 (match_operand:DI 2 "register_operand" ""))) 503 (match_operand:DI 2 "register_operand" "")))
526 (set (match_operand:DI 0 "register_operand" "") 504 (set (match_operand:SI 0 "register_operand" "")
527 (eq:DI (match_dup 3) (const_int 0)))] 505 (eq:SI (match_dup 3) (const_int 0)))]
528 "TARGET_ARCH64" 506 "TARGET_ARCH64"
529 { operands[3] = gen_reg_rtx (DImode); }) 507 { operands[3] = gen_reg_rtx (DImode); })
530 508
531 (define_expand "snesi_special" 509 (define_expand "snesi_special"
532 [(set (match_dup 3) 510 [(set (match_dup 3)
540 518
541 (define_expand "snedi_special" 519 (define_expand "snedi_special"
542 [(set (match_dup 3) 520 [(set (match_dup 3)
543 (xor:DI (match_operand:DI 1 "register_operand" "") 521 (xor:DI (match_operand:DI 1 "register_operand" "")
544 (match_operand:DI 2 "register_operand" ""))) 522 (match_operand:DI 2 "register_operand" "")))
545 (set (match_operand:DI 0 "register_operand" "")
546 (ne:DI (match_dup 3) (const_int 0)))]
547 "TARGET_ARCH64"
548 { operands[3] = gen_reg_rtx (DImode); })
549
550 (define_expand "seqdi_special_trunc"
551 [(set (match_dup 3)
552 (xor:DI (match_operand:DI 1 "register_operand" "")
553 (match_operand:DI 2 "register_operand" "")))
554 (set (match_operand:SI 0 "register_operand" "")
555 (eq:SI (match_dup 3) (const_int 0)))]
556 "TARGET_ARCH64"
557 { operands[3] = gen_reg_rtx (DImode); })
558
559 (define_expand "snedi_special_trunc"
560 [(set (match_dup 3)
561 (xor:DI (match_operand:DI 1 "register_operand" "")
562 (match_operand:DI 2 "register_operand" "")))
563 (set (match_operand:SI 0 "register_operand" "") 523 (set (match_operand:SI 0 "register_operand" "")
564 (ne:SI (match_dup 3) (const_int 0)))] 524 (ne:SI (match_dup 3) (const_int 0)))]
565 "TARGET_ARCH64" 525 "TARGET_ARCH64"
566 { operands[3] = gen_reg_rtx (DImode); }) 526 { operands[3] = gen_reg_rtx (DImode); })
567 527
568 (define_expand "seqsi_special_extend"
569 [(set (match_dup 3)
570 (xor:SI (match_operand:SI 1 "register_operand" "")
571 (match_operand:SI 2 "register_operand" "")))
572 (parallel [(set (match_operand:DI 0 "register_operand" "")
573 (eq:DI (match_dup 3) (const_int 0)))
574 (clobber (reg:CC 100))])]
575 "TARGET_ARCH64"
576 { operands[3] = gen_reg_rtx (SImode); })
577
578 (define_expand "snesi_special_extend"
579 [(set (match_dup 3)
580 (xor:SI (match_operand:SI 1 "register_operand" "")
581 (match_operand:SI 2 "register_operand" "")))
582 (parallel [(set (match_operand:DI 0 "register_operand" "")
583 (ne:DI (match_dup 3) (const_int 0)))
584 (clobber (reg:CC 100))])]
585 "TARGET_ARCH64"
586 { operands[3] = gen_reg_rtx (SImode); })
587
588 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
589 ;; However, the code handles both SImode and DImode.
590 (define_expand "seq"
591 [(set (match_operand:SI 0 "int_register_operand" "")
592 (eq:SI (match_dup 1) (const_int 0)))]
593 ""
594 {
595 if (GET_MODE (sparc_compare_op0) == SImode)
596 {
597 rtx pat;
598
599 if (GET_MODE (operands[0]) == SImode)
600 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
601 sparc_compare_op1);
602 else if (! TARGET_ARCH64)
603 FAIL;
604 else
605 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
606 sparc_compare_op1);
607 emit_insn (pat);
608 DONE;
609 }
610 else if (GET_MODE (sparc_compare_op0) == DImode)
611 {
612 rtx pat;
613
614 if (! TARGET_ARCH64)
615 FAIL;
616 else if (GET_MODE (operands[0]) == SImode)
617 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
618 sparc_compare_op1);
619 else
620 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
621 sparc_compare_op1);
622 emit_insn (pat);
623 DONE;
624 }
625 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
626 {
627 enum rtx_code code
628 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
629 gcc_assert (code == NE);
630 emit_insn (gen_sne (operands[0]));
631 DONE;
632 }
633 else if (TARGET_V9)
634 {
635 if (gen_v9_scc (EQ, operands))
636 DONE;
637 /* fall through */
638 }
639 FAIL;
640 })
641
642 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
643 ;; However, the code handles both SImode and DImode.
644 (define_expand "sne"
645 [(set (match_operand:SI 0 "int_register_operand" "")
646 (ne:SI (match_dup 1) (const_int 0)))]
647 ""
648 {
649 if (GET_MODE (sparc_compare_op0) == SImode)
650 {
651 rtx pat;
652
653 if (GET_MODE (operands[0]) == SImode)
654 pat = gen_snesi_special (operands[0], sparc_compare_op0,
655 sparc_compare_op1);
656 else if (! TARGET_ARCH64)
657 FAIL;
658 else
659 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
660 sparc_compare_op1);
661 emit_insn (pat);
662 DONE;
663 }
664 else if (GET_MODE (sparc_compare_op0) == DImode)
665 {
666 rtx pat;
667
668 if (! TARGET_ARCH64)
669 FAIL;
670 else if (GET_MODE (operands[0]) == SImode)
671 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
672 sparc_compare_op1);
673 else
674 pat = gen_snedi_special (operands[0], sparc_compare_op0,
675 sparc_compare_op1);
676 emit_insn (pat);
677 DONE;
678 }
679 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
680 {
681 enum rtx_code code
682 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
683 gcc_assert (code == NE);
684 emit_insn (gen_sne (operands[0]));
685 DONE;
686 }
687 else if (TARGET_V9)
688 {
689 if (gen_v9_scc (NE, operands))
690 DONE;
691 /* fall through */
692 }
693 FAIL;
694 })
695
696 (define_expand "sgt"
697 [(set (match_operand:SI 0 "int_register_operand" "")
698 (gt:SI (match_dup 1) (const_int 0)))]
699 ""
700 {
701 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
702 {
703 enum rtx_code code
704 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
705 gcc_assert (code == NE);
706 emit_insn (gen_sne (operands[0]));
707 DONE;
708 }
709 else if (TARGET_V9)
710 {
711 if (gen_v9_scc (GT, operands))
712 DONE;
713 /* fall through */
714 }
715 FAIL;
716 })
717
718 (define_expand "slt"
719 [(set (match_operand:SI 0 "int_register_operand" "")
720 (lt:SI (match_dup 1) (const_int 0)))]
721 ""
722 {
723 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
724 {
725 enum rtx_code code
726 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
727 gcc_assert (code == NE);
728 emit_insn (gen_sne (operands[0]));
729 DONE;
730 }
731 else if (TARGET_V9)
732 {
733 if (gen_v9_scc (LT, operands))
734 DONE;
735 /* fall through */
736 }
737 FAIL;
738 })
739
740 (define_expand "sge"
741 [(set (match_operand:SI 0 "int_register_operand" "")
742 (ge:SI (match_dup 1) (const_int 0)))]
743 ""
744 {
745 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
746 {
747 enum rtx_code code
748 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
749 gcc_assert (code == NE);
750 emit_insn (gen_sne (operands[0]));
751 DONE;
752 }
753 else if (TARGET_V9)
754 {
755 if (gen_v9_scc (GE, operands))
756 DONE;
757 /* fall through */
758 }
759 FAIL;
760 })
761
762 (define_expand "sle"
763 [(set (match_operand:SI 0 "int_register_operand" "")
764 (le:SI (match_dup 1) (const_int 0)))]
765 ""
766 {
767 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
768 {
769 enum rtx_code code
770 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
771 gcc_assert (code == NE);
772 emit_insn (gen_sne (operands[0]));
773 DONE;
774 }
775 else if (TARGET_V9)
776 {
777 if (gen_v9_scc (LE, operands))
778 DONE;
779 /* fall through */
780 }
781 FAIL;
782 })
783
784 (define_expand "sgtu"
785 [(set (match_operand:SI 0 "int_register_operand" "")
786 (gtu:SI (match_dup 1) (const_int 0)))]
787 ""
788 {
789 if (! TARGET_V9)
790 {
791 rtx tem, pat;
792
793 /* We can do ltu easily, so if both operands are registers, swap them and
794 do a LTU. */
795 if ((GET_CODE (sparc_compare_op0) == REG
796 || GET_CODE (sparc_compare_op0) == SUBREG)
797 && (GET_CODE (sparc_compare_op1) == REG
798 || GET_CODE (sparc_compare_op1) == SUBREG))
799 {
800 tem = sparc_compare_op0;
801 sparc_compare_op0 = sparc_compare_op1;
802 sparc_compare_op1 = tem;
803 pat = gen_sltu (operands[0]);
804 if (pat == NULL_RTX)
805 FAIL;
806 emit_insn (pat);
807 DONE;
808 }
809 }
810 else
811 {
812 if (gen_v9_scc (GTU, operands))
813 DONE;
814 }
815 FAIL;
816 })
817
818 (define_expand "sltu"
819 [(set (match_operand:SI 0 "int_register_operand" "")
820 (ltu:SI (match_dup 1) (const_int 0)))]
821 ""
822 {
823 if (TARGET_V9)
824 {
825 if (gen_v9_scc (LTU, operands))
826 DONE;
827 }
828 operands[1] = gen_compare_reg (LTU);
829 })
830
831 (define_expand "sgeu"
832 [(set (match_operand:SI 0 "int_register_operand" "")
833 (geu:SI (match_dup 1) (const_int 0)))]
834 ""
835 {
836 if (TARGET_V9)
837 {
838 if (gen_v9_scc (GEU, operands))
839 DONE;
840 }
841 operands[1] = gen_compare_reg (GEU);
842 })
843
844 (define_expand "sleu"
845 [(set (match_operand:SI 0 "int_register_operand" "")
846 (leu:SI (match_dup 1) (const_int 0)))]
847 ""
848 {
849 if (! TARGET_V9)
850 {
851 rtx tem, pat;
852
853 /* We can do geu easily, so if both operands are registers, swap them and
854 do a GEU. */
855 if ((GET_CODE (sparc_compare_op0) == REG
856 || GET_CODE (sparc_compare_op0) == SUBREG)
857 && (GET_CODE (sparc_compare_op1) == REG
858 || GET_CODE (sparc_compare_op1) == SUBREG))
859 {
860 tem = sparc_compare_op0;
861 sparc_compare_op0 = sparc_compare_op1;
862 sparc_compare_op1 = tem;
863 pat = gen_sgeu (operands[0]);
864 if (pat == NULL_RTX)
865 FAIL;
866 emit_insn (pat);
867 DONE;
868 }
869 }
870 else
871 {
872 if (gen_v9_scc (LEU, operands))
873 DONE;
874 }
875 FAIL;
876 })
877 528
878 ;; Now the DEFINE_INSNs for the scc cases. 529 ;; Now the DEFINE_INSNs for the scc cases.
879 530
880 ;; The SEQ and SNE patterns are special because they can be done 531 ;; The SEQ and SNE patterns are special because they can be done
881 ;; without any branching and do not involve a COMPARE. We want 532 ;; without any branching and do not involve a COMPARE. We want
1263 "") 914 "")
1264 915
1265 916
1266 ;; These control RTL generation for conditional jump insns 917 ;; These control RTL generation for conditional jump insns
1267 918
1268 ;; The quad-word fp compare library routines all return nonzero to indicate 919 (define_expand "cbranchcc4"
1269 ;; true, which is different from the equivalent libgcc routines, so we must
1270 ;; handle them specially here.
1271
1272 (define_expand "beq"
1273 [(set (pc) 920 [(set (pc)
1274 (if_then_else (eq (match_dup 1) (const_int 0)) 921 (if_then_else (match_operator 0 "comparison_operator"
1275 (label_ref (match_operand 0 "" "")) 922 [(match_operand 1 "compare_operand" "")
923 (match_operand 2 "const_zero_operand" "")])
924 (label_ref (match_operand 3 "" ""))
1276 (pc)))] 925 (pc)))]
1277 "" 926 ""
1278 { 927 "")
1279 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx 928
1280 && GET_CODE (sparc_compare_op0) == REG 929 (define_expand "cbranchsi4"
1281 && GET_MODE (sparc_compare_op0) == DImode) 930 [(use (match_operator 0 "comparison_operator"
1282 { 931 [(match_operand:SI 1 "compare_operand" "")
1283 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]); 932 (match_operand:SI 2 "arith_operand" "")]))
1284 DONE; 933 (use (match_operand 3 ""))]
1285 } 934 ""
1286 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) 935 {
1287 { 936 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1288 enum rtx_code code 937 operands[1] = force_reg (SImode, operands[1]);
1289 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ); 938 emit_conditional_branch_insn (operands);
1290 gcc_assert (code == NE); 939 DONE;
1291 emit_jump_insn (gen_bne (operands[0]));
1292 DONE;
1293 }
1294 operands[1] = gen_compare_reg (EQ);
1295 }) 940 })
1296 941
1297 (define_expand "bne" 942 (define_expand "cbranchdi4"
1298 [(set (pc) 943 [(use (match_operator 0 "comparison_operator"
1299 (if_then_else (ne (match_dup 1) (const_int 0)) 944 [(match_operand:DI 1 "compare_operand" "")
1300 (label_ref (match_operand 0 "" "")) 945 (match_operand:DI 2 "arith_operand" "")]))
1301 (pc)))] 946 (use (match_operand 3 ""))]
1302 "" 947 "TARGET_ARCH64"
1303 { 948 {
1304 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx 949 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1305 && GET_CODE (sparc_compare_op0) == REG 950 operands[1] = force_reg (DImode, operands[1]);
1306 && GET_MODE (sparc_compare_op0) == DImode) 951 emit_conditional_branch_insn (operands);
1307 { 952 DONE;
1308 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1309 DONE;
1310 }
1311 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1312 {
1313 enum rtx_code code
1314 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1315 gcc_assert (code == NE);
1316 emit_jump_insn (gen_bne (operands[0]));
1317 DONE;
1318 }
1319 operands[1] = gen_compare_reg (NE);
1320 }) 953 })
1321 954
1322 (define_expand "bgt" 955 (define_expand "cbranch<F:mode>4"
1323 [(set (pc) 956 [(use (match_operator 0 "comparison_operator"
1324 (if_then_else (gt (match_dup 1) (const_int 0)) 957 [(match_operand:F 1 "register_operand" "")
1325 (label_ref (match_operand 0 "" "")) 958 (match_operand:F 2 "register_operand" "")]))
1326 (pc)))] 959 (use (match_operand 3 ""))]
1327 "" 960 "TARGET_FPU"
1328 { 961 { emit_conditional_branch_insn (operands); DONE; })
1329 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx 962
1330 && GET_CODE (sparc_compare_op0) == REG 963
1331 && GET_MODE (sparc_compare_op0) == DImode)
1332 {
1333 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1334 DONE;
1335 }
1336 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1337 {
1338 enum rtx_code code
1339 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1340 gcc_assert (code == NE);
1341 emit_jump_insn (gen_bne (operands[0]));
1342 DONE;
1343 }
1344 operands[1] = gen_compare_reg (GT);
1345 })
1346
1347 (define_expand "bgtu"
1348 [(set (pc)
1349 (if_then_else (gtu (match_dup 1) (const_int 0))
1350 (label_ref (match_operand 0 "" ""))
1351 (pc)))]
1352 ""
1353 {
1354 operands[1] = gen_compare_reg (GTU);
1355 })
1356
1357 (define_expand "blt"
1358 [(set (pc)
1359 (if_then_else (lt (match_dup 1) (const_int 0))
1360 (label_ref (match_operand 0 "" ""))
1361 (pc)))]
1362 ""
1363 {
1364 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1365 && GET_CODE (sparc_compare_op0) == REG
1366 && GET_MODE (sparc_compare_op0) == DImode)
1367 {
1368 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1369 DONE;
1370 }
1371 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1372 {
1373 enum rtx_code code
1374 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1375 gcc_assert (code == NE);
1376 emit_jump_insn (gen_bne (operands[0]));
1377 DONE;
1378 }
1379 operands[1] = gen_compare_reg (LT);
1380 })
1381
1382 (define_expand "bltu"
1383 [(set (pc)
1384 (if_then_else (ltu (match_dup 1) (const_int 0))
1385 (label_ref (match_operand 0 "" ""))
1386 (pc)))]
1387 ""
1388 {
1389 operands[1] = gen_compare_reg (LTU);
1390 })
1391
1392 (define_expand "bge"
1393 [(set (pc)
1394 (if_then_else (ge (match_dup 1) (const_int 0))
1395 (label_ref (match_operand 0 "" ""))
1396 (pc)))]
1397 ""
1398 {
1399 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1400 && GET_CODE (sparc_compare_op0) == REG
1401 && GET_MODE (sparc_compare_op0) == DImode)
1402 {
1403 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1404 DONE;
1405 }
1406 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1407 {
1408 enum rtx_code code
1409 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1410 gcc_assert (code == NE);
1411 emit_jump_insn (gen_bne (operands[0]));
1412 DONE;
1413 }
1414 operands[1] = gen_compare_reg (GE);
1415 })
1416
1417 (define_expand "bgeu"
1418 [(set (pc)
1419 (if_then_else (geu (match_dup 1) (const_int 0))
1420 (label_ref (match_operand 0 "" ""))
1421 (pc)))]
1422 ""
1423 {
1424 operands[1] = gen_compare_reg (GEU);
1425 })
1426
1427 (define_expand "ble"
1428 [(set (pc)
1429 (if_then_else (le (match_dup 1) (const_int 0))
1430 (label_ref (match_operand 0 "" ""))
1431 (pc)))]
1432 ""
1433 {
1434 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1435 && GET_CODE (sparc_compare_op0) == REG
1436 && GET_MODE (sparc_compare_op0) == DImode)
1437 {
1438 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1439 DONE;
1440 }
1441 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1442 {
1443 enum rtx_code code
1444 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1445 gcc_assert (code == NE);
1446 emit_jump_insn (gen_bne (operands[0]));
1447 DONE;
1448 }
1449 operands[1] = gen_compare_reg (LE);
1450 })
1451
1452 (define_expand "bleu"
1453 [(set (pc)
1454 (if_then_else (leu (match_dup 1) (const_int 0))
1455 (label_ref (match_operand 0 "" ""))
1456 (pc)))]
1457 ""
1458 {
1459 operands[1] = gen_compare_reg (LEU);
1460 })
1461
1462 (define_expand "bunordered"
1463 [(set (pc)
1464 (if_then_else (unordered (match_dup 1) (const_int 0))
1465 (label_ref (match_operand 0 "" ""))
1466 (pc)))]
1467 ""
1468 {
1469 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1470 {
1471 enum rtx_code code
1472 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNORDERED);
1473 gcc_assert (code == EQ);
1474 emit_jump_insn (gen_beq (operands[0]));
1475 DONE;
1476 }
1477 operands[1] = gen_compare_reg (UNORDERED);
1478 })
1479
1480 (define_expand "bordered"
1481 [(set (pc)
1482 (if_then_else (ordered (match_dup 1) (const_int 0))
1483 (label_ref (match_operand 0 "" ""))
1484 (pc)))]
1485 ""
1486 {
1487 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1488 {
1489 enum rtx_code code
1490 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1491 gcc_assert (code == NE);
1492 emit_jump_insn (gen_bne (operands[0]));
1493 DONE;
1494 }
1495 operands[1] = gen_compare_reg (ORDERED);
1496 })
1497
1498 (define_expand "bungt"
1499 [(set (pc)
1500 (if_then_else (ungt (match_dup 1) (const_int 0))
1501 (label_ref (match_operand 0 "" ""))
1502 (pc)))]
1503 ""
1504 {
1505 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1506 {
1507 enum rtx_code code
1508 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1509 gcc_assert (code == GT);
1510 emit_jump_insn (gen_bgt (operands[0]));
1511 DONE;
1512 }
1513 operands[1] = gen_compare_reg (UNGT);
1514 })
1515
1516 (define_expand "bunlt"
1517 [(set (pc)
1518 (if_then_else (unlt (match_dup 1) (const_int 0))
1519 (label_ref (match_operand 0 "" ""))
1520 (pc)))]
1521 ""
1522 {
1523 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1524 {
1525 enum rtx_code code
1526 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1527 gcc_assert (code == NE);
1528 emit_jump_insn (gen_bne (operands[0]));
1529 DONE;
1530 }
1531 operands[1] = gen_compare_reg (UNLT);
1532 })
1533
1534 (define_expand "buneq"
1535 [(set (pc)
1536 (if_then_else (uneq (match_dup 1) (const_int 0))
1537 (label_ref (match_operand 0 "" ""))
1538 (pc)))]
1539 ""
1540 {
1541 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1542 {
1543 enum rtx_code code
1544 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1545 gcc_assert (code == EQ);
1546 emit_jump_insn (gen_beq (operands[0]));
1547 DONE;
1548 }
1549 operands[1] = gen_compare_reg (UNEQ);
1550 })
1551
1552 (define_expand "bunge"
1553 [(set (pc)
1554 (if_then_else (unge (match_dup 1) (const_int 0))
1555 (label_ref (match_operand 0 "" ""))
1556 (pc)))]
1557 ""
1558 {
1559 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1560 {
1561 enum rtx_code code
1562 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1563 gcc_assert (code == NE);
1564 emit_jump_insn (gen_bne (operands[0]));
1565 DONE;
1566 }
1567 operands[1] = gen_compare_reg (UNGE);
1568 })
1569
1570 (define_expand "bunle"
1571 [(set (pc)
1572 (if_then_else (unle (match_dup 1) (const_int 0))
1573 (label_ref (match_operand 0 "" ""))
1574 (pc)))]
1575 ""
1576 {
1577 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1578 {
1579 enum rtx_code code
1580 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1581 gcc_assert (code == NE);
1582 emit_jump_insn (gen_bne (operands[0]));
1583 DONE;
1584 }
1585 operands[1] = gen_compare_reg (UNLE);
1586 })
1587
1588 (define_expand "bltgt"
1589 [(set (pc)
1590 (if_then_else (ltgt (match_dup 1) (const_int 0))
1591 (label_ref (match_operand 0 "" ""))
1592 (pc)))]
1593 ""
1594 {
1595 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1596 {
1597 enum rtx_code code
1598 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1599 gcc_assert (code == NE);
1600 emit_jump_insn (gen_bne (operands[0]));
1601 DONE;
1602 }
1603 operands[1] = gen_compare_reg (LTGT);
1604 })
1605
1606 ;; Now match both normal and inverted jump. 964 ;; Now match both normal and inverted jump.
1607 965
1608 ;; XXX fpcmp nop braindamage 966 ;; XXX fpcmp nop braindamage
1609 (define_insn "*normal_branch" 967 (define_insn "*normal_branch"
1610 [(set (pc) 968 [(set (pc)
1742 insn); 1100 insn);
1743 } 1101 }
1744 [(set_attr "type" "branch") 1102 [(set_attr "type" "branch")
1745 (set_attr "branch_type" "reg")]) 1103 (set_attr "branch_type" "reg")])
1746 1104
1747
1748 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1749 1105
1750 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic 1106 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1751 ;; value subject to a PC-relative relocation. Operand 2 is a helper function 1107 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1752 ;; that adds the PC value at the call point to operand 0. 1108 ;; that adds the PC value at the call point to operand 0.
1753 1109
2381 }) 1737 })
2382 1738
2383 1739
2384 ;; Floating point and vector move instructions 1740 ;; Floating point and vector move instructions
2385 1741
2386 ;; We don't define V1SI because SI should work just fine.
2387 (define_mode_iterator V32 [SF V2HI V4QI])
2388
2389 ;; Yes, you guessed it right, the former movsf expander. 1742 ;; Yes, you guessed it right, the former movsf expander.
2390 (define_expand "mov<V32:mode>" 1743 (define_expand "mov<V32:mode>"
2391 [(set (match_operand:V32 0 "nonimmediate_operand" "") 1744 [(set (match_operand:V32 0 "nonimmediate_operand" "")
2392 (match_operand:V32 1 "general_operand" ""))] 1745 (match_operand:V32 1 "general_operand" ""))]
2393 "<V32:MODE>mode == SFmode || TARGET_VIS" 1746 "<V32:MODE>mode == SFmode || TARGET_VIS"
2518 (match_operand:SF 1 "fp_const_high_losum_operand" ""))] 1871 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2519 "REG_P (operands[0]) && REGNO (operands[0]) < 32" 1872 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2520 [(set (match_dup 0) (high:SF (match_dup 1))) 1873 [(set (match_dup 0) (high:SF (match_dup 1)))
2521 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))]) 1874 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2522 1875
2523 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
2524
2525 ;; Yes, you again guessed it right, the former movdf expander. 1876 ;; Yes, you again guessed it right, the former movdf expander.
2526 (define_expand "mov<V64:mode>" 1877 (define_expand "mov<V64:mode>"
2527 [(set (match_operand:V64 0 "nonimmediate_operand" "") 1878 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2528 (match_operand:V64 1 "general_operand" ""))] 1879 (match_operand:V64 1 "general_operand" ""))]
2529 "<V64:MODE>mode == DFmode || TARGET_VIS" 1880 "<V64:MODE>mode == DFmode || TARGET_VIS"
3061 ;; it simple and only allow those constants supported by all flavors. 2412 ;; it simple and only allow those constants supported by all flavors.
3062 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand 2413 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3063 ;; 3 contains the constant if one is present, but we handle either for 2414 ;; 3 contains the constant if one is present, but we handle either for
3064 ;; generality (sparc.c puts a constant in operand 2). 2415 ;; generality (sparc.c puts a constant in operand 2).
3065 2416
3066 (define_mode_iterator I [QI HI SI DI])
3067
3068 (define_expand "mov<I:mode>cc" 2417 (define_expand "mov<I:mode>cc"
3069 [(set (match_operand:I 0 "register_operand" "") 2418 [(set (match_operand:I 0 "register_operand" "")
3070 (if_then_else:I (match_operand 1 "comparison_operator" "") 2419 (if_then_else:I (match_operand 1 "comparison_operator" "")
3071 (match_operand:I 2 "arith10_operand" "") 2420 (match_operand:I 2 "arith10_operand" "")
3072 (match_operand:I 3 "arith10_operand" "")))] 2421 (match_operand:I 3 "arith10_operand" "")))]
3073 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)" 2422 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
3074 { 2423 {
3075 enum rtx_code code = GET_CODE (operands[1]); 2424 enum rtx_code code = GET_CODE (operands[1]);
3076 2425 rtx cc_reg;
3077 if (GET_MODE (sparc_compare_op0) == DImode 2426
2427 if (GET_MODE (XEXP (operands[1], 0)) == DImode
3078 && ! TARGET_ARCH64) 2428 && ! TARGET_ARCH64)
3079 FAIL; 2429 FAIL;
3080 2430
3081 if (sparc_compare_op1 == const0_rtx 2431 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
3082 && GET_CODE (sparc_compare_op0) == REG 2432 operands[1]
3083 && GET_MODE (sparc_compare_op0) == DImode 2433 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2434 GET_CODE (operands[1]));
2435
2436 if (XEXP (operands[1], 1) == const0_rtx
2437 && GET_CODE (XEXP (operands[1], 0)) == REG
2438 && GET_MODE (XEXP (operands[1], 0)) == DImode
3084 && v9_regcmp_p (code)) 2439 && v9_regcmp_p (code))
3085 operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx); 2440 cc_reg = XEXP (operands[1], 0);
3086 else 2441 else
3087 operands[1] = gen_compare_operator (code); 2442 cc_reg = gen_compare_reg (operands[1]);
2443
2444 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3088 }) 2445 })
3089
3090 (define_mode_iterator F [SF DF TF])
3091 2446
3092 (define_expand "mov<F:mode>cc" 2447 (define_expand "mov<F:mode>cc"
3093 [(set (match_operand:F 0 "register_operand" "") 2448 [(set (match_operand:F 0 "register_operand" "")
3094 (if_then_else:F (match_operand 1 "comparison_operator" "") 2449 (if_then_else:F (match_operand 1 "comparison_operator" "")
3095 (match_operand:F 2 "register_operand" "") 2450 (match_operand:F 2 "register_operand" "")
3096 (match_operand:F 3 "register_operand" "")))] 2451 (match_operand:F 3 "register_operand" "")))]
3097 "TARGET_V9 && TARGET_FPU" 2452 "TARGET_V9 && TARGET_FPU"
3098 { 2453 {
3099 enum rtx_code code = GET_CODE (operands[1]); 2454 enum rtx_code code = GET_CODE (operands[1]);
3100 2455 rtx cc_reg;
3101 if (GET_MODE (sparc_compare_op0) == DImode 2456
2457 if (GET_MODE (XEXP (operands[1], 0)) == DImode
3102 && ! TARGET_ARCH64) 2458 && ! TARGET_ARCH64)
3103 FAIL; 2459 FAIL;
3104 2460
3105 if (sparc_compare_op1 == const0_rtx 2461 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
3106 && GET_CODE (sparc_compare_op0) == REG 2462 operands[1]
3107 && GET_MODE (sparc_compare_op0) == DImode 2463 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2464 GET_CODE (operands[1]));
2465
2466 if (XEXP (operands[1], 1) == const0_rtx
2467 && GET_CODE (XEXP (operands[1], 0)) == REG
2468 && GET_MODE (XEXP (operands[1], 0)) == DImode
3108 && v9_regcmp_p (code)) 2469 && v9_regcmp_p (code))
3109 operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx); 2470 cc_reg = XEXP (operands[1], 0);
3110 else 2471 else
3111 operands[1] = gen_compare_operator (code); 2472 cc_reg = gen_compare_reg (operands[1]);
2473
2474 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3112 }) 2475 })
3113 2476
3114 ;; Conditional move define_insns 2477 ;; Conditional move define_insns
3115 2478
3116 (define_insn "*mov<I:mode>_cc_v9" 2479 (define_insn "*mov<I:mode>_cc_v9"
5121 ;; Boolean instructions. 4484 ;; Boolean instructions.
5122 4485
5123 ;; We define DImode `and' so with DImode `not' we can get 4486 ;; We define DImode `and' so with DImode `not' we can get
5124 ;; DImode `andn'. Other combinations are possible. 4487 ;; DImode `andn'. Other combinations are possible.
5125 4488
5126 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
5127 (define_mode_iterator V32I [SI V2HI V4QI])
5128
5129 (define_expand "and<V64I:mode>3" 4489 (define_expand "and<V64I:mode>3"
5130 [(set (match_operand:V64I 0 "register_operand" "") 4490 [(set (match_operand:V64I 0 "register_operand" "")
5131 (and:V64I (match_operand:V64I 1 "arith_double_operand" "") 4491 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5132 (match_operand:V64I 2 "arith_double_operand" "")))] 4492 (match_operand:V64I 2 "arith_double_operand" "")))]
5133 "" 4493 ""
6915 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 6275 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6916 "" 6276 ""
6917 "" 6277 ""
6918 [(set_attr "length" "0")]) 6278 [(set_attr "length" "0")])
6919 6279
6280 (define_expand "probe_stack"
6281 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6282 ""
6283 {
6284 operands[0]
6285 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6286 })
6287
6920 ;; Prepare to return any type including a structure value. 6288 ;; Prepare to return any type including a structure value.
6921 6289
6922 (define_expand "untyped_return" 6290 (define_expand "untyped_return"
6923 [(match_operand:BLK 0 "memory_operand" "") 6291 [(match_operand:BLK 0 "memory_operand" "")
6924 (match_operand 1 "" "")] 6292 (match_operand 1 "" "")]
7035 The restore insn that follows will move this to %sp, 6403 The restore insn that follows will move this to %sp,
7036 and reload the appropriate value into %fp. */ 6404 and reload the appropriate value into %fp. */
7037 emit_move_insn (hard_frame_pointer_rtx, stack); 6405 emit_move_insn (hard_frame_pointer_rtx, stack);
7038 6406
7039 emit_use (stack_pointer_rtx); 6407 emit_use (stack_pointer_rtx);
7040 emit_use (static_chain_rtx);
7041 6408
7042 /* ??? The V9-specific version was disabled in rev 1.65. */ 6409 /* ??? The V9-specific version was disabled in rev 1.65. */
7043 emit_jump_insn (gen_goto_handler_and_restore (labreg)); 6410 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7044 emit_barrier (); 6411 emit_barrier ();
7045 DONE; 6412 DONE;
7422 [(trap_if (const_int 1) (const_int 5))] 6789 [(trap_if (const_int 1) (const_int 5))]
7423 "" 6790 ""
7424 "ta\t5" 6791 "ta\t5"
7425 [(set_attr "type" "trap")]) 6792 [(set_attr "type" "trap")])
7426 6793
7427 (define_expand "conditional_trap" 6794 (define_expand "ctrapsi4"
7428 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)]) 6795 [(trap_if (match_operator 0 "noov_compare_operator"
7429 (match_operand:SI 1 "arith_operand" ""))] 6796 [(match_operand:SI 1 "compare_operand" "")
7430 "" 6797 (match_operand:SI 2 "arith_operand" "")])
7431 "operands[2] = gen_compare_reg (GET_CODE (operands[0])); 6798 (match_operand 3 ""))]
7432 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode) 6799 ""
6800 "operands[1] = gen_compare_reg (operands[0]);
6801 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7433 FAIL; 6802 FAIL;
7434 operands[3] = const0_rtx;") 6803 operands[2] = const0_rtx;")
6804
6805 (define_expand "ctrapdi4"
6806 [(trap_if (match_operator 0 "noov_compare_operator"
6807 [(match_operand:DI 1 "compare_operand" "")
6808 (match_operand:DI 2 "arith_operand" "")])
6809 (match_operand 3 ""))]
6810 "TARGET_ARCH64"
6811 "operands[1] = gen_compare_reg (operands[0]);
6812 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6813 FAIL;
6814 operands[2] = const0_rtx;")
6815
7435 6816
7436 (define_insn "" 6817 (define_insn ""
7437 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)]) 6818 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7438 (match_operand:SI 1 "arith_operand" "rM"))] 6819 (match_operand:SI 1 "arith_operand" "rM"))]
7439 "" 6820 ""
8059 [(match_operand 0 "memory_operand" "") 7440 [(match_operand 0 "memory_operand" "")
8060 (match_operand 1 "memory_operand" "") 7441 (match_operand 1 "memory_operand" "")
8061 (match_operand 2 "" "")] 7442 (match_operand 2 "" "")]
8062 "" 7443 ""
8063 { 7444 {
7445 rtx result, test;
8064 #ifdef TARGET_THREAD_SSP_OFFSET 7446 #ifdef TARGET_THREAD_SSP_OFFSET
8065 rtx tlsreg = gen_rtx_REG (Pmode, 7); 7447 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8066 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); 7448 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8067 operands[1] = gen_rtx_MEM (Pmode, addr); 7449 operands[1] = gen_rtx_MEM (Pmode, addr);
8068 #endif 7450 #endif
8069 if (TARGET_ARCH64) 7451 if (TARGET_ARCH64)
8070 { 7452 {
8071 rtx temp = gen_reg_rtx (Pmode); 7453 result = gen_reg_rtx (Pmode);
8072 emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1])); 7454 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
8073 sparc_compare_op0 = temp; 7455 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
8074 sparc_compare_op1 = const0_rtx; 7456 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
8075 } 7457 }
8076 else 7458 else
8077 { 7459 {
8078 emit_insn (gen_stack_protect_testsi (operands[0], operands[1])); 7460 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8079 sparc_compare_op0 = operands[0]; 7461 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8080 sparc_compare_op1 = operands[1]; 7462 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
8081 sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG); 7463 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
8082 } 7464 }
8083 emit_jump_insn (gen_beq (operands[2]));
8084 DONE; 7465 DONE;
8085 }) 7466 })
8086 7467
8087 (define_insn "stack_protect_testsi" 7468 (define_insn "stack_protect_testsi"
8088 [(set (reg:CC 100) 7469 [(set (reg:CC 100)
8171 ;; All other logical instructions have integer equivalents so they 7552 ;; All other logical instructions have integer equivalents so they
8172 ;; are defined together. 7553 ;; are defined together.
8173 7554
8174 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND. 7555 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8175 7556
8176 (define_insn "*nand<V64mode>_vis" 7557 (define_insn "*nand<V64:mode>_vis"
8177 [(set (match_operand:V64 0 "register_operand" "=e") 7558 [(set (match_operand:V64 0 "register_operand" "=e")
8178 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e")) 7559 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8179 (not:V64 (match_operand:V64 2 "register_operand" "e"))))] 7560 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8180 "TARGET_VIS" 7561 "TARGET_VIS"
8181 "fnand\t%1, %2, %0" 7562 "fnand\t%1, %2, %0"
8182 [(set_attr "type" "fga") 7563 [(set_attr "type" "fga")
8183 (set_attr "fptype" "double")]) 7564 (set_attr "fptype" "double")])
8184 7565
8185 (define_insn "*nand<V32mode>_vis" 7566 (define_insn "*nand<V32:mode>_vis"
8186 [(set (match_operand:V32 0 "register_operand" "=f") 7567 [(set (match_operand:V32 0 "register_operand" "=f")
8187 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f")) 7568 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8188 (not:V32 (match_operand:V32 2 "register_operand" "f"))))] 7569 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8189 "TARGET_VIS" 7570 "TARGET_VIS"
8190 "fnands\t%1, %2, %0" 7571 "fnands\t%1, %2, %0"