mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
sh2 drc, cleanup and minor fixes (risc-v, division, typos)
This commit is contained in:
parent
110a49ed2a
commit
83a9e30508
2 changed files with 14 additions and 14 deletions
|
@ -761,7 +761,7 @@ static void emith_op_imm(int f1, int rd, int rs, u32 imm)
|
||||||
if ((imm + _CB(imm,1,11,12)) >> 12) {
|
if ((imm + _CB(imm,1,11,12)) >> 12) {
|
||||||
emith_move_r_imm(AT, imm);
|
emith_move_r_imm(AT, imm);
|
||||||
EMIT(R5_R_INSN(OP_REG^op32, f1&7,_, rd, rs, AT));
|
EMIT(R5_R_INSN(OP_REG^op32, f1&7,_, rd, rs, AT));
|
||||||
} else if (imm + (f1 == F1_AND) || rd != rs)
|
} else if (imm || f1 == F1_AND || rd != rs)
|
||||||
EMIT(R5_I_INSN(OP_IMM^op32, f1&7, rd, rs, imm));
|
EMIT(R5_I_INSN(OP_IMM^op32, f1&7, rd, rs, imm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1035,7 +1035,7 @@ static void emith_ld_offs(int sz, int rd, int rs, int o12)
|
||||||
EMIT(R5_I_INSN(OP_LD, sz, rd, rs, o12));
|
EMIT(R5_I_INSN(OP_LD, sz, rd, rs, o12));
|
||||||
} else {
|
} else {
|
||||||
EMIT(R5_MOVT_IMM(AT, o12 + _CB(o12,1,11,12))); \
|
EMIT(R5_MOVT_IMM(AT, o12 + _CB(o12,1,11,12))); \
|
||||||
EMIT(R5_R_INSN(OP_REG, F1_ADD,_, AT, rs, AT)); \
|
EMIT(R5_ADD_REG(AT, rs, AT)); \
|
||||||
EMIT(R5_I_INSN(OP_LD, sz, rd, AT, o12));
|
EMIT(R5_I_INSN(OP_LD, sz, rd, AT, o12));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1115,7 +1115,7 @@ static void emith_st_offs(int sz, int rt, int rs, int o12)
|
||||||
EMIT(R5_S_INSN(OP_ST, sz, rt, rs, o12));
|
EMIT(R5_S_INSN(OP_ST, sz, rt, rs, o12));
|
||||||
} else {
|
} else {
|
||||||
EMIT(R5_MOVT_IMM(AT, o12 + _CB(o12,1,11,12))); \
|
EMIT(R5_MOVT_IMM(AT, o12 + _CB(o12,1,11,12))); \
|
||||||
EMIT(R5_R_INSN(OP_REG, F1_ADD,_, AT, rs, AT)); \
|
EMIT(R5_ADD_REG(AT, rs, AT)); \
|
||||||
EMIT(R5_S_INSN(OP_ST, sz, rt, AT, o12));
|
EMIT(R5_S_INSN(OP_ST, sz, rt, AT, o12));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,7 +260,7 @@ static void REGPARM(3) *sh2_drc_log_entry(void *block, SH2 *sh2, u32 sr)
|
||||||
printf("trace eof at %08lx\n",ftell(trace[idx]));
|
printf("trace eof at %08lx\n",ftell(trace[idx]));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fsh2.sr = (fsh2.sr & 0xfff) | (sh2->sr & ~0xfff);
|
fsh2.sr = (fsh2.sr & 0xbff) | (sh2->sr & ~0xbff);
|
||||||
fsh2.is_slave = idx;
|
fsh2.is_slave = idx;
|
||||||
if (memcmp(&fsh2, sh2, offsetof(SH2, read8_map)) ||
|
if (memcmp(&fsh2, sh2, offsetof(SH2, read8_map)) ||
|
||||||
0)//memcmp(&fsh2.pdb_io_csum, &sh2->pdb_io_csum, sizeof(sh2->pdb_io_csum)))
|
0)//memcmp(&fsh2.pdb_io_csum, &sh2->pdb_io_csum, sizeof(sh2->pdb_io_csum)))
|
||||||
|
@ -3043,7 +3043,7 @@ static void emit_do_static_regs(int is_write, int tmpr)
|
||||||
|
|
||||||
static uint32_t REGPARM(3) sh2_drc_divu32(uint32_t dv, uint32_t *dt, uint32_t ds)
|
static uint32_t REGPARM(3) sh2_drc_divu32(uint32_t dv, uint32_t *dt, uint32_t ds)
|
||||||
{
|
{
|
||||||
if (ds > dv && (uint16_t)ds == 0) {
|
if (likely(ds > dv && (uint16_t)ds == 0)) {
|
||||||
// good case: no overflow, divisor not 0, lower 16 bits 0
|
// good case: no overflow, divisor not 0, lower 16 bits 0
|
||||||
uint32_t quot = dv / (ds>>16), rem = dv - (quot * (ds>>16));
|
uint32_t quot = dv / (ds>>16), rem = dv - (quot * (ds>>16));
|
||||||
if (~quot&1) rem -= ds>>16;
|
if (~quot&1) rem -= ds>>16;
|
||||||
|
@ -3068,16 +3068,15 @@ static uint32_t REGPARM(3) sh2_drc_divu32(uint32_t dv, uint32_t *dt, uint32_t ds
|
||||||
|
|
||||||
static uint32_t REGPARM(3) sh2_drc_divu64(uint32_t dh, uint32_t *dl, uint32_t ds)
|
static uint32_t REGPARM(3) sh2_drc_divu64(uint32_t dh, uint32_t *dl, uint32_t ds)
|
||||||
{
|
{
|
||||||
if (ds > dh) {
|
|
||||||
// good case: no overflow, divisor not 0
|
|
||||||
uint64_t dv = *dl | ((uint64_t)dh << 32);
|
uint64_t dv = *dl | ((uint64_t)dh << 32);
|
||||||
|
if (likely(ds > dh)) {
|
||||||
|
// good case: no overflow, divisor not 0
|
||||||
uint32_t quot = dv / ds, rem = dv - ((uint64_t)quot * ds);
|
uint32_t quot = dv / ds, rem = dv - ((uint64_t)quot * ds);
|
||||||
if (~quot&1) rem -= ds;
|
if (~quot&1) rem -= ds;
|
||||||
*dl = quot;
|
*dl = quot;
|
||||||
return rem;
|
return rem;
|
||||||
} else {
|
} else {
|
||||||
// bad case: use the sh2 algo to get the right result
|
// bad case: use the sh2 algo to get the right result
|
||||||
uint64_t dv = *dl | ((uint64_t)dh << 32);
|
|
||||||
int q = 0, t = 0, s = 32;
|
int q = 0, t = 0, s = 32;
|
||||||
while (s--) {
|
while (s--) {
|
||||||
uint64_t v = dv>>63;
|
uint64_t v = dv>>63;
|
||||||
|
@ -3096,7 +3095,7 @@ static uint32_t REGPARM(3) sh2_drc_divu64(uint32_t dh, uint32_t *dl, uint32_t ds
|
||||||
static uint32_t REGPARM(3) sh2_drc_divs32(int32_t dv, uint32_t *dt, int32_t ds)
|
static uint32_t REGPARM(3) sh2_drc_divs32(int32_t dv, uint32_t *dt, int32_t ds)
|
||||||
{
|
{
|
||||||
uint32_t adv = abs(dv), ads = abs(ds)>>16;
|
uint32_t adv = abs(dv), ads = abs(ds)>>16;
|
||||||
if (ads > adv>>16 && ds != 0x80000000 && (int16_t)ds == 0) {
|
if (likely(ads > adv>>16 && ds != 0x80000000 && (int16_t)ds == 0)) {
|
||||||
// good case: no overflow, divisor not 0 and not MIN_INT, lower 16 bits 0
|
// good case: no overflow, divisor not 0 and not MIN_INT, lower 16 bits 0
|
||||||
uint32_t quot = adv / ads, rem = adv - (quot * ads);
|
uint32_t quot = adv / ads, rem = adv - (quot * ads);
|
||||||
int m1 = (rem ? dv^ds : ds) < 0;
|
int m1 = (rem ? dv^ds : ds) < 0;
|
||||||
|
@ -3125,9 +3124,10 @@ static uint32_t REGPARM(3) sh2_drc_divs32(int32_t dv, uint32_t *dt, int32_t ds)
|
||||||
static uint32_t REGPARM(3) sh2_drc_divs64(int32_t dh, uint32_t *dl, int32_t ds)
|
static uint32_t REGPARM(3) sh2_drc_divs64(int32_t dh, uint32_t *dl, int32_t ds)
|
||||||
{
|
{
|
||||||
int64_t _dv = *dl | ((int64_t)dh << 32);
|
int64_t _dv = *dl | ((int64_t)dh << 32);
|
||||||
uint64_t adv = (_dv < 0 ? -_dv : _dv); // llabs isn't in older toolchains
|
|
||||||
uint32_t ads = abs(ds);
|
uint32_t ads = abs(ds);
|
||||||
if (ads > adv>>32 && ds != 0x80000000) {
|
if (likely(_dv >= 0 && ads > _dv>>32 && ds != 0x80000000) ||
|
||||||
|
likely(_dv < 0 && ads > -_dv>>32 && ds != 0x80000000)) {
|
||||||
|
uint64_t adv = (_dv < 0 ? -_dv : _dv); // no llabs in older toolchains
|
||||||
// good case: no overflow, divisor not 0 and not MIN_INT
|
// good case: no overflow, divisor not 0 and not MIN_INT
|
||||||
uint32_t quot = adv / ads, rem = adv - ((uint64_t)quot * ads);
|
uint32_t quot = adv / ads, rem = adv - ((uint64_t)quot * ads);
|
||||||
int m1 = (rem ? dh^ds : ds) < 0;
|
int m1 = (rem ? dh^ds : ds) < 0;
|
||||||
|
@ -3138,7 +3138,7 @@ static uint32_t REGPARM(3) sh2_drc_divs64(int32_t dh, uint32_t *dl, int32_t ds)
|
||||||
return rem;
|
return rem;
|
||||||
} else {
|
} else {
|
||||||
// bad case: use the sh2 algo to get the right result
|
// bad case: use the sh2 algo to get the right result
|
||||||
uint64_t dv = *dl | ((uint64_t)dh << 32);
|
uint64_t dv = (uint64_t)_dv;
|
||||||
int m = (uint32_t)ds>>31, q = (uint64_t)dv>>63, t = m^q, s = 32;
|
int m = (uint32_t)ds>>31, q = (uint64_t)dv>>63, t = m^q, s = 32;
|
||||||
while (s--) {
|
while (s--) {
|
||||||
uint64_t v = (uint64_t)dv>>63;
|
uint64_t v = (uint64_t)dv>>63;
|
||||||
|
@ -3539,7 +3539,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
||||||
// if exiting a pinned loop pinned regs must be written back to ctx
|
// if exiting a pinned loop pinned regs must be written back to ctx
|
||||||
// since they are reloaded in the loop entry code
|
// since they are reloaded in the loop entry code
|
||||||
emith_cmp_r_imm(sr, 0);
|
emith_cmp_r_imm(sr, 0);
|
||||||
EMITH_JMP_START(DCOND_GE);
|
EMITH_JMP_START(DCOND_GT);
|
||||||
rcache_save_pinned();
|
rcache_save_pinned();
|
||||||
|
|
||||||
if (blx_target_count < ARRAY_SIZE(blx_targets)) {
|
if (blx_target_count < ARRAY_SIZE(blx_targets)) {
|
||||||
|
@ -3569,7 +3569,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
||||||
tmp = rcache_get_tmp_arg(0);
|
tmp = rcache_get_tmp_arg(0);
|
||||||
emith_cmp_r_imm(sr, 0);
|
emith_cmp_r_imm(sr, 0);
|
||||||
EMITH_SJMP_START(DCOND_GT);
|
EMITH_SJMP_START(DCOND_GT);
|
||||||
emith_move_r_imm_c(DCOND_LT, tmp, pc);
|
emith_move_r_imm_c(DCOND_LE, tmp, pc);
|
||||||
emith_jump_cond(DCOND_LE, sh2_drc_exit);
|
emith_jump_cond(DCOND_LE, sh2_drc_exit);
|
||||||
EMITH_SJMP_END(DCOND_GT);
|
EMITH_SJMP_END(DCOND_GT);
|
||||||
rcache_free_tmp(tmp);
|
rcache_free_tmp(tmp);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue