diff options
author | Dale S. Rahn <rahnds@cvs.openbsd.org> | 1996-12-21 20:42:25 +0000 |
---|---|---|
committer | Dale S. Rahn <rahnds@cvs.openbsd.org> | 1996-12-21 20:42:25 +0000 |
commit | 18bfa0d968e3c3bb24239eaf982fb33bb185bf19 (patch) | |
tree | 0e19e42e1017544442510644e798db671db46527 /lib/libc | |
parent | 3a2ca69baba476e6254a1a232cab2d0981b68db3 (diff) |
Check-in of powerpc library support.
NOTE: This will not work until the other pieces are checked in.
This is primarily the NetBSD powerpc port, with modifications
to support ELF.
Diffstat (limited to 'lib/libc')
28 files changed, 1046 insertions, 0 deletions
diff --git a/lib/libc/arch/powerpc/Makefile.inc b/lib/libc/arch/powerpc/Makefile.inc new file mode 100644 index 00000000000..4634c4cf12f --- /dev/null +++ b/lib/libc/arch/powerpc/Makefile.inc @@ -0,0 +1,4 @@ +# $Id: Makefile.inc,v 1.1 1996/12/21 20:42:21 rahnds Exp $ + +KMINCLUDES= arch/ppc/SYS.h +KMSRCS= diff --git a/lib/libc/arch/powerpc/SYS.h b/lib/libc/arch/powerpc/SYS.h new file mode 100644 index 00000000000..39a86e5f57a --- /dev/null +++ b/lib/libc/arch/powerpc/SYS.h @@ -0,0 +1,72 @@ +/*- + * Copyright (c) 1994 + * Andrew Cagney. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 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: @(#)SYS.h 8.1 (Berkeley) 6/4/93 + * $Id: SYS.h,v 1.1 1996/12/21 20:42:21 rahnds Exp $ + */ + +#include <sys/syscall.h> + +/* r0 will be a non zero errno if there was an error, while r3/r4 will + contain the return value */ + +#include "machine/asm.h" + +#ifdef __STDC__ +#define PSEUDO_PREFIX(x,y) .globl _C_LABEL(x) ; \ + .align 2; \ + .extern cerror ; \ + _C_LABEL(x): li 0, SYS_##y ; \ + /* sc */ +#else /* !__STDC__ */ +#define PSEUDO_PREFIX(x,y) .globl _C_LABEL(x) ; \ + .align 2; \ + .extern cerror ; \ + _C_LABEL(x): li 0, SYS_/**/y ; \ + /* sc */ +#endif /* !__STDC__ */ +#define PSEUDO_SUFFIX cmpwi 0, 0 ; \ + beqlr+ ; \ + b cerror + +#define PREFIX(x) PSEUDO_PREFIX(x,x) + +#define SUFFIX PSEUDO_SUFFIX + +#define PSEUDO(x,y) PSEUDO_PREFIX(x,y) ; \ + sc ; \ + PSEUDO_SUFFIX + +#define RSYSCALL(x) PSEUDO(x,x) diff --git a/lib/libc/arch/powerpc/gen/Makefile.inc b/lib/libc/arch/powerpc/gen/Makefile.inc new file mode 100644 index 00000000000..d466810d196 --- /dev/null +++ b/lib/libc/arch/powerpc/gen/Makefile.inc @@ -0,0 +1 @@ +SRCS+= isinf.c infinity.c setjmp.S sigsetjmp.S flt_rounds.c modf.c ldexp.c fabs.c diff --git a/lib/libc/arch/powerpc/gen/fabs.c b/lib/libc/arch/powerpc/gen/fabs.c new file mode 100644 index 00000000000..e9e8510399d --- /dev/null +++ b/lib/libc/arch/powerpc/gen/fabs.c @@ -0,0 +1,9 @@ +double +fabs(double val) +{ + if (val > 0) { + return val; + } else { + return -val; + } +} diff --git a/lib/libc/arch/powerpc/gen/flt_rounds.c b/lib/libc/arch/powerpc/gen/flt_rounds.c new file mode 100644 index 00000000000..30158a53eba --- /dev/null +++ b/lib/libc/arch/powerpc/gen/flt_rounds.c @@ -0,0 +1,18 @@ +/* $NetBSD$ */ + +static const int map[] = { + 1, /* round to nearest */ + 0, /* round to zero */ + 2, /* round to positive infinity */ + 3 /* round to negative infinity */ +}; + +int +__flt_rounds() +{ + double tmp; + int x; + + asm("mffs %0; stfiwx %0,0,%1" : "=f"(tmp): "b"(&x)); + return map[x & 0x03]; +} diff --git a/lib/libc/arch/powerpc/gen/infinity.c b/lib/libc/arch/powerpc/gen/infinity.c new file mode 100644 index 00000000000..b9b6e460423 --- /dev/null +++ b/lib/libc/arch/powerpc/gen/infinity.c @@ -0,0 +1,10 @@ +#ifndef lint +static char rcsid[] = "$Id: infinity.c,v 1.1 1996/12/21 20:42:22 rahnds Exp $"; +#endif /* not lint */ + +/* infinity.c */ + +#include <math.h> + +/* bytes for +Infinity on a 387 */ +char __infinity[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; diff --git a/lib/libc/arch/powerpc/gen/isinf.c b/lib/libc/arch/powerpc/gen/isinf.c new file mode 100644 index 00000000000..348ef576d46 --- /dev/null +++ b/lib/libc/arch/powerpc/gen/isinf.c @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 1991 The Regents of the University of California. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 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[] = "from: @(#)isinf.c 5.1 (Berkeley) 3/18/91";*/ +static char rcsid[] = "$Id: isinf.c,v 1.1 1996/12/21 20:42:22 rahnds Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> + +isnan(d) + double d; +{ + register struct IEEEdp { + u_int manl : 32; + u_int manh : 20; + u_int exp : 11; + u_int sign : 1; + } *p = (struct IEEEdp *)&d; + + return(p->exp == 2047 && (p->manh || p->manl)); +} + +isinf(d) + double d; +{ + register struct IEEEdp { + u_int manl : 32; + u_int manh : 20; + u_int exp : 11; + u_int sign : 1; + } *p = (struct IEEEdp *)&d; + + return(p->exp == 2047 && !p->manh && !p->manl); +} diff --git a/lib/libc/arch/powerpc/gen/ldexp.c b/lib/libc/arch/powerpc/gen/ldexp.c new file mode 100644 index 00000000000..5a8f7985d42 --- /dev/null +++ b/lib/libc/arch/powerpc/gen/ldexp.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 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: Header: ldexp.c,v 1.1 91/07/07 04:28:19 torek Exp + * $Id: ldexp.c,v 1.1 1996/12/21 20:42:22 rahnds Exp $ + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char sccsid[] = "@(#)ldexp.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <errno.h> + +/* + * double ldexp(double val, int exp) + * returns: val * (2**exp) + */ +double +ldexp(val, exp) + double val; + int exp; +{ + register int oldexp, newexp, mulexp; + union doub { + double v; + struct ieee_double s; + } u, mul; + + /* + * If input is zero, or no change, just return input. + * Likewise, if input is Inf or NaN, just return it. + */ + u.v = val; + oldexp = u.s.dbl_exp; + if (val == 0 || exp == 0 || oldexp == DBL_EXP_INFNAN) + return (val); + + /* + * Compute new exponent and check for over/under flow. + * Underflow, unfortunately, could mean switching to denormal. + * If result out of range, set ERANGE and return 0 if too small + * or Inf if too big, with the same sign as the input value. + */ + newexp = oldexp + exp; + if (newexp >= DBL_EXP_INFNAN) { + /* u.s.dbl_sign = val < 0; -- already set */ + u.s.dbl_exp = DBL_EXP_INFNAN; + u.s.dbl_frach = u.s.dbl_fracl = 0; + errno = ERANGE; + return (u.v); /* Inf */ + } + if (newexp <= 0) { + /* + * The output number is either a denormal or underflows + * (see comments in machine/ieee.h). + */ + if (newexp <= -DBL_FRACBITS) { + /* u.s.dbl_sign = val < 0; -- already set */ + u.s.dbl_exp = 0; + u.s.dbl_frach = u.s.dbl_fracl = 0; + errno = ERANGE; + return (u.v); /* zero */ + } + /* + * We are going to produce a denorm. Our `exp' argument + * might be as small as -2097, and we cannot compute + * 2^-2097, so we may have to do this as many as three + * steps (not just two, as for positive `exp's below). + */ + mul.v = 0; + while (exp <= -DBL_EXP_BIAS) { + mul.s.dbl_exp = 1; + val *= mul.v; + exp += DBL_EXP_BIAS - 1; + } + mul.s.dbl_exp = exp + DBL_EXP_BIAS; + val *= mul.v; + return (val); + } + + /* + * Newexp is positive. + * + * If oldexp is zero, we are starting with a denorm, and simply + * adjusting the exponent will produce bogus answers. We need + * to fix that first. + */ + if (oldexp == 0) { + /* + * Multiply by 2^mulexp to make the number normalizable. + * We cannot multiply by more than 2^1023, but `exp' + * argument might be as large as 2046. A single + * adjustment, however, will normalize the number even + * for huge `exp's, and then we can use exponent + * arithmetic just as for normal `double's. + */ + mulexp = exp <= DBL_EXP_BIAS ? exp : DBL_EXP_BIAS; + mul.v = 0; + mul.s.dbl_exp = mulexp + DBL_EXP_BIAS; + val *= mul.v; + if (mulexp == exp) + return (val); + u.v = val; + newexp -= mulexp; + } + + /* + * Both oldexp and newexp are positive; just replace the + * old exponent with the new one. + */ + u.s.dbl_exp = newexp; + return (u.v); +} diff --git a/lib/libc/arch/powerpc/gen/modf.c b/lib/libc/arch/powerpc/gen/modf.c new file mode 100644 index 00000000000..838b2dfc42e --- /dev/null +++ b/lib/libc/arch/powerpc/gen/modf.c @@ -0,0 +1,309 @@ +/* @(#)s_modf.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_modf.c,v 1.8 1995/05/10 20:47:55 jtc Exp $"; +#endif + +/* + * modf(double x, double *iptr) + * return fraction part of x, and return x's integral part in *iptr. + * Method: + * Bit twiddling. + * + * Exception: + * No exception. + */ + +#include "math.h" + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * from: @(#)fdlibm.h 5.1 93/09/24 + * $Id: modf.c,v 1.1 1996/12/21 20:42:22 rahnds Exp $ + */ + +#ifndef _MATH_PRIVATE_H_ +#define _MATH_PRIVATE_H_ + +#include <machine/endian.h> +#include <sys/types.h> + +/* The original fdlibm code used statements like: + n0 = ((*(int*)&one)>>29)^1; * index of high word * + ix0 = *(n0+(int*)&x); * high word of x * + ix1 = *((1-n0)+(int*)&x); * low word of x * + to dig two 32 bit words out of the 64 bit IEEE floating point + value. That is non-ANSI, and, moreover, the gcc instruction + scheduler gets it wrong. We instead use the following macros. + Unlike the original code, we determine the endianness at compile + time, not at run time; I don't see much benefit to selecting + endianness at run time. */ + +/* A union which permits us to convert between a double and two 32 bit + ints. */ + +/* + * The arm32 port is little endian except for the FP word order which is + * big endian. + */ + +#if (BYTE_ORDER == BIG_ENDIAN) || defined(arm32) + +typedef union +{ + double value; + struct + { + u_int32_t msw; + u_int32_t lsw; + } parts; +} ieee_double_shape_type; + +#endif + +#if (BYTE_ORDER == LITTLE_ENDIAN) && !defined(arm32) + +typedef union +{ + double value; + struct + { + u_int32_t lsw; + u_int32_t msw; + } parts; +} ieee_double_shape_type; + +#endif + +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +do { \ + ieee_double_shape_type gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} while (0) + +/* Get the less significant 32 bit int from a double. */ + +#define GET_LOW_WORD(i,d) \ +do { \ + ieee_double_shape_type gl_u; \ + gl_u.value = (d); \ + (i) = gl_u.parts.lsw; \ +} while (0) + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + +/* Set the more significant 32 bits of a double from an int. */ + +#define SET_HIGH_WORD(d,v) \ +do { \ + ieee_double_shape_type sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} while (0) + +/* Set the less significant 32 bits of a double from an int. */ + +#define SET_LOW_WORD(d,v) \ +do { \ + ieee_double_shape_type sl_u; \ + sl_u.value = (d); \ + sl_u.parts.lsw = (v); \ + (d) = sl_u.value; \ +} while (0) + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union +{ + float value; + u_int32_t word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +do { \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} while (0) + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +do { \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} while (0) + +/* ieee style elementary functions */ +extern double __ieee754_sqrt __P((double)); +extern double __ieee754_acos __P((double)); +extern double __ieee754_acosh __P((double)); +extern double __ieee754_log __P((double)); +extern double __ieee754_atanh __P((double)); +extern double __ieee754_asin __P((double)); +extern double __ieee754_atan2 __P((double,double)); +extern double __ieee754_exp __P((double)); +extern double __ieee754_cosh __P((double)); +extern double __ieee754_fmod __P((double,double)); +extern double __ieee754_pow __P((double,double)); +extern double __ieee754_lgamma_r __P((double,int *)); +extern double __ieee754_gamma_r __P((double,int *)); +extern double __ieee754_lgamma __P((double)); +extern double __ieee754_gamma __P((double)); +extern double __ieee754_log10 __P((double)); +extern double __ieee754_sinh __P((double)); +extern double __ieee754_hypot __P((double,double)); +extern double __ieee754_j0 __P((double)); +extern double __ieee754_j1 __P((double)); +extern double __ieee754_y0 __P((double)); +extern double __ieee754_y1 __P((double)); +extern double __ieee754_jn __P((int,double)); +extern double __ieee754_yn __P((int,double)); +extern double __ieee754_remainder __P((double,double)); +extern int __ieee754_rem_pio2 __P((double,double*)); +extern double __ieee754_scalb __P((double,double)); + +/* fdlibm kernel function */ +extern double __kernel_standard __P((double,double,int)); +extern double __kernel_sin __P((double,double,int)); +extern double __kernel_cos __P((double,double)); +extern double __kernel_tan __P((double,double,int)); +extern int __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*)); + + +/* ieee style elementary float functions */ +extern float __ieee754_sqrtf __P((float)); +extern float __ieee754_acosf __P((float)); +extern float __ieee754_acoshf __P((float)); +extern float __ieee754_logf __P((float)); +extern float __ieee754_atanhf __P((float)); +extern float __ieee754_asinf __P((float)); +extern float __ieee754_atan2f __P((float,float)); +extern float __ieee754_expf __P((float)); +extern float __ieee754_coshf __P((float)); +extern float __ieee754_fmodf __P((float,float)); +extern float __ieee754_powf __P((float,float)); +extern float __ieee754_lgammaf_r __P((float,int *)); +extern float __ieee754_gammaf_r __P((float,int *)); +extern float __ieee754_lgammaf __P((float)); +extern float __ieee754_gammaf __P((float)); +extern float __ieee754_log10f __P((float)); +extern float __ieee754_sinhf __P((float)); +extern float __ieee754_hypotf __P((float,float)); +extern float __ieee754_j0f __P((float)); +extern float __ieee754_j1f __P((float)); +extern float __ieee754_y0f __P((float)); +extern float __ieee754_y1f __P((float)); +extern float __ieee754_jnf __P((int,float)); +extern float __ieee754_ynf __P((int,float)); +extern float __ieee754_remainderf __P((float,float)); +extern int __ieee754_rem_pio2f __P((float,float*)); +extern float __ieee754_scalbf __P((float,float)); + +/* float versions of fdlibm kernel functions */ +extern float __kernel_sinf __P((float,float,int)); +extern float __kernel_cosf __P((float,float)); +extern float __kernel_tanf __P((float,float,int)); +extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const int*)); + +#endif /* _MATH_PRIVATE_H_ */ +#ifdef __STDC__ +static const double one = 1.0; +#else +static double one = 1.0; +#endif + +#ifdef __STDC__ + double modf(double x, double *iptr) +#else + double modf(x, iptr) + double x,*iptr; +#endif +{ + int32_t i0,i1,j0; + u_int32_t i; + EXTRACT_WORDS(i0,i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ + if(j0<20) { /* integer part in high x */ + if(j0<0) { /* |x|<1 */ + INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */ + return x; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) { /* x is integral */ + u_int32_t high; + *iptr = x; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr,i0&(~i),0); + return x - *iptr; + } + } + } else if (j0>51) { /* no fraction part */ + u_int32_t high; + *iptr = x*one; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { /* fraction part in low x */ + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) { /* x is integral */ + u_int32_t high; + *iptr = x; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr,i0,i1&(~i)); + return x - *iptr; + } + } +} diff --git a/lib/libc/arch/powerpc/gen/setjmp.S b/lib/libc/arch/powerpc/gen/setjmp.S new file mode 100644 index 00000000000..9632d3fabbf --- /dev/null +++ b/lib/libc/arch/powerpc/gen/setjmp.S @@ -0,0 +1,125 @@ +#include "SYS.h" +#include <machine/asm.h> + +/* int setjmp(jmp_buf env) */ + +#define JMP_r1 0x04 +#define JMP_r14 0x08 +#define JMP_r15 0x0c +#define JMP_r16 0x10 +#define JMP_r17 0x14 +#define JMP_r18 0x18 +#define JMP_r19 0x1c +#define JMP_r20 0x20 +#define JMP_r21 0x24 +#define JMP_r22 0x28 +#define JMP_r23 0x2c +#define JMP_r24 0x30 +#define JMP_r25 0x34 +#define JMP_r26 0x38 +#define JMP_r27 0x3c +#define JMP_r28 0x40 +#define JMP_r29 0x44 +#define JMP_r30 0x48 +#define JMP_r31 0x4c +#define JMP_lr 0x50 +#define JMP_cr 0x54 +#define JMP_ctr 0x58 +#define JMP_xer 0x5c +#define JMP_sig 0x60 + + +.extern sigblock + +ENTRY(setjmp) + /* r31, mask */ + stw 31, JMP_r31(3) + mflr 0 + stw 0, JMP_lr(3) + mr 31, 3 + li 3, 0 + bl sigblock + stw 3, JMP_sig(31) + /* should sigstack be checked and saved */ + mr 3, 31 + lwz 0, JMP_lr(3) + mtlr 0 + lwz 31, JMP_r31(3) +ENTRY(_setjmp) + stw 31, JMP_r31(3) + /* r1, r14-r30 */ + stw 1, JMP_r1 (3) + stw 14, JMP_r14(3) + stw 15, JMP_r15(3) + stw 16, JMP_r16(3) + stw 17, JMP_r17(3) + stw 18, JMP_r18(3) + stw 19, JMP_r19(3) + stw 20, JMP_r20(3) + stw 21, JMP_r21(3) + stw 22, JMP_r22(3) + stw 23, JMP_r23(3) + stw 24, JMP_r24(3) + stw 25, JMP_r25(3) + stw 26, JMP_r26(3) + stw 27, JMP_r27(3) + stw 28, JMP_r28(3) + stw 29, JMP_r29(3) + stw 30, JMP_r30(3) + /* cr, lr, ctr, xer */ + mfcr 0 + stw 0, JMP_cr(3) + mflr 0 + stw 0, JMP_lr(3) + mfctr 0 + stw 0, JMP_ctr(3) + mfxer 0 + stw 0, JMP_xer(3) + /* f14-f31, fpscr */ + li 3, 0 + blr + + +.extern sigsetmask +ENTRY(longjmp) + /* r31, mask */ + mr 30, 3 + mr 31, 4 + lwz 3, JMP_sig(3) + bl sigsetmask + /* should we deal with sigonstack here ?? */ + mr 4, 31 + mr 3, 30 +ENTRY(_longjmp) + lwz 31, JMP_r31(3) + /* r1, r14-r30 */ + lwz 1, JMP_r1 (3) + lwz 14, JMP_r14(3) + lwz 15, JMP_r15(3) + lwz 16, JMP_r16(3) + lwz 17, JMP_r17(3) + lwz 18, JMP_r18(3) + lwz 19, JMP_r19(3) + lwz 20, JMP_r20(3) + lwz 21, JMP_r21(3) + lwz 22, JMP_r22(3) + lwz 23, JMP_r23(3) + lwz 24, JMP_r24(3) + lwz 25, JMP_r25(3) + lwz 26, JMP_r26(3) + lwz 27, JMP_r27(3) + lwz 28, JMP_r28(3) + lwz 29, JMP_r29(3) + lwz 30, JMP_r30(3) + /* cr, lr, ctr, xer */ + lwz 0, JMP_cr(3) + mtcr 0 + lwz 0, JMP_lr(3) + mtlr 0 + lwz 0, JMP_ctr(3) + mtctr 0 + lwz 0, JMP_xer(3) + mtxer 0 + /* f14-f31, fpscr */ + mr 3, 4 + blr diff --git a/lib/libc/arch/powerpc/gen/sigsetjmp.S b/lib/libc/arch/powerpc/gen/sigsetjmp.S new file mode 100644 index 00000000000..9d998b651c4 --- /dev/null +++ b/lib/libc/arch/powerpc/gen/sigsetjmp.S @@ -0,0 +1,99 @@ +/* $NetBSD$ */ + +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 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: @(#)setjmp.s 5.1 (Berkeley) 4/23/90" + */ +#if 0 +#include <sys/syscall.h> + +#include <machine/asm.h> +#endif + +#include "SYS.h" +#include <machine/asm.h> + +#if defined(LIBC_SCCS) + .text + .asciz "$NetBSD$" +#endif + +#if 1 +ENTRY(sigsetjmp) +#else + .globl sigsetjmp +sigsetjmp: +#endif + mr 6,3 + or. 7,4,4 + beq 1f + li 3,1 # SIG_BLOCK + li 4,0 + li 0,SYS_sigprocmask + sc # assume no error XXX +1: + mflr 11 + mfcr 12 + mr 10,1 + mr 9,2 + mr 8,3 + stmw 7,0(6) + li 3,0 + blr + +#if 1 +ENTRY(siglongjmp) +#else + .globl siglongjmp +siglongjmp: +#endif + lmw 7,0(3) + mr 6,4 + mtlr 11 + mtcr 12 + mr 2,9 + mr 1,10 + or. 7,7,7 + beq 1f + mr 4,8 + li 3,3 # SIG_SETMASK + li 0,SYS_sigprocmask + sc # assume no error XXX +1: + or. 3,6,6 + bnelr + li 3,1 + blr diff --git a/lib/libc/arch/powerpc/net/Makefile.inc b/lib/libc/arch/powerpc/net/Makefile.inc new file mode 100644 index 00000000000..86017c7b155 --- /dev/null +++ b/lib/libc/arch/powerpc/net/Makefile.inc @@ -0,0 +1,2 @@ +SRCS += ntohl.c ntohs.c htons.c htonl.c + diff --git a/lib/libc/arch/powerpc/string/Makefile.inc b/lib/libc/arch/powerpc/string/Makefile.inc new file mode 100644 index 00000000000..a8bdeab3255 --- /dev/null +++ b/lib/libc/arch/powerpc/string/Makefile.inc @@ -0,0 +1,6 @@ +# $NetBSD: Makefile.inc,v 1.1 1995/03/20 14:45:47 mycroft Exp $ + +SRCS+= bcmp.c bcopy.c bzero.c ffs.c index.c memchr.c memcmp.c memset.c \ + rindex.c strcat.c strcmp.c strcpy.c strcspn.c strlen.c \ + strncat.c strncmp.c strncpy.c strpbrk.c strsep.c \ + strspn.c strstr.c swab.c diff --git a/lib/libc/arch/powerpc/sys/Ovfork.S b/lib/libc/arch/powerpc/sys/Ovfork.S new file mode 100644 index 00000000000..ac460a85aad --- /dev/null +++ b/lib/libc/arch/powerpc/sys/Ovfork.S @@ -0,0 +1,4 @@ +#include "SYS.h" + +/* pid = vfork() */ +RSYSCALL(vfork) diff --git a/lib/libc/arch/powerpc/sys/brk.S b/lib/libc/arch/powerpc/sys/brk.S new file mode 100644 index 00000000000..faa44c45e54 --- /dev/null +++ b/lib/libc/arch/powerpc/sys/brk.S @@ -0,0 +1,34 @@ +#include "SYS.h" + + .data + .extern curbrk + .extern _end + + .text +PSEUDO_PREFIX(brk,break) + + /* check >= _end, if not make the call for _end */ + addis 5,0,_end@h + ori 5,5,_end@l /* # 5 = &_end */ + cmpw 3,5 + bge+ brk_call + mr 3, 5 + +brk_call: + mr 7, 3 + /* call break(size) */ + addis 6, 0, curbrk@H + ori 6, 6, curbrk@L /* # 6 = &curbrk */ + + sc + + /* check for error */ + cmpwi 0, 0 + beq+ brk_ok /* OK so this is stupid but I haven't read b */ + b cerror + + /* update, curbrk and return */ +brk_ok: + stw 7, 0(6) /* # remember, 6=&curbrk, 3= new value */ + mr 3, 0 /* # return 0 */ + blr diff --git a/lib/libc/arch/powerpc/sys/cerror.S b/lib/libc/arch/powerpc/sys/cerror.S new file mode 100644 index 00000000000..a99db9ddf83 --- /dev/null +++ b/lib/libc/arch/powerpc/sys/cerror.S @@ -0,0 +1,22 @@ +#include "SYS.h" +#include <machine/asm.h> + + .text +ENTRY(cerror) +#if 1 + addis 5, 0, errno@H + ori 5, 5, errno@L +#else + .data + .extern errno +errno_toc: + .long errno + .text + addis 5, 0, errno_toc@H + ori 5, 5, errno_toc@L + lwz 5, 0(5) +#endif + stw 0, 0(5) + addi 3, 0, -1 + addi 4, 0, -1 + blr diff --git a/lib/libc/arch/powerpc/sys/exect.S b/lib/libc/arch/powerpc/sys/exect.S new file mode 100644 index 00000000000..31307cc3f2e --- /dev/null +++ b/lib/libc/arch/powerpc/sys/exect.S @@ -0,0 +1 @@ +/* rubbish */ diff --git a/lib/libc/arch/powerpc/sys/fork.S b/lib/libc/arch/powerpc/sys/fork.S new file mode 100644 index 00000000000..36d65e8cc94 --- /dev/null +++ b/lib/libc/arch/powerpc/sys/fork.S @@ -0,0 +1,5 @@ +/* pid = fork() */ + +#include "SYS.h" + +RSYSCALL(fork) diff --git a/lib/libc/arch/powerpc/sys/pipe.S b/lib/libc/arch/powerpc/sys/pipe.S new file mode 100644 index 00000000000..a80c05e7bf8 --- /dev/null +++ b/lib/libc/arch/powerpc/sys/pipe.S @@ -0,0 +1,15 @@ +/* int sigsuspend(int *mask) */ + +#include "SYS.h" + + .text +PREFIX(pipe) + mr 5, 3 /* keep buf addr safe */ + sc + cmpwi 0, 0 + beq ok + b cerror +ok: stw 3, 0(5) + stw 4, 4(5) + li 3, 0 + blr diff --git a/lib/libc/arch/powerpc/sys/ptrace.S b/lib/libc/arch/powerpc/sys/ptrace.S new file mode 100644 index 00000000000..31307cc3f2e --- /dev/null +++ b/lib/libc/arch/powerpc/sys/ptrace.S @@ -0,0 +1 @@ +/* rubbish */ diff --git a/lib/libc/arch/powerpc/sys/reboot.S b/lib/libc/arch/powerpc/sys/reboot.S new file mode 100644 index 00000000000..8063167c8d4 --- /dev/null +++ b/lib/libc/arch/powerpc/sys/reboot.S @@ -0,0 +1,3 @@ +/* rubbish */ +#include <SYS.h> +RSYSCALL(reboot) diff --git a/lib/libc/arch/powerpc/sys/sbrk.S b/lib/libc/arch/powerpc/sys/sbrk.S new file mode 100644 index 00000000000..c54fa839e8a --- /dev/null +++ b/lib/libc/arch/powerpc/sys/sbrk.S @@ -0,0 +1,32 @@ +#include "SYS.h" + + .data + .globl _end + .globl curbrk + .globl minbrk +curbrk: .long _end +minbrk: .long _end + + + .text +PSEUDO_PREFIX(sbrk,break) + + /* call break(curbrk + size) */ + addis 6,0,curbrk@h + ori 6,6,curbrk@l /* # 6 = &curbrk */ + lwz 5, 0(6) /* # 5 = *6 (old_curbrk) */ + add 3, 5, 3 /* # 3 = new_curbrk */ + mr 7, 3 + + sc + + /* check for error */ + cmpwi 0, 0 + beq+ sbrk_ok /* OK so this is stupid but I haven't read b */ + b cerror + + /* update, curbrk and return */ +sbrk_ok: + stw 7, 0(6) /* # remember, 6=&curbrk, 7=new_curbrk */ + mr 3, 5 /* # remember, 5=old_curbrk */ + blr diff --git a/lib/libc/arch/powerpc/sys/setlogin.S b/lib/libc/arch/powerpc/sys/setlogin.S new file mode 100644 index 00000000000..793c846e047 --- /dev/null +++ b/lib/libc/arch/powerpc/sys/setlogin.S @@ -0,0 +1,9 @@ +/* rubbish */ +#include "SYS.h" + .extern __logname_valid +RSYSCALL(setlogin) + lis 0, __logname_valid@H + li 4, 4 + stw 4,__logname_valid@L(0) + blr + diff --git a/lib/libc/arch/powerpc/sys/sigpending.S b/lib/libc/arch/powerpc/sys/sigpending.S new file mode 100644 index 00000000000..31307cc3f2e --- /dev/null +++ b/lib/libc/arch/powerpc/sys/sigpending.S @@ -0,0 +1 @@ +/* rubbish */ diff --git a/lib/libc/arch/powerpc/sys/sigprocmask.S b/lib/libc/arch/powerpc/sys/sigprocmask.S new file mode 100644 index 00000000000..e8b250ed4ad --- /dev/null +++ b/lib/libc/arch/powerpc/sys/sigprocmask.S @@ -0,0 +1,30 @@ +/* sigprocmask(int how, const sigset_t *set, sigset_t *oset); */ + +#include "SYS.h" + + .text +PREFIX(sigprocmask) + + /* check set (new mask value) for null, in which case + fiddle arguments */ + cmpwi 4, 0 + bne+ load_set + addi 3, 0, 1 /* how = SIG_BLOCK, new mask already 0 */ + b do_call +load_set: + lwz 4, 0(4) /* get new mask */ +do_call: + + sc + + /* didnt work? */ + cmpwi 0, 0 + beq+ sigprocmask_ok + b cerror + +sigprocmask_ok: + cmpwi 5, 0 + beq+ sigprocmask_done + stw 4, 0(5) +sigprocmask_done: + blr diff --git a/lib/libc/arch/powerpc/sys/sigreturn.S b/lib/libc/arch/powerpc/sys/sigreturn.S new file mode 100644 index 00000000000..31307cc3f2e --- /dev/null +++ b/lib/libc/arch/powerpc/sys/sigreturn.S @@ -0,0 +1 @@ +/* rubbish */ diff --git a/lib/libc/arch/powerpc/sys/sigsuspend.S b/lib/libc/arch/powerpc/sys/sigsuspend.S new file mode 100644 index 00000000000..ea4c5ce33b9 --- /dev/null +++ b/lib/libc/arch/powerpc/sys/sigsuspend.S @@ -0,0 +1,9 @@ +/* int sigsuspend(int *mask) */ + +#include "SYS.h" + + .text +PREFIX(sigsuspend) + lwz 3, 0(3) /* load the mask */ + sc + SUFFIX diff --git a/lib/libc/arch/powerpc/sys/syscall.S b/lib/libc/arch/powerpc/sys/syscall.S new file mode 100644 index 00000000000..4d0ba95ff30 --- /dev/null +++ b/lib/libc/arch/powerpc/sys/syscall.S @@ -0,0 +1,11 @@ +/* + * COPYRIGHT + */ +#if defined(SYSLIBC_SCCS) + .text + .asciz "$OpenBSD: syscall.S,v 1.1 1996/12/21 20:42:24 rahnds Exp $" +#endif /* SYSLIBC_SCCS */ + +#include "SYS.h" + +RSYSCALL(syscall) |