summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-01-25 03:15:55 -0300
committerGravatar ReinUsesLisp2020-01-25 03:15:55 -0300
commit96638f57c9e17c3427d1ec6b39f250268a29ddd3 (patch)
tree03d29965333b1dc26854b9714b43c9cc594055b7 /src
parentMerge pull request #3343 from FearlessTobi/ui-tab (diff)
downloadyuzu-96638f57c9e17c3427d1ec6b39f250268a29ddd3.tar.gz
yuzu-96638f57c9e17c3427d1ec6b39f250268a29ddd3.tar.xz
yuzu-96638f57c9e17c3427d1ec6b39f250268a29ddd3.zip
shader/memory: Implement LDL.S16 and LDS.S16
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/decode/memory.cpp35
1 files changed, 23 insertions, 12 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index 7591a715f..3f3ef6e7c 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -22,6 +22,7 @@ using Tegra::Shader::Attribute;
22using Tegra::Shader::Instruction; 22using Tegra::Shader::Instruction;
23using Tegra::Shader::OpCode; 23using Tegra::Shader::OpCode;
24using Tegra::Shader::Register; 24using Tegra::Shader::Register;
25using Tegra::Shader::StoreType;
25 26
26namespace { 27namespace {
27 28
@@ -61,6 +62,13 @@ u32 GetMemorySize(Tegra::Shader::UniformType uniform_type) {
61 } 62 }
62} 63}
63 64
65Node Sign16Extend(Node value) {
66 Node sign = Operation(OperationCode::UBitwiseAnd, value, Immediate(1U << 15));
67 Node is_sign = Operation(OperationCode::LogicalUEqual, std::move(sign), Immediate(1U << 15));
68 Node extend = Operation(OperationCode::Select, is_sign, Immediate(0xFFFF0000), Immediate(0));
69 return Operation(OperationCode::UBitwiseOr, std::move(value), std::move(extend));
70}
71
64} // Anonymous namespace 72} // Anonymous namespace
65 73
66u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { 74u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
@@ -139,23 +147,26 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
139 const auto GetMemory = [&](s32 offset) { 147 const auto GetMemory = [&](s32 offset) {
140 ASSERT(offset % 4 == 0); 148 ASSERT(offset % 4 == 0);
141 const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset); 149 const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset);
142 const Node address = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), 150 const Node address =
143 immediate_offset); 151 Operation(OperationCode::IAdd, GetRegister(instr.gpr8), immediate_offset);
144 return opcode->get().GetId() == OpCode::Id::LD_S ? GetSharedMemory(address) 152 return opcode->get().GetId() == OpCode::Id::LD_S ? GetSharedMemory(address)
145 : GetLocalMemory(address); 153 : GetLocalMemory(address);
146 }; 154 };
147 155
148 switch (instr.ldst_sl.type.Value()) { 156 switch (instr.ldst_sl.type.Value()) {
149 case Tegra::Shader::StoreType::Bits32: 157 case StoreType::Signed16:
150 case Tegra::Shader::StoreType::Bits64: 158 SetRegister(bb, instr.gpr0, Sign16Extend(GetMemory(0)));
151 case Tegra::Shader::StoreType::Bits128: { 159 break;
152 const u32 count = [&]() { 160 case StoreType::Bits32:
161 case StoreType::Bits64:
162 case StoreType::Bits128: {
163 const u32 count = [&] {
153 switch (instr.ldst_sl.type.Value()) { 164 switch (instr.ldst_sl.type.Value()) {
154 case Tegra::Shader::StoreType::Bits32: 165 case StoreType::Bits32:
155 return 1; 166 return 1;
156 case Tegra::Shader::StoreType::Bits64: 167 case StoreType::Bits64:
157 return 2; 168 return 2;
158 case Tegra::Shader::StoreType::Bits128: 169 case StoreType::Bits128:
159 return 4; 170 return 4;
160 default: 171 default:
161 UNREACHABLE(); 172 UNREACHABLE();
@@ -274,14 +285,14 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
274 : &ShaderIR::SetSharedMemory; 285 : &ShaderIR::SetSharedMemory;
275 286
276 switch (instr.ldst_sl.type.Value()) { 287 switch (instr.ldst_sl.type.Value()) {
277 case Tegra::Shader::StoreType::Bits128: 288 case StoreType::Bits128:
278 (this->*set_memory)(bb, GetAddress(12), GetRegister(instr.gpr0.Value() + 3)); 289 (this->*set_memory)(bb, GetAddress(12), GetRegister(instr.gpr0.Value() + 3));
279 (this->*set_memory)(bb, GetAddress(8), GetRegister(instr.gpr0.Value() + 2)); 290 (this->*set_memory)(bb, GetAddress(8), GetRegister(instr.gpr0.Value() + 2));
280 [[fallthrough]]; 291 [[fallthrough]];
281 case Tegra::Shader::StoreType::Bits64: 292 case StoreType::Bits64:
282 (this->*set_memory)(bb, GetAddress(4), GetRegister(instr.gpr0.Value() + 1)); 293 (this->*set_memory)(bb, GetAddress(4), GetRegister(instr.gpr0.Value() + 1));
283 [[fallthrough]]; 294 [[fallthrough]];
284 case Tegra::Shader::StoreType::Bits32: 295 case StoreType::Bits32:
285 (this->*set_memory)(bb, GetAddress(0), GetRegister(instr.gpr0)); 296 (this->*set_memory)(bb, GetAddress(0), GetRegister(instr.gpr0));
286 break; 297 break;
287 default: 298 default: