summaryrefslogtreecommitdiff
path: root/gcc/explow.c
diff options
context:
space:
mode:
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>1995-04-03 22:12:15 +0000
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>1995-04-03 22:12:15 +0000
commit184aad037f876153e00e92f3dd474ac1181cba5f (patch)
tree31991151d1cb4fc5c94764fba5cfde60362d6b01 /gcc/explow.c
parent1bbb1e248fd8ec2f407bfc4c20378385423750b8 (diff)
downloadgcc-184aad037f876153e00e92f3dd474ac1181cba5f.tar.gz
(convert_memory_address): New function.
(memory_address): Call if it needed. (promote_mode, case POINTER_TYPE): Use Pmode and pointer extension. (allocate_dynamic_stack_space): Convert size from ptr_mode. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@9304 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/explow.c')
-rw-r--r--gcc/explow.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/gcc/explow.c b/gcc/explow.c
index e6dc5f96fe1..ac73f4b4afd 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -29,6 +29,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "insn-flags.h"
#include "insn-codes.h"
+static rtx break_out_memory_refs PROTO((rtx));
+static rtx convert_memory_address PROTO((rtx));
+
/* Return an rtx for the sum of X and the integer C.
This function should be used via the `plus_constant' macro. */
@@ -288,6 +291,38 @@ 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. We take advantage of the fact that pointers are not
+ allowed to overflow by commuting arithmetic operations over
+ conversions so that address arithmetic insns can be used. */
+
+static rtx
+convert_memory_address (x)
+ rtx x;
+{
+ switch (GET_CODE (x))
+ {
+ case CONST_INT:
+ case CONST_DOUBLE:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST:
+ return x;
+
+ case PLUS:
+ case MULT:
+ return gen_rtx (GET_CODE (x), Pmode,
+ convert_memory_address (XEXP (x, 0)),
+ convert_memory_address (XEXP (x, 1)));
+
+ default:
+ return convert_modes (Pmode, ptr_mode, x, 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.
@@ -338,6 +373,11 @@ memory_address (mode, x)
{
register rtx oldx = x;
+#ifdef POINTERS_EXTEND_UNSIGNED
+ if (GET_MODE (x) == ptr_mode)
+ x = convert_memory_address (x);
+#endif
+
/* By passing constant addresses thru registers
we get a chance to cse them. */
if (! cse_not_expected && CONSTANT_P (x) && CONSTANT_ADDRESS_P (x))
@@ -667,8 +707,12 @@ promote_mode (type, mode, punsignedp, for_call)
break;
#endif
+#ifdef POINTERS_EXTEND_UNSIGNED
case POINTER_TYPE:
+ mode = Pmode;
+ unsignedp = POINTERS_EXTEND_UNSIGNED;
break;
+#endif
}
*punsignedp = unsignedp;
@@ -1026,6 +1070,8 @@ allocate_dynamic_stack_space (size, target, known_align)
enum machine_mode mode
= insn_operand_mode[(int) CODE_FOR_allocate_stack][0];
+ size = convert_modes (mode, ptr_mode, size, 1);
+
if (insn_operand_predicate[(int) CODE_FOR_allocate_stack][0]
&& ! ((*insn_operand_predicate[(int) CODE_FOR_allocate_stack][0])
(size, mode)))
@@ -1035,7 +1081,10 @@ allocate_dynamic_stack_space (size, target, known_align)
}
else
#endif
- anti_adjust_stack (size);
+ {
+ size = convert_modes (Pmode, ptr_mode, size, 1);
+ anti_adjust_stack (size);
+ }
#ifdef STACK_GROWS_DOWNWARD
emit_move_insn (target, virtual_stack_dynamic_rtx);