mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-19 09:30:56 +00:00
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:
parent
a5296875f1
commit
5d7ef13a9c
@ -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));
|
||||
});
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user