Commit 707ed997 by Chris Forbes

Add support for OpAtomicISub, OpAtomicIIncrement, OpAtomicIDecrement

These are the remaining operations which were not tested through the dEQP-VK.image.* path. Test: dEQP-VK.spirv_assembly.* Bug: b/127472316 Change-Id: Icedc2fc7b972714bc67705e2458e1207972b95cc Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/29457Tested-by: 's avatarChris Forbes <chrisforbes@google.com> Presubmit-Ready: Chris Forbes <chrisforbes@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 9869d601
...@@ -679,6 +679,7 @@ namespace sw ...@@ -679,6 +679,7 @@ namespace sw
case spv::OpFwidthFine: case spv::OpFwidthFine:
case spv::OpAtomicLoad: case spv::OpAtomicLoad:
case spv::OpAtomicIAdd: case spv::OpAtomicIAdd:
case spv::OpAtomicISub:
case spv::OpAtomicSMin: case spv::OpAtomicSMin:
case spv::OpAtomicSMax: case spv::OpAtomicSMax:
case spv::OpAtomicUMin: case spv::OpAtomicUMin:
...@@ -686,6 +687,8 @@ namespace sw ...@@ -686,6 +687,8 @@ namespace sw
case spv::OpAtomicAnd: case spv::OpAtomicAnd:
case spv::OpAtomicOr: case spv::OpAtomicOr:
case spv::OpAtomicXor: case spv::OpAtomicXor:
case spv::OpAtomicIIncrement:
case spv::OpAtomicIDecrement:
case spv::OpAtomicExchange: case spv::OpAtomicExchange:
case spv::OpAtomicCompareExchange: case spv::OpAtomicCompareExchange:
case spv::OpPhi: case spv::OpPhi:
...@@ -2017,6 +2020,7 @@ namespace sw ...@@ -2017,6 +2020,7 @@ namespace sw
return EmitStore(insn, state); return EmitStore(insn, state);
case spv::OpAtomicIAdd: case spv::OpAtomicIAdd:
case spv::OpAtomicISub:
case spv::OpAtomicSMin: case spv::OpAtomicSMin:
case spv::OpAtomicSMax: case spv::OpAtomicSMax:
case spv::OpAtomicUMin: case spv::OpAtomicUMin:
...@@ -2024,6 +2028,8 @@ namespace sw ...@@ -2024,6 +2028,8 @@ namespace sw
case spv::OpAtomicAnd: case spv::OpAtomicAnd:
case spv::OpAtomicOr: case spv::OpAtomicOr:
case spv::OpAtomicXor: case spv::OpAtomicXor:
case spv::OpAtomicIIncrement:
case spv::OpAtomicIDecrement:
case spv::OpAtomicExchange: case spv::OpAtomicExchange:
return EmitAtomicOp(insn, state); return EmitAtomicOp(insn, state);
...@@ -4759,7 +4765,8 @@ namespace sw ...@@ -4759,7 +4765,8 @@ namespace sw
Object::ID semanticsId = insn.word(5); Object::ID semanticsId = insn.word(5);
auto memorySemantics = static_cast<spv::MemorySemanticsMask>(getObject(semanticsId).constantValue[0]); auto memorySemantics = static_cast<spv::MemorySemanticsMask>(getObject(semanticsId).constantValue[0]);
auto memoryOrder = MemoryOrder(memorySemantics); auto memoryOrder = MemoryOrder(memorySemantics);
auto value = GenericValue(this, state->routine, insn.word(6)); // Where no value is provided (increment/decrement) use an implicit value of 1.
auto value = (insn.wordCount() == 7) ? GenericValue(this, state->routine, insn.word(6)).UInt(0) : RValue<SIMD::UInt>(1);
auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents); auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents);
auto ptr = state->routine->getPointer(insn.word(3)); auto ptr = state->routine->getPointer(insn.word(3));
...@@ -4769,13 +4776,18 @@ namespace sw ...@@ -4769,13 +4776,18 @@ namespace sw
If(Extract(state->activeLaneMask(), j) != 0) If(Extract(state->activeLaneMask(), j) != 0)
{ {
auto offset = Extract(ptr.offset, j); auto offset = Extract(ptr.offset, j);
auto laneValue = Extract(value.UInt(0), j); auto laneValue = Extract(value, j);
UInt v; UInt v;
switch (insn.opcode()) switch (insn.opcode())
{ {
case spv::OpAtomicIAdd: case spv::OpAtomicIAdd:
case spv::OpAtomicIIncrement:
v = AddAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder); v = AddAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
break; break;
case spv::OpAtomicISub:
case spv::OpAtomicIDecrement:
v = SubAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
break;
case spv::OpAtomicAnd: case spv::OpAtomicAnd:
v = AndAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder); v = AndAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
break; break;
......
...@@ -1294,6 +1294,12 @@ namespace rr ...@@ -1294,6 +1294,12 @@ namespace rr
return V(::builder->CreateAtomicRMW(llvm::AtomicRMWInst::Add, V(ptr), V(value), atomicOrdering(true, memoryOrder))); return V(::builder->CreateAtomicRMW(llvm::AtomicRMWInst::Add, V(ptr), V(value), atomicOrdering(true, memoryOrder)));
} }
Value *Nucleus::createAtomicSub(Value *ptr, Value *value, std::memory_order memoryOrder)
{
RR_DEBUG_INFO_UPDATE_LOC();
return V(::builder->CreateAtomicRMW(llvm::AtomicRMWInst::Sub, V(ptr), V(value), atomicOrdering(true, memoryOrder)));
}
Value *Nucleus::createAtomicAnd(Value *ptr, Value *value, std::memory_order memoryOrder) Value *Nucleus::createAtomicAnd(Value *ptr, Value *value, std::memory_order memoryOrder)
{ {
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
......
...@@ -102,6 +102,7 @@ namespace rr ...@@ -102,6 +102,7 @@ namespace rr
// Atomic instructions // Atomic instructions
static Value *createAtomicAdd(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed); static Value *createAtomicAdd(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
static Value *createAtomicSub(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
static Value *createAtomicAnd(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed); static Value *createAtomicAnd(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
static Value *createAtomicOr(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed); static Value *createAtomicOr(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
static Value *createAtomicXor(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed); static Value *createAtomicXor(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
......
...@@ -2512,6 +2512,11 @@ namespace rr ...@@ -2512,6 +2512,11 @@ namespace rr
return RValue<UInt>(Nucleus::createAtomicAdd(x.value, y.value, memoryOrder)); return RValue<UInt>(Nucleus::createAtomicAdd(x.value, y.value, memoryOrder));
} }
RValue<UInt> SubAtomic(RValue<Pointer<UInt> > x, RValue<UInt> y, std::memory_order memoryOrder)
{
return RValue<UInt>(Nucleus::createAtomicSub(x.value, y.value, memoryOrder));
}
RValue<UInt> AndAtomic(RValue<Pointer<UInt> > x, RValue<UInt> y, std::memory_order memoryOrder) RValue<UInt> AndAtomic(RValue<Pointer<UInt> > x, RValue<UInt> y, std::memory_order memoryOrder)
{ {
return RValue<UInt>(Nucleus::createAtomicAnd(x.value, y.value, memoryOrder)); return RValue<UInt>(Nucleus::createAtomicAnd(x.value, y.value, memoryOrder));
......
...@@ -1269,6 +1269,7 @@ namespace rr ...@@ -1269,6 +1269,7 @@ namespace rr
RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max); RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max);
RValue<UInt> AddAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder); RValue<UInt> AddAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder);
RValue<UInt> SubAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder);
RValue<UInt> AndAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder); RValue<UInt> AndAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder);
RValue<UInt> OrAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder); RValue<UInt> OrAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder);
RValue<UInt> XorAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder); RValue<UInt> XorAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder);
......
...@@ -1039,6 +1039,12 @@ namespace rr ...@@ -1039,6 +1039,12 @@ namespace rr
return nullptr; return nullptr;
} }
Value *Nucleus::createAtomicSub(Value *ptr, Value *value, std::memory_order memoryOrder)
{
UNIMPLEMENTED("createAtomicSub");
return nullptr;
}
Value *Nucleus::createAtomicAnd(Value *ptr, Value *value, std::memory_order memoryOrder) Value *Nucleus::createAtomicAnd(Value *ptr, Value *value, std::memory_order memoryOrder)
{ {
UNIMPLEMENTED("createAtomicAnd"); UNIMPLEMENTED("createAtomicAnd");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment