Commit bb8c8e21 by Ben Clayton

SpirvShader: Implement SMod.

Test: *smod* Bug: b/126873455 Change-Id: If946e72d23aa9386b85cffe96b02ab63195f0a24 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26549Tested-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 22570f7f
...@@ -302,6 +302,7 @@ namespace sw ...@@ -302,6 +302,7 @@ namespace sw
case spv::OpFUnordLessThanEqual: case spv::OpFUnordLessThanEqual:
case spv::OpFOrdGreaterThanEqual: case spv::OpFOrdGreaterThanEqual:
case spv::OpFUnordGreaterThanEqual: case spv::OpFUnordGreaterThanEqual:
case spv::OpSMod:
case spv::OpUMod: case spv::OpUMod:
case spv::OpIEqual: case spv::OpIEqual:
case spv::OpINotEqual: case spv::OpINotEqual:
...@@ -943,7 +944,7 @@ namespace sw ...@@ -943,7 +944,7 @@ namespace sw
// TODO: what to do about zero-slot objects? // TODO: what to do about zero-slot objects?
if (pointeeTy.sizeInComponents > 0) if (pointeeTy.sizeInComponents > 0)
{ {
routine->createLvalue(insn.word(2), pointeeTy.sizeInComponents); routine->createLvalue(resultId, pointeeTy.sizeInComponents);
} }
break; break;
} }
...@@ -1081,6 +1082,7 @@ namespace sw ...@@ -1081,6 +1082,7 @@ namespace sw
case spv::OpFUnordLessThanEqual: case spv::OpFUnordLessThanEqual:
case spv::OpFOrdGreaterThanEqual: case spv::OpFOrdGreaterThanEqual:
case spv::OpFUnordGreaterThanEqual: case spv::OpFUnordGreaterThanEqual:
case spv::OpSMod:
case spv::OpUMod: case spv::OpUMod:
case spv::OpIEqual: case spv::OpIEqual:
case spv::OpINotEqual: case spv::OpINotEqual:
...@@ -1541,6 +1543,22 @@ namespace sw ...@@ -1541,6 +1543,22 @@ namespace sw
case spv::OpUDiv: case spv::OpUDiv:
dst.emplace(i, As<SIMD::Float>(As<SIMD::UInt>(lhs) / As<SIMD::UInt>(rhs))); dst.emplace(i, As<SIMD::Float>(As<SIMD::UInt>(lhs) / As<SIMD::UInt>(rhs)));
break; break;
case spv::OpSMod:
{
auto a = As<SIMD::Int>(lhs);
auto b = As<SIMD::Int>(rhs);
auto mod = a % b;
// If a and b have opposite signs, the remainder operation takes
// the sign from a but OpSMod is supposed to take the sign of b.
// Adding b will ensure that the result has the correct sign and
// that it is still congruent to a modulo b.
//
// See also http://mathforum.org/library/drmath/view/52343.html
auto signDiff = CmpNEQ(CmpGE(a, SIMD::Int(0)), CmpGE(b, SIMD::Int(0)));
auto fixedMod = mod + (b & CmpNEQ(mod, SIMD::Int(0)) & signDiff);
dst.emplace(i, As<SIMD::Float>(fixedMod));
break;
}
case spv::OpUMod: case spv::OpUMod:
dst.emplace(i, As<SIMD::Float>(As<SIMD::UInt>(lhs) % As<SIMD::UInt>(rhs))); dst.emplace(i, As<SIMD::Float>(As<SIMD::UInt>(lhs) % As<SIMD::UInt>(rhs)));
break; break;
......
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