Initial import of compiler-rt.
 -


git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@74292 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/x86_64/Makefile.mk b/lib/x86_64/Makefile.mk
new file mode 100644
index 0000000..f5f545e
--- /dev/null
+++ b/lib/x86_64/Makefile.mk
@@ -0,0 +1,22 @@
+#===- 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.
+#
+#===------------------------------------------------------------------------===#
+
+Dir := lib/x86_64
+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)
+Target := Optimized
+
+# FIXME: use automatic dependencies?
+Dependencies := $(wildcard $(Dir)/*.h)
+
+include make/subdir.mk
diff --git a/lib/x86_64/floatdidf.c b/lib/x86_64/floatdidf.c
new file mode 100644
index 0000000..ecef079
--- /dev/null
+++ b/lib/x86_64/floatdidf.c
@@ -0,0 +1,15 @@
+// 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__
\ No newline at end of file
diff --git a/lib/x86_64/floatdisf.c b/lib/x86_64/floatdisf.c
new file mode 100644
index 0000000..c22a453
--- /dev/null
+++ b/lib/x86_64/floatdisf.c
@@ -0,0 +1,13 @@
+// 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__
\ No newline at end of file
diff --git a/lib/x86_64/floatdixf.c b/lib/x86_64/floatdixf.c
new file mode 100644
index 0000000..73b5da9
--- /dev/null
+++ b/lib/x86_64/floatdixf.c
@@ -0,0 +1,15 @@
+// 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 0000000..2eb8c7a
--- /dev/null
+++ b/lib/x86_64/floatundidf.s
@@ -0,0 +1,40 @@
+//===-- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// double __floatundidf(du_int a);
+
+#ifdef __x86_64__
+
+.const
+.align 4
+twop52: .quad 0x4330000000000000
+twop84_plus_twop52:
+		.quad 0x4530000000100000
+twop84: .quad 0x4530000000000000
+
+#define REL_ADDR(_a)	(_a)(%rip)
+
+.text
+.align 4
+.globl ___floatundidf
+___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__
\ No newline at end of file
diff --git a/lib/x86_64/floatundisf.s b/lib/x86_64/floatundisf.s
new file mode 100644
index 0000000..b408687
--- /dev/null
+++ b/lib/x86_64/floatundisf.s
@@ -0,0 +1,30 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// float __floatundisf(du_int a);
+
+#ifdef __x86_64__
+
+.literal4
+two: .single 2.0
+
+#define REL_ADDR(_a)	(_a)(%rip)
+
+.text
+.align 4
+.globl ___floatundisf
+___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__
\ No newline at end of file
diff --git a/lib/x86_64/floatundixf.s b/lib/x86_64/floatundixf.s
new file mode 100644
index 0000000..0764da4
--- /dev/null
+++ b/lib/x86_64/floatundixf.s
@@ -0,0 +1,60 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// long double __floatundixf(du_int a);
+
+#ifdef __x86_64__
+
+.const
+.align 4
+twop64: .quad 0x43f0000000000000
+
+#define REL_ADDR(_a)	(_a)(%rip)
+
+.text
+.align 4
+.globl ___floatundixf
+___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
+.globl ___floatundixf
+___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__
+
+*/
\ No newline at end of file