emit_x64_floating_point: Introduce ICODE
This commit is contained in:
parent
7022281a0b
commit
4b8a781c04
1 changed files with 19 additions and 22 deletions
|
@ -61,19 +61,23 @@ constexpr u64 f64_max_s64_lim = 0x43e0000000000000u; // 2^63 as a double (actual
|
||||||
constexpr u64 f64_min_u64 = 0x0000000000000000u; // 0 as a double
|
constexpr u64 f64_min_u64 = 0x0000000000000000u; // 0 as a double
|
||||||
constexpr u64 f64_max_u64_lim = 0x43f0000000000000u; // 2^64 as a double (actual maximum unrepresentable)
|
constexpr u64 f64_max_u64_lim = 0x43f0000000000000u; // 2^64 as a double (actual maximum unrepresentable)
|
||||||
|
|
||||||
template<size_t fsize, typename T>
|
#define FCODE(NAME) \
|
||||||
T ChooseOnFsize([[maybe_unused]] T f32, [[maybe_unused]] T f64) {
|
[&code](auto... args){ \
|
||||||
static_assert(fsize == 32 || fsize == 64, "fsize must be either 32 or 64");
|
if constexpr (fsize == 32) { \
|
||||||
|
code.NAME##s(args...); \
|
||||||
if constexpr (fsize == 32) {
|
} else { \
|
||||||
return f32;
|
code.NAME##d(args...); \
|
||||||
} else {
|
} \
|
||||||
return f64;
|
|
||||||
}
|
}
|
||||||
|
#define ICODE(NAME) \
|
||||||
|
[&code](auto... args){ \
|
||||||
|
if constexpr (fsize == 32) { \
|
||||||
|
code.NAME##d(args...); \
|
||||||
|
} else { \
|
||||||
|
code.NAME##q(args...); \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FCODE(NAME) (code.*ChooseOnFsize<fsize>(&Xbyak::CodeGenerator::NAME##s, &Xbyak::CodeGenerator::NAME##d))
|
|
||||||
|
|
||||||
std::optional<int> ConvertRoundingModeToX64Immediate(FP::RoundingMode rounding_mode) {
|
std::optional<int> ConvertRoundingModeToX64Immediate(FP::RoundingMode rounding_mode) {
|
||||||
switch (rounding_mode) {
|
switch (rounding_mode) {
|
||||||
case FP::RoundingMode::ToNearest_TieEven:
|
case FP::RoundingMode::ToNearest_TieEven:
|
||||||
|
@ -148,17 +152,10 @@ Xbyak::Label ProcessNaN(BlockOfCode& code, Xbyak::Xmm a) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
void PostProcessNaN(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm tmp) {
|
void PostProcessNaN(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm tmp) {
|
||||||
if constexpr (fsize == 32) {
|
|
||||||
code.movaps(tmp, result);
|
code.movaps(tmp, result);
|
||||||
code.cmpunordps(tmp, tmp);
|
FCODE(cmpunordp)(tmp, tmp);
|
||||||
code.pslld(tmp, 31);
|
ICODE(psll)(tmp, int(fsize - 1));
|
||||||
code.xorps(result, tmp);
|
code.xorps(result, tmp);
|
||||||
} else {
|
|
||||||
code.movaps(tmp, result);
|
|
||||||
code.cmpunordpd(tmp, tmp);
|
|
||||||
code.psllq(tmp, 63);
|
|
||||||
code.xorps(result, tmp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is necessary because x86 and ARM differ in they way they return NaNs from floating point operations
|
// This is necessary because x86 and ARM differ in they way they return NaNs from floating point operations
|
||||||
|
|
Loading…
Reference in a new issue