summaryrefslogtreecommitdiff
path: root/usr/src/lib/libc
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2014-10-31 15:35:24 +0000
committerKeith M Wesolowski <wesolows@foobazco.org>2014-10-31 15:35:24 +0000
commit17d29671cb8be10e20dee85973c91d75605ccfdc (patch)
tree4e06f28256ef1aa8ae41f8f8543b145de3141f70 /usr/src/lib/libc
parent17cf16577a651f32bd17655cbdb526c41cf90d36 (diff)
parent5a172a1e0f9068ec8db35fa123baecf7bd540eb5 (diff)
downloadillumos-joyent-17d29671cb8be10e20dee85973c91d75605ccfdc.tar.gz
[illumos-gate merge]
commit 5a172a1e0f9068ec8db35fa123baecf7bd540eb5 5224 snprintf rounding under [default] FE_TONEAREST
Diffstat (limited to 'usr/src/lib/libc')
-rw-r--r--usr/src/lib/libc/amd64/Makefile5
-rw-r--r--usr/src/lib/libc/amd64/fp/_base_il.s121
-rw-r--r--usr/src/lib/libc/amd64/fp/ieee.c (renamed from usr/src/lib/libc/amd64/fp/_base_il.c)52
-rw-r--r--usr/src/lib/libc/i386/Makefile.com5
-rw-r--r--usr/src/lib/libc/i386/fp/_base_il.s120
-rw-r--r--usr/src/lib/libc/i386/fp/ieee.c (renamed from usr/src/lib/libc/i386/fp/_base_il.c)52
6 files changed, 247 insertions, 108 deletions
diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile
index a7cfc36ddb..9a496b0d7e 100644
--- a/usr/src/lib/libc/amd64/Makefile
+++ b/usr/src/lib/libc/amd64/Makefile
@@ -47,12 +47,12 @@ CRTOBJS= \
DYNOBJS=
FPOBJS= \
- _base_il.o \
fpgetmask.o \
fpgetround.o \
fpsetmask.o \
fpsetround.o \
- fpstart.o
+ fpstart.o \
+ ieee.o
I386FPOBJS= \
_D_cplx_div.o \
@@ -81,6 +81,7 @@ FPASMOBJS= \
__xgetRD.o \
_xtoll.o \
_xtoull.o \
+ _base_il.o \
fpcw.o \
fpgetsticky.o \
fpsetsticky.o
diff --git a/usr/src/lib/libc/amd64/fp/_base_il.s b/usr/src/lib/libc/amd64/fp/_base_il.s
new file mode 100644
index 0000000000..221c848538
--- /dev/null
+++ b/usr/src/lib/libc/amd64/fp/_base_il.s
@@ -0,0 +1,121 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
+ */
+
+ .file "_base_il.s"
+
+/*
+ * These files are in assembly because some compilers will mistakenly reorder
+ * multiplications or divisions wrapped in _putsw() and _getsw(). They are
+ * proper subroutines for now, but should be considered candidates for
+ * inlining eventually.
+ *
+ * The original C sources are included for readability in the pre-function
+ * comment blocks.
+ */
+
+#include <SYS.h>
+
+/*
+ * Multiplies two normal or subnormal doubles, returns result and exceptions.
+ *
+
+double
+__mul_set(double x, double y, int *pe) {
+ extern void _putmxcsr(), _getmxcsr();
+ int csr;
+ double z;
+
+ _putmxcsr(CSR_DEFAULT);
+ z = x * y;
+ _getmxcsr(&csr);
+ if ((csr & 0x3f) == 0) {
+ *pe = 0;
+ } else {
+ *pe = 1;
+ }
+ return (z);
+}
+
+ */
+ ENTRY(__mul_set)
+ xorl %eax, %eax /* Zero-out eax for later... */
+ subq $0x4, %rsp
+ movl $0x1f80, (%rsp) /* 0x1f80 == CSR_DEFAULT. */
+ /* Set the MXCSR to its default (i.e. No FP exceptions). */
+ ldmxcsr (%rsp) /* Essentially _putmxcsr(CSR_DEFAULT); */
+
+ mulsd %xmm1, %xmm0 /* Do the multiply. */
+
+ /* Check to see if the multiply caused any exceptions. */
+ stmxcsr (%rsp) /* Essentially do _getmxcsr(). */
+ andl $0x3f, (%rsp) /* Check it. */
+ setne %al /* Boolean FP exception indicator for *pe. */
+ movl %eax, (%rdi)
+ addq $0x4, %rsp
+ ret
+ SET_SIZE(__mul_set)
+
+/*
+ * Divides two normal or subnormal doubles x/y, returns result and exceptions.
+ *
+
+double
+__div_set(double x, double y, int *pe) {
+ extern void _putmxcsr(), _getmxcsr();
+ int csr;
+ double z;
+
+ _putmxcsr(CSR_DEFAULT);
+ z = x / y;
+ _getmxcsr(&csr);
+ if ((csr & 0x3f) == 0) {
+ *pe = 0;
+ } else {
+ *pe = 1;
+ }
+ return (z);
+}
+
+ */
+
+ ENTRY(__div_set)
+ xorl %eax, %eax /* Zero-out eax for later... */
+ subq $0x4, %rsp
+ movl $0x1f80, (%rsp) /* 0x1f80 == CSR_DEFAULT. */
+ /* Set the MXCSR to its default (i.e. No FP exceptions). */
+ ldmxcsr (%rsp) /* Essentially _putmxcsr(CSR_DEFAULT); */
+
+ divsd %xmm1, %xmm0 /* Do the divide. */
+
+ /* Check to see if the divide caused any exceptions. */
+ stmxcsr (%rsp) /* Essentially do _getmxcsr(). */
+ andl $0x3f, (%rsp) /* Check it. */
+ setne %al /* Boolean FP exception indicator for *pe. */
+ movl %eax, (%rdi)
+ addq $0x4, %rsp
+ ret
+ SET_SIZE(__div_set)
+
+/* double __dabs(double *d) - Get the abs. value of *d. Straightforward. */
+
+ ENTRY(__dabs)
+ subq $0x8, %rsp
+ movq (%rdi), %rax /* Zero the sign bit of the 64-bit double. */
+ btrq $63, %rax
+ movq %rax, (%rsp) /* Get it into %xmm0... */
+ movsd (%rsp), %xmm0 /* ....for an amd64 "double" return. */
+ addq $0x8, %rsp
+ ret
+ SET_SIZE(__dabs)
diff --git a/usr/src/lib/libc/amd64/fp/_base_il.c b/usr/src/lib/libc/amd64/fp/ieee.c
index da4e3ea506..8327d64611 100644
--- a/usr/src/lib/libc/amd64/fp/_base_il.c
+++ b/usr/src/lib/libc/amd64/fp/ieee.c
@@ -24,64 +24,12 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "lint.h"
#include "base_conversion.h"
#include <sys/isa_defs.h>
#define CSR_DEFAULT 0x1f80
-/* The following should be coded as inline expansion templates. */
-
-/*
- * Multiplies two normal or subnormal doubles, returns result and exceptions.
- */
-double
-__mul_set(double x, double y, int *pe) {
- extern void _putmxcsr(), _getmxcsr();
- int csr;
- double z;
-
- _putmxcsr(CSR_DEFAULT);
- z = x * y;
- _getmxcsr(&csr);
- if ((csr & 0x3f) == 0) {
- *pe = 0;
- } else {
- /* Result may not be exact. */
- *pe = 1;
- }
- return (z);
-}
-
-/*
- * Divides two normal or subnormal doubles x/y, returns result and exceptions.
- */
-double
-__div_set(double x, double y, int *pe) {
- extern void _putmxcsr(), _getmxcsr();
- int csr;
- double z;
-
- _putmxcsr(CSR_DEFAULT);
- z = x / y;
- _getmxcsr(&csr);
- if ((csr & 0x3f) == 0) {
- *pe = 0;
- } else {
- *pe = 1;
- }
- return (z);
-}
-
-double
-__dabs(double *d)
-{
- /* should use hardware fabs instruction */
- return ((*d < 0.0) ? -*d : *d);
-}
-
/*
* Returns IEEE mode/status and
* sets up standard environment for base conversion.
diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com
index e8b72336f3..01f71c334c 100644
--- a/usr/src/lib/libc/i386/Makefile.com
+++ b/usr/src/lib/libc/i386/Makefile.com
@@ -70,17 +70,18 @@ FPOBJS= \
_X_cplx_lr_div_ix.o \
_X_cplx_lr_div_rx.o \
_X_cplx_mul.o \
- _base_il.o \
fpgetmask.o \
fpgetround.o \
fpgetsticky.o \
fpsetmask.o \
fpsetround.o \
fpsetsticky.o \
- fpstart.o
+ fpstart.o \
+ ieee.o
FPASMOBJS= \
__xgetRD.o \
+ _base_il.o \
_xtoll.o \
_xtoull.o \
fpcw.o
diff --git a/usr/src/lib/libc/i386/fp/_base_il.s b/usr/src/lib/libc/i386/fp/_base_il.s
new file mode 100644
index 0000000000..157e977922
--- /dev/null
+++ b/usr/src/lib/libc/i386/fp/_base_il.s
@@ -0,0 +1,120 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
+ */
+
+ .file "_base_il.s"
+
+/*
+ * These files are in assembly because some compilers will mistakenly reorder
+ * multiplications or divisions wrapped in _putsw() and _getsw(). They are
+ * proper subroutines for now, but should be considered candidates for
+ * inlining eventually.
+ *
+ * The original C sources are included for readability in the pre-function
+ * comment blocks.
+ */
+
+#include <SYS.h>
+
+/*
+ * Multiplies two normal or subnormal doubles, returns result and exceptions.
+ *
+
+double
+__mul_set(double x, double y, int *pe) {
+ extern void _putsw(), _getsw();
+ int sw;
+ double z;
+
+ _putsw(0);
+ z = x * y;
+ _getsw(&sw);
+ if ((sw & 0x3f) == 0) {
+ *pe = 0;
+ } else {
+ *pe = 1;
+ }
+ return (z);
+}
+
+ */
+ ENTRY(__mul_set)
+ subl $0x8, %esp /* Give us an extra 8 bytes to play with. */
+ /* Clear the floating point exception register. */
+ fnclex /* Equivalent of _putsw(0); */
+
+ fldl 0xc(%esp) /* Load up x */
+ fmull 0x14(%esp) /* And multiply! */
+
+ /* Check to see if the multiply caused any exceptions. */
+ fstsw (%esp) /* Equivalent of... */
+ xorl %edx, %edx
+ andl $0x3f, (%esp) /* If the status word (low bits) are zero... */
+ setne %dl /* ... set *pe (aka. (%eax)) accordingly. */
+ movl 0x1c(%esp), %eax/* Get pe. */
+ movl %edx, (%eax) /* And set it. (True == FP exception). */
+ addl $0x8, %esp /* Release the 8 play bytes. */
+ ret
+ SET_SIZE(__mul_set)
+
+/*
+ * Divides two normal or subnormal doubles x/y, returns result and exceptions.
+ *
+
+double
+__div_set(double x, double y, int *pe) {
+ extern void _putsw(), _getsw();
+ int sw;
+ double z;
+
+ _putsw(0);
+ z = x / y;
+ _getsw(&sw);
+ if ((sw & 0x3f) == 0) {
+ *pe = 0;
+ } else {
+ *pe = 1;
+ }
+ return (z);
+}
+
+ */
+
+ ENTRY(__div_set)
+ subl $0x8, %esp /* Give us an extra 8 bytes to play with. */
+ /* Clear the floating point exception register. */
+ fnclex /* Equivalent of _putsw(0); */
+
+ fldl 0xc(%esp) /* Load up x */
+ fdivl 0x14(%esp) /* And divide! */
+
+ /* Check to see if the divide caused any exceptions. */
+ fstsw (%esp) /* Equivalent of... */
+ xorl %edx, %edx
+ andl $0x3f, (%esp) /* If the status word (low bits) are zero... */
+ setne %dl /* ... set *pe (aka. (%eax)) accordingly. */
+ movl 0x1c(%esp), %eax/* Get pe. */
+ movl %edx, (%eax) /* And set it. (True == FP exception). */
+ addl $0x8, %esp /* Release the 8 play bytes. */
+ ret
+ SET_SIZE(__div_set)
+
+/* double __dabs(double *d) - Get the abs. value of *d. Straightforward. */
+
+ ENTRY(__dabs)
+ movl 0x4(%esp), %eax
+ fldl (%eax)
+ fabs /* Just let the FPU do its thing. */
+ ret
+ SET_SIZE(__dabs)
diff --git a/usr/src/lib/libc/i386/fp/_base_il.c b/usr/src/lib/libc/i386/fp/ieee.c
index a821932d41..3e2f4c950c 100644
--- a/usr/src/lib/libc/i386/fp/_base_il.c
+++ b/usr/src/lib/libc/i386/fp/ieee.c
@@ -24,61 +24,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "lint.h"
#include "base_conversion.h"
-/* The following should be coded as inline expansion templates. */
-
-/*
- * Multiplies two normal or subnormal doubles, returns result and exceptions.
- */
-double
-__mul_set(double x, double y, int *pe) {
- extern void _putsw(), _getsw();
- int sw;
- double z;
-
- _putsw(0);
- z = x * y;
- _getsw(&sw);
- if ((sw & 0x3f) == 0) {
- *pe = 0;
- } else {
- /* Result may not be exact. */
- *pe = 1;
- }
- return (z);
-}
-
-/*
- * Divides two normal or subnormal doubles x/y, returns result and exceptions.
- */
-double
-__div_set(double x, double y, int *pe) {
- extern void _putsw(), _getsw();
- int sw;
- double z;
-
- _putsw(0);
- z = x / y;
- _getsw(&sw);
- if ((sw & 0x3f) == 0) {
- *pe = 0;
- } else {
- *pe = 1;
- }
- return (z);
-}
-
-double
-__dabs(double *d)
-{
- /* should use hardware fabs instruction */
- return ((*d < 0.0) ? -*d : *d);
-}
-
/*
* Returns IEEE mode/status and
* sets up standard environment for base conversion.