Mesa (gallium-0.2): cell: fix function prologue/ epilogue code for large stack frames

Brian Paul brianp at kemper.freedesktop.org
Fri Oct 10 20:58:21 UTC 2008


Module: Mesa
Branch: gallium-0.2
Commit: 53ae243869a9e1ff0f2b1c559ec51adff867b970
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=53ae243869a9e1ff0f2b1c559ec51adff867b970

Author: Brian Paul <brian.paul at tungstengraphics.com>
Date:   Fri Oct 10 14:34:43 2008 -0600

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

The ai instruction is limited to a 10-bit signed immediate value.

---

 src/gallium/drivers/cell/ppu/cell_gen_fp.c |   44 +++++++++++++++++++++++----
 1 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fp.c b/src/gallium/drivers/cell/ppu/cell_gen_fp.c
index db54c7e..3d0e797 100644
--- a/src/gallium/drivers/cell/ppu/cell_gen_fp.c
+++ b/src/gallium/drivers/cell/ppu/cell_gen_fp.c
@@ -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);




More information about the mesa-commit mailing list