/* 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 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
#include "predict.h"
#include "optabs.h"
#include "target.h"
-
-/* Assume that case vectors are not pc-relative. */
-#ifndef CASE_VECTOR_PC_RELATIVE
-#define CASE_VECTOR_PC_RELATIVE 0
-#endif
+#include "regs.h"
\f
/* Functions and data structures for expanding case statements. */
conditional branch points. */
rtx last_unconditional_cleanup;
} GTY ((tag ("BLOCK_NESTING"))) block;
- /* For switch (C) or case (Pascal) statements,
- and also for dummies (see `expand_start_case_dummy'). */
+ /* For switch (C) or case (Pascal) statements. */
struct nesting_case
{
/* The insn after which the case dispatch should finally
{
cfun->computed_goto_common_reg = copy_to_mode_reg (Pmode, x);
cfun->computed_goto_common_label = gen_label_rtx ();
- emit_label (cfun->computed_goto_common_label);
do_pending_stack_adjust ();
+ emit_label (cfun->computed_goto_common_label);
emit_indirect_jump (cfun->computed_goto_common_reg);
current_function_has_computed_jump = 1;
for (regno = REGNO (reg);
regno < (REGNO (reg)
- + HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)));
+ + hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]);
regno++)
if (TEST_HARD_REG_BIT (clobbered_regs, regno))
{
for (t = inputs; t ; t = TREE_CHAIN (t), i++)
constraints[i] = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
-#ifdef MD_ASM_CLOBBERS
/* Sometimes we wish to automatically clobber registers across an asm.
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. */
- MD_ASM_CLOBBERS (clobbers);
-#endif
+ clobbers = targetm.md_asm_clobbers (clobbers);
/* Count the number of meaningful clobbered registers, ignoring what
we would ignore later. */
start_cleanup_deferral ();
}
-
-/* Start a "dummy case statement" within which case labels are invalid
- and are not connected to any larger real case statement.
- This can be used if you don't want to let a case statement jump
- into the middle of certain kinds of constructs. */
-
-void
-expand_start_case_dummy (void)
-{
- struct nesting *thiscase = ALLOC_NESTING ();
-
- /* Make an entry on case_stack for the dummy. */
-
- thiscase->desc = CASE_NESTING;
- thiscase->next = case_stack;
- thiscase->all = nesting_stack;
- thiscase->depth = ++nesting_depth;
- thiscase->exit_label = 0;
- thiscase->data.case_stmt.case_list = 0;
- thiscase->data.case_stmt.start = 0;
- thiscase->data.case_stmt.nominal_type = 0;
- thiscase->data.case_stmt.default_label = 0;
- case_stack = thiscase;
- nesting_stack = thiscase;
- start_cleanup_deferral ();
-}
\f
static void
check_seenlabel (void)
emit_jump (default_label);
}
+#ifndef HAVE_casesi
+#define HAVE_casesi 0
+#endif
+
+#ifndef HAVE_tablejump
+#define HAVE_tablejump 0
+#endif
+
/* Terminate a case (Pascal) or switch (C) statement
in which ORIG_INDEX is the expression to be tested.
If ORIG_TYPE is not NULL, it is the original ORIG_INDEX
#ifndef ASM_OUTPUT_ADDR_DIFF_ELT
|| flag_pic
#endif
- || TREE_CONSTANT (index_expr))
+ || TREE_CONSTANT (index_expr)
+ /* If neither casesi or tablejump is available, we can
+ only go this way. */
+ || (!HAVE_casesi && !HAVE_tablejump))
{
index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);