X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdojump.c;h=c955f5d5fb39f9009951b56046847086436e770b;hb=b2eafcc8ff6d32d29cd7d207a0231ed31b01b873;hp=0dc826bbefc1701a1a24d03630d9623089187115;hpb=e7e9416eb976d574b2288c2a61e9b7edd8c702a2;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/dojump.c b/gcc/dojump.c index 0dc826bbefc..c955f5d5fb3 100644 --- a/gcc/dojump.c +++ b/gcc/dojump.c @@ -1,6 +1,6 @@ /* Convert tree expression to rtl instructions, for GNU compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GCC. @@ -16,8 +16,8 @@ for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #include "config.h" #include "system.h" @@ -164,6 +164,7 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label) int i; tree type; enum machine_mode mode; + rtx drop_through_label = 0; switch (code) { @@ -206,14 +207,6 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label) do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label); break; - case MINUS_EXPR: - /* Nonzero iff operands of minus differ. */ - do_compare_and_jump (build2 (NE_EXPR, TREE_TYPE (exp), - TREE_OPERAND (exp, 0), - TREE_OPERAND (exp, 1)), - NE, NE, if_false_label, if_true_label); - break; - case BIT_AND_EXPR: /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1. See if the former is preferred for jump tests and restore it @@ -293,10 +286,29 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label) do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label); break; + case COND_EXPR: + { + rtx label1 = gen_label_rtx (); + if (!if_true_label || !if_false_label) + { + drop_through_label = gen_label_rtx (); + if (!if_true_label) + if_true_label = drop_through_label; + if (!if_false_label) + if_false_label = drop_through_label; + } + + do_pending_stack_adjust (); + do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX); + do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label); + emit_label (label1); + do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label); + break; + } + case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: case COMPOUND_EXPR: - case COND_EXPR: /* Lowered by gimplify.c. */ gcc_unreachable (); @@ -349,6 +361,12 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label) break; } + case MINUS_EXPR: + /* Nonzero iff operands of minus differ. */ + exp = build2 (NE_EXPR, TREE_TYPE (exp), + TREE_OPERAND (exp, 0), + TREE_OPERAND (exp, 1)); + /* FALLTHRU */ case NE_EXPR: { tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0)); @@ -478,23 +496,16 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label) tree op0 = save_expr (TREE_OPERAND (exp, 0)); tree op1 = save_expr (TREE_OPERAND (exp, 1)); tree cmp0, cmp1; - rtx drop_through_label = 0; /* If the target doesn't support combined unordered compares, decompose into two comparisons. */ if (if_true_label == 0) drop_through_label = if_true_label = gen_label_rtx (); - cmp0 = fold (build2 (tcode1, TREE_TYPE (exp), op0, op1)); - cmp1 = fold (build2 (tcode2, TREE_TYPE (exp), op0, op1)); + cmp0 = fold_build2 (tcode1, TREE_TYPE (exp), op0, op1); + cmp1 = fold_build2 (tcode2, TREE_TYPE (exp), op0, op1); do_jump (cmp0, 0, if_true_label); do_jump (cmp1, if_false_label, if_true_label); - - if (drop_through_label) - { - do_pending_stack_adjust (); - emit_label (drop_through_label); - } } } break; @@ -514,7 +525,7 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label) tree arglist = TREE_OPERAND (exp, 1); if (fndecl - && DECL_BUILT_IN (fndecl) + && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT && arglist != NULL_TREE && TREE_CHAIN (arglist) != NULL_TREE) @@ -568,6 +579,12 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label) if_false_label, if_true_label); } } + + if (drop_through_label) + { + do_pending_stack_adjust (); + emit_label (drop_through_label); + } } /* Given a comparison expression EXP for values too wide to be compared @@ -907,7 +924,7 @@ do_compare_and_jump (tree exp, enum rtx_code signed_code, be reliably compared, then canonicalize them. Only do this if *both* sides of the comparison are function pointers. If one side isn't, we want a noncanonicalized comparison. See PR - middle-end/17564. */ + middle-end/17564. */ if (HAVE_canonicalize_funcptr_for_compare && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE && TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))