summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.c
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2013-05-31 19:12:05 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2013-05-31 19:12:05 +0000
commitfb80316e470b1700ccaff692aed8e6bc063a1278 (patch)
tree8839e3f25e5f8ccb1211432eea5838353cb12a4b /gcc/config/rs6000/rs6000.c
parentefb076ad21b8806881320a3ba40c100653fc501d (diff)
downloadgcc-fb80316e470b1700ccaff692aed8e6bc063a1278.tar.gz
* config/rs6000/predicates.md (rs6000_cbranch_operator): Accept some
unordered comparison operators when -fno-trapping-math is in effect on the e500. * config/rs6000/rs6000.c (rs6000_generate_compare): Remove dead code and implement unordered comparison operators properly on the e500. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@199557 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r--gcc/config/rs6000/rs6000.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index cb6876051d7..9c4b7f04c35 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -16087,16 +16087,41 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
{
rtx cmp, or_result, compare_result2;
enum machine_mode op_mode = GET_MODE (op0);
+ bool reverse_p;
if (op_mode == VOIDmode)
op_mode = GET_MODE (op1);
+ /* First reverse the condition codes that aren't directly supported. */
+ switch (code)
+ {
+ case NE:
+ case UNLT:
+ case UNLE:
+ case UNGT:
+ case UNGE:
+ code = reverse_condition_maybe_unordered (code);
+ reverse_p = true;
+ break;
+
+ case EQ:
+ case LT:
+ case LE:
+ case GT:
+ case GE:
+ reverse_p = false;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
/* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
This explains the following mess. */
switch (code)
{
- case EQ: case UNEQ: case NE: case LTGT:
+ case EQ:
switch (op_mode)
{
case SFmode:
@@ -16122,7 +16147,8 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
}
break;
- case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
+ case GT:
+ case GE:
switch (op_mode)
{
case SFmode:
@@ -16148,7 +16174,8 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
}
break;
- case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
+ case LT:
+ case LE:
switch (op_mode)
{
case SFmode:
@@ -16173,24 +16200,16 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
gcc_unreachable ();
}
break;
+
default:
gcc_unreachable ();
}
/* Synthesize LE and GE from LT/GT || EQ. */
- if (code == LE || code == GE || code == LEU || code == GEU)
+ if (code == LE || code == GE)
{
emit_insn (cmp);
- switch (code)
- {
- case LE: code = LT; break;
- case GE: code = GT; break;
- case LEU: code = LT; break;
- case GEU: code = GT; break;
- default: gcc_unreachable ();
- }
-
compare_result2 = gen_reg_rtx (CCFPmode);
/* Do the EQ. */
@@ -16217,23 +16236,18 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
default:
gcc_unreachable ();
}
+
emit_insn (cmp);
/* OR them together. */
or_result = gen_reg_rtx (CCFPmode);
cmp = gen_e500_cr_ior_compare (or_result, compare_result,
- compare_result2);
+ compare_result2);
compare_result = or_result;
- code = EQ;
- }
- else
- {
- if (code == NE || code == LTGT)
- code = NE;
- else
- code = EQ;
}
+ code = reverse_p ? NE : EQ;
+
emit_insn (cmp);
}
else