summaryrefslogtreecommitdiff
path: root/lib/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'lib/x86_64')
-rw-r--r--lib/x86_64/Makefile.mk22
-rw-r--r--lib/x86_64/floatdidf.c15
-rw-r--r--lib/x86_64/floatdisf.c13
-rw-r--r--lib/x86_64/floatdixf.c15
-rw-r--r--lib/x86_64/floatundidf.s40
-rw-r--r--lib/x86_64/floatundisf.s30
-rw-r--r--lib/x86_64/floatundixf.s60
7 files changed, 195 insertions, 0 deletions
diff --git a/lib/x86_64/Makefile.mk b/lib/x86_64/Makefile.mk
new file mode 100644
index 000000000..f5f545e0e
--- /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 000000000..ecef079b6
--- /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 000000000..c22a453d4
--- /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 000000000..73b5da9fa
--- /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 000000000..2eb8c7a76
--- /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 000000000..b40868740
--- /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 000000000..0764da49a
--- /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