XEmitter: overload MOVBE()
This commit is contained in:
parent
20ded4c1e5
commit
eb13aa43fe
|
@ -870,38 +870,25 @@ void XEmitter::MOVZX(int dbits, int sbits, X64Reg dest, OpArg src)
|
||||||
src.WriteRest(this);
|
src.WriteRest(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XEmitter::MOVBE(int bits, const OpArg& dest, const OpArg& src)
|
void XEmitter::WriteMOVBE(int bits, u8 op, X64Reg reg, OpArg arg)
|
||||||
{
|
{
|
||||||
_assert_msg_(DYNA_REC, cpu_info.bMOVBE, "Generating MOVBE on a system that does not support it.");
|
_assert_msg_(DYNA_REC, cpu_info.bMOVBE, "Generating MOVBE on a system that does not support it.");
|
||||||
if (bits == 8)
|
if (bits == 8)
|
||||||
{
|
{
|
||||||
MOV(bits, dest, src);
|
MOV(8, op & 1 ? arg : R(reg), op & 1 ? R(reg) : arg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bits == 16)
|
if (bits == 16)
|
||||||
Write8(0x66);
|
Write8(0x66);
|
||||||
|
_assert_msg_(DYNA_REC, !arg.IsSimpleReg() && !arg.IsImm(), "MOVBE: need r<-m or m<-r!");
|
||||||
if (dest.IsSimpleReg())
|
arg.WriteRex(this, bits, bits, reg);
|
||||||
{
|
Write8(0x0F);
|
||||||
_assert_msg_(DYNA_REC, !src.IsSimpleReg() && !src.IsImm(), "MOVBE: Loading from !mem");
|
Write8(0x38);
|
||||||
src.WriteRex(this, bits, bits, dest.GetSimpleReg());
|
Write8(op);
|
||||||
Write8(0x0F); Write8(0x38); Write8(0xF0);
|
arg.WriteRest(this, 0, reg);
|
||||||
src.WriteRest(this, 0, dest.GetSimpleReg());
|
|
||||||
}
|
|
||||||
else if (src.IsSimpleReg())
|
|
||||||
{
|
|
||||||
_assert_msg_(DYNA_REC, !dest.IsSimpleReg() && !dest.IsImm(), "MOVBE: Storing to !mem");
|
|
||||||
dest.WriteRex(this, bits, bits, src.GetSimpleReg());
|
|
||||||
Write8(0x0F); Write8(0x38); Write8(0xF1);
|
|
||||||
dest.WriteRest(this, 0, src.GetSimpleReg());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_assert_msg_(DYNA_REC, 0, "MOVBE: Not loading or storing to mem");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
void XEmitter::MOVBE(int bits, X64Reg dest, const OpArg& src) {WriteMOVBE(bits, 0xF0, dest, src);}
|
||||||
|
void XEmitter::MOVBE(int bits, const OpArg& dest, X64Reg src) {WriteMOVBE(bits, 0xF1, src, dest);}
|
||||||
|
|
||||||
void XEmitter::LEA(int bits, X64Reg dest, OpArg src)
|
void XEmitter::LEA(int bits, X64Reg dest, OpArg src)
|
||||||
{
|
{
|
||||||
|
|
|
@ -299,6 +299,7 @@ private:
|
||||||
void WriteVEXOp(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes = 0);
|
void WriteVEXOp(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes = 0);
|
||||||
void WriteBMI1Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes = 0);
|
void WriteBMI1Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes = 0);
|
||||||
void WriteBMI2Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes = 0);
|
void WriteBMI2Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes = 0);
|
||||||
|
void WriteMOVBE(int bits, u8 op, X64Reg regOp, OpArg arg);
|
||||||
void WriteFloatLoadStore(int bits, FloatOp op, FloatOp op_80b, OpArg arg);
|
void WriteFloatLoadStore(int bits, FloatOp op, FloatOp op_80b, OpArg arg);
|
||||||
void WriteNormalOp(XEmitter *emit, int bits, NormalOp op, const OpArg &a1, const OpArg &a2);
|
void WriteNormalOp(XEmitter *emit, int bits, NormalOp op, const OpArg &a1, const OpArg &a2);
|
||||||
|
|
||||||
|
@ -476,7 +477,8 @@ public:
|
||||||
void MOVZX(int dbits, int sbits, X64Reg dest, OpArg src);
|
void MOVZX(int dbits, int sbits, X64Reg dest, OpArg src);
|
||||||
|
|
||||||
// Available only on Atom or >= Haswell so far. Test with cpu_info.bMOVBE.
|
// Available only on Atom or >= Haswell so far. Test with cpu_info.bMOVBE.
|
||||||
void MOVBE(int dbits, const OpArg& dest, const OpArg& src);
|
void MOVBE(int bits, X64Reg dest, const OpArg& src);
|
||||||
|
void MOVBE(int bits, const OpArg& dest, X64Reg src);
|
||||||
|
|
||||||
// Available only on AMD >= Phenom or Intel >= Haswell
|
// Available only on AMD >= Phenom or Intel >= Haswell
|
||||||
void LZCNT(int bits, X64Reg dest, OpArg src);
|
void LZCNT(int bits, X64Reg dest, OpArg src);
|
||||||
|
|
|
@ -27,7 +27,7 @@ void EmuCodeBlock::LoadAndSwap(int size, Gen::X64Reg dst, const Gen::OpArg& src)
|
||||||
{
|
{
|
||||||
if (cpu_info.bMOVBE)
|
if (cpu_info.bMOVBE)
|
||||||
{
|
{
|
||||||
MOVBE(size, R(dst), src);
|
MOVBE(size, dst, src);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,7 @@ void EmuCodeBlock::SwapAndStore(int size, const Gen::OpArg& dst, Gen::X64Reg src
|
||||||
{
|
{
|
||||||
if (cpu_info.bMOVBE)
|
if (cpu_info.bMOVBE)
|
||||||
{
|
{
|
||||||
MOVBE(size, dst, R(src));
|
MOVBE(size, dst, src);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -451,7 +451,7 @@ u8 *EmuCodeBlock::UnsafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acce
|
||||||
{
|
{
|
||||||
if (cpu_info.bMOVBE)
|
if (cpu_info.bMOVBE)
|
||||||
{
|
{
|
||||||
MOVBE(accessSize, dest, reg_value);
|
MOVBE(accessSize, dest, reg_value.GetSimpleReg());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -609,12 +609,12 @@ TEST_F(x64EmitterTest, MOVZX)
|
||||||
|
|
||||||
TEST_F(x64EmitterTest, MOVBE)
|
TEST_F(x64EmitterTest, MOVBE)
|
||||||
{
|
{
|
||||||
emitter->MOVBE(16, R(RAX), MatR(R12));
|
emitter->MOVBE(16, RAX, MatR(R12));
|
||||||
emitter->MOVBE(16, MatR(RAX), R(R12));
|
emitter->MOVBE(16, MatR(RAX), R12);
|
||||||
emitter->MOVBE(32, R(RAX), MatR(R12));
|
emitter->MOVBE(32, RAX, MatR(R12));
|
||||||
emitter->MOVBE(32, MatR(RAX), R(R12));
|
emitter->MOVBE(32, MatR(RAX), R12);
|
||||||
emitter->MOVBE(64, R(RAX), MatR(R12));
|
emitter->MOVBE(64, RAX, MatR(R12));
|
||||||
emitter->MOVBE(64, MatR(RAX), R(R12));
|
emitter->MOVBE(64, MatR(RAX), R12);
|
||||||
ExpectDisassembly("movbe ax, word ptr ds:[r12] "
|
ExpectDisassembly("movbe ax, word ptr ds:[r12] "
|
||||||
"movbe word ptr ds:[rax], r12w "
|
"movbe word ptr ds:[rax], r12w "
|
||||||
"movbe eax, dword ptr ds:[r12] "
|
"movbe eax, dword ptr ds:[r12] "
|
||||||
|
|
Loading…
Reference in New Issue