Add support for float remainder to interpreter
Change-Id: I267c99c8c36b1d39abe9cf196996db43edb2b839
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/212721
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLByteCode.h b/src/sksl/SkSLByteCode.h
index 0454a4b..df8b964 100644
--- a/src/sksl/SkSLByteCode.h
+++ b/src/sksl/SkSLByteCode.h
@@ -72,6 +72,7 @@
kPop,
// Followed by a 32 bit value containing the value to push
kPushImmediate,
+ kRemainderF,
kRemainderS,
kRemainderU,
// Followed by a byte indicating the number of slots being returned
diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp
index 086afa5..699fda2 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -277,7 +277,7 @@
case Token::Kind::PERCENT:
this->writeTypedInstruction(b.fLeft->fType, ByteCodeInstruction::kRemainderS,
ByteCodeInstruction::kRemainderU,
- ByteCodeInstruction::kInvalid);
+ ByteCodeInstruction::kRemainderF);
break;
case Token::Kind::PLUS:
this->writeTypedInstruction(b.fLeft->fType, ByteCodeInstruction::kAddI,
diff --git a/src/sksl/SkSLInterpreter.cpp b/src/sksl/SkSLInterpreter.cpp
index e0de1bd..f33cf42 100644
--- a/src/sksl/SkSLInterpreter.cpp
+++ b/src/sksl/SkSLInterpreter.cpp
@@ -160,6 +160,7 @@
case ByteCodeInstruction::kPushImmediate:
printf("pushimmediate %s", value_string(READ32()).c_str());
break;
+ case ByteCodeInstruction::kRemainderF: printf("remainderf"); break;
case ByteCodeInstruction::kRemainderS: printf("remainders"); break;
case ByteCodeInstruction::kRemainderU: printf("remainderu"); break;
case ByteCodeInstruction::kReturn: printf("return %d", READ8()); break;
@@ -350,6 +351,12 @@
case ByteCodeInstruction::kPushImmediate:
PUSH(Value((int) READ32()));
break;
+ case ByteCodeInstruction::kRemainderF: {
+ float b = POP().fFloat;
+ Value* a = &TOP();
+ *a = Value(fmodf(a->fFloat, b));
+ break;
+ }
BINARY_OP(kRemainderS, int32_t, fSigned, %)
BINARY_OP(kRemainderU, uint32_t, fUnsigned, %)
case ByteCodeInstruction::kReturn: {
@@ -481,6 +488,19 @@
VECTOR_BINARY_OP(kMultiplyS, int32_t, fSigned, *)
VECTOR_BINARY_OP(kMultiplyU, uint32_t, fUnsigned, *)
VECTOR_BINARY_OP(kMultiplyF, float, fFloat, *)
+ case ByteCodeInstruction::kRemainderF: {
+ Value result[VECTOR_MAX];
+ for (int i = count - 1; i >= 0; --i) {
+ result[i] = POP();
+ }
+ for (int i = count - 1; i >= 0; --i) {
+ result[i] = fmodf(POP().fFloat, result[i].fFloat);
+ }
+ for (int i = 0; i < count; ++i) {
+ PUSH(result[i]);
+ }
+ break;
+ }
VECTOR_BINARY_OP(kRemainderS, int32_t, fSigned, %)
VECTOR_BINARY_OP(kRemainderU, uint32_t, fUnsigned, %)
case ByteCodeInstruction::kStore: {
diff --git a/tests/SkSLInterpreterTest.cpp b/tests/SkSLInterpreterTest.cpp
index 6953397..d00469c 100644
--- a/tests/SkSLInterpreterTest.cpp
+++ b/tests/SkSLInterpreterTest.cpp
@@ -133,6 +133,10 @@
}
DEF_TEST(SkSLInterpreterRemainder, r) {
+ test(r, "void main(inout half4 color) { color.r = color.r % color.g; }", 3.125, 2, 0, 0,
+ 1.125, 2, 0, 0);
+ test(r, "void main(inout half4 color) { color %= half4(1, 2, 3, 4); }", 9.5, 9.5, 9.5, 9.5,
+ 0.5, 1.5, 0.5, 1.5);
test(r, "void main(inout half4 color) { int a = 8; int b = 3; a %= b; color.r = a; }", 0, 0, 0,
0, 2, 0, 0, 0);
test(r, "void main(inout half4 color) { int a = 8; int b = 3; color.r = a % b; }", 0, 0, 0, 0,