Now tracking constant values for most operations.

This will make it easier to enable memory access optimizations and hacks.
Not all operations are updating the constant registers, only those that
are likely to participate in constant value building. Constant values are
cleared on every basic block, though this may be too zealous it prevents
weird fall-through cases.
This commit is contained in:
Ben Vanik 2013-05-30 22:50:32 -07:00
parent 7990146001
commit 78086684c6
5 changed files with 281 additions and 5 deletions

View File

@ -45,6 +45,8 @@ XEEMITTER(addx, 0x7C000214, XO )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.XO.RT);
return 0; return 0;
} }
@ -70,6 +72,17 @@ XEEMITTER(addi, 0x38000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
} }
e.update_gpr_value(i.D.RT, v); e.update_gpr_value(i.D.RT, v);
if (i.D.RA) {
uint64_t value;
if (e.get_constant_gpr_value(i.D.RA, &value)) {
e.set_constant_gpr_value(i.D.RT, value + XEEXTS16(i.D.DS));
} else {
e.clear_constant_gpr_value(i.D.RT);
}
} else {
e.set_constant_gpr_value(i.D.RT, XEEXTS16(i.D.DS));
}
return 0; return 0;
} }
@ -85,6 +98,13 @@ XEEMITTER(addic, 0x30000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.D.RT, v); e.update_gpr_value(i.D.RT, v);
e.update_xer_with_carry(cc); e.update_xer_with_carry(cc);
uint64_t value;
if (e.get_constant_gpr_value(i.D.RA, &value)) {
e.set_constant_gpr_value(i.D.RT, value + XEEXTS16(i.D.DS));
} else {
e.clear_constant_gpr_value(i.D.RT);
}
return 0; return 0;
} }
@ -99,6 +119,14 @@ XEEMITTER(addicx, 0x34000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.D.RT, v); e.update_gpr_value(i.D.RT, v);
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
e.update_xer_with_carry(cc); e.update_xer_with_carry(cc);
uint64_t value;
if (e.get_constant_gpr_value(i.D.RA, &value)) {
e.set_constant_gpr_value(i.D.RT, value + XEEXTS16(i.D.DS));
} else {
e.clear_constant_gpr_value(i.D.RT);
}
return 0; return 0;
} }
@ -114,6 +142,17 @@ XEEMITTER(addis, 0x3C000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
} }
e.update_gpr_value(i.D.RT, v); e.update_gpr_value(i.D.RT, v);
if (i.D.RA) {
uint64_t value;
if (e.get_constant_gpr_value(i.D.RA, &value)) {
e.set_constant_gpr_value(i.D.RT, value + (XEEXTS16(i.D.DS) << 16));
} else {
e.clear_constant_gpr_value(i.D.RT);
}
} else {
e.set_constant_gpr_value(i.D.RT, XEEXTS16(i.D.DS) << 16);
}
return 0; return 0;
} }
@ -153,6 +192,8 @@ XEEMITTER(addzex, 0x7C000194, XO )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.XO.RT);
return 0; return 0;
} }
@ -221,6 +262,8 @@ XEEMITTER(divwx, 0x7C0003D6, XO )(X64Emitter& e, X86Compiler& c, InstrDat
b.CreateBr(after_bb); b.CreateBr(after_bb);
#endif #endif
e.clear_constant_gpr_value(i.XO.RT);
return 0; return 0;
} }
@ -282,6 +325,8 @@ XEEMITTER(divwux, 0x7C000396, XO )(X64Emitter& e, X86Compiler& c, InstrDat
b.CreateBr(after_bb); b.CreateBr(after_bb);
#endif #endif
e.clear_constant_gpr_value(i.XO.RT);
return 0; return 0;
} }
@ -324,6 +369,8 @@ XEEMITTER(mulli, 0x1C000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
c.mul(v_hi, v_lo, e.gpr_value(i.D.RA)); c.mul(v_hi, v_lo, e.gpr_value(i.D.RA));
e.update_gpr_value(i.D.RT, v_lo); e.update_gpr_value(i.D.RT, v_lo);
e.clear_constant_gpr_value(i.D.RT);
return 0; return 0;
} }
@ -348,6 +395,8 @@ XEEMITTER(mullwx, 0x7C0001D6, XO )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v_0); e.update_cr_with_cond(0, v_0);
} }
e.clear_constant_gpr_value(i.XO.RT);
return 0; return 0;
} }
@ -374,8 +423,6 @@ XEEMITTER(negx, 0x7C0000D0, XO )(X64Emitter& e, X86Compiler& c, InstrDat
// // With cr0 update. // // With cr0 update.
// e.update_cr_with_cond(0, v0, e.get_int64(0), true); // e.update_cr_with_cond(0, v0, e.get_int64(0), true);
//} //}
return 0;
} else { } else {
// No OE bit setting. // No OE bit setting.
GpVar v(c.newGpVar()); GpVar v(c.newGpVar());
@ -387,9 +434,16 @@ XEEMITTER(negx, 0x7C0000D0, XO )(X64Emitter& e, X86Compiler& c, InstrDat
// With cr0 update. // With cr0 update.
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
return 0;
} }
uint64_t value;
if (e.get_constant_gpr_value(i.XO.RA, &value)) {
e.set_constant_gpr_value(i.XO.RT, ~value + 1);
} else {
e.clear_constant_gpr_value(i.XO.RT);
}
return 0;
} }
XEEMITTER(subfx, 0x7C000050, XO )(X64Emitter& e, X86Compiler& c, InstrData& i) { XEEMITTER(subfx, 0x7C000050, XO )(X64Emitter& e, X86Compiler& c, InstrData& i) {
@ -414,6 +468,8 @@ XEEMITTER(subfx, 0x7C000050, XO )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.XO.RT);
return 0; return 0;
} }
@ -431,6 +487,8 @@ XEEMITTER(subfcx, 0x7C000010, XO )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.XO.RT, v); e.update_gpr_value(i.XO.RT, v);
e.update_xer_with_carry(cc); e.update_xer_with_carry(cc);
e.clear_constant_gpr_value(i.XO.RT);
return 0; return 0;
} }
@ -448,6 +506,13 @@ XEEMITTER(subficx, 0x20000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.D.RT, v); e.update_gpr_value(i.D.RT, v);
e.update_xer_with_carry(cc); e.update_xer_with_carry(cc);
uint64_t value;
if (e.get_constant_gpr_value(i.D.RA, &value)) {
e.set_constant_gpr_value(i.D.RT, ~value + XEEXTS16(i.D.DS) + 1);
} else {
e.clear_constant_gpr_value(i.D.RT);
}
return 0; return 0;
} }
@ -488,6 +553,8 @@ XEEMITTER(subfex, 0x7C000110, XO )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.XO.RT);
return 0; return 0;
} }
@ -642,6 +709,8 @@ XEEMITTER(andx, 0x7C000038, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -659,6 +728,8 @@ XEEMITTER(andcx, 0x7C000078, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -673,6 +744,13 @@ XEEMITTER(andix, 0x70000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// With cr0 update. // With cr0 update.
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
uint64_t value;
if (e.get_constant_gpr_value(i.D.RT, &value)) {
e.set_constant_gpr_value(i.D.RA, value & i.D.DS);
} else {
e.clear_constant_gpr_value(i.D.RA);
}
return 0; return 0;
} }
@ -687,6 +765,13 @@ XEEMITTER(andisx, 0x74000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// With cr0 update. // With cr0 update.
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
uint64_t value;
if (e.get_constant_gpr_value(i.D.RT, &value)) {
e.set_constant_gpr_value(i.D.RA, value & (i.D.DS << 16));
} else {
e.clear_constant_gpr_value(i.D.RA);
}
return 1; return 1;
} }
@ -709,6 +794,8 @@ XEEMITTER(cntlzdx, 0x7C000074, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -731,6 +818,8 @@ XEEMITTER(cntlzwx, 0x7C000034, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -752,6 +841,8 @@ XEEMITTER(eqvx, 0x7C000238, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -773,6 +864,8 @@ XEEMITTER(extsbx, 0x7C000774, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -805,6 +898,8 @@ XEEMITTER(norx, 0x7C0000F8, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -825,6 +920,8 @@ XEEMITTER(orx, 0x7C000378, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -841,6 +938,13 @@ XEEMITTER(ori, 0x60000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
c.or_(v, imm(i.D.DS)); c.or_(v, imm(i.D.DS));
e.update_gpr_value(i.D.RA, v); e.update_gpr_value(i.D.RA, v);
uint64_t value;
if (e.get_constant_gpr_value(i.D.RT, &value)) {
e.set_constant_gpr_value(i.D.RA, value | i.D.DS);
} else {
e.clear_constant_gpr_value(i.D.RA);
}
return 0; return 0;
} }
@ -852,6 +956,13 @@ XEEMITTER(oris, 0x64000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
c.or_(v, imm(i.D.DS << 16)); c.or_(v, imm(i.D.DS << 16));
e.update_gpr_value(i.D.RA, v); e.update_gpr_value(i.D.RA, v);
uint64_t value;
if (e.get_constant_gpr_value(i.D.RT, &value)) {
e.set_constant_gpr_value(i.D.RA, value | (i.D.DS << 16));
} else {
e.clear_constant_gpr_value(i.D.RA);
}
return 0; return 0;
} }
@ -868,6 +979,8 @@ XEEMITTER(xorx, 0x7C000278, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -879,6 +992,13 @@ XEEMITTER(xori, 0x68000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
c.xor_(v, imm(i.D.DS)); c.xor_(v, imm(i.D.DS));
e.update_gpr_value(i.D.RA, v); e.update_gpr_value(i.D.RA, v);
uint64_t value;
if (e.get_constant_gpr_value(i.D.RT, &value)) {
e.set_constant_gpr_value(i.D.RA, value ^ i.D.DS);
} else {
e.clear_constant_gpr_value(i.D.RA);
}
return 0; return 0;
} }
@ -890,6 +1010,13 @@ XEEMITTER(xoris, 0x6C000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
c.xor_(v, imm(i.D.DS << 16)); c.xor_(v, imm(i.D.DS << 16));
e.update_gpr_value(i.D.RA, v); e.update_gpr_value(i.D.RA, v);
uint64_t value;
if (e.get_constant_gpr_value(i.D.RT, &value)) {
e.set_constant_gpr_value(i.D.RA, value ^ (i.D.DS << 16));
} else {
e.clear_constant_gpr_value(i.D.RA);
}
return 0; return 0;
} }
@ -939,6 +1066,8 @@ XEEMITTER(rldiclx, 0x78000000, MD )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.MD.RA);
return 0; return 0;
} }
@ -970,6 +1099,8 @@ XEEMITTER(rldicrx, 0x78000004, MD )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.MD.RA);
return 0; return 0;
} }
@ -1006,6 +1137,8 @@ XEEMITTER(rlwimix, 0x50000000, M )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.M.RA);
return 0; return 0;
} }
@ -1033,6 +1166,8 @@ XEEMITTER(rlwinmx, 0x54000000, M )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.M.RA);
return 0; return 0;
} }
@ -1066,6 +1201,8 @@ XEEMITTER(sldx, 0x7C000036, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -1092,6 +1229,8 @@ XEEMITTER(slwx, 0x7C000030, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -1153,6 +1292,8 @@ XEEMITTER(srawix, 0x7C000670, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -1178,6 +1319,8 @@ XEEMITTER(srdx, 0x7C000436, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -1204,6 +1347,8 @@ XEEMITTER(srwx, 0x7C000430, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_cr_with_cond(0, v); e.update_cr_with_cond(0, v);
} }
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }

View File

@ -642,6 +642,8 @@ XEEMITTER(mfspr, 0x7C0002A6, XFX)(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.XFX.RT, v); e.update_gpr_value(i.XFX.RT, v);
e.clear_constant_gpr_value(i.XFX.RT);
return 0; return 0;
} }

View File

@ -43,6 +43,8 @@ XEEMITTER(lbz, 0x88000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar v = e.ReadMemory(i.address, ea, 1, false); GpVar v = e.ReadMemory(i.address, ea, 1, false);
e.update_gpr_value(i.D.RT, v); e.update_gpr_value(i.D.RT, v);
e.clear_constant_gpr_value(i.D.RT);
return 0; return 0;
} }
@ -58,6 +60,9 @@ XEEMITTER(lbzu, 0x8C000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.D.RT, v); e.update_gpr_value(i.D.RT, v);
e.update_gpr_value(i.D.RA, ea); e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RT);
e.clear_constant_gpr_value(i.D.RA);
return 0; return 0;
} }
@ -73,6 +78,9 @@ XEEMITTER(lbzux, 0x7C0000EE, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.X.RT, v); e.update_gpr_value(i.X.RT, v);
e.update_gpr_value(i.X.RA, ea); e.update_gpr_value(i.X.RA, ea);
e.clear_constant_gpr_value(i.X.RT);
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -92,6 +100,8 @@ XEEMITTER(lbzx, 0x7C0000AE, X )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar v = e.ReadMemory(i.address, ea, 1, false); GpVar v = e.ReadMemory(i.address, ea, 1, false);
e.update_gpr_value(i.X.RT, v); e.update_gpr_value(i.X.RT, v);
e.clear_constant_gpr_value(i.X.RT);
return 0; return 0;
} }
@ -113,6 +123,8 @@ XEEMITTER(ld, 0xE8000000, DS )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar v = e.ReadMemory(i.address, ea, 8, false); GpVar v = e.ReadMemory(i.address, ea, 8, false);
e.update_gpr_value(i.DS.RT, v); e.update_gpr_value(i.DS.RT, v);
e.clear_constant_gpr_value(i.DS.RT);
return 0; return 0;
} }
@ -128,6 +140,9 @@ XEEMITTER(ldu, 0xE8000001, DS )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.DS.RT, v); e.update_gpr_value(i.DS.RT, v);
e.update_gpr_value(i.DS.RA, ea); e.update_gpr_value(i.DS.RA, ea);
e.clear_constant_gpr_value(i.DS.RT);
e.clear_constant_gpr_value(i.DS.RA);
return 0; return 0;
} }
@ -143,6 +158,9 @@ XEEMITTER(ldux, 0x7C00006A, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.X.RT, v); e.update_gpr_value(i.X.RT, v);
e.update_gpr_value(i.X.RA, ea); e.update_gpr_value(i.X.RA, ea);
e.clear_constant_gpr_value(i.X.RT);
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -162,6 +180,8 @@ XEEMITTER(ldx, 0x7C00002A, X )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar v = e.ReadMemory(i.address, ea, 8, false); GpVar v = e.ReadMemory(i.address, ea, 8, false);
e.update_gpr_value(i.X.RT, v); e.update_gpr_value(i.X.RT, v);
e.clear_constant_gpr_value(i.X.RT);
return 0; return 0;
} }
@ -184,6 +204,8 @@ XEEMITTER(lha, 0xA8000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
v = e.sign_extend(v, 2, 8); v = e.sign_extend(v, 2, 8);
e.update_gpr_value(i.D.RT, v); e.update_gpr_value(i.D.RT, v);
e.clear_constant_gpr_value(i.D.RT);
return 0; return 0;
} }
@ -214,6 +236,8 @@ XEEMITTER(lhax, 0x7C0002AE, X )(X64Emitter& e, X86Compiler& c, InstrDat
v = e.sign_extend(v, 2, 8); v = e.sign_extend(v, 2, 8);
e.update_gpr_value(i.X.RT, v); e.update_gpr_value(i.X.RT, v);
e.clear_constant_gpr_value(i.X.RT);
return 0; return 0;
} }
@ -236,6 +260,8 @@ XEEMITTER(lhz, 0xA0000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// Zero extend done by ReadMemory. // Zero extend done by ReadMemory.
e.update_gpr_value(i.D.RT, v); e.update_gpr_value(i.D.RT, v);
e.clear_constant_gpr_value(i.D.RT);
return 0; return 0;
} }
@ -252,6 +278,9 @@ XEEMITTER(lhzu, 0xA4000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.D.RT, v); e.update_gpr_value(i.D.RT, v);
e.update_gpr_value(i.D.RA, ea); e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RT);
e.clear_constant_gpr_value(i.D.RA);
return 0; return 0;
} }
@ -268,6 +297,9 @@ XEEMITTER(lhzux, 0x7C00026E, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.X.RT, v); e.update_gpr_value(i.X.RT, v);
e.update_gpr_value(i.X.RA, ea); e.update_gpr_value(i.X.RA, ea);
e.clear_constant_gpr_value(i.X.RT);
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -288,6 +320,8 @@ XEEMITTER(lhzx, 0x7C00022E, X )(X64Emitter& e, X86Compiler& c, InstrDat
// Zero extend done by ReadMemory. // Zero extend done by ReadMemory.
e.update_gpr_value(i.X.RT, v); e.update_gpr_value(i.X.RT, v);
e.clear_constant_gpr_value(i.X.RT);
return 0; return 0;
} }
@ -310,6 +344,8 @@ XEEMITTER(lwa, 0xE8000002, DS )(X64Emitter& e, X86Compiler& c, InstrDat
v = e.sign_extend(v, 4, 8); v = e.sign_extend(v, 4, 8);
e.update_gpr_value(i.DS.RT, v); e.update_gpr_value(i.DS.RT, v);
e.clear_constant_gpr_value(i.DS.RT);
return 0; return 0;
} }
@ -326,6 +362,9 @@ XEEMITTER(lwaux, 0x7C0002EA, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.X.RT, v); e.update_gpr_value(i.X.RT, v);
e.update_gpr_value(i.X.RA, ea); e.update_gpr_value(i.X.RA, ea);
e.clear_constant_gpr_value(i.X.RT);
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -346,6 +385,8 @@ XEEMITTER(lwax, 0x7C0002AA, X )(X64Emitter& e, X86Compiler& c, InstrDat
v = e.sign_extend(v, 4, 8); v = e.sign_extend(v, 4, 8);
e.update_gpr_value(i.X.RT, v); e.update_gpr_value(i.X.RT, v);
e.clear_constant_gpr_value(i.X.RT);
return 0; return 0;
} }
@ -368,6 +409,8 @@ XEEMITTER(lwz, 0x80000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// Zero extend done by ReadMemory. // Zero extend done by ReadMemory.
e.update_gpr_value(i.D.RT, v); e.update_gpr_value(i.D.RT, v);
e.clear_constant_gpr_value(i.D.RT);
return 0; return 0;
} }
@ -384,6 +427,9 @@ XEEMITTER(lwzu, 0x84000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.D.RT, v); e.update_gpr_value(i.D.RT, v);
e.update_gpr_value(i.D.RA, ea); e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RT);
e.clear_constant_gpr_value(i.D.RA);
return 0; return 0;
} }
@ -400,6 +446,9 @@ XEEMITTER(lwzux, 0x7C00006E, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_gpr_value(i.X.RT, v); e.update_gpr_value(i.X.RT, v);
e.update_gpr_value(i.X.RA, ea); e.update_gpr_value(i.X.RA, ea);
e.clear_constant_gpr_value(i.X.RT);
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -420,6 +469,8 @@ XEEMITTER(lwzx, 0x7C00002E, X )(X64Emitter& e, X86Compiler& c, InstrDat
// Zero extend done by ReadMemory. // Zero extend done by ReadMemory.
e.update_gpr_value(i.X.RT, v); e.update_gpr_value(i.X.RT, v);
e.clear_constant_gpr_value(i.X.RT);
return 0; return 0;
} }
@ -459,6 +510,8 @@ XEEMITTER(stbu, 0x9C000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 1, v); e.WriteMemory(i.address, ea, 1, v);
e.update_gpr_value(i.D.RA, ea); e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0; return 0;
} }
@ -474,6 +527,8 @@ XEEMITTER(stbux, 0x7C0001EE, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 1, v); e.WriteMemory(i.address, ea, 1, v);
e.update_gpr_value(i.X.RA, ea); e.update_gpr_value(i.X.RA, ea);
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -529,6 +584,8 @@ XEEMITTER(stdu, 0xF8000001, DS )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 8, v); e.WriteMemory(i.address, ea, 8, v);
e.update_gpr_value(i.DS.RA, ea); e.update_gpr_value(i.DS.RA, ea);
e.clear_constant_gpr_value(i.DS.RA);
return 0; return 0;
} }
@ -563,6 +620,8 @@ XEEMITTER(stdx, 0x7C00012A, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 8, v); e.WriteMemory(i.address, ea, 8, v);
e.update_gpr_value(i.X.RA, ea); e.update_gpr_value(i.X.RA, ea);
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -599,6 +658,8 @@ XEEMITTER(sthu, 0xB4000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 2, v); e.WriteMemory(i.address, ea, 2, v);
e.update_gpr_value(i.D.RA, ea); e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0; return 0;
} }
@ -614,6 +675,8 @@ XEEMITTER(sthux, 0x7C00036E, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 2, v); e.WriteMemory(i.address, ea, 2, v);
e.update_gpr_value(i.X.RA, ea); e.update_gpr_value(i.X.RA, ea);
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -669,6 +732,8 @@ XEEMITTER(stwu, 0x94000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 4, v); e.WriteMemory(i.address, ea, 4, v);
e.update_gpr_value(i.D.RA, ea); e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0; return 0;
} }
@ -684,6 +749,8 @@ XEEMITTER(stwux, 0x7C00016E, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 4, v); e.WriteMemory(i.address, ea, 4, v);
e.update_gpr_value(i.X.RA, ea); e.update_gpr_value(i.X.RA, ea);
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -814,6 +881,8 @@ XEEMITTER(lwarx, 0x7C000028, X )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar v = e.ReadMemory(i.address, ea, 4, /* acquire */ true); GpVar v = e.ReadMemory(i.address, ea, 4, /* acquire */ true);
e.update_gpr_value(i.X.RT, v); e.update_gpr_value(i.X.RT, v);
e.clear_constant_gpr_value(i.X.RT);
return 0; return 0;
} }
@ -898,6 +967,8 @@ XEEMITTER(lfdu, 0xCC000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_fpr_value(i.D.RT, xmm_v); e.update_fpr_value(i.D.RT, xmm_v);
e.update_gpr_value(i.D.RA, ea); e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0; return 0;
} }
@ -916,6 +987,8 @@ XEEMITTER(lfdux, 0x7C0004EE, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_fpr_value(i.X.RT, xmm_v); e.update_fpr_value(i.X.RT, xmm_v);
e.update_gpr_value(i.X.RA, ea); e.update_gpr_value(i.X.RA, ea);
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -980,6 +1053,8 @@ XEEMITTER(lfsu, 0xC4000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_fpr_value(i.D.RT, xmm_v); e.update_fpr_value(i.D.RT, xmm_v);
e.update_gpr_value(i.D.RA, ea); e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0; return 0;
} }
@ -998,6 +1073,8 @@ XEEMITTER(lfsux, 0x7C00046E, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_fpr_value(i.X.RT, xmm_v); e.update_fpr_value(i.X.RT, xmm_v);
e.update_gpr_value(i.X.RA, ea); e.update_gpr_value(i.X.RA, ea);
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -1065,6 +1142,8 @@ XEEMITTER(stfdu, 0xDC000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 8, gpr_v); e.WriteMemory(i.address, ea, 8, gpr_v);
e.update_gpr_value(i.D.RA, ea); e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0; return 0;
} }
@ -1083,6 +1162,8 @@ XEEMITTER(stfdux, 0x7C0005EE, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 8, gpr_v); e.WriteMemory(i.address, ea, 8, gpr_v);
e.update_gpr_value(i.X.RA, ea); e.update_gpr_value(i.X.RA, ea);
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }
@ -1168,6 +1249,8 @@ XEEMITTER(stfsu, 0xD4000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 4, gpr_v); e.WriteMemory(i.address, ea, 4, gpr_v);
e.update_gpr_value(i.D.RA, ea); e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0; return 0;
} }
@ -1186,6 +1269,8 @@ XEEMITTER(stfsux, 0x7C00056E, X )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 4, gpr_v); e.WriteMemory(i.address, ea, 4, gpr_v);
e.update_gpr_value(i.X.RA, ea); e.update_gpr_value(i.X.RA, ea);
e.clear_constant_gpr_value(i.X.RA);
return 0; return 0;
} }

View File

@ -243,6 +243,8 @@ int X64Emitter::MakeFunction(FunctionSymbol* symbol) {
access_bits_.Clear(); access_bits_.Clear();
clear_all_constant_gpr_values();
locals_.indirection_target = GpVar(); locals_.indirection_target = GpVar();
locals_.indirection_cia = GpVar(); locals_.indirection_cia = GpVar();
@ -550,6 +552,13 @@ void X64Emitter::GenerateBasicBlock(FunctionBlock* block) {
c.comment("bb %.8X - %.8X", block->start_address, block->end_address); c.comment("bb %.8X - %.8X", block->start_address, block->end_address);
} }
// Reset constant values.
// They may be valid, but it's hard to tell.
// If we wanted we could ensure that any incoming edges were immediately
// preceeding us and not something that was messing with the values, however
// most constant values are set within their own blocks anyway.
clear_all_constant_gpr_values();
// This will create a label if it hasn't already been done. // This will create a label if it hasn't already been done.
std::map<uint32_t, Label>::iterator label_it = std::map<uint32_t, Label>::iterator label_it =
bbs_.find(block->start_address); bbs_.find(block->start_address);
@ -1225,6 +1234,32 @@ void X64Emitter::SpillRegisters() {
} }
} }
bool X64Emitter::get_constant_gpr_value(uint32_t n, uint64_t* value) {
if (gpr_values_[n].is_constant) {
*value = gpr_values_[n].value;
return true;
} else {
return false;
}
}
void X64Emitter::set_constant_gpr_value(uint32_t n, uint64_t value) {
gpr_values_[n].is_constant = true;
gpr_values_[n].value = value;
}
void X64Emitter::clear_constant_gpr_value(uint32_t n) {
gpr_values_[n].is_constant = false;
gpr_values_[n].value = 0;
}
void X64Emitter::clear_all_constant_gpr_values() {
for (size_t n = 0; n < XECOUNT(gpr_values_); n++) {
gpr_values_[n].is_constant = false;
gpr_values_[n].value = 0;
}
}
GpVar X64Emitter::xer_value() { GpVar X64Emitter::xer_value() {
X86Compiler& c = compiler_; X86Compiler& c = compiler_;
if (FLAGS_cache_registers) { if (FLAGS_cache_registers) {

View File

@ -58,6 +58,11 @@ public:
void FillRegisters(); void FillRegisters();
void SpillRegisters(); void SpillRegisters();
bool get_constant_gpr_value(uint32_t n, uint64_t* value);
void set_constant_gpr_value(uint32_t n, uint64_t value);
void clear_constant_gpr_value(uint32_t n);
void clear_all_constant_gpr_values();
AsmJit::GpVar xer_value(); AsmJit::GpVar xer_value();
void update_xer_value(AsmJit::GpVar& value); void update_xer_value(AsmJit::GpVar& value);
void update_xer_with_overflow(AsmJit::GpVar& value); void update_xer_with_overflow(AsmJit::GpVar& value);
@ -124,7 +129,11 @@ private:
std::map<uint32_t, AsmJit::Label> bbs_; std::map<uint32_t, AsmJit::Label> bbs_;
ppc::InstrAccessBits access_bits_; ppc::InstrAccessBits access_bits_;
struct {
bool is_constant;
uint64_t value;
} gpr_values_[32];
struct { struct {
AsmJit::GpVar indirection_target; AsmJit::GpVar indirection_target;
AsmJit::GpVar indirection_cia; AsmJit::GpVar indirection_cia;