summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Schleef <ds@ginger.bigkitten.com>2008-05-23 14:43:39 -0700
committerDavid Schleef <ds@ginger.bigkitten.com>2008-05-23 14:43:39 -0700
commit4f76bda40977c581691e47b2ae78334b3651c01f (patch)
treed818a01f2a91ffde49fab1a7e7d1590f2803e8a1
parent9e0b12b550bee13514aa194c4a7ccf043466b01f (diff)
downloadliboil-4f76bda40977c581691e47b2ae78334b3651c01f.tar.gz
[orc] attempt to make the same code work on all platforms
-rw-r--r--orc/orcprogram-powerpc.c4
-rw-r--r--orc/orcprogram-x86.c94
-rw-r--r--orc/orcprogram.c53
-rw-r--r--orc/orcprogram.h13
4 files changed, 122 insertions, 42 deletions
diff --git a/orc/orcprogram-powerpc.c b/orc/orcprogram-powerpc.c
index 2311899..8d22e38 100644
--- a/orc/orcprogram-powerpc.c
+++ b/orc/orcprogram-powerpc.c
@@ -57,7 +57,7 @@ enum {
POWERPC_R29,
POWERPC_R30,
POWERPC_R31,
- POWERPC_V0,
+ POWERPC_V0 = ORC_VEC1_REG_BASE,
POWERPC_V1,
POWERPC_V2,
POWERPC_V3,
@@ -350,7 +350,7 @@ orc_powerpc_init (void)
}
void
-orc_program_powerpc_reset_alloc (OrcProgram *program)
+orc_program_powerpc_init (OrcProgram *program)
{
int i;
diff --git a/orc/orcprogram-x86.c b/orc/orcprogram-x86.c
index d92db4b..bad1b51 100644
--- a/orc/orcprogram-x86.c
+++ b/orc/orcprogram-x86.c
@@ -62,19 +62,26 @@ enum {
X86_R13,
X86_R14,
X86_R15,
- X86_MM0,
+ X86_MM0 = ORC_VEC1_REG_BASE,
X86_MM1,
X86_MM2,
X86_MM3,
X86_MM4,
X86_MM5,
X86_MM6,
- X86_MM7
+ X86_MM7,
+ X86_XMM0 = ORC_VEC2_REG_BASE,
};
+#ifdef HAVE_X86_64
static int x86_64 = 1;
static int x86_ptr_size = 8;
static int x86_exec_ptr = X86_EDI;
+#else
+static int x86_64 = 0;
+static int x86_ptr_size = 4;
+static int x86_exec_ptr = X86_EBP;
+#endif
static const char *
@@ -91,6 +98,7 @@ x86_get_regname(int i)
case 1:
return "direct";
default:
+ printf("register %d\n", i);
return "ERROR";
}
}
@@ -167,30 +175,34 @@ int
orc_program_x86_allocate_register (OrcProgram *program, int data_reg)
{
int i;
+ int klass;
+ int offset;
- if (program->rule_set == ORC_RULE_SCALAR_1) {
- data_reg = FALSE;
+ if (data_reg) {
+ klass = program->data_register_class;
+ } else {
+ klass = ORC_REGCLASS_GP;
}
-
- if (!data_reg) {
- int n_regs = 8;
- if (x86_64) n_regs = 16;
- for(i=ORC_GP_REG_BASE;i<ORC_GP_REG_BASE+n_regs;i++){
- if (program->alloc_regs[i] == 0) {
- program->alloc_regs[i]++;
- program->used_regs[i] = 1;
- return i;
- }
+ offset = klass << 5;
+
+ for(i=offset;i<offset+32;i++){
+ if (program->valid_regs[i] &&
+ !program->save_regs[i] &&
+ program->alloc_regs[i] == 0) {
+ program->alloc_regs[i]++;
+ program->used_regs[i] = 1;
+ return i;
}
- } else {
- for(i=X86_MM0;i<X86_MM0+8;i++){
- if (program->alloc_regs[i] == 0) {
- program->alloc_regs[i]++;
- program->used_regs[i] = 1;
- return i;
- }
+ }
+ for(i=offset;i<offset+32;i++){
+ if (program->valid_regs[i] &&
+ program->alloc_regs[i] == 0) {
+ program->alloc_regs[i]++;
+ program->used_regs[i] = 1;
+ return i;
}
}
+
printf("register overflow\n");
return 0;
}
@@ -269,24 +281,40 @@ orc_x86_init (void)
}
void
-orc_program_x86_reset_alloc (OrcProgram *program)
+orc_program_x86_init (OrcProgram *program)
{
int i;
- for(i=ORC_GP_REG_BASE;i<ORC_GP_REG_BASE+16;i++){
+ if (x86_64) {
+ for(i=ORC_GP_REG_BASE;i<ORC_GP_REG_BASE+16;i++){
+ program->valid_regs[i] = 1;
+ }
+ program->valid_regs[X86_ECX] = 0;
+ program->valid_regs[X86_EDI] = 0;
+ program->valid_regs[X86_ESP] = 0;
+ for(i=X86_XMM0;i<X86_XMM0+16;i++){
+ program->valid_regs[i] = 1;
+ }
+ } else {
+ for(i=ORC_GP_REG_BASE;i<ORC_GP_REG_BASE+8;i++){
+ program->valid_regs[i] = 1;
+ }
+ program->valid_regs[X86_ECX] = 0;
+ program->valid_regs[X86_ESP] = 0;
+ program->valid_regs[X86_EBP] = 0;
+ for(i=X86_XMM0;i<X86_XMM0+8;i++){
+ program->valid_regs[i] = 1;
+ }
+ }
+ for(i=X86_MM0;i<X86_MM0+8;i++){
+ program->valid_regs[i] = 1;
+ }
+ for(i=0;i<128;i++){
program->alloc_regs[i] = 0;
+ program->used_regs[i] = 0;
}
- program->alloc_regs[X86_ECX] = 1;
- program->alloc_regs[X86_ESP] = 1;
- program->alloc_regs[X86_EBP] = 1;
- if (x86_64) {
- /* used for passing parameters */
- program->alloc_regs[X86_EDI] = 1;
- /* don't feel like saving */
- program->alloc_regs[X86_ESI] = 1;
- program->alloc_regs[X86_EBX] = 1;
- }
+ program->data_register_class = 2;
}
void
diff --git a/orc/orcprogram.c b/orc/orcprogram.c
index e0d64d0..30e595b 100644
--- a/orc/orcprogram.c
+++ b/orc/orcprogram.c
@@ -134,21 +134,55 @@ orc_program_append (OrcProgram *program, const char *name, int arg0,
int
orc_program_allocate_register (OrcProgram *program, int data_reg)
{
- if (program->rule_set == ORC_RULE_ALTIVEC_1) {
- return orc_program_powerpc_allocate_register (program, data_reg);
+ int i;
+ int klass;
+ int offset;
+
+ if (data_reg) {
+ klass = program->data_register_class;
} else {
- return orc_program_x86_allocate_register (program, data_reg);
+ klass = ORC_REGCLASS_GP;
+ }
+ offset = klass << 5;
+
+ for(i=offset;i<offset+32;i++){
+ if (program->valid_regs[i] &&
+ !program->save_regs[i] &&
+ program->alloc_regs[i] == 0) {
+ program->alloc_regs[i]++;
+ program->used_regs[i] = 1;
+ return i;
+ }
+ }
+ for(i=offset;i<offset+32;i++){
+ if (program->valid_regs[i] &&
+ program->alloc_regs[i] == 0) {
+ program->alloc_regs[i]++;
+ program->used_regs[i] = 1;
+ return i;
+ }
}
+
+ printf("register overflow\n");
+ return 0;
}
void
orc_program_compile (OrcProgram *program)
{
+#if defined(HAVE_POWERPC)
+ orc_program_powerpc_init (program);
+#elif defined(HAVE_I386)
+ orc_program_x86_init (program);
+#elif defined(HAVE_AMD64)
+ orc_program_x86_init (program);
+#else
+#error FIXME
+#endif
+
orc_program_assign_rules (program);
orc_program_rewrite_vars (program);
- orc_program_x86_reset_alloc (program);
- //orc_program_powerpc_reset_alloc (program);
orc_program_global_reg_alloc (program);
orc_program_do_regs (program);
@@ -156,8 +190,15 @@ orc_program_compile (OrcProgram *program)
orc_program_rewrite_vars2 (program);
orc_program_allocate_codemem (program);
+#if defined(HAVE_POWERPC)
+ orc_program_assemble_powerpc (program);
+#elif defined(HAVE_I386)
+ orc_program_assemble_x86 (program);
+#elif defined(HAVE_AMD64)
orc_program_assemble_x86 (program);
- //orc_program_assemble_powerpc (program);
+#else
+#error FIXME
+#endif
//orc_program_assemble_c (program);
orc_program_dump_code (program);
diff --git a/orc/orcprogram.h b/orc/orcprogram.h
index ab58ffc..5a02b83 100644
--- a/orc/orcprogram.h
+++ b/orc/orcprogram.h
@@ -25,6 +25,12 @@ typedef void (*OrcRuleEmitFunc)(OrcProgram *p, void *user, OrcInstruction *insn)
#define ORC_N_FIXUPS 100
#define ORC_N_LABELS 100
+#define ORC_GP_REG_BASE 32
+#define ORC_VEC1_REG_BASE 64
+#define ORC_VEC2_REG_BASE 96
+
+#define ORC_REGCLASS_GP 1
+
#define ORC_OPCODE_N_ARGS 4
#define ORC_OPCODE_N_RULES 8
@@ -161,6 +167,10 @@ struct _OrcProgram {
int error;
+ int data_register_class;
+
+ int valid_regs[ORC_N_REGS];
+ int save_regs[ORC_N_REGS];
int used_regs[ORC_N_REGS];
int alloc_regs[ORC_N_REGS];
@@ -190,7 +200,6 @@ enum {
ORC_RULE_REG_CL = (1<<6)
};
-#define ORC_GP_REG_BASE 32
void orc_init (void);
@@ -205,6 +214,8 @@ void orc_powerpc_init (void);
void orc_c_init (void);
void orc_program_compile (OrcProgram *p);
+void orc_program_x86_init (OrcProgram *p);
+void orc_program_powerpc_init (OrcProgram *p);
void orc_program_assemble_x86 (OrcProgram *p);
void orc_program_assemble_powerpc (OrcProgram *p);
void orc_program_assemble_c (OrcProgram *p);