1// 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
15#ifndef sw_Nucleus_hpp
16#define sw_Nucleus_hpp
17
18#include "Common/Types.hpp"
19#include "Common/MutexLock.hpp"
20
21#include <stdarg.h>
22#include <vector>
23#include <stdio.h>
24#include <wchar.h>
25
26#undef abs
27#undef max
28#undef min
29#undef Bool
30
31namespace llvm
32{
33	class Function;
34	class Module;
35	class BasicBlock;
36	class Value;
37	class Constant;
38	class ConstantInt;
39	class ConstantFP;
40	class Type;
41	class Argument;
42	class GlobalVariable;
43	class GlobalValue;
44	class ExecutionEngine;
45	class LLVMContext;
46}
47
48namespace sw
49{
50	enum Optimization
51	{
52		Disabled             = 0,
53		InstructionCombining = 1,
54		CFGSimplification    = 2,
55		LICM                 = 3,
56		AggressiveDCE        = 4,
57		GVN                  = 5,
58		Reassociate          = 6,
59		DeadStoreElimination = 7,
60		SCCP                 = 8,
61		ScalarReplAggregates = 9,
62
63		OptimizationCount
64	};
65
66	extern Optimization optimization[10];
67
68	class Routine;
69	class RoutineManager;
70	class Builder;
71
72	class Nucleus
73	{
74	public:
75		Nucleus();
76
77		virtual ~Nucleus();
78
79		Routine *acquireRoutine(const wchar_t *name, bool runOptimizations = true);
80
81		static void setFunction(llvm::Function *function);
82
83		static llvm::Module *getModule();
84		static llvm::Function *getFunction();
85		static llvm::LLVMContext *getContext();
86
87		static llvm::Value *allocateStackVariable(llvm::Type *type, int arraySize = 0);
88		static llvm::BasicBlock *createBasicBlock();
89		static llvm::BasicBlock *getInsertBlock();
90		static void setInsertBlock(llvm::BasicBlock *basicBlock);
91		static llvm::BasicBlock *getPredecessor(llvm::BasicBlock *basicBlock);
92
93		static llvm::Function *createFunction(llvm::Type *ReturnType, std::vector<llvm::Type*> &Params);
94		static llvm::Value *getArgument(llvm::Function *function, unsigned int index);
95
96		// Terminators
97		static llvm::Value *createRetVoid();
98		static llvm::Value *createRet(llvm::Value *V);
99		static llvm::Value *createBr(llvm::BasicBlock *dest);
100		static llvm::Value *createCondBr(llvm::Value *cond, llvm::BasicBlock *ifTrue, llvm::BasicBlock *ifFalse);
101
102		// Binary operators
103		static llvm::Value *createAdd(llvm::Value *lhs, llvm::Value *rhs);
104		static llvm::Value *createSub(llvm::Value *lhs, llvm::Value *rhs);
105		static llvm::Value *createMul(llvm::Value *lhs, llvm::Value *rhs);
106		static llvm::Value *createUDiv(llvm::Value *lhs, llvm::Value *rhs);
107		static llvm::Value *createSDiv(llvm::Value *lhs, llvm::Value *rhs);
108		static llvm::Value *createFAdd(llvm::Value *lhs, llvm::Value *rhs);
109		static llvm::Value *createFSub(llvm::Value *lhs, llvm::Value *rhs);
110		static llvm::Value *createFMul(llvm::Value *lhs, llvm::Value *rhs);
111		static llvm::Value *createFDiv(llvm::Value *lhs, llvm::Value *rhs);
112		static llvm::Value *createURem(llvm::Value *lhs, llvm::Value *rhs);
113		static llvm::Value *createSRem(llvm::Value *lhs, llvm::Value *rhs);
114		static llvm::Value *createFRem(llvm::Value *lhs, llvm::Value *rhs);
115		static llvm::Value *createShl(llvm::Value *lhs, llvm::Value *rhs);
116		static llvm::Value *createLShr(llvm::Value *lhs, llvm::Value *rhs);
117		static llvm::Value *createAShr(llvm::Value *lhs, llvm::Value *rhs);
118		static llvm::Value *createAnd(llvm::Value *lhs, llvm::Value *rhs);
119		static llvm::Value *createOr(llvm::Value *lhs, llvm::Value *rhs);
120		static llvm::Value *createXor(llvm::Value *lhs, llvm::Value *rhs);
121		static llvm::Value *createNeg(llvm::Value *V);
122		static llvm::Value *createFNeg(llvm::Value *V);
123		static llvm::Value *createNot(llvm::Value *V);
124
125		// Memory instructions
126		static llvm::Value *createLoad(llvm::Value *ptr, bool isVolatile = false, unsigned int align = 0);
127		static llvm::Value *createStore(llvm::Value *value, llvm::Value *ptr, bool isVolatile = false, unsigned int align = 0);
128		static llvm::Value *createGEP(llvm::Value *ptr, llvm::Value *index);
129
130		// Atomic instructions
131		static llvm::Value *createAtomicAdd(llvm::Value *ptr, llvm::Value *value);
132
133		// Cast/Conversion Operators
134		static llvm::Value *createTrunc(llvm::Value *V, llvm::Type *destType);
135		static llvm::Value *createZExt(llvm::Value *V, llvm::Type *destType);
136		static llvm::Value *createSExt(llvm::Value *V, llvm::Type *destType);
137		static llvm::Value *createFPToUI(llvm::Value *V, llvm::Type *destType);
138		static llvm::Value *createFPToSI(llvm::Value *V, llvm::Type *destType);
139		static llvm::Value *createUIToFP(llvm::Value *V, llvm::Type *destType);
140		static llvm::Value *createSIToFP(llvm::Value *V, llvm::Type *destType);
141		static llvm::Value *createFPTrunc(llvm::Value *V, llvm::Type *destType);
142		static llvm::Value *createFPExt(llvm::Value *V, llvm::Type *destType);
143		static llvm::Value *createPtrToInt(llvm::Value *V, llvm::Type *destType);
144		static llvm::Value *createIntToPtr(llvm::Value *V, llvm::Type *destType);
145		static llvm::Value *createBitCast(llvm::Value *V, llvm::Type *destType);
146		static llvm::Value *createIntCast(llvm::Value *V, llvm::Type *destType, bool isSigned);
147
148		// Compare instructions
149		static llvm::Value *createICmpEQ(llvm::Value *lhs, llvm::Value *rhs);
150		static llvm::Value *createICmpNE(llvm::Value *lhs, llvm::Value *rhs);
151		static llvm::Value *createICmpUGT(llvm::Value *lhs, llvm::Value *rhs);
152		static llvm::Value *createICmpUGE(llvm::Value *lhs, llvm::Value *rhs);
153		static llvm::Value *createICmpULT(llvm::Value *lhs, llvm::Value *rhs);
154		static llvm::Value *createICmpULE(llvm::Value *lhs, llvm::Value *rhs);
155		static llvm::Value *createICmpSGT(llvm::Value *lhs, llvm::Value *rhs);
156		static llvm::Value *createICmpSGE(llvm::Value *lhs, llvm::Value *rhs);
157		static llvm::Value *createICmpSLT(llvm::Value *lhs, llvm::Value *rhs);
158		static llvm::Value *createICmpSLE(llvm::Value *lhs, llvm::Value *rhs);
159		static llvm::Value *createFCmpOEQ(llvm::Value *lhs, llvm::Value *rhs);
160		static llvm::Value *createFCmpOGT(llvm::Value *lhs, llvm::Value *rhs);
161		static llvm::Value *createFCmpOGE(llvm::Value *lhs, llvm::Value *rhs);
162		static llvm::Value *createFCmpOLT(llvm::Value *lhs, llvm::Value *rhs);
163		static llvm::Value *createFCmpOLE(llvm::Value *lhs, llvm::Value *rhs);
164		static llvm::Value *createFCmpONE(llvm::Value *lhs, llvm::Value *rhs);
165		static llvm::Value *createFCmpORD(llvm::Value *lhs, llvm::Value *rhs);
166		static llvm::Value *createFCmpUNO(llvm::Value *lhs, llvm::Value *rhs);
167		static llvm::Value *createFCmpUEQ(llvm::Value *lhs, llvm::Value *rhs);
168		static llvm::Value *createFCmpUGT(llvm::Value *lhs, llvm::Value *rhs);
169		static llvm::Value *createFCmpUGE(llvm::Value *lhs, llvm::Value *rhs);
170		static llvm::Value *createFCmpULT(llvm::Value *lhs, llvm::Value *rhs);
171		static llvm::Value *createFCmpULE(llvm::Value *lhs, llvm::Value *rhs);
172		static llvm::Value *createFCmpUNE(llvm::Value *lhs, llvm::Value *rhs);
173
174		// Call instructions
175		static llvm::Value *createCall(llvm::Value *callee);
176		static llvm::Value *createCall(llvm::Value *callee, llvm::Value *Arg);
177		static llvm::Value *createCall(llvm::Value *callee, llvm::Value *Arg1, llvm::Value *Arg2);
178		static llvm::Value *createCall(llvm::Value *callee, llvm::Value *Arg1, llvm::Value *Arg2, llvm::Value *Arg3);
179		static llvm::Value *createCall(llvm::Value *callee, llvm::Value *Arg1, llvm::Value *Arg2, llvm::Value *Arg3,llvm::Value *Arg4);
180
181		// Vector instructions
182		static llvm::Value *createExtractElement(llvm::Value *vector, int index);
183		static llvm::Value *createInsertElement(llvm::Value *vector, llvm::Value *element, int index);
184		static llvm::Value *createShuffleVector(llvm::Value *V1, llvm::Value *V2, llvm::Value *mask);
185
186		// Other instructions
187		static llvm::Value *createSelect(llvm::Value *C, llvm::Value *ifTrue, llvm::Value *ifFalse);
188		static llvm::Value *createSwitch(llvm::Value *V, llvm::BasicBlock *Dest, unsigned NumCases);
189		static void addSwitchCase(llvm::Value *Switch, int Case, llvm::BasicBlock *Branch);
190		static llvm::Value *createUnreachable();
191
192		// Derived instructions
193		static llvm::Value *createSwizzle(llvm::Value *val, unsigned char select);
194		static llvm::Value *createMask(llvm::Value *lhs, llvm::Value *rhs, unsigned char select);
195
196		// Global values
197		static const llvm::GlobalValue *getGlobalValueAtAddress(void *Addr);
198		static void addGlobalMapping(const llvm::GlobalValue *GV, void *Addr);
199		static llvm::GlobalValue *createGlobalValue(llvm::Type *Ty, bool isConstant, unsigned int Align);
200		static llvm::Type *getPointerType(llvm::Type *ElementType);
201
202		// Constant values
203		static llvm::Constant *createNullValue(llvm::Type *Ty);
204		static llvm::ConstantInt *createConstantInt(int64_t i);
205		static llvm::ConstantInt *createConstantInt(int i);
206		static llvm::ConstantInt *createConstantInt(unsigned int i);
207		static llvm::ConstantInt *createConstantBool(bool b);
208		static llvm::ConstantInt *createConstantByte(signed char i);
209		static llvm::ConstantInt *createConstantByte(unsigned char i);
210		static llvm::ConstantInt *createConstantShort(short i);
211		static llvm::ConstantInt *createConstantShort(unsigned short i);
212		static llvm::Constant *createConstantFloat(float x);
213		static llvm::Value *createNullPointer(llvm::Type *Ty);
214		static llvm::Value *createConstantVector(llvm::Constant *const *Vals, unsigned NumVals);
215
216	private:
217		void optimize();
218
219		static llvm::ExecutionEngine *executionEngine;
220		static Builder *builder;
221		static llvm::Function *function;
222		static llvm::LLVMContext *context;
223		static llvm::Module *module;
224		static RoutineManager *routineManager;
225
226		static BackoffLock codegenMutex;
227	};
228
229	class Byte;
230	class SByte;
231	class Byte4;
232	class SByte4;
233	class Byte8;
234	class SByte8;
235	class Byte16;
236	class SByte16;
237	class Short;
238	class UShort;
239	class Short4;
240	class UShort4;
241	class Short8;
242	class UShort8;
243	class Int;
244	class UInt;
245	class Int2;
246	class UInt2;
247	class Int4;
248	class UInt4;
249	class Long;
250	class Long1;
251	class Long2;
252	class Float;
253	class Float2;
254	class Float4;
255
256	class Void
257	{
258	public:
259		static llvm::Type *getType();
260
261		static bool isVoid()
262		{
263			return true;
264		}
265
266		typedef void ctype;
267	};
268
269	template<class T>
270	class RValue;
271
272	template<class T>
273	class Pointer;
274
275	class LValue
276	{
277	public:
278		LValue(llvm::Type *type, int arraySize = 0);
279
280		static bool isVoid()
281		{
282			return false;
283		}
284
285		llvm::Value *loadValue(unsigned int alignment = 0) const;
286		llvm::Value *storeValue(llvm::Value *value, unsigned int alignment = 0) const;
287		llvm::Value *getAddress(llvm::Value *index) const;
288
289	protected:
290		llvm::Value *address;
291	};
292
293	template<class T>
294	class Variable : public LValue
295	{
296	public:
297		Variable(int arraySize = 0);
298
299		RValue<Pointer<T>> operator&();
300	};
301
302	template<class T>
303	class Reference
304	{
305	public:
306		explicit Reference(llvm::Value *pointer, int alignment = 1);
307
308		RValue<T> operator=(RValue<T> rhs) const;
309		RValue<T> operator=(const Reference<T> &ref) const;
310
311		RValue<T> operator+=(RValue<T> rhs) const;
312
313		llvm::Value *loadValue() const;
314		int getAlignment() const;
315
316	private:
317		llvm::Value *address;
318
319		const int alignment;
320	};
321
322	template<class T>
323	struct IntLiteral
324	{
325		struct type;
326	};
327
328	template<> struct
329	IntLiteral<Int>
330	{
331		typedef int type;
332	};
333
334	template<> struct
335	IntLiteral<UInt>
336	{
337		typedef unsigned int type;
338	};
339
340	template<> struct
341	IntLiteral<Long>
342	{
343		typedef int64_t type;
344	};
345
346	template<class T>
347	struct FloatLiteral
348	{
349		struct type;
350	};
351
352	template<> struct
353	FloatLiteral<Float>
354	{
355		typedef float type;
356	};
357
358	template<class T>
359	class RValue
360	{
361	public:
362		explicit RValue(llvm::Value *rvalue);
363
364		RValue(const T &lvalue);
365		RValue(typename IntLiteral<T>::type i);
366		RValue(typename FloatLiteral<T>::type f);
367		RValue(const Reference<T> &rhs);
368
369		RValue<T> &operator=(const RValue<T>&) = delete;
370
371		llvm::Value *value;   // FIXME: Make private
372	};
373
374	template<typename T>
375	struct Argument
376	{
377		explicit Argument(llvm::Value *value) : value(value) {}
378
379		llvm::Value *value;
380	};
381
382	class MMX : public Variable<MMX>
383	{
384	public:
385		static llvm::Type *getType();
386	};
387
388	class Bool : public Variable<Bool>
389	{
390	public:
391		Bool(Argument<Bool> argument);
392
393		Bool();
394		Bool(bool x);
395		Bool(RValue<Bool> rhs);
396		Bool(const Bool &rhs);
397		Bool(const Reference<Bool> &rhs);
398
399	//	RValue<Bool> operator=(bool rhs) const;   // FIXME: Implement
400		RValue<Bool> operator=(RValue<Bool> rhs) const;
401		RValue<Bool> operator=(const Bool &rhs) const;
402		RValue<Bool> operator=(const Reference<Bool> &rhs) const;
403
404		static llvm::Type *getType();
405	};
406
407	RValue<Bool> operator!(RValue<Bool> val);
408	RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs);
409	RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs);
410
411	class Byte : public Variable<Byte>
412	{
413	public:
414		Byte(Argument<Byte> argument);
415
416		explicit Byte(RValue<Int> cast);
417		explicit Byte(RValue<UInt> cast);
418		explicit Byte(RValue<UShort> cast);
419
420		Byte();
421		Byte(int x);
422		Byte(unsigned char x);
423		Byte(RValue<Byte> rhs);
424		Byte(const Byte &rhs);
425		Byte(const Reference<Byte> &rhs);
426
427	//	RValue<Byte> operator=(unsigned char rhs) const;   // FIXME: Implement
428		RValue<Byte> operator=(RValue<Byte> rhs) const;
429		RValue<Byte> operator=(const Byte &rhs) const;
430		RValue<Byte> operator=(const Reference<Byte> &rhs) const;
431
432		static llvm::Type *getType();
433	};
434
435	RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs);
436	RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs);
437	RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs);
438	RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs);
439	RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs);
440	RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs);
441	RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs);
442	RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs);
443	RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs);
444	RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs);
445	RValue<Byte> operator+=(const Byte &lhs, RValue<Byte> rhs);
446	RValue<Byte> operator-=(const Byte &lhs, RValue<Byte> rhs);
447	RValue<Byte> operator*=(const Byte &lhs, RValue<Byte> rhs);
448	RValue<Byte> operator/=(const Byte &lhs, RValue<Byte> rhs);
449	RValue<Byte> operator%=(const Byte &lhs, RValue<Byte> rhs);
450	RValue<Byte> operator&=(const Byte &lhs, RValue<Byte> rhs);
451	RValue<Byte> operator|=(const Byte &lhs, RValue<Byte> rhs);
452	RValue<Byte> operator^=(const Byte &lhs, RValue<Byte> rhs);
453	RValue<Byte> operator<<=(const Byte &lhs, RValue<Byte> rhs);
454	RValue<Byte> operator>>=(const Byte &lhs, RValue<Byte> rhs);
455	RValue<Byte> operator+(RValue<Byte> val);
456	RValue<Byte> operator-(RValue<Byte> val);
457	RValue<Byte> operator~(RValue<Byte> val);
458	RValue<Byte> operator++(const Byte &val, int);   // Post-increment
459	const Byte &operator++(const Byte &val);   // Pre-increment
460	RValue<Byte> operator--(const Byte &val, int);   // Post-decrement
461	const Byte &operator--(const Byte &val);   // Pre-decrement
462	RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs);
463	RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs);
464	RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs);
465	RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs);
466	RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs);
467	RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs);
468
469	class SByte : public Variable<SByte>
470	{
471	public:
472		SByte(Argument<SByte> argument);
473
474		explicit SByte(RValue<Int> cast);
475		explicit SByte(RValue<Short> cast);
476
477		SByte();
478		SByte(signed char x);
479		SByte(RValue<SByte> rhs);
480		SByte(const SByte &rhs);
481		SByte(const Reference<SByte> &rhs);
482
483	//	RValue<SByte> operator=(signed char rhs) const;   // FIXME: Implement
484		RValue<SByte> operator=(RValue<SByte> rhs) const;
485		RValue<SByte> operator=(const SByte &rhs) const;
486		RValue<SByte> operator=(const Reference<SByte> &rhs) const;
487
488		static llvm::Type *getType();
489	};
490
491	RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs);
492	RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs);
493	RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs);
494	RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs);
495	RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs);
496	RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs);
497	RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs);
498	RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs);
499	RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs);
500	RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs);
501	RValue<SByte> operator+=(const SByte &lhs, RValue<SByte> rhs);
502	RValue<SByte> operator-=(const SByte &lhs, RValue<SByte> rhs);
503	RValue<SByte> operator*=(const SByte &lhs, RValue<SByte> rhs);
504	RValue<SByte> operator/=(const SByte &lhs, RValue<SByte> rhs);
505	RValue<SByte> operator%=(const SByte &lhs, RValue<SByte> rhs);
506	RValue<SByte> operator&=(const SByte &lhs, RValue<SByte> rhs);
507	RValue<SByte> operator|=(const SByte &lhs, RValue<SByte> rhs);
508	RValue<SByte> operator^=(const SByte &lhs, RValue<SByte> rhs);
509	RValue<SByte> operator<<=(const SByte &lhs, RValue<SByte> rhs);
510	RValue<SByte> operator>>=(const SByte &lhs, RValue<SByte> rhs);
511	RValue<SByte> operator+(RValue<SByte> val);
512	RValue<SByte> operator-(RValue<SByte> val);
513	RValue<SByte> operator~(RValue<SByte> val);
514	RValue<SByte> operator++(const SByte &val, int);   // Post-increment
515	const SByte &operator++(const SByte &val);   // Pre-increment
516	RValue<SByte> operator--(const SByte &val, int);   // Post-decrement
517	const SByte &operator--(const SByte &val);   // Pre-decrement
518	RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs);
519	RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs);
520	RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs);
521	RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs);
522	RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs);
523	RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs);
524
525	class Short : public Variable<Short>
526	{
527	public:
528		Short(Argument<Short> argument);
529
530		explicit Short(RValue<Int> cast);
531
532		Short();
533		Short(short x);
534		Short(RValue<Short> rhs);
535		Short(const Short &rhs);
536		Short(const Reference<Short> &rhs);
537
538	//	RValue<Short> operator=(short rhs) const;   // FIXME: Implement
539		RValue<Short> operator=(RValue<Short> rhs) const;
540		RValue<Short> operator=(const Short &rhs) const;
541		RValue<Short> operator=(const Reference<Short> &rhs) const;
542
543		static llvm::Type *getType();
544	};
545
546	RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs);
547	RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs);
548	RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs);
549	RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs);
550	RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs);
551	RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs);
552	RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs);
553	RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs);
554	RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs);
555	RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs);
556	RValue<Short> operator+=(const Short &lhs, RValue<Short> rhs);
557	RValue<Short> operator-=(const Short &lhs, RValue<Short> rhs);
558	RValue<Short> operator*=(const Short &lhs, RValue<Short> rhs);
559	RValue<Short> operator/=(const Short &lhs, RValue<Short> rhs);
560	RValue<Short> operator%=(const Short &lhs, RValue<Short> rhs);
561	RValue<Short> operator&=(const Short &lhs, RValue<Short> rhs);
562	RValue<Short> operator|=(const Short &lhs, RValue<Short> rhs);
563	RValue<Short> operator^=(const Short &lhs, RValue<Short> rhs);
564	RValue<Short> operator<<=(const Short &lhs, RValue<Short> rhs);
565	RValue<Short> operator>>=(const Short &lhs, RValue<Short> rhs);
566	RValue<Short> operator+(RValue<Short> val);
567	RValue<Short> operator-(RValue<Short> val);
568	RValue<Short> operator~(RValue<Short> val);
569	RValue<Short> operator++(const Short &val, int);   // Post-increment
570	const Short &operator++(const Short &val);   // Pre-increment
571	RValue<Short> operator--(const Short &val, int);   // Post-decrement
572	const Short &operator--(const Short &val);   // Pre-decrement
573	RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs);
574	RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs);
575	RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs);
576	RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs);
577	RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs);
578	RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs);
579
580	class UShort : public Variable<UShort>
581	{
582	public:
583		UShort(Argument<UShort> argument);
584
585		explicit UShort(RValue<UInt> cast);
586		explicit UShort(RValue<Int> cast);
587
588		UShort();
589		UShort(unsigned short x);
590		UShort(RValue<UShort> rhs);
591		UShort(const UShort &rhs);
592		UShort(const Reference<UShort> &rhs);
593
594	//	RValue<UShort> operator=(unsigned short rhs) const;   // FIXME: Implement
595		RValue<UShort> operator=(RValue<UShort> rhs) const;
596		RValue<UShort> operator=(const UShort &rhs) const;
597		RValue<UShort> operator=(const Reference<UShort> &rhs) const;
598
599		static llvm::Type *getType();
600	};
601
602	RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs);
603	RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs);
604	RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs);
605	RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs);
606	RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs);
607	RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs);
608	RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs);
609	RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs);
610	RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs);
611	RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs);
612	RValue<UShort> operator+=(const UShort &lhs, RValue<UShort> rhs);
613	RValue<UShort> operator-=(const UShort &lhs, RValue<UShort> rhs);
614	RValue<UShort> operator*=(const UShort &lhs, RValue<UShort> rhs);
615	RValue<UShort> operator/=(const UShort &lhs, RValue<UShort> rhs);
616	RValue<UShort> operator%=(const UShort &lhs, RValue<UShort> rhs);
617	RValue<UShort> operator&=(const UShort &lhs, RValue<UShort> rhs);
618	RValue<UShort> operator|=(const UShort &lhs, RValue<UShort> rhs);
619	RValue<UShort> operator^=(const UShort &lhs, RValue<UShort> rhs);
620	RValue<UShort> operator<<=(const UShort &lhs, RValue<UShort> rhs);
621	RValue<UShort> operator>>=(const UShort &lhs, RValue<UShort> rhs);
622	RValue<UShort> operator+(RValue<UShort> val);
623	RValue<UShort> operator-(RValue<UShort> val);
624	RValue<UShort> operator~(RValue<UShort> val);
625	RValue<UShort> operator++(const UShort &val, int);   // Post-increment
626	const UShort &operator++(const UShort &val);   // Pre-increment
627	RValue<UShort> operator--(const UShort &val, int);   // Post-decrement
628	const UShort &operator--(const UShort &val);   // Pre-decrement
629	RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs);
630	RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs);
631	RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs);
632	RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs);
633	RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs);
634	RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs);
635
636	class Byte4 : public Variable<Byte4>
637	{
638	public:
639	//	Byte4();
640	//	Byte4(int x, int y, int z, int w);
641	//	Byte4(RValue<Byte4> rhs);
642	//	Byte4(const Byte4 &rhs);
643	//	Byte4(const Reference<Byte4> &rhs);
644
645	//	RValue<Byte4> operator=(RValue<Byte4> rhs) const;
646	//	RValue<Byte4> operator=(const Byte4 &rhs) const;
647	//	RValue<Byte4> operator=(const Reference<Byte4> &rhs) const;
648
649		static llvm::Type *getType();
650	};
651
652//	RValue<Byte4> operator+(RValue<Byte4> lhs, RValue<Byte4> rhs);
653//	RValue<Byte4> operator-(RValue<Byte4> lhs, RValue<Byte4> rhs);
654//	RValue<Byte4> operator*(RValue<Byte4> lhs, RValue<Byte4> rhs);
655//	RValue<Byte4> operator/(RValue<Byte4> lhs, RValue<Byte4> rhs);
656//	RValue<Byte4> operator%(RValue<Byte4> lhs, RValue<Byte4> rhs);
657//	RValue<Byte4> operator&(RValue<Byte4> lhs, RValue<Byte4> rhs);
658//	RValue<Byte4> operator|(RValue<Byte4> lhs, RValue<Byte4> rhs);
659//	RValue<Byte4> operator^(RValue<Byte4> lhs, RValue<Byte4> rhs);
660//	RValue<Byte4> operator<<(RValue<Byte4> lhs, RValue<Byte4> rhs);
661//	RValue<Byte4> operator>>(RValue<Byte4> lhs, RValue<Byte4> rhs);
662//	RValue<Byte4> operator+=(const Byte4 &lhs, RValue<Byte4> rhs);
663//	RValue<Byte4> operator-=(const Byte4 &lhs, RValue<Byte4> rhs);
664//	RValue<Byte4> operator*=(const Byte4 &lhs, RValue<Byte4> rhs);
665//	RValue<Byte4> operator/=(const Byte4 &lhs, RValue<Byte4> rhs);
666//	RValue<Byte4> operator%=(const Byte4 &lhs, RValue<Byte4> rhs);
667//	RValue<Byte4> operator&=(const Byte4 &lhs, RValue<Byte4> rhs);
668//	RValue<Byte4> operator|=(const Byte4 &lhs, RValue<Byte4> rhs);
669//	RValue<Byte4> operator^=(const Byte4 &lhs, RValue<Byte4> rhs);
670//	RValue<Byte4> operator<<=(const Byte4 &lhs, RValue<Byte4> rhs);
671//	RValue<Byte4> operator>>=(const Byte4 &lhs, RValue<Byte4> rhs);
672//	RValue<Byte4> operator+(RValue<Byte4> val);
673//	RValue<Byte4> operator-(RValue<Byte4> val);
674//	RValue<Byte4> operator~(RValue<Byte4> val);
675//	RValue<Byte4> operator++(const Byte4 &val, int);   // Post-increment
676//	const Byte4 &operator++(const Byte4 &val);   // Pre-increment
677//	RValue<Byte4> operator--(const Byte4 &val, int);   // Post-decrement
678//	const Byte4 &operator--(const Byte4 &val);   // Pre-decrement
679
680	class SByte4 : public Variable<SByte4>
681	{
682	public:
683	//	SByte4();
684	//	SByte4(int x, int y, int z, int w);
685	//	SByte4(RValue<SByte4> rhs);
686	//	SByte4(const SByte4 &rhs);
687	//	SByte4(const Reference<SByte4> &rhs);
688
689	//	RValue<SByte4> operator=(RValue<SByte4> rhs) const;
690	//	RValue<SByte4> operator=(const SByte4 &rhs) const;
691	//	RValue<SByte4> operator=(const Reference<SByte4> &rhs) const;
692
693		static llvm::Type *getType();
694	};
695
696//	RValue<SByte4> operator+(RValue<SByte4> lhs, RValue<SByte4> rhs);
697//	RValue<SByte4> operator-(RValue<SByte4> lhs, RValue<SByte4> rhs);
698//	RValue<SByte4> operator*(RValue<SByte4> lhs, RValue<SByte4> rhs);
699//	RValue<SByte4> operator/(RValue<SByte4> lhs, RValue<SByte4> rhs);
700//	RValue<SByte4> operator%(RValue<SByte4> lhs, RValue<SByte4> rhs);
701//	RValue<SByte4> operator&(RValue<SByte4> lhs, RValue<SByte4> rhs);
702//	RValue<SByte4> operator|(RValue<SByte4> lhs, RValue<SByte4> rhs);
703//	RValue<SByte4> operator^(RValue<SByte4> lhs, RValue<SByte4> rhs);
704//	RValue<SByte4> operator<<(RValue<SByte4> lhs, RValue<SByte4> rhs);
705//	RValue<SByte4> operator>>(RValue<SByte4> lhs, RValue<SByte4> rhs);
706//	RValue<SByte4> operator+=(const SByte4 &lhs, RValue<SByte4> rhs);
707//	RValue<SByte4> operator-=(const SByte4 &lhs, RValue<SByte4> rhs);
708//	RValue<SByte4> operator*=(const SByte4 &lhs, RValue<SByte4> rhs);
709//	RValue<SByte4> operator/=(const SByte4 &lhs, RValue<SByte4> rhs);
710//	RValue<SByte4> operator%=(const SByte4 &lhs, RValue<SByte4> rhs);
711//	RValue<SByte4> operator&=(const SByte4 &lhs, RValue<SByte4> rhs);
712//	RValue<SByte4> operator|=(const SByte4 &lhs, RValue<SByte4> rhs);
713//	RValue<SByte4> operator^=(const SByte4 &lhs, RValue<SByte4> rhs);
714//	RValue<SByte4> operator<<=(const SByte4 &lhs, RValue<SByte4> rhs);
715//	RValue<SByte4> operator>>=(const SByte4 &lhs, RValue<SByte4> rhs);
716//	RValue<SByte4> operator+(RValue<SByte4> val);
717//	RValue<SByte4> operator-(RValue<SByte4> val);
718//	RValue<SByte4> operator~(RValue<SByte4> val);
719//	RValue<SByte4> operator++(const SByte4 &val, int);   // Post-increment
720//	const SByte4 &operator++(const SByte4 &val);   // Pre-increment
721//	RValue<SByte4> operator--(const SByte4 &val, int);   // Post-decrement
722//	const SByte4 &operator--(const SByte4 &val);   // Pre-decrement
723
724	class Byte8 : public Variable<Byte8>
725	{
726	public:
727		Byte8();
728		Byte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7);
729		Byte8(int64_t x);
730		Byte8(RValue<Byte8> rhs);
731		Byte8(const Byte8 &rhs);
732		Byte8(const Reference<Byte8> &rhs);
733
734		RValue<Byte8> operator=(RValue<Byte8> rhs) const;
735		RValue<Byte8> operator=(const Byte8 &rhs) const;
736		RValue<Byte8> operator=(const Reference<Byte8> &rhs) const;
737
738		static llvm::Type *getType();
739	};
740
741	RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs);
742	RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs);
743//	RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs);
744//	RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs);
745//	RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs);
746	RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs);
747	RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs);
748	RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs);
749//	RValue<Byte8> operator<<(RValue<Byte8> lhs, RValue<Byte8> rhs);
750//	RValue<Byte8> operator>>(RValue<Byte8> lhs, RValue<Byte8> rhs);
751	RValue<Byte8> operator+=(const Byte8 &lhs, RValue<Byte8> rhs);
752	RValue<Byte8> operator-=(const Byte8 &lhs, RValue<Byte8> rhs);
753//	RValue<Byte8> operator*=(const Byte8 &lhs, RValue<Byte8> rhs);
754//	RValue<Byte8> operator/=(const Byte8 &lhs, RValue<Byte8> rhs);
755//	RValue<Byte8> operator%=(const Byte8 &lhs, RValue<Byte8> rhs);
756	RValue<Byte8> operator&=(const Byte8 &lhs, RValue<Byte8> rhs);
757	RValue<Byte8> operator|=(const Byte8 &lhs, RValue<Byte8> rhs);
758	RValue<Byte8> operator^=(const Byte8 &lhs, RValue<Byte8> rhs);
759//	RValue<Byte8> operator<<=(const Byte8 &lhs, RValue<Byte8> rhs);
760//	RValue<Byte8> operator>>=(const Byte8 &lhs, RValue<Byte8> rhs);
761//	RValue<Byte8> operator+(RValue<Byte8> val);
762//	RValue<Byte8> operator-(RValue<Byte8> val);
763	RValue<Byte8> operator~(RValue<Byte8> val);
764//	RValue<Byte8> operator++(const Byte8 &val, int);   // Post-increment
765//	const Byte8 &operator++(const Byte8 &val);   // Pre-increment
766//	RValue<Byte8> operator--(const Byte8 &val, int);   // Post-decrement
767//	const Byte8 &operator--(const Byte8 &val);   // Pre-decrement
768
769	RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y);
770	RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y);
771	RValue<Short4> Unpack(RValue<Byte4> x);
772	RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y);
773	RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y);
774	RValue<Int> SignMask(RValue<Byte8> x);
775//	RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y);
776	RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y);
777
778	class SByte8 : public Variable<SByte8>
779	{
780	public:
781		SByte8();
782		SByte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7);
783		SByte8(int64_t x);
784		SByte8(RValue<SByte8> rhs);
785		SByte8(const SByte8 &rhs);
786		SByte8(const Reference<SByte8> &rhs);
787
788		RValue<SByte8> operator=(RValue<SByte8> rhs) const;
789		RValue<SByte8> operator=(const SByte8 &rhs) const;
790		RValue<SByte8> operator=(const Reference<SByte8> &rhs) const;
791
792		static llvm::Type *getType();
793	};
794
795	RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs);
796	RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs);
797//	RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs);
798//	RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs);
799//	RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs);
800	RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs);
801	RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs);
802	RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs);
803//	RValue<SByte8> operator<<(RValue<SByte8> lhs, RValue<SByte8> rhs);
804//	RValue<SByte8> operator>>(RValue<SByte8> lhs, RValue<SByte8> rhs);
805	RValue<SByte8> operator+=(const SByte8 &lhs, RValue<SByte8> rhs);
806	RValue<SByte8> operator-=(const SByte8 &lhs, RValue<SByte8> rhs);
807//	RValue<SByte8> operator*=(const SByte8 &lhs, RValue<SByte8> rhs);
808//	RValue<SByte8> operator/=(const SByte8 &lhs, RValue<SByte8> rhs);
809//	RValue<SByte8> operator%=(const SByte8 &lhs, RValue<SByte8> rhs);
810	RValue<SByte8> operator&=(const SByte8 &lhs, RValue<SByte8> rhs);
811	RValue<SByte8> operator|=(const SByte8 &lhs, RValue<SByte8> rhs);
812	RValue<SByte8> operator^=(const SByte8 &lhs, RValue<SByte8> rhs);
813//	RValue<SByte8> operator<<=(const SByte8 &lhs, RValue<SByte8> rhs);
814//	RValue<SByte8> operator>>=(const SByte8 &lhs, RValue<SByte8> rhs);
815//	RValue<SByte8> operator+(RValue<SByte8> val);
816//	RValue<SByte8> operator-(RValue<SByte8> val);
817	RValue<SByte8> operator~(RValue<SByte8> val);
818//	RValue<SByte8> operator++(const SByte8 &val, int);   // Post-increment
819//	const SByte8 &operator++(const SByte8 &val);   // Pre-increment
820//	RValue<SByte8> operator--(const SByte8 &val, int);   // Post-decrement
821//	const SByte8 &operator--(const SByte8 &val);   // Pre-decrement
822
823	RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y);
824	RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y);
825	RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y);
826	RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y);
827	RValue<Int> SignMask(RValue<SByte8> x);
828	RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y);
829	RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y);
830
831	class Byte16 : public Variable<Byte16>
832	{
833	public:
834	//	Byte16();
835	//	Byte16(int x, int y, int z, int w);
836		Byte16(RValue<Byte16> rhs);
837		Byte16(const Byte16 &rhs);
838		Byte16(const Reference<Byte16> &rhs);
839
840		RValue<Byte16> operator=(RValue<Byte16> rhs) const;
841		RValue<Byte16> operator=(const Byte16 &rhs) const;
842		RValue<Byte16> operator=(const Reference<Byte16> &rhs) const;
843
844		static llvm::Type *getType();
845	};
846
847//	RValue<Byte16> operator+(RValue<Byte16> lhs, RValue<Byte16> rhs);
848//	RValue<Byte16> operator-(RValue<Byte16> lhs, RValue<Byte16> rhs);
849//	RValue<Byte16> operator*(RValue<Byte16> lhs, RValue<Byte16> rhs);
850//	RValue<Byte16> operator/(RValue<Byte16> lhs, RValue<Byte16> rhs);
851//	RValue<Byte16> operator%(RValue<Byte16> lhs, RValue<Byte16> rhs);
852//	RValue<Byte16> operator&(RValue<Byte16> lhs, RValue<Byte16> rhs);
853//	RValue<Byte16> operator|(RValue<Byte16> lhs, RValue<Byte16> rhs);
854//	RValue<Byte16> operator^(RValue<Byte16> lhs, RValue<Byte16> rhs);
855//	RValue<Byte16> operator<<(RValue<Byte16> lhs, RValue<Byte16> rhs);
856//	RValue<Byte16> operator>>(RValue<Byte16> lhs, RValue<Byte16> rhs);
857//	RValue<Byte16> operator+=(const Byte16 &lhs, RValue<Byte16> rhs);
858//	RValue<Byte16> operator-=(const Byte16 &lhs, RValue<Byte16> rhs);
859//	RValue<Byte16> operator*=(const Byte16 &lhs, RValue<Byte16> rhs);
860//	RValue<Byte16> operator/=(const Byte16 &lhs, RValue<Byte16> rhs);
861//	RValue<Byte16> operator%=(const Byte16 &lhs, RValue<Byte16> rhs);
862//	RValue<Byte16> operator&=(const Byte16 &lhs, RValue<Byte16> rhs);
863//	RValue<Byte16> operator|=(const Byte16 &lhs, RValue<Byte16> rhs);
864//	RValue<Byte16> operator^=(const Byte16 &lhs, RValue<Byte16> rhs);
865//	RValue<Byte16> operator<<=(const Byte16 &lhs, RValue<Byte16> rhs);
866//	RValue<Byte16> operator>>=(const Byte16 &lhs, RValue<Byte16> rhs);
867//	RValue<Byte16> operator+(RValue<Byte16> val);
868//	RValue<Byte16> operator-(RValue<Byte16> val);
869//	RValue<Byte16> operator~(RValue<Byte16> val);
870//	RValue<Byte16> operator++(const Byte16 &val, int);   // Post-increment
871//	const Byte16 &operator++(const Byte16 &val);   // Pre-increment
872//	RValue<Byte16> operator--(const Byte16 &val, int);   // Post-decrement
873//	const Byte16 &operator--(const Byte16 &val);   // Pre-decrement
874
875	class SByte16 : public Variable<SByte16>
876	{
877	public:
878	//	SByte16();
879	//	SByte16(int x, int y, int z, int w);
880	//	SByte16(RValue<SByte16> rhs);
881	//	SByte16(const SByte16 &rhs);
882	//	SByte16(const Reference<SByte16> &rhs);
883
884	//	RValue<SByte16> operator=(RValue<SByte16> rhs) const;
885	//	RValue<SByte16> operator=(const SByte16 &rhs) const;
886	//	RValue<SByte16> operator=(const Reference<SByte16> &rhs) const;
887
888		static llvm::Type *getType();
889	};
890
891//	RValue<SByte16> operator+(RValue<SByte16> lhs, RValue<SByte16> rhs);
892//	RValue<SByte16> operator-(RValue<SByte16> lhs, RValue<SByte16> rhs);
893//	RValue<SByte16> operator*(RValue<SByte16> lhs, RValue<SByte16> rhs);
894//	RValue<SByte16> operator/(RValue<SByte16> lhs, RValue<SByte16> rhs);
895//	RValue<SByte16> operator%(RValue<SByte16> lhs, RValue<SByte16> rhs);
896//	RValue<SByte16> operator&(RValue<SByte16> lhs, RValue<SByte16> rhs);
897//	RValue<SByte16> operator|(RValue<SByte16> lhs, RValue<SByte16> rhs);
898//	RValue<SByte16> operator^(RValue<SByte16> lhs, RValue<SByte16> rhs);
899//	RValue<SByte16> operator<<(RValue<SByte16> lhs, RValue<SByte16> rhs);
900//	RValue<SByte16> operator>>(RValue<SByte16> lhs, RValue<SByte16> rhs);
901//	RValue<SByte16> operator+=(const SByte16 &lhs, RValue<SByte16> rhs);
902//	RValue<SByte16> operator-=(const SByte16 &lhs, RValue<SByte16> rhs);
903//	RValue<SByte16> operator*=(const SByte16 &lhs, RValue<SByte16> rhs);
904//	RValue<SByte16> operator/=(const SByte16 &lhs, RValue<SByte16> rhs);
905//	RValue<SByte16> operator%=(const SByte16 &lhs, RValue<SByte16> rhs);
906//	RValue<SByte16> operator&=(const SByte16 &lhs, RValue<SByte16> rhs);
907//	RValue<SByte16> operator|=(const SByte16 &lhs, RValue<SByte16> rhs);
908//	RValue<SByte16> operator^=(const SByte16 &lhs, RValue<SByte16> rhs);
909//	RValue<SByte16> operator<<=(const SByte16 &lhs, RValue<SByte16> rhs);
910//	RValue<SByte16> operator>>=(const SByte16 &lhs, RValue<SByte16> rhs);
911//	RValue<SByte16> operator+(RValue<SByte16> val);
912//	RValue<SByte16> operator-(RValue<SByte16> val);
913//	RValue<SByte16> operator~(RValue<SByte16> val);
914//	RValue<SByte16> operator++(const SByte16 &val, int);   // Post-increment
915//	const SByte16 &operator++(const SByte16 &val);   // Pre-increment
916//	RValue<SByte16> operator--(const SByte16 &val, int);   // Post-decrement
917//	const SByte16 &operator--(const SByte16 &val);   // Pre-decrement
918
919	class Short4 : public Variable<Short4>
920	{
921	public:
922		explicit Short4(RValue<Int> cast);
923		explicit Short4(RValue<Int4> cast);
924	//	explicit Short4(RValue<Float> cast);
925		explicit Short4(RValue<Float4> cast);
926
927		Short4();
928		Short4(short xyzw);
929		Short4(short x, short y, short z, short w);
930		Short4(RValue<Short4> rhs);
931		Short4(const Short4 &rhs);
932		Short4(const Reference<Short4> &rhs);
933		Short4(RValue<UShort4> rhs);
934		Short4(const UShort4 &rhs);
935		Short4(const Reference<UShort4> &rhs);
936
937		RValue<Short4> operator=(RValue<Short4> rhs) const;
938		RValue<Short4> operator=(const Short4 &rhs) const;
939		RValue<Short4> operator=(const Reference<Short4> &rhs) const;
940		RValue<Short4> operator=(RValue<UShort4> rhs) const;
941		RValue<Short4> operator=(const UShort4 &rhs) const;
942		RValue<Short4> operator=(const Reference<UShort4> &rhs) const;
943
944		static llvm::Type *getType();
945	};
946
947	RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs);
948	RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs);
949	RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs);
950//	RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs);
951//	RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs);
952	RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs);
953	RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs);
954	RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs);
955	RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs);
956	RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs);
957	RValue<Short4> operator<<(RValue<Short4> lhs, RValue<Long1> rhs);
958	RValue<Short4> operator>>(RValue<Short4> lhs, RValue<Long1> rhs);
959	RValue<Short4> operator+=(const Short4 &lhs, RValue<Short4> rhs);
960	RValue<Short4> operator-=(const Short4 &lhs, RValue<Short4> rhs);
961	RValue<Short4> operator*=(const Short4 &lhs, RValue<Short4> rhs);
962//	RValue<Short4> operator/=(const Short4 &lhs, RValue<Short4> rhs);
963//	RValue<Short4> operator%=(const Short4 &lhs, RValue<Short4> rhs);
964	RValue<Short4> operator&=(const Short4 &lhs, RValue<Short4> rhs);
965	RValue<Short4> operator|=(const Short4 &lhs, RValue<Short4> rhs);
966	RValue<Short4> operator^=(const Short4 &lhs, RValue<Short4> rhs);
967	RValue<Short4> operator<<=(const Short4 &lhs, unsigned char rhs);
968	RValue<Short4> operator>>=(const Short4 &lhs, unsigned char rhs);
969	RValue<Short4> operator<<=(const Short4 &lhs, RValue<Long1> rhs);
970	RValue<Short4> operator>>=(const Short4 &lhs, RValue<Long1> rhs);
971//	RValue<Short4> operator+(RValue<Short4> val);
972	RValue<Short4> operator-(RValue<Short4> val);
973	RValue<Short4> operator~(RValue<Short4> val);
974//	RValue<Short4> operator++(const Short4 &val, int);   // Post-increment
975//	const Short4 &operator++(const Short4 &val);   // Pre-increment
976//	RValue<Short4> operator--(const Short4 &val, int);   // Post-decrement
977//	const Short4 &operator--(const Short4 &val);   // Pre-decrement
978//	RValue<Bool> operator<(RValue<Short4> lhs, RValue<Short4> rhs);
979//	RValue<Bool> operator<=(RValue<Short4> lhs, RValue<Short4> rhs);
980//	RValue<Bool> operator>(RValue<Short4> lhs, RValue<Short4> rhs);
981//	RValue<Bool> operator>=(RValue<Short4> lhs, RValue<Short4> rhs);
982//	RValue<Bool> operator!=(RValue<Short4> lhs, RValue<Short4> rhs);
983//	RValue<Bool> operator==(RValue<Short4> lhs, RValue<Short4> rhs);
984
985	RValue<Short4> RoundShort4(RValue<Float4> cast);
986	RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y);
987	RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y);
988	RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y);
989	RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y);
990	RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y);
991	RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y);
992	RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y);
993	RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y);
994	RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y);
995	RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select);
996	RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i);
997	RValue<Short> Extract(RValue<Short4> val, int i);
998	RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y);
999	RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y);
1000
1001	class UShort4 : public Variable<UShort4>
1002	{
1003	public:
1004		explicit UShort4(RValue<Int4> cast);
1005		explicit UShort4(RValue<Float4> cast, bool saturate = false);
1006
1007		UShort4();
1008		UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w);
1009		UShort4(RValue<UShort4> rhs);
1010		UShort4(const UShort4 &rhs);
1011		UShort4(const Reference<UShort4> &rhs);
1012		UShort4(RValue<Short4> rhs);
1013		UShort4(const Short4 &rhs);
1014		UShort4(const Reference<Short4> &rhs);
1015
1016		RValue<UShort4> operator=(RValue<UShort4> rhs) const;
1017		RValue<UShort4> operator=(const UShort4 &rhs) const;
1018		RValue<UShort4> operator=(const Reference<UShort4> &rhs) const;
1019		RValue<UShort4> operator=(RValue<Short4> rhs) const;
1020		RValue<UShort4> operator=(const Short4 &rhs) const;
1021		RValue<UShort4> operator=(const Reference<Short4> &rhs) const;
1022
1023		static llvm::Type *getType();
1024	};
1025
1026	RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs);
1027	RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs);
1028	RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs);
1029//	RValue<UShort4> operator/(RValue<UShort4> lhs, RValue<UShort4> rhs);
1030//	RValue<UShort4> operator%(RValue<UShort4> lhs, RValue<UShort4> rhs);
1031//	RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs);
1032//	RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs);
1033//	RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs);
1034	RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs);
1035	RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs);
1036	RValue<UShort4> operator<<(RValue<UShort4> lhs, RValue<Long1> rhs);
1037	RValue<UShort4> operator>>(RValue<UShort4> lhs, RValue<Long1> rhs);
1038//	RValue<UShort4> operator+=(const UShort4 &lhs, RValue<UShort4> rhs);
1039//	RValue<UShort4> operator-=(const UShort4 &lhs, RValue<UShort4> rhs);
1040//	RValue<UShort4> operator*=(const UShort4 &lhs, RValue<UShort4> rhs);
1041//	RValue<UShort4> operator/=(const UShort4 &lhs, RValue<UShort4> rhs);
1042//	RValue<UShort4> operator%=(const UShort4 &lhs, RValue<UShort4> rhs);
1043//	RValue<UShort4> operator&=(const UShort4 &lhs, RValue<UShort4> rhs);
1044//	RValue<UShort4> operator|=(const UShort4 &lhs, RValue<UShort4> rhs);
1045//	RValue<UShort4> operator^=(const UShort4 &lhs, RValue<UShort4> rhs);
1046	RValue<UShort4> operator<<=(const UShort4 &lhs, unsigned char rhs);
1047	RValue<UShort4> operator>>=(const UShort4 &lhs, unsigned char rhs);
1048	RValue<UShort4> operator<<=(const UShort4 &lhs, RValue<Long1> rhs);
1049	RValue<UShort4> operator>>=(const UShort4 &lhs, RValue<Long1> rhs);
1050//	RValue<UShort4> operator+(RValue<UShort4> val);
1051//	RValue<UShort4> operator-(RValue<UShort4> val);
1052	RValue<UShort4> operator~(RValue<UShort4> val);
1053//	RValue<UShort4> operator++(const UShort4 &val, int);   // Post-increment
1054//	const UShort4 &operator++(const UShort4 &val);   // Pre-increment
1055//	RValue<UShort4> operator--(const UShort4 &val, int);   // Post-decrement
1056//	const UShort4 &operator--(const UShort4 &val);   // Pre-decrement
1057
1058	RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y);
1059	RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y);
1060	RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y);
1061	RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y);
1062	RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y);
1063	RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y);
1064	RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y);
1065
1066	class Short8 : public Variable<Short8>
1067	{
1068	public:
1069	//	Short8();
1070		Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7);
1071		Short8(RValue<Short8> rhs);
1072	//	Short8(const Short8 &rhs);
1073	//	Short8(const Reference<Short8> &rhs);
1074		Short8(RValue<Short4> lo, RValue<Short4> hi);
1075
1076	//	RValue<Short8> operator=(RValue<Short8> rhs) const;
1077	//	RValue<Short8> operator=(const Short8 &rhs) const;
1078	//	RValue<Short8> operator=(const Reference<Short8> &rhs) const;
1079
1080		static llvm::Type *getType();
1081	};
1082
1083	RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs);
1084//	RValue<Short8> operator-(RValue<Short8> lhs, RValue<Short8> rhs);
1085//	RValue<Short8> operator*(RValue<Short8> lhs, RValue<Short8> rhs);
1086//	RValue<Short8> operator/(RValue<Short8> lhs, RValue<Short8> rhs);
1087//	RValue<Short8> operator%(RValue<Short8> lhs, RValue<Short8> rhs);
1088	RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs);
1089//	RValue<Short8> operator|(RValue<Short8> lhs, RValue<Short8> rhs);
1090//	RValue<Short8> operator^(RValue<Short8> lhs, RValue<Short8> rhs);
1091	RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs);
1092	RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs);
1093//	RValue<Short8> operator<<(RValue<Short8> lhs, RValue<Short8> rhs);
1094//	RValue<Short8> operator>>(RValue<Short8> lhs, RValue<Short8> rhs);
1095//	RValue<Short8> operator+=(const Short8 &lhs, RValue<Short8> rhs);
1096//	RValue<Short8> operator-=(const Short8 &lhs, RValue<Short8> rhs);
1097//	RValue<Short8> operator*=(const Short8 &lhs, RValue<Short8> rhs);
1098//	RValue<Short8> operator/=(const Short8 &lhs, RValue<Short8> rhs);
1099//	RValue<Short8> operator%=(const Short8 &lhs, RValue<Short8> rhs);
1100//	RValue<Short8> operator&=(const Short8 &lhs, RValue<Short8> rhs);
1101//	RValue<Short8> operator|=(const Short8 &lhs, RValue<Short8> rhs);
1102//	RValue<Short8> operator^=(const Short8 &lhs, RValue<Short8> rhs);
1103//	RValue<Short8> operator<<=(const Short8 &lhs, RValue<Short8> rhs);
1104//	RValue<Short8> operator>>=(const Short8 &lhs, RValue<Short8> rhs);
1105//	RValue<Short8> operator+(RValue<Short8> val);
1106//	RValue<Short8> operator-(RValue<Short8> val);
1107//	RValue<Short8> operator~(RValue<Short8> val);
1108//	RValue<Short8> operator++(const Short8 &val, int);   // Post-increment
1109//	const Short8 &operator++(const Short8 &val);   // Pre-increment
1110//	RValue<Short8> operator--(const Short8 &val, int);   // Post-decrement
1111//	const Short8 &operator--(const Short8 &val);   // Pre-decrement
1112//	RValue<Bool> operator<(RValue<Short8> lhs, RValue<Short8> rhs);
1113//	RValue<Bool> operator<=(RValue<Short8> lhs, RValue<Short8> rhs);
1114//	RValue<Bool> operator>(RValue<Short8> lhs, RValue<Short8> rhs);
1115//	RValue<Bool> operator>=(RValue<Short8> lhs, RValue<Short8> rhs);
1116//	RValue<Bool> operator!=(RValue<Short8> lhs, RValue<Short8> rhs);
1117//	RValue<Bool> operator==(RValue<Short8> lhs, RValue<Short8> rhs);
1118
1119	RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y);
1120	RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y);
1121	RValue<Int4> Abs(RValue<Int4> x);
1122
1123	class UShort8 : public Variable<UShort8>
1124	{
1125	public:
1126	//	UShort8();
1127		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);
1128		UShort8(RValue<UShort8> rhs);
1129	//	UShort8(const UShort8 &rhs);
1130	//	UShort8(const Reference<UShort8> &rhs);
1131		UShort8(RValue<UShort4> lo, RValue<UShort4> hi);
1132
1133		RValue<UShort8> operator=(RValue<UShort8> rhs) const;
1134		RValue<UShort8> operator=(const UShort8 &rhs) const;
1135		RValue<UShort8> operator=(const Reference<UShort8> &rhs) const;
1136
1137		static llvm::Type *getType();
1138	};
1139
1140	RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs);
1141//	RValue<UShort8> operator-(RValue<UShort8> lhs, RValue<UShort8> rhs);
1142	RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs);
1143//	RValue<UShort8> operator/(RValue<UShort8> lhs, RValue<UShort8> rhs);
1144//	RValue<UShort8> operator%(RValue<UShort8> lhs, RValue<UShort8> rhs);
1145	RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs);
1146//	RValue<UShort8> operator|(RValue<UShort8> lhs, RValue<UShort8> rhs);
1147//	RValue<UShort8> operator^(RValue<UShort8> lhs, RValue<UShort8> rhs);
1148	RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs);
1149	RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs);
1150//	RValue<UShort8> operator<<(RValue<UShort8> lhs, RValue<UShort8> rhs);
1151//	RValue<UShort8> operator>>(RValue<UShort8> lhs, RValue<UShort8> rhs);
1152	RValue<UShort8> operator+=(const UShort8 &lhs, RValue<UShort8> rhs);
1153//	RValue<UShort8> operator-=(const UShort8 &lhs, RValue<UShort8> rhs);
1154//	RValue<UShort8> operator*=(const UShort8 &lhs, RValue<UShort8> rhs);
1155//	RValue<UShort8> operator/=(const UShort8 &lhs, RValue<UShort8> rhs);
1156//	RValue<UShort8> operator%=(const UShort8 &lhs, RValue<UShort8> rhs);
1157//	RValue<UShort8> operator&=(const UShort8 &lhs, RValue<UShort8> rhs);
1158//	RValue<UShort8> operator|=(const UShort8 &lhs, RValue<UShort8> rhs);
1159//	RValue<UShort8> operator^=(const UShort8 &lhs, RValue<UShort8> rhs);
1160//	RValue<UShort8> operator<<=(const UShort8 &lhs, RValue<UShort8> rhs);
1161//	RValue<UShort8> operator>>=(const UShort8 &lhs, RValue<UShort8> rhs);
1162//	RValue<UShort8> operator+(RValue<UShort8> val);
1163//	RValue<UShort8> operator-(RValue<UShort8> val);
1164	RValue<UShort8> operator~(RValue<UShort8> val);
1165//	RValue<UShort8> operator++(const UShort8 &val, int);   // Post-increment
1166//	const UShort8 &operator++(const UShort8 &val);   // Pre-increment
1167//	RValue<UShort8> operator--(const UShort8 &val, int);   // Post-decrement
1168//	const UShort8 &operator--(const UShort8 &val);   // Pre-decrement
1169//	RValue<Bool> operator<(RValue<UShort8> lhs, RValue<UShort8> rhs);
1170//	RValue<Bool> operator<=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1171//	RValue<Bool> operator>(RValue<UShort8> lhs, RValue<UShort8> rhs);
1172//	RValue<Bool> operator>=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1173//	RValue<Bool> operator!=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1174//	RValue<Bool> operator==(RValue<UShort8> lhs, RValue<UShort8> rhs);
1175
1176	RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7);
1177	RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y);
1178
1179	class Int : public Variable<Int>
1180	{
1181	public:
1182		Int(Argument<Int> argument);
1183
1184		explicit Int(RValue<Byte> cast);
1185		explicit Int(RValue<SByte> cast);
1186		explicit Int(RValue<Short> cast);
1187		explicit Int(RValue<UShort> cast);
1188		explicit Int(RValue<Int2> cast);
1189		explicit Int(RValue<Long> cast);
1190		explicit Int(RValue<Float> cast);
1191
1192		Int();
1193		Int(int x);
1194		Int(RValue<Int> rhs);
1195		Int(RValue<UInt> rhs);
1196		Int(const Int &rhs);
1197		Int(const UInt &rhs);
1198		Int(const Reference<Int> &rhs);
1199		Int(const Reference<UInt> &rhs);
1200
1201		RValue<Int> operator=(int rhs) const;
1202		RValue<Int> operator=(RValue<Int> rhs) const;
1203		RValue<Int> operator=(RValue<UInt> rhs) const;
1204		RValue<Int> operator=(const Int &rhs) const;
1205		RValue<Int> operator=(const UInt &rhs) const;
1206		RValue<Int> operator=(const Reference<Int> &rhs) const;
1207		RValue<Int> operator=(const Reference<UInt> &rhs) const;
1208
1209		static llvm::Type *getType();
1210	};
1211
1212	RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs);
1213	RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs);
1214	RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs);
1215	RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs);
1216	RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs);
1217	RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs);
1218	RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs);
1219	RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs);
1220	RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs);
1221	RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs);
1222	RValue<Int> operator+=(const Int &lhs, RValue<Int> rhs);
1223	RValue<Int> operator-=(const Int &lhs, RValue<Int> rhs);
1224	RValue<Int> operator*=(const Int &lhs, RValue<Int> rhs);
1225	RValue<Int> operator/=(const Int &lhs, RValue<Int> rhs);
1226	RValue<Int> operator%=(const Int &lhs, RValue<Int> rhs);
1227	RValue<Int> operator&=(const Int &lhs, RValue<Int> rhs);
1228	RValue<Int> operator|=(const Int &lhs, RValue<Int> rhs);
1229	RValue<Int> operator^=(const Int &lhs, RValue<Int> rhs);
1230	RValue<Int> operator<<=(const Int &lhs, RValue<Int> rhs);
1231	RValue<Int> operator>>=(const Int &lhs, RValue<Int> rhs);
1232	RValue<Int> operator+(RValue<Int> val);
1233	RValue<Int> operator-(RValue<Int> val);
1234	RValue<Int> operator~(RValue<Int> val);
1235	RValue<Int> operator++(const Int &val, int);   // Post-increment
1236	const Int &operator++(const Int &val);   // Pre-increment
1237	RValue<Int> operator--(const Int &val, int);   // Post-decrement
1238	const Int &operator--(const Int &val);   // Pre-decrement
1239	RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs);
1240	RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs);
1241	RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs);
1242	RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs);
1243	RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs);
1244	RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs);
1245
1246	RValue<Int> Max(RValue<Int> x, RValue<Int> y);
1247	RValue<Int> Min(RValue<Int> x, RValue<Int> y);
1248	RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max);
1249	RValue<Int> RoundInt(RValue<Float> cast);
1250
1251	class Long : public Variable<Long>
1252	{
1253	public:
1254	//	Long(Argument<Long> argument);
1255
1256	//	explicit Long(RValue<Short> cast);
1257	//	explicit Long(RValue<UShort> cast);
1258		explicit Long(RValue<Int> cast);
1259		explicit Long(RValue<UInt> cast);
1260	//	explicit Long(RValue<Float> cast);
1261
1262		Long();
1263	//	Long(qword x);
1264		Long(RValue<Long> rhs);
1265	//	Long(RValue<ULong> rhs);
1266	//	Long(const Long &rhs);
1267	//	Long(const Reference<Long> &rhs);
1268	//	Long(const ULong &rhs);
1269	//	Long(const Reference<ULong> &rhs);
1270
1271		RValue<Long> operator=(int64_t rhs) const;
1272		RValue<Long> operator=(RValue<Long> rhs) const;
1273	//	RValue<Long> operator=(RValue<ULong> rhs) const;
1274		RValue<Long> operator=(const Long &rhs) const;
1275		RValue<Long> operator=(const Reference<Long> &rhs) const;
1276	//	RValue<Long> operator=(const ULong &rhs) const;
1277	//	RValue<Long> operator=(const Reference<ULong> &rhs) const;
1278
1279		static llvm::Type *getType();
1280	};
1281
1282	RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs);
1283	RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs);
1284//	RValue<Long> operator*(RValue<Long> lhs, RValue<Long> rhs);
1285//	RValue<Long> operator/(RValue<Long> lhs, RValue<Long> rhs);
1286//	RValue<Long> operator%(RValue<Long> lhs, RValue<Long> rhs);
1287//	RValue<Long> operator&(RValue<Long> lhs, RValue<Long> rhs);
1288//	RValue<Long> operator|(RValue<Long> lhs, RValue<Long> rhs);
1289//	RValue<Long> operator^(RValue<Long> lhs, RValue<Long> rhs);
1290//	RValue<Long> operator<<(RValue<Long> lhs, RValue<Long> rhs);
1291//	RValue<Long> operator>>(RValue<Long> lhs, RValue<Long> rhs);
1292	RValue<Long> operator+=(const Long &lhs, RValue<Long> rhs);
1293	RValue<Long> operator-=(const Long &lhs, RValue<Long> rhs);
1294//	RValue<Long> operator*=(const Long &lhs, RValue<Long> rhs);
1295//	RValue<Long> operator/=(const Long &lhs, RValue<Long> rhs);
1296//	RValue<Long> operator%=(const Long &lhs, RValue<Long> rhs);
1297//	RValue<Long> operator&=(const Long &lhs, RValue<Long> rhs);
1298//	RValue<Long> operator|=(const Long &lhs, RValue<Long> rhs);
1299//	RValue<Long> operator^=(const Long &lhs, RValue<Long> rhs);
1300//	RValue<Long> operator<<=(const Long &lhs, RValue<Long> rhs);
1301//	RValue<Long> operator>>=(const Long &lhs, RValue<Long> rhs);
1302//	RValue<Long> operator+(RValue<Long> val);
1303//	RValue<Long> operator-(RValue<Long> val);
1304//	RValue<Long> operator~(RValue<Long> val);
1305//	RValue<Long> operator++(const Long &val, int);   // Post-increment
1306//	const Long &operator++(const Long &val);   // Pre-increment
1307//	RValue<Long> operator--(const Long &val, int);   // Post-decrement
1308//	const Long &operator--(const Long &val);   // Pre-decrement
1309//	RValue<Bool> operator<(RValue<Long> lhs, RValue<Long> rhs);
1310//	RValue<Bool> operator<=(RValue<Long> lhs, RValue<Long> rhs);
1311//	RValue<Bool> operator>(RValue<Long> lhs, RValue<Long> rhs);
1312//	RValue<Bool> operator>=(RValue<Long> lhs, RValue<Long> rhs);
1313//	RValue<Bool> operator!=(RValue<Long> lhs, RValue<Long> rhs);
1314//	RValue<Bool> operator==(RValue<Long> lhs, RValue<Long> rhs);
1315
1316//	RValue<Long> RoundLong(RValue<Float> cast);
1317	RValue<Long> AddAtomic( RValue<Pointer<Long>> x, RValue<Long> y);
1318
1319	class Long1 : public Variable<Long1>
1320	{
1321	public:
1322	//	Long1(Argument<Long1> argument);
1323
1324	//	explicit Long1(RValue<Short> cast);
1325	//	explicit Long1(RValue<UShort> cast);
1326	//	explicit Long1(RValue<Int> cast);
1327		explicit Long1(RValue<UInt> cast);
1328	//	explicit Long1(RValue<Float> cast);
1329
1330	//	Long1();
1331	//	Long1(qword x);
1332		Long1(RValue<Long1> rhs);
1333	//	Long1(RValue<ULong1> rhs);
1334	//	Long1(const Long1 &rhs);
1335	//	Long1(const Reference<Long1> &rhs);
1336	//	Long1(const ULong1 &rhs);
1337	//	Long1(const Reference<ULong1> &rhs);
1338
1339	//	RValue<Long1> operator=(qword rhs) const;
1340	//	RValue<Long1> operator=(RValue<Long1> rhs) const;
1341	//	RValue<Long1> operator=(RValue<ULong1> rhs) const;
1342	//	RValue<Long1> operator=(const Long1 &rhs) const;
1343	//	RValue<Long1> operator=(const Reference<Long1> &rhs) const;
1344	//	RValue<Long1> operator=(const ULong1 &rhs) const;
1345	//	RValue<Long1> operator=(const Reference<ULong1> &rhs) const;
1346
1347		static llvm::Type *getType();
1348	};
1349
1350//	RValue<Long1> operator+(RValue<Long1> lhs, RValue<Long1> rhs);
1351//	RValue<Long1> operator-(RValue<Long1> lhs, RValue<Long1> rhs);
1352//	RValue<Long1> operator*(RValue<Long1> lhs, RValue<Long1> rhs);
1353//	RValue<Long1> operator/(RValue<Long1> lhs, RValue<Long1> rhs);
1354//	RValue<Long1> operator%(RValue<Long1> lhs, RValue<Long1> rhs);
1355//	RValue<Long1> operator&(RValue<Long1> lhs, RValue<Long1> rhs);
1356//	RValue<Long1> operator|(RValue<Long1> lhs, RValue<Long1> rhs);
1357//	RValue<Long1> operator^(RValue<Long1> lhs, RValue<Long1> rhs);
1358//	RValue<Long1> operator<<(RValue<Long1> lhs, RValue<Long1> rhs);
1359//	RValue<Long1> operator>>(RValue<Long1> lhs, RValue<Long1> rhs);
1360//	RValue<Long1> operator+=(const Long1 &lhs, RValue<Long1> rhs);
1361//	RValue<Long1> operator-=(const Long1 &lhs, RValue<Long1> rhs);
1362//	RValue<Long1> operator*=(const Long1 &lhs, RValue<Long1> rhs);
1363//	RValue<Long1> operator/=(const Long1 &lhs, RValue<Long1> rhs);
1364//	RValue<Long1> operator%=(const Long1 &lhs, RValue<Long1> rhs);
1365//	RValue<Long1> operator&=(const Long1 &lhs, RValue<Long1> rhs);
1366//	RValue<Long1> operator|=(const Long1 &lhs, RValue<Long1> rhs);
1367//	RValue<Long1> operator^=(const Long1 &lhs, RValue<Long1> rhs);
1368//	RValue<Long1> operator<<=(const Long1 &lhs, RValue<Long1> rhs);
1369//	RValue<Long1> operator>>=(const Long1 &lhs, RValue<Long1> rhs);
1370//	RValue<Long1> operator+(RValue<Long1> val);
1371//	RValue<Long1> operator-(RValue<Long1> val);
1372//	RValue<Long1> operator~(RValue<Long1> val);
1373//	RValue<Long1> operator++(const Long1 &val, int);   // Post-increment
1374//	const Long1 &operator++(const Long1 &val);   // Pre-increment
1375//	RValue<Long1> operator--(const Long1 &val, int);   // Post-decrement
1376//	const Long1 &operator--(const Long1 &val);   // Pre-decrement
1377//	RValue<Bool> operator<(RValue<Long1> lhs, RValue<Long1> rhs);
1378//	RValue<Bool> operator<=(RValue<Long1> lhs, RValue<Long1> rhs);
1379//	RValue<Bool> operator>(RValue<Long1> lhs, RValue<Long1> rhs);
1380//	RValue<Bool> operator>=(RValue<Long1> lhs, RValue<Long1> rhs);
1381//	RValue<Bool> operator!=(RValue<Long1> lhs, RValue<Long1> rhs);
1382//	RValue<Bool> operator==(RValue<Long1> lhs, RValue<Long1> rhs);
1383
1384//	RValue<Long1> RoundLong1(RValue<Float> cast);
1385
1386	class Long2 : public Variable<Long2>
1387	{
1388	public:
1389	//	explicit Long2(RValue<Long> cast);
1390	//	explicit Long2(RValue<Long1> cast);
1391
1392	//	Long2();
1393	//	Long2(int x, int y);
1394	//	Long2(RValue<Long2> rhs);
1395	//	Long2(const Long2 &rhs);
1396	//	Long2(const Reference<Long2> &rhs);
1397
1398	//	RValue<Long2> operator=(RValue<Long2> rhs) const;
1399	//	RValue<Long2> operator=(const Long2 &rhs) const;
1400	//	RValue<Long2> operator=(const Reference<Long2 &rhs) const;
1401
1402		static llvm::Type *getType();
1403	};
1404
1405//	RValue<Long2> operator+(RValue<Long2> lhs, RValue<Long2> rhs);
1406//	RValue<Long2> operator-(RValue<Long2> lhs, RValue<Long2> rhs);
1407//	RValue<Long2> operator*(RValue<Long2> lhs, RValue<Long2> rhs);
1408//	RValue<Long2> operator/(RValue<Long2> lhs, RValue<Long2> rhs);
1409//	RValue<Long2> operator%(RValue<Long2> lhs, RValue<Long2> rhs);
1410//	RValue<Long2> operator&(RValue<Long2> lhs, RValue<Long2> rhs);
1411//	RValue<Long2> operator|(RValue<Long2> lhs, RValue<Long2> rhs);
1412//	RValue<Long2> operator^(RValue<Long2> lhs, RValue<Long2> rhs);
1413//	RValue<Long2> operator<<(RValue<Long2> lhs, unsigned char rhs);
1414//	RValue<Long2> operator>>(RValue<Long2> lhs, unsigned char rhs);
1415//	RValue<Long2> operator<<(RValue<Long2> lhs, RValue<Long1> rhs);
1416//	RValue<Long2> operator>>(RValue<Long2> lhs, RValue<Long1> rhs);
1417//	RValue<Long2> operator+=(const Long2 &lhs, RValue<Long2> rhs);
1418//	RValue<Long2> operator-=(const Long2 &lhs, RValue<Long2> rhs);
1419//	RValue<Long2> operator*=(const Long2 &lhs, RValue<Long2> rhs);
1420//	RValue<Long2> operator/=(const Long2 &lhs, RValue<Long2> rhs);
1421//	RValue<Long2> operator%=(const Long2 &lhs, RValue<Long2> rhs);
1422//	RValue<Long2> operator&=(const Long2 &lhs, RValue<Long2> rhs);
1423//	RValue<Long2> operator|=(const Long2 &lhs, RValue<Long2> rhs);
1424//	RValue<Long2> operator^=(const Long2 &lhs, RValue<Long2> rhs);
1425//	RValue<Long2> operator<<=(const Long2 &lhs, unsigned char rhs);
1426//	RValue<Long2> operator>>=(const Long2 &lhs, unsigned char rhs);
1427//	RValue<Long2> operator<<=(const Long2 &lhs, RValue<Long1> rhs);
1428//	RValue<Long2> operator>>=(const Long2 &lhs, RValue<Long1> rhs);
1429//	RValue<Long2> operator+(RValue<Long2> val);
1430//	RValue<Long2> operator-(RValue<Long2> val);
1431//	RValue<Long2> operator~(RValue<Long2> val);
1432//	RValue<Long2> operator++(const Long2 &val, int);   // Post-increment
1433//	const Long2 &operator++(const Long2 &val);   // Pre-increment
1434//	RValue<Long2> operator--(const Long2 &val, int);   // Post-decrement
1435//	const Long2 &operator--(const Long2 &val);   // Pre-decrement
1436//	RValue<Bool> operator<(RValue<Long2> lhs, RValue<Long2> rhs);
1437//	RValue<Bool> operator<=(RValue<Long2> lhs, RValue<Long2> rhs);
1438//	RValue<Bool> operator>(RValue<Long2> lhs, RValue<Long2> rhs);
1439//	RValue<Bool> operator>=(RValue<Long2> lhs, RValue<Long2> rhs);
1440//	RValue<Bool> operator!=(RValue<Long2> lhs, RValue<Long2> rhs);
1441//	RValue<Bool> operator==(RValue<Long2> lhs, RValue<Long2> rhs);
1442
1443//	RValue<Long2> RoundInt(RValue<Float4> cast);
1444//	RValue<Long2> UnpackLow(RValue<Long2> x, RValue<Long2> y);
1445	RValue<Long2> UnpackHigh(RValue<Long2> x, RValue<Long2> y);
1446//	RValue<Int> Extract(RValue<Long2> val, int i);
1447//	RValue<Long2> Insert(RValue<Long2> val, RValue<Int> element, int i);
1448
1449	class UInt : public Variable<UInt>
1450	{
1451	public:
1452		UInt(Argument<UInt> argument);
1453
1454		explicit UInt(RValue<UShort> cast);
1455		explicit UInt(RValue<Long> cast);
1456		explicit UInt(RValue<Float> cast);
1457
1458		UInt();
1459		UInt(int x);
1460		UInt(unsigned int x);
1461		UInt(RValue<UInt> rhs);
1462		UInt(RValue<Int> rhs);
1463		UInt(const UInt &rhs);
1464		UInt(const Int &rhs);
1465		UInt(const Reference<UInt> &rhs);
1466		UInt(const Reference<Int> &rhs);
1467
1468		RValue<UInt> operator=(unsigned int rhs) const;
1469		RValue<UInt> operator=(RValue<UInt> rhs) const;
1470		RValue<UInt> operator=(RValue<Int> rhs) const;
1471		RValue<UInt> operator=(const UInt &rhs) const;
1472		RValue<UInt> operator=(const Int &rhs) const;
1473		RValue<UInt> operator=(const Reference<UInt> &rhs) const;
1474		RValue<UInt> operator=(const Reference<Int> &rhs) const;
1475
1476		static llvm::Type *getType();
1477	};
1478
1479	RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs);
1480	RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs);
1481	RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs);
1482	RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs);
1483	RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs);
1484	RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs);
1485	RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs);
1486	RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs);
1487	RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs);
1488	RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs);
1489	RValue<UInt> operator+=(const UInt &lhs, RValue<UInt> rhs);
1490	RValue<UInt> operator-=(const UInt &lhs, RValue<UInt> rhs);
1491	RValue<UInt> operator*=(const UInt &lhs, RValue<UInt> rhs);
1492	RValue<UInt> operator/=(const UInt &lhs, RValue<UInt> rhs);
1493	RValue<UInt> operator%=(const UInt &lhs, RValue<UInt> rhs);
1494	RValue<UInt> operator&=(const UInt &lhs, RValue<UInt> rhs);
1495	RValue<UInt> operator|=(const UInt &lhs, RValue<UInt> rhs);
1496	RValue<UInt> operator^=(const UInt &lhs, RValue<UInt> rhs);
1497	RValue<UInt> operator<<=(const UInt &lhs, RValue<UInt> rhs);
1498	RValue<UInt> operator>>=(const UInt &lhs, RValue<UInt> rhs);
1499	RValue<UInt> operator+(RValue<UInt> val);
1500	RValue<UInt> operator-(RValue<UInt> val);
1501	RValue<UInt> operator~(RValue<UInt> val);
1502	RValue<UInt> operator++(const UInt &val, int);   // Post-increment
1503	const UInt &operator++(const UInt &val);   // Pre-increment
1504	RValue<UInt> operator--(const UInt &val, int);   // Post-decrement
1505	const UInt &operator--(const UInt &val);   // Pre-decrement
1506	RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs);
1507	RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs);
1508	RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs);
1509	RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs);
1510	RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs);
1511	RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs);
1512
1513	RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y);
1514	RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y);
1515	RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max);
1516//	RValue<UInt> RoundUInt(RValue<Float> cast);
1517
1518	class Int2 : public Variable<Int2>
1519	{
1520	public:
1521	//	explicit Int2(RValue<Int> cast);
1522		explicit Int2(RValue<Int4> cast);
1523
1524		Int2();
1525		Int2(int x, int y);
1526		Int2(RValue<Int2> rhs);
1527		Int2(const Int2 &rhs);
1528		Int2(const Reference<Int2> &rhs);
1529		Int2(RValue<Int> lo, RValue<Int> hi);
1530
1531		RValue<Int2> operator=(RValue<Int2> rhs) const;
1532		RValue<Int2> operator=(const Int2 &rhs) const;
1533		RValue<Int2> operator=(const Reference<Int2> &rhs) const;
1534
1535		static llvm::Type *getType();
1536	};
1537
1538	RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs);
1539	RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs);
1540//	RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs);
1541//	RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs);
1542//	RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs);
1543	RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs);
1544	RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs);
1545	RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs);
1546	RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs);
1547	RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs);
1548	RValue<Int2> operator<<(RValue<Int2> lhs, RValue<Long1> rhs);
1549	RValue<Int2> operator>>(RValue<Int2> lhs, RValue<Long1> rhs);
1550	RValue<Int2> operator+=(const Int2 &lhs, RValue<Int2> rhs);
1551	RValue<Int2> operator-=(const Int2 &lhs, RValue<Int2> rhs);
1552//	RValue<Int2> operator*=(const Int2 &lhs, RValue<Int2> rhs);
1553//	RValue<Int2> operator/=(const Int2 &lhs, RValue<Int2> rhs);
1554//	RValue<Int2> operator%=(const Int2 &lhs, RValue<Int2> rhs);
1555	RValue<Int2> operator&=(const Int2 &lhs, RValue<Int2> rhs);
1556	RValue<Int2> operator|=(const Int2 &lhs, RValue<Int2> rhs);
1557	RValue<Int2> operator^=(const Int2 &lhs, RValue<Int2> rhs);
1558	RValue<Int2> operator<<=(const Int2 &lhs, unsigned char rhs);
1559	RValue<Int2> operator>>=(const Int2 &lhs, unsigned char rhs);
1560	RValue<Int2> operator<<=(const Int2 &lhs, RValue<Long1> rhs);
1561	RValue<Int2> operator>>=(const Int2 &lhs, RValue<Long1> rhs);
1562//	RValue<Int2> operator+(RValue<Int2> val);
1563//	RValue<Int2> operator-(RValue<Int2> val);
1564	RValue<Int2> operator~(RValue<Int2> val);
1565//	RValue<Int2> operator++(const Int2 &val, int);   // Post-increment
1566//	const Int2 &operator++(const Int2 &val);   // Pre-increment
1567//	RValue<Int2> operator--(const Int2 &val, int);   // Post-decrement
1568//	const Int2 &operator--(const Int2 &val);   // Pre-decrement
1569//	RValue<Bool> operator<(RValue<Int2> lhs, RValue<Int2> rhs);
1570//	RValue<Bool> operator<=(RValue<Int2> lhs, RValue<Int2> rhs);
1571//	RValue<Bool> operator>(RValue<Int2> lhs, RValue<Int2> rhs);
1572//	RValue<Bool> operator>=(RValue<Int2> lhs, RValue<Int2> rhs);
1573//	RValue<Bool> operator!=(RValue<Int2> lhs, RValue<Int2> rhs);
1574//	RValue<Bool> operator==(RValue<Int2> lhs, RValue<Int2> rhs);
1575
1576//	RValue<Int2> RoundInt(RValue<Float4> cast);
1577	RValue<Long1> UnpackLow(RValue<Int2> x, RValue<Int2> y);
1578	RValue<Long1> UnpackHigh(RValue<Int2> x, RValue<Int2> y);
1579	RValue<Int> Extract(RValue<Int2> val, int i);
1580	RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i);
1581
1582	class UInt2 : public Variable<UInt2>
1583	{
1584	public:
1585		UInt2();
1586		UInt2(unsigned int x, unsigned int y);
1587		UInt2(RValue<UInt2> rhs);
1588		UInt2(const UInt2 &rhs);
1589		UInt2(const Reference<UInt2> &rhs);
1590
1591		RValue<UInt2> operator=(RValue<UInt2> rhs) const;
1592		RValue<UInt2> operator=(const UInt2 &rhs) const;
1593		RValue<UInt2> operator=(const Reference<UInt2> &rhs) const;
1594
1595		static llvm::Type *getType();
1596	};
1597
1598	RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs);
1599	RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs);
1600//	RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs);
1601//	RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs);
1602//	RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs);
1603	RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs);
1604	RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs);
1605	RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs);
1606	RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs);
1607	RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs);
1608	RValue<UInt2> operator<<(RValue<UInt2> lhs, RValue<Long1> rhs);
1609	RValue<UInt2> operator>>(RValue<UInt2> lhs, RValue<Long1> rhs);
1610	RValue<UInt2> operator+=(const UInt2 &lhs, RValue<UInt2> rhs);
1611	RValue<UInt2> operator-=(const UInt2 &lhs, RValue<UInt2> rhs);
1612//	RValue<UInt2> operator*=(const UInt2 &lhs, RValue<UInt2> rhs);
1613//	RValue<UInt2> operator/=(const UInt2 &lhs, RValue<UInt2> rhs);
1614//	RValue<UInt2> operator%=(const UInt2 &lhs, RValue<UInt2> rhs);
1615	RValue<UInt2> operator&=(const UInt2 &lhs, RValue<UInt2> rhs);
1616	RValue<UInt2> operator|=(const UInt2 &lhs, RValue<UInt2> rhs);
1617	RValue<UInt2> operator^=(const UInt2 &lhs, RValue<UInt2> rhs);
1618	RValue<UInt2> operator<<=(const UInt2 &lhs, unsigned char rhs);
1619	RValue<UInt2> operator>>=(const UInt2 &lhs, unsigned char rhs);
1620	RValue<UInt2> operator<<=(const UInt2 &lhs, RValue<Long1> rhs);
1621	RValue<UInt2> operator>>=(const UInt2 &lhs, RValue<Long1> rhs);
1622//	RValue<UInt2> operator+(RValue<UInt2> val);
1623//	RValue<UInt2> operator-(RValue<UInt2> val);
1624	RValue<UInt2> operator~(RValue<UInt2> val);
1625//	RValue<UInt2> operator++(const UInt2 &val, int);   // Post-increment
1626//	const UInt2 &operator++(const UInt2 &val);   // Pre-increment
1627//	RValue<UInt2> operator--(const UInt2 &val, int);   // Post-decrement
1628//	const UInt2 &operator--(const UInt2 &val);   // Pre-decrement
1629//	RValue<Bool> operator<(RValue<UInt2> lhs, RValue<UInt2> rhs);
1630//	RValue<Bool> operator<=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1631//	RValue<Bool> operator>(RValue<UInt2> lhs, RValue<UInt2> rhs);
1632//	RValue<Bool> operator>=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1633//	RValue<Bool> operator!=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1634//	RValue<Bool> operator==(RValue<UInt2> lhs, RValue<UInt2> rhs);
1635
1636//	RValue<UInt2> RoundInt(RValue<Float4> cast);
1637
1638	class Int4 : public Variable<Int4>
1639	{
1640	public:
1641		explicit Int4(RValue<Float4> cast);
1642		explicit Int4(RValue<Short4> cast);
1643		explicit Int4(RValue<UShort4> cast);
1644
1645		Int4();
1646		Int4(int xyzw);
1647		Int4(int x, int yzw);
1648		Int4(int x, int y, int zw);
1649		Int4(int x, int y, int z, int w);
1650		Int4(RValue<Int4> rhs);
1651		Int4(const Int4 &rhs);
1652		Int4(const Reference<Int4> &rhs);
1653		Int4(RValue<UInt4> rhs);
1654		Int4(const UInt4 &rhs);
1655		Int4(const Reference<UInt4> &rhs);
1656		Int4(RValue<Int2> lo, RValue<Int2> hi);
1657
1658		RValue<Int4> operator=(RValue<Int4> rhs) const;
1659		RValue<Int4> operator=(const Int4 &rhs) const;
1660		RValue<Int4> operator=(const Reference<Int4> &rhs) const;
1661
1662		static llvm::Type *getType();
1663
1664	private:
1665		void constant(int x, int y, int z, int w);
1666	};
1667
1668	RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs);
1669	RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs);
1670	RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs);
1671	RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs);
1672	RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs);
1673	RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs);
1674	RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs);
1675	RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs);
1676	RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs);
1677	RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs);
1678	RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs);
1679	RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs);
1680	RValue<Int4> operator+=(const Int4 &lhs, RValue<Int4> rhs);
1681	RValue<Int4> operator-=(const Int4 &lhs, RValue<Int4> rhs);
1682	RValue<Int4> operator*=(const Int4 &lhs, RValue<Int4> rhs);
1683//	RValue<Int4> operator/=(const Int4 &lhs, RValue<Int4> rhs);
1684//	RValue<Int4> operator%=(const Int4 &lhs, RValue<Int4> rhs);
1685	RValue<Int4> operator&=(const Int4 &lhs, RValue<Int4> rhs);
1686	RValue<Int4> operator|=(const Int4 &lhs, RValue<Int4> rhs);
1687	RValue<Int4> operator^=(const Int4 &lhs, RValue<Int4> rhs);
1688	RValue<Int4> operator<<=(const Int4 &lhs, unsigned char rhs);
1689	RValue<Int4> operator>>=(const Int4 &lhs, unsigned char rhs);
1690	RValue<Int4> operator+(RValue<Int4> val);
1691	RValue<Int4> operator-(RValue<Int4> val);
1692	RValue<Int4> operator~(RValue<Int4> val);
1693//	RValue<Int4> operator++(const Int4 &val, int);   // Post-increment
1694//	const Int4 &operator++(const Int4 &val);   // Pre-increment
1695//	RValue<Int4> operator--(const Int4 &val, int);   // Post-decrement
1696//	const Int4 &operator--(const Int4 &val);   // Pre-decrement
1697//	RValue<Bool> operator<(RValue<Int4> lhs, RValue<Int4> rhs);
1698//	RValue<Bool> operator<=(RValue<Int4> lhs, RValue<Int4> rhs);
1699//	RValue<Bool> operator>(RValue<Int4> lhs, RValue<Int4> rhs);
1700//	RValue<Bool> operator>=(RValue<Int4> lhs, RValue<Int4> rhs);
1701//	RValue<Bool> operator!=(RValue<Int4> lhs, RValue<Int4> rhs);
1702//	RValue<Bool> operator==(RValue<Int4> lhs, RValue<Int4> rhs);
1703
1704	RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y);
1705	RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y);
1706	RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y);
1707	RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y);
1708	RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y);
1709	RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y);
1710	RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y);
1711	RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y);
1712	RValue<Int4> RoundInt(RValue<Float4> cast);
1713	RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y);
1714	RValue<Int> Extract(RValue<Int4> x, int i);
1715	RValue<Int4> Insert(RValue<Int4> val, RValue<Int> element, int i);
1716	RValue<Int> SignMask(RValue<Int4> x);
1717	RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select);
1718
1719	class UInt4 : public Variable<UInt4>
1720	{
1721	public:
1722		explicit UInt4(RValue<Float4> cast);
1723
1724		UInt4();
1725		UInt4(int xyzw);
1726		UInt4(int x, int yzw);
1727		UInt4(int x, int y, int zw);
1728		UInt4(int x, int y, int z, int w);
1729		UInt4(unsigned int x, unsigned int y, unsigned int z, unsigned int w);
1730		UInt4(RValue<UInt4> rhs);
1731		UInt4(const UInt4 &rhs);
1732		UInt4(const Reference<UInt4> &rhs);
1733		UInt4(RValue<Int4> rhs);
1734		UInt4(const Int4 &rhs);
1735		UInt4(const Reference<Int4> &rhs);
1736		UInt4(RValue<UInt2> lo, RValue<UInt2> hi);
1737
1738		RValue<UInt4> operator=(RValue<UInt4> rhs) const;
1739		RValue<UInt4> operator=(const UInt4 &rhs) const;
1740		RValue<UInt4> operator=(const Reference<UInt4> &rhs) const;
1741
1742		static llvm::Type *getType();
1743
1744	private:
1745		void constant(int x, int y, int z, int w);
1746	};
1747
1748	RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs);
1749	RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs);
1750	RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs);
1751	RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs);
1752	RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs);
1753	RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs);
1754	RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs);
1755	RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs);
1756	RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs);
1757	RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs);
1758	RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs);
1759	RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs);
1760	RValue<UInt4> operator+=(const UInt4 &lhs, RValue<UInt4> rhs);
1761	RValue<UInt4> operator-=(const UInt4 &lhs, RValue<UInt4> rhs);
1762	RValue<UInt4> operator*=(const UInt4 &lhs, RValue<UInt4> rhs);
1763//	RValue<UInt4> operator/=(const UInt4 &lhs, RValue<UInt4> rhs);
1764//	RValue<UInt4> operator%=(const UInt4 &lhs, RValue<UInt4> rhs);
1765	RValue<UInt4> operator&=(const UInt4 &lhs, RValue<UInt4> rhs);
1766	RValue<UInt4> operator|=(const UInt4 &lhs, RValue<UInt4> rhs);
1767	RValue<UInt4> operator^=(const UInt4 &lhs, RValue<UInt4> rhs);
1768	RValue<UInt4> operator<<=(const UInt4 &lhs, unsigned char rhs);
1769	RValue<UInt4> operator>>=(const UInt4 &lhs, unsigned char rhs);
1770	RValue<UInt4> operator+(RValue<UInt4> val);
1771	RValue<UInt4> operator-(RValue<UInt4> val);
1772	RValue<UInt4> operator~(RValue<UInt4> val);
1773//	RValue<UInt4> operator++(const UInt4 &val, int);   // Post-increment
1774//	const UInt4 &operator++(const UInt4 &val);   // Pre-increment
1775//	RValue<UInt4> operator--(const UInt4 &val, int);   // Post-decrement
1776//	const UInt4 &operator--(const UInt4 &val);   // Pre-decrement
1777//	RValue<Bool> operator<(RValue<UInt4> lhs, RValue<UInt4> rhs);
1778//	RValue<Bool> operator<=(RValue<UInt4> lhs, RValue<UInt4> rhs);
1779//	RValue<Bool> operator>(RValue<UInt4> lhs, RValue<UInt4> rhs);
1780//	RValue<Bool> operator>=(RValue<UInt4> lhs, RValue<UInt4> rhs);
1781//	RValue<Bool> operator!=(RValue<UInt4> lhs, RValue<UInt4> rhs);
1782//	RValue<Bool> operator==(RValue<UInt4> lhs, RValue<UInt4> rhs);
1783
1784	RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y);
1785	RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y);
1786	RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y);
1787	RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y);
1788	RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y);
1789	RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y);
1790	RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y);
1791	RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y);
1792//	RValue<UInt4> RoundInt(RValue<Float4> cast);
1793	RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y);
1794
1795	template<int T>
1796	class Swizzle2Float4
1797	{
1798		friend class Float4;
1799
1800	public:
1801		operator RValue<Float4>() const;
1802
1803	private:
1804		Float4 *parent;
1805	};
1806
1807	template<int T>
1808	class SwizzleFloat4
1809	{
1810	public:
1811		operator RValue<Float4>() const;
1812
1813	private:
1814		Float4 *parent;
1815	};
1816
1817	template<int T>
1818	class SwizzleMaskFloat4
1819	{
1820		friend class Float4;
1821
1822	public:
1823		operator RValue<Float4>() const;
1824
1825		RValue<Float4> operator=(RValue<Float4> rhs) const;
1826		RValue<Float4> operator=(RValue<Float> rhs) const;
1827
1828	private:
1829		Float4 *parent;
1830	};
1831
1832	template<int T>
1833	class SwizzleMask1Float4
1834	{
1835	public:
1836		operator RValue<Float>() const;
1837		operator RValue<Float4>() const;
1838
1839		RValue<Float4> operator=(float x) const;
1840		RValue<Float4> operator=(RValue<Float4> rhs) const;
1841		RValue<Float4> operator=(RValue<Float> rhs) const;
1842
1843	private:
1844		Float4 *parent;
1845	};
1846
1847	template<int T>
1848	class SwizzleMask2Float4
1849	{
1850		friend class Float4;
1851
1852	public:
1853		operator RValue<Float4>() const;
1854
1855		RValue<Float4> operator=(RValue<Float4> rhs) const;
1856
1857	private:
1858		Float4 *parent;
1859	};
1860
1861	class Float : public Variable<Float>
1862	{
1863	public:
1864		explicit Float(RValue<Int> cast);
1865
1866		Float();
1867		Float(float x);
1868		Float(RValue<Float> rhs);
1869		Float(const Float &rhs);
1870		Float(const Reference<Float> &rhs);
1871
1872		template<int T>
1873		Float(const SwizzleMask1Float4<T> &rhs);
1874
1875	//	RValue<Float> operator=(float rhs) const;   // FIXME: Implement
1876		RValue<Float> operator=(RValue<Float> rhs) const;
1877		RValue<Float> operator=(const Float &rhs) const;
1878		RValue<Float> operator=(const Reference<Float> &rhs) const;
1879
1880		template<int T>
1881		RValue<Float> operator=(const SwizzleMask1Float4<T> &rhs) const;
1882
1883		static llvm::Type *getType();
1884	};
1885
1886	RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs);
1887	RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs);
1888	RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs);
1889	RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs);
1890	RValue<Float> operator+=(const Float &lhs, RValue<Float> rhs);
1891	RValue<Float> operator-=(const Float &lhs, RValue<Float> rhs);
1892	RValue<Float> operator*=(const Float &lhs, RValue<Float> rhs);
1893	RValue<Float> operator/=(const Float &lhs, RValue<Float> rhs);
1894	RValue<Float> operator+(RValue<Float> val);
1895	RValue<Float> operator-(RValue<Float> val);
1896	RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs);
1897	RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs);
1898	RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs);
1899	RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs);
1900	RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs);
1901	RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs);
1902
1903	RValue<Float> Abs(RValue<Float> x);
1904	RValue<Float> Max(RValue<Float> x, RValue<Float> y);
1905	RValue<Float> Min(RValue<Float> x, RValue<Float> y);
1906	RValue<Float> Rcp_pp(RValue<Float> val, bool exactAtPow2 = false);
1907	RValue<Float> RcpSqrt_pp(RValue<Float> val);
1908	RValue<Float> Sqrt(RValue<Float> x);
1909	RValue<Float> Round(RValue<Float> val);
1910	RValue<Float> Trunc(RValue<Float> val);
1911	RValue<Float> Frac(RValue<Float> val);
1912	RValue<Float> Floor(RValue<Float> val);
1913	RValue<Float> Ceil(RValue<Float> val);
1914
1915	class Float2 : public Variable<Float2>
1916	{
1917	public:
1918	//	explicit Float2(RValue<Byte2> cast);
1919	//	explicit Float2(RValue<Short2> cast);
1920	//	explicit Float2(RValue<UShort2> cast);
1921	//	explicit Float2(RValue<Int2> cast);
1922	//	explicit Float2(RValue<UInt2> cast);
1923		explicit Float2(RValue<Float4> cast);
1924
1925	//	Float2();
1926	//	Float2(float x, float y);
1927	//	Float2(RValue<Float2> rhs);
1928	//	Float2(const Float2 &rhs);
1929	//	Float2(const Reference<Float2> &rhs);
1930	//	Float2(RValue<Float> rhs);
1931	//	Float2(const Float &rhs);
1932	//	Float2(const Reference<Float> &rhs);
1933
1934	//	template<int T>
1935	//	Float2(const SwizzleMask1Float4<T> &rhs);
1936
1937	//	RValue<Float2> operator=(float replicate) const;
1938	//	RValue<Float2> operator=(RValue<Float2> rhs) const;
1939	//	RValue<Float2> operator=(const Float2 &rhs) const;
1940	//	RValue<Float2> operator=(const Reference<Float2> &rhs) const;
1941	//	RValue<Float2> operator=(RValue<Float> rhs) const;
1942	//	RValue<Float2> operator=(const Float &rhs) const;
1943	//	RValue<Float2> operator=(const Reference<Float> &rhs) const;
1944
1945	//	template<int T>
1946	//	RValue<Float2> operator=(const SwizzleMask1Float4<T> &rhs);
1947
1948		static llvm::Type *getType();
1949	};
1950
1951//	RValue<Float2> operator+(RValue<Float2> lhs, RValue<Float2> rhs);
1952//	RValue<Float2> operator-(RValue<Float2> lhs, RValue<Float2> rhs);
1953//	RValue<Float2> operator*(RValue<Float2> lhs, RValue<Float2> rhs);
1954//	RValue<Float2> operator/(RValue<Float2> lhs, RValue<Float2> rhs);
1955//	RValue<Float2> operator%(RValue<Float2> lhs, RValue<Float2> rhs);
1956//	RValue<Float2> operator+=(const Float2 &lhs, RValue<Float2> rhs);
1957//	RValue<Float2> operator-=(const Float2 &lhs, RValue<Float2> rhs);
1958//	RValue<Float2> operator*=(const Float2 &lhs, RValue<Float2> rhs);
1959//	RValue<Float2> operator/=(const Float2 &lhs, RValue<Float2> rhs);
1960//	RValue<Float2> operator%=(const Float2 &lhs, RValue<Float2> rhs);
1961//	RValue<Float2> operator+(RValue<Float2> val);
1962//	RValue<Float2> operator-(RValue<Float2> val);
1963
1964//	RValue<Float2> Abs(RValue<Float2> x);
1965//	RValue<Float2> Max(RValue<Float2> x, RValue<Float2> y);
1966//	RValue<Float2> Min(RValue<Float2> x, RValue<Float2> y);
1967//	RValue<Float2> Swizzle(RValue<Float2> x, unsigned char select);
1968//	RValue<Float2> Mask(Float2 &lhs, RValue<Float2> rhs, unsigned char select);
1969
1970	class Float4 : public Variable<Float4>
1971	{
1972	public:
1973		explicit Float4(RValue<Byte4> cast);
1974		explicit Float4(RValue<SByte4> cast);
1975		explicit Float4(RValue<Short4> cast);
1976		explicit Float4(RValue<UShort4> cast);
1977		explicit Float4(RValue<Int4> cast);
1978		explicit Float4(RValue<UInt4> cast);
1979
1980		Float4();
1981		Float4(float xyzw);
1982		Float4(float x, float yzw);
1983		Float4(float x, float y, float zw);
1984		Float4(float x, float y, float z, float w);
1985		Float4(RValue<Float4> rhs);
1986		Float4(const Float4 &rhs);
1987		Float4(const Reference<Float4> &rhs);
1988		Float4(RValue<Float> rhs);
1989		Float4(const Float &rhs);
1990		Float4(const Reference<Float> &rhs);
1991
1992		template<int T>
1993		Float4(const SwizzleMask1Float4<T> &rhs);
1994		template<int T>
1995		Float4(const SwizzleFloat4<T> &rhs);
1996		template<int X, int Y>
1997		Float4(const Swizzle2Float4<X> &x, const Swizzle2Float4<Y> &y);
1998		template<int X, int Y>
1999		Float4(const SwizzleMask2Float4<X> &x, const Swizzle2Float4<Y> &y);
2000		template<int X, int Y>
2001		Float4(const Swizzle2Float4<X> &x, const SwizzleMask2Float4<Y> &y);
2002		template<int X, int Y>
2003		Float4(const SwizzleMask2Float4<X> &x, const SwizzleMask2Float4<Y> &y);
2004
2005		RValue<Float4> operator=(float replicate) const;
2006		RValue<Float4> operator=(RValue<Float4> rhs) const;
2007		RValue<Float4> operator=(const Float4 &rhs) const;
2008		RValue<Float4> operator=(const Reference<Float4> &rhs) const;
2009		RValue<Float4> operator=(RValue<Float> rhs) const;
2010		RValue<Float4> operator=(const Float &rhs) const;
2011		RValue<Float4> operator=(const Reference<Float> &rhs) const;
2012
2013		template<int T>
2014		RValue<Float4> operator=(const SwizzleMask1Float4<T> &rhs);
2015		template<int T>
2016		RValue<Float4> operator=(const SwizzleFloat4<T> &rhs);
2017
2018		static llvm::Type *getType();
2019
2020		union
2021		{
2022			SwizzleMask1Float4<0x00> x;
2023			SwizzleMask1Float4<0x55> y;
2024			SwizzleMask1Float4<0xAA> z;
2025			SwizzleMask1Float4<0xFF> w;
2026			Swizzle2Float4<0x00>     xx;
2027			Swizzle2Float4<0x01>     yx;
2028			Swizzle2Float4<0x02>     zx;
2029			Swizzle2Float4<0x03>     wx;
2030			SwizzleMask2Float4<0x54> xy;
2031			Swizzle2Float4<0x55>     yy;
2032			Swizzle2Float4<0x56>     zy;
2033			Swizzle2Float4<0x57>     wy;
2034			SwizzleMask2Float4<0xA8> xz;
2035			SwizzleMask2Float4<0xA9> yz;
2036			Swizzle2Float4<0xAA>     zz;
2037			Swizzle2Float4<0xAB>     wz;
2038			SwizzleMask2Float4<0xFC> xw;
2039			SwizzleMask2Float4<0xFD> yw;
2040			SwizzleMask2Float4<0xFE> zw;
2041			Swizzle2Float4<0xFF>     ww;
2042			SwizzleFloat4<0x00>      xxx;
2043			SwizzleFloat4<0x01>      yxx;
2044			SwizzleFloat4<0x02>      zxx;
2045			SwizzleFloat4<0x03>      wxx;
2046			SwizzleFloat4<0x04>      xyx;
2047			SwizzleFloat4<0x05>      yyx;
2048			SwizzleFloat4<0x06>      zyx;
2049			SwizzleFloat4<0x07>      wyx;
2050			SwizzleFloat4<0x08>      xzx;
2051			SwizzleFloat4<0x09>      yzx;
2052			SwizzleFloat4<0x0A>      zzx;
2053			SwizzleFloat4<0x0B>      wzx;
2054			SwizzleFloat4<0x0C>      xwx;
2055			SwizzleFloat4<0x0D>      ywx;
2056			SwizzleFloat4<0x0E>      zwx;
2057			SwizzleFloat4<0x0F>      wwx;
2058			SwizzleFloat4<0x50>      xxy;
2059			SwizzleFloat4<0x51>      yxy;
2060			SwizzleFloat4<0x52>      zxy;
2061			SwizzleFloat4<0x53>      wxy;
2062			SwizzleFloat4<0x54>      xyy;
2063			SwizzleFloat4<0x55>      yyy;
2064			SwizzleFloat4<0x56>      zyy;
2065			SwizzleFloat4<0x57>      wyy;
2066			SwizzleFloat4<0x58>      xzy;
2067			SwizzleFloat4<0x59>      yzy;
2068			SwizzleFloat4<0x5A>      zzy;
2069			SwizzleFloat4<0x5B>      wzy;
2070			SwizzleFloat4<0x5C>      xwy;
2071			SwizzleFloat4<0x5D>      ywy;
2072			SwizzleFloat4<0x5E>      zwy;
2073			SwizzleFloat4<0x5F>      wwy;
2074			SwizzleFloat4<0xA0>      xxz;
2075			SwizzleFloat4<0xA1>      yxz;
2076			SwizzleFloat4<0xA2>      zxz;
2077			SwizzleFloat4<0xA3>      wxz;
2078			SwizzleMaskFloat4<0xA4>  xyz;
2079			SwizzleFloat4<0xA5>      yyz;
2080			SwizzleFloat4<0xA6>      zyz;
2081			SwizzleFloat4<0xA7>      wyz;
2082			SwizzleFloat4<0xA8>      xzz;
2083			SwizzleFloat4<0xA9>      yzz;
2084			SwizzleFloat4<0xAA>      zzz;
2085			SwizzleFloat4<0xAB>      wzz;
2086			SwizzleFloat4<0xAC>      xwz;
2087			SwizzleFloat4<0xAD>      ywz;
2088			SwizzleFloat4<0xAE>      zwz;
2089			SwizzleFloat4<0xAF>      wwz;
2090			SwizzleFloat4<0xF0>      xxw;
2091			SwizzleFloat4<0xF1>      yxw;
2092			SwizzleFloat4<0xF2>      zxw;
2093			SwizzleFloat4<0xF3>      wxw;
2094			SwizzleMaskFloat4<0xF4>  xyw;
2095			SwizzleFloat4<0xF5>      yyw;
2096			SwizzleFloat4<0xF6>      zyw;
2097			SwizzleFloat4<0xF7>      wyw;
2098			SwizzleMaskFloat4<0xF8>  xzw;
2099			SwizzleMaskFloat4<0xF9>  yzw;
2100			SwizzleFloat4<0xFA>      zzw;
2101			SwizzleFloat4<0xFB>      wzw;
2102			SwizzleFloat4<0xFC>      xww;
2103			SwizzleFloat4<0xFD>      yww;
2104			SwizzleFloat4<0xFE>      zww;
2105			SwizzleFloat4<0xFF>      www;
2106			SwizzleFloat4<0x00>      xxxx;
2107			SwizzleFloat4<0x01>      yxxx;
2108			SwizzleFloat4<0x02>      zxxx;
2109			SwizzleFloat4<0x03>      wxxx;
2110			SwizzleFloat4<0x04>      xyxx;
2111			SwizzleFloat4<0x05>      yyxx;
2112			SwizzleFloat4<0x06>      zyxx;
2113			SwizzleFloat4<0x07>      wyxx;
2114			SwizzleFloat4<0x08>      xzxx;
2115			SwizzleFloat4<0x09>      yzxx;
2116			SwizzleFloat4<0x0A>      zzxx;
2117			SwizzleFloat4<0x0B>      wzxx;
2118			SwizzleFloat4<0x0C>      xwxx;
2119			SwizzleFloat4<0x0D>      ywxx;
2120			SwizzleFloat4<0x0E>      zwxx;
2121			SwizzleFloat4<0x0F>      wwxx;
2122			SwizzleFloat4<0x10>      xxyx;
2123			SwizzleFloat4<0x11>      yxyx;
2124			SwizzleFloat4<0x12>      zxyx;
2125			SwizzleFloat4<0x13>      wxyx;
2126			SwizzleFloat4<0x14>      xyyx;
2127			SwizzleFloat4<0x15>      yyyx;
2128			SwizzleFloat4<0x16>      zyyx;
2129			SwizzleFloat4<0x17>      wyyx;
2130			SwizzleFloat4<0x18>      xzyx;
2131			SwizzleFloat4<0x19>      yzyx;
2132			SwizzleFloat4<0x1A>      zzyx;
2133			SwizzleFloat4<0x1B>      wzyx;
2134			SwizzleFloat4<0x1C>      xwyx;
2135			SwizzleFloat4<0x1D>      ywyx;
2136			SwizzleFloat4<0x1E>      zwyx;
2137			SwizzleFloat4<0x1F>      wwyx;
2138			SwizzleFloat4<0x20>      xxzx;
2139			SwizzleFloat4<0x21>      yxzx;
2140			SwizzleFloat4<0x22>      zxzx;
2141			SwizzleFloat4<0x23>      wxzx;
2142			SwizzleFloat4<0x24>      xyzx;
2143			SwizzleFloat4<0x25>      yyzx;
2144			SwizzleFloat4<0x26>      zyzx;
2145			SwizzleFloat4<0x27>      wyzx;
2146			SwizzleFloat4<0x28>      xzzx;
2147			SwizzleFloat4<0x29>      yzzx;
2148			SwizzleFloat4<0x2A>      zzzx;
2149			SwizzleFloat4<0x2B>      wzzx;
2150			SwizzleFloat4<0x2C>      xwzx;
2151			SwizzleFloat4<0x2D>      ywzx;
2152			SwizzleFloat4<0x2E>      zwzx;
2153			SwizzleFloat4<0x2F>      wwzx;
2154			SwizzleFloat4<0x30>      xxwx;
2155			SwizzleFloat4<0x31>      yxwx;
2156			SwizzleFloat4<0x32>      zxwx;
2157			SwizzleFloat4<0x33>      wxwx;
2158			SwizzleFloat4<0x34>      xywx;
2159			SwizzleFloat4<0x35>      yywx;
2160			SwizzleFloat4<0x36>      zywx;
2161			SwizzleFloat4<0x37>      wywx;
2162			SwizzleFloat4<0x38>      xzwx;
2163			SwizzleFloat4<0x39>      yzwx;
2164			SwizzleFloat4<0x3A>      zzwx;
2165			SwizzleFloat4<0x3B>      wzwx;
2166			SwizzleFloat4<0x3C>      xwwx;
2167			SwizzleFloat4<0x3D>      ywwx;
2168			SwizzleFloat4<0x3E>      zwwx;
2169			SwizzleFloat4<0x3F>      wwwx;
2170			SwizzleFloat4<0x40>      xxxy;
2171			SwizzleFloat4<0x41>      yxxy;
2172			SwizzleFloat4<0x42>      zxxy;
2173			SwizzleFloat4<0x43>      wxxy;
2174			SwizzleFloat4<0x44>      xyxy;
2175			SwizzleFloat4<0x45>      yyxy;
2176			SwizzleFloat4<0x46>      zyxy;
2177			SwizzleFloat4<0x47>      wyxy;
2178			SwizzleFloat4<0x48>      xzxy;
2179			SwizzleFloat4<0x49>      yzxy;
2180			SwizzleFloat4<0x4A>      zzxy;
2181			SwizzleFloat4<0x4B>      wzxy;
2182			SwizzleFloat4<0x4C>      xwxy;
2183			SwizzleFloat4<0x4D>      ywxy;
2184			SwizzleFloat4<0x4E>      zwxy;
2185			SwizzleFloat4<0x4F>      wwxy;
2186			SwizzleFloat4<0x50>      xxyy;
2187			SwizzleFloat4<0x51>      yxyy;
2188			SwizzleFloat4<0x52>      zxyy;
2189			SwizzleFloat4<0x53>      wxyy;
2190			SwizzleFloat4<0x54>      xyyy;
2191			SwizzleFloat4<0x55>      yyyy;
2192			SwizzleFloat4<0x56>      zyyy;
2193			SwizzleFloat4<0x57>      wyyy;
2194			SwizzleFloat4<0x58>      xzyy;
2195			SwizzleFloat4<0x59>      yzyy;
2196			SwizzleFloat4<0x5A>      zzyy;
2197			SwizzleFloat4<0x5B>      wzyy;
2198			SwizzleFloat4<0x5C>      xwyy;
2199			SwizzleFloat4<0x5D>      ywyy;
2200			SwizzleFloat4<0x5E>      zwyy;
2201			SwizzleFloat4<0x5F>      wwyy;
2202			SwizzleFloat4<0x60>      xxzy;
2203			SwizzleFloat4<0x61>      yxzy;
2204			SwizzleFloat4<0x62>      zxzy;
2205			SwizzleFloat4<0x63>      wxzy;
2206			SwizzleFloat4<0x64>      xyzy;
2207			SwizzleFloat4<0x65>      yyzy;
2208			SwizzleFloat4<0x66>      zyzy;
2209			SwizzleFloat4<0x67>      wyzy;
2210			SwizzleFloat4<0x68>      xzzy;
2211			SwizzleFloat4<0x69>      yzzy;
2212			SwizzleFloat4<0x6A>      zzzy;
2213			SwizzleFloat4<0x6B>      wzzy;
2214			SwizzleFloat4<0x6C>      xwzy;
2215			SwizzleFloat4<0x6D>      ywzy;
2216			SwizzleFloat4<0x6E>      zwzy;
2217			SwizzleFloat4<0x6F>      wwzy;
2218			SwizzleFloat4<0x70>      xxwy;
2219			SwizzleFloat4<0x71>      yxwy;
2220			SwizzleFloat4<0x72>      zxwy;
2221			SwizzleFloat4<0x73>      wxwy;
2222			SwizzleFloat4<0x74>      xywy;
2223			SwizzleFloat4<0x75>      yywy;
2224			SwizzleFloat4<0x76>      zywy;
2225			SwizzleFloat4<0x77>      wywy;
2226			SwizzleFloat4<0x78>      xzwy;
2227			SwizzleFloat4<0x79>      yzwy;
2228			SwizzleFloat4<0x7A>      zzwy;
2229			SwizzleFloat4<0x7B>      wzwy;
2230			SwizzleFloat4<0x7C>      xwwy;
2231			SwizzleFloat4<0x7D>      ywwy;
2232			SwizzleFloat4<0x7E>      zwwy;
2233			SwizzleFloat4<0x7F>      wwwy;
2234			SwizzleFloat4<0x80>      xxxz;
2235			SwizzleFloat4<0x81>      yxxz;
2236			SwizzleFloat4<0x82>      zxxz;
2237			SwizzleFloat4<0x83>      wxxz;
2238			SwizzleFloat4<0x84>      xyxz;
2239			SwizzleFloat4<0x85>      yyxz;
2240			SwizzleFloat4<0x86>      zyxz;
2241			SwizzleFloat4<0x87>      wyxz;
2242			SwizzleFloat4<0x88>      xzxz;
2243			SwizzleFloat4<0x89>      yzxz;
2244			SwizzleFloat4<0x8A>      zzxz;
2245			SwizzleFloat4<0x8B>      wzxz;
2246			SwizzleFloat4<0x8C>      xwxz;
2247			SwizzleFloat4<0x8D>      ywxz;
2248			SwizzleFloat4<0x8E>      zwxz;
2249			SwizzleFloat4<0x8F>      wwxz;
2250			SwizzleFloat4<0x90>      xxyz;
2251			SwizzleFloat4<0x91>      yxyz;
2252			SwizzleFloat4<0x92>      zxyz;
2253			SwizzleFloat4<0x93>      wxyz;
2254			SwizzleFloat4<0x94>      xyyz;
2255			SwizzleFloat4<0x95>      yyyz;
2256			SwizzleFloat4<0x96>      zyyz;
2257			SwizzleFloat4<0x97>      wyyz;
2258			SwizzleFloat4<0x98>      xzyz;
2259			SwizzleFloat4<0x99>      yzyz;
2260			SwizzleFloat4<0x9A>      zzyz;
2261			SwizzleFloat4<0x9B>      wzyz;
2262			SwizzleFloat4<0x9C>      xwyz;
2263			SwizzleFloat4<0x9D>      ywyz;
2264			SwizzleFloat4<0x9E>      zwyz;
2265			SwizzleFloat4<0x9F>      wwyz;
2266			SwizzleFloat4<0xA0>      xxzz;
2267			SwizzleFloat4<0xA1>      yxzz;
2268			SwizzleFloat4<0xA2>      zxzz;
2269			SwizzleFloat4<0xA3>      wxzz;
2270			SwizzleFloat4<0xA4>      xyzz;
2271			SwizzleFloat4<0xA5>      yyzz;
2272			SwizzleFloat4<0xA6>      zyzz;
2273			SwizzleFloat4<0xA7>      wyzz;
2274			SwizzleFloat4<0xA8>      xzzz;
2275			SwizzleFloat4<0xA9>      yzzz;
2276			SwizzleFloat4<0xAA>      zzzz;
2277			SwizzleFloat4<0xAB>      wzzz;
2278			SwizzleFloat4<0xAC>      xwzz;
2279			SwizzleFloat4<0xAD>      ywzz;
2280			SwizzleFloat4<0xAE>      zwzz;
2281			SwizzleFloat4<0xAF>      wwzz;
2282			SwizzleFloat4<0xB0>      xxwz;
2283			SwizzleFloat4<0xB1>      yxwz;
2284			SwizzleFloat4<0xB2>      zxwz;
2285			SwizzleFloat4<0xB3>      wxwz;
2286			SwizzleFloat4<0xB4>      xywz;
2287			SwizzleFloat4<0xB5>      yywz;
2288			SwizzleFloat4<0xB6>      zywz;
2289			SwizzleFloat4<0xB7>      wywz;
2290			SwizzleFloat4<0xB8>      xzwz;
2291			SwizzleFloat4<0xB9>      yzwz;
2292			SwizzleFloat4<0xBA>      zzwz;
2293			SwizzleFloat4<0xBB>      wzwz;
2294			SwizzleFloat4<0xBC>      xwwz;
2295			SwizzleFloat4<0xBD>      ywwz;
2296			SwizzleFloat4<0xBE>      zwwz;
2297			SwizzleFloat4<0xBF>      wwwz;
2298			SwizzleFloat4<0xC0>      xxxw;
2299			SwizzleFloat4<0xC1>      yxxw;
2300			SwizzleFloat4<0xC2>      zxxw;
2301			SwizzleFloat4<0xC3>      wxxw;
2302			SwizzleFloat4<0xC4>      xyxw;
2303			SwizzleFloat4<0xC5>      yyxw;
2304			SwizzleFloat4<0xC6>      zyxw;
2305			SwizzleFloat4<0xC7>      wyxw;
2306			SwizzleFloat4<0xC8>      xzxw;
2307			SwizzleFloat4<0xC9>      yzxw;
2308			SwizzleFloat4<0xCA>      zzxw;
2309			SwizzleFloat4<0xCB>      wzxw;
2310			SwizzleFloat4<0xCC>      xwxw;
2311			SwizzleFloat4<0xCD>      ywxw;
2312			SwizzleFloat4<0xCE>      zwxw;
2313			SwizzleFloat4<0xCF>      wwxw;
2314			SwizzleFloat4<0xD0>      xxyw;
2315			SwizzleFloat4<0xD1>      yxyw;
2316			SwizzleFloat4<0xD2>      zxyw;
2317			SwizzleFloat4<0xD3>      wxyw;
2318			SwizzleFloat4<0xD4>      xyyw;
2319			SwizzleFloat4<0xD5>      yyyw;
2320			SwizzleFloat4<0xD6>      zyyw;
2321			SwizzleFloat4<0xD7>      wyyw;
2322			SwizzleFloat4<0xD8>      xzyw;
2323			SwizzleFloat4<0xD9>      yzyw;
2324			SwizzleFloat4<0xDA>      zzyw;
2325			SwizzleFloat4<0xDB>      wzyw;
2326			SwizzleFloat4<0xDC>      xwyw;
2327			SwizzleFloat4<0xDD>      ywyw;
2328			SwizzleFloat4<0xDE>      zwyw;
2329			SwizzleFloat4<0xDF>      wwyw;
2330			SwizzleFloat4<0xE0>      xxzw;
2331			SwizzleFloat4<0xE1>      yxzw;
2332			SwizzleFloat4<0xE2>      zxzw;
2333			SwizzleFloat4<0xE3>      wxzw;
2334			SwizzleMaskFloat4<0xE4>  xyzw;
2335			SwizzleFloat4<0xE5>      yyzw;
2336			SwizzleFloat4<0xE6>      zyzw;
2337			SwizzleFloat4<0xE7>      wyzw;
2338			SwizzleFloat4<0xE8>      xzzw;
2339			SwizzleFloat4<0xE9>      yzzw;
2340			SwizzleFloat4<0xEA>      zzzw;
2341			SwizzleFloat4<0xEB>      wzzw;
2342			SwizzleFloat4<0xEC>      xwzw;
2343			SwizzleFloat4<0xED>      ywzw;
2344			SwizzleFloat4<0xEE>      zwzw;
2345			SwizzleFloat4<0xEF>      wwzw;
2346			SwizzleFloat4<0xF0>      xxww;
2347			SwizzleFloat4<0xF1>      yxww;
2348			SwizzleFloat4<0xF2>      zxww;
2349			SwizzleFloat4<0xF3>      wxww;
2350			SwizzleFloat4<0xF4>      xyww;
2351			SwizzleFloat4<0xF5>      yyww;
2352			SwizzleFloat4<0xF6>      zyww;
2353			SwizzleFloat4<0xF7>      wyww;
2354			SwizzleFloat4<0xF8>      xzww;
2355			SwizzleFloat4<0xF9>      yzww;
2356			SwizzleFloat4<0xFA>      zzww;
2357			SwizzleFloat4<0xFB>      wzww;
2358			SwizzleFloat4<0xFC>      xwww;
2359			SwizzleFloat4<0xFD>      ywww;
2360			SwizzleFloat4<0xFE>      zwww;
2361			SwizzleFloat4<0xFF>      wwww;
2362		};
2363
2364	private:
2365		void constant(float x, float y, float z, float w);
2366	};
2367
2368	RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs);
2369	RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs);
2370	RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs);
2371	RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs);
2372	RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs);
2373	RValue<Float4> operator+=(const Float4 &lhs, RValue<Float4> rhs);
2374	RValue<Float4> operator-=(const Float4 &lhs, RValue<Float4> rhs);
2375	RValue<Float4> operator*=(const Float4 &lhs, RValue<Float4> rhs);
2376	RValue<Float4> operator/=(const Float4 &lhs, RValue<Float4> rhs);
2377	RValue<Float4> operator%=(const Float4 &lhs, RValue<Float4> rhs);
2378	RValue<Float4> operator+(RValue<Float4> val);
2379	RValue<Float4> operator-(RValue<Float4> val);
2380
2381	RValue<Float4> Abs(RValue<Float4> x);
2382	RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y);
2383	RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y);
2384	RValue<Float4> Rcp_pp(RValue<Float4> val, bool exactAtPow2 = false);
2385	RValue<Float4> RcpSqrt_pp(RValue<Float4> val);
2386	RValue<Float4> Sqrt(RValue<Float4> x);
2387	RValue<Float4> Insert(const Float4 &val, RValue<Float> element, int i);
2388	RValue<Float> Extract(RValue<Float4> x, int i);
2389	RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select);
2390	RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm);
2391	RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y);
2392	RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y);
2393	RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select);
2394	RValue<Int> SignMask(RValue<Float4> x);
2395	RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y);
2396	RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y);
2397	RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y);
2398	RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y);
2399	RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y);
2400	RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y);
2401	RValue<Float4> Round(RValue<Float4> x);
2402	RValue<Float4> Trunc(RValue<Float4> x);
2403	RValue<Float4> Frac(RValue<Float4> x);
2404	RValue<Float4> Floor(RValue<Float4> x);
2405	RValue<Float4> Ceil(RValue<Float4> x);
2406
2407	template<class T>
2408	class Pointer : public Variable<Pointer<T>>
2409	{
2410	public:
2411		template<class S>
2412		Pointer(RValue<Pointer<S>> pointerS, int alignment = 1) : alignment(alignment)
2413		{
2414			llvm::Value *pointerT = Nucleus::createBitCast(pointerS.value, Nucleus::getPointerType(T::getType()));
2415			LValue::storeValue(pointerT);
2416		}
2417
2418		template<class S>
2419		Pointer(const Pointer<S> &pointer, int alignment = 1) : alignment(alignment)
2420		{
2421			llvm::Value *pointerS = pointer.loadValue(alignment);
2422			llvm::Value *pointerT = Nucleus::createBitCast(pointerS, Nucleus::getPointerType(T::getType()));
2423			LValue::storeValue(pointerT);
2424		}
2425
2426		Pointer(Argument<Pointer<T>> argument);
2427		explicit Pointer(const void *external);
2428
2429		Pointer();
2430		Pointer(RValue<Pointer<T>> rhs);
2431		Pointer(const Pointer<T> &rhs);
2432		Pointer(const Reference<Pointer<T>> &rhs);
2433
2434		RValue<Pointer<T>> operator=(RValue<Pointer<T>> rhs) const;
2435		RValue<Pointer<T>> operator=(const Pointer<T> &rhs) const;
2436		RValue<Pointer<T>> operator=(const Reference<Pointer<T>> &rhs) const;
2437
2438		Reference<T> operator*();
2439
2440		static llvm::Type *getType();
2441
2442	private:
2443		const int alignment;
2444	};
2445
2446	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset);
2447	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset);
2448	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);
2449	RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset);
2450	RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<Int> offset);
2451	RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset);
2452
2453	RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset);
2454	RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset);
2455	RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);
2456	RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, int offset);
2457	RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<Int> offset);
2458	RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset);
2459
2460	template<class T, int S = 1>
2461	class Array : public Variable<T>
2462	{
2463	public:
2464		Array(int size = S);
2465
2466		Reference<T> operator[](int index);
2467		Reference<T> operator[](RValue<Int> index);
2468		Reference<T> operator[](RValue<UInt> index);
2469	};
2470
2471//	RValue<Array<T>> operator++(const Array<T> &val, int);   // Post-increment
2472//	const Array<T> &operator++(const Array<T> &val);   // Pre-increment
2473//	RValue<Array<T>> operator--(const Array<T> &val, int);   // Post-decrement
2474//	const Array<T> &operator--(const Array<T> &val);   // Pre-decrement
2475
2476	llvm::BasicBlock *beginLoop();
2477	bool branch(RValue<Bool> cmp, llvm::BasicBlock *bodyBB, llvm::BasicBlock *endBB);
2478	bool elseBlock(llvm::BasicBlock *falseBB);
2479
2480	void Return();
2481	void Return(bool ret);
2482	void Return(const Int &ret);
2483
2484	template<class T>
2485	void Return(const Pointer<T> &ret);
2486
2487	template<class T>
2488	void Return(RValue<Pointer<T>> ret);
2489
2490	template<unsigned int index, typename... Arguments>
2491	struct ArgI;
2492
2493	template<typename Arg0, typename... Arguments>
2494	struct ArgI<0, Arg0, Arguments...>
2495	{
2496		typedef Arg0 Type;
2497	};
2498
2499	template<unsigned int index, typename Arg0, typename... Arguments>
2500	struct ArgI<index, Arg0, Arguments...>
2501	{
2502		typedef typename ArgI<index - 1, Arguments...>::Type Type;
2503	};
2504
2505	// Generic template, leave undefined!
2506	template<typename FunctionType>
2507	class Function;
2508
2509	// Specialized for function types
2510	template<typename Return, typename... Arguments>
2511	class Function<Return(Arguments...)>
2512	{
2513	public:
2514		Function();
2515
2516		virtual ~Function();
2517
2518		template<int index>
2519		Argument<typename ArgI<index, Arguments...>::Type> Arg() const
2520		{
2521			llvm::Value *arg = Nucleus::getArgument(function, index);
2522			return Argument<typename ArgI<index, Arguments...>::Type>(arg);
2523		}
2524
2525		Routine *operator()(const wchar_t *name, ...);
2526
2527	private:
2528		Nucleus *core;
2529		llvm::Function *function;
2530		std::vector<llvm::Type*> arguments;
2531	};
2532
2533	template<int index, typename Return, typename... Arguments>
2534	Argument<typename ArgI<index, Arguments...>::Type> Arg(Function<Return(Arguments...)> &function)
2535	{
2536		return Argument<typename ArgI<index, Arguments...>::Type>(function.arg(index));
2537	}
2538
2539	RValue<Long> Ticks();
2540}
2541
2542namespace sw
2543{
2544	template<class T>
2545	Variable<T>::Variable(int arraySize) : LValue(T::getType(), arraySize)
2546	{
2547	}
2548
2549	template<class T>
2550	RValue<Pointer<T>> Variable<T>::operator&()
2551	{
2552		return RValue<Pointer<T>>(LValue::address);
2553	}
2554
2555	template<class T>
2556	Reference<T>::Reference(llvm::Value *pointer, int alignment) : alignment(alignment)
2557	{
2558		address = pointer;
2559	}
2560
2561	template<class T>
2562	RValue<T> Reference<T>::operator=(RValue<T> rhs) const
2563	{
2564		Nucleus::createStore(rhs.value, address, false, alignment);
2565
2566		return rhs;
2567	}
2568
2569	template<class T>
2570	RValue<T> Reference<T>::operator=(const Reference<T> &ref) const
2571	{
2572		llvm::Value *tmp = Nucleus::createLoad(ref.address, false, ref.alignment);
2573		Nucleus::createStore(tmp, address, false, alignment);
2574
2575		return RValue<T>(tmp);
2576	}
2577
2578	template<class T>
2579	RValue<T> Reference<T>::operator+=(RValue<T> rhs) const
2580	{
2581		return *this = *this + rhs;
2582	}
2583
2584	template<class T>
2585	llvm::Value *Reference<T>::loadValue() const
2586	{
2587		return Nucleus::createLoad(address, false, alignment);
2588	}
2589
2590	template<class T>
2591	int Reference<T>::getAlignment() const
2592	{
2593		return alignment;
2594	}
2595
2596	template<class T>
2597	RValue<T>::RValue(llvm::Value *rvalue)
2598	{
2599		value = rvalue;
2600	}
2601
2602	template<class T>
2603	RValue<T>::RValue(const T &lvalue)
2604	{
2605		value = lvalue.loadValue();
2606	}
2607
2608	template<class T>
2609	RValue<T>::RValue(typename IntLiteral<T>::type i)
2610	{
2611		value = (llvm::Value*)Nucleus::createConstantInt(i);
2612	}
2613
2614	template<class T>
2615	RValue<T>::RValue(typename FloatLiteral<T>::type f)
2616	{
2617		value = (llvm::Value*)Nucleus::createConstantFloat(f);
2618	}
2619
2620	template<class T>
2621	RValue<T>::RValue(const Reference<T> &ref)
2622	{
2623		value = ref.loadValue();
2624	}
2625
2626	template<int T>
2627	Swizzle2Float4<T>::operator RValue<Float4>() const
2628	{
2629		llvm::Value *vector = parent->loadValue();
2630
2631		return RValue<Float4>(Nucleus::createSwizzle(vector, T));
2632	}
2633
2634	template<int T>
2635	SwizzleFloat4<T>::operator RValue<Float4>() const
2636	{
2637		llvm::Value *vector = parent->loadValue();
2638
2639		return RValue<Float4>(Nucleus::createSwizzle(vector, T));
2640	}
2641
2642	template<int T>
2643	SwizzleMaskFloat4<T>::operator RValue<Float4>() const
2644	{
2645		llvm::Value *vector = parent->loadValue();
2646
2647		return RValue<Float4>(Nucleus::createSwizzle(vector, T));
2648	}
2649
2650	template<int T>
2651	RValue<Float4> SwizzleMaskFloat4<T>::operator=(RValue<Float4> rhs) const
2652	{
2653		return Mask(*parent, rhs, T);
2654	}
2655
2656	template<int T>
2657	RValue<Float4> SwizzleMaskFloat4<T>::operator=(RValue<Float> rhs) const
2658	{
2659		return Mask(*parent, Float4(rhs), T);
2660	}
2661
2662	template<int T>
2663	SwizzleMask1Float4<T>::operator RValue<Float>() const   // FIXME: Call a non-template function
2664	{
2665		return Extract(*parent, T & 0x3);
2666	}
2667
2668	template<int T>
2669	SwizzleMask1Float4<T>::operator RValue<Float4>() const
2670	{
2671		llvm::Value *vector = parent->loadValue();
2672
2673		return RValue<Float4>(Nucleus::createSwizzle(vector, T));
2674	}
2675
2676	template<int T>
2677	RValue<Float4> SwizzleMask1Float4<T>::operator=(float x) const
2678	{
2679		return Insert(*parent, Float(x), T & 0x3);
2680	}
2681
2682	template<int T>
2683	RValue<Float4> SwizzleMask1Float4<T>::operator=(RValue<Float4> rhs) const
2684	{
2685		return Mask(*parent, Float4(rhs), T);
2686	}
2687
2688	template<int T>
2689	RValue<Float4> SwizzleMask1Float4<T>::operator=(RValue<Float> rhs) const   // FIXME: Call a non-template function
2690	{
2691		return Insert(*parent, rhs, T & 0x3);
2692	}
2693
2694	template<int T>
2695	SwizzleMask2Float4<T>::operator RValue<Float4>() const
2696	{
2697		llvm::Value *vector = parent->loadValue();
2698
2699		return RValue<Float4>(Nucleus::createSwizzle(vector, T));
2700	}
2701
2702	template<int T>
2703	RValue<Float4> SwizzleMask2Float4<T>::operator=(RValue<Float4> rhs) const
2704	{
2705		return Mask(*parent, Float4(rhs), T);
2706	}
2707
2708	template<int T>
2709	Float::Float(const SwizzleMask1Float4<T> &rhs)
2710	{
2711		*this = rhs.operator RValue<Float>();
2712	}
2713
2714	template<int T>
2715	RValue<Float> Float::operator=(const SwizzleMask1Float4<T> &rhs) const
2716	{
2717		return *this = rhs.operator RValue<Float>();
2718	}
2719
2720	template<int T>
2721	Float4::Float4(const SwizzleMask1Float4<T> &rhs)
2722	{
2723		xyzw.parent = this;
2724
2725		*this = rhs.operator RValue<Float4>();
2726	}
2727
2728	template<int T>
2729	Float4::Float4(const SwizzleFloat4<T> &rhs)
2730	{
2731		xyzw.parent = this;
2732
2733		*this = rhs.operator RValue<Float4>();
2734	}
2735
2736	template<int X, int Y>
2737	Float4::Float4(const Swizzle2Float4<X> &x, const Swizzle2Float4<Y> &y)
2738	{
2739		xyzw.parent = this;
2740
2741		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2742	}
2743
2744	template<int X, int Y>
2745	Float4::Float4(const SwizzleMask2Float4<X> &x, const Swizzle2Float4<Y> &y)
2746	{
2747		xyzw.parent = this;
2748
2749		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2750	}
2751
2752	template<int X, int Y>
2753	Float4::Float4(const Swizzle2Float4<X> &x, const SwizzleMask2Float4<Y> &y)
2754	{
2755		xyzw.parent = this;
2756
2757		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2758	}
2759
2760	template<int X, int Y>
2761	Float4::Float4(const SwizzleMask2Float4<X> &x, const SwizzleMask2Float4<Y> &y)
2762	{
2763		xyzw.parent = this;
2764
2765		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2766	}
2767
2768	template<int T>
2769	RValue<Float4> Float4::operator=(const SwizzleMask1Float4<T> &rhs)
2770	{
2771		return *this = rhs.operator RValue<Float4>();
2772	}
2773
2774	template<int T>
2775	RValue<Float4> Float4::operator=(const SwizzleFloat4<T> &rhs)
2776	{
2777		return *this = rhs.operator RValue<Float4>();
2778	}
2779
2780	template<class T>
2781	Pointer<T>::Pointer(Argument<Pointer<T>> argument) : alignment(1)
2782	{
2783		LValue::storeValue(argument.value);
2784	}
2785
2786	template<class T>
2787	Pointer<T>::Pointer(const void *external) : alignment((intptr_t)external & 0x0000000F ? 1 : 16)
2788	{
2789		const llvm::GlobalValue *globalPointer = Nucleus::getGlobalValueAtAddress(const_cast<void*>(external));   // FIXME: Const
2790
2791		if(!globalPointer)
2792		{
2793			globalPointer = Nucleus::createGlobalValue(T::getType(), false, alignment);
2794
2795			Nucleus::addGlobalMapping(globalPointer, const_cast<void*>(external));   // FIXME: Const
2796		}
2797
2798		LValue::storeValue((llvm::Value*)globalPointer);   // FIXME: Const
2799	}
2800
2801	template<class T>
2802	Pointer<T>::Pointer() : alignment(1)
2803	{
2804		LValue::storeValue(Nucleus::createNullPointer(T::getType()));
2805	}
2806
2807	template<class T>
2808	Pointer<T>::Pointer(RValue<Pointer<T>> rhs) : alignment(1)
2809	{
2810		LValue::storeValue(rhs.value);
2811	}
2812
2813	template<class T>
2814	Pointer<T>::Pointer(const Pointer<T> &rhs) : alignment(rhs.alignment)
2815	{
2816		llvm::Value *value = rhs.loadValue();
2817		LValue::storeValue(value);
2818	}
2819
2820	template<class T>
2821	Pointer<T>::Pointer(const Reference<Pointer<T>> &rhs) : alignment(rhs.getAlignment())
2822	{
2823		llvm::Value *value = rhs.loadValue();
2824		LValue::storeValue(value);
2825	}
2826
2827	template<class T>
2828	RValue<Pointer<T>> Pointer<T>::operator=(RValue<Pointer<T>> rhs) const
2829	{
2830		LValue::storeValue(rhs.value);
2831
2832		return rhs;
2833	}
2834
2835	template<class T>
2836	RValue<Pointer<T>> Pointer<T>::operator=(const Pointer<T> &rhs) const
2837	{
2838		llvm::Value *value = rhs.loadValue();
2839		LValue::storeValue(value);
2840
2841		return RValue<Pointer<T>>(value);
2842	}
2843
2844	template<class T>
2845	RValue<Pointer<T>> Pointer<T>::operator=(const Reference<Pointer<T>> &rhs) const
2846	{
2847		llvm::Value *value = rhs.loadValue();
2848		LValue::storeValue(value);
2849
2850		return RValue<Pointer<T>>(value);
2851	}
2852
2853	template<class T>
2854	Reference<T> Pointer<T>::operator*()
2855	{
2856		return Reference<T>(LValue::loadValue(), alignment);
2857	}
2858
2859	template<class T>
2860	llvm::Type *Pointer<T>::getType()
2861	{
2862		return Nucleus::getPointerType(T::getType());
2863	}
2864
2865	template<class T, int S>
2866	Array<T, S>::Array(int size) : Variable<T>(size)
2867	{
2868	}
2869
2870	template<class T, int S>
2871	Reference<T> Array<T, S>::operator[](int index)
2872	{
2873		llvm::Value *element = LValue::getAddress((llvm::Value*)Nucleus::createConstantInt(index));
2874
2875		return Reference<T>(element);
2876	}
2877
2878	template<class T, int S>
2879	Reference<T> Array<T, S>::operator[](RValue<Int> index)
2880	{
2881		llvm::Value *element = LValue::getAddress(index.value);
2882
2883		return Reference<T>(element);
2884	}
2885
2886	template<class T, int S>
2887	Reference<T> Array<T, S>::operator[](RValue<UInt> index)
2888	{
2889		llvm::Value *element = LValue::getAddress(index.value);
2890
2891		return Reference<T>(element);
2892	}
2893
2894//	template<class T>
2895//	RValue<Array<T>> operator++(const Array<T> &val, int)
2896//	{
2897//		// FIXME: Requires storing the address of the array
2898//	}
2899
2900//	template<class T>
2901//	const Array<T> &operator++(const Array<T> &val)
2902//	{
2903//		// FIXME: Requires storing the address of the array
2904//	}
2905
2906//	template<class T>
2907//	RValue<Array<T>> operator--(const Array<T> &val, int)
2908//	{
2909//		// FIXME: Requires storing the address of the array
2910//	}
2911
2912//	template<class T>
2913//	const Array<T> &operator--(const Array<T> &val)
2914//	{
2915//		// FIXME: Requires storing the address of the array
2916//	}
2917
2918	template<class T>
2919	RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, RValue<T> ifFalse)
2920	{
2921		return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, ifFalse.value));
2922	}
2923
2924	template<class T>
2925	RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, RValue<T> ifFalse)
2926	{
2927		llvm::Value *trueValue = ifTrue.loadValue();
2928
2929		return RValue<T>(Nucleus::createSelect(condition.value, trueValue, ifFalse.value));
2930	}
2931
2932	template<class T>
2933	RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, const T &ifFalse)
2934	{
2935		llvm::Value *falseValue = ifFalse.loadValue();
2936
2937		return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, falseValue));
2938	}
2939
2940	template<class T>
2941	RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, const T &ifFalse)
2942	{
2943		llvm::Value *trueValue = ifTrue.loadValue();
2944		llvm::Value *falseValue = ifFalse.loadValue();
2945
2946		return RValue<T>(Nucleus::createSelect(condition.value, trueValue, falseValue));
2947	}
2948
2949	template<class T>
2950	void Return(const Pointer<T> &ret)
2951	{
2952		Nucleus::createRet(Nucleus::createLoad(ret.address));
2953		Nucleus::setInsertBlock(Nucleus::createBasicBlock());
2954	}
2955
2956	template<class T>
2957	void Return(RValue<Pointer<T>> ret)
2958	{
2959		Nucleus::createRet(ret.value);
2960		Nucleus::setInsertBlock(Nucleus::createBasicBlock());
2961	}
2962
2963	template<typename Return, typename... Arguments>
2964	Function<Return(Arguments...)>::Function()
2965	{
2966		core = new Nucleus();
2967
2968		llvm::Type *types[] = {Arguments::getType()...};
2969		for(llvm::Type *type : types)
2970		{
2971			arguments.push_back(type);
2972		}
2973
2974		function = Nucleus::createFunction(Return::getType(), arguments);
2975		Nucleus::setFunction(function);
2976	}
2977
2978	template<typename Return, typename... Arguments>
2979	Function<Return(Arguments...)>::~Function()
2980	{
2981		delete core;
2982	}
2983
2984	template<typename Return, typename... Arguments>
2985	Routine *Function<Return(Arguments...)>::operator()(const wchar_t *name, ...)
2986	{
2987		wchar_t fullName[1024 + 1];
2988
2989		va_list vararg;
2990		va_start(vararg, name);
2991		vswprintf(fullName, 1024, name, vararg);
2992		va_end(vararg);
2993
2994		return core->acquireRoutine(fullName, true);
2995	}
2996
2997	template<class T, class S>
2998	RValue<T> ReinterpretCast(RValue<S> val)
2999	{
3000		return RValue<T>(Nucleus::createBitCast(val.value, T::getType()));
3001	}
3002
3003	template<class T>
3004	RValue<T> ReinterpretCast(const LValue &var)
3005	{
3006		llvm::Value *val = var.loadValue();
3007
3008		return RValue<T>(Nucleus::createBitCast(val, T::getType()));
3009	}
3010
3011	template<class T, class S>
3012	RValue<T> ReinterpretCast(const Reference<S> &var)
3013	{
3014		return ReinterpretCast<T>(RValue<S>(var));
3015	}
3016
3017	template<class T, class S>
3018	RValue<T> As(RValue<S> val)
3019	{
3020		return ReinterpretCast<T>(val);
3021	}
3022
3023	template<class T>
3024	RValue<T> As(const LValue &var)
3025	{
3026		return ReinterpretCast<T>(var);
3027	}
3028
3029	template<class T, class S>
3030	RValue<T> As(const Reference<S> &val)
3031	{
3032		return ReinterpretCast<T>(val);
3033	}
3034}
3035
3036#endif   // sw_Nucleus_hpp
3037