aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/CMakeLists.txt81
-rw-r--r--lib/Makefile.mk17
-rw-r--r--lib/absvdi2.c30
-rw-r--r--lib/absvsi2.c30
-rw-r--r--lib/absvti2.c34
-rw-r--r--lib/adddf3.c154
-rw-r--r--lib/addsf3.c164
-rw-r--r--lib/addvdi3.c37
-rw-r--r--lib/addvsi3.c37
-rw-r--r--lib/addvti3.c41
-rw-r--r--lib/apple_versioning.c150
-rw-r--r--lib/arm/CMakeLists.txt0
-rw-r--r--lib/arm/Makefile.mk19
-rw-r--r--lib/arm/adddf3vfp.S24
-rw-r--r--lib/arm/addsf3vfp.S24
-rw-r--r--lib/arm/bswapdi2.S36
-rw-r--r--lib/arm/bswapsi2.S28
-rw-r--r--lib/arm/comparesf2.S130
-rw-r--r--lib/arm/divdf3vfp.S24
-rw-r--r--lib/arm/divsf3vfp.S24
-rw-r--r--lib/arm/eqdf2vfp.S27
-rw-r--r--lib/arm/eqsf2vfp.S28
-rw-r--r--lib/arm/extendsfdf2vfp.S24
-rw-r--r--lib/arm/fixdfsivfp.S24
-rw-r--r--lib/arm/fixsfsivfp.S24
-rw-r--r--lib/arm/fixunsdfsivfp.S25
-rw-r--r--lib/arm/fixunssfsivfp.S25
-rw-r--r--lib/arm/floatsidfvfp.S24
-rw-r--r--lib/arm/floatsisfvfp.S24
-rw-r--r--lib/arm/floatunssidfvfp.S24
-rw-r--r--lib/arm/floatunssisfvfp.S24
-rw-r--r--lib/arm/gedf2vfp.S27
-rw-r--r--lib/arm/gesf2vfp.S28
-rw-r--r--lib/arm/gtdf2vfp.S27
-rw-r--r--lib/arm/gtsf2vfp.S28
-rw-r--r--lib/arm/ledf2vfp.S27
-rw-r--r--lib/arm/lesf2vfp.S28
-rw-r--r--lib/arm/ltdf2vfp.S27
-rw-r--r--lib/arm/ltsf2vfp.S28
-rw-r--r--lib/arm/modsi3.S36
-rw-r--r--lib/arm/muldf3vfp.S24
-rw-r--r--lib/arm/mulsf3vfp.S24
-rw-r--r--lib/arm/nedf2vfp.S27
-rw-r--r--lib/arm/negdf2vfp.S21
-rw-r--r--lib/arm/negsf2vfp.S21
-rw-r--r--lib/arm/nesf2vfp.S28
-rw-r--r--lib/arm/restore_vfp_d8_d15_regs.S37
-rw-r--r--lib/arm/save_vfp_d8_d15_regs.S35
-rw-r--r--lib/arm/subdf3vfp.S24
-rw-r--r--lib/arm/subsf3vfp.S25
-rw-r--r--lib/arm/switch16.S44
-rw-r--r--lib/arm/switch32.S46
-rw-r--r--lib/arm/switch8.S43
-rw-r--r--lib/arm/switchu8.S43
-rw-r--r--lib/arm/sync_synchronize.S34
-rw-r--r--lib/arm/truncdfsf2vfp.S24
-rw-r--r--lib/arm/unorddf2vfp.S27
-rw-r--r--lib/arm/unordsf2vfp.S28
-rw-r--r--lib/ashldi3.c41
-rw-r--r--lib/ashlti3.c45
-rw-r--r--lib/ashrdi3.c42
-rw-r--r--lib/ashrti3.c46
-rw-r--r--lib/assembly.h54
-rw-r--r--lib/clear_cache.c40
-rw-r--r--lib/clzdi2.c29
-rw-r--r--lib/clzsi2.c53
-rw-r--r--lib/clzti2.c33
-rw-r--r--lib/cmpdi2.c38
-rw-r--r--lib/cmpti2.c42
-rw-r--r--lib/comparedf2.c132
-rw-r--r--lib/comparesf2.c131
-rw-r--r--lib/ctzdi2.c29
-rw-r--r--lib/ctzsi2.c57
-rw-r--r--lib/ctzti2.c33
-rw-r--r--lib/divdc3.c59
-rw-r--r--lib/divdf3.c182
-rw-r--r--lib/divdi3.c31
-rw-r--r--lib/divsc3.c59
-rw-r--r--lib/divsf3.c166
-rw-r--r--lib/divsi3.c31
-rw-r--r--lib/divti3.c35
-rw-r--r--lib/divxc3.c62
-rw-r--r--lib/enable_execute_stack.c58
-rw-r--r--lib/endianness.h94
-rw-r--r--lib/eprintf.c33
-rw-r--r--lib/extendsfdf2.c136
-rw-r--r--lib/ffsdi2.c33
-rw-r--r--lib/ffsti2.c37
-rw-r--r--lib/fixdfdi.c43
-rw-r--r--lib/fixdfsi.c45
-rw-r--r--lib/fixdfti.c45
-rw-r--r--lib/fixsfdi.c41
-rw-r--r--lib/fixsfsi.c45
-rw-r--r--lib/fixsfti.c45
-rw-r--r--lib/fixunsdfdi.c45
-rw-r--r--lib/fixunsdfsi.c42
-rw-r--r--lib/fixunsdfti.c47
-rw-r--r--lib/fixunssfdi.c43
-rw-r--r--lib/fixunssfsi.c43
-rw-r--r--lib/fixunssfti.c47
-rw-r--r--lib/fixunsxfdi.c44
-rw-r--r--lib/fixunsxfsi.c44
-rw-r--r--lib/fixunsxfti.c49
-rw-r--r--lib/fixxfdi.c44
-rw-r--r--lib/fixxfti.c47
-rw-r--r--lib/floatdidf.c107
-rw-r--r--lib/floatdisf.c79
-rw-r--r--lib/floatdixf.c46
-rw-r--r--lib/floatsidf.c48
-rw-r--r--lib/floatsisf.c54
-rw-r--r--lib/floattidf.c86
-rw-r--r--lib/floattisf.c85
-rw-r--r--lib/floattixf.c87
-rw-r--r--lib/floatundidf.c107
-rw-r--r--lib/floatundisf.c76
-rw-r--r--lib/floatundixf.c42
-rw-r--r--lib/floatunsidf.c37
-rw-r--r--lib/floatunsisf.c45
-rw-r--r--lib/floatuntidf.c83
-rw-r--r--lib/floatuntisf.c82
-rw-r--r--lib/floatuntixf.c84
-rw-r--r--lib/fp_lib.h143
-rw-r--r--lib/gcc_personality_v0.c251
-rw-r--r--lib/i386/CMakeLists.txt3
-rw-r--r--lib/i386/Makefile.mk19
-rw-r--r--lib/i386/ashldi3.S56
-rw-r--r--lib/i386/ashrdi3.S67
-rw-r--r--lib/i386/divdi3.S161
-rw-r--r--lib/i386/floatdidf.S35
-rw-r--r--lib/i386/floatdisf.S31
-rw-r--r--lib/i386/floatdixf.S29
-rw-r--r--lib/i386/floatundidf.S46
-rw-r--r--lib/i386/floatundisf.S99
-rw-r--r--lib/i386/floatundixf.S37
-rw-r--r--lib/i386/lshrdi3.S57
-rw-r--r--lib/i386/moddi3.S166
-rw-r--r--lib/i386/muldi3.S29
-rw-r--r--lib/i386/udivdi3.S114
-rw-r--r--lib/i386/umoddi3.S125
-rw-r--r--lib/int_lib.h155
-rw-r--r--lib/lshrdi3.c41
-rw-r--r--lib/lshrti3.c45
-rw-r--r--lib/moddi3.c32
-rw-r--r--lib/modsi3.c23
-rw-r--r--lib/modti3.c36
-rw-r--r--lib/muldc3.c74
-rw-r--r--lib/muldf3.c119
-rw-r--r--lib/muldi3.c54
-rw-r--r--lib/mulsc3.c74
-rw-r--r--lib/mulsf3.c109
-rw-r--r--lib/multi3.c58
-rw-r--r--lib/mulvdi3.c57
-rw-r--r--lib/mulvsi3.c57
-rw-r--r--lib/mulvti3.c61
-rw-r--r--lib/mulxc3.c78
-rw-r--r--lib/negdf2.c19
-rw-r--r--lib/negdi2.c26
-rw-r--r--lib/negsf2.c19
-rw-r--r--lib/negti2.c30
-rw-r--r--lib/negvdi2.c29
-rw-r--r--lib/negvsi2.c29
-rw-r--r--lib/negvti2.c33
-rw-r--r--lib/paritydi2.c27
-rw-r--r--lib/paritysi2.c27
-rw-r--r--lib/parityti2.c31
-rw-r--r--lib/popcountdi2.c36
-rw-r--r--lib/popcountsi2.c33
-rw-r--r--lib/popcountti2.c44
-rw-r--r--lib/powidf2.c34
-rw-r--r--lib/powisf2.c34
-rw-r--r--lib/powitf2.c38
-rw-r--r--lib/powixf2.c38
-rw-r--r--lib/ppc/CMakeLists.txt12
-rw-r--r--lib/ppc/DD.h46
-rw-r--r--lib/ppc/Makefile.mk19
-rw-r--r--lib/ppc/divtc3.c93
-rw-r--r--lib/ppc/fixtfdi.c104
-rw-r--r--lib/ppc/fixunstfdi.c60
-rw-r--r--lib/ppc/floatditf.c37
-rw-r--r--lib/ppc/floatunditf.c42
-rw-r--r--lib/ppc/gcc_qadd.c76
-rw-r--r--lib/ppc/gcc_qdiv.c55
-rw-r--r--lib/ppc/gcc_qmul.c53
-rw-r--r--lib/ppc/gcc_qsub.c76
-rw-r--r--lib/ppc/multc3.c97
-rw-r--r--lib/ppc/restFP.S43
-rw-r--r--lib/ppc/saveFP.S40
-rw-r--r--lib/subvdi3.c37
-rw-r--r--lib/subvsi3.c37
-rw-r--r--lib/subvti3.c41
-rw-r--r--lib/trampoline_setup.c50
-rw-r--r--lib/truncdfsf2.c167
-rw-r--r--lib/ucmpdi2.c38
-rw-r--r--lib/ucmpti2.c42
-rw-r--r--lib/udivdi3.c25
-rw-r--r--lib/udivmoddi4.c251
-rw-r--r--lib/udivmodti4.c256
-rw-r--r--lib/udivsi3.c63
-rw-r--r--lib/udivti3.c29
-rw-r--r--lib/umoddi3.c27
-rw-r--r--lib/umodsi3.c25
-rw-r--r--lib/umodti3.c31
-rw-r--r--lib/x86_64/CMakeLists.txt5
-rw-r--r--lib/x86_64/Makefile.mk19
-rw-r--r--lib/x86_64/floatdidf.c16
-rw-r--r--lib/x86_64/floatdisf.c14
-rw-r--r--lib/x86_64/floatdixf.c16
-rw-r--r--lib/x86_64/floatundidf.S43
-rw-r--r--lib/x86_64/floatundisf.S33
-rw-r--r--lib/x86_64/floatundixf.S62
210 files changed, 11184 insertions, 0 deletions
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
new file mode 100644
index 000000000000..e29474a1da6d
--- /dev/null
+++ b/lib/CMakeLists.txt
@@ -0,0 +1,81 @@
+#
+# Create a library called "CompilerRT" which includes the source files.
+
+#INCLUDE_DIRECTORIES(
+# ${CMAKE_CURRENT_BINARY_DIR}
+#)
+
+# Generic functions needed for each architecture
+# libcompiler_rt.Generic.a libcompiler_rt.Optimized.a
+
+# Generic
+SET( Generic_SRCS
+ absvdi2.c absvsi2.c addvdi3.c addvsi3.c ashldi3.c ashrdi3.c
+ clzdi2.c clzsi2.c cmpdi2.c ctzdi2.c ctzsi2.c
+ divdc3.c divdi3.c divsc3.c ffsdi2.c
+ fixdfdi.c fixsfdi.c fixunsdfdi.c fixunsdfsi.c fixunssfdi.c
+ fixunssfsi.c floatdidf.c floatdisf.c floatundidf.c floatundisf.c
+ gcc_personality_v0.c lshrdi3.c moddi3.c muldc3.c muldi3.c
+ mulsc3.c mulvdi3.c mulvsi3.c negdi2.c negvdi2.c negvsi2.c
+ paritydi2.c paritysi2.c popcountdi2.c popcountsi2.c powidf2.c
+ powisf2.c subvdi3.c subvsi3.c ucmpdi2.c udivdi3.c
+ udivmoddi4.c umoddi3.c apple_versioning.c eprintf.c
+ )
+
+# Optimized functions for each architecture
+
+# Commenting out for the min until the basics are working first.
+# ADD_SUBDIRECTORY( ppc )
+# ADD_SUBDIRECTORY( x86_64 )
+# ADD_SUBDIRECTORY( i386 )
+# ADD_SUBDIRECTORY( arm )
+
+# List of functions needed for each architecture.
+SET( i386_Functions
+ divxc3.c fixunsxfdi.c fixunsxfsi.c fixxfdi.c floatdixf.c
+ floatundixf.c mulxc3.c powixf2.c clear_cache.c enable_execute_stack.c
+ )
+
+SET( x86_64_Functions
+ absvti2.c addvti3.c ashlti3.c ashrti3.c clzti2.c cmpti2.c
+ ctzti2.c divti3.c divxc3.c ffsti2.c fixdfti.c fixsfti.c
+ fixunsdfti.c fixunssfti.c fixunsxfdi.c fixunsxfsi.c
+ fixunsxfti.c fixxfdi.c fixxfti.c floatdixf.c floattidf.c
+ floattisf.c floattixf.c floatundixf.c floatuntidf.c
+ floatuntisf.c floatuntixf.c lshrti3.c modti3.c multi3.c
+ mulvti3.c mulxc3.c negti2.c negvti2.c parityti2.c
+ popcountti2.c powixf2.c subvti3.c ucmpti2.c udivmodti4.c
+ udivti3.c umodti3.c clear_cache.c enable_execute_stack.c
+ )
+
+SET( PPC_Functions
+ divtc3.c fixtfdi.c fixunstfdi.c floatditf.c floatunditf.c
+ gcc_qadd.c gcc_qdiv.c gcc_qmul.c gcc_qsub.c multc3.c
+ powitf2.c restFP.c saveFP.c trampoline_setup.c
+ clear_cache.c enable_execute_stack.c
+ )
+
+SET( ARM_Functions
+ adddf3vfp.c addsf3vfp.c bswapdi2.c bswapsi2.c divdf3vfp.c
+ divsf3vfp.c eqdf2vfp.c eqsf2vfp.c extendsfdf2vfp.c
+ fixdfsivfp.c fixsfsivfp.c fixunsdfsivfp.c fixunssfsivfp.c
+ floatsidfvfp.c floatsisfvfp.c floatunssidfvfp.c floatunssisfvfp.c
+ gedf2vfp.c gesf2vfp.c gtdf2vfp.c gtsf2vfp.c
+ ledf2vfp.c lesf2vfp.c ltdf2vfp.c ltsf2vfp.c
+ muldf3vfp.c mulsf3vfp.c
+ nedf2vfp.c negdf2vfp.c negsf2vfp.c nesf2vfp.c
+ subdf3vfp.c subsf3vfp.c truncdfsf2vfp.c unorddf2vfp.c unordsf2vfp.c
+ modsi3.c umodsi3.c udivsi3.c divsi3.c switch.c
+ )
+
+#FOREACH( LOOP_VAR ${Achitectures} )
+# See ARCHIVE_OUTPUT_DIRECTORY docs.
+#${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${LOOP_VAR}
+#ENDFOREACH
+
+ADD_LIBRARY( ${PROJECT_NAME}-Generic STATIC ${Generic_SRCS} )
+#ADD_LIBRARY( ${PROJECT_NAME}-i386 STATIC ${i386_Functions} )
+
+# [[debug|optimized|general]
+#TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${PROJECT_NAME}-Common optimized ${PROJECT_NAME}-i386 )
+
diff --git a/lib/Makefile.mk b/lib/Makefile.mk
new file mode 100644
index 000000000000..1ed8c11a08ba
--- /dev/null
+++ b/lib/Makefile.mk
@@ -0,0 +1,17 @@
+#===- lib/Makefile.mk --------------------------------------*- Makefile -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+SubDirs := i386 ppc x86_64 arm
+
+Sources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))
+ObjNames := $(Sources:%.c=%.o)
+Implementation := Generic
+
+# FIXME: use automatic dependencies?
+Dependencies := $(wildcard $(Dir)/*.h)
diff --git a/lib/absvdi2.c b/lib/absvdi2.c
new file mode 100644
index 000000000000..919afd1351d3
--- /dev/null
+++ b/lib/absvdi2.c
@@ -0,0 +1,30 @@
+/*===-- absvdi2.c - Implement __absvdi2 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ *===----------------------------------------------------------------------===
+ *
+ * This file implements __absvdi2 for the compiler_rt library.
+ *
+ *===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: absolute value */
+
+/* Effects: aborts if abs(x) < 0 */
+
+di_int
+__absvdi2(di_int a)
+{
+ const int N = (int)(sizeof(di_int) * CHAR_BIT);
+ if (a == ((di_int)1 << (N-1)))
+ compilerrt_abort();
+ const di_int t = a >> (N - 1);
+ return (a ^ t) - t;
+}
diff --git a/lib/absvsi2.c b/lib/absvsi2.c
new file mode 100644
index 000000000000..a2c8e3f19052
--- /dev/null
+++ b/lib/absvsi2.c
@@ -0,0 +1,30 @@
+/* ===-- absvsi2.c - Implement __absvsi2 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __absvsi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: absolute value */
+
+/* Effects: aborts if abs(x) < 0 */
+
+si_int
+__absvsi2(si_int a)
+{
+ const int N = (int)(sizeof(si_int) * CHAR_BIT);
+ if (a == (1 << (N-1)))
+ compilerrt_abort();
+ const si_int t = a >> (N - 1);
+ return (a ^ t) - t;
+}
diff --git a/lib/absvti2.c b/lib/absvti2.c
new file mode 100644
index 000000000000..0978122dceef
--- /dev/null
+++ b/lib/absvti2.c
@@ -0,0 +1,34 @@
+/* ===-- absvti2.c - Implement __absvdi2 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __absvti2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: absolute value */
+
+/* Effects: aborts if abs(x) < 0 */
+
+ti_int
+__absvti2(ti_int a)
+{
+ const int N = (int)(sizeof(ti_int) * CHAR_BIT);
+ if (a == ((ti_int)1 << (N-1)))
+ compilerrt_abort();
+ const ti_int s = a >> (N - 1);
+ return (a ^ s) - s;
+}
+
+#endif
diff --git a/lib/adddf3.c b/lib/adddf3.c
new file mode 100644
index 000000000000..1ec43dcf58e2
--- /dev/null
+++ b/lib/adddf3.c
@@ -0,0 +1,154 @@
+//===-- lib/adddf3.c - Double-precision addition and subtraction --*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements double-precision soft-float addition and subtraction
+// with the IEEE-754 default rounding (to nearest, ties to even).
+//
+//===----------------------------------------------------------------------===//
+
+#define DOUBLE_PRECISION
+#include "fp_lib.h"
+
+fp_t __adddf3(fp_t a, fp_t b) {
+
+ rep_t aRep = toRep(a);
+ rep_t bRep = toRep(b);
+ const rep_t aAbs = aRep & absMask;
+ const rep_t bAbs = bRep & absMask;
+
+ // Detect if a or b is zero, infinity, or NaN.
+ if (aAbs - 1U >= infRep - 1U || bAbs - 1U >= infRep - 1U) {
+
+ // NaN + anything = qNaN
+ if (aAbs > infRep) return fromRep(toRep(a) | quietBit);
+ // anything + NaN = qNaN
+ if (bAbs > infRep) return fromRep(toRep(b) | quietBit);
+
+ if (aAbs == infRep) {
+ // +/-infinity + -/+infinity = qNaN
+ if ((toRep(a) ^ toRep(b)) == signBit) return fromRep(qnanRep);
+ // +/-infinity + anything remaining = +/- infinity
+ else return a;
+ }
+
+ // anything remaining + +/-infinity = +/-infinity
+ if (bAbs == infRep) return b;
+
+ // zero + anything = anything
+ if (!aAbs) {
+ // but we need to get the sign right for zero + zero
+ if (!bAbs) return fromRep(toRep(a) & toRep(b));
+ else return b;
+ }
+
+ // anything + zero = anything
+ if (!bAbs) return a;
+ }
+
+ // Swap a and b if necessary so that a has the larger absolute value.
+ if (bAbs > aAbs) {
+ const rep_t temp = aRep;
+ aRep = bRep;
+ bRep = temp;
+ }
+
+ // Extract the exponent and significand from the (possibly swapped) a and b.
+ int aExponent = aRep >> significandBits & maxExponent;
+ int bExponent = bRep >> significandBits & maxExponent;
+ rep_t aSignificand = aRep & significandMask;
+ rep_t bSignificand = bRep & significandMask;
+
+ // Normalize any denormals, and adjust the exponent accordingly.
+ if (aExponent == 0) aExponent = normalize(&aSignificand);
+ if (bExponent == 0) bExponent = normalize(&bSignificand);
+
+ // The sign of the result is the sign of the larger operand, a. If they
+ // have opposite signs, we are performing a subtraction; otherwise addition.
+ const rep_t resultSign = aRep & signBit;
+ const bool subtraction = (aRep ^ bRep) & signBit;
+
+ // Shift the significands to give us round, guard and sticky, and or in the
+ // implicit significand bit. (If we fell through from the denormal path it
+ // was already set by normalize( ), but setting it twice won't hurt
+ // anything.)
+ aSignificand = (aSignificand | implicitBit) << 3;
+ bSignificand = (bSignificand | implicitBit) << 3;
+
+ // Shift the significand of b by the difference in exponents, with a sticky
+ // bottom bit to get rounding correct.
+ const int align = aExponent - bExponent;
+ if (align) {
+ if (align < typeWidth) {
+ const bool sticky = bSignificand << (typeWidth - align);
+ bSignificand = bSignificand >> align | sticky;
+ } else {
+ bSignificand = 1; // sticky; b is known to be non-zero.
+ }
+ }
+
+ if (subtraction) {
+ aSignificand -= bSignificand;
+
+ // If a == -b, return +zero.
+ if (aSignificand == 0) return fromRep(0);
+
+ // If partial cancellation occured, we need to left-shift the result
+ // and adjust the exponent:
+ if (aSignificand < implicitBit << 3) {
+ const int shift = rep_clz(aSignificand) - rep_clz(implicitBit << 3);
+ aSignificand <<= shift;
+ aExponent -= shift;
+ }
+ }
+
+ else /* addition */ {
+ aSignificand += bSignificand;
+
+ // If the addition carried up, we need to right-shift the result and
+ // adjust the exponent:
+ if (aSignificand & implicitBit << 4) {
+ const bool sticky = aSignificand & 1;
+ aSignificand = aSignificand >> 1 | sticky;
+ aExponent += 1;
+ }
+ }
+
+ // If we have overflowed the type, return +/- infinity:
+ if (aExponent >= maxExponent) return fromRep(infRep | resultSign);
+
+ if (aExponent <= 0) {
+ // Result is denormal before rounding; the exponent is zero and we
+ // need to shift the significand.
+ const int shift = 1 - aExponent;
+ const bool sticky = aSignificand << (typeWidth - shift);
+ aSignificand = aSignificand >> shift | sticky;
+ aExponent = 0;
+ }
+
+ // Low three bits are round, guard, and sticky.
+ const int roundGuardSticky = aSignificand & 0x7;
+
+ // Shift the significand into place, and mask off the implicit bit.
+ rep_t result = aSignificand >> 3 & significandMask;
+
+ // Insert the exponent and sign.
+ result |= (rep_t)aExponent << significandBits;
+ result |= resultSign;
+
+ // Final rounding. The result may overflow to infinity, but that is the
+ // correct result in that case.
+ if (roundGuardSticky > 0x4) result++;
+ if (roundGuardSticky == 0x4) result += result & 1;
+ return fromRep(result);
+}
+
+// Subtraction; flip the sign bit of b and add.
+fp_t __subdf3(fp_t a, fp_t b) {
+ return __adddf3(a, fromRep(toRep(b) ^ signBit));
+}
diff --git a/lib/addsf3.c b/lib/addsf3.c
new file mode 100644
index 000000000000..fec14e838518
--- /dev/null
+++ b/lib/addsf3.c
@@ -0,0 +1,164 @@
+//===-- lib/addsf3.c - Single-precision addition and subtraction --*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements single-precision soft-float addition and subtraction
+// with the IEEE-754 default rounding (to nearest, ties to even).
+//
+//===----------------------------------------------------------------------===//
+
+#define SINGLE_PRECISION
+#include "fp_lib.h"
+
+fp_t __addsf3(fp_t a, fp_t b) {
+
+ rep_t aRep = toRep(a);
+ rep_t bRep = toRep(b);
+ const rep_t aAbs = aRep & absMask;
+ const rep_t bAbs = bRep & absMask;
+
+ // Detect if a or b is zero, infinity, or NaN.
+ if (aAbs - 1U >= infRep - 1U || bAbs - 1U >= infRep - 1U) {
+
+ // NaN + anything = qNaN
+ if (aAbs > infRep) return fromRep(toRep(a) | quietBit);
+ // anything + NaN = qNaN
+ if (bAbs > infRep) return fromRep(toRep(b) | quietBit);
+
+ if (aAbs == infRep) {
+ // +/-infinity + -/+infinity = qNaN
+ if ((toRep(a) ^ toRep(b)) == signBit) return fromRep(qnanRep);
+ // +/-infinity + anything remaining = +/- infinity
+ else return a;
+ }
+
+ // anything remaining + +/-infinity = +/-infinity
+ if (bAbs == infRep) return b;
+
+ // zero + anything = anything
+ if (!aAbs) {
+ // but we need to get the sign right for zero + zero
+ if (!bAbs) return fromRep(toRep(a) & toRep(b));
+ else return b;
+ }
+
+ // anything + zero = anything
+ if (!bAbs) return a;
+ }
+
+ // Swap a and b if necessary so that a has the larger absolute value.
+ if (bAbs > aAbs) {
+ const rep_t temp = aRep;
+ aRep = bRep;
+ bRep = temp;
+ }
+
+ // Extract the exponent and significand from the (possibly swapped) a and b.
+ int aExponent = aRep >> significandBits & maxExponent;
+ int bExponent = bRep >> significandBits & maxExponent;
+ rep_t aSignificand = aRep & significandMask;
+ rep_t bSignificand = bRep & significandMask;
+
+ // Normalize any denormals, and adjust the exponent accordingly.
+ if (aExponent == 0) aExponent = normalize(&aSignificand);
+ if (bExponent == 0) bExponent = normalize(&bSignificand);
+
+ // The sign of the result is the sign of the larger operand, a. If they
+ // have opposite signs, we are performing a subtraction; otherwise addition.
+ const rep_t resultSign = aRep & signBit;
+ const bool subtraction = (aRep ^ bRep) & signBit;
+
+ // Shift the significands to give us round, guard and sticky, and or in the
+ // implicit significand bit. (If we fell through from the denormal path it
+ // was already set by normalize( ), but setting it twice won't hurt
+ // anything.)
+ aSignificand = (aSignificand | implicitBit) << 3;
+ bSignificand = (bSignificand | implicitBit) << 3;
+
+ // Shift the significand of b by the difference in exponents, with a sticky
+ // bottom bit to get rounding correct.
+ const int align = aExponent - bExponent;
+ if (align) {
+ if (align < typeWidth) {
+ const bool sticky = bSignificand << (typeWidth - align);
+ bSignificand = bSignificand >> align | sticky;
+ } else {
+ bSignificand = 1; // sticky; b is known to be non-zero.
+ }
+ }
+
+ if (subtraction) {
+ aSignificand -= bSignificand;
+
+ // If a == -b, return +zero.
+ if (aSignificand == 0) return fromRep(0);
+
+ // If partial cancellation occured, we need to left-shift the result
+ // and adjust the exponent:
+ if (aSignificand < implicitBit << 3) {
+ const int shift = rep_clz(aSignificand) - rep_clz(implicitBit << 3);
+ aSignificand <<= shift;
+ aExponent -= shift;
+ }
+ }
+
+ else /* addition */ {
+ aSignificand += bSignificand;
+
+ // If the addition carried up, we need to right-shift the result and
+ // adjust the exponent:
+ if (aSignificand & implicitBit << 4) {
+ const bool sticky = aSignificand & 1;
+ aSignificand = aSignificand >> 1 | sticky;
+ aExponent += 1;
+ }
+ }
+
+ // If we have overflowed the type, return +/- infinity:
+ if (aExponent >= maxExponent) return fromRep(infRep | resultSign);
+
+ if (aExponent <= 0) {
+ // Result is denormal before rounding; the exponent is zero and we
+ // need to shift the significand.
+ const int shift = 1 - aExponent;
+ const bool sticky = aSignificand << (typeWidth - shift);
+ aSignificand = aSignificand >> shift | sticky;
+ aExponent = 0;
+ }
+
+ // Low three bits are round, guard, and sticky.
+ const int roundGuardSticky = aSignificand & 0x7;
+
+ // Shift the significand into place, and mask off the implicit bit.
+ rep_t result = aSignificand >> 3 & significandMask;
+
+ // Insert the exponent and sign.
+ result |= (rep_t)aExponent << significandBits;
+ result |= resultSign;
+
+ // Final rounding. The result may overflow to infinity, but that is the
+ // correct result in that case.
+ if (roundGuardSticky > 0x4) result++;
+ if (roundGuardSticky == 0x4) result += result & 1;
+ return fromRep(result);
+}
+
+// Subtraction; flip the sign bit of b and add.
+fp_t __subsf3(fp_t a, fp_t b) {
+ return __addsf3(a, fromRep(toRep(b) ^ signBit));
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/addvdi3.c b/lib/addvdi3.c
new file mode 100644
index 000000000000..53ab1024bd6f
--- /dev/null
+++ b/lib/addvdi3.c
@@ -0,0 +1,37 @@
+/* ===-- addvdi3.c - Implement __addvdi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __addvdi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: a + b */
+
+/* Effects: aborts if a + b overflows */
+
+di_int
+__addvdi3(di_int a, di_int b)
+{
+ di_int s = a + b;
+ if (b >= 0)
+ {
+ if (s < a)
+ compilerrt_abort();
+ }
+ else
+ {
+ if (s >= a)
+ compilerrt_abort();
+ }
+ return s;
+}
diff --git a/lib/addvsi3.c b/lib/addvsi3.c
new file mode 100644
index 000000000000..22cd3154ce6c
--- /dev/null
+++ b/lib/addvsi3.c
@@ -0,0 +1,37 @@
+/* ===-- addvsi3.c - Implement __addvsi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __addvsi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: a + b */
+
+/* Effects: aborts if a + b overflows */
+
+si_int
+__addvsi3(si_int a, si_int b)
+{
+ si_int s = a + b;
+ if (b >= 0)
+ {
+ if (s < a)
+ compilerrt_abort();
+ }
+ else
+ {
+ if (s >= a)
+ compilerrt_abort();
+ }
+ return s;
+}
diff --git a/lib/addvti3.c b/lib/addvti3.c
new file mode 100644
index 000000000000..3df1a742ce33
--- /dev/null
+++ b/lib/addvti3.c
@@ -0,0 +1,41 @@
+/* ===-- addvti3.c - Implement __addvti3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __addvti3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: a + b */
+
+/* Effects: aborts if a + b overflows */
+
+ti_int
+__addvti3(ti_int a, ti_int b)
+{
+ ti_int s = a + b;
+ if (b >= 0)
+ {
+ if (s < a)
+ compilerrt_abort();
+ }
+ else
+ {
+ if (s >= a)
+ compilerrt_abort();
+ }
+ return s;
+}
+
+#endif
diff --git a/lib/apple_versioning.c b/lib/apple_versioning.c
new file mode 100644
index 000000000000..0360026bceed
--- /dev/null
+++ b/lib/apple_versioning.c
@@ -0,0 +1,150 @@
+/* ===-- apple_versioning.c - Adds versioning symbols for ld ---------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+
+
+#if __APPLE__
+ #if __arm__
+ #define NOT_HERE_BEFORE_10_6(sym)
+ #elif __ppc__
+ #define NOT_HERE_BEFORE_10_6(sym) \
+ extern const char sym##_tmp3 __asm("$ld$hide$os10.3$_" #sym ); \
+ __attribute__((visibility("default"))) const char sym##_tmp3 = 0; \
+ extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
+ __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
+ extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
+ __attribute__((visibility("default"))) const char sym##_tmp5 = 0;
+ #else
+ #define NOT_HERE_BEFORE_10_6(sym) \
+ extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
+ __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
+ extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
+ __attribute__((visibility("default"))) const char sym##_tmp5 = 0;
+ #endif /* __ppc__ */
+
+
+/* Symbols in libSystem.dylib in 10.6 and later,
+ * but are in libgcc_s.dylib in earlier versions
+ */
+
+NOT_HERE_BEFORE_10_6(__absvdi2)
+NOT_HERE_BEFORE_10_6(__absvsi2)
+NOT_HERE_BEFORE_10_6(__absvti2)
+NOT_HERE_BEFORE_10_6(__addvdi3)
+NOT_HERE_BEFORE_10_6(__addvsi3)
+NOT_HERE_BEFORE_10_6(__addvti3)
+NOT_HERE_BEFORE_10_6(__ashldi3)
+NOT_HERE_BEFORE_10_6(__ashlti3)
+NOT_HERE_BEFORE_10_6(__ashrdi3)
+NOT_HERE_BEFORE_10_6(__ashrti3)
+NOT_HERE_BEFORE_10_6(__clear_cache)
+NOT_HERE_BEFORE_10_6(__clzdi2)
+NOT_HERE_BEFORE_10_6(__clzsi2)
+NOT_HERE_BEFORE_10_6(__clzti2)
+NOT_HERE_BEFORE_10_6(__cmpdi2)
+NOT_HERE_BEFORE_10_6(__cmpti2)
+NOT_HERE_BEFORE_10_6(__ctzdi2)
+NOT_HERE_BEFORE_10_6(__ctzsi2)
+NOT_HERE_BEFORE_10_6(__ctzti2)
+NOT_HERE_BEFORE_10_6(__divdc3)
+NOT_HERE_BEFORE_10_6(__divdi3)
+NOT_HERE_BEFORE_10_6(__divsc3)
+NOT_HERE_BEFORE_10_6(__divtc3)
+NOT_HERE_BEFORE_10_6(__divti3)
+NOT_HERE_BEFORE_10_6(__divxc3)
+NOT_HERE_BEFORE_10_6(__enable_execute_stack)
+NOT_HERE_BEFORE_10_6(__ffsdi2)
+NOT_HERE_BEFORE_10_6(__ffsti2)
+NOT_HERE_BEFORE_10_6(__fixdfdi)
+NOT_HERE_BEFORE_10_6(__fixdfti)
+NOT_HERE_BEFORE_10_6(__fixsfdi)
+NOT_HERE_BEFORE_10_6(__fixsfti)
+NOT_HERE_BEFORE_10_6(__fixtfdi)
+NOT_HERE_BEFORE_10_6(__fixunsdfdi)
+NOT_HERE_BEFORE_10_6(__fixunsdfsi)
+NOT_HERE_BEFORE_10_6(__fixunsdfti)
+NOT_HERE_BEFORE_10_6(__fixunssfdi)
+NOT_HERE_BEFORE_10_6(__fixunssfsi)
+NOT_HERE_BEFORE_10_6(__fixunssfti)
+NOT_HERE_BEFORE_10_6(__fixunstfdi)
+NOT_HERE_BEFORE_10_6(__fixunsxfdi)
+NOT_HERE_BEFORE_10_6(__fixunsxfsi)
+NOT_HERE_BEFORE_10_6(__fixunsxfti)
+NOT_HERE_BEFORE_10_6(__fixxfdi)
+NOT_HERE_BEFORE_10_6(__fixxfti)
+NOT_HERE_BEFORE_10_6(__floatdidf)
+NOT_HERE_BEFORE_10_6(__floatdisf)
+NOT_HERE_BEFORE_10_6(__floatditf)
+NOT_HERE_BEFORE_10_6(__floatdixf)
+NOT_HERE_BEFORE_10_6(__floattidf)
+NOT_HERE_BEFORE_10_6(__floattisf)
+NOT_HERE_BEFORE_10_6(__floattixf)
+NOT_HERE_BEFORE_10_6(__floatundidf)
+NOT_HERE_BEFORE_10_6(__floatundisf)
+NOT_HERE_BEFORE_10_6(__floatunditf)
+NOT_HERE_BEFORE_10_6(__floatundixf)
+NOT_HERE_BEFORE_10_6(__floatuntidf)
+NOT_HERE_BEFORE_10_6(__floatuntisf)
+NOT_HERE_BEFORE_10_6(__floatuntixf)
+NOT_HERE_BEFORE_10_6(__gcc_personality_v0)
+NOT_HERE_BEFORE_10_6(__lshrdi3)
+NOT_HERE_BEFORE_10_6(__lshrti3)
+NOT_HERE_BEFORE_10_6(__moddi3)
+NOT_HERE_BEFORE_10_6(__modti3)
+NOT_HERE_BEFORE_10_6(__muldc3)
+NOT_HERE_BEFORE_10_6(__muldi3)
+NOT_HERE_BEFORE_10_6(__mulsc3)
+NOT_HERE_BEFORE_10_6(__multc3)
+NOT_HERE_BEFORE_10_6(__multi3)
+NOT_HERE_BEFORE_10_6(__mulvdi3)
+NOT_HERE_BEFORE_10_6(__mulvsi3)
+NOT_HERE_BEFORE_10_6(__mulvti3)
+NOT_HERE_BEFORE_10_6(__mulxc3)
+NOT_HERE_BEFORE_10_6(__negdi2)
+NOT_HERE_BEFORE_10_6(__negti2)
+NOT_HERE_BEFORE_10_6(__negvdi2)
+NOT_HERE_BEFORE_10_6(__negvsi2)
+NOT_HERE_BEFORE_10_6(__negvti2)
+NOT_HERE_BEFORE_10_6(__paritydi2)
+NOT_HERE_BEFORE_10_6(__paritysi2)
+NOT_HERE_BEFORE_10_6(__parityti2)
+NOT_HERE_BEFORE_10_6(__popcountdi2)
+NOT_HERE_BEFORE_10_6(__popcountsi2)
+NOT_HERE_BEFORE_10_6(__popcountti2)
+NOT_HERE_BEFORE_10_6(__powidf2)
+NOT_HERE_BEFORE_10_6(__powisf2)
+NOT_HERE_BEFORE_10_6(__powitf2)
+NOT_HERE_BEFORE_10_6(__powixf2)
+NOT_HERE_BEFORE_10_6(__subvdi3)
+NOT_HERE_BEFORE_10_6(__subvsi3)
+NOT_HERE_BEFORE_10_6(__subvti3)
+NOT_HERE_BEFORE_10_6(__ucmpdi2)
+NOT_HERE_BEFORE_10_6(__ucmpti2)
+NOT_HERE_BEFORE_10_6(__udivdi3)
+NOT_HERE_BEFORE_10_6(__udivmoddi4)
+NOT_HERE_BEFORE_10_6(__udivmodti4)
+NOT_HERE_BEFORE_10_6(__udivti3)
+NOT_HERE_BEFORE_10_6(__umoddi3)
+NOT_HERE_BEFORE_10_6(__umodti3)
+
+
+#if __ppc__
+NOT_HERE_BEFORE_10_6(__gcc_qadd)
+NOT_HERE_BEFORE_10_6(__gcc_qdiv)
+NOT_HERE_BEFORE_10_6(__gcc_qmul)
+NOT_HERE_BEFORE_10_6(__gcc_qsub)
+NOT_HERE_BEFORE_10_6(__trampoline_setup)
+#endif /* __ppc__ */
+
+#else /* !__APPLE__ */
+
+extern int avoid_empty_file;
+
+#endif /* !__APPLE__*/
diff --git a/lib/arm/CMakeLists.txt b/lib/arm/CMakeLists.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/lib/arm/CMakeLists.txt
diff --git a/lib/arm/Makefile.mk b/lib/arm/Makefile.mk
new file mode 100644
index 000000000000..cde97c3f99ae
--- /dev/null
+++ b/lib/arm/Makefile.mk
@@ -0,0 +1,19 @@
+#===- lib/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.
+#
+#===------------------------------------------------------------------------===#
+
+SubDirs :=
+OnlyArchs := armv5 armv6 armv7
+
+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/lib/arm/adddf3vfp.S b/lib/arm/adddf3vfp.S
new file mode 100644
index 000000000000..5e705e3c5796
--- /dev/null
+++ b/lib/arm/adddf3vfp.S
@@ -0,0 +1,24 @@
+//===-- adddf3vfp.S - Implement adddf3vfp ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__adddf3vfp)
+ fmdrr d6, r0, r1 // move first param from r0/r1 pair into d6
+ fmdrr d7, r2, r3 // move second param from r2/r3 pair into d7
+ faddd d6, d6, d7
+ fmrrd r0, r1, d6 // move result back to r0/r1 pair
+ bx lr
diff --git a/lib/arm/addsf3vfp.S b/lib/arm/addsf3vfp.S
new file mode 100644
index 000000000000..36d509c1f52b
--- /dev/null
+++ b/lib/arm/addsf3vfp.S
@@ -0,0 +1,24 @@
+//===-- addsf3vfp.S - Implement addsf3vfp ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__addsf3vfp)
+ fmsr s14, r0 // move first param from r0 into float register
+ fmsr s15, r1 // move second param from r1 into float register
+ fadds s14, s14, s15
+ fmrs r0, s14 // move result back to r0
+ bx lr
diff --git a/lib/arm/bswapdi2.S b/lib/arm/bswapdi2.S
new file mode 100644
index 000000000000..d3ca33a341c7
--- /dev/null
+++ b/lib/arm/bswapdi2.S
@@ -0,0 +1,36 @@
+//===------- bswapdi2 - Implement bswapdi2 --------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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_5TEJ__ || __ARM_ARCH_4T__
+ // 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)
+ bx lr
diff --git a/lib/arm/bswapsi2.S b/lib/arm/bswapsi2.S
new file mode 100644
index 000000000000..0a0c073706ce
--- /dev/null
+++ b/lib/arm/bswapsi2.S
@@ -0,0 +1,28 @@
+//===------- bswapsi2 - Implement bswapsi2 --------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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_5TEJ__ || __ARM_ARCH_4T__
+ // 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
+ bx lr
diff --git a/lib/arm/comparesf2.S b/lib/arm/comparesf2.S
new file mode 100644
index 000000000000..f21e0bcd13f6
--- /dev/null
+++ b/lib/arm/comparesf2.S
@@ -0,0 +1,130 @@
+//===-- comparesf2.S - Implement single-precision soft-float comparisons --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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)
+DEFINE_COMPILERRT_FUNCTION(__lesf2)
+DEFINE_COMPILERRT_FUNCTION(__ltsf2)
+DEFINE_COMPILERRT_FUNCTION(__nesf2)
+ // 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.
+ 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.
+ 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.
+ 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.
+ 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.
+ 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
+ cmpls r3, #0xff000000
+ movhi r0, #1
+ bx lr
+
+.align 2
+DEFINE_COMPILERRT_FUNCTION(__gesf2)
+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
+ eorsne r12, r0, r1
+ subspl r0, r2, r3
+ mvnlo r0, r1, asr #31
+ movhi r0, r1, asr #31
+ orrne r0, r0, #1
+ cmp r2, #0xff000000
+ cmpls r3, #0xff000000
+ movhi r0, #-1
+ bx lr
+
+.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
+ cmpls r3, #0xff000000
+ movhi r0, #1
+ bx lr
diff --git a/lib/arm/divdf3vfp.S b/lib/arm/divdf3vfp.S
new file mode 100644
index 000000000000..e43baa373274
--- /dev/null
+++ b/lib/arm/divdf3vfp.S
@@ -0,0 +1,24 @@
+//===-- divdf3vfp.S - Implement divdf3vfp ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__divdf3vfp)
+ fmdrr d6, r0, r1 // move first param from r0/r1 pair into d6
+ fmdrr d7, r2, r3 // move second param from r2/r3 pair into d7
+ fdivd d5, d6, d7
+ fmrrd r0, r1, d5 // move result back to r0/r1 pair
+ bx lr
diff --git a/lib/arm/divsf3vfp.S b/lib/arm/divsf3vfp.S
new file mode 100644
index 000000000000..d96c930f8352
--- /dev/null
+++ b/lib/arm/divsf3vfp.S
@@ -0,0 +1,24 @@
+//===-- divsf3vfp.S - Implement divsf3vfp ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__divsf3vfp)
+ fmsr s14, r0 // move first param from r0 into float register
+ fmsr s15, r1 // move second param from r1 into float register
+ fdivs s13, s14, s15
+ fmrs r0, s13 // move result back to r0
+ bx lr
diff --git a/lib/arm/eqdf2vfp.S b/lib/arm/eqdf2vfp.S
new file mode 100644
index 000000000000..d4384ec0e5ea
--- /dev/null
+++ b/lib/arm/eqdf2vfp.S
@@ -0,0 +1,27 @@
+//===-- eqdf2vfp.S - Implement eqdf2vfp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__eqdf2vfp)
+ fmdrr d6, r0, r1 // load r0/r1 pair in double register
+ fmdrr d7, r2, r3 // load r2/r3 pair in double register
+ fcmpd d6, d7
+ fmstat
+ moveq r0, #1 // set result register to 1 if equal
+ movne r0, #0
+ bx lr
diff --git a/lib/arm/eqsf2vfp.S b/lib/arm/eqsf2vfp.S
new file mode 100644
index 000000000000..07355a3c2239
--- /dev/null
+++ b/lib/arm/eqsf2vfp.S
@@ -0,0 +1,28 @@
+//===-- eqsf2vfp.S - Implement eqsf2vfp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__eqsf2vfp)
+ fmsr s14, r0 // move from GPR 0 to float register
+ fmsr s15, r1 // move from GPR 1 to float register
+ fcmps s14, s15
+ fmstat
+ moveq r0, #1 // set result register to 1 if equal
+ movne r0, #0
+ bx lr
+
diff --git a/lib/arm/extendsfdf2vfp.S b/lib/arm/extendsfdf2vfp.S
new file mode 100644
index 000000000000..4343a7ef1ed4
--- /dev/null
+++ b/lib/arm/extendsfdf2vfp.S
@@ -0,0 +1,24 @@
+//===-- extendsfdf2vfp.S - Implement extendsfdf2vfp -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__extendsfdf2vfp)
+ fmsr s15, r0 // load float register from R0
+ fcvtds d7, s15 // convert single to double
+ fmrrd r0, r1, d7 // return result in r0/r1 pair
+ bx lr
diff --git a/lib/arm/fixdfsivfp.S b/lib/arm/fixdfsivfp.S
new file mode 100644
index 000000000000..30458ccd59b3
--- /dev/null
+++ b/lib/arm/fixdfsivfp.S
@@ -0,0 +1,24 @@
+//===-- fixdfsivfp.S - Implement fixdfsivfp -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__fixdfsivfp)
+ fmdrr d7, r0, r1 // load double register from R0/R1
+ ftosizd s15, d7 // convert double to 32-bit int into s15
+ fmrs r0, s15 // move s15 to result register
+ bx lr
diff --git a/lib/arm/fixsfsivfp.S b/lib/arm/fixsfsivfp.S
new file mode 100644
index 000000000000..ce6f18e1b90c
--- /dev/null
+++ b/lib/arm/fixsfsivfp.S
@@ -0,0 +1,24 @@
+//===-- fixsfsivfp.S - Implement fixsfsivfp -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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..
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__fixsfsivfp)
+ fmsr s15, r0 // load float register from R0
+ ftosizs s15, s15 // convert single to 32-bit int into s15
+ fmrs r0, s15 // move s15 to result register
+ bx lr
diff --git a/lib/arm/fixunsdfsivfp.S b/lib/arm/fixunsdfsivfp.S
new file mode 100644
index 000000000000..7e766c02a5e8
--- /dev/null
+++ b/lib/arm/fixunsdfsivfp.S
@@ -0,0 +1,25 @@
+//===-- fixunsdfsivfp.S - Implement fixunsdfsivfp -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__fixunsdfsivfp)
+ fmdrr d7, r0, r1 // load double register from R0/R1
+ ftouizd s15, d7 // convert double to 32-bit int into s15
+ fmrs r0, s15 // move s15 to result register
+ bx lr
diff --git a/lib/arm/fixunssfsivfp.S b/lib/arm/fixunssfsivfp.S
new file mode 100644
index 000000000000..ba2344f587e7
--- /dev/null
+++ b/lib/arm/fixunssfsivfp.S
@@ -0,0 +1,25 @@
+//===-- fixunssfsivfp.S - Implement fixunssfsivfp -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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..
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__fixunssfsivfp)
+ fmsr s15, r0 // load float register from R0
+ ftouizs s15, s15 // convert single to 32-bit unsigned into s15
+ fmrs r0, s15 // move s15 to result register
+ bx lr
diff --git a/lib/arm/floatsidfvfp.S b/lib/arm/floatsidfvfp.S
new file mode 100644
index 000000000000..5ed4ace9b2c0
--- /dev/null
+++ b/lib/arm/floatsidfvfp.S
@@ -0,0 +1,24 @@
+//===-- floatsidfvfp.S - Implement floatsidfvfp ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__floatsidfvfp)
+ fmsr s15, r0 // move int to float register s15
+ fsitod d7, s15 // convert 32-bit int in s15 to double in d7
+ fmrrd r0, r1, d7 // move d7 to result register pair r0/r1
+ bx lr
diff --git a/lib/arm/floatsisfvfp.S b/lib/arm/floatsisfvfp.S
new file mode 100644
index 000000000000..0114c789358a
--- /dev/null
+++ b/lib/arm/floatsisfvfp.S
@@ -0,0 +1,24 @@
+//===-- floatsisfvfp.S - Implement floatsisfvfp ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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..
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__floatsisfvfp)
+ fmsr s15, r0 // move int to float register s15
+ fsitos s15, s15 // convert 32-bit int in s15 to float in s15
+ fmrs r0, s15 // move s15 to result register
+ bx lr
diff --git a/lib/arm/floatunssidfvfp.S b/lib/arm/floatunssidfvfp.S
new file mode 100644
index 000000000000..d1bfe3af5841
--- /dev/null
+++ b/lib/arm/floatunssidfvfp.S
@@ -0,0 +1,24 @@
+//===-- floatunssidfvfp.S - Implement floatunssidfvfp ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__floatunssidfvfp)
+ fmsr s15, r0 // move int to float register s15
+ fuitod d7, s15 // convert 32-bit int in s15 to double in d7
+ fmrrd r0, r1, d7 // move d7 to result register pair r0/r1
+ bx lr
diff --git a/lib/arm/floatunssisfvfp.S b/lib/arm/floatunssisfvfp.S
new file mode 100644
index 000000000000..0b73577b1067
--- /dev/null
+++ b/lib/arm/floatunssisfvfp.S
@@ -0,0 +1,24 @@
+//===-- floatunssisfvfp.S - Implement floatunssisfvfp ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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..
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__floatunssisfvfp)
+ fmsr s15, r0 // move int to float register s15
+ fuitos s15, s15 // convert 32-bit int in s15 to float in s15
+ fmrs r0, s15 // move s15 to result register
+ bx lr
diff --git a/lib/arm/gedf2vfp.S b/lib/arm/gedf2vfp.S
new file mode 100644
index 000000000000..6ab856fe6f34
--- /dev/null
+++ b/lib/arm/gedf2vfp.S
@@ -0,0 +1,27 @@
+//===-- gedf2vfp.S - Implement gedf2vfp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__gedf2vfp)
+ fmdrr d6, r0, r1 // load r0/r1 pair in double register
+ fmdrr d7, r2, r3 // load r2/r3 pair in double register
+ fcmpd d6, d7
+ fmstat
+ movge r0, #1 // set result register to 1 if greater than or equal
+ movlt r0, #0
+ bx lr
diff --git a/lib/arm/gesf2vfp.S b/lib/arm/gesf2vfp.S
new file mode 100644
index 000000000000..b00d82107dc3
--- /dev/null
+++ b/lib/arm/gesf2vfp.S
@@ -0,0 +1,28 @@
+//===-- gesf2vfp.S - Implement gesf2vfp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__gesf2vfp)
+ fmsr s14, r0 // move from GPR 0 to float register
+ fmsr s15, r1 // move from GPR 1 to float register
+ fcmps s14, s15
+ fmstat
+ movge r0, #1 // set result register to 1 if greater than or equal
+ movlt r0, #0
+ bx lr
+
diff --git a/lib/arm/gtdf2vfp.S b/lib/arm/gtdf2vfp.S
new file mode 100644
index 000000000000..65594c7d3f92
--- /dev/null
+++ b/lib/arm/gtdf2vfp.S
@@ -0,0 +1,27 @@
+//===-- gtdf2vfp.S - Implement gtdf2vfp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__gtdf2vfp)
+ fmdrr d6, r0, r1 // load r0/r1 pair in double register
+ fmdrr d7, r2, r3 // load r2/r3 pair in double register
+ fcmpd d6, d7
+ fmstat
+ movgt r0, #1 // set result register to 1 if equal
+ movle r0, #0
+ bx lr
diff --git a/lib/arm/gtsf2vfp.S b/lib/arm/gtsf2vfp.S
new file mode 100644
index 000000000000..53ef2a00f804
--- /dev/null
+++ b/lib/arm/gtsf2vfp.S
@@ -0,0 +1,28 @@
+//===-- gtsf2vfp.S - Implement gtsf2vfp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__gtsf2vfp)
+ fmsr s14, r0 // move from GPR 0 to float register
+ fmsr s15, r1 // move from GPR 1 to float register
+ fcmps s14, s15
+ fmstat
+ movgt r0, #1 // set result register to 1 if equal
+ movle r0, #0
+ bx lr
+
diff --git a/lib/arm/ledf2vfp.S b/lib/arm/ledf2vfp.S
new file mode 100644
index 000000000000..327a7d5159f7
--- /dev/null
+++ b/lib/arm/ledf2vfp.S
@@ -0,0 +1,27 @@
+//===-- ledf2vfp.S - Implement ledf2vfp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__ledf2vfp)
+ fmdrr d6, r0, r1 // load r0/r1 pair in double register
+ fmdrr d7, r2, r3 // load r2/r3 pair in double register
+ fcmpd d6, d7
+ fmstat
+ movls r0, #1 // set result register to 1 if equal
+ movhi r0, #0
+ bx lr
diff --git a/lib/arm/lesf2vfp.S b/lib/arm/lesf2vfp.S
new file mode 100644
index 000000000000..b7e05da9b42b
--- /dev/null
+++ b/lib/arm/lesf2vfp.S
@@ -0,0 +1,28 @@
+//===-- lesf2vfp.S - Implement lesf2vfp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__lesf2vfp)
+ fmsr s14, r0 // move from GPR 0 to float register
+ fmsr s15, r1 // move from GPR 1 to float register
+ fcmps s14, s15
+ fmstat
+ movls r0, #1 // set result register to 1 if equal
+ movhi r0, #0
+ bx lr
+
diff --git a/lib/arm/ltdf2vfp.S b/lib/arm/ltdf2vfp.S
new file mode 100644
index 000000000000..55dfd808a3b8
--- /dev/null
+++ b/lib/arm/ltdf2vfp.S
@@ -0,0 +1,27 @@
+//===-- ltdf2vfp.S - Implement ltdf2vfp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__ltdf2vfp)
+ fmdrr d6, r0, r1 // load r0/r1 pair in double register
+ fmdrr d7, r2, r3 // load r2/r3 pair in double register
+ fcmpd d6, d7
+ fmstat
+ movmi r0, #1 // set result register to 1 if equal
+ movpl r0, #0
+ bx lr
diff --git a/lib/arm/ltsf2vfp.S b/lib/arm/ltsf2vfp.S
new file mode 100644
index 000000000000..3816a7123a64
--- /dev/null
+++ b/lib/arm/ltsf2vfp.S
@@ -0,0 +1,28 @@
+//===-- ltsf2vfp.S - Implement ltsf2vfp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__ltsf2vfp)
+ fmsr s14, r0 // move from GPR 0 to float register
+ fmsr s15, r1 // move from GPR 1 to float register
+ fcmps s14, s15
+ fmstat
+ movmi r0, #1 // set result register to 1 if equal
+ movpl r0, #0
+ bx lr
+
diff --git a/lib/arm/modsi3.S b/lib/arm/modsi3.S
new file mode 100644
index 000000000000..64a3afd9aa06
--- /dev/null
+++ b/lib/arm/modsi3.S
@@ -0,0 +1,36 @@
+//===-------- modsi3.S - Implement modsi3 ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// extern int32_t __modsi3(int32_t a, int32_t b);
+//
+// Returns the remainder when dividing two 32-bit signed integers.
+// Conceptually, the function is: { return a - (a / b) * b; }
+// But if you write that in C, llvm compiles it to a call to __modsi3...
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__modsi3)
+ push {r4, r5, r7, lr}
+ add r7, sp, #8 // set stack frame
+ mov r5, r0 // save a
+ mov r4, r1 // save b
+ bl ___divsi3 // compute a/b
+#if __ARM_ARCH_7A__
+ mls r0, r4, r0, r5 // mulitple result * b and subtract from a
+#else
+ // before armv7, does not have "mls" instruction
+ mul r3, r0, r4 // multiple result * b
+ sub r0, r5, r3 // a - result
+#endif
+ pop {r4, r5, r7, pc}
+
+
+
diff --git a/lib/arm/muldf3vfp.S b/lib/arm/muldf3vfp.S
new file mode 100644
index 000000000000..cb503d309121
--- /dev/null
+++ b/lib/arm/muldf3vfp.S
@@ -0,0 +1,24 @@
+//===-- muldf3vfp.S - Implement muldf3vfp ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__muldf3vfp)
+ fmdrr d6, r0, r1 // move first param from r0/r1 pair into d6
+ fmdrr d7, r2, r3 // move second param from r2/r3 pair into d7
+ fmuld d6, d6, d7
+ fmrrd r0, r1, d6 // move result back to r0/r1 pair
+ bx lr
diff --git a/lib/arm/mulsf3vfp.S b/lib/arm/mulsf3vfp.S
new file mode 100644
index 000000000000..49b4d1df9468
--- /dev/null
+++ b/lib/arm/mulsf3vfp.S
@@ -0,0 +1,24 @@
+//===-- mulsf3vfp.S - Implement mulsf3vfp ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__mulsf3vfp)
+ fmsr s14, r0 // move first param from r0 into float register
+ fmsr s15, r1 // move second param from r1 into float register
+ fmuls s13, s14, s15
+ fmrs r0, s13 // move result back to r0
+ bx lr
diff --git a/lib/arm/nedf2vfp.S b/lib/arm/nedf2vfp.S
new file mode 100644
index 000000000000..813864e88302
--- /dev/null
+++ b/lib/arm/nedf2vfp.S
@@ -0,0 +1,27 @@
+//===-- nedf2vfp.S - Implement nedf2vfp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__nedf2vfp)
+ fmdrr d6, r0, r1 // load r0/r1 pair in double register
+ fmdrr d7, r2, r3 // load r2/r3 pair in double register
+ fcmpd d6, d7
+ fmstat
+ movne r0, #1 // set result register to 0 if unequal
+ moveq r0, #0
+ bx lr
diff --git a/lib/arm/negdf2vfp.S b/lib/arm/negdf2vfp.S
new file mode 100644
index 000000000000..8013975445ad
--- /dev/null
+++ b/lib/arm/negdf2vfp.S
@@ -0,0 +1,21 @@
+//===-- negdf2vfp.S - Implement negdf2vfp ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__negdf2vfp)
+ eor r1, r1, #-2147483648 // flip sign bit on double in r0/r1 pair
+ bx lr
diff --git a/lib/arm/negsf2vfp.S b/lib/arm/negsf2vfp.S
new file mode 100644
index 000000000000..243c0865c8cc
--- /dev/null
+++ b/lib/arm/negsf2vfp.S
@@ -0,0 +1,21 @@
+//===-- negsf2vfp.S - Implement negsf2vfp ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__negsf2vfp)
+ eor r0, r0, #-2147483648 // flip sign bit on float in r0
+ bx lr
diff --git a/lib/arm/nesf2vfp.S b/lib/arm/nesf2vfp.S
new file mode 100644
index 000000000000..d470afa0ef7e
--- /dev/null
+++ b/lib/arm/nesf2vfp.S
@@ -0,0 +1,28 @@
+//===-- nesf2vfp.S - Implement nesf2vfp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__nesf2vfp)
+ fmsr s14, r0 // move from GPR 0 to float register
+ fmsr s15, r1 // move from GPR 1 to float register
+ fcmps s14, s15
+ fmstat
+ movne r0, #1 // set result register to 1 if unequal
+ moveq r0, #0
+ bx lr
+
diff --git a/lib/arm/restore_vfp_d8_d15_regs.S b/lib/arm/restore_vfp_d8_d15_regs.S
new file mode 100644
index 000000000000..25404cd25076
--- /dev/null
+++ b/lib/arm/restore_vfp_d8_d15_regs.S
@@ -0,0 +1,37 @@
+//===-- save_restore_regs.S - Implement save/restore* ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+
+
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
+
diff --git a/lib/arm/save_vfp_d8_d15_regs.S b/lib/arm/save_vfp_d8_d15_regs.S
new file mode 100644
index 000000000000..92de61bc6e8f
--- /dev/null
+++ b/lib/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 distributed under the University of Illinois Open Source
+// License. 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
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
+
diff --git a/lib/arm/subdf3vfp.S b/lib/arm/subdf3vfp.S
new file mode 100644
index 000000000000..88416006a061
--- /dev/null
+++ b/lib/arm/subdf3vfp.S
@@ -0,0 +1,24 @@
+//===-- subdf3vfp.S - Implement subdf3vfp ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__subdf3vfp)
+ fmdrr d6, r0, r1 // move first param from r0/r1 pair into d6
+ fmdrr d7, r2, r3 // move second param from r2/r3 pair into d7
+ fsubd d6, d6, d7
+ fmrrd r0, r1, d6 // move result back to r0/r1 pair
+ bx lr
diff --git a/lib/arm/subsf3vfp.S b/lib/arm/subsf3vfp.S
new file mode 100644
index 000000000000..4ead9c23e712
--- /dev/null
+++ b/lib/arm/subsf3vfp.S
@@ -0,0 +1,25 @@
+//===-- subsf3vfp.S - Implement subsf3vfp ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__subsf3vfp)
+ fmsr s14, r0 // move first param from r0 into float register
+ fmsr s15, r1 // move second param from r1 into float register
+ fsubs s14, s14, s15
+ fmrs r0, s14 // move result back to r0
+ bx lr
diff --git a/lib/arm/switch16.S b/lib/arm/switch16.S
new file mode 100644
index 000000000000..05c7b98b01ab
--- /dev/null
+++ b/lib/arm/switch16.S
@@ -0,0 +1,44 @@
+//===-- switch.S - Implement switch* --------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+ ldrshcc r0, [r0, #1] // load 16-bit element if r0 is in range
+ add ip, lr, ip, lsl #1 // compute address of last element in table
+ 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
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
diff --git a/lib/arm/switch32.S b/lib/arm/switch32.S
new file mode 100644
index 000000000000..a127cb79f534
--- /dev/null
+++ b/lib/arm/switch32.S
@@ -0,0 +1,46 @@
+//===-- switch.S - Implement switch* --------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+ ldrcc r0, [r0, #3] // load 32-bit element if r0 is in range
+ add ip, lr, ip, lsl #2 // compute address of last element in table
+ ldrcs 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
+
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
+
diff --git a/lib/arm/switch8.S b/lib/arm/switch8.S
new file mode 100644
index 000000000000..d05f6ac7f068
--- /dev/null
+++ b/lib/arm/switch8.S
@@ -0,0 +1,43 @@
+//===-- switch.S - Implement switch* --------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+ ldrsbcc 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
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
+
diff --git a/lib/arm/switchu8.S b/lib/arm/switchu8.S
new file mode 100644
index 000000000000..faffddb50c1e
--- /dev/null
+++ b/lib/arm/switchu8.S
@@ -0,0 +1,43 @@
+//===-- switch.S - Implement switch* --------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+ ldrbcc 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
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
+
diff --git a/lib/arm/sync_synchronize.S b/lib/arm/sync_synchronize.S
new file mode 100644
index 000000000000..76fdab1fbdb2
--- /dev/null
+++ b/lib/arm/sync_synchronize.S
@@ -0,0 +1,34 @@
+//===-- sync_synchronize - Implement memory barrier * ----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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}
+
+ // tell linker it can break up file at label boundaries
+ .subsections_via_symbols
+
+#endif
diff --git a/lib/arm/truncdfsf2vfp.S b/lib/arm/truncdfsf2vfp.S
new file mode 100644
index 000000000000..5725e25c76a7
--- /dev/null
+++ b/lib/arm/truncdfsf2vfp.S
@@ -0,0 +1,24 @@
+//===-- truncdfsf2vfp.S - Implement truncdfsf2vfp -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__truncdfsf2vfp)
+ fmdrr d7, r0, r1 // load double from r0/r1 pair
+ fcvtsd s15, d7 // convert double to single (trucate precision)
+ fmrs r0, s15 // return result in r0
+ bx lr
diff --git a/lib/arm/unorddf2vfp.S b/lib/arm/unorddf2vfp.S
new file mode 100644
index 000000000000..de00b07feef9
--- /dev/null
+++ b/lib/arm/unorddf2vfp.S
@@ -0,0 +1,27 @@
+//===-- unorddf2vfp.S - Implement unorddf2vfp ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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.
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__unorddf2vfp)
+ fmdrr d6, r0, r1 // load r0/r1 pair in double register
+ fmdrr d7, r2, r3 // load r2/r3 pair in double register
+ fcmpd d6, d7
+ fmstat
+ movvs r0, #1 // set result register to 1 if "overflow" (any NaNs)
+ movvc r0, #0
+ bx lr
diff --git a/lib/arm/unordsf2vfp.S b/lib/arm/unordsf2vfp.S
new file mode 100644
index 000000000000..ab291a858dab
--- /dev/null
+++ b/lib/arm/unordsf2vfp.S
@@ -0,0 +1,28 @@
+//===-- unordsf2vfp.S - Implement unordsf2vfp -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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
+//
+ .align 2
+DEFINE_COMPILERRT_FUNCTION(__unordsf2vfp)
+ fmsr s14, r0 // move from GPR 0 to float register
+ fmsr s15, r1 // move from GPR 1 to float register
+ fcmps s14, s15
+ fmstat
+ movvs r0, #1 // set result register to 1 if "overflow" (any NaNs)
+ movvc r0, #0
+ bx lr
+
diff --git a/lib/ashldi3.c b/lib/ashldi3.c
new file mode 100644
index 000000000000..993f71ca9724
--- /dev/null
+++ b/lib/ashldi3.c
@@ -0,0 +1,41 @@
+/* ====-- ashldi3.c - Implement __ashldi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __ashldi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: a << b */
+
+/* Precondition: 0 <= b < bits_in_dword */
+
+di_int
+__ashldi3(di_int a, si_int b)
+{
+ const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);
+ dwords input;
+ dwords result;
+ input.all = a;
+ if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */
+ {
+ result.s.low = 0;
+ result.s.high = input.s.low << (b - bits_in_word);
+ }
+ else /* 0 <= b < bits_in_word */
+ {
+ if (b == 0)
+ return a;
+ result.s.low = input.s.low << b;
+ result.s.high = (input.s.high << b) | (input.s.low >> (bits_in_word - b));
+ }
+ return result.all;
+}
diff --git a/lib/ashlti3.c b/lib/ashlti3.c
new file mode 100644
index 000000000000..317de6655956
--- /dev/null
+++ b/lib/ashlti3.c
@@ -0,0 +1,45 @@
+/* ===-- ashlti3.c - Implement __ashlti3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __ashlti3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: a << b */
+
+/* Precondition: 0 <= b < bits_in_tword */
+
+ti_int
+__ashlti3(ti_int a, si_int b)
+{
+ const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT);
+ twords input;
+ twords result;
+ input.all = a;
+ if (b & bits_in_dword) /* bits_in_dword <= b < bits_in_tword */
+ {
+ result.s.low = 0;
+ result.s.high = input.s.low << (b - bits_in_dword);
+ }
+ else /* 0 <= b < bits_in_dword */
+ {
+ if (b == 0)
+ return a;
+ result.s.low = input.s.low << b;
+ result.s.high = (input.s.high << b) | (input.s.low >> (bits_in_dword - b));
+ }
+ return result.all;
+}
+
+#endif /* __x86_64 */
diff --git a/lib/ashrdi3.c b/lib/ashrdi3.c
new file mode 100644
index 000000000000..8e27a11a7523
--- /dev/null
+++ b/lib/ashrdi3.c
@@ -0,0 +1,42 @@
+/*===-- ashrdi3.c - Implement __ashrdi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __ashrdi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: arithmetic a >> b */
+
+/* Precondition: 0 <= b < bits_in_dword */
+
+di_int
+__ashrdi3(di_int a, si_int b)
+{
+ const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);
+ dwords input;
+ dwords result;
+ input.all = a;
+ if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */
+ {
+ /* result.s.high = input.s.high < 0 ? -1 : 0 */
+ result.s.high = input.s.high >> (bits_in_word - 1);
+ result.s.low = input.s.high >> (b - bits_in_word);
+ }
+ else /* 0 <= b < bits_in_word */
+ {
+ if (b == 0)
+ return a;
+ result.s.high = input.s.high >> b;
+ result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b);
+ }
+ return result.all;
+}
diff --git a/lib/ashrti3.c b/lib/ashrti3.c
new file mode 100644
index 000000000000..4eab2475c133
--- /dev/null
+++ b/lib/ashrti3.c
@@ -0,0 +1,46 @@
+/* ===-- ashrti3.c - Implement __ashrti3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __ashrti3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: arithmetic a >> b */
+
+/* Precondition: 0 <= b < bits_in_tword */
+
+ti_int
+__ashrti3(ti_int a, si_int b)
+{
+ const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT);
+ twords input;
+ twords result;
+ input.all = a;
+ if (b & bits_in_dword) /* bits_in_dword <= b < bits_in_tword */
+ {
+ /* result.s.high = input.s.high < 0 ? -1 : 0 */
+ result.s.high = input.s.high >> (bits_in_dword - 1);
+ result.s.low = input.s.high >> (b - bits_in_dword);
+ }
+ else /* 0 <= b < bits_in_dword */
+ {
+ if (b == 0)
+ return a;
+ result.s.high = input.s.high >> b;
+ result.s.low = (input.s.high << (bits_in_dword - b)) | (input.s.low >> b);
+ }
+ return result.all;
+}
+
+#endif /* __x86_64 */
diff --git a/lib/assembly.h b/lib/assembly.h
new file mode 100644
index 000000000000..c2d5a34fffb0
--- /dev/null
+++ b/lib/assembly.h
@@ -0,0 +1,54 @@
+/* ===-- assembly.h - compiler-rt assembler support macros -----------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file defines macros for use in compiler-rt assembler source.
+ * This file is not part of the interface of this library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#ifndef COMPILERRT_ASSEMBLY_H
+#define COMPILERRT_ASSEMBLY_H
+
+#if defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__)
+#define SEPARATOR @
+#else
+#define SEPARATOR ;
+#endif
+
+/* We can't use __USER_LABEL_PREFIX__ here, it isn't possible to concatenate the
+ *values* of two macros. This is quite brittle, though. */
+#if defined(__APPLE__)
+#define SYMBOL_NAME(name) _##name
+#else
+#define SYMBOL_NAME(name) name
+#endif
+
+#ifdef VISIBILITY_HIDDEN
+#define DEFINE_COMPILERRT_FUNCTION(name) \
+ .globl SYMBOL_NAME(name) SEPARATOR \
+ .private_extern SYMBOL_NAME(name) SEPARATOR \
+ SYMBOL_NAME(name):
+#else
+#define DEFINE_COMPILERRT_FUNCTION(name) \
+ .globl SYMBOL_NAME(name) SEPARATOR \
+ SYMBOL_NAME(name):
+#endif
+
+#define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \
+ .globl SYMBOL_NAME(name) SEPARATOR \
+ .private_extern SYMBOL_NAME(name) SEPARATOR \
+ SYMBOL_NAME(name):
+
+#define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \
+ .globl name SEPARATOR \
+ .private_extern name SEPARATOR \
+ name:
+
+#endif /* COMPILERRT_ASSEMBLY_H */
diff --git a/lib/clear_cache.c b/lib/clear_cache.c
new file mode 100644
index 000000000000..ddc48bcc56e3
--- /dev/null
+++ b/lib/clear_cache.c
@@ -0,0 +1,40 @@
+/* ===-- clear_cache.c - Implement __clear_cache ---------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include <stdlib.h>
+
+#if __APPLE__
+ #include <libkern/OSCacheControl.h>
+#endif
+
+/*
+ * The compiler generates calls to __clear_cache() when creating
+ * trampoline functions on the stack for use with nested functions.
+ * It is expected to invalidate the instruction cache for the
+ * specified range.
+ */
+
+void __clear_cache(void* start, void* end)
+{
+#if __i386__ || __x86_64__
+/*
+ * Intel processors have a unified instruction and data cache
+ * so there is nothing to do
+ */
+#else
+ #if __APPLE__
+ /* On Darwin, sys_icache_invalidate() provides this functionality */
+ sys_icache_invalidate(start, end-start);
+ #else
+ compilerrt_abort();
+ #endif
+#endif
+}
+
diff --git a/lib/clzdi2.c b/lib/clzdi2.c
new file mode 100644
index 000000000000..ea953961de09
--- /dev/null
+++ b/lib/clzdi2.c
@@ -0,0 +1,29 @@
+/* ===-- clzdi2.c - Implement __clzdi2 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __clzdi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: the number of leading 0-bits */
+
+/* Precondition: a != 0 */
+
+si_int
+__clzdi2(di_int a)
+{
+ dwords x;
+ x.all = a;
+ const si_int f = -(x.s.high == 0);
+ return __builtin_clz((x.s.high & ~f) | (x.s.low & f)) +
+ (f & ((si_int)(sizeof(si_int) * CHAR_BIT)));
+}
diff --git a/lib/clzsi2.c b/lib/clzsi2.c
new file mode 100644
index 000000000000..7e14af293701
--- /dev/null
+++ b/lib/clzsi2.c
@@ -0,0 +1,53 @@
+/* ===-- clzsi2.c - Implement __clzsi2 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __clzsi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: the number of leading 0-bits */
+
+/* Precondition: a != 0 */
+
+si_int
+__clzsi2(si_int a)
+{
+ su_int x = (su_int)a;
+ si_int t = ((x & 0xFFFF0000) == 0) << 4; /* if (x is small) t = 16 else 0 */
+ x >>= 16 - t; /* x = [0 - 0xFFFF] */
+ su_int r = t; /* r = [0, 16] */
+ /* return r + clz(x) */
+ t = ((x & 0xFF00) == 0) << 3;
+ x >>= 8 - t; /* x = [0 - 0xFF] */
+ r += t; /* r = [0, 8, 16, 24] */
+ /* return r + clz(x) */
+ t = ((x & 0xF0) == 0) << 2;
+ x >>= 4 - t; /* x = [0 - 0xF] */
+ r += t; /* r = [0, 4, 8, 12, 16, 20, 24, 28] */
+ /* return r + clz(x) */
+ t = ((x & 0xC) == 0) << 1;
+ x >>= 2 - t; /* x = [0 - 3] */
+ r += t; /* r = [0 - 30] and is even */
+ /* return r + clz(x) */
+/* switch (x)
+ * {
+ * case 0:
+ * return r + 2;
+ * case 1:
+ * return r + 1;
+ * case 2:
+ * case 3:
+ * return r;
+ * }
+ */
+ return r + ((2 - x) & -((x & 2) == 0));
+}
diff --git a/lib/clzti2.c b/lib/clzti2.c
new file mode 100644
index 000000000000..805688fbe223
--- /dev/null
+++ b/lib/clzti2.c
@@ -0,0 +1,33 @@
+/* ===-- clzti2.c - Implement __clzti2 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __clzti2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: the number of leading 0-bits */
+
+/* Precondition: a != 0 */
+
+si_int
+__clzti2(ti_int a)
+{
+ twords x;
+ x.all = a;
+ const di_int f = -(x.s.high == 0);
+ return __builtin_clzll((x.s.high & ~f) | (x.s.low & f)) +
+ ((si_int)f & ((si_int)(sizeof(di_int) * CHAR_BIT)));
+}
+
+#endif /* __x86_64 */
diff --git a/lib/cmpdi2.c b/lib/cmpdi2.c
new file mode 100644
index 000000000000..0b8735244ca6
--- /dev/null
+++ b/lib/cmpdi2.c
@@ -0,0 +1,38 @@
+/* ===-- cmpdi2.c - Implement __cmpdi2 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __cmpdi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: if (a < b) returns 0
+* if (a == b) returns 1
+* if (a > b) returns 2
+*/
+
+si_int
+__cmpdi2(di_int a, di_int b)
+{
+ dwords x;
+ x.all = a;
+ dwords y;
+ y.all = b;
+ if (x.s.high < y.s.high)
+ return 0;
+ if (x.s.high > y.s.high)
+ return 2;
+ if (x.s.low < y.s.low)
+ return 0;
+ if (x.s.low > y.s.low)
+ return 2;
+ return 1;
+}
diff --git a/lib/cmpti2.c b/lib/cmpti2.c
new file mode 100644
index 000000000000..90b3b75638b7
--- /dev/null
+++ b/lib/cmpti2.c
@@ -0,0 +1,42 @@
+/* ===-- cmpti2.c - Implement __cmpti2 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __cmpti2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: if (a < b) returns 0
+ * if (a == b) returns 1
+ * if (a > b) returns 2
+ */
+
+si_int
+__cmpti2(ti_int a, ti_int b)
+{
+ twords x;
+ x.all = a;
+ twords y;
+ y.all = b;
+ if (x.s.high < y.s.high)
+ return 0;
+ if (x.s.high > y.s.high)
+ return 2;
+ if (x.s.low < y.s.low)
+ return 0;
+ if (x.s.low > y.s.low)
+ return 2;
+ return 1;
+}
+
+#endif
diff --git a/lib/comparedf2.c b/lib/comparedf2.c
new file mode 100644
index 000000000000..5c5ee9d65bf2
--- /dev/null
+++ b/lib/comparedf2.c
@@ -0,0 +1,132 @@
+//===-- lib/comparedf2.c - Double-precision comparisons -----------*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// // This file implements the following soft-float comparison routines:
+//
+// __eqdf2 __gedf2 __unorddf2
+// __ledf2 __gtdf2
+// __ltdf2
+// __nedf2
+//
+// The semantics of the routines grouped in each column are identical, so there
+// is a single implementation for each, and wrappers to provide the other names.
+//
+// The main routines behave as follows:
+//
+// __ledf2(a,b) returns -1 if a < b
+// 0 if a == b
+// 1 if a > b
+// 1 if either a or b is NaN
+//
+// __gedf2(a,b) returns -1 if a < b
+// 0 if a == b
+// 1 if a > b
+// -1 if either a or b is NaN
+//
+// __unorddf2(a,b) returns 0 if both a and b are numbers
+// 1 if either a or b is NaN
+//
+// Note that __ledf2( ) and __gedf2( ) are identical except in their handling of
+// NaN values.
+//
+//===----------------------------------------------------------------------===//
+
+#define DOUBLE_PRECISION
+#include "fp_lib.h"
+
+enum LE_RESULT {
+ LE_LESS = -1,
+ LE_EQUAL = 0,
+ LE_GREATER = 1,
+ LE_UNORDERED = 1
+};
+
+enum LE_RESULT __ledf2(fp_t a, fp_t b) {
+
+ const srep_t aInt = toRep(a);
+ const srep_t bInt = toRep(b);
+ const rep_t aAbs = aInt & absMask;
+ const rep_t bAbs = bInt & absMask;
+
+ // If either a or b is NaN, they are unordered.
+ if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED;
+
+ // If a and b are both zeros, they are equal.
+ if ((aAbs | bAbs) == 0) return LE_EQUAL;
+
+ // If at least one of a and b is positive, we get the same result comparing
+ // a and b as signed integers as we would with a floating-point compare.
+ if ((aInt & bInt) >= 0) {
+ if (aInt < bInt) return LE_LESS;
+ else if (aInt == bInt) return LE_EQUAL;
+ else return LE_GREATER;
+ }
+
+ // Otherwise, both are negative, so we need to flip the sense of the
+ // comparison to get the correct result. (This assumes a twos- or ones-
+ // complement integer representation; if integers are represented in a
+ // sign-magnitude representation, then this flip is incorrect).
+ else {
+ if (aInt > bInt) return LE_LESS;
+ else if (aInt == bInt) return LE_EQUAL;
+ else return LE_GREATER;
+ }
+}
+
+enum GE_RESULT {
+ GE_LESS = -1,
+ GE_EQUAL = 0,
+ GE_GREATER = 1,
+ GE_UNORDERED = -1 // Note: different from LE_UNORDERED
+};
+
+enum GE_RESULT __gedf2(fp_t a, fp_t b) {
+
+ const srep_t aInt = toRep(a);
+ const srep_t bInt = toRep(b);
+ const rep_t aAbs = aInt & absMask;
+ const rep_t bAbs = bInt & absMask;
+
+ if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED;
+ if ((aAbs | bAbs) == 0) return GE_EQUAL;
+ if ((aInt & bInt) >= 0) {
+ if (aInt < bInt) return GE_LESS;
+ else if (aInt == bInt) return GE_EQUAL;
+ else return GE_GREATER;
+ } else {
+ if (aInt > bInt) return GE_LESS;
+ else if (aInt == bInt) return GE_EQUAL;
+ else return GE_GREATER;
+ }
+}
+
+int __unorddf2(fp_t a, fp_t b) {
+ const rep_t aAbs = toRep(a) & absMask;
+ const rep_t bAbs = toRep(b) & absMask;
+ return aAbs > infRep || bAbs > infRep;
+}
+
+// The following are alternative names for the preceeding routines.
+
+enum LE_RESULT __eqdf2(fp_t a, fp_t b) {
+ return __ledf2(a, b);
+}
+
+enum LE_RESULT __ltdf2(fp_t a, fp_t b) {
+ return __ledf2(a, b);
+}
+
+enum LE_RESULT __nedf2(fp_t a, fp_t b) {
+ return __ledf2(a, b);
+}
+
+enum GE_RESULT __gtdf2(fp_t a, fp_t b) {
+ return __gedf2(a, b);
+}
+
diff --git a/lib/comparesf2.c b/lib/comparesf2.c
new file mode 100644
index 000000000000..fd0572401117
--- /dev/null
+++ b/lib/comparesf2.c
@@ -0,0 +1,131 @@
+//===-- lib/comparesf2.c - Single-precision comparisons -----------*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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, and wrappers to provide the other names.
+//
+// The main 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.
+//
+//===----------------------------------------------------------------------===//
+
+#define SINGLE_PRECISION
+#include "fp_lib.h"
+
+enum LE_RESULT {
+ LE_LESS = -1,
+ LE_EQUAL = 0,
+ LE_GREATER = 1,
+ LE_UNORDERED = 1
+};
+
+enum LE_RESULT __lesf2(fp_t a, fp_t b) {
+
+ const srep_t aInt = toRep(a);
+ const srep_t bInt = toRep(b);
+ const rep_t aAbs = aInt & absMask;
+ const rep_t bAbs = bInt & absMask;
+
+ // If either a or b is NaN, they are unordered.
+ if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED;
+
+ // If a and b are both zeros, they are equal.
+ if ((aAbs | bAbs) == 0) return LE_EQUAL;
+
+ // If at least one of a and b is positive, we get the same result comparing
+ // a and b as signed integers as we would with a fp_ting-point compare.
+ if ((aInt & bInt) >= 0) {
+ if (aInt < bInt) return LE_LESS;
+ else if (aInt == bInt) return LE_EQUAL;
+ else return LE_GREATER;
+ }
+
+ // Otherwise, both are negative, so we need to flip the sense of the
+ // comparison to get the correct result. (This assumes a twos- or ones-
+ // complement integer representation; if integers are represented in a
+ // sign-magnitude representation, then this flip is incorrect).
+ else {
+ if (aInt > bInt) return LE_LESS;
+ else if (aInt == bInt) return LE_EQUAL;
+ else return LE_GREATER;
+ }
+}
+
+enum GE_RESULT {
+ GE_LESS = -1,
+ GE_EQUAL = 0,
+ GE_GREATER = 1,
+ GE_UNORDERED = -1 // Note: different from LE_UNORDERED
+};
+
+enum GE_RESULT __gesf2(fp_t a, fp_t b) {
+
+ const srep_t aInt = toRep(a);
+ const srep_t bInt = toRep(b);
+ const rep_t aAbs = aInt & absMask;
+ const rep_t bAbs = bInt & absMask;
+
+ if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED;
+ if ((aAbs | bAbs) == 0) return GE_EQUAL;
+ if ((aInt & bInt) >= 0) {
+ if (aInt < bInt) return GE_LESS;
+ else if (aInt == bInt) return GE_EQUAL;
+ else return GE_GREATER;
+ } else {
+ if (aInt > bInt) return GE_LESS;
+ else if (aInt == bInt) return GE_EQUAL;
+ else return GE_GREATER;
+ }
+}
+
+int __unordsf2(fp_t a, fp_t b) {
+ const rep_t aAbs = toRep(a) & absMask;
+ const rep_t bAbs = toRep(b) & absMask;
+ return aAbs > infRep || bAbs > infRep;
+}
+
+// The following are alternative names for the preceeding routines.
+
+enum LE_RESULT __eqsf2(fp_t a, fp_t b) {
+ return __lesf2(a, b);
+}
+
+enum LE_RESULT __ltsf2(fp_t a, fp_t b) {
+ return __lesf2(a, b);
+}
+
+enum LE_RESULT __nesf2(fp_t a, fp_t b) {
+ return __lesf2(a, b);
+}
+
+enum GE_RESULT __gtsf2(fp_t a, fp_t b) {
+ return __gesf2(a, b);
+}
diff --git a/lib/ctzdi2.c b/lib/ctzdi2.c
new file mode 100644
index 000000000000..b49f2c713534
--- /dev/null
+++ b/lib/ctzdi2.c
@@ -0,0 +1,29 @@
+/* ===-- ctzdi2.c - Implement __ctzdi2 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __ctzdi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: the number of trailing 0-bits */
+
+/* Precondition: a != 0 */
+
+si_int
+__ctzdi2(di_int a)
+{
+ dwords x;
+ x.all = a;
+ const si_int f = -(x.s.low == 0);
+ return __builtin_ctz((x.s.high & f) | (x.s.low & ~f)) +
+ (f & ((si_int)(sizeof(si_int) * CHAR_BIT)));
+}
diff --git a/lib/ctzsi2.c b/lib/ctzsi2.c
new file mode 100644
index 000000000000..30d34c862509
--- /dev/null
+++ b/lib/ctzsi2.c
@@ -0,0 +1,57 @@
+/* ===-- ctzsi2.c - Implement __ctzsi2 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __ctzsi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: the number of trailing 0-bits */
+
+/* Precondition: a != 0 */
+
+si_int
+__ctzsi2(si_int a)
+{
+ su_int x = (su_int)a;
+ si_int t = ((x & 0x0000FFFF) == 0) << 4; /* if (x has no small bits) t = 16 else 0 */
+ x >>= t; /* x = [0 - 0xFFFF] + higher garbage bits */
+ su_int r = t; /* r = [0, 16] */
+ /* return r + ctz(x) */
+ t = ((x & 0x00FF) == 0) << 3;
+ x >>= t; /* x = [0 - 0xFF] + higher garbage bits */
+ r += t; /* r = [0, 8, 16, 24] */
+ /* return r + ctz(x) */
+ t = ((x & 0x0F) == 0) << 2;
+ x >>= t; /* x = [0 - 0xF] + higher garbage bits */
+ r += t; /* r = [0, 4, 8, 12, 16, 20, 24, 28] */
+ /* return r + ctz(x) */
+ t = ((x & 0x3) == 0) << 1;
+ x >>= t;
+ x &= 3; /* x = [0 - 3] */
+ r += t; /* r = [0 - 30] and is even */
+ /* return r + ctz(x) */
+
+/* The branch-less return statement below is equivalent
+ * to the following switch statement:
+ * switch (x)
+ * {
+ * case 0:
+ * return r + 2;
+ * case 2:
+ * return r + 1;
+ * case 1:
+ * case 3:
+ * return r;
+ * }
+ */
+ return r + ((2 - (x >> 1)) & -((x & 1) == 0));
+}
diff --git a/lib/ctzti2.c b/lib/ctzti2.c
new file mode 100644
index 000000000000..f2d41fee1cb8
--- /dev/null
+++ b/lib/ctzti2.c
@@ -0,0 +1,33 @@
+/* ===-- ctzti2.c - Implement __ctzti2 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __ctzti2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: the number of trailing 0-bits */
+
+/* Precondition: a != 0 */
+
+si_int
+__ctzti2(ti_int a)
+{
+ twords x;
+ x.all = a;
+ const di_int f = -(x.s.low == 0);
+ return __builtin_ctzll((x.s.high & f) | (x.s.low & ~f)) +
+ ((si_int)f & ((si_int)(sizeof(di_int) * CHAR_BIT)));
+}
+
+#endif
diff --git a/lib/divdc3.c b/lib/divdc3.c
new file mode 100644
index 000000000000..c96aefd0e49d
--- /dev/null
+++ b/lib/divdc3.c
@@ -0,0 +1,59 @@
+/* ===-- divdc3.c - Implement __divdc3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __divdc3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+
+/* Returns: the quotient of (a + ib) / (c + id) */
+
+double _Complex
+__divdc3(double __a, double __b, double __c, double __d)
+{
+ int __ilogbw = 0;
+ double __logbw = logb(fmax(fabs(__c), fabs(__d)));
+ if (isfinite(__logbw))
+ {
+ __ilogbw = (int)__logbw;
+ __c = scalbn(__c, -__ilogbw);
+ __d = scalbn(__d, -__ilogbw);
+ }
+ double __denom = __c * __c + __d * __d;
+ double _Complex z;
+ __real__ z = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
+ __imag__ z = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
+ if (isnan(__real__ z) && isnan(__imag__ z))
+ {
+ if ((__denom == 0.0) && (!isnan(__a) || !isnan(__b)))
+ {
+ __real__ z = copysign(INFINITY, __c) * __a;
+ __imag__ z = copysign(INFINITY, __c) * __b;
+ }
+ else if ((isinf(__a) || isinf(__b)) && isfinite(__c) && isfinite(__d))
+ {
+ __a = copysign(isinf(__a) ? 1.0 : 0.0, __a);
+ __b = copysign(isinf(__b) ? 1.0 : 0.0, __b);
+ __real__ z = INFINITY * (__a * __c + __b * __d);
+ __imag__ z = INFINITY * (__b * __c - __a * __d);
+ }
+ else if (isinf(__logbw) && __logbw > 0.0 && isfinite(__a) && isfinite(__b))
+ {
+ __c = copysign(isinf(__c) ? 1.0 : 0.0, __c);
+ __d = copysign(isinf(__d) ? 1.0 : 0.0, __d);
+ __real__ z = 0.0 * (__a * __c + __b * __d);
+ __imag__ z = 0.0 * (__b * __c - __a * __d);
+ }
+ }
+ return z;
+}
diff --git a/lib/divdf3.c b/lib/divdf3.c
new file mode 100644
index 000000000000..21b8f09bacb0
--- /dev/null
+++ b/lib/divdf3.c
@@ -0,0 +1,182 @@
+//===-- lib/divdf3.c - Double-precision division ------------------*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements double-precision soft-float division
+// with the IEEE-754 default rounding (to nearest, ties to even).
+//
+// For simplicity, this implementation currently flushes denormals to zero.
+// It should be a fairly straightforward exercise to implement gradual
+// underflow with correct rounding.
+//
+//===----------------------------------------------------------------------===//
+
+#define DOUBLE_PRECISION
+#include "fp_lib.h"
+
+fp_t __divdf3(fp_t a, fp_t b) {
+
+ const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;
+ const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;
+ const rep_t quotientSign = (toRep(a) ^ toRep(b)) & signBit;
+
+ rep_t aSignificand = toRep(a) & significandMask;
+ rep_t bSignificand = toRep(b) & significandMask;
+ int scale = 0;
+
+ // Detect if a or b is zero, denormal, infinity, or NaN.
+ if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) {
+
+ const rep_t aAbs = toRep(a) & absMask;
+ const rep_t bAbs = toRep(b) & absMask;
+
+ // NaN / anything = qNaN
+ if (aAbs > infRep) return fromRep(toRep(a) | quietBit);
+ // anything / NaN = qNaN
+ if (bAbs > infRep) return fromRep(toRep(b) | quietBit);
+
+ if (aAbs == infRep) {
+ // infinity / infinity = NaN
+ if (bAbs == infRep) return fromRep(qnanRep);
+ // infinity / anything else = +/- infinity
+ else return fromRep(aAbs | quotientSign);
+ }
+
+ // anything else / infinity = +/- 0
+ if (bAbs == infRep) return fromRep(quotientSign);
+
+ if (!aAbs) {
+ // zero / zero = NaN
+ if (!bAbs) return fromRep(qnanRep);
+ // zero / anything else = +/- zero
+ else return fromRep(quotientSign);
+ }
+ // anything else / zero = +/- infinity
+ if (!bAbs) return fromRep(infRep | quotientSign);
+
+ // one or both of a or b is denormal, the other (if applicable) is a
+ // normal number. Renormalize one or both of a and b, and set scale to
+ // include the necessary exponent adjustment.
+ if (aAbs < implicitBit) scale += normalize(&aSignificand);
+ if (bAbs < implicitBit) scale -= normalize(&bSignificand);
+ }
+
+ // Or in the implicit significand bit. (If we fell through from the
+ // denormal path it was already set by normalize( ), but setting it twice
+ // won't hurt anything.)
+ aSignificand |= implicitBit;
+ bSignificand |= implicitBit;
+ int quotientExponent = aExponent - bExponent + scale;
+
+ // Align the significand of b as a Q31 fixed-point number in the range
+ // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax
+ // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
+ // is accurate to about 3.5 binary digits.
+ const uint32_t q31b = bSignificand >> 21;
+ uint32_t recip32 = UINT32_C(0x7504f333) - q31b;
+
+ // Now refine the reciprocal estimate using a Newton-Raphson iteration:
+ //
+ // x1 = x0 * (2 - x0 * b)
+ //
+ // This doubles the number of correct binary digits in the approximation
+ // with each iteration, so after three iterations, we have about 28 binary
+ // digits of accuracy.
+ uint32_t correction32;
+ correction32 = -((uint64_t)recip32 * q31b >> 32);
+ recip32 = (uint64_t)recip32 * correction32 >> 31;
+ correction32 = -((uint64_t)recip32 * q31b >> 32);
+ recip32 = (uint64_t)recip32 * correction32 >> 31;
+ correction32 = -((uint64_t)recip32 * q31b >> 32);
+ recip32 = (uint64_t)recip32 * correction32 >> 31;
+
+ // recip32 might have overflowed to exactly zero in the preceeding
+ // computation if the high word of b is exactly 1.0. This would sabotage
+ // the full-width final stage of the computation that follows, so we adjust
+ // recip32 downward by one bit.
+ recip32--;
+
+ // We need to perform one more iteration to get us to 56 binary digits;
+ // The last iteration needs to happen with extra precision.
+ const uint32_t q63blo = bSignificand << 11;
+ uint64_t correction, reciprocal;
+ correction = -((uint64_t)recip32*q31b + ((uint64_t)recip32*q63blo >> 32));
+ uint32_t cHi = correction >> 32;
+ uint32_t cLo = correction;
+ reciprocal = (uint64_t)recip32*cHi + ((uint64_t)recip32*cLo >> 32);
+
+ // We already adjusted the 32-bit estimate, now we need to adjust the final
+ // 64-bit reciprocal estimate downward to ensure that it is strictly smaller
+ // than the infinitely precise exact reciprocal. Because the computation
+ // of the Newton-Raphson step is truncating at every step, this adjustment
+ // is small; most of the work is already done.
+ reciprocal -= 2;
+
+ // The numerical reciprocal is accurate to within 2^-56, lies in the
+ // interval [0.5, 1.0), and is strictly smaller than the true reciprocal
+ // of b. Multiplying a by this reciprocal thus gives a numerical q = a/b
+ // in Q53 with the following properties:
+ //
+ // 1. q < a/b
+ // 2. q is in the interval [0.5, 2.0)
+ // 3. the error in q is bounded away from 2^-53 (actually, we have a
+ // couple of bits to spare, but this is all we need).
+
+ // We need a 64 x 64 multiply high to compute q, which isn't a basic
+ // operation in C, so we need to be a little bit fussy.
+ rep_t quotient, quotientLo;
+ wideMultiply(aSignificand << 2, reciprocal, &quotient, &quotientLo);
+
+ // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0).
+ // In either case, we are going to compute a residual of the form
+ //
+ // r = a - q*b
+ //
+ // We know from the construction of q that r satisfies:
+ //
+ // 0 <= r < ulp(q)*b
+ //
+ // if r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we
+ // already have the correct result. The exact halfway case cannot occur.
+ // We also take this time to right shift quotient if it falls in the [1,2)
+ // range and adjust the exponent accordingly.
+ rep_t residual;
+ if (quotient < (implicitBit << 1)) {
+ residual = (aSignificand << 53) - quotient * bSignificand;
+ quotientExponent--;
+ } else {
+ quotient >>= 1;
+ residual = (aSignificand << 52) - quotient * bSignificand;
+ }
+
+ const int writtenExponent = quotientExponent + exponentBias;
+
+ if (writtenExponent >= maxExponent) {
+ // If we have overflowed the exponent, return infinity.
+ return fromRep(infRep | quotientSign);
+ }
+
+ else if (writtenExponent < 1) {
+ // Flush denormals to zero. In the future, it would be nice to add
+ // code to round them correctly.
+ return fromRep(quotientSign);
+ }
+
+ else {
+ const bool round = (residual << 1) > bSignificand;
+ // Clear the implicit bit
+ rep_t absResult = quotient & significandMask;
+ // Insert the exponent
+ absResult |= (rep_t)writtenExponent << significandBits;
+ // Round
+ absResult += round;
+ // Insert the sign and return
+ const double result = fromRep(absResult | quotientSign);
+ return result;
+ }
+}
diff --git a/lib/divdi3.c b/lib/divdi3.c
new file mode 100644
index 000000000000..fccfb8b09a09
--- /dev/null
+++ b/lib/divdi3.c
@@ -0,0 +1,31 @@
+/* ===-- divdi3.c - Implement __divdi3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __divdi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+du_int __udivmoddi4(du_int a, du_int b, du_int* rem);
+
+/* Returns: a / b */
+
+di_int
+__divdi3(di_int a, di_int b)
+{
+ const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1;
+ di_int s_a = a >> bits_in_dword_m1; /* s_a = a < 0 ? -1 : 0 */
+ di_int s_b = b >> bits_in_dword_m1; /* s_b = b < 0 ? -1 : 0 */
+ a = (a ^ s_a) - s_a; /* negate if s_a == -1 */
+ b = (b ^ s_b) - s_b; /* negate if s_b == -1 */
+ s_a ^= s_b; /*sign of quotient */
+ return (__udivmoddi4(a, b, (du_int*)0) ^ s_a) - s_a; /* negate if s_a == -1 */
+}
diff --git a/lib/divsc3.c b/lib/divsc3.c
new file mode 100644
index 000000000000..c38c8638efb0
--- /dev/null
+++ b/lib/divsc3.c
@@ -0,0 +1,59 @@
+/*===-- divsc3.c - Implement __divsc3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __divsc3 for the compiler_rt library.
+ *
+ *===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+
+/* Returns: the quotient of (a + ib) / (c + id) */
+
+float _Complex
+__divsc3(float __a, float __b, float __c, float __d)
+{
+ int __ilogbw = 0;
+ float __logbw = logbf(fmaxf(fabsf(__c), fabsf(__d)));
+ if (isfinite(__logbw))
+ {
+ __ilogbw = (int)__logbw;
+ __c = scalbnf(__c, -__ilogbw);
+ __d = scalbnf(__d, -__ilogbw);
+ }
+ float __denom = __c * __c + __d * __d;
+ float _Complex z;
+ __real__ z = scalbnf((__a * __c + __b * __d) / __denom, -__ilogbw);
+ __imag__ z = scalbnf((__b * __c - __a * __d) / __denom, -__ilogbw);
+ if (isnan(__real__ z) && isnan(__imag__ z))
+ {
+ if ((__denom == 0) && (!isnan(__a) || !isnan(__b)))
+ {
+ __real__ z = copysignf(INFINITY, __c) * __a;
+ __imag__ z = copysignf(INFINITY, __c) * __b;
+ }
+ else if ((isinf(__a) || isinf(__b)) && isfinite(__c) && isfinite(__d))
+ {
+ __a = copysignf(isinf(__a) ? 1 : 0, __a);
+ __b = copysignf(isinf(__b) ? 1 : 0, __b);
+ __real__ z = INFINITY * (__a * __c + __b * __d);
+ __imag__ z = INFINITY * (__b * __c - __a * __d);
+ }
+ else if (isinf(__logbw) && __logbw > 0 && isfinite(__a) && isfinite(__b))
+ {
+ __c = copysignf(isinf(__c) ? 1 : 0, __c);
+ __d = copysignf(isinf(__d) ? 1 : 0, __d);
+ __real__ z = 0 * (__a * __c + __b * __d);
+ __imag__ z = 0 * (__b * __c - __a * __d);
+ }
+ }
+ return z;
+}
diff --git a/lib/divsf3.c b/lib/divsf3.c
new file mode 100644
index 000000000000..03b7311788bc
--- /dev/null
+++ b/lib/divsf3.c
@@ -0,0 +1,166 @@
+//===-- lib/divsf3.c - Single-precision division ------------------*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements single-precision soft-float division
+// with the IEEE-754 default rounding (to nearest, ties to even).
+//
+// For simplicity, this implementation currently flushes denormals to zero.
+// It should be a fairly straightforward exercise to implement gradual
+// underflow with correct rounding.
+//
+//===----------------------------------------------------------------------===//
+
+#define SINGLE_PRECISION
+#include "fp_lib.h"
+
+fp_t __divsf3(fp_t a, fp_t b) {
+
+ const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;
+ const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;
+ const rep_t quotientSign = (toRep(a) ^ toRep(b)) & signBit;
+
+ rep_t aSignificand = toRep(a) & significandMask;
+ rep_t bSignificand = toRep(b) & significandMask;
+ int scale = 0;
+
+ // Detect if a or b is zero, denormal, infinity, or NaN.
+ if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) {
+
+ const rep_t aAbs = toRep(a) & absMask;
+ const rep_t bAbs = toRep(b) & absMask;
+
+ // NaN / anything = qNaN
+ if (aAbs > infRep) return fromRep(toRep(a) | quietBit);
+ // anything / NaN = qNaN
+ if (bAbs > infRep) return fromRep(toRep(b) | quietBit);
+
+ if (aAbs == infRep) {
+ // infinity / infinity = NaN
+ if (bAbs == infRep) return fromRep(qnanRep);
+ // infinity / anything else = +/- infinity
+ else return fromRep(aAbs | quotientSign);
+ }
+
+ // anything else / infinity = +/- 0
+ if (bAbs == infRep) return fromRep(quotientSign);
+
+ if (!aAbs) {
+ // zero / zero = NaN
+ if (!bAbs) return fromRep(qnanRep);
+ // zero / anything else = +/- zero
+ else return fromRep(quotientSign);
+ }
+ // anything else / zero = +/- infinity
+ if (!bAbs) return fromRep(infRep | quotientSign);
+
+ // one or both of a or b is denormal, the other (if applicable) is a
+ // normal number. Renormalize one or both of a and b, and set scale to
+ // include the necessary exponent adjustment.
+ if (aAbs < implicitBit) scale += normalize(&aSignificand);
+ if (bAbs < implicitBit) scale -= normalize(&bSignificand);
+ }
+
+ // Or in the implicit significand bit. (If we fell through from the
+ // denormal path it was already set by normalize( ), but setting it twice
+ // won't hurt anything.)
+ aSignificand |= implicitBit;
+ bSignificand |= implicitBit;
+ int quotientExponent = aExponent - bExponent + scale;
+
+ // Align the significand of b as a Q31 fixed-point number in the range
+ // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax
+ // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
+ // is accurate to about 3.5 binary digits.
+ uint32_t q31b = bSignificand << 8;
+ uint32_t reciprocal = UINT32_C(0x7504f333) - q31b;
+
+ // Now refine the reciprocal estimate using a Newton-Raphson iteration:
+ //
+ // x1 = x0 * (2 - x0 * b)
+ //
+ // This doubles the number of correct binary digits in the approximation
+ // with each iteration, so after three iterations, we have about 28 binary
+ // digits of accuracy.
+ uint32_t correction;
+ correction = -((uint64_t)reciprocal * q31b >> 32);
+ reciprocal = (uint64_t)reciprocal * correction >> 31;
+ correction = -((uint64_t)reciprocal * q31b >> 32);
+ reciprocal = (uint64_t)reciprocal * correction >> 31;
+ correction = -((uint64_t)reciprocal * q31b >> 32);
+ reciprocal = (uint64_t)reciprocal * correction >> 31;
+
+ // Exhaustive testing shows that the error in reciprocal after three steps
+ // is in the interval [-0x1.f58108p-31, 0x1.d0e48cp-29], in line with our
+ // expectations. We bump the reciprocal by a tiny value to force the error
+ // to be strictly positive (in the range [0x1.4fdfp-37,0x1.287246p-29], to
+ // be specific). This also causes 1/1 to give a sensible approximation
+ // instead of zero (due to overflow).
+ reciprocal -= 2;
+
+ // The numerical reciprocal is accurate to within 2^-28, lies in the
+ // interval [0x1.000000eep-1, 0x1.fffffffcp-1], and is strictly smaller
+ // than the true reciprocal of b. Multiplying a by this reciprocal thus
+ // gives a numerical q = a/b in Q24 with the following properties:
+ //
+ // 1. q < a/b
+ // 2. q is in the interval [0x1.000000eep-1, 0x1.fffffffcp0)
+ // 3. the error in q is at most 2^-24 + 2^-27 -- the 2^24 term comes
+ // from the fact that we truncate the product, and the 2^27 term
+ // is the error in the reciprocal of b scaled by the maximum
+ // possible value of a. As a consequence of this error bound,
+ // either q or nextafter(q) is the correctly rounded
+ rep_t quotient = (uint64_t)reciprocal*(aSignificand << 1) >> 32;
+
+ // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0).
+ // In either case, we are going to compute a residual of the form
+ //
+ // r = a - q*b
+ //
+ // We know from the construction of q that r satisfies:
+ //
+ // 0 <= r < ulp(q)*b
+ //
+ // if r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we
+ // already have the correct result. The exact halfway case cannot occur.
+ // We also take this time to right shift quotient if it falls in the [1,2)
+ // range and adjust the exponent accordingly.
+ rep_t residual;
+ if (quotient < (implicitBit << 1)) {
+ residual = (aSignificand << 24) - quotient * bSignificand;
+ quotientExponent--;
+ } else {
+ quotient >>= 1;
+ residual = (aSignificand << 23) - quotient * bSignificand;
+ }
+
+ const int writtenExponent = quotientExponent + exponentBias;
+
+ if (writtenExponent >= maxExponent) {
+ // If we have overflowed the exponent, return infinity.
+ return fromRep(infRep | quotientSign);
+ }
+
+ else if (writtenExponent < 1) {
+ // Flush denormals to zero. In the future, it would be nice to add
+ // code to round them correctly.
+ return fromRep(quotientSign);
+ }
+
+ else {
+ const bool round = (residual << 1) > bSignificand;
+ // Clear the implicit bit
+ rep_t absResult = quotient & significandMask;
+ // Insert the exponent
+ absResult |= (rep_t)writtenExponent << significandBits;
+ // Round
+ absResult += round;
+ // Insert the sign and return
+ return fromRep(absResult | quotientSign);
+ }
+}
diff --git a/lib/divsi3.c b/lib/divsi3.c
new file mode 100644
index 000000000000..0eff6ef0d735
--- /dev/null
+++ b/lib/divsi3.c
@@ -0,0 +1,31 @@
+/* ===-- divsi3.c - Implement __divsi3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __divsi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+su_int __udivsi3(su_int n, su_int d);
+
+/* Returns: a / b */
+
+si_int
+__divsi3(si_int a, si_int b)
+{
+ const int bits_in_word_m1 = (int)(sizeof(si_int) * CHAR_BIT) - 1;
+ si_int s_a = a >> bits_in_word_m1; /* s_a = a < 0 ? -1 : 0 */
+ si_int s_b = b >> bits_in_word_m1; /* s_b = b < 0 ? -1 : 0 */
+ a = (a ^ s_a) - s_a; /* negate if s_a == -1 */
+ b = (b ^ s_b) - s_b; /* negate if s_b == -1 */
+ s_a ^= s_b; /* sign of quotient */
+ return (__udivsi3(a, b) ^ s_a) - s_a; /* negate if s_a == -1 */
+}
diff --git a/lib/divti3.c b/lib/divti3.c
new file mode 100644
index 000000000000..c752f6cfbe9d
--- /dev/null
+++ b/lib/divti3.c
@@ -0,0 +1,35 @@
+/* ===-- divti3.c - Implement __divti3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __divti3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
+
+/* Returns: a / b */
+
+ti_int
+__divti3(ti_int a, ti_int b)
+{
+ const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1;
+ ti_int s_a = a >> bits_in_tword_m1; /* s_a = a < 0 ? -1 : 0 */
+ ti_int s_b = b >> bits_in_tword_m1; /* s_b = b < 0 ? -1 : 0 */
+ a = (a ^ s_a) - s_a; /* negate if s_a == -1 */
+ b = (b ^ s_b) - s_b; /* negate if s_b == -1 */
+ s_a ^= s_b; /* sign of quotient */
+ return (__udivmodti4(a, b, (tu_int*)0) ^ s_a) - s_a; /* negate if s_a == -1 */
+}
+
+#endif
diff --git a/lib/divxc3.c b/lib/divxc3.c
new file mode 100644
index 000000000000..03357ae552c3
--- /dev/null
+++ b/lib/divxc3.c
@@ -0,0 +1,62 @@
+/* ===-- divxc3.c - Implement __divxc3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __divxc3 for the compiler_rt library.
+ *
+ */
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+
+/* Returns: the quotient of (a + ib) / (c + id) */
+
+long double _Complex
+__divxc3(long double __a, long double __b, long double __c, long double __d)
+{
+ int __ilogbw = 0;
+ long double __logbw = logbl(fmaxl(fabsl(__c), fabsl(__d)));
+ if (isfinite(__logbw))
+ {
+ __ilogbw = (int)__logbw;
+ __c = scalbnl(__c, -__ilogbw);
+ __d = scalbnl(__d, -__ilogbw);
+ }
+ long double __denom = __c * __c + __d * __d;
+ long double _Complex z;
+ __real__ z = scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw);
+ __imag__ z = scalbnl((__b * __c - __a * __d) / __denom, -__ilogbw);
+ if (isnan(__real__ z) && isnan(__imag__ z))
+ {
+ if ((__denom == 0) && (!isnan(__a) || !isnan(__b)))
+ {
+ __real__ z = copysignl(INFINITY, __c) * __a;
+ __imag__ z = copysignl(INFINITY, __c) * __b;
+ }
+ else if ((isinf(__a) || isinf(__b)) && isfinite(__c) && isfinite(__d))
+ {
+ __a = copysignl(isinf(__a) ? 1 : 0, __a);
+ __b = copysignl(isinf(__b) ? 1 : 0, __b);
+ __real__ z = INFINITY * (__a * __c + __b * __d);
+ __imag__ z = INFINITY * (__b * __c - __a * __d);
+ }
+ else if (isinf(__logbw) && __logbw > 0 && isfinite(__a) && isfinite(__b))
+ {
+ __c = copysignl(isinf(__c) ? 1 : 0, __c);
+ __d = copysignl(isinf(__d) ? 1 : 0, __d);
+ __real__ z = 0 * (__a * __c + __b * __d);
+ __imag__ z = 0 * (__b * __c - __a * __d);
+ }
+ }
+ return z;
+}
+
+#endif
diff --git a/lib/enable_execute_stack.c b/lib/enable_execute_stack.c
new file mode 100644
index 000000000000..193e7dbc23bc
--- /dev/null
+++ b/lib/enable_execute_stack.c
@@ -0,0 +1,58 @@
+/* ===-- enable_execute_stack.c - Implement __enable_execute_stack ---------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include <stdint.h>
+#include <sys/mman.h>
+
+/* #include "config.h"
+ * FIXME: CMake - include when cmake system is ready.
+ * Remove #define HAVE_SYSCONF 1 line.
+ */
+#define HAVE_SYSCONF 1
+
+#ifndef __APPLE__
+#include <unistd.h>
+#endif /* __APPLE__ */
+
+#if __LP64__
+ #define TRAMPOLINE_SIZE 48
+#else
+ #define TRAMPOLINE_SIZE 40
+#endif
+
+/*
+ * The compiler generates calls to __enable_execute_stack() when creating
+ * trampoline functions on the stack for use with nested functions.
+ * It is expected to mark the page(s) containing the address
+ * and the next 48 bytes as executable. Since the stack is normally rw-
+ * that means changing the protection on those page(s) to rwx.
+ */
+
+void __enable_execute_stack(void* addr)
+{
+
+#if __APPLE__
+ /* On Darwin, pagesize is always 4096 bytes */
+ const uintptr_t pageSize = 4096;
+#elif !defined(HAVE_SYSCONF)
+#error "HAVE_SYSCONF not defined! See enable_execute_stack.c"
+#else
+ const uintptr_t pageSize = sysconf(_SC_PAGESIZE);
+#endif /* __APPLE__ */
+
+ const uintptr_t pageAlignMask = ~(pageSize-1);
+ uintptr_t p = (uintptr_t)addr;
+ unsigned char* startPage = (unsigned char*)(p & pageAlignMask);
+ unsigned char* endPage = (unsigned char*)((p+TRAMPOLINE_SIZE+pageSize) & pageAlignMask);
+ size_t length = endPage - startPage;
+ (void) mprotect((void *)startPage, length, PROT_READ | PROT_WRITE | PROT_EXEC);
+}
+
+
diff --git a/lib/endianness.h b/lib/endianness.h
new file mode 100644
index 000000000000..6d2587d022e3
--- /dev/null
+++ b/lib/endianness.h
@@ -0,0 +1,94 @@
+/* ===-- endianness.h - configuration header for compiler-rt ---------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file is a configuration header for compiler-rt.
+ * This file is not part of the interface of this library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#ifndef ENDIANNESS_H
+#define ENDIANNESS_H
+
+/*
+ * Known limitations:
+ * Middle endian systems are not handled currently.
+ */
+
+#if defined(__SVR4) && defined(__sun)
+#include <sys/byteorder.h>
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN 1
+#elif _BYTE_ORDER == _LITTLE_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN 0
+#endif /* _BYTE_ORDER */
+
+#endif /* Solaris and AuroraUX. */
+
+/* .. */
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+#include <sys/endian.h>
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN 1
+#elif _BYTE_ORDER == _LITTLE_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN 0
+#endif /* _BYTE_ORDER */
+
+#endif /* *BSD */
+
+/* .. */
+
+/* Mac OSX has __BIG_ENDIAN__ or __LITTLE_ENDIAN__ automatically set by the compiler (at least with GCC) */
+#if defined(__APPLE__) && defined(__MACH__) || defined(__ellcc__ )
+
+#ifdef __BIG_ENDIAN__
+#if __BIG_ENDIAN__
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN 1
+#endif
+#endif /* __BIG_ENDIAN__ */
+
+#ifdef __LITTLE_ENDIAN__
+#if __LITTLE_ENDIAN__
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN 0
+#endif
+#endif /* __LITTLE_ENDIAN__ */
+
+#endif /* Mac OSX */
+
+/* .. */
+
+#if defined(__linux__)
+#include <endian.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN 1
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN 0
+#endif /* __BYTE_ORDER */
+
+#endif /* GNU/Linux */
+
+/* . */
+
+#if !defined(_YUGA_LITTLE_ENDIAN) || !defined(_YUGA_BIG_ENDIAN)
+#error Unable to determine endian
+#endif /* Check we found an endianness correctly. */
+
+#endif /* ENDIANNESS_H */
diff --git a/lib/eprintf.c b/lib/eprintf.c
new file mode 100644
index 000000000000..786fe6aaa672
--- /dev/null
+++ b/lib/eprintf.c
@@ -0,0 +1,33 @@
+/* ===---------- eprintf.c - Implements __eprintf --------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+
+
+#include "int_lib.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/*
+ * __eprintf() was used in an old version of <assert.h>.
+ * It can eventually go away, but it is needed when linking
+ * .o files built with the old <assert.h>.
+ *
+ * It should never be exported from a dylib, so it is marked
+ * visibility hidden.
+ */
+__attribute__((visibility("hidden")))
+void __eprintf(const char* format, const char* assertion_expression,
+ const char* line, const char* file)
+{
+ fprintf(stderr, format, assertion_expression, line, file);
+ fflush(stderr);
+ compilerrt_abort();
+}
diff --git a/lib/extendsfdf2.c b/lib/extendsfdf2.c
new file mode 100644
index 000000000000..025eb9572446
--- /dev/null
+++ b/lib/extendsfdf2.c
@@ -0,0 +1,136 @@
+//===-- lib/extendsfdf2.c - single -> double conversion -----------*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a fairly generic conversion from a narrower to a wider
+// IEEE-754 floating-point type. The constants and types defined following the
+// includes below parameterize the conversion.
+//
+// This routine can be trivially adapted to support conversions from
+// half-precision or to quad-precision. It does not support types that don't
+// use the usual IEEE-754 interchange formats; specifically, some work would be
+// needed to adapt it to (for example) the Intel 80-bit format or PowerPC
+// double-double format.
+//
+// Note please, however, that this implementation is only intended to support
+// *widening* operations; if you need to convert to a *narrower* floating-point
+// type (e.g. double -> float), then this routine will not do what you want it
+// to.
+//
+// It also requires that integer types at least as large as both formats
+// are available on the target platform; this may pose a problem when trying
+// to add support for quad on some 32-bit systems, for example. You also may
+// run into trouble finding an appropriate CLZ function for wide source types;
+// you will likely need to roll your own on some platforms.
+//
+// Finally, the following assumptions are made:
+//
+// 1. floating-point types and integer types have the same endianness on the
+// target platform
+//
+// 2. quiet NaNs, if supported, are indicated by the leading bit of the
+// significand field being set
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdint.h>
+#include <limits.h>
+
+typedef float src_t;
+typedef uint32_t src_rep_t;
+#define SRC_REP_C UINT32_C
+static const int srcSigBits = 23;
+#define src_rep_t_clz __builtin_clz
+
+typedef double dst_t;
+typedef uint64_t dst_rep_t;
+#define DST_REP_C UINT64_C
+static const int dstSigBits = 52;
+
+// End of specialization parameters. Two helper routines for conversion to and
+// from the representation of floating-point data as integer values follow.
+
+static inline src_rep_t srcToRep(src_t x) {
+ const union { src_t f; src_rep_t i; } rep = {.f = x};
+ return rep.i;
+}
+
+static inline dst_t dstFromRep(dst_rep_t x) {
+ const union { dst_t f; dst_rep_t i; } rep = {.i = x};
+ return rep.f;
+}
+
+// End helper routines. Conversion implementation follows.
+
+dst_t __extendsfdf2(src_t a) {
+
+ // Various constants whose values follow from the type parameters.
+ // Any reasonable optimizer will fold and propagate all of these.
+ const int srcBits = sizeof(src_t)*CHAR_BIT;
+ const int srcExpBits = srcBits - srcSigBits - 1;
+ const int srcInfExp = (1 << srcExpBits) - 1;
+ const int srcExpBias = srcInfExp >> 1;
+
+ const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits;
+ const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits;
+ const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits);
+ const src_rep_t srcAbsMask = srcSignMask - 1;
+ const src_rep_t srcQNaN = SRC_REP_C(1) << (srcSigBits - 1);
+ const src_rep_t srcNaNCode = srcQNaN - 1;
+
+ const int dstBits = sizeof(dst_t)*CHAR_BIT;
+ const int dstExpBits = dstBits - dstSigBits - 1;
+ const int dstInfExp = (1 << dstExpBits) - 1;
+ const int dstExpBias = dstInfExp >> 1;
+
+ const dst_rep_t dstMinNormal = DST_REP_C(1) << dstSigBits;
+
+ // Break a into a sign and representation of the absolute value
+ const src_rep_t aRep = srcToRep(a);
+ const src_rep_t aAbs = aRep & srcAbsMask;
+ const src_rep_t sign = aRep & srcSignMask;
+ dst_rep_t absResult;
+
+ if (aAbs - srcMinNormal < srcInfinity - srcMinNormal) {
+ // a is a normal number.
+ // Extend to the destination type by shifting the significand and
+ // exponent into the proper position and rebiasing the exponent.
+ absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits);
+ absResult += (dst_rep_t)(dstExpBias - srcExpBias) << dstSigBits;
+ }
+
+ else if (aAbs >= srcInfinity) {
+ // a is NaN or infinity.
+ // Conjure the result by beginning with infinity, then setting the qNaN
+ // bit (if needed) and right-aligning the rest of the trailing NaN
+ // payload field.
+ absResult = (dst_rep_t)dstInfExp << dstSigBits;
+ absResult |= (dst_rep_t)(aAbs & srcQNaN) << (dstSigBits - srcSigBits);
+ absResult |= aAbs & srcNaNCode;
+ }
+
+ else if (aAbs) {
+ // a is denormal.
+ // renormalize the significand and clear the leading bit, then insert
+ // the correct adjusted exponent in the destination type.
+ const int scale = src_rep_t_clz(aAbs) - src_rep_t_clz(srcMinNormal);
+ absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits + scale);
+ absResult ^= dstMinNormal;
+ const int resultExponent = dstExpBias - srcExpBias - scale + 1;
+ absResult |= (dst_rep_t)resultExponent << dstSigBits;
+ }
+
+ else {
+ // a is zero.
+ absResult = 0;
+ }
+
+ // Apply the signbit to (dst_t)abs(a).
+ const dst_rep_t result = absResult | (dst_rep_t)sign << (dstBits - srcBits);
+ return dstFromRep(result);
+}
diff --git a/lib/ffsdi2.c b/lib/ffsdi2.c
new file mode 100644
index 000000000000..8c03d19afcc6
--- /dev/null
+++ b/lib/ffsdi2.c
@@ -0,0 +1,33 @@
+/* ===-- ffsdi2.c - Implement __ffsdi2 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __ffsdi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: the index of the least significant 1-bit in a, or
+ * the value zero if a is zero. The least significant bit is index one.
+ */
+
+si_int
+__ffsdi2(di_int a)
+{
+ dwords x;
+ x.all = a;
+ if (x.s.low == 0)
+ {
+ if (x.s.high == 0)
+ return 0;
+ return __builtin_ctz(x.s.high) + (1 + sizeof(si_int) * CHAR_BIT);
+ }
+ return __builtin_ctz(x.s.low) + 1;
+}
diff --git a/lib/ffsti2.c b/lib/ffsti2.c
new file mode 100644
index 000000000000..0139eb1f7576
--- /dev/null
+++ b/lib/ffsti2.c
@@ -0,0 +1,37 @@
+/* ===-- ffsti2.c - Implement __ffsti2 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __ffsti2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: the index of the least significant 1-bit in a, or
+ * the value zero if a is zero. The least significant bit is index one.
+ */
+
+si_int
+__ffsti2(ti_int a)
+{
+ twords x;
+ x.all = a;
+ if (x.s.low == 0)
+ {
+ if (x.s.high == 0)
+ return 0;
+ return __builtin_ctzll(x.s.high) + (1 + sizeof(di_int) * CHAR_BIT);
+ }
+ return __builtin_ctzll(x.s.low) + 1;
+}
+
+#endif /* __x86_64 */
diff --git a/lib/fixdfdi.c b/lib/fixdfdi.c
new file mode 100644
index 000000000000..3d3116c1811b
--- /dev/null
+++ b/lib/fixdfdi.c
@@ -0,0 +1,43 @@
+/* ===-- fixdfdi.c - Implement __fixdfdi -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixdfdi for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: convert a to a signed long long, rounding toward zero. */
+
+/* Assumption: double is a IEEE 64 bit floating point type
+ * su_int is a 32 bit integral type
+ * value in double is representable in di_int (no range checking performed)
+ */
+
+/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+
+di_int
+__fixdfdi(double a)
+{
+ double_bits fb;
+ fb.f = a;
+ int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
+ if (e < 0)
+ return 0;
+ di_int s = (si_int)(fb.u.s.high & 0x80000000) >> 31;
+ dwords r;
+ r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000;
+ r.s.low = fb.u.s.low;
+ if (e > 52)
+ r.all <<= (e - 52);
+ else
+ r.all >>= (52 - e);
+ return (r.all ^ s) - s;
+}
diff --git a/lib/fixdfsi.c b/lib/fixdfsi.c
new file mode 100644
index 000000000000..7d17aeddeb48
--- /dev/null
+++ b/lib/fixdfsi.c
@@ -0,0 +1,45 @@
+//===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements double-precision to integer conversion for the
+// compiler-rt library. No range checking is performed; the behavior of this
+// conversion is undefined for out of range values in the C standard.
+//
+//===----------------------------------------------------------------------===//
+
+#define DOUBLE_PRECISION
+#include "fp_lib.h"
+
+int __fixdfsi(fp_t a) {
+
+ // Break a into sign, exponent, significand
+ const rep_t aRep = toRep(a);
+ const rep_t aAbs = aRep & absMask;
+ const int sign = aRep & signBit ? -1 : 1;
+ const int exponent = (aAbs >> significandBits) - exponentBias;
+ const rep_t significand = (aAbs & significandMask) | implicitBit;
+
+ // If 0 < exponent < significandBits, right shift to get the result.
+ if ((unsigned int)exponent < significandBits) {
+ return sign * (significand >> (significandBits - exponent));
+ }
+
+ // If exponent is negative, the result is zero.
+ else if (exponent < 0) {
+ return 0;
+ }
+
+ // If significandBits < exponent, left shift to get the result. This shift
+ // may end up being larger than the type width, which incurs undefined
+ // behavior, but the conversion itself is undefined in that case, so
+ // whatever the compiler decides to do is fine.
+ else {
+ return sign * (significand << (exponent - significandBits));
+ }
+}
diff --git a/lib/fixdfti.c b/lib/fixdfti.c
new file mode 100644
index 000000000000..359b84eaecef
--- /dev/null
+++ b/lib/fixdfti.c
@@ -0,0 +1,45 @@
+/* ===-- fixdfti.c - Implement __fixdfti -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixdfti for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: convert a to a signed long long, rounding toward zero. */
+
+/* Assumption: double is a IEEE 64 bit floating point type
+ * su_int is a 32 bit integral type
+ * value in double is representable in ti_int (no range checking performed)
+ */
+
+/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+
+ti_int
+__fixdfti(double a)
+{
+ double_bits fb;
+ fb.f = a;
+ int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
+ if (e < 0)
+ return 0;
+ ti_int s = (si_int)(fb.u.s.high & 0x80000000) >> 31;
+ ti_int r = 0x0010000000000000uLL | (0x000FFFFFFFFFFFFFuLL & fb.u.all);
+ if (e > 52)
+ r <<= (e - 52);
+ else
+ r >>= (52 - e);
+ return (r ^ s) - s;
+}
+
+#endif
diff --git a/lib/fixsfdi.c b/lib/fixsfdi.c
new file mode 100644
index 000000000000..08f1524e152a
--- /dev/null
+++ b/lib/fixsfdi.c
@@ -0,0 +1,41 @@
+/* ===-- fixsfdi.c - Implement __fixsfdi -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixsfdi for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: convert a to a signed long long, rounding toward zero. */
+
+/* Assumption: float is a IEEE 32 bit floating point type
+ * su_int is a 32 bit integral type
+ * value in float is representable in di_int (no range checking performed)
+ */
+
+/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+
+di_int
+__fixsfdi(float a)
+{
+ float_bits fb;
+ fb.f = a;
+ int e = ((fb.u & 0x7F800000) >> 23) - 127;
+ if (e < 0)
+ return 0;
+ di_int s = (si_int)(fb.u & 0x80000000) >> 31;
+ di_int r = (fb.u & 0x007FFFFF) | 0x00800000;
+ if (e > 23)
+ r <<= (e - 23);
+ else
+ r >>= (23 - e);
+ return (r ^ s) - s;
+}
diff --git a/lib/fixsfsi.c b/lib/fixsfsi.c
new file mode 100644
index 000000000000..ff79377198f4
--- /dev/null
+++ b/lib/fixsfsi.c
@@ -0,0 +1,45 @@
+//===-- lib/fixsfsi.c - Single-precision -> integer conversion ----*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements single-precision to integer conversion for the
+// compiler-rt library. No range checking is performed; the behavior of this
+// conversion is undefined for out of range values in the C standard.
+//
+//===----------------------------------------------------------------------===//
+
+#define SINGLE_PRECISION
+#include "fp_lib.h"
+
+int __fixsfsi(fp_t a) {
+
+ // Break a into sign, exponent, significand
+ const rep_t aRep = toRep(a);
+ const rep_t aAbs = aRep & absMask;
+ const int sign = aRep & signBit ? -1 : 1;
+ const int exponent = (aAbs >> significandBits) - exponentBias;
+ const rep_t significand = (aAbs & significandMask) | implicitBit;
+
+ // If 0 < exponent < significandBits, right shift to get the result.
+ if ((unsigned int)exponent < significandBits) {
+ return sign * (significand >> (significandBits - exponent));
+ }
+
+ // If exponent is negative, the result is zero.
+ else if (exponent < 0) {
+ return 0;
+ }
+
+ // If significandBits < exponent, left shift to get the result. This shift
+ // may end up being larger than the type width, which incurs undefined
+ // behavior, but the conversion itself is undefined in that case, so
+ // whatever the compiler decides to do is fine.
+ else {
+ return sign * (significand << (exponent - significandBits));
+ }
+}
diff --git a/lib/fixsfti.c b/lib/fixsfti.c
new file mode 100644
index 000000000000..95992fe3f48e
--- /dev/null
+++ b/lib/fixsfti.c
@@ -0,0 +1,45 @@
+/* ===-- fixsfti.c - Implement __fixsfti -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixsfti for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: convert a to a signed long long, rounding toward zero. */
+
+/* Assumption: float is a IEEE 32 bit floating point type
+ * su_int is a 32 bit integral type
+ * value in float is representable in ti_int (no range checking performed)
+ */
+
+/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+
+ti_int
+__fixsfti(float a)
+{
+ float_bits fb;
+ fb.f = a;
+ int e = ((fb.u & 0x7F800000) >> 23) - 127;
+ if (e < 0)
+ return 0;
+ ti_int s = (si_int)(fb.u & 0x80000000) >> 31;
+ ti_int r = (fb.u & 0x007FFFFF) | 0x00800000;
+ if (e > 23)
+ r <<= (e - 23);
+ else
+ r >>= (23 - e);
+ return (r ^ s) - s;
+}
+
+#endif
diff --git a/lib/fixunsdfdi.c b/lib/fixunsdfdi.c
new file mode 100644
index 000000000000..bdcee13e80ba
--- /dev/null
+++ b/lib/fixunsdfdi.c
@@ -0,0 +1,45 @@
+/* ===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixunsdfdi for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: convert a to a unsigned long long, rounding toward zero.
+ * Negative values all become zero.
+ */
+
+/* Assumption: double is a IEEE 64 bit floating point type
+ * du_int is a 64 bit integral type
+ * value in double is representable in du_int or is negative
+ * (no range checking performed)
+ */
+
+/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+
+du_int
+__fixunsdfdi(double a)
+{
+ double_bits fb;
+ fb.f = a;
+ int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
+ if (e < 0 || (fb.u.s.high & 0x80000000))
+ return 0;
+ udwords r;
+ r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000;
+ r.s.low = fb.u.s.low;
+ if (e > 52)
+ r.all <<= (e - 52);
+ else
+ r.all >>= (52 - e);
+ return r.all;
+}
diff --git a/lib/fixunsdfsi.c b/lib/fixunsdfsi.c
new file mode 100644
index 000000000000..a0cba79aabb9
--- /dev/null
+++ b/lib/fixunsdfsi.c
@@ -0,0 +1,42 @@
+/* ===-- fixunsdfsi.c - Implement __fixunsdfsi -----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixunsdfsi for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: convert a to a unsigned int, rounding toward zero.
+ * Negative values all become zero.
+ */
+
+/* Assumption: double is a IEEE 64 bit floating point type
+ * su_int is a 32 bit integral type
+ * value in double is representable in su_int or is negative
+ * (no range checking performed)
+ */
+
+/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+
+su_int
+__fixunsdfsi(double a)
+{
+ double_bits fb;
+ fb.f = a;
+ int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
+ if (e < 0 || (fb.u.s.high & 0x80000000))
+ return 0;
+ return (
+ 0x80000000u |
+ ((fb.u.s.high & 0x000FFFFF) << 11) |
+ (fb.u.s.low >> 21)
+ ) >> (31 - e);
+}
diff --git a/lib/fixunsdfti.c b/lib/fixunsdfti.c
new file mode 100644
index 000000000000..c1cd72deca2f
--- /dev/null
+++ b/lib/fixunsdfti.c
@@ -0,0 +1,47 @@
+/* ===-- fixunsdfti.c - Implement __fixunsdfti -----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixunsdfti for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: convert a to a unsigned long long, rounding toward zero.
+ * Negative values all become zero.
+ */
+
+/* Assumption: double is a IEEE 64 bit floating point type
+ * tu_int is a 64 bit integral type
+ * value in double is representable in tu_int or is negative
+ * (no range checking performed)
+ */
+
+/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+
+tu_int
+__fixunsdfti(double a)
+{
+ double_bits fb;
+ fb.f = a;
+ int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
+ if (e < 0 || (fb.u.s.high & 0x80000000))
+ return 0;
+ tu_int r = 0x0010000000000000uLL | (fb.u.all & 0x000FFFFFFFFFFFFFuLL);
+ if (e > 52)
+ r <<= (e - 52);
+ else
+ r >>= (52 - e);
+ return r;
+}
+
+#endif
diff --git a/lib/fixunssfdi.c b/lib/fixunssfdi.c
new file mode 100644
index 000000000000..3837bd890e69
--- /dev/null
+++ b/lib/fixunssfdi.c
@@ -0,0 +1,43 @@
+/* ===-- fixunssfdi.c - Implement __fixunssfdi -----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixunssfdi for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: convert a to a unsigned long long, rounding toward zero.
+ * Negative values all become zero.
+ */
+
+/* Assumption: float is a IEEE 32 bit floating point type
+ * du_int is a 64 bit integral type
+ * value in float is representable in du_int or is negative
+ * (no range checking performed)
+ */
+
+/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+
+du_int
+__fixunssfdi(float a)
+{
+ float_bits fb;
+ fb.f = a;
+ int e = ((fb.u & 0x7F800000) >> 23) - 127;
+ if (e < 0 || (fb.u & 0x80000000))
+ return 0;
+ du_int r = (fb.u & 0x007FFFFF) | 0x00800000;
+ if (e > 23)
+ r <<= (e - 23);
+ else
+ r >>= (23 - e);
+ return r;
+}
diff --git a/lib/fixunssfsi.c b/lib/fixunssfsi.c
new file mode 100644
index 000000000000..a001cd48196b
--- /dev/null
+++ b/lib/fixunssfsi.c
@@ -0,0 +1,43 @@
+/* ===-- fixunssfsi.c - Implement __fixunssfsi -----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixunssfsi for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: convert a to a unsigned int, rounding toward zero.
+ * Negative values all become zero.
+ */
+
+/* Assumption: float is a IEEE 32 bit floating point type
+ * su_int is a 32 bit integral type
+ * value in float is representable in su_int or is negative
+ * (no range checking performed)
+ */
+
+/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+
+su_int
+__fixunssfsi(float a)
+{
+ float_bits fb;
+ fb.f = a;
+ int e = ((fb.u & 0x7F800000) >> 23) - 127;
+ if (e < 0 || (fb.u & 0x80000000))
+ return 0;
+ su_int r = (fb.u & 0x007FFFFF) | 0x00800000;
+ if (e > 23)
+ r <<= (e - 23);
+ else
+ r >>= (23 - e);
+ return r;
+}
diff --git a/lib/fixunssfti.c b/lib/fixunssfti.c
new file mode 100644
index 000000000000..20b7e760547a
--- /dev/null
+++ b/lib/fixunssfti.c
@@ -0,0 +1,47 @@
+/* ===-- fixunssfti.c - Implement __fixunssfti -----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixunssfti for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: convert a to a unsigned long long, rounding toward zero.
+ * Negative values all become zero.
+ */
+
+/* Assumption: float is a IEEE 32 bit floating point type
+ * tu_int is a 64 bit integral type
+ * value in float is representable in tu_int or is negative
+ * (no range checking performed)
+ */
+
+/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+
+tu_int
+__fixunssfti(float a)
+{
+ float_bits fb;
+ fb.f = a;
+ int e = ((fb.u & 0x7F800000) >> 23) - 127;
+ if (e < 0 || (fb.u & 0x80000000))
+ return 0;
+ tu_int r = (fb.u & 0x007FFFFF) | 0x00800000;
+ if (e > 23)
+ r <<= (e - 23);
+ else
+ r >>= (23 - e);
+ return r;
+}
+
+#endif
diff --git a/lib/fixunsxfdi.c b/lib/fixunsxfdi.c
new file mode 100644
index 000000000000..872727bcd3df
--- /dev/null
+++ b/lib/fixunsxfdi.c
@@ -0,0 +1,44 @@
+/* ===-- fixunsxfdi.c - Implement __fixunsxfdi -----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixunsxfdi for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+
+/* Returns: convert a to a unsigned long long, rounding toward zero.
+ * Negative values all become zero.
+ */
+
+/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+ * du_int is a 64 bit integral type
+ * value in long double is representable in du_int or is negative
+ * (no range checking performed)
+ */
+
+/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+ * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+ */
+
+du_int
+__fixunsxfdi(long double a)
+{
+ long_double_bits fb;
+ fb.f = a;
+ int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
+ if (e < 0 || (fb.u.high.s.low & 0x00008000))
+ return 0;
+ return fb.u.low.all >> (63 - e);
+}
+
+#endif
diff --git a/lib/fixunsxfsi.c b/lib/fixunsxfsi.c
new file mode 100644
index 000000000000..c9a607ace6d0
--- /dev/null
+++ b/lib/fixunsxfsi.c
@@ -0,0 +1,44 @@
+/* ===-- fixunsxfsi.c - Implement __fixunsxfsi -----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixunsxfsi for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+
+/* Returns: convert a to a unsigned int, rounding toward zero.
+ * Negative values all become zero.
+ */
+
+/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+ * su_int is a 32 bit integral type
+ * value in long double is representable in su_int or is negative
+ * (no range checking performed)
+ */
+
+/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+ * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+ */
+
+su_int
+__fixunsxfsi(long double a)
+{
+ long_double_bits fb;
+ fb.f = a;
+ int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
+ if (e < 0 || (fb.u.high.s.low & 0x00008000))
+ return 0;
+ return fb.u.low.s.high >> (31 - e);
+}
+
+#endif /* !_ARCH_PPC */
diff --git a/lib/fixunsxfti.c b/lib/fixunsxfti.c
new file mode 100644
index 000000000000..d0bd512c4d41
--- /dev/null
+++ b/lib/fixunsxfti.c
@@ -0,0 +1,49 @@
+/* ===-- fixunsxfti.c - Implement __fixunsxfti -----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixunsxfti for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: convert a to a unsigned long long, rounding toward zero.
+ * Negative values all become zero.
+ */
+
+/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+ * tu_int is a 64 bit integral type
+ * value in long double is representable in tu_int or is negative
+ * (no range checking performed)
+ */
+
+/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+ * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+ */
+
+tu_int
+__fixunsxfti(long double a)
+{
+ long_double_bits fb;
+ fb.f = a;
+ int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
+ if (e < 0 || (fb.u.high.s.low & 0x00008000))
+ return 0;
+ tu_int r = fb.u.low.all;
+ if (e > 63)
+ r <<= (e - 63);
+ else
+ r >>= (63 - e);
+ return r;
+}
+
+#endif
diff --git a/lib/fixxfdi.c b/lib/fixxfdi.c
new file mode 100644
index 000000000000..de6f818b8cda
--- /dev/null
+++ b/lib/fixxfdi.c
@@ -0,0 +1,44 @@
+/* ===-- fixxfdi.c - Implement __fixxfdi -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixxfdi for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+
+/* Returns: convert a to a signed long long, rounding toward zero. */
+
+/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+ * su_int is a 32 bit integral type
+ * value in long double is representable in di_int (no range checking performed)
+ */
+
+/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+ * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+ */
+
+di_int
+__fixxfdi(long double a)
+{
+ long_double_bits fb;
+ fb.f = a;
+ int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
+ if (e < 0)
+ return 0;
+ di_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15);
+ di_int r = fb.u.low.all;
+ r = (du_int)r >> (63 - e);
+ return (r ^ s) - s;
+}
+
+#endif /* !_ARCH_PPC */
diff --git a/lib/fixxfti.c b/lib/fixxfti.c
new file mode 100644
index 000000000000..c2248016c85c
--- /dev/null
+++ b/lib/fixxfti.c
@@ -0,0 +1,47 @@
+/* ===-- fixxfti.c - Implement __fixxfti -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixxfti for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: convert a to a signed long long, rounding toward zero. */
+
+/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
+ * su_int is a 32 bit integral type
+ * value in long double is representable in ti_int (no range checking performed)
+ */
+
+/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+ * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+ */
+
+ti_int
+__fixxfti(long double a)
+{
+ long_double_bits fb;
+ fb.f = a;
+ int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
+ if (e < 0)
+ return 0;
+ ti_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15);
+ ti_int r = fb.u.low.all;
+ if (e > 63)
+ r <<= (e - 63);
+ else
+ r >>= (63 - e);
+ return (r ^ s) - s;
+}
+
+#endif /* __x86_64 */
diff --git a/lib/floatdidf.c b/lib/floatdidf.c
new file mode 100644
index 000000000000..a0f501b60fff
--- /dev/null
+++ b/lib/floatdidf.c
@@ -0,0 +1,107 @@
+/*===-- floatdidf.c - Implement __floatdidf -------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ *===----------------------------------------------------------------------===
+ *
+ * This file implements __floatdidf for the compiler_rt library.
+ *
+ *===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <float.h>
+
+/* Returns: convert a to a double, rounding toward even. */
+
+/* Assumption: double is a IEEE 64 bit floating point type
+ * di_int is a 64 bit integral type
+ */
+
+/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+
+#ifndef __SOFT_FP__
+/* Support for systems that have hardware floating-point; we'll set the inexact flag
+ * as a side-effect of this computation.
+ */
+#include <stdint.h>
+
+double
+__floatdidf(di_int a)
+{
+ static const double twop52 = 0x1.0p52;
+ static const double twop32 = 0x1.0p32;
+
+ union { int64_t x; double d; } low = { .d = twop52 };
+
+ const double high = (int32_t)(a >> 32) * twop32;
+ low.x |= a & INT64_C(0x00000000ffffffff);
+
+ const double result = (high - twop52) + low.d;
+ return result;
+}
+
+#else
+/* Support for systems that don't have hardware floating-point; there are no flags to
+ * set, and we don't want to code-gen to an unknown soft-float implementation.
+ */
+
+double
+__floatdidf(di_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(di_int) * CHAR_BIT;
+ const di_int s = a >> (N-1);
+ a = (a ^ s) - s;
+ int sd = N - __builtin_clzll(a); /* number of significant digits */
+ int e = sd - 1; /* exponent */
+ if (sd > DBL_MANT_DIG)
+ {
+ /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ * 12345678901234567890123456
+ * 1 = msb 1 bit
+ * P = bit DBL_MANT_DIG-1 bits to the right of 1
+ * Q = bit DBL_MANT_DIG bits to the right of 1
+ * R = "or" of all bits to the right of Q
+ */
+ switch (sd)
+ {
+ case DBL_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case DBL_MANT_DIG + 2:
+ break;
+ default:
+ a = ((du_int)a >> (sd - (DBL_MANT_DIG+2))) |
+ ((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);
+ };
+ /* finish: */
+ a |= (a & 4) != 0; /* Or P into R */
+ ++a; /* round - this step may add a significant bit */
+ a >>= 2; /* dump Q and R */
+ /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */
+ if (a & ((du_int)1 << DBL_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ /* a is now rounded to DBL_MANT_DIG bits */
+ }
+ else
+ {
+ a <<= (DBL_MANT_DIG - sd);
+ /* a is now rounded to DBL_MANT_DIG bits */
+ }
+ double_bits fb;
+ fb.u.high = ((su_int)s & 0x80000000) | /* sign */
+ ((e + 1023) << 20) | /* exponent */
+ ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */
+ fb.u.low = (su_int)a; /* mantissa-low */
+ return fb.f;
+}
+#endif
diff --git a/lib/floatdisf.c b/lib/floatdisf.c
new file mode 100644
index 000000000000..1925f1588c5d
--- /dev/null
+++ b/lib/floatdisf.c
@@ -0,0 +1,79 @@
+/*===-- floatdisf.c - Implement __floatdisf -------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ *===----------------------------------------------------------------------===
+ *
+ * This file implements __floatdisf for the compiler_rt library.
+ *
+ *===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <float.h>
+
+/* Returns: convert a to a float, rounding toward even.*/
+
+/* Assumption: float is a IEEE 32 bit floating point type
+ * di_int is a 64 bit integral type
+ */
+
+/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+
+float
+__floatdisf(di_int a)
+{
+ if (a == 0)
+ return 0.0F;
+ const unsigned N = sizeof(di_int) * CHAR_BIT;
+ const di_int s = a >> (N-1);
+ a = (a ^ s) - s;
+ int sd = N - __builtin_clzll(a); /* number of significant digits */
+ int e = sd - 1; /* exponent */
+ if (sd > FLT_MANT_DIG)
+ {
+ /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ * 12345678901234567890123456
+ * 1 = msb 1 bit
+ * P = bit FLT_MANT_DIG-1 bits to the right of 1
+ * Q = bit FLT_MANT_DIG bits to the right of 1
+ * R = "or" of all bits to the right of Q
+ */
+ switch (sd)
+ {
+ case FLT_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case FLT_MANT_DIG + 2:
+ break;
+ default:
+ a = ((du_int)a >> (sd - (FLT_MANT_DIG+2))) |
+ ((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);
+ };
+ /* finish: */
+ a |= (a & 4) != 0; /* Or P into R */
+ ++a; /* round - this step may add a significant bit */
+ a >>= 2; /* dump Q and R */
+ /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */
+ if (a & ((du_int)1 << FLT_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ /* a is now rounded to FLT_MANT_DIG bits */
+ }
+ else
+ {
+ a <<= (FLT_MANT_DIG - sd);
+ /* a is now rounded to FLT_MANT_DIG bits */
+ }
+ float_bits fb;
+ fb.u = ((su_int)s & 0x80000000) | /* sign */
+ ((e + 127) << 23) | /* exponent */
+ ((su_int)a & 0x007FFFFF); /* mantissa */
+ return fb.f;
+}
diff --git a/lib/floatdixf.c b/lib/floatdixf.c
new file mode 100644
index 000000000000..bfda367dfeca
--- /dev/null
+++ b/lib/floatdixf.c
@@ -0,0 +1,46 @@
+/* ===-- floatdixf.c - Implement __floatdixf -------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __floatdixf for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+
+/* Returns: convert a to a long double, rounding toward even. */
+
+/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
+ * di_int is a 64 bit integral type
+ */
+
+/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+ * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+ */
+
+long double
+__floatdixf(di_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(di_int) * CHAR_BIT;
+ const di_int s = a >> (N-1);
+ a = (a ^ s) - s;
+ int clz = __builtin_clzll(a);
+ int e = (N - 1) - clz ; /* exponent */
+ long_double_bits fb;
+ fb.u.high.s.low = ((su_int)s & 0x00008000) | /* sign */
+ (e + 16383); /* exponent */
+ fb.u.low.all = a << clz; /* mantissa */
+ return fb.f;
+}
+
+#endif /* !_ARCH_PPC */
diff --git a/lib/floatsidf.c b/lib/floatsidf.c
new file mode 100644
index 000000000000..a13ab8fbcfb5
--- /dev/null
+++ b/lib/floatsidf.c
@@ -0,0 +1,48 @@
+//===-- lib/floatsidf.c - integer -> double-precision conversion --*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements integer to double-precision conversion for the
+// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
+// mode.
+//
+//===----------------------------------------------------------------------===//
+
+#define DOUBLE_PRECISION
+#include "fp_lib.h"
+
+fp_t __floatsidf(int a) {
+
+ const int aWidth = sizeof a * CHAR_BIT;
+
+ // Handle zero as a special case to protect clz
+ if (a == 0)
+ return fromRep(0);
+
+ // All other cases begin by extracting the sign and absolute value of a
+ rep_t sign = 0;
+ if (a < 0) {
+ sign = signBit;
+ a = -a;
+ }
+
+ // Exponent of (fp_t)a is the width of abs(a).
+ const int exponent = (aWidth - 1) - __builtin_clz(a);
+ rep_t result;
+
+ // Shift a into the significand field and clear the implicit bit. Extra
+ // cast to unsigned int is necessary to get the correct behavior for
+ // the input INT_MIN.
+ const int shift = significandBits - exponent;
+ result = (rep_t)(unsigned int)a << shift ^ implicitBit;
+
+ // Insert the exponent
+ result += (rep_t)(exponent + exponentBias) << significandBits;
+ // Insert the sign bit and return
+ return fromRep(result | sign);
+}
diff --git a/lib/floatsisf.c b/lib/floatsisf.c
new file mode 100644
index 000000000000..4a629755e783
--- /dev/null
+++ b/lib/floatsisf.c
@@ -0,0 +1,54 @@
+//===-- lib/floatsisf.c - integer -> single-precision conversion --*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements integer to single-precision conversion for the
+// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
+// mode.
+//
+//===----------------------------------------------------------------------===//
+
+#define SINGLE_PRECISION
+#include "fp_lib.h"
+
+fp_t __floatsisf(int a) {
+
+ const int aWidth = sizeof a * CHAR_BIT;
+
+ // Handle zero as a special case to protect clz
+ if (a == 0)
+ return fromRep(0);
+
+ // All other cases begin by extracting the sign and absolute value of a
+ rep_t sign = 0;
+ if (a < 0) {
+ sign = signBit;
+ a = -a;
+ }
+
+ // Exponent of (fp_t)a is the width of abs(a).
+ const int exponent = (aWidth - 1) - __builtin_clz(a);
+ rep_t result;
+
+ // Shift a into the significand field, rounding if it is a right-shift
+ if (exponent <= significandBits) {
+ const int shift = significandBits - exponent;
+ result = (rep_t)a << shift ^ implicitBit;
+ } else {
+ const int shift = exponent - significandBits;
+ result = (rep_t)a >> shift ^ implicitBit;
+ rep_t round = (rep_t)a << (typeWidth - shift);
+ if (round > signBit) result++;
+ if (round == signBit) result += result & 1;
+ }
+
+ // Insert the exponent
+ result += (rep_t)(exponent + exponentBias) << significandBits;
+ // Insert the sign bit and return
+ return fromRep(result | sign);
+}
diff --git a/lib/floattidf.c b/lib/floattidf.c
new file mode 100644
index 000000000000..274f58517c4e
--- /dev/null
+++ b/lib/floattidf.c
@@ -0,0 +1,86 @@
+/* ===-- floattidf.c - Implement __floattidf -------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __floattidf for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+
+/* Returns: convert a to a double, rounding toward even.*/
+
+/* Assumption: double is a IEEE 64 bit floating point type
+ * ti_int is a 128 bit integral type
+ */
+
+/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+
+si_int __clzti2(ti_int a);
+
+double
+__floattidf(ti_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(ti_int) * CHAR_BIT;
+ const ti_int s = a >> (N-1);
+ a = (a ^ s) - s;
+ int sd = N - __clzti2(a); /* number of significant digits */
+ int e = sd - 1; /* exponent */
+ if (sd > DBL_MANT_DIG)
+ {
+ /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ * 12345678901234567890123456
+ * 1 = msb 1 bit
+ * P = bit DBL_MANT_DIG-1 bits to the right of 1
+ * Q = bit DBL_MANT_DIG bits to the right of 1
+ * R = "or" of all bits to the right of Q
+ */
+ switch (sd)
+ {
+ case DBL_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case DBL_MANT_DIG + 2:
+ break;
+ default:
+ a = ((tu_int)a >> (sd - (DBL_MANT_DIG+2))) |
+ ((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);
+ };
+ /* finish: */
+ a |= (a & 4) != 0; /* Or P into R */
+ ++a; /* round - this step may add a significant bit */
+ a >>= 2; /* dump Q and R */
+ /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */
+ if (a & ((tu_int)1 << DBL_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ /* a is now rounded to DBL_MANT_DIG bits */
+ }
+ else
+ {
+ a <<= (DBL_MANT_DIG - sd);
+ /* a is now rounded to DBL_MANT_DIG bits */
+ }
+ double_bits fb;
+ fb.u.s.high = ((su_int)s & 0x80000000) | /* sign */
+ ((e + 1023) << 20) | /* exponent */
+ ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */
+ fb.u.s.low = (su_int)a; /* mantissa-low */
+ return fb.f;
+}
+
+#endif
diff --git a/lib/floattisf.c b/lib/floattisf.c
new file mode 100644
index 000000000000..72f37481b3a2
--- /dev/null
+++ b/lib/floattisf.c
@@ -0,0 +1,85 @@
+/* ===-- floattisf.c - Implement __floattisf -------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __floattisf for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+
+/* Returns: convert a to a float, rounding toward even. */
+
+/* Assumption: float is a IEEE 32 bit floating point type
+ * ti_int is a 128 bit integral type
+ */
+
+/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+
+si_int __clzti2(ti_int a);
+
+float
+__floattisf(ti_int a)
+{
+ if (a == 0)
+ return 0.0F;
+ const unsigned N = sizeof(ti_int) * CHAR_BIT;
+ const ti_int s = a >> (N-1);
+ a = (a ^ s) - s;
+ int sd = N - __clzti2(a); /* number of significant digits */
+ int e = sd - 1; /* exponent */
+ if (sd > FLT_MANT_DIG)
+ {
+ /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ * 12345678901234567890123456
+ * 1 = msb 1 bit
+ * P = bit FLT_MANT_DIG-1 bits to the right of 1
+ * Q = bit FLT_MANT_DIG bits to the right of 1
+ * R = "or" of all bits to the right of Q
+ */
+ switch (sd)
+ {
+ case FLT_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case FLT_MANT_DIG + 2:
+ break;
+ default:
+ a = ((tu_int)a >> (sd - (FLT_MANT_DIG+2))) |
+ ((a & ((tu_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);
+ };
+ /* finish: */
+ a |= (a & 4) != 0; /* Or P into R */
+ ++a; /* round - this step may add a significant bit */
+ a >>= 2; /* dump Q and R */
+ /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */
+ if (a & ((tu_int)1 << FLT_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ /* a is now rounded to FLT_MANT_DIG bits */
+ }
+ else
+ {
+ a <<= (FLT_MANT_DIG - sd);
+ /* a is now rounded to FLT_MANT_DIG bits */
+ }
+ float_bits fb;
+ fb.u = ((su_int)s & 0x80000000) | /* sign */
+ ((e + 127) << 23) | /* exponent */
+ ((su_int)a & 0x007FFFFF); /* mantissa */
+ return fb.f;
+}
+
+#endif
diff --git a/lib/floattixf.c b/lib/floattixf.c
new file mode 100644
index 000000000000..77d906049be6
--- /dev/null
+++ b/lib/floattixf.c
@@ -0,0 +1,87 @@
+/* ===-- floattixf.c - Implement __floattixf -------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __floattixf for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+
+/* Returns: convert a to a long double, rounding toward even. */
+
+/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
+ * ti_int is a 128 bit integral type
+ */
+
+/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+ * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+ */
+
+si_int __clzti2(ti_int a);
+
+long double
+__floattixf(ti_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(ti_int) * CHAR_BIT;
+ const ti_int s = a >> (N-1);
+ a = (a ^ s) - s;
+ int sd = N - __clzti2(a); /* number of significant digits */
+ int e = sd - 1; /* exponent */
+ if (sd > LDBL_MANT_DIG)
+ {
+ /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ * 12345678901234567890123456
+ * 1 = msb 1 bit
+ * P = bit LDBL_MANT_DIG-1 bits to the right of 1
+ * Q = bit LDBL_MANT_DIG bits to the right of 1
+ * R = "or" of all bits to the right of Q
+ */
+ switch (sd)
+ {
+ case LDBL_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case LDBL_MANT_DIG + 2:
+ break;
+ default:
+ a = ((tu_int)a >> (sd - (LDBL_MANT_DIG+2))) |
+ ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0);
+ };
+ /* finish: */
+ a |= (a & 4) != 0; /* Or P into R */
+ ++a; /* round - this step may add a significant bit */
+ a >>= 2; /* dump Q and R */
+ /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */
+ if (a & ((tu_int)1 << LDBL_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ /* a is now rounded to LDBL_MANT_DIG bits */
+ }
+ else
+ {
+ a <<= (LDBL_MANT_DIG - sd);
+ /* a is now rounded to LDBL_MANT_DIG bits */
+ }
+ long_double_bits fb;
+ fb.u.high.s.low = ((su_int)s & 0x8000) | /* sign */
+ (e + 16383); /* exponent */
+ fb.u.low.all = (du_int)a; /* mantissa */
+ return fb.f;
+}
+
+#endif
diff --git a/lib/floatundidf.c b/lib/floatundidf.c
new file mode 100644
index 000000000000..1f304c5c3535
--- /dev/null
+++ b/lib/floatundidf.c
@@ -0,0 +1,107 @@
+/* ===-- floatundidf.c - Implement __floatundidf ---------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __floatundidf for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <float.h>
+
+/* Returns: convert a to a double, rounding toward even. */
+
+/* Assumption: double is a IEEE 64 bit floating point type
+ * du_int is a 64 bit integral type
+ */
+
+/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+
+#ifndef __SOFT_FP__
+/* Support for systems that have hardware floating-point; we'll set the inexact flag
+ * as a side-effect of this computation.
+ */
+
+#include <stdint.h>
+
+double
+__floatundidf(du_int a)
+{
+ static const double twop52 = 0x1.0p52;
+ static const double twop84 = 0x1.0p84;
+ static const double twop84_plus_twop52 = 0x1.00000001p84;
+
+ union { uint64_t x; double d; } high = { .d = twop84 };
+ union { uint64_t x; double d; } low = { .d = twop52 };
+
+ high.x |= a >> 32;
+ low.x |= a & UINT64_C(0x00000000ffffffff);
+
+ const double result = (high.d - twop84_plus_twop52) + low.d;
+ return result;
+}
+
+#else
+/* Support for systems that don't have hardware floating-point; there are no flags to
+ * set, and we don't want to code-gen to an unknown soft-float implementation.
+ */
+
+double
+__floatundidf(du_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(du_int) * CHAR_BIT;
+ int sd = N - __builtin_clzll(a); /* number of significant digits */
+ int e = sd - 1; /* exponent */
+ if (sd > DBL_MANT_DIG)
+ {
+ /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ * 12345678901234567890123456
+ * 1 = msb 1 bit
+ * P = bit DBL_MANT_DIG-1 bits to the right of 1
+ * Q = bit DBL_MANT_DIG bits to the right of 1
+ * R = "or" of all bits to the right of Q
+ */
+ switch (sd)
+ {
+ case DBL_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case DBL_MANT_DIG + 2:
+ break;
+ default:
+ a = (a >> (sd - (DBL_MANT_DIG+2))) |
+ ((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);
+ };
+ /* finish: */
+ a |= (a & 4) != 0; /* Or P into R */
+ ++a; /* round - this step may add a significant bit */
+ a >>= 2; /* dump Q and R */
+ /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */
+ if (a & ((du_int)1 << DBL_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ /* a is now rounded to DBL_MANT_DIG bits */
+ }
+ else
+ {
+ a <<= (DBL_MANT_DIG - sd);
+ /* a is now rounded to DBL_MANT_DIG bits */
+ }
+ double_bits fb;
+ fb.u.high = ((e + 1023) << 20) | /* exponent */
+ ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */
+ fb.u.low = (su_int)a; /* mantissa-low */
+ return fb.f;
+}
+#endif
diff --git a/lib/floatundisf.c b/lib/floatundisf.c
new file mode 100644
index 000000000000..79b4b82e3a03
--- /dev/null
+++ b/lib/floatundisf.c
@@ -0,0 +1,76 @@
+/*===-- floatundisf.c - Implement __floatundisf ---------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __floatundisf for the compiler_rt library.
+ *
+ *===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <float.h>
+
+/* Returns: convert a to a float, rounding toward even. */
+
+/* Assumption: float is a IEEE 32 bit floating point type
+ * du_int is a 64 bit integral type
+ */
+
+/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+
+float
+__floatundisf(du_int a)
+{
+ if (a == 0)
+ return 0.0F;
+ const unsigned N = sizeof(du_int) * CHAR_BIT;
+ int sd = N - __builtin_clzll(a); /* number of significant digits */
+ int e = sd - 1; /* 8 exponent */
+ if (sd > FLT_MANT_DIG)
+ {
+ /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ * 12345678901234567890123456
+ * 1 = msb 1 bit
+ * P = bit FLT_MANT_DIG-1 bits to the right of 1
+ * Q = bit FLT_MANT_DIG bits to the right of 1
+ * R = "or" of all bits to the right of Q
+ */
+ switch (sd)
+ {
+ case FLT_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case FLT_MANT_DIG + 2:
+ break;
+ default:
+ a = (a >> (sd - (FLT_MANT_DIG+2))) |
+ ((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);
+ };
+ /* finish: */
+ a |= (a & 4) != 0; /* Or P into R */
+ ++a; /* round - this step may add a significant bit */
+ a >>= 2; /* dump Q and R */
+ /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */
+ if (a & ((du_int)1 << FLT_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ /* a is now rounded to FLT_MANT_DIG bits */
+ }
+ else
+ {
+ a <<= (FLT_MANT_DIG - sd);
+ /* a is now rounded to FLT_MANT_DIG bits */
+ }
+ float_bits fb;
+ fb.u = ((e + 127) << 23) | /* exponent */
+ ((su_int)a & 0x007FFFFF); /* mantissa */
+ return fb.f;
+}
diff --git a/lib/floatundixf.c b/lib/floatundixf.c
new file mode 100644
index 000000000000..bc9582f7604f
--- /dev/null
+++ b/lib/floatundixf.c
@@ -0,0 +1,42 @@
+/* ===-- floatundixf.c - Implement __floatundixf ---------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __floatundixf for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+
+/* Returns: convert a to a long double, rounding toward even. */
+
+/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
+ * du_int is a 64 bit integral type
+ */
+
+/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+ * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+ */
+long double
+__floatundixf(du_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(du_int) * CHAR_BIT;
+ int clz = __builtin_clzll(a);
+ int e = (N - 1) - clz ; /* exponent */
+ long_double_bits fb;
+ fb.u.high.s.low = (e + 16383); /* exponent */
+ fb.u.low.all = a << clz; /* mantissa */
+ return fb.f;
+}
+
+#endif /* _ARCH_PPC */
diff --git a/lib/floatunsidf.c b/lib/floatunsidf.c
new file mode 100644
index 000000000000..05242c18ab37
--- /dev/null
+++ b/lib/floatunsidf.c
@@ -0,0 +1,37 @@
+//===-- lib/floatunsidf.c - uint -> double-precision conversion ---*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements unsigned integer to double-precision conversion for the
+// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
+// mode.
+//
+//===----------------------------------------------------------------------===//
+
+#define DOUBLE_PRECISION
+#include "fp_lib.h"
+
+fp_t __floatunsidf(unsigned int a) {
+
+ const int aWidth = sizeof a * CHAR_BIT;
+
+ // Handle zero as a special case to protect clz
+ if (a == 0) return fromRep(0);
+
+ // Exponent of (fp_t)a is the width of abs(a).
+ const int exponent = (aWidth - 1) - __builtin_clz(a);
+ rep_t result;
+
+ // Shift a into the significand field and clear the implicit bit.
+ const int shift = significandBits - exponent;
+ result = (rep_t)a << shift ^ implicitBit;
+
+ // Insert the exponent
+ result += (rep_t)(exponent + exponentBias) << significandBits;
+ return fromRep(result);
+}
diff --git a/lib/floatunsisf.c b/lib/floatunsisf.c
new file mode 100644
index 000000000000..31c064432908
--- /dev/null
+++ b/lib/floatunsisf.c
@@ -0,0 +1,45 @@
+//===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements unsigned integer to single-precision conversion for the
+// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
+// mode.
+//
+//===----------------------------------------------------------------------===//
+
+#define SINGLE_PRECISION
+#include "fp_lib.h"
+
+fp_t __floatunsisf(unsigned int a) {
+
+ const int aWidth = sizeof a * CHAR_BIT;
+
+ // Handle zero as a special case to protect clz
+ if (a == 0) return fromRep(0);
+
+ // Exponent of (fp_t)a is the width of abs(a).
+ const int exponent = (aWidth - 1) - __builtin_clz(a);
+ rep_t result;
+
+ // Shift a into the significand field, rounding if it is a right-shift
+ if (exponent <= significandBits) {
+ const int shift = significandBits - exponent;
+ result = (rep_t)a << shift ^ implicitBit;
+ } else {
+ const int shift = exponent - significandBits;
+ result = (rep_t)a >> shift ^ implicitBit;
+ rep_t round = (rep_t)a << (typeWidth - shift);
+ if (round > signBit) result++;
+ if (round == signBit) result += result & 1;
+ }
+
+ // Insert the exponent
+ result += (rep_t)(exponent + exponentBias) << significandBits;
+ return fromRep(result);
+}
diff --git a/lib/floatuntidf.c b/lib/floatuntidf.c
new file mode 100644
index 000000000000..51d8b2827a36
--- /dev/null
+++ b/lib/floatuntidf.c
@@ -0,0 +1,83 @@
+/* ===-- floatuntidf.c - Implement __floatuntidf ---------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __floatuntidf for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+
+/* Returns: convert a to a double, rounding toward even. */
+
+/* Assumption: double is a IEEE 64 bit floating point type
+ * tu_int is a 128 bit integral type
+ */
+
+/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+
+si_int __clzti2(ti_int a);
+
+double
+__floatuntidf(tu_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(tu_int) * CHAR_BIT;
+ int sd = N - __clzti2(a); /* number of significant digits */
+ int e = sd - 1; /* exponent */
+ if (sd > DBL_MANT_DIG)
+ {
+ /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ * 12345678901234567890123456
+ * 1 = msb 1 bit
+ * P = bit DBL_MANT_DIG-1 bits to the right of 1
+ * Q = bit DBL_MANT_DIG bits to the right of 1
+ * R = "or" of all bits to the right of Q
+ */
+ switch (sd)
+ {
+ case DBL_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case DBL_MANT_DIG + 2:
+ break;
+ default:
+ a = (a >> (sd - (DBL_MANT_DIG+2))) |
+ ((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);
+ };
+ /* finish: */
+ a |= (a & 4) != 0; /* Or P into R */
+ ++a; /* round - this step may add a significant bit */
+ a >>= 2; /* dump Q and R */
+ /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */
+ if (a & ((tu_int)1 << DBL_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ /* a is now rounded to DBL_MANT_DIG bits */
+ }
+ else
+ {
+ a <<= (DBL_MANT_DIG - sd);
+ /* a is now rounded to DBL_MANT_DIG bits */
+ }
+ double_bits fb;
+ fb.u.s.high = ((e + 1023) << 20) | /* exponent */
+ ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */
+ fb.u.s.low = (su_int)a; /* mantissa-low */
+ return fb.f;
+}
+
+#endif
diff --git a/lib/floatuntisf.c b/lib/floatuntisf.c
new file mode 100644
index 000000000000..328f39bbef78
--- /dev/null
+++ b/lib/floatuntisf.c
@@ -0,0 +1,82 @@
+/* ===-- floatuntisf.c - Implement __floatuntisf ---------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __floatuntisf for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+
+/* Returns: convert a to a float, rounding toward even. */
+
+/* Assumption: float is a IEEE 32 bit floating point type
+ * tu_int is a 128 bit integral type
+ */
+
+/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+
+si_int __clzti2(ti_int a);
+
+float
+__floatuntisf(tu_int a)
+{
+ if (a == 0)
+ return 0.0F;
+ const unsigned N = sizeof(tu_int) * CHAR_BIT;
+ int sd = N - __clzti2(a); /* number of significant digits */
+ int e = sd - 1; /* exponent */
+ if (sd > FLT_MANT_DIG)
+ {
+ /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ * 12345678901234567890123456
+ * 1 = msb 1 bit
+ * P = bit FLT_MANT_DIG-1 bits to the right of 1
+ * Q = bit FLT_MANT_DIG bits to the right of 1
+ * R = "or" of all bits to the right of Q
+ */
+ switch (sd)
+ {
+ case FLT_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case FLT_MANT_DIG + 2:
+ break;
+ default:
+ a = (a >> (sd - (FLT_MANT_DIG+2))) |
+ ((a & ((tu_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);
+ };
+ /* finish: */
+ a |= (a & 4) != 0; /* Or P into R */
+ ++a; /* round - this step may add a significant bit */
+ a >>= 2; /* dump Q and R */
+ /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */
+ if (a & ((tu_int)1 << FLT_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ /* a is now rounded to FLT_MANT_DIG bits */
+ }
+ else
+ {
+ a <<= (FLT_MANT_DIG - sd);
+ /* a is now rounded to FLT_MANT_DIG bits */
+ }
+ float_bits fb;
+ fb.u = ((e + 127) << 23) | /* exponent */
+ ((su_int)a & 0x007FFFFF); /* mantissa */
+ return fb.f;
+}
+
+#endif
diff --git a/lib/floatuntixf.c b/lib/floatuntixf.c
new file mode 100644
index 000000000000..e82d0c1e6ff4
--- /dev/null
+++ b/lib/floatuntixf.c
@@ -0,0 +1,84 @@
+/* ===-- floatuntixf.c - Implement __floatuntixf ---------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __floatuntixf for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <float.h>
+
+/* Returns: convert a to a long double, rounding toward even. */
+
+/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
+ * tu_int is a 128 bit integral type
+ */
+
+/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
+ * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+ */
+
+si_int __clzti2(ti_int a);
+
+long double
+__floatuntixf(tu_int a)
+{
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(tu_int) * CHAR_BIT;
+ int sd = N - __clzti2(a); /* number of significant digits */
+ int e = sd - 1; /* exponent */
+ if (sd > LDBL_MANT_DIG)
+ {
+ /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
+ * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
+ * 12345678901234567890123456
+ * 1 = msb 1 bit
+ * P = bit LDBL_MANT_DIG-1 bits to the right of 1
+ * Q = bit LDBL_MANT_DIG bits to the right of 1
+ * R = "or" of all bits to the right of Q
+ */
+ switch (sd)
+ {
+ case LDBL_MANT_DIG + 1:
+ a <<= 1;
+ break;
+ case LDBL_MANT_DIG + 2:
+ break;
+ default:
+ a = (a >> (sd - (LDBL_MANT_DIG+2))) |
+ ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0);
+ };
+ /* finish: */
+ a |= (a & 4) != 0; /* Or P into R */
+ ++a; /* round - this step may add a significant bit */
+ a >>= 2; /* dump Q and R */
+ /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */
+ if (a & ((tu_int)1 << LDBL_MANT_DIG))
+ {
+ a >>= 1;
+ ++e;
+ }
+ /* a is now rounded to LDBL_MANT_DIG bits */
+ }
+ else
+ {
+ a <<= (LDBL_MANT_DIG - sd);
+ /* a is now rounded to LDBL_MANT_DIG bits */
+ }
+ long_double_bits fb;
+ fb.u.high.s.low = (e + 16383); /* exponent */
+ fb.u.low.all = (du_int)a; /* mantissa */
+ return fb.f;
+}
+
+#endif
diff --git a/lib/fp_lib.h b/lib/fp_lib.h
new file mode 100644
index 000000000000..eac670d7f236
--- /dev/null
+++ b/lib/fp_lib.h
@@ -0,0 +1,143 @@
+//===-- lib/fp_lib.h - Floating-point utilities -------------------*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a configuration header for soft-float routines in compiler-rt.
+// This file does not provide any part of the compiler-rt interface, but defines
+// many useful constants and utility routines that are used in the
+// implementation of the soft-float routines in compiler-rt.
+//
+// Assumes that float and double correspond to the IEEE-754 binary32 and
+// binary64 types, respectively, and that integer endianness matches floating
+// point endianness on the target platform.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FP_LIB_HEADER
+#define FP_LIB_HEADER
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <limits.h>
+
+#if defined SINGLE_PRECISION
+
+typedef uint32_t rep_t;
+typedef int32_t srep_t;
+typedef float fp_t;
+#define REP_C UINT32_C
+#define significandBits 23
+
+static inline int rep_clz(rep_t a) {
+ return __builtin_clz(a);
+}
+
+// 32x32 --> 64 bit multiply
+static inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
+ const uint64_t product = (uint64_t)a*b;
+ *hi = product >> 32;
+ *lo = product;
+}
+
+#elif defined DOUBLE_PRECISION
+
+typedef uint64_t rep_t;
+typedef int64_t srep_t;
+typedef double fp_t;
+#define REP_C UINT64_C
+#define significandBits 52
+
+static inline int rep_clz(rep_t a) {
+#if defined __LP64__
+ return __builtin_clzl(a);
+#else
+ if (a & REP_C(0xffffffff00000000))
+ return __builtin_clz(a >> 32);
+ else
+ return 32 + __builtin_clz(a & REP_C(0xffffffff));
+#endif
+}
+
+#define loWord(a) (a & 0xffffffffU)
+#define hiWord(a) (a >> 32)
+
+// 64x64 -> 128 wide multiply for platforms that don't have such an operation;
+// many 64-bit platforms have this operation, but they tend to have hardware
+// floating-point, so we don't bother with a special case for them here.
+static inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
+ // Each of the component 32x32 -> 64 products
+ const uint64_t plolo = loWord(a) * loWord(b);
+ const uint64_t plohi = loWord(a) * hiWord(b);
+ const uint64_t philo = hiWord(a) * loWord(b);
+ const uint64_t phihi = hiWord(a) * hiWord(b);
+ // Sum terms that contribute to lo in a way that allows us to get the carry
+ const uint64_t r0 = loWord(plolo);
+ const uint64_t r1 = hiWord(plolo) + loWord(plohi) + loWord(philo);
+ *lo = r0 + (r1 << 32);
+ // Sum terms contributing to hi with the carry from lo
+ *hi = hiWord(plohi) + hiWord(philo) + hiWord(r1) + phihi;
+}
+
+#else
+#error Either SINGLE_PRECISION or DOUBLE_PRECISION must be defined.
+#endif
+
+#define typeWidth (sizeof(rep_t)*CHAR_BIT)
+#define exponentBits (typeWidth - significandBits - 1)
+#define maxExponent ((1 << exponentBits) - 1)
+#define exponentBias (maxExponent >> 1)
+
+#define implicitBit (REP_C(1) << significandBits)
+#define significandMask (implicitBit - 1U)
+#define signBit (REP_C(1) << (significandBits + exponentBits))
+#define absMask (signBit - 1U)
+#define exponentMask (absMask ^ significandMask)
+#define oneRep ((rep_t)exponentBias << significandBits)
+#define infRep exponentMask
+#define quietBit (implicitBit >> 1)
+#define qnanRep (exponentMask | quietBit)
+
+static inline rep_t toRep(fp_t x) {
+ const union { fp_t f; rep_t i; } rep = {.f = x};
+ return rep.i;
+}
+
+static inline fp_t fromRep(rep_t x) {
+ const union { fp_t f; rep_t i; } rep = {.i = x};
+ return rep.f;
+}
+
+static inline int normalize(rep_t *significand) {
+ const int shift = rep_clz(*significand) - rep_clz(implicitBit);
+ *significand <<= shift;
+ return 1 - shift;
+}
+
+static inline void wideLeftShift(rep_t *hi, rep_t *lo, int count) {
+ *hi = *hi << count | *lo >> (typeWidth - count);
+ *lo = *lo << count;
+}
+
+static inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo, int count) {
+ if (count < typeWidth) {
+ const bool sticky = *lo << (typeWidth - count);
+ *lo = *hi << (typeWidth - count) | *lo >> count | sticky;
+ *hi = *hi >> count;
+ }
+ else if (count < 2*typeWidth) {
+ const bool sticky = *hi << (2*typeWidth - count) | *lo;
+ *lo = *hi >> (count - typeWidth) | sticky;
+ *hi = 0;
+ } else {
+ const bool sticky = *hi | *lo;
+ *lo = sticky;
+ *hi = 0;
+ }
+}
+
+#endif // FP_LIB_HEADER
diff --git a/lib/gcc_personality_v0.c b/lib/gcc_personality_v0.c
new file mode 100644
index 000000000000..59401900ef85
--- /dev/null
+++ b/lib/gcc_personality_v0.c
@@ -0,0 +1,251 @@
+/* ===-- gcc_personality_v0.c - Implement __gcc_personality_v0 -------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "int_lib.h"
+
+/*
+ * _Unwind_* stuff based on C++ ABI public documentation
+ * http://refspecs.freestandards.org/abi-eh-1.21.html
+ */
+
+typedef enum {
+ _URC_NO_REASON = 0,
+ _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+ _URC_FATAL_PHASE2_ERROR = 2,
+ _URC_FATAL_PHASE1_ERROR = 3,
+ _URC_NORMAL_STOP = 4,
+ _URC_END_OF_STACK = 5,
+ _URC_HANDLER_FOUND = 6,
+ _URC_INSTALL_CONTEXT = 7,
+ _URC_CONTINUE_UNWIND = 8
+} _Unwind_Reason_Code;
+
+typedef enum {
+ _UA_SEARCH_PHASE = 1,
+ _UA_CLEANUP_PHASE = 2,
+ _UA_HANDLER_FRAME = 4,
+ _UA_FORCE_UNWIND = 8,
+ _UA_END_OF_STACK = 16
+} _Unwind_Action;
+
+typedef struct _Unwind_Context* _Unwind_Context_t;
+
+struct _Unwind_Exception {
+ uint64_t exception_class;
+ void (*exception_cleanup)(_Unwind_Reason_Code reason,
+ struct _Unwind_Exception* exc);
+ uintptr_t private_1;
+ uintptr_t private_2;
+};
+
+extern const uint8_t* _Unwind_GetLanguageSpecificData(_Unwind_Context_t c);
+extern void _Unwind_SetGR(_Unwind_Context_t c, int i, uintptr_t n);
+extern void _Unwind_SetIP(_Unwind_Context_t, uintptr_t new_value);
+extern uintptr_t _Unwind_GetIP(_Unwind_Context_t context);
+extern uintptr_t _Unwind_GetRegionStart(_Unwind_Context_t context);
+
+
+/*
+ * Pointer encodings documented at:
+ * http://refspecs.freestandards.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html
+ */
+
+#define DW_EH_PE_omit 0xff /* no data follows */
+
+#define DW_EH_PE_absptr 0x00
+#define DW_EH_PE_uleb128 0x01
+#define DW_EH_PE_udata2 0x02
+#define DW_EH_PE_udata4 0x03
+#define DW_EH_PE_udata8 0x04
+#define DW_EH_PE_sleb128 0x09
+#define DW_EH_PE_sdata2 0x0A
+#define DW_EH_PE_sdata4 0x0B
+#define DW_EH_PE_sdata8 0x0C
+
+#define DW_EH_PE_pcrel 0x10
+#define DW_EH_PE_textrel 0x20
+#define DW_EH_PE_datarel 0x30
+#define DW_EH_PE_funcrel 0x40
+#define DW_EH_PE_aligned 0x50
+#define DW_EH_PE_indirect 0x80 /* gcc extension */
+
+
+
+/* read a uleb128 encoded value and advance pointer */
+static uintptr_t readULEB128(const uint8_t** data)
+{
+ uintptr_t result = 0;
+ uintptr_t shift = 0;
+ unsigned char byte;
+ const uint8_t* p = *data;
+ do {
+ byte = *p++;
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+ } while (byte & 0x80);
+ *data = p;
+ return result;
+}
+
+/* read a pointer encoded value and advance pointer */
+static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding)
+{
+ const uint8_t* p = *data;
+ uintptr_t result = 0;
+
+ if ( encoding == DW_EH_PE_omit )
+ return 0;
+
+ /* first get value */
+ switch (encoding & 0x0F) {
+ case DW_EH_PE_absptr:
+ result = *((uintptr_t*)p);
+ p += sizeof(uintptr_t);
+ break;
+ case DW_EH_PE_uleb128:
+ result = readULEB128(&p);
+ break;
+ case DW_EH_PE_udata2:
+ result = *((uint16_t*)p);
+ p += sizeof(uint16_t);
+ break;
+ case DW_EH_PE_udata4:
+ result = *((uint32_t*)p);
+ p += sizeof(uint32_t);
+ break;
+ case DW_EH_PE_udata8:
+ result = *((uint64_t*)p);
+ p += sizeof(uint64_t);
+ break;
+ case DW_EH_PE_sdata2:
+ result = *((int16_t*)p);
+ p += sizeof(int16_t);
+ break;
+ case DW_EH_PE_sdata4:
+ result = *((int32_t*)p);
+ p += sizeof(int32_t);
+ break;
+ case DW_EH_PE_sdata8:
+ result = *((int64_t*)p);
+ p += sizeof(int64_t);
+ break;
+ case DW_EH_PE_sleb128:
+ default:
+ /* not supported */
+ compilerrt_abort();
+ break;
+ }
+
+ /* then add relative offset */
+ switch ( encoding & 0x70 ) {
+ case DW_EH_PE_absptr:
+ /* do nothing */
+ break;
+ case DW_EH_PE_pcrel:
+ result += (uintptr_t)(*data);
+ break;
+ case DW_EH_PE_textrel:
+ case DW_EH_PE_datarel:
+ case DW_EH_PE_funcrel:
+ case DW_EH_PE_aligned:
+ default:
+ /* not supported */
+ compilerrt_abort();
+ break;
+ }
+
+ /* then apply indirection */
+ if (encoding & DW_EH_PE_indirect) {
+ result = *((uintptr_t*)result);
+ }
+
+ *data = p;
+ return result;
+}
+
+
+/*
+ * The C compiler makes references to __gcc_personality_v0 in
+ * the dwarf unwind information for translation units that use
+ * __attribute__((cleanup(xx))) on local variables.
+ * This personality routine is called by the system unwinder
+ * on each frame as the stack is unwound during a C++ exception
+ * throw through a C function compiled with -fexceptions.
+ */
+#if __arm__
+// the setjump-longjump based exceptions personality routine has a different name
+_Unwind_Reason_Code __gcc_personality_sj0(int version, _Unwind_Action actions,
+ uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,
+ _Unwind_Context_t context)
+#else
+_Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions,
+ uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,
+ _Unwind_Context_t context)
+#endif
+{
+ /* Since C does not have catch clauses, there is nothing to do during */
+ /* phase 1 (the search phase). */
+ if ( actions & _UA_SEARCH_PHASE )
+ return _URC_CONTINUE_UNWIND;
+
+ /* There is nothing to do if there is no LSDA for this frame. */
+ const uint8_t* lsda = _Unwind_GetLanguageSpecificData(context);
+ if ( lsda == NULL )
+ return _URC_CONTINUE_UNWIND;
+
+ uintptr_t pc = _Unwind_GetIP(context)-1;
+ uintptr_t funcStart = _Unwind_GetRegionStart(context);
+ uintptr_t pcOffset = pc - funcStart;
+
+ /* Parse LSDA header. */
+ uint8_t lpStartEncoding = *lsda++;
+ if (lpStartEncoding != DW_EH_PE_omit) {
+ readEncodedPointer(&lsda, lpStartEncoding);
+ }
+ uint8_t ttypeEncoding = *lsda++;
+ if (ttypeEncoding != DW_EH_PE_omit) {
+ readULEB128(&lsda);
+ }
+ /* Walk call-site table looking for range that includes current PC. */
+ uint8_t callSiteEncoding = *lsda++;
+ uint32_t callSiteTableLength = readULEB128(&lsda);
+ const uint8_t* callSiteTableStart = lsda;
+ const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength;
+ const uint8_t* p=callSiteTableStart;
+ while (p < callSiteTableEnd) {
+ uintptr_t start = readEncodedPointer(&p, callSiteEncoding);
+ uintptr_t length = readEncodedPointer(&p, callSiteEncoding);
+ uintptr_t landingPad = readEncodedPointer(&p, callSiteEncoding);
+ readULEB128(&p); /* action value not used for C code */
+ if ( landingPad == 0 )
+ continue; /* no landing pad for this entry */
+ if ( (start <= pcOffset) && (pcOffset < (start+length)) ) {
+ /* Found landing pad for the PC.
+ * Set Instruction Pointer to so we re-enter function
+ * at landing pad. The landing pad is created by the compiler
+ * to take two parameters in registers.
+ */
+ _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
+ (uintptr_t)exceptionObject);
+ _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0);
+ _Unwind_SetIP(context, funcStart+landingPad);
+ return _URC_INSTALL_CONTEXT;
+ }
+ }
+
+ /* No landing pad found, continue unwinding. */
+ return _URC_CONTINUE_UNWIND;
+}
+
diff --git a/lib/i386/CMakeLists.txt b/lib/i386/CMakeLists.txt
new file mode 100644
index 000000000000..1c2861afb06e
--- /dev/null
+++ b/lib/i386/CMakeLists.txt
@@ -0,0 +1,3 @@
+SET( SRCS
+
+ )
diff --git a/lib/i386/Makefile.mk b/lib/i386/Makefile.mk
new file mode 100644
index 000000000000..20f95e651481
--- /dev/null
+++ b/lib/i386/Makefile.mk
@@ -0,0 +1,19 @@
+#===- lib/i386/Makefile.mk ---------------------------------*- Makefile -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+SubDirs :=
+OnlyArchs := i386
+
+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/lib/i386/ashldi3.S b/lib/i386/ashldi3.S
new file mode 100644
index 000000000000..af6f98bc7cf8
--- /dev/null
+++ b/lib/i386/ashldi3.S
@@ -0,0 +1,56 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// di_int __ashldi3(di_int input, int count);
+
+// This routine has some extra memory traffic, loading the 64-bit input via two
+// 32-bit loads, then immediately storing it back to the stack via a single 64-bit
+// store. This is to avoid a write-small, read-large stall.
+// However, if callers of this routine can be safely assumed to store the argument
+// via a 64-bt store, this is unnecessary memory traffic, and should be avoided.
+// It can be turned off by defining the TRUST_CALLERS_USE_64_BIT_STORES macro.
+
+#ifdef __i386__
+#ifdef __SSE2__
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__ashldi3)
+ movd 12(%esp), %xmm2 // Load count
+#ifndef TRUST_CALLERS_USE_64_BIT_STORES
+ movd 4(%esp), %xmm0
+ movd 8(%esp), %xmm1
+ punpckldq %xmm1, %xmm0 // Load input
+#else
+ movq 4(%esp), %xmm0 // Load input
+#endif
+ psllq %xmm2, %xmm0 // shift input by count
+ movd %xmm0, %eax
+ psrlq $32, %xmm0
+ movd %xmm0, %edx
+ ret
+
+#else // Use GPRs instead of SSE2 instructions, if they aren't available.
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__ashldi3)
+ movl 12(%esp), %ecx // Load count
+ movl 8(%esp), %edx // Load high
+ movl 4(%esp), %eax // Load low
+
+ testl $0x20, %ecx // If count >= 32
+ jnz 1f // goto 1
+ shldl %cl, %eax, %edx // left shift high by count
+ shll %cl, %eax // left shift low by count
+ ret
+
+1: movl %eax, %edx // Move low to high
+ xorl %eax, %eax // clear low
+ shll %cl, %edx // shift high by count - 32
+ ret
+
+#endif // __SSE2__
+#endif // __i386__
diff --git a/lib/i386/ashrdi3.S b/lib/i386/ashrdi3.S
new file mode 100644
index 000000000000..346f9b1adc16
--- /dev/null
+++ b/lib/i386/ashrdi3.S
@@ -0,0 +1,67 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// di_int __ashrdi3(di_int input, int count);
+
+#ifdef __i386__
+#ifdef __SSE2__
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__ashrdi3)
+ movd 12(%esp), %xmm2 // Load count
+ movl 8(%esp), %eax
+#ifndef TRUST_CALLERS_USE_64_BIT_STORES
+ movd 4(%esp), %xmm0
+ movd 8(%esp), %xmm1
+ punpckldq %xmm1, %xmm0 // Load input
+#else
+ movq 4(%esp), %xmm0 // Load input
+#endif
+
+ psrlq %xmm2, %xmm0 // unsigned shift input by count
+
+ testl %eax, %eax // check the sign-bit of the input
+ jns 1f // early out for positive inputs
+
+ // If the input is negative, we need to construct the shifted sign bit
+ // to or into the result, as xmm does not have a signed right shift.
+ pcmpeqb %xmm1, %xmm1 // -1ULL
+ psrlq $58, %xmm1 // 0x3f
+ pandn %xmm1, %xmm2 // 63 - count
+ pcmpeqb %xmm1, %xmm1 // -1ULL
+ psubq %xmm1, %xmm2 // 64 - count
+ psllq %xmm2, %xmm1 // -1 << (64 - count) = leading sign bits
+ por %xmm1, %xmm0
+
+ // Move the result back to the general purpose registers and return
+1: movd %xmm0, %eax
+ psrlq $32, %xmm0
+ movd %xmm0, %edx
+ ret
+
+#else // Use GPRs instead of SSE2 instructions, if they aren't available.
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__ashrdi3)
+ movl 12(%esp), %ecx // Load count
+ movl 8(%esp), %edx // Load high
+ movl 4(%esp), %eax // Load low
+
+ testl $0x20, %ecx // If count >= 32
+ jnz 1f // goto 1
+
+ shrdl %cl, %edx, %eax // right shift low by count
+ sarl %cl, %edx // right shift high by count
+ ret
+
+1: movl %edx, %eax // Move high to low
+ sarl $31, %edx // clear high
+ sarl %cl, %eax // shift low by count - 32
+ ret
+
+#endif // __SSE2__
+#endif // __i386__
diff --git a/lib/i386/divdi3.S b/lib/i386/divdi3.S
new file mode 100644
index 000000000000..5ad530c34a4f
--- /dev/null
+++ b/lib/i386/divdi3.S
@@ -0,0 +1,161 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// di_int __divdi3(di_int a, di_int b);
+
+// result = a / b.
+// both inputs and the output are 64-bit signed integers.
+// This will do whatever the underlying hardware is set to do on division by zero.
+// No other exceptions are generated, as the divide cannot overflow.
+//
+// This is targeted at 32-bit x86 *only*, as this can be done directly in hardware
+// on x86_64. The performance goal is ~40 cycles per divide, which is faster than
+// currently possible via simulation of integer divides on the x87 unit.
+//
+// Stephen Canon, December 2008
+
+#ifdef __i386__
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__divdi3)
+
+/* This is currently implemented by wrapping the unsigned divide up in an absolute
+ value, then restoring the correct sign at the end of the computation. This could
+ certainly be improved upon. */
+
+ pushl %esi
+ movl 20(%esp), %edx // high word of b
+ movl 16(%esp), %eax // low word of b
+ movl %edx, %ecx
+ sarl $31, %ecx // (b < 0) ? -1 : 0
+ xorl %ecx, %eax
+ xorl %ecx, %edx // EDX:EAX = (b < 0) ? not(b) : b
+ subl %ecx, %eax
+ sbbl %ecx, %edx // EDX:EAX = abs(b)
+ movl %edx, 20(%esp)
+ movl %eax, 16(%esp) // store abs(b) back to stack
+ movl %ecx, %esi // set aside sign of b
+
+ movl 12(%esp), %edx // high word of b
+ movl 8(%esp), %eax // low word of b
+ movl %edx, %ecx
+ sarl $31, %ecx // (a < 0) ? -1 : 0
+ xorl %ecx, %eax
+ xorl %ecx, %edx // EDX:EAX = (a < 0) ? not(a) : a
+ subl %ecx, %eax
+ sbbl %ecx, %edx // EDX:EAX = abs(a)
+ movl %edx, 12(%esp)
+ movl %eax, 8(%esp) // store abs(a) back to stack
+ xorl %ecx, %esi // sign of result = (sign of a) ^ (sign of b)
+
+ pushl %ebx
+ movl 24(%esp), %ebx // Find the index i of the leading bit in b.
+ bsrl %ebx, %ecx // If the high word of b is zero, jump to
+ jz 9f // the code to handle that special case [9].
+
+ /* High word of b is known to be non-zero on this branch */
+
+ movl 20(%esp), %eax // Construct bhi, containing bits [1+i:32+i] of b
+
+ shrl %cl, %eax // Practically, this means that bhi is given by:
+ shrl %eax //
+ notl %ecx // bhi = (high word of b) << (31 - i) |
+ shll %cl, %ebx // (low word of b) >> (1 + i)
+ orl %eax, %ebx //
+ movl 16(%esp), %edx // Load the high and low words of a, and jump
+ movl 12(%esp), %eax // to [1] if the high word is larger than bhi
+ cmpl %ebx, %edx // to avoid overflowing the upcoming divide.
+ jae 1f
+
+ /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ divl %ebx // eax <-- qs, edx <-- r such that ahi:alo = bs*qs + r
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ shrl %cl, %eax // q = qs >> (1 + i)
+ movl %eax, %edi
+ mull 24(%esp) // q*blo
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 28(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+ sbbl $0, %edi // decrement q if remainder is negative
+ xorl %edx, %edx
+ movl %edi, %eax
+
+ addl %esi, %eax // Restore correct sign to result
+ adcl %esi, %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ popl %edi // Restore callee-save registers
+ popl %ebx
+ popl %esi
+ retl // Return
+
+
+1: /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ subl %ebx, %edx // subtract bhi from ahi so that divide will not
+ divl %ebx // overflow, and find q and r such that
+ //
+ // ahi:alo = (1:q)*bhi + r
+ //
+ // Note that q is a number in (31-i).(1+i)
+ // fix point.
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ orl $0x80000000, %eax
+ shrl %cl, %eax // q = (1:qs) >> (1 + i)
+ movl %eax, %edi
+ mull 24(%esp) // q*blo
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 28(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+ sbbl $0, %edi // decrement q if remainder is negative
+ xorl %edx, %edx
+ movl %edi, %eax
+
+ addl %esi, %eax // Restore correct sign to result
+ adcl %esi, %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ popl %edi // Restore callee-save registers
+ popl %ebx
+ popl %esi
+ retl // Return
+
+
+9: /* High word of b is zero on this branch */
+
+ movl 16(%esp), %eax // Find qhi and rhi such that
+ movl 20(%esp), %ecx //
+ xorl %edx, %edx // ahi = qhi*b + rhi with 0 ≤ rhi < b
+ divl %ecx //
+ movl %eax, %ebx //
+ movl 12(%esp), %eax // Find qlo such that
+ divl %ecx //
+ movl %ebx, %edx // rhi:alo = qlo*b + rlo with 0 ≤ rlo < b
+
+ addl %esi, %eax // Restore correct sign to result
+ adcl %esi, %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ popl %ebx // Restore callee-save registers
+ popl %esi
+ retl // Return
+
+#endif // __i386__
diff --git a/lib/i386/floatdidf.S b/lib/i386/floatdidf.S
new file mode 100644
index 000000000000..3a526eab9f96
--- /dev/null
+++ b/lib/i386/floatdidf.S
@@ -0,0 +1,35 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// double __floatundidf(du_int a);
+
+#ifdef __i386__
+
+#ifndef __ELF__
+.const
+#endif
+.align 4
+twop52: .quad 0x4330000000000000
+twop32: .quad 0x41f0000000000000
+
+#define REL_ADDR(_a) (_a)-0b(%eax)
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__floatdidf)
+ cvtsi2sd 8(%esp), %xmm1
+ movss 4(%esp), %xmm0 // low 32 bits of a
+ calll 0f
+0: popl %eax
+ mulsd REL_ADDR(twop32), %xmm1 // a_hi as a double (without rounding)
+ movsd REL_ADDR(twop52), %xmm2 // 0x1.0p52
+ subsd %xmm2, %xmm1 // a_hi - 0x1p52 (no rounding occurs)
+ orpd %xmm2, %xmm0 // 0x1p52 + a_lo (no rounding occurs)
+ addsd %xmm1, %xmm0 // a_hi + a_lo (round happens here)
+ movsd %xmm0, 4(%esp)
+ fldl 4(%esp)
+ ret
+
+#endif // __i386__
diff --git a/lib/i386/floatdisf.S b/lib/i386/floatdisf.S
new file mode 100644
index 000000000000..741e4a6607fc
--- /dev/null
+++ b/lib/i386/floatdisf.S
@@ -0,0 +1,31 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// float __floatdisf(di_int a);
+
+// This routine has some extra memory traffic, loading the 64-bit input via two
+// 32-bit loads, then immediately storing it back to the stack via a single 64-bit
+// store. This is to avoid a write-small, read-large stall.
+// However, if callers of this routine can be safely assumed to store the argument
+// via a 64-bt store, this is unnecessary memory traffic, and should be avoided.
+// It can be turned off by defining the TRUST_CALLERS_USE_64_BIT_STORES macro.
+
+#ifdef __i386__
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__floatdisf)
+#ifndef TRUST_CALLERS_USE_64_BIT_STORES
+ movd 4(%esp), %xmm0
+ movd 8(%esp), %xmm1
+ punpckldq %xmm1, %xmm0
+ movq %xmm0, 4(%esp)
+#endif
+ fildll 4(%esp)
+ fstps 4(%esp)
+ flds 4(%esp)
+ ret
+
+#endif // __i386__
diff --git a/lib/i386/floatdixf.S b/lib/i386/floatdixf.S
new file mode 100644
index 000000000000..f0271abcbdc2
--- /dev/null
+++ b/lib/i386/floatdixf.S
@@ -0,0 +1,29 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// float __floatdixf(di_int a);
+
+#ifdef __i386__
+
+// This routine has some extra memory traffic, loading the 64-bit input via two
+// 32-bit loads, then immediately storing it back to the stack via a single 64-bit
+// store. This is to avoid a write-small, read-large stall.
+// However, if callers of this routine can be safely assumed to store the argument
+// via a 64-bt store, this is unnecessary memory traffic, and should be avoided.
+// It can be turned off by defining the TRUST_CALLERS_USE_64_BIT_STORES macro.
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__floatdixf)
+#ifndef TRUST_CALLERS_USE_64_BIT_STORES
+ movd 4(%esp), %xmm0
+ movd 8(%esp), %xmm1
+ punpckldq %xmm1, %xmm0
+ movq %xmm0, 4(%esp)
+#endif
+ fildll 4(%esp)
+ ret
+
+#endif // __i386__
diff --git a/lib/i386/floatundidf.S b/lib/i386/floatundidf.S
new file mode 100644
index 000000000000..7186a355d96c
--- /dev/null
+++ b/lib/i386/floatundidf.S
@@ -0,0 +1,46 @@
+//===-- floatundidf.S - Implement __floatundidf for i386 ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatundidf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// double __floatundidf(du_int a);
+
+#ifdef __i386__
+
+#ifndef __ELF__
+.const
+#endif
+.align 4
+twop52: .quad 0x4330000000000000
+twop84_plus_twop52:
+ .quad 0x4530000000100000
+twop84: .quad 0x4530000000000000
+
+#define REL_ADDR(_a) (_a)-0b(%eax)
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__floatundidf)
+ movss 8(%esp), %xmm1 // high 32 bits of a
+ movss 4(%esp), %xmm0 // low 32 bits of a
+ calll 0f
+0: popl %eax
+ orpd REL_ADDR(twop84), %xmm1 // 0x1p84 + a_hi (no rounding occurs)
+ subsd REL_ADDR(twop84_plus_twop52), %xmm1 // a_hi - 0x1p52 (no rounding occurs)
+ orpd REL_ADDR(twop52), %xmm0 // 0x1p52 + a_lo (no rounding occurs)
+ addsd %xmm1, %xmm0 // a_hi + a_lo (round happens here)
+ movsd %xmm0, 4(%esp)
+ fldl 4(%esp)
+ ret
+
+#endif // __i386__
diff --git a/lib/i386/floatundisf.S b/lib/i386/floatundisf.S
new file mode 100644
index 000000000000..070820c9d4d2
--- /dev/null
+++ b/lib/i386/floatundisf.S
@@ -0,0 +1,99 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// float __floatundisf(du_int a);
+
+// Note that there is a hardware instruction, fildll, that does most of what
+// this function needs to do. However, because of our ia32 ABI, it will take
+// a write-small read-large stall, so the software implementation here is
+// actually several cycles faster.
+
+// This is a branch-free implementation. A branchy implementation might be
+// faster for the common case if you know something a priori about the input
+// distribution.
+
+/* branch-free x87 implementation - one cycle slower than without x87.
+
+#ifdef __i386__
+
+.const
+.align 3
+
+ .quad 0x43f0000000000000
+twop64: .quad 0x0000000000000000
+
+#define TWOp64 twop64-0b(%ecx,%eax,8)
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__floatundisf)
+ movl 8(%esp), %eax
+ movd 8(%esp), %xmm1
+ movd 4(%esp), %xmm0
+ punpckldq %xmm1, %xmm0
+ calll 0f
+0: popl %ecx
+ sarl $31, %eax
+ movq %xmm0, 4(%esp)
+ fildll 4(%esp)
+ faddl TWOp64
+ fstps 4(%esp)
+ flds 4(%esp)
+ ret
+
+#endif // __i386__
+
+*/
+
+/* branch-free, x87-free implementation - faster at the expense of code size */
+
+#ifdef __i386__
+
+#ifndef __ELF__
+.const
+.align 3
+#else
+.align 8
+#endif
+twop52: .quad 0x4330000000000000
+ .quad 0x0000000000000fff
+sticky: .quad 0x0000000000000000
+ .long 0x00000012
+twelve: .long 0x00000000
+
+#define TWOp52 twop52-0b(%ecx)
+#define STICKY sticky-0b(%ecx,%eax,8)
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__floatundisf)
+ movl 8(%esp), %eax
+ movd 8(%esp), %xmm1
+ movd 4(%esp), %xmm0
+ punpckldq %xmm1, %xmm0
+
+ calll 0f
+0: popl %ecx
+ shrl %eax // high 31 bits of input as sint32
+ addl $0x7ff80000, %eax
+ sarl $31, %eax // (big input) ? -1 : 0
+ movsd STICKY, %xmm1 // (big input) ? 0xfff : 0
+ movl $12, %edx
+ andl %eax, %edx // (big input) ? 12 : 0
+ movd %edx, %xmm3
+ andpd %xmm0, %xmm1 // (big input) ? input & 0xfff : 0
+ movsd TWOp52, %xmm2 // 0x1.0p52
+ psrlq %xmm3, %xmm0 // (big input) ? input >> 12 : input
+ orpd %xmm2, %xmm1 // 0x1.0p52 + ((big input) ? input & 0xfff : input)
+ orpd %xmm1, %xmm0 // 0x1.0p52 + ((big input) ? (input >> 12 | input & 0xfff) : input)
+ subsd %xmm2, %xmm0 // (double)((big input) ? (input >> 12 | input & 0xfff) : input)
+ cvtsd2ss %xmm0, %xmm0 // (float)((big input) ? (input >> 12 | input & 0xfff) : input)
+ pslld $23, %xmm3
+ paddd %xmm3, %xmm0 // (float)input
+ movd %xmm0, 4(%esp)
+ flds 4(%esp)
+ ret
+
+#endif // __i386__
diff --git a/lib/i386/floatundixf.S b/lib/i386/floatundixf.S
new file mode 100644
index 000000000000..2cf6d5c2a6ee
--- /dev/null
+++ b/lib/i386/floatundixf.S
@@ -0,0 +1,37 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// long double __floatundixf(du_int a);16
+
+#ifdef __i386__
+
+#ifndef __ELF__
+.const
+#endif
+.align 4
+twop52: .quad 0x4330000000000000
+twop84_plus_twop52_neg:
+ .quad 0xc530000000100000
+twop84: .quad 0x4530000000000000
+
+#define REL_ADDR(_a) (_a)-0b(%eax)
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__floatundixf)
+ calll 0f
+0: popl %eax
+ movss 8(%esp), %xmm0 // hi 32 bits of input
+ movss 4(%esp), %xmm1 // lo 32 bits of input
+ orpd REL_ADDR(twop84), %xmm0 // 2^84 + hi (as a double)
+ orpd REL_ADDR(twop52), %xmm1 // 2^52 + lo (as a double)
+ addsd REL_ADDR(twop84_plus_twop52_neg), %xmm0 // hi - 2^52 (no rounding occurs)
+ movsd %xmm1, 4(%esp)
+ fldl 4(%esp)
+ movsd %xmm0, 4(%esp)
+ faddl 4(%esp)
+ ret
+
+#endif // __i386__
diff --git a/lib/i386/lshrdi3.S b/lib/i386/lshrdi3.S
new file mode 100644
index 000000000000..74937d2d8c16
--- /dev/null
+++ b/lib/i386/lshrdi3.S
@@ -0,0 +1,57 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// di_int __lshrdi3(di_int input, int count);
+
+// This routine has some extra memory traffic, loading the 64-bit input via two
+// 32-bit loads, then immediately storing it back to the stack via a single 64-bit
+// store. This is to avoid a write-small, read-large stall.
+// However, if callers of this routine can be safely assumed to store the argument
+// via a 64-bt store, this is unnecessary memory traffic, and should be avoided.
+// It can be turned off by defining the TRUST_CALLERS_USE_64_BIT_STORES macro.
+
+#ifdef __i386__
+#ifdef __SSE2__
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__lshrdi3)
+ movd 12(%esp), %xmm2 // Load count
+#ifndef TRUST_CALLERS_USE_64_BIT_STORES
+ movd 4(%esp), %xmm0
+ movd 8(%esp), %xmm1
+ punpckldq %xmm1, %xmm0 // Load input
+#else
+ movq 4(%esp), %xmm0 // Load input
+#endif
+ psrlq %xmm2, %xmm0 // shift input by count
+ movd %xmm0, %eax
+ psrlq $32, %xmm0
+ movd %xmm0, %edx
+ ret
+
+#else // Use GPRs instead of SSE2 instructions, if they aren't available.
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__lshrdi3)
+ movl 12(%esp), %ecx // Load count
+ movl 8(%esp), %edx // Load high
+ movl 4(%esp), %eax // Load low
+
+ testl $0x20, %ecx // If count >= 32
+ jnz 1f // goto 1
+
+ shrdl %cl, %edx, %eax // right shift low by count
+ shrl %cl, %edx // right shift high by count
+ ret
+
+1: movl %edx, %eax // Move high to low
+ xorl %edx, %edx // clear high
+ shrl %cl, %eax // shift low by count - 32
+ ret
+
+#endif // __SSE2__
+#endif // __i386__
diff --git a/lib/i386/moddi3.S b/lib/i386/moddi3.S
new file mode 100644
index 000000000000..85f5b3811d5c
--- /dev/null
+++ b/lib/i386/moddi3.S
@@ -0,0 +1,166 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// di_int __moddi3(di_int a, di_int b);
+
+// result = remainder of a / b.
+// both inputs and the output are 64-bit signed integers.
+// This will do whatever the underlying hardware is set to do on division by zero.
+// No other exceptions are generated, as the divide cannot overflow.
+//
+// This is targeted at 32-bit x86 *only*, as this can be done directly in hardware
+// on x86_64. The performance goal is ~40 cycles per divide, which is faster than
+// currently possible via simulation of integer divides on the x87 unit.
+//
+
+// Stephen Canon, December 2008
+
+#ifdef __i386__
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__moddi3)
+
+/* This is currently implemented by wrapping the unsigned modulus up in an absolute
+ value. This could certainly be improved upon. */
+
+ pushl %esi
+ movl 20(%esp), %edx // high word of b
+ movl 16(%esp), %eax // low word of b
+ movl %edx, %ecx
+ sarl $31, %ecx // (b < 0) ? -1 : 0
+ xorl %ecx, %eax
+ xorl %ecx, %edx // EDX:EAX = (b < 0) ? not(b) : b
+ subl %ecx, %eax
+ sbbl %ecx, %edx // EDX:EAX = abs(b)
+ movl %edx, 20(%esp)
+ movl %eax, 16(%esp) // store abs(b) back to stack
+
+ movl 12(%esp), %edx // high word of b
+ movl 8(%esp), %eax // low word of b
+ movl %edx, %ecx
+ sarl $31, %ecx // (a < 0) ? -1 : 0
+ xorl %ecx, %eax
+ xorl %ecx, %edx // EDX:EAX = (a < 0) ? not(a) : a
+ subl %ecx, %eax
+ sbbl %ecx, %edx // EDX:EAX = abs(a)
+ movl %edx, 12(%esp)
+ movl %eax, 8(%esp) // store abs(a) back to stack
+ movl %ecx, %esi // set aside sign of a
+
+ pushl %ebx
+ movl 24(%esp), %ebx // Find the index i of the leading bit in b.
+ bsrl %ebx, %ecx // If the high word of b is zero, jump to
+ jz 9f // the code to handle that special case [9].
+
+ /* High word of b is known to be non-zero on this branch */
+
+ movl 20(%esp), %eax // Construct bhi, containing bits [1+i:32+i] of b
+
+ shrl %cl, %eax // Practically, this means that bhi is given by:
+ shrl %eax //
+ notl %ecx // bhi = (high word of b) << (31 - i) |
+ shll %cl, %ebx // (low word of b) >> (1 + i)
+ orl %eax, %ebx //
+ movl 16(%esp), %edx // Load the high and low words of a, and jump
+ movl 12(%esp), %eax // to [2] if the high word is larger than bhi
+ cmpl %ebx, %edx // to avoid overflowing the upcoming divide.
+ jae 2f
+
+ /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ divl %ebx // eax <-- qs, edx <-- r such that ahi:alo = bs*qs + r
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ shrl %cl, %eax // q = qs >> (1 + i)
+ movl %eax, %edi
+ mull 24(%esp) // q*blo
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 28(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+
+ jnc 1f // if positive, this is the result.
+ addl 24(%esp), %ebx // otherwise
+ adcl 28(%esp), %ecx // ECX:EBX = a - (q-1)*b = result
+1: movl %ebx, %eax
+ movl %ecx, %edx
+
+ addl %esi, %eax // Restore correct sign to result
+ adcl %esi, %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ popl %edi // Restore callee-save registers
+ popl %ebx
+ popl %esi
+ retl // Return
+
+2: /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ subl %ebx, %edx // subtract bhi from ahi so that divide will not
+ divl %ebx // overflow, and find q and r such that
+ //
+ // ahi:alo = (1:q)*bhi + r
+ //
+ // Note that q is a number in (31-i).(1+i)
+ // fix point.
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ orl $0x80000000, %eax
+ shrl %cl, %eax // q = (1:qs) >> (1 + i)
+ movl %eax, %edi
+ mull 24(%esp) // q*blo
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 28(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+
+ jnc 3f // if positive, this is the result.
+ addl 24(%esp), %ebx // otherwise
+ adcl 28(%esp), %ecx // ECX:EBX = a - (q-1)*b = result
+3: movl %ebx, %eax
+ movl %ecx, %edx
+
+ addl %esi, %eax // Restore correct sign to result
+ adcl %esi, %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ popl %edi // Restore callee-save registers
+ popl %ebx
+ popl %esi
+ retl // Return
+
+9: /* High word of b is zero on this branch */
+
+ movl 16(%esp), %eax // Find qhi and rhi such that
+ movl 20(%esp), %ecx //
+ xorl %edx, %edx // ahi = qhi*b + rhi with 0 ≤ rhi < b
+ divl %ecx //
+ movl %eax, %ebx //
+ movl 12(%esp), %eax // Find rlo such that
+ divl %ecx //
+ movl %edx, %eax // rhi:alo = qlo*b + rlo with 0 ≤ rlo < b
+ popl %ebx //
+ xorl %edx, %edx // and return 0:rlo
+
+ addl %esi, %eax // Restore correct sign to result
+ adcl %esi, %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ popl %esi
+ retl // Return
+
+
+#endif // __i386__
diff --git a/lib/i386/muldi3.S b/lib/i386/muldi3.S
new file mode 100644
index 000000000000..5f99f6a9ea82
--- /dev/null
+++ b/lib/i386/muldi3.S
@@ -0,0 +1,29 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// di_int __muldi3(di_int a, di_int b);
+
+#ifdef __i386__
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__muldi3)
+ pushl %ebx
+ movl 16(%esp), %eax // b.lo
+ movl 12(%esp), %ecx // a.hi
+ imull %eax, %ecx // b.lo * a.hi
+
+ movl 8(%esp), %edx // a.lo
+ movl 20(%esp), %ebx // b.hi
+ imull %edx, %ebx // a.lo * b.hi
+
+ mull %edx // EDX:EAX = a.lo * b.lo
+ addl %ecx, %ebx // EBX = (a.lo*b.hi + a.hi*b.lo)
+ addl %ebx, %edx
+
+ popl %ebx
+ retl
+
+#endif // __i386__
diff --git a/lib/i386/udivdi3.S b/lib/i386/udivdi3.S
new file mode 100644
index 000000000000..77936f858ac6
--- /dev/null
+++ b/lib/i386/udivdi3.S
@@ -0,0 +1,114 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// du_int __udivdi3(du_int a, du_int b);
+
+// result = a / b.
+// both inputs and the output are 64-bit unsigned integers.
+// This will do whatever the underlying hardware is set to do on division by zero.
+// No other exceptions are generated, as the divide cannot overflow.
+//
+// This is targeted at 32-bit x86 *only*, as this can be done directly in hardware
+// on x86_64. The performance goal is ~40 cycles per divide, which is faster than
+// currently possible via simulation of integer divides on the x87 unit.
+//
+// Stephen Canon, December 2008
+
+#ifdef __i386__
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__udivdi3)
+
+ pushl %ebx
+ movl 20(%esp), %ebx // Find the index i of the leading bit in b.
+ bsrl %ebx, %ecx // If the high word of b is zero, jump to
+ jz 9f // the code to handle that special case [9].
+
+ /* High word of b is known to be non-zero on this branch */
+
+ movl 16(%esp), %eax // Construct bhi, containing bits [1+i:32+i] of b
+
+ shrl %cl, %eax // Practically, this means that bhi is given by:
+ shrl %eax //
+ notl %ecx // bhi = (high word of b) << (31 - i) |
+ shll %cl, %ebx // (low word of b) >> (1 + i)
+ orl %eax, %ebx //
+ movl 12(%esp), %edx // Load the high and low words of a, and jump
+ movl 8(%esp), %eax // to [1] if the high word is larger than bhi
+ cmpl %ebx, %edx // to avoid overflowing the upcoming divide.
+ jae 1f
+
+ /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ divl %ebx // eax <-- qs, edx <-- r such that ahi:alo = bs*qs + r
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ shrl %cl, %eax // q = qs >> (1 + i)
+ movl %eax, %edi
+ mull 20(%esp) // q*blo
+ movl 12(%esp), %ebx
+ movl 16(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 24(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+ sbbl $0, %edi // decrement q if remainder is negative
+ xorl %edx, %edx
+ movl %edi, %eax
+ popl %edi
+ popl %ebx
+ retl
+
+
+1: /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ subl %ebx, %edx // subtract bhi from ahi so that divide will not
+ divl %ebx // overflow, and find q and r such that
+ //
+ // ahi:alo = (1:q)*bhi + r
+ //
+ // Note that q is a number in (31-i).(1+i)
+ // fix point.
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ orl $0x80000000, %eax
+ shrl %cl, %eax // q = (1:qs) >> (1 + i)
+ movl %eax, %edi
+ mull 20(%esp) // q*blo
+ movl 12(%esp), %ebx
+ movl 16(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 24(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+ sbbl $0, %edi // decrement q if remainder is negative
+ xorl %edx, %edx
+ movl %edi, %eax
+ popl %edi
+ popl %ebx
+ retl
+
+
+9: /* High word of b is zero on this branch */
+
+ movl 12(%esp), %eax // Find qhi and rhi such that
+ movl 16(%esp), %ecx //
+ xorl %edx, %edx // ahi = qhi*b + rhi with 0 ≤ rhi < b
+ divl %ecx //
+ movl %eax, %ebx //
+ movl 8(%esp), %eax // Find qlo such that
+ divl %ecx //
+ movl %ebx, %edx // rhi:alo = qlo*b + rlo with 0 ≤ rlo < b
+ popl %ebx //
+ retl // and return qhi:qlo
+
+#endif // __i386__
diff --git a/lib/i386/umoddi3.S b/lib/i386/umoddi3.S
new file mode 100644
index 000000000000..3cf8aeb62b28
--- /dev/null
+++ b/lib/i386/umoddi3.S
@@ -0,0 +1,125 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// du_int __umoddi3(du_int a, du_int b);
+
+// result = remainder of a / b.
+// both inputs and the output are 64-bit unsigned integers.
+// This will do whatever the underlying hardware is set to do on division by zero.
+// No other exceptions are generated, as the divide cannot overflow.
+//
+// This is targeted at 32-bit x86 *only*, as this can be done directly in hardware
+// on x86_64. The performance goal is ~40 cycles per divide, which is faster than
+// currently possible via simulation of integer divides on the x87 unit.
+//
+
+// Stephen Canon, December 2008
+
+#ifdef __i386__
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__umoddi3)
+
+ pushl %ebx
+ movl 20(%esp), %ebx // Find the index i of the leading bit in b.
+ bsrl %ebx, %ecx // If the high word of b is zero, jump to
+ jz 9f // the code to handle that special case [9].
+
+ /* High word of b is known to be non-zero on this branch */
+
+ movl 16(%esp), %eax // Construct bhi, containing bits [1+i:32+i] of b
+
+ shrl %cl, %eax // Practically, this means that bhi is given by:
+ shrl %eax //
+ notl %ecx // bhi = (high word of b) << (31 - i) |
+ shll %cl, %ebx // (low word of b) >> (1 + i)
+ orl %eax, %ebx //
+ movl 12(%esp), %edx // Load the high and low words of a, and jump
+ movl 8(%esp), %eax // to [2] if the high word is larger than bhi
+ cmpl %ebx, %edx // to avoid overflowing the upcoming divide.
+ jae 2f
+
+ /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ divl %ebx // eax <-- qs, edx <-- r such that ahi:alo = bs*qs + r
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ shrl %cl, %eax // q = qs >> (1 + i)
+ movl %eax, %edi
+ mull 20(%esp) // q*blo
+ movl 12(%esp), %ebx
+ movl 16(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 24(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+
+ jnc 1f // if positive, this is the result.
+ addl 20(%esp), %ebx // otherwise
+ adcl 24(%esp), %ecx // ECX:EBX = a - (q-1)*b = result
+1: movl %ebx, %eax
+ movl %ecx, %edx
+
+ popl %edi
+ popl %ebx
+ retl
+
+
+2: /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
+
+ subl %ebx, %edx // subtract bhi from ahi so that divide will not
+ divl %ebx // overflow, and find q and r such that
+ //
+ // ahi:alo = (1:q)*bhi + r
+ //
+ // Note that q is a number in (31-i).(1+i)
+ // fix point.
+
+ pushl %edi
+ notl %ecx
+ shrl %eax
+ orl $0x80000000, %eax
+ shrl %cl, %eax // q = (1:qs) >> (1 + i)
+ movl %eax, %edi
+ mull 20(%esp) // q*blo
+ movl 12(%esp), %ebx
+ movl 16(%esp), %ecx // ECX:EBX = a
+ subl %eax, %ebx
+ sbbl %edx, %ecx // ECX:EBX = a - q*blo
+ movl 24(%esp), %eax
+ imull %edi, %eax // q*bhi
+ subl %eax, %ecx // ECX:EBX = a - q*b
+
+ jnc 3f // if positive, this is the result.
+ addl 20(%esp), %ebx // otherwise
+ adcl 24(%esp), %ecx // ECX:EBX = a - (q-1)*b = result
+3: movl %ebx, %eax
+ movl %ecx, %edx
+
+ popl %edi
+ popl %ebx
+ retl
+
+
+
+9: /* High word of b is zero on this branch */
+
+ movl 12(%esp), %eax // Find qhi and rhi such that
+ movl 16(%esp), %ecx //
+ xorl %edx, %edx // ahi = qhi*b + rhi with 0 ≤ rhi < b
+ divl %ecx //
+ movl %eax, %ebx //
+ movl 8(%esp), %eax // Find rlo such that
+ divl %ecx //
+ movl %edx, %eax // rhi:alo = qlo*b + rlo with 0 ≤ rlo < b
+ popl %ebx //
+ xorl %edx, %edx // and return 0:rlo
+ retl //
+
+#endif // __i386__
diff --git a/lib/int_lib.h b/lib/int_lib.h
new file mode 100644
index 000000000000..912a12f5937c
--- /dev/null
+++ b/lib/int_lib.h
@@ -0,0 +1,155 @@
+/* ===-- int_lib.h - configuration header for compiler-rt -----------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file is a configuration header for compiler-rt.
+ * This file is not part of the interface of this library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#ifndef INT_LIB_H
+#define INT_LIB_H
+
+/* Assumption: signed integral is 2's complement */
+/* Assumption: right shift of signed negative is arithmetic shift */
+
+#include <limits.h>
+#include "endianness.h"
+#include <math.h>
+
+/* If compiling for kernel use, call panic() instead of abort(). */
+#ifdef KERNEL_USE
+extern void panic (const char *, ...);
+#define compilerrt_abort() \
+ panic("%s:%d: abort in %s", __FILE__, __LINE__, __FUNCTION__)
+#else
+#define compilerrt_abort() abort()
+#endif
+
+#if !defined(INFINITY) && defined(HUGE_VAL)
+#define INFINITY HUGE_VAL
+#endif /* INFINITY */
+
+typedef int si_int;
+typedef unsigned su_int;
+
+typedef long long di_int;
+typedef unsigned long long du_int;
+
+typedef union
+{
+ di_int all;
+ struct
+ {
+#if _YUGA_LITTLE_ENDIAN
+ su_int low;
+ si_int high;
+#else
+ si_int high;
+ su_int low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+ }s;
+} dwords;
+
+typedef union
+{
+ du_int all;
+ struct
+ {
+#if _YUGA_LITTLE_ENDIAN
+ su_int low;
+ su_int high;
+#else
+ su_int high;
+ su_int low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+ }s;
+} udwords;
+
+#if __x86_64
+
+typedef int ti_int __attribute__ ((mode (TI)));
+typedef unsigned tu_int __attribute__ ((mode (TI)));
+
+typedef union
+{
+ ti_int all;
+ struct
+ {
+#if _YUGA_LITTLE_ENDIAN
+ du_int low;
+ di_int high;
+#else
+ di_int high;
+ du_int low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+ }s;
+} twords;
+
+typedef union
+{
+ tu_int all;
+ struct
+ {
+#if _YUGA_LITTLE_ENDIAN
+ du_int low;
+ du_int high;
+#else
+ du_int high;
+ du_int low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+ }s;
+} utwords;
+
+static inline ti_int make_ti(di_int h, di_int l) {
+ twords r;
+ r.s.high = h;
+ r.s.low = l;
+ return r.all;
+}
+
+static inline tu_int make_tu(du_int h, du_int l) {
+ utwords r;
+ r.s.high = h;
+ r.s.low = l;
+ return r.all;
+}
+
+#endif /* __x86_64 */
+
+typedef union
+{
+ su_int u;
+ float f;
+} float_bits;
+
+typedef union
+{
+ udwords u;
+ double f;
+} double_bits;
+
+typedef struct
+{
+#if _YUGA_LITTLE_ENDIAN
+ udwords low;
+ udwords high;
+#else
+ udwords high;
+ udwords low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+} uqwords;
+
+typedef union
+{
+ uqwords u;
+ long double f;
+} long_double_bits;
+
+#endif /* INT_LIB_H */
diff --git a/lib/lshrdi3.c b/lib/lshrdi3.c
new file mode 100644
index 000000000000..57484ee750af
--- /dev/null
+++ b/lib/lshrdi3.c
@@ -0,0 +1,41 @@
+/* ===-- lshrdi3.c - Implement __lshrdi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __lshrdi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: logical a >> b */
+
+/* Precondition: 0 <= b < bits_in_dword */
+
+di_int
+__lshrdi3(di_int a, si_int b)
+{
+ const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);
+ udwords input;
+ udwords result;
+ input.all = a;
+ if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */
+ {
+ result.s.high = 0;
+ result.s.low = input.s.high >> (b - bits_in_word);
+ }
+ else /* 0 <= b < bits_in_word */
+ {
+ if (b == 0)
+ return a;
+ result.s.high = input.s.high >> b;
+ result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b);
+ }
+ return result.all;
+}
diff --git a/lib/lshrti3.c b/lib/lshrti3.c
new file mode 100644
index 000000000000..3272c9ca831a
--- /dev/null
+++ b/lib/lshrti3.c
@@ -0,0 +1,45 @@
+/* ===-- lshrti3.c - Implement __lshrti3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __lshrti3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: logical a >> b */
+
+/* Precondition: 0 <= b < bits_in_tword */
+
+ti_int
+__lshrti3(ti_int a, si_int b)
+{
+ const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT);
+ utwords input;
+ utwords result;
+ input.all = a;
+ if (b & bits_in_dword) /* bits_in_dword <= b < bits_in_tword */
+ {
+ result.s.high = 0;
+ result.s.low = input.s.high >> (b - bits_in_dword);
+ }
+ else /* 0 <= b < bits_in_dword */
+ {
+ if (b == 0)
+ return a;
+ result.s.high = input.s.high >> b;
+ result.s.low = (input.s.high << (bits_in_dword - b)) | (input.s.low >> b);
+ }
+ return result.all;
+}
+
+#endif /* __x86_64 */
diff --git a/lib/moddi3.c b/lib/moddi3.c
new file mode 100644
index 000000000000..453355596825
--- /dev/null
+++ b/lib/moddi3.c
@@ -0,0 +1,32 @@
+/*===-- moddi3.c - Implement __moddi3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __moddi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+du_int __udivmoddi4(du_int a, du_int b, du_int* rem);
+
+/* Returns: a % b */
+
+di_int
+__moddi3(di_int a, di_int b)
+{
+ const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1;
+ di_int s = b >> bits_in_dword_m1; /* s = b < 0 ? -1 : 0 */
+ b = (b ^ s) - s; /* negate if s == -1 */
+ s = a >> bits_in_dword_m1; /* s = a < 0 ? -1 : 0 */
+ a = (a ^ s) - s; /* negate if s == -1 */
+ di_int r;
+ __udivmoddi4(a, b, (du_int*)&r);
+ return (r ^ s) - s; /* negate if s == -1 */
+}
diff --git a/lib/modsi3.c b/lib/modsi3.c
new file mode 100644
index 000000000000..c9214a24f39b
--- /dev/null
+++ b/lib/modsi3.c
@@ -0,0 +1,23 @@
+/* ===-- modsi3.c - Implement __modsi3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __modsi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: a % b */
+
+si_int
+__modsi3(si_int a, si_int b)
+{
+ return a - (a / b) * b;
+}
diff --git a/lib/modti3.c b/lib/modti3.c
new file mode 100644
index 000000000000..75d688ef0a63
--- /dev/null
+++ b/lib/modti3.c
@@ -0,0 +1,36 @@
+/* ===-- modti3.c - Implement __modti3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __modti3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
+
+/*Returns: a % b */
+
+ti_int
+__modti3(ti_int a, ti_int b)
+{
+ const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1;
+ ti_int s = b >> bits_in_tword_m1; /* s = b < 0 ? -1 : 0 */
+ b = (b ^ s) - s; /* negate if s == -1 */
+ s = a >> bits_in_tword_m1; /* s = a < 0 ? -1 : 0 */
+ a = (a ^ s) - s; /* negate if s == -1 */
+ ti_int r;
+ __udivmodti4(a, b, (tu_int*)&r);
+ return (r ^ s) - s; /* negate if s == -1 */
+}
+
+#endif
diff --git a/lib/muldc3.c b/lib/muldc3.c
new file mode 100644
index 000000000000..c048d84faa1f
--- /dev/null
+++ b/lib/muldc3.c
@@ -0,0 +1,74 @@
+/* ===-- muldc3.c - Implement __muldc3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __muldc3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+
+/* Returns: the product of a + ib and c + id */
+
+double _Complex
+__muldc3(double __a, double __b, double __c, double __d)
+{
+ double __ac = __a * __c;
+ double __bd = __b * __d;
+ double __ad = __a * __d;
+ double __bc = __b * __c;
+ double _Complex z;
+ __real__ z = __ac - __bd;
+ __imag__ z = __ad + __bc;
+ if (isnan(__real__ z) && isnan(__imag__ z))
+ {
+ int __recalc = 0;
+ if (isinf(__a) || isinf(__b))
+ {
+ __a = copysign(isinf(__a) ? 1 : 0, __a);
+ __b = copysign(isinf(__b) ? 1 : 0, __b);
+ if (isnan(__c))
+ __c = copysign(0, __c);
+ if (isnan(__d))
+ __d = copysign(0, __d);
+ __recalc = 1;
+ }
+ if (isinf(__c) || isinf(__d))
+ {
+ __c = copysign(isinf(__c) ? 1 : 0, __c);
+ __d = copysign(isinf(__d) ? 1 : 0, __d);
+ if (isnan(__a))
+ __a = copysign(0, __a);
+ if (isnan(__b))
+ __b = copysign(0, __b);
+ __recalc = 1;
+ }
+ if (!__recalc && (isinf(__ac) || isinf(__bd) ||
+ isinf(__ad) || isinf(__bc)))
+ {
+ if (isnan(__a))
+ __a = copysign(0, __a);
+ if (isnan(__b))
+ __b = copysign(0, __b);
+ if (isnan(__c))
+ __c = copysign(0, __c);
+ if (isnan(__d))
+ __d = copysign(0, __d);
+ __recalc = 1;
+ }
+ if (__recalc)
+ {
+ __real__ z = INFINITY * (__a * __c - __b * __d);
+ __imag__ z = INFINITY * (__a * __d + __b * __c);
+ }
+ }
+ return z;
+}
diff --git a/lib/muldf3.c b/lib/muldf3.c
new file mode 100644
index 000000000000..63a473e88d21
--- /dev/null
+++ b/lib/muldf3.c
@@ -0,0 +1,119 @@
+//===-- lib/muldf3.c - Double-precision multiplication ------------*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements double-precision soft-float multiplication
+// with the IEEE-754 default rounding (to nearest, ties to even).
+//
+//===----------------------------------------------------------------------===//
+
+#define DOUBLE_PRECISION
+#include "fp_lib.h"
+
+fp_t __muldf3(fp_t a, fp_t b) {
+
+ const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;
+ const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;
+ const rep_t productSign = (toRep(a) ^ toRep(b)) & signBit;
+
+ rep_t aSignificand = toRep(a) & significandMask;
+ rep_t bSignificand = toRep(b) & significandMask;
+ int scale = 0;
+
+ // Detect if a or b is zero, denormal, infinity, or NaN.
+ if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) {
+
+ const rep_t aAbs = toRep(a) & absMask;
+ const rep_t bAbs = toRep(b) & absMask;
+
+ // NaN * anything = qNaN
+ if (aAbs > infRep) return fromRep(toRep(a) | quietBit);
+ // anything * NaN = qNaN
+ if (bAbs > infRep) return fromRep(toRep(b) | quietBit);
+
+ if (aAbs == infRep) {
+ // infinity * non-zero = +/- infinity
+ if (bAbs) return fromRep(aAbs | productSign);
+ // infinity * zero = NaN
+ else return fromRep(qnanRep);
+ }
+
+ if (bAbs == infRep) {
+ // non-zero * infinity = +/- infinity
+ if (aAbs) return fromRep(bAbs | productSign);
+ // zero * infinity = NaN
+ else return fromRep(qnanRep);
+ }
+
+ // zero * anything = +/- zero
+ if (!aAbs) return fromRep(productSign);
+ // anything * zero = +/- zero
+ if (!bAbs) return fromRep(productSign);
+
+ // one or both of a or b is denormal, the other (if applicable) is a
+ // normal number. Renormalize one or both of a and b, and set scale to
+ // include the necessary exponent adjustment.
+ if (aAbs < implicitBit) scale += normalize(&aSignificand);
+ if (bAbs < implicitBit) scale += normalize(&bSignificand);
+ }
+
+ // Or in the implicit significand bit. (If we fell through from the
+ // denormal path it was already set by normalize( ), but setting it twice
+ // won't hurt anything.)
+ aSignificand |= implicitBit;
+ bSignificand |= implicitBit;
+
+ // Get the significand of a*b. Before multiplying the significands, shift
+ // one of them left to left-align it in the field. Thus, the product will
+ // have (exponentBits + 2) integral digits, all but two of which must be
+ // zero. Normalizing this result is just a conditional left-shift by one
+ // and bumping the exponent accordingly.
+ rep_t productHi, productLo;
+ wideMultiply(aSignificand, bSignificand << exponentBits,
+ &productHi, &productLo);
+
+ int productExponent = aExponent + bExponent - exponentBias + scale;
+
+ // Normalize the significand, adjust exponent if needed.
+ if (productHi & implicitBit) productExponent++;
+ else wideLeftShift(&productHi, &productLo, 1);
+
+ // If we have overflowed the type, return +/- infinity.
+ if (productExponent >= maxExponent) return fromRep(infRep | productSign);
+
+ if (productExponent <= 0) {
+ // Result is denormal before rounding
+ //
+ // If the result is so small that it just underflows to zero, return
+ // a zero of the appropriate sign. Mathematically there is no need to
+ // handle this case separately, but we make it a special case to
+ // simplify the shift logic.
+ const int shift = 1 - productExponent;
+ if (shift >= typeWidth) return fromRep(productSign);
+
+ // Otherwise, shift the significand of the result so that the round
+ // bit is the high bit of productLo.
+ wideRightShiftWithSticky(&productHi, &productLo, shift);
+ }
+
+ else {
+ // Result is normal before rounding; insert the exponent.
+ productHi &= significandMask;
+ productHi |= (rep_t)productExponent << significandBits;
+ }
+
+ // Insert the sign of the result:
+ productHi |= productSign;
+
+ // Final rounding. The final result may overflow to infinity, or underflow
+ // to zero, but those are the correct results in those cases. We use the
+ // default IEEE-754 round-to-nearest, ties-to-even rounding mode.
+ if (productLo > signBit) productHi++;
+ if (productLo == signBit) productHi += productHi & 1;
+ return fromRep(productHi);
+}
diff --git a/lib/muldi3.c b/lib/muldi3.c
new file mode 100644
index 000000000000..38963b72630d
--- /dev/null
+++ b/lib/muldi3.c
@@ -0,0 +1,54 @@
+/* ===-- muldi3.c - Implement __muldi3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __muldi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: a * b */
+
+static
+di_int
+__muldsi3(su_int a, su_int b)
+{
+ dwords r;
+ const int bits_in_word_2 = (int)(sizeof(si_int) * CHAR_BIT) / 2;
+ const su_int lower_mask = (su_int)~0 >> bits_in_word_2;
+ r.s.low = (a & lower_mask) * (b & lower_mask);
+ su_int t = r.s.low >> bits_in_word_2;
+ r.s.low &= lower_mask;
+ t += (a >> bits_in_word_2) * (b & lower_mask);
+ r.s.low += (t & lower_mask) << bits_in_word_2;
+ r.s.high = t >> bits_in_word_2;
+ t = r.s.low >> bits_in_word_2;
+ r.s.low &= lower_mask;
+ t += (b >> bits_in_word_2) * (a & lower_mask);
+ r.s.low += (t & lower_mask) << bits_in_word_2;
+ r.s.high += t >> bits_in_word_2;
+ r.s.high += (a >> bits_in_word_2) * (b >> bits_in_word_2);
+ return r.all;
+}
+
+/* Returns: a * b */
+
+di_int
+__muldi3(di_int a, di_int b)
+{
+ dwords x;
+ x.all = a;
+ dwords y;
+ y.all = b;
+ dwords r;
+ r.all = __muldsi3(x.s.low, y.s.low);
+ r.s.high += x.s.high * y.s.low + x.s.low * y.s.high;
+ return r.all;
+}
diff --git a/lib/mulsc3.c b/lib/mulsc3.c
new file mode 100644
index 000000000000..c7b9f6417269
--- /dev/null
+++ b/lib/mulsc3.c
@@ -0,0 +1,74 @@
+/* ===-- mulsc3.c - Implement __mulsc3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __mulsc3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+
+/* Returns: the product of a + ib and c + id */
+
+float _Complex
+__mulsc3(float __a, float __b, float __c, float __d)
+{
+ float __ac = __a * __c;
+ float __bd = __b * __d;
+ float __ad = __a * __d;
+ float __bc = __b * __c;
+ float _Complex z;
+ __real__ z = __ac - __bd;
+ __imag__ z = __ad + __bc;
+ if (isnan(__real__ z) && isnan(__imag__ z))
+ {
+ int __recalc = 0;
+ if (isinf(__a) || isinf(__b))
+ {
+ __a = copysignf(isinf(__a) ? 1 : 0, __a);
+ __b = copysignf(isinf(__b) ? 1 : 0, __b);
+ if (isnan(__c))
+ __c = copysignf(0, __c);
+ if (isnan(__d))
+ __d = copysignf(0, __d);
+ __recalc = 1;
+ }
+ if (isinf(__c) || isinf(__d))
+ {
+ __c = copysignf(isinf(__c) ? 1 : 0, __c);
+ __d = copysignf(isinf(__d) ? 1 : 0, __d);
+ if (isnan(__a))
+ __a = copysignf(0, __a);
+ if (isnan(__b))
+ __b = copysignf(0, __b);
+ __recalc = 1;
+ }
+ if (!__recalc && (isinf(__ac) || isinf(__bd) ||
+ isinf(__ad) || isinf(__bc)))
+ {
+ if (isnan(__a))
+ __a = copysignf(0, __a);
+ if (isnan(__b))
+ __b = copysignf(0, __b);
+ if (isnan(__c))
+ __c = copysignf(0, __c);
+ if (isnan(__d))
+ __d = copysignf(0, __d);
+ __recalc = 1;
+ }
+ if (__recalc)
+ {
+ __real__ z = INFINITY * (__a * __c - __b * __d);
+ __imag__ z = INFINITY * (__a * __d + __b * __c);
+ }
+ }
+ return z;
+}
diff --git a/lib/mulsf3.c b/lib/mulsf3.c
new file mode 100644
index 000000000000..6bd2f9dcae50
--- /dev/null
+++ b/lib/mulsf3.c
@@ -0,0 +1,109 @@
+//===-- lib/mulsf3.c - Single-precision multiplication ------------*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements single-precision soft-float multiplication
+// with the IEEE-754 default rounding (to nearest, ties to even).
+//
+//===----------------------------------------------------------------------===//
+
+#define SINGLE_PRECISION
+#include "fp_lib.h"
+
+fp_t __mulsf3(fp_t a, fp_t b) {
+
+ const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;
+ const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;
+ const rep_t productSign = (toRep(a) ^ toRep(b)) & signBit;
+
+ rep_t aSignificand = toRep(a) & significandMask;
+ rep_t bSignificand = toRep(b) & significandMask;
+ int scale = 0;
+
+ // Detect if a or b is zero, denormal, infinity, or NaN.
+ if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) {
+
+ const rep_t aAbs = toRep(a) & absMask;
+ const rep_t bAbs = toRep(b) & absMask;
+
+ // NaN * anything = qNaN
+ if (aAbs > infRep) return fromRep(toRep(a) | quietBit);
+ // anything * NaN = qNaN
+ if (bAbs > infRep) return fromRep(toRep(b) | quietBit);
+
+ if (aAbs == infRep) {
+ // infinity * non-zero = +/- infinity
+ if (bAbs) return fromRep(aAbs | productSign);
+ // infinity * zero = NaN
+ else return fromRep(qnanRep);
+ }
+
+ if (bAbs == infRep) {
+ // non-zero * infinity = +/- infinity
+ if (aAbs) return fromRep(bAbs | productSign);
+ // zero * infinity = NaN
+ else return fromRep(qnanRep);
+ }
+
+ // zero * anything = +/- zero
+ if (!aAbs) return fromRep(productSign);
+ // anything * zero = +/- zero
+ if (!bAbs) return fromRep(productSign);
+
+ // one or both of a or b is denormal, the other (if applicable) is a
+ // normal number. Renormalize one or both of a and b, and set scale to
+ // include the necessary exponent adjustment.
+ if (aAbs < implicitBit) scale += normalize(&aSignificand);
+ if (bAbs < implicitBit) scale += normalize(&bSignificand);
+ }
+
+ // Or in the implicit significand bit. (If we fell through from the
+ // denormal path it was already set by normalize( ), but setting it twice
+ // won't hurt anything.)
+ aSignificand |= implicitBit;
+ bSignificand |= implicitBit;
+
+ // Get the significand of a*b. Before multiplying the significands, shift
+ // one of them left to left-align it in the field. Thus, the product will
+ // have (exponentBits + 2) integral digits, all but two of which must be
+ // zero. Normalizing this result is just a conditional left-shift by one
+ // and bumping the exponent accordingly.
+ rep_t productHi, productLo;
+ wideMultiply(aSignificand, bSignificand << exponentBits,
+ &productHi, &productLo);
+
+ int productExponent = aExponent + bExponent - exponentBias + scale;
+
+ // Normalize the significand, adjust exponent if needed.
+ if (productHi & implicitBit) productExponent++;
+ else wideLeftShift(&productHi, &productLo, 1);
+
+ // If we have overflowed the type, return +/- infinity.
+ if (productExponent >= maxExponent) return fromRep(infRep | productSign);
+
+ if (productExponent <= 0) {
+ // Result is denormal before rounding, the exponent is zero and we
+ // need to shift the significand.
+ wideRightShiftWithSticky(&productHi, &productLo, 1 - productExponent);
+ }
+
+ else {
+ // Result is normal before rounding; insert the exponent.
+ productHi &= significandMask;
+ productHi |= (rep_t)productExponent << significandBits;
+ }
+
+ // Insert the sign of the result:
+ productHi |= productSign;
+
+ // Final rounding. The final result may overflow to infinity, or underflow
+ // to zero, but those are the correct results in those cases.
+ if (productLo > signBit) productHi++;
+ if (productLo == signBit) productHi += productHi & 1;
+ return fromRep(productHi);
+}
diff --git a/lib/multi3.c b/lib/multi3.c
new file mode 100644
index 000000000000..13a386781a9a
--- /dev/null
+++ b/lib/multi3.c
@@ -0,0 +1,58 @@
+/* ===-- multi3.c - Implement __multi3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+
+ * This file implements __multi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: a * b */
+
+static
+ti_int
+__mulddi3(du_int a, du_int b)
+{
+ twords r;
+ const int bits_in_dword_2 = (int)(sizeof(di_int) * CHAR_BIT) / 2;
+ const du_int lower_mask = (du_int)~0 >> bits_in_dword_2;
+ r.s.low = (a & lower_mask) * (b & lower_mask);
+ du_int t = r.s.low >> bits_in_dword_2;
+ r.s.low &= lower_mask;
+ t += (a >> bits_in_dword_2) * (b & lower_mask);
+ r.s.low += (t & lower_mask) << bits_in_dword_2;
+ r.s.high = t >> bits_in_dword_2;
+ t = r.s.low >> bits_in_dword_2;
+ r.s.low &= lower_mask;
+ t += (b >> bits_in_dword_2) * (a & lower_mask);
+ r.s.low += (t & lower_mask) << bits_in_dword_2;
+ r.s.high += t >> bits_in_dword_2;
+ r.s.high += (a >> bits_in_dword_2) * (b >> bits_in_dword_2);
+ return r.all;
+}
+
+/* Returns: a * b */
+
+ti_int
+__multi3(ti_int a, ti_int b)
+{
+ twords x;
+ x.all = a;
+ twords y;
+ y.all = b;
+ twords r;
+ r.all = __mulddi3(x.s.low, y.s.low);
+ r.s.high += x.s.high * y.s.low + x.s.low * y.s.high;
+ return r.all;
+}
+
+#endif /* __x86_64 */
diff --git a/lib/mulvdi3.c b/lib/mulvdi3.c
new file mode 100644
index 000000000000..295ae18d3c85
--- /dev/null
+++ b/lib/mulvdi3.c
@@ -0,0 +1,57 @@
+/*===-- mulvdi3.c - Implement __mulvdi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __mulvdi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: a * b */
+
+/* Effects: aborts if a * b overflows */
+
+di_int
+__mulvdi3(di_int a, di_int b)
+{
+ const int N = (int)(sizeof(di_int) * CHAR_BIT);
+ const di_int MIN = (di_int)1 << (N-1);
+ const di_int MAX = ~MIN;
+ if (a == MIN)
+ {
+ if (b == 0 || b == 1)
+ return a * b;
+ compilerrt_abort();
+ }
+ if (b == MIN)
+ {
+ if (a == 0 || a == 1)
+ return a * b;
+ compilerrt_abort();
+ }
+ di_int sa = a >> (N - 1);
+ di_int abs_a = (a ^ sa) - sa;
+ di_int sb = b >> (N - 1);
+ di_int abs_b = (b ^ sb) - sb;
+ if (abs_a < 2 || abs_b < 2)
+ return a * b;
+ if (sa == sb)
+ {
+ if (abs_a > MAX / abs_b)
+ compilerrt_abort();
+ }
+ else
+ {
+ if (abs_a > MIN / -abs_b)
+ compilerrt_abort();
+ }
+ return a * b;
+}
diff --git a/lib/mulvsi3.c b/lib/mulvsi3.c
new file mode 100644
index 000000000000..b4a509be2093
--- /dev/null
+++ b/lib/mulvsi3.c
@@ -0,0 +1,57 @@
+/* ===-- mulvsi3.c - Implement __mulvsi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __mulvsi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: a * b */
+
+/* Effects: aborts if a * b overflows */
+
+si_int
+__mulvsi3(si_int a, si_int b)
+{
+ const int N = (int)(sizeof(si_int) * CHAR_BIT);
+ const si_int MIN = (si_int)1 << (N-1);
+ const si_int MAX = ~MIN;
+ if (a == MIN)
+ {
+ if (b == 0 || b == 1)
+ return a * b;
+ compilerrt_abort();
+ }
+ if (b == MIN)
+ {
+ if (a == 0 || a == 1)
+ return a * b;
+ compilerrt_abort();
+ }
+ si_int sa = a >> (N - 1);
+ si_int abs_a = (a ^ sa) - sa;
+ si_int sb = b >> (N - 1);
+ si_int abs_b = (b ^ sb) - sb;
+ if (abs_a < 2 || abs_b < 2)
+ return a * b;
+ if (sa == sb)
+ {
+ if (abs_a > MAX / abs_b)
+ compilerrt_abort();
+ }
+ else
+ {
+ if (abs_a > MIN / -abs_b)
+ compilerrt_abort();
+ }
+ return a * b;
+}
diff --git a/lib/mulvti3.c b/lib/mulvti3.c
new file mode 100644
index 000000000000..778222ee6c96
--- /dev/null
+++ b/lib/mulvti3.c
@@ -0,0 +1,61 @@
+/* ===-- mulvti3.c - Implement __mulvti3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __mulvti3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: a * b */
+
+/* Effects: aborts if a * b overflows */
+
+ti_int
+__mulvti3(ti_int a, ti_int b)
+{
+ const int N = (int)(sizeof(ti_int) * CHAR_BIT);
+ const ti_int MIN = (ti_int)1 << (N-1);
+ const ti_int MAX = ~MIN;
+ if (a == MIN)
+ {
+ if (b == 0 || b == 1)
+ return a * b;
+ compilerrt_abort();
+ }
+ if (b == MIN)
+ {
+ if (a == 0 || a == 1)
+ return a * b;
+ compilerrt_abort();
+ }
+ ti_int sa = a >> (N - 1);
+ ti_int abs_a = (a ^ sa) - sa;
+ ti_int sb = b >> (N - 1);
+ ti_int abs_b = (b ^ sb) - sb;
+ if (abs_a < 2 || abs_b < 2)
+ return a * b;
+ if (sa == sb)
+ {
+ if (abs_a > MAX / abs_b)
+ compilerrt_abort();
+ }
+ else
+ {
+ if (abs_a > MIN / -abs_b)
+ compilerrt_abort();
+ }
+ return a * b;
+}
+
+#endif
diff --git a/lib/mulxc3.c b/lib/mulxc3.c
new file mode 100644
index 000000000000..94895f2551fd
--- /dev/null
+++ b/lib/mulxc3.c
@@ -0,0 +1,78 @@
+/* ===-- mulxc3.c - Implement __mulxc3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __mulxc3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+
+/* Returns: the product of a + ib and c + id */
+
+long double _Complex
+__mulxc3(long double __a, long double __b, long double __c, long double __d)
+{
+ long double __ac = __a * __c;
+ long double __bd = __b * __d;
+ long double __ad = __a * __d;
+ long double __bc = __b * __c;
+ long double _Complex z;
+ __real__ z = __ac - __bd;
+ __imag__ z = __ad + __bc;
+ if (isnan(__real__ z) && isnan(__imag__ z))
+ {
+ int __recalc = 0;
+ if (isinf(__a) || isinf(__b))
+ {
+ __a = copysignl(isinf(__a) ? 1 : 0, __a);
+ __b = copysignl(isinf(__b) ? 1 : 0, __b);
+ if (isnan(__c))
+ __c = copysignl(0, __c);
+ if (isnan(__d))
+ __d = copysignl(0, __d);
+ __recalc = 1;
+ }
+ if (isinf(__c) || isinf(__d))
+ {
+ __c = copysignl(isinf(__c) ? 1 : 0, __c);
+ __d = copysignl(isinf(__d) ? 1 : 0, __d);
+ if (isnan(__a))
+ __a = copysignl(0, __a);
+ if (isnan(__b))
+ __b = copysignl(0, __b);
+ __recalc = 1;
+ }
+ if (!__recalc && (isinf(__ac) || isinf(__bd) ||
+ isinf(__ad) || isinf(__bc)))
+ {
+ if (isnan(__a))
+ __a = copysignl(0, __a);
+ if (isnan(__b))
+ __b = copysignl(0, __b);
+ if (isnan(__c))
+ __c = copysignl(0, __c);
+ if (isnan(__d))
+ __d = copysignl(0, __d);
+ __recalc = 1;
+ }
+ if (__recalc)
+ {
+ __real__ z = INFINITY * (__a * __c - __b * __d);
+ __imag__ z = INFINITY * (__a * __d + __b * __c);
+ }
+ }
+ return z;
+}
+
+#endif
diff --git a/lib/negdf2.c b/lib/negdf2.c
new file mode 100644
index 000000000000..527b068a17a8
--- /dev/null
+++ b/lib/negdf2.c
@@ -0,0 +1,19 @@
+//===-- lib/negdf2.c - double-precision negation ------------------*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements double-precision soft-float negation.
+//
+//===----------------------------------------------------------------------===//
+
+#define DOUBLE_PRECISION
+#include "fp_lib.h"
+
+fp_t __negdf2(fp_t a) {
+ return fromRep(toRep(a) ^ signBit);
+}
diff --git a/lib/negdi2.c b/lib/negdi2.c
new file mode 100644
index 000000000000..707b0dd78255
--- /dev/null
+++ b/lib/negdi2.c
@@ -0,0 +1,26 @@
+/* ===-- negdi2.c - Implement __negdi2 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __negdi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: -a */
+
+di_int
+__negdi2(di_int a)
+{
+ /* Note: this routine is here for API compatibility; any sane compiler
+ * should expand it inline.
+ */
+ return -a;
+}
diff --git a/lib/negsf2.c b/lib/negsf2.c
new file mode 100644
index 000000000000..5e91e87e9888
--- /dev/null
+++ b/lib/negsf2.c
@@ -0,0 +1,19 @@
+//===-- lib/negsf2.c - single-precision negation ------------------*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements single-precision soft-float negation.
+//
+//===----------------------------------------------------------------------===//
+
+#define SINGLE_PRECISION
+#include "fp_lib.h"
+
+fp_t __negsf2(fp_t a) {
+ return fromRep(toRep(a) ^ signBit);
+}
diff --git a/lib/negti2.c b/lib/negti2.c
new file mode 100644
index 000000000000..6ce6a0403acc
--- /dev/null
+++ b/lib/negti2.c
@@ -0,0 +1,30 @@
+/* ===-- negti2.c - Implement __negti2 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __negti2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: -a */
+
+ti_int
+__negti2(ti_int a)
+{
+ /* Note: this routine is here for API compatibility; any sane compiler
+ * should expand it inline.
+ */
+ return -a;
+}
+
+#endif
diff --git a/lib/negvdi2.c b/lib/negvdi2.c
new file mode 100644
index 000000000000..0baf377400e6
--- /dev/null
+++ b/lib/negvdi2.c
@@ -0,0 +1,29 @@
+/* ===-- negvdi2.c - Implement __negvdi2 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __negvdi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: -a */
+
+/* Effects: aborts if -a overflows */
+
+di_int
+__negvdi2(di_int a)
+{
+ const di_int MIN = (di_int)1 << ((int)(sizeof(di_int) * CHAR_BIT)-1);
+ if (a == MIN)
+ compilerrt_abort();
+ return -a;
+}
diff --git a/lib/negvsi2.c b/lib/negvsi2.c
new file mode 100644
index 000000000000..e5a36a5dacf5
--- /dev/null
+++ b/lib/negvsi2.c
@@ -0,0 +1,29 @@
+/* ===-- negvsi2.c - Implement __negvsi2 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __negvsi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: -a */
+
+/* Effects: aborts if -a overflows */
+
+si_int
+__negvsi2(si_int a)
+{
+ const si_int MIN = (si_int)1 << ((int)(sizeof(si_int) * CHAR_BIT)-1);
+ if (a == MIN)
+ compilerrt_abort();
+ return -a;
+}
diff --git a/lib/negvti2.c b/lib/negvti2.c
new file mode 100644
index 000000000000..d56e1e32ade1
--- /dev/null
+++ b/lib/negvti2.c
@@ -0,0 +1,33 @@
+/*===-- negvti2.c - Implement __negvti2 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ *===----------------------------------------------------------------------===
+ *
+ *This file implements __negvti2 for the compiler_rt library.
+ *
+ *===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: -a */
+
+/* Effects: aborts if -a overflows */
+
+ti_int
+__negvti2(ti_int a)
+{
+ const ti_int MIN = (ti_int)1 << ((int)(sizeof(ti_int) * CHAR_BIT)-1);
+ if (a == MIN)
+ compilerrt_abort();
+ return -a;
+}
+
+#endif
diff --git a/lib/paritydi2.c b/lib/paritydi2.c
new file mode 100644
index 000000000000..90e5559bc799
--- /dev/null
+++ b/lib/paritydi2.c
@@ -0,0 +1,27 @@
+/* ===-- paritydi2.c - Implement __paritydi2 -------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __paritydi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: 1 if number of bits is odd else returns 0 */
+
+si_int __paritysi2(si_int a);
+
+si_int
+__paritydi2(di_int a)
+{
+ dwords x;
+ x.all = a;
+ return __paritysi2(x.s.high ^ x.s.low);
+}
diff --git a/lib/paritysi2.c b/lib/paritysi2.c
new file mode 100644
index 000000000000..ba05782a2a7e
--- /dev/null
+++ b/lib/paritysi2.c
@@ -0,0 +1,27 @@
+/* ===-- paritysi2.c - Implement __paritysi2 -------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __paritysi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: 1 if number of bits is odd else returns 0 */
+
+si_int
+__paritysi2(si_int a)
+{
+ su_int x = (su_int)a;
+ x ^= x >> 16;
+ x ^= x >> 8;
+ x ^= x >> 4;
+ return (0x6996 >> (x & 0xF)) & 1;
+}
diff --git a/lib/parityti2.c b/lib/parityti2.c
new file mode 100644
index 000000000000..650d417936af
--- /dev/null
+++ b/lib/parityti2.c
@@ -0,0 +1,31 @@
+/* ===-- parityti2.c - Implement __parityti2 -------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __parityti2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: 1 if number of bits is odd else returns 0 */
+
+si_int __paritydi2(di_int a);
+
+si_int
+__parityti2(ti_int a)
+{
+ twords x;
+ x.all = a;
+ return __paritydi2(x.s.high ^ x.s.low);
+}
+
+#endif
diff --git a/lib/popcountdi2.c b/lib/popcountdi2.c
new file mode 100644
index 000000000000..78b6d88d7311
--- /dev/null
+++ b/lib/popcountdi2.c
@@ -0,0 +1,36 @@
+/* ===-- popcountdi2.c - Implement __popcountdi2 ----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __popcountdi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: count of 1 bits */
+
+si_int
+__popcountdi2(di_int a)
+{
+ du_int x2 = (du_int)a;
+ x2 = x2 - ((x2 >> 1) & 0x5555555555555555uLL);
+ /* Every 2 bits holds the sum of every pair of bits (32) */
+ x2 = ((x2 >> 2) & 0x3333333333333333uLL) + (x2 & 0x3333333333333333uLL);
+ /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (16) */
+ x2 = (x2 + (x2 >> 4)) & 0x0F0F0F0F0F0F0F0FuLL;
+ /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (8) */
+ su_int x = (su_int)(x2 + (x2 >> 32));
+ /* The lower 32 bits hold four 16 bit sums (5 significant bits). */
+ /* Upper 32 bits are garbage */
+ x = x + (x >> 16);
+ /* The lower 16 bits hold two 32 bit sums (6 significant bits). */
+ /* Upper 16 bits are garbage */
+ return (x + (x >> 8)) & 0x0000007F; /* (7 significant bits) */
+}
diff --git a/lib/popcountsi2.c b/lib/popcountsi2.c
new file mode 100644
index 000000000000..4f092ee4017c
--- /dev/null
+++ b/lib/popcountsi2.c
@@ -0,0 +1,33 @@
+/* ===-- popcountsi2.c - Implement __popcountsi2 ---------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __popcountsi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: count of 1 bits */
+
+si_int
+__popcountsi2(si_int a)
+{
+ su_int x = (su_int)a;
+ x = x - ((x >> 1) & 0x55555555);
+ /* Every 2 bits holds the sum of every pair of bits */
+ x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
+ /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) */
+ x = (x + (x >> 4)) & 0x0F0F0F0F;
+ /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) */
+ x = (x + (x >> 16));
+ /* The lower 16 bits hold two 8 bit sums (5 significant bits).*/
+ /* Upper 16 bits are garbage */
+ return (x + (x >> 8)) & 0x0000003F; /* (6 significant bits) */
+}
diff --git a/lib/popcountti2.c b/lib/popcountti2.c
new file mode 100644
index 000000000000..16f89b7abab8
--- /dev/null
+++ b/lib/popcountti2.c
@@ -0,0 +1,44 @@
+/* ===-- popcountti2.c - Implement __popcountti2 ----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __popcountti2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: count of 1 bits */
+
+si_int
+__popcountti2(ti_int a)
+{
+ tu_int x3 = (tu_int)a;
+ x3 = x3 - ((x3 >> 1) & (((tu_int)0x5555555555555555uLL << 64) |
+ 0x5555555555555555uLL));
+ /* Every 2 bits holds the sum of every pair of bits (64) */
+ x3 = ((x3 >> 2) & (((tu_int)0x3333333333333333uLL << 64) | 0x3333333333333333uLL))
+ + (x3 & (((tu_int)0x3333333333333333uLL << 64) | 0x3333333333333333uLL));
+ /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (32) */
+ x3 = (x3 + (x3 >> 4))
+ & (((tu_int)0x0F0F0F0F0F0F0F0FuLL << 64) | 0x0F0F0F0F0F0F0F0FuLL);
+ /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (16) */
+ du_int x2 = (du_int)(x3 + (x3 >> 64));
+ /* Every 8 bits holds the sum of every 8-set of bits (5 significant bits) (8) */
+ su_int x = (su_int)(x2 + (x2 >> 32));
+ /* Every 8 bits holds the sum of every 8-set of bits (6 significant bits) (4) */
+ x = x + (x >> 16);
+ /* Every 8 bits holds the sum of every 8-set of bits (7 significant bits) (2) */
+ /* Upper 16 bits are garbage */
+ return (x + (x >> 8)) & 0xFF; /* (8 significant bits) */
+}
+
+#endif
diff --git a/lib/powidf2.c b/lib/powidf2.c
new file mode 100644
index 000000000000..37972b68b6ea
--- /dev/null
+++ b/lib/powidf2.c
@@ -0,0 +1,34 @@
+/* ===-- powidf2.cpp - Implement __powidf2 ---------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __powidf2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: a ^ b */
+
+double
+__powidf2(double a, si_int b)
+{
+ const int recip = b < 0;
+ double r = 1;
+ while (1)
+ {
+ if (b & 1)
+ r *= a;
+ b /= 2;
+ if (b == 0)
+ break;
+ a *= a;
+ }
+ return recip ? 1/r : r;
+}
diff --git a/lib/powisf2.c b/lib/powisf2.c
new file mode 100644
index 000000000000..ace08c266752
--- /dev/null
+++ b/lib/powisf2.c
@@ -0,0 +1,34 @@
+/*===-- powisf2.cpp - Implement __powisf2 ---------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __powisf2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: a ^ b */
+
+float
+__powisf2(float a, si_int b)
+{
+ const int recip = b < 0;
+ float r = 1;
+ while (1)
+ {
+ if (b & 1)
+ r *= a;
+ b /= 2;
+ if (b == 0)
+ break;
+ a *= a;
+ }
+ return recip ? 1/r : r;
+}
diff --git a/lib/powitf2.c b/lib/powitf2.c
new file mode 100644
index 000000000000..3dacbf6bfc2a
--- /dev/null
+++ b/lib/powitf2.c
@@ -0,0 +1,38 @@
+/* ===-- powitf2.cpp - Implement __powitf2 ---------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __powitf2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if _ARCH_PPC
+
+#include "int_lib.h"
+
+/* Returns: a ^ b */
+
+long double
+__powitf2(long double a, si_int b)
+{
+ const int recip = b < 0;
+ long double r = 1;
+ while (1)
+ {
+ if (b & 1)
+ r *= a;
+ b /= 2;
+ if (b == 0)
+ break;
+ a *= a;
+ }
+ return recip ? 1/r : r;
+}
+
+#endif
diff --git a/lib/powixf2.c b/lib/powixf2.c
new file mode 100644
index 000000000000..1a816e9131cb
--- /dev/null
+++ b/lib/powixf2.c
@@ -0,0 +1,38 @@
+/* ===-- powixf2.cpp - Implement __powixf2 ---------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __powixf2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if !_ARCH_PPC
+
+#include "int_lib.h"
+
+/* Returns: a ^ b */
+
+long double
+__powixf2(long double a, si_int b)
+{
+ const int recip = b < 0;
+ long double r = 1;
+ while (1)
+ {
+ if (b & 1)
+ r *= a;
+ b /= 2;
+ if (b == 0)
+ break;
+ a *= a;
+ }
+ return recip ? 1/r : r;
+}
+
+#endif
diff --git a/lib/ppc/CMakeLists.txt b/lib/ppc/CMakeLists.txt
new file mode 100644
index 000000000000..fb0fcd5a771c
--- /dev/null
+++ b/lib/ppc/CMakeLists.txt
@@ -0,0 +1,12 @@
+SET( SRCS
+ fixtfdi.c
+ gcc_qdiv.c
+ gcc_qmul.c
+ divtc3.c
+ gcc_qsub.c
+ multc3.c
+ floatditf.c
+ gcc_qadd.c
+ fixunstfdi.c
+ floatunditf.c
+ )
diff --git a/lib/ppc/DD.h b/lib/ppc/DD.h
new file mode 100644
index 000000000000..9ecd1f50b8a9
--- /dev/null
+++ b/lib/ppc/DD.h
@@ -0,0 +1,46 @@
+#ifndef __DD_HEADER
+#define __DD_HEADER
+
+#include <stdint.h>
+
+typedef union {
+ long double ld;
+ struct {
+ double hi;
+ double lo;
+ }s;
+}DD;
+
+typedef union {
+ double d;
+ uint64_t x;
+} doublebits;
+
+#define LOWORDER(xy,xHi,xLo,yHi,yLo) \
+ (((((xHi)*(yHi) - (xy)) + (xHi)*(yLo)) + (xLo)*(yHi)) + (xLo)*(yLo))
+
+static inline double __attribute__((always_inline))
+fabs(double x)
+{
+ doublebits result = { .d = x };
+ result.x &= UINT64_C(0x7fffffffffffffff);
+ return result.d;
+}
+
+static inline double __attribute__((always_inline))
+high26bits(double x)
+{
+ doublebits result = { .d = x };
+ result.x &= UINT64_C(0xfffffffff8000000);
+ return result.d;
+}
+
+static inline int __attribute__((always_inline))
+different_sign(double x, double y)
+{
+ doublebits xsignbit = { .d = x }, ysignbit = { .d = y };
+ int result = (int)(xsignbit.x >> 63) ^ (int)(ysignbit.x >> 63);
+ return result;
+}
+
+#endif /* __DD_HEADER */
diff --git a/lib/ppc/Makefile.mk b/lib/ppc/Makefile.mk
new file mode 100644
index 000000000000..519d65467311
--- /dev/null
+++ b/lib/ppc/Makefile.mk
@@ -0,0 +1,19 @@
+#===- lib/ppc/Makefile.mk ----------------------------------*- Makefile -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+SubDirs :=
+OnlyArchs := ppc
+
+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/lib/ppc/divtc3.c b/lib/ppc/divtc3.c
new file mode 100644
index 000000000000..d41f62111b3d
--- /dev/null
+++ b/lib/ppc/divtc3.c
@@ -0,0 +1,93 @@
+/* This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ */
+
+#include "DD.h"
+#include <math.h>
+
+#if !defined(INFINITY) && defined(HUGE_VAL)
+#define INFINITY HUGE_VAL
+#endif /* INFINITY */
+
+#define makeFinite(x) { \
+ (x).s.hi = __builtin_copysign(isinf((x).s.hi) ? 1.0 : 0.0, (x).s.hi); \
+ (x).s.lo = 0.0; \
+ }
+
+long double __gcc_qadd(long double, long double);
+long double __gcc_qsub(long double, long double);
+long double __gcc_qmul(long double, long double);
+long double __gcc_qdiv(long double, long double);
+
+long double _Complex
+__divtc3(long double a, long double b, long double c, long double d)
+{
+ DD cDD = { .ld = c };
+ DD dDD = { .ld = d };
+
+ int ilogbw = 0;
+ const double logbw = logb(__builtin_fmax( __builtin_fabs(cDD.s.hi), __builtin_fabs(dDD.s.hi) ));
+
+ if (isfinite(logbw))
+ {
+ ilogbw = (int)logbw;
+
+ cDD.s.hi = scalbn(cDD.s.hi, -ilogbw);
+ cDD.s.lo = scalbn(cDD.s.lo, -ilogbw);
+ dDD.s.hi = scalbn(dDD.s.hi, -ilogbw);
+ dDD.s.lo = scalbn(dDD.s.lo, -ilogbw);
+ }
+
+ const long double denom = __gcc_qadd(__gcc_qmul(cDD.ld, cDD.ld), __gcc_qmul(dDD.ld, dDD.ld));
+ const long double realNumerator = __gcc_qadd(__gcc_qmul(a,cDD.ld), __gcc_qmul(b,dDD.ld));
+ const long double imagNumerator = __gcc_qsub(__gcc_qmul(b,cDD.ld), __gcc_qmul(a,dDD.ld));
+
+ DD real = { .ld = __gcc_qdiv(realNumerator, denom) };
+ DD imag = { .ld = __gcc_qdiv(imagNumerator, denom) };
+
+ real.s.hi = scalbn(real.s.hi, -ilogbw);
+ real.s.lo = scalbn(real.s.lo, -ilogbw);
+ imag.s.hi = scalbn(imag.s.hi, -ilogbw);
+ imag.s.lo = scalbn(imag.s.lo, -ilogbw);
+
+ if (isnan(real.s.hi) && isnan(imag.s.hi))
+ {
+ DD aDD = { .ld = a };
+ DD bDD = { .ld = b };
+ DD rDD = { .ld = denom };
+
+ if ((rDD.s.hi == 0.0) && (!isnan(aDD.s.hi) || !isnan(bDD.s.hi)))
+ {
+ real.s.hi = __builtin_copysign(INFINITY,cDD.s.hi) * aDD.s.hi;
+ real.s.lo = 0.0;
+ imag.s.hi = __builtin_copysign(INFINITY,cDD.s.hi) * bDD.s.hi;
+ imag.s.lo = 0.0;
+ }
+
+ else if ((isinf(aDD.s.hi) || isinf(bDD.s.hi)) && isfinite(cDD.s.hi) && isfinite(dDD.s.hi))
+ {
+ makeFinite(aDD);
+ makeFinite(bDD);
+ real.s.hi = INFINITY * (aDD.s.hi*cDD.s.hi + bDD.s.hi*dDD.s.hi);
+ real.s.lo = 0.0;
+ imag.s.hi = INFINITY * (bDD.s.hi*cDD.s.hi - aDD.s.hi*dDD.s.hi);
+ imag.s.lo = 0.0;
+ }
+
+ else if ((isinf(cDD.s.hi) || isinf(dDD.s.hi)) && isfinite(aDD.s.hi) && isfinite(bDD.s.hi))
+ {
+ makeFinite(cDD);
+ makeFinite(dDD);
+ real.s.hi = __builtin_copysign(0.0,(aDD.s.hi*cDD.s.hi + bDD.s.hi*dDD.s.hi));
+ real.s.lo = 0.0;
+ imag.s.hi = __builtin_copysign(0.0,(bDD.s.hi*cDD.s.hi - aDD.s.hi*dDD.s.hi));
+ imag.s.lo = 0.0;
+ }
+ }
+
+ long double _Complex z;
+ __real__ z = real.ld;
+ __imag__ z = imag.ld;
+
+ return z;
+}
diff --git a/lib/ppc/fixtfdi.c b/lib/ppc/fixtfdi.c
new file mode 100644
index 000000000000..fa113a037e93
--- /dev/null
+++ b/lib/ppc/fixtfdi.c
@@ -0,0 +1,104 @@
+/* This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ */
+
+/* int64_t __fixunstfdi(long double x);
+ * This file implements the PowerPC 128-bit double-double -> int64_t conversion
+ */
+
+#include "DD.h"
+#include <stdint.h>
+
+uint64_t __fixtfdi(long double input)
+{
+ const DD x = { .ld = input };
+ const doublebits hibits = { .d = x.s.hi };
+
+ const uint32_t absHighWord = (uint32_t)(hibits.x >> 32) & UINT32_C(0x7fffffff);
+ const uint32_t absHighWordMinusOne = absHighWord - UINT32_C(0x3ff00000);
+
+ /* If (1.0 - tiny) <= input < 0x1.0p63: */
+ if (UINT32_C(0x03f00000) > absHighWordMinusOne)
+ {
+ /* Do an unsigned conversion of the absolute value, then restore the sign. */
+ const int unbiasedHeadExponent = absHighWordMinusOne >> 20;
+
+ int64_t result = hibits.x & INT64_C(0x000fffffffffffff); /* mantissa(hi) */
+ result |= INT64_C(0x0010000000000000); /* matissa(hi) with implicit bit */
+ result <<= 10; /* mantissa(hi) with one zero preceeding bit. */
+
+ const int64_t hiNegationMask = ((int64_t)(hibits.x)) >> 63;
+
+ /* If the tail is non-zero, we need to patch in the tail bits. */
+ if (0.0 != x.s.lo)
+ {
+ const doublebits lobits = { .d = x.s.lo };
+ int64_t tailMantissa = lobits.x & INT64_C(0x000fffffffffffff);
+ tailMantissa |= INT64_C(0x0010000000000000);
+
+ /* At this point we have the mantissa of |tail| */
+ /* We need to negate it if head and tail have different signs. */
+ const int64_t loNegationMask = ((int64_t)(lobits.x)) >> 63;
+ const int64_t negationMask = loNegationMask ^ hiNegationMask;
+ tailMantissa = (tailMantissa ^ negationMask) - negationMask;
+
+ /* Now we have the mantissa of tail as a signed 2s-complement integer */
+
+ const int biasedTailExponent = (int)(lobits.x >> 52) & 0x7ff;
+
+ /* Shift the tail mantissa into the right position, accounting for the
+ * bias of 10 that we shifted the head mantissa by.
+ */
+ tailMantissa >>= (unbiasedHeadExponent - (biasedTailExponent - (1023 - 10)));
+
+ result += tailMantissa;
+ }
+
+ result >>= (62 - unbiasedHeadExponent);
+
+ /* Restore the sign of the result and return */
+ result = (result ^ hiNegationMask) - hiNegationMask;
+ return result;
+
+ }
+
+ /* Edge cases handled here: */
+
+ /* |x| < 1, result is zero. */
+ if (1.0 > __builtin_fabs(x.s.hi))
+ return INT64_C(0);
+
+ /* x very close to INT64_MIN, care must be taken to see which side we are on. */
+ if (x.s.hi == -0x1.0p63) {
+
+ int64_t result = INT64_MIN;
+
+ if (0.0 < x.s.lo)
+ {
+ /* If the tail is positive, the correct result is something other than INT64_MIN.
+ * we'll need to figure out what it is.
+ */
+
+ const doublebits lobits = { .d = x.s.lo };
+ int64_t tailMantissa = lobits.x & INT64_C(0x000fffffffffffff);
+ tailMantissa |= INT64_C(0x0010000000000000);
+
+ /* Now we negate the tailMantissa */
+ tailMantissa = (tailMantissa ^ INT64_C(-1)) + INT64_C(1);
+
+ /* And shift it by the appropriate amount */
+ const int biasedTailExponent = (int)(lobits.x >> 52) & 0x7ff;
+ tailMantissa >>= 1075 - biasedTailExponent;
+
+ result -= tailMantissa;
+ }
+
+ return result;
+ }
+
+ /* Signed overflows, infinities, and NaNs */
+ if (x.s.hi > 0.0)
+ return INT64_MAX;
+ else
+ return INT64_MIN;
+}
diff --git a/lib/ppc/fixunstfdi.c b/lib/ppc/fixunstfdi.c
new file mode 100644
index 000000000000..1fb52488172c
--- /dev/null
+++ b/lib/ppc/fixunstfdi.c
@@ -0,0 +1,60 @@
+/* This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ */
+
+/* uint64_t __fixunstfdi(long double x); */
+/* This file implements the PowerPC 128-bit double-double -> uint64_t conversion */
+
+#include "DD.h"
+#include <stdint.h>
+
+uint64_t __fixunstfdi(long double input)
+{
+ const DD x = { .ld = input };
+ const doublebits hibits = { .d = x.s.hi };
+
+ const uint32_t highWordMinusOne = (uint32_t)(hibits.x >> 32) - UINT32_C(0x3ff00000);
+
+ /* If (1.0 - tiny) <= input < 0x1.0p64: */
+ if (UINT32_C(0x04000000) > highWordMinusOne)
+ {
+ const int unbiasedHeadExponent = highWordMinusOne >> 20;
+
+ uint64_t result = hibits.x & UINT64_C(0x000fffffffffffff); /* mantissa(hi) */
+ result |= UINT64_C(0x0010000000000000); /* matissa(hi) with implicit bit */
+ result <<= 11; /* mantissa(hi) left aligned in the int64 field. */
+
+ /* If the tail is non-zero, we need to patch in the tail bits. */
+ if (0.0 != x.s.lo)
+ {
+ const doublebits lobits = { .d = x.s.lo };
+ int64_t tailMantissa = lobits.x & INT64_C(0x000fffffffffffff);
+ tailMantissa |= INT64_C(0x0010000000000000);
+
+ /* At this point we have the mantissa of |tail| */
+
+ const int64_t negationMask = ((int64_t)(lobits.x)) >> 63;
+ tailMantissa = (tailMantissa ^ negationMask) - negationMask;
+
+ /* Now we have the mantissa of tail as a signed 2s-complement integer */
+
+ const int biasedTailExponent = (int)(lobits.x >> 52) & 0x7ff;
+
+ /* Shift the tail mantissa into the right position, accounting for the
+ * bias of 11 that we shifted the head mantissa by.
+ */
+ tailMantissa >>= (unbiasedHeadExponent - (biasedTailExponent - (1023 - 11)));
+
+ result += tailMantissa;
+ }
+
+ result >>= (63 - unbiasedHeadExponent);
+ return result;
+ }
+
+ /* Edge cases are handled here, with saturation. */
+ if (1.0 > x.s.hi)
+ return UINT64_C(0);
+ else
+ return UINT64_MAX;
+}
diff --git a/lib/ppc/floatditf.c b/lib/ppc/floatditf.c
new file mode 100644
index 000000000000..ed23dc84d73c
--- /dev/null
+++ b/lib/ppc/floatditf.c
@@ -0,0 +1,37 @@
+/* This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ */
+
+/* long double __floatditf(long long x); */
+/* This file implements the PowerPC long long -> long double conversion */
+
+#include "DD.h"
+#include <stdint.h>
+
+long double __floatditf(int64_t a) {
+
+ static const double twop32 = 0x1.0p32;
+ static const double twop52 = 0x1.0p52;
+
+ doublebits low = { .d = twop52 };
+ low.x |= a & UINT64_C(0x00000000ffffffff); /* 0x1.0p52 + low 32 bits of a. */
+
+ const double high_addend = (double)((int32_t)(a >> 32))*twop32 - twop52;
+
+ /* At this point, we have two double precision numbers
+ * high_addend and low.d, and we wish to return their sum
+ * as a canonicalized long double:
+ */
+
+ /* This implementation sets the inexact flag spuriously.
+ * This could be avoided, but at some substantial cost.
+ */
+
+ DD result;
+
+ result.s.hi = high_addend + low.d;
+ result.s.lo = (high_addend - result.s.hi) + low.d;
+
+ return result.ld;
+
+}
diff --git a/lib/ppc/floatunditf.c b/lib/ppc/floatunditf.c
new file mode 100644
index 000000000000..20a3b71b317c
--- /dev/null
+++ b/lib/ppc/floatunditf.c
@@ -0,0 +1,42 @@
+/* This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ */
+
+/* long double __floatunditf(unsigned long long x); */
+/* This file implements the PowerPC unsigned long long -> long double conversion */
+
+#include "DD.h"
+#include <stdint.h>
+
+long double __floatunditf(uint64_t a) {
+
+ /* Begins with an exact copy of the code from __floatundidf */
+
+ static const double twop52 = 0x1.0p52;
+ static const double twop84 = 0x1.0p84;
+ static const double twop84_plus_twop52 = 0x1.00000001p84;
+
+ doublebits high = { .d = twop84 };
+ doublebits low = { .d = twop52 };
+
+ high.x |= a >> 32; /* 0x1.0p84 + high 32 bits of a */
+ low.x |= a & UINT64_C(0x00000000ffffffff); /* 0x1.0p52 + low 32 bits of a */
+
+ const double high_addend = high.d - twop84_plus_twop52;
+
+ /* At this point, we have two double precision numbers
+ * high_addend and low.d, and we wish to return their sum
+ * as a canonicalized long double:
+ */
+
+ /* This implementation sets the inexact flag spuriously. */
+ /* This could be avoided, but at some substantial cost. */
+
+ DD result;
+
+ result.s.hi = high_addend + low.d;
+ result.s.lo = (high_addend - result.s.hi) + low.d;
+
+ return result.ld;
+
+}
diff --git a/lib/ppc/gcc_qadd.c b/lib/ppc/gcc_qadd.c
new file mode 100644
index 000000000000..c388c7e99c6e
--- /dev/null
+++ b/lib/ppc/gcc_qadd.c
@@ -0,0 +1,76 @@
+/* This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ */
+
+/* long double __gcc_qadd(long double x, long double y);
+ * This file implements the PowerPC 128-bit double-double add operation.
+ * This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!)
+ */
+
+#include "DD.h"
+
+long double __gcc_qadd(long double x, long double y)
+{
+ static const uint32_t infinityHi = UINT32_C(0x7ff00000);
+
+ DD dst = { .ld = x }, src = { .ld = y };
+
+ register double A = dst.s.hi, a = dst.s.lo,
+ B = src.s.hi, b = src.s.lo;
+
+ /* If both operands are zero: */
+ if ((A == 0.0) && (B == 0.0)) {
+ dst.s.hi = A + B;
+ dst.s.lo = 0.0;
+ return dst.ld;
+ }
+
+ /* If either operand is NaN or infinity: */
+ const doublebits abits = { .d = A };
+ const doublebits bbits = { .d = B };
+ if ((((uint32_t)(abits.x >> 32) & infinityHi) == infinityHi) ||
+ (((uint32_t)(bbits.x >> 32) & infinityHi) == infinityHi)) {
+ dst.s.hi = A + B;
+ dst.s.lo = 0.0;
+ return dst.ld;
+ }
+
+ /* If the computation overflows: */
+ /* This may be playing things a little bit fast and loose, but it will do for a start. */
+ const double testForOverflow = A + (B + (a + b));
+ const doublebits testbits = { .d = testForOverflow };
+ if (((uint32_t)(testbits.x >> 32) & infinityHi) == infinityHi) {
+ dst.s.hi = testForOverflow;
+ dst.s.lo = 0.0;
+ return dst.ld;
+ }
+
+ double H, h;
+ double T, t;
+ double W, w;
+ double Y;
+
+ H = B + (A - (A + B));
+ T = b + (a - (a + b));
+ h = A + (B - (A + B));
+ t = a + (b - (a + b));
+
+ if (fabs(A) <= fabs(B))
+ w = (a + b) + h;
+ else
+ w = (a + b) + H;
+
+ W = (A + B) + w;
+ Y = (A + B) - W;
+ Y += w;
+
+ if (fabs(a) <= fabs(b))
+ w = t + Y;
+ else
+ w = T + Y;
+
+ dst.s.hi = Y = W + w;
+ dst.s.lo = (W - Y) + w;
+
+ return dst.ld;
+}
diff --git a/lib/ppc/gcc_qdiv.c b/lib/ppc/gcc_qdiv.c
new file mode 100644
index 000000000000..70aa00b64400
--- /dev/null
+++ b/lib/ppc/gcc_qdiv.c
@@ -0,0 +1,55 @@
+/* This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ */
+
+/* long double __gcc_qdiv(long double x, long double y);
+ * This file implements the PowerPC 128-bit double-double division operation.
+ * This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!)
+ */
+
+#include "DD.h"
+
+long double __gcc_qdiv(long double a, long double b)
+{
+ static const uint32_t infinityHi = UINT32_C(0x7ff00000);
+ DD dst = { .ld = a }, src = { .ld = b };
+
+ register double x = dst.s.hi, x1 = dst.s.lo,
+ y = src.s.hi, y1 = src.s.lo;
+
+ double yHi, yLo, qHi, qLo;
+ double yq, tmp, q;
+
+ q = x / y;
+
+ /* Detect special cases */
+ if (q == 0.0) {
+ dst.s.hi = q;
+ dst.s.lo = 0.0;
+ return dst.ld;
+ }
+
+ const doublebits qBits = { .d = q };
+ if (((uint32_t)(qBits.x >> 32) & infinityHi) == infinityHi) {
+ dst.s.hi = q;
+ dst.s.lo = 0.0;
+ return dst.ld;
+ }
+
+ yHi = high26bits(y);
+ qHi = high26bits(q);
+
+ yq = y * q;
+ yLo = y - yHi;
+ qLo = q - qHi;
+
+ tmp = LOWORDER(yq, yHi, yLo, qHi, qLo);
+ tmp = (x - yq) - tmp;
+ tmp = ((tmp + x1) - y1 * q) / y;
+ x = q + tmp;
+
+ dst.s.lo = (q - x) + tmp;
+ dst.s.hi = x;
+
+ return dst.ld;
+}
diff --git a/lib/ppc/gcc_qmul.c b/lib/ppc/gcc_qmul.c
new file mode 100644
index 000000000000..fb4c5164ccb5
--- /dev/null
+++ b/lib/ppc/gcc_qmul.c
@@ -0,0 +1,53 @@
+/* This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ */
+
+/* long double __gcc_qmul(long double x, long double y);
+ * This file implements the PowerPC 128-bit double-double multiply operation.
+ * This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!)
+ */
+
+#include "DD.h"
+
+long double __gcc_qmul(long double x, long double y)
+{
+ static const uint32_t infinityHi = UINT32_C(0x7ff00000);
+ DD dst = { .ld = x }, src = { .ld = y };
+
+ register double A = dst.s.hi, a = dst.s.lo,
+ B = src.s.hi, b = src.s.lo;
+
+ double aHi, aLo, bHi, bLo;
+ double ab, tmp, tau;
+
+ ab = A * B;
+
+ /* Detect special cases */
+ if (ab == 0.0) {
+ dst.s.hi = ab;
+ dst.s.lo = 0.0;
+ return dst.ld;
+ }
+
+ const doublebits abBits = { .d = ab };
+ if (((uint32_t)(abBits.x >> 32) & infinityHi) == infinityHi) {
+ dst.s.hi = ab;
+ dst.s.lo = 0.0;
+ return dst.ld;
+ }
+
+ /* Generic cases handled here. */
+ aHi = high26bits(A);
+ bHi = high26bits(B);
+ aLo = A - aHi;
+ bLo = B - bHi;
+
+ tmp = LOWORDER(ab, aHi, aLo, bHi, bLo);
+ tmp += (A * b + a * B);
+ tau = ab + tmp;
+
+ dst.s.lo = (ab - tau) + tmp;
+ dst.s.hi = tau;
+
+ return dst.ld;
+}
diff --git a/lib/ppc/gcc_qsub.c b/lib/ppc/gcc_qsub.c
new file mode 100644
index 000000000000..4f1f7ac70f3c
--- /dev/null
+++ b/lib/ppc/gcc_qsub.c
@@ -0,0 +1,76 @@
+/* This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ */
+
+/* long double __gcc_qsub(long double x, long double y);
+ * This file implements the PowerPC 128-bit double-double add operation.
+ * This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!)
+ */
+
+#include "DD.h"
+
+long double __gcc_qsub(long double x, long double y)
+{
+ static const uint32_t infinityHi = UINT32_C(0x7ff00000);
+
+ DD dst = { .ld = x }, src = { .ld = y };
+
+ register double A = dst.s.hi, a = dst.s.lo,
+ B = -src.s.hi, b = -src.s.lo;
+
+ /* If both operands are zero: */
+ if ((A == 0.0) && (B == 0.0)) {
+ dst.s.hi = A + B;
+ dst.s.lo = 0.0;
+ return dst.ld;
+ }
+
+ /* If either operand is NaN or infinity: */
+ const doublebits abits = { .d = A };
+ const doublebits bbits = { .d = B };
+ if ((((uint32_t)(abits.x >> 32) & infinityHi) == infinityHi) ||
+ (((uint32_t)(bbits.x >> 32) & infinityHi) == infinityHi)) {
+ dst.s.hi = A + B;
+ dst.s.lo = 0.0;
+ return dst.ld;
+ }
+
+ /* If the computation overflows: */
+ /* This may be playing things a little bit fast and loose, but it will do for a start. */
+ const double testForOverflow = A + (B + (a + b));
+ const doublebits testbits = { .d = testForOverflow };
+ if (((uint32_t)(testbits.x >> 32) & infinityHi) == infinityHi) {
+ dst.s.hi = testForOverflow;
+ dst.s.lo = 0.0;
+ return dst.ld;
+ }
+
+ double H, h;
+ double T, t;
+ double W, w;
+ double Y;
+
+ H = B + (A - (A + B));
+ T = b + (a - (a + b));
+ h = A + (B - (A + B));
+ t = a + (b - (a + b));
+
+ if (fabs(A) <= fabs(B))
+ w = (a + b) + h;
+ else
+ w = (a + b) + H;
+
+ W = (A + B) + w;
+ Y = (A + B) - W;
+ Y += w;
+
+ if (fabs(a) <= fabs(b))
+ w = t + Y;
+ else
+ w = T + Y;
+
+ dst.s.hi = Y = W + w;
+ dst.s.lo = (W - Y) + w;
+
+ return dst.ld;
+}
diff --git a/lib/ppc/multc3.c b/lib/ppc/multc3.c
new file mode 100644
index 000000000000..9d17a2c6bc6a
--- /dev/null
+++ b/lib/ppc/multc3.c
@@ -0,0 +1,97 @@
+/* This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ */
+
+#include "DD.h"
+#include <math.h>
+
+#if !defined(INFINITY) && defined(HUGE_VAL)
+#define INFINITY HUGE_VAL
+#endif /* INFINITY */
+
+#define makeFinite(x) { \
+ (x).s.hi = __builtin_copysign(isinf((x).s.hi) ? 1.0 : 0.0, (x).s.hi); \
+ (x).s.lo = 0.0; \
+ }
+
+#define zeroNaN(x) { \
+ if (isnan((x).s.hi)) { \
+ (x).s.hi = __builtin_copysign(0.0, (x).s.hi); \
+ (x).s.lo = 0.0; \
+ } \
+ }
+
+long double __gcc_qadd(long double, long double);
+long double __gcc_qsub(long double, long double);
+long double __gcc_qmul(long double, long double);
+
+long double _Complex
+__multc3(long double a, long double b, long double c, long double d)
+{
+ long double ac = __gcc_qmul(a,c);
+ long double bd = __gcc_qmul(b,d);
+ long double ad = __gcc_qmul(a,d);
+ long double bc = __gcc_qmul(b,c);
+
+ DD real = { .ld = __gcc_qsub(ac,bd) };
+ DD imag = { .ld = __gcc_qadd(ad,bc) };
+
+ if (isnan(real.s.hi) && isnan(imag.s.hi))
+ {
+ int recalc = 0;
+
+ DD aDD = { .ld = a };
+ DD bDD = { .ld = b };
+ DD cDD = { .ld = c };
+ DD dDD = { .ld = d };
+
+ if (isinf(aDD.s.hi) || isinf(bDD.s.hi))
+ {
+ makeFinite(aDD);
+ makeFinite(bDD);
+ zeroNaN(cDD);
+ zeroNaN(dDD);
+ recalc = 1;
+ }
+
+ if (isinf(cDD.s.hi) || isinf(dDD.s.hi))
+ {
+ makeFinite(cDD);
+ makeFinite(dDD);
+ zeroNaN(aDD);
+ zeroNaN(bDD);
+ recalc = 1;
+ }
+
+ if (!recalc)
+ {
+ DD acDD = { .ld = ac };
+ DD bdDD = { .ld = bd };
+ DD adDD = { .ld = ad };
+ DD bcDD = { .ld = bc };
+
+ if (isinf(acDD.s.hi) || isinf(bdDD.s.hi) || isinf(adDD.s.hi) || isinf(bcDD.s.hi))
+ {
+ zeroNaN(aDD);
+ zeroNaN(bDD);
+ zeroNaN(cDD);
+ zeroNaN(dDD);
+ recalc = 1;
+ }
+ }
+
+ if (recalc)
+ {
+ real.s.hi = INFINITY * (aDD.s.hi*cDD.s.hi - bDD.s.hi*dDD.s.hi);
+ real.s.lo = 0.0;
+ imag.s.hi = INFINITY * (aDD.s.hi*dDD.s.hi + bDD.s.hi*cDD.s.hi);
+ imag.s.lo = 0.0;
+ }
+ }
+
+ long double _Complex z;
+ __real__ z = real.ld;
+ __imag__ z = imag.ld;
+
+ return z;
+}
diff --git a/lib/ppc/restFP.S b/lib/ppc/restFP.S
new file mode 100644
index 000000000000..00919c8cdce4
--- /dev/null
+++ b/lib/ppc/restFP.S
@@ -0,0 +1,43 @@
+//===-- restFP.S - Implement restFP ---------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// Helper function used by compiler to restore ppc floating point registers at
+// the end of the function epilog. This function returns to the address
+// in the LR slot. So a function epilog must branch (b) not branch and link
+// (bl) to this function.
+// If the compiler wants to restore f27..f31, it does a "b restFP+52"
+//
+// This function should never be exported by a shared library. Each linkage
+// unit carries its own copy of this function.
+//
+DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(restFP)
+ lfd f14,-144(r1)
+ lfd f15,-136(r1)
+ lfd f16,-128(r1)
+ lfd f17,-120(r1)
+ lfd f18,-112(r1)
+ lfd f19,-104(r1)
+ lfd f20,-96(r1)
+ lfd f21,-88(r1)
+ lfd f22,-80(r1)
+ lfd f23,-72(r1)
+ lfd f24,-64(r1)
+ lfd f25,-56(r1)
+ lfd f26,-48(r1)
+ lfd f27,-40(r1)
+ lfd f28,-32(r1)
+ lfd f29,-24(r1)
+ lfd f30,-16(r1)
+ lfd f31,-8(r1)
+ lwz r0,8(r1)
+ mtlr r0
+ blr
diff --git a/lib/ppc/saveFP.S b/lib/ppc/saveFP.S
new file mode 100644
index 000000000000..302da6e9c595
--- /dev/null
+++ b/lib/ppc/saveFP.S
@@ -0,0 +1,40 @@
+//===-- saveFP.S - Implement saveFP ---------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//
+// Helper function used by compiler to save ppc floating point registers in
+// function prologs. This routines also saves r0 in the LR slot.
+// If the compiler wants to save f27..f31, it does a "bl saveFP+52"
+//
+// This function should never be exported by a shared library. Each linkage
+// unit carries its own copy of this function.
+//
+DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(saveFP)
+ stfd f14,-144(r1)
+ stfd f15,-136(r1)
+ stfd f16,-128(r1)
+ stfd f17,-120(r1)
+ stfd f18,-112(r1)
+ stfd f19,-104(r1)
+ stfd f20,-96(r1)
+ stfd f21,-88(r1)
+ stfd f22,-80(r1)
+ stfd f23,-72(r1)
+ stfd f24,-64(r1)
+ stfd f25,-56(r1)
+ stfd f26,-48(r1)
+ stfd f27,-40(r1)
+ stfd f28,-32(r1)
+ stfd f29,-24(r1)
+ stfd f30,-16(r1)
+ stfd f31,-8(r1)
+ stw r0,8(r1)
+ blr
diff --git a/lib/subvdi3.c b/lib/subvdi3.c
new file mode 100644
index 000000000000..e4926b816460
--- /dev/null
+++ b/lib/subvdi3.c
@@ -0,0 +1,37 @@
+/* ===-- subvdi3.c - Implement __subvdi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __subvdi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: a - b */
+
+/* Effects: aborts if a - b overflows */
+
+di_int
+__subvdi3(di_int a, di_int b)
+{
+ di_int s = a - b;
+ if (b >= 0)
+ {
+ if (s > a)
+ compilerrt_abort();
+ }
+ else
+ {
+ if (s <= a)
+ compilerrt_abort();
+ }
+ return s;
+}
diff --git a/lib/subvsi3.c b/lib/subvsi3.c
new file mode 100644
index 000000000000..ce39c815b86e
--- /dev/null
+++ b/lib/subvsi3.c
@@ -0,0 +1,37 @@
+/* ===-- subvsi3.c - Implement __subvsi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __subvsi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: a - b */
+
+/* Effects: aborts if a - b overflows */
+
+si_int
+__subvsi3(si_int a, si_int b)
+{
+ si_int s = a - b;
+ if (b >= 0)
+ {
+ if (s > a)
+ compilerrt_abort();
+ }
+ else
+ {
+ if (s <= a)
+ compilerrt_abort();
+ }
+ return s;
+}
diff --git a/lib/subvti3.c b/lib/subvti3.c
new file mode 100644
index 000000000000..55b7925a14b3
--- /dev/null
+++ b/lib/subvti3.c
@@ -0,0 +1,41 @@
+/* ===-- subvti3.c - Implement __subvti3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __subvti3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+#include <stdlib.h>
+
+/* Returns: a - b */
+
+/* Effects: aborts if a - b overflows */
+
+ti_int
+__subvti3(ti_int a, ti_int b)
+{
+ ti_int s = a - b;
+ if (b >= 0)
+ {
+ if (s > a)
+ compilerrt_abort();
+ }
+ else
+ {
+ if (s <= a)
+ compilerrt_abort();
+ }
+ return s;
+}
+
+#endif /* __x86_64 */
diff --git a/lib/trampoline_setup.c b/lib/trampoline_setup.c
new file mode 100644
index 000000000000..8254e362a7d7
--- /dev/null
+++ b/lib/trampoline_setup.c
@@ -0,0 +1,50 @@
+/* ===----- trampoline_setup.c - Implement __trampoline_setup -------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "int_lib.h"
+
+extern void __clear_cache(void* start, void* end);
+
+/*
+ * The ppc compiler generates calls to __trampoline_setup() when creating
+ * trampoline functions on the stack for use with nested functions.
+ * This function creates a custom 40-byte trampoline function on the stack
+ * which loads r11 with a pointer to the outer function's locals
+ * and then jumps to the target nested function.
+ */
+
+#if __ppc__
+void __trampoline_setup(uint32_t* trampOnStack, int trampSizeAllocated,
+ const void* realFunc, void* localsPtr)
+{
+ /* should never happen, but if compiler did not allocate */
+ /* enough space on stack for the trampoline, abort */
+ if ( trampSizeAllocated < 40 )
+ compilerrt_abort();
+
+ /* create trampoline */
+ trampOnStack[0] = 0x7c0802a6; /* mflr r0 */
+ trampOnStack[1] = 0x4800000d; /* bl Lbase */
+ trampOnStack[2] = (uint32_t)realFunc;
+ trampOnStack[3] = (uint32_t)localsPtr;
+ trampOnStack[4] = 0x7d6802a6; /* Lbase: mflr r11 */
+ trampOnStack[5] = 0x818b0000; /* lwz r12,0(r11) */
+ trampOnStack[6] = 0x7c0803a6; /* mtlr r0 */
+ trampOnStack[7] = 0x7d8903a6; /* mtctr r12 */
+ trampOnStack[8] = 0x816b0004; /* lwz r11,4(r11) */
+ trampOnStack[9] = 0x4e800420; /* bctr */
+
+ /* clear instruction cache */
+ __clear_cache(trampOnStack, &trampOnStack[10]);
+}
+#endif /* __ppc__ */
diff --git a/lib/truncdfsf2.c b/lib/truncdfsf2.c
new file mode 100644
index 000000000000..d289cb989186
--- /dev/null
+++ b/lib/truncdfsf2.c
@@ -0,0 +1,167 @@
+//===-- lib/truncdfsf2.c - double -> single conversion ------------*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a fairly generic conversion from a wider to a narrower
+// IEEE-754 floating-point type in the default (round to nearest, ties to even)
+// rounding mode. The constants and types defined following the includes below
+// parameterize the conversion.
+//
+// This routine can be trivially adapted to support conversions to
+// half-precision or from quad-precision. It does not support types that don't
+// use the usual IEEE-754 interchange formats; specifically, some work would be
+// needed to adapt it to (for example) the Intel 80-bit format or PowerPC
+// double-double format.
+//
+// Note please, however, that this implementation is only intended to support
+// *narrowing* operations; if you need to convert to a *wider* floating-point
+// type (e.g. float -> double), then this routine will not do what you want it
+// to.
+//
+// It also requires that integer types at least as large as both formats
+// are available on the target platform; this may pose a problem when trying
+// to add support for quad on some 32-bit systems, for example.
+//
+// Finally, the following assumptions are made:
+//
+// 1. floating-point types and integer types have the same endianness on the
+// target platform
+//
+// 2. quiet NaNs, if supported, are indicated by the leading bit of the
+// significand field being set
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdint.h>
+#include <limits.h>
+#include <stdbool.h>
+
+typedef double src_t;
+typedef uint64_t src_rep_t;
+#define SRC_REP_C UINT64_C
+static const int srcSigBits = 52;
+
+typedef float dst_t;
+typedef uint32_t dst_rep_t;
+#define DST_REP_C UINT32_C
+static const int dstSigBits = 23;
+
+// End of specialization parameters. Two helper routines for conversion to and
+// from the representation of floating-point data as integer values follow.
+
+static inline src_rep_t srcToRep(src_t x) {
+ const union { src_t f; src_rep_t i; } rep = {.f = x};
+ return rep.i;
+}
+
+static inline dst_t dstFromRep(dst_rep_t x) {
+ const union { dst_t f; dst_rep_t i; } rep = {.i = x};
+ return rep.f;
+}
+
+// End helper routines. Conversion implementation follows.
+
+dst_t __truncdfsf2(src_t a) {
+
+ // Various constants whose values follow from the type parameters.
+ // Any reasonable optimizer will fold and propagate all of these.
+ const int srcBits = sizeof(src_t)*CHAR_BIT;
+ const int srcExpBits = srcBits - srcSigBits - 1;
+ const int srcInfExp = (1 << srcExpBits) - 1;
+ const int srcExpBias = srcInfExp >> 1;
+
+ const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits;
+ const src_rep_t significandMask = srcMinNormal - 1;
+ const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits;
+ const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits);
+ const src_rep_t srcAbsMask = srcSignMask - 1;
+ const src_rep_t roundMask = (SRC_REP_C(1) << (srcSigBits - dstSigBits)) - 1;
+ const src_rep_t halfway = SRC_REP_C(1) << (srcSigBits - dstSigBits - 1);
+
+ const int dstBits = sizeof(dst_t)*CHAR_BIT;
+ const int dstExpBits = dstBits - dstSigBits - 1;
+ const int dstInfExp = (1 << dstExpBits) - 1;
+ const int dstExpBias = dstInfExp >> 1;
+
+ const int underflowExponent = srcExpBias + 1 - dstExpBias;
+ const int overflowExponent = srcExpBias + dstInfExp - dstExpBias;
+ const src_rep_t underflow = (src_rep_t)underflowExponent << srcSigBits;
+ const src_rep_t overflow = (src_rep_t)overflowExponent << srcSigBits;
+
+ const dst_rep_t dstQNaN = DST_REP_C(1) << (dstSigBits - 1);
+ const dst_rep_t dstNaNCode = dstQNaN - 1;
+
+ // Break a into a sign and representation of the absolute value
+ const src_rep_t aRep = srcToRep(a);
+ const src_rep_t aAbs = aRep & srcAbsMask;
+ const src_rep_t sign = aRep & srcSignMask;
+ dst_rep_t absResult;
+
+ if (aAbs - underflow < aAbs - overflow) {
+ // The exponent of a is within the range of normal numbers in the
+ // destination format. We can convert by simply right-shifting with
+ // rounding and adjusting the exponent.
+ absResult = aAbs >> (srcSigBits - dstSigBits);
+ absResult -= (dst_rep_t)(srcExpBias - dstExpBias) << dstSigBits;
+
+ const src_rep_t roundBits = aAbs & roundMask;
+
+ // Round to nearest
+ if (roundBits > halfway)
+ absResult++;
+
+ // Ties to even
+ else if (roundBits == halfway)
+ absResult += absResult & 1;
+ }
+
+ else if (aAbs > srcInfinity) {
+ // a is NaN.
+ // Conjure the result by beginning with infinity, setting the qNaN
+ // bit and inserting the (truncated) trailing NaN field.
+ absResult = (dst_rep_t)dstInfExp << dstSigBits;
+ absResult |= dstQNaN;
+ absResult |= aAbs & dstNaNCode;
+ }
+
+ else if (aAbs > overflow) {
+ // a overflows to infinity.
+ absResult = (dst_rep_t)dstInfExp << dstSigBits;
+ }
+
+ else {
+ // a underflows on conversion to the destination type or is an exact
+ // zero. The result may be a denormal or zero. Extract the exponent
+ // to get the shift amount for the denormalization.
+ const int aExp = aAbs >> srcSigBits;
+ const int shift = srcExpBias - dstExpBias - aExp + 1;
+
+ const src_rep_t significand = (aRep & significandMask) | srcMinNormal;
+
+ // Right shift by the denormalization amount with sticky.
+ if (shift > srcSigBits) {
+ absResult = 0;
+ } else {
+ const bool sticky = significand << (srcBits - shift);
+ src_rep_t denormalizedSignificand = significand >> shift | sticky;
+ absResult = denormalizedSignificand >> (srcSigBits - dstSigBits);
+ const src_rep_t roundBits = denormalizedSignificand & roundMask;
+ // Round to nearest
+ if (roundBits > halfway)
+ absResult++;
+ // Ties to even
+ else if (roundBits == halfway)
+ absResult += absResult & 1;
+ }
+ }
+
+ // Apply the signbit to (dst_t)abs(a).
+ const dst_rep_t result = absResult | sign >> (srcBits - dstBits);
+ return dstFromRep(result);
+
+}
diff --git a/lib/ucmpdi2.c b/lib/ucmpdi2.c
new file mode 100644
index 000000000000..d2900cae4368
--- /dev/null
+++ b/lib/ucmpdi2.c
@@ -0,0 +1,38 @@
+/* ===-- ucmpdi2.c - Implement __ucmpdi2 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __ucmpdi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: if (a < b) returns 0
+ * if (a == b) returns 1
+ * if (a > b) returns 2
+ */
+
+si_int
+__ucmpdi2(du_int a, du_int b)
+{
+ udwords x;
+ x.all = a;
+ udwords y;
+ y.all = b;
+ if (x.s.high < y.s.high)
+ return 0;
+ if (x.s.high > y.s.high)
+ return 2;
+ if (x.s.low < y.s.low)
+ return 0;
+ if (x.s.low > y.s.low)
+ return 2;
+ return 1;
+}
diff --git a/lib/ucmpti2.c b/lib/ucmpti2.c
new file mode 100644
index 000000000000..0e7eea3e3d1c
--- /dev/null
+++ b/lib/ucmpti2.c
@@ -0,0 +1,42 @@
+/* ===-- ucmpti2.c - Implement __ucmpti2 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __ucmpti2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Returns: if (a < b) returns 0
+ * if (a == b) returns 1
+ * if (a > b) returns 2
+ */
+
+si_int
+__ucmpti2(tu_int a, tu_int b)
+{
+ utwords x;
+ x.all = a;
+ utwords y;
+ y.all = b;
+ if (x.s.high < y.s.high)
+ return 0;
+ if (x.s.high > y.s.high)
+ return 2;
+ if (x.s.low < y.s.low)
+ return 0;
+ if (x.s.low > y.s.low)
+ return 2;
+ return 1;
+}
+
+#endif
diff --git a/lib/udivdi3.c b/lib/udivdi3.c
new file mode 100644
index 000000000000..25d1df643c91
--- /dev/null
+++ b/lib/udivdi3.c
@@ -0,0 +1,25 @@
+/* ===-- udivdi3.c - Implement __udivdi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __udivdi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+du_int __udivmoddi4(du_int a, du_int b, du_int* rem);
+
+/* Returns: a / b */
+
+du_int
+__udivdi3(du_int a, du_int b)
+{
+ return __udivmoddi4(a, b, 0);
+}
diff --git a/lib/udivmoddi4.c b/lib/udivmoddi4.c
new file mode 100644
index 000000000000..92742302cf68
--- /dev/null
+++ b/lib/udivmoddi4.c
@@ -0,0 +1,251 @@
+/* ===-- udivmoddi4.c - Implement __udivmoddi4 -----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __udivmoddi4 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Effects: if rem != 0, *rem = a % b
+ * Returns: a / b
+ */
+
+/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */
+
+du_int
+__udivmoddi4(du_int a, du_int b, du_int* rem)
+{
+ const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT;
+ const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;
+ udwords n;
+ n.all = a;
+ udwords d;
+ d.all = b;
+ udwords q;
+ udwords r;
+ unsigned sr;
+ /* special cases, X is unknown, K != 0 */
+ if (n.s.high == 0)
+ {
+ if (d.s.high == 0)
+ {
+ /* 0 X
+ * ---
+ * 0 X
+ */
+ if (rem)
+ *rem = n.s.low % d.s.low;
+ return n.s.low / d.s.low;
+ }
+ /* 0 X
+ * ---
+ * K X
+ */
+ if (rem)
+ *rem = n.s.low;
+ return 0;
+ }
+ /* n.s.high != 0 */
+ if (d.s.low == 0)
+ {
+ if (d.s.high == 0)
+ {
+ /* K X
+ * ---
+ * 0 0
+ */
+ if (rem)
+ *rem = n.s.high % d.s.low;
+ return n.s.high / d.s.low;
+ }
+ /* d.s.high != 0 */
+ if (n.s.low == 0)
+ {
+ /* K 0
+ * ---
+ * K 0
+ */
+ if (rem)
+ {
+ r.s.high = n.s.high % d.s.high;
+ r.s.low = 0;
+ *rem = r.all;
+ }
+ return n.s.high / d.s.high;
+ }
+ /* K K
+ * ---
+ * K 0
+ */
+ if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */
+ {
+ if (rem)
+ {
+ r.s.low = n.s.low;
+ r.s.high = n.s.high & (d.s.high - 1);
+ *rem = r.all;
+ }
+ return n.s.high >> __builtin_ctz(d.s.high);
+ }
+ /* K K
+ * ---
+ * K 0
+ */
+ sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high);
+ /* 0 <= sr <= n_uword_bits - 2 or sr large */
+ if (sr > n_uword_bits - 2)
+ {
+ if (rem)
+ *rem = n.all;
+ return 0;
+ }
+ ++sr;
+ /* 1 <= sr <= n_uword_bits - 1 */
+ /* q.all = n.all << (n_udword_bits - sr); */
+ q.s.low = 0;
+ q.s.high = n.s.low << (n_uword_bits - sr);
+ /* r.all = n.all >> sr; */
+ r.s.high = n.s.high >> sr;
+ r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
+ }
+ else /* d.s.low != 0 */
+ {
+ if (d.s.high == 0)
+ {
+ /* K X
+ * ---
+ * 0 K
+ */
+ if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */
+ {
+ if (rem)
+ *rem = n.s.low & (d.s.low - 1);
+ if (d.s.low == 1)
+ return n.all;
+ unsigned sr = __builtin_ctz(d.s.low);
+ q.s.high = n.s.high >> sr;
+ q.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
+ return q.all;
+ }
+ /* K X
+ * ---
+ *0 K
+ */
+ sr = 1 + n_uword_bits + __builtin_clz(d.s.low) - __builtin_clz(n.s.high);
+ /* 2 <= sr <= n_udword_bits - 1
+ * q.all = n.all << (n_udword_bits - sr);
+ * r.all = n.all >> sr;
+ * if (sr == n_uword_bits)
+ * {
+ * q.s.low = 0;
+ * q.s.high = n.s.low;
+ * r.s.high = 0;
+ * r.s.low = n.s.high;
+ * }
+ * else if (sr < n_uword_bits) // 2 <= sr <= n_uword_bits - 1
+ * {
+ * q.s.low = 0;
+ * q.s.high = n.s.low << (n_uword_bits - sr);
+ * r.s.high = n.s.high >> sr;
+ * r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
+ * }
+ * else // n_uword_bits + 1 <= sr <= n_udword_bits - 1
+ * {
+ * q.s.low = n.s.low << (n_udword_bits - sr);
+ * q.s.high = (n.s.high << (n_udword_bits - sr)) |
+ * (n.s.low >> (sr - n_uword_bits));
+ * r.s.high = 0;
+ * r.s.low = n.s.high >> (sr - n_uword_bits);
+ * }
+ */
+ q.s.low = (n.s.low << (n_udword_bits - sr)) &
+ ((si_int)(n_uword_bits - sr) >> (n_uword_bits-1));
+ q.s.high = ((n.s.low << ( n_uword_bits - sr)) &
+ ((si_int)(sr - n_uword_bits - 1) >> (n_uword_bits-1))) |
+ (((n.s.high << (n_udword_bits - sr)) |
+ (n.s.low >> (sr - n_uword_bits))) &
+ ((si_int)(n_uword_bits - sr) >> (n_uword_bits-1)));
+ r.s.high = (n.s.high >> sr) &
+ ((si_int)(sr - n_uword_bits) >> (n_uword_bits-1));
+ r.s.low = ((n.s.high >> (sr - n_uword_bits)) &
+ ((si_int)(n_uword_bits - sr - 1) >> (n_uword_bits-1))) |
+ (((n.s.high << (n_uword_bits - sr)) |
+ (n.s.low >> sr)) &
+ ((si_int)(sr - n_uword_bits) >> (n_uword_bits-1)));
+ }
+ else
+ {
+ /* K X
+ * ---
+ * K K
+ */
+ sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high);
+ /* 0 <= sr <= n_uword_bits - 1 or sr large */
+ if (sr > n_uword_bits - 1)
+ {
+ if (rem)
+ *rem = n.all;
+ return 0;
+ }
+ ++sr;
+ /* 1 <= sr <= n_uword_bits */
+ /* q.all = n.all << (n_udword_bits - sr); */
+ q.s.low = 0;
+ q.s.high = n.s.low << (n_uword_bits - sr);
+ /* r.all = n.all >> sr;
+ * if (sr < n_uword_bits)
+ * {
+ * r.s.high = n.s.high >> sr;
+ * r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
+ * }
+ * else
+ * {
+ * r.s.high = 0;
+ * r.s.low = n.s.high;
+ * }
+ */
+ r.s.high = (n.s.high >> sr) &
+ ((si_int)(sr - n_uword_bits) >> (n_uword_bits-1));
+ r.s.low = (n.s.high << (n_uword_bits - sr)) |
+ ((n.s.low >> sr) &
+ ((si_int)(sr - n_uword_bits) >> (n_uword_bits-1)));
+ }
+ }
+ /* Not a special case
+ * q and r are initialized with:
+ * q.all = n.all << (n_udword_bits - sr);
+ * r.all = n.all >> sr;
+ * 1 <= sr <= n_udword_bits - 1
+ */
+ su_int carry = 0;
+ for (; sr > 0; --sr)
+ {
+ /* r:q = ((r:q) << 1) | carry */
+ r.s.high = (r.s.high << 1) | (r.s.low >> (n_uword_bits - 1));
+ r.s.low = (r.s.low << 1) | (q.s.high >> (n_uword_bits - 1));
+ q.s.high = (q.s.high << 1) | (q.s.low >> (n_uword_bits - 1));
+ q.s.low = (q.s.low << 1) | carry;
+ /* carry = 0;
+ * if (r.all >= d.all)
+ * {
+ * r.all -= d.all;
+ * carry = 1;
+ * }
+ */
+ const di_int s = (di_int)(d.all - r.all - 1) >> (n_udword_bits - 1);
+ carry = s & 1;
+ r.all -= d.all & s;
+ }
+ q.all = (q.all << 1) | carry;
+ if (rem)
+ *rem = r.all;
+ return q.all;
+}
diff --git a/lib/udivmodti4.c b/lib/udivmodti4.c
new file mode 100644
index 000000000000..53b407256e67
--- /dev/null
+++ b/lib/udivmodti4.c
@@ -0,0 +1,256 @@
+/* ===-- udivmodti4.c - Implement __udivmodti4 -----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __udivmodti4 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+/* Effects: if rem != 0, *rem = a % b
+ * Returns: a / b
+ */
+
+/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */
+
+tu_int
+__udivmodti4(tu_int a, tu_int b, tu_int* rem)
+{
+ const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;
+ const unsigned n_utword_bits = sizeof(tu_int) * CHAR_BIT;
+ utwords n;
+ n.all = a;
+ utwords d;
+ d.all = b;
+ utwords q;
+ utwords r;
+ unsigned sr;
+ /* special cases, X is unknown, K != 0 */
+ if (n.s.high == 0)
+ {
+ if (d.s.high == 0)
+ {
+ /* 0 X
+ * ---
+ * 0 X
+ */
+ if (rem)
+ *rem = n.s.low % d.s.low;
+ return n.s.low / d.s.low;
+ }
+ /* 0 X
+ * ---
+ * K X
+ */
+ if (rem)
+ *rem = n.s.low;
+ return 0;
+ }
+ /* n.s.high != 0 */
+ if (d.s.low == 0)
+ {
+ if (d.s.high == 0)
+ {
+ /* K X
+ * ---
+ * 0 0
+ */
+ if (rem)
+ *rem = n.s.high % d.s.low;
+ return n.s.high / d.s.low;
+ }
+ /* d.s.high != 0 */
+ if (n.s.low == 0)
+ {
+ /* K 0
+ * ---
+ * K 0
+ */
+ if (rem)
+ {
+ r.s.high = n.s.high % d.s.high;
+ r.s.low = 0;
+ *rem = r.all;
+ }
+ return n.s.high / d.s.high;
+ }
+ /* K K
+ * ---
+ * K 0
+ */
+ if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */
+ {
+ if (rem)
+ {
+ r.s.low = n.s.low;
+ r.s.high = n.s.high & (d.s.high - 1);
+ *rem = r.all;
+ }
+ return n.s.high >> __builtin_ctzll(d.s.high);
+ }
+ /* K K
+ * ---
+ * K 0
+ */
+ sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);
+ /* 0 <= sr <= n_udword_bits - 2 or sr large */
+ if (sr > n_udword_bits - 2)
+ {
+ if (rem)
+ *rem = n.all;
+ return 0;
+ }
+ ++sr;
+ /* 1 <= sr <= n_udword_bits - 1 */
+ /* q.all = n.all << (n_utword_bits - sr); */
+ q.s.low = 0;
+ q.s.high = n.s.low << (n_udword_bits - sr);
+ /* r.all = n.all >> sr; */
+ r.s.high = n.s.high >> sr;
+ r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+ }
+ else /* d.s.low != 0 */
+ {
+ if (d.s.high == 0)
+ {
+ /* K X
+ * ---
+ * 0 K
+ */
+ if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */
+ {
+ if (rem)
+ *rem = n.s.low & (d.s.low - 1);
+ if (d.s.low == 1)
+ return n.all;
+ unsigned sr = __builtin_ctzll(d.s.low);
+ q.s.high = n.s.high >> sr;
+ q.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+ return q.all;
+ }
+ /* K X
+ * ---
+ * 0 K
+ */
+ sr = 1 + n_udword_bits + __builtin_clzll(d.s.low)
+ - __builtin_clzll(n.s.high);
+ /* 2 <= sr <= n_utword_bits - 1
+ * q.all = n.all << (n_utword_bits - sr);
+ * r.all = n.all >> sr;
+ * if (sr == n_udword_bits)
+ * {
+ * q.s.low = 0;
+ * q.s.high = n.s.low;
+ * r.s.high = 0;
+ * r.s.low = n.s.high;
+ * }
+ * else if (sr < n_udword_bits) // 2 <= sr <= n_udword_bits - 1
+ * {
+ * q.s.low = 0;
+ * q.s.high = n.s.low << (n_udword_bits - sr);
+ * r.s.high = n.s.high >> sr;
+ * r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+ * }
+ * else // n_udword_bits + 1 <= sr <= n_utword_bits - 1
+ * {
+ * q.s.low = n.s.low << (n_utword_bits - sr);
+ * q.s.high = (n.s.high << (n_utword_bits - sr)) |
+ * (n.s.low >> (sr - n_udword_bits));
+ * r.s.high = 0;
+ * r.s.low = n.s.high >> (sr - n_udword_bits);
+ * }
+ */
+ q.s.low = (n.s.low << (n_utword_bits - sr)) &
+ ((di_int)(int)(n_udword_bits - sr) >> (n_udword_bits-1));
+ q.s.high = ((n.s.low << ( n_udword_bits - sr)) &
+ ((di_int)(int)(sr - n_udword_bits - 1) >> (n_udword_bits-1))) |
+ (((n.s.high << (n_utword_bits - sr)) |
+ (n.s.low >> (sr - n_udword_bits))) &
+ ((di_int)(int)(n_udword_bits - sr) >> (n_udword_bits-1)));
+ r.s.high = (n.s.high >> sr) &
+ ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1));
+ r.s.low = ((n.s.high >> (sr - n_udword_bits)) &
+ ((di_int)(int)(n_udword_bits - sr - 1) >> (n_udword_bits-1))) |
+ (((n.s.high << (n_udword_bits - sr)) |
+ (n.s.low >> sr)) &
+ ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1)));
+ }
+ else
+ {
+ /* K X
+ * ---
+ * K K
+ */
+ sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);
+ /*0 <= sr <= n_udword_bits - 1 or sr large */
+ if (sr > n_udword_bits - 1)
+ {
+ if (rem)
+ *rem = n.all;
+ return 0;
+ }
+ ++sr;
+ /* 1 <= sr <= n_udword_bits */
+ /* q.all = n.all << (n_utword_bits - sr); */
+ q.s.low = 0;
+ q.s.high = n.s.low << (n_udword_bits - sr);
+ /* r.all = n.all >> sr;
+ * if (sr < n_udword_bits)
+ * {
+ * r.s.high = n.s.high >> sr;
+ * r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+ * }
+ * else
+ * {
+ * r.s.high = 0;
+ * r.s.low = n.s.high;
+ * }
+ */
+ r.s.high = (n.s.high >> sr) &
+ ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1));
+ r.s.low = (n.s.high << (n_udword_bits - sr)) |
+ ((n.s.low >> sr) &
+ ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1)));
+ }
+ }
+ /* Not a special case
+ * q and r are initialized with:
+ * q.all = n.all << (n_utword_bits - sr);
+ * r.all = n.all >> sr;
+ * 1 <= sr <= n_utword_bits - 1
+ */
+ su_int carry = 0;
+ for (; sr > 0; --sr)
+ {
+ /* r:q = ((r:q) << 1) | carry */
+ r.s.high = (r.s.high << 1) | (r.s.low >> (n_udword_bits - 1));
+ r.s.low = (r.s.low << 1) | (q.s.high >> (n_udword_bits - 1));
+ q.s.high = (q.s.high << 1) | (q.s.low >> (n_udword_bits - 1));
+ q.s.low = (q.s.low << 1) | carry;
+ /* carry = 0;
+ * if (r.all >= d.all)
+ * {
+ * r.all -= d.all;
+ * carry = 1;
+ * }
+ */
+ const ti_int s = (ti_int)(d.all - r.all - 1) >> (n_utword_bits - 1);
+ carry = s & 1;
+ r.all -= d.all & s;
+ }
+ q.all = (q.all << 1) | carry;
+ if (rem)
+ *rem = r.all;
+ return q.all;
+}
+
+#endif /* __x86_64 */
diff --git a/lib/udivsi3.c b/lib/udivsi3.c
new file mode 100644
index 000000000000..70528b66e2b4
--- /dev/null
+++ b/lib/udivsi3.c
@@ -0,0 +1,63 @@
+/* ===-- udivsi3.c - Implement __udivsi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __udivsi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: a / b */
+
+/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */
+
+su_int
+__udivsi3(su_int n, su_int d)
+{
+ const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT;
+ su_int q;
+ su_int r;
+ unsigned sr;
+ /* special cases */
+ if (d == 0)
+ return 0; /* ?! */
+ if (n == 0)
+ return 0;
+ sr = __builtin_clz(d) - __builtin_clz(n);
+ /* 0 <= sr <= n_uword_bits - 1 or sr large */
+ if (sr > n_uword_bits - 1) /* d > r */
+ return 0;
+ if (sr == n_uword_bits - 1) /* d == 1 */
+ return n;
+ ++sr;
+ /* 1 <= sr <= n_uword_bits - 1 */
+ /* Not a special case */
+ q = n << (n_uword_bits - sr);
+ r = n >> sr;
+ su_int carry = 0;
+ for (; sr > 0; --sr)
+ {
+ /* r:q = ((r:q) << 1) | carry */
+ r = (r << 1) | (q >> (n_uword_bits - 1));
+ q = (q << 1) | carry;
+ /* carry = 0;
+ * if (r.all >= d.all)
+ * {
+ * r.all -= d.all;
+ * carry = 1;
+ * }
+ */
+ const si_int s = (si_int)(d - r - 1) >> (n_uword_bits - 1);
+ carry = s & 1;
+ r -= d & s;
+ }
+ q = (q << 1) | carry;
+ return q;
+}
diff --git a/lib/udivti3.c b/lib/udivti3.c
new file mode 100644
index 000000000000..fb810fda5fae
--- /dev/null
+++ b/lib/udivti3.c
@@ -0,0 +1,29 @@
+/* ===-- udivti3.c - Implement __udivti3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __udivti3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
+
+/* Returns: a / b */
+
+tu_int
+__udivti3(tu_int a, tu_int b)
+{
+ return __udivmodti4(a, b, 0);
+}
+
+#endif /* __x86_64 */
diff --git a/lib/umoddi3.c b/lib/umoddi3.c
new file mode 100644
index 000000000000..807bb5cec622
--- /dev/null
+++ b/lib/umoddi3.c
@@ -0,0 +1,27 @@
+/* ===-- umoddi3.c - Implement __umoddi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __umoddi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+du_int __udivmoddi4(du_int a, du_int b, du_int* rem);
+
+/* Returns: a % b */
+
+du_int
+__umoddi3(du_int a, du_int b)
+{
+ du_int r;
+ __udivmoddi4(a, b, &r);
+ return r;
+}
diff --git a/lib/umodsi3.c b/lib/umodsi3.c
new file mode 100644
index 000000000000..ead7737587a8
--- /dev/null
+++ b/lib/umodsi3.c
@@ -0,0 +1,25 @@
+/* ===-- umodsi3.c - Implement __umodsi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __umodsi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: a % b */
+
+su_int __udivsi3(su_int a, su_int b);
+
+su_int
+__umodsi3(su_int a, su_int b)
+{
+ return a - __udivsi3(a, b) * b;
+}
diff --git a/lib/umodti3.c b/lib/umodti3.c
new file mode 100644
index 000000000000..6c8a7581aeea
--- /dev/null
+++ b/lib/umodti3.c
@@ -0,0 +1,31 @@
+/* ===-- umodti3.c - Implement __umodti3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __umodti3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#if __x86_64
+
+#include "int_lib.h"
+
+tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
+
+/* Returns: a % b */
+
+tu_int
+__umodti3(tu_int a, tu_int b)
+{
+ tu_int r;
+ __udivmodti4(a, b, &r);
+ return r;
+}
+
+#endif
diff --git a/lib/x86_64/CMakeLists.txt b/lib/x86_64/CMakeLists.txt
new file mode 100644
index 000000000000..ee21308e20c3
--- /dev/null
+++ b/lib/x86_64/CMakeLists.txt
@@ -0,0 +1,5 @@
+SET( SRCS
+ floatdixf.c
+ floatdisf.c
+ floatdidf.c
+ )
diff --git a/lib/x86_64/Makefile.mk b/lib/x86_64/Makefile.mk
new file mode 100644
index 000000000000..09037b9fbc8a
--- /dev/null
+++ b/lib/x86_64/Makefile.mk
@@ -0,0 +1,19 @@
+#===- lib/x86_64/Makefile.mk -------------------------------*- Makefile -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+SubDirs :=
+OnlyArchs := x86_64
+
+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/lib/x86_64/floatdidf.c b/lib/x86_64/floatdidf.c
new file mode 100644
index 000000000000..cce3cd514a40
--- /dev/null
+++ b/lib/x86_64/floatdidf.c
@@ -0,0 +1,16 @@
+/* This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ */
+
+/* double __floatdidf(di_int a); */
+
+#ifdef __x86_64__
+
+#include <stdint.h>
+
+double __floatdidf(int64_t a)
+{
+ return (double)a;
+}
+
+#endif /* __x86_64__ */
diff --git a/lib/x86_64/floatdisf.c b/lib/x86_64/floatdisf.c
new file mode 100644
index 000000000000..753ba90dfb0e
--- /dev/null
+++ b/lib/x86_64/floatdisf.c
@@ -0,0 +1,14 @@
+/* This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ */
+
+#ifdef __x86_64__
+
+#include <stdint.h>
+
+float __floatdisf(int64_t a)
+{
+ return (float)a;
+}
+
+#endif /* __x86_64__ */
diff --git a/lib/x86_64/floatdixf.c b/lib/x86_64/floatdixf.c
new file mode 100644
index 000000000000..569f72774001
--- /dev/null
+++ b/lib/x86_64/floatdixf.c
@@ -0,0 +1,16 @@
+/* This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ */
+
+/* long double __floatdixf(di_int a); */
+
+#ifdef __x86_64__
+
+#include <stdint.h>
+
+long double __floatdixf(int64_t a)
+{
+ return (long double)a;
+}
+
+#endif /* __i386__ */
diff --git a/lib/x86_64/floatundidf.S b/lib/x86_64/floatundidf.S
new file mode 100644
index 000000000000..6e684b2a4cab
--- /dev/null
+++ b/lib/x86_64/floatundidf.S
@@ -0,0 +1,43 @@
+//===-- floatundidf.S - Implement __floatundidf for x86_64 ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatundidf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// double __floatundidf(du_int a);
+
+#ifdef __x86_64__
+
+#ifndef __ELF__
+.const
+#endif
+.align 4
+twop52: .quad 0x4330000000000000
+twop84_plus_twop52:
+ .quad 0x4530000000100000
+twop84: .quad 0x4530000000000000
+
+#define REL_ADDR(_a) (_a)(%rip)
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__floatundidf)
+ movd %edi, %xmm0 // low 32 bits of a
+ shrq $32, %rdi // high 32 bits of a
+ orq REL_ADDR(twop84), %rdi // 0x1p84 + a_hi (no rounding occurs)
+ orpd REL_ADDR(twop52), %xmm0 // 0x1p52 + a_lo (no rounding occurs)
+ movd %rdi, %xmm1
+ subsd REL_ADDR(twop84_plus_twop52), %xmm1 // a_hi - 0x1p52 (no rounding occurs)
+ addsd %xmm1, %xmm0 // a_hi + a_lo (round happens here)
+ ret
+
+#endif // __x86_64__
diff --git a/lib/x86_64/floatundisf.S b/lib/x86_64/floatundisf.S
new file mode 100644
index 000000000000..fe209632a38e
--- /dev/null
+++ b/lib/x86_64/floatundisf.S
@@ -0,0 +1,33 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// float __floatundisf(du_int a);
+
+#ifdef __x86_64__
+
+#ifndef __ELF__
+.literal4
+#endif
+two: .single 2.0
+
+#define REL_ADDR(_a) (_a)(%rip)
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__floatundisf)
+ movq $1, %rsi
+ testq %rdi, %rdi
+ js 1f
+ cvtsi2ssq %rdi, %xmm0
+ ret
+
+1: andq %rdi, %rsi
+ shrq %rdi
+ orq %rsi, %rdi
+ cvtsi2ssq %rdi, %xmm0
+ mulss REL_ADDR(two), %xmm0
+ ret
+
+#endif // __x86_64__
diff --git a/lib/x86_64/floatundixf.S b/lib/x86_64/floatundixf.S
new file mode 100644
index 000000000000..246f0266c8a1
--- /dev/null
+++ b/lib/x86_64/floatundixf.S
@@ -0,0 +1,62 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// long double __floatundixf(du_int a);
+
+#ifdef __x86_64__
+
+#ifndef __ELF__
+.const
+#endif
+.align 4
+twop64: .quad 0x43f0000000000000
+
+#define REL_ADDR(_a) (_a)(%rip)
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__floatundixf)
+ movq %rdi, -8(%rsp)
+ fildq -8(%rsp)
+ test %rdi, %rdi
+ js 1f
+ ret
+1: faddl REL_ADDR(twop64)
+ ret
+
+#endif // __x86_64__
+
+
+/* Branch-free implementation is ever so slightly slower, but more beautiful.
+ It is likely superior for inlining, so I kept it around for future reference.
+
+#ifdef __x86_64__
+
+.const
+.align 4
+twop52: .quad 0x4330000000000000
+twop84_plus_twop52_neg:
+ .quad 0xc530000000100000
+twop84: .quad 0x4530000000000000
+
+#define REL_ADDR(_a) (_a)(%rip)
+
+.text
+.align 4
+DEFINE_COMPILERRT_FUNCTION(__floatundixf)
+ movl %edi, %esi // low 32 bits of input
+ shrq $32, %rdi // hi 32 bits of input
+ orq REL_ADDR(twop84), %rdi // 2^84 + hi (as a double)
+ orq REL_ADDR(twop52), %rsi // 2^52 + lo (as a double)
+ movq %rdi, -8(%rsp)
+ movq %rsi, -16(%rsp)
+ fldl REL_ADDR(twop84_plus_twop52_neg)
+ faddl -8(%rsp) // hi - 2^52 (as double extended, no rounding occurs)
+ faddl -16(%rsp) // hi + lo (as double extended)
+ ret
+
+#endif // __x86_64__
+
+*/