aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornotaz2011-10-07 02:27:32 +0300
committernotaz2011-10-08 03:29:31 +0300
commitdc49e339fa9e3a4061af703e85568d76526eac46 (patch)
tree7c7cb9aa29e7d5d0ef2b89567611f5f7507a0c9b
parent76d1d09c1224af8d663ce63dc5b32425bd62cb29 (diff)
downloadpcsx_rearmed-dc49e339fa9e3a4061af703e85568d76526eac46.tar.gz
pcsx_rearmed-dc49e339fa9e3a4061af703e85568d76526eac46.tar.bz2
pcsx_rearmed-dc49e339fa9e3a4061af703e85568d76526eac46.zip
drc: implement shiftimm constant propagation
it's rare, but it happens.
-rw-r--r--libpcsxcore/new_dynarec/new_dynarec.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c
index a263564..610f86a 100644
--- a/libpcsxcore/new_dynarec/new_dynarec.c
+++ b/libpcsxcore/new_dynarec/new_dynarec.c
@@ -1391,8 +1391,6 @@ void mov_alloc(struct regstat *current,int i)
void shiftimm_alloc(struct regstat *current,int i)
{
- clear_const(current,rs1[i]);
- clear_const(current,rt1[i]);
if(opcode2[i]<=0x3) // SLL/SRL/SRA
{
if(rt1[i]) {
@@ -1401,8 +1399,21 @@ void shiftimm_alloc(struct regstat *current,int i)
alloc_reg(current,i,rt1[i]);
current->is32|=1LL<<rt1[i];
dirty_reg(current,rt1[i]);
+ if(is_const(current,rs1[i])) {
+ int v=get_const(current,rs1[i]);
+ if(opcode2[i]==0x00) set_const(current,rt1[i],v<<imm[i]);
+ if(opcode2[i]==0x02) set_const(current,rt1[i],(u_int)v>>imm[i]);
+ if(opcode2[i]==0x03) set_const(current,rt1[i],v>>imm[i]);
+ }
+ else clear_const(current,rt1[i]);
}
}
+ else
+ {
+ clear_const(current,rs1[i]);
+ clear_const(current,rt1[i]);
+ }
+
if(opcode2[i]>=0x38&&opcode2[i]<=0x3b) // DSLL/DSRL/DSRA
{
if(rt1[i]) {
@@ -2688,7 +2699,7 @@ void shiftimm_assemble(int i,struct regstat *i_regs)
t=get_reg(i_regs->regmap,rt1[i]);
s=get_reg(i_regs->regmap,rs1[i]);
//assert(t>=0);
- if(t>=0){
+ if(t>=0&&!((i_regs->isconst>>t)&1)){
if(rs1[i]==0)
{
emit_zeroreg(t);