summaryrefslogtreecommitdiff
path: root/gcc/config/sparc
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2000-01-26 20:14:10 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2000-01-26 20:14:10 +0000
commitb59496fadbe8fb21b91d6d02370ac9fcff66d2d0 (patch)
tree8e4067bc28c66c251c9d71f70e3f4bc0a717fbde /gcc/config/sparc
parentaa4b252e2bb4fa1a0d85d57f7efa3076ba01a4ec (diff)
downloadgcc-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.c146
-rw-r--r--gcc/config/sparc/sparc.md56
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]));