Adding basic constant checks and updates to memory instructions.

Only those instructions likely to have immediate values have been updated.
It'd be nice to go further than this and a) centralize the ea calculations
b) move this all to the analysis pass c) generate mov's in Read/WriteMemory
using the immediates as bases instead of all the register work.

Also fixing a broken stwcx that was causing crashes.
This commit is contained in:
Ben Vanik 2013-05-30 23:20:05 -07:00
parent 78086684c6
commit e7665c11eb
1 changed files with 238 additions and 78 deletions

View File

@ -35,8 +35,14 @@ XEEMITTER(lbz, 0x88000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.D.RA) {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.D.DS)));
}
@ -54,14 +60,21 @@ XEEMITTER(lbzu, 0x8C000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// RA <- EA
GpVar ea(c.newGpVar());
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
e.set_constant_gpr_value(i.D.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
e.clear_constant_gpr_value(i.D.RA);
}
GpVar v = e.ReadMemory(i.address, ea, 1, false);
e.update_gpr_value(i.D.RT, v);
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;
}
@ -115,8 +128,14 @@ XEEMITTER(ld, 0xE8000000, DS )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.DS.RA) {
c.mov(ea, e.gpr_value(i.DS.RA));
c.add(ea, imm(XEEXTS16(i.DS.DS << 2)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.DS.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.DS.DS << 2);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
} else {
c.mov(ea, e.gpr_value(i.DS.RA));
c.add(ea, imm(XEEXTS16(i.DS.DS << 2)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.DS.DS << 2)));
}
@ -134,14 +153,21 @@ XEEMITTER(ldu, 0xE8000001, DS )(X64Emitter& e, X86Compiler& c, InstrDat
// RA <- EA
GpVar ea(c.newGpVar());
c.mov(ea, e.gpr_value(i.DS.RA));
c.add(ea, imm(XEEXTS16(i.DS.DS << 2)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.DS.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.DS.DS << 2);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
e.set_constant_gpr_value(i.DS.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.DS.RA));
c.add(ea, imm(XEEXTS16(i.DS.DS << 2)));
e.clear_constant_gpr_value(i.DS.RA);
}
GpVar v = e.ReadMemory(i.address, ea, 8, false);
e.update_gpr_value(i.DS.RT, v);
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;
}
@ -195,8 +221,14 @@ XEEMITTER(lha, 0xA8000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.D.RA) {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.D.DS)));
}
@ -251,8 +283,14 @@ XEEMITTER(lhz, 0xA0000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.D.RA) {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.D.DS)));
}
@ -271,15 +309,22 @@ XEEMITTER(lhzu, 0xA4000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// RA <- EA
GpVar ea(c.newGpVar());
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
e.set_constant_gpr_value(i.D.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
e.clear_constant_gpr_value(i.D.RA);
}
GpVar v = e.ReadMemory(i.address, ea, 2, false);
// Zero extend done by ReadMemory.
e.update_gpr_value(i.D.RT, v);
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;
}
@ -335,8 +380,14 @@ XEEMITTER(lwa, 0xE8000002, DS )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.DS.RA) {
c.mov(ea, e.gpr_value(i.DS.RA));
c.add(ea, imm(XEEXTS16(i.DS.DS << 2)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.DS.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.DS.DS << 2);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
} else {
c.mov(ea, e.gpr_value(i.DS.RA));
c.add(ea, imm(XEEXTS16(i.DS.DS << 2)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.DS.DS << 2)));
}
@ -400,8 +451,14 @@ XEEMITTER(lwz, 0x80000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.D.RA) {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.D.DS)));
}
@ -420,15 +477,22 @@ XEEMITTER(lwzu, 0x84000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// RA <- EA
GpVar ea(c.newGpVar());
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
e.set_constant_gpr_value(i.D.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
e.clear_constant_gpr_value(i.D.RA);
}
GpVar v = e.ReadMemory(i.address, ea, 4, false);
// Zero extend done by ReadMemory.
e.update_gpr_value(i.D.RT, v);
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;
}
@ -487,8 +551,14 @@ XEEMITTER(stb, 0x98000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.D.RA) {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.D.DS)));
}
@ -504,14 +574,20 @@ XEEMITTER(stbu, 0x9C000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// RA <- EA
GpVar ea(c.newGpVar());
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
e.set_constant_gpr_value(i.D.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
e.clear_constant_gpr_value(i.D.RA);
}
GpVar v = e.gpr_value(i.D.RT);
e.WriteMemory(i.address, ea, 1, v);
e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0;
}
@ -561,8 +637,14 @@ XEEMITTER(std, 0xF8000000, DS )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.DS.RA) {
c.mov(ea, e.gpr_value(i.DS.RA));
c.add(ea, imm(XEEXTS16(i.DS.DS << 2)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.DS.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.DS.DS << 2);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
} else {
c.mov(ea, e.gpr_value(i.DS.RA));
c.add(ea, imm(XEEXTS16(i.DS.DS << 2)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.DS.DS << 2)));
}
@ -578,14 +660,20 @@ XEEMITTER(stdu, 0xF8000001, DS )(X64Emitter& e, X86Compiler& c, InstrDat
// RA <- EA
GpVar ea(c.newGpVar());
c.mov(ea, e.gpr_value(i.DS.RA));
c.add(ea, imm(XEEXTS16(i.DS.DS << 2)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.DS.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.DS.DS << 2);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
e.set_constant_gpr_value(i.DS.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.DS.RA));
c.add(ea, imm(XEEXTS16(i.DS.DS << 2)));
e.clear_constant_gpr_value(i.DS.RA);
}
GpVar v = e.gpr_value(i.DS.RT);
e.WriteMemory(i.address, ea, 8, v);
e.update_gpr_value(i.DS.RA, ea);
e.clear_constant_gpr_value(i.DS.RA);
return 0;
}
@ -635,8 +723,15 @@ XEEMITTER(sth, 0xB0000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.D.RA) {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
e.set_constant_gpr_value(i.D.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.D.DS)));
}
@ -652,14 +747,20 @@ XEEMITTER(sthu, 0xB4000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// RA <- EA
GpVar ea(c.newGpVar());
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
e.set_constant_gpr_value(i.D.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
e.clear_constant_gpr_value(i.D.RA);
}
GpVar v = e.gpr_value(i.D.RT);
e.WriteMemory(i.address, ea, 2, v);
e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0;
}
@ -709,8 +810,14 @@ XEEMITTER(stw, 0x90000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.D.RA) {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.D.DS)));
}
@ -726,14 +833,20 @@ XEEMITTER(stwu, 0x94000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// RA <- EA
GpVar ea(c.newGpVar());
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
e.set_constant_gpr_value(i.D.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
e.clear_constant_gpr_value(i.D.RA);
}
GpVar v = e.gpr_value(i.D.RT);
e.WriteMemory(i.address, ea, 4, v);
e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0;
}
@ -905,13 +1018,11 @@ XEEMITTER(stwcx, 0x7C00012D, X )(X64Emitter& e, X86Compiler& c, InstrDat
// TODO(benvanik): make this right
GpVar ea(c.newGpVar());
if (i.D.RA) {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
} else {
c.mov(ea, imm(XEEXTS16(i.D.DS)));
c.mov(ea, e.gpr_value(i.X.RB));
if (i.X.RA) {
c.add(ea, e.gpr_value(i.X.RA));
}
GpVar v = e.gpr_value(i.D.RT);
GpVar v = e.gpr_value(i.X.RT);
e.WriteMemory(i.address, ea, 4, v, /* release */ true);
// We always succeed.
@ -938,8 +1049,14 @@ XEEMITTER(lfd, 0xC8000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.D.RA) {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea));
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.D.DS)));
}
@ -958,8 +1075,16 @@ XEEMITTER(lfdu, 0xCC000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// RA <- EA
GpVar ea(c.newGpVar());
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea));
e.set_constant_gpr_value(i.D.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
e.clear_constant_gpr_value(i.D.RA);
}
GpVar v = e.ReadMemory(i.address, ea, 8, false);
XmmVar xmm_v(c.newXmmVar());
c.save(v); // Force to memory.
@ -967,8 +1092,6 @@ XEEMITTER(lfdu, 0xCC000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_fpr_value(i.D.RT, xmm_v);
e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0;
}
@ -1024,8 +1147,14 @@ XEEMITTER(lfs, 0xC0000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.D.RA) {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea));
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.D.DS)));
}
@ -1044,8 +1173,16 @@ XEEMITTER(lfsu, 0xC4000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// RA <- EA
GpVar ea(c.newGpVar());
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea));
e.set_constant_gpr_value(i.D.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
e.clear_constant_gpr_value(i.D.RA);
}
GpVar v = e.ReadMemory(i.address, ea, 4, false);
XmmVar xmm_v(c.newXmmVar());
c.movd(xmm_v, v.r32());
@ -1053,8 +1190,6 @@ XEEMITTER(lfsu, 0xC4000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.update_fpr_value(i.D.RT, xmm_v);
e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0;
}
@ -1113,8 +1248,14 @@ XEEMITTER(stfd, 0xD8000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.D.RA) {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea));
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.D.DS)));
}
@ -1133,8 +1274,16 @@ XEEMITTER(stfdu, 0xDC000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// RA <- EA
GpVar ea(c.newGpVar());
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea));
e.set_constant_gpr_value(i.D.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
e.clear_constant_gpr_value(i.D.RA);
}
XmmVar v = e.fpr_value(i.D.RT);
GpVar gpr_v(c.newGpVar());
c.save(gpr_v); // Force to memory.
@ -1142,8 +1291,6 @@ XEEMITTER(stfdu, 0xDC000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 8, gpr_v);
e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0;
}
@ -1220,8 +1367,15 @@ XEEMITTER(stfs, 0xD0000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
GpVar ea(c.newGpVar());
if (i.D.RA) {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea));
e.set_constant_gpr_value(i.D.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
}
} else {
c.mov(ea, imm(XEEXTS16(i.D.DS)));
}
@ -1240,8 +1394,16 @@ XEEMITTER(stfsu, 0xD4000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// RA <- EA
GpVar ea(c.newGpVar());
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea));
e.set_constant_gpr_value(i.D.RA, constant_ea);
} else {
c.mov(ea, e.gpr_value(i.D.RA));
c.add(ea, imm(XEEXTS16(i.D.DS)));
e.clear_constant_gpr_value(i.D.RA);
}
XmmVar v = e.fpr_value(i.D.RT);
c.cvtsd2ss(v, v);
GpVar gpr_v(c.newGpVar());
@ -1249,8 +1411,6 @@ XEEMITTER(stfsu, 0xD4000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
e.WriteMemory(i.address, ea, 4, gpr_v);
e.update_gpr_value(i.D.RA, ea);
e.clear_constant_gpr_value(i.D.RA);
return 0;
}