Implement pointer arithmetic.

Bug swiftshader:11

Change-Id: I50bb9c6bf7bbe21630bd5f1eb5e0aa0aeb06fdb3
Reviewed-on: https://swiftshader-review.googlesource.com/7393
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index ade6e83..191f215 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -259,14 +259,7 @@
 		assert(arraySize == 0 && "UNIMPLEMENTED");
 
 		Ice::Type type = T(t);
-		
-		int32_t size = 0;
-		switch(type)
-		{
-		case Ice::IceType_i32: size = 4; break;
-		case Ice::IceType_i64: size = 8; break;
-		default: assert(false && "UNIMPLEMENTED" && type);
-		}
+		int size = Ice::typeWidthInBytes(type);
 
 		auto bytes = Ice::ConstantInteger32::create(::context, type, size);
 		auto address = ::function->makeVariable(T(getPointerType(t)));
@@ -490,7 +483,19 @@
 
 	Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index)
 	{
-		assert(false && "UNIMPLEMENTED"); return nullptr;
+		assert(index->getType() == Ice::IceType_i32);
+
+		if(!Ice::isByteSizedType(T(type)))
+		{
+			index = createMul(index, createAssign(createConstantInt((int)Ice::typeWidthInBytes(T(type)))));
+		}
+
+		if(sizeof(void*) == 8)
+		{
+			index = createSExt(index, T(Ice::IceType_i64));
+		}
+
+		return createAdd(ptr, index);
 	}
 
 	Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
@@ -5615,7 +5620,7 @@
 
 	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
 	{
-		assert(false && "UNIMPLEMENTED"); return RValue<Pointer<Byte>>(V(nullptr));
+		return lhs + RValue<Int>(Nucleus::createConstantInt(offset));
 	}
 
 	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)