X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fstmt.c;h=6df6eaa3e2e233c31d0fb3c0e38566e592ce1fb0;hb=75fa4f8228a5394cf18cbe0a924fddd5415287c0;hp=4f366c32264f5bb3cc9f2d71d080e6d711294845;hpb=27335ffdbd00a3c8db8200745a86a2930ff711e8;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/stmt.c b/gcc/stmt.c index 4f366c32264..6df6eaa3e2e 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -1,6 +1,7 @@ /* Expands front end tree to back end RTL for GCC Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Free Software Foundation, Inc. This file is part of GCC. @@ -30,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "tm.h" #include "rtl.h" +#include "hard-reg-set.h" #include "tree.h" #include "tm_p.h" #include "flags.h" @@ -38,7 +40,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "insn-config.h" #include "expr.h" #include "libfuncs.h" -#include "hard-reg-set.h" #include "recog.h" #include "machmode.h" #include "toplev.h" @@ -322,13 +323,13 @@ parse_output_constraint (const char **constraint_p, int operand_num, *is_inout = (*p == '+'); /* Canonicalize the output constraint so that it begins with `='. */ - if (p != constraint || is_inout) + if (p != constraint || *is_inout) { char *buf; size_t c_len = strlen (constraint); if (p != constraint) - warning ("output constraint %qc for operand %d " + warning (0, "output constraint %qc for operand %d " "is not at the beginning", *p, operand_num); @@ -552,20 +553,17 @@ parse_input_constraint (const char **constraint_p, int input_num, } if (saw_match && !*allows_reg) - warning ("matching constraint does not allow a register"); + warning (0, "matching constraint does not allow a register"); return true; } -/* Check for overlap between registers marked in CLOBBERED_REGS and - anything inappropriate in DECL. Emit error and return TRUE for error, - FALSE for ok. */ +/* Return true iff there's an overlap between REGS and DECL, where DECL + can be an asm-declared register. */ -static bool -decl_conflicts_with_clobbers_p (tree decl, const HARD_REG_SET clobbered_regs) +bool +decl_overlaps_hard_reg_set_p (tree decl, const HARD_REG_SET regs) { - /* Conflicts between asm-declared register variables and the clobber - list are not allowed. */ if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) && DECL_REGISTER (decl) && REG_P (DECL_RTL (decl)) @@ -578,18 +576,34 @@ decl_conflicts_with_clobbers_p (tree decl, const HARD_REG_SET clobbered_regs) regno < (REGNO (reg) + hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]); regno++) - if (TEST_HARD_REG_BIT (clobbered_regs, regno)) - { - error ("asm-specifier for variable %qs conflicts with " - "asm clobber list", - IDENTIFIER_POINTER (DECL_NAME (decl))); - - /* Reset registerness to stop multiple errors emitted for a - single variable. */ - DECL_REGISTER (decl) = 0; - return true; - } + if (TEST_HARD_REG_BIT (regs, regno)) + return true; + } + + return false; +} + + +/* Check for overlap between registers marked in CLOBBERED_REGS and + anything inappropriate in DECL. Emit error and return TRUE for error, + FALSE for ok. */ + +static bool +decl_conflicts_with_clobbers_p (tree decl, const HARD_REG_SET clobbered_regs) +{ + /* Conflicts between asm-declared register variables and the clobber + list are not allowed. */ + if (decl_overlaps_hard_reg_set_p (decl, clobbered_regs)) + { + error ("asm-specifier for variable %qs conflicts with asm clobber list", + IDENTIFIER_POINTER (DECL_NAME (decl))); + + /* Reset registerness to stop multiple errors emitted for a single + variable. */ + DECL_REGISTER (decl) = 0; + return true; } + return false; } @@ -655,7 +669,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs, Case in point is when the i386 backend moved from cc0 to a hard reg -- maintaining source-level compatibility means automatically clobbering the flags register. */ - clobbers = targetm.md_asm_clobbers (clobbers); + clobbers = targetm.md_asm_clobbers (outputs, inputs, clobbers); /* Count the number of meaningful clobbered registers, ignoring what we would ignore later. */ @@ -863,10 +877,10 @@ expand_asm_operands (tree string, tree outputs, tree inputs, if (asm_operand_ok (op, constraint) <= 0) { - if (allows_reg) + if (allows_reg && TYPE_MODE (type) != BLKmode) op = force_reg (TYPE_MODE (type), op); else if (!allows_mem) - warning ("asm operand %d probably doesn%'t match constraints", + warning (0, "asm operand %d probably doesn%'t match constraints", i + noutputs); else if (MEM_P (op)) { @@ -876,7 +890,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs, } else { - warning ("use of memory input without lvalue in " + warning (0, "use of memory input without lvalue in " "asm operand %d is deprecated", i + noutputs); if (CONSTANT_P (op)) @@ -1461,7 +1475,7 @@ warn_if_unused_value (tree exp, location_t locus) if (TREE_SIDE_EFFECTS (exp)) return 0; - warning ("%Hvalue computed is not used", &locus); + warning (0, "%Hvalue computed is not used", &locus); return 1; } } @@ -2224,10 +2238,10 @@ emit_case_bit_tests (tree index_type, tree index_expr, tree minval, else test[i].bits++; - lo = tree_low_cst (fold (build2 (MINUS_EXPR, index_type, - n->low, minval)), 1); - hi = tree_low_cst (fold (build2 (MINUS_EXPR, index_type, - n->high, minval)), 1); + lo = tree_low_cst (fold_build2 (MINUS_EXPR, index_type, + n->low, minval), 1); + hi = tree_low_cst (fold_build2 (MINUS_EXPR, index_type, + n->high, minval), 1); for (j = lo; j <= hi; j++) if (j >= HOST_BITS_PER_WIDE_INT) test[i].hi |= (HOST_WIDE_INT) 1 << (j - HOST_BITS_PER_INT); @@ -2237,9 +2251,9 @@ emit_case_bit_tests (tree index_type, tree index_expr, tree minval, qsort (test, count, sizeof(*test), case_bit_test_cmp); - index_expr = fold (build2 (MINUS_EXPR, index_type, - convert (index_type, index_expr), - convert (index_type, minval))); + index_expr = fold_build2 (MINUS_EXPR, index_type, + fold_convert (index_type, index_expr), + fold_convert (index_type, minval)); index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0); do_pending_stack_adjust (); @@ -2393,11 +2407,17 @@ expand_case (tree exp) BITMAP_FREE (label_bitmap); /* cleanup_tree_cfg removes all SWITCH_EXPR with a single - destination, such as one with a default case only. */ - gcc_assert (count != 0); + destination, such as one with a default case only. However, + it doesn't remove cases that are out of range for the switch + type, so we may still get a zero here. */ + if (count == 0) + { + emit_jump (default_label); + return; + } /* Compute span of values. */ - range = fold (build2 (MINUS_EXPR, index_type, maxval, minval)); + range = fold_build2 (MINUS_EXPR, index_type, maxval, minval); /* Try implementing this switch statement by a short sequence of bit-wise comparisons. However, we let the binary-tree case @@ -2417,7 +2437,7 @@ expand_case (tree exp) if (compare_tree_int (minval, 0) > 0 && compare_tree_int (maxval, GET_MODE_BITSIZE (word_mode)) < 0) { - minval = integer_zero_node; + minval = build_int_cst (index_type, 0); range = maxval; } emit_case_bit_tests (index_type, index_expr, minval, range, @@ -2438,6 +2458,7 @@ expand_case (tree exp) #ifndef ASM_OUTPUT_ADDR_DIFF_ELT || flag_pic #endif + || !flag_jump_tables || TREE_CONSTANT (index_expr) /* If neither casesi or tablejump is available, we can only go this way. */ @@ -2495,7 +2516,6 @@ expand_case (tree exp) table_label, default_label)) { bool ok; - index_type = integer_type_node; /* Index jumptables from zero for suitable values of minval to avoid a subtraction. */ @@ -2503,7 +2523,7 @@ expand_case (tree exp) && compare_tree_int (minval, 0) > 0 && compare_tree_int (minval, 3) < 0) { - minval = integer_zero_node; + minval = build_int_cst (index_type, 0); range = maxval; } @@ -2524,11 +2544,11 @@ expand_case (tree exp) value since that should fit in a HOST_WIDE_INT while the actual values may not. */ HOST_WIDE_INT i_low - = tree_low_cst (fold (build2 (MINUS_EXPR, index_type, - n->low, minval)), 1); + = tree_low_cst (fold_build2 (MINUS_EXPR, index_type, + n->low, minval), 1); HOST_WIDE_INT i_high - = tree_low_cst (fold (build2 (MINUS_EXPR, index_type, - n->high, minval)), 1); + = tree_low_cst (fold_build2 (MINUS_EXPR, index_type, + n->high, minval), 1); HOST_WIDE_INT i; for (i = i_low; i <= i_high; i ++) @@ -2611,8 +2631,7 @@ static int estimate_case_costs (case_node_ptr node) { tree min_ascii = integer_minus_one_node; - tree max_ascii = convert (TREE_TYPE (node->high), - build_int_cst (NULL_TREE, 127)); + tree max_ascii = build_int_cst (TREE_TYPE (node->high), 127); case_node_ptr n; int i; @@ -2810,8 +2829,9 @@ node_has_low_bound (case_node_ptr node, tree index_type) if (node->left) return 0; - low_minus_one = fold (build2 (MINUS_EXPR, TREE_TYPE (node->low), - node->low, integer_one_node)); + low_minus_one = fold_build2 (MINUS_EXPR, TREE_TYPE (node->low), + node->low, + build_int_cst (TREE_TYPE (node->low), 1)); /* If the subtraction above overflowed, we can't verify anything. Otherwise, look for a parent that tests our value - 1. */ @@ -2860,8 +2880,9 @@ node_has_high_bound (case_node_ptr node, tree index_type) if (node->right) return 0; - high_plus_one = fold (build2 (PLUS_EXPR, TREE_TYPE (node->high), - node->high, integer_one_node)); + high_plus_one = fold_build2 (PLUS_EXPR, TREE_TYPE (node->high), + node->high, + build_int_cst (TREE_TYPE (node->high), 1)); /* If the addition above overflowed, we can't verify anything. Otherwise, look for a parent that tests our value + 1. */ @@ -3285,8 +3306,8 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label, new_index = expand_simple_binop (mode, MINUS, index, low_rtx, NULL_RTX, unsignedp, OPTAB_WIDEN); - new_bound = expand_expr (fold (build2 (MINUS_EXPR, type, - high, low)), + new_bound = expand_expr (fold_build2 (MINUS_EXPR, type, + high, low), NULL_RTX, mode, 0); emit_cmp_and_jump_insns (new_index, new_bound, GT, NULL_RTX,