aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeoffrey Keating <geoffk@gcc.gnu.org>2000-03-20 23:47:39 +0000
committerGeoffrey Keating <geoffk@gcc.gnu.org>2000-03-20 23:47:39 +0000
commit1c882ea4e71916155a8e51691c816efcf540c8c9 (patch)
tree670d1a01fc1173ce2258821f8b73fbf48fb711c2
parent8c57aea6ec8a35c4fbb8f46eae50b278a602fa24 (diff)
downloadgcc-1c882ea4e71916155a8e51691c816efcf540c8c9.zip
gcc-1c882ea4e71916155a8e51691c816efcf540c8c9.tar.gz
gcc-1c882ea4e71916155a8e51691c816efcf540c8c9.tar.bz2
rs6000.md (bunordered): New expander.
* config/rs6000/rs6000.md (bunordered): New expander. (bordered): New expander. (buneq): New expander. (bunge): New expander. (bungt): New expander. (bunle): New expander. (bunlt): New expander. (bltgt): New expander. * config/rs6000/rs6000.c (ccr_bit): Handle unordered comparisons. (ccr_bit_negated_p): New function. (print_operand): For %C, generate appropriate cror for UNEQ, UNLT, UNGT, and LTGT. For %T and %t, use ccr_bit_negated_p. From-SVN: r32657
-rw-r--r--gcc/ChangeLog28
-rw-r--r--gcc/config/rs6000/rs6000.c89
-rw-r--r--gcc/config/rs6000/rs6000.md120
3 files changed, 206 insertions, 31 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3390bda..c8b1268 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2000-03-20 Geoff Keating <geoffk@cygnus.com>
+
+ * config/rs6000/rs6000.md (bunordered): New expander.
+ (bordered): New expander.
+ (buneq): New expander.
+ (bunge): New expander.
+ (bungt): New expander.
+ (bunle): New expander.
+ (bunlt): New expander.
+ (bltgt): New expander.
+
+ * config/rs6000/rs6000.c (ccr_bit): Handle unordered comparisons.
+ (ccr_bit_negated_p): New function.
+ (print_operand): For %C, generate appropriate cror for UNEQ,
+ UNLT, UNGT, and LTGT. For %T and %t, use ccr_bit_negated_p.
+
2000-03-20 Andreas Jaeger <aj@suse.de>
* sdbout.c (sdbout_one_type): Add braces to avoid "ambigous else"
@@ -17126,7 +17142,7 @@ Fri Aug 20 18:53:43 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
copy_rtx_and_substitute, subst_constants, restore_constants):
Likewise.
- * jump.c (mark_jump_label, invert_exp, redirect_exp,
+ * jump.c (mark_jump_label, invert_exp, redirect_e
rtx_renumbered_equal_p, rtx_equal_for_thread_p): Likewise.
* local-alloc.c (contains_replace_regs, memref_referenced_p):
@@ -17256,7 +17272,7 @@ Fri Aug 20 15:02:10 1999 Mark Mitchell <mark@codesourcery.com>
Fri Aug 20 22:32:17 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
- * config/c4x/c4x.h (STARTFILE_SPEC): Don't define.
+ * config/c4x/c4x.h (STARTFILE_SPEC): Don't def.
1999-08-19 18:43 -0700 Zack Weinberg <zack@bitmover.com>
@@ -17966,7 +17982,7 @@ Mon Aug 9 10:08:50 1999 Bernd Schmidt <bernds@cygnus.co.uk>
(unroll_loop): Access regno_pointer_* variables through
current_function.
- * tree.h (struct tree_decl): Add elt f to saved_insns member.
+ * tree.h (struct tree_decl): Add elt f to saved_ins
(DECL_SAVED_INSNS): use it.
(expand_dummy_function_end): Declare.
(init_function_for_compilation): Declare.
@@ -18072,7 +18088,7 @@ Sat Aug 7 00:21:20 1999 Richard Henderson <rth@cygnus.com>
Sat Aug 7 00:06:54 1999 Jeffrey A Law (law@cygnus.com)
- * Makefile.in (TAROUTOPTS): Kill.
+ * Makefiin (TAROUTOPTS): Kill.
(install-headers-tar): Use "xpf" for tar headerfile extraction
* i370/x-oe (TAROUTOPTS): Delete.
* m68k/x-apollo68 (TAROUTOPTS): Delete.
@@ -18869,7 +18885,7 @@ Wed Jul 28 11:22:21 1999 Richard Henderson <rth@cygnus.com>
Wed Jul 28 11:20:19 1999 Richard Henderson <rth@cygnus.com>
- * mn10200.c (mn10200_va_arg): New.
+ * mn102
* mn10200.h (EXPAND_BUILTIN_VA_ARG): New.
Wed Jul 28 11:19:06 1999 Richard Henderson <rth@cygnus.com>
@@ -18979,7 +18995,7 @@ Mon Jul 26 22:43:12 1999 Richard Henderson <rth@cygnus.com>
Mon Jul 26 18:51:34 1999 Richard Henderson <rth@cygnus.com>
- * except.c (start_dynamic_cleanup): Use force_operand on the
+ * except.c (st_dynamic_cleanup): Use force_operand on the
buffer's address.
Mon Jul 26 16:43:26 1999 Richard Henderson <rth@cygnus.com>
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index e792358..04539ee 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -119,6 +119,7 @@ static int rs6000_sr_alias_set;
static void rs6000_add_gc_roots PARAMS ((void));
static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
static rtx expand_block_move_mem PARAMS ((enum machine_mode, rtx, rtx));
+static int ccr_bit_negated_p PARAMS((rtx));
static void rs6000_emit_stack_tie PARAMS ((void));
static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));
static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
@@ -3172,10 +3173,12 @@ ccr_bit (op, scc_p)
return scc_p ? base_bit + 3 : base_bit + 2;
case EQ:
return base_bit + 2;
- case GT: case GTU:
+ case GT: case GTU: case UNLE:
return base_bit + 1;
- case LT: case LTU:
+ case LT: case LTU: case UNGE:
return base_bit;
+ case ORDERED: case UNORDERED:
+ return base_bit + 3;
case GE: case GEU:
/* If floating-point, we will have done a cror to put the bit in the
@@ -3186,10 +3189,36 @@ ccr_bit (op, scc_p)
case LE: case LEU:
return cc_mode == CCFPmode || scc_p ? base_bit + 3 : base_bit + 1;
+ case UNEQ: case UNGT: case UNLT: case LTGT:
+ return base_bit + 3;
+
default:
abort ();
}
}
+
+/* Given a comparison operation, say whether the bit tested (as returned
+ by ccr_bit) should be negated. */
+
+static int
+ccr_bit_negated_p (op)
+ rtx op;
+{
+ enum rtx_code code = GET_CODE (op);
+ enum machine_mode mode = GET_MODE (XEXP (op, 0));
+
+ if (code == EQ
+ || code == LT || code == GT
+ || code == LTU || code == GTU)
+ return 0;
+ else if (mode != CCFPmode
+ || code == NE
+ || code == ORDERED
+ || code == UNGE || code == UNLE)
+ return 1;
+ else
+ return 0;
+}
/* Return the GOT register. */
@@ -3322,16 +3351,36 @@ print_operand (file, x, code)
return;
case 'C':
- /* This is an optional cror needed for LE or GE floating-point
- comparisons. Otherwise write nothing. */
- if ((GET_CODE (x) == LE || GET_CODE (x) == GE)
- && GET_MODE (XEXP (x, 0)) == CCFPmode)
- {
- int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
-
- fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
- base_bit + 2, base_bit + (GET_CODE (x) == GE));
- }
+ {
+ enum rtx_code code = GET_CODE (x);
+
+ /* This is an optional cror needed for certain floating-point
+ comparisons. Otherwise write nothing. */
+ if ((code == LE || code == GE
+ || code == UNEQ || code == LTGT
+ || code == UNGT || code == UNLT)
+ && GET_MODE (XEXP (x, 0)) == CCFPmode)
+ {
+ int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
+ int bit0, bit1;
+
+ if (code == UNEQ)
+ bit0 = 2;
+ else if (code == UNGT || code == GE)
+ bit0 = 1;
+ else
+ bit0 = 0;
+ if (code == LTGT)
+ bit1 = 1;
+ else if (code == LE || code == GE)
+ bit1 = 2;
+ else
+ bit1 = 3;
+
+ fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
+ base_bit + bit1, base_bit + bit0);
+ }
+ }
return;
case 'D':
@@ -3675,17 +3724,11 @@ print_operand (file, x, code)
}
case 't':
- /* Write 12 if this jump operation will branch if true, 4 otherwise.
- All floating-point operations except NE branch true and integer
- EQ, LT, GT, LTU and GTU also branch true. */
+ /* Write 12 if this jump operation will branch if true, 4 otherwise. */
if (GET_RTX_CLASS (GET_CODE (x)) != '<')
output_operand_lossage ("invalid %%t value");
- else if ((GET_MODE (XEXP (x, 0)) == CCFPmode
- && GET_CODE (x) != NE)
- || GET_CODE (x) == EQ
- || GET_CODE (x) == LT || GET_CODE (x) == GT
- || GET_CODE (x) == LTU || GET_CODE (x) == GTU)
+ else if (! ccr_bit_negated_p (x))
fputs ("12", file);
else
putc ('4', file);
@@ -3697,11 +3740,7 @@ print_operand (file, x, code)
if (GET_RTX_CLASS (GET_CODE (x)) != '<')
output_operand_lossage ("invalid %%T value");
- else if ((GET_MODE (XEXP (x, 0)) == CCFPmode
- && GET_CODE (x) != NE)
- || GET_CODE (x) == EQ
- || GET_CODE (x) == LT || GET_CODE (x) == GT
- || GET_CODE (x) == LTU || GET_CODE (x) == GTU)
+ else if (! ccr_bit_negated_p (x))
putc ('4', file);
else
fputs ("12", file);
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 2e23778..8d9d8a7 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -10849,6 +10849,126 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
operands[2] = gen_reg_rtx (CCUNSmode);
}")
+(define_expand "bunordered"
+ [(set (match_dup 2) (match_dup 1))
+ (set (pc)
+ (if_then_else (unordered (match_dup 2)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{ if (!rs6000_compare_fp_p) FAIL;
+ operands[1] = gen_rtx_COMPARE (CCFPmode,
+ rs6000_compare_op0, rs6000_compare_op1);
+ operands[2] = gen_reg_rtx (CCFPmode);
+}")
+
+(define_expand "bordered"
+ [(set (match_dup 2) (match_dup 1))
+ (set (pc)
+ (if_then_else (ordered (match_dup 2)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{ if (!rs6000_compare_fp_p) FAIL;
+ operands[1] = gen_rtx_COMPARE (CCFPmode,
+ rs6000_compare_op0, rs6000_compare_op1);
+ operands[2] = gen_reg_rtx (CCFPmode);
+}")
+
+(define_expand "buneq"
+ [(set (match_dup 2) (match_dup 1))
+ (set (pc)
+ (if_then_else (uneq (match_dup 2)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{ if (!rs6000_compare_fp_p) FAIL;
+ operands[1] = gen_rtx_COMPARE (CCFPmode,
+ rs6000_compare_op0, rs6000_compare_op1);
+ operands[2] = gen_reg_rtx (CCFPmode);
+}")
+
+(define_expand "bunge"
+ [(set (match_dup 2) (match_dup 1))
+ (set (pc)
+ (if_then_else (unge (match_dup 2)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{ if (!rs6000_compare_fp_p) FAIL;
+ operands[1] = gen_rtx_COMPARE (CCFPmode,
+ rs6000_compare_op0, rs6000_compare_op1);
+ operands[2] = gen_reg_rtx (CCFPmode);
+}")
+
+(define_expand "bungt"
+ [(set (match_dup 2) (match_dup 1))
+ (set (pc)
+ (if_then_else (ungt (match_dup 2)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{ if (!rs6000_compare_fp_p) FAIL;
+ operands[1] = gen_rtx_COMPARE (CCFPmode,
+ rs6000_compare_op0, rs6000_compare_op1);
+ operands[2] = gen_reg_rtx (CCFPmode);
+}")
+
+(define_expand "bunle"
+ [(set (match_dup 2) (match_dup 1))
+ (set (pc)
+ (if_then_else (unle (match_dup 2)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{ if (!rs6000_compare_fp_p) FAIL;
+ operands[1] = gen_rtx_COMPARE (CCFPmode,
+ rs6000_compare_op0, rs6000_compare_op1);
+ operands[2] = gen_reg_rtx (CCFPmode);
+}")
+
+(define_expand "bunlt"
+ [(set (match_dup 2) (match_dup 1))
+ (set (pc)
+ (if_then_else (unlt (match_dup 2)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{ if (!rs6000_compare_fp_p) FAIL;
+ operands[1] = gen_rtx_COMPARE (CCFPmode,
+ rs6000_compare_op0, rs6000_compare_op1);
+ operands[2] = gen_reg_rtx (CCFPmode);
+}")
+
+(define_expand "bltgt"
+ [(set (match_dup 2) (match_dup 1))
+ (set (pc)
+ (if_then_else (ltgt (match_dup 2)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "
+{ if (!rs6000_compare_fp_p) FAIL;
+ operands[1] = gen_rtx_COMPARE (CCFPmode,
+ rs6000_compare_op0, rs6000_compare_op1);
+ operands[2] = gen_reg_rtx (CCFPmode);
+}")
+
;; For SNE, we would prefer that the xor/abs sequence be used for integers.
;; For SEQ, likewise, except that comparisons with zero should be done
;; with an scc insns. However, due to the order that combine see the