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:
parent
fc437ce97f
commit
2591db658c
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue