Pārlūkot izejas kodu

cell: fix function prologue/epilogue code for large stack frames

The ai instruction is limited to a 10-bit signed immediate value.
tags/mesa_20090313
Brian Paul pirms 17 gadiem
vecāks
revīzija
53ae243869
1 mainītis faili ar 37 papildinājumiem un 7 dzēšanām
  1. 37
    7
      src/gallium/drivers/cell/ppu/cell_gen_fp.c

+ 37
- 7
src/gallium/drivers/cell/ppu/cell_gen_fp.c Parādīt failu

@@ -369,18 +369,36 @@ store_dest_reg(struct codegen *gen,
static void
emit_prologue(struct codegen *gen)
{
gen->frame_size = 1024; /* XXX temporary */
gen->frame_size = 1024; /* XXX temporary, should be dynamic */

spe_comment(gen->f, -4, "Function prologue:");

/* save $lr on stack # stqd $lr,16($sp) */
spe_stqd(gen->f, SPE_REG_RA, SPE_REG_SP, 16);

/* save stack pointer # stqd $sp,-frameSize($sp) */
spe_stqd(gen->f, SPE_REG_SP, SPE_REG_SP, -gen->frame_size);
if (gen->frame_size >= 512) {
/* offset is too large for ai instruction */
int offset_reg = spe_allocate_available_register(gen->f);
int sp_reg = spe_allocate_available_register(gen->f);
/* offset = -framesize */
spe_load_int(gen->f, offset_reg, -gen->frame_size);
/* sp = $sp */
spe_move(gen->f, sp_reg, SPE_REG_SP);
/* $sp = $sp + offset_reg */
spe_a(gen->f, SPE_REG_SP, SPE_REG_SP, offset_reg);
/* save $sp in stack frame */
spe_stqd(gen->f, sp_reg, SPE_REG_SP, 0);
/* clean up */
spe_release_register(gen->f, offset_reg);
spe_release_register(gen->f, sp_reg);
}
else {
/* save stack pointer # stqd $sp,-frameSize($sp) */
spe_stqd(gen->f, SPE_REG_SP, SPE_REG_SP, -gen->frame_size);

/* adjust stack pointer # ai $sp,$sp,-frameSize */
spe_ai(gen->f, SPE_REG_SP, SPE_REG_SP, -gen->frame_size);
/* adjust stack pointer # ai $sp,$sp,-frameSize */
spe_ai(gen->f, SPE_REG_SP, SPE_REG_SP, -gen->frame_size);
}
}


@@ -389,8 +407,20 @@ emit_epilogue(struct codegen *gen)
{
spe_comment(gen->f, -4, "Function epilogue:");

/* restore stack pointer # ai $sp,$sp,frameSize */
spe_ai(gen->f, SPE_REG_SP, SPE_REG_SP, gen->frame_size);
if (gen->frame_size >= 512) {
/* offset is too large for ai instruction */
int offset_reg = spe_allocate_available_register(gen->f);
/* offset = framesize */
spe_load_int(gen->f, offset_reg, gen->frame_size);
/* $sp = $sp + offset */
spe_a(gen->f, SPE_REG_SP, SPE_REG_SP, offset_reg);
/* clean up */
spe_release_register(gen->f, offset_reg);
}
else {
/* restore stack pointer # ai $sp,$sp,frameSize */
spe_ai(gen->f, SPE_REG_SP, SPE_REG_SP, gen->frame_size);
}

/* restore $lr # lqd $lr,16($sp) */
spe_lqd(gen->f, SPE_REG_RA, SPE_REG_SP, 16);

Notiek ielāde…
Atcelt
Saglabāt