diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-05-31 19:12:05 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-05-31 19:12:05 +0000 |
commit | fb80316e470b1700ccaff692aed8e6bc063a1278 (patch) | |
tree | 8839e3f25e5f8ccb1211432eea5838353cb12a4b /gcc/config/rs6000/rs6000.c | |
parent | efb076ad21b8806881320a3ba40c100653fc501d (diff) | |
download | gcc-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.c | 58 |
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 |