[MIPS] Add support for 64b MIPS architecture

* LLVM reactor backend: requires LLVM 7.0
* Subzero reactor backend: not supported

Bug: b/117854176
Change-Id: I7b76ebf854f65c2d111552552bd5a81c049d3b50
Reviewed-on: https://swiftshader-review.googlesource.com/c/22308
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Gordana Cmiljanovic <gordana.cmiljanovic@mips.com>
diff --git a/BUILD.gn b/BUILD.gn
index 672e51e..027adfd 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -104,6 +104,13 @@
         "-mhard-float",
         "-mfp32",
       ]
+    } else if (target_cpu == "mips64el" && current_cpu == target_cpu) {
+      cflags += [
+        "-march=mips64el",
+        "-mcpu=mips64r2",
+        "-mabi=64",
+        "-fPIC",
+      ]
     }
 
     if (is_linux) {
@@ -114,6 +121,11 @@
           "-Wl,--hash-style=sysv",
           "-mips32r2",
         ]
+      } else if (target_cpu == "mips64el") {
+        ldflags += [
+          "-Wl,--hash-style=sysv",
+          "-mips64r2",
+        ]
       } else {
         ldflags += [ "-Wl,--hash-style=both" ]
       }
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fb94ffe..0cf0ffc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -139,7 +139,7 @@
         # Don't allow symbols to be overridden by another module.
         set_property(TARGET ${TARGET} APPEND_STRING PROPERTY COMPILE_FLAGS " -fvisibility=protected")
 
-        if(ARCH STREQUAL "mipsel")
+        if(ARCH STREQUAL "mipsel" OR ARCH STREQUAL "mips64el")
           # MIPS supports sysv hash-style only.
           set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--hash-style=sysv")
         else()
@@ -231,6 +231,11 @@
         set_cpp_flag("-mhard-float")
         set_cpp_flag("-mfp32")
     endif()
+    if(ARCH STREQUAL "mips64el")
+        set_cpp_flag("-march=mips64r2")
+        set_cpp_flag("-mabi=64")
+        set_cpp_flag("-fPIC")
+    endif()
 
     if(LINUX)
         set_cpp_flag("-DUSE_X11=1")
diff --git a/src/Reactor/BUILD.gn b/src/Reactor/BUILD.gn
index 1ad06e4..e05154e 100644
--- a/src/Reactor/BUILD.gn
+++ b/src/Reactor/BUILD.gn
@@ -15,8 +15,9 @@
 import("../swiftshader.gni")
 
 declare_args() {
-  # Subzero produces smaller binaries, but doesn't support ARM64.
-  use_swiftshader_with_subzero = (target_cpu != "arm64")
+  # Subzero produces smaller binaries, but doesn't support ARM64 and MIPS64.
+  use_swiftshader_with_subzero =
+      target_cpu != "arm64" && target_cpu != "mips64el"
 }
 
 # Need a separate config to ensure the warnings are added to the end.
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index f7cbfab..6f99e6e 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -830,7 +830,11 @@
 		#elif defined(__arm__)
 			static const char arch[] = "arm";
 		#elif defined(__mips__)
-			static const char arch[] = "mipsel";
+			#if defined(__mips64)
+			    static const char arch[] = "mips64el";
+			#else
+			    static const char arch[] = "mipsel";
+			#endif
 		#else
 		#error "unknown architecture"
 		#endif
diff --git a/third_party/llvm-7.0/configs/linux/include/llvm/Config/config.h b/third_party/llvm-7.0/configs/linux/include/llvm/Config/config.h
index bedb306..ff20611 100644
--- a/third_party/llvm-7.0/configs/linux/include/llvm/Config/config.h
+++ b/third_party/llvm-7.0/configs/linux/include/llvm/Config/config.h
@@ -301,6 +301,8 @@
 #define LLVM_DEFAULT_TARGET_TRIPLE "aarch64-linux-gnu"
 #elif defined(__mips__)
 #define LLVM_DEFAULT_TARGET_TRIPLE "mipsel-linux-gnu"
+#elif defined(__mips64)
+#define LLVM_DEFAULT_TARGET_TRIPLE "mips64el-linux-gnuabi64"
 #else
 #error "unknown architecture"
 #endif
diff --git a/third_party/llvm-7.0/configs/linux/include/llvm/Config/llvm-config.h b/third_party/llvm-7.0/configs/linux/include/llvm/Config/llvm-config.h
index 174aca9..0aa1094 100644
--- a/third_party/llvm-7.0/configs/linux/include/llvm/Config/llvm-config.h
+++ b/third_party/llvm-7.0/configs/linux/include/llvm/Config/llvm-config.h
@@ -31,6 +31,8 @@
 #define LLVM_DEFAULT_TARGET_TRIPLE "aarch64-linux-gnu"
 #elif defined(__mips__)
 #define LLVM_DEFAULT_TARGET_TRIPLE "mipsel-linux-gnu"
+#elif defined(__mips64)
+#define LLVM_DEFAULT_TARGET_TRIPLE "mips64el-linux-gnuabi64"
 #else
 #error "unknown architecture"
 #endif
@@ -52,6 +54,8 @@
 #define LLVM_HOST_TRIPLE "aarch64-linux-gnu"
 #elif defined(__mips__)
 #define LLVM_HOST_TRIPLE "mipsel-linux-gnu"
+#elif defined(__mips64)
+#define LLVM_HOST_TRIPLE "mips64el-linux-gnuabi64"
 #else
 #error "unknown architecture"
 #endif
diff --git a/third_party/llvm-7.0/scripts/update.py b/third_party/llvm-7.0/scripts/update.py
index 0913ee0..1ad1fb9 100755
--- a/third_party/llvm-7.0/scripts/update.py
+++ b/third_party/llvm-7.0/scripts/update.py
@@ -49,6 +49,7 @@
         ('__arm__', 'armv7-linux-gnueabihf'),
         ('__aarch64__', 'aarch64-linux-gnu'),
         ('__mips__', 'mipsel-linux-gnu'),
+        ('__mips64', 'mips64el-linux-gnuabi64'),
     ],
     'darwin': [
         ('__x86_64__', 'x86_64-apple-darwin'),