block_of_code: BlockOfCode should provide cpu info

This commit is contained in:
MerryMage 2017-11-02 19:58:40 +00:00
parent 148c01e08f
commit 60d9392b5c
4 changed files with 18 additions and 12 deletions

View file

@ -244,5 +244,9 @@ void BlockOfCode::EnsurePatchLocationSize(CodePtr begin, size_t size) {
nop(size - current_size); nop(size - current_size);
} }
bool BlockOfCode::DoesCpuSupport(Xbyak::util::Cpu::Type type) const {
return cpu_info.has(type);
}
} // namespace BackendX64 } // namespace BackendX64
} // namespace Dynarmic } // namespace Dynarmic

View file

@ -10,6 +10,7 @@
#include <type_traits> #include <type_traits>
#include <xbyak.h> #include <xbyak.h>
#include <xbyak_util.h>
#include "backend_x64/constant_pool.h" #include "backend_x64/constant_pool.h"
#include "backend_x64/jitstate.h" #include "backend_x64/jitstate.h"
@ -118,6 +119,8 @@ public:
static const Xbyak::Reg64 ABI_PARAM3; static const Xbyak::Reg64 ABI_PARAM3;
static const Xbyak::Reg64 ABI_PARAM4; static const Xbyak::Reg64 ABI_PARAM4;
bool DoesCpuSupport(Xbyak::util::Cpu::Type type) const;
private: private:
UserCallbacks cb; UserCallbacks cb;
LookupBlockCallback lookup_block; LookupBlockCallback lookup_block;
@ -160,6 +163,8 @@ private:
std::unique_ptr<Impl> impl; std::unique_ptr<Impl> impl;
}; };
ExceptionHandler exception_handler; ExceptionHandler exception_handler;
Xbyak::util::Cpu cpu_info;
}; };
} // namespace BackendX64 } // namespace BackendX64

View file

@ -1287,7 +1287,7 @@ void EmitX64::EmitByteReverseDual(RegAlloc& reg_alloc, IR::Block&, IR::Inst* ins
void EmitX64::EmitCountLeadingZeros(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { void EmitX64::EmitCountLeadingZeros(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) {
auto args = reg_alloc.GetArgumentInfo(inst); auto args = reg_alloc.GetArgumentInfo(inst);
if (cpu_info.has(Xbyak::util::Cpu::tLZCNT)) { if (code->DoesCpuSupport(Xbyak::util::Cpu::tLZCNT)) {
Xbyak::Reg32 source = reg_alloc.UseGpr(args[0]).cvt32(); Xbyak::Reg32 source = reg_alloc.UseGpr(args[0]).cvt32();
Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32();
@ -1453,8 +1453,8 @@ void EmitX64::EmitSignedSaturation(RegAlloc& reg_alloc, IR::Block& block, IR::In
* @param value The register containing the value to operate on. Result will be stored in the same register. * @param value The register containing the value to operate on. Result will be stored in the same register.
* @param a_tmp A register which can be used as a scratch register. * @param a_tmp A register which can be used as a scratch register.
*/ */
static void ExtractMostSignificantBitFromPackedBytes(const Xbyak::util::Cpu& cpu_info, BlockOfCode* code, RegAlloc& reg_alloc, Xbyak::Reg32 value, boost::optional<Xbyak::Reg32> a_tmp = boost::none) { static void ExtractMostSignificantBitFromPackedBytes(BlockOfCode* code, RegAlloc& reg_alloc, Xbyak::Reg32 value, boost::optional<Xbyak::Reg32> a_tmp = boost::none) {
if (cpu_info.has(Xbyak::util::Cpu::tBMI2)) { if (code->DoesCpuSupport(Xbyak::util::Cpu::tBMI2)) {
Xbyak::Reg32 tmp = a_tmp ? *a_tmp : reg_alloc.ScratchGpr().cvt32(); Xbyak::Reg32 tmp = a_tmp ? *a_tmp : reg_alloc.ScratchGpr().cvt32();
code->mov(tmp, 0x80808080); code->mov(tmp, 0x80808080);
code->pext(value, value, tmp); code->pext(value, value, tmp);
@ -1501,7 +1501,7 @@ void EmitX64::EmitPackedAddU8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* i
code->movd(reg_ge, tmp); code->movd(reg_ge, tmp);
code->not_(reg_ge); code->not_(reg_ge);
ExtractMostSignificantBitFromPackedBytes(cpu_info, code, reg_alloc, reg_ge); ExtractMostSignificantBitFromPackedBytes(code, reg_alloc, reg_ge);
reg_alloc.DefineValue(ge_inst, reg_ge); reg_alloc.DefineValue(ge_inst, reg_ge);
} }
@ -1532,7 +1532,7 @@ void EmitX64::EmitPackedAddS8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* i
if (ge_inst) { if (ge_inst) {
code->not_(reg_ge); code->not_(reg_ge);
ExtractMostSignificantBitFromPackedBytes(cpu_info, code, reg_alloc, reg_ge); ExtractMostSignificantBitFromPackedBytes(code, reg_alloc, reg_ge);
reg_alloc.DefineValue(ge_inst, reg_ge); reg_alloc.DefineValue(ge_inst, reg_ge);
} }
@ -1560,7 +1560,7 @@ void EmitX64::EmitPackedAddU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst*
code->movd(reg_ge, tmp); code->movd(reg_ge, tmp);
code->not_(reg_ge); code->not_(reg_ge);
ExtractMostSignificantBitFromPackedBytes(cpu_info, code, reg_alloc, reg_ge); ExtractMostSignificantBitFromPackedBytes(code, reg_alloc, reg_ge);
reg_alloc.DefineValue(ge_inst, reg_ge); reg_alloc.DefineValue(ge_inst, reg_ge);
} }
@ -1620,7 +1620,7 @@ void EmitX64::EmitPackedSubU8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* i
code->psubb(xmm_a, xmm_b); code->psubb(xmm_a, xmm_b);
if (ge_inst) { if (ge_inst) {
ExtractMostSignificantBitFromPackedBytes(cpu_info, code, reg_alloc, reg_ge); ExtractMostSignificantBitFromPackedBytes(code, reg_alloc, reg_ge);
reg_alloc.DefineValue(ge_inst, reg_ge); reg_alloc.DefineValue(ge_inst, reg_ge);
} }
@ -1651,7 +1651,7 @@ void EmitX64::EmitPackedSubS8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* i
if (ge_inst) { if (ge_inst) {
code->not_(reg_ge); code->not_(reg_ge);
ExtractMostSignificantBitFromPackedBytes(cpu_info, code, reg_alloc, reg_ge); ExtractMostSignificantBitFromPackedBytes(code, reg_alloc, reg_ge);
reg_alloc.DefineValue(ge_inst, reg_ge); reg_alloc.DefineValue(ge_inst, reg_ge);
} }
@ -1723,7 +1723,7 @@ void EmitX64::EmitPackedHalvingAddU8(RegAlloc& reg_alloc, IR::Block&, IR::Inst*
// This code path requires SSSE3 because of the PSHUFB instruction. // This code path requires SSSE3 because of the PSHUFB instruction.
// A fallback implementation is provided below. // A fallback implementation is provided below.
if (cpu_info.has(Xbyak::util::Cpu::tSSSE3)) { if (code->DoesCpuSupport(Xbyak::util::Cpu::tSSSE3)) {
Xbyak::Xmm xmm_a = reg_alloc.UseScratchXmm(args[0]); Xbyak::Xmm xmm_a = reg_alloc.UseScratchXmm(args[0]);
Xbyak::Xmm xmm_b = reg_alloc.UseScratchXmm(args[1]); Xbyak::Xmm xmm_b = reg_alloc.UseScratchXmm(args[1]);

View file

@ -95,9 +95,6 @@ private:
void EmitPatchJmp(const IR::LocationDescriptor& target_desc, CodePtr target_code_ptr = nullptr); void EmitPatchJmp(const IR::LocationDescriptor& target_desc, CodePtr target_code_ptr = nullptr);
void EmitPatchMovRcx(CodePtr target_code_ptr = nullptr); void EmitPatchMovRcx(CodePtr target_code_ptr = nullptr);
// Global CPU information
Xbyak::util::Cpu cpu_info;
// State // State
BlockOfCode* code; BlockOfCode* code;
UserCallbacks cb; UserCallbacks cb;