Commit f126a1ab authored by Kevin Bracey's avatar Kevin Bracey
Browse files

* __assert2() added to support for C99 assert(), which displays function name.

* _Exit() added.
* Lots of new <math.h> functions (acosh, asinh, atanh, exp2, expm1,
  ilogb, log1p, log2, logb, scalbn, scalbln, cbrt, erf, erfc,
  lgamma, tgamma, nexttoward, fmaf). Float and long double forms
  of every function added; long double forms are included as another
  library object in the stubs rather than the shared library, as they
  just branch to the double form.
* Subnormal/NaN/infinity cases in various <math.h> functions improved.
* Added <tgmath.h>.
* Headers brought into line with CC 5.54.
* RMEnsures added to C library initialisation to try to load minimum
  CallASWI, FPEmulator, CLib. No errors reported if load fails.
* A few pointless inter-file dependencies removed to reduce minimum
  size of included ANSILib.

Version 5.46. Tagged as 'RISC_OSLib-5_46'
parent eb77aba9
No related merge requests found
......@@ -15,4 +15,4 @@ To make Shared C Library compatible with 32-bit RISC OS, build with APCS = APCS-
An APCS-32 Shared C Library will NOT run 26-bit programs, even on a 26-bit
system; an APCS-R Shared C Library must be used. In a build using APCS-32,
the SCL must be forced to APCS-R - pass the option SCL_APCS="-APCS 3/26bit"
in the components file to acheive this.
in the components file to achieve this.
......@@ -181,6 +181,7 @@ HEADERS =\
CLIB:h.stdlib \
CLIB:h.string \
CLIB:h.swis \
CLIB:h.tgmath \
CLIB:h.time \
CLIB:h.varargs \
RISC_OSLib:h.akbd \
......@@ -278,7 +279,7 @@ ANSI_OBJS =\
o.alloc o.armprof o.armsys o.clib o.ctype o.error o.fpprintf \
o.kernel o.locale o.math o.memcpset o.overmgr o.printf o.scanf \
o.signal o.sort o.stdio o.stdlib o.string o.swiv o.time o.fenv \
o.longlong
o.longlong o.mathl
RM_OBJS =\
rm_o.k_modbody \
......@@ -587,17 +588,17 @@ rm_o.k_stub2_rm: kernel.s.k_stub2_rm
rm_o_rl.rl_stub_rm: rlib.s.rl_stub_rm
${OBJASM} ${ALFLAGS} -from rlib.s.rl_stub_rm -to $@
lib.stubs: o.cl_stub_r o.k_stub2_r o.cl_stub2_r
${LIBFILE} ${LIBFLAGS} $@ o.cl_stub_r o.k_stub2_r o.cl_stub2_r
lib.stubs: o.cl_stub_r o.k_stub2_r o.cl_stub2_r o.mathl
${LIBFILE} ${LIBFLAGS} $@ o.cl_stub_r o.k_stub2_r o.cl_stub2_r o.mathl
lib.rstubs: o_rl.rl_stub_r o.k_stub2_r o.cl_stub2_r
${LIBFILE} ${LIBFLAGS} $@ o_rl.rl_stub_r o.k_stub2_r o.cl_stub2_r
lib.rstubs: o_rl.rl_stub_r o.k_stub2_r o.cl_stub2_r o.mathl
${LIBFILE} ${LIBFLAGS} $@ o_rl.rl_stub_r o.k_stub2_r o.cl_stub2_r o.mathl
lib.romcstubs: rm_o.cl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm
${LIBFILE} ${LIBFLAGS} $@ rm_o.cl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm
lib.romcstubs: rm_o.cl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm o.mathl
${LIBFILE} ${LIBFLAGS} $@ rm_o.cl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm o.mathl
lib.romstubs: rm_o_rl.rl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm
${LIBFILE} ${LIBFLAGS} $@ rm_o_rl.rl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm
lib.romstubs: rm_o_rl.rl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm o.mathl
${LIBFILE} ${LIBFLAGS} $@ rm_o_rl.rl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm o.mathl
lib.romastubs: rlib.s.rl_stub_a
${OBJASM} ${AFLAGS} -from rlib.s.rl_stub_a -to $@
......@@ -648,6 +649,7 @@ CLIB:h.stdint: clib.h.stdint; ${CP} clib.h.stdint $@ ${CPFLAGS}
CLIB:h.stdio: clib.h.stdio; ${CP} clib.h.stdio $@ ${CPFLAGS}
CLIB:h.stdlib: clib.h.stdlib; ${CP} clib.h.stdlib $@ ${CPFLAGS}
CLIB:h.string: clib.h.string; ${CP} clib.h.string $@ ${CPFLAGS}
CLIB:h.tgmath: clib.h.tgmath; ${CP} clib.h.tgmath $@ ${CPFLAGS}
CLIB:h.time: clib.h.time; ${CP} clib.h.time $@ ${CPFLAGS}
CLIB:h.varargs: clib.h.varargs; ${CP} clib.h.varargs $@ ${CPFLAGS}
......
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.45"
Module_Version SETA 545
Module_MajorVersion SETS "5.46"
Module_Version SETA 546
Module_MinorVersion SETS ""
Module_Date SETS "17 Jan 2003"
Module_ApplicationDate SETS "17-Jan-03"
Module_Date SETS "15 Apr 2003"
Module_ApplicationDate SETS "15-Apr-03"
Module_ComponentName SETS "RISC_OSLib"
Module_ComponentPath SETS "RiscOS/Sources/Lib/RISC_OSLib"
Module_FullVersion SETS "5.45"
Module_HelpVersion SETS "5.45 (17 Jan 2003)"
Module_FullVersion SETS "5.46"
Module_HelpVersion SETS "5.46 (15 Apr 2003)"
END
/* (5.45)
/* (5.46)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.68.
*
*/
#define Module_MajorVersion_CMHG 5.45
#define Module_MajorVersion_CMHG 5.46
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 17 Jan 2003
#define Module_Date_CMHG 15 Apr 2003
#define Module_MajorVersion "5.45"
#define Module_Version 545
#define Module_MajorVersion "5.46"
#define Module_Version 546
#define Module_MinorVersion ""
#define Module_Date "17 Jan 2003"
#define Module_Date "15 Apr 2003"
#define Module_ApplicationDate "17-Jan-03"
#define Module_ApplicationDate "15-Apr-03"
#define Module_ComponentName "RISC_OSLib"
#define Module_ComponentPath "RiscOS/Sources/Lib/RISC_OSLib"
#define Module_FullVersion "5.45"
#define Module_HelpVersion "5.45 (17 Jan 2003)"
#define Module_LibraryVersionInfo "5:45"
#define Module_FullVersion "5.46"
#define Module_HelpVersion "5.46 (15 Apr 2003)"
#define Module_LibraryVersionInfo "5:46"
......@@ -40,6 +40,7 @@ extern int main(int argc, char **argv); /* the point of it all */
extern FILEHANDLE __dup(int new, int old);
extern void _ctype_init(void);
extern int _fprintf_lf(FILE *fp, const char *fmt, ...);
extern int _sprintf(char *buff, const char *fmt, ...);
extern int _sprintf_lf(char *buff, const char *fmt, ...);
extern _kernel_oserror *_kernel_peek_last_oserror(void);
......@@ -160,22 +161,25 @@ time_t time(time_t *timer)
*/
int _desktop_task()
{
int h = 0;
_kernel_swi_regs r;
if (_kernel_processor_mode() & 0xF) return 0;
_swix(TaskWindow_TaskInfo, _IN(0)|_OUT(0), 0, &h);
if (h) return 0;
_swix(Wimp_ReadSysInfo, _IN(0)|_OUT(0), 3, &h);
if (h == 0) return 0;
_swix(Wimp_ReadSysInfo, _IN(0)|_OUT(0), 5, &h);
return h;
r.r[0] = 0;
if (_kernel_swi(TaskWindow_TaskInfo, &r, &r) || r.r[0])
return 0;
r.r[0] = 3;
_kernel_swi(Wimp_ReadSysInfo, &r, &r);
if (r.r[0] == 0) return 0;
r.r[0] = 5;
_kernel_swi(Wimp_ReadSysInfo, &r, &r);
return r.r[0];
}
static int _desktop_report(const char *s, const char *but)
{
_kernel_swi_regs r;
_kernel_oserror err, *e;
const char *n = NULL;
char *p, *end;
int flags, r, h = _desktop_task();
int flags, h = _desktop_task();
if (h == 0) return 0;
flags = 0x102; /* New error, cancel button */
......@@ -210,17 +214,26 @@ static int _desktop_report(const char *s, const char *but)
e = &err;
}
_swix(TaskManager_TaskNameFromHandle, _IN(0)|_OUT(0), h, &n);
r = 0;
_swix(Wimp_ReportError, _INR(0,5)|_OUT(1), e, flags, n, NULL, 1, but, &r);
return r;
r.r[0] = h;
if (_kernel_swi(TaskManager_TaskNameFromHandle, &r, &r) == 0)
r.r[2] = r.r[0];
else
r.r[2] = 0;
r.r[0] = (int) e;
r.r[1] = flags;
r.r[3] = 0;
r.r[4] = 1;
r.r[5] = (int) but;
if (_kernel_swi(Wimp_ReportError, &r, &r) == 0)
return r.r[1];
else
return 0;
}
bool _sys__assert(const char *s, const char *expr, const char *file, int line)
bool _sys__assert(const char *s, const char *expr, const char *func, const char *file, int line)
{
char buffer[252];
int len, exprlen, filelen;
int len, funclen, exprlen, filelen;
if (!istty(stderr->__file)) return false;
......@@ -228,29 +241,39 @@ bool _sys__assert(const char *s, const char *expr, const char *file, int line)
if (strlen(s) > 200) return false; /* Be safe */
len = sprintf(buffer, s, "", "", line);
len = func ? _sprintf(buffer, s, "", "", "", line)
: _sprintf(buffer, s, "", "", line);
funclen = func ? strlen(func) : 0;
exprlen = strlen(expr);
filelen = strlen(file);
if (len + exprlen + filelen < 251)
if (len + funclen + exprlen + filelen < 251)
{
sprintf(buffer, s, expr, file, line);
func ? _sprintf(buffer, s, expr, func, file, line)
: _sprintf(buffer, s, expr, file, line);
}
else
{
char expr2[200];
char func2[50];
char file2[100];
#define min(a,b) a<b?a:b
exprlen = min(exprlen, 199);
funclen = min(funclen, 49);
filelen = min(filelen, 99);
filelen = min(filelen, 251-len-exprlen);
filelen = min(filelen, 251-len-funclen-exprlen);
if (filelen < 0) filelen = 0;
exprlen = min(exprlen, 251-len-filelen);
funclen = min(funclen, 251-len-exprlen-filelen);
if (funclen < 0) funclen = 0;
exprlen = min(exprlen, 251-len-funclen-filelen);
memcpy(expr2, expr, exprlen);
memcpy(func2, func, funclen);
memcpy(file2, file, filelen);
expr2[exprlen]='\0';
func2[funclen]='\0';
file2[filelen]='\0';
sprintf(buffer, s, expr2, file2, line);
func ? _sprintf(buffer, s, expr2, func2, file2, line)
: _sprintf(buffer, s, expr2, file2, line);
}
return _desktop_report(buffer, NULL);
}
......
......@@ -47,14 +47,27 @@ void _sysdie(const char *s)
}
/* from <assert.h> */
void __assert(char *expr, char *file, int line)
void __assert(const char *expr, const char *file, int line)
{
const char *s;
s = _kernel_getmessage("*** assertion failed: %s, file %s, line %d", "C34");
if (!_sys__assert(s, expr, file, line))
if (!_sys__assert(s, expr, NULL, file, line)) {
_fprintf_lf(stderr, s, expr, file, line);
fputc('\n', stderr);
}
abort();
}
void __assert2(const char *expr, const char *func, const char *file, int line)
{
const char *s;
s = _kernel_getmessage_def("*** assertion failed: %s, function %s, file %s, line %d", "C73");
if (!_sys__assert(s, expr, func, file, line)) {
_fprintf_lf(stderr, s, expr, func, file, line);
fputc('\n', stderr);
}
abort();
}
......
......@@ -35,6 +35,7 @@
#include "hostsys.h"
#include <limits.h>
#include <float.h>
#include <errno.h>
/* This file contains code for most of the math routines from <math.h> */
......@@ -63,7 +64,7 @@ double frexp(double d, int *lvn)
int n;
if (d==0.0)
{ *lvn = 0;
return 0.0;
return d;
}
d1.d = d;
if ((n = d1.i.x - 0x3fe) == -0x3fe)
......@@ -73,8 +74,9 @@ double frexp(double d, int *lvn)
/* suitable nonzero bit appears to go in the implicit-bit place in the */
/* fractional result. For each bit shifted I need to adjust the final */
/* exponent that will be returned. */
/* I have already tested to see if d was zero so the fllowing loop MUST */
/* I have already tested to see if d was zero so the following loop MUST */
/* terminate. */
n++;
do
{ flag = d1.i.mhi & 0x00080000;
d1.i.mhi = (d1.i.mhi << 1) | (d1.i.mlo >> 31);
......@@ -82,11 +84,46 @@ double frexp(double d, int *lvn)
n--;
} while (flag==0);
}
else if (n == 0x401)
{
/* Here d1 has 0x7ff in its exponent field - it's a NaN or infinity */
*lvn = (d1.i.mhi || d1.i.mlo) ? FP_ILOGBNAN : INT_MAX;
return d1.d;
}
*lvn = n;
d1.i.x = 0x3fe;
return d1.d;
}
float frexpf(float s, int *lvn)
{
fp_number_single s1;
int n;
if (s==0.0F)
{ *lvn = 0;
return s;
}
s1.s = s;
if ((n = s1.i.x - 0x7e) == -0x7e)
{ int flag;
n++;
do
{ flag = s1.i.m & 0x00400000;
s1.i.m = s1.i.m << 1;
n--;
} while (flag==0);
}
else if (n == 0x81)
{
/* Here d1 has 0xff in its exponent field - it's a NaN or infinity */
*lvn = (s1.i.m) ? FP_ILOGBNAN : INT_MAX;
return s1.s;
}
*lvn = n;
s1.i.x = 0x7e;
return s1.s;
}
#else /* DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS */
double frexp(double d, int *lvn)
......@@ -94,7 +131,7 @@ double frexp(double d, int *lvn)
fp_number d1;
if (d==0.0)
{ *lvn = 0;
return 0.0;
return d;
}
d1.d = d;
*lvn = d1.i.x - 0x3fe;
......@@ -102,29 +139,246 @@ double frexp(double d, int *lvn)
return d1.d;
}
float frexpf(float s, int *lvn)
{
fp_number_single s1;
int n;
if (s==0.0F)
{ *lvn = 0;
return s;
}
s1.s = s;
*lvn = s1.i.x - 0x7e;
s1.i.x = 0x7e;
return s1.s;
}
#endif /* DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS */
double ldexp(double d, int n)
double scalbln(double d, long int n)
{
fp_number d1;
int nx;
if (d==0.0) return 0.0; /* special case */
d1.d = d;
nx = (int) d1.i.x + n;
if (nx >= 0x7ff)
fp_number x;
long int exponent;
if (n == 0 || d == 0.0) return d;
x.d = d;
exponent = x.i.x;
if (exponent == 0x7ff) return d; /* NaN or infinite */
#ifndef DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS
if (exponent == 0) /* starting subnormal */
{ int flag;
exponent++;
do
{ flag = x.i.mhi & 0x00080000;
x.i.mhi = (x.i.mhi << 1) | (x.i.mlo >> 31);
x.i.mlo = x.i.mlo << 1;
exponent--;
} while (flag==0);
}
#endif
if (n > 0x1000 || exponent + n >= 0x7ff) /* overflow */
{ errno = ERANGE;
return HUGE_VAL; /* overflow yields 'infinity' */
return x.i.s ? -HUGE_VAL : HUGE_VAL;
}
/* Maybe I should be prepared to generate un-normalized numbers here, or */
/* even deal with input d un-normalized and n positive yielding a proper */
/* result. All that seems like a lot of work and so I will not even try */
/* in this version of the code! */
else if (nx <= 0) return 0.0; /* deal with underflow */
d1.i.x = nx;
return (d1.d);
if (n < -0x1000 || exponent + n <= -53) /* total underflow */
{ x.i.x = x.i.mhi = x.i.mlo = 0;
errno = ERANGE;
return x.d;
}
if (exponent + n <= 0) /* subnormal result */
{ unsigned round = 0, hi;
n = 1 - (exponent + n);
hi = 0x00100000 | x.i.mhi;
if (n >= 32)
{ round = x.i.mlo;
x.i.mlo = hi;
hi = 0;
n -= 32;
}
if (n > 0)
{ round = (x.i.mlo << (32-n)) | (round != 0);
x.i.mlo = (hi << (32-n)) | (x.i.mlo >> n);
hi = hi >> n;
}
x.i.mhi = hi;
x.i.x = 0;
/* perform round-to-nearest; to even in tie cases */
if (round > 0x80000000 ||
(round == 0x80000000 && (x.i.mlo & 1)))
if (++x.i.mlo == 0)
if (++x.i.mhi == 0)
x.i.x = 1;
if (round != 0) errno = ERANGE; /* only if inexact */
return x.d;
}
/* normal result */
x.i.x = (int) (exponent + n);
return x.d;
}
float scalblnf(float s, long int n)
{
fp_number_single x;
long int exponent;
if (n == 0 || s == 0.0F) return s;
x.s = s;
exponent = x.i.x;
if (exponent == 0xff) return s; /* NaN or infinite */
#ifndef DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS
if (exponent == 0) /* starting subnormal */
{ int flag;
exponent++;
do
{ flag = x.i.m & 0x00400000;
x.i.m = x.i.m << 1;
exponent--;
} while (flag==0);
}
#endif
if (n > 0x1000 || exponent + n >= 0xff) /* overflow */
{ errno = ERANGE;
return x.i.s ? -HUGE_VALF : HUGE_VALF;
}
if (n < -0x1000 || exponent + n <= -24) /* total underflow */
{ x.i.x = x.i.m = 0;
errno = ERANGE;
return x.s;
}
if (exponent + n <= 0) /* subnormal result */
{ unsigned round, m;
n = 1 - (exponent + n);
m = 0x00800000 | x.i.m;
round = m << (32-n);
x.i.m = m >> n;
x.i.x = 0;
/* perform round-to-nearest; to even in tie cases */
if (round > 0x80000000 ||
(round == 0x80000000 && (x.i.m & 1)))
if (++x.i.m == 0)
x.i.x = 1;
if (round != 0) errno = ERANGE; /* only if inexact */
return x.s;
}
/* normal result */
x.i.x = (int) (exponent + n);
return x.s;
}
double scalbn(double x, int n)
{
return scalbln(x, n);
}
float scalbnf(float x, int n)
{
return scalblnf(x, n);
}
double ldexp(double x, int n)
{
return scalbn(x, n);
}
float ldexpf(float x, int n)
{
return scalbnf(x, n);
}
int ilogb(double d)
{
fp_number x;
int exponent;
if (d == 0.0)
{ errno = ERANGE;
return FP_ILOGB0;
}
x.d = d;
exponent = x.i.x;
#ifndef DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS
if (exponent == 0)
{ int flag;
exponent = 1;
do
{ flag = x.i.mhi & 0x00080000;
x.i.mhi = (x.i.mhi << 1) | (x.i.mlo >> 31);
x.i.mlo = x.i.mlo << 1;
exponent--;
} while (flag==0);
}
else if (exponent == 0x7ff)
{ if (x.i.mhi || x.i.mlo)
return FP_ILOGBNAN;
else
return INT_MAX;
}
#endif
return exponent - 0x3ff;
}
int ilogbf(float s)
{
fp_number_single x;
int exponent;
if (s == 0.0F)
{ errno = ERANGE;
return FP_ILOGB0;
}
x.s = s;
exponent = x.i.x;
#ifndef DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS
if (exponent == 0)
{ int flag;
exponent = 1;
do
{ flag = x.i.m & 0x00400000;
x.i.m = x.i.m << 1;
exponent--;
} while (flag==0);
}
else if (exponent == 0xff)
{ if (x.i.m)
return FP_ILOGBNAN;
else
return INT_MAX;
}
#endif
return exponent - 0x7f;
}
double logb(double d)
{
int x = ilogb(d);
switch (x)
{
case FP_ILOGB0: return -HUGE_VAL;
case FP_ILOGBNAN: return d;
case INT_MAX: return INFINITY;
default: return x;
}
}
float logbf(float s)
{
int x = ilogbf(s);
switch (x)
{
case FP_ILOGB0: return -HUGE_VALF;
case FP_ILOGBNAN: return s;
case INT_MAX: return INFINITY;
default: return x;
}
}
#define _exp_arg_limit 709.78271289338397
......@@ -595,11 +849,15 @@ double pow(double x, double y)
double atan2(double y, double x)
{
if (x==0.0 && y==0.0)
{ errno = EDOM;
return -HUGE_VAL;
}
if (fabs(x) < fabs(y))
if (isunordered(y, x)) return y+x;
if (y==0.0 || (isinf(x) && isfinite(y)))
return signbit(x) ? copysign(_pi_, y) : y;
if (isinf(x)) /* y must also be infinite, from above */
return copysign(x > 0 ? _pi_4 : 3*_pi_4, y);
if (fabs(x) < fabs(y)) /* handles infinite y, finite x */
{ if (fabs(x / y)<1.0e-20)
{ if (y<0.0) return - _pi_2;
else return _pi_2;
......@@ -613,6 +871,30 @@ double atan2(double y, double x)
return y;
}
float atan2f(float y, float x)
{
if (isunordered(y, x)) return y+x;
if (y==0.0F || (isinf(x) && isfinite(y)))
return signbit(x) ? copysignf((float)_pi_, y) : y;
if (isinf(x)) /* y must also be infinite, from above */
return copysignf(x > 0 ? (float)_pi_4 : (float)(3*_pi_4), y);
if (fabsf(x) < fabsf(y)) /* handles infinite y, finite x */
{ if (fabsf(x / y)<1.0e-12F)
{ if (y<0.0F) return (float) - _pi_2;
else return (float) _pi_2;
}
}
y = atanf(y / x);
if (x<0.0F)
{ if (y>0.0F) y -= (float) _pi_;
else y += (float) _pi_;
}
return y;
}
#ifndef HOST_HAS_TRIG
double hypot(double x, double y)
{
......@@ -701,8 +983,9 @@ double sinh(double x)
{
int sign;
double y;
if (x<0.0) y = -x, sign = 1; else y = x, sign = 0;
if (y>1.0)
if (x==0) return x;
if (isless(x,0.0)) y = -x, sign = 1; else y = x, sign = 0;
if (isgreater(y,1.0))
{
/* _sinh_lnv is REQUIRED to read in as a number with the lower part of */
/* its floating point representation zero. */
......@@ -711,7 +994,8 @@ double sinh(double x)
#define _sinh_v2m1 0.13830277879601902638e-4 /* (v/2) - 1 */
double w = y - _sinh_lnv, z, r;
if (w>_exp_arg_limit)
{ errno = ERANGE;
{ if (isinf(x)) return x;
errno = ERANGE;
if (sign) return -HUGE_VAL;
else return HUGE_VAL;
}
......@@ -721,7 +1005,7 @@ double sinh(double x)
if (sign) return -r;
else return r;
}
else if (y<=1.0e-10) return x;
else if (!isgreater(y,1.0e-10)) return x;
else
{
#define _sinh_p0 -0.35181283430177117881e6
......@@ -743,12 +1027,12 @@ double sinh(double x)
double cosh(double x)
{
if (x<0.0) x = -x;
if (x>1.0)
{
x = x - _sinh_lnv;
x = fabs(x);
if (isgreater(x,1.0))
{ x = x - _sinh_lnv;
if (x>_exp_arg_limit)
{ errno = ERANGE;
{ if (isinf(x)) return x;
errno = ERANGE;
return HUGE_VAL;
}
x = exp(x); /* the range check above ensures that this does */
......@@ -768,11 +1052,11 @@ double tanh(double x)
/* The first two exits avoid premature overflow as well as needless use */
/* of the exp() function. */
int sign;
if (x>27.0) return 1.0; /* here exp(2x) dominates 1.0 */
else if (x<-27.0) return -1.0;
if (x<0.0) x = -x, sign = 1;
if (isgreater(x,27.0)) return 1.0; /* here exp(2x) dominates 1.0 */
else if (isless(x,-27.0)) return -1.0;
if (isless(x,0.0)) x = -x, sign = 1;
else sign = 0;
if (x>0.549306144334054846) /* ln(3)/2 is crossover point */
if (isgreater(x,0.549306144334054846)) /* ln(3)/2 is crossover point */
{ x = exp(2.0*x);
x = 1.0 - 2.0/(x + 1.0);
if (sign) return -x;
......@@ -785,7 +1069,7 @@ double tanh(double x)
#define _tanh_q1 0.22337720718962312926e4
#define _tanh_q2 0.11274474380534949335e3
#define _tanh_q3 1.0
if (x>1.0e-10)
if (isgreater(x,1.0e-10))
{ double y = x*x;
/* minimax rational approximation */
y = (((_tanh_p2*y + _tanh_p1)*y + _tanh_p0)*y) /
......@@ -796,6 +1080,100 @@ double tanh(double x)
else return x;
}
/* Simple forms for now */
float coshf(float x)
{
return (float)cosh(x);
}
float sinhf(float x)
{
return (float)sinh(x);
}
float tanhf(float x)
{
return (float)tanh(x);
}
double asinh(double x)
{
if (isless(x, 0.0))
return -asinh(-x);
if (x == 0) return x; // asinh(0) returns 0
return log(x+hypot(x,1.0));
}
double acosh(double x)
{
if (isless(x, 1.0))
{ errno = EDOM;
return NAN;
}
// acosh(0) = 2.0*log(sqrt(1)+sqrt(0)) = 2.0*log(1) = +0
return 2.0*log(sqrt((x+1)*0.5)+sqrt((x-1)*0.5));
}
double atanh(double x)
{
if (isless(x, 0.0))
return -atanh(-x);
if (x == 0) return x; // atanh(0) returns 0
if (isgreater(x, 1.0))
{ errno = EDOM;
return NAN;
}
if (x == 1) // atanh(1) returns inf
{ errno = ERANGE;
return HUGE_VAL;
}
return 0.5*log((1+x)/(1-x));
}
float asinhf(float x)
{
if (isless(x, 0.0F))
return -asinhf(-x);
if (x == 0) return x; // asinhf(0) returns 0
return (float) log(x+hypot(x,1.0));
}
float acoshf(float x)
{
if (isless(x, 1.0F))
{ errno = EDOM;
return NAN;
}
// acoshf(0) = 2.0*log(sqrt(1)+sqrt(0)) = 2.0*log(1) = +0
return (float) (2.0*log(sqrt((x+1.0)*0.5)+sqrt((x-1.0)*0.5)));
}
float atanhf(float x)
{
if (isless(x, 0.0F))
return -atanhf(-x);
if (x == 0) return x; // atanhf(0) returns 0
if (isgreater(x, 1.0))
{ errno = EDOM;
return NAN;
}
if (x == 1) // atanhf(1) returns inf
{ errno = ERANGE;
return HUGE_VALF;
}
return (float) (0.5*log((1.0+x)/(1.0-x)));
}
double fmod(double x, double y)
{
/* floating point remainder of (x/y) for integral quotient. Remainder */
......@@ -823,6 +1201,34 @@ double fmod(double x, double y)
return r;
}
float fmodf(float x, float y)
{
/* floating point remainder of (x/y) for integral quotient. Remainder */
/* has same sign as x. */
float q, r;
if (y==0.0F)
{
errno = EDOM;
return -HUGE_VALF;
}
if (x==0.0F) return x;
if (y < 0.0F) y = -y;
r = modff(x/y, &q);
r = x - q * y;
/* The next few lines are an ultra-cautious scheme to ensure that the */
/* result is less than fabs(y) in value and that it has the sign of x. */
if (x > 0.0F)
{ while (r >= y) r -= y;
while (r < 0.0F) r += y;
}
else
{ while (r <= -y) r += y;
while (r > 0.0F) r -= y;
}
return r;
}
#if 0
double (floor)(double d)
{
/* round x down to an integer towards minus infinity. */
......@@ -855,7 +1261,7 @@ double (ceil)(double d)
/* round x up to an integer towards plus infinity. */
fp_number x;
int exponent, mask, exact;
if (d == 0.0) return 0.0;
if (d == 0.0) return d;
x.d = d; /* pun on union type */
if ((exponent = x.i.x - 0x3ff) < 0)
{ if (x.i.s) return 0.0;
......@@ -876,10 +1282,11 @@ double (ceil)(double d)
if (exact!=0 && x.i.s==0) return x.d + 1.0;
else return x.d;
}
#endif
/*double (ceil)(double x) { return ceil(x); }*/
double (ceil)(double x) { return ceil(x); }
float (ceilf)(float x) { return ceilf(x); }
/*double (floor)(double x) { return floor(x); }*/
double (floor)(double x) { return floor(x); }
float (floorf)(float x) { return floorf(x); }
double (rint)(double x) { return rint(x); }
float (rintf)(float x) { return rintf(x); }
......@@ -889,11 +1296,11 @@ double (trunc)(double x) { return trunc(x); }
float (truncf)(float x) { return truncf(x); }
double (atan)(double x) { return atan(x); }
/*float (atanf)(float x) { return atanf(x); }*/
float (atanf)(float x) { return atanf(x); }
double (sin)(double x) { return sin(x); }
/*float (sinf)(float x) { return sinf(x); }*/
float (sinf)(float x) { return sinf(x); }
double (cos)(double x) { return cos(x); }
/*float (cosf)(float x) { return cosf(x); }*/
float (cosf)(float x) { return cosf(x); }
double modf(double value, double *iptr)
{
......@@ -901,17 +1308,17 @@ double modf(double value, double *iptr)
fp_number x;
int exponent, mask;
if (value == 0.0)
{ *iptr = 0.0;
return 0.0;
{ *iptr = value;
return value;
}
x.d = value;
if ((exponent = x.i.x - 0x3ff) < 0)
{ *iptr = 0.0;
{ *iptr = copysign(0.0, value);
return value;
}
else if (exponent >= 52)
{ *iptr = value;
return 0.0;
return copysign(0.0, value);
}
if (exponent >= 20)
{ mask = ((unsigned) 0xffffffff) >> (exponent - 20);
......@@ -926,6 +1333,30 @@ double modf(double value, double *iptr)
return value - x.d;
}
float modff(float value, float *iptr)
{
/* splits value into integral part & fraction (both same sign) */
fp_number_single x;
int exponent, mask;
if (value == 0.0F)
{ *iptr = value;
return value;
}
x.s = value;
if ((exponent = x.i.x - 0xff) < 0)
{ *iptr = copysignf(0.0F, value);
return value;
}
else if (exponent >= 23)
{ *iptr = value;
return copysignf(0.0F, value);
}
mask = 0x7fffff >> exponent;
x.i.m &= ~mask;
*iptr = x.s;
return value - x.s;
}
double nan(const char *s)
{
return (double) NAN;
......@@ -952,6 +1383,331 @@ float fdimf(float x, float y)
return x - y; /* Will return NaN for NaN input */
}
#define _sqrt2pi 2.50662827463100050242
/*
* Gamma functions computed using Lanczos' approximation.
* Double version uses coefficients computed as per Spouge (1994)
* to achieve (theoretically) < 1 ulp error.
* Float version uses original Lanczos coefficients.
*
* Lanczos' approximation:
*
* G(x+1) = (x+a)^(x+.5)* e^-(x+a) * sqrt(2*pi) *
* [ c0 + c1/(x+1) + c2/(x+3).. + cn/(x+n) ] (x > 0)
*
*
* Spouge's coefficients:
* c0 = 1
* c[k] = (-1)^(k-1) * e^(a-k) * (a-k)^(k-0.5) ( 1 <= k < ceil(a) )
* ------------------------------------
* sqrt(2*pi) * (k-1)!
*
* giving relative error < sqrt(a) * (2*pi)^-(a+0.5) / (a+x)
*
* Useful relations: gamma(x+1) = x*gamma(x)
* gamma(1-x) = pi / (gamma(x)*sin(pi*x))
* gamma(n+1) = n!
*/
#define _lgamma_c1 166599025.853949811570 // actually c[k]*sqrt(2*pi)
#define _lgamma_c2 -981939810.195007931170
#define _lgamma_c3 2548964102.46316408700
#define _lgamma_c4 -3836248618.43839895348
#define _lgamma_c5 3709080184.61731236844
#define _lgamma_c6 -2412708472.49486138749
#define _lgamma_c7 1075449464.75190680642
#define _lgamma_c8 -328534715.011179056348
#define _lgamma_c9 67752870.4715251633277
#define _lgamma_c10 -9145761.20044444915581
#define _lgamma_c11 768402.637723269577278
#define _lgamma_c12 -37175.9448951564986832
#define _lgamma_c13 917.944248521710658895
#define _lgamma_c14 -9.51510944794615044564
#define _lgamma_c15 0.0294177178100457006509
#define _lgamma_c16 -1.37185031730621246722e-5
#define _lgamma_c17 1.72316912091954830013e-10
#define _lgamma_c18 -2.50065513100139951901e-20
static inline double _gamma_sum(double x)
{
/* Do it like this to avoid using client static data for an array */
return _sqrt2pi
+ _lgamma_c1 / (x + 1)
+ _lgamma_c2 / (x + 2)
+ _lgamma_c3 / (x + 3)
+ _lgamma_c4 / (x + 4)
+ _lgamma_c5 / (x + 5)
+ _lgamma_c6 / (x + 6)
+ _lgamma_c7 / (x + 7)
+ _lgamma_c8 / (x + 8)
+ _lgamma_c9 / (x + 9)
+ _lgamma_c10 / (x + 10)
+ _lgamma_c11 / (x + 11)
+ _lgamma_c12 / (x + 12)
+ _lgamma_c13 / (x + 13)
+ _lgamma_c14 / (x + 14)
+ _lgamma_c15 / (x + 15)
+ _lgamma_c16 / (x + 16)
+ _lgamma_c17 / (x + 17)
+ _lgamma_c18 / (x + 18);
}
#define _lgammaf_c0 1.000000000190015
#define _lgammaf_c1 76.18009172947146
#define _lgammaf_c2 -86.50532032941677
#define _lgammaf_c3 24.01409824083091
#define _lgammaf_c4 -1.231739572450155
#define _lgammaf_c5 1.208650973866179e-3
#define _lgammaf_c6 -5.395239384953e-6
static inline double _gammaf_sum(double x)
{
return _lgammaf_c0
+ _lgammaf_c1 / (x + 1)
+ _lgammaf_c2 / (x + 2)
+ _lgammaf_c3 / (x + 3)
+ _lgammaf_c4 / (x + 4)
+ _lgammaf_c5 / (x + 5)
+ _lgammaf_c6 / (x + 6);
}
double lgamma(double x)
{
if (isinf(x)) return INFINITY;
if (isnan(x)) return x;
if (x < 1)
{
if (floor(x) == x)
{ errno = ERANGE;
return HUGE_VAL;
}
return log(fabs((1-x)*_pi_/sin(_pi_*x)))-lgamma(2-x);
}
if (x == 1 || x == 2) return +0;
return (x+0.5)*log(x+18.5) - (x+18.5) + log(_gamma_sum(x) / x);
}
float lgammaf(float x)
{
if (isinf(x)) return INFINITY;
if (isnan(x)) return x;
if (x < 1)
{
if (floorf(x) == x)
{ errno = ERANGE;
return HUGE_VALF;
}
return (float) log(fabs((1.0-x)*_pi_/sin(_pi_*x)))-lgammaf(2-x);
}
if (x == 1 || x == 2) return +0;
return (float) ((x+0.5)*log(x+5.5) - (x+5.5) + log(_sqrt2pi * _gammaf_sum(x) / x));
}
double tgamma(double x)
{
if (isinf(x))
{ if (x > 0)
return x;
else
{ errno = ERANGE;
return NAN;
}
}
if (isnan(x)) return x;
if (x == 0)
{ errno = ERANGE;
return copysign(HUGE_VAL, x);
}
if (floor(x) == x)
{
if (x < 0)
{ errno = EDOM;
return NAN;
}
else if (x <= 171)
{ double r = 1;
for (int n = (int) x - 1; n > 1; n--)
r *= n;
return r;
}
}
if (x < 1)
return (1-x)*_pi_/(sin(_pi_*x)*tgamma(2-x));
return exp(lgamma(x));
}
float tgammaf(float x)
{
if (isinf(x))
{ if (x > 0)
return x;
else
{ errno = ERANGE;
return NAN;
}
}
if (isnan(x)) return x;
if (x == 0)
{ errno = ERANGE;
return copysignf(HUGE_VALF, x);
}
if (floorf(x) == x)
{
if (x < 0)
{ errno = EDOM;
return NAN;
}
else if (x <= 35)
{
float r = 1;
for (int n = (int) x - 1; n > 1; n--)
r *= n;
return r;
}
}
if (x < 1)
return (float) ((1.0-x)*_pi_/(sin(_pi_*x)*tgammaf(2-x)));
return expf(lgammaf(x));
}
/* Error function algorithms derived from "Numerical recipes in C" */
#define _log_sqrt_pi 0.5723649429247000870717137 // == lgamma(0.5)
/* Series calculation for incomplete gamma function P(0.5,x); good for */
/* x <= 1.5. */
static double gser05(double x, double epsilon)
{
double sum,del,ap;
ap = 0.5;
del = sum = 2;
for (;;)
{ ++ap;
del *= x/ap;
sum += del;
if (fabs(del) < fabs(sum)*epsilon)
return sum*exp(-x+0.5*log(x)-_log_sqrt_pi);
}
}
/* Continued fraction calculation for incomplete gamma function */
/* 1 - P(0.5,x); good for x >= 1.5. */
static double gcf05(double x, double epsilon)
{
double an,b,c,d,del,h;
#define FPMIN 1e-300
b = x+0.5;
c = 1/FPMIN;
d = 1/b;
h = d;
for (int i=1; ; i++)
{ an = i*(0.5-i);
b += 2;
d = an*d+b;
if (fabs(d) < FPMIN) d = FPMIN;
c = b + an/c;
if (fabs(c) < FPMIN) c = FPMIN;
d = 1/d;
del = d*c;
h *= del;
if (fabs(del-1) < epsilon) break;
}
return exp(-x+0.5*log(x)-_log_sqrt_pi)*h;
}
static double gammp05(double x, double epsilon)
{
if (isunordered(x, 1.5))
return x;
else if (isless(x, 1.5))
return gser05(x,epsilon);
else
return 1 - gcf05(x,epsilon);
}
static double gammq05(double x, double epsilon)
{
if (isunordered(x, 1.5))
return x;
else if (isless(x, 1.5))
return 1 - gser05(x,epsilon);
else
return gcf05(x,epsilon);
}
double erf(double x)
{
if (x == 0) return x;
if (isless(x, 0.0)) return -erf(-x);
if (isgreater(x, 1e100)) return 1.0;
return gammp05(x*x, 3*DBL_EPSILON);
}
double erfc(double x)
{
if (isgreater(fabs(x), 1e100)) return isless(x, 0.0) ? 2 : 0;
return isless(x, 0.0) ? 1+gammp05(x*x, 3*DBL_EPSILON)
: gammq05(x*x, 3*DBL_EPSILON);
}
float erff(float x)
{
if (x == 0) return x;
if (isless(x, 0.0)) return -erff(-x);
if (isgreater(x, 1e15F)) return 1.0F;
return (float) gammp05((double) x*x, 3.0*FLT_EPSILON);
}
#define _erfcf_c0 -1.26551223
#define _erfcf_c1 1.00002368
#define _erfcf_c2 0.37409196
#define _erfcf_c3 0.09678418
#define _erfcf_c4 -0.18628806
#define _erfcf_c5 0.27886807
#define _erfcf_c6 -1.13520398
#define _erfcf_c7 1.48851586
#define _erfcf_c8 -0.82215223
#define _erfcf_c9 0.17087277
float erfcf(float x)
{
double t,r;
if (isgreater(fabsf(x), 1e15F)) return isless(x, 0.0F) ? 2 : 0;
t = 1/(1+0.5*fabsf(x));
r = (((((((((_erfcf_c9) * t + _erfcf_c8) * t + _erfcf_c7) * t +
_erfcf_c6) * t + _erfcf_c5) * t + _erfcf_c4) * t +
_erfcf_c3) * t + _erfcf_c2) * t + _erfcf_c1) * t +
_erfcf_c0;
r = t*exp(r - (double)x*x);
return (float) (isless(x, 0.0F) ? 2-r : r);
}
#endif /* NO_FLOATING_POINT */
/* end of math.c */
......@@ -94,10 +94,32 @@ typedef struct __extradata {
int __buflim; /* used size of buffer */
int __savedicnt; /* after unget contains old icnt */
int __savedocnt; /* after unget contains old ocnt */
#ifdef SUPPORT_WIDE
int __orientation;
mbstate_t __mbstate; /* must be stored in fpos_t */
#endif
} _extradata, *_extradatap;
static _extradatap _extra;
#ifdef SUPPORT_WIDE
#define O_NONE 0
#define O_BYTE (-1)
#define O_WIDE (+1)
#define ORIENTATION(stream) ((stream)->__extrap->__orientation)
#define BYTEORIENT(stream) (ORIENTATION(stream) == 0 ? \
ORIENTATION(stream) = O_BYTE : \
ORIENTATION(stream))
#define ENSUREBYTE(stream,e) do { if (BYTEORIENT(stream) != O_BYTE) return e; } while (0)
#define WIDEORIENT(stream) (ORIENTATION(stream) == 0 ? \
ORIENTATION(stream) = O_WIDE : \
ORIENTATION(stream))
#define ENSUREWIDE(stream,e) do { if (WIDEORIENT(stream) != O_WIDE) return e; } while (0)
#else
#define BYTEORIENT(stream)
#define ENSUREBYTE(stream,e)
#endif
#define EXTENT(stream) ((stream)->__extrap->__extent > (stream)->__ptr \
? (stream)->__extrap->__extent : (stream)->__ptr)
......@@ -222,6 +244,7 @@ int __backspace(FILE *stream)
int ungetc(int c,FILE *stream)
{ /* made into a fn to evaluate each arg once. */
ENSUREBYTE(stream, EOF);
if (c==EOF || (stream->__flag & (_IOUNGET+_IONOREADS))) return EOF;
/* put char into unget buffer */
stream->__extrap->__lilbuf[1] = c;
......@@ -808,6 +831,7 @@ size_t fread(void *ptr, size_t itemsize, size_t count, FILE *stream)
* is concerned and that the number of WHOLE items read is returned.
*/
dbmsg("fread %d\n", count);
ENSUREBYTE(stream, 0);
return itemsize == 0 ? 0 /* slight ansi irrationality */
: _read(ptr, itemsize*count, stream) / itemsize;
}
......@@ -917,6 +941,7 @@ size_t fwrite(const void *ptr, size_t itemsize, size_t count, FILE *stream)
/* The comments made about fread apply here too */
dbmsg_noNL("fwrite %d ", count);
dbmsg("itemsize %d (decimal)\n", itemsize);
ENSUREBYTE(fwrite, 0);
return itemsize == 0 ? count
: _write(ptr, itemsize*count, stream) / itemsize;
}
......
......@@ -154,23 +154,27 @@ void exit(int n)
_exit(n);
}
void _Exit(int n)
{
/* Is this the best way of doing this? abort() probably shouldn't be calling
* atexit functions either...
*/
while (exit_s.number_of_exit_functions!=0) {
int flags = _exitvector[exit_s.number_of_exit_functions].i;
if ((flags & 3) != 0) { ++exit_s.number_of_exit_functions; break; };
}
_exit(n);
}
void abort()
{
raise(SIGABRT);
exit(1);
}
int abs(int x)
{
if (x<0) return (-x);
else return x;
}
int (abs)(int x) { return abs(x); }
long int labs(long int x)
{
if (x<0) return (-x);
else return x;
}
long int (labs)(long int x) { return labs(x); }
#if 0
/* Compiler generates poo code at the minute - in machine code for now */
......
......@@ -349,15 +349,17 @@ size_t strxfrm(char *s1, const char *s2, size_t n)
int strcoll(const char *a, const char *b)
{
int ret;
_kernel_swi_regs r;
if (strcoll_territory == 0) return strcmp(a, b); /* C locale */
if (_swix(Territory_Collate, _INR(0,3)|_OUT(0),
strcoll_territory, a, b, 0,
&ret))
r.r[0] = strcoll_territory;
r.r[1] = (int) a;
r.r[2] = (int) b;
r.r[3] = 0;
if (_kernel_swi(Territory_Collate, &r, &r))
return 0;
return ret;
return r.r[0];
}
void _set_strcoll(int territory)
......
......@@ -74,3 +74,6 @@ C70:unknown error
#{DictTokens}
C71:Calling standard APCS-A no longer supported by C library
C72:Application is not 32-bit compatible
#{Default}
C73:*** assertion failed: %s, function %s, file %s, line %d
......@@ -14,19 +14,20 @@
*/
#pragma force_top_level
/* assert.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.2 */
/* assert.h: ISO 'C' (9899:1999) library header, section 7.2 */
/* Copyright (C) Codemist Ltd. */
/* Copyright (C) Acorn Computers Ltd. 1991, 1992 */
/* version 2.00 */
/* version 2.01 */
/*
* The assert macro puts diagnostics into programs. When it is executed,
* if its argument expression is false, it writes information about the
* call that failed (including the text of the argument, the name of the
* source file, and the source line number - the latter are respectively
* the values of the preprocessing macros __FILE__ and __LINE__) on the
* source file, the source line number, and the name of the enclosing
* function - the latter are respectively the values of the preprocessing
* macros __FILE__ and __LINE__ and of the identifier __func__) on the
* standard error stream. It then calls the abort function.
* If its argument expression is true, the assert macro returns no value.
* The assert macro returns no value.
*/
/*
......@@ -38,9 +39,11 @@
#ifndef __assert_h
# define __assert_h
#ifdef __cplusplus
extern "C" void __assert(char *, char *, int);
extern "C" void __assert(const char *, const char *, int);
extern "C" void __assert2(const char *, const char *, const char *, int);
#else
extern void __assert(char *, char *, int);
extern void __assert(const char *, const char *, int);
extern void __assert2(const char *, const char *, const char *, int);
#endif
#else
# undef assert
......@@ -50,6 +53,12 @@
# define assert(ignore) ((void)0)
#else
# define assert(e) ((e) ? (void)0 : __assert(#e, __FILE__, __LINE__))
# ifdef __STDC_VERSION__
# if __STDC_VERSION__ >= 199901
# undef assert
# define assert(e) ((e) ? (void)0 : __assert2(#e, __func__, __FILE__, __LINE__))
# endif
# endif
#endif
/* end of assert.h */
......@@ -15,7 +15,7 @@
#pragma force_top_level
#pragma include_only_once
/* ctype.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.3 */
/* ctype.h: ISO 'C' (9899:1999) library header, section 7.4 */
/* Copyright (C) Codemist Ltd. */
/* Copyright (C) Acorn Computers Ltd. 1991, 1992 */
/* version 2.00 */
......@@ -89,27 +89,27 @@ extern unsigned char __ctype[];
/* non-0 iff c is a digit, in 'a'..'f', or in 'A'..'F' */
#ifndef __cplusplus
extern int (isalnum)(int c);
extern int (isalpha)(int c);
extern int (iscntrl)(int c);
extern int (isdigit)(int c);
extern int (isgraph)(int c);
extern int (islower)(int c);
extern int (isprint)(int c);
extern int (ispunct)(int c);
extern int (isspace)(int c);
extern int (isupper)(int c);
extern int (isxdigit)(int c);
int (isalnum)(int c);
int (isalpha)(int c);
int (iscntrl)(int c);
int (isdigit)(int c);
int (isgraph)(int c);
int (islower)(int c);
int (isprint)(int c);
int (ispunct)(int c);
int (isspace)(int c);
int (isupper)(int c);
int (isxdigit)(int c);
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern int tolower(int c);
int tolower(int c);
/* if c is an upper-case letter then return the corresponding */
/* lower-case letter, otherwise return c. */
extern int toupper(int c);
int toupper(int c);
/* if c is an lower-case letter then return the corresponding */
/* upper-case letter, otherwise return c. */
#ifdef __cplusplus
......
......@@ -15,7 +15,7 @@
#pragma force_top_level
#pragma include_only_once
/* errno.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.1.3 */
/* errno.h: ISO 'C' (9899:1999) library header, section 7.5 */
/* Copyright (C) Codemist Ltd. */
/* Copyright (C) Acorn Computers Ltd. 1991, 1992 */
/* version 2.00 */
......
......@@ -15,7 +15,7 @@
#pragma force_top_level
#pragma include_only_once
/* float.h: ISO 'C' (9899 Dec 99) library header, section 5.2.4.2 */
/* float.h: ISO 'C' (9899 Dec 99) library header, section 5.2.4.2.2 */
/* Copyright (C) Codemist Ltd, 1988 */
/* Copyright (C) Acorn Computers Ltd. 1991, 1992 */
/* version 3.00 */
......@@ -50,7 +50,7 @@
* range of the double type, evaluate long double operations and
* constants to the range and precision of the long double type;
* 2 : evaluate all operations and constants to the range and precision
* of the lang double type;
* of the long double type;
* ? : all other negative values are implementation defined.
*/
......@@ -84,6 +84,8 @@
#define DBL_MAX_EXP 1024
#define LDBL_MAX_EXP 1024
/* maximum integer such that FLT_RADIX raised to that power minus 1 is a */
/* representable finite floating-point number. */
#define FLT_MAX_10_EXP 38
#define DBL_MAX_10_EXP 308
#define LDBL_MAX_10_EXP 308
......
......@@ -200,20 +200,20 @@
typedef struct imaxdiv_t { intmax_t quot, rem; } imaxdiv_t;
/* type of the value returned by the imaxdiv function. */
extern intmax_t imaxabs(intmax_t /*j*/);
intmax_t imaxabs(intmax_t /*j*/);
/*
* computes the absolute value of an integer j. If the result cannot be
* represented, the behaviour is undefined.
* Returns: the absolute value.
*/
extern imaxdiv_t imaxdiv(intmax_t /*numer*/, intmax_t /*denom*/);
imaxdiv_t imaxdiv(intmax_t /*numer*/, intmax_t /*denom*/);
/*
* computes numer / denom and numer % denom in a single operation.
* Returns: a structure of type imaxdiv_t, comprising both the quotient and
* the remainder.
*/
extern intmax_t strtoimax(const char * restrict /*nptr*/,
intmax_t strtoimax(const char * restrict /*nptr*/,
char ** restrict /*endptr*/, int /*base*/);
/*
* equivalent to the strtoll function, except that the initial portion of the
......@@ -224,7 +224,7 @@ extern intmax_t strtoimax(const char * restrict /*nptr*/,
* (according to the sign of the value), and the value of the
* macro ERANGE is stored in errno.
*/
extern uintmax_t strtoumax(const char * restrict /*nptr*/,
uintmax_t strtoumax(const char * restrict /*nptr*/,
char ** restrict /*endptr*/, int /*base*/);
/*
* equivalent to the strtoull function, except that the initial portion of
......
......@@ -15,7 +15,7 @@
#pragma force_top_level
#pragma include_only_once
/* locale.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.3 */
/* locale.h: ISO 'C' (9899:1999) library header, section 7.11 */
/* Copyright (C) Codemist Ltd. */
/* Copyright (C) Acorn Computers Ltd. 1991, 1992 */
/* version 2.00 */
......
......@@ -15,10 +15,10 @@
#pragma force_top_level
#pragma include_only_once
/* math.h: ISO 'C' (9899:1999) library header, section 7.22 */
/* math.h: ISO 'C' (9899:1999) library header, section 7.12 */
/* Copyright (C) Codemist Ltd. */
/* Copyright (C) Acorn Computers Ltd. 1991 */
/* version 0.04 */
/* version 0.05 */
#ifndef __math_h
#define __math_h
......@@ -37,6 +37,10 @@ extern const double HUGE_VAL;
#endif
#endif
#ifndef HUGE_VALL
#define HUGE_VALL ((long double) HUGE_VAL)
#endif
#ifndef __cplusplus
#ifndef HUGE_VALF
# define HUGE_VALF INFINITY
......@@ -55,14 +59,17 @@ extern const double HUGE_VAL;
/* the mutually exclusive kinds of floating-point values for fpclassify() */
#endif
#define FP_ILOGB0 (-0x7fffffff) /* -INT_MAX */
#define FP_ILOGBNAN (~0x7fffffff) /* INT_MIN */
/* integer constant expressions whose values are returned by ilogb(x) if */
/* x is zero or NaN, respectively. */
#define MATH_ERRNO 1
#define MATH_ERREXCEPT 2
#define math_errhandling MATH_ERRNO
/* <math.h> functions just set errno - no exceptions are raised */
/*#pragma no_side_effects*/
#ifdef __cplusplus
extern "C" {
#endif
......@@ -73,16 +80,16 @@ extern "C" {
#pragma no_side_effects
#pragma force_fpargs_in_regs
extern int __fpclassifyf(float);
extern int __fpclassifyd(double);
extern int __signbitf(float);
extern int __signbitd(double);
__caller_narrow int __fpclassifyf(float);
int __fpclassifyd(double);
__caller_narrow int __signbitf(float);
int __signbitd(double);
#pragma no_force_fpargs_in_regs
#pragma side_effects
#ifdef __cplusplus
#define __classmacro(fn,r) (sizeof(r) == 4 ? __##fn##f(r) : \
__##fn##d(r))
#define __classmacro(fn,r) (sizeof(r) == 4 ? __##fn##f((float)(r)) : \
__##fn##d((double)(r)))
#else
#define __assertfp(r) ___assert(___typeof(r) == 0x002 ||\
___typeof(r) == 0x202 ||\
......@@ -90,8 +97,8 @@ extern int __signbitd(double);
"Illegal type used with classification macro")
#define __classmacro(fn,r) (__assertfp(r),\
___typeof(r) == 0x402 ? __##fn##f(r) : \
__##fn##d(r))
___typeof(r) == 0x402 ? __##fn##f((float)(r)) : \
__##fn##d((double)(r)))
#endif
#define fpclassify(r) __classmacro(fpclassify,(r))
......@@ -109,232 +116,369 @@ extern int __signbitd(double);
#endif
extern double acos(double /*x*/);
double acos(double /*x*/);
float acosf(float /*x*/);
long double acosl(long double /*x*/);
/* computes the principal value of the arc cosine of x */
/* a domain error occurs for arguments not in the range -1 to 1 */
/* Returns: the arc cosine in the range 0 to Pi. */
extern double asin(double /*x*/);
double asin(double /*x*/);
float asinf(float /*x*/);
long double asinl(long double /*x*/);
/* computes the principal value of the arc sine of x */
/* a domain error occurs for arguments not in the range -1 to 1 */
/* and -HUGE_VAL is returned. */
/* Returns: the arc sine in the range -Pi/2 to Pi/2. */
extern double atan(double /*x*/);
double atan(double /*x*/);
float atanf(float /*x*/);
long double atanl(long double /*x*/);
/* computes the principal value of the arc tangent of x */
/* Returns: the arc tangent in the range -Pi/2 to Pi/2. */
extern double atan2(double /*x*/, double /*y*/);
double atan2(double /*y*/, double /*x*/);
float atan2f(float /*y*/, float /*x*/);
long double atan2l(long double /*y*/, long double /*x*/);
/* computes the principal value of the arc tangent of y/x, using the */
/* signs of both arguments to determine the quadrant of the return value */
/* a domain error occurs if both args are zero, and -HUGE_VAL returned. */
/* Returns: the arc tangent of y/x, in the range -Pi to Pi. */
extern double __d_atan(double);
#define atan(x) __d_atan(x)
#ifndef __cplusplus
extern __caller_narrow float __r_atan(float);
#define atanf(x) __r_atan(x)
#endif
extern double cos(double /*x*/);
double cos(double /*x*/);
float cosf(float /*x*/);
long double cosl(long double /*x*/);
/* computes the cosine of x (measured in radians). A large magnitude */
/* argument may yield a result with little or no significance */
/* Returns: the cosine value. */
extern double sin(double /*x*/);
double sin(double /*x*/);
float sinf(float /*x*/);
long double sinl(long double /*x*/);
/* computes the sine of x (measured in radians). A large magnitude */
/* argument may yield a result with little or no significance */
/* Returns: the sine value. */
extern double __d_cos(double);
extern double __d_sin(double);
#define cos(x) __d_cos(x)
#define sin(x) __d_sin(x)
#ifndef __cplusplus
extern __caller_narrow float __r_sin(float);
extern __caller_narrow float __r_cos(float);
#define sinf(x) __r_sin(x)
#define cosf(x) __r_cos(x)
#endif
extern double tan(double /*x*/);
double tan(double /*x*/);
float tanf(float /*x*/);
long double tanl(long double /*x*/);
/* computes the tangent of x (measured in radians). A large magnitude */
/* argument may yield a result with little or no significance */
/* Returns: the tangent value. */
/* if range error; returns HUGE_VAL. */
extern double cosh(double /*x*/);
double acosh(double /*x*/);
float acoshf(float /*x*/);
long double acoshl(long double /*x*/);
/* computes the (non-negative) arc hyperbolic cosine of x. */
/* A domain error occurs for arguments less than 1. */
/* Returns: arcosh x in the interval [0,+inf] */
double asinh(double /*x*/);
float asinhf(float /*x*/);
long double asinhl(long double /*x*/);
/* computes the arc hyperbolic sine of x. */
/* Returns: arsinh x */
double atanh(double /*x*/);
float atanhf(float /*x*/);
long double atanhl(long double /*x*/);
/* computes the arc hyperbolic tangent of x. A domain error occurs */
/* for arguments not in the interval [-1,+1]. A range error occurs */
/* if the argument equals -1 or +1. */
/* Returns: artanh x */
double cosh(double /*x*/);
float coshf(float /*x*/);
long double coshl(long double /*x*/);
/* computes the hyperbolic cosine of x. A range error occurs if the */
/* magnitude of x is too large. */
/* Returns: the hyperbolic cosine value. */
/* if range error; returns HUGE_VAL. */
extern double sinh(double /*x*/);
double sinh(double /*x*/);
float sinhf(float /*x*/);
long double sinhl(long double /*x*/);
/* computes the hyperbolic sine of x. A range error occurs if the */
/* magnitude of x is too large. */
/* Returns: the hyperbolic sine value. */
/* if range error; returns -HUGE_VAL or HUGE_VAL depending */
/* on the sign of the argument */
extern double tanh(double /*x*/);
double tanh(double /*x*/);
float tanhf(float /*x*/);
long double tanhl(long double /*x*/);
/* computes the hyperbolic tangent of x. */
/* Returns: the hyperbolic tangent value. */
extern double exp(double /*x*/);
/* computes the exponential function of x. A range error occurs if the */
double exp(double /*x*/);
float expf(float /*x*/);
long double expl(long double /*x*/);
/* computes the base-e exponential of x. A range error occurs if the */
/* magnitude of x is too large. */
/* Returns: e^x */
/* if underflow range error; 0 is returned. */
/* if overflow range error; HUGE_VAL is returned. */
double exp2(double /*x*/);
float exp2f(float /*x*/);
long double exp2l(long double /*x*/);
/* computes the base-2 exponential of x. A range error occurs if the */
/* magnitude of x is too large. */
/* Returns: the exponential value. */
/* Returns: 2^x */
/* if underflow range error; 0 is returned. */
/* if overflow range error; HUGE_VAL is returned. */
extern double frexp(double /*value*/, int * /*exp*/);
double expm1(double /*x*/);
float expm1f(float /*x*/);
long double expm1l(long double /*x*/);
/* computes the base-e exponential of x, minus 1. A range error occurs if */
/* the magnitude of x is too large. */
/* Returns: e^x - 1 */
double frexp(double /*value*/, int * /*exp*/);
float frexpf(float /*value*/, int * /*exp*/);
long double frexpl(long double /*value*/, int * /*exp*/);
/* breaks a floating-point number into a normalised fraction and an */
/* integral power of 2. It stores the integer in the int object pointed */
/* to by exp. */
/* Returns: the value x, such that x is a double with magnitude in the */
/* interval 0.5 to 1.0 or zero, and value equals x times 2 raised to the */
/* power *exp. If value is zero, both parts of the result are zero. */
extern double ldexp(double /*x*/, int /*exp*/);
int ilogb(double /*x*/);
int ilogbf(float /*x*/);
int ilogbl(long double /*x*/);
/* extracts the exponent of x as a signed int value. If x is zero it */
/* computes the value FP_ILOGB0; if x is infinite it computes the value */
/* INT_MAX; if x is a NaN it computes the value FP_ILOGBNAN; otherwise it */
/* is equivalent to calling the corresponding logb function and casting */
/* the returned value to type int. A range error occurs if x is 0. */
/* Returns: the exponent of x as a signed int value. */
double ldexp(double /*x*/, int /*exp*/);
float ldexpf(float /*x*/, int /*exp*/);
long double ldexpl(long double /*x*/, int /*exp*/);
/* multiplies a floating-point number by an integral power of 2. */
/* A range error may occur. */
/* Returns: the value of x times 2 raised to the power of exp. */
/* if range error; HUGE_VAL is returned. */
extern double log(double /*x*/);
/* computes the natural logarithm of x. A domain error occurs if the */
/* argument is negative, and -HUGE_VAL is returned. A range error occurs */
/* if the argument is zero. */
double log(double /*x*/);
float logf(float /*x*/);
long double logl(long double /*x*/);
/* computes the base-e (natural) logarithm of x. A domain error occurs if */
/* the argument is negative, and -HUGE_VAL is returned. A range error */
/* occurs if the argument is zero. */
/* Returns: the natural logarithm. */
/* if range error; -HUGE_VAL is returned. */
extern double log10(double /*x*/);
/* computes the base-ten logarithm of x. A domain error occurs if the */
/* argument is negative. A range error occurs if the argument is zero. */
double log10(double /*x*/);
float log10f(float /*x*/);
long double log10l(long double /*x*/);
/* computes the base-ten (common) logarithm of x. A domain error occurs if */
/* the argument is negative. A range error occurs if the argument is zero. */
/* Returns: the base-ten logarithm. */
extern double modf(double /*value*/, double * /*iptr*/);
double log1p(double /*x*/);
float log1pf(float /*x*/);
long double log1pl(long double /*x*/);
/* computes the base-e (natural) logarithm of 1 plus the argument. A */
/* domain error occurs if the argument is less than -1. A range error */
/* occurs if the argument equals -1. */
/* Returns: the natural logarithm of (1+x). */
double log2(double /*x*/);
float log2f(float /*x*/);
long double log2l(long double /*x*/);
/* computes the base-two logarithm of x. A domain error occurs if the */
/* argument is negative. A range error occurs if the argument is zero. */
/* Returns: the base-two logarithm. */
double logb(double /*x*/);
float logbf(float /*x*/);
long double logbl(long double /*x*/);
/* extracts the exponent of x, as a signed integer value in floating- */
/* point format. If x is subnormal it is treated as though it were */
/* normalised; thus, for positive finite x, */
/* 1 <= x * FLT_RADIX ^ -logb(x) < FLT_RADIX */
/* A domain error occurs if the argument is zero. */
/* Returns: the signed exponent of x */
double modf(double /*value*/, double * /*iptr*/);
float modff(float /*value*/, float * /*iptr*/);
long double modfl(long double /*value*/, long double * /*iptr*/);
/* breaks the argument value into integral and fraction parts, each of */
/* which has the same sign as the argument. It stores the integral part */
/* as a double in the object pointed to by iptr. */
/* Returns: the signed fractional part of value. */
extern double hypot(double /*x*/, double /*y*/);
extern float hypotf(float /*x*/, float /*y*/);
double scalbn(double /*x*/, int /*n*/);
float scalbnf(float /*x*/, int /*n*/);
long double scalbnl(long double /*x*/, int /*n*/);
double scalbln(double /*x*/, long int /*n*/);
float scalblnf(float /*x*/, long int /*n*/);
long double scalblnl(long double /*x*/, long int /*n*/);
/* computes x * FLT_RADIX^n efficiently. A range error may occur. */
/* Returns: x * FLT_RADIX^n */
double cbrt(double /*x*/);
float cbrtf(float /*x*/);
long double cbrtl(long double /*x*/);
/* computes the real cube root of x. */
/* Returns: x^(1/3) */
#pragma no_side_effects
double fabs(double /*x*/);
float fabsf(float /*x*/);
long double fabsl(long double /*x*/);
/* computes the absolute value of the floating-point number x. */
/* Returns: the absolute value of x. */
#pragma side_effects
double hypot(double /*x*/, double /*y*/);
float hypotf(float /*x*/, float /*y*/);
long double hypotl(long double /*x*/, long double /*y*/);
/* computes the square root of the sum of the squares of x and y, without */
/* undue overflow or underflow. A ronge error may occur. */
/* undue overflow or underflow. A range error may occur. */
/* Returns: sqrt(x^2 + y^2) */
extern double pow(double /*x*/, double /*y*/);
double pow(double /*x*/, double /*y*/);
float powf(float /*x*/, float /*y*/);
long double powl(long double /*x*/, long double /*y*/);
/* computes x raised to the power of y. A domain error occurs if x is */
/* zero and y is less than or equal to zero, or if x is negative and y */
/* is not an integer, and -HUGE_VAL returned. A range error may occur. */
/* Returns: the value of x raised to the power of y. */
/* if underflow range error; 0 is returned. */
/* if overflow range error; HUGE_VAL is returned. */
extern double sqrt(double /*x*/);
double sqrt(double /*x*/);
float sqrtf(float /*x*/);
long double sqrtl(long double /*x*/);
/* computes the non-negative square root of x. A domain error occurs */
/* if the argument is negative, and -HUGE_VAL returned. */
/* Returns: the value of the square root. */
extern double fabs(double /*x*/);
extern float fabsf(float /*x*/);
/* computes the absolute value of the floating-point number x. */
/* Returns: the absolute value of x. */
extern double ceil(double /*x*/);
extern float ceilf(float /*x*/);
double erf(double /*x*/);
float erff(float /*x*/);
long double erfl(long double /*x*/);
/* computes the error function of x. */
/* Returns: erf x = 2/sqrt(pi) * integral[0,x] (e^(-t^2)) dt */
double erfc(double /*x*/);
float erfcf(float /*x*/);
long double erfcl(long double /*x*/);
/* computes the complementary error function of x. A range error occurs */
/* if x is too large.
/* Returns: erfc x = 1 - erf x */
/* = 2/sqrt(pi) * integral[x,inf] (e^(-t^2)) dt */
double lgamma(double /*x*/);
float lgammaf(float /*x*/);
long double lgammal(long double /*x*/);
/* computes the natural logarithm of the absolute value of gamma of x. */
/* A range error occurs if x is too large. A range error occurs if x is */
/* a negative integer or zero. */
/* Returns: log |Gamma(x)| */
double tgamma(double /*x*/);
float tgammaf(float /*x*/);
long double tgammal(long double /*x*/);
/* computes the gamma function of x. A domain error occurs if x is a */
/* negative integer or if the result cannot be represented when x is */
/* zero. A range error may occur if the magnitude of x is too large or */
/* too small. */
/* Returns: Gamma(x) */
#pragma no_side_effects
double ceil(double /*x*/);
float ceilf(float /*x*/);
long double ceill(long double /*x*/);
/* computes the smallest integer not less than x. */
/* Returns: the smallest integer not less than x, expressed as a double. */
extern double floor(double /*x*/);
extern float floorf(float /*x*/);
double floor(double /*x*/);
float floorf(float /*x*/);
long double floorl(long double /*x*/);
/* computes the largest integer not greater than x. */
/* Returns: the largest integer not greater than x, expressed as a double */
extern double nearbyint(double /*x*/);
extern float nearbyintf(float /*x*/);
double nearbyint(double /*x*/);
float nearbyintf(float /*x*/);
long double nearbyintl(long double /*x*/);
/* rounds its argument to an integer value, using the current rounding */
/* direction. Does not raise the inexact exception. */
/* Returns: the rounded integer value. */
extern double rint(double /*x*/);
extern float rintf(float /*x*/);
double rint(double /*x*/);
float rintf(float /*x*/);
long double rintl(long double /*x*/);
/* rounds its argument to an integer value, using the current rounding */
/* direction. Raises "inexact" if the result differs from the argument. */
/* Returns: the rounded integer value. */
extern long int lrint(double /*x*/);
extern long int lrintf(float /*x*/);
#pragma side_effects
long int lrint(double /*x*/);
long int lrintf(float /*x*/);
long int lrintl(long double /*x*/);
/* rounds its argument to an integer value, using the current rounding */
/* direction. Raises "inexact" if the result differs from the argument. */
/* Returns: the rounded integer value. */
extern double round(double /*x*/);
extern float roundf(float /*x*/);
#pragma no_side_effects
double round(double /*x*/);
float roundf(float /*x*/);
long double roundl(long double /*x*/);
/* rounds its argument to the nearest integer value, rounding halfway */
/* cases away from zero. */
/* Returns: the rounded integer value. */
extern long int lround(double /*x*/);
extern long int lroundf(float /*x*/);
#pragma side_effects
long int lround(double /*x*/);
long int lroundf(float /*x*/);
long int lroundl(long double /*x*/);
/* rounds its argument to the nearest integer value, rounding halfway */
/* cases away from zero. */
/* Returns: the rounded integer value. */
extern double trunc(double /*x*/);
extern float truncf(float /*x*/);
#pragma no_side_effects
double trunc(double /*x*/);
float truncf(float /*x*/);
long double truncl(long double /*x*/);
/* rounds its argument to the integer value, nearest to but no larger in */
/* magnitude than the argument. */
/* Returns: the truncated integer value. */
extern double fmod(double /*x*/, double /*y*/);
#pragma side_effects
double fmod(double /*x*/, double /*y*/);
float fmodf(float /*x*/, float /*y*/);
long double fmodl(long double /*x*/, long double /*y*/);
/* computes the floating-point remainder of x/y. */
/* Returns: the value x - i * y, for some integer i such that, if y is */
/* nonzero, the result has the same sign as x and magnitude */
/* less than the magnitude of y. If y is zero, a domain error */
/* occurs and -HUGE_VAL is returned. */
extern double remainder(double /*x*/, double /*y*/);
extern float remainderf(float /*x*/, float /*y*/);
double remainder(double /*x*/, double /*y*/);
float remainderf(float /*x*/, float /*y*/);
long double remainderl(long double /*x*/, long double /*y*/);
/* computes the remainder x REM y required by IEEE 754 */
/* Returns: x REM y */
extern double __d_abs(double);
extern double __d_floor(double);
extern double __d_ceil(double);
extern double __d_trunc(double);
extern double __d_rint(double);
extern long int __d_lrint(double);
extern float __r_abs(float);
#define fabs(x) __d_abs(x)
#define floor(x) __d_floor(x)
#define ceil(x) __d_ceil(x)
#define trunc(x) __d_trunc(x)
#define rint(x) __d_rint(x)
#define lrint(x) __d_lrint(x)
#ifndef __cplusplus
extern __caller_narrow float __r_floor(float);
extern __caller_narrow float __r_ceil(float);
extern __caller_narrow float __r_trunc(float);
extern __caller_narrow float __r_rint(float);
extern __caller_narrow long int __r_lrint(float);
#define fabsf(x) __r_abs(x)
#define floorf(x) __r_floor(x)
#define ceilf(x) __r_ceil(x)
#define truncf(x) __r_trunc(x)
#define rintf(x) __r_rint(x)
#define lrintf(x) __r_lrint(x)
#endif
#pragma no_side_effects
#ifndef __cplusplus
#pragma force_fpargs_in_regs
extern double copysign(double /*x*/, double /*y*/);
extern float copysignf(float /*x*/, float /*y*/);
double copysign(double /*x*/, double /*y*/);
__caller_narrow float copysignf(float /*x*/, float /*y*/);
long double copysignl(long double /*x*/, long double /*y*/);
#pragma no_force_fpargs_in_regs
/* produce a value with the magnitude of x and the sign of y. They */
/* produce a NaN (with the sign of y) if x is a NaN. */
/* Returns: a value with the magnitude of x and the sign of y. */
#endif
extern double nan(const char * /*tagp*/);
extern float nanf(const char * /*tagp*/);
double nan(const char * /*tagp*/);
float nanf(const char * /*tagp*/);
long double nanl(const char * /*tagp*/);
/* Returns: a quiet NaN, with content indicated through tagp. */
extern double nextafter(double /*x*/, double /*y*/);
extern float nextafterf(float /*x*/, float /*y*/);
#pragma side_effects
double nextafter(double /*x*/, double /*y*/);
float nextafterf(float /*x*/, float /*y*/);
long double nextafterl(long double /*x*/, long double /*y*/);
/* Returns: the next representable value in the specified format after */
/* x in the direction of y */
extern double fdim(double /*x*/, double /*y*/);
extern float fdimf(float /*x*/, float /*y*/);
double nexttoward(double /*x*/, long double /*y*/);
float nexttowardf(float /*x*/, long double /*y*/);
long double nexttowardl(long double /*x*/, long double /*y*/);
/* equivalent to the nextafter functions except that the second parameter */
/* has type long double. */
double fdim(double /*x*/, double /*y*/);
float fdimf(float /*x*/, float /*y*/);
long double fdiml(long double /*x*/, long double /*y*/);
/* determine the positive difference between their arguments: */
/* { x-y if x > y */
/* { +0 if x <= y */
/* A range error may occur. */
/* Returns: the positive difference value. */
extern double fmax(double /*x*/, double /*y*/);
extern float fmaxf(float /*x*/, float /*y*/);
#pragma no_side_effects
double fmax(double /*x*/, double /*y*/);
float fmaxf(float /*x*/, float /*y*/);
long double fmaxl(long double /*x*/, long double /*y*/);
/* Returns: the maximum numeric value of their arguments. */
extern double fmin(double /*x*/, double /*y*/);
extern float fminf(float /*x*/, float /*y*/);
double fmin(double /*x*/, double /*y*/);
float fminf(float /*x*/, float /*y*/);
long double fminl(long double /*x*/, long double /*y*/);
/* Returns: the minimum numeric value of their arguments. */
#pragma side_effects
double fma(double /*x*/, double /*y*/, double /*z*/);
float fmaf(float /*x*/, float /*y*/, float /*z*/);
long double fmal(long double /*x*/, long double /*y*/, long double /*z*/);
/* computes (x*y)+z, rounded as one ternary operation: it computes */
/* the value (as if) to infinite precision and rounds once to the result */
/* format, according to the rounding mode characterised by the value of */
/* FLT_ROUNDS. */
/* Returns: (x*y)+z, rounded as one ternary operation. */
#ifndef __cplusplus
#define isgreater(x,y) ((x) __greater (y))
......@@ -349,12 +493,50 @@ extern float fminf(float /*x*/, float /*y*/);
/* "invalid" floating-point exception. */
#endif
/* Some functions can be safely inlined - appropriate macros defined here */
double __d_atan(double);
double __d_cos(double);
double __d_sin(double);
double __d_abs(double);
double __d_floor(double);
double __d_ceil(double);
double __d_trunc(double);
double __d_rint(double);
long int __d_lrint(double);
float __r_abs(float);
#define atan(x) __d_atan(x)
#define cos(x) __d_cos(x)
#define sin(x) __d_sin(x)
#define fabs(x) ((void) sizeof fabs(x), __abs (double) (x))
#define floor(x) __d_floor(x)
#define ceil(x) __d_ceil(x)
#define trunc(x) __d_trunc(x)
#define rint(x) __d_rint(x)
#define lrint(x) __d_lrint(x)
#ifndef __cplusplus
__caller_narrow float __r_atan(float);
__caller_narrow float __r_sin(float);
__caller_narrow float __r_cos(float);
__caller_narrow float __r_floor(float);
__caller_narrow float __r_ceil(float);
__caller_narrow float __r_trunc(float);
__caller_narrow float __r_rint(float);
__caller_narrow long int __r_lrint(float);
#define atanf(x) __r_atan(x)
#define sinf(x) __r_sin(x)
#define cosf(x) __r_cos(x)
#define fabsf(x) ((void) sizeof fabsf(x), __abs (float) (x))
#define floorf(x) __r_floor(x)
#define ceilf(x) __r_ceil(x)
#define truncf(x) __r_trunc(x)
#define rintf(x) __r_rint(x)
#define lrintf(x) __r_lrint(x)
#endif
#ifdef __cplusplus
}
#endif
#pragma side_effects
#endif
/* end of math.h */
......@@ -15,7 +15,7 @@
#pragma force_top_level
#pragma include_only_once
/* setjmp.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.6 */
/* setjmp.h: ISO 'C' (9899:1999) library header, section 7.13 */
/* Copyright (C) A.C. Norman and A. Mycroft */
/* Copyright (C) Acorn Computers Ltd. 1991, 1992 */
/* version 2.00 */
......@@ -49,7 +49,7 @@ typedef int jmp_buf[22]; /* size suitable for the ARM */
#ifdef __cplusplus
extern "C" {
#endif
extern int setjmp(jmp_buf /*env*/);
int setjmp(jmp_buf /*env*/);
/* Saves its calling environment in its jmp_buf argument, for later use
* by the longjmp function.
* Returns: If the return is from a direct invocation, the setjmp function
......@@ -57,7 +57,7 @@ extern int setjmp(jmp_buf /*env*/);
* function, the setjmp function returns a non zero value.
*/
extern void longjmp(jmp_buf /*env*/, int /*val*/);
void longjmp(jmp_buf /*env*/, int /*val*/);
/* Restores the environment saved by the most recent call to setjmp in the
* same invocation of the program, with the corresponding jmp_buf argument.
* If there has been no such call, or if the function containing the call
......
......@@ -15,7 +15,7 @@
#pragma force_top_level
#pragma include_only_once
/* signal.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.7 */
/* signal.h: ISO 'C' (9899:1999) library header, section 7.14 */
/* Copyright (C) Codemist Ltd. */
/* Copyright (C) Acorn Computers Ltd. 1991, 1992 */
/* version 2.00 */
......@@ -36,9 +36,9 @@ typedef int sig_atomic_t;
#ifdef __cplusplus
extern "C" {
#endif
extern void __SIG_DFL(int);
extern void __SIG_ERR(int);
extern void __SIG_IGN(int);
void __SIG_DFL(int);
void __SIG_ERR(int);
void __SIG_IGN(int);
/*
* Each of the following macros expand to a constant expression with a
* distinct value and has the same type as the second argument to, and the
......@@ -69,7 +69,7 @@ extern void __SIG_IGN(int);
#define SIGUSR2 9
#define SIGOSERROR 10
extern void (*signal (int /*sig*/, void (* /*func*/ )(int)))(int);
void (*signal (int /*sig*/, void (* /*func*/ )(int)))(int);
/*
* Chooses one of three ways in which receipt of the signal number sig is to
* be subsequently handled. If the value of func is SIG_DFL, default
......@@ -102,7 +102,7 @@ extern void (*signal (int /*sig*/, void (* /*func*/ )(int)))(int);
* integer expression errno is set to indicate the error.
*/
extern int raise(int /*sig*/);
int raise(int /*sig*/);
/* sends the signal sig to the executing program. */
/* Returns: zero if successful, non-zero if unsuccessful. */
#ifdef __cplusplus
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment