blob: 488c0bee2a96c19bbbafe80089e67760959cfb6f [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Nicolas Capens48461502018-08-06 14:20:45 -040015#ifndef rr_Reactor_hpp
16#define rr_Reactor_hpp
Nicolas Capensd022e412016-09-26 13:30:14 -040017
Nicolas Capens0bac2852016-05-07 06:09:58 -040018#include "Nucleus.hpp"
19#include "Routine.hpp"
Ben Clayton351be422019-04-30 12:26:57 +010020#include "Traits.hpp"
Nicolas Capens0bac2852016-05-07 06:09:58 -040021
Nicolas Capens4dd1eff2017-08-04 09:33:04 -040022#include <cassert>
Nicolas Capens3bbc5e12016-09-27 10:49:52 -040023#include <cstddef>
Chris Forbes878d4b02019-01-21 10:48:35 -080024#include <cstdio>
Nicolas Capense5720882020-01-13 14:10:04 -050025#include <limits>
Ben Clayton169872e2019-02-27 23:58:35 +000026#include <tuple>
Nicolas Capens0192d152019-03-27 14:46:07 -040027#include <unordered_set>
Ben Clayton1bc7ee92019-02-14 18:43:22 +000028
Ben Clayton713b8d32019-12-17 20:37:56 +000029#undef Bool // b/127920555
Nicolas Capens3bbc5e12016-09-27 10:49:52 -040030
Ben Claytonac07ed82019-03-26 14:17:41 +000031#ifdef ENABLE_RR_DEBUG_INFO
Ben Clayton713b8d32019-12-17 20:37:56 +000032// Functions used for generating JIT debug info.
33// See docs/ReactorDebugInfo.md for more information.
34namespace rr {
35// Update the current source location for debug.
36void EmitDebugLocation();
37// Bind value to its symbolic name taken from the backtrace.
38void EmitDebugVariable(class Value *value);
39// Flush any pending variable bindings before the line ends.
40void FlushDebug();
41} // namespace rr
42# define RR_DEBUG_INFO_UPDATE_LOC() rr::EmitDebugLocation()
43# define RR_DEBUG_INFO_EMIT_VAR(value) rr::EmitDebugVariable(value)
44# define RR_DEBUG_INFO_FLUSH() rr::FlushDebug()
Ben Claytonac07ed82019-03-26 14:17:41 +000045#else
Ben Clayton713b8d32019-12-17 20:37:56 +000046# define RR_DEBUG_INFO_UPDATE_LOC()
47# define RR_DEBUG_INFO_EMIT_VAR(value)
48# define RR_DEBUG_INFO_FLUSH()
49#endif // ENABLE_RR_DEBUG_INFO
Ben Claytonac07ed82019-03-26 14:17:41 +000050
Nicolas Capens157ba262019-12-10 17:49:14 -050051namespace rr {
52
Antonio Maioranoab210f92019-12-13 16:26:24 -050053std::string BackendName();
54
Nicolas Capens157ba262019-12-10 17:49:14 -050055struct Capabilities
Nicolas Capens0bac2852016-05-07 06:09:58 -040056{
Ben Clayton713b8d32019-12-17 20:37:56 +000057 bool CoroutinesSupported; // Support for rr::Coroutine<F>
Nicolas Capens157ba262019-12-10 17:49:14 -050058};
59extern const Capabilities Caps;
60
61class Bool;
62class Byte;
63class SByte;
64class Byte4;
65class SByte4;
66class Byte8;
67class SByte8;
68class Byte16;
69class SByte16;
70class Short;
71class UShort;
72class Short2;
73class UShort2;
74class Short4;
75class UShort4;
76class Short8;
77class UShort8;
78class Int;
79class UInt;
80class Int2;
81class UInt2;
82class Int4;
83class UInt4;
84class Long;
85class Half;
86class Float;
87class Float2;
88class Float4;
89
90class Void
91{
92public:
93 static Type *getType();
94
95 static bool isVoid()
Ben Claytonc7904162019-04-17 17:35:48 -040096 {
Nicolas Capens157ba262019-12-10 17:49:14 -050097 return true;
98 }
99};
Ben Claytonc7904162019-04-17 17:35:48 -0400100
Nicolas Capens157ba262019-12-10 17:49:14 -0500101template<class T>
102class RValue;
Nicolas Capensd022e412016-09-26 13:30:14 -0400103
Nicolas Capens157ba262019-12-10 17:49:14 -0500104template<class T>
105class Pointer;
106
107class Variable
108{
109 friend class Nucleus;
110 friend class PrintValue;
111
112 Variable() = delete;
Ben Clayton713b8d32019-12-17 20:37:56 +0000113 Variable &operator=(const Variable &) = delete;
Nicolas Capens157ba262019-12-10 17:49:14 -0500114
115public:
116 void materialize() const;
117
118 Value *loadValue() const;
119 Value *storeValue(Value *value) const;
120
121 Value *getBaseAddress() const;
122 Value *getElementPointer(Value *index, bool unsignedIndex) const;
123
124protected:
125 Variable(Type *type, int arraySize);
Ben Clayton713b8d32019-12-17 20:37:56 +0000126 Variable(const Variable &) = default;
Nicolas Capens157ba262019-12-10 17:49:14 -0500127
128 ~Variable();
129
130 const int arraySize;
131
132private:
133 static void materializeAll();
134 static void killUnmaterialized();
135
Ben Clayton713b8d32019-12-17 20:37:56 +0000136 static std::unordered_set<Variable *> unmaterializedVariables;
Nicolas Capens157ba262019-12-10 17:49:14 -0500137
138 Type *const type;
139 mutable Value *rvalue = nullptr;
140 mutable Value *address = nullptr;
141};
142
143template<class T>
144class LValue : public Variable
145{
146public:
147 LValue(int arraySize = 0);
148
149 RValue<Pointer<T>> operator&();
150
151 static bool isVoid()
Nicolas Capensd022e412016-09-26 13:30:14 -0400152 {
Nicolas Capens157ba262019-12-10 17:49:14 -0500153 return false;
154 }
Nicolas Capensd022e412016-09-26 13:30:14 -0400155
Nicolas Capens157ba262019-12-10 17:49:14 -0500156 // self() returns the this pointer to this LValue<T> object.
157 // This function exists because operator&() is overloaded.
Ben Clayton713b8d32019-12-17 20:37:56 +0000158 inline LValue<T> *self() { return this; }
Nicolas Capens157ba262019-12-10 17:49:14 -0500159};
Nicolas Capensd022e412016-09-26 13:30:14 -0400160
Nicolas Capens157ba262019-12-10 17:49:14 -0500161template<class T>
162class Reference
163{
164public:
165 using reference_underlying_type = T;
Nicolas Capensd022e412016-09-26 13:30:14 -0400166
Nicolas Capens157ba262019-12-10 17:49:14 -0500167 explicit Reference(Value *pointer, int alignment = 1);
Nicolas Capensd022e412016-09-26 13:30:14 -0400168
Nicolas Capens157ba262019-12-10 17:49:14 -0500169 RValue<T> operator=(RValue<T> rhs) const;
170 RValue<T> operator=(const Reference<T> &ref) const;
Nicolas Capens5da8d8d2019-03-27 14:45:34 -0400171
Nicolas Capens157ba262019-12-10 17:49:14 -0500172 RValue<T> operator+=(RValue<T> rhs) const;
Nicolas Capens5da8d8d2019-03-27 14:45:34 -0400173
Nicolas Capens157ba262019-12-10 17:49:14 -0500174 RValue<Pointer<T>> operator&() const { return RValue<Pointer<T>>(address); }
Nicolas Capens0192d152019-03-27 14:46:07 -0400175
Nicolas Capens157ba262019-12-10 17:49:14 -0500176 Value *loadValue() const;
177 int getAlignment() const;
Nicolas Capens0192d152019-03-27 14:46:07 -0400178
Nicolas Capens157ba262019-12-10 17:49:14 -0500179private:
180 Value *address;
Nicolas Capens5da8d8d2019-03-27 14:45:34 -0400181
Nicolas Capens157ba262019-12-10 17:49:14 -0500182 const int alignment;
183};
Nicolas Capens0192d152019-03-27 14:46:07 -0400184
Nicolas Capens157ba262019-12-10 17:49:14 -0500185template<class T>
186struct BoolLiteral
187{
188 struct type;
189};
Nicolas Capens0192d152019-03-27 14:46:07 -0400190
Nicolas Capens157ba262019-12-10 17:49:14 -0500191template<>
192struct BoolLiteral<Bool>
193{
194 typedef bool type;
195};
Ben Clayton83dd4522019-06-27 10:37:00 +0100196
Nicolas Capens157ba262019-12-10 17:49:14 -0500197template<class T>
198struct IntLiteral
199{
200 struct type;
201};
Nicolas Capens0192d152019-03-27 14:46:07 -0400202
Nicolas Capens157ba262019-12-10 17:49:14 -0500203template<>
204struct IntLiteral<Int>
205{
206 typedef int type;
207};
Nicolas Capens0192d152019-03-27 14:46:07 -0400208
Nicolas Capens157ba262019-12-10 17:49:14 -0500209template<>
210struct IntLiteral<UInt>
211{
212 typedef unsigned int type;
213};
Nicolas Capens297d26e2016-11-18 12:52:17 -0500214
Nicolas Capens157ba262019-12-10 17:49:14 -0500215template<>
216struct IntLiteral<Long>
217{
218 typedef int64_t type;
219};
Nicolas Capensd022e412016-09-26 13:30:14 -0400220
Nicolas Capens157ba262019-12-10 17:49:14 -0500221template<class T>
222struct FloatLiteral
223{
224 struct type;
225};
Nicolas Capens297d26e2016-11-18 12:52:17 -0500226
Nicolas Capens157ba262019-12-10 17:49:14 -0500227template<>
228struct FloatLiteral<Float>
229{
230 typedef float type;
231};
Ben Clayton0953d9b2019-06-25 20:57:06 +0100232
Nicolas Capens157ba262019-12-10 17:49:14 -0500233template<class T>
234class RValue
235{
236public:
237 using rvalue_underlying_type = T;
Nicolas Capensd022e412016-09-26 13:30:14 -0400238
Nicolas Capens157ba262019-12-10 17:49:14 -0500239 explicit RValue(Value *rvalue);
Nicolas Capensd022e412016-09-26 13:30:14 -0400240
Ben Claytonac07ed82019-03-26 14:17:41 +0000241#ifdef ENABLE_RR_DEBUG_INFO
Nicolas Capens157ba262019-12-10 17:49:14 -0500242 RValue(const RValue<T> &rvalue);
Ben Clayton713b8d32019-12-17 20:37:56 +0000243#endif // ENABLE_RR_DEBUG_INFO
Ben Claytonac07ed82019-03-26 14:17:41 +0000244
Nicolas Capens157ba262019-12-10 17:49:14 -0500245 RValue(const T &lvalue);
246 RValue(typename BoolLiteral<T>::type i);
247 RValue(typename IntLiteral<T>::type i);
248 RValue(typename FloatLiteral<T>::type f);
249 RValue(const Reference<T> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400250
Ben Clayton713b8d32019-12-17 20:37:56 +0000251 RValue<T> &operator=(const RValue<T> &) = delete;
Nicolas Capensd022e412016-09-26 13:30:14 -0400252
Ben Clayton713b8d32019-12-17 20:37:56 +0000253 Value *value; // FIXME: Make private
Nicolas Capens157ba262019-12-10 17:49:14 -0500254};
Nicolas Capensd022e412016-09-26 13:30:14 -0400255
Nicolas Capens157ba262019-12-10 17:49:14 -0500256template<typename T>
257struct Argument
258{
Ben Clayton713b8d32019-12-17 20:37:56 +0000259 explicit Argument(Value *value)
260 : value(value)
261 {}
Nicolas Capensd022e412016-09-26 13:30:14 -0400262
Nicolas Capens157ba262019-12-10 17:49:14 -0500263 Value *value;
264};
Nicolas Capensd022e412016-09-26 13:30:14 -0400265
Nicolas Capens157ba262019-12-10 17:49:14 -0500266class Bool : public LValue<Bool>
267{
268public:
269 Bool(Argument<Bool> argument);
Nicolas Capensd022e412016-09-26 13:30:14 -0400270
Nicolas Capens157ba262019-12-10 17:49:14 -0500271 Bool() = default;
272 Bool(bool x);
273 Bool(RValue<Bool> rhs);
274 Bool(const Bool &rhs);
275 Bool(const Reference<Bool> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400276
Ben Clayton713b8d32019-12-17 20:37:56 +0000277 // RValue<Bool> operator=(bool rhs); // FIXME: Implement
Nicolas Capens157ba262019-12-10 17:49:14 -0500278 RValue<Bool> operator=(RValue<Bool> rhs);
279 RValue<Bool> operator=(const Bool &rhs);
280 RValue<Bool> operator=(const Reference<Bool> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400281
Nicolas Capens157ba262019-12-10 17:49:14 -0500282 static Type *getType();
283};
Nicolas Capensd022e412016-09-26 13:30:14 -0400284
Nicolas Capens157ba262019-12-10 17:49:14 -0500285RValue<Bool> operator!(RValue<Bool> val);
286RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs);
287RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs);
288RValue<Bool> operator!=(RValue<Bool> lhs, RValue<Bool> rhs);
289RValue<Bool> operator==(RValue<Bool> lhs, RValue<Bool> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400290
Nicolas Capens157ba262019-12-10 17:49:14 -0500291class Byte : public LValue<Byte>
292{
293public:
294 Byte(Argument<Byte> argument);
Nicolas Capensd022e412016-09-26 13:30:14 -0400295
Nicolas Capens157ba262019-12-10 17:49:14 -0500296 explicit Byte(RValue<Int> cast);
297 explicit Byte(RValue<UInt> cast);
298 explicit Byte(RValue<UShort> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -0400299
Nicolas Capens157ba262019-12-10 17:49:14 -0500300 Byte() = default;
301 Byte(int x);
302 Byte(unsigned char x);
303 Byte(RValue<Byte> rhs);
304 Byte(const Byte &rhs);
305 Byte(const Reference<Byte> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400306
Ben Clayton713b8d32019-12-17 20:37:56 +0000307 // RValue<Byte> operator=(unsigned char rhs); // FIXME: Implement
Nicolas Capens157ba262019-12-10 17:49:14 -0500308 RValue<Byte> operator=(RValue<Byte> rhs);
309 RValue<Byte> operator=(const Byte &rhs);
310 RValue<Byte> operator=(const Reference<Byte> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400311
Nicolas Capens157ba262019-12-10 17:49:14 -0500312 static Type *getType();
313};
Nicolas Capensd022e412016-09-26 13:30:14 -0400314
Nicolas Capens157ba262019-12-10 17:49:14 -0500315RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs);
316RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs);
317RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs);
318RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs);
319RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs);
320RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs);
321RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs);
322RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs);
323RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs);
324RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs);
325RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs);
326RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs);
327RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs);
328RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs);
329RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs);
330RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs);
331RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs);
332RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs);
333RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs);
334RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs);
335RValue<Byte> operator+(RValue<Byte> val);
336RValue<Byte> operator-(RValue<Byte> val);
337RValue<Byte> operator~(RValue<Byte> val);
Ben Clayton713b8d32019-12-17 20:37:56 +0000338RValue<Byte> operator++(Byte &val, int); // Post-increment
339const Byte &operator++(Byte &val); // Pre-increment
340RValue<Byte> operator--(Byte &val, int); // Post-decrement
341const Byte &operator--(Byte &val); // Pre-decrement
Nicolas Capens157ba262019-12-10 17:49:14 -0500342RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs);
343RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs);
344RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs);
345RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs);
346RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs);
347RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400348
Nicolas Capens157ba262019-12-10 17:49:14 -0500349class SByte : public LValue<SByte>
350{
351public:
352 SByte(Argument<SByte> argument);
Nicolas Capensd022e412016-09-26 13:30:14 -0400353
Nicolas Capens157ba262019-12-10 17:49:14 -0500354 explicit SByte(RValue<Int> cast);
355 explicit SByte(RValue<Short> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -0400356
Nicolas Capens157ba262019-12-10 17:49:14 -0500357 SByte() = default;
358 SByte(signed char x);
359 SByte(RValue<SByte> rhs);
360 SByte(const SByte &rhs);
361 SByte(const Reference<SByte> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400362
Ben Clayton713b8d32019-12-17 20:37:56 +0000363 // RValue<SByte> operator=(signed char rhs); // FIXME: Implement
Nicolas Capens157ba262019-12-10 17:49:14 -0500364 RValue<SByte> operator=(RValue<SByte> rhs);
365 RValue<SByte> operator=(const SByte &rhs);
366 RValue<SByte> operator=(const Reference<SByte> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400367
Nicolas Capens157ba262019-12-10 17:49:14 -0500368 static Type *getType();
369};
Nicolas Capensd022e412016-09-26 13:30:14 -0400370
Nicolas Capens157ba262019-12-10 17:49:14 -0500371RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs);
372RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs);
373RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs);
374RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs);
375RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs);
376RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs);
377RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs);
378RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs);
379RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs);
380RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs);
381RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs);
382RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs);
383RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs);
384RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs);
385RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs);
386RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs);
387RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs);
388RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs);
389RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs);
390RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs);
391RValue<SByte> operator+(RValue<SByte> val);
392RValue<SByte> operator-(RValue<SByte> val);
393RValue<SByte> operator~(RValue<SByte> val);
Ben Clayton713b8d32019-12-17 20:37:56 +0000394RValue<SByte> operator++(SByte &val, int); // Post-increment
395const SByte &operator++(SByte &val); // Pre-increment
396RValue<SByte> operator--(SByte &val, int); // Post-decrement
397const SByte &operator--(SByte &val); // Pre-decrement
Nicolas Capens157ba262019-12-10 17:49:14 -0500398RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs);
399RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs);
400RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs);
401RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs);
402RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs);
403RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400404
Nicolas Capens157ba262019-12-10 17:49:14 -0500405class Short : public LValue<Short>
406{
407public:
408 Short(Argument<Short> argument);
Nicolas Capensd022e412016-09-26 13:30:14 -0400409
Nicolas Capens157ba262019-12-10 17:49:14 -0500410 explicit Short(RValue<Int> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -0400411
Nicolas Capens157ba262019-12-10 17:49:14 -0500412 Short() = default;
413 Short(short x);
414 Short(RValue<Short> rhs);
415 Short(const Short &rhs);
416 Short(const Reference<Short> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400417
Ben Clayton713b8d32019-12-17 20:37:56 +0000418 // RValue<Short> operator=(short rhs); // FIXME: Implement
Nicolas Capens157ba262019-12-10 17:49:14 -0500419 RValue<Short> operator=(RValue<Short> rhs);
420 RValue<Short> operator=(const Short &rhs);
421 RValue<Short> operator=(const Reference<Short> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400422
Nicolas Capens157ba262019-12-10 17:49:14 -0500423 static Type *getType();
424};
Nicolas Capensd022e412016-09-26 13:30:14 -0400425
Nicolas Capens157ba262019-12-10 17:49:14 -0500426RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs);
427RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs);
428RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs);
429RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs);
430RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs);
431RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs);
432RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs);
433RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs);
434RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs);
435RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs);
436RValue<Short> operator+=(Short &lhs, RValue<Short> rhs);
437RValue<Short> operator-=(Short &lhs, RValue<Short> rhs);
438RValue<Short> operator*=(Short &lhs, RValue<Short> rhs);
439RValue<Short> operator/=(Short &lhs, RValue<Short> rhs);
440RValue<Short> operator%=(Short &lhs, RValue<Short> rhs);
441RValue<Short> operator&=(Short &lhs, RValue<Short> rhs);
442RValue<Short> operator|=(Short &lhs, RValue<Short> rhs);
443RValue<Short> operator^=(Short &lhs, RValue<Short> rhs);
444RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs);
445RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs);
446RValue<Short> operator+(RValue<Short> val);
447RValue<Short> operator-(RValue<Short> val);
448RValue<Short> operator~(RValue<Short> val);
Ben Clayton713b8d32019-12-17 20:37:56 +0000449RValue<Short> operator++(Short &val, int); // Post-increment
450const Short &operator++(Short &val); // Pre-increment
451RValue<Short> operator--(Short &val, int); // Post-decrement
452const Short &operator--(Short &val); // Pre-decrement
Nicolas Capens157ba262019-12-10 17:49:14 -0500453RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs);
454RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs);
455RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs);
456RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs);
457RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs);
458RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400459
Nicolas Capens157ba262019-12-10 17:49:14 -0500460class UShort : public LValue<UShort>
461{
462public:
463 UShort(Argument<UShort> argument);
Nicolas Capensd022e412016-09-26 13:30:14 -0400464
Nicolas Capens157ba262019-12-10 17:49:14 -0500465 explicit UShort(RValue<UInt> cast);
466 explicit UShort(RValue<Int> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -0400467
Nicolas Capens157ba262019-12-10 17:49:14 -0500468 UShort() = default;
469 UShort(unsigned short x);
470 UShort(RValue<UShort> rhs);
471 UShort(const UShort &rhs);
472 UShort(const Reference<UShort> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400473
Ben Clayton713b8d32019-12-17 20:37:56 +0000474 // RValue<UShort> operator=(unsigned short rhs); // FIXME: Implement
Nicolas Capens157ba262019-12-10 17:49:14 -0500475 RValue<UShort> operator=(RValue<UShort> rhs);
476 RValue<UShort> operator=(const UShort &rhs);
477 RValue<UShort> operator=(const Reference<UShort> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400478
Nicolas Capens157ba262019-12-10 17:49:14 -0500479 static Type *getType();
480};
Nicolas Capensd022e412016-09-26 13:30:14 -0400481
Nicolas Capens157ba262019-12-10 17:49:14 -0500482RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs);
483RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs);
484RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs);
485RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs);
486RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs);
487RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs);
488RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs);
489RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs);
490RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs);
491RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs);
492RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs);
493RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs);
494RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs);
495RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs);
496RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs);
497RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs);
498RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs);
499RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs);
500RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs);
501RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs);
502RValue<UShort> operator+(RValue<UShort> val);
503RValue<UShort> operator-(RValue<UShort> val);
504RValue<UShort> operator~(RValue<UShort> val);
Ben Clayton713b8d32019-12-17 20:37:56 +0000505RValue<UShort> operator++(UShort &val, int); // Post-increment
506const UShort &operator++(UShort &val); // Pre-increment
507RValue<UShort> operator--(UShort &val, int); // Post-decrement
508const UShort &operator--(UShort &val); // Pre-decrement
Nicolas Capens157ba262019-12-10 17:49:14 -0500509RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs);
510RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs);
511RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs);
512RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs);
513RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs);
514RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400515
Nicolas Capens157ba262019-12-10 17:49:14 -0500516class Byte4 : public LValue<Byte4>
517{
518public:
519 explicit Byte4(RValue<Byte8> cast);
Nicolas Capens133b87d2020-01-25 16:26:28 -0500520 explicit Byte4(RValue<UShort4> cast);
521 explicit Byte4(RValue<Short4> cast);
522 explicit Byte4(RValue<UInt4> cast);
523 explicit Byte4(RValue<Int4> cast);
Nicolas Capens16b5f152016-10-13 13:39:01 -0400524
Nicolas Capens157ba262019-12-10 17:49:14 -0500525 Byte4() = default;
Ben Clayton713b8d32019-12-17 20:37:56 +0000526 // Byte4(int x, int y, int z, int w);
Nicolas Capens133b87d2020-01-25 16:26:28 -0500527 Byte4(RValue<Byte4> rhs);
528 Byte4(const Byte4 &rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500529 Byte4(const Reference<Byte4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400530
Nicolas Capens133b87d2020-01-25 16:26:28 -0500531 RValue<Byte4> operator=(RValue<Byte4> rhs);
532 RValue<Byte4> operator=(const Byte4 &rhs);
Ben Clayton713b8d32019-12-17 20:37:56 +0000533 // RValue<Byte4> operator=(const Reference<Byte4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400534
Nicolas Capens157ba262019-12-10 17:49:14 -0500535 static Type *getType();
536};
Nicolas Capensd022e412016-09-26 13:30:14 -0400537
538// RValue<Byte4> operator+(RValue<Byte4> lhs, RValue<Byte4> rhs);
539// RValue<Byte4> operator-(RValue<Byte4> lhs, RValue<Byte4> rhs);
540// RValue<Byte4> operator*(RValue<Byte4> lhs, RValue<Byte4> rhs);
541// RValue<Byte4> operator/(RValue<Byte4> lhs, RValue<Byte4> rhs);
542// RValue<Byte4> operator%(RValue<Byte4> lhs, RValue<Byte4> rhs);
543// RValue<Byte4> operator&(RValue<Byte4> lhs, RValue<Byte4> rhs);
544// RValue<Byte4> operator|(RValue<Byte4> lhs, RValue<Byte4> rhs);
545// RValue<Byte4> operator^(RValue<Byte4> lhs, RValue<Byte4> rhs);
546// RValue<Byte4> operator<<(RValue<Byte4> lhs, RValue<Byte4> rhs);
547// RValue<Byte4> operator>>(RValue<Byte4> lhs, RValue<Byte4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500548// RValue<Byte4> operator+=(Byte4 &lhs, RValue<Byte4> rhs);
549// RValue<Byte4> operator-=(Byte4 &lhs, RValue<Byte4> rhs);
550// RValue<Byte4> operator*=(Byte4 &lhs, RValue<Byte4> rhs);
551// RValue<Byte4> operator/=(Byte4 &lhs, RValue<Byte4> rhs);
552// RValue<Byte4> operator%=(Byte4 &lhs, RValue<Byte4> rhs);
553// RValue<Byte4> operator&=(Byte4 &lhs, RValue<Byte4> rhs);
554// RValue<Byte4> operator|=(Byte4 &lhs, RValue<Byte4> rhs);
555// RValue<Byte4> operator^=(Byte4 &lhs, RValue<Byte4> rhs);
556// RValue<Byte4> operator<<=(Byte4 &lhs, RValue<Byte4> rhs);
557// RValue<Byte4> operator>>=(Byte4 &lhs, RValue<Byte4> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400558// RValue<Byte4> operator+(RValue<Byte4> val);
559// RValue<Byte4> operator-(RValue<Byte4> val);
560// RValue<Byte4> operator~(RValue<Byte4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500561// RValue<Byte4> operator++(Byte4 &val, int); // Post-increment
562// const Byte4 &operator++(Byte4 &val); // Pre-increment
563// RValue<Byte4> operator--(Byte4 &val, int); // Post-decrement
564// const Byte4 &operator--(Byte4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400565
Nicolas Capens157ba262019-12-10 17:49:14 -0500566class SByte4 : public LValue<SByte4>
567{
568public:
569 SByte4() = default;
Ben Clayton713b8d32019-12-17 20:37:56 +0000570 // SByte4(int x, int y, int z, int w);
571 // SByte4(RValue<SByte4> rhs);
572 // SByte4(const SByte4 &rhs);
573 // SByte4(const Reference<SByte4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400574
Ben Clayton713b8d32019-12-17 20:37:56 +0000575 // RValue<SByte4> operator=(RValue<SByte4> rhs);
576 // RValue<SByte4> operator=(const SByte4 &rhs);
577 // RValue<SByte4> operator=(const Reference<SByte4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400578
Nicolas Capens157ba262019-12-10 17:49:14 -0500579 static Type *getType();
580};
Nicolas Capensd022e412016-09-26 13:30:14 -0400581
582// RValue<SByte4> operator+(RValue<SByte4> lhs, RValue<SByte4> rhs);
583// RValue<SByte4> operator-(RValue<SByte4> lhs, RValue<SByte4> rhs);
584// RValue<SByte4> operator*(RValue<SByte4> lhs, RValue<SByte4> rhs);
585// RValue<SByte4> operator/(RValue<SByte4> lhs, RValue<SByte4> rhs);
586// RValue<SByte4> operator%(RValue<SByte4> lhs, RValue<SByte4> rhs);
587// RValue<SByte4> operator&(RValue<SByte4> lhs, RValue<SByte4> rhs);
588// RValue<SByte4> operator|(RValue<SByte4> lhs, RValue<SByte4> rhs);
589// RValue<SByte4> operator^(RValue<SByte4> lhs, RValue<SByte4> rhs);
590// RValue<SByte4> operator<<(RValue<SByte4> lhs, RValue<SByte4> rhs);
591// RValue<SByte4> operator>>(RValue<SByte4> lhs, RValue<SByte4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500592// RValue<SByte4> operator+=(SByte4 &lhs, RValue<SByte4> rhs);
593// RValue<SByte4> operator-=(SByte4 &lhs, RValue<SByte4> rhs);
594// RValue<SByte4> operator*=(SByte4 &lhs, RValue<SByte4> rhs);
595// RValue<SByte4> operator/=(SByte4 &lhs, RValue<SByte4> rhs);
596// RValue<SByte4> operator%=(SByte4 &lhs, RValue<SByte4> rhs);
597// RValue<SByte4> operator&=(SByte4 &lhs, RValue<SByte4> rhs);
598// RValue<SByte4> operator|=(SByte4 &lhs, RValue<SByte4> rhs);
599// RValue<SByte4> operator^=(SByte4 &lhs, RValue<SByte4> rhs);
600// RValue<SByte4> operator<<=(SByte4 &lhs, RValue<SByte4> rhs);
601// RValue<SByte4> operator>>=(SByte4 &lhs, RValue<SByte4> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400602// RValue<SByte4> operator+(RValue<SByte4> val);
603// RValue<SByte4> operator-(RValue<SByte4> val);
604// RValue<SByte4> operator~(RValue<SByte4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500605// RValue<SByte4> operator++(SByte4 &val, int); // Post-increment
606// const SByte4 &operator++(SByte4 &val); // Pre-increment
607// RValue<SByte4> operator--(SByte4 &val, int); // Post-decrement
608// const SByte4 &operator--(SByte4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400609
Nicolas Capens157ba262019-12-10 17:49:14 -0500610class Byte8 : public LValue<Byte8>
611{
612public:
613 Byte8() = default;
614 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);
615 Byte8(RValue<Byte8> rhs);
616 Byte8(const Byte8 &rhs);
617 Byte8(const Reference<Byte8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400618
Nicolas Capens157ba262019-12-10 17:49:14 -0500619 RValue<Byte8> operator=(RValue<Byte8> rhs);
620 RValue<Byte8> operator=(const Byte8 &rhs);
621 RValue<Byte8> operator=(const Reference<Byte8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400622
Nicolas Capens157ba262019-12-10 17:49:14 -0500623 static Type *getType();
624};
Nicolas Capensd022e412016-09-26 13:30:14 -0400625
Nicolas Capens157ba262019-12-10 17:49:14 -0500626RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs);
627RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400628// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs);
629// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs);
630// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500631RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs);
632RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs);
633RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400634// RValue<Byte8> operator<<(RValue<Byte8> lhs, RValue<Byte8> rhs);
635// RValue<Byte8> operator>>(RValue<Byte8> lhs, RValue<Byte8> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500636RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs);
637RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500638// RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs);
639// RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs);
640// RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500641RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs);
642RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs);
643RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500644// RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs);
645// RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400646// RValue<Byte8> operator+(RValue<Byte8> val);
647// RValue<Byte8> operator-(RValue<Byte8> val);
Nicolas Capens157ba262019-12-10 17:49:14 -0500648RValue<Byte8> operator~(RValue<Byte8> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500649// RValue<Byte8> operator++(Byte8 &val, int); // Post-increment
650// const Byte8 &operator++(Byte8 &val); // Pre-increment
651// RValue<Byte8> operator--(Byte8 &val, int); // Post-decrement
652// const Byte8 &operator--(Byte8 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400653
Nicolas Capens157ba262019-12-10 17:49:14 -0500654RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y);
655RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y);
656RValue<Short4> Unpack(RValue<Byte4> x);
657RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y);
658RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y);
659RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y);
660RValue<Int> SignMask(RValue<Byte8> x);
Nicolas Capensd022e412016-09-26 13:30:14 -0400661// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y);
Nicolas Capens157ba262019-12-10 17:49:14 -0500662RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y);
Nicolas Capens133b87d2020-01-25 16:26:28 -0500663RValue<Byte8> Swizzle(RValue<Byte8> x, uint32_t select);
Nicolas Capensd022e412016-09-26 13:30:14 -0400664
Nicolas Capens157ba262019-12-10 17:49:14 -0500665class SByte8 : public LValue<SByte8>
666{
667public:
668 SByte8() = default;
669 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);
670 SByte8(RValue<SByte8> rhs);
671 SByte8(const SByte8 &rhs);
672 SByte8(const Reference<SByte8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400673
Nicolas Capens157ba262019-12-10 17:49:14 -0500674 RValue<SByte8> operator=(RValue<SByte8> rhs);
675 RValue<SByte8> operator=(const SByte8 &rhs);
676 RValue<SByte8> operator=(const Reference<SByte8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400677
Nicolas Capens157ba262019-12-10 17:49:14 -0500678 static Type *getType();
679};
Nicolas Capensd022e412016-09-26 13:30:14 -0400680
Nicolas Capens157ba262019-12-10 17:49:14 -0500681RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs);
682RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400683// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs);
684// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs);
685// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500686RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs);
687RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs);
688RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400689// RValue<SByte8> operator<<(RValue<SByte8> lhs, RValue<SByte8> rhs);
690// RValue<SByte8> operator>>(RValue<SByte8> lhs, RValue<SByte8> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500691RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs);
692RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500693// RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs);
694// RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs);
695// RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500696RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs);
697RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs);
698RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500699// RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs);
700// RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400701// RValue<SByte8> operator+(RValue<SByte8> val);
702// RValue<SByte8> operator-(RValue<SByte8> val);
Nicolas Capens157ba262019-12-10 17:49:14 -0500703RValue<SByte8> operator~(RValue<SByte8> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500704// RValue<SByte8> operator++(SByte8 &val, int); // Post-increment
705// const SByte8 &operator++(SByte8 &val); // Pre-increment
706// RValue<SByte8> operator--(SByte8 &val, int); // Post-decrement
707// const SByte8 &operator--(SByte8 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400708
Nicolas Capens157ba262019-12-10 17:49:14 -0500709RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y);
710RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y);
711RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y);
712RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y);
713RValue<Int> SignMask(RValue<SByte8> x);
714RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y);
715RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y);
Nicolas Capensd022e412016-09-26 13:30:14 -0400716
Nicolas Capens157ba262019-12-10 17:49:14 -0500717class Byte16 : public LValue<Byte16>
718{
719public:
720 Byte16() = default;
Nicolas Capens157ba262019-12-10 17:49:14 -0500721 Byte16(RValue<Byte16> rhs);
722 Byte16(const Byte16 &rhs);
723 Byte16(const Reference<Byte16> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400724
Nicolas Capens157ba262019-12-10 17:49:14 -0500725 RValue<Byte16> operator=(RValue<Byte16> rhs);
726 RValue<Byte16> operator=(const Byte16 &rhs);
727 RValue<Byte16> operator=(const Reference<Byte16> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400728
Nicolas Capens157ba262019-12-10 17:49:14 -0500729 static Type *getType();
730};
Nicolas Capensd022e412016-09-26 13:30:14 -0400731
732// RValue<Byte16> operator+(RValue<Byte16> lhs, RValue<Byte16> rhs);
733// RValue<Byte16> operator-(RValue<Byte16> lhs, RValue<Byte16> rhs);
734// RValue<Byte16> operator*(RValue<Byte16> lhs, RValue<Byte16> rhs);
735// RValue<Byte16> operator/(RValue<Byte16> lhs, RValue<Byte16> rhs);
736// RValue<Byte16> operator%(RValue<Byte16> lhs, RValue<Byte16> rhs);
737// RValue<Byte16> operator&(RValue<Byte16> lhs, RValue<Byte16> rhs);
738// RValue<Byte16> operator|(RValue<Byte16> lhs, RValue<Byte16> rhs);
739// RValue<Byte16> operator^(RValue<Byte16> lhs, RValue<Byte16> rhs);
740// RValue<Byte16> operator<<(RValue<Byte16> lhs, RValue<Byte16> rhs);
741// RValue<Byte16> operator>>(RValue<Byte16> lhs, RValue<Byte16> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500742// RValue<Byte16> operator+=(Byte16 &lhs, RValue<Byte16> rhs);
743// RValue<Byte16> operator-=(Byte16 &lhs, RValue<Byte16> rhs);
744// RValue<Byte16> operator*=(Byte16 &lhs, RValue<Byte16> rhs);
745// RValue<Byte16> operator/=(Byte16 &lhs, RValue<Byte16> rhs);
746// RValue<Byte16> operator%=(Byte16 &lhs, RValue<Byte16> rhs);
747// RValue<Byte16> operator&=(Byte16 &lhs, RValue<Byte16> rhs);
748// RValue<Byte16> operator|=(Byte16 &lhs, RValue<Byte16> rhs);
749// RValue<Byte16> operator^=(Byte16 &lhs, RValue<Byte16> rhs);
750// RValue<Byte16> operator<<=(Byte16 &lhs, RValue<Byte16> rhs);
751// RValue<Byte16> operator>>=(Byte16 &lhs, RValue<Byte16> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400752// RValue<Byte16> operator+(RValue<Byte16> val);
753// RValue<Byte16> operator-(RValue<Byte16> val);
754// RValue<Byte16> operator~(RValue<Byte16> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500755// RValue<Byte16> operator++(Byte16 &val, int); // Post-increment
756// const Byte16 &operator++(Byte16 &val); // Pre-increment
757// RValue<Byte16> operator--(Byte16 &val, int); // Post-decrement
758// const Byte16 &operator--(Byte16 &val); // Pre-decrement
Nicolas Capens133b87d2020-01-25 16:26:28 -0500759RValue<Byte16> Swizzle(RValue<Byte16> x, uint64_t select);
Nicolas Capensd022e412016-09-26 13:30:14 -0400760
Nicolas Capens157ba262019-12-10 17:49:14 -0500761class SByte16 : public LValue<SByte16>
762{
763public:
764 SByte16() = default;
Ben Clayton713b8d32019-12-17 20:37:56 +0000765 // SByte16(int x, int y, int z, int w);
766 // SByte16(RValue<SByte16> rhs);
767 // SByte16(const SByte16 &rhs);
768 // SByte16(const Reference<SByte16> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400769
Ben Clayton713b8d32019-12-17 20:37:56 +0000770 // RValue<SByte16> operator=(RValue<SByte16> rhs);
771 // RValue<SByte16> operator=(const SByte16 &rhs);
772 // RValue<SByte16> operator=(const Reference<SByte16> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400773
Nicolas Capens157ba262019-12-10 17:49:14 -0500774 static Type *getType();
775};
Nicolas Capensd022e412016-09-26 13:30:14 -0400776
777// RValue<SByte16> operator+(RValue<SByte16> lhs, RValue<SByte16> rhs);
778// RValue<SByte16> operator-(RValue<SByte16> lhs, RValue<SByte16> rhs);
779// RValue<SByte16> operator*(RValue<SByte16> lhs, RValue<SByte16> rhs);
780// RValue<SByte16> operator/(RValue<SByte16> lhs, RValue<SByte16> rhs);
781// RValue<SByte16> operator%(RValue<SByte16> lhs, RValue<SByte16> rhs);
782// RValue<SByte16> operator&(RValue<SByte16> lhs, RValue<SByte16> rhs);
783// RValue<SByte16> operator|(RValue<SByte16> lhs, RValue<SByte16> rhs);
784// RValue<SByte16> operator^(RValue<SByte16> lhs, RValue<SByte16> rhs);
785// RValue<SByte16> operator<<(RValue<SByte16> lhs, RValue<SByte16> rhs);
786// RValue<SByte16> operator>>(RValue<SByte16> lhs, RValue<SByte16> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500787// RValue<SByte16> operator+=(SByte16 &lhs, RValue<SByte16> rhs);
788// RValue<SByte16> operator-=(SByte16 &lhs, RValue<SByte16> rhs);
789// RValue<SByte16> operator*=(SByte16 &lhs, RValue<SByte16> rhs);
790// RValue<SByte16> operator/=(SByte16 &lhs, RValue<SByte16> rhs);
791// RValue<SByte16> operator%=(SByte16 &lhs, RValue<SByte16> rhs);
792// RValue<SByte16> operator&=(SByte16 &lhs, RValue<SByte16> rhs);
793// RValue<SByte16> operator|=(SByte16 &lhs, RValue<SByte16> rhs);
794// RValue<SByte16> operator^=(SByte16 &lhs, RValue<SByte16> rhs);
795// RValue<SByte16> operator<<=(SByte16 &lhs, RValue<SByte16> rhs);
796// RValue<SByte16> operator>>=(SByte16 &lhs, RValue<SByte16> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400797// RValue<SByte16> operator+(RValue<SByte16> val);
798// RValue<SByte16> operator-(RValue<SByte16> val);
799// RValue<SByte16> operator~(RValue<SByte16> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500800// RValue<SByte16> operator++(SByte16 &val, int); // Post-increment
801// const SByte16 &operator++(SByte16 &val); // Pre-increment
802// RValue<SByte16> operator--(SByte16 &val, int); // Post-decrement
803// const SByte16 &operator--(SByte16 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400804
Nicolas Capens157ba262019-12-10 17:49:14 -0500805class Short2 : public LValue<Short2>
806{
807public:
808 explicit Short2(RValue<Short4> cast);
Nicolas Capens16b5f152016-10-13 13:39:01 -0400809
Nicolas Capens157ba262019-12-10 17:49:14 -0500810 static Type *getType();
811};
Nicolas Capens16b5f152016-10-13 13:39:01 -0400812
Nicolas Capens157ba262019-12-10 17:49:14 -0500813class UShort2 : public LValue<UShort2>
814{
815public:
816 explicit UShort2(RValue<UShort4> cast);
Nicolas Capens16b5f152016-10-13 13:39:01 -0400817
Nicolas Capens157ba262019-12-10 17:49:14 -0500818 static Type *getType();
819};
Nicolas Capens16b5f152016-10-13 13:39:01 -0400820
Nicolas Capens157ba262019-12-10 17:49:14 -0500821class Short4 : public LValue<Short4>
822{
823public:
824 explicit Short4(RValue<Int> cast);
825 explicit Short4(RValue<Int4> cast);
Ben Clayton713b8d32019-12-17 20:37:56 +0000826 // explicit Short4(RValue<Float> cast);
Nicolas Capens157ba262019-12-10 17:49:14 -0500827 explicit Short4(RValue<Float4> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -0400828
Nicolas Capens157ba262019-12-10 17:49:14 -0500829 Short4() = default;
830 Short4(short xyzw);
831 Short4(short x, short y, short z, short w);
832 Short4(RValue<Short4> rhs);
833 Short4(const Short4 &rhs);
834 Short4(const Reference<Short4> &rhs);
835 Short4(RValue<UShort4> rhs);
836 Short4(const UShort4 &rhs);
837 Short4(const Reference<UShort4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400838
Nicolas Capens157ba262019-12-10 17:49:14 -0500839 RValue<Short4> operator=(RValue<Short4> rhs);
840 RValue<Short4> operator=(const Short4 &rhs);
841 RValue<Short4> operator=(const Reference<Short4> &rhs);
842 RValue<Short4> operator=(RValue<UShort4> rhs);
843 RValue<Short4> operator=(const UShort4 &rhs);
844 RValue<Short4> operator=(const Reference<UShort4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400845
Nicolas Capens157ba262019-12-10 17:49:14 -0500846 static Type *getType();
847};
Nicolas Capensd022e412016-09-26 13:30:14 -0400848
Nicolas Capens157ba262019-12-10 17:49:14 -0500849RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs);
850RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs);
851RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400852// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs);
853// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500854RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs);
855RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs);
856RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs);
857RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs);
858RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs);
859RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs);
860RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs);
861RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500862// RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs);
863// RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500864RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs);
865RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs);
866RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs);
867RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs);
868RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400869// RValue<Short4> operator+(RValue<Short4> val);
Nicolas Capens157ba262019-12-10 17:49:14 -0500870RValue<Short4> operator-(RValue<Short4> val);
871RValue<Short4> operator~(RValue<Short4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500872// RValue<Short4> operator++(Short4 &val, int); // Post-increment
873// const Short4 &operator++(Short4 &val); // Pre-increment
874// RValue<Short4> operator--(Short4 &val, int); // Post-decrement
875// const Short4 &operator--(Short4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400876// RValue<Bool> operator<(RValue<Short4> lhs, RValue<Short4> rhs);
877// RValue<Bool> operator<=(RValue<Short4> lhs, RValue<Short4> rhs);
878// RValue<Bool> operator>(RValue<Short4> lhs, RValue<Short4> rhs);
879// RValue<Bool> operator>=(RValue<Short4> lhs, RValue<Short4> rhs);
880// RValue<Bool> operator!=(RValue<Short4> lhs, RValue<Short4> rhs);
881// RValue<Bool> operator==(RValue<Short4> lhs, RValue<Short4> rhs);
882
Nicolas Capens157ba262019-12-10 17:49:14 -0500883RValue<Short4> RoundShort4(RValue<Float4> cast);
884RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y);
885RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y);
886RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y);
887RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y);
888RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y);
889RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y);
890RValue<SByte8> PackSigned(RValue<Short4> x, RValue<Short4> y);
891RValue<Byte8> PackUnsigned(RValue<Short4> x, RValue<Short4> y);
892RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y);
893RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y);
894RValue<Short4> Swizzle(RValue<Short4> x, uint16_t select);
895RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i);
896RValue<Short> Extract(RValue<Short4> val, int i);
897RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y);
898RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y);
Nicolas Capensd022e412016-09-26 13:30:14 -0400899
Nicolas Capens157ba262019-12-10 17:49:14 -0500900class UShort4 : public LValue<UShort4>
901{
902public:
903 explicit UShort4(RValue<Int4> cast);
904 explicit UShort4(RValue<Float4> cast, bool saturate = false);
Nicolas Capensd022e412016-09-26 13:30:14 -0400905
Nicolas Capens157ba262019-12-10 17:49:14 -0500906 UShort4() = default;
907 UShort4(unsigned short xyzw);
908 UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w);
909 UShort4(RValue<UShort4> rhs);
910 UShort4(const UShort4 &rhs);
911 UShort4(const Reference<UShort4> &rhs);
912 UShort4(RValue<Short4> rhs);
913 UShort4(const Short4 &rhs);
914 UShort4(const Reference<Short4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400915
Nicolas Capens157ba262019-12-10 17:49:14 -0500916 RValue<UShort4> operator=(RValue<UShort4> rhs);
917 RValue<UShort4> operator=(const UShort4 &rhs);
918 RValue<UShort4> operator=(const Reference<UShort4> &rhs);
919 RValue<UShort4> operator=(RValue<Short4> rhs);
920 RValue<UShort4> operator=(const Short4 &rhs);
921 RValue<UShort4> operator=(const Reference<Short4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400922
Nicolas Capens157ba262019-12-10 17:49:14 -0500923 static Type *getType();
924};
Nicolas Capensd022e412016-09-26 13:30:14 -0400925
Nicolas Capens157ba262019-12-10 17:49:14 -0500926RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs);
927RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs);
928RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400929// RValue<UShort4> operator/(RValue<UShort4> lhs, RValue<UShort4> rhs);
930// RValue<UShort4> operator%(RValue<UShort4> lhs, RValue<UShort4> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500931RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs);
932RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs);
933RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs);
934RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs);
935RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500936// RValue<UShort4> operator+=(UShort4 &lhs, RValue<UShort4> rhs);
937// RValue<UShort4> operator-=(UShort4 &lhs, RValue<UShort4> rhs);
938// RValue<UShort4> operator*=(UShort4 &lhs, RValue<UShort4> rhs);
939// RValue<UShort4> operator/=(UShort4 &lhs, RValue<UShort4> rhs);
940// RValue<UShort4> operator%=(UShort4 &lhs, RValue<UShort4> rhs);
941// RValue<UShort4> operator&=(UShort4 &lhs, RValue<UShort4> rhs);
942// RValue<UShort4> operator|=(UShort4 &lhs, RValue<UShort4> rhs);
943// RValue<UShort4> operator^=(UShort4 &lhs, RValue<UShort4> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500944RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs);
945RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400946// RValue<UShort4> operator+(RValue<UShort4> val);
947// RValue<UShort4> operator-(RValue<UShort4> val);
Nicolas Capens157ba262019-12-10 17:49:14 -0500948RValue<UShort4> operator~(RValue<UShort4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500949// RValue<UShort4> operator++(UShort4 &val, int); // Post-increment
950// const UShort4 &operator++(UShort4 &val); // Pre-increment
951// RValue<UShort4> operator--(UShort4 &val, int); // Post-decrement
952// const UShort4 &operator--(UShort4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400953
Nicolas Capens157ba262019-12-10 17:49:14 -0500954RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y);
955RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y);
956RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y);
957RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y);
958RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y);
959RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y);
Nicolas Capensd022e412016-09-26 13:30:14 -0400960
Nicolas Capens157ba262019-12-10 17:49:14 -0500961class Short8 : public LValue<Short8>
962{
963public:
964 Short8() = default;
965 Short8(short c);
966 Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7);
967 Short8(RValue<Short8> rhs);
Ben Clayton713b8d32019-12-17 20:37:56 +0000968 // Short8(const Short8 &rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500969 Short8(const Reference<Short8> &rhs);
970 Short8(RValue<Short4> lo, RValue<Short4> hi);
Nicolas Capensd022e412016-09-26 13:30:14 -0400971
Nicolas Capens157ba262019-12-10 17:49:14 -0500972 RValue<Short8> operator=(RValue<Short8> rhs);
973 RValue<Short8> operator=(const Short8 &rhs);
974 RValue<Short8> operator=(const Reference<Short8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400975
Nicolas Capens157ba262019-12-10 17:49:14 -0500976 static Type *getType();
977};
Nicolas Capensd022e412016-09-26 13:30:14 -0400978
Nicolas Capens157ba262019-12-10 17:49:14 -0500979RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400980// RValue<Short8> operator-(RValue<Short8> lhs, RValue<Short8> rhs);
981// RValue<Short8> operator*(RValue<Short8> lhs, RValue<Short8> rhs);
982// RValue<Short8> operator/(RValue<Short8> lhs, RValue<Short8> rhs);
983// RValue<Short8> operator%(RValue<Short8> lhs, RValue<Short8> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500984RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400985// RValue<Short8> operator|(RValue<Short8> lhs, RValue<Short8> rhs);
986// RValue<Short8> operator^(RValue<Short8> lhs, RValue<Short8> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -0500987RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs);
988RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400989// RValue<Short8> operator<<(RValue<Short8> lhs, RValue<Short8> rhs);
990// RValue<Short8> operator>>(RValue<Short8> lhs, RValue<Short8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500991// RValue<Short8> operator+=(Short8 &lhs, RValue<Short8> rhs);
992// RValue<Short8> operator-=(Short8 &lhs, RValue<Short8> rhs);
993// RValue<Short8> operator*=(Short8 &lhs, RValue<Short8> rhs);
994// RValue<Short8> operator/=(Short8 &lhs, RValue<Short8> rhs);
995// RValue<Short8> operator%=(Short8 &lhs, RValue<Short8> rhs);
996// RValue<Short8> operator&=(Short8 &lhs, RValue<Short8> rhs);
997// RValue<Short8> operator|=(Short8 &lhs, RValue<Short8> rhs);
998// RValue<Short8> operator^=(Short8 &lhs, RValue<Short8> rhs);
999// RValue<Short8> operator<<=(Short8 &lhs, RValue<Short8> rhs);
1000// RValue<Short8> operator>>=(Short8 &lhs, RValue<Short8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001001// RValue<Short8> operator+(RValue<Short8> val);
1002// RValue<Short8> operator-(RValue<Short8> val);
1003// RValue<Short8> operator~(RValue<Short8> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001004// RValue<Short8> operator++(Short8 &val, int); // Post-increment
1005// const Short8 &operator++(Short8 &val); // Pre-increment
1006// RValue<Short8> operator--(Short8 &val, int); // Post-decrement
1007// const Short8 &operator--(Short8 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001008// RValue<Bool> operator<(RValue<Short8> lhs, RValue<Short8> rhs);
1009// RValue<Bool> operator<=(RValue<Short8> lhs, RValue<Short8> rhs);
1010// RValue<Bool> operator>(RValue<Short8> lhs, RValue<Short8> rhs);
1011// RValue<Bool> operator>=(RValue<Short8> lhs, RValue<Short8> rhs);
1012// RValue<Bool> operator!=(RValue<Short8> lhs, RValue<Short8> rhs);
1013// RValue<Bool> operator==(RValue<Short8> lhs, RValue<Short8> rhs);
1014
Nicolas Capens157ba262019-12-10 17:49:14 -05001015RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y);
1016RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y);
1017RValue<Int4> Abs(RValue<Int4> x);
Nicolas Capensd022e412016-09-26 13:30:14 -04001018
Nicolas Capens157ba262019-12-10 17:49:14 -05001019class UShort8 : public LValue<UShort8>
1020{
1021public:
1022 UShort8() = default;
1023 UShort8(unsigned short c);
1024 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);
1025 UShort8(RValue<UShort8> rhs);
Ben Clayton713b8d32019-12-17 20:37:56 +00001026 // UShort8(const UShort8 &rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -05001027 UShort8(const Reference<UShort8> &rhs);
1028 UShort8(RValue<UShort4> lo, RValue<UShort4> hi);
Nicolas Capensd022e412016-09-26 13:30:14 -04001029
Nicolas Capens157ba262019-12-10 17:49:14 -05001030 RValue<UShort8> operator=(RValue<UShort8> rhs);
1031 RValue<UShort8> operator=(const UShort8 &rhs);
1032 RValue<UShort8> operator=(const Reference<UShort8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001033
Nicolas Capens157ba262019-12-10 17:49:14 -05001034 static Type *getType();
1035};
Nicolas Capensd022e412016-09-26 13:30:14 -04001036
Nicolas Capens157ba262019-12-10 17:49:14 -05001037RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001038// RValue<UShort8> operator-(RValue<UShort8> lhs, RValue<UShort8> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -05001039RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001040// RValue<UShort8> operator/(RValue<UShort8> lhs, RValue<UShort8> rhs);
1041// RValue<UShort8> operator%(RValue<UShort8> lhs, RValue<UShort8> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -05001042RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001043// RValue<UShort8> operator|(RValue<UShort8> lhs, RValue<UShort8> rhs);
1044// RValue<UShort8> operator^(RValue<UShort8> lhs, RValue<UShort8> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -05001045RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs);
1046RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001047// RValue<UShort8> operator<<(RValue<UShort8> lhs, RValue<UShort8> rhs);
1048// RValue<UShort8> operator>>(RValue<UShort8> lhs, RValue<UShort8> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -05001049RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001050// RValue<UShort8> operator-=(UShort8 &lhs, RValue<UShort8> rhs);
1051// RValue<UShort8> operator*=(UShort8 &lhs, RValue<UShort8> rhs);
1052// RValue<UShort8> operator/=(UShort8 &lhs, RValue<UShort8> rhs);
1053// RValue<UShort8> operator%=(UShort8 &lhs, RValue<UShort8> rhs);
1054// RValue<UShort8> operator&=(UShort8 &lhs, RValue<UShort8> rhs);
1055// RValue<UShort8> operator|=(UShort8 &lhs, RValue<UShort8> rhs);
1056// RValue<UShort8> operator^=(UShort8 &lhs, RValue<UShort8> rhs);
1057// RValue<UShort8> operator<<=(UShort8 &lhs, RValue<UShort8> rhs);
1058// RValue<UShort8> operator>>=(UShort8 &lhs, RValue<UShort8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001059// RValue<UShort8> operator+(RValue<UShort8> val);
1060// RValue<UShort8> operator-(RValue<UShort8> val);
Nicolas Capens157ba262019-12-10 17:49:14 -05001061RValue<UShort8> operator~(RValue<UShort8> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001062// RValue<UShort8> operator++(UShort8 &val, int); // Post-increment
1063// const UShort8 &operator++(UShort8 &val); // Pre-increment
1064// RValue<UShort8> operator--(UShort8 &val, int); // Post-decrement
1065// const UShort8 &operator--(UShort8 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001066// RValue<Bool> operator<(RValue<UShort8> lhs, RValue<UShort8> rhs);
1067// RValue<Bool> operator<=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1068// RValue<Bool> operator>(RValue<UShort8> lhs, RValue<UShort8> rhs);
1069// RValue<Bool> operator>=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1070// RValue<Bool> operator!=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1071// RValue<Bool> operator==(RValue<UShort8> lhs, RValue<UShort8> rhs);
1072
Nicolas Capens133b87d2020-01-25 16:26:28 -05001073RValue<UShort8> Swizzle(RValue<UShort8> x, uint32_t select);
Nicolas Capens157ba262019-12-10 17:49:14 -05001074RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y);
Nicolas Capensd022e412016-09-26 13:30:14 -04001075
Nicolas Capens157ba262019-12-10 17:49:14 -05001076class Int : public LValue<Int>
1077{
1078public:
1079 Int(Argument<Int> argument);
Nicolas Capensd022e412016-09-26 13:30:14 -04001080
Nicolas Capens157ba262019-12-10 17:49:14 -05001081 explicit Int(RValue<Byte> cast);
1082 explicit Int(RValue<SByte> cast);
1083 explicit Int(RValue<Short> cast);
1084 explicit Int(RValue<UShort> cast);
1085 explicit Int(RValue<Int2> cast);
1086 explicit Int(RValue<Long> cast);
1087 explicit Int(RValue<Float> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -04001088
Nicolas Capens157ba262019-12-10 17:49:14 -05001089 Int() = default;
1090 Int(int x);
1091 Int(RValue<Int> rhs);
1092 Int(RValue<UInt> rhs);
1093 Int(const Int &rhs);
1094 Int(const UInt &rhs);
1095 Int(const Reference<Int> &rhs);
1096 Int(const Reference<UInt> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001097
Nicolas Capens157ba262019-12-10 17:49:14 -05001098 RValue<Int> operator=(int rhs);
1099 RValue<Int> operator=(RValue<Int> rhs);
1100 RValue<Int> operator=(RValue<UInt> rhs);
1101 RValue<Int> operator=(const Int &rhs);
1102 RValue<Int> operator=(const UInt &rhs);
1103 RValue<Int> operator=(const Reference<Int> &rhs);
1104 RValue<Int> operator=(const Reference<UInt> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001105
Nicolas Capens157ba262019-12-10 17:49:14 -05001106 static Type *getType();
1107};
Nicolas Capensd022e412016-09-26 13:30:14 -04001108
Nicolas Capens157ba262019-12-10 17:49:14 -05001109RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs);
1110RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs);
1111RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs);
1112RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs);
1113RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs);
1114RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs);
1115RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs);
1116RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs);
1117RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs);
1118RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs);
1119RValue<Int> operator+=(Int &lhs, RValue<Int> rhs);
1120RValue<Int> operator-=(Int &lhs, RValue<Int> rhs);
1121RValue<Int> operator*=(Int &lhs, RValue<Int> rhs);
1122RValue<Int> operator/=(Int &lhs, RValue<Int> rhs);
1123RValue<Int> operator%=(Int &lhs, RValue<Int> rhs);
1124RValue<Int> operator&=(Int &lhs, RValue<Int> rhs);
1125RValue<Int> operator|=(Int &lhs, RValue<Int> rhs);
1126RValue<Int> operator^=(Int &lhs, RValue<Int> rhs);
1127RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs);
1128RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs);
1129RValue<Int> operator+(RValue<Int> val);
1130RValue<Int> operator-(RValue<Int> val);
1131RValue<Int> operator~(RValue<Int> val);
Ben Clayton713b8d32019-12-17 20:37:56 +00001132RValue<Int> operator++(Int &val, int); // Post-increment
1133const Int &operator++(Int &val); // Pre-increment
1134RValue<Int> operator--(Int &val, int); // Post-decrement
1135const Int &operator--(Int &val); // Pre-decrement
Nicolas Capens157ba262019-12-10 17:49:14 -05001136RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs);
1137RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs);
1138RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs);
1139RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs);
1140RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs);
1141RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001142
Nicolas Capens157ba262019-12-10 17:49:14 -05001143RValue<Int> Max(RValue<Int> x, RValue<Int> y);
1144RValue<Int> Min(RValue<Int> x, RValue<Int> y);
1145RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max);
1146RValue<Int> RoundInt(RValue<Float> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -04001147
Nicolas Capens157ba262019-12-10 17:49:14 -05001148class Long : public LValue<Long>
1149{
1150public:
Ben Clayton713b8d32019-12-17 20:37:56 +00001151 // Long(Argument<Long> argument);
Nicolas Capensd022e412016-09-26 13:30:14 -04001152
Ben Clayton713b8d32019-12-17 20:37:56 +00001153 // explicit Long(RValue<Short> cast);
1154 // explicit Long(RValue<UShort> cast);
Nicolas Capens157ba262019-12-10 17:49:14 -05001155 explicit Long(RValue<Int> cast);
1156 explicit Long(RValue<UInt> cast);
Ben Clayton713b8d32019-12-17 20:37:56 +00001157 // explicit Long(RValue<Float> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -04001158
Nicolas Capens157ba262019-12-10 17:49:14 -05001159 Long() = default;
Ben Clayton713b8d32019-12-17 20:37:56 +00001160 // Long(qword x);
Nicolas Capens157ba262019-12-10 17:49:14 -05001161 Long(RValue<Long> rhs);
Ben Clayton713b8d32019-12-17 20:37:56 +00001162 // Long(RValue<ULong> rhs);
1163 // Long(const Long &rhs);
1164 // Long(const Reference<Long> &rhs);
1165 // Long(const ULong &rhs);
1166 // Long(const Reference<ULong> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001167
Nicolas Capens157ba262019-12-10 17:49:14 -05001168 RValue<Long> operator=(int64_t rhs);
1169 RValue<Long> operator=(RValue<Long> rhs);
Ben Clayton713b8d32019-12-17 20:37:56 +00001170 // RValue<Long> operator=(RValue<ULong> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -05001171 RValue<Long> operator=(const Long &rhs);
1172 RValue<Long> operator=(const Reference<Long> &rhs);
Ben Clayton713b8d32019-12-17 20:37:56 +00001173 // RValue<Long> operator=(const ULong &rhs);
1174 // RValue<Long> operator=(const Reference<ULong> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001175
Nicolas Capens157ba262019-12-10 17:49:14 -05001176 static Type *getType();
1177};
Nicolas Capensd022e412016-09-26 13:30:14 -04001178
Nicolas Capens157ba262019-12-10 17:49:14 -05001179RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs);
1180RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs);
1181RValue<Long> operator*(RValue<Long> lhs, RValue<Long> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001182// RValue<Long> operator/(RValue<Long> lhs, RValue<Long> rhs);
1183// RValue<Long> operator%(RValue<Long> lhs, RValue<Long> rhs);
1184// RValue<Long> operator&(RValue<Long> lhs, RValue<Long> rhs);
1185// RValue<Long> operator|(RValue<Long> lhs, RValue<Long> rhs);
1186// RValue<Long> operator^(RValue<Long> lhs, RValue<Long> rhs);
1187// RValue<Long> operator<<(RValue<Long> lhs, RValue<Long> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -05001188RValue<Long> operator>>(RValue<Long> lhs, RValue<Long> rhs);
1189RValue<Long> operator+=(Long &lhs, RValue<Long> rhs);
1190RValue<Long> operator-=(Long &lhs, RValue<Long> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001191// RValue<Long> operator*=(Long &lhs, RValue<Long> rhs);
1192// RValue<Long> operator/=(Long &lhs, RValue<Long> rhs);
1193// RValue<Long> operator%=(Long &lhs, RValue<Long> rhs);
1194// RValue<Long> operator&=(Long &lhs, RValue<Long> rhs);
1195// RValue<Long> operator|=(Long &lhs, RValue<Long> rhs);
1196// RValue<Long> operator^=(Long &lhs, RValue<Long> rhs);
1197// RValue<Long> operator<<=(Long &lhs, RValue<Long> rhs);
1198// RValue<Long> operator>>=(Long &lhs, RValue<Long> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001199// RValue<Long> operator+(RValue<Long> val);
1200// RValue<Long> operator-(RValue<Long> val);
1201// RValue<Long> operator~(RValue<Long> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001202// RValue<Long> operator++(Long &val, int); // Post-increment
1203// const Long &operator++(Long &val); // Pre-increment
1204// RValue<Long> operator--(Long &val, int); // Post-decrement
1205// const Long &operator--(Long &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001206// RValue<Bool> operator<(RValue<Long> lhs, RValue<Long> rhs);
1207// RValue<Bool> operator<=(RValue<Long> lhs, RValue<Long> rhs);
1208// RValue<Bool> operator>(RValue<Long> lhs, RValue<Long> rhs);
1209// RValue<Bool> operator>=(RValue<Long> lhs, RValue<Long> rhs);
1210// RValue<Bool> operator!=(RValue<Long> lhs, RValue<Long> rhs);
1211// RValue<Bool> operator==(RValue<Long> lhs, RValue<Long> rhs);
1212
1213// RValue<Long> RoundLong(RValue<Float> cast);
Ben Clayton713b8d32019-12-17 20:37:56 +00001214RValue<Long> AddAtomic(RValue<Pointer<Long>> x, RValue<Long> y);
Nicolas Capensd022e412016-09-26 13:30:14 -04001215
Nicolas Capens157ba262019-12-10 17:49:14 -05001216class UInt : public LValue<UInt>
1217{
1218public:
1219 UInt(Argument<UInt> argument);
Nicolas Capensd022e412016-09-26 13:30:14 -04001220
Nicolas Capens157ba262019-12-10 17:49:14 -05001221 explicit UInt(RValue<UShort> cast);
1222 explicit UInt(RValue<Long> cast);
1223 explicit UInt(RValue<Float> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -04001224
Nicolas Capens157ba262019-12-10 17:49:14 -05001225 UInt() = default;
1226 UInt(int x);
1227 UInt(unsigned int x);
1228 UInt(RValue<UInt> rhs);
1229 UInt(RValue<Int> rhs);
1230 UInt(const UInt &rhs);
1231 UInt(const Int &rhs);
1232 UInt(const Reference<UInt> &rhs);
1233 UInt(const Reference<Int> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001234
Nicolas Capens157ba262019-12-10 17:49:14 -05001235 RValue<UInt> operator=(unsigned int rhs);
1236 RValue<UInt> operator=(RValue<UInt> rhs);
1237 RValue<UInt> operator=(RValue<Int> rhs);
1238 RValue<UInt> operator=(const UInt &rhs);
1239 RValue<UInt> operator=(const Int &rhs);
1240 RValue<UInt> operator=(const Reference<UInt> &rhs);
1241 RValue<UInt> operator=(const Reference<Int> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001242
Nicolas Capens157ba262019-12-10 17:49:14 -05001243 static Type *getType();
1244};
Nicolas Capensd022e412016-09-26 13:30:14 -04001245
Nicolas Capens157ba262019-12-10 17:49:14 -05001246RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs);
1247RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs);
1248RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs);
1249RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs);
1250RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs);
1251RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs);
1252RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs);
1253RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs);
1254RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs);
1255RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs);
1256RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs);
1257RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs);
1258RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs);
1259RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs);
1260RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs);
1261RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs);
1262RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs);
1263RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs);
1264RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs);
1265RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs);
1266RValue<UInt> operator+(RValue<UInt> val);
1267RValue<UInt> operator-(RValue<UInt> val);
1268RValue<UInt> operator~(RValue<UInt> val);
Ben Clayton713b8d32019-12-17 20:37:56 +00001269RValue<UInt> operator++(UInt &val, int); // Post-increment
1270const UInt &operator++(UInt &val); // Pre-increment
1271RValue<UInt> operator--(UInt &val, int); // Post-decrement
1272const UInt &operator--(UInt &val); // Pre-decrement
Nicolas Capens157ba262019-12-10 17:49:14 -05001273RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs);
1274RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs);
1275RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs);
1276RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs);
1277RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs);
1278RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001279
Nicolas Capens157ba262019-12-10 17:49:14 -05001280RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y);
1281RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y);
1282RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max);
Chris Forbes17813932019-04-18 11:45:54 -07001283
Nicolas Capens157ba262019-12-10 17:49:14 -05001284RValue<UInt> AddAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder);
1285RValue<UInt> SubAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder);
1286RValue<UInt> AndAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder);
1287RValue<UInt> OrAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder);
1288RValue<UInt> XorAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder);
1289RValue<Int> MinAtomic(RValue<Pointer<Int>> x, RValue<Int> y, std::memory_order memoryOrder);
1290RValue<Int> MaxAtomic(RValue<Pointer<Int>> x, RValue<Int> y, std::memory_order memoryOrder);
1291RValue<UInt> MinAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder);
1292RValue<UInt> MaxAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder);
1293RValue<UInt> ExchangeAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, std::memory_order memoryOrder);
1294RValue<UInt> CompareExchangeAtomic(RValue<Pointer<UInt>> x, RValue<UInt> y, RValue<UInt> compare, std::memory_order memoryOrderEqual, std::memory_order memoryOrderUnequal);
Chris Forbes17813932019-04-18 11:45:54 -07001295
Nicolas Capensd022e412016-09-26 13:30:14 -04001296// RValue<UInt> RoundUInt(RValue<Float> cast);
1297
Nicolas Capens157ba262019-12-10 17:49:14 -05001298class Int2 : public LValue<Int2>
1299{
1300public:
Ben Clayton713b8d32019-12-17 20:37:56 +00001301 // explicit Int2(RValue<Int> cast);
Nicolas Capens157ba262019-12-10 17:49:14 -05001302 explicit Int2(RValue<Int4> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -04001303
Nicolas Capens157ba262019-12-10 17:49:14 -05001304 Int2() = default;
1305 Int2(int x, int y);
1306 Int2(RValue<Int2> rhs);
1307 Int2(const Int2 &rhs);
1308 Int2(const Reference<Int2> &rhs);
1309 Int2(RValue<Int> lo, RValue<Int> hi);
Nicolas Capensd022e412016-09-26 13:30:14 -04001310
Nicolas Capens157ba262019-12-10 17:49:14 -05001311 RValue<Int2> operator=(RValue<Int2> rhs);
1312 RValue<Int2> operator=(const Int2 &rhs);
1313 RValue<Int2> operator=(const Reference<Int2> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001314
Nicolas Capens157ba262019-12-10 17:49:14 -05001315 static Type *getType();
1316};
Nicolas Capensd022e412016-09-26 13:30:14 -04001317
Nicolas Capens157ba262019-12-10 17:49:14 -05001318RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs);
1319RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001320// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs);
1321// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs);
1322// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -05001323RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs);
1324RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs);
1325RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs);
1326RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs);
1327RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs);
1328RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs);
1329RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001330// RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs);
1331// RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs);
1332// RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -05001333RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs);
1334RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs);
1335RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs);
1336RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs);
1337RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001338// RValue<Int2> operator+(RValue<Int2> val);
1339// RValue<Int2> operator-(RValue<Int2> val);
Nicolas Capens157ba262019-12-10 17:49:14 -05001340RValue<Int2> operator~(RValue<Int2> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001341// RValue<Int2> operator++(Int2 &val, int); // Post-increment
1342// const Int2 &operator++(Int2 &val); // Pre-increment
1343// RValue<Int2> operator--(Int2 &val, int); // Post-decrement
1344// const Int2 &operator--(Int2 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001345// RValue<Bool> operator<(RValue<Int2> lhs, RValue<Int2> rhs);
1346// RValue<Bool> operator<=(RValue<Int2> lhs, RValue<Int2> rhs);
1347// RValue<Bool> operator>(RValue<Int2> lhs, RValue<Int2> rhs);
1348// RValue<Bool> operator>=(RValue<Int2> lhs, RValue<Int2> rhs);
1349// RValue<Bool> operator!=(RValue<Int2> lhs, RValue<Int2> rhs);
1350// RValue<Bool> operator==(RValue<Int2> lhs, RValue<Int2> rhs);
1351
1352// RValue<Int2> RoundInt(RValue<Float4> cast);
Nicolas Capens157ba262019-12-10 17:49:14 -05001353RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y);
1354RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y);
1355RValue<Int> Extract(RValue<Int2> val, int i);
1356RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i);
Nicolas Capensd022e412016-09-26 13:30:14 -04001357
Nicolas Capens157ba262019-12-10 17:49:14 -05001358class UInt2 : public LValue<UInt2>
1359{
1360public:
1361 UInt2() = default;
1362 UInt2(unsigned int x, unsigned int y);
1363 UInt2(RValue<UInt2> rhs);
1364 UInt2(const UInt2 &rhs);
1365 UInt2(const Reference<UInt2> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001366
Nicolas Capens157ba262019-12-10 17:49:14 -05001367 RValue<UInt2> operator=(RValue<UInt2> rhs);
1368 RValue<UInt2> operator=(const UInt2 &rhs);
1369 RValue<UInt2> operator=(const Reference<UInt2> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001370
Nicolas Capens157ba262019-12-10 17:49:14 -05001371 static Type *getType();
1372};
Nicolas Capensd022e412016-09-26 13:30:14 -04001373
Nicolas Capens157ba262019-12-10 17:49:14 -05001374RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs);
1375RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001376// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs);
1377// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs);
1378// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -05001379RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs);
1380RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs);
1381RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs);
1382RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs);
1383RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs);
1384RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs);
1385RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001386// RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs);
1387// RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs);
1388// RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -05001389RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs);
1390RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs);
1391RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs);
1392RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs);
1393RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001394// RValue<UInt2> operator+(RValue<UInt2> val);
1395// RValue<UInt2> operator-(RValue<UInt2> val);
Nicolas Capens157ba262019-12-10 17:49:14 -05001396RValue<UInt2> operator~(RValue<UInt2> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001397// RValue<UInt2> operator++(UInt2 &val, int); // Post-increment
1398// const UInt2 &operator++(UInt2 &val); // Pre-increment
1399// RValue<UInt2> operator--(UInt2 &val, int); // Post-decrement
1400// const UInt2 &operator--(UInt2 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001401// RValue<Bool> operator<(RValue<UInt2> lhs, RValue<UInt2> rhs);
1402// RValue<Bool> operator<=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1403// RValue<Bool> operator>(RValue<UInt2> lhs, RValue<UInt2> rhs);
1404// RValue<Bool> operator>=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1405// RValue<Bool> operator!=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1406// RValue<Bool> operator==(RValue<UInt2> lhs, RValue<UInt2> rhs);
1407
1408// RValue<UInt2> RoundInt(RValue<Float4> cast);
Nicolas Capens157ba262019-12-10 17:49:14 -05001409RValue<UInt> Extract(RValue<UInt2> val, int i);
1410RValue<UInt2> Insert(RValue<UInt2> val, RValue<UInt> element, int i);
Nicolas Capensd022e412016-09-26 13:30:14 -04001411
Nicolas Capens157ba262019-12-10 17:49:14 -05001412template<class T>
1413struct Scalar;
Nicolas Capenscb986762017-01-20 11:34:37 -05001414
Nicolas Capens157ba262019-12-10 17:49:14 -05001415template<class Vector4>
1416struct XYZW;
Nicolas Capenscb986762017-01-20 11:34:37 -05001417
Nicolas Capens157ba262019-12-10 17:49:14 -05001418template<class Vector4, int T>
1419class Swizzle2
1420{
1421 friend Vector4;
1422
1423public:
1424 operator RValue<Vector4>() const;
1425
1426private:
1427 Vector4 *parent;
1428};
1429
1430template<class Vector4, int T>
1431class Swizzle4
1432{
1433public:
1434 operator RValue<Vector4>() const;
1435
1436private:
1437 Vector4 *parent;
1438};
1439
1440template<class Vector4, int T>
1441class SwizzleMask4
1442{
1443 friend XYZW<Vector4>;
1444
1445public:
1446 operator RValue<Vector4>() const;
1447
1448 RValue<Vector4> operator=(RValue<Vector4> rhs);
1449 RValue<Vector4> operator=(RValue<typename Scalar<Vector4>::Type> rhs);
1450
1451private:
1452 Vector4 *parent;
1453};
1454
1455template<>
1456struct Scalar<Float4>
1457{
1458 using Type = Float;
1459};
1460
1461template<>
1462struct Scalar<Int4>
1463{
1464 using Type = Int;
1465};
1466
1467template<>
1468struct Scalar<UInt4>
1469{
1470 using Type = UInt;
1471};
1472
1473template<class Vector4, int T>
1474class SwizzleMask1
1475{
1476public:
1477 operator RValue<typename Scalar<Vector4>::Type>() const;
1478 operator RValue<Vector4>() const;
1479
1480 RValue<Vector4> operator=(float x);
1481 RValue<Vector4> operator=(RValue<Vector4> rhs);
1482 RValue<Vector4> operator=(RValue<typename Scalar<Vector4>::Type> rhs);
1483
1484private:
1485 Vector4 *parent;
1486};
1487
1488template<class Vector4, int T>
1489class SwizzleMask2
1490{
1491 friend class Float4;
1492
1493public:
1494 operator RValue<Vector4>() const;
1495
1496 RValue<Vector4> operator=(RValue<Vector4> rhs);
1497
1498private:
1499 Float4 *parent;
1500};
1501
1502template<class Vector4>
1503struct XYZW
1504{
1505 friend Vector4;
1506
1507private:
1508 XYZW(Vector4 *parent)
Nicolas Capenscb986762017-01-20 11:34:37 -05001509 {
Nicolas Capens157ba262019-12-10 17:49:14 -05001510 xyzw.parent = parent;
1511 }
Nicolas Capenscb986762017-01-20 11:34:37 -05001512
Nicolas Capens157ba262019-12-10 17:49:14 -05001513public:
1514 union
Nicolas Capenscb986762017-01-20 11:34:37 -05001515 {
Nicolas Capens157ba262019-12-10 17:49:14 -05001516 SwizzleMask1<Vector4, 0x0000> x;
1517 SwizzleMask1<Vector4, 0x1111> y;
1518 SwizzleMask1<Vector4, 0x2222> z;
1519 SwizzleMask1<Vector4, 0x3333> w;
Ben Clayton713b8d32019-12-17 20:37:56 +00001520 Swizzle2<Vector4, 0x0000> xx;
1521 Swizzle2<Vector4, 0x1000> yx;
1522 Swizzle2<Vector4, 0x2000> zx;
1523 Swizzle2<Vector4, 0x3000> wx;
Nicolas Capens157ba262019-12-10 17:49:14 -05001524 SwizzleMask2<Vector4, 0x0111> xy;
Ben Clayton713b8d32019-12-17 20:37:56 +00001525 Swizzle2<Vector4, 0x1111> yy;
1526 Swizzle2<Vector4, 0x2111> zy;
1527 Swizzle2<Vector4, 0x3111> wy;
Nicolas Capens157ba262019-12-10 17:49:14 -05001528 SwizzleMask2<Vector4, 0x0222> xz;
1529 SwizzleMask2<Vector4, 0x1222> yz;
Ben Clayton713b8d32019-12-17 20:37:56 +00001530 Swizzle2<Vector4, 0x2222> zz;
1531 Swizzle2<Vector4, 0x3222> wz;
Nicolas Capens157ba262019-12-10 17:49:14 -05001532 SwizzleMask2<Vector4, 0x0333> xw;
1533 SwizzleMask2<Vector4, 0x1333> yw;
1534 SwizzleMask2<Vector4, 0x2333> zw;
Ben Clayton713b8d32019-12-17 20:37:56 +00001535 Swizzle2<Vector4, 0x3333> ww;
1536 Swizzle4<Vector4, 0x0000> xxx;
1537 Swizzle4<Vector4, 0x1000> yxx;
1538 Swizzle4<Vector4, 0x2000> zxx;
1539 Swizzle4<Vector4, 0x3000> wxx;
1540 Swizzle4<Vector4, 0x0100> xyx;
1541 Swizzle4<Vector4, 0x1100> yyx;
1542 Swizzle4<Vector4, 0x2100> zyx;
1543 Swizzle4<Vector4, 0x3100> wyx;
1544 Swizzle4<Vector4, 0x0200> xzx;
1545 Swizzle4<Vector4, 0x1200> yzx;
1546 Swizzle4<Vector4, 0x2200> zzx;
1547 Swizzle4<Vector4, 0x3200> wzx;
1548 Swizzle4<Vector4, 0x0300> xwx;
1549 Swizzle4<Vector4, 0x1300> ywx;
1550 Swizzle4<Vector4, 0x2300> zwx;
1551 Swizzle4<Vector4, 0x3300> wwx;
1552 Swizzle4<Vector4, 0x0011> xxy;
1553 Swizzle4<Vector4, 0x1011> yxy;
1554 Swizzle4<Vector4, 0x2011> zxy;
1555 Swizzle4<Vector4, 0x3011> wxy;
1556 Swizzle4<Vector4, 0x0111> xyy;
1557 Swizzle4<Vector4, 0x1111> yyy;
1558 Swizzle4<Vector4, 0x2111> zyy;
1559 Swizzle4<Vector4, 0x3111> wyy;
1560 Swizzle4<Vector4, 0x0211> xzy;
1561 Swizzle4<Vector4, 0x1211> yzy;
1562 Swizzle4<Vector4, 0x2211> zzy;
1563 Swizzle4<Vector4, 0x3211> wzy;
1564 Swizzle4<Vector4, 0x0311> xwy;
1565 Swizzle4<Vector4, 0x1311> ywy;
1566 Swizzle4<Vector4, 0x2311> zwy;
1567 Swizzle4<Vector4, 0x3311> wwy;
1568 Swizzle4<Vector4, 0x0022> xxz;
1569 Swizzle4<Vector4, 0x1022> yxz;
1570 Swizzle4<Vector4, 0x2022> zxz;
1571 Swizzle4<Vector4, 0x3022> wxz;
Nicolas Capens157ba262019-12-10 17:49:14 -05001572 SwizzleMask4<Vector4, 0x0122> xyz;
Ben Clayton713b8d32019-12-17 20:37:56 +00001573 Swizzle4<Vector4, 0x1122> yyz;
1574 Swizzle4<Vector4, 0x2122> zyz;
1575 Swizzle4<Vector4, 0x3122> wyz;
1576 Swizzle4<Vector4, 0x0222> xzz;
1577 Swizzle4<Vector4, 0x1222> yzz;
1578 Swizzle4<Vector4, 0x2222> zzz;
1579 Swizzle4<Vector4, 0x3222> wzz;
1580 Swizzle4<Vector4, 0x0322> xwz;
1581 Swizzle4<Vector4, 0x1322> ywz;
1582 Swizzle4<Vector4, 0x2322> zwz;
1583 Swizzle4<Vector4, 0x3322> wwz;
1584 Swizzle4<Vector4, 0x0033> xxw;
1585 Swizzle4<Vector4, 0x1033> yxw;
1586 Swizzle4<Vector4, 0x2033> zxw;
1587 Swizzle4<Vector4, 0x3033> wxw;
Nicolas Capens157ba262019-12-10 17:49:14 -05001588 SwizzleMask4<Vector4, 0x0133> xyw;
Ben Clayton713b8d32019-12-17 20:37:56 +00001589 Swizzle4<Vector4, 0x1133> yyw;
1590 Swizzle4<Vector4, 0x2133> zyw;
1591 Swizzle4<Vector4, 0x3133> wyw;
Nicolas Capens157ba262019-12-10 17:49:14 -05001592 SwizzleMask4<Vector4, 0x0233> xzw;
1593 SwizzleMask4<Vector4, 0x1233> yzw;
Ben Clayton713b8d32019-12-17 20:37:56 +00001594 Swizzle4<Vector4, 0x2233> zzw;
1595 Swizzle4<Vector4, 0x3233> wzw;
1596 Swizzle4<Vector4, 0x0333> xww;
1597 Swizzle4<Vector4, 0x1333> yww;
1598 Swizzle4<Vector4, 0x2333> zww;
1599 Swizzle4<Vector4, 0x3333> www;
1600 Swizzle4<Vector4, 0x0000> xxxx;
1601 Swizzle4<Vector4, 0x1000> yxxx;
1602 Swizzle4<Vector4, 0x2000> zxxx;
1603 Swizzle4<Vector4, 0x3000> wxxx;
1604 Swizzle4<Vector4, 0x0100> xyxx;
1605 Swizzle4<Vector4, 0x1100> yyxx;
1606 Swizzle4<Vector4, 0x2100> zyxx;
1607 Swizzle4<Vector4, 0x3100> wyxx;
1608 Swizzle4<Vector4, 0x0200> xzxx;
1609 Swizzle4<Vector4, 0x1200> yzxx;
1610 Swizzle4<Vector4, 0x2200> zzxx;
1611 Swizzle4<Vector4, 0x3200> wzxx;
1612 Swizzle4<Vector4, 0x0300> xwxx;
1613 Swizzle4<Vector4, 0x1300> ywxx;
1614 Swizzle4<Vector4, 0x2300> zwxx;
1615 Swizzle4<Vector4, 0x3300> wwxx;
1616 Swizzle4<Vector4, 0x0010> xxyx;
1617 Swizzle4<Vector4, 0x1010> yxyx;
1618 Swizzle4<Vector4, 0x2010> zxyx;
1619 Swizzle4<Vector4, 0x3010> wxyx;
1620 Swizzle4<Vector4, 0x0110> xyyx;
1621 Swizzle4<Vector4, 0x1110> yyyx;
1622 Swizzle4<Vector4, 0x2110> zyyx;
1623 Swizzle4<Vector4, 0x3110> wyyx;
1624 Swizzle4<Vector4, 0x0210> xzyx;
1625 Swizzle4<Vector4, 0x1210> yzyx;
1626 Swizzle4<Vector4, 0x2210> zzyx;
1627 Swizzle4<Vector4, 0x3210> wzyx;
1628 Swizzle4<Vector4, 0x0310> xwyx;
1629 Swizzle4<Vector4, 0x1310> ywyx;
1630 Swizzle4<Vector4, 0x2310> zwyx;
1631 Swizzle4<Vector4, 0x3310> wwyx;
1632 Swizzle4<Vector4, 0x0020> xxzx;
1633 Swizzle4<Vector4, 0x1020> yxzx;
1634 Swizzle4<Vector4, 0x2020> zxzx;
1635 Swizzle4<Vector4, 0x3020> wxzx;
1636 Swizzle4<Vector4, 0x0120> xyzx;
1637 Swizzle4<Vector4, 0x1120> yyzx;
1638 Swizzle4<Vector4, 0x2120> zyzx;
1639 Swizzle4<Vector4, 0x3120> wyzx;
1640 Swizzle4<Vector4, 0x0220> xzzx;
1641 Swizzle4<Vector4, 0x1220> yzzx;
1642 Swizzle4<Vector4, 0x2220> zzzx;
1643 Swizzle4<Vector4, 0x3220> wzzx;
1644 Swizzle4<Vector4, 0x0320> xwzx;
1645 Swizzle4<Vector4, 0x1320> ywzx;
1646 Swizzle4<Vector4, 0x2320> zwzx;
1647 Swizzle4<Vector4, 0x3320> wwzx;
1648 Swizzle4<Vector4, 0x0030> xxwx;
1649 Swizzle4<Vector4, 0x1030> yxwx;
1650 Swizzle4<Vector4, 0x2030> zxwx;
1651 Swizzle4<Vector4, 0x3030> wxwx;
1652 Swizzle4<Vector4, 0x0130> xywx;
1653 Swizzle4<Vector4, 0x1130> yywx;
1654 Swizzle4<Vector4, 0x2130> zywx;
1655 Swizzle4<Vector4, 0x3130> wywx;
1656 Swizzle4<Vector4, 0x0230> xzwx;
1657 Swizzle4<Vector4, 0x1230> yzwx;
1658 Swizzle4<Vector4, 0x2230> zzwx;
1659 Swizzle4<Vector4, 0x3230> wzwx;
1660 Swizzle4<Vector4, 0x0330> xwwx;
1661 Swizzle4<Vector4, 0x1330> ywwx;
1662 Swizzle4<Vector4, 0x2330> zwwx;
1663 Swizzle4<Vector4, 0x3330> wwwx;
1664 Swizzle4<Vector4, 0x0001> xxxy;
1665 Swizzle4<Vector4, 0x1001> yxxy;
1666 Swizzle4<Vector4, 0x2001> zxxy;
1667 Swizzle4<Vector4, 0x3001> wxxy;
1668 Swizzle4<Vector4, 0x0101> xyxy;
1669 Swizzle4<Vector4, 0x1101> yyxy;
1670 Swizzle4<Vector4, 0x2101> zyxy;
1671 Swizzle4<Vector4, 0x3101> wyxy;
1672 Swizzle4<Vector4, 0x0201> xzxy;
1673 Swizzle4<Vector4, 0x1201> yzxy;
1674 Swizzle4<Vector4, 0x2201> zzxy;
1675 Swizzle4<Vector4, 0x3201> wzxy;
1676 Swizzle4<Vector4, 0x0301> xwxy;
1677 Swizzle4<Vector4, 0x1301> ywxy;
1678 Swizzle4<Vector4, 0x2301> zwxy;
1679 Swizzle4<Vector4, 0x3301> wwxy;
1680 Swizzle4<Vector4, 0x0011> xxyy;
1681 Swizzle4<Vector4, 0x1011> yxyy;
1682 Swizzle4<Vector4, 0x2011> zxyy;
1683 Swizzle4<Vector4, 0x3011> wxyy;
1684 Swizzle4<Vector4, 0x0111> xyyy;
1685 Swizzle4<Vector4, 0x1111> yyyy;
1686 Swizzle4<Vector4, 0x2111> zyyy;
1687 Swizzle4<Vector4, 0x3111> wyyy;
1688 Swizzle4<Vector4, 0x0211> xzyy;
1689 Swizzle4<Vector4, 0x1211> yzyy;
1690 Swizzle4<Vector4, 0x2211> zzyy;
1691 Swizzle4<Vector4, 0x3211> wzyy;
1692 Swizzle4<Vector4, 0x0311> xwyy;
1693 Swizzle4<Vector4, 0x1311> ywyy;
1694 Swizzle4<Vector4, 0x2311> zwyy;
1695 Swizzle4<Vector4, 0x3311> wwyy;
1696 Swizzle4<Vector4, 0x0021> xxzy;
1697 Swizzle4<Vector4, 0x1021> yxzy;
1698 Swizzle4<Vector4, 0x2021> zxzy;
1699 Swizzle4<Vector4, 0x3021> wxzy;
1700 Swizzle4<Vector4, 0x0121> xyzy;
1701 Swizzle4<Vector4, 0x1121> yyzy;
1702 Swizzle4<Vector4, 0x2121> zyzy;
1703 Swizzle4<Vector4, 0x3121> wyzy;
1704 Swizzle4<Vector4, 0x0221> xzzy;
1705 Swizzle4<Vector4, 0x1221> yzzy;
1706 Swizzle4<Vector4, 0x2221> zzzy;
1707 Swizzle4<Vector4, 0x3221> wzzy;
1708 Swizzle4<Vector4, 0x0321> xwzy;
1709 Swizzle4<Vector4, 0x1321> ywzy;
1710 Swizzle4<Vector4, 0x2321> zwzy;
1711 Swizzle4<Vector4, 0x3321> wwzy;
1712 Swizzle4<Vector4, 0x0031> xxwy;
1713 Swizzle4<Vector4, 0x1031> yxwy;
1714 Swizzle4<Vector4, 0x2031> zxwy;
1715 Swizzle4<Vector4, 0x3031> wxwy;
1716 Swizzle4<Vector4, 0x0131> xywy;
1717 Swizzle4<Vector4, 0x1131> yywy;
1718 Swizzle4<Vector4, 0x2131> zywy;
1719 Swizzle4<Vector4, 0x3131> wywy;
1720 Swizzle4<Vector4, 0x0231> xzwy;
1721 Swizzle4<Vector4, 0x1231> yzwy;
1722 Swizzle4<Vector4, 0x2231> zzwy;
1723 Swizzle4<Vector4, 0x3231> wzwy;
1724 Swizzle4<Vector4, 0x0331> xwwy;
1725 Swizzle4<Vector4, 0x1331> ywwy;
1726 Swizzle4<Vector4, 0x2331> zwwy;
1727 Swizzle4<Vector4, 0x3331> wwwy;
1728 Swizzle4<Vector4, 0x0002> xxxz;
1729 Swizzle4<Vector4, 0x1002> yxxz;
1730 Swizzle4<Vector4, 0x2002> zxxz;
1731 Swizzle4<Vector4, 0x3002> wxxz;
1732 Swizzle4<Vector4, 0x0102> xyxz;
1733 Swizzle4<Vector4, 0x1102> yyxz;
1734 Swizzle4<Vector4, 0x2102> zyxz;
1735 Swizzle4<Vector4, 0x3102> wyxz;
1736 Swizzle4<Vector4, 0x0202> xzxz;
1737 Swizzle4<Vector4, 0x1202> yzxz;
1738 Swizzle4<Vector4, 0x2202> zzxz;
1739 Swizzle4<Vector4, 0x3202> wzxz;
1740 Swizzle4<Vector4, 0x0302> xwxz;
1741 Swizzle4<Vector4, 0x1302> ywxz;
1742 Swizzle4<Vector4, 0x2302> zwxz;
1743 Swizzle4<Vector4, 0x3302> wwxz;
1744 Swizzle4<Vector4, 0x0012> xxyz;
1745 Swizzle4<Vector4, 0x1012> yxyz;
1746 Swizzle4<Vector4, 0x2012> zxyz;
1747 Swizzle4<Vector4, 0x3012> wxyz;
1748 Swizzle4<Vector4, 0x0112> xyyz;
1749 Swizzle4<Vector4, 0x1112> yyyz;
1750 Swizzle4<Vector4, 0x2112> zyyz;
1751 Swizzle4<Vector4, 0x3112> wyyz;
1752 Swizzle4<Vector4, 0x0212> xzyz;
1753 Swizzle4<Vector4, 0x1212> yzyz;
1754 Swizzle4<Vector4, 0x2212> zzyz;
1755 Swizzle4<Vector4, 0x3212> wzyz;
1756 Swizzle4<Vector4, 0x0312> xwyz;
1757 Swizzle4<Vector4, 0x1312> ywyz;
1758 Swizzle4<Vector4, 0x2312> zwyz;
1759 Swizzle4<Vector4, 0x3312> wwyz;
1760 Swizzle4<Vector4, 0x0022> xxzz;
1761 Swizzle4<Vector4, 0x1022> yxzz;
1762 Swizzle4<Vector4, 0x2022> zxzz;
1763 Swizzle4<Vector4, 0x3022> wxzz;
1764 Swizzle4<Vector4, 0x0122> xyzz;
1765 Swizzle4<Vector4, 0x1122> yyzz;
1766 Swizzle4<Vector4, 0x2122> zyzz;
1767 Swizzle4<Vector4, 0x3122> wyzz;
1768 Swizzle4<Vector4, 0x0222> xzzz;
1769 Swizzle4<Vector4, 0x1222> yzzz;
1770 Swizzle4<Vector4, 0x2222> zzzz;
1771 Swizzle4<Vector4, 0x3222> wzzz;
1772 Swizzle4<Vector4, 0x0322> xwzz;
1773 Swizzle4<Vector4, 0x1322> ywzz;
1774 Swizzle4<Vector4, 0x2322> zwzz;
1775 Swizzle4<Vector4, 0x3322> wwzz;
1776 Swizzle4<Vector4, 0x0032> xxwz;
1777 Swizzle4<Vector4, 0x1032> yxwz;
1778 Swizzle4<Vector4, 0x2032> zxwz;
1779 Swizzle4<Vector4, 0x3032> wxwz;
1780 Swizzle4<Vector4, 0x0132> xywz;
1781 Swizzle4<Vector4, 0x1132> yywz;
1782 Swizzle4<Vector4, 0x2132> zywz;
1783 Swizzle4<Vector4, 0x3132> wywz;
1784 Swizzle4<Vector4, 0x0232> xzwz;
1785 Swizzle4<Vector4, 0x1232> yzwz;
1786 Swizzle4<Vector4, 0x2232> zzwz;
1787 Swizzle4<Vector4, 0x3232> wzwz;
1788 Swizzle4<Vector4, 0x0332> xwwz;
1789 Swizzle4<Vector4, 0x1332> ywwz;
1790 Swizzle4<Vector4, 0x2332> zwwz;
1791 Swizzle4<Vector4, 0x3332> wwwz;
1792 Swizzle4<Vector4, 0x0003> xxxw;
1793 Swizzle4<Vector4, 0x1003> yxxw;
1794 Swizzle4<Vector4, 0x2003> zxxw;
1795 Swizzle4<Vector4, 0x3003> wxxw;
1796 Swizzle4<Vector4, 0x0103> xyxw;
1797 Swizzle4<Vector4, 0x1103> yyxw;
1798 Swizzle4<Vector4, 0x2103> zyxw;
1799 Swizzle4<Vector4, 0x3103> wyxw;
1800 Swizzle4<Vector4, 0x0203> xzxw;
1801 Swizzle4<Vector4, 0x1203> yzxw;
1802 Swizzle4<Vector4, 0x2203> zzxw;
1803 Swizzle4<Vector4, 0x3203> wzxw;
1804 Swizzle4<Vector4, 0x0303> xwxw;
1805 Swizzle4<Vector4, 0x1303> ywxw;
1806 Swizzle4<Vector4, 0x2303> zwxw;
1807 Swizzle4<Vector4, 0x3303> wwxw;
1808 Swizzle4<Vector4, 0x0013> xxyw;
1809 Swizzle4<Vector4, 0x1013> yxyw;
1810 Swizzle4<Vector4, 0x2013> zxyw;
1811 Swizzle4<Vector4, 0x3013> wxyw;
1812 Swizzle4<Vector4, 0x0113> xyyw;
1813 Swizzle4<Vector4, 0x1113> yyyw;
1814 Swizzle4<Vector4, 0x2113> zyyw;
1815 Swizzle4<Vector4, 0x3113> wyyw;
1816 Swizzle4<Vector4, 0x0213> xzyw;
1817 Swizzle4<Vector4, 0x1213> yzyw;
1818 Swizzle4<Vector4, 0x2213> zzyw;
1819 Swizzle4<Vector4, 0x3213> wzyw;
1820 Swizzle4<Vector4, 0x0313> xwyw;
1821 Swizzle4<Vector4, 0x1313> ywyw;
1822 Swizzle4<Vector4, 0x2313> zwyw;
1823 Swizzle4<Vector4, 0x3313> wwyw;
1824 Swizzle4<Vector4, 0x0023> xxzw;
1825 Swizzle4<Vector4, 0x1023> yxzw;
1826 Swizzle4<Vector4, 0x2023> zxzw;
1827 Swizzle4<Vector4, 0x3023> wxzw;
Nicolas Capens157ba262019-12-10 17:49:14 -05001828 SwizzleMask4<Vector4, 0x0123> xyzw;
Ben Clayton713b8d32019-12-17 20:37:56 +00001829 Swizzle4<Vector4, 0x1123> yyzw;
1830 Swizzle4<Vector4, 0x2123> zyzw;
1831 Swizzle4<Vector4, 0x3123> wyzw;
1832 Swizzle4<Vector4, 0x0223> xzzw;
1833 Swizzle4<Vector4, 0x1223> yzzw;
1834 Swizzle4<Vector4, 0x2223> zzzw;
1835 Swizzle4<Vector4, 0x3223> wzzw;
1836 Swizzle4<Vector4, 0x0323> xwzw;
1837 Swizzle4<Vector4, 0x1323> ywzw;
1838 Swizzle4<Vector4, 0x2323> zwzw;
1839 Swizzle4<Vector4, 0x3323> wwzw;
1840 Swizzle4<Vector4, 0x0033> xxww;
1841 Swizzle4<Vector4, 0x1033> yxww;
1842 Swizzle4<Vector4, 0x2033> zxww;
1843 Swizzle4<Vector4, 0x3033> wxww;
1844 Swizzle4<Vector4, 0x0133> xyww;
1845 Swizzle4<Vector4, 0x1133> yyww;
1846 Swizzle4<Vector4, 0x2133> zyww;
1847 Swizzle4<Vector4, 0x3133> wyww;
1848 Swizzle4<Vector4, 0x0233> xzww;
1849 Swizzle4<Vector4, 0x1233> yzww;
1850 Swizzle4<Vector4, 0x2233> zzww;
1851 Swizzle4<Vector4, 0x3233> wzww;
1852 Swizzle4<Vector4, 0x0333> xwww;
1853 Swizzle4<Vector4, 0x1333> ywww;
1854 Swizzle4<Vector4, 0x2333> zwww;
1855 Swizzle4<Vector4, 0x3333> wwww;
Nicolas Capenscb986762017-01-20 11:34:37 -05001856 };
Nicolas Capens157ba262019-12-10 17:49:14 -05001857};
Nicolas Capenscb986762017-01-20 11:34:37 -05001858
Nicolas Capens157ba262019-12-10 17:49:14 -05001859class Int4 : public LValue<Int4>, public XYZW<Int4>
1860{
1861public:
1862 explicit Int4(RValue<Byte4> cast);
1863 explicit Int4(RValue<SByte4> cast);
1864 explicit Int4(RValue<Float4> cast);
1865 explicit Int4(RValue<Short4> cast);
1866 explicit Int4(RValue<UShort4> cast);
Nicolas Capenscb986762017-01-20 11:34:37 -05001867
Nicolas Capens157ba262019-12-10 17:49:14 -05001868 Int4();
1869 Int4(int xyzw);
1870 Int4(int x, int yzw);
1871 Int4(int x, int y, int zw);
1872 Int4(int x, int y, int z, int w);
1873 Int4(RValue<Int4> rhs);
1874 Int4(const Int4 &rhs);
1875 Int4(const Reference<Int4> &rhs);
1876 Int4(RValue<UInt4> rhs);
1877 Int4(const UInt4 &rhs);
1878 Int4(const Reference<UInt4> &rhs);
1879 Int4(RValue<Int2> lo, RValue<Int2> hi);
1880 Int4(RValue<Int> rhs);
1881 Int4(const Int &rhs);
1882 Int4(const Reference<Int> &rhs);
Nicolas Capenscb986762017-01-20 11:34:37 -05001883
Nicolas Capens157ba262019-12-10 17:49:14 -05001884 RValue<Int4> operator=(RValue<Int4> rhs);
1885 RValue<Int4> operator=(const Int4 &rhs);
1886 RValue<Int4> operator=(const Reference<Int4> &rhs);
Nicolas Capenscb986762017-01-20 11:34:37 -05001887
Nicolas Capens157ba262019-12-10 17:49:14 -05001888 static Type *getType();
Nicolas Capenscb986762017-01-20 11:34:37 -05001889
Nicolas Capens157ba262019-12-10 17:49:14 -05001890private:
1891 void constant(int x, int y, int z, int w);
1892};
Nicolas Capenscb986762017-01-20 11:34:37 -05001893
Nicolas Capens157ba262019-12-10 17:49:14 -05001894RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs);
1895RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs);
1896RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs);
1897RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs);
1898RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs);
1899RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs);
1900RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs);
1901RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs);
1902RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs);
1903RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs);
1904RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs);
1905RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs);
1906RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs);
1907RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs);
1908RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001909// RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs);
1910// RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -05001911RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs);
1912RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs);
1913RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs);
1914RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs);
1915RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs);
1916RValue<Int4> operator+(RValue<Int4> val);
1917RValue<Int4> operator-(RValue<Int4> val);
1918RValue<Int4> operator~(RValue<Int4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001919// RValue<Int4> operator++(Int4 &val, int); // Post-increment
1920// const Int4 &operator++(Int4 &val); // Pre-increment
1921// RValue<Int4> operator--(Int4 &val, int); // Post-decrement
1922// const Int4 &operator--(Int4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001923// RValue<Bool> operator<(RValue<Int4> lhs, RValue<Int4> rhs);
1924// RValue<Bool> operator<=(RValue<Int4> lhs, RValue<Int4> rhs);
1925// RValue<Bool> operator>(RValue<Int4> lhs, RValue<Int4> rhs);
1926// RValue<Bool> operator>=(RValue<Int4> lhs, RValue<Int4> rhs);
1927// RValue<Bool> operator!=(RValue<Int4> lhs, RValue<Int4> rhs);
1928// RValue<Bool> operator==(RValue<Int4> lhs, RValue<Int4> rhs);
1929
Nicolas Capens157ba262019-12-10 17:49:14 -05001930inline RValue<Int4> operator+(RValue<Int> lhs, RValue<Int4> rhs)
1931{
1932 return Int4(lhs) + rhs;
1933}
Nicolas Capens4b743732018-05-28 13:22:07 -04001934
Nicolas Capens157ba262019-12-10 17:49:14 -05001935inline RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int> rhs)
1936{
1937 return lhs + Int4(rhs);
1938}
Nicolas Capens4b743732018-05-28 13:22:07 -04001939
Nicolas Capens157ba262019-12-10 17:49:14 -05001940RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y);
1941RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y);
1942RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y);
1943RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y);
1944RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y);
1945RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y);
Ben Clayton713b8d32019-12-17 20:37:56 +00001946inline RValue<Int4> CmpGT(RValue<Int4> x, RValue<Int4> y)
1947{
1948 return CmpNLE(x, y);
1949}
1950inline RValue<Int4> CmpGE(RValue<Int4> x, RValue<Int4> y)
1951{
1952 return CmpNLT(x, y);
1953}
Nicolas Capens157ba262019-12-10 17:49:14 -05001954RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y);
1955RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y);
1956RValue<Int4> RoundInt(RValue<Float4> cast);
1957RValue<Short8> PackSigned(RValue<Int4> x, RValue<Int4> y);
1958RValue<UShort8> PackUnsigned(RValue<Int4> x, RValue<Int4> y);
1959RValue<Int> Extract(RValue<Int4> val, int i);
1960RValue<Int4> Insert(RValue<Int4> val, RValue<Int> element, int i);
1961RValue<Int> SignMask(RValue<Int4> x);
1962RValue<Int4> Swizzle(RValue<Int4> x, uint16_t select);
1963RValue<Int4> Shuffle(RValue<Int4> x, RValue<Int4> y, uint16_t select);
1964RValue<Int4> MulHigh(RValue<Int4> x, RValue<Int4> y);
Nicolas Capensd022e412016-09-26 13:30:14 -04001965
Nicolas Capens157ba262019-12-10 17:49:14 -05001966class UInt4 : public LValue<UInt4>, public XYZW<UInt4>
1967{
1968public:
1969 explicit UInt4(RValue<Float4> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -04001970
Nicolas Capens157ba262019-12-10 17:49:14 -05001971 UInt4();
1972 UInt4(int xyzw);
1973 UInt4(int x, int yzw);
1974 UInt4(int x, int y, int zw);
1975 UInt4(int x, int y, int z, int w);
1976 UInt4(RValue<UInt4> rhs);
1977 UInt4(const UInt4 &rhs);
1978 UInt4(const Reference<UInt4> &rhs);
1979 UInt4(RValue<Int4> rhs);
1980 UInt4(const Int4 &rhs);
1981 UInt4(const Reference<Int4> &rhs);
1982 UInt4(RValue<UInt2> lo, RValue<UInt2> hi);
1983 UInt4(RValue<UInt> rhs);
1984 UInt4(const UInt &rhs);
1985 UInt4(const Reference<UInt> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001986
Nicolas Capens157ba262019-12-10 17:49:14 -05001987 RValue<UInt4> operator=(RValue<UInt4> rhs);
1988 RValue<UInt4> operator=(const UInt4 &rhs);
1989 RValue<UInt4> operator=(const Reference<UInt4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001990
Nicolas Capens157ba262019-12-10 17:49:14 -05001991 static Type *getType();
Nicolas Capensd022e412016-09-26 13:30:14 -04001992
Nicolas Capens157ba262019-12-10 17:49:14 -05001993private:
1994 void constant(int x, int y, int z, int w);
1995};
Nicolas Capensd022e412016-09-26 13:30:14 -04001996
Nicolas Capens157ba262019-12-10 17:49:14 -05001997RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs);
1998RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs);
1999RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs);
2000RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs);
2001RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs);
2002RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs);
2003RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs);
2004RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs);
2005RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs);
2006RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs);
2007RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs);
2008RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs);
2009RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs);
2010RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs);
2011RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05002012// RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs);
2013// RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs);
Nicolas Capens157ba262019-12-10 17:49:14 -05002014RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs);
2015RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs);
2016RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs);
2017RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs);
2018RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs);
2019RValue<UInt4> operator+(RValue<UInt4> val);
2020RValue<UInt4> operator-(RValue<UInt4> val);
2021RValue<UInt4> operator~(RValue<UInt4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05002022// RValue<UInt4> operator++(UInt4 &val, int); // Post-increment
2023// const UInt4 &operator++(UInt4 &val); // Pre-increment
2024// RValue<UInt4> operator--(UInt4 &val, int); // Post-decrement
2025// const UInt4 &operator--(UInt4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04002026// RValue<Bool> operator<(RValue<UInt4> lhs, RValue<UInt4> rhs);
2027// RValue<Bool> operator<=(RValue<UInt4> lhs, RValue<UInt4> rhs);
2028// RValue<Bool> operator>(RValue<UInt4> lhs, RValue<UInt4> rhs);
2029// RValue<Bool> operator>=(RValue<UInt4> lhs, RValue<UInt4> rhs);
2030// RValue<Bool> operator!=(RValue<UInt4> lhs, RValue<UInt4> rhs);
2031// RValue<Bool> operator==(RValue<UInt4> lhs, RValue<UInt4> rhs);
2032
Nicolas Capens157ba262019-12-10 17:49:14 -05002033RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y);
2034RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y);
2035RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y);
2036RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y);
2037RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y);
2038RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y);
Ben Clayton713b8d32019-12-17 20:37:56 +00002039inline RValue<UInt4> CmpGT(RValue<UInt4> x, RValue<UInt4> y)
2040{
2041 return CmpNLE(x, y);
2042}
2043inline RValue<UInt4> CmpGE(RValue<UInt4> x, RValue<UInt4> y)
2044{
2045 return CmpNLT(x, y);
2046}
Nicolas Capens157ba262019-12-10 17:49:14 -05002047RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y);
2048RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y);
2049RValue<UInt4> MulHigh(RValue<UInt4> x, RValue<UInt4> y);
2050RValue<UInt> Extract(RValue<UInt4> val, int i);
2051RValue<UInt4> Insert(RValue<UInt4> val, RValue<UInt> element, int i);
Nicolas Capensd022e412016-09-26 13:30:14 -04002052// RValue<UInt4> RoundInt(RValue<Float4> cast);
Nicolas Capens157ba262019-12-10 17:49:14 -05002053RValue<UInt4> Swizzle(RValue<UInt4> x, uint16_t select);
2054RValue<UInt4> Shuffle(RValue<UInt4> x, RValue<UInt4> y, uint16_t select);
Nicolas Capensd022e412016-09-26 13:30:14 -04002055
Nicolas Capens157ba262019-12-10 17:49:14 -05002056class Half : public LValue<Half>
2057{
2058public:
2059 explicit Half(RValue<Float> cast);
Alexis Hetu734e2572018-12-20 14:00:49 -05002060
Nicolas Capens157ba262019-12-10 17:49:14 -05002061 static Type *getType();
2062};
Alexis Hetu734e2572018-12-20 14:00:49 -05002063
Nicolas Capens157ba262019-12-10 17:49:14 -05002064class Float : public LValue<Float>
2065{
2066public:
2067 explicit Float(RValue<Int> cast);
2068 explicit Float(RValue<UInt> cast);
2069 explicit Float(RValue<Half> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -04002070
Nicolas Capens157ba262019-12-10 17:49:14 -05002071 Float() = default;
2072 Float(float x);
2073 Float(RValue<Float> rhs);
2074 Float(const Float &rhs);
2075 Float(const Reference<Float> &rhs);
2076 Float(Argument<Float> argument);
Nicolas Capensd022e412016-09-26 13:30:14 -04002077
Nicolas Capens157ba262019-12-10 17:49:14 -05002078 template<int T>
2079 Float(const SwizzleMask1<Float4, T> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002080
Ben Clayton713b8d32019-12-17 20:37:56 +00002081 // RValue<Float> operator=(float rhs); // FIXME: Implement
Nicolas Capens157ba262019-12-10 17:49:14 -05002082 RValue<Float> operator=(RValue<Float> rhs);
2083 RValue<Float> operator=(const Float &rhs);
2084 RValue<Float> operator=(const Reference<Float> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002085
Nicolas Capens157ba262019-12-10 17:49:14 -05002086 template<int T>
2087 RValue<Float> operator=(const SwizzleMask1<Float4, T> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002088
Nicolas Capense5720882020-01-13 14:10:04 -05002089 static Float infinity();
2090
Nicolas Capens157ba262019-12-10 17:49:14 -05002091 static Type *getType();
2092};
Nicolas Capensd022e412016-09-26 13:30:14 -04002093
Nicolas Capens157ba262019-12-10 17:49:14 -05002094RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs);
2095RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs);
2096RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs);
2097RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs);
2098RValue<Float> operator+=(Float &lhs, RValue<Float> rhs);
2099RValue<Float> operator-=(Float &lhs, RValue<Float> rhs);
2100RValue<Float> operator*=(Float &lhs, RValue<Float> rhs);
2101RValue<Float> operator/=(Float &lhs, RValue<Float> rhs);
2102RValue<Float> operator+(RValue<Float> val);
2103RValue<Float> operator-(RValue<Float> val);
2104RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs);
2105RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs);
2106RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs);
2107RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs);
2108RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs);
2109RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002110
Nicolas Capens157ba262019-12-10 17:49:14 -05002111RValue<Float> Abs(RValue<Float> x);
2112RValue<Float> Max(RValue<Float> x, RValue<Float> y);
2113RValue<Float> Min(RValue<Float> x, RValue<Float> y);
2114RValue<Float> Rcp_pp(RValue<Float> val, bool exactAtPow2 = false);
2115RValue<Float> RcpSqrt_pp(RValue<Float> val);
2116RValue<Float> Sqrt(RValue<Float> x);
Nicolas Capens88ac3672019-08-01 13:22:34 -04002117
2118// RValue<Int4> IsInf(RValue<Float> x);
2119// RValue<Int4> IsNan(RValue<Float> x);
Nicolas Capens157ba262019-12-10 17:49:14 -05002120RValue<Float> Round(RValue<Float> x);
2121RValue<Float> Trunc(RValue<Float> x);
2122RValue<Float> Frac(RValue<Float> x);
2123RValue<Float> Floor(RValue<Float> x);
2124RValue<Float> Ceil(RValue<Float> x);
Nicolas Capens88ac3672019-08-01 13:22:34 -04002125
Nicolas Capens157ba262019-12-10 17:49:14 -05002126// Trigonometric functions
2127// TODO: Currently unimplemented for Subzero.
Nicolas Capens88ac3672019-08-01 13:22:34 -04002128// RValue<Float> Sin(RValue<Float> x);
2129// RValue<Float> Cos(RValue<Float> x);
2130// RValue<Float> Tan(RValue<Float> x);
2131// RValue<Float> Asin(RValue<Float> x);
2132// RValue<Float> Acos(RValue<Float> x);
2133// RValue<Float> Atan(RValue<Float> x);
2134// RValue<Float> Sinh(RValue<Float> x);
2135// RValue<Float> Cosh(RValue<Float> x);
2136// RValue<Float> Tanh(RValue<Float> x);
2137// RValue<Float> Asinh(RValue<Float> x);
2138// RValue<Float> Acosh(RValue<Float> x);
2139// RValue<Float> Atanh(RValue<Float> x);
2140// RValue<Float> Atan2(RValue<Float> x, RValue<Float> y);
2141
Nicolas Capens157ba262019-12-10 17:49:14 -05002142// Exponential functions
2143// TODO: Currently unimplemented for Subzero.
Nicolas Capens88ac3672019-08-01 13:22:34 -04002144// RValue<Float> Pow(RValue<Float> x, RValue<Float> y);
2145// RValue<Float> Exp(RValue<Float> x);
2146// RValue<Float> Log(RValue<Float> x);
Nicolas Capens157ba262019-12-10 17:49:14 -05002147RValue<Float> Exp2(RValue<Float> x);
2148RValue<Float> Log2(RValue<Float> x);
Nicolas Capensd022e412016-09-26 13:30:14 -04002149
Nicolas Capens157ba262019-12-10 17:49:14 -05002150class Float2 : public LValue<Float2>
2151{
2152public:
Ben Clayton713b8d32019-12-17 20:37:56 +00002153 // explicit Float2(RValue<Byte2> cast);
2154 // explicit Float2(RValue<Short2> cast);
2155 // explicit Float2(RValue<UShort2> cast);
2156 // explicit Float2(RValue<Int2> cast);
2157 // explicit Float2(RValue<UInt2> cast);
Nicolas Capens157ba262019-12-10 17:49:14 -05002158 explicit Float2(RValue<Float4> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -04002159
Nicolas Capens157ba262019-12-10 17:49:14 -05002160 Float2() = default;
Ben Clayton713b8d32019-12-17 20:37:56 +00002161 // Float2(float x, float y);
2162 // Float2(RValue<Float2> rhs);
2163 // Float2(const Float2 &rhs);
2164 // Float2(const Reference<Float2> &rhs);
2165 // Float2(RValue<Float> rhs);
2166 // Float2(const Float &rhs);
2167 // Float2(const Reference<Float> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002168
Ben Clayton713b8d32019-12-17 20:37:56 +00002169 // template<int T>
2170 // Float2(const SwizzleMask1<T> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002171
Ben Clayton713b8d32019-12-17 20:37:56 +00002172 // RValue<Float2> operator=(float replicate);
2173 // RValue<Float2> operator=(RValue<Float2> rhs);
2174 // RValue<Float2> operator=(const Float2 &rhs);
2175 // RValue<Float2> operator=(const Reference<Float2> &rhs);
2176 // RValue<Float2> operator=(RValue<Float> rhs);
2177 // RValue<Float2> operator=(const Float &rhs);
2178 // RValue<Float2> operator=(const Reference<Float> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002179
Ben Clayton713b8d32019-12-17 20:37:56 +00002180 // template<int T>
2181 // RValue<Float2> operator=(const SwizzleMask1<T> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002182
Nicolas Capens157ba262019-12-10 17:49:14 -05002183 static Type *getType();
2184};
Nicolas Capensd022e412016-09-26 13:30:14 -04002185
2186// RValue<Float2> operator+(RValue<Float2> lhs, RValue<Float2> rhs);
2187// RValue<Float2> operator-(RValue<Float2> lhs, RValue<Float2> rhs);
2188// RValue<Float2> operator*(RValue<Float2> lhs, RValue<Float2> rhs);
2189// RValue<Float2> operator/(RValue<Float2> lhs, RValue<Float2> rhs);
2190// RValue<Float2> operator%(RValue<Float2> lhs, RValue<Float2> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05002191// RValue<Float2> operator+=(Float2 &lhs, RValue<Float2> rhs);
2192// RValue<Float2> operator-=(Float2 &lhs, RValue<Float2> rhs);
2193// RValue<Float2> operator*=(Float2 &lhs, RValue<Float2> rhs);
2194// RValue<Float2> operator/=(Float2 &lhs, RValue<Float2> rhs);
2195// RValue<Float2> operator%=(Float2 &lhs, RValue<Float2> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002196// RValue<Float2> operator+(RValue<Float2> val);
2197// RValue<Float2> operator-(RValue<Float2> val);
2198
2199// RValue<Float2> Abs(RValue<Float2> x);
2200// RValue<Float2> Max(RValue<Float2> x, RValue<Float2> y);
2201// RValue<Float2> Min(RValue<Float2> x, RValue<Float2> y);
Ben Clayton8701dc42019-12-05 21:27:03 +00002202// RValue<Float2> Swizzle(RValue<Float2> x, uint16_t select);
2203// RValue<Float2> Mask(Float2 &lhs, RValue<Float2> rhs, uint16_t select);
Nicolas Capensd022e412016-09-26 13:30:14 -04002204
Nicolas Capens157ba262019-12-10 17:49:14 -05002205class Float4 : public LValue<Float4>, public XYZW<Float4>
2206{
2207public:
2208 explicit Float4(RValue<Byte4> cast);
2209 explicit Float4(RValue<SByte4> cast);
2210 explicit Float4(RValue<Short4> cast);
2211 explicit Float4(RValue<UShort4> cast);
2212 explicit Float4(RValue<Int4> cast);
2213 explicit Float4(RValue<UInt4> cast);
2214
2215 Float4();
2216 Float4(float xyzw);
2217 Float4(float x, float yzw);
2218 Float4(float x, float y, float zw);
2219 Float4(float x, float y, float z, float w);
2220 Float4(RValue<Float4> rhs);
2221 Float4(const Float4 &rhs);
2222 Float4(const Reference<Float4> &rhs);
2223 Float4(RValue<Float> rhs);
2224 Float4(const Float &rhs);
2225 Float4(const Reference<Float> &rhs);
2226
2227 template<int T>
2228 Float4(const SwizzleMask1<Float4, T> &rhs);
2229 template<int T>
2230 Float4(const Swizzle4<Float4, T> &rhs);
2231 template<int X, int Y>
2232 Float4(const Swizzle2<Float4, X> &x, const Swizzle2<Float4, Y> &y);
2233 template<int X, int Y>
2234 Float4(const SwizzleMask2<Float4, X> &x, const Swizzle2<Float4, Y> &y);
2235 template<int X, int Y>
2236 Float4(const Swizzle2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y);
2237 template<int X, int Y>
2238 Float4(const SwizzleMask2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y);
2239
2240 RValue<Float4> operator=(float replicate);
2241 RValue<Float4> operator=(RValue<Float4> rhs);
2242 RValue<Float4> operator=(const Float4 &rhs);
2243 RValue<Float4> operator=(const Reference<Float4> &rhs);
2244 RValue<Float4> operator=(RValue<Float> rhs);
2245 RValue<Float4> operator=(const Float &rhs);
2246 RValue<Float4> operator=(const Reference<Float> &rhs);
2247
2248 template<int T>
2249 RValue<Float4> operator=(const SwizzleMask1<Float4, T> &rhs);
2250 template<int T>
2251 RValue<Float4> operator=(const Swizzle4<Float4, T> &rhs);
2252
Nicolas Capense5720882020-01-13 14:10:04 -05002253 static Float4 infinity();
2254
Nicolas Capens157ba262019-12-10 17:49:14 -05002255 static Type *getType();
Ben Clayton713b8d32019-12-17 20:37:56 +00002256
Nicolas Capens157ba262019-12-10 17:49:14 -05002257private:
2258 void constant(float x, float y, float z, float w);
Nicolas Capens157ba262019-12-10 17:49:14 -05002259};
2260
2261RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs);
2262RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs);
2263RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs);
2264RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs);
2265RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs);
2266RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs);
2267RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs);
2268RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs);
2269RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs);
2270RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs);
2271RValue<Float4> operator+(RValue<Float4> val);
2272RValue<Float4> operator-(RValue<Float4> val);
2273
2274RValue<Float4> Abs(RValue<Float4> x);
2275RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y);
2276RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y);
2277RValue<Float4> Rcp_pp(RValue<Float4> val, bool exactAtPow2 = false);
2278RValue<Float4> RcpSqrt_pp(RValue<Float4> val);
2279RValue<Float4> Sqrt(RValue<Float4> x);
2280RValue<Float4> Insert(RValue<Float4> val, RValue<Float> element, int i);
2281RValue<Float> Extract(RValue<Float4> x, int i);
2282RValue<Float4> Swizzle(RValue<Float4> x, uint16_t select);
2283RValue<Float4> Shuffle(RValue<Float4> x, RValue<Float4> y, uint16_t select);
2284RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, uint16_t imm);
2285RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y);
2286RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y);
2287RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, uint16_t select);
2288RValue<Int> SignMask(RValue<Float4> x);
2289
2290// Ordered comparison functions
2291RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y);
2292RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y);
2293RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y);
2294RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y);
2295RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y);
2296RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y);
Ben Clayton713b8d32019-12-17 20:37:56 +00002297inline RValue<Int4> CmpGT(RValue<Float4> x, RValue<Float4> y)
2298{
2299 return CmpNLE(x, y);
2300}
2301inline RValue<Int4> CmpGE(RValue<Float4> x, RValue<Float4> y)
2302{
2303 return CmpNLT(x, y);
2304}
Nicolas Capens157ba262019-12-10 17:49:14 -05002305
2306// Unordered comparison functions
2307RValue<Int4> CmpUEQ(RValue<Float4> x, RValue<Float4> y);
2308RValue<Int4> CmpULT(RValue<Float4> x, RValue<Float4> y);
2309RValue<Int4> CmpULE(RValue<Float4> x, RValue<Float4> y);
2310RValue<Int4> CmpUNEQ(RValue<Float4> x, RValue<Float4> y);
2311RValue<Int4> CmpUNLT(RValue<Float4> x, RValue<Float4> y);
2312RValue<Int4> CmpUNLE(RValue<Float4> x, RValue<Float4> y);
Ben Clayton713b8d32019-12-17 20:37:56 +00002313inline RValue<Int4> CmpUGT(RValue<Float4> x, RValue<Float4> y)
2314{
2315 return CmpUNLE(x, y);
2316}
2317inline RValue<Int4> CmpUGE(RValue<Float4> x, RValue<Float4> y)
2318{
2319 return CmpUNLT(x, y);
2320}
Nicolas Capens157ba262019-12-10 17:49:14 -05002321
2322RValue<Int4> IsInf(RValue<Float4> x);
2323RValue<Int4> IsNan(RValue<Float4> x);
2324RValue<Float4> Round(RValue<Float4> x);
2325RValue<Float4> Trunc(RValue<Float4> x);
2326RValue<Float4> Frac(RValue<Float4> x);
2327RValue<Float4> Floor(RValue<Float4> x);
2328RValue<Float4> Ceil(RValue<Float4> x);
2329
2330// Trigonometric functions
2331// TODO: Currently unimplemented for Subzero.
2332RValue<Float4> Sin(RValue<Float4> x);
2333RValue<Float4> Cos(RValue<Float4> x);
2334RValue<Float4> Tan(RValue<Float4> x);
2335RValue<Float4> Asin(RValue<Float4> x);
2336RValue<Float4> Acos(RValue<Float4> x);
2337RValue<Float4> Atan(RValue<Float4> x);
2338RValue<Float4> Sinh(RValue<Float4> x);
2339RValue<Float4> Cosh(RValue<Float4> x);
2340RValue<Float4> Tanh(RValue<Float4> x);
2341RValue<Float4> Asinh(RValue<Float4> x);
2342RValue<Float4> Acosh(RValue<Float4> x);
2343RValue<Float4> Atanh(RValue<Float4> x);
2344RValue<Float4> Atan2(RValue<Float4> x, RValue<Float4> y);
2345
2346// Exponential functions
2347// TODO: Currently unimplemented for Subzero.
2348RValue<Float4> Pow(RValue<Float4> x, RValue<Float4> y);
2349RValue<Float4> Exp(RValue<Float4> x);
2350RValue<Float4> Log(RValue<Float4> x);
2351RValue<Float4> Exp2(RValue<Float4> x);
2352RValue<Float4> Log2(RValue<Float4> x);
2353
2354// Bit Manipulation functions.
2355// TODO: Currently unimplemented for Subzero.
2356
2357// Count leading zeros.
2358// Returns 32 when: !isZeroUndef && x == 0.
2359// Returns an undefined value when: isZeroUndef && x == 0.
2360RValue<UInt> Ctlz(RValue<UInt> x, bool isZeroUndef);
2361RValue<UInt4> Ctlz(RValue<UInt4> x, bool isZeroUndef);
2362
2363// Count trailing zeros.
2364// Returns 32 when: !isZeroUndef && x == 0.
2365// Returns an undefined value when: isZeroUndef && x == 0.
2366RValue<UInt> Cttz(RValue<UInt> x, bool isZeroUndef);
2367RValue<UInt4> Cttz(RValue<UInt4> x, bool isZeroUndef);
2368
2369template<class T>
2370class Pointer : public LValue<Pointer<T>>
2371{
2372public:
2373 template<class S>
Ben Clayton713b8d32019-12-17 20:37:56 +00002374 Pointer(RValue<Pointer<S>> pointerS, int alignment = 1)
2375 : alignment(alignment)
Nicolas Capensa25311a2017-01-16 17:19:00 -05002376 {
Nicolas Capens157ba262019-12-10 17:49:14 -05002377 Value *pointerT = Nucleus::createBitCast(pointerS.value, Nucleus::getPointerType(T::getType()));
2378 LValue<Pointer<T>>::storeValue(pointerT);
Ben Clayton204a4102019-07-31 13:17:47 +01002379 }
2380
Nicolas Capens157ba262019-12-10 17:49:14 -05002381 template<class S>
Ben Clayton713b8d32019-12-17 20:37:56 +00002382 Pointer(const Pointer<S> &pointer, int alignment = 1)
2383 : alignment(alignment)
Nicolas Capens86509d92019-03-21 13:23:50 -04002384 {
Nicolas Capens157ba262019-12-10 17:49:14 -05002385 Value *pointerS = pointer.loadValue();
2386 Value *pointerT = Nucleus::createBitCast(pointerS, Nucleus::getPointerType(T::getType()));
2387 LValue<Pointer<T>>::storeValue(pointerT);
Nicolas Capens86509d92019-03-21 13:23:50 -04002388 }
2389
Nicolas Capens157ba262019-12-10 17:49:14 -05002390 Pointer(Argument<Pointer<T>> argument);
Ben Clayton97035bd2019-04-16 11:35:38 -04002391
Nicolas Capens157ba262019-12-10 17:49:14 -05002392 Pointer();
2393 Pointer(RValue<Pointer<T>> rhs);
2394 Pointer(const Pointer<T> &rhs);
2395 Pointer(const Reference<Pointer<T>> &rhs);
2396 Pointer(std::nullptr_t);
Ben Claytoncb2ebc92019-06-20 00:18:03 +01002397
Nicolas Capens157ba262019-12-10 17:49:14 -05002398 RValue<Pointer<T>> operator=(RValue<Pointer<T>> rhs);
2399 RValue<Pointer<T>> operator=(const Pointer<T> &rhs);
2400 RValue<Pointer<T>> operator=(const Reference<Pointer<T>> &rhs);
2401 RValue<Pointer<T>> operator=(std::nullptr_t);
Ben Clayton0fc611f2019-04-18 11:23:27 -04002402
Nicolas Capens157ba262019-12-10 17:49:14 -05002403 Reference<T> operator*();
2404 Reference<T> operator[](int index);
2405 Reference<T> operator[](unsigned int index);
2406 Reference<T> operator[](RValue<Int> index);
2407 Reference<T> operator[](RValue<UInt> index);
Nicolas Capens86509d92019-03-21 13:23:50 -04002408
Nicolas Capens157ba262019-12-10 17:49:14 -05002409 static Type *getType();
Ben Clayton97035bd2019-04-16 11:35:38 -04002410
Nicolas Capens157ba262019-12-10 17:49:14 -05002411private:
2412 const int alignment;
2413};
Ben Clayton97035bd2019-04-16 11:35:38 -04002414
Nicolas Capens157ba262019-12-10 17:49:14 -05002415RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset);
2416RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset);
2417RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);
2418RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset);
2419RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset);
2420RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset);
Ben Clayton97035bd2019-04-16 11:35:38 -04002421
Nicolas Capens157ba262019-12-10 17:49:14 -05002422RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset);
2423RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset);
2424RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);
2425RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset);
2426RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset);
2427RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset);
Nicolas Capensd022e412016-09-26 13:30:14 -04002428
Ben Clayton713b8d32019-12-17 20:37:56 +00002429template<typename T>
Nicolas Capens157ba262019-12-10 17:49:14 -05002430RValue<Bool> operator==(const Pointer<T> &lhs, const Pointer<T> &rhs)
2431{
2432 return RValue<Bool>(Nucleus::createPtrEQ(lhs.loadValue(), rhs.loadValue()));
2433}
Ben Clayton0953d9b2019-06-25 20:57:06 +01002434
Nicolas Capens157ba262019-12-10 17:49:14 -05002435template<typename T>
2436RValue<T> Load(RValue<Pointer<T>> pointer, unsigned int alignment, bool atomic, std::memory_order memoryOrder)
2437{
2438 return RValue<T>(Nucleus::createLoad(pointer.value, T::getType(), false, alignment, atomic, memoryOrder));
2439}
2440
2441template<typename T>
2442RValue<T> Load(Pointer<T> pointer, unsigned int alignment, bool atomic, std::memory_order memoryOrder)
2443{
2444 return Load(RValue<Pointer<T>>(pointer), alignment, atomic, memoryOrder);
2445}
2446
2447// TODO: Use SIMD to template these.
2448RValue<Float4> MaskedLoad(RValue<Pointer<Float4>> base, RValue<Int4> mask, unsigned int alignment, bool zeroMaskedLanes = false);
2449RValue<Int4> MaskedLoad(RValue<Pointer<Int4>> base, RValue<Int4> mask, unsigned int alignment, bool zeroMaskedLanes = false);
2450void MaskedStore(RValue<Pointer<Float4>> base, RValue<Float4> val, RValue<Int4> mask, unsigned int alignment);
2451void MaskedStore(RValue<Pointer<Int4>> base, RValue<Int4> val, RValue<Int4> mask, unsigned int alignment);
2452
2453RValue<Float4> Gather(RValue<Pointer<Float>> base, RValue<Int4> offsets, RValue<Int4> mask, unsigned int alignment, bool zeroMaskedLanes = false);
2454RValue<Int4> Gather(RValue<Pointer<Int>> base, RValue<Int4> offsets, RValue<Int4> mask, unsigned int alignment, bool zeroMaskedLanes = false);
2455void Scatter(RValue<Pointer<Float>> base, RValue<Float4> val, RValue<Int4> offsets, RValue<Int4> mask, unsigned int alignment);
2456void Scatter(RValue<Pointer<Int>> base, RValue<Int4> val, RValue<Int4> offsets, RValue<Int4> mask, unsigned int alignment);
2457
2458template<typename T>
2459void Store(RValue<T> value, RValue<Pointer<T>> pointer, unsigned int alignment, bool atomic, std::memory_order memoryOrder)
2460{
2461 Nucleus::createStore(value.value, pointer.value, T::getType(), false, alignment, atomic, memoryOrder);
2462}
2463
2464template<typename T>
2465void Store(RValue<T> value, Pointer<T> pointer, unsigned int alignment, bool atomic, std::memory_order memoryOrder)
2466{
2467 Store(value, RValue<Pointer<T>>(pointer), alignment, atomic, memoryOrder);
2468}
2469
2470template<typename T>
2471void Store(T value, Pointer<T> pointer, unsigned int alignment, bool atomic, std::memory_order memoryOrder)
2472{
2473 Store(RValue<T>(value), RValue<Pointer<T>>(pointer), alignment, atomic, memoryOrder);
2474}
2475
2476// Fence adds a memory barrier that enforces ordering constraints on memory
2477// operations. memoryOrder can only be one of:
2478// std::memory_order_acquire, std::memory_order_release,
2479// std::memory_order_acq_rel, or std::memory_order_seq_cst.
2480void Fence(std::memory_order memoryOrder);
2481
2482template<class T, int S = 1>
2483class Array : public LValue<T>
2484{
2485public:
2486 Array(int size = S);
2487
2488 Reference<T> operator[](int index);
2489 Reference<T> operator[](unsigned int index);
2490 Reference<T> operator[](RValue<Int> index);
2491 Reference<T> operator[](RValue<UInt> index);
2492
2493 // self() returns the this pointer to this Array object.
2494 // This function exists because operator&() is overloaded by LValue<T>.
Ben Clayton713b8d32019-12-17 20:37:56 +00002495 inline Array *self() { return this; }
Nicolas Capens157ba262019-12-10 17:49:14 -05002496};
Nicolas Capensd022e412016-09-26 13:30:14 -04002497
Nicolas Capens96d4e092016-11-18 14:22:38 -05002498// RValue<Array<T>> operator++(Array<T> &val, int); // Post-increment
2499// const Array<T> &operator++(Array<T> &val); // Pre-increment
2500// RValue<Array<T>> operator--(Array<T> &val, int); // Post-decrement
2501// const Array<T> &operator--(Array<T> &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04002502
Nicolas Capens157ba262019-12-10 17:49:14 -05002503void branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB);
Nicolas Capensd022e412016-09-26 13:30:14 -04002504
Nicolas Capens157ba262019-12-10 17:49:14 -05002505// ValueOf returns a rr::Value* for the given C-type, RValue<T>, LValue<T>
2506// or Reference<T>.
Ben Clayton713b8d32019-12-17 20:37:56 +00002507template<typename T>
2508inline Value *ValueOf(const T &v)
Nicolas Capens157ba262019-12-10 17:49:14 -05002509{
2510 return ReactorType<T>::cast(v).loadValue();
Nicolas Capensd022e412016-09-26 13:30:14 -04002511}
2512
Nicolas Capens157ba262019-12-10 17:49:14 -05002513void Return();
2514
2515template<class T>
2516void Return(const T &ret)
Nicolas Capensd022e412016-09-26 13:30:14 -04002517{
Ben Clayton713b8d32019-12-17 20:37:56 +00002518 static_assert(CanBeUsedAsReturn<ReactorTypeT<T>>::value, "Unsupported type for Return()");
Nicolas Capens157ba262019-12-10 17:49:14 -05002519 Nucleus::createRet(ValueOf<T>(ret));
2520 // Place any unreachable instructions in an unreferenced block.
2521 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
2522}
2523
2524// Generic template, leave undefined!
2525template<typename FunctionType>
2526class Function;
2527
2528// Specialized for function types
2529template<typename Return, typename... Arguments>
2530class Function<Return(Arguments...)>
2531{
2532 // Static assert that the function signature is valid.
2533 static_assert(sizeof(AssertFunctionSignatureIsValid<Return(Arguments...)>) >= 0, "Invalid function signature");
2534
2535public:
2536 Function();
2537
2538 virtual ~Function();
2539
2540 template<int index>
2541 Argument<typename std::tuple_element<index, std::tuple<Arguments...>>::type> Arg() const
Nicolas Capens22479eb2016-09-28 22:34:26 -04002542 {
Nicolas Capens157ba262019-12-10 17:49:14 -05002543 Value *arg = Nucleus::getArgument(index);
2544 return Argument<typename std::tuple_element<index, std::tuple<Arguments...>>::type>(arg);
2545 }
2546
2547 std::shared_ptr<Routine> operator()(const char *name, ...);
2548 std::shared_ptr<Routine> operator()(const Config::Edit &cfg, const char *name, ...);
2549
2550protected:
2551 Nucleus *core;
Ben Clayton713b8d32019-12-17 20:37:56 +00002552 std::vector<Type *> arguments;
Nicolas Capens157ba262019-12-10 17:49:14 -05002553};
2554
2555template<typename Return>
2556class Function<Return()> : public Function<Return(Void)>
2557{
2558};
2559
2560// FunctionT accepts a C-style function type template argument, allowing it to return a type-safe RoutineT wrapper
2561template<typename FunctionType>
2562class FunctionT;
2563
2564template<typename Return, typename... Arguments>
2565class FunctionT<Return(Arguments...)> : public Function<CToReactorT<Return>(CToReactorT<Arguments>...)>
2566{
2567public:
2568 // Type of base class
2569 using BaseType = Function<CToReactorT<Return>(CToReactorT<Arguments>...)>;
2570
2571 // Function type, e.g. void(int,float)
2572 using CFunctionType = Return(Arguments...);
2573
2574 // Reactor function type, e.g. Void(Int, Float)
2575 using ReactorFunctionType = CToReactorT<Return>(CToReactorT<Arguments>...);
2576
2577 // Returned RoutineT type
2578 using RoutineType = RoutineT<CFunctionType>;
2579
2580 // Hide base implementations of operator()
2581
Ben Clayton713b8d32019-12-17 20:37:56 +00002582 RoutineType operator()(const char *name, ...)
Nicolas Capens157ba262019-12-10 17:49:14 -05002583 {
2584 return RoutineType(BaseType::operator()(name));
2585 }
2586
Ben Clayton713b8d32019-12-17 20:37:56 +00002587 RoutineType operator()(const Config::Edit &cfg, const char *name, ...)
Nicolas Capens157ba262019-12-10 17:49:14 -05002588 {
2589 return RoutineType(BaseType::operator()(cfg, name));
2590 }
2591};
2592
2593RValue<Long> Ticks();
2594
2595} // namespace rr
2596
2597/* Inline implementations */
2598
2599namespace rr {
2600
2601template<class T>
Ben Clayton713b8d32019-12-17 20:37:56 +00002602LValue<T>::LValue(int arraySize)
2603 : Variable(T::getType(), arraySize)
Nicolas Capens157ba262019-12-10 17:49:14 -05002604{
Ben Claytonac07ed82019-03-26 14:17:41 +00002605#ifdef ENABLE_RR_DEBUG_INFO
Nicolas Capens157ba262019-12-10 17:49:14 -05002606 materialize();
Ben Clayton713b8d32019-12-17 20:37:56 +00002607#endif // ENABLE_RR_DEBUG_INFO
Nicolas Capens157ba262019-12-10 17:49:14 -05002608}
Nicolas Capens22479eb2016-09-28 22:34:26 -04002609
Nicolas Capens157ba262019-12-10 17:49:14 -05002610inline void Variable::materialize() const
2611{
2612 if(!address)
Nicolas Capens22479eb2016-09-28 22:34:26 -04002613 {
Nicolas Capens157ba262019-12-10 17:49:14 -05002614 address = Nucleus::allocateStackVariable(type, arraySize);
2615 RR_DEBUG_INFO_EMIT_VAR(address);
Nicolas Capens0192d152019-03-27 14:46:07 -04002616
Nicolas Capens0192d152019-03-27 14:46:07 -04002617 if(rvalue)
2618 {
Nicolas Capens157ba262019-12-10 17:49:14 -05002619 storeValue(rvalue);
2620 rvalue = nullptr;
Nicolas Capens0192d152019-03-27 14:46:07 -04002621 }
Nicolas Capens157ba262019-12-10 17:49:14 -05002622 }
2623}
Nicolas Capens0192d152019-03-27 14:46:07 -04002624
Nicolas Capens157ba262019-12-10 17:49:14 -05002625inline Value *Variable::loadValue() const
2626{
2627 if(rvalue)
2628 {
2629 return rvalue;
Nicolas Capens22479eb2016-09-28 22:34:26 -04002630 }
2631
Nicolas Capens157ba262019-12-10 17:49:14 -05002632 if(!address)
Nicolas Capens22479eb2016-09-28 22:34:26 -04002633 {
Nicolas Capens157ba262019-12-10 17:49:14 -05002634 // TODO: Return undef instead.
Nicolas Capens0192d152019-03-27 14:46:07 -04002635 materialize();
Nicolas Capens0192d152019-03-27 14:46:07 -04002636 }
2637
Nicolas Capens157ba262019-12-10 17:49:14 -05002638 return Nucleus::createLoad(address, type, false, 0);
2639}
2640
2641inline Value *Variable::storeValue(Value *value) const
2642{
2643 if(address)
Nicolas Capens0192d152019-03-27 14:46:07 -04002644 {
Nicolas Capens157ba262019-12-10 17:49:14 -05002645 return Nucleus::createStore(value, address, type, false, 0);
Nicolas Capens22479eb2016-09-28 22:34:26 -04002646 }
2647
Nicolas Capens157ba262019-12-10 17:49:14 -05002648 rvalue = value;
Nicolas Capensd022e412016-09-26 13:30:14 -04002649
Nicolas Capens157ba262019-12-10 17:49:14 -05002650 return value;
2651}
Nicolas Capensd022e412016-09-26 13:30:14 -04002652
Nicolas Capens157ba262019-12-10 17:49:14 -05002653inline Value *Variable::getBaseAddress() const
2654{
2655 materialize();
Nicolas Capensd022e412016-09-26 13:30:14 -04002656
Nicolas Capens157ba262019-12-10 17:49:14 -05002657 return address;
2658}
Nicolas Capensd022e412016-09-26 13:30:14 -04002659
Nicolas Capens157ba262019-12-10 17:49:14 -05002660inline Value *Variable::getElementPointer(Value *index, bool unsignedIndex) const
2661{
2662 return Nucleus::createGEP(getBaseAddress(), type, index, unsignedIndex);
2663}
Nicolas Capensd022e412016-09-26 13:30:14 -04002664
Nicolas Capens157ba262019-12-10 17:49:14 -05002665template<class T>
2666RValue<Pointer<T>> LValue<T>::operator&()
2667{
2668 return RValue<Pointer<T>>(getBaseAddress());
2669}
Nicolas Capensd022e412016-09-26 13:30:14 -04002670
Nicolas Capens157ba262019-12-10 17:49:14 -05002671template<class T>
Ben Clayton713b8d32019-12-17 20:37:56 +00002672Reference<T>::Reference(Value *pointer, int alignment)
2673 : alignment(alignment)
Nicolas Capens157ba262019-12-10 17:49:14 -05002674{
2675 address = pointer;
2676}
Nicolas Capensd022e412016-09-26 13:30:14 -04002677
Nicolas Capens157ba262019-12-10 17:49:14 -05002678template<class T>
2679RValue<T> Reference<T>::operator=(RValue<T> rhs) const
2680{
2681 Nucleus::createStore(rhs.value, address, T::getType(), false, alignment);
Nicolas Capensd022e412016-09-26 13:30:14 -04002682
Nicolas Capens157ba262019-12-10 17:49:14 -05002683 return rhs;
2684}
2685
2686template<class T>
2687RValue<T> Reference<T>::operator=(const Reference<T> &ref) const
2688{
2689 Value *tmp = Nucleus::createLoad(ref.address, T::getType(), false, ref.alignment);
2690 Nucleus::createStore(tmp, address, T::getType(), false, alignment);
2691
2692 return RValue<T>(tmp);
2693}
2694
2695template<class T>
2696RValue<T> Reference<T>::operator+=(RValue<T> rhs) const
2697{
2698 return *this = *this + rhs;
2699}
2700
2701template<class T>
2702Value *Reference<T>::loadValue() const
2703{
2704 return Nucleus::createLoad(address, T::getType(), false, alignment);
2705}
2706
2707template<class T>
2708int Reference<T>::getAlignment() const
2709{
2710 return alignment;
2711}
Nicolas Capensd022e412016-09-26 13:30:14 -04002712
Ben Claytonac07ed82019-03-26 14:17:41 +00002713#ifdef ENABLE_RR_DEBUG_INFO
Nicolas Capens157ba262019-12-10 17:49:14 -05002714template<class T>
Ben Clayton713b8d32019-12-17 20:37:56 +00002715RValue<T>::RValue(const RValue<T> &rvalue)
2716 : value(rvalue.value)
Nicolas Capens157ba262019-12-10 17:49:14 -05002717{
2718 RR_DEBUG_INFO_EMIT_VAR(value);
2719}
Ben Clayton713b8d32019-12-17 20:37:56 +00002720#endif // ENABLE_RR_DEBUG_INFO
Ben Claytonac07ed82019-03-26 14:17:41 +00002721
Nicolas Capens157ba262019-12-10 17:49:14 -05002722template<class T>
2723RValue<T>::RValue(Value *rvalue)
2724{
Ben Clayton713b8d32019-12-17 20:37:56 +00002725 assert(Nucleus::createBitCast(rvalue, T::getType()) == rvalue); // Run-time type should match T, so bitcast is no-op.
Nicolas Capensbea4dce2017-07-24 16:54:44 -04002726
Nicolas Capens157ba262019-12-10 17:49:14 -05002727 value = rvalue;
2728 RR_DEBUG_INFO_EMIT_VAR(value);
2729}
Nicolas Capensd022e412016-09-26 13:30:14 -04002730
Nicolas Capens157ba262019-12-10 17:49:14 -05002731template<class T>
2732RValue<T>::RValue(const T &lvalue)
2733{
2734 value = lvalue.loadValue();
2735 RR_DEBUG_INFO_EMIT_VAR(value);
2736}
Nicolas Capensd022e412016-09-26 13:30:14 -04002737
Nicolas Capens157ba262019-12-10 17:49:14 -05002738template<class T>
2739RValue<T>::RValue(typename BoolLiteral<T>::type i)
2740{
2741 value = Nucleus::createConstantBool(i);
2742 RR_DEBUG_INFO_EMIT_VAR(value);
2743}
Ben Clayton35e90e22019-03-15 10:06:06 +00002744
Nicolas Capens157ba262019-12-10 17:49:14 -05002745template<class T>
2746RValue<T>::RValue(typename IntLiteral<T>::type i)
2747{
2748 value = Nucleus::createConstantInt(i);
2749 RR_DEBUG_INFO_EMIT_VAR(value);
2750}
Nicolas Capensd022e412016-09-26 13:30:14 -04002751
Nicolas Capens157ba262019-12-10 17:49:14 -05002752template<class T>
2753RValue<T>::RValue(typename FloatLiteral<T>::type f)
2754{
2755 value = Nucleus::createConstantFloat(f);
2756 RR_DEBUG_INFO_EMIT_VAR(value);
2757}
Nicolas Capensd022e412016-09-26 13:30:14 -04002758
Nicolas Capens157ba262019-12-10 17:49:14 -05002759template<class T>
2760RValue<T>::RValue(const Reference<T> &ref)
2761{
2762 value = ref.loadValue();
2763 RR_DEBUG_INFO_EMIT_VAR(value);
2764}
Nicolas Capensd022e412016-09-26 13:30:14 -04002765
Nicolas Capens157ba262019-12-10 17:49:14 -05002766template<class Vector4, int T>
2767Swizzle2<Vector4, T>::operator RValue<Vector4>() const
2768{
2769 RR_DEBUG_INFO_UPDATE_LOC();
2770 Value *vector = parent->loadValue();
Nicolas Capensd022e412016-09-26 13:30:14 -04002771
Nicolas Capens157ba262019-12-10 17:49:14 -05002772 return Swizzle(RValue<Vector4>(vector), T);
2773}
Nicolas Capensd022e412016-09-26 13:30:14 -04002774
Nicolas Capens157ba262019-12-10 17:49:14 -05002775template<class Vector4, int T>
2776Swizzle4<Vector4, T>::operator RValue<Vector4>() const
2777{
2778 RR_DEBUG_INFO_UPDATE_LOC();
2779 Value *vector = parent->loadValue();
Nicolas Capensd022e412016-09-26 13:30:14 -04002780
Nicolas Capens157ba262019-12-10 17:49:14 -05002781 return Swizzle(RValue<Vector4>(vector), T);
2782}
Nicolas Capensd022e412016-09-26 13:30:14 -04002783
Nicolas Capens157ba262019-12-10 17:49:14 -05002784template<class Vector4, int T>
2785SwizzleMask4<Vector4, T>::operator RValue<Vector4>() const
2786{
2787 RR_DEBUG_INFO_UPDATE_LOC();
2788 Value *vector = parent->loadValue();
Nicolas Capensd022e412016-09-26 13:30:14 -04002789
Nicolas Capens157ba262019-12-10 17:49:14 -05002790 return Swizzle(RValue<Vector4>(vector), T);
2791}
Nicolas Capensd022e412016-09-26 13:30:14 -04002792
Nicolas Capens157ba262019-12-10 17:49:14 -05002793template<class Vector4, int T>
2794RValue<Vector4> SwizzleMask4<Vector4, T>::operator=(RValue<Vector4> rhs)
2795{
2796 RR_DEBUG_INFO_UPDATE_LOC();
2797 return Mask(*parent, rhs, T);
2798}
Nicolas Capensd022e412016-09-26 13:30:14 -04002799
Nicolas Capens157ba262019-12-10 17:49:14 -05002800template<class Vector4, int T>
2801RValue<Vector4> SwizzleMask4<Vector4, T>::operator=(RValue<typename Scalar<Vector4>::Type> rhs)
2802{
2803 RR_DEBUG_INFO_UPDATE_LOC();
2804 return Mask(*parent, Vector4(rhs), T);
2805}
Nicolas Capensd022e412016-09-26 13:30:14 -04002806
Nicolas Capens157ba262019-12-10 17:49:14 -05002807template<class Vector4, int T>
Ben Clayton713b8d32019-12-17 20:37:56 +00002808SwizzleMask1<Vector4, T>::operator RValue<typename Scalar<Vector4>::Type>() const // FIXME: Call a non-template function
Nicolas Capens157ba262019-12-10 17:49:14 -05002809{
2810 RR_DEBUG_INFO_UPDATE_LOC();
2811 return Extract(*parent, T & 0x3);
2812}
Nicolas Capensd022e412016-09-26 13:30:14 -04002813
Nicolas Capens157ba262019-12-10 17:49:14 -05002814template<class Vector4, int T>
2815SwizzleMask1<Vector4, T>::operator RValue<Vector4>() const
2816{
2817 RR_DEBUG_INFO_UPDATE_LOC();
2818 Value *vector = parent->loadValue();
Nicolas Capensd022e412016-09-26 13:30:14 -04002819
Nicolas Capens157ba262019-12-10 17:49:14 -05002820 return Swizzle(RValue<Vector4>(vector), T);
2821}
Nicolas Capensd022e412016-09-26 13:30:14 -04002822
Nicolas Capens157ba262019-12-10 17:49:14 -05002823template<class Vector4, int T>
2824RValue<Vector4> SwizzleMask1<Vector4, T>::operator=(float x)
2825{
2826 RR_DEBUG_INFO_UPDATE_LOC();
2827 return *parent = Insert(*parent, Float(x), T & 0x3);
2828}
Nicolas Capensd022e412016-09-26 13:30:14 -04002829
Nicolas Capens157ba262019-12-10 17:49:14 -05002830template<class Vector4, int T>
2831RValue<Vector4> SwizzleMask1<Vector4, T>::operator=(RValue<Vector4> rhs)
2832{
2833 RR_DEBUG_INFO_UPDATE_LOC();
2834 return Mask(*parent, Float4(rhs), T);
2835}
Nicolas Capensd022e412016-09-26 13:30:14 -04002836
Nicolas Capens157ba262019-12-10 17:49:14 -05002837template<class Vector4, int T>
Ben Clayton713b8d32019-12-17 20:37:56 +00002838RValue<Vector4> SwizzleMask1<Vector4, T>::operator=(RValue<typename Scalar<Vector4>::Type> rhs) // FIXME: Call a non-template function
Nicolas Capens157ba262019-12-10 17:49:14 -05002839{
2840 RR_DEBUG_INFO_UPDATE_LOC();
2841 return *parent = Insert(*parent, rhs, T & 0x3);
2842}
Nicolas Capensd022e412016-09-26 13:30:14 -04002843
Nicolas Capens157ba262019-12-10 17:49:14 -05002844template<class Vector4, int T>
2845SwizzleMask2<Vector4, T>::operator RValue<Vector4>() const
2846{
2847 RR_DEBUG_INFO_UPDATE_LOC();
2848 Value *vector = parent->loadValue();
Nicolas Capensd022e412016-09-26 13:30:14 -04002849
Nicolas Capens157ba262019-12-10 17:49:14 -05002850 return Swizzle(RValue<Float4>(vector), T);
2851}
Nicolas Capensd022e412016-09-26 13:30:14 -04002852
Nicolas Capens157ba262019-12-10 17:49:14 -05002853template<class Vector4, int T>
2854RValue<Vector4> SwizzleMask2<Vector4, T>::operator=(RValue<Vector4> rhs)
2855{
2856 RR_DEBUG_INFO_UPDATE_LOC();
2857 return Mask(*parent, Float4(rhs), T);
2858}
Nicolas Capensd022e412016-09-26 13:30:14 -04002859
Nicolas Capens157ba262019-12-10 17:49:14 -05002860template<int T>
2861Float::Float(const SwizzleMask1<Float4, T> &rhs)
2862{
2863 *this = rhs.operator RValue<Float>();
2864}
Nicolas Capensd022e412016-09-26 13:30:14 -04002865
Nicolas Capens157ba262019-12-10 17:49:14 -05002866template<int T>
2867RValue<Float> Float::operator=(const SwizzleMask1<Float4, T> &rhs)
2868{
2869 return *this = rhs.operator RValue<Float>();
2870}
Nicolas Capensd022e412016-09-26 13:30:14 -04002871
Nicolas Capens157ba262019-12-10 17:49:14 -05002872template<int T>
Ben Clayton713b8d32019-12-17 20:37:56 +00002873Float4::Float4(const SwizzleMask1<Float4, T> &rhs)
2874 : XYZW(this)
Nicolas Capens157ba262019-12-10 17:49:14 -05002875{
2876 *this = rhs.operator RValue<Float4>();
2877}
Nicolas Capensd022e412016-09-26 13:30:14 -04002878
Nicolas Capens157ba262019-12-10 17:49:14 -05002879template<int T>
Ben Clayton713b8d32019-12-17 20:37:56 +00002880Float4::Float4(const Swizzle4<Float4, T> &rhs)
2881 : XYZW(this)
Nicolas Capens157ba262019-12-10 17:49:14 -05002882{
2883 *this = rhs.operator RValue<Float4>();
2884}
Nicolas Capensd022e412016-09-26 13:30:14 -04002885
Nicolas Capens157ba262019-12-10 17:49:14 -05002886template<int X, int Y>
Ben Clayton713b8d32019-12-17 20:37:56 +00002887Float4::Float4(const Swizzle2<Float4, X> &x, const Swizzle2<Float4, Y> &y)
2888 : XYZW(this)
Nicolas Capens157ba262019-12-10 17:49:14 -05002889{
2890 RR_DEBUG_INFO_UPDATE_LOC();
2891 *this = ShuffleLowHigh(*x.parent, *y.parent, (uint16_t(X) & 0xFF00u) | (uint16_t(Y >> 8) & 0x00FFu));
2892}
Nicolas Capensd022e412016-09-26 13:30:14 -04002893
Nicolas Capens157ba262019-12-10 17:49:14 -05002894template<int X, int Y>
Ben Clayton713b8d32019-12-17 20:37:56 +00002895Float4::Float4(const SwizzleMask2<Float4, X> &x, const Swizzle2<Float4, Y> &y)
2896 : XYZW(this)
Nicolas Capens157ba262019-12-10 17:49:14 -05002897{
2898 RR_DEBUG_INFO_UPDATE_LOC();
2899 *this = ShuffleLowHigh(*x.parent, *y.parent, (uint16_t(X) & 0xFF00u) | (uint16_t(Y >> 8) & 0x00FFu));
2900}
Nicolas Capensd022e412016-09-26 13:30:14 -04002901
Nicolas Capens157ba262019-12-10 17:49:14 -05002902template<int X, int Y>
Ben Clayton713b8d32019-12-17 20:37:56 +00002903Float4::Float4(const Swizzle2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y)
2904 : XYZW(this)
Nicolas Capens157ba262019-12-10 17:49:14 -05002905{
2906 RR_DEBUG_INFO_UPDATE_LOC();
2907 *this = ShuffleLowHigh(*x.parent, *y.parent, (uint16_t(X) & 0xFF00u) | (uint16_t(Y >> 8) & 0x00FFu));
2908}
Nicolas Capensd022e412016-09-26 13:30:14 -04002909
Nicolas Capens157ba262019-12-10 17:49:14 -05002910template<int X, int Y>
Ben Clayton713b8d32019-12-17 20:37:56 +00002911Float4::Float4(const SwizzleMask2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y)
2912 : XYZW(this)
Nicolas Capens157ba262019-12-10 17:49:14 -05002913{
2914 RR_DEBUG_INFO_UPDATE_LOC();
2915 *this = ShuffleLowHigh(*x.parent, *y.parent, (uint16_t(X) & 0xFF00u) | (uint16_t(Y >> 8) & 0x00FFu));
2916}
Nicolas Capensd022e412016-09-26 13:30:14 -04002917
Nicolas Capens157ba262019-12-10 17:49:14 -05002918template<int T>
2919RValue<Float4> Float4::operator=(const SwizzleMask1<Float4, T> &rhs)
2920{
2921 return *this = rhs.operator RValue<Float4>();
2922}
Nicolas Capensd022e412016-09-26 13:30:14 -04002923
Nicolas Capens157ba262019-12-10 17:49:14 -05002924template<int T>
2925RValue<Float4> Float4::operator=(const Swizzle4<Float4, T> &rhs)
2926{
2927 return *this = rhs.operator RValue<Float4>();
2928}
Nicolas Capensd022e412016-09-26 13:30:14 -04002929
Nicolas Capens157ba262019-12-10 17:49:14 -05002930// Returns a reactor pointer to the fixed-address ptr.
Ben Clayton713b8d32019-12-17 20:37:56 +00002931RValue<Pointer<Byte>> ConstantPointer(void const *ptr);
Ben Claytonb7eb3a82019-11-19 00:43:50 +00002932
Nicolas Capens157ba262019-12-10 17:49:14 -05002933// Returns a reactor pointer to an immutable copy of the data of size bytes.
Ben Clayton713b8d32019-12-17 20:37:56 +00002934RValue<Pointer<Byte>> ConstantData(void const *data, size_t size);
Ben Claytonb7eb3a82019-11-19 00:43:50 +00002935
Nicolas Capens157ba262019-12-10 17:49:14 -05002936template<class T>
Ben Clayton713b8d32019-12-17 20:37:56 +00002937Pointer<T>::Pointer(Argument<Pointer<T>> argument)
2938 : alignment(1)
Nicolas Capens157ba262019-12-10 17:49:14 -05002939{
2940 LValue<Pointer<T>>::storeValue(argument.value);
2941}
Nicolas Capensd022e412016-09-26 13:30:14 -04002942
Nicolas Capens157ba262019-12-10 17:49:14 -05002943template<class T>
Ben Clayton713b8d32019-12-17 20:37:56 +00002944Pointer<T>::Pointer()
2945 : alignment(1)
2946{}
Nicolas Capensd022e412016-09-26 13:30:14 -04002947
Nicolas Capens157ba262019-12-10 17:49:14 -05002948template<class T>
Ben Clayton713b8d32019-12-17 20:37:56 +00002949Pointer<T>::Pointer(RValue<Pointer<T>> rhs)
2950 : alignment(1)
Nicolas Capens157ba262019-12-10 17:49:14 -05002951{
2952 LValue<Pointer<T>>::storeValue(rhs.value);
2953}
Nicolas Capensd022e412016-09-26 13:30:14 -04002954
Nicolas Capens157ba262019-12-10 17:49:14 -05002955template<class T>
Ben Clayton713b8d32019-12-17 20:37:56 +00002956Pointer<T>::Pointer(const Pointer<T> &rhs)
2957 : alignment(rhs.alignment)
Nicolas Capens157ba262019-12-10 17:49:14 -05002958{
2959 Value *value = rhs.loadValue();
2960 LValue<Pointer<T>>::storeValue(value);
2961}
Nicolas Capensd022e412016-09-26 13:30:14 -04002962
Nicolas Capens157ba262019-12-10 17:49:14 -05002963template<class T>
Ben Clayton713b8d32019-12-17 20:37:56 +00002964Pointer<T>::Pointer(const Reference<Pointer<T>> &rhs)
2965 : alignment(rhs.getAlignment())
Nicolas Capens157ba262019-12-10 17:49:14 -05002966{
2967 Value *value = rhs.loadValue();
2968 LValue<Pointer<T>>::storeValue(value);
2969}
Nicolas Capensd022e412016-09-26 13:30:14 -04002970
Nicolas Capens157ba262019-12-10 17:49:14 -05002971template<class T>
Ben Clayton713b8d32019-12-17 20:37:56 +00002972Pointer<T>::Pointer(std::nullptr_t)
2973 : alignment(1)
Nicolas Capens157ba262019-12-10 17:49:14 -05002974{
2975 Value *value = Nucleus::createNullPointer(T::getType());
2976 LValue<Pointer<T>>::storeValue(value);
2977}
Ben Clayton0697da02019-08-01 13:35:48 +01002978
Nicolas Capens157ba262019-12-10 17:49:14 -05002979template<class T>
2980RValue<Pointer<T>> Pointer<T>::operator=(RValue<Pointer<T>> rhs)
2981{
2982 LValue<Pointer<T>>::storeValue(rhs.value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002983
Nicolas Capens157ba262019-12-10 17:49:14 -05002984 return rhs;
2985}
Nicolas Capensd022e412016-09-26 13:30:14 -04002986
Nicolas Capens157ba262019-12-10 17:49:14 -05002987template<class T>
2988RValue<Pointer<T>> Pointer<T>::operator=(const Pointer<T> &rhs)
2989{
2990 Value *value = rhs.loadValue();
2991 LValue<Pointer<T>>::storeValue(value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002992
Nicolas Capens157ba262019-12-10 17:49:14 -05002993 return RValue<Pointer<T>>(value);
2994}
Nicolas Capensd022e412016-09-26 13:30:14 -04002995
Nicolas Capens157ba262019-12-10 17:49:14 -05002996template<class T>
2997RValue<Pointer<T>> Pointer<T>::operator=(const Reference<Pointer<T>> &rhs)
2998{
2999 Value *value = rhs.loadValue();
3000 LValue<Pointer<T>>::storeValue(value);
Nicolas Capensd022e412016-09-26 13:30:14 -04003001
Nicolas Capens157ba262019-12-10 17:49:14 -05003002 return RValue<Pointer<T>>(value);
3003}
Nicolas Capensd022e412016-09-26 13:30:14 -04003004
Nicolas Capens157ba262019-12-10 17:49:14 -05003005template<class T>
3006RValue<Pointer<T>> Pointer<T>::operator=(std::nullptr_t)
3007{
3008 Value *value = Nucleus::createNullPointer(T::getType());
3009 LValue<Pointer<T>>::storeValue(value);
Ben Clayton0697da02019-08-01 13:35:48 +01003010
Nicolas Capens157ba262019-12-10 17:49:14 -05003011 return RValue<Pointer<T>>(this);
3012}
Ben Clayton0697da02019-08-01 13:35:48 +01003013
Nicolas Capens157ba262019-12-10 17:49:14 -05003014template<class T>
3015Reference<T> Pointer<T>::operator*()
3016{
3017 return Reference<T>(LValue<Pointer<T>>::loadValue(), alignment);
3018}
Nicolas Capensd022e412016-09-26 13:30:14 -04003019
Nicolas Capens157ba262019-12-10 17:49:14 -05003020template<class T>
3021Reference<T> Pointer<T>::operator[](int index)
3022{
3023 RR_DEBUG_INFO_UPDATE_LOC();
3024 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), Nucleus::createConstantInt(index), false);
Nicolas Capensd294def2017-01-26 17:44:37 -08003025
Nicolas Capens157ba262019-12-10 17:49:14 -05003026 return Reference<T>(element, alignment);
3027}
Nicolas Capensd294def2017-01-26 17:44:37 -08003028
Nicolas Capens157ba262019-12-10 17:49:14 -05003029template<class T>
3030Reference<T> Pointer<T>::operator[](unsigned int index)
3031{
3032 RR_DEBUG_INFO_UPDATE_LOC();
3033 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), Nucleus::createConstantInt(index), true);
Nicolas Capensd022e412016-09-26 13:30:14 -04003034
Nicolas Capens157ba262019-12-10 17:49:14 -05003035 return Reference<T>(element, alignment);
3036}
Nicolas Capensd022e412016-09-26 13:30:14 -04003037
Nicolas Capens157ba262019-12-10 17:49:14 -05003038template<class T>
3039Reference<T> Pointer<T>::operator[](RValue<Int> index)
3040{
3041 RR_DEBUG_INFO_UPDATE_LOC();
3042 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), index.value, false);
Nicolas Capensd294def2017-01-26 17:44:37 -08003043
Nicolas Capens157ba262019-12-10 17:49:14 -05003044 return Reference<T>(element, alignment);
3045}
Nicolas Capensd294def2017-01-26 17:44:37 -08003046
Nicolas Capens157ba262019-12-10 17:49:14 -05003047template<class T>
3048Reference<T> Pointer<T>::operator[](RValue<UInt> index)
3049{
3050 RR_DEBUG_INFO_UPDATE_LOC();
3051 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), index.value, true);
Nicolas Capensd022e412016-09-26 13:30:14 -04003052
Nicolas Capens157ba262019-12-10 17:49:14 -05003053 return Reference<T>(element, alignment);
3054}
Nicolas Capensd022e412016-09-26 13:30:14 -04003055
Nicolas Capens157ba262019-12-10 17:49:14 -05003056template<class T>
3057Type *Pointer<T>::getType()
3058{
3059 return Nucleus::getPointerType(T::getType());
3060}
Nicolas Capensd022e412016-09-26 13:30:14 -04003061
Nicolas Capens157ba262019-12-10 17:49:14 -05003062template<class T, int S>
Ben Clayton713b8d32019-12-17 20:37:56 +00003063Array<T, S>::Array(int size)
3064 : LValue<T>(size)
Nicolas Capens157ba262019-12-10 17:49:14 -05003065{
3066}
Nicolas Capensd022e412016-09-26 13:30:14 -04003067
Nicolas Capens157ba262019-12-10 17:49:14 -05003068template<class T, int S>
3069Reference<T> Array<T, S>::operator[](int index)
3070{
3071 assert(index < this->arraySize);
3072 Value *element = LValue<T>::getElementPointer(Nucleus::createConstantInt(index), false);
Nicolas Capensd294def2017-01-26 17:44:37 -08003073
Nicolas Capens157ba262019-12-10 17:49:14 -05003074 return Reference<T>(element);
3075}
Nicolas Capensd294def2017-01-26 17:44:37 -08003076
Nicolas Capens157ba262019-12-10 17:49:14 -05003077template<class T, int S>
3078Reference<T> Array<T, S>::operator[](unsigned int index)
3079{
3080 assert(index < static_cast<unsigned int>(this->arraySize));
3081 Value *element = LValue<T>::getElementPointer(Nucleus::createConstantInt(index), true);
Nicolas Capensd022e412016-09-26 13:30:14 -04003082
Nicolas Capens157ba262019-12-10 17:49:14 -05003083 return Reference<T>(element);
3084}
Nicolas Capensd022e412016-09-26 13:30:14 -04003085
Nicolas Capens157ba262019-12-10 17:49:14 -05003086template<class T, int S>
3087Reference<T> Array<T, S>::operator[](RValue<Int> index)
3088{
3089 Value *element = LValue<T>::getElementPointer(index.value, false);
Nicolas Capensd294def2017-01-26 17:44:37 -08003090
Nicolas Capens157ba262019-12-10 17:49:14 -05003091 return Reference<T>(element);
3092}
Nicolas Capensd294def2017-01-26 17:44:37 -08003093
Nicolas Capens157ba262019-12-10 17:49:14 -05003094template<class T, int S>
3095Reference<T> Array<T, S>::operator[](RValue<UInt> index)
3096{
3097 Value *element = LValue<T>::getElementPointer(index.value, true);
Nicolas Capensd022e412016-09-26 13:30:14 -04003098
Nicolas Capens157ba262019-12-10 17:49:14 -05003099 return Reference<T>(element);
3100}
Nicolas Capensd022e412016-09-26 13:30:14 -04003101
3102// template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05003103// RValue<Array<T>> operator++(Array<T> &val, int)
Nicolas Capensd022e412016-09-26 13:30:14 -04003104// {
3105// // FIXME: Requires storing the address of the array
3106// }
3107
3108// template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05003109// const Array<T> &operator++(Array<T> &val)
Nicolas Capensd022e412016-09-26 13:30:14 -04003110// {
3111// // FIXME: Requires storing the address of the array
3112// }
3113
3114// template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05003115// RValue<Array<T>> operator--(Array<T> &val, int)
Nicolas Capensd022e412016-09-26 13:30:14 -04003116// {
3117// // FIXME: Requires storing the address of the array
3118// }
3119
3120// template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05003121// const Array<T> &operator--(Array<T> &val)
Nicolas Capensd022e412016-09-26 13:30:14 -04003122// {
3123// // FIXME: Requires storing the address of the array
3124// }
3125
Nicolas Capens157ba262019-12-10 17:49:14 -05003126template<class T>
3127RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, RValue<T> ifFalse)
3128{
3129 RR_DEBUG_INFO_UPDATE_LOC();
3130 return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, ifFalse.value));
3131}
3132
3133template<class T>
3134RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, RValue<T> ifFalse)
3135{
3136 RR_DEBUG_INFO_UPDATE_LOC();
3137 Value *trueValue = ifTrue.loadValue();
3138
3139 return RValue<T>(Nucleus::createSelect(condition.value, trueValue, ifFalse.value));
3140}
3141
3142template<class T>
3143RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, const T &ifFalse)
3144{
3145 RR_DEBUG_INFO_UPDATE_LOC();
3146 Value *falseValue = ifFalse.loadValue();
3147
3148 return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, falseValue));
3149}
3150
3151template<class T>
3152RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, const T &ifFalse)
3153{
3154 RR_DEBUG_INFO_UPDATE_LOC();
3155 Value *trueValue = ifTrue.loadValue();
3156 Value *falseValue = ifFalse.loadValue();
3157
3158 return RValue<T>(Nucleus::createSelect(condition.value, trueValue, falseValue));
3159}
3160
3161template<typename Return, typename... Arguments>
3162Function<Return(Arguments...)>::Function()
3163{
3164 core = new Nucleus();
3165
Ben Clayton713b8d32019-12-17 20:37:56 +00003166 Type *types[] = { Arguments::getType()... };
Nicolas Capens157ba262019-12-10 17:49:14 -05003167 for(Type *type : types)
Nicolas Capensd022e412016-09-26 13:30:14 -04003168 {
Nicolas Capens157ba262019-12-10 17:49:14 -05003169 if(type != Void::getType())
Nicolas Capensd022e412016-09-26 13:30:14 -04003170 {
Nicolas Capens157ba262019-12-10 17:49:14 -05003171 arguments.push_back(type);
Nicolas Capensd022e412016-09-26 13:30:14 -04003172 }
Nicolas Capensd022e412016-09-26 13:30:14 -04003173 }
3174
Nicolas Capens157ba262019-12-10 17:49:14 -05003175 Nucleus::createFunction(Return::getType(), arguments);
3176}
3177
3178template<typename Return, typename... Arguments>
3179Function<Return(Arguments...)>::~Function()
3180{
3181 delete core;
3182}
3183
3184template<typename Return, typename... Arguments>
3185std::shared_ptr<Routine> Function<Return(Arguments...)>::operator()(const char *name, ...)
3186{
3187 char fullName[1024 + 1];
3188
3189 va_list vararg;
3190 va_start(vararg, name);
3191 vsnprintf(fullName, 1024, name, vararg);
3192 va_end(vararg);
3193
3194 return core->acquireRoutine(fullName, Config::Edit::None);
3195}
3196
3197template<typename Return, typename... Arguments>
3198std::shared_ptr<Routine> Function<Return(Arguments...)>::operator()(const Config::Edit &cfg, const char *name, ...)
3199{
3200 char fullName[1024 + 1];
3201
3202 va_list vararg;
3203 va_start(vararg, name);
3204 vsnprintf(fullName, 1024, name, vararg);
3205 va_end(vararg);
3206
3207 return core->acquireRoutine(fullName, cfg);
3208}
3209
3210template<class T, class S>
3211RValue<T> ReinterpretCast(RValue<S> val)
3212{
3213 RR_DEBUG_INFO_UPDATE_LOC();
3214 return RValue<T>(Nucleus::createBitCast(val.value, T::getType()));
3215}
3216
3217template<class T, class S>
3218RValue<T> ReinterpretCast(const LValue<S> &var)
3219{
3220 RR_DEBUG_INFO_UPDATE_LOC();
3221 Value *val = var.loadValue();
3222
3223 return RValue<T>(Nucleus::createBitCast(val, T::getType()));
3224}
3225
3226template<class T, class S>
3227RValue<T> ReinterpretCast(const Reference<S> &var)
3228{
3229 return ReinterpretCast<T>(RValue<S>(var));
3230}
3231
3232template<class T>
3233RValue<T> As(Value *val)
3234{
3235 RR_DEBUG_INFO_UPDATE_LOC();
3236 return RValue<T>(Nucleus::createBitCast(val, T::getType()));
3237}
3238
3239template<class T, class S>
3240RValue<T> As(RValue<S> val)
3241{
3242 return ReinterpretCast<T>(val);
3243}
3244
3245template<class T, class S>
3246RValue<T> As(const LValue<S> &var)
3247{
3248 return ReinterpretCast<T>(var);
3249}
3250
3251template<class T, class S>
3252RValue<T> As(const Reference<S> &val)
3253{
3254 return ReinterpretCast<T>(val);
3255}
3256
3257// Calls the function pointer fptr with the given arguments, return type
3258// and parameter types. Returns the call's return value if the function has
3259// a non-void return type.
Ben Clayton713b8d32019-12-17 20:37:56 +00003260Value *Call(RValue<Pointer<Byte>> fptr, Type *retTy, std::initializer_list<Value *> args, std::initializer_list<Type *> paramTys);
Nicolas Capens157ba262019-12-10 17:49:14 -05003261
Ben Clayton713b8d32019-12-17 20:37:56 +00003262template<typename F>
3263class CallHelper
3264{};
Nicolas Capens157ba262019-12-10 17:49:14 -05003265
Ben Clayton713b8d32019-12-17 20:37:56 +00003266template<typename Return, typename... Arguments>
Nicolas Capens157ba262019-12-10 17:49:14 -05003267class CallHelper<Return(Arguments...)>
3268{
3269public:
3270 using RReturn = CToReactorT<Return>;
3271
3272 static inline RReturn Call(Return(fptr)(Arguments...), CToReactorT<Arguments>... args)
Nicolas Capensd022e412016-09-26 13:30:14 -04003273 {
Nicolas Capens157ba262019-12-10 17:49:14 -05003274 return RValue<RReturn>(rr::Call(
Ben Clayton713b8d32019-12-17 20:37:56 +00003275 ConstantPointer(reinterpret_cast<void *>(fptr)),
3276 RReturn::getType(),
3277 { ValueOf(args)... },
3278 { CToReactorT<Arguments>::getType()... }));
Nicolas Capensd022e412016-09-26 13:30:14 -04003279 }
3280
Nicolas Capens157ba262019-12-10 17:49:14 -05003281 static inline RReturn Call(Pointer<Byte> fptr, CToReactorT<Arguments>... args)
Nicolas Capensd022e412016-09-26 13:30:14 -04003282 {
Nicolas Capens157ba262019-12-10 17:49:14 -05003283 return RValue<RReturn>(rr::Call(
Ben Clayton713b8d32019-12-17 20:37:56 +00003284 fptr,
3285 RReturn::getType(),
3286 { ValueOf(args)... },
3287 { CToReactorT<Arguments>::getType()... }));
Nicolas Capens157ba262019-12-10 17:49:14 -05003288 }
3289};
Nicolas Capensd022e412016-09-26 13:30:14 -04003290
Ben Clayton713b8d32019-12-17 20:37:56 +00003291template<typename... Arguments>
Nicolas Capens157ba262019-12-10 17:49:14 -05003292class CallHelper<void(Arguments...)>
3293{
3294public:
3295 static inline void Call(void(fptr)(Arguments...), CToReactorT<Arguments>... args)
3296 {
Ben Clayton713b8d32019-12-17 20:37:56 +00003297 rr::Call(ConstantPointer(reinterpret_cast<void *>(fptr)),
3298 Void::getType(),
3299 { ValueOf(args)... },
3300 { CToReactorT<Arguments>::getType()... });
Ben Clayton68cfc782019-06-29 12:31:08 +01003301 }
3302
Nicolas Capens157ba262019-12-10 17:49:14 -05003303 static inline void Call(Pointer<Byte> fptr, CToReactorT<Arguments>... args)
Ben Clayton68cfc782019-06-29 12:31:08 +01003304 {
Nicolas Capens157ba262019-12-10 17:49:14 -05003305 rr::Call(fptr,
Ben Clayton713b8d32019-12-17 20:37:56 +00003306 Void::getType(),
3307 { ValueOf(args)... },
3308 { CToReactorT<Arguments>::getType()... });
Nicolas Capensd022e412016-09-26 13:30:14 -04003309 }
Nicolas Capens157ba262019-12-10 17:49:14 -05003310};
Nicolas Capensd022e412016-09-26 13:30:14 -04003311
Ben Clayton713b8d32019-12-17 20:37:56 +00003312template<typename T>
3313inline ReactorTypeT<T> CastToReactor(const T &v)
3314{
3315 return ReactorType<T>::cast(v);
3316}
Nicolas Capens157ba262019-12-10 17:49:14 -05003317
3318// Calls the static function pointer fptr with the given arguments args.
Ben Clayton713b8d32019-12-17 20:37:56 +00003319template<typename Return, typename... CArgs, typename... RArgs>
3320inline CToReactorT<Return> Call(Return(fptr)(CArgs...), RArgs &&... args)
Nicolas Capens157ba262019-12-10 17:49:14 -05003321{
3322 return CallHelper<Return(CArgs...)>::Call(fptr, CastToReactor(std::forward<RArgs>(args))...);
3323}
3324
3325// Calls the static function pointer fptr with the given arguments args.
3326// Overload for calling functions with void return type.
Ben Clayton713b8d32019-12-17 20:37:56 +00003327template<typename... CArgs, typename... RArgs>
3328inline void Call(void(fptr)(CArgs...), RArgs &&... args)
Nicolas Capens157ba262019-12-10 17:49:14 -05003329{
3330 CallHelper<void(CArgs...)>::Call(fptr, CastToReactor(std::forward<RArgs>(args))...);
3331}
3332
3333// Calls the member function pointer fptr with the given arguments args.
3334// object can be a Class*, or a Pointer<Byte>.
Ben Clayton713b8d32019-12-17 20:37:56 +00003335template<typename Return, typename Class, typename C, typename... CArgs, typename... RArgs>
3336inline CToReactorT<Return> Call(Return (Class::*fptr)(CArgs...), C &&object, RArgs &&... args)
Nicolas Capens157ba262019-12-10 17:49:14 -05003337{
Ben Clayton713b8d32019-12-17 20:37:56 +00003338 using Helper = CallHelper<Return(Class *, void *, CArgs...)>;
Nicolas Capens157ba262019-12-10 17:49:14 -05003339 using fptrTy = decltype(fptr);
3340
3341 struct Static
Nicolas Capensd022e412016-09-26 13:30:14 -04003342 {
Ben Clayton713b8d32019-12-17 20:37:56 +00003343 static inline Return Call(Class *object, void *fptrptr, CArgs... args)
Ben Claytond853c122019-04-16 17:51:49 -04003344 {
Ben Clayton713b8d32019-12-17 20:37:56 +00003345 auto fptr = *reinterpret_cast<fptrTy *>(fptrptr);
Nicolas Capens157ba262019-12-10 17:49:14 -05003346 return (object->*fptr)(std::forward<CArgs>(args)...);
Ben Claytond853c122019-04-16 17:51:49 -04003347 }
3348 };
3349
Nicolas Capens157ba262019-12-10 17:49:14 -05003350 return Helper::Call(&Static::Call,
3351 CastToReactor(object),
3352 ConstantData(&fptr, sizeof(fptr)),
3353 CastToReactor(std::forward<RArgs>(args))...);
3354}
Ben Claytond853c122019-04-16 17:51:49 -04003355
Nicolas Capens157ba262019-12-10 17:49:14 -05003356// Calls the member function pointer fptr with the given arguments args.
3357// Overload for calling functions with void return type.
3358// object can be a Class*, or a Pointer<Byte>.
Ben Clayton713b8d32019-12-17 20:37:56 +00003359template<typename Class, typename C, typename... CArgs, typename... RArgs>
3360inline void Call(void (Class::*fptr)(CArgs...), C &&object, RArgs &&... args)
Nicolas Capens157ba262019-12-10 17:49:14 -05003361{
Ben Clayton713b8d32019-12-17 20:37:56 +00003362 using Helper = CallHelper<void(Class *, void *, CArgs...)>;
Nicolas Capens157ba262019-12-10 17:49:14 -05003363 using fptrTy = decltype(fptr);
3364
3365 struct Static
3366 {
Ben Clayton713b8d32019-12-17 20:37:56 +00003367 static inline void Call(Class *object, void *fptrptr, CArgs... args)
Ben Claytond853c122019-04-16 17:51:49 -04003368 {
Ben Clayton713b8d32019-12-17 20:37:56 +00003369 auto fptr = *reinterpret_cast<fptrTy *>(fptrptr);
Nicolas Capens157ba262019-12-10 17:49:14 -05003370 (object->*fptr)(std::forward<CArgs>(args)...);
Ben Claytond853c122019-04-16 17:51:49 -04003371 }
3372 };
3373
Nicolas Capens157ba262019-12-10 17:49:14 -05003374 Helper::Call(&Static::Call,
3375 CastToReactor(object),
3376 ConstantData(&fptr, sizeof(fptr)),
3377 CastToReactor(std::forward<RArgs>(args))...);
3378}
Ben Clayton51f08312019-11-08 14:39:26 +00003379
Nicolas Capens157ba262019-12-10 17:49:14 -05003380// Calls the Reactor function pointer fptr with the signature
3381// FUNCTION_SIGNATURE and arguments.
Ben Clayton713b8d32019-12-17 20:37:56 +00003382template<typename FUNCTION_SIGNATURE, typename... RArgs>
3383inline void Call(Pointer<Byte> fptr, RArgs &&... args)
Nicolas Capens157ba262019-12-10 17:49:14 -05003384{
3385 CallHelper<FUNCTION_SIGNATURE>::Call(fptr, CastToReactor(std::forward<RArgs>(args))...);
3386}
3387
3388// Breakpoint emits an instruction that will cause the application to trap.
3389// This can be used to stop an attached debugger at the given call.
3390void Breakpoint();
3391
3392class ForData
3393{
3394public:
Ben Clayton713b8d32019-12-17 20:37:56 +00003395 ForData(bool init)
3396 : loopOnce(init)
Ben Claytond853c122019-04-16 17:51:49 -04003397 {
Ben Claytond853c122019-04-16 17:51:49 -04003398 }
3399
Nicolas Capens157ba262019-12-10 17:49:14 -05003400 operator bool()
Antonio Maiorano7363cd22019-10-11 15:23:22 -04003401 {
Nicolas Capens157ba262019-12-10 17:49:14 -05003402 return loopOnce;
Antonio Maiorano7363cd22019-10-11 15:23:22 -04003403 }
3404
Nicolas Capens157ba262019-12-10 17:49:14 -05003405 bool operator=(bool value)
Ben Claytonb7eb3a82019-11-19 00:43:50 +00003406 {
Nicolas Capens157ba262019-12-10 17:49:14 -05003407 return loopOnce = value;
Ben Claytonb7eb3a82019-11-19 00:43:50 +00003408 }
3409
Nicolas Capens157ba262019-12-10 17:49:14 -05003410 bool setup()
Ben Claytonb7eb3a82019-11-19 00:43:50 +00003411 {
Nicolas Capens157ba262019-12-10 17:49:14 -05003412 RR_DEBUG_INFO_FLUSH();
3413 if(Nucleus::getInsertBlock() != endBB)
Nicolas Capens37ed9082016-11-16 17:40:48 -05003414 {
Nicolas Capens157ba262019-12-10 17:49:14 -05003415 testBB = Nucleus::createBasicBlock();
Nicolas Capens37ed9082016-11-16 17:40:48 -05003416
Nicolas Capens157ba262019-12-10 17:49:14 -05003417 Nucleus::createBr(testBB);
3418 Nucleus::setInsertBlock(testBB);
Nicolas Capens37ed9082016-11-16 17:40:48 -05003419
3420 return true;
3421 }
3422
Nicolas Capens157ba262019-12-10 17:49:14 -05003423 return false;
Nicolas Capens0bac2852016-05-07 06:09:58 -04003424 }
3425
Nicolas Capens157ba262019-12-10 17:49:14 -05003426 bool test(RValue<Bool> cmp)
3427 {
3428 BasicBlock *bodyBB = Nucleus::createBasicBlock();
3429 endBB = Nucleus::createBasicBlock();
Nicolas Capens0bac2852016-05-07 06:09:58 -04003430
Nicolas Capens157ba262019-12-10 17:49:14 -05003431 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
3432 Nucleus::setInsertBlock(bodyBB);
Nicolas Capens37ed9082016-11-16 17:40:48 -05003433
Nicolas Capens157ba262019-12-10 17:49:14 -05003434 return true;
3435 }
3436
3437 void end()
3438 {
3439 Nucleus::createBr(testBB);
3440 Nucleus::setInsertBlock(endBB);
3441 }
3442
3443private:
3444 BasicBlock *testBB = nullptr;
3445 BasicBlock *endBB = nullptr;
3446 bool loopOnce = true;
3447};
3448
3449class IfElseData
3450{
3451public:
Ben Clayton713b8d32019-12-17 20:37:56 +00003452 IfElseData(RValue<Bool> cmp)
3453 : iteration(0)
Nicolas Capens157ba262019-12-10 17:49:14 -05003454 {
3455 condition = cmp.value;
3456
3457 beginBB = Nucleus::getInsertBlock();
3458 trueBB = Nucleus::createBasicBlock();
3459 falseBB = nullptr;
3460 endBB = Nucleus::createBasicBlock();
3461
3462 Nucleus::setInsertBlock(trueBB);
3463 }
3464
3465 ~IfElseData()
3466 {
3467 Nucleus::createBr(endBB);
3468
3469 Nucleus::setInsertBlock(beginBB);
3470 Nucleus::createCondBr(condition, trueBB, falseBB ? falseBB : endBB);
3471
3472 Nucleus::setInsertBlock(endBB);
3473 }
3474
3475 operator int()
3476 {
3477 return iteration;
3478 }
3479
3480 IfElseData &operator++()
3481 {
3482 ++iteration;
3483
3484 return *this;
3485 }
3486
3487 void elseClause()
3488 {
3489 Nucleus::createBr(endBB);
3490
3491 falseBB = Nucleus::createBasicBlock();
3492 Nucleus::setInsertBlock(falseBB);
3493 }
3494
3495private:
3496 Value *condition;
3497 BasicBlock *beginBB;
3498 BasicBlock *trueBB;
3499 BasicBlock *falseBB;
3500 BasicBlock *endBB;
3501 int iteration;
3502};
3503
Ben Clayton713b8d32019-12-17 20:37:56 +00003504#define For(init, cond, inc) \
3505 for(ForData for__ = true; for__; for__ = false) \
3506 for(init; for__.setup() && for__.test(cond); inc, for__.end())
Nicolas Capens157ba262019-12-10 17:49:14 -05003507
3508#define While(cond) For((void)0, cond, (void)0)
3509
Ben Clayton713b8d32019-12-17 20:37:56 +00003510#define Do \
3511 { \
3512 BasicBlock *body__ = Nucleus::createBasicBlock(); \
3513 Nucleus::createBr(body__); \
3514 Nucleus::setInsertBlock(body__);
Nicolas Capens157ba262019-12-10 17:49:14 -05003515
3516#define Until(cond) \
3517 BasicBlock *end__ = Nucleus::createBasicBlock(); \
3518 Nucleus::createCondBr((cond).value, end__, body__); \
3519 Nucleus::setInsertBlock(end__); \
Ben Clayton713b8d32019-12-17 20:37:56 +00003520 } \
3521 do \
3522 { \
3523 } while(false) // Require a semi-colon at the end of the Until()
Nicolas Capensd022e412016-09-26 13:30:14 -04003524
Ben Clayton713b8d32019-12-17 20:37:56 +00003525enum
3526{
3527 IF_BLOCK__,
3528 ELSE_CLAUSE__,
3529 ELSE_BLOCK__,
3530 IFELSE_NUM__
3531};
Nicolas Capens157ba262019-12-10 17:49:14 -05003532
Ben Clayton713b8d32019-12-17 20:37:56 +00003533#define If(cond) \
3534 for(IfElseData ifElse__(cond); ifElse__ < IFELSE_NUM__; ++ifElse__) \
3535 if(ifElse__ == IF_BLOCK__)
Nicolas Capens157ba262019-12-10 17:49:14 -05003536
Ben Clayton713b8d32019-12-17 20:37:56 +00003537#define Else \
3538 else if(ifElse__ == ELSE_CLAUSE__) \
3539 { \
3540 ifElse__.elseClause(); \
3541 } \
3542 else // ELSE_BLOCK__
Nicolas Capens157ba262019-12-10 17:49:14 -05003543
3544} // namespace rr
3545
Ben Clayton7e11f462019-11-18 16:00:31 +00003546#include "Traits.inl"
3547
Ben Clayton713b8d32019-12-17 20:37:56 +00003548#endif // rr_Reactor_hpp