sh2 drc, keep T bit in host flags as long as possible

This commit is contained in:
kub 2019-05-23 19:04:31 +02:00
parent 9e36dd0e08
commit 39615f6079
3 changed files with 190 additions and 71 deletions

View file

@ -128,7 +128,7 @@ static NOINLINE void EMIT(u32 op, u32 dst, u32 src)
emit_cache[i] = emit_cache[i+1];
}
}
static void emith_flush(void)
{
int i;
@ -156,6 +156,7 @@ static void emith_flush(void)
#define A_COND_LE 0xd
#define A_COND_CS A_COND_HS
#define A_COND_CC A_COND_LO
#define A_COND_NV 0xf // Not Valid (aka NeVer :-) - ATTN: not a real condition!
/* unified conditions */
#define DCOND_EQ A_COND_EQ
@ -414,6 +415,9 @@ static void emith_op_imm2(int cond, int s, int op, int rd, int rn, unsigned int
u32 v;
int i;
if (cond == A_COND_NV)
return;
switch (op) {
case A_OP_MOV:
rn = 0;
@ -522,6 +526,9 @@ static int emith_xbranch(int cond, void *target, int is_call)
int direct = is_offset_24(val);
u32 *start_ptr = (u32 *)tcache_ptr;
if (cond == A_COND_NV)
return 0; // never taken
if (direct)
{
EOP_C_B(cond,is_call,val & 0xffffff); // b, bl target
@ -1328,3 +1335,52 @@ static inline void emith_pool_adjust(int pool_index, int move_offs)
EMITH_SJMP2_END(DCOND_NE); \
} while (0)
#ifdef T
// T bit handling
static int tcond = -1;
#define emith_invert_cond(cond) \
((cond) ^ 1)
#define emith_clr_t_cond(sr) \
(void)sr
#define emith_set_t_cond(sr, cond) \
tcond = cond
#define emith_get_t_cond() \
tcond
#define emith_invalidate_t() \
tcond = -1
#define emith_set_t(sr, val) \
tcond = ((val) ? A_COND_AL: A_COND_NV)
static void emith_sync_t(sr)
{
if (tcond == A_COND_AL)
emith_or_r_imm(sr, T);
else if (tcond == A_COND_NV)
emith_bic_r_imm(sr, T);
else if (tcond >= 0) {
emith_bic_r_imm_c(emith_invert_cond(tcond),sr, T);
emith_or_r_imm_c(tcond, sr, T);
}
tcond = -1;
}
static int emith_tst_t(int sr, int tf)
{
if (tcond < 0) {
emith_tst_r_imm(sr, T);
return tf ? DCOND_NE: DCOND_EQ;
} else if (tcond >= A_COND_AL) {
// MUST sync because A_COND_NV isn't a real condition
emith_sync_t(sr);
emith_tst_r_imm(sr, T);
return tf ? DCOND_NE: DCOND_EQ;
} else
return tf ? tcond : emith_invert_cond(tcond);
}
#endif

View file

@ -1200,3 +1200,41 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
#define emith_pool_commit(j) /**/
#define emith_insn_ptr() ((u8 *)tcache_ptr)
#define emith_flush() /**/
#ifdef T
// T bit handling
#define emith_invert_cond(cond) \
((cond) ^ 1)
static void emith_clr_t_cond(int sr)
{
emith_bic_r_imm(sr, T);
}
static void emith_set_t_cond(int sr, int cond)
{
EMITH_SJMP_START(emith_invert_cond(cond));
emith_or_r_imm_c(cond, sr, T);
EMITH_SJMP_END(emith_invert_cond(cond));
}
#define emith_get_t_cond() -1
#define emith_sync_t(sr) ((void)sr)
#define emith_invalidate_t()
static void emith_set_t(int sr, int val)
{
if (val)
emith_or_r_imm(sr, T);
else
emith_bic_r_imm(sr, T);
}
static int emith_tst_t(int sr, int tf)
{
emith_tst_r_imm(sr, T);
return tf ? DCOND_NE: DCOND_EQ;
}
#endif