From: kub Date: Sat, 31 Oct 2020 20:05:27 +0000 (+0100) Subject: sh2 drc, fix PIC function calling for MIPS backend X-Git-Tag: v2.00~664 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fde25b40fe29271bf80568c2fe6e43777c211380;p=picodrive.git sh2 drc, fix PIC function calling for MIPS backend --- diff --git a/cpu/drc/emit_arm.c b/cpu/drc/emit_arm.c index 9a89ab30..c9d5e674 100644 --- a/cpu/drc/emit_arm.c +++ b/cpu/drc/emit_arm.c @@ -1221,6 +1221,17 @@ static inline void emith_pool_adjust(int tcache_offs, int move_offs) emith_jump_ctx(offs); \ } while (0) +#define emith_abijump_reg(r) \ + emith_jump_reg(r) +#define emith_abijump_reg_c(cond, r) \ + emith_jump_reg_c(cond, r) +#define emith_abicall(target) \ + emith_call(target) +#define emith_abicall_cond(cond, target) \ + emith_call_cond(cond, target) +#define emith_abicall_reg(r) \ + emith_call_reg(r) + #define emith_call_cleanup() /**/ #define emith_ret_c(cond) \ diff --git a/cpu/drc/emit_arm64.c b/cpu/drc/emit_arm64.c index 5dc9ca20..f9a316fe 100644 --- a/cpu/drc/emit_arm64.c +++ b/cpu/drc/emit_arm64.c @@ -1142,6 +1142,17 @@ static void emith_ldst_offs(int sz, int rd, int rn, int o9, int ld, int mode) rcache_free_tmp(_t); \ } while (0) +#define emith_abijump_reg(r) \ + emith_jump_reg(r) +#define emith_abijump_reg_c(cond, r) \ + emith_abijump_reg(r) +#define emith_abicall(target) \ + emith_call(target) +#define emith_abicall_cond(cond, target) \ + emith_abicall(target) +#define emith_abicall_reg(r) \ + emith_call_reg(r) + #define emith_call_cleanup() /**/ #define emith_ret() \ diff --git a/cpu/drc/emit_mips.c b/cpu/drc/emit_mips.c index ed7c178f..edc23043 100644 --- a/cpu/drc/emit_mips.c +++ b/cpu/drc/emit_mips.c @@ -11,6 +11,7 @@ // saved: r16-r23,r30, reserved: r0(zero), r26-r27(irq), r28(gp), r29(sp) // r1,r15,r24,r25(at,t7-t9) are used internally by the code emitter // MIPSN32/MIPS64 ABI: params: r4-r11, no caller-reserved save area on stack +// for PIC code, on function calls r25(t9) must contain the called address #define RET_REG 2 // v0 #define PARAM_REGS { 4, 5, 6, 7 } // a0-a3 #define PRESERVED_REGS { 16, 17, 18, 19, 20, 21, 22, 23 } // s0-s7 @@ -26,6 +27,7 @@ // registers usable for user code: r1-r25, others reserved or special #define Z0 0 // zero register +#define CR 25 // call register #define GP 28 // global pointer #define SP 29 // stack pointer #define FP 30 // frame pointer @@ -1510,8 +1512,8 @@ static int emith_cond_check(int cond, int *r) emith_jump_reg(r) #define emith_jump_ctx(offs) do { \ - emith_ctx_read_ptr(AT, offs); \ - emith_jump_reg(AT); \ + emith_ctx_read_ptr(CR, offs); \ + emith_jump_reg(CR); \ } while (0) #define emith_jump_ctx_c(cond, offs) \ emith_jump_ctx(offs) @@ -1523,10 +1525,26 @@ static int emith_cond_check(int cond, int *r) #define emith_call_reg(r) \ emith_branch(MIPS_JALR(LR, r)) - #define emith_call_ctx(offs) do { \ - emith_ctx_read_ptr(AT, offs); \ - emith_call_reg(AT); \ + emith_ctx_read_ptr(CR, offs); \ + emith_call_reg(CR); \ +} while (0) + +#define emith_abijump_reg(r) do { \ + if ((r) != CR) emith_move_r_r(CR, r); \ + emith_branch(MIPS_JR(CR)); \ +} while (0) +#define emith_abijump_reg_c(cond, r) \ + emith_abijump_reg(r) +#define emith_abicall(target) do { \ + emith_move_r_imm(CR, target); \ + emith_branch(MIPS_JALR(LR, CR)); \ +} while (0) +#define emith_abicall_cond(cond, target) \ + emith_abicall(target) +#define emith_abicall_reg(r) do { \ + if ((r) != CR) emith_move_r_r(CR, r); \ + emith_branch(MIPS_JALR(LR, CR)); \ } while (0) #define emith_call_cleanup() /**/ @@ -1627,7 +1645,7 @@ static NOINLINE void host_instructions_updated(void *base, void *end, int force) emith_lsl(func, func, PTR_SCALE); \ emith_read_r_r_r_ptr(func, tab, func); \ emith_move_r_r_ptr(6, CONTEXT_REG); /* arg2 */ \ - emith_jump_reg(func); \ + emith_abijump_reg(func); \ } while (0) #define emith_sh2_delay_loop(cycles, reg) do { \ diff --git a/cpu/drc/emit_ppc.c b/cpu/drc/emit_ppc.c index 14e75743..e39f45d1 100644 --- a/cpu/drc/emit_ppc.c +++ b/cpu/drc/emit_ppc.c @@ -1497,6 +1497,17 @@ static int emith_cond_check(int cond) emith_call_reg(AT); \ } while (0) +#define emith_abijump_reg(r) \ + emith_jump_reg(r) +#define emith_abijump_reg_c(cond, r) \ + emith_abijump_reg(r) +#define emith_abicall(target) \ + emith_call(target) +#define emith_abicall_cond(cond, target) \ + emith_abicall(target) +#define emith_abicall_reg(r) \ + emith_call_reg(r) + #define emith_call_cleanup() /**/ #define emith_ret() \ diff --git a/cpu/drc/emit_riscv.c b/cpu/drc/emit_riscv.c index cb02e1ee..ef1900dd 100644 --- a/cpu/drc/emit_riscv.c +++ b/cpu/drc/emit_riscv.c @@ -1370,6 +1370,17 @@ static int emith_cond_check(int cond, int *r, int *s) emith_call_reg(AT); \ } while (0) +#define emith_abijump_reg(r) \ + emith_jump_reg(r) +#define emith_abijump_reg_c(cond, r) \ + emith_abijump_reg(r) +#define emith_abicall(target) \ + emith_call(target) +#define emith_abicall_cond(cond, target) \ + emith_abicall(target) +#define emith_abicall_reg(r) \ + emith_call_reg(r) + #define emith_call_cleanup() /**/ #define emith_ret() \ diff --git a/cpu/drc/emit_x86.c b/cpu/drc/emit_x86.c index 53b7dc3c..060bb80d 100644 --- a/cpu/drc/emit_x86.c +++ b/cpu/drc/emit_x86.c @@ -968,6 +968,17 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI, // x86-64,i386 common emith_ret(); \ } while (0) +#define emith_abijump_reg(r) \ + emith_jump_reg(r) +#define emith_abijump_reg_c(cond, r) \ + emith_abijump_reg(r) +#define emith_abicall(target) \ + emith_call(target) +#define emith_abicall_cond(cond, target) \ + emith_abicall(target) +#define emith_abicall_reg(r) \ + emith_call_reg(r) + #define EMITH_JMP_START(cond) { \ u8 *cond_ptr; \ diff --git a/cpu/sh2/compiler.c b/cpu/sh2/compiler.c index fbabbd91..93c68913 100644 --- a/cpu/sh2/compiler.c +++ b/cpu/sh2/compiler.c @@ -3550,7 +3550,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) emith_move_r_imm(tmp4, pc); emith_ctx_write(tmp4, SHR_PC * 4); rcache_invalidate_tmp(); - emith_call(sh2_drc_log_entry); + emith_abicall(sh2_drc_log_entry); emith_restore_caller_regs(tmp); #endif @@ -3570,7 +3570,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) emith_save_caller_regs(tmp); emit_do_static_regs(1, 0); emith_pass_arg_r(0, CONTEXT_REG); - emith_call(do_sh2_cmp); + emith_abicall(do_sh2_cmp); emith_restore_caller_regs(tmp); } #endif @@ -3905,7 +3905,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) rcache_get_reg_arg(0, div(opd).rn, NULL); rcache_get_reg_arg(1, div(opd).rm, NULL); rcache_invalidate_tmp(); - emith_call(sh2_drc_divu32); + emith_abicall(sh2_drc_divu32); tmp = rcache_get_tmp_ret(); #if REMAP_REGISTER tmp2 = rcache_map_reg(div(opd).rn, tmp); @@ -3932,7 +3932,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) rcache_get_reg_arg(0, div(opd).rn, NULL); rcache_get_reg_arg(2, div(opd).rm, NULL); rcache_invalidate_tmp(); - emith_call(sh2_drc_divu64); + emith_abicall(sh2_drc_divu64); tmp = rcache_get_tmp_ret(); #if REMAP_REGISTER tmp2 = rcache_map_reg(div(opd).rn, tmp); @@ -4030,7 +4030,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) emith_lsr(tmp3, tmp2, 31); emith_or_r_r_lsl(sr, tmp3, M_SHIFT); // M = Rm[31] rcache_invalidate_tmp(); - emith_call(sh2_drc_divs32); + emith_abicall(sh2_drc_divs32); tmp = rcache_get_tmp_ret(); #if REMAP_REGISTER tmp2 = rcache_map_reg(div(opd).rn, tmp); @@ -4060,7 +4060,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) emith_or_r_r_lsl(sr, tmp3, M_SHIFT); // M = Rm[31] emith_add_r_r_ptr_imm(tmp3, CONTEXT_REG, offsetof(SH2, drc_tmp)); rcache_invalidate_tmp(); - emith_call(sh2_drc_divs64); + emith_abicall(sh2_drc_divs64); tmp = rcache_get_tmp_ret(); #if REMAP_REGISTER tmp2 = rcache_map_reg(div(opd).rn, tmp); @@ -5214,7 +5214,7 @@ static void sh2_generate_utils(void) emith_ret_c(DCOND_CC); EMITH_SJMP_END(DCOND_CS); emith_move_r_r_ptr(arg1, CONTEXT_REG); - emith_jump_reg(arg2); + emith_abijump_reg(arg2); emith_flush(); // d = sh2_drc_read16(u32 a) @@ -5228,7 +5228,7 @@ static void sh2_generate_utils(void) emith_ret_c(DCOND_CC); EMITH_SJMP_END(DCOND_CS); emith_move_r_r_ptr(arg1, CONTEXT_REG); - emith_jump_reg(arg2); + emith_abijump_reg(arg2); emith_flush(); // d = sh2_drc_read32(u32 a) @@ -5243,7 +5243,7 @@ static void sh2_generate_utils(void) emith_ret_c(DCOND_CC); EMITH_SJMP_END(DCOND_CS); emith_move_r_r_ptr(arg1, CONTEXT_REG); - emith_jump_reg(arg2); + emith_abijump_reg(arg2); emith_flush(); // d = sh2_drc_read8_poll(u32 a) @@ -5253,14 +5253,14 @@ static void sh2_generate_utils(void) emith_sh2_rcall(arg0, arg1, arg2, arg3); EMITH_SJMP_START(DCOND_CC); emith_move_r_r_ptr_c(DCOND_CS, arg1, CONTEXT_REG); - emith_jump_reg_c(DCOND_CS, arg2); + emith_abijump_reg_c(DCOND_CS, arg2); EMITH_SJMP_END(DCOND_CC); emith_and_r_r_r(arg1, arg0, arg3); emith_eor_r_imm_ptr(arg1, 1); emith_read8s_r_r_r(arg1, arg2, arg1); emith_push_ret(arg1); emith_move_r_r_ptr(arg2, CONTEXT_REG); - emith_call(p32x_sh2_poll_memory8); + emith_abicall(p32x_sh2_poll_memory8); emith_pop_and_ret(arg1); emith_flush(); @@ -5271,13 +5271,13 @@ static void sh2_generate_utils(void) emith_sh2_rcall(arg0, arg1, arg2, arg3); EMITH_SJMP_START(DCOND_CC); emith_move_r_r_ptr_c(DCOND_CS, arg1, CONTEXT_REG); - emith_jump_reg_c(DCOND_CS, arg2); + emith_abijump_reg_c(DCOND_CS, arg2); EMITH_SJMP_END(DCOND_CC); emith_and_r_r_r(arg1, arg0, arg3); emith_read16s_r_r_r(arg1, arg2, arg1); emith_push_ret(arg1); emith_move_r_r_ptr(arg2, CONTEXT_REG); - emith_call(p32x_sh2_poll_memory16); + emith_abicall(p32x_sh2_poll_memory16); emith_pop_and_ret(arg1); emith_flush(); @@ -5288,14 +5288,14 @@ static void sh2_generate_utils(void) emith_sh2_rcall(arg0, arg1, arg2, arg3); EMITH_SJMP_START(DCOND_CC); emith_move_r_r_ptr_c(DCOND_CS, arg1, CONTEXT_REG); - emith_jump_reg_c(DCOND_CS, arg2); + emith_abijump_reg_c(DCOND_CS, arg2); EMITH_SJMP_END(DCOND_CC); emith_and_r_r_r(arg1, arg0, arg3); emith_read_r_r_r(arg1, arg2, arg1); emith_ror(arg1, arg1, 16); emith_push_ret(arg1); emith_move_r_r_ptr(arg2, CONTEXT_REG); - emith_call(p32x_sh2_poll_memory32); + emith_abicall(p32x_sh2_poll_memory32); emith_pop_and_ret(arg1); emith_flush(); @@ -5328,7 +5328,7 @@ static void sh2_generate_utils(void) #endif emith_move_r_r_ptr(arg1, CONTEXT_REG); emith_add_r_r_ptr_imm(arg2, CONTEXT_REG, offsetof(SH2, drc_tmp)); - emith_call(dr_lookup_block); + emith_abicall(dr_lookup_block); // store PC and block entry ptr (in arg0) in branch target cache emith_tst_r_r_ptr(RET_REG, RET_REG); EMITH_SJMP_START(DCOND_EQ); @@ -5350,13 +5350,13 @@ static void sh2_generate_utils(void) // lookup failed, call sh2_translate() emith_move_r_r_ptr(arg0, CONTEXT_REG); emith_ctx_read(arg1, offsetof(SH2, drc_tmp)); // tcache_id - emith_call(sh2_translate); + emith_abicall(sh2_translate); emith_tst_r_r_ptr(RET_REG, RET_REG); EMITH_SJMP_START(DCOND_EQ); emith_jump_reg_c(DCOND_NE, RET_REG); EMITH_SJMP_END(DCOND_EQ); // XXX: can't translate, fail - emith_call(dr_failure); + emith_abicall(dr_failure); emith_flush(); #if CALL_STACK @@ -5428,13 +5428,13 @@ static void sh2_generate_utils(void) emith_clear_msb(tmp, tmp, 22); emith_move_r_r_ptr(arg2, CONTEXT_REG); rcache_invalidate_tmp(); - emith_call(p32x_sh2_write32); // XXX: use sh2_drc_write32? + emith_abicall(p32x_sh2_write32); // XXX: use sh2_drc_write32? // push PC rcache_get_reg_arg(0, SHR_SP, NULL); rcache_get_reg_arg(1, SHR_PC, NULL); emith_move_r_r_ptr(arg2, CONTEXT_REG); rcache_invalidate_tmp(); - emith_call(p32x_sh2_write32); + emith_abicall(p32x_sh2_write32); // update I, cycles, do callback emith_ctx_read(arg1, offsetof(SH2, pending_level)); sr = rcache_get_reg(SHR_SR, RC_GR_RMW, NULL);