summaryrefslogtreecommitdiff
path: root/src/shader_recompiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler')
-rw-r--r--src/shader_recompiler/CMakeLists.txt1
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h5
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp12
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp4
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h1
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc1
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_right.cpp62
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp12
8 files changed, 80 insertions, 18 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt
index 17ccb3d98..14dc51b5f 100644
--- a/src/shader_recompiler/CMakeLists.txt
+++ b/src/shader_recompiler/CMakeLists.txt
@@ -72,6 +72,7 @@ add_library(shader_recompiler STATIC
72 frontend/maxwell/translate/impl/integer_scaled_add.cpp 72 frontend/maxwell/translate/impl/integer_scaled_add.cpp
73 frontend/maxwell/translate/impl/integer_set_predicate.cpp 73 frontend/maxwell/translate/impl/integer_set_predicate.cpp
74 frontend/maxwell/translate/impl/integer_shift_left.cpp 74 frontend/maxwell/translate/impl/integer_shift_left.cpp
75 frontend/maxwell/translate/impl/integer_shift_right.cpp
75 frontend/maxwell/translate/impl/integer_short_multiply_add.cpp 76 frontend/maxwell/translate/impl/integer_short_multiply_add.cpp
76 frontend/maxwell/translate/impl/load_store_attribute.cpp 77 frontend/maxwell/translate/impl/load_store_attribute.cpp
77 frontend/maxwell/translate/impl/load_store_memory.cpp 78 frontend/maxwell/translate/impl/load_store_memory.cpp
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h
index 4b74cf04d..90afbcc90 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.h
@@ -219,14 +219,15 @@ Id EmitIMul32(EmitContext& ctx, Id a, Id b);
219Id EmitINeg32(EmitContext& ctx, Id value); 219Id EmitINeg32(EmitContext& ctx, Id value);
220Id EmitIAbs32(EmitContext& ctx, Id value); 220Id EmitIAbs32(EmitContext& ctx, Id value);
221Id EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift); 221Id EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift);
222void EmitShiftRightLogical32(EmitContext& ctx); 222Id EmitShiftRightLogical32(EmitContext& ctx, Id a, Id b);
223void EmitShiftRightArithmetic32(EmitContext& ctx); 223Id EmitShiftRightArithmetic32(EmitContext& ctx, Id a, Id b);
224Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b); 224Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b);
225Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b); 225Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b);
226Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b); 226Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b);
227Id EmitBitFieldInsert(EmitContext& ctx, Id base, Id insert, Id offset, Id count); 227Id EmitBitFieldInsert(EmitContext& ctx, Id base, Id insert, Id offset, Id count);
228Id EmitBitFieldSExtract(EmitContext& ctx, Id base, Id offset, Id count); 228Id EmitBitFieldSExtract(EmitContext& ctx, Id base, Id offset, Id count);
229Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count); 229Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count);
230Id EmitBitReverse32(EmitContext& ctx, Id value);
230Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs); 231Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs);
231Id EmitULessThan(EmitContext& ctx, Id lhs, Id rhs); 232Id EmitULessThan(EmitContext& ctx, Id lhs, Id rhs);
232Id EmitIEqual(EmitContext& ctx, Id lhs, Id rhs); 233Id EmitIEqual(EmitContext& ctx, Id lhs, Id rhs);
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
index 8aaa0e381..406df1b78 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
@@ -70,12 +70,12 @@ Id EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift) {
70 return ctx.OpShiftLeftLogical(ctx.U32[1], base, shift); 70 return ctx.OpShiftLeftLogical(ctx.U32[1], base, shift);
71} 71}
72 72
73void EmitShiftRightLogical32(EmitContext&) { 73Id EmitShiftRightLogical32(EmitContext& ctx, Id a, Id b) {
74 throw NotImplementedException("SPIR-V Instruction"); 74 return ctx.OpShiftRightLogical(ctx.U32[1], a, b);
75} 75}
76 76
77void EmitShiftRightArithmetic32(EmitContext&) { 77Id EmitShiftRightArithmetic32(EmitContext& ctx, Id a, Id b) {
78 throw NotImplementedException("SPIR-V Instruction"); 78 return ctx.OpShiftRightArithmetic(ctx.U32[1], a, b);
79} 79}
80 80
81Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b) { 81Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b) {
@@ -102,6 +102,10 @@ Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count) {
102 return ctx.OpBitFieldUExtract(ctx.U32[1], base, offset, count); 102 return ctx.OpBitFieldUExtract(ctx.U32[1], base, offset, count);
103} 103}
104 104
105Id EmitBitReverse32(EmitContext& ctx, Id value) {
106 return ctx.OpBitReverse(ctx.U32[1], value);
107}
108
105Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs) { 109Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs) {
106 return ctx.OpSLessThan(ctx.U1, lhs, rhs); 110 return ctx.OpSLessThan(ctx.U1, lhs, rhs);
107} 111}
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index 0209d5540..7c3908398 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -804,6 +804,10 @@ U32 IREmitter::BitFieldExtract(const U32& base, const U32& offset, const U32& co
804 count); 804 count);
805} 805}
806 806
807U32 IREmitter::BitReverse(const U32& value) {
808 return Inst<U32>(Opcode::BitReverse32, value);
809}
810
807U1 IREmitter::ILessThan(const U32& lhs, const U32& rhs, bool is_signed) { 811U1 IREmitter::ILessThan(const U32& lhs, const U32& rhs, bool is_signed) {
808 return Inst<U1>(is_signed ? Opcode::SLessThan : Opcode::ULessThan, lhs, rhs); 812 return Inst<U1>(is_signed ? Opcode::SLessThan : Opcode::ULessThan, lhs, rhs);
809} 813}
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h
index 2c923716a..f7998e156 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.h
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.h
@@ -159,6 +159,7 @@ public:
159 const U32& count); 159 const U32& count);
160 [[nodiscard]] U32 BitFieldExtract(const U32& base, const U32& offset, const U32& count, 160 [[nodiscard]] U32 BitFieldExtract(const U32& base, const U32& offset, const U32& count,
161 bool is_signed); 161 bool is_signed);
162 [[nodiscard]] U32 BitReverse(const U32& value);
162 163
163 [[nodiscard]] U1 ILessThan(const U32& lhs, const U32& rhs, bool is_signed); 164 [[nodiscard]] U1 ILessThan(const U32& lhs, const U32& rhs, bool is_signed);
164 [[nodiscard]] U1 IEqual(const U32& lhs, const U32& rhs); 165 [[nodiscard]] U1 IEqual(const U32& lhs, const U32& rhs);
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc
index 289e76f32..f420f1161 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.inc
+++ b/src/shader_recompiler/frontend/ir/opcodes.inc
@@ -231,6 +231,7 @@ OPCODE(BitwiseXor32, U32, U32,
231OPCODE(BitFieldInsert, U32, U32, U32, U32, U32, ) 231OPCODE(BitFieldInsert, U32, U32, U32, U32, U32, )
232OPCODE(BitFieldSExtract, U32, U32, U32, U32, ) 232OPCODE(BitFieldSExtract, U32, U32, U32, U32, )
233OPCODE(BitFieldUExtract, U32, U32, U32, U32, ) 233OPCODE(BitFieldUExtract, U32, U32, U32, U32, )
234OPCODE(BitReverse32, U32, U32, )
234 235
235OPCODE(SLessThan, U1, U32, U32, ) 236OPCODE(SLessThan, U1, U32, U32, )
236OPCODE(ULessThan, U1, U32, U32, ) 237OPCODE(ULessThan, U1, U32, U32, )
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_right.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_right.cpp
new file mode 100644
index 000000000..a34ccb851
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_right.cpp
@@ -0,0 +1,62 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/bit_field.h"
6#include "common/common_types.h"
7#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
8
9namespace Shader::Maxwell {
10namespace {
11void SHR(TranslatorVisitor& v, u64 insn, const IR::U32& shift) {
12 union {
13 u64 insn;
14 BitField<0, 8, IR::Reg> dest_reg;
15 BitField<8, 8, IR::Reg> src_reg_a;
16 BitField<39, 1, u64> is_wrapped;
17 BitField<40, 1, u64> brev;
18 BitField<43, 1, u64> xmode;
19 BitField<48, 1, u64> is_arithmetic;
20 } const shr{insn};
21
22 if (shr.xmode != 0) {
23 throw NotImplementedException("SHR.XMODE");
24 }
25
26 IR::U32 base{v.X(shr.src_reg_a)};
27 if (shr.brev == 1) {
28 base = v.ir.BitReverse(base);
29 }
30 IR::U32 result;
31 const IR::U32 safe_shift = shr.is_wrapped == 0 ? shift : v.ir.BitwiseAnd(shift, v.ir.Imm32(31));
32 if (shr.is_arithmetic == 1) {
33 result = IR::U32{v.ir.ShiftRightArithmetic(base, safe_shift)};
34 } else {
35 result = IR::U32{v.ir.ShiftRightLogical(base, safe_shift)};
36 }
37
38 if (shr.is_wrapped == 0) {
39 const IR::U32 zero{v.ir.Imm32(0)};
40 const IR::U32 safe_bits{v.ir.Imm32(32)};
41
42 const IR::U1 is_negative{v.ir.ILessThan(result, zero, true)};
43 const IR::U1 is_safe{v.ir.ILessThan(shift, safe_bits, false)};
44 const IR::U32 clamped_value{v.ir.Select(is_negative, v.ir.Imm32(-1), zero)};
45 result = IR::U32{v.ir.Select(is_safe, result, clamped_value)};
46 }
47 v.X(shr.dest_reg, result);
48}
49} // Anonymous namespace
50
51void TranslatorVisitor::SHR_reg(u64 insn) {
52 SHR(*this, insn, GetReg20(insn));
53}
54
55void TranslatorVisitor::SHR_cbuf(u64 insn) {
56 SHR(*this, insn, GetCbuf(insn));
57}
58
59void TranslatorVisitor::SHR_imm(u64 insn) {
60 SHR(*this, insn, GetImm20(insn));
61}
62} // 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 82c73bf8c..45ed04e25 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -757,18 +757,6 @@ void TranslatorVisitor::SHFL(u64) {
757 ThrowNotImplemented(Opcode::SHFL); 757 ThrowNotImplemented(Opcode::SHFL);
758} 758}
759 759
760void TranslatorVisitor::SHR_reg(u64) {
761 ThrowNotImplemented(Opcode::SHR_reg);
762}
763
764void TranslatorVisitor::SHR_cbuf(u64) {
765 ThrowNotImplemented(Opcode::SHR_cbuf);
766}
767
768void TranslatorVisitor::SHR_imm(u64) {
769 ThrowNotImplemented(Opcode::SHR_imm);
770}
771
772void TranslatorVisitor::SSY() { 760void TranslatorVisitor::SSY() {
773 // SSY is a no-op 761 // SSY is a no-op
774} 762}