diff options
| author | bjh21 <bjh21@NetBSD.org> | 2000-05-09 21:55:44 +0000 |
|---|---|---|
| committer | bjh21 <bjh21@NetBSD.org> | 2000-05-09 21:55:44 +0000 |
| commit | 6c97e2bd7817f6eb36ea04f65488ea1e95cb158f (patch) | |
| tree | 499bc6851619a39119e4f4e8919311cbb9b2948d /lib/libc | |
| parent | 6a36c27519360fbbcb9b0533b93429d400c5e315 (diff) | |
Initial commit of arm26 port
Diffstat (limited to 'lib/libc')
68 files changed, 8224 insertions, 8 deletions
diff --git a/lib/libc/arch/arm26/Makefile.inc b/lib/libc/arch/arm26/Makefile.inc new file mode 100644 index 00000000000..fd8aaf64ef4 --- /dev/null +++ b/lib/libc/arch/arm26/Makefile.inc @@ -0,0 +1,9 @@ +# $NetBSD: Makefile.inc,v 1.1 2000/05/09 21:55:45 bjh21 Exp $ + +KMINCLUDES= +KMSRCS=arch/arm26/gen/divsi3.S arch/arm26/string/memmove.S \ + arch/arm26/string/memcpy.S +# __APCS_26__ required for SYS.h stuff +CPPFLAGS+=-DSOFTFLOAT -D__APCS_26__ + +.include <fplib/Makefile.inc> diff --git a/lib/libc/arch/arm26/SYS.h b/lib/libc/arch/arm26/SYS.h new file mode 100644 index 00000000000..4f60f83ffc2 --- /dev/null +++ b/lib/libc/arch/arm26/SYS.h @@ -0,0 +1,92 @@ +/* $NetBSD: SYS.h,v 1.1 2000/05/09 21:55:45 bjh21 Exp $ */ + +/*- + * 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: @(#)SYS.h 5.5 (Berkeley) 5/7/91 + */ + +#include <machine/asm.h> +#include <sys/syscall.h> + +#ifdef __STDC__ +#define SYSTRAP(x) swi SYS_ ## x +#else +#define SYSTRAP(x) swi SYS_/**/x +#endif + +#define _SYSCALL_NOERROR(x,y) \ + ENTRY(x); \ + SYSTRAP(y) + +#define _SYSCALL(x, y) \ + _SYSCALL_NOERROR(x,y); \ + bcs cerror + +#define SYSCALL_NOERROR(x) \ + _SYSCALL_NOERROR(x,x) + +#define SYSCALL(x) \ + _SYSCALL(x,x) + +#ifdef __APCS_26__ + +#define PSEUDO_NOERROR(x,y) \ + _SYSCALL_NOERROR(x,y); \ + movs r15, r14 + +#define PSEUDO(x,y) \ + _SYSCALL(x,y); \ + movs r15, r14 + +#else /* !__APCS_26__ */ + +#define PSEUDO_NOERROR(x,y) \ + _SYSCALL_NOERROR(x,y); \ + mov r15, r14 + +#define PSEUDO(x,y) \ + _SYSCALL(x,y); \ + mov r15, r14 + +#endif /* !__APCS_26__ */ + +#define RSYSCALL_NOERROR(x) \ + PSEUDO_NOERROR(x,x) + +#define RSYSCALL(x) \ + PSEUDO(x,x) + + .globl cerror diff --git a/lib/libc/arch/arm26/fplib/Makefile.inc b/lib/libc/arch/arm26/fplib/Makefile.inc new file mode 100644 index 00000000000..72e2c5b0edf --- /dev/null +++ b/lib/libc/arch/arm26/fplib/Makefile.inc @@ -0,0 +1,23 @@ +# $NetBSD: Makefile.inc,v 1.1 2000/05/09 21:55:46 bjh21 Exp $ + +.PATH: ${.CURDIR}/arch/arm26/fplib + +SRCS+=fplib_glue.S fplib_libc.c softfloat.c + +softfloat.o: softfloat.c + @echo ${COMPILE.c:Q} -freg-struct-return ${.IMPSRC} + @${COMPILE.c} -freg-struct-return ${.IMPSRC} -o ${.TARGET}.o + @${LD} -x -r ${.TARGET}.o -o ${.TARGET} + @rm -f ${.TARGET}.o + +softfloat.po: softfloat.c + @echo ${COMPILE.c:Q} -pg -freg-struct-return ${.IMPSRC} -o ${.TARGET} + @${COMPILE.c} -pg -freg-struct-return ${.IMPSRC} -o ${.TARGET}.o + @${LD} -X -r ${.TARGET}.o -o ${.TARGET} + @rm -f ${.TARGET}.o + +softfloat.so: softfloat.c + @echo ${COMPILE.c:Q} ${CPICFLAGS} -freg-struct-return ${.IMPSRC} -o ${.TARGET} + @${COMPILE.c} ${CPICFLAGS} -freg-struct-return ${.IMPSRC} -o ${.TARGET}.o + @${LD} -x -r ${.TARGET}.o -o ${.TARGET} + @rm -f ${.TARGET}.o diff --git a/lib/libc/arch/arm26/fplib/arm-gcc.h b/lib/libc/arch/arm26/fplib/arm-gcc.h new file mode 100644 index 00000000000..2b4962bd301 --- /dev/null +++ b/lib/libc/arch/arm26/fplib/arm-gcc.h @@ -0,0 +1,79 @@ +/* $NetBSD: arm-gcc.h,v 1.1 2000/05/09 21:55:46 bjh21 Exp $ */ + +/* +------------------------------------------------------------------------------- +One of either `BIGENDIAN' or `LITTLEENDIAN' must be defined. +------------------------------------------------------------------------------- +*/ +#define LITTLEENDIAN + +/* +------------------------------------------------------------------------------- +`BIT64' can be defined to indicate that 64-bit integer types are supported +by the compiler. +------------------------------------------------------------------------------- +*/ +#define BITS64 + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines the most convenient type that holds +integers of at least as many bits as specified. For example, `uint8' should +be the most convenient type that can hold unsigned integers of as many as +8 bits. The `flag' type must be able to hold either a 0 or 1. For most +implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed +to the same as `int'. +------------------------------------------------------------------------------- +*/ +typedef char flag; +typedef unsigned char uint8; +typedef signed char int8; +typedef int uint16; +typedef int int16; +typedef unsigned int uint32; +typedef signed int int32; +#ifdef BITS64 +typedef unsigned long long int bits64; +typedef signed long long int sbits64; +#endif + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines a type that holds integers +of _exactly_ the number of bits specified. For instance, for most +implementation of C, `bits16' and `sbits16' should be `typedef'ed to +`unsigned short int' and `signed short int' (or `short int'), respectively. +------------------------------------------------------------------------------- +*/ +typedef unsigned char bits8; +typedef signed char sbits8; +typedef unsigned short int bits16; +typedef signed short int sbits16; +typedef unsigned int bits32; +typedef signed int sbits32; +#ifdef BITS64 +typedef unsigned long long int uint64; +typedef signed long long int int64; +#endif + + +/* + * Macros to define functions with the GCC expected names + */ + +#define float32_add __addsf3 +#define float64_add __adddf3 +#define float32_sub __subsf3 +#define float64_sub __subdf3 +#define float32_mul __mulsf3 +#define float64_mul __muldf3 +#define float32_div __divsf3 +#define float64_div __divdf3 +#define int32_to_float32 __floatsisf +#define int32_to_float64 __floatsidf +#define float32_to_int32_round_to_zero __fixsfsi +#define float64_to_int32_round_to_zero __fixdfsi +#define float32_to_uint32_round_to_zero __fixunssfsi +#define float64_to_uint32_round_to_zero __fixunsdfsi +#define float32_to_float64 __extendsfdf2 +#define float64_to_float32 __truncdfsf2 diff --git a/lib/libc/arch/arm26/fplib/environment.h b/lib/libc/arch/arm26/fplib/environment.h new file mode 100644 index 00000000000..e567b3e11c5 --- /dev/null +++ b/lib/libc/arch/arm26/fplib/environment.h @@ -0,0 +1,63 @@ +/* $NetBSD: environment.h,v 1.1 2000/05/09 21:55:46 bjh21 Exp $ */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 1a. + +Written by John R. Hauser. This work was made possible by the International +Computer Science Institute, located at Suite 600, 1947 Center Street, +Berkeley, California 94704. Funding was provided in part by the National +Science Foundation under grant MIP-9311980. The original version of +this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the web page `http://www.cs.berkeley.edu/~jhauser/ +softfloat.html'. + +THIS PACKAGE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS PACKAGE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS PACKAGE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY AND ALL +LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these three paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +Include common integer types and flags. +------------------------------------------------------------------------------- +*/ +#include "arm-gcc.h" + +/* +------------------------------------------------------------------------------- +The word `INLINE' appears before all routines that should be inlined. If +a compiler does not support inlining, this macro should be defined to be +`static'. +------------------------------------------------------------------------------- +*/ +#define INLINE static __inline + +/* +------------------------------------------------------------------------------- +Move private identifiers with external linkage into implementation namespace. + -- Klaus Klein <kleink@netbsd.org>, May 5, 1999 +------------------------------------------------------------------------------- +*/ +#define float_exception_flags _arm_float_exception_flags +#define float_rounding_mode _arm_float_rounding_mode +#define float32_eq _arm_float32_eq +#define float32_le _arm_float32_le +#define float32_lt _arm_float32_lt +#define float64_eq _arm_float64_eq +#define float64_le _arm_float64_le +#define float64_lt _arm_float64_lt +#define float_raise _arm_float_raise diff --git a/lib/libc/arch/arm26/fplib/fplib_glue.S b/lib/libc/arch/arm26/fplib/fplib_glue.S new file mode 100644 index 00000000000..f8f8e48bcd8 --- /dev/null +++ b/lib/libc/arch/arm26/fplib/fplib_glue.S @@ -0,0 +1,211 @@ +/* $NetBSD: fplib_glue.S,v 1.1 2000/05/09 21:55:46 bjh21 Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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> + +#define SIGN_BIT_TWIDDLE 0x80000000 + +/********************************* COMPARISONS ********************************/ + +/* + * 'Equal' wrapper. This returns 0 if the numbers are equal, or (1 | -1) + * otherwise. So we need to invert the output. + */ +ENTRY(__eqsf2) + stmfd sp!, {lr} + bl _C_LABEL(_arm_float32_eq) + eor r0, r0, #1 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else + ldmfd sp!, {pc} +#endif + +ENTRY(__eqdf2) + stmfd sp!, {lr} + bl _C_LABEL(_arm_float64_eq) + eor r0, r0, #1 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else + ldmfd sp!, {pc} +#endif + +/* + * 'Not Equal' wrapper. This returns -1 or 1 (say, 1!) if the numbers are + * not equal, 0 otherwise. However no not equal call is provided, so we have + * to use an 'equal' call and invert the result. The result is already + * inverted though! Confusing?! + */ +ENTRY(__nesf2) + stmfd sp!, {lr} + bl _C_LABEL(_arm_float32_eq) + eor r0, r0, #1 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else + ldmfd sp!, {pc} +#endif + +ENTRY(__nedf2) + stmfd sp!, {lr} + bl _C_LABEL(_arm_float64_eq) + eor r0, r0, #1 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else + ldmfd sp!, {pc} +#endif + +/* + * 'Greater Than' wrapper. This returns 1 if the number is greater, 0 + * or -1 otherwise. Unfortunately, no such function exists. We have to + * instead compare the numbers using the 'less than' calls in order to + * make up our mind. This means that we can call 'less than or equal' and + * invert the result. + */ +ENTRY(__gtsf2) + stmfd sp!, {lr} + bl _C_LABEL(_arm_float32_le) + eor r0, r0, #1 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else + ldmfd sp!, {pc} +#endif + +ENTRY(__gtdf2) + stmfd sp!, {lr} + bl _C_LABEL(_arm_float64_le) + eor r0, r0, #1 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else + ldmfd sp!, {pc} +#endif + +/* + * 'Greater Than or Equal' wrapper. We emulate this by inverting the result + * of a 'less than' call. + */ +ENTRY(__gesf2) + stmfd sp!, {lr} + bl _C_LABEL(_arm_float32_lt) + eor r0, r0, #1 + cmp r0, #0 + mvneq r0, #0 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else + ldmfd sp!, {pc} +#endif + +ENTRY(__gedf2) + stmfd sp!, {lr} + bl _C_LABEL(_arm_float64_lt) + eor r0, r0, #1 + cmp r0, #0 + mvneq r0, #0 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else + ldmfd sp!, {pc} +#endif + +/* + * 'Less Than' wrapper. A 1 from the ARM code needs to be turned into -1. + */ +ENTRY(__ltsf2) + stmfd sp!, {lr} + bl _C_LABEL(_arm_float32_lt) + cmp r0, #1 + mvneq r0, #0 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else + ldmfd sp!, {pc} +#endif + +ENTRY(__ltdf2) + stmfd sp!, {lr} + bl _C_LABEL(_arm_float64_lt) + cmp r0, #1 + mvneq r0, #0 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else + ldmfd sp!, {pc} +#endif + +/* + * 'Less Than or Equal' wrapper. A 0 must turn into a 1, and a 1 into a 0. + */ +ENTRY(__lesf2) + stmfd sp!, {lr} + bl _C_LABEL(_arm_float32_le) + eor r0, r0, #1 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else + ldmfd sp!, {pc} +#endif + +ENTRY(__ledf2) + stmfd sp!, {lr} + bl _C_LABEL(_arm_float64_le) + eor r0, r0, #1 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else + ldmfd sp!, {pc} +#endif + +/* + * Float negate... This isn't provided by the library, but it's hardly the + * hardest function in the world to write... :) In fact, because of the + * position in the registers of arguments, the double precision version can + * go here too ;-) + */ +ENTRY(__negsf2) +ENTRY(__negdf2) + eor r0, r0, #SIGN_BIT_TWIDDLE +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif diff --git a/lib/libc/arch/arm26/fplib/fplib_libc.c b/lib/libc/arch/arm26/fplib/fplib_libc.c new file mode 100644 index 00000000000..061998322c0 --- /dev/null +++ b/lib/libc/arch/arm26/fplib/fplib_libc.c @@ -0,0 +1,86 @@ +/* $NetBSD: fplib_libc.c,v 1.1 2000/05/09 21:55:46 bjh21 Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <sys/types.h> +#include "environment.h" +#include "softfloat.h" + +void sfp_setround __P((int rnd_dir)); +int sfp_getround __P((void)); +void sfp_setmask __P((int mask)); +int sfp_getmask __P((void)); +void sfp_setsticky __P((int except)); +int sfp_getsticky __P((void)); + +void +sfp_setround(rnd_dir) + int rnd_dir; +{ + float_rounding_mode = rnd_dir; +} + +int +sfp_getround(void) +{ + return(float_rounding_mode); +} + +void +sfp_setmask(mask) + int mask; +{ +} + +int +sfp_getmask(void) +{ + return(0); +} + +void +sfp_setsticky(except) + int except; +{ + float_exception_flags = except; +} + +int +sfp_getsticky(void) +{ + return(float_exception_flags); +} diff --git a/lib/libc/arch/arm26/fplib/softfloat-macros.h b/lib/libc/arch/arm26/fplib/softfloat-macros.h new file mode 100644 index 00000000000..5df3b52fe17 --- /dev/null +++ b/lib/libc/arch/arm26/fplib/softfloat-macros.h @@ -0,0 +1,754 @@ +/* $NetBSD: softfloat-macros.h,v 1.1 2000/05/09 21:55:46 bjh21 Exp $ */ + +/* +=============================================================================== + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 1a. + +Written by John R. Hauser. This work was made possible by the International +Computer Science Institute, located at Suite 600, 1947 Center Street, +Berkeley, California 94704. Funding was provided in part by the National +Science Foundation under grant MIP-9311980. The original version of +this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the web page `http://www.cs.berkeley.edu/~jhauser/ +softfloat.html'. + +THIS PACKAGE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS PACKAGE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS PACKAGE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY AND ALL +LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these three paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +INLINE void shiftDown32Jamming( bits32 a, uint16 count, bits32 *zPtr ); + +INLINE void shiftDown64ExtraJamming( + bits32 a0, + bits32 a1, + bits32 a2, + uint16 count, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ); + +INLINE void shiftDown64Jamming( + bits32 a0, bits32 a1, uint16 count, bits32 *z0Ptr, bits32 *z1Ptr ); + +INLINE void shiftDown64( + bits32 a0, bits32 a1, uint16 count, bits32 *z0Ptr, bits32 *z1Ptr ); + +INLINE void shortShiftUp64( + bits32 a0, bits32 a1, uint16 count, bits32 *z0Ptr, bits32 *z1Ptr ); + +INLINE void shortShiftUp96( + bits32 a0, + bits32 a1, + bits32 a2, + uint16 count, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ); + +INLINE void add64( + bits32 a0, bits32 a1, bits32 b0, bits32 b1, bits32 *z0Ptr, bits32 *z1Ptr ); + +INLINE void add96( + bits32 a0, + bits32 a1, + bits32 a2, + bits32 b0, + bits32 b1, + bits32 b2, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ); + +INLINE void sub64( + bits32 a0, bits32 a1, bits32 b0, bits32 b1, bits32 *z0Ptr, bits32 *z1Ptr ); + +INLINE void sub96( + bits32 a0, + bits32 a1, + bits32 a2, + bits32 b0, + bits32 b1, + bits32 b2, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ); + +INLINE void mul32To64( bits32 a, bits32 b, bits32 *z0Ptr, bits32 *z1Ptr ); + +INLINE void mul64By32To96( + bits32 a0, + bits32 a1, + bits32 b, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ); + +INLINE void mul64To128( + bits32 a0, + bits32 a1, + bits32 b0, + bits32 b1, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr, + bits32 *z3Ptr + ); + +static bits32 estimateDiv64To32( bits32 a0, bits32 a1, bits32 b ); + +#if 0 /* unused */ +static bits32 estimateSqrt32( int16 aExp, bits32 a ); +#endif + +static int8 countLeadingZeros( bits32 a ); + +INLINE flag eq64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ); + +INLINE flag le64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ); + +INLINE flag lt64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ); + +#if 0 /* XXX not used */ +INLINE flag ne64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ); +#endif + + +/* +------------------------------------------------------------------------------- +Shifts `a' down by the number of bits given in `count'. If any nonzero bits +are shifted off, they are ``jammed'' into the least significant bit of the +result by setting the least significant bit to 1. The value of `count' can +be arbitrarily large; in particular, if `count' is greater than 32, the +result will be either 0 or 1, depending on whether `a' is zero or nonzero. +The result is stored in the location pointed to by `zPtr'. +------------------------------------------------------------------------------- +*/ +INLINE void shiftDown32Jamming( bits32 a, uint16 count, bits32 *zPtr ) +{ + bits32 z; + + if ( count == 0 ) { + z = a; + } + else if ( count < 32 ) { + z = ( a>>count ) | ( 0 < ( a<<( ( - count ) & 31 ) ) ); + } + else { + z = ( 0 < a ); + } + *zPtr = z; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 96-bit value formed by concatenating `a0', `a1', and `a2' down by +32 _plus_ the number of bits given in `count'. The shifted-down result is +at most 64 nonzero bits; these are broken into two 32-bit pieces which are +stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted +off form a third 32-bit result as follows: The _last_ bit shifted off is +the most-significant bit of the extra result, and the other 31 bits of the +extra result are all zero if and only if _all_but_the_last_ bits shifted off +were all zero. This extra result is stored in the location pointed to by +`z2Ptr'. The value of `count' can be arbitrarily large. + (This routine makes more sense if `a0', `a1', and `a2' are considered +to form a fixed-point value with binary point between `a1' and `a2'. This +fixed-point value is shifted down by the number of bits given in `count', +and the integer part of the result is returned at the locations pointed to +by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly +corrupted as described above, and is returned at the location pointed to by +`z2Ptr'.) +------------------------------------------------------------------------------- +*/ +INLINE void + shiftDown64ExtraJamming( + bits32 a0, + bits32 a1, + bits32 a2, + uint16 count, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ) +{ + bits32 z0, z1, z2; + int8 negCount = ( - count ) & 31; + + if ( count == 0 ) { + z2 = a2; + z1 = a1; + z0 = a0; + } + else { + if ( count < 32 ) { + z2 = a1<<negCount; + z1 = ( a0<<negCount ) | ( a1>>count ); + z0 = a0>>count; + } + else { + if ( count == 32 ) { + z2 = a1; + z1 = a0; + } + else { + a2 |= a1; + if ( count < 64 ) { + z2 = a0<<negCount; + z1 = a0>>( count & 31 ); + } + else { + z2 = ( count == 64 ) ? a0 : ( 0 < a0 ); + z1 = 0; + } + } + z0 = 0; + } + z2 |= ( 0 < a2 ); + } + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 64-bit value formed by concatenating `a0' and `a1' down by the +number of bits given in `count'. If any nonzero bits are shifted off, they +are ``jammed'' into the least significant bit of the result by setting the +least significant bit to 1. The value of `count' can be arbitrarily large; +in particular, if `count' is greater than 64, the result will be either 0 +or 1, depending on whether the concatenation of `a0' and `a1' is zero or +nonzero. The result is broken into two 32-bit pieces which are stored at +the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shiftDown64Jamming( + bits32 a0, bits32 a1, uint16 count, bits32 *z0Ptr, bits32 *z1Ptr ) +{ + bits32 z0, z1; + int8 negCount = ( - count ) & 31; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 32 ) { + z1 = ( a0<<negCount ) | ( a1>>count ) | ( 0 < ( a1<<negCount ) ); + z0 = a0>>count; + } + else { + if ( count == 32 ) { + z1 = a0 | ( 0 < a1 ); + } + else if ( count < 64 ) { + z1 = ( a0>>( count & 31 ) ) | ( 0 < ( ( a0<<negCount ) | a1 ) ); + } + else { + z1 = ( 0 < ( a0 | a1 ) ); + } + z0 = 0; + } + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 64-bit value formed by concatenating `a0' and `a1' down by the +number of bits given in `count'. Any bits shifted off are lost. The value +of `count' can be arbitrarily large; in particular, if `count' is greater +than 64, the result will be 0. The result is broken into two 32-bit pieces +which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shiftDown64( + bits32 a0, bits32 a1, uint16 count, bits32 *z0Ptr, bits32 *z1Ptr ) +{ + bits32 z0, z1; + int8 negCount = ( - count ) & 31; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 32 ) { + z1 = ( a0<<negCount ) | ( a1>>count ); + z0 = a0>>count; + } + else { + z1 = ( count < 64 ) ? ( a0>>( count & 31 ) ) : 0; + z0 = 0; + } + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 64-bit value formed by concatenating `a0' and `a1' up by the +number of bits given in `count'. Any bits shifted off are lost. The value +of `count' must be less than 32. The result is broken into two 32-bit +pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shortShiftUp64( + bits32 a0, bits32 a1, uint16 count, bits32 *z0Ptr, bits32 *z1Ptr ) +{ + + *z1Ptr = a1<<count; + *z0Ptr = + ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 31 ) ); + +} + +/* +------------------------------------------------------------------------------- +Shifts the 96-bit value formed by concatenating `a0', `a1', and `a2' up by +the number of bits given in `count'. Any bits shifted off are lost. The +value of `count' must be less than 32. The result is broken into three +32-bit pieces which are stored at the locations pointed to by `z0Ptr', +`z1Ptr', and `z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shortShiftUp96( + bits32 a0, + bits32 a1, + bits32 a2, + uint16 count, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ) +{ + bits32 z0, z1, z2; + int8 negCount; + + z2 = a2<<count; + z1 = a1<<count; + z0 = a0<<count; + if ( 0 < count ) { + negCount = ( ( - count ) & 31 ); + z1 |= a2>>negCount; + z0 |= a1>>negCount; + } + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Adds the 64-bit value formed by concatenating `a0' and `a1' to the 64-bit +value formed by concatenating `b0' and `b1'. Addition is modulo 2^64, so +any carry out is lost. The result is broken into two 32-bit pieces which +are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + add64( + bits32 a0, bits32 a1, bits32 b0, bits32 b1, bits32 *z0Ptr, bits32 *z1Ptr ) +{ + bits32 z1; + + z1 = a1 + b1; + *z1Ptr = z1; + *z0Ptr = a0 + b0 + ( z1 < a1 ); + +} + +/* +------------------------------------------------------------------------------- +Adds the 96-bit value formed by concatenating `a0', `a1', and `a2' to the +96-bit value formed by concatenating `b0', `b1', and `b2'. Addition is +modulo 2^96, so any carry out is lost. The result is broken into three +32-bit pieces which are stored at the locations pointed to by `z0Ptr', +`z1Ptr', and `z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + add96( + bits32 a0, + bits32 a1, + bits32 a2, + bits32 b0, + bits32 b1, + bits32 b2, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ) +{ + bits32 z0, z1, z2; + int8 carry0, carry1; + + z2 = a2 + b2; + carry1 = ( z2 < a2 ); + z1 = a1 + b1; + carry0 = ( z1 < a1 ); + z0 = a0 + b0; + z1 += carry1; + z0 += ( z1 < carry1 ); + z0 += carry0; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Subtracts the 64-bit value formed by concatenating `b0' and `b1' from the +64-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo +2^64, so any borrow out (carry out) is lost. The result is broken into two +32-bit pieces which are stored at the locations pointed to by `z0Ptr' and +`z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + sub64( + bits32 a0, bits32 a1, bits32 b0, bits32 b1, bits32 *z0Ptr, bits32 *z1Ptr ) +{ + + *z1Ptr = a1 - b1; + *z0Ptr = a0 - b0 - ( a1 < b1 ); + +} + +/* +------------------------------------------------------------------------------- +Subtracts the 96-bit value formed by concatenating `b0', `b1', and `b2' from +the 96-bit value formed by concatenating `a0', `a1', and `a2'. Subtraction +is modulo 2^96, so any borrow out (carry out) is lost. The result is broken +into three 32-bit pieces which are stored at the locations pointed to by +`z0Ptr', `z1Ptr', and `z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + sub96( + bits32 a0, + bits32 a1, + bits32 a2, + bits32 b0, + bits32 b1, + bits32 b2, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ) +{ + bits32 z0, z1, z2; + int8 borrow0, borrow1; + + z2 = a2 - b2; + borrow1 = ( a2 < b2 ); + z1 = a1 - b1; + borrow0 = ( a1 < b1 ); + z0 = a0 - b0; + z0 -= ( z1 < borrow1 ); + z1 -= borrow1; + z0 -= borrow0; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Multiplies `a' by `b' to obtain a 64-bit product. The product is broken +into two 32-bit pieces which are stored at the locations pointed to by +`z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void mul32To64( bits32 a, bits32 b, bits32 *z0Ptr, bits32 *z1Ptr ) +{ + bits16 aHigh, aLow, bHigh, bLow; + bits32 z0, zMiddle, zMiddleOther, z1; + + aLow = ( a & 0xFFFF ); + aHigh = a>>16; + bLow = ( b & 0xFFFF ); + bHigh = b>>16; + z1 = aLow * bLow; + zMiddle = aLow * bHigh; + zMiddleOther = aHigh * bLow; + z0 = aHigh * bHigh; + zMiddle += zMiddleOther; + z0 += ( ( zMiddle < zMiddleOther )<<16 ) + ( zMiddle>>16 ); + zMiddle = zMiddle<<16; + z1 += zMiddle; + z0 += ( z1 < zMiddle ); + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Multiplies the 64-bit value formed by concatenating `a0' and `a1' by `b' to +obtain a 96-bit product. The product is broken into three 32-bit pieces +which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and +`z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + mul64By32To96( + bits32 a0, + bits32 a1, + bits32 b, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ) +{ + bits32 z0, z1, z2, more1; + + mul32To64( a1, b, &z1, &z2 ); + mul32To64( a0, b, &z0, &more1 ); + add64( z0, more1, 0, z1, &z0, &z1 ); + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Multiplies the 64-bit value formed by concatenating `a0' and `a1' to the +64-bit value formed by concatenating `b0' and `b1' to obtain a 128-bit +product. The product is broken into four 32-bit pieces which are stored at +the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + mul64To128( + bits32 a0, + bits32 a1, + bits32 b0, + bits32 b1, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr, + bits32 *z3Ptr + ) +{ + bits32 z0, z1, z2, z3; + bits32 more1, more2; + + mul32To64( a1, b1, &z2, &z3 ); + mul32To64( a1, b0, &z1, &more2 ); + add64( z1, more2, 0, z2, &z1, &z2 ); + mul32To64( a0, b0, &z0, &more1 ); + add64( z0, more1, 0, z1, &z0, &z1 ); + mul32To64( a0, b1, &more1, &more2 ); + add64( more1, more2, 0, z2, &more1, &z2 ); + add64( z0, z1, 0, more1, &z0, &z1 ); + *z3Ptr = z3; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Returns an approximation to the 32-bit integer quotient obtained by dividing +the 64-bit value formed by concatenating `a0' and `a1' by `b'. The divisor +`b' must be at least 2^31. If q is the exact quotient truncated toward +zero, the approximation returned lies between q and q + 2 inclusive. If +the exact quotient q is larger than 32 bits, the maximum positive 32-bit +unsigned integer is returned. +------------------------------------------------------------------------------- +*/ +static bits32 estimateDiv64To32( bits32 a0, bits32 a1, bits32 b ) +{ + bits32 z; + bits32 rem0, rem1; + bits32 term0, term1; + bits32 b0, b1; + + if ( b <= a0 ) return 0xFFFFFFFF; + b0 = b>>16; + z = ( b0<<16 <= a0 ) ? 0xFFFF0000 : ( a0 / b0 )<<16; + mul32To64( b, z, &term0, &term1 ); + sub64( a0, a1, term0, term1, &rem0, &rem1 ); + while ( ( (sbits32) rem0 ) < 0 ) { + z -= 0x10000; + b1 = b<<16; + add64( rem0, rem1, b0, b1, &rem0, &rem1 ); + } + rem0 = ( rem0<<16 ) | ( rem1>>16 ); + z |= ( b0<<16 <= rem0 ) ? 0xFFFF : rem0 / b0; + return z; + +} + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Returns an approximation to the square root of the 32-bit significand given +by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of +`aExp' (the least significant bit) is 1, the integer returned approximates +2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp' +is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either +case, the approximation returned lies strictly within +/-2 of the exact +value. +------------------------------------------------------------------------------- +*/ +static bits32 estimateSqrt32( int16 aExp, bits32 a ) +{ + static const bits16 sqrtOddAdjustments[] = { + 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, + 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 + }; + static const bits16 sqrtEvenAdjustments[] = { + 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, + 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 + }; + int8 index; + bits32 z; + + index = ( a>>27 ) & 15; + if ( aExp & 1 ) { + z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ]; + z = ( ( a / z )<<14 ) + ( z<<15 ); + a = a>>1; + } + else { + z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ]; + z = ( ( a / z ) + z ); + z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 ); + if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 ); + } + return ( ( estimateDiv64To32( a, 0, z ) )>>1 ) + ( z>>1 ); + +} +#endif /* unused */ + +/* +------------------------------------------------------------------------------- +Returns the number of leading 0 bits before the most-significant 1 bit +of `a'. If `a' is zero, 32 is returned. +------------------------------------------------------------------------------- +*/ +static int8 countLeadingZeros( bits32 a ) +{ + static const int8 countLeadingZerosHigh[] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + int8 shiftCount; + + shiftCount = 0; + if ( a < 0x10000 ) { + shiftCount += 16; + a = a<<16; + } + if ( a < 0x1000000 ) { + shiftCount += 8; + a = a<<8; + } + shiftCount += countLeadingZerosHigh[ a>>24 ]; + return shiftCount; + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is equal +to the 64-bit value formed by concatenating `b0' and `b1'. Otherwise, +returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag eq64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ) +{ + + return ( a0 == b0 ) && ( a1 == b1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is less +than or equal to the 64-bit value formed by concatenating `b0' and `b1'. +Otherwise, returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag le64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ) +{ + + return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is less +than the 64-bit value formed by concatenating `b0' and `b1'. Otherwise, +returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag lt64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ) +{ + + return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is not +equal to the 64-bit value formed by concatenating `b0' and `b1'. Otherwise, +returns 0. +------------------------------------------------------------------------------- +*/ +#if 0 /* XXX not used */ +INLINE flag ne64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ) +{ + + return ( a0 != b0 ) || ( a1 != b1 ); + +} +#endif + diff --git a/lib/libc/arch/arm26/fplib/softfloat-specialize.h b/lib/libc/arch/arm26/fplib/softfloat-specialize.h new file mode 100644 index 00000000000..c50857d4c82 --- /dev/null +++ b/lib/libc/arch/arm26/fplib/softfloat-specialize.h @@ -0,0 +1,173 @@ +/* $NetBSD: softfloat-specialize.h,v 1.1 2000/05/09 21:55:46 bjh21 Exp $ */ + +/* +=============================================================================== + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 1a. + +Written by John R. Hauser. This work was made possible by the International +Computer Science Institute, located at Suite 600, 1947 Center Street, +Berkeley, California 94704. Funding was provided in part by the National +Science Foundation under grant MIP-9311980. The original version of +this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the web page `http://www.cs.berkeley.edu/~jhauser/ +softfloat.html'. + +THIS PACKAGE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS PACKAGE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS PACKAGE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY AND ALL +LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these three paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +static flag float32_is_signaling_nan( float32 a ); +static flag float64_is_signaling_nan( float64 a ); + +/* +------------------------------------------------------------------------------- +Underflow tininess-detection mode. (Statically initialized to default.) +------------------------------------------------------------------------------- +*/ +static flag float_detect_tininess = float_tininess_after_rounding; + +/* +------------------------------------------------------------------------------- +Raises the exceptions specified by `flags'. Floating-point traps can be +defined here if desired. It is currently not possible for such a trap to +substitute a result value. If traps are not implemented, this routine +should be simply `float_exception_flags |= flags;'. +------------------------------------------------------------------------------- +*/ +void float_raise( uint8 flags ) +{ + + float_exception_flags |= flags; + +} + +/* +------------------------------------------------------------------------------- +The pattern for a default generated single-precision NaN. +------------------------------------------------------------------------------- +*/ +enum { + float32_default_nan = 0xFFC00000 +}; + +/* +------------------------------------------------------------------------------- +The pattern for a default generated double-precision NaN. The `high' and +`low' words hold the most- and least-significant bits, respectively. +------------------------------------------------------------------------------- +*/ +enum { + float64_default_nan_high = 0xFFF80000, + float64_default_nan_low = 0x00000000 +}; + +/* +------------------------------------------------------------------------------- +Returns true if the single-precision floating-point value `a' is a signaling +NaN; otherwise returns false. +------------------------------------------------------------------------------- +*/ +static flag float32_is_signaling_nan( float32 a ) +{ + + return ( ( a & 0x7FC00000 ) == 0x7F800000 ) && ( a & 0x003FFFFF ); + +} + +/* +------------------------------------------------------------------------------- +Returns true if the double-precision floating-point value `a' is a signaling +NaN; otherwise returns false. +------------------------------------------------------------------------------- +*/ +static flag float64_is_signaling_nan( float64 a ) +{ + + return + ( ( a.high & 0x7FF80000 ) == 0x7FF00000 ) + && ( ( a.high & 0x0007FFFF ) || a.low ); + +} + +/* +------------------------------------------------------------------------------- +Converts a single-precision NaN `a' to a double-precision quiet NaN. If `a' +is a signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static float64 float32ToFloat64NaN( float32 a ) +{ + float64 z; + + if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.low = float64_default_nan_low; + z.high = float64_default_nan_high; + return z; + +} + +/* +------------------------------------------------------------------------------- +Converts a double-precision NaN `a' to a single-precision quiet NaN. If `a' +is a signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static float32 float64ToFloat32NaN( float64 a ) +{ + + if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + return float32_default_nan; + +} + +/* +------------------------------------------------------------------------------- +Takes two single-precision floating-point values `a' and `b', one of which +is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static float32 propagateFloat32NaN( float32 a, float32 b ) +{ + + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return float32_default_nan; + +} + +/* +------------------------------------------------------------------------------- +Takes two double-precision floating-point values `a' and `b', one of which +is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static float64 propagateFloat64NaN( float64 a, float64 b ) +{ + float64 z; + + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + z.low = float64_default_nan_low; + z.high = float64_default_nan_high; + return z; + +} + diff --git a/lib/libc/arch/arm26/fplib/softfloat.c b/lib/libc/arch/arm26/fplib/softfloat.c new file mode 100644 index 00000000000..9e5e78c6a9a --- /dev/null +++ b/lib/libc/arch/arm26/fplib/softfloat.c @@ -0,0 +1,2509 @@ +/* $NetBSD: softfloat.c,v 1.1 2000/05/09 21:55:46 bjh21 Exp $ */ + +/* +=============================================================================== + +This C source file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 1a. + +Written by John R. Hauser. This work was made possible by the International +Computer Science Institute, located at Suite 600, 1947 Center Street, +Berkeley, California 94704. Funding was provided in part by the National +Science Foundation under grant MIP-9311980. The original version of +this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the web page `http://www.cs.berkeley.edu/~jhauser/ +softfloat.html'. + +THIS PACKAGE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS PACKAGE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS PACKAGE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY AND ALL +LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these three paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +#include "environment.h" +#include "softfloat.h" + +/* +------------------------------------------------------------------------------- +Floating-point rounding mode and exception flags. +------------------------------------------------------------------------------- +*/ +uint8 float_exception_flags = 0; +uint8 float_rounding_mode = float_round_nearest_even; + +/* +------------------------------------------------------------------------------- +Functions and definitions to determine: (1) what (if anything) happens when +exceptions are raised, (2) how signaling NaNs are distinguished from quiet +NaNs, (3) the default generated quiet NaNs, and (4) how NaNs are propagated +from function inputs to output. These details are target-specific. +------------------------------------------------------------------------------- +*/ +#include "softfloat-specialize.h" + +/* +------------------------------------------------------------------------------- +Primitive arithmetic functions, including multi-word arithmetic, and +division and square root approximations. (Can be specialized to target if +desired.) +------------------------------------------------------------------------------- +*/ +#include "softfloat-macros.h" + +/* Local prototypes */ + +INLINE bits32 extractFloat32Frac( float32 a ); +INLINE int16 extractFloat32Exp( float32 a ); +INLINE flag extractFloat32Sign( float32 a ); +INLINE flag bothZeroFloat32( float32 a, float32 b ); +INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig ); +INLINE bits32 extractFloat64Frac1( float64 a ); +INLINE bits32 extractFloat64Frac0( float64 a ); +INLINE int16 extractFloat64Exp( float64 a ); +INLINE flag extractFloat64Sign( float64 a ); +INLINE flag bothZeroFloat64( float64 a, float64 b ); +INLINE float64 packFloat64( flag zSign, int16 zExp, bits32 zSig0, bits32 zSig1 ); + +/* +------------------------------------------------------------------------------- +Returns the fraction bits of the single-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE bits32 extractFloat32Frac( float32 a ) +{ + + return a & 0x007FFFFF; + +} + +/* +------------------------------------------------------------------------------- +Returns the exponent bits of the single-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE int16 extractFloat32Exp( float32 a ) +{ + + return ( a>>23 ) & 0xFF; + +} + +/* +------------------------------------------------------------------------------- +Returns the sign bit of the single-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE flag extractFloat32Sign( float32 a ) +{ + + return a>>31; + +} + +/* +------------------------------------------------------------------------------- +Returns true if the single-precision floating-point values `a' and `b' are +both zero. Otherwise, returns false. +------------------------------------------------------------------------------- +*/ +INLINE flag bothZeroFloat32( float32 a, float32 b ) +{ + + return ( ( ( a | b )<<1 ) == 0 ); + +} + +/* +------------------------------------------------------------------------------- +Normalizes the subnormal single-precision floating-point value represented +by the denormalized significand `aSig'. The normalized exponent and +significand are stored at the locations pointed to by `zExpPtr' and +`zSigPtr', respectively. +------------------------------------------------------------------------------- +*/ +static void + normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros( aSig ) - 8; + *zSigPtr = aSig<<shiftCount; + *zExpPtr = 1 - shiftCount; + +} + +/* +------------------------------------------------------------------------------- +Packs the sign `zSign', exponent `zExp', and significand `zSig' into a +single-precision floating-point value, returning the result. After being +shifted into the proper positions, the three fields are simply added +together to form the result. This means that any integer portion of `zSig' +will be added into the exponent. Since a properly normalized significand +will have an integer portion equal to 1, the `zExp' input should be 1 less +than the desired result exponent whenever `zSig' is a complete, normalized +significand. +------------------------------------------------------------------------------- +*/ +INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig ) +{ + + return ( zSign<<31 ) + ( zExp<<23 ) + zSig; + +} + +/* +------------------------------------------------------------------------------- +Takes an abstract floating-point value having sign `zSign', exponent `zExp', +and significand `zSig', and returns the proper single-precision floating- +point value corresponding to the abstract input. Ordinarily, the abstract +value is simply rounded and packed into the single-precision format, with +the inexact exception raised if the abstract input cannot be represented +exactly. If the abstract value is too large, however, the overflow and +inexact exceptions are raised and an infinity or maximal finite value is +returned. If the abstract value is too small, the input value is rounded to +a subnormal number, and the underflow and inexact exceptions are raised if +the abstract input cannot be represented exactly as a subnormal single- +precision floating-point number. + The input significand `zSig' has its binary point between bits 30 +and 29, which is 7 bits to the left of the usual location. This shifted +significand must be normalized or smaller. If `zSig' is not normalized, +`zExp' must be 0; in that case, the result returned is a subnormal number, +and it must not require rounding. In the usual case that `zSig' is +normalized, `zExp' must be 1 less than the ``true'' floating-point exponent. +The handling of underflow and overflow follows the IEC/IEEE Standard for +Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) +{ + uint8 roundingMode; + flag roundNearestEven; + int8 roundIncrement, roundBits; + flag isTiny; + + roundingMode = float_rounding_mode; + roundNearestEven = roundingMode == float_round_nearest_even; + roundIncrement = 0x40; + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + roundIncrement = 0; + } + else { + roundIncrement = 0x7F; + if ( zSign ) { + if ( roundingMode == float_round_up ) roundIncrement = 0; + } + else { + if ( roundingMode == float_round_down ) roundIncrement = 0; + } + } + } + roundBits = zSig & 0x7F; + if ( 0xFE - 1 <= ( (bits16) zExp ) ) { + if ( ( 0xFE - 1 < zExp ) + || ( ( zExp == 0xFE - 1 ) + && ( ( (sbits32) ( zSig + roundIncrement ) ) < 0 ) ) + ) { + float_raise( float_flag_overflow | float_flag_inexact ); + return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 ); + } + if ( zExp < 0 ) { + isTiny = + ( float_detect_tininess == float_tininess_before_rounding ) + || ( zExp < -1 ) + || ( zSig + roundIncrement < 0x80000000 ); + shiftDown32Jamming( zSig, - zExp, &zSig ); + zExp = 0; + roundBits = zSig & 0x7F; + if ( isTiny && roundBits ) float_raise( float_flag_underflow ); + } + } + if ( roundBits ) float_exception_flags |= float_flag_inexact; + zSig = ( zSig + roundIncrement )>>7; + zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); + if ( zSig == 0 ) zExp = 0; + return packFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Takes an abstract floating-point value having sign `zSign', exponent `zExp', +and significand `zSig', and returns the proper single-precision floating- +point value corresponding to the abstract input. This routine is just like +`roundAndPackFloat32' except that `zSig' does not have to be normalized in +any way. In all cases, `zExp' must be 1 less than the ``true'' floating- +point exponent. +------------------------------------------------------------------------------- +*/ +static float32 + normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros( zSig ) - 1; + return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount ); + +} + +/* +------------------------------------------------------------------------------- +Returns the least-significant 32 fraction bits of the double-precision +floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE bits32 extractFloat64Frac1( float64 a ) +{ + + return a.low; + +} + +/* +------------------------------------------------------------------------------- +Returns the most-significant 20 fraction bits of the double-precision +floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE bits32 extractFloat64Frac0( float64 a ) +{ + + return a.high & 0x000FFFFF; + +} + +/* +------------------------------------------------------------------------------- +Returns the exponent bits of the double-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE int16 extractFloat64Exp( float64 a ) +{ + + return ( a.high>>20 ) & 0x7FF; + +} + +/* +------------------------------------------------------------------------------- +Returns the sign bit of the double-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE flag extractFloat64Sign( float64 a ) +{ + + return a.high>>31; + +} + +/* +------------------------------------------------------------------------------- +Returns true if the double-precision floating-point values `a' and `b' are +both zero. Otherwise, returns false. +------------------------------------------------------------------------------- +*/ +INLINE flag bothZeroFloat64( float64 a, float64 b ) +{ + + return ( ( ( a.high | b.high )<<1 ) | a.low | b.low ) == 0; + +} + +/* +------------------------------------------------------------------------------- +Normalizes the subnormal double-precision floating-point value represented +by the denormalized significand formed by the concatenation of `aSig0' and +`aSig1'. The normalized exponent is stored at the location pointed to by +`zExpPtr'. The most significant 21 bits of the normalized significand are +stored at the location pointed to by `zSig0Ptr', and the least significant +32 bits of the normalized significand are stored at the location pointed to +by `zSig1Ptr'. +------------------------------------------------------------------------------- +*/ +static void + normalizeFloat64Subnormal( + bits32 aSig0, + bits32 aSig1, + int16 *zExpPtr, + bits32 *zSig0Ptr, + bits32 *zSig1Ptr + ) +{ + int8 shiftCount; + + if ( aSig0 == 0 ) { + shiftCount = countLeadingZeros( aSig1 ) - 11; + if ( shiftCount < 0 ) { + *zSig0Ptr = aSig1>>( - shiftCount ); + *zSig1Ptr = aSig1<<( shiftCount & 31 ); + } + else { + *zSig0Ptr = aSig1<<shiftCount; + *zSig1Ptr = 0; + } + *zExpPtr = - shiftCount - 31; + } + else { + shiftCount = countLeadingZeros( aSig0 ) - 11; + shortShiftUp64( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr ); + *zExpPtr = 1 - shiftCount; + } + +} + +/* +------------------------------------------------------------------------------- +Packs the sign `zSign', the exponent `zExp', and the significand formed by +the concatenation of `zSig0' and `zSig1' into a double-precision floating- +point value, returning the result. After being shifted into the proper +positions, the three fields `zSign', `zExp', and `zSig0' are simply added +together to form the most significant 32 bits of the result. This means +that any integer portion of `zSig0' will be added into the exponent. Since +a properly normalized significand will have an integer portion equal to 1, +the `zExp' input should be 1 less than the desired result exponent whenever +`zSig0' and `zSig1' concatenated form a complete, normalized significand. +------------------------------------------------------------------------------- +*/ +INLINE float64 + packFloat64( flag zSign, int16 zExp, bits32 zSig0, bits32 zSig1 ) +{ + float64 z; + + z.low = zSig1; + z.high = ( zSign<<31 ) + ( zExp<<20 ) + zSig0; + return z; + +} + +/* +------------------------------------------------------------------------------- +Takes an abstract floating-point value having sign `zSign', exponent `zExp', +and extended significand formed by the concatenation of `zSig0', `zSig1', +and `zSig2', and returns the proper double-precision floating-point value +corresponding to the abstract input. Ordinarily, the abstract value is +simply rounded and packed into the double-precision format, with the inexact +exception raised if the abstract input cannot be represented exactly. If +the abstract value is too large, however, the overflow and inexact +exceptions are raised and an infinity or maximal finite value is returned. +If the abstract value is too small, the input value is rounded to a +subnormal number, and the underflow and inexact exceptions are raised if the +abstract input cannot be represented exactly as a subnormal double-precision +floating-point number. + The input significand must be normalized or smaller. If the input +significand is not normalized, `zExp' must be 0; in that case, the result +returned is a subnormal number, and it must not require rounding. In the +usual case that the input significand is normalized, `zExp' must be 1 less +than the ``true'' floating-point exponent. The handling of underflow and +overflow follows the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float64 + roundAndPackFloat64( + flag zSign, int16 zExp, bits32 zSig0, bits32 zSig1, bits32 zSig2 ) +{ + uint8 roundingMode; + flag roundNearestEven, increment; + flag isTiny; + + roundingMode = float_rounding_mode; + roundNearestEven = roundingMode == float_round_nearest_even; + increment = ( (sbits32) zSig2 ) < 0; + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + increment = 0; + } + else { + if ( zSign ) { + increment = ( roundingMode == float_round_down ) && zSig2; + } + else { + increment = ( roundingMode == float_round_up ) && zSig2; + } + } + } + if ( 0x7FE - 1 <= ( (bits16) zExp ) ) { + if ( ( 0x7FE - 1 < zExp ) + || ( ( zExp == 0x7FE - 1 ) + && eq64( 0x001FFFFF, 0xFFFFFFFF, zSig0, zSig1 ) + && increment + ) + ) { + float_raise( float_flag_overflow | float_flag_inexact ); + if ( ( roundingMode == float_round_to_zero ) + || ( zSign && ( roundingMode == float_round_up ) ) + || ( ! zSign && ( roundingMode == float_round_down ) ) + ) { + return packFloat64( zSign, 0x7FE, 0x000FFFFF, 0xFFFFFFFF ); + } + return packFloat64( zSign, 0x7FF, 0, 0 ); + } + if ( zExp < 0 ) { + isTiny = + ( float_detect_tininess == float_tininess_before_rounding ) + || ( zExp < -1 ) + || ! increment + || lt64( zSig0, zSig1, 0x001FFFFF, 0xFFFFFFFF ); + shiftDown64ExtraJamming( + zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 ); + zExp = 0; + if ( isTiny && zSig2 ) float_raise( float_flag_underflow ); + if ( roundNearestEven ) { + increment = ( (sbits32) zSig2 ) < 0; + } + else { + if ( zSign ) { + increment = ( roundingMode == float_round_down ) && zSig2; + } + else { + increment = ( roundingMode == float_round_up ) && zSig2; + } + } + } + } + if ( zSig2 ) float_exception_flags |= float_flag_inexact; + if ( increment ) { + add64( zSig0, zSig1, 0, 1, &zSig0, &zSig1 ); + zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven ); + } + if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0; + return packFloat64( zSign, zExp, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Takes an abstract floating-point value having sign `zSign', exponent `zExp', +and significand formed by the concatenation of `zSig0' and `zSig1', and +returns the proper double-precision floating-point value corresponding to +the abstract input. This routine is just like `roundAndPackFloat64' except +that the input significand has fewer bits and does not have to be normalized +in any way. In all cases, `zExp' must be 1 less than the ``true'' floating- +point exponent. +------------------------------------------------------------------------------- +*/ +static float64 + normalizeRoundAndPackFloat64( + flag zSign, int16 zExp, bits32 zSig0, bits32 zSig1 ) +{ + int8 shiftCount; + bits32 zSig2; + + if ( zSig0 == 0 ) { + zSig0 = zSig1; + zSig1 = 0; + zExp -= 32; + } + shiftCount = countLeadingZeros( zSig0 ) - 11; + if ( 0 <= shiftCount ) { + zSig2 = 0; + shortShiftUp64( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); + } + else { + shiftDown64ExtraJamming( + zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 ); + } + zExp -= shiftCount; + return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the 32-bit two's complement integer `a' to +the single-precision floating-point format. The conversion is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 int32_to_float32( int32 a ) +{ + flag zSign; + + if ( a == 0 ) return 0; + if ( a == -0x80000000 ) return packFloat32( 1, 0x9E, 0 ); + zSign = ( a < 0 ); + return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the 32-bit two's complement integer `a' to +the double-precision floating-point format. The conversion is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 int32_to_float64( int32 a ) +{ + flag zSign; + bits32 absA; + int8 shiftCount; + bits32 zSig0, zSig1; + + if ( a == 0 ) return packFloat64( 0, 0, 0, 0 ); + zSign = ( a < 0 ); + absA = zSign ? - a : a; + shiftCount = countLeadingZeros( absA ) - 11; + if ( 0 <= shiftCount ) { + zSig0 = absA<<shiftCount; + zSig1 = 0; + } + else { + shiftDown64( absA, 0, - shiftCount, &zSig0, &zSig1 ); + } + return packFloat64( zSign, 0x412 - shiftCount, zSig0, zSig1 ); + +} + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic---which means in particular that the conversion is rounded +according to the current rounding mode. If `a' is a NaN, the largest +positive integer is returned. If the conversion overflows, the largest +integer with the same sign as `a' is returned. +------------------------------------------------------------------------------- +*/ +static int32 float32_to_int32( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + bits32 zExtra; + int32 z; + uint8 roundingMode; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + shiftCount = aExp - 0x96; + if ( 0 <= shiftCount ) { + if ( 0x9E <= aExp ) { + if ( a == 0xCF000000 ) return -0x80000000; + float_raise( float_flag_invalid ); + if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF; + return -0x80000000; + } + z = ( aSig | 0x800000 )<<shiftCount; + if ( aSign ) z = - z; + } + else { + if ( aExp < 0x7E ) { + zExtra = aExp | aSig; + z = 0; + } + else { + aSig |= 0x800000; + zExtra = aSig<<( shiftCount & 31 ); + z = aSig>>( - shiftCount ); + } + if ( zExtra ) float_exception_flags |= float_flag_inexact; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + if ( ( (sbits32) zExtra ) < 0 ) { + ++z; + if ( ( zExtra + zExtra ) == 0 ) z &= ~1; + } + if ( aSign ) z = - z; + } + else { + zExtra = zExtra != 0; + if ( aSign ) { + z += ( roundingMode == float_round_down ) & zExtra; + z = - z; + } + else { + z += ( roundingMode == float_round_up ) & zExtra; + } + } + } + return z; + +} +#endif /* unused */ + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic, except that the conversion is always rounded toward zero. If +`a' is a NaN, the largest positive integer is returned. If the conversion +overflows, the largest integer with the same sign as `a' is returned. +------------------------------------------------------------------------------- +*/ +int32 float32_to_int32_round_to_zero( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + int32 z; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + shiftCount = aExp - 0x9E; + if ( 0 <= shiftCount ) { + if ( a == 0xCF000000 ) return -0x80000000; + float_raise( float_flag_invalid ); + if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF; + return -0x80000000; + } + else if ( aExp <= 0x7E ) { + if ( aExp | aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig = ( aSig | 0x800000 )<<8; + z = aSig>>( - shiftCount ); + if ( aSig<<( shiftCount & 31 ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the double-precision floating-point format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float32_to_float64( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + bits32 zSig0, zSig1; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return float32ToFloat64NaN( a ); + return packFloat64( aSign, 0x7FF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( aSign, 0, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + shiftDown64( aSig, 0, 3, &zSig0, &zSig1 ); + return packFloat64( aSign, aExp - 0x7F + 0x3FF, zSig0, zSig1 ); + +} + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic---which means in particular that the conversion is rounded +according to the current rounding mode. If `a' is a NaN, the largest +positive integer is returned. If the conversion overflows, the largest +integer with the same sign as `a' is returned. +------------------------------------------------------------------------------- +*/ + +static int32 float64_to_int32( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig0, aSig1; + bits32 absZ, zExtra; + int32 z; + uint8 roundingMode; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + shiftCount = aExp - 0x413; + if ( 0 <= shiftCount ) { + if ( 11 < shiftCount ) { + if ( ( aExp == 0x7FF ) && ( aSig0 | aSig1 ) ) aSign = 0; + absZ = 0xC0000000; + } + else { + shortShiftUp64( + aSig0 | 0x100000, aSig1, shiftCount, &absZ, &zExtra ); + if ( 0xC0000000 < absZ ) absZ = 0xC0000000; + } + } + else { + aSig1 = aSig1 != 0; + if ( aExp < 0x3FE ) { + zExtra = aExp | aSig0 | aSig1; + absZ = 0; + } + else { + aSig0 |= 0x100000; + zExtra = ( aSig0<<( shiftCount & 31 ) ) | aSig1; + absZ = aSig0>>( - shiftCount ); + } + } + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + if ( ( (sbits32) zExtra ) < 0 ) { + ++absZ; + if ( ( zExtra + zExtra ) == 0 ) absZ &= ~1; + } + z = aSign ? - absZ : absZ; + } + else { + zExtra = zExtra != 0; + if ( aSign ) { + z = - ( absZ + ( ( roundingMode == float_round_down ) & zExtra ) ); + } + else { + z = absZ + ( ( roundingMode == float_round_up ) & zExtra ); + } + } + if ( ( aSign ^ ( z < 0 ) ) && z ) { + float_raise( float_flag_invalid ); + return aSign ? -0x80000000 : 0x7FFFFFFF; + } + if ( zExtra ) float_exception_flags |= float_flag_inexact; + return z; + +} +#endif /* unused */ + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic, except that the conversion is always rounded toward zero. If +`a' is a NaN, the largest positive integer is returned. If the conversion +overflows, the largest integer with the same sign as `a' is returned. +------------------------------------------------------------------------------- +*/ +int32 float64_to_int32_round_to_zero( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig0, aSig1; + bits32 absZ, zExtra; + int32 z; +/* uint8 roundingMode;*/ + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + shiftCount = aExp - 0x413; + if ( 0 <= shiftCount ) { + if ( 11 < shiftCount ) { + if ( ( aExp == 0x7FF ) && ( aSig0 | aSig1 ) ) aSign = 0; + absZ = 0xC0000000; + } + else { + shortShiftUp64( + aSig0 | 0x100000, aSig1, shiftCount, &absZ, &zExtra ); + } + } + else { + if ( aExp < 0x3FE ) { + zExtra = aExp | aSig0 | aSig1; + absZ = 0; + } + else { + aSig0 |= 0x100000; + zExtra = ( aSig0<<( shiftCount & 31 ) ) | aSig1; + absZ = aSig0>>( - shiftCount ); + } + } + z = aSign ? - absZ : absZ; + if ( ( aSign ^ ( z < 0 ) ) && z ) { + float_raise( float_flag_invalid ); + return aSign ? -0x80000000 : 0x7FFFFFFF; + } + if ( zExtra ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the single-precision floating-point format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. The underflow exception is raised only if the result is a +subnormal. +------------------------------------------------------------------------------- +*/ +float32 float64_to_float32( float64 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig0, aSig1, zSig; + bits32 allZero; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 ) return float64ToFloat32NaN( a ); + return packFloat32( aSign, 0xFF, 0 ); + } + shiftDown64Jamming( aSig0, aSig1, 22, &allZero, &zSig ); + if ( aExp ) zSig |= 0x40000000; + return roundAndPackFloat32( aSign, aExp - 0x3FF + 0x7E, zSig ); + +} + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Rounds the single-precision floating-point value `a' to an integer, and +returns the result as a single-precision floating-point value. The +operation is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float32 float32_round_to_int( float32 a ) +{ + flag aSign; + int16 aExp; + uint32 lastBitMask, roundBitsMask; + uint8 roundingMode; + float32 z; + + aExp = extractFloat32Exp( a ); + if ( 0x96 <= aExp ) { + if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) { + return propagateFloat32NaN( a, a ); + } + return a; + } + if ( aExp <= 0x7E ) { + if ( a<<1 == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat32Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { + return packFloat32( aSign, 0x7F, 0 ); + } + break; + case float_round_down: + return + aSign ? packFloat32( 1, 0x7F, 0 ) : packFloat32( 0, 0, 0 ); + case float_round_up: + return + aSign ? packFloat32( 1, 0, 0 ) : packFloat32( 0, 0x7F, 0 ); + } + return packFloat32( aSign, 0, 0 ); + } + lastBitMask = 1<<( 0x96 - aExp ); + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z += lastBitMask>>1; + if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z += roundBitsMask; + } + } + z &= ~ roundBitsMask; + if ( z != a ) float_exception_flags |= float_flag_inexact; + return z; + +} +#endif /* unused */ + +/* +------------------------------------------------------------------------------- +Returns the result of adding the absolute values of the single-precision +floating-point values `a' and `b'. If `zSign' is true, the sum is negated +before being returned. `zSign' is ignored if the result is a NaN. The +addition is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float32 addFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 6; + bSig <<= 6; + if ( 0 < expDiff ) { + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x20000000; + } + shiftDown32Jamming( bSig, expDiff, &bSig ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x20000000; + } + shiftDown32Jamming( aSig, - expDiff, &aSig ); + zExp = bExp; + } + else { + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); + zSig = 0x40000000 + aSig + bSig; + zExp = aExp; + goto roundAndPack; + } + aSig |= 0x20000000; + zSig = ( aSig + bSig )<<1; + --zExp; + if ( ( (sbits32) zSig ) < 0 ) { + zSig = aSig + bSig; + ++zExp; + } + roundAndPack: + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the absolute values of the single- +precision floating-point values `a' and `b'. If `zSign' is true, the +difference is negated before being returned. `zSign' is ignored if the +result is a NaN. The subtraction is performed according to the IEC/IEEE +Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 7; + bSig <<= 7; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloat32( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign ^ 1, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x40000000; + } + shiftDown32Jamming( aSig, - expDiff, &aSig ); + bSig |= 0x40000000; + bBigger: + zSig = bSig - aSig; + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x40000000; + } + shiftDown32Jamming( bSig, expDiff, &bSig ); + aSig |= 0x40000000; + aBigger: + zSig = aSig - bSig; + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the single-precision floating-point values `a' +and `b'. The operation is performed according to the IEC/IEEE Standard for +Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_add( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return addFloat32Sigs( a, b, aSign ); + } + else { + return subFloat32Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the single-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_sub( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return subFloat32Sigs( a, b, aSign ); + } + else { + return addFloat32Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of multiplying the single-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-point Arithmetic. The underflow exception is raised +only if the result is a subnormal. +------------------------------------------------------------------------------- +*/ +float32 float32_mul( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig0, zSig1; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x7F; + aSig = ( aSig | 0x800000 )<<7; + bSig = ( bSig | 0x800000 )<<8; + mul32To64( aSig, bSig, &zSig0, &zSig1 ); + zSig0 |= ( 0 < zSig1 ); + if ( 0 <= ( (sbits32) ( zSig0<<1 ) ) ) { + zSig0 += zSig0; + --zExp; + } + return roundAndPackFloat32( zSign, zExp, zSig0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of dividing the single-precision floating-point value `a' +by the corresponding value `b'. The operation is performed according to +the IEC/IEEE Standard for Binary Floating-point Arithmetic. The underflow +exception is raised only if the result is a subnormal. +------------------------------------------------------------------------------- +*/ +float32 float32_div( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + bits32 rem0, rem1; + bits32 term0, term1; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + float_raise( float_flag_divbyzero ); + return packFloat32( zSign, 0xFF, 0 ); + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x7D; + aSig = ( aSig | 0x800000 )<<7; + bSig = ( bSig | 0x800000 )<<8; + if ( bSig <= ( aSig + aSig ) ) { + aSig = aSig>>1; + ++zExp; + } + zSig = estimateDiv64To32( aSig, 0, bSig ); + if ( ( zSig & 0x3F ) <= 2 ) { + mul32To64( bSig, zSig, &term0, &term1 ); + sub64( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( ( (sbits32) rem0 ) < 0 ) { + --zSig; + add64( rem0, rem1, 0, bSig, &rem0, &rem1 ); + } + zSig |= ( 0 < rem1 ); + } + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Returns the remainder of the single-precision floating-point value `a' +with respect to the corresponding value `b'. The operation is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float32 float32_rem( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, expDiff; + bits32 aSig, bSig; + bits32 q, term0, term1, allZero, alternateASig; + sbits32 sigMean; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return a; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + expDiff = aExp - bExp; + aSig = ( aSig | 0x800000 )<<8; + bSig = ( bSig | 0x800000 )<<8; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + aSig >>= 1; + } + q = bSig <= aSig; + if ( q ) aSig -= bSig; + expDiff -= 32; + while ( 0 < expDiff ) { + q = estimateDiv64To32( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + mul32To64( bSig, q, &term0, &term1 ); + shortShiftUp64( term0, term1, 30, &term1, &allZero ); + aSig = ( aSig<<30 ) - term1; + expDiff -= 30; + } + expDiff += 32; + if ( 0 < expDiff ) { + q = estimateDiv64To32( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + q >>= 32 - expDiff; + bSig >>= 2; + mul32To64( bSig, q, &term0, &term1 ); + aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - term1; + } + else { + aSig >>= 2; + bSig >>= 2; + } + do { + alternateASig = aSig; + ++q; + aSig -= bSig; + } while ( 0 <= ( (sbits32) aSig ) ); + sigMean = aSig + alternateASig; + if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { + aSig = alternateASig; + } + zSign = ( (sbits32) aSig ) < 0; + if ( zSign ) aSig = - aSig; + return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig ); + +} +#endif /* unused */ + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Returns the square root of the single-precision floating-point value `a'. +The operation is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float32 float32_sqrt( float32 a ) +{ + flag aSign; + int16 aExp, zExp; + bits32 aSig, zSig; + bits32 rem0, rem1; + bits32 term0, term1; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, 0 ); + if ( aSign == 0 ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aSign ) { + if ( ( aExp | aSig ) == 0 ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return 0; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = ( ( aExp - 0x7F )>>1 ) + 0x7F - 1; + aSig = ( aSig | 0x800000 )<<8; + zSig = estimateSqrt32( aExp, aSig ); + zSig = ( 0xFFFFFFFD < zSig ) ? 0xFFFFFFFF : zSig + 2; + if ( ( zSig & 0x7F ) <= 5 ) { + aSig = aSig>>( aExp & 1 ); + mul32To64( zSig, zSig, &term0, &term1 ); + sub64( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( ( (sbits32) rem0 ) < 0 ) { + --zSig; + shortShiftUp64( 0, zSig, 1, &term0, &term1 ); + term1 |= 1; + add64( rem0, rem1, term0, term1, &rem0, &rem1 ); + } + zSig |= ( 0 < ( rem0 | rem1 ) ); + } + shiftDown32Jamming( zSig, 1, &zSig ); + return roundAndPackFloat32( 0, zExp, zSig ); + +} +#endif /* unused */ + +/* +------------------------------------------------------------------------------- +Returns true if the single-precision floating-point value `a' is equal +to the corresponding value `b', and false otherwise. The comparison is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_eq( float32 a, float32 b ) +{ + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return ( a == b ) || bothZeroFloat32( a, b ); + +} + +/* +------------------------------------------------------------------------------- +Returns true if the single-precision floating-point value `a' is less +than or equal to the corresponding value `b', and false otherwise. The +comparison is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_le( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || bothZeroFloat32( a, b ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns true if the single-precision floating-point value `a' is less +than the corresponding value `b', and false otherwise. The comparison is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_lt( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ! bothZeroFloat32( a, b ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Returns true if the single-precision floating-point value `a' is equal to +the corresponding value `b', and false otherwise. The invalid exception is +raised if either operand is a NaN. The comparison is performed according to +the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ + +static flag float32_eq_signaling( float32 a, float32 b ) +{ + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return ( a == b ) || bothZeroFloat32( a, b ); + +} +#endif /* unused */ + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Returns true if the single-precision floating-point value `a' is less than +or equal to the corresponding value `b', and false otherwise. Quiet NaNs +do not cause an exception. The comparison is performed according to the +IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static flag float32_le_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; +/* int16 aExp, bExp;*/ + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || bothZeroFloat32( a, b ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} +#endif /* unused */ + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Returns true if the single-precision floating-point value `a' is less than +the corresponding value `b', and false otherwise. Quiet NaNs do not cause +an exception. The comparison is performed according to the IEC/IEEE +Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static flag float32_lt_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ! bothZeroFloat32( a, b ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} +#endif /* unused */ + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Rounds the double-precision floating-point value `a' to an integer, and +returns the result as a double-precision floating-point value. The +operation is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float64 float64_round_to_int( float64 a ) +{ + flag aSign; + int16 aExp; + uint32 lastBitMask, roundBitsMask; + uint8 roundingMode; + float64 z; + + aExp = extractFloat64Exp( a ); + if ( 0x413 <= aExp ) { + if ( 0x433 <= aExp ) { + if ( ( aExp == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) { + return propagateFloat64NaN( a, a ); + } + return a; + } + lastBitMask = ( 1<<( 0x432 - aExp ) )<<1; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + if ( lastBitMask ) { + add64( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low ); + if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; + } + else { + if ( ( (sbits32) z.low ) < 0 ) { + ++z.high; + if ( ( z.low<<1 ) == 0 ) z.high &= ~1; + } + } + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat64Sign( z ) + ^ ( roundingMode == float_round_up ) ) { + add64( z.high, z.low, 0, roundBitsMask, &z.high, &z.low ); + } + } + z.low &= ~ roundBitsMask; + } + else { + if ( aExp <= 0x3FE ) { + if ( ( ( a.high<<1 ) | a.low ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat64Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FE ) + && ( extractFloat64Frac0( a ) + | extractFloat64Frac1( a ) ) + ) { + return packFloat64( aSign, 0x3FF, 0, 0 ); + } + break; + case float_round_down: + return + aSign ? packFloat64( 1, 0x3FF, 0, 0 ) + : packFloat64( 0, 0, 0, 0 ); + case float_round_up: + return + aSign ? packFloat64( 1, 0, 0, 0 ) + : packFloat64( 0, 0x3FF, 0, 0 ); + } + return packFloat64( aSign, 0, 0, 0 ); + } + lastBitMask = 1<<( 0x413 - aExp ); + roundBitsMask = lastBitMask - 1; + z.low = 0; + z.high = a.high; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z.high += lastBitMask>>1; + if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) { + z.high &= ~ lastBitMask; + } + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat64Sign( z ) + ^ ( roundingMode == float_round_up ) ) { + z.high |= ( a.low != 0 ); + z.high += roundBitsMask; + } + } + z.high &= ~ roundBitsMask; + } + if ( ( z.low != a.low ) || ( z.high != a.high ) ) { + float_exception_flags |= float_flag_inexact; + } + return z; + +} +#endif /* unused */ + +/* +------------------------------------------------------------------------------- +Returns the result of adding the absolute values of the double-precision +floating-point values `a' and `b'. If `zSign' is true, the sum is negated +before being returned. `zSign' is ignored if the result is a NaN. The +addition is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float64 addFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + int16 expDiff; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + bSig1 = extractFloat64Frac1( b ); + bSig0 = extractFloat64Frac0( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) { + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig0 |= 0x100000; + } + shiftDown64ExtraJamming( + bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FF ) { + if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0x7FF, 0, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig0 |= 0x100000; + } + shiftDown64ExtraJamming( + aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 ); + zExp = bExp; + } + else { + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 | bSig0 | bSig1 ) { + return propagateFloat64NaN( a, b ); + } + return a; + } + add64( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + if ( aExp == 0 ) return packFloat64( zSign, 0, zSig0, zSig1 ); + zSig2 = 0; + zSig0 |= 0x200000; + zExp = aExp; + goto shiftDown1; + } + aSig0 |= 0x100000; + add64( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + --zExp; + if ( zSig0 < 0x200000 ) goto roundAndPack; + ++zExp; + shiftDown1: + shiftDown64ExtraJamming( zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); + roundAndPack: + return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the absolute values of the double- +precision floating-point values `a' and `b'. If `zSign' is true, the +difference is negated before being returned. `zSign' is ignored if the +result is a NaN. The subtraction is performed according to the IEC/IEEE +Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1; + int16 expDiff; + float64 z; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + bSig1 = extractFloat64Frac1( b ); + bSig0 = extractFloat64Frac0( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + shortShiftUp64( aSig0, aSig1, 10, &aSig0, &aSig1 ); + shortShiftUp64( bSig0, bSig1, 10, &bSig0, &bSig1 ); + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 | bSig0 | bSig1 ) { + return propagateFloat64NaN( a, b ); + } + float_raise( float_flag_invalid ); + z.low = float64_default_nan_low; + z.high = float64_default_nan_high; + return z; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig0 < aSig0 ) goto aBigger; + if ( aSig0 < bSig0 ) goto bBigger; + if ( bSig1 < aSig1 ) goto aBigger; + if ( aSig1 < bSig1 ) goto bBigger; + return packFloat64( float_rounding_mode == float_round_down, 0, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FF ) { + if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign ^ 1, 0x7FF, 0, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig0 |= 0x40000000; + } + shiftDown64Jamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); + bSig0 |= 0x40000000; + bBigger: + sub64( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 ); + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig0 |= 0x40000000; + } + shiftDown64Jamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 ); + aSig0 |= 0x40000000; + aBigger: + sub64( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat64( zSign, zExp - 10, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the double-precision floating-point values `a' +and `b'. The operation is performed according to the IEC/IEEE Standard for +Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_add( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return addFloat64Sigs( a, b, aSign ); + } + else { + return subFloat64Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the double-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_sub( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return subFloat64Sigs( a, b, aSign ); + } + else { + return addFloat64Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of multiplying the double-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-point Arithmetic. The underflow exception is raised +only if the result is a subnormal. +------------------------------------------------------------------------------- +*/ +float64 float64_mul( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3; + float64 z; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig1 = extractFloat64Frac1( b ); + bSig0 = extractFloat64Frac0( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( ( aSig0 | aSig1 ) + || ( ( bExp == 0x7FF ) && ( bSig0 | bSig1 ) ) ) { + return propagateFloat64NaN( a, b ); + } + if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid; + return packFloat64( zSign, 0x7FF, 0, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b ); + if ( ( aExp | aSig0 | aSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float64_default_nan_low; + z.high = float64_default_nan_high; + return z; + } + return packFloat64( zSign, 0x7FF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat64( zSign, 0, 0, 0 ); + normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) return packFloat64( zSign, 0, 0, 0 ); + normalizeFloat64Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + zExp = aExp + bExp - 0x3FF - 1; + aSig0 |= 0x100000; + shortShiftUp64( bSig0, bSig1, 12, &bSig0, &bSig1 ); + mul64To128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 ); + add64( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 ); + zSig2 |= ( 0 < zSig3 ); + if ( 0x200000 <= zSig0 ) { + shiftDown64ExtraJamming( + zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); + ++zExp; + } + return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of dividing the double-precision floating-point value `a' +by the corresponding value `b'. The operation is performed according to +the IEC/IEEE Standard for Binary Floating-point Arithmetic. The underflow +exception is raised only if the result is a subnormal. +------------------------------------------------------------------------------- +*/ +float64 float64_div( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + bits32 rem0, rem1, rem2, rem3; + bits32 term0, term1, term2, term3; + float64 z; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig1 = extractFloat64Frac1( b ); + bSig0 = extractFloat64Frac0( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, b ); + if ( bExp == 0x7FF ) { + if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b ); + goto invalid; + } + return packFloat64( zSign, 0x7FF, 0, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0, 0, 0 ); + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) { + if ( ( aExp | aSig0 | aSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float64_default_nan_low; + z.high = float64_default_nan_high; + return z; + } + float_raise( float_flag_divbyzero ); + return packFloat64( zSign, 0x7FF, 0, 0 ); + } + normalizeFloat64Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat64( zSign, 0, 0, 0 ); + normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + zExp = aExp - bExp + 0x3FE - 1; + shortShiftUp64( aSig0 | 0x100000, aSig1, 11, &aSig0, &aSig1 ); + shortShiftUp64( bSig0 | 0x100000, bSig1, 11, &bSig0, &bSig1 ); + if ( le64( bSig0, bSig1, aSig0, aSig1 ) ) { + shiftDown64( aSig0, aSig1, 1, &aSig0, &aSig1 ); + ++zExp; + } + zSig0 = estimateDiv64To32( aSig0, aSig1, bSig0 ); + mul64By32To96( bSig0, bSig1, zSig0, &term0, &term1, &term2 ); + sub96( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 ); + while ( ( (sbits32) rem0 ) < 0 ) { + --zSig0; + add96( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 ); + } + zSig1 = estimateDiv64To32( rem1, rem2, bSig0 ); + if ( ( zSig1 & 0x3FF ) <= 4 ) { + mul64By32To96( bSig0, bSig1, zSig1, &term1, &term2, &term3 ); + sub96( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 ); + while ( ( (sbits32) rem1 ) < 0 ) { + --zSig1; + add96( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( 0 < ( rem1 | rem2 | rem3 ) ); + } + shiftDown64ExtraJamming( zSig0, zSig1, 0, 11, &zSig0, &zSig1, &zSig2 ); + return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Returns the remainder of the double-precision floating-point value `a' +with respect to the corresponding value `b'. The operation is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float64 float64_rem( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, expDiff; + bits32 aSig0, aSig1, bSig0, bSig1; + bits32 q, term0, term1, term2, allZero, alternateASig0, alternateASig1; + bits32 sigMean1; + sbits32 sigMean0; + float64 z; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig1 = extractFloat64Frac1( b ); + bSig0 = extractFloat64Frac0( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + if ( aExp == 0x7FF ) { + if ( ( aSig0 | aSig1 ) + || ( ( bExp == 0x7FF ) && ( bSig0 | bSig1 ) ) ) { + return propagateFloat64NaN( a, b ); + } + goto invalid; + } + if ( bExp == 0x7FF ) { + if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float64_default_nan_low; + z.high = float64_default_nan_high; + return z; + } + normalizeFloat64Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return a; + normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + expDiff = aExp - bExp; + if ( expDiff < -1 ) return a; + shortShiftUp64( + aSig0 | 0x100000, aSig1, 11 - ( expDiff < 0 ), &aSig0, &aSig1 ); + shortShiftUp64( bSig0 | 0x100000, bSig1, 11, &bSig0, &bSig1 ); + q = le64( bSig0, bSig1, aSig0, aSig1 ); + if ( q ) sub64( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); + expDiff -= 32; + while ( 0 < expDiff ) { + q = estimateDiv64To32( aSig0, aSig1, bSig0 ); + q = ( 4 < q ) ? q - 4 : 0; + mul64By32To96( bSig0, bSig1, q, &term0, &term1, &term2 ); + shortShiftUp96( term0, term1, term2, 29, &term1, &term2, &allZero ); + shortShiftUp64( aSig0, aSig1, 29, &aSig0, &allZero ); + sub64( aSig0, 0, term1, term2, &aSig0, &aSig1 ); + expDiff -= 29; + } + if ( -32 < expDiff ) { + q = estimateDiv64To32( aSig0, aSig1, bSig0 ); + q = ( 4 < q ) ? q - 4 : 0; + q >>= - expDiff; + shiftDown64( bSig0, bSig1, 8, &bSig0, &bSig1 ); + expDiff += 24; + if ( expDiff < 0 ) { + shiftDown64( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); + } + else { + shortShiftUp64( aSig0, aSig1, expDiff, &aSig0, &aSig1 ); + } + mul64By32To96( bSig0, bSig1, q, &term0, &term1, &term2 ); + sub64( aSig0, aSig1, term1, term2, &aSig0, &aSig1 ); + } + else { + shiftDown64( aSig0, aSig1, 8, &aSig0, &aSig1 ); + shiftDown64( bSig0, bSig1, 8, &bSig0, &bSig1 ); + } + do { + alternateASig0 = aSig0; + alternateASig1 = aSig1; + ++q; + sub64( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); + } while ( 0 <= ( (sbits32) aSig0 ) ); + add64( + aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 ); + if ( ( sigMean0 < 0 ) + || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) { + aSig0 = alternateASig0; + aSig1 = alternateASig1; + } + zSign = ( (sbits32) aSig0 ) < 0; + if ( zSign ) sub64( 0, 0, aSig0, aSig1, &aSig0, &aSig1 ); + return + normalizeRoundAndPackFloat64( aSign ^ zSign, bExp - 4, aSig0, aSig1 ); + +} +#endif /* unused */ + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Returns the square root of the double-precision floating-point value `a'. +The operation is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float64 float64_sqrt( float64 a ) +{ + flag aSign; + int16 aExp, zExp; + bits32 aSig0, aSig1, zSig0, zSig1, zSig2; + bits32 rem0, rem1, rem2, rem3; + bits32 term0, term1, term2, term3; + bits32 shiftedRem0, shiftedRem1; + float64 z; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, a ); + if ( aSign == 0 ) return a; + goto invalid; + } + if ( aSign ) { + if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a; + invalid: + float_raise( float_flag_invalid ); + z.low = float64_default_nan_low; + z.high = float64_default_nan_high; + return z; + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat64( 0, 0, 0, 0 ); + normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FF - 1; + shortShiftUp64( aSig0 | 0x100000, aSig1, 11, &aSig0, &aSig1 ); + zSig0 = estimateSqrt32( aExp, aSig0 ); + zSig0 = ( 0xFFFFFFFD < zSig0 ) ? 0xFFFFFFFF : zSig0 + 2; + if ( aExp & 1 ) shiftDown64( aSig0, aSig1, 1, &aSig0, &aSig1 ); + mul32To64( zSig0, zSig0, &term0, &term1 ); + sub64( aSig0, aSig1, term0, term1, &rem0, &rem1 ); + while ( ( (sbits32) rem0 ) < 0 ) { + --zSig0; + shortShiftUp64( 0, zSig0, 1, &term0, &term1 ); + term1 |= 1; + add64( rem0, rem1, term0, term1, &rem0, &rem1 ); + } + shortShiftUp64( rem0, rem1, 31, &shiftedRem0, &shiftedRem1 ); + zSig1 = estimateDiv64To32( shiftedRem0, shiftedRem1, zSig0 ); + if ( ( zSig1 & 0x3FF ) <= 5 ) { + if ( zSig1 == 0 ) zSig1 = 1; + mul32To64( zSig0, zSig1, &term1, &term2 ); + shortShiftUp64( term1, term2, 1, &term1, &term2 ); + sub64( rem1, 0, term1, term2, &rem1, &rem2 ); + mul32To64( zSig1, zSig1, &term2, &term3 ); + sub96( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); + while ( ( (sbits32) rem1 ) < 0 ) { + --zSig1; + shortShiftUp96( 0, zSig0, zSig1, 1, &term1, &term2, &term3 ); + term3 |= 1; + add96( rem1, rem2, rem3, term1, term2, term3, + &rem1, &rem2, &rem3 ); + } + zSig1 |= ( 0 < ( rem1 | rem2 | rem3 ) ); + } + shiftDown64ExtraJamming( zSig0, zSig1, 0, 11, &zSig0, &zSig1, &zSig2 ); + return roundAndPackFloat64( 0, zExp, zSig0, zSig1, zSig2 ); + +} +#endif /* unused */ + +/* +------------------------------------------------------------------------------- +Returns true if the double-precision floating-point value `a' is equal +to the corresponding value `b', and false otherwise. The comparison is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_eq( float64 a, float64 b ) +{ + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) + && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) || bothZeroFloat64( a, b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns true if the double-precision floating-point value `a' is less +than or equal to the corresponding value `b', and false otherwise. The +comparison is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_le( float64 a, float64 b ) +{ + bits32 a0, a1, b0, b1; + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) + && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + a1 = a.low; + a0 = a.high; + aSign = extractFloat64Sign( a ); + b1 = b.low; + b0 = b.high; + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign || bothZeroFloat64( a, b ); + return aSign ? le64( b0, b1, a0, a1 ) : le64( a0, a1, b0, b1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns true if the double-precision floating-point value `a' is less +than the corresponding value `b', and false otherwise. The comparison is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_lt( float64 a, float64 b ) +{ + bits32 a0, a1, b0, b1; + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) + && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + a1 = a.low; + a0 = a.high; + aSign = extractFloat64Sign( a ); + b1 = b.low; + b0 = b.high; + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign && ! bothZeroFloat64( a, b ); + return aSign ? lt64( b0, b1, a0, a1 ) : lt64( a0, a1, b0, b1 ); + +} + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Returns true if the double-precision floating-point value `a' is equal to +the corresponding value `b', and false otherwise. The invalid exception is +raised if either operand is a NaN. The comparison is performed according to +the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static flag float64_eq_signaling( float64 a, float64 b ) +{ + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) + && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) || bothZeroFloat64( a, b ) ); + +} +#endif /* unused */ + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Returns true if the double-precision floating-point value `a' is less than +or equal to the corresponding value `b', and false otherwise. Quiet NaNs +do not cause an exception. The comparison is performed according to the +IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static flag float64_le_quiet( float64 a, float64 b ) +{ + bits32 a0, a1, b0, b1; + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) + && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + a1 = a.low; + a0 = a.high; + aSign = extractFloat64Sign( a ); + b1 = b.low; + b0 = b.high; + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign || bothZeroFloat64( a, b ); + return aSign ? le64( b0, b1, a0, a1 ) : le64( a0, a1, b0, b1 ); + +} +#endif /* unused */ + +#if 0 /* unused */ +/* +------------------------------------------------------------------------------- +Returns true if the double-precision floating-point value `a' is less than +the corresponding value `b', and false otherwise. Quiet NaNs do not cause +an exception. The comparison is performed according to the IEC/IEEE +Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static flag float64_lt_quiet( float64 a, float64 b ) +{ + bits32 a0, a1, b0, b1; + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) + && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + a1 = a.low; + a0 = a.high; + aSign = extractFloat64Sign( a ); + b1 = b.low; + b0 = b.high; + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign && ! bothZeroFloat64( a, b ); + return aSign ? lt64( b0, b1, a0, a1 ) : lt64( a0, a1, b0, b1 ); + +} +#endif /* unused */ + +/* This code isn't needed for GCC 2.95 */ +#if !((defined(__GNUC__) && __GNUC__ == 2 && \ + defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 95) || \ + (defined(__GNUC__) && __GNUC__ > 2)) +/* + * These two routines are not part of the original softfloat distribution. + * + * They are based on the corresponding conversions to integer but return + * unsigned numbers instead since these functions are required by GCC. + * + * Added by Mark Brinicombe <mark@netbsd.org> 27/09/97 + */ + + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the 32-bit unsigned integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic, except that the conversion is always rounded toward zero. If +`a' is a NaN, the largest positive integer is returned. If the conversion +overflows, the largest integer positive is returned. +------------------------------------------------------------------------------- +*/ +uint32 float64_to_uint32_round_to_zero( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig0, aSig1; + bits32 absZ, zExtra; + uint32 z; +/* uint8 roundingMode;*/ + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + + if (aSign) { + float_raise( float_flag_invalid ); + return(0); + } + + shiftCount = aExp - 0x413; + if ( 0 <= shiftCount ) { + if ( 11 < shiftCount ) { + absZ = 0xFFFFFFFF; + } + else { + shortShiftUp64( + aSig0 | 0x100000, aSig1, shiftCount, &absZ, &zExtra ); + } + } + else { + if ( aExp < 0x3FE ) { + zExtra = aExp | aSig0 | aSig1; + absZ = 0; + } + else { + aSig0 |= 0x100000; + zExtra = ( aSig0<<( shiftCount & 31 ) ) | aSig1; + absZ = aSig0>>( - shiftCount ); + } + } + z = absZ; + if ( zExtra ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the 32-bit unsigned integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic, except that the conversion is always rounded toward zero. If +`a' is a NaN, the largest positive integer is returned. If the conversion +overflows, the largest positive integer is returned. +------------------------------------------------------------------------------- +*/ +uint32 float32_to_uint32_round_to_zero( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + uint32 z; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + shiftCount = aExp - 0x9E; + + if (aSign) { + float_raise( float_flag_invalid ); + return(0); + } + if ( 0 < shiftCount ) { + float_raise( float_flag_invalid ); + return 0xFFFFFFFF; + } + else if ( aExp <= 0x7E ) { + if ( aExp | aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig = ( aSig | 0x800000 )<<8; + z = aSig>>( - shiftCount ); + if ( aSig<<( shiftCount & 31 ) ) { + float_exception_flags |= float_flag_inexact; + } + return z; + +} +#endif /* GCC >= 2.95 */ diff --git a/lib/libc/arch/arm26/fplib/softfloat.h b/lib/libc/arch/arm26/fplib/softfloat.h new file mode 100644 index 00000000000..a12b03e22d7 --- /dev/null +++ b/lib/libc/arch/arm26/fplib/softfloat.h @@ -0,0 +1,166 @@ +/* $NetBSD: softfloat.h,v 1.1 2000/05/09 21:55:46 bjh21 Exp $ */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 1a. + +Written by John R. Hauser. This work was made possible by the International +Computer Science Institute, located at Suite 600, 1947 Center Street, +Berkeley, California 94704. Funding was provided in part by the National +Science Foundation under grant MIP-9311980. The original version of +this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the web page `http://www.cs.berkeley.edu/~jhauser/ +softfloat.html'. + +THIS PACKAGE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS PACKAGE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS PACKAGE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY AND ALL +LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these three paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +#include <machine/ieeefp.h> + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point types. +------------------------------------------------------------------------------- +*/ +typedef unsigned int float32; +typedef struct { + unsigned int high; + unsigned int low; +} float64; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point rounding mode and exception flags. +------------------------------------------------------------------------------- +*/ +extern unsigned char float_rounding_mode; +extern unsigned char float_exception_flags; + +/* +------------------------------------------------------------------------------- +Floating-point rounding mode codes. +------------------------------------------------------------------------------- +*/ +enum { + float_round_nearest_even = FP_RN, + float_round_up = FP_RP, + float_round_down = FP_RM, + float_round_to_zero = FP_RZ +}; + +/* +------------------------------------------------------------------------------- +Floating-point exception flag masks. +------------------------------------------------------------------------------- +*/ +enum { + float_flag_invalid = FP_X_INV, + float_flag_divbyzero = FP_X_DZ, + float_flag_overflow = FP_X_OFL, + float_flag_underflow = FP_X_UFL, + float_flag_inexact = FP_X_IMP +}; + +/* +------------------------------------------------------------------------------- +Floating-point underflow tininess-detection mode. +------------------------------------------------------------------------------- +*/ +extern char float_detect_tininess; +enum { + float_tininess_before_rounding = 0, + float_tininess_after_rounding = 1 +}; + +/* +------------------------------------------------------------------------------- +Routine to raise any or all of the software IEC/IEEE floating-point +exception flags. +------------------------------------------------------------------------------- +*/ +void float_raise( unsigned char ); + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point conversion routines. +------------------------------------------------------------------------------- +*/ +float32 int32_to_float32( int ); +float64 int32_to_float64( int ); +#if 0 /* unused */ +static int float32_to_int32( float32 ); +#endif +int float32_to_int32_round_to_zero( float32 ); +float64 float32_to_float64( float32 ); +#if 0 /* unused */ +static int float64_to_int32( float64 ); +#endif +int float64_to_int32_round_to_zero( float64 ); +float32 float64_to_float32( float64 ); +unsigned int float64_to_uint32_round_to_zero( float64 a ); +unsigned int float32_to_uint32_round_to_zero( float32 a ); + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision operations. +------------------------------------------------------------------------------- +*/ +#if 0 /* unused */ +static float32 float32_round_to_int( float32 ); +#endif +float32 float32_add( float32, float32 ); +float32 float32_sub( float32, float32 ); +float32 float32_mul( float32, float32 ); +float32 float32_div( float32, float32 ); +#if 0 /* unused */ +static float32 float32_rem( float32, float32 ); +static float32 float32_sqrt( float32 ); +#endif +char float32_eq( float32, float32 ); +char float32_le( float32, float32 ); +char float32_lt( float32, float32 ); +#if 0 /* unused */ +static char float32_eq_signaling( float32, float32 ); +static char float32_le_quiet( float32, float32 ); +static char float32_lt_quiet( float32, float32 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision operations. +------------------------------------------------------------------------------- +*/ +#if 0 /* unused */ +static float64 float64_round_to_int( float64 ); +#endif +float64 float64_add( float64, float64 ); +float64 float64_sub( float64, float64 ); +float64 float64_mul( float64, float64 ); +float64 float64_div( float64, float64 ); +#if 0 /* unused */ +static float64 float64_rem( float64, float64 ); +static float64 float64_sqrt( float64 ); +#endif +char float64_eq( float64, float64 ); +char float64_le( float64, float64 ); +char float64_lt( float64, float64 ); +#if 0 /* unused */ +char float64_eq_signaling( float64, float64 ); +#endif +char float64_le_quiet( float64, float64 ); +char float64_lt_quiet( float64, float64 ); diff --git a/lib/libc/arch/arm26/gen/Makefile.inc b/lib/libc/arch/arm26/gen/Makefile.inc new file mode 100644 index 00000000000..4c8e9fa7e02 --- /dev/null +++ b/lib/libc/arch/arm26/gen/Makefile.inc @@ -0,0 +1,13 @@ +# $NetBSD: Makefile.inc,v 1.1 2000/05/09 21:55:47 bjh21 Exp $ + +SRCS+= alloca.S byte_swap_2.S byte_swap_4.S bswap64.c divsi3.S \ + fabs.c flt_rounds.c fpgetround.c fpsetround.c \ + fpgetmask.S fpsetmask.S fpgetsticky.S fpsetsticky.S \ + infinity.c isinf.c isnan.c frexp.c ldexp.c modf.c nanf.c + +SRCS+= setjmp.S __setjmp14.S +SRCS+= _setjmp.S +SRCS+= sigsetjmp.S __sigsetjmp14.S + +LSRCS+= Lint_bswap16.c Lint_bswap32.c +DPSRCS+= Lint_bswap16.c Lint_bswap32.c diff --git a/lib/libc/arch/arm26/gen/__setjmp14.S b/lib/libc/arch/arm26/gen/__setjmp14.S new file mode 100644 index 00000000000..d735d58648e --- /dev/null +++ b/lib/libc/arch/arm26/gen/__setjmp14.S @@ -0,0 +1,130 @@ +/* $NetBSD: __setjmp14.S,v 1.1 2000/05/09 21:55:47 bjh21 Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * 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 Mark Brinicombe + * 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 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> +#include <machine/setjmp.h> + +/* + * C library -- setjmp, longjmp + * + * longjmp(a,v) + * will generate a "return(v)" from the last call to + * setjmp(a) + * by restoring registers from the stack. + * The previous signal state is restored. + */ + +ENTRY(__setjmp14) + /* Get the signal mask. */ + stmfd r13!, {r0-r2, r14} + add r2, r0, #(_JB_SIGMASK * 4) + mov r1, #0x00000000 + mov r0, #0x00000000 + bl _C_FUNC(__sigprocmask14) + ldmfd r13!, {r0-r2, r14} + + ldr r1, Lsetjmp_magic + str r1, [r0], #4 + +#ifdef SOFTFLOAT + add r0, r0, #52 +#else + /* Store fp registers */ + sfm f4, 4, [r0], #48 + /* Store fpsr */ + rfs r1 + str r1, [r0], #0x0004 +#endif /*SOFTFLOAT*/ + /* Store integer registers */ + stmia r0, {r4-r14} + mov r0, #0x00000000 +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif + +Lsetjmp_magic: + .word _JB_MAGIC_SETJMP + + +ENTRY(__longjmp14) + ldr r2, Lsetjmp_magic + ldr r3, [r0] + teq r2, r3 + bne botch + + /* Restore the signal mask. */ + stmfd r13!, {r0-r2, r14} + mov r2, #0x00000000 + add r1, r0, #(_JB_SIGMASK * 4) + mov r0, #3 /* SIG_SETMASK */ + bl _C_FUNC(__sigprocmask14) + ldmfd r13!, {r0-r2, r14} + + add r0, r0, #4 +#ifdef SOFTFLOAT + add r0, r0, #52 +#else + /* Restore fp registers */ + lfm f4, 4, [r0], #48 + /* Restore FPSR */ + ldr r4, [r0], #0x0004 + wfs r4 +#endif /* SOFTFLOAT */ + /* Restore integer registers */ + ldmia r0, {r4-r14} + + /* Validate r13 and r14 */ + teq r13, #0 + beq botch + teq r14, #0 + beq botch + + /* Set return value */ + + mov r0, r1 + teq r0, #0x00000000 + moveq r0, #0x00000001 +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif + + /* validation failed, die die die. */ +botch: + bl _C_FUNC(longjmperror) + bl _C_FUNC(abort) + b . - 8 /* Cannot get here */ diff --git a/lib/libc/arch/arm26/gen/__sigsetjmp14.S b/lib/libc/arch/arm26/gen/__sigsetjmp14.S new file mode 100644 index 00000000000..debc39d416f --- /dev/null +++ b/lib/libc/arch/arm26/gen/__sigsetjmp14.S @@ -0,0 +1,61 @@ +/* $NetBSD: __sigsetjmp14.S,v 1.1 2000/05/09 21:55:47 bjh21 Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * 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 Mark Brinicombe + * 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 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> +#include <machine/setjmp.h> + +/* + * C library -- sigsetjmp, siglongjmp + * + * longjmp(a,v) + * will generate a "return(v)" from the last call to + * setjmp(a, m) + * by restoring registers from the stack. + * The previous signal state is restored. + */ + +ENTRY(__sigsetjmp14) + teq r1, #0 + beq _C_FUNC(_setjmp) + b _C_FUNC(__setjmp14) + +L_setjmp_magic: + .word _JB_MAGIC__SETJMP + +ENTRY(__siglongjmp14) + ldr r2, L_setjmp_magic + ldr r3, [r0] + teq r2, r3 + beq _C_FUNC(_longjmp) + b _C_FUNC(__longjmp14) diff --git a/lib/libc/arch/arm26/gen/_setjmp.S b/lib/libc/arch/arm26/gen/_setjmp.S new file mode 100644 index 00000000000..27c7d7cfb50 --- /dev/null +++ b/lib/libc/arch/arm26/gen/_setjmp.S @@ -0,0 +1,114 @@ +/* $NetBSD: _setjmp.S,v 1.1 2000/05/09 21:55:47 bjh21 Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * 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 Mark Brinicombe + * 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 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> +#include <machine/setjmp.h> + +/* + * C library -- _setjmp, _longjmp + * + * _longjmp(a,v) + * will generate a "return(v)" from the last call to + * _setjmp(a) + * by restoring registers from the stack. + * The previous signal state is NOT restored. + * + * Note: r0 is the return value + * r1-r3 are scratch registers in functions + */ + +ENTRY(_setjmp) + ldr r1, L_setjmp_magic + str r1, [r0], #4 +#ifdef SOFTFLOAT + add r0, r0, #52 +#else + /* Store fp registers */ + sfm f4, 4, [r0], #48 + /* Store fpsr */ + rfs r1 + str r1, [r0], #0x0004 +#endif /* SOFTFLOAT */ + /* Store integer registers */ + stmia r0, {r4-r14} + + mov r0, #0x00000000 +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif + +L_setjmp_magic: + .word _JB_MAGIC__SETJMP + +ENTRY(_longjmp) + ldr r2, L_setjmp_magic + ldr r3, [r0], #4 + teq r2, r3 + bne botch + +#ifdef SOFTFLOAT + add r0, r0, #52 +#else + /* Restore fp registers */ + lfm f4, 4, [r0], #48 + /* Restore fpsr */ + ldr r4, [r0], #0x0004 + wfs r4 +#endif /* SOFTFLOAT */ + /* Restore integer registers */ + ldmia r0, {r4-r14} + + /* Validate r13 and r14 */ + teq r13, #0 + beq botch + teq r14, #0 + beq botch + + /* Set return value */ + mov r0, r1 + teq r0, #0x00000000 + moveq r0, #0x00000001 +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif + + /* validation failed, die die die. */ +botch: + bl _C_FUNC(longjmperror) + bl _C_FUNC(abort) + b . - 8 /* Cannot get here */ diff --git a/lib/libc/arch/arm26/gen/alloca.S b/lib/libc/arch/arm26/gen/alloca.S new file mode 100644 index 00000000000..bc5ddb42e33 --- /dev/null +++ b/lib/libc/arch/arm26/gen/alloca.S @@ -0,0 +1,48 @@ +/* $NetBSD: alloca.S,v 1.1 2000/05/09 21:55:47 bjh21 Exp $ */ + +/* + * Copyright (c) 1995 Mark Brinicombe + * 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 Mark Brinicombe + * 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 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. + */ + +/* like alloc, but automatic automatic free in return */ + +#include <machine/asm.h> + +ENTRY(alloca) + add r0, r0, #0x00000003 /* round up to next word */ + bic r0, r0, #0x00000003 + sub r13, r13, r0 /* Adjust the stack pointer */ + mov r0, r13 /* r0 = base of new space */ +#ifdef __APCS_26__ + movs r15, r14 /* return */ +#else + mov r15, r14 /* return */ +#endif diff --git a/lib/libc/arch/arm26/gen/byte_swap_2.S b/lib/libc/arch/arm26/gen/byte_swap_2.S new file mode 100644 index 00000000000..4280571f30c --- /dev/null +++ b/lib/libc/arch/arm26/gen/byte_swap_2.S @@ -0,0 +1,53 @@ +/* $NetBSD: byte_swap_2.S,v 1.1 2000/05/09 21:55:47 bjh21 Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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> + +_BEGIN_ENTRY; +_ENTRY(_C_FUNC(__bswap16)); +_ENTRY(_C_FUNC(ntohs)); +_ENTRY(_C_FUNC(htons)); +_END_ENTRY + and r1, r0, #0xFF00 + mov r0, r0, lsl #8 + orr r0, r0, r1, lsr #8 +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif
\ No newline at end of file diff --git a/lib/libc/arch/arm26/gen/byte_swap_4.S b/lib/libc/arch/arm26/gen/byte_swap_4.S new file mode 100644 index 00000000000..35206c9d534 --- /dev/null +++ b/lib/libc/arch/arm26/gen/byte_swap_4.S @@ -0,0 +1,54 @@ +/* $NetBSD: byte_swap_4.S,v 1.1 2000/05/09 21:55:47 bjh21 Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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> + +_BEGIN_ENTRY; +_ENTRY(_C_FUNC(__bswap32)); +_ENTRY(_C_FUNC(ntohl)); +_ENTRY(_C_FUNC(htonl)); +_END_ENTRY + eor r1, r0, r0, ror #16 + bic r1, r1, #0x00FF0000 + mov r0, r0, ror #8 + eor r0, r0, r1, lsr #8 +#ifdef __APCS_26__ + movs pc,lr +#else + mov pc, lr +#endif
\ No newline at end of file diff --git a/lib/libc/arch/arm26/gen/divsi3.S b/lib/libc/arch/arm26/gen/divsi3.S new file mode 100644 index 00000000000..3d72d0a16c7 --- /dev/null +++ b/lib/libc/arch/arm26/gen/divsi3.S @@ -0,0 +1,398 @@ +/* $NetBSD: divsi3.S,v 1.1 2000/05/09 21:55:47 bjh21 Exp $ */ + +/* + * 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> + +ENTRY(__umodsi3) + stmfd sp!, {lr} + bl L_udivide + mov r0, r1 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else /* APCS-32 */ + ldmfd sp!, {pc} +#endif + +ENTRY(__modsi3) + stmfd sp!, {lr} + bl L_divide + mov r0, r1 +#ifdef __APCS_26__ + ldmfd sp!, {pc}^ +#else + ldmfd sp!, {pc} +#endif + +L_overflow: +#if 0 /* FIXME */ + mov r0, #8 /* SIGFPE */ + bl _C_FUNC(raise) /* raise it */ +#endif + mov r0, #0 +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif + +ENTRY(__udivsi3) +L_udivide: /* r0 = r0 / r1; r1 = r0 % r1 */ + eor r0, r1, r0 + eor r1, r0, r1 + eor r0, r1, r0 + /* r0 = r1 / r0; r1 = r1 % r0 */ + cmp r0, #1 + bcc L_overflow + beq L_divide_l0 + mov ip, #0 + movs r1, r1 + bpl L_divide_l1 + orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */ + movs r1, r1, lsr #1 + orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */ + b L_divide_l1 + +L_divide_l0: /* r0 == 1 */ + mov r0, r1 + mov r1, #0 +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif + +ENTRY(__divsi3) +L_divide: /* r0 = r0 / r1; r1 = r0 % r1 */ + eor r0, r1, r0 + eor r1, r0, r1 + eor r0, r1, r0 + /* r0 = r1 / r0; r1 = r1 % r0 */ + cmp r0, #1 + bcc L_overflow + beq L_divide_l0 + ands ip, r0, #0x80000000 + rsbmi r0, r0, #0 + ands r2, r1, #0x80000000 + eor ip, ip, r2 + rsbmi r1, r1, #0 + orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */ + /* ip bit 0x80000000 = -ve remainder */ + +L_divide_l1: + mov r2, #1 + mov r3, #0 + + /* + * If the highest bit of the dividend is set, we have to be + * careful when shifting the divisor. Test this. + */ + movs r1,r1 + bpl L_old_code + + /* + * At this point, the highest bit of r1 is known to be set. + * We abuse this below in the tst instructions. + */ + tst r1, r0 /*, lsl #0 */ + bmi L_divide_b1 + tst r1, r0, lsl #1 + bmi L_divide_b2 + tst r1, r0, lsl #2 + bmi L_divide_b3 + tst r1, r0, lsl #3 + bmi L_divide_b4 + tst r1, r0, lsl #4 + bmi L_divide_b5 + tst r1, r0, lsl #5 + bmi L_divide_b6 + tst r1, r0, lsl #6 + bmi L_divide_b7 + tst r1, r0, lsl #7 + bmi L_divide_b8 + tst r1, r0, lsl #8 + bmi L_divide_b9 + tst r1, r0, lsl #9 + bmi L_divide_b10 + tst r1, r0, lsl #10 + bmi L_divide_b11 + tst r1, r0, lsl #11 + bmi L_divide_b12 + tst r1, r0, lsl #12 + bmi L_divide_b13 + tst r1, r0, lsl #13 + bmi L_divide_b14 + tst r1, r0, lsl #14 + bmi L_divide_b15 + tst r1, r0, lsl #15 + bmi L_divide_b16 + tst r1, r0, lsl #16 + bmi L_divide_b17 + tst r1, r0, lsl #17 + bmi L_divide_b18 + tst r1, r0, lsl #18 + bmi L_divide_b19 + tst r1, r0, lsl #19 + bmi L_divide_b20 + tst r1, r0, lsl #20 + bmi L_divide_b21 + tst r1, r0, lsl #21 + bmi L_divide_b22 + tst r1, r0, lsl #22 + bmi L_divide_b23 + tst r1, r0, lsl #23 + bmi L_divide_b24 + tst r1, r0, lsl #24 + bmi L_divide_b25 + tst r1, r0, lsl #25 + bmi L_divide_b26 + tst r1, r0, lsl #26 + bmi L_divide_b27 + tst r1, r0, lsl #27 + bmi L_divide_b28 + tst r1, r0, lsl #28 + bmi L_divide_b29 + tst r1, r0, lsl #29 + bmi L_divide_b30 + tst r1, r0, lsl #30 + bmi L_divide_b31 +/* + * instead of: + * tst r1, r0, lsl #31 + * bmi L_divide_b32 + */ + b L_divide_b32 + +L_old_code: + cmp r1, r0 + bcc L_divide_b0 + cmp r1, r0, lsl #1 + bcc L_divide_b1 + cmp r1, r0, lsl #2 + bcc L_divide_b2 + cmp r1, r0, lsl #3 + bcc L_divide_b3 + cmp r1, r0, lsl #4 + bcc L_divide_b4 + cmp r1, r0, lsl #5 + bcc L_divide_b5 + cmp r1, r0, lsl #6 + bcc L_divide_b6 + cmp r1, r0, lsl #7 + bcc L_divide_b7 + cmp r1, r0, lsl #8 + bcc L_divide_b8 + cmp r1, r0, lsl #9 + bcc L_divide_b9 + cmp r1, r0, lsl #10 + bcc L_divide_b10 + cmp r1, r0, lsl #11 + bcc L_divide_b11 + cmp r1, r0, lsl #12 + bcc L_divide_b12 + cmp r1, r0, lsl #13 + bcc L_divide_b13 + cmp r1, r0, lsl #14 + bcc L_divide_b14 + cmp r1, r0, lsl #15 + bcc L_divide_b15 + cmp r1, r0, lsl #16 + bcc L_divide_b16 + cmp r1, r0, lsl #17 + bcc L_divide_b17 + cmp r1, r0, lsl #18 + bcc L_divide_b18 + cmp r1, r0, lsl #19 + bcc L_divide_b19 + cmp r1, r0, lsl #20 + bcc L_divide_b20 + cmp r1, r0, lsl #21 + bcc L_divide_b21 + cmp r1, r0, lsl #22 + bcc L_divide_b22 + cmp r1, r0, lsl #23 + bcc L_divide_b23 + cmp r1, r0, lsl #24 + bcc L_divide_b24 + cmp r1, r0, lsl #25 + bcc L_divide_b25 + cmp r1, r0, lsl #26 + bcc L_divide_b26 + cmp r1, r0, lsl #27 + bcc L_divide_b27 + cmp r1, r0, lsl #28 + bcc L_divide_b28 + cmp r1, r0, lsl #29 + bcc L_divide_b29 + cmp r1, r0, lsl #30 + bcc L_divide_b30 +L_divide_b32: + cmp r1, r0, lsl #31 + subhs r1, r1,r0, lsl #31 + addhs r3, r3,r2, lsl #31 +L_divide_b31: + cmp r1, r0, lsl #30 + subhs r1, r1,r0, lsl #30 + addhs r3, r3,r2, lsl #30 +L_divide_b30: + cmp r1, r0, lsl #29 + subhs r1, r1,r0, lsl #29 + addhs r3, r3,r2, lsl #29 +L_divide_b29: + cmp r1, r0, lsl #28 + subhs r1, r1,r0, lsl #28 + addhs r3, r3,r2, lsl #28 +L_divide_b28: + cmp r1, r0, lsl #27 + subhs r1, r1,r0, lsl #27 + addhs r3, r3,r2, lsl #27 +L_divide_b27: + cmp r1, r0, lsl #26 + subhs r1, r1,r0, lsl #26 + addhs r3, r3,r2, lsl #26 +L_divide_b26: + cmp r1, r0, lsl #25 + subhs r1, r1,r0, lsl #25 + addhs r3, r3,r2, lsl #25 +L_divide_b25: + cmp r1, r0, lsl #24 + subhs r1, r1,r0, lsl #24 + addhs r3, r3,r2, lsl #24 +L_divide_b24: + cmp r1, r0, lsl #23 + subhs r1, r1,r0, lsl #23 + addhs r3, r3,r2, lsl #23 +L_divide_b23: + cmp r1, r0, lsl #22 + subhs r1, r1,r0, lsl #22 + addhs r3, r3,r2, lsl #22 +L_divide_b22: + cmp r1, r0, lsl #21 + subhs r1, r1,r0, lsl #21 + addhs r3, r3,r2, lsl #21 +L_divide_b21: + cmp r1, r0, lsl #20 + subhs r1, r1,r0, lsl #20 + addhs r3, r3,r2, lsl #20 +L_divide_b20: + cmp r1, r0, lsl #19 + subhs r1, r1,r0, lsl #19 + addhs r3, r3,r2, lsl #19 +L_divide_b19: + cmp r1, r0, lsl #18 + subhs r1, r1,r0, lsl #18 + addhs r3, r3,r2, lsl #18 +L_divide_b18: + cmp r1, r0, lsl #17 + subhs r1, r1,r0, lsl #17 + addhs r3, r3,r2, lsl #17 +L_divide_b17: + cmp r1, r0, lsl #16 + subhs r1, r1,r0, lsl #16 + addhs r3, r3,r2, lsl #16 +L_divide_b16: + cmp r1, r0, lsl #15 + subhs r1, r1,r0, lsl #15 + addhs r3, r3,r2, lsl #15 +L_divide_b15: + cmp r1, r0, lsl #14 + subhs r1, r1,r0, lsl #14 + addhs r3, r3,r2, lsl #14 +L_divide_b14: + cmp r1, r0, lsl #13 + subhs r1, r1,r0, lsl #13 + addhs r3, r3,r2, lsl #13 +L_divide_b13: + cmp r1, r0, lsl #12 + subhs r1, r1,r0, lsl #12 + addhs r3, r3,r2, lsl #12 +L_divide_b12: + cmp r1, r0, lsl #11 + subhs r1, r1,r0, lsl #11 + addhs r3, r3,r2, lsl #11 +L_divide_b11: + cmp r1, r0, lsl #10 + subhs r1, r1,r0, lsl #10 + addhs r3, r3,r2, lsl #10 +L_divide_b10: + cmp r1, r0, lsl #9 + subhs r1, r1,r0, lsl #9 + addhs r3, r3,r2, lsl #9 +L_divide_b9: + cmp r1, r0, lsl #8 + subhs r1, r1,r0, lsl #8 + addhs r3, r3,r2, lsl #8 +L_divide_b8: + cmp r1, r0, lsl #7 + subhs r1, r1,r0, lsl #7 + addhs r3, r3,r2, lsl #7 +L_divide_b7: + cmp r1, r0, lsl #6 + subhs r1, r1,r0, lsl #6 + addhs r3, r3,r2, lsl #6 +L_divide_b6: + cmp r1, r0, lsl #5 + subhs r1, r1,r0, lsl #5 + addhs r3, r3,r2, lsl #5 +L_divide_b5: + cmp r1, r0, lsl #4 + subhs r1, r1,r0, lsl #4 + addhs r3, r3,r2, lsl #4 +L_divide_b4: + cmp r1, r0, lsl #3 + subhs r1, r1,r0, lsl #3 + addhs r3, r3,r2, lsl #3 +L_divide_b3: + cmp r1, r0, lsl #2 + subhs r1, r1,r0, lsl #2 + addhs r3, r3,r2, lsl #2 +L_divide_b2: + cmp r1, r0, lsl #1 + subhs r1, r1,r0, lsl #1 + addhs r3, r3,r2, lsl #1 +L_divide_b1: + cmp r1, r0 + subhs r1, r1, r0 + addhs r3, r3, r2 +L_divide_b0: + + tst ip, #0x20000000 + bne L_udivide_l1 + mov r0, r3 + cmp ip, #0 + rsbmi r1, r1, #0 + movs ip, ip, lsl #1 + bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */ + rsbmi r0, r0, #0 +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif + +L_udivide_l1: + tst ip, #0x10000000 + mov r1, r1, lsl #1 + orrne r1, r1, #1 + mov r3, r3, lsl #1 + cmp r1, r0 + subhs r1, r1, r0 + addhs r3, r3, r2 + mov r0, r3 +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif diff --git a/lib/libc/arch/arm26/gen/fabs.c b/lib/libc/arch/arm26/gen/fabs.c new file mode 100644 index 00000000000..83ca3281b9e --- /dev/null +++ b/lib/libc/arch/arm26/gen/fabs.c @@ -0,0 +1,48 @@ +/* $NetBSD: fabs.c,v 1.1 2000/05/09 21:55:48 bjh21 Exp $ */ + +/* + * Copyright (c) 1996 Mark Brinicombe + * + * 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 Mark Brinicombe + * 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 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. + */ + +/* + * fabs(x) returns the absolute value of x. + */ + +#ifdef __STDC__ + double fabs(double x) +#else + double fabs(x) + double x; +#endif +{ + if (x < 0) + x = -x; + return(x); +} diff --git a/lib/libc/arch/arm26/gen/flt_rounds.c b/lib/libc/arch/arm26/gen/flt_rounds.c new file mode 100644 index 00000000000..9cc2f84575c --- /dev/null +++ b/lib/libc/arch/arm26/gen/flt_rounds.c @@ -0,0 +1,76 @@ +/* $NetBSD: flt_rounds.c,v 1.1 2000/05/09 21:55:48 bjh21 Exp $ */ + +/* + * Copyright (c) 1996 Mark Brinicombe + * 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 Mark Brinicombe + * for the NetBSD Project. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * 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/types.h> +#include <ieeefp.h> + +static const int map[] = { + 1, /* round to nearest */ + 2, /* round to positive infinity */ + 3, /* round to negative infinity */ + 0 /* round to zero */ +}; + +/* + * Return the current FP rounding mode + * + * Returns: + * 0 - round to zero + * 1 - round to nearest + * 2 - round to postive infinity + * 3 - round to negative infinity + * + * ok all we need to do is get the current FP rounding mode + * index our map table and return the appropriate value. + * + * HOWEVER: + * The ARM FPA codes the rounding mode into the actual FP instructions + * so there is no such thing as a global rounding mode. + * The default is round to nearest if rounding is not explictly specified. + * FP instructions generated by GCC will not explicitly specify a rounding + * mode. + * + * So the best we can do it to return the rounding mode FP instructions + * use if rounding is not specified which is round to nearest. + * + * This could change in the future with new floating point emulators or + * soft float FP libraries. + */ + +int __flt_rounds(void); + +int +__flt_rounds() +{ + return(map[fpgetround()]); +} diff --git a/lib/libc/arch/arm26/gen/fpgetmask.S b/lib/libc/arch/arm26/gen/fpgetmask.S new file mode 100644 index 00000000000..ec549d8a1b2 --- /dev/null +++ b/lib/libc/arch/arm26/gen/fpgetmask.S @@ -0,0 +1,54 @@ +/* $NetBSD: fpgetmask.S,v 1.1 2000/05/09 21:55:48 bjh21 Exp $ */ + +/* + * Copyright (c) 1996 Mark Brinicombe + * 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 Mark Brinicombe + * for the NetBSD project. + * 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 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> + +/* + * Return the current FP exception enable mask + */ + +ENTRY(fpgetmask) +#ifdef SOFTFLOAT + b _C_FUNC(sfp_getmask) +#else + rfs r0 + mov r0, r0, lsr #16 + and r0, r0, #0x1f +#ifdef __APCS_26__ + movs r15, r14 /* return */ +#else + mov r15, r14 /* return */ +#endif +#endif /* SOFTFLOAT */ diff --git a/lib/libc/arch/arm26/gen/fpgetround.c b/lib/libc/arch/arm26/gen/fpgetround.c new file mode 100644 index 00000000000..d6437254350 --- /dev/null +++ b/lib/libc/arch/arm26/gen/fpgetround.c @@ -0,0 +1,64 @@ +/* $NetBSD: fpgetround.c,v 1.1 2000/05/09 21:55:48 bjh21 Exp $ */ + +/* + * Copyright (c) 1996 Mark Brinicombe + * 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 Mark Brinicombe + * for the NetBSD Project. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * 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/types.h> +#include <ieeefp.h> + +/* + * Return the current FP rounding mode + * + * ok all we need to do is return the current FP rounding mode + * + * HOWEVER: + * The ARM FPA codes the rounding mode into the actual FP instructions + * so there is no such thing as a global rounding mode. + * The default is round to nearest if rounding is not explictly specified. + * FP instructions generated by GCC will not explicitly specify a rounding + * mode. + * + * So the best we can do it to return the rounding mode FP instructions + * use if rounding is not specified which is round to nearest. + * + * This could change in the future with new floating point emulators or + * soft float FP libraries. + */ + +fp_rnd +fpgetround() +{ +#ifdef SOFT_FLOAT + return(sfp_getround()); +#else + return(FP_RN); +#endif +} diff --git a/lib/libc/arch/arm26/gen/fpgetsticky.S b/lib/libc/arch/arm26/gen/fpgetsticky.S new file mode 100644 index 00000000000..366109a5349 --- /dev/null +++ b/lib/libc/arch/arm26/gen/fpgetsticky.S @@ -0,0 +1,53 @@ +/* $NetBSD: fpgetsticky.S,v 1.1 2000/05/09 21:55:48 bjh21 Exp $ */ + +/* + * Copyright (c) 1996 Mark Brinicombe + * 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 Mark Brinicombe + * for the NetBSD project. + * 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 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> + +/* + * Return the current FP cumulative flags + */ + +ENTRY(fpgetsticky) +#ifdef SOFTFLOAT + b _C_FUNC(sfp_getsticky) +#else + rfs r0 + and r0, r0, #0x1f +#ifdef __APCS_26__ + movs r15, r14 /* return */ +#else + mov r15, r14 /* return */ +#endif +#endif /* SOFTFLOAT */ diff --git a/lib/libc/arch/arm26/gen/fpsetmask.S b/lib/libc/arch/arm26/gen/fpsetmask.S new file mode 100644 index 00000000000..ae16cf4c248 --- /dev/null +++ b/lib/libc/arch/arm26/gen/fpsetmask.S @@ -0,0 +1,57 @@ +/* $NetBSD: fpsetmask.S,v 1.1 2000/05/09 21:55:48 bjh21 Exp $ */ + +/* + * Copyright (c) 1996 Mark Brinicombe + * 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 Mark Brinicombe + * for the NetBSD project. + * 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 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> + +/* + * Set the current FP exception enable mask + */ + +ENTRY(fpsetmask) +#ifdef SOFTFLOAT + b _C_FUNC(sfp_setmask) +#else + rfs r1 + bic r1, r1, #0x001f0000 + and r0, r0, #0x0000001f + orr r0, r1, r0, lsl #16 + wfs r0 + mov r0, r1, lsr #16 /* Return old mask */ +#ifdef __APCS_26__ + movs r15, r14 /* return */ +#else + mov r15, r14 /* return */ +#endif +#endif /* SOFTFLOAT */ diff --git a/lib/libc/arch/arm26/gen/fpsetround.c b/lib/libc/arch/arm26/gen/fpsetround.c new file mode 100644 index 00000000000..8ec1ecd42a5 --- /dev/null +++ b/lib/libc/arch/arm26/gen/fpsetround.c @@ -0,0 +1,71 @@ +/* $NetBSD: fpsetround.c,v 1.1 2000/05/09 21:55:48 bjh21 Exp $ */ + +/* + * Copyright (c) 1996 Mark Brinicombe + * 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 Mark Brinicombe + * for the NetBSD Project. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * 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/types.h> +#include <ieeefp.h> + +void sfp_setround __P((fp_rnd)); + +/* + * Return the current FP rounding mode + * + * ok all we need to do is return the current FP rounding mode + * + * HOWEVER: + * The ARM FPA codes the rounding mode into the actual FP instructions + * so there is no such thing as a global rounding mode. + * The default is round to nearest if rounding is not explictly specified. + * FP instructions generated by GCC will not explicitly specify a rounding + * mode. + * + * All we can do is abort + * + * This could change in the future with new floating point emulators or + * soft float FP libraries. + */ + +fp_rnd +fpsetround(rnd_dir) + fp_rnd rnd_dir; +{ + fp_rnd old_rnd; + + old_rnd = fpgetround(); + +#ifdef SOFTFLOAT + sfp_setround(rnd_dir); +#else + abort(); +#endif + return(old_rnd); +} diff --git a/lib/libc/arch/arm26/gen/fpsetsticky.S b/lib/libc/arch/arm26/gen/fpsetsticky.S new file mode 100644 index 00000000000..0b68186b413 --- /dev/null +++ b/lib/libc/arch/arm26/gen/fpsetsticky.S @@ -0,0 +1,57 @@ +/* $NetBSD: fpsetsticky.S,v 1.1 2000/05/09 21:55:48 bjh21 Exp $ */ + +/* + * Copyright (c) 1996 Mark Brinicombe + * 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 Mark Brinicombe + * for the NetBSD project. + * 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 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> + +/* + * Set the current FP cumulative flags + */ + +ENTRY(fpsetsticky) +#ifdef SOFTFLOAT + b _C_FUNC(sfp_setsticky) +#else + rfs r1 + bic r1, r1, #0x1f + and r0, r0, #0x1f + orr r0, r1, r0 + wfs r0 + mov r0, r1 /* Return old mask */ +#ifdef __APCS_26__ + movs r15, r14 /* return */ +#else + mov r15, r14 /* return */ +#endif +#endif /* SOFTFLOAT */ diff --git a/lib/libc/arch/arm26/gen/frexp.c b/lib/libc/arch/arm26/gen/frexp.c new file mode 100644 index 00000000000..ffcd21b312e --- /dev/null +++ b/lib/libc/arch/arm26/gen/frexp.c @@ -0,0 +1,86 @@ +/* $NetBSD: frexp.c,v 1.1 2000/05/09 21:55:48 bjh21 Exp $ */ + +/* + * 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: frexp.c,v 1.1 91/07/07 04:45:01 torek Exp + */ + +#include <sys/cdefs.h> +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)frexp.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: frexp.c,v 1.1 2000/05/09 21:55:48 bjh21 Exp $"); +#endif +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +/* + * Split the given value into a fraction in the range [0.5, 1.0) and + * an exponent, such that frac * (2^exp) == value. If value is 0, + * return 0. + */ +double +frexp(value, eptr) + double value; + int *eptr; +{ + union { + double v; + struct ieee_double s; + } u; + + if (value) { + /* + * Fractions in [0.5..1.0) have an exponent of 2^-1. + * Leave Inf and NaN alone, however. + * WHAT ABOUT DENORMS? + */ + u.v = value; + if (u.s.dbl_exp != DBL_EXP_INFNAN) { + *eptr = u.s.dbl_exp - (DBL_EXP_BIAS - 1); + u.s.dbl_exp = DBL_EXP_BIAS - 1; + } + return (u.v); + } else { + *eptr = 0; + return (0.0); + } +} diff --git a/lib/libc/arch/arm26/gen/infinity.c b/lib/libc/arch/arm26/gen/infinity.c new file mode 100644 index 00000000000..e4a15e791aa --- /dev/null +++ b/lib/libc/arch/arm26/gen/infinity.c @@ -0,0 +1,38 @@ +/* $NetBSD: infinity.c,v 1.1 2000/05/09 21:55:48 bjh21 Exp $ */ + +/* + * Copyright (c) 1996 Mark Brinicombe. + * + * 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 Mark Brinicombe + * 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 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 <math.h> + +/* Bytes for +infinity on an arm32 (IEEE double precision) */ + +const char __infinity[] __attribute__((__aligned__(4))) = { 0, 0, (char)0xf0, 0x7f, 0, 0, 0, 0 }; diff --git a/lib/libc/arch/arm26/gen/isinf.c b/lib/libc/arch/arm26/gen/isinf.c new file mode 100644 index 00000000000..a794e05dccd --- /dev/null +++ b/lib/libc/arch/arm26/gen/isinf.c @@ -0,0 +1,68 @@ +/* $NetBSD: isinf.c,v 1.1 2000/05/09 21:55:49 bjh21 Exp $ */ + +/* + * 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: isinf.c,v 1.1 91/07/08 19:03:34 torek Exp + */ + +#include <sys/cdefs.h> +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)isinf.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: isinf.c,v 1.1 2000/05/09 21:55:49 bjh21 Exp $"); +#endif +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +#ifdef __weak_alias +__weak_alias(isinf,_isinf) +#endif + +int +isinf(d) + double d; +{ + register struct ieee_double *p = (struct ieee_double *)(void *)&d; + + return (p->dbl_exp == DBL_EXP_INFNAN && + (p->dbl_frach == 0 && p->dbl_fracl == 0)); +} diff --git a/lib/libc/arch/arm26/gen/isnan.c b/lib/libc/arch/arm26/gen/isnan.c new file mode 100644 index 00000000000..01f02d4899b --- /dev/null +++ b/lib/libc/arch/arm26/gen/isnan.c @@ -0,0 +1,68 @@ +/* $NetBSD: isnan.c,v 1.1 2000/05/09 21:55:49 bjh21 Exp $ */ + +/* + * 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: isinf.c,v 1.1 91/07/08 19:03:34 torek Exp + */ + +#include <sys/cdefs.h> +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)isinf.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: isnan.c,v 1.1 2000/05/09 21:55:49 bjh21 Exp $"); +#endif +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +#ifdef __weak_alias +__weak_alias(isnan,_isnan) +#endif + +int +isnan(d) + double d; +{ + register struct ieee_double *p = (struct ieee_double *)(void *)&d; + + return (p->dbl_exp == DBL_EXP_INFNAN && + (p->dbl_frach != 0 || p->dbl_fracl != 0)); +} diff --git a/lib/libc/arch/arm26/gen/ldexp.c b/lib/libc/arch/arm26/gen/ldexp.c new file mode 100644 index 00000000000..eebfd26b0d1 --- /dev/null +++ b/lib/libc/arch/arm26/gen/ldexp.c @@ -0,0 +1,154 @@ +/* $NetBSD: ldexp.c,v 1.1 2000/05/09 21:55:49 bjh21 Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <sys/cdefs.h> +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: ldexp.c,v 1.1 2000/05/09 21:55:49 bjh21 Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <errno.h> +#include <math.h> + +/* + * Multiply the given value by 2^exp. + */ +double +ldexp(val, exp) + double val; + int exp; +{ + register int oldexp, newexp; + union { + double v; + struct ieee_double s; + } u, mul; + + u.v = val; + oldexp = u.s.dbl_exp; + + /* + * If input is zero, Inf or NaN, just return it. + */ + if (u.v == 0.0 || oldexp == DBL_EXP_INFNAN) + return (val); + + if (oldexp == 0) { + /* + * u.v is denormal. We must adjust it so that the exponent + * arithmetic below will work. + */ + if (exp <= DBL_EXP_BIAS) { + /* + * Optimization: if the scaling can be done in a single + * multiply, or underflows, just do it now. + */ + if (exp <= -DBL_FRACBITS) { + errno = ERANGE; + return (0.0); + } + mul.v = 0.0; + mul.s.dbl_exp = exp + DBL_EXP_BIAS; + u.v *= mul.v; + if (u.v == 0.0) { + errno = ERANGE; + return (0.0); + } + return (u.v); + } else { + /* + * We know that exp is very large, and therefore the + * result cannot be denormal (though it may be Inf). + * Shift u.v by just enough to make it normal. + */ + mul.v = 0.0; + mul.s.dbl_exp = DBL_FRACBITS + DBL_EXP_BIAS; + u.v *= mul.v; + exp -= DBL_FRACBITS; + oldexp = u.s.dbl_exp; + } + } + + /* + * u.v is now normalized and oldexp has been adjusted if necessary. + * Calculate the new exponent and check for underflow and overflow. + */ + newexp = oldexp + exp; + + if (newexp <= 0) { + /* + * The output number is either denormal or underflows (see + * comments in machine/ieee.h). + */ + if (newexp <= -DBL_FRACBITS) { + errno = ERANGE; + return (0.0); + } + /* + * Denormalize the result. We do this with a multiply. If exp + * is very large, it won't fit in a double, so we have to + * adjust the exponent first. This is safe because we know + * that u.v is normal at this point. + */ + if (exp <= -DBL_EXP_BIAS) { + u.s.dbl_exp = 1; + exp += oldexp - 1; + } + mul.v = 0.0; + mul.s.dbl_exp = exp + DBL_EXP_BIAS; + u.v *= mul.v; + return (u.v); + } else if (newexp >= DBL_EXP_INFNAN) { + /* + * The result overflowed; return +/-Inf. + */ + u.s.dbl_exp = DBL_EXP_INFNAN; + u.s.dbl_frach = 0; + u.s.dbl_fracl = 0; + errno = ERANGE; + return (u.v); + } else { + /* + * The result is normal; just replace the old exponent with the + * new one. + */ + u.s.dbl_exp = newexp; + return (u.v); + } +} diff --git a/lib/libc/arch/arm26/gen/modf.c b/lib/libc/arch/arm26/gen/modf.c new file mode 100644 index 00000000000..1cceff442d3 --- /dev/null +++ b/lib/libc/arch/arm26/gen/modf.c @@ -0,0 +1,104 @@ +/* $NetBSD: modf.c,v 1.1 2000/05/09 21:55:49 bjh21 Exp $ */ + +/* + * Copyright (c) 1994, 1995 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <errno.h> +#include <math.h> + +/* + * double modf(double val, double *iptr) + * returns: f and i such that |f| < 1.0, (f + i) = val, and + * sign(f) == sign(i) == sign(val). + * + * Beware signedness when doing subtraction, and also operand size! + */ +double +modf(val, iptr) + double val, *iptr; +{ + union doub { + double v; + struct ieee_double s; + } u, v; + u_int64_t frac; + + /* + * If input is Inf or NaN, return it and leave i alone. + */ + u.v = val; + if (u.s.dbl_exp == DBL_EXP_INFNAN) + return (u.v); + + /* + * If input can't have a fractional part, return + * (appropriately signed) zero, and make i be the input. + */ + if ((int)u.s.dbl_exp - DBL_EXP_BIAS > DBL_FRACBITS - 1) { + *iptr = u.v; + v.v = 0.0; + v.s.dbl_sign = u.s.dbl_sign; + return (v.v); + } + + /* + * If |input| < 1.0, return it, and set i to the appropriately + * signed zero. + */ + if (u.s.dbl_exp < DBL_EXP_BIAS) { + v.v = 0.0; + v.s.dbl_sign = u.s.dbl_sign; + *iptr = v.v; + return (u.v); + } + + /* + * There can be a fractional part of the input. + * If you look at the math involved for a few seconds, it's + * plain to see that the integral part is the input, with the + * low (DBL_FRACBITS - (exponent - DBL_EXP_BIAS)) bits zeroed, + * the fractional part is the part with the rest of the + * bits zeroed. Just zeroing the high bits to get the + * fractional part would yield a fraction in need of + * normalization. Therefore, we take the easy way out, and + * just use subtraction to get the fractional part. + */ + v.v = u.v; + /* Zero the low bits of the fraction, the sleazy way. */ + frac = ((u_int64_t)v.s.dbl_frach << 32) + v.s.dbl_fracl; + frac >>= DBL_FRACBITS - (u.s.dbl_exp - DBL_EXP_BIAS); + frac <<= DBL_FRACBITS - (u.s.dbl_exp - DBL_EXP_BIAS); + v.s.dbl_fracl = frac & 0xffffffff; + v.s.dbl_frach = frac >> 32; + *iptr = v.v; + + u.v -= v.v; + u.s.dbl_sign = v.s.dbl_sign; + return (u.v); +} diff --git a/lib/libc/arch/arm26/gen/nanf.c b/lib/libc/arch/arm26/gen/nanf.c new file mode 100644 index 00000000000..f19ac11b51d --- /dev/null +++ b/lib/libc/arch/arm26/gen/nanf.c @@ -0,0 +1,13 @@ +/* $NetBSD: nanf.c,v 1.1 2000/05/09 21:55:49 bjh21 Exp $ */ + +#include <sys/cdefs.h> +#ifndef lint +__RCSID("$NetBSD: nanf.c,v 1.1 2000/05/09 21:55:49 bjh21 Exp $"); +#endif /* not lint */ + +/* nanf.c */ + +#include <math.h> + +/* bytes for quiet NaN on an arm32 (IEEE single precision) */ +const char __nanf[] __attribute__((__aligned__(4))) = { 0, 0, (char)0xc0, 0x7f }; diff --git a/lib/libc/arch/arm26/gen/setjmp.S b/lib/libc/arch/arm26/gen/setjmp.S new file mode 100644 index 00000000000..7a7ddf9241f --- /dev/null +++ b/lib/libc/arch/arm26/gen/setjmp.S @@ -0,0 +1,137 @@ +/* $NetBSD: setjmp.S,v 1.1 2000/05/09 21:55:49 bjh21 Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * 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 Mark Brinicombe + * 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 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> +#include <machine/setjmp.h> + +/* + * C library -- setjmp, longjmp + * + * longjmp(a,v) + * will generate a "return(v)" from the last call to + * setjmp(a) + * by restoring registers from the stack. + * The previous signal state is restored. + */ + +ENTRY(setjmp) + /* Block all signals and retrieve the old signal mask */ + stmfd r13!, {r0, r14} + mov r0, #0x00000000 + + bl _C_FUNC(sigblock) + mov r1, r0 + + ldmfd r13!, {r0, r14} + + /* Store signal mask */ + str r1, [r0, #(25 * 4)] + + ldr r1, Lsetjmp_magic + str r1, [r0], #4 + +#ifdef SOFTFLOAT + add r0, r0, #52 +#else + /* Store fp registers */ + sfm f4, 4, [r0], #48 + /* Store fpsr */ + rfs r1 + str r1, [r0], #0x0004 +#endif /*SOFTFLOAT*/ + /* Store integer registers */ + stmia r0, {r4-r14} + mov r0, #0x00000000 +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif + +Lsetjmp_magic: + .word _JB_MAGIC_SETJMP + + +ENTRY(longjmp) + ldr r2, Lsetjmp_magic + ldr r3, [r0] + teq r2, r3 + bne botch + + /* Fetch signal mask */ + ldr r2, [r0, #(25 * 4)] + + /* Set signal mask */ + stmfd r13!, {r0, r1, r14} + + mov r0, r2 + bl _C_FUNC(sigsetmask) + + ldmfd r13!, {r0, r1, r14} + + add r0, r0, #4 +#ifdef SOFTFLOAT + add r0, r0, #52 +#else + /* Restore fp registers */ + lfm f4, 4, [r0], #48 + /* Restore FPSR */ + ldr r4, [r0], #0x0004 + wfs r4 +#endif /* SOFTFLOAT */ + /* Restore integer registers */ + ldmia r0, {r4-r14} + + /* Validate r13 and r14 */ + teq r13, #0 + beq botch + teq r14, #0 + beq botch + + /* Set return value */ + + mov r0, r1 + teq r0, #0x00000000 + moveq r0, #0x00000001 +#ifdef __ARM_26__ + mov r15, r14 +#else + mov r15, r14 +#endif + + /* validation failed, die die die. */ +botch: + bl _C_FUNC(longjmperror) + bl _C_FUNC(abort) + b . - 8 /* Cannot get here */ diff --git a/lib/libc/arch/arm26/gen/sigsetjmp.S b/lib/libc/arch/arm26/gen/sigsetjmp.S new file mode 100644 index 00000000000..6f87ad9026f --- /dev/null +++ b/lib/libc/arch/arm26/gen/sigsetjmp.S @@ -0,0 +1,61 @@ +/* $NetBSD: sigsetjmp.S,v 1.1 2000/05/09 21:55:49 bjh21 Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * 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 Mark Brinicombe + * 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 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> +#include <machine/setjmp.h> + +/* + * C library -- sigsetjmp, siglongjmp + * + * longjmp(a,v) + * will generate a "return(v)" from the last call to + * setjmp(a, m) + * by restoring registers from the stack. + * The previous signal state is restored. + */ + +ENTRY(sigsetjmp) + teq r1, #0 + beq _C_FUNC(_setjmp) + b _C_FUNC(setjmp) + +L_setjmp_magic: + .word _JB_MAGIC__SETJMP + +ENTRY(siglongjmp) + ldr r2, L_setjmp_magic + ldr r3, [r0] + teq r2, r3 + beq _C_FUNC(_longjmp) + b _C_FUNC(longjmp) diff --git a/lib/libc/arch/arm26/net/Makefile.inc b/lib/libc/arch/arm26/net/Makefile.inc new file mode 100644 index 00000000000..542eaea2811 --- /dev/null +++ b/lib/libc/arch/arm26/net/Makefile.inc @@ -0,0 +1,4 @@ +# $NetBSD: Makefile.inc,v 1.1 2000/05/09 21:55:49 bjh21 Exp $ + +# hton* and nto* functions provided by ../gen/byte_swap_*.S +SRCS+= diff --git a/lib/libc/arch/arm26/stdlib/Makefile.inc b/lib/libc/arch/arm26/stdlib/Makefile.inc new file mode 100644 index 00000000000..08616abffd7 --- /dev/null +++ b/lib/libc/arch/arm26/stdlib/Makefile.inc @@ -0,0 +1,3 @@ +# $NetBSD: Makefile.inc,v 1.1 2000/05/09 21:55:49 bjh21 Exp $ + +SRCS+= abs.c div.c labs.c ldiv.c llabs.c diff --git a/lib/libc/arch/arm26/string/Makefile.inc b/lib/libc/arch/arm26/string/Makefile.inc new file mode 100644 index 00000000000..5947b3baf88 --- /dev/null +++ b/lib/libc/arch/arm26/string/Makefile.inc @@ -0,0 +1,8 @@ +# $NetBSD: Makefile.inc,v 1.1 2000/05/09 21:55:50 bjh21 Exp $ + +SRCS+= memcpy.S _memcpy.S bcopy.S memmove.S memset.S bzero.S +SRCS+= bcmp.c ffs.c index.c memchr.c memcmp.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/arm26/string/_memcpy.S b/lib/libc/arch/arm26/string/_memcpy.S new file mode 100644 index 00000000000..2d8ddc8d7fc --- /dev/null +++ b/lib/libc/arch/arm26/string/_memcpy.S @@ -0,0 +1,463 @@ +/* $Id: _memcpy.S,v 1.1 2000/05/09 21:55:50 bjh21 Exp $ */ +/* $NetBSD: _memcpy.S,v 1.1 2000/05/09 21:55:50 bjh21 Exp $ */ + +/* + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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> + +/* + * This is one fun bit of code ... + * Some easy listening music is suggested while trying to understand this + * code e.g. Iron Maiden + * + * For anyone attempting to understand it : + * + * The core code is implemented here with simple stubs for memcpy() + * memmove() and bcopy(). + * + * All local labels are prefixed with Lmemcpy_ + * Following the prefix a label starting f is used in the forward copy code + * while a label using b is used in the backwards copy code + * The source and destination addresses determine whether a forward or + * backward copy is performed. + * Separate bits of code are used to deal with the following situations + * for both the forward and backwards copy. + * unaligned source address + * unaligned destination address + * Separate copy routines are used to produce an optimised result for each + * of these cases. + * The copy code will use LDM/STM instructions to copy up to 32 bytes at + * a time where possible. + * + * Note: r12 (aka ip) can be trashed during the function along with + * r0-r3 although r0-r2 have defined uses i.e. src, dest, len through out. + * Additional registers are preserved prior to use i.e. r4, r5 & lr + * + * Apologies for the state of the comments ;-) + */ + +ENTRY(_memcpy) + /* Determine copy direction */ + cmp r1, r0 + bcc Lmemcpy_backwards + + moveq r0, #0 /* Quick abort for len=0 */ +#ifdef __APCS_26__ + moveqs pc, lr +#else + moveq pc, lr +#endif + + stmdb sp!, {r0, lr} /* memcpy() returns dest addr */ + subs r2, r2, #4 + blt Lmemcpy_fl4 /* less than 4 bytes */ + ands r12, r0, #3 + bne Lmemcpy_fdestul /* oh unaligned destination addr */ + ands r12, r1, #3 + bne Lmemcpy_fsrcul /* oh unaligned source addr */ + +Lmemcpy_ft8: + /* We have aligned source and destination */ + subs r2, r2, #8 + blt Lmemcpy_fl12 /* less than 12 bytes (4 from above) */ + subs r2, r2, #0x14 + blt Lmemcpy_fl32 /* less than 32 bytes (12 from above) */ + stmdb sp!, {r4} /* borrow r4 */ + + /* blat 32 bytes at a time */ + /* XXX for really big copies perhaps we should use more registers */ +Lmemcpy_floop32: + ldmia r1!, {r3, r4, r12, lr} + stmia r0!, {r3, r4, r12, lr} + ldmia r1!, {r3, r4, r12, lr} + stmia r0!, {r3, r4, r12, lr} + subs r2, r2, #0x20 + bge Lmemcpy_floop32 + + cmn r2, #0x10 + ldmgeia r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ + stmgeia r0!, {r3, r4, r12, lr} + subge r2, r2, #0x10 + ldmia sp!, {r4} /* return r4 */ + +Lmemcpy_fl32: + adds r2, r2, #0x14 + + /* blat 12 bytes at a time */ +Lmemcpy_floop12: + ldmgeia r1!, {r3, r12, lr} + stmgeia r0!, {r3, r12, lr} + subges r2, r2, #0x0c + bge Lmemcpy_floop12 + +Lmemcpy_fl12: + adds r2, r2, #8 + blt Lmemcpy_fl4 + + subs r2, r2, #4 + ldrlt r3, [r1], #4 + strlt r3, [r0], #4 + ldmgeia r1!, {r3, r12} + stmgeia r0!, {r3, r12} + subge r2, r2, #4 + +Lmemcpy_fl4: + /* less than 4 bytes to go */ + adds r2, r2, #4 + ldmeqia sp!, {r0, pc} /* done */ + + /* copy the crud byte at a time */ + cmp r2, #2 + ldrb r3, [r1], #1 + strb r3, [r0], #1 + ldrgeb r3, [r1], #1 + strgeb r3, [r0], #1 + ldrgtb r3, [r1], #1 + strgtb r3, [r0], #1 +#ifdef __APCS_26__ + ldmia sp!, {r0, pc}^ +#else + ldmia sp!, {r0, pc} +#endif + + /* erg - unaligned destination */ +Lmemcpy_fdestul: + rsb r12, r12, #4 + cmp r12, #2 + + /* align destination with byte copies */ + ldrb r3, [r1], #1 + strb r3, [r0], #1 + ldrgeb r3, [r1], #1 + strgeb r3, [r0], #1 + ldrgtb r3, [r1], #1 + strgtb r3, [r0], #1 + subs r2, r2, r12 + blt Lmemcpy_fl4 /* less the 4 bytes */ + + ands r12, r1, #3 + beq Lmemcpy_ft8 /* we have an aligned source */ + + /* erg - unaligned source */ + /* This is where it gets nasty ... */ +Lmemcpy_fsrcul: + bic r1, r1, #3 + ldr lr, [r1], #4 + cmp r12, #2 + bgt Lmemcpy_fsrcul3 + beq Lmemcpy_fsrcul2 + cmp r2, #0x0c + blt Lmemcpy_fsrcul1loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5} + +Lmemcpy_fsrcul1loop16: + mov r3, lr, lsr #8 + ldmia r1!, {r4, r5, r12, lr} + orr r3, r3, r4, lsl #24 + mov r4, r4, lsr #8 + orr r4, r4, r5, lsl #24 + mov r5, r5, lsr #8 + orr r5, r5, r12, lsl #24 + mov r12, r12, lsr #8 + orr r12, r12, lr, lsl #24 + stmia r0!, {r3-r5, r12} + subs r2, r2, #0x10 + bge Lmemcpy_fsrcul1loop16 + ldmia sp!, {r4, r5} + adds r2, r2, #0x0c + blt Lmemcpy_fsrcul1l4 + +Lmemcpy_fsrcul1loop4: + mov r12, lr, lsr #8 + ldr lr, [r1], #4 + orr r12, r12, lr, lsl #24 + str r12, [r0], #4 + subs r2, r2, #4 + bge Lmemcpy_fsrcul1loop4 + +Lmemcpy_fsrcul1l4: + sub r1, r1, #3 + b Lmemcpy_fl4 + +Lmemcpy_fsrcul2: + cmp r2, #0x0c + blt Lmemcpy_fsrcul2loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5} + +Lmemcpy_fsrcul2loop16: + mov r3, lr, lsr #16 + ldmia r1!, {r4, r5, r12, lr} + orr r3, r3, r4, lsl #16 + mov r4, r4, lsr #16 + orr r4, r4, r5, lsl #16 + mov r5, r5, lsr #16 + orr r5, r5, r12, lsl #16 + mov r12, r12, lsr #16 + orr r12, r12, lr, lsl #16 + stmia r0!, {r3-r5, r12} + subs r2, r2, #0x10 + bge Lmemcpy_fsrcul2loop16 + ldmia sp!, {r4, r5} + adds r2, r2, #0x0c + blt Lmemcpy_fsrcul2l4 + +Lmemcpy_fsrcul2loop4: + mov r12, lr, lsr #16 + ldr lr, [r1], #4 + orr r12, r12, lr, lsl #16 + str r12, [r0], #4 + subs r2, r2, #4 + bge Lmemcpy_fsrcul2loop4 + +Lmemcpy_fsrcul2l4: + sub r1, r1, #2 + b Lmemcpy_fl4 + +Lmemcpy_fsrcul3: + cmp r2, #0x0c + blt Lmemcpy_fsrcul3loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5} + +Lmemcpy_fsrcul3loop16: + mov r3, lr, lsr #24 + ldmia r1!, {r4, r5, r12, lr} + orr r3, r3, r4, lsl #8 + mov r4, r4, lsr #24 + orr r4, r4, r5, lsl #8 + mov r5, r5, lsr #24 + orr r5, r5, r12, lsl #8 + mov r12, r12, lsr #24 + orr r12, r12, lr, lsl #8 + stmia r0!, {r3-r5, r12} + subs r2, r2, #0x10 + bge Lmemcpy_fsrcul3loop16 + ldmia sp!, {r4, r5} + adds r2, r2, #0x0c + blt Lmemcpy_fsrcul3l4 + +Lmemcpy_fsrcul3loop4: + mov r12, lr, lsr #24 + ldr lr, [r1], #4 + orr r12, r12, lr, lsl #8 + str r12, [r0], #4 + subs r2, r2, #4 + bge Lmemcpy_fsrcul3loop4 + +Lmemcpy_fsrcul3l4: + sub r1, r1, #1 + b Lmemcpy_fl4 + +Lmemcpy_backwards: + add r1, r1, r2 + add r0, r0, r2 + subs r2, r2, #4 + blt Lmemcpy_bl4 /* less than 4 bytes */ + ands r12, r0, #3 + bne Lmemcpy_bdestul /* oh unaligned destination addr */ + ands r12, r1, #3 + bne Lmemcpy_bsrcul /* oh unaligned source addr */ + +Lmemcpy_bt8: + /* We have aligned source and destination */ + subs r2, r2, #8 + blt Lmemcpy_bl12 /* less than 12 bytes (4 from above) */ + stmdb sp!, {r4, lr} + subs r2, r2, #0x14 /* less than 32 bytes (12 from above) */ + blt Lmemcpy_bl32 + + /* blat 32 bytes at a time */ + /* XXX for really big copies perhaps we should use more registers */ +Lmemcpy_bloop32: + ldmdb r1!, {r3, r4, r12, lr} + stmdb r0!, {r3, r4, r12, lr} + ldmdb r1!, {r3, r4, r12, lr} + stmdb r0!, {r3, r4, r12, lr} + subs r2, r2, #0x20 + bge Lmemcpy_bloop32 + +Lmemcpy_bl32: + cmn r2, #0x10 + ldmgedb r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ + stmgedb r0!, {r3, r4, r12, lr} + subge r2, r2, #0x10 + adds r2, r2, #0x14 + ldmgedb r1!, {r3, r12, lr} /* blat a remaining 12 bytes */ + stmgedb r0!, {r3, r12, lr} + subge r2, r2, #0x0c + ldmia sp!, {r4, lr} + +Lmemcpy_bl12: + adds r2, r2, #8 + blt Lmemcpy_bl4 + subs r2, r2, #4 + ldrlt r3, [r1, #-4]! + strlt r3, [r0, #-4]! + ldmgedb r1!, {r3, r12} + stmgedb r0!, {r3, r12} + subge r2, r2, #4 + +Lmemcpy_bl4: + /* less than 4 bytes to go */ + adds r2, r2, #4 + moveq pc, lr /* done */ + + /* copy the crud byte at a time */ + cmp r2, #2 + ldrb r3, [r1, #-1]! + strb r3, [r0, #-1]! + ldrgeb r3, [r1, #-1]! + strgeb r3, [r0, #-1]! + ldrgtb r3, [r1, #-1]! + strgtb r3, [r0, #-1]! +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif + + /* erg - unaligned destination */ +Lmemcpy_bdestul: + cmp r12, #2 + + /* align destination with byte copies */ + ldrb r3, [r1, #-1]! + strb r3, [r0, #-1]! + ldrgeb r3, [r1, #-1]! + strgeb r3, [r0, #-1]! + ldrgtb r3, [r1, #-1]! + strgtb r3, [r0, #-1]! + subs r2, r2, r12 + blt Lmemcpy_bl4 /* less than 4 bytes to go */ + ands r12, r1, #3 + beq Lmemcpy_bt8 /* we have an aligned source */ + + /* erg - unaligned source */ + /* This is where it gets nasty ... */ +Lmemcpy_bsrcul: + bic r1, r1, #3 + ldr r3, [r1, #0] + cmp r12, #2 + blt Lmemcpy_bsrcul1 + beq Lmemcpy_bsrcul2 + cmp r2, #0x0c + blt Lmemcpy_bsrcul3loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5, lr} + +Lmemcpy_bsrcul3loop16: + mov lr, r3, lsl #8 + ldmdb r1!, {r3-r5, r12} + orr lr, lr, r12, lsr #24 + mov r12, r12, lsl #8 + orr r12, r12, r5, lsr #24 + mov r5, r5, lsl #8 + orr r5, r5, r4, lsr #24 + mov r4, r4, lsl #8 + orr r4, r4, r3, lsr #24 + stmdb r0!, {r4, r5, r12, lr} + subs r2, r2, #0x10 + bge Lmemcpy_bsrcul3loop16 + ldmia sp!, {r4, r5, lr} + adds r2, r2, #0x0c + blt Lmemcpy_bsrcul3l4 + +Lmemcpy_bsrcul3loop4: + mov r12, r3, lsl #8 + ldr r3, [r1, #-4]! + orr r12, r12, r3, lsr #24 + str r12, [r0, #-4]! + subs r2, r2, #4 + bge Lmemcpy_bsrcul3loop4 + +Lmemcpy_bsrcul3l4: + add r1, r1, #3 + b Lmemcpy_bl4 + +Lmemcpy_bsrcul2: + cmp r2, #0x0c + blt Lmemcpy_bsrcul2loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5, lr} + +Lmemcpy_bsrcul2loop16: + mov lr, r3, lsl #16 + ldmdb r1!, {r3-r5, r12} + orr lr, lr, r12, lsr #16 + mov r12, r12, lsl #16 + orr r12, r12, r5, lsr #16 + mov r5, r5, lsl #16 + orr r5, r5, r4, lsr #16 + mov r4, r4, lsl #16 + orr r4, r4, r3, lsr #16 + stmdb r0!, {r4, r5, r12, lr} + subs r2, r2, #0x10 + bge Lmemcpy_bsrcul2loop16 + ldmia sp!, {r4, r5, lr} + adds r2, r2, #0x0c + blt Lmemcpy_bsrcul2l4 + +Lmemcpy_bsrcul2loop4: + mov r12, r3, lsl #16 + ldr r3, [r1, #-4]! + orr r12, r12, r3, lsr #16 + str r12, [r0, #-4]! + subs r2, r2, #4 + bge Lmemcpy_bsrcul2loop4 + +Lmemcpy_bsrcul2l4: + add r1, r1, #2 + b Lmemcpy_bl4 + +Lmemcpy_bsrcul1: + cmp r2, #0x0c + blt Lmemcpy_bsrcul1loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5, lr} + +Lmemcpy_bsrcul1loop32: + mov lr, r3, lsl #24 + ldmdb r1!, {r3-r5, r12} + orr lr, lr, r12, lsr #8 + mov r12, r12, lsl #24 + orr r12, r12, r5, lsr #8 + mov r5, r5, lsl #24 + orr r5, r5, r4, lsr #8 + mov r4, r4, lsl #24 + orr r4, r4, r3, lsr #8 + stmdb r0!, {r4, r5, r12, lr} + subs r2, r2, #0x10 + bge Lmemcpy_bsrcul1loop32 + ldmia sp!, {r4, r5, lr} + adds r2, r2, #0x0c + blt Lmemcpy_bsrcul1l4 + +Lmemcpy_bsrcul1loop4: + mov r12, r3, lsl #24 + ldr r3, [r1, #-4]! + orr r12, r12, r3, lsr #8 + str r12, [r0, #-4]! + subs r2, r2, #4 + bge Lmemcpy_bsrcul1loop4 + +Lmemcpy_bsrcul1l4: + add r1, r1, #1 + b Lmemcpy_bl4 + diff --git a/lib/libc/arch/arm26/string/bcopy.S b/lib/libc/arch/arm26/string/bcopy.S new file mode 100644 index 00000000000..598b94d801d --- /dev/null +++ b/lib/libc/arch/arm26/string/bcopy.S @@ -0,0 +1,48 @@ +/* $NetBSD: bcopy.S,v 1.1 2000/05/09 21:55:50 bjh21 Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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> + +/* bcopy = memcpy/memmove with arguments reversed. */ + +TWOENTRY(bcopy,ovbcopy) + /* switch the source and destination registers */ + eor r0, r1, r0 + eor r1, r0, r1 + eor r0, r1, r0 + b _C_FUNC(_memcpy) diff --git a/lib/libc/arch/arm26/string/bzero.S b/lib/libc/arch/arm26/string/bzero.S new file mode 100644 index 00000000000..be67d7fd265 --- /dev/null +++ b/lib/libc/arch/arm26/string/bzero.S @@ -0,0 +1,44 @@ +/* $NetBSD: bzero.S,v 1.1 2000/05/09 21:55:50 bjh21 Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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> + +ENTRY(bzero) + mov r2, r1 + mov r1, #0 + b _C_FUNC(memset) diff --git a/lib/libc/arch/arm26/string/memcpy.S b/lib/libc/arch/arm26/string/memcpy.S new file mode 100644 index 00000000000..2c25f89030e --- /dev/null +++ b/lib/libc/arch/arm26/string/memcpy.S @@ -0,0 +1,48 @@ +/* $NetBSD: memcpy.S,v 1.1 2000/05/09 21:55:50 bjh21 Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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> + +ENTRY(memcpy) + stmfd sp!, {r0, lr} + bl _C_FUNC(_memcpy) +#ifdef __APCS_26__ + ldmfd sp!, {r0, pc}^ +#else + ldmfd sp!, {r0, pc} +#endif diff --git a/lib/libc/arch/arm26/string/memmove.S b/lib/libc/arch/arm26/string/memmove.S new file mode 100644 index 00000000000..130a7b871aa --- /dev/null +++ b/lib/libc/arch/arm26/string/memmove.S @@ -0,0 +1,48 @@ +/* $NetBSD: memmove.S,v 1.1 2000/05/09 21:55:50 bjh21 Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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> + +ENTRY(memmove) + stmfd sp!, {r0, lr} + bl _C_FUNC(_memcpy) +#ifdef __APCS_26__ + ldmfd sp!, {r0, pc}^ +#else + ldmfd sp!, {r0, pc} +#endif diff --git a/lib/libc/arch/arm26/string/memset.S b/lib/libc/arch/arm26/string/memset.S new file mode 100644 index 00000000000..b5ebc037b72 --- /dev/null +++ b/lib/libc/arch/arm26/string/memset.S @@ -0,0 +1,134 @@ +/* $NetBSD: memset.S,v 1.1 2000/05/09 21:55:50 bjh21 Exp $ */ + +/* + * Copyright (c) 1995 Mark Brinicombe. + * 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 Mark Brinicombe. + * 4. The name of the company nor the name of the author may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 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> + +/* + * Sets a block of memory to the specified value + * + * On entry: + * r0 - dest address + * r1 - byte to write + * r2 - number of bytes to write + * + * On exit: + * r0 - dest address + */ + +ENTRY(memset) + stmfd sp!, {r0} /* Remember address for return value */ + and r1, r1, #0x000000ff /* We write bytes */ + + cmp r2, #0x00000004 /* Do we have less than 4 bytes */ + blt Lmemset_lessthanfour + + /* Ok first we will word align the address */ + + ands r3, r0, #0x00000003 /* Get the bottom two bits */ + beq Lmemset_addraligned /* The address is word aligned */ + + rsb r3, r3, #0x00000004 + sub r2, r2, r3 + cmp r3, #0x00000002 + strb r1, [r0], #0x0001 /* Set 1 byte */ + strgeb r1, [r0], #0x0001 /* Set another byte */ + strgtb r1, [r0], #0x0001 /* and a third */ + + cmp r2, #0x00000004 + blt Lmemset_lessthanfour + + /* Now we must be word aligned */ + +Lmemset_addraligned: + + orr r3, r1, r1, lsl #8 /* Repeat the byte into a word */ + orr r3, r3, r3, lsl #16 + + /* We know we have at least 4 bytes ... */ + + cmp r2, #0x00000020 /* If less than 32 then use words */ + blt Lmemset_lessthan32 + + /* We have at least 32 so lets use quad words */ + + stmfd sp!, {r4-r6} /* Store registers */ + mov r4, r3 /* Duplicate data */ + mov r5, r3 + mov r6, r3 + +Lmemset_loop16: + stmia r0!, {r3-r6} /* Store 16 bytes */ + sub r2, r2, #0x00000010 /* Adjust count */ + cmp r2, #0x00000010 /* Still got at least 16 bytes ? */ + bgt Lmemset_loop16 + + ldmfd sp!, {r4-r6} /* Restore registers */ + + /* Do we need to set some words as well ? */ + + cmp r2, #0x00000004 + blt Lmemset_lessthanfour + + /* Have either less than 16 or less than 32 depending on route taken */ + +Lmemset_lessthan32: + + /* We have at least 4 bytes so copy as words */ + +Lmemset_loop4: + str r3, [r0], #0x0004 + sub r2, r2, #0x0004 + cmp r2, #0x00000004 + bge Lmemset_loop4 + +Lmemset_lessthanfour: + cmp r2, #0x00000000 + ldmeqfd sp!, {r0} +#ifdef __APCS_26__ + moveqs pc, lr /* Zero length so exit */ +#else + moveq pc, lr /* Zero length so exit */ +#endif + + cmp r2, #0x00000002 + strb r1, [r0], #0x0001 /* Set 1 byte */ + strgeb r1, [r0], #0x0001 /* Set another byte */ + strgtb r1, [r0], #0x0001 /* and a third */ + + ldmfd sp!, {r0} +#ifdef __APCS_26__ + movs pc, lr /* Exit */ +#else + mov pc, lr /* Exit */ +#endif diff --git a/lib/libc/arch/arm26/sys/Ovfork.S b/lib/libc/arch/arm26/sys/Ovfork.S new file mode 100644 index 00000000000..884eba6abcd --- /dev/null +++ b/lib/libc/arch/arm26/sys/Ovfork.S @@ -0,0 +1,59 @@ +/* $NetBSD: Ovfork.S,v 1.1 2000/05/09 21:55:50 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)Ovfork.s 5.1 (Berkeley) 4/23/90 + */ + +#include "SYS.h" + +WARN_REFERENCES(vfork, \ + "warning: reference to compatibility vfork(); include <unistd.h> for correct reference") + +/* + * pid = vfork(); + */ + .text + .align 0 + +ENTRY(vfork) + mov r2, r14 + swi SYS_vfork + bcs cerror + sub r1, r1, #0x00000001 + and r0, r0, r1 +#ifdef __APCS_26__ + movs r15, r2 +#else + mov r15, r2 +#endif diff --git a/lib/libc/arch/arm26/sys/__semctl.S b/lib/libc/arch/arm26/sys/__semctl.S new file mode 100644 index 00000000000..3499c9a3274 --- /dev/null +++ b/lib/libc/arch/arm26/sys/__semctl.S @@ -0,0 +1,42 @@ +/* $NetBSD: __semctl.S,v 1.1 2000/05/09 21:55:50 bjh21 Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 "SYS.h" + +PSEUDO(__semctl,compat_14___semctl) diff --git a/lib/libc/arch/arm26/sys/__sigreturn14.S b/lib/libc/arch/arm26/sys/__sigreturn14.S new file mode 100644 index 00000000000..3ba14dcc811 --- /dev/null +++ b/lib/libc/arch/arm26/sys/__sigreturn14.S @@ -0,0 +1,49 @@ +/* $NetBSD: __sigreturn14.S,v 1.1 2000/05/09 21:55:50 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)sigreturn.s 5.2 (Berkeley) 12/17/90" + */ + +#include "SYS.h" + +/* + * We must preserve the state of the registers as the user has set them up. + */ + +SYSCALL(__sigreturn14) +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif diff --git a/lib/libc/arch/arm26/sys/__vfork14.S b/lib/libc/arch/arm26/sys/__vfork14.S new file mode 100644 index 00000000000..8b867e6bfb2 --- /dev/null +++ b/lib/libc/arch/arm26/sys/__vfork14.S @@ -0,0 +1,56 @@ +/* $NetBSD: __vfork14.S,v 1.1 2000/05/09 21:55:50 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)Ovfork.s 5.1 (Berkeley) 4/23/90 + */ + +#include "SYS.h" + +/* + * pid = vfork(); + */ + .text + .align 0 + +ENTRY(__vfork14) + mov r2, r14 + swi SYS___vfork14 + bcs cerror + sub r1, r1, #0x00000001 + and r0, r0, r1 +#ifdef __APCS_26__ + movs r15, r2 +#else + mov r15, r2 +#endif diff --git a/lib/libc/arch/arm26/sys/brk.S b/lib/libc/arch/arm26/sys/brk.S new file mode 100644 index 00000000000..77f2cae79e2 --- /dev/null +++ b/lib/libc/arch/arm26/sys/brk.S @@ -0,0 +1,102 @@ +/* $NetBSD: brk.S,v 1.1 2000/05/09 21:55:51 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)brk.s 5.2 (Berkeley) 12/17/90 + */ + +#include "SYS.h" + + .globl _end + .globl curbrk + + .data + .align 0 + .globl _C_LABEL(__minbrk) + .type _C_LABEL(__minbrk),#object +_C_LABEL(__minbrk): + .word _end + +/* + * Change the data segment size + */ +ENTRY(brk) +#ifdef PIC + /* Setup the GOT */ + ldr r3, Lgot + add r3, pc, r3 +L1: + ldr r1, Lminbrk + ldr r1, [r3, r1] +#else + ldr r1, Lminbrk +#endif + /* Get the minimum allowable brk address */ + ldr r1, [r1] + + /* + * Valid the address specified and set to the minimum + * if the address is below minbrk. + */ + cmp r0, r1 + movlt r0, r1 + mov r2, r0 + swi SYS_break + bcs cerror + +#ifdef PIC + ldr r1, Lcurbrk + ldr r1, [r3, r1] +#else + ldr r1, Lcurbrk +#endif + /* Store the new address in curbrk */ + str r2, [r1] + + /* Return 0 for success */ + mov r0, #0x00000000 +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif + + .align 0 +#ifdef PIC +Lgot: + .word __GLOBAL_OFFSET_TABLE_+. - (L1+4) +#endif +Lminbrk: + .word _C_LABEL(__minbrk) +Lcurbrk: + .word curbrk diff --git a/lib/libc/arch/arm26/sys/cerror.S b/lib/libc/arch/arm26/sys/cerror.S new file mode 100644 index 00000000000..649e316056f --- /dev/null +++ b/lib/libc/arch/arm26/sys/cerror.S @@ -0,0 +1,83 @@ +/* $NetBSD: cerror.S,v 1.1 2000/05/09 21:55:51 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)cerror.s 5.1 (Berkeley) 4/23/90 + */ + +#include "SYS.h" + +ASENTRY(cerror) +#ifdef _REENTRANT + stmfd sp!, {r4, lr} + mov r4, r0 + bl _C_LABEL(__errno) + str r4, [r0] + mvn r0, #0x00000000 + mvn r1, #0x00000000 +#ifdef __APCS_26__ + ldmfd sp!, {r4, pc}^ +#else + ldmfd sp!, {r4, pc} +#endif +#else +#ifdef PIC + /* Setup the GOT */ + ldr r3, got + add r3, pc, r3 +L1: + ldr r1, Lerrno + ldr r1, [r3, r1] +#else + ldr r1, Lerrno +#endif /* PIC */ + str r0, [r1] + mvn r0, #0x00000000 + mvn r1, #0x00000000 +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif + +#ifdef PIC + .align 0 +got: + .word __GLOBAL_OFFSET_TABLE_ + (. - (L1+4)) +#endif /* PIC */ + + .globl _C_LABEL(errno) + +Lerrno: + .word _C_LABEL(errno) +#endif /* _REENTRANT */ diff --git a/lib/libc/arch/arm26/sys/exect.S b/lib/libc/arch/arm26/sys/exect.S new file mode 100644 index 00000000000..534b73b4ae2 --- /dev/null +++ b/lib/libc/arch/arm26/sys/exect.S @@ -0,0 +1,47 @@ +/* $NetBSD: exect.S,v 1.1 2000/05/09 21:55:51 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)exect.s 5.1 (Berkeley) 4/23/90 + */ + +#include "SYS.h" + +ENTRY(exect) + swi SYS_execve + bcs cerror +#ifdef __APCS_26__ + mov r15, r14 +#else + mov r15, r14 +#endif diff --git a/lib/libc/arch/arm26/sys/fork.S b/lib/libc/arch/arm26/sys/fork.S new file mode 100644 index 00000000000..b62b5a5f5bd --- /dev/null +++ b/lib/libc/arch/arm26/sys/fork.S @@ -0,0 +1,47 @@ +/* $NetBSD: fork.S,v 1.1 2000/05/09 21:55:51 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)fork.s 5.1 (Berkeley) 4/23/90 + */ + +#include "SYS.h" + +SYSCALL(fork) + sub r1, r1, #0x00000001 + and r0, r0, r1 +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif diff --git a/lib/libc/arch/arm26/sys/msgctl.S b/lib/libc/arch/arm26/sys/msgctl.S new file mode 100644 index 00000000000..6256c2b6ae5 --- /dev/null +++ b/lib/libc/arch/arm26/sys/msgctl.S @@ -0,0 +1,45 @@ +/* $NetBSD: msgctl.S,v 1.1 2000/05/09 21:55:51 bjh21 Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 "SYS.h" + +WARN_REFERENCES(msgctl, \ + "warning: reference to compatibility msgctl(); include <sys/msg.h> for correct reference") + +PSEUDO(msgctl,compat_14_msgctl) diff --git a/lib/libc/arch/arm26/sys/pipe.S b/lib/libc/arch/arm26/sys/pipe.S new file mode 100644 index 00000000000..5499c13ffa1 --- /dev/null +++ b/lib/libc/arch/arm26/sys/pipe.S @@ -0,0 +1,51 @@ +/* $NetBSD: pipe.S,v 1.1 2000/05/09 21:55:51 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)pipe.s 5.1 (Berkeley) 4/23/90 + */ + +#include "SYS.h" + +ENTRY(pipe) + mov r2, r0 + swi SYS_pipe + bcs cerror + str r0, [r2, #0x0000] + str r1, [r2, #0x0004] + mov r0, #0x00000000 +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif diff --git a/lib/libc/arch/arm26/sys/ptrace.S b/lib/libc/arch/arm26/sys/ptrace.S new file mode 100644 index 00000000000..2986a2d2bad --- /dev/null +++ b/lib/libc/arch/arm26/sys/ptrace.S @@ -0,0 +1,81 @@ +/* $NetBSD: ptrace.S,v 1.1 2000/05/09 21:55:51 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)ptrace.s 5.1 (Berkeley) 4/23/90 + */ + +#include "SYS.h" + +ENTRY(ptrace) +#ifdef _REENTRANT + stmfd sp!, {r0-r3, lr} + bl _C_LABEL(__errno) + mov r1, #0x00000000 + str r1, [r0] + ldmfd sp!, {r0-r3, lr} +#else + stmfd sp!, {r0, r1} +#ifdef PIC + /* Setup the GOT */ + ldr r0, got + add r0, pc, r0 +L1: + ldr r1, Lerrno + ldr r1, [r0, r1] +#else + ldr r1, Lerrno +#endif /* PIC */ + mov r0, #0x00000000 + str r0, [r1] + ldmfd sp!, {r0, r1} +#endif /* _REENTRANT */ + + swi SYS_ptrace + bcs cerror +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif + +#ifndef _REENTRANT +#ifdef PIC + .align 0 +got: + .word __GLOBAL_OFFSET_TABLE_ + (. - (L1+4)) +#endif /* PIC */ + +Lerrno: + .word _C_LABEL(errno) +#endif /* !_REENTRANT */ diff --git a/lib/libc/arch/arm26/sys/sbrk.S b/lib/libc/arch/arm26/sys/sbrk.S new file mode 100644 index 00000000000..618bfb1589d --- /dev/null +++ b/lib/libc/arch/arm26/sys/sbrk.S @@ -0,0 +1,90 @@ +/* $NetBSD: sbrk.S,v 1.1 2000/05/09 21:55:51 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)sbrk.s 5.1 (Berkeley) 4/23/90 + */ + +#include "SYS.h" + + .globl _C_LABEL(end) + + .data + .align 0 + .globl curbrk + .type curbrk,#object +curbrk: + .word _C_LABEL(end) + +/* + * Change the data segment size + */ +ENTRY(sbrk) +#ifdef PIC + /* Setup the GOT */ + ldr r3, Lgot + add r3, pc, r3 +L1: + ldr r2, Lcurbrk + ldr r2, [r3, r2] +#else + ldr r2, Lcurbrk +#endif + /* Get the current brk address */ + ldr r1, [r2] + + /* Calculate new value */ + mov r3, r0 + add r0, r0, r1 + swi SYS_break + bcs cerror + + /* Store new curbrk value */ + ldr r0, [r2] + add r1, r0, r3 + str r1, [r2] + + /* Return old curbrk value */ +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif + + .align 0 +#ifdef PIC +Lgot: + .word __GLOBAL_OFFSET_TABLE_+. - (L1+4) +#endif +Lcurbrk: + .word curbrk diff --git a/lib/libc/arch/arm26/sys/setlogin.S b/lib/libc/arch/arm26/sys/setlogin.S new file mode 100644 index 00000000000..b10d69815dc --- /dev/null +++ b/lib/libc/arch/arm26/sys/setlogin.S @@ -0,0 +1,69 @@ +/* $NetBSD: setlogin.S,v 1.1 2000/05/09 21:55:51 bjh21 Exp $ */ + +/*- + * 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. + * + * from: @(#)setlogin.s 5.2 (Berkeley) 4/12/91 + */ + +#include <machine/asm.h> +#include "SYS.h" + + .globl _C_LABEL(__logname_valid) /* in getlogin() */ + +SYSCALL(setlogin) +#ifdef PIC + /* Setup the GOT */ + ldr r0, got + add r0, pc, r0 +L1: + ldr r1, Llogname + ldr r1, [r0, r1] +#else + ldr r1, Llogname +#endif + mov r0, #0x00000000 + str r0, [r1] +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif + +#ifdef PIC + .align 0 +got: + .word __GLOBAL_OFFSET_TABLE_ + (. - (L1+4)) +#endif + +Llogname: + .word _C_LABEL(__logname_valid) diff --git a/lib/libc/arch/arm26/sys/shmctl.S b/lib/libc/arch/arm26/sys/shmctl.S new file mode 100644 index 00000000000..e8b77627eba --- /dev/null +++ b/lib/libc/arch/arm26/sys/shmctl.S @@ -0,0 +1,45 @@ +/* $NetBSD: shmctl.S,v 1.1 2000/05/09 21:55:51 bjh21 Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 "SYS.h" + +WARN_REFERENCES(shmctl, \ + "warning: reference to compatibility shmctl(); include <sys/shm.h> for correct reference") + +PSEUDO(shmctl,compat_14_shmctl) diff --git a/lib/libc/arch/arm26/sys/sigaction.S b/lib/libc/arch/arm26/sys/sigaction.S new file mode 100644 index 00000000000..5dd1f67a683 --- /dev/null +++ b/lib/libc/arch/arm26/sys/sigaction.S @@ -0,0 +1,45 @@ +/* $NetBSD: sigaction.S,v 1.1 2000/05/09 21:55:51 bjh21 Exp $ */ + +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 "SYS.h" + +WARN_REFERENCES(sigaction, \ + "warning: reference to compatibility sigaction(); include <signal.h> for correct reference") + +PSEUDO(sigaction,compat_13_sigaction13) diff --git a/lib/libc/arch/arm26/sys/sigpending.S b/lib/libc/arch/arm26/sys/sigpending.S new file mode 100644 index 00000000000..23f326a4e97 --- /dev/null +++ b/lib/libc/arch/arm26/sys/sigpending.S @@ -0,0 +1,53 @@ +/* $NetBSD: sigpending.S,v 1.1 2000/05/09 21:55:51 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)sigpending.s 5.1 (Berkeley) 7/1/90 + */ + +#include "SYS.h" + +WARN_REFERENCES(sigpending, \ + "warning: reference to compatibility sigpending(); include <signal.h> for correct reference") + +ENTRY(sigpending) + mov r2, r0 + swi SYS_compat_13_sigpending13 + bcs cerror + str r0, [r2] + mov r0, #0x00000000 +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif diff --git a/lib/libc/arch/arm26/sys/sigprocmask.S b/lib/libc/arch/arm26/sys/sigprocmask.S new file mode 100644 index 00000000000..413938afea0 --- /dev/null +++ b/lib/libc/arch/arm26/sys/sigprocmask.S @@ -0,0 +1,57 @@ +/* $NetBSD: sigprocmask.S,v 1.1 2000/05/09 21:55:52 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)sigprocmask.s 5.2 (Berkeley) 12/17/90 + */ + +#include "SYS.h" + +WARN_REFERENCES(sigprocmask, \ + "warning: reference to compatibility sigprocmask(); include <signal.h> for correct reference") + +ENTRY(sigprocmask) + teq r1, #0x00000000 + moveq r0, #0x00000001 + moveq r1, #0x00000000 + ldrne r1, [r1] + swi SYS_compat_13_sigprocmask13 + bcs cerror + teq r2, #0x00000000 + strne r0, [r2] + mov r0, #0x00000000 +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif diff --git a/lib/libc/arch/arm26/sys/sigreturn.S b/lib/libc/arch/arm26/sys/sigreturn.S new file mode 100644 index 00000000000..5d000888baa --- /dev/null +++ b/lib/libc/arch/arm26/sys/sigreturn.S @@ -0,0 +1,47 @@ +/* $NetBSD: sigreturn.S,v 1.1 2000/05/09 21:55:52 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)sigreturn.s 5.2 (Berkeley) 12/17/90" + */ + +#include "SYS.h" + +/* + * We must preserve the state of the registers as the user has set them up. + */ + +WARN_REFERENCES(sigreturn, \ + "warning: reference to compatibility sigreturn(); include <signal.h> for correct reference") + +PSEUDO(sigreturn,compat_13_sigreturn13) diff --git a/lib/libc/arch/arm26/sys/sigsuspend.S b/lib/libc/arch/arm26/sys/sigsuspend.S new file mode 100644 index 00000000000..85bd62244bf --- /dev/null +++ b/lib/libc/arch/arm26/sys/sigsuspend.S @@ -0,0 +1,52 @@ +/* $NetBSD: sigsuspend.S,v 1.1 2000/05/09 21:55:52 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)sigsuspend.s 5.2 (Berkeley) 12/17/90 + */ + +#include "SYS.h" + +WARN_REFERENCES(sigsuspend, \ + "warning: reference to compatibility sigsuspend(); include <signal.h> for correct reference") + +ENTRY(sigsuspend) + ldr r0, [r0] + swi SYS_compat_13_sigsuspend13 + bcs cerror + mov r0, #0x00000000 +#ifdef __APCS_26__ + mov r15, r14 +#else + movs r15, r14 +#endif diff --git a/lib/libc/arch/arm26/sys/syscall.S b/lib/libc/arch/arm26/sys/syscall.S new file mode 100644 index 00000000000..2103847cfd4 --- /dev/null +++ b/lib/libc/arch/arm26/sys/syscall.S @@ -0,0 +1,47 @@ +/* $NetBSD: syscall.S,v 1.1 2000/05/09 21:55:52 bjh21 Exp $ */ + +/*- + * Copyright (c) 1990 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. + * + * from: @(#)syscall.s 5.1 (Berkeley) 4/23/90 + */ + +#include "SYS.h" + +ENTRY(syscall) + swi 0x00000000 + bcs cerror +#ifdef __APCS_26__ + movs r15, r14 +#else + mov r15, r14 +#endif diff --git a/lib/libc/gen/nlist_private.h b/lib/libc/gen/nlist_private.h index 22be2e28300..5dfac3680ab 100644 --- a/lib/libc/gen/nlist_private.h +++ b/lib/libc/gen/nlist_private.h @@ -1,4 +1,4 @@ -/* $NetBSD: nlist_private.h,v 1.7 2000/01/03 02:13:32 msaitoh Exp $ */ +/* $NetBSD: nlist_private.h,v 1.8 2000/05/09 21:55:52 bjh21 Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. @@ -33,6 +33,8 @@ #if defined(__alpha__) # define NLIST_ECOFF # define NLIST_ELF64 +#elif defined(__arm26__) +# define NLIST_ELF32 #elif defined(__mips__) # define NLIST_AOUT # define NLIST_ECOFF diff --git a/lib/libc/rpc/xdr_float.c b/lib/libc/rpc/xdr_float.c index 4076013bbfa..03eb6459278 100644 --- a/lib/libc/rpc/xdr_float.c +++ b/lib/libc/rpc/xdr_float.c @@ -1,4 +1,4 @@ -/* $NetBSD: xdr_float.c,v 1.20 2000/01/22 22:19:18 mycroft Exp $ */ +/* $NetBSD: xdr_float.c,v 1.21 2000/05/09 21:55:52 bjh21 Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -35,7 +35,7 @@ static char *sccsid = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro"; static char *sccsid = "@(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC"; #else -__RCSID("$NetBSD: xdr_float.c,v 1.20 2000/01/22 22:19:18 mycroft Exp $"); +__RCSID("$NetBSD: xdr_float.c,v 1.21 2000/05/09 21:55:52 bjh21 Exp $"); #endif #endif @@ -71,7 +71,8 @@ __weak_alias(xdr_float,_xdr_float) #if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \ - defined(__arm32__) || defined(__powerpc__) || defined(__sh3__) + defined(__arm32__) || defined(__powerpc__) || defined(__sh3__) || \ + defined(__arm26__) #include <machine/endian.h> #define IEEEFP #endif diff --git a/lib/libc/stdlib/strtod.c b/lib/libc/stdlib/strtod.c index d163c9d0e2f..6a6102f626e 100644 --- a/lib/libc/stdlib/strtod.c +++ b/lib/libc/stdlib/strtod.c @@ -1,4 +1,4 @@ -/* $NetBSD: strtod.c,v 1.33 1999/11/26 07:39:45 msaitoh Exp $ */ +/* $NetBSD: strtod.c,v 1.34 2000/05/09 21:55:53 bjh21 Exp $ */ /**************************************************************** * @@ -93,7 +93,7 @@ #include <sys/cdefs.h> #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: strtod.c,v 1.33 1999/11/26 07:39:45 msaitoh Exp $"); +__RCSID("$NetBSD: strtod.c,v 1.34 2000/05/09 21:55:53 bjh21 Exp $"); #endif /* LIBC_SCCS and not lint */ #define Unsigned_Shifts @@ -108,7 +108,7 @@ __RCSID("$NetBSD: strtod.c,v 1.33 1999/11/26 07:39:45 msaitoh Exp $"); #endif #endif -#ifdef __arm32__ +#if defined(__arm32__) || defined(__arm26__) /* * Although the CPU is little endian the FP has different * byte and word endianness. The byte order is still little endian @@ -245,7 +245,8 @@ typedef union { * An alternative that might be better on some machines is * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) */ -#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm32__) +#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm32__) + \ + defined(__arm26__) #define Storeinc(a,b,c) \ (((u_short *)(void *)a)[1] = \ (u_short)b, ((u_short *)(void *)a)[0] = (u_short)c, a++) |
