Runtime spec file and generation

Move to generated headers for the runtime API so we can
track API changes and generate proper comments.  Will
also be able to generate coverage tests.

Change-Id: Iec9b7e6d1bd3f7369f4f5ad3383a09dd8e08ef50
diff --git a/api/gen_runtime.cpp b/api/gen_runtime.cpp
new file mode 100644
index 0000000..a545a2e
--- /dev/null
+++ b/api/gen_runtime.cpp
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <vector>
+#include <list>
+#include <string>
+
+using namespace std;
+
+FILE *gIn;
+FILE *gOut;
+
+class Func {
+public:
+    Func() {
+        mMinVersion = 0;
+        mMaxVersion = 0;
+    }
+
+    string mName;
+    int mMinVersion;
+    int mMaxVersion;
+
+    vector<vector<string> > mReplaceables;
+    vector<string> mArgs;
+    string mRet;
+    vector<string> mComment;
+    vector<string> mInline;
+
+};
+
+vector<Func *> gFuncs;
+
+bool getNextLine(FILE *in, string *s) {
+    s->clear();
+    while (1) {
+        int c = fgetc(in);
+        if (c == EOF) return s->size() != 0;
+        if (c == '\n') break;
+        s->push_back((char)c);
+    }
+    return true;
+}
+
+void trim(string *s, size_t start) {
+    if (start > 0) {
+        s->erase(0, start);
+    }
+
+    while (s->size() && (s->at(0) == ' ')) {
+        s->erase(0, 1);
+    }
+
+    size_t p = s->find_first_of("\n\r");
+    if (p != string::npos) {
+        s->erase(p);
+    }
+
+    while ((s->size() > 0) && (s->at(s->size()-1) == ' ')) {
+        s->erase(s->size() -1);
+    }
+}
+
+Func * scanFunction(FILE *in) {
+    Func *f = new Func();
+    bool modeComment = false;
+    bool modeInline = false;
+    size_t replacables = 0;
+
+    while (1) {
+        string s;
+        bool ret = getNextLine(in, &s);
+        if (!ret) break;
+
+        if (modeComment) {
+            if (!s.size() || (s[0] == ' ')) {
+                trim(&s, 0);
+                f->mComment.push_back(s);
+                continue;
+            } else {
+                modeComment = false;
+            }
+        }
+
+        if (modeInline) {
+            if (!s.size() || (s[0] == ' ')) {
+                trim(&s, 0);
+                f->mInline.push_back(s);
+                continue;
+            } else {
+                modeInline = false;
+            }
+        }
+
+        if (s[0] == '#') {
+            continue;
+        }
+
+        if (s.compare(0, 5, "name:") == 0) {
+            trim(&s, 5);
+            f->mName = s;
+            continue;
+        }
+
+        if (s.compare(0, 4, "arg:") == 0) {
+            trim(&s, 4);
+            f->mArgs.push_back(s);
+            continue;
+        }
+
+        if (s.compare(0, 4, "ret:") == 0) {
+            trim(&s, 4);
+            f->mRet = s;
+            continue;
+        }
+
+        if (s.compare(0, 4, "end:") == 0) {
+            return f;
+        }
+
+        if (s.compare(0, 8, "comment:") == 0) {
+            modeComment = true;
+            continue;
+        }
+
+        if (s.compare(0, 7, "inline:") == 0) {
+            modeInline = true;
+            continue;
+        }
+
+        if (s.compare(0, 8, "version:") == 0) {
+            trim(&s, 8);
+            sscanf(s.c_str(), "%i %i", &f->mMinVersion, &f->mMaxVersion);
+            continue;
+        }
+
+        if (s.compare(0, 8, "start:") == 0) {
+            continue;
+        }
+
+        if (s.compare(0, 2, "w:") == 0) {
+            vector<string> t;
+            if (s.find("1") != string::npos) {
+                t.push_back("");
+            }
+            if (s.find("2") != string::npos) {
+                t.push_back("2");
+            }
+            if (s.find("3") != string::npos) {
+                t.push_back("3");
+            }
+            if (s.find("4") != string::npos) {
+                t.push_back("4");
+            }
+            f->mReplaceables.push_back(t);
+            continue;
+        }
+
+        if (s.compare(0, 2, "t:") == 0) {
+            vector<string> t;
+            if (s.find("f16") != string::npos) {
+                t.push_back("half");
+            }
+            if (s.find("f32") != string::npos) {
+                t.push_back("float");
+            }
+            if (s.find("f64") != string::npos) {
+                t.push_back("double");
+            }
+            if (s.find("i8") != string::npos) {
+                t.push_back("char");
+            }
+            if (s.find("u8") != string::npos) {
+                t.push_back("uchar");
+            }
+            if (s.find("i16") != string::npos) {
+                t.push_back("short");
+            }
+            if (s.find("u16") != string::npos) {
+                t.push_back("ushort");
+            }
+            if (s.find("i32") != string::npos) {
+                t.push_back("int");
+            }
+            if (s.find("u32") != string::npos) {
+                t.push_back("uint");
+            }
+            if (s.find("i64") != string::npos) {
+                t.push_back("long");
+            }
+            if (s.find("u64") != string::npos) {
+                t.push_back("ulong");
+            }
+            f->mReplaceables.push_back(t);
+            continue;
+        }
+
+        if (s.size() == 0) {
+            // eat empty line
+            continue;
+        }
+
+        printf("Error, line:\n");
+        printf("  %s\n", s.c_str());
+    }
+
+    delete f;
+    return NULL;
+}
+
+string stringReplace(string s, string match, string rep) {
+    while(1) {
+        size_t p = s.find(match);
+        if (p == string::npos) break;
+
+        s.erase(p, match.size());
+        s.insert(p, rep);
+    }
+    return s;
+}
+
+string stringExpand(string s, const Func *f, int i1, int i2, int i3, int i4) {
+    if (f->mReplaceables.size() > 0) {
+        s = stringReplace(s, "#1", f->mReplaceables[0][i1]);
+    }
+    if (f->mReplaceables.size() > 1) {
+        s = stringReplace(s, "#2", f->mReplaceables[1][i2]);
+    }
+    if (f->mReplaceables.size() > 2) {
+        s = stringReplace(s, "#3", f->mReplaceables[2][i3]);
+    }
+    if (f->mReplaceables.size() > 3) {
+        s = stringReplace(s, "#4", f->mReplaceables[3][i4]);
+    }
+    return s;
+}
+
+void writeHeaderFunc(FILE *o, const Func *f, int i1, int i2, int i3, int i4) {
+    string s;
+
+    if (f->mMinVersion || f->mMaxVersion) {
+        if (f->mMaxVersion) {
+            fprintf(o, "#if (defined(RS_VERSION) && (RS_VERSION >= %i) && (RS_VERSION < %i))\n",
+                    f->mMinVersion, f->mMaxVersion);
+        } else {
+            fprintf(o, "#if (defined(RS_VERSION) && (RS_VERSION >= %i))\n",
+                    f->mMinVersion);
+        }
+    }
+
+    fprintf(o, "/*\n");
+    for (size_t ct=0; ct < f->mComment.size(); ct++) {
+        s = stringExpand(f->mComment[ct], f, i1, i2, i3, i4);
+        if (s.size()) {
+            fprintf(o, " * %s\n", s.c_str());
+        } else {
+            fprintf(o, " *\n");
+        }
+    }
+    fprintf(o, " *\n");
+    if (f->mMinVersion || f->mMaxVersion) {
+        if (f->mMaxVersion) {
+            fprintf(o, " * Suppored by API versions %i - %i\n",
+                    f->mMinVersion, f->mMaxVersion);
+        } else {
+            fprintf(o, " * Supported by API versions %i and newer.\n",
+                    f->mMinVersion);
+        }
+    }
+
+    fprintf(o, " */\n");
+
+    s.clear();
+    s += "extern ";
+    s += f->mRet;
+    s += " __attribute__((const, overloadable))";
+    s += f->mName;
+    s += "(";
+    if (f->mArgs.size()) {
+        s += f->mArgs[0];
+    }
+    for (size_t ct=1; ct < f->mArgs.size(); ct++) {
+        s += ", ";
+        s += f->mArgs[0];
+    }
+    s += ");";
+    s = stringExpand(s, f, i1, i2, i3, i4);
+    fprintf(o, "%s\n", s.c_str());
+
+
+    if (f->mMinVersion || f->mMaxVersion) {
+        fprintf(o, "#endif\n");
+    }
+
+    fprintf(o, "\n", s.c_str());
+}
+
+
+void writeHeaderFuncs(FILE *o, const Func *f) {
+    switch(f->mReplaceables.size()) {
+    case 0:
+        writeHeaderFunc(o, f, -1, -1, -1, -1);
+        break;
+    case 1:
+        for (size_t i1 = 0; i1 < f->mReplaceables[0].size(); i1++) {
+            writeHeaderFunc(o, f, i1, -1, -1, -1);
+        }
+        break;
+    case 2:
+        for (size_t i2 = 0; i2 < f->mReplaceables[1].size(); i2++) {
+            for (size_t i1 = 0; i1 < f->mReplaceables[0].size(); i1++) {
+                writeHeaderFunc(o, f, i1, i2, -1, -1);
+            }
+        }
+        break;
+    case 3:
+        for (size_t i3 = 0; i3 < f->mReplaceables[2].size(); i3++) {
+            for (size_t i2 = 0; i2 < f->mReplaceables[1].size(); i2++) {
+                for (size_t i1 = 0; i1 < f->mReplaceables[0].size(); i1++) {
+                    writeHeaderFunc(o, f, i1, i2, i3, -1);
+                }
+            }
+        }
+        break;
+    case 4:
+        for (size_t i4 = 0; i4 < f->mReplaceables[3].size(); i4++) {
+            for (size_t i3 = 0; i3 < f->mReplaceables[2].size(); i3++) {
+                for (size_t i2 = 0; i2 < f->mReplaceables[1].size(); i2++) {
+                    for (size_t i1 = 0; i1 < f->mReplaceables[0].size(); i1++) {
+                        writeHeaderFunc(o, f, i1, i2, i3, i4);
+                    }
+                }
+            }
+        }
+        break;
+    }
+}
+
+
+
+int main(int argc, char* argv[])
+{
+    const char *inpath = "runtime.spec";
+    const char *outpath = "rs_core_math.rsh";
+
+    gIn = fopen(inpath, "rt");
+    if (!gIn) {
+        printf("Error opening input file: %s", inpath);
+        return -1;
+    }
+
+    while (1) {
+        Func *f = scanFunction(gIn);
+        if (f != NULL) {
+            gFuncs.push_back(f);
+        } else {
+            break;
+        }
+    }
+
+    gOut = fopen(outpath, "wt");
+    if (!gOut) {
+        printf("Error opening output file: %s", outpath);
+        return -1;
+    }
+
+    for (size_t ct=0; ct < gFuncs.size(); ct++) {
+        writeHeaderFuncs(gOut, gFuncs[ct]);
+    }
+
+    fclose (gIn);
+    fclose (gOut);
+
+    printf("%i Functions processed.\n", (int)gFuncs.size());
+
+    return 0;
+}
+
+
diff --git a/api/runtime.spec b/api/runtime.spec
new file mode 100644
index 0000000..65e29ea
--- /dev/null
+++ b/api/runtime.spec
@@ -0,0 +1,1301 @@
+#
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+start:
+w: 2, 3, 4
+t: u8, u16, u32, u64, i8, i16, i32, i64, f32, f64
+t: u8, u16, u32, u64, i8, i16, i32, i64, f32, f64
+name: convert_uchar#1
+arg: #2#1
+ret: #3#1
+comment:
+ Component wise conversion from #2#1 to #3#1
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: acos
+ret: #2#1
+arg: #2#1
+comment:
+ acos
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: acosh
+ret: #2#1
+arg: #2#1
+comment:
+ acosh
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: acospi
+ret: #2#1
+arg: #2#1
+comment:
+ acospi
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: asin
+ret: #2#1
+arg: #2#1
+comment:
+ asin
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: asinh
+ret: #2#1
+arg: #2#1
+comment:
+ asinh
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: asinpi
+ret: #2#1
+arg: #2#1
+comment:
+ Return the inverse sine divided by PI.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: atan
+ret: #2#1
+arg: #2#1
+comment:
+ Return the inverse tangent.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: atan2
+ret: #2#1
+arg: #2#1 y
+arg: #2#1 x
+comment:
+ Return the inverse tangent of y / x.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: atanh
+ret: #2#1
+arg: #2#1
+comment:
+ Return the inverse hyperbolic tangent.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: atanpi
+ret: #2#1
+arg: #2#1
+comment:
+ Return the inverse tangent divided by PI.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: atan2pi
+ret: #2#1
+arg: #2#1 y
+arg: #2#1 x
+comment:
+ Return the inverse tangent of y / x, divided by PI.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: cbrt
+ret: #2#1
+arg: #2#1
+comment:
+ Return the cube root.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: ceil
+ret: #2#1
+arg: #2#1
+comment:
+ Return the smallest integer not less than a value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: copysign
+ret: #2#1
+arg: #2#1 x
+arg: #2#1 y
+comment:
+ Copy the sign bit from y to x.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: cos
+ret: #2#1
+arg: #2#1
+comment:
+ Return the cosine.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: cosh
+ret: #2#1
+arg: #2#1
+comment:
+ Return the hypebolic cosine.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: cospi
+ret: #2#1
+arg: #2#1
+comment:
+ Return the cosine of the value * PI.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: erfc
+ret: #2#1
+arg: #2#1
+comment:
+ Return the complementary error function.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: erf
+ret: #2#1
+arg: #2#1
+comment:
+ Return the error function.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: exp
+ret: #2#1
+arg: #2#1
+comment:
+ Return e ^ value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: exp2
+ret: #2#1
+arg: #2#1
+comment:
+ Return 2 ^ value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: exp10
+ret: #2#1
+arg: #2#1
+comment:
+ Return 10 ^ value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: expm1
+ret: #2#1
+arg: #2#1
+comment:
+ Return (e ^ value) - 1.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: fabs
+ret: #2#1
+arg: #2#1
+comment:
+ Return the absolute value of a value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: fdim
+ret: #2#1
+arg: #2#1
+comment:
+ Return the positive difference between two values.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: floor
+ret: #2#1
+arg: #2#1
+comment:
+ Return the smallest integer not greater than a value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: fma
+ret: #2#1
+arg: #2#1 a
+arg: #2#1 b
+arg: #2#1 c
+comment:
+ Return (a * b) + c.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: fmax
+ret: #2#1
+arg: #2#1 x
+arg: #2#1 y
+comment:
+ Return (x < y ? y : x)
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: fmax
+ret: #2#1
+arg: #2#1 x
+arg: #2 y
+comment:
+ Return (x < y ? y : x)
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: fmin
+ret: #2#1
+arg: #2#1 x
+arg: #2#1 y
+comment:
+ Return (x > y ? y : x)
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: fmin
+ret: #2#1
+arg: #2#1 x
+arg: #2 y
+comment:
+ Return (x > y ? y : x)
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: fmod
+ret: #2#1
+arg: #2#1 x
+arg: #2#1 y
+comment:
+ Return the remainder from x / y
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: fract
+ret: #2#1
+arg: #2#1 v
+arg: #2#1 *iptr
+comment:
+ Return fractional part of v
+
+ @param iptr  iptr[0] will be set to the floor of the input value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: fract
+ret: #2#1
+arg: #2#1 v
+comment:
+ Return fractional part of v
+inline:
+    #2#1 unused;
+    return fract(v, &unused);
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: frexp
+ret: #2#1
+arg: #2#1 v
+arg: int#1 *iptr
+comment:
+ Return the mantissa and place the exponent into iptr[0]
+
+ @param v Supports float, float2, float3, float4.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: hypot
+ret: #2#1
+arg: #2#1 x
+arg: #2#1 y
+comment:
+ Return sqrt(x*x + y*y)
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: ilogb
+ret: #2#1
+arg: #2#1
+comment:
+ Return the integer exponent of a value
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: ilogb
+ret: #2#1
+arg: #2#1
+arg: int#1
+comment:
+ Return (x * 2^y)
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: ilogb
+ret: #2#1
+arg: #2#1
+arg: int
+comment:
+ Return (x * 2^y)
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: lgamma
+ret: #2#1
+arg: #2#1 x
+comment:
+ Return the log gamma and sign
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: lgamma
+ret: #2#1
+arg: #2#1 x
+arg: int#1 *y
+comment:
+ Return the log gamma and sign
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: log
+ret: #2#1
+arg: #2#1 x
+comment:
+ Return the natural logarithm.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: log2
+ret: #2#1
+arg: #2#1 x
+comment:
+ Return the base 2 logarithm.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: log10
+ret: #2#1
+arg: #2#1 x
+comment:
+ Return the base 10 logarithm.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: log1p
+ret: #2#1
+arg: #2#1 x
+comment:
+ Return the natural logarithm of (v + 1.0f)
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: logb
+ret: #2#1
+arg: #2#1 x
+comment:
+ Compute the exponent of the value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: mad
+ret: #2#1
+arg: #2#1 a
+arg: #2#1 b
+arg: #2#1 c
+comment:
+ Compute (a * b) + c
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: modf
+ret: #2#1
+arg: #2#1 x
+arg: #2#1 *iret
+comment:
+ Return the integral and fractional components of a number.
+
+ @param x Source value
+ @param iret iret[0] will be set to the integral portion of the number.
+ @return The floating point portion of the value.
+version: 9
+end:
+
+start:
+w: 1
+t: f32
+name: nan
+ret: #2#1
+arg: uint#1
+comment:
+ generate a nan
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: nextafter
+ret: #2#1
+arg: #2#1 x
+arg: #2#1 y
+comment:
+ Return the next floating point number from x towards y.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: pow
+ret: #2#1
+arg: #2#1 x
+arg: #2#1 y
+comment:
+ Return x ^ y.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: pown
+ret: #2#1
+arg: #2#1 x
+arg: int#1 y
+comment:
+ Return x ^ y.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: powr
+ret: #2#1
+arg: #2#1 x
+arg: #2#1 y
+comment:
+ Return x ^ y.
+ y must be > 0
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: remainder
+ret: #2#1
+arg: #2#1 x
+arg: #2#1 y
+comment:
+ Return round x/y to the nearest integer then compute the remander.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: remquo
+ret: #2#1
+arg: #2#1
+arg: #2#1
+arg: int#1 *
+comment:
+ todo
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: rint
+ret: #2#1
+arg: #2#1
+comment:
+ Round to the nearest integral value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: rootn
+ret: #2#1
+arg: #2#1 v
+arg: int#1 n
+comment:
+ Compute the Nth root of a value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: round
+ret: #2#1
+arg: #2#1
+comment:
+ Round to the nearest integral value.  Half values are rounded away from zero.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: rsqrt
+ret: #2#1
+arg: #2#1
+comment:
+ Return (1 / sqrt(value)).
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: sqrt
+ret: #2#1
+arg: #2#1
+comment:
+ Return the square root of a value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: sin
+ret: #2#1
+arg: #2#1
+comment:
+ Return the sine of a value specified in radians.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: sincos
+ret: #2#1
+arg: #2#1 v
+arg: #2#1 *cosptr
+comment:
+ Return the sine and cosine of a value.
+
+ @return sine
+ @param v The incoming value in radians
+ @param *cosptr cosptr[0] will be set to the cosine value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: sinh
+ret: #2#1
+arg: #2#1
+comment:
+ Return the hyperbolic sine of a value specified in radians.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: sinpi
+ret: #2#1
+arg: #2#1
+comment:
+ Return the sin(v * PI).
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: tan
+ret: #2#1
+arg: #2#1
+comment:
+ Return the tangent of a value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: tanh
+ret: #2#1
+arg: #2#1
+comment:
+ Return the hyperbolic tangent of a value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: tanpi
+ret: #2#1
+arg: #2#1
+comment:
+ Return tan(v * PI)
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: tgamma
+ret: #2#1
+arg: #2#1
+comment:
+ Compute the gamma function of a value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: trunc
+ret: #2#1
+arg: #2#1
+comment:
+ ound to integral using truncation.
+version: 9
+end:
+
+# int functions
+
+start:
+w: 1, 2, 3, 4
+t: i8, i16, i32
+name: abs
+ret: #2#1
+arg: #2#1 value
+comment:
+ Return the absolute value of a value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: u8, u16, u32, i8, i16, i32
+name: clz
+ret: #2#1
+arg: #2#1 value
+comment:
+ Return the number of leading 0-bits in a value.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: min
+ret: #2#1
+arg: #2#1
+arg: #2#1
+comment:
+ Return the minimum value from two arguments
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: i8 i16 i32 u8 u16 u32
+name: min
+ret: #2#1
+arg: #2#1 v1
+arg: #2#1 v2
+comment:
+ Return the minimum value from two arguments
+inline:
+ return (v1 < v2 ? v1 : v2);
+version: 9 19
+end:
+
+start:
+w: 1, 2, 3, 4
+t: i8 i16 i32 i64 u8 u16 u32 u64
+name: min
+ret: #2#1
+arg: #2#1 v1
+arg: #2#1 v2
+comment:
+ Return the minimum value from two arguments
+version: 19
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: max
+ret: #2#1
+arg: #2#1
+arg: #2#1
+comment:
+ Return the maximum value from two arguments
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: i8 i16 i32 u8 u16 u32
+name: max
+ret: #2#1
+arg: #2#1 v1
+arg: #2#1 v2
+comment:
+ Return the maximum value from two arguments
+inline:
+ return (v1 < v2 ? v1 : v2);
+version: 9 19
+end:
+
+start:
+w: 1, 2, 3, 4
+t: i8 i16 i32 i64 u8 u16 u32 u64
+name: max
+ret: #2#1
+arg: #2#1 v1
+arg: #2#1 v2
+comment:
+ Return the maximum value from two arguments
+version: 19
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: clamp
+ret: #2#1
+arg: #2#1 value
+arg: #2#1 min_value
+arg: #2#1 max_value
+comment:
+ Clamp a value to a specified high and low bound.
+
+ @param amount value to be clamped.  Supports 1,2,3,4 components
+ @param min_value Lower bound, must be scalar or matching vector.
+ @param max_value High bound, must match type of low
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: clamp
+ret: #2#1
+arg: #2#1 value
+arg: #2 min_value
+arg: #2 max_value
+comment:
+ Clamp a value to a specified high and low bound.
+
+ @param amount value to be clamped.  Supports 1,2,3,4 components
+ @param min_value Lower bound, must be scalar or matching vector.
+ @param max_value High bound, must match type of low
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: u8, u16, u32, u64, i8, i16, i32, i64
+name: clamp
+ret: #2#1
+arg: #2#1 value
+arg: #2#1 min_value
+arg: #2#1 max_value
+comment:
+ Clamp a value to a specified high and low bound.
+
+ @param amount value to be clamped.  Supports 1,2,3,4 components
+ @param min_value Lower bound, must be scalar or matching vector.
+ @param max_value High bound, must match type of low
+version: 19
+end:
+
+start:
+w: 1, 2, 3, 4
+t: u8, u16, u32, u64, i8, i16, i32, i64
+name: clamp
+ret: #2#1
+arg: #2#1 value
+arg: #2 min_value
+arg: #2 max_value
+comment:
+ Clamp a value to a specified high and low bound.
+
+ @param amount value to be clamped.  Supports 1,2,3,4 components
+ @param min_value Lower bound, must be scalar or matching vector.
+ @param max_value High bound, must match type of low
+version: 19
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: degrees
+ret: #2#1
+arg: #2#1 value
+comment:
+ Convert from radians to degrees.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: mix
+ret: #2#1
+arg: #2#1 start
+arg: #2#1 stop
+arg: #2#1 amount
+comment:
+ return start + ((stop - start) * amount)
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: mix
+ret: #2#1
+arg: #2#1 start
+arg: #2#1 stop
+arg: #2 amount
+comment:
+ return start + ((stop - start) * amount)
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: radians
+ret: #2#1
+arg: #2#1 value
+comment:
+ Convert from degrees to radians.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: step
+ret: #2#1
+arg: #2#1 value
+comment:
+ if (v < edge)
+     return 0.f;
+ else
+     return 1.f;
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: step
+ret: #2#1
+arg: #2 edge
+arg: #2 v
+comment:
+ if (v < edge)
+     return 0.f;
+ else
+     return 1.f;
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: sign
+ret: #2#1
+arg: #2 v
+comment:
+ Return the sign of a value.
+
+ if (v < 0) return -1.f;
+ else if (v > 0) return 1.f;
+ else return 0.f;
+version: 9
+end:
+
+start:
+w: 3, 4
+t: f32
+name: cross
+ret: #2#1
+arg: #2#1 lhs
+arg: #2#1 rhs
+comment:
+ Compute the cross product of two vectors.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: dot
+ret: #2
+arg: #2#1 lhs
+arg: #2#1 rhs
+comment:
+ Compute the dot product of two vectors.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: length
+ret: #2
+arg: #2#1 v
+comment:
+ Compute the length of a vector.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: distance
+ret: #2
+arg: #2#1 lhs
+arg: #2#1 rhs
+comment:
+ Compute the distance between two points.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: normalize
+ret: #2#1
+arg: #2#1 v
+comment:
+ Normalize a vector.
+version: 9
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: half_recip
+ret: #2#1
+arg: #2#1 v
+comment:
+ Return the approximate reciprocal of a value.
+version: 17
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: half_sqrt
+ret: #2#1
+arg: #2#1 v
+comment:
+ Return the approximate square root of a value.
+version: 17
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: half_rsqrt
+ret: #2#1
+arg: #2#1 v
+comment:
+ Return the approximate value of (1.f / sqrt(value)).
+version: 17
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: fast_length
+ret: #2
+arg: #2#1 v
+comment:
+ Compute the approximate length of a vector.
+version: 17
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: fast_distance
+ret: #2
+arg: #2#1 lhs
+arg: #2#1 rhs
+comment:
+ Compute the approximate distance between two points.
+version: 17
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: fast_normalize
+ret: #2#1
+arg: #2#1 v
+comment:
+ Approximately normalize a vector.
+version: 17
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: native_exp
+ret: #2#1
+arg: #2#1 v
+comment:
+ Fast approximate exp
+ valid for inputs -86.f to 86.f
+ Max 8192 ulps of error
+version: 18
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: native_exp2
+ret: #2#1
+arg: #2#1 v
+comment:
+ Fast approximate exp2
+ valid for inputs -125.f to 125.f
+ Max 8192 ulps of error
+version: 18
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: native_exp10
+ret: #2#1
+arg: #2#1 v
+comment:
+ Fast approximate exp10
+ valid for inputs -37.f to 37.f
+ Max 8192 ulps of error
+version: 18
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: native_log
+ret: #2#1
+arg: #2#1 v
+comment:
+ Fast approximate log
+version: 18
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: native_log2
+ret: #2#1
+arg: #2#1 v
+comment:
+ Fast approximate log2
+version: 18
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: native_log10
+ret: #2#1
+arg: #2#1 v
+comment:
+ Fast approximate log10
+version: 18
+end:
+
+start:
+w: 1, 2, 3, 4
+t: f32
+name: native_powr
+ret: #2#1
+arg: #2#1 v
+arg: #2#1 y
+comment:
+ Fast approximate v ^ y
+version: 18
+end:
+
+