Arm64Emitter: Use Common::BitCast where applicable
Gets rid of the need to set up memcpy boilerplate to reinterpret between floating-point and integers. While we're at it, also do a minor bit of tidying.
This commit is contained in:
parent
2beb135bdf
commit
6fd7a79b93
|
@ -11,6 +11,7 @@
|
||||||
#include "Common/Align.h"
|
#include "Common/Align.h"
|
||||||
#include "Common/Arm64Emitter.h"
|
#include "Common/Arm64Emitter.h"
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
|
#include "Common/BitUtils.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/MathUtil.h"
|
#include "Common/MathUtil.h"
|
||||||
|
|
||||||
|
@ -268,35 +269,34 @@ bool IsImmLogical(uint64_t value, unsigned int width, unsigned int* n, unsigned
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float FPImm8ToFloat(uint8_t bits)
|
float FPImm8ToFloat(u8 bits)
|
||||||
{
|
{
|
||||||
int sign = bits >> 7;
|
const u32 sign = bits >> 7;
|
||||||
uint32_t f = (sign << 31);
|
const u32 bit6 = (bits >> 6) & 1;
|
||||||
int bit6 = (bits >> 6) & 1;
|
const u32 exp = ((!bit6) << 7) | (0x7C * bit6) | ((bits >> 4) & 3);
|
||||||
uint32_t exp = ((!bit6) << 7) | (0x7C * bit6) | ((bits >> 4) & 3);
|
const u32 mantissa = (bits & 0xF) << 19;
|
||||||
uint32_t mantissa = (bits & 0xF) << 19;
|
const u32 f = (sign << 31) | (exp << 23) | mantissa;
|
||||||
f |= exp << 23;
|
|
||||||
f |= mantissa;
|
return Common::BitCast<float>(f);
|
||||||
float fl;
|
|
||||||
memcpy(&fl, &f, sizeof(float));
|
|
||||||
return fl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FPImm8FromFloat(float value, uint8_t* immOut)
|
bool FPImm8FromFloat(float value, u8* imm_out)
|
||||||
{
|
{
|
||||||
uint32_t f;
|
const u32 f = Common::BitCast<u32>(value);
|
||||||
memcpy(&f, &value, sizeof(float));
|
const u32 mantissa4 = (f & 0x7FFFFF) >> 19;
|
||||||
uint32_t mantissa4 = (f & 0x7FFFFF) >> 19;
|
const u32 exponent = (f >> 23) & 0xFF;
|
||||||
uint32_t exponent = (f >> 23) & 0xFF;
|
const u32 sign = f >> 31;
|
||||||
uint32_t sign = f >> 31;
|
|
||||||
if ((exponent >> 7) == ((exponent >> 6) & 1))
|
if ((exponent >> 7) == ((exponent >> 6) & 1))
|
||||||
return false;
|
return false;
|
||||||
uint8_t imm8 = (sign << 7) | ((!(exponent >> 7)) << 6) | ((exponent & 3) << 4) | mantissa4;
|
|
||||||
float newFloat = FPImm8ToFloat(imm8);
|
const u8 imm8 = (sign << 7) | ((!(exponent >> 7)) << 6) | ((exponent & 3) << 4) | mantissa4;
|
||||||
if (newFloat == value)
|
const float new_float = FPImm8ToFloat(imm8);
|
||||||
*immOut = imm8;
|
if (new_float == value)
|
||||||
|
*imm_out = imm8;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
@ -4346,11 +4346,10 @@ void ARM64FloatEmitter::MOVI2F(ARM64Reg Rd, float value, ARM64Reg scratch, bool
|
||||||
{
|
{
|
||||||
ASSERT_MSG(DYNA_REC, scratch != INVALID_REG,
|
ASSERT_MSG(DYNA_REC, scratch != INVALID_REG,
|
||||||
"Failed to find a way to generate FP immediate %f without scratch", value);
|
"Failed to find a way to generate FP immediate %f without scratch", value);
|
||||||
u32 ival;
|
|
||||||
if (negate)
|
if (negate)
|
||||||
value = -value;
|
value = -value;
|
||||||
|
|
||||||
memcpy(&ival, &value, sizeof(ival));
|
const u32 ival = Common::BitCast<u32>(value);
|
||||||
m_emit->MOVI2R(scratch, ival);
|
m_emit->MOVI2R(scratch, ival);
|
||||||
FMOV(Rd, scratch);
|
FMOV(Rd, scratch);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue