Commit 2591db65 by Richard Earnshaw Committed by Richard Earnshaw

arm.h (arm_stack_offsets): Add locals_base field.

	* arm.h (arm_stack_offsets): Add locals_base field.
	* arm.c (arm_get_frame_offsets): Compute it.
	(thumb_compute_initial_elimination offset): Make the Thumb frame
	pointer point to the base of the local variables.
	(thumb_expand_prologue): Update accordingly.
	(thumb_expand_epilogue): Likewise.

	* arm.md (thumb_movhi_clobber): Make this insn a define_expand.  Change
	mode of clobbered scratch to DImode.  Handle a case that's known to
	need this.

From-SVN: r103301
parent fc437ce9
2005-08-20 Richard Earnshaw <richard.earnshaw@arm.com>
* arm.h (arm_stack_offsets): Add locals_base field.
* arm.c (arm_get_frame_offsets): Compute it.
(thumb_compute_initial_elimination offset): Make the Thumb frame
pointer point to the base of the local variables.
(thumb_expand_prologue): Update accordingly.
(thumb_expand_epilogue): Likewise.
* arm.md (thumb_movhi_clobber): Make this insn a define_expand. Change
mode of clobbered scratch to DImode. Handle a case that's known to
need this.
2005-08-19 David Edelsohn <edelsohn@gnu.org> 2005-08-19 David Edelsohn <edelsohn@gnu.org>
* config/rs6000/rs6000.md (gt0<mode>): Delete. * config/rs6000/rs6000.md (gt0<mode>): Delete.
......
...@@ -9992,7 +9992,7 @@ thumb_force_lr_save (void) ...@@ -9992,7 +9992,7 @@ thumb_force_lr_save (void)
| | \ | | \
| | local | | local
| | variables | | variables
| | / locals base pointer -> | | /
-- --
| | \ | | \
| | outgoing | | outgoing
...@@ -10109,8 +10109,9 @@ arm_get_frame_offsets (void) ...@@ -10109,8 +10109,9 @@ arm_get_frame_offsets (void)
&& (offsets->soft_frame & 7)) && (offsets->soft_frame & 7))
offsets->soft_frame += 4; offsets->soft_frame += 4;
offsets->outgoing_args = offsets->soft_frame + frame_size offsets->locals_base = offsets->soft_frame + frame_size;
+ current_function_outgoing_args_size; offsets->outgoing_args = (offsets->locals_base
+ current_function_outgoing_args_size);
if (ARM_DOUBLEWORD_ALIGN) if (ARM_DOUBLEWORD_ALIGN)
{ {
...@@ -13158,8 +13159,10 @@ arm_init_expanders (void) ...@@ -13158,8 +13159,10 @@ arm_init_expanders (void)
} }
/* Like arm_compute_initial_elimination offset. Simpler because /* Like arm_compute_initial_elimination offset. Simpler because there
THUMB_HARD_FRAME_POINTER isn't actually the ABI specified frame pointer. */ isn't an ABI specified frame pointer for Thumb. Instead, we set it
to point at the base of the local variables after static stack
space for a function has been allocated. */
HOST_WIDE_INT HOST_WIDE_INT
thumb_compute_initial_elimination_offset (unsigned int from, unsigned int to) thumb_compute_initial_elimination_offset (unsigned int from, unsigned int to)
...@@ -13179,10 +13182,12 @@ thumb_compute_initial_elimination_offset (unsigned int from, unsigned int to) ...@@ -13179,10 +13182,12 @@ thumb_compute_initial_elimination_offset (unsigned int from, unsigned int to)
case FRAME_POINTER_REGNUM: case FRAME_POINTER_REGNUM:
return offsets->soft_frame - offsets->saved_args; return offsets->soft_frame - offsets->saved_args;
case THUMB_HARD_FRAME_POINTER_REGNUM:
case ARM_HARD_FRAME_POINTER_REGNUM: case ARM_HARD_FRAME_POINTER_REGNUM:
return offsets->saved_regs - offsets->saved_args; return offsets->saved_regs - offsets->saved_args;
case THUMB_HARD_FRAME_POINTER_REGNUM:
return offsets->locals_base - offsets->saved_args;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
...@@ -13194,10 +13199,12 @@ thumb_compute_initial_elimination_offset (unsigned int from, unsigned int to) ...@@ -13194,10 +13199,12 @@ thumb_compute_initial_elimination_offset (unsigned int from, unsigned int to)
case STACK_POINTER_REGNUM: case STACK_POINTER_REGNUM:
return offsets->outgoing_args - offsets->soft_frame; return offsets->outgoing_args - offsets->soft_frame;
case THUMB_HARD_FRAME_POINTER_REGNUM:
case ARM_HARD_FRAME_POINTER_REGNUM: case ARM_HARD_FRAME_POINTER_REGNUM:
return offsets->saved_regs - offsets->soft_frame; return offsets->saved_regs - offsets->soft_frame;
case THUMB_HARD_FRAME_POINTER_REGNUM:
return offsets->locals_base - offsets->soft_frame;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
...@@ -13239,18 +13246,11 @@ thumb_expand_prologue (void) ...@@ -13239,18 +13246,11 @@ thumb_expand_prologue (void)
if (flag_pic) if (flag_pic)
arm_load_pic_register (live_regs_mask); arm_load_pic_register (live_regs_mask);
offsets = arm_get_frame_offsets (); if (!frame_pointer_needed && CALLER_INTERWORKING_SLOT_SIZE > 0)
if (frame_pointer_needed)
{
insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
stack_pointer_rtx));
RTX_FRAME_RELATED_P (insn) = 1;
}
else if (CALLER_INTERWORKING_SLOT_SIZE > 0)
emit_move_insn (gen_rtx_REG (Pmode, ARM_HARD_FRAME_POINTER_REGNUM), emit_move_insn (gen_rtx_REG (Pmode, ARM_HARD_FRAME_POINTER_REGNUM),
stack_pointer_rtx); stack_pointer_rtx);
offsets = arm_get_frame_offsets ();
amount = offsets->outgoing_args - offsets->saved_regs; amount = offsets->outgoing_args - offsets->saved_regs;
if (amount) if (amount)
{ {
...@@ -13336,12 +13336,29 @@ thumb_expand_prologue (void) ...@@ -13336,12 +13336,29 @@ thumb_expand_prologue (void)
REG_NOTES (insn)); REG_NOTES (insn));
} }
} }
/* If the frame pointer is needed, emit a special barrier that }
will prevent the scheduler from moving stores to the frame
before the stack adjustment. */
if (frame_pointer_needed) if (frame_pointer_needed)
emit_insn (gen_stack_tie (stack_pointer_rtx, {
hard_frame_pointer_rtx)); amount = offsets->outgoing_args - offsets->locals_base;
if (amount < 1024)
insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
stack_pointer_rtx, GEN_INT (amount)));
else
{
emit_insn (gen_movsi (hard_frame_pointer_rtx, GEN_INT (amount)));
insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
hard_frame_pointer_rtx,
stack_pointer_rtx));
dwarf = gen_rtx_SET (SImode, hard_frame_pointer_rtx,
plus_constant (stack_pointer_rtx, amount));
RTX_FRAME_RELATED_P (dwarf) = 1;
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
REG_NOTES (insn));
}
RTX_FRAME_RELATED_P (insn) = 1;
} }
if (current_function_profile || !TARGET_SCHED_PROLOG) if (current_function_profile || !TARGET_SCHED_PROLOG)
...@@ -13373,8 +13390,12 @@ thumb_expand_epilogue (void) ...@@ -13373,8 +13390,12 @@ thumb_expand_epilogue (void)
amount = offsets->outgoing_args - offsets->saved_regs; amount = offsets->outgoing_args - offsets->saved_regs;
if (frame_pointer_needed) if (frame_pointer_needed)
{
emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx)); emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
else if (amount) amount = offsets->locals_base - offsets->saved_regs;
}
if (amount)
{ {
if (amount < 512) if (amount < 512)
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
......
...@@ -1476,6 +1476,7 @@ typedef struct arm_stack_offsets GTY(()) ...@@ -1476,6 +1476,7 @@ typedef struct arm_stack_offsets GTY(())
int frame; /* ARM_HARD_FRAME_POINTER_REGNUM. */ int frame; /* ARM_HARD_FRAME_POINTER_REGNUM. */
int saved_regs; int saved_regs;
int soft_frame; /* FRAME_POINTER_REGNUM. */ int soft_frame; /* FRAME_POINTER_REGNUM. */
int locals_base; /* THUMB_HARD_FRAME_POINTER_REGNUM. */
int outgoing_args; /* STACK_POINTER_REGNUM. */ int outgoing_args; /* STACK_POINTER_REGNUM. */
} }
arm_stack_offsets; arm_stack_offsets;
......
...@@ -4951,13 +4951,21 @@ ...@@ -4951,13 +4951,21 @@
[(set_attr "predicable" "yes")] [(set_attr "predicable" "yes")]
) )
(define_insn "thumb_movhi_clobber" (define_expand "thumb_movhi_clobber"
[(set (match_operand:HI 0 "memory_operand" "=m") [(set (match_operand:HI 0 "memory_operand" "")
(match_operand:HI 1 "register_operand" "l")) (match_operand:HI 1 "register_operand" ""))
(clobber (match_operand:SI 2 "register_operand" "=&l"))] (clobber (match_operand:DI 2 "register_operand" ""))]
"TARGET_THUMB" "TARGET_THUMB"
"* "
gcc_unreachable ();" if (strict_memory_address_p (HImode, XEXP (operands[0], 0))
&& REGNO (operands[1]) <= LAST_LO_REGNUM)
{
emit_insn (gen_movhi (operands[0], operands[1]));
DONE;
}
/* XXX Fixme, need to handle other cases here as well. */
gcc_unreachable ();
"
) )
;; We use a DImode scratch because we may occasionally need an additional ;; We use a DImode scratch because we may occasionally need an additional
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment