From eb13aa43feb75264f7fa85f5b1f19e184802144d Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Tue, 13 Jan 2015 22:31:21 +0100 Subject: [PATCH] XEmitter: overload MOVBE() --- Source/Core/Common/x64Emitter.cpp | 33 ++++++------------- Source/Core/Common/x64Emitter.h | 4 ++- .../Core/Core/PowerPC/JitCommon/Jit_Util.cpp | 6 ++-- Source/UnitTests/Common/x64EmitterTest.cpp | 12 +++---- 4 files changed, 22 insertions(+), 33 deletions(-) diff --git a/Source/Core/Common/x64Emitter.cpp b/Source/Core/Common/x64Emitter.cpp index fccbd2770e..850a63b293 100644 --- a/Source/Core/Common/x64Emitter.cpp +++ b/Source/Core/Common/x64Emitter.cpp @@ -870,38 +870,25 @@ void XEmitter::MOVZX(int dbits, int sbits, X64Reg dest, OpArg src) 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."); if (bits == 8) { - MOV(bits, dest, src); + MOV(8, op & 1 ? arg : R(reg), op & 1 ? R(reg) : arg); return; } - if (bits == 16) Write8(0x66); - - if (dest.IsSimpleReg()) - { - _assert_msg_(DYNA_REC, !src.IsSimpleReg() && !src.IsImm(), "MOVBE: Loading from !mem"); - src.WriteRex(this, bits, bits, dest.GetSimpleReg()); - Write8(0x0F); Write8(0x38); Write8(0xF0); - 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"); - } + _assert_msg_(DYNA_REC, !arg.IsSimpleReg() && !arg.IsImm(), "MOVBE: need r<-m or m<-r!"); + arg.WriteRex(this, bits, bits, reg); + Write8(0x0F); + Write8(0x38); + Write8(op); + arg.WriteRest(this, 0, reg); } - +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) { diff --git a/Source/Core/Common/x64Emitter.h b/Source/Core/Common/x64Emitter.h index 4443309004..00536dca34 100644 --- a/Source/Core/Common/x64Emitter.h +++ b/Source/Core/Common/x64Emitter.h @@ -299,6 +299,7 @@ private: 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 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 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); // 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 void LZCNT(int bits, X64Reg dest, OpArg src); diff --git a/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp b/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp index 1209e2bd46..a0c2e038cc 100644 --- a/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp @@ -27,7 +27,7 @@ void EmuCodeBlock::LoadAndSwap(int size, Gen::X64Reg dst, const Gen::OpArg& src) { if (cpu_info.bMOVBE) { - MOVBE(size, R(dst), src); + MOVBE(size, dst, src); } else { @@ -40,7 +40,7 @@ void EmuCodeBlock::SwapAndStore(int size, const Gen::OpArg& dst, Gen::X64Reg src { if (cpu_info.bMOVBE) { - MOVBE(size, dst, R(src)); + MOVBE(size, dst, src); } else { @@ -451,7 +451,7 @@ u8 *EmuCodeBlock::UnsafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acce { if (cpu_info.bMOVBE) { - MOVBE(accessSize, dest, reg_value); + MOVBE(accessSize, dest, reg_value.GetSimpleReg()); } else { diff --git a/Source/UnitTests/Common/x64EmitterTest.cpp b/Source/UnitTests/Common/x64EmitterTest.cpp index 6b875752f8..977b19a9bc 100644 --- a/Source/UnitTests/Common/x64EmitterTest.cpp +++ b/Source/UnitTests/Common/x64EmitterTest.cpp @@ -609,12 +609,12 @@ TEST_F(x64EmitterTest, MOVZX) TEST_F(x64EmitterTest, MOVBE) { - emitter->MOVBE(16, R(RAX), MatR(R12)); - emitter->MOVBE(16, MatR(RAX), R(R12)); - emitter->MOVBE(32, R(RAX), MatR(R12)); - emitter->MOVBE(32, MatR(RAX), R(R12)); - emitter->MOVBE(64, R(RAX), MatR(R12)); - emitter->MOVBE(64, MatR(RAX), R(R12)); + emitter->MOVBE(16, RAX, MatR(R12)); + emitter->MOVBE(16, MatR(RAX), R12); + emitter->MOVBE(32, RAX, MatR(R12)); + emitter->MOVBE(32, MatR(RAX), R12); + emitter->MOVBE(64, RAX, MatR(R12)); + emitter->MOVBE(64, MatR(RAX), R12); ExpectDisassembly("movbe ax, word ptr ds:[r12] " "movbe word ptr ds:[rax], r12w " "movbe eax, dword ptr ds:[r12] "