mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-04 14:08:37 +00:00
Implement std::bit_cast<>
Partial implementation of std::bit_cast from C++20. Also fix most strict-aliasing rule break warnings (gcc).
This commit is contained in:
parent
790962425c
commit
dfd50d0185
24 changed files with 145 additions and 176 deletions
|
|
@ -1000,8 +1000,8 @@ bool spu_interpreter_fast::FM(spu_thread& spu, spu_opcode_t op)
|
|||
|
||||
//check for extended
|
||||
const auto nan_check = _mm_cmpeq_ps(_mm_and_ps(primary_result, all_exp_bits), all_exp_bits);
|
||||
const auto sign_mask = _mm_xor_ps(_mm_and_ps((__m128&)sign_bits, spu.gpr[op.ra].vf), _mm_and_ps((__m128&)sign_bits, spu.gpr[op.rb].vf));
|
||||
const auto extended_result = _mm_or_ps(sign_mask, _mm_andnot_ps((__m128&)sign_bits, primary_result));
|
||||
const auto sign_mask = _mm_xor_ps(_mm_and_ps(sign_bits, spu.gpr[op.ra].vf), _mm_and_ps(sign_bits, spu.gpr[op.rb].vf));
|
||||
const auto extended_result = _mm_or_ps(sign_mask, _mm_andnot_ps(sign_bits, primary_result));
|
||||
const auto final_extended = _mm_andnot_ps(denorm_operand_mask, extended_result);
|
||||
|
||||
//if nan, result = ext, else result = flushed
|
||||
|
|
@ -1769,7 +1769,7 @@ bool spu_interpreter::MPYA(spu_thread& spu, spu_opcode_t op)
|
|||
bool spu_interpreter_fast::FNMS(spu_thread& spu, spu_opcode_t op)
|
||||
{
|
||||
const u32 test_bits = 0x7f800000;
|
||||
auto mask = _mm_set1_ps((f32&)test_bits);
|
||||
auto mask = _mm_set1_ps(std::bit_cast<f32>(test_bits));
|
||||
|
||||
auto test_a = _mm_and_ps(spu.gpr[op.ra].vf, mask);
|
||||
auto mask_a = _mm_cmpneq_ps(test_a, mask);
|
||||
|
|
@ -1786,7 +1786,7 @@ bool spu_interpreter_fast::FNMS(spu_thread& spu, spu_opcode_t op)
|
|||
bool spu_interpreter_fast::FMA(spu_thread& spu, spu_opcode_t op)
|
||||
{
|
||||
const u32 test_bits = 0x7f800000;
|
||||
auto mask = _mm_set1_ps((f32&)test_bits);
|
||||
auto mask = _mm_set1_ps(std::bit_cast<f32>(test_bits));
|
||||
|
||||
auto test_a = _mm_and_ps(spu.gpr[op.ra].vf, mask);
|
||||
auto mask_a = _mm_cmpneq_ps(test_a, mask);
|
||||
|
|
@ -1803,7 +1803,7 @@ bool spu_interpreter_fast::FMA(spu_thread& spu, spu_opcode_t op)
|
|||
bool spu_interpreter_fast::FMS(spu_thread& spu, spu_opcode_t op)
|
||||
{
|
||||
const u32 test_bits = 0x7f800000;
|
||||
auto mask = _mm_set1_ps((f32&)test_bits);
|
||||
auto mask = _mm_set1_ps(std::bit_cast<f32>(test_bits));
|
||||
|
||||
auto test_a = _mm_and_ps(spu.gpr[op.ra].vf, mask);
|
||||
auto mask_a = _mm_cmpneq_ps(test_a, mask);
|
||||
|
|
@ -1838,20 +1838,20 @@ static void SetHostRoundingMode(u32 rn)
|
|||
|
||||
// Floating-point utility constants and functions
|
||||
static const u32 FLOAT_MAX_NORMAL_I = 0x7F7FFFFF;
|
||||
static const float& FLOAT_MAX_NORMAL = (float&)FLOAT_MAX_NORMAL_I;
|
||||
static const f32 FLOAT_MAX_NORMAL = std::bit_cast<f32>(FLOAT_MAX_NORMAL_I);
|
||||
static const u32 FLOAT_NAN_I = 0x7FC00000;
|
||||
static const float& FLOAT_NAN = (float&)FLOAT_NAN_I;
|
||||
static const f32 FLOAT_NAN = std::bit_cast<f32>(FLOAT_NAN_I);
|
||||
static const u64 DOUBLE_NAN_I = 0x7FF8000000000000ULL;
|
||||
static const double DOUBLE_NAN = (double&)DOUBLE_NAN_I;
|
||||
static const f64 DOUBLE_NAN = std::bit_cast<f64>(DOUBLE_NAN_I);
|
||||
|
||||
inline bool issnan(double x)
|
||||
{
|
||||
return std::isnan(x) && ((s64&)x) << 12 > 0;
|
||||
return std::isnan(x) && (std::bit_cast<s64>(x)) << 12 > 0;
|
||||
}
|
||||
|
||||
inline bool issnan(float x)
|
||||
{
|
||||
return std::isnan(x) && ((s32&)x) << 9 > 0;
|
||||
return std::isnan(x) && (std::bit_cast<s32>(x)) << 9 > 0;
|
||||
}
|
||||
|
||||
inline bool isextended(float x)
|
||||
|
|
@ -1862,14 +1862,14 @@ inline bool isextended(float x)
|
|||
inline float extended(bool sign, u32 mantissa) // returns -1^sign * 2^127 * (1.mantissa)
|
||||
{
|
||||
u32 bits = sign << 31 | 0x7F800000 | mantissa;
|
||||
return (float&)bits;
|
||||
return std::bit_cast<f32>(bits);
|
||||
}
|
||||
|
||||
inline float ldexpf_extended(float x, int exp) // ldexpf() for extended values, assumes result is in range
|
||||
{
|
||||
u32 bits = (u32&)x;
|
||||
u32 bits = std::bit_cast<u32>(x);
|
||||
if (bits << 1 != 0) bits += exp * 0x00800000;
|
||||
return (float&)bits;
|
||||
return std::bit_cast<f32>(bits);
|
||||
}
|
||||
|
||||
inline bool isdenormal(float x)
|
||||
|
|
@ -1979,8 +1979,8 @@ static void FA_FS(spu_thread& spu, spu_opcode_t op, bool sub)
|
|||
{
|
||||
if (std::signbit(a) != std::signbit(b))
|
||||
{
|
||||
const u32 bits = (u32&)a - 1;
|
||||
result = (float&)bits;
|
||||
const u32 bits = std::bit_cast<u32>(a) - 1;
|
||||
result = std::bit_cast<f32>(bits);
|
||||
}
|
||||
else
|
||||
|
||||
|
|
@ -1990,8 +1990,8 @@ static void FA_FS(spu_thread& spu, spu_opcode_t op, bool sub)
|
|||
{
|
||||
if (std::signbit(a) != std::signbit(b))
|
||||
{
|
||||
const u32 bits = (u32&)b - 1;
|
||||
result = (float&)bits;
|
||||
const u32 bits = std::bit_cast<u32>(b) - 1;
|
||||
result = std::bit_cast<f32>(bits);
|
||||
}
|
||||
else
|
||||
result = b;
|
||||
|
|
@ -2521,8 +2521,8 @@ static void FMA(spu_thread& spu, spu_opcode_t op, bool neg, bool sub)
|
|||
result = new_a * new_b;
|
||||
if (c != 0.0f && std::signbit(c) != sign)
|
||||
{
|
||||
u32 bits = (u32&)result - 1;
|
||||
result = (float&)bits;
|
||||
u32 bits = std::bit_cast<u32>(result) - 1;
|
||||
result = std::bit_cast<f32>(bits);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -2552,8 +2552,8 @@ static void FMA(spu_thread& spu, spu_opcode_t op, bool neg, bool sub)
|
|||
result = c;
|
||||
if (sign != std::signbit(c))
|
||||
{
|
||||
u32 bits = (u32&)result - 1;
|
||||
result = (float&)bits;
|
||||
u32 bits = std::bit_cast<u32>(result) - 1;
|
||||
result = std::bit_cast<f32>(bits);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue