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
This commit is contained in:
Richard Earnshaw 2005-08-20 10:31:42 +00:00 committed by Richard Earnshaw
parent fc437ce97f
commit 2591db658c
4 changed files with 73 additions and 30 deletions

View File

@ -1,3 +1,16 @@
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.

View File

@ -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,

View File

@ -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;

View File

@ -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