Fix gen_op_invoke*() for 64-bit offsets on x86-64. Drop CPUPARAM since it's

now cached to a host register.
This commit is contained in:
gbeauche 2006-07-09 15:19:32 +00:00
parent a5296875f1
commit 5d7ef13a9c
2 changed files with 49 additions and 44 deletions

View File

@ -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));
});

View File

@ -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);