mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
sh2 drc: cleanup, fix for drc crash, for mips code emitter
This commit is contained in:
parent
9760505eaf
commit
90b1c9db91
12 changed files with 151 additions and 120 deletions
|
@ -20,6 +20,9 @@
|
|||
#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
|
||||
#ifndef __mips_isa_rev
|
||||
#define __mips_isa_rev 1 // surprisingly not always defined
|
||||
#endif
|
||||
|
||||
// registers usable for user code: r1-r25, others reserved or special
|
||||
#define Z0 0 // zero register
|
||||
|
@ -333,32 +336,49 @@ static int emith_is_b(u32 op) // B
|
|||
{ return ((op>>26) & 074) == OP_BEQ ||
|
||||
((op>>26) == OP__RT && ((op>>16) & 036) == RT_BLTZ); }
|
||||
// register usage for dependency evaluation XXX better do this as in emit_arm?
|
||||
static uint64_t emith_has_rs[3] = // OP__FN, OP__RT, others
|
||||
{ 0x00fffffffffa0ff0ULL, 0x000fff0fUL, 0xffffffff0f007ff0ULL };
|
||||
static uint64_t emith_has_rt[3] = // OP__FN, OP__RT, others
|
||||
{ 0xff00fffffff00cffULL, 0x00000000UL, 0x8000ff0000000030ULL };
|
||||
static uint64_t emith_has_rd[3] = // OP__FN, OP__RT, others (rt instead of rd)
|
||||
{ 0xff00fffffff50fffULL, 0x00000000UL, 0x119100ff0f00ff00ULL };
|
||||
static uint64_t emith_has_rs[5] = // OP__FN1-3, OP__RT, others
|
||||
{ 0x005ffcffffda0fd2ULL, 0x0000003300000037ULL, 0x00000000000000ffULL,
|
||||
0x800f5f0fUL, 0xf7ffffff0ff07ff0ULL };
|
||||
static uint64_t emith_has_rt[5] = // OP__FN1-3, OP__RT, others
|
||||
{ 0xdd5ffcffffd00cddULL, 0x0000000000000037ULL, 0x0000001100000000ULL,
|
||||
0x00000000UL, 0x80007f440c300030ULL };
|
||||
static uint64_t emith_has_rd[5] = // OP__FN1-3, OP__RT, others(rt instead of rd)
|
||||
{ 0xdd00fcff00d50edfULL, 0x0000003300000004ULL, 0x08000011000000ffULL,
|
||||
0x00000000UL, 0x119100ff0f00ff00ULL };
|
||||
#define emith_has_(rx,ix,op,sa,m) \
|
||||
(emith_has_##rx[ix] & (1ULL << (((op)>>(sa)) & (m))))
|
||||
static int emith_rs(u32 op)
|
||||
{ if ((op>>26) == OP__FN)
|
||||
return emith_has_(rs,0,op, 0,0x3f) ? (op>>21)&0x1f : 0;
|
||||
if ((op>>26) == OP__FN2)
|
||||
return emith_has_(rs,1,op, 0,0x3f) ? (op>>21)&0x1f : 0;
|
||||
if ((op>>26) == OP__FN3)
|
||||
return emith_has_(rs,2,op, 0,0x3f) ? (op>>21)&0x1f : 0;
|
||||
if ((op>>26) == OP__RT)
|
||||
return emith_has_(rs,1,op,16,0x1f) ? (op>>21)&0x1f : 0;
|
||||
return emith_has_(rs,2,op,26,0x3f) ? (op>>21)&0x1f : 0;
|
||||
return emith_has_(rs,3,op,16,0x1f) ? (op>>21)&0x1f : 0;
|
||||
return emith_has_(rs,4,op,26,0x3f) ? (op>>21)&0x1f : 0;
|
||||
}
|
||||
static int emith_rt(u32 op)
|
||||
{ if ((op>>26) == OP__FN)
|
||||
return emith_has_(rt,0,op, 0,0x3f) ? (op>>16)&0x1f : 0;
|
||||
if ((op>>26) == OP__FN2)
|
||||
return emith_has_(rt,1,op, 0,0x3f) ? (op>>16)&0x1f : 0;
|
||||
if ((op>>26) == OP__FN3)
|
||||
return emith_has_(rt,2,op, 0,0x3f) ? (op>>16)&0x1f : 0;
|
||||
if ((op>>26) == OP__RT)
|
||||
return 0;
|
||||
return emith_has_(rt,2,op,26,0x3f) ? (op>>16)&0x1f : 0;
|
||||
return emith_has_(rt,4,op,26,0x3f) ? (op>>16)&0x1f : 0;
|
||||
}
|
||||
static int emith_rd(u32 op)
|
||||
{ int ret = emith_has_(rd,2,op,26,0x3f) ? (op>>16)&0x1f :-1;
|
||||
{ int ret = emith_has_(rd,4,op,26,0x3f) ? (op>>16)&0x1f :-1;
|
||||
if ((op>>26) == OP__FN)
|
||||
ret = emith_has_(rd,0,op, 0,0x3f) ? (op>>11)&0x1f :-1;
|
||||
if ((op>>26) == OP__FN2)
|
||||
ret = emith_has_(rd,1,op, 0,0x3f) ? (op>>11)&0x1f :-1;
|
||||
if ((op>>26) == OP__FN3 && (op&0x3f) == FN3_BSHFL)
|
||||
ret = emith_has_(rd,2,op, 0,0x3f) ? (op>>11)&0x1f :-1;
|
||||
if ((op>>26) == OP__FN3 && (op&0x3f) != FN3_BSHFL)
|
||||
ret = emith_has_(rd,2,op, 0,0x3f) ? (op>>16)&0x1f :-1;
|
||||
if ((op>>26) == OP__RT)
|
||||
ret = -1;
|
||||
return (ret ?: -1); // Z0 doesn't have dependencies
|
||||
|
@ -970,29 +990,23 @@ static void emith_log_imm(int op, int rd, int rs, u32 imm)
|
|||
#define emith_asr(d, s, cnt) \
|
||||
EMIT(MIPS_ASR_IMM(d, s, cnt))
|
||||
|
||||
#if defined(__mips_isa_rev) && __mips_isa_rev >= 2
|
||||
#define emith_ror(d, s, cnt) \
|
||||
EMIT(MIPS_ROR_IMM(d, s, cnt))
|
||||
#else
|
||||
#define emith_ror(d, s, cnt) do { \
|
||||
EMIT(MIPS_LSL_IMM(AT, s, 32-(cnt))); \
|
||||
EMIT(MIPS_LSR_IMM(d, s, cnt)); \
|
||||
EMIT(MIPS_OR_REG(d, d, AT)); \
|
||||
if (__mips_isa_rev < 2) { \
|
||||
EMIT(MIPS_LSL_IMM(AT, s, 32-(cnt))); \
|
||||
EMIT(MIPS_LSR_IMM(d, s, cnt)); \
|
||||
EMIT(MIPS_OR_REG(d, d, AT)); \
|
||||
} else EMIT(MIPS_ROR_IMM(d, s, cnt)); \
|
||||
} while (0)
|
||||
#endif
|
||||
#define emith_ror_c(cond, d, s, cnt) \
|
||||
emith_ror(d, s, cnt)
|
||||
|
||||
#if defined(__mips_isa_rev) && __mips_isa_rev >= 2
|
||||
#define emith_rol(d, s, cnt) \
|
||||
EMIT(MIPS_ROR_IMM(d, s, 32-(cnt)))
|
||||
#else
|
||||
#define emith_rol(d, s, cnt) do { \
|
||||
EMIT(MIPS_LSR_IMM(AT, s, 32-(cnt))); \
|
||||
EMIT(MIPS_LSL_IMM(d, s, cnt)); \
|
||||
EMIT(MIPS_OR_REG(d, d, AT)); \
|
||||
if (__mips_isa_rev < 2) { \
|
||||
EMIT(MIPS_LSR_IMM(AT, s, 32-(cnt))); \
|
||||
EMIT(MIPS_LSL_IMM(d, s, cnt)); \
|
||||
EMIT(MIPS_OR_REG(d, d, AT)); \
|
||||
} else EMIT(MIPS_ROR_IMM(d, s, 32-(cnt))); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define emith_rorc(d) do { \
|
||||
emith_lsr(d, d, 1); \
|
||||
|
@ -1082,13 +1096,11 @@ static void emith_log_imm(int op, int rd, int rs, u32 imm)
|
|||
} while (0)
|
||||
|
||||
// signed/unsigned extend
|
||||
#if defined(__mips_isa_rev) && __mips_isa_rev >= 2
|
||||
#define emith_clear_msb(d, s, count) /* bits to clear */ \
|
||||
EMIT(MIPS_EXT_IMM(d, s, 0, 32-(count)))
|
||||
#else
|
||||
#define emith_clear_msb(d, s, count) /* bits to clear */ do { \
|
||||
u32 t; \
|
||||
if ((count) >= 16) { \
|
||||
if (__mips_isa_rev >= 2) \
|
||||
EMIT(MIPS_EXT_IMM(d, s, 0, 32-(count))); \
|
||||
else if ((count) >= 16) { \
|
||||
t = (count) - 16; \
|
||||
t = 0xffff >> t; \
|
||||
emith_and_r_r_imm(d, s, t); \
|
||||
|
@ -1097,27 +1109,19 @@ static void emith_log_imm(int op, int rd, int rs, u32 imm)
|
|||
emith_lsr(d, d, count); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
#define emith_clear_msb_c(cond, d, s, count) \
|
||||
emith_clear_msb(d, s, count)
|
||||
|
||||
#if defined(__mips_isa_rev) && __mips_isa_rev >= 2
|
||||
#define emith_sext(d, s, count) /* bits to keep */ do { \
|
||||
if (count == 8) \
|
||||
if (__mips_isa_rev >= 2 && count == 8) \
|
||||
EMIT(MIPS_SEB_REG(d, s)); \
|
||||
else if (count == 16) \
|
||||
else if (__mips_isa_rev >= 2 && count == 16) \
|
||||
EMIT(MIPS_SEH_REG(d, s)); \
|
||||
else { \
|
||||
emith_lsl(d, s, 32-(count)); \
|
||||
emith_asr(d, d, 32-(count)); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define emith_sext(d, s, count) /* bits to keep */ do { \
|
||||
emith_lsl(d, s, 32-(count)); \
|
||||
emith_asr(d, d, 32-(count)); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
// multiply Rd = Rn*Rm (+ Ra); NB: next 2 insns after MFLO/MFHI mustn't be MULT
|
||||
static u8 *last_lohi;
|
||||
|
@ -1716,26 +1720,20 @@ static int emith_cond_check(int cond, int *r)
|
|||
EMITH_SJMP_END(DCOND_EQ); \
|
||||
} while (0)
|
||||
|
||||
#if defined(__mips_isa_rev) && __mips_isa_rev >= 2
|
||||
#define emith_write_sr(sr, srcr) \
|
||||
EMIT(MIPS_INS_IMM(sr, srcr, 0, 10))
|
||||
#else
|
||||
#define emith_write_sr(sr, srcr) do { \
|
||||
emith_lsr(sr, sr , 10); emith_lsl(sr, sr, 10); \
|
||||
emith_lsl(AT, srcr, 22); emith_lsr(AT, AT, 22); \
|
||||
emith_or_r_r(sr, AT); \
|
||||
if (__mips_isa_rev < 2) { \
|
||||
emith_lsr(sr, sr , 10); emith_lsl(sr, sr, 10); \
|
||||
emith_lsl(AT, srcr, 22); emith_lsr(AT, AT, 22); \
|
||||
emith_or_r_r(sr, AT); \
|
||||
} else EMIT(MIPS_INS_IMM(sr, srcr, 0, 10)); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(__mips_isa_rev) && __mips_isa_rev >= 2
|
||||
#define emith_carry_to_t(sr, is_sub) \
|
||||
EMIT(MIPS_INS_IMM(sr, FC, 0, 1))
|
||||
#else
|
||||
#define emith_carry_to_t(sr, is_sub) do { \
|
||||
emith_and_r_imm(sr, 0xfffffffe); \
|
||||
emith_or_r_r(sr, FC); \
|
||||
if (__mips_isa_rev < 2) { \
|
||||
emith_and_r_imm(sr, 0xfffffffe); \
|
||||
emith_or_r_r(sr, FC); \
|
||||
} else EMIT(MIPS_INS_IMM(sr, FC, 0, 1)); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define emith_t_to_carry(sr, is_sub) do { \
|
||||
emith_and_r_r_imm(FC, sr, 1); \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue