Commit 89eac61e authored by Kevin Bracey's avatar Kevin Bracey
Browse files

* Added two new library chunks, 4 and 5, which contain extensions to the...

* Added two new library chunks, 4 and 5, which contain extensions to the kernel and C library respectively. These have no static data associated with them, just being extensions of the stub tables. The reason for this is to minimise wasted space in programs that don't use the C99 facilities; o.stubs is now a library split into 3 pieces - basic kernel and CLib, extra kernel and extra

  CLib; only the bits a program needs get included.

* Previous extensions to the C library stubs revoked - they now stop at _swix;
  all the new C99 functions now live in chunk 4. Anyone using those new
  functions should relink with new stubs and ensure this C library version.

* printf/scanf now support 64-bit types through "ll" and "j" length modifiers.

* Run-time support for VLAs (__rt_allocauto and __rt_freeauto) added. No
  attempt is currently made to clear up on longjmp or to cope with someone
  changing the kernel allocator while a VLA is active. These would be a
  future enhancement.

* Added complete 64-bit run-time support (48 functions) to kernel library;
  these functions are compatible with the ones used by the ARM ADS. Many of
  the simpler functions will not normally be used by the compiler, as it
  will generate inline code. There is scope for improvement by switching
  in MULL and CLZ-using forms of multiply and divide when possible.

* llabs and lldiv added to C library.

* Header files corrected in a few areas, and changed to match the C compiler.
  <stdint.h> and <stdbool.h> now require the compiler to be in C99 mode
  (as detected using __STDC_VERSION__).


Version 5.41. Tagged as 'RISC_OSLib-5_41'
parent 280c51dc
......@@ -277,7 +277,8 @@ EXPORTS = ${MODWRAP} \
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.signal o.sort o.stdio o.stdlib o.string o.swiv o.time o.fenv \
o.longlong
RM_OBJS =\
rm_o.k_modbody \
......@@ -289,6 +290,7 @@ RM_OBJS =\
rm_o.error \
rm_o.fpprintf \
rm_o.locale \
rm_o.longlong \
rm_o.math \
rm_o.memcpset \
rm_o.printf \
......@@ -562,17 +564,41 @@ lib.risc_oslib: ${RLIB_OBJS}
lib.riscoslibm: ${RLIB_MOD_OBJS}
${LIBFILE} ${LIBFLAGS} $@ ${RLIB_MOD_OBJS}
lib.stubs: clib.s.cl_stub_r
o.cl_stub_r: clib.s.cl_stub_r
${OBJASM} ${ALFLAGS} -from clib.s.cl_stub_r -to $@
lib.rstubs: rlib.s.rl_stub_r
o.cl_stub2_r: clib.s.cl_stub2_r
${OBJASM} ${ALFLAGS} -from clib.s.cl_stub2_r -to $@
o.k_stub2_r: kernel.s.k_stub2_r
${OBJASM} ${ALFLAGS} -from kernel.s.k_stub2_r -to $@
o_rl.rl_stub_r: rlib.s.rl_stub_r
${OBJASM} ${ALFLAGS} -from rlib.s.rl_stub_r -to $@
lib.romcstubs: clib.s.cl_stub_rm
${OBJASM} ${AFLAGS} -from clib.s.cl_stub_rm -to $@
rm_o.cl_stub_rm: clib.s.cl_stub_rm
${OBJASM} ${ALFLAGS} -from clib.s.cl_stub_rm -to $@
rm_o.cl_stub2_rm: clib.s.cl_stub2_rm
${OBJASM} ${ALFLAGS} -from clib.s.cl_stub2_rm -to $@
rm_o.k_stub2_rm: kernel.s.k_stub2_rm
${OBJASM} ${ALFLAGS} -from kernel.s.k_stub2_rm -to $@
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.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.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.romstubs: rlib.s.rl_stub_rm
${OBJASM} ${AFLAGS} -from rlib.s.rl_stub_rm -to $@
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.romastubs: rlib.s.rl_stub_a
${OBJASM} ${AFLAGS} -from rlib.s.rl_stub_a -to $@
......
;
; This file is automatically maintained by srccommit, do not edit manually.
; Last processed by srccommit version: 1.62.
; Last processed by srccommit version: 1.63.
;
GBLS Module_MajorVersion
GBLA Module_Version
......@@ -12,14 +12,14 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.40"
Module_Version SETA 540
Module_MajorVersion SETS "5.41"
Module_Version SETA 541
Module_MinorVersion SETS ""
Module_Date SETS "12 Apr 2002"
Module_ApplicationDate2 SETS "12-Apr-02"
Module_ApplicationDate4 SETS "12-Apr-2002"
Module_Date SETS "22 May 2002"
Module_ApplicationDate2 SETS "22-May-02"
Module_ApplicationDate4 SETS "22-May-2002"
Module_ComponentName SETS "RISC_OSLib"
Module_ComponentPath SETS "RiscOS/Sources/Lib/RISC_OSLib"
Module_FullVersion SETS "5.40"
Module_HelpVersion SETS "5.40 (12 Apr 2002)"
Module_FullVersion SETS "5.41"
Module_HelpVersion SETS "5.41 (22 May 2002)"
END
/* (5.40)
/* (5.41)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.62.
* Last processed by srccommit version: 1.63.
*
*/
#define Module_MajorVersion_CMHG 5.40
#define Module_MajorVersion_CMHG 5.41
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 12 Apr 2002
#define Module_Date_CMHG 22 May 2002
#define Module_MajorVersion "5.40"
#define Module_Version 540
#define Module_MajorVersion "5.41"
#define Module_Version 541
#define Module_MinorVersion ""
#define Module_Date "12 Apr 2002"
#define Module_Date "22 May 2002"
#define Module_ApplicationDate2 "12-Apr-02"
#define Module_ApplicationDate4 "12-Apr-2002"
#define Module_ApplicationDate2 "22-May-02"
#define Module_ApplicationDate4 "22-May-2002"
#define Module_ComponentName "RISC_OSLib"
#define Module_ComponentPath "RiscOS/Sources/Lib/RISC_OSLib"
#define Module_FullVersion "5.40"
#define Module_HelpVersion "5.40 (12 Apr 2002)"
#define Module_LibraryVersionInfo "5:40"
#define Module_FullVersion "5.41"
#define Module_HelpVersion "5.41 (22 May 2002)"
#define Module_LibraryVersionInfo "5:41"
......@@ -345,9 +345,7 @@ static int *stackOnEntryToAlloc;
#define STACKDEPTH(local, depth)
#endif
static void _alloc_die(message, rc)
char *message;
int rc;
static void _alloc_die(char *message, int rc)
{
char *cs, *ct;
......@@ -376,16 +374,14 @@ int rc;
#endif
}
static void bad_size(size)
size_t size;
static void bad_size(size_t size)
{
IGNORE(size);
_alloc_die(_kernel_getmessage("Over-large or -ve size request", "C11"), FAILED);
}
#ifdef STATS
void print_event(event)
int event;
void print_event(int event)
{
switch (event) {
case GARBAGE_COLLECT: D0("Garbage Collect :"); break;
......@@ -398,10 +394,7 @@ int event;
}
}
static void MakeEventRec(thisEvent, type, size)
int thisEvent;
Events type;
size_t size;
static void MakeEventRec(int thisEvent, Events type, size_t size)
{
statsP->nextEvent = thisEvent + 1;
thisEvent %= MAXEVENTS;
......@@ -431,22 +424,15 @@ size_t size;
/* ------------------------- Statistics reporting --------------------------*/
extern void _GetStorageInfo(info)
StorageInfoP info;
extern void _GetStorageInfo(StorageInfoP info)
{
statsP->stats.currentHeapRequirement = totalHeap - totalFree;
*info = statsP->stats;
}
extern void _NextHeapElement(
nextBase, guard, size, free, heapHole, bitmap, firstWord)
BlockP *nextBase;
unsigned int *guard;
size_t *size;
int *free;
int *heapHole;
int *bitmap;
unsigned int *firstWord;
extern void _NextHeapElement(BlockP *nextBase, unsigned int *guard,
size_t *size, int *free, int *heapHole,
int *bitmap, unsigned int *firstWord)
{ BlockP junkBlock;
if (*nextBase == NULL) {junkBlock = heapLow;} else {junkBlock = *nextBase;}
#ifdef BLOCKS_GUARDED
......@@ -470,9 +456,7 @@ unsigned int *firstWord;
if (*nextBase > heapHigh) *nextBase = NULL;
}
extern int _GetEventData(event, info)
int event;
EventInfoP info;
extern int _GetEventData(int event, EventInfoP info)
{ int index;
int previous;
if ((event >= statsP->nextEvent) || (event < statsP->nextEvent-MAXEVENTS)
......@@ -584,8 +568,7 @@ static void ShowStats(void)
#endif
#ifdef GC
static void SetBlockFree(block)
BlockP block;
static void SetBlockFree(BlockP block)
{
D1("!!SetBlockFree &%X\n", (unsigned) block);
block->size |= FREEBIT;
......@@ -600,8 +583,7 @@ static void init_bitmaps(void)
memset(mapForExistingHeap, ~0, SIZE(ADDBYTES(mapForExistingHeap,-OVERHEAD)));
}
extern int __register_gc_proc(proc)
GCProc proc;
extern int __register_gc_proc(GCProc proc)
{
ACQUIREMUTEX;
F0("!!__register_gc_proc\n");
......@@ -618,14 +600,12 @@ GCProc proc;
#endif
#ifdef BLOCKS_GUARDED
extern void __heap_checking_on_all_deallocates(on)
int on;
extern void __heap_checking_on_all_deallocates(int on)
{
checkDeallocates = on;
}
extern void __heap_checking_on_all_allocates(on)
int on;
extern void __heap_checking_on_all_allocates(int on)
{
checkAllocates = on;
}
......@@ -729,8 +709,7 @@ static int internal_coalesce(void)
return OK;
}
static int InsertBlockInOverflowList(block)
BlockP block;
static int InsertBlockInOverflowList(BlockP block)
{
#if HEAP_ALLOCATED_IN_ASCENDING_ADDRESS_ORDER
F0("!!InsertBlockInOverflowList &")
......@@ -772,10 +751,8 @@ BlockP block;
return OK;
}
static int GetMoreOSHeap(minSize, base_ptr, size_ptr)
size_t minSize;
BlockP *base_ptr;
size_t *size_ptr;
static int GetMoreOSHeap(size_t minSize, BlockP *base_ptr,
size_t *size_ptr)
{ size_t size = *size_ptr;
BlockP base = *base_ptr;
#ifdef GC
......@@ -1065,13 +1042,11 @@ static int check_heap(void)
}
#endif
#define COALESCED (1<<31)
#define DONEGC (1<<30)
#define FORCECOALESCE (1<<29)
#define COALESCED (1u<<31)
#define DONEGC (1u<<30)
#define FORCECOALESCE (1u<<29)
static int primitive_alloc(gcBits, size/*words*/)
int gcBits;
size_t size;
static int primitive_alloc(int gcBits, size_t size/*words*/)
{ BlockP block;
size_t actualSize;
register int index;
......@@ -1293,8 +1268,7 @@ split_block:
RELEASEANDRETURN((int)block)
}
static int primitive_dealloc(block)
BlockP block;
static int primitive_dealloc(BlockP block)
{ int size;
ACQUIREMUTEX;
F0("!!primitive_dealloc: block ")
......@@ -1346,8 +1320,7 @@ BlockP block;
/*
* Put the veneer functions here for now: don't really need all these.
*/
extern size_t _byte_size(p)
VoidStar p;
extern size_t _byte_size(VoidStar p)
{ BlockP block = (BlockP)p;
if (block != NULL) {
/* decrement the pointer (block) by the number of overhead bytes */
......@@ -1357,8 +1330,7 @@ VoidStar p;
return 0;
}
extern VoidStar malloc(size)
size_t size;
extern VoidStar malloc(size_t size)
{ VoidStar ptr;
if (_kernel_processor_mode() & 0xF) /* not USR26 or USR32 */
return _kernel_RMAalloc(size);
......@@ -1376,9 +1348,7 @@ size_t size;
return ptr;
}
extern VoidStar realloc(p, size)
VoidStar p;
size_t size;
extern VoidStar realloc(VoidStar p, size_t size)
{ int rc;
size_t old;
VoidStar new = NULL;
......@@ -1421,9 +1391,7 @@ size_t size;
return p;
}
extern VoidStar calloc(count, size)
size_t count;
size_t size;
extern VoidStar calloc(size_t count, size_t size)
{ VoidStar r;
/*
* This miserable code computes a full 64-bit product for count & size
......@@ -1450,8 +1418,7 @@ size_t size;
return r;
}
extern void free(p)
VoidStar p;
extern void free(VoidStar p)
{ int rc;
/* free(0) now allowed!!! ECN - 21 09 93 */
if (!p) return;
......@@ -1471,9 +1438,7 @@ VoidStar p;
}
#ifdef CAMEL
static void _allocate(a, bitlen)
VoidStar *a;
size_t bitlen;
static void _allocate(VoidStar *a, size_t bitlen)
/* Default storage allocator */
{ int local;
if (bitlen > 0) {
......@@ -1489,9 +1454,7 @@ size_t bitlen;
}
#endif
extern void _deallocate(a, bitlen)
VoidStar *a;
size_t bitlen;
extern void _deallocate(VoidStar *a, size_t bitlen)
/* Default storage deallocator */
{ VoidStar p = *a;
int rc;
......@@ -1506,8 +1469,7 @@ size_t bitlen;
}
}
extern VoidStar _sys_alloc(n)
size_t n;
extern VoidStar _sys_alloc(size_t n)
{ VoidStar a = malloc(n);
if (a == NULL)
_alloc_die(_kernel_getmessage("No store left for I/O buffer or the like", "C17"), FAILED);
......@@ -1515,9 +1477,7 @@ size_t n;
}
#ifdef GC
extern VoidStar _gc_malloc(gcbits, size)
int gcbits;
size_t size;
extern VoidStar _gc_malloc(int gcbits, size_t size)
{ VoidStar ptr;
ptr = (VoidStar) primitive_alloc(gcbits, BYTESTOWORDS(size));
if ((int)ptr == FAILED || (int)ptr == CORRUPT) {
......@@ -1530,10 +1490,7 @@ size_t size;
return ptr;
}
extern void _gcallocate(a, bitlen, gcbits)
VoidStar *a;
size_t bitlen;
int gcbits;
extern void _gcallocate(VoidStar *a, size_t bitlen, int gcbits)
/* The M2 ALLOCATE function */
{ int local;
if (bitlen > 0) {
......@@ -1548,9 +1505,7 @@ int gcbits;
} else *a = NULL;
}
extern void _set_gcbits(a, gcbits)
VoidStar *a;
int gcbits;
extern void _set_gcbits(VoidStar *a, int gcbits)
{ BlockP p = (BlockP)*a;
/*
* Must acquire the storage lock:- else we cannot change the word (which
......@@ -1641,7 +1596,7 @@ static int _allocated_by_me(BlockP block)
return 0;
}
extern int _alloc_reinit()
extern int _alloc_reinit(void)
{
_kernel_stack_chunk *prev = _kernel_current_stack_chunk();
_kernel_stack_chunk *chunk = prev->sc_next;
......
......@@ -54,6 +54,7 @@ extern int __vfprintf(FILE *fp, const char *fmt,
#define _PADZERO 0200 /* *** DEPRECATED FEATURE *** */
#define _FPCONV 0400
#define _CHARSPEC 01000
#define _LONGLONGSPEC 02000
#ifndef NO_FLOATING_POINT
......
......@@ -378,7 +378,8 @@ size_t strftime(char *s, size_t maxsize, const char *fmt, const struct tm *tt)
/* Format for "C" locale changed as per C99 */
if (!territory)
sprintf(ss, "%s %s %2d %.2d:%.2d:%.2d %d",
abbrweek[tt->tm_wday], abbrmonth[tt->tm_mon], tt->tm_mday,
tt->tm_wday < 7U ? abbrweek[tt->tm_wday] : "???",
abbrmonth[tt->tm_mon], tt->tm_mday,
tt->tm_hour, tt->tm_min, tt->tm_sec, tt->tm_year + 1900);
/*sprintf(ss, "%02d %s %d %02d:%02d:%02d",
tt->tm_mday, abbrmonth[tt->tm_mon], tt->tm_year + 1900,
......
......@@ -54,8 +54,7 @@
#ifndef DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS
double frexp(d, lvn)
double d; int *lvn;
double frexp(double d, int *lvn)
{
/* This version works even if d starts off as an unnormalized number in */
/* the IEEE sense. But in that special case it will be mighty slow! */
......@@ -90,8 +89,7 @@ double d; int *lvn;
#else /* DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS */
double frexp(d, lvn)
double d; int *lvn;
double frexp(double d, int *lvn)
{
fp_number d1;
if (d==0.0)
......@@ -106,8 +104,7 @@ double d; int *lvn;
#endif /* DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS */
double ldexp(d, n)
double d; int n;
double ldexp(double d, int n)
{
fp_number d1;
int nx;
......
......@@ -75,6 +75,7 @@ int _sprintf_lf(char *buff, const char *fmt, ...);
#define _PADZERO 0200 /* *** DEPRECATED FEATURE *** */
#define _FPCONV 0400
#define _CHARSPEC 01000
#define _LONGLONGSPEC 02000
#endif /* _LJUSTIFY */
......@@ -96,7 +97,7 @@ static int pr_num(unsigned int v, int flags, char *prefix,
#endif
static int printf_display(FILE *p, int flags, int ch, int precision, int width,
unsigned int v, fp_print fp_display_fn, char *prefix,
unsigned long long v, fp_print fp_display_fn, char *prefix,
char *hextab, double *d)
{
int charcount = 0;
......@@ -123,7 +124,7 @@ static int printf_display(FILE *p, int flags, int ch, int precision, int width,
case 'u':
case 'i':
case 'd': while (v != 0)
{ unsigned int vDiv10 = _kernel_udiv10(v);
{ unsigned long long vDiv10 = v / 10U;
buff[len++] = '0' + v - vDiv10 * 10U;
v = vDiv10;
}
......@@ -220,7 +221,7 @@ int __vfprintf(FILE *p, const char *fmt, va_list args,
/* to a real string before use, but necessary in that passing unset */
/* parameters to functions is illegal in C. */
char *prefix, *hextab = 0;
unsigned int v;
unsigned long long v;
#ifndef NO_FLOATING_POINT
double d;
#endif
......@@ -293,29 +294,41 @@ int __vfprintf(FILE *p, const char *fmt, va_list args,
}
if (t >= 0) flags |= _PRECGIVEN, precision = t;
}
if (ch=='l' || ch=='L' || ch=='j' || ch=='z' || ch=='t')
if (ch=='l' || ch=='L' || ch=='z' || ch=='t')
/* 'l' Indicate that a numeric argument is 'long'. Here int and long */
/* are the same (32 bits) and so I can ignore this flag! */
/* 'L' Marks floating arguments as being of type long double. Here this */
/* is the same as just double, and so I can ignore the flag. */
/* 'j' Indicates that a numeric argument is 'intmax_t', or that a %n */
/* argument is a pointer to an intmax_t. We can ignore it. */
/* 'z' Indicates that a numeric argument is 'size_t', or that a %n */
/* argument is a pointer to a size_t. We can ignore it. */
/* 't' Indicates that a numeric argument is 'ptrdiff_t', or that a %n */
/* argument is a pointer to a ptrdiff_t. We can ignore it. */
{ flags |= _LONGSPECIFIER;
{ int last = ch;
flags |= _LONGSPECIFIER;
ch = *fmt++;
/* 'll' Indicates that a numeric argument is 'long long', or that a %n */
/* argument is a pointer to long long int. */
if (ch=='l' && last =='l')
{ flags |= _LONGLONGSPEC;
ch = *fmt++;
}
}
else if (ch=='h')
/* 'h' Indicates that an integer value is to be treated as short. */
/* 'h' Indicates that an integer value is to be treated as short. */
{ flags |= _SHORTSPEC;
ch = *fmt++;
/* 'hh' Indicates that an integer value is to be treated as char. */
if (ch=='h')
{ flags |= _CHARSPEC;
ch = *fmt++;
}
}
else if (ch=='j')
/* 'j' Indicates that a numeric argument is '[u]intmax_t', or than a %n */
/* argument is a pointer to intmax_t. */
{ flags |= _LONGSPECIFIER|_LONGLONGSPEC;
ch = *fmt++;
}
/* Now the options have been decoded - I can process the main dispatch */
switch (ch)
......@@ -347,8 +360,13 @@ int __vfprintf(FILE *p, const char *fmt, va_list args,
continue;
/* %n assigns the number of chars printed so far to the next arg (which */
/* is expected to be of type (int *). */
case 'n': { int *xp = va_arg(args, int *);
/* is expected to be of type (int *), or (long long *) if 'j' or 'll'. */
case 'n': if (flags & _LONGLONGSPEC)
{ long long *xp = va_arg(args, long long *);
*xp = charcount;
}
else
{ int *xp = va_arg(args, int *);
*xp = charcount;
}
continue;
......@@ -375,7 +393,8 @@ int __vfprintf(FILE *p, const char *fmt, va_list args,
/* when printing things that are not (decimal) digits. */
/* I can share some messy decoding here with the code that deals with */
/* octal and decimal output via %o and %d. */
case 'X': v = va_arg(args, int);
case 'X': v = (flags & _LONGLONGSPEC) ? va_arg(args, unsigned long long)
: va_arg(args, unsigned int);
if (flags & _SHORTSPEC) v = (unsigned short)v;
if (flags & _CHARSPEC) v = (unsigned char)v;
hextab = "0123456789ABCDEF";
......@@ -383,7 +402,8 @@ int __vfprintf(FILE *p, const char *fmt, va_list args,
if (flags & _PRECGIVEN) flags &= ~_PADZERO;
break;
case 'x': v = va_arg(args, int);
case 'x': v = (flags & _LONGLONGSPEC) ? va_arg(args, unsigned long long)
: va_arg(args, unsigned int);
if (flags & _SHORTSPEC) v = (unsigned short)v;
if (flags & _CHARSPEC) v = (unsigned char)v;
hextab = "0123456789abcdef";
......@@ -400,14 +420,16 @@ int __vfprintf(FILE *p, const char *fmt, va_list args,
precision = 8;
break;
case 'o': v = va_arg(args, int);
case 'o': v = (flags & _LONGLONGSPEC) ? va_arg(args, unsigned long long)
: va_arg(args, unsigned int);
if (flags & _SHORTSPEC) v = (unsigned short)v;
if (flags & _CHARSPEC) v = (unsigned char)v;
prefix = (flags&_VARIANT) ? "0" : "";
if (flags & _PRECGIVEN) flags &= ~_PADZERO;
break;
case 'u': v = va_arg(args, unsigned int);
case 'u': v = (flags & _LONGLONGSPEC) ? va_arg(args, unsigned long long)
: va_arg(args, unsigned int);
if (flags & _SHORTSPEC) v = (unsigned short)v;
if (flags & _CHARSPEC) v = (unsigned char)v;
prefix = "";
......@@ -415,10 +437,12 @@ int __vfprintf(FILE *p, const char *fmt, va_list args,
break;
case 'i':
case 'd': { int w = va_arg(args, int);
case 'd': { long long w;
w = (flags & _LONGLONGSPEC) ? va_arg(args, long long)
: va_arg(args, int);
if (flags & _SHORTSPEC) w = (signed short)w;
if (flags & _CHARSPEC) w = (signed char)w;
if (w<0) v = 0U-w, prefix = "-";
if (w<0) v = 0ULL-w, prefix = "-";
else
v = w, prefix = (flags&_SIGNED) ? "+" :
(flags&_BLANKER) ? " " : "";
......
......@@ -56,12 +56,14 @@ extern int __backspace(FILE *stream); /* a strict R-inverse of getc() */
#define NUMOK 0400 /* ditto + rd_int */
#define NUMNEG 01000 /* ditto + rd_int */
#define CHAR 02000
#define LONGLONG 04000
#define countgetc(p) (charcount++, getc(p))
/* The next macros, with the help of the compiler, ensures that we can */
/* test for LONG and SHORT properly, but not general extra code. */
#define isLONGLONG_(flag) ((flag) & LONGLONG)
#define isLONG_(flag) ((flag) & LONG && sizeof(int) != sizeof(long))
#define isSHORT_(flag) ((flag) & SHORT)
#define isCHAR_(flag) ((flag) & CHAR)
......@@ -97,7 +99,7 @@ static int ch_val(int ch, int radix)
static long int rd_int(FILE *p, va_list res, int flag, int radix, int field)
{ long int charcount = -1; /* allow for always ungetc */
unsigned long int n = 0;
unsigned long long int n = 0;
int ch;
while (isspace(ch = countgetc(p))); /* leading whitespace */
if (ch == EOF) return CVTEOF;
......@@ -132,19 +134,21 @@ case '+': ch = countgetc(p);
if (!(flag & NOSTORE))
{ /* This code is pretty specious on a 2's complement machine */
if (flag & ALLOWSIGN)
{ long int m = flag & NUMNEG ? -n : n;
{ long long m = flag & NUMNEG ? -n : n;
int *p = va_arg(res, int *); /* rely on sizeof(int*)=sizeof(short*) */
if isCHAR_(flag) *(signed char *)p = (signed char)m;
else if isSHORT_(flag) *(short *)p = (short)m;
else if isLONG_(flag) *(long *)p = m;
else if isLONG_(flag) *(long *)p = (long)m;
else if isLONGLONG_(flag) *(long long *)p = m;
else *(int *)p = (int)m;
}
else /* pointer case comes here too - with quite some type pun! */
{ unsigned int *p = va_arg(res, unsigned int *);
/* rely on sizeof(unsigned int *)==sizeof(unsigned short *) */
if isCHAR_(flag) *(unsigned char *)p = (unsigned char)n;
if isSHORT_(flag) *(unsigned short *)p = (unsigned short)n;
else if isLONG_(flag) *(unsigned long *)p = n;
else if isSHORT_(flag) *(unsigned short *)p = (unsigned short)n;
else if isLONG_(flag) *(unsigned long *)p = (unsigned long)n;
else if isLONGLONG_(flag) *(unsigned long long *)p = n;
else *(unsigned int *)p = (unsigned int)n;
}
}
......@@ -699,13 +703,18 @@ case '%': { int field = 0, flag = 0;
flag |= FIELDGIVEN;
}
if (!(flag & FIELDGIVEN)) field = INT_MAX;
if (fch == 'l') fch = *fmt++, flag |= LONG;
if (fch == 'l')
{ fch = *fmt++;
if (fch == 'l') fch = *fmt++, flag |= LONGLONG;
else flag |= LONG;
}
else if (fch == 'L') fch = *fmt++, flag |= LONG | LONGDOUBLE;
else if (fch == 'h')
{ fch = *fmt++, flag |= SHORT;
if (fch == 'h') fch = *fmt++, flag |= CHAR;
}
else if (fch == 'j' || fch == 'z' || fch == 't') fch = *fmt++;
else if (fch == 'z' || fch == 't') fch = *fmt++;
else if (fch == 'j') fch = *fmt++, flag |= LONGLONG;
switch (fch)
{
default: return cnt; /* illegal conversion code */
......@@ -758,6 +767,7 @@ case '%': { int field = 0, flag = 0;
case 'n': if isCHAR_(flag) *va_arg(argv, char *) = (char)charcount;
else if isSHORT_(flag) *va_arg(argv, short *) = (short)charcount;
else if isLONG_(flag) *va_arg(argv, long *) = charcount;
else if isLONGLONG_(flag) *va_arg(argv, long long *) = charcount;
else *va_arg(argv, int *) = (int)charcount;
continue;
case 'o': worked = rd_int(p, argv, flag | ALLOWSIGN, 8, field);
......
......@@ -122,7 +122,7 @@ static void _default_sigstak_handler()
_kernel_exit(100);
}
#else
extern void _default_sigstak_handler();
extern void _default_sigstak_handler(void);
#endif
extern void __default_signal_handler(int sig)
......
......@@ -101,7 +101,7 @@ void srand(unsigned int seed)
#define EXIT_LIMIT 33
typedef void (*vprocp)(void);
static union { vprocp p; int i; } _exitvector[EXIT_LIMIT] = {};
static union { vprocp p; int i; } _exitvector[EXIT_LIMIT] = { 0 };
/* initialised so not in bss (or shared library trouble) */
static struct {
char number_of_exit_functions;
......@@ -172,5 +172,13 @@ long int labs(long int x)
else return x;
}
#if 0
/* Compiler generates poo code at the minute - in machine code for now */
long long int llabs(long long int x) {
if (x<0) return (-x);
else return x;
}
#endif
/* end of stdlib.c */
......@@ -25,9 +25,9 @@
typedef unsigned int fexcept_t;
/* represents the floating-point status flags collectively */
typedef struct fenv_t
{ unsigned status;
unsigned reserved[5];
typedef struct __fenv_t_struct
{ unsigned __status;
unsigned __reserved[5];
} fenv_t;
/* represents the entire floating-point environment */
......@@ -50,19 +50,19 @@ typedef struct fenv_t
#ifdef __cplusplus
extern "C" {
#endif
int feclearexcept(int excepts);
int feclearexcept(int /*excepts*/);
/* attempts to clear the supported floating-point exceptions represented */
/* by its argument. */
/* Returns: zero if the excepts argument is zero or if all the specified */
/* exceptions were successfully cleared. Otherwise, it returns */
/* a nonzero value. */
int fegetexceptflag(fexcept_t *flagp, int excepts);
int fegetexceptflag(fexcept_t */*flagp*/, int /*excepts*/);
/* attempts to store an implementation-defined representation of the */
/* states of the floating-point status flags indicated by the argument */
/* excepts in the object pointed to by the argument flagp. */
/* Returns: zero if the representation was successfully stored. */
/* Otherwise, it returns a nonzero value. */
int feraiseexcept(int excepts);
int feraiseexcept(int /*excepts*/);
/* attempts to raise the supported floating-point exceptions represented */
/* by its argument. The order in which these floating-point exceptions */
/* are raised is unspecified, except as stated in F.7.6. Whether the */
......@@ -72,7 +72,7 @@ int feraiseexcept(int excepts);
/* Returns: zero if the excepts argument is zero or if all the specified */
/* exceptions were successfully raised. Otherwise, it returns a */
/* nonzero value. */
int fesetexceptflag(const fexcept_t *flagp, int excepts);
int fesetexceptflag(const fexcept_t */*flagp*/, int /*excepts*/);
/* attempts to set the floating-point status flags indicated by the */
/* argument excepts to the states stored in the object pointed to by */
/* flagp. The value of *flagp shall have been set by a previous call to */
......@@ -83,7 +83,7 @@ int fesetexceptflag(const fexcept_t *flagp, int excepts);
/* Returns: zero if the excepts argument is zero or if all the specified */
/* flags were successfully set to the appropriate state. */
/* Otherwise, it returns a nonzero value. */
int fetestexcept(int excepts);
int fetestexcept(int /*excepts*/);
/* determines which of a specified subset of the floating-point */
/* exception flags are currently set. The excepts argument specifies the */
/* floating-point status flags to be queried. */
......@@ -97,26 +97,26 @@ int fegetround(void);
/* current rounding direction or a negative value if there is */
/* no such rounding direction macro or the current rounding */
/* direction is not determinable. */
int fesetround(int round);
int fesetround(int /*round*/);
/* establishes the rounding direction represented by its argument round. */
/* If the argument is not equal to the value of a rounding direction */
/* macro, the rounding direction is not changed. */
/* Returns: zero if and only if the requested rounding direction was */
/* established. */
int fegetenv(fenv_t *envp);
int fegetenv(fenv_t */*envp*/);
/* attempts to store the current floating-point environment in the */
/* object pointed to by envp. */
/* Returns: zero if the environment was successfully stored. Otherwise, */
/* it returns a nonzero value. */
int feholdexcept(fenv_t *envp);
int feholdexcept(fenv_t */*envp*/);
/* saves the current floating-point environment in the object pointed to */
/* by envp, clears the floating-point status flags, and then installs a */
/* non-stop (continue on floating-point exceptions) mode for all */
/* floating-point exceptions. */
/* Returns: zero if and only if non-stop floating-point exception */
/* handling was successfully installed. */
int fesetenv(const fenv_t *envp);
int fesetenv(const fenv_t */*envp*/);
/* attempts to establish the floating-point environment represented by */
/* the object pointed to by envp. The argument envp shall point to an */
/* object set by a call to fegetenv or feholdexcept, or equal a */
......@@ -125,7 +125,7 @@ int fesetenv(const fenv_t *envp);
/* argument, and does not raise these floating-point exceptions. */
/* Returns: zero if the environment was successfully established. */
/* Otherwise, it returns a nonzero value. */
int feupdateenv(const fenv_t *envp);
int feupdateenv(const fenv_t */*envp*/);
/* attempts to save the currently raised floating-point exceptions in */
/* its automatic storage, install the floating-point environment */
/* represented by the object pointed to by envp, and then raise the */
......
......@@ -17,182 +17,200 @@
/* inttypes.h: ISO 'C' (ISO/IEC 9899:1999) library header, section 7.8 */
/* Copyright (C) Element 14 Ltd. 1999 */
/* version 1.00 */
/* version 1.01 */
#ifndef __inttypes_h
#define __inttypes_h
#include "stdint.h"
/*
* A set of C9X-style definitions that make sense for the current
* (Norcroft 5) implementation. Note that we have no 64-bit types,
* as a conforming C9X implementation must. We also don't supply
* the four functions we're supposed to supply.
*/
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
#define PRId8 "d"
#define PRId16 "d"
#define PRId32 "d"
#define PRId64 "lld"
#define PRIdLEAST8 "d"
#define PRIdLEAST16 "d"
#define PRIdLEAST32 "d"
#define PRIdLEAST64 "lld"
#define PRIdFAST8 "d"
#define PRIdFAST16 "d"
#define PRIdFAST32 "d"
#define PRIdMAX "d"
#define PRIdFAST64 "lld"
#define PRIdMAX "lld"
#define PRIdPTR "d"
#define PRIi8 "i"
#define PRIi16 "i"
#define PRIi32 "i"
#define PRIi64 "lli"
#define PRIiLEAST8 "i"
#define PRIiLEAST16 "i"
#define PRIiLEAST32 "i"
#define PRIiLEAST64 "lli"
#define PRIiFAST8 "i"
#define PRIiFAST16 "i"
#define PRIiFAST32 "i"
#define PRIiMAX "i"
#define PRIiFAST64 "lli"
#define PRIiMAX "lli"
#define PRIiPTR "i"
#define PRIo8 "o"
#define PRIo16 "o"
#define PRIo32 "o"
#define PRIo64 "llo"
#define PRIoLEAST8 "o"
#define PRIoLEAST16 "o"
#define PRIoLEAST32 "o"
#define PRIoLEAST64 "llo"
#define PRIoFAST8 "o"
#define PRIoFAST16 "o"
#define PRIoFAST32 "o"
#define PRIoMAX "o"
#define PRIoFAST64 "llo"
#define PRIoMAX "llo"
#define PRIoPTR "o"
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "u"
#define PRIu64 "llu"
#define PRIuLEAST8 "u"
#define PRIuLEAST16 "u"
#define PRIuLEAST32 "u"
#define PRIuLEAST64 "llu"
#define PRIuFAST8 "u"
#define PRIuFAST16 "u"
#define PRIuFAST32 "u"
#define PRIuMAX "u"
#define PRIuFAST64 "llu"
#define PRIuMAX "llu"
#define PRIuPTR "u"
#define PRIx8 "x"
#define PRIx16 "x"
#define PRIx32 "x"
#define PRIx64 "llx"
#define PRIxLEAST8 "x"
#define PRIxLEAST16 "x"
#define PRIxLEAST32 "x"
#define PRIxLEAST64 "llx"
#define PRIxFAST8 "x"
#define PRIxFAST16 "x"
#define PRIxFAST32 "x"
#define PRIxMAX "x"
#define PRIxFAST64 "llx"
#define PRIxMAX "llx"
#define PRIxPTR "x"
#define PRIX8 "X"
#define PRIX16 "X"
#define PRIX32 "X"
#define PRIX64 "llX"
#define PRIXLEAST8 "X"
#define PRIXLEAST16 "X"
#define PRIXLEAST32 "X"
#define PRIXLEAST64 "llX"
#define PRIXFAST8 "X"
#define PRIXFAST16 "X"
#define PRIXFAST32 "X"
#define PRIXMAX "X"
#define PRIXFAST64 "llX"
#define PRIXMAX "llX"
#define PRIXPTR "X"
#define SCNd8 "hhd"
#define SCNd16 "hd"
#define SCNd32 "d"
#define SCNd64 "lld"
#define SCNdLEAST8 "hhd"
#define SCNdLEAST16 "hd"
#define SCNdLEAST32 "d"
#define SCNdLEAST64 "lld"
#define SCNdFAST8 "hhd"
#define SCNdFAST16 "d"
#define SCNdFAST32 "d"
#define SCNdMAX "d"
#define SCNdFAST64 "lld"
#define SCNdMAX "lld"
#define SCNdPTR "d"
#define SCNi8 "hhi"
#define SCNi16 "hi"
#define SCNi32 "i"
#define SCNi64 "lli"
#define SCNiLEAST8 "hhi"
#define SCNiLEAST16 "hi"
#define SCNiLEAST32 "i"
#define SCNiLEAST64 "lli"
#define SCNiFAST8 "hhi"
#define SCNiFAST16 "i"
#define SCNiFAST32 "i"
#define SCNiMAX "i"
#define SCNiFAST64 "lli"
#define SCNiMAX "lli"
#define SCNiPTR "i"
#define SCNo8 "hho"
#define SCNo16 "ho"
#define SCNo32 "o"
#define SCNo64 "llo"
#define SCNoLEAST8 "hho"
#define SCNoLEAST16 "ho"
#define SCNoLEAST32 "o"
#define SCNoLEAST64 "llo"
#define SCNoFAST8 "hho"
#define SCNoFAST16 "o"
#define SCNoFAST32 "o"
#define SCNoMAX "o"
#define SCNoFAST64 "llo"
#define SCNoMAX "llo"
#define SCNoPTR "o"
#define SCNu8 "hhu"
#define SCNu16 "hu"
#define SCNu32 "u"
#define SCNu64 "llu"
#define SCNuLEAST8 "hhu"
#define SCNuLEAST16 "hu"
#define SCNuLEAST32 "u"
#define SCNuLEAST64 "llu"
#define SCNuFAST8 "hhu"
#define SCNuFAST16 "u"
#define SCNuFAST32 "u"
#define SCNuMAX "u"
#define SCNuFAST64 "llu"
#define SCNuMAX "llu"
#define SCNuPTR "u"
#define SCNx8 "hhx"
#define SCNx16 "hx"
#define SCNx32 "x"
#define SCNx64 "llx"
#define SCNxLEAST8 "hhx"
#define SCNxLEAST16 "hx"
#define SCNxLEAST32 "x"
#define SCNxLEAST64 "llx"
#define SCNxFAST8 "hhx"
#define SCNxFAST16 "x"
#define SCNxFAST32 "x"
#define SCNxMAX "x"
#define SCNxFAST64 "llx"
#define SCNxMAX "llx"
#define SCNxPTR "x"
#endif
/*
* The following are fudged with macros, as we don't have real functions
* for them.
*/
#ifndef __div_t
# define __div_t 1
typedef struct div_t { int quot, rem; } div_t;
#endif
#define imaxdiv_t div_t
#if 0
/* Not actually in the C library yet */
typedef struct imaxdiv_t { intmax_t quot, rem; } imaxdiv_t;
#ifdef __cplusplus
extern "C" {
#endif
extern div_t div(int /*numer*/, int /*denom*/);
extern long int strtol(const char * /*nptr*/, char **/*endptr*/, int /*base*/);
extern unsigned long int strtoul(const char * /*nptr*/,
char ** /*endptr*/, int /*base*/);
extern intmax_t imaxabs(intmax_t /*j*/);
extern imaxdiv_t imaxdiv(intmax_t /*numer*/, intmax_t /*denom*/);
extern intmax_t strtoimax(const char * restrict /*nptr*/,
char ** restrict /*endptr*/, int /*base*/);
extern uintmax_t strtoumax(const char * restrict /*nptr*/,
char ** restrict /*endptr*/, int /*base*/);
#ifdef __cplusplus
}
#endif
#define imaxdiv(a,b) div(a,b)
#define strtoimax(a,b,c) ((intmax_t)strtol(a,b,c))
#define strtoumax(a,b,c) ((uintmax_t)strtoul(a,b,c))
#endif /* 0 */
#endif
......
......@@ -273,6 +273,16 @@ extern void _kernel_register_allocs(allocproc *malloc, freeproc *free);
* of stack.
*/
extern void *__rt_allocauto(unsigned);
extern void __rt_freeauto(void *);
/*
* Allocate and free blocks of memory with "automatic" storage - ie associated
* with the current stack frame. In future, this will allow automatic clear-up
* when the stack is unwound, eg by longjmp(), but this is not yet implemented.
* Uses the malloc and free procedures registered above.
* __rt_allocauto always returns a valid block, or generates an error.
*/
typedef int _kernel_ExtendProc(int /*n*/, void** /*p*/);
extern _kernel_ExtendProc *_kernel_register_slotextend(_kernel_ExtendProc *proc);
/* When the initial heap is full, the kernel is normally capable of extending
......
......@@ -15,10 +15,10 @@
#pragma force_top_level
#pragma include_only_once
/* limits.h: ANSI 'C' (X3J11 Oct 88) library header, section 2.2.4.2 */
/* limits.h: ISO 'C' (9899:1999) library header, section 5.2.4.2.1 */
/* Copyright (C) Codemist Ltd., 1988 */
/* Copyright (C) Acorn Computers Ltd. 1991, 1992 */
/* version 2.00 */
/* version 3.00 */
#ifndef __limits_h
#define __limits_h
......@@ -43,7 +43,7 @@
/* minimum value for an object of type short int */
#define SHRT_MAX 0x7fff
/* maximum value for an object of type short int */
#define USHRT_MAX 65535U
#define USHRT_MAX 65535
/* maximum value for an object of type unsigned short int */
#define INT_MIN (~0x7fffffff) /* -2147483648 and 0x80000000 are unsigned */
/* minimum value for an object of type int */
......@@ -51,12 +51,22 @@
/* maximum value for an object of type int */
#define UINT_MAX 0xffffffff
/* maximum value for an object of type unsigned int */
#define LONG_MIN (~0x7fffffff)
#define LONG_MIN (~0x7fffffffL)
/* minimum value for an object of type long int */
#define LONG_MAX 0x7fffffff
#define LONG_MAX 0x7fffffffL
/* maximum value for an object of type long int */
#define ULONG_MAX 0xffffffffU
#define ULONG_MAX 0xffffffffL
/* maximum value for an object of type unsigned long int */
#ifdef __STDC_VERSION__
#if __STDC_VERSION__ >= 199901
#define LLONG_MIN (~0x7fffffffffffffffLL)
/* minimum value for an object of type long long int */
#define LLONG_MAX 0x7fffffffffffffffLL
/* maximum value for an object of type long long int */
#define ULLONG_MAX 0xffffffffffffffffLL
/* maximum value for an object of type unsigned long long int */
#endif
#endif
#endif
......
......@@ -15,16 +15,16 @@
#pragma force_top_level
#pragma include_only_once
/* stdarg.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.8 */
/* stdarg.h: ISO 'C' (9899:1999) library header, section 7.15 */
/* Copyright (C) Codemist Ltd. */
/* Copyright (C) Acorn Computers Ltd. 1991, 1992 */
/* version 3.01 */
/* version 3.10 */
#ifndef __stdarg_h
#define __stdarg_h
/*
* stdarg.h declares a type and defines three macros, for advancing through a
* stdarg.h declares a type and defines four macros, for advancing through a
* list of arguments whose number and types are not known to the called
* function when it is translated. A function may be called with a variable
* number of arguments of differing types. Its parameter list contains one or
......@@ -115,6 +115,17 @@ template <class T> struct __alignoftest
*/
#endif
#define va_copy(dest,src) ((void)(*(dest) = *(src)))
/*
* The va_copy macro initialises dest as a copy of src, as if the va_start
* macro had been applied to dest followed by the same sequences of uses
* of the va_arg macro as had previously been used to reach the present
* state of src. Neither the va_copy nor va_start macro shall be invoked
* to reinitialise dest without an intervening invocation of the va_end
* macro for the same dest.
* Returns: no value.
*/
#define va_end(ap) ((void)(*(ap) = (char *)-256))
/*
* The va_end macro facilitates a normal return from the function whose
......
......@@ -15,48 +15,24 @@
#pragma force_top_level
#pragma include_only_once
/* stdbool.h: ISO 'C' (WG14/N843 Aug 98) library header, section 7.16 */
/* Copyright (C) Element 14 Ltd. 1999 */
/* version 1.00 */
/* stdbool.h: ISO 'C' (9899:1999) library header, section 7.16 */
/* Copyright (C) Acorn Computers Ltd. 2002 */
/* version 1.01 */
#ifndef __stdbool_h
#define __stdbool_h
#define false 0
#define true 1
#ifdef __STDC_VERSION__
#if __STDC_VERSION__ >= 199901L
/*
* According to the FDIS of August 1998, _Bool is a built-in type, and
* bool is #defined to it. This will require compiler support...
*/
#define bool _Bool
#define __bool_true_false_are_defined 1
#endif
#if __STDC_VERSION__ < 199901
# error <stdbool.h> can only be used in C99
#endif
#ifndef __bool_true_false_are_defined
#define false 0
#define true 1
/*
* This is bool, as per the working draft of November 1997. We can do this
* without tweaking the compiler. This should be largely indistiguishable
* when used in a conformant manner. Note that sizeof(bool) will almost
* certainly shrink from 4 to 1 when _Bool is implemented...
*
* Would like bool to be a char, but it must be useable as a bitfield.
* Therefore, we use int. Note that an int bitfield is unsigned, so bool:1
* is unsigned, as required.
*/
typedef int bool;
#define bool _Bool
#define __bool_true_false_are_defined 1
#endif
#endif
/* end of stdbool.h */
......@@ -15,103 +15,110 @@
#pragma force_top_level
#pragma include_only_once
/* stdint.h: ISO 'C' (WG14/N843 Aug 98) library header, section 7.18 */
/* Copyright (C) Element 14 Ltd. 1999 */
/* version 1.00 */
/* stdint.h: ISO 'C' (9899:1999) library header, section 7.18 */
/* Copyright (C) Acorn Computers Ltd. 2002 */
/* version 1.02 */
#ifndef __stdint_h
#define __stdint_h
/*
* A set of C9X-style definitions that make sense for the current
* (Norcroft 5) implementation. Note that we have no 64-bit types,
* as a conforming C9X implementation must.
*/
/*
* cfront cannot cope with the signed type declarations
*/
#ifdef __cplusplus
# if __cplusplus < 199711
# error stdint.h cannot be used with this C++ compiler
# endif
#if __STDC_VERSION__ < 199901
# error <stdint.h> can only be used in C99
#endif
/* Types with exactly the specified width */
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
/* The smallest types with at least the specified width */
typedef signed char int_least8_t;
typedef signed short int_least16_t;
typedef signed int int_least32_t;
typedef unsigned char uint_least8_t;
typedef unsigned short uint_least16_t;
typedef unsigned int uint_least32_t;
typedef signed char int_least8_t;
typedef signed short int_least16_t;
typedef signed int int_least32_t;
typedef signed long long int_least64_t;
typedef unsigned char uint_least8_t;
typedef unsigned short uint_least16_t;
typedef unsigned int uint_least32_t;
typedef unsigned long long uint_least64_t;
/* The "fastest" types with at least the specified width */
typedef signed char int_fast8_t;
typedef signed int int_fast16_t; /* actually 32 bits */
typedef signed int int_fast32_t;
typedef unsigned char uint_fast8_t;
typedef unsigned int uint_fast16_t; /* actually 32 bits */
typedef unsigned int uint_fast32_t;
typedef signed char int_fast8_t;
typedef signed int int_fast16_t; /* actually 32 bits */
typedef signed int int_fast32_t;
typedef signed long long int_fast64_t;
typedef unsigned char uint_fast8_t;
typedef unsigned int uint_fast16_t; /* actually 32 bits */
typedef unsigned int uint_fast32_t;
typedef unsigned long long uint_fast64_t;
/* Integer types capable of holding a "void *" pointer */
typedef signed int intptr_t;
typedef unsigned int uintptr_t;
typedef signed int intptr_t;
typedef unsigned int uintptr_t;
/* Integer types that can hold any value of any type */
typedef signed int intmax_t;
typedef unsigned int uintmax_t;
typedef signed long long intmax_t;
typedef unsigned long long uintmax_t;
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (~0x7FFFFFFF)
#define INT64_MIN (~0x7FFFFFFFFFFFFFFF)
#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define UINT8_MAX 255u
#define UINT16_MAX 65535u
#define INT64_MAX 9223372036854775807
#define UINT8_MAX 255
#define UINT16_MAX 65535
#define UINT32_MAX 4294967295u
#define UINT64_MAX 18446744073709551615u
#define INT_LEAST8_MIN (-128)
#define INT_LEAST16_MIN (-32768)
#define INT_LEAST32_MIN (~0x7FFFFFFF)
#define INT_LEAST64_MIN (~0x7FFFFFFFFFFFFFFF)
#define INT_LEAST8_MAX 127
#define INT_LEAST16_MAX 32767
#define INT_LEAST32_MAX 2147483647
#define UINT_LEAST8_MAX 255u
#define UINT_LEAST16_MAX 65535u
#define INT_LEAST64_MAX 9223372036854775807
#define UINT_LEAST8_MAX 255
#define UINT_LEAST16_MAX 65535
#define UINT_LEAST32_MAX 4294967295u
#define UINT_LEAST64_MAX 18446744073709551615u
#define INT_FAST8_MIN (-128)
#define INT_FAST16_MIN (~0x7FFFFFFF)
#define INT_FAST32_MIN (~0x7FFFFFFF)
#define INT_FAST64_MIN (~0x7FFFFFFFFFFFFFFF)
#define INT_FAST8_MAX 127
#define INT_FAST16_MAX 2147483647
#define INT_FAST32_MAX 2147483647
#define INT_FAST64_MAX 9223372036854775807
#define UINT_FAST8_MAX 255u
#define UINT_FAST16_MAX 4294967295u
#define UINT_FAST32_MAX 4294967295u
#define UINT_FAST64_MAX 18446744073709551615u
#define INTPTR_MIN (~0x7FFFFFFF)
#define INTPTR_MAX 2147483647
#define UINTPTR_MAX 4294967295u
#define INTMAX_MIN (~0x7FFFFFFF)
#define INTMAX_MAX 2147483647
#define UINTMAX_MAX 4294967295u
#define INTMAX_MIN (~0x7FFFFFFFFFFFFFFF)
#define INTMAX_MAX 9223372036854775807
#define UINTMAX_MAX 18446744073709551615u
#define PTRDIFF_MIN (~0x7FFFFFFF)
#define PTRDIFF_MAX 2147483647
#define SIG_ATOMIC_MIN (~0x7FFFFFFF)
#define SIG_ATOMIC_MAX 2147483647
#define SIZE_MAX 4294967295u
#define WCHAR_MIN (~0x7FFFFFFF)
......@@ -124,12 +131,14 @@ typedef unsigned int uintmax_t;
#define INT8_C(n) n
#define INT16_C(n) n
#define INT32_C(n) n
#define INT64_C(n) n##ll
#define UINT8_C(n) n##u
#define UINT16_C(n) n##u
#define UINT32_C(n) n##u
#define UINT64_C(n) n##ull
#define INTMAX_C(n) n
#define UINTMAX_C(n) n##u
#define INTMAX_C(n) n##ll
#define UINTMAX_C(n) n##ull
#endif
......
......@@ -15,7 +15,7 @@
#pragma force_top_level
#pragma include_only_once
/* stdlib.h: ANSI draft (X3J11 May 88) library header, section 4.10 */
/* stdlib.h: ISO 'C' (9899:1999) library header, section 7.20 */
/* Copyright (C) Codemist Ltd. */
/* Copyright (C) Acorn Computers Ltd., 1990, 1992 */
/* version 2.00 */
......@@ -42,13 +42,16 @@
# define NULL 0 /* from <stddef.h> */
#endif
#ifndef __div_t
# define __div_t 1
typedef struct div_t { int quot, rem; } div_t;
/* type of the value returned by the div function. */
#endif
typedef struct ldiv_t { long int quot, rem; } ldiv_t;
/* type of the value returned by the ldiv function. */
#ifdef __STDC_VERSION__
#if __STDC_VERSION__ >= 199901
typedef struct lldiv_t { long long int quot, rem; } lldiv_t;
/* type of the value returned by the lldiv function. */
#endif
#endif
#ifdef __EXIT_FAILURE
# define EXIT_FAILURE __EXIT_FAILURE
......@@ -382,36 +385,38 @@ extern int abs(int /*j*/);
*/
extern div_t div(int /*numer*/, int /*denom*/);
/*
* computes the quotient and remainder of the division of the numerator
* numer by the denominator denom. If the division is inexact, the resulting
* quotient is the integer of lesser magnitude that is the nearest to the
* algebraic quotient. If the result cannot be represented, the behaviour is
* undefined; otherwise, quot * demon + rem shall equal numer.
* computes numer / denom and numer % denom in a single operation.
* Returns: a structure of type div_t, comprising both the quotient and the
* remainder. the structure shall contain the following members,
* in either order.
* int quot; int rem;
* remainder.
*/
extern long int labs(long int /*j*/);
/*
* computes the absolute value of an long integer j. If the result cannot be
* 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*/);
/*
* computes the quotient and remainder of the division of the numerator
* numer by the denominator denom. If the division is inexact, the sign of
* the resulting quotient is that of the algebraic quotient, and the
* magnitude of the resulting quotient is the largest integer less than the
* magnitude of the algebraic quotient. If the result cannot be represented,
* the behaviour is undefined; otherwise, quot * demon + rem shall equal
* numer.
* Returns: a structure of type ldiv_t, comprising both the quotient and the
* remainder. the structure shall contain the following members,
* in either order.
* long int quot; long int rem;
* computes numer / denom and numer % denom in a single operation.
* Returns: a structure of type div_t, comprising both the quotient and the
* remainder.
*/
#ifdef __STDC_VERSION__
#if __STDC_VERSION__ > 199901
extern 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*/);
/*
* computes numer / denom and numer % denom in a single operation.
* Returns: a structure of type div_t, comprising both the quotient and the
* remainder.
*/
#endif
#endif
/*
* Multibyte Character Functions.
......
......@@ -98,6 +98,8 @@ $Label
IMPORT |_kernel_sdiv|
IMPORT |_kernel_srem|
IMPORT |_ll_sdiv|
IMPORT |_kernel_stkovf_split_0frame|
IMPORT |_kernel_stkovf_split|
......@@ -336,7 +338,6 @@ Raised
div
ldiv
imaxdiv
FunctionEntry "a1"
MOV a1, a3
BL _kernel_sdiv ; a1 := a2 / a1, a2 := a2 % a1
......@@ -344,6 +345,24 @@ imaxdiv
STMIA ip, {a1,a2}
Return ,LinkNotStacked
lldiv ; a1 -> result, a2 = num.l, a3=num.h, a4=den.l, den.h on stack
imaxdiv
FunctionEntry "a1"
MOV a1, a2
MOV a2, a3
MOV a3, a4
LDR a4, [sp, #8]
BL _ll_sdiv ; (a1,a2) := (a1,a2) / (a3,a4), (a3,a4) := (a1,a2) % (a3,a4)
Pull "ip,lr"
STMIA ip, {a1-a4}
Return ,LinkNotStacked
llabs
TEQ a2, #0
Return ,LinkNotStacked,PL
RSBS a1, a1, #0
RSC a2, a2, #0
Return ,LinkNotStacked
|x$multiply|
; a1 := a2 * a1.
......
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