translator: Use templates for stronger type guarantees
This commit is contained in:
parent
dfcfd62d4f
commit
0bac6e8e1c
|
@ -9,7 +9,6 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/kernel/thread_management.h"
|
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
|
|
||||||
namespace Libraries::Kernel {
|
namespace Libraries::Kernel {
|
||||||
|
@ -82,7 +81,6 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct WaitingThread : public ListBaseHook {
|
struct WaitingThread : public ListBaseHook {
|
||||||
std::string name;
|
|
||||||
std::condition_variable cv;
|
std::condition_variable cv;
|
||||||
u32 priority;
|
u32 priority;
|
||||||
s32 need_count;
|
s32 need_count;
|
||||||
|
@ -90,7 +88,6 @@ public:
|
||||||
bool was_cancled{};
|
bool was_cancled{};
|
||||||
|
|
||||||
explicit WaitingThread(s32 need_count, bool is_fifo) : need_count{need_count} {
|
explicit WaitingThread(s32 need_count, bool is_fifo) : need_count{need_count} {
|
||||||
name = scePthreadSelf()->name;
|
|
||||||
if (is_fifo) {
|
if (is_fifo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,101 +73,190 @@ void Translator::EmitPrologue() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <typename T>
|
||||||
IR::U32F32 Translator::GetSrc(const InstOperand& operand, bool force_flt) {
|
T Translator::GetSrc(const InstOperand& operand) {
|
||||||
IR::U32F32 value{};
|
constexpr bool is_float = std::is_same_v<T, IR::F32>;
|
||||||
|
|
||||||
const bool is_float = operand.type == ScalarType::Float32 || force_flt;
|
const auto get_imm = [&](auto value) -> T {
|
||||||
|
if constexpr (is_float) {
|
||||||
|
return ir.Imm32(std::bit_cast<float>(value));
|
||||||
|
} else {
|
||||||
|
return ir.Imm32(std::bit_cast<u32>(value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
T value{};
|
||||||
switch (operand.field) {
|
switch (operand.field) {
|
||||||
case OperandField::ScalarGPR:
|
case OperandField::ScalarGPR:
|
||||||
if (is_float) {
|
value = ir.GetScalarReg<T>(IR::ScalarReg(operand.code));
|
||||||
value = ir.GetScalarReg<IR::F32>(IR::ScalarReg(operand.code));
|
|
||||||
} else {
|
|
||||||
value = ir.GetScalarReg<IR::U32>(IR::ScalarReg(operand.code));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case OperandField::VectorGPR:
|
case OperandField::VectorGPR:
|
||||||
if (is_float) {
|
value = ir.GetVectorReg<T>(IR::VectorReg(operand.code));
|
||||||
value = ir.GetVectorReg<IR::F32>(IR::VectorReg(operand.code));
|
|
||||||
} else {
|
|
||||||
value = ir.GetVectorReg<IR::U32>(IR::VectorReg(operand.code));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case OperandField::ConstZero:
|
case OperandField::ConstZero:
|
||||||
if (is_float) {
|
value = get_imm(0U);
|
||||||
value = ir.Imm32(0.f);
|
|
||||||
} else {
|
|
||||||
value = ir.Imm32(0U);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case OperandField::SignedConstIntPos:
|
case OperandField::SignedConstIntPos:
|
||||||
ASSERT(!force_flt);
|
value = get_imm(operand.code - SignedConstIntPosMin + 1);
|
||||||
value = ir.Imm32(operand.code - SignedConstIntPosMin + 1);
|
|
||||||
break;
|
break;
|
||||||
case OperandField::SignedConstIntNeg:
|
case OperandField::SignedConstIntNeg:
|
||||||
ASSERT(!force_flt);
|
value = get_imm(-s32(operand.code) + SignedConstIntNegMin - 1);
|
||||||
value = ir.Imm32(-s32(operand.code) + SignedConstIntNegMin - 1);
|
|
||||||
break;
|
break;
|
||||||
case OperandField::LiteralConst:
|
case OperandField::LiteralConst:
|
||||||
if (is_float) {
|
value = get_imm(operand.code);
|
||||||
value = ir.Imm32(std::bit_cast<float>(operand.code));
|
|
||||||
} else {
|
|
||||||
value = ir.Imm32(operand.code);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case OperandField::ConstFloatPos_1_0:
|
case OperandField::ConstFloatPos_1_0:
|
||||||
if (is_float) {
|
value = get_imm(1.f);
|
||||||
value = ir.Imm32(1.f);
|
|
||||||
} else {
|
|
||||||
value = ir.Imm32(std::bit_cast<u32>(1.f));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case OperandField::ConstFloatPos_0_5:
|
case OperandField::ConstFloatPos_0_5:
|
||||||
value = ir.Imm32(0.5f);
|
value = get_imm(0.5f);
|
||||||
break;
|
break;
|
||||||
case OperandField::ConstFloatPos_2_0:
|
case OperandField::ConstFloatPos_2_0:
|
||||||
value = ir.Imm32(2.0f);
|
value = get_imm(2.0f);
|
||||||
break;
|
break;
|
||||||
case OperandField::ConstFloatPos_4_0:
|
case OperandField::ConstFloatPos_4_0:
|
||||||
value = ir.Imm32(4.0f);
|
value = get_imm(4.0f);
|
||||||
break;
|
break;
|
||||||
case OperandField::ConstFloatNeg_0_5:
|
case OperandField::ConstFloatNeg_0_5:
|
||||||
value = ir.Imm32(-0.5f);
|
value = get_imm(-0.5f);
|
||||||
break;
|
break;
|
||||||
case OperandField::ConstFloatNeg_1_0:
|
case OperandField::ConstFloatNeg_1_0:
|
||||||
if (is_float) {
|
value = get_imm(-1.0f);
|
||||||
value = ir.Imm32(-1.0f);
|
|
||||||
} else {
|
|
||||||
value = ir.Imm32(std::bit_cast<u32>(-1.0f));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case OperandField::ConstFloatNeg_2_0:
|
case OperandField::ConstFloatNeg_2_0:
|
||||||
value = ir.Imm32(-2.0f);
|
value = get_imm(-2.0f);
|
||||||
break;
|
break;
|
||||||
case OperandField::ConstFloatNeg_4_0:
|
case OperandField::ConstFloatNeg_4_0:
|
||||||
value = ir.Imm32(-4.0f);
|
value = get_imm(-4.0f);
|
||||||
break;
|
break;
|
||||||
case OperandField::VccLo:
|
case OperandField::VccLo:
|
||||||
if (force_flt) {
|
if constexpr (is_float) {
|
||||||
value = ir.BitCast<IR::F32>(ir.GetVccLo());
|
value = ir.BitCast<IR::F32>(ir.GetVccLo());
|
||||||
} else {
|
} else {
|
||||||
value = ir.GetVccLo();
|
value = ir.GetVccLo();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OperandField::VccHi:
|
case OperandField::VccHi:
|
||||||
if (force_flt) {
|
if constexpr (is_float) {
|
||||||
value = ir.BitCast<IR::F32>(ir.GetVccHi());
|
value = ir.BitCast<IR::F32>(ir.GetVccHi());
|
||||||
} else {
|
} else {
|
||||||
value = ir.GetVccHi();
|
value = ir.GetVccHi();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OperandField::M0:
|
case OperandField::M0:
|
||||||
|
if constexpr (is_float) {
|
||||||
|
UNREACHABLE();
|
||||||
|
} else {
|
||||||
return m0_value;
|
return m0_value;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_float) {
|
if constexpr (is_float) {
|
||||||
|
if (operand.input_modifier.abs) {
|
||||||
|
value = ir.FPAbs(value);
|
||||||
|
}
|
||||||
|
if (operand.input_modifier.neg) {
|
||||||
|
value = ir.FPNeg(value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (operand.input_modifier.abs) {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
if (operand.input_modifier.neg) {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template IR::U32 Translator::GetSrc<IR::U32>(const InstOperand&);
|
||||||
|
template IR::F32 Translator::GetSrc<IR::F32>(const InstOperand&);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T Translator::GetSrc64(const InstOperand& operand) {
|
||||||
|
constexpr bool is_float = std::is_same_v<T, IR::F64>;
|
||||||
|
|
||||||
|
const auto get_imm = [&](auto value) -> T {
|
||||||
|
if constexpr (is_float) {
|
||||||
|
return ir.Imm64(std::bit_cast<double>(value));
|
||||||
|
} else {
|
||||||
|
return ir.Imm64(std::bit_cast<u64>(value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
T value{};
|
||||||
|
switch (operand.field) {
|
||||||
|
case OperandField::ScalarGPR: {
|
||||||
|
const auto value_lo = ir.GetScalarReg(IR::ScalarReg(operand.code));
|
||||||
|
const auto value_hi = ir.GetScalarReg(IR::ScalarReg(operand.code + 1));
|
||||||
|
if constexpr (is_float) {
|
||||||
|
UNREACHABLE();
|
||||||
|
} else {
|
||||||
|
value = ir.PackUint2x32(ir.CompositeConstruct(value_lo, value_hi));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OperandField::VectorGPR: {
|
||||||
|
const auto value_lo = ir.GetVectorReg(IR::VectorReg(operand.code));
|
||||||
|
const auto value_hi = ir.GetVectorReg(IR::VectorReg(operand.code + 1));
|
||||||
|
if constexpr (is_float) {
|
||||||
|
UNREACHABLE();
|
||||||
|
} else {
|
||||||
|
value = ir.PackUint2x32(ir.CompositeConstruct(value_lo, value_hi));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OperandField::ConstZero:
|
||||||
|
value = get_imm(0ULL);
|
||||||
|
break;
|
||||||
|
case OperandField::SignedConstIntPos:
|
||||||
|
value = get_imm(s64(operand.code) - SignedConstIntPosMin + 1);
|
||||||
|
break;
|
||||||
|
case OperandField::SignedConstIntNeg:
|
||||||
|
value = get_imm(-s64(operand.code) + SignedConstIntNegMin - 1);
|
||||||
|
break;
|
||||||
|
case OperandField::LiteralConst:
|
||||||
|
value = get_imm(u64(operand.code));
|
||||||
|
break;
|
||||||
|
case OperandField::ConstFloatPos_1_0:
|
||||||
|
value = get_imm(1.0);
|
||||||
|
break;
|
||||||
|
case OperandField::ConstFloatPos_0_5:
|
||||||
|
value = get_imm(0.5);
|
||||||
|
break;
|
||||||
|
case OperandField::ConstFloatPos_2_0:
|
||||||
|
value = get_imm(2.0);
|
||||||
|
break;
|
||||||
|
case OperandField::ConstFloatPos_4_0:
|
||||||
|
value = get_imm(4.0);
|
||||||
|
break;
|
||||||
|
case OperandField::ConstFloatNeg_0_5:
|
||||||
|
value = get_imm(-0.5);
|
||||||
|
break;
|
||||||
|
case OperandField::ConstFloatNeg_1_0:
|
||||||
|
value = get_imm(-1.0);
|
||||||
|
break;
|
||||||
|
case OperandField::ConstFloatNeg_2_0:
|
||||||
|
value = get_imm(-2.0);
|
||||||
|
break;
|
||||||
|
case OperandField::ConstFloatNeg_4_0:
|
||||||
|
value = get_imm(-4.0);
|
||||||
|
break;
|
||||||
|
case OperandField::VccLo:
|
||||||
|
if constexpr (is_float) {
|
||||||
|
UNREACHABLE();
|
||||||
|
} else {
|
||||||
|
value = ir.PackUint2x32(ir.CompositeConstruct(ir.GetVccLo(), ir.GetVccHi()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OperandField::VccHi:
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (is_float) {
|
||||||
if (operand.input_modifier.abs) {
|
if (operand.input_modifier.abs) {
|
||||||
value = ir.FPAbs(value);
|
value = ir.FPAbs(value);
|
||||||
}
|
}
|
||||||
|
@ -178,148 +267,8 @@ IR::U32F32 Translator::GetSrc(const InstOperand& operand, bool force_flt) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template IR::U64 Translator::GetSrc64<IR::U64>(const InstOperand&);
|
||||||
IR::U32 Translator::GetSrc(const InstOperand& operand, bool force_flt) {
|
template IR::F64 Translator::GetSrc64<IR::F64>(const InstOperand&);
|
||||||
return GetSrc<IR::U32F32>(operand, force_flt);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
IR::F32 Translator::GetSrc(const InstOperand& operand, bool) {
|
|
||||||
return GetSrc<IR::U32F32>(operand, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
IR::U64F64 Translator::GetSrc64(const InstOperand& operand, bool force_flt) {
|
|
||||||
IR::Value value_hi{};
|
|
||||||
IR::Value value_lo{};
|
|
||||||
|
|
||||||
bool immediate = false;
|
|
||||||
const bool is_float = operand.type == ScalarType::Float64 || force_flt;
|
|
||||||
switch (operand.field) {
|
|
||||||
case OperandField::ScalarGPR:
|
|
||||||
if (is_float) {
|
|
||||||
value_lo = ir.GetScalarReg<IR::F32>(IR::ScalarReg(operand.code));
|
|
||||||
value_hi = ir.GetScalarReg<IR::F32>(IR::ScalarReg(operand.code + 1));
|
|
||||||
} else if (operand.type == ScalarType::Uint64 || operand.type == ScalarType::Sint64) {
|
|
||||||
value_lo = ir.GetScalarReg<IR::U32>(IR::ScalarReg(operand.code));
|
|
||||||
value_hi = ir.GetScalarReg<IR::U32>(IR::ScalarReg(operand.code + 1));
|
|
||||||
} else {
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OperandField::VectorGPR:
|
|
||||||
if (is_float) {
|
|
||||||
value_lo = ir.GetVectorReg<IR::F32>(IR::VectorReg(operand.code));
|
|
||||||
value_hi = ir.GetVectorReg<IR::F32>(IR::VectorReg(operand.code + 1));
|
|
||||||
} else if (operand.type == ScalarType::Uint64 || operand.type == ScalarType::Sint64) {
|
|
||||||
value_lo = ir.GetVectorReg<IR::U32>(IR::VectorReg(operand.code));
|
|
||||||
value_hi = ir.GetVectorReg<IR::U32>(IR::VectorReg(operand.code + 1));
|
|
||||||
} else {
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OperandField::ConstZero:
|
|
||||||
immediate = true;
|
|
||||||
if (force_flt) {
|
|
||||||
value_lo = ir.Imm64(0.0);
|
|
||||||
} else {
|
|
||||||
value_lo = ir.Imm64(u64(0U));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OperandField::SignedConstIntPos:
|
|
||||||
ASSERT(!force_flt);
|
|
||||||
immediate = true;
|
|
||||||
value_lo = ir.Imm64(s64(operand.code) - SignedConstIntPosMin + 1);
|
|
||||||
break;
|
|
||||||
case OperandField::SignedConstIntNeg:
|
|
||||||
ASSERT(!force_flt);
|
|
||||||
immediate = true;
|
|
||||||
value_lo = ir.Imm64(-s64(operand.code) + SignedConstIntNegMin - 1);
|
|
||||||
break;
|
|
||||||
case OperandField::LiteralConst:
|
|
||||||
immediate = true;
|
|
||||||
if (force_flt) {
|
|
||||||
UNREACHABLE(); // There is a literal double?
|
|
||||||
} else {
|
|
||||||
value_lo = ir.Imm64(u64(operand.code));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OperandField::ConstFloatPos_1_0:
|
|
||||||
immediate = true;
|
|
||||||
if (force_flt) {
|
|
||||||
value_lo = ir.Imm64(1.0);
|
|
||||||
} else {
|
|
||||||
value_lo = ir.Imm64(std::bit_cast<u64>(f64(1.0)));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OperandField::ConstFloatPos_0_5:
|
|
||||||
immediate = true;
|
|
||||||
value_lo = ir.Imm64(0.5);
|
|
||||||
break;
|
|
||||||
case OperandField::ConstFloatPos_2_0:
|
|
||||||
immediate = true;
|
|
||||||
value_lo = ir.Imm64(2.0);
|
|
||||||
break;
|
|
||||||
case OperandField::ConstFloatPos_4_0:
|
|
||||||
immediate = true;
|
|
||||||
value_lo = ir.Imm64(4.0);
|
|
||||||
break;
|
|
||||||
case OperandField::ConstFloatNeg_0_5:
|
|
||||||
immediate = true;
|
|
||||||
value_lo = ir.Imm64(-0.5);
|
|
||||||
break;
|
|
||||||
case OperandField::ConstFloatNeg_1_0:
|
|
||||||
immediate = true;
|
|
||||||
value_lo = ir.Imm64(-1.0);
|
|
||||||
break;
|
|
||||||
case OperandField::ConstFloatNeg_2_0:
|
|
||||||
immediate = true;
|
|
||||||
value_lo = ir.Imm64(-2.0);
|
|
||||||
break;
|
|
||||||
case OperandField::ConstFloatNeg_4_0:
|
|
||||||
immediate = true;
|
|
||||||
value_lo = ir.Imm64(-4.0);
|
|
||||||
break;
|
|
||||||
case OperandField::VccLo: {
|
|
||||||
value_lo = ir.GetVccLo();
|
|
||||||
value_hi = ir.GetVccHi();
|
|
||||||
} break;
|
|
||||||
case OperandField::VccHi:
|
|
||||||
UNREACHABLE();
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
IR::Value value;
|
|
||||||
|
|
||||||
if (immediate) {
|
|
||||||
value = value_lo;
|
|
||||||
} else if (is_float) {
|
|
||||||
throw NotImplementedException("required OpPackDouble2x32 implementation");
|
|
||||||
} else {
|
|
||||||
IR::Value packed = ir.CompositeConstruct(value_lo, value_hi);
|
|
||||||
value = ir.PackUint2x32(packed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_float) {
|
|
||||||
if (operand.input_modifier.abs) {
|
|
||||||
value = ir.FPAbs(IR::F32F64(value));
|
|
||||||
}
|
|
||||||
if (operand.input_modifier.neg) {
|
|
||||||
value = ir.FPNeg(IR::F32F64(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return IR::U64F64(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
IR::U64 Translator::GetSrc64(const InstOperand& operand, bool force_flt) {
|
|
||||||
return GetSrc64<IR::U64F64>(operand, force_flt);
|
|
||||||
}
|
|
||||||
template <>
|
|
||||||
IR::F64 Translator::GetSrc64(const InstOperand& operand, bool) {
|
|
||||||
return GetSrc64<IR::U64F64>(operand, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Translator::SetDst(const InstOperand& operand, const IR::U32F32& value) {
|
void Translator::SetDst(const InstOperand& operand, const IR::U32F32& value) {
|
||||||
IR::U32F32 result = value;
|
IR::U32F32 result = value;
|
||||||
|
|
|
@ -211,10 +211,10 @@ public:
|
||||||
void IMAGE_ATOMIC(AtomicOp op, const GcnInst& inst);
|
void IMAGE_ATOMIC(AtomicOp op, const GcnInst& inst);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T = IR::U32F32>
|
template <typename T = IR::U32>
|
||||||
[[nodiscard]] T GetSrc(const InstOperand& operand, bool flt_zero = false);
|
[[nodiscard]] T GetSrc(const InstOperand& operand);
|
||||||
template <typename T = IR::U64F64>
|
template <typename T = IR::U64>
|
||||||
[[nodiscard]] T GetSrc64(const InstOperand& operand, bool flt_zero = false);
|
[[nodiscard]] T GetSrc64(const InstOperand& operand);
|
||||||
void SetDst(const InstOperand& operand, const IR::U32F32& value);
|
void SetDst(const InstOperand& operand, const IR::U32F32& value);
|
||||||
void SetDst64(const InstOperand& operand, const IR::U64F64& value_raw);
|
void SetDst64(const InstOperand& operand, const IR::U64F64& value_raw);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "shader_recompiler/frontend/translate/translate.h"
|
#include "shader_recompiler/frontend/translate/translate.h"
|
||||||
#include "shader_recompiler/profile.h"
|
|
||||||
|
|
||||||
namespace Shader::Gcn {
|
namespace Shader::Gcn {
|
||||||
|
|
||||||
|
@ -312,7 +311,7 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_MOV(const GcnInst& inst) {
|
void Translator::V_MOV(const GcnInst& inst) {
|
||||||
SetDst(inst.dst[0], GetSrc(inst.src[0]));
|
SetDst(inst.dst[0], GetSrc<IR::F32>(inst.src[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_SAD(const GcnInst& inst) {
|
void Translator::V_SAD(const GcnInst& inst) {
|
||||||
|
@ -321,14 +320,14 @@ void Translator::V_SAD(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_MAC_F32(const GcnInst& inst) {
|
void Translator::V_MAC_F32(const GcnInst& inst) {
|
||||||
SetDst(inst.dst[0], ir.FPFma(GetSrc(inst.src[0], true), GetSrc(inst.src[1], true),
|
SetDst(inst.dst[0], ir.FPFma(GetSrc<IR::F32>(inst.src[0]), GetSrc<IR::F32>(inst.src[1]),
|
||||||
GetSrc(inst.dst[0], true)));
|
GetSrc<IR::F32>(inst.dst[0])));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_CVT_PKRTZ_F16_F32(const GcnInst& inst) {
|
void Translator::V_CVT_PKRTZ_F16_F32(const GcnInst& inst) {
|
||||||
const IR::VectorReg dst_reg{inst.dst[0].code};
|
const IR::VectorReg dst_reg{inst.dst[0].code};
|
||||||
const IR::Value vec_f32 =
|
const IR::Value vec_f32 =
|
||||||
ir.CompositeConstruct(GetSrc(inst.src[0], true), GetSrc(inst.src[1], true));
|
ir.CompositeConstruct(GetSrc<IR::F32>(inst.src[0]), GetSrc<IR::F32>(inst.src[1]));
|
||||||
ir.SetVectorReg(dst_reg, ir.PackHalf2x16(vec_f32));
|
ir.SetVectorReg(dst_reg, ir.PackHalf2x16(vec_f32));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,13 +338,13 @@ void Translator::V_CVT_F32_F16(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_CVT_F16_F32(const GcnInst& inst) {
|
void Translator::V_CVT_F16_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0 = GetSrc(inst.src[0], true);
|
const IR::F32 src0 = GetSrc<IR::F32>(inst.src[0]);
|
||||||
const IR::F16 src0fp16 = ir.FPConvert(16, src0);
|
const IR::F16 src0fp16 = ir.FPConvert(16, src0);
|
||||||
SetDst(inst.dst[0], ir.UConvert(32, ir.BitCast<IR::U16>(src0fp16)));
|
SetDst(inst.dst[0], ir.UConvert(32, ir.BitCast<IR::U16>(src0fp16)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_MUL_F32(const GcnInst& inst) {
|
void Translator::V_MUL_F32(const GcnInst& inst) {
|
||||||
SetDst(inst.dst[0], ir.FPMul(GetSrc(inst.src[0], true), GetSrc(inst.src[1], true)));
|
SetDst(inst.dst[0], ir.FPMul(GetSrc<IR::F32>(inst.src[0]), GetSrc<IR::F32>(inst.src[1])));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_CNDMASK_B32(const GcnInst& inst) {
|
void Translator::V_CNDMASK_B32(const GcnInst& inst) {
|
||||||
|
@ -363,16 +362,13 @@ void Translator::V_CNDMASK_B32(const GcnInst& inst) {
|
||||||
};
|
};
|
||||||
const bool has_flt_source =
|
const bool has_flt_source =
|
||||||
is_float_const(inst.src[0].field) || is_float_const(inst.src[1].field);
|
is_float_const(inst.src[0].field) || is_float_const(inst.src[1].field);
|
||||||
IR::U32F32 src0 = GetSrc(inst.src[0], has_flt_source);
|
if (has_flt_source) {
|
||||||
IR::U32F32 src1 = GetSrc(inst.src[1], has_flt_source);
|
const IR::Value result = ir.Select(flag, GetSrc<IR::F32>(inst.src[1]), GetSrc<IR::F32>(inst.src[0]));
|
||||||
if (src0.Type() == IR::Type::F32 && src1.Type() == IR::Type::U32) {
|
|
||||||
src1 = ir.BitCast<IR::F32, IR::U32>(src1);
|
|
||||||
}
|
|
||||||
if (src1.Type() == IR::Type::F32 && src0.Type() == IR::Type::U32) {
|
|
||||||
src0 = ir.BitCast<IR::F32, IR::U32>(src0);
|
|
||||||
}
|
|
||||||
const IR::Value result = ir.Select(flag, src1, src0);
|
|
||||||
ir.SetVectorReg(dst_reg, IR::U32F32{result});
|
ir.SetVectorReg(dst_reg, IR::U32F32{result});
|
||||||
|
} else {
|
||||||
|
const IR::Value result = ir.Select(flag, GetSrc(inst.src[1]), GetSrc(inst.src[0]));
|
||||||
|
ir.SetVectorReg(dst_reg, IR::U32F32{result});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_OR_B32(bool is_xor, const GcnInst& inst) {
|
void Translator::V_OR_B32(bool is_xor, const GcnInst& inst) {
|
||||||
|
@ -448,21 +444,21 @@ void Translator::V_CVT_F32_U32(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_MAD_F32(const GcnInst& inst) {
|
void Translator::V_MAD_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::F32 src1{GetSrc(inst.src[1], true)};
|
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||||
const IR::F32 src2{GetSrc(inst.src[2], true)};
|
const IR::F32 src2{GetSrc<IR::F32>(inst.src[2])};
|
||||||
SetDst(inst.dst[0], ir.FPFma(src0, src1, src2));
|
SetDst(inst.dst[0], ir.FPFma(src0, src1, src2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_FRACT_F32(const GcnInst& inst) {
|
void Translator::V_FRACT_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::VectorReg dst_reg{inst.dst[0].code};
|
const IR::VectorReg dst_reg{inst.dst[0].code};
|
||||||
ir.SetVectorReg(dst_reg, ir.Fract(src0));
|
ir.SetVectorReg(dst_reg, ir.Fract(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_ADD_F32(const GcnInst& inst) {
|
void Translator::V_ADD_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::F32 src1{GetSrc(inst.src[1], true)};
|
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||||
SetDst(inst.dst[0], ir.FPAdd(src0, src1));
|
SetDst(inst.dst[0], ir.FPAdd(src0, src1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,9 +472,9 @@ void Translator::V_CVT_OFF_F32_I4(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_MED3_F32(const GcnInst& inst) {
|
void Translator::V_MED3_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::F32 src1{GetSrc(inst.src[1], true)};
|
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||||
const IR::F32 src2{GetSrc(inst.src[2], true)};
|
const IR::F32 src2{GetSrc<IR::F32>(inst.src[2])};
|
||||||
const IR::F32 mmx = ir.FPMin(ir.FPMax(src0, src1), src2);
|
const IR::F32 mmx = ir.FPMin(ir.FPMax(src0, src1), src2);
|
||||||
SetDst(inst.dst[0], ir.FPMax(ir.FPMin(src0, src1), mmx));
|
SetDst(inst.dst[0], ir.FPMax(ir.FPMin(src0, src1), mmx));
|
||||||
}
|
}
|
||||||
|
@ -492,32 +488,32 @@ void Translator::V_MED3_I32(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_FLOOR_F32(const GcnInst& inst) {
|
void Translator::V_FLOOR_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::VectorReg dst_reg{inst.dst[0].code};
|
const IR::VectorReg dst_reg{inst.dst[0].code};
|
||||||
ir.SetVectorReg(dst_reg, ir.FPFloor(src0));
|
ir.SetVectorReg(dst_reg, ir.FPFloor(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_SUB_F32(const GcnInst& inst) {
|
void Translator::V_SUB_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::F32 src1{GetSrc(inst.src[1], true)};
|
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||||
SetDst(inst.dst[0], ir.FPSub(src0, src1));
|
SetDst(inst.dst[0], ir.FPSub(src0, src1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_RCP_F32(const GcnInst& inst) {
|
void Translator::V_RCP_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
SetDst(inst.dst[0], ir.FPRecip(src0));
|
SetDst(inst.dst[0], ir.FPRecip(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_FMA_F32(const GcnInst& inst) {
|
void Translator::V_FMA_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::F32 src1{GetSrc(inst.src[1], true)};
|
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||||
const IR::F32 src2{GetSrc(inst.src[2], true)};
|
const IR::F32 src2{GetSrc<IR::F32>(inst.src[2])};
|
||||||
SetDst(inst.dst[0], ir.FPFma(src0, src1, src2));
|
SetDst(inst.dst[0], ir.FPFma(src0, src1, src2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_CMP_F32(ConditionOp op, bool set_exec, const GcnInst& inst) {
|
void Translator::V_CMP_F32(ConditionOp op, bool set_exec, const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::F32 src1{GetSrc(inst.src[1], true)};
|
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||||
const IR::U1 result = [&] {
|
const IR::U1 result = [&] {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case ConditionOp::F:
|
case ConditionOp::F:
|
||||||
|
@ -557,8 +553,8 @@ void Translator::V_CMP_F32(ConditionOp op, bool set_exec, const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_MAX_F32(const GcnInst& inst, bool is_legacy) {
|
void Translator::V_MAX_F32(const GcnInst& inst, bool is_legacy) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::F32 src1{GetSrc(inst.src[1], true)};
|
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||||
SetDst(inst.dst[0], ir.FPMax(src0, src1, is_legacy));
|
SetDst(inst.dst[0], ir.FPMax(src0, src1, is_legacy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,40 +565,40 @@ void Translator::V_MAX_U32(bool is_signed, const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_RSQ_F32(const GcnInst& inst) {
|
void Translator::V_RSQ_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
SetDst(inst.dst[0], ir.FPRecipSqrt(src0));
|
SetDst(inst.dst[0], ir.FPRecipSqrt(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_SIN_F32(const GcnInst& inst) {
|
void Translator::V_SIN_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
SetDst(inst.dst[0], ir.FPSin(src0));
|
SetDst(inst.dst[0], ir.FPSin(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_LOG_F32(const GcnInst& inst) {
|
void Translator::V_LOG_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
SetDst(inst.dst[0], ir.FPLog2(src0));
|
SetDst(inst.dst[0], ir.FPLog2(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_EXP_F32(const GcnInst& inst) {
|
void Translator::V_EXP_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
SetDst(inst.dst[0], ir.FPExp2(src0));
|
SetDst(inst.dst[0], ir.FPExp2(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_SQRT_F32(const GcnInst& inst) {
|
void Translator::V_SQRT_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
SetDst(inst.dst[0], ir.FPSqrt(src0));
|
SetDst(inst.dst[0], ir.FPSqrt(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_MIN_F32(const GcnInst& inst, bool is_legacy) {
|
void Translator::V_MIN_F32(const GcnInst& inst, bool is_legacy) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::F32 src1{GetSrc(inst.src[1], true)};
|
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||||
SetDst(inst.dst[0], ir.FPMin(src0, src1, is_legacy));
|
SetDst(inst.dst[0], ir.FPMin(src0, src1, is_legacy));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_MIN3_F32(const GcnInst& inst) {
|
void Translator::V_MIN3_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::F32 src1{GetSrc(inst.src[1], true)};
|
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||||
const IR::F32 src2{GetSrc(inst.src[2], true)};
|
const IR::F32 src2{GetSrc<IR::F32>(inst.src[2])};
|
||||||
SetDst(inst.dst[0], ir.FPMin(src0, ir.FPMin(src1, src2)));
|
SetDst(inst.dst[0], ir.FPMin(src0, ir.FPMin(src1, src2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,9 +610,9 @@ void Translator::V_MIN3_I32(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_MADMK_F32(const GcnInst& inst) {
|
void Translator::V_MADMK_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::F32 src1{GetSrc(inst.src[1], true)};
|
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||||
const IR::F32 k{GetSrc(inst.src[2], true)};
|
const IR::F32 k{GetSrc<IR::F32>(inst.src[2])};
|
||||||
SetDst(inst.dst[0], ir.FPFma(src0, k, src1));
|
SetDst(inst.dst[0], ir.FPFma(src0, k, src1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,25 +621,25 @@ void Translator::V_CUBEMA_F32(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_CUBESC_F32(const GcnInst& inst) {
|
void Translator::V_CUBESC_F32(const GcnInst& inst) {
|
||||||
SetDst(inst.dst[0], GetSrc(inst.src[0], true));
|
SetDst(inst.dst[0], GetSrc<IR::F32>(inst.src[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_CUBETC_F32(const GcnInst& inst) {
|
void Translator::V_CUBETC_F32(const GcnInst& inst) {
|
||||||
SetDst(inst.dst[0], GetSrc(inst.src[1], true));
|
SetDst(inst.dst[0], GetSrc<IR::F32>(inst.src[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_CUBEID_F32(const GcnInst& inst) {
|
void Translator::V_CUBEID_F32(const GcnInst& inst) {
|
||||||
SetDst(inst.dst[0], GetSrc(inst.src[2], true));
|
SetDst(inst.dst[0], GetSrc<IR::F32>(inst.src[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_CVT_U32_F32(const GcnInst& inst) {
|
void Translator::V_CVT_U32_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
SetDst(inst.dst[0], ir.ConvertFToU(32, src0));
|
SetDst(inst.dst[0], ir.ConvertFToU(32, src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_SUBREV_F32(const GcnInst& inst) {
|
void Translator::V_SUBREV_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::F32 src1{GetSrc(inst.src[1], true)};
|
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||||
SetDst(inst.dst[0], ir.FPSub(src1, src0));
|
SetDst(inst.dst[0], ir.FPSub(src1, src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,7 +779,7 @@ void Translator::V_MAD_U32_U24(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_RNDNE_F32(const GcnInst& inst) {
|
void Translator::V_RNDNE_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
SetDst(inst.dst[0], ir.FPRoundEven(src0));
|
SetDst(inst.dst[0], ir.FPRoundEven(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,14 +790,14 @@ void Translator::V_BCNT_U32_B32(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_COS_F32(const GcnInst& inst) {
|
void Translator::V_COS_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
SetDst(inst.dst[0], ir.FPCos(src0));
|
SetDst(inst.dst[0], ir.FPCos(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_MAX3_F32(const GcnInst& inst) {
|
void Translator::V_MAX3_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::F32 src1{GetSrc(inst.src[1], true)};
|
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||||
const IR::F32 src2{GetSrc(inst.src[2], true)};
|
const IR::F32 src2{GetSrc<IR::F32>(inst.src[2])};
|
||||||
SetDst(inst.dst[0], ir.FPMax(src0, ir.FPMax(src1, src2)));
|
SetDst(inst.dst[0], ir.FPMax(src0, ir.FPMax(src1, src2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,7 +809,7 @@ void Translator::V_MAX3_U32(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_CVT_I32_F32(const GcnInst& inst) {
|
void Translator::V_CVT_I32_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
SetDst(inst.dst[0], ir.ConvertFToS(32, src0));
|
SetDst(inst.dst[0], ir.ConvertFToS(32, src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,12 +826,12 @@ void Translator::V_MUL_LO_U32(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_TRUNC_F32(const GcnInst& inst) {
|
void Translator::V_TRUNC_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
SetDst(inst.dst[0], ir.FPTrunc(src0));
|
SetDst(inst.dst[0], ir.FPTrunc(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_CEIL_F32(const GcnInst& inst) {
|
void Translator::V_CEIL_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
SetDst(inst.dst[0], ir.FPCeil(src0));
|
SetDst(inst.dst[0], ir.FPCeil(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -899,18 +895,18 @@ void Translator::V_BFREV_B32(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_LDEXP_F32(const GcnInst& inst) {
|
void Translator::V_LDEXP_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::U32 src1{GetSrc(inst.src[1])};
|
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||||
SetDst(inst.dst[0], ir.FPLdexp(src0, src1));
|
SetDst(inst.dst[0], ir.FPLdexp(src0, src1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_CVT_FLR_I32_F32(const GcnInst& inst) {
|
void Translator::V_CVT_FLR_I32_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
SetDst(inst.dst[0], ir.ConvertFToI(32, true, ir.FPFloor(src0)));
|
SetDst(inst.dst[0], ir.ConvertFToI(32, true, ir.FPFloor(src0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_CMP_CLASS_F32(const GcnInst& inst) {
|
void Translator::V_CMP_CLASS_F32(const GcnInst& inst) {
|
||||||
const IR::F32F64 src0{GetSrc(inst.src[0])};
|
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||||
const IR::U32 src1{GetSrc(inst.src[1])};
|
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||||
IR::U1 value;
|
IR::U1 value;
|
||||||
if (src1.IsImmediate()) {
|
if (src1.IsImmediate()) {
|
||||||
|
|
|
@ -209,6 +209,10 @@ void PipelineCache::RefreshGraphicsKey() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto* bininfo = Liverpool::GetBinaryInfo(*pgm);
|
const auto* bininfo = Liverpool::GetBinaryInfo(*pgm);
|
||||||
|
if (!bininfo->Valid()) {
|
||||||
|
key.stage_hashes[i] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
key.stage_hashes[i] = bininfo->shader_hash;
|
key.stage_hashes[i] = bininfo->shader_hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue