diff options
author | Joern Rennecke <joern.rennecke@embecosm.com> | 2013-04-08 12:22:41 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 2013-04-08 13:22:41 +0100 |
commit | 3b088b475ae0a65236db759996dce4406b6abb70 (patch) | |
tree | 9bf68a745c02f6be1adfd6e016b1d38fe3f5151d /gcc | |
parent | d8484d41e41682c4a0a21b6e8ab8270a6db226a6 (diff) | |
download | gcc-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/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/config/epiphany/epiphany.c | 46 | ||||
-rw-r--r-- | gcc/config/epiphany/epiphany.h | 1 | ||||
-rw-r--r-- | gcc/config/epiphany/epiphany.md | 9 |
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); }) |