summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-09-01 10:01:36 -0700
committerGitHub <noreply@github.com>2022-09-01 10:01:36 -0700
commit1f3130055956dbe441f7fc6849b189624a05f7df (patch)
tree8b07682fbae53b0cf17af7ad76812111719e76f4 /source
parent4a94473eb34376dd8474f8ca3f2834b5c1daac14 (diff)
Public interface for arithmetic types in stdlib. (#2389)
Diffstat (limited to 'source')
-rw-r--r--source/slang/core.meta.slang270
-rw-r--r--source/slang/slang-stdlib.cpp42
2 files changed, 266 insertions, 46 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index 42295eeca..c0c8c84f6 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -398,6 +398,9 @@ void __store<T>(Ptr<T> ptr, T val);
__intrinsic_op($(kIROp_getElementPtr))
Ptr<T> __getElementPtr<T>(Ptr<T> ptr, int index);
+__intrinsic_op($(kIROp_getElementPtr))
+Ptr<T> __getElementPtr<T>(Ptr<T> ptr, int64_t index);
+
__generic<T>
__intrinsic_op($(kIROp_Less))
bool operator<(Ptr<T> p1, Ptr<T> p2);
@@ -429,8 +432,8 @@ extension bool
__intrinsic_op($(kIROp_CastPtrToBool))
__init(Ptr<T> ptr);
- static bool maxValue = true;
- static bool minValue = false;
+ static const bool maxValue = true;
+ static const bool minValue = false;
}
extension uint64_t
@@ -439,8 +442,8 @@ extension uint64_t
__intrinsic_op($(kIROp_Construct))
__init(Ptr<T> ptr);
- static uint64_t maxValue = 0xFFFFFFFFFFFFFFFFULL;
- static uint64_t minValue = 0;
+ static const uint64_t maxValue = 0xFFFFFFFFFFFFFFFFULL;
+ static const uint64_t minValue = 0;
}
extension int64_t
@@ -449,8 +452,8 @@ extension int64_t
__intrinsic_op($(kIROp_Construct))
__init(Ptr<T> ptr);
- static int64_t maxValue = 0x7FFFFFFFFFFFFFFFLL;
- static int64_t minValue = -0x8000000000000000LL;
+ static const int64_t maxValue = 0x7FFFFFFFFFFFFFFFLL;
+ static const int64_t minValue = -0x8000000000000000LL;
}
__generic<T>
@@ -555,50 +558,59 @@ __intrinsic_type($(kIROp_DynamicType))
struct __Dynamic
{};
+extension half
+{
+ static const half maxValue = half(65504);
+ static const half minValue = half(-65504);
+}
+
extension float
{
- static float maxValue = 340282346638528859811704183484516925440.0f;
+ static const float maxValue = 340282346638528859811704183484516925440.0f;
+ static const float minValue = -340282346638528859811704183484516925440.0f;
+
}
extension double
{
- static double maxValue = 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0;
+ static const double maxValue = 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0;
+ static const double minValue = -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0;
}
extension int
{
- static int maxValue = 2147483647;
- static int minValue = -2147483648;
+ static const int maxValue = 2147483647;
+ static const int minValue = -2147483648;
}
extension uint
{
- static uint maxValue = 4294967295;
- static uint minValue = 0;
+ static const uint maxValue = 4294967295;
+ static const uint minValue = 0;
}
extension int8_t
{
- static int8_t maxValue = 127;
- static int8_t minValue = -128;
+ static const int8_t maxValue = 127;
+ static const int8_t minValue = -128;
}
-extension uint16_t
+extension uint8_t
{
- static uint16_t maxValue = 255;
- static uint16_t minValue = 0;
+ static const uint8_t maxValue = 255;
+ static const uint8_t minValue = 0;
}
-extension int16_t
+extension uint16_t
{
- static int16_t maxValue = 32767;
- static int16_t minValue = -32768;
+ static const uint16_t maxValue = 65535;
+ static const uint16_t minValue = 0;
}
-extension uint16_t
+extension int16_t
{
- static uint16_t maxValue = 65535;
- static uint16_t minValue = 0;
+ static const int16_t maxValue = 32767;
+ static const int16_t minValue = -32768;
}
/// An `N` component vector with elements of type `T`.
@@ -1795,6 +1807,7 @@ for (auto op : intrinsicUnaryOps)
// scalar version
sb << "__prefix __intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << type.name << " value);\n";
+ sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " __" << op.funcName << "(" << type.name << " value);\n";
// vector version
sb << "__generic<let N : int> ";
@@ -1939,6 +1952,7 @@ for (auto op : intrinsicBinaryOps)
// scalar version
sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << leftType << " left, " << rightType << " right);\n";
+ sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " __" << op.funcName << "(" << leftType << " left, " << rightType << " right);\n";
// vector version
sb << "__generic<let N : int> ";
@@ -2041,11 +2055,12 @@ for (auto op : intrinsicBinaryOps)
static const struct ShiftOpInfo
{
char const* name;
+ char const* funcName;
int op;
} kShiftOps[] =
{
- { "<<", kIROp_Lsh },
- { ">>", kIROp_Rsh },
+ { "<<", "shl", kIROp_Lsh },
+ { ">>", "shr", kIROp_Rsh },
};
for(auto info : kShiftOps) {
}}}}
@@ -2055,6 +2070,10 @@ __intrinsic_op($(info.op))
L operator$(info.name)(L left, R right);
__generic<L: __BuiltinIntegerType, R: __BuiltinIntegerType>
+__intrinsic_op($(info.op))
+L __$(info.funcName)(L left, R right);
+
+__generic<L: __BuiltinIntegerType, R: __BuiltinIntegerType>
[__unsafeForceInlineEarly]
L operator$(info.name)=(in out L left, R right)
{
@@ -2188,6 +2207,7 @@ ${{{{
//@ public:
+
// Bit cast
__generic<T, U>
[__unsafeForceInlineEarly]
@@ -2276,6 +2296,206 @@ bool operator!=(E left, E right);
//@ public:
+// public interfaces for generic arithmetic types.
+
+interface IComparable
+{
+ int compareTo(This other);
+}
+
+interface IArithmetic : IComparable
+{
+ This add(This other);
+ This sub(This other);
+ This mul(This other);
+ This div(This other);
+ This mod(This other);
+ This neg();
+ __init(int val);
+ static const This maxValue;
+ static const This minValue;
+}
+
+interface IInteger : IArithmetic
+{
+ This shl(int value);
+ This shr(int value);
+ This bitAnd(This other);
+ This bitOr(This other);
+ This bitXor(This other);
+ This bitNot();
+ int toInt();
+ int64_t toInt64();
+ uint toUInt();
+ uint64_t toUInt64();
+}
+
+interface IFloat : IArithmetic
+{
+ __init(float value);
+ float toFloat();
+}
+
+__generic<T : IComparable>
+[__unsafeForceInlineEarly]
+bool operator<(T v0, T v1)
+{
+ return v0.compareTo(v1) < 0;
+}
+__generic<T : IComparable>
+[__unsafeForceInlineEarly]
+bool operator>(T v0, T v1)
+{
+ return v0.compareTo(v1) > 0;
+}
+__generic<T : IComparable>
+[__unsafeForceInlineEarly]
+bool operator ==(T v0, T v1)
+{
+ return v0.compareTo(v1) == 0;
+}
+__generic<T : IComparable>
+[__unsafeForceInlineEarly]
+bool operator >=(T v0, T v1)
+{
+ return v0.compareTo(v1) >= 0;
+}
+__generic<T : IComparable>
+[__unsafeForceInlineEarly]
+bool operator <=(T v0, T v1)
+{
+ return v0.compareTo(v1) <= 0;
+}
+__generic<T : IComparable>
+[__unsafeForceInlineEarly]
+bool operator !=(T v0, T v1)
+{
+ return v0.compareTo(v1) != 0;
+}
+
+__generic<T : IArithmetic>
+[__unsafeForceInlineEarly]
+T operator +(T v0, T v1)
+{
+ return v0.add(v1);
+}
+
+__generic<T : IArithmetic>
+[__unsafeForceInlineEarly]
+T operator -(T v0, T v1)
+{
+ return v0.sub(v1);
+}
+
+__generic<T : IArithmetic>
+[__unsafeForceInlineEarly]
+T operator *(T v0, T v1)
+{
+ return v0.mul(v1);
+}
+
+__generic<T : IArithmetic>
+[__unsafeForceInlineEarly]
+T operator /(T v0, T v1)
+{
+ return v0.div(v1);
+}
+
+__generic<T : IArithmetic>
+[__unsafeForceInlineEarly]
+T operator %(T v0, T v1)
+{
+ return v0.mod(v1);
+}
+
+__generic<T : IArithmetic>
+[__unsafeForceInlineEarly]
+__prefix T operator -(T v0)
+{
+ return v0.neg();
+}
+__generic<T : IInteger>
+[__unsafeForceInlineEarly]
+T operator &(T v0, T v1)
+{
+ return v0.bitAnd(v1);
+}
+__generic<T : IInteger>
+[__unsafeForceInlineEarly]
+T operator |(T v0, T v1)
+{
+ return v0.bitOr(v1);
+}
+__generic<T : IInteger>
+[__unsafeForceInlineEarly]
+T operator ^(T v0, T v1)
+{
+ return v0.bitXor(v1);
+}
+__generic<T : IInteger>
+[__unsafeForceInlineEarly]
+__prefix T operator ~(T v0)
+{
+ return v0.bitNot();
+}
+
+// Provide implementations to public generic arithmetic interfaces for builtin types.
+
+${{{{
+// Code gen integer type implementations.
+
+for (int tt = 0; tt < kBaseTypeCount; ++tt)
+{
+ if (kBaseTypes[tt].flags & (SINT_MASK | UINT_MASK))
+ {
+}}}}
+extension $(kBaseTypes[tt].name) : IInteger
+{
+ [__unsafeForceInlineEarly] int compareTo(This other){return this-other;}
+ [__unsafeForceInlineEarly] This add(This other) { return __add(this, other); }
+ [__unsafeForceInlineEarly] This sub(This other) { return __sub(this, other); }
+ [__unsafeForceInlineEarly] This mul(This other) { return __mul(this, other); }
+ [__unsafeForceInlineEarly] This div(This other) { return __div(this, other); }
+ [__unsafeForceInlineEarly] This mod(This other) { return __irem(this, other); }
+ [__unsafeForceInlineEarly] This neg() { return __neg(this); }
+ [__unsafeForceInlineEarly] This shl(int other) { return __shl(this, other); }
+ [__unsafeForceInlineEarly] This shr(int other) { return __shr(this, other); }
+ [__unsafeForceInlineEarly] This bitAnd(This other) { return __add(this, other); }
+ [__unsafeForceInlineEarly] This bitOr(This other) { return __or(this, other); }
+ [__unsafeForceInlineEarly] This bitXor(This other) { return __xor(this, other); }
+ [__unsafeForceInlineEarly] This bitNot() { return __not(this); }
+ [__unsafeForceInlineEarly] int toInt() { return int(this); }
+ [__unsafeForceInlineEarly] int64_t toInt64() { return int64_t(this); }
+ [__unsafeForceInlineEarly] uint toUInt() { return uint(this); }
+ [__unsafeForceInlineEarly] uint64_t toUInt64() { return uint64_t(this); }
+}
+${{{{
+ }
+ else if (kBaseTypes[tt].flags & FLOAT_MASK)
+ {
+}}}}
+
+extension $(kBaseTypes[tt].name) : IFloat
+{
+ [__unsafeForceInlineEarly] static int __sign(This val)
+ {
+ return int(__leq(This(0),val)) - int(__leq(val,This(0)));
+ }
+
+ [__unsafeForceInlineEarly] int compareTo(This other) { return __sign(this-other); }
+ [__unsafeForceInlineEarly] This add(This other) { return __add(this, other); }
+ [__unsafeForceInlineEarly] This sub(This other) { return __sub(this, other); }
+ [__unsafeForceInlineEarly] This mul(This other) { return __mul(this, other); }
+ [__unsafeForceInlineEarly] This div(This other) { return __div(this, other); }
+ [__unsafeForceInlineEarly] This mod(This other) { return __frem(this, other); }
+ [__unsafeForceInlineEarly] This neg() { return __neg(this); }
+ [__unsafeForceInlineEarly] float toFloat() { return float(this); }
+}
+${{{{
+ }
+}
+}}}}
+
// Binding Attributes
__attributeTarget(DeclBase)
diff --git a/source/slang/slang-stdlib.cpp b/source/slang/slang-stdlib.cpp
index 1ead48cb8..ac952d2eb 100644
--- a/source/slang/slang-stdlib.cpp
+++ b/source/slang/slang-stdlib.cpp
@@ -189,32 +189,32 @@ namespace Slang
}
}
- struct IntrinsicOpInfo { IROp opCode; char const* opName; char const* interface; unsigned flags; };
+ struct IntrinsicOpInfo { IROp opCode; char const* funcName; char const* opName; char const* interface; unsigned flags; };
static const IntrinsicOpInfo intrinsicUnaryOps[] = {
- { kIROp_Neg, "-", "__BuiltinArithmeticType", ARITHMETIC_MASK },
- { kIROp_Not, "!", nullptr, BOOL_MASK | BOOL_RESULT },
- { kIROp_BitNot, "~", "__BuiltinIntegerType", INT_MASK },
+ { kIROp_Neg, "neg", "-", "__BuiltinArithmeticType", ARITHMETIC_MASK },
+ { kIROp_Not, "logicalNot", "!", nullptr, BOOL_MASK | BOOL_RESULT },
+ { kIROp_BitNot, "not", "~", "__BuiltinIntegerType", INT_MASK },
};
static const IntrinsicOpInfo intrinsicBinaryOps[] = {
- { kIROp_Add, "+", "__BuiltinArithmeticType", ARITHMETIC_MASK },
- { kIROp_Sub, "-", "__BuiltinArithmeticType", ARITHMETIC_MASK },
- { kIROp_Mul, "*", "__BuiltinArithmeticType", ARITHMETIC_MASK },
- { kIROp_Div, "/", "__BuiltinArithmeticType", ARITHMETIC_MASK },
- { kIROp_IRem, "%", "__BuiltinIntegerType", INT_MASK },
- { kIROp_FRem, "%", "__BuiltinFloatingPointType", FLOAT_MASK },
- { kIROp_And, "&&", nullptr, BOOL_MASK | BOOL_RESULT},
- { kIROp_Or, "||", nullptr, BOOL_MASK | BOOL_RESULT },
- { kIROp_BitAnd, "&", "__BuiltinLogicalType", LOGICAL_MASK },
- { kIROp_BitOr, "|", "__BuiltinLogicalType", LOGICAL_MASK },
- { kIROp_BitXor, "^", "__BuiltinLogicalType", LOGICAL_MASK },
- { kIROp_Eql, "==", "__BuiltinType", ANY_MASK | BOOL_RESULT },
- { kIROp_Neq, "!=", "__BuiltinType", ANY_MASK | BOOL_RESULT },
- { kIROp_Greater, ">", "__BuiltinArithmeticType", ARITHMETIC_MASK | BOOL_RESULT },
- { kIROp_Less, "<", "__BuiltinArithmeticType", ARITHMETIC_MASK | BOOL_RESULT },
- { kIROp_Geq, ">=", "__BuiltinArithmeticType", ARITHMETIC_MASK | BOOL_RESULT },
- { kIROp_Leq, "<=", "__BuiltinArithmeticType", ARITHMETIC_MASK | BOOL_RESULT },
+ {kIROp_Add, "add", "+", "__BuiltinArithmeticType", ARITHMETIC_MASK},
+ {kIROp_Sub, "sub", "-", "__BuiltinArithmeticType", ARITHMETIC_MASK},
+ {kIROp_Mul, "mul", "*", "__BuiltinArithmeticType", ARITHMETIC_MASK},
+ {kIROp_Div, "div", "/", "__BuiltinArithmeticType", ARITHMETIC_MASK},
+ {kIROp_IRem, "irem", "%", "__BuiltinIntegerType", INT_MASK},
+ {kIROp_FRem, "frem", "%", "__BuiltinFloatingPointType", FLOAT_MASK},
+ {kIROp_And, "logicalAnd", "&&", nullptr, BOOL_MASK | BOOL_RESULT},
+ {kIROp_Or, "logicalOr", "||", nullptr, BOOL_MASK | BOOL_RESULT},
+ {kIROp_BitAnd, "and", "&", "__BuiltinLogicalType", LOGICAL_MASK},
+ {kIROp_BitOr, "or", "|", "__BuiltinLogicalType", LOGICAL_MASK},
+ {kIROp_BitXor, "xor", "^", "__BuiltinLogicalType", LOGICAL_MASK},
+ {kIROp_Eql, "eql", "==", "__BuiltinType", ANY_MASK | BOOL_RESULT},
+ {kIROp_Neq, "neq", "!=", "__BuiltinType", ANY_MASK | BOOL_RESULT},
+ {kIROp_Greater, "greater", ">", "__BuiltinArithmeticType", ARITHMETIC_MASK | BOOL_RESULT},
+ {kIROp_Less, "less", "<", "__BuiltinArithmeticType", ARITHMETIC_MASK | BOOL_RESULT},
+ {kIROp_Geq, "geq", ">=", "__BuiltinArithmeticType", ARITHMETIC_MASK | BOOL_RESULT},
+ {kIROp_Leq, "leq", "<=", "__BuiltinArithmeticType", ARITHMETIC_MASK | BOOL_RESULT},
};
// Both the following functions use these macros.