summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Schleef <ds@ginger.bigkitten.com>2008-05-16 21:10:21 -0700
committerDavid Schleef <ds@ginger.bigkitten.com>2008-05-16 21:10:21 -0700
commitabcbb3b826a3f00d1d87fb63500ad6204f8692a7 (patch)
treec8477d321a08282ee5d87c2f2819389ba7db877c
parent7653940717d0fadc8dd3157b624b66fc0210ca1a (diff)
downloadliboil-abcbb3b826a3f00d1d87fb63500ad6204f8692a7.tar.gz
[orc] keep track of registers that are used, in order to save/restore
only those registers
-rw-r--r--orc/orcprogram-x86.c24
-rw-r--r--orc/orcprogram.c1
-rw-r--r--orc/orcprogram.h2
3 files changed, 21 insertions, 6 deletions
diff --git a/orc/orcprogram-x86.c b/orc/orcprogram-x86.c
index 64b2381..16f1579 100644
--- a/orc/orcprogram-x86.c
+++ b/orc/orcprogram-x86.c
@@ -95,17 +95,29 @@ x86_emit_prologue (OrcProgram *program)
g_print("test:\n");
x86_emit_push (program, 4, X86_EBP);
x86_emit_mov_memoffset_reg (program, 4, 8, X86_ESP, X86_EBP);
- x86_emit_push (program, 4, X86_EDI);
- x86_emit_push (program, 4, X86_ESI);
- x86_emit_push (program, 4, X86_EBX);
+ if (program->used_regs[x86_get_regnum(X86_EDI)]) {
+ x86_emit_push (program, 4, X86_EDI);
+ }
+ if (program->used_regs[x86_get_regnum(X86_ESI)]) {
+ x86_emit_push (program, 4, X86_ESI);
+ }
+ if (program->used_regs[x86_get_regnum(X86_EBX)]) {
+ x86_emit_push (program, 4, X86_EBX);
+ }
}
void
x86_emit_epilogue (OrcProgram *program)
{
- x86_emit_pop (program, 4, X86_EBX);
- x86_emit_pop (program, 4, X86_ESI);
- x86_emit_pop (program, 4, X86_EDI);
+ if (program->used_regs[x86_get_regnum(X86_EBX)]) {
+ x86_emit_pop (program, 4, X86_EBX);
+ }
+ if (program->used_regs[x86_get_regnum(X86_ESI)]) {
+ x86_emit_pop (program, 4, X86_ESI);
+ }
+ if (program->used_regs[x86_get_regnum(X86_EDI)]) {
+ x86_emit_pop (program, 4, X86_EDI);
+ }
x86_emit_pop (program, 4, X86_EBP);
x86_emit_ret (program);
}
diff --git a/orc/orcprogram.c b/orc/orcprogram.c
index 591902d..a0244bc 100644
--- a/orc/orcprogram.c
+++ b/orc/orcprogram.c
@@ -207,6 +207,7 @@ orc_program_rewrite_vars (OrcProgram *program)
if (!alloc[k]) {
program->vars[i].alloc = k + ORC_GP_REG_BASE;
alloc[k] = 1;
+ program->used_regs[k] = 1;
break;
}
}
diff --git a/orc/orcprogram.h b/orc/orcprogram.h
index 2ef5671..42eb1a4 100644
--- a/orc/orcprogram.h
+++ b/orc/orcprogram.h
@@ -102,6 +102,8 @@ struct _OrcProgram {
unsigned char *labels[100];
int error;
+
+ int used_regs[8];
};
struct _OrcExecutor {