modf implementation

Implemented modf as trunc + sub
Passes all related dEQP tests

Change-Id: I43656c51a670d235153e5fac390a8db311b14f8d
Reviewed-on: https://swiftshader-review.googlesource.com/5280
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/compiler/Initialize.cpp b/src/OpenGL/compiler/Initialize.cpp
index 63088a3..2fc517f 100644
--- a/src/OpenGL/compiler/Initialize.cpp
+++ b/src/OpenGL/compiler/Initialize.cpp
@@ -100,6 +100,16 @@
     symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", genType, genType, genType);
     symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", float1, float1, genType);
 
+	TType *outFloat1 = new TType(EbtFloat, EbpUndefined, EvqOut);
+	TType *outFloat2 = new TType(EbtFloat, EbpUndefined, EvqOut, 2);
+	TType *outFloat3 = new TType(EbtFloat, EbpUndefined, EvqOut, 3);
+	TType *outFloat4 = new TType(EbtFloat, EbpUndefined, EvqOut, 4);
+
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float1, "modf", float1, outFloat1);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float2, "modf", float2, outFloat2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float3, "modf", float3, outFloat3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float4, "modf", float4, outFloat4);
+
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIsNan, genBType, "isnan", genType);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIsInf, genBType, "isinf", genType);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFloatBitsToInt, genIType, "floatBitsToInt", genType);
diff --git a/src/OpenGL/compiler/OutputASM.cpp b/src/OpenGL/compiler/OutputASM.cpp
index 0abb9e4..91f6418 100644
--- a/src/OpenGL/compiler/OutputASM.cpp
+++ b/src/OpenGL/compiler/OutputASM.cpp
@@ -1474,6 +1474,15 @@
 		case EOpVectorEqual:      if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_EQ, result, arg[0], arg[1]); break;

 		case EOpVectorNotEqual:   if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_NE, result, arg[0], arg[1]); break;

 		case EOpMod:              if(visit == PostVisit) emit(sw::Shader::OPCODE_MOD, result, arg[0], arg[1]); break;

+		case EOpModf:

+			if(visit == PostVisit)

+			{

+				TIntermTyped* arg1 = arg[1]->getAsTyped();

+				emit(sw::Shader::OPCODE_TRUNC, arg1, arg[0]);

+				assignLvalue(arg1, arg1);

+				emitBinary(sw::Shader::OPCODE_SUB, result, arg[0], arg1);

+			}

+			break;

 		case EOpPow:              if(visit == PostVisit) emit(sw::Shader::OPCODE_POW, result, arg[0], arg[1]); break;

 		case EOpAtan:             if(visit == PostVisit) emit(sw::Shader::OPCODE_ATAN2, result, arg[0], arg[1]); break;

 		case EOpMin:              if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_MIN, result), result, arg[0], arg[1]); break;

@@ -2196,7 +2205,7 @@
 	void OutputASM::assignLvalue(TIntermTyped *dst, TIntermTyped *src)

 	{

 		if(src &&

-			((src->isVector() && (!dst->isVector() || (dst->getNominalSize() != dst->getNominalSize()))) ||

+			((src->isVector() && (!dst->isVector() || (src->getNominalSize() != dst->getNominalSize()))) ||

 			 (src->isMatrix() && (!dst->isMatrix() || (src->getNominalSize() != dst->getNominalSize()) || (src->getSecondarySize() != dst->getSecondarySize())))))

 		{

 			return mContext.error(src->getLine(), "Result type should match the l-value type in compound assignment", src->isVector() ? "vector" : "matrix");

diff --git a/src/OpenGL/compiler/intermOut.cpp b/src/OpenGL/compiler/intermOut.cpp
index a482175..0b219b9 100644
--- a/src/OpenGL/compiler/intermOut.cpp
+++ b/src/OpenGL/compiler/intermOut.cpp
@@ -281,6 +281,7 @@
         case EOpVectorNotEqual:   out << "NotEqual";                      break;
 
         case EOpMod:           out << "mod";         break;
+        case EOpModf:          out << "modf";        break;
         case EOpPow:           out << "pow";         break;
 
         case EOpAtan:          out << "arc tangent"; break;
diff --git a/src/OpenGL/compiler/intermediate.h b/src/OpenGL/compiler/intermediate.h
index 7d7007a..7db04f4 100644
--- a/src/OpenGL/compiler/intermediate.h
+++ b/src/OpenGL/compiler/intermediate.h
@@ -130,6 +130,7 @@
     EOpCeil,
     EOpFract,
     EOpMod,
+    EOpModf,
     EOpMin,
     EOpMax,
     EOpClamp,