aboutsummaryrefslogtreecommitdiff
path: root/gcc/yara-trans.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/yara-trans.c')
-rw-r--r--gcc/yara-trans.c430
1 files changed, 266 insertions, 164 deletions
diff --git a/gcc/yara-trans.c b/gcc/yara-trans.c
index 3babb3593e1..33bb658e7bf 100644
--- a/gcc/yara-trans.c
+++ b/gcc/yara-trans.c
@@ -76,6 +76,11 @@ static void reserve_stack_memory (int, int);
static int find_free_stack_memory (int, int);
static void finish_stack_memory (void);
+static void initiate_copy_changes (void);
+static void free_copy_change (struct copy_change *);
+static struct copy_change *get_free_copy_change (void);
+static void finish_copy_changes (void);
+
static struct memory_slot *get_free_memory_slot_structure (void);
static void free_memory_slot_structure (struct memory_slot *);
static void switch_on_pending_memory_slot_structures (void);
@@ -114,11 +119,11 @@ static int find_hard_reg_for_mode (enum reg_class, enum machine_mode,
static bool allocate_copy_secondary_memory (bool, copy_t, int, enum reg_class,
enum reg_class, enum machine_mode);
#endif
-#ifdef HAVE_ANY_SECONDARY_MOVES
-static bool assign_copy_secondary (copy_t);
-static bool assign_secondary (allocno_t);
-static void unassign_secondary (allocno_t a);
-#endif
+static bool assign_copy_interm_equiv_const_hard_reg (copy_t);
+static void unassign_copy_interm_equiv_const_hard_reg (copy_t);
+static bool assign_copy (copy_t);
+static bool assign_allocno_copies (allocno_t);
+static void unassign_allocno_copies (allocno_t a);
static bool check_hard_regno_for_a (allocno_t, int, HARD_REG_SET);
static bool collect_conflict_hard_regs (allocno_t, HARD_REG_SET *);
static bool assign_allocno_hard_regno (allocno_t, int, HARD_REG_SET);
@@ -131,8 +136,6 @@ static void possible_alt_reg_intersection (allocno_t, HARD_REG_SET *);
static bool all_alt_offset_ok_p (allocno_t, HOST_WIDE_INT);
static bool find_interm_elimination_reg (allocno_t, enum reg_class,
HARD_REG_SET);
-static struct reg_eliminate *check_elimination_in_addr (rtx *, rtx *, bool *);
-
static struct log_entry *get_free_log_entry (void);
static void free_log_entry (struct log_entry *);
static void free_all_log_entries (void);
@@ -311,71 +314,67 @@ finish_stack_memory (void)
-#ifdef HAVE_ANY_SECONDARY_MOVES
-
-static struct secondary_copy_change *free_secondary_copy_changes;
-static varray_type secondary_copy_change_varray;
+static struct copy_change *free_copy_changes;
+static varray_type copy_change_varray;
static void
-initiate_secondary_copy_changes (void)
+initiate_copy_changes (void)
{
- free_secondary_copy_changes = NULL;
- VARRAY_GENERIC_PTR_NOGC_INIT (secondary_copy_change_varray, 2000,
- "all secondary copy changes");
+ free_copy_changes = NULL;
+ VARRAY_GENERIC_PTR_NOGC_INIT (copy_change_varray, 2000, "all copy changes");
}
static void
-free_secondary_copy_change (struct secondary_copy_change *change)
+free_copy_change (struct copy_change *change)
{
- *(struct secondary_copy_change **) change = free_secondary_copy_changes;
- free_secondary_copy_changes = change;
+ *(struct copy_change **) change = free_copy_changes;
+ free_copy_changes = change;
}
-static struct secondary_copy_change *
-get_free_secondary_copy_change (void)
+static struct copy_change *
+get_free_copy_change (void)
{
- struct secondary_copy_change *result;
+ struct copy_change *result;
- if (free_secondary_copy_changes == NULL)
+ if (free_copy_changes == NULL)
{
- result = yara_allocate (sizeof (struct secondary_copy_change));
- VARRAY_PUSH_GENERIC_PTR (secondary_copy_change_varray, result);
+ result = yara_allocate (sizeof (struct copy_change));
+ VARRAY_PUSH_GENERIC_PTR (copy_change_varray, result);
}
else
{
- result = free_secondary_copy_changes;
- free_secondary_copy_changes
- = *(struct secondary_copy_change **) free_secondary_copy_changes;
+ result = free_copy_changes;
+ free_copy_changes
+ = *(struct copy_change **) free_copy_changes;
}
#ifdef HAVE_SECONDARY_RELOADS
result->icode = CODE_FOR_nothing;
result->interm_mode = result->scratch_mode = VOIDmode;
result->interm_regno = result->scratch_regno = -1;
- CLEAR_HARD_REG_SET (result->interm_scratch_hard_regset);
#endif
+ result->interm_equiv_const_regno = -1;
+ result->interm_equiv_const_mode = VOIDmode;
#ifdef SECONDARY_MEMORY_NEEDED
result->memory_mode = VOIDmode;
result->user_defined_memory = NULL_RTX;
result->memory_slot = NULL;
#endif
+ CLEAR_HARD_REG_SET (result->interm_scratch_hard_regset);
return result;
}
-
static void
-finish_secondary_copy_changes (void)
+finish_copy_changes (void)
{
int i;
- for (i = VARRAY_ACTIVE_SIZE (secondary_copy_change_varray) - 1;
+ for (i = VARRAY_ACTIVE_SIZE (copy_change_varray) - 1;
i >= 0;
i--)
- yara_free (VARRAY_GENERIC_PTR (secondary_copy_change_varray, i));
- VARRAY_FREE (secondary_copy_change_varray);
+ yara_free (VARRAY_GENERIC_PTR (copy_change_varray, i));
+ VARRAY_FREE (copy_change_varray);
}
-#endif /* HAVE_ANY_SECONDARY_MOVES */
-
/* This page contains functions to allocate/deallocate memory slots for
@@ -970,8 +969,7 @@ allocate_allocno_memory_slot (allocno_t a)
{
if (can_copy_conflict_p (can, copies [i]))
{
- yara_assert (COPY_SECONDARY_CHANGE_ADDR (copies [i])
- != NULL);
+ yara_assert (COPY_CHANGE_ADDR (copies [i]) != NULL);
conflict_slot = COPY_MEMORY_SLOT (copies [i]);
yara_assert (conflict_slot != NULL);
reserve_stack_memory (conflict_slot->start,
@@ -1043,8 +1041,7 @@ allocate_copy_memory_slot (copy_t cp)
struct memory_slot *slot, *conflict_slot;
allocno_t *vec;
- yara_assert (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL
- && COPY_MEMORY_SLOT (cp) == NULL);
+ yara_assert (COPY_CHANGE_ADDR (cp) != NULL && COPY_MEMORY_SLOT (cp) == NULL);
slot = COPY_MEMORY_SLOT (cp) = get_free_memory_slot_structure ();
bitmap_set_bit (secondary_memory_copies, COPY_NUM (cp));
slot->size = GET_MODE_SIZE (COPY_MEMORY_MODE (cp));
@@ -1071,7 +1068,7 @@ deallocate_copy_memory_slot (copy_t cp)
struct memory_slot *slot;
int align;
- yara_assert (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL);
+ yara_assert (COPY_CHANGE_ADDR (cp) != NULL);
slot = COPY_MEMORY_SLOT (cp);
align = get_stack_align (COPY_MEMORY_MODE (cp)) / BITS_PER_UNIT;
yara_assert (slot->mem == NULL_RTX);
@@ -1150,7 +1147,7 @@ compact_stack (void)
{
if (can_copy_conflict_p (can, copies [j]))
{
- yara_assert (COPY_SECONDARY_CHANGE_ADDR (copies [j]) != NULL);
+ yara_assert (COPY_CHANGE_ADDR (copies [j]) != NULL);
conflict_slot = COPY_MEMORY_SLOT (copies [j]);
yara_assert (conflict_slot != NULL
&& conflict_slot->mem == NULL_RTX);
@@ -1672,8 +1669,8 @@ allocate_copy_secondary_memory (bool in_p, copy_t cp, int hard_regno,
if (COPY_DST (cp) != NULL && ALLOCNO_TYPE (COPY_DST (cp)) == INSN_ALLOCNO
&& INSN_ALLOCNO_ELIMINATION_P (COPY_DST (cp)))
return false;
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL)
- COPY_SECONDARY_CHANGE_ADDR (cp) = get_free_secondary_copy_change ();
+ if (COPY_CHANGE_ADDR (cp) == NULL)
+ COPY_CHANGE_ADDR (cp) = get_free_copy_change ();
COPY_MEMORY_MODE (cp) = mode;
allocate_copy_memory_slot (cp);
}
@@ -1682,10 +1679,45 @@ allocate_copy_secondary_memory (bool in_p, copy_t cp, int hard_regno,
#endif
-#ifdef HAVE_ANY_SECONDARY_MOVES
+/* The function checks (and returns true in case of success) that copy
+ CP with source allocno using equivalent constant can be successfully
+ generated and, if necessary, assigns an intermediate hard register
+ will be used to assign the constant to the copy destination. */
+static bool
+assign_copy_interm_equiv_const_hard_reg (copy_t cp)
+{
+ allocno_t src, dst;
+
+ src = COPY_SRC (cp);
+ dst = COPY_DST (cp);
+ yara_assert (src != NULL && dst != NULL);
+ if (ALLOCNO_USE_EQUIV_CONST_P (dst))
+ return true;
+ yara_assert (ALLOCNO_USE_EQUIV_CONST_P (src));
+ /* ??? We need better code for all possible cases including usage of
+ an intermediate register.*/
+ if (ALLOCNO_MEMORY_SLOT (dst) != NULL)
+ return false;
+ return true;
+}
+
+/* The function frees an intermediate hard register (if any) used to
+ assign the constant to the copy destination. */
+static void
+unassign_copy_interm_equiv_const_hard_reg (copy_t cp)
+{
+ allocno_t src, dst;
+
+ src = COPY_SRC (cp);
+ dst = COPY_DST (cp);
+ yara_assert (src != NULL && dst != NULL);
+ if (ALLOCNO_USE_EQUIV_CONST_P (dst))
+ return;
+ yara_assert (ALLOCNO_USE_EQUIV_CONST_P (src));
+}
static bool
-assign_copy_secondary (copy_t cp)
+assign_copy (copy_t cp)
{
bool in_p;
enum reg_class cl;
@@ -1697,6 +1729,9 @@ assign_copy_secondary (copy_t cp)
in_p = false;
a = COPY_SRC (cp);
a2 = COPY_DST (cp);
+ if (a != NULL && ALLOCNO_USE_EQUIV_CONST_P (a)
+ && ! assign_copy_interm_equiv_const_hard_reg (cp))
+ return false;
if (a == NULL)
{
a = COPY_DST (cp);
@@ -1854,7 +1889,7 @@ assign_copy_secondary (copy_t cp)
#endif
if (ALLOCNO_TYPE (a) == INSN_ALLOCNO && INSN_ALLOCNO_ELIMINATION_P (a))
return false;
- yara_assert (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL);
+ yara_assert (COPY_CHANGE_ADDR (cp) == NULL);
logged_p = true;
log_copy (cp);
vec = COPY_ALLOCNO_CONFLICT_VEC (cp);
@@ -1929,7 +1964,7 @@ assign_copy_secondary (copy_t cp)
}
}
#ifdef ENABLE_YARA_CHECKING
- if (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL)
+ if (COPY_CHANGE_ADDR (cp) != NULL)
{
GO_IF_HARD_REG_EQUAL (COPY_INTERM_SCRATCH_HARD_REGSET (cp),
zero_hard_reg_set, ok);
@@ -1938,7 +1973,7 @@ assign_copy_secondary (copy_t cp)
ok:
#endif
interm_hard_regno = scratch_hard_regno = -1;
- COPY_SECONDARY_CHANGE_ADDR (cp) = get_free_secondary_copy_change ();
+ COPY_CHANGE_ADDR (cp) = get_free_copy_change ();
if (interm_class != NO_REGS)
{
interm_hard_regno = find_hard_reg_for_mode (interm_class,
@@ -1999,52 +2034,52 @@ assign_copy_secondary (copy_t cp)
}
static bool
-assign_secondary (allocno_t a)
+assign_allocno_copies (allocno_t a)
{
copy_t cp;
bool succ_p = true;
for (cp = ALLOCNO_DST_COPIES (a); cp != NULL; cp = COPY_NEXT_DST_COPY (cp))
- if (! (succ_p = assign_copy_secondary (cp)))
+ if (! (succ_p = assign_copy (cp)))
break;
if (succ_p)
for (cp = ALLOCNO_SRC_COPIES (a); cp != NULL; cp = COPY_NEXT_SRC_COPY (cp))
- if (! (succ_p = assign_copy_secondary (cp)))
+ if (! (succ_p = assign_copy (cp)))
break;
if (succ_p)
return true;
/* Fail: restore the allocation state. */
for (cp = ALLOCNO_DST_COPIES (a); cp != NULL; cp = COPY_NEXT_DST_COPY (cp))
{
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL)
+ if (COPY_CHANGE_ADDR (cp) == NULL)
continue;
log_copy (cp);
#ifdef SECONDARY_MEMORY_NEEDED
if (COPY_MEMORY_SLOT (cp) != NULL)
deallocate_copy_memory_slot (cp);
#endif
- COPY_SECONDARY_CHANGE_ADDR (cp) = NULL;
+ COPY_CHANGE_ADDR (cp) = NULL;
}
for (cp = ALLOCNO_SRC_COPIES (a); cp != NULL; cp = COPY_NEXT_SRC_COPY (cp))
{
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL)
+ if (COPY_CHANGE_ADDR (cp) == NULL)
continue;
log_copy (cp);
#ifdef SECONDARY_MEMORY_NEEDED
if (COPY_MEMORY_SLOT (cp) != NULL)
deallocate_copy_memory_slot (cp);
#endif
- COPY_SECONDARY_CHANGE_ADDR (cp) = NULL;
+ COPY_CHANGE_ADDR (cp) = NULL;
}
return false;
}
void
-unassign_copy_secondary (copy_t cp)
+unassign_copy (copy_t cp)
{
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL)
+ if (COPY_CHANGE_ADDR (cp) == NULL)
return;
- log_copy (cp);
+ log_copy (cp);
#ifdef HAVE_SECONDARY_RELOADS
if (COPY_INTERM_REGNO (cp) >= 0)
mark_regno_release (COPY_INTERM_REGNO (cp), COPY_INTERM_MODE (cp));
@@ -2055,24 +2090,24 @@ unassign_copy_secondary (copy_t cp)
if (COPY_MEMORY_SLOT (cp) != NULL)
deallocate_copy_memory_slot (cp);
#endif
- free_secondary_copy_change (COPY_SECONDARY_CHANGE_ADDR (cp));
- COPY_SECONDARY_CHANGE_ADDR (cp) = NULL;
+ if (COPY_SRC (cp) != NULL && ALLOCNO_USE_EQUIV_CONST_P (COPY_SRC (cp)))
+ unassign_copy_interm_equiv_const_hard_reg (cp);
+ free_copy_change (COPY_CHANGE_ADDR (cp));
+ COPY_CHANGE_ADDR (cp) = NULL;
}
static void
-unassign_secondary (allocno_t a)
+unassign_allocno_copies (allocno_t a)
{
copy_t cp;
yara_assert (ALLOCNO_HARD_REGNO (a) >= 0 || ALLOCNO_MEMORY_SLOT (a) != NULL);
for (cp = ALLOCNO_DST_COPIES (a); cp != NULL; cp = COPY_NEXT_DST_COPY (cp))
- unassign_copy_secondary (cp);
+ unassign_copy (cp);
for (cp = ALLOCNO_SRC_COPIES (a); cp != NULL; cp = COPY_NEXT_SRC_COPY (cp))
- unassign_copy_secondary (cp);
+ unassign_copy (cp);
}
-#endif
-
static bool
check_hard_regno_for_a (allocno_t a, int hard_regno,
HARD_REG_SET possible_regs)
@@ -2153,19 +2188,15 @@ check_hard_regno_for_a (allocno_t a, int hard_regno,
return false;
}
}
-#ifdef HAVE_ANY_SECONDARY_MOVES
-#ifdef HAVE_SECONDARY_RELOADS
copy_vec = ALLOCNO_COPY_CONFLICT_VEC (a);
for (i = 0; (cp = copy_vec [i]) != NULL; i++)
{
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL)
+ if (COPY_CHANGE_ADDR (cp) == NULL)
continue;
if (! hard_reg_not_in_set_p (start, allocation_mode,
COPY_INTERM_SCRATCH_HARD_REGSET (cp)))
return false;
}
-#endif
-#endif
return true;
}
@@ -2251,13 +2282,11 @@ collect_conflict_hard_regs (allocno_t a, HARD_REG_SET *prohibited_hard_regs)
if (possible_hard_regnos_num == 0)
return false;
}
-#ifdef HAVE_ANY_SECONDARY_MOVES
-#ifdef HAVE_SECONDARY_RELOADS
CLEAR_HARD_REG_SET (temp_set);
copy_vec = ALLOCNO_COPY_CONFLICT_VEC (a);
for (i = 0; (cp = copy_vec [i]) != NULL; i++)
{
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL)
+ if (COPY_CHANGE_ADDR (cp) == NULL)
continue;
IOR_HARD_REG_SET (temp_set, COPY_INTERM_SCRATCH_HARD_REGSET (cp));
}
@@ -2276,8 +2305,6 @@ collect_conflict_hard_regs (allocno_t a, HARD_REG_SET *prohibited_hard_regs)
}
}
IOR_HARD_REG_SET (conflict_set, temp_set);
-#endif
-#endif
COPY_HARD_REG_SET (*prohibited_hard_regs, conflict_set);
return true;
}
@@ -2403,9 +2430,7 @@ assign_allocno_hard_regno (allocno_t a, int hard_regno,
log_allocno (a);
INSN_ALLOCNO_USE_WITHOUT_CHANGE_P (a) = true;
global_allocation_cost += allocno_copy_cost (a);
-#ifdef HAVE_ANY_SECONDARY_MOVES
- yara_assert (assign_secondary (a));
-#endif
+ yara_assert (assign_allocno_copies (a));
return true;
}
}
@@ -2413,13 +2438,11 @@ assign_allocno_hard_regno (allocno_t a, int hard_regno,
return false;
log_allocno (a);
ALLOCNO_HARD_REGNO (a) = hard_regno;
-#ifdef HAVE_ANY_SECONDARY_MOVES
- if (! assign_secondary (a))
+ if (! assign_allocno_copies (a))
{
ALLOCNO_HARD_REGNO (a) = -1;
return false;
}
-#endif
allocation_mode = get_allocation_mode (a);
start = get_maximal_part_start_hard_regno (hard_regno, a);
yara_assert (start >= 0);
@@ -2452,8 +2475,7 @@ assign_one_allocno (allocno_t a, enum reg_class cl, HARD_REG_SET possible_regs)
else
ALLOCNO_USE_EQUIV_CONST_P (a) = true;
global_allocation_cost += allocno_copy_cost (a);
-#ifdef HAVE_ANY_SECONDARY_MOVES
- if (! assign_secondary (a))
+ if (! assign_allocno_copies (a))
{
if (equiv_const == NULL_RTX)
INSN_ALLOCNO_USE_WITHOUT_CHANGE_P (a) = false;
@@ -2461,7 +2483,6 @@ assign_one_allocno (allocno_t a, enum reg_class cl, HARD_REG_SET possible_regs)
ALLOCNO_USE_EQUIV_CONST_P (a) = false;
return false;
}
-#endif
return true;
}
else if (cl == NO_REGS)
@@ -2482,8 +2503,7 @@ assign_one_allocno (allocno_t a, enum reg_class cl, HARD_REG_SET possible_regs)
INSN_ALLOCNO_CONST_POOL_P (a) = true;
}
global_allocation_cost += allocno_copy_cost (a);
-#ifdef HAVE_ANY_SECONDARY_MOVES
- if (! assign_secondary (a))
+ if (! assign_allocno_copies (a))
{
if (ALLOCNO_MEMORY_SLOT (a) != NULL)
deallocate_allocno_memory_slot (a);
@@ -2491,7 +2511,6 @@ assign_one_allocno (allocno_t a, enum reg_class cl, HARD_REG_SET possible_regs)
INSN_ALLOCNO_CONST_POOL_P (a) = false;
return false;
}
-#endif
return true;
}
yara_assert (ALLOCNO_HARD_REGNO (a) < 0);
@@ -2513,13 +2532,11 @@ assign_one_allocno (allocno_t a, enum reg_class cl, HARD_REG_SET possible_regs)
return false;
log_allocno (a);
ALLOCNO_HARD_REGNO (a) = hard_regno;
-#ifdef HAVE_ANY_SECONDARY_MOVES
- if (! assign_secondary (a))
+ if (! assign_allocno_copies (a))
{
ALLOCNO_HARD_REGNO (a) = -1;
return false;
}
-#endif
allocation_mode = get_allocation_mode (a);
start = get_maximal_part_start_hard_regno (hard_regno, a);
yara_assert (start >= 0);
@@ -2537,9 +2554,7 @@ unassign_one_allocno (allocno_t a)
global_allocation_cost -= allocno_copy_cost (a);
if (ALLOCNO_HARD_REGNO (a) >= 0)
{
-#ifdef HAVE_ANY_SECONDARY_MOVES
- unassign_secondary (a);
-#endif
+ unassign_allocno_copies (a);
mark_regno_release
(get_maximal_part_start_hard_regno (ALLOCNO_HARD_REGNO (a), a),
get_allocation_mode (a));
@@ -2548,13 +2563,14 @@ unassign_one_allocno (allocno_t a)
}
else if (ALLOCNO_MEMORY_SLOT (a) != NULL)
{
-#ifdef HAVE_ANY_SECONDARY_MOVES
- unassign_secondary (a);
-#endif
+ unassign_allocno_copies (a);
deallocate_allocno_memory_slot (a);
}
else if (ALLOCNO_USE_EQUIV_CONST_P (a))
- ALLOCNO_USE_EQUIV_CONST_P (a) = false;
+ {
+ unassign_allocno_copies (a);
+ ALLOCNO_USE_EQUIV_CONST_P (a) = false;
+ }
else if (ALLOCNO_TYPE (a) == INSN_ALLOCNO)
{
if (INSN_ALLOCNO_CONST_POOL_P (a))
@@ -3018,8 +3034,14 @@ find_interm_elimination_reg (allocno_t a, enum reg_class cl,
return hard_regno >= 0;
}
-static struct reg_eliminate *
-check_elimination_in_addr (rtx *address_loc, rtx *container_loc, bool *base_p)
+/* The function checks that address *ADDRESS_LOC of CONTAINER_LOC can
+ be eliminated and return elimination info and what should be
+ eliminated through BASE_REG_P. The function do substitution of
+ register CHANGE in the address by SUBST_REGNO before the check.
+ ADDITION is an additional offset after the elimination. */
+struct reg_eliminate *
+check_elimination_in_addr (int change, int subst_regno, HOST_WIDE_INT addition,
+ rtx *address_loc, rtx *container_loc, bool *base_p)
{
bool ok_p;
int base_regno, index_regno, saved_regno;
@@ -3036,9 +3058,17 @@ check_elimination_in_addr (rtx *address_loc, rtx *container_loc, bool *base_p)
yara_assert (temp_container_loc == container_loc);
base_regno = index_regno = -1;
if (base_reg_loc != NULL)
- base_regno = REGNO (*base_reg_loc);
+ {
+ base_regno = REGNO (*base_reg_loc);
+ if (base_regno == change)
+ base_regno = subst_regno;
+ }
if (index_reg_loc != NULL)
- index_regno = REGNO (*index_reg_loc);
+ {
+ index_regno = REGNO (*index_reg_loc);
+ if (index_regno == change)
+ index_regno = subst_regno;
+ }
yara_assert (base_regno >= 0 || index_regno >= 0);
if (base_regno >= 0 && HARD_REGISTER_NUM_P (base_regno)
&& reg_eliminate [base_regno] != NULL)
@@ -3061,17 +3091,17 @@ check_elimination_in_addr (rtx *address_loc, rtx *container_loc, bool *base_p)
elim != NULL;
elim = elim->next)
{
- offset = elim->offset;
+ offset = elim->offset + addition;
if (elim->to == STACK_POINTER_REGNUM)
offset += slot_memory_size;
if (*base_p)
{
- saved_regno = base_regno;
+ saved_regno = REGNO (*base_reg_loc);
REGNO (*base_reg_loc) = elim->to;
}
else
{
- saved_regno = index_regno;
+ saved_regno = REGNO (*index_reg_loc);
REGNO (*index_reg_loc) = elim->to;
offset *= scale;
}
@@ -3115,6 +3145,7 @@ bool
eliminate_reg (allocno_t a)
{
int regno = ALLOCNO_REGNO (a);
+ allocno_t disp_a;
HOST_WIDE_INT offset;
rtx *container_loc;
struct reg_eliminate *elim;
@@ -3137,8 +3168,8 @@ eliminate_reg (allocno_t a)
{
/* It is a non-register allocno. */
base_p = true;
- elim = check_elimination_in_addr (INSN_ALLOCNO_LOC (a), container_loc,
- &base_p);
+ elim = check_elimination_in_addr (-1, -1, 0, INSN_ALLOCNO_LOC (a),
+ container_loc, &base_p);
possible_alt_reg_intersection (a, &possible_regs);
if (base_p)
{
@@ -3168,7 +3199,8 @@ eliminate_reg (allocno_t a)
address_loc = (GET_CODE (*container_loc) == MEM
? &XEXP (*container_loc, 0) : container_loc);
- elim = check_elimination_in_addr (address_loc, container_loc, &base_p);
+ elim = check_elimination_in_addr (-1, -1, 0,
+ address_loc, container_loc, &base_p);
yara_assert ((base_p && INSN_ALLOCNO_TYPE (a) == BASE_REG)
|| (! base_p && INSN_ALLOCNO_TYPE (a) == INDEX_REG));
if (elim != NULL)
@@ -3190,8 +3222,12 @@ eliminate_reg (allocno_t a)
}
else
{
+ rtx insn = INSN_ALLOCNO_INSN (a);
+
if (GET_CODE (*container_loc) == PLUS
- && GET_CODE (XEXP (*container_loc, 1)) == CONST_INT)
+ && GET_CODE (XEXP (*container_loc, 1)) == CONST_INT
+ && ((disp_a = insn_allocno (XEXP (*container_loc, 1), insn)) == NULL
+ || INSN_ALLOCNO_USE_WITHOUT_CHANGE_P (disp_a)))
{
/* The register is in operator PLUS. */
rtx temp_const_int;
@@ -3229,6 +3265,54 @@ uneliminate_reg (allocno_t a ATTRIBUTE_UNUSED)
|| ALLOCNO_REGNO (a) > LAST_VIRTUAL_REGISTER);
}
+/* The function returns hard register and offset through paarmeters TO
+ and OFFSET of function invariant address X. */
+void
+get_equiv_const_addr_info (rtx x, int *to, HOST_WIDE_INT *offset)
+{
+ if (GET_CODE (x) != PLUS)
+ *offset = 0;
+ else
+ {
+ /* ??? Fixme: In general it should be a general constant. */
+ yara_assert (GET_CODE (XEXP (x, 1)) == CONST_INT);
+ *offset = INTVAL (XEXP (x, 1));
+ x = XEXP (x, 0);
+ }
+ yara_assert (x == frame_pointer_rtx || x == arg_pointer_rtx);
+ *to = REGNO (x);
+}
+
+/* The function returns final hard register and final offset through
+ paarmeters TO and OFFSET of function invariant address X after
+ elimination of virtual register in X. */
+void
+get_equiv_const_elimination_info (rtx x, int *to, HOST_WIDE_INT *offset)
+{
+ struct reg_eliminate *elim;
+
+ if (GET_CODE (x) != PLUS)
+ *offset = 0;
+ else
+ {
+ /* ??? Fixme: In general it should be a constant. */
+ yara_assert (GET_CODE (XEXP (x, 1)) == CONST_INT);
+ *offset = INTVAL (XEXP (x, 1));
+ x = XEXP (x, 0);
+ }
+ yara_assert (x == frame_pointer_rtx || x == arg_pointer_rtx);
+ if ((elim = reg_eliminate [REGNO (x)]) == NULL)
+ *to = REGNO (x);
+ else
+ {
+ /* ??? only 1st elimination. */
+ *to = elim->to;
+ *offset += elim->offset;
+ if (*to == STACK_POINTER_REGNUM)
+ *offset += slot_memory_size;
+ }
+}
+
enum log_type {ALLOCNO_LOG, COPY_LOG, MEMORY_SLOT_LOG};
@@ -3451,15 +3535,13 @@ log_copy (copy_t cp)
l = get_free_log_entry ();
l->type = COPY_LOG;
l->u.c.copy = cp;
- l->u.c.change = COPY_CHANGE (cp);
-#ifdef HAVE_ANY_SECONDARY_MOVES
- if (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL)
+ l->u.c.copy_change = COPY_CHANGE_ADDR (cp);
+ if (COPY_CHANGE_ADDR (cp) != NULL)
{
- l->u.c.change.secondary_change = get_free_secondary_copy_change ();
- memcpy (l->u.c.change.secondary_change, COPY_SECONDARY_CHANGE_ADDR (cp),
- sizeof (struct secondary_copy_change));
+ l->u.c.copy_change = get_free_copy_change ();
+ memcpy (l->u.c.copy_change, COPY_CHANGE_ADDR (cp),
+ sizeof (struct copy_change));
}
-#endif
VARRAY_PUSH_GENERIC_PTR (log_varray, l);
}
@@ -3472,10 +3554,8 @@ undo_copy_change (struct copy_log_entry *cl)
bool new_p;
#ifdef SECONDARY_MEMORY_NEEDED
- copy_slot = (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL
- ? NULL : COPY_MEMORY_SLOT (cp));
- log_slot = (cl->change.secondary_change == NULL
- ? NULL : cl->change.secondary_change->memory_slot);
+ copy_slot = (COPY_CHANGE_ADDR (cp) == NULL ? NULL : COPY_MEMORY_SLOT (cp));
+ log_slot = (cl->copy_change == NULL ? NULL : cl->copy_change->memory_slot);
if (copy_slot != log_slot)
{
int align;
@@ -3489,7 +3569,7 @@ undo_copy_change (struct copy_log_entry *cl)
}
if (log_slot != NULL)
{
- align = (get_stack_align (cl->change.secondary_change->memory_mode)
+ align = (get_stack_align (cl->copy_change->memory_mode)
/ BITS_PER_UNIT);
yara_assert (log_slot->mem == NULL_RTX);
register_memory_slot_usage (log_slot, align);
@@ -3498,51 +3578,53 @@ undo_copy_change (struct copy_log_entry *cl)
}
#endif
#ifdef HAVE_SECONDARY_RELOADS
- copy_regno = (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL
- ? -1 : COPY_INTERM_REGNO (cp));
- log_regno = (cl->change.secondary_change == NULL
- ? -1 : cl->change.secondary_change->interm_regno);
+ copy_regno = (COPY_CHANGE_ADDR (cp) == NULL ? -1 : COPY_INTERM_REGNO (cp));
+ log_regno = (cl->copy_change == NULL ? -1 : cl->copy_change->interm_regno);
if (copy_regno != log_regno)
{
if (log_regno < 0)
mark_regno_release (copy_regno, COPY_INTERM_MODE (cp));
else if (copy_regno < 0)
- mark_regno_allocation (log_regno,
- cl->change.secondary_change->interm_mode);
+ mark_regno_allocation (log_regno, cl->copy_change->interm_mode);
else
gcc_unreachable ();
}
- copy_regno = (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL
- ? -1 : COPY_SCRATCH_REGNO (cp));
- log_regno = (cl->change.secondary_change == NULL
- ? -1 : cl->change.secondary_change->scratch_regno);
+ copy_regno = (COPY_CHANGE_ADDR (cp) == NULL ? -1 : COPY_SCRATCH_REGNO (cp));
+ log_regno = (cl->copy_change == NULL ? -1 : cl->copy_change->scratch_regno);
if (copy_regno != log_regno)
{
if (log_regno < 0)
mark_regno_release (copy_regno, COPY_SCRATCH_MODE (cp));
else if (copy_regno < 0)
- mark_regno_allocation (log_regno,
- cl->change.secondary_change->scratch_mode);
+ mark_regno_allocation (log_regno, cl->copy_change->scratch_mode);
else
gcc_unreachable ();
}
#endif
-#ifdef HAVE_ANY_SECONDARY_MOVES
- if (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL
- && cl->change.secondary_change == NULL)
- free_secondary_copy_change (COPY_SECONDARY_CHANGE_ADDR (cp));
- new_p = (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL
- && cl->change.secondary_change != NULL);
-#endif
- COPY_CHANGE (cp) = cl->change;
-#ifdef HAVE_ANY_SECONDARY_MOVES
+ copy_regno = (COPY_CHANGE_ADDR (cp) == NULL
+ ? -1 : COPY_INTERM_EQUIV_CONST_REGNO (cp));
+ log_regno = (cl->copy_change == NULL
+ ? -1 : cl->copy_change->interm_equiv_const_regno);
+ if (copy_regno != log_regno)
+ {
+ if (log_regno < 0)
+ mark_regno_release (copy_regno, COPY_INTERM_EQUIV_CONST_MODE (cp));
+ else if (copy_regno < 0)
+ mark_regno_allocation
+ (log_regno, cl->copy_change->interm_equiv_const_mode);
+ else
+ gcc_unreachable ();
+ }
+ if (COPY_CHANGE_ADDR (cp) != NULL && cl->copy_change == NULL)
+ free_copy_change (COPY_CHANGE_ADDR (cp));
+ new_p = (COPY_CHANGE_ADDR (cp) == NULL && cl->copy_change != NULL);
+ COPY_CHANGE_ADDR (cp) = cl->copy_change;
if (new_p)
{
- COPY_SECONDARY_CHANGE_ADDR (cp) = get_free_secondary_copy_change ();
- memcpy (COPY_SECONDARY_CHANGE_ADDR (cp), cl->change.secondary_change,
- sizeof (struct secondary_copy_change));
+ COPY_CHANGE_ADDR (cp) = get_free_copy_change ();
+ memcpy (COPY_CHANGE_ADDR (cp), cl->copy_change,
+ sizeof (struct copy_change));
}
-#endif
}
static void
@@ -3591,8 +3673,8 @@ undo_change (struct log_entry *l, bool accept_change_p)
else
gcc_unreachable ();
}
- if (l->type == COPY_LOG && l->u.c.change.secondary_change != NULL)
- free_secondary_copy_change (l->u.c.change.secondary_change);
+ if (l->type == COPY_LOG && l->u.c.copy_change != NULL)
+ free_copy_change (l->u.c.copy_change);
free_log_entry (l);
}
@@ -3652,8 +3734,8 @@ finish_transactions (void)
bool
-check_hard_regno_memory_on_contraint (allocno_t a, bool use_equiv_const_p,
- int hard_regno)
+check_hard_regno_memory_on_constraint (allocno_t a, bool use_equiv_const_p,
+ int hard_regno)
{
alt_set_t temp_alt_set, saved_alt_set;
bool saved_use_equiv_const_p;
@@ -3667,15 +3749,39 @@ check_hard_regno_memory_on_contraint (allocno_t a, bool use_equiv_const_p,
if (INSN_ALLOCNO_TYPE (a) == NON_OPERAND)
/* ???? */
return hard_regno >= 0;
- if (INSN_ALLOCNO_TYPE (a) == BASE_REG)
- /* ??? use_equiv_const_p */
- return (hard_regno >= 0
- && TEST_HARD_REG_BIT (base_regs
- [GET_MODE (*INSN_ALLOCNO_CONTAINER_LOC (a))],
- hard_regno));
- if (INSN_ALLOCNO_TYPE (a) == INDEX_REG)
- /* ??? use_equiv_const_p */
- return hard_regno >= 0 && TEST_HARD_REG_BIT (index_regs, hard_regno);
+ if (INSN_ALLOCNO_TYPE (a) == BASE_REG || INSN_ALLOCNO_TYPE (a) == INDEX_REG)
+ {
+ HARD_REG_SET temp;
+
+ if (INSN_ALLOCNO_TYPE (a) == BASE_REG)
+ COPY_HARD_REG_SET
+ (temp, base_regs [GET_MODE (*INSN_ALLOCNO_CONTAINER_LOC (a))]);
+ else
+ COPY_HARD_REG_SET (temp, index_regs);
+ if (! use_equiv_const_p)
+ return hard_regno >= 0 && TEST_HARD_REG_BIT (temp, hard_regno);
+ else
+ {
+ rtx equiv_const, *container_loc, *address_loc;
+ int to;
+ HOST_WIDE_INT offset;
+ bool base_p;
+
+ equiv_const = reg_equiv_constant [ALLOCNO_REGNO (a)];
+ yara_assert (equiv_cosnt != NULL_RTX);
+ if (CONSTANT_P (equiv_const))
+ return false;
+ get_equiv_const_addr_info (equiv_const, &to, &offset);
+ container_loc = INSN_ALLOCNO_CONTAINER_LOC (a);
+ address_loc = (GET_CODE (*container_loc) == MEM
+ ? &XEXP (*container_loc, 0) : container_loc);
+ /* ??? Allocate interm equiv constant register. Do we need
+ this? */
+ return check_elimination_in_addr (ALLOCNO_REGNO (a), to, offset,
+ address_loc, container_loc,
+ &base_p) != NULL;
+ }
+ }
op_num = INSN_ALLOCNO_TYPE (a) - OPERAND_BASE;
yara_assert (op_num >= 0);
info = insn_infos [INSN_UID (INSN_ALLOCNO_INSN (a))];
@@ -3749,9 +3855,7 @@ void
yara_trans_init (void)
{
set_ever_live_regs ();
-#ifdef HAVE_ANY_SECONDARY_MOVES
- initiate_secondary_copy_changes ();
-#endif
+ initiate_copy_changes ();
initiate_memory_slots ();
initiate_transactions ();
}
@@ -3762,9 +3866,7 @@ yara_trans_finish (void)
{
finish_memory_slots ();
finish_transactions ();
-#ifdef HAVE_ANY_SECONDARY_MOVES
- finish_secondary_copy_changes ();
-#endif
+ finish_copy_changes ();
}
#include "gt-yara-trans.h"