Implement minimal SIMD::Int functionality

This change introduces the first Reactor SIMD type with minimal working
functionality.

SIMD types go in the SIMD namespace, to facilitate the writing of
parallel algorithms without explicitly using SIMD everywhere. In other
words one can write SPMD style code such as shaders.

The types are defined in SIMD.hpp, while the target-independent
operations are implemented in SIMD.cpp. LLVMReactor.cpp and
SubzeroReactor.cpp contain the target-dependent code. Note we don't add
new files for the latter, as some of the static utilities defined in
the old files will be reused, including adaptations of some of the
narrow-vector operations.

SIMD related unit tests do go in a new source file, as the legacy
functionality should remain independent and this also avoids some
confusion for tests that will use the SIMD namespace.

Bug: b/214583550
Change-Id: I2b17d38d6e8ccf6fa5568344a8d6163fea4ef44a
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/66189
Reviewed-by: Alexis Hétu <sugoi@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Android.bp b/src/Android.bp
index 26ed610..b647f2a 100644
--- a/src/Android.bp
+++ b/src/Android.bp
@@ -39,6 +39,7 @@
         "Reactor/LLVMReactor.cpp",
         "Reactor/Pragma.cpp",
         "Reactor/Reactor.cpp",
+        "Reactor/SIMD.cpp",
     ],
 
     cflags: [
diff --git a/src/Reactor/BUILD.gn b/src/Reactor/BUILD.gn
index 676f99f..45a2acf 100644
--- a/src/Reactor/BUILD.gn
+++ b/src/Reactor/BUILD.gn
@@ -43,6 +43,7 @@
     "ExecutableMemory.cpp",
     "Pragma.cpp",
     "Reactor.cpp",
+    "SIMD.cpp",
   ]
 
   configs = [
diff --git a/src/Reactor/CMakeLists.txt b/src/Reactor/CMakeLists.txt
index bb49a08..3e301a1 100644
--- a/src/Reactor/CMakeLists.txt
+++ b/src/Reactor/CMakeLists.txt
@@ -34,6 +34,8 @@
     ReactorDebugInfo.cpp
     ReactorDebugInfo.hpp
     Routine.hpp
+    SIMD.cpp
+    SIMD.hpp
     Swizzle.hpp
 )
 
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index cfd4629..6d5beaf 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -20,6 +20,7 @@
 #include "PragmaInternals.hpp"
 #include "Print.hpp"
 #include "Reactor.hpp"
+#include "SIMD.hpp"
 #include "x86.hpp"
 
 #include "llvm/IR/Intrinsics.h"
@@ -359,6 +360,8 @@
 
 namespace rr {
 
+const int SIMD::Width = 8;
+
 std::string Caps::backendName()
 {
 	return std::string("LLVM ") + LLVM_VERSION_STRING;
@@ -4312,4 +4315,9 @@
 	return func();
 }
 
+Type *SIMD::Int::type()
+{
+	return T(llvm::VectorType::get(T(rr::Int::type()), SIMD::Width, false));
+}
+
 }  // namespace rr
diff --git a/src/Reactor/SIMD.cpp b/src/Reactor/SIMD.cpp
new file mode 100644
index 0000000..a520990
--- /dev/null
+++ b/src/Reactor/SIMD.cpp
@@ -0,0 +1,34 @@
+// Copyright 2022 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "SIMD.hpp"
+
+namespace rr::SIMD {
+
+SIMD::Int::Int(RValue<SIMD::Int> rhs)
+{
+	store(rhs);
+}
+
+SIMD::Int::Int(const Reference<SIMD::Int> &rhs)
+{
+	storeValue(rhs.loadValue());
+}
+
+RValue<SIMD::Int> operator+(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
+{
+	return RValue<SIMD::Int>(Nucleus::createAdd(lhs.value(), rhs.value()));
+}
+
+}  // namespace rr::SIMD
diff --git a/src/Reactor/SIMD.hpp b/src/Reactor/SIMD.hpp
new file mode 100644
index 0000000..b720714
--- /dev/null
+++ b/src/Reactor/SIMD.hpp
@@ -0,0 +1,37 @@
+// Copyright 2022 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef rr_SIMD_hpp
+#define rr_SIMD_hpp
+
+#include "Reactor.hpp"
+
+namespace rr::SIMD {
+
+extern const int Width;
+
+class Int : public LValue<Int>
+{
+public:
+	Int(RValue<Int> rhs);
+	Int(const Reference<Int> &rhs);
+
+	static Type *type();
+};
+
+RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs);
+
+}  // namespace rr::SIMD
+
+#endif  // rr_SIMD_hpp
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index b6e4106..9538b5c 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -16,6 +16,7 @@
 #include "Print.hpp"
 #include "Reactor.hpp"
 #include "ReactorDebugInfo.hpp"
+#include "SIMD.hpp"
 
 #include "ExecutableMemory.hpp"
 #include "Optimizer.hpp"
@@ -342,6 +343,8 @@
 
 namespace rr {
 
+const int SIMD::Width = 4;
+
 std::string Caps::backendName()
 {
 	return "Subzero";
@@ -5082,4 +5085,9 @@
 	}
 }
 
+Type *SIMD::Int::type()
+{
+	return T(Ice::IceType_v4i32);
+}
+
 }  // namespace rr