summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend
diff options
context:
space:
mode:
authorGravatar ameerj2021-03-04 01:02:44 -0500
committerGravatar ameerj2021-07-22 21:51:23 -0400
commit81f72471e831a0bc4205df6df61e5b510a5c25ac (patch)
tree529ce1f6999c0c2ec7d55255b6c8c62be57f4370 /src/shader_recompiler/frontend
parentshader: Implement HADD2 (diff)
downloadyuzu-81f72471e831a0bc4205df6df61e5b510a5c25ac.tar.gz
yuzu-81f72471e831a0bc4205df6df61e5b510a5c25ac.tar.xz
yuzu-81f72471e831a0bc4205df6df61e5b510a5c25ac.zip
shader: Implement I2I
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_to_integer_conversion.cpp99
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp12
2 files changed, 99 insertions, 12 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_to_integer_conversion.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_to_integer_conversion.cpp
new file mode 100644
index 000000000..ca28c6dd9
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_to_integer_conversion.cpp
@@ -0,0 +1,99 @@
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 {
11enum class IntegerWidth : u64 {
12 Byte,
13 Short,
14 Word,
15};
16
17[[nodiscard]] IR::U32 WidthSize(IR::IREmitter& ir, IntegerWidth width) {
18 switch (width) {
19 case IntegerWidth::Byte:
20 return ir.Imm32(8);
21 case IntegerWidth::Short:
22 return ir.Imm32(16);
23 case IntegerWidth::Word:
24 return ir.Imm32(32);
25 default:
26 throw NotImplementedException("Invalid width {}", width);
27 }
28}
29
30[[nodiscard]] IR::U32 ConvertInteger(IR::IREmitter& ir, const IR::U32& src,
31 IntegerWidth dst_width) {
32 const IR::U32 zero{ir.Imm32(0)};
33 switch (dst_width) {
34 case IntegerWidth::Byte:
35 return ir.BitFieldExtract(src, zero, ir.Imm32(8), false);
36 case IntegerWidth::Short:
37 return ir.BitFieldExtract(src, zero, ir.Imm32(16), false);
38 case IntegerWidth::Word:
39 return ir.BitFieldExtract(src, zero, ir.Imm32(32), false);
40 default:
41 throw NotImplementedException("Invalid width {}", dst_width);
42 }
43}
44
45void I2I(TranslatorVisitor& v, u64 insn, const IR::U32& src_a) {
46 union {
47 u64 insn;
48 BitField<0, 8, IR::Reg> dest_reg;
49 BitField<8, 2, IntegerWidth> dst_fmt;
50 BitField<12, 1, u64> dst_fmt_sign;
51 BitField<10, 2, IntegerWidth> src_fmt;
52 BitField<13, 1, u64> src_fmt_sign;
53 BitField<41, 3, u64> selector;
54 BitField<45, 1, u64> neg;
55 BitField<49, 1, u64> abs;
56 BitField<50, 1, u64> sat;
57 } const i2i{insn};
58
59 if (i2i.sat != 0) {
60 throw NotImplementedException("I2I SAT");
61 }
62 if (i2i.src_fmt == IntegerWidth::Short && (i2i.selector == 1 || i2i.selector == 3)) {
63 throw NotImplementedException("16-bit source format incompatible with selector {}",
64 i2i.selector);
65 }
66 if (i2i.src_fmt == IntegerWidth::Word && i2i.selector != 0) {
67 throw NotImplementedException("32-bit source format incompatible with selector {}",
68 i2i.selector);
69 }
70
71 const s32 selector{static_cast<s32>(i2i.selector)};
72 const IR::U32 offset{v.ir.Imm32(selector * 8)};
73 const IR::U32 count{WidthSize(v.ir, i2i.src_fmt)};
74 IR::U32 src_values{v.ir.BitFieldExtract(src_a, offset, count, i2i.src_fmt_sign != 0)};
75 if (i2i.abs) {
76 src_values = v.ir.IAbs(src_values);
77 }
78 if (i2i.neg) {
79 src_values = v.ir.INeg(src_values);
80 }
81
82 const IR::U32 result{ConvertInteger(v.ir, src_values, i2i.dst_fmt)};
83 v.X(i2i.dest_reg, result);
84}
85} // Anonymous namespace
86
87void TranslatorVisitor::I2I_reg(u64 insn) {
88 I2I(*this, insn, GetReg20(insn));
89}
90
91void TranslatorVisitor::I2I_cbuf(u64 insn) {
92 I2I(*this, insn, GetCbuf(insn));
93}
94
95void TranslatorVisitor::I2I_imm(u64 insn) {
96 I2I(*this, insn, GetImm20(insn));
97}
98
99} // 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 c24f29ff7..bd7a7a8b7 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -337,18 +337,6 @@ void TranslatorVisitor::I2F_imm(u64) {
337 ThrowNotImplemented(Opcode::I2F_imm); 337 ThrowNotImplemented(Opcode::I2F_imm);
338} 338}
339 339
340void TranslatorVisitor::I2I_reg(u64) {
341 ThrowNotImplemented(Opcode::I2I_reg);
342}
343
344void TranslatorVisitor::I2I_cbuf(u64) {
345 ThrowNotImplemented(Opcode::I2I_cbuf);
346}
347
348void TranslatorVisitor::I2I_imm(u64) {
349 ThrowNotImplemented(Opcode::I2I_imm);
350}
351
352void TranslatorVisitor::IDE(u64) { 340void TranslatorVisitor::IDE(u64) {
353 ThrowNotImplemented(Opcode::IDE); 341 ThrowNotImplemented(Opcode::IDE);
354} 342}