sh2 drc: moved host register assignment to code emitters, minor bugfixing

This commit is contained in:
kub 2019-11-09 10:24:52 +01:00
parent 7e940f142e
commit 9bd6706dca
12 changed files with 174 additions and 250 deletions

View file

@ -6,9 +6,21 @@
* This work is licensed under the terms of MAME license.
* See COPYING file in the top-level directory.
*/
#define HOST_REGS 16
#define CONTEXT_REG 11
#define RET_REG 0
#define HOST_REGS 16
// OABI/EABI: params: r0-r3, return: r0-r1, temp: r12,r14, saved: r4-r8,r10,r11
// SP,PC: r13,r15 must not be used. saved: r9 (for platform use, e.g. on ios)
#define RET_REG 0
#define PARAM_REGS { 0, 1, 2, 3 }
#ifndef __MACH__
#define PRESERVED_REGS { 4, 5, 6, 7, 8, 9, 10, 11 }
#else
#define PRESERVED_REGS { 4, 5, 6, 7, 8, 10, 11 } // no r9..
#endif
#define TEMPORARY_REGS { 12, 14 }
#define CONTEXT_REG 11
#define STATIC_SH2_REGS { SHR_SR,10 , SHR_R0,8 , SHR_R0+1,9 }
// XXX: tcache_ptr type for SVP and SH2 compilers differs..
#define EMIT_PTR(ptr, x) \

View file

@ -6,8 +6,16 @@
* See COPYING file in the top-level directory.
*/
#define HOST_REGS 32
#define CONTEXT_REG 19
// AAPCS64: params: r0-r7, return: r0-r1, temp: r8-r17, saved: r19-r29
// reserved: r18 (for platform use)
#define RET_REG 0
#define PARAM_REGS { 0, 1, 2, 3, 4, 5, 6, 7 }
#define PRESERVED_REGS { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 }
#define TEMPORARY_REGS { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }
#define CONTEXT_REG 29
#define STATIC_SH2_REGS { SHR_SR,28 , SHR_R0,27 , SHR_R0+1,26 }
// R31 doesn't exist, it aliases either with zero or SP
#define SP 31 // stack pointer
@ -100,9 +108,9 @@ enum { XT_UXTW=0x4, XT_UXTX=0x6, XT_LSL=0x7, XT_SXTW=0xc, XT_SXTX=0xe };
#define A64_NEGS_REG(rd, rm, stype, simm) \
A64_SUBS_REG(rd,Z0,rm,stype,simm)
#define A64_NEGC_REG(rd, rm) \
A64_SBC_REG(rd,Z0,rm,stype,simm)
A64_SBC_REG(rd,Z0,rm)
#define A64_NEGCS_REG(rd, rm) \
A64_SBCS_REG(rd,Z0,rm,stype,simm)
A64_SBCS_REG(rd,Z0,rm)
#define A64_CMP_REG(rn, rm, stype, simm) \
A64_SUBS_REG(Z0, rn, rm, stype, simm)
#define A64_CMN_REG(rn, rm, stype, simm) \
@ -145,7 +153,7 @@ enum { XT_UXTW=0x4, XT_UXTX=0x6, XT_LSL=0x7, XT_SXTW=0xc, XT_SXTX=0xe };
A64_INSN(0xd,OP_ADD &3,0x0,_,rm,_,_,rn,rd)
#define A64_ADCS_REG(rd, rn, rm) \
A64_INSN(0xd,OP_ADDS&3,0x0,_,rm,_,_,rn,rd)
#define A64_SBC_REG(rd, rn, rm, s) \
#define A64_SBC_REG(rd, rn, rm) \
A64_INSN(0xd,OP_SUB &3,0x0,_,rm,_,_,rn,rd)
#define A64_SBCS_REG(rd, rn, rm) \
A64_INSN(0xd,OP_SUBS&3,0x0,_,rm,_,_,rn,rd)

View file

@ -6,8 +6,17 @@
* See COPYING file in the top-level directory.
*/
#define HOST_REGS 32
// MIPS ABI: params: r4-r7, return: r2-r3, temp: r1(at),r8-r15,r24-r25,r31(ra),
// 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
#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
#define TEMPORARY_REGS { 2, 3, 8, 9, 10, 11, 12, 13, 14 } // v0-v1,t0-t6
#define CONTEXT_REG 23 // s7
#define RET_REG 2 // v0
#define STATIC_SH2_REGS { SHR_SR,22 , SHR_R0,21 , SHR_R0+1,20 }
// NB: the ubiquitous JZ74[46]0 uses MIPS32 Release 1, a slight MIPS II superset
@ -73,7 +82,7 @@ enum { RT_BLTZ=000, RT_BGEZ, RT_BLTZAL=020, RT_BGEZAL, RT_SYNCI=037 };
#define MIPS_OP_IMM(op, rt, rs, imm) \
MIPS_INSN(op, rs, rt, _, _, (u16)(imm)) // I-type
// rd = rt OP rs
// rd = rs OP rt
#define MIPS_ADD_REG(rd, rs, rt) \
MIPS_OP_REG(FN_ADDU, rd, rs, rt)
#define MIPS_SUB_REG(rd, rs, rt) \
@ -334,7 +343,7 @@ static void *emith_branch(u32 op)
#define JMP_EMIT(cond, ptr) { \
u32 val_ = (u8 *)tcache_ptr - (u8 *)(ptr) - 4; \
emith_flush(); /* NO delay slot handling across jump targets */ \
emith_flush(); /* prohibit delay slot switching across jump targets */ \
EMIT_PTR(ptr, MIPS_BCONDZ(cond_m, cond_r, val_ & 0x0003ffff)); \
}
@ -658,14 +667,19 @@ static void emith_move_imm(int r, uintptr_t imm)
EMIT_PTR(ptr_, (*ptr_ & 0xffff0000) | (u16)(s8)(imm)); \
} while (0)
// arithmetic, immediate
// arithmetic, immediate - can only be ADDI[U], since SUBI[U] doesn't exist
static void emith_arith_imm(int op, int rd, int rs, u32 imm)
{
if ((s16)imm != imm) {
if ((s16)imm == imm) {
if (imm || rd != rs)
EMIT(MIPS_OP_IMM(op, rd, rs, imm));
} else if ((s32)imm < 0) {
emith_move_r_imm(AT, -imm);
EMIT(MIPS_OP_REG(FN_SUB + (op-OP_ADDI), rd, rs, AT));
} else {
emith_move_r_imm(AT, imm);
EMIT(MIPS_OP_REG(FN_ADD + (op-OP_ADDI), rd, rs, AT));
} else if (imm || rd != rs)
EMIT(MIPS_OP_IMM(op, rd, rs, imm));
}
}
#define emith_add_r_imm(r, imm) \
@ -1137,7 +1151,7 @@ static int emith_cond_check(int cond, int *r)
// conditions using CZ
case DCOND_LS: // C || Z
case DCOND_HI: // !C && !Z
EMIT(MIPS_ADD_IMM(AT, FC, (u16)-1)); // !C && !Z
EMIT(MIPS_ADD_IMM(AT, FC, -1)); // !C && !Z
EMIT(MIPS_AND_REG(AT, FNZ, AT));
*r = AT, b = (cond == DCOND_HI ? MIPS_BNE : MIPS_BEQ);
break;
@ -1161,7 +1175,7 @@ static int emith_cond_check(int cond, int *r)
case DCOND_GT: // !(N^V) && !Z
EMIT(MIPS_LSR_IMM(AT, FV, 31)); // Nd^V = Nt^Ns^C
EMIT(MIPS_XOR_REG(AT, FC, AT));
EMIT(MIPS_ADD_IMM(AT, AT, (u16)-1)); // !(Nd^V) && !Z
EMIT(MIPS_ADD_IMM(AT, AT, -1)); // !(Nd^V) && !Z
EMIT(MIPS_AND_REG(AT, FNZ, AT));
*r = AT, b = (cond == DCOND_GT ? MIPS_BNE : MIPS_BEQ);
break;

View file

@ -17,8 +17,8 @@
enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI, // x86-64,i386 common
xR8, xR9, xR10, xR11, xR12, xR13, xR14, xR15 }; // x86-64 only
#define CONTEXT_REG xBP
#define RET_REG xAX
#define CONTEXT_REG xBP
#define RET_REG xAX
#define ICOND_JO 0x00
#define ICOND_JNO 0x01
@ -935,6 +935,7 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI, // x86-64,i386 common
emith_ret(); \
} while (0)
#define EMITH_JMP_START(cond) { \
u8 *cond_ptr; \
JMP8_POS(cond_ptr)
@ -1006,6 +1007,14 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI, // x86-64,i386 common
#ifndef _WIN32
// SystemV ABI conventions:
// rbx,rbp,r12-r15 are preserved, rax,rcx,rdx,rsi,rdi,r8-r11 are temporaries
// parameters in rdi,rsi,rdx,rcx,r8,r9, return values in rax,rdx
#define PARAM_REGS { xDI, xSI, xDX, xCX, xR8, xR9 }
#define PRESERVED_REGS { xR12, xR13, xR14, xR15, xBX, xBP }
#define TEMPORARY_REGS { xAX, xR10, xR11 }
#define STATIC_SH2_REGS { SHR_SR,xBX , SHR_R0,xR15 }
#define host_arg2reg(rd, arg) \
switch (arg) { \
case 0: rd = xDI; break; \
@ -1037,6 +1046,14 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI, // x86-64,i386 common
#else // _WIN32
// M$ ABI conventions:
// rbx,rbp,rsi,rdi,r12-r15 are preserved, rcx,rdx,rax,r8,r9,r10,r11 temporaries
// parameters in rcx,rdx,r8,r9, return values in rax,rdx
#define PARAM_REGS { xCX, xDX, xR8, xR9 }
#define PRESERVED_REGS { xSI, xDI, xR12, xR13, xR14, xR15, xBX, xBP }
#define TEMPORARY_REGS { xAX, xR10, xR11 }
#define STATIC_SH2_REGS { SHR_SR,xBX , SHR_R0,xR15 , SH2_R0+1,xR14 }
#define host_arg2reg(rd, arg) \
switch (arg) { \
case 0: rd = xCX; break; \
@ -1087,6 +1104,14 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI, // x86-64,i386 common
assert((u32)(rm) < 8u); \
} while (0)
// MS/SystemV ABI: ebx,esi,edi,ebp are preserved, eax,ecx,edx are temporaries
// DRC uses REGPARM to pass upto 3 parameters in registers eax,ecx,edx.
// To avoid conflicts with param passing ebx must be declared temp here.
#define PARAM_REGS { xAX, xDX, xCX }
#define PRESERVED_REGS { xSI, xDI, xBP }
#define TEMPORARY_REGS { xBX }
#define STATIC_SH2_REGS { SHR_SR,xDI , SHR_R0,xSI }
#define host_arg2reg(rd, arg) \
switch (arg) { \
case 0: rd = xAX; break; \