// Copyright 2020 The Tint Authors. // // 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 "src/semantic/intrinsic.h" TINT_INSTANTIATE_TYPEINFO(tint::semantic::Intrinsic); namespace tint { namespace semantic { std::ostream& operator<<(std::ostream& out, IntrinsicType i) { out << str(i); return out; } const char* Intrinsic::str() const { return semantic::str(type_); } IntrinsicType ParseIntrinsicType(const std::string& name) { if (name == "abs") { return IntrinsicType::kAbs; } else if (name == "acos") { return IntrinsicType::kAcos; } else if (name == "all") { return IntrinsicType::kAll; } else if (name == "any") { return IntrinsicType::kAny; } else if (name == "arrayLength") { return IntrinsicType::kArrayLength; } else if (name == "asin") { return IntrinsicType::kAsin; } else if (name == "atan") { return IntrinsicType::kAtan; } else if (name == "atan2") { return IntrinsicType::kAtan2; } else if (name == "ceil") { return IntrinsicType::kCeil; } else if (name == "clamp") { return IntrinsicType::kClamp; } else if (name == "cos") { return IntrinsicType::kCos; } else if (name == "cosh") { return IntrinsicType::kCosh; } else if (name == "countOneBits") { return IntrinsicType::kCountOneBits; } else if (name == "cross") { return IntrinsicType::kCross; } else if (name == "determinant") { return IntrinsicType::kDeterminant; } else if (name == "distance") { return IntrinsicType::kDistance; } else if (name == "dot") { return IntrinsicType::kDot; } else if (name == "dpdx") { return IntrinsicType::kDpdx; } else if (name == "dpdxCoarse") { return IntrinsicType::kDpdxCoarse; } else if (name == "dpdxFine") { return IntrinsicType::kDpdxFine; } else if (name == "dpdy") { return IntrinsicType::kDpdy; } else if (name == "dpdyCoarse") { return IntrinsicType::kDpdyCoarse; } else if (name == "dpdyFine") { return IntrinsicType::kDpdyFine; } else if (name == "exp") { return IntrinsicType::kExp; } else if (name == "exp2") { return IntrinsicType::kExp2; } else if (name == "faceForward") { return IntrinsicType::kFaceForward; } else if (name == "floor") { return IntrinsicType::kFloor; } else if (name == "fma") { return IntrinsicType::kFma; } else if (name == "fract") { return IntrinsicType::kFract; } else if (name == "frexp") { return IntrinsicType::kFrexp; } else if (name == "fwidth") { return IntrinsicType::kFwidth; } else if (name == "fwidthCoarse") { return IntrinsicType::kFwidthCoarse; } else if (name == "fwidthFine") { return IntrinsicType::kFwidthFine; } else if (name == "inverseSqrt") { return IntrinsicType::kInverseSqrt; } else if (name == "isFinite") { return IntrinsicType::kIsFinite; } else if (name == "isInf") { return IntrinsicType::kIsInf; } else if (name == "isNan") { return IntrinsicType::kIsNan; } else if (name == "isNormal") { return IntrinsicType::kIsNormal; } else if (name == "ldexp") { return IntrinsicType::kLdexp; } else if (name == "length") { return IntrinsicType::kLength; } else if (name == "log") { return IntrinsicType::kLog; } else if (name == "log2") { return IntrinsicType::kLog2; } else if (name == "max") { return IntrinsicType::kMax; } else if (name == "min") { return IntrinsicType::kMin; } else if (name == "mix") { return IntrinsicType::kMix; } else if (name == "modf") { return IntrinsicType::kModf; } else if (name == "normalize") { return IntrinsicType::kNormalize; } else if (name == "pack4x8snorm") { return IntrinsicType::kPack4x8Snorm; } else if (name == "pack4x8unorm") { return IntrinsicType::kPack4x8Unorm; } else if (name == "pack2x16snorm") { return IntrinsicType::kPack2x16Snorm; } else if (name == "pack2x16unorm") { return IntrinsicType::kPack2x16Unorm; } else if (name == "pack2x16float") { return IntrinsicType::kPack2x16Float; } else if (name == "pow") { return IntrinsicType::kPow; } else if (name == "reflect") { return IntrinsicType::kReflect; } else if (name == "reverseBits") { return IntrinsicType::kReverseBits; } else if (name == "round") { return IntrinsicType::kRound; } else if (name == "select") { return IntrinsicType::kSelect; } else if (name == "sign") { return IntrinsicType::kSign; } else if (name == "sin") { return IntrinsicType::kSin; } else if (name == "sinh") { return IntrinsicType::kSinh; } else if (name == "smoothStep") { return IntrinsicType::kSmoothStep; } else if (name == "sqrt") { return IntrinsicType::kSqrt; } else if (name == "step") { return IntrinsicType::kStep; } else if (name == "tan") { return IntrinsicType::kTan; } else if (name == "tanh") { return IntrinsicType::kTanh; } else if (name == "textureDimensions") { return IntrinsicType::kTextureDimensions; } else if (name == "textureNumLayers") { return IntrinsicType::kTextureNumLayers; } else if (name == "textureNumLevels") { return IntrinsicType::kTextureNumLevels; } else if (name == "textureNumSamples") { return IntrinsicType::kTextureNumSamples; } else if (name == "textureLoad") { return IntrinsicType::kTextureLoad; } else if (name == "textureStore") { return IntrinsicType::kTextureStore; } else if (name == "textureSample") { return IntrinsicType::kTextureSample; } else if (name == "textureSampleBias") { return IntrinsicType::kTextureSampleBias; } else if (name == "textureSampleCompare") { return IntrinsicType::kTextureSampleCompare; } else if (name == "textureSampleGrad") { return IntrinsicType::kTextureSampleGrad; } else if (name == "textureSampleLevel") { return IntrinsicType::kTextureSampleLevel; } else if (name == "trunc") { return IntrinsicType::kTrunc; } else if (name == "unpack4x8snorm") { return IntrinsicType::kUnpack4x8Snorm; } else if (name == "unpack4x8unorm") { return IntrinsicType::kUnpack4x8Unorm; } else if (name == "unpack2x16snorm") { return IntrinsicType::kUnpack2x16Snorm; } else if (name == "unpack2x16unorm") { return IntrinsicType::kUnpack2x16Unorm; } else if (name == "unpack2x16float") { return IntrinsicType::kUnpack2x16Float; } return IntrinsicType::kNone; } const char* str(IntrinsicType i) { /// The emitted name matches the spelling in the WGSL spec. /// including case. switch (i) { case IntrinsicType::kNone: return ""; case IntrinsicType::kAbs: return "abs"; case IntrinsicType::kAcos: return "acos"; case IntrinsicType::kAll: return "all"; case IntrinsicType::kAny: return "any"; case IntrinsicType::kArrayLength: return "arrayLength"; case IntrinsicType::kAsin: return "asin"; case IntrinsicType::kAtan: return "atan"; case IntrinsicType::kAtan2: return "atan2"; case IntrinsicType::kCeil: return "ceil"; case IntrinsicType::kClamp: return "clamp"; case IntrinsicType::kCos: return "cos"; case IntrinsicType::kCosh: return "cosh"; case IntrinsicType::kCountOneBits: return "countOneBits"; case IntrinsicType::kCross: return "cross"; case IntrinsicType::kDeterminant: return "determinant"; case IntrinsicType::kDistance: return "distance"; case IntrinsicType::kDot: return "dot"; case IntrinsicType::kDpdx: return "dpdx"; case IntrinsicType::kDpdxCoarse: return "dpdxCoarse"; case IntrinsicType::kDpdxFine: return "dpdxFine"; case IntrinsicType::kDpdy: return "dpdy"; case IntrinsicType::kDpdyCoarse: return "dpdyCoarse"; case IntrinsicType::kDpdyFine: return "dpdyFine"; case IntrinsicType::kExp: return "exp"; case IntrinsicType::kExp2: return "exp2"; case IntrinsicType::kFaceForward: return "faceForward"; case IntrinsicType::kFloor: return "floor"; case IntrinsicType::kFma: return "fma"; case IntrinsicType::kFract: return "fract"; case IntrinsicType::kFrexp: return "frexp"; case IntrinsicType::kFwidth: return "fwidth"; case IntrinsicType::kFwidthCoarse: return "fwidthCoarse"; case IntrinsicType::kFwidthFine: return "fwidthFine"; case IntrinsicType::kInverseSqrt: return "inverseSqrt"; case IntrinsicType::kIsFinite: return "isFinite"; case IntrinsicType::kIsInf: return "isInf"; case IntrinsicType::kIsNan: return "isNan"; case IntrinsicType::kIsNormal: return "isNormal"; case IntrinsicType::kLdexp: return "ldexp"; case IntrinsicType::kLength: return "length"; case IntrinsicType::kLog: return "log"; case IntrinsicType::kLog2: return "log2"; case IntrinsicType::kMax: return "max"; case IntrinsicType::kMin: return "min"; case IntrinsicType::kMix: return "mix"; case IntrinsicType::kModf: return "modf"; case IntrinsicType::kNormalize: return "normalize"; case IntrinsicType::kPack4x8Snorm: return "pack4x8snorm"; case IntrinsicType::kPack4x8Unorm: return "pack4x8unorm"; case IntrinsicType::kPack2x16Snorm: return "pack2x16snorm"; case IntrinsicType::kPack2x16Unorm: return "pack2x16unorm"; case IntrinsicType::kPack2x16Float: return "pack2x16float"; case IntrinsicType::kPow: return "pow"; case IntrinsicType::kReflect: return "reflect"; case IntrinsicType::kReverseBits: return "reverseBits"; case IntrinsicType::kRound: return "round"; case IntrinsicType::kSelect: return "select"; case IntrinsicType::kSign: return "sign"; case IntrinsicType::kSin: return "sin"; case IntrinsicType::kSinh: return "sinh"; case IntrinsicType::kSmoothStep: return "smoothStep"; case IntrinsicType::kSqrt: return "sqrt"; case IntrinsicType::kStep: return "step"; case IntrinsicType::kTan: return "tan"; case IntrinsicType::kTanh: return "tanh"; case IntrinsicType::kTextureDimensions: return "textureDimensions"; case IntrinsicType::kTextureLoad: return "textureLoad"; case IntrinsicType::kTextureNumLayers: return "textureNumLayers"; case IntrinsicType::kTextureNumLevels: return "textureNumLevels"; case IntrinsicType::kTextureNumSamples: return "textureNumSamples"; case IntrinsicType::kTextureSample: return "textureSample"; case IntrinsicType::kTextureSampleBias: return "textureSampleBias"; case IntrinsicType::kTextureSampleCompare: return "textureSampleCompare"; case IntrinsicType::kTextureSampleGrad: return "textureSampleGrad"; case IntrinsicType::kTextureSampleLevel: return "textureSampleLevel"; case IntrinsicType::kTextureStore: return "textureStore"; case IntrinsicType::kTrunc: return "trunc"; case IntrinsicType::kUnpack4x8Snorm: return "unpack4x8snorm"; case IntrinsicType::kUnpack4x8Unorm: return "unpack4x8unorm"; case IntrinsicType::kUnpack2x16Snorm: return "unpack2x16snorm"; case IntrinsicType::kUnpack2x16Unorm: return "unpack2x16unorm"; case IntrinsicType::kUnpack2x16Float: return "unpack2x16float"; } return ""; } bool IsCoarseDerivativeIntrinsic(IntrinsicType i) { return i == IntrinsicType::kDpdxCoarse || i == IntrinsicType::kDpdyCoarse || i == IntrinsicType::kFwidthCoarse; } bool IsFineDerivativeIntrinsic(IntrinsicType i) { return i == IntrinsicType::kDpdxFine || i == IntrinsicType::kDpdyFine || i == IntrinsicType::kFwidthFine; } bool IsDerivativeIntrinsic(IntrinsicType i) { return i == IntrinsicType::kDpdx || i == IntrinsicType::kDpdy || i == IntrinsicType::kFwidth || IsCoarseDerivativeIntrinsic(i) || IsFineDerivativeIntrinsic(i); } bool IsFloatClassificationIntrinsic(IntrinsicType i) { return i == IntrinsicType::kIsFinite || i == IntrinsicType::kIsInf || i == IntrinsicType::kIsNan || i == IntrinsicType::kIsNormal; } bool IsTextureIntrinsic(IntrinsicType i) { return IsImageQueryIntrinsic(i) || i == IntrinsicType::kTextureLoad || i == IntrinsicType::kTextureSample || i == IntrinsicType::kTextureSampleLevel || i == IntrinsicType::kTextureSampleBias || i == IntrinsicType::kTextureSampleCompare || i == IntrinsicType::kTextureSampleGrad || i == IntrinsicType::kTextureStore; } bool IsImageQueryIntrinsic(IntrinsicType i) { return i == IntrinsicType::kTextureDimensions || i == IntrinsicType::kTextureNumLayers || i == IntrinsicType::kTextureNumLevels || i == IntrinsicType::kTextureNumSamples; } bool IsDataPackingIntrinsic(IntrinsicType i) { return i == IntrinsicType::kPack4x8Snorm || i == IntrinsicType::kPack4x8Unorm || i == IntrinsicType::kPack2x16Snorm || i == IntrinsicType::kPack2x16Unorm || i == IntrinsicType::kPack2x16Float; } bool IsDataUnpackingIntrinsic(IntrinsicType i) { return i == IntrinsicType::kUnpack4x8Snorm || i == IntrinsicType::kUnpack4x8Unorm || i == IntrinsicType::kUnpack2x16Snorm || i == IntrinsicType::kUnpack2x16Unorm || i == IntrinsicType::kUnpack2x16Float; } Intrinsic::Intrinsic(IntrinsicType type, type::Type* return_type, const ParameterList& parameters) : Base(return_type, parameters), type_(type) {} Intrinsic::~Intrinsic() = default; bool Intrinsic::IsCoarseDerivative() const { return IsCoarseDerivativeIntrinsic(type_); } bool Intrinsic::IsFineDerivative() const { return IsFineDerivativeIntrinsic(type_); } bool Intrinsic::IsDerivative() const { return IsDerivativeIntrinsic(type_); } bool Intrinsic::IsFloatClassification() const { return IsFloatClassificationIntrinsic(type_); } bool Intrinsic::IsTexture() const { return IsTextureIntrinsic(type_); } bool Intrinsic::IsImageQuery() const { return IsImageQueryIntrinsic(type_); } bool Intrinsic::IsDataPacking() const { return IsDataPackingIntrinsic(type_); } bool Intrinsic::IsDataUnpacking() const { return IsDataUnpackingIntrinsic(type_); } } // namespace semantic } // namespace tint