for mode MODE in address space AS. */
bool
-memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED,
- rtx addr, addr_space_t as)
+memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED, rtx addr,
+ addr_space_t as, code_helper ch)
{
#ifdef GO_IF_LEGITIMATE_ADDRESS
gcc_assert (ADDR_SPACE_GENERIC_P (as));
win:
return true;
#else
- return targetm.addr_space.legitimate_address_p (mode, addr, 0, as,
- ERROR_MARK);
+ return targetm.addr_space.legitimate_address_p (mode, addr, 0, as, ch);
#endif
}
rtx z;
rtx y1 = y;
rtx *y2;
- bool (*addressp) (machine_mode, rtx, addr_space_t) =
+ bool (*addressp) (machine_mode, rtx, addr_space_t, code_helper) =
(strictp ? strict_memory_address_addr_space_p
: memory_address_addr_space_p);
poly_int64 mode_sz = GET_MODE_SIZE (mode);
*y2 = plus_constant (address_mode, *y2, mode_sz - 1);
/* Use QImode because an odd displacement may be automatically invalid
for any wider mode. But it should be valid for a single byte. */
- good = (*addressp) (QImode, y, as);
+ good = (*addressp) (QImode, y, as, ERROR_MARK);
/* In any case, restore old contents of memory. */
*y2 = y1;
/* Use QImode because an odd displacement may be automatically invalid
for any wider mode. But it should be valid for a single byte. */
- return (*addressp) (QImode, z, as);
+ return (*addressp) (QImode, z, as, ERROR_MARK);
}
/* Return true if ADDR is an address-expression whose effect depends
#ifndef GCC_RECOG_H
#define GCC_RECOG_H
+/* For enum tree_code ERROR_MARK. */
+#include "tree.h"
+
/* Random number that should be large enough for all purposes. Also define
a type that has at least MAX_RECOG_ALTERNATIVES + 1 bits, with the extra
bit giving an invalid value that can be used to mean "uninitialized". */
extern void redo_changes (int);
extern bool constrain_operands (int, alternative_mask);
extern bool constrain_operands_cached (rtx_insn *, int);
-extern bool memory_address_addr_space_p (machine_mode, rtx, addr_space_t);
+extern bool memory_address_addr_space_p (machine_mode, rtx, addr_space_t,
+ code_helper = ERROR_MARK);
#define memory_address_p(mode,addr) \
memory_address_addr_space_p ((mode), (addr), ADDR_SPACE_GENERIC)
-extern bool strict_memory_address_addr_space_p (machine_mode, rtx,
- addr_space_t);
+extern bool strict_memory_address_addr_space_p (machine_mode, rtx, addr_space_t,
+ code_helper = ERROR_MARK);
#define strict_memory_address_p(mode,addr) \
strict_memory_address_addr_space_p ((mode), (addr), ADDR_SPACE_GENERIC)
extern bool validate_replace_rtx_subexp (rtx, rtx, rtx_insn *, rtx *);
bool
strict_memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED,
- rtx addr, addr_space_t as)
+ rtx addr, addr_space_t as, code_helper)
{
#ifdef GO_IF_LEGITIMATE_ADDRESS
gcc_assert (ADDR_SPACE_GENERIC_P (as));
bool
valid_mem_ref_p (machine_mode mode, addr_space_t as,
- struct mem_address *addr)
+ struct mem_address *addr, code_helper ch)
{
rtx address;
if (!address)
return false;
- return memory_address_addr_space_p (mode, address, as);
+ return memory_address_addr_space_p (mode, address, as, ch);
}
/* Checks whether a TARGET_MEM_REF with type TYPE and parameters given by ADDR
extern rtx addr_for_mem_ref (tree exp, addr_space_t as, bool really_expand);
extern void get_address_description (tree, struct mem_address *);
extern tree tree_mem_ref_addr (tree, tree);
-extern bool valid_mem_ref_p (machine_mode, addr_space_t, struct mem_address *);
+extern bool valid_mem_ref_p (machine_mode, addr_space_t, struct mem_address *,
+ code_helper = ERROR_MARK);
extern void move_fixed_address_to_symbol (struct mem_address *,
class aff_tree *);
tree create_mem_ref (gimple_stmt_iterator *, tree,
/* Only true if ratio != 1. */
bool ok_with_ratio_p = false;
bool ok_without_ratio_p = false;
+ code_helper code = ERROR_MARK;
+
+ if (use->type == USE_PTR_ADDRESS)
+ {
+ gcall *call = as_a<gcall *> (use->stmt);
+ gcc_assert (gimple_call_internal_p (call));
+ code = gimple_call_internal_fn (call);
+ }
if (!aff_combination_const_p (aff_inv))
{
parts.index = integer_one_node;
/* Addressing mode "base + index". */
- ok_without_ratio_p = valid_mem_ref_p (mem_mode, as, &parts);
+ ok_without_ratio_p = valid_mem_ref_p (mem_mode, as, &parts, code);
if (ratio != 1)
{
parts.step = wide_int_to_tree (type, ratio);
/* Addressing mode "base + index << scale". */
- ok_with_ratio_p = valid_mem_ref_p (mem_mode, as, &parts);
+ ok_with_ratio_p = valid_mem_ref_p (mem_mode, as, &parts, code);
if (!ok_with_ratio_p)
parts.step = NULL_TREE;
}
{
parts.offset = wide_int_to_tree (sizetype, aff_inv->offset);
/* Addressing mode "base + index [<< scale] + offset". */
- if (!valid_mem_ref_p (mem_mode, as, &parts))
+ if (!valid_mem_ref_p (mem_mode, as, &parts, code))
parts.offset = NULL_TREE;
else
aff_inv->offset = 0;
/* Addressing mode "symbol + base + index [<< scale] [+ offset]". */
if (parts.symbol != NULL_TREE
- && !valid_mem_ref_p (mem_mode, as, &parts))
+ && !valid_mem_ref_p (mem_mode, as, &parts, code))
{
aff_combination_add_elt (aff_inv, parts.symbol, 1);
parts.symbol = NULL_TREE;
{
parts.offset = wide_int_to_tree (sizetype, aff_inv->offset);
/* Addressing mode "base + offset". */
- if (!valid_mem_ref_p (mem_mode, as, &parts))
+ if (!valid_mem_ref_p (mem_mode, as, &parts, code))
parts.offset = NULL_TREE;
else
aff_inv->offset = 0;