/* Search an insn for pseudo regs that must be in hard regs and are not.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
- Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
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, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* This file contains subroutines used only from the file reload1.c.
It knows how to scan one insn for operands and values
#include "toplev.h"
#include "params.h"
#include "target.h"
+#include "df.h"
/* True if X is a constant that can be forced into the constant pool. */
#define CONST_POOL_OK_P(X) \
}
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (HARD_REGNO_MODE_OK (i, mode)
- && TEST_HARD_REG_BIT (reg_class_contents[(int) class], i))
- {
- int nregs = hard_regno_nregs[i][mode];
-
- int j;
- for (j = 1; j < nregs; j++)
- if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class], i + j))
- break;
- if (j == nregs)
- break;
- }
+ && in_hard_reg_set_p (reg_class_contents[(int) class], mode, i))
+ break;
if (i == FIRST_PSEUDO_REGISTER)
{
error_for_asm (this_insn, "impossible register constraint "
/* Check that we don't use a hardreg for an uninitialized
pseudo. See also find_dummy_reload(). */
&& (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
- || ! bitmap_bit_p (ENTRY_BLOCK_PTR->il.rtl->global_live_at_end,
+ || ! bitmap_bit_p (DF_RA_LIVE_OUT (ENTRY_BLOCK_PTR),
ORIGINAL_REGNO (XEXP (note, 0))))
&& ! refers_to_regno_for_reload_p (regno,
- (regno
- + hard_regno_nregs[regno]
- [rel_mode]),
+ end_hard_regno (rel_mode,
+ regno),
PATTERN (this_insn), inloc)
/* If this is also an output reload, IN cannot be used as
the reload register if it is set in this insn unless IN
is also OUT. */
&& (out == 0 || in == out
|| ! hard_reg_set_here_p (regno,
- (regno
- + hard_regno_nregs[regno]
- [rel_mode]),
+ end_hard_regno (rel_mode, regno),
PATTERN (this_insn)))
/* ??? Why is this code so different from the previous?
Is there any simple coherent way to describe the two together?
if (offs == nregs
&& (! (refers_to_regno_for_reload_p
- (regno, (regno + hard_regno_nregs[regno][inmode]),
- in, (rtx *)0))
+ (regno, end_hard_regno (inmode, regno), in, (rtx *) 0))
|| can_reload_into (in, regno, inmode)))
{
rld[i].reg_rtx = gen_rtx_REG (rel_mode, regno);
/* Check that we don't use a hardreg for an uninitialized
pseudo. See also find_dummy_reload(). */
&& (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
- || ! bitmap_bit_p (ENTRY_BLOCK_PTR->il.rtl->global_live_at_end,
+ || ! bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR),
ORIGINAL_REGNO (XEXP (note, 0)))))
{
rld[output_reload].reg_rtx
as they would clobber the other live pseudo using the same.
See also PR20973. */
&& (ORIGINAL_REGNO (in) < FIRST_PSEUDO_REGISTER
- || ! bitmap_bit_p (ENTRY_BLOCK_PTR->il.rtl->global_live_at_end,
+ || ! bitmap_bit_p (DF_RA_LIVE_OUT (ENTRY_BLOCK_PTR),
ORIGINAL_REGNO (in))))
{
unsigned int regno = REGNO (in) + in_offset;
/* See if this reg overlaps range under consideration. */
if (r < end_regno
- && r + hard_regno_nregs[r][GET_MODE (op0)] > beg_regno)
+ && end_hard_regno (GET_MODE (op0), r) > beg_regno)
return 1;
}
}
{
case CONST_INT:
case CONST_DOUBLE:
+ case CONST_FIXED:
return 0;
case LABEL_REF:
}
else
/* A hard reg. */
- val.end = val.start + hard_regno_nregs[val.start][GET_MODE (x)];
+ val.end = end_hard_regno (GET_MODE (x), val.start);
break;
case SUBREG:
&& MEM_P (op)
&& REG_P (reg)
&& (GET_MODE_SIZE (GET_MODE (reg))
- >= GET_MODE_SIZE (GET_MODE (op))))
+ >= GET_MODE_SIZE (GET_MODE (op)))
+ && reg_equiv_constant[REGNO (reg)] == 0)
set_unique_reg_note (emit_insn_before (gen_rtx_USE (VOIDmode, reg),
insn),
REG_EQUAL, reg_equiv_memory_loc[REGNO (reg)]);
*recog_data.operand_loc[i] = substitution;
- /* If we're replacing an operand with a LABEL_REF, we need
- to make sure that there's a REG_LABEL note attached to
+ /* If we're replacing an operand with a LABEL_REF, we need to
+ make sure that there's a REG_LABEL_OPERAND note attached to
this instruction. */
- if (!JUMP_P (insn)
- && GET_CODE (substitution) == LABEL_REF
- && !find_reg_note (insn, REG_LABEL, XEXP (substitution, 0)))
- REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL,
+ if (GET_CODE (substitution) == LABEL_REF
+ && !find_reg_note (insn, REG_LABEL_OPERAND,
+ XEXP (substitution, 0))
+ /* For a JUMP_P, if it was a branch target it must have
+ already been recorded as such. */
+ && (!JUMP_P (insn)
+ || !label_is_jump_target_p (XEXP (substitution, 0),
+ insn)))
+ REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL_OPERAND,
XEXP (substitution, 0),
REG_NOTES (insn));
}
int regno = REGNO (SUBREG_REG (x));
rtx tem;
- if (subreg_lowpart_p (x)
- && regno >= FIRST_PSEUDO_REGISTER
- && reg_renumber[regno] < 0
- && reg_equiv_constant[regno] != 0
- && (tem = gen_lowpart_common (GET_MODE (x),
- reg_equiv_constant[regno])) != 0)
- return tem;
-
if (regno >= FIRST_PSEUDO_REGISTER
&& reg_renumber[regno] < 0
&& reg_equiv_constant[regno] != 0)
simplify_gen_subreg (GET_MODE (x), reg_equiv_constant[regno],
GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
gcc_assert (tem);
+ if (CONSTANT_P (tem) && !LEGITIMATE_CONSTANT_P (tem))
+ {
+ tem = force_const_mem (GET_MODE (x), tem);
+ i = find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
+ &XEXP (tem, 0), opnum, type,
+ ind_levels, insn);
+ if (address_reloaded)
+ *address_reloaded = i;
+ }
return tem;
}
case CONST_INT:
case CONST:
case CONST_DOUBLE:
+ case CONST_FIXED:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
else if (code0 == REG && code1 == REG)
{
- if (REGNO_OK_FOR_INDEX_P (REGNO (op0))
- && regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
+ if (REGNO_OK_FOR_INDEX_P (REGNO (op1))
+ && regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
return 0;
- else if (REGNO_OK_FOR_INDEX_P (REGNO (op1))
- && regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
+ else if (REGNO_OK_FOR_INDEX_P (REGNO (op0))
+ && regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
return 0;
- else if (regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
- find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
- &XEXP (x, 0), opnum, type, ind_levels,
- insn);
else if (regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
&XEXP (x, 1), opnum, type, ind_levels,
find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG,
&XEXP (x, 0), opnum, type, ind_levels,
insn);
+ else if (regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
+ find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
+ &XEXP (x, 0), opnum, type, ind_levels,
+ insn);
else if (REGNO_OK_FOR_INDEX_P (REGNO (op0)))
find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG,
&XEXP (x, 1), opnum, type, ind_levels,
insn);
else
{
- find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
+ find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG,
&XEXP (x, 0), opnum, type, ind_levels,
insn);
- find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG,
+ find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
&XEXP (x, 1), opnum, type, ind_levels,
insn);
}
rtx equiv = (MEM_P (XEXP (x, 0))
? XEXP (x, 0)
: reg_equiv_mem[regno]);
- int icode = (int) add_optab->handlers[(int) Pmode].insn_code;
+ int icode = (int) optab_handler (add_optab, Pmode)->insn_code;
if (insn && NONJUMP_INSN_P (insn) && equiv
&& memory_operand (equiv, GET_MODE (equiv))
#ifdef HAVE_cc0
&& (! LEGITIMATE_CONSTANT_P (x)
|| PREFERRED_RELOAD_CLASS (x, class) == NO_REGS))
{
- rtx tem;
-
- tem = x = force_const_mem (mode, x);
- find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
+ x = force_const_mem (mode, x);
+ find_reloads_address (mode, &x, XEXP (x, 0), &XEXP (x, 0),
opnum, type, ind_levels, 0);
}
tem = force_const_mem (GET_MODE (x), XEXP (x, 1));
x = gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), tem);
- find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
+ find_reloads_address (mode, &XEXP (x, 1), XEXP (tem, 0), &XEXP (tem, 0),
opnum, type, ind_levels, 0);
}
}
#endif /* DEBUG_RELOAD */
- /* If we're replacing a LABEL_REF with a register, add a
- REG_LABEL note to indicate to flow which label this
+ /* If we're replacing a LABEL_REF with a register, there must
+ already be an indication (to e.g. flow) which label this
register refers to. */
- if (GET_CODE (*r->where) == LABEL_REF
- && JUMP_P (insn))
- {
- REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL,
- XEXP (*r->where, 0),
- REG_NOTES (insn));
- JUMP_LABEL (insn) = XEXP (*r->where, 0);
- }
+ gcc_assert (GET_CODE (*r->where) != LABEL_REF
+ || !JUMP_P (insn)
+ || find_reg_note (insn,
+ REG_LABEL_OPERAND,
+ XEXP (*r->where, 0))
+ || label_is_jump_target_p (XEXP (*r->where, 0), insn));
/* Encapsulate RELOADREG so its machine mode matches what
used to be there. Note that gen_lowpart_common will
return 0;
}
- endregno = regno + hard_regno_nregs[regno][GET_MODE (x)];
+ endregno = END_HARD_REGNO (x);
return refers_to_regno_for_reload_p (regno, endregno, in, (rtx*) 0);
}
}
else if ((unsigned) valueno >= FIRST_PSEUDO_REGISTER)
continue;
- else
- {
- int i;
-
- for (i = hard_regno_nregs[valueno][mode] - 1; i >= 0; i--)
- if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
- valueno + i))
- break;
- if (i >= 0)
- continue;
- }
+ else if (!in_hard_reg_set_p (reg_class_contents[(int) class],
+ mode, valueno))
+ continue;
value = valtry;
where = p;
break;
and is also a register that appears in the address of GOAL. */
if (goal_mem && value == SET_DEST (single_set (where))
- && refers_to_regno_for_reload_p (valueno,
- (valueno
- + hard_regno_nregs[valueno][mode]),
+ && refers_to_regno_for_reload_p (valueno, end_hard_regno (mode, valueno),
goal, (rtx*) 0))
return 0;