newlib: update

git-svn-id: svn://kolibrios.org@1906 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2011-03-11 18:52:24 +00:00
parent a316fa7c9d
commit 2336060a0c
297 changed files with 26930 additions and 2094 deletions

View File

@ -0,0 +1,386 @@
CC = gcc
CFLAGS = -c -O2 -fomit-frame-pointer
LDFLAGS = -nostdlib -shared -s -T libcdll.lds --out-implib libcimp.a --image-base 0
LIBC_TOPDIR = .
LIBC_INCLUDES = $(LIBC_TOPDIR)/include
NAME:= libc
DEFINES:=
INCLUDES:= -I $(LIBC_INCLUDES)
AMZ_SRCS:= \
crt/crt_amz.S \
crt/chkstk.S \
crt/exit.S \
crt/pseudo-reloc.S \
crt/setjmp.S
STATIC_SRCS:= \
crt/start.S \
crt/crt1.c \
crt/chkstk.S \
crt/exit.S \
crt/setjmp.S
DLL_SRCS:= \
crt/crtdll.c \
crt/chkstk.S \
crt/exit.S \
crt/setjmp.S \
pe/loader.c
CORE_SRCS:= \
argz/buf_findstr.c \
argz/envz_get.c \
crt/emutls.c \
crt/thread.S \
crt/tls.S \
crt/assert.c \
crt/cpu_features.c \
ctype/ctype_.c \
ctype/isascii.c \
ctype/isblank.c \
ctype/isalnum.c \
ctype/isalpha.c \
ctype/iscntrl.c \
ctype/isdigit.c \
ctype/islower.c \
ctype/isupper.c \
ctype/isprint.c \
ctype/ispunct.c \
ctype/isspace.c \
ctype/iswctype.c \
ctype/iswalnum.c \
ctype/iswalpha.c \
ctype/iswblank.c \
ctype/iswcntrl.c \
ctype/iswdigit.c \
ctype/iswgraph.c \
ctype/iswlower.c \
ctype/iswprint.c \
ctype/iswpunct.c \
ctype/iswspace.c \
ctype/iswupper.c \
ctype/iswxdigit.c \
ctype/isxdigit.c \
ctype/toascii.c \
ctype/tolower.c \
ctype/toupper.c \
ctype/towctrans.c \
ctype/towlower.c \
ctype/towupper.c \
ctype/wctrans.c \
ctype/wctype.c \
errno/errno.c \
locale/locale.c \
locale/lctype.c \
reent/impure.c \
reent/getreent.c \
reent/gettimeofdayr.c \
reent/hdlman.c \
reent/isattyr.c \
reent/openr.c \
reent/closer.c \
reent/readr.c \
reent/lseekr.c \
reent/fstatr.c \
reent/writer.c \
search/qsort.c \
search/bsearch.c \
signal/signal.c \
sys/create.c \
sys/delete.c \
sys/finfo.c \
sys/read.c \
sys/write.c \
sys/fsize.c \
sys/fload.c \
time/asctime.c \
time/asctime_r.c \
time/clock.c \
time/ctime.c \
time/ctime_r.c \
time/difftime.c \
time/gettzinfo.c \
time/gmtime.c \
time/gmtime_r.c \
time/mktime.c \
time/mktm_r.c \
time/lcltime.c \
time/lcltime_r.c \
time/strftime.c \
time/time.c \
time/tzlock.c \
time/tzvars.c \
unpack/unpacker.asm
STDLIB_SRCS= \
__atexit.c \
__call_atexit.c \
abort.c \
abs.c \
atof.c \
atoi.c \
div.c \
dtoa.c \
dtoastub.c \
exit.c \
gdtoa-gethex.c \
gdtoa-hexnan.c \
getenv.c \
mprec.c \
mbtowc.c \
mbtowc_r.c \
mbrtowc.c \
mlock.c \
calloc.c \
malloc.c \
mallocr.c \
rand.c \
rand_r.c \
rand48.c \
realloc.c \
seed48.c \
srand48.c \
strtod.c \
strtol.c \
strtold.c \
strtoll.c \
strtoll_r.c \
strtoul.c \
strtoull.c \
strtoull_r.c \
system.c \
wcrtomb.c \
wctomb_r.c
STRING_SRCS= memcpy.c \
memcmp.c \
memmove.c \
memset.c \
memchr.c \
strcat.c \
strchr.c \
strcmp.c \
strcoll.c \
strcasecmp.c \
strncasecmp.c \
strncat.c \
strncmp.c \
strncpy.c \
strndup.c \
strndup_r.c \
strnlen.c \
strcasestr.c \
strdup.c \
strdup_r.c \
strerror.c \
strlen.c \
strrchr.c \
strpbrk.c \
strsep.c \
strstr.c \
strtok.c \
strtok_r.c \
strupr.c \
strcspn.c \
strspn.c \
strcpy.c \
u_strerr.c
STDIO_SRCS= \
printf.c \
putchar.c \
fgets.c \
fopen.c \
fclose.c \
fdopen.c \
fflush.c \
flags.c \
findfp.c \
fiprintf.c \
fiscanf.c \
fprintf.c \
fputc.c \
fputs.c \
fputwc.c \
fread.c \
freopen.c \
fscanf.c \
fseek.c \
fseeko.c \
ftell.c \
ftello.c \
fwrite.c \
fvwrite.c \
fwalk.c \
putc.c \
puts.c \
refill.c \
rget.c \
remove.c \
rename.c \
setvbuf.c \
stdio.c \
tmpfile.c \
tmpnam.c \
ungetc.c \
vscanf.c \
vsprintf.c \
vsnprintf.c \
vsscanf.c \
makebuf.c \
wsetup.c \
wbuf.c \
sccl.c \
snprintf.c \
sprintf.c \
sscanf.c
MATH_SRCS = acosf.c acosh.c acoshf.c acoshl.c acosl.c asinf.c asinh.c asinhf.c asinhl.c \
asinl.c atan2f.c atan2l.c atanf.c atanh.c atanhf.c atanhl.c atanl.c cbrt.c \
cbrtf.c cbrtl.c coshf.c coshl.c erfl.c expf.c expl.c expm1.c expm1f.c expm1l.c\
fabs.c fabsf.c fabsl.c fdim.c fdimf.c fdiml.c fmal.c fmax.c fmaxf.c fmaxl.c\
fmin.c fminf.c fminl.c fmodf.c fmodl.c fp_consts.c fp_constsf.c fp_constsl.c\
fpclassify.c fpclassifyf.c fpclassifyl.c frexpf.c fucom.c hypotf.c isnan.c \
isnanf.c isnanl.c ldexp.c ldexpf.c ldexpl.c lgamma.c lgammaf.c lgammal.c \
llrint.c llrintf.c llrintl.c logb.c logbf.c logbl.c lrint.c lrintf.c lrintl.c\
lround_generic.c modff.c modfl.c nextafterf.c nextafterl.c nexttoward.c \
nexttowardf.c pow.c powf.c powi.c powif.c powil.c powl.c rint.c rintf.c \
rintl.c round_generic.c s_erf.c sf_erf.c signbit.c signbitf.c signbitl.c \
sinhf.c sinhl.c sqrtf.c sqrtl.c tanhf.c tanhl.c tgamma.c tgammaf.c tgammal.c \
trunc.c truncf.c truncl.c e_sqrt.c e_sinh.c e_cosh.c e_hypot.c s_tanh.c \
s_roundf.c s_fpclassify.c s_isnand.c w_hypot.c s_modf.c e_atan2.c w_atan2.c\
ceil.S ceilf.S ceill.S copysign.S copysignf.S copysignl.S cos.S cosf.S cosl.S exp.S exp2.S \
exp2f.S exp2l.S floor.S floorf.S floorl.S fma.S fmaf.S frexp.S frexpl.S ilogb.S ilogbf.S \
ilogbl.S log10.S log10f.S log10l.S log1p.S log1pf.S log1pl.S log2.S log2f.S log2l.S \
log.S logf.S logl.S nearbyint.S nearbyintf.S nearbyintl.S remainder.S remainderf.S \
remainderl.S remquo.S remquof.S remquol.S scalbn.S scalbnf.S scalbnl.S sin.S \
sinf.S sinl.S tan.S tanf.S tanl.S s_expm1.S
AMZ_OBJS = $(patsubst %.S, %.o, $(AMZ_SRCS))
STATIC_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(STATIC_SRCS)))
DLL_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(DLL_SRCS)))
CORE_OBJS = $(patsubst %.S, %.o, $(patsubst %.asm, %.obj,\
$(patsubst %.c, %.o, $(CORE_SRCS))))
STDIO_OBJS = $(patsubst %.c, stdio/%.o,$(STDIO_SRCS))
STRING_OBJS = $(patsubst %.S, string/%.o, $(patsubst %.asm, string/%.o,\
$(patsubst %.c, string/%.o, $(STRING_SRCS))))
STDLIB_OBJS = $(patsubst %.S, stdlib/%.o, $(patsubst %.asm, stdlib/%.o,\
$(patsubst %.c, stdlib/%.o, $(STDLIB_SRCS))))
MATH_OBJS = $(patsubst %.S, math/%.o, $(patsubst %.asm, math/%.o,\
$(patsubst %.c, math/%.o, $(MATH_SRCS))))
PRINTF_OBJS= stdio/vfprintf.o \
stdio/vfiprintf.o \
stdio/svfprintf.o \
stdio/svfiprintf.o \
stdio/vfscanf.o \
stdio/vfiscanf.o \
stdio/svscanf.o \
stdio/svfiscanf.o
ifeq ($(findstring static,$(MAKECMDGOALS)),static)
LIB_SRCS:= $(STATIC_SRCS)
LIB_OBJS:= $(STATIC_OBJS)
else
LIB_SRCS:= $(DLL_SRCS)
LIB_OBJS:= $(DLL_OBJS)
endif
LIB_SRCS+= \
$(CORE_SRCS) \
$(STDIO_SRCS) \
$(STRING_SRCS) \
$(STDLIB_SRCS)
LIB_OBJS+= \
$(CORE_OBJS) \
$(STRING_OBJS) \
$(STDLIB_OBJS) \
$(STDIO_OBJS) \
$(PRINTF_OBJS) \
$(MATH_OBJS)
shared: $(NAME).dll libamz.a
$(NAME).dll: $(LIB_OBJS) $(SRC_DEP) Makefile
ld $(LDFLAGS) -L. -o $@ $(LIB_OBJS) -lgcc
libamz.a: $(AMZ_OBJS) Makefile
ar rc libamz.a $(AMZ_OBJS)
static: $(NAME).a
$(NAME).a: $(LIB_OBJS) $(SRC_DEP) Makefile
ar rc $(NAME).a $(LIB_OBJS)
stdio/vfprintf.o: stdio/vfprintf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -fshort-enums -DFLOATING_POINT -c stdio/vfprintf.c -o $@
stdio/vfiprintf.o: stdio/vfprintf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -fshort-enums -DINTEGER_ONLY -c stdio/vfprintf.c -o $@
stdio/svfprintf.o: stdio/vfprintf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -fshort-enums -DSTRING_ONLY -c stdio/vfprintf.c -o $@
stdio/svfiprintf.o: stdio/vfprintf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -fshort-enums -DINTEGER_ONLY -DSTRING_ONLY -c stdio/vfprintf.c -o $@
stdio/vfscanf.o: stdio/vfscanf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) stdio/vfscanf.c -o $@
stdio/vfiscanf.o: stdio/vfscanf.c
$(CC) $(CFLAGS) $(DEFINES) -DINTEGER_ONLY $(INCLUDES) stdio/vfscanf.c -o $@
stdio/svscanf.o: stdio/vfscanf.c
$(CC) $(CFLAGS) $(DEFINES) -DSTRING_ONLY $(INCLUDES) stdio/vfscanf.c -o $@
stdio/svfiscanf.o: stdio/vfscanf.c
$(CC) $(CFLAGS) $(DEFINES) -DINTEGER_ONLY -DSTRING_ONLY $(INCLUDES) stdio/vfscanf.c -o $@
%.obj : %.asm Makefile
fasm $< $@
%.o : %.c Makefile
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
clean:
-rm -f */*.o

View File

@ -0,0 +1,44 @@
/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software
* is freely granted, provided that this notice is preserved.
*/
#include <errno.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include "buf_findstr.h"
/* Find string str in buffer buf of length buf_len. Point buf to character after string,
or set it to NULL if end of buffer is reached. Return 1 if found, 0 if not. */
int
_buf_findstr(const char *str, char **buf, size_t *buf_len)
{
int i = 0;
int j = 0;
for (i = 0; i < *buf_len; i++)
{
if (str[0] == (*buf)[i])
{
j = i;
while (str[j - i] && (str[j - i] == (*buf)[j])) j++;
if(str[j - i] == '\0')
{
*buf += j;
*buf_len -= j;
return 1;
}
}
}
if (i == *buf_len)
{
*buf += *buf_len;
*buf_len = 0;
}
return 0;
}

View File

@ -0,0 +1,12 @@
/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software
* is freely granted, provided that this notice is preserved.
*/
#include <sys/types.h>
/* Find string str in buffer buf of length buf_len. Point buf to
character after string, or set it to NULL if end of buffer is
reached. Return 1 if found, 0 if not. */
int _buf_findstr(const char *str, char **buf, size_t *buf_len);

View File

@ -0,0 +1,43 @@
/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software
* is freely granted, provided that this notice is preserved.
*/
#include <errno.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <envz.h>
#include "buf_findstr.h"
char *
_DEFUN (envz_get, (envz, envz_len, name),
const char *envz _AND
size_t envz_len _AND
const char *name)
{
char *buf_ptr = (char *)envz;
size_t buf_len = envz_len;
while(buf_len)
{
if (_buf_findstr(name, &buf_ptr, &buf_len))
{
if (*buf_ptr == '=')
{
buf_ptr++;
return (char *)buf_ptr;
}
else
{
if (*buf_ptr == '\0')
/* NULL entry. */
return NULL;
}
}
}
/* No matching entries found. */
return NULL;
}

View File

@ -0,0 +1,74 @@
/*
FUNCTION
<<assert>>---macro for debugging diagnostics
INDEX
assert
ANSI_SYNOPSIS
#include <assert.h>
void assert(int <[expression]>);
DESCRIPTION
Use this macro to embed debuggging diagnostic statements in
your programs. The argument <[expression]> should be an
expression which evaluates to true (nonzero) when your program
is working as you intended.
When <[expression]> evaluates to false (zero), <<assert>>
calls <<abort>>, after first printing a message showing what
failed and where:
. Assertion failed: <[expression]>, file <[filename]>, line <[lineno]>, function: <[func]>
If the name of the current function is not known (for example,
when using a C89 compiler that does not understand __func__),
the function location is omitted.
The macro is defined to permit you to turn off all uses of
<<assert>> at compile time by defining <<NDEBUG>> as a
preprocessor variable. If you do this, the <<assert>> macro
expands to
. (void(0))
RETURNS
<<assert>> does not return a value.
PORTABILITY
The <<assert>> macro is required by ANSI, as is the behavior
when <<NDEBUG>> is defined.
Supporting OS subroutines required (only if enabled): <<close>>, <<fstat>>,
<<getpid>>, <<isatty>>, <<kill>>, <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
/* func can be NULL, in which case no function information is given. */
void
_DEFUN (__assert_func, (file, line, func, failedexpr),
const char *file _AND
int line _AND
const char *func _AND
const char *failedexpr)
{
fiprintf(stderr,
"assertion \"%s\" failed: file \"%s\", line %d%s%s\n",
failedexpr, file, line,
func ? ", function: " : "", func ? func : "");
abort();
/* NOTREACHED */
}
void
_DEFUN (_assert, (file, line, failedexpr),
const char *file _AND
int line _AND
const char *failedexpr)
{
__assert_func (file, line, NULL, failedexpr);
/* NOTREACHED */
}

View File

@ -4,7 +4,6 @@
.section .text
.align 4
___chkstk:
__alloca:
pushl %ecx /* save temp */
@ -27,3 +26,4 @@ __alloca:
int3 #trap to debugger
.ascii "Stack overflow"

View File

@ -16,6 +16,9 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/kos_io.h>
#include "cpu_features.h"
@ -51,8 +54,6 @@ char * __libc_getenv(const char *name)
}
void __main (){};
void init_reent();
void __attribute__((noreturn))
@ -73,10 +74,25 @@ __thread_startup (int (*entry)(void*), void *param,
_exit(retval);
};
struct app_hdr
{
char banner[8];
int version;
int start;
int iend;
int memsize;
int stacktop;
char *cmdline;
char *path;
};
void __attribute__((noreturn))
__crt_startup (void)
{
int nRet;
struct app_hdr *header;
init_reent();
@ -89,12 +105,12 @@ __crt_startup (void)
__initPOSIXHandles();
__appcwdlen = strrchr(&__pgmname, '/') - &__pgmname + 1;
__appcwdlen = __appcwdlen > 1023 ? 1023 : __appcwdlen;
strncpy(__appcwd, &__pgmname, __appcwdlen);
memcpy(__appcwd, &__pgmname, __appcwdlen);
__appcwd[__appcwdlen] = 0;
set_cwd(__appcwd);
arg[0] = &__pgmname;
if( __cmdline != 0)
@ -113,13 +129,14 @@ __crt_startup (void)
*/
// _mingw32_init_fmode ();
nRet = main (_argc, _argv, NULL);
/*
* Perform exit processing for the C library. This means
* flushing output and calling 'atexit' registered functions.
*/
_exit (nRet);
exit (nRet);
}

View File

@ -0,0 +1,15 @@
.section .text
.global __start
.global ___main
.align 4
__start:
jmp _main
.align 4
___main:
ret

View File

@ -0,0 +1,144 @@
#include <_ansi.h>
#include <reent.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <setjmp.h>
#include <sys/kos_io.h>
struct app_hdr
{
char banner[8];
int version;
int start;
int iend;
int memsize;
int stacktop;
char *cmdline;
char *path;
};
int _argc;
char **_argv;
void __fastcall init_loader(void *libc_image);
void* __fastcall create_image(void *raw);
int __fastcall link_image(void *img_base);
void* get_entry_point(void *raw);
int (*entry)(int, char **, char **);
void init_reent();
jmp_buf loader_env;
void __attribute__((noreturn))
__thread_startup (int (*entry)(void*), void *param,
void *stacklow, void *stackhigh)
{
int retval;
asm volatile ( "xchgw %bx, %bx");
__asm__ __volatile__( // save stack limits
"movl %0, %%fs:4 \n\t" // use TLS
"movl %1, %%fs:8 \n\t"
::"r"(stacklow), "r"(stackhigh));
init_reent(); // initialize thread reentry structure
retval = entry(param); // call user thread function
_exit(retval);
};
char * __libc_getenv(const char *name)
{
return NULL;
}
char __appcwd[1024];
int __appcwdlen;
char* __appenv;
int __appenv_size;
void __attribute__((noreturn))
crt_startup (void *libc_base, void *obj_base, uint32_t *params)
{
struct app_hdr *header;
char *arg[2];
int len;
char *p;
void *my_app;
int retval = 0;
// user_free(obj_base);
init_reent();
__initPOSIXHandles();
__appenv = load_file("/sys/system.env", &__appenv_size);
init_loader(libc_base);
my_app = create_image((void*)(params[0]));
if( link_image(my_app)==0)
goto done;
header = (struct app_hdr*)NULL;
__appcwdlen = strrchr(header->path, '/') - header->path;
__appcwdlen = __appcwdlen > 1022 ? 1022 : __appcwdlen;
memcpy(__appcwd, header->path, __appcwdlen);
set_cwd(__appcwd);
#ifdef BRAVE_NEW_WORLD
len = strlen(header->path);
p = alloca(len+1);
memcpy(p, header->path, len);
p[len]=0;
arg[0] = p;
#else
arg[0] = header->path;
#endif
_argc = 1;
if( header->cmdline != 0)
{
#ifdef BRAVE_NEW_WORLD
len = strlen(header->cmdline);
if(len)
{
p = alloca(len+1);
memcpy(p, header->cmdline, len);
p[len]=0;
_argc = 2;
arg[1] = p;
};
#else
_argc = 2;
arg[1] = header->cmdline;
#endif
};
_argv = arg;
entry = get_entry_point(my_app);
// __asm__ __volatile__("int3");
retval = entry(_argc, _argv, NULL);
done:
exit (retval);
}

View File

@ -0,0 +1,218 @@
/* TLS emulation.
Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#include <stdlib.h>
#include <memory.h>
#include <malloc.h>
#include <errno.h>
#include <gthr.h>
void *tls_alloc(void);
void __mutex_lock(volatile int *val);
static inline void yield(void)
{
__asm__ __volatile__(
"int $0x40"
::"a"(68), "b"(1));
};
int __gthread_once (__gthread_once_t *once, void (*func) (void))
{
if (once == NULL || func == NULL)
return EINVAL;
if (! once->done)
{
if(++once->started == 0)
{
(*func) ();
once->done = 1;
}
else
{
/* Another thread is currently executing the code, so wait for it
to finish; yield the CPU in the meantime. If performance
does become an issue, the solution is to use an Event that
we wait on here (and set above), but that implies a place to
create the event before this routine is called. */
while (! once->done)
yield();
}
}
return 0;
}
#define __GTHREAD_ONCE_INIT {0, -1}
typedef unsigned int word __attribute__((mode(word)));
typedef unsigned int pointer __attribute__((mode(pointer)));
struct __emutls_object
{
word size;
word align;
union {
pointer offset;
void *ptr;
} loc;
void *templ;
};
struct __emutls_array
{
pointer size;
void **data[];
};
void *__emutls_get_address (struct __emutls_object *);
void __emutls_register_common (struct __emutls_object *, word, word, void *);
static __gthread_mutex_t emutls_mutex;
static __gthread_key_t emutls_key;
static pointer emutls_size;
static void emutls_destroy (void *ptr)
{
struct __emutls_array *arr = ptr;
pointer size = arr->size;
pointer i;
for (i = 0; i < size; ++i)
{
if (arr->data[i])
free (arr->data[i][-1]);
}
free (ptr);
};
static void emutls_init (void)
{
if (__gthread_key_create (&emutls_key, emutls_destroy) != 0)
abort ();
}
static void *emutls_alloc (struct __emutls_object *obj)
{
void *ptr;
void *ret;
/* We could use here posix_memalign if available and adjust
emutls_destroy accordingly. */
if (obj->align <= sizeof (void *))
{
ptr = malloc (obj->size + sizeof (void *));
if (ptr == NULL)
abort ();
((void **) ptr)[0] = ptr;
ret = ptr + sizeof (void *);
}
else
{
ptr = malloc (obj->size + sizeof (void *) + obj->align - 1);
if (ptr == NULL)
abort ();
ret = (void *) (((pointer) (ptr + sizeof (void *) + obj->align - 1))
& ~(pointer)(obj->align - 1));
((void **) ret)[-1] = ptr;
}
if (obj->templ)
memcpy (ret, obj->templ, obj->size);
else
memset (ret, 0, obj->size);
return ret;
}
void * __emutls_get_address (struct __emutls_object *obj)
{
pointer offset = obj->loc.offset;
if (__builtin_expect (offset == 0, 0))
{
static __gthread_once_t once = __GTHREAD_ONCE_INIT;
__gthread_once (&once, emutls_init);
__gthread_mutex_lock (&emutls_mutex);
offset = obj->loc.offset;
if (offset == 0)
{
offset = ++emutls_size;
obj->loc.offset = offset;
}
__gthread_mutex_unlock (&emutls_mutex);
}
struct __emutls_array *arr = __gthread_getspecific (emutls_key);
if (__builtin_expect (arr == NULL, 0))
{
pointer size = offset + 32;
arr = calloc (size + 1, sizeof (void *));
if (arr == NULL)
abort ();
arr->size = size;
__gthread_setspecific (emutls_key, (void *) arr);
}
else if (__builtin_expect (offset > arr->size, 0))
{
pointer orig_size = arr->size;
pointer size = orig_size * 2;
if (offset > size)
size = offset + 32;
arr = realloc (arr, (size + 1) * sizeof (void *));
if (arr == NULL)
abort ();
arr->size = size;
memset (arr->data + orig_size, 0,
(size - orig_size) * sizeof (void *));
__gthread_setspecific (emutls_key, (void *) arr);
}
void *ret = arr->data[offset - 1];
if (__builtin_expect (ret == NULL, 0))
{
ret = emutls_alloc (obj);
arr->data[offset - 1] = ret;
}
return ret;
}
void __emutls_register_common (struct __emutls_object *obj,
word size, word align, void *templ)
{
if (obj->size < size)
{
obj->size = size;
obj->templ = NULL;
}
if (obj->align < align)
obj->align = align;
if (templ && size == obj->size)
obj->templ = templ;
}

View File

@ -0,0 +1,20 @@
.section .text
.global __exit
.global __Exit
.align 4
__exit:
__Exit:
movl 4(%esp), %edx #store exit code
movl $68, %eax
movl $13, %ebx
movl %fs:4, %ecx
int $0x40 #destroy stack
movl $-1, %eax
int $0x40 #terminate thread

View File

@ -0,0 +1,76 @@
/* This file was based on the modified setjmp.S performed by
* Joel Sherill (joel@OARcorp.com) which specified the use
* of the __USER_LABEL_PREFIX__ and __REGISTER_PREFIX__ macros.
**
** This file is distributed WITHOUT ANY WARRANTY; without even the implied
** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/* These are predefined by new versions of GNU cpp. */
#ifndef __USER_LABEL_PREFIX__
#define __USER_LABEL_PREFIX__ _
#endif
#define __REG_PREFIX__ %
/* ANSI concatenation macros. */
#define CONCAT1(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a##b
/* Use the right prefix for global labels. */
#define SYM(x) CONCAT1(__USER_LABEL_PREFIX__, x)
/* Use the right prefix for registers. */
#define REG(x) CONCAT1(__REG_PREFIX__, x)
#define eax REG(eax)
#define ebx REG(ebx)
#define ecx REG(ecx)
#define edx REG(edx)
#define esi REG(esi)
#define edi REG(edi)
#define ebp REG(ebp)
#define esp REG(esp)
#define st0 REG(st)
#define st1 REG(st(1))
#define st2 REG(st(2))
#define st3 REG(st(3))
#define st4 REG(st(4))
#define st5 REG(st(5))
#define st6 REG(st(6))
#define st7 REG(st(7))
#define ax REG(ax)
#define bx REG(bx)
#define cx REG(cx)
#define dx REG(dx)
#define ah REG(ah)
#define bh REG(bh)
#define ch REG(ch)
#define dh REG(dh)
#define al REG(al)
#define bl REG(bl)
#define cl REG(cl)
#define dl REG(dl)
#define mm1 REG(mm1)
#define mm2 REG(mm2)
#define mm3 REG(mm3)
#define mm4 REG(mm4)
#define mm5 REG(mm5)
#define mm6 REG(mm6)
#define mm7 REG(mm7)
#ifdef _I386MACH_NEED_SOTYPE_FUNCTION
#define SOTYPE_FUNCTION(sym) .type SYM(sym),@function
#else
#define SOTYPE_FUNCTION(sym)
#endif

View File

@ -0,0 +1,26 @@
.global __pei386_runtime_relocator
.text
__pei386_runtime_relocator:
# movl $___RUNTIME_PSEUDO_RELOC_LIST__, %ecx
# pushl %ebp
# cmpl $___RUNTIME_PSEUDO_RELOC_LIST_END__, %ecx
# movl %esp, %ebp
# jnb .L2
#.L1:
# movl (%ecx), %eax
# movl 4(%ecx), %edx
# addl $8, %ecx
# addl %eax, __image_base__(%edx)
# cmpl $___RUNTIME_PSEUDO_RELOC_LIST_END__, %ecx
# jb .L1
#.L2:
# popl %ebp
ret

View File

@ -0,0 +1,89 @@
/* This is file is a merger of SETJMP.S and LONGJMP.S */
/*
* This file was modified to use the __USER_LABEL_PREFIX__ and
* __REGISTER_PREFIX__ macros defined by later versions of GNU cpp by
* Joel Sherrill (joel@OARcorp.com)
* Slight change: now includes i386mach.h for this (Werner Almesberger)
*
* Copyright (C) 1991 DJ Delorie
* All rights reserved.
*
* Redistribution and use in source and binary forms is permitted
* provided that the above copyright notice and following paragraph are
* duplicated in all such forms.
*
* This file is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
** jmp_buf:
** eax ebx ecx edx esi edi ebp esp eip
** 0 4 8 12 16 20 24 28 32
*/
#include "i386mach.h"
.global SYM (setjmp)
.global SYM (longjmp)
SOTYPE_FUNCTION(setjmp)
SOTYPE_FUNCTION(longjmp)
.def _setjmp; .scl 2; .type 32; .endef
SYM (setjmp):
pushl ebp
movl esp,ebp
pushl edi
movl 8 (ebp),edi
movl eax,0 (edi)
movl ebx,4 (edi)
movl ecx,8 (edi)
movl edx,12 (edi)
movl esi,16 (edi)
movl -4 (ebp),eax
movl eax,20 (edi)
movl 0 (ebp),eax
movl eax,24 (edi)
movl esp,eax
addl $12,eax
movl eax,28 (edi)
movl 4 (ebp),eax
movl eax,32 (edi)
popl edi
movl $0,eax
leave
ret
.def _longjmp; .scl 2; .type 32; .endef
SYM (longjmp):
pushl ebp
movl esp,ebp
movl 8(ebp),edi /* get jmp_buf */
movl 12(ebp),eax /* store retval in j->eax */
movl eax,0(edi)
movl 24(edi),ebp
movl 28(edi),esp
pushl 32(edi)
movl 0(edi),eax
movl 4(edi),ebx
movl 8(edi),ecx
movl 12(edi),edx
movl 16(edi),esi
movl 20(edi),edi
ret

View File

@ -2,8 +2,6 @@
.section .init
.global __start
.global __exit
.global __Exit
.align 4
__start:
@ -20,21 +18,30 @@ __start:
movl %eax, %fs:4
movl %ecx, %fs:8 #save stack base - low limit
#save stack top - high limit
movl %ecx, %esp
jmp ___crt_startup #reload stack
movl %ecx, %esp #reload stack
subl $1024, %esp
movl $9, %eax
movl %esp, %ebx
movl $-1, %ecx
int $0x40
movl 30(%ebx), %eax
movl %eax, %fs:0 #save pid
movl $__tls_map, %edi #init TLS
movl $32, %ecx
xorl %eax, %eax
notl %eax
rep
stosl
movb $0xF0, __tls_map
jmp ___crt_startup
1:
int3 #trap to debugger
.ascii "No enough memory for stack allocation"
.align 4
__exit:
__Exit:
movl 4(%esp), %edx #store exit code
movl $68, %eax
movl $13, %ebx
movl %fs:4, %ecx
int $0x40 #destroy stack
movl $-1, %eax
int $0x40 #terminate thread

View File

@ -0,0 +1,48 @@
.section .text
.global _tls_alloc
.global __tls_map
.align 4
_tls_alloc:
pushl $tls_mutex
call ___mutex_lock
popl %eax
movl tls_map_start, %edx
.align 4
.test:
bsfl (%edx), %eax
jnz .done
add $4, %edx
cmpl $128+__tls_map, %edx
jb .test
xorl %eax, %eax
mov %eax, tls_mutex
ret
.done:
btrl %eax, (%edx)
movl %edx, tls_map_start
movl $0, tls_mutex
subl $__tls_map, %edx
leal (%eax, %edx, 8), %eax
shll $2, %eax
ret
.section .data
tls_mutex: .long(0)
tls_map_start: .long(__tls_map)
.section .bss
.align 16
__tls_map: .space 128

View File

@ -0,0 +1,43 @@
/*
FUNCTION
<<isascii>>---ASCII character predicate
INDEX
isascii
ANSI_SYNOPSIS
#include <ctype.h>
int isascii(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int isascii(<[c]>);
DESCRIPTION
<<isascii>> is a macro which returns non-zero when <[c]> is an ASCII
character, and 0 otherwise. It is defined for all integer values.
You can use a compiled subroutine instead of the macro definition by
undefining the macro using `<<#undef isascii>>'.
RETURNS
<<isascii>> returns non-zero if the low order byte of <[c]> is in the range
0 to 127 (<<0x00>>--<<0x7F>>).
PORTABILITY
<<isascii>> is ANSI C.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef isascii
int
_DEFUN(isascii,(c),int c)
{
return c >= 0 && c< 128;
}

View File

@ -0,0 +1,41 @@
/*
FUNCTION
<<isblank>>---blank character predicate
INDEX
isblank
ANSI_SYNOPSIS
#include <ctype.h>
int isblank(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int isblank(<[c]>);
DESCRIPTION
<<isblank>> is a function which classifies ASCII integer values by table
lookup. It is a predicate returning non-zero for blank characters, and 0
for other characters.
RETURNS
<<isblank>> returns non-zero if <[c]> is a blank character.
PORTABILITY
<<isblank>> is C99.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef isblank
int
_DEFUN(isblank,(c),int c)
{
return ((__ctype_ptr__[c+1] & _B) || (c == '\t'));
}

View File

@ -0,0 +1,41 @@
/*
FUNCTION
<<toascii>>---force integers to ASCII range
INDEX
toascii
ANSI_SYNOPSIS
#include <ctype.h>
int toascii(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int toascii(<[c]>);
int (<[c]>);
DESCRIPTION
<<toascii>> is a macro which coerces integers to the ASCII range (0--127) by zeroing any higher-order bits.
You can use a compiled subroutine instead of the macro definition by
undefining this macro using `<<#undef toascii>>'.
RETURNS
<<toascii>> returns integers between 0 and 127.
PORTABILITY
<<toascii>> is not ANSI C.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef toascii
int
_DEFUN(toascii,(c),int c)
{
return (c)&0177;
}

View File

@ -0,0 +1,97 @@
/* Copyright (c) 2002 Red Hat Incorporated.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
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.
The name of Red Hat Incorporated may not be used to endorse
or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 RED HAT INCORPORATED 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.
*/
/*
FUNCTION
<<towctrans>>---extensible wide-character translation
INDEX
towctrans
ANSI_SYNOPSIS
#include <wctype.h>
wint_t towctrans(wint_t <[c]>, wctrans_t <[w]>);
TRAD_SYNOPSIS
#include <wctype.h>
wint_t towctrans(<[c]>, <[w]>)
wint_t <[c]>;
wctrans_t <[w]>;
DESCRIPTION
<<towctrans>> is a function which converts wide characters based on
a specified translation type <[w]>. If the translation type is
invalid or cannot be applied to the current character, no change
to the character is made.
RETURNS
<<towctrans>> returns the translated equivalent of <[c]> when it is a
valid for the given translation, otherwise, it returns the input character.
When the translation type is invalid, <<errno>> is set <<EINVAL>>.
PORTABILITY
<<towctrans>> is C99.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <string.h>
#include <reent.h>
#include <wctype.h>
#include <errno.h>
#include "local.h"
wint_t
_DEFUN (_towctrans_r, (r, c, w),
struct _reent *r _AND
wint_t c _AND
wctrans_t w)
{
if (w == WCT_TOLOWER)
return towlower (c);
else if (w == WCT_TOUPPER)
return towupper (c);
else
{
r->_errno = EINVAL;
return c;
}
}
#ifndef _REENT_ONLY
wint_t
_DEFUN (towctrans, (c, w),
wint_t c _AND
wctrans_t w)
{
return _towctrans_r (_REENT, c, w);
}
#endif /* !_REENT_ONLY */

View File

@ -0,0 +1,94 @@
/* Copyright (c) 2002 Red Hat Incorporated.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
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.
The name of Red Hat Incorporated may not be used to endorse
or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 RED HAT INCORPORATED 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.
*/
/*
FUNCTION
<<wctrans>>---get wide-character translation type
INDEX
wctrans
ANSI_SYNOPSIS
#include <wctype.h>
wctrans_t wctrans(const char *<[c]>);
TRAD_SYNOPSIS
#include <wctype.h>
wctrans_t wctrans(<[c]>)
const char * <[c]>;
DESCRIPTION
<<wctrans>> is a function which takes a string <[c]> and gives back
the appropriate wctrans_t type value associated with the string,
if one exists. The following values are guaranteed to be recognized:
"tolower" and "toupper".
RETURNS
<<wctrans>> returns 0 and sets <<errno>> to <<EINVAL>> if the
given name is invalid. Otherwise, it returns a valid non-zero wctrans_t
value.
PORTABILITY
<<wctrans>> is C99.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <string.h>
#include <reent.h>
#include <wctype.h>
#include <errno.h>
#include "local.h"
wctrans_t
_DEFUN (_wctrans_r, (r, c),
struct _reent *r _AND
const char *c)
{
if (!strcmp (c, "tolower"))
return WCT_TOLOWER;
else if (!strcmp (c, "toupper"))
return WCT_TOUPPER;
else
{
r->_errno = EINVAL;
return 0;
}
}
#ifndef _REENT_ONLY
wctrans_t
_DEFUN (wctrans, (c),
const char *c)
{
return _wctrans_r (_REENT, c);
}
#endif /* !_REENT_ONLY */

View File

@ -0,0 +1,137 @@
/* Copyright (c) 2002 Red Hat Incorporated.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
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.
The name of Red Hat Incorporated may not be used to endorse
or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 RED HAT INCORPORATED 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.
*/
/*
FUNCTION
<<wctype>>---get wide-character classification type
INDEX
wctype
ANSI_SYNOPSIS
#include <wctype.h>
wctype_t wctype(const char *<[c]>);
TRAD_SYNOPSIS
#include <wctype.h>
wctype_t wctype(<[c]>)
const char * <[c]>;
DESCRIPTION
<<wctype>> is a function which takes a string <[c]> and gives back
the appropriate wctype_t type value associated with the string,
if one exists. The following values are guaranteed to be recognized:
"alnum", "alpha", "blank", "cntrl", "digit", "graph", "lower", "print",
"punct", "space", "upper", and "xdigit".
RETURNS
<<wctype>> returns 0 and sets <<errno>> to <<EINVAL>> if the
given name is invalid. Otherwise, it returns a valid non-zero wctype_t
value.
PORTABILITY
<<wctype>> is C99.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <string.h>
#include <reent.h>
#include <wctype.h>
#include <errno.h>
#include "local.h"
wctype_t
_DEFUN (_wctype_r, (r, c),
struct _reent *r _AND
const char *c)
{
switch (*c)
{
case 'a':
if (!strcmp (c, "alnum"))
return WC_ALNUM;
else if (!strcmp (c, "alpha"))
return WC_ALPHA;
break;
case 'b':
if (!strcmp (c, "blank"))
return WC_BLANK;
break;
case 'c':
if (!strcmp (c, "cntrl"))
return WC_CNTRL;
break;
case 'd':
if (!strcmp (c, "digit"))
return WC_DIGIT;
break;
case 'g':
if (!strcmp (c, "graph"))
return WC_GRAPH;
break;
case 'l':
if (!strcmp (c, "lower"))
return WC_LOWER;
break;
case 'p':
if (!strcmp (c, "print"))
return WC_PRINT;
else if (!strcmp (c, "punct"))
return WC_PUNCT;
break;
case 's':
if (!strcmp (c, "space"))
return WC_SPACE;
break;
case 'u':
if (!strcmp (c, "upper"))
return WC_UPPER;
break;
case 'x':
if (!strcmp (c, "xdigit"))
return WC_XDIGIT;
break;
}
/* otherwise invalid */
r->_errno = EINVAL;
return 0;
}
#ifndef _REENT_ONLY
wctype_t
_DEFUN (wctype, (c),
const char *c)
{
return _wctype_r (_REENT, c);
}
#endif /* !_REENT_ONLY */

View File

@ -0,0 +1,126 @@
OUTPUT_FORMAT(pei-i386)
ENTRY("__start")
SECTIONS
{
. = SIZEOF_HEADERS;
. = ALIGN(__section_alignment__);
.text __image_base__ + . :
{
*(.init)
*(.text)
*(SORT(.text$*))
*(.text.*)
*(.glue_7t)
*(.glue_7)
___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0);
___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0);
*(.fini)
/* ??? Why is .gcc_exc here? */
*(.gcc_exc)
PROVIDE (etext = .);
*(.gcc_except_table)
}
.rdata ALIGN(__section_alignment__):
{
*(.rdata)
*(SORT(.rdata$*))
___RUNTIME_PSEUDO_RELOC_LIST__ = .;
__RUNTIME_PSEUDO_RELOC_LIST__ = .;
*(.rdata_runtime_pseudo_reloc)
___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
__RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
}
.CRT ALIGN(__section_alignment__):
{
___crt_xc_start__ = . ;
*(SORT(.CRT$XC*)) /* C initialization */
___crt_xc_end__ = . ;
___crt_xi_start__ = . ;
*(SORT(.CRT$XI*)) /* C++ initialization */
___crt_xi_end__ = . ;
___crt_xl_start__ = . ;
*(SORT(.CRT$XL*)) /* TLS callbacks */
/* ___crt_xl_end__ is defined in the TLS Directory support code */
___crt_xp_start__ = . ;
*(SORT(.CRT$XP*)) /* Pre-termination */
___crt_xp_end__ = . ;
___crt_xt_start__ = . ;
*(SORT(.CRT$XT*)) /* Termination */
___crt_xt_end__ = . ;
}
.data ALIGN(__section_alignment__):
{
PROVIDE ( __data_start__ = .) ;
*(.data)
*(.data2)
*(SORT(.data$*))
*(.jcr)
__CRT_MT = .;
LONG(0);
PROVIDE ( __data_end__ = .) ;
*(.data_cygwin_nocopy)
}
.eh_frame ALIGN(__section_alignment__):
{
*(.eh_frame)
___iend = . ;
}
.bss ALIGN(__section_alignment__):
{
*(.bss)
*(COMMON)
}
.edata ALIGN(__section_alignment__):
{
*(.edata)
}
/DISCARD/ :
{
*(.debug$S)
*(.debug$T)
*(.debug$F)
*(.drectve)
*(.note.GNU-stack)
*(.comment)
*(.debug_abbrev)
*(.debug_info)
*(.debug_line)
*(.debug_frame)
*(.debug_loc)
*(.debug_pubnames)
*(.debug_aranges)
*(.debug_ranges)
}
.idata ALIGN(__section_alignment__):
{
SORT(*)(.idata$2)
SORT(*)(.idata$3)
/* These zeroes mark the end of the import list. */
LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
SORT(*)(.idata$4)
SORT(*)(.idata$5)
SORT(*)(.idata$6)
SORT(*)(.idata$7)
}
.reloc ALIGN(__section_alignment__) :
{
*(.reloc)
}
}

View File

@ -0,0 +1,103 @@
/* Threads compatibility routines for libgcc2. */
/* Compile this one with gcc. */
/* Copyright (C) 1997, 1998, 2004, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_GTHR_H
#define GCC_GTHR_H
typedef unsigned int __gthread_key_t;
typedef struct {
volatile int done;
int started;
} __gthread_once_t;
typedef struct {
volatile int counter;
} __gthread_mutex_t;
void *tls_alloc(void);
static int __gthread_mutex_lock (__gthread_mutex_t *mutex)
{
__mutex_lock(&mutex->counter);
return 0;
};
static int __gthread_mutex_unlock (__gthread_mutex_t *mutex)
{
mutex->counter = 0;
return 0;
};
static inline int __gthread_key_create (__gthread_key_t *__key,
void (*__dtor) (void *) __attribute__((unused)))
{
int __status = 0;
void *__tls_index = tls_alloc();
if (__tls_index != NULL)
{
*__key = (unsigned int)__tls_index;
#ifdef MINGW32_SUPPORTS_MT_EH /* FIXME */
/* Mingw runtime will run the dtors in reverse order for each thread
when the thread exits. */
// __status = __mingwthr_key_dtor (*__key, __dtor);
#endif
}
else
__status = (int) ENOMEM;
return __status;
}
static inline void *
__gthread_getspecific (__gthread_key_t __key)
{
void *val;
__asm__ __volatile__(
"movl %%fs:(%1), %0"
:"=r"(val)
:"r"(__key));
return val;
};
static inline int
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
{
if(!(__key & 3))
{
__asm__ __volatile__(
"movl %0, %%fs:(%1)"
::"r"(__ptr),"r"(__key));
return 0;
}
else return EINVAL;
}
#endif

View File

@ -5,16 +5,6 @@
#ifndef _NEWLIB_H_
#define _NEWLIB_H_
/*
#ifdef __LIBC_DLL__
#ifdef __LIBC_EXPORT__
#define API __attribute__ ((dllexport))
#else
#define API __attribute__ ((dllimport))
#endif
#else
#define API
#endif
*/
#define __DYNAMIC_REENT__
#endif /* _NEWLIB_H_ */

View File

@ -27,9 +27,13 @@ typedef __libc_lock_recursive_t _LOCK_RECURSIVE_T;
#define __LOCK_INIT(class,lock) \
__libc_lock_define_initialized(class, lock)
#define __LOCK_INIT_RECURSIVE(class, lock) \
__libc_lock_define_initialized_recursive(class, lock)
#define __libc_lock_define_initialized(CLASS,NAME) \
CLASS __libc_lock_t NAME;
#define __libc_lock_define_initialized_recursive(CLASS,NAME) \
CLASS __libc_lock_recursive_t NAME = _LIBC_LOCK_RECURSIVE_INITIALIZER;

View File

@ -822,19 +822,17 @@ void _reclaim_reent _PARAMS ((struct _reent *));
/* #define _REENT_ONLY define this to get only reentrant routines */
#ifndef _REENT_ONLY
#if defined(__DYNAMIC_REENT__) && !defined(__SINGLE_THREAD__)
#ifndef __getreent
struct _reent * _EXFUN(__getreent, (void));
#endif
static inline struct _reent *__getreent(void)
{
struct _reent *ent;
__asm__ __volatile__(
"movl %%fs:12, %0"
:"=r"(ent));
return ent;
};
# define _REENT (__getreent())
#else /* __SINGLE_THREAD__ || !__DYNAMIC_REENT__ */
# define _REENT _impure_ptr
#endif /* __SINGLE_THREAD__ || !__DYNAMIC_REENT__ */
#endif /* !_REENT_ONLY */
#define _GLOBAL_REENT _global_impure_ptr
#ifdef __cplusplus

View File

@ -0,0 +1,82 @@
OUTPUT_FORMAT(pei-i386)
ENTRY("_crt_startup")
SECTIONS
{
. = SIZEOF_HEADERS;
. = ALIGN(__section_alignment__);
.text __image_base__ + . :
{
*(.text) *(.rdata)
. = ALIGN(16);
___RUNTIME_PSEUDO_RELOC_LIST__ = .;
__RUNTIME_PSEUDO_RELOC_LIST__ = .;
*(.rdata_runtime_pseudo_reloc)
___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
__RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
__pei386_runtime_relocator = .;
}
.data ALIGN(__section_alignment__):
{
PROVIDE ( __data_start__ = .) ;
*(.data)
*(.data2)
*(SORT(.data$*))
*(.jcr)
PROVIDE ( __data_end__ = .) ;
*(.data_cygwin_nocopy)
}
.bss ALIGN(__section_alignment__):
{
*(.bss)
*(COMMON)
}
.edata ALIGN(__section_alignment__):
{
*(.edata)
}
/DISCARD/ :
{
*(.debug$S)
*(.debug$T)
*(.debug$F)
*(.drectve)
*(.note.GNU-stack)
*(.comment)
*(.debug_abbrev)
*(.debug_info)
*(.debug_line)
*(.debug_frame)
*(.debug_loc)
*(.debug_pubnames)
*(.debug_aranges)
*(.debug_ranges)
}
.idata ALIGN(__section_alignment__):
{
SORT(*)(.idata$2)
SORT(*)(.idata$3)
/* These zeroes mark the end of the import list. */
LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
SORT(*)(.idata$4)
SORT(*)(.idata$5)
SORT(*)(.idata$6)
SORT(*)(.idata$7)
}
.reloc ALIGN(__section_alignment__) :
{
*(.reloc)
}
}

View File

@ -0,0 +1,111 @@
/*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <limits.h>
#include <string.h>
#include "lctype.h"
#include "ldpart.h"
#include "setlocale.h"
#define LCCTYPE_SIZE (sizeof(struct lc_ctype_T) / sizeof(char *))
static char numone[] = { '\1', '\0'};
static const struct lc_ctype_T _C_ctype_locale = {
"ASCII", /* codeset */
numone /* mb_cur_max */
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
,
{ "0", "1", "2", "3", "4", /* outdigits */
"5", "6", "7", "8", "9" },
{ L"0", L"1", L"2", L"3", L"4", /* woutdigits */
L"5", L"6", L"7", L"8", L"9" }
#endif
};
static struct lc_ctype_T _ctype_locale;
static int _ctype_using_locale;
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
static char *_ctype_locale_buf;
#else
/* Max encoding_len + NUL byte + 1 byte mb_cur_max plus trailing NUL byte */
#define _CTYPE_BUF_SIZE (ENCODING_LEN + 3)
static char _ctype_locale_buf[_CTYPE_BUF_SIZE];
#endif
int
__ctype_load_locale(const char *name, void *f_wctomb, const char *charset,
int mb_cur_max)
{
int ret;
#ifdef __CYGWIN__
extern int __set_lc_ctype_from_win (const char *,
const struct lc_ctype_T *,
struct lc_ctype_T *, char **,
void *, const char *, int);
int old_ctype_using_locale = _ctype_using_locale;
_ctype_using_locale = 0;
ret = __set_lc_ctype_from_win (name, &_C_ctype_locale, &_ctype_locale,
&_ctype_locale_buf, f_wctomb, charset,
mb_cur_max);
/* ret == -1: error, ret == 0: C/POSIX, ret > 0: valid */
if (ret < 0)
_ctype_using_locale = old_ctype_using_locale;
else
{
_ctype_using_locale = ret;
ret = 0;
}
#elif !defined (__HAVE_LOCALE_INFO_EXTENDED__)
if (!strcmp (name, "C"))
_ctype_using_locale = 0;
else
{
_ctype_locale.codeset = strcpy (_ctype_locale_buf, charset);
char *mbc = _ctype_locale_buf + _CTYPE_BUF_SIZE - 2;
mbc[0] = mb_cur_max;
mbc[1] = '\0';
_ctype_locale.mb_cur_max = mbc;
_ctype_using_locale = 1;
}
ret = 0;
#else
ret = __part_load_locale(name, &_ctype_using_locale,
_ctype_locale_buf, "LC_CTYPE",
LCCTYPE_SIZE, LCCTYPE_SIZE,
(const char **)&_ctype_locale);
if (ret == 0 && _ctype_using_locale)
_ctype_locale.grouping =
__fix_locale_grouping_str(_ctype_locale.grouping);
#endif
return ret;
}
struct lc_ctype_T *
__get_current_ctype_locale(void) {
return (_ctype_using_locale
? &_ctype_locale
: (struct lc_ctype_T *)&_C_ctype_locale);
}

View File

@ -0,0 +1,40 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
#include <math.h>
float
acosf (float x)
{
float res;
/* acosl = atanl (sqrtl(1 - x^2) / x) */
asm ( "fld %%st\n\t"
"fmul %%st(0)\n\t" /* x^2 */
"fld1\n\t"
"fsubp\n\t" /* 1 - x^2 */
"fsqrt\n\t" /* sqrtl (1 - x^2) */
"fxch %%st(1)\n\t"
"fpatan"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}
double
acos (double x)
{
double res;
/* acosl = atanl (sqrtl(1 - x^2) / x) */
asm ( "fld %%st\n\t"
"fmul %%st(0)\n\t" /* x^2 */
"fld1\n\t"
"fsubp\n\t" /* 1 - x^2 */
"fsqrt\n\t" /* sqrtl (1 - x^2) */
"fxch %%st(1)\n\t"
"fpatan"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}

View File

@ -0,0 +1,26 @@
#include <math.h>
#include <errno.h>
#include "fastmath.h"
/* acosh(x) = log (x + sqrt(x * x - 1)) */
double acosh (double x)
{
if (isnan (x))
return x;
if (x < 1.0)
{
errno = EDOM;
return nan("");
}
if (x > 0x1p32)
/* Avoid overflow (and unnecessary calculation when
sqrt (x * x - 1) == x). GCC optimizes by replacing
the long double M_LN2 const with a fldln2 insn. */
return __fast_log (x) + 6.9314718055994530941723E-1L;
/* Since x >= 1, the arg to log will always be greater than
the fyl2xp1 limit (approx 0.29) so just use logl. */
return __fast_log (x + __fast_sqrt((x + 1.0) * (x - 1.0)));
}

View File

@ -0,0 +1,25 @@
#include <math.h>
#include <errno.h>
#include "fastmath.h"
/* acosh(x) = log (x + sqrt(x * x - 1)) */
float acoshf (float x)
{
if (isnan (x))
return x;
if (x < 1.0f)
{
errno = EDOM;
return nan("");
}
if (x > 0x1p32f)
/* Avoid overflow (and unnecessary calculation when
sqrt (x * x - 1) == x). GCC optimizes by replacing
the long double M_LN2 const with a fldln2 insn. */
return __fast_log (x) + 6.9314718055994530941723E-1L;
/* Since x >= 1, the arg to log will always be greater than
the fyl2xp1 limit (approx 0.29) so just use logl. */
return __fast_log (x + __fast_sqrt((x + 1.0) * (x - 1.0)));
}

View File

@ -0,0 +1,27 @@
#include <math.h>
#include <errno.h>
#include "fastmath.h"
/* acosh(x) = log (x + sqrt(x * x - 1)) */
long double acoshl (long double x)
{
if (isnan (x))
return x;
if (x < 1.0L)
{
errno = EDOM;
return nanl("");
}
if (x > 0x1p32L)
/* Avoid overflow (and unnecessary calculation when
sqrt (x * x - 1) == x).
The M_LN2 define doesn't have enough precison for
long double so use this one. GCC optimizes by replacing
the const with a fldln2 insn. */
return __fast_logl (x) + 6.9314718055994530941723E-1L;
/* Since x >= 1, the arg to log will always be greater than
the fyl2xp1 limit (approx 0.29) so just use logl. */
return __fast_logl (x + __fast_sqrtl((x + 1.0L) * (x - 1.0L)));
}

View File

@ -0,0 +1,25 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
*/
#include <math.h>
long double
acosl (long double x)
{
long double res;
/* acosl = atanl (sqrtl(1 - x^2) / x) */
asm ( "fld %%st\n\t"
"fmul %%st(0)\n\t" /* x^2 */
"fld1\n\t"
"fsubp\n\t" /* 1 - x^2 */
"fsqrt\n\t" /* sqrtl (1 - x^2) */
"fxch %%st(1)\n\t"
"fpatan"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}

View File

@ -0,0 +1,34 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
/* asin = atan (x / sqrt(1 - x^2)) */
float asinf (float x)
{
float res;
asm ( "fld %%st\n\t"
"fmul %%st(0)\n\t" /* x^2 */
"fld1\n\t"
"fsubp\n\t" /* 1 - x^2 */
"fsqrt\n\t" /* sqrt (1 - x^2) */
"fpatan"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}
double asin (double x)
{
double res;
asm ( "fld %%st\n\t"
"fmul %%st(0)\n\t" /* x^2 */
"fld1\n\t"
"fsubp\n\t" /* 1 - x^2 */
"fsqrt\n\t" /* sqrt (1 - x^2) */
"fpatan"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}

View File

@ -0,0 +1,28 @@
#include <math.h>
#include <errno.h>
#include "fastmath.h"
/* asinh(x) = copysign(log(fabs(x) + sqrt(x * x + 1.0)), x) */
double asinh(double x)
{
double z;
if (!isfinite (x))
return x;
z = fabs (x);
/* Avoid setting FPU underflow exception flag in x * x. */
#if 0
if ( z < 0x1p-32)
return x;
#endif
/* Use log1p to avoid cancellation with small x. Put
x * x in denom, so overflow is harmless.
asinh(x) = log1p (x + sqrt (x * x + 1.0) - 1.0)
= log1p (x + x * x / (sqrt (x * x + 1.0) + 1.0)) */
z = __fast_log1p (z + z * z / (__fast_sqrt (z * z + 1.0) + 1.0));
return ( x > 0.0 ? z : -z);
}

View File

@ -0,0 +1,28 @@
#include <math.h>
#include <errno.h>
#include "fastmath.h"
/* asinh(x) = copysign(log(fabs(x) + sqrt(x * x + 1.0)), x) */
float asinhf(float x)
{
float z;
if (!isfinite (x))
return x;
z = fabsf (x);
/* Avoid setting FPU underflow exception flag in x * x. */
#if 0
if ( z < 0x1p-32)
return x;
#endif
/* Use log1p to avoid cancellation with small x. Put
x * x in denom, so overflow is harmless.
asinh(x) = log1p (x + sqrt (x * x + 1.0) - 1.0)
= log1p (x + x * x / (sqrt (x * x + 1.0) + 1.0)) */
z = __fast_log1p (z + z * z / (__fast_sqrt (z * z + 1.0) + 1.0));
return ( x > 0.0 ? z : -z);
}

View File

@ -0,0 +1,28 @@
#include <math.h>
#include <errno.h>
#include "fastmath.h"
/* asinh(x) = copysign(log(fabs(x) + sqrt(x * x + 1.0)), x) */
long double asinhl(long double x)
{
long double z;
if (!isfinite (x))
return x;
z = fabsl (x);
/* Avoid setting FPU underflow exception flag in x * x. */
#if 0
if ( z < 0x1p-32)
return x;
#endif
/* Use log1p to avoid cancellation with small x. Put
x * x in denom, so overflow is harmless.
asinh(x) = log1p (x + sqrt (x * x + 1.0) - 1.0)
= log1p (x + x * x / (sqrt (x * x + 1.0) + 1.0)) */
z = __fast_log1pl (z + z * z / (__fast_sqrtl (z * z + 1.0L) + 1.0L));
return ( x > 0.0 ? z : -z);
}

View File

@ -0,0 +1,21 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Adapted for long double type by Danny Smith <dannysmith@users.sourceforge.net>.
*/
/* asin = atan (x / sqrt(1 - x^2)) */
long double asinl (long double x)
{
long double res;
asm ( "fld %%st\n\t"
"fmul %%st(0)\n\t" /* x^2 */
"fld1\n\t"
"fsubp\n\t" /* 1 - x^2 */
"fsqrt\n\t" /* sqrt (1 - x^2) */
"fpatan"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}

View File

@ -0,0 +1,15 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
*/
#include <math.h>
float
atan2f (float y, float x)
{
float res;
asm ("fpatan" : "=t" (res) : "u" (y), "0" (x) : "st(1)");
return res;
}

View File

@ -0,0 +1,16 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
*/
#include <math.h>
long double
atan2l (long double y, long double x)
{
long double res;
asm ("fpatan" : "=t" (res) : "u" (y), "0" (x) : "st(1)");
return res;
}

View File

@ -0,0 +1,28 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
*/
#include <math.h>
float
atanf (float x)
{
float res;
asm ("fld1\n\t"
"fpatan" : "=t" (res) : "0" (x));
return res;
}
double
atan (double x)
{
double res;
asm ("fld1 \n\t"
"fpatan" : "=t" (res) : "0" (x));
return res;
}

View File

@ -0,0 +1,31 @@
#include <math.h>
#include <errno.h>
#include "fastmath.h"
/* atanh (x) = 0.5 * log ((1.0 + x)/(1.0 - x)) */
double atanh(double x)
{
double z;
if isnan (x)
return x;
z = fabs (x);
if (z == 1.0)
{
errno = ERANGE;
return (x > 0 ? INFINITY : -INFINITY);
}
if (z > 1.0)
{
errno = EDOM;
return nan("");
}
/* Rearrange formula to avoid precision loss for small x.
atanh(x) = 0.5 * log ((1.0 + x)/(1.0 - x))
= 0.5 * log1p ((1.0 + x)/(1.0 - x) - 1.0)
= 0.5 * log1p ((1.0 + x - 1.0 + x) /(1.0 - x))
= 0.5 * log1p ((2.0 * x ) / (1.0 - x)) */
z = 0.5 * __fast_log1p ((z + z) / (1.0 - z));
return x >= 0 ? z : -z;
}

View File

@ -0,0 +1,30 @@
#include <math.h>
#include <errno.h>
#include "fastmath.h"
/* atanh (x) = 0.5 * log ((1.0 + x)/(1.0 - x)) */
float atanhf (float x)
{
float z;
if isnan (x)
return x;
z = fabsf (x);
if (z == 1.0)
{
errno = ERANGE;
return (x > 0 ? INFINITY : -INFINITY);
}
if ( z > 1.0)
{
errno = EDOM;
return nanf("");
}
/* Rearrange formula to avoid precision loss for small x.
atanh(x) = 0.5 * log ((1.0 + x)/(1.0 - x))
= 0.5 * log1p ((1.0 + x)/(1.0 - x) - 1.0)
= 0.5 * log1p ((1.0 + x - 1.0 + x) /(1.0 - x))
= 0.5 * log1p ((2.0 * x ) / (1.0 - x)) */
z = 0.5 * __fast_log1p ((z + z) / (1.0 - z));
return x >= 0 ? z : -z;
}

View File

@ -0,0 +1,29 @@
#include <math.h>
#include <errno.h>
#include "fastmath.h"
/* atanh (x) = 0.5 * log ((1.0 + x)/(1.0 - x)) */
long double atanhl (long double x)
{
long double z;
if isnan (x)
return x;
z = fabsl (x);
if (z == 1.0L)
{
errno = ERANGE;
return (x > 0 ? INFINITY : -INFINITY);
}
if ( z > 1.0L)
{
errno = EDOM;
return nanl("");
}
/* Rearrange formula to avoid precision loss for small x.
atanh(x) = 0.5 * log ((1.0 + x)/(1.0 - x))
= 0.5 * log1p ((1.0 + x)/(1.0 - x) - 1.0)
= 0.5 * log1p ((1.0 + x - 1.0 + x) /(1.0 - x))
= 0.5 * log1p ((2.0 * x ) / (1.0 - x)) */
z = 0.5L * __fast_log1pl ((z + z) / (1.0L - z));
return x >= 0 ? z : -z;
}

View File

@ -0,0 +1,19 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
*/
#include <math.h>
long double
atanl (long double x)
{
long double res;
asm ("fld1\n\t"
"fpatan"
: "=t" (res) : "0" (x));
return res;
}

View File

@ -0,0 +1,162 @@
/* cbrt.c
*
* Cube root
*
*
*
* SYNOPSIS:
*
* double x, y, cbrt();
*
* y = cbrt( x );
*
*
*
* DESCRIPTION:
*
* Returns the cube root of the argument, which may be negative.
*
* Range reduction involves determining the power of 2 of
* the argument. A polynomial of degree 2 applied to the
* mantissa, and multiplication by the cube root of 1, 2, or 4
* approximates the root to within about 0.1%. Then Newton's
* iteration is used three times to converge to an accurate
* result.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* DEC -10,10 200000 1.8e-17 6.2e-18
* IEEE 0,1e308 30000 1.5e-16 5.0e-17
*
*/
/* cbrt.c */
/*
Cephes Math Library Release 2.2: January, 1991
Copyright 1984, 1991 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
/*
Modified for mingwex.a
2002-07-01 Danny Smith <dannysmith@users.sourceforge.net>
*/
#ifdef __MINGW32__
#include <math.h>
#include "cephes_mconf.h"
#else
#include "mconf.h"
#endif
static const double CBRT2 = 1.2599210498948731647672;
static const double CBRT4 = 1.5874010519681994747517;
static const double CBRT2I = 0.79370052598409973737585;
static const double CBRT4I = 0.62996052494743658238361;
#ifndef __MINGW32__
#ifdef ANSIPROT
extern double frexp ( double, int * );
extern double ldexp ( double, int );
extern int isnan ( double );
extern int isfinite ( double );
#else
double frexp(), ldexp();
int isnan(), isfinite();
#endif
#endif
double cbrt(x)
double x;
{
int e, rem, sign;
double z;
#ifdef __MINGW32__
if (!isfinite (x) || x == 0 )
return x;
#else
#ifdef NANS
if( isnan(x) )
return x;
#endif
#ifdef INFINITIES
if( !isfinite(x) )
return x;
#endif
if( x == 0 )
return( x );
#endif /* __MINGW32__ */
if( x > 0 )
sign = 1;
else
{
sign = -1;
x = -x;
}
z = x;
/* extract power of 2, leaving
* mantissa between 0.5 and 1
*/
x = frexp( x, &e );
/* Approximate cube root of number between .5 and 1,
* peak relative error = 9.2e-6
*/
x = (((-1.3466110473359520655053e-1 * x
+ 5.4664601366395524503440e-1) * x
- 9.5438224771509446525043e-1) * x
+ 1.1399983354717293273738e0 ) * x
+ 4.0238979564544752126924e-1;
/* exponent divided by 3 */
if( e >= 0 )
{
rem = e;
e /= 3;
rem -= 3*e;
if( rem == 1 )
x *= CBRT2;
else if( rem == 2 )
x *= CBRT4;
}
/* argument less than 1 */
else
{
e = -e;
rem = e;
e /= 3;
rem -= 3*e;
if( rem == 1 )
x *= CBRT2I;
else if( rem == 2 )
x *= CBRT4I;
e = -e;
}
/* multiply by power of 2 */
x = ldexp( x, e );
/* Newton iteration */
x -= ( x - (z/(x*x)) )*0.33333333333333333333;
#ifdef DEC
x -= ( x - (z/(x*x)) )/3.0;
#else
x -= ( x - (z/(x*x)) )*0.33333333333333333333;
#endif
if( sign < 0 )
x = -x;
return(x);
}

View File

@ -0,0 +1,147 @@
/* cbrtf.c
*
* Cube root
*
*
*
* SYNOPSIS:
*
* float x, y, cbrtf();
*
* y = cbrtf( x );
*
*
*
* DESCRIPTION:
*
* Returns the cube root of the argument, which may be negative.
*
* Range reduction involves determining the power of 2 of
* the argument. A polynomial of degree 2 applied to the
* mantissa, and multiplication by the cube root of 1, 2, or 4
* approximates the root to within about 0.1%. Then Newton's
* iteration is used to converge to an accurate result.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE 0,1e38 100000 7.6e-8 2.7e-8
*
*/
/* cbrt.c */
/*
Cephes Math Library Release 2.2: June, 1992
Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
/*
Modified for mingwex.a
2002-07-01 Danny Smith <dannysmith@users.sourceforge.net>
*/
#ifdef __MINGW32__
#include <math.h>
#include "cephes_mconf.h"
#else
#include "mconf.h"
#endif
static const float CBRT2 = 1.25992104989487316477;
static const float CBRT4 = 1.58740105196819947475;
#ifndef __MINGW32__
#ifdef ANSIC
float frexpf(float, int *), ldexpf(float, int);
float cbrtf( float xx )
#else
float frexpf(), ldexpf();
float cbrtf(xx)
double xx;
#endif
{
int e, rem, sign;
float x, z;
x = xx;
#else /* __MINGW32__ */
float cbrtf (float x)
{
int e, rem, sign;
float z;
#endif /* __MINGW32__ */
#ifdef __MINGW32__
if (!isfinite (x) || x == 0.0F )
return x;
#else
if( x == 0 )
return( 0.0 );
#endif
if( x > 0 )
sign = 1;
else
{
sign = -1;
x = -x;
}
z = x;
/* extract power of 2, leaving
* mantissa between 0.5 and 1
*/
x = frexpf( x, &e );
/* Approximate cube root of number between .5 and 1,
* peak relative error = 9.2e-6
*/
x = (((-0.13466110473359520655053 * x
+ 0.54664601366395524503440 ) * x
- 0.95438224771509446525043 ) * x
+ 1.1399983354717293273738 ) * x
+ 0.40238979564544752126924;
/* exponent divided by 3 */
if( e >= 0 )
{
rem = e;
e /= 3;
rem -= 3*e;
if( rem == 1 )
x *= CBRT2;
else if( rem == 2 )
x *= CBRT4;
}
/* argument less than 1 */
else
{
e = -e;
rem = e;
e /= 3;
rem -= 3*e;
if( rem == 1 )
x /= CBRT2;
else if( rem == 2 )
x /= CBRT4;
e = -e;
}
/* multiply by power of 2 */
x = ldexpf( x, e );
/* Newton iteration */
x -= ( x - (z/(x*x)) ) * 0.333333333333;
if( sign < 0 )
x = -x;
return(x);
}

View File

@ -0,0 +1,161 @@
/* cbrtl.c
*
* Cube root, long double precision
*
*
*
* SYNOPSIS:
*
* long double x, y, cbrtl();
*
* y = cbrtl( x );
*
*
*
* DESCRIPTION:
*
* Returns the cube root of the argument, which may be negative.
*
* Range reduction involves determining the power of 2 of
* the argument. A polynomial of degree 2 applied to the
* mantissa, and multiplication by the cube root of 1, 2, or 4
* approximates the root to within about 0.1%. Then Newton's
* iteration is used three times to converge to an accurate
* result.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE .125,8 80000 7.0e-20 2.2e-20
* IEEE exp(+-707) 100000 7.0e-20 2.4e-20
*
*/
/*
Cephes Math Library Release 2.2: January, 1991
Copyright 1984, 1991 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
/*
Modified for mingwex.a
2002-07-01 Danny Smith <dannysmith@users.sourceforge.net>
*/
#ifdef __MINGW32__
#include "cephes_mconf.h"
#else
#include "mconf.h"
#endif
static const long double CBRT2 = 1.2599210498948731647672L;
static const long double CBRT4 = 1.5874010519681994747517L;
static const long double CBRT2I = 0.79370052598409973737585L;
static const long double CBRT4I = 0.62996052494743658238361L;
#ifndef __MINGW32__
#ifdef ANSIPROT
extern long double frexpl ( long double, int * );
extern long double ldexpl ( long double, int );
extern int isnanl ( long double );
#else
long double frexpl(), ldexpl();
extern int isnanl();
#endif
#ifdef INFINITIES
extern long double INFINITYL;
#endif
#endif /* __MINGW32__ */
long double cbrtl(x)
long double x;
{
int e, rem, sign;
long double z;
#ifdef __MINGW32__
if (!isfinite (x) || x == 0.0L)
return(x);
#else
#ifdef NANS
if(isnanl(x))
return(x);
#endif
#ifdef INFINITIES
if( x == INFINITYL)
return(x);
if( x == -INFINITYL)
return(x);
#endif
if( x == 0 )
return( x );
#endif /* __MINGW32__ */
if( x > 0 )
sign = 1;
else
{
sign = -1;
x = -x;
}
z = x;
/* extract power of 2, leaving
* mantissa between 0.5 and 1
*/
x = frexpl( x, &e );
/* Approximate cube root of number between .5 and 1,
* peak relative error = 1.2e-6
*/
x = (((( 1.3584464340920900529734e-1L * x
- 6.3986917220457538402318e-1L) * x
+ 1.2875551670318751538055e0L) * x
- 1.4897083391357284957891e0L) * x
+ 1.3304961236013647092521e0L) * x
+ 3.7568280825958912391243e-1L;
/* exponent divided by 3 */
if( e >= 0 )
{
rem = e;
e /= 3;
rem -= 3*e;
if( rem == 1 )
x *= CBRT2;
else if( rem == 2 )
x *= CBRT4;
}
else
{ /* argument less than 1 */
e = -e;
rem = e;
e /= 3;
rem -= 3*e;
if( rem == 1 )
x *= CBRT2I;
else if( rem == 2 )
x *= CBRT4I;
e = -e;
}
/* multiply by power of 2 */
x = ldexpl( x, e );
/* Newton iteration */
x -= ( x - (z/(x*x)) )*0.3333333333333333333333L;
x -= ( x - (z/(x*x)) )*0.3333333333333333333333L;
if( sign < 0 )
x = -x;
return(x);
}

View File

@ -0,0 +1,31 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
.file "ceil.s"
.text
.align 4
.globl _ceil
.def _ceil; .scl 2; .type 32; .endef
_ceil:
fldl 4(%esp)
subl $8,%esp
fstcw 4(%esp) /* store fpu control word */
/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
movl $0x0800,%edx /* round towards +oo */
orl 4(%esp),%edx
andl $0xfbff,%edx
movl %edx,(%esp)
fldcw (%esp) /* load modified control word */
frndint /* round */
fldcw 4(%esp) /* restore original control word */
addl $8,%esp
ret

View File

@ -0,0 +1,31 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
.file "ceilf.S"
.text
.align 4
.globl _ceilf
.def _ceilf; .scl 2; .type 32; .endef
_ceilf:
flds 4(%esp)
subl $8,%esp
fstcw 4(%esp) /* store fpu control word */
/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
movl $0x0800,%edx /* round towards +oo */
orl 4(%esp),%edx
andl $0xfbff,%edx
movl %edx,(%esp)
fldcw (%esp) /* load modified control word */
frndint /* round */
fldcw 4(%esp) /* restore original control word */
addl $8,%esp
ret

View File

@ -0,0 +1,33 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
*/
.file "ceill.S"
.text
.align 4
.globl _ceill
.def _ceill; .scl 2; .type 32; .endef
_ceill:
fldt 4(%esp)
subl $8,%esp
fstcw 4(%esp) /* store fpu control word */
/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
movl $0x0800,%edx /* round towards +oo */
orl 4(%esp),%edx
andl $0xfbff,%edx
movl %edx,(%esp)
fldcw (%esp) /* load modified control word */
frndint /* round */
fldcw 4(%esp) /* restore original control word */
addl $8,%esp
ret

View File

@ -0,0 +1,395 @@
#include <math.h>
#include <errno.h>
#define IBMPC 1
#define ANSIPROT 1
#define MINUSZERO 1
#define INFINITIES 1
#define NANS 1
#define DENORMAL 1
#define VOLATILE
#define mtherr(fname, code)
#define XPD 0,
//#define _CEPHES_USE_ERRNO
#ifdef _CEPHES_USE_ERRNO
#define _SET_ERRNO(x) errno = (x)
#else
#define _SET_ERRNO(x)
#endif
/* constants used by cephes functions */
/* double */
#define MAXNUM 1.7976931348623158E308
#define MAXLOG 7.09782712893383996843E2
#define MINLOG -7.08396418532264106224E2
#define LOGE2 6.93147180559945309417E-1
#define LOG2E 1.44269504088896340736
#define PI 3.14159265358979323846
#define PIO2 1.57079632679489661923
#define PIO4 7.85398163397448309616E-1
#define NEGZERO (-0.0)
#undef NAN
#undef INFINITY
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2))
#define INFINITY __builtin_huge_val()
#define NAN __builtin_nan("")
#else
extern double __INF;
#define INFINITY (__INF)
extern double __QNAN;
#define NAN (__QNAN)
#endif
/*long double*/
#define MAXNUML 1.189731495357231765021263853E4932L
#define MAXLOGL 1.1356523406294143949492E4L
#define MINLOGL -1.13994985314888605586758E4L
#define LOGE2L 6.9314718055994530941723E-1L
#define LOG2EL 1.4426950408889634073599E0L
#define PIL 3.1415926535897932384626L
#define PIO2L 1.5707963267948966192313L
#define PIO4L 7.8539816339744830961566E-1L
#define isfinitel isfinite
#define isinfl isinf
#define isnanl isnan
#define signbitl signbit
#define NEGZEROL (-0.0L)
#undef NANL
#undef INFINITYL
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2))
#define INFINITYL __builtin_huge_vall()
#define NANL __builtin_nanl("")
#else
extern long double __INFL;
#define INFINITYL (__INFL)
extern long double __QNANL;
#define NANL (__QNANL)
#endif
/* float */
#define MAXNUMF 3.4028234663852885981170418348451692544e38F
#define MAXLOGF 88.72283905206835F
#define MINLOGF -103.278929903431851103F /* log(2^-149) */
#define LOG2EF 1.44269504088896341F
#define LOGE2F 0.693147180559945309F
#define PIF 3.141592653589793238F
#define PIO2F 1.5707963267948966192F
#define PIO4F 0.7853981633974483096F
#define isfinitef isfinite
#define isinff isinf
#define isnanf isnan
#define signbitf signbit
#define NEGZEROF (-0.0F)
#undef NANF
#undef INFINITYF
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2))
#define INFINITYF __builtin_huge_valf()
#define NANF __builtin_nanf("")
#else
extern float __INFF;
#define INFINITYF (__INFF)
extern float __QNANF;
#define NANF (__QNANF)
#endif
/* double */
/*
Cephes Math Library Release 2.2: July, 1992
Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
/* polevl.c
* p1evl.c
*
* Evaluate polynomial
*
*
*
* SYNOPSIS:
*
* int N;
* double x, y, coef[N+1], polevl[];
*
* y = polevl( x, coef, N );
*
*
*
* DESCRIPTION:
*
* Evaluates polynomial of degree N:
*
* 2 N
* y = C + C x + C x +...+ C x
* 0 1 2 N
*
* Coefficients are stored in reverse order:
*
* coef[0] = C , ..., coef[N] = C .
* N 0
*
* The function p1evl() assumes that coef[N] = 1.0 and is
* omitted from the array. Its calling arguments are
* otherwise the same as polevl().
*
*
* SPEED:
*
* In the interest of speed, there are no checks for out
* of bounds arithmetic. This routine is used by most of
* the functions in the library. Depending on available
* equipment features, the user may wish to rewrite the
* program in microcode or assembly language.
*
*/
/* Polynomial evaluator:
* P[0] x^n + P[1] x^(n-1) + ... + P[n]
*/
static __inline__ double polevl( x, p, n )
double x;
const void *p;
int n;
{
register double y;
register double *P = (double *)p;
y = *P++;
do
{
y = y * x + *P++;
}
while( --n );
return(y);
}
/* Polynomial evaluator:
* x^n + P[0] x^(n-1) + P[1] x^(n-2) + ... + P[n]
*/
static __inline__ double p1evl( x, p, n )
double x;
const void *p;
int n;
{
register double y;
register double *P = (double *)p;
n -= 1;
y = x + *P++;
do
{
y = y * x + *P++;
}
while( --n );
return( y );
}
/* long double */
/*
Cephes Math Library Release 2.2: July, 1992
Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
/* polevll.c
* p1evll.c
*
* Evaluate polynomial
*
*
*
* SYNOPSIS:
*
* int N;
* long double x, y, coef[N+1], polevl[];
*
* y = polevll( x, coef, N );
*
*
*
* DESCRIPTION:
*
* Evaluates polynomial of degree N:
*
* 2 N
* y = C + C x + C x +...+ C x
* 0 1 2 N
*
* Coefficients are stored in reverse order:
*
* coef[0] = C , ..., coef[N] = C .
* N 0
*
* The function p1evll() assumes that coef[N] = 1.0 and is
* omitted from the array. Its calling arguments are
* otherwise the same as polevll().
*
*
* SPEED:
*
* In the interest of speed, there are no checks for out
* of bounds arithmetic. This routine is used by most of
* the functions in the library. Depending on available
* equipment features, the user may wish to rewrite the
* program in microcode or assembly language.
*
*/
/* Polynomial evaluator:
* P[0] x^n + P[1] x^(n-1) + ... + P[n]
*/
static __inline__ long double polevll( x, p, n )
long double x;
const void *p;
int n;
{
register long double y;
register long double *P = (long double *)p;
y = *P++;
do
{
y = y * x + *P++;
}
while( --n );
return(y);
}
/* Polynomial evaluator:
* x^n + P[0] x^(n-1) + P[1] x^(n-2) + ... + P[n]
*/
static __inline__ long double p1evll( x, p, n )
long double x;
const void *p;
int n;
{
register long double y;
register long double *P = (long double *)p;
n -= 1;
y = x + *P++;
do
{
y = y * x + *P++;
}
while( --n );
return( y );
}
/* Float version */
/* polevlf.c
* p1evlf.c
*
* Evaluate polynomial
*
*
*
* SYNOPSIS:
*
* int N;
* float x, y, coef[N+1], polevlf[];
*
* y = polevlf( x, coef, N );
*
*
*
* DESCRIPTION:
*
* Evaluates polynomial of degree N:
*
* 2 N
* y = C + C x + C x +...+ C x
* 0 1 2 N
*
* Coefficients are stored in reverse order:
*
* coef[0] = C , ..., coef[N] = C .
* N 0
*
* The function p1evl() assumes that coef[N] = 1.0 and is
* omitted from the array. Its calling arguments are
* otherwise the same as polevl().
*
*
* SPEED:
*
* In the interest of speed, there are no checks for out
* of bounds arithmetic. This routine is used by most of
* the functions in the library. Depending on available
* equipment features, the user may wish to rewrite the
* program in microcode or assembly language.
*
*/
/*
Cephes Math Library Release 2.1: December, 1988
Copyright 1984, 1987, 1988 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
static __inline__ float polevlf(float x, const float* coef, int N )
{
float ans;
float *p;
int i;
p = (float*)coef;
ans = *p++;
/*
for( i=0; i<N; i++ )
ans = ans * x + *p++;
*/
i = N;
do
ans = ans * x + *p++;
while( --i );
return( ans );
}
/* p1evl() */
/* N
* Evaluate polynomial when coefficient of x is 1.0.
* Otherwise same as polevl.
*/
static __inline__ float p1evlf( float x, const float *coef, int N )
{
float ans;
float *p;
int i;
p = (float*)coef;
ans = x + *p++;
i = N-1;
do
ans = ans * x + *p++;
while( --i );
return( ans );
}

View File

@ -0,0 +1,19 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
.file "copysign.S"
.text
.align 4
.globl _copysign
.def _copysign; .scl 2; .type 32; .endef
_copysign:
movl 16(%esp),%edx
movl 8(%esp),%eax
andl $0x80000000,%edx
andl $0x7fffffff,%eax
orl %edx,%eax
movl %eax,8(%esp)
fldl 4(%esp)
ret

View File

@ -0,0 +1,19 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
.file "copysignf.S"
.text
.align 4
.globl _copysignf
.def _copysignf; .scl 2; .type 32; .endef
_copysignf:
movl 8(%esp),%edx
movl 4(%esp),%eax
andl $0x80000000,%edx
andl $0x7fffffff,%eax
orl %edx,%eax
movl %eax,4(%esp)
flds 4(%esp)
ret

View File

@ -0,0 +1,20 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
* Public domain.
*/
.file "copysignl.S"
.text
.align 4
.globl _copysignl
.def _copysignl; .scl 2; .type 32; .endef
_copysignl:
movl 24(%esp),%edx
movl 12(%esp),%eax
andl $0x8000,%edx
andl $0x7fff,%eax
orl %edx,%eax
movl %eax,12(%esp)
fldt 4(%esp)
ret

View File

@ -0,0 +1,29 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Removed glibc header dependancy by Danny Smith
* <dannysmith@users.sourceforge.net>
*/
.file "cos.s"
.text
.align 4
.globl _cos
.def _cos; .scl 2; .type 32; .endef
_cos:
fldl 4(%esp)
fcos
fnstsw %ax
testl $0x400,%eax
jnz 1f
ret
1: fldpi
fadd %st(0)
fxch %st(1)
2: fprem1
fnstsw %ax
testl $0x400,%eax
jnz 2b
fstp %st(1)
fcos
ret

View File

@ -0,0 +1,29 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Removed glibc header dependancy by Danny Smith
* <dannysmith@users.sourceforge.net>
*/
.file "cosf.S"
.text
.align 4
.globl _cosl
.def _cosf; .scl 2; .type 32; .endef
_cosf:
flds 4(%esp)
fcos
fnstsw %ax
testl $0x400,%eax
jnz 1f
ret
1: fldpi
fadd %st(0)
fxch %st(1)
2: fprem1
fnstsw %ax
testl $0x400,%eax
jnz 2b
fstp %st(1)
fcos
ret

View File

@ -0,0 +1,3 @@
#include <math.h>
float coshf (float x)
{return (float) cosh (x);}

View File

@ -0,0 +1,110 @@
/* coshl.c
*
* Hyperbolic cosine, long double precision
*
*
*
* SYNOPSIS:
*
* long double x, y, coshl();
*
* y = coshl( x );
*
*
*
* DESCRIPTION:
*
* Returns hyperbolic cosine of argument in the range MINLOGL to
* MAXLOGL.
*
* cosh(x) = ( exp(x) + exp(-x) )/2.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE +-10000 30000 1.1e-19 2.8e-20
*
*
* ERROR MESSAGES:
*
* message condition value returned
* cosh overflow |x| > MAXLOGL+LOGE2L INFINITYL
*
*
*/
/*
Cephes Math Library Release 2.7: May, 1998
Copyright 1985, 1991, 1998 by Stephen L. Moshier
*/
/*
Modified for mingw
2002-07-22 Danny Smith <dannysmith@users.sourceforge.net>
*/
#ifdef __MINGW32__
#include "cephes_mconf.h"
#else
#include "mconf.h"
#endif
#ifndef _SET_ERRNO
#define _SET_ERRNO(x)
#endif
#ifndef __MINGW32__
extern long double MAXLOGL, MAXNUML, LOGE2L;
#ifdef ANSIPROT
extern long double expl ( long double );
extern int isnanl ( long double );
#else
long double expl(), isnanl();
#endif
#ifdef INFINITIES
extern long double INFINITYL;
#endif
#ifdef NANS
extern long double NANL;
#endif
#endif /* __MINGW32__ */
long double coshl(x)
long double x;
{
long double y;
#ifdef NANS
if( isnanl(x) )
{
_SET_ERRNO(EDOM);
return(x);
}
#endif
if( x < 0 )
x = -x;
if( x > (MAXLOGL + LOGE2L) )
{
mtherr( "coshl", OVERFLOW );
_SET_ERRNO(ERANGE);
#ifdef INFINITIES
return( INFINITYL );
#else
return( MAXNUML );
#endif
}
if( x >= (MAXLOGL - LOGE2L) )
{
y = expl(0.5L * x);
y = (0.5L * y) * y;
return(y);
}
y = expl(x);
y = 0.5L * (y + 1.0L / y);
return( y );
}

View File

@ -0,0 +1,30 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
* Removed glibc header dependancy by Danny Smith
* <dannysmith@users.sourceforge.net>
*/
.file "cosl.S"
.text
.align 4
.globl _cosl
.def _cosl; .scl 2; .type 32; .endef
_cosl:
fldt 4(%esp)
fcos
fnstsw %ax
testl $0x400,%eax
jnz 1f
ret
1: fldpi
fadd %st(0)
fxch %st(1)
2: fprem1
fnstsw %ax
testl $0x400,%eax
jnz 2b
fstp %st(1)
fcos
ret

View File

@ -0,0 +1,265 @@
/* Software floating-point emulation.
Definitions for IEEE Double Precision
Copyright (C) 1997, 1998, 1999, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson (rth@cygnus.com),
Jakub Jelinek (jj@ultra.linux.cz),
David S. Miller (davem@redhat.com) and
Peter Maydell (pmaydell@chiark.greenend.org.uk).
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
In addition to the permissions in the GNU Lesser General Public
License, the Free Software Foundation gives you unlimited
permission to link the compiled version of this file into
combinations with other programs, and to distribute those
combinations without any restriction coming from the use of this
file. (The Lesser General Public License restrictions do apply in
other respects; for example, they cover modification of the file,
and distribution when not linked into a combine executable.)
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#if _FP_W_TYPE_SIZE < 32
#error "Here's a nickel kid. Go buy yourself a real computer."
#endif
#if _FP_W_TYPE_SIZE < 64
#define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE)
#else
#define _FP_FRACTBITS_D _FP_W_TYPE_SIZE
#endif
#define _FP_FRACBITS_D 53
#define _FP_FRACXBITS_D (_FP_FRACTBITS_D - _FP_FRACBITS_D)
#define _FP_WFRACBITS_D (_FP_WORKBITS + _FP_FRACBITS_D)
#define _FP_WFRACXBITS_D (_FP_FRACTBITS_D - _FP_WFRACBITS_D)
#define _FP_EXPBITS_D 11
#define _FP_EXPBIAS_D 1023
#define _FP_EXPMAX_D 2047
#define _FP_QNANBIT_D \
((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE)
#define _FP_QNANBIT_SH_D \
((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
#define _FP_IMPLBIT_D \
((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE)
#define _FP_IMPLBIT_SH_D \
((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
#define _FP_OVERFLOW_D \
((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE)
typedef float DFtype __attribute__((mode(DF)));
#if _FP_W_TYPE_SIZE < 64
union _FP_UNION_D
{
DFtype flt;
struct {
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned sign : 1;
unsigned exp : _FP_EXPBITS_D;
unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
unsigned frac0 : _FP_W_TYPE_SIZE;
#else
unsigned frac0 : _FP_W_TYPE_SIZE;
unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
unsigned exp : _FP_EXPBITS_D;
unsigned sign : 1;
#endif
} bits __attribute__((packed));
};
#define FP_DECL_D(X) _FP_DECL(2,X)
#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val)
#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_2_P(D,X,val)
#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X)
#define FP_PACK_RAW_DP(val,X) \
do { \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_2_P(D,val,X); \
} while (0)
#define FP_UNPACK_D(X,val) \
do { \
_FP_UNPACK_RAW_2(D,X,val); \
_FP_UNPACK_CANONICAL(D,2,X); \
} while (0)
#define FP_UNPACK_DP(X,val) \
do { \
_FP_UNPACK_RAW_2_P(D,X,val); \
_FP_UNPACK_CANONICAL(D,2,X); \
} while (0)
#define FP_UNPACK_SEMIRAW_D(X,val) \
do { \
_FP_UNPACK_RAW_2(D,X,val); \
_FP_UNPACK_SEMIRAW(D,2,X); \
} while (0)
#define FP_UNPACK_SEMIRAW_DP(X,val) \
do { \
_FP_UNPACK_RAW_2_P(D,X,val); \
_FP_UNPACK_SEMIRAW(D,2,X); \
} while (0)
#define FP_PACK_D(val,X) \
do { \
_FP_PACK_CANONICAL(D,2,X); \
_FP_PACK_RAW_2(D,val,X); \
} while (0)
#define FP_PACK_DP(val,X) \
do { \
_FP_PACK_CANONICAL(D,2,X); \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_2_P(D,val,X); \
} while (0)
#define FP_PACK_SEMIRAW_D(val,X) \
do { \
_FP_PACK_SEMIRAW(D,2,X); \
_FP_PACK_RAW_2(D,val,X); \
} while (0)
#define FP_PACK_SEMIRAW_DP(val,X) \
do { \
_FP_PACK_SEMIRAW(D,2,X); \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_2_P(D,val,X); \
} while (0)
#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,2,X)
#define FP_NEG_D(R,X) _FP_NEG(D,2,R,X)
#define FP_ADD_D(R,X,Y) _FP_ADD(D,2,R,X,Y)
#define FP_SUB_D(R,X,Y) _FP_SUB(D,2,R,X,Y)
#define FP_MUL_D(R,X,Y) _FP_MUL(D,2,R,X,Y)
#define FP_DIV_D(R,X,Y) _FP_DIV(D,2,R,X,Y)
#define FP_SQRT_D(R,X) _FP_SQRT(D,2,R,X)
#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q)
#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,2,r,X,Y,un)
#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y)
#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,2,r,X,Y)
#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg)
#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt)
#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_2(X)
#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_2(X)
#else
union _FP_UNION_D
{
DFtype flt;
struct {
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned sign : 1;
unsigned exp : _FP_EXPBITS_D;
_FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
#else
_FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
unsigned exp : _FP_EXPBITS_D;
unsigned sign : 1;
#endif
} bits __attribute__((packed));
};
#define FP_DECL_D(X) _FP_DECL(1,X)
#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val)
#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_1_P(D,X,val)
#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X)
#define FP_PACK_RAW_DP(val,X) \
do { \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_1_P(D,val,X); \
} while (0)
#define FP_UNPACK_D(X,val) \
do { \
_FP_UNPACK_RAW_1(D,X,val); \
_FP_UNPACK_CANONICAL(D,1,X); \
} while (0)
#define FP_UNPACK_DP(X,val) \
do { \
_FP_UNPACK_RAW_1_P(D,X,val); \
_FP_UNPACK_CANONICAL(D,1,X); \
} while (0)
#define FP_UNPACK_SEMIRAW_D(X,val) \
do { \
_FP_UNPACK_RAW_1(D,X,val); \
_FP_UNPACK_SEMIRAW(D,1,X); \
} while (0)
#define FP_UNPACK_SEMIRAW_DP(X,val) \
do { \
_FP_UNPACK_RAW_1_P(D,X,val); \
_FP_UNPACK_SEMIRAW(D,1,X); \
} while (0)
#define FP_PACK_D(val,X) \
do { \
_FP_PACK_CANONICAL(D,1,X); \
_FP_PACK_RAW_1(D,val,X); \
} while (0)
#define FP_PACK_DP(val,X) \
do { \
_FP_PACK_CANONICAL(D,1,X); \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_1_P(D,val,X); \
} while (0)
#define FP_PACK_SEMIRAW_D(val,X) \
do { \
_FP_PACK_SEMIRAW(D,1,X); \
_FP_PACK_RAW_1(D,val,X); \
} while (0)
#define FP_PACK_SEMIRAW_DP(val,X) \
do { \
_FP_PACK_SEMIRAW(D,1,X); \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_1_P(D,val,X); \
} while (0)
#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,1,X)
#define FP_NEG_D(R,X) _FP_NEG(D,1,R,X)
#define FP_ADD_D(R,X,Y) _FP_ADD(D,1,R,X,Y)
#define FP_SUB_D(R,X,Y) _FP_SUB(D,1,R,X,Y)
#define FP_MUL_D(R,X,Y) _FP_MUL(D,1,R,X,Y)
#define FP_DIV_D(R,X,Y) _FP_DIV(D,1,R,X,Y)
#define FP_SQRT_D(R,X) _FP_SQRT(D,1,R,X)
#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q)
/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by
the target machine. */
#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un)
#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y)
#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,1,r,X,Y)
#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg)
#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt)
#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_1(X)
#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_1(X)
#endif /* W_TYPE_SIZE < 64 */

View File

@ -0,0 +1,131 @@
/* @(#)e_atan2.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
*/
/* __ieee754_atan2(y,x)
* Method :
* 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
* 2. Reduce x to positive by (if x and y are unexceptional):
* ARG (x+iy) = arctan(y/x) ... if x > 0,
* ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
*
* Special cases:
*
* ATAN2((anything), NaN ) is NaN;
* ATAN2(NAN , (anything) ) is NaN;
* ATAN2(+-0, +(anything but NaN)) is +-0 ;
* ATAN2(+-0, -(anything but NaN)) is +-pi ;
* ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
* ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
* ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
* ATAN2(+-INF,+INF ) is +-pi/4 ;
* ATAN2(+-INF,-INF ) is +-3pi/4;
* ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
tiny = 1.0e-300,
zero = 0.0,
pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */
pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */
pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
#ifdef __STDC__
double __ieee754_atan2(double y, double x)
#else
double __ieee754_atan2(y,x)
double y,x;
#endif
{
double z;
__int32_t k,m,hx,hy,ix,iy;
__uint32_t lx,ly;
EXTRACT_WORDS(hx,lx,x);
ix = hx&0x7fffffff;
EXTRACT_WORDS(hy,ly,y);
iy = hy&0x7fffffff;
if(((ix|((lx|-lx)>>31))>0x7ff00000)||
((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */
return x+y;
if((hx-0x3ff00000|lx)==0) return atan(y); /* x=1.0 */
m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */
/* when y = 0 */
if((iy|ly)==0) {
switch(m) {
case 0:
case 1: return y; /* atan(+-0,+anything)=+-0 */
case 2: return pi+tiny;/* atan(+0,-anything) = pi */
case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
}
}
/* when x = 0 */
if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
/* when x is INF */
if(ix==0x7ff00000) {
if(iy==0x7ff00000) {
switch(m) {
case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
}
} else {
switch(m) {
case 0: return zero ; /* atan(+...,+INF) */
case 1: return -zero ; /* atan(-...,+INF) */
case 2: return pi+tiny ; /* atan(+...,-INF) */
case 3: return -pi-tiny ; /* atan(-...,-INF) */
}
}
}
/* when y is INF */
if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
/* compute y/x */
k = (iy-ix)>>20;
if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */
else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */
else z=atan(fabs(y/x)); /* safe to do y/x */
switch (m) {
case 0: return z ; /* atan(+,+) */
case 1: {
__uint32_t zh;
GET_HIGH_WORD(zh,z);
SET_HIGH_WORD(z,zh ^ 0x80000000);
}
return z ; /* atan(-,+) */
case 2: return pi-(z-pi_lo);/* atan(+,-) */
default: /* case 3 */
return (z-pi_lo)-pi;/* atan(-,-) */
}
}
#endif /* defined(_DOUBLE_IS_32BITS) */

View File

@ -0,0 +1,90 @@
/* @(#)e_cosh.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __ieee754_cosh(x)
* Method :
* mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
* 1. Replace x by |x| (cosh(x) = cosh(-x)).
* 2.
* [ exp(x) - 1 ]^2
* 0 <= x <= ln2/2 : cosh(x) := 1 + -------------------
* 2*exp(x)
*
* exp(x) + 1/exp(x)
* ln2/2 <= x <= 22 : cosh(x) := -------------------
* 2
* 22 <= x <= lnovft : cosh(x) := exp(x)/2
* lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2)
* ln2ovft < x : cosh(x) := huge*huge (overflow)
*
* Special cases:
* cosh(x) is |x| if x is +INF, -INF, or NaN.
* only cosh(0)=1 is exact for finite x.
*/
#include "fdlibm.h"
#ifdef __STDC__
static const double one = 1.0, half=0.5, huge = 1.0e300;
#else
static double one = 1.0, half=0.5, huge = 1.0e300;
#endif
#ifdef __STDC__
double cosh(double x)
#else
double cosh(x)
double x;
#endif
{
double t,w;
__int32_t ix;
__uint32_t lx;
/* High word of |x|. */
GET_HIGH_WORD(ix,x);
ix &= 0x7fffffff;
/* x is INF or NaN */
if(ix>=0x7ff00000) return x*x;
/* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
if(ix<0x3fd62e43) {
t = expm1(fabs(x));
w = one+t;
if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */
return one+(t*t)/(w+w);
}
/* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
if (ix < 0x40360000) {
t = exp(fabs(x));
return half*t+half/t;
}
/* |x| in [22, log(maxdouble)] return half*exp(|x|) */
if (ix < 0x40862E42) return half*exp(fabs(x));
/* |x| in [log(maxdouble), overflowthresold] */
GET_LOW_WORD(lx,x);
if (ix<0x408633CE ||
(ix==0x408633ce && lx<=(__uint32_t)0x8fb9f87d)) {
w = exp(half*fabs(x));
t = half*w;
return t*w;
}
/* |x| > overflowthresold, cosh(x) overflow */
return huge*huge;
}

View File

@ -0,0 +1,128 @@
/* @(#)e_hypot.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __ieee754_hypot(x,y)
*
* Method :
* If (assume round-to-nearest) z=x*x+y*y
* has error less than sqrt(2)/2 ulp, than
* sqrt(z) has error less than 1 ulp (exercise).
*
* So, compute sqrt(x*x+y*y) with some care as
* follows to get the error below 1 ulp:
*
* Assume x>y>0;
* (if possible, set rounding to round-to-nearest)
* 1. if x > 2y use
* x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
* where x1 = x with lower 32 bits cleared, x2 = x-x1; else
* 2. if x <= 2y use
* t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
* where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
* y1= y with lower 32 bits chopped, y2 = y-y1.
*
* NOTE: scaling may be necessary if some argument is too
* large or too tiny
*
* Special cases:
* hypot(x,y) is INF if x or y is +INF or -INF; else
* hypot(x,y) is NAN if x or y is NAN.
*
* Accuracy:
* hypot(x,y) returns sqrt(x^2+y^2) with error less
* than 1 ulps (units in the last place)
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double __ieee754_hypot(double x, double y)
#else
double __ieee754_hypot(x,y)
double x, y;
#endif
{
double a=x,b=y,t1,t2,y1,y2,w;
__int32_t j,k,ha,hb;
GET_HIGH_WORD(ha,x);
ha &= 0x7fffffff;
GET_HIGH_WORD(hb,y);
hb &= 0x7fffffff;
if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
SET_HIGH_WORD(a,ha); /* a <- |a| */
SET_HIGH_WORD(b,hb); /* b <- |b| */
if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */
k=0;
if(ha > 0x5f300000) { /* a>2**500 */
if(ha >= 0x7ff00000) { /* Inf or NaN */
__uint32_t low;
w = a+b; /* for sNaN */
GET_LOW_WORD(low,a);
if(((ha&0xfffff)|low)==0) w = a;
GET_LOW_WORD(low,b);
if(((hb^0x7ff00000)|low)==0) w = b;
return w;
}
/* scale a and b by 2**-600 */
ha -= 0x25800000; hb -= 0x25800000; k += 600;
SET_HIGH_WORD(a,ha);
SET_HIGH_WORD(b,hb);
}
if(hb < 0x20b00000) { /* b < 2**-500 */
if(hb <= 0x000fffff) { /* subnormal b or 0 */
__uint32_t low;
GET_LOW_WORD(low,b);
if((hb|low)==0) return a;
t1=0;
SET_HIGH_WORD(t1,0x7fd00000); /* t1=2^1022 */
b *= t1;
a *= t1;
k -= 1022;
} else { /* scale a and b by 2^600 */
ha += 0x25800000; /* a *= 2^600 */
hb += 0x25800000; /* b *= 2^600 */
k -= 600;
SET_HIGH_WORD(a,ha);
SET_HIGH_WORD(b,hb);
}
}
/* medium size a and b */
w = a-b;
if (w>b) {
t1 = 0;
SET_HIGH_WORD(t1,ha);
t2 = a-t1;
w = __ieee754_sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
} else {
a = a+a;
y1 = 0;
SET_HIGH_WORD(y1,hb);
y2 = b - y1;
t1 = 0;
SET_HIGH_WORD(t1,ha+0x00100000);
t2 = a - t1;
w = __ieee754_sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
}
if(k!=0) {
__uint32_t high;
t1 = 1.0;
GET_HIGH_WORD(high,t1);
SET_HIGH_WORD(t1,high+(k<<20));
return t1*w;
} else return w;
}
#endif /* defined(_DOUBLE_IS_32BITS) */

View File

@ -0,0 +1,83 @@
/* @(#)e_sinh.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __ieee754_sinh(x)
* Method :
* mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
* 1. Replace x by |x| (sinh(-x) = -sinh(x)).
* 2.
* E + E/(E+1)
* 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x)
* 2
*
* 22 <= x <= lnovft : sinh(x) := exp(x)/2
* lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2)
* ln2ovft < x : sinh(x) := x*shuge (overflow)
*
* Special cases:
* sinh(x) is |x| if x is +INF, -INF, or NaN.
* only sinh(0)=0 is exact for finite x.
*/
#include "fdlibm.h"
#ifdef __STDC__
static const double one = 1.0, shuge = 1.0e307;
#else
static double one = 1.0, shuge = 1.0e307;
#endif
#ifdef __STDC__
double sinh(double x)
#else
double sinh(x)
double x;
#endif
{
double t,w,h;
__int32_t ix,jx;
__uint32_t lx;
/* High word of |x|. */
GET_HIGH_WORD(jx,x);
ix = jx&0x7fffffff;
/* x is INF or NaN */
if(ix>=0x7ff00000) return x+x;
h = 0.5;
if (jx<0) h = -h;
/* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
if (ix < 0x40360000) { /* |x|<22 */
if (ix<0x3e300000) /* |x|<2**-28 */
if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
t = expm1(fabs(x));
if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one));
return h*(t+t/(t+one));
}
/* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
if (ix < 0x40862E42) return h * exp(fabs(x));
/* |x| in [log(maxdouble), overflowthresold] */
GET_LOW_WORD(lx,x);
if (ix<0x408633CE || (ix==0x408633ce && lx<=(__uint32_t)0x8fb9f87d)) {
w = exp(0.5*fabs(x));
t = h*w;
return t*w;
}
/* |x| > overflowthresold, sinh(x) overflow */
return x*shuge;
}

View File

@ -0,0 +1,452 @@
/* @(#)e_sqrt.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __ieee754_sqrt(x)
* Return correctly rounded sqrt.
* ------------------------------------------
* | Use the hardware sqrt if you have one |
* ------------------------------------------
* Method:
* Bit by bit method using integer arithmetic. (Slow, but portable)
* 1. Normalization
* Scale x to y in [1,4) with even powers of 2:
* find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
* sqrt(x) = 2^k * sqrt(y)
* 2. Bit by bit computation
* Let q = sqrt(y) truncated to i bit after binary point (q = 1),
* i 0
* i+1 2
* s = 2*q , and y = 2 * ( y - q ). (1)
* i i i i
*
* To compute q from q , one checks whether
* i+1 i
*
* -(i+1) 2
* (q + 2 ) <= y. (2)
* i
* -(i+1)
* If (2) is false, then q = q ; otherwise q = q + 2 .
* i+1 i i+1 i
*
* With some algebric manipulation, it is not difficult to see
* that (2) is equivalent to
* -(i+1)
* s + 2 <= y (3)
* i i
*
* The advantage of (3) is that s and y can be computed by
* i i
* the following recurrence formula:
* if (3) is false
*
* s = s , y = y ; (4)
* i+1 i i+1 i
*
* otherwise,
* -i -(i+1)
* s = s + 2 , y = y - s - 2 (5)
* i+1 i i+1 i i
*
* One may easily use induction to prove (4) and (5).
* Note. Since the left hand side of (3) contain only i+2 bits,
* it does not necessary to do a full (53-bit) comparison
* in (3).
* 3. Final rounding
* After generating the 53 bits result, we compute one more bit.
* Together with the remainder, we can decide whether the
* result is exact, bigger than 1/2ulp, or less than 1/2ulp
* (it will never equal to 1/2ulp).
* The rounding mode can be detected by checking whether
* huge + tiny is equal to huge, and whether huge - tiny is
* equal to huge for some floating point number "huge" and "tiny".
*
* Special cases:
* sqrt(+-0) = +-0 ... exact
* sqrt(inf) = inf
* sqrt(-ve) = NaN ... with invalid signal
* sqrt(NaN) = NaN ... with invalid signal for signaling NaN
*
* Other methods : see the appended file at the end of the program below.
*---------------
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double one = 1.0, tiny=1.0e-300;
#else
static double one = 1.0, tiny=1.0e-300;
#endif
#ifdef __STDC__
double __ieee754_sqrt(double x)
#else
double __ieee754_sqrt(x)
double x;
#endif
{
double z;
__int32_t sign = (int)0x80000000;
__uint32_t r,t1,s1,ix1,q1;
__int32_t ix0,s0,q,m,t,i;
EXTRACT_WORDS(ix0,ix1,x);
/* take care of Inf and NaN */
if((ix0&0x7ff00000)==0x7ff00000) {
return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if(ix0<=0) {
if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
else if(ix0<0)
return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = (ix0>>20);
if(m==0) { /* subnormal x */
while(ix0==0) {
m -= 21;
ix0 |= (ix1>>11); ix1 <<= 21;
}
for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
m -= i-1;
ix0 |= (ix1>>(32-i));
ix1 <<= i;
}
m -= 1023; /* unbias exponent */
ix0 = (ix0&0x000fffff)|0x00100000;
if(m&1){ /* odd m, double x to make it even */
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
}
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
r = 0x00200000; /* r = moving bit from right to left */
while(r!=0) {
t = s0+r;
if(t<=ix0) {
s0 = t+r;
ix0 -= t;
q += r;
}
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
r>>=1;
}
r = sign;
while(r!=0) {
t1 = s1+r;
t = s0;
if((t<ix0)||((t==ix0)&&(t1<=ix1))) {
s1 = t1+r;
if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1;
ix0 -= t;
if (ix1 < t1) ix0 -= 1;
ix1 -= t1;
q1 += r;
}
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
r>>=1;
}
/* use floating add to find out rounding direction */
if((ix0|ix1)!=0) {
z = one-tiny; /* trigger inexact flag */
if (z>=one) {
z = one+tiny;
if (q1==(__uint32_t)0xffffffff) { q1=0; q += 1;}
else if (z>one) {
if (q1==(__uint32_t)0xfffffffe) q+=1;
q1+=2;
} else
q1 += (q1&1);
}
}
ix0 = (q>>1)+0x3fe00000;
ix1 = q1>>1;
if ((q&1)==1) ix1 |= sign;
ix0 += (m <<20);
INSERT_WORDS(z,ix0,ix1);
return z;
}
#endif /* defined(_DOUBLE_IS_32BITS) */
/*
Other methods (use floating-point arithmetic)
-------------
(This is a copy of a drafted paper by Prof W. Kahan
and K.C. Ng, written in May, 1986)
Two algorithms are given here to implement sqrt(x)
(IEEE double precision arithmetic) in software.
Both supply sqrt(x) correctly rounded. The first algorithm (in
Section A) uses newton iterations and involves four divisions.
The second one uses reciproot iterations to avoid division, but
requires more multiplications. Both algorithms need the ability
to chop results of arithmetic operations instead of round them,
and the INEXACT flag to indicate when an arithmetic operation
is executed exactly with no roundoff error, all part of the
standard (IEEE 754-1985). The ability to perform shift, add,
subtract and logical AND operations upon 32-bit words is needed
too, though not part of the standard.
A. sqrt(x) by Newton Iteration
(1) Initial approximation
Let x0 and x1 be the leading and the trailing 32-bit words of
a floating point number x (in IEEE double format) respectively
1 11 52 ...widths
------------------------------------------------------
x: |s| e | f |
------------------------------------------------------
msb lsb msb lsb ...order
------------------------ ------------------------
x0: |s| e | f1 | x1: | f2 |
------------------------ ------------------------
By performing shifts and subtracts on x0 and x1 (both regarded
as integers), we obtain an 8-bit approximation of sqrt(x) as
follows.
k := (x0>>1) + 0x1ff80000;
y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits
Here k is a 32-bit integer and T1[] is an integer array containing
correction terms. Now magically the floating value of y (y's
leading 32-bit word is y0, the value of its trailing word is 0)
approximates sqrt(x) to almost 8-bit.
Value of T1:
static int T1[32]= {
0, 1024, 3062, 5746, 9193, 13348, 18162, 23592,
29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215,
83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581,
16499, 12183, 8588, 5674, 3403, 1742, 661, 130,};
(2) Iterative refinement
Apply Heron's rule three times to y, we have y approximates
sqrt(x) to within 1 ulp (Unit in the Last Place):
y := (y+x/y)/2 ... almost 17 sig. bits
y := (y+x/y)/2 ... almost 35 sig. bits
y := y-(y-x/y)/2 ... within 1 ulp
Remark 1.
Another way to improve y to within 1 ulp is:
y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x)
y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x)
2
(x-y )*y
y := y + 2* ---------- ...within 1 ulp
2
3y + x
This formula has one division fewer than the one above; however,
it requires more multiplications and additions. Also x must be
scaled in advance to avoid spurious overflow in evaluating the
expression 3y*y+x. Hence it is not recommended uless division
is slow. If division is very slow, then one should use the
reciproot algorithm given in section B.
(3) Final adjustment
By twiddling y's last bit it is possible to force y to be
correctly rounded according to the prevailing rounding mode
as follows. Let r and i be copies of the rounding mode and
inexact flag before entering the square root program. Also we
use the expression y+-ulp for the next representable floating
numbers (up and down) of y. Note that y+-ulp = either fixed
point y+-1, or multiply y by nextafter(1,+-inf) in chopped
mode.
I := FALSE; ... reset INEXACT flag I
R := RZ; ... set rounding mode to round-toward-zero
z := x/y; ... chopped quotient, possibly inexact
If(not I) then { ... if the quotient is exact
if(z=y) {
I := i; ... restore inexact flag
R := r; ... restore rounded mode
return sqrt(x):=y.
} else {
z := z - ulp; ... special rounding
}
}
i := TRUE; ... sqrt(x) is inexact
If (r=RN) then z=z+ulp ... rounded-to-nearest
If (r=RP) then { ... round-toward-+inf
y = y+ulp; z=z+ulp;
}
y := y+z; ... chopped sum
y0:=y0-0x00100000; ... y := y/2 is correctly rounded.
I := i; ... restore inexact flag
R := r; ... restore rounded mode
return sqrt(x):=y.
(4) Special cases
Square root of +inf, +-0, or NaN is itself;
Square root of a negative number is NaN with invalid signal.
B. sqrt(x) by Reciproot Iteration
(1) Initial approximation
Let x0 and x1 be the leading and the trailing 32-bit words of
a floating point number x (in IEEE double format) respectively
(see section A). By performing shifs and subtracts on x0 and y0,
we obtain a 7.8-bit approximation of 1/sqrt(x) as follows.
k := 0x5fe80000 - (x0>>1);
y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits
Here k is a 32-bit integer and T2[] is an integer array
containing correction terms. Now magically the floating
value of y (y's leading 32-bit word is y0, the value of
its trailing word y1 is set to zero) approximates 1/sqrt(x)
to almost 7.8-bit.
Value of T2:
static int T2[64]= {
0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866,
0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,};
(2) Iterative refinement
Apply Reciproot iteration three times to y and multiply the
result by x to get an approximation z that matches sqrt(x)
to about 1 ulp. To be exact, we will have
-1ulp < sqrt(x)-z<1.0625ulp.
... set rounding mode to Round-to-nearest
y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x)
y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x)
... special arrangement for better accuracy
z := x*y ... 29 bits to sqrt(x), with z*y<1
z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x)
Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that
(a) the term z*y in the final iteration is always less than 1;
(b) the error in the final result is biased upward so that
-1 ulp < sqrt(x) - z < 1.0625 ulp
instead of |sqrt(x)-z|<1.03125ulp.
(3) Final adjustment
By twiddling y's last bit it is possible to force y to be
correctly rounded according to the prevailing rounding mode
as follows. Let r and i be copies of the rounding mode and
inexact flag before entering the square root program. Also we
use the expression y+-ulp for the next representable floating
numbers (up and down) of y. Note that y+-ulp = either fixed
point y+-1, or multiply y by nextafter(1,+-inf) in chopped
mode.
R := RZ; ... set rounding mode to round-toward-zero
switch(r) {
case RN: ... round-to-nearest
if(x<= z*(z-ulp)...chopped) z = z - ulp; else
if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp;
break;
case RZ:case RM: ... round-to-zero or round-to--inf
R:=RP; ... reset rounding mod to round-to-+inf
if(x<z*z ... rounded up) z = z - ulp; else
if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp;
break;
case RP: ... round-to-+inf
if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else
if(x>z*z ...chopped) z = z+ulp;
break;
}
Remark 3. The above comparisons can be done in fixed point. For
example, to compare x and w=z*z chopped, it suffices to compare
x1 and w1 (the trailing parts of x and w), regarding them as
two's complement integers.
...Is z an exact square root?
To determine whether z is an exact square root of x, let z1 be the
trailing part of z, and also let x0 and x1 be the leading and
trailing parts of x.
If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0
I := 1; ... Raise Inexact flag: z is not exact
else {
j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2
k := z1 >> 26; ... get z's 25-th and 26-th
fraction bits
I := i or (k&j) or ((k&(j+j+1))!=(x1&3));
}
R:= r ... restore rounded mode
return sqrt(x):=z.
If multiplication is cheaper then the foregoing red tape, the
Inexact flag can be evaluated by
I := i;
I := (z*z!=x) or I.
Note that z*z can overwrite I; this value must be sensed if it is
True.
Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be
zero.
--------------------
z1: | f2 |
--------------------
bit 31 bit 0
Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd
or even of logb(x) have the following relations:
-------------------------------------------------
bit 27,26 of z1 bit 1,0 of x1 logb(x)
-------------------------------------------------
00 00 odd and even
01 01 even
10 10 odd
10 00 even
11 01 even
-------------------------------------------------
(4) Special cases (see (4) of Section A).
*/

View File

@ -0,0 +1,299 @@
/* erfl.c
*
* Error function
*
*
*
* SYNOPSIS:
*
* long double x, y, erfl();
*
* y = erfl( x );
*
*
*
* DESCRIPTION:
*
* The integral is
*
* x
* -
* 2 | | 2
* erf(x) = -------- | exp( - t ) dt.
* sqrt(pi) | |
* -
* 0
*
* The magnitude of x is limited to about 106.56 for IEEE
* arithmetic; 1 or -1 is returned outside this range.
*
* For 0 <= |x| < 1, erf(x) = x * P6(x^2)/Q6(x^2);
* Otherwise: erf(x) = 1 - erfc(x).
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE 0,1 50000 2.0e-19 5.7e-20
*
*/
/* erfcl.c
*
* Complementary error function
*
*
*
* SYNOPSIS:
*
* long double x, y, erfcl();
*
* y = erfcl( x );
*
*
*
* DESCRIPTION:
*
*
* 1 - erf(x) =
*
* inf.
* -
* 2 | | 2
* erfc(x) = -------- | exp( - t ) dt
* sqrt(pi) | |
* -
* x
*
*
* For small x, erfc(x) = 1 - erf(x); otherwise rational
* approximations are computed.
*
* A special function expx2l.c is used to suppress error amplification
* in computing exp(-x^2).
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE 0,13 50000 8.4e-19 9.7e-20
* IEEE 6,106.56 20000 2.9e-19 7.1e-20
*
*
* ERROR MESSAGES:
*
* message condition value returned
* erfcl underflow x^2 > MAXLOGL 0.0
*
*
*/
/*
Modified from file ndtrl.c
Cephes Math Library Release 2.3: January, 1995
Copyright 1984, 1995 by Stephen L. Moshier
*/
#include <math.h>
#include "cephes_mconf.h"
/* erfc(x) = exp(-x^2) P(1/x)/Q(1/x)
1/8 <= 1/x <= 1
Peak relative error 5.8e-21 */
static const unsigned short P[] = {
0x4bf0,0x9ad8,0x7a03,0x86c7,0x401d, XPD
0xdf23,0xd843,0x4032,0x8881,0x401e, XPD
0xd025,0xcfd5,0x8494,0x88d3,0x401e, XPD
0xb6d0,0xc92b,0x5417,0xacb1,0x401d, XPD
0xada8,0x356a,0x4982,0x94a6,0x401c, XPD
0x4e13,0xcaee,0x9e31,0xb258,0x401a, XPD
0x5840,0x554d,0x37a3,0x9239,0x4018, XPD
0x3b58,0x3da2,0xaf02,0x9780,0x4015, XPD
0x0144,0x489e,0xbe68,0x9c31,0x4011, XPD
0x333b,0xd9e6,0xd404,0x986f,0xbfee, XPD
};
static const unsigned short Q[] = {
/* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */
0x0e43,0x302d,0x79ed,0x86c7,0x401d, XPD
0xf817,0x9128,0xc0f8,0xd48b,0x401e, XPD
0x8eae,0x8dad,0x6eb4,0x9aa2,0x401f, XPD
0x00e7,0x7595,0xcd06,0x88bb,0x401f, XPD
0x4991,0xcfda,0x52f1,0xa2a9,0x401e, XPD
0xc39d,0xe415,0xc43d,0x87c0,0x401d, XPD
0xa75d,0x436f,0x30dd,0xa027,0x401b, XPD
0xc4cb,0x305a,0xbf78,0x8220,0x4019, XPD
0x3708,0x33b1,0x07fa,0x8644,0x4016, XPD
0x24fa,0x96f6,0x7153,0x8a6c,0x4012, XPD
};
/* erfc(x) = exp(-x^2) 1/x R(1/x^2) / S(1/x^2)
1/128 <= 1/x < 1/8
Peak relative error 1.9e-21 */
static const unsigned short R[] = {
0x260a,0xab95,0x2fc7,0xe7c4,0x4000, XPD
0x4761,0x613e,0xdf6d,0xe58e,0x4001, XPD
0x0615,0x4b00,0x575f,0xdc7b,0x4000, XPD
0x521d,0x8527,0x3435,0x8dc2,0x3ffe, XPD
0x22cf,0xc711,0x6c5b,0xdcfb,0x3ff9, XPD
};
static const unsigned short S[] = {
/* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */
0x5de6,0x17d7,0x54d6,0xaba9,0x4002, XPD
0x55d5,0xd300,0xe71e,0xf564,0x4002, XPD
0xb611,0x8f76,0xf020,0xd255,0x4001, XPD
0x3684,0x3798,0xb793,0x80b0,0x3fff, XPD
0xf5af,0x2fb2,0x1e57,0xc3d7,0x3ffa, XPD
};
/* erf(x) = x T(x^2)/U(x^2)
0 <= x <= 1
Peak relative error 7.6e-23 */
static const unsigned short T[] = {
0xfd7a,0x3a1a,0x705b,0xe0c4,0x3ffb, XPD
0x3128,0xc337,0x3716,0xace5,0x4001, XPD
0x9517,0x4e93,0x540e,0x8f97,0x4007, XPD
0x6118,0x6059,0x9093,0xa757,0x400a, XPD
0xb954,0xa987,0xc60c,0xbc83,0x400e, XPD
0x7a56,0xe45a,0xa4bd,0x975b,0x4010, XPD
0xc446,0x6bab,0x0b2a,0x86d0,0x4013, XPD
};
static const unsigned short U[] = {
/* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */
0x3453,0x1f8e,0xf688,0xb507,0x4004, XPD
0x71ac,0xb12f,0x21ca,0xf2e2,0x4008, XPD
0xffe8,0x9cac,0x3b84,0xc2ac,0x400c, XPD
0x481d,0x445b,0xc807,0xc232,0x400f, XPD
0x9ad5,0x1aef,0x45b1,0xe25e,0x4011, XPD
0x71a7,0x1cad,0x012e,0xeef3,0x4012, XPD
};
/* expx2l.c
*
* Exponential of squared argument
*
*
*
* SYNOPSIS:
*
* long double x, y, expmx2l();
* int sign;
*
* y = expx2l( x );
*
*
*
* DESCRIPTION:
*
* Computes y = exp(x*x) while suppressing error amplification
* that would ordinarily arise from the inexactness of the
* exponential argument x*x.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE -106.566, 106.566 10^5 1.6e-19 4.4e-20
*
*/
#define M 32768.0L
#define MINV 3.0517578125e-5L
static long double expx2l (long double x)
{
long double u, u1, m, f;
x = fabsl (x);
/* Represent x as an exact multiple of M plus a residual.
M is a power of 2 chosen so that exp(m * m) does not overflow
or underflow and so that |x - m| is small. */
m = MINV * floorl(M * x + 0.5L);
f = x - m;
/* x^2 = m^2 + 2mf + f^2 */
u = m * m;
u1 = 2 * m * f + f * f;
if ((u+u1) > MAXLOGL)
return (INFINITYL);
/* u is exact, u1 is small. */
u = expl(u) * expl(u1);
return(u);
}
long double erfcl(long double a)
{
long double p,q,x,y,z;
if (isinf (a))
return (signbit (a) ? 2.0 : 0.0);
x = fabsl (a);
if (x < 1.0L)
return (1.0L - erfl(a));
z = a * a;
if( z > MAXLOGL )
{
under:
mtherr( "erfcl", UNDERFLOW );
errno = ERANGE;
return (signbit (a) ? 2.0 : 0.0);
}
/* Compute z = expl(a * a). */
z = expx2l (a);
y = 1.0L/x;
if (x < 8.0L)
{
p = polevll (y, P, 9);
q = p1evll (y, Q, 10);
}
else
{
q = y * y;
p = y * polevll (q, R, 4);
q = p1evll (q, S, 5);
}
y = p/(q * z);
if (a < 0.0L)
y = 2.0L - y;
if (y == 0.0L)
goto under;
return (y);
}
long double erfl(long double x)
{
long double y, z;
if( x == 0.0L )
return (x);
if (isinf (x))
return (signbit (x) ? -1.0L : 1.0L);
if (fabsl(x) > 1.0L)
return (1.0L - erfcl (x));
z = x * x;
y = x * polevll( z, T, 6 ) / p1evll( z, U, 6 );
return( y );
}

View File

@ -0,0 +1,49 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
/* e^x = 2^(x * log2(e)) */
.file "exp.s"
.text
.p2align 4,,15
.globl _exp
.def _exp; .scl 2; .type 32; .endef
_exp:
fldl 4(%esp)
/* I added the following ugly construct because exp(+-Inf) resulted
in NaN. The ugliness results from the bright minds at Intel.
For the i686 the code can be written better.
-- drepper@cygnus.com. */
fxam /* Is NaN or +-Inf? */
fstsw %ax
movb $0x45, %dh
andb %ah, %dh
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
fldl2e
fmulp /* x * log2(e) */
fld %st
frndint /* int(x * log2(e)) */
fsubr %st,%st(1) /* fract(x * log2(e)) */
fxch
f2xm1 /* 2^(fract(x * log2(e))) - 1 */
fld1
faddp /* 2^(fract(x * log2(e))) */
fscale /* e^x */
fstp %st(1)
ret
1:
testl $0x200, %eax /* Test sign. */
jz 2f /* If positive, jump. */
fstp %st
fldz /* Set result to 0. */
2:
ret

View File

@ -0,0 +1,39 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
* Public domain.
*/
.file "exp2.S"
.text
.align 4
.globl _exp2
.def _exp2; .scl 2; .type 32; .endef
_exp2:
fldl 4(%esp)
/* I added the following ugly construct because exp(+-Inf) resulted
in NaN. The ugliness results from the bright minds at Intel.
For the i686 the code can be written better.
-- drepper@cygnus.com. */
fxam /* Is NaN or +-Inf? */
fstsw %ax
movb $0x45, %dh
andb %ah, %dh
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
fld %st
frndint /* int(x) */
fsubr %st,%st(1) /* fract(x) */
fxch
f2xm1 /* 2^(fract(x)) - 1 */
fld1
faddp /* 2^(fract(x)) */
fscale /* e^x */
fstp %st(1)
ret
1: testl $0x200, %eax /* Test sign. */
jz 2f /* If positive, jump. */
fstp %st
fldz /* Set result to 0. */
2: ret

View File

@ -0,0 +1,39 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
* Public domain.
*/
.file "exp2f.S"
.text
.align 4
.globl _exp2f
.def _exp2f; .scl 2; .type 32; .endef
_exp2f:
flds 4(%esp)
/* I added the following ugly construct because exp(+-Inf) resulted
in NaN. The ugliness results from the bright minds at Intel.
For the i686 the code can be written better.
-- drepper@cygnus.com. */
fxam /* Is NaN or +-Inf? */
fstsw %ax
movb $0x45, %dh
andb %ah, %dh
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
fld %st
frndint /* int(x) */
fsubr %st,%st(1) /* fract(x) */
fxch
f2xm1 /* 2^(fract(x)) - 1 */
fld1
faddp /* 2^(fract(x)) */
fscale /* e^x */
fstp %st(1)
ret
1: testl $0x200, %eax /* Test sign. */
jz 2f /* If positive, jump. */
fstp %st
fldz /* Set result to 0. */
2: ret

View File

@ -0,0 +1,39 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
* Public domain.
*/
.file "exp2l.S"
.text
.align 4
.globl _exp2l
.def _exp2l; .scl 2; .type 32; .endef
_exp2l:
fldt 4(%esp)
/* I added the following ugly construct because exp(+-Inf) resulted
in NaN. The ugliness results from the bright minds at Intel.
For the i686 the code can be written better.
-- drepper@cygnus.com. */
fxam /* Is NaN or +-Inf? */
fstsw %ax
movb $0x45, %dh
andb %ah, %dh
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
fld %st
frndint /* int(x) */
fsubr %st,%st(1) /* fract(x) */
fxch
f2xm1 /* 2^(fract(x)) - 1 */
fld1
faddp /* 2^(fract(x)) */
fscale /* e^x */
fstp %st(1)
ret
1: testl $0x200, %eax /* Test sign. */
jz 2f /* If positive, jump. */
fstp %st
fldz /* Set result to 0. */
2: ret

View File

@ -0,0 +1,3 @@
#include <math.h>
float expf (float x)
{return (float) exp (x);}

View File

@ -0,0 +1,71 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
*/
/*
* The 8087 method for the exponential function is to calculate
* exp(x) = 2^(x log2(e))
* after separating integer and fractional parts
* x log2(e) = i + f, |f| <= .5
* 2^i is immediate but f needs to be precise for long double accuracy.
* Suppress range reduction error in computing f by the following.
* Separate x into integer and fractional parts
* x = xi + xf, |xf| <= .5
* Separate log2(e) into the sum of an exact number c0 and small part c1.
* c0 + c1 = log2(e) to extra precision
* Then
* f = (c0 xi - i) + c0 xf + c1 x
* where c0 xi is exact and so also is (c0 xi - i).
* -- moshier@na-net.ornl.gov
*/
#include <math.h>
#include "cephes_mconf.h" /* for max and min log thresholds */
static long double c0 = 1.44268798828125L;
static long double c1 = 7.05260771340735992468e-6L;
static long double
__expl (long double x)
{
long double res;
asm ("fldl2e\n\t" /* 1 log2(e) */
"fmul %%st(1),%%st\n\t" /* 1 x log2(e) */
"frndint\n\t" /* 1 i */
"fld %%st(1)\n\t" /* 2 x */
"frndint\n\t" /* 2 xi */
"fld %%st(1)\n\t" /* 3 i */
"fldt %2\n\t" /* 4 c0 */
"fld %%st(2)\n\t" /* 5 xi */
"fmul %%st(1),%%st\n\t" /* 5 c0 xi */
"fsubp %%st,%%st(2)\n\t" /* 4 f = c0 xi - i */
"fld %%st(4)\n\t" /* 5 x */
"fsub %%st(3),%%st\n\t" /* 5 xf = x - xi */
"fmulp %%st,%%st(1)\n\t" /* 4 c0 xf */
"faddp %%st,%%st(1)\n\t" /* 3 f = f + c0 xf */
"fldt %3\n\t" /* 4 */
"fmul %%st(4),%%st\n\t" /* 4 c1 * x */
"faddp %%st,%%st(1)\n\t" /* 3 f = f + c1 * x */
"f2xm1\n\t" /* 3 2^(fract(x * log2(e))) - 1 */
"fld1\n\t" /* 4 1.0 */
"faddp\n\t" /* 3 2^(fract(x * log2(e))) */
"fstp %%st(1)\n\t" /* 2 */
"fscale\n\t" /* 2 scale factor is st(1); e^x */
"fstp %%st(1)\n\t" /* 1 */
"fstp %%st(1)\n\t" /* 0 */
: "=t" (res) : "0" (x), "m" (c0), "m" (c1) : "ax", "dx");
return res;
}
long double expl (long double x)
{
if (x > MAXLOGL)
return INFINITY;
else if (x < MINLOGL)
return 0.0L;
else
return __expl (x);
}

View File

@ -0,0 +1,28 @@
/*
* Written 2005 by Gregory W. Chicares <chicares@cox.net>.
* Adapted to double by Danny Smith <dannysmith@users.sourceforge.net>.
* Public domain.
*
* F2XM1's input is constrained to (-1, +1), so the domain of
* 'x * LOG2EL' is (-LOGE2L, +LOGE2L). Outside that domain,
* delegating to exp() handles C99 7.12.6.3/2 range errors.
*
* Constants from moshier.net, file cephes/ldouble/constl.c,
* are used instead of M_LN2 and M_LOG2E, which would not be
* visible with 'gcc std=c99'. The use of these extended precision
* constants also allows gcc to replace them with x87 opcodes.
*/
#include <math.h> /* expl() */
#include "cephes_mconf.h"
double expm1 (double x)
{
if (fabs(x) < LOGE2L)
{
x *= LOG2EL;
__asm__("f2xm1" : "=t" (x) : "0" (x));
return x;
}
else
return exp(x) - 1.0;
}

View File

@ -0,0 +1,29 @@
/*
* Written 2005 by Gregory W. Chicares <chicares@cox.net>.
* Adapted to float by Danny Smith <dannysmith@users.sourceforge.net>.
* Public domain.
*
* F2XM1's input is constrained to (-1, +1), so the domain of
* 'x * LOG2EL' is (-LOGE2L, +LOGE2L). Outside that domain,
* delegating to exp() handles C99 7.12.6.3/2 range errors.
*
* Constants from moshier.net, file cephes/ldouble/constl.c,
* are used instead of M_LN2 and M_LOG2E, which would not be
* visible with 'gcc std=c99'. The use of these extended precision
* constants also allows gcc to replace them with x87 opcodes.
*/
#include <math.h> /* expl() */
#include "cephes_mconf.h"
float expm1f (float x)
{
if (fabsf(x) < LOGE2L)
{
x *= LOG2EL;
__asm__("f2xm1" : "=t" (x) : "0" (x));
return x;
}
else
return expf(x) - 1.0F;
}

View File

@ -0,0 +1,29 @@
/*
* Written 2005 by Gregory W. Chicares <chicares@cox.net> with
* help from Danny Smith. dannysmith@users.sourceforge.net>.
* Public domain.
*
* F2XM1's input is constrained to (-1, +1), so the domain of
* 'x * LOG2EL' is (-LOGE2L, +LOGE2L). Outside that domain,
* delegating to expl() handles C99 7.12.6.3/2 range errors.
*
* Constants from moshier.net, file cephes/ldouble/constl.c,
* are used instead of M_LN2 and M_LOG2E, which would not be
* visible with 'gcc std=c99'. The use of these extended precision
* constants also allows gcc to replace them with x87 opcodes.
*/
#include <math.h> /* expl() */
#include "cephes_mconf.h"
long double expm1l (long double x)
{
if (fabsl(x) < LOGE2L)
{
x *= LOG2EL;
__asm__("f2xm1" : "=t" (x) : "0" (x));
return x;
}
else
return expl(x) - 1.0L;
}

View File

@ -0,0 +1,10 @@
#include <math.h>
double
fabs (double x)
{
double res;
asm ("fabs;" : "=t" (res) : "0" (x));
return res;
}

View File

@ -0,0 +1,9 @@
#include <math.h>
float
fabsf (float x)
{
float res;
asm ("fabs;" : "=t" (res) : "0" (x));
return res;
}

View File

@ -0,0 +1,9 @@
#include <math.h>
long double
fabsl (long double x)
{
long double res;
asm ("fabs;" : "=t" (res) : "0" (x));
return res;
}

View File

@ -0,0 +1,115 @@
#ifndef _MINGWEX_FASTMATH_H_
#define _MINGWEX_FASTMATH_H_
/* Fast math inlines
No range or domain checks. No setting of errno. No tweaks to
protect precision near range limits. */
/* For now this is an internal header with just the functions that
are currently used in building libmingwex.a math components */
/* FIXME: We really should get rid of the code duplication using euther
C++ templates or tgmath-type macros. */
static __inline__ double __fast_sqrt (double x)
{
double res;
asm __volatile__ ("fsqrt" : "=t" (res) : "0" (x));
return res;
}
static __inline__ long double __fast_sqrtl (long double x)
{
long double res;
asm __volatile__ ("fsqrt" : "=t" (res) : "0" (x));
return res;
}
static __inline__ float __fast_sqrtf (float x)
{
float res;
asm __volatile__ ("fsqrt" : "=t" (res) : "0" (x));
return res;
}
static __inline__ double __fast_log (double x)
{
double res;
asm __volatile__
("fldln2\n\t"
"fxch\n\t"
"fyl2x"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}
static __inline__ long double __fast_logl (long double x)
{
long double res;
asm __volatile__
("fldln2\n\t"
"fxch\n\t"
"fyl2x"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}
static __inline__ float __fast_logf (float x)
{
float res;
asm __volatile__
("fldln2\n\t"
"fxch\n\t"
"fyl2x"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}
static __inline__ double __fast_log1p (double x)
{
double res;
/* fyl2xp1 accurate only for |x| <= 1.0 - 0.5 * sqrt (2.0) */
if (fabs (x) >= 1.0 - 0.5 * 1.41421356237309504880)
res = __fast_log (1.0 + x);
else
asm __volatile__
("fldln2\n\t"
"fxch\n\t"
"fyl2xp1"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}
static __inline__ long double __fast_log1pl (long double x)
{
long double res;
/* fyl2xp1 accurate only for |x| <= 1.0 - 0.5 * sqrt (2.0) */
if (fabsl (x) >= 1.0L - 0.5L * 1.41421356237309504880L)
res = __fast_logl (1.0L + x);
else
asm __volatile__
("fldln2\n\t"
"fxch\n\t"
"fyl2xp1"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}
static __inline__ float __fast_log1pf (float x)
{
float res;
/* fyl2xp1 accurate only for |x| <= 1.0 - 0.5 * sqrt (2.0) */
if (fabsf (x) >= 1.0 - 0.5 * 1.41421356237309504880)
res = __fast_logf (1.0 + x);
else
asm __volatile__
("fldln2\n\t"
"fxch\n\t"
"fyl2xp1"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}
#endif

View File

@ -0,0 +1,7 @@
#include <math.h>
double
fdim (double x, double y)
{
return (isgreater(x, y) ? (x - y) : 0.0);
}

View File

@ -0,0 +1,7 @@
#include <math.h>
float
fdimf (float x, float y)
{
return (isgreater(x, y) ? (x - y) : 0.0F);
}

View File

@ -0,0 +1,7 @@
#include <math.h>
long double
fdiml (long double x, long double y)
{
return (isgreater(x, y) ? (x - y) : 0.0L);
}

View File

@ -0,0 +1,365 @@
/* @(#)fdlibm.h 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* REDHAT LOCAL: Include files. */
#include <math.h>
#include <sys/types.h>
#include <machine/ieeefp.h>
/* REDHAT LOCAL: Default to XOPEN_MODE. */
#define _XOPEN_MODE
/* Most routines need to check whether a float is finite, infinite, or not a
number, and many need to know whether the result of an operation will
overflow. These conditions depend on whether the largest exponent is
used for NaNs & infinities, or whether it's used for finite numbers. The
macros below wrap up that kind of information:
FLT_UWORD_IS_FINITE(X)
True if a positive float with bitmask X is finite.
FLT_UWORD_IS_NAN(X)
True if a positive float with bitmask X is not a number.
FLT_UWORD_IS_INFINITE(X)
True if a positive float with bitmask X is +infinity.
FLT_UWORD_MAX
The bitmask of FLT_MAX.
FLT_UWORD_HALF_MAX
The bitmask of FLT_MAX/2.
FLT_UWORD_EXP_MAX
The bitmask of the largest finite exponent (129 if the largest
exponent is used for finite numbers, 128 otherwise).
FLT_UWORD_LOG_MAX
The bitmask of log(FLT_MAX), rounded down. This value is the largest
input that can be passed to exp() without producing overflow.
FLT_UWORD_LOG_2MAX
The bitmask of log(2*FLT_MAX), rounded down. This value is the
largest input than can be passed to cosh() without producing
overflow.
FLT_LARGEST_EXP
The largest biased exponent that can be used for finite numbers
(255 if the largest exponent is used for finite numbers, 254
otherwise) */
#ifdef _FLT_LARGEST_EXPONENT_IS_NORMAL
#define FLT_UWORD_IS_FINITE(x) 1
#define FLT_UWORD_IS_NAN(x) 0
#define FLT_UWORD_IS_INFINITE(x) 0
#define FLT_UWORD_MAX 0x7fffffff
#define FLT_UWORD_EXP_MAX 0x43010000
#define FLT_UWORD_LOG_MAX 0x42b2d4fc
#define FLT_UWORD_LOG_2MAX 0x42b437e0
#define HUGE ((float)0X1.FFFFFEP128)
#else
#define FLT_UWORD_IS_FINITE(x) ((x)<0x7f800000L)
#define FLT_UWORD_IS_NAN(x) ((x)>0x7f800000L)
#define FLT_UWORD_IS_INFINITE(x) ((x)==0x7f800000L)
#define FLT_UWORD_MAX 0x7f7fffffL
#define FLT_UWORD_EXP_MAX 0x43000000
#define FLT_UWORD_LOG_MAX 0x42b17217
#define FLT_UWORD_LOG_2MAX 0x42b2d4fc
#define HUGE ((float)3.40282346638528860e+38)
#endif
#define FLT_UWORD_HALF_MAX (FLT_UWORD_MAX-(1L<<23))
#define FLT_LARGEST_EXP (FLT_UWORD_MAX>>23)
/* Many routines check for zero and subnormal numbers. Such things depend
on whether the target supports denormals or not:
FLT_UWORD_IS_ZERO(X)
True if a positive float with bitmask X is +0. Without denormals,
any float with a zero exponent is a +0 representation. With
denormals, the only +0 representation is a 0 bitmask.
FLT_UWORD_IS_SUBNORMAL(X)
True if a non-zero positive float with bitmask X is subnormal.
(Routines should check for zeros first.)
FLT_UWORD_MIN
The bitmask of the smallest float above +0. Call this number
REAL_FLT_MIN...
FLT_UWORD_EXP_MIN
The bitmask of the float representation of REAL_FLT_MIN's exponent.
FLT_UWORD_LOG_MIN
The bitmask of |log(REAL_FLT_MIN)|, rounding down.
FLT_SMALLEST_EXP
REAL_FLT_MIN's exponent - EXP_BIAS (1 if denormals are not supported,
-22 if they are).
*/
#ifdef _FLT_NO_DENORMALS
#define FLT_UWORD_IS_ZERO(x) ((x)<0x00800000L)
#define FLT_UWORD_IS_SUBNORMAL(x) 0
#define FLT_UWORD_MIN 0x00800000
#define FLT_UWORD_EXP_MIN 0x42fc0000
#define FLT_UWORD_LOG_MIN 0x42aeac50
#define FLT_SMALLEST_EXP 1
#else
#define FLT_UWORD_IS_ZERO(x) ((x)==0)
#define FLT_UWORD_IS_SUBNORMAL(x) ((x)<0x00800000L)
#define FLT_UWORD_MIN 0x00000001
#define FLT_UWORD_EXP_MIN 0x43160000
#define FLT_UWORD_LOG_MIN 0x42cff1b5
#define FLT_SMALLEST_EXP -22
#endif
#ifdef __STDC__
#undef __P
#define __P(p) p
#else
#define __P(p) ()
#endif
/*
* set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
* (one may replace the following line by "#include <values.h>")
*/
#define X_TLOSS 1.41484755040568800000e+16
/* Functions that are not documented, and are not in <math.h>. */
extern double logb __P((double));
#ifdef _SCALB_INT
extern double scalb __P((double, int));
#else
extern double scalb __P((double, double));
#endif
extern double significand __P((double));
/* ieee style elementary functions */
extern double __ieee754_sqrt __P((double));
extern double __ieee754_acos __P((double));
extern double __ieee754_acosh __P((double));
extern double __ieee754_log __P((double));
extern double __ieee754_atanh __P((double));
extern double __ieee754_asin __P((double));
extern double __ieee754_atan2 __P((double,double));
extern double __ieee754_exp __P((double));
extern double __ieee754_cosh __P((double));
extern double __ieee754_fmod __P((double,double));
extern double __ieee754_pow __P((double,double));
extern double __ieee754_lgamma_r __P((double,int *));
extern double __ieee754_gamma_r __P((double,int *));
extern double __ieee754_log10 __P((double));
extern double __ieee754_sinh __P((double));
extern double __ieee754_hypot __P((double,double));
extern double __ieee754_j0 __P((double));
extern double __ieee754_j1 __P((double));
extern double __ieee754_y0 __P((double));
extern double __ieee754_y1 __P((double));
extern double __ieee754_jn __P((int,double));
extern double __ieee754_yn __P((int,double));
extern double __ieee754_remainder __P((double,double));
extern __int32_t __ieee754_rem_pio2 __P((double,double*));
#ifdef _SCALB_INT
extern double __ieee754_scalb __P((double,int));
#else
extern double __ieee754_scalb __P((double,double));
#endif
/* fdlibm kernel function */
extern double __kernel_standard __P((double,double,int));
extern double __kernel_sin __P((double,double,int));
extern double __kernel_cos __P((double,double));
extern double __kernel_tan __P((double,double,int));
extern int __kernel_rem_pio2 __P((double*,double*,int,int,int,const __int32_t*));
/* Undocumented float functions. */
extern float logbf __P((float));
#ifdef _SCALB_INT
extern float scalbf __P((float, int));
#else
extern float scalbf __P((float, float));
#endif
extern float significandf __P((float));
/* ieee style elementary float functions */
extern float __ieee754_sqrtf __P((float));
extern float __ieee754_acosf __P((float));
extern float __ieee754_acoshf __P((float));
extern float __ieee754_logf __P((float));
extern float __ieee754_atanhf __P((float));
extern float __ieee754_asinf __P((float));
extern float __ieee754_atan2f __P((float,float));
extern float __ieee754_expf __P((float));
extern float __ieee754_coshf __P((float));
extern float __ieee754_fmodf __P((float,float));
extern float __ieee754_powf __P((float,float));
extern float __ieee754_lgammaf_r __P((float,int *));
extern float __ieee754_gammaf_r __P((float,int *));
extern float __ieee754_log10f __P((float));
extern float __ieee754_sinhf __P((float));
extern float __ieee754_hypotf __P((float,float));
extern float __ieee754_j0f __P((float));
extern float __ieee754_j1f __P((float));
extern float __ieee754_y0f __P((float));
extern float __ieee754_y1f __P((float));
extern float __ieee754_jnf __P((int,float));
extern float __ieee754_ynf __P((int,float));
extern float __ieee754_remainderf __P((float,float));
extern __int32_t __ieee754_rem_pio2f __P((float,float*));
#ifdef _SCALB_INT
extern float __ieee754_scalbf __P((float,int));
#else
extern float __ieee754_scalbf __P((float,float));
#endif
/* float versions of fdlibm kernel functions */
extern float __kernel_sinf __P((float,float,int));
extern float __kernel_cosf __P((float,float));
extern float __kernel_tanf __P((float,float,int));
extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const __int32_t*));
/* The original code used statements like
n0 = ((*(int*)&one)>>29)^1; * index of high word *
ix0 = *(n0+(int*)&x); * high word of x *
ix1 = *((1-n0)+(int*)&x); * low word of x *
to dig two 32 bit words out of the 64 bit IEEE floating point
value. That is non-ANSI, and, moreover, the gcc instruction
scheduler gets it wrong. We instead use the following macros.
Unlike the original code, we determine the endianness at compile
time, not at run time; I don't see much benefit to selecting
endianness at run time. */
#ifndef __IEEE_BIG_ENDIAN
#ifndef __IEEE_LITTLE_ENDIAN
#error Must define endianness
#endif
#endif
/* A union which permits us to convert between a double and two 32 bit
ints. */
#ifdef __IEEE_BIG_ENDIAN
typedef union
{
double value;
struct
{
__uint32_t msw;
__uint32_t lsw;
} parts;
} ieee_double_shape_type;
#endif
#ifdef __IEEE_LITTLE_ENDIAN
typedef union
{
double value;
struct
{
__uint32_t lsw;
__uint32_t msw;
} parts;
} ieee_double_shape_type;
#endif
/* Get two 32 bit ints from a double. */
#define EXTRACT_WORDS(ix0,ix1,d) \
do { \
ieee_double_shape_type ew_u; \
ew_u.value = (d); \
(ix0) = ew_u.parts.msw; \
(ix1) = ew_u.parts.lsw; \
} while (0)
/* Get the more significant 32 bit int from a double. */
#define GET_HIGH_WORD(i,d) \
do { \
ieee_double_shape_type gh_u; \
gh_u.value = (d); \
(i) = gh_u.parts.msw; \
} while (0)
/* Get the less significant 32 bit int from a double. */
#define GET_LOW_WORD(i,d) \
do { \
ieee_double_shape_type gl_u; \
gl_u.value = (d); \
(i) = gl_u.parts.lsw; \
} while (0)
/* Set a double from two 32 bit ints. */
#define INSERT_WORDS(d,ix0,ix1) \
do { \
ieee_double_shape_type iw_u; \
iw_u.parts.msw = (ix0); \
iw_u.parts.lsw = (ix1); \
(d) = iw_u.value; \
} while (0)
/* Set the more significant 32 bits of a double from an int. */
#define SET_HIGH_WORD(d,v) \
do { \
ieee_double_shape_type sh_u; \
sh_u.value = (d); \
sh_u.parts.msw = (v); \
(d) = sh_u.value; \
} while (0)
/* Set the less significant 32 bits of a double from an int. */
#define SET_LOW_WORD(d,v) \
do { \
ieee_double_shape_type sl_u; \
sl_u.value = (d); \
sl_u.parts.lsw = (v); \
(d) = sl_u.value; \
} while (0)
/* A union which permits us to convert between a float and a 32 bit
int. */
typedef union
{
float value;
__uint32_t word;
} ieee_float_shape_type;
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(i,d) \
do { \
ieee_float_shape_type gf_u; \
gf_u.value = (d); \
(i) = gf_u.word; \
} while (0)
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d,i) \
do { \
ieee_float_shape_type sf_u; \
sf_u.word = (i); \
(d) = sf_u.value; \
} while (0)

View File

@ -0,0 +1,33 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
*
*/
.file "floor.s"
.text
.align 4
.globl _floor
.def _floor; .scl 2; .type 32; .endef
_floor:
fldl 4(%esp)
subl $8,%esp
fstcw 4(%esp) /* store fpu control word */
/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
movl $0x400,%edx /* round towards -oo */
orl 4(%esp),%edx
andl $0xf7ff,%edx
movl %edx,(%esp)
fldcw (%esp) /* load modified control word */
frndint /* round */
fldcw 4(%esp) /* restore original control word */
addl $8,%esp
ret

View File

@ -0,0 +1,35 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
.file "floorf.S"
.text
.align 4
.globl _floorf
.def _floorf; .scl 2; .type 32; .endef
_floorf:
flds 4(%esp)
subl $8,%esp
fstcw 4(%esp) /* store fpu control word */
/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
movl $0x400,%edx /* round towards -oo */
orl 4(%esp),%edx
andl $0xf7ff,%edx
movl %edx,(%esp)
fldcw (%esp) /* load modified control word */
frndint /* round */
fldcw 4(%esp) /* restore original control word */
addl $8,%esp
ret

View File

@ -0,0 +1,33 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
*
*/
.file "floorl.S"
.text
.align 4
.globl _floorl
.def _floorl; .scl 2; .type 32; .endef
_floorl:
fldt 4(%esp)
subl $8,%esp
fstcw 4(%esp) /* store fpu control word */
/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
movl $0x400,%edx /* round towards -oo */
orl 4(%esp),%edx
andl $0xf7ff,%edx
movl %edx,(%esp)
fldcw (%esp) /* load modified control word */
frndint /* round */
fldcw 4(%esp) /* restore original control word */
addl $8,%esp
ret

View File

@ -0,0 +1,12 @@
.file "fma.S"
.text
.align 2
.p2align 4,,15
.globl _fma
.def _fma; .scl 2; .type 32; .endef
_fma:
fldl 4(%esp)
fmull 12(%esp)
fldl 20(%esp)
faddp
ret

View File

@ -0,0 +1,12 @@
.file "fmaf.S"
.text
.align 2
.p2align 4,,15
.globl _fmaf
.def _fmaf; .scl 2; .type 32; .endef
_fmaf:
flds 4(%esp)
fmuls 8(%esp)
flds 12(%esp)
faddp
ret

View File

@ -0,0 +1,5 @@
long double
fmal ( long double _x, long double _y, long double _z)
{
return ((_x * _y) + _z);
}

View File

@ -0,0 +1,7 @@
#include <math.h>
double
fmax (double _x, double _y)
{
return ( isgreaterequal (_x, _y)|| __isnan (_y) ? _x : _y );
}

View File

@ -0,0 +1,7 @@
#include <math.h>
float
fmaxf (float _x, float _y)
{
return (( isgreaterequal(_x, _y) || __isnanf (_y)) ? _x : _y );
}

View File

@ -0,0 +1,7 @@
#include <math.h>
long double
fmaxl (long double _x, long double _y)
{
return (( isgreaterequal(_x, _y) || __isnanl (_y)) ? _x : _y );
}

View File

@ -0,0 +1,7 @@
#include <math.h>
double
fmin (double _x, double _y)
{
return ((islessequal(_x, _y) || __isnan (_y)) ? _x : _y );
}

View File

@ -0,0 +1,7 @@
#include <math.h>
float
fminf (float _x, float _y)
{
return ((islessequal(_x, _y) || isnan (_y)) ? _x : _y );
}

View File

@ -0,0 +1,7 @@
#include <math.h>
long double
fminl (long double _x, long double _y)
{
return ((islessequal(_x, _y) || __isnanl (_y)) ? _x : _y );
}

View File

@ -0,0 +1,37 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for float type by Danny Smith
* <dannysmith@users.sourceforge.net>.
*/
#include <math.h>
float
fmodf (float x, float y)
{
float res;
asm ("1:\tfprem\n\t"
"fstsw %%ax\n\t"
"sahf\n\t"
"jp 1b\n\t"
"fstp %%st(1)"
: "=t" (res) : "0" (x), "u" (y) : "ax", "st(1)");
return res;
}
double
fmod (double x, double y)
{
float res;
asm ("1:\tfprem\n\t"
"fstsw %%ax\n\t"
"sahf\n\t"
"jp 1b\n\t"
"fstp %%st(1)"
: "=t" (res) : "0" (x), "u" (y) : "ax", "st(1)");
return res;
}

View File

@ -0,0 +1,22 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
*/
#include <math.h>
long double
fmodl (long double x, long double y)
{
long double res;
asm ("1:\tfprem\n\t"
"fstsw %%ax\n\t"
"sahf\n\t"
"jp 1b\n\t"
"fstp %%st(1)"
: "=t" (res) : "0" (x), "u" (y) : "ax", "st(1)");
return res;
}

View File

@ -0,0 +1,14 @@
#include "fp_consts.h"
const union _ieee_rep __QNAN = { __DOUBLE_QNAN_REP };
const union _ieee_rep __SNAN = { __DOUBLE_SNAN_REP };
const union _ieee_rep __INF = { __DOUBLE_INF_REP };
const union _ieee_rep __DENORM = { __DOUBLE_DENORM_REP };
/* ISO C99 */
#undef nan
/* FIXME */
double nan (const char * tagp __attribute__((unused)) )
{ return __QNAN.double_val; }

Some files were not shown because too many files have changed in this diff Show More