From 5d7ef13a9cf6bb6d462a53088d09110a7e3080a6 Mon Sep 17 00:00:00 2001 From: gbeauche <> Date: Sun, 9 Jul 2006 15:19:32 +0000 Subject: [PATCH] Fix gen_op_invoke*() for 64-bit offsets on x86-64. Drop CPUPARAM since it's now cached to a host register. --- .../kpx_cpu/src/cpu/jit/basic-dyngen-ops.cpp | 50 +++++++++++-------- SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c | 43 +++++++--------- 2 files changed, 49 insertions(+), 44 deletions(-) diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen-ops.cpp b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen-ops.cpp index 3492b3e1..99df2361 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen-ops.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen-ops.cpp @@ -65,22 +65,21 @@ DYNGEN_DEFINE_GLOBAL_REGISTER(2); // XXX update for new 64-bit arches #if defined __x86_64__ -#define DEFINE_REG(REG) asm volatile ("movabsq $__op_param1,%" REG_T##REG) +#define MOV_AD_REG(PARAM, REG) asm volatile ("movabsq $__op_" #PARAM ",%0" : "=r" (REG)) #else -#define DEFINE_REG(REG) A##REG = PARAM1 +#define MOV_AD_REG(PARAM, REG) REG = PARAM #endif #define DEFINE_OP(REG) \ -void OPPROTO op_mov_ad_A##REG##_im(void) \ +void OPPROTO op_mov_ad_##REG##_im(void) \ { \ - DEFINE_REG(REG); \ + MOV_AD_REG(PARAM1, REG); \ } -DEFINE_OP(0); -DEFINE_OP(1); -DEFINE_OP(2); +DEFINE_OP(A0); +DEFINE_OP(A1); +DEFINE_OP(A2); -#undef DEFINE_REG #undef DEFINE_OP #define DEFINE_OP(NAME, CODE) \ @@ -295,7 +294,7 @@ void OPPROTO op_jmp_slow(void) void OPPROTO op_jmp_fast(void) { #ifdef DYNGEN_FAST_DISPATCH - DYNGEN_FAST_DISPATCH(__op_param1); + DYNGEN_FAST_DISPATCH(__op_PARAM1); #else SLOW_DISPATCH(PARAM1); #endif @@ -358,67 +357,78 @@ void OPPROTO NAME(void) \ DEFINE_OP(op_invoke, { typedef void (*func_t)(void); - func_t func = (func_t)PARAM1; + uintptr func; + MOV_AD_REG(PARAM1, func); CALL(func, ()); }); DEFINE_OP(op_invoke_T0, { typedef void (*func_t)(uint32); - func_t func = (func_t)PARAM1; + uintptr func; + MOV_AD_REG(PARAM1, func); CALL(func, (T0)); }); DEFINE_OP(op_invoke_T0_T1, { typedef void (*func_t)(uint32, uint32); - func_t func = (func_t)PARAM1; + uintptr func; + MOV_AD_REG(PARAM1, func); CALL(func, (T0, T1)); }); DEFINE_OP(op_invoke_T0_T1_T2, { typedef void (*func_t)(uint32, uint32, uint32); - func_t func = (func_t)PARAM1; + uintptr func; + MOV_AD_REG(PARAM1, func); CALL(func, (T0, T1, T2)); }); DEFINE_OP(op_invoke_T0_ret_T0, { typedef uint32 (*func_t)(uint32); - func_t func = (func_t)PARAM1; + uintptr func; + MOV_AD_REG(PARAM1, func); T0 = CALL(func, (T0)); }); DEFINE_OP(op_invoke_im, { typedef void (*func_t)(uint32); - func_t func = (func_t)PARAM1; + uintptr func; + MOV_AD_REG(PARAM1, func); CALL(func, (PARAM2)); }); DEFINE_OP(op_invoke_CPU, { typedef void (*func_t)(void *); - func_t func = (func_t)PARAM1; + uintptr func; + MOV_AD_REG(PARAM1, func); CALL(func, (CPU)); }); DEFINE_OP(op_invoke_CPU_T0, { typedef void (*func_t)(void *, uint32); - func_t func = (func_t)PARAM1; + uintptr func; + MOV_AD_REG(PARAM1, func); CALL(func, (CPU, T0)); }); DEFINE_OP(op_invoke_CPU_im, { typedef void (*func_t)(void *, uint32); - func_t func = (func_t)PARAM1; + uintptr func; + MOV_AD_REG(PARAM1, func); CALL(func, (CPU, PARAM2)); }); DEFINE_OP(op_invoke_CPU_im_im, { typedef void (*func_t)(void *, uint32, uint32); - func_t func = (func_t)PARAM1; + uintptr func; + MOV_AD_REG(PARAM1, func); CALL(func, (CPU, PARAM2, PARAM3)); }); DEFINE_OP(op_invoke_CPU_A0_ret_A0, { typedef void *(*func_t)(void *, uintptr); - func_t func = (func_t)PARAM1; + uintptr func; + MOV_AD_REG(PARAM1, func); A0 = (uintptr)CALL(func, (CPU, A0)); }); diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c b/SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c index 652653ce..8be846a0 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c @@ -1603,7 +1603,7 @@ int arm_emit_ldr_info(const char *name, unsigned long start_offset, if (rel->r_offset == (pc_offset + start_offset)) { sym_name = get_rel_sym_name(rel); /* the compiler leave some unnecessary references to the code */ - if (strstart(sym_name, "__op_param", &p)) { + if (strstart(sym_name, "__op_PARAM", &p)) { snprintf(relname, sizeof(relname), "param%s", p); } else { snprintf(relname, sizeof(relname), "(long)(&%s)", sym_name); @@ -1878,7 +1878,7 @@ void gen_code(const char *name, const char *demangled_name, sym_name = get_rel_sym_name(rel); if(!sym_name) continue; - if (strstart(sym_name, "__op_param", &p)) { + if (strstart(sym_name, "__op_PARAM", &p)) { n = strtoul(p, NULL, 10); if (n > MAX_ARGS) error("too many arguments in %s", name); @@ -1925,8 +1925,7 @@ void gen_code(const char *name, const char *demangled_name, if(!sym_name) continue; if (*sym_name && - !strstart(sym_name, "__op_param", NULL) && - !strstart(sym_name, "__op_cpuparam", NULL) && + !strstart(sym_name, "__op_PARAM", NULL) && !strstart(sym_name, "__op_jmp", NULL) && !strstart(sym_name, ".LC", NULL)) error("unexpected external symbol %s", sym_name); @@ -2058,10 +2057,8 @@ void gen_code(const char *name, const char *demangled_name, continue; /* dunno how to handle without final_sym_name */ } - if (strstart(sym_name, "__op_param", &p)) + if (strstart(sym_name, "__op_PARAM", &p)) snprintf(final_sym_name, sizeof(final_sym_name), "param%s", p); - else if (strstart(sym_name, "__op_cpuparam", &p)) - snprintf(final_sym_name, sizeof(final_sym_name), "(long)(cpu())", p); else snprintf(final_sym_name, sizeof(final_sym_name), "(long)(&%s)", sym_name); @@ -2103,10 +2100,8 @@ void gen_code(const char *name, const char *demangled_name, continue; } - if (strstart(sym_name, "__op_param", &p)) { + if (strstart(sym_name, "__op_PARAM", &p)) { snprintf(name, sizeof(name), "param%s", p); - } else if (strstart(sym_name, "__op_cpuparam", &p)) { - snprintf(name, sizeof(name), "(long)(cpu())", p); } else { snprintf(name, sizeof(name), "(long)(&%s)", sym_name); } @@ -2180,7 +2175,7 @@ void gen_code(const char *name, const char *demangled_name, continue; } - if (strstart(sym_name, "__op_param", &p)) + if (strstart(sym_name, "__op_PARAM", &p)) snprintf(name, sizeof(name), "param%s", p); else if (strstart(sym_name, ".LC", NULL)) snprintf(name, sizeof(name), "(long)(gen_const_%s())", gen_dot_prefix(sym_name)); @@ -2233,7 +2228,7 @@ void gen_code(const char *name, const char *demangled_name, continue; } - if (strstart(sym_name, "__op_param", &p)) { + if (strstart(sym_name, "__op_PARAM", &p)) { snprintf(name, sizeof(name), "param%s", p); } else { snprintf(name, sizeof(name), "(long)(&%s)", sym_name); @@ -2322,7 +2317,7 @@ void gen_code(const char *name, const char *demangled_name, continue; /* dunno how to handle without final_sym_name */ } - if (strstart(sym_name, "__op_param", &p)) { + if (strstart(sym_name, "__op_PARAM", &p)) { snprintf(final_sym_name, sizeof(final_sym_name), "param%s", p); } else { snprintf(final_sym_name, sizeof(final_sym_name), "(long)(&%s)", sym_name); @@ -2330,7 +2325,7 @@ void gen_code(const char *name, const char *demangled_name, switch(type) { case PPC_RELOC_BR24: - if (!strstart(sym_name, "__op_param", &p)) { + if (!strstart(sym_name, "__op_PARAM", &p)) { fprintf(outfile, "{\n"); fprintf(outfile, " uint32_t imm = *(uint32_t *)(code_ptr() + %d) & 0x3fffffc;\n", slide); fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = (*(uint32_t *)(code_ptr() + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)code_ptr()) + %d) & 0x03fffffc);\n", @@ -2370,7 +2365,7 @@ void gen_code(const char *name, const char *demangled_name, if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) { sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; - if (strstart(sym_name, "__op_param", &p)) { + if (strstart(sym_name, "__op_PARAM", &p)) { snprintf(name, sizeof(name), "param%s", p); } else { snprintf(name, sizeof(name), "(long)(&%s)", sym_name); @@ -2426,15 +2421,15 @@ void gen_code(const char *name, const char *demangled_name, single gp, nothing is to be done. */ break; case R_ALPHA_GPRELHIGH: - /* Handle fake relocations against __op_param symbol. Need to emit the + /* Handle fake relocations against __op_PARAM symbol. Need to emit the high part of the immediate value instead. Other symbols need no special treatment. */ - if (strstart(sym_name, "__op_param", &p)) + if (strstart(sym_name, "__op_PARAM", &p)) fprintf(outfile, " immediate_ldah(code_ptr() + %ld, param%s);\n", rel->r_offset - start_offset, p); break; case R_ALPHA_GPRELLOW: - if (strstart(sym_name, "__op_param", &p)) + if (strstart(sym_name, "__op_PARAM", &p)) fprintf(outfile, " immediate_lda(code_ptr() + %ld, param%s);\n", rel->r_offset - start_offset, p); break; @@ -2458,7 +2453,7 @@ void gen_code(const char *name, const char *demangled_name, for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) { sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name; - if (strstart(sym_name, "__op_param", &p)) { + if (strstart(sym_name, "__op_PARAM", &p)) { snprintf(name, sizeof(name), "param%s", p); } else { snprintf(name, sizeof(name), "(long)(&%s)", sym_name); @@ -2485,7 +2480,7 @@ void gen_code(const char *name, const char *demangled_name, if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) { sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; - if (strstart(sym_name, "__op_param", &p)) { + if (strstart(sym_name, "__op_PARAM", &p)) { snprintf(name, sizeof(name), "param%s", p); } else { if (sym_name[0] == '.') @@ -2550,7 +2545,7 @@ void gen_code(const char *name, const char *demangled_name, if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) { sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name; - if (strstart(sym_name, "__op_param", &p)) { + if (strstart(sym_name, "__op_PARAM", &p)) { snprintf(name, sizeof(name), "param%s", p); } else { snprintf(name, sizeof(name), "(long)(&%s)", sym_name); @@ -2616,7 +2611,7 @@ void gen_code(const char *name, const char *demangled_name, /* the compiler leave some unnecessary references to the code */ if (sym_name[0] == '\0') continue; - if (strstart(sym_name, "__op_param", &p)) { + if (strstart(sym_name, "__op_PARAM", &p)) { snprintf(name, sizeof(name), "param%s", p); } else { snprintf(name, sizeof(name), "(long)(&%s)", sym_name); @@ -2649,7 +2644,7 @@ void gen_code(const char *name, const char *demangled_name, rel->r_offset < start_offset + copy_size) { sym = &(symtab[ELFW(R_SYM)(rel->r_info)]); sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; - if (strstart(sym_name, "__op_param", &p)) { + if (strstart(sym_name, "__op_PARAM", &p)) { snprintf(name, sizeof(name), "param%s", p); } else { snprintf(name, sizeof(name), "(long)(&%s)", sym_name); @@ -2694,7 +2689,7 @@ void gen_code(const char *name, const char *demangled_name, continue; } - if (strstart(sym_name, "__op_param", &p)) { + if (strstart(sym_name, "__op_PARAM", &p)) { snprintf(name, sizeof(name), "param%s", p); } else { snprintf(name, sizeof(name), "(long)(&%s)", sym_name);