summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/builtins/arm
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/builtins/arm')
-rw-r--r--compiler-rt/lib/builtins/arm/Makefile.mk20
-rw-r--r--compiler-rt/lib/builtins/arm/adddf3vfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/addsf3vfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/aeabi_dcmp.S40
-rw-r--r--compiler-rt/lib/builtins/arm/aeabi_fcmp.S40
-rw-r--r--compiler-rt/lib/builtins/arm/aeabi_idivmod.S28
-rw-r--r--compiler-rt/lib/builtins/arm/aeabi_ldivmod.S31
-rw-r--r--compiler-rt/lib/builtins/arm/aeabi_memcmp.S20
-rw-r--r--compiler-rt/lib/builtins/arm/aeabi_memcpy.S20
-rw-r--r--compiler-rt/lib/builtins/arm/aeabi_memmove.S20
-rw-r--r--compiler-rt/lib/builtins/arm/aeabi_memset.S34
-rw-r--r--compiler-rt/lib/builtins/arm/aeabi_uidivmod.S29
-rw-r--r--compiler-rt/lib/builtins/arm/aeabi_uldivmod.S31
-rw-r--r--compiler-rt/lib/builtins/arm/bswapdi2.S37
-rw-r--r--compiler-rt/lib/builtins/arm/bswapsi2.S29
-rw-r--r--compiler-rt/lib/builtins/arm/clzdi2.S89
-rw-r--r--compiler-rt/lib/builtins/arm/clzsi2.S69
-rw-r--r--compiler-rt/lib/builtins/arm/comparesf2.S148
-rw-r--r--compiler-rt/lib/builtins/arm/divdf3vfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/divmodsi4.S61
-rw-r--r--compiler-rt/lib/builtins/arm/divsf3vfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/divsi3.S52
-rw-r--r--compiler-rt/lib/builtins/arm/eqdf2vfp.S29
-rw-r--r--compiler-rt/lib/builtins/arm/eqsf2vfp.S29
-rw-r--r--compiler-rt/lib/builtins/arm/extendsfdf2vfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/fixdfsivfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/fixsfsivfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/fixunsdfsivfp.S27
-rw-r--r--compiler-rt/lib/builtins/arm/fixunssfsivfp.S27
-rw-r--r--compiler-rt/lib/builtins/arm/floatsidfvfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/floatsisfvfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/floatunssidfvfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/floatunssisfvfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/gedf2vfp.S29
-rw-r--r--compiler-rt/lib/builtins/arm/gesf2vfp.S29
-rw-r--r--compiler-rt/lib/builtins/arm/gtdf2vfp.S29
-rw-r--r--compiler-rt/lib/builtins/arm/gtsf2vfp.S29
-rw-r--r--compiler-rt/lib/builtins/arm/ledf2vfp.S29
-rw-r--r--compiler-rt/lib/builtins/arm/lesf2vfp.S29
-rw-r--r--compiler-rt/lib/builtins/arm/ltdf2vfp.S29
-rw-r--r--compiler-rt/lib/builtins/arm/ltsf2vfp.S29
-rw-r--r--compiler-rt/lib/builtins/arm/modsi3.S51
-rw-r--r--compiler-rt/lib/builtins/arm/muldf3vfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/mulsf3vfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/nedf2vfp.S29
-rw-r--r--compiler-rt/lib/builtins/arm/negdf2vfp.S23
-rw-r--r--compiler-rt/lib/builtins/arm/negsf2vfp.S23
-rw-r--r--compiler-rt/lib/builtins/arm/nesf2vfp.S29
-rw-r--r--compiler-rt/lib/builtins/arm/restore_vfp_d8_d15_regs.S35
-rw-r--r--compiler-rt/lib/builtins/arm/save_vfp_d8_d15_regs.S35
-rw-r--r--compiler-rt/lib/builtins/arm/softfloat-alias.list21
-rw-r--r--compiler-rt/lib/builtins/arm/subdf3vfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/subsf3vfp.S27
-rw-r--r--compiler-rt/lib/builtins/arm/switch16.S46
-rw-r--r--compiler-rt/lib/builtins/arm/switch32.S47
-rw-r--r--compiler-rt/lib/builtins/arm/switch8.S45
-rw-r--r--compiler-rt/lib/builtins/arm/switchu8.S45
-rw-r--r--compiler-rt/lib/builtins/arm/sync_synchronize.S35
-rw-r--r--compiler-rt/lib/builtins/arm/truncdfsf2vfp.S26
-rw-r--r--compiler-rt/lib/builtins/arm/udivmodsi4.S161
-rw-r--r--compiler-rt/lib/builtins/arm/udivsi3.S148
-rw-r--r--compiler-rt/lib/builtins/arm/umodsi3.S141
-rw-r--r--compiler-rt/lib/builtins/arm/unorddf2vfp.S29
-rw-r--r--compiler-rt/lib/builtins/arm/unordsf2vfp.S29
64 files changed, 2531 insertions, 0 deletions
diff --git a/compiler-rt/lib/builtins/arm/Makefile.mk b/compiler-rt/lib/builtins/arm/Makefile.mk
new file mode 100644
index 00000000000..ed2e8323e39
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/Makefile.mk
@@ -0,0 +1,20 @@
+#===- lib/builtins/arm/Makefile.mk -------------------------*- Makefile -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+ModuleName := builtins
+SubDirs :=
+OnlyArchs := armv5 armv6 armv7 armv7k armv7m armv7em armv7s
+
+AsmSources := $(foreach file,$(wildcard $(Dir)/*.S),$(notdir $(file)))
+Sources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))
+ObjNames := $(Sources:%.c=%.o) $(AsmSources:%.S=%.o)
+Implementation := Optimized
+
+# FIXME: use automatic dependencies?
+Dependencies := $(wildcard lib/*.h $(Dir)/*.h)
diff --git a/compiler-rt/lib/builtins/arm/adddf3vfp.S b/compiler-rt/lib/builtins/arm/adddf3vfp.S
new file mode 100644
index 00000000000..4302b6ab310
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/adddf3vfp.S
@@ -0,0 +1,26 @@
+//===-- adddf3vfp.S - Implement adddf3vfp ---------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// double __adddf3vfp(double a, double b) { return a + b; }
+//
+// Adds two double precision floating point numbers using the Darwin
+// calling convention where double arguments are passsed in GPR pairs
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__adddf3vfp)
+ vmov d6, r0, r1 // move first param from r0/r1 pair into d6
+ vmov d7, r2, r3 // move second param from r2/r3 pair into d7
+ vadd.f64 d6, d6, d7
+ vmov r0, r1, d6 // move result back to r0/r1 pair
+ bx lr
+END_COMPILERRT_FUNCTION(__adddf3vfp)
diff --git a/compiler-rt/lib/builtins/arm/addsf3vfp.S b/compiler-rt/lib/builtins/arm/addsf3vfp.S
new file mode 100644
index 00000000000..316328abe69
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/addsf3vfp.S
@@ -0,0 +1,26 @@
+//===-- addsf3vfp.S - Implement addsf3vfp ---------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern float __addsf3vfp(float a, float b);
+//
+// Adds two single precision floating point numbers using the Darwin
+// calling convention where single arguments are passsed in GPRs
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__addsf3vfp)
+ vmov s14, r0 // move first param from r0 into float register
+ vmov s15, r1 // move second param from r1 into float register
+ vadd.f32 s14, s14, s15
+ vmov r0, s14 // move result back to r0
+ bx lr
+END_COMPILERRT_FUNCTION(__addsf3vfp)
diff --git a/compiler-rt/lib/builtins/arm/aeabi_dcmp.S b/compiler-rt/lib/builtins/arm/aeabi_dcmp.S
new file mode 100644
index 00000000000..ee2946d2d55
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_dcmp.S
@@ -0,0 +1,40 @@
+//===-- aeabi_dcmp.S - EABI dcmp* implementation ---------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// int __aeabi_dcmp{eq,lt,le,ge,gt}(double a, double b) {
+// int result = __{eq,lt,le,ge,gt}df2(a, b);
+// if (result {==,<,<=,>=,>} 0) {
+// return 1;
+// } else {
+// return 0;
+// }
+// }
+
+#define DEFINE_AEABI_DCMP(cond) \
+ .syntax unified SEPARATOR \
+ .align 2 SEPARATOR \
+DEFINE_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond) \
+ push { r4, lr } SEPARATOR \
+ bl SYMBOL_NAME(__ ## cond ## df2) SEPARATOR \
+ cmp r0, #0 SEPARATOR \
+ b ## cond 1f SEPARATOR \
+ mov r0, #0 SEPARATOR \
+ pop { r4, pc } SEPARATOR \
+1: SEPARATOR \
+ mov r0, #1 SEPARATOR \
+ pop { r4, pc } SEPARATOR \
+END_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond)
+
+DEFINE_AEABI_DCMP(eq)
+DEFINE_AEABI_DCMP(lt)
+DEFINE_AEABI_DCMP(le)
+DEFINE_AEABI_DCMP(ge)
+DEFINE_AEABI_DCMP(gt)
diff --git a/compiler-rt/lib/builtins/arm/aeabi_fcmp.S b/compiler-rt/lib/builtins/arm/aeabi_fcmp.S
new file mode 100644
index 00000000000..ac3f54721f7
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_fcmp.S
@@ -0,0 +1,40 @@
+//===-- aeabi_fcmp.S - EABI fcmp* implementation ---------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// int __aeabi_fcmp{eq,lt,le,ge,gt}(float a, float b) {
+// int result = __{eq,lt,le,ge,gt}sf2(a, b);
+// if (result {==,<,<=,>=,>} 0) {
+// return 1;
+// } else {
+// return 0;
+// }
+// }
+
+#define DEFINE_AEABI_FCMP(cond) \
+ .syntax unified SEPARATOR \
+ .align 2 SEPARATOR \
+DEFINE_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond) \
+ push { r4, lr } SEPARATOR \
+ bl SYMBOL_NAME(__ ## cond ## sf2) SEPARATOR \
+ cmp r0, #0 SEPARATOR \
+ b ## cond 1f SEPARATOR \
+ mov r0, #0 SEPARATOR \
+ pop { r4, pc } SEPARATOR \
+1: SEPARATOR \
+ mov r0, #1 SEPARATOR \
+ pop { r4, pc } SEPARATOR \
+END_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond)
+
+DEFINE_AEABI_FCMP(eq)
+DEFINE_AEABI_FCMP(lt)
+DEFINE_AEABI_FCMP(le)
+DEFINE_AEABI_FCMP(ge)
+DEFINE_AEABI_FCMP(gt)
diff --git a/compiler-rt/lib/builtins/arm/aeabi_idivmod.S b/compiler-rt/lib/builtins/arm/aeabi_idivmod.S
new file mode 100644
index 00000000000..ac5dfcc22be
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_idivmod.S
@@ -0,0 +1,28 @@
+//===-- aeabi_idivmod.S - EABI idivmod implementation ---------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// struct { int quot, int rem} __aeabi_idivmod(int numerator, int denominator) {
+// int rem, quot;
+// quot = __divmodsi4(numerator, denominator, &rem);
+// return {quot, rem};
+// }
+
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_idivmod)
+ push { lr }
+ sub sp, sp, #4
+ mov r2, sp
+ bl SYMBOL_NAME(__divmodsi4)
+ ldr r1, [sp]
+ add sp, sp, #4
+ pop { pc }
+END_COMPILERRT_FUNCTION(__aeabi_idivmod)
diff --git a/compiler-rt/lib/builtins/arm/aeabi_ldivmod.S b/compiler-rt/lib/builtins/arm/aeabi_ldivmod.S
new file mode 100644
index 00000000000..68425257141
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_ldivmod.S
@@ -0,0 +1,31 @@
+//===-- aeabi_ldivmod.S - EABI ldivmod implementation ---------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// struct { int64_t quot, int64_t rem}
+// __aeabi_ldivmod(int64_t numerator, int64_t denominator) {
+// int64_t rem, quot;
+// quot = __divmoddi4(numerator, denominator, &rem);
+// return {quot, rem};
+// }
+
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod)
+ push {r11, lr}
+ sub sp, sp, #16
+ add r12, sp, #8
+ str r12, [sp]
+ bl SYMBOL_NAME(__divmoddi4)
+ ldr r2, [sp, #8]
+ ldr r3, [sp, #12]
+ add sp, sp, #16
+ pop {r11, pc}
+END_COMPILERRT_FUNCTION(__aeabi_ldivmod)
diff --git a/compiler-rt/lib/builtins/arm/aeabi_memcmp.S b/compiler-rt/lib/builtins/arm/aeabi_memcmp.S
new file mode 100644
index 00000000000..fc20825f475
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_memcmp.S
@@ -0,0 +1,20 @@
+//===-- aeabi_memcmp.S - EABI memcmp implementation -----------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// void __aeabi_memcmp(void *dest, void *src, size_t n) { memcmp(dest, src, n); }
+
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memcmp)
+ b memcmp
+END_COMPILERRT_FUNCTION(__aeabi_memcmp)
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp4, __aeabi_memcmp)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp8, __aeabi_memcmp)
diff --git a/compiler-rt/lib/builtins/arm/aeabi_memcpy.S b/compiler-rt/lib/builtins/arm/aeabi_memcpy.S
new file mode 100644
index 00000000000..f6184632ed9
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_memcpy.S
@@ -0,0 +1,20 @@
+//===-- aeabi_memcpy.S - EABI memcpy implementation -----------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// void __aeabi_memcpy(void *dest, void *src, size_t n) { memcpy(dest, src, n); }
+
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memcpy)
+ b memcpy
+END_COMPILERRT_FUNCTION(__aeabi_memcpy)
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy4, __aeabi_memcpy)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy8, __aeabi_memcpy)
diff --git a/compiler-rt/lib/builtins/arm/aeabi_memmove.S b/compiler-rt/lib/builtins/arm/aeabi_memmove.S
new file mode 100644
index 00000000000..f3d6b0e1ab8
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_memmove.S
@@ -0,0 +1,20 @@
+//===-- aeabi_memmove.S - EABI memmove implementation --------------------===//
+//
+// 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.
+//
+//===---------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// void __aeabi_memmove(void *dest, void *src, size_t n) { memmove(dest, src, n); }
+
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memmove)
+ b memmove
+END_COMPILERRT_FUNCTION(__aeabi_memmove)
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove4, __aeabi_memmove)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove8, __aeabi_memmove)
diff --git a/compiler-rt/lib/builtins/arm/aeabi_memset.S b/compiler-rt/lib/builtins/arm/aeabi_memset.S
new file mode 100644
index 00000000000..43c085e2665
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_memset.S
@@ -0,0 +1,34 @@
+//===-- aeabi_memset.S - EABI memset implementation -----------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// void __aeabi_memset(void *dest, size_t n, int c) { memset(dest, c, n); }
+// void __aeabi_memclr(void *dest, size_t n) { __aeabi_memset(dest, n, 0); }
+
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memset)
+ mov r3, r1
+ mov r1, r2
+ mov r2, r3
+ b memset
+END_COMPILERRT_FUNCTION(__aeabi_memset)
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset4, __aeabi_memset)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset8, __aeabi_memset)
+
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memclr)
+ mov r2, r1
+ mov r1, #0
+ b memset
+END_COMPILERRT_FUNCTION(__aeabi_memclr)
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr4, __aeabi_memclr)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr8, __aeabi_memclr)
+
diff --git a/compiler-rt/lib/builtins/arm/aeabi_uidivmod.S b/compiler-rt/lib/builtins/arm/aeabi_uidivmod.S
new file mode 100644
index 00000000000..4c1e818cb3d
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_uidivmod.S
@@ -0,0 +1,29 @@
+//===-- aeabi_uidivmod.S - EABI uidivmod implementation -------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// struct { unsigned quot, unsigned rem}
+// __aeabi_uidivmod(unsigned numerator, unsigned denominator) {
+// unsigned rem, quot;
+// quot = __udivmodsi4(numerator, denominator, &rem);
+// return {quot, rem};
+// }
+
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_uidivmod)
+ push { lr }
+ sub sp, sp, #4
+ mov r2, sp
+ bl SYMBOL_NAME(__udivmodsi4)
+ ldr r1, [sp]
+ add sp, sp, #4
+ pop { pc }
+END_COMPILERRT_FUNCTION(__aeabi_uidivmod)
diff --git a/compiler-rt/lib/builtins/arm/aeabi_uldivmod.S b/compiler-rt/lib/builtins/arm/aeabi_uldivmod.S
new file mode 100644
index 00000000000..62a2113cc2b
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_uldivmod.S
@@ -0,0 +1,31 @@
+//===-- aeabi_uldivmod.S - EABI uldivmod implementation -------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// struct { uint64_t quot, uint64_t rem}
+// __aeabi_uldivmod(uint64_t numerator, uint64_t denominator) {
+// uint64_t rem, quot;
+// quot = __udivmoddi4(numerator, denominator, &rem);
+// return {quot, rem};
+// }
+
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_uldivmod)
+ push {r11, lr}
+ sub sp, sp, #16
+ add r12, sp, #8
+ str r12, [sp]
+ bl SYMBOL_NAME(__udivmoddi4)
+ ldr r2, [sp, #8]
+ ldr r3, [sp, #12]
+ add sp, sp, #16
+ pop {r11, pc}
+END_COMPILERRT_FUNCTION(__aeabi_uldivmod)
diff --git a/compiler-rt/lib/builtins/arm/bswapdi2.S b/compiler-rt/lib/builtins/arm/bswapdi2.S
new file mode 100644
index 00000000000..c6e1b79c608
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/bswapdi2.S
@@ -0,0 +1,37 @@
+//===------- bswapdi2 - Implement bswapdi2 --------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern uint64_t __bswapdi2(uint64_t);
+//
+// Reverse all the bytes in a 64-bit integer.
+//
+.align 2
+DEFINE_COMPILERRT_FUNCTION(__bswapdi2)
+#if __ARM_ARCH < 6
+ // before armv6 does not have "rev" instruction
+ // r2 = rev(r0)
+ eor r2, r0, r0, ror #16
+ bic r2, r2, #0xff0000
+ mov r2, r2, lsr #8
+ eor r2, r2, r0, ror #8
+ // r0 = rev(r1)
+ eor r0, r1, r1, ror #16
+ bic r0, r0, #0xff0000
+ mov r0, r0, lsr #8
+ eor r0, r0, r1, ror #8
+#else
+ rev r2, r0 // r2 = rev(r0)
+ rev r0, r1 // r0 = rev(r1)
+#endif
+ mov r1, r2 // r1 = r2 = rev(r0)
+ JMP(lr)
+END_COMPILERRT_FUNCTION(__bswapdi2)
diff --git a/compiler-rt/lib/builtins/arm/bswapsi2.S b/compiler-rt/lib/builtins/arm/bswapsi2.S
new file mode 100644
index 00000000000..5842da263d2
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/bswapsi2.S
@@ -0,0 +1,29 @@
+//===------- bswapsi2 - Implement bswapsi2 --------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern uint32_t __bswapsi2(uint32_t);
+//
+// Reverse all the bytes in a 32-bit integer.
+//
+.align 2
+DEFINE_COMPILERRT_FUNCTION(__bswapsi2)
+#if __ARM_ARCH < 6
+ // before armv6 does not have "rev" instruction
+ eor r1, r0, r0, ror #16
+ bic r1, r1, #0xff0000
+ mov r1, r1, lsr #8
+ eor r0, r1, r0, ror #8
+#else
+ rev r0, r0
+#endif
+ JMP(lr)
+END_COMPILERRT_FUNCTION(__bswapsi2)
diff --git a/compiler-rt/lib/builtins/arm/clzdi2.S b/compiler-rt/lib/builtins/arm/clzdi2.S
new file mode 100644
index 00000000000..33284cd3af2
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/clzdi2.S
@@ -0,0 +1,89 @@
+/* ===-- clzdi2.c - Implement __clzdi2 -------------------------------------===
+ *
+ * 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.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements count leading zeros for 64bit arguments.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+#include "../assembly.h"
+
+ .syntax unified
+
+ .text
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__clzdi2)
+#ifdef __ARM_FEATURE_CLZ
+#ifdef __ARMEB__
+ cmp r0, 0
+ itee ne
+ clzne r0, r0
+ clzeq r0, r1
+ addeq r0, r0, 32
+#else
+ cmp r1, 0
+ itee ne
+ clzne r0, r1
+ clzeq r0, r0
+ addeq r0, r0, 32
+#endif
+ JMP(lr)
+#else
+ /* Assumption: n != 0 */
+
+ /*
+ * r0: n
+ * r1: upper half of n, overwritten after check
+ * r1: count of leading zeros in n + 1
+ * r2: scratch register for shifted r0
+ */
+#ifdef __ARMEB__
+ cmp r0, 0
+ moveq r0, r1
+#else
+ cmp r1, 0
+ movne r0, r1
+#endif
+ movne r1, 1
+ moveq r1, 33
+
+ /*
+ * Basic block:
+ * if ((r0 >> SHIFT) == 0)
+ * r1 += SHIFT;
+ * else
+ * r0 >>= SHIFT;
+ * for descending powers of two as SHIFT.
+ */
+#define BLOCK(shift) \
+ lsrs r2, r0, shift; \
+ movne r0, r2; \
+ addeq r1, shift \
+
+ BLOCK(16)
+ BLOCK(8)
+ BLOCK(4)
+ BLOCK(2)
+
+ /*
+ * The basic block invariants at this point are (r0 >> 2) == 0 and
+ * r0 != 0. This means 1 <= r0 <= 3 and 0 <= (r0 >> 1) <= 1.
+ *
+ * r0 | (r0 >> 1) == 0 | (r0 >> 1) == 1 | -(r0 >> 1) | 1 - (r0 >> 1)
+ * ---+----------------+----------------+------------+--------------
+ * 1 | 1 | 0 | 0 | 1
+ * 2 | 0 | 1 | -1 | 0
+ * 3 | 0 | 1 | -1 | 0
+ *
+ * The r1's initial value of 1 compensates for the 1 here.
+ */
+ sub r0, r1, r0, lsr #1
+
+ JMP(lr)
+#endif // __ARM_FEATURE_CLZ
+END_COMPILERRT_FUNCTION(__clzdi2)
diff --git a/compiler-rt/lib/builtins/arm/clzsi2.S b/compiler-rt/lib/builtins/arm/clzsi2.S
new file mode 100644
index 00000000000..8081d3284b8
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/clzsi2.S
@@ -0,0 +1,69 @@
+/* ===-- clzsi2.c - Implement __clzsi2 -------------------------------------===
+ *
+ * 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.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements count leading zeros for 32bit arguments.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+#include "../assembly.h"
+
+ .syntax unified
+
+ .text
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__clzsi2)
+#ifdef __ARM_FEATURE_CLZ
+ clz r0, r0
+ JMP(lr)
+#else
+ /* Assumption: n != 0 */
+
+ /*
+ * r0: n
+ * r1: count of leading zeros in n + 1
+ * r2: scratch register for shifted r0
+ */
+ mov r1, 1
+
+ /*
+ * Basic block:
+ * if ((r0 >> SHIFT) == 0)
+ * r1 += SHIFT;
+ * else
+ * r0 >>= SHIFT;
+ * for descending powers of two as SHIFT.
+ */
+
+#define BLOCK(shift) \
+ lsrs r2, r0, shift; \
+ movne r0, r2; \
+ addeq r1, shift \
+
+ BLOCK(16)
+ BLOCK(8)
+ BLOCK(4)
+ BLOCK(2)
+
+ /*
+ * The basic block invariants at this point are (r0 >> 2) == 0 and
+ * r0 != 0. This means 1 <= r0 <= 3 and 0 <= (r0 >> 1) <= 1.
+ *
+ * r0 | (r0 >> 1) == 0 | (r0 >> 1) == 1 | -(r0 >> 1) | 1 - (r0 >> 1)
+ * ---+----------------+----------------+------------+--------------
+ * 1 | 1 | 0 | 0 | 1
+ * 2 | 0 | 1 | -1 | 0
+ * 3 | 0 | 1 | -1 | 0
+ *
+ * The r1's initial value of 1 compensates for the 1 here.
+ */
+ sub r0, r1, r0, lsr #1
+
+ JMP(lr)
+#endif // __ARM_FEATURE_CLZ
+END_COMPILERRT_FUNCTION(__clzsi2)
diff --git a/compiler-rt/lib/builtins/arm/comparesf2.S b/compiler-rt/lib/builtins/arm/comparesf2.S
new file mode 100644
index 00000000000..ad1b10a7fd3
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/comparesf2.S
@@ -0,0 +1,148 @@
+//===-- comparesf2.S - Implement single-precision soft-float comparisons --===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the following soft-fp_t comparison routines:
+//
+// __eqsf2 __gesf2 __unordsf2
+// __lesf2 __gtsf2
+// __ltsf2
+// __nesf2
+//
+// The semantics of the routines grouped in each column are identical, so there
+// is a single implementation for each, with multiple names.
+//
+// The routines behave as follows:
+//
+// __lesf2(a,b) returns -1 if a < b
+// 0 if a == b
+// 1 if a > b
+// 1 if either a or b is NaN
+//
+// __gesf2(a,b) returns -1 if a < b
+// 0 if a == b
+// 1 if a > b
+// -1 if either a or b is NaN
+//
+// __unordsf2(a,b) returns 0 if both a and b are numbers
+// 1 if either a or b is NaN
+//
+// Note that __lesf2( ) and __gesf2( ) are identical except in their handling of
+// NaN values.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+.syntax unified
+
+.align 2
+DEFINE_COMPILERRT_FUNCTION(__eqsf2)
+ // Make copies of a and b with the sign bit shifted off the top. These will
+ // be used to detect zeros and NaNs.
+ mov r2, r0, lsl #1
+ mov r3, r1, lsl #1
+
+ // We do the comparison in three stages (ignoring NaN values for the time
+ // being). First, we orr the absolute values of a and b; this sets the Z
+ // flag if both a and b are zero (of either sign). The shift of r3 doesn't
+ // effect this at all, but it *does* make sure that the C flag is clear for
+ // the subsequent operations.
+ orrs r12, r2, r3, lsr #1
+
+ // Next, we check if a and b have the same or different signs. If they have
+ // opposite signs, this eor will set the N flag.
+ it ne
+ eorsne r12, r0, r1
+
+ // If a and b are equal (either both zeros or bit identical; again, we're
+ // ignoring NaNs for now), this subtract will zero out r0. If they have the
+ // same sign, the flags are updated as they would be for a comparison of the
+ // absolute values of a and b.
+ it pl
+ subspl r0, r2, r3
+
+ // If a is smaller in magnitude than b and both have the same sign, place
+ // the negation of the sign of b in r0. Thus, if both are negative and
+ // a > b, this sets r0 to 0; if both are positive and a < b, this sets
+ // r0 to -1.
+ //
+ // This is also done if a and b have opposite signs and are not both zero,
+ // because in that case the subtract was not performed and the C flag is
+ // still clear from the shift argument in orrs; if a is positive and b
+ // negative, this places 0 in r0; if a is negative and b positive, -1 is
+ // placed in r0.
+ it lo
+ mvnlo r0, r1, asr #31
+
+ // If a is greater in magnitude than b and both have the same sign, place
+ // the sign of b in r0. Thus, if both are negative and a < b, -1 is placed
+ // in r0, which is the desired result. Conversely, if both are positive
+ // and a > b, zero is placed in r0.
+ it hi
+ movhi r0, r1, asr #31
+
+ // If you've been keeping track, at this point r0 contains -1 if a < b and
+ // 0 if a >= b. All that remains to be done is to set it to 1 if a > b.
+ // If a == b, then the Z flag is set, so we can get the correct final value
+ // into r0 by simply or'ing with 1 if Z is clear.
+ it ne
+ orrne r0, r0, #1
+
+ // Finally, we need to deal with NaNs. If either argument is NaN, replace
+ // the value in r0 with 1.
+ cmp r2, #0xff000000
+ ite ls
+ cmpls r3, #0xff000000
+ movhi r0, #1
+ JMP(lr)
+END_COMPILERRT_FUNCTION(__eqsf2)
+DEFINE_COMPILERRT_FUNCTION_ALIAS(__lesf2, __eqsf2)
+DEFINE_COMPILERRT_FUNCTION_ALIAS(__ltsf2, __eqsf2)
+DEFINE_COMPILERRT_FUNCTION_ALIAS(__nesf2, __eqsf2)
+
+.align 2
+DEFINE_COMPILERRT_FUNCTION(__gtsf2)
+ // Identical to the preceeding except in that we return -1 for NaN values.
+ // Given that the two paths share so much code, one might be tempted to
+ // unify them; however, the extra code needed to do so makes the code size
+ // to performance tradeoff very hard to justify for such small functions.
+ mov r2, r0, lsl #1
+ mov r3, r1, lsl #1
+ orrs r12, r2, r3, lsr #1
+ it ne
+ eorsne r12, r0, r1
+ it pl
+ subspl r0, r2, r3
+ it lo
+ mvnlo r0, r1, asr #31
+ it hi
+ movhi r0, r1, asr #31
+ it ne
+ orrne r0, r0, #1
+ cmp r2, #0xff000000
+ ite ls
+ cmpls r3, #0xff000000
+ movhi r0, #-1
+ JMP(lr)
+END_COMPILERRT_FUNCTION(__gtsf2)
+DEFINE_COMPILERRT_FUNCTION_ALIAS(__gesf2, __gtsf2)
+
+.align 2
+DEFINE_COMPILERRT_FUNCTION(__unordsf2)
+ // Return 1 for NaN values, 0 otherwise.
+ mov r2, r0, lsl #1
+ mov r3, r1, lsl #1
+ mov r0, #0
+ cmp r2, #0xff000000
+ ite ls
+ cmpls r3, #0xff000000
+ movhi r0, #1
+ JMP(lr)
+END_COMPILERRT_FUNCTION(__unordsf2)
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_fcmpun, __unordsf2)
diff --git a/compiler-rt/lib/builtins/arm/divdf3vfp.S b/compiler-rt/lib/builtins/arm/divdf3vfp.S
new file mode 100644
index 00000000000..ec2f9972124
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/divdf3vfp.S
@@ -0,0 +1,26 @@
+//===-- divdf3vfp.S - Implement divdf3vfp ---------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern double __divdf3vfp(double a, double b);
+//
+// Divides two double precision floating point numbers using the Darwin
+// calling convention where double arguments are passsed in GPR pairs
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__divdf3vfp)
+ vmov d6, r0, r1 // move first param from r0/r1 pair into d6
+ vmov d7, r2, r3 // move second param from r2/r3 pair into d7
+ vdiv.f64 d5, d6, d7
+ vmov r0, r1, d5 // move result back to r0/r1 pair
+ bx lr
+END_COMPILERRT_FUNCTION(__divdf3vfp)
diff --git a/compiler-rt/lib/builtins/arm/divmodsi4.S b/compiler-rt/lib/builtins/arm/divmodsi4.S
new file mode 100644
index 00000000000..24e3657dd38
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/divmodsi4.S
@@ -0,0 +1,61 @@
+/*===-- divmodsi4.S - 32-bit signed integer divide and modulus ------------===//
+ *
+ * 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.
+ *
+ *===----------------------------------------------------------------------===//
+ *
+ * This file implements the __divmodsi4 (32-bit signed integer divide and
+ * modulus) function for the ARM architecture. A naive digit-by-digit
+ * computation is employed for simplicity.
+ *
+ *===----------------------------------------------------------------------===*/
+
+#include "../assembly.h"
+
+#define ESTABLISH_FRAME \
+ push {r4-r7, lr} ;\
+ add r7, sp, #12
+#define CLEAR_FRAME_AND_RETURN \
+ pop {r4-r7, pc}
+
+.syntax unified
+.align 3
+DEFINE_COMPILERRT_FUNCTION(__divmodsi4)
+#if __ARM_ARCH_EXT_IDIV__
+ tst r1, r1
+ beq LOCAL_LABEL(divzero)
+ mov r3, r0
+ sdiv r0, r3, r1
+ mls r1, r0, r1, r3
+ str r1, [r2]
+ bx lr
+LOCAL_LABEL(divzero):
+ mov r0, #0
+ bx lr
+#else
+ ESTABLISH_FRAME
+// Set aside the sign of the quotient and modulus, and the address for the
+// modulus.
+ eor r4, r0, r1
+ mov r5, r0
+ mov r6, r2
+// Take the absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
+ eor ip, r0, r0, asr #31
+ eor lr, r1, r1, asr #31
+ sub r0, ip, r0, asr #31
+ sub r1, lr, r1, asr #31
+// Unsigned divmod:
+ bl SYMBOL_NAME(__udivmodsi4)
+// Apply the sign of quotient and modulus
+ ldr r1, [r6]
+ eor r0, r0, r4, asr #31
+ eor r1, r1, r5, asr #31
+ sub r0, r0, r4, asr #31
+ sub r1, r1, r5, asr #31
+ str r1, [r6]
+ CLEAR_FRAME_AND_RETURN
+#endif
+END_COMPILERRT_FUNCTION(__divmodsi4)
diff --git a/compiler-rt/lib/builtins/arm/divsf3vfp.S b/compiler-rt/lib/builtins/arm/divsf3vfp.S
new file mode 100644
index 00000000000..a4e2f814867
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/divsf3vfp.S
@@ -0,0 +1,26 @@
+//===-- divsf3vfp.S - Implement divsf3vfp ---------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern float __divsf3vfp(float a, float b);
+//
+// Divides two single precision floating point numbers using the Darwin
+// calling convention where single arguments are passsed like 32-bit ints.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__divsf3vfp)
+ vmov s14, r0 // move first param from r0 into float register
+ vmov s15, r1 // move second param from r1 into float register
+ vdiv.f32 s13, s14, s15
+ vmov r0, s13 // move result back to r0
+ bx lr
+END_COMPILERRT_FUNCTION(__divsf3vfp)
diff --git a/compiler-rt/lib/builtins/arm/divsi3.S b/compiler-rt/lib/builtins/arm/divsi3.S
new file mode 100644
index 00000000000..76b67935265
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/divsi3.S
@@ -0,0 +1,52 @@
+/*===-- divsi3.S - 32-bit signed integer divide ---------------------------===//
+ *
+ * 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.
+ *
+ *===----------------------------------------------------------------------===//
+ *
+ * This file implements the __divsi3 (32-bit signed integer divide) function
+ * for the ARM architecture as a wrapper around the unsigned routine.
+ *
+ *===----------------------------------------------------------------------===*/
+
+#include "../assembly.h"
+
+#define ESTABLISH_FRAME \
+ push {r4, r7, lr} ;\
+ add r7, sp, #4
+#define CLEAR_FRAME_AND_RETURN \
+ pop {r4, r7, pc}
+
+.syntax unified
+.align 3
+// Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine.
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_idiv, __divsi3)
+DEFINE_COMPILERRT_FUNCTION(__divsi3)
+#if __ARM_ARCH_EXT_IDIV__
+ tst r1,r1
+ beq LOCAL_LABEL(divzero)
+ sdiv r0, r0, r1
+ bx lr
+LOCAL_LABEL(divzero):
+ mov r0,#0
+ bx lr
+#else
+ESTABLISH_FRAME
+// Set aside the sign of the quotient.
+ eor r4, r0, r1
+// Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
+ eor r2, r0, r0, asr #31
+ eor r3, r1, r1, asr #31
+ sub r0, r2, r0, asr #31
+ sub r1, r3, r1, asr #31
+// abs(a) / abs(b)
+ bl SYMBOL_NAME(__udivsi3)
+// Apply sign of quotient to result and return.
+ eor r0, r0, r4, asr #31
+ sub r0, r0, r4, asr #31
+ CLEAR_FRAME_AND_RETURN
+#endif
+END_COMPILERRT_FUNCTION(__divsi3)
diff --git a/compiler-rt/lib/builtins/arm/eqdf2vfp.S b/compiler-rt/lib/builtins/arm/eqdf2vfp.S
new file mode 100644
index 00000000000..198d42278e0
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/eqdf2vfp.S
@@ -0,0 +1,29 @@
+//===-- eqdf2vfp.S - Implement eqdf2vfp -----------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern int __eqdf2vfp(double a, double b);
+//
+// Returns one iff a == b and neither is NaN.
+// Uses Darwin calling convention where double precision arguments are passsed
+// like in GPR pairs.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__eqdf2vfp)
+ vmov d6, r0, r1 // load r0/r1 pair in double register
+ vmov d7, r2, r3 // load r2/r3 pair in double register
+ vcmp.f64 d6, d7
+ vmrs apsr_nzcv, fpscr
+ moveq r0, #1 // set result register to 1 if equal
+ movne r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__eqdf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/eqsf2vfp.S b/compiler-rt/lib/builtins/arm/eqsf2vfp.S
new file mode 100644
index 00000000000..395187f47bf
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/eqsf2vfp.S
@@ -0,0 +1,29 @@
+//===-- eqsf2vfp.S - Implement eqsf2vfp -----------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern int __eqsf2vfp(float a, float b);
+//
+// Returns one iff a == b and neither is NaN.
+// Uses Darwin calling convention where single precision arguments are passsed
+// like 32-bit ints
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__eqsf2vfp)
+ vmov s14, r0 // move from GPR 0 to float register
+ vmov s15, r1 // move from GPR 1 to float register
+ vcmp.f32 s14, s15
+ vmrs apsr_nzcv, fpscr
+ moveq r0, #1 // set result register to 1 if equal
+ movne r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__eqsf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/extendsfdf2vfp.S b/compiler-rt/lib/builtins/arm/extendsfdf2vfp.S
new file mode 100644
index 00000000000..ba31f3e0c5b
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/extendsfdf2vfp.S
@@ -0,0 +1,26 @@
+//===-- extendsfdf2vfp.S - Implement extendsfdf2vfp -----------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern double __extendsfdf2vfp(float a);
+//
+// Converts single precision float to double precision result.
+// Uses Darwin calling convention where a single precision parameter is
+// passed in a GPR and a double precision result is returned in R0/R1 pair.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__extendsfdf2vfp)
+ vmov s15, r0 // load float register from R0
+ vcvt.f64.f32 d7, s15 // convert single to double
+ vmov r0, r1, d7 // return result in r0/r1 pair
+ bx lr
+END_COMPILERRT_FUNCTION(__extendsfdf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/fixdfsivfp.S b/compiler-rt/lib/builtins/arm/fixdfsivfp.S
new file mode 100644
index 00000000000..26adbe3899b
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/fixdfsivfp.S
@@ -0,0 +1,26 @@
+//===-- fixdfsivfp.S - Implement fixdfsivfp -----------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern int __fixdfsivfp(double a);
+//
+// Converts double precision float to a 32-bit int rounding towards zero.
+// Uses Darwin calling convention where a double precision parameter is
+// passed in GPR register pair.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__fixdfsivfp)
+ vmov d7, r0, r1 // load double register from R0/R1
+ vcvt.s32.f64 s15, d7 // convert double to 32-bit int into s15
+ vmov r0, s15 // move s15 to result register
+ bx lr
+END_COMPILERRT_FUNCTION(__fixdfsivfp)
diff --git a/compiler-rt/lib/builtins/arm/fixsfsivfp.S b/compiler-rt/lib/builtins/arm/fixsfsivfp.S
new file mode 100644
index 00000000000..c1e0dadb7b3
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/fixsfsivfp.S
@@ -0,0 +1,26 @@
+//===-- fixsfsivfp.S - Implement fixsfsivfp -----------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern int __fixsfsivfp(float a);
+//
+// Converts single precision float to a 32-bit int rounding towards zero.
+// Uses Darwin calling convention where a single precision parameter is
+// passed in a GPR..
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__fixsfsivfp)
+ vmov s15, r0 // load float register from R0
+ vcvt.s32.f32 s15, s15 // convert single to 32-bit int into s15
+ vmov r0, s15 // move s15 to result register
+ bx lr
+END_COMPILERRT_FUNCTION(__fixsfsivfp)
diff --git a/compiler-rt/lib/builtins/arm/fixunsdfsivfp.S b/compiler-rt/lib/builtins/arm/fixunsdfsivfp.S
new file mode 100644
index 00000000000..fb91da752e3
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/fixunsdfsivfp.S
@@ -0,0 +1,27 @@
+//===-- fixunsdfsivfp.S - Implement fixunsdfsivfp -------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern unsigned int __fixunsdfsivfp(double a);
+//
+// Converts double precision float to a 32-bit unsigned int rounding towards
+// zero. All negative values become zero.
+// Uses Darwin calling convention where a double precision parameter is
+// passed in GPR register pair.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__fixunsdfsivfp)
+ vmov d7, r0, r1 // load double register from R0/R1
+ vcvt.u32.f64 s15, d7 // convert double to 32-bit int into s15
+ vmov r0, s15 // move s15 to result register
+ bx lr
+END_COMPILERRT_FUNCTION(__fixunsdfsivfp)
diff --git a/compiler-rt/lib/builtins/arm/fixunssfsivfp.S b/compiler-rt/lib/builtins/arm/fixunssfsivfp.S
new file mode 100644
index 00000000000..f12dff61af5
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/fixunssfsivfp.S
@@ -0,0 +1,27 @@
+//===-- fixunssfsivfp.S - Implement fixunssfsivfp -------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern unsigned int __fixunssfsivfp(float a);
+//
+// Converts single precision float to a 32-bit unsigned int rounding towards
+// zero. All negative values become zero.
+// Uses Darwin calling convention where a single precision parameter is
+// passed in a GPR..
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__fixunssfsivfp)
+ vmov s15, r0 // load float register from R0
+ vcvt.u32.f32 s15, s15 // convert single to 32-bit unsigned into s15
+ vmov r0, s15 // move s15 to result register
+ bx lr
+END_COMPILERRT_FUNCTION(__fixunssfsivfp)
diff --git a/compiler-rt/lib/builtins/arm/floatsidfvfp.S b/compiler-rt/lib/builtins/arm/floatsidfvfp.S
new file mode 100644
index 00000000000..ab48933b971
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/floatsidfvfp.S
@@ -0,0 +1,26 @@
+//===-- floatsidfvfp.S - Implement floatsidfvfp ---------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern double __floatsidfvfp(int a);
+//
+// Converts a 32-bit int to a double precision float.
+// Uses Darwin calling convention where a double precision result is
+// return in GPR register pair.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__floatsidfvfp)
+ vmov s15, r0 // move int to float register s15
+ vcvt.f64.s32 d7, s15 // convert 32-bit int in s15 to double in d7
+ vmov r0, r1, d7 // move d7 to result register pair r0/r1
+ bx lr
+END_COMPILERRT_FUNCTION(__floatsidfvfp)
diff --git a/compiler-rt/lib/builtins/arm/floatsisfvfp.S b/compiler-rt/lib/builtins/arm/floatsisfvfp.S
new file mode 100644
index 00000000000..eb265e99025
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/floatsisfvfp.S
@@ -0,0 +1,26 @@
+//===-- floatsisfvfp.S - Implement floatsisfvfp ---------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern float __floatsisfvfp(int a);
+//
+// Converts single precision float to a 32-bit int rounding towards zero.
+// Uses Darwin calling convention where a single precision result is
+// return in a GPR..
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__floatsisfvfp)
+ vmov s15, r0 // move int to float register s15
+ vcvt.f32.s32 s15, s15 // convert 32-bit int in s15 to float in s15
+ vmov r0, s15 // move s15 to result register
+ bx lr
+END_COMPILERRT_FUNCTION(__floatsisfvfp)
diff --git a/compiler-rt/lib/builtins/arm/floatunssidfvfp.S b/compiler-rt/lib/builtins/arm/floatunssidfvfp.S
new file mode 100644
index 00000000000..96e2eb21e49
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/floatunssidfvfp.S
@@ -0,0 +1,26 @@
+//===-- floatunssidfvfp.S - Implement floatunssidfvfp ---------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern double __floatunssidfvfp(unsigned int a);
+//
+// Converts a 32-bit int to a double precision float.
+// Uses Darwin calling convention where a double precision result is
+// return in GPR register pair.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__floatunssidfvfp)
+ vmov s15, r0 // move int to float register s15
+ vcvt.f64.u32 d7, s15 // convert 32-bit int in s15 to double in d7
+ vmov r0, r1, d7 // move d7 to result register pair r0/r1
+ bx lr
+END_COMPILERRT_FUNCTION(__floatunssidfvfp)
diff --git a/compiler-rt/lib/builtins/arm/floatunssisfvfp.S b/compiler-rt/lib/builtins/arm/floatunssisfvfp.S
new file mode 100644
index 00000000000..05471c4a5ff
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/floatunssisfvfp.S
@@ -0,0 +1,26 @@
+//===-- floatunssisfvfp.S - Implement floatunssisfvfp ---------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern float __floatunssisfvfp(unsigned int a);
+//
+// Converts single precision float to a 32-bit int rounding towards zero.
+// Uses Darwin calling convention where a single precision result is
+// return in a GPR..
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__floatunssisfvfp)
+ vmov s15, r0 // move int to float register s15
+ vcvt.f32.u32 s15, s15 // convert 32-bit int in s15 to float in s15
+ vmov r0, s15 // move s15 to result register
+ bx lr
+END_COMPILERRT_FUNCTION(__floatunssisfvfp)
diff --git a/compiler-rt/lib/builtins/arm/gedf2vfp.S b/compiler-rt/lib/builtins/arm/gedf2vfp.S
new file mode 100644
index 00000000000..aa636aa1429
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/gedf2vfp.S
@@ -0,0 +1,29 @@
+//===-- gedf2vfp.S - Implement gedf2vfp -----------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern int __gedf2vfp(double a, double b);
+//
+// Returns one iff a >= b and neither is NaN.
+// Uses Darwin calling convention where double precision arguments are passsed
+// like in GPR pairs.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__gedf2vfp)
+ vmov d6, r0, r1 // load r0/r1 pair in double register
+ vmov d7, r2, r3 // load r2/r3 pair in double register
+ vcmp.f64 d6, d7
+ vmrs apsr_nzcv, fpscr
+ movge r0, #1 // set result register to 1 if greater than or equal
+ movlt r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__gedf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/gesf2vfp.S b/compiler-rt/lib/builtins/arm/gesf2vfp.S
new file mode 100644
index 00000000000..087ce15f1b0
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/gesf2vfp.S
@@ -0,0 +1,29 @@
+//===-- gesf2vfp.S - Implement gesf2vfp -----------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern int __gesf2vfp(float a, float b);
+//
+// Returns one iff a >= b and neither is NaN.
+// Uses Darwin calling convention where single precision arguments are passsed
+// like 32-bit ints
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__gesf2vfp)
+ vmov s14, r0 // move from GPR 0 to float register
+ vmov s15, r1 // move from GPR 1 to float register
+ vcmp.f32 s14, s15
+ vmrs apsr_nzcv, fpscr
+ movge r0, #1 // set result register to 1 if greater than or equal
+ movlt r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__gesf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/gtdf2vfp.S b/compiler-rt/lib/builtins/arm/gtdf2vfp.S
new file mode 100644
index 00000000000..230952a9f65
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/gtdf2vfp.S
@@ -0,0 +1,29 @@
+//===-- gtdf2vfp.S - Implement gtdf2vfp -----------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern double __gtdf2vfp(double a, double b);
+//
+// Returns one iff a > b and neither is NaN.
+// Uses Darwin calling convention where double precision arguments are passsed
+// like in GPR pairs.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__gtdf2vfp)
+ vmov d6, r0, r1 // load r0/r1 pair in double register
+ vmov d7, r2, r3 // load r2/r3 pair in double register
+ vcmp.f64 d6, d7
+ vmrs apsr_nzcv, fpscr
+ movgt r0, #1 // set result register to 1 if equal
+ movle r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__gtdf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/gtsf2vfp.S b/compiler-rt/lib/builtins/arm/gtsf2vfp.S
new file mode 100644
index 00000000000..c1f5db05325
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/gtsf2vfp.S
@@ -0,0 +1,29 @@
+//===-- gtsf2vfp.S - Implement gtsf2vfp -----------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern int __gtsf2vfp(float a, float b);
+//
+// Returns one iff a > b and neither is NaN.
+// Uses Darwin calling convention where single precision arguments are passsed
+// like 32-bit ints
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__gtsf2vfp)
+ vmov s14, r0 // move from GPR 0 to float register
+ vmov s15, r1 // move from GPR 1 to float register
+ vcmp.f32 s14, s15
+ vmrs apsr_nzcv, fpscr
+ movgt r0, #1 // set result register to 1 if equal
+ movle r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__gtsf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/ledf2vfp.S b/compiler-rt/lib/builtins/arm/ledf2vfp.S
new file mode 100644
index 00000000000..94980a2efd2
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/ledf2vfp.S
@@ -0,0 +1,29 @@
+//===-- ledf2vfp.S - Implement ledf2vfp -----------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern double __ledf2vfp(double a, double b);
+//
+// Returns one iff a <= b and neither is NaN.
+// Uses Darwin calling convention where double precision arguments are passsed
+// like in GPR pairs.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__ledf2vfp)
+ vmov d6, r0, r1 // load r0/r1 pair in double register
+ vmov d7, r2, r3 // load r2/r3 pair in double register
+ vcmp.f64 d6, d7
+ vmrs apsr_nzcv, fpscr
+ movls r0, #1 // set result register to 1 if equal
+ movhi r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__ledf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/lesf2vfp.S b/compiler-rt/lib/builtins/arm/lesf2vfp.S
new file mode 100644
index 00000000000..362352a83aa
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/lesf2vfp.S
@@ -0,0 +1,29 @@
+//===-- lesf2vfp.S - Implement lesf2vfp -----------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern int __lesf2vfp(float a, float b);
+//
+// Returns one iff a <= b and neither is NaN.
+// Uses Darwin calling convention where single precision arguments are passsed
+// like 32-bit ints
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__lesf2vfp)
+ vmov s14, r0 // move from GPR 0 to float register
+ vmov s15, r1 // move from GPR 1 to float register
+ vcmp.f32 s14, s15
+ vmrs apsr_nzcv, fpscr
+ movls r0, #1 // set result register to 1 if equal
+ movhi r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__lesf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/ltdf2vfp.S b/compiler-rt/lib/builtins/arm/ltdf2vfp.S
new file mode 100644
index 00000000000..391ff2924f0
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/ltdf2vfp.S
@@ -0,0 +1,29 @@
+//===-- ltdf2vfp.S - Implement ltdf2vfp -----------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern double __ltdf2vfp(double a, double b);
+//
+// Returns one iff a < b and neither is NaN.
+// Uses Darwin calling convention where double precision arguments are passsed
+// like in GPR pairs.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__ltdf2vfp)
+ vmov d6, r0, r1 // load r0/r1 pair in double register
+ vmov d7, r2, r3 // load r2/r3 pair in double register
+ vcmp.f64 d6, d7
+ vmrs apsr_nzcv, fpscr
+ movmi r0, #1 // set result register to 1 if equal
+ movpl r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__ltdf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/ltsf2vfp.S b/compiler-rt/lib/builtins/arm/ltsf2vfp.S
new file mode 100644
index 00000000000..dcaa03561ff
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/ltsf2vfp.S
@@ -0,0 +1,29 @@
+//===-- ltsf2vfp.S - Implement ltsf2vfp -----------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern int __ltsf2vfp(float a, float b);
+//
+// Returns one iff a < b and neither is NaN.
+// Uses Darwin calling convention where single precision arguments are passsed
+// like 32-bit ints
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__ltsf2vfp)
+ vmov s14, r0 // move from GPR 0 to float register
+ vmov s15, r1 // move from GPR 1 to float register
+ vcmp.f32 s14, s15
+ vmrs apsr_nzcv, fpscr
+ movmi r0, #1 // set result register to 1 if equal
+ movpl r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__ltsf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/modsi3.S b/compiler-rt/lib/builtins/arm/modsi3.S
new file mode 100644
index 00000000000..07c5f9381ec
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/modsi3.S
@@ -0,0 +1,51 @@
+/*===-- modsi3.S - 32-bit signed integer modulus --------------------------===//
+ *
+ * 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.
+ *
+ *===----------------------------------------------------------------------===//
+ *
+ * This file implements the __modsi3 (32-bit signed integer modulus) function
+ * for the ARM architecture as a wrapper around the unsigned routine.
+ *
+ *===----------------------------------------------------------------------===*/
+
+#include "../assembly.h"
+
+#define ESTABLISH_FRAME \
+ push {r4, r7, lr} ;\
+ add r7, sp, #4
+#define CLEAR_FRAME_AND_RETURN \
+ pop {r4, r7, pc}
+
+.syntax unified
+.align 3
+DEFINE_COMPILERRT_FUNCTION(__modsi3)
+#if __ARM_ARCH_EXT_IDIV__
+ tst r1, r1
+ beq LOCAL_LABEL(divzero)
+ sdiv r2, r0, r1
+ mls r0, r2, r1, r0
+ bx lr
+LOCAL_LABEL(divzero):
+ mov r0, #0
+ bx lr
+#else
+ ESTABLISH_FRAME
+ // Set aside the sign of the dividend.
+ mov r4, r0
+ // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
+ eor r2, r0, r0, asr #31
+ eor r3, r1, r1, asr #31
+ sub r0, r2, r0, asr #31
+ sub r1, r3, r1, asr #31
+ // abs(a) % abs(b)
+ bl SYMBOL_NAME(__umodsi3)
+ // Apply sign of dividend to result and return.
+ eor r0, r0, r4, asr #31
+ sub r0, r0, r4, asr #31
+ CLEAR_FRAME_AND_RETURN
+#endif
+END_COMPILERRT_FUNCTION(__modsi3)
diff --git a/compiler-rt/lib/builtins/arm/muldf3vfp.S b/compiler-rt/lib/builtins/arm/muldf3vfp.S
new file mode 100644
index 00000000000..2c1d7037728
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/muldf3vfp.S
@@ -0,0 +1,26 @@
+//===-- muldf3vfp.S - Implement muldf3vfp ---------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern double __muldf3vfp(double a, double b);
+//
+// Multiplies two double precision floating point numbers using the Darwin
+// calling convention where double arguments are passsed in GPR pairs
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__muldf3vfp)
+ vmov d6, r0, r1 // move first param from r0/r1 pair into d6
+ vmov d7, r2, r3 // move second param from r2/r3 pair into d7
+ vmul.f64 d6, d6, d7
+ vmov r0, r1, d6 // move result back to r0/r1 pair
+ bx lr
+END_COMPILERRT_FUNCTION(__muldf3vfp)
diff --git a/compiler-rt/lib/builtins/arm/mulsf3vfp.S b/compiler-rt/lib/builtins/arm/mulsf3vfp.S
new file mode 100644
index 00000000000..98af81d2364
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/mulsf3vfp.S
@@ -0,0 +1,26 @@
+//===-- mulsf3vfp.S - Implement mulsf3vfp ---------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern float __mulsf3vfp(float a, float b);
+//
+// Multiplies two single precision floating point numbers using the Darwin
+// calling convention where single arguments are passsed like 32-bit ints.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__mulsf3vfp)
+ vmov s14, r0 // move first param from r0 into float register
+ vmov s15, r1 // move second param from r1 into float register
+ vmul.f32 s13, s14, s15
+ vmov r0, s13 // move result back to r0
+ bx lr
+END_COMPILERRT_FUNCTION(__mulsf3vfp)
diff --git a/compiler-rt/lib/builtins/arm/nedf2vfp.S b/compiler-rt/lib/builtins/arm/nedf2vfp.S
new file mode 100644
index 00000000000..c1a832e1a61
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/nedf2vfp.S
@@ -0,0 +1,29 @@
+//===-- nedf2vfp.S - Implement nedf2vfp -----------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern double __nedf2vfp(double a, double b);
+//
+// Returns zero if a and b are unequal and neither is NaN.
+// Uses Darwin calling convention where double precision arguments are passsed
+// like in GPR pairs.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__nedf2vfp)
+ vmov d6, r0, r1 // load r0/r1 pair in double register
+ vmov d7, r2, r3 // load r2/r3 pair in double register
+ vcmp.f64 d6, d7
+ vmrs apsr_nzcv, fpscr
+ movne r0, #1 // set result register to 0 if unequal
+ moveq r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__nedf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/negdf2vfp.S b/compiler-rt/lib/builtins/arm/negdf2vfp.S
new file mode 100644
index 00000000000..ad9b8741807
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/negdf2vfp.S
@@ -0,0 +1,23 @@
+//===-- negdf2vfp.S - Implement negdf2vfp ---------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern double __negdf2vfp(double a, double b);
+//
+// Returns the negation a double precision floating point numbers using the
+// Darwin calling convention where double arguments are passsed in GPR pairs.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__negdf2vfp)
+ eor r1, r1, #-2147483648 // flip sign bit on double in r0/r1 pair
+ bx lr
+END_COMPILERRT_FUNCTION(__negdf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/negsf2vfp.S b/compiler-rt/lib/builtins/arm/negsf2vfp.S
new file mode 100644
index 00000000000..482eb264070
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/negsf2vfp.S
@@ -0,0 +1,23 @@
+//===-- negsf2vfp.S - Implement negsf2vfp ---------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern float __negsf2vfp(float a);
+//
+// Returns the negation of a single precision floating point numbers using the
+// Darwin calling convention where single arguments are passsed like 32-bit ints
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__negsf2vfp)
+ eor r0, r0, #-2147483648 // flip sign bit on float in r0
+ bx lr
+END_COMPILERRT_FUNCTION(__negsf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/nesf2vfp.S b/compiler-rt/lib/builtins/arm/nesf2vfp.S
new file mode 100644
index 00000000000..127145ec42e
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/nesf2vfp.S
@@ -0,0 +1,29 @@
+//===-- nesf2vfp.S - Implement nesf2vfp -----------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern int __nesf2vfp(float a, float b);
+//
+// Returns one iff a != b and neither is NaN.
+// Uses Darwin calling convention where single precision arguments are passsed
+// like 32-bit ints
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__nesf2vfp)
+ vmov s14, r0 // move from GPR 0 to float register
+ vmov s15, r1 // move from GPR 1 to float register
+ vcmp.f32 s14, s15
+ vmrs apsr_nzcv, fpscr
+ movne r0, #1 // set result register to 1 if unequal
+ moveq r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__nesf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/restore_vfp_d8_d15_regs.S b/compiler-rt/lib/builtins/arm/restore_vfp_d8_d15_regs.S
new file mode 100644
index 00000000000..5d55474158a
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/restore_vfp_d8_d15_regs.S
@@ -0,0 +1,35 @@
+//===-- save_restore_regs.S - Implement save/restore* ---------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// When compiling C++ functions that need to handle thrown exceptions the
+// compiler is required to save all registers and call __Unwind_SjLj_Register
+// in the function prolog. But when compiling for thumb1, there are
+// no instructions to access the floating point registers, so the
+// compiler needs to add a call to the helper function _save_vfp_d8_d15_regs
+// written in ARM to save the float registers. In the epilog, the compiler
+// must also add a call to __restore_vfp_d8_d15_regs to restore those registers.
+//
+
+ .text
+ .syntax unified
+
+//
+// Restore registers d8-d15 from stack
+//
+ .align 2
+DEFINE_COMPILERRT_PRIVATE_FUNCTION(__restore_vfp_d8_d15_regs)
+ vldmia sp!, {d8-d15} // pop registers d8-d15 off stack
+ bx lr // return to prolog
+END_COMPILERRT_FUNCTION(__restore_vfp_d8_d15_regs)
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
diff --git a/compiler-rt/lib/builtins/arm/save_vfp_d8_d15_regs.S b/compiler-rt/lib/builtins/arm/save_vfp_d8_d15_regs.S
new file mode 100644
index 00000000000..4be3ff3a525
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/save_vfp_d8_d15_regs.S
@@ -0,0 +1,35 @@
+//===-- save_restore_regs.S - Implement save/restore* ---------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// When compiling C++ functions that need to handle thrown exceptions the
+// compiler is required to save all registers and call __Unwind_SjLj_Register
+// in the function prolog. But when compiling for thumb1, there are
+// no instructions to access the floating point registers, so the
+// compiler needs to add a call to the helper function _save_vfp_d8_d15_regs
+// written in ARM to save the float registers. In the epilog, the compiler
+// must also add a call to __restore_vfp_d8_d15_regs to restore those registers.
+//
+
+ .text
+ .syntax unified
+
+//
+// Save registers d8-d15 onto stack
+//
+ .align 2
+DEFINE_COMPILERRT_PRIVATE_FUNCTION(__save_vfp_d8_d15_regs)
+ vstmdb sp!, {d8-d15} // push registers d8-d15 onto stack
+ bx lr // return to prolog
+END_COMPILERRT_FUNCTION(__save_vfp_d8_d15_regs)
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
diff --git a/compiler-rt/lib/builtins/arm/softfloat-alias.list b/compiler-rt/lib/builtins/arm/softfloat-alias.list
new file mode 100644
index 00000000000..cc6a4b3cdd2
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/softfloat-alias.list
@@ -0,0 +1,21 @@
+#
+# These are soft float functions which can be
+# aliased to the *vfp functions on arm processors
+# that support floating point instructions.
+#
+___adddf3vfp ___adddf3
+___addsf3vfp ___addsf3
+___divdf3vfp ___divdf3
+___divsf3vfp ___divsf3
+___extendsfdf2vfp ___extendsfdf2
+___fixdfsivfp ___fixdfsi
+___fixsfsivfp ___fixsfsi
+___floatsidfvfp ___floatsidf
+___floatsisfvfp ___floatsisf
+___muldf3vfp ___muldf3
+___mulsf3vfp ___mulsf3
+___subdf3vfp ___subdf3
+___subsf3vfp ___subsf3
+___truncdfsf2vfp ___truncdfsf2
+___floatunssidfvfp ___floatunsidf
+___floatunssisfvfp ___floatunsisf
diff --git a/compiler-rt/lib/builtins/arm/subdf3vfp.S b/compiler-rt/lib/builtins/arm/subdf3vfp.S
new file mode 100644
index 00000000000..747d6596cdd
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/subdf3vfp.S
@@ -0,0 +1,26 @@
+//===-- subdf3vfp.S - Implement subdf3vfp ---------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern double __subdf3vfp(double a, double b);
+//
+// Returns difference between two double precision floating point numbers using
+// the Darwin calling convention where double arguments are passsed in GPR pairs
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__subdf3vfp)
+ vmov d6, r0, r1 // move first param from r0/r1 pair into d6
+ vmov d7, r2, r3 // move second param from r2/r3 pair into d7
+ vsub.f64 d6, d6, d7
+ vmov r0, r1, d6 // move result back to r0/r1 pair
+ bx lr
+END_COMPILERRT_FUNCTION(__subdf3vfp)
diff --git a/compiler-rt/lib/builtins/arm/subsf3vfp.S b/compiler-rt/lib/builtins/arm/subsf3vfp.S
new file mode 100644
index 00000000000..7cc63cccc31
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/subsf3vfp.S
@@ -0,0 +1,27 @@
+//===-- subsf3vfp.S - Implement subsf3vfp ---------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern float __subsf3vfp(float a, float b);
+//
+// Returns the difference between two single precision floating point numbers
+// using the Darwin calling convention where single arguments are passsed
+// like 32-bit ints.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__subsf3vfp)
+ vmov s14, r0 // move first param from r0 into float register
+ vmov s15, r1 // move second param from r1 into float register
+ vsub.f32 s14, s14, s15
+ vmov r0, s14 // move result back to r0
+ bx lr
+END_COMPILERRT_FUNCTION(__subsf3vfp)
diff --git a/compiler-rt/lib/builtins/arm/switch16.S b/compiler-rt/lib/builtins/arm/switch16.S
new file mode 100644
index 00000000000..0dedc598a13
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/switch16.S
@@ -0,0 +1,46 @@
+//===-- switch.S - Implement switch* --------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// When compiling switch statements in thumb mode, the compiler
+// can use these __switch* helper functions The compiler emits a blx to
+// the __switch* function followed by a table of displacements for each
+// case statement. On entry, R0 is the index into the table. The __switch*
+// function uses the return address in lr to find the start of the table.
+// The first entry in the table is the count of the entries in the table.
+// It then uses R0 to index into the table and get the displacement of the
+// address to jump to. If R0 is greater than the size of the table, it jumps
+// to the last entry in the table. Each displacement in the table is actually
+// the distance from lr to the label, thus making the tables PIC.
+
+
+ .text
+ .syntax unified
+
+//
+// The table contains signed 2-byte sized elements which are 1/2 the distance
+// from lr to the target label.
+//
+ .align 2
+DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch16)
+ ldrh ip, [lr, #-1] // get first 16-bit word in table
+ cmp r0, ip // compare with index
+ add r0, lr, r0, lsl #1 // compute address of element in table
+ add ip, lr, ip, lsl #1 // compute address of last element in table
+ ite lo
+ ldrshlo r0, [r0, #1] // load 16-bit element if r0 is in range
+ ldrshhs r0, [ip, #1] // load 16-bit element if r0 out of range
+ add ip, lr, r0, lsl #1 // compute label = lr + element*2
+ bx ip // jump to computed label
+END_COMPILERRT_FUNCTION(__switch16)
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
diff --git a/compiler-rt/lib/builtins/arm/switch32.S b/compiler-rt/lib/builtins/arm/switch32.S
new file mode 100644
index 00000000000..64d558eb8fa
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/switch32.S
@@ -0,0 +1,47 @@
+//===-- switch.S - Implement switch* --------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// When compiling switch statements in thumb mode, the compiler
+// can use these __switch* helper functions The compiler emits a blx to
+// the __switch* function followed by a table of displacements for each
+// case statement. On entry, R0 is the index into the table. The __switch*
+// function uses the return address in lr to find the start of the table.
+// The first entry in the table is the count of the entries in the table.
+// It then uses R0 to index into the table and get the displacement of the
+// address to jump to. If R0 is greater than the size of the table, it jumps
+// to the last entry in the table. Each displacement in the table is actually
+// the distance from lr to the label, thus making the tables PIC.
+
+
+ .text
+ .syntax unified
+
+//
+// The table contains signed 4-byte sized elements which are the distance
+// from lr to the target label.
+//
+ .align 2
+DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch32)
+ ldr ip, [lr, #-1] // get first 32-bit word in table
+ cmp r0, ip // compare with index
+ add r0, lr, r0, lsl #2 // compute address of element in table
+ add ip, lr, ip, lsl #2 // compute address of last element in table
+ ite lo
+ ldrlo r0, [r0, #3] // load 32-bit element if r0 is in range
+ ldrhs r0, [ip, #3] // load 32-bit element if r0 out of range
+ add ip, lr, r0 // compute label = lr + element
+ bx ip // jump to computed label
+END_COMPILERRT_FUNCTION(__switch32)
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
+
diff --git a/compiler-rt/lib/builtins/arm/switch8.S b/compiler-rt/lib/builtins/arm/switch8.S
new file mode 100644
index 00000000000..b5008849a30
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/switch8.S
@@ -0,0 +1,45 @@
+//===-- switch.S - Implement switch* --------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// When compiling switch statements in thumb mode, the compiler
+// can use these __switch* helper functions The compiler emits a blx to
+// the __switch* function followed by a table of displacements for each
+// case statement. On entry, R0 is the index into the table. The __switch*
+// function uses the return address in lr to find the start of the table.
+// The first entry in the table is the count of the entries in the table.
+// It then uses R0 to index into the table and get the displacement of the
+// address to jump to. If R0 is greater than the size of the table, it jumps
+// to the last entry in the table. Each displacement in the table is actually
+// the distance from lr to the label, thus making the tables PIC.
+
+
+ .text
+ .syntax unified
+
+//
+// The table contains signed byte sized elements which are 1/2 the distance
+// from lr to the target label.
+//
+ .align 2
+DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch8)
+ ldrb ip, [lr, #-1] // get first byte in table
+ cmp r0, ip // signed compare with index
+ ite lo
+ ldrsblo r0, [lr, r0] // get indexed byte out of table
+ ldrsbhs r0, [lr, ip] // if out of range, use last entry in table
+ add ip, lr, r0, lsl #1 // compute label = lr + element*2
+ bx ip // jump to computed label
+END_COMPILERRT_FUNCTION(__switch8)
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
+
diff --git a/compiler-rt/lib/builtins/arm/switchu8.S b/compiler-rt/lib/builtins/arm/switchu8.S
new file mode 100644
index 00000000000..488d4e74eed
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/switchu8.S
@@ -0,0 +1,45 @@
+//===-- switch.S - Implement switch* --------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// When compiling switch statements in thumb mode, the compiler
+// can use these __switch* helper functions The compiler emits a blx to
+// the __switch* function followed by a table of displacements for each
+// case statement. On entry, R0 is the index into the table. The __switch*
+// function uses the return address in lr to find the start of the table.
+// The first entry in the table is the count of the entries in the table.
+// It then uses R0 to index into the table and get the displacement of the
+// address to jump to. If R0 is greater than the size of the table, it jumps
+// to the last entry in the table. Each displacement in the table is actually
+// the distance from lr to the label, thus making the tables PIC.
+
+
+ .text
+ .syntax unified
+
+//
+// The table contains unsigned byte sized elements which are 1/2 the distance
+// from lr to the target label.
+//
+ .align 2
+DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switchu8)
+ ldrb ip, [lr, #-1] // get first byte in table
+ cmp r0, ip // compare with index
+ ite lo
+ ldrblo r0, [lr, r0] // get indexed byte out of table
+ ldrbhs r0, [lr, ip] // if out of range, use last entry in table
+ add ip, lr, r0, lsl #1 // compute label = lr + element*2
+ bx ip // jump to computed label
+END_COMPILERRT_FUNCTION(__switchu8)
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
+
diff --git a/compiler-rt/lib/builtins/arm/sync_synchronize.S b/compiler-rt/lib/builtins/arm/sync_synchronize.S
new file mode 100644
index 00000000000..aa18f04fb5f
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/sync_synchronize.S
@@ -0,0 +1,35 @@
+//===-- sync_synchronize - Implement memory barrier * ----------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// When compiling a use of the gcc built-in __sync_synchronize() in thumb1 mode
+// the compiler may emit a call to __sync_synchronize.
+// On Darwin the implementation jumps to an OS supplied function named
+// OSMemoryBarrier
+//
+
+ .text
+ .syntax unified
+
+#if __APPLE__
+
+ .align 2
+DEFINE_COMPILERRT_PRIVATE_FUNCTION(__sync_synchronize)
+ stmfd sp!, {r7, lr}
+ add r7, sp, #0
+ bl _OSMemoryBarrier
+ ldmfd sp!, {r7, pc}
+END_COMPILERRT_FUNCTION(__sync_synchronize)
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
+
+#endif
diff --git a/compiler-rt/lib/builtins/arm/truncdfsf2vfp.S b/compiler-rt/lib/builtins/arm/truncdfsf2vfp.S
new file mode 100644
index 00000000000..55bf324ccc4
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/truncdfsf2vfp.S
@@ -0,0 +1,26 @@
+//===-- truncdfsf2vfp.S - Implement truncdfsf2vfp -------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern float __truncdfsf2vfp(double a);
+//
+// Converts double precision float to signle precision result.
+// Uses Darwin calling convention where a double precision parameter is
+// passed in a R0/R1 pair and a signle precision result is returned in R0.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__truncdfsf2vfp)
+ vmov d7, r0, r1 // load double from r0/r1 pair
+ vcvt.f32.f64 s15, d7 // convert double to single (trucate precision)
+ vmov r0, s15 // return result in r0
+ bx lr
+END_COMPILERRT_FUNCTION(__truncdfsf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/udivmodsi4.S b/compiler-rt/lib/builtins/arm/udivmodsi4.S
new file mode 100644
index 00000000000..bb5d29c03e6
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/udivmodsi4.S
@@ -0,0 +1,161 @@
+/*===-- udivmodsi4.S - 32-bit unsigned integer divide and modulus ---------===//
+ *
+ * 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.
+ *
+ *===----------------------------------------------------------------------===//
+ *
+ * This file implements the __udivmodsi4 (32-bit unsigned integer divide and
+ * modulus) function for the ARM 32-bit architecture.
+ *
+ *===----------------------------------------------------------------------===*/
+
+#include "../assembly.h"
+
+ .syntax unified
+
+ .text
+ .p2align 2
+DEFINE_COMPILERRT_FUNCTION(__udivmodsi4)
+#if __ARM_ARCH_EXT_IDIV__
+ tst r1, r1
+ beq LOCAL_LABEL(divby0)
+ mov r3, r0
+ udiv r0, r3, r1
+ mls r1, r0, r1, r3
+ str r1, [r2]
+ bx lr
+#else
+ cmp r1, #1
+ bcc LOCAL_LABEL(divby0)
+ beq LOCAL_LABEL(divby1)
+ cmp r0, r1
+ bcc LOCAL_LABEL(quotient0)
+ /*
+ * Implement division using binary long division algorithm.
+ *
+ * r0 is the numerator, r1 the denominator.
+ *
+ * The code before JMP computes the correct shift I, so that
+ * r0 and (r1 << I) have the highest bit set in the same position.
+ * At the time of JMP, ip := .Ldiv0block - 12 * I.
+ * This depends on the fixed instruction size of block.
+ *
+ * block(shift) implements the test-and-update-quotient core.
+ * It assumes (r0 << shift) can be computed without overflow and
+ * that (r0 << shift) < 2 * r1. The quotient is stored in r3.
+ */
+
+# ifdef __ARM_FEATURE_CLZ
+ clz ip, r0
+ clz r3, r1
+ /* r0 >= r1 implies clz(r0) <= clz(r1), so ip <= r3. */
+ sub r3, r3, ip
+ adr ip, LOCAL_LABEL(div0block)
+ sub ip, ip, r3, lsl #2
+ sub ip, ip, r3, lsl #3
+ mov r3, #0
+ bx ip
+# else
+ str r4, [sp, #-8]!
+
+ mov r4, r0
+ adr ip, LOCAL_LABEL(div0block)
+
+ lsr r3, r4, #16
+ cmp r3, r1
+ movhs r4, r3
+ subhs ip, ip, #(16 * 12)
+
+ lsr r3, r4, #8
+ cmp r3, r1
+ movhs r4, r3
+ subhs ip, ip, #(8 * 12)
+
+ lsr r3, r4, #4
+ cmp r3, r1
+ movhs r4, r3
+ subhs ip, #(4 * 12)
+
+ lsr r3, r4, #2
+ cmp r3, r1
+ movhs r4, r3
+ subhs ip, ip, #(2 * 12)
+
+ /* Last block, no need to update r3 or r4. */
+ cmp r1, r4, lsr #1
+ subls ip, ip, #(1 * 12)
+
+ ldr r4, [sp], #8 /* restore r4, we are done with it. */
+ mov r3, #0
+
+ JMP(ip)
+# endif
+
+#define IMM #
+
+#define block(shift) \
+ cmp r0, r1, lsl IMM shift; \
+ addhs r3, r3, IMM (1 << shift); \
+ subhs r0, r0, r1, lsl IMM shift
+
+ block(31)
+ block(30)
+ block(29)
+ block(28)
+ block(27)
+ block(26)
+ block(25)
+ block(24)
+ block(23)
+ block(22)
+ block(21)
+ block(20)
+ block(19)
+ block(18)
+ block(17)
+ block(16)
+ block(15)
+ block(14)
+ block(13)
+ block(12)
+ block(11)
+ block(10)
+ block(9)
+ block(8)
+ block(7)
+ block(6)
+ block(5)
+ block(4)
+ block(3)
+ block(2)
+ block(1)
+LOCAL_LABEL(div0block):
+ block(0)
+
+ str r0, [r2]
+ mov r0, r3
+ JMP(lr)
+
+LOCAL_LABEL(quotient0):
+ str r0, [r2]
+ mov r0, #0
+ JMP(lr)
+
+LOCAL_LABEL(divby1):
+ mov r3, #0
+ str r3, [r2]
+ JMP(lr)
+#endif /* __ARM_ARCH_EXT_IDIV__ */
+
+LOCAL_LABEL(divby0):
+ mov r0, #0
+#ifdef __ARM_EABI__
+ b __aeabi_idiv0
+#else
+ JMP(lr)
+#endif
+
+END_COMPILERRT_FUNCTION(__udivmodsi4)
diff --git a/compiler-rt/lib/builtins/arm/udivsi3.S b/compiler-rt/lib/builtins/arm/udivsi3.S
new file mode 100644
index 00000000000..11c1c096ec1
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/udivsi3.S
@@ -0,0 +1,148 @@
+/*===-- udivsi3.S - 32-bit unsigned integer divide ------------------------===//
+ *
+ * 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.
+ *
+ *===----------------------------------------------------------------------===//
+ *
+ * This file implements the __udivsi3 (32-bit unsigned integer divide)
+ * function for the ARM 32-bit architecture.
+ *
+ *===----------------------------------------------------------------------===*/
+
+#include "../assembly.h"
+
+ .syntax unified
+
+ .text
+ .p2align 2
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_uidiv, __udivsi3)
+DEFINE_COMPILERRT_FUNCTION(__udivsi3)
+#if __ARM_ARCH_EXT_IDIV__
+ tst r1, r1
+ beq LOCAL_LABEL(divby0)
+ mov r3, r0
+ udiv r0, r3, r1
+ mls r1, r0, r1, r3
+ bx lr
+#else
+ cmp r1, #1
+ bcc LOCAL_LABEL(divby0)
+ JMPc(lr, eq)
+ cmp r0, r1
+ movcc r0, #0
+ JMPc(lr, cc)
+ /*
+ * Implement division using binary long division algorithm.
+ *
+ * r0 is the numerator, r1 the denominator.
+ *
+ * The code before JMP computes the correct shift I, so that
+ * r0 and (r1 << I) have the highest bit set in the same position.
+ * At the time of JMP, ip := .Ldiv0block - 12 * I.
+ * This depends on the fixed instruction size of block.
+ *
+ * block(shift) implements the test-and-update-quotient core.
+ * It assumes (r0 << shift) can be computed without overflow and
+ * that (r0 << shift) < 2 * r1. The quotient is stored in r3.
+ */
+
+# ifdef __ARM_FEATURE_CLZ
+ clz ip, r0
+ clz r3, r1
+ /* r0 >= r1 implies clz(r0) <= clz(r1), so ip <= r3. */
+ sub r3, r3, ip
+ adr ip, LOCAL_LABEL(div0block)
+ sub ip, ip, r3, lsl #2
+ sub ip, ip, r3, lsl #3
+ mov r3, #0
+ bx ip
+# else
+ mov r2, r0
+ adr ip, LOCAL_LABEL(div0block)
+
+ lsr r3, r2, #16
+ cmp r3, r1
+ movhs r2, r3
+ subhs ip, ip, #(16 * 12)
+
+ lsr r3, r2, #8
+ cmp r3, r1
+ movhs r2, r3
+ subhs ip, ip, #(8 * 12)
+
+ lsr r3, r2, #4
+ cmp r3, r1
+ movhs r2, r3
+ subhs ip, #(4 * 12)
+
+ lsr r3, r2, #2
+ cmp r3, r1
+ movhs r2, r3
+ subhs ip, ip, #(2 * 12)
+
+ /* Last block, no need to update r2 or r3. */
+ cmp r1, r2, lsr #1
+ subls ip, ip, #(1 * 12)
+
+ mov r3, #0
+
+ JMP(ip)
+# endif
+
+#define IMM #
+
+#define block(shift) \
+ cmp r0, r1, lsl IMM shift; \
+ addhs r3, r3, IMM (1 << shift); \
+ subhs r0, r0, r1, lsl IMM shift
+
+ block(31)
+ block(30)
+ block(29)
+ block(28)
+ block(27)
+ block(26)
+ block(25)
+ block(24)
+ block(23)
+ block(22)
+ block(21)
+ block(20)
+ block(19)
+ block(18)
+ block(17)
+ block(16)
+ block(15)
+ block(14)
+ block(13)
+ block(12)
+ block(11)
+ block(10)
+ block(9)
+ block(8)
+ block(7)
+ block(6)
+ block(5)
+ block(4)
+ block(3)
+ block(2)
+ block(1)
+LOCAL_LABEL(div0block):
+ block(0)
+
+ mov r0, r3
+ JMP(lr)
+#endif /* __ARM_ARCH_EXT_IDIV__ */
+
+LOCAL_LABEL(divby0):
+ mov r0, #0
+#ifdef __ARM_EABI__
+ b __aeabi_idiv0
+#else
+ JMP(lr)
+#endif
+
+END_COMPILERRT_FUNCTION(__udivsi3)
diff --git a/compiler-rt/lib/builtins/arm/umodsi3.S b/compiler-rt/lib/builtins/arm/umodsi3.S
new file mode 100644
index 00000000000..a03afefdaa2
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/umodsi3.S
@@ -0,0 +1,141 @@
+/*===-- umodsi3.S - 32-bit unsigned integer modulus -----------------------===//
+ *
+ * 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.
+ *
+ *===----------------------------------------------------------------------===//
+ *
+ * This file implements the __umodsi3 (32-bit unsigned integer modulus)
+ * function for the ARM 32-bit architecture.
+ *
+ *===----------------------------------------------------------------------===*/
+
+#include "../assembly.h"
+
+ .syntax unified
+
+ .text
+ .p2align 2
+DEFINE_COMPILERRT_FUNCTION(__umodsi3)
+#if __ARM_ARCH_EXT_IDIV__
+ tst r1, r1
+ beq LOCAL_LABEL(divby0)
+ mov r3, r0
+ udiv r0, r3, r1
+ mls r1, r0, r1, r3
+ str r1, [r2]
+ bx lr
+#else
+ cmp r1, #1
+ bcc LOCAL_LABEL(divby0)
+ moveq r0, #0
+ JMPc(lr, eq)
+ cmp r0, r1
+ JMPc(lr, cc)
+ /*
+ * Implement division using binary long division algorithm.
+ *
+ * r0 is the numerator, r1 the denominator.
+ *
+ * The code before JMP computes the correct shift I, so that
+ * r0 and (r1 << I) have the highest bit set in the same position.
+ * At the time of JMP, ip := .Ldiv0block - 8 * I.
+ * This depends on the fixed instruction size of block.
+ *
+ * block(shift) implements the test-and-update-quotient core.
+ * It assumes (r0 << shift) can be computed without overflow and
+ * that (r0 << shift) < 2 * r1. The quotient is stored in r3.
+ */
+
+# ifdef __ARM_FEATURE_CLZ
+ clz ip, r0
+ clz r3, r1
+ /* r0 >= r1 implies clz(r0) <= clz(r1), so ip <= r3. */
+ sub r3, r3, ip
+ adr ip, LOCAL_LABEL(div0block)
+ sub ip, ip, r3, lsl #3
+ bx ip
+# else
+ mov r2, r0
+ adr ip, LOCAL_LABEL(div0block)
+
+ lsr r3, r2, #16
+ cmp r3, r1
+ movhs r2, r3
+ subhs ip, ip, #(16 * 8)
+
+ lsr r3, r2, #8
+ cmp r3, r1
+ movhs r2, r3
+ subhs ip, ip, #(8 * 8)
+
+ lsr r3, r2, #4
+ cmp r3, r1
+ movhs r2, r3
+ subhs ip, #(4 * 8)
+
+ lsr r3, r2, #2
+ cmp r3, r1
+ movhs r2, r3
+ subhs ip, ip, #(2 * 8)
+
+ /* Last block, no need to update r2 or r3. */
+ cmp r1, r2, lsr #1
+ subls ip, ip, #(1 * 8)
+
+ JMP(ip)
+# endif
+
+#define IMM #
+
+#define block(shift) \
+ cmp r0, r1, lsl IMM shift; \
+ subhs r0, r0, r1, lsl IMM shift
+
+ block(31)
+ block(30)
+ block(29)
+ block(28)
+ block(27)
+ block(26)
+ block(25)
+ block(24)
+ block(23)
+ block(22)
+ block(21)
+ block(20)
+ block(19)
+ block(18)
+ block(17)
+ block(16)
+ block(15)
+ block(14)
+ block(13)
+ block(12)
+ block(11)
+ block(10)
+ block(9)
+ block(8)
+ block(7)
+ block(6)
+ block(5)
+ block(4)
+ block(3)
+ block(2)
+ block(1)
+LOCAL_LABEL(div0block):
+ block(0)
+ JMP(lr)
+#endif /* __ARM_ARCH_EXT_IDIV__ */
+
+LOCAL_LABEL(divby0):
+ mov r0, #0
+#ifdef __ARM_EABI__
+ b __aeabi_idiv0
+#else
+ JMP(lr)
+#endif
+
+END_COMPILERRT_FUNCTION(__umodsi3)
diff --git a/compiler-rt/lib/builtins/arm/unorddf2vfp.S b/compiler-rt/lib/builtins/arm/unorddf2vfp.S
new file mode 100644
index 00000000000..ee7de402531
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/unorddf2vfp.S
@@ -0,0 +1,29 @@
+//===-- unorddf2vfp.S - Implement unorddf2vfp ------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern int __unorddf2vfp(double a, double b);
+//
+// Returns one iff a or b is NaN
+// Uses Darwin calling convention where double precision arguments are passsed
+// like in GPR pairs.
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__unorddf2vfp)
+ vmov d6, r0, r1 // load r0/r1 pair in double register
+ vmov d7, r2, r3 // load r2/r3 pair in double register
+ vcmp.f64 d6, d7
+ vmrs apsr_nzcv, fpscr
+ movvs r0, #1 // set result register to 1 if "overflow" (any NaNs)
+ movvc r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__unorddf2vfp)
diff --git a/compiler-rt/lib/builtins/arm/unordsf2vfp.S b/compiler-rt/lib/builtins/arm/unordsf2vfp.S
new file mode 100644
index 00000000000..eb419a54154
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/unordsf2vfp.S
@@ -0,0 +1,29 @@
+//===-- unordsf2vfp.S - Implement unordsf2vfp -----------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern int __unordsf2vfp(float a, float b);
+//
+// Returns one iff a or b is NaN
+// Uses Darwin calling convention where single precision arguments are passsed
+// like 32-bit ints
+//
+ .syntax unified
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__unordsf2vfp)
+ vmov s14, r0 // move from GPR 0 to float register
+ vmov s15, r1 // move from GPR 1 to float register
+ vcmp.f32 s14, s15
+ vmrs apsr_nzcv, fpscr
+ movvs r0, #1 // set result register to 1 if "overflow" (any NaNs)
+ movvc r0, #0
+ bx lr
+END_COMPILERRT_FUNCTION(__unordsf2vfp)
OpenPOWER on IntegriCloud