From 83a9e3050807584bc7ee2ea79519ecd3b8a94c80 Mon Sep 17 00:00:00 2001 From: kub Date: Mon, 1 May 2023 09:08:23 +0000 Subject: [PATCH] sh2 drc, cleanup and minor fixes (risc-v, division, typos) --- cpu/drc/emit_riscv.c | 6 +++--- cpu/sh2/compiler.c | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cpu/drc/emit_riscv.c b/cpu/drc/emit_riscv.c index 2b597608..832575b2 100644 --- a/cpu/drc/emit_riscv.c +++ b/cpu/drc/emit_riscv.c @@ -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) { emith_move_r_imm(AT, imm); 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)); } @@ -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)); } else { 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)); } } @@ -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)); } else { 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)); } } diff --git a/cpu/sh2/compiler.c b/cpu/sh2/compiler.c index 53721b7c..d7ae8960 100644 --- a/cpu/sh2/compiler.c +++ b/cpu/sh2/compiler.c @@ -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])); exit(1); } - fsh2.sr = (fsh2.sr & 0xfff) | (sh2->sr & ~0xfff); + fsh2.sr = (fsh2.sr & 0xbff) | (sh2->sr & ~0xbff); fsh2.is_slave = idx; if (memcmp(&fsh2, sh2, offsetof(SH2, read8_map)) || 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) { - 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 uint32_t quot = dv / (ds>>16), rem = dv - (quot * (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) { - if (ds > dh) { + uint64_t dv = *dl | ((uint64_t)dh << 32); + if (likely(ds > dh)) { // good case: no overflow, divisor not 0 - uint64_t dv = *dl | ((uint64_t)dh << 32); uint32_t quot = dv / ds, rem = dv - ((uint64_t)quot * ds); if (~quot&1) rem -= ds; *dl = quot; return rem; } else { // 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; while (s--) { 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) { 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 uint32_t quot = adv / ads, rem = adv - (quot * ads); 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) { 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); - 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 uint32_t quot = adv / ads, rem = adv - ((uint64_t)quot * ads); 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; } else { // 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; while (s--) { 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 // since they are reloaded in the loop entry code emith_cmp_r_imm(sr, 0); - EMITH_JMP_START(DCOND_GE); + EMITH_JMP_START(DCOND_GT); rcache_save_pinned(); 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); emith_cmp_r_imm(sr, 0); 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_SJMP_END(DCOND_GT); rcache_free_tmp(tmp); -- 2.39.5