no aliases, fix type util
Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
ee1c3dc1f8
commit
f03c6571cb
13 changed files with 80 additions and 92 deletions
|
|
@ -8,7 +8,7 @@ add_library(dynarmic STATIC
|
|||
backend/exception_handler.h
|
||||
common/assert.cpp
|
||||
common/assert.h
|
||||
common/cast_util.h
|
||||
common/type_util.h
|
||||
common/common_types.h
|
||||
common/crypto/aes.cpp
|
||||
common/crypto/aes.h
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include "dynarmic/backend/arm64/devirtualize.h"
|
||||
#include "dynarmic/backend/arm64/emit_arm64.h"
|
||||
#include "dynarmic/backend/arm64/stack_layout.h"
|
||||
#include "dynarmic/common/cast_util.h"
|
||||
#include "dynarmic/common/type_util.h"
|
||||
#include "dynarmic/common/fp/fpcr.h"
|
||||
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
||||
#include "dynarmic/frontend/A32/translate/a32_translate.h"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include "dynarmic/backend/arm64/devirtualize.h"
|
||||
#include "dynarmic/backend/arm64/emit_arm64.h"
|
||||
#include "dynarmic/backend/arm64/stack_layout.h"
|
||||
#include "dynarmic/common/cast_util.h"
|
||||
#include "dynarmic/common/type_util.h"
|
||||
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
||||
#include "dynarmic/frontend/A64/translate/a64_translate.h"
|
||||
#include "dynarmic/interface/A64/config.h"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include "dynarmic/backend/arm64/devirtualize.h"
|
||||
#include "dynarmic/backend/arm64/emit_arm64.h"
|
||||
#include "dynarmic/backend/arm64/stack_layout.h"
|
||||
#include "dynarmic/common/cast_util.h"
|
||||
#include "dynarmic/common/type_util.h"
|
||||
#include "dynarmic/common/fp/fpcr.h"
|
||||
#include "dynarmic/common/llvm_disassemble.h"
|
||||
#include "dynarmic/interface/exclusive_monitor.h"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include "dynarmic/backend/arm64/emit_context.h"
|
||||
#include "dynarmic/backend/arm64/fpsr_manager.h"
|
||||
#include "dynarmic/backend/arm64/reg_alloc.h"
|
||||
#include "dynarmic/common/cast_util.h"
|
||||
#include "dynarmic/common/type_util.h"
|
||||
#include "dynarmic/common/fp/fpcr.h"
|
||||
#include "dynarmic/common/fp/fpsr.h"
|
||||
#include "dynarmic/common/fp/info.h"
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#include "dynarmic/backend/x64/constant_pool.h"
|
||||
#include "dynarmic/backend/x64/host_feature.h"
|
||||
#include "dynarmic/backend/x64/jitstate_info.h"
|
||||
#include "dynarmic/common/cast_util.h"
|
||||
#include "dynarmic/common/type_util.h"
|
||||
#include "dynarmic/interface/halt_reason.h"
|
||||
#include "dynarmic/ir/cond.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include "dynarmic/backend/x64/block_of_code.h"
|
||||
#include "dynarmic/backend/x64/constants.h"
|
||||
#include "dynarmic/backend/x64/emit_x64.h"
|
||||
#include "dynarmic/common/cast_util.h"
|
||||
#include "dynarmic/common/type_util.h"
|
||||
#include "dynarmic/common/fp/fpcr.h"
|
||||
#include "dynarmic/common/fp/fpsr.h"
|
||||
#include "dynarmic/common/fp/info.h"
|
||||
|
|
@ -35,22 +35,8 @@
|
|||
#include "dynarmic/ir/basic_block.h"
|
||||
#include "dynarmic/ir/microinstruction.h"
|
||||
|
||||
#define FCODE(NAME) \
|
||||
[&code](auto... args) { \
|
||||
if (fsize == 32) { \
|
||||
code.NAME##s(args...); \
|
||||
} else { \
|
||||
code.NAME##d(args...); \
|
||||
} \
|
||||
}
|
||||
#define ICODE(NAME) \
|
||||
[&code](auto... args) { \
|
||||
if (fsize == 32) { \
|
||||
code.NAME##d(args...); \
|
||||
} else { \
|
||||
code.NAME##q(args...); \
|
||||
} \
|
||||
}
|
||||
#define FCODE(NAME) [&](auto... args) { if (fsize == 32) code.NAME##s(args...); else code.NAME##d(args...); }
|
||||
#define ICODE(NAME) [&](auto... args) { if (fsize == 32) code.NAME##d(args...); else code.NAME##q(args...); }
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
||||
|
|
@ -204,7 +190,7 @@ void PostProcessNaN(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm tmp) {
|
|||
// We allow for the case where op1 and result are the same register. We do not read from op1 once result is written to.
|
||||
template<size_t fsize>
|
||||
void EmitPostProcessNaNs(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm op1, Xbyak::Xmm op2, Xbyak::Reg64 tmp, Xbyak::Label end) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
constexpr FPT exponent_mask = FP::FPInfo<FPT>::exponent_mask;
|
||||
constexpr FPT mantissa_msb = FP::FPInfo<FPT>::mantissa_msb;
|
||||
constexpr u8 mantissa_msb_bit = static_cast<u8>(FP::FPInfo<FPT>::explicit_mantissa_width - 1);
|
||||
|
|
@ -279,7 +265,7 @@ void FPTwoOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
|
|||
if (!ctx.FPCR().DN() && !ctx.HasOptimization(OptimizationFlag::Unsafe_InaccurateNaN)) {
|
||||
end = ProcessNaN<fsize>(code, ctx, result);
|
||||
}
|
||||
if (std::is_member_function_pointer_v<Function>) {
|
||||
if constexpr (std::is_member_function_pointer_v<Function>) {
|
||||
(code.*fn)(result, result);
|
||||
} else {
|
||||
fn(result);
|
||||
|
|
@ -298,7 +284,7 @@ void FPTwoOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
|
|||
|
||||
template<size_t fsize, typename Function>
|
||||
void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
|
|
@ -306,7 +292,7 @@ void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn)
|
|||
const Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]);
|
||||
const Xbyak::Xmm operand = ctx.reg_alloc.UseScratchXmm(args[1]);
|
||||
|
||||
if (std::is_member_function_pointer_v<Function>) {
|
||||
if constexpr (std::is_member_function_pointer_v<Function>) {
|
||||
(code.*fn)(result, operand);
|
||||
} else {
|
||||
fn(result, operand);
|
||||
|
|
@ -328,7 +314,7 @@ void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn)
|
|||
SharedLabel end = GenSharedLabel(), nan = GenSharedLabel();
|
||||
|
||||
code.movaps(result, op1);
|
||||
if (std::is_member_function_pointer_v<Function>) {
|
||||
if constexpr (std::is_member_function_pointer_v<Function>) {
|
||||
(code.*fn)(result, op2);
|
||||
} else {
|
||||
fn(result, op2);
|
||||
|
|
@ -357,7 +343,7 @@ void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn)
|
|||
|
||||
template<size_t fsize>
|
||||
void FPAbs(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
constexpr FPT non_sign_mask = FP::FPInfo<FPT>::sign_mask - FPT(1u);
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
|
@ -383,7 +369,7 @@ void EmitX64::EmitFPAbs64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize>
|
||||
void FPNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
constexpr FPT sign_mask = FP::FPInfo<FPT>::sign_mask;
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
|
@ -473,7 +459,7 @@ static void EmitFPMinMax(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize, bool is_max>
|
||||
static inline void EmitFPMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) noexcept {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
constexpr FPT default_nan = FP::FPInfo<FPT>::DefaultNaN();
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
|
@ -625,7 +611,7 @@ void EmitX64::EmitFPMul64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize, bool negate_product>
|
||||
static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
const auto fallback_fn = negate_product ? &FP::FPMulSub<FPT> : &FP::FPMulAdd<FPT>;
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
|
@ -852,7 +838,7 @@ void EmitX64::EmitFPMulSub64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize>
|
||||
static void EmitFPMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
|
|
@ -912,7 +898,7 @@ void EmitX64::EmitFPMulX64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize>
|
||||
static void EmitFPRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
if (fsize != 16) {
|
||||
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
|
||||
|
|
@ -958,7 +944,7 @@ void EmitX64::EmitFPRecipEstimate64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize>
|
||||
static void EmitFPRecipExponent(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ctx.reg_alloc.HostCall(inst, args[0]);
|
||||
|
|
@ -981,7 +967,7 @@ void EmitX64::EmitFPRecipExponent64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize>
|
||||
static void EmitFPRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
|
|
@ -1105,7 +1091,7 @@ static void EmitFPRound(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, siz
|
|||
constexpr size_t fsize = mp::get<0, I>::value;
|
||||
constexpr FP::RoundingMode rounding_mode = mp::get<1, I>::value;
|
||||
constexpr bool exact = mp::get<2, I>::value;
|
||||
using InputSize = FP::UnsignedIntegerN<fsize>;
|
||||
using InputSize = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
return FP::FPRoundInt<InputSize>(static_cast<InputSize>(input), fpcr, rounding_mode, exact, fpsr);
|
||||
})};
|
||||
|
|
@ -1133,7 +1119,7 @@ void EmitX64::EmitFPRoundInt64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize>
|
||||
static void EmitFPRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
if (fsize != 16) {
|
||||
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
|
||||
|
|
@ -1312,7 +1298,7 @@ void EmitX64::EmitFPRSqrtEstimate64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize>
|
||||
static void EmitFPRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
|
|
@ -1735,7 +1721,7 @@ static void EmitFPToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
[](u64 input, FP::FPSR& fpsr, FP::FPCR fpcr) {
|
||||
constexpr size_t fbits = mp::get<0, I>::value;
|
||||
constexpr FP::RoundingMode rounding_mode = mp::get<1, I>::value;
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
return FP::FPToFixed<FPT>(isize, static_cast<FPT>(input), fbits, unsigned_, fpcr, rounding_mode, fpsr);
|
||||
})};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <mcl/macro/concatenate_tokens.hpp>
|
||||
#include "dynarmic/common/fp/util.h"
|
||||
#include "dynarmic/common/type_util.h"
|
||||
|
||||
#define AxxEmitX64 CONCATENATE_TOKENS(Axx, EmitX64)
|
||||
#define AxxEmitContext CONCATENATE_TOKENS(Axx, EmitContext)
|
||||
|
|
@ -224,7 +224,7 @@ void AxxEmitX64::EmitExclusiveReadMemory(AxxEmitContext& ctx, IR::Inst* inst) {
|
|||
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
|
||||
|
||||
if constexpr (bitsize != 128) {
|
||||
using T = FP::UnsignedIntegerN<bitsize>;
|
||||
using T = Common::UnsignedIntegerN<bitsize>;
|
||||
|
||||
ctx.reg_alloc.HostCall(inst, {}, args[1]);
|
||||
|
||||
|
|
@ -291,7 +291,7 @@ void AxxEmitX64::EmitExclusiveWriteMemory(AxxEmitContext& ctx, IR::Inst* inst) {
|
|||
code.mov(code.byte[code.ABI_JIT_PTR + offsetof(AxxJitState, exclusive_state)], u8(0));
|
||||
code.mov(code.ABI_PARAM1, reinterpret_cast<u64>(&conf));
|
||||
if constexpr (bitsize != 128) {
|
||||
using T = FP::UnsignedIntegerN<bitsize>;
|
||||
using T = Common::UnsignedIntegerN<bitsize>;
|
||||
|
||||
code.CallLambda(
|
||||
[](AxxUserConfig& conf, Axx::VAddr vaddr, T value) -> u32 {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "dynarmic/ir/microinstruction.h"
|
||||
#include "dynarmic/ir/opcodes.h"
|
||||
#include "dynarmic/common/fp/util.h"
|
||||
#include "dynarmic/common/type_util.h"
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
||||
|
|
@ -38,7 +39,7 @@ void EmitSignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst)
|
|||
Xbyak::Reg addend = ctx.reg_alloc.UseGpr(args[1]).changeBit(size);
|
||||
Xbyak::Reg overflow = ctx.reg_alloc.ScratchGpr().changeBit(size);
|
||||
|
||||
constexpr u64 int_max = static_cast<u64>((std::numeric_limits<FP::SignedIntegerN<size>>::max)());
|
||||
constexpr u64 int_max = static_cast<u64>((std::numeric_limits<Common::SignedIntegerN<size>>::max)());
|
||||
if constexpr (size < 64) {
|
||||
code.xor_(overflow.cvt32(), overflow.cvt32());
|
||||
code.bt(result.cvt32(), size - 1);
|
||||
|
|
@ -82,7 +83,7 @@ void EmitUnsignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst
|
|||
Xbyak::Reg op_result = ctx.reg_alloc.UseScratchGpr(args[0]).changeBit(size);
|
||||
Xbyak::Reg addend = ctx.reg_alloc.UseScratchGpr(args[1]).changeBit(size);
|
||||
|
||||
constexpr u64 boundary = op == Op::Add ? (std::numeric_limits<FP::UnsignedIntegerN<size>>::max)() : 0;
|
||||
constexpr u64 boundary = op == Op::Add ? (std::numeric_limits<Common::UnsignedIntegerN<size>>::max)() : 0;
|
||||
|
||||
if constexpr (op == Op::Add) {
|
||||
code.add(op_result, addend);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "dynarmic/common/fp/info.h"
|
||||
#include "dynarmic/common/fp/op.h"
|
||||
#include "dynarmic/common/fp/util.h"
|
||||
#include "dynarmic/common/type_util.h"
|
||||
#include "dynarmic/common/lut_from_list.h"
|
||||
#include "dynarmic/interface/optimization_flags.h"
|
||||
#include "dynarmic/ir/basic_block.h"
|
||||
|
|
@ -75,7 +76,7 @@ void MaybeStandardFPSCRValue(BlockOfCode& code, EmitContext& ctx, bool fpcr_cont
|
|||
template<size_t fsize, template<typename> class Indexer, size_t narg>
|
||||
struct NaNHandler {
|
||||
public:
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
using function_type = void (*)(std::array<VectorArray<FPT>, narg>&, FP::FPCR);
|
||||
|
||||
|
|
@ -157,33 +158,33 @@ Xbyak::Address GetVectorOf(BlockOfCode& code) {
|
|||
|
||||
template<size_t fsize>
|
||||
Xbyak::Address GetNaNVector(BlockOfCode& code) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
return GetVectorOf<fsize, FP::FPInfo<FPT>::DefaultNaN()>(code);
|
||||
}
|
||||
|
||||
template<size_t fsize>
|
||||
Xbyak::Address GetNegativeZeroVector(BlockOfCode& code) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
return GetVectorOf<fsize, FP::FPInfo<FPT>::Zero(true)>(code);
|
||||
}
|
||||
|
||||
template<size_t fsize>
|
||||
Xbyak::Address GetNonSignMaskVector(BlockOfCode& code) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
constexpr FPT non_sign_mask = FP::FPInfo<FPT>::exponent_mask | FP::FPInfo<FPT>::mantissa_mask;
|
||||
return GetVectorOf<fsize, non_sign_mask>(code);
|
||||
}
|
||||
|
||||
template<size_t fsize>
|
||||
Xbyak::Address GetSmallestNormalVector(BlockOfCode& code) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
constexpr FPT smallest_normal_number = FP::FPValue<FPT, false, FP::FPInfo<FPT>::exponent_min, 1>();
|
||||
return GetVectorOf<fsize, smallest_normal_number>(code);
|
||||
}
|
||||
|
||||
template<size_t fsize, bool sign, int exponent, FP::UnsignedIntegerN<fsize> value>
|
||||
template<size_t fsize, bool sign, int exponent, Common::UnsignedIntegerN<fsize> value>
|
||||
Xbyak::Address GetVectorOf(BlockOfCode& code) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
return GetVectorOf<fsize, FP::FPValue<FPT, sign, exponent, value>()>(code);
|
||||
}
|
||||
|
||||
|
|
@ -1083,7 +1084,7 @@ static void EmitFPVectorMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::I
|
|||
|
||||
if (code.HasHostFeature(HostFeature::AVX)) {
|
||||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
// result = xmm_a == SNaN || xmm_b == QNaN
|
||||
{
|
||||
|
|
@ -1156,7 +1157,7 @@ static void EmitFPVectorMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::I
|
|||
}
|
||||
|
||||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
// result = xmm_a == SNaN || xmm_b == QNaN
|
||||
{
|
||||
|
|
@ -1312,7 +1313,7 @@ static void EmitFPVectorMulAddFallback(VectorArray<FPT>& result, const VectorArr
|
|||
|
||||
template<size_t fsize>
|
||||
void EmitFPVectorMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& addend, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
for (size_t i = 0; i < result.size(); i++) {
|
||||
|
|
@ -1423,7 +1424,7 @@ void EmitX64::EmitFPVectorMulAdd64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize>
|
||||
static void EmitFPVectorMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const bool fpcr_controlled = args[2].GetImmediateU1();
|
||||
|
|
@ -1489,7 +1490,7 @@ void EmitX64::EmitFPVectorMulX64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize>
|
||||
void FPVectorNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
constexpr FPT sign_mask = FP::FPInfo<FPT>::sign_mask;
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
|
@ -1542,7 +1543,7 @@ void EmitX64::EmitFPVectorPairedAddLower64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize>
|
||||
static void EmitRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
if constexpr (fsize != 16) {
|
||||
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
|
||||
|
|
@ -1588,7 +1589,7 @@ void EmitX64::EmitFPVectorRecipEstimate64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize>
|
||||
static void EmitRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
for (size_t i = 0; i < result.size(); i++) {
|
||||
|
|
@ -1720,7 +1721,7 @@ void EmitFPVectorRoundInt(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
static const auto lut = Common::GenerateLookupTableFromList(
|
||||
[]<typename I>(I) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>; // WORKAROUND: For issue 678 on MSVC
|
||||
using FPT = Common::UnsignedIntegerN<fsize>; // WORKAROUND: For issue 678 on MSVC
|
||||
return std::pair{
|
||||
mp::lower_to_tuple_v<I>,
|
||||
Common::FptrCast(
|
||||
|
|
@ -1752,7 +1753,7 @@ void EmitX64::EmitFPVectorRoundInt64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize>
|
||||
static void EmitRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& operand, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
for (size_t i = 0; i < result.size(); i++) {
|
||||
|
|
@ -1844,7 +1845,7 @@ void EmitX64::EmitFPVectorRSqrtEstimate64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<size_t fsize>
|
||||
static void EmitRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>;
|
||||
using FPT = Common::UnsignedIntegerN<fsize>;
|
||||
|
||||
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
for (size_t i = 0; i < result.size(); i++) {
|
||||
|
|
@ -2114,7 +2115,7 @@ void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
FCODE(orp)(src, exceed_unsigned);
|
||||
}
|
||||
} else {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>; // WORKAROUND: For issue 678 on MSVC
|
||||
using FPT = Common::UnsignedIntegerN<fsize>; // WORKAROUND: For issue 678 on MSVC
|
||||
constexpr u64 integer_max = static_cast<FPT>((std::numeric_limits<std::conditional_t<unsigned_, FPT, std::make_signed_t<FPT>>>::max)());
|
||||
|
||||
code.movaps(xmm0, GetVectorOf<fsize, float_upper_limit_signed>(code));
|
||||
|
|
@ -2139,7 +2140,7 @@ void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
static const auto lut = Common::GenerateLookupTableFromList(
|
||||
[]<typename I>(I) {
|
||||
using FPT = FP::UnsignedIntegerN<fsize>; // WORKAROUND: For issue 678 on MSVC
|
||||
using FPT = Common::UnsignedIntegerN<fsize>; // WORKAROUND: For issue 678 on MSVC
|
||||
return std::pair{
|
||||
mp::lower_to_tuple_v<I>,
|
||||
Common::FptrCast(
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2018 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mcl/type_traits/function_info.hpp>
|
||||
|
||||
namespace Dynarmic::Common {
|
||||
|
||||
/// Cast a lambda into an equivalent function pointer.
|
||||
template<class Function>
|
||||
inline auto FptrCast(Function f) noexcept {
|
||||
return static_cast<mcl::equivalent_function_type<Function>*>(f);
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Common
|
||||
|
|
@ -97,14 +97,4 @@ constexpr std::optional<FPT> ProcessNaNs(FPT a, FPT b, FPT c) {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
namespace Detail {
|
||||
template<std::size_t size> struct IntegerOfSize {};
|
||||
template<> struct IntegerOfSize<8> { using U = std::uint8_t, S = std::int8_t; };
|
||||
template<> struct IntegerOfSize<16> { using U = std::uint16_t, S = std::int16_t; };
|
||||
template<> struct IntegerOfSize<32> { using U = std::uint32_t, S = std::int32_t; };
|
||||
template<> struct IntegerOfSize<64> { using U = std::uint64_t, S = std::int64_t; };
|
||||
}
|
||||
template<size_t N> using FP::UnsignedIntegerN = typename Detail::IntegerOfSize<N>::U;
|
||||
template<size_t N> using FP::SignedIntegerN = typename Detail::IntegerOfSize<N>::S;
|
||||
|
||||
} // namespace Dynarmic::FP
|
||||
|
|
|
|||
28
src/dynarmic/src/dynarmic/common/type_util.h
Normal file
28
src/dynarmic/src/dynarmic/common/type_util.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2018 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mcl/type_traits/function_info.hpp>
|
||||
|
||||
namespace Dynarmic::Common {
|
||||
|
||||
/// Cast a lambda into an equivalent function pointer.
|
||||
template<class Function>
|
||||
inline auto FptrCast(Function f) noexcept {
|
||||
return static_cast<mcl::equivalent_function_type<Function>*>(f);
|
||||
}
|
||||
|
||||
namespace Detail {
|
||||
template<std::size_t size> struct IntegerOfSize {};
|
||||
template<> struct IntegerOfSize<8> { using U = std::uint8_t; using S = std::int8_t; };
|
||||
template<> struct IntegerOfSize<16> { using U = std::uint16_t; using S = std::int16_t; };
|
||||
template<> struct IntegerOfSize<32> { using U = std::uint32_t; using S = std::int32_t; };
|
||||
template<> struct IntegerOfSize<64> { using U = std::uint64_t; using S = std::int64_t; };
|
||||
}
|
||||
template<size_t N> using UnsignedIntegerN = typename Detail::IntegerOfSize<N>::U;
|
||||
template<size_t N> using SignedIntegerN = typename Detail::IntegerOfSize<N>::S;
|
||||
|
||||
} // namespace Dynarmic::Common
|
||||
Loading…
Add table
Add a link
Reference in a new issue