summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/frontend/maxwell/translate/impl
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/translate/impl')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp20
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp4
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp17
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.h7
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp4
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/move_predicate_to_register.cpp66
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp12
9 files changed, 100 insertions, 34 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp
index cb3a326cf..219ffcc6a 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp
@@ -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) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp
index 4d82a0009..81175627f 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp
@@ -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);
}
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp
index 1464f2807..758700d3c 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp
@@ -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) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp
index 1b1d38be7..5c38d3fc1 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp
@@ -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) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
index 079e3497f..be17bb0d9 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
@@ -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;
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
index 27aba2cf8..4d4cf2ebf 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
@@ -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);
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp
index 623e78ff8..1493e1815 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp
@@ -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) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/move_predicate_to_register.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/move_predicate_to_register.cpp
new file mode 100644
index 000000000..4324fd443
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/move_predicate_to_register.cpp
@@ -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
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
index 6b2a1356b..628cf1c14 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -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
}