diff options
| author | 2020-01-25 02:18:14 -0300 | |
|---|---|---|
| committer | 2020-01-25 03:16:10 -0300 | |
| commit | 531f25a03789dbdd3242edbe00d07dabc85847eb (patch) | |
| tree | cd11d0ca1d984375b572d1928a0dbfcf955e2560 /src | |
| parent | shader/memory: Implement LDL.S16 and LDS.S16 (diff) | |
| download | yuzu-531f25a03789dbdd3242edbe00d07dabc85847eb.tar.gz yuzu-531f25a03789dbdd3242edbe00d07dabc85847eb.tar.xz yuzu-531f25a03789dbdd3242edbe00d07dabc85847eb.zip | |
shader/memory: Move unaligned load/store to functions
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/memory.cpp | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 3f3ef6e7c..2f5ca5de5 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp | |||
| @@ -62,6 +62,20 @@ u32 GetMemorySize(Tegra::Shader::UniformType uniform_type) { | |||
| 62 | } | 62 | } |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | Node ExtractUnaligned(Node value, Node address, u32 mask, u32 size) { | ||
| 66 | Node offset = Operation(OperationCode::UBitwiseAnd, address, Immediate(mask)); | ||
| 67 | offset = Operation(OperationCode::ULogicalShiftLeft, std::move(offset), Immediate(3)); | ||
| 68 | return Operation(OperationCode::UBitfieldExtract, std::move(value), std::move(offset), | ||
| 69 | Immediate(size)); | ||
| 70 | } | ||
| 71 | |||
| 72 | Node InsertUnaligned(Node dest, Node value, Node address, u32 mask, u32 size) { | ||
| 73 | Node offset = Operation(OperationCode::UBitwiseAnd, std::move(address), Immediate(mask)); | ||
| 74 | offset = Operation(OperationCode::ULogicalShiftLeft, std::move(offset), Immediate(3)); | ||
| 75 | return Operation(OperationCode::UBitfieldInsert, std::move(dest), std::move(value), | ||
| 76 | std::move(offset), Immediate(size)); | ||
| 77 | } | ||
| 78 | |||
| 65 | Node Sign16Extend(Node value) { | 79 | Node Sign16Extend(Node value) { |
| 66 | Node sign = Operation(OperationCode::UBitwiseAnd, value, Immediate(1U << 15)); | 80 | Node sign = Operation(OperationCode::UBitwiseAnd, value, Immediate(1U << 15)); |
| 67 | Node is_sign = Operation(OperationCode::LogicalUEqual, std::move(sign), Immediate(1U << 15)); | 81 | Node is_sign = Operation(OperationCode::LogicalUEqual, std::move(sign), Immediate(1U << 15)); |
| @@ -144,19 +158,23 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | |||
| 144 | LOG_DEBUG(HW_GPU, "LD_L cache management mode: {}", static_cast<u64>(instr.ld_l.unknown)); | 158 | LOG_DEBUG(HW_GPU, "LD_L cache management mode: {}", static_cast<u64>(instr.ld_l.unknown)); |
| 145 | [[fallthrough]]; | 159 | [[fallthrough]]; |
| 146 | case OpCode::Id::LD_S: { | 160 | case OpCode::Id::LD_S: { |
| 147 | const auto GetMemory = [&](s32 offset) { | 161 | const auto GetAddress = [&](s32 offset) { |
| 148 | ASSERT(offset % 4 == 0); | 162 | ASSERT(offset % 4 == 0); |
| 149 | const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset); | 163 | const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset); |
| 150 | const Node address = | 164 | return Operation(OperationCode::IAdd, GetRegister(instr.gpr8), immediate_offset); |
| 151 | Operation(OperationCode::IAdd, GetRegister(instr.gpr8), immediate_offset); | 165 | }; |
| 152 | return opcode->get().GetId() == OpCode::Id::LD_S ? GetSharedMemory(address) | 166 | const auto GetMemory = [&](s32 offset) { |
| 153 | : GetLocalMemory(address); | 167 | return opcode->get().GetId() == OpCode::Id::LD_S ? GetSharedMemory(GetAddress(offset)) |
| 168 | : GetLocalMemory(GetAddress(offset)); | ||
| 154 | }; | 169 | }; |
| 155 | 170 | ||
| 156 | switch (instr.ldst_sl.type.Value()) { | 171 | switch (instr.ldst_sl.type.Value()) { |
| 157 | case StoreType::Signed16: | 172 | case StoreType::Signed16: { |
| 173 | Node address = GetAddress(0); | ||
| 174 | |||
| 158 | SetRegister(bb, instr.gpr0, Sign16Extend(GetMemory(0))); | 175 | SetRegister(bb, instr.gpr0, Sign16Extend(GetMemory(0))); |
| 159 | break; | 176 | break; |
| 177 | } | ||
| 160 | case StoreType::Bits32: | 178 | case StoreType::Bits32: |
| 161 | case StoreType::Bits64: | 179 | case StoreType::Bits64: |
| 162 | case StoreType::Bits128: { | 180 | case StoreType::Bits128: { |
| @@ -223,12 +241,7 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | |||
| 223 | // To handle unaligned loads get the bytes used to dereference global memory and extract | 241 | // To handle unaligned loads get the bytes used to dereference global memory and extract |
| 224 | // those bytes from the loaded u32. | 242 | // those bytes from the loaded u32. |
| 225 | if (IsUnaligned(type)) { | 243 | if (IsUnaligned(type)) { |
| 226 | Node mask = Immediate(GetUnalignedMask(type)); | 244 | gmem = ExtractUnaligned(gmem, real_address, GetUnalignedMask(type), size); |
| 227 | Node offset = Operation(OperationCode::UBitwiseAnd, real_address, std::move(mask)); | ||
| 228 | offset = Operation(OperationCode::ULogicalShiftLeft, offset, Immediate(3)); | ||
| 229 | |||
| 230 | gmem = Operation(OperationCode::UBitfieldExtract, std::move(gmem), | ||
| 231 | std::move(offset), Immediate(size)); | ||
| 232 | } | 245 | } |
| 233 | 246 | ||
| 234 | SetTemporary(bb, i, gmem); | 247 | SetTemporary(bb, i, gmem); |
| @@ -334,12 +347,8 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | |||
| 334 | Node value = GetRegister(instr.gpr0.Value() + i); | 347 | Node value = GetRegister(instr.gpr0.Value() + i); |
| 335 | 348 | ||
| 336 | if (IsUnaligned(type)) { | 349 | if (IsUnaligned(type)) { |
| 337 | Node mask = Immediate(GetUnalignedMask(type)); | 350 | const u32 mask = GetUnalignedMask(type); |
| 338 | Node offset = Operation(OperationCode::UBitwiseAnd, real_address, std::move(mask)); | 351 | value = InsertUnaligned(gmem, std::move(value), real_address, mask, size); |
| 339 | offset = Operation(OperationCode::ULogicalShiftLeft, offset, Immediate(3)); | ||
| 340 | |||
| 341 | value = Operation(OperationCode::UBitfieldInsert, gmem, std::move(value), offset, | ||
| 342 | Immediate(size)); | ||
| 343 | } | 352 | } |
| 344 | 353 | ||
| 345 | bb.push_back(Operation(OperationCode::Assign, gmem, value)); | 354 | bb.push_back(Operation(OperationCode::Assign, gmem, value)); |