From 89eac61e456121cb7c7b7b7be1dee70136df7bc2 Mon Sep 17 00:00:00 2001 From: Kevin Bracey <kbracey@gitlab.riscosopen.org> Date: Wed, 22 May 2002 10:45:29 +0000 Subject: [PATCH] * 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' --- Makefile | 40 +++++++++++++--- VersionASM | 16 +++---- VersionNum | 24 +++++----- c/alloc | 111 +++++++++++++------------------------------- c/fpprintf | 1 + c/locale | 3 +- c/math | 9 ++-- c/printf | 56 +++++++++++++++------- c/scanf | 24 +++++++--- c/signal | 2 +- c/stdlib | 10 +++- clib/h/fenv | 26 +++++------ clib/h/inttypes | 92 +++++++++++++++++++++--------------- clib/h/kernel | 10 ++++ clib/h/limits | 22 ++++++--- clib/h/stdarg | 17 +++++-- clib/h/stdbool | 40 ++++------------ clib/h/stdint | 103 +++++++++++++++++++++------------------- clib/h/stdlib | 53 +++++++++++---------- clib/s/cl_body | 21 ++++++++- clib/s/cl_entries | 56 ---------------------- clib/s/cl_entry2 | 81 ++++++++++++++++++++++++++++++++ clib/s/cl_mod_r | 10 ++++ clib/s/cl_stub | 33 +++++++------ clib/s/cl_stub2 | 63 +++++++++++++++++++++++++ clib/s/cl_stub2_r | 22 +++++++++ clib/s/cl_stub2_rm | 24 ++++++++++ h/alloc | 10 ++-- kernel/s/k_body | 27 +++++++++++ kernel/s/k_entries2 | 78 +++++++++++++++++++++++++++++++ kernel/s/k_mod_r | 10 ++++ kernel/s/k_stub2 | 63 +++++++++++++++++++++++++ kernel/s/k_stub2_r | 22 +++++++++ kernel/s/k_stub2_rm | 22 +++++++++ s/initmodule | 8 ++-- 35 files changed, 831 insertions(+), 378 deletions(-) create mode 100644 clib/s/cl_entry2 create mode 100644 clib/s/cl_stub2 create mode 100644 clib/s/cl_stub2_r create mode 100644 clib/s/cl_stub2_rm create mode 100644 kernel/s/k_entries2 create mode 100644 kernel/s/k_stub2 create mode 100644 kernel/s/k_stub2_r create mode 100644 kernel/s/k_stub2_rm diff --git a/Makefile b/Makefile index 8783c35..159ee32 100644 --- a/Makefile +++ b/Makefile @@ -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 $@ diff --git a/VersionASM b/VersionASM index e655f00..c4ce7be 100644 --- a/VersionASM +++ b/VersionASM @@ -1,6 +1,6 @@ ; ; 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 diff --git a/VersionNum b/VersionNum index d4bb380..90360e0 100644 --- a/VersionNum +++ b/VersionNum @@ -1,24 +1,24 @@ -/* (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" diff --git a/c/alloc b/c/alloc index 2ba0d45..025dbfb 100644 --- a/c/alloc +++ b/c/alloc @@ -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; diff --git a/c/fpprintf b/c/fpprintf index 75a9c70..68b158f 100644 --- a/c/fpprintf +++ b/c/fpprintf @@ -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 diff --git a/c/locale b/c/locale index 2c44c29..fa02a4f 100644 --- a/c/locale +++ b/c/locale @@ -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, diff --git a/c/math b/c/math index 2119cc9..b971525 100644 --- a/c/math +++ b/c/math @@ -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; diff --git a/c/printf b/c/printf index 9d813a8..73db8e4 100644 --- a/c/printf +++ b/c/printf @@ -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) ? " " : ""; diff --git a/c/scanf b/c/scanf index cbcf04b..fdeefd6 100644 --- a/c/scanf +++ b/c/scanf @@ -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); diff --git a/c/signal b/c/signal index fb4417e..8946938 100644 --- a/c/signal +++ b/c/signal @@ -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) diff --git a/c/stdlib b/c/stdlib index f12b9fc..2bdac5a 100644 --- a/c/stdlib +++ b/c/stdlib @@ -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 */ diff --git a/clib/h/fenv b/clib/h/fenv index 2ff9e3e..77c9219 100644 --- a/clib/h/fenv +++ b/clib/h/fenv @@ -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 */ diff --git a/clib/h/inttypes b/clib/h/inttypes index 70382fa..38bbfcf 100644 --- a/clib/h/inttypes +++ b/clib/h/inttypes @@ -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 diff --git a/clib/h/kernel b/clib/h/kernel index d7881ad..2acb0c2 100644 --- a/clib/h/kernel +++ b/clib/h/kernel @@ -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 diff --git a/clib/h/limits b/clib/h/limits index 642804d..c749871 100644 --- a/clib/h/limits +++ b/clib/h/limits @@ -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 diff --git a/clib/h/stdarg b/clib/h/stdarg index 3dbf82d..e9e4cec 100644 --- a/clib/h/stdarg +++ b/clib/h/stdarg @@ -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 diff --git a/clib/h/stdbool b/clib/h/stdbool index 04ca4fc..b3d5eff 100644 --- a/clib/h/stdbool +++ b/clib/h/stdbool @@ -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 */ diff --git a/clib/h/stdint b/clib/h/stdint index ff35046..e379489 100644 --- a/clib/h/stdint +++ b/clib/h/stdint @@ -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 diff --git a/clib/h/stdlib b/clib/h/stdlib index 9a11a6e..b6f1c9f 100644 --- a/clib/h/stdlib +++ b/clib/h/stdlib @@ -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. diff --git a/clib/s/cl_body b/clib/s/cl_body index 568b630..ef1f7be 100644 --- a/clib/s/cl_body +++ b/clib/s/cl_body @@ -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. diff --git a/clib/s/cl_entries b/clib/s/cl_entries index b8d8035..b17ce43 100644 --- a/clib/s/cl_entries +++ b/clib/s/cl_entries @@ -214,61 +214,5 @@ Entry _swi, imported, , unveneered Entry _swix, imported, , unveneered - Entry __fpclassifyf, , , unveneered - Entry __fpclassifyd, , , unveneered - Entry __signbitf, , , unveneered - Entry __signbitd, , , unveneered - Entry copysign, , , unveneered - Entry copysignf, , , unveneered - Entry nan, imported, , unveneered - Entry nanf, imported, , unveneered - Entry nextafter, , , unveneered - Entry nextafterf, , , unveneered - Entry fdim, imported, , unveneered - Entry fdimf, imported, , unveneered - Entry fmax, , , unveneered - Entry fmaxf, , , unveneered - Entry fmin, , , unveneered - Entry fminf, , , unveneered - Entry fabsf, imported, , unveneered - Entry hypot, , , unveneered - Entry hypotf, , , unveneered - - Entry feclearexcept, imported, , unveneered - Entry fegetexceptflag, imported, , unveneered - Entry feraiseexcept, imported, , unveneered - Entry fesetexceptflag, imported, , unveneered - Entry fetestexcept, imported, , unveneered - Entry fegetround, imported, , unveneered - Entry fesetround, imported, , unveneered - Entry fegetenv, imported, , unveneered - Entry feholdexcept, imported, , unveneered - Entry fesetenv, imported, , unveneered - Entry feupdateenv, imported, , unveneered - - Entry _snprintf, imported, , unveneered - Entry snprintf, imported, , unveneered - Entry vsnprintf, imported, , unveneered - Entry vfscanf, imported, , unveneered - Entry vscanf, imported, , unveneered - Entry vsscanf, imported, , unveneered - - Entry ceilf, imported, , unveneered - Entry floorf, imported, , unveneered - Entry nearbyint, , , unveneered - Entry nearbyintf, , , unveneered - Entry rint, imported, , unveneered - Entry rintf, imported, , unveneered - Entry lrint, imported, , unveneered - Entry lrintf, imported, , unveneered - Entry round, , , unveneered - Entry roundf, , , unveneered - Entry lround, , , unveneered - Entry lroundf, , , unveneered - Entry trunc, imported, , unveneered - Entry truncf, imported, , unveneered - Entry remainder, , , unveneered - Entry remainderf, , , unveneered - ; __va_illegal_arg 0 END diff --git a/clib/s/cl_entry2 b/clib/s/cl_entry2 new file mode 100644 index 0000000..1de9f63 --- /dev/null +++ b/clib/s/cl_entry2 @@ -0,0 +1,81 @@ +; Copyright 2002 Pace Micro Technology plc +; +; 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. +; +;-*- Mode: Assembler -*- +; +; Copyright (C) Acorn Computers Ltd., 1989. +; +; Add new entries ONLY AT THE END of the list +; + + Entry __fpclassifyf, , , unveneered + Entry __fpclassifyd, , , unveneered + Entry __signbitf, , , unveneered + Entry __signbitd, , , unveneered + Entry copysign, , , unveneered + Entry copysignf, , , unveneered + Entry nan, imported, , unveneered + Entry nanf, imported, , unveneered + Entry nextafter, , , unveneered + Entry nextafterf, , , unveneered + Entry fdim, imported, , unveneered + Entry fdimf, imported, , unveneered + Entry fmax, , , unveneered + Entry fmaxf, , , unveneered + Entry fmin, , , unveneered + Entry fminf, , , unveneered + Entry fabsf, imported, , unveneered + Entry hypot, , , unveneered + Entry hypotf, , , unveneered + + Entry feclearexcept, imported, , unveneered + Entry fegetexceptflag, imported, , unveneered + Entry feraiseexcept, imported, , unveneered + Entry fesetexceptflag, imported, , unveneered + Entry fetestexcept, imported, , unveneered + Entry fegetround, imported, , unveneered + Entry fesetround, imported, , unveneered + Entry fegetenv, imported, , unveneered + Entry feholdexcept, imported, , unveneered + Entry fesetenv, imported, , unveneered + Entry feupdateenv, imported, , unveneered + + Entry _snprintf, imported, , unveneered + Entry snprintf, imported, , unveneered + Entry vsnprintf, imported, , unveneered + Entry vfscanf, imported, , unveneered + Entry vscanf, imported, , unveneered + Entry vsscanf, imported, , unveneered + + Entry ceilf, imported, , unveneered + Entry floorf, imported, , unveneered + Entry nearbyint, , , unveneered + Entry nearbyintf, , , unveneered + Entry rint, imported, , unveneered + Entry rintf, imported, , unveneered + Entry lrint, imported, , unveneered + Entry lrintf, imported, , unveneered + Entry round, , , unveneered + Entry roundf, , , unveneered + Entry lround, , , unveneered + Entry lroundf, , , unveneered + Entry trunc, imported, , unveneered + Entry truncf, imported, , unveneered + Entry remainder, , , unveneered + Entry remainderf, , , unveneered + + Entry llabs, , , unveneered + Entry lldiv, , , unveneered + + END diff --git a/clib/s/cl_mod_r b/clib/s/cl_mod_r index 36ff647..77401dd 100644 --- a/clib/s/cl_mod_r +++ b/clib/s/cl_mod_r @@ -51,6 +51,12 @@ dataStart & dataStart & |CLib_data_end| + & 5 + & entries2Start + & entries2End + & 0 + & 0 + AREA |RTSK$$Data|, READONLY IMPORT |C$$code$$Base| @@ -79,6 +85,10 @@ entriesStart GET clib.s.cl_entries entriesEnd +entries2Start + GET clib.s.cl_entry2 +entries2End + EXPORT |__main| ; The compiler produces references to this, so it must be defined, ; but it had better not be branched to. diff --git a/clib/s/cl_stub b/clib/s/cl_stub index 3370c0e..aa5dfcd 100644 --- a/clib/s/cl_stub +++ b/clib/s/cl_stub @@ -92,7 +92,9 @@ SharedLibrary SETL {TRUE} ; r6 = requested stack size (in K) << 16 ; r6 bit 0 indicates 32-bit mode - ADR r0, |_lib_init_table| + IMPORT |Stub$$Init$$Base| + LDR r0, =|Stub$$Init$$Base| +; ADR r0, |_lib_init_table| LDR r6, =|__root_stack_size| CMP r6, #0 MOVEQ r6, #RootStackSize @@ -212,7 +214,8 @@ LookupError LDR r2, [r12, #blocksize] ADD r2, r2, r1 ; Pointer to high end of block LDR r3, =|Image$$ZI$$Base| - ADR r0, |_lib_init_table| + LDR r0, =|Stub$$Init$$Base| +; ADR r0, |_lib_init_table| LDR r6, =|__root_stack_size| CMP r6, #0 MOVEQ r6, #RootStackSize :SHL: 6 @@ -324,6 +327,19 @@ LookupError ] ] +|_k_init_block| + & |Image$$RO$$Base| + & |RTSK$$Data$$Base| + & |RTSK$$Data$$Limit| + + LTORG + + GET clib.s.cl_init + + LTORG + + AREA |Stub$$Init|, CODE, READONLY + |_lib_init_table| & 1 & |_k_entries_start| @@ -348,18 +364,9 @@ LookupError ] ] - & -1 - -|_k_init_block| - & |Image$$RO$$Base| - & |RTSK$$Data$$Base| - & |RTSK$$Data$$Limit| + AREA |Stub$$InitEnd|, CODE, READONLY - LTORG - - GET clib.s.cl_init - - LTORG + & -1 AREA |Stub$$Entries|, CODE, READONLY diff --git a/clib/s/cl_stub2 b/clib/s/cl_stub2 new file mode 100644 index 0000000..b11dec3 --- /dev/null +++ b/clib/s/cl_stub2 @@ -0,0 +1,63 @@ +; Copyright 2002 Pace Micro Technology plc +; +; 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. +; +; -*- Mode: Assembler -*- +;* Lastedit: 08 Mar 90 15:18:04 by Harry Meekings * +;* Shared C library: stub for clients to link with +; 2-Mar-89: IDJ: taken for RISC_OSLib purposes +; +; Copyright (C) Acorn Computers Ltd., 1988. +; + + GBLL Brazil_Compatible + GBLL ModeMayBeNonUser + GBLL SharedLibrary + +Brazil_Compatible SETL {FALSE} +ModeMayBeNonUser SETL {TRUE} +SharedLibrary SETL {TRUE} + + GET s.h_Regs + GET s.h_Brazil + GET s.h_stubs + GET s.h_stack + GET s.h_workspc + + AREA |Stub$$Init|, CODE, READONLY + + & 5 + & |_clib_entries2_start| + & |_clib_entries2_end| + & 0 + & 0 + + AREA |Stub$$Entries|, CODE, READONLY + +; Don't GET the stub entries if in ROM + + + GBLS GetRoundObjAsm +|_clib_entries2_start| + [ Code_Destination = "RAM" +GetRoundObjAsm SETS " GET clib.s.cl_entry2" + | +GetRoundObjAsm SETS "" + ] +$GetRoundObjAsm +|_clib_entries2_end| + [ Code_Destination = "RAM" :LAND: APCS_Type <> "APCS-R" + % |_clib_entries2_end| - |_clib_entries2_start| + ] + + END diff --git a/clib/s/cl_stub2_r b/clib/s/cl_stub2_r new file mode 100644 index 0000000..4c44898 --- /dev/null +++ b/clib/s/cl_stub2_r @@ -0,0 +1,22 @@ +; Copyright 2002 Pace Micro Technology plc +; +; 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. +; + GBLS Calling_Standard + +Calling_Standard SETS "APCS_U" + + GBLS Code_Destination +Code_Destination SETS "RAM" + + LNK clib.s.cl_stub2 diff --git a/clib/s/cl_stub2_rm b/clib/s/cl_stub2_rm new file mode 100644 index 0000000..caccc28 --- /dev/null +++ b/clib/s/cl_stub2_rm @@ -0,0 +1,24 @@ +; Copyright 2002 Pace Micro Technology plc +; +; 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. +; + GBLS Calling_Standard + +Calling_Standard SETS "APCS_U" + + GBLS Code_Destination +Code_Destination SETS "ROM" + + GBLL Module_Only + + LNK clib.s.cl_stub2 diff --git a/h/alloc b/h/alloc index 900c115..1e1d540 100644 --- a/h/alloc +++ b/h/alloc @@ -60,11 +60,11 @@ typedef struct BlockStruct { #define SIZEMASK 0x07ffffff /* all except top five bits, when applied */ /* to block.size yields no of address units */ /* of user space in this block. */ -#define PUREDATABIT (1<<31) /* indicates the block contains no pointers */ -#define NOTGCABLEBIT (1<<30) /* the block is not to be garbage collected */ -#define USEDBIT (1<<29) /* if set, indicates that the block is not free */ -#define FREEBIT (1<<28) /* if set, indicates that the block is free */ -#define HEAPHOLEBIT (1<<27) /* block used for marking start of heap hole */ +#define PUREDATABIT (1u<<31) /* indicates the block contains no pointers */ +#define NOTGCABLEBIT (1u<<30) /* the block is not to be garbage collected */ +#define USEDBIT (1u<<29) /* if set, indicates that the block is not free */ +#define FREEBIT (1u<<28) /* if set, indicates that the block is free */ +#define HEAPHOLEBIT (1u<<27) /* block used for marking start of heap hole */ #define GUARDCONSTANT 0x3E694C3C /* not a legal word pointer */ #define GCABLE 0 #define GCDATA PUREDATABIT diff --git a/kernel/s/k_body b/kernel/s/k_body index 87badcd..4b26a7a 100644 --- a/kernel/s/k_body +++ b/kernel/s/k_body @@ -55,6 +55,8 @@ EXPORT |_kernel_register_allocs| EXPORT |_kernel_register_slotextend| EXPORT |_kernel_alloc| + EXPORT |__rt_allocauto| + EXPORT |__rt_freeauto| EXPORT |_kernel_current_stack_chunk| EXPORT |_kernel_stkovf_split_0frame| @@ -2566,6 +2568,29 @@ alloc_return_block ; if I do, it complicates malloc and alloc above. Return ,LinkNotStacked +; In future these could be sophisticated allocators that associate +; allocated blocks with stack chunks, allowing longjmp() et al to +; clear them up. But for now, this suffices for C99's VLAs. +|__rt_allocauto| + FunctionEntry + LoadStaticBase ip, a2 + MOV lr, pc + LDR pc, [ip, #O_allocProc] + TEQ a1, #0 + Return ,,NE + LoadStaticBase ip, a1 + LDR lr, [sp], #4 + ADD ip, ip, #O_registerDump + STMIA ip, {a1 - r14} + ADR r0, E_StackOverflow + BL |_kernel_copyerror| + SWI GenerateError + +|__rt_freeauto| + LoadStaticBase ip, a2 + LDR pc, [ip, #O_freeProc] + + ;*-------------------------------------------------------------------* ;* Stack chunk handling * ;*-------------------------------------------------------------------* @@ -3059,6 +3084,8 @@ s_sh0 RSBS ip, a1, a2 RSBMI a2, a2, #0 Return ,LinkNotStacked + EXPORT __rt_div0 +__rt_div0 dividebyzero ; Dump all registers, then enter the abort code. ; We need to discover whether we were doing a divide (in which case, diff --git a/kernel/s/k_entries2 b/kernel/s/k_entries2 new file mode 100644 index 0000000..bee4e39 --- /dev/null +++ b/kernel/s/k_entries2 @@ -0,0 +1,78 @@ +; Copyright 2002 Pace Micro Technology plc +; +; 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. +; +;-*- Mode: Assembler -*- +; Last modified 20 May 02 16:30:31 by KJB +; +; Copyright (C) Acorn Computers Ltd., 2002. +; +; Add new entries ONLY AT THE END of the list + + Entry __rt_allocauto, , , unveneered + Entry __rt_freeauto, , , unveneered + + Entry _ll_from_u, imported, , unveneered + Entry _ll_from_l, imported, , unveneered + Entry _ll_to_l, imported, , unveneered + + Entry _ll_add, imported, , unveneered + Entry _ll_addlu, imported, , unveneered + Entry _ll_addls, imported, , unveneered + Entry _ll_adduu, imported, , unveneered + Entry _ll_addss, imported, , unveneered + Entry _ll_sub, imported, , unveneered + Entry _ll_sublu, imported, , unveneered + Entry _ll_subls, imported, , unveneered + Entry _ll_subuu, imported, , unveneered + Entry _ll_subss, imported, , unveneered + Entry _ll_rsb, imported, , unveneered + Entry _ll_rsblu, imported, , unveneered + Entry _ll_rsbls, imported, , unveneered + Entry _ll_rsbuu, imported, , unveneered + Entry _ll_rsbss, imported, , unveneered + Entry _ll_mul, imported, , unveneered + Entry _ll_mullu, imported, , unveneered + Entry _ll_mulls, imported, , unveneered + Entry _ll_muluu, imported, , unveneered + Entry _ll_mulss, imported, , unveneered + Entry _ll_udiv, imported, , unveneered + Entry _ll_urdv, imported, , unveneered + Entry _ll_udiv10, imported, , unveneered + Entry _ll_sdiv, imported, , unveneered + Entry _ll_srdv, imported, , unveneered + Entry _ll_sdiv10, imported, , unveneered + + Entry _ll_not, imported, , unveneered + Entry _ll_neg, imported, , unveneered + Entry _ll_and, imported, , unveneered + Entry _ll_or, imported, , unveneered + Entry _ll_eor, imported, , unveneered + Entry _ll_shift_l, imported, , unveneered + Entry _ll_ushift_r, imported, , unveneered + Entry _ll_sshift_r, imported, , unveneered + + Entry _ll_cmpu, imported, , unveneered + Entry _ll_cmpge, imported, , unveneered + Entry _ll_cmple, imported, , unveneered + + Entry _ll_uto_d, imported, , unveneered + Entry _ll_sto_d, imported, , unveneered + Entry _ll_uto_f, imported, , unveneered + Entry _ll_sto_f, imported, , unveneered + Entry _ll_ufrom_d, imported, , unveneered + Entry _ll_sfrom_d, imported, , unveneered + Entry _ll_ufrom_f, imported, , unveneered + Entry _ll_sfrom_f, imported, , unveneered + + END diff --git a/kernel/s/k_mod_r b/kernel/s/k_mod_r index 63a2def..790cebf 100644 --- a/kernel/s/k_mod_r +++ b/kernel/s/k_mod_r @@ -51,6 +51,12 @@ dataEnd & dataStart & dataEnd + & 4 + & entries2Start + & entries2End + & 0 + & 0 + AREA |RTSK$$Data|, DATA, READONLY ; an empty one, so the symbols below are always defined @@ -62,4 +68,8 @@ entriesStart GET kernel.s.k_entries entriesEnd +entries2Start + GET kernel.s.k_entries2 +entries2End + LNK kernel.s.k_body diff --git a/kernel/s/k_stub2 b/kernel/s/k_stub2 new file mode 100644 index 0000000..b76d294 --- /dev/null +++ b/kernel/s/k_stub2 @@ -0,0 +1,63 @@ +; Copyright 2002 Pace Micro Technology plc +; +; 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. +; +; -*- Mode: Assembler -*- +;* Lastedit: 08 Mar 90 15:18:04 by Harry Meekings * +;* Shared C library: stub for clients to link with +; 2-Mar-89: IDJ: taken for RISC_OSLib purposes +; +; Copyright (C) Acorn Computers Ltd., 1988. +; + + GBLL Brazil_Compatible + GBLL ModeMayBeNonUser + GBLL SharedLibrary + +Brazil_Compatible SETL {FALSE} +ModeMayBeNonUser SETL {TRUE} +SharedLibrary SETL {TRUE} + + GET s.h_Regs + GET s.h_Brazil + GET s.h_stubs + GET s.h_stack + GET s.h_workspc + + AREA |Stub$$Init|, CODE, READONLY + + & 4 + & |_k_entries2_start| + & |_k_entries2_end| + & 0 + & 0 + + AREA |Stub$$Entries|, CODE, READONLY + +; Don't GET the stub entries if in ROM + + + GBLS GetRoundObjAsm +|_k_entries2_start| + [ Code_Destination = "RAM" +GetRoundObjAsm SETS " GET kernel.s.k_entries2" + | +GetRoundObjAsm SETS "" + ] +$GetRoundObjAsm +|_k_entries2_end| + [ Code_Destination = "RAM" :LAND: APCS_Type <> "APCS-R" + % |_k_entries2_end| - |_k_entries2_start| + ] + + END diff --git a/kernel/s/k_stub2_r b/kernel/s/k_stub2_r new file mode 100644 index 0000000..23791bd --- /dev/null +++ b/kernel/s/k_stub2_r @@ -0,0 +1,22 @@ +; Copyright 2002 Pace Micro Technology plc +; +; 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. +; + GBLS Calling_Standard + +Calling_Standard SETS "APCS_U" + + GBLS Code_Destination +Code_Destination SETS "RAM" + + LNK kernel.s.k_stub2 diff --git a/kernel/s/k_stub2_rm b/kernel/s/k_stub2_rm new file mode 100644 index 0000000..536f424 --- /dev/null +++ b/kernel/s/k_stub2_rm @@ -0,0 +1,22 @@ +; Copyright 2002 Pace Micro Technology plc +; +; 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. +; + GBLS Calling_Standard + +Calling_Standard SETS "APCS_U" + + GBLS Code_Destination +Code_Destination SETS "ROM" + + LNK kernel.s.k_stub2 diff --git a/s/initmodule b/s/initmodule index 8588d0e..bd90ea8 100644 --- a/s/initmodule +++ b/s/initmodule @@ -444,8 +444,11 @@ libdatasize_text staticsizeok ] - SUB r3, r3, r2 ; size of library chunk statics + SUBS r3, r3, r2 ; size of library chunk statics + BLE NextLibraryChunk ; no statics for this chunk + ; and the offset must agree with that for all earlier chunks + LDR r1, [r13, #Proc_RegOffset + 4] LDR r1, [r1, #SC_SLOffset+SL_Client_Offset] ADD r2, r2, r1 ; relocate address to copy to!! @@ -456,9 +459,6 @@ staticsizeok BNE Failed MOV r5, r1 - CMP r3, #0 - BLE NextLibraryChunk ; no statics for this chunk - ; Copy the data from our fixed static data area to the clients dynamic ; static data area. No zero initialised data at all. CopyLibStatics -- GitLab