diff options
author | David Schleef <ds@ginger.bigkitten.com> | 2008-05-23 14:43:39 -0700 |
---|---|---|
committer | David Schleef <ds@ginger.bigkitten.com> | 2008-05-23 14:43:39 -0700 |
commit | 4f76bda40977c581691e47b2ae78334b3651c01f (patch) | |
tree | d818a01f2a91ffde49fab1a7e7d1590f2803e8a1 | |
parent | 9e0b12b550bee13514aa194c4a7ccf043466b01f (diff) | |
download | liboil-4f76bda40977c581691e47b2ae78334b3651c01f.tar.gz |
[orc] attempt to make the same code work on all platforms
-rw-r--r-- | orc/orcprogram-powerpc.c | 4 | ||||
-rw-r--r-- | orc/orcprogram-x86.c | 94 | ||||
-rw-r--r-- | orc/orcprogram.c | 53 | ||||
-rw-r--r-- | orc/orcprogram.h | 13 |
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); |