diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-01-26 20:14:10 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-01-26 20:14:10 +0000 |
commit | b59496fadbe8fb21b91d6d02370ac9fcff66d2d0 (patch) | |
tree | 8e4067bc28c66c251c9d71f70e3f4bc0a717fbde /gcc/config/sparc | |
parent | aa4b252e2bb4fa1a0d85d57f7efa3076ba01a4ec (diff) | |
download | gcc-b59496fadbe8fb21b91d6d02370ac9fcff66d2d0.tar.gz |
* config/sparc/sparc.c (sparc_emit_float_lib_cmp): Handle
TARGET_ARCH32 again. Handle ORDERED, UN* and LTGT comparisons
using _Qp_cmp/_Q_cmp and testing the return value.
(print_operand): Call reverse_condition_maybe_unordered if
we are handling CCFPmode or CCFPEmode.
Handle ORDERED, UN* and LTGT comparisons.
* config/sparc/sparc.md (cmptf): Use even on TARGET_ARCH32
if not TARGET_HARD_QUAD.
(seq, sne, sgt, slt, sge, sle, beq, bne, bgt, blt, bge, ble,
bunordered, bordered, bungt, bunlt, buneq, bunge, bunle, bltgt):
Call sparc_emit_float_lib_cmp even on TARGET_ARCH32.
Adjust gen_b* calls so that they reflect return comparison of
sparc_emit_float_lib_cmp.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31631 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/sparc')
-rw-r--r-- | gcc/config/sparc/sparc.c | 146 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 56 |
2 files changed, 143 insertions, 59 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 88502a3ec27..d6b80b28399 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -4822,33 +4822,46 @@ sparc_emit_float_lib_cmp (x, y, comparison) rtx x, y; enum rtx_code comparison; { - const char *qpfunc; - rtx slot0, slot1, result; + char *qpfunc; + rtx cmp = const0_rtx; + rtx slot0, slot1, result, tem, tem2; + enum machine_mode mode; switch (comparison) { case EQ: - qpfunc = "_Qp_feq"; + qpfunc = (TARGET_ARCH64) ? "_Qp_feq" : "_Q_feq"; break; case NE: - qpfunc = "_Qp_fne"; + qpfunc = (TARGET_ARCH64) ? "_Qp_fne" : "_Q_fne"; break; case GT: - qpfunc = "_Qp_fgt"; + qpfunc = (TARGET_ARCH64) ? "_Qp_fgt" : "_Q_fgt"; break; case GE: - qpfunc = "_Qp_fge"; + qpfunc = (TARGET_ARCH64) ? "_Qp_fge" : "_Q_fge"; break; case LT: - qpfunc = "_Qp_flt"; + qpfunc = (TARGET_ARCH64) ? "_Qp_flt" : "_Q_flt"; break; case LE: - qpfunc = "_Qp_fle"; + qpfunc = (TARGET_ARCH64) ? "_Qp_fle" : "_Q_fle"; + break; + + case ORDERED: + case UNORDERED: + case UNGT: + case UNLT: + case UNEQ: + case UNGE: + case UNLE: + case LTGT: + qpfunc = (TARGET_ARCH64) ? "_Qp_cmp" : "_Q_cmp"; break; default: @@ -4856,33 +4869,97 @@ sparc_emit_float_lib_cmp (x, y, comparison) break; } - if (GET_CODE (x) != MEM) + if (TARGET_ARCH64) { - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot0, x)); - } + if (GET_CODE (x) != MEM) + { + slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); + emit_insn (gen_rtx_SET (VOIDmode, slot0, x)); + } + else + slot0 = x; + + if (GET_CODE (y) != MEM) + { + slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); + emit_insn (gen_rtx_SET (VOIDmode, slot1, y)); + } + else + slot1 = y; - if (GET_CODE (y) != MEM) + emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), 1, + DImode, 2, + XEXP (slot0, 0), Pmode, + XEXP (slot1, 0), Pmode); + + mode = DImode; + } + else { - slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot1, y)); + emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), 1, + SImode, 2, + x, TFmode, y, TFmode); + + mode = SImode; } - emit_library_call (gen_rtx (SYMBOL_REF, Pmode, qpfunc), 1, - DImode, 2, - XEXP (slot0, 0), Pmode, - XEXP (slot1, 0), Pmode); /* Immediately move the result of the libcall into a pseudo register so reload doesn't clobber the value if it needs the return register for a spill reg. */ - result = gen_reg_rtx (DImode); - emit_move_insn (result, hard_libcall_value (DImode)); + result = gen_reg_rtx (mode); + emit_move_insn (result, hard_libcall_value (mode)); - emit_cmp_insn (result, const0_rtx, comparison, - NULL_RTX, DImode, 0, 0); + switch (comparison) + { + default: + emit_cmp_insn (result, const0_rtx, NE, + NULL_RTX, mode, 0, 0); + break; + case ORDERED: + case UNORDERED: + emit_cmp_insn (result, GEN_INT(3), + (comparison == UNORDERED) ? EQ : NE, + NULL_RTX, mode, 0, 0); + break; + case UNGT: + case UNGE: + emit_cmp_insn (result, const1_rtx, + (comparison == UNGT) ? GT : NE, + NULL_RTX, mode, 0, 0); + break; + case UNLE: + emit_cmp_insn (result, const2_rtx, NE, + NULL_RTX, mode, 0, 0); + break; + case UNLT: + tem = gen_reg_rtx (mode); + if (TARGET_ARCH32) + emit_insn (gen_andsi3 (tem, result, const1_rtx)); + else + emit_insn (gen_anddi3 (tem, result, const1_rtx)); + emit_cmp_insn (tem, const0_rtx, NE, + NULL_RTX, mode, 0, 0); + break; + case UNEQ: + case LTGT: + tem = gen_reg_rtx (mode); + if (TARGET_ARCH32) + emit_insn (gen_addsi3 (tem, result, const1_rtx)); + else + emit_insn (gen_adddi3 (tem, result, const1_rtx)); + tem2 = gen_reg_rtx (mode); + if (TARGET_ARCH32) + emit_insn (gen_andsi3 (tem2, tem, const2_rtx)); + else + emit_insn (gen_anddi3 (tem2, tem, const2_rtx)); + emit_cmp_insn (tem2, const0_rtx, + (comparison == UNEQ) ? EQ : NE, + NULL_RTX, mode, 0, 0); + break; + } } - + /* Return the string to output a conditional branch to LABEL, testing register REG. LABEL is the operand number of the label; REG is the operand number of the reg. OP is the conditional expression. The mode @@ -5449,9 +5526,16 @@ print_operand (file, x, code) case 'c' : case 'C': { - enum rtx_code rc = (code == 'c' - ? reverse_condition (GET_CODE (x)) - : GET_CODE (x)); + enum rtx_code rc = GET_CODE (x); + + if (code == 'c') + { + enum machine_mode mode = GET_MODE (XEXP (x, 0)); + if (mode == CCFPmode || mode == CCFPEmode) + rc = reverse_condition_maybe_unordered (GET_CODE (x)); + else + rc = reverse_condition (GET_CODE (x)); + } switch (rc) { case NE: fputs ("ne", file); break; @@ -5464,6 +5548,14 @@ print_operand (file, x, code) case GTU: fputs ("gu", file); break; case LEU: fputs ("leu", file); break; case LTU: fputs ("lu", file); break; + case LTGT: fputs ("lg", file); break; + case UNORDERED: fputs ("u", file); break; + case ORDERED: fputs ("o", file); break; + case UNLT: fputs ("ul", file); break; + case UNLE: fputs ("ule", file); break; + case UNGT: fputs ("ug", file); break; + case UNGE: fputs ("uge", file); break; + case UNEQ: fputs ("ue", file); break; default: output_operand_lossage (code == 'c' ? "Invalid %%c operand" : "Invalid %%C operand"); diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 950d9ae4718..40fe3a86d8f 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -627,7 +627,7 @@ [(set (reg:CCFP 96) (compare:CCFP (match_operand:TF 0 "register_operand" "") (match_operand:TF 1 "register_operand" "")))] - "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" + "TARGET_FPU" " { sparc_compare_op0 = operands[0]; @@ -855,7 +855,7 @@ emit_insn (pat); DONE; } - else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ); emit_jump_insn (gen_sne (operands[0])); @@ -908,7 +908,7 @@ emit_insn (pat); DONE; } - else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE); emit_jump_insn (gen_sne (operands[0])); @@ -929,7 +929,7 @@ "! TARGET_LIVE_G0" " { - if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT); emit_jump_insn (gen_sne (operands[0])); @@ -950,7 +950,7 @@ "! TARGET_LIVE_G0" " { - if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT); emit_jump_insn (gen_sne (operands[0])); @@ -971,7 +971,7 @@ "! TARGET_LIVE_G0" " { - if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE); emit_jump_insn (gen_sne (operands[0])); @@ -992,7 +992,7 @@ "! TARGET_LIVE_G0" " { - if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE); emit_jump_insn (gen_sne (operands[0])); @@ -1626,7 +1626,7 @@ emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]); DONE; } - else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ); emit_jump_insn (gen_bne (operands[0])); @@ -1650,7 +1650,7 @@ emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]); DONE; } - else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE); emit_jump_insn (gen_bne (operands[0])); @@ -1674,7 +1674,7 @@ emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]); DONE; } - else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT); emit_jump_insn (gen_bne (operands[0])); @@ -1708,7 +1708,7 @@ emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]); DONE; } - else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT); emit_jump_insn (gen_bne (operands[0])); @@ -1742,7 +1742,7 @@ emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]); DONE; } - else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE); emit_jump_insn (gen_bne (operands[0])); @@ -1776,7 +1776,7 @@ emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]); DONE; } - else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE); emit_jump_insn (gen_bne (operands[0])); @@ -1803,12 +1803,11 @@ "" " { - if (GET_MODE (sparc_compare_op0) == TFmode - && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNORDERED); - emit_jump_insn (gen_bne (operands[0])); + emit_jump_insn (gen_beq (operands[0])); DONE; } operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0, @@ -1823,8 +1822,7 @@ "" " { - if (GET_MODE (sparc_compare_op0) == TFmode - && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED); emit_jump_insn (gen_bne (operands[0])); @@ -1842,11 +1840,10 @@ "" " { - if (GET_MODE (sparc_compare_op0) == TFmode - && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT); - emit_jump_insn (gen_bne (operands[0])); + emit_jump_insn (gen_bgt (operands[0])); DONE; } operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1); @@ -1860,8 +1857,7 @@ "" " { - if (GET_MODE (sparc_compare_op0) == TFmode - && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT); emit_jump_insn (gen_bne (operands[0])); @@ -1878,11 +1874,10 @@ "" " { - if (GET_MODE (sparc_compare_op0) == TFmode - && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ); - emit_jump_insn (gen_bne (operands[0])); + emit_jump_insn (gen_beq (operands[0])); DONE; } operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1); @@ -1896,8 +1891,7 @@ "" " { - if (GET_MODE (sparc_compare_op0) == TFmode - && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE); emit_jump_insn (gen_bne (operands[0])); @@ -1914,8 +1908,7 @@ "" " { - if (GET_MODE (sparc_compare_op0) == TFmode - && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE); emit_jump_insn (gen_bne (operands[0])); @@ -1932,8 +1925,7 @@ "" " { - if (GET_MODE (sparc_compare_op0) == TFmode - && TARGET_ARCH64 && ! TARGET_HARD_QUAD) + if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) { sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT); emit_jump_insn (gen_bne (operands[0])); |