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