Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 1905 → Rev 1906

/programs/develop/libraries/newlib/Makefile
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
 
 
/programs/develop/libraries/newlib/argz/buf_findstr.c
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;
}
/programs/develop/libraries/newlib/argz/buf_findstr.h
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);
/programs/develop/libraries/newlib/argz/envz_get.c
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;
}
/programs/develop/libraries/newlib/argz
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property
/programs/develop/libraries/newlib/crt/assert.c
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 */
}
/programs/develop/libraries/newlib/crt/chkstk.S
4,7 → 4,6
 
.section .text
 
.align 4
___chkstk:
__alloca:
pushl %ecx /* save temp */
27,3 → 26,4
int3 #trap to debugger
.ascii "Stack overflow"
 
 
/programs/develop/libraries/newlib/crt/crt1.c
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
}
 
void __main (){};
 
 
void init_reent();
 
void __attribute__((noreturn))
73,11 → 74,26
_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
__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,6 → 129,7
*/
// _mingw32_init_fmode ();
 
 
nRet = main (_argc, _argv, NULL);
 
/*
119,7 → 136,7
* Perform exit processing for the C library. This means
* flushing output and calling 'atexit' registered functions.
*/
_exit (nRet);
exit (nRet);
}
 
 
/programs/develop/libraries/newlib/crt/crt_amz.S
0,0 → 1,15
 
.section .text
 
.global __start
.global ___main
 
.align 4
__start:
jmp _main
 
.align 4
___main:
ret
 
 
/programs/develop/libraries/newlib/crt/crtdll.c
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);
}
 
 
/programs/develop/libraries/newlib/crt/emutls.c
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;
}
/programs/develop/libraries/newlib/crt/exit.S
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
 
/programs/develop/libraries/newlib/crt/i386mach.h
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
 
/programs/develop/libraries/newlib/crt/pseudo-reloc.S
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
 
/programs/develop/libraries/newlib/crt/setjmp.S
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
/programs/develop/libraries/newlib/crt/start.S
2,8 → 2,6
.section .init
 
.global __start
.global __exit
.global __Exit
 
.align 4
__start:
20,21 → 18,30
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
/programs/develop/libraries/newlib/crt/tls.S
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
/programs/develop/libraries/newlib/ctype/isascii.c
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;
}
/programs/develop/libraries/newlib/ctype/isblank.c
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'));
}
/programs/develop/libraries/newlib/ctype/toascii.c
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;
}
 
/programs/develop/libraries/newlib/ctype/towctrans.c
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 */
/programs/develop/libraries/newlib/ctype/wctrans.c
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 */
/programs/develop/libraries/newlib/ctype/wctype.c
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 */
/programs/develop/libraries/newlib/dll.lds
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)
}
 
}
 
/programs/develop/libraries/newlib/include/gthr.h
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
/programs/develop/libraries/newlib/include/newlib.h
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_ */
/programs/develop/libraries/newlib/include/sys/lock.h
27,9 → 27,13
 
#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;
 
/programs/develop/libraries/newlib/include/sys/reent.h
822,19 → 822,17
 
/* #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
/programs/develop/libraries/newlib/libcdll.lds
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)
}
 
}
 
/programs/develop/libraries/newlib/locale/lctype.c
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);
}
/programs/develop/libraries/newlib/math/acosf.c
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;
}
/programs/develop/libraries/newlib/math/acosh.c
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)));
}
/programs/develop/libraries/newlib/math/acoshf.c
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)));
}
/programs/develop/libraries/newlib/math/acoshl.c
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)));
}
/programs/develop/libraries/newlib/math/acosl.c
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;
}
/programs/develop/libraries/newlib/math/asinf.c
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;
}
/programs/develop/libraries/newlib/math/asinh.c
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);
}
 
/programs/develop/libraries/newlib/math/asinhf.c
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);
}
/programs/develop/libraries/newlib/math/asinhl.c
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);
}
/programs/develop/libraries/newlib/math/asinl.c
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;
}
/programs/develop/libraries/newlib/math/atan2f.c
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;
}
/programs/develop/libraries/newlib/math/atan2l.c
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;
}
/programs/develop/libraries/newlib/math/atanf.c
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;
}
 
/programs/develop/libraries/newlib/math/atanh.c
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;
}
/programs/develop/libraries/newlib/math/atanhf.c
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;
}
/programs/develop/libraries/newlib/math/atanhl.c
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;
}
/programs/develop/libraries/newlib/math/atanl.c
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;
}
/programs/develop/libraries/newlib/math/cbrt.c
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);
}
/programs/develop/libraries/newlib/math/cbrtf.c
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);
}
/programs/develop/libraries/newlib/math/cbrtl.c
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);
}
/programs/develop/libraries/newlib/math/ceil.S
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
/programs/develop/libraries/newlib/math/ceilf.S
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
/programs/develop/libraries/newlib/math/ceill.S
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
/programs/develop/libraries/newlib/math/cephes_mconf.h
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 );
}
/programs/develop/libraries/newlib/math/copysign.S
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
/programs/develop/libraries/newlib/math/copysignf.S
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
/programs/develop/libraries/newlib/math/copysignl.S
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
/programs/develop/libraries/newlib/math/cos.S
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
/programs/develop/libraries/newlib/math/cosf.S
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
/programs/develop/libraries/newlib/math/coshf.c
0,0 → 1,3
#include <math.h>
float coshf (float x)
{return (float) cosh (x);}
/programs/develop/libraries/newlib/math/coshl.c
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 );
}
/programs/develop/libraries/newlib/math/cosl.S
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
/programs/develop/libraries/newlib/math/double.h
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 */
/programs/develop/libraries/newlib/math/e_atan2.c
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) */
/programs/develop/libraries/newlib/math/e_cosh.c
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;
}
 
/programs/develop/libraries/newlib/math/e_hypot.c
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) */
/programs/develop/libraries/newlib/math/e_sinh.c
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;
}
 
/programs/develop/libraries/newlib/math/e_sqrt.c
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).
*/
/programs/develop/libraries/newlib/math/erfl.c
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 );
}
/programs/develop/libraries/newlib/math/exp.S
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
/programs/develop/libraries/newlib/math/exp2.S
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
/programs/develop/libraries/newlib/math/exp2f.S
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
/programs/develop/libraries/newlib/math/exp2l.S
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
/programs/develop/libraries/newlib/math/expf.c
0,0 → 1,3
#include <math.h>
float expf (float x)
{return (float) exp (x);}
/programs/develop/libraries/newlib/math/expl.c
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);
}
/programs/develop/libraries/newlib/math/expm1.c
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;
}
/programs/develop/libraries/newlib/math/expm1f.c
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;
}
/programs/develop/libraries/newlib/math/expm1l.c
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;
}
/programs/develop/libraries/newlib/math/fabs.c
0,0 → 1,10
#include <math.h>
 
double
fabs (double x)
{
double res;
 
asm ("fabs;" : "=t" (res) : "0" (x));
return res;
}
/programs/develop/libraries/newlib/math/fabsf.c
0,0 → 1,9
#include <math.h>
 
float
fabsf (float x)
{
float res;
asm ("fabs;" : "=t" (res) : "0" (x));
return res;
}
/programs/develop/libraries/newlib/math/fabsl.c
0,0 → 1,9
#include <math.h>
 
long double
fabsl (long double x)
{
long double res;
asm ("fabs;" : "=t" (res) : "0" (x));
return res;
}
/programs/develop/libraries/newlib/math/fastmath.h
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
/programs/develop/libraries/newlib/math/fdim.c
0,0 → 1,7
#include <math.h>
 
double
fdim (double x, double y)
{
return (isgreater(x, y) ? (x - y) : 0.0);
}
/programs/develop/libraries/newlib/math/fdimf.c
0,0 → 1,7
#include <math.h>
 
float
fdimf (float x, float y)
{
return (isgreater(x, y) ? (x - y) : 0.0F);
}
/programs/develop/libraries/newlib/math/fdiml.c
0,0 → 1,7
#include <math.h>
 
long double
fdiml (long double x, long double y)
{
return (isgreater(x, y) ? (x - y) : 0.0L);
}
/programs/develop/libraries/newlib/math/fdlibm.h
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)
/programs/develop/libraries/newlib/math/floor.S
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
/programs/develop/libraries/newlib/math/floorf.S
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
/programs/develop/libraries/newlib/math/floorl.S
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
/programs/develop/libraries/newlib/math/fma.S
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
/programs/develop/libraries/newlib/math/fmaf.S
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
/programs/develop/libraries/newlib/math/fmal.c
0,0 → 1,5
long double
fmal ( long double _x, long double _y, long double _z)
{
return ((_x * _y) + _z);
}
/programs/develop/libraries/newlib/math/fmax.c
0,0 → 1,7
#include <math.h>
 
double
fmax (double _x, double _y)
{
return ( isgreaterequal (_x, _y)|| __isnan (_y) ? _x : _y );
}
/programs/develop/libraries/newlib/math/fmaxf.c
0,0 → 1,7
#include <math.h>
 
float
fmaxf (float _x, float _y)
{
return (( isgreaterequal(_x, _y) || __isnanf (_y)) ? _x : _y );
}
/programs/develop/libraries/newlib/math/fmaxl.c
0,0 → 1,7
#include <math.h>
 
long double
fmaxl (long double _x, long double _y)
{
return (( isgreaterequal(_x, _y) || __isnanl (_y)) ? _x : _y );
}
/programs/develop/libraries/newlib/math/fmin.c
0,0 → 1,7
#include <math.h>
 
double
fmin (double _x, double _y)
{
return ((islessequal(_x, _y) || __isnan (_y)) ? _x : _y );
}
/programs/develop/libraries/newlib/math/fminf.c
0,0 → 1,7
#include <math.h>
 
float
fminf (float _x, float _y)
{
return ((islessequal(_x, _y) || isnan (_y)) ? _x : _y );
}
/programs/develop/libraries/newlib/math/fminl.c
0,0 → 1,7
#include <math.h>
 
long double
fminl (long double _x, long double _y)
{
return ((islessequal(_x, _y) || __isnanl (_y)) ? _x : _y );
}
/programs/develop/libraries/newlib/math/fmodf.c
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;
}
/programs/develop/libraries/newlib/math/fmodl.c
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;
}
/programs/develop/libraries/newlib/math/fp_consts.c
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; }
 
 
/programs/develop/libraries/newlib/math/fp_consts.h
0,0 → 1,48
#ifndef _FP_CONSTS_H
#define _FP_CONSTS_H
 
/*
According to IEEE 754 a QNaN has exponent bits of all 1 values and
initial significand bit of 1. A SNaN has has an exponent of all 1
values and initial significand bit of 0 (with one or more other
significand bits of 1). An Inf has significand of 0 and
exponent of all 1 values. A denormal value has all exponent bits of 0.
 
The following does _not_ follow those rules, but uses values
equal to those exported from MS C++ runtime lib, msvcprt.dll
for float and double. MSVC however, does not have long doubles.
*/
 
 
#define __DOUBLE_INF_REP { 0, 0, 0, 0x7ff0 }
#define __DOUBLE_QNAN_REP { 0, 0, 0, 0xfff8 } /* { 0, 0, 0, 0x7ff8 } */
#define __DOUBLE_SNAN_REP { 0, 0, 0, 0xfff0 } /* { 1, 0, 0, 0x7ff0 } */
#define __DOUBLE_DENORM_REP {1, 0, 0, 0}
 
#define D_NAN_MASK 0x7ff0000000000000LL /* this will mask NaN's and Inf's */
 
#define __FLOAT_INF_REP { 0, 0x7f80 }
#define __FLOAT_QNAN_REP { 0, 0xffc0 } /* { 0, 0x7fc0 } */
#define __FLOAT_SNAN_REP { 0, 0xff80 } /* { 1, 0x7f80 } */
#define __FLOAT_DENORM_REP {1,0}
 
#define F_NAN_MASK 0x7f800000
 
/*
This assumes no implicit (hidden) bit in extended mode.
Padded to 96 bits
*/
#define __LONG_DOUBLE_INF_REP { 0, 0, 0, 0x8000, 0x7fff, 0 }
#define __LONG_DOUBLE_QNAN_REP { 0, 0, 0, 0xc000, 0xffff, 0 }
#define __LONG_DOUBLE_SNAN_REP { 0, 0, 0, 0x8000, 0xffff, 0 }
#define __LONG_DOUBLE_DENORM_REP {1, 0, 0, 0, 0, 0}
 
union _ieee_rep
{
unsigned short rep[6];
float float_val;
double double_val;
long double ldouble_val;
} ;
 
#endif
/programs/develop/libraries/newlib/math/fp_constsf.c
0,0 → 1,12
#include "fp_consts.h"
 
const union _ieee_rep __QNANF = { __FLOAT_QNAN_REP };
const union _ieee_rep __SNANF = { __FLOAT_SNAN_REP };
const union _ieee_rep __INFF = { __FLOAT_INF_REP };
const union _ieee_rep __DENORMF = { __FLOAT_DENORM_REP };
 
/* ISO C99 */
#undef nanf
/* FIXME */
float nanf(const char * tagp __attribute__((unused)) )
{ return __QNANF.float_val;}
/programs/develop/libraries/newlib/math/fp_constsl.c
0,0 → 1,12
#include "fp_consts.h"
 
const union _ieee_rep __QNANL = { __LONG_DOUBLE_QNAN_REP };
const union _ieee_rep __SNANL = { __LONG_DOUBLE_SNAN_REP };
const union _ieee_rep __INFL = { __LONG_DOUBLE_INF_REP };
const union _ieee_rep __DENORML = { __LONG_DOUBLE_DENORM_REP };
 
 
#undef nanl
/* FIXME */
long double nanl (const char * tagp __attribute__((unused)) )
{ return __QNANL.ldouble_val; }
/programs/develop/libraries/newlib/math/fpclassify.c
0,0 → 1,20
#include <math.h>
 
/* 'fxam' sets FPU flags C3,C2,C0 'fstsw' stores:
FP_NAN 001 0x0100
FP_NORMAL 010 0x0400
FP_INFINITE 011 0x0500
FP_ZERO 100 0x4000
FP_SUBNORMAL 110 0x4400
 
and sets C1 flag (signbit) if neg */
 
int __fpclassify (double _x){
unsigned short sw;
__asm__ (
"fxam; fstsw %%ax;"
: "=a" (sw)
: "t" (_x)
);
return sw & (FP_NAN | FP_NORMAL | FP_ZERO );
}
/programs/develop/libraries/newlib/math/fpclassifyf.c
0,0 → 1,10
#include <math.h>
int __fpclassifyf (float _x){
unsigned short sw;
__asm__ (
"fxam; fstsw %%ax;"
: "=a" (sw)
: "t" (_x)
);
return sw & (FP_NAN | FP_NORMAL | FP_ZERO );
}
/programs/develop/libraries/newlib/math/fpclassifyl.c
0,0 → 1,10
#include <math.h>
int __fpclassifyl (long double _x){
unsigned short sw;
__asm__ (
"fxam; fstsw %%ax;"
: "=a" (sw)
: "t" (_x)
);
return sw & (FP_NAN | FP_NORMAL | FP_ZERO );
}
/programs/develop/libraries/newlib/math/frexp.S
0,0 → 1,74
/* ix87 specific frexp implementation for double.
Copyright (C) 1997, 2000, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
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.
 
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, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
 
 
.file "frexp.s"
.text
 
.align 4
two54: .byte 0, 0, 0, 0, 0, 0, 0x50, 0x43
 
.p2align 4,,15
 
.globl _frexp
.def _frexp; .scl 2; .type 32; .endef
 
_frexp:
 
movl 4(%esp), %ecx
movl 8(%esp), %eax
movl %eax, %edx
andl $0x7fffffff, %eax
orl %eax, %ecx
jz 1f
 
xorl %ecx, %ecx
cmpl $0x7ff00000, %eax
jae 1f
 
cmpl $0x00100000, %eax
jae 2f
 
fld 4(%esp)
 
fmull two54
movl $-54, %ecx
fstpl 4(%esp)
fwait
movl 8(%esp), %eax
movl %eax, %edx
andl $0x7fffffff, %eax
 
2:
shrl $20, %eax
andl $0x800fffff, %edx
subl $1022, %eax
orl $0x3fe00000, %edx
addl %eax, %ecx
movl %edx, 8(%esp)
 
/* Store %ecx in the variable pointed to by the second argument,
get the factor from the stack and return. */
1:
movl 12(%esp), %eax
fldl 4(%esp)
movl %ecx, (%eax)
 
ret
/programs/develop/libraries/newlib/math/frexpf.c
0,0 → 1,3
#include <math.h>
float frexpf (float x, int* expn)
{return (float)frexp(x, expn);}
/programs/develop/libraries/newlib/math/frexpl.S
0,0 → 1,71
/*
Cephes Math Library Release 2.7: May, 1998
Copyright 1984, 1987, 1988, 1992, 1998 by Stephen L. Moshier
 
Extracted from floorl.387 for use in libmingwex.a by
Danny Smith <dannysmith@users.sourceforge.net>
2002-06-20
*/
 
/*
* frexpl(long double x, int* expnt) extracts the exponent from x.
* It returns an integer power of two to expnt and the significand
* between 0.5 and 1 to y. Thus x = y * 2**expn.
*/
.align 2
.globl _frexpl
_frexpl:
pushl %ebp
movl %esp,%ebp
subl $24,%esp
pushl %esi
pushl %ebx
fldt 8(%ebp)
movl 20(%ebp),%ebx
fld %st(0)
fstpt -12(%ebp)
leal -4(%ebp),%ecx
movw -4(%ebp),%dx
andl $32767,%edx
jne L25
fldz
fucompp
fnstsw %ax
andb $68,%ah
xorb $64,%ah
jne L21
movl $0,(%ebx)
fldz
jmp L24
.align 2,0x90
.align 2,0x90
L21:
fldt -12(%ebp)
fadd %st(0),%st
fstpt -12(%ebp)
decl %edx
movw (%ecx),%si
andl $32767,%esi
jne L22
cmpl $-66,%edx
jg L21
L22:
addl %esi,%edx
jmp L19
.align 2,0x90
L25:
fstp %st(0)
L19:
addl $-16382,%edx
movl %edx,(%ebx)
movw (%ecx),%ax
andl $-32768,%eax
orl $16382,%eax
movw %ax,(%ecx)
fldt -12(%ebp)
L24:
leal -32(%ebp),%esp
popl %ebx
popl %esi
leave
ret
/programs/develop/libraries/newlib/math/fucom.c
0,0 → 1,11
int
__fp_unordered_compare (long double x, long double y){
unsigned short retval;
__asm__ (
"fucom %%st(1);"
"fnstsw;"
: "=a" (retval)
: "t" (x), "u" (y)
);
return retval;
}
/programs/develop/libraries/newlib/math/hypotf.c
0,0 → 1,75
#include <math.h>
#include "fdlibm.h"
 
float hypotf (float x, float y)
{
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 = 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 = 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;
}
/programs/develop/libraries/newlib/math/hypotl.c
0,0 → 1,73
#include <math.h>
#include <float.h>
#include <errno.h>
 
/*
This implementation is based largely on Cephes library
function cabsl (cmplxl.c), which bears the following notice:
 
Cephes Math Library Release 2.1: January, 1989
Copyright 1984, 1987, 1989 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
 
/*
Modified for use in libmingwex.a
02 Sept 2002 Danny Smith <dannysmith@users.sourceforege.net>
Calls to ldexpl replaced by logbl and calls to frexpl replaced
by scalbnl to avoid duplicated range checks.
*/
 
extern long double __INFL;
#define PRECL 32
 
long double
hypotl (long double x, long double y)
{
int exx;
int eyy;
int scale;
long double xx =fabsl(x);
long double yy =fabsl(y);
if (!isfinite(xx) || !isfinite(yy))
return xx + yy; /* Return INF or NAN. */
 
if (xx == 0.0L)
return yy;
if (yy == 0.0L)
return xx;
 
/* Get exponents */
exx = logbl (xx);
eyy = logbl (yy);
 
/* Check if large differences in scale */
scale = exx - eyy;
if ( scale > PRECL)
return xx;
if ( scale < -PRECL)
return yy;
 
/* Exponent of approximate geometric mean (x 2) */
scale = (exx + eyy) >> 1;
 
/* Rescale: Geometric mean is now about 2 */
x = scalbnl(xx, -scale);
y = scalbnl(yy, -scale);
 
xx = sqrtl(x * x + y * y);
 
/* Check for overflow and underflow */
exx = logbl(xx);
exx += scale;
if (exx > LDBL_MAX_EXP)
{
errno = ERANGE;
return __INFL;
}
if (exx < LDBL_MIN_EXP)
return 0.0L;
 
/* Undo scaling */
return (scalbnl (xx, scale));
}
/programs/develop/libraries/newlib/math/ilogb.S
0,0 → 1,37
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
 
 
.file "ilogb.S"
.text
.align 4
.globl _ilogb
.def _ilogb; .scl 2; .type 32; .endef
_ilogb:
 
fldl 4(%esp)
/* I added the following ugly construct because ilogb(+-Inf) is
required to return INT_MAX in ISO C99.
-- jakub@redhat.com. */
fxam /* Is NaN or +-Inf? */
fstsw %ax
movb $0x45, %dh
andb %ah, %dh
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
 
fxtract
pushl %eax
fstp %st
 
fistpl (%esp)
fwait
popl %eax
 
ret
 
1: fstp %st
movl $0x7fffffff, %eax
ret
/programs/develop/libraries/newlib/math/ilogbf.S
0,0 → 1,35
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
 
.file "ilogbf.S"
.text
.align 4
.globl _ilogbf
.def _ilogbf; .scl 2; .type 32; .endef
_ilogbf:
flds 4(%esp)
/* I added the following ugly construct because ilogb(+-Inf) is
required to return INT_MAX in ISO C99.
-- jakub@redhat.com. */
fxam /* Is NaN or +-Inf? */
fstsw %ax
movb $0x45, %dh
andb %ah, %dh
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
 
fxtract
pushl %eax
fstp %st
 
fistpl (%esp)
fwait
popl %eax
 
ret
 
1: fstp %st
movl $0x7fffffff, %eax
ret
/programs/develop/libraries/newlib/math/ilogbl.S
0,0 → 1,36
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
* Public domain.
*/
 
.file "ilogbl.S"
.text
.align 4
.globl _ilogbl
.def _ilogbl; .scl 2; .type 32; .endef
_ilogbl:
fldt 4(%esp)
/* I added the following ugly construct because ilogb(+-Inf) is
required to return INT_MAX in ISO C99.
-- jakub@redhat.com. */
fxam /* Is NaN or +-Inf? */
fstsw %ax
movb $0x45, %dh
andb %ah, %dh
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
 
fxtract
pushl %eax
fstp %st
 
fistpl (%esp)
fwait
popl %eax
 
ret
 
1: fstp %st
movl $0x7fffffff, %eax
ret
/programs/develop/libraries/newlib/math/isnan.c
0,0 → 1,14
#include <math.h>
 
int
__isnan (double _x)
{
unsigned short _sw;
__asm__ ("fxam;"
"fstsw %%ax": "=a" (_sw) : "t" (_x));
return (_sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
== FP_NAN;
}
 
#undef isnan
int __attribute__ ((alias ("__isnan"))) isnan (double);
/programs/develop/libraries/newlib/math/isnanf.c
0,0 → 1,12
#include <math.h>
int
__isnanf (float _x)
{
unsigned short _sw;
__asm__ ("fxam;"
"fstsw %%ax": "=a" (_sw) : "t" (_x) );
return (_sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
== FP_NAN;
}
 
int __attribute__ ((alias ("__isnanf"))) isnanf (float);
/programs/develop/libraries/newlib/math/isnanl.c
0,0 → 1,13
#include <math.h>
 
int
__isnanl (long double _x)
{
unsigned short _sw;
__asm__ ("fxam;"
"fstsw %%ax": "=a" (_sw) : "t" (_x));
return (_sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
== FP_NAN;
}
 
int __attribute__ ((alias ("__isnanl"))) isnanl (long double);
/programs/develop/libraries/newlib/math/ldexp.c
0,0 → 1,19
#include <math.h>
#include <errno.h>
 
double ldexp(double x, int expn)
{
double res;
if (!isfinite (x) || x == 0.0L)
return x;
 
__asm__ ("fscale"
: "=t" (res)
: "0" (x), "u" ((double) expn));
 
// if (!isfinite (res) || res == 0.0L)
// errno = ERANGE;
 
return res;
}
 
/programs/develop/libraries/newlib/math/ldexpf.c
0,0 → 1,3
#include <math.h>
float ldexpf (float x, int expn)
{return (float) ldexp (x, expn);}
/programs/develop/libraries/newlib/math/ldexpl.c
0,0 → 1,19
#include <math.h>
#include <errno.h>
long double ldexpl(long double x, int expn)
{
long double res;
if (!isfinite (x) || x == 0.0L)
return x;
 
__asm__ ("fscale"
: "=t" (res)
: "0" (x), "u" ((long double) expn));
 
if (!isfinite (res) || res == 0.0L)
errno = ERANGE;
 
return res;
}
 
/programs/develop/libraries/newlib/math/lgamma.c
0,0 → 1,369
/* lgam()
*
* Natural logarithm of gamma function
*
*
*
* SYNOPSIS:
*
* double x, y, __lgamma_r();
* int* sgngam;
* y = __lgamma_r( x, sgngam );
*
* double x, y, lgamma();
* y = lgamma( x);
*
*
*
* DESCRIPTION:
*
* Returns the base e (2.718...) logarithm of the absolute
* value of the gamma function of the argument. In the reentrant
* version, the sign (+1 or -1) of the gamma function is returned
* in the variable referenced by sgngam.
*
* For arguments greater than 13, the logarithm of the gamma
* function is approximated by the logarithmic version of
* Stirling's formula using a polynomial approximation of
* degree 4. Arguments between -33 and +33 are reduced by
* recurrence to the interval [2,3] of a rational approximation.
* The cosecant reflection formula is employed for arguments
* less than -33.
*
* Arguments greater than MAXLGM return MAXNUM and an error
* message. MAXLGM = 2.035093e36 for DEC
* arithmetic or 2.556348e305 for IEEE arithmetic.
*
*
*
* ACCURACY:
*
*
* arithmetic domain # trials peak rms
* DEC 0, 3 7000 5.2e-17 1.3e-17
* DEC 2.718, 2.035e36 5000 3.9e-17 9.9e-18
* IEEE 0, 3 28000 5.4e-16 1.1e-16
* IEEE 2.718, 2.556e305 40000 3.5e-16 8.3e-17
* The error criterion was relative when the function magnitude
* was greater than one but absolute when it was less than one.
*
* The following test used the relative error criterion, though
* at certain points the relative error could be much higher than
* indicated.
* IEEE -200, -4 10000 4.8e-16 1.3e-16
*
*/
 
/*
* Cephes Math Library Release 2.8: June, 2000
* Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
*/
 
/*
* 26-11-2002 Modified for mingw.
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
 
#ifndef __MINGW32__
#include "mconf.h"
#ifdef ANSIPROT
extern double pow ( double, double );
extern double log ( double );
extern double exp ( double );
extern double sin ( double );
extern double polevl ( double, void *, int );
extern double p1evl ( double, void *, int );
extern double floor ( double );
extern double fabs ( double );
extern int isnan ( double );
extern int isfinite ( double );
#else
double pow(), log(), exp(), sin(), polevl(), p1evl(), floor(), fabs();
int isnan(), isfinite();
#endif
#ifdef INFINITIES
extern double INFINITY;
#endif
#ifdef NANS
extern double NAN;
#endif
#else /* __MINGW32__ */
#include "cephes_mconf.h"
#endif /* __MINGW32__ */
 
 
/* A[]: Stirling's formula expansion of log gamma
* B[], C[]: log gamma function between 2 and 3
*/
#ifdef UNK
static double A[] = {
8.11614167470508450300E-4,
-5.95061904284301438324E-4,
7.93650340457716943945E-4,
-2.77777777730099687205E-3,
8.33333333333331927722E-2
};
static double B[] = {
-1.37825152569120859100E3,
-3.88016315134637840924E4,
-3.31612992738871184744E5,
-1.16237097492762307383E6,
-1.72173700820839662146E6,
-8.53555664245765465627E5
};
static double C[] = {
/* 1.00000000000000000000E0, */
-3.51815701436523470549E2,
-1.70642106651881159223E4,
-2.20528590553854454839E5,
-1.13933444367982507207E6,
-2.53252307177582951285E6,
-2.01889141433532773231E6
};
/* log( sqrt( 2*pi ) ) */
static double LS2PI = 0.91893853320467274178;
#define MAXLGM 2.556348e305
static double LOGPI = 1.14472988584940017414;
#endif
 
#ifdef DEC
static const unsigned short A[] = {
0035524,0141201,0034633,0031405,
0135433,0176755,0126007,0045030,
0035520,0006371,0003342,0172730,
0136066,0005540,0132605,0026407,
0037252,0125252,0125252,0125132
};
static const unsigned short B[] = {
0142654,0044014,0077633,0035410,
0144027,0110641,0125335,0144760,
0144641,0165637,0142204,0047447,
0145215,0162027,0146246,0155211,
0145322,0026110,0010317,0110130,
0145120,0061472,0120300,0025363
};
static const unsigned short C[] = {
/*0040200,0000000,0000000,0000000*/
0142257,0164150,0163630,0112622,
0143605,0050153,0156116,0135272,
0144527,0056045,0145642,0062332,
0145213,0012063,0106250,0001025,
0145432,0111254,0044577,0115142,
0145366,0071133,0050217,0005122
};
/* log( sqrt( 2*pi ) ) */
static const unsigned short LS2P[] = {040153,037616,041445,0172645,};
#define LS2PI *(double *)LS2P
#define MAXLGM 2.035093e36
static const unsigned short LPI[4] = {
0040222,0103202,0043475,0006750,
};
#define LOGPI *(double *)LPI
 
#endif
 
#ifdef IBMPC
static const unsigned short A[] = {
0x6661,0x2733,0x9850,0x3f4a,
0xe943,0xb580,0x7fbd,0xbf43,
0x5ebb,0x20dc,0x019f,0x3f4a,
0xa5a1,0x16b0,0xc16c,0xbf66,
0x554b,0x5555,0x5555,0x3fb5
};
static const unsigned short B[] = {
0x6761,0x8ff3,0x8901,0xc095,
0xb93e,0x355b,0xf234,0xc0e2,
0x89e5,0xf890,0x3d73,0xc114,
0xdb51,0xf994,0xbc82,0xc131,
0xf20b,0x0219,0x4589,0xc13a,
0x055e,0x5418,0x0c67,0xc12a
};
static const unsigned short C[] = {
/*0x0000,0x0000,0x0000,0x3ff0,*/
0x12b2,0x1cf3,0xfd0d,0xc075,
0xd757,0x7b89,0xaa0d,0xc0d0,
0x4c9b,0xb974,0xeb84,0xc10a,
0x0043,0x7195,0x6286,0xc131,
0xf34c,0x892f,0x5255,0xc143,
0xe14a,0x6a11,0xce4b,0xc13e
};
/* log( sqrt( 2*pi ) ) */
static const union
{
unsigned short s[4];
double d;
} ls2p = {{0xbeb5,0xc864,0x67f1,0x3fed}};
#define LS2PI (ls2p.d)
#define MAXLGM 2.556348e305
/* log (pi) */
static const union
{
unsigned short s[4];
double d;
} lpi = {{0xa1bd,0x48e7,0x50d0,0x3ff2}};
#define LOGPI (lpi.d)
#endif
 
#ifdef MIEEE
static const unsigned short A[] = {
0x3f4a,0x9850,0x2733,0x6661,
0xbf43,0x7fbd,0xb580,0xe943,
0x3f4a,0x019f,0x20dc,0x5ebb,
0xbf66,0xc16c,0x16b0,0xa5a1,
0x3fb5,0x5555,0x5555,0x554b
};
static const unsigned short B[] = {
0xc095,0x8901,0x8ff3,0x6761,
0xc0e2,0xf234,0x355b,0xb93e,
0xc114,0x3d73,0xf890,0x89e5,
0xc131,0xbc82,0xf994,0xdb51,
0xc13a,0x4589,0x0219,0xf20b,
0xc12a,0x0c67,0x5418,0x055e
};
static const unsigned short C[] = {
0xc075,0xfd0d,0x1cf3,0x12b2,
0xc0d0,0xaa0d,0x7b89,0xd757,
0xc10a,0xeb84,0xb974,0x4c9b,
0xc131,0x6286,0x7195,0x0043,
0xc143,0x5255,0x892f,0xf34c,
0xc13e,0xce4b,0x6a11,0xe14a
};
/* log( sqrt( 2*pi ) ) */
static const union
{
unsigned short s[4];
double d;
} ls2p = {{0x3fed,0x67f1,0xc864,0xbeb5}};
#define LS2PI ls2p.d
#define MAXLGM 2.556348e305
/* log (pi) */
static const union
{
unsigned short s[4];
double d;
} lpi = {{0x3ff2, 0x50d0, 0x48e7, 0xa1bd}};
#define LOGPI (lpi.d)
#endif
 
 
/* Logarithm of gamma function */
/* Reentrant version */
 
double __lgamma_r(double x, int* sgngam)
{
double p, q, u, w, z;
int i;
 
*sgngam = 1;
#ifdef NANS
if( isnan(x) )
return(x);
#endif
 
#ifdef INFINITIES
if( !isfinite(x) )
return(INFINITY);
#endif
 
if( x < -34.0 )
{
q = -x;
w = __lgamma_r(q, sgngam); /* note this modifies sgngam! */
p = floor(q);
if( p == q )
{
lgsing:
_SET_ERRNO(EDOM);
mtherr( "lgam", SING );
#ifdef INFINITIES
return (INFINITY);
#else
return (MAXNUM);
#endif
}
i = p;
if( (i & 1) == 0 )
*sgngam = -1;
else
*sgngam = 1;
z = q - p;
if( z > 0.5 )
{
p += 1.0;
z = p - q;
}
z = q * sin( PI * z );
if( z == 0.0 )
goto lgsing;
/* z = log(PI) - log( z ) - w;*/
z = LOGPI - log( z ) - w;
return( z );
}
 
if( x < 13.0 )
{
z = 1.0;
p = 0.0;
u = x;
while( u >= 3.0 )
{
p -= 1.0;
u = x + p;
z *= u;
}
while( u < 2.0 )
{
if( u == 0.0 )
goto lgsing;
z /= u;
p += 1.0;
u = x + p;
}
if( z < 0.0 )
{
*sgngam = -1;
z = -z;
}
else
*sgngam = 1;
if( u == 2.0 )
return( log(z) );
p -= 2.0;
x = x + p;
p = x * polevl( x, B, 5 ) / p1evl( x, C, 6);
return( log(z) + p );
}
 
if( x > MAXLGM )
{
_SET_ERRNO(ERANGE);
mtherr( "lgamma", OVERFLOW );
#ifdef INFINITIES
return( *sgngam * INFINITY );
#else
return( *sgngam * MAXNUM );
#endif
}
 
q = ( x - 0.5 ) * log(x) - x + LS2PI;
if( x > 1.0e8 )
return( q );
 
p = 1.0/(x*x);
if( x >= 1000.0 )
q += (( 7.9365079365079365079365e-4 * p
- 2.7777777777777777777778e-3) *p
+ 0.0833333333333333333333) / x;
else
q += polevl( p, A, 4 ) / x;
return( q );
}
 
/* This is the C99 version */
 
double lgamma(double x)
{
int local_sgngam=0;
return (__lgamma_r(x, &local_sgngam));
}
/programs/develop/libraries/newlib/math/lgammaf.c
0,0 → 1,253
/* lgamf()
*
* Natural logarithm of gamma function
*
*
*
* SYNOPSIS:
*
* float x, y, __lgammaf_r();
* int* sgngamf;
* y = __lgammaf_r( x, sgngamf );
*
* float x, y, lgammaf();
* y = lgammaf( x);
*
*
*
* DESCRIPTION:
*
* Returns the base e (2.718...) logarithm of the absolute
* value of the gamma function of the argument. In the reentrant
* version the sign (+1 or -1) of the gamma function is returned in
* variable referenced by sgngamf.
*
* For arguments greater than 6.5, the logarithm of the gamma
* function is approximated by the logarithmic version of
* Stirling's formula. Arguments between 0 and +6.5 are reduced by
* by recurrence to the interval [.75,1.25] or [1.5,2.5] of a rational
* approximation. The cosecant reflection formula is employed for
* arguments less than zero.
*
* Arguments greater than MAXLGM = 2.035093e36 return MAXNUM and an
* error message.
*
*
*
* ACCURACY:
*
*
*
* arithmetic domain # trials peak rms
* IEEE -100,+100 500,000 7.4e-7 6.8e-8
* The error criterion was relative when the function magnitude
* was greater than one but absolute when it was less than one.
* The routine has low relative error for positive arguments.
*
* The following test used the relative error criterion.
* IEEE -2, +3 100000 4.0e-7 5.6e-8
*
*/
 
 
/*
Cephes Math Library Release 2.7: July, 1998
Copyright 1984, 1987, 1989, 1992, 1998 by Stephen L. Moshier
*/
 
/*
26-11-2002 Modified for mingw.
Danny Smith <dannysmith@users.sourceforge.net>
*/
 
 
/* log gamma(x+2), -.5 < x < .5 */
static const float B[] = {
6.055172732649237E-004,
-1.311620815545743E-003,
2.863437556468661E-003,
-7.366775108654962E-003,
2.058355474821512E-002,
-6.735323259371034E-002,
3.224669577325661E-001,
4.227843421859038E-001
};
 
/* log gamma(x+1), -.25 < x < .25 */
static const float C[] = {
1.369488127325832E-001,
-1.590086327657347E-001,
1.692415923504637E-001,
-2.067882815621965E-001,
2.705806208275915E-001,
-4.006931650563372E-001,
8.224670749082976E-001,
-5.772156501719101E-001
};
 
/* log( sqrt( 2*pi ) ) */
static const float LS2PI = 0.91893853320467274178;
#define MAXLGM 2.035093e36
static const float PIINV = 0.318309886183790671538;
 
#ifndef __MINGW32__
#include "mconf.h"
float floorf(float);
float polevlf( float, float *, int );
float p1evlf( float, float *, int );
#else
#include "cephes_mconf.h"
#endif
 
/* Reentrant version */
/* Logarithm of gamma function */
 
float __lgammaf_r( float x, int* sgngamf )
{
float p, q, w, z;
float nx, tx;
int i, direction;
 
*sgngamf = 1;
#ifdef NANS
if( isnan(x) )
return(x);
#endif
 
#ifdef INFINITIES
if( !isfinite(x) )
return(x);
#endif
 
 
if( x < 0.0 )
{
q = -x;
w = __lgammaf_r(q, sgngamf); /* note this modifies sgngam! */
p = floorf(q);
if( p == q )
{
lgsing:
_SET_ERRNO(EDOM);
mtherr( "lgamf", SING );
#ifdef INFINITIES
return (INFINITYF);
#else
return( *sgngamf * MAXNUMF );
#endif
}
i = p;
if( (i & 1) == 0 )
*sgngamf = -1;
else
*sgngamf = 1;
z = q - p;
if( z > 0.5 )
{
p += 1.0;
z = p - q;
}
z = q * sinf( PIF * z );
if( z == 0.0 )
goto lgsing;
z = -logf( PIINV*z ) - w;
return( z );
}
 
if( x < 6.5 )
{
direction = 0;
z = 1.0;
tx = x;
nx = 0.0;
if( x >= 1.5 )
{
while( tx > 2.5 )
{
nx -= 1.0;
tx = x + nx;
z *=tx;
}
x += nx - 2.0;
iv1r5:
p = x * polevlf( x, B, 7 );
goto cont;
}
if( x >= 1.25 )
{
z *= x;
x -= 1.0; /* x + 1 - 2 */
direction = 1;
goto iv1r5;
}
if( x >= 0.75 )
{
x -= 1.0;
p = x * polevlf( x, C, 7 );
q = 0.0;
goto contz;
}
while( tx < 1.5 )
{
if( tx == 0.0 )
goto lgsing;
z *=tx;
nx += 1.0;
tx = x + nx;
}
direction = 1;
x += nx - 2.0;
p = x * polevlf( x, B, 7 );
 
cont:
if( z < 0.0 )
{
*sgngamf = -1;
z = -z;
}
else
{
*sgngamf = 1;
}
q = logf(z);
if( direction )
q = -q;
contz:
return( p + q );
}
 
if( x > MAXLGM )
{
_SET_ERRNO(ERANGE);
mtherr( "lgamf", OVERFLOW );
#ifdef INFINITIES
return( *sgngamf * INFINITYF );
#else
return( *sgngamf * MAXNUMF );
#endif
 
}
 
/* Note, though an asymptotic formula could be used for x >= 3,
* there is cancellation error in the following if x < 6.5. */
q = LS2PI - x;
q += ( x - 0.5 ) * logf(x);
 
if( x <= 1.0e4 )
{
z = 1.0/x;
p = z * z;
q += (( 6.789774945028216E-004 * p
- 2.769887652139868E-003 ) * p
+ 8.333316229807355E-002 ) * z;
}
return( q );
}
 
/* This is the C99 version */
 
float lgammaf(float x)
{
int local_sgngamf=0;
return (__lgammaf_r(x, &local_sgngamf));
}
/programs/develop/libraries/newlib/math/lgammal.c
0,0 → 1,416
/* lgaml()
*
* Natural logarithm of gamma function
*
*
*
* SYNOPSIS:
*
* long double x, y, __lgammal_r();
* int* sgngaml;
* y = __lgammal_r( x, sgngaml );
*
* long double x, y, lgammal();
* y = lgammal( x);
*
*
*
* DESCRIPTION:
*
* Returns the base e (2.718...) logarithm of the absolute
* value of the gamma function of the argument. In the reentrant
* version, the sign (+1 or -1) of the gamma function is returned
* in the variable referenced by sgngaml.
*
* For arguments greater than 33, the logarithm of the gamma
* function is approximated by the logarithmic version of
* Stirling's formula using a polynomial approximation of
* degree 4. Arguments between -33 and +33 are reduced by
* recurrence to the interval [2,3] of a rational approximation.
* The cosecant reflection formula is employed for arguments
* less than -33.
*
* Arguments greater than MAXLGML (10^4928) return MAXNUML.
*
*
*
* ACCURACY:
*
*
* arithmetic domain # trials peak rms
* IEEE -40, 40 100000 2.2e-19 4.6e-20
* IEEE 10^-2000,10^+2000 20000 1.6e-19 3.3e-20
* The error criterion was relative when the function magnitude
* was greater than one but absolute when it was less than one.
*
*/
 
/*
* Copyright 1994 by Stephen L. Moshier
*/
 
/*
* 26-11-2002 Modified for mingw.
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
#ifndef __MINGW32__
#include "mconf.h"
#ifdef ANSIPROT
extern long double fabsl ( long double );
extern long double lgaml ( long double );
extern long double logl ( long double );
extern long double expl ( long double );
extern long double gammal ( long double );
extern long double sinl ( long double );
extern long double floorl ( long double );
extern long double powl ( long double, long double );
extern long double polevll ( long double, void *, int );
extern long double p1evll ( long double, void *, int );
extern int isnanl ( long double );
extern int isfinitel ( long double );
#else
long double fabsl(), lgaml(), logl(), expl(), gammal(), sinl();
long double floorl(), powl(), polevll(), p1evll(), isnanl(), isfinitel();
#endif
#ifdef INFINITIES
extern long double INFINITYL;
#endif
#ifdef NANS
extern long double NANL;
#endif
#else /* __MINGW32__ */
#include "cephes_mconf.h"
#endif /* __MINGW32__ */
 
#if UNK
static long double S[9] = {
-1.193945051381510095614E-3L,
7.220599478036909672331E-3L,
-9.622023360406271645744E-3L,
-4.219773360705915470089E-2L,
1.665386113720805206758E-1L,
-4.200263503403344054473E-2L,
-6.558780715202540684668E-1L,
5.772156649015328608253E-1L,
1.000000000000000000000E0L,
};
#endif
#if IBMPC
static const unsigned short S[] = {
0xbaeb,0xd6d3,0x25e5,0x9c7e,0xbff5, XPD
0xfe9a,0xceb4,0xc74e,0xec9a,0x3ff7, XPD
0x9225,0xdfef,0xb0e9,0x9da5,0xbff8, XPD
0x10b0,0xec17,0x87dc,0xacd7,0xbffa, XPD
0x6b8d,0x7515,0x1905,0xaa89,0x3ffc, XPD
0xf183,0x126b,0xf47d,0xac0a,0xbffa, XPD
0x7bf6,0x57d1,0xa013,0xa7e7,0xbffe, XPD
0xc7a9,0x7db0,0x67e3,0x93c4,0x3ffe, XPD
0x0000,0x0000,0x0000,0x8000,0x3fff, XPD
};
#endif
#if MIEEE
static long S[27] = {
0xbff50000,0x9c7e25e5,0xd6d3baeb,
0x3ff70000,0xec9ac74e,0xceb4fe9a,
0xbff80000,0x9da5b0e9,0xdfef9225,
0xbffa0000,0xacd787dc,0xec1710b0,
0x3ffc0000,0xaa891905,0x75156b8d,
0xbffa0000,0xac0af47d,0x126bf183,
0xbffe0000,0xa7e7a013,0x57d17bf6,
0x3ffe0000,0x93c467e3,0x7db0c7a9,
0x3fff0000,0x80000000,0x00000000,
};
#endif
 
#if UNK
static long double SN[9] = {
1.133374167243894382010E-3L,
7.220837261893170325704E-3L,
9.621911155035976733706E-3L,
-4.219773343731191721664E-2L,
-1.665386113944413519335E-1L,
-4.200263503402112910504E-2L,
6.558780715202536547116E-1L,
5.772156649015328608727E-1L,
-1.000000000000000000000E0L,
};
#endif
#if IBMPC
static const unsigned SN[] = {
0x5dd1,0x02de,0xb9f7,0x948d,0x3ff5, XPD
0x989b,0xdd68,0xc5f1,0xec9c,0x3ff7, XPD
0x2ca1,0x18f0,0x386f,0x9da5,0x3ff8, XPD
0x783f,0x41dd,0x87d1,0xacd7,0xbffa, XPD
0x7a5b,0xd76d,0x1905,0xaa89,0xbffc, XPD
0x7f64,0x1234,0xf47d,0xac0a,0xbffa, XPD
0x5e26,0x57d1,0xa013,0xa7e7,0x3ffe, XPD
0xc7aa,0x7db0,0x67e3,0x93c4,0x3ffe, XPD
0x0000,0x0000,0x0000,0x8000,0xbfff, XPD
};
#endif
#if MIEEE
static long SN[27] = {
0x3ff50000,0x948db9f7,0x02de5dd1,
0x3ff70000,0xec9cc5f1,0xdd68989b,
0x3ff80000,0x9da5386f,0x18f02ca1,
0xbffa0000,0xacd787d1,0x41dd783f,
0xbffc0000,0xaa891905,0xd76d7a5b,
0xbffa0000,0xac0af47d,0x12347f64,
0x3ffe0000,0xa7e7a013,0x57d15e26,
0x3ffe0000,0x93c467e3,0x7db0c7aa,
0xbfff0000,0x80000000,0x00000000,
};
#endif
 
 
/* A[]: Stirling's formula expansion of log gamma
* B[], C[]: log gamma function between 2 and 3
*/
 
 
/* log gamma(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x A(1/x^2)
* x >= 8
* Peak relative error 1.51e-21
* Relative spread of error peaks 5.67e-21
*/
#if UNK
static long double A[7] = {
4.885026142432270781165E-3L,
-1.880801938119376907179E-3L,
8.412723297322498080632E-4L,
-5.952345851765688514613E-4L,
7.936507795855070755671E-4L,
-2.777777777750349603440E-3L,
8.333333333333331447505E-2L,
};
#endif
#if IBMPC
static const unsigned short A[] = {
0xd984,0xcc08,0x91c2,0xa012,0x3ff7, XPD
0x3d91,0x0304,0x3da1,0xf685,0xbff5, XPD
0x3bdc,0xaad1,0xd492,0xdc88,0x3ff4, XPD
0x8b20,0x9fce,0x844e,0x9c09,0xbff4, XPD
0xf8f2,0x30e5,0x0092,0xd00d,0x3ff4, XPD
0x4d88,0x03a8,0x60b6,0xb60b,0xbff6, XPD
0x9fcc,0xaaaa,0xaaaa,0xaaaa,0x3ffb, XPD
};
#endif
#if MIEEE
static long A[21] = {
0x3ff70000,0xa01291c2,0xcc08d984,
0xbff50000,0xf6853da1,0x03043d91,
0x3ff40000,0xdc88d492,0xaad13bdc,
0xbff40000,0x9c09844e,0x9fce8b20,
0x3ff40000,0xd00d0092,0x30e5f8f2,
0xbff60000,0xb60b60b6,0x03a84d88,
0x3ffb0000,0xaaaaaaaa,0xaaaa9fcc,
};
#endif
 
/* log gamma(x+2) = x B(x)/C(x)
* 0 <= x <= 1
* Peak relative error 7.16e-22
* Relative spread of error peaks 4.78e-20
*/
#if UNK
static long double B[7] = {
-2.163690827643812857640E3L,
-8.723871522843511459790E4L,
-1.104326814691464261197E6L,
-6.111225012005214299996E6L,
-1.625568062543700591014E7L,
-2.003937418103815175475E7L,
-8.875666783650703802159E6L,
};
static long double C[7] = {
/* 1.000000000000000000000E0L,*/
-5.139481484435370143617E2L,
-3.403570840534304670537E4L,
-6.227441164066219501697E5L,
-4.814940379411882186630E6L,
-1.785433287045078156959E7L,
-3.138646407656182662088E7L,
-2.099336717757895876142E7L,
};
#endif
#if IBMPC
static const unsigned short B[] = {
0x9557,0x4995,0x0da1,0x873b,0xc00a, XPD
0xfe44,0x9af8,0x5b8c,0xaa63,0xc00f, XPD
0x5aa8,0x7cf5,0x3684,0x86ce,0xc013, XPD
0x259a,0x258c,0xf206,0xba7f,0xc015, XPD
0xbe18,0x1ca3,0xc0a0,0xf80a,0xc016, XPD
0x168f,0x2c42,0x6717,0x98e3,0xc017, XPD
0x2051,0x9d55,0x92c8,0x876e,0xc016, XPD
};
static const unsigned short C[] = {
/*0x0000,0x0000,0x0000,0x8000,0x3fff, XPD*/
0xaa77,0xcf2f,0xae76,0x807c,0xc008, XPD
0xb280,0x0d74,0xb55a,0x84f3,0xc00e, XPD
0xa505,0xcd30,0x81dc,0x9809,0xc012, XPD
0x3369,0x4246,0xb8c2,0x92f0,0xc015, XPD
0x63cf,0x6aee,0xbe6f,0x8837,0xc017, XPD
0x26bb,0xccc7,0xb009,0xef75,0xc017, XPD
0x462b,0xbae8,0xab96,0xa02a,0xc017, XPD
};
#endif
#if MIEEE
static long B[21] = {
0xc00a0000,0x873b0da1,0x49959557,
0xc00f0000,0xaa635b8c,0x9af8fe44,
0xc0130000,0x86ce3684,0x7cf55aa8,
0xc0150000,0xba7ff206,0x258c259a,
0xc0160000,0xf80ac0a0,0x1ca3be18,
0xc0170000,0x98e36717,0x2c42168f,
0xc0160000,0x876e92c8,0x9d552051,
};
static long C[21] = {
/*0x3fff0000,0x80000000,0x00000000,*/
0xc0080000,0x807cae76,0xcf2faa77,
0xc00e0000,0x84f3b55a,0x0d74b280,
0xc0120000,0x980981dc,0xcd30a505,
0xc0150000,0x92f0b8c2,0x42463369,
0xc0170000,0x8837be6f,0x6aee63cf,
0xc0170000,0xef75b009,0xccc726bb,
0xc0170000,0xa02aab96,0xbae8462b,
};
#endif
 
/* log( sqrt( 2*pi ) ) */
static const long double LS2PI = 0.91893853320467274178L;
#define MAXLGM 1.04848146839019521116e+4928L
 
 
/* Logarithm of gamma function */
/* Reentrant version */
 
long double __lgammal_r(long double x, int* sgngaml)
{
long double p, q, w, z, f, nx;
int i;
 
*sgngaml = 1;
#ifdef NANS
if( isnanl(x) )
return(NANL);
#endif
#ifdef INFINITIES
if( !isfinitel(x) )
return(INFINITYL);
#endif
if( x < -34.0L )
{
q = -x;
w = __lgammal_r(q, sgngaml); /* note this modifies sgngam! */
p = floorl(q);
if( p == q )
{
lgsing:
_SET_ERRNO(EDOM);
mtherr( "lgammal", SING );
#ifdef INFINITIES
return (INFINITYL);
#else
return (MAXNUML);
#endif
}
i = p;
if( (i & 1) == 0 )
*sgngaml = -1;
else
*sgngaml = 1;
z = q - p;
if( z > 0.5L )
{
p += 1.0L;
z = p - q;
}
z = q * sinl( PIL * z );
if( z == 0.0L )
goto lgsing;
/* z = LOGPI - logl( z ) - w; */
z = logl( PIL/z ) - w;
return( z );
}
 
if( x < 13.0L )
{
z = 1.0L;
nx = floorl( x + 0.5L );
f = x - nx;
while( x >= 3.0L )
{
nx -= 1.0L;
x = nx + f;
z *= x;
}
while( x < 2.0L )
{
if( fabsl(x) <= 0.03125 )
goto lsmall;
z /= nx + f;
nx += 1.0L;
x = nx + f;
}
if( z < 0.0L )
{
*sgngaml = -1;
z = -z;
}
else
*sgngaml = 1;
if( x == 2.0L )
return( logl(z) );
x = (nx - 2.0L) + f;
p = x * polevll( x, B, 6 ) / p1evll( x, C, 7);
return( logl(z) + p );
}
 
if( x > MAXLGM )
{
_SET_ERRNO(ERANGE);
mtherr( "lgammal", OVERFLOW );
#ifdef INFINITIES
return( *sgngaml * INFINITYL );
#else
return( *sgngaml * MAXNUML );
#endif
}
 
q = ( x - 0.5L ) * logl(x) - x + LS2PI;
if( x > 1.0e10L )
return(q);
p = 1.0L/(x*x);
q += polevll( p, A, 6 ) / x;
return( q );
 
 
lsmall:
if( x == 0.0L )
goto lgsing;
if( x < 0.0L )
{
x = -x;
q = z / (x * polevll( x, SN, 8 ));
}
else
q = z / (x * polevll( x, S, 8 ));
if( q < 0.0L )
{
*sgngaml = -1;
q = -q;
}
else
*sgngaml = 1;
q = logl( q );
return(q);
}
 
/* This is the C99 version */
 
long double lgammal(long double x)
{
int local_sgngaml=0;
return (__lgammal_r(x, &local_sgngaml));
}
/programs/develop/libraries/newlib/math/llrint.c
0,0 → 1,10
#include <math.h>
 
long long llrint (double x)
{
long long retval;
__asm__ __volatile__ \
("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}
 
/programs/develop/libraries/newlib/math/llrintf.c
0,0 → 1,9
#include <math.h>
 
long long llrintf (float x)
{
long long retval;
__asm__ __volatile__ \
("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}
/programs/develop/libraries/newlib/math/llrintl.c
0,0 → 1,10
#include <math.h>
 
long long llrintl (long double x)
{
long long retval;
__asm__ __volatile__ \
("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}
 
/programs/develop/libraries/newlib/math/log.S
0,0 → 1,38
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*/
 
.file "log.s"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
 
.text
.align 4
.globl _log
.def _log; .scl 2; .type 32; .endef
_log:
fldln2 /* log(2) */
fldl 4(%esp) /* x : log(2) */
fld %st /* x : x : log(2) */
fsubl one /* x-1 : x : log(2) */
fld %st /* x-1 : x-1 : x : log(2) */
fabs /* |x-1| : x-1 : x : log(2) */
fcompl limit /* x-1 : x : log(2) */
fnstsw /* x-1 : x : log(2) */
andb $0x45, %ah
jz 2f
fstp %st(1) /* x-1 : log(2) */
fyl2xp1 /* log(x) */
ret
 
2: fstp %st(0) /* x : log(2) */
fyl2x /* log(x) */
ret
/programs/develop/libraries/newlib/math/log10.S
0,0 → 1,48
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*/
 
.file "log10.s"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
 
.text
.align 4
.globl _log10
.def _log10; .scl 2; .type 32; .endef
_log10:
fldlg2 /* log10(2) */
fldl 4(%esp) /* x : log10(2) */
fxam
fnstsw
fld %st /* x : x : log10(2) */
sahf
jc 3f /* in case x is NaN or ±Inf */
4: fsubl one /* x-1 : x : log10(2) */
fld %st /* x-1 : x-1 : x : log10(2) */
fabs /* |x-1| : x-1 : x : log10(2) */
fcompl limit /* x-1 : x : log10(2) */
fnstsw /* x-1 : x : log10(2) */
andb $0x45, %ah
jz 2f
fstp %st(1) /* x-1 : log10(2) */
fyl2xp1 /* log10(x) */
ret
 
2: fstp %st(0) /* x : log10(2) */
fyl2x /* log10(x) */
ret
 
3: jp 4b /* in case x is ±Inf */
fstp %st(1)
fstp %st(1)
ret
/programs/develop/libraries/newlib/math/log10f.S
0,0 → 1,48
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*/
 
.file "log10f.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
 
.text
.align 4
.globl _log10f
.def _log10f; .scl 2; .type 32; .endef
_log10f:
fldlg2 /* log10(2) */
flds 4(%esp) /* x : log10(2) */
fxam
fnstsw
fld %st /* x : x : log10(2) */
sahf
jc 3f /* in case x is NaN or ±Inf */
4: fsubl one /* x-1 : x : log10(2) */
fld %st /* x-1 : x-1 : x : log10(2) */
fabs /* |x-1| : x-1 : x : log10(2) */
fcompl limit /* x-1 : x : log10(2) */
fnstsw /* x-1 : x : log10(2) */
andb $0x45, %ah
jz 2f
fstp %st(1) /* x-1 : log10(2) */
fyl2xp1 /* log10(x) */
ret
 
2: fstp %st(0) /* x : log10(2) */
fyl2x /* log10(x) */
ret
 
3: jp 4b /* in case x is ±Inf */
fstp %st(1)
fstp %st(1)
ret
/programs/develop/libraries/newlib/math/log10l.S
0,0 → 1,52
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
.file "log10l.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
 
.text
.align 4
.globl _log10l
.def _log10l; .scl 2; .type 32; .endef
_log10l:
fldlg2 /* log10(2) */
fldt 4(%esp) /* x : log10(2) */
fxam
fnstsw
fld %st /* x : x : log10(2) */
sahf
jc 3f /* in case x is NaN or ±Inf */
4: fsubl one /* x-1 : x : log10(2) */
fld %st /* x-1 : x-1 : x : log10(2) */
fabs /* |x-1| : x-1 : x : log10(2) */
fcompl limit /* x-1 : x : log10(2) */
fnstsw /* x-1 : x : log10(2) */
andb $0x45, %ah
jz 2f
fstp %st(1) /* x-1 : log10(2) */
fyl2xp1 /* log10(x) */
ret
 
2: fstp %st(0) /* x : log10(2) */
fyl2x /* log10(x) */
ret
 
3: jp 4b /* in case x is ±Inf */
fstp %st(1)
fstp %st(1)
ret
/programs/develop/libraries/newlib/math/log1p.S
0,0 → 1,47
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
.file "log1p.S"
.text
.align 4
/* The fyl2xp1 can only be used for values in
-1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
0.29 is a safe value.
*/
limit: .double 0.29
one: .double 1.0
/*
* Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
* otherwise fyl2x with the needed extra computation.
*/
.globl _log1p;
.def _log1p; .scl 2; .type 32; .endef
_log1p:
fldln2
fldl 4(%esp)
fxam
fnstsw
fld %st
sahf
jc 3f /* in case x is NaN or ±Inf */
 
4: fabs
fcompl limit
fnstsw
sahf
jc 2f
faddl one
fyl2x
ret
 
2: fyl2xp1
ret
 
3: jp 4b /* in case x is ±Inf */
fstp %st(1)
fstp %st(1)
ret
/programs/develop/libraries/newlib/math/log1pf.S
0,0 → 1,47
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
.file "log1pf.S"
.text
.align 4
/* The fyl2xp1 can only be used for values in
-1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
0.29 is a safe value.
*/
limit: .float 0.29
one: .float 1.0
/*
* Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
* otherwise fyl2x with the needed extra computation.
*/
.globl _log1pf;
.def _log1pf; .scl 2; .type 32; .endef
_log1pf:
fldln2
flds 4(%esp)
fxam
fnstsw
fld %st
sahf
jc 3f /* in case x is NaN or ±Inf */
 
4: fabs
fcomps limit
fnstsw
sahf
jc 2f
fadds one
fyl2x
ret
 
2: fyl2xp1
ret
 
3: jp 4b /* in case x is ±Inf */
fstp %st(1)
fstp %st(1)
ret
/programs/develop/libraries/newlib/math/log1pl.S
0,0 → 1,54
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted 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 "log1pl.S"
.text
.align 4
/* The fyl2xp1 can only be used for values in
-1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
0.29 is a safe value.
*/
limit: .tfloat 0.29
/* Please note: we use a double value here. Since 1.0 has
an exact representation this does not effect the accuracy
but it helps to optimize the code. */
one: .double 1.0
 
/*
* Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
* otherwise fyl2x with the needed extra computation.
*/
.globl _log1pl;
.def _log1pl; .scl 2; .type 32; .endef
_log1pl:
fldln2
fldt 4(%esp)
fxam
fnstsw
fld %st
sahf
jc 3f /* in case x is NaN or ±Inf */
4:
fabs
fldt limit
fcompp
fnstsw
sahf
jnc 2f
faddl one
fyl2x
ret
 
2: fyl2xp1
ret
 
3: jp 4b /* in case x is ±Inf */
fstp %st(1)
fstp %st(1)
ret
/programs/develop/libraries/newlib/math/log2.S
0,0 → 1,51
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
* Public domain.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
.file "log2.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
 
.text
.align 4
.globl _log2
.def _log2; .scl 2; .type 32; .endef
_log2:
fldl one
fldl 4(%esp) /* x : 1 */
fxam
fnstsw
fld %st /* x : x : 1 */
sahf
jc 3f /* in case x is NaN or ±Inf */
4: fsub %st(2), %st /* x-1 : x : 1 */
fld %st /* x-1 : x-1 : x : 1 */
fabs /* |x-1| : x-1 : x : 1 */
fcompl limit /* x-1 : x : 1 */
fnstsw /* x-1 : x : 1 */
andb $0x45, %ah
jz 2f
fstp %st(1) /* x-1 : 1 */
fyl2xp1 /* log(x) */
ret
 
2: fstp %st(0) /* x : 1 */
fyl2x /* log(x) */
ret
 
3: jp 4b /* in case x is ±Inf */
fstp %st(1)
fstp %st(1)
ret
/programs/develop/libraries/newlib/math/log2f.S
0,0 → 1,51
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
* Public domain.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
.file "log2f.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
 
.text
.align 4
.globl _log2f
.def _log2f; .scl 2; .type 32; .endef
_log2f:
fldl one
flds 4(%esp) /* x : 1 */
fxam
fnstsw
fld %st /* x : x : 1 */
sahf
jc 3f /* in case x is NaN or ±Inf */
4: fsub %st(2), %st /* x-1 : x : 1 */
fld %st /* x-1 : x-1 : x : 1 */
fabs /* |x-1| : x-1 : x : 1 */
fcompl limit /* x-1 : x : 1 */
fnstsw /* x-1 : x : 1 */
andb $0x45, %ah
jz 2f
fstp %st(1) /* x-1 : 1 */
fyl2xp1 /* log(x) */
ret
 
2: fstp %st(0) /* x : 1 */
fyl2x /* log(x) */
ret
 
3: jp 4b /* in case x is ±Inf */
fstp %st(1)
fstp %st(1)
ret
/programs/develop/libraries/newlib/math/log2l.S
0,0 → 1,48
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
* Public domain.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*/
 
.file "log2l.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
 
.text
.align 4
.globl _log2l
.def _log2l; .scl 2; .type 32; .endef
_log2l:
fldl one
fldt 4(%esp) /* x : 1 */
fxam
fnstsw
fld %st /* x : x : 1 */
sahf
jc 3f /* in case x is NaN or ±Inf */
4: fsub %st(2), %st /* x-1 : x : 1 */
fld %st /* x-1 : x-1 : x : 1 */
fabs /* |x-1| : x-1 : x : 1 */
fcompl limit /* x-1 : x : 1 */
fnstsw /* x-1 : x : 1 */
andb $0x45, %ah
jz 2f
fstp %st(1) /* x-1 : 1 */
fyl2xp1 /* log(x) */
ret
 
2: fstp %st(0) /* x : 1 */
fyl2x /* log(x) */
ret
 
3: jp 4b /* in case x is ±Inf */
fstp %st(1)
fstp %st(1)
ret
/programs/develop/libraries/newlib/math/logb.c
0,0 → 1,16
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
* Public domain.
*/
 
#include <math.h>
 
double
logb (double x)
{
double res;
asm ("fxtract\n\t"
"fstp %%st" : "=t" (res) : "0" (x));
return res;
}
/programs/develop/libraries/newlib/math/logbf.c
0,0 → 1,16
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
* Public domain.
*/
 
#include <math.h>
 
float
logbf (float x)
{
float res;
asm ("fxtract\n\t"
"fstp %%st" : "=t" (res) : "0" (x));
return res;
}
/programs/develop/libraries/newlib/math/logbl.c
0,0 → 1,17
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
* Public domain.
*/
 
#include <math.h>
 
long double
logbl (long double x)
{
long double res;
 
asm ("fxtract\n\t"
"fstp %%st" : "=t" (res) : "0" (x));
return res;
}
/programs/develop/libraries/newlib/math/logf.S
0,0 → 1,39
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Adapted for float by Ulrich Drepper <drepper@cygnus.com>.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*/
 
.file "logf.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
 
.text
.align 4
.globl _logf
.def _logf; .scl 2; .type 32; .endef
_logf:
fldln2 /* log(2) */
flds 4(%esp) /* x : log(2) */
fld %st /* x : x : log(2) */
fsubl one /* x-1 : x : log(2) */
fld %st /* x-1 : x-1 : x : log(2) */
fabs /* |x-1| : x-1 : x : log(2) */
fcompl limit /* x-1 : x : log(2) */
fnstsw /* x-1 : x : log(2) */
andb $0x45, %ah
jz 2f
fstp %st(1) /* x-1 : log(2) */
fyl2xp1 /* log(x) */
ret
 
2: fstp %st(0) /* x : log(2) */
fyl2x /* log(x) */
ret
/programs/develop/libraries/newlib/math/logl.S
0,0 → 1,40
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted 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 "logl.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
 
.text
.align 4
.globl _logl
.def _logl; .scl 2; .type 32; .endef
_logl:
fldln2 /* log(2) */
fldt 4(%esp) /* x : log(2) */
fld %st /* x : x : log(2) */
fsubl one /* x-1 : x : log(2) */
fld %st /* x-1 : x-1 : x : log(2) */
fabs /* |x-1| : x-1 : x : log(2) */
fcompl limit /* x-1 : x : log(2) */
fnstsw /* x-1 : x : log(2) */
andb $0x45, %ah
jz 2f
fstp %st(1) /* x-1 : log(2) */
fyl2xp1 /* log(x) */
ret
 
2: fstp %st(0) /* x : log(2) */
fyl2x /* log(x) */
ret
/programs/develop/libraries/newlib/math/lrint.c
0,0 → 1,9
#include <math.h>
 
long lrint (double x)
{
long retval;
__asm__ __volatile__ \
("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}
/programs/develop/libraries/newlib/math/lrintf.c
0,0 → 1,9
#include <math.h>
 
long lrintf (float x)
{
long retval;
__asm__ __volatile__ \
("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}
/programs/develop/libraries/newlib/math/lrintl.c
0,0 → 1,10
#include <math.h>
 
long lrintl (long double x)
{
long retval;
__asm__ __volatile__ \
("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}
 
/programs/develop/libraries/newlib/math/lround_generic.c
0,0 → 1,64
/*
* lround_generic.c
*
* $Id: lround_generic.c,v 1.1 2008/06/03 18:42:21 keithmarshall Exp $
*
* Provides a generic implementation for the `lround()', `lroundf()',
* `lroundl()', `llround()', `llroundf()' and `llroundl()' functions;
* compile with `-D FUNCTION=name', with `name' set to each of these
* six in turn, to create separate object files for each of the six
* functions.
*
* Written by Keith Marshall <keithmarshall@users.sourceforge.net>
*
* This is free software. You may redistribute and/or modify it as you
* see fit, without restriction of copyright.
*
* This software is provided "as is", in the hope that it may be useful,
* but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of
* MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no
* time will the author accept any form of liability for any damages,
* however caused, resulting from the use of this software.
*
*/
#ifndef FUNCTION
/*
* Normally specified with `-D FUNCTION=name', on the command line.
* Valid FUNCTION names are `lround', `lroundf', `lroundl', `llround'
* `llroundf' and `llroundl'; specifying anything else will most likely
* cause a compilation error. If user did not specify an appropriate
* FUNCTION name, default to `lround'.
*/
#define FUNCTION lround
#endif
 
#include "round_internal.h"
 
#include <limits.h>
#include <errno.h>
 
/* Generic implementation.
* The user is required to specify the FUNCTION name;
* the RETURN_TYPE and INPUT_TYPE macros resolve to appropriate
* type declarations, to match the selected FUNCTION prototype,
* while RETURN_MAX and RETURN_MIN map to the correspondingly
* appropriate limits.h manifest values, to establish the
* valid range for the RETURN_TYPE.
*/
RETURN_TYPE FUNCTION( INPUT_TYPE x )
{
if( !isfinite( x ) || !isfinite( x = round_internal( x ) )
|| (x > MAX_RETURN_VALUE) || (x < MIN_RETURN_VALUE) )
/*
* Undefined behaviour...
* POSIX requires us to report a domain error; ANSI C99 says we
* _may_ report a range error, and previous MinGW implementation
* set `errno = ERANGE' here; we change that, conforming to the
* stricter requiremment of the POSIX standard.
*/
errno = EDOM;
 
return (RETURN_TYPE)(x);
}
 
/* $RCSfile: lround_generic.c,v $$Revision: 1.1 $: end of file */
/programs/develop/libraries/newlib/math/modff.c
0,0 → 1,22
#include <fenv.h>
#include <math.h>
#include <errno.h>
#define FE_ROUNDING_MASK \
(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
 
float
modff (float value, float* iptr)
{
float int_part;
unsigned short saved_cw;
unsigned short tmp_cw;
/* truncate */
asm ("fnstcw %0;" : "=m" (saved_cw)); /* save control word */
tmp_cw = (saved_cw & ~FE_ROUNDING_MASK) | FE_TOWARDZERO;
asm ("fldcw %0;" : : "m" (tmp_cw));
asm ("frndint;" : "=t" (int_part) : "0" (value)); /* round */
asm ("fldcw %0;" : : "m" (saved_cw)); /* restore saved cw */
if (iptr)
*iptr = int_part;
return (isinf (value) ? 0.0F : value - int_part);
}
/programs/develop/libraries/newlib/math/modfl.c
0,0 → 1,22
#include <fenv.h>
#include <math.h>
#include <errno.h>
#define FE_ROUNDING_MASK \
(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
 
long double
modfl (long double value, long double* iptr)
{
long double int_part;
unsigned short saved_cw;
unsigned short tmp_cw;
/* truncate */
asm ("fnstcw %0;" : "=m" (saved_cw)); /* save control word */
tmp_cw = (saved_cw & ~FE_ROUNDING_MASK) | FE_TOWARDZERO;
asm ("fldcw %0;" : : "m" (tmp_cw));
asm ("frndint;" : "=t" (int_part) : "0" (value)); /* round */
asm ("fldcw %0;" : : "m" (saved_cw)); /* restore saved cw */
if (iptr)
*iptr = int_part;
return (isinf (value) ? 0.0L : value - int_part);
}
/programs/develop/libraries/newlib/math/nearbyint.S
0,0 → 1,30
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for use as nearbyint by Ulrich Drepper <drepper@cygnus.com>.
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
.file "nearbyint.S"
.text
.align 4
.globl _nearbyint
.def _nearbyint; .scl 2; .type 32; .endef
_nearbyint:
fldl 4(%esp)
pushl %eax
pushl %ecx
fnstcw (%esp)
movl (%esp), %eax
orl $0x20, %eax
movl %eax, 4(%esp)
fldcw 4(%esp)
frndint
fclex
fldcw (%esp)
popl %ecx
popl %eax
ret
/programs/develop/libraries/newlib/math/nearbyintf.S
0,0 → 1,29
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Adapted for use as nearbyint by Ulrich Drepper <drepper@cygnus.com>.
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
.file "nearbyintf.S"
.text
.align 4
.globl _nearbyintf
.def _nearbyintf; .scl 2; .type 32; .endef
_nearbyintf:
flds 4(%esp)
pushl %eax
pushl %ecx
fnstcw (%esp)
movl (%esp), %eax
orl $0x20, %eax
movl %eax, 4(%esp)
fldcw 4(%esp)
frndint
fclex
fldcw (%esp)
popl %ecx
popl %eax
ret
/programs/develop/libraries/newlib/math/nearbyintl.S
0,0 → 1,30
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adaptedfor use as nearbyint by Ulrich Drepper <drepper@cygnus.com>.
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
.file "nearbyintl.S"
.text
.align 4
.globl _nearbyintl
.def _nearbyintl; .scl 2; .type 32; .endef
_nearbyintl:
fldt 4(%esp)
pushl %eax
pushl %ecx
fnstcw (%esp)
movl (%esp), %eax
orl $0x20, %eax
movl %eax, 4(%esp)
fldcw 4(%esp)
frndint
fclex
fldcw (%esp)
popl %ecx
popl %eax
ret
/programs/develop/libraries/newlib/math/nextafterf.c
0,0 → 1,27
#include <math.h>
 
float
nextafterf (float x, float y)
{
union
{
float f;
unsigned int i;
} u;
if (isnan (y) || isnan (x))
return x + y;
if (x == y )
/* nextafter (0.0, -O.0) should return -0.0. */
return y;
u.f = x;
if (x == 0.0F)
{
u.i = 1;
return y > 0.0F ? u.f : -u.f;
}
if (((x > 0.0F) ^ (y > x)) == 0)
u.i++;
else
u.i--;
return u.f;
}
/programs/develop/libraries/newlib/math/nextafterl.c
0,0 → 1,65
/*
nextafterl.c
Contributed by Danny Smith <dannysmith@users.sourceforge.net>
No copyright claimed, absolutely no warranties.
 
2005-05-09
*/
 
#include <math.h>
 
long double
nextafterl (long double x, long double y)
{
union {
long double ld;
struct {
unsigned long long mantissa;
unsigned short expn;
unsigned short pad;
} __attribute__ ((packed)) parts;
} u;
 
/* The normal bit is explicit for long doubles, unlike
float and double. */
static const unsigned long long normal_bit = 0x8000000000000000ull;
 
if (isnan (y) || isnan (x))
return x + y;
 
if (x == y )
/* nextafter (0.0, -O.0) should return -0.0. */
return y;
 
u.ld = x;
if (x == 0.0L)
{
u.parts.mantissa = 1ull;
return y > 0.0L ? u.ld : -u.ld;
}
 
if (((x > 0.0L) ^ (y > x)) == 0)
{
u.parts.mantissa++;
if ((u.parts.mantissa & ~normal_bit) == 0ull)
u.parts.expn++;
}
else
{
if ((u.parts.mantissa & ~normal_bit) == 0ull)
u.parts.expn--;
u.parts.mantissa--;
}
 
/* If we have updated the expn of a normal number,
or moved from denormal to normal, [re]set the normal bit. */
if (u.parts.expn & 0x7fff)
u.parts.mantissa |= normal_bit;
 
return u.ld;
}
 
/* nexttowardl is the same function with a different name. */
long double
nexttowardl (long double, long double) __attribute__ ((alias("nextafterl")));
/programs/develop/libraries/newlib/math/nexttoward.c
0,0 → 1,42
/*
nexttoward.c
Contributed by Danny Smith <dannysmith@users.sourceforge.net>
No copyright claimed, absolutely no warranties.
 
2005-05-10
*/
 
#include <math.h>
 
double
nexttoward (double x, long double y)
{
union
{
double d;
unsigned long long ll;
} u;
 
long double xx = x;
 
if (isnan (y) || isnan (x))
return x + y;
 
if (xx == y)
/* nextafter (0.0, -O.0) should return -0.0. */
return y;
u.d = x;
if (x == 0.0)
{
u.ll = 1;
return y > 0.0L ? u.d : -u.d;
}
 
/* Non-extended encodings are lexicographically ordered,
with implicit "normal" bit. */
if (((x > 0.0) ^ (y > xx)) == 0)
u.ll++;
else
u.ll--;
return u.d;
}
/programs/develop/libraries/newlib/math/nexttowardf.c
0,0 → 1,38
/*
nexttowardf.c
Contributed by Danny Smith <dannysmith@users.sourceforge.net>
No copyright claimed, absolutely no warranties.
 
2005-05-10
*/
 
#include <math.h>
 
float
nexttowardf (float x, long double y)
{
union
{
float f;
unsigned int i;
} u;
 
long double xx = x;
 
if (isnan (y) || isnan (x))
return x + y;
if (xx == y )
/* nextafter (0.0, -O.0) should return -0.0. */
return y;
u.f = x;
if (x == 0.0F)
{
u.i = 1;
return y > 0.0L ? u.f : -u.f;
}
if (((x > 0.0F) ^ (y > xx)) == 0)
u.i++;
else
u.i--;
return u.f;
}
/programs/develop/libraries/newlib/math/op-1.h
0,0 → 1,302
/* Software floating-point emulation.
Basic one-word fraction declaration and manipulation.
Copyright (C) 1997,1998,1999,2006 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. */
 
#define _FP_FRAC_DECL_1(X) _FP_W_TYPE X##_f
#define _FP_FRAC_COPY_1(D,S) (D##_f = S##_f)
#define _FP_FRAC_SET_1(X,I) (X##_f = I)
#define _FP_FRAC_HIGH_1(X) (X##_f)
#define _FP_FRAC_LOW_1(X) (X##_f)
#define _FP_FRAC_WORD_1(X,w) (X##_f)
 
#define _FP_FRAC_ADDI_1(X,I) (X##_f += I)
#define _FP_FRAC_SLL_1(X,N) \
do { \
if (__builtin_constant_p(N) && (N) == 1) \
X##_f += X##_f; \
else \
X##_f <<= (N); \
} while (0)
#define _FP_FRAC_SRL_1(X,N) (X##_f >>= N)
 
/* Right shift with sticky-lsb. */
#define _FP_FRAC_SRST_1(X,S,N,sz) __FP_FRAC_SRST_1(X##_f, S, N, sz)
#define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz)
 
#define __FP_FRAC_SRST_1(X,S,N,sz) \
do { \
S = (__builtin_constant_p(N) && (N) == 1 \
? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0); \
X = X >> (N); \
} while (0)
 
#define __FP_FRAC_SRS_1(X,N,sz) \
(X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1 \
? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0)))
 
#define _FP_FRAC_ADD_1(R,X,Y) (R##_f = X##_f + Y##_f)
#define _FP_FRAC_SUB_1(R,X,Y) (R##_f = X##_f - Y##_f)
#define _FP_FRAC_DEC_1(X,Y) (X##_f -= Y##_f)
#define _FP_FRAC_CLZ_1(z, X) __FP_CLZ(z, X##_f)
 
/* Predicates */
#define _FP_FRAC_NEGP_1(X) ((_FP_WS_TYPE)X##_f < 0)
#define _FP_FRAC_ZEROP_1(X) (X##_f == 0)
#define _FP_FRAC_OVERP_1(fs,X) (X##_f & _FP_OVERFLOW_##fs)
#define _FP_FRAC_CLEAR_OVERP_1(fs,X) (X##_f &= ~_FP_OVERFLOW_##fs)
#define _FP_FRAC_EQ_1(X, Y) (X##_f == Y##_f)
#define _FP_FRAC_GE_1(X, Y) (X##_f >= Y##_f)
#define _FP_FRAC_GT_1(X, Y) (X##_f > Y##_f)
 
#define _FP_ZEROFRAC_1 0
#define _FP_MINFRAC_1 1
#define _FP_MAXFRAC_1 (~(_FP_WS_TYPE)0)
 
/*
* Unpack the raw bits of a native fp value. Do not classify or
* normalize the data.
*/
 
#define _FP_UNPACK_RAW_1(fs, X, val) \
do { \
union _FP_UNION_##fs _flo; _flo.flt = (val); \
\
X##_f = _flo.bits.frac; \
X##_e = _flo.bits.exp; \
X##_s = _flo.bits.sign; \
} while (0)
 
#define _FP_UNPACK_RAW_1_P(fs, X, val) \
do { \
union _FP_UNION_##fs *_flo = \
(union _FP_UNION_##fs *)(val); \
\
X##_f = _flo->bits.frac; \
X##_e = _flo->bits.exp; \
X##_s = _flo->bits.sign; \
} while (0)
 
/*
* Repack the raw bits of a native fp value.
*/
 
#define _FP_PACK_RAW_1(fs, val, X) \
do { \
union _FP_UNION_##fs _flo; \
\
_flo.bits.frac = X##_f; \
_flo.bits.exp = X##_e; \
_flo.bits.sign = X##_s; \
\
(val) = _flo.flt; \
} while (0)
 
#define _FP_PACK_RAW_1_P(fs, val, X) \
do { \
union _FP_UNION_##fs *_flo = \
(union _FP_UNION_##fs *)(val); \
\
_flo->bits.frac = X##_f; \
_flo->bits.exp = X##_e; \
_flo->bits.sign = X##_s; \
} while (0)
 
 
/*
* Multiplication algorithms:
*/
 
/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the
multiplication immediately. */
 
#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y) \
do { \
R##_f = X##_f * Y##_f; \
/* Normalize since we know where the msb of the multiplicands \
were (bit B), we know that the msb of the of the product is \
at either 2B or 2B-1. */ \
_FP_FRAC_SRS_1(R, wfracbits-1, 2*wfracbits); \
} while (0)
 
/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
 
#define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit) \
do { \
_FP_W_TYPE _Z_f0, _Z_f1; \
doit(_Z_f1, _Z_f0, X##_f, Y##_f); \
/* Normalize since we know where the msb of the multiplicands \
were (bit B), we know that the msb of the of the product is \
at either 2B or 2B-1. */ \
_FP_FRAC_SRS_2(_Z, wfracbits-1, 2*wfracbits); \
R##_f = _Z_f0; \
} while (0)
 
/* Finally, a simple widening multiply algorithm. What fun! */
 
#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y) \
do { \
_FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1; \
\
/* split the words in half */ \
_xh = X##_f >> (_FP_W_TYPE_SIZE/2); \
_xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \
_yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \
_yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \
\
/* multiply the pieces */ \
_z_f0 = _xl * _yl; \
_a_f0 = _xh * _yl; \
_a_f1 = _xl * _yh; \
_z_f1 = _xh * _yh; \
\
/* reassemble into two full words */ \
if ((_a_f0 += _a_f1) < _a_f1) \
_z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2); \
_a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \
_a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \
_FP_FRAC_ADD_2(_z, _z, _a); \
\
/* normalize */ \
_FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits); \
R##_f = _z_f0; \
} while (0)
 
 
/*
* Division algorithms:
*/
 
/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the
division immediately. Give this macro either _FP_DIV_HELP_imm for
C primitives or _FP_DIV_HELP_ldiv for the ISO function. Which you
choose will depend on what the compiler does with divrem4. */
 
#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \
do { \
_FP_W_TYPE _q, _r; \
X##_f <<= (X##_f < Y##_f \
? R##_e--, _FP_WFRACBITS_##fs \
: _FP_WFRACBITS_##fs - 1); \
doit(_q, _r, X##_f, Y##_f); \
R##_f = _q | (_r != 0); \
} while (0)
 
/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
that may be useful in this situation. This first is for a primitive
that requires normalization, the second for one that does not. Look
for UDIV_NEEDS_NORMALIZATION to tell which your machine needs. */
 
#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \
do { \
_FP_W_TYPE _nh, _nl, _q, _r, _y; \
\
/* Normalize Y -- i.e. make the most significant bit set. */ \
_y = Y##_f << _FP_WFRACXBITS_##fs; \
\
/* Shift X op correspondingly high, that is, up one full word. */ \
if (X##_f < Y##_f) \
{ \
R##_e--; \
_nl = 0; \
_nh = X##_f; \
} \
else \
{ \
_nl = X##_f << (_FP_W_TYPE_SIZE - 1); \
_nh = X##_f >> 1; \
} \
\
udiv_qrnnd(_q, _r, _nh, _nl, _y); \
R##_f = _q | (_r != 0); \
} while (0)
 
#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \
do { \
_FP_W_TYPE _nh, _nl, _q, _r; \
if (X##_f < Y##_f) \
{ \
R##_e--; \
_nl = X##_f << _FP_WFRACBITS_##fs; \
_nh = X##_f >> _FP_WFRACXBITS_##fs; \
} \
else \
{ \
_nl = X##_f << (_FP_WFRACBITS_##fs - 1); \
_nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \
} \
udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \
R##_f = _q | (_r != 0); \
} while (0)
/*
* Square root algorithms:
* We have just one right now, maybe Newton approximation
* should be added for those machines where division is fast.
*/
#define _FP_SQRT_MEAT_1(R, S, T, X, q) \
do { \
while (q != _FP_WORK_ROUND) \
{ \
T##_f = S##_f + q; \
if (T##_f <= X##_f) \
{ \
S##_f = T##_f + q; \
X##_f -= T##_f; \
R##_f += q; \
} \
_FP_FRAC_SLL_1(X, 1); \
q >>= 1; \
} \
if (X##_f) \
{ \
if (S##_f < X##_f) \
R##_f |= _FP_WORK_ROUND; \
R##_f |= _FP_WORK_STICKY; \
} \
} while (0)
 
/*
* Assembly/disassembly for converting to/from integral types.
* No shifting or overflow handled here.
*/
 
#define _FP_FRAC_ASSEMBLE_1(r, X, rsize) (r = X##_f)
#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize) (X##_f = r)
 
 
/*
* Convert FP values between word sizes
*/
 
#define _FP_FRAC_COPY_1_1(D, S) (D##_f = S##_f)
/programs/develop/libraries/newlib/math/op-2.h
0,0 → 1,617
/* Software floating-point emulation.
Basic two-word fraction declaration and manipulation.
Copyright (C) 1997,1998,1999,2006,2007 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. */
 
#define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0, X##_f1
#define _FP_FRAC_COPY_2(D,S) (D##_f0 = S##_f0, D##_f1 = S##_f1)
#define _FP_FRAC_SET_2(X,I) __FP_FRAC_SET_2(X, I)
#define _FP_FRAC_HIGH_2(X) (X##_f1)
#define _FP_FRAC_LOW_2(X) (X##_f0)
#define _FP_FRAC_WORD_2(X,w) (X##_f##w)
 
#define _FP_FRAC_SLL_2(X,N) \
(void)(((N) < _FP_W_TYPE_SIZE) \
? ({ \
if (__builtin_constant_p(N) && (N) == 1) \
{ \
X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \
X##_f0 += X##_f0; \
} \
else \
{ \
X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \
X##_f0 <<= (N); \
} \
0; \
}) \
: ({ \
X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \
X##_f0 = 0; \
}))
 
 
#define _FP_FRAC_SRL_2(X,N) \
(void)(((N) < _FP_W_TYPE_SIZE) \
? ({ \
X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \
X##_f1 >>= (N); \
}) \
: ({ \
X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \
X##_f1 = 0; \
}))
 
/* Right shift with sticky-lsb. */
#define _FP_FRAC_SRST_2(X,S, N,sz) \
(void)(((N) < _FP_W_TYPE_SIZE) \
? ({ \
S = (__builtin_constant_p(N) && (N) == 1 \
? X##_f0 & 1 \
: (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0); \
X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N)); \
X##_f1 >>= (N); \
}) \
: ({ \
S = ((((N) == _FP_W_TYPE_SIZE \
? 0 \
: (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \
| X##_f0) != 0); \
X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE)); \
X##_f1 = 0; \
}))
 
#define _FP_FRAC_SRS_2(X,N,sz) \
(void)(((N) < _FP_W_TYPE_SIZE) \
? ({ \
X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \
(__builtin_constant_p(N) && (N) == 1 \
? X##_f0 & 1 \
: (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \
X##_f1 >>= (N); \
}) \
: ({ \
X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \
((((N) == _FP_W_TYPE_SIZE \
? 0 \
: (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \
| X##_f0) != 0)); \
X##_f1 = 0; \
}))
 
#define _FP_FRAC_ADDI_2(X,I) \
__FP_FRAC_ADDI_2(X##_f1, X##_f0, I)
 
#define _FP_FRAC_ADD_2(R,X,Y) \
__FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
 
#define _FP_FRAC_SUB_2(R,X,Y) \
__FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
 
#define _FP_FRAC_DEC_2(X,Y) \
__FP_FRAC_DEC_2(X##_f1, X##_f0, Y##_f1, Y##_f0)
 
#define _FP_FRAC_CLZ_2(R,X) \
do { \
if (X##_f1) \
__FP_CLZ(R,X##_f1); \
else \
{ \
__FP_CLZ(R,X##_f0); \
R += _FP_W_TYPE_SIZE; \
} \
} while(0)
 
/* Predicates */
#define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE)X##_f1 < 0)
#define _FP_FRAC_ZEROP_2(X) ((X##_f1 | X##_f0) == 0)
#define _FP_FRAC_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
#define _FP_FRAC_CLEAR_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs)
#define _FP_FRAC_EQ_2(X, Y) (X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
#define _FP_FRAC_GT_2(X, Y) \
(X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))
#define _FP_FRAC_GE_2(X, Y) \
(X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0))
 
#define _FP_ZEROFRAC_2 0, 0
#define _FP_MINFRAC_2 0, 1
#define _FP_MAXFRAC_2 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0)
 
/*
* Internals
*/
 
#define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1)
 
#define __FP_CLZ_2(R, xh, xl) \
do { \
if (xh) \
__FP_CLZ(R,xh); \
else \
{ \
__FP_CLZ(R,xl); \
R += _FP_W_TYPE_SIZE; \
} \
} while(0)
 
#if 0
 
#ifndef __FP_FRAC_ADDI_2
#define __FP_FRAC_ADDI_2(xh, xl, i) \
(xh += ((xl += i) < i))
#endif
#ifndef __FP_FRAC_ADD_2
#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \
(rh = xh + yh + ((rl = xl + yl) < xl))
#endif
#ifndef __FP_FRAC_SUB_2
#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \
(rh = xh - yh - ((rl = xl - yl) > xl))
#endif
#ifndef __FP_FRAC_DEC_2
#define __FP_FRAC_DEC_2(xh, xl, yh, yl) \
do { \
UWtype _t = xl; \
xh -= yh + ((xl -= yl) > _t); \
} while (0)
#endif
 
#else
 
#undef __FP_FRAC_ADDI_2
#define __FP_FRAC_ADDI_2(xh, xl, i) add_ssaaaa(xh, xl, xh, xl, 0, i)
#undef __FP_FRAC_ADD_2
#define __FP_FRAC_ADD_2 add_ssaaaa
#undef __FP_FRAC_SUB_2
#define __FP_FRAC_SUB_2 sub_ddmmss
#undef __FP_FRAC_DEC_2
#define __FP_FRAC_DEC_2(xh, xl, yh, yl) sub_ddmmss(xh, xl, xh, xl, yh, yl)
 
#endif
 
/*
* Unpack the raw bits of a native fp value. Do not classify or
* normalize the data.
*/
 
#define _FP_UNPACK_RAW_2(fs, X, val) \
do { \
union _FP_UNION_##fs _flo; _flo.flt = (val); \
\
X##_f0 = _flo.bits.frac0; \
X##_f1 = _flo.bits.frac1; \
X##_e = _flo.bits.exp; \
X##_s = _flo.bits.sign; \
} while (0)
 
#define _FP_UNPACK_RAW_2_P(fs, X, val) \
do { \
union _FP_UNION_##fs *_flo = \
(union _FP_UNION_##fs *)(val); \
\
X##_f0 = _flo->bits.frac0; \
X##_f1 = _flo->bits.frac1; \
X##_e = _flo->bits.exp; \
X##_s = _flo->bits.sign; \
} while (0)
 
 
/*
* Repack the raw bits of a native fp value.
*/
 
#define _FP_PACK_RAW_2(fs, val, X) \
do { \
union _FP_UNION_##fs _flo; \
\
_flo.bits.frac0 = X##_f0; \
_flo.bits.frac1 = X##_f1; \
_flo.bits.exp = X##_e; \
_flo.bits.sign = X##_s; \
\
(val) = _flo.flt; \
} while (0)
 
#define _FP_PACK_RAW_2_P(fs, val, X) \
do { \
union _FP_UNION_##fs *_flo = \
(union _FP_UNION_##fs *)(val); \
\
_flo->bits.frac0 = X##_f0; \
_flo->bits.frac1 = X##_f1; \
_flo->bits.exp = X##_e; \
_flo->bits.sign = X##_s; \
} while (0)
 
 
/*
* Multiplication algorithms:
*/
 
/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
 
#define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit) \
do { \
_FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \
\
doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \
doit(_b_f1, _b_f0, X##_f0, Y##_f1); \
doit(_c_f1, _c_f0, X##_f1, Y##_f0); \
doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \
\
__FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
_FP_FRAC_WORD_4(_z,1), 0, _b_f1, _b_f0, \
_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
_FP_FRAC_WORD_4(_z,1)); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
_FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0, \
_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
_FP_FRAC_WORD_4(_z,1)); \
\
/* Normalize since we know where the msb of the multiplicands \
were (bit B), we know that the msb of the of the product is \
at either 2B or 2B-1. */ \
_FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \
R##_f0 = _FP_FRAC_WORD_4(_z,0); \
R##_f1 = _FP_FRAC_WORD_4(_z,1); \
} while (0)
 
/* Given a 1W * 1W => 2W primitive, do the extended multiplication.
Do only 3 multiplications instead of four. This one is for machines
where multiplication is much more expensive than subtraction. */
 
#define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit) \
do { \
_FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \
_FP_W_TYPE _d; \
int _c1, _c2; \
\
_b_f0 = X##_f0 + X##_f1; \
_c1 = _b_f0 < X##_f0; \
_b_f1 = Y##_f0 + Y##_f1; \
_c2 = _b_f1 < Y##_f0; \
doit(_d, _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \
doit(_FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1), _b_f0, _b_f1); \
doit(_c_f1, _c_f0, X##_f1, Y##_f1); \
\
_b_f0 &= -_c2; \
_b_f1 &= -_c1; \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
_FP_FRAC_WORD_4(_z,1), (_c1 & _c2), 0, _d, \
0, _FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1)); \
__FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
_b_f0); \
__FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
_b_f1); \
__FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
_FP_FRAC_WORD_4(_z,1), \
0, _d, _FP_FRAC_WORD_4(_z,0)); \
__FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
_FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0); \
__FP_FRAC_ADD_2(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), \
_c_f1, _c_f0, \
_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2)); \
\
/* Normalize since we know where the msb of the multiplicands \
were (bit B), we know that the msb of the of the product is \
at either 2B or 2B-1. */ \
_FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \
R##_f0 = _FP_FRAC_WORD_4(_z,0); \
R##_f1 = _FP_FRAC_WORD_4(_z,1); \
} while (0)
 
#define _FP_MUL_MEAT_2_gmp(wfracbits, R, X, Y) \
do { \
_FP_FRAC_DECL_4(_z); \
_FP_W_TYPE _x[2], _y[2]; \
_x[0] = X##_f0; _x[1] = X##_f1; \
_y[0] = Y##_f0; _y[1] = Y##_f1; \
\
mpn_mul_n(_z_f, _x, _y, 2); \
\
/* Normalize since we know where the msb of the multiplicands \
were (bit B), we know that the msb of the of the product is \
at either 2B or 2B-1. */ \
_FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \
R##_f0 = _z_f[0]; \
R##_f1 = _z_f[1]; \
} while (0)
 
/* Do at most 120x120=240 bits multiplication using double floating
point multiplication. This is useful if floating point
multiplication has much bigger throughput than integer multiply.
It is supposed to work for _FP_W_TYPE_SIZE 64 and wfracbits
between 106 and 120 only.
Caller guarantees that X and Y has (1LLL << (wfracbits - 1)) set.
SETFETZ is a macro which will disable all FPU exceptions and set rounding
towards zero, RESETFE should optionally reset it back. */
 
#define _FP_MUL_MEAT_2_120_240_double(wfracbits, R, X, Y, setfetz, resetfe) \
do { \
static const double _const[] = { \
/* 2^-24 */ 5.9604644775390625e-08, \
/* 2^-48 */ 3.5527136788005009e-15, \
/* 2^-72 */ 2.1175823681357508e-22, \
/* 2^-96 */ 1.2621774483536189e-29, \
/* 2^28 */ 2.68435456e+08, \
/* 2^4 */ 1.600000e+01, \
/* 2^-20 */ 9.5367431640625e-07, \
/* 2^-44 */ 5.6843418860808015e-14, \
/* 2^-68 */ 3.3881317890172014e-21, \
/* 2^-92 */ 2.0194839173657902e-28, \
/* 2^-116 */ 1.2037062152420224e-35}; \
double _a240, _b240, _c240, _d240, _e240, _f240, \
_g240, _h240, _i240, _j240, _k240; \
union { double d; UDItype i; } _l240, _m240, _n240, _o240, \
_p240, _q240, _r240, _s240; \
UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \
\
if (wfracbits < 106 || wfracbits > 120) \
abort(); \
\
setfetz; \
\
_e240 = (double)(long)(X##_f0 & 0xffffff); \
_j240 = (double)(long)(Y##_f0 & 0xffffff); \
_d240 = (double)(long)((X##_f0 >> 24) & 0xffffff); \
_i240 = (double)(long)((Y##_f0 >> 24) & 0xffffff); \
_c240 = (double)(long)(((X##_f1 << 16) & 0xffffff) | (X##_f0 >> 48)); \
_h240 = (double)(long)(((Y##_f1 << 16) & 0xffffff) | (Y##_f0 >> 48)); \
_b240 = (double)(long)((X##_f1 >> 8) & 0xffffff); \
_g240 = (double)(long)((Y##_f1 >> 8) & 0xffffff); \
_a240 = (double)(long)(X##_f1 >> 32); \
_f240 = (double)(long)(Y##_f1 >> 32); \
_e240 *= _const[3]; \
_j240 *= _const[3]; \
_d240 *= _const[2]; \
_i240 *= _const[2]; \
_c240 *= _const[1]; \
_h240 *= _const[1]; \
_b240 *= _const[0]; \
_g240 *= _const[0]; \
_s240.d = _e240*_j240;\
_r240.d = _d240*_j240 + _e240*_i240;\
_q240.d = _c240*_j240 + _d240*_i240 + _e240*_h240;\
_p240.d = _b240*_j240 + _c240*_i240 + _d240*_h240 + _e240*_g240;\
_o240.d = _a240*_j240 + _b240*_i240 + _c240*_h240 + _d240*_g240 + _e240*_f240;\
_n240.d = _a240*_i240 + _b240*_h240 + _c240*_g240 + _d240*_f240; \
_m240.d = _a240*_h240 + _b240*_g240 + _c240*_f240; \
_l240.d = _a240*_g240 + _b240*_f240; \
_k240 = _a240*_f240; \
_r240.d += _s240.d; \
_q240.d += _r240.d; \
_p240.d += _q240.d; \
_o240.d += _p240.d; \
_n240.d += _o240.d; \
_m240.d += _n240.d; \
_l240.d += _m240.d; \
_k240 += _l240.d; \
_s240.d -= ((_const[10]+_s240.d)-_const[10]); \
_r240.d -= ((_const[9]+_r240.d)-_const[9]); \
_q240.d -= ((_const[8]+_q240.d)-_const[8]); \
_p240.d -= ((_const[7]+_p240.d)-_const[7]); \
_o240.d += _const[7]; \
_n240.d += _const[6]; \
_m240.d += _const[5]; \
_l240.d += _const[4]; \
if (_s240.d != 0.0) _y240 = 1; \
if (_r240.d != 0.0) _y240 = 1; \
if (_q240.d != 0.0) _y240 = 1; \
if (_p240.d != 0.0) _y240 = 1; \
_t240 = (DItype)_k240; \
_u240 = _l240.i; \
_v240 = _m240.i; \
_w240 = _n240.i; \
_x240 = _o240.i; \
R##_f1 = (_t240 << (128 - (wfracbits - 1))) \
| ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104)); \
R##_f0 = ((_u240 & 0xffffff) << (168 - (wfracbits - 1))) \
| ((_v240 & 0xffffff) << (144 - (wfracbits - 1))) \
| ((_w240 & 0xffffff) << (120 - (wfracbits - 1))) \
| ((_x240 & 0xffffff) >> ((wfracbits - 1) - 96)) \
| _y240; \
resetfe; \
} while (0)
 
/*
* Division algorithms:
*/
 
#define _FP_DIV_MEAT_2_udiv(fs, R, X, Y) \
do { \
_FP_W_TYPE _n_f2, _n_f1, _n_f0, _r_f1, _r_f0, _m_f1, _m_f0; \
if (_FP_FRAC_GT_2(X, Y)) \
{ \
_n_f2 = X##_f1 >> 1; \
_n_f1 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \
_n_f0 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \
} \
else \
{ \
R##_e--; \
_n_f2 = X##_f1; \
_n_f1 = X##_f0; \
_n_f0 = 0; \
} \
\
/* Normalize, i.e. make the most significant bit of the \
denominator set. */ \
_FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs); \
\
udiv_qrnnd(R##_f1, _r_f1, _n_f2, _n_f1, Y##_f1); \
umul_ppmm(_m_f1, _m_f0, R##_f1, Y##_f0); \
_r_f0 = _n_f0; \
if (_FP_FRAC_GT_2(_m, _r)) \
{ \
R##_f1--; \
_FP_FRAC_ADD_2(_r, Y, _r); \
if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \
{ \
R##_f1--; \
_FP_FRAC_ADD_2(_r, Y, _r); \
} \
} \
_FP_FRAC_DEC_2(_r, _m); \
\
if (_r_f1 == Y##_f1) \
{ \
/* This is a special case, not an optimization \
(_r/Y##_f1 would not fit into UWtype). \
As _r is guaranteed to be < Y, R##_f0 can be either \
(UWtype)-1 or (UWtype)-2. But as we know what kind \
of bits it is (sticky, guard, round), we don't care. \
We also don't care what the reminder is, because the \
guard bit will be set anyway. -jj */ \
R##_f0 = -1; \
} \
else \
{ \
udiv_qrnnd(R##_f0, _r_f1, _r_f1, _r_f0, Y##_f1); \
umul_ppmm(_m_f1, _m_f0, R##_f0, Y##_f0); \
_r_f0 = 0; \
if (_FP_FRAC_GT_2(_m, _r)) \
{ \
R##_f0--; \
_FP_FRAC_ADD_2(_r, Y, _r); \
if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \
{ \
R##_f0--; \
_FP_FRAC_ADD_2(_r, Y, _r); \
} \
} \
if (!_FP_FRAC_EQ_2(_r, _m)) \
R##_f0 |= _FP_WORK_STICKY; \
} \
} while (0)
 
 
#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y) \
do { \
_FP_W_TYPE _x[4], _y[2], _z[4]; \
_y[0] = Y##_f0; _y[1] = Y##_f1; \
_x[0] = _x[3] = 0; \
if (_FP_FRAC_GT_2(X, Y)) \
{ \
R##_e++; \
_x[1] = (X##_f0 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE) | \
X##_f1 >> (_FP_W_TYPE_SIZE - \
(_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE))); \
_x[2] = X##_f1 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE); \
} \
else \
{ \
_x[1] = (X##_f0 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE) | \
X##_f1 >> (_FP_W_TYPE_SIZE - \
(_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE))); \
_x[2] = X##_f1 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE); \
} \
\
(void) mpn_divrem (_z, 0, _x, 4, _y, 2); \
R##_f1 = _z[1]; \
R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0); \
} while (0)
 
 
/*
* Square root algorithms:
* We have just one right now, maybe Newton approximation
* should be added for those machines where division is fast.
*/
#define _FP_SQRT_MEAT_2(R, S, T, X, q) \
do { \
while (q) \
{ \
T##_f1 = S##_f1 + q; \
if (T##_f1 <= X##_f1) \
{ \
S##_f1 = T##_f1 + q; \
X##_f1 -= T##_f1; \
R##_f1 += q; \
} \
_FP_FRAC_SLL_2(X, 1); \
q >>= 1; \
} \
q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
while (q != _FP_WORK_ROUND) \
{ \
T##_f0 = S##_f0 + q; \
T##_f1 = S##_f1; \
if (T##_f1 < X##_f1 || \
(T##_f1 == X##_f1 && T##_f0 <= X##_f0)) \
{ \
S##_f0 = T##_f0 + q; \
S##_f1 += (T##_f0 > S##_f0); \
_FP_FRAC_DEC_2(X, T); \
R##_f0 += q; \
} \
_FP_FRAC_SLL_2(X, 1); \
q >>= 1; \
} \
if (X##_f0 | X##_f1) \
{ \
if (S##_f1 < X##_f1 || \
(S##_f1 == X##_f1 && S##_f0 < X##_f0)) \
R##_f0 |= _FP_WORK_ROUND; \
R##_f0 |= _FP_WORK_STICKY; \
} \
} while (0)
 
 
/*
* Assembly/disassembly for converting to/from integral types.
* No shifting or overflow handled here.
*/
 
#define _FP_FRAC_ASSEMBLE_2(r, X, rsize) \
(void)((rsize <= _FP_W_TYPE_SIZE) \
? ({ r = X##_f0; }) \
: ({ \
r = X##_f1; \
r <<= _FP_W_TYPE_SIZE; \
r += X##_f0; \
}))
 
#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize) \
do { \
X##_f0 = r; \
X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \
} while (0)
 
/*
* Convert FP values between word sizes
*/
 
#define _FP_FRAC_COPY_1_2(D, S) (D##_f = S##_f0)
 
#define _FP_FRAC_COPY_2_1(D, S) ((D##_f0 = S##_f), (D##_f1 = 0))
 
#define _FP_FRAC_COPY_2_2(D,S) _FP_FRAC_COPY_2(D,S)
/programs/develop/libraries/newlib/math/op-4.h
0,0 → 1,688
/* Software floating-point emulation.
Basic four-word fraction declaration and manipulation.
Copyright (C) 1997,1998,1999,2006,2007 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. */
 
#define _FP_FRAC_DECL_4(X) _FP_W_TYPE X##_f[4]
#define _FP_FRAC_COPY_4(D,S) \
(D##_f[0] = S##_f[0], D##_f[1] = S##_f[1], \
D##_f[2] = S##_f[2], D##_f[3] = S##_f[3])
#define _FP_FRAC_SET_4(X,I) __FP_FRAC_SET_4(X, I)
#define _FP_FRAC_HIGH_4(X) (X##_f[3])
#define _FP_FRAC_LOW_4(X) (X##_f[0])
#define _FP_FRAC_WORD_4(X,w) (X##_f[w])
 
#define _FP_FRAC_SLL_4(X,N) \
do { \
_FP_I_TYPE _up, _down, _skip, _i; \
_skip = (N) / _FP_W_TYPE_SIZE; \
_up = (N) % _FP_W_TYPE_SIZE; \
_down = _FP_W_TYPE_SIZE - _up; \
if (!_up) \
for (_i = 3; _i >= _skip; --_i) \
X##_f[_i] = X##_f[_i-_skip]; \
else \
{ \
for (_i = 3; _i > _skip; --_i) \
X##_f[_i] = X##_f[_i-_skip] << _up \
| X##_f[_i-_skip-1] >> _down; \
X##_f[_i--] = X##_f[0] << _up; \
} \
for (; _i >= 0; --_i) \
X##_f[_i] = 0; \
} while (0)
 
/* This one was broken too */
#define _FP_FRAC_SRL_4(X,N) \
do { \
_FP_I_TYPE _up, _down, _skip, _i; \
_skip = (N) / _FP_W_TYPE_SIZE; \
_down = (N) % _FP_W_TYPE_SIZE; \
_up = _FP_W_TYPE_SIZE - _down; \
if (!_down) \
for (_i = 0; _i <= 3-_skip; ++_i) \
X##_f[_i] = X##_f[_i+_skip]; \
else \
{ \
for (_i = 0; _i < 3-_skip; ++_i) \
X##_f[_i] = X##_f[_i+_skip] >> _down \
| X##_f[_i+_skip+1] << _up; \
X##_f[_i++] = X##_f[3] >> _down; \
} \
for (; _i < 4; ++_i) \
X##_f[_i] = 0; \
} while (0)
 
 
/* Right shift with sticky-lsb.
* What this actually means is that we do a standard right-shift,
* but that if any of the bits that fall off the right hand side
* were one then we always set the LSbit.
*/
#define _FP_FRAC_SRST_4(X,S,N,size) \
do { \
_FP_I_TYPE _up, _down, _skip, _i; \
_FP_W_TYPE _s; \
_skip = (N) / _FP_W_TYPE_SIZE; \
_down = (N) % _FP_W_TYPE_SIZE; \
_up = _FP_W_TYPE_SIZE - _down; \
for (_s = _i = 0; _i < _skip; ++_i) \
_s |= X##_f[_i]; \
if (!_down) \
for (_i = 0; _i <= 3-_skip; ++_i) \
X##_f[_i] = X##_f[_i+_skip]; \
else \
{ \
_s |= X##_f[_i] << _up; \
for (_i = 0; _i < 3-_skip; ++_i) \
X##_f[_i] = X##_f[_i+_skip] >> _down \
| X##_f[_i+_skip+1] << _up; \
X##_f[_i++] = X##_f[3] >> _down; \
} \
for (; _i < 4; ++_i) \
X##_f[_i] = 0; \
S = (_s != 0); \
} while (0)
 
#define _FP_FRAC_SRS_4(X,N,size) \
do { \
int _sticky; \
_FP_FRAC_SRST_4(X, _sticky, N, size); \
X##_f[0] |= _sticky; \
} while (0)
 
#define _FP_FRAC_ADD_4(R,X,Y) \
__FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \
X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
 
#define _FP_FRAC_SUB_4(R,X,Y) \
__FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \
X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
 
#define _FP_FRAC_DEC_4(X,Y) \
__FP_FRAC_DEC_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
 
#define _FP_FRAC_ADDI_4(X,I) \
__FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I)
 
#define _FP_ZEROFRAC_4 0,0,0,0
#define _FP_MINFRAC_4 0,0,0,1
#define _FP_MAXFRAC_4 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0)
 
#define _FP_FRAC_ZEROP_4(X) ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
#define _FP_FRAC_NEGP_4(X) ((_FP_WS_TYPE)X##_f[3] < 0)
#define _FP_FRAC_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
#define _FP_FRAC_CLEAR_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs)
 
#define _FP_FRAC_EQ_4(X,Y) \
(X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \
&& X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3])
 
#define _FP_FRAC_GT_4(X,Y) \
(X##_f[3] > Y##_f[3] || \
(X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \
(X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \
(X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0]) \
)) \
)) \
)
 
#define _FP_FRAC_GE_4(X,Y) \
(X##_f[3] > Y##_f[3] || \
(X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \
(X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \
(X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0]) \
)) \
)) \
)
 
 
#define _FP_FRAC_CLZ_4(R,X) \
do { \
if (X##_f[3]) \
{ \
__FP_CLZ(R,X##_f[3]); \
} \
else if (X##_f[2]) \
{ \
__FP_CLZ(R,X##_f[2]); \
R += _FP_W_TYPE_SIZE; \
} \
else if (X##_f[1]) \
{ \
__FP_CLZ(R,X##_f[1]); \
R += _FP_W_TYPE_SIZE*2; \
} \
else \
{ \
__FP_CLZ(R,X##_f[0]); \
R += _FP_W_TYPE_SIZE*3; \
} \
} while(0)
 
 
#define _FP_UNPACK_RAW_4(fs, X, val) \
do { \
union _FP_UNION_##fs _flo; _flo.flt = (val); \
X##_f[0] = _flo.bits.frac0; \
X##_f[1] = _flo.bits.frac1; \
X##_f[2] = _flo.bits.frac2; \
X##_f[3] = _flo.bits.frac3; \
X##_e = _flo.bits.exp; \
X##_s = _flo.bits.sign; \
} while (0)
 
#define _FP_UNPACK_RAW_4_P(fs, X, val) \
do { \
union _FP_UNION_##fs *_flo = \
(union _FP_UNION_##fs *)(val); \
\
X##_f[0] = _flo->bits.frac0; \
X##_f[1] = _flo->bits.frac1; \
X##_f[2] = _flo->bits.frac2; \
X##_f[3] = _flo->bits.frac3; \
X##_e = _flo->bits.exp; \
X##_s = _flo->bits.sign; \
} while (0)
 
#define _FP_PACK_RAW_4(fs, val, X) \
do { \
union _FP_UNION_##fs _flo; \
_flo.bits.frac0 = X##_f[0]; \
_flo.bits.frac1 = X##_f[1]; \
_flo.bits.frac2 = X##_f[2]; \
_flo.bits.frac3 = X##_f[3]; \
_flo.bits.exp = X##_e; \
_flo.bits.sign = X##_s; \
(val) = _flo.flt; \
} while (0)
 
#define _FP_PACK_RAW_4_P(fs, val, X) \
do { \
union _FP_UNION_##fs *_flo = \
(union _FP_UNION_##fs *)(val); \
\
_flo->bits.frac0 = X##_f[0]; \
_flo->bits.frac1 = X##_f[1]; \
_flo->bits.frac2 = X##_f[2]; \
_flo->bits.frac3 = X##_f[3]; \
_flo->bits.exp = X##_e; \
_flo->bits.sign = X##_s; \
} while (0)
 
/*
* Multiplication algorithms:
*/
 
/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
 
#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit) \
do { \
_FP_FRAC_DECL_8(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \
_FP_FRAC_DECL_2(_d); _FP_FRAC_DECL_2(_e); _FP_FRAC_DECL_2(_f); \
\
doit(_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0), X##_f[0], Y##_f[0]); \
doit(_b_f1, _b_f0, X##_f[0], Y##_f[1]); \
doit(_c_f1, _c_f0, X##_f[1], Y##_f[0]); \
doit(_d_f1, _d_f0, X##_f[1], Y##_f[1]); \
doit(_e_f1, _e_f0, X##_f[0], Y##_f[2]); \
doit(_f_f1, _f_f0, X##_f[2], Y##_f[0]); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \
_FP_FRAC_WORD_8(_z,1), 0,_b_f1,_b_f0, \
0,0,_FP_FRAC_WORD_8(_z,1)); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \
_FP_FRAC_WORD_8(_z,1), 0,_c_f1,_c_f0, \
_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \
_FP_FRAC_WORD_8(_z,1)); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
_FP_FRAC_WORD_8(_z,2), 0,_d_f1,_d_f0, \
0,_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2)); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
_FP_FRAC_WORD_8(_z,2), 0,_e_f1,_e_f0, \
_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
_FP_FRAC_WORD_8(_z,2)); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
_FP_FRAC_WORD_8(_z,2), 0,_f_f1,_f_f0, \
_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
_FP_FRAC_WORD_8(_z,2)); \
doit(_b_f1, _b_f0, X##_f[0], Y##_f[3]); \
doit(_c_f1, _c_f0, X##_f[3], Y##_f[0]); \
doit(_d_f1, _d_f0, X##_f[1], Y##_f[2]); \
doit(_e_f1, _e_f0, X##_f[2], Y##_f[1]); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
_FP_FRAC_WORD_8(_z,3), 0,_b_f1,_b_f0, \
0,_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3)); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
_FP_FRAC_WORD_8(_z,3), 0,_c_f1,_c_f0, \
_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
_FP_FRAC_WORD_8(_z,3)); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
_FP_FRAC_WORD_8(_z,3), 0,_d_f1,_d_f0, \
_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
_FP_FRAC_WORD_8(_z,3)); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
_FP_FRAC_WORD_8(_z,3), 0,_e_f1,_e_f0, \
_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
_FP_FRAC_WORD_8(_z,3)); \
doit(_b_f1, _b_f0, X##_f[2], Y##_f[2]); \
doit(_c_f1, _c_f0, X##_f[1], Y##_f[3]); \
doit(_d_f1, _d_f0, X##_f[3], Y##_f[1]); \
doit(_e_f1, _e_f0, X##_f[2], Y##_f[3]); \
doit(_f_f1, _f_f0, X##_f[3], Y##_f[2]); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
_FP_FRAC_WORD_8(_z,4), 0,_b_f1,_b_f0, \
0,_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4)); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
_FP_FRAC_WORD_8(_z,4), 0,_c_f1,_c_f0, \
_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
_FP_FRAC_WORD_8(_z,4)); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
_FP_FRAC_WORD_8(_z,4), 0,_d_f1,_d_f0, \
_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
_FP_FRAC_WORD_8(_z,4)); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \
_FP_FRAC_WORD_8(_z,5), 0,_e_f1,_e_f0, \
0,_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5)); \
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \
_FP_FRAC_WORD_8(_z,5), 0,_f_f1,_f_f0, \
_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \
_FP_FRAC_WORD_8(_z,5)); \
doit(_b_f1, _b_f0, X##_f[3], Y##_f[3]); \
__FP_FRAC_ADD_2(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \
_b_f1,_b_f0, \
_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6)); \
\
/* Normalize since we know where the msb of the multiplicands \
were (bit B), we know that the msb of the of the product is \
at either 2B or 2B-1. */ \
_FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \
__FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \
_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \
} while (0)
 
#define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y) \
do { \
_FP_FRAC_DECL_8(_z); \
\
mpn_mul_n(_z_f, _x_f, _y_f, 4); \
\
/* Normalize since we know where the msb of the multiplicands \
were (bit B), we know that the msb of the of the product is \
at either 2B or 2B-1. */ \
_FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \
__FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \
_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \
} while (0)
 
/*
* Helper utility for _FP_DIV_MEAT_4_udiv:
* pppp = m * nnn
*/
#define umul_ppppmnnn(p3,p2,p1,p0,m,n2,n1,n0) \
do { \
UWtype _t; \
umul_ppmm(p1,p0,m,n0); \
umul_ppmm(p2,_t,m,n1); \
__FP_FRAC_ADDI_2(p2,p1,_t); \
umul_ppmm(p3,_t,m,n2); \
__FP_FRAC_ADDI_2(p3,p2,_t); \
} while (0)
 
/*
* Division algorithms:
*/
 
#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y) \
do { \
int _i; \
_FP_FRAC_DECL_4(_n); _FP_FRAC_DECL_4(_m); \
_FP_FRAC_SET_4(_n, _FP_ZEROFRAC_4); \
if (_FP_FRAC_GT_4(X, Y)) \
{ \
_n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1); \
_FP_FRAC_SRL_4(X, 1); \
} \
else \
R##_e--; \
\
/* Normalize, i.e. make the most significant bit of the \
denominator set. */ \
_FP_FRAC_SLL_4(Y, _FP_WFRACXBITS_##fs); \
\
for (_i = 3; ; _i--) \
{ \
if (X##_f[3] == Y##_f[3]) \
{ \
/* This is a special case, not an optimization \
(X##_f[3]/Y##_f[3] would not fit into UWtype). \
As X## is guaranteed to be < Y, R##_f[_i] can be either \
(UWtype)-1 or (UWtype)-2. */ \
R##_f[_i] = -1; \
if (!_i) \
break; \
__FP_FRAC_SUB_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
Y##_f[2], Y##_f[1], Y##_f[0], 0, \
X##_f[2], X##_f[1], X##_f[0], _n_f[_i]); \
_FP_FRAC_SUB_4(X, Y, X); \
if (X##_f[3] > Y##_f[3]) \
{ \
R##_f[_i] = -2; \
_FP_FRAC_ADD_4(X, Y, X); \
} \
} \
else \
{ \
udiv_qrnnd(R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]); \
umul_ppppmnnn(_m_f[3], _m_f[2], _m_f[1], _m_f[0], \
R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]); \
X##_f[2] = X##_f[1]; \
X##_f[1] = X##_f[0]; \
X##_f[0] = _n_f[_i]; \
if (_FP_FRAC_GT_4(_m, X)) \
{ \
R##_f[_i]--; \
_FP_FRAC_ADD_4(X, Y, X); \
if (_FP_FRAC_GE_4(X, Y) && _FP_FRAC_GT_4(_m, X)) \
{ \
R##_f[_i]--; \
_FP_FRAC_ADD_4(X, Y, X); \
} \
} \
_FP_FRAC_DEC_4(X, _m); \
if (!_i) \
{ \
if (!_FP_FRAC_EQ_4(X, _m)) \
R##_f[0] |= _FP_WORK_STICKY; \
break; \
} \
} \
} \
} while (0)
 
 
/*
* Square root algorithms:
* We have just one right now, maybe Newton approximation
* should be added for those machines where division is fast.
*/
#define _FP_SQRT_MEAT_4(R, S, T, X, q) \
do { \
while (q) \
{ \
T##_f[3] = S##_f[3] + q; \
if (T##_f[3] <= X##_f[3]) \
{ \
S##_f[3] = T##_f[3] + q; \
X##_f[3] -= T##_f[3]; \
R##_f[3] += q; \
} \
_FP_FRAC_SLL_4(X, 1); \
q >>= 1; \
} \
q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
while (q) \
{ \
T##_f[2] = S##_f[2] + q; \
T##_f[3] = S##_f[3]; \
if (T##_f[3] < X##_f[3] || \
(T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2])) \
{ \
S##_f[2] = T##_f[2] + q; \
S##_f[3] += (T##_f[2] > S##_f[2]); \
__FP_FRAC_DEC_2(X##_f[3], X##_f[2], \
T##_f[3], T##_f[2]); \
R##_f[2] += q; \
} \
_FP_FRAC_SLL_4(X, 1); \
q >>= 1; \
} \
q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
while (q) \
{ \
T##_f[1] = S##_f[1] + q; \
T##_f[2] = S##_f[2]; \
T##_f[3] = S##_f[3]; \
if (T##_f[3] < X##_f[3] || \
(T##_f[3] == X##_f[3] && (T##_f[2] < X##_f[2] || \
(T##_f[2] == X##_f[2] && T##_f[1] <= X##_f[1])))) \
{ \
S##_f[1] = T##_f[1] + q; \
S##_f[2] += (T##_f[1] > S##_f[1]); \
S##_f[3] += (T##_f[2] > S##_f[2]); \
__FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1], \
T##_f[3], T##_f[2], T##_f[1]); \
R##_f[1] += q; \
} \
_FP_FRAC_SLL_4(X, 1); \
q >>= 1; \
} \
q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
while (q != _FP_WORK_ROUND) \
{ \
T##_f[0] = S##_f[0] + q; \
T##_f[1] = S##_f[1]; \
T##_f[2] = S##_f[2]; \
T##_f[3] = S##_f[3]; \
if (_FP_FRAC_GE_4(X,T)) \
{ \
S##_f[0] = T##_f[0] + q; \
S##_f[1] += (T##_f[0] > S##_f[0]); \
S##_f[2] += (T##_f[1] > S##_f[1]); \
S##_f[3] += (T##_f[2] > S##_f[2]); \
_FP_FRAC_DEC_4(X, T); \
R##_f[0] += q; \
} \
_FP_FRAC_SLL_4(X, 1); \
q >>= 1; \
} \
if (!_FP_FRAC_ZEROP_4(X)) \
{ \
if (_FP_FRAC_GT_4(X,S)) \
R##_f[0] |= _FP_WORK_ROUND; \
R##_f[0] |= _FP_WORK_STICKY; \
} \
} while (0)
 
 
/*
* Internals
*/
 
#define __FP_FRAC_SET_4(X,I3,I2,I1,I0) \
(X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)
 
#ifndef __FP_FRAC_ADD_3
#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
do { \
_FP_W_TYPE _c1, _c2; \
r0 = x0 + y0; \
_c1 = r0 < x0; \
r1 = x1 + y1; \
_c2 = r1 < x1; \
r1 += _c1; \
_c2 |= r1 < _c1; \
r2 = x2 + y2 + _c2; \
} while (0)
#endif
 
#ifndef __FP_FRAC_ADD_4
#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
do { \
_FP_W_TYPE _c1, _c2, _c3; \
r0 = x0 + y0; \
_c1 = r0 < x0; \
r1 = x1 + y1; \
_c2 = r1 < x1; \
r1 += _c1; \
_c2 |= r1 < _c1; \
r2 = x2 + y2; \
_c3 = r2 < x2; \
r2 += _c2; \
_c3 |= r2 < _c2; \
r3 = x3 + y3 + _c3; \
} while (0)
#endif
 
#ifndef __FP_FRAC_SUB_3
#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
do { \
_FP_W_TYPE _c1, _c2; \
r0 = x0 - y0; \
_c1 = r0 > x0; \
r1 = x1 - y1; \
_c2 = r1 > x1; \
r1 -= _c1; \
_c2 |= _c1 && (y1 == x1); \
r2 = x2 - y2 - _c2; \
} while (0)
#endif
 
#ifndef __FP_FRAC_SUB_4
#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
do { \
_FP_W_TYPE _c1, _c2, _c3; \
r0 = x0 - y0; \
_c1 = r0 > x0; \
r1 = x1 - y1; \
_c2 = r1 > x1; \
r1 -= _c1; \
_c2 |= _c1 && (y1 == x1); \
r2 = x2 - y2; \
_c3 = r2 > x2; \
r2 -= _c2; \
_c3 |= _c2 && (y2 == x2); \
r3 = x3 - y3 - _c3; \
} while (0)
#endif
 
#ifndef __FP_FRAC_DEC_3
#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) \
do { \
UWtype _t0, _t1, _t2; \
_t0 = x0, _t1 = x1, _t2 = x2; \
__FP_FRAC_SUB_3 (x2, x1, x0, _t2, _t1, _t0, y2, y1, y0); \
} while (0)
#endif
 
#ifndef __FP_FRAC_DEC_4
#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) \
do { \
UWtype _t0, _t1, _t2, _t3; \
_t0 = x0, _t1 = x1, _t2 = x2, _t3 = x3; \
__FP_FRAC_SUB_4 (x3,x2,x1,x0,_t3,_t2,_t1,_t0, y3,y2,y1,y0); \
} while (0)
#endif
 
#ifndef __FP_FRAC_ADDI_4
#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \
do { \
UWtype _t; \
_t = ((x0 += i) < i); \
x1 += _t; _t = (x1 < _t); \
x2 += _t; _t = (x2 < _t); \
x3 += _t; \
} while (0)
#endif
 
/* Convert FP values between word sizes. This appears to be more
* complicated than I'd have expected it to be, so these might be
* wrong... These macros are in any case somewhat bogus because they
* use information about what various FRAC_n variables look like
* internally [eg, that 2 word vars are X_f0 and x_f1]. But so do
* the ones in op-2.h and op-1.h.
*/
#define _FP_FRAC_COPY_1_4(D, S) (D##_f = S##_f[0])
 
#define _FP_FRAC_COPY_2_4(D, S) \
do { \
D##_f0 = S##_f[0]; \
D##_f1 = S##_f[1]; \
} while (0)
 
/* Assembly/disassembly for converting to/from integral types.
* No shifting or overflow handled here.
*/
/* Put the FP value X into r, which is an integer of size rsize. */
#define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \
do { \
if (rsize <= _FP_W_TYPE_SIZE) \
r = X##_f[0]; \
else if (rsize <= 2*_FP_W_TYPE_SIZE) \
{ \
r = X##_f[1]; \
r <<= _FP_W_TYPE_SIZE; \
r += X##_f[0]; \
} \
else \
{ \
/* I'm feeling lazy so we deal with int == 3words (implausible)*/ \
/* and int == 4words as a single case. */ \
r = X##_f[3]; \
r <<= _FP_W_TYPE_SIZE; \
r += X##_f[2]; \
r <<= _FP_W_TYPE_SIZE; \
r += X##_f[1]; \
r <<= _FP_W_TYPE_SIZE; \
r += X##_f[0]; \
} \
} while (0)
 
/* "No disassemble Number Five!" */
/* move an integer of size rsize into X's fractional part. We rely on
* the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid
* having to mask the values we store into it.
*/
#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \
do { \
X##_f[0] = r; \
X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \
X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \
X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \
} while (0);
 
#define _FP_FRAC_COPY_4_1(D, S) \
do { \
D##_f[0] = S##_f; \
D##_f[1] = D##_f[2] = D##_f[3] = 0; \
} while (0)
 
#define _FP_FRAC_COPY_4_2(D, S) \
do { \
D##_f[0] = S##_f0; \
D##_f[1] = S##_f1; \
D##_f[2] = D##_f[3] = 0; \
} while (0)
 
#define _FP_FRAC_COPY_4_4(D,S) _FP_FRAC_COPY_4(D,S)
/programs/develop/libraries/newlib/math/op-8.h
0,0 → 1,111
/* Software floating-point emulation.
Basic eight-word fraction declaration and manipulation.
Copyright (C) 1997,1998,1999,2006 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) 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. */
 
/* We need just a few things from here for op-4, if we ever need some
other macros, they can be added. */
#define _FP_FRAC_DECL_8(X) _FP_W_TYPE X##_f[8]
#define _FP_FRAC_HIGH_8(X) (X##_f[7])
#define _FP_FRAC_LOW_8(X) (X##_f[0])
#define _FP_FRAC_WORD_8(X,w) (X##_f[w])
 
#define _FP_FRAC_SLL_8(X,N) \
do { \
_FP_I_TYPE _up, _down, _skip, _i; \
_skip = (N) / _FP_W_TYPE_SIZE; \
_up = (N) % _FP_W_TYPE_SIZE; \
_down = _FP_W_TYPE_SIZE - _up; \
if (!_up) \
for (_i = 7; _i >= _skip; --_i) \
X##_f[_i] = X##_f[_i-_skip]; \
else \
{ \
for (_i = 7; _i > _skip; --_i) \
X##_f[_i] = X##_f[_i-_skip] << _up \
| X##_f[_i-_skip-1] >> _down; \
X##_f[_i--] = X##_f[0] << _up; \
} \
for (; _i >= 0; --_i) \
X##_f[_i] = 0; \
} while (0)
 
#define _FP_FRAC_SRL_8(X,N) \
do { \
_FP_I_TYPE _up, _down, _skip, _i; \
_skip = (N) / _FP_W_TYPE_SIZE; \
_down = (N) % _FP_W_TYPE_SIZE; \
_up = _FP_W_TYPE_SIZE - _down; \
if (!_down) \
for (_i = 0; _i <= 7-_skip; ++_i) \
X##_f[_i] = X##_f[_i+_skip]; \
else \
{ \
for (_i = 0; _i < 7-_skip; ++_i) \
X##_f[_i] = X##_f[_i+_skip] >> _down \
| X##_f[_i+_skip+1] << _up; \
X##_f[_i++] = X##_f[7] >> _down; \
} \
for (; _i < 8; ++_i) \
X##_f[_i] = 0; \
} while (0)
 
 
/* Right shift with sticky-lsb.
* What this actually means is that we do a standard right-shift,
* but that if any of the bits that fall off the right hand side
* were one then we always set the LSbit.
*/
#define _FP_FRAC_SRS_8(X,N,size) \
do { \
_FP_I_TYPE _up, _down, _skip, _i; \
_FP_W_TYPE _s; \
_skip = (N) / _FP_W_TYPE_SIZE; \
_down = (N) % _FP_W_TYPE_SIZE; \
_up = _FP_W_TYPE_SIZE - _down; \
for (_s = _i = 0; _i < _skip; ++_i) \
_s |= X##_f[_i]; \
if (!_down) \
for (_i = 0; _i <= 7-_skip; ++_i) \
X##_f[_i] = X##_f[_i+_skip]; \
else \
{ \
_s |= X##_f[_i] << _up; \
for (_i = 0; _i < 7-_skip; ++_i) \
X##_f[_i] = X##_f[_i+_skip] >> _down \
| X##_f[_i+_skip+1] << _up; \
X##_f[_i++] = X##_f[7] >> _down; \
} \
for (; _i < 8; ++_i) \
X##_f[_i] = 0; \
/* don't fix the LSB until the very end when we're sure f[0] is stable */ \
X##_f[0] |= (_s != 0); \
} while (0)
 
/programs/develop/libraries/newlib/math/op-common.h
0,0 → 1,1359
/* Software floating-point emulation. Common operations.
Copyright (C) 1997,1998,1999,2006,2007 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. */
 
#define _FP_DECL(wc, X) \
_FP_I_TYPE X##_c __attribute__((unused)), X##_s, X##_e; \
_FP_FRAC_DECL_##wc(X)
 
/*
* Finish truely unpacking a native fp value by classifying the kind
* of fp value and normalizing both the exponent and the fraction.
*/
 
#define _FP_UNPACK_CANONICAL(fs, wc, X) \
do { \
switch (X##_e) \
{ \
default: \
_FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \
_FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \
X##_e -= _FP_EXPBIAS_##fs; \
X##_c = FP_CLS_NORMAL; \
break; \
\
case 0: \
if (_FP_FRAC_ZEROP_##wc(X)) \
X##_c = FP_CLS_ZERO; \
else \
{ \
/* a denormalized number */ \
_FP_I_TYPE _shift; \
_FP_FRAC_CLZ_##wc(_shift, X); \
_shift -= _FP_FRACXBITS_##fs; \
_FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \
X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
X##_c = FP_CLS_NORMAL; \
FP_SET_EXCEPTION(FP_EX_DENORM); \
} \
break; \
\
case _FP_EXPMAX_##fs: \
if (_FP_FRAC_ZEROP_##wc(X)) \
X##_c = FP_CLS_INF; \
else \
{ \
X##_c = FP_CLS_NAN; \
/* Check for signaling NaN */ \
if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
FP_SET_EXCEPTION(FP_EX_INVALID); \
} \
break; \
} \
} while (0)
 
/* Finish unpacking an fp value in semi-raw mode: the mantissa is
shifted by _FP_WORKBITS but the implicit MSB is not inserted and
other classification is not done. */
#define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc(X, _FP_WORKBITS)
 
/* A semi-raw value has overflowed to infinity. Adjust the mantissa
and exponent appropriately. */
#define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \
do { \
if (FP_ROUNDMODE == FP_RND_NEAREST \
|| (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \
|| (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \
{ \
X##_e = _FP_EXPMAX_##fs; \
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
} \
else \
{ \
X##_e = _FP_EXPMAX_##fs - 1; \
_FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \
} \
FP_SET_EXCEPTION(FP_EX_INEXACT); \
FP_SET_EXCEPTION(FP_EX_OVERFLOW); \
} while (0)
 
/* Check for a semi-raw value being a signaling NaN and raise the
invalid exception if so. */
#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \
do { \
if (X##_e == _FP_EXPMAX_##fs \
&& !_FP_FRAC_ZEROP_##wc(X) \
&& !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) \
FP_SET_EXCEPTION(FP_EX_INVALID); \
} while (0)
 
/* Choose a NaN result from an operation on two semi-raw NaN
values. */
#define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \
do { \
/* _FP_CHOOSENAN expects raw values, so shift as required. */ \
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
_FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \
_FP_CHOOSENAN(fs, wc, R, X, Y, OP); \
_FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \
} while (0)
 
/* Test whether a biased exponent is normal (not zero or maximum). */
#define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1)
 
/* Prepare to pack an fp value in semi-raw mode: the mantissa is
rounded and shifted right, with the rounding possibly increasing
the exponent (including changing a finite value to infinity). */
#define _FP_PACK_SEMIRAW(fs, wc, X) \
do { \
_FP_ROUND(wc, X); \
if (_FP_FRAC_HIGH_##fs(X) \
& (_FP_OVERFLOW_##fs >> 1)) \
{ \
_FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \
X##_e++; \
if (X##_e == _FP_EXPMAX_##fs) \
_FP_OVERFLOW_SEMIRAW(fs, wc, X); \
} \
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X)) \
{ \
if (X##_e == 0) \
FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
else \
{ \
if (!_FP_KEEPNANFRACP) \
{ \
_FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
X##_s = _FP_NANSIGN_##fs; \
} \
else \
_FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
} \
} \
} while (0)
 
/*
* Before packing the bits back into the native fp result, take care
* of such mundane things as rounding and overflow. Also, for some
* kinds of fp values, the original parts may not have been fully
* extracted -- but that is ok, we can regenerate them now.
*/
 
#define _FP_PACK_CANONICAL(fs, wc, X) \
do { \
switch (X##_c) \
{ \
case FP_CLS_NORMAL: \
X##_e += _FP_EXPBIAS_##fs; \
if (X##_e > 0) \
{ \
_FP_ROUND(wc, X); \
if (_FP_FRAC_OVERP_##wc(fs, X)) \
{ \
_FP_FRAC_CLEAR_OVERP_##wc(fs, X); \
X##_e++; \
} \
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
if (X##_e >= _FP_EXPMAX_##fs) \
{ \
/* overflow */ \
switch (FP_ROUNDMODE) \
{ \
case FP_RND_NEAREST: \
X##_c = FP_CLS_INF; \
break; \
case FP_RND_PINF: \
if (!X##_s) X##_c = FP_CLS_INF; \
break; \
case FP_RND_MINF: \
if (X##_s) X##_c = FP_CLS_INF; \
break; \
} \
if (X##_c == FP_CLS_INF) \
{ \
/* Overflow to infinity */ \
X##_e = _FP_EXPMAX_##fs; \
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
} \
else \
{ \
/* Overflow to maximum normal */ \
X##_e = _FP_EXPMAX_##fs - 1; \
_FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \
} \
FP_SET_EXCEPTION(FP_EX_OVERFLOW); \
FP_SET_EXCEPTION(FP_EX_INEXACT); \
} \
} \
else \
{ \
/* we've got a denormalized number */ \
X##_e = -X##_e + 1; \
if (X##_e <= _FP_WFRACBITS_##fs) \
{ \
_FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
_FP_ROUND(wc, X); \
if (_FP_FRAC_HIGH_##fs(X) \
& (_FP_OVERFLOW_##fs >> 1)) \
{ \
X##_e = 1; \
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
} \
else \
{ \
X##_e = 0; \
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
} \
} \
else \
{ \
/* underflow to zero */ \
X##_e = 0; \
if (!_FP_FRAC_ZEROP_##wc(X)) \
{ \
_FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
_FP_ROUND(wc, X); \
_FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \
} \
FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
} \
} \
break; \
\
case FP_CLS_ZERO: \
X##_e = 0; \
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
break; \
\
case FP_CLS_INF: \
X##_e = _FP_EXPMAX_##fs; \
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
break; \
\
case FP_CLS_NAN: \
X##_e = _FP_EXPMAX_##fs; \
if (!_FP_KEEPNANFRACP) \
{ \
_FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
X##_s = _FP_NANSIGN_##fs; \
} \
else \
_FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
break; \
} \
} while (0)
 
/* This one accepts raw argument and not cooked, returns
* 1 if X is a signaling NaN.
*/
#define _FP_ISSIGNAN(fs, wc, X) \
({ \
int __ret = 0; \
if (X##_e == _FP_EXPMAX_##fs) \
{ \
if (!_FP_FRAC_ZEROP_##wc(X) \
&& !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
__ret = 1; \
} \
__ret; \
})
 
 
 
 
 
/* Addition on semi-raw values. */
#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \
do { \
if (X##_s == Y##_s) \
{ \
/* Addition. */ \
R##_s = X##_s; \
int ediff = X##_e - Y##_e; \
if (ediff > 0) \
{ \
R##_e = X##_e; \
if (Y##_e == 0) \
{ \
/* Y is zero or denormalized. */ \
if (_FP_FRAC_ZEROP_##wc(Y)) \
{ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
_FP_FRAC_COPY_##wc(R, X); \
goto add_done; \
} \
else \
{ \
FP_SET_EXCEPTION(FP_EX_DENORM); \
ediff--; \
if (ediff == 0) \
{ \
_FP_FRAC_ADD_##wc(R, X, Y); \
goto add3; \
} \
if (X##_e == _FP_EXPMAX_##fs) \
{ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
_FP_FRAC_COPY_##wc(R, X); \
goto add_done; \
} \
goto add1; \
} \
} \
else if (X##_e == _FP_EXPMAX_##fs) \
{ \
/* X is NaN or Inf, Y is normal. */ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
_FP_FRAC_COPY_##wc(R, X); \
goto add_done; \
} \
\
/* Insert implicit MSB of Y. */ \
_FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
\
add1: \
/* Shift the mantissa of Y to the right EDIFF steps; \
remember to account later for the implicit MSB of X. */ \
if (ediff <= _FP_WFRACBITS_##fs) \
_FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \
else if (!_FP_FRAC_ZEROP_##wc(Y)) \
_FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
_FP_FRAC_ADD_##wc(R, X, Y); \
} \
else if (ediff < 0) \
{ \
ediff = -ediff; \
R##_e = Y##_e; \
if (X##_e == 0) \
{ \
/* X is zero or denormalized. */ \
if (_FP_FRAC_ZEROP_##wc(X)) \
{ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
_FP_FRAC_COPY_##wc(R, Y); \
goto add_done; \
} \
else \
{ \
FP_SET_EXCEPTION(FP_EX_DENORM); \
ediff--; \
if (ediff == 0) \
{ \
_FP_FRAC_ADD_##wc(R, Y, X); \
goto add3; \
} \
if (Y##_e == _FP_EXPMAX_##fs) \
{ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
_FP_FRAC_COPY_##wc(R, Y); \
goto add_done; \
} \
goto add2; \
} \
} \
else if (Y##_e == _FP_EXPMAX_##fs) \
{ \
/* Y is NaN or Inf, X is normal. */ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
_FP_FRAC_COPY_##wc(R, Y); \
goto add_done; \
} \
\
/* Insert implicit MSB of X. */ \
_FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
\
add2: \
/* Shift the mantissa of X to the right EDIFF steps; \
remember to account later for the implicit MSB of Y. */ \
if (ediff <= _FP_WFRACBITS_##fs) \
_FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \
else if (!_FP_FRAC_ZEROP_##wc(X)) \
_FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
_FP_FRAC_ADD_##wc(R, Y, X); \
} \
else \
{ \
/* ediff == 0. */ \
if (!_FP_EXP_NORMAL(fs, wc, X)) \
{ \
if (X##_e == 0) \
{ \
/* X and Y are zero or denormalized. */ \
R##_e = 0; \
if (_FP_FRAC_ZEROP_##wc(X)) \
{ \
if (!_FP_FRAC_ZEROP_##wc(Y)) \
FP_SET_EXCEPTION(FP_EX_DENORM); \
_FP_FRAC_COPY_##wc(R, Y); \
goto add_done; \
} \
else if (_FP_FRAC_ZEROP_##wc(Y)) \
{ \
FP_SET_EXCEPTION(FP_EX_DENORM); \
_FP_FRAC_COPY_##wc(R, X); \
goto add_done; \
} \
else \
{ \
FP_SET_EXCEPTION(FP_EX_DENORM); \
_FP_FRAC_ADD_##wc(R, X, Y); \
if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
{ \
/* Normalized result. */ \
_FP_FRAC_HIGH_##fs(R) \
&= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
R##_e = 1; \
} \
goto add_done; \
} \
} \
else \
{ \
/* X and Y are NaN or Inf. */ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
R##_e = _FP_EXPMAX_##fs; \
if (_FP_FRAC_ZEROP_##wc(X)) \
_FP_FRAC_COPY_##wc(R, Y); \
else if (_FP_FRAC_ZEROP_##wc(Y)) \
_FP_FRAC_COPY_##wc(R, X); \
else \
_FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \
goto add_done; \
} \
} \
/* The exponents of X and Y, both normal, are equal. The \
implicit MSBs will always add to increase the \
exponent. */ \
_FP_FRAC_ADD_##wc(R, X, Y); \
R##_e = X##_e + 1; \
_FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
if (R##_e == _FP_EXPMAX_##fs) \
/* Overflow to infinity (depending on rounding mode). */ \
_FP_OVERFLOW_SEMIRAW(fs, wc, R); \
goto add_done; \
} \
add3: \
if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
{ \
/* Overflow. */ \
_FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
R##_e++; \
_FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
if (R##_e == _FP_EXPMAX_##fs) \
/* Overflow to infinity (depending on rounding mode). */ \
_FP_OVERFLOW_SEMIRAW(fs, wc, R); \
} \
add_done: ; \
} \
else \
{ \
/* Subtraction. */ \
int ediff = X##_e - Y##_e; \
if (ediff > 0) \
{ \
R##_e = X##_e; \
R##_s = X##_s; \
if (Y##_e == 0) \
{ \
/* Y is zero or denormalized. */ \
if (_FP_FRAC_ZEROP_##wc(Y)) \
{ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
_FP_FRAC_COPY_##wc(R, X); \
goto sub_done; \
} \
else \
{ \
FP_SET_EXCEPTION(FP_EX_DENORM); \
ediff--; \
if (ediff == 0) \
{ \
_FP_FRAC_SUB_##wc(R, X, Y); \
goto sub3; \
} \
if (X##_e == _FP_EXPMAX_##fs) \
{ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
_FP_FRAC_COPY_##wc(R, X); \
goto sub_done; \
} \
goto sub1; \
} \
} \
else if (X##_e == _FP_EXPMAX_##fs) \
{ \
/* X is NaN or Inf, Y is normal. */ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
_FP_FRAC_COPY_##wc(R, X); \
goto sub_done; \
} \
\
/* Insert implicit MSB of Y. */ \
_FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
\
sub1: \
/* Shift the mantissa of Y to the right EDIFF steps; \
remember to account later for the implicit MSB of X. */ \
if (ediff <= _FP_WFRACBITS_##fs) \
_FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \
else if (!_FP_FRAC_ZEROP_##wc(Y)) \
_FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
_FP_FRAC_SUB_##wc(R, X, Y); \
} \
else if (ediff < 0) \
{ \
ediff = -ediff; \
R##_e = Y##_e; \
R##_s = Y##_s; \
if (X##_e == 0) \
{ \
/* X is zero or denormalized. */ \
if (_FP_FRAC_ZEROP_##wc(X)) \
{ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
_FP_FRAC_COPY_##wc(R, Y); \
goto sub_done; \
} \
else \
{ \
FP_SET_EXCEPTION(FP_EX_DENORM); \
ediff--; \
if (ediff == 0) \
{ \
_FP_FRAC_SUB_##wc(R, Y, X); \
goto sub3; \
} \
if (Y##_e == _FP_EXPMAX_##fs) \
{ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
_FP_FRAC_COPY_##wc(R, Y); \
goto sub_done; \
} \
goto sub2; \
} \
} \
else if (Y##_e == _FP_EXPMAX_##fs) \
{ \
/* Y is NaN or Inf, X is normal. */ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
_FP_FRAC_COPY_##wc(R, Y); \
goto sub_done; \
} \
\
/* Insert implicit MSB of X. */ \
_FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
\
sub2: \
/* Shift the mantissa of X to the right EDIFF steps; \
remember to account later for the implicit MSB of Y. */ \
if (ediff <= _FP_WFRACBITS_##fs) \
_FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \
else if (!_FP_FRAC_ZEROP_##wc(X)) \
_FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
_FP_FRAC_SUB_##wc(R, Y, X); \
} \
else \
{ \
/* ediff == 0. */ \
if (!_FP_EXP_NORMAL(fs, wc, X)) \
{ \
if (X##_e == 0) \
{ \
/* X and Y are zero or denormalized. */ \
R##_e = 0; \
if (_FP_FRAC_ZEROP_##wc(X)) \
{ \
_FP_FRAC_COPY_##wc(R, Y); \
if (_FP_FRAC_ZEROP_##wc(Y)) \
R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
else \
{ \
FP_SET_EXCEPTION(FP_EX_DENORM); \
R##_s = Y##_s; \
} \
goto sub_done; \
} \
else if (_FP_FRAC_ZEROP_##wc(Y)) \
{ \
FP_SET_EXCEPTION(FP_EX_DENORM); \
_FP_FRAC_COPY_##wc(R, X); \
R##_s = X##_s; \
goto sub_done; \
} \
else \
{ \
FP_SET_EXCEPTION(FP_EX_DENORM); \
_FP_FRAC_SUB_##wc(R, X, Y); \
R##_s = X##_s; \
if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
{ \
/* |X| < |Y|, negate result. */ \
_FP_FRAC_SUB_##wc(R, Y, X); \
R##_s = Y##_s; \
} \
else if (_FP_FRAC_ZEROP_##wc(R)) \
R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
goto sub_done; \
} \
} \
else \
{ \
/* X and Y are NaN or Inf, of opposite signs. */ \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
R##_e = _FP_EXPMAX_##fs; \
if (_FP_FRAC_ZEROP_##wc(X)) \
{ \
if (_FP_FRAC_ZEROP_##wc(Y)) \
{ \
/* Inf - Inf. */ \
R##_s = _FP_NANSIGN_##fs; \
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
_FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \
FP_SET_EXCEPTION(FP_EX_INVALID); \
} \
else \
{ \
/* Inf - NaN. */ \
R##_s = Y##_s; \
_FP_FRAC_COPY_##wc(R, Y); \
} \
} \
else \
{ \
if (_FP_FRAC_ZEROP_##wc(Y)) \
{ \
/* NaN - Inf. */ \
R##_s = X##_s; \
_FP_FRAC_COPY_##wc(R, X); \
} \
else \
{ \
/* NaN - NaN. */ \
_FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \
} \
} \
goto sub_done; \
} \
} \
/* The exponents of X and Y, both normal, are equal. The \
implicit MSBs cancel. */ \
R##_e = X##_e; \
_FP_FRAC_SUB_##wc(R, X, Y); \
R##_s = X##_s; \
if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
{ \
/* |X| < |Y|, negate result. */ \
_FP_FRAC_SUB_##wc(R, Y, X); \
R##_s = Y##_s; \
} \
else if (_FP_FRAC_ZEROP_##wc(R)) \
{ \
R##_e = 0; \
R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
goto sub_done; \
} \
goto norm; \
} \
sub3: \
if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
{ \
int diff; \
/* Carry into most significant bit of larger one of X and Y, \
canceling it; renormalize. */ \
_FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \
norm: \
_FP_FRAC_CLZ_##wc(diff, R); \
diff -= _FP_WFRACXBITS_##fs; \
_FP_FRAC_SLL_##wc(R, diff); \
if (R##_e <= diff) \
{ \
/* R is denormalized. */ \
diff = diff - R##_e + 1; \
_FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \
R##_e = 0; \
} \
else \
{ \
R##_e -= diff; \
_FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
} \
} \
sub_done: ; \
} \
} while (0)
 
#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+')
#define _FP_SUB(fs, wc, R, X, Y) \
do { \
if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \
_FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \
} while (0)
 
 
/*
* Main negation routine. FIXME -- when we care about setting exception
* bits reliably, this will not do. We should examine all of the fp classes.
*/
 
#define _FP_NEG(fs, wc, R, X) \
do { \
_FP_FRAC_COPY_##wc(R, X); \
R##_c = X##_c; \
R##_e = X##_e; \
R##_s = 1 ^ X##_s; \
} while (0)
 
 
/*
* Main multiplication routine. The input values should be cooked.
*/
 
#define _FP_MUL(fs, wc, R, X, Y) \
do { \
R##_s = X##_s ^ Y##_s; \
switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
{ \
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
R##_c = FP_CLS_NORMAL; \
R##_e = X##_e + Y##_e + 1; \
\
_FP_MUL_MEAT_##fs(R,X,Y); \
\
if (_FP_FRAC_OVERP_##wc(fs, R)) \
_FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
else \
R##_e--; \
break; \
\
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
_FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \
break; \
\
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
R##_s = X##_s; \
\
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
_FP_FRAC_COPY_##wc(R, X); \
R##_c = X##_c; \
break; \
\
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
R##_s = Y##_s; \
\
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
_FP_FRAC_COPY_##wc(R, Y); \
R##_c = Y##_c; \
break; \
\
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
R##_s = _FP_NANSIGN_##fs; \
R##_c = FP_CLS_NAN; \
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
FP_SET_EXCEPTION(FP_EX_INVALID); \
break; \
\
default: \
abort(); \
} \
} while (0)
 
 
/*
* Main division routine. The input values should be cooked.
*/
 
#define _FP_DIV(fs, wc, R, X, Y) \
do { \
R##_s = X##_s ^ Y##_s; \
switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
{ \
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
R##_c = FP_CLS_NORMAL; \
R##_e = X##_e - Y##_e; \
\
_FP_DIV_MEAT_##fs(R,X,Y); \
break; \
\
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
_FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \
break; \
\
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
R##_s = X##_s; \
_FP_FRAC_COPY_##wc(R, X); \
R##_c = X##_c; \
break; \
\
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
R##_s = Y##_s; \
_FP_FRAC_COPY_##wc(R, Y); \
R##_c = Y##_c; \
break; \
\
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
R##_c = FP_CLS_ZERO; \
break; \
\
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
FP_SET_EXCEPTION(FP_EX_DIVZERO); \
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
R##_c = FP_CLS_INF; \
break; \
\
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
R##_s = _FP_NANSIGN_##fs; \
R##_c = FP_CLS_NAN; \
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
FP_SET_EXCEPTION(FP_EX_INVALID); \
break; \
\
default: \
abort(); \
} \
} while (0)
 
 
/*
* Main differential comparison routine. The inputs should be raw not
* cooked. The return is -1,0,1 for normal values, 2 otherwise.
*/
 
#define _FP_CMP(fs, wc, ret, X, Y, un) \
do { \
/* NANs are unordered */ \
if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
{ \
ret = un; \
} \
else \
{ \
int __is_zero_x; \
int __is_zero_y; \
\
__is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \
__is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \
\
if (__is_zero_x && __is_zero_y) \
ret = 0; \
else if (__is_zero_x) \
ret = Y##_s ? 1 : -1; \
else if (__is_zero_y) \
ret = X##_s ? -1 : 1; \
else if (X##_s != Y##_s) \
ret = X##_s ? -1 : 1; \
else if (X##_e > Y##_e) \
ret = X##_s ? -1 : 1; \
else if (X##_e < Y##_e) \
ret = X##_s ? 1 : -1; \
else if (_FP_FRAC_GT_##wc(X, Y)) \
ret = X##_s ? -1 : 1; \
else if (_FP_FRAC_GT_##wc(Y, X)) \
ret = X##_s ? 1 : -1; \
else \
ret = 0; \
} \
} while (0)
 
 
/* Simplification for strict equality. */
 
#define _FP_CMP_EQ(fs, wc, ret, X, Y) \
do { \
/* NANs are unordered */ \
if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
{ \
ret = 1; \
} \
else \
{ \
ret = !(X##_e == Y##_e \
&& _FP_FRAC_EQ_##wc(X, Y) \
&& (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \
} \
} while (0)
 
/* Version to test unordered. */
 
#define _FP_CMP_UNORD(fs, wc, ret, X, Y) \
do { \
ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \
} while (0)
 
/*
* Main square root routine. The input value should be cooked.
*/
 
#define _FP_SQRT(fs, wc, R, X) \
do { \
_FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \
_FP_W_TYPE q; \
switch (X##_c) \
{ \
case FP_CLS_NAN: \
_FP_FRAC_COPY_##wc(R, X); \
R##_s = X##_s; \
R##_c = FP_CLS_NAN; \
break; \
case FP_CLS_INF: \
if (X##_s) \
{ \
R##_s = _FP_NANSIGN_##fs; \
R##_c = FP_CLS_NAN; /* NAN */ \
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
FP_SET_EXCEPTION(FP_EX_INVALID); \
} \
else \
{ \
R##_s = 0; \
R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
} \
break; \
case FP_CLS_ZERO: \
R##_s = X##_s; \
R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \
break; \
case FP_CLS_NORMAL: \
R##_s = 0; \
if (X##_s) \
{ \
R##_c = FP_CLS_NAN; /* sNAN */ \
R##_s = _FP_NANSIGN_##fs; \
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
FP_SET_EXCEPTION(FP_EX_INVALID); \
break; \
} \
R##_c = FP_CLS_NORMAL; \
if (X##_e & 1) \
_FP_FRAC_SLL_##wc(X, 1); \
R##_e = X##_e >> 1; \
_FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \
_FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \
q = _FP_OVERFLOW_##fs >> 1; \
_FP_SQRT_MEAT_##wc(R, S, T, X, q); \
} \
} while (0)
 
/*
* Convert from FP to integer. Input is raw.
*/
 
/* RSIGNED can have following values:
* 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus
* the result is either 0 or (2^rsize)-1 depending on the sign in such
* case.
* 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
* NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
* depending on the sign in such case.
* -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
* set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
* depending on the sign in such case.
*/
#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
do { \
if (X##_e < _FP_EXPBIAS_##fs) \
{ \
r = 0; \
if (X##_e == 0) \
{ \
if (!_FP_FRAC_ZEROP_##wc(X)) \
{ \
FP_SET_EXCEPTION(FP_EX_INEXACT); \
FP_SET_EXCEPTION(FP_EX_DENORM); \
} \
} \
else \
FP_SET_EXCEPTION(FP_EX_INEXACT); \
} \
else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \
|| (!rsigned && X##_s)) \
{ \
/* Overflow or converting to the most negative integer. */ \
if (rsigned) \
{ \
r = 1; \
r <<= rsize - 1; \
r -= 1 - X##_s; \
} else { \
r = 0; \
if (X##_s) \
r = ~r; \
} \
\
if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \
{ \
/* Possibly converting to most negative integer; check the \
mantissa. */ \
int inexact = 0; \
(void)((_FP_FRACBITS_##fs > rsize) \
? ({ _FP_FRAC_SRST_##wc(X, inexact, \
_FP_FRACBITS_##fs - rsize, \
_FP_FRACBITS_##fs); 0; }) \
: 0); \
if (!_FP_FRAC_ZEROP_##wc(X)) \
FP_SET_EXCEPTION(FP_EX_INVALID); \
else if (inexact) \
FP_SET_EXCEPTION(FP_EX_INEXACT); \
} \
else \
FP_SET_EXCEPTION(FP_EX_INVALID); \
} \
else \
{ \
_FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \
if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \
{ \
_FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \
} \
else \
{ \
int inexact; \
_FP_FRAC_SRST_##wc(X, inexact, \
(_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \
- X##_e), \
_FP_FRACBITS_##fs); \
if (inexact) \
FP_SET_EXCEPTION(FP_EX_INEXACT); \
_FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
} \
if (rsigned && X##_s) \
r = -r; \
} \
} while (0)
 
/* Convert integer to fp. Output is raw. RTYPE is unsigned even if
input is signed. */
#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
do { \
if (r) \
{ \
rtype ur_; \
\
if ((X##_s = (r < 0))) \
r = -(rtype)r; \
\
ur_ = (rtype) r; \
(void)((rsize <= _FP_W_TYPE_SIZE) \
? ({ \
int lz_; \
__FP_CLZ(lz_, (_FP_W_TYPE)ur_); \
X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \
}) \
: ((rsize <= 2 * _FP_W_TYPE_SIZE) \
? ({ \
int lz_; \
__FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \
(_FP_W_TYPE)ur_); \
X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \
- lz_); \
}) \
: (abort(), 0))); \
\
if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \
&& X##_e >= _FP_EXPMAX_##fs) \
{ \
/* Exponent too big; overflow to infinity. (May also \
happen after rounding below.) */ \
_FP_OVERFLOW_SEMIRAW(fs, wc, X); \
goto pack_semiraw; \
} \
\
if (rsize <= _FP_FRACBITS_##fs \
|| X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \
{ \
/* Exactly representable; shift left. */ \
_FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
_FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \
+ _FP_FRACBITS_##fs - 1 - X##_e)); \
} \
else \
{ \
/* More bits in integer than in floating type; need to \
round. */ \
if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \
ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \
- _FP_WFRACBITS_##fs + 1)) \
| ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \
- _FP_WFRACBITS_##fs + 1))) \
!= 0)); \
_FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \
_FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \
+ _FP_WFRACBITS_##fs - 1 - X##_e)); \
_FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
pack_semiraw: \
_FP_PACK_SEMIRAW(fs, wc, X); \
} \
} \
else \
{ \
X##_s = 0; \
X##_e = 0; \
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
} \
} while (0)
 
 
/* Extend from a narrower floating-point format to a wider one. Input
and output are raw. */
#define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \
do { \
if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \
|| (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \
< _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \
|| (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \
&& _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \
abort(); \
D##_s = S##_s; \
_FP_FRAC_COPY_##dwc##_##swc(D, S); \
if (_FP_EXP_NORMAL(sfs, swc, S)) \
{ \
D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
_FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \
} \
else \
{ \
if (S##_e == 0) \
{ \
if (_FP_FRAC_ZEROP_##swc(S)) \
D##_e = 0; \
else if (_FP_EXPBIAS_##dfs \
< _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \
{ \
FP_SET_EXCEPTION(FP_EX_DENORM); \
_FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \
- _FP_FRACBITS_##sfs)); \
D##_e = 0; \
} \
else \
{ \
int _lz; \
FP_SET_EXCEPTION(FP_EX_DENORM); \
_FP_FRAC_CLZ_##swc(_lz, S); \
_FP_FRAC_SLL_##dwc(D, \
_lz + _FP_FRACBITS_##dfs \
- _FP_FRACTBITS_##sfs); \
D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \
+ _FP_FRACXBITS_##sfs - _lz); \
} \
} \
else \
{ \
D##_e = _FP_EXPMAX_##dfs; \
if (!_FP_FRAC_ZEROP_##swc(S)) \
{ \
if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs)) \
FP_SET_EXCEPTION(FP_EX_INVALID); \
_FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \
- _FP_FRACBITS_##sfs)); \
} \
} \
} \
} while (0)
 
/* Truncate from a wider floating-point format to a narrower one.
Input and output are semi-raw. */
#define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \
do { \
if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \
|| (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \
&& _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \
abort(); \
D##_s = S##_s; \
if (_FP_EXP_NORMAL(sfs, swc, S)) \
{ \
D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
if (D##_e >= _FP_EXPMAX_##dfs) \
_FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \
else \
{ \
if (D##_e <= 0) \
{ \
if (D##_e < 1 - _FP_FRACBITS_##dfs) \
{ \
_FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \
_FP_FRAC_LOW_##swc(S) |= 1; \
} \
else \
{ \
_FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \
_FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
- _FP_WFRACBITS_##dfs + 1 - D##_e), \
_FP_WFRACBITS_##sfs); \
} \
D##_e = 0; \
} \
else \
_FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
- _FP_WFRACBITS_##dfs), \
_FP_WFRACBITS_##sfs); \
_FP_FRAC_COPY_##dwc##_##swc(D, S); \
} \
} \
else \
{ \
if (S##_e == 0) \
{ \
D##_e = 0; \
if (_FP_FRAC_ZEROP_##swc(S)) \
_FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
else \
{ \
FP_SET_EXCEPTION(FP_EX_DENORM); \
if (_FP_EXPBIAS_##sfs \
< _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \
{ \
_FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
- _FP_WFRACBITS_##dfs), \
_FP_WFRACBITS_##sfs); \
_FP_FRAC_COPY_##dwc##_##swc(D, S); \
} \
else \
{ \
_FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
_FP_FRAC_LOW_##dwc(D) |= 1; \
} \
} \
} \
else \
{ \
D##_e = _FP_EXPMAX_##dfs; \
if (_FP_FRAC_ZEROP_##swc(S)) \
_FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
else \
{ \
_FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \
_FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \
- _FP_WFRACBITS_##dfs)); \
_FP_FRAC_COPY_##dwc##_##swc(D, S); \
/* Semi-raw NaN must have all workbits cleared. */ \
_FP_FRAC_LOW_##dwc(D) \
&= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \
_FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs; \
} \
} \
} \
} while (0)
 
/*
* Helper primitives.
*/
 
/* Count leading zeros in a word. */
 
#ifndef __FP_CLZ
/* GCC 3.4 and later provide the builtins for us. */
#define __FP_CLZ(r, x) \
do { \
if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \
r = __builtin_clz (x); \
else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \
r = __builtin_clzl (x); \
else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \
r = __builtin_clzll (x); \
else \
abort (); \
} while (0)
#endif /* ndef __FP_CLZ */
 
#define _FP_DIV_HELP_imm(q, r, n, d) \
do { \
q = n / d, r = n % d; \
} while (0)
 
 
/* A restoring bit-by-bit division primitive. */
 
#define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \
do { \
int count = _FP_WFRACBITS_##fs; \
_FP_FRAC_DECL_##wc (u); \
_FP_FRAC_DECL_##wc (v); \
_FP_FRAC_COPY_##wc (u, X); \
_FP_FRAC_COPY_##wc (v, Y); \
_FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \
/* Normalize U and V. */ \
_FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \
_FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \
/* First round. Since the operands are normalized, either the \
first or second bit will be set in the fraction. Produce a \
normalized result by checking which and adjusting the loop \
count and exponent accordingly. */ \
if (_FP_FRAC_GE_1 (u, v)) \
{ \
_FP_FRAC_SUB_##wc (u, u, v); \
_FP_FRAC_LOW_##wc (R) |= 1; \
count--; \
} \
else \
R##_e--; \
/* Subsequent rounds. */ \
do { \
int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \
_FP_FRAC_SLL_##wc (u, 1); \
_FP_FRAC_SLL_##wc (R, 1); \
if (msb || _FP_FRAC_GE_1 (u, v)) \
{ \
_FP_FRAC_SUB_##wc (u, u, v); \
_FP_FRAC_LOW_##wc (R) |= 1; \
} \
} while (--count > 0); \
/* If there's anything left in U, the result is inexact. */ \
_FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \
} while (0)
 
#define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y)
#define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y)
#define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y)
/programs/develop/libraries/newlib/math/pow.c
0,0 → 1,781
/* pow.c
*
* Power function
*
*
*
* SYNOPSIS:
*
* double x, y, z, pow();
*
* z = pow( x, y );
*
*
*
* DESCRIPTION:
*
* Computes x raised to the yth power. Analytically,
*
* x**y = exp( y log(x) ).
*
* Following Cody and Waite, this program uses a lookup table
* of 2**-i/16 and pseudo extended precision arithmetic to
* obtain an extra three bits of accuracy in both the logarithm
* and the exponential.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE -26,26 30000 4.2e-16 7.7e-17
* DEC -26,26 60000 4.8e-17 9.1e-18
* 1/26 < x < 26, with log(x) uniformly distributed.
* -26 < y < 26, y uniformly distributed.
* IEEE 0,8700 30000 1.5e-14 2.1e-15
* 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed.
*
*
* ERROR MESSAGES:
*
* message condition value returned
* pow overflow x**y > MAXNUM INFINITY
* pow underflow x**y < 1/MAXNUM 0.0
* pow domain x<0 and y noninteger 0.0
*
*/
/*
Cephes Math Library Release 2.8: June, 2000
Copyright 1984, 1995, 2000 by Stephen L. Moshier
*/
 
/*
Modified for mingw
2002-09-27 Danny Smith <dannysmith@users.sourceforge.net>
*/
 
#ifdef __MINGW32__
#include "cephes_mconf.h"
#else
#include "mconf.h"
static char fname[] = {"pow"};
#endif
 
#ifndef _SET_ERRNO
#define _SET_ERRNO(x)
#endif
 
#define SQRTH 0.70710678118654752440
 
#ifdef UNK
static double P[] = {
4.97778295871696322025E-1,
3.73336776063286838734E0,
7.69994162726912503298E0,
4.66651806774358464979E0
};
static double Q[] = {
/* 1.00000000000000000000E0, */
9.33340916416696166113E0,
2.79999886606328401649E1,
3.35994905342304405431E1,
1.39995542032307539578E1
};
/* 2^(-i/16), IEEE precision */
static double A[] = {
1.00000000000000000000E0,
9.57603280698573700036E-1,
9.17004043204671215328E-1,
8.78126080186649726755E-1,
8.40896415253714502036E-1,
8.05245165974627141736E-1,
7.71105412703970372057E-1,
7.38413072969749673113E-1,
7.07106781186547572737E-1,
6.77127773468446325644E-1,
6.48419777325504820276E-1,
6.20928906036742001007E-1,
5.94603557501360513449E-1,
5.69394317378345782288E-1,
5.45253866332628844837E-1,
5.22136891213706877402E-1,
5.00000000000000000000E-1
};
static double B[] = {
0.00000000000000000000E0,
1.64155361212281360176E-17,
4.09950501029074826006E-17,
3.97491740484881042808E-17,
-4.83364665672645672553E-17,
1.26912513974441574796E-17,
1.99100761573282305549E-17,
-1.52339103990623557348E-17,
0.00000000000000000000E0
};
static double R[] = {
1.49664108433729301083E-5,
1.54010762792771901396E-4,
1.33335476964097721140E-3,
9.61812908476554225149E-3,
5.55041086645832347466E-2,
2.40226506959099779976E-1,
6.93147180559945308821E-1
};
 
#define douba(k) A[k]
#define doubb(k) B[k]
#define MEXP 16383.0
#ifdef DENORMAL
#define MNEXP -17183.0
#else
#define MNEXP -16383.0
#endif
#endif
 
#ifdef DEC
static unsigned short P[] = {
0037776,0156313,0175332,0163602,
0040556,0167577,0052366,0174245,
0040766,0062753,0175707,0055564,
0040625,0052035,0131344,0155636,
};
static unsigned short Q[] = {
/*0040200,0000000,0000000,0000000,*/
0041025,0052644,0154404,0105155,
0041337,0177772,0007016,0047646,
0041406,0062740,0154273,0020020,
0041137,0177054,0106127,0044555,
};
static unsigned short A[] = {
0040200,0000000,0000000,0000000,
0040165,0022575,0012444,0103314,
0040152,0140306,0163735,0022071,
0040140,0146336,0166052,0112341,
0040127,0042374,0145326,0116553,
0040116,0022214,0012437,0102201,
0040105,0063452,0010525,0003333,
0040075,0004243,0117530,0006067,
0040065,0002363,0031771,0157145,
0040055,0054076,0165102,0120513,
0040045,0177326,0124661,0050471,
0040036,0172462,0060221,0120422,
0040030,0033760,0050615,0134251,
0040021,0141723,0071653,0010703,
0040013,0112701,0161752,0105727,
0040005,0125303,0063714,0044173,
0040000,0000000,0000000,0000000
};
static unsigned short B[] = {
0000000,0000000,0000000,0000000,
0021473,0040265,0153315,0140671,
0121074,0062627,0042146,0176454,
0121413,0003524,0136332,0066212,
0121767,0046404,0166231,0012553,
0121257,0015024,0002357,0043574,
0021736,0106532,0043060,0056206,
0121310,0020334,0165705,0035326,
0000000,0000000,0000000,0000000
};
 
static unsigned short R[] = {
0034173,0014076,0137624,0115771,
0035041,0076763,0003744,0111311,
0035656,0141766,0041127,0074351,
0036435,0112533,0073611,0116664,
0037143,0054106,0134040,0152223,
0037565,0176757,0176026,0025551,
0040061,0071027,0173721,0147572
};
 
/*
static double R[] = {
0.14928852680595608186e-4,
0.15400290440989764601e-3,
0.13333541313585784703e-2,
0.96181290595172416964e-2,
0.55504108664085595326e-1,
0.24022650695909537056e0,
0.69314718055994529629e0
};
*/
#define douba(k) (*(double *)&A[(k)<<2])
#define doubb(k) (*(double *)&B[(k)<<2])
#define MEXP 2031.0
#define MNEXP -2031.0
#endif
 
#ifdef IBMPC
static const unsigned short P[] = {
0x5cf0,0x7f5b,0xdb99,0x3fdf,
0xdf15,0xea9e,0xddef,0x400d,
0xeb6f,0x7f78,0xccbd,0x401e,
0x9b74,0xb65c,0xaa83,0x4012,
};
static const unsigned short Q[] = {
/*0x0000,0x0000,0x0000,0x3ff0,*/
0x914e,0x9b20,0xaab4,0x4022,
0xc9f5,0x41c1,0xffff,0x403b,
0x6402,0x1b17,0xccbc,0x4040,
0xe92e,0x918a,0xffc5,0x402b,
};
static const unsigned short A[] = {
0x0000,0x0000,0x0000,0x3ff0,
0x90da,0xa2a4,0xa4af,0x3fee,
0xa487,0xdcfb,0x5818,0x3fed,
0x529c,0xdd85,0x199b,0x3fec,
0xd3ad,0x995a,0xe89f,0x3fea,
0xf090,0x82a3,0xc491,0x3fe9,
0xa0db,0x422a,0xace5,0x3fe8,
0x0187,0x73eb,0xa114,0x3fe7,
0x3bcd,0x667f,0xa09e,0x3fe6,
0x5429,0xdd48,0xab07,0x3fe5,
0x2a27,0xd536,0xbfda,0x3fe4,
0x3422,0x4c12,0xdea6,0x3fe3,
0xb715,0x0a31,0x06fe,0x3fe3,
0x6238,0x6e75,0x387a,0x3fe2,
0x517b,0x3c7d,0x72b8,0x3fe1,
0x890f,0x6cf9,0xb558,0x3fe0,
0x0000,0x0000,0x0000,0x3fe0
};
static const unsigned short B[] = {
0x0000,0x0000,0x0000,0x0000,
0x3707,0xd75b,0xed02,0x3c72,
0xcc81,0x345d,0xa1cd,0x3c87,
0x4b27,0x5686,0xe9f1,0x3c86,
0x6456,0x13b2,0xdd34,0xbc8b,
0x42e2,0xafec,0x4397,0x3c6d,
0x82e4,0xd231,0xf46a,0x3c76,
0x8a76,0xb9d7,0x9041,0xbc71,
0x0000,0x0000,0x0000,0x0000
};
static const unsigned short R[] = {
0x937f,0xd7f2,0x6307,0x3eef,
0x9259,0x60fc,0x2fbe,0x3f24,
0xef1d,0xc84a,0xd87e,0x3f55,
0x33b7,0x6ef1,0xb2ab,0x3f83,
0x1a92,0xd704,0x6b08,0x3fac,
0xc56d,0xff82,0xbfbd,0x3fce,
0x39ef,0xfefa,0x2e42,0x3fe6
};
 
#define douba(k) (*(double *)&A[(k)<<2])
#define doubb(k) (*(double *)&B[(k)<<2])
#define MEXP 16383.0
#ifdef DENORMAL
#define MNEXP -17183.0
#else
#define MNEXP -16383.0
#endif
#endif
 
#ifdef MIEEE
static unsigned short P[] = {
0x3fdf,0xdb99,0x7f5b,0x5cf0,
0x400d,0xddef,0xea9e,0xdf15,
0x401e,0xccbd,0x7f78,0xeb6f,
0x4012,0xaa83,0xb65c,0x9b74
};
static unsigned short Q[] = {
0x4022,0xaab4,0x9b20,0x914e,
0x403b,0xffff,0x41c1,0xc9f5,
0x4040,0xccbc,0x1b17,0x6402,
0x402b,0xffc5,0x918a,0xe92e
};
static unsigned short A[] = {
0x3ff0,0x0000,0x0000,0x0000,
0x3fee,0xa4af,0xa2a4,0x90da,
0x3fed,0x5818,0xdcfb,0xa487,
0x3fec,0x199b,0xdd85,0x529c,
0x3fea,0xe89f,0x995a,0xd3ad,
0x3fe9,0xc491,0x82a3,0xf090,
0x3fe8,0xace5,0x422a,0xa0db,
0x3fe7,0xa114,0x73eb,0x0187,
0x3fe6,0xa09e,0x667f,0x3bcd,
0x3fe5,0xab07,0xdd48,0x5429,
0x3fe4,0xbfda,0xd536,0x2a27,
0x3fe3,0xdea6,0x4c12,0x3422,
0x3fe3,0x06fe,0x0a31,0xb715,
0x3fe2,0x387a,0x6e75,0x6238,
0x3fe1,0x72b8,0x3c7d,0x517b,
0x3fe0,0xb558,0x6cf9,0x890f,
0x3fe0,0x0000,0x0000,0x0000
};
static unsigned short B[] = {
0x0000,0x0000,0x0000,0x0000,
0x3c72,0xed02,0xd75b,0x3707,
0x3c87,0xa1cd,0x345d,0xcc81,
0x3c86,0xe9f1,0x5686,0x4b27,
0xbc8b,0xdd34,0x13b2,0x6456,
0x3c6d,0x4397,0xafec,0x42e2,
0x3c76,0xf46a,0xd231,0x82e4,
0xbc71,0x9041,0xb9d7,0x8a76,
0x0000,0x0000,0x0000,0x0000
};
static unsigned short R[] = {
0x3eef,0x6307,0xd7f2,0x937f,
0x3f24,0x2fbe,0x60fc,0x9259,
0x3f55,0xd87e,0xc84a,0xef1d,
0x3f83,0xb2ab,0x6ef1,0x33b7,
0x3fac,0x6b08,0xd704,0x1a92,
0x3fce,0xbfbd,0xff82,0xc56d,
0x3fe6,0x2e42,0xfefa,0x39ef
};
 
#define douba(k) (*(double *)&A[(k)<<2])
#define doubb(k) (*(double *)&B[(k)<<2])
#define MEXP 16383.0
#ifdef DENORMAL
#define MNEXP -17183.0
#else
#define MNEXP -16383.0
#endif
#endif
 
/* log2(e) - 1 */
#define LOG2EA 0.44269504088896340736
 
#define F W
#define Fa Wa
#define Fb Wb
#define G W
#define Ga Wa
#define Gb u
#define H W
#define Ha Wb
#define Hb Wb
 
#ifdef __MINGW32__
static __inline__ double reduc( double );
extern double __powi ( double, int );
extern double pow ( double x, double y);
 
#else /* __MINGW32__ */
 
#ifdef ANSIPROT
extern double floor ( double );
extern double fabs ( double );
extern double frexp ( double, int * );
extern double ldexp ( double, int );
extern double polevl ( double, void *, int );
extern double p1evl ( double, void *, int );
extern double __powi ( double, int );
extern int signbit ( double );
extern int isnan ( double );
extern int isfinite ( double );
static double reduc ( double );
#else
double floor(), fabs(), frexp(), ldexp();
double polevl(), p1evl(), __powi();
int signbit(), isnan(), isfinite();
static double reduc();
#endif
extern double MAXNUM;
#ifdef INFINITIES
extern double INFINITY;
#endif
#ifdef NANS
extern double NAN;
#endif
#ifdef MINUSZERO
extern double NEGZERO;
#endif
 
#endif /* __MINGW32__ */
 
double pow( x, y )
double x, y;
{
double w, z, W, Wa, Wb, ya, yb, u;
/* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */
double aw, ay, wy;
int e, i, nflg, iyflg, yoddint;
 
if( y == 0.0 )
return( 1.0 );
#ifdef NANS
if( isnan(x) || isnan(y) )
{
_SET_ERRNO (EDOM);
return( x + y );
}
#endif
if( y == 1.0 )
return( x );
 
 
#ifdef INFINITIES
if( !isfinite(y) && (x == 1.0 || x == -1.0) )
{
mtherr( "pow", DOMAIN );
#ifdef NANS
return( NAN );
#else
return( INFINITY );
#endif
}
#endif
 
if( x == 1.0 )
return( 1.0 );
 
if( y >= MAXNUM )
{
_SET_ERRNO (ERANGE);
#ifdef INFINITIES
if( x > 1.0 )
return( INFINITY );
#else
if( x > 1.0 )
return( MAXNUM );
#endif
if( x > 0.0 && x < 1.0 )
return( 0.0);
if( x < -1.0 )
{
#ifdef INFINITIES
return( INFINITY );
#else
return( MAXNUM );
#endif
}
if( x > -1.0 && x < 0.0 )
return( 0.0 );
}
if( y <= -MAXNUM )
{
_SET_ERRNO (ERANGE);
if( x > 1.0 )
return( 0.0 );
#ifdef INFINITIES
if( x > 0.0 && x < 1.0 )
return( INFINITY );
#else
if( x > 0.0 && x < 1.0 )
return( MAXNUM );
#endif
if( x < -1.0 )
return( 0.0 );
#ifdef INFINITIES
if( x > -1.0 && x < 0.0 )
return( INFINITY );
#else
if( x > -1.0 && x < 0.0 )
return( MAXNUM );
#endif
}
if( x >= MAXNUM )
{
#if INFINITIES
if( y > 0.0 )
return( INFINITY );
#else
if( y > 0.0 )
return( MAXNUM );
#endif
return(0.0);
}
/* Set iyflg to 1 if y is an integer. */
iyflg = 0;
w = floor(y);
if( w == y )
iyflg = 1;
 
/* Test for odd integer y. */
yoddint = 0;
if( iyflg )
{
ya = fabs(y);
ya = floor(0.5 * ya);
yb = 0.5 * fabs(w);
if( ya != yb )
yoddint = 1;
}
 
if( x <= -MAXNUM )
{
if( y > 0.0 )
{
#ifdef INFINITIES
if( yoddint )
return( -INFINITY );
return( INFINITY );
#else
if( yoddint )
return( -MAXNUM );
return( MAXNUM );
#endif
}
if( y < 0.0 )
{
#ifdef MINUSZERO
if( yoddint )
return( NEGZERO );
#endif
return( 0.0 );
}
}
 
nflg = 0; /* flag = 1 if x<0 raised to integer power */
if( x <= 0.0 )
{
if( x == 0.0 )
{
if( y < 0.0 )
{
#ifdef MINUSZERO
if( signbit(x) && yoddint )
return( -INFINITY );
#endif
#ifdef INFINITIES
return( INFINITY );
#else
return( MAXNUM );
#endif
}
if( y > 0.0 )
{
#ifdef MINUSZERO
if( signbit(x) && yoddint )
return( NEGZERO );
#endif
return( 0.0 );
}
return( 1.0 );
}
else
{
if( iyflg == 0 )
{ /* noninteger power of negative number */
mtherr( fname, DOMAIN );
_SET_ERRNO (EDOM);
#ifdef NANS
return(NAN);
#else
return(0.0L);
#endif
}
nflg = 1;
}
}
 
/* Integer power of an integer. */
 
if( iyflg )
{
i = w;
w = floor(x);
if( (w == x) && (fabs(y) < 32768.0) )
{
w = __powi( x, (int) y );
return( w );
}
}
 
if( nflg )
x = fabs(x);
 
/* For results close to 1, use a series expansion. */
w = x - 1.0;
aw = fabs(w);
ay = fabs(y);
wy = w * y;
ya = fabs(wy);
if((aw <= 1.0e-3 && ay <= 1.0)
|| (ya <= 1.0e-3 && ay >= 1.0))
{
z = (((((w*(y-5.)/720. + 1./120.)*w*(y-4.) + 1./24.)*w*(y-3.)
+ 1./6.)*w*(y-2.) + 0.5)*w*(y-1.) )*wy + wy + 1.;
goto done;
}
/* These are probably too much trouble. */
#if 0
w = y * log(x);
if (aw > 1.0e-3 && fabs(w) < 1.0e-3)
{
z = ((((((
w/7. + 1.)*w/6. + 1.)*w/5. + 1.)*w/4. + 1.)*w/3. + 1.)*w/2. + 1.)*w + 1.;
goto done;
}
 
if(ya <= 1.0e-3 && aw <= 1.0e-4)
{
z = (((((
wy*1./720.
+ (-w*1./48. + 1./120.) )*wy
+ ((w*17./144. - 1./12.)*w + 1./24.) )*wy
+ (((-w*5./16. + 7./24.)*w - 1./4.)*w + 1./6.) )*wy
+ ((((w*137./360. - 5./12.)*w + 11./24.)*w - 1./2.)*w + 1./2.) )*wy
+ (((((-w*1./6. + 1./5.)*w - 1./4)*w + 1./3.)*w -1./2.)*w ) )*wy
+ wy + 1.0;
goto done;
}
#endif
 
/* separate significand from exponent */
x = frexp( x, &e );
 
#if 0
/* For debugging, check for gross overflow. */
if( (e * y) > (MEXP + 1024) )
goto overflow;
#endif
 
/* Find significand of x in antilog table A[]. */
i = 1;
if( x <= douba(9) )
i = 9;
if( x <= douba(i+4) )
i += 4;
if( x <= douba(i+2) )
i += 2;
if( x >= douba(1) )
i = -1;
i += 1;
 
 
/* Find (x - A[i])/A[i]
* in order to compute log(x/A[i]):
*
* log(x) = log( a x/a ) = log(a) + log(x/a)
*
* log(x/a) = log(1+v), v = x/a - 1 = (x-a)/a
*/
x -= douba(i);
x -= doubb(i/2);
x /= douba(i);
 
 
/* rational approximation for log(1+v):
*
* log(1+v) = v - v**2/2 + v**3 P(v) / Q(v)
*/
z = x*x;
w = x * ( z * polevl( x, P, 3 ) / p1evl( x, Q, 4 ) );
w = w - ldexp( z, -1 ); /* w - 0.5 * z */
 
/* Convert to base 2 logarithm:
* multiply by log2(e)
*/
w = w + LOG2EA * w;
/* Note x was not yet added in
* to above rational approximation,
* so do it now, while multiplying
* by log2(e).
*/
z = w + LOG2EA * x;
z = z + x;
 
/* Compute exponent term of the base 2 logarithm. */
w = -i;
w = ldexp( w, -4 ); /* divide by 16 */
w += e;
/* Now base 2 log of x is w + z. */
 
/* Multiply base 2 log by y, in extended precision. */
 
/* separate y into large part ya
* and small part yb less than 1/16
*/
ya = reduc(y);
yb = y - ya;
 
 
F = z * y + w * yb;
Fa = reduc(F);
Fb = F - Fa;
 
G = Fa + w * ya;
Ga = reduc(G);
Gb = G - Ga;
 
H = Fb + Gb;
Ha = reduc(H);
w = ldexp( Ga+Ha, 4 );
 
/* Test the power of 2 for overflow */
if( w > MEXP )
{
#ifndef INFINITIES
mtherr( fname, OVERFLOW );
#endif
#ifdef INFINITIES
if( nflg && yoddint )
return( -INFINITY );
return( INFINITY );
#else
if( nflg && yoddint )
return( -MAXNUM );
return( MAXNUM );
#endif
}
 
if( w < (MNEXP - 1) )
{
#ifndef DENORMAL
mtherr( fname, UNDERFLOW );
#endif
#ifdef MINUSZERO
if( nflg && yoddint )
return( NEGZERO );
#endif
return( 0.0 );
}
 
e = w;
Hb = H - Ha;
 
if( Hb > 0.0 )
{
e += 1;
Hb -= 0.0625;
}
 
/* Now the product y * log2(x) = Hb + e/16.0.
*
* Compute base 2 exponential of Hb,
* where -0.0625 <= Hb <= 0.
*/
z = Hb * polevl( Hb, R, 6 ); /* z = 2**Hb - 1 */
 
/* Express e/16 as an integer plus a negative number of 16ths.
* Find lookup table entry for the fractional power of 2.
*/
if( e < 0 )
i = 0;
else
i = 1;
i = e/16 + i;
e = 16*i - e;
w = douba( e );
z = w + w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */
z = ldexp( z, i ); /* multiply by integer power of 2 */
 
done:
 
/* Negate if odd integer power of negative number */
if( nflg && yoddint )
{
#ifdef MINUSZERO
if( z == 0.0 )
z = NEGZERO;
else
#endif
z = -z;
}
return( z );
}
 
 
/* Find a multiple of 1/16 that is within 1/16 of x. */
static __inline__ double reduc(x)
double x;
{
double t;
 
t = ldexp( x, 4 );
t = floor( t );
t = ldexp( t, -4 );
return(t);
}
/programs/develop/libraries/newlib/math/powf.c
0,0 → 1,3
#include <math.h>
float powf (float x, float y)
{return (float) pow (x, y);}
/programs/develop/libraries/newlib/math/powi.c
0,0 → 1,200
/* powi.c
*
* Real raised to integer power
*
*
*
* SYNOPSIS:
*
* double x, y, __powi();
* int n;
*
* y = __powi( x, n );
*
*
*
* DESCRIPTION:
*
* Returns argument x raised to the nth power.
* The routine efficiently decomposes n as a sum of powers of
* two. The desired power is a product of two-to-the-kth
* powers of x. Thus to compute the 32767 power of x requires
* 28 multiplications instead of 32767 multiplications.
*
*
*
* ACCURACY:
*
*
* Relative error:
* arithmetic x domain n domain # trials peak rms
* DEC .04,26 -26,26 100000 2.7e-16 4.3e-17
* IEEE .04,26 -26,26 50000 2.0e-15 3.8e-16
* IEEE 1,2 -1022,1023 50000 8.6e-14 1.6e-14
*
* Returns MAXNUM on overflow, zero on underflow.
*
*/
/* powi.c */
 
/*
Cephes Math Library Release 2.8: June, 2000
Copyright 1984, 1995, 2000 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"
#ifdef ANSIPROT
extern double log ( double );
extern double frexp ( double, int * );
extern int signbit ( double );
#else
double log(), frexp();
int signbit();
#endif
extern double NEGZERO, INFINITY, MAXNUM, MAXLOG, MINLOG, LOGE2;
#endif /* __MINGW32__ */
 
#ifndef _SET_ERRNO
#define _SET_ERRNO(x)
#endif
 
double __powi( x, nn )
double x;
int nn;
{
int n, e, sign, asign, lx;
double w, y, s;
 
/* See pow.c for these tests. */
if( x == 0.0 )
{
if( nn == 0 )
return( 1.0 );
else if( nn < 0 )
return( INFINITY );
else
{
if( nn & 1 )
return( x );
else
return( 0.0 );
}
}
 
if( nn == 0 )
return( 1.0 );
 
if( nn == -1 )
return( 1.0/x );
 
if( x < 0.0 )
{
asign = -1;
x = -x;
}
else
asign = 0;
 
 
if( nn < 0 )
{
sign = -1;
n = -nn;
}
else
{
sign = 1;
n = nn;
}
 
/* Even power will be positive. */
if( (n & 1) == 0 )
asign = 0;
 
/* Overflow detection */
 
/* Calculate approximate logarithm of answer */
s = frexp( x, &lx );
e = (lx - 1)*n;
if( (e == 0) || (e > 64) || (e < -64) )
{
s = (s - 7.0710678118654752e-1) / (s + 7.0710678118654752e-1);
s = (2.9142135623730950 * s - 0.5 + lx) * nn * LOGE2;
}
else
{
s = LOGE2 * e;
}
 
if( s > MAXLOG )
{
mtherr( "powi", OVERFLOW );
_SET_ERRNO(ERANGE);
y = INFINITY;
goto done;
}
 
#if DENORMAL
if( s < MINLOG )
{
y = 0.0;
goto done;
}
 
/* Handle tiny denormal answer, but with less accuracy
* since roundoff error in 1.0/x will be amplified.
* The precise demarcation should be the gradual underflow threshold.
*/
if( (s < (-MAXLOG+2.0)) && (sign < 0) )
{
x = 1.0/x;
sign = -sign;
}
#else
/* do not produce denormal answer */
if( s < -MAXLOG )
return(0.0);
#endif
 
 
/* First bit of the power */
if( n & 1 )
y = x;
else
y = 1.0;
 
w = x;
n >>= 1;
while( n )
{
w = w * w; /* arg to the 2-to-the-kth power */
if( n & 1 ) /* if that bit is set, then include in product */
y *= w;
n >>= 1;
}
 
if( sign < 0 )
y = 1.0/y;
 
done:
 
if( asign )
{
/* odd power of negative number */
if( y == 0.0 )
y = NEGZERO;
else
y = -y;
}
return(y);
}
/programs/develop/libraries/newlib/math/powif.c
0,0 → 1,198
/* powi.c
*
* Real raised to integer power
*
*
*
* SYNOPSIS:
*
* float x, y, __powif();
* int n;
*
* y = powi( x, n );
*
*
*
* DESCRIPTION:
*
* Returns argument x raised to the nth power.
* The routine efficiently decomposes n as a sum of powers of
* two. The desired power is a product of two-to-the-kth
* powers of x. Thus to compute the 32767 power of x requires
* 28 multiplications instead of 32767 multiplications.
*
*
*
* ACCURACY:
*
*
* Relative error:
* arithmetic x domain n domain # trials peak rms
* DEC .04,26 -26,26 100000 2.7e-16 4.3e-17
* IEEE .04,26 -26,26 50000 2.0e-15 3.8e-16
* IEEE 1,2 -1022,1023 50000 8.6e-14 1.6e-14
*
* Returns MAXNUM on overflow, zero on underflow.
*
*/
/* powi.c */
 
/*
Cephes Math Library Release 2.8: June, 2000
Copyright 1984, 1995, 2000 by Stephen L. Moshier
*/
 
/*
Modified for float from powi.c and adapted to mingw
2002-10-01 Danny Smith <dannysmith@users.sourceforge.net>
*/
 
#ifdef __MINGW32__
#include "cephes_mconf.h"
#else
#include "mconf.h"
#ifdef ANSIPROT
extern float logf ( float );
extern float frexpf ( float, int * );
extern int signbitf ( float );
#else
float logf(), frexpf();
int signbitf();
#endif
extern float NEGZEROF, INFINITYF, MAXNUMF, MAXLOGF, MINLOGF, LOGE2F;
#endif /* __MINGW32__ */
 
#ifndef _SET_ERRNO
#define _SET_ERRNO(x)
#endif
 
float __powif( float x, int nn )
{
int n, e, sign, asign, lx;
float w, y, s;
 
/* See pow.c for these tests. */
if( x == 0.0F )
{
if( nn == 0 )
return( 1.0F );
else if( nn < 0 )
return( INFINITYF );
else
{
if( nn & 1 )
return( x );
else
return( 0.0 );
}
}
 
if( nn == 0 )
return( 1.0 );
 
if( nn == -1 )
return( 1.0/x );
 
if( x < 0.0 )
{
asign = -1;
x = -x;
}
else
asign = 0;
 
 
if( nn < 0 )
{
sign = -1;
n = -nn;
}
else
{
sign = 1;
n = nn;
}
 
/* Even power will be positive. */
if( (n & 1) == 0 )
asign = 0;
 
/* Overflow detection */
 
/* Calculate approximate logarithm of answer */
s = frexpf( x, &lx );
e = (lx - 1)*n;
if( (e == 0) || (e > 64) || (e < -64) )
{
s = (s - 7.0710678118654752e-1) / (s + 7.0710678118654752e-1);
s = (2.9142135623730950 * s - 0.5 + lx) * nn * LOGE2F;
}
else
{
s = LOGE2F * e;
}
 
if( s > MAXLOGF )
{
mtherr( "__powif", OVERFLOW );
_SET_ERRNO(ERANGE);
y = INFINITYF;
goto done;
}
 
#if DENORMAL
if( s < MINLOGF )
{
y = 0.0;
goto done;
}
 
/* Handle tiny denormal answer, but with less accuracy
* since roundoff error in 1.0/x will be amplified.
* The precise demarcation should be the gradual underflow threshold.
*/
if( (s < (-MAXLOGF+2.0)) && (sign < 0) )
{
x = 1.0/x;
sign = -sign;
}
#else
/* do not produce denormal answer */
if( s < -MAXLOGF )
return(0.0);
#endif
 
 
/* First bit of the power */
if( n & 1 )
y = x;
else
y = 1.0;
 
w = x;
n >>= 1;
while( n )
{
w = w * w; /* arg to the 2-to-the-kth power */
if( n & 1 ) /* if that bit is set, then include in product */
y *= w;
n >>= 1;
}
 
if( sign < 0 )
y = 1.0/y;
 
done:
 
if( asign )
{
/* odd power of negative number */
if( y == 0.0 )
y = NEGZEROF;
else
y = -y;
}
return(y);
}
/programs/develop/libraries/newlib/math/powil.c
0,0 → 1,179
/* __powil.c
*
* Real raised to integer power, long double precision
*
*
*
* SYNOPSIS:
*
* long double x, y, __powil();
* int n;
*
* y = __powil( x, n );
*
*
*
* DESCRIPTION:
*
* Returns argument x raised to the nth power.
* The routine efficiently decomposes n as a sum of powers of
* two. The desired power is a product of two-to-the-kth
* powers of x. Thus to compute the 32767 power of x requires
* 28 multiplications instead of 32767 multiplications.
*
*
*
* ACCURACY:
*
*
* Relative error:
* arithmetic x domain n domain # trials peak rms
* IEEE .001,1000 -1022,1023 50000 4.3e-17 7.8e-18
* IEEE 1,2 -1022,1023 20000 3.9e-17 7.6e-18
* IEEE .99,1.01 0,8700 10000 3.6e-16 7.2e-17
*
* Returns INFINITY on overflow, zero on underflow.
*
*/
 
/* __powil.c */
 
/*
Cephes Math Library Release 2.2: December, 1990
Copyright 1984, 1990 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
 
/*
Modified for mingw
2002-07-22 Danny Smith <dannysmith@users.sourceforge.net>
*/
 
#ifdef __MINGW32__
#include "cephes_mconf.h"
#else
#include "mconf.h"
extern long double MAXNUML, MAXLOGL, MINLOGL;
extern long double LOGE2L;
#ifdef ANSIPROT
extern long double frexpl ( long double, int * );
#else
long double frexpl();
#endif
#endif /* __MINGW32__ */
 
#ifndef _SET_ERRNO
#define _SET_ERRNO(x)
#endif
 
long double __powil( x, nn )
long double x;
int nn;
{
long double w, y;
long double s;
int n, e, sign, asign, lx;
 
if( x == 0.0L )
{
if( nn == 0 )
return( 1.0L );
else if( nn < 0 )
return( INFINITYL );
else
return( 0.0L );
}
 
if( nn == 0 )
return( 1.0L );
 
 
if( x < 0.0L )
{
asign = -1;
x = -x;
}
else
asign = 0;
 
 
if( nn < 0 )
{
sign = -1;
n = -nn;
}
else
{
sign = 1;
n = nn;
}
 
/* Overflow detection */
 
/* Calculate approximate logarithm of answer */
s = x;
s = frexpl( s, &lx );
e = (lx - 1)*n;
if( (e == 0) || (e > 64) || (e < -64) )
{
s = (s - 7.0710678118654752e-1L) / (s + 7.0710678118654752e-1L);
s = (2.9142135623730950L * s - 0.5L + lx) * nn * LOGE2L;
}
else
{
s = LOGE2L * e;
}
 
if( s > MAXLOGL )
{
mtherr( "__powil", OVERFLOW );
_SET_ERRNO(ERANGE);
y = INFINITYL;
goto done;
}
 
if( s < MINLOGL )
{
mtherr( "__powil", UNDERFLOW );
_SET_ERRNO(ERANGE);
return(0.0L);
}
/* Handle tiny denormal answer, but with less accuracy
* since roundoff error in 1.0/x will be amplified.
* The precise demarcation should be the gradual underflow threshold.
*/
if( s < (-MAXLOGL+2.0L) )
{
x = 1.0L/x;
sign = -sign;
}
 
/* First bit of the power */
if( n & 1 )
y = x;
else
{
y = 1.0L;
asign = 0;
}
 
w = x;
n >>= 1;
while( n )
{
w = w * w; /* arg to the 2-to-the-kth power */
if( n & 1 ) /* if that bit is set, then include in product */
y *= w;
n >>= 1;
}
 
 
done:
 
if( asign )
y = -y; /* odd power of negative number */
if( sign < 0 )
y = 1.0L/y;
return(y);
}
/programs/develop/libraries/newlib/math/powl.c
0,0 → 1,804
/* powl.c
*
* Power function, long double precision
*
*
*
* SYNOPSIS:
*
* long double x, y, z, powl();
*
* z = powl( x, y );
*
*
*
* DESCRIPTION:
*
* Computes x raised to the yth power. Analytically,
*
* x**y = exp( y log(x) ).
*
* Following Cody and Waite, this program uses a lookup table
* of 2**-i/32 and pseudo extended precision arithmetic to
* obtain several extra bits of accuracy in both the logarithm
* and the exponential.
*
*
*
* ACCURACY:
*
* The relative error of pow(x,y) can be estimated
* by y dl ln(2), where dl is the absolute error of
* the internally computed base 2 logarithm. At the ends
* of the approximation interval the logarithm equal 1/32
* and its relative error is about 1 lsb = 1.1e-19. Hence
* the predicted relative error in the result is 2.3e-21 y .
*
* Relative error:
* arithmetic domain # trials peak rms
*
* IEEE +-1000 40000 2.8e-18 3.7e-19
* .001 < x < 1000, with log(x) uniformly distributed.
* -1000 < y < 1000, y uniformly distributed.
*
* IEEE 0,8700 60000 6.5e-18 1.0e-18
* 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed.
*
*
* ERROR MESSAGES:
*
* message condition value returned
* pow overflow x**y > MAXNUM INFINITY
* pow underflow x**y < 1/MAXNUM 0.0
* pow domain x<0 and y noninteger 0.0
*
*/
/*
Cephes Math Library Release 2.7: May, 1998
Copyright 1984, 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"
 
static char fname[] = {"powl"};
#endif
 
#ifndef _SET_ERRNO
#define _SET_ERRNO(x)
#endif
 
 
/* Table size */
#define NXT 32
/* log2(Table size) */
#define LNXT 5
 
#ifdef UNK
/* log(1+x) = x - .5x^2 + x^3 * P(z)/Q(z)
* on the domain 2^(-1/32) - 1 <= x <= 2^(1/32) - 1
*/
static long double P[] = {
8.3319510773868690346226E-4L,
4.9000050881978028599627E-1L,
1.7500123722550302671919E0L,
1.4000100839971580279335E0L,
};
static long double Q[] = {
/* 1.0000000000000000000000E0L,*/
5.2500282295834889175431E0L,
8.4000598057587009834666E0L,
4.2000302519914740834728E0L,
};
/* A[i] = 2^(-i/32), rounded to IEEE long double precision.
* If i is even, A[i] + B[i/2] gives additional accuracy.
*/
static long double A[33] = {
1.0000000000000000000000E0L,
9.7857206208770013448287E-1L,
9.5760328069857364691013E-1L,
9.3708381705514995065011E-1L,
9.1700404320467123175367E-1L,
8.9735453750155359320742E-1L,
8.7812608018664974155474E-1L,
8.5930964906123895780165E-1L,
8.4089641525371454301892E-1L,
8.2287773907698242225554E-1L,
8.0524516597462715409607E-1L,
7.8799042255394324325455E-1L,
7.7110541270397041179298E-1L,
7.5458221379671136985669E-1L,
7.3841307296974965571198E-1L,
7.2259040348852331001267E-1L,
7.0710678118654752438189E-1L,
6.9195494098191597746178E-1L,
6.7712777346844636413344E-1L,
6.6261832157987064729696E-1L,
6.4841977732550483296079E-1L,
6.3452547859586661129850E-1L,
6.2092890603674202431705E-1L,
6.0762367999023443907803E-1L,
5.9460355750136053334378E-1L,
5.8186242938878875689693E-1L,
5.6939431737834582684856E-1L,
5.5719337129794626814472E-1L,
5.4525386633262882960438E-1L,
5.3357020033841180906486E-1L,
5.2213689121370692017331E-1L,
5.1094857432705833910408E-1L,
5.0000000000000000000000E-1L,
};
static long double B[17] = {
0.0000000000000000000000E0L,
2.6176170809902549338711E-20L,
-1.0126791927256478897086E-20L,
1.3438228172316276937655E-21L,
1.2207982955417546912101E-20L,
-6.3084814358060867200133E-21L,
1.3164426894366316434230E-20L,
-1.8527916071632873716786E-20L,
1.8950325588932570796551E-20L,
1.5564775779538780478155E-20L,
6.0859793637556860974380E-21L,
-2.0208749253662532228949E-20L,
1.4966292219224761844552E-20L,
3.3540909728056476875639E-21L,
-8.6987564101742849540743E-22L,
-1.2327176863327626135542E-20L,
0.0000000000000000000000E0L,
};
 
/* 2^x = 1 + x P(x),
* on the interval -1/32 <= x <= 0
*/
static long double R[] = {
1.5089970579127659901157E-5L,
1.5402715328927013076125E-4L,
1.3333556028915671091390E-3L,
9.6181291046036762031786E-3L,
5.5504108664798463044015E-2L,
2.4022650695910062854352E-1L,
6.9314718055994530931447E-1L,
};
 
#define douba(k) A[k]
#define doubb(k) B[k]
#define MEXP (NXT*16384.0L)
/* The following if denormal numbers are supported, else -MEXP: */
#ifdef DENORMAL
#define MNEXP (-NXT*(16384.0L+64.0L))
#else
#define MNEXP (-NXT*16384.0L)
#endif
/* log2(e) - 1 */
#define LOG2EA 0.44269504088896340735992L
#endif
 
 
#ifdef IBMPC
static const unsigned short P[] = {
0xb804,0xa8b7,0xc6f4,0xda6a,0x3ff4, XPD
0x7de9,0xcf02,0x58c0,0xfae1,0x3ffd, XPD
0x405a,0x3722,0x67c9,0xe000,0x3fff, XPD
0xcd99,0x6b43,0x87ca,0xb333,0x3fff, XPD
};
static const unsigned short Q[] = {
/* 0x0000,0x0000,0x0000,0x8000,0x3fff, */
0x6307,0xa469,0x3b33,0xa800,0x4001, XPD
0xfec2,0x62d7,0xa51c,0x8666,0x4002, XPD
0xda32,0xd072,0xa5d7,0x8666,0x4001, XPD
};
static const unsigned short A[] = {
0x0000,0x0000,0x0000,0x8000,0x3fff, XPD
0x033a,0x722a,0xb2db,0xfa83,0x3ffe, XPD
0xcc2c,0x2486,0x7d15,0xf525,0x3ffe, XPD
0xf5cb,0xdcda,0xb99b,0xefe4,0x3ffe, XPD
0x392f,0xdd24,0xc6e7,0xeac0,0x3ffe, XPD
0x48a8,0x7c83,0x06e7,0xe5b9,0x3ffe, XPD
0xe111,0x2a94,0xdeec,0xe0cc,0x3ffe, XPD
0x3755,0xdaf2,0xb797,0xdbfb,0x3ffe, XPD
0x6af4,0xd69d,0xfcca,0xd744,0x3ffe, XPD
0xe45a,0xf12a,0x1d91,0xd2a8,0x3ffe, XPD
0x80e4,0x1f84,0x8c15,0xce24,0x3ffe, XPD
0x27a3,0x6e2f,0xbd86,0xc9b9,0x3ffe, XPD
0xdadd,0x5506,0x2a11,0xc567,0x3ffe, XPD
0x9456,0x6670,0x4cca,0xc12c,0x3ffe, XPD
0x36bf,0x580c,0xa39f,0xbd08,0x3ffe, XPD
0x9ee9,0x62fb,0xaf47,0xb8fb,0x3ffe, XPD
0x6484,0xf9de,0xf333,0xb504,0x3ffe, XPD
0x2590,0xd2ac,0xf581,0xb123,0x3ffe, XPD
0x4ac6,0x42a1,0x3eea,0xad58,0x3ffe, XPD
0x0ef8,0xea7c,0x5ab4,0xa9a1,0x3ffe, XPD
0x38ea,0xb151,0xd6a9,0xa5fe,0x3ffe, XPD
0x6819,0x0c49,0x4303,0xa270,0x3ffe, XPD
0x11ae,0x91a1,0x3260,0x9ef5,0x3ffe, XPD
0x5539,0xd54e,0x39b9,0x9b8d,0x3ffe, XPD
0xa96f,0x8db8,0xf051,0x9837,0x3ffe, XPD
0x0961,0xfef7,0xefa8,0x94f4,0x3ffe, XPD
0xc336,0xab11,0xd373,0x91c3,0x3ffe, XPD
0x53c0,0x45cd,0x398b,0x8ea4,0x3ffe, XPD
0xd6e7,0xea8b,0xc1e3,0x8b95,0x3ffe, XPD
0x8527,0x92da,0x0e80,0x8898,0x3ffe, XPD
0x7b15,0xcc48,0xc367,0x85aa,0x3ffe, XPD
0xa1d7,0xac2b,0x8698,0x82cd,0x3ffe, XPD
0x0000,0x0000,0x0000,0x8000,0x3ffe, XPD
};
static const unsigned short B[] = {
0x0000,0x0000,0x0000,0x0000,0x0000, XPD
0x1f87,0xdb30,0x18f5,0xf73a,0x3fbd, XPD
0xac15,0x3e46,0x2932,0xbf4a,0xbfbc, XPD
0x7944,0xba66,0xa091,0xcb12,0x3fb9, XPD
0xff78,0x40b4,0x2ee6,0xe69a,0x3fbc, XPD
0xc895,0x5069,0xe383,0xee53,0xbfbb, XPD
0x7cde,0x9376,0x4325,0xf8ab,0x3fbc, XPD
0xa10c,0x25e0,0xc093,0xaefd,0xbfbd, XPD
0x7d3e,0xea95,0x1366,0xb2fb,0x3fbd, XPD
0x5d89,0xeb34,0x5191,0x9301,0x3fbd, XPD
0x80d9,0xb883,0xfb10,0xe5eb,0x3fbb, XPD
0x045d,0x288c,0xc1ec,0xbedd,0xbfbd, XPD
0xeded,0x5c85,0x4630,0x8d5a,0x3fbd, XPD
0x9d82,0xe5ac,0x8e0a,0xfd6d,0x3fba, XPD
0x6dfd,0xeb58,0xaf14,0x8373,0xbfb9, XPD
0xf938,0x7aac,0x91cf,0xe8da,0xbfbc, XPD
0x0000,0x0000,0x0000,0x0000,0x0000, XPD
};
static const unsigned short R[] = {
0xa69b,0x530e,0xee1d,0xfd2a,0x3fee, XPD
0xc746,0x8e7e,0x5960,0xa182,0x3ff2, XPD
0x63b6,0xadda,0xfd6a,0xaec3,0x3ff5, XPD
0xc104,0xfd99,0x5b7c,0x9d95,0x3ff8, XPD
0xe05e,0x249d,0x46b8,0xe358,0x3ffa, XPD
0x5d1d,0x162c,0xeffc,0xf5fd,0x3ffc, XPD
0x79aa,0xd1cf,0x17f7,0xb172,0x3ffe, XPD
};
 
/* 10 byte sizes versus 12 byte */
#define douba(k) (*(long double *)(&A[(sizeof( long double )/2)*(k)]))
#define doubb(k) (*(long double *)(&B[(sizeof( long double )/2)*(k)]))
#define MEXP (NXT*16384.0L)
#ifdef DENORMAL
#define MNEXP (-NXT*(16384.0L+64.0L))
#else
#define MNEXP (-NXT*16384.0L)
#endif
static const
union
{
unsigned short L[6];
long double ld;
} log2ea = {{0xc2ef,0x705f,0xeca5,0xe2a8,0x3ffd, XPD}};
 
#define LOG2EA (log2ea.ld)
/*
#define LOG2EA 0.44269504088896340735992L
*/
#endif
 
#ifdef MIEEE
static long P[] = {
0x3ff40000,0xda6ac6f4,0xa8b7b804,
0x3ffd0000,0xfae158c0,0xcf027de9,
0x3fff0000,0xe00067c9,0x3722405a,
0x3fff0000,0xb33387ca,0x6b43cd99,
};
static long Q[] = {
/* 0x3fff0000,0x80000000,0x00000000, */
0x40010000,0xa8003b33,0xa4696307,
0x40020000,0x8666a51c,0x62d7fec2,
0x40010000,0x8666a5d7,0xd072da32,
};
static long A[] = {
0x3fff0000,0x80000000,0x00000000,
0x3ffe0000,0xfa83b2db,0x722a033a,
0x3ffe0000,0xf5257d15,0x2486cc2c,
0x3ffe0000,0xefe4b99b,0xdcdaf5cb,
0x3ffe0000,0xeac0c6e7,0xdd24392f,
0x3ffe0000,0xe5b906e7,0x7c8348a8,
0x3ffe0000,0xe0ccdeec,0x2a94e111,
0x3ffe0000,0xdbfbb797,0xdaf23755,
0x3ffe0000,0xd744fcca,0xd69d6af4,
0x3ffe0000,0xd2a81d91,0xf12ae45a,
0x3ffe0000,0xce248c15,0x1f8480e4,
0x3ffe0000,0xc9b9bd86,0x6e2f27a3,
0x3ffe0000,0xc5672a11,0x5506dadd,
0x3ffe0000,0xc12c4cca,0x66709456,
0x3ffe0000,0xbd08a39f,0x580c36bf,
0x3ffe0000,0xb8fbaf47,0x62fb9ee9,
0x3ffe0000,0xb504f333,0xf9de6484,
0x3ffe0000,0xb123f581,0xd2ac2590,
0x3ffe0000,0xad583eea,0x42a14ac6,
0x3ffe0000,0xa9a15ab4,0xea7c0ef8,
0x3ffe0000,0xa5fed6a9,0xb15138ea,
0x3ffe0000,0xa2704303,0x0c496819,
0x3ffe0000,0x9ef53260,0x91a111ae,
0x3ffe0000,0x9b8d39b9,0xd54e5539,
0x3ffe0000,0x9837f051,0x8db8a96f,
0x3ffe0000,0x94f4efa8,0xfef70961,
0x3ffe0000,0x91c3d373,0xab11c336,
0x3ffe0000,0x8ea4398b,0x45cd53c0,
0x3ffe0000,0x8b95c1e3,0xea8bd6e7,
0x3ffe0000,0x88980e80,0x92da8527,
0x3ffe0000,0x85aac367,0xcc487b15,
0x3ffe0000,0x82cd8698,0xac2ba1d7,
0x3ffe0000,0x80000000,0x00000000,
};
static long B[51] = {
0x00000000,0x00000000,0x00000000,
0x3fbd0000,0xf73a18f5,0xdb301f87,
0xbfbc0000,0xbf4a2932,0x3e46ac15,
0x3fb90000,0xcb12a091,0xba667944,
0x3fbc0000,0xe69a2ee6,0x40b4ff78,
0xbfbb0000,0xee53e383,0x5069c895,
0x3fbc0000,0xf8ab4325,0x93767cde,
0xbfbd0000,0xaefdc093,0x25e0a10c,
0x3fbd0000,0xb2fb1366,0xea957d3e,
0x3fbd0000,0x93015191,0xeb345d89,
0x3fbb0000,0xe5ebfb10,0xb88380d9,
0xbfbd0000,0xbeddc1ec,0x288c045d,
0x3fbd0000,0x8d5a4630,0x5c85eded,
0x3fba0000,0xfd6d8e0a,0xe5ac9d82,
0xbfb90000,0x8373af14,0xeb586dfd,
0xbfbc0000,0xe8da91cf,0x7aacf938,
0x00000000,0x00000000,0x00000000,
};
static long R[] = {
0x3fee0000,0xfd2aee1d,0x530ea69b,
0x3ff20000,0xa1825960,0x8e7ec746,
0x3ff50000,0xaec3fd6a,0xadda63b6,
0x3ff80000,0x9d955b7c,0xfd99c104,
0x3ffa0000,0xe35846b8,0x249de05e,
0x3ffc0000,0xf5fdeffc,0x162c5d1d,
0x3ffe0000,0xb17217f7,0xd1cf79aa,
};
 
#define douba(k) (*(long double *)&A[3*(k)])
#define doubb(k) (*(long double *)&B[3*(k)])
#define MEXP (NXT*16384.0L)
#ifdef DENORMAL
#define MNEXP (-NXT*(16384.0L+64.0L))
#else
#define MNEXP (-NXT*16382.0L)
#endif
static long L[3] = {0x3ffd0000,0xe2a8eca5,0x705fc2ef};
#define LOG2EA (*(long double *)(&L[0]))
#endif
 
 
#define F W
#define Fa Wa
#define Fb Wb
#define G W
#define Ga Wa
#define Gb u
#define H W
#define Ha Wb
#define Hb Wb
 
#ifndef __MINGW32__
extern long double MAXNUML;
#endif
 
static VOLATILE long double z;
static long double w, W, Wa, Wb, ya, yb, u;
 
#ifdef __MINGW32__
static __inline__ long double reducl( long double );
extern long double __powil ( long double, int );
extern long double powl ( long double x, long double y);
#else
#ifdef ANSIPROT
extern long double floorl ( long double );
extern long double fabsl ( long double );
extern long double frexpl ( long double, int * );
extern long double ldexpl ( long double, int );
extern long double polevll ( long double, void *, int );
extern long double p1evll ( long double, void *, int );
extern long double __powil ( long double, int );
extern int isnanl ( long double );
extern int isfinitel ( long double );
static long double reducl( long double );
extern int signbitl ( long double );
#else
long double floorl(), fabsl(), frexpl(), ldexpl();
long double polevll(), p1evll(), __powil();
static long double reducl();
int isnanl(), isfinitel(), signbitl();
#endif /* __MINGW32__ */
 
#ifdef INFINITIES
extern long double INFINITYL;
#else
#define INFINITYL MAXNUML
#endif
 
#ifdef NANS
extern long double NANL;
#endif
#ifdef MINUSZERO
extern long double NEGZEROL;
#endif
 
#endif /* __MINGW32__ */
 
#ifdef __MINGW32__
 
/* No error checking. We handle Infs and zeros ourselves. */
static __inline__ long double
__fast_ldexpl (long double x, int expn)
{
long double res;
__asm__ ("fscale"
: "=t" (res)
: "0" (x), "u" ((long double) expn));
return res;
}
 
#define ldexpl __fast_ldexpl
 
#endif
 
 
long double powl( x, y )
long double x, y;
{
/* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */
int i, nflg, iyflg, yoddint;
long e;
 
if( y == 0.0L )
return( 1.0L );
 
#ifdef NANS
if( isnanl(x) )
{
_SET_ERRNO (EDOM);
return( x );
}
if( isnanl(y) )
{
_SET_ERRNO (EDOM);
return( y );
}
#endif
 
if( y == 1.0L )
return( x );
 
if( isinfl(y) && (x == -1.0L || x == 1.0L) )
return( y );
 
if( x == 1.0L )
return( 1.0L );
 
if( y >= MAXNUML )
{
_SET_ERRNO (ERANGE);
#ifdef INFINITIES
if( x > 1.0L )
return( INFINITYL );
#else
if( x > 1.0L )
return( MAXNUML );
#endif
if( x > 0.0L && x < 1.0L )
return( 0.0L );
#ifdef INFINITIES
if( x < -1.0L )
return( INFINITYL );
#else
if( x < -1.0L )
return( MAXNUML );
#endif
if( x > -1.0L && x < 0.0L )
return( 0.0L );
}
if( y <= -MAXNUML )
{
_SET_ERRNO (ERANGE);
if( x > 1.0L )
return( 0.0L );
#ifdef INFINITIES
if( x > 0.0L && x < 1.0L )
return( INFINITYL );
#else
if( x > 0.0L && x < 1.0L )
return( MAXNUML );
#endif
if( x < -1.0L )
return( 0.0L );
#ifdef INFINITIES
if( x > -1.0L && x < 0.0L )
return( INFINITYL );
#else
if( x > -1.0L && x < 0.0L )
return( MAXNUML );
#endif
}
if( x >= MAXNUML )
{
#if INFINITIES
if( y > 0.0L )
return( INFINITYL );
#else
if( y > 0.0L )
return( MAXNUML );
#endif
return( 0.0L );
}
 
w = floorl(y);
/* Set iyflg to 1 if y is an integer. */
iyflg = 0;
if( w == y )
iyflg = 1;
 
/* Test for odd integer y. */
yoddint = 0;
if( iyflg )
{
ya = fabsl(y);
ya = floorl(0.5L * ya);
yb = 0.5L * fabsl(w);
if( ya != yb )
yoddint = 1;
}
 
if( x <= -MAXNUML )
{
if( y > 0.0L )
{
#ifdef INFINITIES
if( yoddint )
return( -INFINITYL );
return( INFINITYL );
#else
if( yoddint )
return( -MAXNUML );
return( MAXNUML );
#endif
}
if( y < 0.0L )
{
#ifdef MINUSZERO
if( yoddint )
return( NEGZEROL );
#endif
return( 0.0 );
}
}
 
 
nflg = 0; /* flag = 1 if x<0 raised to integer power */
if( x <= 0.0L )
{
if( x == 0.0L )
{
if( y < 0.0 )
{
#ifdef MINUSZERO
if( signbitl(x) && yoddint )
return( -INFINITYL );
#endif
#ifdef INFINITIES
return( INFINITYL );
#else
return( MAXNUML );
#endif
}
if( y > 0.0 )
{
#ifdef MINUSZERO
if( signbitl(x) && yoddint )
return( NEGZEROL );
#endif
return( 0.0 );
}
if( y == 0.0L )
return( 1.0L ); /* 0**0 */
else
return( 0.0L ); /* 0**y */
}
else
{
if( iyflg == 0 )
{ /* noninteger power of negative number */
mtherr( fname, DOMAIN );
_SET_ERRNO (EDOM);
#ifdef NANS
return(NANL);
#else
return(0.0L);
#endif
}
nflg = 1;
}
}
 
/* Integer power of an integer. */
 
if( iyflg )
{
i = w;
w = floorl(x);
if( (w == x) && (fabsl(y) < 32768.0) )
{
w = __powil( x, (int) y );
return( w );
}
}
 
 
if( nflg )
x = fabsl(x);
 
/* separate significand from exponent */
x = frexpl( x, &i );
e = i;
 
/* find significand in antilog table A[] */
i = 1;
if( x <= douba(17) )
i = 17;
if( x <= douba(i+8) )
i += 8;
if( x <= douba(i+4) )
i += 4;
if( x <= douba(i+2) )
i += 2;
if( x >= douba(1) )
i = -1;
i += 1;
 
 
/* Find (x - A[i])/A[i]
* in order to compute log(x/A[i]):
*
* log(x) = log( a x/a ) = log(a) + log(x/a)
*
* log(x/a) = log(1+v), v = x/a - 1 = (x-a)/a
*/
x -= douba(i);
x -= doubb(i/2);
x /= douba(i);
 
 
/* rational approximation for log(1+v):
*
* log(1+v) = v - v**2/2 + v**3 P(v) / Q(v)
*/
z = x*x;
w = x * ( z * polevll( x, P, 3 ) / p1evll( x, Q, 3 ) );
w = w - ldexpl( z, -1 ); /* w - 0.5 * z */
 
/* Convert to base 2 logarithm:
* multiply by log2(e) = 1 + LOG2EA
*/
z = LOG2EA * w;
z += w;
z += LOG2EA * x;
z += x;
 
/* Compute exponent term of the base 2 logarithm. */
w = -i;
w = ldexpl( w, -LNXT ); /* divide by NXT */
w += e;
/* Now base 2 log of x is w + z. */
 
/* Multiply base 2 log by y, in extended precision. */
 
/* separate y into large part ya
* and small part yb less than 1/NXT
*/
ya = reducl(y);
yb = y - ya;
 
/* (w+z)(ya+yb)
* = w*ya + w*yb + z*y
*/
F = z * y + w * yb;
Fa = reducl(F);
Fb = F - Fa;
 
G = Fa + w * ya;
Ga = reducl(G);
Gb = G - Ga;
 
H = Fb + Gb;
Ha = reducl(H);
w = ldexpl( Ga + Ha, LNXT );
 
/* Test the power of 2 for overflow */
if( w > MEXP )
{
_SET_ERRNO (ERANGE);
mtherr( fname, OVERFLOW );
return( MAXNUML );
}
 
if( w < MNEXP )
{
_SET_ERRNO (ERANGE);
mtherr( fname, UNDERFLOW );
return( 0.0L );
}
 
e = w;
Hb = H - Ha;
 
if( Hb > 0.0L )
{
e += 1;
Hb -= (1.0L/NXT); /*0.0625L;*/
}
 
/* Now the product y * log2(x) = Hb + e/NXT.
*
* Compute base 2 exponential of Hb,
* where -0.0625 <= Hb <= 0.
*/
z = Hb * polevll( Hb, R, 6 ); /* z = 2**Hb - 1 */
 
/* Express e/NXT as an integer plus a negative number of (1/NXT)ths.
* Find lookup table entry for the fractional power of 2.
*/
if( e < 0 )
i = 0;
else
i = 1;
i = e/NXT + i;
e = NXT*i - e;
w = douba( e );
z = w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */
z = z + w;
z = ldexpl( z, i ); /* multiply by integer power of 2 */
 
if( nflg )
{
/* For negative x,
* find out if the integer exponent
* is odd or even.
*/
w = ldexpl( y, -1 );
w = floorl(w);
w = ldexpl( w, 1 );
if( w != y )
z = -z; /* odd exponent */
}
 
return( z );
}
 
static __inline__ long double
__convert_inf_to_maxnum(long double x)
{
if (isinf(x))
return (x > 0.0L ? MAXNUML : -MAXNUML);
else
return x;
}
 
 
/* Find a multiple of 1/NXT that is within 1/NXT of x. */
static __inline__ long double reducl(x)
long double x;
{
long double t;
 
/* If the call to ldexpl overflows, set it to MAXNUML.
This avoids Inf - Inf = Nan result when calculating the 'small'
part of a reduction. Instead, the small part becomes Inf,
causing under/overflow when adding it to the 'large' part.
There must be a cleaner way of doing this. */
t = __convert_inf_to_maxnum (ldexpl( x, LNXT ));
t = floorl( t );
t = ldexpl( t, -LNXT );
return(t);
}
/programs/develop/libraries/newlib/math/quad.h
0,0 → 1,271
/* Software floating-point emulation.
Definitions for IEEE Quad Precision.
Copyright (C) 1997,1998,1999,2006,2007 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_Q (4*_FP_W_TYPE_SIZE)
#else
#define _FP_FRACTBITS_Q (2*_FP_W_TYPE_SIZE)
#endif
 
#define _FP_FRACBITS_Q 113
#define _FP_FRACXBITS_Q (_FP_FRACTBITS_Q - _FP_FRACBITS_Q)
#define _FP_WFRACBITS_Q (_FP_WORKBITS + _FP_FRACBITS_Q)
#define _FP_WFRACXBITS_Q (_FP_FRACTBITS_Q - _FP_WFRACBITS_Q)
#define _FP_EXPBITS_Q 15
#define _FP_EXPBIAS_Q 16383
#define _FP_EXPMAX_Q 32767
 
#define _FP_QNANBIT_Q \
((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE)
#define _FP_QNANBIT_SH_Q \
((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
#define _FP_IMPLBIT_Q \
((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE)
#define _FP_IMPLBIT_SH_Q \
((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
#define _FP_OVERFLOW_Q \
((_FP_W_TYPE)1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE))
 
typedef float TFtype __attribute__((mode(TF)));
 
#if _FP_W_TYPE_SIZE < 64
 
union _FP_UNION_Q
{
TFtype flt;
struct
{
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned sign : 1;
unsigned exp : _FP_EXPBITS_Q;
unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3);
unsigned long frac2 : _FP_W_TYPE_SIZE;
unsigned long frac1 : _FP_W_TYPE_SIZE;
unsigned long frac0 : _FP_W_TYPE_SIZE;
#else
unsigned long frac0 : _FP_W_TYPE_SIZE;
unsigned long frac1 : _FP_W_TYPE_SIZE;
unsigned long frac2 : _FP_W_TYPE_SIZE;
unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3);
unsigned exp : _FP_EXPBITS_Q;
unsigned sign : 1;
#endif /* not bigendian */
} bits __attribute__((packed));
};
 
 
#define FP_DECL_Q(X) _FP_DECL(4,X)
#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_4(Q,X,val)
#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_4_P(Q,X,val)
#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_4(Q,val,X)
#define FP_PACK_RAW_QP(val,X) \
do { \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_4_P(Q,val,X); \
} while (0)
 
#define FP_UNPACK_Q(X,val) \
do { \
_FP_UNPACK_RAW_4(Q,X,val); \
_FP_UNPACK_CANONICAL(Q,4,X); \
} while (0)
 
#define FP_UNPACK_QP(X,val) \
do { \
_FP_UNPACK_RAW_4_P(Q,X,val); \
_FP_UNPACK_CANONICAL(Q,4,X); \
} while (0)
 
#define FP_UNPACK_SEMIRAW_Q(X,val) \
do { \
_FP_UNPACK_RAW_4(Q,X,val); \
_FP_UNPACK_SEMIRAW(Q,4,X); \
} while (0)
 
#define FP_UNPACK_SEMIRAW_QP(X,val) \
do { \
_FP_UNPACK_RAW_4_P(Q,X,val); \
_FP_UNPACK_SEMIRAW(Q,4,X); \
} while (0)
 
#define FP_PACK_Q(val,X) \
do { \
_FP_PACK_CANONICAL(Q,4,X); \
_FP_PACK_RAW_4(Q,val,X); \
} while (0)
 
#define FP_PACK_QP(val,X) \
do { \
_FP_PACK_CANONICAL(Q,4,X); \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_4_P(Q,val,X); \
} while (0)
 
#define FP_PACK_SEMIRAW_Q(val,X) \
do { \
_FP_PACK_SEMIRAW(Q,4,X); \
_FP_PACK_RAW_4(Q,val,X); \
} while (0)
 
#define FP_PACK_SEMIRAW_QP(val,X) \
do { \
_FP_PACK_SEMIRAW(Q,4,X); \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_4_P(Q,val,X); \
} while (0)
 
#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,4,X)
#define FP_NEG_Q(R,X) _FP_NEG(Q,4,R,X)
#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,4,R,X,Y)
#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,4,R,X,Y)
#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,4,R,X,Y)
#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,4,R,X,Y)
#define FP_SQRT_Q(R,X) _FP_SQRT(Q,4,R,X)
#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_4(R,S,T,X,Q)
 
#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,4,r,X,Y,un)
#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,4,r,X,Y)
#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,4,r,X,Y)
 
#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,4,r,X,rsz,rsg)
#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,4,X,r,rs,rt)
 
#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_4(X)
#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_4(X)
 
#else /* not _FP_W_TYPE_SIZE < 64 */
union _FP_UNION_Q
{
TFtype flt /* __attribute__((mode(TF))) */ ;
struct {
_FP_W_TYPE a, b;
} longs;
struct {
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned sign : 1;
unsigned exp : _FP_EXPBITS_Q;
_FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE;
_FP_W_TYPE frac0 : _FP_W_TYPE_SIZE;
#else
_FP_W_TYPE frac0 : _FP_W_TYPE_SIZE;
_FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE;
unsigned exp : _FP_EXPBITS_Q;
unsigned sign : 1;
#endif
} bits;
};
 
#define FP_DECL_Q(X) _FP_DECL(2,X)
#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_2(Q,X,val)
#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_2_P(Q,X,val)
#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_2(Q,val,X)
#define FP_PACK_RAW_QP(val,X) \
do { \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_2_P(Q,val,X); \
} while (0)
 
#define FP_UNPACK_Q(X,val) \
do { \
_FP_UNPACK_RAW_2(Q,X,val); \
_FP_UNPACK_CANONICAL(Q,2,X); \
} while (0)
 
#define FP_UNPACK_QP(X,val) \
do { \
_FP_UNPACK_RAW_2_P(Q,X,val); \
_FP_UNPACK_CANONICAL(Q,2,X); \
} while (0)
 
#define FP_UNPACK_SEMIRAW_Q(X,val) \
do { \
_FP_UNPACK_RAW_2(Q,X,val); \
_FP_UNPACK_SEMIRAW(Q,2,X); \
} while (0)
 
#define FP_UNPACK_SEMIRAW_QP(X,val) \
do { \
_FP_UNPACK_RAW_2_P(Q,X,val); \
_FP_UNPACK_SEMIRAW(Q,2,X); \
} while (0)
 
#define FP_PACK_Q(val,X) \
do { \
_FP_PACK_CANONICAL(Q,2,X); \
_FP_PACK_RAW_2(Q,val,X); \
} while (0)
 
#define FP_PACK_QP(val,X) \
do { \
_FP_PACK_CANONICAL(Q,2,X); \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_2_P(Q,val,X); \
} while (0)
 
#define FP_PACK_SEMIRAW_Q(val,X) \
do { \
_FP_PACK_SEMIRAW(Q,2,X); \
_FP_PACK_RAW_2(Q,val,X); \
} while (0)
 
#define FP_PACK_SEMIRAW_QP(val,X) \
do { \
_FP_PACK_SEMIRAW(Q,2,X); \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_2_P(Q,val,X); \
} while (0)
 
#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,2,X)
#define FP_NEG_Q(R,X) _FP_NEG(Q,2,R,X)
#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,2,R,X,Y)
#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,2,R,X,Y)
#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,2,R,X,Y)
#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,2,R,X,Y)
#define FP_SQRT_Q(R,X) _FP_SQRT(Q,2,R,X)
#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q)
 
#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,2,r,X,Y,un)
#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,2,r,X,Y)
#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,2,r,X,Y)
 
#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,2,r,X,rsz,rsg)
#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,2,X,r,rs,rt)
 
#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_2(X)
#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_2(X)
 
#endif /* not _FP_W_TYPE_SIZE < 64 */
/programs/develop/libraries/newlib/math/remainder.S
0,0 → 1,19
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
 
.file "remainder.S"
.text
.align 4
.globl _remainder
.def _remainder; .scl 2; .type 32; .endef
_remainder:
fldl 12(%esp)
fldl 4(%esp)
1: fprem1
fstsw %ax
sahf
jp 1b
fstp %st(1)
ret
/programs/develop/libraries/newlib/math/remainderf.S
0,0 → 1,19
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
 
.file "remainderf.S"
.text
.align 4
.globl _remainder
.def _remainderf; .scl 2; .type 32; .endef
_remainderf:
flds 8(%esp)
flds 4(%esp)
1: fprem1
fstsw %ax
sahf
jp 1b
fstp %st(1)
ret
/programs/develop/libraries/newlib/math/remainderl.S
0,0 → 1,22
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Adapted 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 "remainderl.S"
.text
.align 4
.globl _remainderl
.def _remainderl; .scl 2; .type 32; .endef
_remainderl:
fldt 16(%esp)
fldt 4(%esp)
1: fprem1
fstsw %ax
sahf
jp 1b
fstp %st(1)
ret
/programs/develop/libraries/newlib/math/remquo.S
0,0 → 1,38
/*
* Written by Ulrich Drepper <drepper@cygnus.com>.
* Based on e_remainder by J.T. Conklin <jtc@netbsd.org>.
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.ne
* Public domain.
*/
 
.file "remquo.S"
.text
.align 4;
.globl _remquo;
_remquo:
fldl 4 +8(%esp)
fldl 4(%esp)
1: fprem1
fstsw %ax
sahf
jp 1b
fstp %st(1)
movl %eax, %ecx
shrl $8, %eax
shrl $12, %ecx
andl $4, %ecx
andl $3, %eax
orl %eax, %ecx
movl $0xef2960, %eax
shrl %cl, %eax
andl $3, %eax
movl 4 +8 +8(%esp), %ecx
movl 4 +4(%esp), %edx
xorl 4 +8 +4(%esp), %edx
testl $0x80000000, %edx
jz 1f
negl %eax
1: movl %eax, (%ecx)
 
ret
/programs/develop/libraries/newlib/math/remquof.S
0,0 → 1,38
/*
* Written by Ulrich Drepper <drepper@cygnus.com>.
* Based on e_remainder by J.T. Conklin <jtc@netbsd.org>.
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.ne
* Public domain.
*/
 
.file "remquo.S"
.text
.align 4;
.globl _remquof;
_remquof:
flds 4 +4(%esp)
flds 4(%esp)
1: fprem1
fstsw %ax
sahf
jp 1b
fstp %st(1)
movl %eax, %ecx
shrl $8, %eax
shrl $12, %ecx
andl $4, %ecx
andl $3, %eax
orl %eax, %ecx
movl $0xef2960, %eax
shrl %cl, %eax
andl $3, %eax
movl 4 +4 +4(%esp), %ecx
movl 4(%esp), %edx
xorl 4 +4(%esp), %edx
testl $0x80000000, %edx
jz 1f
negl %eax
1: movl %eax, (%ecx)
 
ret
/programs/develop/libraries/newlib/math/remquol.S
0,0 → 1,36
/*
* Written by Ulrich Drepper <drepper@cygnus.com>.
* Based on e_remainder by J.T. Conklin <jtc@netbsd.org>.
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
* Public domain.
*/
.text
.align 4;
.globl _remquol;
_remquol:
fldt 4 +12(%esp)
fldt 4(%esp)
1: fprem1
fstsw %ax
sahf
jp 1b
fstp %st(1)
movl %eax, %ecx
shrl $8, %eax
shrl $12, %ecx
andl $4, %ecx
andl $3, %eax
orl %eax, %ecx
movl $0xef2960, %eax
shrl %cl, %eax
andl $3, %eax
movl 4 +12 +12(%esp), %ecx
movl 4 +8(%esp), %edx
xorl 4 +12 +8(%esp), %edx
testl $0x8000, %edx
jz 1f
negl %eax
1: movl %eax, (%ecx)
ret
/programs/develop/libraries/newlib/math/rint.c
0,0 → 1,6
#include <math.h>
double rint (double x){
double retval;
__asm__ ("frndint;" : "=t" (retval) : "0" (x));
return retval;
}
/programs/develop/libraries/newlib/math/rintf.c
0,0 → 1,7
#include <math.h>
 
float rintf (float x){
float retval;
__asm__ ("frndint;": "=t" (retval) : "0" (x));
return retval;
}
/programs/develop/libraries/newlib/math/rintl.c
0,0 → 1,7
#include <math.h>
 
long double rintl (long double x){
long double retval;
__asm__ ("frndint;": "=t" (retval) : "0" (x));
return retval;
}
/programs/develop/libraries/newlib/math/round_generic.c
0,0 → 1,51
/*
* round_generic.c
*
* $Id: round_generic.c,v 1.1 2008/06/03 18:42:21 keithmarshall Exp $
*
* Provides a generic implementation for the `round()', `roundf()'
* and `roundl()' functions; compile with `-D FUNCTION=name', with
* `name' set to each of these three in turn, to create separate
* object files for each of the three functions.
*
* Written by Keith Marshall <keithmarshall@users.sourceforge.net>
*
* This is free software. You may redistribute and/or modify it as you
* see fit, without restriction of copyright.
*
* This software is provided "as is", in the hope that it may be useful,
* but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of
* MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no
* time will the author accept any form of liability for any damages,
* however caused, resulting from the use of this software.
*
*/
#ifndef FUNCTION
/*
* Normally specified with `-D FUNCTION=name', on the command line.
* Valid FUNCTION names are `round', `roundf' and `roundl'; specifying
* anything else will most likely cause a compilation error. If user
* did not specify any FUNCTION name, default to `round'.
*/
#define FUNCTION round
#endif
 
#include "round_internal.h"
 
/* Generic implementation.
* The user is required to specify the FUNCTION name;
* the RETURN_TYPE and INPUT_TYPE macros resolve to appropriate
* type declarations, to match the selected FUNCTION prototype.
*/
RETURN_TYPE FUNCTION( INPUT_TYPE x )
{
/* Round to nearest integer, away from zero for half-way.
*
* We split it with the `round_internal()' function in
* a private header file, so that it may be shared by this,
* `lround()' and `llround()' implementations.
*/
return isfinite( x ) ? round_internal( x ) : x;
}
 
/* $RCSfile: round_generic.c,v $$Revision: 1.1 $: end of file */
/programs/develop/libraries/newlib/math/round_internal.h
0,0 → 1,155
#ifndef _ROUND_INTERNAL_H
/*
* round_internal.h
*
* $Id: round_internal.h,v 1.1 2008/06/03 18:42:21 keithmarshall Exp $
*
* Provides a generic implementation of the numerical rounding
* algorithm, which is shared by all functions in the `round()',
* `lround()' and `llround()' families.
*
* Written by Keith Marshall <keithmarshall@users.sourceforge.net>
*
* This is free software. You may redistribute and/or modify it as you
* see fit, without restriction of copyright.
*
* This software is provided "as is", in the hope that it may be useful,
* but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of
* MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no
* time will the author accept any form of liability for any damages,
* however caused, resulting from the use of this software.
*
*/
#define _ROUND_INTERNAL_H
 
#include <math.h>
#include <fenv.h>
 
#define TYPE_PASTE( NAME, TYPE ) NAME##TYPE
 
#define INPUT_TYPE INPUT_TYPEDEF( FUNCTION )
#define INPUT_TYPEDEF( FUNCTION ) TYPE_PASTE( FUNCTION, _input_type )
/*
* The types for the formal parameter, to each of the derived functions.
*/
#define round_input_type double
#define roundf_input_type float
#define roundl_input_type long double
 
#define lround_input_type double
#define lroundf_input_type float
#define lroundl_input_type long double
 
#define llround_input_type double
#define llroundf_input_type float
#define llroundl_input_type long double
 
#define RETURN_TYPE RETURN_TYPEDEF( FUNCTION )
#define RETURN_TYPEDEF( FUNCTION ) TYPE_PASTE( FUNCTION, _return_type )
/*
* The types for the return value, from each of the derived functions.
*/
#define round_return_type double
#define roundf_return_type float
#define roundl_return_type long double
 
#define lround_return_type long
#define lroundf_return_type long
#define lroundl_return_type long
 
#define llround_return_type long long
#define llroundf_return_type long long
#define llroundl_return_type long long
 
#define MAX_RETURN_VALUE RETURN_MAX( FUNCTION )
#define RETURN_MAX( FUNCTION ) TYPE_PASTE( FUNCTION, _return_max )
/*
* The maximum values which may be returned by each of the derived functions
* in the `lround' or the `llround' families.
*/
#define lround_return_max LONG_MAX
#define lroundf_return_max LONG_MAX
#define lroundl_return_max LONG_MAX
 
#define llround_return_max LLONG_MAX
#define llroundf_return_max LLONG_MAX
#define llroundl_return_max LLONG_MAX
 
#define MIN_RETURN_VALUE RETURN_MIN( FUNCTION )
#define RETURN_MIN( FUNCTION ) TYPE_PASTE( FUNCTION, _return_min )
/*
* The minimum values which may be returned by each of the derived functions
* in the `lround' or the `llround' families.
*/
#define lround_return_min LONG_MIN
#define lroundf_return_min LONG_MIN
#define lroundl_return_min LONG_MIN
 
#define llround_return_min LLONG_MIN
#define llroundf_return_min LLONG_MIN
#define llroundl_return_min LLONG_MIN
 
#define REF_VALUE( VALUE ) REF_TYPE( FUNCTION, VALUE )
#define REF_TYPE( FUNC, VAL ) TYPE_PASTE( FUNC, _ref )( VAL )
/*
* Macros for expressing constant values of the appropriate data type,
* for use in each of the derived functions.
*/
#define round_ref( VALUE ) VALUE
#define lround_ref( VALUE ) VALUE
#define llround_ref( VALUE ) VALUE
 
#define roundl_ref( VALUE ) TYPE_PASTE( VALUE, L )
#define lroundl_ref( VALUE ) TYPE_PASTE( VALUE, L )
#define llroundl_ref( VALUE ) TYPE_PASTE( VALUE, L )
 
#define roundf_ref( VALUE ) TYPE_PASTE( VALUE, F )
#define lroundf_ref( VALUE ) TYPE_PASTE( VALUE, F )
#define llroundf_ref( VALUE ) TYPE_PASTE( VALUE, F )
 
static __inline__
INPUT_TYPE __attribute__(( always_inline )) round_internal( INPUT_TYPE x )
#define ROUND_MODES ( FE_TONEAREST | FE_UPWARD | FE_DOWNWARD | FE_TOWARDZERO )
{
/* Generic helper function, for rounding of the input parameter value to
* the nearest integer value.
*/
INPUT_TYPE z;
unsigned short saved_CW, tmp_required_CW;
 
/* Rounding method suggested by Danny Smith <dannysmith@users.sf.net>
*
* Save the FPU control word state, set rounding mode TONEAREST, round the
* input value, then restore the original FPU control word state.
*/
__asm__( "fnstcw %0;" : "=m"( saved_CW ));
tmp_required_CW = ( saved_CW & ~ROUND_MODES ) | FE_TONEAREST;
__asm__( "fldcw %0;" :: "m"( tmp_required_CW ));
__asm__( "frndint;" : "=t"( z ) : "0"( x ));
__asm__( "fldcw %0;" :: "m"( saved_CW ));
 
/* We now have a possible rounded value; unfortunately the FPU uses the
* `round-to-even' rule for exact mid-way cases, where both C99 and POSIX
* require us to always round away from zero, so we need to adjust those
* mid-way cases which the FPU rounded in the wrong direction.
*
* Correction method suggested by Greg Chicares <gchicares@sbcglobal.net>
*/
return x < REF_VALUE( 0.0 )
? /*
* For negative input values, an incorrectly rounded value will be
* exactly 0.5 greater than the original value; when we find such an
* exact rounding offset, we must subtract an additional 1.0 from the
* rounded result, otherwise we return the rounded result unchanged.
*/
z - x == REF_VALUE( 0.5 ) ? z - REF_VALUE( 1.0 ) : z
 
: /* For positive input values, an incorrectly rounded value will be
* exactly 0.5 less than the original value; when we find such an exact
* rounding offset, we must add an additional 1.0 to the rounded result,
* otherwise we return the rounded result unchanged.
*/
x - z == REF_VALUE( 0.5 ) ? z + REF_VALUE( 1.0 ) : z;
}
 
#endif /* !defined _ROUND_INTERNAL_H: $RCSfile: round_internal.h,v $: end of file */
/programs/develop/libraries/newlib/math/s_erf.c
0,0 → 1,345
 
/* @(#)s_erf.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
 
/* double erf(double x)
* double erfc(double x)
* x
* 2 |\
* erf(x) = --------- | exp(-t*t)dt
* sqrt(pi) \|
* 0
*
* erfc(x) = 1-erf(x)
* Note that
* erf(-x) = -erf(x)
* erfc(-x) = 2 - erfc(x)
*
* Method:
* 1. For |x| in [0, 0.84375]
* erf(x) = x + x*R(x^2)
* erfc(x) = 1 - erf(x) if x in [-.84375,0.25]
* = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375]
* where R = P/Q where P is an odd poly of degree 8 and
* Q is an odd poly of degree 10.
* -57.90
* | R - (erf(x)-x)/x | <= 2
*
*
* Remark. The formula is derived by noting
* erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
* and that
* 2/sqrt(pi) = 1.128379167095512573896158903121545171688
* is close to one. The interval is chosen because the fix
* point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
* near 0.6174), and by some experiment, 0.84375 is chosen to
* guarantee the error is less than one ulp for erf.
*
* 2. For |x| in [0.84375,1.25], let s = |x| - 1, and
* c = 0.84506291151 rounded to single (24 bits)
* erf(x) = sign(x) * (c + P1(s)/Q1(s))
* erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0
* 1+(c+P1(s)/Q1(s)) if x < 0
* |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06
* Remark: here we use the taylor series expansion at x=1.
* erf(1+s) = erf(1) + s*Poly(s)
* = 0.845.. + P1(s)/Q1(s)
* That is, we use rational approximation to approximate
* erf(1+s) - (c = (single)0.84506291151)
* Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
* where
* P1(s) = degree 6 poly in s
* Q1(s) = degree 6 poly in s
*
* 3. For x in [1.25,1/0.35(~2.857143)],
* erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1)
* erf(x) = 1 - erfc(x)
* where
* R1(z) = degree 7 poly in z, (z=1/x^2)
* S1(z) = degree 8 poly in z
*
* 4. For x in [1/0.35,28]
* erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
* = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0
* = 2.0 - tiny (if x <= -6)
* erf(x) = sign(x)*(1.0 - erfc(x)) if x < 6, else
* erf(x) = sign(x)*(1.0 - tiny)
* where
* R2(z) = degree 6 poly in z, (z=1/x^2)
* S2(z) = degree 7 poly in z
*
* Note1:
* To compute exp(-x*x-0.5625+R/S), let s be a single
* precision number and s := x; then
* -x*x = -s*s + (s-x)*(s+x)
* exp(-x*x-0.5626+R/S) =
* exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
* Note2:
* Here 4 and 5 make use of the asymptotic series
* exp(-x*x)
* erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
* x*sqrt(pi)
* We use rational approximation to approximate
* g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625
* Here is the error bound for R1/S1 and R2/S2
* |R1/S1 - f(x)| < 2**(-62.57)
* |R2/S2 - f(x)| < 2**(-61.52)
*
* 5. For inf > x >= 28
* erf(x) = sign(x) *(1 - tiny) (raise inexact)
* erfc(x) = tiny*tiny (raise underflow) if x > 0
* = 2 - tiny if x<0
*
* 7. Special case:
* erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
* erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
* erfc/erf(NaN) is NaN
*/
 
 
/* #include "fdlibm.h" */
 
#include <math.h>
#include <stdint.h>
#include <errno.h>
 
#define __ieee754_exp exp
 
typedef union
{
double value;
struct
{
uint32_t lsw;
uint32_t msw;
} parts;
} ieee_double_shape_type;
 
 
static inline int __get_hi_word(const double x)
{
ieee_double_shape_type u;
u.value = x;
return u.parts.msw;
}
 
static inline void __trunc_lo_word(double *x)
{
ieee_double_shape_type u;
u.value = *x;
u.parts.lsw = 0;
*x = u.value;
}
 
 
#ifdef __STDC__
static const double
#else
static double
#endif
tiny = 1e-300,
half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
/* c = (float)0.84506291151 */
erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */
/*
* Coefficients for approximation to erf on [0,0.84375]
*/
efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */
efx8= 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */
pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */
pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */
pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */
pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */
pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */
qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */
qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */
qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */
qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */
qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */
/*
* Coefficients for approximation to erf in [0.84375,1.25]
*/
pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */
pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */
pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */
pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */
pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */
pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */
pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */
qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */
qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */
qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */
qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */
qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */
qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */
/*
* Coefficients for approximation to erfc in [1.25,1/0.35]
*/
ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */
ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */
ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */
ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */
ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */
ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */
ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */
ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */
sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */
sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */
sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */
sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */
sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */
sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */
sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */
sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */
/*
* Coefficients for approximation to erfc in [1/.35,28]
*/
rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */
rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */
rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */
rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */
rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */
rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */
rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */
sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */
sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */
sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */
sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */
sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */
sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */
sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */
 
#ifdef __STDC__
double erf(double x)
#else
double erf(x)
double x;
#endif
{
int hx,ix,i;
double R,S,P,Q,s,y,z,r;
hx = __get_hi_word(x);
ix = hx&0x7fffffff;
if(ix>=0x7ff00000) { /* erf(nan)=nan */
i = ((unsigned)hx>>31)<<1;
return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */
}
 
if(ix < 0x3feb0000) { /* |x|<0.84375 */
if(ix < 0x3e300000) { /* |x|<2**-28 */
if (ix < 0x00800000)
return 0.125*(8.0*x+efx8*x); /*avoid underflow */
return x + efx*x;
}
z = x*x;
r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
y = r/s;
return x + x*y;
}
if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */
s = fabs(x)-one;
P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
if(hx>=0) return erx + P/Q; else return -erx - P/Q;
}
if (ix >= 0x40180000) { /* inf>|x|>=6 */
if(hx>=0) return one-tiny; else return tiny-one;
}
x = fabs(x);
s = one/(x*x);
if(ix< 0x4006DB6E) { /* |x| < 1/0.35 */
R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
ra5+s*(ra6+s*ra7))))));
S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
sa5+s*(sa6+s*(sa7+s*sa8)))))));
} else { /* |x| >= 1/0.35 */
R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
rb5+s*rb6)))));
S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
sb5+s*(sb6+s*sb7))))));
}
z = x;
__trunc_lo_word(&z);
r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S);
if(hx>=0) return one-r/x; else return r/x-one;
}
 
#ifdef __STDC__
double erfc(double x)
#else
double erfc(x)
double x;
#endif
{
int hx,ix;
double R,S,P,Q,s,y,z,r;
hx = __get_hi_word(x);
ix = hx&0x7fffffff;
if(ix>=0x7ff00000) { /* erfc(nan)=nan */
/* erfc(+-inf)=0,2 */
return (double)(((unsigned)hx>>31)<<1)+one/x;
}
 
if(ix < 0x3feb0000) { /* |x|<0.84375 */
if(ix < 0x3c700000) /* |x|<2**-56 */
return one-x;
z = x*x;
r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
y = r/s;
if(hx < 0x3fd00000) { /* x<1/4 */
return one-(x+x*y);
} else {
r = x*y;
r += (x-half);
return half - r ;
}
}
if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */
s = fabs(x)-one;
P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
if(hx>=0) {
z = one-erx; return z - P/Q;
} else {
z = erx+P/Q; return one+z;
}
}
if (ix < 0x403c0000) { /* |x|<28 */
x = fabs(x);
s = one/(x*x);
if(ix< 0x4006DB6D) { /* |x| < 1/.35 ~ 2.857143*/
R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
ra5+s*(ra6+s*ra7))))));
S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
sa5+s*(sa6+s*(sa7+s*sa8)))))));
} else { /* |x| >= 1/.35 ~ 2.857143 */
if(hx<0&&ix>=0x40180000) return two-tiny;/* x < -6 */
R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
rb5+s*rb6)))));
S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
sb5+s*(sb6+s*sb7))))));
}
z = x;
__trunc_lo_word(&z);
r = __ieee754_exp(-z*z-0.5625)*
__ieee754_exp((z-x)*(z+x)+R/S);
if(hx>0) return r/x; else return two-r/x;
} else {
/* set range error */
errno = ERANGE;
if(hx>0) return tiny*tiny; else return two-tiny;
}
}
/programs/develop/libraries/newlib/math/s_expm1.S
0,0 → 1,70
/* ix87 specific implementation of exp(x)-1.
Copyright (C) 1996, 1997, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
Based on code by John C. Bowman <bowman@ipp-garching.mpg.de>.
Corrections by H.J. Lu (hjl@gnu.ai.mit.edu), 1997.
 
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.
 
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, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
 
/* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
 
.file "s_expm1.s"
.text
.align 4
 
minus1: .double -1.0
one: .double 1.0
l2e: .tfloat 1.442695040888963407359924681002
 
.align 4
.globl ___expm1
.def __expm1; .scl 2; .type 32; .endef
 
___expm1:
fldl 4(%esp) # x
fxam # Is NaN or +-Inf?
fstsw %ax
movb $0x45, %ch
andb %ah, %ch
cmpb $0x40, %ch
je 3f # If +-0, jump.
 
cmpb $0x05, %ch
je 2f # If +-Inf, jump.
 
fldt l2e # log2(e) : x
fmulp # log2(e)*x
fld %st # log2(e)*x : log2(e)*x
frndint # int(log2(e)*x) : log2(e)*x
fsubr %st, %st(1) # int(log2(e)*x) : fract(log2(e)*x)
fxch # fract(log2(e)*x) : int(log2(e)*x)
f2xm1 # 2^fract(log2(e)*x)-1 : int(log2(e)*x)
fscale # 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x)
fxch # int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
fldl one # 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
fscale # 2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
fsubrl one # 1-2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
fstp %st(1) # 1-2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
fsubrp %st, %st(1) # 2^(log2(e)*x)
ret
 
2: testl $0x200, %eax # Test sign.
jz 3f # If positive, jump.
fstp %st
fldl minus1 # Set result to -1.0.
3: ret
 
/programs/develop/libraries/newlib/math/s_fpclassify.c
0,0 → 1,31
/* Copyright (C) 2002, 2007 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 "fdlibm.h"
 
int
__fpclassifyd (double x)
{
__uint32_t msw, lsw;
 
EXTRACT_WORDS(msw,lsw,x);
 
if ((msw == 0x00000000 && lsw == 0x00000000) ||
(msw == 0x80000000 && lsw == 0x00000000))
return FP_ZERO;
else if ((msw >= 0x00100000 && msw <= 0x7fefffff) ||
(msw >= 0x80100000 && msw <= 0xffefffff))
return FP_NORMAL;
else if ((msw >= 0x00000000 && msw <= 0x000fffff) ||
(msw >= 0x80000000 && msw <= 0x800fffff))
/* zero is already handled above */
return FP_SUBNORMAL;
else if ((msw == 0x7ff00000 && lsw == 0x00000000) ||
(msw == 0xfff00000 && lsw == 0x00000000))
return FP_INFINITE;
else
return FP_NAN;
}
/programs/develop/libraries/newlib/math/s_isnand.c
0,0 → 1,31
/*
* ====================================================
* 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.
* ====================================================
*/
 
 
/*
* __isnand(x) returns 1 is x is nan, else 0;
* no branching!
*/
 
#include "fdlibm.h"
 
int
_DEFUN (__isnand, (x),
double x)
{
__int32_t hx,lx;
EXTRACT_WORDS(hx,lx,x);
hx &= 0x7fffffff;
hx |= (__uint32_t)(lx|(-lx))>>31;
hx = 0x7ff00000 - hx;
return (int)(((__uint32_t)(hx))>>31);
}
 
/programs/develop/libraries/newlib/math/s_modf.c
0,0 → 1,131
 
/* @(#)s_modf.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
 
/*
FUNCTION
<<modf>>, <<modff>>---split fractional and integer parts
 
INDEX
modf
INDEX
modff
 
ANSI_SYNOPSIS
#include <math.h>
double modf(double <[val]>, double *<[ipart]>);
float modff(float <[val]>, float *<[ipart]>);
 
TRAD_SYNOPSIS
#include <math.h>
double modf(<[val]>, <[ipart]>)
double <[val]>;
double *<[ipart]>;
 
float modff(<[val]>, <[ipart]>)
float <[val]>;
float *<[ipart]>;
 
DESCRIPTION
<<modf>> splits the double <[val]> apart into an integer part
and a fractional part, returning the fractional part and
storing the integer part in <<*<[ipart]>>>. No rounding
whatsoever is done; the sum of the integer and fractional
parts is guaranteed to be exactly equal to <[val]>. That
is, if <[realpart]> = modf(<[val]>, &<[intpart]>); then
`<<<[realpart]>+<[intpart]>>>' is the same as <[val]>.
<<modff>> is identical, save that it takes and returns
<<float>> rather than <<double>> values.
 
RETURNS
The fractional part is returned. Each result has the same
sign as the supplied argument <[val]>.
 
PORTABILITY
<<modf>> is ANSI C. <<modff>> is an extension.
 
QUICKREF
modf ansi pure
modff - pure
 
*/
 
/*
* modf(double x, double *iptr)
* return fraction part of x, and return x's integral part in *iptr.
* Method:
* Bit twiddling.
*
* Exception:
* No exception.
*/
 
#include "fdlibm.h"
 
#ifndef _DOUBLE_IS_32BITS
 
#ifdef __STDC__
static const double one = 1.0;
#else
static double one = 1.0;
#endif
 
#ifdef __STDC__
double modf(double x, double *iptr)
#else
double modf(x, iptr)
double x,*iptr;
#endif
{
__int32_t i0,i1,j0;
__uint32_t i;
EXTRACT_WORDS(i0,i1,x);
j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */
if(j0<20) { /* integer part in high x */
if(j0<0) { /* |x|<1 */
INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */
return x;
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) { /* x is integral */
__uint32_t high;
*iptr = x;
GET_HIGH_WORD(high,x);
INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
return x;
} else {
INSERT_WORDS(*iptr,i0&(~i),0);
return x - *iptr;
}
}
} else if (j0>51) { /* no fraction part */
__uint32_t high;
*iptr = x*one;
GET_HIGH_WORD(high,x);
INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
return x;
} else { /* fraction part in low x */
i = ((__uint32_t)(0xffffffff))>>(j0-20);
if((i1&i)==0) { /* x is integral */
__uint32_t high;
*iptr = x;
GET_HIGH_WORD(high,x);
INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
return x;
} else {
INSERT_WORDS(*iptr,i0,i1&(~i));
return x - *iptr;
}
}
}
 
#endif /* _DOUBLE_IS_32BITS */
/programs/develop/libraries/newlib/math/s_roundf.c
0,0 → 1,70
/* Round float to integer away from zero.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
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.
 
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, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
 
#include <math.h>
#include "fdlibm.h"
 
 
static const float huge = 1.0e30;
 
 
float roundf (float x)
{
int i0, j0;
 
GET_FLOAT_WORD (i0, x);
j0 = ((i0 >> 23) & 0xff) - 0x7f;
if (j0 < 23)
{
if (j0 < 0)
{
if (huge + x > 0.0F)
{
i0 &= 0x80000000;
if (j0 == -1)
i0 |= 0x3f800000;
}
}
else
{
unsigned int i = 0x007fffff >> j0;
if ((i0 & i) == 0)
/* X is integral. */
return x;
if (huge + x > 0.0F)
{
/* Raise inexact if x != 0. */
i0 += 0x00400000 >> j0;
i0 &= ~i;
}
}
}
else
{
if (j0 == 0x80)
/* Inf or NaN. */
return x + x;
else
return x;
}
 
SET_FLOAT_WORD (x, i0);
return x;
}
/programs/develop/libraries/newlib/math/s_signbit.c
0,0 → 1,30
/* 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 "fdlibm.h"
 
int __signbitf (float x);
int __signbitd (double x);
 
int
__signbitf (float x)
{
unsigned int w;
 
GET_FLOAT_WORD(w,x);
 
return (w & 0x80000000);
}
 
int
__signbitd (double x)
{
unsigned int msw;
 
GET_HIGH_WORD(msw, x);
 
return (msw & 0x80000000);
}
/programs/develop/libraries/newlib/math/s_tanh.c
0,0 → 1,80
/* @(#)s_tanh.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.
* ====================================================
*/
 
 
/* Tanh(x)
* Return the Hyperbolic Tangent of x
*
* Method :
* x -x
* e - e
* 0. tanh(x) is defined to be -----------
* x -x
* e + e
* 1. reduce x to non-negative by tanh(-x) = -tanh(x).
* 2. 0 <= x <= 2**-55 : tanh(x) := x*(one+x)
* -t
* 2**-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x)
* t + 2
* 2
* 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t=expm1(2x)
* t + 2
* 22.0 < x <= INF : tanh(x) := 1.
*
* Special cases:
* tanh(NaN) is NaN;
* only tanh(0)=0 is exact for finite argument.
*/
 
#include <math.h>
#include "fdlibm.h"
 
#ifdef __STDC__
static const double one=1.0, two=2.0, tiny = 1.0e-300;
#else
static double one=1.0, two=2.0, tiny = 1.0e-300;
#endif
 
double tanh(double x)
{
double t,z;
int jx,ix,lx;
 
/* High word of |x|. */
EXTRACT_WORDS(jx,lx,x);
ix = jx&0x7fffffff;
 
/* x is INF or NaN */
if(ix>=0x7ff00000) {
if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */
else return one/x-one; /* tanh(NaN) = NaN */
}
 
/* |x| < 22 */
if (ix < 0x40360000) { /* |x|<22 */
if ((ix | lx) == 0)
return x; /* x == +-0 */
if (ix<0x3c800000) /* |x|<2**-55 */
return x*(one+x); /* tanh(small) = small */
if (ix>=0x3ff00000) { /* |x|>=1 */
t = __expm1(two*fabs(x));
z = one - two/(t+two);
} else {
t = __expm1(-two*fabs(x));
z= -t/(t+two);
}
/* |x| > 22, return +-1 */
} else {
z = one - tiny; /* raised inexact flag */
}
return (jx>=0)? z: -z;
}
/programs/develop/libraries/newlib/math/scalbn.S
0,0 → 1,19
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
 
.file "scalbn.S"
.text
.align 4
.globl _scalbn
.def _scalbn; .scl 2; .type 32; .endef
_scalbn:
fildl 12(%esp)
fldl 4(%esp)
fscale
fstp %st(1)
ret
 
.globl _scalbln
.set _scalbln,_scalbn
/programs/develop/libraries/newlib/math/scalbnf.S
0,0 → 1,19
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
 
.file "scalbnf.S"
.text
.align 4
.globl _scalbnf
.def _scalbnf; .scl 2; .type 32; .endef
_scalbnf:
fildl 8(%esp)
flds 4(%esp)
fscale
fstp %st(1)
ret
 
.globl _scalblnf
.set _scalblnf,_scalbnf
/programs/develop/libraries/newlib/math/scalbnl.S
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 "scalbnl.S"
.text
.align 4
.globl _scalbnl
.def _scalbnl; .scl 2; .type 32; .endef
_scalbnl:
fildl 16(%esp)
fldt 4(%esp)
fscale
fstp %st(1)
ret
 
.globl _scalblnl
.set _scalblnl,_scalbnl
/programs/develop/libraries/newlib/math/sf_erf.c
0,0 → 1,267
/* sf_erf.c -- float version of s_erf.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
 
/*
* ====================================================
* 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.
* ====================================================
*/
 
/*
#include "fdlibm.h"
*/
#include <math.h>
#include <stdint.h>
#include <errno.h>
 
#define __ieee754_expf expf
 
 
 
typedef union
{
float value;
uint32_t word;
} ieee_float_shape_type;
 
/* Get a 32 bit int from a float. */
 
static inline int
__get_float_word(float d)
{
ieee_float_shape_type u;
u.value = d;
return u.word;
}
 
/* 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)
 
static inline void __trunc_float_word(float * x)
{
ieee_float_shape_type u;
u.value = * x;
u.word &= 0xfffff000;
}
 
#ifdef __v810__
#define const
#endif
 
#ifdef __STDC__
static const float
#else
static float
#endif
tiny = 1e-30,
half= 5.0000000000e-01, /* 0x3F000000 */
one = 1.0000000000e+00, /* 0x3F800000 */
two = 2.0000000000e+00, /* 0x40000000 */
/* c = (subfloat)0.84506291151 */
erx = 8.4506291151e-01, /* 0x3f58560b */
/*
* Coefficients for approximation to erf on [0,0.84375]
*/
efx = 1.2837916613e-01, /* 0x3e0375d4 */
efx8= 1.0270333290e+00, /* 0x3f8375d4 */
pp0 = 1.2837916613e-01, /* 0x3e0375d4 */
pp1 = -3.2504209876e-01, /* 0xbea66beb */
pp2 = -2.8481749818e-02, /* 0xbce9528f */
pp3 = -5.7702702470e-03, /* 0xbbbd1489 */
pp4 = -2.3763017452e-05, /* 0xb7c756b1 */
qq1 = 3.9791721106e-01, /* 0x3ecbbbce */
qq2 = 6.5022252500e-02, /* 0x3d852a63 */
qq3 = 5.0813062117e-03, /* 0x3ba68116 */
qq4 = 1.3249473704e-04, /* 0x390aee49 */
qq5 = -3.9602282413e-06, /* 0xb684e21a */
/*
* Coefficients for approximation to erf in [0.84375,1.25]
*/
pa0 = -2.3621185683e-03, /* 0xbb1acdc6 */
pa1 = 4.1485610604e-01, /* 0x3ed46805 */
pa2 = -3.7220788002e-01, /* 0xbebe9208 */
pa3 = 3.1834661961e-01, /* 0x3ea2fe54 */
pa4 = -1.1089469492e-01, /* 0xbde31cc2 */
pa5 = 3.5478305072e-02, /* 0x3d1151b3 */
pa6 = -2.1663755178e-03, /* 0xbb0df9c0 */
qa1 = 1.0642088205e-01, /* 0x3dd9f331 */
qa2 = 5.4039794207e-01, /* 0x3f0a5785 */
qa3 = 7.1828655899e-02, /* 0x3d931ae7 */
qa4 = 1.2617121637e-01, /* 0x3e013307 */
qa5 = 1.3637083583e-02, /* 0x3c5f6e13 */
qa6 = 1.1984500103e-02, /* 0x3c445aa3 */
/*
* Coefficients for approximation to erfc in [1.25,1/0.35]
*/
ra0 = -9.8649440333e-03, /* 0xbc21a093 */
ra1 = -6.9385856390e-01, /* 0xbf31a0b7 */
ra2 = -1.0558626175e+01, /* 0xc128f022 */
ra3 = -6.2375331879e+01, /* 0xc2798057 */
ra4 = -1.6239666748e+02, /* 0xc322658c */
ra5 = -1.8460508728e+02, /* 0xc3389ae7 */
ra6 = -8.1287437439e+01, /* 0xc2a2932b */
ra7 = -9.8143291473e+00, /* 0xc11d077e */
sa1 = 1.9651271820e+01, /* 0x419d35ce */
sa2 = 1.3765776062e+02, /* 0x4309a863 */
sa3 = 4.3456588745e+02, /* 0x43d9486f */
sa4 = 6.4538726807e+02, /* 0x442158c9 */
sa5 = 4.2900814819e+02, /* 0x43d6810b */
sa6 = 1.0863500214e+02, /* 0x42d9451f */
sa7 = 6.5702495575e+00, /* 0x40d23f7c */
sa8 = -6.0424413532e-02, /* 0xbd777f97 */
/*
* Coefficients for approximation to erfc in [1/.35,28]
*/
rb0 = -9.8649431020e-03, /* 0xbc21a092 */
rb1 = -7.9928326607e-01, /* 0xbf4c9dd4 */
rb2 = -1.7757955551e+01, /* 0xc18e104b */
rb3 = -1.6063638306e+02, /* 0xc320a2ea */
rb4 = -6.3756646729e+02, /* 0xc41f6441 */
rb5 = -1.0250950928e+03, /* 0xc480230b */
rb6 = -4.8351919556e+02, /* 0xc3f1c275 */
sb1 = 3.0338060379e+01, /* 0x41f2b459 */
sb2 = 3.2579251099e+02, /* 0x43a2e571 */
sb3 = 1.5367296143e+03, /* 0x44c01759 */
sb4 = 3.1998581543e+03, /* 0x4547fdbb */
sb5 = 2.5530502930e+03, /* 0x451f90ce */
sb6 = 4.7452853394e+02, /* 0x43ed43a7 */
sb7 = -2.2440952301e+01; /* 0xc1b38712 */
 
#ifdef __STDC__
float erff(float x)
#else
float erff(x)
float x;
#endif
{
int32_t hx,ix,i;
float R,S,P,Q,s,y,z,r;
hx = __get_float_word(x);
ix = hx&0x7fffffff;
if(!(ix<0x7f800000L)) { /* erf(nan)=nan */
i = ((uint32_t)hx>>31)<<1;
return (float)(1-i)+one/x; /* erf(+-inf)=+-1 */
}
 
if(ix < 0x3f580000) { /* |x|<0.84375 */
if(ix < 0x31800000) { /* |x|<2**-28 */
if (ix < 0x04000000)
/*avoid underflow */
return (float)0.125*((float)8.0*x+efx8*x);
return x + efx*x;
}
z = x*x;
r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
y = r/s;
return x + x*y;
}
if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */
s = fabsf(x)-one;
P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
if(hx>=0) return erx + P/Q; else return -erx - P/Q;
}
if (ix >= 0x40c00000) { /* inf>|x|>=6 */
if(hx>=0) return one-tiny; else return tiny-one;
}
x = fabsf(x);
s = one/(x*x);
if(ix< 0x4036DB6E) { /* |x| < 1/0.35 */
R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
ra5+s*(ra6+s*ra7))))));
S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
sa5+s*(sa6+s*(sa7+s*sa8)))))));
} else { /* |x| >= 1/0.35 */
R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
rb5+s*rb6)))));
S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
sb5+s*(sb6+s*sb7))))));
}
 
z = x;
__trunc_float_word (&z);
r = __ieee754_expf(-z*z-(float)0.5625)*__ieee754_expf((z-x)*(z+x)+R/S);
if(hx>=0) return one-r/x; else return r/x-one;
}
 
#ifdef __STDC__
float erfcf(float x)
#else
float erfcf(x)
float x;
#endif
{
int32_t hx,ix;
float R,S,P,Q,s,y,z,r;
hx = __get_float_word(x);
ix = hx&0x7fffffff;
if(!(ix<0x7f800000L)) { /* erfc(nan)=nan */
/* erfc(+-inf)=0,2 */
return (float)(((uint32_t)hx>>31)<<1)+one/x;
}
 
if(ix < 0x3f580000) { /* |x|<0.84375 */
if(ix < 0x23800000) /* |x|<2**-56 */
return one-x;
z = x*x;
r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
y = r/s;
if(hx < 0x3e800000) { /* x<1/4 */
return one-(x+x*y);
} else {
r = x*y;
r += (x-half);
return half - r ;
}
}
if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */
s = fabsf(x)-one;
P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
if(hx>=0) {
z = one-erx; return z - P/Q;
} else {
z = erx+P/Q; return one+z;
}
}
 
if (ix < 0x41e00000) { /* |x|<28 */
x = fabsf(x);
s = one/(x*x);
if(ix< 0x4036DB6D) { /* |x| < 1/.35 ~ 2.857143*/
R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
ra5+s*(ra6+s*ra7))))));
S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
sa5+s*(sa6+s*(sa7+s*sa8)))))));
} else { /* |x| >= 1/.35 ~ 2.857143 */
if(hx<0&&ix>=0x40c00000) return two-tiny;/* x < -6 */
R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
rb5+s*rb6)))));
S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
sb5+s*(sb6+s*sb7))))));
}
z = x;
__trunc_float_word (&z);
r = __ieee754_expf(-z*z-(float)0.5625)*
__ieee754_expf((z-x)*(z+x)+R/S);
if(hx>0) return r/x; else return two-r/x;
} else {
/* set range error */
errno = ERANGE;
if(hx>0) return tiny*tiny; else return two-tiny;
}
}
/programs/develop/libraries/newlib/math/signbit.c
0,0 → 1,21
#define __FP_SIGNBIT 0x0200
 
int __signbit (double x) {
unsigned short sw;
__asm__ ("fxam; fstsw %%ax;"
: "=a" (sw)
: "t" (x) );
return (sw & __FP_SIGNBIT) != 0;
}
 
int __signbitd (double x) {
unsigned short sw;
__asm__ ("fxam; fstsw %%ax;"
: "=a" (sw)
: "t" (x) );
return (sw & __FP_SIGNBIT) != 0;
}
 
#undef signbit
int __attribute__ ((alias ("__signbit"))) signbit (double);
 
/programs/develop/libraries/newlib/math/signbitf.c
0,0 → 1,10
#define __FP_SIGNBIT 0x0200
 
int __signbitf (float x) {
unsigned short sw;
__asm__ ("fxam; fstsw %%ax;"
: "=a" (sw)
: "t" (x) );
return (sw & __FP_SIGNBIT) != 0;
}
int __attribute__ ((alias ("__signbitf"))) signbitf (float);
/programs/develop/libraries/newlib/math/signbitl.c
0,0 → 1,11
#define __FP_SIGNBIT 0x0200
 
int __signbitl (long double x) {
unsigned short sw;
__asm__ ("fxam; fstsw %%ax;"
: "=a" (sw)
: "t" (x) );
return (sw & __FP_SIGNBIT) != 0;
}
 
int __attribute__ ((alias ("__signbitl"))) signbitl (long double);
/programs/develop/libraries/newlib/math/sin.S
0,0 → 1,30
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
.file "sin.s"
.text
.align 4
.globl _sin
.def _sin; .scl 2; .type 32; .endef
_sin:
fldl 4(%esp)
fsin
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)
fsin
ret
/programs/develop/libraries/newlib/math/sinf.S
0,0 → 1,32
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted 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 "sinf.S"
.text
.align 4
.globl _sinf
.def _sinf; .scl 2; .type 32; .endef
_sinf:
flds 4(%esp)
fsin
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)
fsin
ret
/programs/develop/libraries/newlib/math/single.h
0,0 → 1,151
/* Software floating-point emulation.
Definitions for IEEE Single Precision.
Copyright (C) 1997,1998,1999,2006 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
 
#define _FP_FRACTBITS_S _FP_W_TYPE_SIZE
 
#define _FP_FRACBITS_S 24
#define _FP_FRACXBITS_S (_FP_FRACTBITS_S - _FP_FRACBITS_S)
#define _FP_WFRACBITS_S (_FP_WORKBITS + _FP_FRACBITS_S)
#define _FP_WFRACXBITS_S (_FP_FRACTBITS_S - _FP_WFRACBITS_S)
#define _FP_EXPBITS_S 8
#define _FP_EXPBIAS_S 127
#define _FP_EXPMAX_S 255
#define _FP_QNANBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2))
#define _FP_QNANBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2+_FP_WORKBITS))
#define _FP_IMPLBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1))
#define _FP_IMPLBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1+_FP_WORKBITS))
#define _FP_OVERFLOW_S ((_FP_W_TYPE)1 << (_FP_WFRACBITS_S))
 
/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be
chosen by the target machine. */
 
typedef float SFtype __attribute__((mode(SF)));
 
union _FP_UNION_S
{
SFtype flt;
struct {
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned sign : 1;
unsigned exp : _FP_EXPBITS_S;
unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
#else
unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
unsigned exp : _FP_EXPBITS_S;
unsigned sign : 1;
#endif
} bits __attribute__((packed));
};
 
#define FP_DECL_S(X) _FP_DECL(1,X)
#define FP_UNPACK_RAW_S(X,val) _FP_UNPACK_RAW_1(S,X,val)
#define FP_UNPACK_RAW_SP(X,val) _FP_UNPACK_RAW_1_P(S,X,val)
#define FP_PACK_RAW_S(val,X) _FP_PACK_RAW_1(S,val,X)
#define FP_PACK_RAW_SP(val,X) \
do { \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_1_P(S,val,X); \
} while (0)
 
#define FP_UNPACK_S(X,val) \
do { \
_FP_UNPACK_RAW_1(S,X,val); \
_FP_UNPACK_CANONICAL(S,1,X); \
} while (0)
 
#define FP_UNPACK_SP(X,val) \
do { \
_FP_UNPACK_RAW_1_P(S,X,val); \
_FP_UNPACK_CANONICAL(S,1,X); \
} while (0)
 
#define FP_UNPACK_SEMIRAW_S(X,val) \
do { \
_FP_UNPACK_RAW_1(S,X,val); \
_FP_UNPACK_SEMIRAW(S,1,X); \
} while (0)
 
#define FP_UNPACK_SEMIRAW_SP(X,val) \
do { \
_FP_UNPACK_RAW_1_P(S,X,val); \
_FP_UNPACK_SEMIRAW(S,1,X); \
} while (0)
 
#define FP_PACK_S(val,X) \
do { \
_FP_PACK_CANONICAL(S,1,X); \
_FP_PACK_RAW_1(S,val,X); \
} while (0)
 
#define FP_PACK_SP(val,X) \
do { \
_FP_PACK_CANONICAL(S,1,X); \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_1_P(S,val,X); \
} while (0)
 
#define FP_PACK_SEMIRAW_S(val,X) \
do { \
_FP_PACK_SEMIRAW(S,1,X); \
_FP_PACK_RAW_1(S,val,X); \
} while (0)
 
#define FP_PACK_SEMIRAW_SP(val,X) \
do { \
_FP_PACK_SEMIRAW(S,1,X); \
if (!FP_INHIBIT_RESULTS) \
_FP_PACK_RAW_1_P(S,val,X); \
} while (0)
 
#define FP_ISSIGNAN_S(X) _FP_ISSIGNAN(S,1,X)
#define FP_NEG_S(R,X) _FP_NEG(S,1,R,X)
#define FP_ADD_S(R,X,Y) _FP_ADD(S,1,R,X,Y)
#define FP_SUB_S(R,X,Y) _FP_SUB(S,1,R,X,Y)
#define FP_MUL_S(R,X,Y) _FP_MUL(S,1,R,X,Y)
#define FP_DIV_S(R,X,Y) _FP_DIV(S,1,R,X,Y)
#define FP_SQRT_S(R,X) _FP_SQRT(S,1,R,X)
#define _FP_SQRT_MEAT_S(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q)
 
#define FP_CMP_S(r,X,Y,un) _FP_CMP(S,1,r,X,Y,un)
#define FP_CMP_EQ_S(r,X,Y) _FP_CMP_EQ(S,1,r,X,Y)
#define FP_CMP_UNORD_S(r,X,Y) _FP_CMP_UNORD(S,1,r,X,Y)
 
#define FP_TO_INT_S(r,X,rsz,rsg) _FP_TO_INT(S,1,r,X,rsz,rsg)
#define FP_FROM_INT_S(X,r,rs,rt) _FP_FROM_INT(S,1,X,r,rs,rt)
 
#define _FP_FRAC_HIGH_S(X) _FP_FRAC_HIGH_1(X)
#define _FP_FRAC_HIGH_RAW_S(X) _FP_FRAC_HIGH_1(X)
/programs/develop/libraries/newlib/math/sinhf.c
0,0 → 1,3
#include <math.h>
float sinhf (float x)
{return (float) sinh (x);}
/programs/develop/libraries/newlib/math/sinhl.c
0,0 → 1,172
/* sinhl.c
*
* Hyperbolic sine, long double precision
*
*
*
* SYNOPSIS:
*
* long double x, y, sinhl();
*
* y = sinhl( x );
*
*
*
* DESCRIPTION:
*
* Returns hyperbolic sine of argument in the range MINLOGL to
* MAXLOGL.
*
* The range is partitioned into two segments. If |x| <= 1, a
* rational function of the form x + x**3 P(x)/Q(x) is employed.
* Otherwise the calculation is sinh(x) = ( exp(x) - exp(-x) )/2.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE -2,2 10000 1.5e-19 3.9e-20
* IEEE +-10000 30000 1.1e-19 2.8e-20
*
*/
/*
Cephes Math Library Release 2.7: January, 1998
Copyright 1984, 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
 
#ifdef UNK
static long double P[] = {
1.7550769032975377032681E-6L,
4.1680702175874268714539E-4L,
3.0993532520425419002409E-2L,
9.9999999999999999998002E-1L,
};
static long double Q[] = {
1.7453965448620151484660E-8L,
-5.9116673682651952419571E-6L,
1.0599252315677389339530E-3L,
-1.1403880487744749056675E-1L,
6.0000000000000000000200E0L,
};
#endif
 
#ifdef IBMPC
static const unsigned short P[] = {
0xec6a,0xd942,0xfbb3,0xeb8f,0x3feb, XPD
0x365e,0xb30a,0xe437,0xda86,0x3ff3, XPD
0x8890,0x01f6,0x2612,0xfde6,0x3ff9, XPD
0x0000,0x0000,0x0000,0x8000,0x3fff, XPD
};
static const unsigned short Q[] = {
0x4edd,0x4c21,0xad09,0x95ed,0x3fe5, XPD
0x4376,0x9b70,0xd605,0xc65c,0xbfed, XPD
0xc8ad,0x5d21,0x3069,0x8aed,0x3ff5, XPD
0x9c32,0x6374,0x2d4b,0xe98d,0xbffb, XPD
0x0000,0x0000,0x0000,0xc000,0x4001, XPD
};
#endif
 
#ifdef MIEEE
static long P[] = {
0x3feb0000,0xeb8ffbb3,0xd942ec6a,
0x3ff30000,0xda86e437,0xb30a365e,
0x3ff90000,0xfde62612,0x01f68890,
0x3fff0000,0x80000000,0x00000000,
};
static long Q[] = {
0x3fe50000,0x95edad09,0x4c214edd,
0xbfed0000,0xc65cd605,0x9b704376,
0x3ff50000,0x8aed3069,0x5d21c8ad,
0xbffb0000,0xe98d2d4b,0x63749c32,
0x40010000,0xc0000000,0x00000000,
};
#endif
 
#ifndef __MINGW32__
extern long double MAXNUML, MAXLOGL, MINLOGL, LOGE2L;
#ifdef ANSIPROT
extern long double fabsl ( long double );
extern long double expl ( long double );
extern long double polevll ( long double, void *, int );
extern long double p1evll ( long double, void *, int );
#else
long double fabsl(), expl(), polevll(), p1evll();
#endif
#ifdef INFINITIES
extern long double INFINITYL;
#endif
#ifdef NANS
extern long double NANL;
#endif
#endif /* __MINGW32__ */
 
long double sinhl(x)
long double x;
{
long double a;
 
#ifdef MINUSZERO
if( x == 0.0 )
return(x);
#endif
#ifdef NANS
if (isnanl(x))
{
_SET_ERRNO(EDOM);
}
#endif
a = fabsl(x);
if( (x > (MAXLOGL + LOGE2L)) || (x > -(MINLOGL-LOGE2L) ) )
{
mtherr( "sinhl", DOMAIN );
_SET_ERRNO(ERANGE);
#ifdef INFINITIES
if( x > 0.0L )
return( INFINITYL );
else
return( -INFINITYL );
#else
if( x > 0.0L )
return( MAXNUML );
else
return( -MAXNUML );
#endif
}
if( a > 1.0L )
{
if( a >= (MAXLOGL - LOGE2L) )
{
a = expl(0.5L*a);
a = (0.5L * a) * a;
if( x < 0.0L )
a = -a;
return(a);
}
a = expl(a);
a = 0.5L*a - (0.5L/a);
if( x < 0.0L )
a = -a;
return(a);
}
 
a *= a;
return( x + x * a * (polevll(a,P,3)/polevll(a,Q,4)) );
}
/programs/develop/libraries/newlib/math/sinl.S
0,0 → 1,32
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted 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 "sinl.S"
.text
.align 4
.globl _sinl
.def _sinl; .scl 2; .type 32; .endef
_sinl:
fldt 4(%esp)
fsin
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)
fsin
ret
/programs/develop/libraries/newlib/math/soft-fp.h
0,0 → 1,199
/* Software floating-point emulation.
Copyright (C) 1997,1998,1999,2000,2002,2003,2005,2006,2007
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. */
 
#ifndef SOFT_FP_H
#define SOFT_FP_H
 
 
#define _FP_WORKBITS 3
#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3)
#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2)
#define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1)
#define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0)
 
#ifndef FP_RND_NEAREST
# define FP_RND_NEAREST 0
# define FP_RND_ZERO 1
# define FP_RND_PINF 2
# define FP_RND_MINF 3
#endif
#ifndef FP_ROUNDMODE
# define FP_ROUNDMODE FP_RND_NEAREST
#endif
 
/* By default don't care about exceptions. */
#ifndef FP_EX_INVALID
#define FP_EX_INVALID 0
#endif
#ifndef FP_EX_OVERFLOW
#define FP_EX_OVERFLOW 0
#endif
#ifndef FP_EX_UNDERFLOW
#define FP_EX_UNDERFLOW 0
#endif
#ifndef FP_EX_DIVZERO
#define FP_EX_DIVZERO 0
#endif
#ifndef FP_EX_INEXACT
#define FP_EX_INEXACT 0
#endif
#ifndef FP_EX_DENORM
#define FP_EX_DENORM 0
#endif
 
#ifdef _FP_DECL_EX
#define FP_DECL_EX \
int _fex = 0; \
_FP_DECL_EX
#else
#define FP_DECL_EX int _fex = 0
#endif
 
#ifndef FP_INIT_ROUNDMODE
#define FP_INIT_ROUNDMODE do {} while (0)
#endif
 
#ifndef FP_HANDLE_EXCEPTIONS
#define FP_HANDLE_EXCEPTIONS do {} while (0)
#endif
 
#ifndef FP_INHIBIT_RESULTS
/* By default we write the results always.
* sfp-machine may override this and e.g.
* check if some exceptions are unmasked
* and inhibit it in such a case.
*/
#define FP_INHIBIT_RESULTS 0
#endif
 
#define FP_SET_EXCEPTION(ex) \
_fex |= (ex)
 
#define FP_UNSET_EXCEPTION(ex) \
_fex &= ~(ex)
 
#define FP_CLEAR_EXCEPTIONS \
_fex = 0
 
#define _FP_ROUND_NEAREST(wc, X) \
do { \
if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \
_FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \
} while (0)
 
#define _FP_ROUND_ZERO(wc, X) (void)0
 
#define _FP_ROUND_PINF(wc, X) \
do { \
if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \
_FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \
} while (0)
 
#define _FP_ROUND_MINF(wc, X) \
do { \
if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \
_FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \
} while (0)
 
#define _FP_ROUND(wc, X) \
do { \
if (_FP_FRAC_LOW_##wc(X) & 7) \
FP_SET_EXCEPTION(FP_EX_INEXACT); \
switch (FP_ROUNDMODE) \
{ \
case FP_RND_NEAREST: \
_FP_ROUND_NEAREST(wc,X); \
break; \
case FP_RND_ZERO: \
_FP_ROUND_ZERO(wc,X); \
break; \
case FP_RND_PINF: \
_FP_ROUND_PINF(wc,X); \
break; \
case FP_RND_MINF: \
_FP_ROUND_MINF(wc,X); \
break; \
} \
} while (0)
 
#define FP_CLS_NORMAL 0
#define FP_CLS_ZERO 1
#define FP_CLS_INF 2
#define FP_CLS_NAN 3
 
#define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y))
 
#include "op-1.h"
#include "op-2.h"
#include "op-4.h"
#include "op-8.h"
#include "op-common.h"
 
/* Sigh. Silly things longlong.h needs. */
#define UWtype _FP_W_TYPE
#define W_TYPE_SIZE _FP_W_TYPE_SIZE
 
typedef int QItype __attribute__((mode(QI)));
typedef int SItype __attribute__((mode(SI)));
typedef int DItype __attribute__((mode(DI)));
typedef unsigned int UQItype __attribute__((mode(QI)));
typedef unsigned int USItype __attribute__((mode(SI)));
typedef unsigned int UDItype __attribute__((mode(DI)));
#if _FP_W_TYPE_SIZE == 32
typedef unsigned int UHWtype __attribute__((mode(HI)));
#elif _FP_W_TYPE_SIZE == 64
typedef USItype UHWtype;
#endif
 
#ifndef CMPtype
#define CMPtype int
#endif
 
#define SI_BITS (__CHAR_BIT__ * (int)sizeof(SItype))
#define DI_BITS (__CHAR_BIT__ * (int)sizeof(DItype))
 
#ifndef umul_ppmm
#ifdef _LIBC
#include <stdlib/longlong.h>
#else
#include "longlong.h"
#endif
#endif
 
#ifdef _LIBC
#include <stdlib.h>
#else
extern void abort (void);
#endif
 
#endif
/programs/develop/libraries/newlib/math/sqrtf.c
0,0 → 1,37
#include <math.h>
#include <errno.h>
 
extern float __QNANF;
 
float
sqrtf (float x)
{
if (x < 0.0F )
{
errno = EDOM;
return __QNANF;
}
else
{
float res;
asm ("fsqrt" : "=t" (res) : "0" (x));
return res;
}
}
 
double
sqrt (double x)
{
if (x < 0.0F )
{
errno = EDOM;
return __QNANF;
}
else
{
double res;
asm ("fsqrt" : "=t" (res) : "0" (x));
return res;
}
}
 
/programs/develop/libraries/newlib/math/sqrtl.c
0,0 → 1,20
#include <math.h>
#include <errno.h>
 
extern long double __QNANL;
 
long double
sqrtl (long double x)
{
if (x < 0.0L )
{
errno = EDOM;
return __QNANL;
}
else
{
long double res;
asm ("fsqrt" : "=t" (res) : "0" (x));
return res;
}
}
/programs/develop/libraries/newlib/math/tan.S
0,0 → 1,31
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
.file "tan.s"
.text
.align 4
.globl _tan
.def _tan; .scl 2; .type 32; .endef
_tan:
fldl 4(%esp)
fptan
fnstsw %ax
testl $0x400,%eax
jnz 1f
fstp %st(0)
ret
1: fldpi
fadd %st(0)
fxch %st(1)
2: fprem1
fstsw %ax
testl $0x400,%eax
jnz 2b
fstp %st(1)
fptan
fstp %st(0)
ret
/programs/develop/libraries/newlib/math/tanf.S
0,0 → 1,31
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
.file "tanf.S"
.text
.align 4
.globl _tanf
.def _tanf; .scl 2; .type 32; .endef
_tanf:
flds 4(%esp)
fptan
fnstsw %ax
testl $0x400,%eax
jnz 1f
fstp %st(0)
ret
1: fldpi
fadd %st(0)
fxch %st(1)
2: fprem1
fstsw %ax
testl $0x400,%eax
jnz 2b
fstp %st(1)
fptan
fstp %st(0)
ret
/programs/develop/libraries/newlib/math/tanhf.c
0,0 → 1,3
#include <math.h>
float tanhf (float x)
{return (float) tanh (x);}
/programs/develop/libraries/newlib/math/tanhl.c
0,0 → 1,151
/* tanhl.c
*
* Hyperbolic tangent, long double precision
*
*
*
* SYNOPSIS:
*
* long double x, y, tanhl();
*
* y = tanhl( x );
*
*
*
* DESCRIPTION:
*
* Returns hyperbolic tangent of argument in the range MINLOGL to
* MAXLOGL.
*
* A rational function is used for |x| < 0.625. The form
* x + x**3 P(x)/Q(x) of Cody _& Waite is employed.
* Otherwise,
* tanh(x) = sinh(x)/cosh(x) = 1 - 2/(exp(2x) + 1).
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE -2,2 30000 1.3e-19 2.4e-20
*
*/
/*
Cephes Math Library Release 2.7: May, 1998
Copyright 1984, 1987, 1989, 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
 
#ifdef UNK
static long double P[] = {
-6.8473739392677100872869E-5L,
-9.5658283111794641589011E-1L,
-8.4053568599672284488465E1L,
-1.3080425704712825945553E3L,
};
static long double Q[] = {
/* 1.0000000000000000000000E0L,*/
9.6259501838840336946872E1L,
1.8218117903645559060232E3L,
3.9241277114138477845780E3L,
};
#endif
 
#ifdef IBMPC
static unsigned short P[] = {
0xd2a4,0x1b0c,0x8f15,0x8f99,0xbff1, XPD
0x5959,0x9111,0x9cc7,0xf4e2,0xbffe, XPD
0xb576,0xef5e,0x6d57,0xa81b,0xc005, XPD
0xe3be,0xbfbd,0x5cbc,0xa381,0xc009, XPD
};
static unsigned short Q[] = {
/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
0x687f,0xce24,0xdd6c,0xc084,0x4005, XPD
0x3793,0xc95f,0xfa2f,0xe3b9,0x4009, XPD
0xd5a2,0x1f9c,0x0b1b,0xf542,0x400a, XPD
};
#endif
 
#ifdef MIEEE
static long P[] = {
0xbff10000,0x8f998f15,0x1b0cd2a4,
0xbffe0000,0xf4e29cc7,0x91115959,
0xc0050000,0xa81b6d57,0xef5eb576,
0xc0090000,0xa3815cbc,0xbfbde3be,
};
static long Q[] = {
/*0x3fff0000,0x80000000,0x00000000,*/
0x40050000,0xc084dd6c,0xce24687f,
0x40090000,0xe3b9fa2f,0xc95f3793,
0x400a0000,0xf5420b1b,0x1f9cd5a2,
};
#endif
 
#ifndef __MINGW32__
extern long double MAXLOGL;
#ifdef ANSIPROT
extern long double fabsl ( long double );
extern long double expl ( long double );
extern long double polevll ( long double, void *, int );
extern long double p1evll ( long double, void *, int );
#else
long double fabsl(), expl(), polevll(), p1evll();
#endif
#endif /* __MINGW32__ */
 
long double tanhl(x)
long double x;
{
long double s, z;
 
#ifdef MINUSZERO
if( x == 0.0L )
return(x);
#endif
if (isnanl(x))
{
_SET_ERRNO (EDOM);
return x;
}
 
z = fabsl(x);
if( z > 0.5L * MAXLOGL )
{
_SET_ERRNO (ERANGE);
if( x > 0 )
return( 1.0L );
else
return( -1.0L );
}
if( z >= 0.625L )
{
s = expl(2.0*z);
z = 1.0L - 2.0/(s + 1.0L);
if( x < 0 )
z = -z;
}
else
{
s = x * x;
z = polevll( s, P, 3 )/p1evll(s, Q, 3);
z = x * s * z;
z = x + z;
}
return( z );
}
/programs/develop/libraries/newlib/math/tanl.S
0,0 → 1,33
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted 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 "tanl.S"
.text
.align 4
.globl _tanl
.def _tanl; .scl 2; .type 32; .endef
_tanl:
fldt 4(%esp)
fptan
fnstsw %ax
testl $0x400,%eax
jnz 1f
fstp %st(0)
ret
1: fldpi
fadd %st(0)
fxch %st(1)
2: fprem1
fstsw %ax
testl $0x400,%eax
jnz 2b
fstp %st(1)
fptan
fstp %st(0)
ret
/programs/develop/libraries/newlib/math/tgamma.c
0,0 → 1,388
/* gamma.c
*
* Gamma function
*
*
*
* SYNOPSIS:
*
* double x, y, __tgamma_r();
* int* sgngam;
* y = __tgamma_r( x, sgngam );
*
* double x, y, tgamma();
* y = tgamma( x)
*
*
*
* DESCRIPTION:
*
* Returns gamma function of the argument. The result is
* correctly signed. In the reentrant version the sign (+1 or -1)
* is returned in the variable referenced by sgngam.
*
* Arguments |x| <= 34 are reduced by recurrence and the function
* approximated by a rational function of degree 6/7 in the
* interval (2,3). Large arguments are handled by Stirling's
* formula. Large negative arguments are made positive using
* a reflection formula.
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* DEC -34, 34 10000 1.3e-16 2.5e-17
* IEEE -170,-33 20000 2.3e-15 3.3e-16
* IEEE -33, 33 20000 9.4e-16 2.2e-16
* IEEE 33, 171.6 20000 2.3e-15 3.2e-16
*
* Error for arguments outside the test range will be larger
* owing to error amplification by the exponential function.
*
*/
 
/*
Cephes Math Library Release 2.8: June, 2000
Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
*/
 
 
/*
* 26-11-2002 Modified for mingw.
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
 
#ifndef __MINGW32__
#include "mconf.h"
#else
#include "cephes_mconf.h"
#endif
 
#ifdef UNK
static const double P[] = {
1.60119522476751861407E-4,
1.19135147006586384913E-3,
1.04213797561761569935E-2,
4.76367800457137231464E-2,
2.07448227648435975150E-1,
4.94214826801497100753E-1,
9.99999999999999996796E-1
};
static const double Q[] = {
-2.31581873324120129819E-5,
5.39605580493303397842E-4,
-4.45641913851797240494E-3,
1.18139785222060435552E-2,
3.58236398605498653373E-2,
-2.34591795718243348568E-1,
7.14304917030273074085E-2,
1.00000000000000000320E0
};
#define MAXGAM 171.624376956302725
static const double LOGPI = 1.14472988584940017414;
#endif
 
#ifdef DEC
static const unsigned short P[] = {
0035047,0162701,0146301,0005234,
0035634,0023437,0032065,0176530,
0036452,0137157,0047330,0122574,
0037103,0017310,0143041,0017232,
0037524,0066516,0162563,0164605,
0037775,0004671,0146237,0014222,
0040200,0000000,0000000,0000000
};
static const unsigned short Q[] = {
0134302,0041724,0020006,0116565,
0035415,0072121,0044251,0025634,
0136222,0003447,0035205,0121114,
0036501,0107552,0154335,0104271,
0037022,0135717,0014776,0171471,
0137560,0034324,0165024,0037021,
0037222,0045046,0047151,0161213,
0040200,0000000,0000000,0000000
};
#define MAXGAM 34.84425627277176174
#endif
 
#ifdef IBMPC
static const unsigned short P[] = {
0x2153,0x3998,0xfcb8,0x3f24,
0xbfab,0xe686,0x84e3,0x3f53,
0x14b0,0xe9db,0x57cd,0x3f85,
0x23d3,0x18c4,0x63d9,0x3fa8,
0x7d31,0xdcae,0x8da9,0x3fca,
0xe312,0x3993,0xa137,0x3fdf,
0x0000,0x0000,0x0000,0x3ff0
};
static const unsigned short Q[] = {
0xd3af,0x8400,0x487a,0xbef8,
0x2573,0x2915,0xae8a,0x3f41,
0xb44a,0xe750,0x40e4,0xbf72,
0xb117,0x5b1b,0x31ed,0x3f88,
0xde67,0xe33f,0x5779,0x3fa2,
0x87c2,0x9d42,0x071a,0xbfce,
0x3c51,0xc9cd,0x4944,0x3fb2,
0x0000,0x0000,0x0000,0x3ff0
};
#define MAXGAM 171.624376956302725
#endif
 
#ifdef MIEEE
static const unsigned short P[] = {
0x3f24,0xfcb8,0x3998,0x2153,
0x3f53,0x84e3,0xe686,0xbfab,
0x3f85,0x57cd,0xe9db,0x14b0,
0x3fa8,0x63d9,0x18c4,0x23d3,
0x3fca,0x8da9,0xdcae,0x7d31,
0x3fdf,0xa137,0x3993,0xe312,
0x3ff0,0x0000,0x0000,0x0000
};
static const unsigned short Q[] = {
0xbef8,0x487a,0x8400,0xd3af,
0x3f41,0xae8a,0x2915,0x2573,
0xbf72,0x40e4,0xe750,0xb44a,
0x3f88,0x31ed,0x5b1b,0xb117,
0x3fa2,0x5779,0xe33f,0xde67,
0xbfce,0x071a,0x9d42,0x87c2,
0x3fb2,0x4944,0xc9cd,0x3c51,
0x3ff0,0x0000,0x0000,0x0000
};
#define MAXGAM 171.624376956302725
#endif
 
/* Stirling's formula for the gamma function */
#if UNK
static const double STIR[5] = {
7.87311395793093628397E-4,
-2.29549961613378126380E-4,
-2.68132617805781232825E-3,
3.47222221605458667310E-3,
8.33333333333482257126E-2,
};
#define MAXSTIR 143.01608
static const double SQTPI = 2.50662827463100050242E0;
#endif
#if DEC
static const unsigned short STIR[20] = {
0035516,0061622,0144553,0112224,
0135160,0131531,0037460,0165740,
0136057,0134460,0037242,0077270,
0036143,0107070,0156306,0027751,
0037252,0125252,0125252,0146064,
};
#define MAXSTIR 26.77
static const unsigned short SQT[4] = {
0040440,0066230,0177661,0034055,
};
#define SQTPI *(double *)SQT
#endif
#if IBMPC
static const unsigned short STIR[20] = {
0x7293,0x592d,0xcc72,0x3f49,
0x1d7c,0x27e6,0x166b,0xbf2e,
0x4fd7,0x07d4,0xf726,0xbf65,
0xc5fd,0x1b98,0x71c7,0x3f6c,
0x5986,0x5555,0x5555,0x3fb5,
};
#define MAXSTIR 143.01608
 
static const union
{
unsigned short s[4];
double d;
} sqt = {{0x2706,0x1ff6,0x0d93,0x4004}};
#define SQTPI (sqt.d)
#endif
#if MIEEE
static const unsigned short STIR[20] = {
0x3f49,0xcc72,0x592d,0x7293,
0xbf2e,0x166b,0x27e6,0x1d7c,
0xbf65,0xf726,0x07d4,0x4fd7,
0x3f6c,0x71c7,0x1b98,0xc5fd,
0x3fb5,0x5555,0x5555,0x5986,
};
#define MAXSTIR 143.01608
static const unsigned short SQT[4] = {
0x4004,0x0d93,0x1ff6,0x2706,
};
#define SQTPI *(double *)SQT
#endif
 
#ifndef __MINGW32__
int sgngam = 0;
extern int sgngam;
extern double MAXLOG, MAXNUM, PI;
#ifdef ANSIPROT
extern double pow ( double, double );
extern double log ( double );
extern double exp ( double );
extern double sin ( double );
extern double polevl ( double, void *, int );
extern double p1evl ( double, void *, int );
extern double floor ( double );
extern double fabs ( double );
extern int isnan ( double );
extern int isfinite ( double );
static double stirf ( double );
double lgam ( double );
#else
double pow(), log(), exp(), sin(), polevl(), p1evl(), floor(), fabs();
int isnan(), isfinite();
static double stirf();
double lgam();
#endif
#ifdef INFINITIES
extern double INFINITY;
#endif
#ifdef NANS
extern double NAN;
#endif
#else /* __MINGW32__ */
static double stirf ( double );
#endif
 
/* Gamma function computed by Stirling's formula.
* The polynomial STIR is valid for 33 <= x <= 172.
*/
static double stirf(x)
double x;
{
double y, w, v;
 
w = 1.0/x;
w = 1.0 + w * polevl( w, STIR, 4 );
y = exp(x);
if( x > MAXSTIR )
{ /* Avoid overflow in pow() */
v = pow( x, 0.5 * x - 0.25 );
y = v * (v / y);
}
else
{
y = pow( x, x - 0.5 ) / y;
}
y = SQTPI * y * w;
return( y );
}
 
 
 
double __tgamma_r(double x, int* sgngam)
{
double p, q, z;
int i;
 
*sgngam = 1;
#ifdef NANS
if( isnan(x) )
return(x);
#endif
#ifdef INFINITIES
#ifdef NANS
if( x == INFINITY )
return(x);
if( x == -INFINITY )
return(NAN);
#else
if( !isfinite(x) )
return(x);
#endif
#endif
q = fabs(x);
 
if( q > 33.0 )
{
if( x < 0.0 )
{
p = floor(q);
if( p == q )
{
gsing:
_SET_ERRNO(EDOM);
mtherr( "tgamma", SING );
#ifdef INFINITIES
return (INFINITY);
#else
return (MAXNUM);
#endif
}
i = p;
if( (i & 1) == 0 )
*sgngam = -1;
z = q - p;
if( z > 0.5 )
{
p += 1.0;
z = q - p;
}
z = q * sin( PI * z );
if( z == 0.0 )
{
_SET_ERRNO(ERANGE);
mtherr( "tgamma", OVERFLOW );
#ifdef INFINITIES
return( *sgngam * INFINITY);
#else
return( *sgngam * MAXNUM);
#endif
}
z = fabs(z);
z = PI/(z * stirf(q) );
}
else
{
z = stirf(x);
}
return( *sgngam * z );
}
 
z = 1.0;
while( x >= 3.0 )
{
x -= 1.0;
z *= x;
}
 
while( x < 0.0 )
{
if( x > -1.E-9 )
goto Small;
z /= x;
x += 1.0;
}
 
while( x < 2.0 )
{
if( x < 1.e-9 )
goto Small;
z /= x;
x += 1.0;
}
 
if( x == 2.0 )
return(z);
 
x -= 2.0;
p = polevl( x, P, 6 );
q = polevl( x, Q, 7 );
return( z * p / q );
 
Small:
if( x == 0.0 )
{
goto gsing;
}
else
return( z/((1.0 + 0.5772156649015329 * x) * x) );
}
 
/* This is the C99 version */
 
double tgamma(double x)
{
int local_sgngam=0;
return (__tgamma_r(x, &local_sgngam));
}
/programs/develop/libraries/newlib/math/tgammaf.c
0,0 → 1,265
/* gammaf.c
*
* Gamma function
*
*
*
* SYNOPSIS:
*
* float x, y, __tgammaf_r();
* int* sgngamf;
* y = __tgammaf_r( x, sgngamf );
*
* float x, y, tgammaf();
* y = tgammaf( x);
*
*
* DESCRIPTION:
*
* Returns gamma function of the argument. The result is
* correctly signed. In the reentrant version the sign (+1 or -1)
* is returned in the variable referenced by sgngamf.
*
* Arguments between 0 and 10 are reduced by recurrence and the
* function is approximated by a polynomial function covering
* the interval (2,3). Large arguments are handled by Stirling's
* formula. Negative arguments are made positive using
* a reflection formula.
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE 0,-33 100,000 5.7e-7 1.0e-7
* IEEE -33,0 100,000 6.1e-7 1.2e-7
*
*
*/
 
/*
Cephes Math Library Release 2.7: July, 1998
Copyright 1984, 1987, 1989, 1992, 1998 by Stephen L. Moshier
*/
 
 
/*
* 26-11-2002 Modified for mingw.
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
 
#ifndef __MINGW32__
#include "mconf.h"
#else
#include "cephes_mconf.h"
#endif
 
/* define MAXGAM 34.84425627277176174 */
 
/* Stirling's formula for the gamma function
* gamma(x) = sqrt(2 pi) x^(x-.5) exp(-x) ( 1 + 1/x P(1/x) )
* .028 < 1/x < .1
* relative error < 1.9e-11
*/
static const float STIR[] = {
-2.705194986674176E-003,
3.473255786154910E-003,
8.333331788340907E-002,
};
static const float MAXSTIR = 26.77;
static const float SQTPIF = 2.50662827463100050242; /* sqrt( 2 pi ) */
 
#ifndef __MINGW32__
 
extern float MAXLOGF, MAXNUMF, PIF;
 
#ifdef ANSIC
float expf(float);
float logf(float);
float powf( float, float );
float sinf(float);
float gammaf(float);
float floorf(float);
static float stirf(float);
float polevlf( float, float *, int );
float p1evlf( float, float *, int );
#else
float expf(), logf(), powf(), sinf(), floorf();
float polevlf(), p1evlf();
static float stirf();
#endif
 
#else /* __MINGW32__ */
static float stirf(float);
#endif
 
/* Gamma function computed by Stirling's formula,
* sqrt(2 pi) x^(x-.5) exp(-x) (1 + 1/x P(1/x))
* The polynomial STIR is valid for 33 <= x <= 172.
*/
static float stirf( float x )
{
float y, w, v;
 
w = 1.0/x;
w = 1.0 + w * polevlf( w, STIR, 2 );
y = expf( -x );
if( x > MAXSTIR )
{ /* Avoid overflow in pow() */
v = powf( x, 0.5 * x - 0.25 );
y *= v;
y *= v;
}
else
{
y = powf( x, x - 0.5 ) * y;
}
y = SQTPIF * y * w;
return( y );
}
 
 
/* gamma(x+2), 0 < x < 1 */
static const float P[] = {
1.536830450601906E-003,
5.397581592950993E-003,
4.130370201859976E-003,
7.232307985516519E-002,
8.203960091619193E-002,
4.117857447645796E-001,
4.227867745131584E-001,
9.999999822945073E-001,
};
 
float __tgammaf_r( float x, int* sgngamf)
{
float p, q, z, nz;
int i, direction, negative;
 
#ifdef NANS
if( isnan(x) )
return(x);
#endif
#ifdef INFINITIES
#ifdef NANS
if( x == INFINITYF )
return(x);
if( x == -INFINITYF )
return(NANF);
#else
if( !isfinite(x) )
return(x);
#endif
#endif
 
*sgngamf = 1;
negative = 0;
nz = 0.0;
if( x < 0.0 )
{
negative = 1;
q = -x;
p = floorf(q);
if( p == q )
{
gsing:
_SET_ERRNO(EDOM);
mtherr( "tgammaf", SING );
#ifdef INFINITIES
return (INFINITYF);
#else
return (MAXNUMF);
#endif
}
i = p;
if( (i & 1) == 0 )
*sgngamf = -1;
nz = q - p;
if( nz > 0.5 )
{
p += 1.0;
nz = q - p;
}
nz = q * sinf( PIF * nz );
if( nz == 0.0 )
{
_SET_ERRNO(ERANGE);
mtherr( "tgamma", OVERFLOW );
#ifdef INFINITIES
return( *sgngamf * INFINITYF);
#else
return( *sgngamf * MAXNUMF);
#endif
}
if( nz < 0 )
nz = -nz;
x = q;
}
if( x >= 10.0 )
{
z = stirf(x);
}
if( x < 2.0 )
direction = 1;
else
direction = 0;
z = 1.0;
while( x >= 3.0 )
{
x -= 1.0;
z *= x;
}
/*
while( x < 0.0 )
{
if( x > -1.E-4 )
goto Small;
z *=x;
x += 1.0;
}
*/
while( x < 2.0 )
{
if( x < 1.e-4 )
goto Small;
z *=x;
x += 1.0;
}
 
if( direction )
z = 1.0/z;
 
if( x == 2.0 )
return(z);
 
x -= 2.0;
p = z * polevlf( x, P, 7 );
 
gdone:
 
if( negative )
{
p = *sgngamf * PIF/(nz * p );
}
return(p);
 
Small:
if( x == 0.0 )
{
goto gsing;
}
else
{
p = z / ((1.0 + 0.5772156649015329 * x) * x);
goto gdone;
}
}
 
/* This is the C99 version */
 
float tgammaf(float x)
{
int local_sgngamf=0;
return (__tgammaf_r(x, &local_sgngamf));
}
/programs/develop/libraries/newlib/math/tgammal.c
0,0 → 1,501
/* gammal.c
*
* Gamma function
*
*
*
* SYNOPSIS:
*
* long double x, y, __tgammal_r();
* int* sgngaml;
* y = __tgammal_r( x, sgngaml );
*
* long double x, y, tgammal();
* y = tgammal( x); *
*
*
* DESCRIPTION:
*
* Returns gamma function of the argument. The result is
* correctly signed. In the reentrant version the sign (+1 or -1)
* is returned in the variable referenced by sgngamf.
*
* Arguments |x| <= 13 are reduced by recurrence and the function
* approximated by a rational function of degree 7/8 in the
* interval (2,3). Large arguments are handled by Stirling's
* formula. Large negative arguments are made positive using
* a reflection formula.
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE -40,+40 10000 3.6e-19 7.9e-20
* IEEE -1755,+1755 10000 4.8e-18 6.5e-19
*
* Accuracy for large arguments is dominated by error in powl().
*
*/
 
/*
Copyright 1994 by Stephen L. Moshier
*/
 
 
/*
* 26-11-2002 Modified for mingw.
* Danny Smith <dannysmith@users.sourceforge.net>
*/
 
 
#ifndef __MINGW32__
#include "mconf.h"
#else
#include "cephes_mconf.h"
#endif
 
/*
gamma(x+2) = gamma(x+2) P(x)/Q(x)
0 <= x <= 1
Relative error
n=7, d=8
Peak error = 1.83e-20
Relative error spread = 8.4e-23
*/
 
#if UNK
static const long double P[8] = {
4.212760487471622013093E-5L,
4.542931960608009155600E-4L,
4.092666828394035500949E-3L,
2.385363243461108252554E-2L,
1.113062816019361559013E-1L,
3.629515436640239168939E-1L,
8.378004301573126728826E-1L,
1.000000000000000000009E0L,
};
static const long double Q[9] = {
-1.397148517476170440917E-5L,
2.346584059160635244282E-4L,
-1.237799246653152231188E-3L,
-7.955933682494738320586E-4L,
2.773706565840072979165E-2L,
-4.633887671244534213831E-2L,
-2.243510905670329164562E-1L,
4.150160950588455434583E-1L,
9.999999999999999999908E-1L,
};
#endif
#if IBMPC
static const unsigned short P[] = {
0x434a,0x3f22,0x2bda,0xb0b2,0x3ff0, XPD
0xf5aa,0xe82f,0x335b,0xee2e,0x3ff3, XPD
0xbe6c,0x3757,0xc717,0x861b,0x3ff7, XPD
0x7f43,0x5196,0xb166,0xc368,0x3ff9, XPD
0x9549,0x8eb5,0x8c3a,0xe3f4,0x3ffb, XPD
0x8d75,0x23af,0xc8e4,0xb9d4,0x3ffd, XPD
0x29cf,0x19b3,0x16c8,0xd67a,0x3ffe, XPD
0x0000,0x0000,0x0000,0x8000,0x3fff, XPD
};
static const unsigned short Q[] = {
0x5473,0x2de8,0x1268,0xea67,0xbfee, XPD
0x334b,0xc2f0,0xa2dd,0xf60e,0x3ff2, XPD
0xbeed,0x1853,0xa691,0xa23d,0xbff5, XPD
0x296e,0x7cb1,0x5dfd,0xd08f,0xbff4, XPD
0x0417,0x7989,0xd7bc,0xe338,0x3ff9, XPD
0x3295,0x3698,0xd580,0xbdcd,0xbffa, XPD
0x75ef,0x3ab7,0x4ad3,0xe5bc,0xbffc, XPD
0xe458,0x2ec7,0xfd57,0xd47c,0x3ffd, XPD
0x0000,0x0000,0x0000,0x8000,0x3fff, XPD
};
#endif
#if MIEEE
static const long P[24] = {
0x3ff00000,0xb0b22bda,0x3f22434a,
0x3ff30000,0xee2e335b,0xe82ff5aa,
0x3ff70000,0x861bc717,0x3757be6c,
0x3ff90000,0xc368b166,0x51967f43,
0x3ffb0000,0xe3f48c3a,0x8eb59549,
0x3ffd0000,0xb9d4c8e4,0x23af8d75,
0x3ffe0000,0xd67a16c8,0x19b329cf,
0x3fff0000,0x80000000,0x00000000,
};
static const long Q[27] = {
0xbfee0000,0xea671268,0x2de85473,
0x3ff20000,0xf60ea2dd,0xc2f0334b,
0xbff50000,0xa23da691,0x1853beed,
0xbff40000,0xd08f5dfd,0x7cb1296e,
0x3ff90000,0xe338d7bc,0x79890417,
0xbffa0000,0xbdcdd580,0x36983295,
0xbffc0000,0xe5bc4ad3,0x3ab775ef,
0x3ffd0000,0xd47cfd57,0x2ec7e458,
0x3fff0000,0x80000000,0x00000000,
};
#endif
/*
static const long double P[] = {
-3.01525602666895735709e0L,
-3.25157411956062339893e1L,
-2.92929976820724030353e2L,
-1.70730828800510297666e3L,
-7.96667499622741999770e3L,
-2.59780216007146401957e4L,
-5.99650230220855581642e4L,
-7.15743521530849602425e4L
};
static const long double Q[] = {
1.00000000000000000000e0L,
-1.67955233807178858919e1L,
8.85946791747759881659e1L,
5.69440799097468430177e1L,
-1.98526250512761318471e3L,
3.31667508019495079814e3L,
1.60577839621734713377e4L,
-2.97045081369399940529e4L,
-7.15743521530849602412e4L
};
*/
#define MAXGAML 1755.455L
/*static const long double LOGPI = 1.14472988584940017414L;*/
 
/* Stirling's formula for the gamma function
gamma(x) = sqrt(2 pi) x^(x-.5) exp(-x) (1 + 1/x P(1/x))
z(x) = x
13 <= x <= 1024
Relative error
n=8, d=0
Peak error = 9.44e-21
Relative error spread = 8.8e-4
*/
#if UNK
static const long double STIR[9] = {
7.147391378143610789273E-4L,
-2.363848809501759061727E-5L,
-5.950237554056330156018E-4L,
6.989332260623193171870E-5L,
7.840334842744753003862E-4L,
-2.294719747873185405699E-4L,
-2.681327161876304418288E-3L,
3.472222222230075327854E-3L,
8.333333333333331800504E-2L,
};
#endif
#if IBMPC
static const unsigned short STIR[] = {
0x6ede,0x69f7,0x54e3,0xbb5d,0x3ff4, XPD
0xc395,0x0295,0x4443,0xc64b,0xbfef, XPD
0xba6f,0x7c59,0x5e47,0x9bfb,0xbff4, XPD
0x5704,0x1a39,0xb11d,0x9293,0x3ff1, XPD
0x30b7,0x1a21,0x98b2,0xcd87,0x3ff4, XPD
0xbef3,0x7023,0x6a08,0xf09e,0xbff2, XPD
0x3a1c,0x5ac8,0x3478,0xafb9,0xbff6, XPD
0xc3c9,0x906e,0x38e3,0xe38e,0x3ff6, XPD
0xa1d5,0xaaaa,0xaaaa,0xaaaa,0x3ffb, XPD
};
#endif
#if MIEEE
static const long STIR[27] = {
0x3ff40000,0xbb5d54e3,0x69f76ede,
0xbfef0000,0xc64b4443,0x0295c395,
0xbff40000,0x9bfb5e47,0x7c59ba6f,
0x3ff10000,0x9293b11d,0x1a395704,
0x3ff40000,0xcd8798b2,0x1a2130b7,
0xbff20000,0xf09e6a08,0x7023bef3,
0xbff60000,0xafb93478,0x5ac83a1c,
0x3ff60000,0xe38e38e3,0x906ec3c9,
0x3ffb0000,0xaaaaaaaa,0xaaaaa1d5,
};
#endif
#define MAXSTIR 1024.0L
static const long double SQTPI = 2.50662827463100050242E0L;
 
/* 1/gamma(x) = z P(z)
* z(x) = 1/x
* 0 < x < 0.03125
* Peak relative error 4.2e-23
*/
#if UNK
static const long double S[9] = {
-1.193945051381510095614E-3L,
7.220599478036909672331E-3L,
-9.622023360406271645744E-3L,
-4.219773360705915470089E-2L,
1.665386113720805206758E-1L,
-4.200263503403344054473E-2L,
-6.558780715202540684668E-1L,
5.772156649015328608253E-1L,
1.000000000000000000000E0L,
};
#endif
#if IBMPC
static const unsigned short S[] = {
0xbaeb,0xd6d3,0x25e5,0x9c7e,0xbff5, XPD
0xfe9a,0xceb4,0xc74e,0xec9a,0x3ff7, XPD
0x9225,0xdfef,0xb0e9,0x9da5,0xbff8, XPD
0x10b0,0xec17,0x87dc,0xacd7,0xbffa, XPD
0x6b8d,0x7515,0x1905,0xaa89,0x3ffc, XPD
0xf183,0x126b,0xf47d,0xac0a,0xbffa, XPD
0x7bf6,0x57d1,0xa013,0xa7e7,0xbffe, XPD
0xc7a9,0x7db0,0x67e3,0x93c4,0x3ffe, XPD
0x0000,0x0000,0x0000,0x8000,0x3fff, XPD
};
#endif
#if MIEEE
static const long S[27] = {
0xbff50000,0x9c7e25e5,0xd6d3baeb,
0x3ff70000,0xec9ac74e,0xceb4fe9a,
0xbff80000,0x9da5b0e9,0xdfef9225,
0xbffa0000,0xacd787dc,0xec1710b0,
0x3ffc0000,0xaa891905,0x75156b8d,
0xbffa0000,0xac0af47d,0x126bf183,
0xbffe0000,0xa7e7a013,0x57d17bf6,
0x3ffe0000,0x93c467e3,0x7db0c7a9,
0x3fff0000,0x80000000,0x00000000,
};
#endif
/* 1/gamma(-x) = z P(z)
* z(x) = 1/x
* 0 < x < 0.03125
* Peak relative error 5.16e-23
* Relative error spread = 2.5e-24
*/
#if UNK
static const long double SN[9] = {
1.133374167243894382010E-3L,
7.220837261893170325704E-3L,
9.621911155035976733706E-3L,
-4.219773343731191721664E-2L,
-1.665386113944413519335E-1L,
-4.200263503402112910504E-2L,
6.558780715202536547116E-1L,
5.772156649015328608727E-1L,
-1.000000000000000000000E0L,
};
#endif
#if IBMPC
static const unsigned short SN[] = {
0x5dd1,0x02de,0xb9f7,0x948d,0x3ff5, XPD
0x989b,0xdd68,0xc5f1,0xec9c,0x3ff7, XPD
0x2ca1,0x18f0,0x386f,0x9da5,0x3ff8, XPD
0x783f,0x41dd,0x87d1,0xacd7,0xbffa, XPD
0x7a5b,0xd76d,0x1905,0xaa89,0xbffc, XPD
0x7f64,0x1234,0xf47d,0xac0a,0xbffa, XPD
0x5e26,0x57d1,0xa013,0xa7e7,0x3ffe, XPD
0xc7aa,0x7db0,0x67e3,0x93c4,0x3ffe, XPD
0x0000,0x0000,0x0000,0x8000,0xbfff, XPD
};
#endif
#if MIEEE
static const long SN[27] = {
0x3ff50000,0x948db9f7,0x02de5dd1,
0x3ff70000,0xec9cc5f1,0xdd68989b,
0x3ff80000,0x9da5386f,0x18f02ca1,
0xbffa0000,0xacd787d1,0x41dd783f,
0xbffc0000,0xaa891905,0xd76d7a5b,
0xbffa0000,0xac0af47d,0x12347f64,
0x3ffe0000,0xa7e7a013,0x57d15e26,
0x3ffe0000,0x93c467e3,0x7db0c7aa,
0xbfff0000,0x80000000,0x00000000,
};
#endif
 
#ifndef __MINGW32__
extern long double MAXLOGL, MAXNUML, PIL;
/* #define PIL 3.14159265358979323846L */
/* #define MAXNUML 1.189731495357231765021263853E4932L */
 
#ifdef ANSIPROT
extern long double fabsl ( long double );
extern long double lgaml ( long double );
extern long double logl ( long double );
extern long double expl ( long double );
extern long double gammal ( long double );
extern long double sinl ( long double );
extern long double floorl ( long double );
extern long double powl ( long double, long double );
extern long double polevll ( long double, void *, int );
extern long double p1evll ( long double, void *, int );
extern int isnanl ( long double );
extern int isfinitel ( long double );
static long double stirf ( long double );
#else
long double fabsl(), lgaml(), logl(), expl(), gammal(), sinl();
long double floorl(), powl(), polevll(), p1evll(), isnanl(), isfinitel();
static long double stirf();
#endif
#ifdef INFINITIES
extern long double INFINITYL;
#endif
#ifdef NANS
extern long double NANL;
#endif
 
#else /* __MINGW32__ */
static long double stirf ( long double );
#endif
 
 
/* Gamma function computed by Stirling's formula. */
 
static long double stirf(x)
long double x;
{
long double y, w, v;
 
w = 1.0L/x;
/* For large x, use rational coefficients from the analytical expansion. */
if( x > 1024.0L )
w = (((((6.97281375836585777429E-5L * w
+ 7.84039221720066627474E-4L) * w
- 2.29472093621399176955E-4L) * w
- 2.68132716049382716049E-3L) * w
+ 3.47222222222222222222E-3L) * w
+ 8.33333333333333333333E-2L) * w
+ 1.0L;
else
w = 1.0L + w * polevll( w, STIR, 8 );
y = expl(x);
if( x > MAXSTIR )
{ /* Avoid overflow in pow() */
v = powl( x, 0.5L * x - 0.25L );
y = v * (v / y);
}
else
{
y = powl( x, x - 0.5L ) / y;
}
y = SQTPI * y * w;
return( y );
}
 
 
long double __tgammal_r(long double x, int* sgngaml)
{
long double p, q, z;
int i;
 
*sgngaml = 1;
#ifdef NANS
if( isnanl(x) )
return(NANL);
#endif
#ifdef INFINITIES
#ifdef NANS
if( x == INFINITYL )
return(x);
if( x == -INFINITYL )
return(NANL);
#else
if( !isfinite(x) )
return(x);
#endif
#endif
q = fabsl(x);
 
if( q > 13.0L )
{
if( q > MAXGAML )
goto goverf;
if( x < 0.0L )
{
p = floorl(q);
if( p == q )
{
gsing:
_SET_ERRNO(EDOM);
mtherr( "tgammal", SING );
#ifdef INFINITIES
return (INFINITYL);
#else
return( *sgngaml * MAXNUML);
#endif
}
i = p;
if( (i & 1) == 0 )
*sgngaml = -1;
z = q - p;
if( z > 0.5L )
{
p += 1.0L;
z = q - p;
}
z = q * sinl( PIL * z );
z = fabsl(z) * stirf(q);
if( z <= PIL/MAXNUML )
{
goverf:
_SET_ERRNO(ERANGE);
mtherr( "tgammal", OVERFLOW );
#ifdef INFINITIES
return( *sgngaml * INFINITYL);
#else
return( *sgngaml * MAXNUML);
#endif
}
z = PIL/z;
}
else
{
z = stirf(x);
}
return( *sgngaml * z );
}
 
z = 1.0L;
while( x >= 3.0L )
{
x -= 1.0L;
z *= x;
}
 
while( x < -0.03125L )
{
z /= x;
x += 1.0L;
}
 
if( x <= 0.03125L )
goto Small;
 
while( x < 2.0L )
{
z /= x;
x += 1.0L;
}
 
if( x == 2.0L )
return(z);
 
x -= 2.0L;
p = polevll( x, P, 7 );
q = polevll( x, Q, 8 );
return( z * p / q );
 
Small:
if( x == 0.0L )
{
goto gsing;
}
else
{
if( x < 0.0L )
{
x = -x;
q = z / (x * polevll( x, SN, 8 ));
}
else
q = z / (x * polevll( x, S, 8 ));
}
return q;
}
 
 
/* This is the C99 version. */
 
long double tgammal(long double x)
{
int local_sgngaml=0;
return (__tgammal_r(x, &local_sgngaml));
}
 
/programs/develop/libraries/newlib/math/trunc.c
0,0 → 1,16
#include <fenv.h>
#include <math.h>
 
double
trunc (double _x){
double retval;
unsigned short saved_cw;
unsigned short tmp_cw;
__asm__ ("fnstcw %0;" : "=m" (saved_cw)); /* save FPU control word */
tmp_cw = (saved_cw & ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO))
| FE_TOWARDZERO;
__asm__ ("fldcw %0;" : : "m" (tmp_cw));
__asm__ ("frndint;" : "=t" (retval) : "0" (_x)); /* round towards zero */
__asm__ ("fldcw %0;" : : "m" (saved_cw) ); /* restore saved control word */
return retval;
}
/programs/develop/libraries/newlib/math/truncf.c
0,0 → 1,17
#include <fenv.h>
#include <math.h>
 
float
truncf (float _x)
{
float retval;
unsigned short saved_cw;
unsigned short tmp_cw;
__asm__ ("fnstcw %0;" : "=m" (saved_cw)); /* save FPU control word */
tmp_cw = (saved_cw & ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO))
| FE_TOWARDZERO;
__asm__ ("fldcw %0;" : : "m" (tmp_cw));
__asm__ ("frndint;" : "=t" (retval) : "0" (_x)); /* round towards zero */
__asm__ ("fldcw %0;" : : "m" (saved_cw) ); /* restore saved control word */
return retval;
}
/programs/develop/libraries/newlib/math/truncl.c
0,0 → 1,16
#include <fenv.h>
#include <math.h>
 
long double
truncl (long double _x){
long double retval;
unsigned short saved_cw;
unsigned short tmp_cw;
__asm__ ("fnstcw %0;" : "=m" (saved_cw)); /* save FPU control word */
tmp_cw = (saved_cw & ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO))
| FE_TOWARDZERO;
__asm__ ("fldcw %0;" : : "m" (tmp_cw));
__asm__ ("frndint;" : "=t" (retval) : "0" (_x)); /* round towards zero */
__asm__ ("fldcw %0;" : : "m" (saved_cw) ); /* restore saved control word */
return retval;
}
/programs/develop/libraries/newlib/math/w_atan2.c
0,0 → 1,90
 
/* @(#)w_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.
* ====================================================
*
*/
 
/*
FUNCTION
<<atan2>>, <<atan2f>>---arc tangent of y/x
 
INDEX
atan2
INDEX
atan2f
 
ANSI_SYNOPSIS
#include <math.h>
double atan2(double <[y]>,double <[x]>);
float atan2f(float <[y]>,float <[x]>);
 
TRAD_SYNOPSIS
#include <math.h>
double atan2(<[y]>,<[x]>);
double <[y]>;
double <[x]>;
 
float atan2f(<[y]>,<[x]>);
float <[y]>;
float <[x]>;
 
DESCRIPTION
 
<<atan2>> computes the inverse tangent (arc tangent) of <[y]>/<[x]>.
<<atan2>> produces the correct result even for angles near
@ifnottex
pi/2 or -pi/2
@end ifnottex
@tex
$\pi/2$ or $-\pi/2$
@end tex
(that is, when <[x]> is near 0).
 
<<atan2f>> is identical to <<atan2>>, save that it takes and returns
<<float>>.
 
RETURNS
<<atan2>> and <<atan2f>> return a value in radians, in the range of
@ifnottex
-pi to pi.
@end ifnottex
@tex
$-\pi$ to $\pi$.
@end tex
 
You can modify error handling for these functions using <<matherr>>.
 
PORTABILITY
<<atan2>> is ANSI C. <<atan2f>> is an extension.
 
 
*/
 
/*
* wrapper atan2(y,x)
*/
 
#include "fdlibm.h"
#include <errno.h>
 
#ifndef _DOUBLE_IS_32BITS
 
#ifdef __STDC__
double atan2(double y, double x) /* wrapper atan2 */
#else
double atan2(y,x) /* wrapper atan2 */
double y,x;
#endif
{
return __ieee754_atan2(y,x);
}
 
#endif /* defined(_DOUBLE_IS_32BITS) */
/programs/develop/libraries/newlib/math/w_hypot.c
0,0 → 1,111
 
/* @(#)w_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.
* ====================================================
*/
 
/*
FUNCTION
<<hypot>>, <<hypotf>>---distance from origin
INDEX
hypot
INDEX
hypotf
 
ANSI_SYNOPSIS
#include <math.h>
double hypot(double <[x]>, double <[y]>);
float hypotf(float <[x]>, float <[y]>);
 
TRAD_SYNOPSIS
double hypot(<[x]>, <[y]>)
double <[x]>, <[y]>;
 
float hypotf(<[x]>, <[y]>)
float <[x]>, <[y]>;
 
DESCRIPTION
<<hypot>> calculates the Euclidean distance
@tex
$\sqrt{x^2+y^2}$
@end tex
@ifnottex
<<sqrt(<[x]>*<[x]> + <[y]>*<[y]>)>>
@end ifnottex
between the origin (0,0) and a point represented by the
Cartesian coordinates (<[x]>,<[y]>). <<hypotf>> differs only
in the type of its arguments and result.
 
RETURNS
Normally, the distance value is returned. On overflow,
<<hypot>> returns <<HUGE_VAL>> and sets <<errno>> to
<<ERANGE>>.
 
You can change the error treatment with <<matherr>>.
 
PORTABILITY
<<hypot>> and <<hypotf>> are not ANSI C. */
 
/*
* wrapper hypot(x,y)
*/
 
#define _IEEE_LIBM
 
#include "fdlibm.h"
#include <errno.h>
 
#ifndef _DOUBLE_IS_32BITS
 
#ifdef __STDC__
double hypot(double x, double y)/* wrapper hypot */
#else
double hypot(x,y) /* wrapper hypot */
double x,y;
#endif
{
#ifdef _IEEE_LIBM
return __ieee754_hypot(x,y);
#else
double z;
struct exception exc;
z = __ieee754_hypot(x,y);
if(_LIB_VERSION == _IEEE_) return z;
if((!finite(z))&&finite(x)&&finite(y)) {
/* hypot(finite,finite) overflow */
#ifndef HUGE_VAL
#define HUGE_VAL inf
double inf = 0.0;
 
SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */
#endif
exc.type = OVERFLOW;
exc.name = "hypot";
exc.err = 0;
exc.arg1 = x;
exc.arg2 = y;
if (_LIB_VERSION == _SVID_)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
if (_LIB_VERSION == _POSIX_)
errno = ERANGE;
else if (!matherr(&exc)) {
errno = ERANGE;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
} else
return z;
#endif
}
 
#endif /* defined(_DOUBLE_IS_32BITS) */
/programs/develop/libraries/newlib/math
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property
/programs/develop/libraries/newlib/pe/list.h
0,0 → 1,707
#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H
 
 
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
 
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
 
#define LIST_POISON1 ((struct list_head*)0xFFFF0100)
#define LIST_POISON2 ((struct list_head*)0xFFFF0200)
 
#define prefetch(x) __builtin_prefetch(x)
 
struct list_head {
struct list_head *next, *prev;
};
 
#define LIST_HEAD_INIT(name) { &(name), &(name) }
 
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
 
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
 
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
#ifndef CONFIG_DEBUG_LIST
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
#else
extern void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next);
#endif
 
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
 
 
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
 
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
 
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
#ifndef CONFIG_DEBUG_LIST
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
#else
extern void list_del(struct list_head *entry);
#endif
 
/**
* list_replace - replace old entry by new one
* @old : the element to be replaced
* @new : the new element to insert
*
* If @old was empty, it will be overwritten.
*/
static inline void list_replace(struct list_head *old,
struct list_head *new)
{
new->next = old->next;
new->next->prev = new;
new->prev = old->prev;
new->prev->next = new;
}
 
static inline void list_replace_init(struct list_head *old,
struct list_head *new)
{
list_replace(old, new);
INIT_LIST_HEAD(old);
}
 
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
 
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}
 
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
 
/**
* list_is_last - tests whether @list is the last entry in list @head
* @list: the entry to test
* @head: the head of the list
*/
static inline int list_is_last(const struct list_head *list,
const struct list_head *head)
{
return list->next == head;
}
 
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
 
/**
* list_empty_careful - tests whether a list is empty and not being modified
* @head: the list to test
*
* Description:
* tests whether a list is empty _and_ checks that no other CPU might be
* in the process of modifying either member (next or prev)
*
* NOTE: using list_empty_careful() without synchronization
* can only be safe if the only activity that can happen
* to the list entry is list_del_init(). Eg. it cannot be used
* if another CPU could re-list_add() it.
*/
static inline int list_empty_careful(const struct list_head *head)
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}
 
/**
* list_is_singular - tests whether a list has just one entry.
* @head: the list to test.
*/
static inline int list_is_singular(const struct list_head *head)
{
return !list_empty(head) && (head->next == head->prev);
}
 
static inline void __list_cut_position(struct list_head *list,
struct list_head *head, struct list_head *entry)
{
struct list_head *new_first = entry->next;
list->next = head->next;
list->next->prev = list;
list->prev = entry;
entry->next = list;
head->next = new_first;
new_first->prev = head;
}
 
/**
* list_cut_position - cut a list into two
* @list: a new list to add all removed entries
* @head: a list with entries
* @entry: an entry within head, could be the head itself
* and if so we won't cut the list
*
* This helper moves the initial part of @head, up to and
* including @entry, from @head to @list. You should
* pass on @entry an element you know is on @head. @list
* should be an empty list or a list you do not care about
* losing its data.
*
*/
static inline void list_cut_position(struct list_head *list,
struct list_head *head, struct list_head *entry)
{
if (list_empty(head))
return;
if (list_is_singular(head) &&
(head->next != entry && head != entry))
return;
if (entry == head)
INIT_LIST_HEAD(list);
else
__list_cut_position(list, head, entry);
}
 
static inline void __list_splice(const struct list_head *list,
struct list_head *prev,
struct list_head *next)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
 
first->prev = prev;
prev->next = first;
 
last->next = next;
next->prev = last;
}
 
/**
* list_splice - join two lists, this is designed for stacks
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(const struct list_head *list,
struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head, head->next);
}
 
/**
* list_splice_tail - join two lists, each list being a queue
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice_tail(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head->prev, head);
}
 
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head, head->next);
INIT_LIST_HEAD(list);
}
}
 
/**
* list_splice_tail_init - join two lists and reinitialise the emptied list
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* Each of the lists is a queue.
* The list at @list is reinitialised
*/
static inline void list_splice_tail_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head->prev, head);
INIT_LIST_HEAD(list);
}
}
 
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
 
/**
* list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
 
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = pos->next)
 
/**
* __list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*
* This variant differs from list_for_each() in that it's the
* simplest possible list iteration code, no prefetching is done.
* Use this for code that knows the list to be very short (empty
* or 1 entry) most of the time.
*/
#define __list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
 
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
pos = pos->prev)
 
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
 
/**
* list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_prev_safe(pos, n, head) \
for (pos = (head)->prev, n = pos->prev; \
prefetch(pos->prev), pos != (head); \
pos = n, n = pos->prev)
 
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
 
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); \
prefetch(pos->member.prev), &pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
 
/**
* list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
* @pos: the type * to use as a start point
* @head: the head of the list
* @member: the name of the list_struct within the struct.
*
* Prepares a pos entry for use as a start point in list_for_each_entry_continue().
*/
#define list_prepare_entry(pos, head, member) \
((pos) ? : list_entry(head, typeof(*pos), member))
 
/**
* list_for_each_entry_continue - continue iteration over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Continue to iterate over list of given type, continuing after
* the current position.
*/
#define list_for_each_entry_continue(pos, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
 
/**
* list_for_each_entry_continue_reverse - iterate backwards from the given point
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Start to iterate over list of given type backwards, continuing after
* the current position.
*/
#define list_for_each_entry_continue_reverse(pos, head, member) \
for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
prefetch(pos->member.prev), &pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
 
/**
* list_for_each_entry_from - iterate over list of given type from the current point
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate over list of given type, continuing from current position.
*/
#define list_for_each_entry_from(pos, head, member) \
for (; prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
 
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
 
/**
* list_for_each_entry_safe_continue
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate over list of given type, continuing after current point,
* safe against removal of list entry.
*/
#define list_for_each_entry_safe_continue(pos, n, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
 
/**
* list_for_each_entry_safe_from
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate over list of given type from current point, safe against
* removal of list entry.
*/
#define list_for_each_entry_safe_from(pos, n, head, member) \
for (n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
 
/**
* list_for_each_entry_safe_reverse
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate backwards over list of given type, safe against removal
* of list entry.
*/
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member), \
n = list_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
 
/*
* Double linked lists with a single pointer list head.
* Mostly useful for hash tables where the two pointer list head is
* too wasteful.
* You lose the ability to access the tail in O(1).
*/
 
struct hlist_head {
struct hlist_node *first;
};
 
struct hlist_node {
struct hlist_node *next, **pprev;
};
 
#define HLIST_HEAD_INIT { .first = NULL }
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
static inline void INIT_HLIST_NODE(struct hlist_node *h)
{
h->next = NULL;
h->pprev = NULL;
}
 
static inline int hlist_unhashed(const struct hlist_node *h)
{
return !h->pprev;
}
 
static inline int hlist_empty(const struct hlist_head *h)
{
return !h->first;
}
 
static inline void __hlist_del(struct hlist_node *n)
{
struct hlist_node *next = n->next;
struct hlist_node **pprev = n->pprev;
*pprev = next;
if (next)
next->pprev = pprev;
}
 
static inline void hlist_del(struct hlist_node *n)
{
__hlist_del(n);
n->next = (struct hlist_node*)LIST_POISON1;
n->pprev = (struct hlist_node**)LIST_POISON2;
}
 
static inline void hlist_del_init(struct hlist_node *n)
{
if (!hlist_unhashed(n)) {
__hlist_del(n);
INIT_HLIST_NODE(n);
}
}
 
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{
struct hlist_node *first = h->first;
n->next = first;
if (first)
first->pprev = &n->next;
h->first = n;
n->pprev = &h->first;
}
 
/* next must be != NULL */
static inline void hlist_add_before(struct hlist_node *n,
struct hlist_node *next)
{
n->pprev = next->pprev;
n->next = next;
next->pprev = &n->next;
*(n->pprev) = n;
}
 
static inline void hlist_add_after(struct hlist_node *n,
struct hlist_node *next)
{
next->next = n->next;
n->next = next;
next->pprev = &n->next;
 
if(next->next)
next->next->pprev = &next->next;
}
 
/*
* Move a list from one list head to another. Fixup the pprev
* reference of the first entry if it exists.
*/
static inline void hlist_move_list(struct hlist_head *old,
struct hlist_head *new)
{
new->first = old->first;
if (new->first)
new->first->pprev = &new->first;
old->first = NULL;
}
 
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
 
#define hlist_for_each(pos, head) \
for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
pos = pos->next)
 
#define hlist_for_each_safe(pos, n, head) \
for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
pos = n)
 
/**
* hlist_for_each_entry - iterate over list of given type
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct hlist_node to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry(tpos, pos, head, member) \
for (pos = (head)->first; \
pos && ({ prefetch(pos->next); 1;}) && \
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = pos->next)
 
/**
* hlist_for_each_entry_continue - iterate over a hlist continuing after current point
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct hlist_node to use as a loop cursor.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_continue(tpos, pos, member) \
for (pos = (pos)->next; \
pos && ({ prefetch(pos->next); 1;}) && \
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = pos->next)
 
/**
* hlist_for_each_entry_from - iterate over a hlist continuing from current point
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct hlist_node to use as a loop cursor.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_from(tpos, pos, member) \
for (; pos && ({ prefetch(pos->next); 1;}) && \
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = pos->next)
 
/**
* hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct hlist_node to use as a loop cursor.
* @n: another &struct hlist_node to use as temporary storage
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
for (pos = (head)->first; \
pos && ({ n = pos->next; 1; }) && \
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = n)
 
#endif
/programs/develop/libraries/newlib/pe/loader.c
0,0 → 1,652
 
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <alloca.h>
#include <malloc.h>
#include <setjmp.h>
#include <envz.h>
 
#include <sys/kos_io.h>
 
#include "list.h"
#include "pe.h"
 
#define unlikely(x) __builtin_expect(!!(x), 0)
 
//#define DBG(format,...) printf(format,##__VA_ARGS__)
 
#define DBG(format,...)
 
 
void __fastcall init_loader(void *libc_image);
void* __fastcall create_image(void *raw);
int __fastcall link_image(void *img_base);
int __fastcall do_exec(uint32_t my_app, uint32_t *params);
 
 
extern char* __appenv;
extern int __appenv_size;
 
typedef struct tag_module module_t;
 
struct app_hdr
{
char banner[8];
int version;
int start;
int iend;
int memsize;
int stacktop;
char *cmdline;
char *path;
};
 
struct tag_module
{
struct list_head list;
 
char *img_name;
char *img_path;
 
uint32_t refcount;
 
void *start;
uint32_t end;
 
void *entry;
 
PIMAGE_NT_HEADERS32 img_hdr;
PIMAGE_SECTION_HEADER img_sec;
PIMAGE_EXPORT_DIRECTORY img_exp;
};
 
typedef struct
{
struct list_head list;
char *path;
int path_len;
}dll_path_t;
 
module_t* load_module(const char *name);
 
LIST_HEAD(dll_list);
LIST_HEAD(path_list);
 
static module_t libc_dll;
static char libc_name[] = "libc.dll";
static char libc_path[] = "/sys/lib/libc.dll";
 
static inline int IsPowerOf2(uint32_t val)
{
if(val == 0)
return 0;
return (val & (val - 1)) == 0;
}
 
 
int validate_pe(void *raw, size_t raw_size, int is_exec)
{
PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS32 nt;
 
dos = (PIMAGE_DOS_HEADER)raw;
 
if( !raw || raw_size < sizeof(IMAGE_DOS_HEADER) )
return 0;
 
if( dos->e_magic != IMAGE_DOS_SIGNATURE || dos->e_lfanew <= 0)
return 0;
 
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
 
if( (uint32_t)nt < (uint32_t)raw)
return 0;
 
if(nt->Signature != IMAGE_NT_SIGNATURE)
return 0;
 
if(nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
return 0;
 
if(is_exec && (nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
return 0;
 
if(nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
return 0;
 
if( is_exec && nt->OptionalHeader.ImageBase != 0)
return 0;
 
if(nt->OptionalHeader.SectionAlignment < 4096)
{
if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment)
return 0;
}
else if(nt->OptionalHeader.SectionAlignment < nt->OptionalHeader.FileAlignment)
return 0;
 
if(!IsPowerOf2(nt->OptionalHeader.SectionAlignment) ||
!IsPowerOf2(nt->OptionalHeader.FileAlignment))
return 0;
 
if(nt->FileHeader.NumberOfSections > 96)
return 0;
 
return 1;
}
 
 
void __fastcall init_loader(void *libc_image)
{
 
PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS32 nt;
PIMAGE_EXPORT_DIRECTORY exp;
 
struct app_hdr *header;
 
dll_path_t *path;
int len;
char *p;
 
if(__appenv_size)
{
char *env;
env = envz_get(__appenv, __appenv_size, "PATH");
if( env )
{
while( *env )
{
p = env;
while(*p)
{
if( *p == 0x0D)
break;
else if( *p == 0x0A)
break;
else if( *p == ':')
break;
p++;
};
len = p-env;
if(len)
{
char *p1;
 
p1 = (char*)malloc(len+1);
memcpy(p1, env, len);
p1[len]=0;
 
path = (dll_path_t*)malloc(sizeof(dll_path_t));
INIT_LIST_HEAD(&path->list);
path->path = p1;
path->path_len = len;
DBG("add libraries path %s\n", path->path);
list_add_tail(&path->list, &path_list);
};
if(*p == ':')
{
env = p+1;
continue;
}
else break;
};
};
};
 
header = (struct app_hdr*)NULL;
 
len = strrchr(header->path, '/') - header->path+1;
p = (char*)malloc(len+1);
memcpy(p, header->path, len);
p[len]=0;
 
path = (dll_path_t*)malloc(sizeof(dll_path_t));
INIT_LIST_HEAD(&path->list);
path->path = p;
path->path_len = len;
DBG("add libraries path %s\n", path->path);
list_add_tail(&path->list, &path_list);
 
 
#if 0
path = (dll_path_t*)malloc(sizeof(dll_path_t));
INIT_LIST_HEAD(&path->list);
path->path = "/sys/lib/";
path->path_len = 9; /* FIXME */
DBG("add libraries path %s\n", path->path);
list_add_tail(&path->list, &path_list);
#endif
 
INIT_LIST_HEAD(&libc_dll.list);
 
libc_dll.img_name = libc_name;
libc_dll.img_path = libc_path;
 
libc_dll.refcount = 1;
 
dos = (PIMAGE_DOS_HEADER)libc_image;
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, libc_image,
nt->OptionalHeader.DataDirectory[0].VirtualAddress);
 
libc_dll.start = libc_image;
libc_dll.end = MakePtr(uint32_t,libc_image, nt->OptionalHeader.SizeOfImage);
 
libc_dll.img_hdr = nt;
libc_dll.img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
libc_dll.img_exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,libc_image,
nt->OptionalHeader.DataDirectory[0].VirtualAddress);
 
list_add_tail(&libc_dll.list, &dll_list);
};
 
const module_t* find_module(const char *name)
{
module_t* mod;
 
list_for_each_entry(mod, &dll_list, list)
{
if( !strncmp(name, mod->img_name, 16))
return mod;
};
 
return load_module(name);
};
 
static inline void sec_copy(void *dst, void *src, size_t len)
{
__asm__ __volatile__ (
"shrl $2, %%ecx \n\t"
"rep movsl"
:
:"c"(len),"S"(src),"D"(dst)
:"cc");
__asm__ __volatile__ (
""
:::"ecx","esi","edi");
};
 
static inline void *user_alloc(size_t size)
{
void *val;
__asm__ __volatile__(
"int $0x40"
:"=eax"(val)
:"a"(68),"b"(12),"c"(size));
return val;
}
 
void* __fastcall create_image(void *raw)
{
PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS32 nt;
PIMAGE_SECTION_HEADER img_sec;
 
void *img_base;
uint32_t sec_align;
int i;
 
dos = (PIMAGE_DOS_HEADER)raw;
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
 
img_base = user_alloc(nt->OptionalHeader.SizeOfImage);
 
if(unlikely(img_base == NULL))
return 0;
 
sec_copy(img_base, raw, nt->OptionalHeader.SizeOfHeaders);
 
img_sec = MakePtr(PIMAGE_SECTION_HEADER, nt, sizeof(IMAGE_NT_HEADERS32));
 
sec_align = nt->OptionalHeader.SectionAlignment;
 
for(i=0; i< nt->FileHeader.NumberOfSections; i++)
{
void *src_ptr;
void *dest_ptr;
size_t sec_size;
 
if ( img_sec->SizeOfRawData && img_sec->PointerToRawData )
{
src_ptr = MakePtr(void*, raw, img_sec->PointerToRawData);
dest_ptr = MakePtr(void*, img_base, img_sec->VirtualAddress);
sec_copy(dest_ptr, src_ptr, img_sec->SizeOfRawData);
};
 
img_sec++;
};
 
if(nt->OptionalHeader.DataDirectory[5].Size)
{
PIMAGE_BASE_RELOCATION reloc;
 
uint32_t delta = (uint32_t)img_base - nt->OptionalHeader.ImageBase;
 
reloc = MakePtr(PIMAGE_BASE_RELOCATION, img_base,
nt->OptionalHeader.DataDirectory[5].VirtualAddress);
 
while ( reloc->SizeOfBlock != 0 )
{
uint32_t cnt;
uint16_t *entry;
uint16_t reltype;
uint32_t offs;
 
cnt = (reloc->SizeOfBlock - sizeof(*reloc))/sizeof(uint16_t);
entry = MakePtr( uint16_t*, reloc, sizeof(*reloc) );
 
for ( i=0; i < cnt; i++ )
{
uint16_t *p16;
uint32_t *p32;
 
reltype = (*entry & 0xF000) >> 12;
offs = (*entry & 0x0FFF) + reloc->VirtualAddress;
switch(reltype)
{
case 1:
p16 = MakePtr(uint16_t*, img_base, offs);
*p16+= (uint16_t)(delta>>16);
break;
case 2:
p16 = MakePtr(uint16_t*, img_base, offs);
*p16+= (uint16_t)delta;
break;
case 3:
p32 = MakePtr(uint32_t*, img_base, offs);
*p32+= delta;
}
entry++;
}
reloc = MakePtr(PIMAGE_BASE_RELOCATION, reloc,reloc->SizeOfBlock);
}
};
return img_base;
};
 
int __fastcall link_image(void *img_base)
{
static jmp_buf loader_env;
static recursion = -1;
 
PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS32 nt;
int warn = 0;
 
recursion++;
if( !recursion )
{
if( unlikely(setjmp(loader_env) != 0))
{
recursion = -1;
return 0;
};
};
 
dos = (PIMAGE_DOS_HEADER)img_base;
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
 
if(nt->OptionalHeader.DataDirectory[1].Size)
{
PIMAGE_IMPORT_DESCRIPTOR imp;
 
imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base,
nt->OptionalHeader.DataDirectory[1].VirtualAddress);
 
while ( imp->Name )
{
PIMAGE_DOS_HEADER expdos;
PIMAGE_NT_HEADERS32 expnt;
PIMAGE_EXPORT_DIRECTORY exp;
PIMAGE_THUNK_DATA32 thunk;
 
void **iat;
char *libname;
uint32_t *exp_functions;
uint16_t *exp_ordinals;
char **exp_names;
 
const module_t *api;
 
libname=MakePtr(char*,imp->Name, img_base);
 
DBG("import from %s\n",libname);
 
api = find_module(libname);
if(unlikely(api == NULL))
{
printf("library %s not found\n", libname);
longjmp(loader_env, 1);
}
 
iat = MakePtr(void**,imp->FirstThunk, img_base);
 
if(imp->OriginalFirstThunk !=0 )
{
thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->OriginalFirstThunk, img_base);
}
else
{
thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->FirstThunk, img_base);
};
 
exp = api->img_exp;
 
exp_functions = MakePtr(uint32_t*,exp->AddressOfFunctions,api->start);
exp_ordinals = MakePtr(uint16_t*, exp->AddressOfNameOrdinals,api->start);
exp_names = MakePtr(char**, exp->AddressOfNames,api->start);
 
while ( thunk->u1.AddressOfData != 0 )
{
PIMAGE_IMPORT_BY_NAME imp_name;
 
if (thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)
{
// ordinal = (*func_list) & 0x7fffffff;
// *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->DllBase, Ordinal);
// if ((*ImportAddressList) == NULL)
// {
// DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName);
// RtlpRaiseImportNotFound(NULL, Ordinal, &ImportedModule->FullDllName);
// return STATUS_ENTRYPOINT_NOT_FOUND;
// }
}
else
{
char *export_name;
uint16_t ordinal;
void *function;
uint32_t minn;
uint32_t maxn;
 
imp_name = MakePtr(PIMAGE_IMPORT_BY_NAME,
thunk->u1.AddressOfData, img_base);
*iat = NULL;
 
DBG("import %s", imp_name->Name);
 
if(imp_name->Hint < exp->NumberOfNames)
{
export_name = MakePtr(char*,exp_names[imp_name->Hint],
api->start);
if(strcmp(imp_name->Name, export_name) == 0)
{
ordinal = exp_ordinals[imp_name->Hint];
function = MakePtr(void*,exp_functions[ordinal], api->start);
if((uint32_t)function >= (uint32_t)exp)
{
printf("forward %s\n", function);
warn=1;
}
else
{
DBG(" \t\tat %x\n", function);
*iat = function;
};
thunk++; // Advance to next thunk
iat++;
continue;
};
};
 
 
minn = 0;
maxn = exp->NumberOfNames - 1;
while (minn <= maxn)
{
int mid;
int res;
 
mid = (minn + maxn) / 2;
 
export_name = MakePtr(char*,exp_names[mid],api->start);
 
res = strcmp(export_name, imp_name->Name);
if (res == 0)
{
ordinal = exp_ordinals[mid];
function = MakePtr(void*,exp_functions[ordinal], api->start);
 
if((uint32_t)function >= (uint32_t)exp)
{
printf("forward %s\n", function);
warn=1;
}
else
{
DBG(" \t\tat %x\n", function);
*iat = function;
};
break;
}
else if (minn == maxn)
{
printf(" unresolved\n",imp_name->Name);
warn=1;
break;
}
else if (res > 0)
{
maxn = mid - 1;
}
else
{
minn = mid + 1;
}
};
};
thunk++; // Advance to next thunk
iat++;
}
imp++; // advance to next IMAGE_IMPORT_DESCRIPTOR
};
};
 
recursion--;
 
if ( !warn )
return 1;
else
return 0;
}
 
void* get_entry_point(void *raw)
{
PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS32 nt;
 
dos = (PIMAGE_DOS_HEADER)raw;
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
 
return MakePtr(void*, raw, nt->OptionalHeader.AddressOfEntryPoint);
}
 
 
module_t* load_module(const char *name)
{
char *path;
int len;
 
len = strlen(name);
 
dll_path_t *dllpath;
 
list_for_each_entry(dllpath, &path_list, list)
{
PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS32 nt;
PIMAGE_EXPORT_DIRECTORY exp;
 
module_t *module;
void *raw_img;
size_t raw_size;
void *img_base;
 
path = alloca(len+dllpath->path_len+1);
memcpy(path, dllpath->path, dllpath->path_len);
 
memcpy(path+dllpath->path_len, name, len);
path[len+dllpath->path_len]=0;
 
raw_img = load_file(path, &raw_size);
if(raw_img == NULL)
continue;
 
if( validate_pe(raw_img, raw_size, 0) == 0)
{
printf("invalide module %s\n", path);
user_free(raw_img);
continue;
};
 
img_base = create_image(raw_img);
user_free(raw_img);
 
if( unlikely(img_base == NULL) )
{
printf("cannot create image %s\n",path);
continue;
};
 
module = (module_t*)malloc(sizeof(module_t));
 
if(unlikely(module == NULL))
{
printf("%s epic fail: no enough memory\n",__FUNCTION__);
user_free(img_base);
return 0;
}
 
INIT_LIST_HEAD(&module->list);
 
module->img_name = strdup(name);
module->img_path = strdup(path);
module->start = img_base;
module->entry = get_entry_point(img_base);
module->refcount = 1;
 
dos = (PIMAGE_DOS_HEADER)img_base;
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
nt->OptionalHeader.DataDirectory[0].VirtualAddress);
 
module->end = MakePtr(uint32_t,img_base, nt->OptionalHeader.SizeOfImage);
 
module->img_hdr = nt;
module->img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
module->img_exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
nt->OptionalHeader.DataDirectory[0].VirtualAddress);
 
list_add_tail(&module->list, &dll_list);
 
if( link_image(img_base))
return module;
return NULL;
};
 
return NULL;
};
 
 
/programs/develop/libraries/newlib/pe/pe.h
0,0 → 1,188
 
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef unsigned int LONG;
typedef unsigned char BYTE;
 
#define IMAGE_DOS_SIGNATURE 0x5A4D
#define IMAGE_NT_SIGNATURE 0x00004550
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
 
#pragma pack(push,2)
typedef struct _IMAGE_DOS_HEADER
{
WORD e_magic;
WORD e_cblp;
WORD e_cp;
WORD e_crlc;
WORD e_cparhdr;
WORD e_minalloc;
WORD e_maxalloc;
WORD e_ss;
WORD e_sp;
WORD e_csum;
WORD e_ip;
WORD e_cs;
WORD e_lfarlc;
WORD e_ovno;
WORD e_res[4];
WORD e_oemid;
WORD e_oeminfo;
WORD e_res2[10];
LONG e_lfanew;
} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
#pragma pack(pop)
 
 
#pragma pack(push,4)
typedef struct _IMAGE_FILE_HEADER
{
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
 
#define IMAGE_FILE_DLL 0x2000
 
#define IMAGE_FILE_MACHINE_I386 0x014c /* Intel 386 or later processors
and compatible processors */
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
 
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
 
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER;
 
#pragma pack(pop)
 
 
#pragma pack(push,4)
typedef struct _IMAGE_NT_HEADERS
{
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER OptionalHeader;
} IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32;
 
#define IMAGE_SIZEOF_SHORT_NAME 8
 
typedef struct _IMAGE_SECTION_HEADER
{
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union
{
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
#pragma pack(pop)
 
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
#define IMAGE_SCN_MEM_SHARED 0x10000000
#define IMAGE_SCN_MEM_EXECUTE 0x20000000
#define IMAGE_SCN_MEM_WRITE 0x80000000
 
#pragma pack(push,4)
typedef struct _IMAGE_BASE_RELOCATION {
DWORD VirtualAddress;
DWORD SizeOfBlock;
} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION;
#pragma pack(pop)
 
typedef struct _IMAGE_IMPORT_DESCRIPTOR
{
union
{
DWORD Characteristics;
DWORD OriginalFirstThunk;
};
DWORD TimeDateStamp;
DWORD ForwarderChain;
DWORD Name;
DWORD FirstThunk;
} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;
 
typedef struct _IMAGE_THUNK_DATA32
{
union
{
DWORD ForwarderString;
DWORD Function;
DWORD Ordinal;
DWORD AddressOfData;
} u1;
} IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32;
 
typedef struct _IMAGE_IMPORT_BY_NAME
{
WORD Hint;
BYTE Name[1];
} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;
 
#define IMAGE_ORDINAL_FLAG 0x80000000
 
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions;
DWORD AddressOfNames;
DWORD AddressOfNameOrdinals;
} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
 
 
#define MakePtr( cast, ptr, addValue ) (cast)( (uint32_t)(ptr) + (uint32_t)(addValue) )
 
 
/programs/develop/libraries/newlib/pe
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property
/programs/develop/libraries/newlib/pe_app.lds
0,0 → 1,122
 
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)
}
 
/DISCARD/ :
{
*(.debug$S)
*(.debug$T)
*(.debug$F)
*(.drectve)
*(.note.GNU-stack)
*(.edata)
*(.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)
}
 
}
 
/programs/develop/libraries/newlib/reent/getreent.c
4,10 → 4,6
#include <string.h>
#include <reent.h>
 
#ifdef __getreent
#undef __getreent
#endif
 
static inline
void *user_alloc(int size)
{
28,21 → 24,12
_REENT_INIT_PTR(ent);
 
__asm__ __volatile__(
"movl %0, %%fs:0"
"movl %0, %%fs:12"
::"r"(ent));
__sinit(ent);
}
 
struct _reent *
_DEFUN_VOID(__getreent)
{
struct _reent *ent;
 
__asm__ __volatile__(
"movl %%fs:0, %0"
:"=r"(ent));
return ent;
}
 
void __mutex_lock(volatile int *val)
{
/programs/develop/libraries/newlib/reent/gettimeofdayr.c
0,0 → 1,113
/* Reentrant version of gettimeofday system call
This implementation just calls the times/gettimeofday system calls.
Gettimeofday may not be available on all targets. It's presence
here is dubious. Consider it for internal use only. */
 
#include <reent.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
#include <_syslist.h>
#include <errno.h>
 
/* Some targets provides their own versions of these functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */
 
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
 
#ifdef REENTRANT_SYSCALLS_PROVIDED
 
int _dummy_gettimeofday_syscalls = 1;
 
#else
 
/* We use the errno variable used by the system dependent layer. */
#undef errno
static int errno;
 
/*
FUNCTION
<<_gettimeofday_r>>---Reentrant version of gettimeofday
 
INDEX
_gettimeofday_r
 
ANSI_SYNOPSIS
#include <reent.h>
#include <time.h>
int _gettimeofday_r(struct _reent *<[ptr]>,
struct timeval *<[ptimeval]>,
void *<[ptimezone]>);
 
TRAD_SYNOPSIS
#include <reent.h>
#include <time.h>
int _gettimeofday_r(<[ptr]>, <[ptimeval]>, <[ptimezone]>)
struct _reent *<[ptr]>;
struct timeval *<[ptimeval]>;
void *<[ptimezone]>;
 
DESCRIPTION
This is a reentrant version of <<gettimeofday>>. It
takes a pointer to the global data block, which holds
<<errno>>.
 
This function is only available for a few targets.
Check libc.a to see if its available on yours.
*/
 
int
_DEFUN (_gettimeofday_r, (ptr, ptimeval, ptimezone),
struct _reent *ptr _AND
struct timeval *ptimeval _AND
void *ptimezone)
{
int ret;
 
errno = 0;
if ((ret = _gettimeofday (ptimeval, ptimezone)) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
 
#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
 
int
_gettimeofday (struct timeval *tv, void *tz)
{
unsigned int xtmp;
struct tm tmblk;
 
if( tv )
{
tv->tv_usec = 0;
 
__asm__ __volatile__("int $0x40":"=a"(xtmp):"0"(3));
tmblk.tm_sec = (xtmp>>16)&0xff;
tmblk.tm_min = (xtmp>>8)&0xff;
tmblk.tm_hour = xtmp&0xff;
BCD_TO_BIN(tmblk.tm_sec);
BCD_TO_BIN(tmblk.tm_min);
BCD_TO_BIN(tmblk.tm_hour);
__asm__ __volatile__("int $0x40":"=a"(xtmp):"0"(29));
tmblk.tm_mday = (xtmp>>16)&0xff;
tmblk.tm_mon = ((xtmp>>8)&0xff)-1;
tmblk.tm_year = ((xtmp&0xff)+2000)-1900;
tmblk.tm_wday = tmblk.tm_yday = 0;
tmblk.tm_isdst = -1;
tv->tv_sec = mktime(&tmblk);
return 0;
}
else
{
errno = EINVAL;
return -1;
};
}
 
 
#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */
/programs/develop/libraries/newlib/reent/openr.c
8,6 → 8,7
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/kos_io.h>
 
/* Some targets provides their own versions of this functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */
49,63 → 50,7
*/
 
 
#pragma pack(push, 1)
typedef struct
{
char sec;
char min;
char hour;
char rsv;
}detime_t;
 
typedef struct
{
char day;
char month;
short year;
}dedate_t;
 
typedef struct
{
unsigned attr;
unsigned flags;
union
{
detime_t ctime;
unsigned cr_time;
};
union
{
dedate_t cdate;
unsigned cr_date;
};
union
{
detime_t atime;
unsigned acc_time;
};
union
{
dedate_t adate;
unsigned acc_date;
};
union
{
detime_t mtime;
unsigned mod_time;
};
union
{
dedate_t mdate;
unsigned mod_date;
};
unsigned size;
unsigned size_high;
} fileinfo_t;
 
#pragma pack(pop)
 
 
#define NULL_HANDLE (int)-1
#define DUMMY_HANDLE (int)-2
 
126,100 → 71,7
 
extern int _fmode;
 
int create_file(const char *path)
{
int retval;
__asm__ __volatile__ (
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %0, 1(%%esp) \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $2 \n\t"
"movl %%esp, %%ebx \n\t"
"movl $70, %%eax \n\t"
"int $0x40 \n\t"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"r" (path)
:"ebx");
return retval;
};
 
int set_file_size(const char *path, unsigned size)
{
int retval;
__asm__ __volatile__(
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %%eax, 1(%%esp) \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl %%ebx \n\t"
"push $4 \n\t"
"movl %%esp, %%ebx \n\t"
"movl $70, %%eax \n\t"
"int $0x40 \n\t"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"a" (path), "b" (size));
return retval;
};
 
int get_fileinfo(const char *path, fileinfo_t *info)
{
int retval;
 
__asm__ __volatile__ (
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %1, 1(%%esp) \n\t"
"pushl %%ebx \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $5 \n\t"
"movl %%esp, %%ebx \n\t"
"movl $70, %%eax \n\t"
"int $0x40 \n\t"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"r" (path), "b" (info));
return retval;
};
 
 
int read_file(const char *path, void *buff,
size_t offset, size_t count, size_t *reads)
{
int retval;
int d0;
__asm__ __volatile__(
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %%eax, 1(%%esp) \n\t"
"pushl %%ebx \n\t"
"pushl %%edx \n\t"
"pushl $0 \n\t"
"pushl %%ecx \n\t"
"pushl $0 \n\t"
"movl %%esp, %%ebx \n\t"
"mov $70, %%eax \n\t"
"int $0x40 \n\t"
"testl %%esi, %%esi \n\t"
"jz 1f \n\t"
"movl %%ebx, (%%esi) \n\t"
"1:"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"a"(path),"b"(buff),"c"(offset),"d"(count),"S"(reads));
return retval;
};
 
 
static inline void debug_out(const char val)
{
__asm__ __volatile__(
241,33 → 93,6
return ret;
};
 
 
int write_file(const char *path,const void *buff,
size_t offset, size_t count, size_t *writes)
{
int retval;
__asm__ __volatile__(
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %%eax, 1(%%esp) \n\t"
"pushl %%ebx \n\t"
"pushl %%edx \n\t"
"pushl $0 \n\t"
"pushl %%ecx \n\t"
"pushl $3 \n\t"
"movl %%esp, %%ebx \n\t"
"mov $70, %%eax \n\t"
"int $0x40 \n\t"
"testl %%esi, %%esi \n\t"
"jz 1f \n\t"
"movl %%ebx, (%%esi) \n\t"
"1:"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"a"(path),"b"(buff),"c"(offset),"d"(count),"S"(writes));
return retval;
};
 
static int __openFileHandle(const char *path, int mode, int *err)
{
fileinfo_t info;
/programs/develop/libraries/newlib/signal/signal.c
0,0 → 1,260
/*
FUNCTION
<<signal>>---specify handler subroutine for a signal
 
INDEX
signal
INDEX
_signal_r
 
ANSI_SYNOPSIS
#include <signal.h>
void (*signal(int <[sig]>, void(*<[func]>)(int))) (int);
 
void (*_signal_r(void *<[reent]>, int <[sig]>, void(*<[func]>)(int))) (int);
 
TRAD_SYNOPSIS
#include <signal.h>
char ( * signal(<[sig]>, <[func]>) )()
int <[sig]>;
char ( * <[func]> )();
 
char ( * _signal_r(<[reent]>, <[sig]>, <[func]>) )()
char *<[reent]>;
int <[sig]>;
char ( * <[func]> )();
 
DESCRIPTION
<<signal>> provides a simple signal-handling implementation for embedded
targets.
 
<<signal>> allows you to request changed treatment for a particular
signal <[sig]>. You can use one of the predefined macros <<SIG_DFL>>
(select system default handling) or <<SIG_IGN>> (ignore this signal)
as the value of <[func]>; otherwise, <[func]> is a function pointer
that identifies a subroutine in your program as the handler for this signal.
 
Some of the execution environment for signal handlers is
unpredictable; notably, the only library function required to work
correctly from within a signal handler is <<signal>> itself, and
only when used to redefine the handler for the current signal value.
 
Static storage is likewise unreliable for signal handlers, with one
exception: if you declare a static storage location as `<<volatile
sig_atomic_t>>', then you may use that location in a signal handler to
store signal values.
 
If your signal handler terminates using <<return>> (or implicit
return), your program's execution continues at the point
where it was when the signal was raised (whether by your program
itself, or by an external event). Signal handlers can also
use functions such as <<exit>> and <<abort>> to avoid returning.
 
The alternate function <<_signal_r>> is the reentrant version.
The extra argument <[reent]> is a pointer to a reentrancy structure.
 
@c FIXME: do we have setjmp.h and assoc fns?
 
RETURNS
If your request for a signal handler cannot be honored, the result is
<<SIG_ERR>>; a specific error number is also recorded in <<errno>>.
 
Otherwise, the result is the previous handler (a function pointer or
one of the predefined macros).
 
PORTABILITY
ANSI C requires <<signal>>.
 
No supporting OS subroutines are required to link with <<signal>>, but
it will not have any useful effects, except for software generated signals,
without an operating system that can actually raise exceptions.
*/
 
/*
* signal.c
* Original Author: G. Haley
*
* signal associates the function pointed to by func with the signal sig. When
* a signal occurs, the value of func determines the action taken as follows:
* if func is SIG_DFL, the default handling for that signal will occur; if func
* is SIG_IGN, the signal will be ignored; otherwise, the default handling for
* the signal is restored (SIG_DFL), and the function func is called with sig
* as its argument. Returns the value of func for the previous call to signal
* for the signal sig, or SIG_ERR if the request fails.
*/
 
/* _init_signal initialises the signal handlers for each signal. This function
is called by crt0 at program startup. */
 
#ifdef SIGNAL_PROVIDED
 
int _dummy_simulated_signal;
 
#else
 
#include <errno.h>
#include <signal.h>
#include <stddef.h>
#include <stdlib.h>
#include <reent.h>
#include <_syslist.h>
 
int
_DEFUN (_init_signal_r, (ptr),
struct _reent *ptr)
{
int i;
 
if (ptr->_sig_func == NULL)
{
ptr->_sig_func = (_sig_func_ptr *)_malloc_r (ptr, sizeof (_sig_func_ptr) * NSIG);
if (ptr->_sig_func == NULL)
return -1;
 
for (i = 0; i < NSIG; i++)
ptr->_sig_func[i] = SIG_DFL;
}
 
return 0;
}
 
_sig_func_ptr
_DEFUN (_signal_r, (ptr, sig, func),
struct _reent *ptr _AND
int sig _AND
_sig_func_ptr func)
{
_sig_func_ptr old_func;
 
if (sig < 0 || sig >= NSIG)
{
ptr->_errno = EINVAL;
return SIG_ERR;
}
 
if (ptr->_sig_func == NULL && _init_signal_r (ptr) != 0)
return SIG_ERR;
old_func = ptr->_sig_func[sig];
ptr->_sig_func[sig] = func;
 
return old_func;
}
 
int
_DEFUN (_raise_r, (ptr, sig),
struct _reent *ptr _AND
int sig)
{
_sig_func_ptr func;
 
if (sig < 0 || sig >= NSIG)
{
ptr->_errno = EINVAL;
return -1;
}
 
if (ptr->_sig_func == NULL)
func = SIG_DFL;
else
func = ptr->_sig_func[sig];
 
if (func == SIG_DFL)
return _kill_r (ptr, _getpid_r (ptr), sig);
else if (func == SIG_IGN)
return 0;
else if (func == SIG_ERR)
{
ptr->_errno = EINVAL;
return 1;
}
else
{
ptr->_sig_func[sig] = SIG_DFL;
func (sig);
return 0;
}
}
 
int
_DEFUN (__sigtramp_r, (ptr, sig),
struct _reent *ptr _AND
int sig)
{
_sig_func_ptr func;
 
if (sig < 0 || sig >= NSIG)
{
return -1;
}
 
if (ptr->_sig_func == NULL && _init_signal_r (ptr) != 0)
return -1;
 
func = ptr->_sig_func[sig];
if (func == SIG_DFL)
return 1;
else if (func == SIG_ERR)
return 2;
else if (func == SIG_IGN)
return 3;
else
{
ptr->_sig_func[sig] = SIG_DFL;
func (sig);
return 0;
}
}
 
 
int _DEFUN (_kill_r, (ptr, pid, sig),
struct _reent *ptr _AND
int pid _AND
int sig)
{
// int ret;
 
// errno = 0;
// if ((ret = _kill (pid, sig)) == -1 && errno != 0)
// ptr->_errno = errno;
// return ret;
 
/* sorry, guys */
 
ptr->_errno = EPERM;
return -1;
}
 
 
#ifndef _REENT_ONLY
 
int
_DEFUN (raise, (sig),
int sig)
{
return _raise_r (_REENT, sig);
}
 
_sig_func_ptr
_DEFUN (signal, (sig, func),
int sig _AND
_sig_func_ptr func)
{
return _signal_r (_REENT, sig, func);
}
 
int
_DEFUN_VOID (_init_signal)
{
return _init_signal_r (_REENT);
}
 
int
_DEFUN (__sigtramp, (sig), int sig)
{
return __sigtramp_r (_REENT, sig);
}
 
#endif
 
#endif /* !SIGNAL_PROVIDED */
/programs/develop/libraries/newlib/signal
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property
/programs/develop/libraries/newlib/static.lds
0,0 → 1,116
/*OUTPUT_FORMAT("binary")*/
 
ENTRY(__start)
SECTIONS
{
.text 0x000000:
{
LONG(0x554e454D);
LONG(0x32305445);
LONG(1);
LONG(__start);
LONG(___iend);
LONG(___memsize);
LONG(___stacktop);
LONG(___cmdline);
LONG(___pgmname); /* full path */
LONG(0); /*FIXME tls data */
 
*(.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(16) :
{
*(.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(16) :
{
___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(16) :
{
__data_start__ = . ;
*(.data)
*(.data2)
*(SORT(.data$*))
*(.jcr)
__CRT_MT = .;
LONG(0);
__data_end__ = . ;
*(.data_cygwin_nocopy)
}
 
.eh_frame ALIGN(16) :
{
*(.eh_frame)
___iend = . ;
}
 
bss ALIGN(16):
{
*(.bss)
*(COMMON)
. = ALIGN(16);
___cmdline = .;
. = . + 256;
___pgmname = .;
___menuet__app_path_area = .;
. = . + 1024 + 16;
___stacktop = .;
___memsize = . ;
}
 
/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)
}
 
}
/programs/develop/libraries/newlib/stdio/fdopen.c
0,0 → 1,144
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<fdopen>>---turn open file into a stream
 
INDEX
fdopen
INDEX
_fdopen_r
 
ANSI_SYNOPSIS
#include <stdio.h>
FILE *fdopen(int <[fd]>, const char *<[mode]>);
FILE *_fdopen_r(struct _reent *<[reent]>,
int <[fd]>, const char *<[mode]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
FILE *fdopen(<[fd]>, <[mode]>)
int <[fd]>;
char *<[mode]>;
 
FILE *_fdopen_r(<[reent]>, <[fd]>, <[mode]>)
struct _reent *<[reent]>;
int <[fd]>;
char *<[mode]>);
 
DESCRIPTION
<<fdopen>> produces a file descriptor of type <<FILE *>>, from a
descriptor for an already-open file (returned, for example, by the
system subroutine <<open>> rather than by <<fopen>>).
The <[mode]> argument has the same meanings as in <<fopen>>.
 
RETURNS
File pointer or <<NULL>>, as for <<fopen>>.
 
PORTABILITY
<<fdopen>> is ANSI.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <stdio.h>
#include <errno.h>
#include "local.h"
#include <_syslist.h>
 
FILE *
_DEFUN(_fdopen_r, (ptr, fd, mode),
struct _reent *ptr _AND
int fd _AND
_CONST char *mode)
{
register FILE *fp;
int flags, oflags;
#ifdef HAVE_FCNTL
int fdflags, fdmode;
#endif
 
if ((flags = __sflags (ptr, mode, &oflags)) == 0)
return 0;
 
/* make sure the mode the user wants is a subset of the actual mode */
#ifdef HAVE_FCNTL
if ((fdflags = _fcntl_r (ptr, fd, F_GETFL, 0)) < 0)
return 0;
fdmode = fdflags & O_ACCMODE;
if (fdmode != O_RDWR && (fdmode != (oflags & O_ACCMODE)))
{
ptr->_errno = EBADF;
return 0;
}
#endif
 
if ((fp = __sfp (ptr)) == 0)
return 0;
 
_flockfile (fp);
 
fp->_flags = flags;
/* POSIX recommends setting the O_APPEND bit on fd to match append
streams. Someone may later clear O_APPEND on fileno(fp), but the
stream must still remain in append mode. Rely on __sflags
setting __SAPP properly. */
#ifdef HAVE_FCNTL
if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
_fcntl_r (ptr, fd, F_SETFL, fdflags | O_APPEND);
#endif
fp->_file = fd;
fp->_cookie = (_PTR) fp;
 
#undef _read
#undef _write
#undef _seek
#undef _close
 
fp->_read = __sread;
fp->_write = __swrite;
fp->_seek = __sseek;
fp->_close = __sclose;
 
#ifdef __SCLE
/* Explicit given mode results in explicit setting mode on fd */
if (oflags & O_BINARY)
setmode (fp->_file, O_BINARY);
else if (oflags & O_TEXT)
setmode (fp->_file, O_TEXT);
if (__stextmode (fp->_file))
fp->_flags |= __SCLE;
#endif
 
_funlockfile (fp);
return fp;
}
 
#ifndef _REENT_ONLY
 
FILE *
_DEFUN(fdopen, (fd, mode),
int fd _AND
_CONST char *mode)
{
return _fdopen_r (_REENT, fd, mode);
}
 
#endif
/programs/develop/libraries/newlib/stdio/fgets.c
0,0 → 1,193
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<fgets>>---get character string from a file or stream
 
INDEX
fgets
INDEX
_fgets_r
 
ANSI_SYNOPSIS
#include <stdio.h>
char *fgets(char *<[buf]>, int <[n]>, FILE *<[fp]>);
 
#include <stdio.h>
char *_fgets_r(struct _reent *<[ptr]>, char *<[buf]>, int <[n]>, FILE *<[fp]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
char *fgets(<[buf]>,<[n]>,<[fp]>)
char *<[buf]>;
int <[n]>;
FILE *<[fp]>;
 
#include <stdio.h>
char *_fgets_r(<[ptr]>, <[buf]>,<[n]>,<[fp]>)
struct _reent *<[ptr]>;
char *<[buf]>;
int <[n]>;
FILE *<[fp]>;
 
DESCRIPTION
Reads at most <[n-1]> characters from <[fp]> until a newline
is found. The characters including to the newline are stored
in <[buf]>. The buffer is terminated with a 0.
 
The <<_fgets_r>> function is simply the reentrant version of
<<fgets>> and is passed an additional reentrancy structure
pointer: <[ptr]>.
 
RETURNS
<<fgets>> returns the buffer passed to it, with the data
filled in. If end of file occurs with some data already
accumulated, the data is returned with no other indication. If
no data are read, NULL is returned instead.
 
PORTABILITY
<<fgets>> should replace all uses of <<gets>>. Note however
that <<fgets>> returns all of the data, while <<gets>> removes
the trailing newline (with no indication that it has done so.)
 
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
 
#include <_ansi.h>
#include <stdio.h>
#include <string.h>
#include "local.h"
 
/*
* Read at most n-1 characters from the given file.
* Stop when a newline has been read, or the count runs out.
* Return first argument, or NULL if no characters were read.
*/
 
char *
_DEFUN(_fgets_r, (ptr, buf, n, fp),
struct _reent * ptr _AND
char *buf _AND
int n _AND
FILE * fp)
{
size_t len;
char *s;
unsigned char *p, *t;
 
if (n < 2) /* sanity check */
return 0;
 
s = buf;
 
CHECK_INIT(ptr, fp);
 
__sfp_lock_acquire ();
_flockfile (fp);
#ifdef __SCLE
if (fp->_flags & __SCLE)
{
int c;
/* Sorry, have to do it the slow way */
while (--n > 0 && (c = __sgetc_r (ptr, fp)) != EOF)
{
*s++ = c;
if (c == '\n')
break;
}
if (c == EOF && s == buf)
{
_funlockfile (fp);
__sfp_lock_release ();
return NULL;
}
*s = 0;
_funlockfile (fp);
__sfp_lock_release ();
return buf;
}
#endif
 
n--; /* leave space for NUL */
do
{
/*
* If the buffer is empty, refill it.
*/
if ((len = fp->_r) <= 0)
{
if (__srefill_r (ptr, fp))
{
/* EOF: stop with partial or no line */
if (s == buf)
{
_funlockfile (fp);
__sfp_lock_release ();
return 0;
}
break;
}
len = fp->_r;
}
p = fp->_p;
 
/*
* Scan through at most n bytes of the current buffer,
* looking for '\n'. If found, copy up to and including
* newline, and stop. Otherwise, copy entire chunk
* and loop.
*/
if (len > n)
len = n;
t = (unsigned char *) memchr ((_PTR) p, '\n', len);
if (t != 0)
{
len = ++t - p;
fp->_r -= len;
fp->_p = t;
_CAST_VOID memcpy ((_PTR) s, (_PTR) p, len);
s[len] = 0;
_funlockfile (fp);
__sfp_lock_release ();
return (buf);
}
fp->_r -= len;
fp->_p += len;
_CAST_VOID memcpy ((_PTR) s, (_PTR) p, len);
s += len;
}
while ((n -= len) != 0);
*s = 0;
_funlockfile (fp);
__sfp_lock_release ();
return buf;
}
 
#ifndef _REENT_ONLY
 
char *
_DEFUN(fgets, (buf, n, fp),
char *buf _AND
int n _AND
FILE * fp)
{
return _fgets_r (_REENT, buf, n, fp);
}
 
#endif /* !_REENT_ONLY */
/programs/develop/libraries/newlib/stdio/fiscanf.c
0,0 → 1,78
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "local.h"
 
#ifndef _REENT_ONLY
 
int
#ifdef _HAVE_STDC
fiscanf(FILE *fp, _CONST char *fmt, ...)
#else
fiscanf(FILE *fp, fmt, va_alist)
FILE *fp;
char *fmt;
va_dcl
#endif
{
int ret;
va_list ap;
 
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
ret = __svfiscanf_r (_REENT, fp, fmt, ap);
va_end (ap);
return ret;
}
 
#endif /* !_REENT_ONLY */
 
int
#ifdef _HAVE_STDC
_fiscanf_r(struct _reent *ptr, FILE *fp, _CONST char *fmt, ...)
#else
_fiscanf_r(ptr, FILE *fp, fmt, va_alist)
struct _reent *ptr;
FILE *fp;
char *fmt;
va_dcl
#endif
{
int ret;
va_list ap;
 
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
ret = __svfiscanf_r (ptr, fp, fmt, ap);
va_end (ap);
return (ret);
}
 
/programs/develop/libraries/newlib/stdio/fread.c
0,0 → 1,265
/*
* Copyright (c) 1990, 2007 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<fread>>---read array elements from a file
 
INDEX
fread
INDEX
_fread_r
 
ANSI_SYNOPSIS
#include <stdio.h>
size_t fread(void *<[buf]>, size_t <[size]>, size_t <[count]>,
FILE *<[fp]>);
 
#include <stdio.h>
size_t _fread_r(struct _reent *<[ptr]>, void *<[buf]>,
size_t <[size]>, size_t <[count]>, FILE *<[fp]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
size_t fread(<[buf]>, <[size]>, <[count]>, <[fp]>)
char *<[buf]>;
size_t <[size]>;
size_t <[count]>;
FILE *<[fp]>;
 
#include <stdio.h>
size_t _fread_r(<[ptr]>, <[buf]>, <[size]>, <[count]>, <[fp]>)
struct _reent *<[ptr]>;
char *<[buf]>;
size_t <[size]>;
size_t <[count]>;
FILE *<[fp]>;
 
DESCRIPTION
<<fread>> attempts to copy, from the file or stream identified by
<[fp]>, <[count]> elements (each of size <[size]>) into memory,
starting at <[buf]>. <<fread>> may copy fewer elements than
<[count]> if an error, or end of file, intervenes.
 
<<fread>> also advances the file position indicator (if any) for
<[fp]> by the number of @emph{characters} actually read.
 
<<_fread_r>> is simply the reentrant version of <<fread>> that
takes an additional reentrant structure pointer argument: <[ptr]>.
 
RETURNS
The result of <<fread>> is the number of elements it succeeded in
reading.
 
PORTABILITY
ANSI C requires <<fread>>.
 
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
 
#include <_ansi.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "local.h"
 
#ifdef __SCLE
static size_t
_DEFUN(crlf_r, (ptr, fp, buf, count, eof),
struct _reent * ptr _AND
FILE * fp _AND
char * buf _AND
size_t count _AND
int eof)
{
int r;
char *s, *d, *e;
 
if (count == 0)
return 0;
 
e = buf + count;
for (s=d=buf; s<e-1; s++)
{
if (*s == '\r' && s[1] == '\n')
s++;
*d++ = *s;
}
if (s < e)
{
if (*s == '\r')
{
int c = __sgetc_raw_r (ptr, fp);
if (c == '\n')
*s = '\n';
else
ungetc (c, fp);
}
*d++ = *s++;
}
 
 
while (d < e)
{
r = _getc_r (ptr, fp);
if (r == EOF)
return count - (e-d);
*d++ = r;
}
 
return count;
}
 
#endif
 
size_t
_DEFUN(_fread_r, (ptr, buf, size, count, fp),
struct _reent * ptr _AND
_PTR buf _AND
size_t size _AND
size_t count _AND
FILE * fp)
{
register size_t resid;
register char *p;
register int r;
size_t total;
 
if ((resid = count * size) == 0)
return 0;
 
CHECK_INIT(ptr, fp);
 
__sfp_lock_acquire ();
_flockfile (fp);
ORIENT (fp, -1);
if (fp->_r < 0)
fp->_r = 0;
total = resid;
p = buf;
 
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
 
/* Optimize unbuffered I/O. */
if (fp->_flags & __SNBF)
{
/* First copy any available characters from ungetc buffer. */
int copy_size = resid > fp->_r ? fp->_r : resid;
_CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) copy_size);
fp->_p += copy_size;
fp->_r -= copy_size;
p += copy_size;
resid -= copy_size;
 
/* If still more data needed, free any allocated ungetc buffer. */
if (HASUB (fp) && resid > 0)
FREEUB (ptr, fp);
 
/* Finally read directly into user's buffer if needed. */
while (resid > 0)
{
int rc = 0;
/* save fp buffering state */
void *old_base = fp->_bf._base;
void * old_p = fp->_p;
int old_size = fp->_bf._size;
/* allow __refill to use user's buffer */
fp->_bf._base = (unsigned char *) p;
fp->_bf._size = resid;
fp->_p = (unsigned char *) p;
rc = __srefill_r (ptr, fp);
/* restore fp buffering back to original state */
fp->_bf._base = old_base;
fp->_bf._size = old_size;
fp->_p = old_p;
resid -= fp->_r;
p += fp->_r;
fp->_r = 0;
if (rc)
{
#ifdef __SCLE
if (fp->_flags & __SCLE)
{
_funlockfile (fp);
__sfp_lock_release ();
return crlf_r (ptr, fp, buf, total-resid, 1) / size;
}
#endif
_funlockfile (fp);
__sfp_lock_release ();
return (total - resid) / size;
}
}
}
else
#endif /* !PREFER_SIZE_OVER_SPEED && !__OPTIMIZE_SIZE__ */
{
while (resid > (r = fp->_r))
{
_CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) r);
fp->_p += r;
/* fp->_r = 0 ... done in __srefill */
p += r;
resid -= r;
if (__srefill_r (ptr, fp))
{
/* no more input: return partial result */
#ifdef __SCLE
if (fp->_flags & __SCLE)
{
_funlockfile (fp);
__sfp_lock_release ();
return crlf_r (ptr, fp, buf, total-resid, 1) / size;
}
#endif
_funlockfile (fp);
__sfp_lock_release ();
return (total - resid) / size;
}
}
_CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, resid);
fp->_r -= resid;
fp->_p += resid;
}
 
/* Perform any CR/LF clean-up if necessary. */
#ifdef __SCLE
if (fp->_flags & __SCLE)
{
_funlockfile (fp);
__sfp_lock_release ();
return crlf_r(ptr, fp, buf, total, 0) / size;
}
#endif
_funlockfile (fp);
__sfp_lock_release ();
return count;
}
 
#ifndef _REENT_ONLY
size_t
_DEFUN(fread, (buf, size, count, fp),
_PTR buf _AND
size_t size _AND
size_t count _AND
FILE * fp)
{
return _fread_r (_REENT, buf, size, count, fp);
}
#endif
/programs/develop/libraries/newlib/stdio/freopen.c
0,0 → 1,250
/*
* Copyright (c) 1990, 2007 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<freopen>>---open a file using an existing file descriptor
 
INDEX
freopen
INDEX
_freopen_r
 
ANSI_SYNOPSIS
#include <stdio.h>
FILE *freopen(const char *<[file]>, const char *<[mode]>,
FILE *<[fp]>);
FILE *_freopen_r(struct _reent *<[ptr]>, const char *<[file]>,
const char *<[mode]>, FILE *<[fp]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
FILE *freopen(<[file]>, <[mode]>, <[fp]>)
char *<[file]>;
char *<[mode]>;
FILE *<[fp]>;
 
FILE *_freopen_r(<[ptr]>, <[file]>, <[mode]>, <[fp]>)
struct _reent *<[ptr]>;
char *<[file]>;
char *<[mode]>;
FILE *<[fp]>;
 
DESCRIPTION
Use this variant of <<fopen>> if you wish to specify a particular file
descriptor <[fp]> (notably <<stdin>>, <<stdout>>, or <<stderr>>) for
the file.
 
If <[fp]> was associated with another file or stream, <<freopen>>
closes that other file or stream (but ignores any errors while closing
it).
 
<[file]> and <[mode]> are used just as in <<fopen>>.
 
If <[file]> is <<NULL>>, the underlying stream is modified rather than
closed. The file cannot be given a more permissive access mode (for
example, a <[mode]> of "w" will fail on a read-only file descriptor),
but can change status such as append or binary mode. If modification
is not possible, failure occurs.
 
RETURNS
If successful, the result is the same as the argument <[fp]>. If the
file cannot be opened as specified, the result is <<NULL>>.
 
PORTABILITY
ANSI C requires <<freopen>>.
 
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/lock.h>
#include "local.h"
 
/*
* Re-direct an existing, open (probably) file to some other file.
*/
 
FILE *
_DEFUN(_freopen_r, (ptr, file, mode, fp),
struct _reent *ptr _AND
const char *file _AND
const char *mode _AND
register FILE *fp)
{
register int f;
int flags, oflags;
int e = 0;
 
__sfp_lock_acquire ();
 
CHECK_INIT (ptr, fp);
 
_flockfile (fp);
 
if ((flags = __sflags (ptr, mode, &oflags)) == 0)
{
_funlockfile (fp);
_fclose_r (ptr, fp);
__sfp_lock_release ();
return NULL;
}
 
/*
* Remember whether the stream was open to begin with, and
* which file descriptor (if any) was associated with it.
* If it was attached to a descriptor, defer closing it,
* so that, e.g., freopen("/dev/stdin", "r", stdin) works.
* This is unnecessary if it was not a Unix file.
*/
 
if (fp->_flags == 0)
fp->_flags = __SEOF; /* hold on to it */
else
{
if (fp->_flags & __SWR)
_fflush_r (ptr, fp);
/*
* If close is NULL, closing is a no-op, hence pointless.
* If file is NULL, the file should not be closed.
*/
if (fp->_close != NULL && file != NULL)
fp->_close (ptr, fp->_cookie);
}
 
/*
* Now get a new descriptor to refer to the new file, or reuse the
* existing file descriptor if file is NULL.
*/
 
if (file != NULL)
{
f = _open_r (ptr, (char *) file, oflags, 0666);
e = ptr->_errno;
}
else
{
#ifdef HAVE_FCNTL
int oldflags;
/*
* Reuse the file descriptor, but only if the new access mode is
* equal or less permissive than the old. F_SETFL correctly
* ignores creation flags.
*/
f = fp->_file;
if ((oldflags = _fcntl_r (ptr, f, F_GETFL, 0)) == -1
|| ! ((oldflags & O_ACCMODE) == O_RDWR
|| ((oldflags ^ oflags) & O_ACCMODE) == 0)
|| _fcntl_r (ptr, f, F_SETFL, oflags) == -1)
f = -1;
#else
/* We cannot modify without fcntl support. */
f = -1;
#endif
 
#ifdef __SCLE
/*
* F_SETFL doesn't change textmode. Don't mess with modes of ttys.
*/
if (0 <= f && ! _isatty_r (ptr, f)
&& setmode (f, oflags & (O_BINARY | O_TEXT)) == -1)
f = -1;
#endif
 
if (f < 0)
{
e = EBADF;
if (fp->_close != NULL)
fp->_close (ptr, fp->_cookie);
}
}
 
/*
* Finish closing fp. Even if the open succeeded above,
* we cannot keep fp->_base: it may be the wrong size.
* This loses the effect of any setbuffer calls,
* but stdio has always done this before.
*/
 
if (fp->_flags & __SMBF)
_free_r (ptr, (char *) fp->_bf._base);
fp->_w = 0;
fp->_r = 0;
fp->_p = NULL;
fp->_bf._base = NULL;
fp->_bf._size = 0;
fp->_lbfsize = 0;
if (HASUB (fp))
FREEUB (ptr, fp);
fp->_ub._size = 0;
if (HASLB (fp))
FREELB (ptr, fp);
fp->_lb._size = 0;
fp->_flags & ~__SORD;
fp->_flags2 = 0;
memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
 
if (f < 0)
{ /* did not get it after all */
fp->_flags = 0; /* set it free */
ptr->_errno = e; /* restore in case _close clobbered */
_funlockfile (fp);
#ifndef __SINGLE_THREAD__
__lock_close_recursive (fp->_lock);
#endif
__sfp_lock_release ();
return NULL;
}
 
fp->_flags = flags;
fp->_file = f;
fp->_cookie = (_PTR) fp;
fp->_read = __sread;
fp->_write = __swrite;
fp->_seek = __sseek;
fp->_close = __sclose;
 
#ifdef __SCLE
if (__stextmode (fp->_file))
fp->_flags |= __SCLE;
#endif
 
_funlockfile (fp);
__sfp_lock_release ();
return fp;
}
 
#ifndef _REENT_ONLY
 
FILE *
_DEFUN(freopen, (file, mode, fp),
_CONST char *file _AND
_CONST char *mode _AND
register FILE *fp)
{
return _freopen_r (_REENT, file, mode, fp);
}
 
#endif /*!_REENT_ONLY */
/programs/develop/libraries/newlib/stdio/fscanf.c
0,0 → 1,78
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "local.h"
 
#ifndef _REENT_ONLY
 
int
#ifdef _HAVE_STDC
fscanf(FILE *fp, _CONST char *fmt, ...)
#else
fscanf(FILE *fp, fmt, va_alist)
FILE *fp;
char *fmt;
va_dcl
#endif
{
int ret;
va_list ap;
 
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
ret = __svfscanf_r (_REENT, fp, fmt, ap);
va_end (ap);
return ret;
}
 
#endif /* !_REENT_ONLY */
 
int
#ifdef _HAVE_STDC
_fscanf_r(struct _reent *ptr, FILE *fp, _CONST char *fmt, ...)
#else
_fscanf_r(ptr, FILE *fp, fmt, va_alist)
struct _reent *ptr;
FILE *fp;
char *fmt;
va_dcl
#endif
{
int ret;
va_list ap;
 
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
ret = __svfscanf_r (ptr, fp, fmt, ap);
va_end (ap);
return (ret);
}
 
/programs/develop/libraries/newlib/stdio/fseeko.c
0,0 → 1,44
/*
* Copyright (c) 2002, Red Hat Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
 
int
_DEFUN(_fseeko_r, (ptr, fp, offset, whence),
struct _reent *ptr _AND
register FILE *fp _AND
_off_t offset _AND
int whence)
{
return _fseek_r (ptr, fp, (long)offset, whence);
}
 
#ifndef _REENT_ONLY
 
int
_DEFUN(fseeko, (fp, offset, whence),
register FILE *fp _AND
_off_t offset _AND
int whence)
{
/* for now we simply cast since off_t should be long */
return _fseek_r (_REENT, fp, (long)offset, whence);
}
 
#endif /* !_REENT_ONLY */
/programs/develop/libraries/newlib/stdio/ftell.c
0,0 → 1,177
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<ftell>>, <<ftello>>---return position in a stream or file
 
INDEX
ftell
INDEX
ftello
INDEX
_ftell_r
INDEX
_ftello_r
 
ANSI_SYNOPSIS
#include <stdio.h>
long ftell(FILE *<[fp]>);
off_t ftello(FILE *<[fp]>);
long _ftell_r(struct _reent *<[ptr]>, FILE *<[fp]>);
off_t _ftello_r(struct _reent *<[ptr]>, FILE *<[fp]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
long ftell(<[fp]>)
FILE *<[fp]>;
 
off_t ftello(<[fp]>)
FILE *<[fp]>;
 
long _ftell_r(<[ptr]>, <[fp]>)
struct _reent *<[ptr]>;
FILE *<[fp]>;
 
off_t _ftello_r(<[ptr]>, <[fp]>)
struct _reent *<[ptr]>;
FILE *<[fp]>;
 
DESCRIPTION
Objects of type <<FILE>> can have a ``position'' that records how much
of the file your program has already read. Many of the <<stdio>> functions
depend on this position, and many change it as a side effect.
 
The result of <<ftell>>/<<ftello>> is the current position for a file
identified by <[fp]>. If you record this result, you can later
use it with <<fseek>>/<<fseeko>> to return the file to this
position. The difference between <<ftell>> and <<ftello>> is that
<<ftell>> returns <<long>> and <<ftello>> returns <<off_t>>.
 
In the current implementation, <<ftell>>/<<ftello>> simply uses a character
count to represent the file position; this is the same number that
would be recorded by <<fgetpos>>.
 
RETURNS
<<ftell>>/<<ftello>> return the file position, if possible. If they cannot do
this, they return <<-1L>>. Failure occurs on streams that do not support
positioning; the global <<errno>> indicates this condition with the
value <<ESPIPE>>.
 
PORTABILITY
<<ftell>> is required by the ANSI C standard, but the meaning of its
result (when successful) is not specified beyond requiring that it be
acceptable as an argument to <<fseek>>. In particular, other
conforming C implementations may return a different result from
<<ftell>> than what <<fgetpos>> records.
 
<<ftello>> is defined by the Single Unix specification.
 
No supporting OS subroutines are required.
*/
 
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
 
/*
* ftell: return current offset.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <errno.h>
#include "local.h"
 
long
_DEFUN(_ftell_r, (ptr, fp),
struct _reent *ptr _AND
register FILE * fp)
{
_fpos_t pos;
 
/* Ensure stdio is set up. */
 
CHECK_INIT (ptr, fp);
 
_flockfile (fp);
 
if (fp->_seek == NULL)
{
ptr->_errno = ESPIPE;
_funlockfile (fp);
return -1L;
}
 
/* Find offset of underlying I/O object, then adjust for buffered
bytes. Flush a write stream, since the offset may be altered if
the stream is appending. Do not flush a read stream, since we
must not lose the ungetc buffer. */
if (fp->_flags & __SWR)
_fflush_r (ptr, fp);
if (fp->_flags & __SOFF)
pos = fp->_offset;
else
{
pos = fp->_seek (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR);
if (pos == -1L)
{
_funlockfile (fp);
return pos;
}
}
if (fp->_flags & __SRD)
{
/*
* Reading. Any unread characters (including
* those from ungetc) cause the position to be
* smaller than that in the underlying object.
*/
pos -= fp->_r;
if (HASUB (fp))
pos -= fp->_ur;
}
else if ((fp->_flags & __SWR) && fp->_p != NULL)
{
/*
* Writing. Any buffered characters cause the
* position to be greater than that in the
* underlying object.
*/
pos += fp->_p - fp->_bf._base;
}
 
_funlockfile (fp);
if ((long)pos != pos)
{
pos = -1;
ptr->_errno = EOVERFLOW;
}
return pos;
}
 
#ifndef _REENT_ONLY
 
long
_DEFUN(ftell, (fp),
register FILE * fp)
{
return _ftell_r (_REENT, fp);
}
 
#endif /* !_REENT_ONLY */
/programs/develop/libraries/newlib/stdio/ftello.c
0,0 → 1,40
/*
* Copyright (c) 2002, Red Hat Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
 
_off_t
_DEFUN(_ftello_r, (ptr, fp),
struct _reent * ptr _AND
register FILE * fp)
{
/* for now we simply cast since off_t should be long */
return (_off_t)_ftell_r (ptr, fp);
}
 
#ifndef _REENT_ONLY
 
_off_t
_DEFUN(ftello, (fp),
register FILE * fp)
{
return (_off_t)_ftell_r (_REENT, fp);
}
 
#endif /* !_REENT_ONLY */
/programs/develop/libraries/newlib/stdio/putchar.c
0,0 → 1,97
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<putchar>>---write a character (macro)
 
INDEX
putchar
INDEX
_putchar_r
 
ANSI_SYNOPSIS
#include <stdio.h>
int putchar(int <[ch]>);
 
int _putchar_r(struct _reent *<[reent]>, int <[ch]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
int putchar(<[ch]>)
int <[ch]>;
 
int _putchar_r(<[reent]>, <[ch]>)
struct _reent *<[reent]>;
int <[ch]>;
 
DESCRIPTION
<<putchar>> is a macro, defined in <<stdio.h>>. <<putchar>>
writes its argument to the standard output stream,
after converting it from an <<int>> to an <<unsigned char>>.
 
The alternate function <<_putchar_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
 
RETURNS
If successful, <<putchar>> returns its argument <[ch]>. If an error
intervenes, the result is <<EOF>>. You can use `<<ferror(stdin)>>' to
query for errors.
 
PORTABILITY
ANSI C requires <<putchar>>; it suggests, but does not require, that
<<putchar>> be implemented as a macro.
 
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
 
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
 
/*
* A subroutine version of the macro putchar.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include "local.h"
 
#undef putchar
 
int
_DEFUN(_putchar_r, (ptr, c),
struct _reent *ptr _AND
int c)
{
_REENT_SMALL_CHECK_INIT (ptr);
return _putc_r (ptr, c, _stdout_r (ptr));
}
 
#ifndef _REENT_ONLY
 
int
_DEFUN(putchar, (c),
int c)
{
_REENT_SMALL_CHECK_INIT (_REENT);
return _putc_r (_REENT, c, _stdout_r (_REENT));
}
 
#endif
/programs/develop/libraries/newlib/stdio/remove.c
0,0 → 1,91
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<remove>>---delete a file's name
 
INDEX
remove
INDEX
_remove_r
 
ANSI_SYNOPSIS
#include <stdio.h>
int remove(char *<[filename]>);
 
int _remove_r(struct _reent *<[reent]>, char *<[filename]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
int remove(<[filename]>)
char *<[filename]>;
 
int _remove_r(<[reent]>, <[filename]>)
struct _reent *<[reent]>;
char *<[filename]>;
 
DESCRIPTION
Use <<remove>> to dissolve the association between a particular
filename (the string at <[filename]>) and the file it represents.
After calling <<remove>> with a particular filename, you will no
longer be able to open the file by that name.
 
In this implementation, you may use <<remove>> on an open file without
error; existing file descriptors for the file will continue to access
the file's data until the program using them closes the file.
 
The alternate function <<_remove_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
 
RETURNS
<<remove>> returns <<0>> if it succeeds, <<-1>> if it fails.
 
PORTABILITY
ANSI C requires <<remove>>, but only specifies that the result on
failure be nonzero. The behavior of <<remove>> when you call it on an
open file may vary among implementations.
 
Supporting OS subroutine required: <<unlink>>.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <sys/kos_io.h>
 
 
int
_DEFUN(_remove_r, (ptr, filename),
struct _reent *ptr _AND
_CONST char *filename)
{
return delete_file(filename)==0 ? 0: -1;
}
 
#ifndef _REENT_ONLY
 
int
_DEFUN(remove, (filename),
_CONST char *filename)
{
 
return delete_file(filename)==0 ? 0: -1;
 
}
 
#endif
/programs/develop/libraries/newlib/stdio/rename.c
0,0 → 1,80
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<rename>>---rename a file
 
INDEX
rename
 
ANSI_SYNOPSIS
#include <stdio.h>
int rename(const char *<[old]>, const char *<[new]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
int rename(<[old]>, <[new]>)
char *<[old]>;
char *<[new]>;
 
DESCRIPTION
Use <<rename>> to establish a new name (the string at <[new]>) for a
file now known by the string at <[old]>. After a successful
<<rename>>, the file is no longer accessible by the string at <[old]>.
 
If <<rename>> fails, the file named <<*<[old]>>> is unaffected. The
conditions for failure depend on the host operating system.
 
RETURNS
The result is either <<0>> (when successful) or <<-1>> (when the file
could not be renamed).
 
PORTABILITY
ANSI C requires <<rename>>, but only specifies that the result on
failure be nonzero. The effects of using the name of an existing file
as <<*<[new]>>> may vary from one implementation to another.
 
Supporting OS subroutines required: <<link>>, <<unlink>>, or <<rename>>.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <sys/unistd.h>
 
int
_DEFUN (_rename_r, (ptr, old, new),
struct _reent *ptr _AND
_CONST char *old _AND
_CONST char *new)
{
return -1;
}
 
 
#ifndef _REENT_ONLY
 
int
_DEFUN(rename, (old, new),
_CONST char *old _AND
_CONST char *new)
{
return -1;
}
 
#endif
/programs/develop/libraries/newlib/stdio/rget.c
0,0 → 1,59
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* No user fns here. Pesch 15apr92. */
 
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
 
#include <_ansi.h>
#include <stdio.h>
#include <errno.h>
#include "local.h"
 
/*
* Handle getc() when the buffer ran out:
* Refill, then return the first character
* in the newly-filled buffer.
*/
 
int
_DEFUN(__srget_r, (ptr, fp),
struct _reent *ptr _AND
register FILE *fp)
{
/* Ensure that any fake std stream is resolved before
we call __srefill_r so we may access the true read buffer. */
CHECK_INIT(ptr, fp);
 
if (__srefill_r (ptr, fp) == 0)
{
fp->_r--;
return *fp->_p++;
}
return EOF;
}
 
/* This function isn't any longer declared in stdio.h, but it's
required for backward compatibility with applications built against
earlier dynamically built newlib libraries. */
int
_DEFUN(__srget, (fp),
register FILE *fp)
{
return __srget_r (_REENT, fp);
}
/programs/develop/libraries/newlib/stdio/setvbuf.c
0,0 → 1,198
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<setvbuf>>---specify file or stream buffering
 
INDEX
setvbuf
 
ANSI_SYNOPSIS
#include <stdio.h>
int setvbuf(FILE *<[fp]>, char *<[buf]>,
int <[mode]>, size_t <[size]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
int setvbuf(<[fp]>, <[buf]>, <[mode]>, <[size]>)
FILE *<[fp]>;
char *<[buf]>;
int <[mode]>;
size_t <[size]>;
 
DESCRIPTION
Use <<setvbuf>> to specify what kind of buffering you want for the
file or stream identified by <[fp]>, by using one of the following
values (from <<stdio.h>>) as the <[mode]> argument:
 
o+
o _IONBF
Do not use a buffer: send output directly to the host system for the
file or stream identified by <[fp]>.
 
o _IOFBF
Use full output buffering: output will be passed on to the host system
only when the buffer is full, or when an input operation intervenes.
 
o _IOLBF
Use line buffering: pass on output to the host system at every
newline, as well as when the buffer is full, or when an input
operation intervenes.
o-
 
Use the <[size]> argument to specify how large a buffer you wish. You
can supply the buffer itself, if you wish, by passing a pointer to a
suitable area of memory as <[buf]>. Otherwise, you may pass <<NULL>>
as the <[buf]> argument, and <<setvbuf>> will allocate the buffer.
 
WARNINGS
You may only use <<setvbuf>> before performing any file operation other
than opening the file.
 
If you supply a non-null <[buf]>, you must ensure that the associated
storage continues to be available until you close the stream
identified by <[fp]>.
 
RETURNS
A <<0>> result indicates success, <<EOF>> failure (invalid <[mode]> or
<[size]> can cause failure).
 
PORTABILITY
Both ANSI C and the System V Interface Definition (Issue 2) require
<<setvbuf>>. However, they differ on the meaning of a <<NULL>> buffer
pointer: the SVID issue 2 specification says that a <<NULL>> buffer
pointer requests unbuffered output. For maximum portability, avoid
<<NULL>> buffer pointers.
 
Both specifications describe the result on failure only as a
nonzero value.
 
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
 
#include <_ansi.h>
#include <stdio.h>
#include <stdlib.h>
#include "local.h"
 
/*
* Set one of the three kinds of buffering, optionally including a buffer.
*/
 
int
_DEFUN(setvbuf, (fp, buf, mode, size),
register FILE * fp _AND
char *buf _AND
register int mode _AND
register size_t size)
{
int ret = 0;
 
CHECK_INIT (_REENT, fp);
 
_flockfile (fp);
 
/*
* Verify arguments. The `int' limit on `size' is due to this
* particular implementation.
*/
 
if ((mode != _IOFBF && mode != _IOLBF && mode != _IONBF) || (int)(_POINTER_INT) size < 0)
{
_funlockfile (fp);
return (EOF);
}
 
/*
* Write current buffer, if any; drop read count, if any.
* Make sure putc() will not think fp is line buffered.
* Free old buffer if it was from malloc(). Clear line and
* non buffer flags, and clear malloc flag.
*/
 
_fflush_r (_REENT, fp);
fp->_r = 0;
fp->_lbfsize = 0;
if (fp->_flags & __SMBF)
_free_r (_REENT, (_PTR) fp->_bf._base);
fp->_flags &= ~(__SLBF | __SNBF | __SMBF);
 
if (mode == _IONBF)
goto nbf;
 
/*
* Allocate buffer if needed. */
if (buf == NULL)
{
/* we need this here because malloc() may return a pointer
even if size == 0 */
if (!size) size = BUFSIZ;
if ((buf = malloc (size)) == NULL)
{
ret = EOF;
/* Try another size... */
buf = malloc (BUFSIZ);
size = BUFSIZ;
}
if (buf == NULL)
{
/* Can't allocate it, let's try another approach */
nbf:
fp->_flags |= __SNBF;
fp->_w = 0;
fp->_bf._base = fp->_p = fp->_nbuf;
fp->_bf._size = 1;
_funlockfile (fp);
return (ret);
}
fp->_flags |= __SMBF;
}
/*
* Now put back whichever flag is needed, and fix _lbfsize
* if line buffered. Ensure output flush on exit if the
* stream will be buffered at all.
* If buf is NULL then make _lbfsize 0 to force the buffer
* to be flushed and hence malloced on first use
*/
 
switch (mode)
{
case _IOLBF:
fp->_flags |= __SLBF;
fp->_lbfsize = buf ? -size : 0;
/* FALLTHROUGH */
 
case _IOFBF:
/* no flag */
_REENT->__cleanup = _cleanup_r;
fp->_bf._base = fp->_p = (unsigned char *) buf;
fp->_bf._size = size;
break;
}
 
/*
* Patch up write count if necessary.
*/
 
if (fp->_flags & __SWR)
fp->_w = fp->_flags & (__SLBF | __SNBF) ? 0 : size;
 
_funlockfile (fp);
return 0;
}
/programs/develop/libraries/newlib/stdio/tmpfile.c
0,0 → 1,96
/*
FUNCTION
<<tmpfile>>---create a temporary file
 
INDEX
tmpfile
INDEX
_tmpfile_r
 
ANSI_SYNOPSIS
#include <stdio.h>
FILE *tmpfile(void);
 
FILE *_tmpfile_r(struct _reent *<[reent]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
FILE *tmpfile();
 
FILE *_tmpfile_r(<[reent]>)
struct _reent *<[reent]>;
 
DESCRIPTION
Create a temporary file (a file which will be deleted automatically),
using a name generated by <<tmpnam>>. The temporary file is opened with
the mode <<"wb+">>, permitting you to read and write anywhere in it
as a binary file (without any data transformations the host system may
perform for text files).
 
The alternate function <<_tmpfile_r>> is a reentrant version. The
argument <[reent]> is a pointer to a reentrancy structure.
 
RETURNS
<<tmpfile>> normally returns a pointer to the temporary file. If no
temporary file could be created, the result is NULL, and <<errno>>
records the reason for failure.
 
PORTABILITY
Both ANSI C and the System V Interface Definition (Issue 2) require
<<tmpfile>>.
 
Supporting OS subroutines required: <<close>>, <<fstat>>, <<getpid>>,
<<isatty>>, <<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>.
 
<<tmpfile>> also requires the global pointer <<environ>>.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
 
#ifndef O_BINARY
# define O_BINARY 0
#endif
 
FILE *
_DEFUN(_tmpfile_r, (ptr),
struct _reent *ptr)
{
FILE *fp;
int e;
char *f;
char buf[L_tmpnam];
int fd;
 
do
{
if ((f = _tmpnam_r (ptr, buf)) == NULL)
return NULL;
fd = _open_r (ptr, f, O_RDWR | O_CREAT | O_EXCL | O_BINARY,
S_IRUSR | S_IWUSR);
}
while (fd < 0 && ptr->_errno == EEXIST);
if (fd < 0)
return NULL;
fp = _fdopen_r (ptr, fd, "wb+");
e = ptr->_errno;
if (!fp)
_close_r (ptr, fd);
_CAST_VOID _remove_r (ptr, f);
ptr->_errno = e;
return fp;
}
 
#ifndef _REENT_ONLY
 
FILE *
_DEFUN_VOID(tmpfile)
{
return _tmpfile_r (_REENT);
}
 
#endif
/programs/develop/libraries/newlib/stdio/tmpnam.c
0,0 → 1,209
/*
* tmpname.c
* Original Author: G. Haley
*/
/*
FUNCTION
<<tmpnam>>, <<tempnam>>---name for a temporary file
 
INDEX
tmpnam
INDEX
tempnam
INDEX
_tmpnam_r
INDEX
_tempnam_r
 
ANSI_SYNOPSIS
#include <stdio.h>
char *tmpnam(char *<[s]>);
char *tempnam(char *<[dir]>, char *<[pfx]>);
char *_tmpnam_r(struct _reent *<[reent]>, char *<[s]>);
char *_tempnam_r(struct _reent *<[reent]>, char *<[dir]>, char *<[pfx]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
char *tmpnam(<[s]>)
char *<[s]>;
 
char *tempnam(<[dir]>, <[pfx]>)
char *<[dir]>;
char *<[pfx]>;
 
char *_tmpnam_r(<[reent]>, <[s]>)
struct _reent *<[reent]>;
char *<[s]>;
 
char *_tempnam_r(<[reent]>, <[dir]>, <[pfx]>)
struct *<[reent]>;
char *<[dir]>;
char *<[pfx]>;
 
DESCRIPTION
Use either of these functions to generate a name for a temporary file.
The generated name is guaranteed to avoid collision with other files
(for up to <<TMP_MAX>> calls of either function).
 
<<tmpnam>> generates file names with the value of <<P_tmpdir>>
(defined in `<<stdio.h>>') as the leading directory component of the path.
 
You can use the <<tmpnam>> argument <[s]> to specify a suitable area
of memory for the generated filename; otherwise, you can call
<<tmpnam(NULL)>> to use an internal static buffer.
 
<<tempnam>> allows you more control over the generated filename: you
can use the argument <[dir]> to specify the path to a directory for
temporary files, and you can use the argument <[pfx]> to specify a
prefix for the base filename.
 
If <[dir]> is <<NULL>>, <<tempnam>> will attempt to use the value of
environment variable <<TMPDIR>> instead; if there is no such value,
<<tempnam>> uses the value of <<P_tmpdir>> (defined in `<<stdio.h>>').
 
If you don't need any particular prefix to the basename of temporary
files, you can pass <<NULL>> as the <[pfx]> argument to <<tempnam>>.
 
<<_tmpnam_r>> and <<_tempnam_r>> are reentrant versions of <<tmpnam>>
and <<tempnam>> respectively. The extra argument <[reent]> is a
pointer to a reentrancy structure.
 
WARNINGS
The generated filenames are suitable for temporary files, but do not
in themselves make files temporary. Files with these names must still
be explicitly removed when you no longer want them.
 
If you supply your own data area <[s]> for <<tmpnam>>, you must ensure
that it has room for at least <<L_tmpnam>> elements of type <<char>>.
 
RETURNS
Both <<tmpnam>> and <<tempnam>> return a pointer to the newly
generated filename.
 
PORTABILITY
ANSI C requires <<tmpnam>>, but does not specify the use of
<<P_tmpdir>>. The System V Interface Definition (Issue 2) requires
both <<tmpnam>> and <<tempnam>>.
 
Supporting OS subroutines required: <<close>>, <<fstat>>, <<getpid>>,
<<isatty>>, <<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>.
 
The global pointer <<environ>> is also required.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <reent.h>
#include <errno.h>
 
/* Try to open the file specified, if it can't be opened then try
another one. Return nonzero if successful, otherwise zero. */
 
static int
_DEFUN(worker, (ptr, result, part1, part2, part3, part4),
struct _reent *ptr _AND
char *result _AND
_CONST char *part1 _AND
_CONST char *part2 _AND
int part3 _AND
int *part4)
{
/* Generate the filename and make sure that there isn't one called
it already. */
 
while (1)
{
int t;
_sprintf_r (ptr, result, "%s/%s%x.%x", part1, part2, part3, *part4);
(*part4)++;
t = _open_r (ptr, result, O_RDONLY, 0);
if (t == -1)
{
if (ptr->_errno == ENOSYS)
{
result[0] = '\0';
return 0;
}
break;
}
_close_r (ptr, t);
}
return 1;
}
 
char *
_DEFUN(_tmpnam_r, (p, s),
struct _reent *p _AND
char *s)
{
char *result;
int pid;
 
if (s == NULL)
{
/* ANSI states we must use an internal static buffer if s is NULL */
_REENT_CHECK_EMERGENCY(p);
result = _REENT_EMERGENCY(p);
}
else
{
result = s;
}
pid = _getpid_r (p);
 
if (worker (p, result, P_tmpdir, "t", pid, &p->_inc))
{
p->_inc++;
return result;
}
 
return NULL;
}
 
char *
_DEFUN(_tempnam_r, (p, dir, pfx),
struct _reent *p _AND
_CONST char *dir _AND
_CONST char *pfx)
{
char *filename;
int length;
_CONST char *prefix = (pfx) ? pfx : "";
if (dir == NULL && (dir = getenv ("TMPDIR")) == NULL)
dir = P_tmpdir;
 
/* two 8 digit numbers + . / */
length = strlen (dir) + strlen (prefix) + (4 * sizeof (int)) + 2 + 1;
 
filename = _malloc_r (p, length);
if (filename)
{
if (! worker (p, filename, dir, prefix,
_getpid_r (p) ^ (int) (_POINTER_INT) p, &p->_inc))
return NULL;
}
return filename;
}
 
#ifndef _REENT_ONLY
 
char *
_DEFUN(tempnam, (dir, pfx),
_CONST char *dir _AND
_CONST char *pfx)
{
return _tempnam_r (_REENT, dir, pfx);
}
 
char *
_DEFUN(tmpnam, (s),
char *s)
{
return _tmpnam_r (_REENT, s);
}
 
#endif
/programs/develop/libraries/newlib/stdio/vscanf.c
0,0 → 1,52
/*-
* Code created by modifying scanf.c which has following copyright.
*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "local.h"
 
#ifndef _REENT_ONLY
 
int
_DEFUN(vscanf, (fmt, ap),
_CONST char *fmt _AND
va_list ap)
{
_REENT_SMALL_CHECK_INIT (_REENT);
return __svfscanf_r (_REENT, _stdin_r (_REENT), fmt, ap);
}
 
#endif /* !_REENT_ONLY */
 
int
_DEFUN(_vscanf_r, (ptr, fmt, ap),
struct _reent *ptr _AND
_CONST char *fmt _AND
va_list ap)
{
_REENT_SMALL_CHECK_INIT (ptr);
return __svfscanf_r (ptr, _stdin_r (ptr), fmt, ap);
}
 
/programs/develop/libraries/newlib/stdio/vsscanf.c
0,0 → 1,65
/*
* Code created by modifying scanf.c which has following copyright.
*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <string.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "local.h"
 
/*
* vsscanf
*/
 
#ifndef _REENT_ONLY
 
int
_DEFUN(vsscanf, (str, fmt, ap),
_CONST char *str _AND
_CONST char *fmt _AND
va_list ap)
{
return _vsscanf_r (_REENT, str, fmt, ap);
}
 
#endif /* !_REENT_ONLY */
 
int
_DEFUN(_vsscanf_r, (ptr, str, fmt, ap),
struct _reent *ptr _AND
_CONST char *str _AND
_CONST char *fmt _AND
va_list ap)
{
FILE f;
 
f._flags = __SRD | __SSTR;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._r = strlen (str);
f._read = __seofread;
f._ub._base = NULL;
f._lb._base = NULL;
f._file = -1; /* No file. */
return __ssvfscanf_r (ptr, &f, fmt, ap);
}
/programs/develop/libraries/newlib/stdlib/mallocr1.c
File deleted
/programs/develop/libraries/newlib/stdlib/__atexit.c
0,0 → 1,99
/*
* Common routine to implement atexit-like functionality.
*/
 
#include <stddef.h>
#include <stdlib.h>
#include <reent.h>
#include <sys/lock.h>
#include "atexit.h"
 
/* Make this a weak reference to avoid pulling in malloc. */
void * malloc(size_t) _ATTRIBUTE((__weak__));
__LOCK_INIT_RECURSIVE(, __atexit_lock);
 
/*
* Register a function to be performed at exit or on shared library unload.
*/
 
int
_DEFUN (__register_exitproc,
(type, fn, arg, d),
int type _AND
void (*fn) (void) _AND
void *arg _AND
void *d)
{
struct _on_exit_args * args;
register struct _atexit *p;
 
#ifndef __SINGLE_THREAD__
__lock_acquire_recursive(__atexit_lock);
#endif
 
p = _GLOBAL_REENT->_atexit;
if (p == NULL)
_GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0;
if (p->_ind >= _ATEXIT_SIZE)
{
#ifndef _ATEXIT_DYNAMIC_ALLOC
return -1;
#else
/* Don't dynamically allocate the atexit array if malloc is not
available. */
if (!malloc)
return -1;
 
p = (struct _atexit *) malloc (sizeof *p);
if (p == NULL)
{
#ifndef __SINGLE_THREAD__
__lock_release_recursive(__atexit_lock);
#endif
return -1;
}
p->_ind = 0;
p->_next = _GLOBAL_REENT->_atexit;
_GLOBAL_REENT->_atexit = p;
#ifndef _REENT_SMALL
p->_on_exit_args._fntypes = 0;
p->_on_exit_args._is_cxa = 0;
#endif
#endif
}
 
if (type != __et_atexit)
{
#ifdef _REENT_SMALL
args = p->_on_exit_args_ptr;
if (args == NULL)
{
if (malloc)
args = malloc (sizeof * p->_on_exit_args_ptr);
 
if (args == NULL)
{
#ifndef __SINGLE_THREAD__
__lock_release(lock);
#endif
return -1;
}
args->_fntypes = 0;
args->_is_cxa = 0;
p->_on_exit_args_ptr = args;
}
#else
args = &p->_on_exit_args;
#endif
args->_fnargs[p->_ind] = arg;
args->_fntypes |= (1 << p->_ind);
args->_dso_handle[p->_ind] = d;
if (type == __et_cxa)
args->_is_cxa |= (1 << p->_ind);
}
p->_fns[p->_ind++] = fn;
#ifndef __SINGLE_THREAD__
__lock_release_recursive(__atexit_lock);
#endif
return 0;
}
/programs/develop/libraries/newlib/stdlib/__call_atexit.c
0,0 → 1,161
/*
* COmmon routine to call call registered atexit-like routines.
*/
 
 
#include <stdlib.h>
#include <reent.h>
#include <sys/lock.h>
#include "atexit.h"
 
/* Make this a weak reference to avoid pulling in free. */
void free(void *) _ATTRIBUTE((__weak__));
 
#ifndef __SINGLE_THREAD__
extern _LOCK_RECURSIVE_T __atexit_lock;
#endif
 
#ifdef _WANT_REGISTER_FINI
 
/* If "__libc_fini" is defined, finalizers (either
"__libc_fini_array", or "_fini", as appropriate) will be run after
all user-specified atexit handlers. For example, you can define
"__libc_fini" to "_fini" in your linker script if you want the C
library, rather than startup code, to register finalizers. If you
do that, then your startup code need not contain references to
"atexit" or "exit". As a result, only applications that reference
"exit" explicitly will pull in finalization code.
 
The choice of whether to register finalizers from libc or from
startup code is deferred to link-time, rather than being a
configure-time option, so that the same C library binary can be
used with multiple BSPs, some of which register finalizers from
startup code, while others defer to the C library. */
extern char __libc_fini __attribute__((weak));
 
/* Register the application finalization function with atexit. These
finalizers should run last. Therefore, we want to call atexit as
soon as possible. */
static void
register_fini(void) __attribute__((constructor (0)));
 
static void
register_fini(void)
{
if (&__libc_fini) {
#ifdef HAVE_INITFINI_ARRAY
extern void __libc_fini_array (void);
atexit (__libc_fini_array);
#else
extern void _fini (void);
atexit (_fini);
#endif
}
}
 
#endif /* _WANT_REGISTER_FINI */
 
/*
* Call registered exit handlers. If D is null then all handlers are called,
* otherwise only the handlers from that DSO are called.
*/
 
void
_DEFUN (__call_exitprocs, (code, d),
int code _AND _PTR d)
{
register struct _atexit *p;
struct _atexit **lastp;
register struct _on_exit_args * args;
register int n;
int i;
void (*fn) (void);
 
 
#ifndef __SINGLE_THREAD__
__lock_acquire_recursive(__atexit_lock);
#endif
 
restart:
 
p = _GLOBAL_REENT->_atexit;
lastp = &_GLOBAL_REENT->_atexit;
while (p)
{
#ifdef _REENT_SMALL
args = p->_on_exit_args_ptr;
#else
args = &p->_on_exit_args;
#endif
for (n = p->_ind - 1; n >= 0; n--)
{
int ind;
 
i = 1 << n;
 
/* Skip functions not from this dso. */
if (d && (!args || args->_dso_handle[n] != d))
continue;
 
/* Remove the function now to protect against the
function calling exit recursively. */
fn = p->_fns[n];
if (n == p->_ind - 1)
p->_ind--;
else
p->_fns[n] = NULL;
 
/* Skip functions that have already been called. */
if (!fn)
continue;
 
ind = p->_ind;
 
/* Call the function. */
if (!args || (args->_fntypes & i) == 0)
fn ();
else if ((args->_is_cxa & i) == 0)
(*((void (*)(int, _PTR)) fn))(code, args->_fnargs[n]);
else
(*((void (*)(_PTR)) fn))(args->_fnargs[n]);
 
/* The function we called call atexit and registered another
function (or functions). Call these new functions before
continuing with the already registered functions. */
if (ind != p->_ind || *lastp != p)
goto restart;
}
 
#ifndef _ATEXIT_DYNAMIC_ALLOC
break;
#else
/* Don't dynamically free the atexit array if free is not
available. */
if (!free)
break;
 
/* Move to the next block. Free empty blocks except the last one,
which is part of _GLOBAL_REENT. */
if (p->_ind == 0 && p->_next)
{
/* Remove empty block from the list. */
*lastp = p->_next;
#ifdef _REENT_SMALL
if (args)
free (args);
#endif
free (p);
p = *lastp;
}
else
{
lastp = &p->_next;
p = p->_next;
}
#endif
}
#ifndef __SINGLE_THREAD__
__lock_release_recursive(__atexit_lock);
#endif
 
}
/programs/develop/libraries/newlib/stdlib/atof.c
0,0 → 1,72
/*
FUNCTION
<<atof>>, <<atoff>>---string to double or float
 
INDEX
atof
INDEX
atoff
 
ANSI_SYNOPSIS
#include <stdlib.h>
double atof(const char *<[s]>);
float atoff(const char *<[s]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
double atof(<[s]>)
char *<[s]>;
 
float atoff(<[s]>)
char *<[s]>;
 
DESCRIPTION
<<atof>> converts the initial portion of a string to a <<double>>.
<<atoff>> converts the initial portion of a string to a <<float>>.
 
The functions parse the character string <[s]>,
locating a substring which can be converted to a floating-point
value. The substring must match the format:
. [+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>]
The substring converted is the longest initial
fragment of <[s]> that has the expected format, beginning with
the first non-whitespace character. The substring
is empty if <<str>> is empty, consists entirely
of whitespace, or if the first non-whitespace character is
something other than <<+>>, <<->>, <<.>>, or a digit.
 
<<atof(<[s]>)>> is implemented as <<strtod(<[s]>, NULL)>>.
<<atoff(<[s]>)>> is implemented as <<strtof(<[s]>, NULL)>>.
 
RETURNS
<<atof>> returns the converted substring value, if any, as a
<<double>>; or <<0.0>>, if no conversion could be performed.
If the correct value is out of the range of representable values, plus
or minus <<HUGE_VAL>> is returned, and <<ERANGE>> is stored in
<<errno>>.
If the correct value would cause underflow, <<0.0>> is returned
and <<ERANGE>> is stored in <<errno>>.
 
<<atoff>> obeys the same rules as <<atof>>, except that it
returns a <<float>>.
 
PORTABILITY
<<atof>> is ANSI C. <<atof>>, <<atoi>>, and <<atol>> are subsumed by <<strod>>
and <<strol>>, but are used extensively in existing code. These functions are
less reliable, but may be faster if the argument is verified to be in a valid
range.
 
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
 
 
#include <stdlib.h>
#include <_ansi.h>
 
double
_DEFUN (atof, (s),
_CONST char *s)
{
return strtod (s, NULL);
}
/programs/develop/libraries/newlib/stdlib/div.c
0,0 → 1,132
/*
FUNCTION
<<div>>---divide two integers
 
INDEX
div
 
ANSI_SYNOPSIS
#include <stdlib.h>
div_t div(int <[n]>, int <[d]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
div_t div(<[n]>, <[d]>)
int <[n]>, <[d]>;
 
DESCRIPTION
Divide
@tex
$n/d$,
@end tex
@ifnottex
<[n]>/<[d]>,
@end ifnottex
returning quotient and remainder as two integers in a structure <<div_t>>.
 
RETURNS
The result is represented with the structure
 
. typedef struct
. {
. int quot;
. int rem;
. } div_t;
 
where the <<quot>> field represents the quotient, and <<rem>> the
remainder. For nonzero <[d]>, if `<<<[r]> = div(<[n]>,<[d]>);>>' then
<[n]> equals `<<<[r]>.rem + <[d]>*<[r]>.quot>>'.
 
To divide <<long>> rather than <<int>> values, use the similar
function <<ldiv>>.
 
PORTABILITY
<<div>> is ANSI.
 
No supporting OS subroutines are required.
*/
 
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
 
#include <_ansi.h>
#include <stdlib.h> /* div_t */
 
div_t
_DEFUN (div, (num, denom),
int num _AND
int denom)
{
div_t r;
 
r.quot = num / denom;
r.rem = num % denom;
/*
* The ANSI standard says that |r.quot| <= |n/d|, where
* n/d is to be computed in infinite precision. In other
* words, we should always truncate the quotient towards
* 0, never -infinity or +infinity.
*
* Machine division and remainer may work either way when
* one or both of n or d is negative. If only one is
* negative and r.quot has been truncated towards -inf,
* r.rem will have the same sign as denom and the opposite
* sign of num; if both are negative and r.quot has been
* truncated towards -inf, r.rem will be positive (will
* have the opposite sign of num). These are considered
* `wrong'.
*
* If both are num and denom are positive, r will always
* be positive.
*
* This all boils down to:
* if num >= 0, but r.rem < 0, we got the wrong answer.
* In that case, to get the right answer, add 1 to r.quot and
* subtract denom from r.rem.
* if num < 0, but r.rem > 0, we also have the wrong answer.
* In this case, to get the right answer, subtract 1 from r.quot and
* add denom to r.rem.
*/
if (num >= 0 && r.rem < 0) {
++r.quot;
r.rem -= denom;
}
else if (num < 0 && r.rem > 0) {
--r.quot;
r.rem += denom;
}
return (r);
}
/programs/develop/libraries/newlib/stdlib/exit.c
0,0 → 1,66
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
*
* %sccs.include.redist.c%
*/
 
/*
FUNCTION
<<exit>>---end program execution
 
INDEX
exit
 
ANSI_SYNOPSIS
#include <stdlib.h>
void exit(int <[code]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
void exit(<[code]>)
int <[code]>;
 
DESCRIPTION
Use <<exit>> to return control from a program to the host operating
environment. Use the argument <[code]> to pass an exit status to the
operating environment: two particular values, <<EXIT_SUCCESS>> and
<<EXIT_FAILURE>>, are defined in `<<stdlib.h>>' to indicate success or
failure in a portable fashion.
 
<<exit>> does two kinds of cleanup before ending execution of your
program. First, it calls all application-defined cleanup functions
you have enrolled with <<atexit>>. Second, files and streams are
cleaned up: any pending output is delivered to the host system, each
open file or stream is closed, and files created by <<tmpfile>> are
deleted.
 
RETURNS
<<exit>> does not return to its caller.
 
PORTABILITY
ANSI C requires <<exit>>, and specifies that <<EXIT_SUCCESS>> and
<<EXIT_FAILURE>> must be defined.
 
Supporting OS subroutines required: <<_exit>>.
*/
 
#include <stdlib.h>
#include <unistd.h> /* for _exit() declaration */
#include <reent.h>
#include "atexit.h"
 
/*
* Exit, flushing stdio buffers if necessary.
*/
 
void
_DEFUN (exit, (code),
int code)
{
__call_exitprocs (code, NULL);
 
if (_GLOBAL_REENT->__cleanup)
(*_GLOBAL_REENT->__cleanup) (_GLOBAL_REENT);
_exit (code);
}
/programs/develop/libraries/newlib/stdlib/getenv.c
0,0 → 1,93
/*
FUNCTION
<<getenv>>---look up environment variable
 
INDEX
getenv
INDEX
environ
 
ANSI_SYNOPSIS
#include <stdlib.h>
char *getenv(const char *<[name]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
char *getenv(<[name]>)
char *<[name]>;
 
DESCRIPTION
<<getenv>> searches the list of environment variable names and values
(using the global pointer ``<<char **environ>>'') for a variable whose
name matches the string at <[name]>. If a variable name matches,
<<getenv>> returns a pointer to the associated value.
 
RETURNS
A pointer to the (string) value of the environment variable, or
<<NULL>> if there is no such environment variable.
 
PORTABILITY
<<getenv>> is ANSI, but the rules for properly forming names of environment
variables vary from one system to another.
 
<<getenv>> requires a global pointer <<environ>>.
*/
 
/*
* Copyright (c) 1987, 2000 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that: (1) source distributions retain this entire copyright
* notice and comment, and (2) distributions including binaries display
* the following acknowledgement: ``This product includes software
* developed by the University of California, Berkeley and its contributors''
* in the documentation or other materials provided with the distribution
* and in all advertising materials mentioning features or use of this
* software. Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
#ifndef _REENT_ONLY
 
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
 
/*
* _findenv --
* Returns pointer to value associated with name, if any, else NULL.
* Sets offset to be the offset of the name/value combination in the
* environmental array, for use by setenv(3) and unsetenv(3).
* Explicitly removes '=' in argument name.
*
* This routine *should* be a static; don't use it.
*/
 
char *
_DEFUN (_findenv, (name, offset),
register _CONST char *name _AND
int *offset)
{
return NULL; //_findenv_r (_REENT, name, offset);
}
 
/*
* getenv --
* Returns ptr to value associated with name, if any, else NULL.
*/
 
char *
_DEFUN (getenv, (name),
_CONST char *name)
{
int offset;
 
return NULL; //_findenv_r (_REENT, name, &offset);
}
 
#endif /* !_REENT_ONLY */
/programs/develop/libraries/newlib/stdlib/rand.c
0,0 → 1,91
/*
FUNCTION
<<rand>>, <<srand>>---pseudo-random numbers
 
INDEX
rand
INDEX
srand
INDEX
rand_r
 
ANSI_SYNOPSIS
#include <stdlib.h>
int rand(void);
void srand(unsigned int <[seed]>);
int rand_r(unsigned int *<[seed]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
int rand();
 
void srand(<[seed]>)
unsigned int <[seed]>;
 
void rand_r(<[seed]>)
unsigned int *<[seed]>;
 
 
DESCRIPTION
<<rand>> returns a different integer each time it is called; each
integer is chosen by an algorithm designed to be unpredictable, so
that you can use <<rand>> when you require a random number.
The algorithm depends on a static variable called the ``random seed'';
starting with a given value of the random seed always produces the
same sequence of numbers in successive calls to <<rand>>.
 
You can set the random seed using <<srand>>; it does nothing beyond
storing its argument in the static variable used by <<rand>>. You can
exploit this to make the pseudo-random sequence less predictable, if
you wish, by using some other unpredictable value (often the least
significant parts of a time-varying value) as the random seed before
beginning a sequence of calls to <<rand>>; or, if you wish to ensure
(for example, while debugging) that successive runs of your program
use the same ``random'' numbers, you can use <<srand>> to set the same
random seed at the outset.
 
RETURNS
<<rand>> returns the next pseudo-random integer in sequence; it is a
number between <<0>> and <<RAND_MAX>> (inclusive).
 
<<srand>> does not return a result.
 
NOTES
<<rand>> and <<srand>> are unsafe for multi-threaded applications.
<<rand_r>> is thread-safe and should be used instead.
 
 
PORTABILITY
<<rand>> is required by ANSI, but the algorithm for pseudo-random
number generation is not specified; therefore, even if you use
the same random seed, you cannot expect the same sequence of results
on two different systems.
 
<<rand>> requires no supporting OS subroutines.
*/
 
#ifndef _REENT_ONLY
 
#include <stdlib.h>
#include <reent.h>
 
void
_DEFUN (srand, (seed), unsigned int seed)
{
_REENT_CHECK_RAND48(_REENT);
_REENT_RAND_NEXT(_REENT) = seed;
}
 
int
_DEFUN_VOID (rand)
{
/* This multiplier was obtained from Knuth, D.E., "The Art of
Computer Programming," Vol 2, Seminumerical Algorithms, Third
Edition, Addison-Wesley, 1998, p. 106 (line 26) & p. 108 */
_REENT_CHECK_RAND48(_REENT);
_REENT_RAND_NEXT(_REENT) =
_REENT_RAND_NEXT(_REENT) * __extension__ 6364136223846793005LL + 1;
return (int)((_REENT_RAND_NEXT(_REENT) >> 32) & RAND_MAX);
}
 
#endif /* _REENT_ONLY */
/programs/develop/libraries/newlib/stdlib/rand48.c
0,0 → 1,179
/*
* Copyright (c) 1993 Martin Birgmeier
* All rights reserved.
*
* You may redistribute unmodified or modified versions of this source
* code provided that the above copyright notice and this and the
* following conditions are retained.
*
* This software is provided ``as is'', and comes with no warranties
* of any kind. I shall in no event be liable for anything that happens
* to anyone/anything when using this software.
*/
 
/*
FUNCTION
<<rand48>>, <<drand48>>, <<erand48>>, <<lrand48>>, <<nrand48>>, <<mrand48>>, <<jrand48>>, <<srand48>>, <<seed48>>, <<lcong48>>---pseudo-random number generators and initialization routines
 
INDEX
rand48
INDEX
drand48
INDEX
erand48
INDEX
lrand48
INDEX
nrand48
INDEX
mrand48
INDEX
jrand48
INDEX
srand48
INDEX
seed48
INDEX
lcong48
 
ANSI_SYNOPSIS
#include <stdlib.h>
double drand48(void);
double erand48(unsigned short <[xseed]>[3]);
long lrand48(void);
long nrand48(unsigned short <[xseed]>[3]);
long mrand48(void);
long jrand48(unsigned short <[xseed]>[3]);
void srand48(long <[seed]>);
unsigned short *seed48(unsigned short <[xseed]>[3]);
void lcong48(unsigned short <[p]>[7]);
 
TRAD_SYNOPSIS
#include <stdlib.h>
double drand48();
 
double erand48(<[xseed]>)
unsigned short <[xseed]>[3];
 
long lrand48();
 
long nrand48(<[xseed]>)
unsigned short <[xseed]>[3];
 
long mrand48();
 
long jrand48(<[xseed]>)
unsigned short <[xseed]>[3];
 
void srand48(<[seed]>)
long <[seed]>;
 
unsigned short *seed48(<[xseed]>)
unsigned short <[xseed]>[3];
 
void lcong48(<[p]>)
unsigned short <[p]>[7];
 
DESCRIPTION
The <<rand48>> family of functions generates pseudo-random numbers
using a linear congruential algorithm working on integers 48 bits in size.
The particular formula employed is
r(n+1) = (a * r(n) + c) mod m
where the default values are
for the multiplicand a = 0xfdeece66d = 25214903917 and
the addend c = 0xb = 11. The modulo is always fixed at m = 2 ** 48.
r(n) is called the seed of the random number generator.
 
For all the six generator routines described next, the first
computational step is to perform a single iteration of the algorithm.
 
<<drand48>> and <<erand48>>
return values of type double. The full 48 bits of r(n+1) are
loaded into the mantissa of the returned value, with the exponent set
such that the values produced lie in the interval [0.0, 1.0].
 
<<lrand48>> and <<nrand48>>
return values of type long in the range
[0, 2**31-1]. The high-order (31) bits of
r(n+1) are loaded into the lower bits of the returned value, with
the topmost (sign) bit set to zero.
 
<<mrand48>> and <<jrand48>>
return values of type long in the range
[-2**31, 2**31-1]. The high-order (32) bits of
r(n+1) are loaded into the returned value.
 
<<drand48>>, <<lrand48>>, and <<mrand48>>
use an internal buffer to store r(n). For these functions
the initial value of r(0) = 0x1234abcd330e = 20017429951246.
 
On the other hand, <<erand48>>, <<nrand48>>, and <<jrand48>>
use a user-supplied buffer to store the seed r(n),
which consists of an array of 3 shorts, where the zeroth member
holds the least significant bits.
 
All functions share the same multiplicand and addend.
 
<<srand48>> is used to initialize the internal buffer r(n) of
<<drand48>>, <<lrand48>>, and <<mrand48>>
such that the 32 bits of the seed value are copied into the upper 32 bits
of r(n), with the lower 16 bits of r(n) arbitrarily being set to 0x330e.
Additionally, the constant multiplicand and addend of the algorithm are
reset to the default values given above.
 
<<seed48>> also initializes the internal buffer r(n) of
<<drand48>>, <<lrand48>>, and <<mrand48>>,
but here all 48 bits of the seed can be specified in an array of 3 shorts,
where the zeroth member specifies the lowest bits. Again,
the constant multiplicand and addend of the algorithm are
reset to the default values given above.
<<seed48>> returns a pointer to an array of 3 shorts which contains
the old seed.
This array is statically allocated, thus its contents are lost after
each new call to <<seed48>>.
 
Finally, <<lcong48>> allows full control over the multiplicand and
addend used in <<drand48>>, <<erand48>>, <<lrand48>>, <<nrand48>>,
<<mrand48>>, and <<jrand48>>,
and the seed used in <<drand48>>, <<lrand48>>, and <<mrand48>>.
An array of 7 shorts is passed as parameter; the first three shorts are
used to initialize the seed; the second three are used to initialize the
multiplicand; and the last short is used to initialize the addend.
It is thus not possible to use values greater than 0xffff as the addend.
 
Note that all three methods of seeding the random number generator
always also set the multiplicand and addend for any of the six
generator calls.
 
For a more powerful random number generator, see <<random>>.
 
PORTABILITY
SUS requires these functions.
 
No supporting OS subroutines are required.
*/
 
#include "rand48.h"
 
void
_DEFUN (__dorand48, (r, xseed),
struct _reent *r _AND
unsigned short xseed[3])
{
unsigned long accu;
unsigned short temp[2];
 
_REENT_CHECK_RAND48(r);
accu = (unsigned long) __rand48_mult[0] * (unsigned long) xseed[0] +
(unsigned long) __rand48_add;
temp[0] = (unsigned short) accu; /* lower 16 bits */
accu >>= sizeof(unsigned short) * 8;
accu += (unsigned long) __rand48_mult[0] * (unsigned long) xseed[1] +
(unsigned long) __rand48_mult[1] * (unsigned long) xseed[0];
temp[1] = (unsigned short) accu; /* middle 16 bits */
accu >>= sizeof(unsigned short) * 8;
accu += __rand48_mult[0] * xseed[2] + __rand48_mult[1] * xseed[1] + __rand48_mult[2] * xseed[0];
xseed[0] = temp[0];
xseed[1] = temp[1];
xseed[2] = (unsigned short) accu;
}
/programs/develop/libraries/newlib/stdlib/rand_r.c
0,0 → 1,37
#include <stdlib.h>
 
/* Pseudo-random generator based on Minimal Standard by
Lewis, Goodman, and Miller in 1969.
I[j+1] = a*I[j] (mod m)
 
where a = 16807
m = 2147483647
 
Using Schrage's algorithm, a*I[j] (mod m) can be rewritten as:
a*(I[j] mod q) - r*{I[j]/q} if >= 0
a*(I[j] mod q) - r*{I[j]/q} + m otherwise
 
where: {} denotes integer division
q = {m/a} = 127773
r = m (mod a) = 2836
 
note that the seed value of 0 cannot be used in the calculation as
it results in 0 itself
*/
int
_DEFUN (rand_r, (seed), unsigned int *seed)
{
long k;
long s = (long)(*seed);
if (s == 0)
s = 0x12345987;
k = s / 127773;
s = 16807 * (s - k * 127773) - 2836 * k;
if (s < 0)
s += 2147483647;
(*seed) = (unsigned int)s;
return (int)(s & RAND_MAX);
}
/programs/develop/libraries/newlib/stdlib/seed48.c
0,0 → 1,44
/*
* Copyright (c) 1993 Martin Birgmeier
* All rights reserved.
*
* You may redistribute unmodified or modified versions of this source
* code provided that the above copyright notice and this and the
* following conditions are retained.
*
* This software is provided ``as is'', and comes with no warranties
* of any kind. I shall in no event be liable for anything that happens
* to anyone/anything when using this software.
*/
 
#include "rand48.h"
 
unsigned short *
_DEFUN (_seed48_r, (r, xseed),
struct _reent *r _AND
unsigned short xseed[3])
{
static unsigned short sseed[3];
 
_REENT_CHECK_RAND48(r);
sseed[0] = __rand48_seed[0];
sseed[1] = __rand48_seed[1];
sseed[2] = __rand48_seed[2];
__rand48_seed[0] = xseed[0];
__rand48_seed[1] = xseed[1];
__rand48_seed[2] = xseed[2];
__rand48_mult[0] = _RAND48_MULT_0;
__rand48_mult[1] = _RAND48_MULT_1;
__rand48_mult[2] = _RAND48_MULT_2;
__rand48_add = _RAND48_ADD;
return sseed;
}
 
#ifndef _REENT_ONLY
unsigned short *
_DEFUN (seed48, (xseed),
unsigned short xseed[3])
{
return _seed48_r (_REENT, xseed);
}
#endif /* !_REENT_ONLY */
/programs/develop/libraries/newlib/stdlib/srand48.c
0,0 → 1,38
/*
* Copyright (c) 1993 Martin Birgmeier
* All rights reserved.
*
* You may redistribute unmodified or modified versions of this source
* code provided that the above copyright notice and this and the
* following conditions are retained.
*
* This software is provided ``as is'', and comes with no warranties
* of any kind. I shall in no event be liable for anything that happens
* to anyone/anything when using this software.
*/
 
#include "rand48.h"
 
_VOID
_DEFUN (_srand48_r, (r, seed),
struct _reent *r _AND
long seed)
{
_REENT_CHECK_RAND48(r);
__rand48_seed[0] = _RAND48_SEED_0;
__rand48_seed[1] = (unsigned short) seed;
__rand48_seed[2] = (unsigned short) ((unsigned long)seed >> 16);
__rand48_mult[0] = _RAND48_MULT_0;
__rand48_mult[1] = _RAND48_MULT_1;
__rand48_mult[2] = _RAND48_MULT_2;
__rand48_add = _RAND48_ADD;
}
 
#ifndef _REENT_ONLY
_VOID
_DEFUN (srand48, (seed),
long seed)
{
_srand48_r (_REENT, seed);
}
#endif /* !_REENT_ONLY */
/programs/develop/libraries/newlib/stdlib/strtold.c
0,0 → 1,42
/*
(C) Copyright IBM Corp. 2009
 
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.
* Neither the name of IBM nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
 
THIS SOFTWARE IS PROVIDED BY THE 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 THE COPYRIGHT OWNER 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 <stdlib.h>
#include "local.h"
 
/* On platforms where long double is as wide as double. */
#ifdef _LDBL_EQ_DBL
long double
strtold (const char *s00, char **se)
{
return strtod(s00, se);
}
#endif /* _LDBL_EQ_DBL */
 
/programs/develop/libraries/newlib/stdlib/strtoll.c
0,0 → 1,138
/*
FUNCTION
<<strtoll>>---string to long long
 
INDEX
strtoll
INDEX
_strtoll_r
 
ANSI_SYNOPSIS
#include <stdlib.h>
long long strtoll(const char *<[s]>, char **<[ptr]>,int <[base]>);
 
long long _strtoll_r(void *<[reent]>,
const char *<[s]>, char **<[ptr]>,int <[base]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
long long strtoll (<[s]>, <[ptr]>, <[base]>)
const char *<[s]>;
char **<[ptr]>;
int <[base]>;
 
long long _strtoll_r (<[reent]>, <[s]>, <[ptr]>, <[base]>)
char *<[reent]>;
const char *<[s]>;
char **<[ptr]>;
int <[base]>;
 
DESCRIPTION
The function <<strtoll>> converts the string <<*<[s]>>> to
a <<long long>>. First, it breaks down the string into three parts:
leading whitespace, which is ignored; a subject string consisting
of characters resembling an integer in the radix specified by <[base]>;
and a trailing portion consisting of zero or more unparseable characters,
and always including the terminating null character. Then, it attempts
to convert the subject string into a <<long long>> and returns the
result.
 
If the value of <[base]> is 0, the subject string is expected to look
like a normal C integer constant: an optional sign, a possible `<<0x>>'
indicating a hexadecimal base, and a number. If <[base]> is between
2 and 36, the expected form of the subject is a sequence of letters
and digits representing an integer in the radix specified by <[base]>,
with an optional plus or minus sign. The letters <<a>>--<<z>> (or,
equivalently, <<A>>--<<Z>>) are used to signify values from 10 to 35;
only letters whose ascribed values are less than <[base]> are
permitted. If <[base]> is 16, a leading <<0x>> is permitted.
 
The subject sequence is the longest initial sequence of the input
string that has the expected form, starting with the first
non-whitespace character. If the string is empty or consists entirely
of whitespace, or if the first non-whitespace character is not a
permissible letter or digit, the subject string is empty.
 
If the subject string is acceptable, and the value of <[base]> is zero,
<<strtoll>> attempts to determine the radix from the input string. A
string with a leading <<0x>> is treated as a hexadecimal value; a string with
a leading 0 and no <<x>> is treated as octal; all other strings are
treated as decimal. If <[base]> is between 2 and 36, it is used as the
conversion radix, as described above. If the subject string begins with
a minus sign, the value is negated. Finally, a pointer to the first
character past the converted subject string is stored in <[ptr]>, if
<[ptr]> is not <<NULL>>.
 
If the subject string is empty (or not in acceptable form), no conversion
is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is
not <<NULL>>).
 
The alternate function <<_strtoll_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
 
RETURNS
<<strtoll>> returns the converted value, if any. If no conversion was
made, 0 is returned.
 
<<strtoll>> returns <<LONG_LONG_MAX>> or <<LONG_LONG_MIN>> if the magnitude of
the converted value is too large, and sets <<errno>> to <<ERANGE>>.
 
PORTABILITY
<<strtoll>> is ANSI.
 
No supporting OS subroutines are required.
*/
 
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
 
 
#include <_ansi.h>
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <reent.h>
 
#ifndef _REENT_ONLY
 
long long
_DEFUN (strtoll, (s, ptr, base),
_CONST char *s _AND
char **ptr _AND
int base)
{
return _strtoll_r (_REENT, s, ptr, base);
}
 
#endif
/programs/develop/libraries/newlib/stdlib/strtoll_r.c
0,0 → 1,140
/*
This code is based on strtoul.c which has the following copyright.
It is used to convert a string into a signed long long.
 
long long _strtoll_r (struct _reent *rptr, const char *s,
char **ptr, int base);
*/
 
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
 
#ifdef __GNUC__
 
#define _GNU_SOURCE
#include <_ansi.h>
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <reent.h>
 
/*
* Convert a string to a long long integer.
*
* Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
long long
_DEFUN (_strtoll_r, (rptr, nptr, endptr, base),
struct _reent *rptr _AND
_CONST char *nptr _AND
char **endptr _AND
int base)
{
register const unsigned char *s = (const unsigned char *)nptr;
register unsigned long long acc;
register int c;
register unsigned long long cutoff;
register int neg = 0, any, cutlim;
 
/*
* Skip white space and pick up leading +/- sign if any.
* If base is 0, allow 0x for hex and 0 for octal, else
* assume decimal; if base is already 16, allow 0x.
*/
do {
c = *s++;
} while (isspace(c));
if (c == '-') {
neg = 1;
c = *s++;
} else if (c == '+')
c = *s++;
if ((base == 0 || base == 16) &&
c == '0' && (*s == 'x' || *s == 'X')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
 
/*
* Compute the cutoff value between legal numbers and illegal
* numbers. That is the largest legal value, divided by the
* base. An input number that is greater than this value, if
* followed by a legal input character, is too big. One that
* is equal to this value may be valid or not; the limit
* between valid and invalid numbers is then based on the last
* digit. For instance, if the range for longs is
* [-2147483648..2147483647] and the input base is 10,
* cutoff will be set to 214748364 and cutlim to either
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
* a value > 214748364, or equal but the next digit is > 7 (or 8),
* the number is too big, and we will return a range error.
*
* Set any if any `digits' consumed; make it negative to indicate
* overflow.
*/
cutoff = neg ? -(unsigned long long)LONG_LONG_MIN : LONG_LONG_MAX;
cutlim = cutoff % (unsigned long long)base;
cutoff /= (unsigned long long)base;
for (acc = 0, any = 0;; c = *s++) {
if (isdigit(c))
c -= '0';
else if (isalpha(c))
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
any = -1;
else {
any = 1;
acc *= base;
acc += c;
}
}
if (any < 0) {
acc = neg ? LONG_LONG_MIN : LONG_LONG_MAX;
rptr->_errno = ERANGE;
} else if (neg)
acc = -acc;
if (endptr != 0)
*endptr = (char *) (any ? (char *)s - 1 : nptr);
return (acc);
}
 
#endif /* __GNUC__ */
/programs/develop/libraries/newlib/stdlib/strtoull.c
0,0 → 1,139
/*
FUNCTION
<<strtoull>>---string to unsigned long long
 
INDEX
strtoull
INDEX
_strtoull_r
 
ANSI_SYNOPSIS
#include <stdlib.h>
unsigned long long strtoull(const char *<[s]>, char **<[ptr]>,
int <[base]>);
 
unsigned long long _strtoull_r(void *<[reent]>, const char *<[s]>,
char **<[ptr]>, int <[base]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
unsigned long long strtoull(<[s]>, <[ptr]>, <[base]>)
char *<[s]>;
char **<[ptr]>;
int <[base]>;
 
unsigned long long _strtoull_r(<[reent]>, <[s]>, <[ptr]>, <[base]>)
char *<[reent]>;
char *<[s]>;
char **<[ptr]>;
int <[base]>;
 
DESCRIPTION
The function <<strtoull>> converts the string <<*<[s]>>> to
an <<unsigned long long>>. First, it breaks down the string into three parts:
leading whitespace, which is ignored; a subject string consisting
of the digits meaningful in the radix specified by <[base]>
(for example, <<0>> through <<7>> if the value of <[base]> is 8);
and a trailing portion consisting of one or more unparseable characters,
which always includes the terminating null character. Then, it attempts
to convert the subject string into an unsigned long long integer, and returns the
result.
 
If the value of <[base]> is zero, the subject string is expected to look
like a normal C integer constant (save that no optional sign is permitted):
a possible <<0x>> indicating hexadecimal radix, and a number.
If <[base]> is between 2 and 36, the expected form of the subject is a
sequence of digits (which may include letters, depending on the
base) representing an integer in the radix specified by <[base]>.
The letters <<a>>--<<z>> (or <<A>>--<<Z>>) are used as digits valued from
10 to 35. If <[base]> is 16, a leading <<0x>> is permitted.
 
The subject sequence is the longest initial sequence of the input
string that has the expected form, starting with the first
non-whitespace character. If the string is empty or consists entirely
of whitespace, or if the first non-whitespace character is not a
permissible digit, the subject string is empty.
 
If the subject string is acceptable, and the value of <[base]> is zero,
<<strtoull>> attempts to determine the radix from the input string. A
string with a leading <<0x>> is treated as a hexadecimal value; a string with
a leading <<0>> and no <<x>> is treated as octal; all other strings are
treated as decimal. If <[base]> is between 2 and 36, it is used as the
conversion radix, as described above. Finally, a pointer to the first
character past the converted subject string is stored in <[ptr]>, if
<[ptr]> is not <<NULL>>.
 
If the subject string is empty (that is, if <<*>><[s]> does not start
with a substring in acceptable form), no conversion
is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is
not <<NULL>>).
 
The alternate function <<_strtoull_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
 
 
RETURNS
<<strtoull>> returns the converted value, if any. If no conversion was
made, <<0>> is returned.
 
<<strtoull>> returns <<ULONG_LONG_MAX>> if the magnitude of the converted
value is too large, and sets <<errno>> to <<ERANGE>>.
 
PORTABILITY
<<strtoull>> is ANSI.
 
<<strtoull>> requires no supporting OS subroutines.
*/
 
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
 
#include <_ansi.h>
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <reent.h>
 
#ifndef _REENT_ONLY
 
unsigned long long
_DEFUN (strtoull, (s, ptr, base),
_CONST char *s _AND
char **ptr _AND
int base)
{
return _strtoull_r (_REENT, s, ptr, base);
}
 
#endif
/programs/develop/libraries/newlib/stdlib/strtoull_r.c
0,0 → 1,120
/*
This code is based on strtoul.c which has the following copyright.
It is used to convert a string into an unsigned long long.
long long _strtoull_r (struct _reent *rptr, const char *s,
char **ptr, int base);
 
*/
 
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
 
#ifdef __GNUC__
 
#define _GNU_SOURCE
#include <_ansi.h>
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <reent.h>
 
/*
* Convert a string to an unsigned long long integer.
*
* Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
unsigned long long
_DEFUN (_strtoull_r, (rptr, nptr, endptr, base),
struct _reent *rptr _AND
_CONST char *nptr _AND
char **endptr _AND
int base)
{
register const unsigned char *s = (const unsigned char *)nptr;
register unsigned long long acc;
register int c;
register unsigned long long cutoff;
register int neg = 0, any, cutlim;
 
/*
* See strtol for comments as to the logic used.
*/
do {
c = *s++;
} while (isspace(c));
if (c == '-') {
neg = 1;
c = *s++;
} else if (c == '+')
c = *s++;
if ((base == 0 || base == 16) &&
c == '0' && (*s == 'x' || *s == 'X')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
cutoff = (unsigned long long)ULONG_LONG_MAX / (unsigned long long)base;
cutlim = (unsigned long long)ULONG_LONG_MAX % (unsigned long long)base;
for (acc = 0, any = 0;; c = *s++) {
if (isdigit(c))
c -= '0';
else if (isalpha(c))
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
any = -1;
else {
any = 1;
acc *= base;
acc += c;
}
}
if (any < 0) {
acc = ULONG_LONG_MAX;
rptr->_errno = ERANGE;
} else if (neg)
acc = -acc;
if (endptr != 0)
*endptr = (char *) (any ? (char *)s - 1 : nptr);
return (acc);
}
 
#endif /* __GNUC__ */
/programs/develop/libraries/newlib/stdlib/system.c
0,0 → 1,85
/*
FUNCTION
<<system>>---execute command string
 
INDEX
system
INDEX
_system_r
 
ANSI_SYNOPSIS
#include <stdlib.h>
int system(char *<[s]>);
 
int _system_r(void *<[reent]>, char *<[s]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
int system(<[s]>)
char *<[s]>;
 
int _system_r(<[reent]>, <[s]>)
char *<[reent]>;
char *<[s]>;
 
DESCRIPTION
 
Use <<system>> to pass a command string <<*<[s]>>> to <</bin/sh>> on
your system, and wait for it to finish executing.
 
Use ``<<system(NULL)>>'' to test whether your system has <</bin/sh>>
available.
 
The alternate function <<_system_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
 
RETURNS
<<system(NULL)>> returns a non-zero value if <</bin/sh>> is available, and
<<0>> if it is not.
 
With a command argument, the result of <<system>> is the exit status
returned by <</bin/sh>>.
 
PORTABILITY
ANSI C requires <<system>>, but leaves the nature and effects of a
command processor undefined. ANSI C does, however, specify that
<<system(NULL)>> return zero or nonzero to report on the existence of
a command processor.
 
POSIX.2 requires <<system>>, and requires that it invoke a <<sh>>.
Where <<sh>> is found is left unspecified.
 
Supporting OS subroutines required: <<_exit>>, <<_execve>>, <<_fork_r>>,
<<_wait_r>>.
*/
 
#include <_ansi.h>
#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <_syslist.h>
#include <reent.h>
 
 
int
_DEFUN(_system_r, (ptr, s),
struct _reent *ptr _AND
_CONST char *s)
{
if (s == NULL)
return 0;
errno = ENOSYS;
return -1;
}
 
#ifndef _REENT_ONLY
 
int
_DEFUN(system, (s),
_CONST char *s)
{
return _system_r (_REENT, s);
}
 
#endif
/programs/develop/libraries/newlib/string/strcasestr.c
0,0 → 1,147
/*
FUNCTION
<<strcasestr>>---case-insensitive character string search
 
INDEX
strcasestr
 
ANSI_SYNOPSIS
#include <string.h>
char *strcasestr(const char *<[s]>, const char *<[find]>);
 
TRAD_SYNOPSIS
#include <string.h>
int strcasecmp(<[s]>, <[find]>)
char *<[s]>;
char *<[find]>;
 
DESCRIPTION
<<strcasestr>> searchs the string <[s]> for
the first occurrence of the sequence <[find]>. <<strcasestr>>
is identical to <<strstr>> except the search is
case-insensitive.
 
RETURNS
 
A pointer to the first case-insensitive occurrence of the sequence
<[find]> or <<NULL>> if no match was found.
 
PORTABILITY
<<strcasestr>> is in the Berkeley Software Distribution.
 
<<strcasestr>> requires no supporting OS subroutines. It uses
tolower() from elsewhere in this library.
 
QUICKREF
strcasestr
*/
 
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* The quadratic code is derived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* Linear algorithm Copyright (C) 2008 Eric Blake
* Permission to use, copy, modify, and distribute the linear portion of
* software is freely granted, provided that this notice is preserved.
*/
 
#include <sys/cdefs.h>
 
#include <ctype.h>
#include <string.h>
 
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
# define RETURN_TYPE char *
# define AVAILABLE(h, h_l, j, n_l) \
(!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \
&& ((h_l) = (j) + (n_l)))
# define CANON_ELEMENT(c) tolower (c)
# define CMP_FUNC strncasecmp
# include "str-two-way.h"
#endif
 
/*
* Find the first occurrence of find in s, ignore case.
*/
char *
strcasestr(s, find)
const char *s, *find;
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
 
/* Less code size, but quadratic performance in the worst case. */
char c, sc;
size_t len;
 
if ((c = *find++) != 0) {
c = tolower((unsigned char)c);
len = strlen(find);
do {
do {
if ((sc = *s++) == 0)
return (NULL);
} while ((char)tolower((unsigned char)sc) != c);
} while (strncasecmp(s, find, len) != 0);
s--;
}
return ((char *)s);
 
#else /* compilation for speed */
 
/* Larger code size, but guaranteed linear performance. */
const char *haystack = s;
const char *needle = find;
size_t needle_len; /* Length of NEEDLE. */
size_t haystack_len; /* Known minimum length of HAYSTACK. */
int ok = 1; /* True if NEEDLE is prefix of HAYSTACK. */
 
/* Determine length of NEEDLE, and in the process, make sure
HAYSTACK is at least as long (no point processing all of a long
NEEDLE if HAYSTACK is too short). */
while (*haystack && *needle)
ok &= (tolower ((unsigned char) *haystack++)
== tolower ((unsigned char) *needle++));
if (*needle)
return NULL;
if (ok)
return (char *) s;
needle_len = needle - find;
haystack = s + 1;
haystack_len = needle_len - 1;
 
/* Perform the search. */
if (needle_len < LONG_NEEDLE_THRESHOLD)
return two_way_short_needle ((const unsigned char *) haystack,
haystack_len,
(const unsigned char *) find, needle_len);
return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
(const unsigned char *) find, needle_len);
#endif /* compilation for speed */
}
/programs/develop/libraries/newlib/string/strcat.c
0,0 → 1,104
/*
FUNCTION
<<strcat>>---concatenate strings
 
INDEX
strcat
 
ANSI_SYNOPSIS
#include <string.h>
char *strcat(char *<[dst]>, const char *<[src]>);
 
TRAD_SYNOPSIS
#include <string.h>
char *strcat(<[dst]>, <[src]>)
char *<[dst]>;
char *<[src]>;
 
DESCRIPTION
<<strcat>> appends a copy of the string pointed to by <[src]>
(including the terminating null character) to the end of the
string pointed to by <[dst]>. The initial character of
<[src]> overwrites the null character at the end of <[dst]>.
 
RETURNS
This function returns the initial value of <[dst]>
 
PORTABILITY
<<strcat>> is ANSI C.
 
<<strcat>> requires no supporting OS subroutines.
 
QUICKREF
strcat ansi pure
*/
 
#include <string.h>
#include <limits.h>
 
/* Nonzero if X is aligned on a "long" boundary. */
#define ALIGNED(X) \
(((long)X & (sizeof (long) - 1)) == 0)
 
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
 
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
 
 
/*SUPPRESS 560*/
/*SUPPRESS 530*/
 
char *
_DEFUN (strcat, (s1, s2),
char *s1 _AND
_CONST char *s2)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *s = s1;
 
while (*s1)
s1++;
 
while (*s1++ = *s2++)
;
return s;
#else
char *s = s1;
 
 
/* Skip over the data in s1 as quickly as possible. */
if (ALIGNED (s1))
{
unsigned long *aligned_s1 = (unsigned long *)s1;
while (!DETECTNULL (*aligned_s1))
aligned_s1++;
 
s1 = (char *)aligned_s1;
}
 
while (*s1)
s1++;
 
/* s1 now points to the its trailing null character, we can
just use strcpy to do the work for us now.
 
?!? We might want to just include strcpy here.
Also, this will cause many more unaligned string copies because
s1 is much less likely to be aligned. I don't know if its worth
tweaking strcpy to handle this better. */
strcpy (s1, s2);
return s;
#endif /* not PREFER_SIZE_OVER_SPEED */
}
/programs/develop/libraries/newlib/string/strcoll.c
0,0 → 1,48
/*
FUNCTION
<<strcoll>>---locale-specific character string compare
INDEX
strcoll
 
ANSI_SYNOPSIS
#include <string.h>
int strcoll(const char *<[stra]>, const char * <[strb]>);
 
TRAD_SYNOPSIS
#include <string.h>
int strcoll(<[stra]>, <[strb]>)
char *<[stra]>;
char *<[strb]>;
 
DESCRIPTION
<<strcoll>> compares the string pointed to by <[stra]> to
the string pointed to by <[strb]>, using an interpretation
appropriate to the current <<LC_COLLATE>> state.
 
RETURNS
If the first string is greater than the second string,
<<strcoll>> returns a number greater than zero. If the two
strings are equivalent, <<strcoll>> returns zero. If the first
string is less than the second string, <<strcoll>> returns a
number less than zero.
 
PORTABILITY
<<strcoll>> is ANSI C.
 
<<strcoll>> requires no supporting OS subroutines.
 
QUICKREF
strcoll ansi pure
*/
 
#include <string.h>
 
int
_DEFUN (strcoll, (a, b),
_CONST char *a _AND
_CONST char *b)
 
{
return strcmp (a, b);
}
/programs/develop/libraries/newlib/string/strncat.c
0,0 → 1,114
/*
FUNCTION
<<strncat>>---concatenate strings
 
INDEX
strncat
 
ANSI_SYNOPSIS
#include <string.h>
char *strncat(char *<[dst]>, const char *<[src]>, size_t <[length]>);
 
TRAD_SYNOPSIS
#include <string.h>
char *strncat(<[dst]>, <[src]>, <[length]>)
char *<[dst]>;
char *<[src]>;
size_t <[length]>;
 
DESCRIPTION
<<strncat>> appends not more than <[length]> characters from
the string pointed to by <[src]> (including the terminating
null character) to the end of the string pointed to by
<[dst]>. The initial character of <[src]> overwrites the null
character at the end of <[dst]>. A terminating null character
is always appended to the result
 
WARNINGS
Note that a null is always appended, so that if the copy is
limited by the <[length]> argument, the number of characters
appended to <[dst]> is <<n + 1>>.
 
RETURNS
This function returns the initial value of <[dst]>
 
PORTABILITY
<<strncat>> is ANSI C.
 
<<strncat>> requires no supporting OS subroutines.
 
QUICKREF
strncat ansi pure
*/
 
#include <string.h>
#include <limits.h>
 
/* Nonzero if X is aligned on a "long" boundary. */
#define ALIGNED(X) \
(((long)X & (sizeof (long) - 1)) == 0)
 
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
 
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
 
char *
_DEFUN (strncat, (s1, s2, n),
char *s1 _AND
_CONST char *s2 _AND
size_t n)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *s = s1;
 
while (*s1)
s1++;
while (n-- != 0 && (*s1++ = *s2++))
{
if (n == 0)
*s1 = '\0';
}
 
return s;
#else
char *s = s1;
 
/* Skip over the data in s1 as quickly as possible. */
if (ALIGNED (s1))
{
unsigned long *aligned_s1 = (unsigned long *)s1;
while (!DETECTNULL (*aligned_s1))
aligned_s1++;
 
s1 = (char *)aligned_s1;
}
 
while (*s1)
s1++;
 
/* s1 now points to the its trailing null character, now copy
up to N bytes from S2 into S1 stopping if a NULL is encountered
in S2.
 
It is not safe to use strncpy here since it copies EXACTLY N
characters, NULL padding if necessary. */
while (n-- != 0 && (*s1++ = *s2++))
{
if (n == 0)
*s1 = '\0';
}
return s;
#endif /* not PREFER_SIZE_OVER_SPEED */
}
/programs/develop/libraries/newlib/string/strndup.c
0,0 → 1,16
#ifndef _REENT_ONLY
 
#include <_ansi.h>
#include <reent.h>
#include <stdlib.h>
#include <string.h>
 
char *
_DEFUN (strndup, (str, n),
_CONST char *str _AND
size_t n)
{
return _strndup_r (_REENT, str, n);
}
 
#endif /* !_REENT_ONLY */
/programs/develop/libraries/newlib/string/strndup_r.c
0,0 → 1,27
#include <reent.h>
#include <stdlib.h>
#include <string.h>
 
char *
_DEFUN (_strndup_r, (reent_ptr, str, n),
struct _reent *reent_ptr _AND
_CONST char *str _AND
size_t n)
{
_CONST char *ptr = str;
size_t len;
char *copy;
 
while (n-- > 0 && *ptr)
ptr++;
 
len = ptr - str;
 
copy = _malloc_r (reent_ptr, len + 1);
if (copy)
{
memcpy (copy, str, len);
copy[len] = '\0';
}
return copy;
}
/programs/develop/libraries/newlib/string/strpbrk.c
0,0 → 1,58
/*
FUNCTION
<<strpbrk>>---find characters in string
 
INDEX
strpbrk
 
ANSI_SYNOPSIS
#include <string.h>
char *strpbrk(const char *<[s1]>, const char *<[s2]>);
 
TRAD_SYNOPSIS
#include <string.h>
char *strpbrk(<[s1]>, <[s2]>)
char *<[s1]>;
char *<[s2]>;
 
DESCRIPTION
This function locates the first occurence in the string
pointed to by <[s1]> of any character in string pointed to by
<[s2]> (excluding the terminating null character).
 
RETURNS
<<strpbrk>> returns a pointer to the character found in <[s1]>, or a
null pointer if no character from <[s2]> occurs in <[s1]>.
 
PORTABILITY
<<strpbrk>> requires no supporting OS subroutines.
*/
 
#include <string.h>
 
char *
_DEFUN (strpbrk, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
_CONST char *c = s2;
if (!*s1)
return (char *) NULL;
 
while (*s1)
{
for (c = s2; *c; c++)
{
if (*s1 == *c)
break;
}
if (*c)
break;
s1++;
}
 
if (*c == '\0')
s1 = NULL;
 
return (char *) s1;
}
/programs/develop/libraries/newlib/string/strsep.c
0,0 → 1,19
/* BSD strsep function */
 
/* Copyright 2002, Red Hat Inc. */
 
/* undef STRICT_ANSI so that strsep prototype will be defined */
#undef __STRICT_ANSI__
#include <string.h>
#include <_ansi.h>
#include <reent.h>
 
extern char *__strtok_r (char *, const char *, char **, int);
 
char *
_DEFUN (strsep, (source_ptr, delim),
register char **source_ptr _AND
register const char *delim)
{
return __strtok_r (*source_ptr, delim, source_ptr, 0);
}
/programs/develop/libraries/newlib/string/strtok.c
0,0 → 1,101
/*
FUNCTION
<<strtok>>, <<strtok_r>>, <<strsep>>---get next token from a string
 
INDEX
strtok
 
INDEX
strtok_r
 
INDEX
strsep
 
ANSI_SYNOPSIS
#include <string.h>
char *strtok(char *<[source]>, const char *<[delimiters]>)
char *strtok_r(char *<[source]>, const char *<[delimiters]>,
char **<[lasts]>)
char *strsep(char **<[source_ptr]>, const char *<[delimiters]>)
 
TRAD_SYNOPSIS
#include <string.h>
char *strtok(<[source]>, <[delimiters]>)
char *<[source]>;
char *<[delimiters]>;
 
char *strtok_r(<[source]>, <[delimiters]>, <[lasts]>)
char *<[source]>;
char *<[delimiters]>;
char **<[lasts]>;
 
char *strsep(<[source_ptr]>, <[delimiters]>)
char **<[source_ptr]>;
char *<[delimiters]>;
 
DESCRIPTION
The <<strtok>> function is used to isolate sequential tokens in a
null-terminated string, <<*<[source]>>>. These tokens are delimited
in the string by at least one of the characters in <<*<[delimiters]>>>.
The first time that <<strtok>> is called, <<*<[source]>>> should be
specified; subsequent calls, wishing to obtain further tokens from
the same string, should pass a null pointer instead. The separator
string, <<*<[delimiters]>>>, must be supplied each time and may
change between calls.
 
The <<strtok>> function returns a pointer to the beginning of each
subsequent token in the string, after replacing the separator
character itself with a null character. When no more tokens remain,
a null pointer is returned.
 
The <<strtok_r>> function has the same behavior as <<strtok>>, except
a pointer to placeholder <<*<[lasts]>>> must be supplied by the caller.
 
The <<strsep>> function is similar in behavior to <<strtok>>, except
a pointer to the string pointer must be supplied <<<[source_ptr]>>> and
the function does not skip leading delimiters. When the string starts
with a delimiter, the delimiter is changed to the null character and
the empty string is returned. Like <<strtok_r>> and <<strtok>>, the
<<*<[source_ptr]>>> is updated to the next character following the
last delimiter found or NULL if the end of string is reached with
no more delimiters.
 
RETURNS
<<strtok>>, <<strtok_r>>, and <<strsep>> all return a pointer to the
next token, or <<NULL>> if no more tokens can be found. For
<<strsep>>, a token may be the empty string.
 
NOTES
<<strtok>> is unsafe for multi-threaded applications. <<strtok_r>>
and <<strsep>> are thread-safe and should be used instead.
 
PORTABILITY
<<strtok>> is ANSI C.
<<strtok_r>> is POSIX.
<<strsep>> is a BSD extension.
 
<<strtok>>, <<strtok_r>>, and <<strsep>> require no supporting OS subroutines.
 
QUICKREF
strtok ansi impure
*/
 
/* undef STRICT_ANSI so that strtok_r prototype will be defined */
#undef __STRICT_ANSI__
#include <string.h>
#include <_ansi.h>
#include <reent.h>
 
#ifndef _REENT_ONLY
 
extern char *__strtok_r (char *, const char *, char **, int);
 
char *
_DEFUN (strtok, (s, delim),
register char *s _AND
register const char *delim)
{
_REENT_CHECK_MISC(_REENT);
return __strtok_r (s, delim, &(_REENT_STRTOK_LAST(_REENT)), 1);
}
#endif
/programs/develop/libraries/newlib/string/strtok_r.c
0,0 → 1,99
/*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
 
#include <string.h>
 
char *
_DEFUN (__strtok_r, (s, delim, lasts, skip_leading_delim),
register char *s _AND
register const char *delim _AND
char **lasts _AND
int skip_leading_delim)
{
register char *spanp;
register int c, sc;
char *tok;
 
 
if (s == NULL && (s = *lasts) == NULL)
return (NULL);
 
/*
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
*/
cont:
c = *s++;
for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
if (c == sc) {
if (skip_leading_delim) {
goto cont;
}
else {
*lasts = s;
s[-1] = 0;
return (s - 1);
}
}
}
 
if (c == 0) { /* no non-delimiter characters */
*lasts = NULL;
return (NULL);
}
tok = s - 1;
 
/*
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
* Note that delim must have one NUL; we stop if we see that, too.
*/
for (;;) {
c = *s++;
spanp = (char *)delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*lasts = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
 
char *
_DEFUN (strtok_r, (s, delim, lasts),
register char *s _AND
register const char *delim _AND
char **lasts)
{
return __strtok_r (s, delim, lasts, 1);
}
/programs/develop/libraries/newlib/string/strupr.c
0,0 → 1,46
/*
FUNCTION
<<strupr>>---force string to uppercase
INDEX
strupr
 
ANSI_SYNOPSIS
#include <string.h>
char *strupr(char *<[a]>);
 
TRAD_SYNOPSIS
#include <string.h>
char *strupr(<[a]>)
char *<[a]>;
 
DESCRIPTION
<<strupr>> converts each character in the string at <[a]> to
uppercase.
 
RETURNS
<<strupr>> returns its argument, <[a]>.
 
PORTABILITY
<<strupr>> is not widely portable.
 
<<strupr>> requires no supporting OS subroutines.
 
QUICKREF
strupr
*/
 
#include <string.h>
#include <ctype.h>
 
char *
_DEFUN (strupr, (s),
char *s)
{
unsigned char *ucs = (unsigned char *) s;
for ( ; *ucs != '\0'; ucs++)
{
*ucs = toupper(*ucs);
}
return s;
}
/programs/develop/libraries/newlib/sys/create.c
0,0 → 1,25
 
#include <sys/types.h>
#include <sys/kos_io.h>
 
int create_file(const char *path)
{
int retval;
__asm__ __volatile__ (
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %0, 1(%%esp) \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $2 \n\t"
"movl %%esp, %%ebx \n\t"
"movl $70, %%eax \n\t"
"int $0x40 \n\t"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"r" (path)
:"ebx");
return retval;
};
/programs/develop/libraries/newlib/sys/delete.c
0,0 → 1,26
 
#include <sys/types.h>
#include <sys/kos_io.h>
 
int delete_file(const char *path)
{
int retval;
__asm__ __volatile__ (
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %0, 1(%%esp) \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $8 \n\t"
"movl %%esp, %%ebx \n\t"
"movl $70, %%eax \n\t"
"int $0x40 \n\t"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"r" (path)
:"ebx");
return retval;
};
 
/programs/develop/libraries/newlib/sys/finfo.c
0,0 → 1,26
 
#include <sys/types.h>
#include <sys/kos_io.h>
 
int get_fileinfo(const char *path, fileinfo_t *info)
{
int retval;
 
__asm__ __volatile__ (
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %1, 1(%%esp) \n\t"
"pushl %%ebx \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $5 \n\t"
"movl %%esp, %%ebx \n\t"
"movl $70, %%eax \n\t"
"int $0x40 \n\t"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"r" (path), "b" (info));
return retval;
};
 
/programs/develop/libraries/newlib/sys/fload.c
0,0 → 1,37
 
#include <sys/types.h>
#include <stdint.h>
#include <sys/kos_io.h>
 
void *load_file(const char *path, size_t *len)
{
fileinfo_t info;
size_t bytes;
void *file = NULL;
 
if( len) *len = 0;
 
 
if( !get_fileinfo(path, &info) )
{
 
file = user_alloc( info.size );
read_file(path, file, 0, info.size, &bytes );
if( bytes == info.size )
{
if ( *(uint32_t*)file == 0x4B43504B )
{
void *tmp = NULL;
info.size = ((size_t*)file)[1];
tmp = user_alloc(info.size);
unpack(file, tmp);
user_free(file);
file = tmp;
}
if(len) *len = info.size;
};
};
return file;
};
 
 
/programs/develop/libraries/newlib/sys/fsize.c
0,0 → 1,26
 
#include <sys/types.h>
#include <sys/kos_io.h>
 
 
int set_file_size(const char *path, unsigned size)
{
int retval;
__asm__ __volatile__(
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %%eax, 1(%%esp) \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl %%ebx \n\t"
"push $4 \n\t"
"movl %%esp, %%ebx \n\t"
"movl $70, %%eax \n\t"
"int $0x40 \n\t"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"a" (path), "b" (size));
return retval;
};
 
/programs/develop/libraries/newlib/sys/read.c
0,0 → 1,31
 
#include <sys/types.h>
#include <sys/kos_io.h>
 
int read_file(const char *path, void *buff,
size_t offset, size_t count, size_t *reads)
{
int retval;
int d0;
__asm__ __volatile__(
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %%eax, 1(%%esp) \n\t"
"pushl %%ebx \n\t"
"pushl %%edx \n\t"
"pushl $0 \n\t"
"pushl %%ecx \n\t"
"pushl $0 \n\t"
"movl %%esp, %%ebx \n\t"
"mov $70, %%eax \n\t"
"int $0x40 \n\t"
"testl %%esi, %%esi \n\t"
"jz 1f \n\t"
"movl %%ebx, (%%esi) \n\t"
"1:"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"a"(path),"b"(buff),"c"(offset),"d"(count),"S"(reads));
return retval;
};
 
/programs/develop/libraries/newlib/sys/write.c
0,0 → 1,29
 
#include <sys/types.h>
#include <sys/kos_io.h>
 
int write_file(const char *path,const void *buff,
size_t offset, size_t count, size_t *writes)
{
int retval;
__asm__ __volatile__(
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %%eax, 1(%%esp) \n\t"
"pushl %%ebx \n\t"
"pushl %%edx \n\t"
"pushl $0 \n\t"
"pushl %%ecx \n\t"
"pushl $3 \n\t"
"movl %%esp, %%ebx \n\t"
"mov $70, %%eax \n\t"
"int $0x40 \n\t"
"testl %%esi, %%esi \n\t"
"jz 1f \n\t"
"movl %%ebx, (%%esi) \n\t"
"1:"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"a"(path),"b"(buff),"c"(offset),"d"(count),"S"(writes));
return retval;
};
/programs/develop/libraries/newlib/sys
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property
/programs/develop/libraries/newlib/time/asctime.c
0,0 → 1,64
/*
* asctime.c
* Original Author: G. Haley
*
* Converts the broken down time in the structure pointed to by tim_p into a
* string of the form
*
* Wed Jun 15 11:38:07 1988\n\0
*
* Returns a pointer to the string.
*/
 
/*
FUNCTION
<<asctime>>---format time as string
 
INDEX
asctime
INDEX
_asctime_r
 
ANSI_SYNOPSIS
#include <time.h>
char *asctime(const struct tm *<[clock]>);
char *_asctime_r(const struct tm *<[clock]>, char *<[buf]>);
 
TRAD_SYNOPSIS
#include <time.h>
char *asctime(<[clock]>)
struct tm *<[clock]>;
char *asctime_r(<[clock]>)
struct tm *<[clock]>;
char *<[buf]>;
 
DESCRIPTION
Format the time value at <[clock]> into a string of the form
. Wed Jun 15 11:38:07 1988\n\0
The string is generated in a static buffer; each call to <<asctime>>
overwrites the string generated by previous calls.
 
RETURNS
A pointer to the string containing a formatted timestamp.
 
PORTABILITY
ANSI C requires <<asctime>>.
 
<<asctime>> requires no supporting OS subroutines.
*/
 
#include <time.h>
#include <_ansi.h>
#include <reent.h>
 
#ifndef _REENT_ONLY
 
char *
_DEFUN (asctime, (tim_p),
_CONST struct tm *tim_p)
{
_REENT_CHECK_ASCTIME_BUF(_REENT);
return asctime_r (tim_p, _REENT_ASCTIME_BUF(_REENT));
}
 
#endif
/programs/develop/libraries/newlib/time/asctime_r.c
0,0 → 1,27
/*
* asctime_r.c
*/
 
#include <stdio.h>
#include <time.h>
 
char *
_DEFUN (asctime_r, (tim_p, result),
_CONST struct tm *tim_p _AND
char *result)
{
static _CONST char day_name[7][3] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static _CONST char mon_name[12][3] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
 
sprintf (result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
day_name[tim_p->tm_wday],
mon_name[tim_p->tm_mon],
tim_p->tm_mday, tim_p->tm_hour, tim_p->tm_min,
tim_p->tm_sec, 1900 + tim_p->tm_year);
return result;
}
/programs/develop/libraries/newlib/time/clock.c
0,0 → 1,78
/* NetWare can not use this implementation of clock, since it does not
have times or any similar function. It provides its own version of
clock in clib.nlm. If we can not use clib.nlm, then we must write
clock in sys/netware. */
 
#ifdef CLOCK_PROVIDED
 
int _dummy_clock = 1;
 
#else
 
/*
* clock.c
* Original Author: G. Haley
*
* Determines the processor time used by the program since invocation. The time
* in seconds is the value returned divided by the value of the macro CLK_TCK.
* If the processor time used is not available, (clock_t) -1 is returned.
*/
 
/*
FUNCTION
<<clock>>---cumulative processor time
 
INDEX
clock
 
ANSI_SYNOPSIS
#include <time.h>
clock_t clock(void);
 
TRAD_SYNOPSIS
#include <time.h>
clock_t clock();
 
DESCRIPTION
Calculates the best available approximation of the cumulative amount
of time used by your program since it started. To convert the result
into seconds, divide by the macro <<CLOCKS_PER_SEC>>.
 
RETURNS
The amount of processor time used so far by your program, in units
defined by the machine-dependent macro <<CLOCKS_PER_SEC>>. If no
measurement is available, the result is (clock_t)<<-1>>.
 
PORTABILITY
ANSI C requires <<clock>> and <<CLOCKS_PER_SEC>>.
 
Supporting OS subroutine required: <<times>>.
*/
 
#include <time.h>
#include <sys/times.h>
#include <reent.h>
 
 
clock_t
_DEFUN (_times_r, (ptr, ptms),
struct _reent *ptr _AND
struct tms *ptms)
{
return -1;
}
 
clock_t
clock ()
{
struct tms tim_s;
clock_t res;
 
if ((res = (clock_t) _times_r (_REENT, &tim_s)) != -1)
res = (clock_t) (tim_s.tms_utime + tim_s.tms_stime +
tim_s.tms_cutime + tim_s.tms_cstime);
 
return res;
}
 
#endif /* CLOCK_PROVIDED */
/programs/develop/libraries/newlib/time/ctime.c
0,0 → 1,55
/*
* ctime.c
* Original Author: G. Haley
*/
 
/*
FUNCTION
<<ctime>>---convert time to local and format as string
 
INDEX
ctime
INDEX
ctime_r
 
ANSI_SYNOPSIS
#include <time.h>
char *ctime(const time_t *<[clock]>);
char *ctime_r(const time_t *<[clock]>, char *<[buf]>);
 
TRAD_SYNOPSIS
#include <time.h>
char *ctime(<[clock]>)
time_t *<[clock]>;
 
char *ctime_r(<[clock]>, <[buf]>)
time_t *<[clock]>;
char *<[buf]>;
 
DESCRIPTION
Convert the time value at <[clock]> to local time (like <<localtime>>)
and format it into a string of the form
. Wed Jun 15 11:38:07 1988\n\0
(like <<asctime>>).
 
RETURNS
A pointer to the string containing a formatted timestamp.
 
PORTABILITY
ANSI C requires <<ctime>>.
 
<<ctime>> requires no supporting OS subroutines.
*/
 
#include <time.h>
 
#ifndef _REENT_ONLY
 
char *
_DEFUN (ctime, (tim_p),
_CONST time_t * tim_p)
{
return asctime (localtime (tim_p));
}
 
#endif
/programs/develop/libraries/newlib/time/ctime_r.c
0,0 → 1,15
/*
* ctime_r.c
*/
 
#include <time.h>
 
char *
_DEFUN (ctime_r, (tim_p, result),
_CONST time_t * tim_p _AND
char * result)
 
{
struct tm tm;
return asctime_r (localtime_r (tim_p, &tm), result);
}
/programs/develop/libraries/newlib/time/difftime.c
0,0 → 1,44
/*
* difftime.c
* Original Author: G. Haley
*/
 
/*
FUNCTION
<<difftime>>---subtract two times
 
INDEX
difftime
 
ANSI_SYNOPSIS
#include <time.h>
double difftime(time_t <[tim1]>, time_t <[tim2]>);
 
TRAD_SYNOPSIS
#include <time.h>
double difftime(<[tim1]>, <[tim2]>)
time_t <[tim1]>;
time_t <[tim2]>;
 
DESCRIPTION
Subtracts the two times in the arguments: `<<<[tim1]> - <[tim2]>>>'.
 
RETURNS
The difference (in seconds) between <[tim2]> and <[tim1]>, as a <<double>>.
 
PORTABILITY
ANSI C requires <<difftime>>, and defines its result to be in seconds
in all implementations.
 
<<difftime>> requires no supporting OS subroutines.
*/
 
#include <time.h>
 
double
_DEFUN (difftime, (tim1, tim2),
time_t tim1 _AND
time_t tim2)
{
return (double)(tim1 - tim2);
}
/programs/develop/libraries/newlib/time/gettzinfo.c
0,0 → 1,15
#include <sys/types.h>
#include "local.h"
 
/* Shared timezone information for libc/time functions. */
static __tzinfo_type tzinfo = {1, 0,
{ {'J', 0, 0, 0, 0, (time_t)0, 0L },
{'J', 0, 0, 0, 0, (time_t)0, 0L }
}
};
 
__tzinfo_type *
__gettzinfo (void)
{
return &tzinfo;
}
/programs/develop/libraries/newlib/time/gmtime.c
0,0 → 1,68
/*
* gmtime.c
* Original Author: G. Haley
*
* Converts the calendar time pointed to by tim_p into a broken-down time
* expressed as Greenwich Mean Time (GMT). Returns a pointer to a structure
* containing the broken-down time, or a null pointer if GMT is not
* available.
*/
 
/*
FUNCTION
<<gmtime>>---convert time to UTC traditional form
 
INDEX
gmtime
INDEX
gmtime_r
 
ANSI_SYNOPSIS
#include <time.h>
struct tm *gmtime(const time_t *<[clock]>);
struct tm *gmtime_r(const time_t *<[clock]>, struct tm *<[res]>);
 
TRAD_SYNOPSIS
#include <time.h>
struct tm *gmtime(<[clock]>)
const time_t *<[clock]>;
struct tm *gmtime_r(<[clock]>, <[res]>)
const time_t *<[clock]>;
struct tm *<[res]>;
 
DESCRIPTION
<<gmtime>> takes the time at <[clock]> representing the number
of elapsed seconds since 00:00:00 on January 1, 1970, Universal
Coordinated Time (UTC, also known in some countries as GMT,
Greenwich Mean time) and converts it to a <<struct tm>>
representation.
 
<<gmtime>> constructs the traditional time representation in static
storage; each call to <<gmtime>> or <<localtime>> will overwrite the
information generated by previous calls to either function.
 
RETURNS
A pointer to the traditional time representation (<<struct tm>>).
 
PORTABILITY
ANSI C requires <<gmtime>>.
 
<<gmtime>> requires no supporting OS subroutines.
*/
 
#include <stdlib.h>
#include <time.h>
 
#define _GMT_OFFSET 0
 
#ifndef _REENT_ONLY
 
struct tm *
_DEFUN (gmtime, (tim_p),
_CONST time_t * tim_p)
{
_REENT_CHECK_TM(_REENT);
return gmtime_r (tim_p, (struct tm *)_REENT_TM(_REENT));
}
 
#endif
/programs/develop/libraries/newlib/time/gmtime_r.c
0,0 → 1,14
/*
* gmtime_r.c
*/
 
#include <time.h>
#include "local.h"
 
struct tm *
_DEFUN (gmtime_r, (tim_p, res),
_CONST time_t * tim_p _AND
struct tm *res)
{
return (_mktm_r (tim_p, res, 1));
}
/programs/develop/libraries/newlib/time/lcltime.c
0,0 → 1,60
/*
* localtime.c
*/
 
/*
FUNCTION
<<localtime>>---convert time to local representation
 
INDEX
localtime
INDEX
localtime_r
 
ANSI_SYNOPSIS
#include <time.h>
struct tm *localtime(time_t *<[clock]>);
struct tm *localtime_r(time_t *<[clock]>, struct tm *<[res]>);
 
TRAD_SYNOPSIS
#include <time.h>
struct tm *localtime(<[clock]>)
time_t *<[clock]>;
struct tm *localtime(<[clock]>, <[res]>)
time_t *<[clock]>;
struct tm *<[res]>;
 
DESCRIPTION
<<localtime>> converts the time at <[clock]> into local time, then
converts its representation from the arithmetic representation to the
traditional representation defined by <<struct tm>>.
 
<<localtime>> constructs the traditional time representation in static
storage; each call to <<gmtime>> or <<localtime>> will overwrite the
information generated by previous calls to either function.
 
<<mktime>> is the inverse of <<localtime>>.
 
RETURNS
A pointer to the traditional time representation (<<struct tm>>).
 
PORTABILITY
ANSI C requires <<localtime>>.
 
<<localtime>> requires no supporting OS subroutines.
*/
 
#include <time.h>
#include <reent.h>
 
#ifndef _REENT_ONLY
 
struct tm *
_DEFUN (localtime, (tim_p),
_CONST time_t * tim_p)
{
_REENT_CHECK_TM(_REENT);
return localtime_r (tim_p, (struct tm *)_REENT_TM(_REENT));
}
 
#endif
/programs/develop/libraries/newlib/time/lcltime_r.c
0,0 → 1,18
/*
* localtime_r.c
*
* Converts the calendar time pointed to by tim_p into a broken-down time
* expressed as local time. Returns a pointer to a structure containing the
* broken-down time.
*/
 
#include <time.h>
#include "local.h"
 
struct tm *
_DEFUN (localtime_r, (tim_p, res),
_CONST time_t * tim_p _AND
struct tm *res)
{
return _mktm_r (tim_p, res, 0);
}
/programs/develop/libraries/newlib/time/local.h
0,0 → 1,36
/* local header used by libc/time routines */
#include <_ansi.h>
#include <time.h>
 
#define SECSPERMIN 60L
#define MINSPERHOUR 60L
#define HOURSPERDAY 24L
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
#define SECSPERDAY (SECSPERHOUR * HOURSPERDAY)
#define DAYSPERWEEK 7
#define MONSPERYEAR 12
 
#define YEAR_BASE 1900
#define EPOCH_YEAR 1970
#define EPOCH_WDAY 4
#define EPOCH_YEARS_SINCE_LEAP 2
#define EPOCH_YEARS_SINCE_CENTURY 70
#define EPOCH_YEARS_SINCE_LEAP_CENTURY 370
 
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
 
struct tm * _EXFUN (_mktm_r, (_CONST time_t *, struct tm *, int __is_gmtime));
int _EXFUN (__tzcalc_limits, (int __year));
 
/* locks for multi-threading */
#ifdef __SINGLE_THREAD__
#define TZ_LOCK
#define TZ_UNLOCK
#else
#define TZ_LOCK __tz_lock()
#define TZ_UNLOCK __tz_unlock()
#endif
 
void _EXFUN(__tz_lock,(_VOID));
void _EXFUN(__tz_unlock,(_VOID));
 
/programs/develop/libraries/newlib/time/mktime.c
0,0 → 1,264
/*
* mktime.c
* Original Author: G. Haley
*
* Converts the broken-down time, expressed as local time, in the structure
* pointed to by tim_p into a calendar time value. The original values of the
* tm_wday and tm_yday fields of the structure are ignored, and the original
* values of the other fields have no restrictions. On successful completion
* the fields of the structure are set to represent the specified calendar
* time. Returns the specified calendar time. If the calendar time can not be
* represented, returns the value (time_t) -1.
*
* Modifications: Fixed tm_isdst usage - 27 August 2008 Craig Howland.
*/
 
/*
FUNCTION
<<mktime>>---convert time to arithmetic representation
 
INDEX
mktime
 
ANSI_SYNOPSIS
#include <time.h>
time_t mktime(struct tm *<[timp]>);
 
TRAD_SYNOPSIS
#include <time.h>
time_t mktime(<[timp]>)
struct tm *<[timp]>;
 
DESCRIPTION
<<mktime>> assumes the time at <[timp]> is a local time, and converts
its representation from the traditional representation defined by
<<struct tm>> into a representation suitable for arithmetic.
 
<<localtime>> is the inverse of <<mktime>>.
 
RETURNS
If the contents of the structure at <[timp]> do not form a valid
calendar time representation, the result is <<-1>>. Otherwise, the
result is the time, converted to a <<time_t>> value.
 
PORTABILITY
ANSI C requires <<mktime>>.
 
<<mktime>> requires no supporting OS subroutines.
*/
 
#include <stdlib.h>
#include <time.h>
#include "local.h"
 
#define _SEC_IN_MINUTE 60L
#define _SEC_IN_HOUR 3600L
#define _SEC_IN_DAY 86400L
 
static _CONST int DAYS_IN_MONTH[12] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
#define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x])
 
static _CONST int _DAYS_BEFORE_MONTH[12] =
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
 
#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0))
#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365)
 
static void
_DEFUN(validate_structure, (tim_p),
struct tm *tim_p)
{
div_t res;
int days_in_feb = 28;
 
/* calculate time & date to account for out of range values */
if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59)
{
res = div (tim_p->tm_sec, 60);
tim_p->tm_min += res.quot;
if ((tim_p->tm_sec = res.rem) < 0)
{
tim_p->tm_sec += 60;
--tim_p->tm_min;
}
}
 
if (tim_p->tm_min < 0 || tim_p->tm_min > 59)
{
res = div (tim_p->tm_min, 60);
tim_p->tm_hour += res.quot;
if ((tim_p->tm_min = res.rem) < 0)
{
tim_p->tm_min += 60;
--tim_p->tm_hour;
}
}
 
if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23)
{
res = div (tim_p->tm_hour, 24);
tim_p->tm_mday += res.quot;
if ((tim_p->tm_hour = res.rem) < 0)
{
tim_p->tm_hour += 24;
--tim_p->tm_mday;
}
}
 
if (tim_p->tm_mon > 11)
{
res = div (tim_p->tm_mon, 12);
tim_p->tm_year += res.quot;
if ((tim_p->tm_mon = res.rem) < 0)
{
tim_p->tm_mon += 12;
--tim_p->tm_year;
}
}
 
if (_DAYS_IN_YEAR (tim_p->tm_year) == 366)
days_in_feb = 29;
 
if (tim_p->tm_mday <= 0)
{
while (tim_p->tm_mday <= 0)
{
if (--tim_p->tm_mon == -1)
{
tim_p->tm_year--;
tim_p->tm_mon = 11;
days_in_feb =
((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ?
29 : 28);
}
tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon);
}
}
else
{
while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon))
{
tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon);
if (++tim_p->tm_mon == 12)
{
tim_p->tm_year++;
tim_p->tm_mon = 0;
days_in_feb =
((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ?
29 : 28);
}
}
}
}
 
time_t
_DEFUN(mktime, (tim_p),
struct tm *tim_p)
{
time_t tim = 0;
long days = 0;
int year, isdst, tm_isdst;
__tzinfo_type *tz = __gettzinfo ();
 
/* validate structure */
validate_structure (tim_p);
 
/* compute hours, minutes, seconds */
tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) +
(tim_p->tm_hour * _SEC_IN_HOUR);
 
/* compute days in year */
days += tim_p->tm_mday - 1;
days += _DAYS_BEFORE_MONTH[tim_p->tm_mon];
if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366)
days++;
 
/* compute day of the year */
tim_p->tm_yday = days;
 
if (tim_p->tm_year > 10000
|| tim_p->tm_year < -10000)
{
return (time_t) -1;
}
 
/* compute days in other years */
if (tim_p->tm_year > 70)
{
for (year = 70; year < tim_p->tm_year; year++)
days += _DAYS_IN_YEAR (year);
}
else if (tim_p->tm_year < 70)
{
for (year = 69; year > tim_p->tm_year; year--)
days -= _DAYS_IN_YEAR (year);
days -= _DAYS_IN_YEAR (year);
}
 
/* compute day of the week */
if ((tim_p->tm_wday = (days + 4) % 7) < 0)
tim_p->tm_wday += 7;
 
/* compute total seconds */
tim += (days * _SEC_IN_DAY);
 
/* Convert user positive into 1 */
tm_isdst = tim_p->tm_isdst > 0 ? 1 : tim_p->tm_isdst;
isdst = tm_isdst;
 
if (_daylight)
{
int y = tim_p->tm_year + YEAR_BASE;
if (y == tz->__tzyear || __tzcalc_limits (y))
{
/* calculate start of dst in dst local time and
start of std in both std local time and dst local time */
time_t startdst_dst = tz->__tzrule[0].change
- (time_t) tz->__tzrule[1].offset;
time_t startstd_dst = tz->__tzrule[1].change
- (time_t) tz->__tzrule[1].offset;
time_t startstd_std = tz->__tzrule[1].change
- (time_t) tz->__tzrule[0].offset;
/* if the time is in the overlap between dst and std local times */
if (tim >= startstd_std && tim < startstd_dst)
; /* we let user decide or leave as -1 */
else
{
isdst = (tz->__tznorth
? (tim >= startdst_dst && tim < startstd_std)
: (tim >= startdst_dst || tim < startstd_std));
/* if user committed and was wrong, perform correction, but not
* if the user has given a negative value (which
* asks mktime() to determine if DST is in effect or not) */
if (tm_isdst >= 0 && (isdst ^ tm_isdst) == 1)
{
/* we either subtract or add the difference between
time zone offsets, depending on which way the user got it
wrong. The diff is typically one hour, or 3600 seconds,
and should fit in a 16-bit int, even though offset
is a long to accomodate 12 hours. */
int diff = (int) (tz->__tzrule[0].offset
- tz->__tzrule[1].offset);
if (!isdst)
diff = -diff;
tim_p->tm_sec += diff;
validate_structure (tim_p);
tim += diff; /* we also need to correct our current time calculation */
}
}
}
}
 
/* add appropriate offset to put time in gmt format */
if (isdst == 1)
tim += (time_t) tz->__tzrule[1].offset;
else /* otherwise assume std time */
tim += (time_t) tz->__tzrule[0].offset;
 
/* reset isdst flag to what we have calculated */
tim_p->tm_isdst = isdst;
 
return tim;
}
/programs/develop/libraries/newlib/time/mktm_r.c
0,0 → 1,257
/*
* mktm_r.c
* Original Author: Adapted from tzcode maintained by Arthur David Olson.
* Modifications: Changed to mktm_r and added __tzcalc_limits - 04/10/02, Jeff Johnston
* Fixed bug in mday computations - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru>
* Fixed bug in __tzcalc_limits - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru>
*
* Converts the calendar time pointed to by tim_p into a broken-down time
* expressed as local time. Returns a pointer to a structure containing the
* broken-down time.
*/
 
#include <stdlib.h>
#include <time.h>
#include "local.h"
 
static _CONST int mon_lengths[2][MONSPERYEAR] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
} ;
 
static _CONST int year_lengths[2] = {
365,
366
} ;
 
struct tm *
_DEFUN (_mktm_r, (tim_p, res, is_gmtime),
_CONST time_t * tim_p _AND
struct tm *res _AND
int is_gmtime)
{
long days, rem;
time_t lcltime;
int y;
int yleap;
_CONST int *ip;
__tzinfo_type *tz = __gettzinfo ();
 
/* base decision about std/dst time on current time */
lcltime = *tim_p;
days = ((long)lcltime) / SECSPERDAY;
rem = ((long)lcltime) % SECSPERDAY;
while (rem < 0)
{
rem += SECSPERDAY;
--days;
}
while (rem >= SECSPERDAY)
{
rem -= SECSPERDAY;
++days;
}
/* compute hour, min, and sec */
res->tm_hour = (int) (rem / SECSPERHOUR);
rem %= SECSPERHOUR;
res->tm_min = (int) (rem / SECSPERMIN);
res->tm_sec = (int) (rem % SECSPERMIN);
 
/* compute day of week */
if ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0)
res->tm_wday += DAYSPERWEEK;
 
/* compute year & day of year */
y = EPOCH_YEAR;
if (days >= 0)
{
for (;;)
{
yleap = isleap(y);
if (days < year_lengths[yleap])
break;
y++;
days -= year_lengths[yleap];
}
}
else
{
do
{
--y;
yleap = isleap(y);
days += year_lengths[yleap];
} while (days < 0);
}
 
res->tm_year = y - YEAR_BASE;
res->tm_yday = days;
ip = mon_lengths[yleap];
for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon)
days -= ip[res->tm_mon];
res->tm_mday = days + 1;
 
if (!is_gmtime)
{
long offset;
int hours, mins, secs;
 
TZ_LOCK;
if (_daylight)
{
if (y == tz->__tzyear || __tzcalc_limits (y))
res->tm_isdst = (tz->__tznorth
? (*tim_p >= tz->__tzrule[0].change
&& *tim_p < tz->__tzrule[1].change)
: (*tim_p >= tz->__tzrule[0].change
|| *tim_p < tz->__tzrule[1].change));
else
res->tm_isdst = -1;
}
else
res->tm_isdst = 0;
 
offset = (res->tm_isdst == 1
? tz->__tzrule[1].offset
: tz->__tzrule[0].offset);
 
hours = (int) (offset / SECSPERHOUR);
offset = offset % SECSPERHOUR;
mins = (int) (offset / SECSPERMIN);
secs = (int) (offset % SECSPERMIN);
 
res->tm_sec -= secs;
res->tm_min -= mins;
res->tm_hour -= hours;
 
if (res->tm_sec >= SECSPERMIN)
{
res->tm_min += 1;
res->tm_sec -= SECSPERMIN;
}
else if (res->tm_sec < 0)
{
res->tm_min -= 1;
res->tm_sec += SECSPERMIN;
}
if (res->tm_min >= MINSPERHOUR)
{
res->tm_hour += 1;
res->tm_min -= MINSPERHOUR;
}
else if (res->tm_min < 0)
{
res->tm_hour -= 1;
res->tm_min += MINSPERHOUR;
}
if (res->tm_hour >= HOURSPERDAY)
{
++res->tm_yday;
++res->tm_wday;
if (res->tm_wday > 6)
res->tm_wday = 0;
++res->tm_mday;
res->tm_hour -= HOURSPERDAY;
if (res->tm_mday > ip[res->tm_mon])
{
res->tm_mday -= ip[res->tm_mon];
res->tm_mon += 1;
if (res->tm_mon == 12)
{
res->tm_mon = 0;
res->tm_year += 1;
res->tm_yday = 0;
}
}
}
else if (res->tm_hour < 0)
{
res->tm_yday -= 1;
res->tm_wday -= 1;
if (res->tm_wday < 0)
res->tm_wday = 6;
res->tm_mday -= 1;
res->tm_hour += 24;
if (res->tm_mday == 0)
{
res->tm_mon -= 1;
if (res->tm_mon < 0)
{
res->tm_mon = 11;
res->tm_year -= 1;
res->tm_yday = 365 + isleap(res->tm_year);
}
res->tm_mday = ip[res->tm_mon];
}
}
TZ_UNLOCK;
}
else
res->tm_isdst = 0;
 
return (res);
}
 
int
_DEFUN (__tzcalc_limits, (year),
int year)
{
int days, year_days, years;
int i, j;
__tzinfo_type *tz = __gettzinfo ();
 
if (year < EPOCH_YEAR)
return 0;
 
tz->__tzyear = year;
 
years = (year - EPOCH_YEAR);
 
year_days = years * 365 +
(years - 1 + EPOCH_YEARS_SINCE_LEAP) / 4 - (years - 1 + EPOCH_YEARS_SINCE_CENTURY) / 100 +
(years - 1 + EPOCH_YEARS_SINCE_LEAP_CENTURY) / 400;
for (i = 0; i < 2; ++i)
{
if (tz->__tzrule[i].ch == 'J')
days = year_days + tz->__tzrule[i].d +
(isleap(year) && tz->__tzrule[i].d >= 60);
else if (tz->__tzrule[i].ch == 'D')
days = year_days + tz->__tzrule[i].d;
else
{
int yleap = isleap(year);
int m_day, m_wday, wday_diff;
_CONST int *ip = mon_lengths[yleap];
 
days = year_days;
 
for (j = 1; j < tz->__tzrule[i].m; ++j)
days += ip[j-1];
 
m_wday = (EPOCH_WDAY + days) % DAYSPERWEEK;
wday_diff = tz->__tzrule[i].d - m_wday;
if (wday_diff < 0)
wday_diff += DAYSPERWEEK;
m_day = (tz->__tzrule[i].n - 1) * DAYSPERWEEK + wday_diff;
 
while (m_day >= ip[j-1])
m_day -= DAYSPERWEEK;
 
days += m_day;
}
 
/* store the change-over time in GMT form by adding offset */
tz->__tzrule[i].change = days * SECSPERDAY +
tz->__tzrule[i].s + tz->__tzrule[i].offset;
}
 
tz->__tznorth = (tz->__tzrule[0].change < tz->__tzrule[1].change);
 
return 1;
}
 
/programs/develop/libraries/newlib/time/strftime.c
0,0 → 1,333
/* NOTE: This file defines both strftime() and wcsftime(). Take care when
* making changes. See also wcsftime.c, and note the (small) overlap in the
* manual description, taking care to edit both as needed. */
/*
* strftime.c
* Original Author: G. Haley
* Additions from: Eric Blake
* Changes to allow dual use as wcstime, also: Craig Howland
*
* Places characters into the array pointed to by s as controlled by the string
* pointed to by format. If the total number of resulting characters including
* the terminating null character is not more than maxsize, returns the number
* of characters placed into the array pointed to by s (not including the
* terminating null character); otherwise zero is returned and the contents of
* the array indeterminate.
*/
 
/*
FUNCTION
<<strftime>>---convert date and time to a formatted string
 
INDEX
strftime
 
ANSI_SYNOPSIS
#include <time.h>
size_t strftime(char *<[s]>, size_t <[maxsize]>,
const char *<[format]>, const struct tm *<[timp]>);
 
TRAD_SYNOPSIS
#include <time.h>
size_t strftime(<[s]>, <[maxsize]>, <[format]>, <[timp]>)
char *<[s]>;
size_t <[maxsize]>;
char *<[format]>;
struct tm *<[timp]>;
 
DESCRIPTION
<<strftime>> converts a <<struct tm>> representation of the time (at
<[timp]>) into a null-terminated string, starting at <[s]> and occupying
no more than <[maxsize]> characters.
 
You control the format of the output using the string at <[format]>.
<<*<[format]>>> can contain two kinds of specifications: text to be
copied literally into the formatted string, and time conversion
specifications. Time conversion specifications are two- and
three-character sequences beginning with `<<%>>' (use `<<%%>>' to
include a percent sign in the output). Each defined conversion
specification selects only the specified field(s) of calendar time
data from <<*<[timp]>>>, and converts it to a string in one of the
following ways:
 
o+
o %a
The abbreviated weekday name according to the current locale. [tm_wday]
 
o %A
The full weekday name according to the current locale.
In the default "C" locale, one of `<<Sunday>>', `<<Monday>>', `<<Tuesday>>',
`<<Wednesday>>', `<<Thursday>>', `<<Friday>>', `<<Saturday>>'. [tm_wday]
 
o %b
The abbreviated month name according to the current locale. [tm_mon]
 
o %B
The full month name according to the current locale.
In the default "C" locale, one of `<<January>>', `<<February>>',
`<<March>>', `<<April>>', `<<May>>', `<<June>>', `<<July>>',
`<<August>>', `<<September>>', `<<October>>', `<<November>>',
`<<December>>'. [tm_mon]
 
o %c
The preferred date and time representation for the current locale.
[tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year, tm_wday]
 
o %C
The century, that is, the year divided by 100 then truncated. For
4-digit years, the result is zero-padded and exactly two characters;
but for other years, there may a negative sign or more digits. In
this way, `<<%C%y>>' is equivalent to `<<%Y>>'. [tm_year]
 
o %d
The day of the month, formatted with two digits (from `<<01>>' to
`<<31>>'). [tm_mday]
 
o %D
A string representing the date, in the form `<<"%m/%d/%y">>'.
[tm_mday, tm_mon, tm_year]
 
o %e
The day of the month, formatted with leading space if single digit
(from `<<1>>' to `<<31>>'). [tm_mday]
 
o %E<<x>>
In some locales, the E modifier selects alternative representations of
certain modifiers <<x>>. In newlib, it is ignored, and treated as %<<x>>.
 
o %F
A string representing the ISO 8601:2000 date format, in the form
`<<"%Y-%m-%d">>'. [tm_mday, tm_mon, tm_year]
 
o %g
The last two digits of the week-based year, see specifier %G (from
`<<00>>' to `<<99>>'). [tm_year, tm_wday, tm_yday]
 
o %G
The week-based year. In the ISO 8601:2000 calendar, week 1 of the year
includes January 4th, and begin on Mondays. Therefore, if January 1st,
2nd, or 3rd falls on a Sunday, that day and earlier belong to the last
week of the previous year; and if December 29th, 30th, or 31st falls
on Monday, that day and later belong to week 1 of the next year. For
consistency with %Y, it always has at least four characters.
Example: "%G" for Saturday 2nd January 1999 gives "1998", and for
Tuesday 30th December 1997 gives "1998". [tm_year, tm_wday, tm_yday]
 
o %h
Synonym for "%b". [tm_mon]
 
o %H
The hour (on a 24-hour clock), formatted with two digits (from
`<<00>>' to `<<23>>'). [tm_hour]
 
o %I
The hour (on a 12-hour clock), formatted with two digits (from
`<<01>>' to `<<12>>'). [tm_hour]
 
o %j
The count of days in the year, formatted with three digits
(from `<<001>>' to `<<366>>'). [tm_yday]
 
o %k
The hour (on a 24-hour clock), formatted with leading space if single
digit (from `<<0>>' to `<<23>>'). Non-POSIX extension (c.p. %I). [tm_hour]
 
o %l
The hour (on a 12-hour clock), formatted with leading space if single
digit (from `<<1>>' to `<<12>>'). Non-POSIX extension (c.p. %H). [tm_hour]
 
o %m
The month number, formatted with two digits (from `<<01>>' to `<<12>>').
[tm_mon]
 
o %M
The minute, formatted with two digits (from `<<00>>' to `<<59>>'). [tm_min]
 
o %n
A newline character (`<<\n>>').
 
o %O<<x>>
In some locales, the O modifier selects alternative digit characters
for certain modifiers <<x>>. In newlib, it is ignored, and treated as %<<x>>.
 
o %p
Either `<<AM>>' or `<<PM>>' as appropriate, or the corresponding strings for
the current locale. [tm_hour]
 
o %P
Same as '<<%p>>', but in lowercase. This is a GNU extension. [tm_hour]
 
o %r
Replaced by the time in a.m. and p.m. notation. In the "C" locale this
is equivalent to "%I:%M:%S %p". In locales which don't define a.m./p.m.
notations, the result is an empty string. [tm_sec, tm_min, tm_hour]
 
o %R
The 24-hour time, to the minute. Equivalent to "%H:%M". [tm_min, tm_hour]
 
o %S
The second, formatted with two digits (from `<<00>>' to `<<60>>'). The
value 60 accounts for the occasional leap second. [tm_sec]
 
o %t
A tab character (`<<\t>>').
 
o %T
The 24-hour time, to the second. Equivalent to "%H:%M:%S". [tm_sec,
tm_min, tm_hour]
 
o %u
The weekday as a number, 1-based from Monday (from `<<1>>' to
`<<7>>'). [tm_wday]
 
o %U
The week number, where weeks start on Sunday, week 1 contains the first
Sunday in a year, and earlier days are in week 0. Formatted with two
digits (from `<<00>>' to `<<53>>'). See also <<%W>>. [tm_wday, tm_yday]
 
o %V
The week number, where weeks start on Monday, week 1 contains January 4th,
and earlier days are in the previous year. Formatted with two digits
(from `<<01>>' to `<<53>>'). See also <<%G>>. [tm_year, tm_wday, tm_yday]
 
o %w
The weekday as a number, 0-based from Sunday (from `<<0>>' to `<<6>>').
[tm_wday]
 
o %W
The week number, where weeks start on Monday, week 1 contains the first
Monday in a year, and earlier days are in week 0. Formatted with two
digits (from `<<00>>' to `<<53>>'). [tm_wday, tm_yday]
 
o %x
Replaced by the preferred date representation in the current locale.
In the "C" locale this is equivalent to "%m/%d/%y".
[tm_mon, tm_mday, tm_year]
 
o %X
Replaced by the preferred time representation in the current locale.
In the "C" locale this is equivalent to "%H:%M:%S". [tm_sec, tm_min, tm_hour]
 
o %y
The last two digits of the year (from `<<00>>' to `<<99>>'). [tm_year]
(Implementation interpretation: always positive, even for negative years.)
 
o %Y
The full year, equivalent to <<%C%y>>. It will always have at least four
characters, but may have more. The year is accurate even when tm_year
added to the offset of 1900 overflows an int. [tm_year]
 
o %z
The offset from UTC. The format consists of a sign (negative is west of
Greewich), two characters for hour, then two characters for minutes
(-hhmm or +hhmm). If tm_isdst is negative, the offset is unknown and no
output is generated; if it is zero, the offset is the standard offset for
the current time zone; and if it is positive, the offset is the daylight
savings offset for the current timezone. The offset is determined from
the TZ environment variable, as if by calling tzset(). [tm_isdst]
 
o %Z
The time zone name. If tm_isdst is negative, no output is generated.
Otherwise, the time zone name is based on the TZ environment variable,
as if by calling tzset(). [tm_isdst]
 
o %%
A single character, `<<%>>'.
o-
 
RETURNS
When the formatted time takes up no more than <[maxsize]> characters,
the result is the length of the formatted string. Otherwise, if the
formatting operation was abandoned due to lack of room, the result is
<<0>>, and the string starting at <[s]> corresponds to just those
parts of <<*<[format]>>> that could be completely filled in within the
<[maxsize]> limit.
 
PORTABILITY
ANSI C requires <<strftime>>, but does not specify the contents of
<<*<[s]>>> when the formatted string would require more than
<[maxsize]> characters. Unrecognized specifiers and fields of
<<timp>> that are out of range cause undefined results. Since some
formats expand to 0 bytes, it is wise to set <<*<[s]>>> to a nonzero
value beforehand to distinguish between failure and an empty string.
This implementation does not support <<s>> being NULL, nor overlapping
<<s>> and <<format>>.
 
<<strftime>> requires no supporting OS subroutines.
 
BUGS
<<strftime>> ignores the LC_TIME category of the current locale, hard-coding
the "C" locale settings.
*/
 
#include <newlib.h>
#include <sys/config.h>
#include <stddef.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <ctype.h>
#include <wctype.h>
 
/* Defines to make the file dual use for either strftime() or wcsftime().
* To get wcsftime, define MAKE_WCSFTIME.
* To get strftime, do not define MAKE_WCSFTIME.
* Names are kept friendly to strftime() usage. The biggest ugliness is the
* use of the CQ() macro to make either regular character constants and
* string literals or wide-character constants and wide-character-string
* literals, as appropriate. */
#if !defined(MAKE_WCSFTIME)
# define CHAR char /* string type basis */
# define CQ(a) a /* character constant qualifier */
# define SFLG /* %s flag (null for normal char) */
# define _ctloc(x) (ctloclen = strlen (ctloc = _CurrentTimeLocale->x), ctloc)
# define TOLOWER(c) tolower((int)(unsigned char)(c))
# define STRTOUL(c,p,b) strtoul((c),(p),(b))
# define STRCPY(a,b) strcpy((a),(b))
# define STRCHR(a,b) strchr((a),(b))
# define STRLEN(a) strlen(a)
# else
# define strftime wcsftime /* Alternate function name */
# define CHAR wchar_t /* string type basis */
# define CQ(a) L##a /* character constant qualifier */
# define snprintf swprintf /* wide-char equivalent function name */
# define strncmp wcsncmp /* wide-char equivalent function name */
# define TOLOWER(c) towlower((wint_t)(c))
# define STRTOUL(c,p,b) wcstoul((c),(p),(b))
# define STRCPY(a,b) wcscpy((a),(b))
# define STRCHR(a,b) wcschr((a),(b))
# define STRLEN(a) wcslen(a)
# define SFLG "l" /* %s flag (l for wide char) */
# ifdef __HAVE_LOCALE_INFO_EXTENDED__
# define _ctloc(x) (ctloclen = wcslen (ctloc = _CurrentTimeLocale->w##x), \
ctloc)
# else
# define CTLOCBUFLEN 256 /* Arbitrary big buffer size */
const wchar_t *
__ctloc (wchar_t *buf, const char *elem, size_t *len_ret)
{
buf[CTLOCBUFLEN - 1] = L'\0';
*len_ret = mbstowcs (buf, elem, CTLOCBUFLEN - 1);
if (*len_ret == (size_t) -1 )
*len_ret = 0;
return buf;
}
# define _ctloc(x) (ctloc = __ctloc (ctlocbuf, _CurrentTimeLocale->x, \
&ctloclen))
# endif
#endif /* MAKE_WCSFTIME */
 
 
size_t _DEFUN (strftime, (s, maxsize, format, tim_p),
CHAR *s _AND
size_t maxsize _AND
_CONST CHAR *format _AND
_CONST struct tm *tim_p)
{
 
return 0;
}
 
 
/programs/develop/libraries/newlib/time/time.c
0,0 → 1,53
/*
FUNCTION
<<time>>---get current calendar time (as single number)
 
INDEX
time
 
ANSI_SYNOPSIS
#include <time.h>
time_t time(time_t *<[t]>);
 
TRAD_SYNOPSIS
#include <time.h>
time_t time(<[t]>)
time_t *<[t]>;
 
DESCRIPTION
<<time>> looks up the best available representation of the current
time and returns it, encoded as a <<time_t>>. It stores the same
value at <[t]> unless the argument is <<NULL>>.
 
RETURNS
A <<-1>> result means the current time is not available; otherwise the
result represents the current time.
 
PORTABILITY
ANSI C requires <<time>>.
 
Supporting OS subroutine required: Some implementations require
<<gettimeofday>>.
*/
 
/* Most times we have a system call in newlib/libc/sys/.. to do this job */
 
#include <_ansi.h>
#include <reent.h>
#include <sys/types.h>
#include <sys/time.h>
 
time_t
_DEFUN (time, (t),
time_t * t)
{
struct timeval now;
 
if (_gettimeofday_r (_REENT, &now, NULL) >= 0)
{
if (t)
*t = now.tv_sec;
return now.tv_sec;
}
return -1;
}
/programs/develop/libraries/newlib/time/tzlock.c
0,0 → 1,56
/*
FUNCTION
<<__tz_lock>>, <<__tz_unlock>>---lock time zone global variables
 
INDEX
__tz_lock
INDEX
__tz_unlock
 
ANSI_SYNOPSIS
#include "local.h"
void __tz_lock (void);
void __tz_unlock (void);
 
TRAD_SYNOPSIS
void __tz_lock();
void __tz_unlock();
 
DESCRIPTION
The <<tzset>> facility functions call these functions when they need to
ensure the values of global variables. The version of these routines
supplied in the library use the lock API defined in sys/lock.h. If multiple
threads of execution can call the time functions and give up scheduling in
the middle, then you you need to define your own versions of these functions
in order to safely lock the time zone variables during a call. If you do
not, the results of <<localtime>>, <<mktime>>, <<ctime>>, and <<strftime>>
are undefined.
 
The lock <<__tz_lock>> may not be called recursively; that is,
a call <<__tz_lock>> will always lock all subsequent <<__tz_lock>> calls
until the corresponding <<__tz_unlock>> call on the same thread is made.
*/
 
#include <_ansi.h>
#include "local.h"
#include <sys/lock.h>
 
#ifndef __SINGLE_THREAD__
__LOCK_INIT(static, __tz_lock_object);
#endif
 
_VOID
_DEFUN_VOID (__tz_lock)
{
#ifndef __SINGLE_THREAD__
__lock_acquire(__tz_lock_object);
#endif
}
 
_VOID
_DEFUN_VOID (__tz_unlock)
{
#ifndef __SINGLE_THREAD__
__lock_release(__tz_lock_object);
#endif
}
/programs/develop/libraries/newlib/time/tzvars.c
0,0 → 1,10
#include <time.h>
 
/* Global timezone variables. */
 
/* Default timezone to GMT */
char *_tzname[2] = {"GMT", "GMT"};
int _daylight = 0;
long _timezone = 0;
 
 
/programs/develop/libraries/newlib/time
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property