Implement gather/scatter operations for shader register files.

This allows to address the registers with a vector of indices.

Also rename 'dynamic' register files to 'indirect addressable', to
disambiguate from 'dynamic indexing' at the shader level. Indexing with
a uniform does not require gather/scatter operations, but does require
indirect addressing.

Bug chromium:845103
Bug skia:7846

Change-Id: I3c42be33def66328688f2900c61c80246bf1e584
Reviewed-on: https://swiftshader-review.googlesource.com/18989
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Shader/Shader.cpp b/src/Shader/Shader.cpp
index 6874051..36192c9 100644
--- a/src/Shader/Shader.cpp
+++ b/src/Shader/Shader.cpp
@@ -1890,40 +1890,34 @@
 		}
 	}
 
-	void Shader::analyzeDynamicIndexing()
+	void Shader::analyzeIndirectAddressing()
 	{
-		dynamicallyIndexedTemporaries = false;
-		dynamicallyIndexedInput = false;
-		dynamicallyIndexedOutput = false;
+		indirectAddressableTemporaries = false;
+		indirectAddressableInput = false;
+		indirectAddressableOutput = false;
 
 		for(const auto &inst : instruction)
 		{
-			if(inst->dst.rel.type == PARAMETER_ADDR ||
-			   inst->dst.rel.type == PARAMETER_LOOP ||
-			   inst->dst.rel.type == PARAMETER_TEMP ||
-			   inst->dst.rel.type == PARAMETER_CONST)
+			if(inst->dst.rel.type != PARAMETER_VOID)
 			{
 				switch(inst->dst.type)
 				{
-				case PARAMETER_TEMP:   dynamicallyIndexedTemporaries = true; break;
-				case PARAMETER_INPUT:  dynamicallyIndexedInput = true;       break;
-				case PARAMETER_OUTPUT: dynamicallyIndexedOutput = true;      break;
+				case PARAMETER_TEMP:   indirectAddressableTemporaries = true; break;
+				case PARAMETER_INPUT:  indirectAddressableInput = true;       break;
+				case PARAMETER_OUTPUT: indirectAddressableOutput = true;      break;
 				default: break;
 				}
 			}
 
 			for(int j = 0; j < 3; j++)
 			{
-				if(inst->src[j].rel.type == PARAMETER_ADDR ||
-				   inst->src[j].rel.type == PARAMETER_LOOP ||
-				   inst->src[j].rel.type == PARAMETER_TEMP ||
-				   inst->src[j].rel.type == PARAMETER_CONST)
+				if(inst->src[j].rel.type != PARAMETER_VOID)
 				{
 					switch(inst->src[j].type)
 					{
-					case PARAMETER_TEMP:   dynamicallyIndexedTemporaries = true; break;
-					case PARAMETER_INPUT:  dynamicallyIndexedInput = true;       break;
-					case PARAMETER_OUTPUT: dynamicallyIndexedOutput = true;      break;
+					case PARAMETER_TEMP:   indirectAddressableTemporaries = true; break;
+					case PARAMETER_INPUT:  indirectAddressableInput = true;       break;
+					case PARAMETER_OUTPUT: indirectAddressableOutput = true;      break;
 					default: break;
 					}
 				}