Implement saving of dirty registers onto the stack.
This commit is contained in:
parent
6a06ce798b
commit
1e17921208
|
@ -2,6 +2,25 @@
|
||||||
|
|
||||||
void pass_add_prologue_epilogue(void)
|
void pass_add_prologue_epilogue(void)
|
||||||
{
|
{
|
||||||
|
int i, j, k;
|
||||||
|
|
||||||
|
current_proc->usedregs.count = 0;
|
||||||
|
for (i=0; i<cfg.preorder.count; i++)
|
||||||
|
{
|
||||||
|
struct basicblock* bb = cfg.preorder.item[i];
|
||||||
|
|
||||||
|
for (j=0; j<bb->hops.count; j++)
|
||||||
|
{
|
||||||
|
struct hop* hop = bb->hops.item[j];
|
||||||
|
|
||||||
|
for (k=0; k<hop->regsin.count; k++)
|
||||||
|
array_appendu(¤t_proc->usedregs, hop->regsin.item[k].left);
|
||||||
|
|
||||||
|
for (k=0; k<hop->regsout.count; k++)
|
||||||
|
array_appendu(¤t_proc->usedregs, hop->regsout.item[k].left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
platform_calculate_offsets();
|
platform_calculate_offsets();
|
||||||
|
|
||||||
array_insert(¤t_proc->entry->hops, platform_prologue(), 0);
|
array_insert(¤t_proc->entry->hops, platform_prologue(), 0);
|
||||||
|
|
|
@ -15,8 +15,25 @@
|
||||||
* st indexes up; lb indexes down.
|
* st indexes up; lb indexes down.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static ARRAYOF(struct hreg) saved_regs;
|
||||||
|
|
||||||
void platform_calculate_offsets(void)
|
void platform_calculate_offsets(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
saved_regs.count = 0;
|
||||||
|
for (i=0; i<current_proc->usedregs.count; i++)
|
||||||
|
{
|
||||||
|
struct hreg* hreg = current_proc->usedregs.item[i];
|
||||||
|
|
||||||
|
if (!(hreg->attrs & burm_volatile_ATTR) &&
|
||||||
|
((hreg->attrs & burm_int_ATTR) || (hreg->attrs & burm_float_ATTR)))
|
||||||
|
{
|
||||||
|
current_proc->saved_size += 4;
|
||||||
|
array_append(&saved_regs, hreg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
current_proc->fp_to_st = 0;
|
current_proc->fp_to_st = 0;
|
||||||
current_proc->fp_to_ab = current_proc->spills_size + current_proc->saved_size + 8;
|
current_proc->fp_to_ab = current_proc->spills_size + current_proc->saved_size + 8;
|
||||||
current_proc->fp_to_lb = 0;
|
current_proc->fp_to_lb = 0;
|
||||||
|
@ -24,6 +41,8 @@ void platform_calculate_offsets(void)
|
||||||
|
|
||||||
struct hop* platform_prologue(void)
|
struct hop* platform_prologue(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
int saved_offset;
|
||||||
struct hop* hop = new_hop(current_proc->entry, NULL);
|
struct hop* hop = new_hop(current_proc->entry, NULL);
|
||||||
|
|
||||||
hop_add_insel(hop, "! saved_size = %d+8 bytes", current_proc->saved_size);
|
hop_add_insel(hop, "! saved_size = %d+8 bytes", current_proc->saved_size);
|
||||||
|
@ -31,18 +50,47 @@ struct hop* platform_prologue(void)
|
||||||
hop_add_insel(hop, "! locals_size = %d bytes", current_proc->locals_size);
|
hop_add_insel(hop, "! locals_size = %d bytes", current_proc->locals_size);
|
||||||
hop_add_insel(hop, "addi sp, sp, %d", -(current_proc->fp_to_ab + current_proc->locals_size));
|
hop_add_insel(hop, "addi sp, sp, %d", -(current_proc->fp_to_ab + current_proc->locals_size));
|
||||||
hop_add_insel(hop, "mfspr r0, lr");
|
hop_add_insel(hop, "mfspr r0, lr");
|
||||||
hop_add_insel(hop, "stw fp, %d(sp)", current_proc->fp_to_st + current_proc->locals_size);
|
|
||||||
hop_add_insel(hop, "stw r0, %d(sp)", current_proc->fp_to_st + current_proc->locals_size + 4);
|
hop_add_insel(hop, "stw r0, %d(sp)", current_proc->locals_size + current_proc->spills_size);
|
||||||
|
hop_add_insel(hop, "stw fp, %d(sp)", current_proc->locals_size + current_proc->spills_size + 4);
|
||||||
hop_add_insel(hop, "addi fp, sp, %d", current_proc->locals_size);
|
hop_add_insel(hop, "addi fp, sp, %d", current_proc->locals_size);
|
||||||
|
|
||||||
|
saved_offset = current_proc->spills_size + 8;
|
||||||
|
for (i=0; i<saved_regs.count; i++)
|
||||||
|
{
|
||||||
|
struct hreg* hreg = saved_regs.item[i];
|
||||||
|
if (hreg->type & burm_int_ATTR)
|
||||||
|
hop_add_insel(hop, "stw %H, %d(fp)", hreg, saved_offset);
|
||||||
|
else if (hreg->type & burm_float_ATTR)
|
||||||
|
hop_add_insel(hop, "stfs %H, %d(fp)", hreg, saved_offset);
|
||||||
|
saved_offset += 4;
|
||||||
|
}
|
||||||
return hop;
|
return hop;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hop* platform_epilogue(void)
|
struct hop* platform_epilogue(void)
|
||||||
{
|
{
|
||||||
struct hop* hop = new_hop(current_proc->exit, NULL);
|
struct hop* hop = new_hop(current_proc->exit, NULL);
|
||||||
|
int i;
|
||||||
|
int saved_offset;
|
||||||
|
|
||||||
hop_add_insel(hop, "b .ret");
|
saved_offset = current_proc->spills_size + 8;
|
||||||
|
for (i=0; i<saved_regs.count; i++)
|
||||||
|
{
|
||||||
|
struct hreg* hreg = saved_regs.item[i];
|
||||||
|
if (hreg->type & burm_int_ATTR)
|
||||||
|
hop_add_insel(hop, "lwz %H, %d(fp)", hreg, saved_offset);
|
||||||
|
else if (hreg->type & burm_float_ATTR)
|
||||||
|
hop_add_insel(hop, "lfs %H, %d(fp)", hreg, saved_offset);
|
||||||
|
saved_offset += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
hop_add_insel(hop, "lwz r0, %d(fp)", current_proc->spills_size);
|
||||||
|
hop_add_insel(hop, "mtspr lr, r0");
|
||||||
|
hop_add_insel(hop, "lwz r0, %d(fp)", current_proc->spills_size + 4);
|
||||||
|
hop_add_insel(hop, "addi sp, fp, %d", current_proc->fp_to_ab);
|
||||||
|
hop_add_insel(hop, "mr fp, r0");
|
||||||
|
hop_add_insel(hop, "blr");
|
||||||
|
|
||||||
return hop;
|
return hop;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ struct procedure
|
||||||
int fp_to_lb;
|
int fp_to_lb;
|
||||||
ARRAYOF(struct basicblock) blocks;
|
ARRAYOF(struct basicblock) blocks;
|
||||||
IMAPOF(struct local) locals;
|
IMAPOF(struct local) locals;
|
||||||
|
ARRAYOF(struct hreg) usedregs;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void procedure_compile(struct procedure* proc);
|
extern void procedure_compile(struct procedure* proc);
|
||||||
|
|
Loading…
Reference in a new issue