X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fnew_dynarec%2Fassem_arm.c;h=0c16fc235d101063313ef6b705f98f5ae6e384d6;hp=ddbfafaa6394073664528eefdbc750ab8e48ea19;hb=8575a877a535931198a3d0105cf0e6675a9d0c17;hpb=82ed88ebe25a0312aab83623b5a983bd96f3d830 diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c index ddbfafaa..0c16fc23 100644 --- a/libpcsxcore/new_dynarec/assem_arm.c +++ b/libpcsxcore/new_dynarec/assem_arm.c @@ -1149,7 +1149,7 @@ void emit_addimm(u_int rs,int imm,u_int rt) assem_debug("add %s,%s,#%d\n",regname[rt],regname[rs],imm); output_w32(0xe2800000|rd_rn_rm(rt,rs,0)|armval); }else if(genimm(-imm,&armval)) { - assem_debug("sub %s,%s,#%d\n",regname[rt],regname[rs],imm); + assem_debug("sub %s,%s,#%d\n",regname[rt],regname[rs],-imm); output_w32(0xe2400000|rd_rn_rm(rt,rs,0)|armval); }else if(imm<0) { assert(imm>-65536); @@ -2726,14 +2726,45 @@ emit_extjump_ds(int addr, int target) // put rt_val into rt, potentially making use of rs with value rs_val static void emit_movimm_from(u_int rs_val,int rs,u_int rt_val,int rt) { - u_int xor=rs_val^rt_val; + u_int armval; + int diff; + if(genimm(rt_val,&armval)) { + assem_debug("mov %s,#%d\n",regname[rt],rt_val); + output_w32(0xe3a00000|rd_rn_rm(rt,0,0)|armval); + return; + } + if(genimm(~rt_val,&armval)) { + assem_debug("mvn %s,#%d\n",regname[rt],rt_val); + output_w32(0xe3e00000|rd_rn_rm(rt,0,0)|armval); + return; + } + diff=rt_val-rs_val; + if(genimm(diff,&armval)) { + assem_debug("add %s,%s,#%d\n",regname[rt],regname[rs],diff); + output_w32(0xe2800000|rd_rn_rm(rt,rs,0)|armval); + return; + }else if(genimm(-diff,&armval)) { + assem_debug("sub %s,%s,#%d\n",regname[rt],regname[rs],-diff); + output_w32(0xe2400000|rd_rn_rm(rt,rs,0)|armval); + return; + } + emit_movimm(rt_val,rt); +} + +// return 1 if above function can do it's job cheaply +static int is_similar_value(u_int v1,u_int v2) +{ u_int xs; - for(xs=xor;xs!=0&&(xs&3)==0;xs>>=2) + int diff; + if(v1==v2) return 1; + diff=v2-v1; + for(xs=diff;xs!=0&&(xs&3)==0;xs>>=2) ; - if(xs<0x100) - emit_xorimm(rs,xor,rt); - else - emit_movimm(rt_val,rt); + if(xs<0x100) return 1; + for(xs=-diff;xs!=0&&(xs&3)==0;xs>>=2) + ; + if(xs<0x100) return 1; + return 0; } // trashes r2 @@ -3209,7 +3240,6 @@ do_writestub(int n) set_jump_target(restore_jump,(int)out); restore_regs(reglist); ra=stubs[n][2]; - if(!restore_jump) ra+=4*3; // skip invcode check emit_jmp(ra); #else // if !PCSX if(addr<0) addr=get_reg(i_regmap,-1);