shader: Rename, implement FADD.SAT and P2R (imm)
This commit is contained in:
parent
e2bc05b17d
commit
704c6f353f
18 changed files with 213 additions and 127 deletions
|
@ -468,11 +468,11 @@ F16F32F64 IREmitter::FPFma(const F16F32F64& a, const F16F32F64& b, const F16F32F
|
|||
|
||||
F16F32F64 IREmitter::FPAbs(const F16F32F64& value) {
|
||||
switch (value.Type()) {
|
||||
case Type::U16:
|
||||
case Type::F16:
|
||||
return Inst<F16>(Opcode::FPAbs16, value);
|
||||
case Type::U32:
|
||||
case Type::F32:
|
||||
return Inst<F32>(Opcode::FPAbs32, value);
|
||||
case Type::U64:
|
||||
case Type::F64:
|
||||
return Inst<F64>(Opcode::FPAbs64, value);
|
||||
default:
|
||||
ThrowInvalidType(value.Type());
|
||||
|
@ -481,11 +481,11 @@ F16F32F64 IREmitter::FPAbs(const F16F32F64& value) {
|
|||
|
||||
F16F32F64 IREmitter::FPNeg(const F16F32F64& value) {
|
||||
switch (value.Type()) {
|
||||
case Type::U16:
|
||||
case Type::F16:
|
||||
return Inst<F16>(Opcode::FPNeg16, value);
|
||||
case Type::U32:
|
||||
case Type::F32:
|
||||
return Inst<F32>(Opcode::FPNeg32, value);
|
||||
case Type::U64:
|
||||
case Type::F64:
|
||||
return Inst<F64>(Opcode::FPNeg64, value);
|
||||
default:
|
||||
ThrowInvalidType(value.Type());
|
||||
|
@ -495,10 +495,10 @@ F16F32F64 IREmitter::FPNeg(const F16F32F64& value) {
|
|||
F16F32F64 IREmitter::FPAbsNeg(const F16F32F64& value, bool abs, bool neg) {
|
||||
F16F32F64 result{value};
|
||||
if (abs) {
|
||||
result = FPAbs(value);
|
||||
result = FPAbs(result);
|
||||
}
|
||||
if (neg) {
|
||||
result = FPNeg(value);
|
||||
result = FPNeg(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ enum class Pred : u64 {
|
|||
PT,
|
||||
};
|
||||
|
||||
constexpr size_t NUM_USER_PREDS = 6;
|
||||
constexpr size_t NUM_PREDS = 7;
|
||||
constexpr size_t NUM_USER_PREDS = 7;
|
||||
constexpr size_t NUM_PREDS = 8;
|
||||
|
||||
[[nodiscard]] constexpr size_t PredIndex(Pred pred) noexcept {
|
||||
return static_cast<size_t>(pred);
|
||||
|
|
|
@ -56,12 +56,12 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo
|
|||
.post_order_blocks{},
|
||||
});
|
||||
}
|
||||
fmt::print(stdout, "{}\n", IR::DumpProgram(program));
|
||||
Optimization::LowerFp16ToFp32(program);
|
||||
for (IR::Function& function : functions) {
|
||||
function.post_order_blocks = PostOrder(function.blocks);
|
||||
Optimization::SsaRewritePass(function.post_order_blocks);
|
||||
}
|
||||
fmt::print(stdout, "{}\n", IR::DumpProgram(program));
|
||||
Optimization::GlobalMemoryToStorageBufferPass(program);
|
||||
for (IR::Function& function : functions) {
|
||||
Optimization::PostOrderInvoke(Optimization::ConstantPropagationPass, function);
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
namespace Shader::Maxwell {
|
||||
namespace {
|
||||
|
||||
void FADD(TranslatorVisitor& v, u64 insn, bool sat, bool cc, bool ftz, FpRounding fp_rounding,
|
||||
const IR::F32& src_b, bool abs_a, bool neg_a, bool abs_b, bool neg_b) {
|
||||
union {
|
||||
|
@ -18,9 +17,6 @@ void FADD(TranslatorVisitor& v, u64 insn, bool sat, bool cc, bool ftz, FpRoundin
|
|||
BitField<8, 8, IR::Reg> src_a;
|
||||
} const fadd{insn};
|
||||
|
||||
if (sat) {
|
||||
throw NotImplementedException("FADD SAT");
|
||||
}
|
||||
if (cc) {
|
||||
throw NotImplementedException("FADD CC");
|
||||
}
|
||||
|
@ -31,7 +27,11 @@ void FADD(TranslatorVisitor& v, u64 insn, bool sat, bool cc, bool ftz, FpRoundin
|
|||
.rounding{CastFpRounding(fp_rounding)},
|
||||
.fmz_mode{ftz ? IR::FmzMode::FTZ : IR::FmzMode::None},
|
||||
};
|
||||
v.F(fadd.dest_reg, v.ir.FPAdd(op_a, op_b, control));
|
||||
IR::F32 value{v.ir.FPAdd(op_a, op_b, control)};
|
||||
if (sat) {
|
||||
value = v.ir.FPSaturate(value);
|
||||
}
|
||||
v.F(fadd.dest_reg, value);
|
||||
}
|
||||
|
||||
void FADD(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
|
||||
|
@ -53,15 +53,15 @@ void FADD(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
|
|||
} // Anonymous namespace
|
||||
|
||||
void TranslatorVisitor::FADD_reg(u64 insn) {
|
||||
FADD(*this, insn, GetReg20F(insn));
|
||||
FADD(*this, insn, GetRegFloat20(insn));
|
||||
}
|
||||
|
||||
void TranslatorVisitor::FADD_cbuf(u64) {
|
||||
throw NotImplementedException("FADD (cbuf)");
|
||||
void TranslatorVisitor::FADD_cbuf(u64 insn) {
|
||||
FADD(*this, insn, GetFloatCbuf(insn));
|
||||
}
|
||||
|
||||
void TranslatorVisitor::FADD_imm(u64) {
|
||||
throw NotImplementedException("FADD (imm)");
|
||||
void TranslatorVisitor::FADD_imm(u64 insn) {
|
||||
FADD(*this, insn, GetFloatImm20(insn));
|
||||
}
|
||||
|
||||
void TranslatorVisitor::FADD32I(u64) {
|
||||
|
|
|
@ -158,7 +158,7 @@ void TranslatorVisitor::F2I_cbuf(u64 insn) {
|
|||
case SrcFormat::F16:
|
||||
return IR::F16{ir.CompositeExtract(ir.UnpackFloat2x16(GetCbuf(insn)), f2i.half)};
|
||||
case SrcFormat::F32:
|
||||
return GetCbufF(insn);
|
||||
return GetFloatCbuf(insn);
|
||||
case SrcFormat::F64: {
|
||||
return UnpackCbuf(*this, insn);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ void FFMA(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, const IR::F32& s
|
|||
} // Anonymous namespace
|
||||
|
||||
void TranslatorVisitor::FFMA_reg(u64 insn) {
|
||||
FFMA(*this, insn, GetReg20F(insn), GetReg39F(insn));
|
||||
FFMA(*this, insn, GetRegFloat20(insn), GetRegFloat39(insn));
|
||||
}
|
||||
|
||||
void TranslatorVisitor::FFMA_rc(u64) {
|
||||
|
@ -59,7 +59,7 @@ void TranslatorVisitor::FFMA_rc(u64) {
|
|||
}
|
||||
|
||||
void TranslatorVisitor::FFMA_cr(u64 insn) {
|
||||
FFMA(*this, insn, GetCbufF(insn), GetReg39F(insn));
|
||||
FFMA(*this, insn, GetFloatCbuf(insn), GetRegFloat39(insn));
|
||||
}
|
||||
|
||||
void TranslatorVisitor::FFMA_imm(u64) {
|
||||
|
|
|
@ -91,7 +91,7 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
|
|||
} // Anonymous namespace
|
||||
|
||||
void TranslatorVisitor::FMUL_reg(u64 insn) {
|
||||
return FMUL(*this, insn, GetReg20F(insn));
|
||||
return FMUL(*this, insn, GetRegFloat20(insn));
|
||||
}
|
||||
|
||||
void TranslatorVisitor::FMUL_cbuf(u64) {
|
||||
|
|
|
@ -48,11 +48,11 @@ IR::U32 TranslatorVisitor::GetReg39(u64 insn) {
|
|||
return X(reg.index);
|
||||
}
|
||||
|
||||
IR::F32 TranslatorVisitor::GetReg20F(u64 insn) {
|
||||
IR::F32 TranslatorVisitor::GetRegFloat20(u64 insn) {
|
||||
return ir.BitCast<IR::F32>(GetReg20(insn));
|
||||
}
|
||||
|
||||
IR::F32 TranslatorVisitor::GetReg39F(u64 insn) {
|
||||
IR::F32 TranslatorVisitor::GetRegFloat39(u64 insn) {
|
||||
return ir.BitCast<IR::F32>(GetReg39(insn));
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ IR::U32 TranslatorVisitor::GetCbuf(u64 insn) {
|
|||
return ir.GetCbuf(binding, byte_offset);
|
||||
}
|
||||
|
||||
IR::F32 TranslatorVisitor::GetCbufF(u64 insn) {
|
||||
IR::F32 TranslatorVisitor::GetFloatCbuf(u64 insn) {
|
||||
return ir.BitCast<IR::F32>(GetCbuf(insn));
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,17 @@ IR::U32 TranslatorVisitor::GetImm20(u64 insn) {
|
|||
return ir.Imm32(value);
|
||||
}
|
||||
|
||||
IR::F32 TranslatorVisitor::GetFloatImm20(u64 insn) {
|
||||
union {
|
||||
u64 raw;
|
||||
BitField<20, 19, u64> value;
|
||||
BitField<56, 1, u64> is_negative;
|
||||
} const imm{insn};
|
||||
const f32 positive_value{Common::BitCast<f32>(static_cast<u32>(imm.value) << 12)};
|
||||
const f32 value{imm.is_negative != 0 ? -positive_value : positive_value};
|
||||
return ir.Imm32(value);
|
||||
}
|
||||
|
||||
IR::U32 TranslatorVisitor::GetImm32(u64 insn) {
|
||||
union {
|
||||
u64 raw;
|
||||
|
|
|
@ -304,13 +304,14 @@ public:
|
|||
[[nodiscard]] IR::U32 GetReg8(u64 insn);
|
||||
[[nodiscard]] IR::U32 GetReg20(u64 insn);
|
||||
[[nodiscard]] IR::U32 GetReg39(u64 insn);
|
||||
[[nodiscard]] IR::F32 GetReg20F(u64 insn);
|
||||
[[nodiscard]] IR::F32 GetReg39F(u64 insn);
|
||||
[[nodiscard]] IR::F32 GetRegFloat20(u64 insn);
|
||||
[[nodiscard]] IR::F32 GetRegFloat39(u64 insn);
|
||||
|
||||
[[nodiscard]] IR::U32 GetCbuf(u64 insn);
|
||||
[[nodiscard]] IR::F32 GetCbufF(u64 insn);
|
||||
[[nodiscard]] IR::F32 GetFloatCbuf(u64 insn);
|
||||
|
||||
[[nodiscard]] IR::U32 GetImm20(u64 insn);
|
||||
[[nodiscard]] IR::F32 GetFloatImm20(u64 insn);
|
||||
|
||||
[[nodiscard]] IR::U32 GetImm32(u64 insn);
|
||||
|
||||
|
|
|
@ -84,8 +84,8 @@ void TranslatorVisitor::IADD_cbuf(u64 insn) {
|
|||
IADD(*this, insn, GetCbuf(insn));
|
||||
}
|
||||
|
||||
void TranslatorVisitor::IADD_imm(u64) {
|
||||
throw NotImplementedException("IADD (imm)");
|
||||
void TranslatorVisitor::IADD_imm(u64 insn) {
|
||||
IADD(*this, insn, GetImm20(insn));
|
||||
}
|
||||
|
||||
void TranslatorVisitor::IADD32I(u64 insn) {
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/bit_field.h"
|
||||
#include "shader_recompiler/exception.h"
|
||||
#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
|
||||
|
||||
namespace Shader::Maxwell {
|
||||
namespace {
|
||||
enum class Mode : u64 {
|
||||
PR,
|
||||
CC,
|
||||
};
|
||||
} // Anonymous namespace
|
||||
|
||||
void TranslatorVisitor::P2R_reg(u64) {
|
||||
throw NotImplementedException("P2R (reg)");
|
||||
}
|
||||
|
||||
void TranslatorVisitor::P2R_cbuf(u64) {
|
||||
throw NotImplementedException("P2R (cbuf)");
|
||||
}
|
||||
|
||||
void TranslatorVisitor::P2R_imm(u64 insn) {
|
||||
union {
|
||||
u64 raw;
|
||||
BitField<0, 8, IR::Reg> dest_reg;
|
||||
BitField<8, 8, IR::Reg> src;
|
||||
BitField<40, 1, Mode> mode;
|
||||
BitField<41, 2, u64> byte_selector;
|
||||
} const p2r{insn};
|
||||
|
||||
const u32 mask{GetImm20(insn).U32()};
|
||||
const bool pr_mode{p2r.mode == Mode::PR};
|
||||
const u32 num_items{pr_mode ? 7U : 4U};
|
||||
const u32 offset{static_cast<u32>(p2r.byte_selector) * 8};
|
||||
IR::U32 insert{ir.Imm32(0)};
|
||||
for (u32 index = 0; index < num_items; ++index) {
|
||||
if (((mask >> index) & 1) == 0) {
|
||||
continue;
|
||||
}
|
||||
const IR::U1 cond{[this, index, pr_mode] {
|
||||
if (pr_mode) {
|
||||
return ir.GetPred(IR::Pred{index});
|
||||
}
|
||||
switch (index) {
|
||||
case 0:
|
||||
return ir.GetZFlag();
|
||||
case 1:
|
||||
return ir.GetSFlag();
|
||||
case 2:
|
||||
return ir.GetCFlag();
|
||||
case 3:
|
||||
return ir.GetOFlag();
|
||||
}
|
||||
throw LogicError("Unreachable P2R index");
|
||||
}()};
|
||||
const IR::U32 bit{ir.Select(cond, ir.Imm32(1U << (index + offset)), ir.Imm32(0))};
|
||||
insert = ir.BitwiseOr(insert, bit);
|
||||
}
|
||||
const IR::U32 masked_out{ir.BitwiseAnd(X(p2r.src), ir.Imm32(~(mask << offset)))};
|
||||
X(p2r.dest_reg, ir.BitwiseOr(masked_out, insert));
|
||||
}
|
||||
|
||||
} // namespace Shader::Maxwell
|
|
@ -633,18 +633,6 @@ void TranslatorVisitor::OUT_imm(u64) {
|
|||
ThrowNotImplemented(Opcode::OUT_imm);
|
||||
}
|
||||
|
||||
void TranslatorVisitor::P2R_reg(u64) {
|
||||
ThrowNotImplemented(Opcode::P2R_reg);
|
||||
}
|
||||
|
||||
void TranslatorVisitor::P2R_cbuf(u64) {
|
||||
ThrowNotImplemented(Opcode::P2R_cbuf);
|
||||
}
|
||||
|
||||
void TranslatorVisitor::P2R_imm(u64) {
|
||||
ThrowNotImplemented(Opcode::P2R_imm);
|
||||
}
|
||||
|
||||
void TranslatorVisitor::PBK() {
|
||||
// PBK is a no-op
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue