aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2004-01-23 14:24:58 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2004-01-23 14:24:58 +0100
commit72613dfaa22b438aa161bad3a92e87984148ae0d (patch)
treef67cbdcb1cbea103fe639e0b587f59e241edefb3 /gcc
parent7be4d808ffd3bb0bab32a4882fe7db2dd9aac379 (diff)
downloadgcc-72613dfaa22b438aa161bad3a92e87984148ae0d.zip
gcc-72613dfaa22b438aa161bad3a92e87984148ae0d.tar.gz
gcc-72613dfaa22b438aa161bad3a92e87984148ae0d.tar.bz2
* i386.c (ix86_emit_restore_regs_using_mov): Deal with large offsets.
From-SVN: r76416
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/config/i386/i386.c21
2 files changed, 21 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 99f3135..e1c07a0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+2003-11-30 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_emit_restore_regs_using_mov): Deal with large offsets.
+
2004-01-23 J"orn Rennecke <joern.rennecke@superh.com>
* doc/tm.texi: Insert some weasel words when LOAD_EXTEND_OP
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b7c7008..0cad3f1 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -808,7 +808,7 @@ static int ix86_split_to_parts (rtx, rtx *, enum machine_mode);
static int ix86_nsaved_regs (void);
static void ix86_emit_save_regs (void);
static void ix86_emit_save_regs_using_mov (rtx, HOST_WIDE_INT);
-static void ix86_emit_restore_regs_using_mov (rtx, int, int);
+static void ix86_emit_restore_regs_using_mov (rtx, HOST_WIDE_INT, int);
static void ix86_output_function_epilogue (FILE *, HOST_WIDE_INT);
static void ix86_set_move_mem_attrs_1 (rtx, rtx, rtx, rtx, rtx);
static void ix86_sched_reorder_ppro (rtx *, rtx *);
@@ -5278,16 +5278,29 @@ ix86_expand_prologue (void)
/* Emit code to restore saved registers using MOV insns. First register
is restored from POINTER + OFFSET. */
static void
-ix86_emit_restore_regs_using_mov (rtx pointer, int offset, int maybe_eh_return)
+ix86_emit_restore_regs_using_mov (rtx pointer, HOST_WIDE_INT offset,
+ int maybe_eh_return)
{
int regno;
+ rtx base_address = gen_rtx_MEM (Pmode, pointer);
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (ix86_save_reg (regno, maybe_eh_return))
{
+ /* Ensure that adjust_address won't be forced to produce pointer
+ out of range allowed by x86-64 instruction set. */
+ if (TARGET_64BIT && offset != trunc_int_for_mode (offset, SImode))
+ {
+ rtx r11;
+
+ r11 = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 3 /* R11 */);
+ emit_move_insn (r11, GEN_INT (offset));
+ emit_insn (gen_adddi3 (r11, r11, pointer));
+ base_address = gen_rtx_MEM (Pmode, r11);
+ offset = 0;
+ }
emit_move_insn (gen_rtx_REG (Pmode, regno),
- adjust_address (gen_rtx_MEM (Pmode, pointer),
- Pmode, offset));
+ adjust_address (base_address, Pmode, offset));
offset += UNITS_PER_WORD;
}
}