Implement support for For loops.

Bug swiftshader:13

Change-Id: I054d0521ecbb1959c5c19b6fa54f76707f4e49c9
Reviewed-on: https://swiftshader-review.googlesource.com/7358
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/Main.cpp b/src/Reactor/Main.cpp
index 0e2e739..ff26a1a 100644
--- a/src/Reactor/Main.cpp
+++ b/src/Reactor/Main.cpp
@@ -30,6 +30,11 @@
 			Int y = function.Arg<1>();
 			Int z = 4;
 
+			For(Int i = 0, i < 10, i++)
+			{
+				z += 2;
+			}
+
 			Int sum = x + y + z;
    
 			Return(sum);
@@ -42,7 +47,7 @@
 			int (*add)(int*, int) = (int(*)(int*,int))routine->getEntry();
 			int one = 1;
 			int result = add(&one, 2);
-			assert(result == 7);
+			assert(result == 27);
 		}
 	}
 
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 594f748..7a427d1 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -76,6 +76,11 @@
 		return reinterpret_cast<Constant*>(c);
 	}
 
+	BasicBlock *B(Ice::CfgNode *b)
+	{
+		return reinterpret_cast<BasicBlock*>(b);
+	}
+
 	Optimization optimization[10] = {InstructionCombining, Disabled};
 
 	void *loadImage(uint8_t *const elfImage)
@@ -273,18 +278,18 @@
 
 	BasicBlock *Nucleus::createBasicBlock()
 	{
-		assert(false && "UNIMPLEMENTED"); return nullptr;
+		return B(::function->makeNode());
 	}
 
 	BasicBlock *Nucleus::getInsertBlock()
 	{
-		assert(false && "UNIMPLEMENTED"); return nullptr;
+		return B(::basicBlock);
 	}
 
 	void Nucleus::setInsertBlock(BasicBlock *basicBlock)
 	{
-		assert(!basicBlock->getInsts().back().getTerminatorEdges().empty() && "Previous basic block must have a terminator");
-		assert(false && "UNIMPLEMENTED"); return;
+		assert(::basicBlock->getInsts().back().getTerminatorEdges().size() >= 0 && "Previous basic block must have a terminator");
+		::basicBlock = basicBlock;
 	}
 
 	BasicBlock *Nucleus::getPredecessor(BasicBlock *basicBlock)
@@ -326,12 +331,14 @@
 
 	void Nucleus::createBr(BasicBlock *dest)
 	{
-		assert(false && "UNIMPLEMENTED");
+		auto br = Ice::InstBr::create(::function, dest);
+		::basicBlock->appendInst(br);
 	}
 
 	void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
 	{
-		assert(false && "UNIMPLEMENTED");
+		auto br = Ice::InstBr::create(::function, cond, ifTrue, ifFalse);
+		::basicBlock->appendInst(br);
 	}
 
 	Value *Nucleus::createAdd(Value *lhs, Value *rhs)
@@ -585,7 +592,13 @@
 
 	Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
 	{
-		assert(false && "UNIMPLEMENTED"); return nullptr;
+		assert(lhs->getType() == rhs->getType());
+
+		auto result = ::function->makeVariable(Ice::IceType_i1);
+		auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Slt, result, lhs, rhs);
+		::basicBlock->appendInst(cmp);
+
+		return V(result);
 	}
 
 	Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
@@ -3406,7 +3419,13 @@
 
 	RValue<Int> operator++(const Int &val, int)   // Post-increment
 	{
-		assert(false && "UNIMPLEMENTED"); return RValue<Int>(V(nullptr));
+		auto oldValue = val.loadValue();
+		auto newValue = ::function->makeVariable(Ice::IceType_i32);
+		auto inc = Ice::InstArithmetic::create(::function, Ice::InstArithmetic::Add, newValue, oldValue, ::context->getConstantInt32(1));
+		::basicBlock->appendInst(inc);
+		val.storeValue(V(newValue));
+
+		return RValue<Int>(oldValue);
 	}
 
 	const Int &operator++(const Int &val)   // Pre-increment