mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-31 18:19:49 -06:00
Merge pull request #5246 from MerryMage/math-util
Jit64AsmCommon: Make frsqrte and fres PIE-compliant
This commit is contained in:
@ -7,7 +7,6 @@
|
||||
#include <utility>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/x64Emitter.h"
|
||||
#include "Core/PowerPC/Jit64Common/ConstantPool.h"
|
||||
|
||||
ConstantPool::ConstantPool() = default;
|
||||
@ -37,8 +36,8 @@ void ConstantPool::Shutdown()
|
||||
m_const_info.clear();
|
||||
}
|
||||
|
||||
Gen::OpArg ConstantPool::GetConstantOpArg(const void* value, size_t element_size,
|
||||
size_t num_elements, size_t index)
|
||||
const void* ConstantPool::GetConstant(const void* value, size_t element_size, size_t num_elements,
|
||||
size_t index)
|
||||
{
|
||||
const size_t value_size = element_size * num_elements;
|
||||
auto iter = m_const_info.find(value);
|
||||
@ -59,5 +58,5 @@ Gen::OpArg ConstantPool::GetConstantOpArg(const void* value, size_t element_size
|
||||
_assert_msg_(DYNA_REC, info.m_size == value_size,
|
||||
"Constant has incorrect size in constant pool.");
|
||||
u8* location = static_cast<u8*>(info.m_location);
|
||||
return Gen::M(location + element_size * index);
|
||||
return location + element_size * index;
|
||||
}
|
||||
|
@ -7,12 +7,6 @@
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
|
||||
namespace Gen
|
||||
{
|
||||
struct OpArg;
|
||||
class X64CodeBlock;
|
||||
}
|
||||
|
||||
// Constants are copied into this pool so that they live at a memory location
|
||||
// that is close to the code that references it. This ensures that the 32-bit
|
||||
// limitation on RIP addressing is not an issue.
|
||||
@ -32,8 +26,8 @@ public:
|
||||
// Copies the value into the pool if it doesn't exist. Returns a pointer
|
||||
// to existing values if they were already copied. Pointer equality is
|
||||
// used to determine if two constants are the same.
|
||||
Gen::OpArg GetConstantOpArg(const void* value, size_t element_size, size_t num_elements,
|
||||
size_t index);
|
||||
const void* GetConstant(const void* value, size_t element_size, size_t num_elements,
|
||||
size_t index);
|
||||
|
||||
private:
|
||||
struct ConstantInfo
|
||||
|
@ -29,16 +29,22 @@ public:
|
||||
void SwitchToFarCode();
|
||||
void SwitchToNearCode();
|
||||
|
||||
template <typename T>
|
||||
const void* GetConstantFromPool(const T& value)
|
||||
{
|
||||
return m_const_pool.GetConstant(&value, sizeof(T), 1, 0);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Gen::OpArg MConst(const T& value)
|
||||
{
|
||||
return m_const_pool.GetConstantOpArg(&value, sizeof(T), 1, 0);
|
||||
return Gen::M(GetConstantFromPool(value));
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
Gen::OpArg MConst(const T (&value)[N], size_t index = 0)
|
||||
{
|
||||
return m_const_pool.GetConstantOpArg(&value, sizeof(T), N, index);
|
||||
return Gen::M(m_const_pool.GetConstant(&value, sizeof(T), N, index));
|
||||
}
|
||||
|
||||
Gen::FixupBranch CheckIfSafeAddress(const Gen::OpArg& reg_value, Gen::X64Reg reg_addr,
|
||||
|
@ -69,13 +69,20 @@ void CommonAsmRoutines::GenFrsqrte()
|
||||
AND(32, R(RSCRATCH_EXTRA), Imm8(0x1F));
|
||||
XOR(32, R(RSCRATCH_EXTRA), Imm8(0x10)); // int index = i / 2048 + (odd_exponent ? 16 : 0);
|
||||
|
||||
PUSH(RSCRATCH2);
|
||||
MOV(64, R(RSCRATCH2), ImmPtr(GetConstantFromPool(MathUtil::frsqrte_expected)));
|
||||
static_assert(sizeof(MathUtil::BaseAndDec) == 8, "Unable to use SCALE_8; incorrect size");
|
||||
|
||||
SHR(64, R(RSCRATCH), Imm8(37));
|
||||
AND(32, R(RSCRATCH), Imm32(0x7FF));
|
||||
IMUL(32, RSCRATCH, MScaled(RSCRATCH_EXTRA, SCALE_4, PtrOffset(MathUtil::frsqrte_expected_dec)));
|
||||
IMUL(32, RSCRATCH,
|
||||
MComplex(RSCRATCH2, RSCRATCH_EXTRA, SCALE_8, offsetof(MathUtil::BaseAndDec, m_dec)));
|
||||
MOV(32, R(RSCRATCH_EXTRA),
|
||||
MScaled(RSCRATCH_EXTRA, SCALE_4, PtrOffset(MathUtil::frsqrte_expected_base)));
|
||||
MComplex(RSCRATCH2, RSCRATCH_EXTRA, SCALE_8, offsetof(MathUtil::BaseAndDec, m_base)));
|
||||
SUB(32, R(RSCRATCH_EXTRA), R(RSCRATCH));
|
||||
SHL(64, R(RSCRATCH_EXTRA), Imm8(26));
|
||||
|
||||
POP(RSCRATCH2);
|
||||
OR(64, R(RSCRATCH2), R(RSCRATCH_EXTRA)); // vali |= (s64)(frsqrte_expected_base[index] -
|
||||
// frsqrte_expected_dec[index] * (i % 2048)) << 26;
|
||||
MOVQ_xmm(XMM0, R(RSCRATCH2));
|
||||
@ -140,13 +147,22 @@ void CommonAsmRoutines::GenFres()
|
||||
AND(32, R(RSCRATCH), Imm32(0x3FF)); // i % 1024
|
||||
AND(32, R(RSCRATCH2), Imm8(0x1F)); // i / 1024
|
||||
|
||||
IMUL(32, RSCRATCH, MScaled(RSCRATCH2, SCALE_4, PtrOffset(MathUtil::fres_expected_dec)));
|
||||
PUSH(RSCRATCH_EXTRA);
|
||||
MOV(64, R(RSCRATCH_EXTRA), ImmPtr(GetConstantFromPool(MathUtil::fres_expected)));
|
||||
static_assert(sizeof(MathUtil::BaseAndDec) == 8, "Unable to use SCALE_8; incorrect size");
|
||||
|
||||
IMUL(32, RSCRATCH,
|
||||
MComplex(RSCRATCH_EXTRA, RSCRATCH2, SCALE_8, offsetof(MathUtil::BaseAndDec, m_dec)));
|
||||
ADD(32, R(RSCRATCH), Imm8(1));
|
||||
SHR(32, R(RSCRATCH), Imm8(1));
|
||||
|
||||
MOV(32, R(RSCRATCH2), MScaled(RSCRATCH2, SCALE_4, PtrOffset(MathUtil::fres_expected_base)));
|
||||
MOV(32, R(RSCRATCH2),
|
||||
MComplex(RSCRATCH_EXTRA, RSCRATCH2, SCALE_8, offsetof(MathUtil::BaseAndDec, m_base)));
|
||||
SUB(32, R(RSCRATCH2), R(RSCRATCH));
|
||||
SHL(64, R(RSCRATCH2), Imm8(29));
|
||||
|
||||
POP(RSCRATCH_EXTRA);
|
||||
|
||||
OR(64, R(RSCRATCH2), R(RSCRATCH_EXTRA)); // vali |= (s64)(fres_expected_base[i / 1024] -
|
||||
// (fres_expected_dec[i / 1024] * (i % 1024) + 1) / 2)
|
||||
// << 29
|
||||
|
Reference in New Issue
Block a user