summaryrefslogtreecommitdiff
path: root/lib/builtins/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'lib/builtins/x86_64')
-rw-r--r--lib/builtins/x86_64/Makefile.mk20
-rw-r--r--lib/builtins/x86_64/floatdidf.c16
-rw-r--r--lib/builtins/x86_64/floatdisf.c14
-rw-r--r--lib/builtins/x86_64/floatdixf.c16
-rw-r--r--lib/builtins/x86_64/floatundidf.S49
-rw-r--r--lib/builtins/x86_64/floatundisf.S35
-rw-r--r--lib/builtins/x86_64/floatundixf.S68
7 files changed, 218 insertions, 0 deletions
diff --git a/lib/builtins/x86_64/Makefile.mk b/lib/builtins/x86_64/Makefile.mk
new file mode 100644
index 0000000000000..83848dddd964c
--- /dev/null
+++ b/lib/builtins/x86_64/Makefile.mk
@@ -0,0 +1,20 @@
+#===- lib/builtins/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.
+#
+#===------------------------------------------------------------------------===#
+
+ModuleName := builtins
+SubDirs :=
+OnlyArchs := x86_64 x86_64h
+
+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/builtins/x86_64/floatdidf.c b/lib/builtins/x86_64/floatdidf.c
new file mode 100644
index 0000000000000..388404e5e0891
--- /dev/null
+++ b/lib/builtins/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 "../int_lib.h"
+
+double __floatdidf(int64_t a)
+{
+ return (double)a;
+}
+
+#endif /* __x86_64__ */
diff --git a/lib/builtins/x86_64/floatdisf.c b/lib/builtins/x86_64/floatdisf.c
new file mode 100644
index 0000000000000..96c3728e92c36
--- /dev/null
+++ b/lib/builtins/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 "../int_lib.h"
+
+float __floatdisf(int64_t a)
+{
+ return (float)a;
+}
+
+#endif /* __x86_64__ */
diff --git a/lib/builtins/x86_64/floatdixf.c b/lib/builtins/x86_64/floatdixf.c
new file mode 100644
index 0000000000000..c01193a82b5e8
--- /dev/null
+++ b/lib/builtins/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 "../int_lib.h"
+
+long double __floatdixf(int64_t a)
+{
+ return (long double)a;
+}
+
+#endif /* __i386__ */
diff --git a/lib/builtins/x86_64/floatundidf.S b/lib/builtins/x86_64/floatundidf.S
new file mode 100644
index 0000000000000..3cd5d02a743a8
--- /dev/null
+++ b/lib/builtins/x86_64/floatundidf.S
@@ -0,0 +1,49 @@
+//===-- floatundidf.S - Implement __floatundidf for x86_64 ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements __floatundidf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// double __floatundidf(du_int a);
+
+#ifdef __x86_64__
+
+CONST_SECTION
+
+ .balign 16
+twop52:
+ .quad 0x4330000000000000
+
+ .balign 16
+twop84_plus_twop52:
+ .quad 0x4530000000100000
+
+ .balign 16
+twop84:
+ .quad 0x4530000000000000
+
+#define REL_ADDR(_a) (_a)(%rip)
+
+.text
+.balign 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
+END_COMPILERRT_FUNCTION(__floatundidf)
+
+#endif // __x86_64__
diff --git a/lib/builtins/x86_64/floatundisf.S b/lib/builtins/x86_64/floatundisf.S
new file mode 100644
index 0000000000000..61952f40470c0
--- /dev/null
+++ b/lib/builtins/x86_64/floatundisf.S
@@ -0,0 +1,35 @@
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// float __floatundisf(du_int a);
+
+#ifdef __x86_64__
+
+CONST_SECTION
+
+ .balign 16
+two:
+ .single 2.0
+
+#define REL_ADDR(_a) (_a)(%rip)
+
+.text
+.balign 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
+END_COMPILERRT_FUNCTION(__floatundisf)
+
+#endif // __x86_64__
diff --git a/lib/builtins/x86_64/floatundixf.S b/lib/builtins/x86_64/floatundixf.S
new file mode 100644
index 0000000000000..92961c89115d9
--- /dev/null
+++ b/lib/builtins/x86_64/floatundixf.S
@@ -0,0 +1,68 @@
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+
+#include "../assembly.h"
+
+// long double __floatundixf(du_int a);
+
+#ifdef __x86_64__
+
+CONST_SECTION
+
+ .balign 16
+twop64:
+ .quad 0x43f0000000000000
+
+#define REL_ADDR(_a) (_a)(%rip)
+
+ .text
+
+ .balign 4
+DEFINE_COMPILERRT_FUNCTION(__floatundixf)
+ movq %rdi, -8(%rsp)
+ fildq -8(%rsp)
+ test %rdi, %rdi
+ js 1f
+ ret
+1: faddl REL_ADDR(twop64)
+ ret
+END_COMPILERRT_FUNCTION(__floatundixf)
+
+#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_SECTION
+
+ .balign 4
+twop52:
+ .quad 0x4330000000000000
+twop84_plus_twop52_neg:
+ .quad 0xc530000000100000
+twop84:
+ .quad 0x4530000000000000
+
+#define REL_ADDR(_a) (_a)(%rip)
+
+.text
+.balign 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
+END_COMPILERRT_FUNCTION(__floatundixf)
+
+#endif // __x86_64__
+
+*/