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>
* config/rs6000/rs6000.md (gt0<mode>): Delete.
......
......@@ -9992,7 +9992,7 @@ thumb_force_lr_save (void)
| | \
| | local
| | variables
| | /
locals base pointer -> | | /
--
| | \
| | outgoing
......@@ -10109,8 +10109,9 @@ arm_get_frame_offsets (void)
&& (offsets->soft_frame & 7))
offsets->soft_frame += 4;
offsets->outgoing_args = offsets->soft_frame + frame_size
+ current_function_outgoing_args_size;
offsets->locals_base = offsets->soft_frame + frame_size;
offsets->outgoing_args = (offsets->locals_base
+ current_function_outgoing_args_size);
if (ARM_DOUBLEWORD_ALIGN)
{
......@@ -13158,8 +13159,10 @@ arm_init_expanders (void)
}
/* Like arm_compute_initial_elimination offset. Simpler because
THUMB_HARD_FRAME_POINTER isn't actually the ABI specified frame pointer. */
/* Like arm_compute_initial_elimination offset. Simpler because there
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
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:
return offsets->soft_frame - offsets->saved_args;
case THUMB_HARD_FRAME_POINTER_REGNUM:
case ARM_HARD_FRAME_POINTER_REGNUM:
return offsets->saved_regs - offsets->saved_args;
case THUMB_HARD_FRAME_POINTER_REGNUM:
return offsets->locals_base - offsets->saved_args;
default:
gcc_unreachable ();
}
......@@ -13194,10 +13199,12 @@ thumb_compute_initial_elimination_offset (unsigned int from, unsigned int to)
case STACK_POINTER_REGNUM:
return offsets->outgoing_args - offsets->soft_frame;
case THUMB_HARD_FRAME_POINTER_REGNUM:
case ARM_HARD_FRAME_POINTER_REGNUM:
return offsets->saved_regs - offsets->soft_frame;
case THUMB_HARD_FRAME_POINTER_REGNUM:
return offsets->locals_base - offsets->soft_frame;
default:
gcc_unreachable ();
}
......@@ -13239,18 +13246,11 @@ thumb_expand_prologue (void)
if (flag_pic)
arm_load_pic_register (live_regs_mask);
offsets = arm_get_frame_offsets ();
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)
if (!frame_pointer_needed && CALLER_INTERWORKING_SLOT_SIZE > 0)
emit_move_insn (gen_rtx_REG (Pmode, ARM_HARD_FRAME_POINTER_REGNUM),
stack_pointer_rtx);
offsets = arm_get_frame_offsets ();
amount = offsets->outgoing_args - offsets->saved_regs;
if (amount)
{
......@@ -13336,12 +13336,29 @@ thumb_expand_prologue (void)
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)
emit_insn (gen_stack_tie (stack_pointer_rtx,
hard_frame_pointer_rtx));
}
if (frame_pointer_needed)
{
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)
......@@ -13373,8 +13390,12 @@ thumb_expand_epilogue (void)
amount = offsets->outgoing_args - offsets->saved_regs;
if (frame_pointer_needed)
emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
else if (amount)
{
emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
amount = offsets->locals_base - offsets->saved_regs;
}
if (amount)
{
if (amount < 512)
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
......
......@@ -1476,6 +1476,7 @@ typedef struct arm_stack_offsets GTY(())
int frame; /* ARM_HARD_FRAME_POINTER_REGNUM. */
int saved_regs;
int soft_frame; /* FRAME_POINTER_REGNUM. */
int locals_base; /* THUMB_HARD_FRAME_POINTER_REGNUM. */
int outgoing_args; /* STACK_POINTER_REGNUM. */
}
arm_stack_offsets;
......
......@@ -4951,13 +4951,21 @@
[(set_attr "predicable" "yes")]
)
(define_insn "thumb_movhi_clobber"
[(set (match_operand:HI 0 "memory_operand" "=m")
(match_operand:HI 1 "register_operand" "l"))
(clobber (match_operand:SI 2 "register_operand" "=&l"))]
(define_expand "thumb_movhi_clobber"
[(set (match_operand:HI 0 "memory_operand" "")
(match_operand:HI 1 "register_operand" ""))
(clobber (match_operand:DI 2 "register_operand" ""))]
"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
......
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