Merge remote-tracking branch 'llvm-upstream/master'

This brings in r236319:
Fix float->uint conversion for inputs less than 0
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..63603d3
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,7 @@
+dschuff@chromium.org
+jfb@chromium.org
+jvoung@chromium.org
+kschimpf@chromium.org
+mseaborn@chromium.org
+sehr@chromium.org
+stichnot@chromium.org
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
new file mode 100644
index 0000000..d81168e
--- /dev/null
+++ b/PRESUBMIT.py
@@ -0,0 +1,66 @@
+# Copyright (c) 2012 The Native Client Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Documentation on PRESUBMIT.py can be found at:
+# http://www.chromium.org/developers/how-tos/depottools/presubmit-scripts
+
+EXCLUDE_PROJECT_CHECKS_DIRS = [ '.' ]
+
+import subprocess
+def CheckGitBranch():
+  p = subprocess.Popen("git branch -vv", shell=True,
+                       stdout=subprocess.PIPE)
+  output, _ = p.communicate()
+
+  lines = output.split('\n')
+  for line in lines:
+    # output format for checked-out branch should be
+    # * branchname hash [TrackedBranchName ...
+    toks = line.split()
+    if '*' not in toks[0]:
+      continue
+    if not 'origin/master' in toks[3]:
+      warning = 'Warning: your current branch:\n' + line
+      warning += '\nis not tracking origin/master. git cl push may silently '
+      warning += 'fail to push your change. To fix this, do\n'
+      warning += 'git branch -u origin/master'
+      return warning
+    return None
+  print 'Warning: presubmit check could not determine local git branch'
+  return None
+
+def _CommonChecks(input_api, output_api):
+  """Checks for both upload and commit."""
+  results = []
+  results.extend(input_api.canned_checks.PanProjectChecks(
+      input_api, output_api, project_name='Native Client',
+      excluded_paths=tuple(EXCLUDE_PROJECT_CHECKS_DIRS)))
+  branch_warning = CheckGitBranch()
+  if branch_warning:
+    results.append(output_api.PresubmitPromptWarning(branch_warning))
+  return results
+
+def CheckChangeOnUpload(input_api, output_api):
+  """Verifies all changes in all files.
+  Args:
+    input_api: the limited set of input modules allowed in presubmit.
+    output_api: the limited set of output modules allowed in presubmit.
+  """
+  report = []
+  report.extend(_CommonChecks(input_api, output_api))
+  return report
+
+def CheckChangeOnCommit(input_api, output_api):
+  """Verifies all changes in all files and verifies that the
+  tree is open and can accept a commit.
+  Args:
+    input_api: the limited set of input modules allowed in presubmit.
+    output_api: the limited set of output modules allowed in presubmit.
+  """
+  report = []
+  report.extend(CheckChangeOnUpload(input_api, output_api))
+  return report
+
+def GetPreferredTrySlaves(project, change):
+  return []
diff --git a/codereview.settings b/codereview.settings
new file mode 100644
index 0000000..38eca30
--- /dev/null
+++ b/codereview.settings
@@ -0,0 +1,8 @@
+# This file is used by gcl to get repository specific information.
+CODE_REVIEW_SERVER: codereview.chromium.org
+CC_LIST: native-client-reviews@googlegroups.com
+VIEW_VC: https://gerrit.chromium.org/gerrit/gitweb?p=native_client/pnacl-compiler-rt.git;a=commit;h=
+STATUS: http://nativeclient-status.appspot.com/status
+TRY_ON_UPLOAD: False
+TRYSERVER_PROJECT: nacl
+TRYSERVER_SVN_URL: svn://svn.chromium.org/chrome-try/try-nacl
diff --git a/lib/builtins/Makefile-pnacl-bitcode b/lib/builtins/Makefile-pnacl-bitcode
new file mode 100644
index 0000000..0281f92
--- /dev/null
+++ b/lib/builtins/Makefile-pnacl-bitcode
@@ -0,0 +1,39 @@
+# This Makefile builds the PNaCl version of compiler-rt (libgcc.a).
+#
+# This builds the *bitcode* version, for anything that the frontend
+# (clang) depends upon (not functions the backend translator depends upon).
+#
+# More information on the functions of libgcc can be found at:
+# http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc
+# ../README.txt
+#
+# The following variables are expected to be set externally:
+
+# SRC_DIR
+# CC
+# AR
+# CFLAGS
+
+# pick up .c files from another dir
+vpath %.c ${SRC_DIR}
+
+LIBM=compilerrt_logb.c compilerrt_logbf.c compilerrt_fmax.c compilerrt_fmaxf.c
+
+FLOATING_POINT_COMPLEX=\
+divdc3.c divsc3.c \
+muldc3.c mulsc3.c
+
+SRCS=$(LIBM) $(FLOATING_POINT_COMPLEX)
+
+EXTRA_FLAGS= -I${SRC_DIR}
+
+# overwrite default rule to make sure nothing unexpected happens.
+%.o : %.c
+	$(CC) -c $(CFLAGS) ${EXTRA_FLAGS} $< -o $@
+
+# The main target of this Makefile.
+libgcc.a: $(SRCS:.c=.o)
+	$(AR) rc $@ $^
+
+nacltest-pnacl:
+	test/builtins/Unit/nacltest.py $(TCROOT)/bin/pnacl-clang $(SRCS)
diff --git a/lib/builtins/arm/aeabi_idivmod.S b/lib/builtins/arm/aeabi_idivmod.S
index 384add3..859c86d 100644
--- a/lib/builtins/arm/aeabi_idivmod.S
+++ b/lib/builtins/arm/aeabi_idivmod.S
@@ -19,10 +19,13 @@
         .p2align 2
 DEFINE_COMPILERRT_FUNCTION(__aeabi_idivmod)
         push    { lr }
+        SFI_SP \
         sub     sp, sp, #4
         mov     r2, sp
-        bl      SYMBOL_NAME(__divmodsi4)
+        SFI_BL  SYMBOL_NAME(__divmodsi4)
         ldr     r1, [sp]
+        SFI_SP \
         add     sp, sp, #4
-        pop     { pc }
+        pop     { lr }
+        SFI_BX  lr
 END_COMPILERRT_FUNCTION(__aeabi_idivmod)
diff --git a/lib/builtins/arm/aeabi_ldivmod.S b/lib/builtins/arm/aeabi_ldivmod.S
index ad06f1d..1cad939 100644
--- a/lib/builtins/arm/aeabi_ldivmod.S
+++ b/lib/builtins/arm/aeabi_ldivmod.S
@@ -20,12 +20,15 @@
         .p2align 2
 DEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod)
         push    {r11, lr}
+        SFI_SP \
         sub     sp, sp, #16
         add     r12, sp, #8
         str     r12, [sp]
-        bl      SYMBOL_NAME(__divmoddi4)
+        SFI_BL  SYMBOL_NAME(__divmoddi4)
         ldr     r2, [sp, #8]
         ldr     r3, [sp, #12]
+        SFI_SP \
         add     sp, sp, #16
-        pop     {r11, pc}
+        pop     {r11, lr}
+        SFI_BX  lr
 END_COMPILERRT_FUNCTION(__aeabi_ldivmod)
diff --git a/lib/builtins/arm/aeabi_uidivmod.S b/lib/builtins/arm/aeabi_uidivmod.S
index 8ea474d..002ef12 100644
--- a/lib/builtins/arm/aeabi_uidivmod.S
+++ b/lib/builtins/arm/aeabi_uidivmod.S
@@ -20,10 +20,13 @@
         .p2align 2
 DEFINE_COMPILERRT_FUNCTION(__aeabi_uidivmod)
         push    { lr }
+        SFI_SP \
         sub     sp, sp, #4
         mov     r2, sp
-        bl      SYMBOL_NAME(__udivmodsi4)
+        SFI_BL      SYMBOL_NAME(__udivmodsi4)
         ldr     r1, [sp]
+        SFI_SP \
         add     sp, sp, #4
-        pop     { pc }
+        pop     { lr }
+        SFI_BX  lr
 END_COMPILERRT_FUNCTION(__aeabi_uidivmod)
diff --git a/lib/builtins/arm/aeabi_uldivmod.S b/lib/builtins/arm/aeabi_uldivmod.S
index 4e1f8e2..8d6eef5 100644
--- a/lib/builtins/arm/aeabi_uldivmod.S
+++ b/lib/builtins/arm/aeabi_uldivmod.S
@@ -20,12 +20,15 @@
         .p2align 2
 DEFINE_COMPILERRT_FUNCTION(__aeabi_uldivmod)
         push	{r11, lr}
+        SFI_SP \
         sub	sp, sp, #16
         add	r12, sp, #8
         str	r12, [sp]
-        bl	SYMBOL_NAME(__udivmoddi4)
+        SFI_BL	SYMBOL_NAME(__udivmoddi4)
         ldr	r2, [sp, #8]
         ldr	r3, [sp, #12]
+        SFI_SP \
         add	sp, sp, #16
-        pop	{r11, pc}
+        pop     {r11, lr}
+        SFI_BX  lr
 END_COMPILERRT_FUNCTION(__aeabi_uldivmod)
diff --git a/lib/builtins/assembly.h b/lib/builtins/assembly.h
index 8bb0ddc..0102e73 100644
--- a/lib/builtins/assembly.h
+++ b/lib/builtins/assembly.h
@@ -63,6 +63,23 @@
 #if !defined(__ARM_FEATURE_CLZ) &&                                             \
     (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__)))
 #define __ARM_FEATURE_CLZ
+
+/* LOCALMOD-START */
+#if defined(__native_client__) && !defined(__native_client_nonsfi__)
+#define SFI_SP sfi_sp
+#define SFI_BREG sfi_breg reg
+#define SFI_BL sfi_bl
+#define SFI_BX sfi_bx
+#define ENTRY_P2ALIGN 4
+#define NACL_ALIGN .p2align ENTRY_P2ALIGN
+#else
+#define SFI_SP
+#define SFI_BREG
+#define SFI_BL bl
+#define SFI_BX bx
+#define NACL_ALIGN
+#endif
+/* LOCALMOD-END */
 #endif
 
 #ifdef ARM_HAS_BX
@@ -100,6 +117,7 @@
 #endif
 
 #define DEFINE_COMPILERRT_FUNCTION(name)                                       \
+  NACL_ALIGN                                                                   \
   FILE_LEVEL_DIRECTIVE SEPARATOR                                               \
   .globl SYMBOL_NAME(name) SEPARATOR                                           \
   SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \
diff --git a/lib/builtins/atomic64.c b/lib/builtins/atomic64.c
new file mode 100644
index 0000000..1245d94
--- /dev/null
+++ b/lib/builtins/atomic64.c
@@ -0,0 +1,240 @@
+/*===----- atomic64.c - Support functions for 64-bit atomic operations.-----===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ *===-----------------------------------------------------------------------===
+ *
+ *  atomic64.c defines a set of functions for performing atomic accesses on
+ *  64-bit memory locations. It also implements spinlock synchronization
+ *  operations.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#pragma redefine_extname __nacl_sync_fetch_and_add_8 __sync_fetch_and_add_8
+#pragma redefine_extname __nacl_sync_fetch_and_sub_8 __sync_fetch_and_sub_8
+#pragma redefine_extname __nacl_sync_fetch_and_and_8 __sync_fetch_and_and_8
+#pragma redefine_extname __nacl_sync_fetch_and_or_8  __sync_fetch_and_or_8
+#pragma redefine_extname __nacl_sync_fetch_and_xor_8 __sync_fetch_and_xor_8
+
+#pragma redefine_extname __nacl_sync_add_and_fetch_8 __sync_add_and_fetch_8
+#pragma redefine_extname __nacl_sync_sub_and_fetch_8 __sync_sub_and_fetch_8
+#pragma redefine_extname __nacl_sync_and_and_fetch_8 __sync_and_and_fetch_8
+#pragma redefine_extname __nacl_sync_or_and_fetch_8  __sync_or_and_fetch_8
+#pragma redefine_extname __nacl_sync_xor_and_fetch_8 __sync_xor_and_fetch_8
+
+#pragma redefine_extname __nacl_sync_bool_compare_and_swap_8 \
+                         __sync_bool_compare_and_swap_8
+#pragma redefine_extname __nacl_sync_val_compare_and_swap_8 \
+                         __sync_val_compare_and_swap_8
+#pragma redefine_extname __nacl_sync_lock_test_and_set_8 \
+                         __sync_lock_test_and_set_8
+#pragma redefine_extname __nacl_sync_lock_release_8 __sync_lock_release_8
+
+static void __spin_lock(volatile int *lock) {
+  while (__sync_lock_test_and_set(lock, 1))
+    while (*lock) {}
+}
+
+static void __spin_unlock(volatile int *lock) {
+  __sync_lock_release(lock);
+}
+
+/*
+ * Make sure the lock is on its own cache line to prevent false sharing.
+ * Put it inside a struct that is aligned and padded to the typical MIPS
+ * cacheline which is 32 bytes.
+ */
+static struct {
+  int lock;
+  char pad[32 - sizeof(int)];
+} __attribute__((aligned (32))) lock = { 0 };
+
+
+uint64_t __nacl_sync_fetch_and_add_8(volatile uint64_t *ptr, uint64_t val) {
+  uint64_t ret;
+
+  __spin_lock(&lock.lock);
+
+  ret = *ptr;
+  *ptr = ret + val;
+
+  __spin_unlock(&lock.lock);
+
+  return ret;
+}
+
+uint64_t __nacl_sync_fetch_and_sub_8(volatile uint64_t *ptr, uint64_t val) {
+  uint64_t ret;
+
+  __spin_lock(&lock.lock);
+
+  ret = *ptr;
+  *ptr = ret - val;
+
+  __spin_unlock(&lock.lock);
+
+  return ret;
+}
+
+uint64_t __nacl_sync_fetch_and_and_8(volatile uint64_t *ptr, uint64_t val) {
+  uint64_t ret;
+
+  __spin_lock(&lock.lock);
+
+  ret = *ptr;
+  *ptr = ret & val;
+
+  __spin_unlock(&lock.lock);
+
+  return ret;
+}
+
+uint64_t __nacl_sync_fetch_and_or_8(volatile uint64_t *ptr, uint64_t val) {
+  uint64_t ret;
+
+  __spin_lock(&lock.lock);
+
+  ret = *ptr;
+  *ptr = ret | val;
+
+  __spin_unlock(&lock.lock);
+
+  return ret;
+}
+
+uint64_t __nacl_sync_fetch_and_xor_8(volatile uint64_t *ptr, uint64_t val) {
+  uint64_t ret;
+
+  __spin_lock(&lock.lock);
+
+  ret = *ptr;
+  *ptr = ret ^ val;
+
+  __spin_unlock(&lock.lock);
+
+  return ret;
+}
+
+uint64_t __nacl_sync_add_and_fetch_8(volatile uint64_t *ptr, uint64_t val) {
+  uint64_t ret;
+
+  __spin_lock(&lock.lock);
+
+  ret = *ptr + val;
+  *ptr = ret;
+
+  __spin_unlock(&lock.lock);
+
+  return ret;
+}
+
+uint64_t __nacl_sync_sub_and_fetch_8(volatile uint64_t *ptr, uint64_t val) {
+  uint64_t ret;
+
+  __spin_lock(&lock.lock);
+
+  ret = *ptr - val;
+  *ptr = ret;
+
+  __spin_unlock(&lock.lock);
+
+  return ret;
+}
+
+uint64_t __nacl_sync_and_and_fetch_8(volatile uint64_t *ptr, uint64_t val) {
+  uint64_t ret;
+
+  __spin_lock(&lock.lock);
+
+  ret = *ptr & val;
+  *ptr = ret;
+
+  __spin_unlock(&lock.lock);
+
+  return ret;
+}
+
+uint64_t __nacl_sync_or_and_fetch_8(volatile uint64_t *ptr, uint64_t val) {
+  uint64_t ret;
+
+  __spin_lock(&lock.lock);
+
+  ret = *ptr | val;
+  *ptr = ret;
+
+  __spin_unlock(&lock.lock);
+
+  return ret;
+}
+
+uint64_t __nacl_sync_xor_and_fetch_8(volatile uint64_t *ptr, uint64_t val) {
+  uint64_t ret;
+
+  __spin_lock(&lock.lock);
+
+  ret = *ptr ^ val;
+  *ptr = ret;
+
+  __spin_unlock(&lock.lock);
+
+  return ret;
+}
+
+bool __nacl_sync_bool_compare_and_swap_8(volatile uint64_t *ptr,
+                                         uint64_t oldval, uint64_t newval) {
+  bool ret = false;
+
+  __spin_lock(&lock.lock);
+
+  if (*ptr == oldval) {
+    *ptr = newval;
+    ret = true;
+  }
+
+  __spin_unlock(&lock.lock);
+
+  return ret;
+}
+
+uint64_t __nacl_sync_val_compare_and_swap_8(volatile uint64_t *ptr,
+                                            uint64_t oldval, uint64_t newval) {
+  uint64_t ret;
+
+  __spin_lock(&lock.lock);
+
+  ret = *ptr;
+  if (ret == oldval)
+    *ptr = newval;
+
+  __spin_unlock(&lock.lock);
+
+  return ret;
+}
+
+uint64_t __nacl_sync_lock_test_and_set_8(volatile uint64_t *ptr, uint64_t val) {
+  uint64_t ret;
+
+  __spin_lock(&lock.lock);
+
+  ret = *ptr;
+  *ptr = val;
+
+  __spin_unlock(&lock.lock);
+
+  return ret;
+}
+
+void __nacl_sync_lock_release_8(volatile uint64_t *ptr) {
+  __spin_lock(&lock.lock);
+
+  *ptr = 0;
+
+  __spin_unlock(&lock.lock);
+}
diff --git a/lib/builtins/compilerrt_fmax.c b/lib/builtins/compilerrt_fmax.c
new file mode 100644
index 0000000..a4b0741
--- /dev/null
+++ b/lib/builtins/compilerrt_fmax.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2015 The Native Client Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "int_math.h"
+
+double __compilerrt_fmax(double x, double y)
+{
+  if (crt_isnan(x))
+    return y;
+  if (crt_isnan(y))
+    return x;
+  return x > y ? x : y;
+}
diff --git a/lib/builtins/compilerrt_fmaxf.c b/lib/builtins/compilerrt_fmaxf.c
new file mode 100644
index 0000000..eb8d937
--- /dev/null
+++ b/lib/builtins/compilerrt_fmaxf.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2015 The Native Client Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "int_math.h"
+
+float __compilerrt_fmaxf(float x, float y)
+{
+  if (crt_isnan(x))
+    return y;
+  if (crt_isnan(y))
+    return x;
+  return x > y ? x : y;
+}
diff --git a/lib/builtins/compilerrt_logb.c b/lib/builtins/compilerrt_logb.c
new file mode 100644
index 0000000..69abe4d
--- /dev/null
+++ b/lib/builtins/compilerrt_logb.c
@@ -0,0 +1,40 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* From newlib's newlib/libm/common/s_logb.c */
+
+#include "fdlibm_nacl.h"
+
+double __compilerrt_logb(double x)
+{
+        __int32_t hx,lx,ix;
+
+        EXTRACT_WORDS(hx,lx,x);
+        hx &= 0x7fffffff;               /* high |x| */
+        if(hx<0x00100000) {             /* 0 or subnormal */
+            if((hx|lx)==0)  {
+                double  xx;
+                /* arg==0:  return -inf and raise divide-by-zero exception */
+                INSERT_WORDS(xx,hx,lx); /* +0.0 */
+                return -1./xx;  /* logb(0) = -inf */
+                }
+            else                        /* subnormal x */
+                if(hx==0) {
+                    for (ix = -1043; lx>0; lx<<=1) ix -=1;
+                } else {
+                    for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
+                }
+            return (double) ix;
+        }
+        else if (hx<0x7ff00000) return (hx>>20)-1023;   /* normal # */
+        else if (hx>0x7ff00000 || lx)  return x;        /* x==NaN */
+        else  return HUGE_VAL;  /* x==inf (+ or -) */
+}
diff --git a/lib/builtins/compilerrt_logbf.c b/lib/builtins/compilerrt_logbf.c
new file mode 100644
index 0000000..66ab268
--- /dev/null
+++ b/lib/builtins/compilerrt_logbf.c
@@ -0,0 +1,35 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* From newlib's newlib/libm/common/sf_logb.c */
+
+#include "fdlibm_nacl.h"
+
+float __compilerrt_logbf(float x)
+{
+        __int32_t hx,ix;
+
+        GET_FLOAT_WORD(hx,x);
+        hx &= 0x7fffffff;
+        if(FLT_UWORD_IS_ZERO(hx))  {
+                float  xx;
+                /* arg==0:  return -inf and raise divide-by-zero exception */
+                SET_FLOAT_WORD(xx,hx);  /* +0.0 */
+                return -1./xx;  /* logbf(0) = -inf */
+                }
+        if(FLT_UWORD_IS_SUBNORMAL(hx)) {
+            for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1;
+            return (float) ix;
+        }
+        else if (FLT_UWORD_IS_INFINITE(hx)) return HUGE_VALF;   /* x==+|-inf */
+        else if (FLT_UWORD_IS_NAN(hx)) return x;
+        else return (float) ((hx>>23)-127);
+}
diff --git a/lib/builtins/fdlibm_nacl.h b/lib/builtins/fdlibm_nacl.h
new file mode 100644
index 0000000..51cff7f
--- /dev/null
+++ b/lib/builtins/fdlibm_nacl.h
@@ -0,0 +1,93 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* NaCl-specific defines and typedefs */
+#define HUGE_VALF __builtin_huge_valf()
+#define HUGE_VAL __builtin_huge_val()
+
+typedef int __int32_t;
+typedef unsigned int __uint32_t;
+
+/* Excerpted from newlib's libm/common/fdlibm.h */
+
+#define FLT_UWORD_IS_FINITE(x) ((x)<0x7f800000L)
+#define FLT_UWORD_IS_NAN(x) ((x)>0x7f800000L)
+#define FLT_UWORD_IS_INFINITE(x) ((x)==0x7f800000L)
+#define FLT_UWORD_MAX 0x7f7fffffL
+#define FLT_UWORD_EXP_MAX 0x43000000
+#define FLT_UWORD_LOG_MAX 0x42b17217
+#define FLT_UWORD_LOG_2MAX 0x42b2d4fc
+#define HUGE ((float)3.40282346638528860e+38)
+
+#define FLT_UWORD_IS_ZERO(x) ((x)==0)
+#define FLT_UWORD_IS_SUBNORMAL(x) ((x)<0x00800000L)
+#define FLT_UWORD_MIN 0x00000001
+#define FLT_UWORD_EXP_MIN 0x43160000
+#define FLT_UWORD_LOG_MIN 0x42cff1b5
+#define FLT_SMALLEST_EXP -22
+
+
+typedef union
+{
+  double value;
+  struct
+  {
+    __uint32_t lsw;
+    __uint32_t msw;
+  } parts;
+} ieee_double_shape_type;
+
+/* Get two 32 bit ints from a double.  */
+
+#define EXTRACT_WORDS(ix0,ix1,d)                                \
+do {                                                            \
+  ieee_double_shape_type ew_u;                                  \
+  ew_u.value = (d);                                             \
+  (ix0) = ew_u.parts.msw;                                       \
+  (ix1) = ew_u.parts.lsw;                                       \
+} while (0)
+
+/* Set a double from two 32 bit ints.  */
+
+#define INSERT_WORDS(d,ix0,ix1)                                 \
+do {                                                            \
+  ieee_double_shape_type iw_u;                                  \
+  iw_u.parts.msw = (ix0);                                       \
+  iw_u.parts.lsw = (ix1);                                       \
+  (d) = iw_u.value;                                             \
+} while (0)
+
+/* A union which permits us to convert between a float and a 32 bit
+   int.  */
+
+typedef union
+{
+  float value;
+  __uint32_t word;
+} ieee_float_shape_type;
+
+/* Get a 32 bit int from a float.  */
+
+#define GET_FLOAT_WORD(i,d)                                     \
+do {                                                            \
+  ieee_float_shape_type gf_u;                                   \
+  gf_u.value = (d);                                             \
+  (i) = gf_u.word;                                              \
+} while (0)
+
+/* Set a float from a 32 bit int.  */
+
+#define SET_FLOAT_WORD(d,i)                                     \
+do {                                                            \
+  ieee_float_shape_type sf_u;                                   \
+  sf_u.word = (i);                                              \
+  (d) = sf_u.value;                                             \
+} while (0)
diff --git a/lib/builtins/int_math.h b/lib/builtins/int_math.h
index d6b4bda..aa6a4f1 100644
--- a/lib/builtins/int_math.h
+++ b/lib/builtins/int_math.h
@@ -52,13 +52,21 @@
 #define crt_fabsf(x) __builtin_fabsf((x))
 #define crt_fabsl(x) __builtin_fabsl((x))
 
-#define crt_fmax(x, y) __builtin_fmax((x), (y))
-#define crt_fmaxf(x, y) __builtin_fmaxf((x), (y))
-#define crt_fmaxl(x, y) __builtin_fmaxl((x), (y))
+// @LOCALMOD-START
+float __compilerrt_fmaxf(float x, float y);
+double __compilerrt_fmax(double x, double y);
 
-#define crt_logb(x) __builtin_logb((x))
-#define crt_logbf(x) __builtin_logbf((x))
-#define crt_logbl(x) __builtin_logbl((x))
+#define crt_fmax(x, y) __compilerrt_fmax((x), (y))
+#define crt_fmaxf(x, y) __compilerrt_fmaxf((x), (y))
+#define crt_fmaxl(x, y) __compilerrt_fmax((x), (y))
+
+float __compilerrt_logbf(float x);
+double __compilerrt_logb(double x);
+
+#define crt_logb(x) __compilerrt_logb((x))
+#define crt_logbf(x) __compilerrt_logbf((x))
+#define crt_logbl(x) __compilerrt_logb((x))
+// @LOCALMOD-END
 
 #define crt_scalbn(x, y) __builtin_scalbn((x), (y))
 #define crt_scalbnf(x, y) __builtin_scalbnf((x), (y))
diff --git a/lib/builtins/int_types.h b/lib/builtins/int_types.h
index aedae14..d6a72ab 100644
--- a/lib/builtins/int_types.h
+++ b/lib/builtins/int_types.h
@@ -57,7 +57,10 @@
 } udwords;
 
 /* MIPS64 issue: PR 20098 */
-#if defined(__LP64__) && !(defined(__mips__) && defined(__clang__))
+// @LOCALMOD
+#if (defined(__LP64__) || \
+     (defined(__native_client__) && defined(__x86_64__))) \
+    && !(defined(__mips__) && defined(__clang__))
 #define CRT_HAS_128BIT
 #endif
 
@@ -141,4 +144,3 @@
 } long_double_bits;
 
 #endif /* INT_TYPES_H */
-
diff --git a/make/platform/clang_nacl.mk b/make/platform/clang_nacl.mk
new file mode 100644
index 0000000..e7448d9
--- /dev/null
+++ b/make/platform/clang_nacl.mk
@@ -0,0 +1,173 @@
+Description := Static runtime libraries for clang/NaCl.
+
+###
+
+CC := clang
+Arch := unknown
+Configs :=
+
+# We don't currently have any general purpose way to target architectures other
+# than the compiler defaults (because there is no generalized way to invoke
+# cross compilers). For now, we just find the target architecture of the compiler
+# and only define configurations we know that compiler can generate.
+CompilerTargetTriple := $(shell \
+	$(CC) $(EXTRA_CFLAGS) -v 2>&1 | grep 'Target:' | cut -d' ' -f2)
+ifneq ($(DEBUGMAKE),)
+ifeq ($(CompilerTargetTriple),)
+$(error "unable to infer compiler target triple for $(CC)")
+endif
+endif
+
+CompilerTargetArch := $(firstword $(subst -, ,$(CompilerTargetTriple)))
+$(call CheckValue,CompilerTargetTriple)
+# Only define configs if we detected a nacl target.
+ifneq ($(findstring -nacl,$(CompilerTargetTriple)),)
+
+ifneq ($(findstring pnacl-clang,$(CC)),)
+# pnacl-clang already uses the integrated assembler and does not support the
+# integrated-as flag
+INTEGRATED_AS :=
+else
+INTEGRATED_AS := -integrated-as
+endif
+
+# Configurations which just include all the runtime functions.
+ifeq ($(call contains,i686,$(CompilerTargetArch)),true)
+Configs += full-i386
+Arch.full-i386 := i386
+else
+ifeq ($(call contains,x86_64,$(CompilerTargetArch)),true)
+Configs += full-x86_64
+Arch.full-x86_64 := x86_64
+else
+ifeq ($(call contains,arm,$(CompilerTargetArch)),true)
+# arm-nacl-clang reports this target
+Configs += full-arm
+Arch.full-arm := armv7
+else
+ifeq ($(call contains,armv7,$(CompilerTargetArch)),true)
+# pnacl-clang with arm bias (used for arm-nonsfi) reports this target
+Configs += full-arm
+Arch.full-arm := armv7
+else
+ifeq ($(call contains,le32,$(CompilerTargetArch)),true)
+# This is really for mips, but mips uses le32 bitcode
+Configs += full-mips32
+Arch.full-mips32 := mips32
+endif
+endif
+endif
+endif
+endif
+
+endif
+
+###
+
+$(call CheckValue,CFLAGS)
+CFLAGS := -Wall -Werror -O3 -fomit-frame-pointer $(EXTRA_CFLAGS)
+$(call CheckValue,CFLAGS)
+# Use the integrated assembler on x86-64 to ensure sandbox base-address hiding.
+
+CFLAGS.full-x86_64 := $(CFLAGS) -m64 $(INTEGRATED_AS)
+CFLAGS.full-arm := $(CFLAGS)
+CFLAGS.full-i386 := $(CFLAGS) -m32 $(INTEGRATED_AS)
+
+
+# The following are common to all platforms and are also included in PNaCl:
+IdivFunctions := divdi3 divsi3 udivdi3 udivsi3 divmoddi4 divmodsi4 udivmoddi4 \
+                 udivmodsi4 moddi3 modsi3 umoddi3 umodsi3
+
+# These are copies of a few libm functions, to avoid having to link
+# with libm for compiler-rt
+LibMFunctions := compilerrt_fmaxf compilerrt_fmax \
+                 compilerrt_logb compilerrt_logbf
+FPComplexFunctions := $(LibMFunctions) divdc3 divsc3 muldc3 mulsc3
+
+FPRoundToZeroFunctions := fixdfdi fixdfsi fixsfdi fixsfsi fixunsdfdi fixunsdfsi \
+		          fixunssfdi fixunssfsi
+
+FPRoundToEvenFunctions := floatdidf floatdisf floatsidf floatsisf floatundidf \
+			  floatundisf floatunsidf floatunsisf
+
+FPPowFunctions := powisf2 powidf2
+
+PopCountFunctions := popcountsi2 popcountdi2
+
+# The following are used everywhere except x86-64:
+OverflowFunctions := mulodi4 mulosi4
+
+
+Int128Functions := fixdfti fixsfti fixunsdfti fixunssfti \
+                   floatuntidf floatuntisf muloti4 \
+                   floattidf floattisf udivmodti4 clzti2 ctzti2 \
+                   udivti3  umodti3  modti3 multi3 divti3 popcountti2
+
+# TODO(dschuff): maybe add some of the following. They are currently handled w/
+# native instructions but non-LLVM codegens might want them.
+# Soft-float arith: addsf3 adddf3 addtf3 subsf3 subdf3 subtf3
+# Integer bit manipulation: ashldi3 ashlti3 ashrdi3 ashrti3 lshrdi3 lshrti3
+#  clzsi2 clzdi2 clzti2 ctzsi2 ctzdi2 ctzti2
+#  ffsdi2 ffsti2 paritysi2 paritydi2 parityti2
+#  bswapsi2 bswapdi2 (arm only)
+# Integer arithmetic: negdi2 negti2 muldi3 multi3
+# Integer artith with trapping overflow: absvsi2 absvdi2 absvti2
+#  negvsi2 negvdi2 negvti2 mulvsi3 mulvti3 mulvti3
+#  addvdi3 addvsi3 addvti3 subvdi3 subvsi3 subvti3
+# Integer comparison: cmpdi2 cmpti2 ucmpdi2 ucmpti2
+
+
+# Functions excluded:
+# 80 bit complex float: divxc3 mulxc3
+# 80 bit float: floatdixf floatundixf fixunsxfdi fixunsxfsi fixunsxfti
+#   fixxfdi fixxfsi fixxfti posixf2 powixf2 powitf2 floattixf floatuntixf
+# PPC: powitf2 fixtfdi fixunstfdi floatditf floatunditf divtc3
+# gcc_personality_v0
+# apple_versioning
+# trampoline_setup
+# enable_execute_stack
+# clear_cache
+# eprintf
+
+# ARM helper functions defined by EABI
+# Note that there are many other aeabi functions that get defined as aliases to
+# functions included in other categories. This list only inlcludes functions
+# that have their own separate implementations.
+# We leave out the soft-float routines, since the soft-float routines above are
+# also left out, and NaCl requires VFP (this will also help ensure we don't
+# accidentally start depending on them):
+# aeabi_dcmp aeabi_fcmp
+AEABIFunctions := aeabi_div0 aeabi_idivmod aeabi_ldivmod \
+	          aeabi_memcmp aeabi_memcpy aeabi_memmove aeabi_memset \
+		  aeabi_uidivmod aeabi_uldivmod
+
+# Mips/portability functions
+MipsFunctions := atomic64
+
+NaClCommonFunctions := $(IdivFunctions) $(FPComplexFunctions) \
+	               $(FPRoundToZeroFunctions) $(FPRoundToEvenFunctions) \
+	               $(FPPowFunctions) $(PopCountFunctions)
+
+FUNCTIONS.full-i386 := $(NaClCommonFunctions) $(OverflowFunctions)
+FUNCTIONS.full-x86_64 := $(NaClCommonFunctions) $(Int128Functions)
+FUNCTIONS.full-arm := $(NaClCommonFunctions) $(OverflowFunctions) \
+	              $(AEABIFunctions)
+FUNCTIONS.full-mips32 := $(NaClCommonFunctions) $(OverflowFunctions) \
+                         $(MipsFunctions)
+
+# For now, do not use the assembly implementations because they haven't been
+# ported to NaCl.
+OPTIMIZED := 0
+
+# We don't need to use visibility hidden on Linux.
+VISIBILITY_HIDDEN := 0
+
+nacltest-x86-32:
+	test/builtins/Unit/nacltest.py $(TCROOT)/bin/i686-nacl-clang \
+	 $(FUNCTIONS.full-i386)
+nacltest-x86-64:
+	test/builtins/Unit/nacltest.py $(TCROOT)/bin/x86_64-nacl-clang \
+	 $(FUNCTIONS.full-x86_64)
+nacltest-arm:
+	test/builtins/Unit/nacltest.py $(TCROOT)/bin/arm-nacl-clang \
+	 $(FUNCTIONS.full-arm)
diff --git a/test/builtins/Unit/nacltest.py b/test/builtins/Unit/nacltest.py
new file mode 100755
index 0000000..f0372b7
--- /dev/null
+++ b/test/builtins/Unit/nacltest.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python
+# Copyright (c) 2015 The Native Client Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# This script runs the tests for compiler_rt. It is meant to run on a
+# fully-constructed toolchain (as opposed to being run during the compiler-rt
+# build process) because the tests need libc/libnacl to link.
+
+import os
+import shutil
+import subprocess
+import sys
+import tempfile
+
+def find_run_py():
+  """ Find run.py somewhere in one of the parents of the current directory."""
+  dir = os.path.abspath(os.path.dirname(__file__))
+  while os.path.dirname(dir) != dir:
+    run_py = os.path.join(dir, 'run.py')
+    if os.path.isfile(run_py):
+      return run_py
+    dir = os.path.dirname(dir)
+  print 'Could not find run.py'
+  sys.exit(1)
+
+def parse_args(argv):
+  cc = argv[1]
+  tests = argv[2:]
+  return cc, tests
+
+def get_tests(functions, test_dir):
+  """ Find the test files for the given functions.
+
+      Given a list of functions to test, find each corresponding compiler-rt
+      unit test, if it exists. The functions may be specified as bare function
+      names (with no underscores), or source files of the same name.
+  """
+  tests = []
+  for function in functions:
+    # If the argument is specified as a source file, strip the suffix.
+    if function.endswith('.c'):
+      function = function[:-2]
+    test_src = os.path.join(test_dir, '%s_test.c' % function)
+    if os.path.isfile(test_src):
+      tests.append(test_src)
+    else:
+      print 'no test for', function
+  return tests
+
+def main(argv):
+  cc, functions = parse_args(argv)
+  cc = os.path.abspath(cc)
+  src_root = os.getcwd()
+  test_src_dir = os.path.join(src_root, 'test', 'builtins', 'Unit')
+  inc_dir = os.path.join(src_root, 'lib', 'builtins')
+  tests = get_tests(functions, test_src_dir)
+  run_py = find_run_py()
+  failures = 0
+  workdir = tempfile.mkdtemp()
+
+  for test in tests:
+    flags = ['-lm']
+    exe_suffix = '.pexe' if 'pnacl-clang' in cc else '.nexe'
+    nexe = os.path.join(workdir, os.path.basename(test + exe_suffix))
+    build_cmd = [cc, '-I' + inc_dir, '-o', nexe, test] + flags
+    run_cmd = [run_py, '-arch', 'env', nexe]
+    try:
+      print ' '.join(build_cmd)
+      subprocess.check_call(build_cmd)
+      print ' '.join(run_cmd)
+      subprocess.check_call(run_cmd)
+    except subprocess.CalledProcessError, e:
+      print '[  FAILED  ]:', test
+      print e
+      failures += 1
+
+  shutil.rmtree(workdir)
+  return failures
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))