Add SwiftShader dump from Feb 6 2013
diff --git a/src/Reactor/DLL.cpp b/src/Reactor/DLL.cpp
new file mode 100644
index 0000000..729b640
--- /dev/null
+++ b/src/Reactor/DLL.cpp
@@ -0,0 +1,378 @@
+// SwiftShader Software Renderer

+//

+// Copyright(c) 2005-2011 TransGaming Inc.

+//

+// All rights reserved. No part of this software may be copied, distributed, transmitted,

+// transcribed, stored in a retrieval system, translated into any human or computer

+// language by any means, or disclosed to third parties without the explicit written

+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

+// or implied, including but not limited to any patent rights, are granted to you.

+//

+

+#include "Dll.hpp"

+

+#include <time.h>

+

+#ifndef IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE

+#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040

+#endif

+

+#ifndef IMAGE_DLLCHARACTERISTICS_NX_COMPAT 

+#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100

+#endif

+ 

+namespace sw

+{

+	#ifdef _M_AMD64

+		const bool AMD64 = true;

+	#else

+		const bool AMD64 = false;

+	#endif

+

+	DLL::DLL(const char *name, const void *constants, int constSize) : constants(constants), constSize(constSize)

+	{

+		dllName = new char[strlen(name) + 1];

+		strcpy(dllName, name);

+

+		codeSize = 0;

+	}

+

+	DLL::~DLL()

+	{

+		delete[] dllName;

+

+		for(FunctionList::iterator i = functionList.begin(); i != functionList.end(); i++)

+		{

+			delete i->second;

+		}

+	}

+

+	void DLL::addFunction(const void *function, const void *entry, int size)

+	{

+		functionOrder.push_back(function);

+		functionList[function] = new Function(codeSize, function, entry, size);

+

+		codeSize += size;

+	}

+

+	void DLL::addRelocation(const void *function, const void *address, bool ripRelative)

+	{

+		globalRelocations[function].push_back(Relocation((unsigned int)((unsigned char*)address - (unsigned char*)function), ripRelative));

+	}

+

+	void DLL::emit()

+	{

+		if(codeSize == 0)

+		{

+			return;

+		}

+

+		for(GlobalRelocations::iterator i = globalRelocations.begin(); i != globalRelocations.end(); i++)

+		{

+			const unsigned char *function = (const unsigned char*)i->first;

+			const std::vector<Relocation> &functionRelocations = i->second;

+			unsigned int location = functionList[function]->location;

+			

+			for(unsigned int j = 0; j < functionRelocations.size(); j++)

+			{

+				unsigned int address = location + functionRelocations[j].offset;

+				unsigned int page = address / 0x1000;

+				unsigned short reloc = address - page * 0x1000;

+

+				unsigned int relocType = AMD64 ? IMAGE_REL_BASED_DIR64 : IMAGE_REL_BASED_HIGHLOW;

+				pageRelocations[page].push_back((relocType << 12) | reloc);

+			}

+		}

+

+		if(pageRelocations.empty())

+		{

+			pageRelocations[0];   // Initialize an emtpy list

+		}

+

+		int relocSize = 0;

+

+		for(PageRelocations::iterator i = pageRelocations.begin(); i != pageRelocations.end(); i++)

+		{

+			if(i->second.size() % 2)   // Pad to align to DWORD

+			{

+				i->second.push_back(0);

+			}

+

+			relocSize += (int)sizeof(IMAGE_BASE_RELOCATION) + (int)i->second.size() * (int)sizeof(unsigned short);

+		}

+

+		unsigned long timeDateStamp = (unsigned long)time(0);

+

+		memset(&DOSheader, 0, sizeof(DOSheader));

+		DOSheader.e_magic = IMAGE_DOS_SIGNATURE;   // "MZ"

+		DOSheader.e_lfanew = sizeof(DOSheader);

+

+		int base = 0x10000000;

+		int codePage = pageAlign(sizeof(DOSheader) + AMD64 ? sizeof(COFFheader64) : sizeof(COFFheader32));

+		int exportsPage = codePage + pageAlign(codeSize);

+		int exportsSize = (int)(sizeof(IMAGE_EXPORT_DIRECTORY) + functionList.size() * sizeof(void*) + (strlen(dllName) + 1));

+		int relocPage = exportsPage + pageAlign(exportsSize);

+		int constPage = relocPage + pageAlign(relocSize);

+

+		if(!AMD64)

+		{

+			memset(&COFFheader32, 0, sizeof(COFFheader32));

+			COFFheader32.Signature = IMAGE_NT_SIGNATURE;   // "PE"

+			COFFheader32.FileHeader.Machine = IMAGE_FILE_MACHINE_I386;

+			COFFheader32.FileHeader.NumberOfSections = 4;

+			COFFheader32.FileHeader.TimeDateStamp = timeDateStamp;

+			COFFheader32.FileHeader.PointerToSymbolTable = 0;   // Deprecated COFF symbol table

+			COFFheader32.FileHeader.NumberOfSymbols = 0;

+			COFFheader32.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER32);

+			COFFheader32.FileHeader.Characteristics =	IMAGE_FILE_EXECUTABLE_IMAGE |

+														IMAGE_FILE_32BIT_MACHINE |

+														IMAGE_FILE_DLL;

+

+			COFFheader32.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC;

+			COFFheader32.OptionalHeader.MajorLinkerVersion = 8;

+			COFFheader32.OptionalHeader.MinorLinkerVersion = 0;

+			COFFheader32.OptionalHeader.SizeOfCode = fileAlign(codeSize);

+			COFFheader32.OptionalHeader.SizeOfInitializedData = fileAlign(exportsSize) + fileAlign(relocSize) + fileAlign(constSize);

+			COFFheader32.OptionalHeader.SizeOfUninitializedData = 0;

+			COFFheader32.OptionalHeader.AddressOfEntryPoint = 0;

+			COFFheader32.OptionalHeader.BaseOfCode = codePage;

+			COFFheader32.OptionalHeader.BaseOfData = exportsPage;

+

+			COFFheader32.OptionalHeader.ImageBase = base;

+			COFFheader32.OptionalHeader.SectionAlignment = 0x1000;

+			COFFheader32.OptionalHeader.FileAlignment = 0x200;

+			COFFheader32.OptionalHeader.MajorOperatingSystemVersion = 4;

+			COFFheader32.OptionalHeader.MinorOperatingSystemVersion = 0;

+			COFFheader32.OptionalHeader.MajorImageVersion = 0;

+			COFFheader32.OptionalHeader.MinorImageVersion = 0;

+			COFFheader32.OptionalHeader.MajorSubsystemVersion = 4;

+			COFFheader32.OptionalHeader.MinorSubsystemVersion = 0;

+			COFFheader32.OptionalHeader.Win32VersionValue = 0;

+			COFFheader32.OptionalHeader.SizeOfImage = constPage + pageAlign(constSize);

+			COFFheader32.OptionalHeader.SizeOfHeaders = fileAlign(sizeof(DOSheader) + sizeof(COFFheader32));

+			COFFheader32.OptionalHeader.CheckSum = 0;

+			COFFheader32.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;

+			COFFheader32.OptionalHeader.DllCharacteristics =	IMAGE_DLLCHARACTERISTICS_NO_SEH |

+															IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE |   // Base address randomization

+															IMAGE_DLLCHARACTERISTICS_NX_COMPAT;       // Data Execution Prevention compatible

+			COFFheader32.OptionalHeader.SizeOfStackReserve = 1024 * 1024;

+			COFFheader32.OptionalHeader.SizeOfStackCommit = 4 * 1024;

+			COFFheader32.OptionalHeader.SizeOfHeapReserve = 1024 * 1024;

+			COFFheader32.OptionalHeader.SizeOfHeapCommit = 4 * 1024;

+			COFFheader32.OptionalHeader.LoaderFlags = 0;

+			COFFheader32.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;

+

+			COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = exportsPage;

+			COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = exportsSize;

+

+			COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = relocPage;

+			COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = relocSize;

+		}

+		else

+		{

+			memset(&COFFheader64, 0, sizeof(COFFheader64));

+			COFFheader64.Signature = IMAGE_NT_SIGNATURE;   // "PE"

+			COFFheader64.FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64;

+			COFFheader64.FileHeader.NumberOfSections = 4;

+			COFFheader64.FileHeader.TimeDateStamp = timeDateStamp;

+			COFFheader64.FileHeader.PointerToSymbolTable = 0;   // Deprecated COFF symbol table

+			COFFheader64.FileHeader.NumberOfSymbols = 0;

+			COFFheader64.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64);

+			COFFheader64.FileHeader.Characteristics =	IMAGE_FILE_EXECUTABLE_IMAGE |

+														IMAGE_FILE_LARGE_ADDRESS_AWARE |

+														IMAGE_FILE_DLL;

+

+			COFFheader64.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;

+			COFFheader64.OptionalHeader.MajorLinkerVersion = 8;

+			COFFheader64.OptionalHeader.MinorLinkerVersion = 0;

+			COFFheader64.OptionalHeader.SizeOfCode = fileAlign(codeSize);

+			COFFheader64.OptionalHeader.SizeOfInitializedData = fileAlign(exportsSize) + fileAlign(relocSize) + fileAlign(constSize);

+			COFFheader64.OptionalHeader.SizeOfUninitializedData = 0;

+			COFFheader64.OptionalHeader.AddressOfEntryPoint = 0;

+			COFFheader64.OptionalHeader.BaseOfCode = codePage;

+

+			COFFheader64.OptionalHeader.ImageBase = base;

+			COFFheader64.OptionalHeader.SectionAlignment = 0x1000;

+			COFFheader64.OptionalHeader.FileAlignment = 0x200;

+			COFFheader64.OptionalHeader.MajorOperatingSystemVersion = 4;

+			COFFheader64.OptionalHeader.MinorOperatingSystemVersion = 0;

+			COFFheader64.OptionalHeader.MajorImageVersion = 0;

+			COFFheader64.OptionalHeader.MinorImageVersion = 0;

+			COFFheader64.OptionalHeader.MajorSubsystemVersion = 4;

+			COFFheader64.OptionalHeader.MinorSubsystemVersion = 0;

+			COFFheader64.OptionalHeader.Win32VersionValue = 0;

+			COFFheader64.OptionalHeader.SizeOfImage = constPage + pageAlign(constSize);

+			COFFheader64.OptionalHeader.SizeOfHeaders = fileAlign(sizeof(DOSheader) + sizeof(COFFheader64));

+			COFFheader64.OptionalHeader.CheckSum = 0;

+			COFFheader64.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;

+			COFFheader64.OptionalHeader.DllCharacteristics =	IMAGE_DLLCHARACTERISTICS_NO_SEH |

+															IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE |   // Base address randomization

+															IMAGE_DLLCHARACTERISTICS_NX_COMPAT;       // Data Execution Prevention compatible

+			COFFheader64.OptionalHeader.SizeOfStackReserve = 1024 * 1024;

+			COFFheader64.OptionalHeader.SizeOfStackCommit = 4 * 1024;

+			COFFheader64.OptionalHeader.SizeOfHeapReserve = 1024 * 1024;

+			COFFheader64.OptionalHeader.SizeOfHeapCommit = 4 * 1024;

+			COFFheader64.OptionalHeader.LoaderFlags = 0;

+			COFFheader64.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;

+

+			COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = exportsPage;

+			COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = exportsSize;

+

+			COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = relocPage;

+			COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = relocSize;

+		}

+

+		memset(&textSection, 0, sizeof(textSection));

+		strcpy((char*)&textSection.Name, ".text");

+		textSection.Misc.VirtualSize = pageAlign(codeSize);

+		textSection.VirtualAddress = codePage;

+		textSection.SizeOfRawData = fileAlign(codeSize);

+		textSection.PointerToRawData = fileAlign(sizeof(DOSheader) + AMD64 ? sizeof(COFFheader64) : sizeof(COFFheader32));

+		textSection.PointerToRelocations = 0;

+		textSection.PointerToLinenumbers = 0;

+		textSection.NumberOfRelocations = 0;

+		textSection.NumberOfLinenumbers = 0;

+		textSection.Characteristics = IMAGE_SCN_CNT_CODE |

+		                              IMAGE_SCN_MEM_EXECUTE |

+		                              IMAGE_SCN_MEM_READ;

+

+		memset(&exportsSection, 0, sizeof(exportsSection));

+		strcpy((char*)&exportsSection.Name, ".edata");

+		exportsSection.Misc.VirtualSize = pageAlign(exportsSize);

+		exportsSection.VirtualAddress = exportsPage;

+		exportsSection.SizeOfRawData = fileAlign(exportsSize);

+		exportsSection.PointerToRawData = textSection.PointerToRawData + fileAlign(codeSize);

+		exportsSection.PointerToRelocations = 0;

+		exportsSection.PointerToLinenumbers = 0;

+		exportsSection.NumberOfRelocations = 0;

+		exportsSection.NumberOfLinenumbers = 0;

+		exportsSection.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |

+		                                 IMAGE_SCN_MEM_READ;

+

+		memset(&relocSection, 0, sizeof(relocSection));

+		strcpy((char*)&relocSection.Name, ".reloc");

+		relocSection.Misc.VirtualSize = pageAlign(relocSize);

+		relocSection.VirtualAddress = relocPage;

+		relocSection.SizeOfRawData = fileAlign(relocSize);

+		relocSection.PointerToRawData = exportsSection.PointerToRawData + fileAlign(exportsSize);

+		relocSection.PointerToRelocations = 0;

+		relocSection.PointerToLinenumbers = 0;

+		relocSection.NumberOfRelocations = 0;

+		relocSection.NumberOfLinenumbers = 0;

+		relocSection.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |

+		                               IMAGE_SCN_MEM_DISCARDABLE |

+		                               IMAGE_SCN_MEM_READ;

+

+		memset(&constSection, 0, sizeof(constSection));

+		strcpy((char*)&constSection.Name, ".rdata");

+		constSection.Misc.VirtualSize = pageAlign(constSize);

+		constSection.VirtualAddress = constPage;

+		constSection.SizeOfRawData = fileAlign(constSize);

+		constSection.PointerToRawData = relocSection.PointerToRawData + fileAlign(relocSize);

+		constSection.PointerToRelocations = 0;

+		constSection.PointerToLinenumbers = 0;

+		constSection.NumberOfRelocations = 0;

+		constSection.NumberOfLinenumbers = 0;

+		constSection.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |

+		                               IMAGE_SCN_MEM_READ;

+

+		memset(&exportDirectory, 0, sizeof(exportDirectory));

+		exportDirectory.Characteristics = 0;

+		exportDirectory.TimeDateStamp = timeDateStamp;

+		exportDirectory.MajorVersion = 0;

+		exportDirectory.MinorVersion = 0;

+		exportDirectory.Name = (unsigned long)(exportsPage + sizeof(IMAGE_EXPORT_DIRECTORY) + functionList.size() * sizeof(void*));

+		exportDirectory.Base = 1;

+		exportDirectory.NumberOfFunctions = (unsigned long)functionList.size();

+		exportDirectory.NumberOfNames = 0;

+		exportDirectory.AddressOfFunctions = exportsPage + sizeof(IMAGE_EXPORT_DIRECTORY);

+		exportDirectory.AddressOfNames = 0;

+		exportDirectory.AddressOfNameOrdinals = 0;

+

+		FILE *file = fopen(dllName, "wb");

+

+		if(file)

+		{

+			fwrite(&DOSheader, 1, sizeof(DOSheader), file);

+			

+			if(AMD64)

+			{

+				fwrite(&COFFheader64, 1, sizeof(COFFheader64), file);

+			}

+			else

+			{

+				fwrite(&COFFheader32, 1, sizeof(COFFheader32), file);

+			}

+

+			fwrite(&textSection, 1, sizeof(textSection), file);

+			fwrite(&exportsSection, 1, sizeof(textSection), file);

+			fwrite(&relocSection, 1, sizeof(relocSection), file);

+			fwrite(&constSection, 1, sizeof(constSection), file);

+			

+			for(FunctionList::iterator i = functionList.begin(); i != functionList.end(); i++)

+			{

+				const void *function = i->first;

+				unsigned int location = i->second->location;

+				const std::vector<Relocation> &functionRelocations = globalRelocations[function];

+

+				for(unsigned int j = 0; j < functionRelocations.size(); j++)

+				{

+					unsigned int *address = (unsigned int*)((unsigned char*)i->second->buffer + functionRelocations[j].offset);

+

+					if(functionRelocations[j].ripRelative)

+					{

+						*address = base + codePage + location + (*address - (unsigned int)(size_t)function);

+					}

+					else

+					{

+						*address = base + constPage + (*address - (unsigned int)(size_t)constants);

+					}

+				}

+

+				fseek(file, textSection.PointerToRawData + location, SEEK_SET);

+				fwrite(i->second->buffer, 1, i->second->size, file);

+			}

+

+			fseek(file, exportsSection.PointerToRawData, SEEK_SET);

+			fwrite(&exportDirectory, 1, sizeof(exportDirectory), file);

+

+			for(unsigned int i = 0; i < functionOrder.size(); i++)

+			{

+				const void *buffer = functionOrder[i];

+				Function *function = functionList[buffer];

+

+				unsigned int functionAddress = codePage + function->location;

+				unsigned int functionEntry = functionAddress + (int)((size_t)function->entry - (size_t)buffer);

+				fwrite(&functionEntry, 1, sizeof(functionEntry), file);

+			}

+

+			fwrite(dllName, 1, strlen(dllName) + 1, file);

+

+			fseek(file, relocSection.PointerToRawData, SEEK_SET);

+			

+			for(PageRelocations::iterator i = pageRelocations.begin(); i != pageRelocations.end(); i++)

+			{

+				IMAGE_BASE_RELOCATION relocationBlock;

+

+				relocationBlock.VirtualAddress = codePage + i->first * 0x1000;

+				relocationBlock.SizeOfBlock = (unsigned long)(sizeof(IMAGE_BASE_RELOCATION) + i->second.size() * sizeof(unsigned short));

+

+				fwrite(&relocationBlock, 1, sizeof(IMAGE_BASE_RELOCATION), file);

+

+				if(i->second.size() > 0)

+				{

+					fwrite(&i->second[0], 1, i->second.size() * sizeof(unsigned short), file);

+				}

+			}

+

+			fseek(file, constSection.PointerToRawData, SEEK_SET);

+			fwrite(constants, 1, constSize, file);

+

+			char *padding = new char[fileAlign(constSize) - constSize];

+			fwrite(padding, 1, fileAlign(constSize) - constSize, file);

+			delete[] padding;

+

+			fclose(file);

+		}

+	}

+}

diff --git a/src/Reactor/DLL.hpp b/src/Reactor/DLL.hpp
new file mode 100644
index 0000000..9e10caf
--- /dev/null
+++ b/src/Reactor/DLL.hpp
@@ -0,0 +1,102 @@
+// SwiftShader Software Renderer

+//

+// Copyright(c) 2005-2012 TransGaming Inc.

+//

+// All rights reserved. No part of this software may be copied, distributed, transmitted,

+// transcribed, stored in a retrieval system, translated into any human or computer

+// language by any means, or disclosed to third parties without the explicit written

+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

+// or implied, including but not limited to any patent rights, are granted to you.

+//

+

+#ifndef sw_DLL_hpp

+#define sw_DLL_hpp

+

+#include <windows.h>

+#include <vector>

+#include <map>

+

+namespace sw

+{

+	class DLL

+	{

+	public:

+		DLL(const char *name, const void *constants = 0, int constSize = 0);

+

+		~DLL();

+

+		void addFunction(const void *function, const void *entry, int size);

+		void addRelocation(const void *function, const void *address, bool ripRelative);

+		void emit();

+

+	private:

+		int pageAlign(int address)   // Align to 4 kB virtual page size

+		{

+			return (address + 0xFFF) & -0x1000;

+		}

+

+		int fileAlign(int address)   // Align to 512 byte file sections

+		{

+			return (address + 0x1FF) & -0x200;

+		}

+

+		char *dllName;

+

+		IMAGE_DOS_HEADER DOSheader;

+		IMAGE_NT_HEADERS32 COFFheader32;

+		IMAGE_NT_HEADERS64 COFFheader64;

+		IMAGE_SECTION_HEADER textSection;

+		IMAGE_SECTION_HEADER exportsSection;

+		IMAGE_SECTION_HEADER relocSection;

+		IMAGE_SECTION_HEADER constSection;

+

+		IMAGE_EXPORT_DIRECTORY exportDirectory;

+

+		struct Function

+		{

+			Function() {};

+			Function(unsigned int location, const void *function, const void *entry, int size) : location(location), entry(entry), size(size)

+			{

+				buffer = new unsigned char[size];

+				

+				memcpy(buffer, function, size);

+			}

+

+			~Function()

+			{

+				delete[] buffer;

+			}

+

+			void *buffer;

+

+			unsigned int location;

+			const void *entry;

+			int size;

+		};

+

+		std::vector<const void*> functionOrder;

+		typedef std::map<const void*, Function*> FunctionList;

+		FunctionList functionList;

+		int codeSize;

+

+		const void *constants;

+		int constSize;

+

+		struct Relocation

+		{

+			Relocation(unsigned int offset, bool ripRelative) : offset(offset), ripRelative(ripRelative)

+			{

+			}

+

+			unsigned int offset;

+			bool ripRelative;

+		};

+

+		typedef std::map<const void*, std::vector<Relocation> > GlobalRelocations;

+		GlobalRelocations globalRelocations;

+		typedef std::map<unsigned int, std::vector<unsigned short> > PageRelocations;

+		PageRelocations pageRelocations;

+	};

+}

+

+#endif   // sw_DLL_hpp

diff --git a/src/Reactor/Nucleus.cpp b/src/Reactor/Nucleus.cpp
index 9a429c7..fec9421 100644
--- a/src/Reactor/Nucleus.cpp
+++ b/src/Reactor/Nucleus.cpp
@@ -18,7 +18,7 @@
 #include "llvm/LLVMContext.h"
 #include "llvm/Constants.h"
 #include "llvm/Intrinsics.h"
-#include "llvm/Passmanager.h"
+#include "llvm/PassManager.h"
 #include "llvm/Analysis/LoopPass.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Target/TargetData.h"
@@ -34,6 +34,13 @@
 
 #include <fstream>
 
+#if defined(__x86_64__)
+extern "C" void X86CompilationCallback()
+{
+	assert(false);   // UNIMPLEMENTED
+}
+#endif
+
 extern "C"
 {
 	bool (*CodeAnalystInitialize)() = 0;
@@ -152,7 +159,7 @@
 
 		module = new Module("", *context);
 		memoryManager = new MemoryManager();
-		
+
 		#if defined(__x86_64__)
 			const char *architecture = "x86-64";
 		#else
@@ -176,15 +183,17 @@
 		{
 			builder = static_cast<Builder*>(new IRBuilder<>(*context));
 
-			HMODULE CodeAnalyst = LoadLibrary("CAJitNtfyLib.dll");
-			if(CodeAnalyst)
-			{
-				CodeAnalystInitialize = (bool(*)())GetProcAddress(CodeAnalyst, "CAJIT_Initialize");
-				CodeAnalystCompleteJITLog = (void(*)())GetProcAddress(CodeAnalyst, "CAJIT_CompleteJITLog");
-				CodeAnalystLogJITCode = (bool(*)(const void*, unsigned int, const wchar_t*))GetProcAddress(CodeAnalyst, "CAJIT_LogJITCode");
-			
-				CodeAnalystInitialize();
-			}
+			#if defined(_WIN32)
+				HMODULE CodeAnalyst = LoadLibrary("CAJitNtfyLib.dll");
+				if(CodeAnalyst)
+				{
+					CodeAnalystInitialize = (bool(*)())GetProcAddress(CodeAnalyst, "CAJIT_Initialize");
+					CodeAnalystCompleteJITLog = (void(*)())GetProcAddress(CodeAnalyst, "CAJIT_CompleteJITLog");
+					CodeAnalystLogJITCode = (bool(*)(const void*, unsigned int, const wchar_t*))GetProcAddress(CodeAnalyst, "CAJIT_LogJITCode");
+
+					CodeAnalystInitialize();
+				}
+			#endif
 		}
 	}
 
@@ -202,10 +211,6 @@
 	{
 		if(builder->GetInsertBlock()->empty() || !builder->GetInsertBlock()->back().isTerminator())
 		{
-			#if !(defined(_M_AMD64) || defined(_M_X64))
-				x86::emms();
-			#endif
-
 			Type *type = function->getReturnType();
 
 			if(type->isVoidTy())
@@ -220,7 +225,9 @@
 
 		if(false)
 		{
-			module->print(raw_fd_ostream("llvm-dump-unopt.txt", std::string()), 0);
+			std::string error;
+			raw_fd_ostream file("llvm-dump-unopt.txt", error);
+			module->print(file, 0);
 		}
 
 		if(runOptimizations)
@@ -230,11 +237,13 @@
 
 		if(false)
 		{
-			module->print(raw_fd_ostream("llvm-dump-opt.txt", std::string()), 0);
+			std::string error;
+			raw_fd_ostream file("llvm-dump-opt.txt", error);
+			module->print(file, 0);
 		}
 
 		void *entry = executionEngine->getPointerToFunction(function);
-		
+
 		Routine *routine = memoryManager->acquireRoutine();
 		routine->entry = entry;
 		markExecutable(routine->buffer, routine->bufferSize);
@@ -250,7 +259,7 @@
 	void Nucleus::optimize()
 	{
 		static PassManager *passManager = 0;
-		
+
 		if(!passManager)
 		{
 			passManager = new PassManager();
@@ -297,11 +306,6 @@
 		return module;
 	}
 
-	Builder *Nucleus::getBuilder()
-	{
-		return builder;
-	}
-
 	llvm::Function *Nucleus::getFunction()
 	{
 		return function;
@@ -379,11 +383,15 @@
 
 	Value *Nucleus::createRetVoid()
 	{
+		x86::emms();
+
 		return builder->CreateRetVoid();
 	}
 
 	Value *Nucleus::createRet(Value *V)
 	{
+		x86::emms();
+
 		return builder->CreateRet(V);
 	}
 
@@ -828,7 +836,7 @@
 		return llvm::Constant::getNullValue(Ty);
 	}
 
-	llvm::ConstantInt *Nucleus::createConstantLong(int64_t i)
+	llvm::ConstantInt *Nucleus::createConstantInt(int64_t i)
 	{
 		return llvm::ConstantInt::get(Type::getInt64Ty(*context), i, true);
 	}
@@ -888,6 +896,26 @@
 		return Type::getVoidTy(*Nucleus::getContext());
 	}
 
+	LValue::LValue(llvm::Type *type, int arraySize)
+	{
+		address = Nucleus::allocateStackVariable(type, arraySize);
+	}
+
+	llvm::Value *LValue::loadValue(unsigned int alignment) const
+	{
+		return Nucleus::createLoad(address, false, alignment);
+	}
+
+	llvm::Value *LValue::storeValue(llvm::Value *value, unsigned int alignment) const
+	{
+		return Nucleus::createStore(value, address, false, alignment);
+	}
+
+	llvm::Value *LValue::getAddress(llvm::Value *index) const
+	{
+		return Nucleus::createGEP(address, index);
+	}
+
 	Type *MMX::getType()
 	{
 		return Type::getX86_MMXTy(*Nucleus::getContext());
@@ -895,56 +923,56 @@
 
 	Bool::Bool(Argument *argument)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(argument, address);
+		storeValue(argument);
 	}
 
 	Bool::Bool()
 	{
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	Bool::Bool(bool x)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(Nucleus::createConstantBool(x), address);
+		storeValue(Nucleus::createConstantBool(x));
 	}
 
 	Bool::Bool(RValue<Bool> rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Bool::Bool(const Bool &rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+	Bool::Bool(const Reference<Bool> &rhs)
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<Bool> Bool::operator=(RValue<Bool> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<Bool> Bool::operator=(const Bool &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Bool>(value);
 	}
 
-	RValue<Pointer<Bool>> Bool::operator&()
+	RValue<Bool> Bool::operator=(const Reference<Bool> &rhs) const
 	{
-		return RValue<Pointer<Bool>>(address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Bool>(value);
 	}
 
 	RValue<Bool> operator!(RValue<Bool> val)
@@ -969,72 +997,68 @@
 
 	Byte::Byte(Argument *argument)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(argument, address);
+		storeValue(argument);
 	}
 
 	Byte::Byte(RValue<Int> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	Byte::Byte()
 	{
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	Byte::Byte(int x)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(Nucleus::createConstantByte((unsigned char)x), address);
+		storeValue(Nucleus::createConstantByte((unsigned char)x));
 	}
 
 	Byte::Byte(unsigned char x)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(Nucleus::createConstantByte(x), address);
+		storeValue(Nucleus::createConstantByte(x));
 	}
 
 	Byte::Byte(RValue<Byte> rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Byte::Byte(const Byte &rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+	Byte::Byte(const Reference<Byte> &rhs)
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<Byte> Byte::operator=(RValue<Byte> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<Byte> Byte::operator=(const Byte &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Byte>(value);
 	}
 
-	RValue<Pointer<Byte>> Byte::operator&()
+	RValue<Byte> Byte::operator=(const Reference<Byte> &rhs) const
 	{
-		return RValue<Pointer<Byte>>(address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Byte>(value);
 	}
 
 	RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
@@ -1157,15 +1181,15 @@
 		RValue<Byte> res = val;
 
 		Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantByte((unsigned char)1));
-		Nucleus::createStore(inc, val.address);
+		val.storeValue(inc);
 
 		return res;
 	}
 
 	const Byte &operator++(const Byte &val)   // Pre-increment
 	{
-		Value *inc = Nucleus::createAdd(Nucleus::createLoad(val.address), Nucleus::createConstantByte((unsigned char)1));
-		Nucleus::createStore(inc, val.address);
+		Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantByte((unsigned char)1));
+		val.storeValue(inc);
 
 		return val;
 	}
@@ -1175,15 +1199,15 @@
 		RValue<Byte> res = val;
 
 		Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantByte((unsigned char)1));
-		Nucleus::createStore(inc, val.address);
+		val.storeValue(inc);
 
 		return res;
 	}
 
 	const Byte &operator--(const Byte &val)   // Pre-decrement
 	{
-		Value *inc = Nucleus::createSub(Nucleus::createLoad(val.address), Nucleus::createConstantByte((unsigned char)1));
-		Nucleus::createStore(inc, val.address);
+		Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantByte((unsigned char)1));
+		val.storeValue(inc);
 
 		return val;
 	}
@@ -1225,56 +1249,56 @@
 
 	SByte::SByte(Argument *argument)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(argument, address);
+		storeValue(argument);
 	}
 
 	SByte::SByte()
 	{
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	SByte::SByte(signed char x)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(Nucleus::createConstantByte(x), address);
+		storeValue(Nucleus::createConstantByte(x));
 	}
 
 	SByte::SByte(RValue<SByte> rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	SByte::SByte(const SByte &rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+	SByte::SByte(const Reference<SByte> &rhs)
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<SByte> SByte::operator=(RValue<SByte> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<SByte> SByte::operator=(const SByte &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<SByte>(value);
 	}
 
-	RValue<Pointer<SByte>> SByte::operator&()
+	RValue<SByte> SByte::operator=(const Reference<SByte> &rhs) const
 	{
-		return RValue<Pointer<SByte>>(address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<SByte>(value);
 	}
 
 	RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
@@ -1397,15 +1421,15 @@
 		RValue<SByte> res = val;
 
 		Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantByte((signed char)1));
-		Nucleus::createStore(inc, val.address);
+		val.storeValue(inc);
 
 		return res;
 	}
 
 	const SByte &operator++(const SByte &val)   // Pre-increment
 	{
-		Value *inc = Nucleus::createAdd(Nucleus::createLoad(val.address), Nucleus::createConstantByte((signed char)1));
-		Nucleus::createStore(inc, val.address);
+		Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantByte((signed char)1));
+		val.storeValue(inc);
 
 		return val;
 	}
@@ -1415,15 +1439,15 @@
 		RValue<SByte> res = val;
 
 		Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantByte((signed char)1));
-		Nucleus::createStore(inc, val.address);
+		val.storeValue(inc);
 
 		return res;
 	}
 
 	const SByte &operator--(const SByte &val)   // Pre-decrement
 	{
-		Value *inc = Nucleus::createSub(Nucleus::createLoad(val.address), Nucleus::createConstantByte((signed char)1));
-		Nucleus::createStore(inc, val.address);
+		Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantByte((signed char)1));
+		val.storeValue(inc);
 
 		return val;
 	}
@@ -1465,65 +1489,63 @@
 
 	Short::Short(Argument *argument)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(argument, address);
+		storeValue(argument);
 	}
 
 	Short::Short(RValue<Int> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	Short::Short()
 	{
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	Short::Short(short x)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(Nucleus::createConstantShort(x), address);
+		storeValue(Nucleus::createConstantShort(x));
 	}
 
 	Short::Short(RValue<Short> rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Short::Short(const Short &rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+	Short::Short(const Reference<Short> &rhs)
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<Short> Short::operator=(RValue<Short> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<Short> Short::operator=(const Short &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Short>(value);
 	}
 
-	RValue<Pointer<Short>> Short::operator&()
+	RValue<Short> Short::operator=(const Reference<Short> &rhs) const
 	{
-		return RValue<Pointer<Short>>(address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Short>(value);
 	}
 
 	RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
@@ -1646,15 +1668,15 @@
 		RValue<Short> res = val;
 
 		Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantShort((short)1));
-		Nucleus::createStore(inc, val.address);
+		val.storeValue(inc);
 
 		return res;
 	}
 
 	const Short &operator++(const Short &val)   // Pre-increment
 	{
-		Value *inc = Nucleus::createAdd(Nucleus::createLoad(val.address), Nucleus::createConstantShort((short)1));
-		Nucleus::createStore(inc, val.address);
+		Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantShort((short)1));
+		val.storeValue(inc);
 
 		return val;
 	}
@@ -1664,15 +1686,15 @@
 		RValue<Short> res = val;
 
 		Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantShort((short)1));
-		Nucleus::createStore(inc, val.address);
+		val.storeValue(inc);
 
 		return res;
 	}
 
 	const Short &operator--(const Short &val)   // Pre-decrement
 	{
-		Value *inc = Nucleus::createSub(Nucleus::createLoad(val.address), Nucleus::createConstantShort((short)1));
-		Nucleus::createStore(inc, val.address);
+		Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantShort((short)1));
+		val.storeValue(inc);
 
 		return val;
 	}
@@ -1714,56 +1736,56 @@
 
 	UShort::UShort(Argument *argument)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(argument, address);
+		storeValue(argument);
 	}
 
 	UShort::UShort()
 	{
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	UShort::UShort(unsigned short x)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(Nucleus::createConstantShort(x), address);
+		storeValue(Nucleus::createConstantShort(x));
 	}
 
 	UShort::UShort(RValue<UShort> rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	UShort::UShort(const UShort &rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+	UShort::UShort(const Reference<UShort> &rhs)
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<UShort> UShort::operator=(RValue<UShort> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<UShort> UShort::operator=(const UShort &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<UShort>(value);
 	}
 
-	RValue<Pointer<UShort>> UShort::operator&()
+	RValue<UShort> UShort::operator=(const Reference<UShort> &rhs) const
 	{
-		return RValue<Pointer<UShort>>(address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<UShort>(value);
 	}
 
 	RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
@@ -1886,15 +1908,15 @@
 		RValue<UShort> res = val;
 
 		Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantShort((unsigned short)1));
-		Nucleus::createStore(inc, val.address);
+		val.storeValue(inc);
 
 		return res;
 	}
 
 	const UShort &operator++(const UShort &val)   // Pre-increment
 	{
-		Value *inc = Nucleus::createAdd(Nucleus::createLoad(val.address), Nucleus::createConstantShort((unsigned short)1));
-		Nucleus::createStore(inc, val.address);
+		Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantShort((unsigned short)1));
+		val.storeValue(inc);
 
 		return val;
 	}
@@ -1904,15 +1926,15 @@
 		RValue<UShort> res = val;
 
 		Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantShort((unsigned short)1));
-		Nucleus::createStore(inc, val.address);
+		val.storeValue(inc);
 
 		return res;
 	}
 
 	const UShort &operator--(const UShort &val)   // Pre-decrement
 	{
-		Value *inc = Nucleus::createSub(Nucleus::createLoad(val.address), Nucleus::createConstantShort((unsigned short)1));
-		Nucleus::createStore(inc, val.address);
+		Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantShort((unsigned short)1));
+		val.storeValue(inc);
 
 		return val;
 	}
@@ -1973,13 +1995,11 @@
 	Byte8::Byte8()
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	Byte8::Byte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[8];
 		constantVector[0] = Nucleus::createConstantByte(x0);
@@ -1992,13 +2012,12 @@
 		constantVector[7] = Nucleus::createConstantByte(x7);
 		Value *vector = Nucleus::createConstantVector(constantVector, 8);
 
-		Nucleus::createStore(Nucleus::createBitCast(vector, getType()), address);
+		storeValue(Nucleus::createBitCast(vector, getType()));
 	}
 
 	Byte8::Byte8(int64_t x)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[8];
 		constantVector[0] = Nucleus::createConstantByte((unsigned char)(x >>  0));
@@ -2011,37 +2030,51 @@
 		constantVector[7] = Nucleus::createConstantByte((unsigned char)(x >> 56));
 		Value *vector = Nucleus::createConstantVector(constantVector, 8);
 
-		Nucleus::createStore(Nucleus::createBitCast(vector, getType()), address);
+		storeValue(Nucleus::createBitCast(vector, getType()));
 	}
 
 	Byte8::Byte8(RValue<Byte8> rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Byte8::Byte8(const Byte8 &rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
+	Byte8::Byte8(const Reference<Byte8> &rhs)
+	{
+	//	xyzw.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<Byte8> Byte8::operator=(const Byte8 &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Byte8>(value);
+	}
+
+	RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Byte8>(value);
 	}
@@ -2116,7 +2149,7 @@
 			return As<Byte8>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
 		}
 		else
-		{	
+		{
 			return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
 		}
 	}
@@ -2207,7 +2240,7 @@
 	{
 		return x86::paddusb(x, y);
 	}
-	
+
 	RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
 	{
 		return x86::psubusb(x, y);
@@ -2244,7 +2277,7 @@
 			return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
 		}
 	}
-	
+
 	RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
 	{
 		if(CPUID::supportsMMX2())
@@ -2278,7 +2311,7 @@
 //	{
 //		return x86::pcmpgtb(x, y);   // FIXME: Signedness
 //	}
-	
+
 	RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
 	{
 		return x86::pcmpeqb(x, y);
@@ -2299,13 +2332,11 @@
 	SByte8::SByte8()
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	SByte8::SByte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[8];
 		constantVector[0] = Nucleus::createConstantByte(x0);
@@ -2318,13 +2349,12 @@
 		constantVector[7] = Nucleus::createConstantByte(x7);
 		Value *vector = Nucleus::createConstantVector(constantVector, 8);
 
-		Nucleus::createStore(Nucleus::createBitCast(vector, getType()), address);
+		storeValue(Nucleus::createBitCast(vector, getType()));
 	}
 
 	SByte8::SByte8(int64_t x)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[8];
 		constantVector[0] = Nucleus::createConstantByte((unsigned char)(x >>  0));
@@ -2337,37 +2367,51 @@
 		constantVector[7] = Nucleus::createConstantByte((unsigned char)(x >> 56));
 		Value *vector = Nucleus::createConstantVector(constantVector, 8);
 
-		Nucleus::createStore(Nucleus::createBitCast(vector, getType()), address);
+		storeValue(Nucleus::createBitCast(vector, getType()));
 	}
 
 	SByte8::SByte8(RValue<SByte8> rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	SByte8::SByte8(const SByte8 &rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
+	SByte8::SByte8(const Reference<SByte8> &rhs)
+	{
+	//	xyzw.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<SByte8> SByte8::operator=(const SByte8 &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<SByte8>(value);
+	}
+
+	RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<SByte8>(value);
 	}
@@ -2512,7 +2556,7 @@
 	{
 		return x86::paddsb(x, y);
 	}
-	
+
 	RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
 	{
 		return x86::psubsb(x, y);
@@ -2541,7 +2585,7 @@
 			return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
 		}
 	}
-	
+
 	RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
 	{
 		if(CPUID::supportsMMX2())
@@ -2575,7 +2619,7 @@
 	{
 		return x86::pcmpgtb(x, y);
 	}
-	
+
 	RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
 	{
 		return x86::pcmpeqb(As<Byte8>(x), As<Byte8>(y));
@@ -2596,31 +2640,45 @@
 	Byte16::Byte16(RValue<Byte16> rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Byte16::Byte16(const Byte16 &rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
+	Byte16::Byte16(const Reference<Byte16> &rhs)
+	{
+	//	xyzw.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<Byte16> Byte16::operator=(const Byte16 &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Byte16>(value);
+	}
+
+	RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Byte16>(value);
 	}
@@ -2637,18 +2695,14 @@
 
 	Short4::Short4(RValue<Int> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *extend = Nucleus::createZExt(cast.value, Long::getType());
 		Value *swizzle = Swizzle(RValue<Short4>(extend), 0x00).value;
-		
-		Nucleus::createStore(swizzle, address);
+
+		storeValue(swizzle);
 	}
 
 	Short4::Short4(RValue<Int4> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
 
 		#if 0   // FIXME: Check codegen (pshuflw phshufhw pshufd)
@@ -2724,7 +2778,7 @@
 			#endif
 		#endif
 
-		Nucleus::createStore(short4, address);
+		storeValue(short4);
 	}
 
 //	Short4::Short4(RValue<Float> cast)
@@ -2733,24 +2787,20 @@
 
 	Short4::Short4(RValue<Float4> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Int4 v4i32 = Int4(cast);
 		v4i32 = As<Int4>(x86::packssdw(v4i32, v4i32));
-		
-		Nucleus::createStore(As<Short4>(Int2(v4i32)).value, address);
+
+		storeValue(As<Short4>(Int2(v4i32)).value);
 	}
 
 	Short4::Short4()
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	Short4::Short4(short xyzw)
 	{
 		//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[4];
 		constantVector[0] = Nucleus::createConstantShort(xyzw);
@@ -2759,13 +2809,12 @@
 		constantVector[3] = Nucleus::createConstantShort(xyzw);
 		Value *vector = Nucleus::createConstantVector(constantVector, 4);
 
-		Nucleus::createStore(Nucleus::createBitCast(vector, getType()), address);
+		storeValue(Nucleus::createBitCast(vector, getType()));
 	}
 
 	Short4::Short4(short x, short y, short z, short w)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[4];
 		constantVector[0] = Nucleus::createConstantShort(x);
@@ -2774,69 +2823,95 @@
 		constantVector[3] = Nucleus::createConstantShort(w);
 		Value *vector = Nucleus::createConstantVector(constantVector, 4);
 
-		Nucleus::createStore(Nucleus::createBitCast(vector, getType()), address);
+		storeValue(Nucleus::createBitCast(vector, getType()));
 	}
 
 	Short4::Short4(RValue<Short4> rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Short4::Short4(const Short4 &rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
+	Short4::Short4(const Reference<Short4> &rhs)
+	{
+	//	xyzw.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	Short4::Short4(RValue<UShort4> rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Short4::Short4(const UShort4 &rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		storeValue(rhs.loadValue());
+	}
+
+	Short4::Short4(const Reference<UShort4> &rhs)
+	{
+	//	xyzw.parent = this;
+
+		storeValue(rhs.loadValue());
 	}
 
 	RValue<Short4> Short4::operator=(RValue<Short4> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<Short4> Short4::operator=(const Short4 &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Short4>(value);
+	}
+
+	RValue<Short4> Short4::operator=(const Reference<Short4> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Short4>(value);
 	}
 
 	RValue<Short4> Short4::operator=(RValue<UShort4> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
-		return rhs;
+		return RValue<Short4>(rhs);
 	}
 
 	RValue<Short4> Short4::operator=(const UShort4 &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Short4>(value);
+	}
+
+	RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Short4>(value);
 	}
@@ -3044,7 +3119,7 @@
 	{
 		RValue<Int4> v4i32 = x86::cvtps2dq(cast);
 		v4i32 = As<Int4>(x86::packssdw(v4i32, v4i32));
-		
+
 		return As<Short4>(Int2(v4i32));
 	}
 
@@ -3183,15 +3258,11 @@
 
 	UShort4::UShort4(RValue<Int4> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		*this = Short4(cast);
 	}
 
 	UShort4::UShort4(RValue<Float4> cast, bool saturate)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Float4 sat;
 
 		if(saturate)
@@ -3225,13 +3296,11 @@
 	UShort4::UShort4()
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[4];
 		constantVector[0] = Nucleus::createConstantShort(x);
@@ -3240,69 +3309,97 @@
 		constantVector[3] = Nucleus::createConstantShort(w);
 		Value *vector = Nucleus::createConstantVector(constantVector, 4);
 
-		Nucleus::createStore(Nucleus::createBitCast(vector, getType()), address);
+		storeValue(Nucleus::createBitCast(vector, getType()));
 	}
 
 	UShort4::UShort4(RValue<UShort4> rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	UShort4::UShort4(const UShort4 &rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
+	UShort4::UShort4(const Reference<UShort4> &rhs)
+	{
+	//	xyzw.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	UShort4::UShort4(RValue<Short4> rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	UShort4::UShort4(const Short4 &rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
+	UShort4::UShort4(const Reference<Short4> &rhs)
+	{
+	//	xyzw.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<UShort4> UShort4::operator=(const UShort4 &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<UShort4>(value);
+	}
+
+	RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<UShort4>(value);
 	}
 
 	RValue<UShort4> UShort4::operator=(RValue<Short4> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
-		return rhs;
+		return RValue<UShort4>(rhs);
 	}
 
 	RValue<UShort4> UShort4::operator=(const Short4 &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<UShort4>(value);
+	}
+
+	RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<UShort4>(value);
 	}
@@ -3406,12 +3503,12 @@
 
 	RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
 	{
-		return Max(As<Short4>(x) - Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u), As<Short4>(y) - Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u)) + Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u);;
+		return RValue<UShort4>(Max(As<Short4>(x) - Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u), As<Short4>(y) - Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u)) + Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u));
 	}
 
 	RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
 	{
-		return Min(As<Short4>(x) - Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u), As<Short4>(y) - Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u)) + Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u);;
+		return RValue<UShort4>(Min(As<Short4>(x) - Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u), As<Short4>(y) - Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u)) + Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u));
 	}
 
 	RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
@@ -3454,7 +3551,6 @@
 	Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[8];
 		constantVector[0] = Nucleus::createConstantShort(c0);
@@ -3466,15 +3562,14 @@
 		constantVector[6] = Nucleus::createConstantShort(c6);
 		constantVector[7] = Nucleus::createConstantShort(c7);
 
-		Nucleus::createStore(Nucleus::createConstantVector(constantVector, 8), address);
+		storeValue(Nucleus::createConstantVector(constantVector, 8));
 	}
 
 	Short8::Short8(RValue<Short8> rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
@@ -3528,7 +3623,6 @@
 	UShort8::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)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[8];
 		constantVector[0] = Nucleus::createConstantShort(c0);
@@ -3540,28 +3634,35 @@
 		constantVector[6] = Nucleus::createConstantShort(c6);
 		constantVector[7] = Nucleus::createConstantShort(c7);
 
-		Nucleus::createStore(Nucleus::createConstantVector(constantVector, 8), address);
+		storeValue(Nucleus::createConstantVector(constantVector, 8));
 	}
 
 	UShort8::UShort8(RValue<UShort8> rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<UShort8> UShort8::operator=(const UShort8 &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<UShort8>(value);
+	}
+
+	RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<UShort8>(value);
 	}
@@ -3680,152 +3781,148 @@
 
 	Int::Int(Argument *argument)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(argument, address);
+		storeValue(argument);
 	}
 
 	Int::Int(RValue<Byte> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *integer = Nucleus::createZExt(cast.value, Int::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	Int::Int(RValue<SByte> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *integer = Nucleus::createSExt(cast.value, Int::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	Int::Int(RValue<Short> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *integer = Nucleus::createSExt(cast.value, Int::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	Int::Int(RValue<UShort> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *integer = Nucleus::createZExt(cast.value, Int::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	Int::Int(RValue<Int2> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		*this = Extract(cast, 0);
 	}
 
 	Int::Int(RValue<Long> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	Int::Int(RValue<Float> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	Int::Int()
 	{
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	Int::Int(int x)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(Nucleus::createConstantInt(x), address);
+		storeValue(Nucleus::createConstantInt(x));
 	}
 
 	Int::Int(RValue<Int> rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Int::Int(RValue<UInt> rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Int::Int(const Int &rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+	Int::Int(const Reference<Int> &rhs)
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	Int::Int(const UInt &rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+	Int::Int(const Reference<UInt> &rhs)
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<Int> Int::operator=(int rhs) const
 	{
-		return RValue<Int>(Nucleus::createStore(Nucleus::createConstantInt(rhs), address));
+		return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
 	}
 
 	RValue<Int> Int::operator=(RValue<Int> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<Int> Int::operator=(RValue<UInt> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
-		return rhs;
+		return RValue<Int>(rhs);
 	}
 
 	RValue<Int> Int::operator=(const Int &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Int>(value);
+	}
+
+	RValue<Int> Int::operator=(const Reference<Int> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Int>(value);
 	}
 
 	RValue<Int> Int::operator=(const UInt &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Int>(value);
 	}
 
-	RValue<Pointer<Int>> Int::operator&()
+	RValue<Int> Int::operator=(const Reference<UInt> &rhs) const
 	{
-		return RValue<Pointer<Int>>(address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Int>(value);
 	}
 
 	RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
@@ -3948,15 +4045,15 @@
 		RValue<Int> res = val;
 
 		Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantInt(1));
-		Nucleus::createStore(inc, val.address);
+		val.storeValue(inc);
 
 		return res;
 	}
 
 	const Int &operator++(const Int &val)   // Pre-increment
 	{
-		Value *inc = Nucleus::createAdd(Nucleus::createLoad(val.address), Nucleus::createConstantInt(1));
-		Nucleus::createStore(inc, val.address);
+		Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantInt(1));
+		val.storeValue(inc);
 
 		return val;
 	}
@@ -3966,15 +4063,15 @@
 		RValue<Int> res = val;
 
 		Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantInt(1));
-		Nucleus::createStore(inc, val.address);
+		val.storeValue(inc);
 
 		return res;
 	}
 
 	const Int &operator--(const Int &val)   // Pre-decrement
 	{
-		Value *inc = Nucleus::createSub(Nucleus::createLoad(val.address), Nucleus::createConstantInt(1));
-		Nucleus::createStore(inc, val.address);
+		Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantInt(1));
+		val.storeValue(inc);
 
 		return val;
 	}
@@ -4028,7 +4125,7 @@
 	{
 		return x86::cvtss2si(cast);
 
-	//	return IfThenElse(val > Float(0), Int(val + Float(0.5f)), Int(val - Float(0.5f)));
+	//	return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
 	}
 
 	Type *Int::getType()
@@ -4038,50 +4135,53 @@
 
 	Long::Long(RValue<Int> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
+
 
 		Value *integer = Nucleus::createSExt(cast.value, Long::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	Long::Long(RValue<UInt> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *integer = Nucleus::createZExt(cast.value, Long::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	Long::Long()
 	{
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	Long::Long(RValue<Long> rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	RValue<Long> Long::operator=(int64_t rhs) const
 	{
-		return RValue<Long>(Nucleus::createStore(Nucleus::createConstantLong(rhs), address));
+		return RValue<Long>(storeValue(Nucleus::createConstantInt(rhs)));
 	}
 
 	RValue<Long> Long::operator=(RValue<Long> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<Long> Long::operator=(const Long &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Long>(value);
+	}
+
+	RValue<Long> Long::operator=(const Reference<Long> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Long>(value);
 	}
@@ -4106,7 +4206,7 @@
 		return lhs = lhs - rhs;
 	}
 
-	RValue<Long> AddAtomic(RValue<Pointer<Long>> x, RValue<Long> y)
+	RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
 	{
 		return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
 	}
@@ -4118,20 +4218,16 @@
 
 	Long1::Long1(const Reference<UInt> &cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Value *uint = Nucleus::createLoad(cast.address);
+		Value *uint = cast.loadValue();
 		Value *int64 = Nucleus::createZExt(uint, Long::getType());
 		Value *long1 = Nucleus::createBitCast(int64, Long1::getType());
-		
-		Nucleus::createStore(long1, address);
+
+		storeValue(long1);
 	}
 
 	Long1::Long1(RValue<Long1> rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Type *Long1::getType()
@@ -4164,125 +4260,127 @@
 
 	UInt::UInt(Argument *argument)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(argument, address);
+		storeValue(argument);
 	}
 
 	UInt::UInt(RValue<UShort> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	UInt::UInt(RValue<Long> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	UInt::UInt(RValue<Float> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *integer = Nucleus::createFPToSI(cast.value, UInt::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	UInt::UInt()
 	{
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	UInt::UInt(int x)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(Nucleus::createConstantInt(x), address);
+		storeValue(Nucleus::createConstantInt(x));
 	}
 
 	UInt::UInt(unsigned int x)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(Nucleus::createConstantInt(x), address);
+		storeValue(Nucleus::createConstantInt(x));
 	}
 
 	UInt::UInt(RValue<UInt> rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	UInt::UInt(RValue<Int> rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	UInt::UInt(const UInt &rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+	UInt::UInt(const Reference<UInt> &rhs)
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	UInt::UInt(const Int &rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+	UInt::UInt(const Reference<Int> &rhs)
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<UInt> UInt::operator=(unsigned int rhs) const
 	{
-		return RValue<UInt>(Nucleus::createStore(Nucleus::createConstantInt(rhs), address));
+		return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
 	}
 
 	RValue<UInt> UInt::operator=(RValue<UInt> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<UInt> UInt::operator=(RValue<Int> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
-		return rhs;
+		return RValue<UInt>(rhs);
 	}
 
 	RValue<UInt> UInt::operator=(const UInt &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<UInt>(value);
+	}
+
+	RValue<UInt> UInt::operator=(const Reference<UInt> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<UInt>(value);
 	}
 
 	RValue<UInt> UInt::operator=(const Int &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<UInt>(value);
 	}
 
-	RValue<Pointer<UInt>> UInt::operator&()
+	RValue<UInt> UInt::operator=(const Reference<Int> &rhs) const
 	{
-		return RValue<Pointer<UInt>>(address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<UInt>(value);
 	}
 
 	RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
@@ -4405,15 +4503,15 @@
 		RValue<UInt> res = val;
 
 		Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantInt(1));
-		Nucleus::createStore(inc, val.address);
+		val.storeValue(inc);
 
 		return res;
 	}
 
 	const UInt &operator++(const UInt &val)   // Pre-increment
 	{
-		Value *inc = Nucleus::createAdd(Nucleus::createLoad(val.address), Nucleus::createConstantInt(1));
-		Nucleus::createStore(inc, val.address);
+		Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantInt(1));
+		val.storeValue(inc);
 
 		return val;
 	}
@@ -4423,15 +4521,15 @@
 		RValue<UInt> res = val;
 
 		Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantInt(1));
-		Nucleus::createStore(inc, val.address);
+		val.storeValue(inc);
 
 		return res;
 	}
 
 	const UInt &operator--(const UInt &val)   // Pre-decrement
 	{
-		Value *inc = Nucleus::createSub(Nucleus::createLoad(val.address), Nucleus::createConstantInt(1));
-		Nucleus::createStore(inc, val.address);
+		Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantInt(1));
+		val.storeValue(inc);
 
 		return val;
 	}
@@ -4485,7 +4583,7 @@
 //	{
 //		return x86::cvtss2si(val);   // FIXME: Unsigned
 //
-//	//	return IfThenElse(val > Float(0), Int(val + Float(0.5f)), Int(val - Float(0.5f)));
+//	//	return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
 //	}
 
 	Type *UInt::getType()
@@ -4495,78 +4593,86 @@
 
 //	Int2::Int2(RValue<Int> cast)
 //	{
-//		address = Nucleus::allocateStackVariable(getType());
-//
 //		Value *extend = Nucleus::createZExt(cast.value, Long::getType());
 //		Value *vector = Nucleus::createBitCast(extend, Int2::getType());
-//		
+//
 //		Constant *shuffle[2];
 //		shuffle[0] = Nucleus::createConstantInt(0);
 //		shuffle[1] = Nucleus::createConstantInt(0);
 //
 //		Value *replicate = Nucleus::createShuffleVector(vector, UndefValue::get(Int2::getType()), Nucleus::createConstantVector(shuffle, 2));
 //
-//		Nucleus::createStore(replicate, address);
+//		storeValue(replicate);
 //	}
 
 	Int2::Int2(RValue<Int4> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *long2 = Nucleus::createBitCast(cast.value, Long2::getType());
 		Value *element = Nucleus::createExtractElement(long2, 0);
 		Value *int2 = Nucleus::createBitCast(element, Int2::getType());
 
-		Nucleus::createStore(int2, address);
+		storeValue(int2);
 	}
 
 	Int2::Int2()
 	{
 	//	xy.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	Int2::Int2(int x, int y)
 	{
 	//	xy.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[2];
 		constantVector[0] = Nucleus::createConstantInt(x);
 		constantVector[1] = Nucleus::createConstantInt(y);
 		Value *vector = Nucleus::createConstantVector(constantVector, 2);
 
-		Nucleus::createStore(Nucleus::createBitCast(vector, getType()), address);
+		storeValue(Nucleus::createBitCast(vector, getType()));
 	}
 
 	Int2::Int2(RValue<Int2> rhs)
 	{
 	//	xy.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Int2::Int2(const Int2 &rhs)
 	{
 	//	xy.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
+	Int2::Int2(const Reference<Int2> &rhs)
+	{
+	//	xy.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<Int2> Int2::operator=(RValue<Int2> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<Int2> Int2::operator=(const Int2 &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Int2>(value);
+	}
+
+	RValue<Int2> Int2::operator=(const Reference<Int2> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Int2>(value);
 	}
@@ -4773,7 +4879,7 @@
 			return RValue<Long1>(Nucleus::createBitCast(packed, Long1::getType()));
 		}
 	}
-	
+
 	RValue<Long1> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
 	{
 		if(CPUID::supportsMMX2())
@@ -4834,50 +4940,62 @@
 	UInt2::UInt2()
 	{
 	//	xy.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	UInt2::UInt2(unsigned int x, unsigned int y)
 	{
 	//	xy.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[2];
 		constantVector[0] = Nucleus::createConstantInt(x);
 		constantVector[1] = Nucleus::createConstantInt(y);
 		Value *vector = Nucleus::createConstantVector(constantVector, 2);
 
-		Nucleus::createStore(Nucleus::createBitCast(vector, getType()), address);
+		storeValue(Nucleus::createBitCast(vector, getType()));
 	}
 
 	UInt2::UInt2(RValue<UInt2> rhs)
 	{
 	//	xy.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	UInt2::UInt2(const UInt2 &rhs)
 	{
 	//	xy.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
+	UInt2::UInt2(const Reference<UInt2> &rhs)
+	{
+	//	xy.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<UInt2> UInt2::operator=(const UInt2 &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<UInt2>(value);
+	}
+
+	RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<UInt2>(value);
 	}
@@ -5082,17 +5200,15 @@
 	Int4::Int4(RValue<Float4> cast)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
 
-		Nucleus::createStore(xyzw, address);
+		storeValue(xyzw);
 	}
 
 	Int4::Int4()
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	Int4::Int4(int xyzw)
@@ -5118,7 +5234,6 @@
 	void Int4::constant(int x, int y, int z, int w)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[4];
 		constantVector[0] = Nucleus::createConstantInt(x);
@@ -5126,54 +5241,74 @@
 		constantVector[2] = Nucleus::createConstantInt(z);
 		constantVector[3] = Nucleus::createConstantInt(w);
 
-		Nucleus::createStore(Nucleus::createConstantVector(constantVector, 4), address);
+		storeValue(Nucleus::createConstantVector(constantVector, 4));
 	}
 
 	Int4::Int4(RValue<Int4> rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Int4::Int4(const Int4 &rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
+	Int4::Int4(const Reference<Int4> &rhs)
+	{
+	//	xyzw.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	Int4::Int4(RValue<UInt4> rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Int4::Int4(const UInt4 &rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
+	Int4::Int4(const Reference<UInt4> &rhs)
+	{
+	//	xyzw.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<Int4> Int4::operator=(RValue<Int4> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<Int4> Int4::operator=(const Int4 &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Int4>(value);
+	}
+
+	RValue<Int4> Int4::operator=(const Reference<Int4> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Int4>(value);
 	}
@@ -5404,17 +5539,15 @@
 	UInt4::UInt4(RValue<Float4> cast)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Value *xyzw = Nucleus::createFPToUI(cast.value, UInt4::getType());
 
-		Nucleus::createStore(xyzw, address);
+		storeValue(xyzw);
 	}
 
 	UInt4::UInt4()
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 	}
 
 	UInt4::UInt4(int xyzw)
@@ -5440,7 +5573,6 @@
 	void UInt4::constant(int x, int y, int z, int w)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[4];
 		constantVector[0] = Nucleus::createConstantInt(x);
@@ -5448,54 +5580,74 @@
 		constantVector[2] = Nucleus::createConstantInt(z);
 		constantVector[3] = Nucleus::createConstantInt(w);
 
-		Nucleus::createStore(Nucleus::createConstantVector(constantVector, 4), address);
+		storeValue(Nucleus::createConstantVector(constantVector, 4));
 	}
 
 	UInt4::UInt4(RValue<UInt4> rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	UInt4::UInt4(const UInt4 &rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
+	UInt4::UInt4(const Reference<UInt4> &rhs)
+	{
+	//	xyzw.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	UInt4::UInt4(RValue<Int4> rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	UInt4::UInt4(const Int4 &rhs)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
+	UInt4::UInt4(const Reference<Int4> &rhs)
+	{
+	//	xyzw.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<UInt4> UInt4::operator=(const UInt4 &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<UInt4>(value);
+	}
+
+	RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<UInt4>(value);
 	}
@@ -5700,58 +5852,59 @@
 
 	Float::Float(RValue<Int> cast)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
 		Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
 
-		Nucleus::createStore(integer, address);
+		storeValue(integer);
 	}
 
 	Float::Float()
 	{
-		address = Nucleus::allocateStackVariable(getType());
+
 	}
 
 	Float::Float(float x)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(Nucleus::createConstantFloat(x), address);
+		storeValue(Nucleus::createConstantFloat(x));
 	}
 
 	Float::Float(RValue<Float> rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
-
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Float::Float(const Float &rhs)
 	{
-		address = Nucleus::allocateStackVariable(getType());
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+	Float::Float(const Reference<Float> &rhs)
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	RValue<Float> Float::operator=(RValue<Float> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<Float> Float::operator=(const Float &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Float>(value);
 	}
 
-	RValue<Pointer<Float>> Float::operator&()
+	RValue<Float> Float::operator=(const Reference<Float> &rhs) const
 	{
-		return RValue<Pointer<Float>>(address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Float>(value);
 	}
 
 	RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
@@ -5836,7 +5989,7 @@
 
 	RValue<Float> Abs(RValue<Float> x)
 	{
-		return IfThenElse(x > Float(0), x, -x);
+		return IfThenElse(x > 0.0f, x, -x);
 	}
 
 	RValue<Float> Max(RValue<Float> x, RValue<Float> y)
@@ -5853,7 +6006,7 @@
 	{
 		return x86::rcpss(x);
 	}
-	
+
 	RValue<Float> RcpSqrt_pp(RValue<Float> x)
 	{
 		return x86::rsqrtss(x);
@@ -5932,13 +6085,12 @@
 	Float2::Float2(RValue<Float4> cast)
 	{
 	//	xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Value *int64x2 = Nucleus::createBitCast(cast.value, Long2::getType());
 		Value *int64 = Nucleus::createExtractElement(int64x2, 0);
 		Value *float2 = Nucleus::createBitCast(int64, Float2::getType());
 
-		Nucleus::createStore(float2, address);
+		storeValue(float2);
 	}
 
 	Type *Float2::getType()
@@ -5949,12 +6101,11 @@
 	Float4::Float4(RValue<Byte4> cast)
 	{
 		xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		#if 0
 			Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());   // FIXME: Crashes
 		#elif 0
-			Value *vector = Nucleus::createLoad(address);
+			Value *vector = loadValue();
 
 			Value *i8x = Nucleus::createExtractElement(cast.value, 0);
 			Value *f32x = Nucleus::createUIToFP(i8x, Float::getType());
@@ -6022,19 +6173,18 @@
 			Value *g = Nucleus::createSIToFP(f, Float4::getType());
 			Value *xyzw = g;
 		#endif
-		
-		Nucleus::createStore(xyzw, address);
+
+		storeValue(xyzw);
 	}
 
 	Float4::Float4(RValue<SByte4> cast)
 	{
 		xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		#if 0
 			Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());   // FIXME: Crashes
 		#elif 0
-			Value *vector = Nucleus::createLoad(address);
+			Value *vector = loadValue();
 
 			Value *i8x = Nucleus::createExtractElement(cast.value, 0);
 			Value *f32x = Nucleus::createSIToFP(i8x, Float::getType());
@@ -6104,19 +6254,18 @@
 
 			Value *xyzw = Nucleus::createSIToFP(g, Float4::getType());
 		#endif
-		
-		Nucleus::createStore(xyzw, address);
+
+		storeValue(xyzw);
 	}
 
 	Float4::Float4(RValue<Short4> cast)
 	{
 		xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		#if 0
 			Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());   // FIXME: Crashes
 		#elif 0
-			Value *vector = Nucleus::createLoad(address);
+			Value *vector = loadValue();
 
 			Value *i16x = Nucleus::createExtractElement(cast.value, 0);
 			Value *f32x = Nucleus::createSIToFP(i16x, Float::getType());
@@ -6160,11 +6309,11 @@
 				swizzle[5] = Nucleus::createConstantInt(2);
 				swizzle[6] = Nucleus::createConstantInt(3);
 				swizzle[7] = Nucleus::createConstantInt(3);
-				
+
 				Value *c = Nucleus::createShuffleVector(b, b, Nucleus::createConstantVector(swizzle, 8));
 				Value *d = Nucleus::createBitCast(c, Int4::getType());
 				Value *e = Nucleus::createSIToFP(d, Float4::getType());
-				
+
 				Constant *constantVector[4];
 				constantVector[0] = Nucleus::createConstantFloat(1.0f / (1 << 16));
 				constantVector[1] = Nucleus::createConstantFloat(1.0f / (1 << 16));
@@ -6174,19 +6323,18 @@
 				xyzw = Nucleus::createFMul(e, Nucleus::createConstantVector(constantVector, 4));
 			}
 		#endif
-		
-		Nucleus::createStore(xyzw, address);
+
+		storeValue(xyzw);
 	}
 
 	Float4::Float4(RValue<UShort4> cast)
 	{
 		xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		#if 0
 			Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());   // FIXME: Crashes
 		#elif 0
-			Value *vector = Nucleus::createLoad(address);
+			Value *vector = loadValue();
 
 			Value *i16x = Nucleus::createExtractElement(cast.value, 0);
 			Value *f32x = Nucleus::createUIToFP(i16x, Float::getType());
@@ -6210,7 +6358,7 @@
 			RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
 
 			Value *c;
-				
+
 			if(CPUID::supportsSSE4_1())
 			{
 				c = x86::pmovzxwd(RValue<Int4>(vector)).value;
@@ -6236,36 +6384,33 @@
 			Value *e = Nucleus::createSIToFP(d, Float4::getType());
 			Value *xyzw = e;
 		#endif
-		
-		Nucleus::createStore(xyzw, address);
+
+		storeValue(xyzw);
 	}
 
 	Float4::Float4(RValue<Int4> cast)
 	{
 		xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
 
-		Nucleus::createStore(xyzw, address);
+		storeValue(xyzw);
 	}
 
 	Float4::Float4(RValue<UInt4> cast)
 	{
 		xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());
 
-		Nucleus::createStore(xyzw, address);
+		storeValue(xyzw);
 	}
 
 	Float4::Float4()
 	{
 		xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 	}
-	
+
 	Float4::Float4(float xyzw)
 	{
 		constant(xyzw, xyzw, xyzw, xyzw);
@@ -6289,7 +6434,6 @@
 	void Float4::constant(float x, float y, float z, float w)
 	{
 		xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
 		Constant *constantVector[4];
 		constantVector[0] = Nucleus::createConstantFloat(x);
@@ -6297,32 +6441,37 @@
 		constantVector[2] = Nucleus::createConstantFloat(z);
 		constantVector[3] = Nucleus::createConstantFloat(w);
 
-		Nucleus::createStore(Nucleus::createConstantVector(constantVector, 4), address);
+		storeValue(Nucleus::createConstantVector(constantVector, 4));
 	}
 
 	Float4::Float4(RValue<Float4> rhs)
 	{
 		xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 	}
 
 	Float4::Float4(const Float4 &rhs)
 	{
 		xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
+	Float4::Float4(const Reference<Float4> &rhs)
+	{
+		xyzw.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
 	}
 
 	Float4::Float4(RValue<Float> rhs)
 	{
 		xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *vector = Nucleus::createLoad(address);
+		Value *vector = loadValue();
 		Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
 
 		Constant *swizzle[4];
@@ -6333,27 +6482,21 @@
 
 		Value *replicate = Nucleus::createShuffleVector(insert, UndefValue::get(Float4::getType()), Nucleus::createConstantVector(swizzle, 4));
 
-		Nucleus::createStore(replicate, address);
+		storeValue(replicate);
 	}
 
 	Float4::Float4(const Float &rhs)
 	{
 		xyzw.parent = this;
-		address = Nucleus::allocateStackVariable(getType());
 
-		Value *vector = Nucleus::createLoad(address);
-		Value *element = Nucleus::createLoad(rhs.address);
-		Value *insert = Nucleus::createInsertElement(vector, element, 0);
+		*this = RValue<Float>(rhs.loadValue());
+	}
 
-		Constant *swizzle[4];
-		swizzle[0] = Nucleus::createConstantInt(0);
-		swizzle[1] = Nucleus::createConstantInt(0);
-		swizzle[2] = Nucleus::createConstantInt(0);
-		swizzle[3] = Nucleus::createConstantInt(0);
+	Float4::Float4(const Reference<Float> &rhs)
+	{
+		xyzw.parent = this;
 
-		Value *replicate = Nucleus::createShuffleVector(insert, UndefValue::get(Float4::getType()), Nucleus::createConstantVector(swizzle, 4));
-
-		Nucleus::createStore(replicate, address);
+		*this = RValue<Float>(rhs.loadValue());
 	}
 
 	RValue<Float4> Float4::operator=(float x) const
@@ -6363,15 +6506,23 @@
 
 	RValue<Float4> Float4::operator=(RValue<Float4> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address);
+		storeValue(rhs.value);
 
 		return rhs;
 	}
 
 	RValue<Float4> Float4::operator=(const Float4 &rhs) const
 	{
-		Value *value = Nucleus::createLoad(rhs.address);
-		Nucleus::createStore(value, address);
+		Value *value = rhs.loadValue();
+		storeValue(value);
+
+		return RValue<Float4>(value);
+	}
+
+	RValue<Float4> Float4::operator=(const Reference<Float4> &rhs) const
+	{
+		Value *value = rhs.loadValue();
+		storeValue(value);
 
 		return RValue<Float4>(value);
 	}
@@ -6386,9 +6537,9 @@
 		return *this = Float4(rhs);
 	}
 
-	RValue<Pointer<Float4>> Float4::operator&()
+	RValue<Float4> Float4::operator=(const Reference<Float> &rhs) const
 	{
-		return RValue<Pointer<Float4>>(address);
+		return *this = Float4(rhs);
 	}
 
 	RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
@@ -6480,7 +6631,7 @@
 	{
 		return x86::rcpps(x);
 	}
-	
+
 	RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
 	{
 		return x86::rsqrtps(x);
@@ -6493,7 +6644,7 @@
 
 	RValue<Float4> Insert(const Float4 &val, RValue<Float> element, int i)
 	{
-		llvm::Value *value = Nucleus::createLoad(val.address);
+		llvm::Value *value = val.loadValue();
 		llvm::Value *insert = Nucleus::createInsertElement(value, element.value, i);
 
 		val = RValue<Float4>(insert);
@@ -6543,12 +6694,12 @@
 
 		return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4)));
 	}
-	
+
 	RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
 	{
-		Value *vector = Nucleus::createLoad(lhs.address);
+		Value *vector = lhs.loadValue();
 		Value *shuffle = Nucleus::createMask(vector, rhs.value, select);
-		Nucleus::createStore(shuffle, lhs.address);
+		lhs.storeValue(shuffle);
 
 		return RValue<Float4>(shuffle);
 	}
@@ -6661,72 +6812,68 @@
 		return VectorType::get(Float::getType(), 4);
 	}
 
-	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
+	RValue<Pointer<Byte> > operator+(RValue<Pointer<Byte> > lhs, int offset)
 	{
-		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Nucleus::createConstantInt(offset)));
+		return RValue<Pointer<Byte> >(Nucleus::createGEP(lhs.value, Nucleus::createConstantInt(offset)));
 	}
 
-	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
+	RValue<Pointer<Byte> > operator+(RValue<Pointer<Byte> > lhs, RValue<Int> offset)
 	{
-		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, offset.value));
+		return RValue<Pointer<Byte> >(Nucleus::createGEP(lhs.value, offset.value));
 	}
 
-	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
+	RValue<Pointer<Byte> > operator+(RValue<Pointer<Byte> > lhs, RValue<UInt> offset)
 	{
-		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, offset.value));
+		return RValue<Pointer<Byte> >(Nucleus::createGEP(lhs.value, offset.value));
 	}
 
-	RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset)
+	RValue<Pointer<Byte> > operator+=(const Pointer<Byte> &lhs, int offset)
 	{
 		return lhs = lhs + offset;
 	}
 
-	RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<Int> offset)
+	RValue<Pointer<Byte> > operator+=(const Pointer<Byte> &lhs, RValue<Int> offset)
 	{
 		return lhs = lhs + offset;
 	}
 
-	RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset)
+	RValue<Pointer<Byte> > operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset)
 	{
 		return lhs = lhs + offset;
 	}
 
-	RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
+	RValue<Pointer<Byte> > operator-(RValue<Pointer<Byte> > lhs, int offset)
 	{
 		return lhs + -offset;
 	}
 
-	RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
+	RValue<Pointer<Byte> > operator-(RValue<Pointer<Byte> > lhs, RValue<Int> offset)
 	{
 		return lhs + -offset;
 	}
 
-	RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
+	RValue<Pointer<Byte> > operator-(RValue<Pointer<Byte> > lhs, RValue<UInt> offset)
 	{
 		return lhs + -offset;
 	}
 
-	RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, int offset)
+	RValue<Pointer<Byte> > operator-=(const Pointer<Byte> &lhs, int offset)
 	{
 		return lhs = lhs - offset;
 	}
 
-	RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<Int> offset)
+	RValue<Pointer<Byte> > operator-=(const Pointer<Byte> &lhs, RValue<Int> offset)
 	{
 		return lhs = lhs - offset;
 	}
 
-	RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset)
+	RValue<Pointer<Byte> > operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset)
 	{
 		return lhs = lhs - offset;
 	}
 
 	void Return()
 	{
-		#if !(defined(_M_AMD64) || defined(_M_X64))
-			x86::emms();
-		#endif
-
 		Nucleus::createRetVoid();
 		Nucleus::setInsertBlock(Nucleus::createBasicBlock());
 		Nucleus::createUnreachable();
@@ -6734,10 +6881,6 @@
 
 	void Return(bool ret)
 	{
-		#if !(defined(_M_AMD64) || defined(_M_X64))
-			x86::emms();
-		#endif
-
 		Nucleus::createRet(Nucleus::createConstantBool(ret));
 		Nucleus::setInsertBlock(Nucleus::createBasicBlock());
 		Nucleus::createUnreachable();
@@ -6745,11 +6888,7 @@
 
 	void Return(const Int &ret)
 	{
-		#if !(defined(_M_AMD64) || defined(_M_X64))
-			x86::emms();
-		#endif
-
-		Nucleus::createRet(Nucleus::createLoad(ret.address));
+		Nucleus::createRet(ret.loadValue());
 		Nucleus::setInsertBlock(Nucleus::createBasicBlock());
 		Nucleus::createUnreachable();
 	}
@@ -6759,7 +6898,7 @@
 		BasicBlock *loopBB = Nucleus::createBasicBlock();
 
 		Nucleus::createBr(loopBB);
-		Nucleus::getBuilder()->SetInsertPoint(loopBB);
+		Nucleus::setInsertBlock(loopBB);
 
 		return loopBB;
 	}
@@ -6767,15 +6906,15 @@
 	bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
 	{
 		Nucleus::createCondBr(cmp.value, bodyBB, endBB);
-		Nucleus::getBuilder()->SetInsertPoint(bodyBB);
-		
+		Nucleus::setInsertBlock(bodyBB);
+
 		return true;
 	}
 
 	bool elseBlock(BasicBlock *falseBB)
 	{
 		falseBB->back().eraseFromParent();
-		Nucleus::getBuilder()->SetInsertPoint(falseBB);
+		Nucleus::setInsertBlock(falseBB);
 
 		return true;
 	}
@@ -6787,11 +6926,6 @@
 
 		return RValue<Long>(Nucleus::createCall(rdtsc));
 	}
-
-	void Emms()
-	{
-		x86::emms();
-	}
 }
 
 namespace sw
@@ -6802,7 +6936,7 @@
 		{
 			Module *module = Nucleus::getModule();
 			llvm::Function *cvtss2si = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_cvtss2si);
-			
+
 			Float4 vector;
 			vector.x = val;
 
@@ -6838,7 +6972,7 @@
 			{
 				Int2 lo = x86::cvtps2pi(val);
 				Int2 hi = x86::cvtps2pi(Swizzle(val, 0xEE));
-				
+
 				return Concatenate(lo, hi);
 			}
 		}
@@ -6849,7 +6983,7 @@
 			llvm::Function *rcpss = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_rcp_ss);
 
 			Value *vector = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), val.value, 0);
-			
+
 			return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(rcpss, vector), 0));
 		}
 
@@ -6859,7 +6993,7 @@
 			llvm::Function *sqrtss = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_sqrt_ss);
 
 			Value *vector = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), val.value, 0);
-			
+
 			return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(sqrtss, vector), 0));
 		}
 
@@ -6867,7 +7001,7 @@
 		{
 			Module *module = Nucleus::getModule();
 			llvm::Function *rsqrtss = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_rsqrt_ss);
-			
+
 			Value *vector = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), val.value, 0);
 
 			return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(rsqrtss, vector), 0));
@@ -6877,7 +7011,7 @@
 		{
 			Module *module = Nucleus::getModule();
 			llvm::Function *rcpps = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_rcp_ps);
-			
+
 			return RValue<Float4>(Nucleus::createCall(rcpps, val.value));
 		}
 
@@ -6885,7 +7019,7 @@
 		{
 			Module *module = Nucleus::getModule();
 			llvm::Function *sqrtps = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_sqrt_ps);
-			
+
 			return RValue<Float4>(Nucleus::createCall(sqrtps, val.value));
 		}
 
@@ -6893,7 +7027,7 @@
 		{
 			Module *module = Nucleus::getModule();
 			llvm::Function *rsqrtps = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_rsqrt_ps);
-			
+
 			return RValue<Float4>(Nucleus::createCall(rsqrtps, val.value));
 		}
 
@@ -7066,7 +7200,7 @@
 
 			return As<Short4>(RValue<MMX>(Nucleus::createCall(paddsw, As<MMX>(x).value, As<MMX>(y).value)));
 		}
-		
+
 		RValue<Short4> psubsw(RValue<Short4> x, RValue<Short4> y)
 		{
 			Module *module = Nucleus::getModule();
@@ -7082,7 +7216,7 @@
 
 			return As<UShort4>(RValue<MMX>(Nucleus::createCall(paddusw, As<MMX>(x).value, As<MMX>(y).value)));
 		}
-		
+
 		RValue<UShort4> psubusw(RValue<UShort4> x, RValue<UShort4> y)
 		{
 			Module *module = Nucleus::getModule();
@@ -7098,7 +7232,7 @@
 
 			return As<SByte8>(RValue<MMX>(Nucleus::createCall(paddsb, As<MMX>(x).value, As<MMX>(y).value)));
 		}
-		
+
 		RValue<SByte8> psubsb(RValue<SByte8> x, RValue<SByte8> y)
 		{
 			Module *module = Nucleus::getModule();
@@ -7106,7 +7240,7 @@
 
 			return As<SByte8>(RValue<MMX>(Nucleus::createCall(psubsb, As<MMX>(x).value, As<MMX>(y).value)));
 		}
-		
+
 		RValue<Byte8> paddusb(RValue<Byte8> x, RValue<Byte8> y)
 		{
 			Module *module = Nucleus::getModule();
@@ -7114,7 +7248,7 @@
 
 			return As<Byte8>(RValue<MMX>(Nucleus::createCall(paddusb, As<MMX>(x).value, As<MMX>(y).value)));
 		}
-		
+
 		RValue<Byte8> psubusb(RValue<Byte8> x, RValue<Byte8> y)
 		{
 			Module *module = Nucleus::getModule();
@@ -7355,10 +7489,10 @@
 
 				Int2 loY = Int2(y);
 				Int2 hiY = Int2(Swizzle(y, 0xEE));
-				
+
 				Short4 lo = x86::packssdw(loX, hiX);
 				Short4 hi = x86::packssdw(loY, hiY);
-				
+
 				return Concatenate(lo, hi);
 			}
 		}
@@ -7385,7 +7519,7 @@
 			{
 				Module *module = Nucleus::getModule();
 				llvm::Function *packusdw = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_packusdw);
-	
+
 				return RValue<UShort8>(Nucleus::createCall(packusdw, x.value, y.value));
 			}
 			else
@@ -7464,10 +7598,10 @@
 			{
 				Int2 lo = Int2(x);
 				Int2 hi = Int2(Swizzle(x, 0xEE));
-				
+
 				lo = x86::pslld(lo, y);
 				hi = x86::pslld(hi, y);
-				
+
 				return Concatenate(lo, hi);
 			}
 		}
@@ -7493,10 +7627,10 @@
 			{
 				Int2 lo = Int2(x);
 				Int2 hi = Int2(Swizzle(x, 0xEE));
-				
+
 				lo = x86::psrad(lo, y);
 				hi = x86::psrad(hi, y);
-				
+
 				return Concatenate(lo, hi);
 			}
 		}
@@ -7522,10 +7656,10 @@
 			{
 				UInt2 lo = As<UInt2>(Int2(As<Int4>(x)));
 				UInt2 hi = As<UInt2>(Int2(Swizzle(As<Int4>(x), 0xEE)));
-				
+
 				lo = x86::psrld(lo, y);
 				hi = x86::psrld(hi, y);
-				
+
 				return Concatenate(lo, hi);
 			}
 		}
@@ -7599,7 +7733,7 @@
 			Module *module = Nucleus::getModule();
 			llvm::Function *pmaxud = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pmaxud);
 
-			return RValue<Int4>(Nucleus::createCall(pmaxud, x.value, y.value));
+			return RValue<UInt4>(Nucleus::createCall(pmaxud, x.value, y.value));
 		}
 
 		RValue<UInt4> pminud(RValue<UInt4> x, RValue<UInt4> y)
@@ -7607,7 +7741,7 @@
 			Module *module = Nucleus::getModule();
 			llvm::Function *pminud = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pminud);
 
-			return RValue<Int4>(Nucleus::createCall(pminud, x.value, y.value));
+			return RValue<UInt4>(Nucleus::createCall(pminud, x.value, y.value));
 		}
 
 		RValue<Short4> pmulhw(RValue<Short4> x, RValue<Short4> y)
@@ -7674,7 +7808,7 @@
 			return RValue<Int>(Nucleus::createCall(pmovmskb, As<MMX>(x).value));
 		}
 
-		//RValue<Int2> movd(RValue<Pointer<Int>> x)
+		//RValue<Int2> movd(RValue<Pointer<Int> > x)
 		//{
 		//	Value *element = Nucleus::createLoad(x.value);
 
@@ -7698,7 +7832,7 @@
 		{
 			Module *module = Nucleus::getModule();
 			llvm::Function *pmovzxbd = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pmovzxbd);
-		
+
 			return RValue<Int4>(Nucleus::createCall(pmovzxbd, Nucleus::createBitCast(x.value, Byte16::getType())));
 		}
 
@@ -7706,7 +7840,7 @@
 		{
 			Module *module = Nucleus::getModule();
 			llvm::Function *pmovsxbd = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pmovsxbd);
-		
+
 			return RValue<Int4>(Nucleus::createCall(pmovsxbd, Nucleus::createBitCast(x.value, SByte16::getType())));
 		}
 
@@ -7714,7 +7848,7 @@
 		{
 			Module *module = Nucleus::getModule();
 			llvm::Function *pmovzxwd = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pmovzxwd);
-		
+
 			return RValue<Int4>(Nucleus::createCall(pmovzxwd, Nucleus::createBitCast(x.value, UShort8::getType())));
 		}
 
@@ -7722,7 +7856,7 @@
 		{
 			Module *module = Nucleus::getModule();
 			llvm::Function *pmovsxwd = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pmovsxwd);
-		
+
 			return RValue<Int4>(Nucleus::createCall(pmovsxwd, Nucleus::createBitCast(x.value, Short8::getType())));
 		}
 
diff --git a/src/Reactor/Nucleus.hpp b/src/Reactor/Nucleus.hpp
index 12b9e66..c029088 100644
--- a/src/Reactor/Nucleus.hpp
+++ b/src/Reactor/Nucleus.hpp
@@ -16,10 +16,13 @@
 

 #include <stdarg.h>

 #include <vector>

+#include <stdio.h>

+#include <wchar.h>

 

 #undef abs

 #undef max

 #undef min

+#undef Bool

 

 namespace llvm

 {

@@ -64,7 +67,7 @@
 

 	class Routine

 	{

-		friend Nucleus;

+		friend class Nucleus;

 

 	public:

 		Routine(int bufferSize);

@@ -106,7 +109,6 @@
 		static void setFunction(llvm::Function *function);

 

 		static llvm::Module *getModule();

-		static Builder *getBuilder();

 		static llvm::Function *getFunction();

 		static llvm::LLVMContext *getContext();

 

@@ -124,7 +126,7 @@
 		static llvm::Value *createRet(llvm::Value *V);

 		static llvm::Value *createBr(llvm::BasicBlock *dest);

 		static llvm::Value *createCondBr(llvm::Value *cond, llvm::BasicBlock *ifTrue, llvm::BasicBlock *ifFalse);

-		

+

 		// Binary operators

 		static llvm::Value *createAdd(llvm::Value *lhs, llvm::Value *rhs);

 		static llvm::Value *createSub(llvm::Value *lhs, llvm::Value *rhs);

@@ -147,7 +149,7 @@
 		static llvm::Value *createNeg(llvm::Value *V);

 		static llvm::Value *createFNeg(llvm::Value *V);

 		static llvm::Value *createNot(llvm::Value *V);

-  

+

 		// Memory instructions

 		static llvm::Value *createLoad(llvm::Value *ptr, bool isVolatile = false, unsigned int align = 0);

 		static llvm::Value *createStore(llvm::Value *value, llvm::Value *ptr, bool isVolatile = false, unsigned int align = 0);

@@ -227,7 +229,7 @@
 

 		// Constant values

 		static llvm::Constant *createNullValue(llvm::Type *Ty);

-		static llvm::ConstantInt *createConstantLong(int64_t i);

+		static llvm::ConstantInt *createConstantInt(int64_t i);

 		static llvm::ConstantInt *createConstantInt(int i);

 		static llvm::ConstantInt *createConstantInt(unsigned int i);

 		static llvm::ConstantInt *createConstantBool(bool b);

@@ -281,7 +283,7 @@
 	{

 	public:

 		static llvm::Type *getType();

-		

+

 		static bool isVoid()

 		{

 			return true;

@@ -291,35 +293,52 @@
 	};

 

 	template<class T>

-	class Variable

+	class RValue;

+

+	template<class T>

+	class Pointer;

+

+	class LValue

 	{

 	public:

+		LValue(llvm::Type *type, int arraySize = 0);

+

 		static bool isVoid()

 		{

 			return false;

 		}

 

+		llvm::Value *loadValue(unsigned int alignment = 0) const;

+		llvm::Value *storeValue(llvm::Value *value, unsigned int alignment = 0) const;

+		llvm::Value *getAddress(llvm::Value *index) const;

+

+	private:

 		llvm::Value *address;

-		typedef T ctype;

 	};

 

 	template<class T>

-	class RValue;

+	class Variable : public LValue

+	{

+	public:

+		Variable(int arraySize = 0);

+

+		RValue<Pointer<T> > operator&();

+	};

 

 	template<class T>

 	class Reference

 	{

-		friend Long1;

-

 	public:

 		explicit Reference(llvm::Value *pointer, int alignment = 1);

 

 		RValue<T> operator=(RValue<T> rhs) const;

-		operator RValue<T>() const;

 		RValue<T> operator=(const Reference<T> &ref) const;

 

 		RValue<T> operator+=(RValue<T> rhs) const;

 

+		llvm::Value *loadValue() const;

+		int getAlignment() const;

+

 	private:

 		llvm::Value *address;

 

@@ -338,6 +357,30 @@
 		typedef int type;

 	};

 

+	template<> struct

+	IntLiteral<UInt>

+	{

+		typedef unsigned int type;

+	};

+

+	template<> struct

+	IntLiteral<Long>

+	{

+		typedef int64_t type;

+	};

+

+	template<class T>

+	struct FloatLiteral

+	{

+		struct type;

+	};

+

+	template<> struct

+	FloatLiteral<Float>

+	{

+		typedef float type;

+	};

+

 	template<class T>

 	class RValue

 	{

@@ -346,20 +389,19 @@
 

 		RValue(const T &lvalue);

 		RValue(typename IntLiteral<T>::type i);

+		RValue(typename FloatLiteral<T>::type f);

+		RValue(const Reference<T> &rhs);

 

 		llvm::Value *value;   // FIXME: Make private

 	};

 

-	template<class T>

-	class Pointer;

-

-	class MMX : public Variable<uint64_t>

+	class MMX : public Variable<MMX>

 	{

 	public:

 		static llvm::Type *getType();

 	};

 

-	class Bool : public Variable<bool>

+	class Bool : public Variable<Bool>

 	{

 	public:

 		explicit Bool(llvm::Argument *argument);

@@ -368,12 +410,12 @@
 		Bool(bool x);

 		Bool(RValue<Bool> rhs);

 		Bool(const Bool &rhs);

+		Bool(const Reference<Bool> &rhs);

 

 	//	RValue<Bool> operator=(bool rhs) const;   // FIXME: Implement

 		RValue<Bool> operator=(RValue<Bool> rhs) const;

 		RValue<Bool> operator=(const Bool &rhs) const;

-

-		RValue<Pointer<Bool>> operator&();

+		RValue<Bool> operator=(const Reference<Bool> &rhs) const;

 

 		friend RValue<Bool> operator!(RValue<Bool> val);

 		friend RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs);

@@ -382,7 +424,7 @@
 		static llvm::Type *getType();

 	};

 

-	class Byte : public Variable<unsigned char>

+	class Byte : public Variable<Byte>

 	{

 	public:

 		explicit Byte(llvm::Argument *argument);

@@ -394,11 +436,12 @@
 		Byte(unsigned char x);

 		Byte(RValue<Byte> rhs);

 		Byte(const Byte &rhs);

+		Byte(const Reference<Byte> &rhs);

 

 	//	RValue<Byte> operator=(unsigned char rhs) const;   // FIXME: Implement

 		RValue<Byte> operator=(RValue<Byte> rhs) const;

 		RValue<Byte> operator=(const Byte &rhs) const;

-		RValue<Pointer<Byte>> operator&();

+		RValue<Byte> operator=(const Reference<Byte> &rhs) const;

 

 		friend RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs);

 		friend RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs);

@@ -437,7 +480,7 @@
 		static llvm::Type *getType();

 	};

 

-	class SByte : public Variable<signed char>

+	class SByte : public Variable<SByte>

 	{

 	public:

 		explicit SByte(llvm::Argument *argument);

@@ -446,11 +489,12 @@
 		SByte(signed char x);

 		SByte(RValue<SByte> rhs);

 		SByte(const SByte &rhs);

+		SByte(const Reference<SByte> &rhs);

 

 	//	RValue<SByte> operator=(signed char rhs) const;   // FIXME: Implement

 		RValue<SByte> operator=(RValue<SByte> rhs) const;

 		RValue<SByte> operator=(const SByte &rhs) const;

-		RValue<Pointer<SByte>> operator&();

+		RValue<SByte> operator=(const Reference<SByte> &rhs) const;

 

 		friend RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs);

 		friend RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs);

@@ -489,7 +533,7 @@
 		static llvm::Type *getType();

 	};

 

-	class Short : public Variable<short>

+	class Short : public Variable<Short>

 	{

 	public:

 		explicit Short(llvm::Argument *argument);

@@ -500,11 +544,12 @@
 		Short(short x);

 		Short(RValue<Short> rhs);

 		Short(const Short &rhs);

+		Short(const Reference<Short> &rhs);

 

 	//	RValue<Short> operator=(short rhs) const;   // FIXME: Implement

 		RValue<Short> operator=(RValue<Short> rhs) const;

 		RValue<Short> operator=(const Short &rhs) const;

-		RValue<Pointer<Short>> operator&();

+		RValue<Short> operator=(const Reference<Short> &rhs) const;

 

 		friend RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs);

 		friend RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs);

@@ -543,7 +588,7 @@
 		static llvm::Type *getType();

 	};

 

-	class UShort : public Variable<unsigned short>

+	class UShort : public Variable<UShort>

 	{

 	public:

 		explicit UShort(llvm::Argument *argument);

@@ -552,11 +597,12 @@
 		UShort(unsigned short x);

 		UShort(RValue<UShort> rhs);

 		UShort(const UShort &rhs);

+		UShort(const Reference<UShort> &rhs);

 

 	//	RValue<UShort> operator=(unsigned short rhs) const;   // FIXME: Implement

 		RValue<UShort> operator=(RValue<UShort> rhs) const;

 		RValue<UShort> operator=(const UShort &rhs) const;

-		RValue<Pointer<UShort>> operator&();

+		RValue<UShort> operator=(const Reference<UShort> &rhs) const;

 

 		friend RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs);

 		friend RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs);

@@ -595,17 +641,18 @@
 		static llvm::Type *getType();

 	};

 

-	class Byte4 : public Variable<byte4>

+	class Byte4 : public Variable<Byte4>

 	{

 	public:

 	//	Byte4();

 	//	Byte4(int x, int y, int z, int w);

 	//	Byte4(RValue<Byte4> rhs);

 	//	Byte4(const Byte4 &rhs);

+	//	Byte4(const Reference<Byte4> &rhs);

 

 	//	RValue<Byte4> operator=(RValue<Byte4> rhs) const;

 	//	RValue<Byte4> operator=(const Byte4 &rhs) const;

-	//	RValue<Pointer<Byte4>> operator&();

+	//	RValue<Byte4> operator=(const Reference<Byte4> &rhs) const;

 

 	//	friend RValue<Byte4> operator+(RValue<Byte4> lhs, RValue<Byte4> rhs);

 	//	friend RValue<Byte4> operator-(RValue<Byte4> lhs, RValue<Byte4> rhs);

@@ -638,17 +685,18 @@
 		static llvm::Type *getType();

 	};

 

-	class SByte4 : public Variable<sbyte4>

+	class SByte4 : public Variable<SByte4>

 	{

 	public:

 	//	SByte4();

 	//	SByte4(int x, int y, int z, int w);

 	//	SByte4(RValue<SByte4> rhs);

 	//	SByte4(const SByte4 &rhs);

+	//	SByte4(const Reference<SByte4> &rhs);

 

 	//	RValue<SByte4> operator=(RValue<SByte4> rhs) const;

 	//	RValue<SByte4> operator=(const SByte4 &rhs) const;

-	//	RValue<Pointer<SByte4>> operator&();

+	//	RValue<SByte4> operator=(const Reference<SByte4> &rhs) const;

 

 	//	friend RValue<SByte4> operator+(RValue<SByte4> lhs, RValue<SByte4> rhs);

 	//	friend RValue<SByte4> operator-(RValue<SByte4> lhs, RValue<SByte4> rhs);

@@ -681,7 +729,7 @@
 		static llvm::Type *getType();

 	};

 

-	class Byte8 : public Variable<byte8>

+	class Byte8 : public Variable<Byte8>

 	{

 	public:

 		Byte8();

@@ -689,10 +737,11 @@
 		Byte8(int64_t x);

 		Byte8(RValue<Byte8> rhs);

 		Byte8(const Byte8 &rhs);

+		Byte8(const Reference<Byte8> &rhs);

 

 		RValue<Byte8> operator=(RValue<Byte8> rhs) const;

 		RValue<Byte8> operator=(const Byte8 &rhs) const;

-	//	RValue<Pointer<Byte8>> operator&();

+		RValue<Byte8> operator=(const Reference<Byte8> &rhs) const;

 

 		friend RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs);

 		friend RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs);

@@ -736,7 +785,7 @@
 		static llvm::Type *getType();

 	};

 

-	class SByte8 : public Variable<sbyte8>

+	class SByte8 : public Variable<SByte8>

 	{

 	public:

 		SByte8();

@@ -744,10 +793,11 @@
 		SByte8(int64_t x);

 		SByte8(RValue<SByte8> rhs);

 		SByte8(const SByte8 &rhs);

+		SByte8(const Reference<SByte8> &rhs);

 

 		RValue<SByte8> operator=(RValue<SByte8> rhs) const;

 		RValue<SByte8> operator=(const SByte8 &rhs) const;

-	//	RValue<Pointer<SByte8>> operator&();

+		RValue<SByte8> operator=(const Reference<SByte8> &rhs) const;

 

 		friend RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs);

 		friend RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs);

@@ -790,17 +840,18 @@
 		static llvm::Type *getType();

 	};

 

-	class Byte16 : public Variable<byte16>

+	class Byte16 : public Variable<Byte16>

 	{

 	public:

 	//	Byte16();

 	//	Byte16(int x, int y, int z, int w);

 		Byte16(RValue<Byte16> rhs);

 		Byte16(const Byte16 &rhs);

+		Byte16(const Reference<Byte16> &rhs);

 

 		RValue<Byte16> operator=(RValue<Byte16> rhs) const;

 		RValue<Byte16> operator=(const Byte16 &rhs) const;

-	//	RValue<Pointer<Byte16>> operator&();

+		RValue<Byte16> operator=(const Reference<Byte16> &rhs) const;

 

 	//	friend RValue<Byte16> operator+(RValue<Byte16> lhs, RValue<Byte16> rhs);

 	//	friend RValue<Byte16> operator-(RValue<Byte16> lhs, RValue<Byte16> rhs);

@@ -833,17 +884,18 @@
 		static llvm::Type *getType();

 	};

 

-	class SByte16 : public Variable<sbyte16>

+	class SByte16 : public Variable<SByte16>

 	{

 	public:

 	//	SByte16();

 	//	SByte16(int x, int y, int z, int w);

 	//	SByte16(RValue<SByte16> rhs);

 	//	SByte16(const SByte16 &rhs);

+	//	SByte16(const Reference<SByte16> &rhs);

 

 	//	RValue<SByte16> operator=(RValue<SByte16> rhs) const;

 	//	RValue<SByte16> operator=(const SByte16 &rhs) const;

-	//	RValue<Pointer<SByte16>> operator&();

+	//	RValue<SByte16> operator=(const Reference<SByte16> &rhs) const;

 

 	//	friend RValue<SByte16> operator+(RValue<SByte16> lhs, RValue<SByte16> rhs);

 	//	friend RValue<SByte16> operator-(RValue<SByte16> lhs, RValue<SByte16> rhs);

@@ -876,7 +928,7 @@
 		static llvm::Type *getType();

 	};

 

-	class Short4 : public Variable<short4>

+	class Short4 : public Variable<Short4>

 	{

 	public:

 		explicit Short4(RValue<Int> cast);

@@ -889,14 +941,17 @@
 		Short4(short x, short y, short z, short w);

 		Short4(RValue<Short4> rhs);

 		Short4(const Short4 &rhs);

+		Short4(const Reference<Short4> &rhs);

 		Short4(RValue<UShort4> rhs);

 		Short4(const UShort4 &rhs);

+		Short4(const Reference<UShort4> &rhs);

 

 		RValue<Short4> operator=(RValue<Short4> rhs) const;

 		RValue<Short4> operator=(const Short4 &rhs) const;

+		RValue<Short4> operator=(const Reference<Short4> &rhs) const;

 		RValue<Short4> operator=(RValue<UShort4> rhs) const;

 		RValue<Short4> operator=(const UShort4 &rhs) const;

-		RValue<Pointer<Short4>> operator&();

+		RValue<Short4> operator=(const Reference<UShort4> &rhs) const;

 

 		friend RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs);

 		friend RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs);

@@ -958,7 +1013,7 @@
 		static llvm::Type *getType();

 	};

 

-	class UShort4 : public Variable<ushort4>

+	class UShort4 : public Variable<UShort4>

 	{

 	public:

 		explicit UShort4(RValue<Int4> cast);

@@ -968,14 +1023,17 @@
 		UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w);

 		UShort4(RValue<UShort4> rhs);

 		UShort4(const UShort4 &rhs);

+		UShort4(const Reference<UShort4> &rhs);

 		UShort4(RValue<Short4> rhs);

 		UShort4(const Short4 &rhs);

+		UShort4(const Reference<Short4> &rhs);

 

 		RValue<UShort4> operator=(RValue<UShort4> rhs) const;

 		RValue<UShort4> operator=(const UShort4 &rhs) const;

+		RValue<UShort4> operator=(const Reference<UShort4> &rhs) const;

 		RValue<UShort4> operator=(RValue<Short4> rhs) const;

 		RValue<UShort4> operator=(const Short4 &rhs) const;

-	//	RValue<Pointer<UShort4>> operator&();

+		RValue<UShort4> operator=(const Reference<Short4> &rhs) const;

 

 		friend RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs);

 		friend RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs);

@@ -1022,17 +1080,18 @@
 		static llvm::Type *getType();

 	};

 

-	class Short8 : public Variable<short8>

+	class Short8 : public Variable<Short8>

 	{

 	public:

 	//	Short8();

 		Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7);

 		Short8(RValue<Short8> rhs);

 	//	Short8(const Short8 &rhs);

+	//	Short8(const Reference<Short8> &rhs);

 

 	//	RValue<Short8> operator=(RValue<Short8> rhs) const;

 	//	RValue<Short8> operator=(const Short8 &rhs) const;

-	//	RValue<Pointer<Short8>> operator&();

+	//	RValue<Short8> operator=(const Reference<Short8> &rhs) const;

 

 		friend RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs);

 	//	friend RValue<Short8> operator-(RValue<Short8> lhs, RValue<Short8> rhs);

@@ -1078,17 +1137,18 @@
 		static llvm::Type *getType();

 	};

 

-	class UShort8 : public Variable<ushort8>

+	class UShort8 : public Variable<UShort8>

 	{

 	public:

 	//	UShort8();

 		UShort8(unsigned short c0, unsigned short c1, unsigned short c2, unsigned short c3, unsigned short c4, unsigned short c5, unsigned short c6, unsigned short c7);

 		UShort8(RValue<UShort8> rhs);

 	//	UShort8(const UShort8 &rhs);

+	//	UShort8(const Reference<UShort8> &rhs);

 

 		RValue<UShort8> operator=(RValue<UShort8> rhs) const;

 		RValue<UShort8> operator=(const UShort8 &rhs) const;

-	//	RValue<Pointer<UShort8>> operator&();

+		RValue<UShort8> operator=(const Reference<UShort8> &rhs) const;

 

 		friend RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs);

 	//	friend RValue<UShort8> operator-(RValue<UShort8> lhs, RValue<UShort8> rhs);

@@ -1134,7 +1194,7 @@
 		static llvm::Type *getType();

 	};

 

-	class Int : public Variable<int>

+	class Int : public Variable<Int>

 	{

 	public:

 		explicit Int(llvm::Argument *argument);

@@ -1153,13 +1213,16 @@
 		Int(RValue<UInt> rhs);

 		Int(const Int &rhs);

 		Int(const UInt &rhs);

+		Int(const Reference<Int> &rhs);

+		Int(const Reference<UInt> &rhs);

 

 		RValue<Int> operator=(int rhs) const;

 		RValue<Int> operator=(RValue<Int> rhs) const;

 		RValue<Int> operator=(RValue<UInt> rhs) const;

 		RValue<Int> operator=(const Int &rhs) const;

 		RValue<Int> operator=(const UInt &rhs) const;

-		RValue<Pointer<Int>> operator&();

+		RValue<Int> operator=(const Reference<Int> &rhs) const;

+		RValue<Int> operator=(const Reference<UInt> &rhs) const;

 

 		friend RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs);

 		friend RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs);

@@ -1204,7 +1267,7 @@
 		static llvm::Type *getType();

 	};

 

-	class Long : public Variable<qword>

+	class Long : public Variable<Long>

 	{

 	public:

 	//	explicit Long(llvm::Argument *argument);

@@ -1220,14 +1283,17 @@
 		Long(RValue<Long> rhs);

 	//	Long(RValue<ULong> rhs);

 	//	Long(const Long &rhs);

+	//	Long(const Reference<Long> &rhs);

 	//	Long(const ULong &rhs);

+	//	Long(const Reference<ULong> &rhs);

 

 		RValue<Long> operator=(int64_t rhs) const;

 		RValue<Long> operator=(RValue<Long> rhs) const;

 	//	RValue<Long> operator=(RValue<ULong> rhs) const;

 		RValue<Long> operator=(const Long &rhs) const;

+		RValue<Long> operator=(const Reference<Long> &rhs) const;

 	//	RValue<Long> operator=(const ULong &rhs) const;

-	//	RValue<Pointer<Long>> operator&();

+	//	RValue<Long> operator=(const Reference<ULong> &rhs) const;

 

 		friend RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs);

 		friend RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs);

@@ -1265,12 +1331,12 @@
 

 	//	friend RValue<Long> RoundLong(RValue<Float> cast);

 

-		friend RValue<Long> AddAtomic( RValue<Pointer<Long>> x, RValue<Long> y);

+		friend RValue<Long> AddAtomic( RValue<Pointer<Long> > x, RValue<Long> y);

 

 		static llvm::Type *getType();

 	};

 

-	class Long1 : public Variable<qword>

+	class Long1 : public Variable<Long1>

 	{

 	public:

 	//	explicit Long1(llvm::Argument *argument);

@@ -1288,14 +1354,17 @@
 		Long1(RValue<Long1> rhs);

 	//	Long1(RValue<ULong1> rhs);

 	//	Long1(const Long1 &rhs);

+	//	Long1(const Reference<Long1> &rhs);

 	//	Long1(const ULong1 &rhs);

+	//	Long1(const Reference<ULong1> &rhs);

 

 	//	RValue<Long1> operator=(qword rhs) const;

 	//	RValue<Long1> operator=(RValue<Long1> rhs) const;

 	//	RValue<Long1> operator=(RValue<ULong1> rhs) const;

 	//	RValue<Long1> operator=(const Long1 &rhs) const;

+	//	RValue<Long1> operator=(const Reference<Long1> &rhs) const;

 	//	RValue<Long1> operator=(const ULong1 &rhs) const;

-	//	RValue<Pointer<Long1>> operator&();

+	//	RValue<Long1> operator=(const Reference<ULong1> &rhs) const;

 

 	//	friend RValue<Long1> operator+(RValue<Long1> lhs, RValue<Long1> rhs);

 	//	friend RValue<Long1> operator-(RValue<Long1> lhs, RValue<Long1> rhs);

@@ -1336,7 +1405,7 @@
 		static llvm::Type *getType();

 	};

 

-	class Long2 : public Variable<qword2>

+	class Long2 : public Variable<Long2>

 	{

 	public:

 	//	explicit Long2(RValue<Long> cast);

@@ -1346,10 +1415,11 @@
 	//	Long2(int x, int y);

 	//	Long2(RValue<Long2> rhs);

 	//	Long2(const Long2 &rhs);

+	//	Long2(const Reference<Long2> &rhs);

 

 	//	RValue<Long2> operator=(RValue<Long2> rhs) const;

 	//	RValue<Long2> operator=(const Long2 &rhs) const;

-	//	RValue<Pointer<Long2>> operator&();

+	//	RValue<Long2> operator=(const Reference<Long2 &rhs) const;

 

 	//	friend RValue<Long2> operator+(RValue<Long2> lhs, RValue<Long2> rhs);

 	//	friend RValue<Long2> operator-(RValue<Long2> lhs, RValue<Long2> rhs);

@@ -1399,7 +1469,7 @@
 		static llvm::Type *getType();

 	};

 

-	class UInt : public Variable<unsigned int>

+	class UInt : public Variable<UInt>

 	{

 	public:

 		explicit UInt(llvm::Argument *argument);

@@ -1415,13 +1485,16 @@
 		UInt(RValue<Int> rhs);

 		UInt(const UInt &rhs);

 		UInt(const Int &rhs);

+		UInt(const Reference<UInt> &rhs);

+		UInt(const Reference<Int> &rhs);

 

 		RValue<UInt> operator=(unsigned int rhs) const;

 		RValue<UInt> operator=(RValue<UInt> rhs) const;

 		RValue<UInt> operator=(RValue<Int> rhs) const;

 		RValue<UInt> operator=(const UInt &rhs) const;

 		RValue<UInt> operator=(const Int &rhs) const;

-		RValue<Pointer<UInt>> operator&();

+		RValue<UInt> operator=(const Reference<UInt> &rhs) const;

+		RValue<UInt> operator=(const Reference<Int> &rhs) const;

 

 		friend RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs);

 		friend RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs);

@@ -1466,7 +1539,7 @@
 		static llvm::Type *getType();

 	};

 

-	class Int2 : public Variable<int2>

+	class Int2 : public Variable<Int2>

 	{

 	public:

 	//	explicit Int2(RValue<Int> cast);

@@ -1476,10 +1549,11 @@
 		Int2(int x, int y);

 		Int2(RValue<Int2> rhs);

 		Int2(const Int2 &rhs);

+		Int2(const Reference<Int2> &rhs);

 

 		RValue<Int2> operator=(RValue<Int2> rhs) const;

 		RValue<Int2> operator=(const Int2 &rhs) const;

-	//	RValue<Pointer<Int2>> operator&();

+		RValue<Int2> operator=(const Reference<Int2> &rhs) const;

 

 		friend RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs);

 		friend RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs);

@@ -1529,17 +1603,18 @@
 		static llvm::Type *getType();

 	};

 

-	class UInt2 : public Variable<uint2>

+	class UInt2 : public Variable<UInt2>

 	{

 	public:

 		UInt2();

 		UInt2(unsigned int x, unsigned int y);

 		UInt2(RValue<UInt2> rhs);

 		UInt2(const UInt2 &rhs);

+		UInt2(const Reference<UInt2> &rhs);

 

 		RValue<UInt2> operator=(RValue<UInt2> rhs) const;

 		RValue<UInt2> operator=(const UInt2 &rhs) const;

-	//	RValue<Pointer<UInt2>> operator&();

+		RValue<UInt2> operator=(const Reference<UInt2> &rhs) const;

 

 		friend RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs);

 		friend RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs);

@@ -1584,7 +1659,7 @@
 		static llvm::Type *getType();

 	};

 

-	class Int4 : public Variable<int4>

+	class Int4 : public Variable<Int4>

 	{

 	public:

 		explicit Int4(RValue<Float4> cast);

@@ -1596,12 +1671,14 @@
 		Int4(int x, int y, int z, int w);

 		Int4(RValue<Int4> rhs);

 		Int4(const Int4 &rhs);

+		Int4(const Reference<Int4> &rhs);

 		Int4(RValue<UInt4> rhs);

 		Int4(const UInt4 &rhs);

+		Int4(const Reference<UInt4> &rhs);

 

 		RValue<Int4> operator=(RValue<Int4> rhs) const;

 		RValue<Int4> operator=(const Int4 &rhs) const;

-	//	RValue<Pointer<Int4>> operator&();

+		RValue<Int4> operator=(const Reference<Int4> &rhs) const;

 

 		friend RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs);

 		friend RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs);

@@ -1661,7 +1738,7 @@
 		void constant(int x, int y, int z, int w);

 	};

 

-	class UInt4 : public Variable<uint4>

+	class UInt4 : public Variable<UInt4>

 	{

 	public:

 		explicit UInt4(RValue<Float4> cast);

@@ -1674,12 +1751,14 @@
 		UInt4(unsigned int x, unsigned int y, unsigned int z, unsigned int w);

 		UInt4(RValue<UInt4> rhs);

 		UInt4(const UInt4 &rhs);

+		UInt4(const Reference<UInt4> &rhs);

 		UInt4(RValue<Int4> rhs);

 		UInt4(const Int4 &rhs);

+		UInt4(const Reference<Int4> &rhs);

 

 		RValue<UInt4> operator=(RValue<UInt4> rhs) const;

 		RValue<UInt4> operator=(const UInt4 &rhs) const;

-	//	RValue<Pointer<UInt4>> operator&();

+		RValue<UInt4> operator=(const Reference<UInt4> &rhs) const;

 

 		friend RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs);

 		friend RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs);

@@ -1735,7 +1814,73 @@
 		void constant(int x, int y, int z, int w);

 	};

 

-	class Float : public Variable<float>

+	template<int T>

+	class Swizzle2Float4

+	{

+		friend class Float4;

+

+	public:

+		operator RValue<Float4>() const;

+

+	private:

+		Float4 *parent;

+	};

+

+	template<int T>

+	class SwizzleFloat4

+	{

+	public:

+		operator RValue<Float4>() const;

+

+	private:

+		Float4 *parent;

+	};

+

+	template<int T>

+	class SwizzleMaskFloat4

+	{

+		friend class Float4;

+

+	public:

+		operator RValue<Float4>() const;

+

+		RValue<Float4> operator=(RValue<Float4> rhs) const;

+		RValue<Float4> operator=(RValue<Float> rhs) const;

+

+	private:

+		Float4 *parent;

+	};

+

+	template<int T>

+	class SwizzleMask1Float4

+	{

+	public:

+		operator RValue<Float>() const;

+		operator RValue<Float4>() const;

+

+		RValue<Float4> operator=(float x) const;

+		RValue<Float4> operator=(RValue<Float4> rhs) const;

+		RValue<Float4> operator=(RValue<Float> rhs) const;

+

+	private:

+		Float4 *parent;

+	};

+

+	template<int T>

+	class SwizzleMask2Float4

+	{

+		friend class Float4;

+

+	public:

+		operator RValue<Float4>() const;

+

+		RValue<Float4> operator=(RValue<Float4> rhs) const;

+

+	private:

+		Float4 *parent;

+	};

+

+	class Float : public Variable<Float>

 	{

 	public:

 		explicit Float(RValue<Int> cast);

@@ -1744,11 +1889,18 @@
 		Float(float x);

 		Float(RValue<Float> rhs);

 		Float(const Float &rhs);

+		Float(const Reference<Float> &rhs);

+

+		template<int T>

+		Float(const SwizzleMask1Float4<T> &rhs);

 

 	//	RValue<Float> operator=(float rhs) const;   // FIXME: Implement

 		RValue<Float> operator=(RValue<Float> rhs) const;

 		RValue<Float> operator=(const Float &rhs) const;

-		RValue<Pointer<Float>> operator&();

+		RValue<Float> operator=(const Reference<Float> &rhs) const;

+

+		template<int T>

+		RValue<Float> operator=(const SwizzleMask1Float4<T> &rhs) const;

 

 		friend RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs);

 		friend RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs);

@@ -1784,7 +1936,7 @@
 		static llvm::Type *getType();

 	};

 

-	class Float2 : public Variable<float2>

+	class Float2 : public Variable<Float2>

 	{

 	public:

 	//	explicit Float2(RValue<Byte2> cast);

@@ -1798,8 +1950,10 @@
 	//	Float2(float x, float y);

 	//	Float2(RValue<Float2> rhs);

 	//	Float2(const Float2 &rhs);

+	//	Float2(const Reference<Float2> &rhs);

 	//	Float2(RValue<Float> rhs);

 	//	Float2(const Float &rhs);

+	//	Float2(const Reference<Float> &rhs);

 

 	//	template<int T>

 	//	Float2(const SwizzleMask1Float4<T> &rhs);

@@ -1807,14 +1961,14 @@
 	//	RValue<Float2> operator=(float replicate) const;

 	//	RValue<Float2> operator=(RValue<Float2> rhs) const;

 	//	RValue<Float2> operator=(const Float2 &rhs) const;

+	//	RValue<Float2> operator=(const Reference<Float2> &rhs) const;

 	//	RValue<Float2> operator=(RValue<Float> rhs) const;

 	//	RValue<Float2> operator=(const Float &rhs) const;

+	//	RValue<Float2> operator=(const Reference<Float> &rhs) const;

 

 	//	template<int T>

 	//	RValue<Float2> operator=(const SwizzleMask1Float4<T> &rhs);

 

-	//	RValue<Pointer<Float2>> operator&();

-

 	//	friend RValue<Float2> operator+(RValue<Float2> lhs, RValue<Float2> rhs);

 	//	friend RValue<Float2> operator-(RValue<Float2> lhs, RValue<Float2> rhs);

 	//	friend RValue<Float2> operator*(RValue<Float2> lhs, RValue<Float2> rhs);

@@ -1838,73 +1992,7 @@
 		static llvm::Type *getType();

 	};

 

-	template<int T>

-	class Swizzle2Float4

-	{

-		friend Float4;

-

-	public:

-		operator RValue<Float4>() const;

-

-	private:

-		Float4 *parent;

-	};

-

-	template<int T>

-	class SwizzleFloat4

-	{

-	public:

-		operator RValue<Float4>() const;

-

-	private:

-		Float4 *parent;

-	};

-

-	template<int T>

-	class SwizzleMaskFloat4

-	{

-		friend Float4;

-

-	public:

-		operator RValue<Float4>() const;

-

-		RValue<Float4> operator=(RValue<Float4> rhs) const;

-		RValue<Float4> operator=(RValue<Float> rhs) const;

-

-	private:

-		Float4 *parent;

-	};

-

-	template<int T>

-	class SwizzleMask1Float4

-	{

-	public:

-		operator RValue<Float>() const;

-		operator RValue<Float4>() const;

-

-		RValue<Float4> operator=(float x) const;

-		RValue<Float4> operator=(RValue<Float4> rhs) const;

-		RValue<Float4> operator=(RValue<Float> rhs) const;

-

-	private:

-		Float4 *parent;

-	};

-

-	template<int T>

-	class SwizzleMask2Float4

-	{

-		friend Float4;

-

-	public:

-		operator RValue<Float4>() const;

-

-		RValue<Float4> operator=(RValue<Float4> rhs) const;

-

-	private:

-		Float4 *parent;

-	};

-

-	class Float4 : public Variable<float4>

+	class Float4 : public Variable<Float4>

 	{

 	public:

 		explicit Float4(RValue<Byte4> cast);

@@ -1921,11 +2009,15 @@
 		Float4(float x, float y, float z, float w);

 		Float4(RValue<Float4> rhs);

 		Float4(const Float4 &rhs);

+		Float4(const Reference<Float4> &rhs);

 		Float4(RValue<Float> rhs);

 		Float4(const Float &rhs);

+		Float4(const Reference<Float> &rhs);

 

 		template<int T>

 		Float4(const SwizzleMask1Float4<T> &rhs);

+		template<int T>

+		Float4(const SwizzleFloat4<T> &rhs);

 		template<int X, int Y>

 		Float4(const Swizzle2Float4<X> &x, const Swizzle2Float4<Y> &y);

 		template<int X, int Y>

@@ -1938,13 +2030,15 @@
 		RValue<Float4> operator=(float replicate) const;

 		RValue<Float4> operator=(RValue<Float4> rhs) const;

 		RValue<Float4> operator=(const Float4 &rhs) const;

+		RValue<Float4> operator=(const Reference<Float4> &rhs) const;

 		RValue<Float4> operator=(RValue<Float> rhs) const;

 		RValue<Float4> operator=(const Float &rhs) const;

+		RValue<Float4> operator=(const Reference<Float> &rhs) const;

 

 		template<int T>

 		RValue<Float4> operator=(const SwizzleMask1Float4<T> &rhs);

-

-		RValue<Pointer<Float4>> operator&();

+		template<int T>

+		RValue<Float4> operator=(const SwizzleFloat4<T> &rhs);

 

 		friend RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs);

 		friend RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs);

@@ -2340,54 +2434,51 @@
 	};

 

 	template<class T>

-	class Pointer : public Variable<T*>

+	class Pointer : public Variable<Pointer<T> >

 	{

 	public:

 		template<class S>

-		Pointer(RValue<Pointer<S>> pointerS, int alignment = 1) : alignment(alignment)

+		Pointer(RValue<Pointer<S> > pointerS, int alignment = 1) : alignment(alignment)

 		{

-			address = Nucleus::allocateStackVariable(Nucleus::getPointerType(T::getType()));

-

 			llvm::Value *pointerT = Nucleus::createBitCast(pointerS.value, Nucleus::getPointerType(T::getType()));

-			Nucleus::createStore(pointerT, address);

+			LValue::storeValue(pointerT);

 		}

 

 		template<class S>

 		Pointer(const Pointer<S> &pointer, int alignment = 1) : alignment(alignment)

 		{

-			address = Nucleus::allocateStackVariable(Nucleus::getPointerType(T::getType()));

-

-			llvm::Value *pointerS = Nucleus::createLoad(pointer.address);

+			llvm::Value *pointerS = pointer.loadValue(alignment);

 			llvm::Value *pointerT = Nucleus::createBitCast(pointerS, Nucleus::getPointerType(T::getType()));

-			Nucleus::createStore(pointerT, address);

+			LValue::storeValue(pointerT);

 		}

 

-		explicit Pointer(llvm::Value *pointer);

 		explicit Pointer(llvm::Argument *argument);

 		explicit Pointer(const void *external);

 

 		Pointer();

-		Pointer(RValue<Pointer<T>> rhs);

+		Pointer(RValue<Pointer<T> > rhs);

 		Pointer(const Pointer<T> &rhs);

+		Pointer(const Reference<Pointer<T> > &rhs);

 

-		RValue<Pointer<T>> operator=(RValue<Pointer<T>> rhs) const;

-		RValue<Pointer<T>> operator=(const Pointer<T> &rhs) const;

+		RValue<Pointer<T> > operator=(RValue<Pointer<T> > rhs) const;

+		RValue<Pointer<T> > operator=(const Pointer<T> &rhs) const;

+		RValue<Pointer<T> > operator=(const Reference<Pointer<T> > &rhs) const;

 

 		Reference<T> operator*();

 

-		friend RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset);

-		friend RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset);

-		friend RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);

-		friend RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset);

-		friend RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<Int> offset);

-		friend RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset);

+		friend RValue<Pointer<Byte> > operator+(RValue<Pointer<Byte> > lhs, int offset);

+		friend RValue<Pointer<Byte> > operator+(RValue<Pointer<Byte> > lhs, RValue<Int> offset);

+		friend RValue<Pointer<Byte> > operator+(RValue<Pointer<Byte> > lhs, RValue<UInt> offset);

+		friend RValue<Pointer<Byte> > operator+=(const Pointer<Byte> &lhs, int offset);

+		friend RValue<Pointer<Byte> > operator+=(const Pointer<Byte> &lhs, RValue<Int> offset);

+		friend RValue<Pointer<Byte> > operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset);

 

-		friend RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset);

-		friend RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset);

-		friend RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);

-		friend RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, int offset);

-		friend RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<Int> offset);

-		friend RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset);

+		friend RValue<Pointer<Byte> > operator-(RValue<Pointer<Byte> > lhs, int offset);

+		friend RValue<Pointer<Byte> > operator-(RValue<Pointer<Byte> > lhs, RValue<Int> offset);

+		friend RValue<Pointer<Byte> > operator-(RValue<Pointer<Byte> > lhs, RValue<UInt> offset);

+		friend RValue<Pointer<Byte> > operator-=(const Pointer<Byte> &lhs, int offset);

+		friend RValue<Pointer<Byte> > operator-=(const Pointer<Byte> &lhs, RValue<Int> offset);

+		friend RValue<Pointer<Byte> > operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset);

 

 		static llvm::Type *getType();

 

@@ -2396,7 +2487,7 @@
 	};

 

 	template<class T, int S = 1>

-	class Array : public Variable<T[]>

+	class Array : public Variable<T>

 	{

 	public:

 		Array(int size = S);

@@ -2405,9 +2496,9 @@
 		Reference<T> operator[](RValue<Int> index);

 		Reference<T> operator[](RValue<UInt> index);

 

-	//	friend RValue<Array<T>> operator++(const Array<T> &val, int);   // Post-increment

+	//	friend RValue<Array<T> > operator++(const Array<T> &val, int);   // Post-increment

 	//	friend const Array<T> &operator++(const Array<T> &val);   // Pre-increment

-	//	friend RValue<Array<T>> operator--(const Array<T> &val, int);   // Post-decrement

+	//	friend RValue<Array<T> > operator--(const Array<T> &val, int);   // Post-decrement

 	//	friend const Array<T> &operator--(const Array<T> &val);   // Pre-decrement

 	};

 

@@ -2423,7 +2514,7 @@
 	void Return(const Pointer<T> &ret);

 

 	template<class T>

-	void Return(RValue<Pointer<T>> ret);

+	void Return(RValue<Pointer<T> > ret);

 

 	template<class R = Void, class A1 = Void, class A2 = Void, class A3 = Void, class A4 = Void>

 	class Function

@@ -2444,12 +2535,22 @@
 	};

 

 	RValue<Long> Ticks();

-	void Emms();

 }

 

 namespace sw

 {

 	template<class T>

+	Variable<T>::Variable(int arraySize) : LValue(T::getType(), arraySize)

+	{

+	}

+

+	template<class T>

+	RValue<Pointer<T> > Variable<T>::operator&()

+	{

+		return RValue<Pointer<T> >(LValue::address);

+	}

+

+	template<class T>

 	Reference<T>::Reference(llvm::Value *pointer, int alignment) : alignment(alignment)

 	{

 		address = pointer;

@@ -2464,12 +2565,6 @@
 	}

 

 	template<class T>

-	Reference<T>::operator RValue<T>() const

-	{

-		return RValue<T>(Nucleus::createLoad(address, false, alignment));

-	}

-

-	template<class T>

 	RValue<T> Reference<T>::operator=(const Reference<T> &ref) const

 	{

 		llvm::Value *tmp = Nucleus::createLoad(ref.address, false, ref.alignment);

@@ -2485,6 +2580,18 @@
 	}

 

 	template<class T>

+	llvm::Value *Reference<T>::loadValue() const

+	{

+		return Nucleus::createLoad(address, false, alignment);

+	}

+

+	template<class T>

+	int Reference<T>::getAlignment() const

+	{

+		return alignment;

+	}

+

+	template<class T>

 	RValue<T>::RValue(llvm::Value *rvalue)

 	{

 		value = rvalue;

@@ -2493,7 +2600,7 @@
 	template<class T>

 	RValue<T>::RValue(const T &lvalue)

 	{

-		value = Nucleus::createLoad(lvalue.address);

+		value = lvalue.loadValue();

 	}

 

 	template<class T>

@@ -2502,10 +2609,22 @@
 		value = (llvm::Value*)Nucleus::createConstantInt(i);

 	}

 

+	template<class T>

+	RValue<T>::RValue(typename FloatLiteral<T>::type f)

+	{

+		value = (llvm::Value*)Nucleus::createConstantFloat(f);

+	}

+

+	template<class T>

+	RValue<T>::RValue(const Reference<T> &ref)

+	{

+		value = ref.loadValue();

+	}

+

 	template<int T>

 	Swizzle2Float4<T>::operator RValue<Float4>() const

 	{

-		llvm::Value *vector = Nucleus::createLoad(parent->address);

+		llvm::Value *vector = parent->loadValue();

 

 		return RValue<Float4>(Nucleus::createSwizzle(vector, T));

 	}

@@ -2513,7 +2632,7 @@
 	template<int T>

 	SwizzleFloat4<T>::operator RValue<Float4>() const

 	{

-		llvm::Value *vector = Nucleus::createLoad(parent->address);

+		llvm::Value *vector = parent->loadValue();

 

 		return RValue<Float4>(Nucleus::createSwizzle(vector, T));

 	}

@@ -2521,7 +2640,7 @@
 	template<int T>

 	SwizzleMaskFloat4<T>::operator RValue<Float4>() const

 	{

-		llvm::Value *vector = Nucleus::createLoad(parent->address);

+		llvm::Value *vector = parent->loadValue();

 

 		return RValue<Float4>(Nucleus::createSwizzle(vector, T));

 	}

@@ -2547,7 +2666,7 @@
 	template<int T>

 	SwizzleMask1Float4<T>::operator RValue<Float4>() const

 	{

-		llvm::Value *vector = Nucleus::createLoad(parent->address);

+		llvm::Value *vector = parent->loadValue();

 

 		return RValue<Float4>(Nucleus::createSwizzle(vector, T));

 	}

@@ -2573,7 +2692,7 @@
 	template<int T>

 	SwizzleMask2Float4<T>::operator RValue<Float4>() const

 	{

-		llvm::Value *vector = Nucleus::createLoad(parent->address);

+		llvm::Value *vector = parent->loadValue();

 

 		return RValue<Float4>(Nucleus::createSwizzle(vector, T));

 	}

@@ -2585,19 +2704,37 @@
 	}

 

 	template<int T>

-	Float4::Float4(const SwizzleMask1Float4<T> &lhs)

+	Float::Float(const SwizzleMask1Float4<T> &rhs)

+	{

+		*this = rhs.operator RValue<Float>();

+	}

+

+	template<int T>

+	RValue<Float> Float::operator=(const SwizzleMask1Float4<T> &rhs) const

+	{

+		return *this = rhs.operator RValue<Float>();

+	}

+

+	template<int T>

+	Float4::Float4(const SwizzleMask1Float4<T> &rhs)

 	{

 		xyzw.parent = this;

-		address = Nucleus::allocateStackVariable(getType());

 

-		*this = RValue<Float4>(lhs);

+		*this = rhs.operator RValue<Float4>();

+	}

+

+	template<int T>

+	Float4::Float4(const SwizzleFloat4<T> &rhs)

+	{

+		xyzw.parent = this;

+

+		*this = rhs.operator RValue<Float4>();

 	}

 

 	template<int X, int Y>

 	Float4::Float4(const Swizzle2Float4<X> &x, const Swizzle2Float4<Y> &y)

 	{

 		xyzw.parent = this;

-		address = Nucleus::allocateStackVariable(getType());

 

 		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);

 	}

@@ -2606,7 +2743,6 @@
 	Float4::Float4(const SwizzleMask2Float4<X> &x, const Swizzle2Float4<Y> &y)

 	{

 		xyzw.parent = this;

-		address = Nucleus::allocateStackVariable(getType());

 

 		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);

 	}

@@ -2615,7 +2751,6 @@
 	Float4::Float4(const Swizzle2Float4<X> &x, const SwizzleMask2Float4<Y> &y)

 	{

 		xyzw.parent = this;

-		address = Nucleus::allocateStackVariable(getType());

 

 		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);

 	}

@@ -2624,36 +2759,31 @@
 	Float4::Float4(const SwizzleMask2Float4<X> &x, const SwizzleMask2Float4<Y> &y)

 	{

 		xyzw.parent = this;

-		address = Nucleus::allocateStackVariable(getType());

 

 		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);

 	}

 

 	template<int T>

-	RValue<Float4> Float4::operator=(const SwizzleMask1Float4<T> &lhs)

+	RValue<Float4> Float4::operator=(const SwizzleMask1Float4<T> &rhs)

 	{

-		return *this = RValue<Float4>(lhs);

+		return *this = rhs.operator RValue<Float4>();

 	}

 

-	template<class T>

-	Pointer<T>::Pointer(llvm::Value *pointer) : alignment(1)

+	template<int T>

+	RValue<Float4> Float4::operator=(const SwizzleFloat4<T> &rhs)

 	{

-		address = pointer;

+		return *this = rhs.operator RValue<Float4>();

 	}

 

 	template<class T>

 	Pointer<T>::Pointer(llvm::Argument *argument) : alignment(1)

 	{

-		address = Nucleus::allocateStackVariable(Nucleus::getPointerType(T::getType()));

-

-		Nucleus::createStore((llvm::Value*)argument, address);

+		LValue::storeValue((llvm::Value*)argument);

 	}

 

 	template<class T>

-	Pointer<T>::Pointer(const void *external) : alignment((size_t)external & 0x0000000F ? 1 : 16)

+	Pointer<T>::Pointer(const void *external) : alignment((intptr_t)external & 0x0000000F ? 1 : 16)

 	{

-		address = Nucleus::allocateStackVariable(Nucleus::getPointerType(T::getType()));

-

 		llvm::Module *module = Nucleus::getModule();

 		const llvm::GlobalValue *globalPointer = Nucleus::getGlobalValueAtAddress(const_cast<void*>(external));   // FIXME: Const

 

@@ -2664,55 +2794,65 @@
 			Nucleus::addGlobalMapping(globalPointer, const_cast<void*>(external));   // FIXME: Const

 		}

 

-		Nucleus::createStore((llvm::Value*)globalPointer, address);   // FIXME: Const

+		LValue::storeValue((llvm::Value*)globalPointer);   // FIXME: Const

 	}

 

 	template<class T>

 	Pointer<T>::Pointer() : alignment(1)

 	{

-		address = Nucleus::allocateStackVariable(Nucleus::getPointerType(T::getType()));

-

-		Nucleus::createStore(Nucleus::createNullPointer(T::getType()), address);

+		LValue::storeValue(Nucleus::createNullPointer(T::getType()));

 	}

 

 	template<class T>

-	Pointer<T>::Pointer(RValue<Pointer<T>> rhs) : alignment(1)

+	Pointer<T>::Pointer(RValue<Pointer<T> > rhs) : alignment(1)

 	{

-		address = Nucleus::allocateStackVariable(Nucleus::getPointerType(T::getType()));

-

-		Nucleus::createStore(rhs.value, address);

+		LValue::storeValue(rhs.value);

 	}

 

 	template<class T>

 	Pointer<T>::Pointer(const Pointer<T> &rhs) : alignment(rhs.alignment)

 	{

-		address = Nucleus::allocateStackVariable(Nucleus::getPointerType(T::getType()));

-

-		llvm::Value *value = Nucleus::createLoad(rhs.address);

-		Nucleus::createStore(value, address);

+		llvm::Value *value = rhs.loadValue();

+		LValue::storeValue(value);

 	}

 

 	template<class T>

-	RValue<Pointer<T>> Pointer<T>::operator=(RValue<Pointer<T>> rhs) const

+	Pointer<T>::Pointer(const Reference<Pointer<T> > &rhs) : alignment(rhs.getAlignment())

 	{

-		Nucleus::createStore(rhs.value, address);

+		llvm::Value *value = rhs.loadValue();

+		LValue::storeValue(value);

+	}

+

+	template<class T>

+	RValue<Pointer<T> > Pointer<T>::operator=(RValue<Pointer<T> > rhs) const

+	{

+		LValue::storeValue(rhs.value);

 

 		return rhs;

 	}

 

 	template<class T>

-	RValue<Pointer<T>> Pointer<T>::operator=(const Pointer<T> &rhs) const

+	RValue<Pointer<T> > Pointer<T>::operator=(const Pointer<T> &rhs) const

 	{

-		llvm::Value *value = Nucleus::createLoad(rhs.address);

-		Nucleus::createStore(value, address);

+		llvm::Value *value = rhs.loadValue();

+		LValue::storeValue(value);

 

-		return RValue<Pointer<T>>(value);

+		return RValue<Pointer<T> >(value);

+	}

+

+	template<class T>

+	RValue<Pointer<T> > Pointer<T>::operator=(const Reference<Pointer<T> > &rhs) const

+	{

+		llvm::Value *value = rhs.loadValue();

+		LValue::storeValue(value);

+

+		return RValue<Pointer<T> >(value);

 	}

 

 	template<class T>

 	Reference<T> Pointer<T>::operator*()

 	{

-		return Reference<T>(Nucleus::createLoad(address), alignment);

+		return Reference<T>(LValue::loadValue(), alignment);

 	}

 

 	template<class T>

@@ -2722,41 +2862,40 @@
 	}

 

 	template<class T, int S>

-	Array<T, S>::Array(int size)

+	Array<T, S>::Array(int size) : Variable<T>(size)

 	{

-		address = Nucleus::allocateStackVariable(T::getType(), size);

 	}

 

 	template<class T, int S>

 	Reference<T> Array<T, S>::operator[](int index)

 	{

-		llvm::Value *element = Nucleus::createGEP(address, (llvm::Value*)Nucleus::createConstantInt(index));

-	

+		llvm::Value *element = LValue::getAddress((llvm::Value*)Nucleus::createConstantInt(index));

+

 		return Reference<T>(element);

 	}

 

 	template<class T, int S>

 	Reference<T> Array<T, S>::operator[](RValue<Int> index)

 	{

-		llvm::Value *element = Nucleus::createGEP(address, index.value);

-	

+		llvm::Value *element = LValue::getAddress(index.value);

+

 		return Reference<T>(element);

 	}

 

 	template<class T, int S>

 	Reference<T> Array<T, S>::operator[](RValue<UInt> index)

 	{

-		llvm::Value *element = Nucleus::createGEP(address, index.value);

-	

+		llvm::Value *element = LValue::getAddress(index.value);

+

 		return Reference<T>(element);

 	}

 

 //	template<class T>

-//	RValue<Array<T>> operator++(const Array<T> &val, int)

+//	RValue<Array<T> > operator++(const Array<T> &val, int)

 //	{

 //		// FIXME: Requires storing the address of the array

 //	}

-	

+

 //	template<class T>

 //	const Array<T> &operator++(const Array<T> &val)

 //	{

@@ -2764,7 +2903,7 @@
 //	}

 

 //	template<class T>

-//	RValue<Array<T>> operator--(const Array<T> &val, int)

+//	RValue<Array<T> > operator--(const Array<T> &val, int)

 //	{

 //		// FIXME: Requires storing the address of the array

 //	}

@@ -2784,7 +2923,7 @@
 	template<class T>

 	RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, RValue<T> ifFalse)

 	{

-		llvm::Value *trueValue = Nucleus::createLoad(ifTrue.address);

+		llvm::Value *trueValue = ifTrue.loadValue();

 

 		return RValue<T>(Nucleus::createSelect(condition.value, trueValue, ifFalse.value));

 	}

@@ -2792,7 +2931,7 @@
 	template<class T>

 	RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, const T &ifFalse)

 	{

-		llvm::Value *falseValue = Nucleus::createLoad(ifFalse.address);

+		llvm::Value *falseValue = ifFalse.loadValue();

 

 		return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, falseValue));

 	}

@@ -2800,8 +2939,8 @@
 	template<class T>

 	RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, const T &ifFalse)

 	{

-		llvm::Value *trueValue = Nucleus::createLoad(ifTrue.address);

-		llvm::Value *falseValue = Nucleus::createLoad(ifFalse.address);

+		llvm::Value *trueValue = ifTrue.loadValue();

+		llvm::Value *falseValue = ifFalse.loadValue();

 

 		return RValue<T>(Nucleus::createSelect(condition.value, trueValue, falseValue));

 	}

@@ -2809,21 +2948,13 @@
 	template<class T>

 	void Return(const Pointer<T> &ret)

 	{

-		#if !(defined(_M_AMD64) || defined(_M_X64))

-			x86::emms();

-		#endif

-

 		Nucleus::createRet(Nucleus::createLoad(ret.address));

 		Nucleus::setInsertBlock(Nucleus::createBasicBlock());

 	}

 

 	template<class T>

-	void Return(RValue<Pointer<T>> ret)

+	void Return(RValue<Pointer<T> > ret)

 	{

-		#if !(defined(_M_AMD64) || defined(_M_X64))

-			x86::emms();

-		#endif

-

 		Nucleus::createRet(ret.value);

 		Nucleus::setInsertBlock(Nucleus::createBasicBlock());

 	}

@@ -2839,7 +2970,7 @@
 		if(!A4::isVoid()) arguments.push_back(A4::getType());

 

 		function = Nucleus::createFunction(R::getType(), arguments);

-		Nucleus::setFunction(function);	

+		Nucleus::setFunction(function);

 	}

 

 	template<class R, class A1, class A2, class A3, class A4>

@@ -2873,10 +3004,10 @@
 		return RValue<T>(Nucleus::createBitCast(val.value, T::getType()));

 	}

 

-	template<class T, class S>

-	RValue<T> ReinterpretCast(const Variable<S> &var)

+	template<class T>

+	RValue<T> ReinterpretCast(const LValue &var)

 	{

-		llvm::Value *val = Nucleus::createLoad(var.address);

+		llvm::Value *val = var.loadValue();

 

 		return RValue<T>(Nucleus::createBitCast(val, T::getType()));

 	}

@@ -2893,8 +3024,8 @@
 		return ReinterpretCast<T>(val);

 	}

 

-	template<class T, class S>

-	RValue<T> As(const Variable<S> &var)

+	template<class T>

+	RValue<T> As(const LValue &var)

 	{

 		return ReinterpretCast<T>(var);

 	}

diff --git a/src/Reactor/Reactor.vcxproj b/src/Reactor/Reactor.vcxproj
index e7e98cd..6660e0a 100644
--- a/src/Reactor/Reactor.vcxproj
+++ b/src/Reactor/Reactor.vcxproj
@@ -254,10 +254,12 @@
     </ProjectReference>

   </ItemDefinitionGroup>

   <ItemGroup>

+    <ClCompile Include="DLL.cpp" />

     <ClCompile Include="MemoryManager.cpp" />

     <ClCompile Include="Nucleus.cpp" />

   </ItemGroup>

   <ItemGroup>

+    <ClInclude Include="DLL.hpp" />

     <ClInclude Include="MemoryManager.hpp" />

     <ClInclude Include="Nucleus.hpp" />

     <ClInclude Include="Reactor.hpp" />

diff --git a/src/Reactor/Reactor.vcxproj.filters b/src/Reactor/Reactor.vcxproj.filters
index d5233ba..012054d 100644
--- a/src/Reactor/Reactor.vcxproj.filters
+++ b/src/Reactor/Reactor.vcxproj.filters
@@ -15,6 +15,9 @@
     </Filter>

   </ItemGroup>

   <ItemGroup>

+    <ClCompile Include="DLL.cpp">

+      <Filter>Source Files</Filter>

+    </ClCompile>

     <ClCompile Include="MemoryManager.cpp">

       <Filter>Source Files</Filter>

     </ClCompile>

@@ -23,6 +26,9 @@
     </ClCompile>

   </ItemGroup>

   <ItemGroup>

+    <ClInclude Include="DLL.hpp">

+      <Filter>Header Files</Filter>

+    </ClInclude>

     <ClInclude Include="MemoryManager.hpp">

       <Filter>Header Files</Filter>

     </ClInclude>

diff --git a/src/Reactor/Shell.cpp b/src/Reactor/Shell.cpp
deleted file mode 100644
index a6f7829..0000000
--- a/src/Reactor/Shell.cpp
+++ /dev/null
@@ -1,340 +0,0 @@
-// SwiftShader Software Renderer
-//
-// Copyright(c) 2005-2011 TransGaming Inc.
-//
-// All rights reserved. No part of this software may be copied, distributed, transmitted,
-// transcribed, stored in a retrieval system, translated into any human or computer
-// language by any means, or disclosed to third parties without the explicit written
-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
-// or implied, including but not limited to any patent rights, are granted to you.
-//
-
-#include "Shell.hpp"
-
-namespace sw
-{
-	TranscendentalPrecision logPrecision = ACCURATE;
-	TranscendentalPrecision expPrecision = ACCURATE;
-	TranscendentalPrecision rcpPrecision = ACCURATE;
-	TranscendentalPrecision rsqPrecision = ACCURATE;
-	bool perspectiveCorrection = true;
-
-	Color4i::Color4i() : x(r), y(g), z(b), w(a)
-	{
-	}
-
-	Color4i::Color4i(unsigned short red, unsigned short green, unsigned short blue, unsigned short alpha) : x(r), y(g), z(b), w(a)
-	{
-		r = Short4(red);
-		g = Short4(green);
-		b = Short4(blue);
-		a = Short4(alpha);
-	}
-
-	Color4i::Color4i(const Color4i &rhs) : x(r), y(g), z(b), w(a)
-	{
-		r = rhs.r;
-		g = rhs.g;
-		b = rhs.b;
-		a = rhs.a;
-	}
-
-	Color4i &Color4i::operator=(const Color4i &rhs)
-	{
-		r = rhs.r;
-		g = rhs.g;
-		b = rhs.b;
-		a = rhs.a;
-
-		return *this;
-	}
-
-	Short4 &Color4i::operator[](int i)
-	{
-		switch(i)
-		{
-		case 0: return x;
-		case 1: return y;
-		case 2: return z;
-		case 3: return w;
-		}
-
-		return x;
-	}
-
-	Color4f::Color4f() : x(r), y(g), z(b), w(a), u(r), v(g), s(b), t(a)
-	{
-	}
-
-	Color4f::Color4f(float red, float green, float blue, float alpha) : x(r), y(g), z(b), w(a), u(r), v(g), s(b), t(a)
-	{
-		r = Float4(red);
-		g = Float4(green);
-		b = Float4(blue);
-		a = Float4(alpha);
-	}
-
-	Color4f::Color4f(const Color4f &rhs) : x(r), y(g), z(b), w(a), u(r), v(g), s(b), t(a)
-	{
-		r = rhs.r;
-		g = rhs.g;
-		b = rhs.b;
-		a = rhs.a;
-	}
-
-	Color4f &Color4f::operator=(const Color4f &rhs)
-	{
-		r = rhs.r;
-		g = rhs.g;
-		b = rhs.b;
-		a = rhs.a;
-
-		return *this;
-	}
-
-	Float4 &Color4f::operator[](int i)
-	{
-		switch(i)
-		{
-		case 0: return x;
-		case 1: return y;
-		case 2: return z;
-		case 3: return w;
-		}
-
-		return x;
-	}
-
-	Float4 exponential(Float4 &src, bool pp)
-	{
-		Float4 x0;
-		Float4 x1;
-		Int4 x2;
-	
-		x0 = src;
-
-		x0 = Min(x0, As<Float4>(Int4(0x43010000, 0x43010000, 0x43010000, 0x43010000)));   // 129.00000e+0f
-		x0 = Max(x0, As<Float4>(Int4(0xC2FDFFFF, 0xC2FDFFFF, 0xC2FDFFFF, 0xC2FDFFFF)));   // -126.99999e+0f
-		x1 = x0;
-		x1 -= Float4(0.5f, 0.5f, 0.5f, 0.5f);
-		x2 = RoundInt(x1);
-		x1 = Float4(x2);
-		x2 += Int4(0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F);   // 127
-		x2 = x2 << 23;
-		x0 -= x1;
-		x1 = As<Float4>(Int4(0x3AF61905, 0x3AF61905, 0x3AF61905, 0x3AF61905));   // 1.8775767e-3f
-		x1 *= x0;
-		x1 += As<Float4>(Int4(0x3C134806, 0x3C134806, 0x3C134806, 0x3C134806));   // 8.9893397e-3f
-		x1 *= x0;
-		x1 += As<Float4>(Int4(0x3D64AA23, 0x3D64AA23, 0x3D64AA23, 0x3D64AA23));   // 5.5826318e-2f
-		x1 *= x0;
-		x1 += As<Float4>(Int4(0x3E75EAD4, 0x3E75EAD4, 0x3E75EAD4, 0x3E75EAD4));   // 2.4015361e-1f
-		x1 *= x0;
-		x1 += As<Float4>(Int4(0x3F31727B, 0x3F31727B, 0x3F31727B, 0x3F31727B));   // 6.9315308e-1f
-		x1 *= x0;
-		x1 += As<Float4>(Int4(0x3F7FFFFF, 0x3F7FFFFF, 0x3F7FFFFF, 0x3F7FFFFF));   // 9.9999994e-1f
-		x1 *= As<Float4>(x2);
-			
-		return x1;
-	}
-
-	Float4 logarithm(Float4 &src, bool absolute, bool pp)
-	{
-		Float4 x0;
-		Float4 x1;
-		Float4 x2;
-		Float4 x3;
-		
-		x0 = src;
-		
-		x1 = As<Float4>(As<Int4>(x0) & Int4(0x7F800000));
-		x1 = As<Float4>(As<UInt4>(x1) >> 8);
-		x1 = As<Float4>(As<Int4>(x1) | As<Int4>(Float4(1.0f)));
-		x1 = (x1 - Float4(1.4960938f)) * Float4(256.0f);   // FIXME: (x1 - 1.4960938f) * 256.0f;
-		x0 = As<Float4>((As<Int4>(x0) & Int4(0x007FFFFF)) | As<Int4>(Float4(1.0f)));
-
-		x2 = (Float4(9.5428179e-2f) * x0 + Float4(4.7779095e-1f)) * x0 + Float4(1.9782813e-1f);
-		x3 = ((Float4(1.6618466e-2f) * x0 + Float4(2.0350508e-1f)) * x0 + Float4(2.7382900e-1f)) * x0 + Float4(4.0496687e-2f);
-		x2 /= x3;
-
-		x1 += (x0 - Float4(1.0f)) * x2;
-				
-		return x1;
-	}
-
-	Float4 power(Float4 &src0, Float4 &src1, bool pp)
-	{
-		Float4 log = logarithm(src0, true, pp);
-		log *= src1;
-		return exponential(log, pp);
-	}
-
-	Float4 reciprocal(Float4 &src, bool pp, bool finite)
-	{
-		Float4 dst;
-
-		if(!pp && rcpPrecision >= WHQL)
-		{
-			dst = Float4(1, 1, 1, 1) / src;
-		}
-		else
-		{
-			dst = Rcp_pp(src);
-
-			if(!pp)
-			{
-				dst = (dst + dst) - (src * dst * dst);
-			}
-		}
-
-		if(finite)
-		{
-			int x = 0x7F7FFFFF;
-			dst = Min(dst, Float4((float&)x, (float&)x, (float&)x, (float&)x));
-		}
-
-		return dst;
-	}
-
-	Float4 reciprocalSquareRoot(Float4 &src, bool absolute, bool pp)
-	{
-		Float4 abs = src;
-
-		if(absolute)
-		{
-			abs = Abs(abs);
-		}
-
-		Float4 rsq;
-
-		if(!pp && rsqPrecision >= IEEE)
-		{
-			rsq = Float4(1.0f, 1.0f, 1.0f, 1.0f) / Sqrt(abs);
-		}
-		else
-		{
-			rsq = RcpSqrt_pp(abs);
-
-			if(!pp)
-			{
-				rsq = rsq * (Float4(3.0f) - rsq * rsq * abs) * Float4(0.5f);
-			}
-		}
-
-		int x = 0x7F7FFFFF;
-		rsq = Min(rsq, Float4((float&)x, (float&)x, (float&)x, (float&)x));
-
-		return rsq;
-	}
-
-	Float4 sine(Float4 &src, bool pp)
-	{
-		const Float4 A = Float4(-4.05284734e-1f);   // -4/pi^2
-		const Float4 B = Float4(1.27323954e+0f);    // 4/pi
-		const Float4 C = Float4(7.75160950e-1f);
-		const Float4 D = Float4(2.24839049e-1f);
-
-		// Parabola approximating sine
-		Float4 sin = src * (Abs(src) * A + B);
-
-		// Improve precision from 0.06 to 0.001
-		if(true)
-		{
-			sin = sin * (Abs(sin) * D + C);
-		}
-
-		return sin;
-	}
-
-	Float4 dot3(Color4f &src0, Color4f &src1)
-	{
-		return src0.x * src1.x + src0.y * src1.y + src0.z * src1.z;
-	}
-
-	Float4 dot4(Color4f &src0, Color4f &src1)
-	{
-		return src0.x * src1.x + src0.y * src1.y + src0.z * src1.z + src0.w * src1.w;
-	}
-
-	void transpose4x4(Short4 &row0, Short4 &row1, Short4 &row2, Short4 &row3)
-	{
-		Int2 tmp0 = UnpackHigh(row0, row1);
-		Int2 tmp1 = UnpackHigh(row2, row3);
-		Int2 tmp2 = UnpackLow(row0, row1);
-		Int2 tmp3 = UnpackLow(row2, row3);
-
-		row0 = As<Short4>(UnpackLow(tmp2, tmp3));
-		row1 = As<Short4>(UnpackHigh(tmp2, tmp3));
-		row2 = As<Short4>(UnpackLow(tmp0, tmp1));
-		row3 = As<Short4>(UnpackHigh(tmp0, tmp1));
-	}
-
-	void transpose4x4(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3)
-	{
-		Float4 tmp0 = UnpackLow(row0, row1);
-		Float4 tmp1 = UnpackLow(row2, row3);
-		Float4 tmp2 = UnpackHigh(row0, row1);
-		Float4 tmp3 = UnpackHigh(row2, row3);
-
-		row0 = Float4(tmp0.xy, tmp1.xy);
-		row1 = Float4(tmp0.zw, tmp1.zw);
-		row2 = Float4(tmp2.xy, tmp3.xy);
-		row3 = Float4(tmp2.zw, tmp3.zw);
-	}
-
-	void transpose4x3(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3)
-	{
-		Float4 tmp0 = UnpackLow(row0, row1);
-		Float4 tmp1 = UnpackLow(row2, row3);
-		Float4 tmp2 = UnpackHigh(row0, row1);
-		Float4 tmp3 = UnpackHigh(row2, row3);
-
-		row0 = Float4(tmp0.xy, tmp1.xy);
-		row1 = Float4(tmp0.zw, tmp1.zw);
-		row2 = Float4(tmp2.xy, tmp3.xy);
-	}
-
-	void transpose4x2(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3)
-	{
-		Float4 tmp0 = UnpackLow(row0, row1);
-		Float4 tmp1 = UnpackLow(row2, row3);
-
-		row0 = Float4(tmp0.xy, tmp1.xy);
-		row1 = Float4(tmp0.zw, tmp1.zw);
-	}
-
-	void transpose4x1(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3)
-	{
-		Float4 tmp0 = UnpackLow(row0, row1);
-		Float4 tmp1 = UnpackLow(row2, row3);
-
-		row0 = Float4(tmp0.xy, tmp1.xy);
-	}
-
-	void transpose2x4(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3)
-	{
-		row0 = UnpackLow(row0, row1);
-		row1 = Float4(row0.zw, row1.zw);
-		row2 = UnpackHigh(row0, row1);
-		row3 = Float4(row2.zw, row3.zw);
-	}
-
-	void transpose2x4h(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3)
-	{
-		row0 = UnpackLow(row2, row3);
-		row1 = Float4(row0.zw, row1.zw);
-		row2 = UnpackHigh(row2, row3);
-		row3 = Float4(row2.zw, row3.zw);
-	}
-
-	void transpose4xN(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3, int N)
-	{
-		switch(N)
-		{
-		case 1: transpose4x1(row0, row1, row2, row3); break;
-		case 2: transpose4x2(row0, row1, row2, row3); break;
-		case 3: transpose4x3(row0, row1, row2, row3); break;
-		case 4: transpose4x4(row0, row1, row2, row3); break;
-		}
-	}
-}
diff --git a/src/Reactor/Shell.hpp b/src/Reactor/Shell.hpp
deleted file mode 100644
index f2d2b1b..0000000
--- a/src/Reactor/Shell.hpp
+++ /dev/null
@@ -1,133 +0,0 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2011 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-#ifndef sw_Shell_hpp

-#define sw_Shell_hpp

-

-#include "Nucleus.hpp"

-

-namespace sw

-{

-	enum TranscendentalPrecision

-	{

-		APPROXIMATE,

-		PARTIAL,	// 2^-10

-		ACCURATE,

-		WHQL,		// 2^-21

-		IEEE		// 2^-23

-	};

-

-	class Color4i

-	{

-	public:

-		Color4i();

-		Color4i(unsigned short red, unsigned short green, unsigned short blue, unsigned short alpha);

-		Color4i(const Color4i &rhs);

-

-		Short4 &operator[](int i);

-		Color4i &operator=(const Color4i &rhs);

-

-		Short4 r;

-		Short4 g;

-		Short4 b;

-		Short4 a;

-

-		Short4 &x;

-		Short4 &y;

-		Short4 &z;

-		Short4 &w;

-	};

-

-	class Color4f

-	{

-	public:

-		Color4f();

-		Color4f(float red, float green, float blue, float alpha);

-		Color4f(const Color4f &rhs);

-

-		Float4 &operator[](int i);

-		Color4f &operator=(const Color4f &rhs);

-

-		Float4 r;

-		Float4 g;

-		Float4 b;

-		Float4 a;

-

-		Float4 &x;

-		Float4 &y;

-		Float4 &z;

-		Float4 &w;

-

-		Float4 &u;

-		Float4 &v;

-		Float4 &s;

-		Float4 &t;

-	};

-

-	Float4 exponential(Float4 &src, bool pp = false);

-	Float4 logarithm(Float4 &src, bool abs, bool pp = false);

-	Float4 power(Float4 &src0, Float4 &src1, bool pp = false);

-	Float4 reciprocal(Float4 &src, bool pp = false, bool finite = false);

-	Float4 reciprocalSquareRoot(Float4 &src, bool abs, bool pp = false);

-	Float4 sine(Float4 &src, bool pp = false);

-

-	Float4 dot3(Color4f &src0, Color4f &src1);

-	Float4 dot4(Color4f &src0, Color4f &src1);

-

-	void transpose4x4(Short4 &row0, Short4 &row1, Short4 &row2, Short4 &row3);

-	void transpose4x4(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);

-	void transpose4x3(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);

-	void transpose4x2(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);

-	void transpose4x1(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);

-	void transpose2x4(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);

-	void transpose2x4h(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);

-	void transpose4xN(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3, int N);

-

-	#define For(init, cond, inc)                     \

-	init;                                            \

-	for(llvm::BasicBlock *loopBB__ = beginLoop(),    \

-		*bodyBB__ = Nucleus::createBasicBlock(),        \

-		*endBB__ = Nucleus::createBasicBlock(),         \

-		*onceBB__ = endBB__;                         \

-		onceBB__ && branch(cond, bodyBB__, endBB__); \

-		inc, onceBB__ = 0, Nucleus::createBr(loopBB__), Nucleus::setInsertBlock(endBB__))

-

-	#define While(cond) For(((void*)0), cond, ((void*)0))

-

-	#define Do \

-	{ \

-		llvm::BasicBlock *body = Nucleus::createBasicBlock(); \

-		Nucleus::createBr(body); \

-		Nucleus::setInsertBlock(body);

-

-	#define Until(cond) \

-		llvm::BasicBlock *end = Nucleus::createBasicBlock(); \

-		Nucleus::createCondBr((cond).value, end, body); \

-		Nucleus::setInsertBlock(end); \

-	}

-

-	#define If(cond)                                                              \

-	for(llvm::BasicBlock *trueBB__ = Nucleus::createBasicBlock(), \

-		*falseBB__ = Nucleus::createBasicBlock(),                 \

-		*endBB__ = Nucleus::createBasicBlock(),                   \

-		*onceBB__ = endBB__;                                   \

-		onceBB__ && branch(cond, trueBB__, falseBB__);         \

-		onceBB__ = 0, Nucleus::createBr(endBB__), Nucleus::setInsertBlock(falseBB__), Nucleus::createBr(endBB__), Nucleus::setInsertBlock(endBB__))

-

-	#define Else                                            \

-	for(llvm::BasicBlock *endBB__ = Nucleus::getInsertBlock(), \

-		*falseBB__ = Nucleus::getPredecessor(endBB__),         \

-		*onceBB__ = endBB__;                                \

-		onceBB__ && elseBlock(falseBB__);                   \

-		onceBB__ = 0, Nucleus::createBr(endBB__), Nucleus::setInsertBlock(endBB__))

-}

-

-#endif   // sw_Shell_hpp