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
......@@ -15,7 +15,7 @@
#pragma force_top_level
#pragma include_only_once
/* stddef.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.1.4 */
/* stddef.h: ISO 'C' (9899:1999) library header, section 7.17 */
/* Copyright (C) Codemist Ltd. */
/* Copyright (C) Acorn Computers Ltd. 1991, 1992 */
/* version 2.01 */
......
This diff is collapsed.
......@@ -18,7 +18,7 @@
/* stdlib.h: ISO 'C' (9899:1999) library header, section 7.20 */
/* Copyright (C) Codemist Ltd. */
/* Copyright (C) Acorn Computers Ltd., 1990, 1992 */
/* version 2.01 */
/* version 2.03 */
/*
* stdlib.h declares four types, several general purpose functions,
......@@ -91,19 +91,19 @@ typedef struct lldiv_t { long long int quot, rem; } lldiv_t;
#ifdef __cplusplus
extern "C" {
#endif
extern double atof(const char * /*nptr*/);
double atof(const char * /*nptr*/);
/*
* converts the initial part of the string pointed to by nptr to double
* representation.
* Returns: the converted value.
*/
extern int atoi(const char * /*nptr*/);
int atoi(const char * /*nptr*/);
/*
* converts the initial part of the string pointed to by nptr to int
* representation.
* Returns: the converted value.
*/
extern long int atol(const char * /*nptr*/);
long int atol(const char * /*nptr*/);
/*
* converts the initial part of the string pointed to by nptr to long int
* representation.
......@@ -111,7 +111,7 @@ extern long int atol(const char * /*nptr*/);
*/
#ifdef __STDC_VERSION__
#if __STDC_VERSION__ >= 199901
extern long long int atoll(const char * /*nptr*/);
long long int atoll(const char * /*nptr*/);
/*
* converts the initial part of the string pointed to by nptr to long long
* int representation.
......@@ -120,7 +120,7 @@ extern long long int atoll(const char * /*nptr*/);
#endif
#endif
extern double strtod(const char * /*nptr*/, char ** /*endptr*/);
double strtod(const char * /*nptr*/, char ** /*endptr*/);
/*
* converts the initial part of the string pointed to by nptr to double
* representation. First it decomposes the input string into three parts:
......@@ -140,7 +140,7 @@ extern double strtod(const char * /*nptr*/, char ** /*endptr*/);
* underflow, zero is returned and the value of the macro ERANGE is
* stored in errno.
*/
extern long int strtol(const char * /*nptr*/, char **/*endptr*/, int /*base*/);
long int strtol(const char * /*nptr*/, char **/*endptr*/, int /*base*/);
/*
* converts the initial part of the string pointed to by nptr to long int
* representation. First it decomposes the input string into three parts:
......@@ -169,8 +169,8 @@ extern long int strtol(const char * /*nptr*/, char **/*endptr*/, int /*base*/);
* (according to the sign of the value), and the value of the
* macro ERANGE is stored in errno.
*/
extern unsigned long int strtoul(const char * /*nptr*/,
char ** /*endptr*/, int /*base*/);
unsigned long int strtoul(const char * /*nptr*/,
char ** /*endptr*/, int /*base*/);
/*
* converts the initial part of the string pointed to by nptr to unsigned
* long int representation. First it decomposes the input string into three
......@@ -200,8 +200,8 @@ extern unsigned long int strtoul(const char * /*nptr*/,
*/
#ifdef __STDC_VERSION__
#if __STDC_VERSION__ >= 199901
extern long long int strtoll(const char * restrict /*nptr*/,
char ** restrict /*endptr*/, int /*base*/);
long long int strtoll(const char * restrict /*nptr*/,
char ** restrict /*endptr*/, int /*base*/);
/*
* converts the initial part of the string pointed to by nptr to long long
* int representation. First it decomposes the input string into three parts:
......@@ -230,9 +230,9 @@ extern long long int strtoll(const char * restrict /*nptr*/,
* (according to the sign of the value), and the value of the
* macro ERANGE is stored in errno.
*/
extern unsigned long long int strtoull(const char * restrict /*nptr*/,
char ** restrict /*endptr*/,
int /*base*/);
unsigned long long int strtoull(const char * restrict /*nptr*/,
char ** restrict /*endptr*/,
int /*base*/);
/*
* converts the initial part of the string pointed to by nptr to unsigned
* long long int representation. First it decomposes the input string into
......@@ -263,7 +263,7 @@ extern unsigned long long int strtoull(const char * restrict /*nptr*/,
#endif
#endif
extern int rand(void);
int rand(void);
/*
* Computes a sequence of pseudo-random integers in the range 0 to RAND_MAX.
* Uses an additive generator (Mitchell & Moore) of the form:
......@@ -273,7 +273,7 @@ extern int rand(void);
* conjectured to be good. Empirical testing since 1958 has shown no flaws.
* Returns: a pseudo-random integer.
*/
extern void srand(unsigned int /*seed*/);
void srand(unsigned int /*seed*/);
/*
* uses its argument as a seed for a new sequence of pseudo-random numbers
* to be returned by subsequent calls to rand. If srand is then called with
......@@ -282,7 +282,7 @@ extern void srand(unsigned int /*seed*/);
* sequence is generated as when srand is first called with a seed value
* of 1.
*/
extern int _ANSI_rand(void);
int _ANSI_rand(void);
/*
* The ANSI-defined 16-bit random number generator which computes
* a sequence of pseudo-random integers in the range 0 to _ANSI_RAND_MAX.
......@@ -290,7 +290,7 @@ extern int _ANSI_rand(void);
* *** NOT AVAILABLE IN THE SHARED C LIBRARY ***
* Returns: a pseudo-random integer.
*/
extern void _ANSI_srand(unsigned int /*seed*/);
void _ANSI_srand(unsigned int /*seed*/);
/*
* Uses its argument as a seed for a new sequence of pseudo-random numbers
* to be returned by subsequent calls to _ANSI_rand. If _ANSI_srand is then
......@@ -307,19 +307,19 @@ extern void _ANSI_srand(unsigned int /*seed*/);
typedef char *malloc_t;
extern char *calloc(size_t /*nmemb*/, size_t /*size*/);
extern void free(void * /*ptr*/);
extern char *malloc(size_t /*size*/);
extern char *realloc(void * /*ptr*/, size_t /*size*/);
char *calloc(size_t /*nmemb*/, size_t /*size*/);
void free(void * /*ptr*/);
char *malloc(size_t /*size*/);
char *realloc(void * /*ptr*/, size_t /*size*/);
#endif
#else
extern void *calloc(size_t /*nmemb*/, size_t /*size*/);
void *calloc(size_t /*nmemb*/, size_t /*size*/);
/*
* allocates space for an array of nmemb objects, each of whose size is
* 'size'. The space is initialised to all bits zero.
* Returns: either a null pointer or a pointer to the allocated space.
*/
extern void free(void * /*ptr*/);
void free(void * /*ptr*/);
/*
* causes the space pointed to by ptr to be deallocated (i.e., made
* available for further allocation). If ptr is a null pointer, no action
......@@ -327,13 +327,13 @@ extern void free(void * /*ptr*/);
* calloc, malloc or realloc or if the space has been deallocated by a call
* to free or realloc, the behaviour is undefined.
*/
extern void *malloc(size_t /*size*/);
void *malloc(size_t /*size*/);
/*
* allocates space for an object whose size is specified by 'size' and whose
* value is indeterminate.
* Returns: either a null pointer or a pointer to the allocated space.
*/
extern void *realloc(void * /*ptr*/, size_t /*size*/);
void *realloc(void * /*ptr*/, size_t /*size*/);
/*
* changes the size of the object pointed to by ptr to the size specified by
* size. The contents of the object shall be unchanged up to the lesser of
......@@ -351,17 +351,17 @@ extern void *realloc(void * /*ptr*/, size_t /*size*/);
*/
#endif
extern void abort(void);
void abort(void);
/*
* causes abnormal program termination to occur, unless the signal SIGABRT
* is being caught and the signal handler does not return. Whether open
* output streams are flushed or open streams are closed or temporary files
* removed is implementation-defined (under Arthur/Brazil all these occur).
* removed is implementation-defined (under RISC OS all these occur).
* An implementation-defined form of the status 'unsuccessful termination'
* (1 under Arthur/Brazil) is returned to the host environment by means
* of a call to raise(SIGABRT).
* (1 under RISC OS) is returned to the host environment by means of a call
* to raise(SIGABRT).
*/
extern int atexit(void (* /*func*/)(void));
int atexit(void (* /*func*/)(void));
/*
* registers the function pointed to by func, to be called without its
* arguments at normal program termination. It is possible to register at
......@@ -369,7 +369,7 @@ extern int atexit(void (* /*func*/)(void));
* Returns: zero if the registration succeeds, nonzero if it fails.
*/
extern void exit(int status);
void exit(int /*status*/);
/*
* causes normal program termination to occur. If more than one call to the
* exit function is executed by a program, the behaviour is undefined.
......@@ -379,14 +379,26 @@ extern void exit(int status);
* and all files created by the tmpfile function are removed.
* Finally, control is returned to the host environment. If the value of
* status is zero or EXIT_SUCCESS, an implementation-defined form of the
* status 'successful termination' (0 under Arthur/Brazil) is returned. If
* the value of status is EXIT_FAILURE, an implementation-defined form of
* the status 'unsuccessful termination' (1 under Arthur/Brazil) is
* returned. Otherwise the status returned is implementation-defined (the
* value of status is returned under Arthur/Brazil).
* status 'successful termination' (0 under RISC OS) is returned. If the
* value of status is EXIT_FAILURE, an implementation-defined form of the
* status 'unsuccessful termination' (1 under RISC OS) is returned.
* Otherwise the status returned is implementation-defined (the value of
* status is returned under RISC OS).
*/
extern char *getenv(const char * /*name*/);
void _Exit(int /*status*/);
/*
* causes normal program termination to occur and control to be returned to
* the host environment. No functions registered by the atexit function or
* signal handlers registered by the signal function are called.
* The status returned to the host environment is determined in the same
* way as for the exit function.
* Whether open streams with unwritten buffered data are flushed, open
* streams are closed or temporary files are removed is implementation-
* defined (under RISC OS all these occur).
*/
char *getenv(const char * /*name*/);
/*
* searches the environment list, provided by the host environment, for a
* string that matches the string pointed to by name. The set of environment
......@@ -398,14 +410,14 @@ extern char *getenv(const char * /*name*/);
* If the specified name cannot be found, a null pointer is
* returned.
*/
extern int system(const char * /*string*/);
int system(const char * /*string*/);
/*
* passes the string pointed to by string to the host environment to be
* executed by a command processor in an implementation-defined manner.
* A null pointer may be used for string, to inquire whether a command
* processor exists.
*
* Under Arthur/Brazil care must be taken when executing a command, that the
* Under RISC OS care must be taken when executing a command, that the
* command does not overwrite the calling program. The string 'chain:' or
* 'call:' may immediately precede the actual command. The effect of 'call:'
* is the same as if 'call:' were not present, which is to attempt to return
......@@ -415,12 +427,12 @@ extern int system(const char * /*string*/);
* Returns: If the argument is a null pointer, the system function returns
* non-zero only if a command processor is available. If the
* argument is not a null pointer, the system function returns an
* implementation-defined value (under Arthur/Brazil 0 is returned
* implementation-defined value (under RISC OS 0 is returned
* for success, -2 for failure to invoke the command and any other
* value is the return code from the executed command).
*/
extern void *bsearch(const void * /*key*/, const void * /*base*/,
void *bsearch(const void * /*key*/, const void * /*base*/,
size_t /*nmemb*/, size_t /*size*/,
int (* /*compar*/)(const void *, const void *));
/*
......@@ -437,7 +449,7 @@ extern void *bsearch(const void * /*key*/, const void * /*base*/,
* if no match is found. If two members compare as equal, which
* member is matched is unspecified.
*/
extern void qsort(void * /*base*/, size_t /*nmemb*/, size_t /*size*/,
void qsort(void * /*base*/, size_t /*nmemb*/, size_t /*size*/,
int (* /*compar*/)(const void *, const void *));
/*
* sorts an array of nmemb objects, the initial member of which is pointed
......@@ -451,25 +463,25 @@ extern void qsort(void * /*base*/, size_t /*nmemb*/, size_t /*size*/,
* sorted array is unspecified.
*/
extern int abs(int /*j*/);
int abs(int /*j*/);
/*
* computes the absolute value of an integer j. If the result cannot be
* represented, the behaviour is undefined.
* Returns: the absolute value.
*/
extern div_t div(int /*numer*/, int /*denom*/);
div_t div(int /*numer*/, int /*denom*/);
/*
* computes numer / denom and numer % denom in a single operation.
* Returns: a structure of type div_t, comprising both the quotient and the
* remainder.
*/
extern long int labs(long int /*j*/);
long int labs(long int /*j*/);
/*
* computes the absolute value of an integer j. If the result cannot be
* represented, the behaviour is undefined.
* Returns: the absolute value.
*/
extern ldiv_t ldiv(long int /*numer*/, long int /*denom*/);
ldiv_t ldiv(long int /*numer*/, long int /*denom*/);
/*
* computes numer / denom and numer % denom in a single operation.
* Returns: a structure of type ldiv_t, comprising both the quotient and the
......@@ -477,13 +489,13 @@ extern ldiv_t ldiv(long int /*numer*/, long int /*denom*/);
*/
#ifdef __STDC_VERSION__
#if __STDC_VERSION__ >= 199901
extern long long int llabs(long long int /*j*/);
long long int llabs(long long int /*j*/);
/*
* computes the absolute value of an integer j. If the result cannot be
* represented, the behaviour is undefined.
* Returns: the absolute value.
*/
extern lldiv_t lldiv(long long int /*numer*/, long long int /*denom*/);
lldiv_t lldiv(long long int /*numer*/, long long int /*denom*/);
/*
* computes numer / denom and numer % denom in a single operation.
* Returns: a structure of type lldiv_t, comprising both the quotient and the
......@@ -492,6 +504,12 @@ extern lldiv_t lldiv(long long int /*numer*/, long long int /*denom*/);
#endif
#endif
#ifndef __cplusplus
/* the sizeof expression performs the necessary type-checking */
#define abs(j) ((void) sizeof abs(j), __abs (int) (j))
#define labs(j) ((void) sizeof labs(j), __abs (long int) (j))
#endif
/*
* Multibyte Character Functions.
* The behaviour of the multibyte character functions is affected by the
......@@ -504,7 +522,7 @@ extern lldiv_t lldiv(long long int /*numer*/, long long int /*denom*/);
* otherwise. After the LC_CTYPE category is changed, the shift state of these
* functions is indeterminate.
*/
extern int mblen(const char * /*s*/, size_t /*n*/);
int mblen(const char * /*s*/, size_t /*n*/);
/*
* If s is not a null pointer, the mblen function determines the number of
* bytes compromising the multibyte character pointed to by s. Except that
......@@ -519,7 +537,7 @@ extern int mblen(const char * /*s*/, size_t /*n*/);
* valid multibyte character), or returns -1 (they do not form a
* valid multibyte character).
*/
extern int mbtowc(wchar_t * /*pwc*/, const char * /*s*/, size_t /*n*/);
int mbtowc(wchar_t * /*pwc*/, const char * /*s*/, size_t /*n*/);
/*
* If s is not a null pointer, the mbtowc function determines the number of
* bytes that compromise the multibyte character pointed to by s. It then
......@@ -537,7 +555,7 @@ extern int mbtowc(wchar_t * /*pwc*/, const char * /*s*/, size_t /*n*/);
* fewer bytes form a valid multibyte character), or returns -1
* (they do not form a valid multibyte character).
*/
extern int wctomb(char * /*s*/, wchar_t /*wchar*/);
int wctomb(char * /*s*/, wchar_t /*wchar*/);
/*
* determines the number of bytes need to represent the multibyte character
* corresponding to the code whose value is wchar (including any change in
......@@ -559,7 +577,7 @@ extern int wctomb(char * /*s*/, wchar_t /*wchar*/);
* The behaviour of the multibyte string functions is affected by the LC_CTYPE
* category of the current locale.
*/
extern size_t mbstowcs(wchar_t * /*pwcs*/, const char * /*s*/, size_t /*n*/);
size_t mbstowcs(wchar_t * /*pwcs*/, const char * /*s*/, size_t /*n*/);
/*
* converts a sequence of multibyte character that begins in the initial
* shift state from the array pointed to by s into a sequence of
......@@ -576,7 +594,7 @@ extern size_t mbstowcs(wchar_t * /*pwcs*/, const char * /*s*/, size_t /*n*/);
* returns the number of array elements modified, not including
* a terminating zero code, if any.
*/
extern size_t wcstombs(char * /*s*/, const wchar_t * /*pwcs*/, size_t /*n*/);
size_t wcstombs(char * /*s*/, const wchar_t * /*pwcs*/, size_t /*n*/);
/*
* converts a sequence of codes that correspond to multibyte characters
* from the array pointed to by pwcs into a sequence of multibyte
......
......@@ -15,7 +15,7 @@
#pragma force_top_level
#pragma include_only_once
/* string.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.11 */
/* string.h: ISO 'C' (9899:1999) library header, section 7.21 */
/* Copyright (C) Codemist Ltd. */
/* Copyright (C) Acorn Computers Ltd. 1991, 1992 */
/* version 2.00 */
......@@ -44,14 +44,14 @@ typedef unsigned int size_t; /* from <stddef.h> */
#ifdef __cplusplus
extern "C" {
#endif
extern char *strcpy(char * /*s1*/, const char * /*s2*/);
char *strcpy(char * /*s1*/, const char * /*s2*/);
/*
* copies the string pointed to by s2 (including the terminating nul
* character) into the array pointed to by s1. If copying takes place
* between objects that overlap, the behaviour is undefined.
* Returns: the value of s1.
*/
extern char *strncpy(char * /*s1*/, const char * /*s2*/, size_t /*n*/);
char *strncpy(char * /*s1*/, const char * /*s2*/, size_t /*n*/);
/*
* copies not more than n characters (characters that follow a null
* character are not copied) from the array pointed to by s2 into the array
......@@ -60,14 +60,14 @@ extern char *strncpy(char * /*s1*/, const char * /*s2*/, size_t /*n*/);
* Returns: the value of s1.
*/
extern char *strcat(char * /*s1*/, const char * /*s2*/);
char *strcat(char * /*s1*/, const char * /*s2*/);
/*
* appends a copy of the string pointed to by s2 (including the terminating
* null character) to the end of the string pointed to by s1. The initial
* character of s2 overwrites the null character at the end of s1.
* Returns: the value of s1.
*/
extern char *strncat(char * /*s1*/, const char * /*s2*/, size_t /*n*/);
char *strncat(char * /*s1*/, const char * /*s2*/, size_t /*n*/);
/*
* appends not more than n characters (a null character and characters that
* follow it are not appended) from the array pointed to by s2 to the end of
......@@ -84,7 +84,7 @@ extern char *strncat(char * /*s1*/, const char * /*s2*/, size_t /*n*/);
* objects being compared.
*/
extern int memcmp(const void * /*s1*/, const void * /*s2*/, size_t /*n*/);
int memcmp(const void * /*s1*/, const void * /*s2*/, size_t /*n*/);
/*
* compares the first n characters of the object pointed to by s1 to the
* first n characters of the object pointed to by s2.
......@@ -92,14 +92,14 @@ extern int memcmp(const void * /*s1*/, const void * /*s2*/, size_t /*n*/);
* as the object pointed to by s1 is greater than, equal to, or
* less than the object pointed to by s2.
*/
extern int strcmp(const char * /*s1*/, const char * /*s2*/);
int strcmp(const char * /*s1*/, const char * /*s2*/);
/*
* compares the string pointed to by s1 to the string pointed to by s2.
* Returns: an integer greater than, equal to, or less than zero, according
* as the string pointed to by s1 is greater than, equal to, or
* less than the string pointed to by s2.
*/
extern int strncmp(const char * /*s1*/, const char * /*s2*/, size_t /*n*/);
int strncmp(const char * /*s1*/, const char * /*s2*/, size_t /*n*/);
/*
* compares not more than n characters (characters that follow a null
* character are not compared) from the array pointed to by s1 to the array
......@@ -108,7 +108,7 @@ extern int strncmp(const char * /*s1*/, const char * /*s2*/, size_t /*n*/);
* as the string pointed to by s1 is greater than, equal to, or
* less than the string pointed to by s2.
*/
extern int strcoll(const char * /*s1*/, const char * /*s2*/);
int strcoll(const char * /*s1*/, const char * /*s2*/);
/*
* compares the string pointed to by s1 to the string pointed to by s2, both
* interpreted as appropriate to the LC_COLLATE category of the current
......@@ -119,7 +119,7 @@ extern int strcoll(const char * /*s1*/, const char * /*s2*/);
* as appropriate to the current locale.
*/
extern size_t strxfrm(char * /*s1*/, const char * /*s2*/, size_t /*n*/);
size_t strxfrm(char * /*s1*/, const char * /*s2*/, size_t /*n*/);
/*
* transforms the string pointed to by s2 and places the resulting string
* into the array pointed to by s1. The transformation function is such that
......@@ -136,28 +136,28 @@ extern size_t strxfrm(char * /*s1*/, const char * /*s2*/, size_t /*n*/);
* indeterminate.
*/
extern char *strchr(const char * /*s*/, int /*c*/);
char *strchr(const char * /*s*/, int /*c*/);
/*
* locates the first occurence of c (converted to an char) in the string
* pointed to by s (including the terminating null character).
* Returns: a pointer to the located character, or a null pointer if the
* character does not occur in the string.
*/
extern size_t strcspn(const char * /*s1*/, const char * /*s2*/);
size_t strcspn(const char * /*s1*/, const char * /*s2*/);
/*
* computes the length of the initial segment of the string pointed to by s1
* which consists entirely of characters not from the string pointed to by
* s2. The terminating null character is not considered part of s2.
* Returns: the length of the segment.
*/
extern char *strpbrk(const char * /*s1*/, const char * /*s2*/);
char *strpbrk(const char * /*s1*/, const char * /*s2*/);
/*
* locates the first occurence in the string pointed to by s1 of any
* character from the string pointed to by s2.
* Returns: returns a pointer to the character, or a null pointer if no
* character form s2 occurs in s1.
*/
extern char *strrchr(const char * /*s*/, int /*c*/);
char *strrchr(const char * /*s*/, int /*c*/);
/*
* locates the last occurence of c (converted to a char) in the string
* pointed to by s. The terminating null character is considered part of
......@@ -165,13 +165,13 @@ extern char *strrchr(const char * /*s*/, int /*c*/);
* Returns: returns a pointer to the character, or a null pointer if c does
* not occur in the string.
*/
extern size_t strspn(const char * /*s1*/, const char * /*s2*/);
size_t strspn(const char * /*s1*/, const char * /*s2*/);
/*
* computes the length of the initial segment of the string pointed to by s1
* which consists entirely of characters from the string pointed to by S2
* Returns: the length of the segment.
*/
extern char *strstr(const char * /*s1*/, const char * /*s2*/);
char *strstr(const char * /*s1*/, const char * /*s2*/);
/*
* locates the first occurence in the string pointed to by s1 of the
* sequence of characters (excluding the terminating null character) in the
......@@ -179,7 +179,7 @@ extern char *strstr(const char * /*s1*/, const char * /*s2*/);
* Returns: a pointer to the located string, or a null pointer if the string
* is not found.
*/
extern char *strtok(char * /*s1*/, const char * /*s2*/);
char *strtok(char * /*s1*/, const char * /*s2*/);
/*
* A sequence of calls to the strtok function breaks the string pointed to
* by s1 into a sequence of tokens, each of which is delimited by a
......@@ -206,14 +206,14 @@ extern char *strtok(char * /*s1*/, const char * /*s2*/);
* there is no token.
*/
extern void *memcpy(void * /*s1*/, const void * /*s2*/, size_t /*n*/);
void *memcpy(void * /*s1*/, const void * /*s2*/, size_t /*n*/);
/*
* copies n characters from the object pointed to by s2 into the object
* pointed to by s1. If copying takes place between objects that overlap,
* the behaviour is undefined.
* Returns: the value of s1.
*/
extern void *memmove(void * /*s1*/, const void * /*s2*/, size_t /*n*/);
void *memmove(void * /*s1*/, const void * /*s2*/, size_t /*n*/);
/*
* copies n characters from the object pointed to by s2 into the object
* pointed to by s1. Copying takes place as if the n characters from the
......@@ -223,7 +223,7 @@ extern void *memmove(void * /*s1*/, const void * /*s2*/, size_t /*n*/);
* object pointed to by s1.
* Returns: the value of s1.
*/
extern void *memchr(const void * /*s*/, int /*c*/, size_t /*n*/);
void *memchr(const void * /*s*/, int /*c*/, size_t /*n*/);
/*
* locates the first occurence of c (converted to an unsigned char) in the
* initial n characters (each interpreted as unsigned char) of the object
......@@ -231,14 +231,14 @@ extern void *memchr(const void * /*s*/, int /*c*/, size_t /*n*/);
* Returns: a pointer to the located character, or a null pointer if the
* character does not occur in the object.
*/
extern void *memset(void * /*s*/, int /*c*/, size_t /*n*/);
void *memset(void * /*s*/, int /*c*/, size_t /*n*/);
/*
* copies the value of c (converted to an unsigned char) into each of the
* first n charactes of the object pointed to by s.
* Returns: the value of s.
*/
extern char *strerror(int /*errnum*/);
char *strerror(int /*errnum*/);
/*
* maps the error number in errnum to an error message string.
* Returns: a pointer to the string, the contents of which are
......@@ -253,7 +253,7 @@ extern char *strerror(int /*errnum*/);
* modified by the program, but may be overwritten by a subsequent
* call to the strerror function.
*/
extern size_t strlen(const char * /*s*/);
size_t strlen(const char * /*s*/);
/*
* computes the length of the string pointed to by s.
* Returns: the number of characters that precede the terminating null
......
/* Copyright 2003 Tematic Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma force_top_level
#pragma include_only_once
/* tgmath.h: ISO 'C' (9899:1999) library header, section 7.22 */
/* Copyright (C) Acorn Computers Ltd. 2002 */
/* version 1.00 */
/*
* tgmath.h includes the headers <math.h> and <complex.h> and defines
* several type-generic macros.
*/
#ifndef __tgmath_h
#define __tgmath_h
#include <math.h>
#define _TG(o, ...) (___select(0, o##f, o, o##l, __VA_ARGS__))(__VA_ARGS__)
#define _TG1(o, x,...) (___select(0, o##f, o, o##l, x))(x,__VA_ARGS__)
#define _TG2(o, x,y,...) (___select(0, o##f, o, o##l, x,y))(x,y,__VA_ARGS__)
#define _TGx(f,d,l, ...) (___select(0, f, d, l, __VA_ARGS__))(__VA_ARGS__)
/* Type-generic macros for functions with both real and complex forms */
#undef acos
#undef asin
#undef atan
#undef acosh
#undef asinh
#undef atanh
#undef cos
#undef sin
#undef tan
#undef cosh
#undef sinh
#undef tanh
#undef exp
#undef log
#undef pow
#undef sqrt
#undef fabs
#define acos(x) _TG(acos, x)
#define asin(x) _TG(asin, x)
#define atan(x) _TG(atan, x)
#define acosh(x) _TG(acosh, x)
#define asinh(x) _TG(asinh, x)
#define atanh(x) _TG(atanh, x)
#define cos(x) _TG(cos, x)
#define sin(x) _TG(sin, x)
#define tan(x) _TG(tan, x)
#define cosh(x) _TG(cosh, x)
#define sinh(x) _TG(sinh, x)
#define tanh(x) _TG(tanh, x)
#define exp(x) _TG(exp, x)
#define log(x) _TG(log, x)
#define pow(x) _TG(pow, x)
#define sqrt(x) _TG(sqrt, x)
#define fabs(x) _TG(fabs, x)
/* Type-generic macros for real-only functions */
#undef atan2
#undef cbrt
#undef ceil
#undef copysign
#undef erf
#undef erfc
#undef expm1
#undef fdim
#undef floor
#undef fma
#undef fmax
#undef fmin
#undef fmod
#undef frexp
#undef hypot
#undef ilogb
#undef ldexp
#undef lgamma
#undef llrint
#undef llround
#undef log10
#undef log1p
#undef log2
#undef logb
#undef lrint
#undef lround
#undef nearbyint
#undef nextafter
#undef nexttoward
#undef remainder
#undef remquo
#undef rint
#undef round
#undef scalbn
#undef scalbln
#undef tgamma
#undef trunc
#define atan2(y,x) _TG(atan2, y,x)
#define cbrt(x) _TG(cbrt, x)
#define ceil(x) _TG(ceil, x)
#define copysign(x,y) _TG(copysign, x,y)
#define erf(x) _TG(erf, x)
#define erfc(x) _TG(erfc, x)
#define expm1(x) _TG(expm1, x)
#define fdim(x,y) _TG(fdim, x,y)
#define floor(x) _TG(floor, x)
#define fma(x,y,z) _TG(fma, x,y,z)
#define fmax(x,y) _TG(fmax, x,y)
#define fmin(x,y) _TG(fmin, x,y)
#define fmod(x,y) _TG(fmod, x,y)
#define frexp(v,e) _TG1(frexp, v,e)
#define hypot(x,y) _TG(hypot, x,y)
#define ilogb(x) _TG(ilogb, x)
#define ldexp(x,e) _TG1(ldexp, x,e)
#define lgamma(x) _TG(lgamma, x)
#define llrint(x) _TG(llrint, x)
#define llround(x) _TG(llround, x)
#define log10(x) _TG(log10, x)
#define log1p(x) _TG(log1p, x)
#define log2(x) _TG(log2, x)
#define logb(x) _TG(logb, x)
#define lrint(x) _TG(lrint, x)
#define lround(x) _TG(lround, x)
#define nearbyint(x) _TG(nearbyint, x)
#define nextafter(x,y) _TG(nextafter, x,y)
#define nexttoward(x,y) _TG1(nexttoward, x,y)
#define remainder(x,y) _TG(remainder, x,y)
#define remquo(x,y,q) _TG2(remquo, x,y,q)
#define rint(x) _TG(rint, x)
#define round(x) _TG(round, x)
#define scalbn(x,n) _TG1(scalbn, x,n)
#define scalbln(x,n) _TG1(scalbln, x,n)
#define tgamma(x) _TG(tgamma, x)
#define trunc(x) _TG(trunc, x)
/* Ensure inlining still happens, unless requested otherwise */
#ifndef __TGMATH_NO_INLINING
#undef atan
#undef cos
#undef sin
#undef fabs
#undef floor
#undef ceil
#undef trunc
#undef rint
#undef lrint
#define atan(x) _TGx(__r_atan, __d_atan, atanl, x)
#define cos(x) _TGx(__r_cos, __d_cos, cosl, x)
#define sin(x) _TGx(__r_sin, __d_sin, sinl, x)
#define fabs(x) (___select(0, __abs (x), __abs (double) (x), __abs (x), x))
#define floor(x) _TGx(__r_floor, __d_floor, floorl, x)
#define ceil(x) _TGx(__r_ceil, __d_ceil, ceill, x)
#define trunc(x) _TGx(__r_trunc, __d_trunc, truncl, x)
#define rint(x) _TGx(__r_rint, __d_rint, rintl, x)
#define lrint(x) _TGx(__r_lrint, __d_lrint, lrintl, x)
#endif
#endif
/* end of tgmath.h */
......@@ -74,7 +74,7 @@ struct tm {
#ifdef __cplusplus
extern "C" {
#endif
extern clock_t clock(void);
clock_t clock(void);
/* determines the processor time used.
* Returns: the implementation's best approximation to the processor time
* used by the program since program invocation. The time in
......@@ -82,12 +82,12 @@ extern clock_t clock(void);
* CLK_TCK. The value (clock_t)-1 is returned if the processor time
* used is not available.
*/
extern double difftime(time_t /*time1*/, time_t /*time0*/);
double difftime(time_t /*time1*/, time_t /*time0*/);
/*
* computes the difference between two calendar times: time1 - time0.
* Returns: the difference expressed in seconds as a double.
*/
extern time_t mktime(struct tm * /*timeptr*/);
time_t mktime(struct tm * /*timeptr*/);
/*
* converts the broken-down time, expressed as local time, in the structure
* pointed to by timeptr into a calendar time value with the same encoding
......@@ -103,7 +103,7 @@ extern time_t mktime(struct tm * /*timeptr*/);
* If the calendar time cannot be represented, the function returns
* the value (time_t)-1.
*/
extern time_t time(time_t * /*timer*/);
time_t time(time_t * /*timer*/);
/*
* determines the current calendar time. The encoding of the value is
* unspecified.
......@@ -113,33 +113,33 @@ extern time_t time(time_t * /*timer*/);
* is also assigned to the object it points to.
*/
extern char *asctime(const struct tm * /*timeptr*/);
char *asctime(const struct tm * /*timeptr*/);
/*
* converts the broken-down time in the structure pointed to by timeptr into
* a string in the form Sun Sep 16 01:03:52 1973\n\0.
* Returns: a pointer to the string containing the date and time.
*/
extern char *ctime(const time_t * /*timer*/);
char *ctime(const time_t * /*timer*/);
/*
* converts the calendar time pointed to by timer to local time in the form
* of a string. It is equivalent to asctime(localtime(timer));
* Returns: the pointer returned by the asctime function with that
* broken-down time as argument.
*/
extern struct tm *gmtime(const time_t * /*timer*/);
struct tm *gmtime(const time_t * /*timer*/);
/*
* converts the calendar time pointed to by timer into a broken-down time,
* expressed as Greenwich Mean Time (GMT).
* Returns: a pointer to that object or a null pointer if GMT not available.
*/
extern struct tm *localtime(const time_t * /*timer*/);
struct tm *localtime(const time_t * /*timer*/);
/*
* converts the calendar time pointed to by timer into a broken-down time,
* expressed a local time.
* Returns: a pointer to that object.
*/
extern size_t strftime(char * /*s*/, size_t /*maxsize*/,
const char * /*format*/, const struct tm * /*timeptr*/);
size_t strftime(char * /*s*/, size_t /*maxsize*/,
const char * /*format*/, const struct tm * /*timeptr*/);
/*
* places characters into the array pointed to by s as controlled by the
* string pointed to by format. The format string consists of zero or more
......
......@@ -57,6 +57,12 @@ $Label MOV r1, #0
WFS r1
MEND
MACRO
$Label CheckFPInterrupts $nocheck
; Sets r1 to the current fp flags.
RFS r1
MEND
MACRO
$Label ReEnableFPInterrupts $nocheck
; Reinstates the exception mask state which prevailed before the call
......@@ -152,6 +158,8 @@ $Label
EXPORT copysignf
EXPORT nextafter
EXPORT nextafterf
EXPORT nexttoward
EXPORT nexttowardf
EXPORT |__rt_stkovf_split_small|
EXPORT |__rt_stkovf_split_big|
......@@ -175,6 +183,8 @@ $Label
EXPORT fmax
EXPORT fmaxf
EXPORT fmaf
EXPORT nearbyint
EXPORT nearbyintf
EXPORT round
......@@ -184,14 +194,31 @@ $Label
EXPORT remainder
EXPORT remainderf
EXPORT exp
EXPORT expf
EXPORT expm1
EXPORT expm1f
EXPORT exp2
EXPORT exp2f
EXPORT log10
EXPORT log10f
EXPORT log
EXPORT logf
EXPORT log1p
EXPORT log1pf
EXPORT log2
EXPORT log2f
EXPORT sqrt
EXPORT sqrtf
EXPORT cbrt
EXPORT cbrtf
EXPORT tan
EXPORT tanf
EXPORT asin
EXPORT asinf
EXPORT acos
EXPORT acosf
EXPORT pow
EXPORT powf
EXPORT hypot
EXPORT hypotf
......@@ -852,6 +879,7 @@ chunks_deallocated
|_osbyte|
B |_kernel_osbyte|
LTORG
; double _ldfp(void *x) converts packed decimal at x to a double
......@@ -951,6 +979,8 @@ copysignf
; Back to normal calling conventions
nexttoward
NOP
nextafter
[ :LNOT:FloatingPointArgsInRegs
STMFD sp!, {r0-r3}
......@@ -1166,7 +1196,6 @@ fminf
Return ,LinkNotStacked,VC
B fcmpnan
[ {FALSE}
fmaf
[ :LNOT:FloatingPointArgsInRegs
STMFD sp!, {r0-r3}
......@@ -1180,7 +1209,6 @@ fmaf
MUFE f0, f0, f1 ; totally accurate result
ADFS f0, f0, f2
Return ,LinkNotStacked
]
nearbyint
[ :LNOT:FloatingPointArgsInRegs
......@@ -1292,7 +1320,9 @@ exp
|
DisableFPInterrupts
]
exp_common
EXPD f0, f0
exp_exit
ReEnableFPInterrupts
TST r1, #&0F
Return ,LinkNotStacked, EQ
......@@ -1300,6 +1330,52 @@ exp
BNE underflow_error
B huge_error
expf
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
DisableFPInterrupts
LDFD f0, [sp], #8
|
DisableFPInterrupts
]
MVFS f0, f0
expf_common
EXPS f0, f0
expf_exit
ReEnableFPInterrupts
TST r1, #&0F
Return ,LinkNotStacked, EQ
TST r1, #8
BNE underflow_error
B huge_errorf
; Mickey-mouse implementations, but they are still better than the user
; doing it, because of intermediate extended precision.
expm1
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
DisableFPInterrupts
LDFD f0, [sp], #8
|
DisableFPInterrupts
]
EXPE f0, f0
SUFD f0, f0, #1
B exp_exit
expm1f
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
DisableFPInterrupts
LDFD f0, [sp], #8
|
DisableFPInterrupts
]
MVFS f0, f0
EXPE f0, f0
SUFS f0, f0, #1
B expf_exit
ldfp_overflow
LDR r0, [r0, #0]
CMPS r0, #0
......@@ -1323,6 +1399,13 @@ huge_val
DCD &7FEFFFFF ; put constant where it is easy to find
DCD &FFFFFFFF
huge_negative_resultf
MOV r0, #ERANGE
LDFS f0, negative_huge_valf
B Set_errno
negative_huge_valf
DCD &FF800000
huge_errorf
MOV r0, #ERANGE
LDFS f0, huge_valf
......@@ -1340,8 +1423,6 @@ negative_errorf
MOV r0, #EDOM
LDFS f0, negative_huge_valf ; @@@@!!!!
B Set_errno
negative_huge_valf
DCD &FF800000 ; put constant where it is easy to find
underflow_error
MOV r0, #ERANGE
......@@ -1353,31 +1434,221 @@ log10
STMFD sp!, {r0, r1}
LDFD f0, [sp], #8
]
CMFE f0, #0
CMF f0, #0
BEQ huge_negative_result
BMI negative_error
LOGD f0, f0
Return ,LinkNotStacked
log10f
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
LDFD f0, [sp], #8
]
MVFS f0, f0
CMF f0, #0
BEQ huge_negative_resultf
BMI negative_errorf
LOGGTS f0, f0
Return ,LinkNotStacked
log
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
LDFD f0, [sp], #8
]
CMFE f0, #0
CMF f0, #0
BEQ huge_negative_result
BMI negative_error
LGNGTD f0, f0
Return ,LinkNotStacked
logf
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
LDFD f0, [sp], #8
]
MVFS f0, f0
CMF f0, #0
BEQ huge_negative_resultf
BMI negative_errorf
LGNGTS f0, f0
Return ,LinkNotStacked
; Mickey-mouse implementations, but they are still better than the user
; doing it, because of intermediate extended precision.
log1p
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
LDFD f0, [sp], #8
]
CNF f0, #1
BEQ huge_negative_result
BMI negative_error
LGND f0, f0
ADFGTE f0, f0, #1
LGNGTD f0, f0
Return ,LinkNotStacked
log1pf
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
LDFD f0, [sp], #8
]
MVFS f0, f0
CNF f0, #1
BEQ huge_negative_result
BMI negative_error
ADFGTE f0, f0, #1
LGNGTS f0, f0
Return ,LinkNotStacked
log2
[ FloatingPointArgsInRegs
STFD f0, [sp, #-8]!
LDMFD sp!, {r0, r1}
|
STMFD sp!, {r0, r1}
LDFD f0, [sp], #8
]
; Now argument is in both {r0,r1} and f0
CMF f0, #0
BEQ huge_negative_result
BMI negative_error
Return ,LinkNotStacked,VS
; Argument is strictly positive and finite
MOVS r2, r0, LSR #20 ; r2 = exponent field
BNE %FT30
; Subnormal case - normalise
MOV r2, #1
10 ADDS r1, r1, r1
ADCS r0, r0, r0
SUB r2, r2, #1
TST r0, #&00100000
BEQ %BT10
30 ORRS r3, r1, r0, LSL #12 ; EQ if exact power of 2
; If exact, just convert exponent field to FP, else
; compute log2(e)*log(x)
BEQ log2_exact
LDFE f1, log2_e
LGNE f0, f0
MUFD f0, f0, f1
Return ,LinkNotStacked
log2_exact
SUB r2, r2, #&400
ADD r2, r2, #1
TEQ r2, #&400 ; EQ if infinity
FLTNED f0, r2
Return ,LinkNotStacked
log2f
[ :LNOT:FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
LDFD f0, [sp], #8
]
MVFS f0, f0
STFS f0, [sp, #-4]!
LDR r0, [sp], #4
; Now argument is in both r0 and f0
CMF f0, #0
BEQ huge_negative_result
BMI negative_error
Return ,LinkNotStacked,VS
; Argument is strictly positive and finite
MOVS r2, r0, LSR #23 ; r2 = exponent field
MOV r0, r0, LSL #9 ; r0 = fraction
BNE %FT30
; Subnormal case - normalise
MOV r2, #1
10 ADDS r0, r0, r0
SUB r2, r2, #1
BCC %BT10
30 TEQ r0, #0 ; EQ if exact power of 2
; If exact, just convert exponent field to FP, else
; compute log2(e)*log(x)
BEQ log2f_exact
LDFE f1, log2_e
LGNE f0, f0
MUFS f0, f0, f1
Return ,LinkNotStacked
log2f_exact
SUB r2, r2, #&400
ADD r2, r2, #1
TEQ r2, #&400 ; EQ if infinity
FLTNES f0, r2
Return ,LinkNotStacked
log2_e DCD &00003FFF, &B8AA3B29, &5C17F0BC
loge_2 DCD &00003FFE, &B17217F7, &D1CF79AC
IMPORT scalbln
exp2
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
DisableFPInterrupts
LDFD f0, [sp], #8
|
DisableFPInterrupts
]
FIX r0, f0
CheckFPInterrupts
ANDS r1, r1, #&1F ; inexact or invalid?
BNE exp2_inexact
; exp2 of an integer - can create an exact result using scalbn
ReEnableFPInterrupts nocheck
[ FloatingPointArgsInRegs
MVFD f0, #1
|
MOV r2, r0
ADR r3, D_one
LDMIA r3, {r0,r1}
]
B scalbln
exp2_inexact
LDFE f1, loge_2
MUFE f0, f0, f1
B exp_common
IMPORT scalblnf
exp2f
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
DisableFPInterrupts
LDFD f0, [sp], #8
|
DisableFPInterrupts
]
MVFS f0, f0
FIX r0, f0
CheckFPInterrupts
ANDS r1, r1, #&1F ; inexact or invalid?
BNE exp2f_inexact
; exp2f of an integer - can create an exact result using scalbn
ReEnableFPInterrupts nocheck
[ FloatingPointArgsInRegs
MVFS f0, #1
|
MOV r2, r0
ADR r3, D_one
LDMIA r3, {r0,r1}
]
B scalblnf
exp2f_inexact
LDFE f1, loge_2
MUFE f0, f0, f1
B expf_common
D_one DCFD 1
OneThird
DCD &00003FFD, &AAAAAAAA, &AAAAAAAB
sqrt
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
LDFD f0, [sp], #8
]
CMFE f0, #0
CMF f0, #0
BMI negative_error
SQTD f0, f0
SQTGED f0, f0
Return ,LinkNotStacked
sqrtf
......@@ -1386,9 +1657,36 @@ sqrtf
LDFD f0, [sp], #8
]
MVFS f0, f0
CMFE f0, #0
CMF f0, #0
BMI negative_errorf
SQTS f0, f0
SQTGES f0, f0
Return ,LinkNotStacked
cbrt
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
LDFD f0, [sp], #8
]
CMF f0, #0
Return ,LinkNotStacked,EQ
LDFVCE f1, OneThird
ABSVCE f0, f0
POWVCD f0, f0, f1
MNFMID f0, f0
Return ,LinkNotStacked
cbrtf
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
LDFD f0, [sp], #8
]
MVFS f0, f0
CMF f0, #0
Return ,LinkNotStacked,EQ
LDFVCE f1, OneThird
ABSVCE f0, f0
POWVCS f0, f0, f1
MNFMIS f0, f0
Return ,LinkNotStacked
tan
......@@ -1405,7 +1703,6 @@ tan
Return ,LinkNotStacked, EQ
B huge_error
[ {FALSE}
tanf
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
......@@ -1420,7 +1717,6 @@ tanf
TST r1, #&07
Return ,LinkNotStacked, EQ
B huge_errorf
]
asin
[ :LNOT: FloatingPointArgsInRegs
......@@ -1439,6 +1735,24 @@ asin
Return ,LinkNotStacked, EQ
B negative_error
asinf
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
DisableFPInterrupts
LDFD f0, [sp], #8
|
DisableFPInterrupts
]
MVFS f0, f0
ASNS f0, f0
ReEnableFPInterrupts
; A range error is not possible; any error must be a domain error.
; (And the only plausible error flag is IVO, but I don't check).
; Dunno what result is sensible.
TST r1, #&07
Return ,LinkNotStacked, EQ
B negative_errorf
acos
[ :LNOT: FloatingPointArgsInRegs
......@@ -1457,6 +1771,24 @@ acos
Return ,LinkNotStacked, EQ
B negative_error
acosf
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1}
DisableFPInterrupts
LDFD f0, [sp], #8
|
DisableFPInterrupts
]
MVFS f0, f0
ACSS f0, f0
ReEnableFPInterrupts
; A range error is not possible; any error must be a domain error.
; (And the only plausible error flag is IVO, but I don't check).
; Dunno what result is sensible.
TST r1, #&07
Return ,LinkNotStacked, EQ
B negative_errorf
pow
[ :LNOT: FloatingPointArgsInRegs
......@@ -1470,6 +1802,7 @@ pow
CMFE f0, #0
BEQ POWFirstArgZero
POWD f0, f0, f1
POWCommonExit
ReEnableFPInterrupts
; Plausibly, there may have been either an overflow or IVO error.
; I assume that the former is always a range error, and the latter
......@@ -1484,6 +1817,22 @@ pow
BNE underflow_error
B huge_error
powf
[ :LNOT: FloatingPointArgsInRegs
STMFD sp!, {r0, r1, r2, r3}
DisableFPInterrupts
LDFD f0, [sp], #8
LDFD f1, [sp], #8
|
DisableFPInterrupts
]
MVFS f0, f0
MVFS f1, f1
CMFE f0, #0
BEQ POWFirstArgZero
POWS f0, f0, f1
B POWCommonExit
POWFirstArgZero
CMFE f1, #0
MVFEQD f0, #1 ; return 1.0 if both args 0.0
......@@ -1502,7 +1851,8 @@ hypot
LDFD f0, [sp], #8
LDFD f1, [sp], #8
]
LDFS f3, infinity
ADRL r0, infinity
LDFS f3, [r0]
CMF f0, f1
BVS hypot_nan
MVFMID f2, f0
......@@ -1538,7 +1888,8 @@ hypotf
]
ABSS f0, f0
ABSS f1, f1
LDFS f3, infinity
ADRL r0, infinity
LDFS f3, [r0]
CMF f0, f1
BVS hypot_nan
MVFMIS f2, f0
......
......@@ -85,4 +85,59 @@
Entry strtoimax, imported, , unveneered
Entry strtoumax, imported, , unveneered
Entry __assert2, imported, , unveneered
Entry _Exit, imported, , unveneered
Entry acosf, , , unveneered
Entry asinf, , , unveneered
Entry atanf, imported, , unveneered
Entry atan2f, imported, , unveneered
Entry cosf, imported, , unveneered
Entry sinf, imported, , unveneered
Entry tanf, , , unveneered
Entry acosh, imported, , unveneered
Entry acoshf, imported, , unveneered
Entry asinh, imported, , unveneered
Entry asinhf, imported, , unveneered
Entry atanh, imported, , unveneered
Entry atanhf, imported, , unveneered
Entry expf, , , unveneered
Entry exp2, , , unveneered
Entry exp2f, , , unveneered
Entry expm1, , , unveneered
Entry expm1f, , , unveneered
Entry frexpf, imported, , unveneered
Entry ilogb, imported, , unveneered
Entry ilogbf, imported, , unveneered
Entry ldexpf, imported, , unveneered
Entry logf, , , unveneered
Entry log10f, , , unveneered
Entry log1p, , , unveneered
Entry log1pf, , , unveneered
Entry log2, , , unveneered
Entry log2f, , , unveneered
Entry logb, imported, , unveneered
Entry logbf, imported, , unveneered
Entry modff, imported, , unveneered
Entry fmodf, imported, , unveneered
Entry scalbn, imported, , unveneered
Entry scalbnf, imported, , unveneered
Entry scalbln, imported, , unveneered
Entry scalblnf, imported, , unveneered
Entry cbrt, , , unveneered
Entry cbrtf, , , unveneered
Entry powf, , , unveneered
Entry sqrtf, , , unveneered
Entry erf, imported, , unveneered
Entry erff, imported, , unveneered
Entry erfc, imported, , unveneered
Entry erfcf, imported, , unveneered
Entry lgamma, imported, , unveneered
Entry lgammaf, imported, , unveneered
Entry tgamma, imported, , unveneered
Entry tgammaf, imported, , unveneered
Entry nexttoward, , , unveneered
Entry nexttowardf, , , unveneered
Entry fmaf, , , unveneered
END
......@@ -79,6 +79,11 @@ SharedLibrary SETL {TRUE}
|_kernel_entrypoint|
SWI GetEnv
[ APCS_Type <> "APCS-R" :LAND: Code_Destination = "RAM"
MOV sp, r1
BL EnsureCLib
; SWIVS GenerateError
]
MOV r2, r1
LDR r1, =|Image$$RW$$Limit|
MOV r3, #-1
......@@ -185,6 +190,10 @@ LookupError
; Note that finalise always discards the RMA (whether fatal or not)
; so initialise always acquires it. Is this reasonable?
STMFD sp!, {r14}
[ APCS_Type <> "APCS-R" :LAND: Code_Destination = "RAM"
BL EnsureCLib
; LDMVSFD sp!, {pc}
]
MOV r9, r0 ; save 'copy statics' flag
; [ Code_Destination = "RAM"
; Old versions of RelocCode would "return" the last field of the
......@@ -305,6 +314,43 @@ LookupError
LDMIA sp!, {pc}
]
[ APCS_Type <> "APCS-R" :LAND: Code_Destination = "RAM"
EnsureCLib
STMFD sp!, {r0,lr}
; ADR r0, RMEnsure1
; SWI CLI
ADR r0, RMEnsure2
SWI CLI
; ADRVC r0, RMEnsure3
; SWIVC CLI
ADRVC r0, RMEnsure4
SWIVC CLI
; ADRVC r0, RMEnsure5
; SWIVC CLI
ADRVC r0, RMEnsure6
SWIVC CLI
; ADRVC r0, RMEnsure7
; SWIVC CLI
STRVS r0, [sp]
LDMFD sp!, {r0,pc}
;RMEnsure1
; = "RMEnsure UtilityModule 3.10", 0
RMEnsure2
= "RMEnsure UtilityModule 3.70 RMEnsure CallASWI 0.02 RMLoad System:Modules.CallASWI", 0
;RMEnsure3
; = "RMEnsure UtilityModule 3.70 RMEnsure CallASWI 0.02", 0
RMEnsure4
= "RMEnsure FPEmulator 4.03 RMLoad System:Modules.FPEmulator", 0
;RMEnsure5
; = "RMEnsure FPEmulator 4.03", 0
RMEnsure6
= "RMEnsure SharedCLibrary 5.17 RMLoad System:Modules.CLib", 0
;RMEnsure7
; = "RMEnsure SharedCLibrary 5.34", 0
ALIGN
]
EXPORT |_clib_initialisemodule|
|_clib_initialisemodule|
STMFD sp!, {r14}
......
......@@ -100,8 +100,8 @@ extern void *_sys_alloc(size_t n);
extern void _init_user_alloc(void);
extern void _terminate_user_alloc(void);
extern void _sys_msg(const char *);
extern bool _sys__assert(const char *fmt,
const char *expr, const char *file, int line);
extern bool _sys__assert(const char *fmt, const char *expr,
const char *func, const char *file, int line);
extern void _exit(int n);
extern void _terminate_getenv(void);
......@@ -153,7 +153,7 @@ extern struct _svcwto _io_emsg; /* beware only 64 bytes thereof */
/* For the current ARM floating point system that Acorn use the first */
/* word of a floating point value is the one containing the exponent. */
# undef OTHER_WORD_ORDER_FOR_FP_NUMBERS
# define DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS 1
/*# define DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS 1*/
# endif
# endif
#endif
......@@ -350,9 +350,11 @@ extern FILE *_fopen_string_file(const char *data, int length);
#ifdef DEFAULT_TEXT
extern char *_kernel_getmessage(char *msg, char *tag);
extern char *_kernel_getmessage2(char *msg, char *tag, char *dst, size_t len);
#define _kernel_getmessage_def(msg, tag) _kernel_getmessage(msg, tag)
#else
extern char *_kernel_getmessage(char *tag);
extern char *_kernel_getmessage2(char *tag, char *dst, size_t len);
extern char *_kernel_getmessage_def(char *msg, char *tag);
#define _kernel_getmessage(msg, tag) _kernel_getmessage(tag)
#define _kernel_getmessage2(msg, tag, dst, len) _kernel_getmessage2(tag, dst, len)
#endif
......
......@@ -3150,6 +3150,7 @@ dividebyzero
EXPORT |_kernel_copyerror|
EXPORT |_kernel_getmessage|
EXPORT |_kernel_getmessage_def|
EXPORT |_kernel_getmessage2|
[ SharedLibrary ; Only works with module for the moment
......@@ -3197,15 +3198,14 @@ n_module_lookupname EQU 18
; Return:
; R0 = Message
;
[ :DEF:DEFAULT_TEXT
|_kernel_getmessage|
]
|_kernel_getmessage_def|
FunctionEntry "r0-r7,r12"
BL open_messagefile
MOV r0, r1
[ :DEF:DEFAULT_TEXT
LDR r1, [sp, #4]
|
LDR r1, [sp]
]
MOV r2, #0
MOV r4, #0
MOV r5, #0
......@@ -3215,6 +3215,20 @@ n_module_lookupname EQU 18
STRVC r2, [sp]
Return "r0-r7,r12"
[ :LNOT::DEF:DEFAULT_TEXT
; On entry:
; R0 = Message tag
;
; Return:
; R0 = Message
;
|_kernel_getmessage|
FunctionEntry "r1"
MOV r1, r0
BL |_kernel_getmessage_def|
Return "r1"
]
; On entry:
; [ DEFAULT_TEXT
; R0 = Message to use if failed to get message from message file
......@@ -3292,6 +3306,7 @@ open_messagefile
Return ,LinkNotStacked
|_kernel_getmessage|
|_kernel_getmessage_def|
|_kernel_getmessage2|
Return ,LinkNotStacked
......
......@@ -267,8 +267,6 @@ static int txt1__min(int a, int b) {return(a < b ? a : b);}
static int txt1__max(int a, int b) {return(a > b ? a : b);}
static int txt1__abs(int a) {return(a < 0 ? -a : a);}
/* -------- checking and debugging. -------- */
#if TRACE
......@@ -1405,7 +1403,7 @@ of the succuessor line rather than the end of the previous one. */
txt1__horizmeasure(t, x, t->w->caretx + t->w->caretoffsetx, &at);
if (
0 == (txt_DISPLAY & t->charoptionset)
|| (txt1__abs(by) < (3 * t->w->limy) / (4 * t->w->linesep))) {
|| (abs(by) < (3 * t->w->limy) / (4 * t->w->linesep))) {
/* could end up doing on-screen block copies */
tracef0("movevertical is near.\n");
txt1_dosetdot(t, txt1__bufindextoindex(t, at));
......@@ -1476,7 +1474,7 @@ void txt1_domovehorizontal(txt t, int by)
caret = 0 != (txt_CARET & t->charoptionset);
t->charoptionset &= ~txt_CARET;
spacewidth = txt1__spacewidth(t);
for (i = 1; i <= txt1__abs(by); i++) {
for (i = 1; i <= abs(by); i++) {
if (((t->w->caretoffsetx > 0) || ((t->w->caretoffsetx == 0) && (by > 0)))
&& ((t->gapend == txt1__termchbi(t)) || (t->buf[t->gapend] == '\n'))
&& (t->w->caretoffsetx + t->w->caretx + by*spacewidth <= t->w->limx)
......@@ -2440,7 +2438,7 @@ void txt1__updatescrollbar(txt t)
offset = (first * 100) / max;
};
/* try not to keep fiddling the size by small amounts. */
if (t->w->isize != 0 && txt1__abs(size - t->w->isize) < 3) {
if (t->w->isize != 0 && abs(size - t->w->isize) < 3) {
size = t->w->isize;
};
if (size != t->w->isize || offset != t->w->ioffset) {
......@@ -3376,7 +3374,7 @@ a move or replace. */
tracef3("limy=%i lastvisy=%i linesep=%i\n",
t->w->limy, t->w->lastvisy, t->w->linesep);
if (by == 0) return;
byy = txt1__abs(by) * t->w->linesep;
byy = abs(by) * t->w->linesep;
/* >>>> replaced by stuff below
if ((by > 0) && (t->w->lastvis.pos == txt1__termchbi(t))) {
......
......@@ -216,8 +216,6 @@ static int txtar__max(int a, int b) {return(a > b ? a : b);}
static int txtar__min(int a, int b) {return(a < b ? a : b);}
static int txtar__abs(int a) {return(a < 0 ? -a : a);}
static void txtar__setmode(txtar__sysdata *s) {
txt t = s->t;
#ifdef BIG_WINDOWS
......@@ -2466,8 +2464,8 @@ drag event. */
m = 0;
};
if ((txtar__abs(s->prevmousex - e->data.but.m.x) <= 2 * wimpt_dx())
&& (txtar__abs(s->prevmousey - e->data.but.m.y) <= 2 * wimpt_dy())
if ((abs(s->prevmousex - e->data.but.m.x) <= 2 * wimpt_dx())
&& (abs(s->prevmousey - e->data.but.m.y) <= 2 * wimpt_dy())
&& (mousetime - s->prevmousetime < 100)) {
tracef0("mouse exact multi-click.\n");
m |= txt_MEXACT;
......
; Copyright 2003 Tematic Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; As long double is the same as double, all the long double <math.h> functions
; can just bounce to the double ones. These bounces are included in ANSILib
; and the stubs as is - the Shared C Library doesn't contain or export them.
AREA |C$$code|, CODE, READONLY
MACRO
DoL $func
EXPORT $func.l
IMPORT $func
$func.l B $func
MEND
DoL acos
DoL asin
DoL atan
DoL atan2
DoL cos
DoL sin
DoL tan
DoL acosh
DoL asinh
DoL atanh
DoL cosh
DoL sinh
DoL tanh
DoL exp
DoL exp2
DoL expm1
DoL frexp
DoL ilogb
DoL ldexp
DoL log
DoL log10
DoL log1p
DoL log2
DoL logb
DoL modf
DoL scalbn
DoL scalbln
DoL cbrt
DoL fabs
DoL hypot
DoL pow
DoL sqrt
DoL erf
DoL erfc
DoL lgamma
DoL tgamma
DoL ceil
DoL floor
DoL nearbyint
DoL rint
DoL lrint
DoL round
DoL lround
DoL trunc
DoL fmod
DoL remainder
; DoL remquo
DoL copysign
DoL nan
DoL nextafter
DoL nexttoward
DoL fdim
DoL fmax
DoL fmin
; DoL fma
END
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