mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
x64Emitter: add LZCNT/TZCNT support and detection
Also add a unit test.
This commit is contained in:
@ -197,6 +197,7 @@ void CPUInfo::Detect()
|
||||
// Check for more features.
|
||||
__cpuid(cpu_id, 0x80000001);
|
||||
if (cpu_id[2] & 1) bLAHFSAHF64 = true;
|
||||
if ((cpu_id[2] >> 5) & 1) bLZCNT = true;
|
||||
if ((cpu_id[3] >> 29) & 1) bLongMode = true;
|
||||
}
|
||||
|
||||
|
@ -750,12 +750,14 @@ void XEmitter::IDIV(int bits, OpArg src) {WriteMulDivType(bits, src, 7);}
|
||||
void XEmitter::NEG(int bits, OpArg src) {WriteMulDivType(bits, src, 3);}
|
||||
void XEmitter::NOT(int bits, OpArg src) {WriteMulDivType(bits, src, 2);}
|
||||
|
||||
void XEmitter::WriteBitSearchType(int bits, X64Reg dest, OpArg src, u8 byte2)
|
||||
void XEmitter::WriteBitSearchType(int bits, X64Reg dest, OpArg src, u8 byte2, bool rep)
|
||||
{
|
||||
_assert_msg_(DYNA_REC, !src.IsImm(), "WriteBitSearchType - Imm argument");
|
||||
src.operandReg = (u8)dest;
|
||||
if (bits == 16)
|
||||
Write8(0x66);
|
||||
if (rep)
|
||||
Write8(0xF3);
|
||||
src.WriteRex(this, bits, bits);
|
||||
Write8(0x0F);
|
||||
Write8(byte2);
|
||||
@ -772,6 +774,19 @@ void XEmitter::MOVNTI(int bits, OpArg dest, X64Reg src)
|
||||
void XEmitter::BSF(int bits, X64Reg dest, OpArg src) {WriteBitSearchType(bits,dest,src,0xBC);} //bottom bit to top bit
|
||||
void XEmitter::BSR(int bits, X64Reg dest, OpArg src) {WriteBitSearchType(bits,dest,src,0xBD);} //top bit to bottom bit
|
||||
|
||||
void XEmitter::TZCNT(int bits, X64Reg dest, OpArg src)
|
||||
{
|
||||
if (!cpu_info.bBMI1)
|
||||
PanicAlert("Trying to use BMI1 on a system that doesn't support it. Bad programmer.");
|
||||
WriteBitSearchType(bits, dest, src, 0xBC, true);
|
||||
}
|
||||
void XEmitter::LZCNT(int bits, X64Reg dest, OpArg src)
|
||||
{
|
||||
if (!cpu_info.bLZCNT)
|
||||
PanicAlert("Trying to use LZCNT on a system that doesn't support it. Bad programmer.");
|
||||
WriteBitSearchType(bits, dest, src, 0xBD, true);
|
||||
}
|
||||
|
||||
void XEmitter::MOVSX(int dbits, int sbits, X64Reg dest, OpArg src)
|
||||
{
|
||||
_assert_msg_(DYNA_REC, !src.IsImm(), "MOVSX - Imm argument");
|
||||
|
@ -266,7 +266,7 @@ private:
|
||||
void WriteSimple1Byte(int bits, u8 byte, X64Reg reg);
|
||||
void WriteSimple2Byte(int bits, u8 byte1, u8 byte2, X64Reg reg);
|
||||
void WriteMulDivType(int bits, OpArg src, int ext);
|
||||
void WriteBitSearchType(int bits, X64Reg dest, OpArg src, u8 byte2);
|
||||
void WriteBitSearchType(int bits, X64Reg dest, OpArg src, u8 byte2, bool rep = false);
|
||||
void WriteShift(int bits, OpArg dest, OpArg &shift, int ext);
|
||||
void WriteBitTest(int bits, OpArg &dest, OpArg &index, int ext);
|
||||
void WriteMXCSR(OpArg arg, int ext);
|
||||
@ -454,6 +454,11 @@ public:
|
||||
// Available only on Atom or >= Haswell so far. Test with cpu_info.bMOVBE.
|
||||
void MOVBE(int dbits, const OpArg& dest, const OpArg& src);
|
||||
|
||||
// Available only on AMD >= Phenom or Intel >= Haswell
|
||||
void LZCNT(int bits, X64Reg dest, OpArg src);
|
||||
// Note: this one is actually part of BMI1
|
||||
void TZCNT(int bits, X64Reg dest, OpArg src);
|
||||
|
||||
// WARNING - These two take 11-13 cycles and are VectorPath! (AMD64)
|
||||
void STMXCSR(OpArg memloc);
|
||||
void LDMXCSR(OpArg memloc);
|
||||
|
Reference in New Issue
Block a user