mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
various small improvements and fixes
This commit is contained in:
parent
f133766faa
commit
d40a5af495
32 changed files with 372 additions and 241 deletions
|
@ -1,9 +1,3 @@
|
|||
typedef unsigned char u8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short s16;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int s32;
|
||||
|
||||
#define DRC_TCACHE_SIZE (4*1024*1024)
|
||||
|
||||
|
|
|
@ -177,26 +177,25 @@
|
|||
#define EOP_C_AM3_REG(cond,u,l,rn,rd,s,h,rm) EOP_C_AM3(cond,u,0,l,rn,rd,s,h,rm)
|
||||
|
||||
/* ldr and str */
|
||||
#define EOP_LDR_IMM2(cond,rd,rn,offset_12) EOP_C_AM2_IMM(cond,1,0,1,rn,rd,offset_12)
|
||||
#define EOP_LDRB_IMM2(cond,rd,rn,offset_12) EOP_C_AM2_IMM(cond,1,1,1,rn,rd,offset_12)
|
||||
#define EOP_LDR_IMM2(cond,rd,rn,offset_12) EOP_C_AM2_IMM(cond,(offset_12) >= 0,0,1,rn,rd,abs(offset_12))
|
||||
#define EOP_LDRB_IMM2(cond,rd,rn,offset_12) EOP_C_AM2_IMM(cond,(offset_12) >= 0,1,1,rn,rd,abs(offset_12))
|
||||
#define EOP_STR_IMM2(cond,rd,rn,offset_12) EOP_C_AM2_IMM(cond,(offset_12) >= 0,0,0,rn,rd,abs(offset_12))
|
||||
|
||||
#define EOP_LDR_IMM( rd,rn,offset_12) EOP_C_AM2_IMM(A_COND_AL,1,0,1,rn,rd,offset_12)
|
||||
#define EOP_LDR_NEGIMM(rd,rn,offset_12) EOP_C_AM2_IMM(A_COND_AL,0,0,1,rn,rd,offset_12)
|
||||
#define EOP_LDR_IMM( rd,rn,offset_12) EOP_C_AM2_IMM(A_COND_AL,(offset_12) >= 0,0,1,rn,rd,abs(offset_12))
|
||||
#define EOP_LDR_SIMPLE(rd,rn) EOP_C_AM2_IMM(A_COND_AL,1,0,1,rn,rd,0)
|
||||
#define EOP_STR_IMM( rd,rn,offset_12) EOP_C_AM2_IMM(A_COND_AL,1,0,0,rn,rd,offset_12)
|
||||
#define EOP_STR_IMM( rd,rn,offset_12) EOP_C_AM2_IMM(A_COND_AL,(offset_12) >= 0,0,0,rn,rd,abs(offset_12))
|
||||
#define EOP_STR_SIMPLE(rd,rn) EOP_C_AM2_IMM(A_COND_AL,1,0,0,rn,rd,0)
|
||||
|
||||
#define EOP_LDR_REG_LSL(cond,rd,rn,rm,shift_imm) EOP_C_AM2_REG(cond,1,0,1,rn,rd,shift_imm,A_AM1_LSL,rm)
|
||||
#define EOP_LDRB_REG_LSL(cond,rd,rn,rm,shift_imm) EOP_C_AM2_REG(cond,1,1,1,rn,rd,shift_imm,A_AM1_LSL,rm);
|
||||
|
||||
#define EOP_LDRH_IMM2(cond,rd,rn,offset_8) EOP_C_AM3_IMM(cond,1,1,rn,rd,0,1,offset_8)
|
||||
#define EOP_LDRH_IMM2(cond,rd,rn,offset_8) EOP_C_AM3_IMM(cond,(offset_8) >= 0,1,rn,rd,0,1,abs(offset_8))
|
||||
#define EOP_LDRH_REG2(cond,rd,rn,rm) EOP_C_AM3_REG(cond,1,1,rn,rd,0,1,rm)
|
||||
|
||||
#define EOP_LDRH_IMM( rd,rn,offset_8) EOP_C_AM3_IMM(A_COND_AL,1,1,rn,rd,0,1,offset_8)
|
||||
#define EOP_LDRH_IMM( rd,rn,offset_8) EOP_C_AM3_IMM(A_COND_AL,(offset_8) >= 0,1,rn,rd,0,1,abs(offset_8))
|
||||
#define EOP_LDRH_SIMPLE(rd,rn) EOP_C_AM3_IMM(A_COND_AL,1,1,rn,rd,0,1,0)
|
||||
#define EOP_LDRH_REG( rd,rn,rm) EOP_C_AM3_REG(A_COND_AL,1,1,rn,rd,0,1,rm)
|
||||
#define EOP_STRH_IMM( rd,rn,offset_8) EOP_C_AM3_IMM(A_COND_AL,1,0,rn,rd,0,1,offset_8)
|
||||
#define EOP_STRH_IMM( rd,rn,offset_8) EOP_C_AM3_IMM(A_COND_AL,(offset_8) >= 0,0,rn,rd,0,1,abs(offset_8))
|
||||
#define EOP_STRH_SIMPLE(rd,rn) EOP_C_AM3_IMM(A_COND_AL,1,0,rn,rd,0,1,0)
|
||||
#define EOP_STRH_REG( rd,rn,rm) EOP_C_AM3_REG(A_COND_AL,1,0,rn,rd,0,1,rm)
|
||||
|
||||
|
@ -285,11 +284,29 @@ static void emith_op_imm2(int cond, int s, int op, int rd, int rn, unsigned int
|
|||
imm = ~imm;
|
||||
op = A_OP_MVN;
|
||||
}
|
||||
#ifdef HAVE_ARMV7
|
||||
for (v = imm, ror2 = 0; v && !(v & 3); v >>= 2)
|
||||
ror2--;
|
||||
if (v >> 8) {
|
||||
/* 2+ insns needed - prefer movw/movt */
|
||||
if (op == A_OP_MVN)
|
||||
imm = ~imm;
|
||||
EOP_MOVW(rd, imm);
|
||||
if (imm & 0xffff0000)
|
||||
EOP_MOVT(rd, imm);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case A_OP_EOR:
|
||||
case A_OP_SUB:
|
||||
case A_OP_ADD:
|
||||
// count bits in imm and swap ADD and SUB if more bits 1 than 0
|
||||
if (s == 0 && count_bits(imm) > 16) {
|
||||
imm = -imm;
|
||||
op ^= (A_OP_ADD^A_OP_SUB);
|
||||
}
|
||||
case A_OP_EOR:
|
||||
case A_OP_ORR:
|
||||
case A_OP_BIC:
|
||||
if (s == 0 && imm == 0 && rd == rn)
|
||||
|
@ -412,6 +429,8 @@ static int emith_xbranch(int cond, void *target, int is_call)
|
|||
|
||||
#define emith_add_r_r_r_lsl(d, s1, s2, lslimm) \
|
||||
EOP_ADD_REG(A_COND_AL,0,d,s1,s2,A_AM1_LSL,lslimm)
|
||||
#define emith_add_r_r_r_lsl_ptr(d, s1, s2, lslimm) \
|
||||
emith_add_r_r_r_lsl(d, s1, s2, lslimm)
|
||||
|
||||
#define emith_addf_r_r_r_lsl(d, s1, s2, lslimm) \
|
||||
EOP_ADD_REG(A_COND_AL,1,d,s1,s2,A_AM1_LSL,lslimm)
|
||||
|
@ -483,7 +502,7 @@ static int emith_xbranch(int cond, void *target, int is_call)
|
|||
emith_add_r_r_r(d, d, s)
|
||||
|
||||
#define emith_sub_r_r(d, s) \
|
||||
EOP_SUB_REG(A_COND_AL,0,d,d,s,A_AM1_LSL,0)
|
||||
emith_sub_r_r_r(d, d, s)
|
||||
|
||||
#define emith_adc_r_r(d, s) \
|
||||
EOP_ADC_REG(A_COND_AL,0,d,d,s,A_AM1_LSL,0)
|
||||
|
@ -529,6 +548,9 @@ static int emith_xbranch(int cond, void *target, int is_call)
|
|||
#define emith_move_r_imm(r, imm) \
|
||||
emith_op_imm(A_COND_AL, 0, A_OP_MOV, r, imm)
|
||||
|
||||
#define emith_move_r_ptr_imm(r, imm) \
|
||||
emith_move_r_imm(r, (u32)(imm))
|
||||
|
||||
#define emith_add_r_imm(r, imm) \
|
||||
emith_op_imm(A_COND_AL, 0, A_OP_ADD, r, imm)
|
||||
|
||||
|
@ -536,7 +558,7 @@ static int emith_xbranch(int cond, void *target, int is_call)
|
|||
emith_op_imm(A_COND_AL, 0, A_OP_ADC, r, imm)
|
||||
|
||||
#define emith_adcf_r_imm(r, imm) \
|
||||
emith_op_imm(A_COND_AL, 1, A_OP_ADC, r, (imm))
|
||||
emith_op_imm(A_COND_AL, 1, A_OP_ADC, r, imm)
|
||||
|
||||
#define emith_sub_r_imm(r, imm) \
|
||||
emith_op_imm(A_COND_AL, 0, A_OP_SUB, r, imm)
|
||||
|
@ -610,13 +632,13 @@ static int emith_xbranch(int cond, void *target, int is_call)
|
|||
emith_op_imm2(A_COND_AL, 0, A_OP_SUB, d, s, imm)
|
||||
|
||||
#define emith_subf_r_r_imm(d, s, imm) \
|
||||
emith_op_imm2(A_COND_AL, 1, A_OP_SUB, d, s, (imm))
|
||||
emith_op_imm2(A_COND_AL, 1, A_OP_SUB, d, s, imm)
|
||||
|
||||
#define emith_or_r_r_imm(d, s, imm) \
|
||||
emith_op_imm2(A_COND_AL, 0, A_OP_ORR, d, s, (imm))
|
||||
emith_op_imm2(A_COND_AL, 0, A_OP_ORR, d, s, imm)
|
||||
|
||||
#define emith_eor_r_r_imm(d, s, imm) \
|
||||
emith_op_imm2(A_COND_AL, 0, A_OP_EOR, d, s, (imm))
|
||||
emith_op_imm2(A_COND_AL, 0, A_OP_EOR, d, s, imm)
|
||||
|
||||
#define emith_neg_r_r(d, s) \
|
||||
EOP_RSB_IMM(d, s, 0, 0)
|
||||
|
@ -758,7 +780,7 @@ static int emith_xbranch(int cond, void *target, int is_call)
|
|||
#define emith_clear_msb_c(cond, d, s, count) { \
|
||||
u32 t; \
|
||||
if ((count) <= 8) { \
|
||||
t = (count) - 8; \
|
||||
t = 8 - (count); \
|
||||
t = (0xff << t) & 0xff; \
|
||||
EOP_C_DOP_IMM(cond,A_OP_BIC,0,s,d,8/2,t); \
|
||||
} else if ((count) >= 24) { \
|
||||
|
@ -880,7 +902,9 @@ static int emith_xbranch(int cond, void *target, int is_call)
|
|||
#define emith_sh2_rcall(a, tab, func, mask) { \
|
||||
emith_lsr(mask, a, SH2_READ_SHIFT); \
|
||||
EOP_ADD_REG_LSL(tab, tab, mask, 3); \
|
||||
EOP_LDMIA(tab, (1<<func)|(1<<mask)); \
|
||||
if (func < mask) EOP_LDMIA(tab, (1<<func)|(1<<mask)); /* ldm if possible */ \
|
||||
else { emith_read_r_r_offs(func, tab, 0); \
|
||||
emith_read_r_r_offs(mask, tab, 4); } \
|
||||
emith_addf_r_r_r(func,func,func); \
|
||||
}
|
||||
|
||||
|
|
|
@ -194,6 +194,17 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define emith_add_r_r_r_ptr(d, s1, s2) do { \
|
||||
if (d == s1) { \
|
||||
emith_add_r_r_ptr(d, s2); \
|
||||
} else if (d == s2) { \
|
||||
emith_add_r_r_ptr(d, s1); \
|
||||
} else { \
|
||||
emith_move_r_r_ptr(d, s1); \
|
||||
emith_add_r_r_ptr(d, s2); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define emith_sub_r_r_r(d, s1, s2) do { \
|
||||
if (d == s1) { \
|
||||
emith_sub_r_r(d, s2); \
|
||||
|
@ -268,9 +279,16 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
|
|||
rcache_free_tmp(tmp_); \
|
||||
} while (0)
|
||||
|
||||
#define emith_add_r_r_r_lsr(d, s1, s2, lslimm) do { \
|
||||
#define emith_add_r_r_r_lsl_ptr(d, s1, s2, lslimm) do { \
|
||||
int tmp_ = rcache_get_tmp(); \
|
||||
emith_lsr(tmp_, s2, lslimm); \
|
||||
emith_lsl(tmp_, s2, lslimm); \
|
||||
emith_add_r_r_r_ptr(d, s1, tmp_); \
|
||||
rcache_free_tmp(tmp_); \
|
||||
} while (0)
|
||||
|
||||
#define emith_add_r_r_r_lsr(d, s1, s2, lsrimm) do { \
|
||||
int tmp_ = rcache_get_tmp(); \
|
||||
emith_lsr(tmp_, s2, lsrimm); \
|
||||
emith_add_r_r_r(d, s1, tmp_); \
|
||||
rcache_free_tmp(tmp_); \
|
||||
} while (0)
|
||||
|
@ -297,6 +315,16 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
|
|||
EMIT(imm, u32); \
|
||||
} while (0)
|
||||
|
||||
#define emith_move_r_ptr_imm(r, imm) do { \
|
||||
if ((uint64_t)(imm) <= UINT32_MAX) \
|
||||
emith_move_r_imm(r, (uintptr_t)(imm)); \
|
||||
else { \
|
||||
EMIT_REX_IF(1, 0, r); \
|
||||
EMIT_OP(0xb8 + (r)); \
|
||||
EMIT((uint64_t)(imm), uint64_t); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define emith_move_r_imm_s8(r, imm) \
|
||||
emith_move_r_imm(r, (u32)(signed int)(signed char)(imm))
|
||||
|
||||
|
@ -421,27 +449,28 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
|
|||
#define emith_sub_r_r_imm(d, s, imm) do { \
|
||||
if (d != s) \
|
||||
emith_move_r_r(d, s); \
|
||||
if (imm) \
|
||||
if ((s32)(imm) != 0) \
|
||||
emith_sub_r_imm(d, imm); \
|
||||
} while (0)
|
||||
|
||||
#define emith_and_r_r_imm(d, s, imm) do { \
|
||||
if (d != s) \
|
||||
emith_move_r_r(d, s); \
|
||||
emith_and_r_imm(d, imm); \
|
||||
if ((s32)(imm) != -1) \
|
||||
emith_and_r_imm(d, imm); \
|
||||
} while (0)
|
||||
|
||||
#define emith_or_r_r_imm(d, s, imm) do { \
|
||||
if (d != s) \
|
||||
emith_move_r_r(d, s); \
|
||||
if ((s32)imm != 0) \
|
||||
if ((s32)(imm) != 0) \
|
||||
emith_or_r_imm(d, imm); \
|
||||
} while (0)
|
||||
|
||||
#define emith_eor_r_r_imm(d, s, imm) do { \
|
||||
if (d != s) \
|
||||
emith_move_r_r(d, s); \
|
||||
if ((s32)imm != 0) \
|
||||
if ((s32)(imm) != 0) \
|
||||
emith_eor_r_imm(d, imm); \
|
||||
} while (0)
|
||||
|
||||
|
@ -612,31 +641,17 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
|
|||
EMIT_REX_IF(1, r, rs); \
|
||||
emith_deref_op(0x89, r, rs, offs)
|
||||
|
||||
// note: don't use prefixes on this
|
||||
#define emith_read8_r_r_offs(r, rs, offs) do { \
|
||||
int r_ = r; \
|
||||
if (!is_abcdx(r)) \
|
||||
r_ = rcache_get_tmp(); \
|
||||
EMIT(0x0f, u8); \
|
||||
emith_deref_op(0xb6, r_, rs, offs); \
|
||||
if ((r) != r_) { \
|
||||
emith_move_r_r(r, r_); \
|
||||
rcache_free_tmp(r_); \
|
||||
} \
|
||||
emith_deref_op(0xb6, r, rs, offs); \
|
||||
} while (0)
|
||||
|
||||
#define emith_read8s_r_r_offs(r, rs, offs) do { \
|
||||
int r_ = r; \
|
||||
if (!is_abcdx(r)) \
|
||||
r_ = rcache_get_tmp(); \
|
||||
EMIT(0x0f, u8); \
|
||||
emith_deref_op(0xbe, r_, rs, offs); \
|
||||
if ((r) != r_) { \
|
||||
emith_move_r_r(r, r_); \
|
||||
rcache_free_tmp(r_); \
|
||||
} \
|
||||
emith_deref_op(0xbe, r, rs, offs); \
|
||||
} while (0)
|
||||
|
||||
// note: don't use prefixes on this
|
||||
#define emith_write8_r_r_offs(r, rs, offs) do {\
|
||||
int r_ = r; \
|
||||
if (!is_abcdx(r)) { \
|
||||
|
@ -664,16 +679,9 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
|
|||
} while (0)
|
||||
|
||||
#define emith_read8_r_r_r(r, rs, rm) do { \
|
||||
int r_ = r; \
|
||||
if (!is_abcdx(r)) \
|
||||
r_ = rcache_get_tmp(); \
|
||||
EMIT(0x0f, u8); \
|
||||
EMIT_OP_MODRM(0xb6, 0, r, 4); \
|
||||
EMIT_SIB(0, rs, rm); /* mov r, [rm + rs * 1] */ \
|
||||
if ((r) != r_) { \
|
||||
emith_move_r_r(r, r_); \
|
||||
rcache_free_tmp(r_); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define emith_read16_r_r_r(r, rs, rm) do { \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue