/* Subroutines used by or related to instruction recognition.
Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of GCC.
#include "expr.h"
#include "function.h"
#include "flags.h"
-#include "real.h"
#include "toplev.h"
#include "basic-block.h"
#include "output.h"
else
return false;
}
-
+
/* This subroutine of apply_change_group verifies whether the changes to INSN
were valid; i.e. whether INSN can still be recognized. */
rtx. */
static void
-simplify_while_replacing (rtx *loc, rtx to, rtx object,
+simplify_while_replacing (rtx *loc, rtx to, rtx object,
enum machine_mode op0_mode)
{
rtx x = *loc;
validate_change passing OBJECT. */
static void
-validate_replace_rtx_1 (rtx *loc, rtx from, rtx to, rtx object,
+validate_replace_rtx_1 (rtx *loc, rtx from, rtx to, rtx object,
bool simplify)
{
int i, j;
from, to, object, simplify);
}
else
- validate_replace_rtx_1 (&XVECEXP (x, 0, j), from, to, object,
+ validate_replace_rtx_1 (&XVECEXP (x, 0, j), from, to, object,
simplify);
}
}
validate_replace_rtx_1 (&XEXP (x, i), from, to, object, simplify);
else if (fmt[i] == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object,
+ validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object,
simplify);
}
}
/* Try replacing every occurrence of FROM in WHERE with TO. Assume that WHERE
- is a part of INSN. After all changes have been made, validate by seeing if
- INSN is still valid.
- validate_replace_rtx (from, to, insn) is equivalent to
+ is a part of INSN. After all changes have been made, validate by seeing if
+ INSN is still valid.
+ validate_replace_rtx (from, to, insn) is equivalent to
validate_replace_rtx_part (from, to, &PATTERN (insn), insn). */
int
}
/* Same as above, but do not simplify rtx afterwards. */
-int
-validate_replace_rtx_part_nosimplify (rtx from, rtx to, rtx *where,
+int
+validate_replace_rtx_part_nosimplify (rtx from, rtx to, rtx *where,
rtx insn)
{
validate_replace_rtx_1 (where, from, to, insn, false);
}
-/* Try replacing every occurrence of FROM in INSN with TO. */
+/* Try replacing every occurrence of FROM in INSN with TO. This also
+ will replace in REG_EQUAL and REG_EQUIV notes. */
void
validate_replace_rtx_group (rtx from, rtx to, rtx insn)
{
+ rtx note;
validate_replace_rtx_1 (&PATTERN (insn), from, to, insn, true);
+ for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ if (REG_NOTE_KIND (note) == REG_EQUAL
+ || REG_NOTE_KIND (note) == REG_EQUIV)
+ validate_replace_rtx_1 (&XEXP (note, 0), from, to, insn, true);
}
/* Function called by note_uses to replace used subexpressions. */
if (GET_CODE (XVECEXP (body, 0, 0)) == SET)
{
/* Multiple output operands, or 1 output plus some clobbers:
- body is
+ body is
[(set OUTPUT (asm_operands ...))... (clobber (reg ...))...]. */
/* Count backwards through CLOBBERs to determine number of SETs. */
for (i = XVECLEN (body, 0); i > 0; i--)
const char **constraints, enum machine_mode *modes,
location_t *loc)
{
- int noperands, nbase = 0, n, i;
+ int nbase = 0, n, i;
rtx asmop;
switch (GET_CODE (body))
gcc_unreachable ();
}
- noperands = (ASM_OPERANDS_INPUT_LENGTH (asmop)
- + ASM_OPERANDS_LABEL_LENGTH (asmop) + nbase);
-
n = ASM_OPERANDS_INPUT_LENGTH (asmop);
for (i = 0; i < n; i++)
{
Autoincrement addressing is a typical example of mode-dependence
because the amount of the increment depends on the mode. */
-int
+bool
mode_dependent_address_p (rtx addr)
{
/* Auto-increment addressing with anything other than post_modify
|| GET_CODE (addr) == POST_INC
|| GET_CODE (addr) == PRE_DEC
|| GET_CODE (addr) == POST_DEC)
- return 1;
+ return true;
- GO_IF_MODE_DEPENDENT_ADDRESS (addr, win);
- return 0;
- /* Label `win' might (not) be used via GO_IF_MODE_DEPENDENT_ADDRESS. */
- win: ATTRIBUTE_UNUSED_LABEL
- return 1;
+ return targetm.mode_dependent_address_p (addr);
}
\f
/* Like extract_insn, but save insn extracted and don't extract again, when
recog_data.operand_loc,
recog_data.constraints,
recog_data.operand_mode, NULL);
+ memset (recog_data.is_operator, 0, sizeof recog_data.is_operator);
if (noperands > 0)
{
const char *p = recog_data.constraints[0];
for (i = 0; i < noperands; i++)
{
recog_data.constraints[i] = insn_data[icode].operand[i].constraint;
+ recog_data.is_operator[i] = insn_data[icode].operand[i].is_operator;
recog_data.operand_mode[i] = insn_data[icode].operand[i].mode;
/* VOIDmode match_operands gets mode from their real operand. */
if (recog_data.operand_mode[i] == VOIDmode)
do_cleanup_cfg |= purge_dead_edges (bb);
}
-#ifdef HAVE_conditional_execution
- for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
- peep2_insn_data[i].insn = NULL_RTX;
- peep2_insn_data[peep2_current].insn = PEEP2_EOB;
- peep2_current_count = 0;
-#else
- /* Back up lifetime information past the end of the
- newly created sequence. */
- if (++i >= MAX_INSNS_PER_PEEP2 + 1)
- i = 0;
- bitmap_copy (live, peep2_insn_data[i].live_before);
-
- /* Update life information for the new sequence. */
- x = attempt;
- do
+ if (targetm.have_conditional_execution ())
{
- if (INSN_P (x))
+ for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
+ peep2_insn_data[i].insn = NULL_RTX;
+ peep2_insn_data[peep2_current].insn = PEEP2_EOB;
+ peep2_current_count = 0;
+ }
+ else
+ {
+ /* Back up lifetime information past the end of the
+ newly created sequence. */
+ if (++i >= MAX_INSNS_PER_PEEP2 + 1)
+ i = 0;
+ bitmap_copy (live, peep2_insn_data[i].live_before);
+
+ /* Update life information for the new sequence. */
+ x = attempt;
+ do
{
- if (--i < 0)
- i = MAX_INSNS_PER_PEEP2;
- if (peep2_current_count < MAX_INSNS_PER_PEEP2
- && peep2_insn_data[i].insn == NULL_RTX)
- peep2_current_count++;
- peep2_insn_data[i].insn = x;
- df_insn_rescan (x);
- df_simulate_one_insn_backwards (bb, x, live);
- bitmap_copy (peep2_insn_data[i].live_before, live);
+ if (INSN_P (x))
+ {
+ if (--i < 0)
+ i = MAX_INSNS_PER_PEEP2;
+ if (peep2_current_count < MAX_INSNS_PER_PEEP2
+ && peep2_insn_data[i].insn == NULL_RTX)
+ peep2_current_count++;
+ peep2_insn_data[i].insn = x;
+ df_insn_rescan (x);
+ df_simulate_one_insn_backwards (bb, x, live);
+ bitmap_copy (peep2_insn_data[i].live_before,
+ live);
+ }
+ x = PREV_INSN (x);
}
- x = PREV_INSN (x);
- }
- while (x != prev);
+ while (x != prev);
- peep2_current = i;
-#endif
+ peep2_current = i;
+ }
/* If we generated a jump instruction, it won't have
JUMP_LABEL set. Recompute after we're done. */
return 1;
#else
return 0;
-#endif
+#endif
}
struct rtl_opt_pass pass_split_for_shorten_branches =