summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/explow.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/explow.c')
-rw-r--r--contrib/gcc/explow.c256
1 files changed, 74 insertions, 182 deletions
diff --git a/contrib/gcc/explow.c b/contrib/gcc/explow.c
index 0d9139a..c1de4c8 100644
--- a/contrib/gcc/explow.c
+++ b/contrib/gcc/explow.c
@@ -1,6 +1,6 @@
/* Subroutines for manipulating rtx's in semantically interesting ways.
Copyright (C) 1987, 1991, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "tree.h"
@@ -36,16 +38,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "recog.h"
#include "langhooks.h"
-static rtx break_out_memory_refs PARAMS ((rtx));
-static void emit_stack_probe PARAMS ((rtx));
+static rtx break_out_memory_refs (rtx);
+static void emit_stack_probe (rtx);
/* Truncate and perhaps sign-extend C as appropriate for MODE. */
HOST_WIDE_INT
-trunc_int_for_mode (c, mode)
- HOST_WIDE_INT c;
- enum machine_mode mode;
+trunc_int_for_mode (HOST_WIDE_INT c, enum machine_mode mode)
{
int width = GET_MODE_BITSIZE (mode);
@@ -76,9 +76,7 @@ trunc_int_for_mode (c, mode)
This function should be used via the `plus_constant' macro. */
rtx
-plus_constant_wide (x, c)
- rtx x;
- HOST_WIDE_INT c;
+plus_constant_wide (rtx x, HOST_WIDE_INT c)
{
RTX_CODE code;
rtx y;
@@ -204,9 +202,7 @@ plus_constant_wide (x, c)
it is not isomorphic to X. */
rtx
-eliminate_constant_term (x, constptr)
- rtx x;
- rtx *constptr;
+eliminate_constant_term (rtx x, rtx *constptr)
{
rtx x0, x1;
rtx tem;
@@ -239,61 +235,14 @@ eliminate_constant_term (x, constptr)
return x;
}
-/* Returns the insn that next references REG after INSN, or 0
- if REG is clobbered before next referenced or we cannot find
- an insn that references REG in a straight-line piece of code. */
-
-rtx
-find_next_ref (reg, insn)
- rtx reg;
- rtx insn;
-{
- rtx next;
-
- for (insn = NEXT_INSN (insn); insn; insn = next)
- {
- next = NEXT_INSN (insn);
- if (GET_CODE (insn) == NOTE)
- continue;
- if (GET_CODE (insn) == CODE_LABEL
- || GET_CODE (insn) == BARRIER)
- return 0;
- if (GET_CODE (insn) == INSN
- || GET_CODE (insn) == JUMP_INSN
- || GET_CODE (insn) == CALL_INSN)
- {
- if (reg_set_p (reg, insn))
- return 0;
- if (reg_mentioned_p (reg, PATTERN (insn)))
- return insn;
- if (GET_CODE (insn) == JUMP_INSN)
- {
- if (any_uncondjump_p (insn))
- next = JUMP_LABEL (insn);
- else
- return 0;
- }
- if (GET_CODE (insn) == CALL_INSN
- && REGNO (reg) < FIRST_PSEUDO_REGISTER
- && call_used_regs[REGNO (reg)])
- return 0;
- }
- else
- abort ();
- }
- return 0;
-}
-
/* Return an rtx for the size in bytes of the value of EXP. */
rtx
-expr_size (exp)
- tree exp;
+expr_size (tree exp)
{
tree size = (*lang_hooks.expr_size) (exp);
- if (TREE_CODE (size) != INTEGER_CST
- && contains_placeholder_p (size))
+ if (CONTAINS_PLACEHOLDER_P (size))
size = build (WITH_RECORD_EXPR, sizetype, size, exp);
return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
@@ -303,8 +252,7 @@ expr_size (exp)
if the size can vary or is larger than an integer. */
HOST_WIDE_INT
-int_expr_size (exp)
- tree exp;
+int_expr_size (tree exp)
{
tree t = (*lang_hooks.expr_size) (exp);
@@ -336,8 +284,7 @@ int_expr_size (exp)
Values returned by expand_expr with 1 for sum_ok fit this constraint. */
static rtx
-break_out_memory_refs (x)
- rtx x;
+break_out_memory_refs (rtx x)
{
if (GET_CODE (x) == MEM
|| (CONSTANT_P (x) && CONSTANT_ADDRESS_P (x)
@@ -356,8 +303,6 @@ break_out_memory_refs (x)
return x;
}
-#ifdef POINTERS_EXTEND_UNSIGNED
-
/* Given X, a memory address in ptr_mode, convert it to an address
in Pmode, or vice versa (TO_MODE says which way). We take advantage of
the fact that pointers are not allowed to overflow by commuting arithmetic
@@ -365,14 +310,22 @@ break_out_memory_refs (x)
used. */
rtx
-convert_memory_address (to_mode, x)
- enum machine_mode to_mode;
- rtx x;
+convert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED,
+ rtx x)
{
- enum machine_mode from_mode = to_mode == ptr_mode ? Pmode : ptr_mode;
+#ifndef POINTERS_EXTEND_UNSIGNED
+ return x;
+#else /* defined(POINTERS_EXTEND_UNSIGNED) */
+ enum machine_mode from_mode;
rtx temp;
enum rtx_code code;
+ /* If X already has the right mode, just return it. */
+ if (GET_MODE (x) == to_mode)
+ return x;
+
+ from_mode = to_mode == ptr_mode ? Pmode : ptr_mode;
+
/* Here we handle some special cases. If none of them apply, fall through
to the default case. */
switch (GET_CODE (x))
@@ -436,8 +389,8 @@ convert_memory_address (to_mode, x)
return convert_modes (to_mode, from_mode,
x, POINTERS_EXTEND_UNSIGNED);
+#endif /* defined(POINTERS_EXTEND_UNSIGNED) */
}
-#endif
/* Given a memory address or facsimile X, construct a new address,
currently equivalent, that is stable: future stores won't change it.
@@ -453,8 +406,7 @@ convert_memory_address (to_mode, x)
but then you wouldn't get indexed addressing in the reference. */
rtx
-copy_all_regs (x)
- rtx x;
+copy_all_regs (rtx x)
{
if (GET_CODE (x) == REG)
{
@@ -483,21 +435,16 @@ copy_all_regs (x)
works by copying X or subexpressions of it into registers. */
rtx
-memory_address (mode, x)
- enum machine_mode mode;
- rtx x;
+memory_address (enum machine_mode mode, rtx x)
{
rtx oldx = x;
if (GET_CODE (x) == ADDRESSOF)
return x;
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (x) != Pmode)
- x = convert_memory_address (Pmode, x);
-#endif
+ x = convert_memory_address (Pmode, x);
- /* By passing constant addresses thru registers
+ /* By passing constant addresses through registers
we get a chance to cse them. */
if (! cse_not_expected && CONSTANT_P (x) && CONSTANT_ADDRESS_P (x))
x = force_reg (Pmode, x);
@@ -613,9 +560,7 @@ memory_address (mode, x)
/* Like `memory_address' but pretend `flag_force_addr' is 0. */
rtx
-memory_address_noforce (mode, x)
- enum machine_mode mode;
- rtx x;
+memory_address_noforce (enum machine_mode mode, rtx x)
{
int ambient_force_addr = flag_force_addr;
rtx val;
@@ -630,8 +575,7 @@ memory_address_noforce (mode, x)
Pass through anything else unchanged. */
rtx
-validize_mem (ref)
- rtx ref;
+validize_mem (rtx ref)
{
if (GET_CODE (ref) != MEM)
return ref;
@@ -648,28 +592,17 @@ validize_mem (ref)
appropriate. */
void
-maybe_set_unchanging (ref, t)
- rtx ref;
- tree t;
+maybe_set_unchanging (rtx ref, tree t)
{
/* We can set RTX_UNCHANGING_P from TREE_READONLY for decls whose
initialization is only executed once, or whose initializer always
has the same value. Currently we simplify this to PARM_DECLs in the
- first case, and decls with TREE_CONSTANT initializers in the second.
-
- We cannot do this for non-static aggregates, because of the double
- writes that can be generated by store_constructor, depending on the
- contents of the initializer. Yes, this does eliminate a good fraction
- of the number of uses of RTX_UNCHANGING_P for a language like Ada.
- It also eliminates a good quantity of bugs. Let this be incentive to
- eliminate RTX_UNCHANGING_P entirely in favour of a more reliable
- solution, perhaps based on alias sets. */
+ first case, and decls with TREE_CONSTANT initializers in the second. */
if ((TREE_READONLY (t) && DECL_P (t)
- && (TREE_STATIC (t) || ! AGGREGATE_TYPE_P (TREE_TYPE (t)))
- && (TREE_CODE (t) == PARM_DECL
- || DECL_INITIAL (t) == NULL_TREE
- || TREE_CONSTANT (DECL_INITIAL (t))))
+ && (DECL_EXTERNAL (t)
+ || TREE_CODE (t) == PARM_DECL
+ || (DECL_INITIAL (t) && TREE_CONSTANT (DECL_INITIAL (t)))))
|| TREE_CODE_CLASS (TREE_CODE (t)) == 'c')
RTX_UNCHANGING_P (ref) = 1;
}
@@ -680,10 +613,8 @@ maybe_set_unchanging (ref, t)
Perhaps even if it is a MEM, if there is no need to change it. */
rtx
-stabilize (x)
- rtx x;
+stabilize (rtx x)
{
-
if (GET_CODE (x) != MEM
|| ! rtx_unstable_p (XEXP (x, 0)))
return x;
@@ -695,8 +626,7 @@ stabilize (x)
/* Copy the value or contents of X to a new temp reg and return that reg. */
rtx
-copy_to_reg (x)
- rtx x;
+copy_to_reg (rtx x)
{
rtx temp = gen_reg_rtx (GET_MODE (x));
@@ -715,8 +645,7 @@ copy_to_reg (x)
in case X is a constant. */
rtx
-copy_addr_to_reg (x)
- rtx x;
+copy_addr_to_reg (rtx x)
{
return copy_to_mode_reg (Pmode, x);
}
@@ -725,9 +654,7 @@ copy_addr_to_reg (x)
in case X is a constant. */
rtx
-copy_to_mode_reg (mode, x)
- enum machine_mode mode;
- rtx x;
+copy_to_mode_reg (enum machine_mode mode, rtx x)
{
rtx temp = gen_reg_rtx (mode);
@@ -752,9 +679,7 @@ copy_to_mode_reg (mode, x)
since we mark it as a "constant" register. */
rtx
-force_reg (mode, x)
- enum machine_mode mode;
- rtx x;
+force_reg (enum machine_mode mode, rtx x)
{
rtx temp, insn, set;
@@ -784,7 +709,8 @@ force_reg (mode, x)
if INSN set something else (such as a SUBREG of TEMP). */
if (CONSTANT_P (x)
&& (set = single_set (insn)) != 0
- && SET_DEST (set) == temp)
+ && SET_DEST (set) == temp
+ && ! rtx_equal_p (x, SET_SRC (set)))
set_unique_reg_note (insn, REG_EQUAL, x);
return temp;
@@ -794,8 +720,7 @@ force_reg (mode, x)
that reg. Otherwise, return X. */
rtx
-force_not_mem (x)
- rtx x;
+force_not_mem (rtx x)
{
rtx temp;
@@ -812,9 +737,7 @@ force_not_mem (x)
MODE is the mode to use for X in case it is a constant. */
rtx
-copy_to_suggested_reg (x, target, mode)
- rtx x, target;
- enum machine_mode mode;
+copy_to_suggested_reg (rtx x, rtx target, enum machine_mode mode)
{
rtx temp;
@@ -834,11 +757,8 @@ copy_to_suggested_reg (x, target, mode)
FOR_CALL is nonzero if this call is promoting args for a call. */
enum machine_mode
-promote_mode (type, mode, punsignedp, for_call)
- tree type;
- enum machine_mode mode;
- int *punsignedp;
- int for_call ATTRIBUTE_UNUSED;
+promote_mode (tree type, enum machine_mode mode, int *punsignedp,
+ int for_call ATTRIBUTE_UNUSED)
{
enum tree_code code = TREE_CODE (type);
int unsignedp = *punsignedp;
@@ -877,8 +797,7 @@ promote_mode (type, mode, punsignedp, for_call)
This pops when ADJUST is positive. ADJUST need not be constant. */
void
-adjust_stack (adjust)
- rtx adjust;
+adjust_stack (rtx adjust)
{
rtx temp;
adjust = protect_from_queue (adjust, 0);
@@ -908,8 +827,7 @@ adjust_stack (adjust)
This pushes when ADJUST is positive. ADJUST need not be constant. */
void
-anti_adjust_stack (adjust)
- rtx adjust;
+anti_adjust_stack (rtx adjust)
{
rtx temp;
adjust = protect_from_queue (adjust, 0);
@@ -939,15 +857,17 @@ anti_adjust_stack (adjust)
by this machine. SIZE is the desired size, which need not be constant. */
rtx
-round_push (size)
- rtx size;
+round_push (rtx size)
{
int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
+
if (align == 1)
return size;
+
if (GET_CODE (size) == CONST_INT)
{
- int new = (INTVAL (size) + align - 1) / align * align;
+ HOST_WIDE_INT new = (INTVAL (size) + align - 1) / align * align;
+
if (INTVAL (size) != new)
size = GEN_INT (new);
}
@@ -962,6 +882,7 @@ round_push (size)
NULL_RTX, 1);
size = expand_mult (Pmode, size, GEN_INT (align), NULL_RTX, 1);
}
+
return size;
}
@@ -974,14 +895,11 @@ round_push (size)
are emitted at the current position. */
void
-emit_stack_save (save_level, psave, after)
- enum save_level save_level;
- rtx *psave;
- rtx after;
+emit_stack_save (enum save_level save_level, rtx *psave, rtx after)
{
rtx sa = *psave;
/* The default is that we use a move insn and save in a Pmode object. */
- rtx (*fcn) PARAMS ((rtx, rtx)) = gen_move_insn;
+ rtx (*fcn) (rtx, rtx) = gen_move_insn;
enum machine_mode mode = STACK_SAVEAREA_MODE (save_level);
/* See if this machine has anything special to do for this kind of save. */
@@ -1057,13 +975,10 @@ emit_stack_save (save_level, psave, after)
current position. */
void
-emit_stack_restore (save_level, sa, after)
- enum save_level save_level;
- rtx after;
- rtx sa;
+emit_stack_restore (enum save_level save_level, rtx sa, rtx after)
{
/* The default is that we use a move insn. */
- rtx (*fcn) PARAMS ((rtx, rtx)) = gen_move_insn;
+ rtx (*fcn) (rtx, rtx) = gen_move_insn;
/* See if this machine has anything special to do for this kind of save. */
switch (save_level)
@@ -1097,7 +1012,7 @@ emit_stack_restore (save_level, sa, after)
references to variable arrays below the code
that deletes (pops) the arrays. */
emit_insn (gen_rtx_CLOBBER (VOIDmode,
- gen_rtx_MEM (BLKmode,
+ gen_rtx_MEM (BLKmode,
gen_rtx_SCRATCH (VOIDmode))));
emit_insn (gen_rtx_CLOBBER (VOIDmode,
gen_rtx_MEM (BLKmode, stack_pointer_rtx)));
@@ -1124,8 +1039,7 @@ emit_stack_restore (save_level, sa, after)
frame, thus causing a crash if a longjmp unwinds to it. */
void
-optimize_save_area_alloca (insns)
- rtx insns;
+optimize_save_area_alloca (rtx insns)
{
rtx insn;
@@ -1209,10 +1123,7 @@ optimize_save_area_alloca (insns)
KNOWN_ALIGN is the alignment (in bits) that we know SIZE has. */
rtx
-allocate_dynamic_stack_space (size, target, known_align)
- rtx size;
- rtx target;
- int known_align;
+allocate_dynamic_stack_space (rtx size, rtx target, int known_align)
{
#ifdef SETJMP_VIA_SAVE_AREA
rtx setjmpless_size = NULL_RTX;
@@ -1373,7 +1284,7 @@ allocate_dynamic_stack_space (size, target, known_align)
pred = insn_data[(int) CODE_FOR_allocate_stack].operand[1].predicate;
if (pred && ! ((*pred) (size, mode)))
- size = copy_to_mode_reg (mode, size);
+ size = copy_to_mode_reg (mode, convert_to_mode (mode, size, 1));
emit_insn (gen_allocate_stack (target, size));
}
@@ -1443,13 +1354,6 @@ allocate_dynamic_stack_space (size, target, known_align)
NULL_RTX, 1);
}
- /* Some systems require a particular insn to refer to the stack
- to make the pages exist. */
-#ifdef HAVE_probe
- if (HAVE_probe)
- emit_insn (gen_probe ());
-#endif
-
/* Record the new stack level for nonlocal gotos. */
if (nonlocal_goto_handler_slots != 0)
emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
@@ -1464,8 +1368,7 @@ allocate_dynamic_stack_space (size, target, known_align)
static GTY(()) rtx stack_check_libfunc;
void
-set_stack_check_libfunc (libfunc)
- rtx libfunc;
+set_stack_check_libfunc (rtx libfunc)
{
stack_check_libfunc = libfunc;
}
@@ -1473,8 +1376,7 @@ set_stack_check_libfunc (libfunc)
/* Emit one stack probe at ADDRESS, an address within the stack. */
static void
-emit_stack_probe (address)
- rtx address;
+emit_stack_probe (rtx address)
{
rtx memref = gen_rtx_MEM (word_mode, address);
@@ -1499,9 +1401,7 @@ emit_stack_probe (address)
#endif
void
-probe_stack_range (first, size)
- HOST_WIDE_INT first;
- rtx size;
+probe_stack_range (HOST_WIDE_INT first, rtx size)
{
/* First ensure SIZE is Pmode. */
if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode)
@@ -1516,11 +1416,7 @@ probe_stack_range (first, size)
stack_pointer_rtx,
plus_constant (size, first)));
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (addr) != ptr_mode)
- addr = convert_memory_address (ptr_mode, addr);
-#endif
-
+ addr = convert_memory_address (ptr_mode, addr);
emit_library_call (stack_check_libfunc, LCT_NORMAL, VOIDmode, 1, addr,
ptr_mode);
}
@@ -1591,13 +1487,13 @@ probe_stack_range (first, size)
|| REGNO (test_addr) < FIRST_PSEUDO_REGISTER)
test_addr = force_reg (Pmode, test_addr);
- emit_note (NULL, NOTE_INSN_LOOP_BEG);
+ emit_note (NOTE_INSN_LOOP_BEG);
emit_jump (test_lab);
emit_label (loop_lab);
emit_stack_probe (test_addr);
- emit_note (NULL, NOTE_INSN_LOOP_CONT);
+ emit_note (NOTE_INSN_LOOP_CONT);
#ifdef STACK_GROWS_DOWNWARD
#define CMP_OPCODE GTU
@@ -1616,7 +1512,7 @@ probe_stack_range (first, size)
emit_cmp_and_jump_insns (test_addr, last_addr, CMP_OPCODE,
NULL_RTX, Pmode, 1, loop_lab);
emit_jump (end_lab);
- emit_note (NULL, NOTE_INSN_LOOP_END);
+ emit_note (NOTE_INSN_LOOP_END);
emit_label (end_lab);
emit_stack_probe (last_addr);
@@ -1633,10 +1529,8 @@ probe_stack_range (first, size)
and 0 otherwise. */
rtx
-hard_function_value (valtype, func, outgoing)
- tree valtype;
- tree func ATTRIBUTE_UNUSED;
- int outgoing ATTRIBUTE_UNUSED;
+hard_function_value (tree valtype, tree func ATTRIBUTE_UNUSED,
+ int outgoing ATTRIBUTE_UNUSED)
{
rtx val;
@@ -1679,8 +1573,7 @@ hard_function_value (valtype, func, outgoing)
in which a scalar value of mode MODE was returned by a library call. */
rtx
-hard_libcall_value (mode)
- enum machine_mode mode;
+hard_libcall_value (enum machine_mode mode)
{
return LIBCALL_VALUE (mode);
}
@@ -1691,8 +1584,7 @@ hard_libcall_value (mode)
what `enum tree_code' means. */
int
-rtx_to_tree_code (code)
- enum rtx_code code;
+rtx_to_tree_code (enum rtx_code code)
{
enum tree_code tcode;
OpenPOWER on IntegriCloud