Mercurial > hg > CbC > CbC_gcc
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" |