Commit 980e61bb by Daniel Jacobowitz Committed by Daniel Jacobowitz

arm.c: Include "debug.h".

	* config/arm/arm.c: Include "debug.h".
	(thumb_pushpop): Take two new arguments.  Add some commentary.
	Output frame information when pushing.
	(thumb_exit, thumb_unexpanded_epilogue): Update calls to
	thumb_pushpop.
	(thumb_output_function_prologue): Likewise.  Accumulate a CFA
	offset, and pass it to thumb_pushpop.  Output CFI information.
	(thumb_expand_prologue): Add some frame-related markers and notes.

From-SVN: r76362
parent 0067d121
2004-01-22 Daniel Jacobowitz <drow@mvista.com>
* config/arm/arm.c: Include "debug.h".
(thumb_pushpop): Take two new arguments. Add some commentary.
Output frame information when pushing.
(thumb_exit, thumb_unexpanded_epilogue): Update calls to
thumb_pushpop.
(thumb_output_function_prologue): Likewise. Accumulate a CFA
offset, and pass it to thumb_pushpop. Output CFI information.
(thumb_expand_prologue): Add some frame-related markers and notes.
2004-01-22 Ulrich Weigand <uweigand@de.ibm.com> 2004-01-22 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/s390.c (s390_frame_info): Allow large frame sizes * config/s390/s390.c (s390_frame_info): Allow large frame sizes
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "tm_p.h" #include "tm_p.h"
#include "target.h" #include "target.h"
#include "target-def.h" #include "target-def.h"
#include "debug.h"
/* Forward definitions of types. */ /* Forward definitions of types. */
typedef struct minipool_node Mnode; typedef struct minipool_node Mnode;
...@@ -85,7 +86,7 @@ static struct machine_function *arm_init_machine_status (void); ...@@ -85,7 +86,7 @@ static struct machine_function *arm_init_machine_status (void);
static int number_of_first_bit_set (int); static int number_of_first_bit_set (int);
static void replace_symbols_in_block (tree, rtx, rtx); static void replace_symbols_in_block (tree, rtx, rtx);
static void thumb_exit (FILE *, int, rtx); static void thumb_exit (FILE *, int, rtx);
static void thumb_pushpop (FILE *, int, int); static void thumb_pushpop (FILE *, int, int, int *, int);
static rtx is_jump_table (rtx); static rtx is_jump_table (rtx);
static HOST_WIDE_INT get_jump_table_size (rtx); static HOST_WIDE_INT get_jump_table_size (rtx);
static Mnode *move_minipool_fix_forward_ref (Mnode *, Mnode *, HOST_WIDE_INT); static Mnode *move_minipool_fix_forward_ref (Mnode *, Mnode *, HOST_WIDE_INT);
...@@ -11562,7 +11563,8 @@ thumb_exit (FILE *f, int reg_containing_return_addr, rtx eh_ofs) ...@@ -11562,7 +11563,8 @@ thumb_exit (FILE *f, int reg_containing_return_addr, rtx eh_ofs)
} }
/* Pop as many registers as we can. */ /* Pop as many registers as we can. */
thumb_pushpop (f, regs_available_for_popping, FALSE); thumb_pushpop (f, regs_available_for_popping, FALSE, NULL,
regs_available_for_popping);
/* Process the registers we popped. */ /* Process the registers we popped. */
if (reg_containing_return_addr == -1) if (reg_containing_return_addr == -1)
...@@ -11643,7 +11645,8 @@ thumb_exit (FILE *f, int reg_containing_return_addr, rtx eh_ofs) ...@@ -11643,7 +11645,8 @@ thumb_exit (FILE *f, int reg_containing_return_addr, rtx eh_ofs)
int popped_into; int popped_into;
int move_to; int move_to;
thumb_pushpop (f, regs_available_for_popping, FALSE); thumb_pushpop (f, regs_available_for_popping, FALSE, NULL,
regs_available_for_popping);
/* We have popped either FP or SP. /* We have popped either FP or SP.
Move whichever one it is into the correct register. */ Move whichever one it is into the correct register. */
...@@ -11663,7 +11666,8 @@ thumb_exit (FILE *f, int reg_containing_return_addr, rtx eh_ofs) ...@@ -11663,7 +11666,8 @@ thumb_exit (FILE *f, int reg_containing_return_addr, rtx eh_ofs)
{ {
int popped_into; int popped_into;
thumb_pushpop (f, regs_available_for_popping, FALSE); thumb_pushpop (f, regs_available_for_popping, FALSE, NULL,
regs_available_for_popping);
popped_into = number_of_first_bit_set (regs_available_for_popping); popped_into = number_of_first_bit_set (regs_available_for_popping);
...@@ -11693,12 +11697,20 @@ thumb_exit (FILE *f, int reg_containing_return_addr, rtx eh_ofs) ...@@ -11693,12 +11697,20 @@ thumb_exit (FILE *f, int reg_containing_return_addr, rtx eh_ofs)
asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr); asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
} }
/* Emit code to push or pop registers to or from the stack. */ /* Emit code to push or pop registers to or from the stack. F is the
assembly file. MASK is the registers to push or pop. PUSH is
non-zero if we should push, and zero if we should pop. For debugging
output, if pushing, adjust CFA_OFFSET by the amount of space added
to the stack. REAL_REGS should have the same number of bits set as
MASK, and will be used instead (in the same order) to describe which
registers were saved - this is used to mark the save slots when we
push high registers after moving them to low registers. */
static void static void
thumb_pushpop (FILE *f, int mask, int push) thumb_pushpop (FILE *f, int mask, int push, int *cfa_offset, int real_regs)
{ {
int regno; int regno;
int lo_mask = mask & 0xFF; int lo_mask = mask & 0xFF;
int pushed_words = 0;
if (lo_mask == 0 && !push && (mask & (1 << 15))) if (lo_mask == 0 && !push && (mask & (1 << 15)))
{ {
...@@ -11719,6 +11731,8 @@ thumb_pushpop (FILE *f, int mask, int push) ...@@ -11719,6 +11731,8 @@ thumb_pushpop (FILE *f, int mask, int push)
if ((lo_mask & ~1) != 0) if ((lo_mask & ~1) != 0)
fprintf (f, ", "); fprintf (f, ", ");
pushed_words++;
} }
} }
...@@ -11729,6 +11743,8 @@ thumb_pushpop (FILE *f, int mask, int push) ...@@ -11729,6 +11743,8 @@ thumb_pushpop (FILE *f, int mask, int push)
fprintf (f, ", "); fprintf (f, ", ");
asm_fprintf (f, "%r", LR_REGNUM); asm_fprintf (f, "%r", LR_REGNUM);
pushed_words++;
} }
else if (!push && (mask & (1 << PC_REGNUM))) else if (!push && (mask & (1 << PC_REGNUM)))
{ {
...@@ -11753,6 +11769,23 @@ thumb_pushpop (FILE *f, int mask, int push) ...@@ -11753,6 +11769,23 @@ thumb_pushpop (FILE *f, int mask, int push)
} }
fprintf (f, "}\n"); fprintf (f, "}\n");
if (push && pushed_words && dwarf2out_do_frame ())
{
char *l = dwarf2out_cfi_label ();
int pushed_mask = real_regs;
*cfa_offset += pushed_words * 4;
dwarf2out_def_cfa (l, SP_REGNUM, *cfa_offset);
pushed_words = 0;
pushed_mask = real_regs;
for (regno = 0; regno <= 14; regno++, pushed_mask >>= 1)
{
if (pushed_mask & 1)
dwarf2out_reg_save (l, regno, 4 * pushed_words++ - *cfa_offset);
}
}
} }
void void
...@@ -11951,7 +11984,7 @@ thumb_unexpanded_epilogue (void) ...@@ -11951,7 +11984,7 @@ thumb_unexpanded_epilogue (void)
mask &= (2 << regno) - 1; /* A noop if regno == 8 */ mask &= (2 << regno) - 1; /* A noop if regno == 8 */
/* Pop the values into the low register(s). */ /* Pop the values into the low register(s). */
thumb_pushpop (asm_out_file, mask, 0); thumb_pushpop (asm_out_file, mask, 0, NULL, mask);
/* Move the value(s) into the high registers. */ /* Move the value(s) into the high registers. */
for (regno = 0; regno <= LAST_LO_REGNUM; regno++) for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
...@@ -11993,7 +12026,8 @@ thumb_unexpanded_epilogue (void) ...@@ -11993,7 +12026,8 @@ thumb_unexpanded_epilogue (void)
structure was created which includes an adjusted stack structure was created which includes an adjusted stack
pointer, so just pop everything. */ pointer, so just pop everything. */
if (live_regs_mask) if (live_regs_mask)
thumb_pushpop (asm_out_file, live_regs_mask, FALSE); thumb_pushpop (asm_out_file, live_regs_mask, FALSE, NULL,
live_regs_mask);
if (eh_ofs) if (eh_ofs)
thumb_exit (asm_out_file, 2, eh_ofs); thumb_exit (asm_out_file, 2, eh_ofs);
...@@ -12013,11 +12047,13 @@ thumb_unexpanded_epilogue (void) ...@@ -12013,11 +12047,13 @@ thumb_unexpanded_epilogue (void)
live_regs_mask &= ~(1 << PC_REGNUM); live_regs_mask &= ~(1 << PC_REGNUM);
if (live_regs_mask) if (live_regs_mask)
thumb_pushpop (asm_out_file, live_regs_mask, FALSE); thumb_pushpop (asm_out_file, live_regs_mask, FALSE, NULL,
live_regs_mask);
if (had_to_push_lr) if (had_to_push_lr)
/* Get the return address into a temporary register. */ /* Get the return address into a temporary register. */
thumb_pushpop (asm_out_file, 1 << LAST_ARG_REGNUM, 0); thumb_pushpop (asm_out_file, 1 << LAST_ARG_REGNUM, 0, NULL,
1 << LAST_ARG_REGNUM);
/* Remove the argument registers that were pushed onto the stack. */ /* Remove the argument registers that were pushed onto the stack. */
asm_fprintf (asm_out_file, "\tadd\t%r, %r, #%d\n", asm_fprintf (asm_out_file, "\tadd\t%r, %r, #%d\n",
...@@ -12163,6 +12199,8 @@ thumb_get_frame_size (void) ...@@ -12163,6 +12199,8 @@ thumb_get_frame_size (void)
void void
thumb_expand_prologue (void) thumb_expand_prologue (void)
{ {
rtx insn, dwarf;
HOST_WIDE_INT amount = (thumb_get_frame_size () HOST_WIDE_INT amount = (thumb_get_frame_size ()
+ current_function_outgoing_args_size); + current_function_outgoing_args_size);
unsigned long func_type; unsigned long func_type;
...@@ -12180,15 +12218,21 @@ thumb_expand_prologue (void) ...@@ -12180,15 +12218,21 @@ thumb_expand_prologue (void)
} }
if (frame_pointer_needed) if (frame_pointer_needed)
emit_insn (gen_movsi (hard_frame_pointer_rtx, stack_pointer_rtx)); {
insn = emit_insn (gen_movsi (hard_frame_pointer_rtx, stack_pointer_rtx));
RTX_FRAME_RELATED_P (insn) = 1;
}
if (amount) if (amount)
{ {
amount = ROUND_UP_WORD (amount); amount = ROUND_UP_WORD (amount);
if (amount < 512) if (amount < 512)
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, {
GEN_INT (- amount))); insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
GEN_INT (- amount)));
RTX_FRAME_RELATED_P (insn) = 1;
}
else else
{ {
int regno; int regno;
...@@ -12228,8 +12272,16 @@ thumb_expand_prologue (void) ...@@ -12228,8 +12272,16 @@ thumb_expand_prologue (void)
/* Decrement the stack. */ /* Decrement the stack. */
emit_insn (gen_movsi (reg, GEN_INT (- amount))); emit_insn (gen_movsi (reg, GEN_INT (- amount)));
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
reg)); stack_pointer_rtx, reg));
RTX_FRAME_RELATED_P (insn) = 1;
dwarf = gen_rtx_SET (SImode, stack_pointer_rtx,
plus_constant (stack_pointer_rtx,
GEN_INT (- amount)));
RTX_FRAME_RELATED_P (dwarf) = 1;
REG_NOTES (insn)
= gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
REG_NOTES (insn));
/* Restore the low register's original value. */ /* Restore the low register's original value. */
emit_insn (gen_movsi (reg, spare)); emit_insn (gen_movsi (reg, spare));
...@@ -12245,8 +12297,17 @@ thumb_expand_prologue (void) ...@@ -12245,8 +12297,17 @@ thumb_expand_prologue (void)
reg = gen_rtx (REG, SImode, regno); reg = gen_rtx (REG, SImode, regno);
emit_insn (gen_movsi (reg, GEN_INT (- amount))); emit_insn (gen_movsi (reg, GEN_INT (- amount)));
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
reg)); insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
stack_pointer_rtx, reg));
RTX_FRAME_RELATED_P (insn) = 1;
dwarf = gen_rtx_SET (SImode, stack_pointer_rtx,
plus_constant (stack_pointer_rtx,
GEN_INT (- amount)));
RTX_FRAME_RELATED_P (dwarf) = 1;
REG_NOTES (insn)
= gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
REG_NOTES (insn));
} }
} }
} }
...@@ -12307,6 +12368,7 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED) ...@@ -12307,6 +12368,7 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{ {
int live_regs_mask = 0; int live_regs_mask = 0;
int high_regs_pushed = 0; int high_regs_pushed = 0;
int cfa_offset = 0;
int regno; int regno;
if (IS_NAKED (arm_current_func_type ())) if (IS_NAKED (arm_current_func_type ()))
...@@ -12369,6 +12431,16 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED) ...@@ -12369,6 +12431,16 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
asm_fprintf (f, "\tsub\t%r, %r, #%d\n", asm_fprintf (f, "\tsub\t%r, %r, #%d\n",
SP_REGNUM, SP_REGNUM, SP_REGNUM, SP_REGNUM,
current_function_pretend_args_size); current_function_pretend_args_size);
/* We don't need to record the stores for unwinding (would it
help the debugger any if we did?), but record the change in
the stack pointer. */
if (dwarf2out_do_frame ())
{
char *l = dwarf2out_cfi_label ();
cfa_offset = cfa_offset + current_function_pretend_args_size;
dwarf2out_def_cfa (l, SP_REGNUM, cfa_offset);
}
} }
for (regno = 0; regno <= LAST_LO_REGNUM; regno++) for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
...@@ -12424,9 +12496,16 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED) ...@@ -12424,9 +12496,16 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
asm_fprintf asm_fprintf
(f, "\tsub\t%r, %r, #16\t%@ Create stack backtrace structure\n", (f, "\tsub\t%r, %r, #16\t%@ Create stack backtrace structure\n",
SP_REGNUM, SP_REGNUM); SP_REGNUM, SP_REGNUM);
if (dwarf2out_do_frame ())
{
char *l = dwarf2out_cfi_label ();
cfa_offset = cfa_offset + 16;
dwarf2out_def_cfa (l, SP_REGNUM, cfa_offset);
}
if (live_regs_mask) if (live_regs_mask)
thumb_pushpop (f, live_regs_mask, 1); thumb_pushpop (f, live_regs_mask, 1, &cfa_offset, live_regs_mask);
for (offset = 0, wr = 1 << 15; wr != 0; wr >>= 1) for (offset = 0, wr = 1 << 15; wr != 0; wr >>= 1)
if (wr & live_regs_mask) if (wr & live_regs_mask)
...@@ -12470,7 +12549,7 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED) ...@@ -12470,7 +12549,7 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
ARM_HARD_FRAME_POINTER_REGNUM, work_register); ARM_HARD_FRAME_POINTER_REGNUM, work_register);
} }
else if (live_regs_mask) else if (live_regs_mask)
thumb_pushpop (f, live_regs_mask, 1); thumb_pushpop (f, live_regs_mask, 1, &cfa_offset, live_regs_mask);
for (regno = 8; regno < 13; regno++) for (regno = 8; regno < 13; regno++)
if (THUMB_REG_PUSHED_P (regno)) if (THUMB_REG_PUSHED_P (regno))
...@@ -12498,6 +12577,8 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED) ...@@ -12498,6 +12577,8 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
while (high_regs_pushed > 0) while (high_regs_pushed > 0)
{ {
int real_regs_mask = 0;
for (regno = LAST_LO_REGNUM; regno >= 0; regno--) for (regno = LAST_LO_REGNUM; regno >= 0; regno--)
{ {
if (mask & (1 << regno)) if (mask & (1 << regno))
...@@ -12505,6 +12586,7 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED) ...@@ -12505,6 +12586,7 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
asm_fprintf (f, "\tmov\t%r, %r\n", regno, next_hi_reg); asm_fprintf (f, "\tmov\t%r, %r\n", regno, next_hi_reg);
high_regs_pushed--; high_regs_pushed--;
real_regs_mask |= (1 << next_hi_reg);
if (high_regs_pushed) if (high_regs_pushed)
{ {
...@@ -12520,8 +12602,8 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED) ...@@ -12520,8 +12602,8 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
} }
} }
} }
thumb_pushpop (f, mask, 1); thumb_pushpop (f, mask, 1, &cfa_offset, real_regs_mask);
} }
if (pushable_regs == 0 if (pushable_regs == 0
......
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