sh2 drc, fix PIC function calling for MIPS backend
authorkub <derkub@gmail.com>
Sat, 31 Oct 2020 20:05:27 +0000 (21:05 +0100)
committerkub <derkub@gmail.com>
Sat, 31 Oct 2020 20:05:27 +0000 (21:05 +0100)
cpu/drc/emit_arm.c
cpu/drc/emit_arm64.c
cpu/drc/emit_mips.c
cpu/drc/emit_ppc.c
cpu/drc/emit_riscv.c
cpu/drc/emit_x86.c
cpu/sh2/compiler.c

index 9a89ab3..c9d5e67 100644 (file)
@@ -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) \
index 5dc9ca2..f9a316f 100644 (file)
@@ -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() \
index ed7c178..edc2304 100644 (file)
@@ -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 {                 \
index 14e7574..e39f45d 100644 (file)
@@ -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() \
index cb02e1e..ef1900d 100644 (file)
@@ -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() \
index 53b7dc3..060bb80 100644 (file)
@@ -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; \
index fbabbd9..93c6891 100644 (file)
@@ -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);