From 50c7cb1717c8f4e6c8a60d93ae0cf54f0444480d Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Wed, 9 Dec 2015 23:51:51 +0100 Subject: [PATCH] x86emitter: implement some BMI instructions Only a couple of one to do some memory profiling --- common/include/x86emitter/implement/bmi.h | 61 +++++++++++++++++++++++ common/include/x86emitter/instructions.h | 4 ++ common/include/x86emitter/x86types.h | 1 + common/src/x86emitter/CMakeLists.txt | 1 + common/src/x86emitter/bmi.cpp | 32 ++++++++++++ 5 files changed, 99 insertions(+) create mode 100644 common/include/x86emitter/implement/bmi.h create mode 100644 common/src/x86emitter/bmi.cpp diff --git a/common/include/x86emitter/implement/bmi.h b/common/include/x86emitter/implement/bmi.h new file mode 100644 index 0000000000..52e576b751 --- /dev/null +++ b/common/include/x86emitter/implement/bmi.h @@ -0,0 +1,61 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2015 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +#pragma once + +// Implement BMI1/BMI2 instruction set + +namespace x86Emitter { + + struct xImplBMI_RVM + { + u8 Prefix; + u8 MbPrefix; + u8 Opcode; + + // RVM + // MULX Unsigned multiply without affecting flags, and arbitrary destination registers + // PDEP Parallel bits deposit + // PEXT Parallel bits extract + // ANDN Logical and not ~x & y + void operator()( const xRegisterInt& to, const xRegisterInt& from1, const xRegisterInt& from2) const; + void operator()( const xRegisterInt& to, const xRegisterInt& from1, const xIndirectVoid& from2) const; + +#if 0 + // RMV + // BEXTR Bit field extract (with register) (src >> start) & ((1 << len)-1)[9] + // BZHI Zero high bits starting with specified bit position + // SARX Shift arithmetic right without affecting flags + // SHRX Shift logical right without affecting flags + // SHLX Shift logical left without affecting flags + // FIXME: WARNING same as above but V and M are inverted + //void operator()( const xRegisterInt& to, const xRegisterInt& from1, const xRegisterInt& from2) const; + //void operator()( const xRegisterInt& to, const xIndirectVoid& from1, const xRegisterInt& from2) const; + + // VM + // BLSI Extract lowest set isolated bit x & -x + // BLSMSK Get mask up to lowest set bit x ^ (x - 1) + // BLSR Reset lowest set bit x & (x - 1) + void operator()( const xRegisterInt& to, const xRegisterInt& from) const; + void operator()( const xRegisterInt& to, const xIndirectVoid& from) const; + + // RMI + //RORX Rotate right logical without affecting flags + void operator()( const xRegisterInt& to, const xRegisterInt& from, u8 imm) const; + void operator()( const xRegisterInt& to, const xIndirectVoid& from, u8 imm) const; +#endif + }; + +} diff --git a/common/include/x86emitter/instructions.h b/common/include/x86emitter/instructions.h index ccc83b3091..8d80012ae9 100644 --- a/common/include/x86emitter/instructions.h +++ b/common/include/x86emitter/instructions.h @@ -124,6 +124,10 @@ namespace x86Emitter xSETS, xSETNS, xSETPE, xSETPO; + // ------------------------------------------------------------------------ + // BMI extra instruction requires BMI1/BMI2 + extern const xImplBMI_RVM xMULX, xPDEP, xPEXT, xANDN_S; // Warning xANDN is already used by SSE + ////////////////////////////////////////////////////////////////////////////////////////// // Miscellaneous Instructions // These are all defined inline or in ix86.cpp. diff --git a/common/include/x86emitter/x86types.h b/common/include/x86emitter/x86types.h index e5671b781d..3d00a3fc2a 100644 --- a/common/include/x86emitter/x86types.h +++ b/common/include/x86emitter/x86types.h @@ -1002,3 +1002,4 @@ template< typename T > void xWrite( T val ); #include "implement/test.h" #include "implement/jmpcall.h" +#include "implement/bmi.h" diff --git a/common/src/x86emitter/CMakeLists.txt b/common/src/x86emitter/CMakeLists.txt index 8472947561..5fab97c9b1 100644 --- a/common/src/x86emitter/CMakeLists.txt +++ b/common/src/x86emitter/CMakeLists.txt @@ -42,6 +42,7 @@ endif(CMAKE_BUILD_TYPE STREQUAL Release) # variable with all sources of this library set(x86emitterSources + bmi.cpp cpudetect.cpp fpu.cpp groups.cpp diff --git a/common/src/x86emitter/bmi.cpp b/common/src/x86emitter/bmi.cpp new file mode 100644 index 0000000000..cd5ce7db8d --- /dev/null +++ b/common/src/x86emitter/bmi.cpp @@ -0,0 +1,32 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2015 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +#include "PrecompiledHeader.h" +#include "internal.h" +#include "tools.h" + +namespace x86Emitter { + + const xImplBMI_RVM xMULX = { 0xF2, 0x38, 0xF6 }; + const xImplBMI_RVM xPDEP = { 0xF2, 0x38, 0xF5 }; + const xImplBMI_RVM xPEXT = { 0xF3, 0x38, 0xF5 }; + const xImplBMI_RVM xANDN_S = { 0x00, 0x38, 0xF2 }; + + void xImplBMI_RVM::operator()( const xRegisterInt& to, const xRegisterInt& from1, const xRegisterInt& from2) const + { xOpWriteC4(Prefix, MbPrefix, Opcode, to, from1, from2); } + void xImplBMI_RVM::operator()( const xRegisterInt& to, const xRegisterInt& from1, const xIndirectVoid& from2) const + { xOpWriteC4(Prefix, MbPrefix, Opcode, to, from1, from2); } + +}