SkSL interpreter intrinsics

Bug: skia:
Change-Id: I418fb05444f9c1ee076ace41a24072c4a5e7ef6c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/214691
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp
index e213594..b53fe47 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -10,6 +10,17 @@
 
 namespace SkSL {
 
+ByteCodeGenerator::ByteCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors,
+                  ByteCode* output)
+    : INHERITED(program, errors, nullptr)
+    , fContext(*context)
+    , fOutput(output) {
+    fIntrinsics["cos"]  = ByteCodeInstruction::kCos;
+    fIntrinsics["sin"]  = ByteCodeInstruction::kSin;
+    fIntrinsics["sqrt"] = ByteCodeInstruction::kSqrt;
+    fIntrinsics["tan"]  = ByteCodeInstruction::kTan;
+}
+
 static int slot_count(const Type& type) {
     return type.columns() * type.rows();
 }
@@ -331,15 +342,15 @@
             if (inCategory == TypeCategory::kFloat) {
                 SkASSERT(outCategory == TypeCategory::kSigned ||
                          outCategory == TypeCategory::kUnsigned);
-                this->write(vector_instruction(ByteCodeInstruction::kFloatToInt,
+                this->write(vector_instruction(ByteCodeInstruction::kConvertFtoI,
                                                c.fType.columns()));
             } else if (outCategory == TypeCategory::kFloat) {
                 if (inCategory == TypeCategory::kSigned) {
-                    this->write(vector_instruction(ByteCodeInstruction::kSignedToFloat,
+                    this->write(vector_instruction(ByteCodeInstruction::kConvertStoF,
                                                    c.fType.columns()));
                 } else {
                     SkASSERT(inCategory == TypeCategory::kUnsigned);
-                    this->write(vector_instruction(ByteCodeInstruction::kUnsignedToFloat,
+                    this->write(vector_instruction(ByteCodeInstruction::kConvertUtoF,
                                                    c.fType.columns()));
                 }
             } else {
@@ -384,7 +395,31 @@
     this->write32(Interpreter::Value((float) f.fValue).fUnsigned);
 }
 
+void ByteCodeGenerator::writeIntrinsicCall(const FunctionCall& c) {
+    auto found = fIntrinsics.find(c.fFunction.fName);
+    if (found == fIntrinsics.end()) {
+        fErrors.error(c.fOffset, "unsupported intrinsic function");
+        return;
+    }
+    switch (found->second) {
+        case ByteCodeInstruction::kCos:  // fall through
+        case ByteCodeInstruction::kSin:  // fall through
+        case ByteCodeInstruction::kSqrt: // fall through
+        case ByteCodeInstruction::kTan:
+            SkASSERT(c.fArguments.size() == 1);
+            this->write((ByteCodeInstruction) ((int) found->second +
+                        slot_count(c.fArguments[0]->fType) - 1));
+            break;
+        default:
+            SkASSERT(false);
+    }
+}
+
 void ByteCodeGenerator::writeFunctionCall(const FunctionCall& f) {
+    if (f.fFunction.fBuiltin) {
+        this->writeIntrinsicCall(f);
+        return;
+    }
     for (const auto& arg : f.fArguments) {
         this->writeExpression(*arg);
     }