block_of_code: BlockOfCode should provide cpu info
This commit is contained in:
parent
148c01e08f
commit
60d9392b5c
4 changed files with 18 additions and 12 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue