svp compiler: few more optimizations

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@389 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2008-03-19 22:13:59 +00:00
parent 34e243f167
commit 2385f27374
2 changed files with 88 additions and 6 deletions

View file

@ -277,6 +277,14 @@ static void tr_flush_dirty_prs(void)
{
int i, ror = 0, reg;
int dirty = dirty_regb >> 8;
if ((dirty&7) == 7) {
emit_mov_const(A_COND_AL, 8, known_regs.r[0]|(known_regs.r[1]<<8)|(known_regs.r[2]<<16));
dirty &= ~7;
}
if ((dirty&0x70) == 0x70) {
emit_mov_const(A_COND_AL, 9, known_regs.r[4]|(known_regs.r[5]<<8)|(known_regs.r[6]<<16));
dirty &= ~0x70;
}
/* r0-r7 */
for (i = 0; dirty && i < 8; i++, dirty >>= 1)
{
@ -558,6 +566,69 @@ static void tr_rX_read2(int op)
hostreg_r[0] = hostreg_r[2] = -1;
}
// check if AL is going to be used later in block
static int tr_predict_al_need(void)
{
int tmpv, tmpv2, op, pc = known_regs.gr[SSP_PC].h;
while (1)
{
op = PROGRAM(pc);
switch (op >> 9)
{
// ld d, s
case 0x00:
tmpv2 = (op >> 4) & 0xf; // dst
tmpv = op & 0xf; // src
if ((tmpv2 == SSP_A && tmpv == SSP_P) || tmpv2 == SSP_AL) // ld A, P; ld AL, *
return 0;
break;
// ld (ri), s
case 0x02:
// ld ri, s
case 0x0a:
// OP a, s
case 0x10: case 0x30: case 0x40: case 0x60: case 0x70:
tmpv = op & 0xf; // src
if (tmpv == SSP_AL) // OP *, AL
return 1;
break;
case 0x04:
case 0x06:
case 0x14:
case 0x34:
case 0x44:
case 0x64:
case 0x74: pc++; break;
// call cond, addr
case 0x24:
// bra cond, addr
case 0x26:
// mod cond, op
case 0x48:
// mpys?
case 0x1b:
// mpya (rj), (ri), b
case 0x4b: return 1;
// mld (rj), (ri), b
case 0x5b: return 0; // cleared anyway
// and A, *
case 0x50:
tmpv = op & 0xf; // src
if (tmpv == SSP_AL) return 1;
case 0x51: case 0x53: case 0x54: case 0x55: case 0x59: case 0x5c:
return 0;
}
pc++;
}
}
/* get ARM cond which would mean that SSP cond is satisfied. No trash. */
static int tr_cond_check(int op)
{
@ -877,9 +948,13 @@ static void tr_r0_to_Y(int const_val)
static void tr_r0_to_A(int const_val)
{
EOP_MOV_REG_LSL(5, 5, 16); // mov r5, r5, lsl #16
EOP_MOV_REG_LSR(5, 5, 16); // mov r5, r5, lsr #16 @ AL
EOP_ORR_REG_LSL(5, 5, 0, 16); // orr r5, r5, r0, lsl #16
if (tr_predict_al_need()) {
EOP_MOV_REG_LSL(5, 5, 16); // mov r5, r5, lsl #16
EOP_MOV_REG_LSR(5, 5, 16); // mov r5, r5, lsr #16 @ AL
EOP_ORR_REG_LSL(5, 5, 0, 16); // orr r5, r5, r0, lsl #16
}
else
EOP_MOV_REG_LSL(5, 0, 16);
TR_WRITE_R0_TO_REG(SSP_A);
}
@ -1206,8 +1281,15 @@ static int translate_op(unsigned int op, int *pc, int imm, int *end_cond, int *j
ret = tr_detect_rotate(op, pc, imm);
if (ret > 0) break;
if (tmpv != 0)
tr_rX_read(r, mod);
else tr_ptrr_mod(r, mod, 1, 1);
tr_rX_read(r, mod);
else {
int cnt = 1;
while (PROGRAM(*pc) == op) {
(*pc)++; cnt++; ret++;
n_in_ops++;
}
tr_ptrr_mod(r, mod, 1, cnt); // skip
}
tr_write_funcs[tmpv](-1);
if (tmpv == SSP_PC) {
ret |= 0x10000;

View file

@ -13,7 +13,7 @@
#endif
svp_t *svp = NULL;
int PicoSVPCycles = 1000; // cycles/line
int PicoSVPCycles = 820; // cycles/line, just a guess
/* save state stuff */
typedef enum {