// Copyright 2016 The SwiftShader Authors. All Rights Reserved. // // 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. #ifndef sw_Reactor_hpp #define sw_Reactor_hpp #include "Nucleus.hpp" #include "Routine.hpp" #include #include #include #undef Bool namespace sw { class Bool; class Byte; class SByte; class Byte4; class SByte4; class Byte8; class SByte8; class Byte16; class SByte16; class Short; class UShort; class Short2; class UShort2; class Short4; class UShort4; class Short8; class UShort8; class Int; class UInt; class Int2; class UInt2; class Int4; class UInt4; class Long; class Float; class Float2; class Float4; class Void { public: static Type *getType(); static bool isVoid() { return true; } }; template class RValue; template class Pointer; class Variable { protected: Value *address; }; template class LValue : public Variable { public: LValue(int arraySize = 0); RValue> operator&(); static bool isVoid() { return false; } Value *loadValue() const; Value *storeValue(Value *value) const; Value *getAddress(Value *index, bool unsignedIndex) const; }; template class Reference { public: explicit Reference(Value *pointer, int alignment = 1); RValue operator=(RValue rhs) const; RValue operator=(const Reference &ref) const; RValue operator+=(RValue rhs) const; Value *loadValue() const; int getAlignment() const; private: Value *address; const int alignment; }; template struct IntLiteral { struct type; }; template<> struct IntLiteral { typedef bool type; }; template<> struct IntLiteral { typedef int type; }; template<> struct IntLiteral { typedef unsigned int type; }; template<> struct IntLiteral { typedef int64_t type; }; template struct FloatLiteral { struct type; }; template<> struct FloatLiteral { typedef float type; }; template class RValue { public: explicit RValue(Value *rvalue); RValue(const T &lvalue); RValue(typename IntLiteral::type i); RValue(typename FloatLiteral::type f); RValue(const Reference &rhs); RValue &operator=(const RValue&) = delete; Value *value; // FIXME: Make private }; template struct Argument { explicit Argument(Value *value) : value(value) {} Value *value; }; class Bool : public LValue { public: Bool(Argument argument); Bool() = default; Bool(bool x); Bool(RValue rhs); Bool(const Bool &rhs); Bool(const Reference &rhs); // RValue operator=(bool rhs); // FIXME: Implement RValue operator=(RValue rhs); RValue operator=(const Bool &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator!(RValue val); RValue operator&&(RValue lhs, RValue rhs); RValue operator||(RValue lhs, RValue rhs); class Byte : public LValue { public: Byte(Argument argument); explicit Byte(RValue cast); explicit Byte(RValue cast); explicit Byte(RValue cast); Byte() = default; Byte(int x); Byte(unsigned char x); Byte(RValue rhs); Byte(const Byte &rhs); Byte(const Reference &rhs); // RValue operator=(unsigned char rhs); // FIXME: Implement RValue operator=(RValue rhs); RValue operator=(const Byte &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); RValue operator*(RValue lhs, RValue rhs); RValue operator/(RValue lhs, RValue rhs); RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, RValue rhs); RValue operator>>(RValue lhs, RValue rhs); RValue operator+=(Byte &lhs, RValue rhs); RValue operator-=(Byte &lhs, RValue rhs); RValue operator*=(Byte &lhs, RValue rhs); RValue operator/=(Byte &lhs, RValue rhs); RValue operator%=(Byte &lhs, RValue rhs); RValue operator&=(Byte &lhs, RValue rhs); RValue operator|=(Byte &lhs, RValue rhs); RValue operator^=(Byte &lhs, RValue rhs); RValue operator<<=(Byte &lhs, RValue rhs); RValue operator>>=(Byte &lhs, RValue rhs); RValue operator+(RValue val); RValue operator-(RValue val); RValue operator~(RValue val); RValue operator++(Byte &val, int); // Post-increment const Byte &operator++(Byte &val); // Pre-increment RValue operator--(Byte &val, int); // Post-decrement const Byte &operator--(Byte &val); // Pre-decrement RValue operator<(RValue lhs, RValue rhs); RValue operator<=(RValue lhs, RValue rhs); RValue operator>(RValue lhs, RValue rhs); RValue operator>=(RValue lhs, RValue rhs); RValue operator!=(RValue lhs, RValue rhs); RValue operator==(RValue lhs, RValue rhs); class SByte : public LValue { public: SByte(Argument argument); explicit SByte(RValue cast); explicit SByte(RValue cast); SByte() = default; SByte(signed char x); SByte(RValue rhs); SByte(const SByte &rhs); SByte(const Reference &rhs); // RValue operator=(signed char rhs); // FIXME: Implement RValue operator=(RValue rhs); RValue operator=(const SByte &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); RValue operator*(RValue lhs, RValue rhs); RValue operator/(RValue lhs, RValue rhs); RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, RValue rhs); RValue operator>>(RValue lhs, RValue rhs); RValue operator+=(SByte &lhs, RValue rhs); RValue operator-=(SByte &lhs, RValue rhs); RValue operator*=(SByte &lhs, RValue rhs); RValue operator/=(SByte &lhs, RValue rhs); RValue operator%=(SByte &lhs, RValue rhs); RValue operator&=(SByte &lhs, RValue rhs); RValue operator|=(SByte &lhs, RValue rhs); RValue operator^=(SByte &lhs, RValue rhs); RValue operator<<=(SByte &lhs, RValue rhs); RValue operator>>=(SByte &lhs, RValue rhs); RValue operator+(RValue val); RValue operator-(RValue val); RValue operator~(RValue val); RValue operator++(SByte &val, int); // Post-increment const SByte &operator++(SByte &val); // Pre-increment RValue operator--(SByte &val, int); // Post-decrement const SByte &operator--(SByte &val); // Pre-decrement RValue operator<(RValue lhs, RValue rhs); RValue operator<=(RValue lhs, RValue rhs); RValue operator>(RValue lhs, RValue rhs); RValue operator>=(RValue lhs, RValue rhs); RValue operator!=(RValue lhs, RValue rhs); RValue operator==(RValue lhs, RValue rhs); class Short : public LValue { public: Short(Argument argument); explicit Short(RValue cast); Short() = default; Short(short x); Short(RValue rhs); Short(const Short &rhs); Short(const Reference &rhs); // RValue operator=(short rhs); // FIXME: Implement RValue operator=(RValue rhs); RValue operator=(const Short &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); RValue operator*(RValue lhs, RValue rhs); RValue operator/(RValue lhs, RValue rhs); RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, RValue rhs); RValue operator>>(RValue lhs, RValue rhs); RValue operator+=(Short &lhs, RValue rhs); RValue operator-=(Short &lhs, RValue rhs); RValue operator*=(Short &lhs, RValue rhs); RValue operator/=(Short &lhs, RValue rhs); RValue operator%=(Short &lhs, RValue rhs); RValue operator&=(Short &lhs, RValue rhs); RValue operator|=(Short &lhs, RValue rhs); RValue operator^=(Short &lhs, RValue rhs); RValue operator<<=(Short &lhs, RValue rhs); RValue operator>>=(Short &lhs, RValue rhs); RValue operator+(RValue val); RValue operator-(RValue val); RValue operator~(RValue val); RValue operator++(Short &val, int); // Post-increment const Short &operator++(Short &val); // Pre-increment RValue operator--(Short &val, int); // Post-decrement const Short &operator--(Short &val); // Pre-decrement RValue operator<(RValue lhs, RValue rhs); RValue operator<=(RValue lhs, RValue rhs); RValue operator>(RValue lhs, RValue rhs); RValue operator>=(RValue lhs, RValue rhs); RValue operator!=(RValue lhs, RValue rhs); RValue operator==(RValue lhs, RValue rhs); class UShort : public LValue { public: UShort(Argument argument); explicit UShort(RValue cast); explicit UShort(RValue cast); UShort() = default; UShort(unsigned short x); UShort(RValue rhs); UShort(const UShort &rhs); UShort(const Reference &rhs); // RValue operator=(unsigned short rhs); // FIXME: Implement RValue operator=(RValue rhs); RValue operator=(const UShort &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); RValue operator*(RValue lhs, RValue rhs); RValue operator/(RValue lhs, RValue rhs); RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, RValue rhs); RValue operator>>(RValue lhs, RValue rhs); RValue operator+=(UShort &lhs, RValue rhs); RValue operator-=(UShort &lhs, RValue rhs); RValue operator*=(UShort &lhs, RValue rhs); RValue operator/=(UShort &lhs, RValue rhs); RValue operator%=(UShort &lhs, RValue rhs); RValue operator&=(UShort &lhs, RValue rhs); RValue operator|=(UShort &lhs, RValue rhs); RValue operator^=(UShort &lhs, RValue rhs); RValue operator<<=(UShort &lhs, RValue rhs); RValue operator>>=(UShort &lhs, RValue rhs); RValue operator+(RValue val); RValue operator-(RValue val); RValue operator~(RValue val); RValue operator++(UShort &val, int); // Post-increment const UShort &operator++(UShort &val); // Pre-increment RValue operator--(UShort &val, int); // Post-decrement const UShort &operator--(UShort &val); // Pre-decrement RValue operator<(RValue lhs, RValue rhs); RValue operator<=(RValue lhs, RValue rhs); RValue operator>(RValue lhs, RValue rhs); RValue operator>=(RValue lhs, RValue rhs); RValue operator!=(RValue lhs, RValue rhs); RValue operator==(RValue lhs, RValue rhs); class Byte4 : public LValue { public: explicit Byte4(RValue cast); Byte4() = default; // Byte4(int x, int y, int z, int w); // Byte4(RValue rhs); // Byte4(const Byte4 &rhs); Byte4(const Reference &rhs); // RValue operator=(RValue rhs); // RValue operator=(const Byte4 &rhs); // RValue operator=(const Reference &rhs); static Type *getType(); }; // RValue operator+(RValue lhs, RValue rhs); // RValue operator-(RValue lhs, RValue rhs); // RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); // RValue operator&(RValue lhs, RValue rhs); // RValue operator|(RValue lhs, RValue rhs); // RValue operator^(RValue lhs, RValue rhs); // RValue operator<<(RValue lhs, RValue rhs); // RValue operator>>(RValue lhs, RValue rhs); // RValue operator+=(Byte4 &lhs, RValue rhs); // RValue operator-=(Byte4 &lhs, RValue rhs); // RValue operator*=(Byte4 &lhs, RValue rhs); // RValue operator/=(Byte4 &lhs, RValue rhs); // RValue operator%=(Byte4 &lhs, RValue rhs); // RValue operator&=(Byte4 &lhs, RValue rhs); // RValue operator|=(Byte4 &lhs, RValue rhs); // RValue operator^=(Byte4 &lhs, RValue rhs); // RValue operator<<=(Byte4 &lhs, RValue rhs); // RValue operator>>=(Byte4 &lhs, RValue rhs); // RValue operator+(RValue val); // RValue operator-(RValue val); // RValue operator~(RValue val); // RValue operator++(Byte4 &val, int); // Post-increment // const Byte4 &operator++(Byte4 &val); // Pre-increment // RValue operator--(Byte4 &val, int); // Post-decrement // const Byte4 &operator--(Byte4 &val); // Pre-decrement class SByte4 : public LValue { public: SByte4() = default; // SByte4(int x, int y, int z, int w); // SByte4(RValue rhs); // SByte4(const SByte4 &rhs); // SByte4(const Reference &rhs); // RValue operator=(RValue rhs); // RValue operator=(const SByte4 &rhs); // RValue operator=(const Reference &rhs); static Type *getType(); }; // RValue operator+(RValue lhs, RValue rhs); // RValue operator-(RValue lhs, RValue rhs); // RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); // RValue operator&(RValue lhs, RValue rhs); // RValue operator|(RValue lhs, RValue rhs); // RValue operator^(RValue lhs, RValue rhs); // RValue operator<<(RValue lhs, RValue rhs); // RValue operator>>(RValue lhs, RValue rhs); // RValue operator+=(SByte4 &lhs, RValue rhs); // RValue operator-=(SByte4 &lhs, RValue rhs); // RValue operator*=(SByte4 &lhs, RValue rhs); // RValue operator/=(SByte4 &lhs, RValue rhs); // RValue operator%=(SByte4 &lhs, RValue rhs); // RValue operator&=(SByte4 &lhs, RValue rhs); // RValue operator|=(SByte4 &lhs, RValue rhs); // RValue operator^=(SByte4 &lhs, RValue rhs); // RValue operator<<=(SByte4 &lhs, RValue rhs); // RValue operator>>=(SByte4 &lhs, RValue rhs); // RValue operator+(RValue val); // RValue operator-(RValue val); // RValue operator~(RValue val); // RValue operator++(SByte4 &val, int); // Post-increment // const SByte4 &operator++(SByte4 &val); // Pre-increment // RValue operator--(SByte4 &val, int); // Post-decrement // const SByte4 &operator--(SByte4 &val); // Pre-decrement class Byte8 : public LValue { public: Byte8() = default; Byte8(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7); Byte8(RValue rhs); Byte8(const Byte8 &rhs); Byte8(const Reference &rhs); RValue operator=(RValue rhs); RValue operator=(const Byte8 &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); // RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); // RValue operator<<(RValue lhs, RValue rhs); // RValue operator>>(RValue lhs, RValue rhs); RValue operator+=(Byte8 &lhs, RValue rhs); RValue operator-=(Byte8 &lhs, RValue rhs); // RValue operator*=(Byte8 &lhs, RValue rhs); // RValue operator/=(Byte8 &lhs, RValue rhs); // RValue operator%=(Byte8 &lhs, RValue rhs); RValue operator&=(Byte8 &lhs, RValue rhs); RValue operator|=(Byte8 &lhs, RValue rhs); RValue operator^=(Byte8 &lhs, RValue rhs); // RValue operator<<=(Byte8 &lhs, RValue rhs); // RValue operator>>=(Byte8 &lhs, RValue rhs); // RValue operator+(RValue val); // RValue operator-(RValue val); RValue operator~(RValue val); // RValue operator++(Byte8 &val, int); // Post-increment // const Byte8 &operator++(Byte8 &val); // Pre-increment // RValue operator--(Byte8 &val, int); // Post-decrement // const Byte8 &operator--(Byte8 &val); // Pre-decrement RValue AddSat(RValue x, RValue y); RValue SubSat(RValue x, RValue y); RValue Unpack(RValue x); RValue Unpack(RValue x, RValue y); RValue UnpackLow(RValue x, RValue y); RValue UnpackHigh(RValue x, RValue y); RValue SignMask(RValue x); // RValue CmpGT(RValue x, RValue y); RValue CmpEQ(RValue x, RValue y); class SByte8 : public LValue { public: SByte8() = default; SByte8(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7); SByte8(RValue rhs); SByte8(const SByte8 &rhs); SByte8(const Reference &rhs); RValue operator=(RValue rhs); RValue operator=(const SByte8 &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); // RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); // RValue operator<<(RValue lhs, RValue rhs); // RValue operator>>(RValue lhs, RValue rhs); RValue operator+=(SByte8 &lhs, RValue rhs); RValue operator-=(SByte8 &lhs, RValue rhs); // RValue operator*=(SByte8 &lhs, RValue rhs); // RValue operator/=(SByte8 &lhs, RValue rhs); // RValue operator%=(SByte8 &lhs, RValue rhs); RValue operator&=(SByte8 &lhs, RValue rhs); RValue operator|=(SByte8 &lhs, RValue rhs); RValue operator^=(SByte8 &lhs, RValue rhs); // RValue operator<<=(SByte8 &lhs, RValue rhs); // RValue operator>>=(SByte8 &lhs, RValue rhs); // RValue operator+(RValue val); // RValue operator-(RValue val); RValue operator~(RValue val); // RValue operator++(SByte8 &val, int); // Post-increment // const SByte8 &operator++(SByte8 &val); // Pre-increment // RValue operator--(SByte8 &val, int); // Post-decrement // const SByte8 &operator--(SByte8 &val); // Pre-decrement RValue AddSat(RValue x, RValue y); RValue SubSat(RValue x, RValue y); RValue UnpackLow(RValue x, RValue y); RValue UnpackHigh(RValue x, RValue y); RValue SignMask(RValue x); RValue CmpGT(RValue x, RValue y); RValue CmpEQ(RValue x, RValue y); class Byte16 : public LValue { public: Byte16() = default; // Byte16(int x, int y, int z, int w); Byte16(RValue rhs); Byte16(const Byte16 &rhs); Byte16(const Reference &rhs); RValue operator=(RValue rhs); RValue operator=(const Byte16 &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; // RValue operator+(RValue lhs, RValue rhs); // RValue operator-(RValue lhs, RValue rhs); // RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); // RValue operator&(RValue lhs, RValue rhs); // RValue operator|(RValue lhs, RValue rhs); // RValue operator^(RValue lhs, RValue rhs); // RValue operator<<(RValue lhs, RValue rhs); // RValue operator>>(RValue lhs, RValue rhs); // RValue operator+=(Byte16 &lhs, RValue rhs); // RValue operator-=(Byte16 &lhs, RValue rhs); // RValue operator*=(Byte16 &lhs, RValue rhs); // RValue operator/=(Byte16 &lhs, RValue rhs); // RValue operator%=(Byte16 &lhs, RValue rhs); // RValue operator&=(Byte16 &lhs, RValue rhs); // RValue operator|=(Byte16 &lhs, RValue rhs); // RValue operator^=(Byte16 &lhs, RValue rhs); // RValue operator<<=(Byte16 &lhs, RValue rhs); // RValue operator>>=(Byte16 &lhs, RValue rhs); // RValue operator+(RValue val); // RValue operator-(RValue val); // RValue operator~(RValue val); // RValue operator++(Byte16 &val, int); // Post-increment // const Byte16 &operator++(Byte16 &val); // Pre-increment // RValue operator--(Byte16 &val, int); // Post-decrement // const Byte16 &operator--(Byte16 &val); // Pre-decrement class SByte16 : public LValue { public: SByte16() = default; // SByte16(int x, int y, int z, int w); // SByte16(RValue rhs); // SByte16(const SByte16 &rhs); // SByte16(const Reference &rhs); // RValue operator=(RValue rhs); // RValue operator=(const SByte16 &rhs); // RValue operator=(const Reference &rhs); static Type *getType(); }; // RValue operator+(RValue lhs, RValue rhs); // RValue operator-(RValue lhs, RValue rhs); // RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); // RValue operator&(RValue lhs, RValue rhs); // RValue operator|(RValue lhs, RValue rhs); // RValue operator^(RValue lhs, RValue rhs); // RValue operator<<(RValue lhs, RValue rhs); // RValue operator>>(RValue lhs, RValue rhs); // RValue operator+=(SByte16 &lhs, RValue rhs); // RValue operator-=(SByte16 &lhs, RValue rhs); // RValue operator*=(SByte16 &lhs, RValue rhs); // RValue operator/=(SByte16 &lhs, RValue rhs); // RValue operator%=(SByte16 &lhs, RValue rhs); // RValue operator&=(SByte16 &lhs, RValue rhs); // RValue operator|=(SByte16 &lhs, RValue rhs); // RValue operator^=(SByte16 &lhs, RValue rhs); // RValue operator<<=(SByte16 &lhs, RValue rhs); // RValue operator>>=(SByte16 &lhs, RValue rhs); // RValue operator+(RValue val); // RValue operator-(RValue val); // RValue operator~(RValue val); // RValue operator++(SByte16 &val, int); // Post-increment // const SByte16 &operator++(SByte16 &val); // Pre-increment // RValue operator--(SByte16 &val, int); // Post-decrement // const SByte16 &operator--(SByte16 &val); // Pre-decrement class Short2 : public LValue { public: explicit Short2(RValue cast); static Type *getType(); }; class UShort2 : public LValue { public: explicit UShort2(RValue cast); static Type *getType(); }; class Short4 : public LValue { public: explicit Short4(RValue cast); explicit Short4(RValue cast); // explicit Short4(RValue cast); explicit Short4(RValue cast); Short4() = default; Short4(short xyzw); Short4(short x, short y, short z, short w); Short4(RValue rhs); Short4(const Short4 &rhs); Short4(const Reference &rhs); Short4(RValue rhs); Short4(const UShort4 &rhs); Short4(const Reference &rhs); RValue operator=(RValue rhs); RValue operator=(const Short4 &rhs); RValue operator=(const Reference &rhs); RValue operator=(RValue rhs); RValue operator=(const UShort4 &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, unsigned char rhs); RValue operator>>(RValue lhs, unsigned char rhs); RValue operator+=(Short4 &lhs, RValue rhs); RValue operator-=(Short4 &lhs, RValue rhs); RValue operator*=(Short4 &lhs, RValue rhs); // RValue operator/=(Short4 &lhs, RValue rhs); // RValue operator%=(Short4 &lhs, RValue rhs); RValue operator&=(Short4 &lhs, RValue rhs); RValue operator|=(Short4 &lhs, RValue rhs); RValue operator^=(Short4 &lhs, RValue rhs); RValue operator<<=(Short4 &lhs, unsigned char rhs); RValue operator>>=(Short4 &lhs, unsigned char rhs); // RValue operator+(RValue val); RValue operator-(RValue val); RValue operator~(RValue val); // RValue operator++(Short4 &val, int); // Post-increment // const Short4 &operator++(Short4 &val); // Pre-increment // RValue operator--(Short4 &val, int); // Post-decrement // const Short4 &operator--(Short4 &val); // Pre-decrement // RValue operator<(RValue lhs, RValue rhs); // RValue operator<=(RValue lhs, RValue rhs); // RValue operator>(RValue lhs, RValue rhs); // RValue operator>=(RValue lhs, RValue rhs); // RValue operator!=(RValue lhs, RValue rhs); // RValue operator==(RValue lhs, RValue rhs); RValue RoundShort4(RValue cast); RValue Max(RValue x, RValue y); RValue Min(RValue x, RValue y); RValue AddSat(RValue x, RValue y); RValue SubSat(RValue x, RValue y); RValue MulHigh(RValue x, RValue y); RValue MulAdd(RValue x, RValue y); RValue Pack(RValue x, RValue y); RValue UnpackLow(RValue x, RValue y); RValue UnpackHigh(RValue x, RValue y); RValue Swizzle(RValue x, unsigned char select); RValue Insert(RValue val, RValue element, int i); RValue Extract(RValue val, int i); RValue CmpGT(RValue x, RValue y); RValue CmpEQ(RValue x, RValue y); class UShort4 : public LValue { public: explicit UShort4(RValue cast); explicit UShort4(RValue cast, bool saturate = false); UShort4() = default; UShort4(unsigned short xyzw); UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w); UShort4(RValue rhs); UShort4(const UShort4 &rhs); UShort4(const Reference &rhs); UShort4(RValue rhs); UShort4(const Short4 &rhs); UShort4(const Reference &rhs); RValue operator=(RValue rhs); RValue operator=(const UShort4 &rhs); RValue operator=(const Reference &rhs); RValue operator=(RValue rhs); RValue operator=(const Short4 &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, unsigned char rhs); RValue operator>>(RValue lhs, unsigned char rhs); // RValue operator+=(UShort4 &lhs, RValue rhs); // RValue operator-=(UShort4 &lhs, RValue rhs); // RValue operator*=(UShort4 &lhs, RValue rhs); // RValue operator/=(UShort4 &lhs, RValue rhs); // RValue operator%=(UShort4 &lhs, RValue rhs); // RValue operator&=(UShort4 &lhs, RValue rhs); // RValue operator|=(UShort4 &lhs, RValue rhs); // RValue operator^=(UShort4 &lhs, RValue rhs); RValue operator<<=(UShort4 &lhs, unsigned char rhs); RValue operator>>=(UShort4 &lhs, unsigned char rhs); // RValue operator+(RValue val); // RValue operator-(RValue val); RValue operator~(RValue val); // RValue operator++(UShort4 &val, int); // Post-increment // const UShort4 &operator++(UShort4 &val); // Pre-increment // RValue operator--(UShort4 &val, int); // Post-decrement // const UShort4 &operator--(UShort4 &val); // Pre-decrement RValue Max(RValue x, RValue y); RValue Min(RValue x, RValue y); RValue AddSat(RValue x, RValue y); RValue SubSat(RValue x, RValue y); RValue MulHigh(RValue x, RValue y); RValue Average(RValue x, RValue y); RValue Pack(RValue x, RValue y); class Short8 : public LValue { public: Short8() = default; Short8(short c); Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7); Short8(RValue rhs); // Short8(const Short8 &rhs); Short8(const Reference &rhs); Short8(RValue lo, RValue hi); // RValue operator=(RValue rhs); // RValue operator=(const Short8 &rhs); // RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); // RValue operator-(RValue lhs, RValue rhs); // RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); // RValue operator|(RValue lhs, RValue rhs); // RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, unsigned char rhs); RValue operator>>(RValue lhs, unsigned char rhs); // RValue operator<<(RValue lhs, RValue rhs); // RValue operator>>(RValue lhs, RValue rhs); // RValue operator+=(Short8 &lhs, RValue rhs); // RValue operator-=(Short8 &lhs, RValue rhs); // RValue operator*=(Short8 &lhs, RValue rhs); // RValue operator/=(Short8 &lhs, RValue rhs); // RValue operator%=(Short8 &lhs, RValue rhs); // RValue operator&=(Short8 &lhs, RValue rhs); // RValue operator|=(Short8 &lhs, RValue rhs); // RValue operator^=(Short8 &lhs, RValue rhs); // RValue operator<<=(Short8 &lhs, RValue rhs); // RValue operator>>=(Short8 &lhs, RValue rhs); // RValue operator+(RValue val); // RValue operator-(RValue val); // RValue operator~(RValue val); // RValue operator++(Short8 &val, int); // Post-increment // const Short8 &operator++(Short8 &val); // Pre-increment // RValue operator--(Short8 &val, int); // Post-decrement // const Short8 &operator--(Short8 &val); // Pre-decrement // RValue operator<(RValue lhs, RValue rhs); // RValue operator<=(RValue lhs, RValue rhs); // RValue operator>(RValue lhs, RValue rhs); // RValue operator>=(RValue lhs, RValue rhs); // RValue operator!=(RValue lhs, RValue rhs); // RValue operator==(RValue lhs, RValue rhs); RValue MulHigh(RValue x, RValue y); RValue MulAdd(RValue x, RValue y); RValue Abs(RValue x); class UShort8 : public LValue { public: UShort8() = default; UShort8(unsigned short c); UShort8(unsigned short c0, unsigned short c1, unsigned short c2, unsigned short c3, unsigned short c4, unsigned short c5, unsigned short c6, unsigned short c7); UShort8(RValue rhs); // UShort8(const UShort8 &rhs); UShort8(const Reference &rhs); UShort8(RValue lo, RValue hi); RValue operator=(RValue rhs); RValue operator=(const UShort8 &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); // RValue operator-(RValue lhs, RValue rhs); RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); // RValue operator|(RValue lhs, RValue rhs); // RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, unsigned char rhs); RValue operator>>(RValue lhs, unsigned char rhs); // RValue operator<<(RValue lhs, RValue rhs); // RValue operator>>(RValue lhs, RValue rhs); RValue operator+=(UShort8 &lhs, RValue rhs); // RValue operator-=(UShort8 &lhs, RValue rhs); // RValue operator*=(UShort8 &lhs, RValue rhs); // RValue operator/=(UShort8 &lhs, RValue rhs); // RValue operator%=(UShort8 &lhs, RValue rhs); // RValue operator&=(UShort8 &lhs, RValue rhs); // RValue operator|=(UShort8 &lhs, RValue rhs); // RValue operator^=(UShort8 &lhs, RValue rhs); // RValue operator<<=(UShort8 &lhs, RValue rhs); // RValue operator>>=(UShort8 &lhs, RValue rhs); // RValue operator+(RValue val); // RValue operator-(RValue val); RValue operator~(RValue val); // RValue operator++(UShort8 &val, int); // Post-increment // const UShort8 &operator++(UShort8 &val); // Pre-increment // RValue operator--(UShort8 &val, int); // Post-decrement // const UShort8 &operator--(UShort8 &val); // Pre-decrement // RValue operator<(RValue lhs, RValue rhs); // RValue operator<=(RValue lhs, RValue rhs); // RValue operator>(RValue lhs, RValue rhs); // RValue operator>=(RValue lhs, RValue rhs); // RValue operator!=(RValue lhs, RValue rhs); // RValue operator==(RValue lhs, RValue rhs); RValue Swizzle(RValue x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7); RValue MulHigh(RValue x, RValue y); class Int : public LValue { public: Int(Argument argument); explicit Int(RValue cast); explicit Int(RValue cast); explicit Int(RValue cast); explicit Int(RValue cast); explicit Int(RValue cast); explicit Int(RValue cast); explicit Int(RValue cast); Int() = default; Int(int x); Int(RValue rhs); Int(RValue rhs); Int(const Int &rhs); Int(const UInt &rhs); Int(const Reference &rhs); Int(const Reference &rhs); RValue operator=(int rhs); RValue operator=(RValue rhs); RValue operator=(RValue rhs); RValue operator=(const Int &rhs); RValue operator=(const UInt &rhs); RValue operator=(const Reference &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); RValue operator*(RValue lhs, RValue rhs); RValue operator/(RValue lhs, RValue rhs); RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, RValue rhs); RValue operator>>(RValue lhs, RValue rhs); RValue operator+=(Int &lhs, RValue rhs); RValue operator-=(Int &lhs, RValue rhs); RValue operator*=(Int &lhs, RValue rhs); RValue operator/=(Int &lhs, RValue rhs); RValue operator%=(Int &lhs, RValue rhs); RValue operator&=(Int &lhs, RValue rhs); RValue operator|=(Int &lhs, RValue rhs); RValue operator^=(Int &lhs, RValue rhs); RValue operator<<=(Int &lhs, RValue rhs); RValue operator>>=(Int &lhs, RValue rhs); RValue operator+(RValue val); RValue operator-(RValue val); RValue operator~(RValue val); RValue operator++(Int &val, int); // Post-increment const Int &operator++(Int &val); // Pre-increment RValue operator--(Int &val, int); // Post-decrement const Int &operator--(Int &val); // Pre-decrement RValue operator<(RValue lhs, RValue rhs); RValue operator<=(RValue lhs, RValue rhs); RValue operator>(RValue lhs, RValue rhs); RValue operator>=(RValue lhs, RValue rhs); RValue operator!=(RValue lhs, RValue rhs); RValue operator==(RValue lhs, RValue rhs); RValue Max(RValue x, RValue y); RValue Min(RValue x, RValue y); RValue Clamp(RValue x, RValue min, RValue max); RValue RoundInt(RValue cast); class Long : public LValue { public: // Long(Argument argument); // explicit Long(RValue cast); // explicit Long(RValue cast); explicit Long(RValue cast); explicit Long(RValue cast); // explicit Long(RValue cast); Long() = default; // Long(qword x); Long(RValue rhs); // Long(RValue rhs); // Long(const Long &rhs); // Long(const Reference &rhs); // Long(const ULong &rhs); // Long(const Reference &rhs); RValue operator=(int64_t rhs); RValue operator=(RValue rhs); // RValue operator=(RValue rhs); RValue operator=(const Long &rhs); RValue operator=(const Reference &rhs); // RValue operator=(const ULong &rhs); // RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); // RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); // RValue operator&(RValue lhs, RValue rhs); // RValue operator|(RValue lhs, RValue rhs); // RValue operator^(RValue lhs, RValue rhs); // RValue operator<<(RValue lhs, RValue rhs); // RValue operator>>(RValue lhs, RValue rhs); RValue operator+=(Long &lhs, RValue rhs); RValue operator-=(Long &lhs, RValue rhs); // RValue operator*=(Long &lhs, RValue rhs); // RValue operator/=(Long &lhs, RValue rhs); // RValue operator%=(Long &lhs, RValue rhs); // RValue operator&=(Long &lhs, RValue rhs); // RValue operator|=(Long &lhs, RValue rhs); // RValue operator^=(Long &lhs, RValue rhs); // RValue operator<<=(Long &lhs, RValue rhs); // RValue operator>>=(Long &lhs, RValue rhs); // RValue operator+(RValue val); // RValue operator-(RValue val); // RValue operator~(RValue val); // RValue operator++(Long &val, int); // Post-increment // const Long &operator++(Long &val); // Pre-increment // RValue operator--(Long &val, int); // Post-decrement // const Long &operator--(Long &val); // Pre-decrement // RValue operator<(RValue lhs, RValue rhs); // RValue operator<=(RValue lhs, RValue rhs); // RValue operator>(RValue lhs, RValue rhs); // RValue operator>=(RValue lhs, RValue rhs); // RValue operator!=(RValue lhs, RValue rhs); // RValue operator==(RValue lhs, RValue rhs); // RValue RoundLong(RValue cast); RValue AddAtomic( RValue> x, RValue y); class UInt : public LValue { public: UInt(Argument argument); explicit UInt(RValue cast); explicit UInt(RValue cast); explicit UInt(RValue cast); UInt() = default; UInt(int x); UInt(unsigned int x); UInt(RValue rhs); UInt(RValue rhs); UInt(const UInt &rhs); UInt(const Int &rhs); UInt(const Reference &rhs); UInt(const Reference &rhs); RValue operator=(unsigned int rhs); RValue operator=(RValue rhs); RValue operator=(RValue rhs); RValue operator=(const UInt &rhs); RValue operator=(const Int &rhs); RValue operator=(const Reference &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); RValue operator*(RValue lhs, RValue rhs); RValue operator/(RValue lhs, RValue rhs); RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, RValue rhs); RValue operator>>(RValue lhs, RValue rhs); RValue operator+=(UInt &lhs, RValue rhs); RValue operator-=(UInt &lhs, RValue rhs); RValue operator*=(UInt &lhs, RValue rhs); RValue operator/=(UInt &lhs, RValue rhs); RValue operator%=(UInt &lhs, RValue rhs); RValue operator&=(UInt &lhs, RValue rhs); RValue operator|=(UInt &lhs, RValue rhs); RValue operator^=(UInt &lhs, RValue rhs); RValue operator<<=(UInt &lhs, RValue rhs); RValue operator>>=(UInt &lhs, RValue rhs); RValue operator+(RValue val); RValue operator-(RValue val); RValue operator~(RValue val); RValue operator++(UInt &val, int); // Post-increment const UInt &operator++(UInt &val); // Pre-increment RValue operator--(UInt &val, int); // Post-decrement const UInt &operator--(UInt &val); // Pre-decrement RValue operator<(RValue lhs, RValue rhs); RValue operator<=(RValue lhs, RValue rhs); RValue operator>(RValue lhs, RValue rhs); RValue operator>=(RValue lhs, RValue rhs); RValue operator!=(RValue lhs, RValue rhs); RValue operator==(RValue lhs, RValue rhs); RValue Max(RValue x, RValue y); RValue Min(RValue x, RValue y); RValue Clamp(RValue x, RValue min, RValue max); // RValue RoundUInt(RValue cast); class Int2 : public LValue { public: // explicit Int2(RValue cast); explicit Int2(RValue cast); Int2() = default; Int2(int x, int y); Int2(RValue rhs); Int2(const Int2 &rhs); Int2(const Reference &rhs); Int2(RValue lo, RValue hi); RValue operator=(RValue rhs); RValue operator=(const Int2 &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); // RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, unsigned char rhs); RValue operator>>(RValue lhs, unsigned char rhs); RValue operator+=(Int2 &lhs, RValue rhs); RValue operator-=(Int2 &lhs, RValue rhs); // RValue operator*=(Int2 &lhs, RValue rhs); // RValue operator/=(Int2 &lhs, RValue rhs); // RValue operator%=(Int2 &lhs, RValue rhs); RValue operator&=(Int2 &lhs, RValue rhs); RValue operator|=(Int2 &lhs, RValue rhs); RValue operator^=(Int2 &lhs, RValue rhs); RValue operator<<=(Int2 &lhs, unsigned char rhs); RValue operator>>=(Int2 &lhs, unsigned char rhs); // RValue operator+(RValue val); // RValue operator-(RValue val); RValue operator~(RValue val); // RValue operator++(Int2 &val, int); // Post-increment // const Int2 &operator++(Int2 &val); // Pre-increment // RValue operator--(Int2 &val, int); // Post-decrement // const Int2 &operator--(Int2 &val); // Pre-decrement // RValue operator<(RValue lhs, RValue rhs); // RValue operator<=(RValue lhs, RValue rhs); // RValue operator>(RValue lhs, RValue rhs); // RValue operator>=(RValue lhs, RValue rhs); // RValue operator!=(RValue lhs, RValue rhs); // RValue operator==(RValue lhs, RValue rhs); // RValue RoundInt(RValue cast); RValue UnpackLow(RValue x, RValue y); RValue UnpackHigh(RValue x, RValue y); RValue Extract(RValue val, int i); RValue Insert(RValue val, RValue element, int i); class UInt2 : public LValue { public: UInt2() = default; UInt2(unsigned int x, unsigned int y); UInt2(RValue rhs); UInt2(const UInt2 &rhs); UInt2(const Reference &rhs); RValue operator=(RValue rhs); RValue operator=(const UInt2 &rhs); RValue operator=(const Reference &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); // RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, unsigned char rhs); RValue operator>>(RValue lhs, unsigned char rhs); RValue operator+=(UInt2 &lhs, RValue rhs); RValue operator-=(UInt2 &lhs, RValue rhs); // RValue operator*=(UInt2 &lhs, RValue rhs); // RValue operator/=(UInt2 &lhs, RValue rhs); // RValue operator%=(UInt2 &lhs, RValue rhs); RValue operator&=(UInt2 &lhs, RValue rhs); RValue operator|=(UInt2 &lhs, RValue rhs); RValue operator^=(UInt2 &lhs, RValue rhs); RValue operator<<=(UInt2 &lhs, unsigned char rhs); RValue operator>>=(UInt2 &lhs, unsigned char rhs); // RValue operator+(RValue val); // RValue operator-(RValue val); RValue operator~(RValue val); // RValue operator++(UInt2 &val, int); // Post-increment // const UInt2 &operator++(UInt2 &val); // Pre-increment // RValue operator--(UInt2 &val, int); // Post-decrement // const UInt2 &operator--(UInt2 &val); // Pre-decrement // RValue operator<(RValue lhs, RValue rhs); // RValue operator<=(RValue lhs, RValue rhs); // RValue operator>(RValue lhs, RValue rhs); // RValue operator>=(RValue lhs, RValue rhs); // RValue operator!=(RValue lhs, RValue rhs); // RValue operator==(RValue lhs, RValue rhs); // RValue RoundInt(RValue cast); template struct Scalar; template struct XYZW; template class Swizzle2 { friend Vector4; public: operator RValue() const; private: Vector4 *parent; }; template class Swizzle4 { public: operator RValue() const; private: Vector4 *parent; }; template class SwizzleMask4 { friend XYZW; public: operator RValue() const; RValue operator=(RValue rhs); RValue operator=(RValue::Type> rhs); private: Vector4 *parent; }; template<> struct Scalar { using Type = Float; }; template<> struct Scalar { using Type = Int; }; template<> struct Scalar { using Type = UInt; }; template class SwizzleMask1 { public: operator RValue::Type>() const; operator RValue() const; RValue operator=(float x); RValue operator=(RValue rhs); RValue operator=(RValue::Type> rhs); private: Float4 *parent; }; template class SwizzleMask2 { friend class Float4; public: operator RValue() const; RValue operator=(RValue rhs); private: Float4 *parent; }; template struct XYZW { friend Vector4; private: XYZW(Vector4 *parent) { xyzw.parent = parent; } public: union { SwizzleMask1 x; SwizzleMask1 y; SwizzleMask1 z; SwizzleMask1 w; Swizzle2 xx; Swizzle2 yx; Swizzle2 zx; Swizzle2 wx; SwizzleMask2 xy; Swizzle2 yy; Swizzle2 zy; Swizzle2 wy; SwizzleMask2 xz; SwizzleMask2 yz; Swizzle2 zz; Swizzle2 wz; SwizzleMask2 xw; SwizzleMask2 yw; SwizzleMask2 zw; Swizzle2 ww; Swizzle4 xxx; Swizzle4 yxx; Swizzle4 zxx; Swizzle4 wxx; Swizzle4 xyx; Swizzle4 yyx; Swizzle4 zyx; Swizzle4 wyx; Swizzle4 xzx; Swizzle4 yzx; Swizzle4 zzx; Swizzle4 wzx; Swizzle4 xwx; Swizzle4 ywx; Swizzle4 zwx; Swizzle4 wwx; Swizzle4 xxy; Swizzle4 yxy; Swizzle4 zxy; Swizzle4 wxy; Swizzle4 xyy; Swizzle4 yyy; Swizzle4 zyy; Swizzle4 wyy; Swizzle4 xzy; Swizzle4 yzy; Swizzle4 zzy; Swizzle4 wzy; Swizzle4 xwy; Swizzle4 ywy; Swizzle4 zwy; Swizzle4 wwy; Swizzle4 xxz; Swizzle4 yxz; Swizzle4 zxz; Swizzle4 wxz; SwizzleMask4 xyz; Swizzle4 yyz; Swizzle4 zyz; Swizzle4 wyz; Swizzle4 xzz; Swizzle4 yzz; Swizzle4 zzz; Swizzle4 wzz; Swizzle4 xwz; Swizzle4 ywz; Swizzle4 zwz; Swizzle4 wwz; Swizzle4 xxw; Swizzle4 yxw; Swizzle4 zxw; Swizzle4 wxw; SwizzleMask4 xyw; Swizzle4 yyw; Swizzle4 zyw; Swizzle4 wyw; SwizzleMask4 xzw; SwizzleMask4 yzw; Swizzle4 zzw; Swizzle4 wzw; Swizzle4 xww; Swizzle4 yww; Swizzle4 zww; Swizzle4 www; Swizzle4 xxxx; Swizzle4 yxxx; Swizzle4 zxxx; Swizzle4 wxxx; Swizzle4 xyxx; Swizzle4 yyxx; Swizzle4 zyxx; Swizzle4 wyxx; Swizzle4 xzxx; Swizzle4 yzxx; Swizzle4 zzxx; Swizzle4 wzxx; Swizzle4 xwxx; Swizzle4 ywxx; Swizzle4 zwxx; Swizzle4 wwxx; Swizzle4 xxyx; Swizzle4 yxyx; Swizzle4 zxyx; Swizzle4 wxyx; Swizzle4 xyyx; Swizzle4 yyyx; Swizzle4 zyyx; Swizzle4 wyyx; Swizzle4 xzyx; Swizzle4 yzyx; Swizzle4 zzyx; Swizzle4 wzyx; Swizzle4 xwyx; Swizzle4 ywyx; Swizzle4 zwyx; Swizzle4 wwyx; Swizzle4 xxzx; Swizzle4 yxzx; Swizzle4 zxzx; Swizzle4 wxzx; Swizzle4 xyzx; Swizzle4 yyzx; Swizzle4 zyzx; Swizzle4 wyzx; Swizzle4 xzzx; Swizzle4 yzzx; Swizzle4 zzzx; Swizzle4 wzzx; Swizzle4 xwzx; Swizzle4 ywzx; Swizzle4 zwzx; Swizzle4 wwzx; Swizzle4 xxwx; Swizzle4 yxwx; Swizzle4 zxwx; Swizzle4 wxwx; Swizzle4 xywx; Swizzle4 yywx; Swizzle4 zywx; Swizzle4 wywx; Swizzle4 xzwx; Swizzle4 yzwx; Swizzle4 zzwx; Swizzle4 wzwx; Swizzle4 xwwx; Swizzle4 ywwx; Swizzle4 zwwx; Swizzle4 wwwx; Swizzle4 xxxy; Swizzle4 yxxy; Swizzle4 zxxy; Swizzle4 wxxy; Swizzle4 xyxy; Swizzle4 yyxy; Swizzle4 zyxy; Swizzle4 wyxy; Swizzle4 xzxy; Swizzle4 yzxy; Swizzle4 zzxy; Swizzle4 wzxy; Swizzle4 xwxy; Swizzle4 ywxy; Swizzle4 zwxy; Swizzle4 wwxy; Swizzle4 xxyy; Swizzle4 yxyy; Swizzle4 zxyy; Swizzle4 wxyy; Swizzle4 xyyy; Swizzle4 yyyy; Swizzle4 zyyy; Swizzle4 wyyy; Swizzle4 xzyy; Swizzle4 yzyy; Swizzle4 zzyy; Swizzle4 wzyy; Swizzle4 xwyy; Swizzle4 ywyy; Swizzle4 zwyy; Swizzle4 wwyy; Swizzle4 xxzy; Swizzle4 yxzy; Swizzle4 zxzy; Swizzle4 wxzy; Swizzle4 xyzy; Swizzle4 yyzy; Swizzle4 zyzy; Swizzle4 wyzy; Swizzle4 xzzy; Swizzle4 yzzy; Swizzle4 zzzy; Swizzle4 wzzy; Swizzle4 xwzy; Swizzle4 ywzy; Swizzle4 zwzy; Swizzle4 wwzy; Swizzle4 xxwy; Swizzle4 yxwy; Swizzle4 zxwy; Swizzle4 wxwy; Swizzle4 xywy; Swizzle4 yywy; Swizzle4 zywy; Swizzle4 wywy; Swizzle4 xzwy; Swizzle4 yzwy; Swizzle4 zzwy; Swizzle4 wzwy; Swizzle4 xwwy; Swizzle4 ywwy; Swizzle4 zwwy; Swizzle4 wwwy; Swizzle4 xxxz; Swizzle4 yxxz; Swizzle4 zxxz; Swizzle4 wxxz; Swizzle4 xyxz; Swizzle4 yyxz; Swizzle4 zyxz; Swizzle4 wyxz; Swizzle4 xzxz; Swizzle4 yzxz; Swizzle4 zzxz; Swizzle4 wzxz; Swizzle4 xwxz; Swizzle4 ywxz; Swizzle4 zwxz; Swizzle4 wwxz; Swizzle4 xxyz; Swizzle4 yxyz; Swizzle4 zxyz; Swizzle4 wxyz; Swizzle4 xyyz; Swizzle4 yyyz; Swizzle4 zyyz; Swizzle4 wyyz; Swizzle4 xzyz; Swizzle4 yzyz; Swizzle4 zzyz; Swizzle4 wzyz; Swizzle4 xwyz; Swizzle4 ywyz; Swizzle4 zwyz; Swizzle4 wwyz; Swizzle4 xxzz; Swizzle4 yxzz; Swizzle4 zxzz; Swizzle4 wxzz; Swizzle4 xyzz; Swizzle4 yyzz; Swizzle4 zyzz; Swizzle4 wyzz; Swizzle4 xzzz; Swizzle4 yzzz; Swizzle4 zzzz; Swizzle4 wzzz; Swizzle4 xwzz; Swizzle4 ywzz; Swizzle4 zwzz; Swizzle4 wwzz; Swizzle4 xxwz; Swizzle4 yxwz; Swizzle4 zxwz; Swizzle4 wxwz; Swizzle4 xywz; Swizzle4 yywz; Swizzle4 zywz; Swizzle4 wywz; Swizzle4 xzwz; Swizzle4 yzwz; Swizzle4 zzwz; Swizzle4 wzwz; Swizzle4 xwwz; Swizzle4 ywwz; Swizzle4 zwwz; Swizzle4 wwwz; Swizzle4 xxxw; Swizzle4 yxxw; Swizzle4 zxxw; Swizzle4 wxxw; Swizzle4 xyxw; Swizzle4 yyxw; Swizzle4 zyxw; Swizzle4 wyxw; Swizzle4 xzxw; Swizzle4 yzxw; Swizzle4 zzxw; Swizzle4 wzxw; Swizzle4 xwxw; Swizzle4 ywxw; Swizzle4 zwxw; Swizzle4 wwxw; Swizzle4 xxyw; Swizzle4 yxyw; Swizzle4 zxyw; Swizzle4 wxyw; Swizzle4 xyyw; Swizzle4 yyyw; Swizzle4 zyyw; Swizzle4 wyyw; Swizzle4 xzyw; Swizzle4 yzyw; Swizzle4 zzyw; Swizzle4 wzyw; Swizzle4 xwyw; Swizzle4 ywyw; Swizzle4 zwyw; Swizzle4 wwyw; Swizzle4 xxzw; Swizzle4 yxzw; Swizzle4 zxzw; Swizzle4 wxzw; SwizzleMask4 xyzw; Swizzle4 yyzw; Swizzle4 zyzw; Swizzle4 wyzw; Swizzle4 xzzw; Swizzle4 yzzw; Swizzle4 zzzw; Swizzle4 wzzw; Swizzle4 xwzw; Swizzle4 ywzw; Swizzle4 zwzw; Swizzle4 wwzw; Swizzle4 xxww; Swizzle4 yxww; Swizzle4 zxww; Swizzle4 wxww; Swizzle4 xyww; Swizzle4 yyww; Swizzle4 zyww; Swizzle4 wyww; Swizzle4 xzww; Swizzle4 yzww; Swizzle4 zzww; Swizzle4 wzww; Swizzle4 xwww; Swizzle4 ywww; Swizzle4 zwww; Swizzle4 wwww; }; }; class Int4 : public LValue, public XYZW { public: explicit Int4(RValue cast); explicit Int4(RValue cast); explicit Int4(RValue cast); explicit Int4(RValue cast); explicit Int4(RValue cast); Int4(); Int4(int xyzw); Int4(int x, int yzw); Int4(int x, int y, int zw); Int4(int x, int y, int z, int w); Int4(RValue rhs); Int4(const Int4 &rhs); Int4(const Reference &rhs); Int4(RValue rhs); Int4(const UInt4 &rhs); Int4(const Reference &rhs); Int4(RValue lo, RValue hi); Int4(RValue rhs); Int4(const Int &rhs); Int4(const Reference &rhs); RValue operator=(RValue rhs); RValue operator=(const Int4 &rhs); RValue operator=(const Reference &rhs); static Type *getType(); private: void constant(int x, int y, int z, int w); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); RValue operator*(RValue lhs, RValue rhs); RValue operator/(RValue lhs, RValue rhs); RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, unsigned char rhs); RValue operator>>(RValue lhs, unsigned char rhs); RValue operator<<(RValue lhs, RValue rhs); RValue operator>>(RValue lhs, RValue rhs); RValue operator+=(Int4 &lhs, RValue rhs); RValue operator-=(Int4 &lhs, RValue rhs); RValue operator*=(Int4 &lhs, RValue rhs); // RValue operator/=(Int4 &lhs, RValue rhs); // RValue operator%=(Int4 &lhs, RValue rhs); RValue operator&=(Int4 &lhs, RValue rhs); RValue operator|=(Int4 &lhs, RValue rhs); RValue operator^=(Int4 &lhs, RValue rhs); RValue operator<<=(Int4 &lhs, unsigned char rhs); RValue operator>>=(Int4 &lhs, unsigned char rhs); RValue operator+(RValue val); RValue operator-(RValue val); RValue operator~(RValue val); // RValue operator++(Int4 &val, int); // Post-increment // const Int4 &operator++(Int4 &val); // Pre-increment // RValue operator--(Int4 &val, int); // Post-decrement // const Int4 &operator--(Int4 &val); // Pre-decrement // RValue operator<(RValue lhs, RValue rhs); // RValue operator<=(RValue lhs, RValue rhs); // RValue operator>(RValue lhs, RValue rhs); // RValue operator>=(RValue lhs, RValue rhs); // RValue operator!=(RValue lhs, RValue rhs); // RValue operator==(RValue lhs, RValue rhs); RValue CmpEQ(RValue x, RValue y); RValue CmpLT(RValue x, RValue y); RValue CmpLE(RValue x, RValue y); RValue CmpNEQ(RValue x, RValue y); RValue CmpNLT(RValue x, RValue y); RValue CmpNLE(RValue x, RValue y); RValue Max(RValue x, RValue y); RValue Min(RValue x, RValue y); RValue RoundInt(RValue cast); RValue Pack(RValue x, RValue y); RValue Extract(RValue val, int i); RValue Insert(RValue val, RValue element, int i); RValue SignMask(RValue x); RValue Swizzle(RValue x, unsigned char select); class UInt4 : public LValue, public XYZW { public: explicit UInt4(RValue cast); UInt4(); UInt4(int xyzw); UInt4(int x, int yzw); UInt4(int x, int y, int zw); UInt4(int x, int y, int z, int w); UInt4(unsigned int x, unsigned int y, unsigned int z, unsigned int w); UInt4(RValue rhs); UInt4(const UInt4 &rhs); UInt4(const Reference &rhs); UInt4(RValue rhs); UInt4(const Int4 &rhs); UInt4(const Reference &rhs); UInt4(RValue lo, RValue hi); RValue operator=(RValue rhs); RValue operator=(const UInt4 &rhs); RValue operator=(const Reference &rhs); static Type *getType(); private: void constant(int x, int y, int z, int w); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); RValue operator*(RValue lhs, RValue rhs); RValue operator/(RValue lhs, RValue rhs); RValue operator%(RValue lhs, RValue rhs); RValue operator&(RValue lhs, RValue rhs); RValue operator|(RValue lhs, RValue rhs); RValue operator^(RValue lhs, RValue rhs); RValue operator<<(RValue lhs, unsigned char rhs); RValue operator>>(RValue lhs, unsigned char rhs); RValue operator<<(RValue lhs, RValue rhs); RValue operator>>(RValue lhs, RValue rhs); RValue operator+=(UInt4 &lhs, RValue rhs); RValue operator-=(UInt4 &lhs, RValue rhs); RValue operator*=(UInt4 &lhs, RValue rhs); // RValue operator/=(UInt4 &lhs, RValue rhs); // RValue operator%=(UInt4 &lhs, RValue rhs); RValue operator&=(UInt4 &lhs, RValue rhs); RValue operator|=(UInt4 &lhs, RValue rhs); RValue operator^=(UInt4 &lhs, RValue rhs); RValue operator<<=(UInt4 &lhs, unsigned char rhs); RValue operator>>=(UInt4 &lhs, unsigned char rhs); RValue operator+(RValue val); RValue operator-(RValue val); RValue operator~(RValue val); // RValue operator++(UInt4 &val, int); // Post-increment // const UInt4 &operator++(UInt4 &val); // Pre-increment // RValue operator--(UInt4 &val, int); // Post-decrement // const UInt4 &operator--(UInt4 &val); // Pre-decrement // RValue operator<(RValue lhs, RValue rhs); // RValue operator<=(RValue lhs, RValue rhs); // RValue operator>(RValue lhs, RValue rhs); // RValue operator>=(RValue lhs, RValue rhs); // RValue operator!=(RValue lhs, RValue rhs); // RValue operator==(RValue lhs, RValue rhs); RValue CmpEQ(RValue x, RValue y); RValue CmpLT(RValue x, RValue y); RValue CmpLE(RValue x, RValue y); RValue CmpNEQ(RValue x, RValue y); RValue CmpNLT(RValue x, RValue y); RValue CmpNLE(RValue x, RValue y); RValue Max(RValue x, RValue y); RValue Min(RValue x, RValue y); // RValue RoundInt(RValue cast); RValue Pack(RValue x, RValue y); class Float : public LValue { public: explicit Float(RValue cast); explicit Float(RValue cast); Float() = default; Float(float x); Float(RValue rhs); Float(const Float &rhs); Float(const Reference &rhs); template Float(const SwizzleMask1 &rhs); // RValue operator=(float rhs); // FIXME: Implement RValue operator=(RValue rhs); RValue operator=(const Float &rhs); RValue operator=(const Reference &rhs); template RValue operator=(const SwizzleMask1 &rhs); static Type *getType(); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); RValue operator*(RValue lhs, RValue rhs); RValue operator/(RValue lhs, RValue rhs); RValue operator+=(Float &lhs, RValue rhs); RValue operator-=(Float &lhs, RValue rhs); RValue operator*=(Float &lhs, RValue rhs); RValue operator/=(Float &lhs, RValue rhs); RValue operator+(RValue val); RValue operator-(RValue val); RValue operator<(RValue lhs, RValue rhs); RValue operator<=(RValue lhs, RValue rhs); RValue operator>(RValue lhs, RValue rhs); RValue operator>=(RValue lhs, RValue rhs); RValue operator!=(RValue lhs, RValue rhs); RValue operator==(RValue lhs, RValue rhs); RValue Abs(RValue x); RValue Max(RValue x, RValue y); RValue Min(RValue x, RValue y); RValue Rcp_pp(RValue val, bool exactAtPow2 = false); RValue RcpSqrt_pp(RValue val); RValue Sqrt(RValue x); RValue Round(RValue val); RValue Trunc(RValue val); RValue Frac(RValue val); RValue Floor(RValue val); RValue Ceil(RValue val); class Float2 : public LValue { public: // explicit Float2(RValue cast); // explicit Float2(RValue cast); // explicit Float2(RValue cast); // explicit Float2(RValue cast); // explicit Float2(RValue cast); explicit Float2(RValue cast); Float2() = default; // Float2(float x, float y); // Float2(RValue rhs); // Float2(const Float2 &rhs); // Float2(const Reference &rhs); // Float2(RValue rhs); // Float2(const Float &rhs); // Float2(const Reference &rhs); // template // Float2(const SwizzleMask1 &rhs); // RValue operator=(float replicate); // RValue operator=(RValue rhs); // RValue operator=(const Float2 &rhs); // RValue operator=(const Reference &rhs); // RValue operator=(RValue rhs); // RValue operator=(const Float &rhs); // RValue operator=(const Reference &rhs); // template // RValue operator=(const SwizzleMask1 &rhs); static Type *getType(); }; // RValue operator+(RValue lhs, RValue rhs); // RValue operator-(RValue lhs, RValue rhs); // RValue operator*(RValue lhs, RValue rhs); // RValue operator/(RValue lhs, RValue rhs); // RValue operator%(RValue lhs, RValue rhs); // RValue operator+=(Float2 &lhs, RValue rhs); // RValue operator-=(Float2 &lhs, RValue rhs); // RValue operator*=(Float2 &lhs, RValue rhs); // RValue operator/=(Float2 &lhs, RValue rhs); // RValue operator%=(Float2 &lhs, RValue rhs); // RValue operator+(RValue val); // RValue operator-(RValue val); // RValue Abs(RValue x); // RValue Max(RValue x, RValue y); // RValue Min(RValue x, RValue y); // RValue Swizzle(RValue x, unsigned char select); // RValue Mask(Float2 &lhs, RValue rhs, unsigned char select); class Float4 : public LValue, public XYZW { public: explicit Float4(RValue cast); explicit Float4(RValue cast); explicit Float4(RValue cast); explicit Float4(RValue cast); explicit Float4(RValue cast); explicit Float4(RValue cast); Float4(); Float4(float xyzw); Float4(float x, float yzw); Float4(float x, float y, float zw); Float4(float x, float y, float z, float w); Float4(RValue rhs); Float4(const Float4 &rhs); Float4(const Reference &rhs); Float4(RValue rhs); Float4(const Float &rhs); Float4(const Reference &rhs); template Float4(const SwizzleMask1 &rhs); template Float4(const Swizzle4 &rhs); template Float4(const Swizzle2 &x, const Swizzle2 &y); template Float4(const SwizzleMask2 &x, const Swizzle2 &y); template Float4(const Swizzle2 &x, const SwizzleMask2 &y); template Float4(const SwizzleMask2 &x, const SwizzleMask2 &y); RValue operator=(float replicate); RValue operator=(RValue rhs); RValue operator=(const Float4 &rhs); RValue operator=(const Reference &rhs); RValue operator=(RValue rhs); RValue operator=(const Float &rhs); RValue operator=(const Reference &rhs); template RValue operator=(const SwizzleMask1 &rhs); template RValue operator=(const Swizzle4 &rhs); static Type *getType(); private: void constant(float x, float y, float z, float w); }; RValue operator+(RValue lhs, RValue rhs); RValue operator-(RValue lhs, RValue rhs); RValue operator*(RValue lhs, RValue rhs); RValue operator/(RValue lhs, RValue rhs); RValue operator%(RValue lhs, RValue rhs); RValue operator+=(Float4 &lhs, RValue rhs); RValue operator-=(Float4 &lhs, RValue rhs); RValue operator*=(Float4 &lhs, RValue rhs); RValue operator/=(Float4 &lhs, RValue rhs); RValue operator%=(Float4 &lhs, RValue rhs); RValue operator+(RValue val); RValue operator-(RValue val); RValue Abs(RValue x); RValue Max(RValue x, RValue y); RValue Min(RValue x, RValue y); RValue Rcp_pp(RValue val, bool exactAtPow2 = false); RValue RcpSqrt_pp(RValue val); RValue Sqrt(RValue x); RValue Insert(RValue val, RValue element, int i); RValue Extract(RValue x, int i); RValue Swizzle(RValue x, unsigned char select); RValue ShuffleLowHigh(RValue x, RValue y, unsigned char imm); RValue UnpackLow(RValue x, RValue y); RValue UnpackHigh(RValue x, RValue y); RValue Mask(Float4 &lhs, RValue rhs, unsigned char select); RValue SignMask(RValue x); RValue CmpEQ(RValue x, RValue y); RValue CmpLT(RValue x, RValue y); RValue CmpLE(RValue x, RValue y); RValue CmpNEQ(RValue x, RValue y); RValue CmpNLT(RValue x, RValue y); RValue CmpNLE(RValue x, RValue y); RValue Round(RValue x); RValue Trunc(RValue x); RValue Frac(RValue x); RValue Floor(RValue x); RValue Ceil(RValue x); template class Pointer : public LValue> { public: template Pointer(RValue> pointerS, int alignment = 1) : alignment(alignment) { Value *pointerT = Nucleus::createBitCast(pointerS.value, Nucleus::getPointerType(T::getType())); LValue>::storeValue(pointerT); } template Pointer(const Pointer &pointer, int alignment = 1) : alignment(alignment) { Value *pointerS = pointer.loadValue(); Value *pointerT = Nucleus::createBitCast(pointerS, Nucleus::getPointerType(T::getType())); LValue>::storeValue(pointerT); } Pointer(Argument> argument); Pointer(); Pointer(RValue> rhs); Pointer(const Pointer &rhs); Pointer(const Reference> &rhs); RValue> operator=(RValue> rhs); RValue> operator=(const Pointer &rhs); RValue> operator=(const Reference> &rhs); Reference operator*(); Reference operator[](int index); Reference operator[](unsigned int index); Reference operator[](RValue index); Reference operator[](RValue index); static Type *getType(); private: const int alignment; }; RValue> operator+(RValue> lhs, int offset); RValue> operator+(RValue> lhs, RValue offset); RValue> operator+(RValue> lhs, RValue offset); RValue> operator+=(Pointer &lhs, int offset); RValue> operator+=(Pointer &lhs, RValue offset); RValue> operator+=(Pointer &lhs, RValue offset); RValue> operator-(RValue> lhs, int offset); RValue> operator-(RValue> lhs, RValue offset); RValue> operator-(RValue> lhs, RValue offset); RValue> operator-=(Pointer &lhs, int offset); RValue> operator-=(Pointer &lhs, RValue offset); RValue> operator-=(Pointer &lhs, RValue offset); template class Array : public LValue { public: Array(int size = S); Reference operator[](int index); Reference operator[](unsigned int index); Reference operator[](RValue index); Reference operator[](RValue index); }; // RValue> operator++(Array &val, int); // Post-increment // const Array &operator++(Array &val); // Pre-increment // RValue> operator--(Array &val, int); // Post-decrement // const Array &operator--(Array &val); // Pre-decrement void branch(RValue cmp, BasicBlock *bodyBB, BasicBlock *endBB); void Return(); void Return(RValue ret); template void Return(const Pointer &ret); template void Return(RValue> ret); template struct ArgI; template struct ArgI<0, Arg0, Arguments...> { typedef Arg0 Type; }; template struct ArgI { typedef typename ArgI::Type Type; }; // Generic template, leave undefined! template class Function; // Specialized for function types template class Function { public: Function(); virtual ~Function(); template Argument::Type> Arg() const { Value *arg = Nucleus::getArgument(index); return Argument::Type>(arg); } Routine *operator()(const wchar_t *name, ...); protected: Nucleus *core; std::vector arguments; }; template class Function : public Function { }; template Argument::Type> Arg(Function &function) { return Argument::Type>(function.arg(index)); } RValue Ticks(); } namespace sw { template LValue::LValue(int arraySize) { address = Nucleus::allocateStackVariable(T::getType(), arraySize); } template Value *LValue::loadValue() const { return Nucleus::createLoad(address, T::getType(), false, 0); } template Value *LValue::storeValue(Value *value) const { return Nucleus::createStore(value, address, T::getType(), false, 0); } template Value *LValue::getAddress(Value *index, bool unsignedIndex) const { return Nucleus::createGEP(address, T::getType(), index, unsignedIndex); } template RValue> LValue::operator&() { return RValue>(address); } template Reference::Reference(Value *pointer, int alignment) : alignment(alignment) { address = pointer; } template RValue Reference::operator=(RValue rhs) const { Nucleus::createStore(rhs.value, address, T::getType(), false, alignment); return rhs; } template RValue Reference::operator=(const Reference &ref) const { Value *tmp = Nucleus::createLoad(ref.address, T::getType(), false, ref.alignment); Nucleus::createStore(tmp, address, T::getType(), false, alignment); return RValue(tmp); } template RValue Reference::operator+=(RValue rhs) const { return *this = *this + rhs; } template Value *Reference::loadValue() const { return Nucleus::createLoad(address, T::getType(), false, alignment); } template int Reference::getAlignment() const { return alignment; } template RValue::RValue(Value *rvalue) { assert(Nucleus::createBitCast(rvalue, T::getType()) == rvalue); // Run-time type should match T, so bitcast is no-op. value = rvalue; } template RValue::RValue(const T &lvalue) { value = lvalue.loadValue(); } template RValue::RValue(typename IntLiteral::type i) { value = Nucleus::createConstantInt(i); } template RValue::RValue(typename FloatLiteral::type f) { value = Nucleus::createConstantFloat(f); } template RValue::RValue(const Reference &ref) { value = ref.loadValue(); } template Swizzle2::operator RValue() const { Value *vector = parent->loadValue(); return Swizzle(RValue(vector), T); } template Swizzle4::operator RValue() const { Value *vector = parent->loadValue(); return Swizzle(RValue(vector), T); } template SwizzleMask4::operator RValue() const { Value *vector = parent->loadValue(); return Swizzle(RValue(vector), T); } template RValue SwizzleMask4::operator=(RValue rhs) { return Mask(*parent, rhs, T); } template RValue SwizzleMask4::operator=(RValue::Type> rhs) { return Mask(*parent, Vector4(rhs), T); } template SwizzleMask1::operator RValue::Type>() const // FIXME: Call a non-template function { return Extract(*parent, T & 0x3); } template SwizzleMask1::operator RValue() const { Value *vector = parent->loadValue(); return Swizzle(RValue(vector), T); } template RValue SwizzleMask1::operator=(float x) { return *parent = Insert(*parent, Float(x), T & 0x3); } template RValue SwizzleMask1::operator=(RValue rhs) { return Mask(*parent, Float4(rhs), T); } template RValue SwizzleMask1::operator=(RValue::Type> rhs) // FIXME: Call a non-template function { return *parent = Insert(*parent, rhs, T & 0x3); } template SwizzleMask2::operator RValue() const { Value *vector = parent->loadValue(); return Swizzle(RValue(vector), T); } template RValue SwizzleMask2::operator=(RValue rhs) { return Mask(*parent, Float4(rhs), T); } template Float::Float(const SwizzleMask1 &rhs) { *this = rhs.operator RValue(); } template RValue Float::operator=(const SwizzleMask1 &rhs) { return *this = rhs.operator RValue(); } template Float4::Float4(const SwizzleMask1 &rhs) : XYZW(this) { *this = rhs.operator RValue(); } template Float4::Float4(const Swizzle4 &rhs) : XYZW(this) { *this = rhs.operator RValue(); } template Float4::Float4(const Swizzle2 &x, const Swizzle2 &y) : XYZW(this) { *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4); } template Float4::Float4(const SwizzleMask2 &x, const Swizzle2 &y) : XYZW(this) { *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4); } template Float4::Float4(const Swizzle2 &x, const SwizzleMask2 &y) : XYZW(this) { *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4); } template Float4::Float4(const SwizzleMask2 &x, const SwizzleMask2 &y) : XYZW(this) { *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4); } template RValue Float4::operator=(const SwizzleMask1 &rhs) { return *this = rhs.operator RValue(); } template RValue Float4::operator=(const Swizzle4 &rhs) { return *this = rhs.operator RValue(); } template Pointer::Pointer(Argument> argument) : alignment(1) { LValue>::storeValue(argument.value); } template Pointer::Pointer() : alignment(1) { LValue>::storeValue(Nucleus::createNullPointer(T::getType())); } template Pointer::Pointer(RValue> rhs) : alignment(1) { LValue>::storeValue(rhs.value); } template Pointer::Pointer(const Pointer &rhs) : alignment(rhs.alignment) { Value *value = rhs.loadValue(); LValue>::storeValue(value); } template Pointer::Pointer(const Reference> &rhs) : alignment(rhs.getAlignment()) { Value *value = rhs.loadValue(); LValue>::storeValue(value); } template RValue> Pointer::operator=(RValue> rhs) { LValue>::storeValue(rhs.value); return rhs; } template RValue> Pointer::operator=(const Pointer &rhs) { Value *value = rhs.loadValue(); LValue>::storeValue(value); return RValue>(value); } template RValue> Pointer::operator=(const Reference> &rhs) { Value *value = rhs.loadValue(); LValue>::storeValue(value); return RValue>(value); } template Reference Pointer::operator*() { return Reference(LValue>::loadValue(), alignment); } template Reference Pointer::operator[](int index) { Value *element = Nucleus::createGEP(LValue>::loadValue(), T::getType(), Nucleus::createConstantInt(index), false); return Reference(element, alignment); } template Reference Pointer::operator[](unsigned int index) { Value *element = Nucleus::createGEP(LValue>::loadValue(), T::getType(), Nucleus::createConstantInt(index), true); return Reference(element, alignment); } template Reference Pointer::operator[](RValue index) { Value *element = Nucleus::createGEP(LValue>::loadValue(), T::getType(), index.value, false); return Reference(element, alignment); } template Reference Pointer::operator[](RValue index) { Value *element = Nucleus::createGEP(LValue>::loadValue(), T::getType(), index.value, true); return Reference(element, alignment); } template Type *Pointer::getType() { return Nucleus::getPointerType(T::getType()); } template Array::Array(int size) : LValue(size) { } template Reference Array::operator[](int index) { Value *element = LValue::getAddress(Nucleus::createConstantInt(index), false); return Reference(element); } template Reference Array::operator[](unsigned int index) { Value *element = LValue::getAddress(Nucleus::createConstantInt(index), true); return Reference(element); } template Reference Array::operator[](RValue index) { Value *element = LValue::getAddress(index.value, false); return Reference(element); } template Reference Array::operator[](RValue index) { Value *element = LValue::getAddress(index.value, true); return Reference(element); } // template // RValue> operator++(Array &val, int) // { // // FIXME: Requires storing the address of the array // } // template // const Array &operator++(Array &val) // { // // FIXME: Requires storing the address of the array // } // template // RValue> operator--(Array &val, int) // { // // FIXME: Requires storing the address of the array // } // template // const Array &operator--(Array &val) // { // // FIXME: Requires storing the address of the array // } template RValue IfThenElse(RValue condition, RValue ifTrue, RValue ifFalse) { return RValue(Nucleus::createSelect(condition.value, ifTrue.value, ifFalse.value)); } template RValue IfThenElse(RValue condition, const T &ifTrue, RValue ifFalse) { Value *trueValue = ifTrue.loadValue(); return RValue(Nucleus::createSelect(condition.value, trueValue, ifFalse.value)); } template RValue IfThenElse(RValue condition, RValue ifTrue, const T &ifFalse) { Value *falseValue = ifFalse.loadValue(); return RValue(Nucleus::createSelect(condition.value, ifTrue.value, falseValue)); } template RValue IfThenElse(RValue condition, const T &ifTrue, const T &ifFalse) { Value *trueValue = ifTrue.loadValue(); Value *falseValue = ifFalse.loadValue(); return RValue(Nucleus::createSelect(condition.value, trueValue, falseValue)); } template void Return(const Pointer &ret) { Nucleus::createRet(Nucleus::createLoad(ret.address, Pointer::getType())); Nucleus::setInsertBlock(Nucleus::createBasicBlock()); } template void Return(RValue> ret) { Nucleus::createRet(ret.value); Nucleus::setInsertBlock(Nucleus::createBasicBlock()); } template Function::Function() { core = new Nucleus(); Type *types[] = {Arguments::getType()...}; for(Type *type : types) { if(type != Void::getType()) { arguments.push_back(type); } } Nucleus::createFunction(Return::getType(), arguments); } template Function::~Function() { delete core; } template Routine *Function::operator()(const wchar_t *name, ...) { wchar_t fullName[1024 + 1]; va_list vararg; va_start(vararg, name); vswprintf(fullName, 1024, name, vararg); va_end(vararg); return core->acquireRoutine(fullName, true); } template RValue ReinterpretCast(RValue val) { return RValue(Nucleus::createBitCast(val.value, T::getType())); } template RValue ReinterpretCast(const LValue &var) { Value *val = var.loadValue(); return RValue(Nucleus::createBitCast(val, T::getType())); } template RValue ReinterpretCast(const Reference &var) { return ReinterpretCast(RValue(var)); } template RValue As(Value *val) { return RValue(Nucleus::createBitCast(val, T::getType())); } template RValue As(RValue val) { return ReinterpretCast(val); } template RValue As(const LValue &var) { return ReinterpretCast(var); } template RValue As(const Reference &val) { return ReinterpretCast(val); } class ForData { public: ForData(bool init) : loopOnce(init) { } operator bool() { return loopOnce; } bool operator=(bool value) { return loopOnce = value; } bool setup() { if(Nucleus::getInsertBlock() != endBB) { testBB = Nucleus::createBasicBlock(); Nucleus::createBr(testBB); Nucleus::setInsertBlock(testBB); return true; } return false; } bool test(RValue cmp) { BasicBlock *bodyBB = Nucleus::createBasicBlock(); endBB = Nucleus::createBasicBlock(); Nucleus::createCondBr(cmp.value, bodyBB, endBB); Nucleus::setInsertBlock(bodyBB); return true; } void end() { Nucleus::createBr(testBB); Nucleus::setInsertBlock(endBB); } private: BasicBlock *testBB = nullptr; BasicBlock *endBB = nullptr; bool loopOnce = true; }; class IfElseData { public: IfElseData(RValue cmp) : iteration(0) { condition = cmp.value; beginBB = Nucleus::getInsertBlock(); trueBB = Nucleus::createBasicBlock(); falseBB = nullptr; endBB = Nucleus::createBasicBlock(); Nucleus::setInsertBlock(trueBB); } ~IfElseData() { Nucleus::createBr(endBB); Nucleus::setInsertBlock(beginBB); Nucleus::createCondBr(condition, trueBB, falseBB ? falseBB : endBB); Nucleus::setInsertBlock(endBB); } operator int() { return iteration; } IfElseData &operator++() { ++iteration; return *this; } void elseClause() { Nucleus::createBr(endBB); falseBB = Nucleus::createBasicBlock(); Nucleus::setInsertBlock(falseBB); } private: Value *condition; BasicBlock *beginBB; BasicBlock *trueBB; BasicBlock *falseBB; BasicBlock *endBB; int iteration; }; #define For(init, cond, inc) \ for(ForData for__ = true; for__; for__ = false) \ for(init; for__.setup() && for__.test(cond); inc, for__.end()) #define While(cond) For((void)0, cond, (void)0) #define Do \ { \ BasicBlock *body__ = Nucleus::createBasicBlock(); \ Nucleus::createBr(body__); \ Nucleus::setInsertBlock(body__); #define Until(cond) \ BasicBlock *end__ = Nucleus::createBasicBlock(); \ Nucleus::createCondBr((cond).value, end__, body__); \ Nucleus::setInsertBlock(end__); \ } enum {IF_BLOCK__, ELSE_CLAUSE__, ELSE_BLOCK__, IFELSE_NUM__}; #define If(cond) \ for(IfElseData ifElse__(cond); ifElse__ < IFELSE_NUM__; ++ifElse__) \ if(ifElse__ == IF_BLOCK__) #define Else \ else if(ifElse__ == ELSE_CLAUSE__) \ { \ ifElse__.elseClause(); \ } \ else // ELSE_BLOCK__ } #endif // sw_Reactor_hpp