aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJoern Rennecke <joern.rennecke@embecosm.com>2013-04-08 12:22:41 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2013-04-08 13:22:41 +0100
commit3b088b475ae0a65236db759996dce4406b6abb70 (patch)
tree9bf68a745c02f6be1adfd6e016b1d38fe3f5151d /gcc
parentd8484d41e41682c4a0a21b6e8ab8270a6db226a6 (diff)
downloadgcc-3b088b475ae0a65236db759996dce4406b6abb70.zip
gcc-3b088b475ae0a65236db759996dce4406b6abb70.tar.gz
gcc-3b088b475ae0a65236db759996dce4406b6abb70.tar.bz2
epiphany.h (struct GTY (()) machine_function): Add member lr_slot_known.
* config/epiphany/epiphany.h (struct GTY (()) machine_function): Add member lr_slot_known. * config/epiphany/epiphany.md (reload_insi_ra): Compute lr_slot_offs if necessary. * config/epiphany/epiphany.c (epiphany_compute_frame_size): Remove code that sets lr_slot_offset according to what a previous version of epiphany_emit_save_restore used to do. (epiphany_emit_save_restore): When doing an lr save or restore, set/verify lr_slot_known and lr_slot_offset. From-SVN: r197577
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/epiphany/epiphany.c46
-rw-r--r--gcc/config/epiphany/epiphany.h1
-rw-r--r--gcc/config/epiphany/epiphany.md9
4 files changed, 44 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b915a6f..c16ea07 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2013-04-08 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * config/epiphany/epiphany.h (struct GTY (()) machine_function):
+ Add member lr_slot_known.
+ * config/epiphany/epiphany.md (reload_insi_ra): Compute lr_slot_offs
+ if necessary.
+ * config/epiphany/epiphany.c (epiphany_compute_frame_size):
+ Remove code that sets lr_slot_offset according to what a previous
+ version of epiphany_emit_save_restore used to do.
+ (epiphany_emit_save_restore): When doing an lr save or restore,
+ set/verify lr_slot_known and lr_slot_offset.
+
2013-04-08 Xinyu Qi <xyqi@marvell.com>
PR target/54338
diff --git a/gcc/config/epiphany/epiphany.c b/gcc/config/epiphany/epiphany.c
index 5520a63..9fec199 100644
--- a/gcc/config/epiphany/epiphany.c
+++ b/gcc/config/epiphany/epiphany.c
@@ -964,7 +964,6 @@ epiphany_compute_frame_size (int size /* # of var. bytes allocated. */)
int first_slot, last_slot, first_slot_offset, last_slot_offset;
int first_slot_size;
int small_slots = 0;
- long lr_slot_offset;
var_size = size;
args_size = crtl->outgoing_args_size;
@@ -1116,28 +1115,6 @@ epiphany_compute_frame_size (int size /* # of var. bytes allocated. */)
}
total_size = first_slot_offset + last_slot_offset;
- lr_slot_offset
- = (frame_pointer_needed ? first_slot_offset : (long) total_size);
- if (first_slot != GPR_LR)
- {
- int stack_offset = epiphany_stack_offset - UNITS_PER_WORD;
-
- for (regno = 0; ; regno++)
- {
- if (stack_offset + UNITS_PER_WORD - first_slot_size == 0
- && first_slot >= 0)
- {
- stack_offset -= first_slot_size;
- regno--;
- }
- else if (regno == GPR_LR)
- break;
- else if TEST_HARD_REG_BIT (gmask, regno)
- stack_offset -= UNITS_PER_WORD;
- }
- lr_slot_offset += stack_offset;
- }
-
/* Save computed information. */
current_frame_info.total_size = total_size;
current_frame_info.pretend_size = pretend_size;
@@ -1150,7 +1127,6 @@ epiphany_compute_frame_size (int size /* # of var. bytes allocated. */)
current_frame_info.first_slot_offset = first_slot_offset;
current_frame_info.first_slot_size = first_slot_size;
current_frame_info.last_slot_offset = last_slot_offset;
- MACHINE_FUNCTION (cfun)->lr_slot_offset = lr_slot_offset;
current_frame_info.initialized = reload_completed;
@@ -1622,6 +1598,28 @@ epiphany_emit_save_restore (int min, int limit, rtx addr, int epilogue_p)
mem = skipped_mem;
else
mem = gen_mem (mode, addr);
+
+ /* If we are loading / storing LR, note the offset that
+ gen_reload_insi_ra requires. Since GPR_LR is even,
+ we only need to test n, even if mode is DImode. */
+ gcc_assert ((GPR_LR & 1) == 0);
+ if (n == GPR_LR)
+ {
+ long lr_slot_offset = 0;
+ rtx m_addr = XEXP (mem, 0);
+
+ if (GET_CODE (m_addr) == PLUS)
+ lr_slot_offset = INTVAL (XEXP (m_addr, 1));
+ if (frame_pointer_needed)
+ lr_slot_offset += (current_frame_info.first_slot_offset
+ - current_frame_info.total_size);
+ if (MACHINE_FUNCTION (cfun)->lr_slot_known)
+ gcc_assert (MACHINE_FUNCTION (cfun)->lr_slot_offset
+ == lr_slot_offset);
+ MACHINE_FUNCTION (cfun)->lr_slot_offset = lr_slot_offset;
+ MACHINE_FUNCTION (cfun)->lr_slot_known = 1;
+ }
+
if (!epilogue_p)
frame_move_insn (mem, reg);
else if (n >= MAX_EPIPHANY_PARM_REGS || !crtl->args.pretend_args_size)
diff --git a/gcc/config/epiphany/epiphany.h b/gcc/config/epiphany/epiphany.h
index 42b1630..1e5c305 100644
--- a/gcc/config/epiphany/epiphany.h
+++ b/gcc/config/epiphany/epiphany.h
@@ -450,6 +450,7 @@ typedef struct GTY (()) machine_function
unsigned pretend_args_odd : 1;
unsigned lr_clobbered : 1;
unsigned control_use_inserted : 1;
+ unsigned lr_slot_known : 1;
unsigned sw_entities_processed : 6;
long lr_slot_offset;
rtx and_mask;
diff --git a/gcc/config/epiphany/epiphany.md b/gcc/config/epiphany/epiphany.md
index 6375d3f..8037277 100644
--- a/gcc/config/epiphany/epiphany.md
+++ b/gcc/config/epiphany/epiphany.md
@@ -264,6 +264,15 @@
rtx addr
= (frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx);
+ if (!MACHINE_FUNCTION (cfun)->lr_slot_known)
+ {
+ start_sequence ();
+ epiphany_expand_prologue ();
+ if (!MACHINE_FUNCTION (cfun)->lr_slot_known)
+ epiphany_expand_epilogue (0);
+ end_sequence ();
+ gcc_assert (MACHINE_FUNCTION (cfun)->lr_slot_known);
+ }
addr = plus_constant (Pmode, addr, MACHINE_FUNCTION (cfun)->lr_slot_offset);
operands[1] = gen_frame_mem (SImode, addr);
})