diff options
Diffstat (limited to 'lib/libc/amd64/gen')
-rw-r--r-- | lib/libc/amd64/gen/Makefile.inc | 8 | ||||
-rw-r--r-- | lib/libc/amd64/gen/_set_tp.c | 38 | ||||
-rw-r--r-- | lib/libc/amd64/gen/_setjmp.S | 83 | ||||
-rw-r--r-- | lib/libc/amd64/gen/fabs.S | 43 | ||||
-rw-r--r-- | lib/libc/amd64/gen/flt_rounds.c | 26 | ||||
-rw-r--r-- | lib/libc/amd64/gen/fpgetmask.c | 8 | ||||
-rw-r--r-- | lib/libc/amd64/gen/fpgetprec.c | 8 | ||||
-rw-r--r-- | lib/libc/amd64/gen/fpgetround.c | 8 | ||||
-rw-r--r-- | lib/libc/amd64/gen/fpgetsticky.c | 8 | ||||
-rw-r--r-- | lib/libc/amd64/gen/fpsetmask.c | 8 | ||||
-rw-r--r-- | lib/libc/amd64/gen/fpsetprec.c | 8 | ||||
-rw-r--r-- | lib/libc/amd64/gen/fpsetround.c | 8 | ||||
-rw-r--r-- | lib/libc/amd64/gen/infinity.c | 14 | ||||
-rw-r--r-- | lib/libc/amd64/gen/ldexp.c | 62 | ||||
-rw-r--r-- | lib/libc/amd64/gen/makecontext.c | 107 | ||||
-rw-r--r-- | lib/libc/amd64/gen/modf.S | 88 | ||||
-rw-r--r-- | lib/libc/amd64/gen/rfork_thread.S | 101 | ||||
-rw-r--r-- | lib/libc/amd64/gen/setjmp.S | 101 | ||||
-rw-r--r-- | lib/libc/amd64/gen/signalcontext.c | 106 | ||||
-rw-r--r-- | lib/libc/amd64/gen/sigsetjmp.S | 111 |
20 files changed, 944 insertions, 0 deletions
diff --git a/lib/libc/amd64/gen/Makefile.inc b/lib/libc/amd64/gen/Makefile.inc new file mode 100644 index 0000000..38fe7e1 --- /dev/null +++ b/lib/libc/amd64/gen/Makefile.inc @@ -0,0 +1,8 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD$ + +SRCS+= _setjmp.S _set_tp.c rfork_thread.S setjmp.S sigsetjmp.S \ + fabs.S modf.S \ + infinity.c ldexp.c makecontext.c signalcontext.c \ + flt_rounds.c fpgetmask.c fpsetmask.c fpgetprec.c fpsetprec.c \ + fpgetround.c fpsetround.c fpgetsticky.c diff --git a/lib/libc/amd64/gen/_set_tp.c b/lib/libc/amd64/gen/_set_tp.c new file mode 100644 index 0000000..02e5e14 --- /dev/null +++ b/lib/libc/amd64/gen/_set_tp.c @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * 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 <string.h> +#include <stdint.h> +#include <machine/sysarch.h> + +void +_set_tp(void *tp) +{ + + amd64_set_fsbase(tp); +} diff --git a/lib/libc/amd64/gen/_setjmp.S b/lib/libc/amd64/gen/_setjmp.S new file mode 100644 index 0000000..3998fbe --- /dev/null +++ b/lib/libc/amd64/gen/_setjmp.S @@ -0,0 +1,83 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) + .asciz "@(#)_setjmp.s 5.1 (Berkeley) 4/23/90" +#endif /* LIBC_SCCS and not lint */ +#include <machine/asm.h> +__FBSDID("$FreeBSD$"); + +/* + * C library -- _setjmp, _longjmp + * + * _longjmp(a,v) + * will generate a "return(v)" from the last call to + * _setjmp(a) + * by restoring registers from the environment 'a'. + * The previous signal state is NOT restored. + */ + +ENTRY(_setjmp) + movq %rdi,%rax + movq 0(%rsp),%rdx /* retval */ + movq %rdx, 0(%rax) /* 0; retval */ + movq %rbx, 8(%rax) /* 1; rbx */ + movq %rsp,16(%rax) /* 2; rsp */ + movq %rbp,24(%rax) /* 3; rbp */ + movq %r12,32(%rax) /* 4; r12 */ + movq %r13,40(%rax) /* 5; r13 */ + movq %r14,48(%rax) /* 6; r14 */ + movq %r15,56(%rax) /* 7; r15 */ + fnstcw 64(%rax) /* 8; fpu cw */ + xorq %rax,%rax + ret + + .weak CNAME(_longjmp) + .set CNAME(_longjmp),CNAME(___longjmp) +ENTRY(___longjmp) + movq %rdi,%rdx + movq %rsi,%rax /* retval */ + movq 0(%rdx),%rcx + movq 8(%rdx),%rbx + movq 16(%rdx),%rsp + movq 24(%rdx),%rbp + movq 32(%rdx),%r12 + movq 40(%rdx),%r13 + movq 48(%rdx),%r14 + movq 56(%rdx),%r15 + fninit + fldcw 64(%rdx) + testq %rax,%rax + jnz 1f + incq %rax +1: movq %rcx,0(%rsp) + ret diff --git a/lib/libc/amd64/gen/fabs.S b/lib/libc/amd64/gen/fabs.S new file mode 100644 index 0000000..59cd910 --- /dev/null +++ b/lib/libc/amd64/gen/fabs.S @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2004 Peter Wemm + * 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. + */ + +#include <machine/asm.h> +__FBSDID("$FreeBSD$"); + +/* + * Return floating point absolute value of a double. + */ + + .text +ENTRY(fabs) + movsd %xmm0, %xmm1 + movsd signbit(%rip), %xmm0 + andnpd %xmm1, %xmm0 + ret + + .data +signbit: + .quad 0x8000000000000000 diff --git a/lib/libc/amd64/gen/flt_rounds.c b/lib/libc/amd64/gen/flt_rounds.c new file mode 100644 index 0000000..c0ce81f --- /dev/null +++ b/lib/libc/amd64/gen/flt_rounds.c @@ -0,0 +1,26 @@ +/* + * Written by J.T. Conklin, Apr 10, 1995 + * Public domain. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <float.h> + +static const int map[] = { + 1, /* round to nearest */ + 3, /* round to zero */ + 2, /* round to negative infinity */ + 0 /* round to positive infinity */ +}; + +int +__flt_rounds(void) +{ + int x; + + /* Assume that the x87 and the SSE unit agree on the rounding mode. */ + __asm("fnstcw %0" : "=m" (x)); + return (map[(x >> 10) & 0x03]); +} diff --git a/lib/libc/amd64/gen/fpgetmask.c b/lib/libc/amd64/gen/fpgetmask.c new file mode 100644 index 0000000..03bb274 --- /dev/null +++ b/lib/libc/amd64/gen/fpgetmask.c @@ -0,0 +1,8 @@ +/* $FreeBSD$ */ +#define __IEEEFP_NOINLINES__ 1 +#include <ieeefp.h> + +fp_except_t fpgetmask(void) +{ + return __fpgetmask(); +} diff --git a/lib/libc/amd64/gen/fpgetprec.c b/lib/libc/amd64/gen/fpgetprec.c new file mode 100644 index 0000000..22d2148 --- /dev/null +++ b/lib/libc/amd64/gen/fpgetprec.c @@ -0,0 +1,8 @@ +/* $FreeBSD$ */ +#define __IEEEFP_NOINLINES__ 1 +#include <ieeefp.h> + +fp_prec_t fpgetprec(void) +{ + return __fpgetprec(); +} diff --git a/lib/libc/amd64/gen/fpgetround.c b/lib/libc/amd64/gen/fpgetround.c new file mode 100644 index 0000000..9c066b1 --- /dev/null +++ b/lib/libc/amd64/gen/fpgetround.c @@ -0,0 +1,8 @@ +/* $FreeBSD$ */ +#define __IEEEFP_NOINLINES__ 1 +#include <ieeefp.h> + +fp_rnd_t fpgetround(void) +{ + return __fpgetround(); +} diff --git a/lib/libc/amd64/gen/fpgetsticky.c b/lib/libc/amd64/gen/fpgetsticky.c new file mode 100644 index 0000000..c3acb91 --- /dev/null +++ b/lib/libc/amd64/gen/fpgetsticky.c @@ -0,0 +1,8 @@ +/* $FreeBSD$ */ +#define __IEEEFP_NOINLINES__ 1 +#include <ieeefp.h> + +fp_except_t fpgetsticky(void) +{ + return __fpgetsticky(); +} diff --git a/lib/libc/amd64/gen/fpsetmask.c b/lib/libc/amd64/gen/fpsetmask.c new file mode 100644 index 0000000..996e167 --- /dev/null +++ b/lib/libc/amd64/gen/fpsetmask.c @@ -0,0 +1,8 @@ +/* $FreeBSD$ */ +#define __IEEEFP_NOINLINES__ 1 +#include <ieeefp.h> + +fp_except_t fpsetmask(fp_except_t m) +{ + return (__fpsetmask(m)); +} diff --git a/lib/libc/amd64/gen/fpsetprec.c b/lib/libc/amd64/gen/fpsetprec.c new file mode 100644 index 0000000..5898de7 --- /dev/null +++ b/lib/libc/amd64/gen/fpsetprec.c @@ -0,0 +1,8 @@ +/* $FreeBSD$ */ +#define __IEEEFP_NOINLINES__ 1 +#include <ieeefp.h> + +fp_prec_t fpsetprec(fp_prec_t m) +{ + return (__fpsetprec(m)); +} diff --git a/lib/libc/amd64/gen/fpsetround.c b/lib/libc/amd64/gen/fpsetround.c new file mode 100644 index 0000000..6f13367 --- /dev/null +++ b/lib/libc/amd64/gen/fpsetround.c @@ -0,0 +1,8 @@ +/* $FreeBSD$ */ +#define __IEEEFP_NOINLINES__ 1 +#include <ieeefp.h> + +fp_rnd_t fpsetround(fp_rnd_t m) +{ + return (__fpsetround(m)); +} diff --git a/lib/libc/amd64/gen/infinity.c b/lib/libc/amd64/gen/infinity.c new file mode 100644 index 0000000..464b402 --- /dev/null +++ b/lib/libc/amd64/gen/infinity.c @@ -0,0 +1,14 @@ +/* + * infinity.c + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <math.h> + +/* bytes for +Infinity on a 387 */ +const union __infinity_un __infinity = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }; + +/* bytes for NaN */ +const union __nan_un __nan = { { 0, 0, 0xc0, 0xff } }; diff --git a/lib/libc/amd64/gen/ldexp.c b/lib/libc/amd64/gen/ldexp.c new file mode 100644 index 0000000..43107fc --- /dev/null +++ b/lib/libc/amd64/gen/ldexp.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Sean Eric Fagan. + * + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)ldexp.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * ldexp(value, exp): return value * (2 ** exp). + * + * Written by Sean Eric Fagan (sef@kithrup.COM) + * Sun Mar 11 20:27:09 PST 1990 + */ + +/* + * We do the conversion in C to let gcc optimize it away, if possible. + */ +double +ldexp (double value, int exp) +{ + double temp, texp, temp2; + texp = exp; +#ifdef __GNUC__ + __asm ("fscale " + : "=u" (temp2), "=t" (temp) + : "0" (texp), "1" (value)); +#else +#error unknown asm +#endif + return (temp); +} diff --git a/lib/libc/amd64/gen/makecontext.c b/lib/libc/amd64/gen/makecontext.c new file mode 100644 index 0000000..15f10b5 --- /dev/null +++ b/lib/libc/amd64/gen/makecontext.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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 ``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 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/ucontext.h> +#include <stdarg.h> +#include <stdlib.h> + +typedef void (*func_t)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t); + +/* Prototypes */ +static void makectx_wrapper(ucontext_t *ucp, func_t func, uint64_t *args); + +__weak_reference(__makecontext, makecontext); + +void +__makecontext(ucontext_t *ucp, void (*start)(void), int argc, ...) +{ + uint64_t *args; + uint64_t *sp; + va_list ap; + int i; + + /* A valid context is required. */ + if ((ucp == NULL) || (ucp->uc_mcontext.mc_len != sizeof(mcontext_t))) + return; + else if ((argc < 0) || (argc > 6) || (ucp->uc_stack.ss_sp == NULL) || + (ucp->uc_stack.ss_size < MINSIGSTKSZ)) { + /* + * This should really return -1 with errno set to ENOMEM + * or something, but the spec says that makecontext is + * a void function. At least make sure that the context + * isn't valid so it can't be used without an error. + */ + ucp->uc_mcontext.mc_len = 0; + return; + } + + /* Align the stack to 16 bytes. */ + sp = (uint64_t *)(ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + sp = (uint64_t *)((uint64_t)sp & ~15UL); + + /* Allocate space for a maximum of 6 arguments on the stack. */ + args = sp - 6; + + /* + * Account for arguments on stack and do the funky C entry alignment. + * This means that we need an 8-byte-odd alignment since the ABI expects + * the return address to be pushed, thus breaking the 16 byte alignment. + */ + sp -= 7; + + /* Add the arguments: */ + va_start(ap, argc); + for (i = 0; i < argc; i++) + args[i] = va_arg(ap, uint64_t); + va_end(ap); + for (i = argc; i < 6; i++) + args[i] = 0; + + ucp->uc_mcontext.mc_rdi = (register_t)ucp; + ucp->uc_mcontext.mc_rsi = (register_t)start; + ucp->uc_mcontext.mc_rdx = (register_t)args; + ucp->uc_mcontext.mc_rbp = 0; + ucp->uc_mcontext.mc_rbx = (register_t)sp; + ucp->uc_mcontext.mc_rsp = (register_t)sp; + ucp->uc_mcontext.mc_rip = (register_t)makectx_wrapper; +} + +static void +makectx_wrapper(ucontext_t *ucp, func_t func, uint64_t *args) +{ + (*func)(args[0], args[1], args[2], args[3], args[4], args[5]); + if (ucp->uc_link == NULL) + exit(0); + setcontext((const ucontext_t *)ucp->uc_link); + /* should never get here */ + abort(); + /* NOTREACHED */ +} diff --git a/lib/libc/amd64/gen/modf.S b/lib/libc/amd64/gen/modf.S new file mode 100644 index 0000000..63eec8c --- /dev/null +++ b/lib/libc/amd64/gen/modf.S @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Sean Eric Fagan. + * + * 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: @(#)modf.s 5.5 (Berkeley) 3/18/91 + */ + +#include <machine/asm.h> +#if defined(LIBC_SCCS) + RCSID("$NetBSD: modf.S,v 1.5 1997/07/16 14:37:18 christos Exp $") +#endif +__FBSDID("$FreeBSD$"); + +/* + * modf(value, iptr): return fractional part of value, and stores the + * integral part into iptr (a pointer to double). + * + * Written by Sean Eric Fagan (sef@kithrup.COM) + * Sun Mar 11 20:27:30 PST 1990 + */ + +/* With CHOP mode on, frndint behaves as TRUNC does. Useful. */ +ENTRY(modf) + + /* + * Set chop mode. + */ + fnstcw -12(%rsp) + movw -12(%rsp),%dx + orw $3072,%dx + movw %dx,-16(%rsp) + fldcw -16(%rsp) + + /* + * Get integral part. + */ + movsd %xmm0,-24(%rsp) + fldl -24(%rsp) + frndint + fstpl -8(%rsp) + + /* + * Restore control word. + */ + fldcw -12(%rsp) + + /* + * Store integral part. + */ + movsd -8(%rsp),%xmm0 + movsd %xmm0,(%rdi) + + /* + * Get fractional part and return it. + */ + fldl -24(%rsp) + fsubl -8(%rsp) + fstpl -8(%rsp) + movsd -8(%rsp),%xmm0 + + ret diff --git a/lib/libc/amd64/gen/rfork_thread.S b/lib/libc/amd64/gen/rfork_thread.S new file mode 100644 index 0000000..aa7001c --- /dev/null +++ b/lib/libc/amd64/gen/rfork_thread.S @@ -0,0 +1,101 @@ +/*- + * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> + * Copyright (c) 2003 Alan L. Cox <alc@cs.rice.edu> + * 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. + */ + +#include <machine/asm.h> +__FBSDID("$FreeBSD$"); + +/* + * With thanks to John Dyson for the original version of this. + */ + +#include <SYS.h> + +/* + * %edi %rsi %rdx %rcx + * rfork_thread(flags, stack_addr, start_fnc, start_arg); + * + * flags: Flags to rfork system call. See rfork(2). + * stack_addr: Top of stack for thread. + * start_fnc: Address of thread function to call in child. + * start_arg: Argument to pass to the thread function in child. + */ + +ENTRY(rfork_thread) + pushq %rbx + pushq %r12 + movq %rdx, %rbx + movq %rcx, %r12 + + /* + * Prepare and execute the thread creation syscall + */ + movq $SYS_rfork, %rax + KERNCALL + jb 2f + + /* + * Check to see if we are in the parent or child + */ + cmpl $0, %edx + jnz 1f + popq %r12 + popq %rbx + ret + + /* + * If we are in the child (new thread), then + * set-up the call to the internal subroutine. If it + * returns, then call __exit. + */ +1: + movq %rsi, %rsp + movq %r12, %rdi + call *%rbx + movl %eax, %edi + + /* + * Exit system call + */ +#ifdef SYS_exit + movq $SYS_exit, %rax +#else + movq $SYS_sys_exit, %rax +#endif + KERNCALL + + /* + * Branch here if the thread creation fails: + */ +2: + popq %r12 + popq %rbx +#ifdef PIC + movq PIC_GOT(HIDENAME(cerror)), %rdx + jmp *%rdx +#else + jmp HIDENAME(cerror) +#endif diff --git a/lib/libc/amd64/gen/setjmp.S b/lib/libc/amd64/gen/setjmp.S new file mode 100644 index 0000000..7d11384 --- /dev/null +++ b/lib/libc/amd64/gen/setjmp.S @@ -0,0 +1,101 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) + .asciz "@(#)setjmp.s 5.1 (Berkeley) 4/23/90" +#endif /* LIBC_SCCS and not lint */ +#include <machine/asm.h> +__FBSDID("$FreeBSD$"); + +/* + * C library -- _setjmp, _longjmp + * + * longjmp(a,v) + * will generate a "return(v)" from the last call to + * setjmp(a) + * by restoring registers from the environment 'a'. + * The previous signal state is restored. + */ + +#include "SYS.h" + +ENTRY(setjmp) + pushq %rdi + movq %rdi,%rcx + movq $1,%rdi /* SIG_BLOCK */ + movq $0,%rsi /* (sigset_t*)set */ + leaq 72(%rcx),%rdx /* 9,10; (sigset_t*)oset */ + call PIC_PLT(CNAME(_sigprocmask)) + popq %rdi + movq %rdi,%rcx + movq 0(%rsp),%rdx /* retval */ + movq %rdx, 0(%rcx) /* 0; retval */ + movq %rbx, 8(%rcx) /* 1; rbx */ + movq %rsp,16(%rcx) /* 2; rsp */ + movq %rbp,24(%rcx) /* 3; rbp */ + movq %r12,32(%rcx) /* 4; r12 */ + movq %r13,40(%rcx) /* 5; r13 */ + movq %r14,48(%rcx) /* 6; r14 */ + movq %r15,56(%rcx) /* 7; r15 */ + fnstcw 64(%rcx) /* 8; fpu cw */ + xorq %rax,%rax + ret + + .weak CNAME(longjmp) + .set CNAME(longjmp),CNAME(__longjmp) +ENTRY(__longjmp) + pushq %rdi + pushq %rsi + movq %rdi,%rdx + movq $3,%rdi /* SIG_SETMASK */ + leaq 72(%rdx),%rsi /* (sigset_t*)set */ + movq $0,%rdx /* (sigset_t*)oset */ + call PIC_PLT(CNAME(_sigprocmask)) + popq %rsi + popq %rdi /* jmpbuf */ + movq %rdi,%rdx + movq %rsi,%rax /* retval */ + movq 0(%rdx),%rcx + movq 8(%rdx),%rbx + movq 16(%rdx),%rsp + movq 24(%rdx),%rbp + movq 32(%rdx),%r12 + movq 40(%rdx),%r13 + movq 48(%rdx),%r14 + movq 56(%rdx),%r15 + fninit + fldcw 64(%rdx) + testq %rax,%rax + jnz 1f + incq %rax +1: movq %rcx,0(%rsp) + ret diff --git a/lib/libc/amd64/gen/signalcontext.c b/lib/libc/amd64/gen/signalcontext.c new file mode 100644 index 0000000..1a2621a --- /dev/null +++ b/lib/libc/amd64/gen/signalcontext.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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 ``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 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/ucontext.h> +#include <signal.h> +#include <stdlib.h> +#include <strings.h> + +typedef void (*handler_t)(uint64_t, uint64_t, uint64_t); + +/* Prototypes */ +static void sigctx_wrapper(ucontext_t *ucp, handler_t func, uint64_t *args); + +__weak_reference(__signalcontext, signalcontext); + +int +__signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func) +{ + uint64_t *args; + siginfo_t *sig_si; + ucontext_t *sig_uc; + uint64_t sp; + + /* Bail out if we don't have a valid ucontext pointer. */ + if (ucp == NULL) + abort(); + + /* + * Build a signal frame and copy the arguments of signal handler + * 'func' onto the stack and do the funky stack alignment. + * This means that we need an 8-byte-odd alignment since the ABI expects + * the return address to be pushed, thus breaking the 16 byte alignment. + */ + sp = (ucp->uc_mcontext.mc_rsp - 128 - sizeof(ucontext_t)) & ~15UL; + sig_uc = (ucontext_t *)sp; + bcopy(ucp, sig_uc, sizeof(*sig_uc)); + sp = (sp - sizeof(siginfo_t)) & ~15UL; + sig_si = (siginfo_t *)sp; + bzero(sig_si, sizeof(*sig_si)); + sig_si->si_signo = sig; + sp -= 3 * sizeof(uint64_t); + args = (uint64_t *)sp; + args[0] = sig; + args[1] = (intptr_t)sig_si; + args[2] = (intptr_t)sig_uc; + sp -= 16; + + /* + * Setup the ucontext of the signal handler. + */ + bzero(&ucp->uc_mcontext, sizeof(ucp->uc_mcontext)); + ucp->uc_mcontext.mc_fpformat = _MC_FPFMT_NODEV; + ucp->uc_mcontext.mc_ownedfp = _MC_FPOWNED_NONE; + ucp->uc_link = sig_uc; + sigdelset(&ucp->uc_sigmask, sig); + + ucp->uc_mcontext.mc_len = sizeof(mcontext_t); + ucp->uc_mcontext.mc_rdi = (register_t)ucp; + ucp->uc_mcontext.mc_rsi = (register_t)func; + ucp->uc_mcontext.mc_rdx = (register_t)args; + ucp->uc_mcontext.mc_rbp = (register_t)sp; + ucp->uc_mcontext.mc_rbx = (register_t)sp; + ucp->uc_mcontext.mc_rsp = (register_t)sp; + ucp->uc_mcontext.mc_rip = (register_t)sigctx_wrapper; + return (0); +} + +static void +sigctx_wrapper(ucontext_t *ucp, handler_t func, uint64_t *args) +{ + + (*func)(args[0], args[1], args[2]); + if (ucp->uc_link == NULL) + exit(0); + setcontext((const ucontext_t *)ucp->uc_link); + /* should never get here */ + abort(); + /* NOTREACHED */ +} diff --git a/lib/libc/amd64/gen/sigsetjmp.S b/lib/libc/amd64/gen/sigsetjmp.S new file mode 100644 index 0000000..718edf9 --- /dev/null +++ b/lib/libc/amd64/gen/sigsetjmp.S @@ -0,0 +1,111 @@ +/*- + * 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. + * + * @(#)setjmp.s 5.1 (Berkeley) 4/23/90" + */ + +#if defined(LIBC_SCCS) && !defined(lint) + .text + .asciz "$Id: sigsetjmp.S,v 1.1 1993/12/05 13:01:05 ats Exp $" +#endif /* LIBC_SCCS and not lint */ +#include <machine/asm.h> +__FBSDID("$FreeBSD$"); + +#include "SYS.h" + +/*- + * TODO: + * Rename sigsetjmp to __sigsetjmp and siglongjmp to __siglongjmp, + * remove the other *jmp functions and define everything in terms + * of the renamed functions. This requires compiler support for + * the renamed functions (introduced in gcc-2.5.3; previous versions + * only supported *jmp with 0 or 1 leading underscores). + * + * Restore _all_ the registers and the signal mask atomically. Can + * use sigreturn() if sigreturn() works. + */ + +ENTRY(sigsetjmp) + movl %esi,88(%rdi) /* 11; savemask */ + testl %esi,%esi + jz 2f + pushq %rdi + movq %rdi,%rcx + movq $1,%rdi /* SIG_BLOCK */ + movq $0,%rsi /* (sigset_t*)set */ + leaq 72(%rcx),%rdx /* 9,10 (sigset_t*)oset */ + call PIC_PLT(CNAME(_sigprocmask)) + popq %rdi +2: movq %rdi,%rcx + movq 0(%rsp),%rdx /* retval */ + movq %rdx, 0(%rcx) /* 0; retval */ + movq %rbx, 8(%rcx) /* 1; rbx */ + movq %rsp,16(%rcx) /* 2; rsp */ + movq %rbp,24(%rcx) /* 3; rbp */ + movq %r12,32(%rcx) /* 4; r12 */ + movq %r13,40(%rcx) /* 5; r13 */ + movq %r14,48(%rcx) /* 6; r14 */ + movq %r15,56(%rcx) /* 7; r15 */ + fnstcw 64(%rcx) /* 8; fpu cw */ + xorq %rax,%rax + ret + + .weak CNAME(siglongjmp) + .set CNAME(siglongjmp),CNAME(__siglongjmp) +ENTRY(__siglongjmp) + cmpl $0,88(%rdi) + jz 2f + movq %rdi,%rdx + pushq %rdi + pushq %rsi + movq $3,%rdi /* SIG_SETMASK */ + leaq 72(%rdx),%rsi /* (sigset_t*)set */ + movq $0,%rdx /* (sigset_t*)oset */ + call PIC_PLT(CNAME(_sigprocmask)) + popq %rsi + popq %rdi /* jmpbuf */ +2: movq %rdi,%rdx + movq %rsi,%rax /* retval */ + movq 0(%rdx),%rcx + movq 8(%rdx),%rbx + movq 16(%rdx),%rsp + movq 24(%rdx),%rbp + movq 32(%rdx),%r12 + movq 40(%rdx),%r13 + movq 48(%rdx),%r14 + movq 56(%rdx),%r15 + fninit + fldcw 64(%rdx) + testq %rax,%rax + jnz 1f + incq %rax +1: movq %rcx,0(%rsp) + ret |