mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-11 14:11:31 +08:00
Makefile.in (rtlanal.o): Depend on tree.h.
gcc/ * Makefile.in (rtlanal.o): Depend on tree.h. * rtl.h (offset_within_section_p, split_const): Declare. * rtlanal.c: Include tree.h. (offset_within_block_p): New function, taken from mips_offset_within_object_p. (split_const): New function, taken from mips_split_const. * config/m68k/m68k-protos.h (m68k_illegitimate_symbolic_constant_p): Declare. * config/m68k/m68k.h (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P): Define. (CONSTANT_ADDRESS_P): Only accept legitimate constants. (LEGITIMATE_CONSTANT_P): Check m68k_illegitimate_symbolic_constant_p. * config/m68k/m68k.c (TARGET_CANNOT_FORCE_CONST_MEM): Define. (m68k_illegitimate_symbolic_constant_p): New function. * config/m68k/m68k.md (movsi): Remove misleading predicates. If M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P and the source is a symbolic constant that might be outside the symbol's section, move the symbol first and then add the offset. * config/m68k/uclinux.h (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P): Override. * config/mips/mips.c (mips_split_const): Delete. (mips_offset_within_object_p): Delete. (mips_symbolic_constant_p): Use offset_within_section_p and split_const instead of mips_offset_within_object_p and mips_split_const. (mips_cannot_force_const_mem, mips_const_insns, mips_unspec_address) (mips_legitimize_const_move, print_operand_reloc) (mips_dangerous_for_la25_p): Use split_const instead of mips_split_const. From-SVN: r122428
This commit is contained in:
parent
96e7e5ad47
commit
7ffb5e7879
@ -1,3 +1,34 @@
|
||||
2007-03-01 Richard Sandiford <richard@codesourcery.com>
|
||||
|
||||
* Makefile.in (rtlanal.o): Depend on tree.h.
|
||||
* rtl.h (offset_within_section_p, split_const): Declare.
|
||||
* rtlanal.c: Include tree.h.
|
||||
(offset_within_block_p): New function, taken from
|
||||
mips_offset_within_object_p.
|
||||
(split_const): New function, taken from mips_split_const.
|
||||
* config/m68k/m68k-protos.h (m68k_illegitimate_symbolic_constant_p):
|
||||
Declare.
|
||||
* config/m68k/m68k.h (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P): Define.
|
||||
(CONSTANT_ADDRESS_P): Only accept legitimate constants.
|
||||
(LEGITIMATE_CONSTANT_P): Check m68k_illegitimate_symbolic_constant_p.
|
||||
* config/m68k/m68k.c (TARGET_CANNOT_FORCE_CONST_MEM): Define.
|
||||
(m68k_illegitimate_symbolic_constant_p): New function.
|
||||
* config/m68k/m68k.md (movsi): Remove misleading predicates.
|
||||
If M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P and the source is a
|
||||
symbolic constant that might be outside the symbol's section,
|
||||
move the symbol first and then add the offset.
|
||||
* config/m68k/uclinux.h (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P):
|
||||
Override.
|
||||
* config/mips/mips.c (mips_split_const): Delete.
|
||||
(mips_offset_within_object_p): Delete.
|
||||
(mips_symbolic_constant_p): Use offset_within_section_p and
|
||||
split_const instead of mips_offset_within_object_p and
|
||||
mips_split_const.
|
||||
(mips_cannot_force_const_mem, mips_const_insns, mips_unspec_address)
|
||||
(mips_legitimize_const_move, print_operand_reloc)
|
||||
(mips_dangerous_for_la25_p): Use split_const instead of
|
||||
mips_split_const.
|
||||
|
||||
2007-02-28 Eric Christopher <echristo@apple.com>
|
||||
|
||||
* Makefile.in (install-include-dir): Don't rm -rf include.
|
||||
|
@ -2314,7 +2314,7 @@ print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(BCONFIG_H) $(REAL_H)
|
||||
rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h \
|
||||
$(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) $(REAL_H) \
|
||||
$(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H)
|
||||
$(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H) $(TREE_H)
|
||||
|
||||
varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
$(RTL_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) hard-reg-set.h $(REGS_H) \
|
||||
|
@ -50,6 +50,7 @@ extern int standard_68881_constant_p (rtx);
|
||||
extern void print_operand_address (FILE *, rtx);
|
||||
extern void print_operand (FILE *, rtx, int);
|
||||
extern void notice_update_cc (rtx, rtx);
|
||||
extern bool m68k_illegitimate_symbolic_constant_p (rtx);
|
||||
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
|
||||
extern int valid_dbcc_comparison_p_2 (rtx, enum machine_mode);
|
||||
extern rtx m68k_libcall_value (enum machine_mode);
|
||||
|
@ -191,6 +191,9 @@ int m68k_last_compare_had_fp_operands;
|
||||
#undef TARGET_STRUCT_VALUE_RTX
|
||||
#define TARGET_STRUCT_VALUE_RTX m68k_struct_value_rtx
|
||||
|
||||
#undef TARGET_CANNOT_FORCE_CONST_MEM
|
||||
#define TARGET_CANNOT_FORCE_CONST_MEM m68k_illegitimate_symbolic_constant_p
|
||||
|
||||
static const struct attribute_spec m68k_attribute_table[] =
|
||||
{
|
||||
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
|
||||
@ -1663,6 +1666,23 @@ output_btst (rtx *operands, rtx countop, rtx dataop, rtx insn, int signpos)
|
||||
return "btst %0,%1";
|
||||
}
|
||||
|
||||
/* Return true if X is an illegitimate symbolic constant. */
|
||||
|
||||
bool
|
||||
m68k_illegitimate_symbolic_constant_p (rtx x)
|
||||
{
|
||||
rtx base, offset;
|
||||
|
||||
if (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
|
||||
{
|
||||
split_const (x, &base, &offset);
|
||||
if (GET_CODE (base) == SYMBOL_REF
|
||||
&& !offset_within_block_p (base, INTVAL (offset)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Legitimize PIC addresses. If the address is already
|
||||
position-independent, we return ORIG. Newly generated
|
||||
position-independent addresses go to REG. If we need more
|
||||
|
@ -786,17 +786,25 @@ __transfer_from_trampoline () \
|
||||
/* 1 if X is an address register */
|
||||
#define ADDRESS_REG_P(X) (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X)))
|
||||
|
||||
/* True if SYMBOL + OFFSET constants must refer to something within
|
||||
SYMBOL's section. */
|
||||
#ifndef M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P
|
||||
#define M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 0
|
||||
#endif
|
||||
|
||||
#define MAX_REGS_PER_ADDRESS 2
|
||||
|
||||
#define CONSTANT_ADDRESS_P(X) \
|
||||
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|
||||
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
|
||||
|| GET_CODE (X) == HIGH)
|
||||
#define CONSTANT_ADDRESS_P(X) \
|
||||
((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|
||||
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
|
||||
|| GET_CODE (X) == HIGH) \
|
||||
&& LEGITIMATE_CONSTANT_P (X))
|
||||
|
||||
/* Nonzero if the constant value X is a legitimate general operand.
|
||||
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
|
||||
#define LEGITIMATE_CONSTANT_P(X) (GET_MODE (X) != XFmode)
|
||||
#define LEGITIMATE_CONSTANT_P(X) \
|
||||
(GET_MODE (X) != XFmode \
|
||||
&& !m68k_illegitimate_symbolic_constant_p (X))
|
||||
|
||||
#ifndef REG_OK_STRICT
|
||||
#define PCREL_GENERAL_OPERAND_OK 0
|
||||
|
@ -627,10 +627,12 @@
|
||||
;; In both the PIC and non-PIC cases the patterns generated will
|
||||
;; matched by the next define_insn.
|
||||
(define_expand "movsi"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "")
|
||||
(match_operand:SI 1 "general_operand" ""))]
|
||||
[(set (match_operand:SI 0 "" "")
|
||||
(match_operand:SI 1 "" ""))]
|
||||
""
|
||||
{
|
||||
rtx tmp, base, offset;
|
||||
|
||||
if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
|
||||
{
|
||||
/* The source is an address which requires PIC relocation.
|
||||
@ -651,6 +653,18 @@
|
||||
operands[0] = gen_rtx_MEM (SImode,
|
||||
force_reg (SImode, XEXP (operands[0], 0)));
|
||||
}
|
||||
if (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
|
||||
{
|
||||
split_const (operands[1], &base, &offset);
|
||||
if (GET_CODE (base) == SYMBOL_REF
|
||||
&& !offset_within_block_p (base, INTVAL (offset)))
|
||||
{
|
||||
tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
|
||||
emit_move_insn (tmp, base);
|
||||
emit_insn (gen_addsi3 (operands[0], tmp, offset));
|
||||
DONE;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
;; General case of fullword move. The register constraints
|
||||
|
@ -65,3 +65,9 @@ Boston, MA 02110-1301, USA. */
|
||||
/* -msep-data is the default PIC mode on this target. */
|
||||
#define DRIVER_SELF_SPECS \
|
||||
"%{fpie|fPIE|fpic|fPIC:%{!msep-data:%{!mid-shared-library: -msep-data}}}"
|
||||
|
||||
/* The uclinux binary format relies on relocations against a segment being
|
||||
within that segment. Conservatively apply this rule to individual
|
||||
sections. */
|
||||
#undef M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P
|
||||
#define M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 1
|
||||
|
@ -267,8 +267,6 @@ struct mips_integer_op;
|
||||
struct mips_sim;
|
||||
|
||||
static enum mips_symbol_type mips_classify_symbol (rtx);
|
||||
static void mips_split_const (rtx, rtx *, HOST_WIDE_INT *);
|
||||
static bool mips_offset_within_object_p (rtx, HOST_WIDE_INT);
|
||||
static bool mips_valid_base_register_p (rtx, enum machine_mode, int);
|
||||
static bool mips_symbolic_address_p (enum mips_symbol_type, enum machine_mode);
|
||||
static bool mips_classify_address (struct mips_address_info *, rtx,
|
||||
@ -1292,58 +1290,6 @@ mips_classify_symbol (rtx x)
|
||||
return SYMBOL_GENERAL;
|
||||
}
|
||||
|
||||
|
||||
/* Split X into a base and a constant offset, storing them in *BASE
|
||||
and *OFFSET respectively. */
|
||||
|
||||
static void
|
||||
mips_split_const (rtx x, rtx *base, HOST_WIDE_INT *offset)
|
||||
{
|
||||
*offset = 0;
|
||||
|
||||
if (GET_CODE (x) == CONST)
|
||||
{
|
||||
x = XEXP (x, 0);
|
||||
if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
|
||||
{
|
||||
*offset += INTVAL (XEXP (x, 1));
|
||||
x = XEXP (x, 0);
|
||||
}
|
||||
}
|
||||
*base = x;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if SYMBOL is a SYMBOL_REF and OFFSET + SYMBOL points
|
||||
to the same object as SYMBOL, or to the same object_block. */
|
||||
|
||||
static bool
|
||||
mips_offset_within_object_p (rtx symbol, HOST_WIDE_INT offset)
|
||||
{
|
||||
if (GET_CODE (symbol) != SYMBOL_REF)
|
||||
return false;
|
||||
|
||||
if (CONSTANT_POOL_ADDRESS_P (symbol)
|
||||
&& offset >= 0
|
||||
&& offset < (int) GET_MODE_SIZE (get_pool_mode (symbol)))
|
||||
return true;
|
||||
|
||||
if (SYMBOL_REF_DECL (symbol) != 0
|
||||
&& offset >= 0
|
||||
&& offset < int_size_in_bytes (TREE_TYPE (SYMBOL_REF_DECL (symbol))))
|
||||
return true;
|
||||
|
||||
if (SYMBOL_REF_HAS_BLOCK_INFO_P (symbol)
|
||||
&& SYMBOL_REF_BLOCK (symbol)
|
||||
&& SYMBOL_REF_BLOCK_OFFSET (symbol) >= 0
|
||||
&& ((unsigned HOST_WIDE_INT) offset + SYMBOL_REF_BLOCK_OFFSET (symbol)
|
||||
< (unsigned HOST_WIDE_INT) SYMBOL_REF_BLOCK (symbol)->size))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if X is a symbolic constant that can be calculated in
|
||||
the same way as a bare symbol. If it is, store the type of the
|
||||
symbol in *SYMBOL_TYPE. */
|
||||
@ -1351,9 +1297,9 @@ mips_offset_within_object_p (rtx symbol, HOST_WIDE_INT offset)
|
||||
bool
|
||||
mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
|
||||
{
|
||||
HOST_WIDE_INT offset;
|
||||
rtx offset;
|
||||
|
||||
mips_split_const (x, &x, &offset);
|
||||
split_const (x, &x, &offset);
|
||||
if (UNSPEC_ADDRESS_P (x))
|
||||
*symbol_type = UNSPEC_ADDRESS_TYPE (x);
|
||||
else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
|
||||
@ -1365,7 +1311,7 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
|
||||
else
|
||||
return false;
|
||||
|
||||
if (offset == 0)
|
||||
if (offset == const0_rtx)
|
||||
return true;
|
||||
|
||||
/* Check whether a nonzero offset is valid for the underlying
|
||||
@ -1381,7 +1327,7 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
|
||||
sign-extended. In this case we can't allow an arbitrary offset
|
||||
in case the 32-bit value X + OFFSET has a different sign from X. */
|
||||
if (Pmode == DImode && !ABI_HAS_64BIT_SYMBOLS)
|
||||
return mips_offset_within_object_p (x, offset);
|
||||
return offset_within_block_p (x, INTVAL (offset));
|
||||
|
||||
/* In other cases the relocations can handle any offset. */
|
||||
return true;
|
||||
@ -1397,15 +1343,15 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
|
||||
|
||||
case SYMBOL_SMALL_DATA:
|
||||
/* Make sure that the offset refers to something within the
|
||||
underlying object. This should guarantee that the final
|
||||
same object block. This should guarantee that the final
|
||||
PC- or GP-relative offset is within the 16-bit limit. */
|
||||
return mips_offset_within_object_p (x, offset);
|
||||
return offset_within_block_p (x, INTVAL (offset));
|
||||
|
||||
case SYMBOL_GOT_LOCAL:
|
||||
case SYMBOL_GOTOFF_PAGE:
|
||||
/* The linker should provide enough local GOT entries for a
|
||||
16-bit offset. Larger offsets may lead to GOT overflow. */
|
||||
return SMALL_OPERAND (offset);
|
||||
return SMALL_INT (offset);
|
||||
|
||||
case SYMBOL_GOT_GLOBAL:
|
||||
case SYMBOL_GOTOFF_GLOBAL:
|
||||
@ -1595,8 +1541,7 @@ mips_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
|
||||
static bool
|
||||
mips_cannot_force_const_mem (rtx x)
|
||||
{
|
||||
rtx base;
|
||||
HOST_WIDE_INT offset;
|
||||
rtx base, offset;
|
||||
|
||||
if (!TARGET_MIPS16)
|
||||
{
|
||||
@ -1612,8 +1557,8 @@ mips_cannot_force_const_mem (rtx x)
|
||||
if (GET_CODE (x) == CONST_INT)
|
||||
return true;
|
||||
|
||||
mips_split_const (x, &base, &offset);
|
||||
if (symbolic_operand (base, VOIDmode) && SMALL_OPERAND (offset))
|
||||
split_const (x, &base, &offset);
|
||||
if (symbolic_operand (base, VOIDmode) && SMALL_INT (offset))
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1800,7 +1745,7 @@ mips_const_insns (rtx x)
|
||||
{
|
||||
struct mips_integer_op codes[MIPS_MAX_INTEGER_OPS];
|
||||
enum mips_symbol_type symbol_type;
|
||||
HOST_WIDE_INT offset;
|
||||
rtx offset;
|
||||
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
@ -1841,16 +1786,16 @@ mips_const_insns (rtx x)
|
||||
/* Otherwise try splitting the constant into a base and offset.
|
||||
16-bit offsets can be added using an extra addiu. Larger offsets
|
||||
must be calculated separately and then added to the base. */
|
||||
mips_split_const (x, &x, &offset);
|
||||
split_const (x, &x, &offset);
|
||||
if (offset != 0)
|
||||
{
|
||||
int n = mips_const_insns (x);
|
||||
if (n != 0)
|
||||
{
|
||||
if (SMALL_OPERAND (offset))
|
||||
if (SMALL_INT (offset))
|
||||
return n + 1;
|
||||
else
|
||||
return n + 1 + mips_build_integer (codes, offset);
|
||||
return n + 1 + mips_build_integer (codes, INTVAL (offset));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -1949,13 +1894,14 @@ mips_split_symbol (rtx temp, rtx addr)
|
||||
rtx
|
||||
mips_unspec_address (rtx address, enum mips_symbol_type symbol_type)
|
||||
{
|
||||
rtx base;
|
||||
HOST_WIDE_INT offset;
|
||||
rtx base, offset;
|
||||
|
||||
mips_split_const (address, &base, &offset);
|
||||
split_const (address, &base, &offset);
|
||||
base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
|
||||
UNSPEC_ADDRESS_FIRST + symbol_type);
|
||||
return plus_constant (gen_rtx_CONST (Pmode, base), offset);
|
||||
if (offset != const0_rtx)
|
||||
base = gen_rtx_PLUS (Pmode, base, offset);
|
||||
return gen_rtx_CONST (Pmode, base);
|
||||
}
|
||||
|
||||
|
||||
@ -2303,8 +2249,7 @@ mips_move_integer (rtx dest, rtx temp, unsigned HOST_WIDE_INT value)
|
||||
static void
|
||||
mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
|
||||
{
|
||||
rtx base;
|
||||
HOST_WIDE_INT offset;
|
||||
rtx base, offset;
|
||||
|
||||
/* Split moves of big integers into smaller pieces. */
|
||||
if (splittable_const_int_operand (src, mode))
|
||||
@ -2329,13 +2274,13 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
|
||||
/* If we have (const (plus symbol offset)), load the symbol first
|
||||
and then add in the offset. This is usually better than forcing
|
||||
the constant into memory, at least in non-mips16 code. */
|
||||
mips_split_const (src, &base, &offset);
|
||||
split_const (src, &base, &offset);
|
||||
if (!TARGET_MIPS16
|
||||
&& offset != 0
|
||||
&& (!no_new_pseudos || SMALL_OPERAND (offset)))
|
||||
&& offset != const0_rtx
|
||||
&& (!no_new_pseudos || SMALL_INT (offset)))
|
||||
{
|
||||
base = mips_force_temporary (dest, base);
|
||||
emit_move_insn (dest, mips_add_offset (0, base, offset));
|
||||
emit_move_insn (dest, mips_add_offset (0, base, INTVAL (offset)));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5709,16 +5654,15 @@ print_operand_reloc (FILE *file, rtx op, const char **relocs)
|
||||
{
|
||||
enum mips_symbol_type symbol_type;
|
||||
const char *p;
|
||||
rtx base;
|
||||
HOST_WIDE_INT offset;
|
||||
rtx base, offset;
|
||||
|
||||
if (!mips_symbolic_constant_p (op, &symbol_type) || relocs[symbol_type] == 0)
|
||||
fatal_insn ("PRINT_OPERAND, invalid operand for relocation", op);
|
||||
|
||||
/* If OP uses an UNSPEC address, we want to print the inner symbol. */
|
||||
mips_split_const (op, &base, &offset);
|
||||
split_const (op, &base, &offset);
|
||||
if (UNSPEC_ADDRESS_P (base))
|
||||
op = plus_constant (UNSPEC_ADDRESS (base), offset);
|
||||
op = plus_constant (UNSPEC_ADDRESS (base), INTVAL (offset));
|
||||
|
||||
fputs (relocs[symbol_type], file);
|
||||
output_addr_const (file, op);
|
||||
@ -7640,12 +7584,12 @@ mips_cannot_change_mode_class (enum machine_mode from,
|
||||
bool
|
||||
mips_dangerous_for_la25_p (rtx x)
|
||||
{
|
||||
HOST_WIDE_INT offset;
|
||||
rtx offset;
|
||||
|
||||
if (TARGET_EXPLICIT_RELOCS)
|
||||
return false;
|
||||
|
||||
mips_split_const (x, &x, &offset);
|
||||
split_const (x, &x, &offset);
|
||||
return global_got_operand (x, VOIDmode);
|
||||
}
|
||||
|
||||
|
@ -1672,6 +1672,8 @@ extern int rtx_varies_p (rtx, int);
|
||||
extern int rtx_addr_varies_p (rtx, int);
|
||||
extern HOST_WIDE_INT get_integer_term (rtx);
|
||||
extern rtx get_related_value (rtx);
|
||||
extern bool offset_within_block_p (rtx, HOST_WIDE_INT);
|
||||
extern void split_const (rtx, rtx *, rtx *);
|
||||
extern int reg_mentioned_p (rtx, rtx);
|
||||
extern int count_occurrences (rtx, rtx, int);
|
||||
extern int reg_referenced_p (rtx, rtx);
|
||||
|
@ -37,6 +37,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
#include "real.h"
|
||||
#include "regs.h"
|
||||
#include "function.h"
|
||||
#include "tree.h"
|
||||
|
||||
/* Information about a subreg of a hard register. */
|
||||
struct subreg_info
|
||||
@ -496,6 +497,61 @@ get_related_value (rtx x)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return true if SYMBOL is a SYMBOL_REF and OFFSET + SYMBOL points
|
||||
to somewhere in the same object or object_block as SYMBOL. */
|
||||
|
||||
bool
|
||||
offset_within_block_p (rtx symbol, HOST_WIDE_INT offset)
|
||||
{
|
||||
tree decl;
|
||||
|
||||
if (GET_CODE (symbol) != SYMBOL_REF)
|
||||
return false;
|
||||
|
||||
if (offset == 0)
|
||||
return true;
|
||||
|
||||
if (offset > 0)
|
||||
{
|
||||
if (CONSTANT_POOL_ADDRESS_P (symbol)
|
||||
&& offset < (int) GET_MODE_SIZE (get_pool_mode (symbol)))
|
||||
return true;
|
||||
|
||||
decl = SYMBOL_REF_DECL (symbol);
|
||||
if (decl && offset < int_size_in_bytes (TREE_TYPE (decl)))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SYMBOL_REF_HAS_BLOCK_INFO_P (symbol)
|
||||
&& SYMBOL_REF_BLOCK (symbol)
|
||||
&& SYMBOL_REF_BLOCK_OFFSET (symbol) >= 0
|
||||
&& ((unsigned HOST_WIDE_INT) offset + SYMBOL_REF_BLOCK_OFFSET (symbol)
|
||||
< (unsigned HOST_WIDE_INT) SYMBOL_REF_BLOCK (symbol)->size))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Split X into a base and a constant offset, storing them in *BASE_OUT
|
||||
and *OFFSET_OUT respectively. */
|
||||
|
||||
void
|
||||
split_const (rtx x, rtx *base_out, rtx *offset_out)
|
||||
{
|
||||
if (GET_CODE (x) == CONST)
|
||||
{
|
||||
x = XEXP (x, 0);
|
||||
if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
|
||||
{
|
||||
*base_out = XEXP (x, 0);
|
||||
*offset_out = XEXP (x, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
*base_out = x;
|
||||
*offset_out = const0_rtx;
|
||||
}
|
||||
|
||||
/* Return the number of places FIND appears within X. If COUNT_DEST is
|
||||
zero, we do not count occurrences inside the destination of a SET. */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user