diff options
author | Nguyen Dac Nam <nam.kazt.91@gmail.com> | 2020-03-13 19:23:47 +0100 |
---|---|---|
committer | namkazy <nam.kazt.91@gmail.com> | 2020-03-30 12:44:48 +0200 |
commit | 972485ff18c9929faa07d1091634715e4c7f7eb4 (patch) | |
tree | 7c162353f15bdf06c0748c5b0e19a6f263f52bd9 /src | |
parent | clang-format (diff) | |
download | yuzu-972485ff18c9929faa07d1091634715e4c7f7eb4.tar yuzu-972485ff18c9929faa07d1091634715e4c7f7eb4.tar.gz yuzu-972485ff18c9929faa07d1091634715e4c7f7eb4.tar.bz2 yuzu-972485ff18c9929faa07d1091634715e4c7f7eb4.tar.lz yuzu-972485ff18c9929faa07d1091634715e4c7f7eb4.tar.xz yuzu-972485ff18c9929faa07d1091634715e4c7f7eb4.tar.zst yuzu-972485ff18c9929faa07d1091634715e4c7f7eb4.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/video_core/shader/decode/memory.cpp | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 98ae474e6..47edec71f 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp @@ -363,10 +363,13 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { break; } case OpCode::Id::ATOM: { - UNIMPLEMENTED_IF_MSG(instr.atom.operation != GlobalAtomicOp::Add, "operation={}", - static_cast<int>(instr.atom.operation.Value())); - UNIMPLEMENTED_IF_MSG(instr.atom.type != GlobalAtomicType::S32, "type={}", - static_cast<int>(instr.atom.type.Value())); + UNIMPLEMENTED_IF_MSG(instr.atom.operation == GlobalAtomicOp::Inc || + instr.atom.operation == GlobalAtomicOp::Dec || + instr.atom.operation == GlobalAtomicOp::SafeAdd, + "operation={}", static_cast<int>(instr.atom.operation.Value())); + UNIMPLEMENTED_IF_MSG(instr.atom.type == GlobalAtomicType::S64 || + instr.atom.type == GlobalAtomicType::U64, + "type={}", static_cast<int>(instr.atom.type.Value())); const auto [real_address, base_address, descriptor] = TrackGlobalMemory(bb, instr, true, true); @@ -375,9 +378,39 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { break; } + const bool is_signed = + instr.atoms.type == AtomicType::S32 || instr.atoms.type == AtomicType::S64; Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor); - Node value = - Operation(OperationCode::AtomicIAdd, std::move(gmem), GetRegister(instr.gpr20)); + Node data = GetRegister(instr.gpr20); + + Node value = [&]() { + switch (instr.atoms.operation) { + case AtomicOp::Add: + return SignedOperation(OperationCode::AtomicIAdd, is_signed, std::move(gmem), + std::move(data)); + case AtomicOp::Min: + return SignedOperation(OperationCode::AtomicIMin, is_signed, std::move(gmem), + std::move(data)); + case AtomicOp::Max: + return SignedOperation(OperationCode::AtomicIMax, is_signed, std::move(gmem), + std::move(data)); + case AtomicOp::And: + return SignedOperation(OperationCode::AtomicIAnd, is_signed, std::move(gmem), + std::move(data)); + case AtomicOp::Or: + return SignedOperation(OperationCode::AtomicIOr, is_signed, std::move(gmem), + std::move(data)); + case AtomicOp::Xor: + return SignedOperation(OperationCode::AtomicIXor, is_signed, std::move(gmem), + std::move(data)); + case AtomicOp::Exch: + return SignedOperation(OperationCode::AtomicIExchange, is_signed, std::move(gmem), + std::move(data)); + default: + UNREACHABLE(); + return Immediate(0); + } + }(); SetRegister(bb, instr.gpr0, std::move(value)); break; } |