[haiku-commits] BRANCH xyzzy-github.x86_64 - headers/posix/arch/x86_64 src/system/libroot/posix/arch/x86_64 src/system/glue/arch/x86_64

  • From: xyzzy-github.x86_64 <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 27 Jul 2012 17:49:22 +0200 (CEST)

added 2 changesets to branch 'refs/remotes/xyzzy-github/x86_64'
old head: e3ac2588e64059e0c140504e9acc8e73b3c36fdc
new head: 3fde53501d6fd13daa168378d3f8ae8f3ca6bafd

----------------------------------------------------------------------------

5f119ed: Added x86_64 glue code.

3fde535: Updated x86_64 fenv.h and added fenv.c.

                                      [ Alex Smith <alex@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

8 files changed, 463 insertions(+), 7 deletions(-)
headers/posix/arch/x86_64/fenv.h             |   13 +-
headers/posix/arch/x86_64/fpu.h              |  218 ++++++++++++++++++++++
headers/posix/fenv.h                         |    2 +-
src/system/glue/arch/x86_64/Jamfile          |    7 +
src/system/glue/arch/x86_64/crti.S           |   43 +++++
src/system/glue/arch/x86_64/crtn.S           |   27 +++
src/system/libroot/posix/arch/x86_64/Jamfile |    2 +-
src/system/libroot/posix/arch/x86_64/fenv.c  |  158 ++++++++++++++++

############################################################################

Commit:      5f119ed78f400fbaec842d982fb7943a14d6b60e

Author:      Alex Smith <alex@xxxxxxxxxxxxxxxx>
Date:        Fri Jul 27 08:22:54 2012 UTC

Added x86_64 glue code.

----------------------------------------------------------------------------

diff --git a/src/system/glue/arch/x86_64/Jamfile 
b/src/system/glue/arch/x86_64/Jamfile
new file mode 100644
index 0000000..4d43342
--- /dev/null
+++ b/src/system/glue/arch/x86_64/Jamfile
@@ -0,0 +1,7 @@
+SubDir HAIKU_TOP src system glue arch x86_64 ;
+
+KernelObjects
+       crti.S
+       crtn.S
+       ;
+
diff --git a/src/system/glue/arch/x86_64/crti.S 
b/src/system/glue/arch/x86_64/crti.S
new file mode 100644
index 0000000..3ef8e5f
--- /dev/null
+++ b/src/system/glue/arch/x86_64/crti.S
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2005-2006, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2012, Alex Smith, alex@xxxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include <asm_defs.h>
+
+
+/**    This file contains the first part of the ".init" and ".fini" sections in
+ *     the ELF executable.
+ *     The functions defined here will be called during 
initialization/termination
+ *     of the loaded executable/library. The ".init" and ".fini" sections are
+ *     stacked together like this:
+ *
+ *     crti.S          entry point
+ *                             call to _init_before/_term_before
+ *     crtbegin.S      GCC specific: constructors/destructors are called, ...
+ *     crtend.S
+ *     crtn.S          call to _init_after/_term_after
+ *                             exit
+ */
+
+
+.section .init
+FUNCTION(_init):
+       push    %rbp
+       movq    %rsp, %rbp
+
+       // Preserve image ID for call to __haiku_init_after.
+       push    %rdi
+
+       call    __haiku_init_before
+       // crtbegin.o stuff comes here
+
+.section .fini
+FUNCTION(_fini):
+       push    %rbp
+       movq    %rsp, %rbp
+       push    %rdi
+       call    __haiku_term_before
+       // crtend.o stuff comes here
diff --git a/src/system/glue/arch/x86_64/crtn.S 
b/src/system/glue/arch/x86_64/crtn.S
new file mode 100644
index 0000000..8ed6433
--- /dev/null
+++ b/src/system/glue/arch/x86_64/crtn.S
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2005-2006, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2012, Alex Smith, alex@xxxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+/**    This file contains the final part of the ".init" and ".fini" sections in
+ *     the ELF executable. It is tightly connected to crti.S.
+ *     Have a look at crti.S to find a description of what happens here.
+ */
+
+
+.section .init
+       // The image ID is preserved on the stack.
+       pop             %rdi
+       call    __haiku_init_after
+       movq    %rbp, %rsp
+       pop             %rbp
+       ret
+
+.section .fini
+       pop             %rdi
+       call    __haiku_term_after
+       movq    %rbp, %rsp
+       pop             %rbp
+       ret

############################################################################

Commit:      3fde53501d6fd13daa168378d3f8ae8f3ca6bafd

Author:      Alex Smith <alex@xxxxxxxxxxxxxxxx>
Date:        Fri Jul 27 14:21:41 2012 UTC

Updated x86_64 fenv.h and added fenv.c.

----------------------------------------------------------------------------

diff --git a/headers/posix/arch/x86_64/fenv.h b/headers/posix/arch/x86_64/fenv.h
index a9992f9..9a3df8e 100644
--- a/headers/posix/arch/x86_64/fenv.h
+++ b/headers/posix/arch/x86_64/fenv.h
@@ -111,7 +111,8 @@ feclearexcept(int __excepts)
 static __inline int
 fegetexceptflag(fexcept_t *__flagp, int __excepts)
 {
-       int __mxcsr, __status;
+       uint32_t __mxcsr;
+       uint16_t __status;
 
        __stmxcsr(&__mxcsr);
        __fnstsw(&__status);
@@ -125,7 +126,8 @@ int feraiseexcept(int __excepts);
 static __inline int
 fetestexcept(int __excepts)
 {
-       int __mxcsr, __status;
+       uint32_t __mxcsr;
+       uint16_t __status;
 
        __stmxcsr(&__mxcsr);
        __fnstsw(&__status);
@@ -135,7 +137,7 @@ fetestexcept(int __excepts)
 static __inline int
 fegetround(void)
 {
-       int __control;
+       uint16_t __control;
 
        /*
         * We assume that the x87 and the SSE unit agree on the
@@ -150,7 +152,8 @@ fegetround(void)
 static __inline int
 fesetround(int __round)
 {
-       int __mxcsr, __control;
+       uint32_t __mxcsr;
+       uint16_t __control;
 
        if (__round & ~_ROUND_MASK)
                return (-1);
@@ -198,7 +201,7 @@ int fedisableexcept(int __mask);
 static __inline int
 fegetexcept(void)
 {
-       int __control;
+       uint16_t __control;
 
        /*
         * We assume that the masks for the x87 and the SSE unit are
diff --git a/headers/posix/arch/x86_64/fpu.h b/headers/posix/arch/x86_64/fpu.h
new file mode 100644
index 0000000..a22d8ca
--- /dev/null
+++ b/headers/posix/arch/x86_64/fpu.h
@@ -0,0 +1,218 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     from: @(#)npx.h 5.3 (Berkeley) 1/18/91
+ * $FreeBSD$
+ */
+
+/*
+ * Floating Point Data Structures and Constants
+ * W. Jolitz 1/90
+ */
+
+#ifndef _X86_FPU_H_
+#define        _X86_FPU_H_
+
+#define __aligned(x)    __attribute__((__aligned__(x)))
+
+/* Environment information of floating point unit. */
+struct env87 {
+       int32_t         en_cw;          /* control word (16bits) */
+       int32_t         en_sw;          /* status word (16bits) */
+       int32_t         en_tw;          /* tag word (16bits) */
+       int32_t         en_fip;         /* fp instruction pointer */
+       uint16_t        en_fcs;         /* fp code segment selector */
+       uint16_t        en_opcode;      /* opcode last executed (11 bits) */
+       int32_t         en_foo;         /* fp operand offset */
+       int32_t         en_fos;         /* fp operand segment selector */
+};
+
+/* Contents of each x87 floating point accumulator. */
+struct fpacc87 {
+       uint8_t         fp_bytes[10];
+};
+
+/* Floating point context. (i386 fnsave/frstor) */
+struct save87 {
+       struct env87    sv_env;         /* floating point control/status */
+       struct fpacc87  sv_ac[8];       /* accumulator contents, 0-7 */
+       uint8_t         sv_pad0[4];     /* saved status word (now unused) */
+       /*
+        * Bogus padding for emulators.  Emulators should use their own
+        * struct and arrange to store into this struct (ending here)
+        * before it is inspected for ptracing or for core dumps.  Some
+        * emulators overwrite the whole struct.  We have no good way of
+        * knowing how much padding to leave.  Leave just enough for the
+        * GPL emulator's i387_union (176 bytes total).
+        */
+       uint8_t         sv_pad[64];     /* padding; used by emulators */
+};
+
+/* Contents of each SSE extended accumulator. */
+struct xmmacc {
+       uint8_t         xmm_bytes[16];
+};
+
+/* Contents of the upper 16 bytes of each AVX extended accumulator. */
+struct ymmacc {
+       uint8_t         ymm_bytes[16];
+};
+
+/* Rename structs below depending on machine architecture. */
+#ifdef __i386__
+#define        __envxmm32      envxmm
+#else
+#define        __envxmm32      envxmm32
+#define        __envxmm64      envxmm
+#endif
+
+struct __envxmm32 {
+       uint16_t        en_cw;          /* control word (16bits) */
+       uint16_t        en_sw;          /* status word (16bits) */
+       uint16_t        en_tw;          /* tag word (16bits) */
+       uint16_t        en_opcode;      /* opcode last executed (11 bits) */
+       uint32_t        en_fip;         /* fp instruction pointer */
+       uint16_t        en_fcs;         /* fp code segment selector */
+       uint16_t        en_pad0;        /* padding */
+       uint32_t        en_foo;         /* fp operand offset */
+       uint16_t        en_fos;         /* fp operand segment selector */
+       uint16_t        en_pad1;        /* padding */
+       uint32_t        en_mxcsr;       /* SSE control/status register */
+       uint32_t        en_mxcsr_mask;  /* valid bits in mxcsr */
+};
+
+struct __envxmm64 {
+       uint16_t        en_cw;          /* control word (16bits) */
+       uint16_t        en_sw;          /* status word (16bits) */
+       uint8_t         en_tw;          /* tag word (8bits) */
+       uint8_t         en_zero;
+       uint16_t        en_opcode;      /* opcode last executed (11 bits ) */
+       uint64_t        en_rip;         /* fp instruction pointer */
+       uint64_t        en_rdp;         /* fp operand pointer */
+       uint32_t        en_mxcsr;       /* SSE control/status register */
+       uint32_t        en_mxcsr_mask;  /* valid bits in mxcsr */
+};
+
+/* Floating point context. (i386 fxsave/fxrstor) */
+struct savexmm {
+       struct __envxmm32       sv_env;
+       struct {
+               struct fpacc87  fp_acc;
+               uint8_t         fp_pad[6];      /* padding */
+       } sv_fp[8];
+       struct xmmacc           sv_xmm[8];
+       uint8_t                 sv_pad[224];
+} __aligned(16);
+
+#ifdef __i386__
+union savefpu {
+       struct save87   sv_87;
+       struct savexmm  sv_xmm;
+};
+#else
+/* Floating point context. (amd64 fxsave/fxrstor) */
+struct savefpu {
+       struct __envxmm64       sv_env;
+       struct {
+               struct fpacc87  fp_acc;
+               uint8_t         fp_pad[6];      /* padding */
+       } sv_fp[8];
+       struct xmmacc           sv_xmm[16];
+       uint8_t                 sv_pad[96];
+} __aligned(16);
+#endif
+
+struct xstate_hdr {
+       uint64_t        xstate_bv;
+       uint8_t         xstate_rsrv0[16];
+       uint8_t         xstate_rsrv[40];
+};
+
+struct savexmm_xstate {
+       struct xstate_hdr       sx_hd;
+       struct ymmacc           sx_ymm[16];
+};
+
+struct savexmm_ymm {
+       struct __envxmm32       sv_env;
+       struct {
+               struct fpacc87  fp_acc;
+               int8_t          fp_pad[6];      /* padding */
+       } sv_fp[8];
+       struct xmmacc           sv_xmm[16];
+       uint8_t                 sv_pad[96];
+       struct savexmm_xstate   sv_xstate;
+} __aligned(64);
+
+struct savefpu_xstate {
+       struct xstate_hdr       sx_hd;
+       struct ymmacc           sx_ymm[16];
+};
+
+struct savefpu_ymm {
+       struct __envxmm64       sv_env;
+       struct {
+               struct fpacc87  fp_acc;
+               int8_t          fp_pad[6];      /* padding */
+       } sv_fp[8];
+       struct xmmacc           sv_xmm[16];
+       uint8_t                 sv_pad[96];
+       struct savefpu_xstate   sv_xstate;
+} __aligned(64);
+
+#undef __envxmm32
+#undef __envxmm64
+
+/*
+ * The hardware default control word for i387's and later coprocessors is
+ * 0x37F, giving:
+ *
+ *     round to nearest
+ *     64-bit precision
+ *     all exceptions masked.
+ *
+ * FreeBSD/i386 uses 53 bit precision for things like fadd/fsub/fsqrt etc
+ * because of the difference between memory and fpu register stack arguments.
+ * If its using an intermediate fpu register, it has 80/64 bits to work
+ * with.  If it uses memory, it has 64/53 bits to work with.  However,
+ * gcc is aware of this and goes to a fair bit of trouble to make the
+ * best use of it.
+ *
+ * This is mostly academic for AMD64, because the ABI prefers the use
+ * SSE2 based math.  For FreeBSD/amd64, we go with the default settings.
+ */
+#define        __INITIAL_FPUCW__       0x037F
+#define        __INITIAL_FPUCW_I386__  0x127F
+#define        __INITIAL_NPXCW__       __INITIAL_FPUCW_I386__
+#define        __INITIAL_MXCSR__       0x1F80
+#define        __INITIAL_MXCSR_MASK__  0xFFBF
+
+#endif /* !_X86_FPU_H_ */
diff --git a/headers/posix/fenv.h b/headers/posix/fenv.h
index 0fb1e20..31fdd0b 100644
--- a/headers/posix/fenv.h
+++ b/headers/posix/fenv.h
@@ -3,7 +3,7 @@
 
 #if defined(__INTEL__)
 #  include <arch/x86/fenv.h>
-#elif defined(_x86_64_)
+#elif defined(__x86_64__)
 #  include <arch/x86_64/fenv.h>
 #elif defined(__ARM__)
 #  include <arch/arm/fenv.h>
diff --git a/src/system/libroot/posix/arch/x86_64/Jamfile 
b/src/system/libroot/posix/arch/x86_64/Jamfile
index cbbe851..5891f1b 100644
--- a/src/system/libroot/posix/arch/x86_64/Jamfile
+++ b/src/system/libroot/posix/arch/x86_64/Jamfile
@@ -8,7 +8,7 @@ local genericSources =
 ;
 
 MergeObject posix_arch_$(TARGET_ARCH).o :
-       #fenv.c
+       fenv.c
        sigsetjmp.S
        siglongjmp.S
 
diff --git a/src/system/libroot/posix/arch/x86_64/fenv.c 
b/src/system/libroot/posix/arch/x86_64/fenv.c
new file mode 100644
index 0000000..861f621
--- /dev/null
+++ b/src/system/libroot/posix/arch/x86_64/fenv.c
@@ -0,0 +1,158 @@
+/*-
+ * Copyright (c) 2004-2005 David Schultz <das@xxxxxxxxxxx>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <posix/fenv.h>
+#include <arch/x86_64/fpu.h>
+
+const fenv_t __fe_dfl_env = {
+       { 0xffff0000 | __INITIAL_FPUCW__,
+         0xffff0000,
+         0xffffffff,
+         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }
+       },
+       __INITIAL_MXCSR__
+};
+
+extern inline int feclearexcept(int __excepts);
+extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts);
+
+int
+fesetexceptflag(const fexcept_t *flagp, int excepts)
+{
+       fenv_t env;
+
+       __fnstenv(&env.__x87);
+       env.__x87.__status &= ~excepts;
+       env.__x87.__status |= *flagp & excepts;
+       __fldenv(env.__x87);
+
+       __stmxcsr(&env.__mxcsr);
+       env.__mxcsr &= ~excepts;
+       env.__mxcsr |= *flagp & excepts;
+       __ldmxcsr(env.__mxcsr);
+
+       return (0);
+}
+
+int
+feraiseexcept(int excepts)
+{
+       fexcept_t ex = excepts;
+
+       fesetexceptflag(&ex, excepts);
+       __fwait();
+       return (0);
+}
+
+extern inline int fetestexcept(int __excepts);
+extern inline int fegetround(void);
+extern inline int fesetround(int __round);
+
+int
+fegetenv(fenv_t *envp)
+{
+
+       __fnstenv(&envp->__x87);
+       __stmxcsr(&envp->__mxcsr);
+       /*
+        * fnstenv masks all exceptions, so we need to restore the
+        * control word to avoid this side effect.
+        */
+       __fldcw(envp->__x87.__control);
+       return (0);
+}
+
+int
+feholdexcept(fenv_t *envp)
+{
+       uint32_t mxcsr;
+
+       __stmxcsr(&mxcsr);
+       __fnstenv(&envp->__x87);
+       __fnclex();
+       envp->__mxcsr = mxcsr;
+       mxcsr &= ~FE_ALL_EXCEPT;
+       mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT;
+       __ldmxcsr(mxcsr);
+       return (0);
+}
+
+extern inline int fesetenv(const fenv_t *__envp);
+
+int
+feupdateenv(const fenv_t *envp)
+{
+       uint32_t mxcsr;
+       uint16_t status;
+
+       __fnstsw(&status);
+       __stmxcsr(&mxcsr);
+       fesetenv(envp);
+       feraiseexcept((mxcsr | status) & FE_ALL_EXCEPT);
+       return (0);
+}
+
+int
+__feenableexcept(int mask)
+{
+       uint32_t mxcsr, omask;
+       uint16_t control;
+
+       mask &= FE_ALL_EXCEPT;
+       __fnstcw(&control);
+       __stmxcsr(&mxcsr);
+       omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
+       control &= ~mask;
+       __fldcw(control);
+       mxcsr &= ~(mask << _SSE_EMASK_SHIFT);
+       __ldmxcsr(mxcsr);
+       return (omask);
+}
+
+int
+__fedisableexcept(int mask)
+{
+       uint32_t mxcsr, omask;
+       uint16_t control;
+
+       mask &= FE_ALL_EXCEPT;
+       __fnstcw(&control);
+       __stmxcsr(&mxcsr);
+       omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
+       control |= mask;
+       __fldcw(control);
+       mxcsr |= mask << _SSE_EMASK_SHIFT;
+       __ldmxcsr(mxcsr);
+       return (omask);
+}
+
+__weak_reference(__feenableexcept, feenableexcept);
+__weak_reference(__fedisableexcept, fedisableexcept);


Other related posts:

  • » [haiku-commits] BRANCH xyzzy-github.x86_64 - headers/posix/arch/x86_64 src/system/libroot/posix/arch/x86_64 src/system/glue/arch/x86_64 - xyzzy-github . x86_64