diff options
author | Geoffrey Keating <geoffk@gcc.gnu.org> | 2000-03-20 23:47:39 +0000 |
---|---|---|
committer | Geoffrey Keating <geoffk@gcc.gnu.org> | 2000-03-20 23:47:39 +0000 |
commit | 1c882ea4e71916155a8e51691c816efcf540c8c9 (patch) | |
tree | 670d1a01fc1173ce2258821f8b73fbf48fb711c2 | |
parent | 8c57aea6ec8a35c4fbb8f46eae50b278a602fa24 (diff) | |
download | gcc-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/ChangeLog | 28 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 89 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 120 |
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 |