Index: cmake/config-ix.cmake
===================================================================
--- cmake/config-ix.cmake
+++ cmake/config-ix.cmake
@@ -137,7 +137,7 @@
     test_target_arch(powerpc64le ${TARGET_64_BIT_CFLAGS})
   elseif("${LLVM_NATIVE_ARCH}" STREQUAL "Mips")
     if("${COMPILER_RT_TEST_TARGET_ARCH}" MATCHES "mipsel|mips64el")
-      # regex for mipsel, mips64el                                                                                                                                                                                 
+      # regex for mipsel, mips64el
       test_target_arch(mipsel ${TARGET_32_BIT_CFLAGS})
       test_target_arch(mips64el ${TARGET_64_BIT_CFLAGS})
     else()
@@ -174,7 +174,7 @@
 filter_available_targets(ASAN_SUPPORTED_ARCH
   x86_64 i386 i686 powerpc64 powerpc64le arm mips mipsel)
 filter_available_targets(DFSAN_SUPPORTED_ARCH x86_64)
-filter_available_targets(LSAN_SUPPORTED_ARCH x86_64)
+filter_available_targets(LSAN_SUPPORTED_ARCH x86_64 mips64 mips64el)
 # LSan common files should be available on all architectures supported
 # by other sanitizers (even if they build into dummy object files).
 filter_available_targets(LSAN_COMMON_SUPPORTED_ARCH
Index: lib/lsan/lsan_allocator.cc
===================================================================
--- lib/lsan/lsan_allocator.cc
+++ lib/lsan/lsan_allocator.cc
@@ -26,8 +26,13 @@
 namespace __lsan {
 
 static const uptr kMaxAllowedMallocSize = 8UL << 30;
+#if defined(__mips64)
+static const uptr kAllocatorSpace = 0x4000000000ULL;
+static const uptr kAllocatorSize  = 0x4000000000ULL;  // 256GB.
+#else
 static const uptr kAllocatorSpace = 0x600000000000ULL;
 static const uptr kAllocatorSize  =  0x40000000000ULL;  // 4T.
+#endif
 
 struct ChunkMetadata {
   bool allocated : 8;  // Must be first.
Index: lib/lsan/lsan_common.h
===================================================================
--- lib/lsan/lsan_common.h
+++ lib/lsan/lsan_common.h
@@ -21,7 +21,8 @@
 #include "sanitizer_common/sanitizer_platform.h"
 #include "sanitizer_common/sanitizer_symbolizer.h"
 
-#if SANITIZER_LINUX && defined(__x86_64__) && (SANITIZER_WORDSIZE == 64)
+#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips64)) \
+                    && (SANITIZER_WORDSIZE == 64)
 #define CAN_SANITIZE_LEAKS 1
 #else
 #define CAN_SANITIZE_LEAKS 0
Index: lib/lsan/lsan_common.cc
===================================================================
--- lib/lsan/lsan_common.cc
+++ lib/lsan/lsan_common.cc
@@ -144,6 +144,8 @@
 #ifdef __x86_64__
   // Accept only canonical form user-space addresses.
   return ((p >> 47) == 0);
+#elif defined(__mips64)
+  return ((p >> 40) == 0);
 #else
   return true;
 #endif
Index: lib/sanitizer_common/sanitizer_linux.h
===================================================================
--- lib/sanitizer_common/sanitizer_linux.h
+++ lib/sanitizer_common/sanitizer_linux.h
@@ -43,7 +43,7 @@
 // internal_sigaction instead.
 int internal_sigaction_norestorer(int signum, const void *act, void *oldact);
 void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
-#if defined(__x86_64__)
+#if defined(__x86_64__) || defined(__mips__)
 uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
                     int *parent_tidptr, void *newtls, int *child_tidptr);
 #endif
Index: lib/sanitizer_common/sanitizer_linux.cc
===================================================================
--- lib/sanitizer_common/sanitizer_linux.cc
+++ lib/sanitizer_common/sanitizer_linux.cc
@@ -833,6 +833,13 @@
                        : "rsp", "memory", "r11", "rcx");
   return res;
 }
+#elif defined(__mips__)
+// TODO(kumarsukhani): clone function is to be rewritten in assembly
+uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
+                    int *parent_tidptr, void *newtls, int *child_tidptr) {
+  return clone(fn, child_stack, flags, arg, parent_tidptr,
+               newtls, child_tidptr);
+}
 #endif  // defined(__x86_64__) && SANITIZER_LINUX
 
 #if SANITIZER_ANDROID
Index: lib/sanitizer_common/sanitizer_linux_libcdep.cc
===================================================================
--- lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -177,7 +177,8 @@
 #endif  // !SANITIZER_FREEBSD && !SANITIZER_ANDROID
 }
 
-#if (defined(__x86_64__) || defined(__i386__)) && SANITIZER_LINUX
+#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__)) \
+     && SANITIZER_LINUX
 // sizeof(struct thread) from glibc.
 static atomic_uintptr_t kThreadDescriptorSize;
 
@@ -185,7 +186,13 @@
   uptr val = atomic_load(&kThreadDescriptorSize, memory_order_relaxed);
   if (val)
     return val;
-#ifdef _CS_GNU_LIBC_VERSION
+
+#ifdef __mips__
+  // TODO(kumarsukhani): add more values as per different glibc versions
+  val = FIRST_32_SECOND_64(1152, 1760);
+  return val;
+
+#elif defined(_CS_GNU_LIBC_VERSION)
   char buf[64];
   uptr len = confstr(_CS_GNU_LIBC_VERSION, buf, sizeof(buf));
   if (len < sizeof(buf) && internal_strncmp(buf, "glibc 2.", 8) == 0) {
@@ -231,13 +238,34 @@
   asm("mov %%gs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset));
 # elif defined(__x86_64__)
   asm("mov %%fs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset));
+# elif defined(__mips__)
+
+  // MIPS uses TLS variant I. The thread pointer (in hardware register $29)
+  // points to the end of the TCB + 0x7000. The pthread_descr structure is
+  // immediately in front of the TCB. kTlsPreTcbSize includes the size of the
+  // TCB and the size of pthread_descr."
+
+  const uptr kTlsTcbOffset = 0x7000;
+  const uptr kTcbHead = 16;
+  const uptr kTlsTcbAlign = 16;
+  uptr kThreadPointer;
+
+  uptr kTlsPreTcbSize = (ThreadDescriptorSize() + kTcbHead + kTlsTcbAlign -1)
+                        & ~(kTlsTcbAlign -1);
+
+  asm volatile(".set push;\
+                .set mips32r2;\
+                rdhwr %0,$29;\
+                .set\tpop" : "=r" (kThreadPointer));
+
+  descr_addr = kThreadPointer - kTlsTcbOffset - kTlsPreTcbSize;
 # else
 #  error "unsupported CPU arch"
 # endif
   return descr_addr;
 }
-#endif  // (defined(__x86_64__) || defined(__i386__)) && SANITIZER_LINUX
-
+#endif  // (defined(__x86_64__) || defined(__i386__) || defined(__mips__)) \
+        //  && SANITIZER_LINUX
 #if SANITIZER_FREEBSD
 static void **ThreadSelfSegbase() {
   void **segbase = 0;
@@ -265,6 +293,9 @@
   *size = GetTlsSize();
   *addr -= *size;
   *addr += ThreadDescriptorSize();
+# elif defined(__mips__)
+  *addr = ThreadSelf();
+  *size = GetTlsSize();
 # else
   *addr = 0;
   *size = 0;
Index: lib/sanitizer_common/sanitizer_platform.h
===================================================================
--- lib/sanitizer_common/sanitizer_platform.h
+++ lib/sanitizer_common/sanitizer_platform.h
@@ -109,4 +109,10 @@
 # endif
 #endif
 
+#ifdef __mips__
+# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(10, 8)
+#else
+# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(12, 8)
+#endif
+
 #endif // SANITIZER_PLATFORM_H
Index: lib/sanitizer_common/sanitizer_platform_limits_posix.h
===================================================================
--- lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -538,6 +538,10 @@
 
 #if SANITIZER_FREEBSD
   typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t;
+#elif defined(__mips__)
+  struct __sanitizer_kernel_sigset_t {
+    u8 sig[16];
+  };
 #else
   struct __sanitizer_kernel_sigset_t {
     u8 sig[8];
Index: lib/sanitizer_common/sanitizer_printf.cc
===================================================================
--- lib/sanitizer_common/sanitizer_printf.cc
+++ lib/sanitizer_common/sanitizer_printf.cc
@@ -113,7 +113,7 @@
   int result = 0;
   result += AppendString(buff, buff_end, -1, "0x");
   result += AppendUnsigned(buff, buff_end, ptr_value, 16,
-                           (SANITIZER_WORDSIZE == 64) ? 12 : 8, true);
+                           SANITIZER_POINTER_FORMAT_LENGTH, true);
   return result;
 }
 
Index: lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
===================================================================
--- lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
+++ lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
@@ -14,7 +14,7 @@
 
 
 #include "sanitizer_platform.h"
-#if SANITIZER_LINUX && defined(__x86_64__)
+#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__))
 
 #include "sanitizer_stoptheworld.h"
 
@@ -459,4 +459,4 @@
 }
 }  // namespace __sanitizer
 
-#endif  // SANITIZER_LINUX && defined(__x86_64__)
+#endif  // SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__))