[Liboil-commit] 2 commits - orc/orcprogram-x86.c orc/orcprogram.c orc/orcprogram.h
David Schleef
ds at kemper.freedesktop.org
Sat May 17 10:20:11 PDT 2008
orc/orcprogram-x86.c | 37 +++++++++++++++++++++++++----------
orc/orcprogram.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++-----
orc/orcprogram.h | 6 +++++
3 files changed, 81 insertions(+), 15 deletions(-)
New commits:
commit db3dd6f982e20135e4702e2fcb47ad9face8ced4
Author: David Schleef <ds at ginger.bigkitten.com>
Date: Sat May 17 10:08:45 2008 -0700
[orc] implement register chaining
diff --git a/orc/orcprogram-x86.c b/orc/orcprogram-x86.c
index 16f1579..b32bd2c 100644
--- a/orc/orcprogram-x86.c
+++ b/orc/orcprogram-x86.c
@@ -136,7 +136,7 @@ x86_do_fixups (OrcProgram *program)
}
}
-static OrcRuleList *orc_x86_list;
+OrcRuleList *orc_x86_list;
void
orc_x86_init (void)
@@ -176,12 +176,17 @@ orc_program_compile_x86 (OrcProgram *program)
insn = program->insns + j;
opcode = insn->opcode;
- printf("# %d: %s\n", j, insn->opcode->name);
+ printf("# %d: %s", j, insn->opcode->name);
/* set up args */
for(k=0;k<opcode->n_src + opcode->n_dest;k++){
args[k] = program->vars + insn->args[k];
+ printf(" %d", args[k]->alloc);
+ if (args[k]->is_chained) {
+ printf(" (chained)");
+ }
}
+ printf("\n");
for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
switch (args[k]->vartype) {
@@ -205,9 +210,9 @@ orc_program_compile_x86 (OrcProgram *program)
}
}
- rule = orc_rule_list_get (orc_x86_list, opcode);
+ rule = insn->rule;
if (rule) {
- if (!(rule->flags & ORC_RULE_3REG) && insn->args[0] != insn->args[1]) {
+ if (!(rule->flags & ORC_RULE_3REG) && args[0]->alloc != args[1]->alloc) {
x86_emit_mov_reg_reg (program, 2, args[1]->alloc, args[0]->alloc);
}
rule->emit (program, rule->emit_user, insn);
diff --git a/orc/orcprogram.c b/orc/orcprogram.c
index a0244bc..f93a1b9 100644
--- a/orc/orcprogram.c
+++ b/orc/orcprogram.c
@@ -121,6 +121,17 @@ orc_program_append (OrcProgram *program, const char *name, int arg0,
program->n_insns++;
}
+void
+orc_program_assign_rules (OrcProgram *program)
+{
+ int i;
+
+ for(i=0;i<program->n_insns;i++) {
+ program->insns[i].rule = orc_rule_list_get (orc_x86_list,
+ program->insns[i].opcode);
+ }
+}
+
void
orc_program_rewrite_vars (OrcProgram *program)
@@ -134,6 +145,8 @@ orc_program_rewrite_vars (OrcProgram *program)
int actual_var;
int alloc[8] = { 0, 1, 0, 0, 1, 1, 0, 0 };
+ orc_program_assign_rules (program);
+
for(j=0;j<program->n_insns;j++){
insn = program->insns + j;
opcode = insn->opcode;
@@ -201,10 +214,39 @@ orc_program_rewrite_vars (OrcProgram *program)
}
for(j=0;j<program->n_insns;j++){
+#if 1
+ /* must be true to chain src1 to dest:
+ * - rule must handle it
+ * - src1 must be last_use
+ */
+ if (1 || program->insns[j].rule->flags & ORC_RULE_REG_REG) {
+ int src1 = program->insns[j].args[1];
+ int dest = program->insns[j].args[0];
+ if (program->vars[src1].last_use == j) {
+ if (program->vars[src1].first_use == j) {
+ for(k=0;k<8;k++){
+ if (alloc[k] == 0) {
+ program->vars[src1].alloc = k + ORC_GP_REG_BASE;
+ alloc[k] = 1;
+ program->used_regs[k] = 1;
+ break;
+ }
+ }
+ if (k==8) {
+ g_print("register overflow\n");
+ }
+ }
+ alloc[program->vars[src1].alloc - ORC_GP_REG_BASE]++;
+ program->vars[dest].alloc = program->vars[src1].alloc;
+ }
+ }
+#endif
+
for(i=0;i<program->n_vars;i++){
if (program->vars[i].first_use == j) {
+ if (program->vars[i].alloc) continue;
for(k=0;k<8;k++){
- if (!alloc[k]) {
+ if (alloc[k] == 0) {
program->vars[i].alloc = k + ORC_GP_REG_BASE;
alloc[k] = 1;
program->used_regs[k] = 1;
@@ -218,18 +260,18 @@ orc_program_rewrite_vars (OrcProgram *program)
}
for(i=0;i<program->n_vars;i++){
if (program->vars[i].last_use == j) {
- alloc[program->vars[i].alloc - ORC_GP_REG_BASE] = 0;
+ alloc[program->vars[i].alloc - ORC_GP_REG_BASE]--;
}
}
}
-#if 0
+#if 1
for(i=0;i<program->n_vars;i++){
- g_print("%2d: %2d %2d %s\n",
+ g_print("# %2d: %2d %2d %d\n",
i,
program->vars[i].first_use,
program->vars[i].last_use,
- x86_get_regname(program->vars[i].alloc));
+ program->vars[i].alloc);
}
#endif
diff --git a/orc/orcprogram.h b/orc/orcprogram.h
index 42eb1a4..bc7b3f3 100644
--- a/orc/orcprogram.h
+++ b/orc/orcprogram.h
@@ -44,6 +44,7 @@ struct _OrcVariable {
int replacement;
int alloc;
+ int is_chained;
int16_t s16;
};
@@ -104,6 +105,7 @@ struct _OrcProgram {
int error;
int used_regs[8];
+ int alloc_regs[8];
};
struct _OrcExecutor {
@@ -186,6 +188,8 @@ OrcRule * orc_rule_list_get (OrcRuleList *rule_list, OrcOpcode *opcode);
void orc_program_x86_register_rules (OrcRuleList *rule_list);
void orc_program_allocate_codemem (OrcProgram *program);
void orc_program_dump_code (OrcProgram *program);
+
+extern OrcRuleList *orc_x86_list;
#endif
commit abcbb3b826a3f00d1d87fb63500ad6204f8692a7
Author: David Schleef <ds at ginger.bigkitten.com>
Date: Fri May 16 21:10:21 2008 -0700
[orc] keep track of registers that are used, in order to save/restore
only those registers
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 {
More information about the Liboil-commit
mailing list