Commit dd1e37e3 by Ben Clayton Committed by Chris Forbes

SpirvShader: Begin unary and binary ops.

Far from a complete set, but both Chris and I are looking at tests that require these opcodes. Bug: b/126870789 Bug: b/126873455 Change-Id: Idb2109cfc3352da83aa38d42eed5d15537dfb6b7 Reviewed-on: https://swiftshader-review.googlesource.com/c/25868Tested-by: 's avatarChris Forbes <chrisforbes@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent a1924739
......@@ -212,6 +212,27 @@ namespace sw
case spv::OpCompositeInsert:
case spv::OpCompositeExtract:
case spv::OpVectorShuffle:
case spv::OpNot: // Unary ops
case spv::OpSNegate:
case spv::OpFNegate:
case spv::OpLogicalNot:
case spv::OpIAdd: // Binary ops
case spv::OpISub:
case spv::OpIMul:
case spv::OpSDiv:
case spv::OpUDiv:
case spv::OpFAdd:
case spv::OpFSub:
case spv::OpFDiv:
case spv::OpUMod:
case spv::OpShiftRightLogical:
case spv::OpShiftRightArithmetic:
case spv::OpShiftLeftLogical:
case spv::OpBitwiseOr:
case spv::OpBitwiseXor:
case spv::OpBitwiseAnd:
case spv::OpLogicalOr:
case spv::OpLogicalAnd:
// Instructions that yield an ssavalue.
{
TypeID typeId = insn.word(1);
......@@ -862,6 +883,33 @@ namespace sw
EmitVectorShuffle(insn, routine);
break;
case spv::OpNot:
case spv::OpSNegate:
case spv::OpFNegate:
case spv::OpLogicalNot:
EmitUnaryOp(insn, routine);
break;
case spv::OpIAdd:
case spv::OpISub:
case spv::OpIMul:
case spv::OpSDiv:
case spv::OpUDiv:
case spv::OpFAdd:
case spv::OpFSub:
case spv::OpFDiv:
case spv::OpUMod:
case spv::OpShiftRightLogical:
case spv::OpShiftRightArithmetic:
case spv::OpShiftLeftLogical:
case spv::OpBitwiseOr:
case spv::OpBitwiseXor:
case spv::OpBitwiseAnd:
case spv::OpLogicalOr:
case spv::OpLogicalAnd:
EmitBinaryOp(insn, routine);
break;
default:
printf("emit: ignoring opcode %s\n", OpcodeName(insn.opcode()).c_str());
break;
......@@ -1120,6 +1168,101 @@ namespace sw
}
}
void SpirvShader::EmitUnaryOp(InsnIterator insn, SpirvRoutine *routine) const
{
auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents);
auto src = GenericValue(this, routine, insn.word(3));
for (auto i = 0u; i < type.sizeInComponents; i++)
{
auto val = src[i];
switch (insn.opcode())
{
case spv::OpNot:
case spv::OpLogicalNot: // logical not == bitwise not due to all-bits boolean representation
dst.emplace(i, As<SIMD::Float>(~As<SIMD::UInt>(val)));
break;
case spv::OpSNegate:
dst.emplace(i, As<SIMD::Float>(-As<SIMD::Int>(val)));
break;
case spv::OpFNegate:
dst.emplace(i, -val);
break;
default:
UNIMPLEMENTED("Unhandled unary operator %s", OpcodeName(insn.opcode()).c_str());
}
}
}
void SpirvShader::EmitBinaryOp(InsnIterator insn, SpirvRoutine *routine) const
{
auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents);
auto srcLHS = GenericValue(this, routine, insn.word(3));
auto srcRHS = GenericValue(this, routine, insn.word(4));
for (auto i = 0u; i < type.sizeInComponents; i++)
{
auto lhs = srcLHS[i];
auto rhs = srcRHS[i];
switch (insn.opcode())
{
case spv::OpIAdd:
dst.emplace(i, As<SIMD::Float>(As<SIMD::Int>(lhs) + As<SIMD::Int>(rhs)));
break;
case spv::OpISub:
dst.emplace(i, As<SIMD::Float>(As<SIMD::Int>(lhs) - As<SIMD::Int>(rhs)));
break;
case spv::OpIMul:
dst.emplace(i, As<SIMD::Float>(As<SIMD::Int>(lhs) * As<SIMD::Int>(rhs)));
break;
case spv::OpSDiv:
dst.emplace(i, As<SIMD::Float>(As<SIMD::Int>(lhs) / As<SIMD::Int>(rhs)));
break;
case spv::OpUDiv:
dst.emplace(i, As<SIMD::Float>(As<SIMD::UInt>(lhs) / As<SIMD::UInt>(rhs)));
break;
case spv::OpUMod:
dst.emplace(i, As<SIMD::Float>(As<SIMD::UInt>(lhs) % As<SIMD::UInt>(rhs)));
break;
case spv::OpFAdd:
dst.emplace(i, lhs + rhs);
break;
case spv::OpFSub:
dst.emplace(i, lhs - rhs);
break;
case spv::OpFDiv:
dst.emplace(i, lhs / rhs);
break;
case spv::OpShiftRightLogical:
dst.emplace(i, As<SIMD::Float>(As<SIMD::UInt>(lhs) >> As<SIMD::UInt>(rhs)));
break;
case spv::OpShiftRightArithmetic:
dst.emplace(i, As<SIMD::Float>(As<SIMD::Int>(lhs) >> As<SIMD::Int>(rhs)));
break;
case spv::OpShiftLeftLogical:
dst.emplace(i, As<SIMD::Float>(As<SIMD::UInt>(lhs) << As<SIMD::UInt>(rhs)));
break;
case spv::OpBitwiseOr:
case spv::OpLogicalOr:
dst.emplace(i, As<SIMD::Float>(As<SIMD::UInt>(lhs) | As<SIMD::UInt>(rhs)));
break;
case spv::OpBitwiseXor:
dst.emplace(i, As<SIMD::Float>(As<SIMD::UInt>(lhs) ^ As<SIMD::UInt>(rhs)));
break;
case spv::OpBitwiseAnd:
case spv::OpLogicalAnd:
dst.emplace(i, As<SIMD::Float>(As<SIMD::UInt>(lhs) & As<SIMD::UInt>(rhs)));
break;
default:
UNIMPLEMENTED("Unhandled binary operator %s", OpcodeName(insn.opcode()).c_str());
}
}
}
void SpirvShader::emitEpilog(SpirvRoutine *routine) const
{
for (auto insn : *this)
......
......@@ -45,6 +45,7 @@ namespace sw
using Float = rr::Float4;
using Int = rr::Int4;
using UInt = rr::UInt4;
}
// Incrementally constructed complex bundle of rvalues
......@@ -390,6 +391,8 @@ namespace sw
void EmitCompositeInsert(InsnIterator insn, SpirvRoutine *routine) const;
void EmitCompositeExtract(InsnIterator insn, SpirvRoutine *routine) const;
void EmitVectorShuffle(InsnIterator insn, SpirvRoutine *routine) const;
void EmitUnaryOp(InsnIterator insn, SpirvRoutine *routine) const;
void EmitBinaryOp(InsnIterator insn, SpirvRoutine *routine) const;
// OpcodeName returns the name of the opcode op.
// If NDEBUG is defined, then OpcodeName will only return the numerical code.
......
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