stmt.c: Don't include insn-codes.h.
* stmt.c: Don't include insn-codes.h. (expand_end_case): Machine specific logic moved to expr.c. No need to worry about __builtin_classify_type. (check_for_full_enumeration_handling, emit_case_nodes): Kill #if 0 blocks. * builtins.o (expand_builtin_classify_type): Split up so code can be shared with fold_builtin_classify_type. (type_to_class, fold_builtin_classify_type): New functions. (fold_builtins): Handle __builtin_classify_type. * expr.c (do_tablejump): Now static. (case_values_threshold, try_casesi, try_tablejump): New; code mostly from stmt.c (expand_end_case). (expr.h): Update prototypes. * Makefile.in (stmt.o): Update dependencies. From-SVN: r45078
This commit is contained in:
parent
71038fd576
commit
ad82abb8e6
|
@ -1,3 +1,23 @@
|
|||
2001-08-21 Zack Weinberg <zackw@panix.com>
|
||||
|
||||
* stmt.c: Don't include insn-codes.h.
|
||||
(expand_end_case): Machine specific logic moved to expr.c.
|
||||
No need to worry about __builtin_classify_type.
|
||||
(check_for_full_enumeration_handling, emit_case_nodes):
|
||||
Kill #if 0 blocks.
|
||||
|
||||
* builtins.o (expand_builtin_classify_type): Split up so code
|
||||
can be shared with fold_builtin_classify_type.
|
||||
(type_to_class, fold_builtin_classify_type): New functions.
|
||||
(fold_builtins): Handle __builtin_classify_type.
|
||||
|
||||
* expr.c (do_tablejump): Now static.
|
||||
(case_values_threshold, try_casesi, try_tablejump): New;
|
||||
code mostly from stmt.c (expand_end_case).
|
||||
(expr.h): Update prototypes.
|
||||
|
||||
* Makefile.in (stmt.o): Update dependencies.
|
||||
|
||||
2001-08-21 Will Cohen <wcohen@redhat.com>
|
||||
|
||||
* configure/alpha/alpha.h (CONDITIONAL_REGISTER_USAGE): Added local
|
||||
|
|
|
@ -1383,7 +1383,7 @@ function.o : function.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
|
|||
function.h insn-codes.h $(EXPR_H) libfuncs.h $(REGS_H) hard-reg-set.h \
|
||||
insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h $(GGC_H) $(TM_P_H)
|
||||
stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h \
|
||||
insn-config.h insn-codes.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \
|
||||
insn-config.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \
|
||||
$(LOOP_H) $(RECOG_H) toplev.h output.h varray.h $(GGC_H) $(TM_P_H)
|
||||
except.o : except.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
|
||||
except.h function.h $(EXPR_H) libfuncs.h integrate.h \
|
||||
|
|
|
@ -91,6 +91,7 @@ static rtx expand_builtin_apply_args PARAMS ((void));
|
|||
static rtx expand_builtin_apply_args_1 PARAMS ((void));
|
||||
static rtx expand_builtin_apply PARAMS ((rtx, rtx, rtx));
|
||||
static void expand_builtin_return PARAMS ((rtx));
|
||||
static int type_to_class PARAMS ((tree));
|
||||
static rtx expand_builtin_classify_type PARAMS ((tree));
|
||||
static rtx expand_builtin_mathfn PARAMS ((tree, rtx, rtx));
|
||||
static rtx expand_builtin_constant_p PARAMS ((tree));
|
||||
|
@ -142,6 +143,7 @@ static rtx expand_builtin_fputs PARAMS ((tree, int));
|
|||
static tree stabilize_va_list PARAMS ((tree, int));
|
||||
static rtx expand_builtin_expect PARAMS ((tree, rtx));
|
||||
static tree fold_builtin_constant_p PARAMS ((tree));
|
||||
static tree fold_builtin_classify_type PARAMS ((tree));
|
||||
static tree build_function_call_expr PARAMS ((tree, tree));
|
||||
static int validate_arglist PARAMS ((tree, ...));
|
||||
|
||||
|
@ -1267,6 +1269,37 @@ expand_builtin_return (result)
|
|||
expand_null_return ();
|
||||
}
|
||||
|
||||
/* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
|
||||
static enum type_class
|
||||
type_to_class (type)
|
||||
tree type;
|
||||
{
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
case VOID_TYPE: return void_type_class;
|
||||
case INTEGER_TYPE: return integer_type_class;
|
||||
case CHAR_TYPE: return char_type_class;
|
||||
case ENUMERAL_TYPE: return enumeral_type_class;
|
||||
case BOOLEAN_TYPE: return boolean_type_class;
|
||||
case POINTER_TYPE: return pointer_type_class;
|
||||
case REFERENCE_TYPE: return reference_type_class;
|
||||
case OFFSET_TYPE: return offset_type_class;
|
||||
case REAL_TYPE: return real_type_class;
|
||||
case COMPLEX_TYPE: return complex_type_class;
|
||||
case FUNCTION_TYPE: return function_type_class;
|
||||
case METHOD_TYPE: return method_type_class;
|
||||
case RECORD_TYPE: return record_type_class;
|
||||
case UNION_TYPE:
|
||||
case QUAL_UNION_TYPE: return union_type_class;
|
||||
case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
|
||||
? string_type_class : array_type_class);
|
||||
case SET_TYPE: return set_type_class;
|
||||
case FILE_TYPE: return file_type_class;
|
||||
case LANG_TYPE: return lang_type_class;
|
||||
default: return no_type_class;
|
||||
}
|
||||
}
|
||||
|
||||
/* Expand a call to __builtin_classify_type with arguments found in
|
||||
ARGLIST. */
|
||||
static rtx
|
||||
|
@ -1274,51 +1307,7 @@ expand_builtin_classify_type (arglist)
|
|||
tree arglist;
|
||||
{
|
||||
if (arglist != 0)
|
||||
{
|
||||
tree type = TREE_TYPE (TREE_VALUE (arglist));
|
||||
enum tree_code code = TREE_CODE (type);
|
||||
if (code == VOID_TYPE)
|
||||
return GEN_INT (void_type_class);
|
||||
if (code == INTEGER_TYPE)
|
||||
return GEN_INT (integer_type_class);
|
||||
if (code == CHAR_TYPE)
|
||||
return GEN_INT (char_type_class);
|
||||
if (code == ENUMERAL_TYPE)
|
||||
return GEN_INT (enumeral_type_class);
|
||||
if (code == BOOLEAN_TYPE)
|
||||
return GEN_INT (boolean_type_class);
|
||||
if (code == POINTER_TYPE)
|
||||
return GEN_INT (pointer_type_class);
|
||||
if (code == REFERENCE_TYPE)
|
||||
return GEN_INT (reference_type_class);
|
||||
if (code == OFFSET_TYPE)
|
||||
return GEN_INT (offset_type_class);
|
||||
if (code == REAL_TYPE)
|
||||
return GEN_INT (real_type_class);
|
||||
if (code == COMPLEX_TYPE)
|
||||
return GEN_INT (complex_type_class);
|
||||
if (code == FUNCTION_TYPE)
|
||||
return GEN_INT (function_type_class);
|
||||
if (code == METHOD_TYPE)
|
||||
return GEN_INT (method_type_class);
|
||||
if (code == RECORD_TYPE)
|
||||
return GEN_INT (record_type_class);
|
||||
if (code == UNION_TYPE || code == QUAL_UNION_TYPE)
|
||||
return GEN_INT (union_type_class);
|
||||
if (code == ARRAY_TYPE)
|
||||
{
|
||||
if (TYPE_STRING_FLAG (type))
|
||||
return GEN_INT (string_type_class);
|
||||
else
|
||||
return GEN_INT (array_type_class);
|
||||
}
|
||||
if (code == SET_TYPE)
|
||||
return GEN_INT (set_type_class);
|
||||
if (code == FILE_TYPE)
|
||||
return GEN_INT (file_type_class);
|
||||
if (code == LANG_TYPE)
|
||||
return GEN_INT (lang_type_class);
|
||||
}
|
||||
return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
|
||||
return GEN_INT (no_type_class);
|
||||
}
|
||||
|
||||
|
@ -3806,6 +3795,17 @@ fold_builtin_constant_p (arglist)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Fold a call to __builtin_classify_type. */
|
||||
static tree
|
||||
fold_builtin_classify_type (arglist)
|
||||
tree arglist;
|
||||
{
|
||||
if (arglist == 0)
|
||||
return build_int_2 (no_type_class, 0);
|
||||
|
||||
return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
|
||||
}
|
||||
|
||||
/* Used by constant folding to eliminate some builtin calls early. EXP is
|
||||
the CALL_EXPR of a call to a builtin function. */
|
||||
|
||||
|
@ -3825,6 +3825,9 @@ fold_builtin (exp)
|
|||
case BUILT_IN_CONSTANT_P:
|
||||
return fold_builtin_constant_p (arglist);
|
||||
|
||||
case BUILT_IN_CLASSIFY_TYPE:
|
||||
return fold_builtin_classify_type (arglist);
|
||||
|
||||
case BUILT_IN_STRLEN:
|
||||
if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
|
||||
{
|
||||
|
|
139
gcc/expr.c
139
gcc/expr.c
|
@ -177,6 +177,7 @@ static rtx do_store_flag PARAMS ((tree, rtx, enum machine_mode, int));
|
|||
#ifdef PUSH_ROUNDING
|
||||
static void emit_single_push_insn PARAMS ((enum machine_mode, rtx, tree));
|
||||
#endif
|
||||
static void do_tablejump PARAMS ((rtx, enum machine_mode, rtx, rtx, rtx));
|
||||
|
||||
/* Record for each mode whether we can move a register directly to or
|
||||
from an object of that mode in memory. If we can't, we won't try
|
||||
|
@ -10717,11 +10718,112 @@ do_store_flag (exp, target, mode, only_cheap)
|
|||
return target;
|
||||
}
|
||||
|
||||
/* Generate a tablejump instruction (used for switch statements). */
|
||||
|
||||
#ifdef HAVE_tablejump
|
||||
/* Stubs in case we haven't got a casesi insn. */
|
||||
#ifndef HAVE_casesi
|
||||
# define HAVE_casesi 0
|
||||
# define gen_casesi(a, b, c, d, e) (0)
|
||||
# define CODE_FOR_casesi CODE_FOR_nothing
|
||||
#endif
|
||||
|
||||
/* INDEX is the value being switched on, with the lowest value
|
||||
/* If the machine does not have a case insn that compares the bounds,
|
||||
this means extra overhead for dispatch tables, which raises the
|
||||
threshold for using them. */
|
||||
#ifndef CASE_VALUES_THRESHOLD
|
||||
#define CASE_VALUES_THRESHOLD (HAVE_casesi ? 4 : 5)
|
||||
#endif /* CASE_VALUES_THRESHOLD */
|
||||
|
||||
unsigned int
|
||||
case_values_threshold ()
|
||||
{
|
||||
return CASE_VALUES_THRESHOLD;
|
||||
}
|
||||
|
||||
/* Attempt to generate a casesi instruction. Returns 1 if successful,
|
||||
0 otherwise (i.e. if there is no casesi instruction). */
|
||||
int
|
||||
try_casesi (index_type, index_expr, minval, range,
|
||||
table_label, default_label)
|
||||
tree index_type, index_expr, minval, range;
|
||||
rtx table_label ATTRIBUTE_UNUSED;
|
||||
rtx default_label;
|
||||
{
|
||||
enum machine_mode index_mode = SImode;
|
||||
int index_bits = GET_MODE_BITSIZE (index_mode);
|
||||
rtx op1, op2, index;
|
||||
enum machine_mode op_mode;
|
||||
|
||||
if (! HAVE_casesi)
|
||||
return 0;
|
||||
|
||||
/* Convert the index to SImode. */
|
||||
if (GET_MODE_BITSIZE (TYPE_MODE (index_type)) > GET_MODE_BITSIZE (index_mode))
|
||||
{
|
||||
enum machine_mode omode = TYPE_MODE (index_type);
|
||||
rtx rangertx = expand_expr (range, NULL_RTX, VOIDmode, 0);
|
||||
|
||||
/* We must handle the endpoints in the original mode. */
|
||||
index_expr = build (MINUS_EXPR, index_type,
|
||||
index_expr, minval);
|
||||
minval = integer_zero_node;
|
||||
index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
|
||||
emit_cmp_and_jump_insns (rangertx, index, LTU, NULL_RTX,
|
||||
omode, 1, 0, default_label);
|
||||
/* Now we can safely truncate. */
|
||||
index = convert_to_mode (index_mode, index, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TYPE_MODE (index_type) != index_mode)
|
||||
{
|
||||
index_expr = convert (type_for_size (index_bits, 0),
|
||||
index_expr);
|
||||
index_type = TREE_TYPE (index_expr);
|
||||
}
|
||||
|
||||
index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
|
||||
}
|
||||
emit_queue ();
|
||||
index = protect_from_queue (index, 0);
|
||||
do_pending_stack_adjust ();
|
||||
|
||||
op_mode = insn_data[(int) CODE_FOR_casesi].operand[0].mode;
|
||||
if (! (*insn_data[(int) CODE_FOR_casesi].operand[0].predicate)
|
||||
(index, op_mode))
|
||||
index = copy_to_mode_reg (op_mode, index);
|
||||
|
||||
op1 = expand_expr (minval, NULL_RTX, VOIDmode, 0);
|
||||
|
||||
op_mode = insn_data[(int) CODE_FOR_casesi].operand[1].mode;
|
||||
op1 = convert_modes (op_mode, TYPE_MODE (TREE_TYPE (minval)),
|
||||
op1, TREE_UNSIGNED (TREE_TYPE (minval)));
|
||||
if (! (*insn_data[(int) CODE_FOR_casesi].operand[1].predicate)
|
||||
(op1, op_mode))
|
||||
op1 = copy_to_mode_reg (op_mode, op1);
|
||||
|
||||
op2 = expand_expr (range, NULL_RTX, VOIDmode, 0);
|
||||
|
||||
op_mode = insn_data[(int) CODE_FOR_casesi].operand[2].mode;
|
||||
op2 = convert_modes (op_mode, TYPE_MODE (TREE_TYPE (range)),
|
||||
op2, TREE_UNSIGNED (TREE_TYPE (range)));
|
||||
if (! (*insn_data[(int) CODE_FOR_casesi].operand[2].predicate)
|
||||
(op2, op_mode))
|
||||
op2 = copy_to_mode_reg (op_mode, op2);
|
||||
|
||||
emit_jump_insn (gen_casesi (index, op1, op2,
|
||||
table_label, default_label));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Attempt to generate a tablejump instruction; same concept. */
|
||||
#ifndef HAVE_tablejump
|
||||
#define HAVE_tablejump 0
|
||||
#define gen_tablejump(x, y) (0)
|
||||
#endif
|
||||
|
||||
/* Subroutine of the next function.
|
||||
|
||||
INDEX is the value being switched on, with the lowest value
|
||||
in the table already subtracted.
|
||||
MODE is its expected mode (needed if INDEX is constant).
|
||||
RANGE is the length of the jump table.
|
||||
|
@ -10730,7 +10832,7 @@ do_store_flag (exp, target, mode, only_cheap)
|
|||
DEFAULT_LABEL is a CODE_LABEL rtx to jump to if the
|
||||
index value is out of range. */
|
||||
|
||||
void
|
||||
static void
|
||||
do_tablejump (index, mode, range, table_label, default_label)
|
||||
rtx index, range, table_label, default_label;
|
||||
enum machine_mode mode;
|
||||
|
@ -10792,4 +10894,31 @@ do_tablejump (index, mode, range, table_label, default_label)
|
|||
emit_barrier ();
|
||||
}
|
||||
|
||||
#endif /* HAVE_tablejump */
|
||||
int
|
||||
try_tablejump (index_type, index_expr, minval, range,
|
||||
table_label, default_label)
|
||||
tree index_type, index_expr, minval, range;
|
||||
rtx table_label, default_label;
|
||||
{
|
||||
rtx index;
|
||||
|
||||
if (! HAVE_tablejump)
|
||||
return 0;
|
||||
|
||||
index_expr = fold (build (MINUS_EXPR, index_type,
|
||||
convert (index_type, index_expr),
|
||||
convert (index_type, minval)));
|
||||
index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
|
||||
emit_queue ();
|
||||
index = protect_from_queue (index, 0);
|
||||
do_pending_stack_adjust ();
|
||||
|
||||
do_tablejump (index, TYPE_MODE (index_type),
|
||||
convert_modes (TYPE_MODE (index_type),
|
||||
TYPE_MODE (TREE_TYPE (range)),
|
||||
expand_expr (range, NULL_RTX,
|
||||
VOIDmode, 0),
|
||||
TREE_UNSIGNED (TREE_TYPE (range))),
|
||||
table_label, default_label);
|
||||
return 1;
|
||||
}
|
||||
|
|
10
gcc/expr.h
10
gcc/expr.h
|
@ -540,8 +540,14 @@ extern void do_compare_rtx_and_jump PARAMS ((rtx, rtx, enum rtx_code, int,
|
|||
enum machine_mode, rtx,
|
||||
unsigned int, rtx, rtx));
|
||||
|
||||
/* Generate a tablejump instruction (used for switch statements). */
|
||||
extern void do_tablejump PARAMS ((rtx, enum machine_mode, rtx, rtx, rtx));
|
||||
/* Two different ways of generating switch statements. */
|
||||
extern int try_casesi PARAMS ((tree, tree, tree, tree, rtx, rtx));
|
||||
extern int try_tablejump PARAMS ((tree, tree, tree, tree, rtx, rtx));
|
||||
|
||||
/* Smallest number of adjacent cases before we use a jump table.
|
||||
XXX Should be a target hook. */
|
||||
extern unsigned int case_values_threshold PARAMS ((void));
|
||||
|
||||
|
||||
#ifdef TREE_CODE
|
||||
/* rtl.h and tree.h were included. */
|
||||
|
|
156
gcc/stmt.c
156
gcc/stmt.c
|
@ -43,7 +43,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "except.h"
|
||||
#include "function.h"
|
||||
#include "insn-config.h"
|
||||
#include "insn-codes.h"
|
||||
#include "expr.h"
|
||||
#include "libfuncs.h"
|
||||
#include "hard-reg-set.h"
|
||||
|
@ -5021,10 +5020,6 @@ check_for_full_enumeration_handling (type)
|
|||
{
|
||||
register struct case_node *n;
|
||||
register tree chain;
|
||||
#if 0 /* variable used by 'if 0'ed code below. */
|
||||
register struct case_node **l;
|
||||
int all_values = 1;
|
||||
#endif
|
||||
|
||||
/* True iff the selector type is a numbered set mode. */
|
||||
int sparseness = 0;
|
||||
|
@ -5122,28 +5117,6 @@ check_for_full_enumeration_handling (type)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* ??? This optimization is disabled because it causes valid programs to
|
||||
fail. ANSI C does not guarantee that an expression with enum type
|
||||
will have a value that is the same as one of the enumeration literals. */
|
||||
|
||||
/* If all values were found as case labels, make one of them the default
|
||||
label. Thus, this switch will never fall through. We arbitrarily pick
|
||||
the last one to make the default since this is likely the most
|
||||
efficient choice. */
|
||||
|
||||
if (all_values)
|
||||
{
|
||||
for (l = &case_stack->data.case_stmt.case_list;
|
||||
(*l)->right != 0;
|
||||
l = &(*l)->right)
|
||||
;
|
||||
|
||||
case_stack->data.case_stmt.default_label = (*l)->code_label;
|
||||
*l = 0;
|
||||
}
|
||||
#endif /* 0 */
|
||||
}
|
||||
|
||||
/* Free CN, and its children. */
|
||||
|
@ -5161,6 +5134,7 @@ free_case_nodes (cn)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* Terminate a case (Pascal) or switch (C) statement
|
||||
in which ORIG_INDEX is the expression to be tested.
|
||||
Generate the code to test it and jump to the right place. */
|
||||
|
@ -5289,18 +5263,7 @@ expand_end_case (orig_index)
|
|||
If the switch-index is a constant, do it this way
|
||||
because we can optimize it. */
|
||||
|
||||
#ifndef CASE_VALUES_THRESHOLD
|
||||
#ifdef HAVE_casesi
|
||||
#define CASE_VALUES_THRESHOLD (HAVE_casesi ? 4 : 5)
|
||||
#else
|
||||
/* If machine does not have a case insn that compares the
|
||||
bounds, this means extra overhead for dispatch tables
|
||||
which raises the threshold for using them. */
|
||||
#define CASE_VALUES_THRESHOLD 5
|
||||
#endif /* HAVE_casesi */
|
||||
#endif /* CASE_VALUES_THRESHOLD */
|
||||
|
||||
else if (count < CASE_VALUES_THRESHOLD
|
||||
else if (count < case_values_threshold ()
|
||||
|| compare_tree_int (range, 10 * count) > 0
|
||||
/* RANGE may be signed, and really large ranges will show up
|
||||
as negative numbers. */
|
||||
|
@ -5309,12 +5272,6 @@ expand_end_case (orig_index)
|
|||
|| flag_pic
|
||||
#endif
|
||||
|| TREE_CODE (index_expr) == INTEGER_CST
|
||||
/* These will reduce to a constant. */
|
||||
|| (TREE_CODE (index_expr) == CALL_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (index_expr, 0)) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (TREE_OPERAND (index_expr, 0), 0)) == FUNCTION_DECL
|
||||
&& DECL_BUILT_IN_CLASS (TREE_OPERAND (TREE_OPERAND (index_expr, 0), 0)) == BUILT_IN_NORMAL
|
||||
&& DECL_FUNCTION_CODE (TREE_OPERAND (TREE_OPERAND (index_expr, 0), 0)) == BUILT_IN_CLASSIFY_TYPE)
|
||||
|| (TREE_CODE (index_expr) == COMPOUND_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (index_expr, 1)) == INTEGER_CST))
|
||||
{
|
||||
|
@ -5399,99 +5356,14 @@ expand_end_case (orig_index)
|
|||
}
|
||||
else
|
||||
{
|
||||
int win = 0;
|
||||
#ifdef HAVE_casesi
|
||||
if (HAVE_casesi)
|
||||
{
|
||||
enum machine_mode index_mode = SImode;
|
||||
int index_bits = GET_MODE_BITSIZE (index_mode);
|
||||
rtx op1, op2;
|
||||
enum machine_mode op_mode;
|
||||
|
||||
/* Convert the index to SImode. */
|
||||
if (GET_MODE_BITSIZE (TYPE_MODE (index_type))
|
||||
> GET_MODE_BITSIZE (index_mode))
|
||||
{
|
||||
enum machine_mode omode = TYPE_MODE (index_type);
|
||||
rtx rangertx = expand_expr (range, NULL_RTX, VOIDmode, 0);
|
||||
|
||||
/* We must handle the endpoints in the original mode. */
|
||||
index_expr = build (MINUS_EXPR, index_type,
|
||||
index_expr, minval);
|
||||
minval = integer_zero_node;
|
||||
index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
|
||||
emit_cmp_and_jump_insns (rangertx, index, LTU, NULL_RTX,
|
||||
omode, 1, 0, default_label);
|
||||
/* Now we can safely truncate. */
|
||||
index = convert_to_mode (index_mode, index, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TYPE_MODE (index_type) != index_mode)
|
||||
{
|
||||
index_expr = convert (type_for_size (index_bits, 0),
|
||||
index_expr);
|
||||
index_type = TREE_TYPE (index_expr);
|
||||
}
|
||||
|
||||
index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
|
||||
}
|
||||
emit_queue ();
|
||||
index = protect_from_queue (index, 0);
|
||||
do_pending_stack_adjust ();
|
||||
|
||||
op_mode = insn_data[(int) CODE_FOR_casesi].operand[0].mode;
|
||||
if (! (*insn_data[(int) CODE_FOR_casesi].operand[0].predicate)
|
||||
(index, op_mode))
|
||||
index = copy_to_mode_reg (op_mode, index);
|
||||
|
||||
op1 = expand_expr (minval, NULL_RTX, VOIDmode, 0);
|
||||
|
||||
op_mode = insn_data[(int) CODE_FOR_casesi].operand[1].mode;
|
||||
op1 = convert_modes (op_mode, TYPE_MODE (TREE_TYPE (minval)),
|
||||
op1, TREE_UNSIGNED (TREE_TYPE (minval)));
|
||||
if (! (*insn_data[(int) CODE_FOR_casesi].operand[1].predicate)
|
||||
(op1, op_mode))
|
||||
op1 = copy_to_mode_reg (op_mode, op1);
|
||||
|
||||
op2 = expand_expr (range, NULL_RTX, VOIDmode, 0);
|
||||
|
||||
op_mode = insn_data[(int) CODE_FOR_casesi].operand[2].mode;
|
||||
op2 = convert_modes (op_mode, TYPE_MODE (TREE_TYPE (range)),
|
||||
op2, TREE_UNSIGNED (TREE_TYPE (range)));
|
||||
if (! (*insn_data[(int) CODE_FOR_casesi].operand[2].predicate)
|
||||
(op2, op_mode))
|
||||
op2 = copy_to_mode_reg (op_mode, op2);
|
||||
|
||||
emit_jump_insn (gen_casesi (index, op1, op2,
|
||||
table_label, default_label));
|
||||
win = 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_tablejump
|
||||
if (! win && HAVE_tablejump)
|
||||
if (! try_casesi (index_type, index_expr, minval, range,
|
||||
table_label, default_label))
|
||||
{
|
||||
index_type = thiscase->data.case_stmt.nominal_type;
|
||||
index_expr = fold (build (MINUS_EXPR, index_type,
|
||||
convert (index_type, index_expr),
|
||||
convert (index_type, minval)));
|
||||
index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
|
||||
emit_queue ();
|
||||
index = protect_from_queue (index, 0);
|
||||
do_pending_stack_adjust ();
|
||||
|
||||
do_tablejump (index, TYPE_MODE (index_type),
|
||||
convert_modes (TYPE_MODE (index_type),
|
||||
TYPE_MODE (TREE_TYPE (range)),
|
||||
expand_expr (range, NULL_RTX,
|
||||
VOIDmode, 0),
|
||||
TREE_UNSIGNED (TREE_TYPE (range))),
|
||||
table_label, default_label);
|
||||
win = 1;
|
||||
}
|
||||
#endif
|
||||
if (! win)
|
||||
if (! try_tablejump (index_type, index_expr, minval, range,
|
||||
table_label, default_label))
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Get table of labels to jump to, in order of case index. */
|
||||
|
||||
|
@ -6133,20 +6005,6 @@ emit_case_nodes (index, node, default_label, index_type)
|
|||
else if (node->right == 0 && node->left != 0)
|
||||
{
|
||||
/* Just one subtree, on the left. */
|
||||
|
||||
#if 0 /* The following code and comment were formerly part
|
||||
of the condition here, but they didn't work
|
||||
and I don't understand what the idea was. -- rms. */
|
||||
/* If our "most probable entry" is less probable
|
||||
than the default label, emit a jump to
|
||||
the default label using condition codes
|
||||
already lying around. With no right branch,
|
||||
a branch-greater-than will get us to the default
|
||||
label correctly. */
|
||||
if (use_cost_table
|
||||
&& COST_TABLE (TREE_INT_CST_LOW (node->high)) < 12)
|
||||
;
|
||||
#endif /* 0 */
|
||||
if (node->left->left || node->left->right
|
||||
|| !tree_int_cst_equal (node->left->low, node->left->high))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue